diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2016-07-23 20:44:14 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2016-07-23 20:44:14 +0000 |
commit | 2b6b257f4e5503a7a2675bdb8735693db769f75c (patch) | |
tree | e85e046ae7003fe3bcc8b5454cd0fa3f7407b470 /include/clang | |
parent | b4348ed0b7e90c0831b925fbee00b5f179a99796 (diff) |
Notes
Diffstat (limited to 'include/clang')
219 files changed, 15235 insertions, 4267 deletions
diff --git a/include/clang/ARCMigrate/ARCMTActions.h b/include/clang/ARCMigrate/ARCMTActions.h index c830aa3d78744..554e0c0c6d028 100644 --- a/include/clang/ARCMigrate/ARCMTActions.h +++ b/include/clang/ARCMigrate/ARCMTActions.h @@ -22,7 +22,7 @@ protected: bool BeginInvocation(CompilerInstance &CI) override; public: - CheckAction(FrontendAction *WrappedAction); + CheckAction(std::unique_ptr<FrontendAction> WrappedAction); }; class ModifyAction : public WrapperFrontendAction { @@ -30,7 +30,7 @@ protected: bool BeginInvocation(CompilerInstance &CI) override; public: - ModifyAction(FrontendAction *WrappedAction); + ModifyAction(std::unique_ptr<FrontendAction> WrappedAction); }; class MigrateSourceAction : public ASTFrontendAction { @@ -49,7 +49,8 @@ protected: bool BeginInvocation(CompilerInstance &CI) override; public: - MigrateAction(FrontendAction *WrappedAction, StringRef migrateDir, + MigrateAction(std::unique_ptr<FrontendAction> WrappedAction, + StringRef migrateDir, StringRef plistOut, bool emitPremigrationARCErrors); }; @@ -61,8 +62,8 @@ class ObjCMigrateAction : public WrapperFrontendAction { FileRemapper Remapper; CompilerInstance *CompInst; public: - ObjCMigrateAction(FrontendAction *WrappedAction, StringRef migrateDir, - unsigned migrateAction); + ObjCMigrateAction(std::unique_ptr<FrontendAction> WrappedAction, + StringRef migrateDir, unsigned migrateAction); protected: std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI, diff --git a/include/clang/AST/ASTConsumer.h b/include/clang/AST/ASTConsumer.h index b2730e4622287..0b1f0068fa6f0 100644 --- a/include/clang/AST/ASTConsumer.h +++ b/include/clang/AST/ASTConsumer.h @@ -55,9 +55,9 @@ public: /// \returns true to continue parsing, or false to abort parsing. virtual bool HandleTopLevelDecl(DeclGroupRef D); - /// \brief This callback is invoked each time an inline method definition is - /// completed. - virtual void HandleInlineMethodDefinition(CXXMethodDecl *D) {} + /// \brief This callback is invoked each time an inline (method or friend) + /// function definition in a class is completed. + virtual void HandleInlineFunctionDefinition(FunctionDecl *D) {} /// HandleInterestingDecl - Handle the specified interesting declaration. This /// is called by the AST reader when deserializing things that might interest @@ -94,21 +94,6 @@ public: /// The default implementation passes it to HandleTopLevelDecl. virtual void HandleImplicitImportDecl(ImportDecl *D); - /// \brief Handle a pragma that appends to Linker Options. Currently this - /// only exists to support Microsoft's #pragma comment(linker, "/foo"). - virtual void HandleLinkerOptionPragma(llvm::StringRef Opts) {} - - /// \brief Handle a pragma that emits a mismatch identifier and value to the - /// object file for the linker to work with. Currently, this only exists to - /// support Microsoft's #pragma detect_mismatch. - virtual void HandleDetectMismatch(llvm::StringRef Name, - llvm::StringRef Value) {} - - /// \brief Handle a dependent library created by a pragma in the source. - /// Currently this only exists to support Microsoft's - /// #pragma comment(lib, "/foo"). - virtual void HandleDependentLibrary(llvm::StringRef Lib) {} - /// CompleteTentativeDefinition - Callback invoked at the end of a translation /// unit to notify the consumer that the given tentative definition should be /// completed. @@ -120,6 +105,10 @@ public: /// modified by the introduction of an implicit zero initializer. virtual void CompleteTentativeDefinition(VarDecl *D) {} + /// \brief Callback invoked when an MSInheritanceAttr has been attached to a + /// CXXRecordDecl. + virtual void AssignInheritanceModel(CXXRecordDecl *RD) {} + /// HandleCXXStaticMemberVarInstantiation - Tell the consumer that this // variable has been instantiated. virtual void HandleCXXStaticMemberVarInstantiation(VarDecl *D) {} diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h index abf92948bb42e..1d223f47a9aec 100644 --- a/include/clang/AST/ASTContext.h +++ b/include/clang/AST/ASTContext.h @@ -36,6 +36,7 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/IntrusiveRefCntPtr.h" +#include "llvm/ADT/MapVector.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/TinyPtrVector.h" #include "llvm/Support/Allocator.h" @@ -128,6 +129,8 @@ class ASTContext : public RefCountedBase<ASTContext> { llvm::FoldingSet<PackExpansionType> PackExpansionTypes; mutable llvm::FoldingSet<ObjCObjectTypeImpl> ObjCObjectTypes; mutable llvm::FoldingSet<ObjCObjectPointerType> ObjCObjectPointerTypes; + mutable llvm::FoldingSet<DependentUnaryTransformType> + DependentUnaryTransformTypes; mutable llvm::FoldingSet<AutoType> AutoTypes; mutable llvm::FoldingSet<AtomicType> AtomicTypes; llvm::FoldingSet<AttributedType> AttributedTypes; @@ -212,9 +215,6 @@ class ASTContext : public RefCountedBase<ASTContext> { /// \brief The typedef for the __uint128_t type. mutable TypedefDecl *UInt128Decl; - /// \brief The typedef for the __float128 stub type. - mutable TypeDecl *Float128StubDecl; - /// \brief The typedef for the target specific predefined /// __builtin_va_list type. mutable TypedefDecl *BuiltinVaListDecl; @@ -243,6 +243,9 @@ class ASTContext : public RefCountedBase<ASTContext> { QualType ObjCClassRedefinitionType; QualType ObjCSelRedefinitionType; + /// The identifier 'bool'. + mutable IdentifierInfo *BoolName = nullptr; + /// The identifier 'NSObject'. IdentifierInfo *NSObjectName = nullptr; @@ -252,9 +255,13 @@ class ASTContext : public RefCountedBase<ASTContext> { /// The identifier '__make_integer_seq'. mutable IdentifierInfo *MakeIntegerSeqName = nullptr; + /// The identifier '__type_pack_element'. + mutable IdentifierInfo *TypePackElementName = nullptr; + QualType ObjCConstantStringType; - mutable RecordDecl *CFConstantStringTypeDecl; - + mutable RecordDecl *CFConstantStringTagDecl; + mutable TypedefDecl *CFConstantStringTypeDecl; + mutable QualType ObjCSuperType; QualType ObjCNSStringType; @@ -392,8 +399,8 @@ private: /// \brief Side-table of mangling numbers for declarations which rarely /// need them (like static local vars). - llvm::DenseMap<const NamedDecl *, unsigned> MangleNumbers; - llvm::DenseMap<const VarDecl *, unsigned> StaticLocalNumbers; + llvm::MapVector<const NamedDecl *, unsigned> MangleNumbers; + llvm::MapVector<const VarDecl *, unsigned> StaticLocalNumbers; /// \brief Mapping that stores parameterIndex values for ParmVarDecls when /// that value exceeds the bitfield size of ParmVarDeclBits.ParameterIndex. @@ -406,6 +413,7 @@ private: TranslationUnitDecl *TUDecl; mutable ExternCContextDecl *ExternCContext; mutable BuiltinTemplateDecl *MakeIntegerSeqDecl; + mutable BuiltinTemplateDecl *TypePackElementDecl; /// \brief The associated SourceManager object.a SourceManager &SourceMgr; @@ -817,6 +825,9 @@ public: overridden_methods_end(const CXXMethodDecl *Method) const; unsigned overridden_methods_size(const CXXMethodDecl *Method) const; + typedef llvm::iterator_range<overridden_cxx_method_iterator> + overridden_method_range; + overridden_method_range overridden_methods(const CXXMethodDecl *Method) const; /// \brief Note that the given C++ \p Method overrides the given \p /// Overridden method. @@ -876,6 +887,7 @@ public: ExternCContextDecl *getExternCContextDecl() const; BuiltinTemplateDecl *getMakeIntegerSeqDecl() const; + BuiltinTemplateDecl *getTypePackElementDecl() const; // Builtin Types. CanQualType VoidTy; @@ -889,20 +901,19 @@ public: CanQualType SignedCharTy, ShortTy, IntTy, LongTy, LongLongTy, Int128Ty; CanQualType UnsignedCharTy, UnsignedShortTy, UnsignedIntTy, UnsignedLongTy; CanQualType UnsignedLongLongTy, UnsignedInt128Ty; - CanQualType FloatTy, DoubleTy, LongDoubleTy; + CanQualType FloatTy, DoubleTy, LongDoubleTy, Float128Ty; CanQualType HalfTy; // [OpenCL 6.1.1.1], ARM NEON CanQualType FloatComplexTy, DoubleComplexTy, LongDoubleComplexTy; + CanQualType Float128ComplexTy; CanQualType VoidPtrTy, NullPtrTy; CanQualType DependentTy, OverloadTy, BoundMemberTy, UnknownAnyTy; CanQualType BuiltinFnTy; CanQualType PseudoObjectTy, ARCUnbridgedCastTy; CanQualType ObjCBuiltinIdTy, ObjCBuiltinClassTy, ObjCBuiltinSelTy; CanQualType ObjCBuiltinBoolTy; - CanQualType OCLImage1dTy, OCLImage1dArrayTy, OCLImage1dBufferTy; - CanQualType OCLImage2dTy, OCLImage2dArrayTy, OCLImage2dDepthTy; - CanQualType OCLImage2dArrayDepthTy, OCLImage2dMSAATy, OCLImage2dArrayMSAATy; - CanQualType OCLImage2dMSAADepthTy, OCLImage2dArrayMSAADepthTy; - CanQualType OCLImage3dTy; +#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ + CanQualType SingletonId; +#include "clang/Basic/OpenCLImageTypes.def" CanQualType OCLSamplerTy, OCLEventTy, OCLClkEventTy; CanQualType OCLQueueTy, OCLNDRangeTy, OCLReserveIDTy; CanQualType OMPArraySectionTy; @@ -966,9 +977,6 @@ public: /// \brief Retrieve the declaration for the 128-bit unsigned integer type. TypedefDecl *getUInt128Decl() const; - /// \brief Retrieve the declaration for a 128-bit float stub type. - TypeDecl *getFloat128StubType() const; - //===--------------------------------------------------------------------===// // Type Constructors //===--------------------------------------------------------------------===// @@ -1229,13 +1237,12 @@ public: TemplateTypeParmDecl *ParmDecl = nullptr) const; QualType getTemplateSpecializationType(TemplateName T, - const TemplateArgument *Args, - unsigned NumArgs, + ArrayRef<TemplateArgument> Args, QualType Canon = QualType()) const; - QualType getCanonicalTemplateSpecializationType(TemplateName T, - const TemplateArgument *Args, - unsigned NumArgs) const; + QualType + getCanonicalTemplateSpecializationType(TemplateName T, + ArrayRef<TemplateArgument> Args) const; QualType getTemplateSpecializationType(TemplateName T, const TemplateArgumentListInfo &Args, @@ -1260,11 +1267,9 @@ public: NestedNameSpecifier *NNS, const IdentifierInfo *Name, const TemplateArgumentListInfo &Args) const; - QualType getDependentTemplateSpecializationType(ElaboratedTypeKeyword Keyword, - NestedNameSpecifier *NNS, - const IdentifierInfo *Name, - unsigned NumArgs, - const TemplateArgument *Args) const; + QualType getDependentTemplateSpecializationType( + ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS, + const IdentifierInfo *Name, ArrayRef<TemplateArgument> Args) const; QualType getPackExpansionType(QualType Pattern, Optional<unsigned> NumExpansions); @@ -1381,10 +1386,12 @@ public: /// if it hasn't yet been built. QualType getRawCFConstantStringType() const { if (CFConstantStringTypeDecl) - return getTagDeclType(CFConstantStringTypeDecl); + return getTypedefType(CFConstantStringTypeDecl); return QualType(); } void setCFConstantStringType(QualType T); + TypedefDecl *getCFConstantStringDecl() const; + RecordDecl *getCFConstantStringTagDecl() const; // This setter/getter represents the ObjC type for an NSConstantString. void setObjCConstantStringInterface(ObjCInterfaceDecl *Decl); @@ -1458,12 +1465,25 @@ public: return NSCopyingName; } + /// Retrieve the identifier 'bool'. + IdentifierInfo *getBoolName() const { + if (!BoolName) + BoolName = &Idents.get("bool"); + return BoolName; + } + IdentifierInfo *getMakeIntegerSeqName() const { if (!MakeIntegerSeqName) MakeIntegerSeqName = &Idents.get("__make_integer_seq"); return MakeIntegerSeqName; } + IdentifierInfo *getTypePackElementName() const { + if (!TypePackElementName) + TypePackElementName = &Idents.get("__type_pack_element"); + return TypePackElementName; + } + /// \brief Retrieve the Objective-C "instancetype" type, if already known; /// otherwise, returns a NULL type; QualType getObjCInstanceType() { @@ -2257,7 +2277,7 @@ public: QualType mergeObjCGCQualifiers(QualType, QualType); - bool FunctionTypesMatchOnNSConsumedAttrs( + bool doFunctionTypesMatchOnExtParameterInfos( const FunctionProtoType *FromFunctionType, const FunctionProtoType *ToFunctionType); @@ -2508,7 +2528,21 @@ public: /// \brief Returns true if this is an inline-initialized static data member /// which is treated as a definition for MSVC compatibility. bool isMSStaticDataMemberInlineDefinition(const VarDecl *VD) const; - + + enum class InlineVariableDefinitionKind { + None, ///< Not an inline variable. + Weak, ///< Weak definition of inline variable. + WeakUnknown, ///< Weak for now, might become strong later in this TU. + Strong ///< Strong definition. + }; + /// \brief Determine whether a definition of this inline variable should + /// be treated as a weak or strong definition. For compatibility with + /// C++14 and before, for a constexpr static data member, if there is an + /// out-of-line declaration of the member, we may promote it from weak to + /// strong. + InlineVariableDefinitionKind + getInlineVariableDefinitionKind(const VarDecl *VD) const; + private: const ASTRecordLayout & getObjCLayout(const ObjCInterfaceDecl *D, diff --git a/include/clang/AST/ASTImporter.h b/include/clang/AST/ASTImporter.h index ee48955ca6362..e116abaef7970 100644 --- a/include/clang/AST/ASTImporter.h +++ b/include/clang/AST/ASTImporter.h @@ -23,6 +23,7 @@ namespace clang { class ASTContext; + class CXXCtorInitializer; class Decl; class DeclContext; class DiagnosticsEngine; @@ -204,6 +205,14 @@ namespace clang { /// \returns the equivalent file ID in the source manager of the "to" /// context. FileID Import(FileID); + + /// \brief Import the given C++ constructor initializer from the "from" + /// context into the "to" context. + /// + /// \returns the equivalent initializer in the "to" context. + CXXCtorInitializer *Import(CXXCtorInitializer *FromInit); + + /// \brief Import the definition of the given declaration, including all of /// the declarations it contains. diff --git a/include/clang/AST/ASTMutationListener.h b/include/clang/AST/ASTMutationListener.h index cf3b55d7b2c74..e2d184d654e3a 100644 --- a/include/clang/AST/ASTMutationListener.h +++ b/include/clang/AST/ASTMutationListener.h @@ -17,6 +17,7 @@ namespace clang { class Attr; class ClassTemplateDecl; class ClassTemplateSpecializationDecl; + class ConstructorUsingShadowDecl; class CXXDestructorDecl; class CXXRecordDecl; class Decl; @@ -107,6 +108,14 @@ public: /// \param D the declaration marked OpenMP threadprivate. virtual void DeclarationMarkedOpenMPThreadPrivate(const Decl *D) {} + /// \brief A declaration is marked as OpenMP declaretarget which was not + /// previously marked as declaretarget. + /// + /// \param D the declaration marked OpenMP declaretarget. + /// \param Attr the added attribute. + virtual void DeclarationMarkedOpenMPDeclareTarget(const Decl *D, + const Attr *Attr) {} + /// \brief A definition has been made visible by being redefined locally. /// /// \param D The definition that was previously not visible. diff --git a/include/clang/AST/ASTTypeTraits.h b/include/clang/AST/ASTTypeTraits.h index dcaac802c110a..ad301b14829e5 100644 --- a/include/clang/AST/ASTTypeTraits.h +++ b/include/clang/AST/ASTTypeTraits.h @@ -62,7 +62,9 @@ public: /// \} /// \brief Returns \c true if \c this and \c Other represent the same kind. - bool isSame(ASTNodeKind Other) const; + bool isSame(ASTNodeKind Other) const { + return KindId != NKI_None && KindId == Other.KindId; + } /// \brief Returns \c true only for the default \c ASTNodeKind() bool isNone() const { return KindId == NKI_None; } diff --git a/include/clang/AST/Attr.h b/include/clang/AST/Attr.h index 8b80e9f6396ec..a94b161a04bc8 100644 --- a/include/clang/AST/Attr.h +++ b/include/clang/AST/Attr.h @@ -20,6 +20,7 @@ #include "clang/AST/Type.h" #include "clang/Basic/AttrKinds.h" #include "clang/Basic/LLVM.h" +#include "clang/Basic/OpenMPKinds.h" #include "clang/Basic/Sanitizers.h" #include "clang/Basic/SourceLocation.h" #include "clang/Basic/VersionTuple.h" @@ -50,11 +51,11 @@ protected: /// An index into the spelling list of an /// attribute defined in Attr.td file. unsigned SpellingListIndex : 4; - bool Inherited : 1; - bool IsPackExpansion : 1; - bool Implicit : 1; - bool IsLateParsed : 1; - bool DuplicatesAllowed : 1; + unsigned Inherited : 1; + unsigned IsPackExpansion : 1; + unsigned Implicit : 1; + unsigned IsLateParsed : 1; + unsigned DuplicatesAllowed : 1; void *operator new(size_t bytes) LLVM_NOEXCEPT { llvm_unreachable("Attrs cannot be allocated with regular 'new'."); @@ -118,6 +119,19 @@ public: bool duplicatesAllowed() const { return DuplicatesAllowed; } }; +class StmtAttr : public Attr { +protected: + StmtAttr(attr::Kind AK, SourceRange R, unsigned SpellingListIndex, + bool IsLateParsed, bool DuplicatesAllowed) + : Attr(AK, R, SpellingListIndex, IsLateParsed, DuplicatesAllowed) {} + +public: + static bool classof(const Attr *A) { + return A->getKind() >= attr::FirstStmtAttr && + A->getKind() <= attr::LastStmtAttr; + } +}; + class InheritableAttr : public Attr { protected: InheritableAttr(attr::Kind AK, SourceRange R, unsigned SpellingListIndex, @@ -129,7 +143,8 @@ public: // Implement isa/cast/dyncast/etc. static bool classof(const Attr *A) { - return A->getKind() <= attr::LAST_INHERITABLE; + return A->getKind() >= attr::FirstInheritableAttr && + A->getKind() <= attr::LastInheritableAttr; } }; @@ -143,12 +158,41 @@ protected: public: // Implement isa/cast/dyncast/etc. static bool classof(const Attr *A) { - // Relies on relative order of enum emission with respect to MS inheritance - // attrs. - return A->getKind() <= attr::LAST_INHERITABLE_PARAM; + return A->getKind() >= attr::FirstInheritableParamAttr && + A->getKind() <= attr::LastInheritableParamAttr; } }; +/// A parameter attribute which changes the argument-passing ABI rule +/// for the parameter. +class ParameterABIAttr : public InheritableParamAttr { +protected: + ParameterABIAttr(attr::Kind AK, SourceRange R, + unsigned SpellingListIndex, bool IsLateParsed, + bool DuplicatesAllowed) + : InheritableParamAttr(AK, R, SpellingListIndex, IsLateParsed, + DuplicatesAllowed) {} + +public: + ParameterABI getABI() const { + switch (getKind()) { + case attr::SwiftContext: + return ParameterABI::SwiftContext; + case attr::SwiftErrorResult: + return ParameterABI::SwiftErrorResult; + case attr::SwiftIndirectResult: + return ParameterABI::SwiftIndirectResult; + default: + llvm_unreachable("bad parameter ABI attribute kind"); + } + } + + static bool classof(const Attr *A) { + return A->getKind() >= attr::FirstParameterABIAttr && + A->getKind() <= attr::LastParameterABIAttr; + } +}; + #include "clang/AST/Attrs.inc" inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, diff --git a/include/clang/AST/Availability.h b/include/clang/AST/Availability.h new file mode 100644 index 0000000000000..5ed8313784567 --- /dev/null +++ b/include/clang/AST/Availability.h @@ -0,0 +1,63 @@ +//===--- Availability.h - Classes for availability --------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This files defines some classes that implement availability checking. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_AST_AVAILABILITY_H +#define LLVM_CLANG_AST_AVAILABILITY_H + +#include "clang/Basic/SourceLocation.h" +#include "clang/Basic/VersionTuple.h" +#include "llvm/ADT/StringRef.h" + +namespace clang { + +/// \brief One specifier in an @available expression. +/// +/// \code +/// @available(macos 10.10, *) +/// \endcode +/// +/// Here, 'macos 10.10' and '*' both map to an instance of this type. +/// +class AvailabilitySpec { + /// Represents the version that this specifier requires. If the host OS + /// version is greater than or equal to Version, the @available will evaluate + /// to true. + VersionTuple Version; + + /// Name of the platform that Version corresponds to. + StringRef Platform; + + SourceLocation BeginLoc, EndLoc; + +public: + AvailabilitySpec(VersionTuple Version, StringRef Platform, + SourceLocation BeginLoc, SourceLocation EndLoc) + : Version(Version), Platform(Platform), BeginLoc(BeginLoc), + EndLoc(EndLoc) {} + + /// This constructor is used when representing the '*' case. + AvailabilitySpec(SourceLocation StarLoc) + : BeginLoc(StarLoc), EndLoc(StarLoc) {} + + VersionTuple getVersion() const { return Version; } + StringRef getPlatform() const { return Platform; } + SourceLocation getBeginLoc() const { return BeginLoc; } + SourceLocation getEndLoc() const { return EndLoc; } + + /// Returns true when this represents the '*' case. + bool isOtherPlatformSpec() const { return Version.empty(); } +}; + +} // end namespace clang + +#endif diff --git a/include/clang/AST/BaseSubobject.h b/include/clang/AST/BaseSubobject.h index da538e3566a7a..66af023c828e4 100644 --- a/include/clang/AST/BaseSubobject.h +++ b/include/clang/AST/BaseSubobject.h @@ -15,13 +15,12 @@ #define LLVM_CLANG_AST_BASESUBOBJECT_H #include "clang/AST/CharUnits.h" +#include "clang/AST/DeclCXX.h" #include "llvm/ADT/DenseMap.h" #include "llvm/Support/DataTypes.h" #include "llvm/Support/type_traits.h" namespace clang { - class CXXRecordDecl; - // BaseSubobject - Uniquely identifies a direct or indirect base class. // Stores both the base class decl and the offset from the most derived class to // the base class. Used for vtable and VTT generation. diff --git a/include/clang/AST/BuiltinTypes.def b/include/clang/AST/BuiltinTypes.def index a08a6839024b4..c0c6819280d24 100644 --- a/include/clang/AST/BuiltinTypes.def +++ b/include/clang/AST/BuiltinTypes.def @@ -133,6 +133,9 @@ FLOATING_TYPE(Double, DoubleTy) // 'long double' FLOATING_TYPE(LongDouble, LongDoubleTy) +// '__float128' +FLOATING_TYPE(Float128, Float128Ty) + //===- Language-specific types --------------------------------------------===// // This is the type of C++0x 'nullptr'. @@ -154,20 +157,6 @@ BUILTIN_TYPE(ObjCClass, ObjCBuiltinClassTy) // type is a typedef of a PointerType to this. BUILTIN_TYPE(ObjCSel, ObjCBuiltinSelTy) -// OpenCL image types. -BUILTIN_TYPE(OCLImage1d, OCLImage1dTy) -BUILTIN_TYPE(OCLImage1dArray, OCLImage1dArrayTy) -BUILTIN_TYPE(OCLImage1dBuffer, OCLImage1dBufferTy) -BUILTIN_TYPE(OCLImage2d, OCLImage2dTy) -BUILTIN_TYPE(OCLImage2dArray, OCLImage2dArrayTy) -BUILTIN_TYPE(OCLImage2dDepth, OCLImage2dDepthTy) -BUILTIN_TYPE(OCLImage2dArrayDepth, OCLImage2dArrayDepthTy) -BUILTIN_TYPE(OCLImage2dMSAA, OCLImage2dMSAATy) -BUILTIN_TYPE(OCLImage2dArrayMSAA, OCLImage2dArrayMSAATy) -BUILTIN_TYPE(OCLImage2dMSAADepth, OCLImage2dMSAADepthTy) -BUILTIN_TYPE(OCLImage2dArrayMSAADepth, OCLImage2dArrayMSAADepthTy) -BUILTIN_TYPE(OCLImage3d, OCLImage3dTy) - // OpenCL sampler_t. BUILTIN_TYPE(OCLSampler, OCLSamplerTy) diff --git a/include/clang/AST/CanonicalType.h b/include/clang/AST/CanonicalType.h index b25800bfedb91..77510afeec1b9 100644 --- a/include/clang/AST/CanonicalType.h +++ b/include/clang/AST/CanonicalType.h @@ -484,6 +484,9 @@ struct CanProxyAdaptor<FunctionProtoType> LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getReturnType) LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(FunctionType::ExtInfo, getExtInfo) LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumParams) + 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)); } diff --git a/include/clang/AST/CharUnits.h b/include/clang/AST/CharUnits.h index 1d22bccd2e896..564c8ec9b9ea0 100644 --- a/include/clang/AST/CharUnits.h +++ b/include/clang/AST/CharUnits.h @@ -133,7 +133,7 @@ namespace clang { /// Test whether this is a multiple of the other value. /// /// Among other things, this promises that - /// self.RoundUpToAlignment(N) will just return self. + /// self.alignTo(N) will just return self. bool isMultipleOf(CharUnits N) const { return (*this % N) == 0; } @@ -142,9 +142,17 @@ namespace clang { CharUnits operator* (QuantityType N) const { return CharUnits(Quantity * N); } + CharUnits &operator*= (QuantityType N) { + Quantity *= N; + return *this; + } CharUnits operator/ (QuantityType N) const { return CharUnits(Quantity / N); } + CharUnits &operator/= (QuantityType N) { + Quantity /= N; + return *this; + } QuantityType operator/ (const CharUnits &Other) const { return Quantity / Other.Quantity; } @@ -170,12 +178,11 @@ namespace clang { /// getQuantity - Get the raw integer representation of this quantity. QuantityType getQuantity() const { return Quantity; } - /// RoundUpToAlignment - Returns the next integer (mod 2**64) that is + /// alignTo - Returns the next integer (mod 2**64) that is /// greater than or equal to this quantity and is a multiple of \p Align. /// Align must be non-zero. - CharUnits RoundUpToAlignment(const CharUnits &Align) const { - return CharUnits(llvm::RoundUpToAlignment(Quantity, - Align.Quantity)); + CharUnits alignTo(const CharUnits &Align) const { + return CharUnits(llvm::alignTo(Quantity, Align.Quantity)); } /// Given that this is a non-zero alignment value, what is the diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h index 029c1182f26e6..109036f9588ea 100644 --- a/include/clang/AST/Decl.h +++ b/include/clang/AST/Decl.h @@ -23,6 +23,7 @@ #include "clang/Basic/Linkage.h" #include "clang/Basic/Module.h" #include "clang/Basic/OperatorKinds.h" +#include "clang/Basic/PragmaKinds.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/Optional.h" #include "llvm/Support/Compiler.h" @@ -103,6 +104,73 @@ public: } }; +/// \brief Represents a `#pragma comment` line. Always a child of +/// TranslationUnitDecl. +class PragmaCommentDecl final + : public Decl, + private llvm::TrailingObjects<PragmaCommentDecl, char> { + virtual void anchor(); + + PragmaMSCommentKind CommentKind; + + friend TrailingObjects; + friend class ASTDeclReader; + friend class ASTDeclWriter; + + PragmaCommentDecl(TranslationUnitDecl *TU, SourceLocation CommentLoc, + PragmaMSCommentKind CommentKind) + : Decl(PragmaComment, TU, CommentLoc), CommentKind(CommentKind) {} + +public: + static PragmaCommentDecl *Create(const ASTContext &C, TranslationUnitDecl *DC, + SourceLocation CommentLoc, + PragmaMSCommentKind CommentKind, + StringRef Arg); + static PragmaCommentDecl *CreateDeserialized(ASTContext &C, unsigned ID, + unsigned ArgSize); + + PragmaMSCommentKind getCommentKind() const { return CommentKind; } + + StringRef getArg() const { return getTrailingObjects<char>(); } + + // Implement isa/cast/dyncast/etc. + static bool classof(const Decl *D) { return classofKind(D->getKind()); } + static bool classofKind(Kind K) { return K == PragmaComment; } +}; + +/// \brief Represents a `#pragma detect_mismatch` line. Always a child of +/// TranslationUnitDecl. +class PragmaDetectMismatchDecl final + : public Decl, + private llvm::TrailingObjects<PragmaDetectMismatchDecl, char> { + virtual void anchor(); + + size_t ValueStart; + + friend TrailingObjects; + friend class ASTDeclReader; + friend class ASTDeclWriter; + + PragmaDetectMismatchDecl(TranslationUnitDecl *TU, SourceLocation Loc, + size_t ValueStart) + : Decl(PragmaDetectMismatch, TU, Loc), ValueStart(ValueStart) {} + +public: + static PragmaDetectMismatchDecl *Create(const ASTContext &C, + TranslationUnitDecl *DC, + SourceLocation Loc, StringRef Name, + StringRef Value); + static PragmaDetectMismatchDecl * + CreateDeserialized(ASTContext &C, unsigned ID, unsigned NameValueSize); + + StringRef getName() const { return getTrailingObjects<char>(); } + StringRef getValue() const { return getTrailingObjects<char>() + ValueStart; } + + // Implement isa/cast/dyncast/etc. + static bool classof(const Decl *D) { return classofKind(D->getKind()); } + static bool classofKind(Kind K) { return K == PragmaDetectMismatch; } +}; + /// \brief Declaration context for names declared as extern "C" in C++. This /// is neither the semantic nor lexical context for such declarations, but is /// used to check for conflicts with other extern "C" declarations. Example: @@ -319,6 +387,7 @@ public: NamedDecl *getUnderlyingDecl() { // Fast-path the common case. if (this->getKind() != UsingShadow && + this->getKind() != ConstructorUsingShadow && this->getKind() != ObjCCompatibleAlias && this->getKind() != NamespaceAlias) return this; @@ -813,12 +882,15 @@ protected: /// variable; see isARCPseudoStrong() for details. unsigned ARCPseudoStrong : 1; + /// \brief Whether this variable is (C++1z) inline. + unsigned IsInline : 1; + + /// \brief Whether this variable has (C++1z) inline explicitly specified. + unsigned IsInlineSpecified : 1; + /// \brief Whether this variable is (C++0x) constexpr. unsigned IsConstexpr : 1; - /// \brief Whether this variable is a (C++ Concepts TS) concept. - unsigned IsConcept : 1; - /// \brief Whether this variable is the implicit variable for a lambda /// init-capture. unsigned IsInitCapture : 1; @@ -1037,9 +1109,6 @@ public: /// definition of a static data member. bool isOutOfLine() const override; - /// \brief If this is a static data member, find its out-of-line definition. - VarDecl *getOutOfLineDefinition(); - /// isFileVarDecl - Returns true for file scoped variable declaration. bool isFileVarDecl() const { Kind K = getKind(); @@ -1185,6 +1254,24 @@ public: NonParmVarDeclBits.ARCPseudoStrong = ps; } + /// Whether this variable is (C++1z) inline. + bool isInline() const { + return isa<ParmVarDecl>(this) ? false : NonParmVarDeclBits.IsInline; + } + bool isInlineSpecified() const { + return isa<ParmVarDecl>(this) ? false + : NonParmVarDeclBits.IsInlineSpecified; + } + void setInlineSpecified() { + assert(!isa<ParmVarDecl>(this)); + NonParmVarDeclBits.IsInline = true; + NonParmVarDeclBits.IsInlineSpecified = true; + } + void setImplicitlyInline() { + assert(!isa<ParmVarDecl>(this)); + NonParmVarDeclBits.IsInline = true; + } + /// Whether this variable is (C++11) constexpr. bool isConstexpr() const { return isa<ParmVarDecl>(this) ? false : NonParmVarDeclBits.IsConstexpr; @@ -1194,15 +1281,6 @@ public: NonParmVarDeclBits.IsConstexpr = IC; } - /// Whether this variable is (C++ Concepts TS) concept. - bool isConcept() const { - return isa<ParmVarDecl>(this) ? false : NonParmVarDeclBits.IsConcept; - } - void setConcept(bool IC) { - assert(!isa<ParmVarDecl>(this)); - NonParmVarDeclBits.IsConcept = IC; - } - /// Whether this variable is the implicit variable for a lambda init-capture. bool isInitCapture() const { return isa<ParmVarDecl>(this) ? false : NonParmVarDeclBits.IsInitCapture; @@ -1702,6 +1780,17 @@ public: return isDefined(Definition); } + /// \brief Get the definition for this declaration. + FunctionDecl *getDefinition() { + const FunctionDecl *Definition; + if (isDefined(Definition)) + return const_cast<FunctionDecl *>(Definition); + return nullptr; + } + const FunctionDecl *getDefinition() const { + return const_cast<FunctionDecl *>(this)->getDefinition(); + } + /// getBody - Retrieve the body (definition) of the function. The /// function body might be in any of the (re-)declarations of this /// function. The variant that accepts a FunctionDecl pointer will @@ -1896,29 +1985,24 @@ public: unsigned getBuiltinID() const; - // Iterator access to formal parameters. - unsigned param_size() const { return getNumParams(); } - typedef ParmVarDecl **param_iterator; - typedef ParmVarDecl * const *param_const_iterator; - typedef llvm::iterator_range<param_iterator> param_range; - typedef llvm::iterator_range<param_const_iterator> param_const_range; - - param_iterator param_begin() { return param_iterator(ParamInfo); } - param_iterator param_end() { - return param_iterator(ParamInfo + param_size()); - } - param_range params() { return param_range(param_begin(), param_end()); } - - param_const_iterator param_begin() const { - return param_const_iterator(ParamInfo); + // ArrayRef interface to parameters. + ArrayRef<ParmVarDecl *> parameters() const { + return {ParamInfo, getNumParams()}; } - param_const_iterator param_end() const { - return param_const_iterator(ParamInfo + param_size()); - } - param_const_range params() const { - return param_const_range(param_begin(), param_end()); + MutableArrayRef<ParmVarDecl *> parameters() { + return {ParamInfo, getNumParams()}; } + // Iterator access to formal parameters. + typedef MutableArrayRef<ParmVarDecl *>::iterator param_iterator; + typedef ArrayRef<ParmVarDecl *>::const_iterator param_const_iterator; + bool param_empty() const { return parameters().empty(); } + param_iterator param_begin() { return parameters().begin(); } + param_iterator param_end() { return parameters().end(); } + param_const_iterator param_begin() const { return parameters().begin(); } + param_const_iterator param_end() const { return parameters().end(); } + size_t param_size() const { return parameters().size(); } + /// getNumParams - Return the number of parameters this function must have /// based on its FunctionType. This is the length of the ParamInfo array /// after it has been created. @@ -1936,12 +2020,6 @@ public: setParams(getASTContext(), NewParamInfo); } - // ArrayRef iterface to parameters. - // FIXME: Should one day replace iterator interface. - ArrayRef<ParmVarDecl*> parameters() const { - return llvm::makeArrayRef(ParamInfo, getNumParams()); - } - ArrayRef<NamedDecl *> getDeclsInPrototypeScope() const { return DeclsInPrototypeScope; } @@ -1954,6 +2032,7 @@ public: unsigned getMinRequiredArguments() const; QualType getReturnType() const { + assert(getType()->getAs<FunctionType>() && "Expected a FunctionType!"); return getType()->getAs<FunctionType>()->getReturnType(); } @@ -1964,15 +2043,20 @@ public: /// \brief Determine the type of an expression that calls this function. QualType getCallResultType() const { + assert(getType()->getAs<FunctionType>() && "Expected a FunctionType!"); return getType()->getAs<FunctionType>()->getCallResultType(getASTContext()); } + /// \brief Returns the WarnUnusedResultAttr that is either declared on this + /// function, or its return type declaration. + const Attr *getUnusedResultAttr() const; + /// \brief Returns true if this function or its return type has the /// warn_unused_result attribute. If the return type has the attribute and /// this function is a method of the return type's class, then false will be /// returned to avoid spurious warnings on member methods such as assignment /// operators. - bool hasUnusedResultAttr() const; + bool hasUnusedResultAttr() const { return getUnusedResultAttr() != nullptr; } /// \brief Returns the storage class as written in the source. For the /// computed linkage of symbol, see getLinkage. @@ -2208,7 +2292,7 @@ public: /// represent a member of a struct/union/class. class FieldDecl : public DeclaratorDecl, public Mergeable<FieldDecl> { // FIXME: This can be packed into the bitfields in Decl. - bool Mutable : 1; + unsigned Mutable : 1; mutable unsigned CachedFieldIndex : 31; /// The kinds of value we can store in InitializerOrBitWidth. @@ -2442,34 +2526,33 @@ class IndirectFieldDecl : public ValueDecl, IndirectFieldDecl(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName N, QualType T, - NamedDecl **CH, unsigned CHS); + MutableArrayRef<NamedDecl *> CH); public: static IndirectFieldDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L, IdentifierInfo *Id, - QualType T, NamedDecl **CH, unsigned CHS); + QualType T, llvm::MutableArrayRef<NamedDecl *> CH); static IndirectFieldDecl *CreateDeserialized(ASTContext &C, unsigned ID); - - typedef NamedDecl * const *chain_iterator; - typedef llvm::iterator_range<chain_iterator> chain_range; - chain_range chain() const { return chain_range(chain_begin(), chain_end()); } - chain_iterator chain_begin() const { return chain_iterator(Chaining); } - chain_iterator chain_end() const { - return chain_iterator(Chaining + ChainingSize); + typedef ArrayRef<NamedDecl *>::const_iterator chain_iterator; + + ArrayRef<NamedDecl *> chain() const { + return llvm::makeArrayRef(Chaining, ChainingSize); } + chain_iterator chain_begin() const { return chain().begin(); } + chain_iterator chain_end() const { return chain().end(); } unsigned getChainingSize() const { return ChainingSize; } FieldDecl *getAnonField() const { - assert(ChainingSize >= 2); - return cast<FieldDecl>(Chaining[ChainingSize - 1]); + assert(chain().size() >= 2); + return cast<FieldDecl>(chain().back()); } VarDecl *getVarDecl() const { - assert(ChainingSize >= 2); - return dyn_cast<VarDecl>(*chain_begin()); + assert(chain().size() >= 2); + return dyn_cast<VarDecl>(chain().front()); } IndirectFieldDecl *getCanonicalDecl() override { return getFirstDecl(); } @@ -2655,20 +2738,20 @@ private: /// IsCompleteDefinition - True if this is a definition ("struct foo /// {};"), false if it is a declaration ("struct foo;"). It is not /// a definition until the definition has been fully processed. - bool IsCompleteDefinition : 1; + unsigned IsCompleteDefinition : 1; protected: /// IsBeingDefined - True if this is currently being defined. - bool IsBeingDefined : 1; + unsigned IsBeingDefined : 1; private: /// IsEmbeddedInDeclarator - True if this tag declaration is /// "embedded" (i.e., defined or declared for the very first time) /// in the syntax of a declarator. - bool IsEmbeddedInDeclarator : 1; + unsigned IsEmbeddedInDeclarator : 1; /// \brief True if this tag is free standing, e.g. "struct foo;". - bool IsFreeStanding : 1; + unsigned IsFreeStanding : 1; protected: // These are used by (and only defined for) EnumDecl. @@ -2677,28 +2760,28 @@ protected: /// IsScoped - True if this tag declaration is a scoped enumeration. Only /// possible in C++11 mode. - bool IsScoped : 1; + unsigned IsScoped : 1; /// IsScopedUsingClassTag - If this tag declaration is a scoped enum, /// then this is true if the scoped enum was declared using the class /// tag, false if it was declared with the struct tag. No meaning is /// associated if this tag declaration is not a scoped enum. - bool IsScopedUsingClassTag : 1; + unsigned IsScopedUsingClassTag : 1; /// IsFixed - True if this is an enumeration with fixed underlying type. Only /// possible in C++11, Microsoft extensions, or Objective C mode. - bool IsFixed : 1; + unsigned IsFixed : 1; /// \brief Indicates whether it is possible for declarations of this kind /// to have an out-of-date definition. /// /// This option is only enabled when modules are enabled. - bool MayHaveOutOfDateDef : 1; + unsigned MayHaveOutOfDateDef : 1; /// Has the full definition of this type been required by a use somewhere in /// the TU. - bool IsCompleteDefinitionRequired : 1; + unsigned IsCompleteDefinitionRequired : 1; private: - SourceLocation RBraceLoc; + SourceRange BraceRange; // A struct representing syntactic qualifier info, // to be used for the (uncommon) case of out-of-line declarations. @@ -2760,8 +2843,8 @@ public: using redeclarable_base::getMostRecentDecl; using redeclarable_base::isFirstDecl; - SourceLocation getRBraceLoc() const { return RBraceLoc; } - void setRBraceLoc(SourceLocation L) { RBraceLoc = L; } + SourceRange getBraceRange() const { return BraceRange; } + void setBraceRange(SourceRange R) { BraceRange = R; } /// getInnerLocStart - Return SourceLocation representing start of source /// range ignoring outer template declarations. @@ -3122,6 +3205,10 @@ public: return isCompleteDefinition() || isFixed(); } + /// \brief Retrieve the enum definition from which this enumeration could + /// be instantiated, if it is an instantiation (rather than a non-template). + EnumDecl *getTemplateInstantiationPattern() const; + /// \brief Returns the enumeration (declared within the template) /// from which this enumeration type was instantiated, or NULL if /// this enumeration was not instantiated from any template. @@ -3452,35 +3539,23 @@ public: void setSignatureAsWritten(TypeSourceInfo *Sig) { SignatureAsWritten = Sig; } TypeSourceInfo *getSignatureAsWritten() const { return SignatureAsWritten; } - // Iterator access to formal parameters. - unsigned param_size() const { return getNumParams(); } - typedef ParmVarDecl **param_iterator; - typedef ParmVarDecl * const *param_const_iterator; - typedef llvm::iterator_range<param_iterator> param_range; - typedef llvm::iterator_range<param_const_iterator> param_const_range; - // ArrayRef access to formal parameters. - // FIXME: Should eventual replace iterator access. - ArrayRef<ParmVarDecl*> parameters() const { - return llvm::makeArrayRef(ParamInfo, param_size()); + ArrayRef<ParmVarDecl *> parameters() const { + return {ParamInfo, getNumParams()}; } - - bool param_empty() const { return NumParams == 0; } - param_range params() { return param_range(param_begin(), param_end()); } - param_iterator param_begin() { return param_iterator(ParamInfo); } - param_iterator param_end() { - return param_iterator(ParamInfo + param_size()); + MutableArrayRef<ParmVarDecl *> parameters() { + return {ParamInfo, getNumParams()}; } - param_const_range params() const { - return param_const_range(param_begin(), param_end()); - } - param_const_iterator param_begin() const { - return param_const_iterator(ParamInfo); - } - param_const_iterator param_end() const { - return param_const_iterator(ParamInfo + param_size()); - } + // Iterator access to formal parameters. + typedef MutableArrayRef<ParmVarDecl *>::iterator param_iterator; + typedef ArrayRef<ParmVarDecl *>::const_iterator param_const_iterator; + bool param_empty() const { return parameters().empty(); } + param_iterator param_begin() { return parameters().begin(); } + param_iterator param_end() { return parameters().end(); } + param_const_iterator param_begin() const { return parameters().begin(); } + param_const_iterator param_end() const { return parameters().end(); } + size_t param_size() const { return parameters().size(); } unsigned getNumParams() const { return NumParams; } const ParmVarDecl *getParamDecl(unsigned i) const { @@ -3501,22 +3576,12 @@ public: /// Does not include an entry for 'this'. unsigned getNumCaptures() const { return NumCaptures; } - typedef const Capture *capture_iterator; - typedef const Capture *capture_const_iterator; - typedef llvm::iterator_range<capture_iterator> capture_range; - typedef llvm::iterator_range<capture_const_iterator> capture_const_range; + typedef ArrayRef<Capture>::const_iterator capture_const_iterator; - capture_range captures() { - return capture_range(capture_begin(), capture_end()); - } - capture_const_range captures() const { - return capture_const_range(capture_begin(), capture_end()); - } + ArrayRef<Capture> captures() const { return {Captures, NumCaptures}; } - capture_iterator capture_begin() { return Captures; } - capture_iterator capture_end() { return Captures + NumCaptures; } - capture_const_iterator capture_begin() const { return Captures; } - capture_const_iterator capture_end() const { return Captures + NumCaptures; } + capture_const_iterator capture_begin() const { return captures().begin(); } + capture_const_iterator capture_end() const { return captures().end(); } bool capturesCXXThis() const { return CapturesCXXThis; } bool blockMissingReturnType() const { return BlockMissingReturnType; } @@ -3607,6 +3672,14 @@ public: getParams()[i] = P; } + // ArrayRef interface to parameters. + ArrayRef<ImplicitParamDecl *> parameters() const { + return {getParams(), getNumParams()}; + } + MutableArrayRef<ImplicitParamDecl *> parameters() { + return {getParams(), getNumParams()}; + } + /// \brief Retrieve the parameter containing captured variables. ImplicitParamDecl *getContextParam() const { assert(ContextParam < NumParams); @@ -3627,9 +3700,6 @@ public: /// \brief Retrieve an iterator one past the last parameter decl. param_iterator param_end() const { return getParams() + NumParams; } - /// \brief Retrieve an iterator range for the parameter declarations. - param_range params() const { return param_range(param_begin(), param_end()); } - // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K == Captured; } diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h index 2d6e84a68aa5b..ec8bb3aaa305e 100644 --- a/include/clang/AST/DeclBase.h +++ b/include/clang/AST/DeclBase.h @@ -52,6 +52,7 @@ struct PrintingPolicy; class RecordDecl; class Stmt; class StoredDeclsMap; +class TemplateDecl; class TranslationUnitDecl; class UsingDirectiveDecl; } @@ -72,13 +73,10 @@ namespace clang { /// /// Note: There are objects tacked on before the *beginning* of Decl /// (and its subclasses) in its Decl::operator new(). Proper alignment -/// of all subclasses (not requiring more than DeclObjAlignment) is +/// of all subclasses (not requiring more than the alignment of Decl) is /// asserted in DeclBase.cpp. -class Decl { +class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) Decl { public: - /// \brief Alignment guaranteed when allocating Decl and any subtypes. - enum { DeclObjAlignment = llvm::AlignOf<uint64_t>::Alignment }; - /// \brief Lists the kind of concrete classes of Decl. enum Kind { #define DECL(DERIVED, BASE) DERIVED, @@ -166,7 +164,10 @@ public: /// has been declared outside any function. These act mostly like /// invisible friend declarations, but are also visible to unqualified /// lookup within the scope of the declaring function. - IDNS_LocalExtern = 0x0800 + IDNS_LocalExtern = 0x0800, + + /// This declaration is an OpenMP user defined reduction construction. + IDNS_OMPReduction = 0x1000 }; /// ObjCDeclQualifier - 'Qualifiers' written next to the return and @@ -256,7 +257,7 @@ private: SourceLocation Loc; /// DeclKind - This indicates which class this is. - unsigned DeclKind : 8; + unsigned DeclKind : 7; /// InvalidDecl - This indicates a semantic error occurred. unsigned InvalidDecl : 1; @@ -296,7 +297,7 @@ protected: unsigned Hidden : 1; /// IdentifierNamespace - This specifies what IDNS_* namespace this lives in. - unsigned IdentifierNamespace : 12; + unsigned IdentifierNamespace : 13; /// \brief If 0, we have not computed the linkage of this declaration. /// Otherwise, it is the linkage + 1. @@ -514,8 +515,8 @@ public: bool isImplicit() const { return Implicit; } void setImplicit(bool I = true) { Implicit = I; } - /// \brief Whether this declaration was used, meaning that a definition - /// is required. + /// \brief Whether *any* (re-)declaration of the entity was used, meaning that + /// a definition is required. /// /// \param CheckUsedAttr When true, also consider the "used" attribute /// (in addition to the "used" bit set by \c setUsed()) when determining @@ -525,7 +526,8 @@ public: /// \brief Set whether the declaration is used, in the sense of odr-use. /// /// This should only be used immediately after creating a declaration. - void setIsUsed() { Used = true; } + /// It intentionally doesn't notify any listeners. + void setIsUsed() { getCanonicalDecl()->Used = true; } /// \brief Mark the declaration used, in the sense of odr-use. /// @@ -564,6 +566,13 @@ public: return NextInContextAndBits.getInt() & ModulePrivateFlag; } + /// Return true if this declaration has an attribute which acts as + /// definition of the entity, such as 'alias' or 'ifunc'. + bool hasDefiningAttr() const; + + /// Return this declaration's defining attribute if it has one. + const Attr *getDefiningAttr() const; + protected: /// \brief Specify whether this declaration was marked as being private /// to the module in which it was defined. @@ -895,6 +904,10 @@ public: DeclKind == FunctionTemplate; } + /// \brief If this is a declaration that describes some template, this + /// method returns that template declaration. + TemplateDecl *getDescribedTemplate() const; + /// \brief Returns the function itself, or the templated function if this is a /// function template. FunctionDecl *getAsFunction() LLVM_READONLY; @@ -1117,6 +1130,7 @@ public: /// ObjCContainerDecl /// LinkageSpecDecl /// BlockDecl +/// OMPDeclareReductionDecl /// class DeclContext { /// DeclKind - This indicates which class this is. diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h index 7c54901be3ea5..66acfee60db05 100644 --- a/include/clang/AST/DeclCXX.h +++ b/include/clang/AST/DeclCXX.h @@ -16,6 +16,7 @@ #ifndef LLVM_CLANG_AST_DECLCXX_H #define LLVM_CLANG_AST_DECLCXX_H +#include "clang/AST/ASTContext.h" #include "clang/AST/ASTUnresolvedSet.h" #include "clang/AST/Attr.h" #include "clang/AST/Decl.h" @@ -29,6 +30,7 @@ namespace clang { class ClassTemplateDecl; class ClassTemplateSpecializationDecl; +class ConstructorUsingShadowDecl; class CXXBasePath; class CXXBasePaths; class CXXConstructorDecl; @@ -165,13 +167,13 @@ class CXXBaseSpecifier { SourceLocation EllipsisLoc; /// \brief Whether this is a virtual base class or not. - bool Virtual : 1; + unsigned Virtual : 1; /// \brief Whether this is the base of a class (true) or of a struct (false). /// /// This determines the mapping from the access specifier as written in the /// source code to the access specifier used for semantic analysis. - bool BaseOfClass : 1; + unsigned BaseOfClass : 1; /// \brief Access specifier as written in the source code (may be AS_none). /// @@ -181,7 +183,7 @@ class CXXBaseSpecifier { /// \brief Whether the class contains a using declaration /// to inherit the named class's constructors. - bool InheritConstructors : 1; + unsigned InheritConstructors : 1; /// \brief The type of the base class. /// @@ -257,30 +259,6 @@ public: TypeSourceInfo *getTypeSourceInfo() const { return BaseTypeInfo; } }; -/// \brief A lazy pointer to the definition data for a declaration. -/// FIXME: This is a little CXXRecordDecl-specific that the moment. -template<typename Decl, typename T> class LazyDefinitionDataPtr { - llvm::PointerUnion<T *, Decl *> DataOrCanonicalDecl; - - LazyDefinitionDataPtr update() { - if (Decl *Canon = DataOrCanonicalDecl.template dyn_cast<Decl*>()) { - if (Canon->isCanonicalDecl()) - Canon->getMostRecentDecl(); - else - // Declaration isn't canonical any more; - // update it and perform path compression. - *this = Canon->getPreviousDecl()->DefinitionData.update(); - } - return *this; - } - -public: - LazyDefinitionDataPtr(Decl *Canon) : DataOrCanonicalDecl(Canon) {} - LazyDefinitionDataPtr(T *Data) : DataOrCanonicalDecl(Data) {} - T *getNotUpdated() { return DataOrCanonicalDecl.template dyn_cast<T*>(); } - T *get() { return update().getNotUpdated(); } -}; - /// \brief Represents a C++ struct/union/class. class CXXRecordDecl : public RecordDecl { @@ -301,30 +279,30 @@ class CXXRecordDecl : public RecordDecl { DefinitionData(CXXRecordDecl *D); /// \brief True if this class has any user-declared constructors. - bool UserDeclaredConstructor : 1; + unsigned UserDeclaredConstructor : 1; /// \brief The user-declared special members which this class has. unsigned UserDeclaredSpecialMembers : 6; /// \brief True when this class is an aggregate. - bool Aggregate : 1; + unsigned Aggregate : 1; /// \brief True when this class is a POD-type. - bool PlainOldData : 1; + unsigned PlainOldData : 1; /// true when this class is empty for traits purposes, /// i.e. has no data members other than 0-width bit-fields, has no /// virtual function/base, and doesn't inherit from a non-empty /// class. Doesn't take union-ness into account. - bool Empty : 1; + unsigned Empty : 1; /// \brief True when this class is polymorphic, i.e., has at /// least one virtual member or derives from a polymorphic class. - bool Polymorphic : 1; + unsigned Polymorphic : 1; /// \brief True when this class is abstract, i.e., has at least /// one pure virtual function, (that can come from a base class). - bool Abstract : 1; + unsigned Abstract : 1; /// \brief True when this class has standard layout. /// @@ -340,58 +318,70 @@ class CXXRecordDecl : public RecordDecl { /// classes with non-static data members, and /// * has no base classes of the same type as the first non-static data /// member. - bool IsStandardLayout : 1; + unsigned IsStandardLayout : 1; /// \brief True when there are no non-empty base classes. /// /// This is a helper bit of state used to implement IsStandardLayout more /// efficiently. - bool HasNoNonEmptyBases : 1; + unsigned HasNoNonEmptyBases : 1; /// \brief True when there are private non-static data members. - bool HasPrivateFields : 1; + unsigned HasPrivateFields : 1; /// \brief True when there are protected non-static data members. - bool HasProtectedFields : 1; + unsigned HasProtectedFields : 1; /// \brief True when there are private non-static data members. - bool HasPublicFields : 1; + unsigned HasPublicFields : 1; /// \brief True if this class (or any subobject) has mutable fields. - bool HasMutableFields : 1; + unsigned HasMutableFields : 1; /// \brief True if this class (or any nested anonymous struct or union) /// has variant members. - bool HasVariantMembers : 1; + unsigned HasVariantMembers : 1; /// \brief True if there no non-field members declared by the user. - bool HasOnlyCMembers : 1; + unsigned HasOnlyCMembers : 1; /// \brief True if any field has an in-class initializer, including those /// within anonymous unions or structs. - bool HasInClassInitializer : 1; + unsigned HasInClassInitializer : 1; /// \brief True if any field is of reference type, and does not have an /// in-class initializer. /// /// In this case, value-initialization of this class is illegal in C++98 /// even if the class has a trivial default constructor. - bool HasUninitializedReferenceMember : 1; + unsigned HasUninitializedReferenceMember : 1; + + /// \brief True if any non-mutable field whose type doesn't have a user- + /// provided default ctor also doesn't have an in-class initializer. + unsigned HasUninitializedFields : 1; + + /// \brief True if there are any member using-declarations that inherit + /// constructors from a base class. + unsigned HasInheritedConstructor : 1; + + /// \brief True if there are any member using-declarations named + /// 'operator='. + unsigned HasInheritedAssignment : 1; /// \brief These flags are \c true if a defaulted corresponding special /// member can't be fully analyzed without performing overload resolution. /// @{ - bool NeedOverloadResolutionForMoveConstructor : 1; - bool NeedOverloadResolutionForMoveAssignment : 1; - bool NeedOverloadResolutionForDestructor : 1; + unsigned NeedOverloadResolutionForMoveConstructor : 1; + unsigned NeedOverloadResolutionForMoveAssignment : 1; + unsigned NeedOverloadResolutionForDestructor : 1; /// @} /// \brief These flags are \c true if an implicit defaulted corresponding /// special member would be defined as deleted. /// @{ - bool DefaultedMoveConstructorIsDeleted : 1; - bool DefaultedMoveAssignmentIsDeleted : 1; - bool DefaultedDestructorIsDeleted : 1; + unsigned DefaultedMoveConstructorIsDeleted : 1; + unsigned DefaultedMoveAssignmentIsDeleted : 1; + unsigned DefaultedDestructorIsDeleted : 1; /// @} /// \brief The trivial special members which this class has, per @@ -411,33 +401,37 @@ class CXXRecordDecl : public RecordDecl { unsigned DeclaredNonTrivialSpecialMembers : 6; /// \brief True when this class has a destructor with no semantic effect. - bool HasIrrelevantDestructor : 1; + unsigned HasIrrelevantDestructor : 1; /// \brief True when this class has at least one user-declared constexpr /// constructor which is neither the copy nor move constructor. - bool HasConstexprNonCopyMoveConstructor : 1; + unsigned HasConstexprNonCopyMoveConstructor : 1; + + /// \brief True if this class has a (possibly implicit) defaulted default + /// constructor. + unsigned HasDefaultedDefaultConstructor : 1; /// \brief True if a defaulted default constructor for this class would /// be constexpr. - bool DefaultedDefaultConstructorIsConstexpr : 1; + unsigned DefaultedDefaultConstructorIsConstexpr : 1; /// \brief True if this class has a constexpr default constructor. /// /// This is true for either a user-declared constexpr default constructor /// or an implicitly declared constexpr default constructor. - bool HasConstexprDefaultConstructor : 1; + unsigned HasConstexprDefaultConstructor : 1; /// \brief True when this class contains at least one non-static data /// member or base class of non-literal or volatile type. - bool HasNonLiteralTypeFieldsOrBases : 1; + unsigned HasNonLiteralTypeFieldsOrBases : 1; /// \brief True when visible conversion functions are already computed /// and are available. - bool ComputedVisibleConversions : 1; + unsigned ComputedVisibleConversions : 1; /// \brief Whether we have a C++11 user-provided default constructor (not /// explicitly deleted or defaulted). - bool UserProvidedDefaultConstructor : 1; + unsigned UserProvidedDefaultConstructor : 1; /// \brief The special members which have been declared for this class, /// either by the user or implicitly. @@ -445,25 +439,25 @@ class CXXRecordDecl : public RecordDecl { /// \brief Whether an implicit copy constructor would have a const-qualified /// parameter. - bool ImplicitCopyConstructorHasConstParam : 1; + unsigned ImplicitCopyConstructorHasConstParam : 1; /// \brief Whether an implicit copy assignment operator would have a /// const-qualified parameter. - bool ImplicitCopyAssignmentHasConstParam : 1; + unsigned ImplicitCopyAssignmentHasConstParam : 1; /// \brief Whether any declared copy constructor has a const-qualified /// parameter. - bool HasDeclaredCopyConstructorWithConstParam : 1; + unsigned HasDeclaredCopyConstructorWithConstParam : 1; /// \brief Whether any declared copy assignment operator has either a /// const-qualified reference parameter or a non-reference parameter. - bool HasDeclaredCopyAssignmentWithConstParam : 1; + unsigned HasDeclaredCopyAssignmentWithConstParam : 1; /// \brief Whether this class describes a C++ lambda. - bool IsLambda : 1; + unsigned IsLambda : 1; /// \brief Whether we are currently parsing base specifiers. - bool IsParsingBaseSpecifiers : 1; + unsigned IsParsingBaseSpecifiers : 1; /// \brief The number of base class specifiers in Bases. unsigned NumBases; @@ -515,16 +509,19 @@ class CXXRecordDecl : public RecordDecl { return getVBasesSlowCase(); } + ArrayRef<CXXBaseSpecifier> bases() const { + return llvm::makeArrayRef(getBases(), NumBases); + } + ArrayRef<CXXBaseSpecifier> vbases() const { + return llvm::makeArrayRef(getVBases(), NumVBases); + } + private: CXXBaseSpecifier *getBasesSlowCase() const; CXXBaseSpecifier *getVBasesSlowCase() const; }; - typedef LazyDefinitionDataPtr<CXXRecordDecl, struct DefinitionData> - DefinitionDataPtr; - friend class LazyDefinitionDataPtr<CXXRecordDecl, struct DefinitionData>; - - mutable DefinitionDataPtr DefinitionData; + struct DefinitionData *DefinitionData; /// \brief Describes a C++ closure type (generated by a lambda expression). struct LambdaDefinitionData : public DefinitionData { @@ -587,8 +584,14 @@ class CXXRecordDecl : public RecordDecl { }; + struct DefinitionData *dataPtr() const { + // Complete the redecl chain (if necessary). + getMostRecentDecl(); + return DefinitionData; + } + struct DefinitionData &data() const { - auto *DD = DefinitionData.get(); + auto *DD = dataPtr(); assert(DD && "queried property of class with no definition"); return *DD; } @@ -596,7 +599,7 @@ class CXXRecordDecl : public RecordDecl { struct LambdaDefinitionData &getLambdaData() const { // No update required: a merged definition cannot change any lambda // properties. - auto *DD = DefinitionData.getNotUpdated(); + auto *DD = DefinitionData; assert(DD && DD->IsLambda && "queried lambda property of non-lambda class"); return static_cast<LambdaDefinitionData&>(*DD); } @@ -673,11 +676,13 @@ public: } CXXRecordDecl *getDefinition() const { - auto *DD = DefinitionData.get(); + // We only need an update if we don't already know which + // declaration is the definition. + auto *DD = DefinitionData ? DefinitionData : dataPtr(); return DD ? DD->Definition : nullptr; } - bool hasDefinition() const { return DefinitionData.get(); } + bool hasDefinition() const { return DefinitionData || dataPtr(); } static CXXRecordDecl *Create(const ASTContext &C, TagKind TK, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, @@ -1021,7 +1026,7 @@ public: /// \brief Determine whether this class describes a lambda function object. bool isLambda() const { // An update record can't turn a non-lambda into a lambda. - auto *DD = DefinitionData.getNotUpdated(); + auto *DD = DefinitionData; return DD && DD->IsLambda; } @@ -1136,9 +1141,10 @@ public: /// \brief Determine whether this is an empty class in the sense of /// (C++11 [meta.unary.prop]). /// - /// A non-union class is empty iff it has a virtual function, virtual base, - /// data member (other than 0-width bit-field) or inherits from a non-empty - /// class. + /// The CXXRecordDecl is a class type, but not a union type, + /// with no non-static data members other than bit-fields of length 0, + /// no virtual member functions, no virtual base classes, + /// and no base class B for which is_empty<B>::value is false. /// /// \note This does NOT include a check for union-ness. bool isEmpty() const { return data().Empty; } @@ -1270,6 +1276,14 @@ public: return !(data().HasTrivialSpecialMembers & SMF_Destructor); } + /// \brief Determine whether declaring a const variable with this type is ok + /// per core issue 253. + bool allowConstDefaultInit() const { + return !data().HasUninitializedFields || + !(data().HasDefaultedDefaultConstructor || + needsImplicitDefaultConstructor()); + } + /// \brief Determine whether this class has a destructor which has no /// semantic effect. /// @@ -1285,6 +1299,18 @@ public: return data().HasNonLiteralTypeFieldsOrBases; } + /// \brief Determine whether this class has a using-declaration that names + /// a user-declared base class constructor. + bool hasInheritedConstructor() const { + return data().HasInheritedConstructor; + } + + /// \brief Determine whether this class has a using-declaration that names + /// a base class assignment operator. + bool hasInheritedAssignment() const { + return data().HasInheritedAssignment; + } + /// \brief Determine whether this class is considered trivially copyable per /// (C++11 [class]p6). bool isTriviallyCopyable() const; @@ -1555,6 +1581,14 @@ public: CXXBasePath &Path, DeclarationName Name); /// \brief Base-class lookup callback that determines whether there exists + /// an OpenMP declare reduction member with the given name. + /// + /// This callback can be used with \c lookupInBases() to find members + /// of the given name within a C++ class hierarchy. + static bool FindOMPReductionMember(const CXXBaseSpecifier *Specifier, + CXXBasePath &Path, DeclarationName Name); + + /// \brief Base-class lookup callback that determines whether there exists /// a member with the given name that can be used in a nested-name-specifier. /// /// This callback can be used with \c lookupInBases() to find members of @@ -1690,6 +1724,7 @@ public: friend class ASTDeclReader; friend class ASTDeclWriter; + friend class ASTRecordWriter; friend class ASTReader; friend class ASTWriter; }; @@ -1795,6 +1830,8 @@ public: method_iterator begin_overridden_methods() const; method_iterator end_overridden_methods() const; unsigned size_overridden_methods() const; + typedef ASTContext::overridden_method_range overridden_method_range; + overridden_method_range overridden_methods() const; /// Returns the parent of this method declaration, which /// is the class in which this method is defined. @@ -1910,15 +1947,15 @@ class CXXCtorInitializer final /// \brief If the initializee is a type, whether that type makes this /// a delegating initialization. - bool IsDelegating : 1; + unsigned IsDelegating : 1; /// \brief If the initializer is a base initializer, this keeps track /// of whether the base is virtual or not. - bool IsVirtual : 1; + unsigned IsVirtual : 1; /// \brief Whether or not the initializer is explicitly written /// in the sources. - bool IsWritten : 1; + unsigned IsWritten : 1; /// If IsWritten is true, then this number keeps track of the textual order /// of this initializer in the original sources, counting from 0; otherwise, @@ -2109,8 +2146,7 @@ public: assert(I < getNumArrayIndices() && "Out of bounds member array index"); getTrailingObjects<VarDecl *>()[I] = Index; } - ArrayRef<VarDecl *> getArrayIndexes() { - assert(getNumArrayIndices() != 0 && "Getting indexes for non-array init"); + ArrayRef<VarDecl *> getArrayIndices() { return llvm::makeArrayRef(getTrailingObjects<VarDecl *>(), getNumArrayIndices()); } @@ -2121,6 +2157,23 @@ public: friend TrailingObjects; }; +/// Description of a constructor that was inherited from a base class. +class InheritedConstructor { + ConstructorUsingShadowDecl *Shadow; + CXXConstructorDecl *BaseCtor; + +public: + InheritedConstructor() : Shadow(), BaseCtor() {} + InheritedConstructor(ConstructorUsingShadowDecl *Shadow, + CXXConstructorDecl *BaseCtor) + : Shadow(Shadow), BaseCtor(BaseCtor) {} + + explicit operator bool() const { return Shadow; } + + ConstructorUsingShadowDecl *getShadowDecl() const { return Shadow; } + CXXConstructorDecl *getConstructor() const { return BaseCtor; } +}; + /// \brief Represents a C++ constructor within a class. /// /// For example: @@ -2131,40 +2184,51 @@ public: /// explicit X(int); // represented by a CXXConstructorDecl. /// }; /// \endcode -class CXXConstructorDecl : public CXXMethodDecl { +class CXXConstructorDecl final + : public CXXMethodDecl, + private llvm::TrailingObjects<CXXConstructorDecl, InheritedConstructor> { void anchor() override; - /// \brief Whether this constructor declaration has the \c explicit keyword - /// specified. - bool IsExplicitSpecified : 1; /// \name Support for base and member initializers. /// \{ /// \brief The arguments used to initialize the base or member. LazyCXXCtorInitializersPtr CtorInitializers; - unsigned NumCtorInitializers; + unsigned NumCtorInitializers : 30; /// \} + /// \brief Whether this constructor declaration has the \c explicit keyword + /// specified. + unsigned IsExplicitSpecified : 1; + + /// \brief Whether this constructor declaration is an implicitly-declared + /// inheriting constructor. + unsigned IsInheritingConstructor : 1; + CXXConstructorDecl(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc, const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, bool isExplicitSpecified, bool isInline, - bool isImplicitlyDeclared, bool isConstexpr) + bool isImplicitlyDeclared, bool isConstexpr, + InheritedConstructor Inherited) : CXXMethodDecl(CXXConstructor, C, RD, StartLoc, NameInfo, T, TInfo, SC_None, isInline, isConstexpr, SourceLocation()), - IsExplicitSpecified(isExplicitSpecified), CtorInitializers(nullptr), - NumCtorInitializers(0) { + CtorInitializers(nullptr), NumCtorInitializers(0), + IsExplicitSpecified(isExplicitSpecified), + IsInheritingConstructor((bool)Inherited) { setImplicit(isImplicitlyDeclared); + if (Inherited) + *getTrailingObjects<InheritedConstructor>() = Inherited; } public: - static CXXConstructorDecl *CreateDeserialized(ASTContext &C, unsigned ID); - static CXXConstructorDecl *Create(ASTContext &C, CXXRecordDecl *RD, - SourceLocation StartLoc, - const DeclarationNameInfo &NameInfo, - QualType T, TypeSourceInfo *TInfo, - bool isExplicit, - bool isInline, bool isImplicitlyDeclared, - bool isConstexpr); + static CXXConstructorDecl *CreateDeserialized(ASTContext &C, unsigned ID, + bool InheritsConstructor); + static CXXConstructorDecl * + Create(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc, + const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, + bool isExplicit, bool isInline, bool isImplicitlyDeclared, + bool isConstexpr, + InheritedConstructor Inherited = InheritedConstructor()); /// \brief Determine whether this constructor declaration has the /// \c explicit keyword specified. @@ -2311,11 +2375,15 @@ public: /// an object. bool isSpecializationCopyingObject() const; - /// \brief Get the constructor that this inheriting constructor is based on. - const CXXConstructorDecl *getInheritedConstructor() const; + /// \brief Determine whether this is an implicit constructor synthesized to + /// model a call to a constructor inherited from a base class. + bool isInheritingConstructor() const { return IsInheritingConstructor; } - /// \brief Set the constructor that this inheriting constructor is based on. - void setInheritedConstructor(const CXXConstructorDecl *BaseCtor); + /// \brief Get the constructor that this inheriting constructor is based on. + InheritedConstructor getInheritedConstructor() const { + return IsInheritingConstructor ? *getTrailingObjects<InheritedConstructor>() + : InheritedConstructor(); + } CXXConstructorDecl *getCanonicalDecl() override { return cast<CXXConstructorDecl>(FunctionDecl::getCanonicalDecl()); @@ -2330,6 +2398,7 @@ public: friend class ASTDeclReader; friend class ASTDeclWriter; + friend TrailingObjects; }; /// \brief Represents a C++ destructor within a class. @@ -2774,18 +2843,6 @@ class UsingShadowDecl : public NamedDecl, public Redeclarable<UsingShadowDecl> { NamedDecl *UsingOrNextShadow; friend class UsingDecl; - UsingShadowDecl(ASTContext &C, DeclContext *DC, SourceLocation Loc, - UsingDecl *Using, NamedDecl *Target) - : NamedDecl(UsingShadow, DC, Loc, DeclarationName()), - redeclarable_base(C), Underlying(Target), - UsingOrNextShadow(reinterpret_cast<NamedDecl *>(Using)) { - if (Target) { - setDeclName(Target->getDeclName()); - IdentifierNamespace = Target->getIdentifierNamespace(); - } - setImplicit(); - } - typedef Redeclarable<UsingShadowDecl> redeclarable_base; UsingShadowDecl *getNextRedeclarationImpl() override { return getNextRedeclaration(); @@ -2797,11 +2854,16 @@ class UsingShadowDecl : public NamedDecl, public Redeclarable<UsingShadowDecl> { return getMostRecentDecl(); } +protected: + UsingShadowDecl(Kind K, ASTContext &C, DeclContext *DC, SourceLocation Loc, + UsingDecl *Using, NamedDecl *Target); + UsingShadowDecl(Kind K, ASTContext &C, EmptyShell); + public: static UsingShadowDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation Loc, UsingDecl *Using, NamedDecl *Target) { - return new (C, DC) UsingShadowDecl(C, DC, Loc, Using, Target); + return new (C, DC) UsingShadowDecl(UsingShadow, C, DC, Loc, Using, Target); } static UsingShadowDecl *CreateDeserialized(ASTContext &C, unsigned ID); @@ -2813,6 +2875,7 @@ public: using redeclarable_base::redecls; using redeclarable_base::getPreviousDecl; using redeclarable_base::getMostRecentDecl; + using redeclarable_base::isFirstDecl; UsingShadowDecl *getCanonicalDecl() override { return getFirstDecl(); @@ -2843,7 +2906,125 @@ public: } static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classofKind(Kind K) { return K == Decl::UsingShadow; } + static bool classofKind(Kind K) { + return K == Decl::UsingShadow || K == Decl::ConstructorUsingShadow; + } + + friend class ASTDeclReader; + friend class ASTDeclWriter; +}; + +/// \brief Represents a shadow constructor declaration introduced into a +/// class by a C++11 using-declaration that names a constructor. +/// +/// For example: +/// \code +/// struct Base { Base(int); }; +/// struct Derived { +/// using Base::Base; // creates a UsingDecl and a ConstructorUsingShadowDecl +/// }; +/// \endcode +class ConstructorUsingShadowDecl final : public UsingShadowDecl { + void anchor() override; + + /// \brief If this constructor using declaration inherted the constructor + /// from an indirect base class, this is the ConstructorUsingShadowDecl + /// in the named direct base class from which the declaration was inherited. + ConstructorUsingShadowDecl *NominatedBaseClassShadowDecl; + + /// \brief If this constructor using declaration inherted the constructor + /// from an indirect base class, this is the ConstructorUsingShadowDecl + /// that will be used to construct the unique direct or virtual base class + /// that receives the constructor arguments. + ConstructorUsingShadowDecl *ConstructedBaseClassShadowDecl; + + /// \brief \c true if the constructor ultimately named by this using shadow + /// declaration is within a virtual base class subobject of the class that + /// contains this declaration. + unsigned IsVirtual : 1; + + ConstructorUsingShadowDecl(ASTContext &C, DeclContext *DC, SourceLocation Loc, + UsingDecl *Using, NamedDecl *Target, + bool TargetInVirtualBase) + : UsingShadowDecl(ConstructorUsingShadow, C, DC, Loc, Using, + Target->getUnderlyingDecl()), + NominatedBaseClassShadowDecl( + dyn_cast<ConstructorUsingShadowDecl>(Target)), + ConstructedBaseClassShadowDecl(NominatedBaseClassShadowDecl), + IsVirtual(TargetInVirtualBase) { + // If we found a constructor for a non-virtual base class, but it chains to + // a constructor for a virtual base, we should directly call the virtual + // base constructor instead. + // FIXME: This logic belongs in Sema. + if (!TargetInVirtualBase && NominatedBaseClassShadowDecl && + NominatedBaseClassShadowDecl->constructsVirtualBase()) { + ConstructedBaseClassShadowDecl = + NominatedBaseClassShadowDecl->ConstructedBaseClassShadowDecl; + IsVirtual = true; + } + } + ConstructorUsingShadowDecl(ASTContext &C, EmptyShell Empty) + : UsingShadowDecl(ConstructorUsingShadow, C, Empty) {} + +public: + static ConstructorUsingShadowDecl *Create(ASTContext &C, DeclContext *DC, + SourceLocation Loc, + UsingDecl *Using, NamedDecl *Target, + bool IsVirtual); + static ConstructorUsingShadowDecl *CreateDeserialized(ASTContext &C, + unsigned ID); + + /// Returns the parent of this using shadow declaration, which + /// is the class in which this is declared. + //@{ + const CXXRecordDecl *getParent() const { + return cast<CXXRecordDecl>(getDeclContext()); + } + CXXRecordDecl *getParent() { + return cast<CXXRecordDecl>(getDeclContext()); + } + //@} + + /// \brief Get the inheriting constructor declaration for the direct base + /// class from which this using shadow declaration was inherited, if there is + /// one. This can be different for each redeclaration of the same shadow decl. + ConstructorUsingShadowDecl *getNominatedBaseClassShadowDecl() const { + return NominatedBaseClassShadowDecl; + } + + /// \brief Get the inheriting constructor declaration for the base class + /// for which we don't have an explicit initializer, if there is one. + ConstructorUsingShadowDecl *getConstructedBaseClassShadowDecl() const { + return ConstructedBaseClassShadowDecl; + } + + /// \brief Get the base class that was named in the using declaration. This + /// can be different for each redeclaration of this same shadow decl. + CXXRecordDecl *getNominatedBaseClass() const; + + /// \brief Get the base class whose constructor or constructor shadow + /// declaration is passed the constructor arguments. + CXXRecordDecl *getConstructedBaseClass() const { + return cast<CXXRecordDecl>((ConstructedBaseClassShadowDecl + ? ConstructedBaseClassShadowDecl + : getTargetDecl()) + ->getDeclContext()); + } + + /// \brief Returns \c true if the constructed base class is a virtual base + /// class subobject of this declaration's class. + bool constructsVirtualBase() const { + return IsVirtual; + } + + /// \brief Get the constructor or constructor template in the derived class + /// correspnding to this using shadow declaration, if it has been implicitly + /// declared already. + CXXConstructorDecl *getConstructor() const; + void setConstructor(NamedDecl *Ctor); + + static bool classof(const Decl *D) { return classofKind(D->getKind()); } + static bool classofKind(Kind K) { return K == ConstructorUsingShadow; } friend class ASTDeclReader; friend class ASTDeclWriter; diff --git a/include/clang/AST/DeclFriend.h b/include/clang/AST/DeclFriend.h index 27b0388007a1c..5b2e2d9915eb1 100644 --- a/include/clang/AST/DeclFriend.h +++ b/include/clang/AST/DeclFriend.h @@ -57,7 +57,7 @@ private: /// True if this 'friend' declaration is unsupported. Eventually we /// will support every possible friend declaration, but for now we /// silently ignore some and set this flag to authorize all access. - bool UnsupportedFriend : 1; + unsigned UnsupportedFriend : 1; // The number of "outer" template parameter lists in non-templatic // (currently unsupported) friend type declarations, such as diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h index f46078f28a7d8..ad9b5a26b7c86 100644 --- a/include/clang/AST/DeclObjC.h +++ b/include/clang/AST/DeclObjC.h @@ -351,11 +351,6 @@ public: typedef llvm::iterator_range<param_iterator> param_range; typedef llvm::iterator_range<param_const_iterator> param_const_range; - param_range params() { return param_range(param_begin(), param_end()); } - param_const_range params() const { - return param_const_range(param_begin(), param_end()); - } - param_const_iterator param_begin() const { return param_const_iterator(getParams()); } @@ -689,6 +684,216 @@ public: friend TrailingObjects; }; +enum class ObjCPropertyQueryKind : uint8_t { + OBJC_PR_query_unknown = 0x00, + OBJC_PR_query_instance, + OBJC_PR_query_class +}; + +/// \brief Represents one property declaration in an Objective-C interface. +/// +/// For example: +/// \code{.mm} +/// \@property (assign, readwrite) int MyProperty; +/// \endcode +class ObjCPropertyDecl : public NamedDecl { + void anchor() override; +public: + enum PropertyAttributeKind { + OBJC_PR_noattr = 0x00, + OBJC_PR_readonly = 0x01, + OBJC_PR_getter = 0x02, + OBJC_PR_assign = 0x04, + OBJC_PR_readwrite = 0x08, + OBJC_PR_retain = 0x10, + OBJC_PR_copy = 0x20, + OBJC_PR_nonatomic = 0x40, + OBJC_PR_setter = 0x80, + OBJC_PR_atomic = 0x100, + OBJC_PR_weak = 0x200, + OBJC_PR_strong = 0x400, + OBJC_PR_unsafe_unretained = 0x800, + /// Indicates that the nullability of the type was spelled with a + /// property attribute rather than a type qualifier. + OBJC_PR_nullability = 0x1000, + OBJC_PR_null_resettable = 0x2000, + OBJC_PR_class = 0x4000 + // Adding a property should change NumPropertyAttrsBits + }; + + enum { + /// \brief Number of bits fitting all the property attributes. + NumPropertyAttrsBits = 15 + }; + + enum SetterKind { Assign, Retain, Copy, Weak }; + enum PropertyControl { None, Required, Optional }; +private: + SourceLocation AtLoc; // location of \@property + SourceLocation LParenLoc; // location of '(' starting attribute list or null. + QualType DeclType; + TypeSourceInfo *DeclTypeSourceInfo; + unsigned PropertyAttributes : NumPropertyAttrsBits; + unsigned PropertyAttributesAsWritten : NumPropertyAttrsBits; + // \@required/\@optional + unsigned PropertyImplementation : 2; + + Selector GetterName; // getter name of NULL if no getter + Selector SetterName; // setter name of NULL if no setter + + ObjCMethodDecl *GetterMethodDecl; // Declaration of getter instance method + ObjCMethodDecl *SetterMethodDecl; // Declaration of setter instance method + ObjCIvarDecl *PropertyIvarDecl; // Synthesize ivar for this property + + ObjCPropertyDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id, + SourceLocation AtLocation, SourceLocation LParenLocation, + QualType T, TypeSourceInfo *TSI, + PropertyControl propControl) + : NamedDecl(ObjCProperty, DC, L, Id), AtLoc(AtLocation), + LParenLoc(LParenLocation), DeclType(T), DeclTypeSourceInfo(TSI), + PropertyAttributes(OBJC_PR_noattr), + PropertyAttributesAsWritten(OBJC_PR_noattr), + PropertyImplementation(propControl), + GetterName(Selector()), + SetterName(Selector()), + GetterMethodDecl(nullptr), SetterMethodDecl(nullptr), + PropertyIvarDecl(nullptr) {} + +public: + static ObjCPropertyDecl *Create(ASTContext &C, DeclContext *DC, + SourceLocation L, + IdentifierInfo *Id, SourceLocation AtLocation, + SourceLocation LParenLocation, + QualType T, + TypeSourceInfo *TSI, + PropertyControl propControl = None); + + static ObjCPropertyDecl *CreateDeserialized(ASTContext &C, unsigned ID); + + SourceLocation getAtLoc() const { return AtLoc; } + void setAtLoc(SourceLocation L) { AtLoc = L; } + + SourceLocation getLParenLoc() const { return LParenLoc; } + void setLParenLoc(SourceLocation L) { LParenLoc = L; } + + TypeSourceInfo *getTypeSourceInfo() const { return DeclTypeSourceInfo; } + + QualType getType() const { return DeclType; } + + void setType(QualType T, TypeSourceInfo *TSI) { + DeclType = T; + DeclTypeSourceInfo = TSI; + } + + /// Retrieve the type when this property is used with a specific base object + /// type. + QualType getUsageType(QualType objectType) const; + + PropertyAttributeKind getPropertyAttributes() const { + return PropertyAttributeKind(PropertyAttributes); + } + void setPropertyAttributes(PropertyAttributeKind PRVal) { + PropertyAttributes |= PRVal; + } + void overwritePropertyAttributes(unsigned PRVal) { + PropertyAttributes = PRVal; + } + + PropertyAttributeKind getPropertyAttributesAsWritten() const { + return PropertyAttributeKind(PropertyAttributesAsWritten); + } + + void setPropertyAttributesAsWritten(PropertyAttributeKind PRVal) { + PropertyAttributesAsWritten = PRVal; + } + + // Helper methods for accessing attributes. + + /// isReadOnly - Return true iff the property has a setter. + bool isReadOnly() const { + return (PropertyAttributes & OBJC_PR_readonly); + } + + /// isAtomic - Return true if the property is atomic. + bool isAtomic() const { + return (PropertyAttributes & OBJC_PR_atomic); + } + + /// isRetaining - Return true if the property retains its value. + bool isRetaining() const { + return (PropertyAttributes & + (OBJC_PR_retain | OBJC_PR_strong | OBJC_PR_copy)); + } + + bool isInstanceProperty() const { return !isClassProperty(); } + bool isClassProperty() const { return PropertyAttributes & OBJC_PR_class; } + ObjCPropertyQueryKind getQueryKind() const { + return isClassProperty() ? ObjCPropertyQueryKind::OBJC_PR_query_class : + ObjCPropertyQueryKind::OBJC_PR_query_instance; + } + static ObjCPropertyQueryKind getQueryKind(bool isClassProperty) { + return isClassProperty ? ObjCPropertyQueryKind::OBJC_PR_query_class : + ObjCPropertyQueryKind::OBJC_PR_query_instance; + } + + /// getSetterKind - Return the method used for doing assignment in + /// the property setter. This is only valid if the property has been + /// defined to have a setter. + SetterKind getSetterKind() const { + if (PropertyAttributes & OBJC_PR_strong) + return getType()->isBlockPointerType() ? Copy : Retain; + if (PropertyAttributes & OBJC_PR_retain) + return Retain; + if (PropertyAttributes & OBJC_PR_copy) + return Copy; + if (PropertyAttributes & OBJC_PR_weak) + return Weak; + return Assign; + } + + Selector getGetterName() const { return GetterName; } + void setGetterName(Selector Sel) { GetterName = Sel; } + + Selector getSetterName() const { return SetterName; } + void setSetterName(Selector Sel) { SetterName = Sel; } + + ObjCMethodDecl *getGetterMethodDecl() const { return GetterMethodDecl; } + void setGetterMethodDecl(ObjCMethodDecl *gDecl) { GetterMethodDecl = gDecl; } + + ObjCMethodDecl *getSetterMethodDecl() const { return SetterMethodDecl; } + void setSetterMethodDecl(ObjCMethodDecl *gDecl) { SetterMethodDecl = gDecl; } + + // Related to \@optional/\@required declared in \@protocol + void setPropertyImplementation(PropertyControl pc) { + PropertyImplementation = pc; + } + PropertyControl getPropertyImplementation() const { + return PropertyControl(PropertyImplementation); + } + + void setPropertyIvarDecl(ObjCIvarDecl *Ivar) { + PropertyIvarDecl = Ivar; + } + ObjCIvarDecl *getPropertyIvarDecl() const { + return PropertyIvarDecl; + } + + SourceRange getSourceRange() const override LLVM_READONLY { + return SourceRange(AtLoc, getLocation()); + } + + /// Get the default name of the synthesized ivar. + IdentifierInfo *getDefaultSynthIvarName(ASTContext &Ctx) const; + + /// Lookup a property by name in the specified DeclContext. + static ObjCPropertyDecl *findPropertyDecl(const DeclContext *DC, + const IdentifierInfo *propertyID, + ObjCPropertyQueryKind queryKind); + + static bool classof(const Decl *D) { return classofKind(D->getKind()); } + static bool classofKind(Kind K) { return K == ObjCProperty; } +}; + /// ObjCContainerDecl - Represents a container for method declarations. /// Current sub-classes are ObjCInterfaceDecl, ObjCCategoryDecl, /// ObjCProtocolDecl, and ObjCImplDecl. @@ -708,7 +913,7 @@ public: SourceLocation atStartLoc) : NamedDecl(DK, DC, nameLoc, Id), DeclContext(DK), AtStart(atStartLoc) {} - // Iterator access to properties. + // Iterator access to instance/class properties. typedef specific_decl_iterator<ObjCPropertyDecl> prop_iterator; typedef llvm::iterator_range<specific_decl_iterator<ObjCPropertyDecl>> prop_range; @@ -721,6 +926,36 @@ public: return prop_iterator(decls_end()); } + typedef filtered_decl_iterator<ObjCPropertyDecl, + &ObjCPropertyDecl::isInstanceProperty> + instprop_iterator; + typedef llvm::iterator_range<instprop_iterator> instprop_range; + + instprop_range instance_properties() const { + return instprop_range(instprop_begin(), instprop_end()); + } + instprop_iterator instprop_begin() const { + return instprop_iterator(decls_begin()); + } + instprop_iterator instprop_end() const { + return instprop_iterator(decls_end()); + } + + typedef filtered_decl_iterator<ObjCPropertyDecl, + &ObjCPropertyDecl::isClassProperty> + classprop_iterator; + typedef llvm::iterator_range<classprop_iterator> classprop_range; + + classprop_range class_properties() const { + return classprop_range(classprop_begin(), classprop_end()); + } + classprop_iterator classprop_begin() const { + return classprop_iterator(decls_begin()); + } + classprop_iterator classprop_end() const { + return classprop_iterator(decls_end()); + } + // Iterator access to instance/class methods. typedef specific_decl_iterator<ObjCMethodDecl> method_iterator; typedef llvm::iterator_range<specific_decl_iterator<ObjCMethodDecl>> @@ -780,9 +1015,12 @@ public: ObjCIvarDecl *getIvarDecl(IdentifierInfo *Id) const; ObjCPropertyDecl * - FindPropertyDeclaration(const IdentifierInfo *PropertyId) const; + FindPropertyDeclaration(const IdentifierInfo *PropertyId, + ObjCPropertyQueryKind QueryKind) const; - typedef llvm::DenseMap<IdentifierInfo*, ObjCPropertyDecl*> PropertyMap; + typedef llvm::DenseMap<std::pair<IdentifierInfo*, + unsigned/*isClassProperty*/>, + ObjCPropertyDecl*> PropertyMap; typedef llvm::DenseMap<const ObjCProtocolDecl *, ObjCPropertyDecl*> ProtocolPropertyMap; @@ -886,15 +1124,15 @@ class ObjCInterfaceDecl : public ObjCContainerDecl /// \brief Indicates that the contents of this Objective-C class will be /// completed by the external AST source when required. - mutable bool ExternallyCompleted : 1; + mutable unsigned ExternallyCompleted : 1; /// \brief Indicates that the ivar cache does not yet include ivars /// declared in the implementation. - mutable bool IvarListMissingImplementation : 1; + mutable unsigned IvarListMissingImplementation : 1; /// Indicates that this interface decl contains at least one initializer /// marked with the 'objc_designated_initializer' attribute. - bool HasDesignatedInitializers : 1; + unsigned HasDesignatedInitializers : 1; enum InheritedDesignatedInitializersState { /// We didn't calculate whether the designated initializers should be @@ -1463,7 +1701,8 @@ public: } ObjCPropertyDecl - *FindPropertyVisibleInPrimaryClass(IdentifierInfo *PropertyId) const; + *FindPropertyVisibleInPrimaryClass(IdentifierInfo *PropertyId, + ObjCPropertyQueryKind QueryKind) const; void collectPropertiesToImplement(PropertyMap &PM, PropertyDeclOrder &PO) const override; @@ -1529,8 +1768,9 @@ public: /// including in all categories except for category passed /// as argument. ObjCMethodDecl *lookupPropertyAccessor(const Selector Sel, - const ObjCCategoryDecl *Cat) const { - return lookupMethod(Sel, true/*isInstance*/, + const ObjCCategoryDecl *Cat, + bool IsClassProperty) const { + return lookupMethod(Sel, !IsClassProperty/*isInstance*/, false/*shallowCategoryLookup*/, true /* followsSuper */, Cat); @@ -2099,7 +2339,8 @@ public: void addPropertyImplementation(ObjCPropertyImplDecl *property); - ObjCPropertyImplDecl *FindPropertyImplDecl(IdentifierInfo *propertyId) const; + ObjCPropertyImplDecl *FindPropertyImplDecl(IdentifierInfo *propertyId, + ObjCPropertyQueryKind queryKind) const; ObjCPropertyImplDecl *FindPropertyImplIvarDecl(IdentifierInfo *ivarId) const; // Iterator access to properties. @@ -2407,197 +2648,6 @@ public: }; -/// \brief Represents one property declaration in an Objective-C interface. -/// -/// For example: -/// \code{.mm} -/// \@property (assign, readwrite) int MyProperty; -/// \endcode -class ObjCPropertyDecl : public NamedDecl { - void anchor() override; -public: - enum PropertyAttributeKind { - OBJC_PR_noattr = 0x00, - OBJC_PR_readonly = 0x01, - OBJC_PR_getter = 0x02, - OBJC_PR_assign = 0x04, - OBJC_PR_readwrite = 0x08, - OBJC_PR_retain = 0x10, - OBJC_PR_copy = 0x20, - OBJC_PR_nonatomic = 0x40, - OBJC_PR_setter = 0x80, - OBJC_PR_atomic = 0x100, - OBJC_PR_weak = 0x200, - OBJC_PR_strong = 0x400, - OBJC_PR_unsafe_unretained = 0x800, - /// Indicates that the nullability of the type was spelled with a - /// property attribute rather than a type qualifier. - OBJC_PR_nullability = 0x1000, - OBJC_PR_null_resettable = 0x2000 - // Adding a property should change NumPropertyAttrsBits - }; - - enum { - /// \brief Number of bits fitting all the property attributes. - NumPropertyAttrsBits = 14 - }; - - enum SetterKind { Assign, Retain, Copy, Weak }; - enum PropertyControl { None, Required, Optional }; -private: - SourceLocation AtLoc; // location of \@property - SourceLocation LParenLoc; // location of '(' starting attribute list or null. - QualType DeclType; - TypeSourceInfo *DeclTypeSourceInfo; - unsigned PropertyAttributes : NumPropertyAttrsBits; - unsigned PropertyAttributesAsWritten : NumPropertyAttrsBits; - // \@required/\@optional - unsigned PropertyImplementation : 2; - - Selector GetterName; // getter name of NULL if no getter - Selector SetterName; // setter name of NULL if no setter - - ObjCMethodDecl *GetterMethodDecl; // Declaration of getter instance method - ObjCMethodDecl *SetterMethodDecl; // Declaration of setter instance method - ObjCIvarDecl *PropertyIvarDecl; // Synthesize ivar for this property - - ObjCPropertyDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id, - SourceLocation AtLocation, SourceLocation LParenLocation, - QualType T, TypeSourceInfo *TSI, - PropertyControl propControl) - : NamedDecl(ObjCProperty, DC, L, Id), AtLoc(AtLocation), - LParenLoc(LParenLocation), DeclType(T), DeclTypeSourceInfo(TSI), - PropertyAttributes(OBJC_PR_noattr), - PropertyAttributesAsWritten(OBJC_PR_noattr), - PropertyImplementation(propControl), - GetterName(Selector()), - SetterName(Selector()), - GetterMethodDecl(nullptr), SetterMethodDecl(nullptr), - PropertyIvarDecl(nullptr) {} - -public: - static ObjCPropertyDecl *Create(ASTContext &C, DeclContext *DC, - SourceLocation L, - IdentifierInfo *Id, SourceLocation AtLocation, - SourceLocation LParenLocation, - QualType T, - TypeSourceInfo *TSI, - PropertyControl propControl = None); - - static ObjCPropertyDecl *CreateDeserialized(ASTContext &C, unsigned ID); - - SourceLocation getAtLoc() const { return AtLoc; } - void setAtLoc(SourceLocation L) { AtLoc = L; } - - SourceLocation getLParenLoc() const { return LParenLoc; } - void setLParenLoc(SourceLocation L) { LParenLoc = L; } - - TypeSourceInfo *getTypeSourceInfo() const { return DeclTypeSourceInfo; } - - QualType getType() const { return DeclType; } - - void setType(QualType T, TypeSourceInfo *TSI) { - DeclType = T; - DeclTypeSourceInfo = TSI; - } - - /// Retrieve the type when this property is used with a specific base object - /// type. - QualType getUsageType(QualType objectType) const; - - PropertyAttributeKind getPropertyAttributes() const { - return PropertyAttributeKind(PropertyAttributes); - } - void setPropertyAttributes(PropertyAttributeKind PRVal) { - PropertyAttributes |= PRVal; - } - void overwritePropertyAttributes(unsigned PRVal) { - PropertyAttributes = PRVal; - } - - PropertyAttributeKind getPropertyAttributesAsWritten() const { - return PropertyAttributeKind(PropertyAttributesAsWritten); - } - - void setPropertyAttributesAsWritten(PropertyAttributeKind PRVal) { - PropertyAttributesAsWritten = PRVal; - } - - // Helper methods for accessing attributes. - - /// isReadOnly - Return true iff the property has a setter. - bool isReadOnly() const { - return (PropertyAttributes & OBJC_PR_readonly); - } - - /// isAtomic - Return true if the property is atomic. - bool isAtomic() const { - return (PropertyAttributes & OBJC_PR_atomic); - } - - /// isRetaining - Return true if the property retains its value. - bool isRetaining() const { - return (PropertyAttributes & - (OBJC_PR_retain | OBJC_PR_strong | OBJC_PR_copy)); - } - - /// getSetterKind - Return the method used for doing assignment in - /// the property setter. This is only valid if the property has been - /// defined to have a setter. - SetterKind getSetterKind() const { - if (PropertyAttributes & OBJC_PR_strong) - return getType()->isBlockPointerType() ? Copy : Retain; - if (PropertyAttributes & OBJC_PR_retain) - return Retain; - if (PropertyAttributes & OBJC_PR_copy) - return Copy; - if (PropertyAttributes & OBJC_PR_weak) - return Weak; - return Assign; - } - - Selector getGetterName() const { return GetterName; } - void setGetterName(Selector Sel) { GetterName = Sel; } - - Selector getSetterName() const { return SetterName; } - void setSetterName(Selector Sel) { SetterName = Sel; } - - ObjCMethodDecl *getGetterMethodDecl() const { return GetterMethodDecl; } - void setGetterMethodDecl(ObjCMethodDecl *gDecl) { GetterMethodDecl = gDecl; } - - ObjCMethodDecl *getSetterMethodDecl() const { return SetterMethodDecl; } - void setSetterMethodDecl(ObjCMethodDecl *gDecl) { SetterMethodDecl = gDecl; } - - // Related to \@optional/\@required declared in \@protocol - void setPropertyImplementation(PropertyControl pc) { - PropertyImplementation = pc; - } - PropertyControl getPropertyImplementation() const { - return PropertyControl(PropertyImplementation); - } - - void setPropertyIvarDecl(ObjCIvarDecl *Ivar) { - PropertyIvarDecl = Ivar; - } - ObjCIvarDecl *getPropertyIvarDecl() const { - return PropertyIvarDecl; - } - - SourceRange getSourceRange() const override LLVM_READONLY { - return SourceRange(AtLoc, getLocation()); - } - - /// Get the default name of the synthesized ivar. - IdentifierInfo *getDefaultSynthIvarName(ASTContext &Ctx) const; - - /// Lookup a property by name in the specified DeclContext. - static ObjCPropertyDecl *findPropertyDecl(const DeclContext *DC, - const IdentifierInfo *propertyID); - - static bool classof(const Decl *D) { return classofKind(D->getKind()); } - static bool classofKind(Kind K) { return K == ObjCProperty; } -}; - /// ObjCPropertyImplDecl - Represents implementation declaration of a property /// in a class or category implementation block. For example: /// \@synthesize prop1 = ivar1; diff --git a/include/clang/AST/DeclOpenMP.h b/include/clang/AST/DeclOpenMP.h index 598f418f7e355..1975bc551ca52 100644 --- a/include/clang/AST/DeclOpenMP.h +++ b/include/clang/AST/DeclOpenMP.h @@ -15,11 +15,14 @@ #ifndef LLVM_CLANG_AST_DECLOPENMP_H #define LLVM_CLANG_AST_DECLOPENMP_H -#include "clang/AST/DeclBase.h" +#include "clang/AST/Decl.h" +#include "clang/AST/Expr.h" +#include "clang/AST/ExternalASTSource.h" +#include "clang/AST/Type.h" #include "llvm/ADT/ArrayRef.h" +#include "llvm/Support/TrailingObjects.h" namespace clang { -class Expr; /// \brief This represents '#pragma omp threadprivate ...' directive. /// For example, in the following, both 'a' and 'A::b' are threadprivate: @@ -86,6 +89,107 @@ public: static bool classofKind(Kind K) { return K == OMPThreadPrivate; } }; -} // end namespace clang +/// \brief This represents '#pragma omp declare reduction ...' directive. +/// For example, in the following, declared reduction 'foo' for types 'int' and +/// 'float': +/// +/// \code +/// #pragma omp declare reduction (foo : int,float : omp_out += omp_in) \ +/// initializer (omp_priv = 0) +/// \endcode +/// +/// Here 'omp_out += omp_in' is a combiner and 'omp_priv = 0' is an initializer. +class OMPDeclareReductionDecl final : public ValueDecl, public DeclContext { +private: + friend class ASTDeclReader; + /// \brief Combiner for declare reduction construct. + Expr *Combiner; + /// \brief Initializer for declare reduction construct. + Expr *Initializer; + /// \brief Reference to the previous declare reduction construct in the same + /// scope with the same name. Required for proper templates instantiation if + /// the declare reduction construct is declared inside compound statement. + LazyDeclPtr PrevDeclInScope; + + virtual void anchor(); + + OMPDeclareReductionDecl(Kind DK, DeclContext *DC, SourceLocation L, + DeclarationName Name, QualType Ty, + OMPDeclareReductionDecl *PrevDeclInScope) + : ValueDecl(DK, DC, L, Name, Ty), DeclContext(DK), Combiner(nullptr), + Initializer(nullptr), PrevDeclInScope(PrevDeclInScope) {} + + void setPrevDeclInScope(OMPDeclareReductionDecl *Prev) { + PrevDeclInScope = Prev; + } + +public: + /// \brief Create declare reduction node. + static OMPDeclareReductionDecl * + Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, + QualType T, OMPDeclareReductionDecl *PrevDeclInScope); + /// \brief Create deserialized declare reduction node. + static OMPDeclareReductionDecl *CreateDeserialized(ASTContext &C, + unsigned ID); + + /// \brief Get combiner expression of the declare reduction construct. + Expr *getCombiner() { return Combiner; } + const Expr *getCombiner() const { return Combiner; } + /// \brief Set combiner expression for the declare reduction construct. + void setCombiner(Expr *E) { Combiner = E; } + + /// \brief Get initializer expression (if specified) of the declare reduction + /// construct. + Expr *getInitializer() { return Initializer; } + const Expr *getInitializer() const { return Initializer; } + /// \brief Set initializer expression for the declare reduction construct. + void setInitializer(Expr *E) { Initializer = E; } + + /// \brief Get reference to previous declare reduction construct in the same + /// scope with the same name. + OMPDeclareReductionDecl *getPrevDeclInScope(); + const OMPDeclareReductionDecl *getPrevDeclInScope() const; + + static bool classof(const Decl *D) { return classofKind(D->getKind()); } + static bool classofKind(Kind K) { return K == OMPDeclareReduction; } + static DeclContext *castToDeclContext(const OMPDeclareReductionDecl *D) { + return static_cast<DeclContext *>(const_cast<OMPDeclareReductionDecl *>(D)); + } + static OMPDeclareReductionDecl *castFromDeclContext(const DeclContext *DC) { + return static_cast<OMPDeclareReductionDecl *>( + const_cast<DeclContext *>(DC)); + } +}; + +/// Pseudo declaration for capturing expressions. Also is used for capturing of +/// non-static data members in non-static member functions. +/// +/// Clang supports capturing of variables only, but OpenMP 4.5 allows to +/// privatize non-static members of current class in non-static member +/// functions. This pseudo-declaration allows properly handle this kind of +/// capture by wrapping captured expression into a variable-like declaration. +class OMPCapturedExprDecl final : public VarDecl { + friend class ASTDeclReader; + void anchor() override; + + OMPCapturedExprDecl(ASTContext &C, DeclContext *DC, IdentifierInfo *Id, + QualType Type) + : VarDecl(OMPCapturedExpr, C, DC, SourceLocation(), SourceLocation(), Id, + Type, nullptr, SC_None) { + setImplicit(); + } + +public: + static OMPCapturedExprDecl *Create(ASTContext &C, DeclContext *DC, + IdentifierInfo *Id, QualType T); + + static OMPCapturedExprDecl *CreateDeserialized(ASTContext &C, unsigned ID); + + // Implement isa/cast/dyncast/etc. + static bool classof(const Decl *D) { return classofKind(D->getKind()); } + static bool classofKind(Kind K) { return K == OMPCapturedExpr; } +}; + +} // end namespace clang #endif diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h index a9109ef114264..4ac8cdc9beeb1 100644 --- a/include/clang/AST/DeclTemplate.h +++ b/include/clang/AST/DeclTemplate.h @@ -22,6 +22,7 @@ #include "llvm/Support/Compiler.h" #include "llvm/Support/TrailingObjects.h" #include <limits> +#include <utility> namespace clang { @@ -183,7 +184,7 @@ class TemplateArgumentList final // Constructs an instance with an internal Argument list, containing // a copy of the Args array. (Called by CreateCopy) - TemplateArgumentList(const TemplateArgument *Args, unsigned NumArgs); + TemplateArgumentList(ArrayRef<TemplateArgument> Args); public: /// \brief Type used to indicate that the template argument list itself is a @@ -193,16 +194,14 @@ public: /// \brief Create a new template argument list that copies the given set of /// template arguments. static TemplateArgumentList *CreateCopy(ASTContext &Context, - const TemplateArgument *Args, - unsigned NumArgs); + ArrayRef<TemplateArgument> Args); /// \brief Construct a new, temporary template argument list on the stack. /// /// The template argument list does not own the template arguments /// provided. - explicit TemplateArgumentList(OnStackType, const TemplateArgument *Args, - unsigned NumArgs) - : Arguments(Args), NumArguments(NumArgs) {} + explicit TemplateArgumentList(OnStackType, ArrayRef<TemplateArgument> Args) + : Arguments(Args.data()), NumArguments(Args.size()) {} /// \brief Produces a shallow copy of the given template argument list. /// @@ -332,24 +331,23 @@ class TemplateDecl : public NamedDecl { void anchor() override; protected: // This is probably never used. - TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L, - DeclarationName Name) - : NamedDecl(DK, DC, L, Name), TemplatedDecl(nullptr), - TemplateParams(nullptr) {} + TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName Name) + : NamedDecl(DK, DC, L, Name), TemplatedDecl(nullptr, false), + TemplateParams(nullptr) {} // Construct a template decl with the given name and parameters. // Used when there is not templated element (tt-params). - TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L, - DeclarationName Name, TemplateParameterList *Params) - : NamedDecl(DK, DC, L, Name), TemplatedDecl(nullptr), - TemplateParams(Params) {} + TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName Name, + TemplateParameterList *Params) + : NamedDecl(DK, DC, L, Name), TemplatedDecl(nullptr, false), + TemplateParams(Params) {} // Construct a template decl with name, parameters, and templated element. - TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L, - DeclarationName Name, TemplateParameterList *Params, - NamedDecl *Decl) - : NamedDecl(DK, DC, L, Name), TemplatedDecl(Decl), - TemplateParams(Params) { } + TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName Name, + TemplateParameterList *Params, NamedDecl *Decl) + : NamedDecl(DK, DC, L, Name), TemplatedDecl(Decl, false), + TemplateParams(Params) {} + public: /// Get the list of template parameters TemplateParameterList *getTemplateParameters() const { @@ -357,7 +355,7 @@ public: } /// Get the underlying, templated declaration. - NamedDecl *getTemplatedDecl() const { return TemplatedDecl; } + NamedDecl *getTemplatedDecl() const { return TemplatedDecl.getPointer(); } // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } @@ -367,20 +365,30 @@ public: SourceRange getSourceRange() const override LLVM_READONLY { return SourceRange(TemplateParams->getTemplateLoc(), - TemplatedDecl->getSourceRange().getEnd()); + TemplatedDecl.getPointer()->getSourceRange().getEnd()); } + /// Whether this is a (C++ Concepts TS) function or variable concept. + bool isConcept() const { return TemplatedDecl.getInt(); } + void setConcept() { TemplatedDecl.setInt(true); } + protected: - NamedDecl *TemplatedDecl; + /// \brief The named declaration from which this template was instantiated. + /// (or null). + /// + /// The boolean value will be true to indicate that this template + /// (function or variable) is a concept. + llvm::PointerIntPair<NamedDecl *, 1, bool> TemplatedDecl; + TemplateParameterList* TemplateParams; public: /// \brief Initialize the underlying templated declaration and /// template parameters. void init(NamedDecl *templatedDecl, TemplateParameterList* templateParams) { - assert(!TemplatedDecl && "TemplatedDecl already set!"); + assert(!TemplatedDecl.getPointer() && "TemplatedDecl already set!"); assert(!TemplateParams && "TemplateParams already set!"); - TemplatedDecl = templatedDecl; + TemplatedDecl.setPointer(templatedDecl); TemplateParams = templateParams; } }; @@ -481,8 +489,8 @@ public: Profile(llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs, ASTContext &Context) { ID.AddInteger(TemplateArgs.size()); - for (unsigned Arg = 0; Arg != TemplateArgs.size(); ++Arg) - TemplateArgs[Arg].Profile(ID, Context); + for (const TemplateArgument &TemplateArg : TemplateArgs) + TemplateArg.Profile(ID, Context); } }; @@ -889,7 +897,7 @@ public: /// Get the underlying function declaration of the template. FunctionDecl *getTemplatedDecl() const { - return static_cast<FunctionDecl*>(TemplatedDecl); + return static_cast<FunctionDecl *>(TemplatedDecl.getPointer()); } /// Returns whether this template declaration defines the primary @@ -1171,9 +1179,8 @@ class NonTypeTemplateParmDecl final SourceLocation IdLoc, unsigned D, unsigned P, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, - const QualType *ExpandedTypes, - unsigned NumExpandedTypes, - TypeSourceInfo **ExpandedTInfos); + ArrayRef<QualType> ExpandedTypes, + ArrayRef<TypeSourceInfo *> ExpandedTInfos); friend class ASTDeclReader; friend TrailingObjects; @@ -1187,9 +1194,8 @@ public: static NonTypeTemplateParmDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, unsigned D, unsigned P, IdentifierInfo *Id, - QualType T, TypeSourceInfo *TInfo, - const QualType *ExpandedTypes, unsigned NumExpandedTypes, - TypeSourceInfo **ExpandedTInfos); + QualType T, TypeSourceInfo *TInfo, ArrayRef<QualType> ExpandedTypes, + ArrayRef<TypeSourceInfo *> ExpandedTInfos); static NonTypeTemplateParmDecl *CreateDeserialized(ASTContext &C, unsigned ID); @@ -1352,8 +1358,7 @@ class TemplateTemplateParmDecl final TemplateTemplateParmDecl(DeclContext *DC, SourceLocation L, unsigned D, unsigned P, IdentifierInfo *Id, TemplateParameterList *Params, - unsigned NumExpansions, - TemplateParameterList * const *Expansions); + ArrayRef<TemplateParameterList *> Expansions); public: static TemplateTemplateParmDecl *Create(const ASTContext &C, DeclContext *DC, @@ -1480,8 +1485,8 @@ public: }; /// \brief Represents the builtin template declaration which is used to -/// implement __make_integer_seq. It serves no real purpose beyond existing as -/// a place to hold template parameters. +/// implement __make_integer_seq and other builtin templates. It serves +/// no real purpose beyond existing as a place to hold template parameters. class BuiltinTemplateDecl : public TemplateDecl { void anchor() override; @@ -1573,8 +1578,7 @@ protected: DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, ClassTemplateDecl *SpecializedTemplate, - const TemplateArgument *Args, - unsigned NumArgs, + ArrayRef<TemplateArgument> Args, ClassTemplateSpecializationDecl *PrevDecl); explicit ClassTemplateSpecializationDecl(ASTContext &C, Kind DK); @@ -1584,8 +1588,7 @@ public: Create(ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, ClassTemplateDecl *SpecializedTemplate, - const TemplateArgument *Args, - unsigned NumArgs, + ArrayRef<TemplateArgument> Args, ClassTemplateSpecializationDecl *PrevDecl); static ClassTemplateSpecializationDecl * CreateDeserialized(ASTContext &C, unsigned ID); @@ -1762,8 +1765,8 @@ public: Profile(llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs, ASTContext &Context) { ID.AddInteger(TemplateArgs.size()); - for (unsigned Arg = 0; Arg != TemplateArgs.size(); ++Arg) - TemplateArgs[Arg].Profile(ID, Context); + for (const TemplateArgument &TemplateArg : TemplateArgs) + TemplateArg.Profile(ID, Context); } static bool classof(const Decl *D) { return classofKind(D->getKind()); } @@ -1801,8 +1804,7 @@ class ClassTemplatePartialSpecializationDecl SourceLocation IdLoc, TemplateParameterList *Params, ClassTemplateDecl *SpecializedTemplate, - const TemplateArgument *Args, - unsigned NumArgs, + ArrayRef<TemplateArgument> Args, const ASTTemplateArgumentListInfo *ArgsAsWritten, ClassTemplatePartialSpecializationDecl *PrevDecl); @@ -1817,8 +1819,7 @@ public: SourceLocation StartLoc, SourceLocation IdLoc, TemplateParameterList *Params, ClassTemplateDecl *SpecializedTemplate, - const TemplateArgument *Args, - unsigned NumArgs, + ArrayRef<TemplateArgument> Args, const TemplateArgumentListInfo &ArgInfos, QualType CanonInjectedType, ClassTemplatePartialSpecializationDecl *PrevDecl); @@ -1867,6 +1868,10 @@ public: cast<ClassTemplatePartialSpecializationDecl>(getFirstDecl()); return First->InstantiatedFromMember.getPointer(); } + ClassTemplatePartialSpecializationDecl * + getInstantiatedFromMemberTemplate() const { + return getInstantiatedFromMember(); + } void setInstantiatedFromMember( ClassTemplatePartialSpecializationDecl *PartialSpec) { @@ -1982,7 +1987,7 @@ public: /// \brief Get the underlying class declarations of the template. CXXRecordDecl *getTemplatedDecl() const { - return static_cast<CXXRecordDecl *>(TemplatedDecl); + return static_cast<CXXRecordDecl *>(TemplatedDecl.getPointer()); } /// \brief Returns whether this template declaration defines the primary @@ -2154,18 +2159,11 @@ private: // Location of the 'friend' specifier. SourceLocation FriendLoc; - FriendTemplateDecl(DeclContext *DC, SourceLocation Loc, - unsigned NParams, - TemplateParameterList **Params, - FriendUnion Friend, - SourceLocation FriendLoc) - : Decl(Decl::FriendTemplate, DC, Loc), - NumParams(NParams), - Params(Params), - Friend(Friend), - FriendLoc(FriendLoc) - {} + MutableArrayRef<TemplateParameterList *> Params, + FriendUnion Friend, SourceLocation FriendLoc) + : Decl(Decl::FriendTemplate, DC, Loc), NumParams(Params.size()), + Params(Params.data()), Friend(Friend), FriendLoc(FriendLoc) {} FriendTemplateDecl(EmptyShell Empty) : Decl(Decl::FriendTemplate, Empty), @@ -2174,12 +2172,10 @@ private: {} public: - static FriendTemplateDecl *Create(ASTContext &Context, - DeclContext *DC, SourceLocation Loc, - unsigned NParams, - TemplateParameterList **Params, - FriendUnion Friend, - SourceLocation FriendLoc); + static FriendTemplateDecl * + Create(ASTContext &Context, DeclContext *DC, SourceLocation Loc, + MutableArrayRef<TemplateParameterList *> Params, FriendUnion Friend, + SourceLocation FriendLoc); static FriendTemplateDecl *CreateDeserialized(ASTContext &C, unsigned ID); @@ -2245,7 +2241,7 @@ protected: public: /// Get the underlying function declaration of the template. TypeAliasDecl *getTemplatedDecl() const { - return static_cast<TypeAliasDecl*>(TemplatedDecl); + return static_cast<TypeAliasDecl *>(TemplatedDecl.getPointer()); } @@ -2319,9 +2315,9 @@ class ClassScopeFunctionSpecializationDecl : public Decl { ClassScopeFunctionSpecializationDecl(DeclContext *DC, SourceLocation Loc, CXXMethodDecl *FD, bool Args, TemplateArgumentListInfo TemplArgs) - : Decl(Decl::ClassScopeFunctionSpecialization, DC, Loc), - Specialization(FD), HasExplicitTemplateArgs(Args), - TemplateArgs(TemplArgs) {} + : Decl(Decl::ClassScopeFunctionSpecialization, DC, Loc), + Specialization(FD), HasExplicitTemplateArgs(Args), + TemplateArgs(std::move(TemplArgs)) {} ClassScopeFunctionSpecializationDecl(EmptyShell Empty) : Decl(Decl::ClassScopeFunctionSpecialization, Empty) {} @@ -2342,7 +2338,7 @@ public: bool HasExplicitTemplateArgs, TemplateArgumentListInfo TemplateArgs) { return new (C, DC) ClassScopeFunctionSpecializationDecl( - DC, Loc, FD, HasExplicitTemplateArgs, TemplateArgs); + DC, Loc, FD, HasExplicitTemplateArgs, std::move(TemplateArgs)); } static ClassScopeFunctionSpecializationDecl * @@ -2428,8 +2424,8 @@ protected: SourceLocation StartLoc, SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo, - StorageClass S, const TemplateArgument *Args, - unsigned NumArgs); + StorageClass S, + ArrayRef<TemplateArgument> Args); explicit VarTemplateSpecializationDecl(Kind DK, ASTContext &Context); @@ -2437,8 +2433,8 @@ public: static VarTemplateSpecializationDecl * Create(ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T, - TypeSourceInfo *TInfo, StorageClass S, const TemplateArgument *Args, - unsigned NumArgs); + TypeSourceInfo *TInfo, StorageClass S, + ArrayRef<TemplateArgument> Args); static VarTemplateSpecializationDecl *CreateDeserialized(ASTContext &C, unsigned ID); @@ -2502,17 +2498,11 @@ public: /// it was instantiated. llvm::PointerUnion<VarTemplateDecl *, VarTemplatePartialSpecializationDecl *> getInstantiatedFrom() const { - if (getSpecializationKind() != TSK_ImplicitInstantiation && - getSpecializationKind() != TSK_ExplicitInstantiationDefinition && - getSpecializationKind() != TSK_ExplicitInstantiationDeclaration) + if (!isTemplateInstantiation(getSpecializationKind())) return llvm::PointerUnion<VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>(); - if (SpecializedPartialSpecialization *PartialSpec = - SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>()) - return PartialSpec->PartialSpecialization; - - return SpecializedTemplate.get<VarTemplateDecl *>(); + return getSpecializedTemplateOrPartial(); } /// \brief Retrieve the variable template or variable template partial @@ -2610,8 +2600,8 @@ public: ArrayRef<TemplateArgument> TemplateArgs, ASTContext &Context) { ID.AddInteger(TemplateArgs.size()); - for (unsigned Arg = 0; Arg != TemplateArgs.size(); ++Arg) - TemplateArgs[Arg].Profile(ID, Context); + for (const TemplateArgument &TemplateArg : TemplateArgs) + TemplateArg.Profile(ID, Context); } static bool classof(const Decl *D) { return classofKind(D->getKind()); } @@ -2647,7 +2637,7 @@ class VarTemplatePartialSpecializationDecl ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, TemplateParameterList *Params, VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo, - StorageClass S, const TemplateArgument *Args, unsigned NumArgs, + StorageClass S, ArrayRef<TemplateArgument> Args, const ASTTemplateArgumentListInfo *ArgInfos); VarTemplatePartialSpecializationDecl(ASTContext &Context) @@ -2660,8 +2650,8 @@ public: Create(ASTContext &Context, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, TemplateParameterList *Params, VarTemplateDecl *SpecializedTemplate, QualType T, - TypeSourceInfo *TInfo, StorageClass S, const TemplateArgument *Args, - unsigned NumArgs, const TemplateArgumentListInfo &ArgInfos); + TypeSourceInfo *TInfo, StorageClass S, ArrayRef<TemplateArgument> Args, + const TemplateArgumentListInfo &ArgInfos); static VarTemplatePartialSpecializationDecl *CreateDeserialized(ASTContext &C, unsigned ID); @@ -2808,7 +2798,7 @@ public: /// \brief Get the underlying variable declarations of the template. VarDecl *getTemplatedDecl() const { - return static_cast<VarDecl *>(TemplatedDecl); + return static_cast<VarDecl *>(TemplatedDecl.getPointer()); } /// \brief Returns whether this template declaration defines the primary diff --git a/include/clang/AST/DeclarationName.h b/include/clang/AST/DeclarationName.h index 9482e83e81dc3..2d3cfe27a1659 100644 --- a/include/clang/AST/DeclarationName.h +++ b/include/clang/AST/DeclarationName.h @@ -30,6 +30,7 @@ namespace clang { class IdentifierInfo; class MultiKeywordSelector; enum OverloadedOperatorKind : int; + struct PrintingPolicy; class QualType; class Type; class TypeSourceInfo; @@ -302,7 +303,9 @@ public: } static int compare(DeclarationName LHS, DeclarationName RHS); - + + void print(raw_ostream &OS, const PrintingPolicy &Policy); + void dump() const; }; diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h index 38733eee82c36..9179c7736a9a4 100644 --- a/include/clang/AST/Expr.h +++ b/include/clang/AST/Expr.h @@ -29,6 +29,7 @@ #include "llvm/ADT/APSInt.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" +#include "llvm/Support/AtomicOrdering.h" #include "llvm/Support/Compiler.h" namespace clang { @@ -593,6 +594,13 @@ public: bool EvaluateAsInt(llvm::APSInt &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects = SE_NoSideEffects) const; + /// EvaluateAsFloat - Return true if this is a constant which we can fold and + /// convert to a floating point value, using any crazy technique that we + /// want to. + bool + EvaluateAsFloat(llvm::APFloat &Result, const ASTContext &Ctx, + SideEffectsKind AllowSideEffects = SE_NoSideEffects) const; + /// isEvaluatable - Call EvaluateAsRValue to see if this expression can be /// constant folded without side-effects, but discard the result. bool isEvaluatable(const ASTContext &Ctx, @@ -847,10 +855,12 @@ public: ExprObjectKind OK = OK_Ordinary, Expr *SourceExpr = nullptr) : Expr(OpaqueValueExprClass, T, VK, OK, - T->isDependentType(), + T->isDependentType() || + (SourceExpr && SourceExpr->isTypeDependent()), T->isDependentType() || (SourceExpr && SourceExpr->isValueDependent()), - T->isInstantiationDependentType(), + T->isInstantiationDependentType() || + (SourceExpr && SourceExpr->isInstantiationDependent()), false), SourceExpr(SourceExpr), Loc(Loc) { } @@ -1110,6 +1120,10 @@ public: return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->NumTemplateArgs; } + ArrayRef<TemplateArgumentLoc> template_arguments() const { + return {getTemplateArgs(), getNumTemplateArgs()}; + } + /// \brief Returns true if this expression refers to a function that /// was resolved from an overloaded set having size greater than 1. bool hadMultipleCandidates() const { @@ -2137,11 +2151,15 @@ class CallExpr : public Expr { unsigned NumArgs; SourceLocation RParenLoc; + void updateDependenciesFromArg(Expr *Arg); + protected: // These versions of the constructor are for derived classes. - CallExpr(const ASTContext& C, StmtClass SC, Expr *fn, unsigned NumPreArgs, - ArrayRef<Expr*> args, QualType t, ExprValueKind VK, - SourceLocation rparenloc); + CallExpr(const ASTContext &C, StmtClass SC, Expr *fn, + ArrayRef<Expr *> preargs, ArrayRef<Expr *> args, QualType t, + ExprValueKind VK, SourceLocation rparenloc); + CallExpr(const ASTContext &C, StmtClass SC, Expr *fn, ArrayRef<Expr *> args, + QualType t, ExprValueKind VK, SourceLocation rparenloc); CallExpr(const ASTContext &C, StmtClass SC, unsigned NumPreArgs, EmptyShell Empty); @@ -2477,6 +2495,10 @@ public: return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->NumTemplateArgs; } + ArrayRef<TemplateArgumentLoc> template_arguments() const { + return {getTemplateArgs(), getNumTemplateArgs()}; + } + /// \brief Retrieve the member declaration name info. DeclarationNameInfo getMemberNameInfo() const { return DeclarationNameInfo(MemberDecl->getDeclName(), @@ -3942,7 +3964,7 @@ private: /// Whether this designated initializer used the GNU deprecated /// syntax rather than the C99 '=' syntax. - bool GNUSyntax : 1; + unsigned GNUSyntax : 1; /// The number of designators in this initializer expression. unsigned NumDesignators : 15; @@ -3956,11 +3978,10 @@ private: /// expression. Designator *Designators; - - DesignatedInitExpr(const ASTContext &C, QualType Ty, unsigned NumDesignators, - const Designator *Designators, + DesignatedInitExpr(const ASTContext &C, QualType Ty, + llvm::ArrayRef<Designator> Designators, SourceLocation EqualOrColonLoc, bool GNUSyntax, - ArrayRef<Expr*> IndexExprs, Expr *Init); + ArrayRef<Expr *> IndexExprs, Expr *Init); explicit DesignatedInitExpr(unsigned NumSubExprs) : Expr(DesignatedInitExprClass, EmptyShell()), @@ -4120,8 +4141,7 @@ public: }; static DesignatedInitExpr *Create(const ASTContext &C, - Designator *Designators, - unsigned NumDesignators, + llvm::ArrayRef<Designator> Designators, ArrayRef<Expr*> IndexExprs, SourceLocation EqualOrColonLoc, bool GNUSyntax, Expr *Init); @@ -4133,48 +4153,15 @@ public: unsigned size() const { return NumDesignators; } // Iterator access to the designators. - typedef Designator *designators_iterator; - designators_iterator designators_begin() { return Designators; } - designators_iterator designators_end() { - return Designators + NumDesignators; - } - - typedef const Designator *const_designators_iterator; - const_designators_iterator designators_begin() const { return Designators; } - const_designators_iterator designators_end() const { - return Designators + NumDesignators; - } - - typedef llvm::iterator_range<designators_iterator> designators_range; - designators_range designators() { - return designators_range(designators_begin(), designators_end()); - } - - typedef llvm::iterator_range<const_designators_iterator> - designators_const_range; - designators_const_range designators() const { - return designators_const_range(designators_begin(), designators_end()); + llvm::MutableArrayRef<Designator> designators() { + return {Designators, NumDesignators}; } - typedef std::reverse_iterator<designators_iterator> - reverse_designators_iterator; - reverse_designators_iterator designators_rbegin() { - return reverse_designators_iterator(designators_end()); - } - reverse_designators_iterator designators_rend() { - return reverse_designators_iterator(designators_begin()); + llvm::ArrayRef<Designator> designators() const { + return {Designators, NumDesignators}; } - typedef std::reverse_iterator<const_designators_iterator> - const_reverse_designators_iterator; - const_reverse_designators_iterator designators_rbegin() const { - return const_reverse_designators_iterator(designators_end()); - } - const_reverse_designators_iterator designators_rend() const { - return const_reverse_designators_iterator(designators_begin()); - } - - Designator *getDesignator(unsigned Idx) { return &designators_begin()[Idx]; } + Designator *getDesignator(unsigned Idx) { return &designators()[Idx]; } void setDesignators(const ASTContext &C, const Designator *Desigs, unsigned NumDesigs); @@ -4824,16 +4811,6 @@ public: BI_First = 0 }; - // The ABI values for various atomic memory orderings. - enum AtomicOrderingKind { - AO_ABI_memory_order_relaxed = 0, - AO_ABI_memory_order_consume = 1, - AO_ABI_memory_order_acquire = 2, - AO_ABI_memory_order_release = 3, - AO_ABI_memory_order_acq_rel = 4, - AO_ABI_memory_order_seq_cst = 5 - }; - private: enum { PTR, ORDER, VAL1, ORDER_FAIL, VAL2, WEAK, END_EXPR }; Stmt* SubExprs[END_EXPR]; @@ -4882,9 +4859,12 @@ public: } AtomicOp getOp() const { return Op; } - unsigned getNumSubExprs() { return NumSubExprs; } + unsigned getNumSubExprs() const { return NumSubExprs; } Expr **getSubExprs() { return reinterpret_cast<Expr **>(SubExprs); } + const Expr * const *getSubExprs() const { + return reinterpret_cast<Expr * const *>(SubExprs); + } bool isVolatile() const { return getPtr()->getType()->getPointeeType().isVolatileQualified(); diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h index 6821274986479..86cbfb2cd0b4c 100644 --- a/include/clang/AST/ExprCXX.h +++ b/include/clang/AST/ExprCXX.h @@ -16,6 +16,7 @@ #define LLVM_CLANG_AST_EXPRCXX_H #include "clang/AST/Decl.h" +#include "clang/AST/DeclCXX.h" #include "clang/AST/Expr.h" #include "clang/AST/LambdaCapture.h" #include "clang/AST/TemplateBase.h" @@ -26,9 +27,6 @@ namespace clang { -class CXXConstructorDecl; -class CXXDestructorDecl; -class CXXMethodDecl; class CXXTemporary; class MSPropertyDecl; class TemplateArgumentListInfo; @@ -66,8 +64,7 @@ public: CXXOperatorCallExpr(ASTContext& C, OverloadedOperatorKind Op, Expr *fn, ArrayRef<Expr*> args, QualType t, ExprValueKind VK, SourceLocation operatorloc, bool fpContractable) - : CallExpr(C, CXXOperatorCallExprClass, fn, 0, args, t, VK, - operatorloc), + : CallExpr(C, CXXOperatorCallExprClass, fn, args, t, VK, operatorloc), Operator(Op), FPContractable(fpContractable) { Range = getSourceRangeImpl(); } @@ -125,7 +122,7 @@ class CXXMemberCallExpr : public CallExpr { public: CXXMemberCallExpr(ASTContext &C, Expr *fn, ArrayRef<Expr*> args, QualType t, ExprValueKind VK, SourceLocation RP) - : CallExpr(C, CXXMemberCallExprClass, fn, 0, args, t, VK, RP) {} + : CallExpr(C, CXXMemberCallExprClass, fn, args, t, VK, RP) {} CXXMemberCallExpr(ASTContext &C, EmptyShell Empty) : CallExpr(C, CXXMemberCallExprClass, Empty) { } @@ -146,6 +143,14 @@ public: /// FIXME: Returns 0 for member pointer call exprs. CXXRecordDecl *getRecordDecl() const; + SourceLocation getExprLoc() const LLVM_READONLY { + SourceLocation CLoc = getCallee()->getExprLoc(); + if (CLoc.isValid()) + return CLoc; + + return getLocStart(); + } + static bool classof(const Stmt *T) { return T->getStmtClass() == CXXMemberCallExprClass; } @@ -160,9 +165,7 @@ public: CUDAKernelCallExpr(ASTContext &C, Expr *fn, CallExpr *Config, ArrayRef<Expr*> args, QualType t, ExprValueKind VK, SourceLocation RP) - : CallExpr(C, CUDAKernelCallExprClass, fn, END_PREARG, args, t, VK, RP) { - setConfig(Config); - } + : CallExpr(C, CUDAKernelCallExprClass, fn, Config, args, t, VK, RP) {} CUDAKernelCallExpr(ASTContext &C, EmptyShell Empty) : CallExpr(C, CUDAKernelCallExprClass, END_PREARG, Empty) { } @@ -171,7 +174,20 @@ public: return cast_or_null<CallExpr>(getPreArg(CONFIG)); } CallExpr *getConfig() { return cast_or_null<CallExpr>(getPreArg(CONFIG)); } - void setConfig(CallExpr *E) { setPreArg(CONFIG, E); } + + /// \brief Sets the kernel configuration expression. + /// + /// Note that this method cannot be called if config has already been set to a + /// non-null value. + void setConfig(CallExpr *E) { + assert(!getConfig() && + "Cannot call setConfig if config is not null"); + setPreArg(CONFIG, E); + setInstantiationDependent(isInstantiationDependent() || + E->isInstantiationDependent()); + setContainsUnexpandedParameterPack(containsUnexpandedParameterPack() || + E->containsUnexpandedParameterPack()); + } static bool classof(const Stmt *T) { return T->getStmtClass() == CUDAKernelCallExprClass; @@ -398,7 +414,7 @@ public: UserDefinedLiteral(const ASTContext &C, Expr *Fn, ArrayRef<Expr*> Args, QualType T, ExprValueKind VK, SourceLocation LitEndLoc, SourceLocation SuffixLoc) - : CallExpr(C, UserDefinedLiteralClass, Fn, 0, Args, T, VK, LitEndLoc), + : CallExpr(C, UserDefinedLiteralClass, Fn, Args, T, VK, LitEndLoc), UDSuffixLoc(SuffixLoc) {} explicit UserDefinedLiteral(const ASTContext &C, EmptyShell Empty) : CallExpr(C, UserDefinedLiteralClass, Empty) {} @@ -768,22 +784,23 @@ public: class CXXUuidofExpr : public Expr { private: llvm::PointerUnion<Stmt *, TypeSourceInfo *> Operand; + StringRef UuidStr; SourceRange Range; public: - CXXUuidofExpr(QualType Ty, TypeSourceInfo *Operand, SourceRange R) - : Expr(CXXUuidofExprClass, Ty, VK_LValue, OK_Ordinary, - false, Operand->getType()->isDependentType(), - Operand->getType()->isInstantiationDependentType(), - Operand->getType()->containsUnexpandedParameterPack()), - Operand(Operand), Range(R) { } - - CXXUuidofExpr(QualType Ty, Expr *Operand, SourceRange R) - : Expr(CXXUuidofExprClass, Ty, VK_LValue, OK_Ordinary, - false, Operand->isTypeDependent(), - Operand->isInstantiationDependent(), - Operand->containsUnexpandedParameterPack()), - Operand(Operand), Range(R) { } + CXXUuidofExpr(QualType Ty, TypeSourceInfo *Operand, StringRef UuidStr, + SourceRange R) + : Expr(CXXUuidofExprClass, Ty, VK_LValue, OK_Ordinary, false, + Operand->getType()->isDependentType(), + Operand->getType()->isInstantiationDependentType(), + Operand->getType()->containsUnexpandedParameterPack()), + Operand(Operand), UuidStr(UuidStr), Range(R) {} + + CXXUuidofExpr(QualType Ty, Expr *Operand, StringRef UuidStr, SourceRange R) + : Expr(CXXUuidofExprClass, Ty, VK_LValue, OK_Ordinary, false, + Operand->isTypeDependent(), Operand->isInstantiationDependent(), + Operand->containsUnexpandedParameterPack()), + Operand(Operand), UuidStr(UuidStr), Range(R) {} CXXUuidofExpr(EmptyShell Empty, bool isExpr) : Expr(CXXUuidofExprClass, Empty) { @@ -820,7 +837,8 @@ public: Operand = E; } - StringRef getUuidAsStringRef(ASTContext &Context) const; + void setUuidStr(StringRef US) { UuidStr = US; } + StringRef getUuidStr() const { return UuidStr; } SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); } SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); } @@ -831,11 +849,6 @@ public: return T->getStmtClass() == CXXUuidofExprClass; } - /// Grabs __declspec(uuid()) off a type, or returns 0 if we cannot resolve to - /// a single GUID. - static const UuidAttr *GetUuidAttrOfType(QualType QT, - bool *HasMultipleGUIDsPtr = nullptr); - // Iterators child_range children() { if (isTypeOperand()) @@ -1161,18 +1174,21 @@ private: SourceLocation Loc; SourceRange ParenOrBraceRange; unsigned NumArgs : 16; - bool Elidable : 1; - bool HadMultipleCandidates : 1; - bool ListInitialization : 1; - bool StdInitListInitialization : 1; - bool ZeroInitialization : 1; + unsigned Elidable : 1; + unsigned HadMultipleCandidates : 1; + unsigned ListInitialization : 1; + unsigned StdInitListInitialization : 1; + unsigned ZeroInitialization : 1; unsigned ConstructKind : 2; Stmt **Args; + void setConstructor(CXXConstructorDecl *C) { Constructor = C; } + protected: CXXConstructExpr(const ASTContext &C, StmtClass SC, QualType T, SourceLocation Loc, - CXXConstructorDecl *d, bool elidable, + CXXConstructorDecl *Ctor, + bool Elidable, ArrayRef<Expr *> Args, bool HadMultipleCandidates, bool ListInitialization, @@ -1191,15 +1207,12 @@ protected: public: /// \brief Construct an empty C++ construction expression. explicit CXXConstructExpr(EmptyShell Empty) - : Expr(CXXConstructExprClass, Empty), Constructor(nullptr), - NumArgs(0), Elidable(false), HadMultipleCandidates(false), - ListInitialization(false), ZeroInitialization(false), - ConstructKind(0), Args(nullptr) - { } + : CXXConstructExpr(CXXConstructExprClass, Empty) {} static CXXConstructExpr *Create(const ASTContext &C, QualType T, SourceLocation Loc, - CXXConstructorDecl *D, bool Elidable, + CXXConstructorDecl *Ctor, + bool Elidable, ArrayRef<Expr *> Args, bool HadMultipleCandidates, bool ListInitialization, @@ -1208,8 +1221,8 @@ public: ConstructionKind ConstructKind, SourceRange ParenOrBraceRange); + /// \brief Get the constructor that this expression will (ultimately) call. CXXConstructorDecl *getConstructor() const { return Constructor; } - void setConstructor(CXXConstructorDecl *C) { Constructor = C; } SourceLocation getLocation() const { return Loc; } void setLocation(SourceLocation Loc) { this->Loc = Loc; } @@ -1305,6 +1318,73 @@ public: friend class ASTStmtReader; }; +/// \brief Represents a call to an inherited base class constructor from an +/// inheriting constructor. This call implicitly forwards the arguments from +/// the enclosing context (an inheriting constructor) to the specified inherited +/// base class constructor. +class CXXInheritedCtorInitExpr : public Expr { +private: + CXXConstructorDecl *Constructor; + + /// The location of the using declaration. + SourceLocation Loc; + + /// Whether this is the construction of a virtual base. + unsigned ConstructsVirtualBase : 1; + + /// Whether the constructor is inherited from a virtual base class of the + /// class that we construct. + unsigned InheritedFromVirtualBase : 1; + +public: + /// \brief Construct a C++ inheriting construction expression. + CXXInheritedCtorInitExpr(SourceLocation Loc, QualType T, + CXXConstructorDecl *Ctor, bool ConstructsVirtualBase, + bool InheritedFromVirtualBase) + : Expr(CXXInheritedCtorInitExprClass, T, VK_RValue, OK_Ordinary, false, + false, false, false), + Constructor(Ctor), Loc(Loc), + ConstructsVirtualBase(ConstructsVirtualBase), + InheritedFromVirtualBase(InheritedFromVirtualBase) { + assert(!T->isDependentType()); + } + + /// \brief Construct an empty C++ inheriting construction expression. + explicit CXXInheritedCtorInitExpr(EmptyShell Empty) + : Expr(CXXInheritedCtorInitExprClass, Empty), Constructor(nullptr), + ConstructsVirtualBase(false), InheritedFromVirtualBase(false) {} + + /// \brief Get the constructor that this expression will call. + CXXConstructorDecl *getConstructor() const { return Constructor; } + + /// \brief Determine whether this constructor is actually constructing + /// a base class (rather than a complete object). + bool constructsVBase() const { return ConstructsVirtualBase; } + CXXConstructExpr::ConstructionKind getConstructionKind() const { + return ConstructsVirtualBase ? CXXConstructExpr::CK_VirtualBase + : CXXConstructExpr::CK_NonVirtualBase; + } + + /// \brief Determine whether the inherited constructor is inherited from a + /// virtual base of the object we construct. If so, we are not responsible + /// for calling the inherited constructor (the complete object constructor + /// does that), and so we don't need to pass any arguments. + bool inheritedFromVBase() const { return InheritedFromVirtualBase; } + + SourceLocation getLocation() const LLVM_READONLY { return Loc; } + SourceLocation getLocStart() const LLVM_READONLY { return Loc; } + SourceLocation getLocEnd() const LLVM_READONLY { return Loc; } + + static bool classof(const Stmt *T) { + return T->getStmtClass() == CXXInheritedCtorInitExprClass; + } + child_range children() { + return child_range(child_iterator(), child_iterator()); + } + + friend class ASTStmtReader; +}; + /// \brief Represents an explicit C++ type conversion that uses "functional" /// notation (C++ [expr.type.conv]). /// @@ -1375,7 +1455,8 @@ class CXXTemporaryObjectExpr : public CXXConstructExpr { TypeSourceInfo *Type; public: - CXXTemporaryObjectExpr(const ASTContext &C, CXXConstructorDecl *Cons, + CXXTemporaryObjectExpr(const ASTContext &C, + CXXConstructorDecl *Cons, TypeSourceInfo *Type, ArrayRef<Expr *> Args, SourceRange ParenOrBraceRange, @@ -1744,12 +1825,12 @@ class CXXNewExpr : public Expr { SourceRange DirectInitRange; /// Was the usage ::new, i.e. is the global new to be used? - bool GlobalNew : 1; + unsigned GlobalNew : 1; /// Do we allocate an array? If so, the first SubExpr is the size expression. - bool Array : 1; + unsigned Array : 1; /// If this is an array allocation, does the usual deallocation /// function for the allocated type want to know the allocated size? - bool UsualArrayDeleteWantsSize : 1; + unsigned UsualArrayDeleteWantsSize : 1; /// The number of placement new arguments. unsigned NumPlacementArgs : 13; /// What kind of initializer do we have? Could be none, parens, or braces. @@ -2348,7 +2429,7 @@ class ExpressionTraitExpr : public Expr { /// \brief The trait. A ExpressionTrait enum in MSVC compatible unsigned. unsigned ET : 31; /// \brief The value of the type trait. Unspecified if dependent. - bool Value : 1; + unsigned Value : 1; /// \brief The location of the type trait keyword. SourceLocation Loc; @@ -2557,6 +2638,10 @@ public: return getTrailingASTTemplateKWAndArgsInfo()->NumTemplateArgs; } + ArrayRef<TemplateArgumentLoc> template_arguments() const { + return {getTemplateArgs(), getNumTemplateArgs()}; + } + /// \brief Copies the template arguments into the given structure. void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const { if (hasExplicitTemplateArgs()) @@ -2810,6 +2895,10 @@ public: return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->NumTemplateArgs; } + ArrayRef<TemplateArgumentLoc> template_arguments() const { + return {getTemplateArgs(), getNumTemplateArgs()}; + } + /// Note: getLocStart() is the start of the whole DependentScopeDeclRefExpr, /// and differs from getLocation().getStart(). SourceLocation getLocStart() const LLVM_READONLY { @@ -2858,7 +2947,8 @@ private: Stmt *SubExpr; ExprWithCleanups(EmptyShell, unsigned NumObjects); - ExprWithCleanups(Expr *SubExpr, ArrayRef<CleanupObject> Objects); + ExprWithCleanups(Expr *SubExpr, bool CleanupsHaveSideEffects, + ArrayRef<CleanupObject> Objects); friend TrailingObjects; friend class ASTStmtReader; @@ -2868,6 +2958,7 @@ public: unsigned numObjects); static ExprWithCleanups *Create(const ASTContext &C, Expr *subexpr, + bool CleanupsHaveSideEffects, ArrayRef<CleanupObject> objects); ArrayRef<CleanupObject> getObjects() const { @@ -2884,6 +2975,9 @@ public: Expr *getSubExpr() { return cast<Expr>(SubExpr); } const Expr *getSubExpr() const { return cast<Expr>(SubExpr); } + bool cleanupsHaveSideEffects() const { + return ExprWithCleanupsBits.CleanupsHaveSideEffects; + } /// As with any mutator of the AST, be very careful /// when modifying an existing AST to preserve its invariants. @@ -3220,6 +3314,10 @@ public: return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->NumTemplateArgs; } + ArrayRef<TemplateArgumentLoc> template_arguments() const { + return {getTemplateArgs(), getNumTemplateArgs()}; + } + SourceLocation getLocStart() const LLVM_READONLY { if (!isImplicitAccess()) return Base->getLocStart(); diff --git a/include/clang/AST/ExprObjC.h b/include/clang/AST/ExprObjC.h index 61e6383bffedd..5f9623db24163 100644 --- a/include/clang/AST/ExprObjC.h +++ b/include/clang/AST/ExprObjC.h @@ -1562,7 +1562,52 @@ public: return T->getStmtClass() == ObjCBridgedCastExprClass; } }; - + +/// \brief A runtime availability query. +/// +/// There are 2 ways to spell this node: +/// \code +/// @available(macos 10.10, ios 8, *); // Objective-C +/// __builtin_available(macos 10.10, ios 8, *); // C, C++, and Objective-C +/// \endcode +/// +/// Note that we only need to keep track of one \c VersionTuple here, which is +/// the one that corresponds to the current deployment target. This is meant to +/// be used in the condition of an \c if, but it is also usable as top level +/// expressions. +/// +class ObjCAvailabilityCheckExpr : public Expr { + VersionTuple VersionToCheck; + SourceLocation AtLoc, RParen; + + friend class ASTStmtReader; +public: + ObjCAvailabilityCheckExpr(VersionTuple VersionToCheck, SourceLocation AtLoc, + SourceLocation RParen, QualType Ty) + : Expr(ObjCAvailabilityCheckExprClass, Ty, VK_RValue, OK_Ordinary, false, + false, false, false), + VersionToCheck(VersionToCheck), AtLoc(AtLoc), RParen(RParen) {} + + explicit ObjCAvailabilityCheckExpr(EmptyShell Shell) + : Expr(ObjCAvailabilityCheckExprClass, Shell) {} + + SourceLocation getLocStart() const { return AtLoc; } + SourceLocation getLocEnd() const { return RParen; } + SourceRange getSourceRange() const { return {AtLoc, RParen}; } + + /// \brief This may be '*', in which case this should fold to true. + bool hasVersion() const { return !VersionToCheck.empty(); } + VersionTuple getVersion() { return VersionToCheck; } + + child_range children() { + return child_range(child_iterator(), child_iterator()); + } + + static bool classof(const Stmt *T) { + return T->getStmtClass() == ObjCAvailabilityCheckExprClass; + } +}; + } // end namespace clang #endif diff --git a/include/clang/AST/ExprOpenMP.h b/include/clang/AST/ExprOpenMP.h index 2d71a3ad47c77..a4ef93ba8b14a 100644 --- a/include/clang/AST/ExprOpenMP.h +++ b/include/clang/AST/ExprOpenMP.h @@ -85,7 +85,7 @@ public: void setBase(Expr *E) { SubExprs[BASE] = E; } /// \brief Return original type of the base expression for array section. - static QualType getBaseOriginalType(Expr *Base); + static QualType getBaseOriginalType(const Expr *Base); /// \brief Get lower bound of array section. Expr *getLowerBound() { return cast_or_null<Expr>(SubExprs[LOWER_BOUND]); } diff --git a/include/clang/AST/GlobalDecl.h b/include/clang/AST/GlobalDecl.h index 54c9d88c9b2ee..adf63a3aea69c 100644 --- a/include/clang/AST/GlobalDecl.h +++ b/include/clang/AST/GlobalDecl.h @@ -17,6 +17,7 @@ #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclObjC.h" +#include "clang/AST/DeclOpenMP.h" #include "clang/Basic/ABI.h" namespace clang { @@ -43,6 +44,7 @@ public: GlobalDecl(const BlockDecl *D) { Init(D); } GlobalDecl(const CapturedDecl *D) { Init(D); } GlobalDecl(const ObjCMethodDecl *D) { Init(D); } + GlobalDecl(const OMPDeclareReductionDecl *D) { Init(D); } GlobalDecl(const CXXConstructorDecl *D, CXXCtorType Type) : Value(D, Type) {} diff --git a/include/clang/AST/LambdaCapture.h b/include/clang/AST/LambdaCapture.h index ddefa88a6b697..6517d656878ee 100644 --- a/include/clang/AST/LambdaCapture.h +++ b/include/clang/AST/LambdaCapture.h @@ -33,10 +33,22 @@ class LambdaCapture { /// given capture was by-copy. /// /// This includes the case of a non-reference init-capture. - Capture_ByCopy = 0x02 + Capture_ByCopy = 0x02, + + /// \brief Flag used by the Capture class to distinguish between a capture + /// of '*this' and a capture of a VLA type. + Capture_This = 0x04 }; - llvm::PointerIntPair<Decl *, 2> DeclAndBits; + // Decl could represent: + // - a VarDecl* that represents the variable that was captured or the + // init-capture. + // - or, is a nullptr and Capture_This is set in Bits if this represents a + // capture of '*this' by value or reference. + // - or, is a nullptr and Capture_This is not set in Bits if this represents + // a capture of a VLA type. + llvm::PointerIntPair<Decl*, 3> DeclAndBits; + SourceLocation Loc; SourceLocation EllipsisLoc; @@ -69,8 +81,8 @@ public: /// \brief Determine whether this capture handles the C++ \c this /// pointer. bool capturesThis() const { - return (DeclAndBits.getPointer() == nullptr) && - !(DeclAndBits.getInt() & Capture_ByCopy); + return DeclAndBits.getPointer() == nullptr && + (DeclAndBits.getInt() & Capture_This); } /// \brief Determine whether this capture handles a variable. @@ -81,8 +93,8 @@ public: /// \brief Determine whether this captures a variable length array bound /// expression. bool capturesVLAType() const { - return (DeclAndBits.getPointer() == nullptr) && - (DeclAndBits.getInt() & Capture_ByCopy); + return DeclAndBits.getPointer() == nullptr && + !(DeclAndBits.getInt() & Capture_This); } /// \brief Retrieve the declaration of the local variable being @@ -91,13 +103,15 @@ public: /// This operation is only valid if this capture is a variable capture /// (other than a capture of \c this). VarDecl *getCapturedVar() const { - assert(capturesVariable() && "No variable available for 'this' capture"); - return cast<VarDecl>(DeclAndBits.getPointer()); + assert(capturesVariable() && "No variable available for capture"); + return static_cast<VarDecl *>(DeclAndBits.getPointer()); } /// \brief Determine whether this was an implicit capture (not /// written between the square brackets introducing the lambda). - bool isImplicit() const { return DeclAndBits.getInt() & Capture_Implicit; } + bool isImplicit() const { + return DeclAndBits.getInt() & Capture_Implicit; + } /// \brief Determine whether this was an explicit capture (written /// between the square brackets introducing the lambda). diff --git a/include/clang/Sema/LocInfoType.h b/include/clang/AST/LocInfoType.h index 63dfa72b8f742..7e573bd7bac44 100644 --- a/include/clang/Sema/LocInfoType.h +++ b/include/clang/AST/LocInfoType.h @@ -36,11 +36,10 @@ class LocInfoType : public Type { TypeSourceInfo *DeclInfo; LocInfoType(QualType ty, TypeSourceInfo *TInfo) - : Type((TypeClass)LocInfo, ty, ty->isDependentType(), - ty->isInstantiationDependentType(), - ty->isVariablyModifiedType(), - ty->containsUnexpandedParameterPack()), - DeclInfo(TInfo) { + : Type((TypeClass)LocInfo, ty, ty->isDependentType(), + ty->isInstantiationDependentType(), ty->isVariablyModifiedType(), + ty->containsUnexpandedParameterPack()), + DeclInfo(TInfo) { assert(getTypeClass() == (TypeClass)LocInfo && "LocInfo didn't fit in TC?"); } friend class Sema; diff --git a/include/clang/AST/Makefile b/include/clang/AST/Makefile deleted file mode 100644 index 85e6449c509a2..0000000000000 --- a/include/clang/AST/Makefile +++ /dev/null @@ -1,79 +0,0 @@ -CLANG_LEVEL := ../../.. -TD_SRC_DIR = $(PROJ_SRC_DIR)/../Basic -BUILT_SOURCES = Attrs.inc AttrImpl.inc AttrDump.inc AttrVisitor.inc \ - StmtNodes.inc DeclNodes.inc \ - CommentNodes.inc CommentHTMLTags.inc \ - CommentHTMLTagsProperties.inc \ - CommentHTMLNamedCharacterReferences.inc \ - CommentCommandInfo.inc \ - CommentCommandList.inc - -TABLEGEN_INC_FILES_COMMON = 1 - -include $(CLANG_LEVEL)/Makefile - -$(ObjDir)/Attrs.inc.tmp : $(TD_SRC_DIR)/Attr.td $(CLANG_TBLGEN) \ - $(ObjDir)/.dir - $(Echo) "Building Clang attribute classes with tblgen" - $(Verb) $(ClangTableGen) -gen-clang-attr-classes -o $(call SYSPATH, $@) \ - -I $(PROJ_SRC_DIR)/../../ $< - -$(ObjDir)/AttrImpl.inc.tmp : $(TD_SRC_DIR)/Attr.td $(CLANG_TBLGEN) \ - $(ObjDir)/.dir - $(Echo) "Building Clang attribute implementations with tblgen" - $(Verb) $(ClangTableGen) -gen-clang-attr-impl -o $(call SYSPATH, $@) \ - -I $(PROJ_SRC_DIR)/../../ $< - -$(ObjDir)/AttrDump.inc.tmp : $(TD_SRC_DIR)/Attr.td $(CLANG_TBLGEN) \ - $(ObjDir)/.dir - $(Echo) "Building Clang attribute dumper with tblgen" - $(Verb) $(ClangTableGen) -gen-clang-attr-dump -o $(call SYSPATH, $@) \ - -I $(PROJ_SRC_DIR)/../../ $< - -$(ObjDir)/AttrVisitor.inc.tmp : $(TD_SRC_DIR)/Attr.td $(CLANG_TBLGEN) \ - $(ObjDir)/.dir - $(Echo) "Building Clang attribute AST visitor with tblgen" - $(Verb) $(ClangTableGen) -gen-clang-attr-ast-visitor -o $(call SYSPATH, $@) \ - -I $(PROJ_SRC_DIR)/../../ $< - -$(ObjDir)/StmtNodes.inc.tmp : $(TD_SRC_DIR)/StmtNodes.td $(CLANG_TBLGEN) \ - $(ObjDir)/.dir - $(Echo) "Building Clang statement node tables with tblgen" - $(Verb) $(ClangTableGen) -gen-clang-stmt-nodes -o $(call SYSPATH, $@) $< - -$(ObjDir)/DeclNodes.inc.tmp : $(TD_SRC_DIR)/DeclNodes.td $(CLANG_TBLGEN) \ - $(ObjDir)/.dir - $(Echo) "Building Clang declaration node tables with tblgen" - $(Verb) $(ClangTableGen) -gen-clang-decl-nodes -o $(call SYSPATH, $@) $< - -$(ObjDir)/CommentNodes.inc.tmp : $(TD_SRC_DIR)/CommentNodes.td $(CLANG_TBLGEN) \ - $(ObjDir)/.dir - $(Echo) "Building Clang comment node tables with tblgen" - $(Verb) $(ClangTableGen) -gen-clang-comment-nodes -o $(call SYSPATH, $@) $< - -$(ObjDir)/CommentHTMLTags.inc.tmp : $(PROJ_SRC_DIR)/CommentHTMLTags.td $(CLANG_TBLGEN) \ - $(ObjDir)/.dir - $(Echo) "Building Clang comment HTML tag matchers with tblgen" - $(Verb) $(ClangTableGen) -gen-clang-comment-html-tags -o $(call SYSPATH, $@) $< - -$(ObjDir)/CommentHTMLTagsProperties.inc.tmp : $(PROJ_SRC_DIR)/CommentHTMLTags.td \ - $(CLANG_TBLGEN) $(ObjDir)/.dir - $(Echo) "Building Clang comment HTML tag properties with tblgen" - $(Verb) $(ClangTableGen) -gen-clang-comment-html-tags-properties -o $(call SYSPATH, $@) $< - -$(ObjDir)/CommentHTMLNamedCharacterReferences.inc.tmp : \ - $(PROJ_SRC_DIR)/CommentHTMLNamedCharacterReferences.td \ - $(CLANG_TBLGEN) $(ObjDir)/.dir - $(Echo) "Building Clang named character reference translation function with tblgen" - $(Verb) $(ClangTableGen) -gen-clang-comment-html-named-character-references -o $(call SYSPATH, $@) $< - -$(ObjDir)/CommentCommandInfo.inc.tmp : $(PROJ_SRC_DIR)/CommentCommands.td \ - $(CLANG_TBLGEN) $(ObjDir)/.dir - $(Echo) "Building Clang comment command info with tblgen" - $(Verb) $(ClangTableGen) -gen-clang-comment-command-info -o $(call SYSPATH, $@) $< - -$(ObjDir)/CommentCommandList.inc.tmp : $(PROJ_SRC_DIR)/CommentCommands.td \ - $(CLANG_TBLGEN) $(ObjDir)/.dir - $(Echo) "Building Clang list of comment commands with tblgen" - $(Verb) $(ClangTableGen) -gen-clang-comment-command-list -o $(call SYSPATH, $@) $< - diff --git a/include/clang/AST/Mangle.h b/include/clang/AST/Mangle.h index 4872738e7a1ea..6e3ef9da0c3d4 100644 --- a/include/clang/AST/Mangle.h +++ b/include/clang/AST/Mangle.h @@ -14,6 +14,7 @@ #ifndef LLVM_CLANG_AST_MANGLE_H #define LLVM_CLANG_AST_MANGLE_H +#include "clang/AST/Decl.h" #include "clang/AST/Type.h" #include "clang/Basic/ABI.h" #include "llvm/ADT/DenseMap.h" @@ -123,6 +124,7 @@ public: void mangleBlock(const DeclContext *DC, const BlockDecl *BD, raw_ostream &Out); + void mangleObjCMethodNameWithoutSize(const ObjCMethodDecl *MD, raw_ostream &); void mangleObjCMethodName(const ObjCMethodDecl *MD, raw_ostream &); virtual void mangleStaticGuardVariable(const VarDecl *D, raw_ostream &) = 0; @@ -206,7 +208,8 @@ public: raw_ostream &Out) = 0; virtual void mangleCXXThrowInfo(QualType T, bool IsConst, bool IsVolatile, - uint32_t NumEntries, raw_ostream &Out) = 0; + bool IsUnaligned, uint32_t NumEntries, + raw_ostream &Out) = 0; virtual void mangleCXXCatchableTypeArray(QualType T, uint32_t NumEntries, raw_ostream &Out) = 0; diff --git a/include/clang/AST/OpenMPClause.h b/include/clang/AST/OpenMPClause.h index 7632a4b3560a8..43988cd864bb0 100644 --- a/include/clang/AST/OpenMPClause.h +++ b/include/clang/AST/OpenMPClause.h @@ -70,6 +70,51 @@ public: static bool classof(const OMPClause *) { return true; } }; +/// Class that handles pre-initialization statement for some clauses, like +/// 'shedule', 'firstprivate' etc. +class OMPClauseWithPreInit { + friend class OMPClauseReader; + /// Pre-initialization statement for the clause. + Stmt *PreInit; +protected: + /// Set pre-initialization statement for the clause. + void setPreInitStmt(Stmt *S) { PreInit = S; } + OMPClauseWithPreInit(const OMPClause *This) : PreInit(nullptr) { + assert(get(This) && "get is not tuned for pre-init."); + } + +public: + /// Get pre-initialization statement for the clause. + const Stmt *getPreInitStmt() const { return PreInit; } + /// Get pre-initialization statement for the clause. + Stmt *getPreInitStmt() { return PreInit; } + static OMPClauseWithPreInit *get(OMPClause *C); + static const OMPClauseWithPreInit *get(const OMPClause *C); +}; + +/// Class that handles post-update expression for some clauses, like +/// 'lastprivate', 'reduction' etc. +class OMPClauseWithPostUpdate : public OMPClauseWithPreInit { + friend class OMPClauseReader; + /// Post-update expression for the clause. + Expr *PostUpdate; +protected: + /// Set pre-initialization statement for the clause. + void setPostUpdateExpr(Expr *S) { PostUpdate = S; } + OMPClauseWithPostUpdate(const OMPClause *This) + : OMPClauseWithPreInit(This), PostUpdate(nullptr) { + assert(get(This) && "get is not tuned for post-update."); + } + +public: + /// Get post-update expression for the clause. + const Expr *getPostUpdateExpr() const { return PostUpdate; } + /// Get post-update expression for the clause. + Expr *getPostUpdateExpr() { return PostUpdate; } + static OMPClauseWithPostUpdate *get(OMPClause *C); + static const OMPClauseWithPostUpdate *get(const OMPClause *C); +}; + /// \brief This represents clauses with the list of variables like 'private', /// 'firstprivate', 'copyin', 'shared', or 'reduction' clauses in the /// '#pragma omp ...' directives. @@ -650,7 +695,7 @@ public: /// In this example directive '#pragma omp for' has 'schedule' clause with /// arguments 'static' and '3'. /// -class OMPScheduleClause : public OMPClause { +class OMPScheduleClause : public OMPClause, public OMPClauseWithPreInit { friend class OMPClauseReader; /// \brief Location of '('. SourceLocation LParenLoc; @@ -665,10 +710,8 @@ class OMPScheduleClause : public OMPClause { SourceLocation KindLoc; /// \brief Location of ',' (if any). SourceLocation CommaLoc; - /// \brief Chunk size and a reference to pseudo variable for combined - /// directives. - enum { CHUNK_SIZE, HELPER_CHUNK_SIZE, NUM_EXPRS }; - Stmt *ChunkSizes[NUM_EXPRS]; + /// \brief Chunk size. + Expr *ChunkSize; /// \brief Set schedule kind. /// @@ -730,12 +773,7 @@ class OMPScheduleClause : public OMPClause { /// /// \param E Chunk size. /// - void setChunkSize(Expr *E) { ChunkSizes[CHUNK_SIZE] = E; } - /// \brief Set helper chunk size. - /// - /// \param E Helper chunk size. - /// - void setHelperChunkSize(Expr *E) { ChunkSizes[HELPER_CHUNK_SIZE] = E; } + void setChunkSize(Expr *E) { ChunkSize = E; } public: /// \brief Build 'schedule' clause with schedule kind \a Kind and chunk size @@ -757,13 +795,13 @@ public: OMPScheduleClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation KLoc, SourceLocation CommaLoc, SourceLocation EndLoc, OpenMPScheduleClauseKind Kind, - Expr *ChunkSize, Expr *HelperChunkSize, + Expr *ChunkSize, Stmt *HelperChunkSize, OpenMPScheduleClauseModifier M1, SourceLocation M1Loc, OpenMPScheduleClauseModifier M2, SourceLocation M2Loc) - : OMPClause(OMPC_schedule, StartLoc, EndLoc), LParenLoc(LParenLoc), - Kind(Kind), KindLoc(KLoc), CommaLoc(CommaLoc) { - ChunkSizes[CHUNK_SIZE] = ChunkSize; - ChunkSizes[HELPER_CHUNK_SIZE] = HelperChunkSize; + : OMPClause(OMPC_schedule, StartLoc, EndLoc), OMPClauseWithPreInit(this), + LParenLoc(LParenLoc), Kind(Kind), KindLoc(KLoc), CommaLoc(CommaLoc), + ChunkSize(ChunkSize) { + setPreInitStmt(HelperChunkSize); Modifiers[FIRST] = M1; Modifiers[SECOND] = M2; ModifiersLoc[FIRST] = M1Loc; @@ -774,9 +812,8 @@ public: /// explicit OMPScheduleClause() : OMPClause(OMPC_schedule, SourceLocation(), SourceLocation()), - Kind(OMPC_SCHEDULE_unknown) { - ChunkSizes[CHUNK_SIZE] = nullptr; - ChunkSizes[HELPER_CHUNK_SIZE] = nullptr; + OMPClauseWithPreInit(this), Kind(OMPC_SCHEDULE_unknown), + ChunkSize(nullptr) { Modifiers[FIRST] = OMPC_SCHEDULE_MODIFIER_unknown; Modifiers[SECOND] = OMPC_SCHEDULE_MODIFIER_unknown; } @@ -815,29 +852,18 @@ public: SourceLocation getCommaLoc() { return CommaLoc; } /// \brief Get chunk size. /// - Expr *getChunkSize() { return dyn_cast_or_null<Expr>(ChunkSizes[CHUNK_SIZE]); } + Expr *getChunkSize() { return ChunkSize; } /// \brief Get chunk size. /// - Expr *getChunkSize() const { - return dyn_cast_or_null<Expr>(ChunkSizes[CHUNK_SIZE]); - } - /// \brief Get helper chunk size. - /// - Expr *getHelperChunkSize() { - return dyn_cast_or_null<Expr>(ChunkSizes[HELPER_CHUNK_SIZE]); - } - /// \brief Get helper chunk size. - /// - Expr *getHelperChunkSize() const { - return dyn_cast_or_null<Expr>(ChunkSizes[HELPER_CHUNK_SIZE]); - } + const Expr *getChunkSize() const { return ChunkSize; } static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_schedule; } child_range children() { - return child_range(&ChunkSizes[CHUNK_SIZE], &ChunkSizes[CHUNK_SIZE] + 1); + return child_range(reinterpret_cast<Stmt **>(&ChunkSize), + reinterpret_cast<Stmt **>(&ChunkSize) + 1); } }; @@ -1250,6 +1276,7 @@ public: /// class OMPFirstprivateClause final : public OMPVarListClause<OMPFirstprivateClause>, + public OMPClauseWithPreInit, private llvm::TrailingObjects<OMPFirstprivateClause, Expr *> { friend TrailingObjects; friend OMPVarListClause; @@ -1265,7 +1292,8 @@ class OMPFirstprivateClause final OMPFirstprivateClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, unsigned N) : OMPVarListClause<OMPFirstprivateClause>(OMPC_firstprivate, StartLoc, - LParenLoc, EndLoc, N) {} + LParenLoc, EndLoc, N), + OMPClauseWithPreInit(this) {} /// \brief Build an empty clause. /// @@ -1274,7 +1302,8 @@ class OMPFirstprivateClause final explicit OMPFirstprivateClause(unsigned N) : OMPVarListClause<OMPFirstprivateClause>( OMPC_firstprivate, SourceLocation(), SourceLocation(), - SourceLocation(), N) {} + SourceLocation(), N), + OMPClauseWithPreInit(this) {} /// \brief Sets the list of references to private copies with initializers for /// new private variables. /// \param VL List of references. @@ -1315,11 +1344,13 @@ public: /// \param InitVL List of references to auto generated variables used for /// initialization of a single array element. Used if firstprivate variable is /// of array type. + /// \param PreInit Statement that must be executed before entering the OpenMP + /// region with this clause. /// static OMPFirstprivateClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef<Expr *> VL, ArrayRef<Expr *> PrivateVL, - ArrayRef<Expr *> InitVL); + ArrayRef<Expr *> InitVL, Stmt *PreInit); /// \brief Creates an empty clause with the place for \a N variables. /// /// \param C AST context. @@ -1374,6 +1405,7 @@ public: /// with the variables 'a' and 'b'. class OMPLastprivateClause final : public OMPVarListClause<OMPLastprivateClause>, + public OMPClauseWithPostUpdate, private llvm::TrailingObjects<OMPLastprivateClause, Expr *> { // There are 4 additional tail-allocated arrays at the end of the class: // 1. Contains list of pseudo variables with the default initialization for @@ -1406,7 +1438,8 @@ class OMPLastprivateClause final OMPLastprivateClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, unsigned N) : OMPVarListClause<OMPLastprivateClause>(OMPC_lastprivate, StartLoc, - LParenLoc, EndLoc, N) {} + LParenLoc, EndLoc, N), + OMPClauseWithPostUpdate(this) {} /// \brief Build an empty clause. /// @@ -1415,7 +1448,8 @@ class OMPLastprivateClause final explicit OMPLastprivateClause(unsigned N) : OMPVarListClause<OMPLastprivateClause>( OMPC_lastprivate, SourceLocation(), SourceLocation(), - SourceLocation(), N) {} + SourceLocation(), N), + OMPClauseWithPostUpdate(this) {} /// \brief Get the list of helper expressions for initialization of private /// copies for lastprivate variables. @@ -1488,12 +1522,16 @@ public: /// \endcode /// Required for proper codegen of final assignment performed by the /// lastprivate clause. - /// + /// \param PreInit Statement that must be executed before entering the OpenMP + /// region with this clause. + /// \param PostUpdate Expression that must be executed after exit from the + /// OpenMP region with this clause. /// static OMPLastprivateClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef<Expr *> VL, ArrayRef<Expr *> SrcExprs, - ArrayRef<Expr *> DstExprs, ArrayRef<Expr *> AssignmentOps); + ArrayRef<Expr *> DstExprs, ArrayRef<Expr *> AssignmentOps, + Stmt *PreInit, Expr *PostUpdate); /// \brief Creates an empty clause with the place for \a N variables. /// /// \param C AST context. @@ -1627,6 +1665,7 @@ public: /// class OMPReductionClause final : public OMPVarListClause<OMPReductionClause>, + public OMPClauseWithPostUpdate, private llvm::TrailingObjects<OMPReductionClause, Expr *> { friend TrailingObjects; friend OMPVarListClause; @@ -1654,7 +1693,8 @@ class OMPReductionClause final const DeclarationNameInfo &NameInfo) : OMPVarListClause<OMPReductionClause>(OMPC_reduction, StartLoc, LParenLoc, EndLoc, N), - ColonLoc(ColonLoc), QualifierLoc(QualifierLoc), NameInfo(NameInfo) {} + OMPClauseWithPostUpdate(this), ColonLoc(ColonLoc), + QualifierLoc(QualifierLoc), NameInfo(NameInfo) {} /// \brief Build an empty clause. /// @@ -1664,7 +1704,7 @@ class OMPReductionClause final : OMPVarListClause<OMPReductionClause>(OMPC_reduction, SourceLocation(), SourceLocation(), SourceLocation(), N), - ColonLoc(), QualifierLoc(), NameInfo() {} + OMPClauseWithPostUpdate(this), ColonLoc(), QualifierLoc(), NameInfo() {} /// \brief Sets location of ':' symbol in clause. void setColonLoc(SourceLocation CL) { ColonLoc = CL; } @@ -1757,6 +1797,10 @@ public: /// \endcode /// Required for proper codegen of final reduction operation performed by the /// reduction clause. + /// \param PreInit Statement that must be executed before entering the OpenMP + /// region with this clause. + /// \param PostUpdate Expression that must be executed after exit from the + /// OpenMP region with this clause. /// static OMPReductionClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, @@ -1764,7 +1808,7 @@ public: NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, ArrayRef<Expr *> Privates, ArrayRef<Expr *> LHSExprs, ArrayRef<Expr *> RHSExprs, - ArrayRef<Expr *> ReductionOps); + ArrayRef<Expr *> ReductionOps, Stmt *PreInit, Expr *PostUpdate); /// \brief Creates an empty clause with the place for \a N variables. /// /// \param C AST context. @@ -1833,6 +1877,7 @@ public: /// class OMPLinearClause final : public OMPVarListClause<OMPLinearClause>, + public OMPClauseWithPostUpdate, private llvm::TrailingObjects<OMPLinearClause, Expr *> { friend TrailingObjects; friend OMPVarListClause; @@ -1864,7 +1909,8 @@ class OMPLinearClause final unsigned NumVars) : OMPVarListClause<OMPLinearClause>(OMPC_linear, StartLoc, LParenLoc, EndLoc, NumVars), - Modifier(Modifier), ModifierLoc(ModifierLoc), ColonLoc(ColonLoc) {} + OMPClauseWithPostUpdate(this), Modifier(Modifier), + ModifierLoc(ModifierLoc), ColonLoc(ColonLoc) {} /// \brief Build an empty clause. /// @@ -1874,7 +1920,8 @@ class OMPLinearClause final : OMPVarListClause<OMPLinearClause>(OMPC_linear, SourceLocation(), SourceLocation(), SourceLocation(), NumVars), - Modifier(OMPC_LINEAR_val), ModifierLoc(), ColonLoc() {} + OMPClauseWithPostUpdate(this), Modifier(OMPC_LINEAR_val), ModifierLoc(), + ColonLoc() {} /// \brief Gets the list of initial values for linear variables. /// @@ -1943,11 +1990,16 @@ public: /// \param IL List of initial values for the variables. /// \param Step Linear step. /// \param CalcStep Calculation of the linear step. + /// \param PreInit Statement that must be executed before entering the OpenMP + /// region with this clause. + /// \param PostUpdate Expression that must be executed after exit from the + /// OpenMP region with this clause. static OMPLinearClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, OpenMPLinearClauseKind Modifier, SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef<Expr *> VL, - ArrayRef<Expr *> PL, ArrayRef<Expr *> IL, Expr *Step, Expr *CalcStep); + ArrayRef<Expr *> PL, ArrayRef<Expr *> IL, Expr *Step, Expr *CalcStep, + Stmt *PreInit, Expr *PostUpdate); /// \brief Creates an empty clause with the place for \a NumVars variables. /// @@ -2577,7 +2629,6 @@ public: /// \param DepLoc Location of the dependency type. /// \param ColonLoc Colon location. /// \param VL List of references to the variables. - /// static OMPDependClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, OpenMPDependClauseKind DepKind, @@ -2596,6 +2647,14 @@ public: /// \brief Get colon location. SourceLocation getColonLoc() const { return ColonLoc; } + /// Set the loop counter value for the depend clauses with 'sink|source' kind + /// of dependency. Required for codegen. + void setCounterValue(Expr *V); + /// Get the loop counter value. + Expr *getCounterValue(); + /// Get the loop counter value. + const Expr *getCounterValue() const; + child_range children() { return child_range(reinterpret_cast<Stmt **>(varlist_begin()), reinterpret_cast<Stmt **>(varlist_end())); @@ -2722,6 +2781,495 @@ public: } }; +/// \brief Struct that defines common infrastructure to handle mappable +/// expressions used in OpenMP clauses. +class OMPClauseMappableExprCommon { +public: + // \brief Class that represents a component of a mappable expression. E.g. + // for an expression S.a, the first component is a declaration reference + // expression associated with 'S' and the second is a member expression + // associated with the field declaration 'a'. If the expression is an array + // subscript it may not have any associated declaration. In that case the + // associated declaration is set to nullptr. + class MappableComponent { + // \brief Expression associated with the component. + Expr *AssociatedExpression = nullptr; + // \brief Declaration associated with the declaration. If the component does + // not have a declaration (e.g. array subscripts or section), this is set to + // nullptr. + ValueDecl *AssociatedDeclaration = nullptr; + + public: + explicit MappableComponent() {} + explicit MappableComponent(Expr *AssociatedExpression, + ValueDecl *AssociatedDeclaration) + : AssociatedExpression(AssociatedExpression), + AssociatedDeclaration( + AssociatedDeclaration + ? cast<ValueDecl>(AssociatedDeclaration->getCanonicalDecl()) + : nullptr) {} + + Expr *getAssociatedExpression() const { return AssociatedExpression; } + ValueDecl *getAssociatedDeclaration() const { + return AssociatedDeclaration; + } + }; + + // \brief List of components of an expression. This first one is the whole + // expression and the last one is the base expression. + typedef SmallVector<MappableComponent, 8> MappableExprComponentList; + typedef ArrayRef<MappableComponent> MappableExprComponentListRef; + + // \brief List of all component lists associated to the same base declaration. + // E.g. if both 'S.a' and 'S.b' are a mappable expressions, each will have + // their component list but the same base declaration 'S'. + typedef SmallVector<MappableExprComponentList, 8> MappableExprComponentLists; + typedef ArrayRef<MappableExprComponentList> MappableExprComponentListsRef; + +protected: + // \brief Return the total number of elements in a list of component lists. + static unsigned + getComponentsTotalNumber(MappableExprComponentListsRef ComponentLists); + + // \brief Return the total number of elements in a list of declarations. All + // declarations are expected to be canonical. + static unsigned + getUniqueDeclarationsTotalNumber(ArrayRef<ValueDecl *> Declarations); +}; + +/// \brief This represents clauses with a list of expressions that are mappable. +/// Examples of these clauses are 'map' in +/// '#pragma omp target [enter|exit] [data]...' directives, and 'to' and 'from +/// in '#pragma omp target update...' directives. +template <class T> +class OMPMappableExprListClause : public OMPVarListClause<T>, + public OMPClauseMappableExprCommon { + friend class OMPClauseReader; + + /// \brief Number of unique declarations in this clause. + unsigned NumUniqueDeclarations; + + /// \brief Number of component lists in this clause. + unsigned NumComponentLists; + + /// \brief Total number of components in this clause. + unsigned NumComponents; + +protected: + /// \brief Get the unique declarations that are in the trailing objects of the + /// class. + MutableArrayRef<ValueDecl *> getUniqueDeclsRef() { + return MutableArrayRef<ValueDecl *>( + static_cast<T *>(this)->template getTrailingObjects<ValueDecl *>(), + NumUniqueDeclarations); + } + + /// \brief Get the unique declarations that are in the trailing objects of the + /// class. + ArrayRef<ValueDecl *> getUniqueDeclsRef() const { + return ArrayRef<ValueDecl *>( + static_cast<const T *>(this) + ->template getTrailingObjects<ValueDecl *>(), + NumUniqueDeclarations); + } + + /// \brief Set the unique declarations that are in the trailing objects of the + /// class. + void setUniqueDecls(ArrayRef<ValueDecl *> UDs) { + assert(UDs.size() == NumUniqueDeclarations && + "Unexpected amount of unique declarations."); + std::copy(UDs.begin(), UDs.end(), getUniqueDeclsRef().begin()); + } + + /// \brief Get the number of lists per declaration that are in the trailing + /// objects of the class. + MutableArrayRef<unsigned> getDeclNumListsRef() { + return MutableArrayRef<unsigned>( + static_cast<T *>(this)->template getTrailingObjects<unsigned>(), + NumUniqueDeclarations); + } + + /// \brief Get the number of lists per declaration that are in the trailing + /// objects of the class. + ArrayRef<unsigned> getDeclNumListsRef() const { + return ArrayRef<unsigned>( + static_cast<const T *>(this)->template getTrailingObjects<unsigned>(), + NumUniqueDeclarations); + } + + /// \brief Set the number of lists per declaration that are in the trailing + /// objects of the class. + void setDeclNumLists(ArrayRef<unsigned> DNLs) { + assert(DNLs.size() == NumUniqueDeclarations && + "Unexpected amount of list numbers."); + std::copy(DNLs.begin(), DNLs.end(), getDeclNumListsRef().begin()); + } + + /// \brief Get the cumulative component lists sizes that are in the trailing + /// objects of the class. They are appended after the number of lists. + MutableArrayRef<unsigned> getComponentListSizesRef() { + return MutableArrayRef<unsigned>( + static_cast<T *>(this)->template getTrailingObjects<unsigned>() + + NumUniqueDeclarations, + NumComponentLists); + } + + /// \brief Get the cumulative component lists sizes that are in the trailing + /// objects of the class. They are appended after the number of lists. + ArrayRef<unsigned> getComponentListSizesRef() const { + return ArrayRef<unsigned>( + static_cast<const T *>(this)->template getTrailingObjects<unsigned>() + + NumUniqueDeclarations, + NumComponentLists); + } + + /// \brief Set the cumulative component lists sizes that are in the trailing + /// objects of the class. + void setComponentListSizes(ArrayRef<unsigned> CLSs) { + assert(CLSs.size() == NumComponentLists && + "Unexpected amount of component lists."); + std::copy(CLSs.begin(), CLSs.end(), getComponentListSizesRef().begin()); + } + + /// \brief Get the components that are in the trailing objects of the class. + MutableArrayRef<MappableComponent> getComponentsRef() { + return MutableArrayRef<MappableComponent>( + static_cast<T *>(this) + ->template getTrailingObjects<MappableComponent>(), + NumComponents); + } + + /// \brief Get the components that are in the trailing objects of the class. + ArrayRef<MappableComponent> getComponentsRef() const { + return ArrayRef<MappableComponent>( + static_cast<const T *>(this) + ->template getTrailingObjects<MappableComponent>(), + NumComponents); + } + + /// \brief Set the components that are in the trailing objects of the class. + /// This requires the list sizes so that it can also fill the original + /// expressions, which are the first component of each list. + void setComponents(ArrayRef<MappableComponent> Components, + ArrayRef<unsigned> CLSs) { + assert(Components.size() == NumComponents && + "Unexpected amount of component lists."); + assert(CLSs.size() == NumComponentLists && + "Unexpected amount of list sizes."); + std::copy(Components.begin(), Components.end(), getComponentsRef().begin()); + } + + /// \brief Fill the clause information from the list of declarations and + /// associated component lists. + void setClauseInfo(ArrayRef<ValueDecl *> Declarations, + MappableExprComponentListsRef ComponentLists) { + // Perform some checks to make sure the data sizes are consistent with the + // information available when the clause was created. + assert(getUniqueDeclarationsTotalNumber(Declarations) == + NumUniqueDeclarations && + "Unexpected number of mappable expression info entries!"); + assert(getComponentsTotalNumber(ComponentLists) == NumComponents && + "Unexpected total number of components!"); + assert(Declarations.size() == ComponentLists.size() && + "Declaration and component lists size is not consistent!"); + assert(Declarations.size() == NumComponentLists && + "Unexpected declaration and component lists size!"); + + // Organize the components by declaration and retrieve the original + // expression. Original expressions are always the first component of the + // mappable component list. + llvm::DenseMap<ValueDecl *, SmallVector<MappableExprComponentListRef, 8>> + ComponentListMap; + { + auto CI = ComponentLists.begin(); + for (auto DI = Declarations.begin(), DE = Declarations.end(); DI != DE; + ++DI, ++CI) { + assert(!CI->empty() && "Invalid component list!"); + ComponentListMap[*DI].push_back(*CI); + } + } + + // Iterators of the target storage. + auto UniqueDeclarations = getUniqueDeclsRef(); + auto UDI = UniqueDeclarations.begin(); + + auto DeclNumLists = getDeclNumListsRef(); + auto DNLI = DeclNumLists.begin(); + + auto ComponentListSizes = getComponentListSizesRef(); + auto CLSI = ComponentListSizes.begin(); + + auto Components = getComponentsRef(); + auto CI = Components.begin(); + + // Variable to compute the accumulation of the number of components. + unsigned PrevSize = 0u; + + // Scan all the declarations and associated component lists. + for (auto &M : ComponentListMap) { + // The declaration. + auto *D = M.first; + // The component lists. + auto CL = M.second; + + // Initialize the entry. + *UDI = D; + ++UDI; + + *DNLI = CL.size(); + ++DNLI; + + // Obtain the cumulative sizes and concatenate all the components in the + // reserved storage. + for (auto C : CL) { + // Accumulate with the previous size. + PrevSize += C.size(); + + // Save the size. + *CLSI = PrevSize; + ++CLSI; + + // Append components after the current components iterator. + CI = std::copy(C.begin(), C.end(), CI); + } + } + } + + /// \brief Build a clause for \a NumUniqueDeclarations declarations, \a + /// NumComponentLists total component lists, and \a NumComponents total + /// components. + /// + /// \param K Kind of the clause. + /// \param StartLoc Starting location of the clause (the clause keyword). + /// \param LParenLoc Location of '('. + /// \param EndLoc Ending location of the clause. + /// \param NumVars Number of expressions listed in the clause. + /// \param NumUniqueDeclarations Number of unique base declarations in this + /// clause. + /// \param NumComponentLists Number of component lists in this clause - one + /// list for each expression in the clause. + /// \param NumComponents Total number of expression components in the clause. + /// + OMPMappableExprListClause(OpenMPClauseKind K, SourceLocation StartLoc, + SourceLocation LParenLoc, SourceLocation EndLoc, + unsigned NumVars, unsigned NumUniqueDeclarations, + unsigned NumComponentLists, unsigned NumComponents) + : OMPVarListClause<T>(K, StartLoc, LParenLoc, EndLoc, NumVars), + NumUniqueDeclarations(NumUniqueDeclarations), + NumComponentLists(NumComponentLists), NumComponents(NumComponents) {} + +public: + /// \brief Return the number of unique base declarations in this clause. + unsigned getUniqueDeclarationsNum() const { return NumUniqueDeclarations; } + /// \brief Return the number of lists derived from the clause expressions. + unsigned getTotalComponentListNum() const { return NumComponentLists; } + /// \brief Return the total number of components in all lists derived from the + /// clause. + unsigned getTotalComponentsNum() const { return NumComponents; } + + /// \brief Iterator that browse the components by lists. It also allows + /// browsing components of a single declaration. + class const_component_lists_iterator + : public llvm::iterator_adaptor_base< + const_component_lists_iterator, + MappableExprComponentListRef::const_iterator, + std::forward_iterator_tag, MappableComponent, ptrdiff_t, + MappableComponent, MappableComponent> { + // The declaration the iterator currently refers to. + ArrayRef<ValueDecl *>::iterator DeclCur; + + // The list number associated with the current declaration. + ArrayRef<unsigned>::iterator NumListsCur; + + // Remaining lists for the current declaration. + unsigned RemainingLists; + + // The cumulative size of the previous list, or zero if there is no previous + // list. + unsigned PrevListSize; + + // The cumulative sizes of the current list - it will delimit the remaining + // range of interest. + ArrayRef<unsigned>::const_iterator ListSizeCur; + ArrayRef<unsigned>::const_iterator ListSizeEnd; + + // Iterator to the end of the components storage. + MappableExprComponentListRef::const_iterator End; + + public: + /// \brief Construct an iterator that scans all lists. + explicit const_component_lists_iterator( + ArrayRef<ValueDecl *> UniqueDecls, ArrayRef<unsigned> DeclsListNum, + ArrayRef<unsigned> CumulativeListSizes, + MappableExprComponentListRef Components) + : const_component_lists_iterator::iterator_adaptor_base( + Components.begin()), + DeclCur(UniqueDecls.begin()), NumListsCur(DeclsListNum.begin()), + RemainingLists(0u), PrevListSize(0u), + ListSizeCur(CumulativeListSizes.begin()), + ListSizeEnd(CumulativeListSizes.end()), End(Components.end()) { + assert(UniqueDecls.size() == DeclsListNum.size() && + "Inconsistent number of declarations and list sizes!"); + if (!DeclsListNum.empty()) + RemainingLists = *NumListsCur; + } + + /// \brief Construct an iterator that scan lists for a given declaration \a + /// Declaration. + explicit const_component_lists_iterator( + const ValueDecl *Declaration, ArrayRef<ValueDecl *> UniqueDecls, + ArrayRef<unsigned> DeclsListNum, ArrayRef<unsigned> CumulativeListSizes, + MappableExprComponentListRef Components) + : const_component_lists_iterator(UniqueDecls, DeclsListNum, + CumulativeListSizes, Components) { + + // Look for the desired declaration. While we are looking for it, we + // update the state so that we know the component where a given list + // starts. + for (; DeclCur != UniqueDecls.end(); ++DeclCur, ++NumListsCur) { + if (*DeclCur == Declaration) + break; + + assert(*NumListsCur > 0 && "No lists associated with declaration??"); + + // Skip the lists associated with the current declaration, but save the + // last list size that was skipped. + std::advance(ListSizeCur, *NumListsCur - 1); + PrevListSize = *ListSizeCur; + ++ListSizeCur; + } + + // If we didn't find any declaration, advance the iterator to after the + // last component and set remaining lists to zero. + if (ListSizeCur == CumulativeListSizes.end()) { + this->I = End; + RemainingLists = 0u; + return; + } + + // Set the remaining lists with the total number of lists of the current + // declaration. + RemainingLists = *NumListsCur; + + // Adjust the list size end iterator to the end of the relevant range. + ListSizeEnd = ListSizeCur; + std::advance(ListSizeEnd, RemainingLists); + + // Given that the list sizes are cumulative, the index of the component + // that start the list is the size of the previous list. + std::advance(this->I, PrevListSize); + } + + // Return the array with the current list. The sizes are cumulative, so the + // array size is the difference between the current size and previous one. + std::pair<const ValueDecl *, MappableExprComponentListRef> + operator*() const { + assert(ListSizeCur != ListSizeEnd && "Invalid iterator!"); + return std::make_pair( + *DeclCur, + MappableExprComponentListRef(&*this->I, *ListSizeCur - PrevListSize)); + } + std::pair<const ValueDecl *, MappableExprComponentListRef> + operator->() const { + return **this; + } + + // Skip the components of the current list. + const_component_lists_iterator &operator++() { + assert(ListSizeCur != ListSizeEnd && RemainingLists && + "Invalid iterator!"); + + // If we don't have more lists just skip all the components. Otherwise, + // advance the iterator by the number of components in the current list. + if (std::next(ListSizeCur) == ListSizeEnd) { + this->I = End; + RemainingLists = 0; + } else { + std::advance(this->I, *ListSizeCur - PrevListSize); + PrevListSize = *ListSizeCur; + + // We are done with a declaration, move to the next one. + if (!(--RemainingLists)) { + ++DeclCur; + ++NumListsCur; + RemainingLists = *NumListsCur; + assert(RemainingLists && "No lists in the following declaration??"); + } + } + + ++ListSizeCur; + return *this; + } + }; + + typedef llvm::iterator_range<const_component_lists_iterator> + const_component_lists_range; + + /// \brief Iterators for all component lists. + const_component_lists_iterator component_lists_begin() const { + return const_component_lists_iterator( + getUniqueDeclsRef(), getDeclNumListsRef(), getComponentListSizesRef(), + getComponentsRef()); + } + const_component_lists_iterator component_lists_end() const { + return const_component_lists_iterator( + ArrayRef<ValueDecl *>(), ArrayRef<unsigned>(), ArrayRef<unsigned>(), + MappableExprComponentListRef(getComponentsRef().end(), + getComponentsRef().end())); + } + const_component_lists_range component_lists() const { + return {component_lists_begin(), component_lists_end()}; + } + + /// \brief Iterators for component lists associated with the provided + /// declaration. + const_component_lists_iterator + decl_component_lists_begin(const ValueDecl *VD) const { + return const_component_lists_iterator( + VD, getUniqueDeclsRef(), getDeclNumListsRef(), + getComponentListSizesRef(), getComponentsRef()); + } + const_component_lists_iterator decl_component_lists_end() const { + return component_lists_end(); + } + const_component_lists_range decl_component_lists(const ValueDecl *VD) const { + return {decl_component_lists_begin(VD), decl_component_lists_end()}; + } + + /// Iterators to access all the declarations, number of lists, list sizes, and + /// components. + typedef ArrayRef<ValueDecl *>::iterator const_all_decls_iterator; + typedef llvm::iterator_range<const_all_decls_iterator> const_all_decls_range; + const_all_decls_range all_decls() const { + auto A = getUniqueDeclsRef(); + return const_all_decls_range(A.begin(), A.end()); + } + + typedef ArrayRef<unsigned>::iterator const_all_num_lists_iterator; + typedef llvm::iterator_range<const_all_num_lists_iterator> + const_all_num_lists_range; + const_all_num_lists_range all_num_lists() const { + auto A = getDeclNumListsRef(); + return const_all_num_lists_range(A.begin(), A.end()); + } + + typedef ArrayRef<unsigned>::iterator const_all_lists_sizes_iterator; + typedef llvm::iterator_range<const_all_lists_sizes_iterator> + const_all_lists_sizes_range; + const_all_lists_sizes_range all_lists_sizes() const { + auto A = getComponentListSizesRef(); + return const_all_lists_sizes_range(A.begin(), A.end()); + } + + typedef ArrayRef<MappableComponent>::iterator const_all_components_iterator; + typedef llvm::iterator_range<const_all_components_iterator> + const_all_components_range; + const_all_components_range all_components() const { + auto A = getComponentsRef(); + return const_all_components_range(A.begin(), A.end()); + } +}; + /// \brief This represents clause 'map' in the '#pragma omp ...' /// directives. /// @@ -2731,16 +3279,33 @@ public: /// In this example directive '#pragma omp target' has clause 'map' /// with the variables 'a' and 'b'. /// -class OMPMapClause final : public OMPVarListClause<OMPMapClause>, - private llvm::TrailingObjects<OMPMapClause, Expr *> { +class OMPMapClause final : public OMPMappableExprListClause<OMPMapClause>, + private llvm::TrailingObjects< + OMPMapClause, Expr *, ValueDecl *, unsigned, + OMPClauseMappableExprCommon::MappableComponent> { friend TrailingObjects; friend OMPVarListClause; + friend OMPMappableExprListClause; friend class OMPClauseReader; + /// Define the sizes of each trailing object array except the last one. This + /// is required for TrailingObjects to work properly. + size_t numTrailingObjects(OverloadToken<Expr *>) const { + return varlist_size(); + } + size_t numTrailingObjects(OverloadToken<ValueDecl *>) const { + return getUniqueDeclarationsNum(); + } + size_t numTrailingObjects(OverloadToken<unsigned>) const { + return getUniqueDeclarationsNum() + getTotalComponentListNum(); + } + /// \brief Map type modifier for the 'map' clause. OpenMPMapClauseKind MapTypeModifier; /// \brief Map type for the 'map' clause. OpenMPMapClauseKind MapType; + /// \brief Is this an implicit map type or not. + bool MapTypeIsImplicit; /// \brief Location of the map type. SourceLocation MapLoc; /// \brief Colon location. @@ -2767,30 +3332,49 @@ class OMPMapClause final : public OMPVarListClause<OMPMapClause>, /// \brief Set colon location. void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; } - /// \brief Build clause with number of variables \a N. + /// \brief Build a clause for \a NumVars listed expressions, \a + /// NumUniqueDeclarations declarations, \a NumComponentLists total component + /// lists, and \a NumComponents total expression components. /// /// \param MapTypeModifier Map type modifier. /// \param MapType Map type. + /// \param MapTypeIsImplicit Map type is inferred implicitly. /// \param MapLoc Location of the map type. /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. - /// \param N Number of the variables in the clause. + /// \param NumVars Number of expressions listed in this clause. + /// \param NumUniqueDeclarations Number of unique base declarations in this + /// clause. + /// \param NumComponentLists Number of component lists in this clause. + /// \param NumComponents Total number of expression components in the clause. /// explicit OMPMapClause(OpenMPMapClauseKind MapTypeModifier, - OpenMPMapClauseKind MapType, SourceLocation MapLoc, - SourceLocation StartLoc, SourceLocation LParenLoc, - SourceLocation EndLoc, unsigned N) - : OMPVarListClause<OMPMapClause>(OMPC_map, StartLoc, LParenLoc, EndLoc, N), - MapTypeModifier(MapTypeModifier), MapType(MapType), MapLoc(MapLoc) {} + OpenMPMapClauseKind MapType, bool MapTypeIsImplicit, + SourceLocation MapLoc, SourceLocation StartLoc, + SourceLocation LParenLoc, SourceLocation EndLoc, + unsigned NumVars, unsigned NumUniqueDeclarations, + unsigned NumComponentLists, unsigned NumComponents) + : OMPMappableExprListClause(OMPC_map, StartLoc, LParenLoc, EndLoc, + NumVars, NumUniqueDeclarations, + NumComponentLists, NumComponents), + MapTypeModifier(MapTypeModifier), MapType(MapType), + MapTypeIsImplicit(MapTypeIsImplicit), MapLoc(MapLoc) {} /// \brief Build an empty clause. /// - /// \param N Number of variables. + /// \param NumVars Number of expressions listed in this clause. + /// \param NumUniqueDeclarations Number of unique base declarations in this + /// clause. + /// \param NumComponentLists Number of component lists in this clause. + /// \param NumComponents Total number of expression components in the clause. /// - explicit OMPMapClause(unsigned N) - : OMPVarListClause<OMPMapClause>(OMPC_map, SourceLocation(), - SourceLocation(), SourceLocation(), N), - MapTypeModifier(OMPC_MAP_unknown), MapType(OMPC_MAP_unknown), MapLoc() {} + explicit OMPMapClause(unsigned NumVars, unsigned NumUniqueDeclarations, + unsigned NumComponentLists, unsigned NumComponents) + : OMPMappableExprListClause( + OMPC_map, SourceLocation(), SourceLocation(), SourceLocation(), + NumVars, NumUniqueDeclarations, NumComponentLists, NumComponents), + MapTypeModifier(OMPC_MAP_unknown), MapType(OMPC_MAP_unknown), + MapTypeIsImplicit(false), MapLoc() {} public: /// \brief Creates clause with a list of variables \a VL. @@ -2798,26 +3382,49 @@ public: /// \param C AST context. /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. - /// \param VL List of references to the variables. + /// \param Vars The original expression used in the clause. + /// \param Declarations Declarations used in the clause. + /// \param ComponentLists Component lists used in the clause. /// \param TypeModifier Map type modifier. /// \param Type Map type. + /// \param TypeIsImplicit Map type is inferred implicitly. /// \param TypeLoc Location of the map type. /// static OMPMapClause *Create(const ASTContext &C, SourceLocation StartLoc, - SourceLocation LParenLoc, - SourceLocation EndLoc, ArrayRef<Expr *> VL, + SourceLocation LParenLoc, SourceLocation EndLoc, + ArrayRef<Expr *> Vars, + ArrayRef<ValueDecl *> Declarations, + MappableExprComponentListsRef ComponentLists, OpenMPMapClauseKind TypeModifier, - OpenMPMapClauseKind Type, SourceLocation TypeLoc); - /// \brief Creates an empty clause with the place for \a N variables. + OpenMPMapClauseKind Type, bool TypeIsImplicit, + SourceLocation TypeLoc); + /// \brief Creates an empty clause with the place for for \a NumVars original + /// expressions, \a NumUniqueDeclarations declarations, \NumComponentLists + /// lists, and \a NumComponents expression components. /// /// \param C AST context. - /// \param N The number of variables. - /// - static OMPMapClause *CreateEmpty(const ASTContext &C, unsigned N); + /// \param NumVars Number of expressions listed in the clause. + /// \param NumUniqueDeclarations Number of unique base declarations in this + /// clause. + /// \param NumComponentLists Number of unique base declarations in this + /// clause. + /// \param NumComponents Total number of expression components in the clause. + /// + static OMPMapClause *CreateEmpty(const ASTContext &C, unsigned NumVars, + unsigned NumUniqueDeclarations, + unsigned NumComponentLists, + unsigned NumComponents); /// \brief Fetches mapping kind for the clause. OpenMPMapClauseKind getMapType() const LLVM_READONLY { return MapType; } + /// \brief Is this an implicit map type? + /// We have to capture 'IsMapTypeImplicit' from the parser for more + /// informative error messages. It helps distinguish map(r) from + /// map(tofrom: r), which is important to print more helpful error + /// messages for some target directives. + bool isImplicitMapType() const LLVM_READONLY { return MapTypeIsImplicit; } + /// \brief Fetches the map type modifier for the clause. OpenMPMapClauseKind getMapTypeModifier() const LLVM_READONLY { return MapTypeModifier; @@ -3193,6 +3800,553 @@ public: child_range children() { return child_range(&Hint, &Hint + 1); } }; +/// \brief This represents 'dist_schedule' clause in the '#pragma omp ...' +/// directive. +/// +/// \code +/// #pragma omp distribute dist_schedule(static, 3) +/// \endcode +/// In this example directive '#pragma omp distribute' has 'dist_schedule' +/// clause with arguments 'static' and '3'. +/// +class OMPDistScheduleClause : public OMPClause, public OMPClauseWithPreInit { + friend class OMPClauseReader; + /// \brief Location of '('. + SourceLocation LParenLoc; + /// \brief A kind of the 'schedule' clause. + OpenMPDistScheduleClauseKind Kind; + /// \brief Start location of the schedule kind in source code. + SourceLocation KindLoc; + /// \brief Location of ',' (if any). + SourceLocation CommaLoc; + /// \brief Chunk size. + Expr *ChunkSize; + + /// \brief Set schedule kind. + /// + /// \param K Schedule kind. + /// + void setDistScheduleKind(OpenMPDistScheduleClauseKind K) { Kind = K; } + /// \brief Sets the location of '('. + /// + /// \param Loc Location of '('. + /// + void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } + /// \brief Set schedule kind start location. + /// + /// \param KLoc Schedule kind location. + /// + void setDistScheduleKindLoc(SourceLocation KLoc) { KindLoc = KLoc; } + /// \brief Set location of ','. + /// + /// \param Loc Location of ','. + /// + void setCommaLoc(SourceLocation Loc) { CommaLoc = Loc; } + /// \brief Set chunk size. + /// + /// \param E Chunk size. + /// + void setChunkSize(Expr *E) { ChunkSize = E; } + +public: + /// \brief Build 'dist_schedule' clause with schedule kind \a Kind and chunk + /// size expression \a ChunkSize. + /// + /// \param StartLoc Starting location of the clause. + /// \param LParenLoc Location of '('. + /// \param KLoc Starting location of the argument. + /// \param CommaLoc Location of ','. + /// \param EndLoc Ending location of the clause. + /// \param Kind DistSchedule kind. + /// \param ChunkSize Chunk size. + /// \param HelperChunkSize Helper chunk size for combined directives. + /// + OMPDistScheduleClause(SourceLocation StartLoc, SourceLocation LParenLoc, + SourceLocation KLoc, SourceLocation CommaLoc, + SourceLocation EndLoc, + OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, + Stmt *HelperChunkSize) + : OMPClause(OMPC_dist_schedule, StartLoc, EndLoc), + OMPClauseWithPreInit(this), LParenLoc(LParenLoc), Kind(Kind), + KindLoc(KLoc), CommaLoc(CommaLoc), ChunkSize(ChunkSize) { + setPreInitStmt(HelperChunkSize); + } + + /// \brief Build an empty clause. + /// + explicit OMPDistScheduleClause() + : OMPClause(OMPC_dist_schedule, SourceLocation(), SourceLocation()), + OMPClauseWithPreInit(this), Kind(OMPC_DIST_SCHEDULE_unknown), + ChunkSize(nullptr) {} + + /// \brief Get kind of the clause. + /// + OpenMPDistScheduleClauseKind getDistScheduleKind() const { return Kind; } + /// \brief Get location of '('. + /// + SourceLocation getLParenLoc() { return LParenLoc; } + /// \brief Get kind location. + /// + SourceLocation getDistScheduleKindLoc() { return KindLoc; } + /// \brief Get location of ','. + /// + SourceLocation getCommaLoc() { return CommaLoc; } + /// \brief Get chunk size. + /// + Expr *getChunkSize() { return ChunkSize; } + /// \brief Get chunk size. + /// + const Expr *getChunkSize() const { return ChunkSize; } + + static bool classof(const OMPClause *T) { + return T->getClauseKind() == OMPC_dist_schedule; + } + + child_range children() { + return child_range(reinterpret_cast<Stmt **>(&ChunkSize), + reinterpret_cast<Stmt **>(&ChunkSize) + 1); + } +}; + +/// \brief This represents 'defaultmap' clause in the '#pragma omp ...' directive. +/// +/// \code +/// #pragma omp target defaultmap(tofrom: scalar) +/// \endcode +/// In this example directive '#pragma omp target' has 'defaultmap' clause of kind +/// 'scalar' with modifier 'tofrom'. +/// +class OMPDefaultmapClause : public OMPClause { + friend class OMPClauseReader; + /// \brief Location of '('. + SourceLocation LParenLoc; + /// \brief Modifiers for 'defaultmap' clause. + OpenMPDefaultmapClauseModifier Modifier; + /// \brief Locations of modifiers. + SourceLocation ModifierLoc; + /// \brief A kind of the 'defaultmap' clause. + OpenMPDefaultmapClauseKind Kind; + /// \brief Start location of the defaultmap kind in source code. + SourceLocation KindLoc; + + /// \brief Set defaultmap kind. + /// + /// \param K Defaultmap kind. + /// + void setDefaultmapKind(OpenMPDefaultmapClauseKind K) { Kind = K; } + /// \brief Set the defaultmap modifier. + /// + /// \param M Defaultmap modifier. + /// + void setDefaultmapModifier(OpenMPDefaultmapClauseModifier M) { + Modifier = M; + } + /// \brief Set location of the defaultmap modifier. + /// + void setDefaultmapModifierLoc(SourceLocation Loc) { + ModifierLoc = Loc; + } + /// \brief Sets the location of '('. + /// + /// \param Loc Location of '('. + /// + void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } + /// \brief Set defaultmap kind start location. + /// + /// \param KLoc Defaultmap kind location. + /// + void setDefaultmapKindLoc(SourceLocation KLoc) { KindLoc = KLoc; } + +public: + /// \brief Build 'defaultmap' clause with defaultmap kind \a Kind + /// + /// \param StartLoc Starting location of the clause. + /// \param LParenLoc Location of '('. + /// \param KLoc Starting location of the argument. + /// \param EndLoc Ending location of the clause. + /// \param Kind Defaultmap kind. + /// \param M The modifier applied to 'defaultmap' clause. + /// \param MLoc Location of the modifier + /// + OMPDefaultmapClause(SourceLocation StartLoc, SourceLocation LParenLoc, + SourceLocation MLoc, SourceLocation KLoc, + SourceLocation EndLoc, OpenMPDefaultmapClauseKind Kind, + OpenMPDefaultmapClauseModifier M) + : OMPClause(OMPC_defaultmap, StartLoc, EndLoc), LParenLoc(LParenLoc), + Modifier(M), ModifierLoc(MLoc), Kind(Kind), KindLoc(KLoc) {} + + /// \brief Build an empty clause. + /// + explicit OMPDefaultmapClause() + : OMPClause(OMPC_defaultmap, SourceLocation(), SourceLocation()), + Modifier(OMPC_DEFAULTMAP_MODIFIER_unknown), + Kind(OMPC_DEFAULTMAP_unknown) {} + + /// \brief Get kind of the clause. + /// + OpenMPDefaultmapClauseKind getDefaultmapKind() const { return Kind; } + /// \brief Get the modifier of the clause. + /// + OpenMPDefaultmapClauseModifier getDefaultmapModifier() const { + return Modifier; + } + /// \brief Get location of '('. + /// + SourceLocation getLParenLoc() { return LParenLoc; } + /// \brief Get kind location. + /// + SourceLocation getDefaultmapKindLoc() { return KindLoc; } + /// \brief Get the modifier location. + /// + SourceLocation getDefaultmapModifierLoc() const { + return ModifierLoc; + } + + static bool classof(const OMPClause *T) { + return T->getClauseKind() == OMPC_defaultmap; + } + + child_range children() { + return child_range(child_iterator(), child_iterator()); + } +}; + +/// \brief This represents clause 'to' in the '#pragma omp ...' +/// directives. +/// +/// \code +/// #pragma omp target update to(a,b) +/// \endcode +/// In this example directive '#pragma omp target update' has clause 'to' +/// with the variables 'a' and 'b'. +/// +class OMPToClause final : public OMPMappableExprListClause<OMPToClause>, + private llvm::TrailingObjects< + OMPToClause, Expr *, ValueDecl *, unsigned, + OMPClauseMappableExprCommon::MappableComponent> { + friend TrailingObjects; + friend OMPVarListClause; + friend OMPMappableExprListClause; + friend class OMPClauseReader; + + /// Define the sizes of each trailing object array except the last one. This + /// is required for TrailingObjects to work properly. + size_t numTrailingObjects(OverloadToken<Expr *>) const { + return varlist_size(); + } + size_t numTrailingObjects(OverloadToken<ValueDecl *>) const { + return getUniqueDeclarationsNum(); + } + size_t numTrailingObjects(OverloadToken<unsigned>) const { + return getUniqueDeclarationsNum() + getTotalComponentListNum(); + } + + /// \brief Build clause with number of variables \a NumVars. + /// + /// \param StartLoc Starting location of the clause. + /// \param EndLoc Ending location of the clause. + /// \param NumVars Number of expressions listed in this clause. + /// \param NumUniqueDeclarations Number of unique base declarations in this + /// clause. + /// \param NumComponentLists Number of component lists in this clause. + /// \param NumComponents Total number of expression components in the clause. + /// + explicit OMPToClause(SourceLocation StartLoc, SourceLocation LParenLoc, + SourceLocation EndLoc, unsigned NumVars, + unsigned NumUniqueDeclarations, + unsigned NumComponentLists, unsigned NumComponents) + : OMPMappableExprListClause(OMPC_to, StartLoc, LParenLoc, EndLoc, NumVars, + NumUniqueDeclarations, NumComponentLists, + NumComponents) {} + + /// \brief Build an empty clause. + /// + /// \param NumVars Number of expressions listed in this clause. + /// \param NumUniqueDeclarations Number of unique base declarations in this + /// clause. + /// \param NumComponentLists Number of component lists in this clause. + /// \param NumComponents Total number of expression components in the clause. + /// + explicit OMPToClause(unsigned NumVars, unsigned NumUniqueDeclarations, + unsigned NumComponentLists, unsigned NumComponents) + : OMPMappableExprListClause( + OMPC_to, SourceLocation(), SourceLocation(), SourceLocation(), + NumVars, NumUniqueDeclarations, NumComponentLists, NumComponents) {} + +public: + /// \brief Creates clause with a list of variables \a Vars. + /// + /// \param C AST context. + /// \param StartLoc Starting location of the clause. + /// \param EndLoc Ending location of the clause. + /// \param Vars The original expression used in the clause. + /// \param Declarations Declarations used in the clause. + /// \param ComponentLists Component lists used in the clause. + /// + static OMPToClause *Create(const ASTContext &C, SourceLocation StartLoc, + SourceLocation LParenLoc, SourceLocation EndLoc, + ArrayRef<Expr *> Vars, + ArrayRef<ValueDecl *> Declarations, + MappableExprComponentListsRef ComponentLists); + + /// \brief Creates an empty clause with the place for \a NumVars variables. + /// + /// \param C AST context. + /// \param NumVars Number of expressions listed in the clause. + /// \param NumUniqueDeclarations Number of unique base declarations in this + /// clause. + /// \param NumComponentLists Number of unique base declarations in this + /// clause. + /// \param NumComponents Total number of expression components in the clause. + /// + static OMPToClause *CreateEmpty(const ASTContext &C, unsigned NumVars, + unsigned NumUniqueDeclarations, + unsigned NumComponentLists, + unsigned NumComponents); + + static bool classof(const OMPClause *T) { + return T->getClauseKind() == OMPC_to; + } + + child_range children() { + return child_range(reinterpret_cast<Stmt **>(varlist_begin()), + reinterpret_cast<Stmt **>(varlist_end())); + } +}; + +/// \brief This represents clause 'from' in the '#pragma omp ...' +/// directives. +/// +/// \code +/// #pragma omp target update from(a,b) +/// \endcode +/// In this example directive '#pragma omp target update' has clause 'from' +/// with the variables 'a' and 'b'. +/// +class OMPFromClause final + : public OMPMappableExprListClause<OMPFromClause>, + private llvm::TrailingObjects< + OMPFromClause, Expr *, ValueDecl *, unsigned, + OMPClauseMappableExprCommon::MappableComponent> { + friend TrailingObjects; + friend OMPVarListClause; + friend OMPMappableExprListClause; + friend class OMPClauseReader; + + /// Define the sizes of each trailing object array except the last one. This + /// is required for TrailingObjects to work properly. + size_t numTrailingObjects(OverloadToken<Expr *>) const { + return varlist_size(); + } + size_t numTrailingObjects(OverloadToken<ValueDecl *>) const { + return getUniqueDeclarationsNum(); + } + size_t numTrailingObjects(OverloadToken<unsigned>) const { + return getUniqueDeclarationsNum() + getTotalComponentListNum(); + } + + /// \brief Build clause with number of variables \a NumVars. + /// + /// \param StartLoc Starting location of the clause. + /// \param EndLoc Ending location of the clause. + /// \param NumVars Number of expressions listed in this clause. + /// \param NumUniqueDeclarations Number of unique base declarations in this + /// clause. + /// \param NumComponentLists Number of component lists in this clause. + /// \param NumComponents Total number of expression components in the clause. + /// + explicit OMPFromClause(SourceLocation StartLoc, SourceLocation LParenLoc, + SourceLocation EndLoc, unsigned NumVars, + unsigned NumUniqueDeclarations, + unsigned NumComponentLists, unsigned NumComponents) + : OMPMappableExprListClause(OMPC_from, StartLoc, LParenLoc, EndLoc, + NumVars, NumUniqueDeclarations, + NumComponentLists, NumComponents) {} + + /// \brief Build an empty clause. + /// + /// \param NumVars Number of expressions listed in this clause. + /// \param NumUniqueDeclarations Number of unique base declarations in this + /// clause. + /// \param NumComponentLists Number of component lists in this clause. + /// \param NumComponents Total number of expression components in the clause. + /// + explicit OMPFromClause(unsigned NumVars, unsigned NumUniqueDeclarations, + unsigned NumComponentLists, unsigned NumComponents) + : OMPMappableExprListClause( + OMPC_from, SourceLocation(), SourceLocation(), SourceLocation(), + NumVars, NumUniqueDeclarations, NumComponentLists, NumComponents) {} + +public: + /// \brief Creates clause with a list of variables \a Vars. + /// + /// \param C AST context. + /// \param StartLoc Starting location of the clause. + /// \param EndLoc Ending location of the clause. + /// \param Vars The original expression used in the clause. + /// \param Declarations Declarations used in the clause. + /// \param ComponentLists Component lists used in the clause. + /// + static OMPFromClause *Create(const ASTContext &C, SourceLocation StartLoc, + SourceLocation LParenLoc, SourceLocation EndLoc, + ArrayRef<Expr *> Vars, + ArrayRef<ValueDecl *> Declarations, + MappableExprComponentListsRef ComponentLists); + + /// \brief Creates an empty clause with the place for \a NumVars variables. + /// + /// \param C AST context. + /// \param NumVars Number of expressions listed in the clause. + /// \param NumUniqueDeclarations Number of unique base declarations in this + /// clause. + /// \param NumComponentLists Number of unique base declarations in this + /// clause. + /// \param NumComponents Total number of expression components in the clause. + /// + static OMPFromClause *CreateEmpty(const ASTContext &C, unsigned NumVars, + unsigned NumUniqueDeclarations, + unsigned NumComponentLists, + unsigned NumComponents); + + static bool classof(const OMPClause *T) { + return T->getClauseKind() == OMPC_from; + } + + child_range children() { + return child_range(reinterpret_cast<Stmt **>(varlist_begin()), + reinterpret_cast<Stmt **>(varlist_end())); + } +}; + +/// This represents clause 'use_device_ptr' in the '#pragma omp ...' +/// directives. +/// +/// \code +/// #pragma omp target data use_device_ptr(a,b) +/// \endcode +/// In this example directive '#pragma omp target data' has clause +/// 'use_device_ptr' with the variables 'a' and 'b'. +/// +class OMPUseDevicePtrClause final + : public OMPVarListClause<OMPUseDevicePtrClause>, + private llvm::TrailingObjects<OMPUseDevicePtrClause, Expr *> { + friend TrailingObjects; + friend OMPVarListClause; + friend class OMPClauseReader; + /// Build clause with number of variables \a N. + /// + /// \param StartLoc Starting location of the clause. + /// \param LParenLoc Location of '('. + /// \param EndLoc Ending location of the clause. + /// \param N Number of the variables in the clause. + /// + OMPUseDevicePtrClause(SourceLocation StartLoc, SourceLocation LParenLoc, + SourceLocation EndLoc, unsigned N) + : OMPVarListClause<OMPUseDevicePtrClause>(OMPC_use_device_ptr, StartLoc, + LParenLoc, EndLoc, N) {} + + /// \brief Build an empty clause. + /// + /// \param N Number of variables. + /// + explicit OMPUseDevicePtrClause(unsigned N) + : OMPVarListClause<OMPUseDevicePtrClause>( + OMPC_use_device_ptr, SourceLocation(), SourceLocation(), + SourceLocation(), N) {} + +public: + /// Creates clause with a list of variables \a VL. + /// + /// \param C AST context. + /// \param StartLoc Starting location of the clause. + /// \param LParenLoc Location of '('. + /// \param EndLoc Ending location of the clause. + /// \param VL List of references to the variables. + /// + static OMPUseDevicePtrClause * + Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, + SourceLocation EndLoc, ArrayRef<Expr *> VL); + /// Creates an empty clause with the place for \a N variables. + /// + /// \param C AST context. + /// \param N The number of variables. + /// + static OMPUseDevicePtrClause *CreateEmpty(const ASTContext &C, unsigned N); + + child_range children() { + return child_range(reinterpret_cast<Stmt **>(varlist_begin()), + reinterpret_cast<Stmt **>(varlist_end())); + } + + static bool classof(const OMPClause *T) { + return T->getClauseKind() == OMPC_use_device_ptr; + } +}; + +/// This represents clause 'is_device_ptr' in the '#pragma omp ...' +/// directives. +/// +/// \code +/// #pragma omp target is_device_ptr(a,b) +/// \endcode +/// In this example directive '#pragma omp target' has clause +/// 'is_device_ptr' with the variables 'a' and 'b'. +/// +class OMPIsDevicePtrClause final + : public OMPVarListClause<OMPIsDevicePtrClause>, + private llvm::TrailingObjects<OMPIsDevicePtrClause, Expr *> { + friend TrailingObjects; + friend OMPVarListClause; + friend class OMPClauseReader; + /// Build clause with number of variables \a N. + /// + /// \param StartLoc Starting location of the clause. + /// \param LParenLoc Location of '('. + /// \param EndLoc Ending location of the clause. + /// \param N Number of the variables in the clause. + /// + OMPIsDevicePtrClause(SourceLocation StartLoc, SourceLocation LParenLoc, + SourceLocation EndLoc, unsigned N) + : OMPVarListClause<OMPIsDevicePtrClause>(OMPC_is_device_ptr, StartLoc, + LParenLoc, EndLoc, N) {} + + /// Build an empty clause. + /// + /// \param N Number of variables. + /// + explicit OMPIsDevicePtrClause(unsigned N) + : OMPVarListClause<OMPIsDevicePtrClause>( + OMPC_is_device_ptr, SourceLocation(), SourceLocation(), + SourceLocation(), N) {} + +public: + /// Creates clause with a list of variables \a VL. + /// + /// \param C AST context. + /// \param StartLoc Starting location of the clause. + /// \param LParenLoc Location of '('. + /// \param EndLoc Ending location of the clause. + /// \param VL List of references to the variables. + /// + static OMPIsDevicePtrClause * + Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, + SourceLocation EndLoc, ArrayRef<Expr *> VL); + /// Creates an empty clause with the place for \a N variables. + /// + /// \param C AST context. + /// \param N The number of variables. + /// + static OMPIsDevicePtrClause *CreateEmpty(const ASTContext &C, unsigned N); + + child_range children() { + return child_range(reinterpret_cast<Stmt **>(varlist_begin()), + reinterpret_cast<Stmt **>(varlist_end())); + } + + static bool classof(const OMPClause *T) { + return T->getClauseKind() == OMPC_is_device_ptr; + } +}; } // end namespace clang #endif // LLVM_CLANG_AST_OPENMPCLAUSE_H diff --git a/include/clang/AST/OperationKinds.def b/include/clang/AST/OperationKinds.def new file mode 100644 index 0000000000000..82f494bec9951 --- /dev/null +++ b/include/clang/AST/OperationKinds.def @@ -0,0 +1,406 @@ +//===--- OperationKinds.def - Operations Database ---------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file enumerates the different kinds of operations that can be +// performed by various expressions. +// +//===----------------------------------------------------------------------===// +// +/// @file OperationKinds.def +/// +/// In this file, each of the C/C++ operations is enumerated CAST_OPERATION, +/// BINARY_OPERATION or UNARY_OPERATION macro, each of which can be specified by +/// the code including this file. +/// +/// Macros had one or two arguments: +/// +/// Name: The name of the operation. Name (prefixed with CK_, UO_ or BO_) will +/// be the name of the corresponding enumerator (see OperationsKinds.h). +/// +/// Spelling: A string that provides a canonical spelling for the operation. + +#ifndef CAST_OPERATION +# define CAST_OPERATION(Name) +#endif + +#ifndef BINARY_OPERATION +# define BINARY_OPERATION(Name, Spelling) +#endif + +#ifndef UNARY_OPERATION +# define UNARY_OPERATION(Name, Spelling) +#endif + +//===- Cast Operations ---------------------------------------------------===// + +/// CK_Dependent - A conversion which cannot yet be analyzed because +/// either the expression or target type is dependent. These are +/// created only for explicit casts; dependent ASTs aren't required +/// to even approximately type-check. +/// (T*) malloc(sizeof(T)) +/// reinterpret_cast<intptr_t>(A<T>::alloc()); +CAST_OPERATION(Dependent) + +/// CK_BitCast - A conversion which causes a bit pattern of one type +/// to be reinterpreted as a bit pattern of another type. Generally +/// the operands must have equivalent size and unrelated types. +/// +/// The pointer conversion char* -> int* is a bitcast. A conversion +/// from any pointer type to a C pointer type is a bitcast unless +/// it's actually BaseToDerived or DerivedToBase. A conversion to a +/// block pointer or ObjC pointer type is a bitcast only if the +/// operand has the same type kind; otherwise, it's one of the +/// specialized casts below. +/// +/// Vector coercions are bitcasts. +CAST_OPERATION(BitCast) + +/// CK_LValueBitCast - A conversion which reinterprets the address of +/// an l-value as an l-value of a different kind. Used for +/// reinterpret_casts of l-value expressions to reference types. +/// bool b; reinterpret_cast<char&>(b) = 'a'; +CAST_OPERATION(LValueBitCast) + +/// CK_LValueToRValue - A conversion which causes the extraction of +/// an r-value from the operand gl-value. The result of an r-value +/// conversion is always unqualified. +CAST_OPERATION(LValueToRValue) + +/// CK_NoOp - A conversion which does not affect the type other than +/// (possibly) adding qualifiers. +/// int -> int +/// char** -> const char * const * +CAST_OPERATION(NoOp) + +/// CK_BaseToDerived - A conversion from a C++ class pointer/reference +/// to a derived class pointer/reference. +/// B *b = static_cast<B*>(a); +CAST_OPERATION(BaseToDerived) + +/// CK_DerivedToBase - A conversion from a C++ class pointer +/// to a base class pointer. +/// A *a = new B(); +CAST_OPERATION(DerivedToBase) + +/// CK_UncheckedDerivedToBase - A conversion from a C++ class +/// pointer/reference to a base class that can assume that the +/// derived pointer is not null. +/// const A &a = B(); +/// b->method_from_a(); +CAST_OPERATION(UncheckedDerivedToBase) + +/// CK_Dynamic - A C++ dynamic_cast. +CAST_OPERATION(Dynamic) + +/// CK_ToUnion - The GCC cast-to-union extension. +/// int -> union { int x; float y; } +/// float -> union { int x; float y; } +CAST_OPERATION(ToUnion) + +/// CK_ArrayToPointerDecay - Array to pointer decay. +/// int[10] -> int* +/// char[5][6] -> char(*)[6] +CAST_OPERATION(ArrayToPointerDecay) + +/// CK_FunctionToPointerDecay - Function to pointer decay. +/// void(int) -> void(*)(int) +CAST_OPERATION(FunctionToPointerDecay) + +/// CK_NullToPointer - Null pointer constant to pointer, ObjC +/// pointer, or block pointer. +/// (void*) 0 +/// void (^block)() = 0; +CAST_OPERATION(NullToPointer) + +/// CK_NullToMemberPointer - Null pointer constant to member pointer. +/// int A::*mptr = 0; +/// int (A::*fptr)(int) = nullptr; +CAST_OPERATION(NullToMemberPointer) + +/// CK_BaseToDerivedMemberPointer - Member pointer in base class to +/// member pointer in derived class. +/// int B::*mptr = &A::member; +CAST_OPERATION(BaseToDerivedMemberPointer) + +/// CK_DerivedToBaseMemberPointer - Member pointer in derived class to +/// member pointer in base class. +/// int A::*mptr = static_cast<int A::*>(&B::member); +CAST_OPERATION(DerivedToBaseMemberPointer) + +/// CK_MemberPointerToBoolean - Member pointer to boolean. A check +/// against the null member pointer. +CAST_OPERATION(MemberPointerToBoolean) + +/// CK_ReinterpretMemberPointer - Reinterpret a member pointer as a +/// different kind of member pointer. C++ forbids this from +/// crossing between function and object types, but otherwise does +/// not restrict it. However, the only operation that is permitted +/// on a "punned" member pointer is casting it back to the original +/// type, which is required to be a lossless operation (although +/// many ABIs do not guarantee this on all possible intermediate types). +CAST_OPERATION(ReinterpretMemberPointer) + +/// CK_UserDefinedConversion - Conversion using a user defined type +/// conversion function. +/// struct A { operator int(); }; int i = int(A()); +CAST_OPERATION(UserDefinedConversion) + +/// CK_ConstructorConversion - Conversion by constructor. +/// struct A { A(int); }; A a = A(10); +CAST_OPERATION(ConstructorConversion) + +/// CK_IntegralToPointer - Integral to pointer. A special kind of +/// reinterpreting conversion. Applies to normal, ObjC, and block +/// pointers. +/// (char*) 0x1001aab0 +/// reinterpret_cast<int*>(0) +CAST_OPERATION(IntegralToPointer) + +/// CK_PointerToIntegral - Pointer to integral. A special kind of +/// reinterpreting conversion. Applies to normal, ObjC, and block +/// pointers. +/// (intptr_t) "help!" +CAST_OPERATION(PointerToIntegral) + +/// CK_PointerToBoolean - Pointer to boolean conversion. A check +/// against null. Applies to normal, ObjC, and block pointers. +CAST_OPERATION(PointerToBoolean) + +/// CK_ToVoid - Cast to void, discarding the computed value. +/// (void) malloc(2048) +CAST_OPERATION(ToVoid) + +/// CK_VectorSplat - A conversion from an arithmetic type to a +/// vector of that element type. Fills all elements ("splats") with +/// the source value. +/// __attribute__((ext_vector_type(4))) int v = 5; +CAST_OPERATION(VectorSplat) + +/// CK_IntegralCast - A cast between integral types (other than to +/// boolean). Variously a bitcast, a truncation, a sign-extension, +/// or a zero-extension. +/// long l = 5; +/// (unsigned) i +CAST_OPERATION(IntegralCast) + +/// CK_IntegralToBoolean - Integral to boolean. A check against zero. +/// (bool) i +CAST_OPERATION(IntegralToBoolean) + +/// CK_IntegralToFloating - Integral to floating point. +/// float f = i; +CAST_OPERATION(IntegralToFloating) + +/// CK_FloatingToIntegral - Floating point to integral. Rounds +/// towards zero, discarding any fractional component. +/// (int) f +CAST_OPERATION(FloatingToIntegral) + +/// CK_FloatingToBoolean - Floating point to boolean. +/// (bool) f +CAST_OPERATION(FloatingToBoolean) + +// CK_BooleanToSignedIntegral - Convert a boolean to -1 or 0 for true and +// false, respectively. +CAST_OPERATION(BooleanToSignedIntegral) + +/// CK_FloatingCast - Casting between floating types of different size. +/// (double) f +/// (float) ld +CAST_OPERATION(FloatingCast) + +/// CK_CPointerToObjCPointerCast - Casting a C pointer kind to an +/// Objective-C pointer. +CAST_OPERATION(CPointerToObjCPointerCast) + +/// CK_BlockPointerToObjCPointerCast - Casting a block pointer to an +/// ObjC pointer. +CAST_OPERATION(BlockPointerToObjCPointerCast) + +/// CK_AnyPointerToBlockPointerCast - Casting any non-block pointer +/// to a block pointer. Block-to-block casts are bitcasts. +CAST_OPERATION(AnyPointerToBlockPointerCast) + +/// \brief Converting between two Objective-C object types, which +/// can occur when performing reference binding to an Objective-C +/// object. +CAST_OPERATION(ObjCObjectLValueCast) + +/// \brief A conversion of a floating point real to a floating point +/// complex of the original type. Injects the value as the real +/// component with a zero imaginary component. +/// float -> _Complex float +CAST_OPERATION(FloatingRealToComplex) + +/// \brief Converts a floating point complex to floating point real +/// of the source's element type. Just discards the imaginary +/// component. +/// _Complex long double -> long double +CAST_OPERATION(FloatingComplexToReal) + +/// \brief Converts a floating point complex to bool by comparing +/// against 0+0i. +CAST_OPERATION(FloatingComplexToBoolean) + +/// \brief Converts between different floating point complex types. +/// _Complex float -> _Complex double +CAST_OPERATION(FloatingComplexCast) + +/// \brief Converts from a floating complex to an integral complex. +/// _Complex float -> _Complex int +CAST_OPERATION(FloatingComplexToIntegralComplex) + +/// \brief Converts from an integral real to an integral complex +/// whose element type matches the source. Injects the value as +/// the real component with a zero imaginary component. +/// long -> _Complex long +CAST_OPERATION(IntegralRealToComplex) + +/// \brief Converts an integral complex to an integral real of the +/// source's element type by discarding the imaginary component. +/// _Complex short -> short +CAST_OPERATION(IntegralComplexToReal) + +/// \brief Converts an integral complex to bool by comparing against +/// 0+0i. +CAST_OPERATION(IntegralComplexToBoolean) + +/// \brief Converts between different integral complex types. +/// _Complex char -> _Complex long long +/// _Complex unsigned int -> _Complex signed int +CAST_OPERATION(IntegralComplexCast) + +/// \brief Converts from an integral complex to a floating complex. +/// _Complex unsigned -> _Complex float +CAST_OPERATION(IntegralComplexToFloatingComplex) + +/// \brief [ARC] Produces a retainable object pointer so that it may +/// be consumed, e.g. by being passed to a consuming parameter. +/// Calls objc_retain. +CAST_OPERATION(ARCProduceObject) + +/// \brief [ARC] Consumes a retainable object pointer that has just +/// been produced, e.g. as the return value of a retaining call. +/// Enters a cleanup to call objc_release at some indefinite time. +CAST_OPERATION(ARCConsumeObject) + +/// \brief [ARC] Reclaim a retainable object pointer object that may +/// have been produced and autoreleased as part of a function return +/// sequence. +CAST_OPERATION(ARCReclaimReturnedObject) + +/// \brief [ARC] Causes a value of block type to be copied to the +/// heap, if it is not already there. A number of other operations +/// in ARC cause blocks to be copied; this is for cases where that +/// would not otherwise be guaranteed, such as when casting to a +/// non-block pointer type. +CAST_OPERATION(ARCExtendBlockObject) + +/// \brief Converts from _Atomic(T) to T. +CAST_OPERATION(AtomicToNonAtomic) +/// \brief Converts from T to _Atomic(T). +CAST_OPERATION(NonAtomicToAtomic) + +/// \brief Causes a block literal to by copied to the heap and then +/// autoreleased. +/// +/// This particular cast kind is used for the conversion from a C++11 +/// lambda expression to a block pointer. +CAST_OPERATION(CopyAndAutoreleaseBlockObject) + +// Convert a builtin function to a function pointer; only allowed in the +// callee of a call expression. +CAST_OPERATION(BuiltinFnToFnPtr) + +// Convert a zero value for OpenCL event_t initialization. +CAST_OPERATION(ZeroToOCLEvent) + +// Convert a pointer to a different address space. +CAST_OPERATION(AddressSpaceConversion) + + +//===- Binary Operations -------------------------------------------------===// +// Operators listed in order of precedence. +// Note that additions to this should also update the StmtVisitor class. + +// [C++ 5.5] Pointer-to-member operators. +BINARY_OPERATION(PtrMemD, ".*") +BINARY_OPERATION(PtrMemI, "->*") +// [C99 6.5.5] Multiplicative operators. +BINARY_OPERATION(Mul, "*") +BINARY_OPERATION(Div, "/") +BINARY_OPERATION(Rem, "%") +// [C99 6.5.6] Additive operators. +BINARY_OPERATION(Add, "+") +BINARY_OPERATION(Sub, "-") +// [C99 6.5.7] Bitwise shift operators. +BINARY_OPERATION(Shl, "<<") +BINARY_OPERATION(Shr, ">>") +// [C99 6.5.8] Relational operators. +BINARY_OPERATION(LT, "<") +BINARY_OPERATION(GT, ">") +BINARY_OPERATION(LE, "<=") +BINARY_OPERATION(GE, ">=") +// [C99 6.5.9] Equality operators. +BINARY_OPERATION(EQ, "==") +BINARY_OPERATION(NE, "!=") +// [C99 6.5.10] Bitwise AND operator. +BINARY_OPERATION(And, "&") +// [C99 6.5.11] Bitwise XOR operator. +BINARY_OPERATION(Xor, "^") +// [C99 6.5.12] Bitwise OR operator. +BINARY_OPERATION(Or, "|") +// [C99 6.5.13] Logical AND operator. +BINARY_OPERATION(LAnd, "&&") +// [C99 6.5.14] Logical OR operator. +BINARY_OPERATION(LOr, "||") +// [C99 6.5.16] Assignment operators. +BINARY_OPERATION(Assign, "=") +BINARY_OPERATION(MulAssign, "*=") +BINARY_OPERATION(DivAssign, "/=") +BINARY_OPERATION(RemAssign, "%=") +BINARY_OPERATION(AddAssign, "+=") +BINARY_OPERATION(SubAssign, "-=") +BINARY_OPERATION(ShlAssign, "<<=") +BINARY_OPERATION(ShrAssign, ">>=") +BINARY_OPERATION(AndAssign, "&=") +BINARY_OPERATION(XorAssign, "^=") +BINARY_OPERATION(OrAssign, "|=") +// [C99 6.5.17] Comma operator. +BINARY_OPERATION(Comma, ",") + + +//===- Unary Operations ---------------------------------------------------===// +// Note that additions to this should also update the StmtVisitor class. + +// [C99 6.5.2.4] Postfix increment and decrement +UNARY_OPERATION(PostInc, "++") +UNARY_OPERATION(PostDec, "--") +// [C99 6.5.3.1] Prefix increment and decrement +UNARY_OPERATION(PreInc, "++") +UNARY_OPERATION(PreDec, "--") +// [C99 6.5.3.2] Address and indirection +UNARY_OPERATION(AddrOf, "&") +UNARY_OPERATION(Deref, "*") +// [C99 6.5.3.3] Unary arithmetic +UNARY_OPERATION(Plus, "+") +UNARY_OPERATION(Minus, "-") +UNARY_OPERATION(Not, "~") +UNARY_OPERATION(LNot, "!") +// "__real expr"/"__imag expr" Extension. +UNARY_OPERATION(Real, "__real") +UNARY_OPERATION(Imag, "__imag") +// __extension__ marker. +UNARY_OPERATION(Extension, "__extension__") +// [C++ Coroutines] co_await operator +UNARY_OPERATION(Coawait, "co_await") + +#undef CAST_OPERATION +#undef BINARY_OPERATION +#undef UNARY_OPERATION diff --git a/include/clang/AST/OperationKinds.h b/include/clang/AST/OperationKinds.h index 102bbc21edb37..00f060fe9e3d0 100644 --- a/include/clang/AST/OperationKinds.h +++ b/include/clang/AST/OperationKinds.h @@ -19,327 +19,20 @@ namespace clang { /// CastKind - The kind of operation required for a conversion. enum CastKind { - /// CK_Dependent - A conversion which cannot yet be analyzed because - /// either the expression or target type is dependent. These are - /// created only for explicit casts; dependent ASTs aren't required - /// to even approximately type-check. - /// (T*) malloc(sizeof(T)) - /// reinterpret_cast<intptr_t>(A<T>::alloc()); - CK_Dependent, - - /// CK_BitCast - A conversion which causes a bit pattern of one type - /// to be reinterpreted as a bit pattern of another type. Generally - /// the operands must have equivalent size and unrelated types. - /// - /// The pointer conversion char* -> int* is a bitcast. A conversion - /// from any pointer type to a C pointer type is a bitcast unless - /// it's actually BaseToDerived or DerivedToBase. A conversion to a - /// block pointer or ObjC pointer type is a bitcast only if the - /// operand has the same type kind; otherwise, it's one of the - /// specialized casts below. - /// - /// Vector coercions are bitcasts. - CK_BitCast, - - /// CK_LValueBitCast - A conversion which reinterprets the address of - /// an l-value as an l-value of a different kind. Used for - /// reinterpret_casts of l-value expressions to reference types. - /// bool b; reinterpret_cast<char&>(b) = 'a'; - CK_LValueBitCast, - - /// CK_LValueToRValue - A conversion which causes the extraction of - /// an r-value from the operand gl-value. The result of an r-value - /// conversion is always unqualified. - CK_LValueToRValue, - - /// CK_NoOp - A conversion which does not affect the type other than - /// (possibly) adding qualifiers. - /// int -> int - /// char** -> const char * const * - CK_NoOp, - - /// CK_BaseToDerived - A conversion from a C++ class pointer/reference - /// to a derived class pointer/reference. - /// B *b = static_cast<B*>(a); - CK_BaseToDerived, - - /// CK_DerivedToBase - A conversion from a C++ class pointer - /// to a base class pointer. - /// A *a = new B(); - CK_DerivedToBase, - - /// CK_UncheckedDerivedToBase - A conversion from a C++ class - /// pointer/reference to a base class that can assume that the - /// derived pointer is not null. - /// const A &a = B(); - /// b->method_from_a(); - CK_UncheckedDerivedToBase, - - /// CK_Dynamic - A C++ dynamic_cast. - CK_Dynamic, - - /// CK_ToUnion - The GCC cast-to-union extension. - /// int -> union { int x; float y; } - /// float -> union { int x; float y; } - CK_ToUnion, - - /// CK_ArrayToPointerDecay - Array to pointer decay. - /// int[10] -> int* - /// char[5][6] -> char(*)[6] - CK_ArrayToPointerDecay, - - /// CK_FunctionToPointerDecay - Function to pointer decay. - /// void(int) -> void(*)(int) - CK_FunctionToPointerDecay, - - /// CK_NullToPointer - Null pointer constant to pointer, ObjC - /// pointer, or block pointer. - /// (void*) 0 - /// void (^block)() = 0; - CK_NullToPointer, - - /// CK_NullToMemberPointer - Null pointer constant to member pointer. - /// int A::*mptr = 0; - /// int (A::*fptr)(int) = nullptr; - CK_NullToMemberPointer, - - /// CK_BaseToDerivedMemberPointer - Member pointer in base class to - /// member pointer in derived class. - /// int B::*mptr = &A::member; - CK_BaseToDerivedMemberPointer, - - /// CK_DerivedToBaseMemberPointer - Member pointer in derived class to - /// member pointer in base class. - /// int A::*mptr = static_cast<int A::*>(&B::member); - CK_DerivedToBaseMemberPointer, - - /// CK_MemberPointerToBoolean - Member pointer to boolean. A check - /// against the null member pointer. - CK_MemberPointerToBoolean, - - /// CK_ReinterpretMemberPointer - Reinterpret a member pointer as a - /// different kind of member pointer. C++ forbids this from - /// crossing between function and object types, but otherwise does - /// not restrict it. However, the only operation that is permitted - /// on a "punned" member pointer is casting it back to the original - /// type, which is required to be a lossless operation (although - /// many ABIs do not guarantee this on all possible intermediate types). - CK_ReinterpretMemberPointer, - - /// CK_UserDefinedConversion - Conversion using a user defined type - /// conversion function. - /// struct A { operator int(); }; int i = int(A()); - CK_UserDefinedConversion, - - /// CK_ConstructorConversion - Conversion by constructor. - /// struct A { A(int); }; A a = A(10); - CK_ConstructorConversion, - - /// CK_IntegralToPointer - Integral to pointer. A special kind of - /// reinterpreting conversion. Applies to normal, ObjC, and block - /// pointers. - /// (char*) 0x1001aab0 - /// reinterpret_cast<int*>(0) - CK_IntegralToPointer, - - /// CK_PointerToIntegral - Pointer to integral. A special kind of - /// reinterpreting conversion. Applies to normal, ObjC, and block - /// pointers. - /// (intptr_t) "help!" - CK_PointerToIntegral, - - /// CK_PointerToBoolean - Pointer to boolean conversion. A check - /// against null. Applies to normal, ObjC, and block pointers. - CK_PointerToBoolean, - - /// CK_ToVoid - Cast to void, discarding the computed value. - /// (void) malloc(2048) - CK_ToVoid, - - /// CK_VectorSplat - A conversion from an arithmetic type to a - /// vector of that element type. Fills all elements ("splats") with - /// the source value. - /// __attribute__((ext_vector_type(4))) int v = 5; - CK_VectorSplat, - - /// CK_IntegralCast - A cast between integral types (other than to - /// boolean). Variously a bitcast, a truncation, a sign-extension, - /// or a zero-extension. - /// long l = 5; - /// (unsigned) i - CK_IntegralCast, - - /// CK_IntegralToBoolean - Integral to boolean. A check against zero. - /// (bool) i - CK_IntegralToBoolean, - - /// CK_IntegralToFloating - Integral to floating point. - /// float f = i; - CK_IntegralToFloating, - - /// CK_FloatingToIntegral - Floating point to integral. Rounds - /// towards zero, discarding any fractional component. - /// (int) f - CK_FloatingToIntegral, - - /// CK_FloatingToBoolean - Floating point to boolean. - /// (bool) f - CK_FloatingToBoolean, - - // CK_BooleanToSignedIntegral - Convert a boolean to -1 or 0 for true and - // false, respectively. - CK_BooleanToSignedIntegral, - - /// CK_FloatingCast - Casting between floating types of different size. - /// (double) f - /// (float) ld - CK_FloatingCast, - - /// CK_CPointerToObjCPointerCast - Casting a C pointer kind to an - /// Objective-C pointer. - CK_CPointerToObjCPointerCast, - - /// CK_BlockPointerToObjCPointerCast - Casting a block pointer to an - /// ObjC pointer. - CK_BlockPointerToObjCPointerCast, - - /// CK_AnyPointerToBlockPointerCast - Casting any non-block pointer - /// to a block pointer. Block-to-block casts are bitcasts. - CK_AnyPointerToBlockPointerCast, - - /// \brief Converting between two Objective-C object types, which - /// can occur when performing reference binding to an Objective-C - /// object. - CK_ObjCObjectLValueCast, - - /// \brief A conversion of a floating point real to a floating point - /// complex of the original type. Injects the value as the real - /// component with a zero imaginary component. - /// float -> _Complex float - CK_FloatingRealToComplex, - - /// \brief Converts a floating point complex to floating point real - /// of the source's element type. Just discards the imaginary - /// component. - /// _Complex long double -> long double - CK_FloatingComplexToReal, - - /// \brief Converts a floating point complex to bool by comparing - /// against 0+0i. - CK_FloatingComplexToBoolean, - - /// \brief Converts between different floating point complex types. - /// _Complex float -> _Complex double - CK_FloatingComplexCast, - - /// \brief Converts from a floating complex to an integral complex. - /// _Complex float -> _Complex int - CK_FloatingComplexToIntegralComplex, - - /// \brief Converts from an integral real to an integral complex - /// whose element type matches the source. Injects the value as - /// the real component with a zero imaginary component. - /// long -> _Complex long - CK_IntegralRealToComplex, - - /// \brief Converts an integral complex to an integral real of the - /// source's element type by discarding the imaginary component. - /// _Complex short -> short - CK_IntegralComplexToReal, - - /// \brief Converts an integral complex to bool by comparing against - /// 0+0i. - CK_IntegralComplexToBoolean, - - /// \brief Converts between different integral complex types. - /// _Complex char -> _Complex long long - /// _Complex unsigned int -> _Complex signed int - CK_IntegralComplexCast, - - /// \brief Converts from an integral complex to a floating complex. - /// _Complex unsigned -> _Complex float - CK_IntegralComplexToFloatingComplex, - - /// \brief [ARC] Produces a retainable object pointer so that it may - /// be consumed, e.g. by being passed to a consuming parameter. - /// Calls objc_retain. - CK_ARCProduceObject, - - /// \brief [ARC] Consumes a retainable object pointer that has just - /// been produced, e.g. as the return value of a retaining call. - /// Enters a cleanup to call objc_release at some indefinite time. - CK_ARCConsumeObject, - - /// \brief [ARC] Reclaim a retainable object pointer object that may - /// have been produced and autoreleased as part of a function return - /// sequence. - CK_ARCReclaimReturnedObject, - - /// \brief [ARC] Causes a value of block type to be copied to the - /// heap, if it is not already there. A number of other operations - /// in ARC cause blocks to be copied; this is for cases where that - /// would not otherwise be guaranteed, such as when casting to a - /// non-block pointer type. - CK_ARCExtendBlockObject, - - /// \brief Converts from _Atomic(T) to T. - CK_AtomicToNonAtomic, - /// \brief Converts from T to _Atomic(T). - CK_NonAtomicToAtomic, - - /// \brief Causes a block literal to by copied to the heap and then - /// autoreleased. - /// - /// This particular cast kind is used for the conversion from a C++11 - /// lambda expression to a block pointer. - CK_CopyAndAutoreleaseBlockObject, - - // Convert a builtin function to a function pointer; only allowed in the - // callee of a call expression. - CK_BuiltinFnToFnPtr, - - // Convert a zero value for OpenCL event_t initialization. - CK_ZeroToOCLEvent, - - // Convert a pointer to a different address space. - CK_AddressSpaceConversion +#define CAST_OPERATION(Name) CK_##Name, +#include "clang/AST/OperationKinds.def" }; static const CastKind CK_Invalid = static_cast<CastKind>(-1); enum BinaryOperatorKind { - // Operators listed in order of precedence. - // Note that additions to this should also update the StmtVisitor class. - BO_PtrMemD, BO_PtrMemI, // [C++ 5.5] Pointer-to-member operators. - BO_Mul, BO_Div, BO_Rem, // [C99 6.5.5] Multiplicative operators. - BO_Add, BO_Sub, // [C99 6.5.6] Additive operators. - BO_Shl, BO_Shr, // [C99 6.5.7] Bitwise shift operators. - BO_LT, BO_GT, BO_LE, BO_GE, // [C99 6.5.8] Relational operators. - BO_EQ, BO_NE, // [C99 6.5.9] Equality operators. - BO_And, // [C99 6.5.10] Bitwise AND operator. - BO_Xor, // [C99 6.5.11] Bitwise XOR operator. - BO_Or, // [C99 6.5.12] Bitwise OR operator. - BO_LAnd, // [C99 6.5.13] Logical AND operator. - BO_LOr, // [C99 6.5.14] Logical OR operator. - BO_Assign, BO_MulAssign, // [C99 6.5.16] Assignment operators. - BO_DivAssign, BO_RemAssign, - BO_AddAssign, BO_SubAssign, - BO_ShlAssign, BO_ShrAssign, - BO_AndAssign, BO_XorAssign, - BO_OrAssign, - BO_Comma // [C99 6.5.17] Comma operator. +#define BINARY_OPERATION(Name, Spelling) BO_##Name, +#include "clang/AST/OperationKinds.def" }; enum UnaryOperatorKind { - // Note that additions to this should also update the StmtVisitor class. - UO_PostInc, UO_PostDec, // [C99 6.5.2.4] Postfix increment and decrement - UO_PreInc, UO_PreDec, // [C99 6.5.3.1] Prefix increment and decrement - UO_AddrOf, UO_Deref, // [C99 6.5.3.2] Address and indirection - UO_Plus, UO_Minus, // [C99 6.5.3.3] Unary arithmetic - UO_Not, UO_LNot, // [C99 6.5.3.3] Unary arithmetic - UO_Real, UO_Imag, // "__real expr"/"__imag expr" Extension. - UO_Extension, // __extension__ marker. - UO_Coawait // [C++ Coroutines] co_await operator +#define UNARY_OPERATION(Name, Spelling) UO_##Name, +#include "clang/AST/OperationKinds.def" }; /// \brief The kind of bridging performed by the Objective-C bridge cast. @@ -355,6 +48,6 @@ enum ObjCBridgeCastKind { OBC_BridgeRetained }; -} +} // end namespace clang #endif diff --git a/include/clang/AST/PrettyPrinter.h b/include/clang/AST/PrettyPrinter.h index 8ab3f61703a3c..274df220e160e 100644 --- a/include/clang/AST/PrettyPrinter.h +++ b/include/clang/AST/PrettyPrinter.h @@ -32,20 +32,35 @@ public: /// \brief 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. struct PrintingPolicy { - /// \brief Create a default printing policy for C. + /// \brief Create a default printing policy for the specified language. PrintingPolicy(const LangOptions &LO) - : LangOpts(LO), Indentation(2), SuppressSpecifiers(false), - SuppressTagKeyword(false), SuppressTag(false), SuppressScope(false), + : Indentation(2), SuppressSpecifiers(false), + SuppressTagKeyword(LO.CPlusPlus), + IncludeTagDefinition(false), SuppressScope(false), SuppressUnwrittenScope(false), SuppressInitializers(false), ConstantArraySizeAsWritten(false), AnonymousTagLocations(true), SuppressStrongLifetime(false), SuppressLifetimeQualifiers(false), - Bool(LO.Bool), TerseOutput(false), PolishForDeclaration(false), + SuppressTemplateArgsInCXXConstructors(false), + Bool(LO.Bool), Restrict(LO.C99), + Alignof(LO.CPlusPlus11), UnderscoreAlignof(LO.C11), + UseVoidForZeroParams(!LO.CPlusPlus), + TerseOutput(false), PolishForDeclaration(false), Half(LO.Half), MSWChar(LO.MicrosoftExt && !LO.WChar), IncludeNewlines(true), MSVCFormatting(false) { } - /// \brief What language we're printing. - LangOptions LangOpts; + /// \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. + void adjustForCPlusPlus() { + SuppressTagKeyword = true; + Bool = true; + UseVoidForZeroParams = false; + } /// \brief The number of spaces to use to indent each line. unsigned Indentation : 8; @@ -76,15 +91,15 @@ struct PrintingPolicy { /// \endcode bool SuppressTagKeyword : 1; - /// \brief Whether type printing should skip printing the actual tag type. + /// \brief When true, include the body of a tag definition. /// - /// This is used when the caller needs to print a tag definition in front - /// of the type, as in constructs like the following: + /// This is used to place the definition of a struct + /// in the middle of another declaration as with: /// /// \code /// typedef struct { int x, y; } Point; /// \endcode - bool SuppressTag : 1; + bool IncludeTagDefinition : 1; /// \brief Suppresses printing of scope specifiers. bool SuppressScope : 1; @@ -136,11 +151,28 @@ struct PrintingPolicy { /// \brief When true, suppress printing of lifetime qualifier in /// ARC. unsigned SuppressLifetimeQualifiers : 1; - - /// \brief 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). + + /// 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 + /// 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'. + unsigned Restrict : 1; + + /// \brief Whether we can use 'alignof' rather than '__alignof'. + unsigned Alignof : 1; + + /// \brief 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. + unsigned UseVoidForZeroParams : 1; + /// \brief Provide a 'terse' output. /// /// For example, in this mode we don't print function bodies, class members, diff --git a/include/clang/AST/RecordLayout.h b/include/clang/AST/RecordLayout.h index 667f23520eb78..7a39c3b2539df 100644 --- a/include/clang/AST/RecordLayout.h +++ b/include/clang/AST/RecordLayout.h @@ -71,10 +71,7 @@ private: CharUnits RequiredAlignment; /// FieldOffsets - Array of field offsets in bits. - uint64_t *FieldOffsets; - - // FieldCount - Number of fields. - unsigned FieldCount; + ASTVector<uint64_t> FieldOffsets; /// CXXRecordLayoutInfo - Contains C++ specific layout information. struct CXXRecordLayoutInfo { @@ -104,10 +101,10 @@ private: /// a primary base class. bool HasExtendableVFPtr : 1; - /// HasZeroSizedSubObject - True if this class contains a zero sized member - /// or base or a base with a zero sized member or base. Only used for - /// MS-ABI. - bool HasZeroSizedSubObject : 1; + /// EndsWithZeroSizedObject - True if this class contains a zero sized + /// member or base or a base with a zero sized member or base. + /// Only used for MS-ABI. + bool EndsWithZeroSizedObject : 1; /// \brief True if this class is zero sized or first base is zero sized or /// has this property. Only used for MS-ABI. @@ -136,9 +133,8 @@ private: friend class ASTContext; ASTRecordLayout(const ASTContext &Ctx, CharUnits size, CharUnits alignment, - CharUnits requiredAlignment, - CharUnits datasize, const uint64_t *fieldoffsets, - unsigned fieldcount); + CharUnits requiredAlignment, CharUnits datasize, + ArrayRef<uint64_t> fieldoffsets); // Constructor for C++ records. typedef CXXRecordLayoutInfo::BaseOffsetsMapTy BaseOffsetsMapTy; @@ -148,13 +144,13 @@ private: bool hasOwnVFPtr, bool hasExtendableVFPtr, CharUnits vbptroffset, CharUnits datasize, - const uint64_t *fieldoffsets, unsigned fieldcount, + ArrayRef<uint64_t> fieldoffsets, CharUnits nonvirtualsize, CharUnits nonvirtualalignment, CharUnits SizeOfLargestEmptySubobject, const CXXRecordDecl *PrimaryBase, bool IsPrimaryBaseVirtual, const CXXRecordDecl *BaseSharingVBPtr, - bool HasZeroSizedSubObject, + bool EndsWithZeroSizedObject, bool LeadsWithZeroSizedBase, const BaseOffsetsMapTy& BaseOffsets, const VBaseOffsetsMapTy& VBaseOffsets); @@ -174,12 +170,11 @@ public: CharUnits getSize() const { return Size; } /// getFieldCount - Get the number of fields in the layout. - unsigned getFieldCount() const { return FieldCount; } + unsigned getFieldCount() const { return FieldOffsets.size(); } /// getFieldOffset - Get the offset of the given field index, in /// bits. uint64_t getFieldOffset(unsigned FieldNo) const { - assert (FieldNo < FieldCount && "Invalid Field No"); return FieldOffsets[FieldNo]; } @@ -283,8 +278,8 @@ public: return RequiredAlignment; } - bool hasZeroSizedSubObject() const { - return CXXInfo && CXXInfo->HasZeroSizedSubObject; + bool endsWithZeroSizedObject() const { + return CXXInfo && CXXInfo->EndsWithZeroSizedObject; } bool leadsWithZeroSizedBase() const { diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h index 0c25a45c1cec3..f918b830d4212 100644 --- a/include/clang/AST/RecursiveASTVisitor.h +++ b/include/clang/AST/RecursiveASTVisitor.h @@ -72,8 +72,8 @@ namespace clang { return false; \ } while (0) -/// \brief A class that does preorder depth-first traversal on the -/// entire Clang AST and visits each node. +/// \brief A class that does preordor or postorder +/// depth-first traversal on the entire Clang AST and visits each node. /// /// This class performs three distinct tasks: /// 1. traverse the AST (i.e. go to each node); @@ -133,13 +133,19 @@ namespace clang { /// to return true, in which case all known implicit and explicit /// instantiations will be visited at the same time as the pattern /// from which they were produced. +/// +/// By default, this visitor preorder traverses the AST. If postorder traversal +/// is needed, the \c shouldTraversePostOrder method needs to be overriden +/// to return \c true. template <typename Derived> class RecursiveASTVisitor { public: /// A queue used for performing data recursion over statements. /// Parameters involving this type are used to implement data /// recursion over Stmts and Exprs within this class, and should /// typically not be explicitly specified by derived classes. - typedef SmallVectorImpl<Stmt *> DataRecursionQueue; + /// The bool bit indicates whether the statement has been traversed or not. + typedef SmallVectorImpl<llvm::PointerIntPair<Stmt *, 1, bool>> + DataRecursionQueue; /// \brief Return a reference to the derived class. Derived &getDerived() { return *static_cast<Derived *>(this); } @@ -156,6 +162,9 @@ public: /// code, e.g., implicit constructors and destructors. bool shouldVisitImplicitCode() const { return false; } + /// \brief Return whether this visitor should traverse post-order. + bool shouldTraversePostOrder() const { return false; } + /// \brief Recursively visit a statement or expression, by /// dispatching to Traverse*() based on the argument's dynamic type. /// @@ -163,6 +172,18 @@ public: /// otherwise (including when the argument is nullptr). bool TraverseStmt(Stmt *S, DataRecursionQueue *Queue = nullptr); + /// Invoked before visiting a statement or expression via data recursion. + /// + /// \returns false to skip visiting the node, true otherwise. + bool dataTraverseStmtPre(Stmt *S) { return true; } + + /// Invoked after visiting a statement or expression via data recursion. + /// This is not invoked if the previously invoked \c dataTraverseStmtPre + /// returned false. + /// + /// \returns false if the visitation was terminated early, true otherwise. + bool dataTraverseStmtPost(Stmt *S) { return true; } + /// \brief Recursively visit a type, by dispatching to /// Traverse*Type() based on the argument's getTypeClass() property. /// @@ -335,7 +356,7 @@ public: bool TraverseUnary##NAME(UnaryOperator *S, \ DataRecursionQueue *Queue = nullptr) { \ TRY_TO(WalkUpFromUnary##NAME(S)); \ - TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getSubExpr()); \ + TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getSubExpr()); \ return true; \ } \ bool WalkUpFromUnary##NAME(UnaryOperator *S) { \ @@ -353,9 +374,10 @@ public: // (they're all opcodes in BinaryOperator) but do have visitors. #define GENERAL_BINOP_FALLBACK(NAME, BINOP_TYPE) \ bool TraverseBin##NAME(BINOP_TYPE *S, DataRecursionQueue *Queue = nullptr) { \ - TRY_TO(WalkUpFromBin##NAME(S)); \ - TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getLHS()); \ - TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getRHS()); \ + if (!getDerived().shouldTraversePostOrder()) \ + TRY_TO(WalkUpFromBin##NAME(S)); \ + TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getLHS()); \ + TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getRHS()); \ return true; \ } \ bool WalkUpFromBin##NAME(BINOP_TYPE *S) { \ @@ -480,8 +502,12 @@ private: #include "clang/Basic/OpenMPKinds.def" /// \brief Process clauses with list of variables. template <typename T> bool VisitOMPClauseList(T *Node); + /// Process clauses with pre-initis. + bool VisitOMPClauseWithPreInit(OMPClauseWithPreInit *Node); + bool VisitOMPClauseWithPostUpdate(OMPClauseWithPostUpdate *Node); bool dataTraverseNode(Stmt *S, DataRecursionQueue *Queue); + bool PostVisitStmt(Stmt *S); }; template <typename Derived> @@ -539,6 +565,24 @@ bool RecursiveASTVisitor<Derived>::dataTraverseNode(Stmt *S, #undef DISPATCH_STMT + +template <typename Derived> +bool RecursiveASTVisitor<Derived>::PostVisitStmt(Stmt *S) { + switch (S->getStmtClass()) { + case Stmt::NoStmtClass: + break; +#define ABSTRACT_STMT(STMT) +#define STMT(CLASS, PARENT) \ + case Stmt::CLASS##Class: \ + TRY_TO(WalkUpFrom##CLASS(static_cast<CLASS *>(S))); break; +#include "clang/AST/StmtNodes.inc" + } + + return true; +} + +#undef DISPATCH_STMT + template <typename Derived> bool RecursiveASTVisitor<Derived>::TraverseStmt(Stmt *S, DataRecursionQueue *Queue) { @@ -546,20 +590,35 @@ bool RecursiveASTVisitor<Derived>::TraverseStmt(Stmt *S, return true; if (Queue) { - Queue->push_back(S); + Queue->push_back({S, false}); return true; } - SmallVector<Stmt *, 8> LocalQueue; - LocalQueue.push_back(S); + SmallVector<llvm::PointerIntPair<Stmt *, 1, bool>, 8> LocalQueue; + LocalQueue.push_back({S, false}); while (!LocalQueue.empty()) { - Stmt *CurrS = LocalQueue.pop_back_val(); + auto &CurrSAndVisited = LocalQueue.back(); + Stmt *CurrS = CurrSAndVisited.getPointer(); + bool Visited = CurrSAndVisited.getInt(); + if (Visited) { + LocalQueue.pop_back(); + TRY_TO(dataTraverseStmtPost(CurrS)); + if (getDerived().shouldTraversePostOrder()) { + TRY_TO(PostVisitStmt(CurrS)); + } + continue; + } - size_t N = LocalQueue.size(); - TRY_TO(dataTraverseNode(CurrS, &LocalQueue)); - // Process new children in the order they were added. - std::reverse(LocalQueue.begin() + N, LocalQueue.end()); + if (getDerived().dataTraverseStmtPre(CurrS)) { + CurrSAndVisited.setInt(true); + size_t N = LocalQueue.size(); + TRY_TO(dataTraverseNode(CurrS, &LocalQueue)); + // Process new children in the order they were added. + std::reverse(LocalQueue.begin() + N, LocalQueue.end()); + } else { + LocalQueue.pop_back(); + } } return true; @@ -809,6 +868,17 @@ bool RecursiveASTVisitor<Derived>::TraverseConstructorInitializer( if (Init->isWritten() || getDerived().shouldVisitImplicitCode()) TRY_TO(TraverseStmt(Init->getInit())); + + if (getDerived().shouldVisitImplicitCode()) + // The braces for this one-line loop are required for MSVC2013. It + // refuses to compile + // for (int i : int_vec) + // do {} while(false); + // without braces on the for loop. + for (VarDecl *VD : Init->getArrayIndices()) { + TRY_TO(TraverseDecl(VD)); + } + return true; } @@ -834,8 +904,11 @@ bool RecursiveASTVisitor<Derived>::TraverseLambdaBody( #define DEF_TRAVERSE_TYPE(TYPE, CODE) \ template <typename Derived> \ bool RecursiveASTVisitor<Derived>::Traverse##TYPE(TYPE *T) { \ - TRY_TO(WalkUpFrom##TYPE(T)); \ + if (!getDerived().shouldTraversePostOrder()) \ + TRY_TO(WalkUpFrom##TYPE(T)); \ { CODE; } \ + if (getDerived().shouldTraversePostOrder()) \ + TRY_TO(WalkUpFrom##TYPE(T)); \ return true; \ } @@ -1238,10 +1311,16 @@ bool RecursiveASTVisitor<Derived>::TraverseDeclContextHelper(DeclContext *DC) { #define DEF_TRAVERSE_DECL(DECL, CODE) \ template <typename Derived> \ bool RecursiveASTVisitor<Derived>::Traverse##DECL(DECL *D) { \ - TRY_TO(WalkUpFrom##DECL(D)); \ + bool ShouldVisitChildren = true; \ + bool ReturnValue = true; \ + if (!getDerived().shouldTraversePostOrder()) \ + TRY_TO(WalkUpFrom##DECL(D)); \ { CODE; } \ - TRY_TO(TraverseDeclContextHelper(dyn_cast<DeclContext>(D))); \ - return true; \ + if (ReturnValue && ShouldVisitChildren) \ + TRY_TO(TraverseDeclContextHelper(dyn_cast<DeclContext>(D))); \ + if (ReturnValue && getDerived().shouldTraversePostOrder()) \ + TRY_TO(WalkUpFrom##DECL(D)); \ + return ReturnValue; \ } DEF_TRAVERSE_DECL(AccessSpecDecl, {}) @@ -1255,18 +1334,12 @@ DEF_TRAVERSE_DECL(BlockDecl, { TRY_TO(TraverseStmt(I.getCopyExpr())); } } - // This return statement makes sure the traversal of nodes in - // decls_begin()/decls_end() (done in the DEF_TRAVERSE_DECL macro) - // is skipped - don't remove it. - return true; + ShouldVisitChildren = false; }) DEF_TRAVERSE_DECL(CapturedDecl, { TRY_TO(TraverseStmt(D->getBody())); - // This return statement makes sure the traversal of nodes in - // decls_begin()/decls_end() (done in the DEF_TRAVERSE_DECL macro) - // is skipped - don't remove it. - return true; + ShouldVisitChildren = false; }) DEF_TRAVERSE_DECL(EmptyDecl, {}) @@ -1325,6 +1398,10 @@ DEF_TRAVERSE_DECL( // D->getAnonymousNamespace(). }) +DEF_TRAVERSE_DECL(PragmaCommentDecl, {}) + +DEF_TRAVERSE_DECL(PragmaDetectMismatchDecl, {}) + DEF_TRAVERSE_DECL(ExternCContextDecl, {}) DEF_TRAVERSE_DECL(NamespaceAliasDecl, { @@ -1332,11 +1409,7 @@ DEF_TRAVERSE_DECL(NamespaceAliasDecl, { // We shouldn't traverse an aliased namespace, since it will be // defined (and, therefore, traversed) somewhere else. - // - // This return statement makes sure the traversal of nodes in - // decls_begin()/decls_end() (done in the DEF_TRAVERSE_DECL macro) - // is skipped - don't remove it. - return true; + ShouldVisitChildren = false; }) DEF_TRAVERSE_DECL(LabelDecl, {// There is no code in a LabelDecl. @@ -1385,14 +1458,13 @@ DEF_TRAVERSE_DECL(ObjCMethodDecl, { if (D->getReturnTypeSourceInfo()) { TRY_TO(TraverseTypeLoc(D->getReturnTypeSourceInfo()->getTypeLoc())); } - for (ObjCMethodDecl::param_iterator I = D->param_begin(), E = D->param_end(); - I != E; ++I) { - TRY_TO(TraverseDecl(*I)); + for (ParmVarDecl *Parameter : D->parameters()) { + TRY_TO(TraverseDecl(Parameter)); } if (D->isThisDeclarationADefinition()) { TRY_TO(TraverseStmt(D->getBody())); } - return true; + ShouldVisitChildren = false; }) DEF_TRAVERSE_DECL(ObjCTypeParamDecl, { @@ -1409,7 +1481,7 @@ DEF_TRAVERSE_DECL(ObjCPropertyDecl, { TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc())); else TRY_TO(TraverseType(D->getType())); - return true; + ShouldVisitChildren = false; }) DEF_TRAVERSE_DECL(UsingDecl, { @@ -1423,12 +1495,24 @@ DEF_TRAVERSE_DECL(UsingDirectiveDecl, { DEF_TRAVERSE_DECL(UsingShadowDecl, {}) +DEF_TRAVERSE_DECL(ConstructorUsingShadowDecl, {}) + DEF_TRAVERSE_DECL(OMPThreadPrivateDecl, { for (auto *I : D->varlists()) { TRY_TO(TraverseStmt(I)); } }) +DEF_TRAVERSE_DECL(OMPDeclareReductionDecl, { + TRY_TO(TraverseStmt(D->getCombiner())); + if (auto *Initializer = D->getInitializer()) + TRY_TO(TraverseStmt(Initializer)); + TRY_TO(TraverseType(D->getType())); + return true; +}) + +DEF_TRAVERSE_DECL(OMPCapturedExprDecl, { TRY_TO(TraverseVarHelper(D)); }) + // A helper method for TemplateDecl's children. template <typename Derived> bool RecursiveASTVisitor<Derived>::TraverseTemplateParameterListHelper( @@ -1778,10 +1862,9 @@ bool RecursiveASTVisitor<Derived>::TraverseFunctionHelper(FunctionDecl *D) { // if the traverser is visiting implicit code. Parameter variable // declarations do not have valid TypeSourceInfo, so to visit them // we need to traverse the declarations explicitly. - for (FunctionDecl::param_const_iterator I = D->param_begin(), - E = D->param_end(); - I != E; ++I) - TRY_TO(TraverseDecl(*I)); + for (ParmVarDecl *Parameter : D->parameters()) { + TRY_TO(TraverseDecl(Parameter)); + } } if (CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(D)) { @@ -1800,19 +1883,22 @@ bool RecursiveASTVisitor<Derived>::TraverseFunctionHelper(FunctionDecl *D) { DEF_TRAVERSE_DECL(FunctionDecl, { // We skip decls_begin/decls_end, which are already covered by // TraverseFunctionHelper(). - return TraverseFunctionHelper(D); + ShouldVisitChildren = false; + ReturnValue = TraverseFunctionHelper(D); }) DEF_TRAVERSE_DECL(CXXMethodDecl, { // We skip decls_begin/decls_end, which are already covered by // TraverseFunctionHelper(). - return TraverseFunctionHelper(D); + ShouldVisitChildren = false; + ReturnValue = TraverseFunctionHelper(D); }) DEF_TRAVERSE_DECL(CXXConstructorDecl, { // We skip decls_begin/decls_end, which are already covered by // TraverseFunctionHelper(). - return TraverseFunctionHelper(D); + ShouldVisitChildren = false; + ReturnValue = TraverseFunctionHelper(D); }) // CXXConversionDecl is the declaration of a type conversion operator. @@ -1820,13 +1906,15 @@ DEF_TRAVERSE_DECL(CXXConstructorDecl, { DEF_TRAVERSE_DECL(CXXConversionDecl, { // We skip decls_begin/decls_end, which are already covered by // TraverseFunctionHelper(). - return TraverseFunctionHelper(D); + ShouldVisitChildren = false; + ReturnValue = TraverseFunctionHelper(D); }) DEF_TRAVERSE_DECL(CXXDestructorDecl, { // We skip decls_begin/decls_end, which are already covered by // TraverseFunctionHelper(). - return TraverseFunctionHelper(D); + ShouldVisitChildren = false; + ReturnValue = TraverseFunctionHelper(D); }) template <typename Derived> @@ -1878,12 +1966,19 @@ DEF_TRAVERSE_DECL(ParmVarDecl, { template <typename Derived> \ bool RecursiveASTVisitor<Derived>::Traverse##STMT( \ STMT *S, DataRecursionQueue *Queue) { \ - TRY_TO(WalkUpFrom##STMT(S)); \ + bool ShouldVisitChildren = true; \ + bool ReturnValue = true; \ + if (!getDerived().shouldTraversePostOrder()) \ + TRY_TO(WalkUpFrom##STMT(S)); \ { CODE; } \ - for (Stmt *SubStmt : S->children()) { \ - TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(SubStmt); \ + if (ShouldVisitChildren) { \ + for (Stmt *SubStmt : S->children()) { \ + TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(SubStmt); \ + } \ } \ - return true; \ + if (!Queue && ReturnValue && getDerived().shouldTraversePostOrder()) \ + TRY_TO(WalkUpFrom##STMT(S)); \ + return ReturnValue; \ } DEF_TRAVERSE_STMT(GCCAsmStmt, { @@ -1920,7 +2015,7 @@ DEF_TRAVERSE_STMT(DeclStmt, { // initializer]'. The decls above already traverse over the // initializers, so we don't have to do it again (which // children() would do). - return true; + ShouldVisitChildren = false; }) // These non-expr stmts (most of them), do not need any action except @@ -1952,7 +2047,7 @@ DEF_TRAVERSE_STMT(CXXForRangeStmt, { TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getRangeInit()); TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getBody()); // Visit everything else only if shouldVisitImplicitCode(). - return true; + ShouldVisitChildren = false; } }) DEF_TRAVERSE_STMT(MSDependentExistsStmt, { @@ -2029,7 +2124,11 @@ template <typename Derived> bool RecursiveASTVisitor<Derived>::TraverseSynOrSemInitListExpr( InitListExpr *S, DataRecursionQueue *Queue) { if (S) { - TRY_TO(WalkUpFromInitListExpr(S)); + // Skip this if we traverse postorder. We will visit it later + // in PostVisitStmt. + if (!getDerived().shouldTraversePostOrder()) + TRY_TO(WalkUpFromInitListExpr(S)); + // All we need are the default actions. FIXME: use a helper function. for (Stmt *SubStmt : S->children()) { TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(SubStmt); @@ -2049,7 +2148,7 @@ DEF_TRAVERSE_STMT(InitListExpr, { S->isSemanticForm() ? S->getSyntacticForm() : S, Queue)); TRY_TO(TraverseSynOrSemInitListExpr( S->isSemanticForm() ? S : S->getSemanticForm(), Queue)); - return true; + ShouldVisitChildren = false; }) // GenericSelectionExpr is a special case because the types and expressions @@ -2062,7 +2161,7 @@ DEF_TRAVERSE_STMT(GenericSelectionExpr, { TRY_TO(TraverseTypeLoc(TS->getTypeLoc())); TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getAssocExpr(i)); } - return true; + ShouldVisitChildren = false; }) // PseudoObjectExpr is a special case because of the weirdness with @@ -2077,7 +2176,7 @@ DEF_TRAVERSE_STMT(PseudoObjectExpr, { sub = OVE->getSourceExpr(); TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(sub); } - return true; + ShouldVisitChildren = false; }) DEF_TRAVERSE_STMT(CXXScalarValueInitExpr, { @@ -2181,7 +2280,8 @@ DEF_TRAVERSE_STMT(LambdaExpr, { TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(NE); } - return TRAVERSE_STMT_BASE(LambdaBody, LambdaExpr, S, Queue); + ReturnValue = TRAVERSE_STMT_BASE(LambdaBody, LambdaExpr, S, Queue); + ShouldVisitChildren = false; }) DEF_TRAVERSE_STMT(CXXUnresolvedConstructExpr, { @@ -2214,6 +2314,7 @@ DEF_TRAVERSE_STMT(CXXDefaultArgExpr, {}) DEF_TRAVERSE_STMT(CXXDefaultInitExpr, {}) DEF_TRAVERSE_STMT(CXXDeleteExpr, {}) DEF_TRAVERSE_STMT(ExprWithCleanups, {}) +DEF_TRAVERSE_STMT(CXXInheritedCtorInitExpr, {}) DEF_TRAVERSE_STMT(CXXNullPtrLiteralExpr, {}) DEF_TRAVERSE_STMT(CXXStdInitializerListExpr, {}) DEF_TRAVERSE_STMT(CXXPseudoDestructorExpr, { @@ -2251,6 +2352,7 @@ DEF_TRAVERSE_STMT(ObjCIndirectCopyRestoreExpr, {}) DEF_TRAVERSE_STMT(ObjCBridgedCastExpr, { TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc())); }) +DEF_TRAVERSE_STMT(ObjCAvailabilityCheckExpr, {}) DEF_TRAVERSE_STMT(ParenExpr, {}) DEF_TRAVERSE_STMT(ParenListExpr, {}) DEF_TRAVERSE_STMT(PredefinedExpr, {}) @@ -2307,25 +2409,25 @@ DEF_TRAVERSE_STMT(AtomicExpr, {}) DEF_TRAVERSE_STMT(CoroutineBodyStmt, { if (!getDerived().shouldVisitImplicitCode()) { TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getBody()); - return true; + ShouldVisitChildren = false; } }) DEF_TRAVERSE_STMT(CoreturnStmt, { if (!getDerived().shouldVisitImplicitCode()) { TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getOperand()); - return true; + ShouldVisitChildren = false; } }) DEF_TRAVERSE_STMT(CoawaitExpr, { if (!getDerived().shouldVisitImplicitCode()) { TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getOperand()); - return true; + ShouldVisitChildren = false; } }) DEF_TRAVERSE_STMT(CoyieldExpr, { if (!getDerived().shouldVisitImplicitCode()) { TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getOperand()); - return true; + ShouldVisitChildren = false; } }) @@ -2433,9 +2535,24 @@ DEF_TRAVERSE_STMT(OMPTargetDirective, DEF_TRAVERSE_STMT(OMPTargetDataDirective, { TRY_TO(TraverseOMPExecutableDirective(S)); }) +DEF_TRAVERSE_STMT(OMPTargetEnterDataDirective, + { TRY_TO(TraverseOMPExecutableDirective(S)); }) + +DEF_TRAVERSE_STMT(OMPTargetExitDataDirective, + { TRY_TO(TraverseOMPExecutableDirective(S)); }) + +DEF_TRAVERSE_STMT(OMPTargetParallelDirective, + { TRY_TO(TraverseOMPExecutableDirective(S)); }) + +DEF_TRAVERSE_STMT(OMPTargetParallelForDirective, + { TRY_TO(TraverseOMPExecutableDirective(S)); }) + DEF_TRAVERSE_STMT(OMPTeamsDirective, { TRY_TO(TraverseOMPExecutableDirective(S)); }) +DEF_TRAVERSE_STMT(OMPTargetUpdateDirective, + { TRY_TO(TraverseOMPExecutableDirective(S)); }) + DEF_TRAVERSE_STMT(OMPTaskLoopDirective, { TRY_TO(TraverseOMPExecutableDirective(S)); }) @@ -2445,6 +2562,18 @@ DEF_TRAVERSE_STMT(OMPTaskLoopSimdDirective, DEF_TRAVERSE_STMT(OMPDistributeDirective, { TRY_TO(TraverseOMPExecutableDirective(S)); }) +DEF_TRAVERSE_STMT(OMPDistributeParallelForDirective, + { TRY_TO(TraverseOMPExecutableDirective(S)); }) + +DEF_TRAVERSE_STMT(OMPDistributeParallelForSimdDirective, + { TRY_TO(TraverseOMPExecutableDirective(S)); }) + +DEF_TRAVERSE_STMT(OMPDistributeSimdDirective, + { TRY_TO(TraverseOMPExecutableDirective(S)); }) + +DEF_TRAVERSE_STMT(OMPTargetParallelForSimdDirective, + { TRY_TO(TraverseOMPExecutableDirective(S)); }) + // OpenMP clauses. template <typename Derived> bool RecursiveASTVisitor<Derived>::TraverseOMPClause(OMPClause *C) { @@ -2457,6 +2586,7 @@ bool RecursiveASTVisitor<Derived>::TraverseOMPClause(OMPClause *C) { break; #include "clang/Basic/OpenMPKinds.def" case OMPC_threadprivate: + case OMPC_uniform: case OMPC_unknown: break; } @@ -2464,6 +2594,21 @@ bool RecursiveASTVisitor<Derived>::TraverseOMPClause(OMPClause *C) { } template <typename Derived> +bool RecursiveASTVisitor<Derived>::VisitOMPClauseWithPreInit( + OMPClauseWithPreInit *Node) { + TRY_TO(TraverseStmt(Node->getPreInitStmt())); + return true; +} + +template <typename Derived> +bool RecursiveASTVisitor<Derived>::VisitOMPClauseWithPostUpdate( + OMPClauseWithPostUpdate *Node) { + TRY_TO(VisitOMPClauseWithPreInit(Node)); + TRY_TO(TraverseStmt(Node->getPostUpdateExpr())); + return true; +} + +template <typename Derived> bool RecursiveASTVisitor<Derived>::VisitOMPIfClause(OMPIfClause *C) { TRY_TO(TraverseStmt(C->getCondition())); return true; @@ -2514,8 +2659,8 @@ bool RecursiveASTVisitor<Derived>::VisitOMPProcBindClause(OMPProcBindClause *) { template <typename Derived> bool RecursiveASTVisitor<Derived>::VisitOMPScheduleClause(OMPScheduleClause *C) { + TRY_TO(VisitOMPClauseWithPreInit(C)); TRY_TO(TraverseStmt(C->getChunkSize())); - TRY_TO(TraverseStmt(C->getHelperChunkSize())); return true; } @@ -2603,6 +2748,7 @@ template <typename Derived> bool RecursiveASTVisitor<Derived>::VisitOMPFirstprivateClause( OMPFirstprivateClause *C) { TRY_TO(VisitOMPClauseList(C)); + TRY_TO(VisitOMPClauseWithPreInit(C)); for (auto *E : C->private_copies()) { TRY_TO(TraverseStmt(E)); } @@ -2616,6 +2762,7 @@ template <typename Derived> bool RecursiveASTVisitor<Derived>::VisitOMPLastprivateClause( OMPLastprivateClause *C) { TRY_TO(VisitOMPClauseList(C)); + TRY_TO(VisitOMPClauseWithPostUpdate(C)); for (auto *E : C->private_copies()) { TRY_TO(TraverseStmt(E)); } @@ -2642,6 +2789,7 @@ bool RecursiveASTVisitor<Derived>::VisitOMPLinearClause(OMPLinearClause *C) { TRY_TO(TraverseStmt(C->getStep())); TRY_TO(TraverseStmt(C->getCalcStep())); TRY_TO(VisitOMPClauseList(C)); + TRY_TO(VisitOMPClauseWithPostUpdate(C)); for (auto *E : C->privates()) { TRY_TO(TraverseStmt(E)); } @@ -2701,6 +2849,7 @@ RecursiveASTVisitor<Derived>::VisitOMPReductionClause(OMPReductionClause *C) { TRY_TO(TraverseNestedNameSpecifierLoc(C->getQualifierLoc())); TRY_TO(TraverseDeclarationNameInfo(C->getNameInfo())); TRY_TO(VisitOMPClauseList(C)); + TRY_TO(VisitOMPClauseWithPostUpdate(C)); for (auto *E : C->privates()) { TRY_TO(TraverseStmt(E)); } @@ -2781,6 +2930,46 @@ bool RecursiveASTVisitor<Derived>::VisitOMPHintClause(OMPHintClause *C) { return true; } +template <typename Derived> +bool RecursiveASTVisitor<Derived>::VisitOMPDistScheduleClause( + OMPDistScheduleClause *C) { + TRY_TO(VisitOMPClauseWithPreInit(C)); + TRY_TO(TraverseStmt(C->getChunkSize())); + return true; +} + +template <typename Derived> +bool +RecursiveASTVisitor<Derived>::VisitOMPDefaultmapClause(OMPDefaultmapClause *C) { + return true; +} + +template <typename Derived> +bool RecursiveASTVisitor<Derived>::VisitOMPToClause(OMPToClause *C) { + TRY_TO(VisitOMPClauseList(C)); + return true; +} + +template <typename Derived> +bool RecursiveASTVisitor<Derived>::VisitOMPFromClause(OMPFromClause *C) { + TRY_TO(VisitOMPClauseList(C)); + return true; +} + +template <typename Derived> +bool RecursiveASTVisitor<Derived>::VisitOMPUseDevicePtrClause( + OMPUseDevicePtrClause *C) { + TRY_TO(VisitOMPClauseList(C)); + return true; +} + +template <typename Derived> +bool RecursiveASTVisitor<Derived>::VisitOMPIsDevicePtrClause( + OMPIsDevicePtrClause *C) { + TRY_TO(VisitOMPClauseList(C)); + return true; +} + // FIXME: look at the following tricky-seeming exprs to see if we // need to recurse on anything. These are ones that have methods // returning decls or qualtypes or nestednamespecifier -- though I'm diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h index d3950e92cf0d7..96847cf88f969 100644 --- a/include/clang/AST/Stmt.h +++ b/include/clang/AST/Stmt.h @@ -93,6 +93,13 @@ protected: unsigned NumStmts : 32 - NumStmtBits; }; + class IfStmtBitfields { + friend class IfStmt; + unsigned : NumStmtBits; + + unsigned IsConstexpr : 1; + }; + class ExprBitfields { friend class Expr; friend class DeclRefExpr; // computeDependence @@ -115,6 +122,7 @@ protected: friend class OverloadExpr; // ctor friend class PseudoObjectExpr; // ctor friend class AtomicExpr; // ctor + friend class OpaqueValueExpr; // ctor unsigned : NumStmtBits; unsigned ValueKind : 2; @@ -191,7 +199,10 @@ protected: unsigned : NumExprBits; - unsigned NumObjects : 32 - NumExprBits; + // When false, it must not have side effects. + unsigned CleanupsHaveSideEffects : 1; + + unsigned NumObjects : 32 - 1 - NumExprBits; }; class PseudoObjectExprBitfields { @@ -244,6 +255,7 @@ protected: union { StmtBitfields StmtBits; CompoundStmtBitfields CompoundStmtBits; + IfStmtBitfields IfStmtBits; ExprBitfields ExprBits; CharacterLiteralBitfields CharacterLiteralBits; FloatingLiteralBitfields FloatingLiteralBits; @@ -867,14 +879,15 @@ public: /// IfStmt - This represents an if/then/else. /// class IfStmt : public Stmt { - enum { VAR, COND, THEN, ELSE, END_EXPR }; + enum { INIT, VAR, COND, THEN, ELSE, END_EXPR }; Stmt* SubExprs[END_EXPR]; SourceLocation IfLoc; SourceLocation ElseLoc; public: - IfStmt(const ASTContext &C, SourceLocation IL, VarDecl *var, Expr *cond, + IfStmt(const ASTContext &C, SourceLocation IL, + bool IsConstexpr, Stmt *init, VarDecl *var, Expr *cond, Stmt *then, SourceLocation EL = SourceLocation(), Stmt *elsev = nullptr); @@ -898,6 +911,9 @@ public: return reinterpret_cast<DeclStmt*>(SubExprs[VAR]); } + Stmt *getInit() { return SubExprs[INIT]; } + const Stmt *getInit() const { return SubExprs[INIT]; } + void setInit(Stmt *S) { SubExprs[INIT] = S; } const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt *>(E); } const Stmt *getThen() const { return SubExprs[THEN]; } @@ -914,6 +930,9 @@ public: SourceLocation getElseLoc() const { return ElseLoc; } void setElseLoc(SourceLocation L) { ElseLoc = L; } + bool isConstexpr() const { return IfStmtBits.IsConstexpr; } + void setConstexpr(bool C) { IfStmtBits.IsConstexpr = C; } + SourceLocation getLocStart() const LLVM_READONLY { return IfLoc; } SourceLocation getLocEnd() const LLVM_READONLY { if (SubExprs[ELSE]) @@ -937,7 +956,7 @@ public: /// class SwitchStmt : public Stmt { SourceLocation SwitchLoc; - enum { VAR, COND, BODY, END_EXPR }; + enum { INIT, VAR, COND, BODY, END_EXPR }; Stmt* SubExprs[END_EXPR]; // This points to a linked list of case and default statements and, if the // SwitchStmt is a switch on an enum value, records whether all the enum @@ -946,7 +965,7 @@ class SwitchStmt : public Stmt { llvm::PointerIntPair<SwitchCase *, 1, bool> FirstCase; public: - SwitchStmt(const ASTContext &C, VarDecl *Var, Expr *cond); + SwitchStmt(const ASTContext &C, Stmt *Init, VarDecl *Var, Expr *cond); /// \brief Build a empty switch statement. explicit SwitchStmt(EmptyShell Empty) : Stmt(SwitchStmtClass, Empty) { } @@ -969,6 +988,9 @@ public: return reinterpret_cast<DeclStmt*>(SubExprs[VAR]); } + Stmt *getInit() { return SubExprs[INIT]; } + const Stmt *getInit() const { return SubExprs[INIT]; } + void setInit(Stmt *S) { SubExprs[INIT] = S; } const Expr *getCond() const { return reinterpret_cast<Expr*>(SubExprs[COND]);} const Stmt *getBody() const { return SubExprs[BODY]; } const SwitchCase *getSwitchCaseList() const { return FirstCase.getPointer(); } diff --git a/include/clang/AST/StmtCXX.h b/include/clang/AST/StmtCXX.h index 1ca73e207e4c5..1d29c228a4b3c 100644 --- a/include/clang/AST/StmtCXX.h +++ b/include/clang/AST/StmtCXX.h @@ -127,7 +127,7 @@ public: /// can be extracted using getLoopVariable and getRangeInit. class CXXForRangeStmt : public Stmt { SourceLocation ForLoc; - enum { RANGE, BEGINEND, COND, INC, LOOPVAR, BODY, END }; + enum { RANGE, BEGINSTMT, ENDSTMT, COND, INC, LOOPVAR, BODY, END }; // SubExprs[RANGE] is an expression or declstmt. // SubExprs[COND] and SubExprs[INC] are expressions. Stmt *SubExprs[END]; @@ -137,7 +137,7 @@ class CXXForRangeStmt : public Stmt { friend class ASTStmtReader; public: - CXXForRangeStmt(DeclStmt *Range, DeclStmt *BeginEnd, + CXXForRangeStmt(DeclStmt *Range, DeclStmt *Begin, DeclStmt *End, Expr *Cond, Expr *Inc, DeclStmt *LoopVar, Stmt *Body, SourceLocation FL, SourceLocation CAL, SourceLocation CL, SourceLocation RPL); @@ -152,9 +152,10 @@ public: DeclStmt *getRangeStmt() { return cast<DeclStmt>(SubExprs[RANGE]); } - DeclStmt *getBeginEndStmt() { - return cast_or_null<DeclStmt>(SubExprs[BEGINEND]); + DeclStmt *getBeginStmt() { + return cast_or_null<DeclStmt>(SubExprs[BEGINSTMT]); } + DeclStmt *getEndStmt() { return cast_or_null<DeclStmt>(SubExprs[ENDSTMT]); } Expr *getCond() { return cast_or_null<Expr>(SubExprs[COND]); } Expr *getInc() { return cast_or_null<Expr>(SubExprs[INC]); } DeclStmt *getLoopVarStmt() { return cast<DeclStmt>(SubExprs[LOOPVAR]); } @@ -163,8 +164,11 @@ public: const DeclStmt *getRangeStmt() const { return cast<DeclStmt>(SubExprs[RANGE]); } - const DeclStmt *getBeginEndStmt() const { - return cast_or_null<DeclStmt>(SubExprs[BEGINEND]); + const DeclStmt *getBeginStmt() const { + return cast_or_null<DeclStmt>(SubExprs[BEGINSTMT]); + } + const DeclStmt *getEndStmt() const { + return cast_or_null<DeclStmt>(SubExprs[ENDSTMT]); } const Expr *getCond() const { return cast_or_null<Expr>(SubExprs[COND]); @@ -179,7 +183,8 @@ public: void setRangeInit(Expr *E) { SubExprs[RANGE] = reinterpret_cast<Stmt*>(E); } void setRangeStmt(Stmt *S) { SubExprs[RANGE] = S; } - void setBeginEndStmt(Stmt *S) { SubExprs[BEGINEND] = S; } + void setBeginStmt(Stmt *S) { SubExprs[BEGINSTMT] = S; } + void setEndStmt(Stmt *S) { SubExprs[ENDSTMT] = S; } void setCond(Expr *E) { SubExprs[COND] = reinterpret_cast<Stmt*>(E); } void setInc(Expr *E) { SubExprs[INC] = reinterpret_cast<Stmt*>(E); } void setLoopVarStmt(Stmt *S) { SubExprs[LOOPVAR] = S; } diff --git a/include/clang/AST/StmtObjC.h b/include/clang/AST/StmtObjC.h index 68fe3ef697bc6..5260b6985bf58 100644 --- a/include/clang/AST/StmtObjC.h +++ b/include/clang/AST/StmtObjC.h @@ -326,7 +326,7 @@ public: Expr *getThrowExpr() { return reinterpret_cast<Expr*>(Throw); } void setThrowExpr(Stmt *S) { Throw = S; } - SourceLocation getThrowLoc() { return AtThrowLoc; } + SourceLocation getThrowLoc() const LLVM_READONLY { return AtThrowLoc; } void setThrowLoc(SourceLocation Loc) { AtThrowLoc = Loc; } SourceLocation getLocStart() const LLVM_READONLY { return AtThrowLoc; } diff --git a/include/clang/AST/StmtOpenMP.h b/include/clang/AST/StmtOpenMP.h index 1ba859c0b8467..1e357263461ed 100644 --- a/include/clang/AST/StmtOpenMP.h +++ b/include/clang/AST/StmtOpenMP.h @@ -70,8 +70,7 @@ protected: : Stmt(SC), Kind(K), StartLoc(std::move(StartLoc)), EndLoc(std::move(EndLoc)), NumClauses(NumClauses), NumChildren(NumChildren), - ClausesOffset(llvm::RoundUpToAlignment(sizeof(T), - llvm::alignOf<OMPClause *>())) {} + ClausesOffset(llvm::alignTo(sizeof(T), llvm::alignOf<OMPClause *>())) {} /// \brief Sets the list of variables for this clause. /// @@ -300,9 +299,11 @@ class OMPLoopDirective : public OMPExecutableDirective { /// This enumeration contains offsets to all the pointers to children /// expressions stored in OMPLoopDirective. /// The first 9 children are nesessary for all the loop directives, and - /// the next 7 are specific to the worksharing ones. + /// the next 10 are specific to the worksharing ones. /// After the fixed children, three arrays of length CollapsedNum are /// allocated: loop counters, their updates and final values. + /// PrevLowerBound and PrevUpperBound are used to communicate blocking + /// information in composite constructs which require loop blocking /// enum { AssociatedStmtOffset = 0, @@ -313,21 +314,25 @@ class OMPLoopDirective : public OMPExecutableDirective { CondOffset = 5, InitOffset = 6, IncOffset = 7, + PreInitsOffset = 8, // The '...End' enumerators do not correspond to child expressions - they // specify the offset to the end (and start of the following counters/ // updates/finals arrays). - DefaultEnd = 8, + DefaultEnd = 9, // The following 7 exprs are used by worksharing loops only. - IsLastIterVariableOffset = 8, - LowerBoundVariableOffset = 9, - UpperBoundVariableOffset = 10, - StrideVariableOffset = 11, - EnsureUpperBoundOffset = 12, - NextLowerBoundOffset = 13, - NextUpperBoundOffset = 14, + IsLastIterVariableOffset = 9, + LowerBoundVariableOffset = 10, + UpperBoundVariableOffset = 11, + StrideVariableOffset = 12, + EnsureUpperBoundOffset = 13, + NextLowerBoundOffset = 14, + NextUpperBoundOffset = 15, + NumIterationsOffset = 16, + PrevLowerBoundVariableOffset = 17, + PrevUpperBoundVariableOffset = 18, // Offset to the end (and start of the following counters/updates/finals // arrays) for worksharing loop directives. - WorksharingEnd = 15, + WorksharingEnd = 19, }; /// \brief Get the counters storage. @@ -423,6 +428,9 @@ protected: } void setInit(Expr *Init) { *std::next(child_begin(), InitOffset) = Init; } void setInc(Expr *Inc) { *std::next(child_begin(), IncOffset) = Inc; } + void setPreInits(Stmt *PreInits) { + *std::next(child_begin(), PreInitsOffset) = PreInits; + } void setIsLastIterVariable(Expr *IL) { assert((isOpenMPWorksharingDirective(getDirectiveKind()) || isOpenMPTaskLoopDirective(getDirectiveKind()) || @@ -472,6 +480,27 @@ protected: "expected worksharing loop directive"); *std::next(child_begin(), NextUpperBoundOffset) = NUB; } + void setNumIterations(Expr *NI) { + assert((isOpenMPWorksharingDirective(getDirectiveKind()) || + isOpenMPTaskLoopDirective(getDirectiveKind()) || + isOpenMPDistributeDirective(getDirectiveKind())) && + "expected worksharing loop directive"); + *std::next(child_begin(), NumIterationsOffset) = NI; + } + void setPrevLowerBoundVariable(Expr *PrevLB) { + assert((isOpenMPWorksharingDirective(getDirectiveKind()) || + isOpenMPTaskLoopDirective(getDirectiveKind()) || + isOpenMPDistributeDirective(getDirectiveKind())) && + "expected worksharing loop directive"); + *std::next(child_begin(), PrevLowerBoundVariableOffset) = PrevLB; + } + void setPrevUpperBoundVariable(Expr *PrevUB) { + assert((isOpenMPWorksharingDirective(getDirectiveKind()) || + isOpenMPTaskLoopDirective(getDirectiveKind()) || + isOpenMPDistributeDirective(getDirectiveKind())) && + "expected worksharing loop directive"); + *std::next(child_begin(), PrevUpperBoundVariableOffset) = PrevUB; + } void setCounters(ArrayRef<Expr *> A); void setPrivateCounters(ArrayRef<Expr *> A); void setInits(ArrayRef<Expr *> A); @@ -512,6 +541,12 @@ public: Expr *NLB; /// \brief Update of UpperBound for statically sheduled 'omp for' loops. Expr *NUB; + /// \brief PreviousLowerBound - local variable passed to runtime in the + /// enclosing schedule or null if that does not apply. + Expr *PrevLB; + /// \brief PreviousUpperBound - local variable passed to runtime in the + /// enclosing schedule or null if that does not apply. + Expr *PrevUB; /// \brief Counters Loop counters. SmallVector<Expr *, 4> Counters; /// \brief PrivateCounters Loop counters. @@ -522,6 +557,8 @@ public: SmallVector<Expr *, 4> Updates; /// \brief Final loop counter values for GodeGen. SmallVector<Expr *, 4> Finals; + /// Init statement for all captured expressions. + Stmt *PreInits; /// \brief Check if all the expressions are built (does not check the /// worksharing ones). @@ -548,6 +585,9 @@ public: EUB = nullptr; NLB = nullptr; NUB = nullptr; + NumIterations = nullptr; + PrevLB = nullptr; + PrevUB = nullptr; Counters.resize(Size); PrivateCounters.resize(Size); Inits.resize(Size); @@ -560,6 +600,7 @@ public: Updates[i] = nullptr; Finals[i] = nullptr; } + PreInits = nullptr; } }; @@ -594,55 +635,90 @@ public: return const_cast<Expr *>( reinterpret_cast<const Expr *>(*std::next(child_begin(), IncOffset))); } + const Stmt *getPreInits() const { + return *std::next(child_begin(), PreInitsOffset); + } + Stmt *getPreInits() { return *std::next(child_begin(), PreInitsOffset); } Expr *getIsLastIterVariable() const { assert((isOpenMPWorksharingDirective(getDirectiveKind()) || - isOpenMPTaskLoopDirective(getDirectiveKind())) && + isOpenMPTaskLoopDirective(getDirectiveKind()) || + isOpenMPDistributeDirective(getDirectiveKind())) && "expected worksharing loop directive"); return const_cast<Expr *>(reinterpret_cast<const Expr *>( *std::next(child_begin(), IsLastIterVariableOffset))); } Expr *getLowerBoundVariable() const { assert((isOpenMPWorksharingDirective(getDirectiveKind()) || - isOpenMPTaskLoopDirective(getDirectiveKind())) && + isOpenMPTaskLoopDirective(getDirectiveKind()) || + isOpenMPDistributeDirective(getDirectiveKind())) && "expected worksharing loop directive"); return const_cast<Expr *>(reinterpret_cast<const Expr *>( *std::next(child_begin(), LowerBoundVariableOffset))); } Expr *getUpperBoundVariable() const { assert((isOpenMPWorksharingDirective(getDirectiveKind()) || - isOpenMPTaskLoopDirective(getDirectiveKind())) && + isOpenMPTaskLoopDirective(getDirectiveKind()) || + isOpenMPDistributeDirective(getDirectiveKind())) && "expected worksharing loop directive"); return const_cast<Expr *>(reinterpret_cast<const Expr *>( *std::next(child_begin(), UpperBoundVariableOffset))); } Expr *getStrideVariable() const { assert((isOpenMPWorksharingDirective(getDirectiveKind()) || - isOpenMPTaskLoopDirective(getDirectiveKind())) && + isOpenMPTaskLoopDirective(getDirectiveKind()) || + isOpenMPDistributeDirective(getDirectiveKind())) && "expected worksharing loop directive"); return const_cast<Expr *>(reinterpret_cast<const Expr *>( *std::next(child_begin(), StrideVariableOffset))); } Expr *getEnsureUpperBound() const { assert((isOpenMPWorksharingDirective(getDirectiveKind()) || - isOpenMPTaskLoopDirective(getDirectiveKind())) && + isOpenMPTaskLoopDirective(getDirectiveKind()) || + isOpenMPDistributeDirective(getDirectiveKind())) && "expected worksharing loop directive"); return const_cast<Expr *>(reinterpret_cast<const Expr *>( *std::next(child_begin(), EnsureUpperBoundOffset))); } Expr *getNextLowerBound() const { assert((isOpenMPWorksharingDirective(getDirectiveKind()) || - isOpenMPTaskLoopDirective(getDirectiveKind())) && + isOpenMPTaskLoopDirective(getDirectiveKind()) || + isOpenMPDistributeDirective(getDirectiveKind())) && "expected worksharing loop directive"); return const_cast<Expr *>(reinterpret_cast<const Expr *>( *std::next(child_begin(), NextLowerBoundOffset))); } Expr *getNextUpperBound() const { assert((isOpenMPWorksharingDirective(getDirectiveKind()) || - isOpenMPTaskLoopDirective(getDirectiveKind())) && + isOpenMPTaskLoopDirective(getDirectiveKind()) || + isOpenMPDistributeDirective(getDirectiveKind())) && "expected worksharing loop directive"); return const_cast<Expr *>(reinterpret_cast<const Expr *>( *std::next(child_begin(), NextUpperBoundOffset))); } + Expr *getNumIterations() const { + assert((isOpenMPWorksharingDirective(getDirectiveKind()) || + isOpenMPTaskLoopDirective(getDirectiveKind()) || + isOpenMPDistributeDirective(getDirectiveKind())) && + "expected worksharing loop directive"); + return const_cast<Expr *>(reinterpret_cast<const Expr *>( + *std::next(child_begin(), NumIterationsOffset))); + } + Expr *getPrevLowerBoundVariable() const { + assert((isOpenMPWorksharingDirective(getDirectiveKind()) || + isOpenMPTaskLoopDirective(getDirectiveKind()) || + isOpenMPDistributeDirective(getDirectiveKind())) && + "expected worksharing loop directive"); + return const_cast<Expr *>(reinterpret_cast<const Expr *>( + *std::next(child_begin(), PrevLowerBoundVariableOffset))); + } + Expr *getPrevUpperBoundVariable() const { + assert((isOpenMPWorksharingDirective(getDirectiveKind()) || + isOpenMPTaskLoopDirective(getDirectiveKind()) || + isOpenMPDistributeDirective(getDirectiveKind())) && + "expected worksharing loop directive"); + return const_cast<Expr *>(reinterpret_cast<const Expr *>( + *std::next(child_begin(), PrevUpperBoundVariableOffset))); + } const Stmt *getBody() const { // This relies on the loop form is already checked by Sema. Stmt *Body = getAssociatedStmt()->IgnoreContainers(true); @@ -692,7 +768,12 @@ public: T->getStmtClass() == OMPParallelForSimdDirectiveClass || T->getStmtClass() == OMPTaskLoopDirectiveClass || T->getStmtClass() == OMPTaskLoopSimdDirectiveClass || - T->getStmtClass() == OMPDistributeDirectiveClass; + T->getStmtClass() == OMPDistributeDirectiveClass || + T->getStmtClass() == OMPTargetParallelForDirectiveClass || + T->getStmtClass() == OMPDistributeParallelForDirectiveClass || + T->getStmtClass() == OMPDistributeParallelForSimdDirectiveClass || + T->getStmtClass() == OMPDistributeSimdDirectiveClass || + T->getStmtClass() == OMPTargetParallelForSimdDirectiveClass; } }; @@ -2039,6 +2120,264 @@ public: } }; +/// \brief This represents '#pragma omp target enter data' directive. +/// +/// \code +/// #pragma omp target enter data device(0) if(a) map(b[:]) +/// \endcode +/// In this example directive '#pragma omp target enter data' has clauses +/// 'device' with the value '0', 'if' with condition 'a' and 'map' with array +/// section 'b[:]'. +/// +class OMPTargetEnterDataDirective : public OMPExecutableDirective { + friend class ASTStmtReader; + /// \brief Build directive with the given start and end location. + /// + /// \param StartLoc Starting location of the directive kind. + /// \param EndLoc Ending Location of the directive. + /// \param NumClauses The number of clauses. + /// + OMPTargetEnterDataDirective(SourceLocation StartLoc, SourceLocation EndLoc, + unsigned NumClauses) + : OMPExecutableDirective(this, OMPTargetEnterDataDirectiveClass, + OMPD_target_enter_data, StartLoc, EndLoc, + NumClauses, /*NumChildren=*/0) {} + + /// \brief Build an empty directive. + /// + /// \param NumClauses Number of clauses. + /// + explicit OMPTargetEnterDataDirective(unsigned NumClauses) + : OMPExecutableDirective(this, OMPTargetEnterDataDirectiveClass, + OMPD_target_enter_data, SourceLocation(), + SourceLocation(), NumClauses, + /*NumChildren=*/0) {} + +public: + /// \brief Creates directive with a list of \a Clauses. + /// + /// \param C AST context. + /// \param StartLoc Starting location of the directive kind. + /// \param EndLoc Ending Location of the directive. + /// \param Clauses List of clauses. + /// + static OMPTargetEnterDataDirective *Create(const ASTContext &C, + SourceLocation StartLoc, + SourceLocation EndLoc, + ArrayRef<OMPClause *> Clauses); + + /// \brief Creates an empty directive with the place for \a N clauses. + /// + /// \param C AST context. + /// \param N The number of clauses. + /// + static OMPTargetEnterDataDirective *CreateEmpty(const ASTContext &C, + unsigned N, EmptyShell); + + static bool classof(const Stmt *T) { + return T->getStmtClass() == OMPTargetEnterDataDirectiveClass; + } +}; + +/// \brief This represents '#pragma omp target exit data' directive. +/// +/// \code +/// #pragma omp target exit data device(0) if(a) map(b[:]) +/// \endcode +/// In this example directive '#pragma omp target exit data' has clauses +/// 'device' with the value '0', 'if' with condition 'a' and 'map' with array +/// section 'b[:]'. +/// +class OMPTargetExitDataDirective : public OMPExecutableDirective { + friend class ASTStmtReader; + /// \brief Build directive with the given start and end location. + /// + /// \param StartLoc Starting location of the directive kind. + /// \param EndLoc Ending Location of the directive. + /// \param NumClauses The number of clauses. + /// + OMPTargetExitDataDirective(SourceLocation StartLoc, SourceLocation EndLoc, + unsigned NumClauses) + : OMPExecutableDirective(this, OMPTargetExitDataDirectiveClass, + OMPD_target_exit_data, StartLoc, EndLoc, + NumClauses, /*NumChildren=*/0) {} + + /// \brief Build an empty directive. + /// + /// \param NumClauses Number of clauses. + /// + explicit OMPTargetExitDataDirective(unsigned NumClauses) + : OMPExecutableDirective(this, OMPTargetExitDataDirectiveClass, + OMPD_target_exit_data, SourceLocation(), + SourceLocation(), NumClauses, + /*NumChildren=*/0) {} + +public: + /// \brief Creates directive with a list of \a Clauses. + /// + /// \param C AST context. + /// \param StartLoc Starting location of the directive kind. + /// \param EndLoc Ending Location of the directive. + /// \param Clauses List of clauses. + /// + static OMPTargetExitDataDirective *Create(const ASTContext &C, + SourceLocation StartLoc, + SourceLocation EndLoc, + ArrayRef<OMPClause *> Clauses); + + /// \brief Creates an empty directive with the place for \a N clauses. + /// + /// \param C AST context. + /// \param N The number of clauses. + /// + static OMPTargetExitDataDirective *CreateEmpty(const ASTContext &C, + unsigned N, EmptyShell); + + static bool classof(const Stmt *T) { + return T->getStmtClass() == OMPTargetExitDataDirectiveClass; + } +}; + +/// \brief This represents '#pragma omp target parallel' directive. +/// +/// \code +/// #pragma omp target parallel if(a) +/// \endcode +/// In this example directive '#pragma omp target parallel' has clause 'if' with +/// condition 'a'. +/// +class OMPTargetParallelDirective : public OMPExecutableDirective { + friend class ASTStmtReader; + /// \brief Build directive with the given start and end location. + /// + /// \param StartLoc Starting location of the directive kind. + /// \param EndLoc Ending location of the directive. + /// \param NumClauses Number of clauses. + /// + OMPTargetParallelDirective(SourceLocation StartLoc, SourceLocation EndLoc, + unsigned NumClauses) + : OMPExecutableDirective(this, OMPTargetParallelDirectiveClass, + OMPD_target_parallel, StartLoc, EndLoc, + NumClauses, /*NumChildren=*/1) {} + + /// \brief Build an empty directive. + /// + /// \param NumClauses Number of clauses. + /// + explicit OMPTargetParallelDirective(unsigned NumClauses) + : OMPExecutableDirective(this, OMPTargetParallelDirectiveClass, + OMPD_target_parallel, SourceLocation(), + SourceLocation(), NumClauses, + /*NumChildren=*/1) {} + +public: + /// \brief Creates directive with a list of \a Clauses. + /// + /// \param C AST context. + /// \param StartLoc Starting location of the directive kind. + /// \param EndLoc Ending Location of the directive. + /// \param Clauses List of clauses. + /// \param AssociatedStmt Statement, associated with the directive. + /// + static OMPTargetParallelDirective * + Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, + ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); + + /// \brief Creates an empty directive with the place for \a NumClauses + /// clauses. + /// + /// \param C AST context. + /// \param NumClauses Number of clauses. + /// + static OMPTargetParallelDirective * + CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell); + + static bool classof(const Stmt *T) { + return T->getStmtClass() == OMPTargetParallelDirectiveClass; + } +}; + +/// \brief This represents '#pragma omp target parallel for' directive. +/// +/// \code +/// #pragma omp target parallel for private(a,b) reduction(+:c,d) +/// \endcode +/// In this example directive '#pragma omp target parallel for' has clauses +/// 'private' with the variables 'a' and 'b' and 'reduction' with operator '+' +/// and variables 'c' and 'd'. +/// +class OMPTargetParallelForDirective : public OMPLoopDirective { + friend class ASTStmtReader; + + /// \brief true if current region has inner cancel directive. + bool HasCancel; + + /// \brief Build directive with the given start and end location. + /// + /// \param StartLoc Starting location of the directive kind. + /// \param EndLoc Ending location of the directive. + /// \param CollapsedNum Number of collapsed nested loops. + /// \param NumClauses Number of clauses. + /// + OMPTargetParallelForDirective(SourceLocation StartLoc, SourceLocation EndLoc, + unsigned CollapsedNum, unsigned NumClauses) + : OMPLoopDirective(this, OMPTargetParallelForDirectiveClass, + OMPD_target_parallel_for, StartLoc, EndLoc, + CollapsedNum, NumClauses), + HasCancel(false) {} + + /// \brief Build an empty directive. + /// + /// \param CollapsedNum Number of collapsed nested loops. + /// \param NumClauses Number of clauses. + /// + explicit OMPTargetParallelForDirective(unsigned CollapsedNum, + unsigned NumClauses) + : OMPLoopDirective(this, OMPTargetParallelForDirectiveClass, + OMPD_target_parallel_for, SourceLocation(), + SourceLocation(), CollapsedNum, NumClauses), + HasCancel(false) {} + + /// \brief Set cancel state. + void setHasCancel(bool Has) { HasCancel = Has; } + +public: + /// \brief Creates directive with a list of \a Clauses. + /// + /// \param C AST context. + /// \param StartLoc Starting location of the directive kind. + /// \param EndLoc Ending Location of the directive. + /// \param CollapsedNum Number of collapsed loops. + /// \param Clauses List of clauses. + /// \param AssociatedStmt Statement, associated with the directive. + /// \param Exprs Helper expressions for CodeGen. + /// \param HasCancel true if current directive has inner cancel directive. + /// + static OMPTargetParallelForDirective * + Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, + unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, + Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel); + + /// \brief Creates an empty directive with the place + /// for \a NumClauses clauses. + /// + /// \param C AST context. + /// \param CollapsedNum Number of collapsed nested loops. + /// \param NumClauses Number of clauses. + /// + static OMPTargetParallelForDirective *CreateEmpty(const ASTContext &C, + unsigned NumClauses, + unsigned CollapsedNum, + EmptyShell); + + /// \brief Return true if current directive has inner cancel directive. + bool hasCancel() const { return HasCancel; } + + static bool classof(const Stmt *T) { + return T->getStmtClass() == OMPTargetParallelForDirectiveClass; + } +}; + /// \brief This represents '#pragma omp teams' directive. /// /// \code @@ -2395,7 +2734,7 @@ public: /// \param Clauses List of clauses. /// \param AssociatedStmt Statement, associated with the directive. /// \param Exprs Helper expressions for CodeGen. - /// + /// static OMPDistributeDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, @@ -2417,6 +2756,340 @@ public: } }; +/// \brief This represents '#pragma omp target update' directive. +/// +/// \code +/// #pragma omp target update to(a) from(b) device(1) +/// \endcode +/// In this example directive '#pragma omp target update' has clause 'to' with +/// argument 'a', clause 'from' with argument 'b' and clause 'device' with +/// argument '1'. +/// +class OMPTargetUpdateDirective : public OMPExecutableDirective { + friend class ASTStmtReader; + /// \brief Build directive with the given start and end location. + /// + /// \param StartLoc Starting location of the directive kind. + /// \param EndLoc Ending Location of the directive. + /// \param NumClauses The number of clauses. + /// + OMPTargetUpdateDirective(SourceLocation StartLoc, SourceLocation EndLoc, + unsigned NumClauses) + : OMPExecutableDirective(this, OMPTargetUpdateDirectiveClass, + OMPD_target_update, StartLoc, EndLoc, NumClauses, + 0) {} + + /// \brief Build an empty directive. + /// + /// \param NumClauses Number of clauses. + /// + explicit OMPTargetUpdateDirective(unsigned NumClauses) + : OMPExecutableDirective(this, OMPTargetUpdateDirectiveClass, + OMPD_target_update, SourceLocation(), + SourceLocation(), NumClauses, 0) {} + +public: + /// \brief Creates directive with a list of \a Clauses. + /// + /// \param C AST context. + /// \param StartLoc Starting location of the directive kind. + /// \param EndLoc Ending Location of the directive. + /// \param Clauses List of clauses. + /// + static OMPTargetUpdateDirective *Create(const ASTContext &C, + SourceLocation StartLoc, + SourceLocation EndLoc, + ArrayRef<OMPClause *> Clauses); + + /// \brief Creates an empty directive with the place for \a NumClauses + /// clauses. + /// + /// \param C AST context. + /// \param NumClauses The number of clauses. + /// + static OMPTargetUpdateDirective *CreateEmpty(const ASTContext &C, + unsigned NumClauses, EmptyShell); + + static bool classof(const Stmt *T) { + return T->getStmtClass() == OMPTargetUpdateDirectiveClass; + } +}; + +/// \brief This represents '#pragma omp distribute parallel for' composite +/// directive. +/// +/// \code +/// #pragma omp distribute parallel for private(a,b) +/// \endcode +/// In this example directive '#pragma omp distribute parallel for' has clause +/// 'private' with the variables 'a' and 'b' +/// +class OMPDistributeParallelForDirective : public OMPLoopDirective { + friend class ASTStmtReader; + + /// \brief Build directive with the given start and end location. + /// + /// \param StartLoc Starting location of the directive kind. + /// \param EndLoc Ending location of the directive. + /// \param CollapsedNum Number of collapsed nested loops. + /// \param NumClauses Number of clauses. + /// + OMPDistributeParallelForDirective(SourceLocation StartLoc, + SourceLocation EndLoc, + unsigned CollapsedNum, unsigned NumClauses) + : OMPLoopDirective(this, OMPDistributeParallelForDirectiveClass, + OMPD_distribute_parallel_for, StartLoc, EndLoc, + CollapsedNum, NumClauses) {} + + /// \brief Build an empty directive. + /// + /// \param CollapsedNum Number of collapsed nested loops. + /// \param NumClauses Number of clauses. + /// + explicit OMPDistributeParallelForDirective(unsigned CollapsedNum, + unsigned NumClauses) + : OMPLoopDirective(this, OMPDistributeParallelForDirectiveClass, + OMPD_distribute_parallel_for, SourceLocation(), + SourceLocation(), CollapsedNum, NumClauses) {} + +public: + /// \brief Creates directive with a list of \a Clauses. + /// + /// \param C AST context. + /// \param StartLoc Starting location of the directive kind. + /// \param EndLoc Ending Location of the directive. + /// \param CollapsedNum Number of collapsed loops. + /// \param Clauses List of clauses. + /// \param AssociatedStmt Statement, associated with the directive. + /// \param Exprs Helper expressions for CodeGen. + /// + static OMPDistributeParallelForDirective * + Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, + unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, + Stmt *AssociatedStmt, const HelperExprs &Exprs); + + /// \brief Creates an empty directive with the place + /// for \a NumClauses clauses. + /// + /// \param C AST context. + /// \param CollapsedNum Number of collapsed nested loops. + /// \param NumClauses Number of clauses. + /// + static OMPDistributeParallelForDirective *CreateEmpty(const ASTContext &C, + unsigned NumClauses, + unsigned CollapsedNum, + EmptyShell); + + static bool classof(const Stmt *T) { + return T->getStmtClass() == OMPDistributeParallelForDirectiveClass; + } +}; + +/// This represents '#pragma omp distribute parallel for simd' composite +/// directive. +/// +/// \code +/// #pragma omp distribute parallel for simd private(x) +/// \endcode +/// In this example directive '#pragma omp distribute parallel for simd' has +/// clause 'private' with the variables 'x' +/// +class OMPDistributeParallelForSimdDirective final : public OMPLoopDirective { + friend class ASTStmtReader; + + /// Build directive with the given start and end location. + /// + /// \param StartLoc Starting location of the directive kind. + /// \param EndLoc Ending location of the directive. + /// \param CollapsedNum Number of collapsed nested loops. + /// \param NumClauses Number of clauses. + /// + OMPDistributeParallelForSimdDirective(SourceLocation StartLoc, + SourceLocation EndLoc, + unsigned CollapsedNum, + unsigned NumClauses) + : OMPLoopDirective(this, OMPDistributeParallelForSimdDirectiveClass, + OMPD_distribute_parallel_for_simd, StartLoc, + EndLoc, CollapsedNum, NumClauses) {} + + /// Build an empty directive. + /// + /// \param CollapsedNum Number of collapsed nested loops. + /// \param NumClauses Number of clauses. + /// + explicit OMPDistributeParallelForSimdDirective(unsigned CollapsedNum, + unsigned NumClauses) + : OMPLoopDirective(this, OMPDistributeParallelForSimdDirectiveClass, + OMPD_distribute_parallel_for_simd, + SourceLocation(), SourceLocation(), CollapsedNum, + NumClauses) {} + +public: + /// Creates directive with a list of \a Clauses. + /// + /// \param C AST context. + /// \param StartLoc Starting location of the directive kind. + /// \param EndLoc Ending Location of the directive. + /// \param CollapsedNum Number of collapsed loops. + /// \param Clauses List of clauses. + /// \param AssociatedStmt Statement, associated with the directive. + /// \param Exprs Helper expressions for CodeGen. + /// + static OMPDistributeParallelForSimdDirective *Create( + const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, + unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, + Stmt *AssociatedStmt, const HelperExprs &Exprs); + + /// Creates an empty directive with the place for \a NumClauses clauses. + /// + /// \param C AST context. + /// \param CollapsedNum Number of collapsed nested loops. + /// \param NumClauses Number of clauses. + /// + static OMPDistributeParallelForSimdDirective *CreateEmpty( + const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, + EmptyShell); + + static bool classof(const Stmt *T) { + return T->getStmtClass() == OMPDistributeParallelForSimdDirectiveClass; + } +}; + +/// This represents '#pragma omp distribute simd' composite directive. +/// +/// \code +/// #pragma omp distribute simd private(x) +/// \endcode +/// In this example directive '#pragma omp distribute simd' has clause +/// 'private' with the variables 'x' +/// +class OMPDistributeSimdDirective final : public OMPLoopDirective { + friend class ASTStmtReader; + + /// Build directive with the given start and end location. + /// + /// \param StartLoc Starting location of the directive kind. + /// \param EndLoc Ending location of the directive. + /// \param CollapsedNum Number of collapsed nested loops. + /// \param NumClauses Number of clauses. + /// + OMPDistributeSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc, + unsigned CollapsedNum, unsigned NumClauses) + : OMPLoopDirective(this, OMPDistributeSimdDirectiveClass, + OMPD_distribute_simd, StartLoc, EndLoc, CollapsedNum, + NumClauses) {} + + /// Build an empty directive. + /// + /// \param CollapsedNum Number of collapsed nested loops. + /// \param NumClauses Number of clauses. + /// + explicit OMPDistributeSimdDirective(unsigned CollapsedNum, + unsigned NumClauses) + : OMPLoopDirective(this, OMPDistributeSimdDirectiveClass, + OMPD_distribute_simd, SourceLocation(), + SourceLocation(), CollapsedNum, NumClauses) {} + +public: + /// Creates directive with a list of \a Clauses. + /// + /// \param C AST context. + /// \param StartLoc Starting location of the directive kind. + /// \param EndLoc Ending Location of the directive. + /// \param CollapsedNum Number of collapsed loops. + /// \param Clauses List of clauses. + /// \param AssociatedStmt Statement, associated with the directive. + /// \param Exprs Helper expressions for CodeGen. + /// + static OMPDistributeSimdDirective * + Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, + unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, + Stmt *AssociatedStmt, const HelperExprs &Exprs); + + /// Creates an empty directive with the place for \a NumClauses clauses. + /// + /// \param C AST context. + /// \param CollapsedNum Number of collapsed nested loops. + /// \param NumClauses Number of clauses. + /// + static OMPDistributeSimdDirective *CreateEmpty(const ASTContext &C, + unsigned NumClauses, + unsigned CollapsedNum, + EmptyShell); + + static bool classof(const Stmt *T) { + return T->getStmtClass() == OMPDistributeSimdDirectiveClass; + } +}; + +/// This represents '#pragma omp target parallel for simd' directive. +/// +/// \code +/// #pragma omp target parallel for simd private(a) map(b) safelen(c) +/// \endcode +/// In this example directive '#pragma omp target parallel for simd' has clauses +/// 'private' with the variable 'a', 'map' with the variable 'b' and 'safelen' +/// with the variable 'c'. +/// +class OMPTargetParallelForSimdDirective final : public OMPLoopDirective { + friend class ASTStmtReader; + + /// Build directive with the given start and end location. + /// + /// \param StartLoc Starting location of the directive kind. + /// \param EndLoc Ending location of the directive. + /// \param CollapsedNum Number of collapsed nested loops. + /// \param NumClauses Number of clauses. + /// + OMPTargetParallelForSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc, + unsigned CollapsedNum, unsigned NumClauses) + : OMPLoopDirective(this, OMPTargetParallelForSimdDirectiveClass, + OMPD_target_parallel_for_simd, StartLoc, EndLoc, + CollapsedNum, NumClauses) {} + + /// Build an empty directive. + /// + /// \param CollapsedNum Number of collapsed nested loops. + /// \param NumClauses Number of clauses. + /// + explicit OMPTargetParallelForSimdDirective(unsigned CollapsedNum, + unsigned NumClauses) + : OMPLoopDirective(this, OMPTargetParallelForSimdDirectiveClass, + OMPD_target_parallel_for_simd, SourceLocation(), + SourceLocation(), CollapsedNum, NumClauses) {} + +public: + /// Creates directive with a list of \a Clauses. + /// + /// \param C AST context. + /// \param StartLoc Starting location of the directive kind. + /// \param EndLoc Ending Location of the directive. + /// \param CollapsedNum Number of collapsed loops. + /// \param Clauses List of clauses. + /// \param AssociatedStmt Statement, associated with the directive. + /// \param Exprs Helper expressions for CodeGen. + /// + static OMPTargetParallelForSimdDirective * + Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, + unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, + Stmt *AssociatedStmt, const HelperExprs &Exprs); + + /// Creates an empty directive with the place for \a NumClauses clauses. + /// + /// \param C AST context. + /// \param CollapsedNum Number of collapsed nested loops. + /// \param NumClauses Number of clauses. + /// + static OMPTargetParallelForSimdDirective *CreateEmpty(const ASTContext &C, + unsigned NumClauses, + unsigned CollapsedNum, + EmptyShell); + + static bool classof(const Stmt *T) { + return T->getStmtClass() == OMPTargetParallelForSimdDirectiveClass; + } +}; + } // end namespace clang #endif diff --git a/include/clang/AST/TemplateBase.h b/include/clang/AST/TemplateBase.h index f87171a81d1d2..b9c2c08943e95 100644 --- a/include/clang/AST/TemplateBase.h +++ b/include/clang/AST/TemplateBase.h @@ -354,6 +354,12 @@ public: /// \brief Print this template argument to the given output stream. void print(const PrintingPolicy &Policy, raw_ostream &Out) const; + /// \brief Debugging aid that dumps the template argument. + void dump(raw_ostream &Out) const; + + /// \brief Debugging aid that dumps the template argument to standard error. + void dump() const; + /// \brief Used to insert TemplateArguments into FoldingSets. void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) const; }; diff --git a/include/clang/AST/TemplateName.h b/include/clang/AST/TemplateName.h index 3e10d2fc4ad2a..bf4d008ee807a 100644 --- a/include/clang/AST/TemplateName.h +++ b/include/clang/AST/TemplateName.h @@ -14,6 +14,7 @@ #ifndef LLVM_CLANG_AST_TEMPLATENAME_H #define LLVM_CLANG_AST_TEMPLATENAME_H +#include "clang/AST/NestedNameSpecifier.h" #include "clang/Basic/LLVM.h" #include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/PointerUnion.h" diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h index d63b2c43d5538..1067c086c764a 100644 --- a/include/clang/AST/Type.h +++ b/include/clang/AST/Type.h @@ -111,6 +111,7 @@ namespace clang { /// The collection of all-type qualifiers we support. /// Clang supports five independent qualifiers: /// * C99: const, volatile, and restrict +/// * MS: __unaligned /// * Embedded C (TR18037): address spaces /// * Objective C: the GC attributes (none, weak, or strong) class Qualifiers { @@ -152,8 +153,8 @@ public: enum { /// The maximum supported address space number. - /// 24 bits should be enough for anyone. - MaxAddressSpace = 0xffffffu, + /// 23 bits should be enough for anyone. + MaxAddressSpace = 0x7fffffu, /// The width of the "fast" qualifier mask. FastWidth = 3, @@ -214,6 +215,12 @@ public: return Qs; } + static Qualifiers fromCVRUMask(unsigned CVRU) { + Qualifiers Qs; + Qs.addCVRUQualifiers(CVRU); + return Qs; + } + // Deserialize qualifiers from an opaque representation. static Qualifiers fromOpaqueValue(unsigned opaque) { Qualifiers Qs; @@ -264,6 +271,17 @@ public: assert(!(mask & ~CVRMask) && "bitmask contains non-CVR bits"); Mask |= mask; } + void addCVRUQualifiers(unsigned mask) { + assert(!(mask & ~CVRMask & ~UMask) && "bitmask contains non-CVRU bits"); + Mask |= mask; + } + + bool hasUnaligned() const { return Mask & UMask; } + void setUnaligned(bool flag) { + Mask = (Mask & ~UMask) | (flag ? UMask : 0); + } + void removeUnaligned() { Mask &= ~UMask; } + void addUnaligned() { Mask |= UMask; } bool hasObjCGCAttr() const { return Mask & GCAttrMask; } GC getObjCGCAttr() const { return GC((Mask & GCAttrMask) >> GCAttrShift); } @@ -433,7 +451,9 @@ public: // ObjC lifetime qualifiers must match exactly. getObjCLifetime() == other.getObjCLifetime() && // CVR qualifiers may subset. - (((Mask & CVRMask) | (other.Mask & CVRMask)) == (Mask & CVRMask)); + (((Mask & CVRMask) | (other.Mask & CVRMask)) == (Mask & CVRMask)) && + // U qualifier may superset. + (!other.hasUnaligned() || hasUnaligned()); } /// \brief Determines if these qualifiers compatibly include another set of @@ -501,16 +521,19 @@ public: private: - // bits: |0 1 2|3 .. 4|5 .. 7|8 ... 31| - // |C R V|GCAttr|Lifetime|AddressSpace| + // bits: |0 1 2|3|4 .. 5|6 .. 8|9 ... 31| + // |C R V|U|GCAttr|Lifetime|AddressSpace| uint32_t Mask; - static const uint32_t GCAttrMask = 0x18; - static const uint32_t GCAttrShift = 3; - static const uint32_t LifetimeMask = 0xE0; - static const uint32_t LifetimeShift = 5; - static const uint32_t AddressSpaceMask = ~(CVRMask|GCAttrMask|LifetimeMask); - static const uint32_t AddressSpaceShift = 8; + static const uint32_t UMask = 0x8; + static const uint32_t UShift = 3; + static const uint32_t GCAttrMask = 0x30; + static const uint32_t GCAttrShift = 4; + static const uint32_t LifetimeMask = 0x1C0; + static const uint32_t LifetimeShift = 6; + static const uint32_t AddressSpaceMask = + ~(CVRMask | UMask | GCAttrMask | LifetimeMask); + static const uint32_t AddressSpaceShift = 9; }; /// A std::pair-like structure for storing a qualified type split @@ -709,27 +732,27 @@ public: /// applied to this type. unsigned getCVRQualifiers() const; - bool isConstant(ASTContext& Ctx) const { + bool isConstant(const ASTContext& Ctx) const { return QualType::isConstant(*this, Ctx); } /// \brief Determine whether this is a Plain Old Data (POD) type (C++ 3.9p10). - bool isPODType(ASTContext &Context) const; + bool isPODType(const ASTContext &Context) const; /// Return true if this is a POD type according to the rules of the C++98 /// standard, regardless of the current compilation's language. - bool isCXX98PODType(ASTContext &Context) const; + bool isCXX98PODType(const ASTContext &Context) const; /// Return true if this is a POD type according to the more relaxed rules /// of the C++11 standard, regardless of the current compilation's language. /// (C++0x [basic.types]p9) - bool isCXX11PODType(ASTContext &Context) const; + bool isCXX11PODType(const ASTContext &Context) const; /// Return true if this is a trivial type per (C++0x [basic.types]p9) - bool isTrivialType(ASTContext &Context) const; + bool isTrivialType(const ASTContext &Context) const; /// Return true if this is a trivially copyable type (C++0x [basic.types]p9) - bool isTriviallyCopyableType(ASTContext &Context) const; + bool isTriviallyCopyableType(const ASTContext &Context) const; // Don't promise in the API that anything besides 'const' can be // easily added. @@ -909,16 +932,19 @@ public: std::string getAsString(const PrintingPolicy &Policy) const; void print(raw_ostream &OS, const PrintingPolicy &Policy, - const Twine &PlaceHolder = Twine()) const { - print(split(), OS, Policy, PlaceHolder); + const Twine &PlaceHolder = Twine(), + unsigned Indentation = 0) const { + print(split(), OS, Policy, PlaceHolder, Indentation); } static void print(SplitQualType split, raw_ostream &OS, - const PrintingPolicy &policy, const Twine &PlaceHolder) { - return print(split.Ty, split.Quals, OS, policy, PlaceHolder); + const PrintingPolicy &policy, const Twine &PlaceHolder, + unsigned Indentation = 0) { + return print(split.Ty, split.Quals, OS, policy, PlaceHolder, Indentation); } static void print(const Type *ty, Qualifiers qs, raw_ostream &OS, const PrintingPolicy &policy, - const Twine &PlaceHolder); + const Twine &PlaceHolder, + unsigned Indentation = 0); void getAsStringInternal(std::string &Str, const PrintingPolicy &Policy) const { @@ -936,21 +962,24 @@ public: const QualType &T; const PrintingPolicy &Policy; const Twine &PlaceHolder; + unsigned Indentation; public: StreamedQualTypeHelper(const QualType &T, const PrintingPolicy &Policy, - const Twine &PlaceHolder) - : T(T), Policy(Policy), PlaceHolder(PlaceHolder) { } + const Twine &PlaceHolder, unsigned Indentation) + : T(T), Policy(Policy), PlaceHolder(PlaceHolder), + Indentation(Indentation) { } friend raw_ostream &operator<<(raw_ostream &OS, const StreamedQualTypeHelper &SQT) { - SQT.T.print(OS, SQT.Policy, SQT.PlaceHolder); + SQT.T.print(OS, SQT.Policy, SQT.PlaceHolder, SQT.Indentation); return OS; } }; StreamedQualTypeHelper stream(const PrintingPolicy &Policy, - const Twine &PlaceHolder = Twine()) const { - return StreamedQualTypeHelper(*this, Policy, PlaceHolder); + const Twine &PlaceHolder = Twine(), + unsigned Indentation = 0) const { + return StreamedQualTypeHelper(*this, Policy, PlaceHolder, Indentation); } void dump(const char *s) const; @@ -1061,11 +1090,14 @@ public: /// Strip Objective-C "__kindof" types from the given type. QualType stripObjCKindOfType(const ASTContext &ctx) const; + /// Remove all qualifiers including _Atomic. + QualType getAtomicUnqualifiedType() const; + private: // These methods are implemented in a separate translation unit; // "static"-ize them to avoid creating temporary QualTypes in the // caller. - static bool isConstant(QualType T, ASTContext& Ctx); + static bool isConstant(QualType T, const ASTContext& Ctx); static QualType getDesugaredType(QualType T, const ASTContext &Context); static SplitQualType getSplitDesugaredType(QualType T); static SplitQualType getSplitUnqualifiedTypeImpl(QualType type); @@ -1353,7 +1385,7 @@ protected: /// /// C++ 8.3.5p4: The return type, the parameter type list and the /// cv-qualifier-seq, [...], are part of the function type. - unsigned TypeQuals : 3; + unsigned TypeQuals : 4; /// \brief The ref-qualifier associated with a \c FunctionProtoType. /// @@ -1600,7 +1632,7 @@ public: bool isChar16Type() const; bool isChar32Type() const; bool isAnyCharacterType() const; - bool isIntegralType(ASTContext &Ctx) const; + bool isIntegralType(const ASTContext &Ctx) const; /// Determine whether this type is an integral or enumeration type. bool isIntegralOrEnumerationType() const; @@ -1699,18 +1731,9 @@ public: bool isNullPtrType() const; // C++0x nullptr_t bool isAtomicType() const; // C11 _Atomic() - bool isImage1dT() const; // OpenCL image1d_t - bool isImage1dArrayT() const; // OpenCL image1d_array_t - bool isImage1dBufferT() const; // OpenCL image1d_buffer_t - bool isImage2dT() const; // OpenCL image2d_t - bool isImage2dArrayT() const; // OpenCL image2d_array_t - bool isImage2dDepthT() const; // OpenCL image_2d_depth_t - bool isImage2dArrayDepthT() const; // OpenCL image_2d_array_depth_t - bool isImage2dMSAAT() const; // OpenCL image_2d_msaa_t - bool isImage2dArrayMSAAT() const; // OpenCL image_2d_array_msaa_t - bool isImage2dMSAATDepth() const; // OpenCL image_2d_msaa_depth_t - bool isImage2dArrayMSAATDepth() const; // OpenCL image_2d_array_msaa_depth_t - bool isImage3dT() const; // OpenCL image3d_t +#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ + bool is##Id##Type() const; +#include "clang/Basic/OpenCLImageTypes.def" bool isImageType() const; // Any OpenCL image type @@ -1875,6 +1898,11 @@ public: /// This should never be used when type qualifiers are meaningful. const Type *getArrayElementTypeNoTypeQual() const; + /// If this is a pointer type, return the pointee type. + /// If this is an array type, return the array element type. + /// This should never be used when type qualifiers are meaningful. + const Type *getPointeeOrArrayElementType() const; + /// If this is a pointer, ObjC object pointer, or block /// pointer, this returns the respective pointee. QualType getPointeeType() const; @@ -2011,6 +2039,10 @@ template <> inline const Class##Type *Type::castAs() const { \ class BuiltinType : public Type { public: enum Kind { +// OpenCL image types +#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) Id, +#include "clang/Basic/OpenCLImageTypes.def" +// All other builtin types #define BUILTIN_TYPE(Id, SingletonId) Id, #define LAST_BUILTIN_TYPE(Id) LastKind = Id #include "clang/AST/BuiltinTypes.def" @@ -2050,7 +2082,7 @@ public: } bool isFloatingPoint() const { - return getKind() >= Half && getKind() <= LongDouble; + return getKind() >= Half && getKind() <= Float128; } /// Determines whether the given kind corresponds to a placeholder type. @@ -2499,13 +2531,13 @@ public: /// \brief Determine the number of bits required to address a member of // an array with the given element type and number of elements. - static unsigned getNumAddressingBits(ASTContext &Context, + static unsigned getNumAddressingBits(const ASTContext &Context, QualType ElementType, const llvm::APInt &NumElements); /// \brief Determine the maximum number of active bits that an array's size /// can require, which limits the maximum size of the array. - static unsigned getMaxSizeBits(ASTContext &Context); + static unsigned getMaxSizeBits(const ASTContext &Context); void Profile(llvm::FoldingSetNodeID &ID) { Profile(ID, getElementType(), getSize(), @@ -2990,7 +3022,7 @@ public: /// \brief Determine the type of an expression that calls a function of /// this type. - QualType getCallResultType(ASTContext &Context) const { + QualType getCallResultType(const ASTContext &Context) const { return getReturnType().getNonLValueExprType(Context); } @@ -3040,6 +3072,74 @@ public: /// type. class FunctionProtoType : public FunctionType, public llvm::FoldingSetNode { public: + /// Interesting information about a specific parameter that can't simply + /// be reflected in parameter's type. + /// + /// It makes sense to model language features this way when there's some + /// sort of parameter-specific override (such as an attribute) that + /// affects how the function is called. For example, the ARC ns_consumed + /// attribute changes whether a parameter is passed at +0 (the default) + /// or +1 (ns_consumed). This must be reflected in the function type, + /// but isn't really a change to the parameter type. + /// + /// One serious disadvantage of modelling language features this way is + /// that they generally do not work with language features that attempt + /// to destructure types. For example, template argument deduction will + /// not be able to match a parameter declared as + /// T (*)(U) + /// against an argument of type + /// void (*)(__attribute__((ns_consumed)) id) + /// because the substitution of T=void, U=id into the former will + /// not produce the latter. + class ExtParameterInfo { + enum { + ABIMask = 0x0F, + IsConsumed = 0x10 + }; + unsigned char Data; + public: + ExtParameterInfo() : Data(0) {} + + /// Return the ABI treatment of this parameter. + ParameterABI getABI() const { + return ParameterABI(Data & ABIMask); + } + ExtParameterInfo withABI(ParameterABI kind) const { + ExtParameterInfo copy = *this; + copy.Data = (copy.Data & ~ABIMask) | unsigned(kind); + return copy; + } + + /// Is this parameter considered "consumed" by Objective-C ARC? + /// Consumed parameters must have retainable object type. + bool isConsumed() const { + return (Data & IsConsumed); + } + ExtParameterInfo withIsConsumed(bool consumed) const { + ExtParameterInfo copy = *this; + if (consumed) { + copy.Data |= IsConsumed; + } else { + copy.Data &= ~IsConsumed; + } + return copy; + } + + unsigned char getOpaqueValue() const { return Data; } + static ExtParameterInfo getFromOpaqueValue(unsigned char data) { + ExtParameterInfo result; + result.Data = data; + return result; + } + + friend bool operator==(ExtParameterInfo lhs, ExtParameterInfo rhs) { + return lhs.Data == rhs.Data; + } + friend bool operator!=(ExtParameterInfo lhs, ExtParameterInfo rhs) { + return lhs.Data != rhs.Data; + } + }; + struct ExceptionSpecInfo { ExceptionSpecInfo() : Type(EST_None), NoexceptExpr(nullptr), @@ -3067,11 +3167,11 @@ public: struct ExtProtoInfo { ExtProtoInfo() : Variadic(false), HasTrailingReturn(false), TypeQuals(0), - RefQualifier(RQ_None), ConsumedParameters(nullptr) {} + RefQualifier(RQ_None), ExtParameterInfos(nullptr) {} ExtProtoInfo(CallingConv CC) : ExtInfo(CC), Variadic(false), HasTrailingReturn(false), TypeQuals(0), - RefQualifier(RQ_None), ConsumedParameters(nullptr) {} + RefQualifier(RQ_None), ExtParameterInfos(nullptr) {} ExtProtoInfo withExceptionSpec(const ExceptionSpecInfo &O) { ExtProtoInfo Result(*this); @@ -3085,7 +3185,7 @@ public: unsigned char TypeQuals; RefQualifierKind RefQualifier; ExceptionSpecInfo ExceptionSpec; - const bool *ConsumedParameters; + const ExtParameterInfo *ExtParameterInfos; }; private: @@ -3112,8 +3212,8 @@ private: /// The type of exception specification this function has. unsigned ExceptionSpecType : 4; - /// Whether this function has any consumed parameters. - unsigned HasAnyConsumedParams : 1; + /// Whether this function has extended parameter information. + unsigned HasExtParameterInfos : 1; /// Whether the function is variadic. unsigned Variadic : 1; @@ -3135,25 +3235,36 @@ private: // instantiate this function type's exception specification, and the function // from which it should be instantiated. - // ConsumedParameters - A variable size array, following Exceptions - // and of length NumParams, holding flags indicating which parameters - // are consumed. This only appears if HasAnyConsumedParams is true. + // ExtParameterInfos - A variable size array, following the exception + // specification and of length NumParams, holding an ExtParameterInfo + // for each of the parameters. This only appears if HasExtParameterInfos + // is true. friend class ASTContext; // ASTContext creates these. - const bool *getConsumedParamsBuffer() const { - assert(hasAnyConsumedParams()); + const ExtParameterInfo *getExtParameterInfosBuffer() const { + assert(hasExtParameterInfos()); - // Find the end of the exceptions. - Expr *const *eh_end = reinterpret_cast<Expr *const *>(exception_end()); - if (getExceptionSpecType() == EST_ComputedNoexcept) - eh_end += 1; // NoexceptExpr - // The memory layout of these types isn't handled here, so - // hopefully this is never called for them? - assert(getExceptionSpecType() != EST_Uninstantiated && - getExceptionSpecType() != EST_Unevaluated); + // Find the end of the exception specification. + const char *ptr = reinterpret_cast<const char *>(exception_begin()); + ptr += getExceptionSpecSize(); - return reinterpret_cast<const bool*>(eh_end); + return reinterpret_cast<const ExtParameterInfo *>(ptr); + } + + size_t getExceptionSpecSize() const { + switch (getExceptionSpecType()) { + case EST_None: return 0; + case EST_DynamicNone: return 0; + case EST_MSAny: return 0; + case EST_BasicNoexcept: return 0; + case EST_Unparsed: return 0; + case EST_Dynamic: return getNumExceptions() * sizeof(QualType); + case EST_ComputedNoexcept: return sizeof(Expr*); + case EST_Uninstantiated: return 2 * sizeof(FunctionDecl*); + case EST_Unevaluated: return sizeof(FunctionDecl*); + } + llvm_unreachable("bad exception specification kind"); } public: @@ -3184,8 +3295,8 @@ public: } else if (EPI.ExceptionSpec.Type == EST_Unevaluated) { EPI.ExceptionSpec.SourceDecl = getExceptionSpecDecl(); } - if (hasAnyConsumedParams()) - EPI.ConsumedParameters = getConsumedParamsBuffer(); + if (hasExtParameterInfos()) + EPI.ExtParameterInfos = getExtParameterInfosBuffer(); return EPI; } @@ -3300,11 +3411,41 @@ public: return exception_begin() + NumExceptions; } - bool hasAnyConsumedParams() const { return HasAnyConsumedParams; } + /// Is there any interesting extra information for any of the parameters + /// of this function type? + bool hasExtParameterInfos() const { return HasExtParameterInfos; } + ArrayRef<ExtParameterInfo> getExtParameterInfos() const { + assert(hasExtParameterInfos()); + return ArrayRef<ExtParameterInfo>(getExtParameterInfosBuffer(), + getNumParams()); + } + /// Return a pointer to the beginning of the array of extra parameter + /// information, if present, or else null if none of the parameters + /// carry it. This is equivalent to getExtProtoInfo().ExtParameterInfos. + const ExtParameterInfo *getExtParameterInfosOrNull() const { + if (!hasExtParameterInfos()) + return nullptr; + return getExtParameterInfosBuffer(); + } + + ExtParameterInfo getExtParameterInfo(unsigned I) const { + assert(I < getNumParams() && "parameter index out of range"); + if (hasExtParameterInfos()) + return getExtParameterInfosBuffer()[I]; + return ExtParameterInfo(); + } + + ParameterABI getParameterABI(unsigned I) const { + assert(I < getNumParams() && "parameter index out of range"); + if (hasExtParameterInfos()) + return getExtParameterInfosBuffer()[I].getABI(); + return ParameterABI::Ordinary; + } + bool isParamConsumed(unsigned I) const { assert(I < getNumParams() && "parameter index out of range"); - if (hasAnyConsumedParams()) - return getConsumedParamsBuffer()[I]; + if (hasExtParameterInfos()) + return getExtParameterInfosBuffer()[I].isConsumed(); return false; } @@ -3518,6 +3659,28 @@ public: } }; +/// \brief Internal representation of canonical, dependent +/// __underlying_type(type) types. +/// +/// This class is used internally by the ASTContext to manage +/// canonical, dependent types, only. Clients will only see instances +/// of this class via UnaryTransformType nodes. +class DependentUnaryTransformType : public UnaryTransformType, + public llvm::FoldingSetNode { +public: + DependentUnaryTransformType(const ASTContext &C, QualType BaseType, + UTTKind UKind); + void Profile(llvm::FoldingSetNodeID &ID) { + Profile(ID, getBaseType(), getUTTKind()); + } + + static void Profile(llvm::FoldingSetNodeID &ID, QualType BaseType, + UTTKind UKind) { + ID.AddPointer(BaseType.getAsOpaquePtr()); + ID.AddInteger((unsigned)UKind); + } +}; + class TagType : public Type { /// Stores the TagDecl associated with this type. The decl may point to any /// TagDecl that declares the entity. @@ -3626,10 +3789,13 @@ public: attr_stdcall, attr_thiscall, attr_pascal, + attr_swiftcall, attr_vectorcall, attr_inteloclbicc, attr_ms_abi, attr_sysv_abi, + attr_preserve_most, + attr_preserve_all, attr_ptr32, attr_ptr64, attr_sptr, @@ -4002,19 +4168,18 @@ class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) TemplateSpecializationType unsigned NumArgs : 31; /// Whether this template specialization type is a substituted type alias. - bool TypeAlias : 1; + unsigned TypeAlias : 1; TemplateSpecializationType(TemplateName T, - const TemplateArgument *Args, - unsigned NumArgs, QualType Canon, + ArrayRef<TemplateArgument> Args, + QualType Canon, QualType Aliased); friend class ASTContext; // ASTContext creates these public: /// Determine whether any of the given template arguments are dependent. - static bool anyDependentTemplateArguments(const TemplateArgumentLoc *Args, - unsigned NumArgs, + static bool anyDependentTemplateArguments(ArrayRef<TemplateArgumentLoc> Args, bool &InstantiationDependent); static bool anyDependentTemplateArguments(const TemplateArgumentListInfo &, @@ -4023,14 +4188,12 @@ public: /// \brief Print a template argument list, including the '<' and '>' /// enclosing the template arguments. static void PrintTemplateArgumentList(raw_ostream &OS, - const TemplateArgument *Args, - unsigned NumArgs, + ArrayRef<TemplateArgument> Args, const PrintingPolicy &Policy, bool SkipBrackets = false); static void PrintTemplateArgumentList(raw_ostream &OS, - const TemplateArgumentLoc *Args, - unsigned NumArgs, + ArrayRef<TemplateArgumentLoc> Args, const PrintingPolicy &Policy); static void PrintTemplateArgumentList(raw_ostream &OS, @@ -4087,20 +4250,23 @@ public: /// \pre \c isArgType(Arg) const TemplateArgument &getArg(unsigned Idx) const; // in TemplateBase.h + ArrayRef<TemplateArgument> template_arguments() const { + return {getArgs(), NumArgs}; + } + bool isSugared() const { return !isDependentType() || isCurrentInstantiation() || isTypeAlias(); } QualType desugar() const { return getCanonicalTypeInternal(); } void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx) { - Profile(ID, Template, getArgs(), NumArgs, Ctx); + Profile(ID, Template, template_arguments(), Ctx); if (isTypeAlias()) getAliasedType().Profile(ID); } static void Profile(llvm::FoldingSetNodeID &ID, TemplateName T, - const TemplateArgument *Args, - unsigned NumArgs, + ArrayRef<TemplateArgument> Args, const ASTContext &Context); static bool classof(const Type *T) { @@ -4143,6 +4309,8 @@ class InjectedClassNameType : public Type { friend class ASTReader; // FIXME: ASTContext::getInjectedClassNameType is not // currently suitable for AST reading, too much // interdependencies. + friend class ASTNodeImporter; + InjectedClassNameType(CXXRecordDecl *D, QualType TST) : Type(InjectedClassName, QualType(), /*Dependent=*/true, /*InstantiationDependent=*/true, @@ -4402,8 +4570,7 @@ class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) DependentTemplateSpecializationType DependentTemplateSpecializationType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS, const IdentifierInfo *Name, - unsigned NumArgs, - const TemplateArgument *Args, + ArrayRef<TemplateArgument> Args, QualType Canon); friend class ASTContext; // ASTContext creates these @@ -4422,6 +4589,10 @@ public: const TemplateArgument &getArg(unsigned Idx) const; // in TemplateBase.h + ArrayRef<TemplateArgument> template_arguments() const { + return {getArgs(), NumArgs}; + } + typedef const TemplateArgument * iterator; iterator begin() const { return getArgs(); } iterator end() const; // inline in TemplateBase.h @@ -4430,7 +4601,7 @@ public: QualType desugar() const { return QualType(this, 0); } void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) { - Profile(ID, Context, getKeyword(), NNS, Name, NumArgs, getArgs()); + Profile(ID, Context, getKeyword(), NNS, Name, {getArgs(), NumArgs}); } static void Profile(llvm::FoldingSetNodeID &ID, @@ -4438,8 +4609,7 @@ public: ElaboratedTypeKeyword Keyword, NestedNameSpecifier *Qualifier, const IdentifierInfo *Name, - unsigned NumArgs, - const TemplateArgument *Args); + ArrayRef<TemplateArgument> Args); static bool classof(const Type *T) { return T->getTypeClass() == DependentTemplateSpecialization; @@ -5194,7 +5364,8 @@ inline void QualType::removeLocalVolatile() { inline void QualType::removeLocalCVRQualifiers(unsigned Mask) { assert(!(Mask & ~Qualifiers::CVRMask) && "mask has non-CVR bits"); - assert((int)Qualifiers::CVRMask == (int)Qualifiers::FastMask); + static_assert((int)Qualifiers::CVRMask == (int)Qualifiers::FastMask, + "Fast bits differ from CVR bits!"); // Fast path: we don't need to touch the slow qualifiers. removeLocalFastQualifiers(Mask); @@ -5230,9 +5401,9 @@ inline FunctionType::ExtInfo getFunctionExtInfo(QualType t) { /// "int". However, it is not more qualified than "const volatile /// int". inline bool QualType::isMoreQualifiedThan(QualType other) const { - Qualifiers myQuals = getQualifiers(); - Qualifiers otherQuals = other.getQualifiers(); - return (myQuals != otherQuals && myQuals.compatiblyIncludes(otherQuals)); + Qualifiers MyQuals = getQualifiers(); + Qualifiers OtherQuals = other.getQualifiers(); + return (MyQuals != OtherQuals && MyQuals.compatiblyIncludes(OtherQuals)); } /// Determine whether this type is at last @@ -5240,7 +5411,13 @@ inline bool QualType::isMoreQualifiedThan(QualType other) const { /// int" is at least as qualified as "const int", "volatile int", /// "int", and "const volatile int". inline bool QualType::isAtLeastAsQualifiedAs(QualType other) const { - return getQualifiers().compatiblyIncludes(other.getQualifiers()); + Qualifiers OtherQuals = other.getQualifiers(); + + // Ignore __unaligned qualifier if this type is a void. + if (getUnqualifiedType()->isVoidType()) + OtherQuals.removeUnaligned(); + + return getQualifiers().compatiblyIncludes(OtherQuals); } /// If Type is a reference type (e.g., const @@ -5417,53 +5594,11 @@ inline bool Type::isObjCBuiltinType() const { return isObjCIdType() || isObjCClassType() || isObjCSelType(); } -inline bool Type::isImage1dT() const { - return isSpecificBuiltinType(BuiltinType::OCLImage1d); -} - -inline bool Type::isImage1dArrayT() const { - return isSpecificBuiltinType(BuiltinType::OCLImage1dArray); -} - -inline bool Type::isImage1dBufferT() const { - return isSpecificBuiltinType(BuiltinType::OCLImage1dBuffer); -} - -inline bool Type::isImage2dT() const { - return isSpecificBuiltinType(BuiltinType::OCLImage2d); -} - -inline bool Type::isImage2dArrayT() const { - return isSpecificBuiltinType(BuiltinType::OCLImage2dArray); -} - -inline bool Type::isImage2dDepthT() const { - return isSpecificBuiltinType(BuiltinType::OCLImage2dDepth); -} - -inline bool Type::isImage2dArrayDepthT() const { - return isSpecificBuiltinType(BuiltinType::OCLImage2dArrayDepth); -} - -inline bool Type::isImage2dMSAAT() const { - return isSpecificBuiltinType(BuiltinType::OCLImage2dMSAA); -} - -inline bool Type::isImage2dArrayMSAAT() const { - return isSpecificBuiltinType(BuiltinType::OCLImage2dArrayMSAA); -} - -inline bool Type::isImage2dMSAATDepth() const { - return isSpecificBuiltinType(BuiltinType::OCLImage2dMSAADepth); -} - -inline bool Type::isImage2dArrayMSAATDepth() const { - return isSpecificBuiltinType(BuiltinType::OCLImage2dArrayMSAADepth); -} - -inline bool Type::isImage3dT() const { - return isSpecificBuiltinType(BuiltinType::OCLImage3d); -} +#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ + inline bool Type::is##Id##Type() const { \ + return isSpecificBuiltinType(BuiltinType::Id); \ + } +#include "clang/Basic/OpenCLImageTypes.def" inline bool Type::isSamplerT() const { return isSpecificBuiltinType(BuiltinType::OCLSampler); @@ -5490,11 +5625,10 @@ inline bool Type::isReserveIDT() const { } inline bool Type::isImageType() const { - return isImage3dT() || isImage2dT() || isImage2dArrayT() || - isImage2dDepthT() || isImage2dArrayDepthT() || isImage2dMSAAT() || - isImage2dArrayMSAAT() || isImage2dMSAATDepth() || - isImage2dArrayMSAATDepth() || isImage1dT() || isImage1dArrayT() || - isImage1dBufferT(); +#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) is##Id##Type() || + return +#include "clang/Basic/OpenCLImageTypes.def" + 0; // end boolean or operation } inline bool Type::isPipeType() const { @@ -5644,6 +5778,15 @@ inline const Type *Type::getBaseElementTypeUnsafe() const { return type; } +inline const Type *Type::getPointeeOrArrayElementType() const { + const Type *type = this; + if (type->isAnyPointerType()) + return type->getPointeeType().getTypePtr(); + else if (type->isArrayType()) + return type->getBaseElementTypeUnsafe(); + return type; +} + /// Insertion operator for diagnostics. This allows sending QualType's into a /// diagnostic with <<. inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, diff --git a/include/clang/AST/TypeLoc.h b/include/clang/AST/TypeLoc.h index 29035a41776e8..67adf4a638bc9 100644 --- a/include/clang/AST/TypeLoc.h +++ b/include/clang/AST/TypeLoc.h @@ -254,7 +254,7 @@ public: unsigned align = TypeLoc::getLocalAlignmentForType(QualType(getTypePtr(), 0)); uintptr_t dataInt = reinterpret_cast<uintptr_t>(Data); - dataInt = llvm::RoundUpToAlignment(dataInt, align); + dataInt = llvm::alignTo(dataInt, align); return UnqualTypeLoc(getTypePtr(), reinterpret_cast<void*>(dataInt)); } @@ -353,7 +353,7 @@ public: unsigned getLocalDataSize() const { unsigned size = sizeof(LocalData); unsigned extraAlign = asDerived()->getExtraLocalDataAlignment(); - size = llvm::RoundUpToAlignment(size, extraAlign); + size = llvm::alignTo(size, extraAlign); size += asDerived()->getExtraLocalDataSize(); return size; } @@ -399,14 +399,14 @@ protected: void *getExtraLocalData() const { unsigned size = sizeof(LocalData); unsigned extraAlign = asDerived()->getExtraLocalDataAlignment(); - size = llvm::RoundUpToAlignment(size, extraAlign); + size = llvm::alignTo(size, extraAlign); return reinterpret_cast<char*>(Base::Data) + size; } void *getNonLocalData() const { uintptr_t data = reinterpret_cast<uintptr_t>(Base::Data); data += asDerived()->getLocalDataSize(); - data = llvm::RoundUpToAlignment(data, getNextTypeAlign()); + data = llvm::alignTo(data, getNextTypeAlign()); return reinterpret_cast<void*>(data); } @@ -538,7 +538,7 @@ public: bool needsExtraLocalData() const { BuiltinType::Kind bk = getTypePtr()->getKind(); return (bk >= BuiltinType::UShort && bk <= BuiltinType::UInt128) - || (bk >= BuiltinType::Short && bk <= BuiltinType::LongDouble) + || (bk >= BuiltinType::Short && bk <= BuiltinType::Float128) || bk == BuiltinType::UChar || bk == BuiltinType::SChar; } diff --git a/include/clang/AST/UnresolvedSet.h b/include/clang/AST/UnresolvedSet.h index 26ee1cf71c813..c1be2aa0f2013 100644 --- a/include/clang/AST/UnresolvedSet.h +++ b/include/clang/AST/UnresolvedSet.h @@ -59,8 +59,13 @@ class UnresolvedSetImpl { // UnresolvedSet. private: template <unsigned N> friend class UnresolvedSet; - UnresolvedSetImpl() {} - UnresolvedSetImpl(const UnresolvedSetImpl &) {} + UnresolvedSetImpl() = default; + UnresolvedSetImpl(const UnresolvedSetImpl &) = default; + UnresolvedSetImpl &operator=(const UnresolvedSetImpl &) = default; + + // FIXME: Switch these to "= default" once MSVC supports generating move ops + UnresolvedSetImpl(UnresolvedSetImpl &&) {} + UnresolvedSetImpl &operator=(UnresolvedSetImpl &&) { return *this; } public: // We don't currently support assignment through this iterator, so we might diff --git a/include/clang/ASTMatchers/ASTMatchFinder.h b/include/clang/ASTMatchers/ASTMatchFinder.h index 92ec92c299c57..042408859c9de 100644 --- a/include/clang/ASTMatchers/ASTMatchFinder.h +++ b/include/clang/ASTMatchers/ASTMatchFinder.h @@ -241,6 +241,11 @@ match(MatcherT Matcher, const ast_type_traits::DynTypedNode &Node, ASTContext &Context); /// @} +/// \brief Returns the results of matching \p Matcher on the translation unit of +/// \p Context and collects the \c BoundNodes of all callback invocations. +template <typename MatcherT> +SmallVector<BoundNodes, 1> match(MatcherT Matcher, ASTContext &Context); + /// \brief Returns the first result of type \c NodeT bound to \p BoundTo. /// /// Returns \c NULL if there is no match, or if the matching node cannot be @@ -288,6 +293,16 @@ match(MatcherT Matcher, const NodeT &Node, ASTContext &Context) { return match(Matcher, ast_type_traits::DynTypedNode::create(Node), Context); } +template <typename MatcherT> +SmallVector<BoundNodes, 1> +match(MatcherT Matcher, ASTContext &Context) { + internal::CollectMatchesCallback Callback; + MatchFinder Finder; + Finder.addMatcher(Matcher, &Callback); + Finder.matchAST(Context); + return std::move(Callback.Nodes); +} + } // end namespace ast_matchers } // end namespace clang diff --git a/include/clang/ASTMatchers/ASTMatchers.h b/include/clang/ASTMatchers/ASTMatchers.h index e6ba8778f249a..aef4b4eafd9ac 100644 --- a/include/clang/ASTMatchers/ASTMatchers.h +++ b/include/clang/ASTMatchers/ASTMatchers.h @@ -163,11 +163,35 @@ const internal::VariadicDynCastAllOfMatcher<Decl, TranslationUnitDecl> /// Given /// \code /// typedef int X; +/// using Y = int; /// \endcode /// typedefDecl() -/// matches "typedef int X" +/// matches "typedef int X", but not "using Y = int" const internal::VariadicDynCastAllOfMatcher<Decl, TypedefDecl> typedefDecl; +/// \brief Matches typedef name declarations. +/// +/// Given +/// \code +/// typedef int X; +/// using Y = int; +/// \endcode +/// typedefNameDecl() +/// matches "typedef int X" and "using Y = int" +const internal::VariadicDynCastAllOfMatcher<Decl, TypedefNameDecl> + typedefNameDecl; + +/// \brief Matches type alias declarations. +/// +/// Given +/// \code +/// typedef int X; +/// using Y = int; +/// \endcode +/// typeAliasDecl() +/// matches "using Y = int", but not "typedef int X" +const internal::VariadicDynCastAllOfMatcher<Decl, TypeAliasDecl> typeAliasDecl; + /// \brief Matches AST nodes that were expanded within the main-file. /// /// Example matches X but not Y @@ -282,6 +306,17 @@ const internal::VariadicDynCastAllOfMatcher<Decl, LinkageSpecDecl> /// \endcode const internal::VariadicDynCastAllOfMatcher<Decl, NamedDecl> namedDecl; +/// \brief Matches a declaration of label. +/// +/// Given +/// \code +/// goto FOO; +/// FOO: bar(); +/// \endcode +/// labelDecl() +/// matches 'FOO:' +const internal::VariadicDynCastAllOfMatcher<Decl, LabelDecl> labelDecl; + /// \brief Matches a declaration of a namespace. /// /// Given @@ -447,7 +482,7 @@ const internal::VariadicDynCastAllOfMatcher< /// }; /// \endcode /// fieldDecl(isPublic()) -/// matches 'int a;' +/// matches 'int a;' AST_MATCHER(Decl, isPublic) { return Node.getAccess() == AS_public; } @@ -463,7 +498,7 @@ AST_MATCHER(Decl, isPublic) { /// }; /// \endcode /// fieldDecl(isProtected()) -/// matches 'int b;' +/// matches 'int b;' AST_MATCHER(Decl, isProtected) { return Node.getAccess() == AS_protected; } @@ -479,11 +514,43 @@ AST_MATCHER(Decl, isProtected) { /// }; /// \endcode /// fieldDecl(isPrivate()) -/// matches 'int c;' +/// matches 'int c;' AST_MATCHER(Decl, isPrivate) { return Node.getAccess() == AS_private; } +/// \brief Matches non-static data members that are bit-fields. +/// +/// Given +/// \code +/// class C { +/// int a : 2; +/// int b; +/// }; +/// \endcode +/// fieldDecl(isBitField()) +/// matches 'int a;' but not 'int b;'. +AST_MATCHER(FieldDecl, isBitField) { + return Node.isBitField(); +} + +/// \brief Matches non-static data members that are bit-fields. +/// +/// Given +/// \code +/// class C { +/// int a : 2; +/// int b : 4; +/// int c : 2; +/// }; +/// \endcode +/// fieldDecl(isBitField()) +/// matches 'int a;' and 'int c;' but not 'int b;'. +AST_MATCHER_P(FieldDecl, hasBitWidth, unsigned, Width) { + return Node.isBitField() && + Node.getBitWidthValue(Finder->getASTContext()) == Width; +} + /// \brief Matches a declaration that has been implicitly added /// by the compiler (eg. implicit default/copy constructors). AST_MATCHER(Decl, isImplicit) { @@ -513,6 +580,32 @@ AST_POLYMORPHIC_MATCHER_P( Builder); } +/// \brief Matches expressions that match InnerMatcher after any implicit AST +/// nodes are stripped off. +/// +/// Parentheses and explicit casts are not discarded. +/// Given +/// \code +/// class C {}; +/// C a = C(); +/// C b; +/// C c = b; +/// \endcode +/// The matchers +/// \code +/// varDecl(hasInitializer(ignoringImplicit(cxxConstructExpr()))) +/// \endcode +/// would match the declarations for a, b, and c. +/// While +/// \code +/// varDecl(hasInitializer(cxxConstructExpr())) +/// \endcode +/// only match the declarations for b and c. +AST_MATCHER_P(Expr, ignoringImplicit, ast_matchers::internal::Matcher<Expr>, + InnerMatcher) { + return InnerMatcher.matches(*Node.IgnoreImplicit(), Finder, Builder); +} + /// \brief Matches expressions that match InnerMatcher after any implicit casts /// are stripped off. /// @@ -590,6 +683,22 @@ AST_MATCHER_P(Expr, ignoringParenImpCasts, return InnerMatcher.matches(*Node.IgnoreParenImpCasts(), Finder, Builder); } +/// \brief Matches types that match InnerMatcher after any parens are stripped. +/// +/// Given +/// \code +/// void (*fp)(void); +/// \endcode +/// The matcher +/// \code +/// varDecl(hasType(pointerType(pointee(ignoringParens(functionType()))))) +/// \endcode +/// would match the declaration for fp. +AST_MATCHER_P(QualType, ignoringParens, + internal::Matcher<QualType>, InnerMatcher) { + return InnerMatcher.matches(Node.IgnoreParens(), Finder, Builder); +} + /// \brief Matches classTemplateSpecializations where the n'th TemplateArgument /// matches the given InnerMatcher. /// @@ -976,6 +1085,43 @@ const internal::VariadicDynCastAllOfMatcher< /// matches "{ 1, 2 }" and "{ 5, 6 }" const internal::VariadicDynCastAllOfMatcher<Stmt, InitListExpr> initListExpr; +/// \brief Matches the syntactic form of init list expressions +/// (if expression have it). +AST_MATCHER_P(InitListExpr, hasSyntacticForm, + internal::Matcher<Expr>, InnerMatcher) { + const Expr *SyntForm = Node.getSyntacticForm(); + return (SyntForm != nullptr && + InnerMatcher.matches(*SyntForm, Finder, Builder)); +} + +/// \brief Matches implicit initializers of init list expressions. +/// +/// Given +/// \code +/// point ptarray[10] = { [2].y = 1.0, [2].x = 2.0, [0].x = 1.0 }; +/// \endcode +/// implicitValueInitExpr() +/// matches "[0].y" (implicitly) +const internal::VariadicDynCastAllOfMatcher<Stmt, ImplicitValueInitExpr> +implicitValueInitExpr; + +/// \brief Matches paren list expressions. +/// ParenListExprs don't have a predefined type and are used for late parsing. +/// In the final AST, they can be met in template declarations. +/// +/// Given +/// \code +/// template<typename T> class X { +/// void f() { +/// X x(*this); +/// int a = 0, b = 1; int i = (a, b); +/// } +/// }; +/// \endcode +/// parenListExpr() matches "*this" but NOT matches (a, b) because (a, b) +/// has a predefined type and is a ParenExpr, not a ParenListExpr. +const internal::VariadicDynCastAllOfMatcher<Stmt, ParenListExpr> parenListExpr; + /// \brief Matches substitutions of non-type template parameters. /// /// Given @@ -1014,6 +1160,24 @@ const internal::VariadicDynCastAllOfMatcher< Decl, UsingDirectiveDecl> usingDirectiveDecl; +/// \brief Matches reference to a name that can be looked up during parsing +/// but could not be resolved to a specific declaration. +/// +/// Given +/// \code +/// template<typename T> +/// T foo() { T a; return a; } +/// template<typename T> +/// void bar() { +/// foo<T>(); +/// } +/// \endcode +/// unresolvedLookupExpr() +/// matches \code foo<T>() \endcode +const internal::VariadicDynCastAllOfMatcher< + Stmt, + UnresolvedLookupExpr> unresolvedLookupExpr; + /// \brief Matches unresolved using value declarations. /// /// Given @@ -1048,6 +1212,17 @@ const internal::VariadicDynCastAllOfMatcher< Decl, UnresolvedUsingTypenameDecl> unresolvedUsingTypenameDecl; +/// \brief Matches parentheses used in expressions. +/// +/// Example matches (foo() + 1) +/// \code +/// int foo() { return 1; } +/// int a = (foo() + 1); +/// \endcode +const internal::VariadicDynCastAllOfMatcher< + Stmt, + ParenExpr> parenExpr; + /// \brief Matches constructor call expressions (including implicit ones). /// /// Example matches string(ptr, n) and ptr within arguments of f @@ -1357,6 +1532,18 @@ const internal::VariadicDynCastAllOfMatcher<Stmt, GotoStmt> gotoStmt; /// matches 'FOO:' const internal::VariadicDynCastAllOfMatcher<Stmt, LabelStmt> labelStmt; +/// \brief Matches address of label statements (GNU extension). +/// +/// Given +/// \code +/// FOO: bar(); +/// void *ptr = &&FOO; +/// goto *bar; +/// \endcode +/// addrLabelExpr() +/// matches '&&FOO' +const internal::VariadicDynCastAllOfMatcher<Stmt, AddrLabelExpr> addrLabelExpr; + /// \brief Matches switch statements. /// /// Given @@ -1465,7 +1652,8 @@ const internal::VariadicDynCastAllOfMatcher< /// /// Example matches "abcd", L"abcd" /// \code -/// char *s = "abcd"; wchar_t *ws = L"abcd" +/// char *s = "abcd"; +/// wchar_t *ws = L"abcd"; /// \endcode const internal::VariadicDynCastAllOfMatcher< Stmt, @@ -1478,7 +1666,8 @@ const internal::VariadicDynCastAllOfMatcher< /// /// Example matches 'a', L'a' /// \code -/// char ch = 'a'; wchar_t chw = L'a'; +/// char ch = 'a'; +/// wchar_t chw = L'a'; /// \endcode const internal::VariadicDynCastAllOfMatcher< Stmt, @@ -1514,7 +1703,8 @@ const internal::VariadicDynCastAllOfMatcher< /// /// Example match: {1}, (1, 2) /// \code -/// int array[4] = {1}; vector int myvec = (vector int)(1, 2); +/// int array[4] = {1}; +/// vector int myvec = (vector int)(1, 2); /// \endcode const internal::VariadicDynCastAllOfMatcher< Stmt, @@ -1526,9 +1716,22 @@ const internal::VariadicDynCastAllOfMatcher< CXXNullPtrLiteralExpr> cxxNullPtrLiteralExpr; /// \brief Matches GNU __null expression. -const internal::VariadicDynCastAllOfMatcher< - Stmt, - GNUNullExpr> gnuNullExpr; +const internal::VariadicDynCastAllOfMatcher<Stmt, GNUNullExpr> gnuNullExpr; + +/// \brief Matches atomic builtins. +/// Example matches __atomic_load_n(ptr, 1) +/// \code +/// void foo() { int *ptr; __atomic_load_n(ptr, 1); } +/// \endcode +const internal::VariadicDynCastAllOfMatcher<Stmt, AtomicExpr> atomicExpr; + +/// \brief Matches statement expression (GNU extension). +/// +/// Example match: ({ int X = 4; X; }) +/// \code +/// int C = ({ int X = 4; X; }); +/// \endcode +const internal::VariadicDynCastAllOfMatcher<Stmt, StmtExpr> stmtExpr; /// \brief Matches binary operator expressions. /// @@ -1560,6 +1763,28 @@ const internal::VariadicDynCastAllOfMatcher< Stmt, ConditionalOperator> conditionalOperator; +/// \brief Matches binary conditional operator expressions (GNU extension). +/// +/// Example matches a ?: b +/// \code +/// (a ?: b) + 42; +/// \endcode +const internal::VariadicDynCastAllOfMatcher< + Stmt, + BinaryConditionalOperator> binaryConditionalOperator; + +/// \brief Matches opaque value expressions. They are used as helpers +/// to reference another expressions and can be met +/// in BinaryConditionalOperators, for example. +/// +/// Example matches 'a' +/// \code +/// (a ?: c) + 42; +/// \endcode +const internal::VariadicDynCastAllOfMatcher< + Stmt, + OpaqueValueExpr> opaqueValueExpr; + /// \brief Matches a C++ static_assert declaration. /// /// Example: @@ -1716,6 +1941,41 @@ const internal::VariadicDynCastAllOfMatcher< Stmt, CXXTemporaryObjectExpr> cxxTemporaryObjectExpr; +/// \brief Matches predefined identifier expressions [C99 6.4.2.2]. +/// +/// Example: Matches __func__ +/// \code +/// printf("%s", __func__); +/// \endcode +const internal::VariadicDynCastAllOfMatcher< + Stmt, + PredefinedExpr> predefinedExpr; + +/// \brief Matches C99 designated initializer expressions [C99 6.7.8]. +/// +/// Example: Matches { [2].y = 1.0, [0].x = 1.0 } +/// \code +/// point ptarray[10] = { [2].y = 1.0, [0].x = 1.0 }; +/// \endcode +const internal::VariadicDynCastAllOfMatcher< + Stmt, + DesignatedInitExpr> designatedInitExpr; + +/// \brief Matches designated initializer expressions that contain +/// a specific number of designators. +/// +/// Example: Given +/// \code +/// point ptarray[10] = { [2].y = 1.0, [0].x = 1.0 }; +/// point ptarray2[10] = { [2].y = 1.0, [2].x = 0.0, [0].x = 1.0 }; +/// \endcode +/// designatorCountIs(2) +/// matches '{ [2].y = 1.0, [0].x = 1.0 }', +/// but not '{ [2].y = 1.0, [2].x = 0.0, [0].x = 1.0 }'. +AST_MATCHER_P(DesignatedInitExpr, designatorCountIs, unsigned, N) { + return Node.size() == N; +} + /// \brief Matches \c QualTypes in the clang AST. const internal::VariadicAllOfMatcher<QualType> qualType; @@ -1834,9 +2094,25 @@ inline internal::Matcher<Stmt> sizeOfExpr( /// namespace a { namespace b { class X; } } /// \endcode inline internal::Matcher<NamedDecl> hasName(const std::string &Name) { - return internal::Matcher<NamedDecl>(new internal::HasNameMatcher(Name)); + std::vector<std::string> Names; + Names.push_back(Name); + return internal::Matcher<NamedDecl>(new internal::HasNameMatcher(Names)); } +/// \brief Matches NamedDecl nodes that have any of the specified names. +/// +/// This matcher is only provided as a performance optimization of hasName. +/// \code +/// hasAnyName(a, b, c) +/// \endcode +/// is equivalent to, but faster than +/// \code +/// anyOf(hasName(a), hasName(b), hasName(c)) +/// \endcode +const internal::VariadicFunction<internal::Matcher<NamedDecl>, StringRef, + internal::hasAnyNameFunc> + hasAnyName = {}; + /// \brief Matches NamedDecl nodes whose fully qualified names contain /// a substring matched by the given RegExp. /// @@ -1953,6 +2229,19 @@ AST_MATCHER_P(CXXRecordDecl, hasMethod, internal::Matcher<CXXMethodDecl>, Node.method_end(), Finder, Builder); } +/// \brief Matches the generated class of lambda expressions. +/// +/// Given: +/// \code +/// auto x = []{}; +/// \endcode +/// +/// \c cxxRecordDecl(isLambda()) matches the implicit class declaration of +/// \c decltype(x) +AST_MATCHER(CXXRecordDecl, isLambda) { + return Node.isLambda(); +} + /// \brief Matches AST nodes that have child AST nodes that match the /// provided matcher. /// @@ -1967,6 +2256,10 @@ AST_MATCHER_P(CXXRecordDecl, hasMethod, internal::Matcher<CXXMethodDecl>, /// ChildT must be an AST base type. /// /// Usable as: Any Matcher +/// Note that has is direct matcher, so it also matches things like implicit +/// casts and paren casts. If you are matching with expr then you should +/// probably consider using ignoringParenImpCasts like: +/// has(ignoringParenImpCasts(expr())). const internal::ArgumentAdaptingMatcherFunc<internal::HasMatcher> LLVM_ATTRIBUTE_UNUSED has = {}; @@ -2117,8 +2410,8 @@ const internal::VariadicOperatorMatcherFunc<1, 1> unless = { /// /// Usable as: Matcher<CallExpr>, Matcher<CXXConstructExpr>, /// Matcher<DeclRefExpr>, Matcher<EnumType>, Matcher<InjectedClassNameType>, -/// Matcher<LabelStmt>, Matcher<MemberExpr>, Matcher<QualType>, -/// Matcher<RecordType>, Matcher<TagType>, +/// Matcher<LabelStmt>, Matcher<AddrLabelExpr>, Matcher<MemberExpr>, +/// Matcher<QualType>, Matcher<RecordType>, Matcher<TagType>, /// Matcher<TemplateSpecializationType>, Matcher<TemplateTypeParmType>, /// Matcher<TypedefType>, Matcher<UnresolvedUsingType> inline internal::PolymorphicMatcherWithParam1< @@ -2287,14 +2580,17 @@ AST_MATCHER_P_OVERLOAD(CallExpr, callee, internal::Matcher<Decl>, InnerMatcher, /// /// Example matches x (matcher = expr(hasType(cxxRecordDecl(hasName("X"))))) /// and z (matcher = varDecl(hasType(cxxRecordDecl(hasName("X"))))) +/// and U (matcher = typedefDecl(hasType(asString("int"))) /// \code /// class X {}; /// void y(X &x) { x; X z; } +/// typedef int U; /// \endcode AST_POLYMORPHIC_MATCHER_P_OVERLOAD( - hasType, AST_POLYMORPHIC_SUPPORTED_TYPES(Expr, ValueDecl), + hasType, AST_POLYMORPHIC_SUPPORTED_TYPES(Expr, TypedefNameDecl, ValueDecl), internal::Matcher<QualType>, InnerMatcher, 0) { - return InnerMatcher.matches(Node.getType(), Finder, Builder); + return InnerMatcher.matches(internal::getUnderlyingType(Node), + Finder, Builder); } /// \brief Overloaded to match the declaration of the expression's or value @@ -2829,18 +3125,13 @@ AST_MATCHER(CXXCtorInitializer, isMemberInitializer) { /// matches x(1, y, 42) /// with hasAnyArgument(...) /// matching y -/// -/// FIXME: Currently this will ignore parentheses and implicit casts on -/// the argument before applying the inner matcher. We'll want to remove -/// this to allow for greater control by the user once \c ignoreImplicit() -/// has been implemented. AST_POLYMORPHIC_MATCHER_P(hasAnyArgument, AST_POLYMORPHIC_SUPPORTED_TYPES(CallExpr, CXXConstructExpr), internal::Matcher<Expr>, InnerMatcher) { for (const Expr *Arg : Node.arguments()) { BoundNodesTreeBuilder Result(*Builder); - if (InnerMatcher.matches(*Arg->IgnoreParenImpCasts(), Finder, &Result)) { + if (InnerMatcher.matches(*Arg, Finder, &Result)) { *Builder = std::move(Result); return true; } @@ -2853,6 +3144,22 @@ AST_MATCHER(CXXConstructExpr, isListInitialization) { return Node.isListInitialization(); } +/// \brief Matches a constructor call expression which requires +/// zero initialization. +/// +/// Given +/// \code +/// void foo() { +/// struct point { double x; double y; }; +/// point pt[2] = { { 1.0, 2.0 } }; +/// } +/// \endcode +/// initListExpr(has(cxxConstructExpr(requiresZeroInitialization())) +/// will match the implicit array filler for pt[1]. +AST_MATCHER(CXXConstructExpr, requiresZeroInitialization) { + return Node.requiresZeroInitialization(); +} + /// \brief Matches the n'th parameter of a function declaration. /// /// Given @@ -2871,6 +3178,60 @@ AST_MATCHER_P2(FunctionDecl, hasParameter, *Node.getParamDecl(N), Finder, Builder)); } +/// \brief Matches all arguments and their respective ParmVarDecl. +/// +/// Given +/// \code +/// void f(int i); +/// int y; +/// f(y); +/// \endcode +/// callExpr( +/// forEachArgumentWithParam( +/// declRefExpr(to(varDecl(hasName("y")))), +/// parmVarDecl(hasType(isInteger())) +/// )) +/// matches f(y); +/// with declRefExpr(...) +/// matching int y +/// and parmVarDecl(...) +/// matching int i +AST_POLYMORPHIC_MATCHER_P2(forEachArgumentWithParam, + AST_POLYMORPHIC_SUPPORTED_TYPES(CallExpr, + CXXConstructExpr), + internal::Matcher<Expr>, ArgMatcher, + internal::Matcher<ParmVarDecl>, ParamMatcher) { + BoundNodesTreeBuilder Result; + // The first argument of an overloaded member operator is the implicit object + // argument of the method which should not be matched against a parameter, so + // we skip over it here. + BoundNodesTreeBuilder Matches; + unsigned ArgIndex = cxxOperatorCallExpr(callee(cxxMethodDecl())) + .matches(Node, Finder, &Matches) + ? 1 + : 0; + int ParamIndex = 0; + bool Matched = false; + for (; ArgIndex < Node.getNumArgs(); ++ArgIndex) { + BoundNodesTreeBuilder ArgMatches(*Builder); + if (ArgMatcher.matches(*(Node.getArg(ArgIndex)->IgnoreParenCasts()), + Finder, &ArgMatches)) { + BoundNodesTreeBuilder ParamMatches(ArgMatches); + if (expr(anyOf(cxxConstructExpr(hasDeclaration(cxxConstructorDecl( + hasParameter(ParamIndex, ParamMatcher)))), + callExpr(callee(functionDecl( + hasParameter(ParamIndex, ParamMatcher)))))) + .matches(Node, Finder, &ParamMatches)) { + Result.addMatch(ParamMatches); + Matched = true; + } + } + ++ParamIndex; + } + *Builder = std::move(Result); + return Matched; +} + /// \brief Matches any parameter of a function declaration. /// /// Does not match the 'this' parameter of a method. @@ -2889,16 +3250,27 @@ AST_MATCHER_P(FunctionDecl, hasAnyParameter, Node.param_end(), Finder, Builder); } -/// \brief Matches \c FunctionDecls that have a specific parameter count. +/// \brief Matches \c FunctionDecls and \c FunctionProtoTypes that have a +/// specific parameter count. /// /// Given /// \code /// void f(int i) {} /// void g(int i, int j) {} +/// void h(int i, int j); +/// void j(int i); +/// void k(int x, int y, int z, ...); /// \endcode /// functionDecl(parameterCountIs(2)) -/// matches g(int i, int j) {} -AST_MATCHER_P(FunctionDecl, parameterCountIs, unsigned, N) { +/// matches void g(int i, int j) {} +/// functionProtoType(parameterCountIs(2)) +/// matches void h(int i, int j) +/// functionProtoType(parameterCountIs(3)) +/// matches void k(int x, int y, int z, ...); +AST_POLYMORPHIC_MATCHER_P(parameterCountIs, + AST_POLYMORPHIC_SUPPORTED_TYPES(FunctionDecl, + FunctionProtoType), + unsigned, N) { return Node.getNumParams() == N; } @@ -2942,6 +3314,42 @@ AST_MATCHER(FunctionDecl, isDeleted) { return Node.isDeleted(); } +/// \brief Matches defaulted function declarations. +/// +/// Given: +/// \code +/// class A { ~A(); }; +/// class B { ~B() = default; }; +/// \endcode +/// functionDecl(isDefaulted()) +/// matches the declaration of ~B, but not ~A. +AST_MATCHER(FunctionDecl, isDefaulted) { + return Node.isDefaulted(); +} + +/// \brief Matches functions that have a dynamic exception specification. +/// +/// Given: +/// \code +/// void f(); +/// void g() noexcept; +/// void h() noexcept(true); +/// void i() noexcept(false); +/// void j() throw(); +/// void k() throw(int); +/// void l() throw(...); +/// \endcode +/// functionDecl(hasDynamicExceptionSpec()) and +/// functionProtoType(hasDynamicExceptionSpec()) +/// match the declarations of j, k, and l, but not f, g, h, or i. +AST_POLYMORPHIC_MATCHER(hasDynamicExceptionSpec, + AST_POLYMORPHIC_SUPPORTED_TYPES(FunctionDecl, + FunctionProtoType)) { + if (const FunctionProtoType *FnTy = internal::getFunctionProtoType(Node)) + return FnTy->hasDynamicExceptionSpec(); + return false; +} + /// \brief Matches functions that have a non-throwing exception specification. /// /// Given: @@ -2952,10 +3360,12 @@ AST_MATCHER(FunctionDecl, isDeleted) { /// void i() throw(int); /// void j() noexcept(false); /// \endcode -/// functionDecl(isNoThrow()) -/// matches the declarations of g, and h, but not f, i or j. -AST_MATCHER(FunctionDecl, isNoThrow) { - const auto *FnTy = Node.getType()->getAs<FunctionProtoType>(); +/// functionDecl(isNoThrow()) and functionProtoType(isNoThrow()) +/// match the declarations of g, and h, but not f, i or j. +AST_POLYMORPHIC_MATCHER(isNoThrow, + AST_POLYMORPHIC_SUPPORTED_TYPES(FunctionDecl, + FunctionProtoType)) { + const FunctionProtoType *FnTy = internal::getFunctionProtoType(Node); // If the function does not have a prototype, then it is assumed to be a // throwing function (as it would if the function did not have any exception @@ -2967,7 +3377,7 @@ AST_MATCHER(FunctionDecl, isNoThrow) { if (isUnresolvedExceptionSpec(FnTy->getExceptionSpecType())) return true; - return FnTy->isNothrow(Node.getASTContext()); + return FnTy->isNothrow(Finder->getASTContext()); } /// \brief Matches constexpr variable and function declarations. @@ -2988,17 +3398,17 @@ AST_POLYMORPHIC_MATCHER(isConstexpr, } /// \brief Matches the condition expression of an if statement, for loop, -/// or conditional operator. +/// switch statement or conditional operator. /// /// Example matches true (matcher = hasCondition(cxxBoolLiteral(equals(true)))) /// \code /// if (true) {} /// \endcode -AST_POLYMORPHIC_MATCHER_P(hasCondition, - AST_POLYMORPHIC_SUPPORTED_TYPES(IfStmt, ForStmt, - WhileStmt, DoStmt, - ConditionalOperator), - internal::Matcher<Expr>, InnerMatcher) { +AST_POLYMORPHIC_MATCHER_P( + hasCondition, + AST_POLYMORPHIC_SUPPORTED_TYPES(IfStmt, ForStmt, WhileStmt, DoStmt, + SwitchStmt, AbstractConditionalOperator), + internal::Matcher<Expr>, InnerMatcher) { const Expr *const Condition = Node.getCond(); return (Condition != nullptr && InnerMatcher.matches(*Condition, Finder, Builder)); @@ -3114,8 +3524,8 @@ AST_MATCHER_P(ArraySubscriptExpr, hasBase, return false; } -/// \brief Matches a 'for', 'while', or 'do while' statement that has -/// a given body. +/// \brief Matches a 'for', 'while', 'do while' statement or a function +/// definition that has a given body. /// /// Given /// \code @@ -3128,15 +3538,16 @@ AST_MATCHER_P(ArraySubscriptExpr, hasBase, AST_POLYMORPHIC_MATCHER_P(hasBody, AST_POLYMORPHIC_SUPPORTED_TYPES(DoStmt, ForStmt, WhileStmt, - CXXForRangeStmt), + CXXForRangeStmt, + FunctionDecl), internal::Matcher<Stmt>, InnerMatcher) { - const Stmt *const Statement = Node.getBody(); + const Stmt *const Statement = internal::GetBodyMatcher<NodeType>::get(Node); return (Statement != nullptr && InnerMatcher.matches(*Statement, Finder, Builder)); } /// \brief Matches compound statements where at least one substatement matches -/// a given matcher. +/// a given matcher. Also matches StmtExprs that have CompoundStmt as children. /// /// Given /// \code @@ -3146,10 +3557,13 @@ AST_POLYMORPHIC_MATCHER_P(hasBody, /// matches '{ {}; 1+2; }' /// with compoundStmt() /// matching '{}' -AST_MATCHER_P(CompoundStmt, hasAnySubstatement, - internal::Matcher<Stmt>, InnerMatcher) { - return matchesFirstInPointerRange(InnerMatcher, Node.body_begin(), - Node.body_end(), Finder, Builder); +AST_POLYMORPHIC_MATCHER_P(hasAnySubstatement, + AST_POLYMORPHIC_SUPPORTED_TYPES(CompoundStmt, + StmtExpr), + internal::Matcher<Stmt>, InnerMatcher) { + const CompoundStmt *CS = CompoundStmtMatcher<NodeType>::get(Node); + return CS && matchesFirstInPointerRange(InnerMatcher, CS->body_begin(), + CS->body_end(), Finder, Builder); } /// \brief Checks that a compound statement contains a specific number of @@ -3248,21 +3662,43 @@ AST_MATCHER_P(UnaryOperator, hasUnaryOperand, InnerMatcher.matches(*Operand, Finder, Builder)); } -/// \brief Matches if the cast's source expression matches the given matcher. +/// \brief Matches if the cast's source expression +/// or opaque value's source expression matches the given matcher. /// -/// Example: matches "a string" (matcher = -/// hasSourceExpression(cxxConstructExpr())) +/// Example 1: matches "a string" +/// (matcher = castExpr(hasSourceExpression(cxxConstructExpr()))) /// \code /// class URL { URL(string); }; /// URL url = "a string"; /// \endcode -AST_MATCHER_P(CastExpr, hasSourceExpression, - internal::Matcher<Expr>, InnerMatcher) { - const Expr* const SubExpression = Node.getSubExpr(); +/// +/// Example 2: matches 'b' (matcher = +/// opaqueValueExpr(hasSourceExpression(implicitCastExpr(declRefExpr()))) +/// \code +/// int a = b ?: 1; +/// \endcode + +AST_POLYMORPHIC_MATCHER_P(hasSourceExpression, + AST_POLYMORPHIC_SUPPORTED_TYPES(CastExpr, + OpaqueValueExpr), + internal::Matcher<Expr>, InnerMatcher) { + const Expr *const SubExpression = + internal::GetSourceExpressionMatcher<NodeType>::get(Node); return (SubExpression != nullptr && InnerMatcher.matches(*SubExpression, Finder, Builder)); } +/// \brief Matches casts that has a given cast kind. +/// +/// Example: matches the implicit cast around \c 0 +/// (matcher = castExpr(hasCastKind(CK_NullToPointer))) +/// \code +/// int *p = 0; +/// \endcode +AST_MATCHER_P(CastExpr, hasCastKind, CastKind, Kind) { + return Node.getCastKind() == Kind; +} + /// \brief Matches casts whose destination type matches a given matcher. /// /// (Note: Clang's AST refers to other conversions as "casts" too, and calls @@ -3320,24 +3756,31 @@ AST_MATCHER(RecordDecl, isClass) { /// \brief Matches the true branch expression of a conditional operator. /// -/// Example matches a +/// Example 1 (conditional ternary operator): matches a /// \code /// condition ? a : b /// \endcode -AST_MATCHER_P(ConditionalOperator, hasTrueExpression, +/// +/// Example 2 (conditional binary operator): matches opaqueValueExpr(condition) +/// \code +/// condition ?: b +/// \endcode +AST_MATCHER_P(AbstractConditionalOperator, hasTrueExpression, internal::Matcher<Expr>, InnerMatcher) { const Expr *Expression = Node.getTrueExpr(); return (Expression != nullptr && InnerMatcher.matches(*Expression, Finder, Builder)); } -/// \brief Matches the false branch expression of a conditional operator. +/// \brief Matches the false branch expression of a conditional operator +/// (binary or ternary). /// /// Example matches b /// \code /// condition ? a : b +/// condition ?: b /// \endcode -AST_MATCHER_P(ConditionalOperator, hasFalseExpression, +AST_MATCHER_P(AbstractConditionalOperator, hasFalseExpression, internal::Matcher<Expr>, InnerMatcher) { const Expr *Expression = Node.getFalseExpr(); return (Expression != nullptr && @@ -3401,6 +3844,47 @@ AST_MATCHER_P(CXXMethodDecl, ofClass, InnerMatcher.matches(*Parent, Finder, Builder)); } +/// \brief Matches each method overriden by the given method. This matcher may +/// produce multiple matches. +/// +/// Given +/// \code +/// class A { virtual void f(); }; +/// class B : public A { void f(); }; +/// class C : public B { void f(); }; +/// \endcode +/// cxxMethodDecl(ofClass(hasName("C")), +/// forEachOverridden(cxxMethodDecl().bind("b"))).bind("d") +/// matches once, with "b" binding "A::f" and "d" binding "C::f" (Note +/// that B::f is not overridden by C::f). +/// +/// The check can produce multiple matches in case of multiple inheritance, e.g. +/// \code +/// class A1 { virtual void f(); }; +/// class A2 { virtual void f(); }; +/// class C : public A1, public A2 { void f(); }; +/// \endcode +/// cxxMethodDecl(ofClass(hasName("C")), +/// forEachOverridden(cxxMethodDecl().bind("b"))).bind("d") +/// matches twice, once with "b" binding "A1::f" and "d" binding "C::f", and +/// once with "b" binding "A2::f" and "d" binding "C::f". +AST_MATCHER_P(CXXMethodDecl, forEachOverridden, + internal::Matcher<CXXMethodDecl>, InnerMatcher) { + BoundNodesTreeBuilder Result; + bool Matched = false; + for (const auto *Overridden : Node.overridden_methods()) { + BoundNodesTreeBuilder OverriddenBuilder(*Builder); + const bool OverriddenMatched = + InnerMatcher.matches(*Overridden, Finder, &OverriddenBuilder); + if (OverriddenMatched) { + Matched = true; + Result.addMatch(OverriddenBuilder); + } + } + *Builder = std::move(Result); + return Matched; +} + /// \brief Matches if the given method declaration is virtual. /// /// Given @@ -3415,6 +3899,24 @@ AST_MATCHER(CXXMethodDecl, isVirtual) { return Node.isVirtual(); } +/// \brief Matches if the given method declaration has an explicit "virtual". +/// +/// Given +/// \code +/// class A { +/// public: +/// virtual void x(); +/// }; +/// class B : public A { +/// public: +/// void x(); +/// }; +/// \endcode +/// matches A::x but not B::x +AST_MATCHER(CXXMethodDecl, isVirtualAsWritten) { + return Node.isVirtualAsWritten(); +} + /// \brief Matches if the given method or class declaration is final. /// /// Given: @@ -3482,6 +3984,23 @@ AST_MATCHER(CXXMethodDecl, isCopyAssignmentOperator) { return Node.isCopyAssignmentOperator(); } +/// \brief Matches if the given method declaration declares a move assignment +/// operator. +/// +/// Given +/// \code +/// struct A { +/// A &operator=(const A &); +/// A &operator=(A &&); +/// }; +/// \endcode +/// +/// cxxMethodDecl(isMoveAssignmentOperator()) matches the second method but not +/// the first one. +AST_MATCHER(CXXMethodDecl, isMoveAssignmentOperator) { + return Node.isMoveAssignmentOperator(); +} + /// \brief Matches if the given method declaration overrides another method. /// /// Given @@ -3500,6 +4019,21 @@ AST_MATCHER(CXXMethodDecl, isOverride) { return Node.size_overridden_methods() > 0 || Node.hasAttr<OverrideAttr>(); } +/// \brief Matches method declarations that are user-provided. +/// +/// Given +/// \code +/// struct S { +/// S(); // #1 +/// S(const S &) = default; // #2 +/// S(S &&) = delete; // #3 +/// }; +/// \endcode +/// cxxConstructorDecl(isUserProvided()) will match #1, but not #2 or #3. +AST_MATCHER(CXXMethodDecl, isUserProvided) { + return Node.isUserProvided(); +} + /// \brief Matches member expressions that are called with '->' as opposed /// to '.'. /// @@ -3533,6 +4067,34 @@ AST_MATCHER(QualType, isInteger) { return Node->isIntegerType(); } +/// \brief Matches QualType nodes that are of unsigned integer type. +/// +/// Given +/// \code +/// void a(int); +/// void b(unsigned long); +/// void c(double); +/// \endcode +/// functionDecl(hasAnyParameter(hasType(isInteger()))) +/// matches "b(unsigned long)", but not "a(int)" and "c(double)". +AST_MATCHER(QualType, isUnsignedInteger) { + return Node->isUnsignedIntegerType(); +} + +/// \brief Matches QualType nodes that are of signed integer type. +/// +/// Given +/// \code +/// void a(int); +/// void b(unsigned long); +/// void c(double); +/// \endcode +/// functionDecl(hasAnyParameter(hasType(isInteger()))) +/// matches "a(int)", but not "b(unsigned long)" and "c(double)". +AST_MATCHER(QualType, isSignedInteger) { + return Node->isSignedIntegerType(); +} + /// \brief Matches QualType nodes that are of character type. /// /// Given @@ -3547,6 +4109,26 @@ AST_MATCHER(QualType, isAnyCharacter) { return Node->isAnyCharacterType(); } +/// \brief Matches QualType nodes that are of any pointer type; this includes +/// the Objective-C object pointer type, which is different despite being +/// syntactically similar. +/// +/// Given +/// \code +/// int *i = nullptr; +/// +/// @interface Foo +/// @end +/// Foo *f; +/// +/// int j; +/// \endcode +/// varDecl(hasType(isAnyPointer())) +/// matches "int *i" and "Foo *f", but not "int j". +AST_MATCHER(QualType, isAnyPointer) { + return Node->isAnyPointerType(); +} + /// \brief Matches QualType nodes that are const-qualified, i.e., that /// include "top-level" const. /// @@ -3822,6 +4404,19 @@ AST_TYPE_MATCHER(ArrayType, arrayType); /// matches "_Complex float f" AST_TYPE_MATCHER(ComplexType, complexType); +/// \brief Matches any real floating-point type (float, double, long double). +/// +/// Given +/// \code +/// int i; +/// float f; +/// \endcode +/// realFloatingPointType() +/// matches "float f" but not "int i" +AST_MATCHER(Type, realFloatingPointType) { + return Node.isRealFloatingType(); +} + /// \brief Matches arrays and C99 complex types that have a specific element /// type. /// @@ -3853,18 +4448,26 @@ AST_TYPELOC_TRAVERSE_MATCHER(hasElementType, getElement, /// matches "int a[2]" AST_TYPE_MATCHER(ConstantArrayType, constantArrayType); -/// \brief Matches \c ConstantArrayType nodes that have the specified size. +/// \brief Matches nodes that have the specified size. /// /// Given /// \code /// int a[42]; /// int b[2 * 21]; /// int c[41], d[43]; +/// char *s = "abcd"; +/// wchar_t *ws = L"abcd"; +/// char *w = "a"; /// \endcode /// constantArrayType(hasSize(42)) /// matches "int a[42]" and "int b[2 * 21]" -AST_MATCHER_P(ConstantArrayType, hasSize, unsigned, N) { - return Node.getSize() == N; +/// stringLiteral(hasSize(4)) +/// matches "abcd", L"abcd" +AST_POLYMORPHIC_MATCHER_P(hasSize, + AST_POLYMORPHIC_SUPPORTED_TYPES(ConstantArrayType, + StringLiteral), + unsigned, N) { + return internal::HasSizeMatcher<NodeType>::hasSize(Node, N); } /// \brief Matches C++ arrays whose size is a value-dependent expression. @@ -3988,6 +4591,18 @@ AST_TYPE_TRAVERSE_MATCHER(hasDeducedType, getDeducedType, /// matches "int (*f)(int)" and the type of "g". AST_TYPE_MATCHER(FunctionType, functionType); +/// \brief Matches \c FunctionProtoType nodes. +/// +/// Given +/// \code +/// int (*f)(int); +/// void g(); +/// \endcode +/// functionProtoType() +/// matches "int (*f)(int)" and the type of "g" in C++ mode. +/// In C mode, "g" is not matched because it does not contain a prototype. +AST_TYPE_MATCHER(FunctionProtoType, functionProtoType); + /// \brief Matches \c ParenType nodes. /// /// Given @@ -4143,6 +4758,21 @@ AST_TYPELOC_TRAVERSE_MATCHER(pointee, getPointee, /// matches "typedef int X" AST_TYPE_MATCHER(TypedefType, typedefType); +/// \brief Matches enum types. +/// +/// Given +/// \code +/// enum C { Green }; +/// enum class S { Red }; +/// +/// C c; +/// S s; +/// \endcode +// +/// \c enumType() matches the type of the variable declarations of both \c c and +/// \c s. +AST_TYPE_MATCHER(EnumType, enumType); + /// \brief Matches template specialization types. /// /// Given @@ -4563,6 +5193,23 @@ AST_MATCHER(CXXConstructorDecl, isDefaultConstructor) { return Node.isDefaultConstructor(); } +/// \brief Matches constructors that delegate to another constructor. +/// +/// Given +/// \code +/// struct S { +/// S(); // #1 +/// S(int) {} // #2 +/// S(S &&) : S() {} // #3 +/// }; +/// S::S() : S(0) {} // #4 +/// \endcode +/// cxxConstructorDecl(isDelegatingConstructor()) will match #3 and #4, but not +/// #1 or #2. +AST_MATCHER(CXXConstructorDecl, isDelegatingConstructor) { + return Node.isDelegatingConstructor(); +} + /// \brief Matches constructor and conversion declarations that are marked with /// the explicit keyword. /// @@ -4655,6 +5302,24 @@ AST_MATCHER_P(Decl, hasAttr, attr::Kind, AttrKind) { return false; } +/// \brief Matches the return value expression of a return statement +/// +/// Given +/// \code +/// return a + b; +/// \endcode +/// hasReturnValue(binaryOperator()) +/// matches 'return a + b' +/// with binaryOperator() +/// matching 'a + b' +AST_MATCHER_P(ReturnStmt, hasReturnValue, internal::Matcher<Expr>, + InnerMatcher) { + if (const auto *RetValue = Node.getRetValue()) + return InnerMatcher.matches(*RetValue, Finder, Builder); + return false; +} + + /// \brief Matches CUDA kernel call expression. /// /// Example matches, @@ -4665,6 +5330,66 @@ const internal::VariadicDynCastAllOfMatcher< Stmt, CUDAKernelCallExpr> cudaKernelCallExpr; + +/// \brief Matches expressions that resolve to a null pointer constant, such as +/// GNU's __null, C++11's nullptr, or C's NULL macro. +/// +/// Given: +/// \code +/// void *v1 = NULL; +/// void *v2 = nullptr; +/// void *v3 = __null; // GNU extension +/// char *cp = (char *)0; +/// int *ip = 0; +/// int i = 0; +/// \endcode +/// expr(nullPointerConstant()) +/// matches the initializer for v1, v2, v3, cp, and ip. Does not match the +/// initializer for i. +AST_MATCHER_FUNCTION(internal::Matcher<Expr>, nullPointerConstant) { + return anyOf( + gnuNullExpr(), cxxNullPtrLiteralExpr(), + integerLiteral(equals(0), hasParent(expr(hasType(pointerType()))))); +} + +/// \brief Matches declaration of the function the statemenet belongs to +/// +/// Given: +/// \code +/// F& operator=(const F& o) { +/// std::copy_if(o.begin(), o.end(), begin(), [](V v) { return v > 0; }); +/// return *this; +/// } +/// \endcode +/// returnStmt(forFunction(hasName("operator="))) +/// matches 'return *this' +/// but does match 'return > 0' +AST_MATCHER_P(Stmt, forFunction, internal::Matcher<FunctionDecl>, + InnerMatcher) { + const auto &Parents = Finder->getASTContext().getParents(Node); + + llvm::SmallVector<ast_type_traits::DynTypedNode, 8> Stack(Parents.begin(), + Parents.end()); + while(!Stack.empty()) { + const auto &CurNode = Stack.back(); + Stack.pop_back(); + if(const auto *FuncDeclNode = CurNode.get<FunctionDecl>()) { + if(InnerMatcher.matches(*FuncDeclNode, Finder, Builder)) { + return true; + } + } else if(const auto *LambdaExprNode = CurNode.get<LambdaExpr>()) { + if(InnerMatcher.matches(*LambdaExprNode->getCallOperator(), + Finder, Builder)) { + return true; + } + } else { + for(const auto &Parent: Finder->getASTContext().getParents(CurNode)) + Stack.push_back(Parent); + } + } + return false; +} + } // end namespace ast_matchers } // end namespace clang diff --git a/include/clang/ASTMatchers/ASTMatchersInternal.h b/include/clang/ASTMatchers/ASTMatchersInternal.h index 1d1d7952c1667..c2c01fbd78ea3 100644 --- a/include/clang/ASTMatchers/ASTMatchersInternal.h +++ b/include/clang/ASTMatchers/ASTMatchersInternal.h @@ -46,8 +46,9 @@ #include "clang/AST/StmtCXX.h" #include "clang/AST/StmtObjC.h" #include "clang/AST/Type.h" +#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/Optional.h" -#include "llvm/ADT/VariadicFunction.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/Support/ManagedStatic.h" #include <map> #include <string> @@ -60,6 +61,62 @@ class BoundNodes; namespace internal { +/// \brief Variadic function object. +/// +/// Most of the functions below that use VariadicFunction could be implemented +/// using plain C++11 variadic functions, but the function object allows us to +/// capture it on the dynamic matcher registry. +template <typename ResultT, typename ArgT, + ResultT (*Func)(ArrayRef<const ArgT *>)> +struct VariadicFunction { + ResultT operator()() const { return Func(None); } + + template <typename... ArgsT> + ResultT operator()(const ArgT &Arg1, const ArgsT &... Args) const { + return Execute(Arg1, static_cast<const ArgT &>(Args)...); + } + + // We also allow calls with an already created array, in case the caller + // already had it. + ResultT operator()(ArrayRef<ArgT> Args) const { + SmallVector<const ArgT*, 8> InnerArgs; + for (const ArgT &Arg : Args) + InnerArgs.push_back(&Arg); + return Func(InnerArgs); + } + +private: + // Trampoline function to allow for implicit conversions to take place + // before we make the array. + template <typename... ArgsT> ResultT Execute(const ArgsT &... Args) const { + const ArgT *const ArgsArray[] = {&Args...}; + return Func(ArrayRef<const ArgT *>(ArgsArray, sizeof...(ArgsT))); + } +}; + +/// \brief Unifies obtaining the underlying type of a regular node through +/// `getType` and a TypedefNameDecl node through `getUnderlyingType`. +inline QualType getUnderlyingType(const Expr &Node) { return Node.getType(); } + +inline QualType getUnderlyingType(const ValueDecl &Node) { + return Node.getType(); +} + +inline QualType getUnderlyingType(const TypedefNameDecl &Node) { + return Node.getUnderlyingType(); +} + +/// \brief Unifies obtaining the FunctionProtoType pointer from both +/// FunctionProtoType and FunctionDecl nodes.. +inline const FunctionProtoType * +getFunctionProtoType(const FunctionProtoType &Node) { + return &Node; +} + +inline const FunctionProtoType *getFunctionProtoType(const FunctionDecl &Node) { + return Node.getType()->getAs<FunctionProtoType>(); +} + /// \brief Internal version of BoundNodes. Holds all the bound nodes. class BoundNodesMap { public: @@ -420,7 +477,7 @@ public: template <typename From> Matcher(const Matcher<From> &Other, typename std::enable_if<std::is_base_of<From, T>::value && - !std::is_same<From, T>::value>::type * = 0) + !std::is_same<From, T>::value>::type * = nullptr) : Implementation(restrictMatcher(Other.Implementation)) { assert(Implementation.getSupportedKind().isSame( ast_type_traits::ASTNodeKind::getFromNodeKind<T>())); @@ -433,7 +490,7 @@ public: Matcher(const Matcher<TypeT> &Other, typename std::enable_if< std::is_same<T, QualType>::value && - std::is_same<TypeT, Type>::value>::type* = 0) + std::is_same<TypeT, Type>::value>::type* = nullptr) : Implementation(new TypeToQualType<TypeT>(Other)) {} /// \brief Convert \c this into a \c Matcher<T> by applying dyn_cast<> to the @@ -558,32 +615,21 @@ bool matchesFirstInPointerRange(const MatcherT &Matcher, IteratorT Start, return false; } -// Metafunction to determine if type T has a member called -// getDecl. -#if defined(_MSC_VER) && !defined(__clang__) -// For MSVC, we use a weird nonstandard __if_exists statement, as it -// is not standards-conformant enough to properly compile the standard -// code below. (At least up through MSVC 2015 require this workaround) -template <typename T> struct has_getDecl { - __if_exists(T::getDecl) { - enum { value = 1 }; - } - __if_not_exists(T::getDecl) { - enum { value = 0 }; - } +// Metafunction to determine if type T has a member called getDecl. +template <typename Ty> +class has_getDecl { + typedef char yes[1]; + typedef char no[2]; + + template <typename Inner> + static yes& test(Inner *I, decltype(I->getDecl()) * = nullptr); + + template <typename> + static no& test(...); + +public: + static const bool value = sizeof(test<Ty>(nullptr)) == sizeof(yes); }; -#else -// There is a default template inheriting from "false_type". Then, a -// partial specialization inherits from "true_type". However, this -// specialization will only exist when the call to getDecl() isn't an -// error -- it vanishes by SFINAE when the member doesn't exist. -template <typename> struct type_sink_to_void { typedef void type; }; -template <typename T, typename = void> struct has_getDecl : std::false_type {}; -template <typename T> -struct has_getDecl< - T, typename type_sink_to_void<decltype(std::declval<T>().getDecl())>::type> - : std::true_type {}; -#endif /// \brief Matches overloaded operators with a specific name. /// @@ -626,10 +672,10 @@ private: /// \brief Matches named declarations with a specific name. /// -/// See \c hasName() in ASTMatchers.h for details. +/// See \c hasName() and \c hasAnyName() in ASTMatchers.h for details. class HasNameMatcher : public SingleNodeMatcherInterface<NamedDecl> { public: - explicit HasNameMatcher(StringRef Name); + explicit HasNameMatcher(std::vector<std::string> Names); bool matchesNode(const NamedDecl &Node) const override; @@ -642,15 +688,27 @@ class HasNameMatcher : public SingleNodeMatcherInterface<NamedDecl> { /// \brief Full match routine /// + /// Fast implementation for the simple case of a named declaration at + /// namespace or RecordDecl scope. + /// It is slower than matchesNodeUnqualified, but faster than + /// matchesNodeFullSlow. + bool matchesNodeFullFast(const NamedDecl &Node) const; + + /// \brief Full match routine + /// /// It generates the fully qualified name of the declaration (which is /// expensive) before trying to match. /// It is slower but simple and works on all cases. - bool matchesNodeFull(const NamedDecl &Node) const; + bool matchesNodeFullSlow(const NamedDecl &Node) const; const bool UseUnqualifiedMatch; - const std::string Name; + const std::vector<std::string> Names; }; +/// \brief Trampoline function to use VariadicFunction<> to construct a +/// HasNameMatcher. +Matcher<NamedDecl> hasAnyNameFunc(ArrayRef<const StringRef *> NameRefs); + /// \brief Matches declarations for QualType and CallExpr. /// /// Type argument DeclMatcherT is required by PolymorphicMatcherWithParam1 but @@ -737,6 +795,14 @@ private: return matchesDecl(Node.getMemberDecl(), Finder, Builder); } + /// \brief Extracts the \c LabelDecl a \c AddrLabelExpr refers to and returns + /// whether the inner matcher matches on it. + bool matchesSpecialized(const AddrLabelExpr &Node, + ASTMatchFinder *Finder, + BoundNodesTreeBuilder *Builder) const { + return matchesDecl(Node.getLabel(), Finder, Builder); + } + /// \brief Returns whether the inner matcher \c Node. Returns false if \c Node /// is \c NULL. bool matchesDecl(const Decl *Node, ASTMatchFinder *Finder, @@ -942,8 +1008,8 @@ typedef TypeList<Decl, Stmt, NestedNameSpecifier, NestedNameSpecifierLoc, /// \brief All types that are supported by HasDeclarationMatcher above. typedef TypeList<CallExpr, CXXConstructExpr, DeclRefExpr, EnumType, - InjectedClassNameType, LabelStmt, MemberExpr, QualType, - RecordType, TagType, TemplateSpecializationType, + InjectedClassNameType, LabelStmt, AddrLabelExpr, MemberExpr, + QualType, RecordType, TagType, TemplateSpecializationType, TemplateTypeParmType, TypedefType, UnresolvedUsingType> HasDeclarationSupportedTypes; @@ -1110,8 +1176,6 @@ public: /// ChildT must be an AST base type. template <typename T, typename ChildT> class HasMatcher : public WrapperMatcherInterface<T> { - static_assert(IsBaseType<ChildT>::value, - "has only accepts base type matcher"); public: explicit HasMatcher(const Matcher<ChildT> &ChildMatcher) @@ -1119,10 +1183,9 @@ public: bool matches(const T &Node, ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder) const override { - return Finder->matchesChildOf( - Node, this->InnerMatcher, Builder, - ASTMatchFinder::TK_IgnoreImplicitCastsAndParentheses, - ASTMatchFinder::BK_First); + return Finder->matchesChildOf(Node, this->InnerMatcher, Builder, + ASTMatchFinder::TK_AsIs, + ASTMatchFinder::BK_First); } }; @@ -1385,9 +1448,8 @@ inline bool ValueEqualsMatcher<FloatingLiteral, llvm::APFloat>::matchesNode( /// casted to CXXRecordDecl and all given matchers match. template <typename SourceT, typename TargetT> class VariadicDynCastAllOfMatcher - : public llvm::VariadicFunction< - BindableMatcher<SourceT>, Matcher<TargetT>, - makeDynCastAllOfComposite<SourceT, TargetT> > { + : public VariadicFunction<BindableMatcher<SourceT>, Matcher<TargetT>, + makeDynCastAllOfComposite<SourceT, TargetT>> { public: VariadicDynCastAllOfMatcher() {} }; @@ -1403,9 +1465,9 @@ public: /// \c Matcher<NestedNameSpecifier>. /// The returned matcher matches if all given matchers match. template <typename T> -class VariadicAllOfMatcher : public llvm::VariadicFunction< - BindableMatcher<T>, Matcher<T>, - makeAllOfComposite<T> > { +class VariadicAllOfMatcher + : public VariadicFunction<BindableMatcher<T>, Matcher<T>, + makeAllOfComposite<T>> { public: VariadicAllOfMatcher() {} }; @@ -1526,8 +1588,8 @@ public: new MatcherImpl<OuterT>(InnerMatcher, Getter<OuterT>::value())); } - struct Func : public llvm::VariadicFunction<Self, Matcher<InnerTBase>, - &Self::create> { + struct Func + : public VariadicFunction<Self, Matcher<InnerTBase>, &Self::create> { Func() {} }; @@ -1584,8 +1646,60 @@ struct NotEqualsBoundNodePredicate { ast_type_traits::DynTypedNode Node; }; +template <typename Ty> +struct GetBodyMatcher { + static const Stmt *get(const Ty &Node) { + return Node.getBody(); + } +}; + +template <> +inline const Stmt *GetBodyMatcher<FunctionDecl>::get(const FunctionDecl &Node) { + return Node.doesThisDeclarationHaveABody() ? Node.getBody() : nullptr; +} + +template <typename Ty> +struct HasSizeMatcher { + static bool hasSize(const Ty &Node, unsigned int N) { + return Node.getSize() == N; + } +}; + +template <> +inline bool HasSizeMatcher<StringLiteral>::hasSize( + const StringLiteral &Node, unsigned int N) { + return Node.getLength() == N; +} + +template <typename Ty> +struct GetSourceExpressionMatcher { + static const Expr *get(const Ty &Node) { + return Node.getSubExpr(); + } +}; + +template <> +inline const Expr *GetSourceExpressionMatcher<OpaqueValueExpr>::get( + const OpaqueValueExpr &Node) { + return Node.getSourceExpr(); +} + +template <typename Ty> +struct CompoundStmtMatcher { + static const CompoundStmt *get(const Ty &Node) { + return &Node; + } +}; + +template <> +inline const CompoundStmt * +CompoundStmtMatcher<StmtExpr>::get(const StmtExpr &Node) { + return Node.getSubStmt(); +} + + } // end namespace internal } // end namespace ast_matchers } // end namespace clang -#endif +#endif // LLVM_CLANG_ASTMATCHERS_ASTMATCHERSINTERNAL_H diff --git a/include/clang/Analysis/Analyses/FormatString.h b/include/clang/Analysis/Analyses/FormatString.h index 4471311a3390a..74803a295d712 100644 --- a/include/clang/Analysis/Analyses/FormatString.h +++ b/include/clang/Analysis/Analyses/FormatString.h @@ -210,11 +210,16 @@ public: unsigned getLength() const { return EndScanList ? EndScanList - Position : 1; } + void setEndScanList(const char *pos) { EndScanList = pos; } bool isIntArg() const { return (kind >= IntArgBeg && kind <= IntArgEnd) || kind == FreeBSDrArg || kind == FreeBSDyArg; } bool isUIntArg() const { return kind >= UIntArgBeg && kind <= UIntArgEnd; } bool isAnyIntArg() const { return kind >= IntArgBeg && kind <= UIntArgEnd; } + bool isDoubleArg() const { + return kind >= DoubleArgBeg && kind <= DoubleArgEnd; + } + const char *toString() const; bool isPrintfKind() const { return IsPrintf; } @@ -413,11 +418,6 @@ public: bool isObjCArg() const { return kind >= ObjCBeg && kind <= ObjCEnd; } bool isDoubleArg() const { return kind >= DoubleArgBeg && kind <= DoubleArgEnd; } - unsigned getLength() const { - // Conversion specifiers currently only are represented by - // single characters, but we be flexible. - return 1; - } static bool classof(const analyze_format_string::ConversionSpecifier *CS) { return CS->isPrintfKind(); @@ -546,8 +546,6 @@ public: ScanfConversionSpecifier(const char *pos, Kind k) : ConversionSpecifier(false, pos, k) {} - void setEndScanList(const char *pos) { EndScanList = pos; } - static bool classof(const analyze_format_string::ConversionSpecifier *CS) { return !CS->isPrintfKind(); } diff --git a/include/clang/Analysis/Analyses/ThreadSafetyUtil.h b/include/clang/Analysis/Analyses/ThreadSafetyUtil.h index 4d3402f8c00b1..6ea93653b91aa 100644 --- a/include/clang/Analysis/Analyses/ThreadSafetyUtil.h +++ b/include/clang/Analysis/Analyses/ThreadSafetyUtil.h @@ -58,18 +58,15 @@ private: llvm::BumpPtrAllocator *Allocator; }; - } // end namespace til } // end namespace threadSafety } // end namespace clang - inline void *operator new(size_t Sz, clang::threadSafety::til::MemRegionRef &R) { return R.allocate(Sz); } - namespace clang { namespace threadSafety { @@ -80,7 +77,6 @@ using clang::SourceLocation; namespace til { - // A simple fixed size array class that does not manage its own memory, // suitable for use with bump pointer allocation. template <class T> class SimpleArray { @@ -117,7 +113,6 @@ public: Data = A.allocateT<T>(Ncp); Capacity = Ncp; memcpy(Data, Odata, sizeof(T) * Size); - return; } // Reserve space for at least N more items. @@ -221,10 +216,8 @@ private: size_t Capacity; }; - } // end namespace til - // A copy on write vector. // The vector can be in one of three states: // * invalid -- no operations are permitted. @@ -346,13 +339,11 @@ private: VectorData *Data; }; - inline std::ostream& operator<<(std::ostream& ss, const StringRef str) { return ss.write(str.data(), str.size()); } - } // end namespace threadSafety } // end namespace clang -#endif // LLVM_CLANG_THREAD_SAFETY_UTIL_H +#endif // LLVM_CLANG_THREAD_SAFETY_UTIL_H diff --git a/include/clang/Analysis/AnalysisContext.h b/include/clang/Analysis/AnalysisContext.h index 931190e43a668..4324a0352e3a1 100644 --- a/include/clang/Analysis/AnalysisContext.h +++ b/include/clang/Analysis/AnalysisContext.h @@ -201,6 +201,10 @@ public: } return static_cast<T*>(data); } + + /// Returns true if the root namespace of the given declaration is the 'std' + /// C++ namespace. + static bool isInStdNamespace(const Decl *D); private: ManagedAnalysis *&getAnalysisImpl(const void* tag); diff --git a/include/clang/Analysis/ProgramPoint.h b/include/clang/Analysis/ProgramPoint.h index 6d816fd733ec5..5045194ef8646 100644 --- a/include/clang/Analysis/ProgramPoint.h +++ b/include/clang/Analysis/ProgramPoint.h @@ -595,6 +595,13 @@ public: return static_cast<const StackFrameContext *>(getData2()); } + /// Returns the entry block in the CFG for the entered function. + const CFGBlock *getEntry() const { + const StackFrameContext *CalleeCtx = getCalleeContext(); + const CFG *CalleeCFG = CalleeCtx->getCFG(); + return &(CalleeCFG->getEntry()); + } + private: friend class ProgramPoint; CallEnter() {} diff --git a/include/clang/Basic/AddressSpaces.h b/include/clang/Basic/AddressSpaces.h index 8dd75660c6728..63df61bedbc60 100644 --- a/include/clang/Basic/AddressSpaces.h +++ b/include/clang/Basic/AddressSpaces.h @@ -25,7 +25,7 @@ namespace LangAS { /// This uses a high starting offset so as not to conflict with any address /// space used by a target. enum ID { - Offset = 0xFFFF00, + Offset = 0x7FFF00, opencl_global = Offset, opencl_local, diff --git a/include/clang/Basic/Attr.td b/include/clang/Basic/Attr.td index d5ba722616444..7da1efe5ff405 100644 --- a/include/clang/Basic/Attr.td +++ b/include/clang/Basic/Attr.td @@ -82,6 +82,8 @@ def NormalVar : SubsetSubject<Var, S->getKind() != Decl::ImplicitParam && S->getKind() != Decl::ParmVar && S->getKind() != Decl::NonTypeTemplateParm}]>; +def NonParmVar : SubsetSubject<Var, + [{S->getKind() != Decl::ParmVar}]>; def NonBitField : SubsetSubject<Field, [{!S->isBitField()}]>; @@ -239,6 +241,8 @@ def MicrosoftExt : LangOpt<"MicrosoftExt">; def Borland : LangOpt<"Borland">; def CUDA : LangOpt<"CUDA">; def COnly : LangOpt<"CPlusPlus", 1>; +def OpenCL : LangOpt<"OpenCL">; +def RenderScript : LangOpt<"RenderScript">; // Defines targets for target-specific attributes. The list of strings should // specify architectures for which the target applies, based off the ArchType @@ -252,6 +256,7 @@ def TargetARM : TargetArch<["arm", "thumb"]>; def TargetMips : TargetArch<["mips", "mipsel"]>; def TargetMSP430 : TargetArch<["msp430"]>; def TargetX86 : TargetArch<["x86"]>; +def TargetAnyX86 : TargetArch<["x86", "x86_64"]>; def TargetWindows : TargetArch<["x86", "x86_64", "arm", "thumb"]> { let OSes = ["Win32"]; } @@ -310,6 +315,9 @@ class TypeAttr : Attr { let ASTNode = 0; } +/// A stmt attribute is not processed on a declaration or a type. +class StmtAttr : Attr; + /// An inheritable attribute is inherited by later redeclarations. class InheritableAttr : Attr; @@ -337,6 +345,11 @@ class TargetSpecificAttr<TargetArch target> { /// redeclarations, even when it's written on a parameter. class InheritableParamAttr : InheritableAttr; +/// An attribute which changes the ABI rules for a specific parameter. +class ParameterABIAttr : InheritableParamAttr { + let Subjects = SubjectList<[ParmVar]>; +} + /// An ignored attribute, which we parse but discard with no checking. class IgnoredAttr : Attr { let Ignored = 1; @@ -349,6 +362,14 @@ class IgnoredAttr : Attr { // Attributes begin here // +def AbiTag : Attr { + let Spellings = [GCC<"abi_tag">]; + let Args = [VariadicStringArgument<"Tags">]; + let Subjects = SubjectList<[Struct, Var, Function, Namespace], ErrorDiag, + "ExpectedStructClassVariableFunctionOrInlineNamespace">; + let Documentation = [AbiTagsDocs]; +} + def AddressSpace : TypeAttr { let Spellings = [GNU<"address_space">]; let Args = [IntArgument<"AddressSpace">]; @@ -407,6 +428,22 @@ def AlwaysInline : InheritableAttr { let Documentation = [Undocumented]; } +def XRayInstrument : InheritableAttr { + let Spellings = [GNU<"xray_always_instrument">, + CXX11<"clang", "xray_always_instrument">, + GNU<"xray_never_instrument">, + CXX11<"clang", "xray_never_instrument">]; + let Subjects = SubjectList<[CXXMethod, ObjCMethod, Function], WarnDiag, + "ExpectedFunctionOrMethod">; + let Accessors = [Accessor<"alwaysXRayInstrument", + [GNU<"xray_always_instrument">, + CXX11<"clang", "xray_always_instrument">]>, + Accessor<"neverXRayInstrument", + [GNU<"xray_never_instrument">, + CXX11<"clang", "xray_never_instrument">]>]; + let Documentation = [XRayDocs]; +} + def TLSModel : InheritableAttr { let Spellings = [GCC<"tls_model">]; let Subjects = SubjectList<[TLSVar], ErrorDiag, "ExpectedTLSVar">; @@ -426,8 +463,8 @@ def Annotate : InheritableParamAttr { } def ARMInterrupt : InheritableAttr, TargetSpecificAttr<TargetARM> { - // NOTE: If you add any additional spellings, MSP430Interrupt's and - // MipsInterrupt's spellings must match. + // NOTE: If you add any additional spellings, MSP430Interrupt's, + // MipsInterrupt's and AnyX86Interrupt's spellings must match. let Spellings = [GNU<"interrupt">]; let Args = [EnumArgument<"Interrupt", "InterruptType", ["IRQ", "FIQ", "SWI", "ABORT", "UNDEF", ""], @@ -449,17 +486,18 @@ def Availability : InheritableAttr { let Spellings = [GNU<"availability">]; let Args = [IdentifierArgument<"platform">, VersionArgument<"introduced">, VersionArgument<"deprecated">, VersionArgument<"obsoleted">, - BoolArgument<"unavailable">, StringArgument<"message">]; + BoolArgument<"unavailable">, StringArgument<"message">, + BoolArgument<"strict">, StringArgument<"replacement">]; let AdditionalMembers = [{static llvm::StringRef getPrettyPlatformName(llvm::StringRef Platform) { return llvm::StringSwitch<llvm::StringRef>(Platform) .Case("android", "Android") .Case("ios", "iOS") - .Case("macosx", "OS X") + .Case("macos", "macOS") .Case("tvos", "tvOS") .Case("watchos", "watchOS") .Case("ios_app_extension", "iOS (App Extension)") - .Case("macosx_app_extension", "OS X (App Extension)") + .Case("macos_app_extension", "macOS (App Extension)") .Case("tvos_app_extension", "tvOS (App Extension)") .Case("watchos_app_extension", "watchOS (App Extension)") .Default(llvm::StringRef()); @@ -654,20 +692,27 @@ def OpenCLKernel : InheritableAttr { let Documentation = [Undocumented]; } +def OpenCLUnrollHint : InheritableAttr { + let Spellings = [GNU<"opencl_unroll_hint">]; + let Args = [UnsignedArgument<"UnrollHint">]; + let Documentation = [OpenCLUnrollHintDocs]; +} + // This attribute is both a type attribute, and a declaration attribute (for // parameter variables). -def OpenCLImageAccess : Attr { +def OpenCLAccess : Attr { let Spellings = [Keyword<"__read_only">, Keyword<"read_only">, Keyword<"__write_only">, Keyword<"write_only">, Keyword<"__read_write">, Keyword<"read_write">]; - let Subjects = SubjectList<[ParmVar], ErrorDiag>; + let Subjects = SubjectList<[ParmVar, TypedefName], ErrorDiag, + "ExpectedParameterOrTypedef">; let Accessors = [Accessor<"isReadOnly", [Keyword<"__read_only">, Keyword<"read_only">]>, Accessor<"isReadWrite", [Keyword<"__read_write">, Keyword<"read_write">]>, Accessor<"isWriteOnly", [Keyword<"__write_only">, Keyword<"write_only">]>]; - let Documentation = [Undocumented]; + let Documentation = [OpenCLAccessDocs]; } def OpenCLPrivateAddressSpace : TypeAttr { @@ -695,11 +740,29 @@ def OpenCLGenericAddressSpace : TypeAttr { let Documentation = [OpenCLAddressSpaceGenericDocs]; } +def OpenCLNoSVM : Attr { + let Spellings = [GNU<"nosvm">]; + let Subjects = SubjectList<[Var]>; + let Documentation = [OpenCLNoSVMDocs]; + let LangOpts = [OpenCL]; + let ASTNode = 0; +} + +def RenderScriptKernel : Attr { + let Spellings = [GNU<"kernel">]; + let Subjects = SubjectList<[Function]>; + let Documentation = [RenderScriptKernelAttributeDocs]; + let LangOpts = [RenderScript]; +} + def Deprecated : InheritableAttr { let Spellings = [GCC<"deprecated">, Declspec<"deprecated">, CXX11<"","deprecated", 201309>]; - let Args = [StringArgument<"Message", 1>]; - let Documentation = [Undocumented]; + let Args = [StringArgument<"Message", 1>, + // An optional string argument that enables us to provide a + // Fix-It. + StringArgument<"Replacement", 1>]; + let Documentation = [DeprecatedDocs]; } def Destructor : InheritableAttr { @@ -709,6 +772,12 @@ def Destructor : InheritableAttr { let Documentation = [Undocumented]; } +def EmptyBases : InheritableAttr, TargetSpecificAttr<TargetMicrosoftCXXABI> { + let Spellings = [Declspec<"empty_bases">]; + let Subjects = SubjectList<[CXXRecord]>; + let Documentation = [EmptyBasesDocs]; +} + def EnableIf : InheritableAttr { let Spellings = [GNU<"enable_if">]; let Subjects = SubjectList<[Function]>; @@ -725,8 +794,9 @@ def ExtVectorType : Attr { let Documentation = [Undocumented]; } -def FallThrough : Attr { - let Spellings = [CXX11<"clang", "fallthrough">]; +def FallThrough : StmtAttr { + let Spellings = [CXX11<"", "fallthrough", 201603>, + CXX11<"clang", "fallthrough">]; // let Subjects = [NullStmt]; let Documentation = [FallthroughDocs]; } @@ -818,12 +888,26 @@ def IBOutletCollection : InheritableAttr { let Documentation = [Undocumented]; } +def IFunc : Attr { + let Spellings = [GCC<"ifunc">]; + let Args = [StringArgument<"Resolver">]; + let Subjects = SubjectList<[Function]>; + let Documentation = [IFuncDocs]; +} + def Restrict : InheritableAttr { let Spellings = [Declspec<"restrict">, GCC<"malloc">]; let Subjects = SubjectList<[Function]>; let Documentation = [Undocumented]; } +def LayoutVersion : InheritableAttr, TargetSpecificAttr<TargetMicrosoftCXXABI> { + let Spellings = [Declspec<"layout_version">]; + let Args = [UnsignedArgument<"Version">]; + let Subjects = SubjectList<[CXXRecord]>; + let Documentation = [LayoutVersionDocs]; +} + def MaxFieldAlignment : InheritableAttr { // This attribute has no spellings as it is only ever created implicitly. let Spellings = []; @@ -845,8 +929,8 @@ def MSABI : InheritableAttr { } def MSP430Interrupt : InheritableAttr, TargetSpecificAttr<TargetMSP430> { - // NOTE: If you add any additional spellings, ARMInterrupt's and - // MipsInterrupt's spellings must match. + // NOTE: If you add any additional spellings, ARMInterrupt's, MipsInterrupt's + // and AnyX86Interrupt's spellings must match. let Spellings = [GNU<"interrupt">]; let Args = [UnsignedArgument<"Number">]; let ParseKind = "Interrupt"; @@ -861,8 +945,8 @@ def Mips16 : InheritableAttr, TargetSpecificAttr<TargetMips> { } def MipsInterrupt : InheritableAttr, TargetSpecificAttr<TargetMips> { - // NOTE: If you add any additional spellings, ARMInterrupt's and - // MSP430Interrupt's spellings must match. + // NOTE: If you add any additional spellings, ARMInterrupt's, + // MSP430Interrupt's and AnyX86Interrupt's spellings must match. let Spellings = [GNU<"interrupt">]; let Subjects = SubjectList<[Function]>; let Args = [EnumArgument<"Interrupt", "InterruptType", @@ -878,6 +962,8 @@ def MipsInterrupt : InheritableAttr, TargetSpecificAttr<TargetMips> { def Mode : Attr { let Spellings = [GCC<"mode">]; + let Subjects = SubjectList<[Var, Enum, TypedefName, Field], ErrorDiag, + "ExpectedVariableEnumFieldOrTypedef">; let Args = [IdentifierArgument<"Mode">]; let Documentation = [Undocumented]; } @@ -927,7 +1013,9 @@ def NoCommon : InheritableAttr { def NoDebug : InheritableAttr { let Spellings = [GCC<"nodebug">]; - let Documentation = [Undocumented]; + let Subjects = SubjectList<[FunctionLike, ObjCMethod, NonParmVar], WarnDiag, + "ExpectedVariableOrFunction">; + let Documentation = [NoDebugDocs]; } def NoDuplicate : InheritableAttr { @@ -1202,6 +1290,12 @@ def ObjCRuntimeName : Attr { let Documentation = [ObjCRuntimeNameDocs]; } +def ObjCRuntimeVisible : Attr { + let Spellings = [GNU<"objc_runtime_visible">]; + let Subjects = SubjectList<[ObjCInterface], ErrorDiag>; + let Documentation = [ObjCRuntimeVisibleDocs]; +} + def ObjCBoxable : Attr { let Spellings = [GNU<"objc_boxable">]; let Subjects = SubjectList<[Record], ErrorDiag, "ExpectedStructOrUnion">; @@ -1325,6 +1419,27 @@ def StdCall : InheritableAttr { let Documentation = [StdCallDocs]; } +def SwiftCall : InheritableAttr { + let Spellings = [GCC<"swiftcall">]; +// let Subjects = SubjectList<[Function]>; + let Documentation = [SwiftCallDocs]; +} + +def SwiftContext : ParameterABIAttr { + let Spellings = [GCC<"swift_context">]; + let Documentation = [SwiftContextDocs]; +} + +def SwiftErrorResult : ParameterABIAttr { + let Spellings = [GCC<"swift_error_result">]; + let Documentation = [SwiftErrorResultDocs]; +} + +def SwiftIndirectResult : ParameterABIAttr { + let Spellings = [GCC<"swift_indirect_result">]; + let Documentation = [SwiftIndirectResultDocs]; +} + def SysVABI : InheritableAttr { let Spellings = [GCC<"sysv_abi">]; // let Subjects = [Function, ObjCMethod]; @@ -1351,6 +1466,16 @@ def Pascal : InheritableAttr { let Documentation = [Undocumented]; } +def PreserveMost : InheritableAttr { + let Spellings = [GNU<"preserve_most">]; + let Documentation = [PreserveMostDocs]; +} + +def PreserveAll : InheritableAttr { + let Spellings = [GNU<"preserve_all">]; + let Documentation = [PreserveAllDocs]; +} + def Target : InheritableAttr { let Spellings = [GCC<"target">]; let Args = [StringArgument<"featuresStr">]; @@ -1436,11 +1561,11 @@ def ObjCRequiresPropertyDefs : InheritableAttr { } def Unused : InheritableAttr { - let Spellings = [GCC<"unused">]; - let Subjects = SubjectList<[Var, ObjCIvar, Type, Label, Field, ObjCMethod, - FunctionLike], WarnDiag, - "ExpectedVariableFunctionOrLabel">; - let Documentation = [Undocumented]; + let Spellings = [CXX11<"", "maybe_unused", 201603>, GCC<"unused">]; + let Subjects = SubjectList<[Var, ObjCIvar, Type, Enum, EnumConstant, Label, + Field, ObjCMethod, FunctionLike], WarnDiag, + "ExpectedForMaybeUnused">; + let Documentation = [WarnMaybeUnusedDocs]; } def Used : InheritableAttr { @@ -1501,11 +1626,12 @@ def WarnUnused : InheritableAttr { } def WarnUnusedResult : InheritableAttr { - let Spellings = [GCC<"warn_unused_result">, - CXX11<"clang", "warn_unused_result">]; - let Subjects = SubjectList<[ObjCMethod, CXXRecord, FunctionLike], WarnDiag, - "ExpectedFunctionMethodOrClass">; - let Documentation = [Undocumented]; + let Spellings = [CXX11<"", "nodiscard", 201603>, + CXX11<"clang", "warn_unused_result">, + GCC<"warn_unused_result">]; + let Subjects = SubjectList<[ObjCMethod, Enum, CXXRecord, FunctionLike], + WarnDiag, "ExpectedFunctionMethodEnumOrClass">; + let Documentation = [WarnUnusedResultsDocs]; } def Weak : InheritableAttr { @@ -1527,6 +1653,22 @@ def WeakRef : InheritableAttr { let Documentation = [Undocumented]; } +def LTOVisibilityPublic : InheritableAttr { + let Spellings = [CXX11<"clang", "lto_visibility_public">]; + let Subjects = SubjectList<[Record]>; + let Documentation = [LTOVisibilityDocs]; +} + +def AnyX86Interrupt : InheritableAttr, TargetSpecificAttr<TargetAnyX86> { + // NOTE: If you add any additional spellings, ARMInterrupt's, + // MSP430Interrupt's and MipsInterrupt's spellings must match. + let Spellings = [GNU<"interrupt">]; + let Subjects = SubjectList<[HasFunctionProto]>; + let ParseKind = "Interrupt"; + let HasCustomParsing = 1; + let Documentation = [AnyX86InterruptDocs]; +} + def X86ForceAlignArgPointer : InheritableAttr, TargetSpecificAttr<TargetX86> { let Spellings = [GNU<"force_align_arg_pointer">]; // Technically, this appertains to a FunctionDecl, but the target-specific @@ -1945,14 +2087,14 @@ def MSStruct : InheritableAttr { def DLLExport : InheritableAttr, TargetSpecificAttr<TargetWindows> { let Spellings = [Declspec<"dllexport">, GCC<"dllexport">]; - let Subjects = SubjectList<[Function, Var, CXXRecord]>; - let Documentation = [Undocumented]; + let Subjects = SubjectList<[Function, Var, CXXRecord, ObjCInterface]>; + let Documentation = [DLLExportDocs]; } def DLLImport : InheritableAttr, TargetSpecificAttr<TargetWindows> { let Spellings = [Declspec<"dllimport">, GCC<"dllimport">]; - let Subjects = SubjectList<[Function, Var, CXXRecord]>; - let Documentation = [Undocumented]; + let Subjects = SubjectList<[Function, Var, CXXRecord, ObjCInterface]>; + let Documentation = [DLLImportDocs]; } def SelectAny : InheritableAttr { @@ -2055,10 +2197,6 @@ def InitSeg : Attr { }]; } -def Unaligned : IgnoredAttr { - let Spellings = [Keyword<"__unaligned">]; -} - def LoopHint : Attr { /// #pragma clang loop <option> directive /// vectorize: vectorizes loop operations if State == Enable. @@ -2067,6 +2205,7 @@ def LoopHint : Attr { /// interleave_count: interleaves 'Value' loop interations. /// unroll: fully unroll loop if State == Enable. /// unroll_count: unrolls loop 'Value' times. + /// distribute: attempt to distribute loop if State == Enable /// #pragma unroll <argument> directive /// <no arg>: fully unrolls loop. @@ -2079,9 +2218,9 @@ def LoopHint : Attr { /// State of the loop optimization specified by the spelling. let Args = [EnumArgument<"Option", "OptionType", ["vectorize", "vectorize_width", "interleave", "interleave_count", - "unroll", "unroll_count"], + "unroll", "unroll_count", "distribute"], ["Vectorize", "VectorizeWidth", "Interleave", "InterleaveCount", - "Unroll", "UnrollCount"]>, + "Unroll", "UnrollCount", "Distribute"]>, EnumArgument<"State", "LoopHintState", ["enable", "disable", "numeric", "assume_safety", "full"], ["Enable", "Disable", "Numeric", "AssumeSafety", "Full"]>, @@ -2096,6 +2235,7 @@ def LoopHint : Attr { case InterleaveCount: return "interleave_count"; case Unroll: return "unroll"; case UnrollCount: return "unroll_count"; + case Distribute: return "distribute"; } llvm_unreachable("Unhandled LoopHint option."); } @@ -2165,6 +2305,98 @@ def OMPThreadPrivateDecl : InheritableAttr { let Documentation = [Undocumented]; } +def OMPCaptureNoInit : InheritableAttr { + // This attribute has no spellings as it is only ever created implicitly. + let Spellings = []; + let SemaHandler = 0; + let Documentation = [Undocumented]; +} + +def OMPDeclareSimdDecl : Attr { + let Spellings = [Pragma<"omp", "declare simd">]; + let Subjects = SubjectList<[Function]>; + let SemaHandler = 0; + let HasCustomParsing = 1; + let Documentation = [OMPDeclareSimdDocs]; + let Args = [ + EnumArgument<"BranchState", "BranchStateTy", + [ "", "inbranch", "notinbranch" ], + [ "BS_Undefined", "BS_Inbranch", "BS_Notinbranch" ]>, + ExprArgument<"Simdlen">, VariadicExprArgument<"Uniforms">, + VariadicExprArgument<"Aligneds">, VariadicExprArgument<"Alignments">, + VariadicExprArgument<"Linears">, VariadicUnsignedArgument<"Modifiers">, + VariadicExprArgument<"Steps"> + ]; + let AdditionalMembers = [{ + void printPrettyPragma(raw_ostream & OS, const PrintingPolicy &Policy) + const { + if (getBranchState() != BS_Undefined) + OS << ConvertBranchStateTyToStr(getBranchState()) << " "; + if (auto *E = getSimdlen()) { + OS << "simdlen("; + E->printPretty(OS, nullptr, Policy); + OS << ") "; + } + if (uniforms_size() > 0) { + OS << "uniform"; + StringRef Sep = "("; + for (auto *E : uniforms()) { + OS << Sep; + E->printPretty(OS, nullptr, Policy); + Sep = ", "; + } + OS << ") "; + } + alignments_iterator NI = alignments_begin(); + for (auto *E : aligneds()) { + OS << "aligned("; + E->printPretty(OS, nullptr, Policy); + if (*NI) { + OS << ": "; + (*NI)->printPretty(OS, nullptr, Policy); + } + OS << ") "; + ++NI; + } + steps_iterator I = steps_begin(); + modifiers_iterator MI = modifiers_begin(); + for (auto *E : linears()) { + OS << "linear("; + if (*MI != OMPC_LINEAR_unknown) + OS << getOpenMPSimpleClauseTypeName(OMPC_linear, *MI) << "("; + E->printPretty(OS, nullptr, Policy); + if (*MI != OMPC_LINEAR_unknown) + OS << ")"; + if (*I) { + OS << ": "; + (*I)->printPretty(OS, nullptr, Policy); + } + OS << ") "; + ++I; + ++MI; + } + } + }]; +} + +def OMPDeclareTargetDecl : Attr { + let Spellings = [Pragma<"omp", "declare target">]; + let SemaHandler = 0; + let Documentation = [OMPDeclareTargetDocs]; + let Args = [ + EnumArgument<"MapType", "MapTypeTy", + [ "to", "link" ], + [ "MT_To", "MT_Link" ]> + ]; + let AdditionalMembers = [{ + void printPrettyPragma(raw_ostream &OS, const PrintingPolicy &Policy) const { + // Use fake syntax because it is for testing and debugging purpose only. + if (getMapType() != MT_To) + OS << ConvertMapTypeTyToStr(getMapType()) << " "; + } + }]; +} + def InternalLinkage : InheritableAttr { let Spellings = [GNU<"internal_linkage">, CXX11<"clang", "internal_linkage">]; let Subjects = SubjectList<[Var, Function, CXXRecord]>; diff --git a/include/clang/Basic/AttrDocs.td b/include/clang/Basic/AttrDocs.td index 2567d55eb7e0d..d0342bc6038a9 100644 --- a/include/clang/Basic/AttrDocs.td +++ b/include/clang/Basic/AttrDocs.td @@ -67,6 +67,34 @@ TLS models are mutually exclusive. }]; } +def DLLExportDocs : Documentation { + let Category = DocCatVariable; + let Content = [{ +The ``__declspec(dllexport)`` attribute declares a variable, function, or +Objective-C interface to be exported from the module. It is available under the +``-fdeclspec`` flag for compatibility with various compilers. The primary use +is for COFF object files which explicitly specify what interfaces are available +for external use. See the dllexport_ documentation on MSDN for more +information. + +.. _dllexport: https://msdn.microsoft.com/en-us/library/3y1sfaz2.aspx + }]; +} + +def DLLImportDocs : Documentation { + let Category = DocCatVariable; + let Content = [{ +The ``__declspec(dllimport)`` attribute declares a variable, function, or +Objective-C interface to be imported from an external module. It is available +under the ``-fdeclspec`` flag for compatibility with various compilers. The +primary use is for COFF object files which explicitly specify what interfaces +are imported from external modules. See the dllimport_ documentation on MSDN +for more information. + +.. _dllimport: https://msdn.microsoft.com/en-us/library/3y1sfaz2.aspx + }]; +} + def ThreadDocs : Documentation { let Category = DocCatVariable; let Content = [{ @@ -260,6 +288,55 @@ only a single candidate. In a call to g(1, 1), the call is ambiguous even though not ODR-equivalent. Query for this feature with ``__has_attribute(enable_if)``. + +Note that functions with one or more ``enable_if`` attributes may not have +their address taken, unless all of the conditions specified by said +``enable_if`` are constants that evaluate to ``true``. For example: + +.. code-block:: c + + const int TrueConstant = 1; + const int FalseConstant = 0; + int f(int a) __attribute__((enable_if(a > 0, ""))); + int g(int a) __attribute__((enable_if(a == 0 || a != 0, ""))); + int h(int a) __attribute__((enable_if(1, ""))); + int i(int a) __attribute__((enable_if(TrueConstant, ""))); + int j(int a) __attribute__((enable_if(FalseConstant, ""))); + + void fn() { + int (*ptr)(int); + ptr = &f; // error: 'a > 0' is not always true + ptr = &g; // error: 'a == 0 || a != 0' is not a truthy constant + ptr = &h; // OK: 1 is a truthy constant + ptr = &i; // OK: 'TrueConstant' is a truthy constant + ptr = &j; // error: 'FalseConstant' is a constant, but not truthy + } + +Because ``enable_if`` evaluation happens during overload resolution, +``enable_if`` may give unintuitive results when used with templates, depending +on when overloads are resolved. In the example below, clang will emit a +diagnostic about no viable overloads for ``foo`` in ``bar``, but not in ``baz``: + +.. code-block:: c++ + + double foo(int i) __attribute__((enable_if(i > 0, ""))); + void *foo(int i) __attribute__((enable_if(i <= 0, ""))); + template <int I> + auto bar() { return foo(I); } + + template <typename T> + auto baz() { return foo(T::number); } + + struct WithNumber { constexpr static int number = 1; }; + void callThem() { + bar<sizeof(WithNumber)>(); + baz<WithNumber>(); + } + +This is because, in ``bar``, ``foo`` is resolved prior to template +instantiation, so the value for ``I`` isn't known (thus, both ``enable_if`` +conditions for ``foo`` fail). However, in ``baz``, ``foo`` is resolved during +template instantiation, so the value for ``T::number`` is known. }]; } @@ -471,6 +548,15 @@ Query for this feature with ``__has_attribute(objc_method_family)``. }]; } +def NoDebugDocs : Documentation { + let Category = DocCatVariable; + let Content = [{ +The ``nodebug`` attribute allows you to suppress debugging information for a +function or method, or for a variable that is not a parameter or a non-static +data member. + }]; +} + def NoDuplicateDocs : Documentation { let Category = DocCatFunction; let Content = [{ @@ -589,6 +675,13 @@ can only be placed before an @protocol or @interface declaration: }]; } +def ObjCRuntimeVisibleDocs : Documentation { + let Category = DocCatFunction; + let Content = [{ +This attribute specifies that the Objective-C class to which it applies is visible to the Objective-C runtime but not to the linker. Classes annotated with this attribute cannot be subclassed and cannot have categories defined for them. + }]; +} + def ObjCBoxableDocs : Documentation { let Category = DocCatFunction; let Content = [{ @@ -626,7 +719,7 @@ the function declaration for a hypothetical function ``f``: .. code-block:: c++ - void f(void) __attribute__((availability(macosx,introduced=10.4,deprecated=10.6,obsoleted=10.7))); + void f(void) __attribute__((availability(macos,introduced=10.4,deprecated=10.6,obsoleted=10.7))); The availability attribute states that ``f`` was introduced in Mac OS X 10.4, deprecated in Mac OS X 10.6, and obsoleted in Mac OS X 10.7. This information @@ -661,6 +754,11 @@ message=\ *string-literal* error about use of a deprecated or obsoleted declaration. Useful to direct users to replacement APIs. +replacement=\ *string-literal* + Additional message text that Clang will use to provide Fix-It when emitting + a warning about use of a deprecated declaration. The Fix-It will replace + the deprecated declaration with the new declaration specified. + Multiple availability attributes can be placed on a declaration, which may correspond to different platforms. Only the availability attribute with the platform corresponding to the target platform will be used; any others will be @@ -673,9 +771,11 @@ are: the ``-mios-version-min=*version*`` or ``-miphoneos-version-min=*version*`` command-line arguments. -``macosx`` +``macos`` Apple's Mac OS X operating system. The minimum deployment target is specified by the ``-mmacosx-version-min=*version*`` command-line argument. + ``macosx`` is supported for backward-compatibility reasons, but it is + deprecated. ``tvos`` Apple's tvOS operating system. The minimum deployment target is specified by @@ -685,15 +785,21 @@ are: Apple's watchOS operating system. The minimum deployment target is specified by the ``-mwatchos-version-min=*version*`` command-line argument. -A declaration can be used even when deploying back to a platform version prior -to when the declaration was introduced. When this happens, the declaration is -`weakly linked +A declaration can typically be used even when deploying back to a platform +version prior to when the declaration was introduced. When this happens, the +declaration is `weakly linked <https://developer.apple.com/library/mac/#documentation/MacOSX/Conceptual/BPFrameworks/Concepts/WeakLinking.html>`_, as if the ``weak_import`` attribute were added to the declaration. A weakly-linked declaration may or may not be present a run-time, and a program can determine whether the declaration is present by checking whether the address of that declaration is non-NULL. +The flag ``strict`` disallows using API when deploying back to a +platform version prior to when the declaration was introduced. An +attempt to use such API before its introduction causes a hard error. +Weakly-linking is almost always a better API choice, since it allows +users to query availability at runtime. + If there are multiple declarations of the same entity, the availability attributes must either match on a per-platform basis or later declarations must not have availability attributes for that @@ -701,33 +807,85 @@ platform. For example: .. code-block:: c - void g(void) __attribute__((availability(macosx,introduced=10.4))); - void g(void) __attribute__((availability(macosx,introduced=10.4))); // okay, matches + void g(void) __attribute__((availability(macos,introduced=10.4))); + void g(void) __attribute__((availability(macos,introduced=10.4))); // okay, matches void g(void) __attribute__((availability(ios,introduced=4.0))); // okay, adds a new platform - void g(void); // okay, inherits both macosx and ios availability from above. - void g(void) __attribute__((availability(macosx,introduced=10.5))); // error: mismatch + void g(void); // okay, inherits both macos and ios availability from above. + void g(void) __attribute__((availability(macos,introduced=10.5))); // error: mismatch When one method overrides another, the overriding method can be more widely available than the overridden method, e.g.,: .. code-block:: objc @interface A - - (id)method __attribute__((availability(macosx,introduced=10.4))); - - (id)method2 __attribute__((availability(macosx,introduced=10.4))); + - (id)method __attribute__((availability(macos,introduced=10.4))); + - (id)method2 __attribute__((availability(macos,introduced=10.4))); @end @interface B : A - - (id)method __attribute__((availability(macosx,introduced=10.3))); // okay: method moved into base class later - - (id)method __attribute__((availability(macosx,introduced=10.5))); // error: this method was available via the base class in 10.4 + - (id)method __attribute__((availability(macos,introduced=10.3))); // okay: method moved into base class later + - (id)method __attribute__((availability(macos,introduced=10.5))); // error: this method was available via the base class in 10.4 @end }]; } +def WarnMaybeUnusedDocs : Documentation { + let Category = DocCatVariable; + let Heading = "maybe_unused, unused, gnu::unused"; + let Content = [{ +When passing the ``-Wunused`` flag to Clang, entities that are unused by the +program may be diagnosed. The ``[[maybe_unused]]`` (or +``__attribute__((unused))``) attribute can be used to silence such diagnostics +when the entity cannot be removed. For instance, a local variable may exist +solely for use in an ``assert()`` statement, which makes the local variable +unused when ``NDEBUG`` is defined. + +The attribute may be applied to the declaration of a class, a typedef, a +variable, a function or method, a function parameter, an enumeration, an +enumerator, a non-static data member, or a label. + +.. code-block: c++ + #include <cassert>
+
+ [[maybe_unused]] void f([[maybe_unused]] bool thing1,
+ [[maybe_unused]] bool thing2) {
+ [[maybe_unused]] bool b = thing1 && thing2;
+ assert(b);
+ } + }]; +} + +def WarnUnusedResultsDocs : Documentation { + let Category = DocCatFunction; + let Heading = "nodiscard, warn_unused_result, clang::warn_unused_result, gnu::warn_unused_result"; + let Content = [{ +Clang supports the ability to diagnose when the results of a function call +expression are discarded under suspicious circumstances. A diagnostic is +generated when a function or its return type is marked with ``[[nodiscard]]`` +(or ``__attribute__((warn_unused_result))``) and the function call appears as a +potentially-evaluated discarded-value expression that is not explicitly cast to +`void`. + +.. code-block: c++ + struct [[nodiscard]] error_info { /*...*/ };
+ error_info enable_missile_safety_mode();
+
+ void launch_missiles();
+ void test_missiles() {
+ enable_missile_safety_mode(); // diagnoses
+ launch_missiles();
+ }
+ error_info &foo();
+ void f() { foo(); } // Does not diagnose, error_info is a reference. + }]; +} + def FallthroughDocs : Documentation { let Category = DocCatStmt; + let Heading = "fallthrough, clang::fallthrough"; let Content = [{ -The ``clang::fallthrough`` attribute is used along with the -``-Wimplicit-fallthrough`` argument to annotate intentional fall-through +The ``fallthrough`` (or ``clang::fallthrough``) attribute is used +to annotate intentional fall-through between switch labels. It can only be applied to a null statement placed at a point of execution between any statement and the next switch label. It is common to mark these places with a specific comment, but this attribute is @@ -738,6 +896,10 @@ control-flow statements like ``break;``, so it can be placed in most places where ``break;`` can, but only if there are no statements on the execution path between it and the next switch label. +By default, Clang does not warn on unannotated fallthrough from one ``switch`` +case to another. Diagnostics on fallthrough without a corresponding annotation +can be enabled with the ``-Wimplicit-fallthrough`` argument. + Here is an example: .. code-block:: c++ @@ -1421,6 +1583,26 @@ manipulating bits of the enumerator when issuing warnings. }]; } +def EmptyBasesDocs : Documentation { + let Category = DocCatType; + let Content = [{ +The empty_bases attribute permits the compiler to utilize the +empty-base-optimization more frequently. +This attribute only applies to struct, class, and union types. +It is only supported when using the Microsoft C++ ABI. + }]; +} + +def LayoutVersionDocs : Documentation { + let Category = DocCatType; + let Content = [{ +The layout_version attribute requests that the compiler utilize the class +layout rules of a particular compiler version. +This attribute only applies to struct, class, and union types. +It is only supported when using the Microsoft C++ ABI. + }]; +} + def MSInheritanceDocs : Documentation { let Category = DocCatType; let Heading = "__single_inhertiance, __multiple_inheritance, __virtual_inheritance"; @@ -1562,6 +1744,46 @@ for further details including limitations of the unroll hints. }]; } +def OpenCLUnrollHintDocs : Documentation { + let Category = DocCatStmt; + let Heading = "__attribute__((opencl_unroll_hint))"; + let Content = [{ +The opencl_unroll_hint attribute qualifier can be used to specify that a loop +(for, while and do loops) can be unrolled. This attribute qualifier can be +used to specify full unrolling or partial unrolling by a specified amount. +This is a compiler hint and the compiler may ignore this directive. See +`OpenCL v2.0 <https://www.khronos.org/registry/cl/specs/opencl-2.0.pdf>`_ +s6.11.5 for details. + }]; +} + +def OpenCLAccessDocs : Documentation { + let Category = DocCatStmt; + let Heading = "__read_only, __write_only, __read_write (read_only, write_only, read_write)"; + let Content = [{ +The access qualifiers must be used with image object arguments or pipe arguments +to declare if they are being read or written by a kernel or function. + +The read_only/__read_only, write_only/__write_only and read_write/__read_write +names are reserved for use as access qualifiers and shall not be used otherwise. + +.. code-block:: c + + kernel void + foo (read_only image2d_t imageA, + write_only image2d_t imageB) { + ... + } + +In the above example imageA is a read-only 2D image object, and imageB is a +write-only 2D image object. + +The read_write (or __read_write) qualifier can not be used with pipe. + +More details can be found in the OpenCL C language Spec v2.0, Section 6.6. + }]; +} + def DocOpenCLAddressSpaces : DocumentationCategory<"OpenCL Address Spaces"> { let Content = [{ The address space qualifier may be used to specify the region of memory that is @@ -1643,6 +1865,17 @@ cannot point to the private address space. }]; } +def OpenCLNoSVMDocs : Documentation { + let Category = DocCatVariable; + let Content = [{ +OpenCL 2.0 supports the optional ``__attribute__((nosvm))`` qualifier for +pointer variable. It informs the compiler that the pointer does not refer +to a shared virtual memory region. See OpenCL v2.0 s6.7.2 for details. + +Since it is not widely used and has been removed from OpenCL 2.1, it is ignored +by Clang. + }]; +} def NullabilityDocs : DocumentationCategory<"Nullability Attributes"> { let Content = [{ Whether a particular pointer may be "null" is an important concern when working with pointers in the C family of languages. The various nullability attributes indicate whether a particular pointer can be null or not, which makes APIs more expressive and can help static analysis tools identify bugs involving null pointers. Clang supports several kinds of nullability attributes: the ``nonnull`` and ``returns_nonnull`` attributes indicate which function or method parameters and result types can never be null, while nullability type qualifiers indicate which pointer types can be null (``_Nullable``) or cannot be null (``_Nonnull``). @@ -1758,6 +1991,58 @@ arguments, with arbitrary offsets. }]; } +def OMPDeclareSimdDocs : Documentation { + let Category = DocCatFunction; + let Heading = "#pragma omp declare simd"; + let Content = [{ +The `declare simd` construct can be applied to a function to enable the creation +of one or more versions that can process multiple arguments using SIMD +instructions from a single invocation in a SIMD loop. The `declare simd` +directive is a declarative directive. There may be multiple `declare simd` +directives for a function. The use of a `declare simd` construct on a function +enables the creation of SIMD versions of the associated function that can be +used to process multiple arguments from a single invocation from a SIMD loop +concurrently. +The syntax of the `declare simd` construct is as follows: + + .. code-block:: c + + #pragma omp declare simd [clause[[,] clause] ...] new-line + [#pragma omp declare simd [clause[[,] clause] ...] new-line] + [...] + function definition or declaration + +where clause is one of the following: + + .. code-block:: c + + simdlen(length) + linear(argument-list[:constant-linear-step]) + aligned(argument-list[:alignment]) + uniform(argument-list) + inbranch + notinbranch + + }]; +} + +def OMPDeclareTargetDocs : Documentation { + let Category = DocCatFunction; + let Heading = "#pragma omp declare target"; + let Content = [{ +The `declare target` directive specifies that variables and functions are mapped +to a device for OpenMP offload mechanism. + +The syntax of the declare target directive is as follows: + + .. code-block:: c + + #pragma omp declare target new-line + declarations-definition-seq + #pragma omp end declare target new-line + }]; +} + def NotTailCalledDocs : Documentation { let Category = DocCatFunction; let Content = [{ @@ -1765,7 +2050,7 @@ The ``not_tail_called`` attribute prevents tail-call optimization on statically For example, it prevents tail-call optimization in the following case: - .. code-block: c + .. code-block:: c int __attribute__((not_tail_called)) foo1(int); @@ -1775,7 +2060,7 @@ For example, it prevents tail-call optimization in the following case: However, it doesn't prevent tail-call optimization in this case: - .. code-block: c + .. code-block:: c int __attribute__((not_tail_called)) foo1(int); @@ -1789,7 +2074,7 @@ However, it doesn't prevent tail-call optimization in this case: Marking virtual functions as ``not_tail_called`` is an error: - .. code-block: c++ + .. code-block:: c++ class Base { public: @@ -1839,7 +2124,7 @@ For example: Marking virtual functions as ``disable_tail_calls`` is legal. - .. code-block: c++ + .. code-block:: c++ int callee(int); @@ -1859,3 +2144,349 @@ Marking virtual functions as ``disable_tail_calls`` is legal. }]; } + +def AnyX86InterruptDocs : Documentation { + let Category = DocCatFunction; + let Content = [{ +Clang supports the GNU style ``__attribute__((interrupt))`` attribute on +x86/x86-64 targets.The compiler generates function entry and exit sequences +suitable for use in an interrupt handler when this attribute is present. +The 'IRET' instruction, instead of the 'RET' instruction, is used to return +from interrupt or exception handlers. All registers, except for the EFLAGS +register which is restored by the 'IRET' instruction, are preserved by the +compiler. + +Any interruptible-without-stack-switch code must be compiled with +-mno-red-zone since interrupt handlers can and will, because of the +hardware design, touch the red zone. + +1. interrupt handler must be declared with a mandatory pointer argument: + + .. code-block:: c + + struct interrupt_frame + { + uword_t ip; + uword_t cs; + uword_t flags; + uword_t sp; + uword_t ss; + }; + + __attribute__ ((interrupt)) + void f (struct interrupt_frame *frame) { + ... + } + +2. exception handler: + + The exception handler is very similar to the interrupt handler with + a different mandatory function signature: + + .. code-block:: c + + __attribute__ ((interrupt)) + void f (struct interrupt_frame *frame, uword_t error_code) { + ... + } + + and compiler pops 'ERROR_CODE' off stack before the 'IRET' instruction. + + The exception handler should only be used for exceptions which push an + error code and all other exceptions must use the interrupt handler. + The system will crash if the wrong handler is used. + }]; +} + +def SwiftCallDocs : Documentation { + let Category = DocCatVariable; + let Content = [{ +The ``swiftcall`` attribute indicates that a function should be called +using the Swift calling convention for a function or function pointer. + +The lowering for the Swift calling convention, as described by the Swift +ABI documentation, occurs in multiple phases. The first, "high-level" +phase breaks down the formal parameters and results into innately direct +and indirect components, adds implicit paraameters for the generic +signature, and assigns the context and error ABI treatments to parameters +where applicable. The second phase breaks down the direct parameters +and results from the first phase and assigns them to registers or the +stack. The ``swiftcall`` convention only handles this second phase of +lowering; the C function type must accurately reflect the results +of the first phase, as follows: + +- Results classified as indirect by high-level lowering should be + represented as parameters with the ``swift_indirect_result`` attribute. + +- Results classified as direct by high-level lowering should be represented + as follows: + + - First, remove any empty direct results. + + - If there are no direct results, the C result type should be ``void``. + + - If there is one direct result, the C result type should be a type with + the exact layout of that result type. + + - If there are a multiple direct results, the C result type should be + a struct type with the exact layout of a tuple of those results. + +- Parameters classified as indirect by high-level lowering should be + represented as parameters of pointer type. + +- Parameters classified as direct by high-level lowering should be + omitted if they are empty types; otherwise, they should be represented + as a parameter type with a layout exactly matching the layout of the + Swift parameter type. + +- The context parameter, if present, should be represented as a trailing + parameter with the ``swift_context`` attribute. + +- The error result parameter, if present, should be represented as a + trailing parameter (always following a context parameter) with the + ``swift_error_result`` attribute. + +``swiftcall`` does not support variadic arguments or unprototyped functions. + +The parameter ABI treatment attributes are aspects of the function type. +A function type which which applies an ABI treatment attribute to a +parameter is a different type from an otherwise-identical function type +that does not. A single parameter may not have multiple ABI treatment +attributes. + +Support for this feature is target-dependent, although it should be +supported on every target that Swift supports. Query for this support +with ``__has_attribute(swiftcall)``. This implies support for the +``swift_context``, ``swift_error_result``, and ``swift_indirect_result`` +attributes. + }]; +} + +def SwiftContextDocs : Documentation { + let Category = DocCatVariable; + let Content = [{ +The ``swift_context`` attribute marks a parameter of a ``swiftcall`` +function as having the special context-parameter ABI treatment. + +This treatment generally passes the context value in a special register +which is normally callee-preserved. + +A ``swift_context`` parameter must either be the last parameter or must be +followed by a ``swift_error_result`` parameter (which itself must always be +the last parameter). + +A context parameter must have pointer or reference type. + }]; +} + +def SwiftErrorResultDocs : Documentation { + let Category = DocCatVariable; + let Content = [{ +The ``swift_error_result`` attribute marks a parameter of a ``swiftcall`` +function as having the special error-result ABI treatment. + +This treatment generally passes the underlying error value in and out of +the function through a special register which is normally callee-preserved. +This is modeled in C by pretending that the register is addressable memory: + +- The caller appears to pass the address of a variable of pointer type. + The current value of this variable is copied into the register before + the call; if the call returns normally, the value is copied back into the + variable. + +- The callee appears to receive the address of a variable. This address + is actually a hidden location in its own stack, initialized with the + value of the register upon entry. When the function returns normally, + the value in that hidden location is written back to the register. + +A ``swift_error_result`` parameter must be the last parameter, and it must be +preceded by a ``swift_context`` parameter. + +A ``swift_error_result`` parameter must have type ``T**`` or ``T*&`` for some +type T. Note that no qualifiers are permitted on the intermediate level. + +It is undefined behavior if the caller does not pass a pointer or +reference to a valid object. + +The standard convention is that the error value itself (that is, the +value stored in the apparent argument) will be null upon function entry, +but this is not enforced by the ABI. + }]; +} + +def SwiftIndirectResultDocs : Documentation { + let Category = DocCatVariable; + let Content = [{ +The ``swift_indirect_result`` attribute marks a parameter of a ``swiftcall`` +function as having the special indirect-result ABI treatmenet. + +This treatment gives the parameter the target's normal indirect-result +ABI treatment, which may involve passing it differently from an ordinary +parameter. However, only the first indirect result will receive this +treatment. Furthermore, low-level lowering may decide that a direct result +must be returned indirectly; if so, this will take priority over the +``swift_indirect_result`` parameters. + +A ``swift_indirect_result`` parameter must either be the first parameter or +follow another ``swift_indirect_result`` parameter. + +A ``swift_indirect_result`` parameter must have type ``T*`` or ``T&`` for +some object type ``T``. If ``T`` is a complete type at the point of +definition of a function, it is undefined behavior if the argument +value does not point to storage of adequate size and alignment for a +value of type ``T``. + +Making indirect results explicit in the signature allows C functions to +directly construct objects into them without relying on language +optimizations like C++'s named return value optimization (NRVO). + }]; +} + +def AbiTagsDocs : Documentation { + let Category = DocCatFunction; + let Content = [{ +The ``abi_tag`` attribute can be applied to a function, variable, class or +inline namespace declaration to modify the mangled name of the entity. It gives +the ability to distinguish between different versions of the same entity but +with different ABI versions supported. For example, a newer version of a class +could have a different set of data members and thus have a different size. Using +the ``abi_tag`` attribute, it is possible to have different mangled names for +a global variable of the class type. Therefor, the old code could keep using +the old manged name and the new code will use the new mangled name with tags. + }]; +} + +def PreserveMostDocs : Documentation { + let Category = DocCatCallingConvs; + let Content = [{ +On X86-64 and AArch64 targets, this attribute changes the calling convention of +a function. The ``preserve_most`` calling convention attempts to make the code +in the caller as unintrusive as possible. This convention behaves identically +to the ``C`` calling convention on how arguments and return values are passed, +but it uses a different set of caller/callee-saved registers. This alleviates +the burden of saving and recovering a large register set before and after the +call in the caller. If the arguments are passed in callee-saved registers, +then they will be preserved by the callee across the call. This doesn't +apply for values returned in callee-saved registers. + +- On X86-64 the callee preserves all general purpose registers, except for + R11. R11 can be used as a scratch register. Floating-point registers + (XMMs/YMMs) are not preserved and need to be saved by the caller. + +The idea behind this convention is to support calls to runtime functions +that have a hot path and a cold path. The hot path is usually a small piece +of code that doesn't use many registers. The cold path might need to call out to +another function and therefore only needs to preserve the caller-saved +registers, which haven't already been saved by the caller. The +`preserve_most` calling convention is very similar to the ``cold`` calling +convention in terms of caller/callee-saved registers, but they are used for +different types of function calls. ``coldcc`` is for function calls that are +rarely executed, whereas `preserve_most` function calls are intended to be +on the hot path and definitely executed a lot. Furthermore ``preserve_most`` +doesn't prevent the inliner from inlining the function call. + +This calling convention will be used by a future version of the Objective-C +runtime and should therefore still be considered experimental at this time. +Although this convention was created to optimize certain runtime calls to +the Objective-C runtime, it is not limited to this runtime and might be used +by other runtimes in the future too. The current implementation only +supports X86-64 and AArch64, but the intention is to support more architectures +in the future. + }]; +} + +def PreserveAllDocs : Documentation { + let Category = DocCatCallingConvs; + let Content = [{ +On X86-64 and AArch64 targets, this attribute changes the calling convention of +a function. The ``preserve_all`` calling convention attempts to make the code +in the caller even less intrusive than the ``preserve_most`` calling convention. +This calling convention also behaves identical to the ``C`` calling convention +on how arguments and return values are passed, but it uses a different set of +caller/callee-saved registers. This removes the burden of saving and +recovering a large register set before and after the call in the caller. If +the arguments are passed in callee-saved registers, then they will be +preserved by the callee across the call. This doesn't apply for values +returned in callee-saved registers. + +- On X86-64 the callee preserves all general purpose registers, except for + R11. R11 can be used as a scratch register. Furthermore it also preserves + all floating-point registers (XMMs/YMMs). + +The idea behind this convention is to support calls to runtime functions +that don't need to call out to any other functions. + +This calling convention, like the ``preserve_most`` calling convention, will be +used by a future version of the Objective-C runtime and should be considered +experimental at this time. + }]; +} + +def DeprecatedDocs : Documentation { + let Category = DocCatFunction; + let Content = [{ +The ``deprecated`` attribute can be applied to a function, a variable, or a +type. This is useful when identifying functions, variables, or types that are +expected to be removed in a future version of a program. + +Consider the function declaration for a hypothetical function ``f``: + +.. code-block:: c++ + + void f(void) __attribute__((deprecated("message", "replacement"))); + +When spelled as `__attribute__((deprecated))`, the deprecated attribute can have +two optional string arguments. The first one is the message to display when +emitting the warning; the second one enables the compiler to provide a Fix-It +to replace the deprecated name with a new name. Otherwise, when spelled as +`[[gnu::deprecated]] or [[deprecated]]`, the attribute can have one optional +string argument which is the message to display when emitting the warning. + }]; +} + +def IFuncDocs : Documentation { + let Category = DocCatFunction; + let Content = [{ +``__attribute__((ifunc("resolver")))`` is used to mark that the address of a declaration should be resolved at runtime by calling a resolver function. + +The symbol name of the resolver function is given in quotes. A function with this name (after mangling) must be defined in the current translation unit; it may be ``static``. The resolver function should take no arguments and return a pointer. + +The ``ifunc`` attribute may only be used on a function declaration. A function declaration with an ``ifunc`` attribute is considered to be a definition of the declared entity. The entity must not have weak linkage; for example, in C++, it cannot be applied to a declaration if a definition at that location would be considered inline. + +Not all targets support this attribute. ELF targets support this attribute when using binutils v2.20.1 or higher and glibc v2.11.1 or higher. Non-ELF targets currently do not support this attribute. + }]; +} + +def LTOVisibilityDocs : Documentation { + let Category = DocCatType; + let Content = [{ +See :doc:`LTOVisibility`. + }]; +} + +def RenderScriptKernelAttributeDocs : Documentation { + let Category = DocCatFunction; + let Content = [{ +``__attribute__((kernel))`` is used to mark a ``kernel`` function in +RenderScript. + +In RenderScript, ``kernel`` functions are used to express data-parallel +computations. The RenderScript runtime efficiently parallelizes ``kernel`` +functions to run on computational resources such as multi-core CPUs and GPUs. +See the RenderScript_ documentation for more information. + +.. _RenderScript: https://developer.android.com/guide/topics/renderscript/compute.html + }]; +} + +def XRayDocs : Documentation { + let Category = DocCatFunction; + let Heading = "xray_always_instrument (clang::xray_always_instrument), xray_never_instrument (clang::xray_never_instrument)"; + let Content = [{ +``__attribute__((xray_always_instrument))`` or ``[[clang::xray_always_instrument]]`` is used to mark member functions (in C++), methods (in Objective C), and free functions (in C, C++, and Objective C) to be instrumented with XRay. This will cause the function to always have space at the beginning and exit points to allow for runtime patching. + +Conversely, ``__attribute__((xray_never_instrument))`` or ``[[clang::xray_never_instrument]]`` will inhibit the insertion of these instrumentation points. + +If a function has neither of these attributes, they become subject to the XRay heuristics used to determine whether a function should be instrumented or otherwise. + }]; +} diff --git a/include/clang/Basic/AttrKinds.h b/include/clang/Basic/AttrKinds.h index f0b0a6445d404..8f7394f59d4d1 100644 --- a/include/clang/Basic/AttrKinds.h +++ b/include/clang/Basic/AttrKinds.h @@ -22,10 +22,10 @@ namespace attr { // \brief A list of all the recognized kinds of attributes. enum Kind { #define ATTR(X) X, -#define LAST_INHERITABLE_ATTR(X) X, LAST_INHERITABLE = X, -#define LAST_INHERITABLE_PARAM_ATTR(X) X, LAST_INHERITABLE_PARAM = X, +#define ATTR_RANGE(CLASS, FIRST_NAME, LAST_NAME) \ + First##CLASS = FIRST_NAME, \ + Last##CLASS = LAST_NAME, #include "clang/Basic/AttrList.inc" - NUM_ATTRS }; } // end namespace attr diff --git a/include/clang/Basic/Builtins.def b/include/clang/Basic/Builtins.def index 4f474ebe42ba5..96bb359e51cb4 100644 --- a/include/clang/Basic/Builtins.def +++ b/include/clang/Basic/Builtins.def @@ -67,6 +67,7 @@ // Builtin::Context class. Currently we have: // n -> nothrow // r -> noreturn +// U -> pure // c -> const // t -> signature is meaningless, use custom typechecking // F -> this is a libc/libm function with a '__builtin_' prefix added. @@ -377,6 +378,11 @@ BUILTIN(__builtin_signbit, "i.", "Fnc") BUILTIN(__builtin_signbitf, "if", "Fnc") BUILTIN(__builtin_signbitl, "iLd", "Fnc") +// Special FP builtins. +BUILTIN(__builtin_canonicalize, "dd", "nc") +BUILTIN(__builtin_canonicalizef, "ff", "nc") +BUILTIN(__builtin_canonicalizel, "LdLd", "nc") + // Builtins for arithmetic. BUILTIN(__builtin_clzs , "iUs" , "nc") BUILTIN(__builtin_clz , "iUi" , "nc") @@ -404,6 +410,11 @@ BUILTIN(__builtin_bswap16, "UsUs", "nc") BUILTIN(__builtin_bswap32, "UiUi", "nc") BUILTIN(__builtin_bswap64, "ULLiULLi", "nc") +BUILTIN(__builtin_bitreverse8, "UcUc", "nc") +BUILTIN(__builtin_bitreverse16, "UsUs", "nc") +BUILTIN(__builtin_bitreverse32, "UiUi", "nc") +BUILTIN(__builtin_bitreverse64, "ULLiULLi", "nc") + // Random GCC builtins BUILTIN(__builtin_constant_p, "i.", "nctu") BUILTIN(__builtin_classify_type, "i.", "nctu") @@ -456,6 +467,7 @@ BUILTIN(__builtin_eh_return_data_regno, "iIi", "nc") BUILTIN(__builtin_snprintf, "ic*zcC*.", "nFp:2:") BUILTIN(__builtin_vsprintf, "ic*cC*a", "nFP:1:") BUILTIN(__builtin_vsnprintf, "ic*zcC*a", "nFP:2:") +BUILTIN(__builtin_thread_pointer, "v*", "nc") // GCC exception builtins BUILTIN(__builtin_eh_return, "vzv*", "r") // FIXME: Takes intptr_t, not size_t! @@ -763,6 +775,22 @@ LIBBUILTIN(sscanf, "icC*RcC*R.", "fs:1:", "stdio.h", ALL_LANGUAGES) LIBBUILTIN(vscanf, "icC*Ra", "fS:0:", "stdio.h", ALL_LANGUAGES) LIBBUILTIN(vfscanf, "iP*RcC*Ra", "fS:1:", "stdio.h", ALL_LANGUAGES) LIBBUILTIN(vsscanf, "icC*RcC*Ra", "fS:1:", "stdio.h", ALL_LANGUAGES) +// C99 ctype.h +LIBBUILTIN(isalnum, "ii", "fnU", "ctype.h", ALL_LANGUAGES) +LIBBUILTIN(isalpha, "ii", "fnU", "ctype.h", ALL_LANGUAGES) +LIBBUILTIN(isblank, "ii", "fnU", "ctype.h", ALL_LANGUAGES) +LIBBUILTIN(iscntrl, "ii", "fnU", "ctype.h", ALL_LANGUAGES) +LIBBUILTIN(isdigit, "ii", "fnU", "ctype.h", ALL_LANGUAGES) +LIBBUILTIN(isgraph, "ii", "fnU", "ctype.h", ALL_LANGUAGES) +LIBBUILTIN(islower, "ii", "fnU", "ctype.h", ALL_LANGUAGES) +LIBBUILTIN(isprint, "ii", "fnU", "ctype.h", ALL_LANGUAGES) +LIBBUILTIN(ispunct, "ii", "fnU", "ctype.h", ALL_LANGUAGES) +LIBBUILTIN(isspace, "ii", "fnU", "ctype.h", ALL_LANGUAGES) +LIBBUILTIN(isupper, "ii", "fnU", "ctype.h", ALL_LANGUAGES) +LIBBUILTIN(isxdigit, "ii", "fnU", "ctype.h", ALL_LANGUAGES) +LIBBUILTIN(tolower, "ii", "fnU", "ctype.h", ALL_LANGUAGES) +LIBBUILTIN(toupper, "ii", "fnU", "ctype.h", ALL_LANGUAGES) + // C99 // In some systems setjmp is a macro that expands to _setjmp. We undefine // it here to avoid having two identical LIBBUILTIN entries. @@ -1252,6 +1280,43 @@ BUILTIN(__builtin___get_unsafe_stack_ptr, "v*", "Fn") BUILTIN(__builtin_nontemporal_store, "v.", "t") BUILTIN(__builtin_nontemporal_load, "v.", "t") +// OpenCL v2.0 s6.13.16, s9.17.3.5 - Pipe functions. +// We need the generic prototype, since the packet type could be anything. +LANGBUILTIN(read_pipe, "i.", "tn", OCLC20_LANG) +LANGBUILTIN(write_pipe, "i.", "tn", OCLC20_LANG) + +LANGBUILTIN(reserve_read_pipe, "i.", "tn", OCLC20_LANG) +LANGBUILTIN(reserve_write_pipe, "i.", "tn", OCLC20_LANG) + +LANGBUILTIN(commit_write_pipe, "v.", "tn", OCLC20_LANG) +LANGBUILTIN(commit_read_pipe, "v.", "tn", OCLC20_LANG) + +LANGBUILTIN(sub_group_reserve_read_pipe, "i.", "tn", OCLC20_LANG) +LANGBUILTIN(sub_group_reserve_write_pipe, "i.", "tn", OCLC20_LANG) + +LANGBUILTIN(sub_group_commit_read_pipe, "v.", "tn", OCLC20_LANG) +LANGBUILTIN(sub_group_commit_write_pipe, "v.", "tn", OCLC20_LANG) + +LANGBUILTIN(work_group_reserve_read_pipe, "i.", "tn", OCLC20_LANG) +LANGBUILTIN(work_group_reserve_write_pipe, "i.", "tn", OCLC20_LANG) + +LANGBUILTIN(work_group_commit_read_pipe, "v.", "tn", OCLC20_LANG) +LANGBUILTIN(work_group_commit_write_pipe, "v.", "tn", OCLC20_LANG) + +LANGBUILTIN(get_pipe_num_packets, "Ui.", "tn", OCLC20_LANG) +LANGBUILTIN(get_pipe_max_packets, "Ui.", "tn", OCLC20_LANG) + +// OpenCL v2.0 s6.13.17 - Enqueue kernel functions. +// Custom builtin check allows to perform special check of passed block arguments. +LANGBUILTIN(enqueue_kernel, "i.", "tn", OCLC20_LANG) +LANGBUILTIN(get_kernel_work_group_size, "i.", "tn", OCLC20_LANG) +LANGBUILTIN(get_kernel_preferred_work_group_size_multiple, "i.", "tn", OCLC20_LANG) + +// OpenCL v2.0 s6.13.9 - Address space qualifier functions. +LANGBUILTIN(to_global, "v*v*", "tn", OCLC20_LANG) +LANGBUILTIN(to_local, "v*v*", "tn", OCLC20_LANG) +LANGBUILTIN(to_private, "v*v*", "tn", OCLC20_LANG) + #undef BUILTIN #undef LIBBUILTIN #undef LANGBUILTIN diff --git a/include/clang/Basic/Builtins.h b/include/clang/Basic/Builtins.h index c0a6af9e26254..15e9a413fb420 100644 --- a/include/clang/Basic/Builtins.h +++ b/include/clang/Basic/Builtins.h @@ -31,11 +31,12 @@ class QualType; class LangOptions; enum LanguageID { - GNU_LANG = 0x1, // builtin requires GNU mode. - C_LANG = 0x2, // builtin for c only. - CXX_LANG = 0x4, // builtin for cplusplus only. - OBJC_LANG = 0x8, // builtin for objective-c and objective-c++ - MS_LANG = 0x10, // builtin requires MS mode. + GNU_LANG = 0x1, // builtin requires GNU mode. + C_LANG = 0x2, // builtin for c only. + CXX_LANG = 0x4, // builtin for cplusplus only. + OBJC_LANG = 0x8, // builtin for objective-c and objective-c++ + MS_LANG = 0x10, // builtin requires MS mode. + OCLC20_LANG = 0x20, // builtin for OpenCL C only. ALL_LANGUAGES = C_LANG | CXX_LANG | OBJC_LANG, // builtin for all languages. ALL_GNU_LANGUAGES = ALL_LANGUAGES | GNU_LANG, // builtin requires GNU mode. ALL_MS_LANGUAGES = ALL_LANGUAGES | MS_LANG // builtin requires MS mode. @@ -88,11 +89,16 @@ public: return getRecord(ID).Type; } - /// \brief Return true if this function is a target-specific builtin + /// \brief Return true if this function is a target-specific builtin. bool isTSBuiltin(unsigned ID) const { return ID >= Builtin::FirstTSBuiltin; } + /// \brief Return true if this function has no side effects. + bool isPure(unsigned ID) const { + return strchr(getRecord(ID).Attributes, 'U') != nullptr; + } + /// \brief Return true if this function has no side effects and doesn't /// read memory. bool isConst(unsigned ID) const { @@ -154,7 +160,7 @@ public: /// \brief Completely forget that the given ID was ever considered a builtin, /// e.g., because the user provided a conflicting signature. void forgetBuiltin(unsigned ID, IdentifierTable &Table); - + /// \brief If this is a library function that comes from a specific /// header, retrieve that header name. const char *getHeaderName(unsigned ID) const { @@ -213,7 +219,10 @@ private: /// \brief Kinds of BuiltinTemplateDecl. enum BuiltinTemplateKind : int { /// \brief This names the __make_integer_seq BuiltinTemplateDecl. - BTK__make_integer_seq + BTK__make_integer_seq, + + /// \brief This names the __type_pack_element BuiltinTemplateDecl. + BTK__type_pack_element }; } // end namespace clang diff --git a/include/clang/Basic/BuiltinsAArch64.def b/include/clang/Basic/BuiltinsAArch64.def index b4404434e7a82..1db4c1471029b 100644 --- a/include/clang/Basic/BuiltinsAArch64.def +++ b/include/clang/Basic/BuiltinsAArch64.def @@ -60,6 +60,5 @@ BUILTIN(__builtin_arm_rsrp, "v*cC*", "nc") BUILTIN(__builtin_arm_wsr, "vcC*Ui", "nc") BUILTIN(__builtin_arm_wsr64, "vcC*LUi", "nc") BUILTIN(__builtin_arm_wsrp, "vcC*vC*", "nc") -BUILTIN(__builtin_thread_pointer, "v*", "nc") #undef BUILTIN diff --git a/include/clang/Basic/BuiltinsAMDGPU.def b/include/clang/Basic/BuiltinsAMDGPU.def index bb9931f7a2066..ea63ea10f84cc 100644 --- a/include/clang/Basic/BuiltinsAMDGPU.def +++ b/include/clang/Basic/BuiltinsAMDGPU.def @@ -7,30 +7,97 @@ // //===----------------------------------------------------------------------===// // -// This file defines the R600-specific builtin function database. Users of this -// file must define the BUILTIN macro to make use of this information. +// This file defines the AMDGPU-specific builtin function database. Users of +// this file must define the BUILTIN macro to make use of this information. // //===----------------------------------------------------------------------===// // The format of this database matches clang/Basic/Builtins.def. -BUILTIN(__builtin_amdgpu_div_scale, "dddbb*", "n") -BUILTIN(__builtin_amdgpu_div_scalef, "fffbb*", "n") -BUILTIN(__builtin_amdgpu_div_fmas, "ddddb", "nc") -BUILTIN(__builtin_amdgpu_div_fmasf, "ffffb", "nc") -BUILTIN(__builtin_amdgpu_div_fixup, "dddd", "nc") -BUILTIN(__builtin_amdgpu_div_fixupf, "ffff", "nc") -BUILTIN(__builtin_amdgpu_trig_preop, "ddi", "nc") -BUILTIN(__builtin_amdgpu_trig_preopf, "ffi", "nc") -BUILTIN(__builtin_amdgpu_rcp, "dd", "nc") -BUILTIN(__builtin_amdgpu_rcpf, "ff", "nc") -BUILTIN(__builtin_amdgpu_rsq, "dd", "nc") -BUILTIN(__builtin_amdgpu_rsqf, "ff", "nc") -BUILTIN(__builtin_amdgpu_rsq_clamped, "dd", "nc") -BUILTIN(__builtin_amdgpu_rsq_clampedf, "ff", "nc") -BUILTIN(__builtin_amdgpu_ldexp, "ddi", "nc") -BUILTIN(__builtin_amdgpu_ldexpf, "ffi", "nc") -BUILTIN(__builtin_amdgpu_class, "bdi", "nc") -BUILTIN(__builtin_amdgpu_classf, "bfi", "nc") +#if defined(BUILTIN) && !defined(TARGET_BUILTIN) +# define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) BUILTIN(ID, TYPE, ATTRS) +#endif +//===----------------------------------------------------------------------===// +// SI+ only builtins. +//===----------------------------------------------------------------------===// + +BUILTIN(__builtin_amdgcn_kernarg_segment_ptr, "Uc*2", "nc") +BUILTIN(__builtin_amdgcn_implicitarg_ptr, "Uc*2", "nc") + +BUILTIN(__builtin_amdgcn_workgroup_id_x, "Ui", "nc") +BUILTIN(__builtin_amdgcn_workgroup_id_y, "Ui", "nc") +BUILTIN(__builtin_amdgcn_workgroup_id_z, "Ui", "nc") + +BUILTIN(__builtin_amdgcn_workitem_id_x, "Ui", "nc") +BUILTIN(__builtin_amdgcn_workitem_id_y, "Ui", "nc") +BUILTIN(__builtin_amdgcn_workitem_id_z, "Ui", "nc") + +//===----------------------------------------------------------------------===// +// Instruction builtins. +//===----------------------------------------------------------------------===// +BUILTIN(__builtin_amdgcn_s_barrier, "v", "n") +BUILTIN(__builtin_amdgcn_div_scale, "dddbb*", "n") +BUILTIN(__builtin_amdgcn_div_scalef, "fffbb*", "n") +BUILTIN(__builtin_amdgcn_div_fmas, "ddddb", "nc") +BUILTIN(__builtin_amdgcn_div_fmasf, "ffffb", "nc") +BUILTIN(__builtin_amdgcn_div_fixup, "dddd", "nc") +BUILTIN(__builtin_amdgcn_div_fixupf, "ffff", "nc") +BUILTIN(__builtin_amdgcn_trig_preop, "ddi", "nc") +BUILTIN(__builtin_amdgcn_trig_preopf, "ffi", "nc") +BUILTIN(__builtin_amdgcn_rcp, "dd", "nc") +BUILTIN(__builtin_amdgcn_rcpf, "ff", "nc") +BUILTIN(__builtin_amdgcn_rsq, "dd", "nc") +BUILTIN(__builtin_amdgcn_rsqf, "ff", "nc") +BUILTIN(__builtin_amdgcn_rsq_clamp, "dd", "nc") +BUILTIN(__builtin_amdgcn_rsq_clampf, "ff", "nc") +BUILTIN(__builtin_amdgcn_sinf, "ff", "nc") +BUILTIN(__builtin_amdgcn_cosf, "ff", "nc") +BUILTIN(__builtin_amdgcn_log_clampf, "ff", "nc") +BUILTIN(__builtin_amdgcn_ldexp, "ddi", "nc") +BUILTIN(__builtin_amdgcn_ldexpf, "ffi", "nc") +BUILTIN(__builtin_amdgcn_frexp_mant, "dd", "nc") +BUILTIN(__builtin_amdgcn_frexp_mantf, "ff", "nc") +BUILTIN(__builtin_amdgcn_frexp_exp, "id", "nc") +BUILTIN(__builtin_amdgcn_frexp_expf, "if", "nc") +BUILTIN(__builtin_amdgcn_fract, "dd", "nc") +BUILTIN(__builtin_amdgcn_fractf, "ff", "nc") +BUILTIN(__builtin_amdgcn_lerp, "UiUiUiUi", "nc") +BUILTIN(__builtin_amdgcn_class, "bdi", "nc") +BUILTIN(__builtin_amdgcn_classf, "bfi", "nc") +BUILTIN(__builtin_amdgcn_cubeid, "ffff", "nc") +BUILTIN(__builtin_amdgcn_cubesc, "ffff", "nc") +BUILTIN(__builtin_amdgcn_cubetc, "ffff", "nc") +BUILTIN(__builtin_amdgcn_cubema, "ffff", "nc") +BUILTIN(__builtin_amdgcn_s_memtime, "LUi", "n") +BUILTIN(__builtin_amdgcn_s_sleep, "vIi", "n") + +//===----------------------------------------------------------------------===// +// VI+ only builtins. +//===----------------------------------------------------------------------===// + +TARGET_BUILTIN(__builtin_amdgcn_s_memrealtime, "LUi", "n", "s-memrealtime") + +//===----------------------------------------------------------------------===// +// Special builtins. +//===----------------------------------------------------------------------===// +BUILTIN(__builtin_amdgcn_read_exec, "LUi", "nc") + +//===----------------------------------------------------------------------===// +// R600-NI only builtins. +//===----------------------------------------------------------------------===// + +BUILTIN(__builtin_r600_implicitarg_ptr, "Uc*7", "nc") + +BUILTIN(__builtin_r600_read_tgid_x, "Ui", "nc") +BUILTIN(__builtin_r600_read_tgid_y, "Ui", "nc") +BUILTIN(__builtin_r600_read_tgid_z, "Ui", "nc") + +BUILTIN(__builtin_r600_read_tidig_x, "Ui", "nc") +BUILTIN(__builtin_r600_read_tidig_y, "Ui", "nc") +BUILTIN(__builtin_r600_read_tidig_z, "Ui", "nc") + +BUILTIN(__builtin_r600_recipsqrt_ieee, "dd", "nc") +BUILTIN(__builtin_r600_recipsqrt_ieeef, "ff", "nc") #undef BUILTIN +#undef TARGET_BUILTIN diff --git a/include/clang/Basic/BuiltinsARM.def b/include/clang/Basic/BuiltinsARM.def index 3e8e2bf912ad1..93b6458c5ef23 100644 --- a/include/clang/Basic/BuiltinsARM.def +++ b/include/clang/Basic/BuiltinsARM.def @@ -20,7 +20,6 @@ // In libgcc BUILTIN(__clear_cache, "vv*v*", "i") -BUILTIN(__builtin_thread_pointer, "v*", "") // Saturating arithmetic BUILTIN(__builtin_arm_qadd, "iii", "nc") @@ -48,14 +47,26 @@ BUILTIN(__builtin_arm_vcvtr_f, "ffi", "nc") BUILTIN(__builtin_arm_vcvtr_d, "fdi", "nc") // Coprocessor +BUILTIN(__builtin_arm_ldc, "vUIiUIivC*", "") +BUILTIN(__builtin_arm_ldcl, "vUIiUIivC*", "") +BUILTIN(__builtin_arm_ldc2, "vUIiUIivC*", "") +BUILTIN(__builtin_arm_ldc2l, "vUIiUIivC*", "") + +BUILTIN(__builtin_arm_stc, "vUIiUIiv*", "") +BUILTIN(__builtin_arm_stcl, "vUIiUIiv*", "") +BUILTIN(__builtin_arm_stc2, "vUIiUIiv*", "") +BUILTIN(__builtin_arm_stc2l, "vUIiUIiv*", "") + +BUILTIN(__builtin_arm_cdp, "vUIiUIiUIiUIiUIiUIi", "") +BUILTIN(__builtin_arm_cdp2, "vUIiUIiUIiUIiUIiUIi", "") BUILTIN(__builtin_arm_mcr, "vUIiUIiUiUIiUIiUIi", "") BUILTIN(__builtin_arm_mcr2, "vUIiUIiUiUIiUIiUIi", "") BUILTIN(__builtin_arm_mrc, "UiUIiUIiUIiUIiUIi", "") BUILTIN(__builtin_arm_mrc2, "UiUIiUIiUIiUIiUIi", "") -BUILTIN(__builtin_arm_cdp, "vUiUiUiUiUiUi", "") -BUILTIN(__builtin_arm_cdp2, "vUiUiUiUiUiUi", "") -BUILTIN(__builtin_arm_mcrr, "vUIiUIiUiUiUIi", "") -BUILTIN(__builtin_arm_mcrr2, "vUIiUIiUiUiUIi", "") +BUILTIN(__builtin_arm_mcrr, "vUIiUIiLLUiUIi", "") +BUILTIN(__builtin_arm_mcrr2, "vUIiUIiLLUiUIi", "") +BUILTIN(__builtin_arm_mrrc, "LLUiUIiUIiUIi", "") +BUILTIN(__builtin_arm_mrrc2, "LLUiUIiUIiUIi", "") // CRC32 BUILTIN(__builtin_arm_crc32b, "UiUiUc", "nc") diff --git a/include/clang/Basic/BuiltinsHexagon.def b/include/clang/Basic/BuiltinsHexagon.def index c071a464b0ac6..85936cbfc08ea 100644 --- a/include/clang/Basic/BuiltinsHexagon.def +++ b/include/clang/Basic/BuiltinsHexagon.def @@ -18,57 +18,78 @@ // Make sure you do not overwrite these. BUILTIN(__builtin_SI_to_SXTHI_asrh, "ii", "") -BUILTIN(__builtin_circ_ldd, "LLi*LLi*LLi*ii", "") +BUILTIN(__builtin_brev_ldd, "LLi*LLi*LLi*i", "") +BUILTIN(__builtin_brev_ldw, "i*i*i*i", "") +BUILTIN(__builtin_brev_ldh, "s*s*s*i", "") +BUILTIN(__builtin_brev_lduh, "Us*Us*Us*i", "") +BUILTIN(__builtin_brev_ldb, "c*c*c*i", "") +BUILTIN(__builtin_brev_ldub, "Uc*Uc*Uc*i", "") +BUILTIN(__builtin_circ_ldd, "LLi*LLi*LLi*iIi", "") +BUILTIN(__builtin_circ_ldw, "i*i*i*iIi", "") +BUILTIN(__builtin_circ_ldh, "s*s*s*iIi", "") +BUILTIN(__builtin_circ_lduh, "Us*Us*Us*iIi", "") +BUILTIN(__builtin_circ_ldb, "c*c*c*iIi", "") +BUILTIN(__builtin_circ_ldub, "Uc*Uc*Uc*iIi", "") +BUILTIN(__builtin_brev_std, "LLi*LLi*LLii", "") +BUILTIN(__builtin_brev_stw, "i*i*ii", "") +BUILTIN(__builtin_brev_sth, "s*s*ii", "") +BUILTIN(__builtin_brev_sthhi, "s*s*ii", "") +BUILTIN(__builtin_brev_stb, "c*c*ii", "") +BUILTIN(__builtin_circ_std, "LLi*LLi*LLiiIi", "") +BUILTIN(__builtin_circ_stw, "i*i*iiIi", "") +BUILTIN(__builtin_circ_sth, "s*s*iiIi", "") +BUILTIN(__builtin_circ_sthhi, "s*s*iiIi", "") +BUILTIN(__builtin_circ_stb, "c*c*iiIi", "") // The builtins above are not autogenerated from iset.py. // Make sure you do not overwrite these. -BUILTIN(__builtin_HEXAGON_C2_cmpeq,"bii","") -BUILTIN(__builtin_HEXAGON_C2_cmpgt,"bii","") -BUILTIN(__builtin_HEXAGON_C2_cmpgtu,"bii","") -BUILTIN(__builtin_HEXAGON_C2_cmpeqp,"bLLiLLi","") -BUILTIN(__builtin_HEXAGON_C2_cmpgtp,"bLLiLLi","") -BUILTIN(__builtin_HEXAGON_C2_cmpgtup,"bLLiLLi","") +BUILTIN(__builtin_HEXAGON_C2_cmpeq,"iii","") +BUILTIN(__builtin_HEXAGON_C2_cmpgt,"iii","") +BUILTIN(__builtin_HEXAGON_C2_cmpgtu,"iii","") +BUILTIN(__builtin_HEXAGON_C2_cmpeqp,"iLLiLLi","") +BUILTIN(__builtin_HEXAGON_C2_cmpgtp,"iLLiLLi","") +BUILTIN(__builtin_HEXAGON_C2_cmpgtup,"iLLiLLi","") BUILTIN(__builtin_HEXAGON_A4_rcmpeqi,"iii","") BUILTIN(__builtin_HEXAGON_A4_rcmpneqi,"iii","") BUILTIN(__builtin_HEXAGON_A4_rcmpeq,"iii","") BUILTIN(__builtin_HEXAGON_A4_rcmpneq,"iii","") -BUILTIN(__builtin_HEXAGON_C2_bitsset,"bii","") -BUILTIN(__builtin_HEXAGON_C2_bitsclr,"bii","") -BUILTIN(__builtin_HEXAGON_C4_nbitsset,"bii","") -BUILTIN(__builtin_HEXAGON_C4_nbitsclr,"bii","") -BUILTIN(__builtin_HEXAGON_C2_cmpeqi,"bii","") -BUILTIN(__builtin_HEXAGON_C2_cmpgti,"bii","") -BUILTIN(__builtin_HEXAGON_C2_cmpgtui,"bii","") -BUILTIN(__builtin_HEXAGON_C2_cmpgei,"bii","") -BUILTIN(__builtin_HEXAGON_C2_cmpgeui,"bii","") -BUILTIN(__builtin_HEXAGON_C2_cmplt,"bii","") -BUILTIN(__builtin_HEXAGON_C2_cmpltu,"bii","") -BUILTIN(__builtin_HEXAGON_C2_bitsclri,"bii","") -BUILTIN(__builtin_HEXAGON_C4_nbitsclri,"bii","") -BUILTIN(__builtin_HEXAGON_C4_cmpneqi,"bii","") -BUILTIN(__builtin_HEXAGON_C4_cmpltei,"bii","") -BUILTIN(__builtin_HEXAGON_C4_cmplteui,"bii","") -BUILTIN(__builtin_HEXAGON_C4_cmpneq,"bii","") -BUILTIN(__builtin_HEXAGON_C4_cmplte,"bii","") -BUILTIN(__builtin_HEXAGON_C4_cmplteu,"bii","") -BUILTIN(__builtin_HEXAGON_C2_and,"bii","") -BUILTIN(__builtin_HEXAGON_C2_or,"bii","") -BUILTIN(__builtin_HEXAGON_C2_xor,"bii","") -BUILTIN(__builtin_HEXAGON_C2_andn,"bii","") -BUILTIN(__builtin_HEXAGON_C2_not,"bi","") -BUILTIN(__builtin_HEXAGON_C2_orn,"bii","") -BUILTIN(__builtin_HEXAGON_C4_and_and,"biii","") -BUILTIN(__builtin_HEXAGON_C4_and_or,"biii","") -BUILTIN(__builtin_HEXAGON_C4_or_and,"biii","") -BUILTIN(__builtin_HEXAGON_C4_or_or,"biii","") -BUILTIN(__builtin_HEXAGON_C4_and_andn,"biii","") -BUILTIN(__builtin_HEXAGON_C4_and_orn,"biii","") -BUILTIN(__builtin_HEXAGON_C4_or_andn,"biii","") -BUILTIN(__builtin_HEXAGON_C4_or_orn,"biii","") -BUILTIN(__builtin_HEXAGON_C2_pxfer_map,"bi","") -BUILTIN(__builtin_HEXAGON_C2_any8,"bi","") -BUILTIN(__builtin_HEXAGON_C2_all8,"bi","") +BUILTIN(__builtin_HEXAGON_C2_bitsset,"iii","") +BUILTIN(__builtin_HEXAGON_C2_bitsclr,"iii","") +BUILTIN(__builtin_HEXAGON_C4_nbitsset,"iii","") +BUILTIN(__builtin_HEXAGON_C4_nbitsclr,"iii","") +BUILTIN(__builtin_HEXAGON_C2_cmpeqi,"iii","") +BUILTIN(__builtin_HEXAGON_C2_cmpgti,"iii","") +BUILTIN(__builtin_HEXAGON_C2_cmpgtui,"iii","") +BUILTIN(__builtin_HEXAGON_C2_cmpgei,"iii","") +BUILTIN(__builtin_HEXAGON_C2_cmpgeui,"iii","") +BUILTIN(__builtin_HEXAGON_C2_cmplt,"iii","") +BUILTIN(__builtin_HEXAGON_C2_cmpltu,"iii","") +BUILTIN(__builtin_HEXAGON_C2_bitsclri,"iii","") +BUILTIN(__builtin_HEXAGON_C4_nbitsclri,"iii","") +BUILTIN(__builtin_HEXAGON_C4_cmpneqi,"iii","") +BUILTIN(__builtin_HEXAGON_C4_cmpltei,"iii","") +BUILTIN(__builtin_HEXAGON_C4_cmplteui,"iii","") +BUILTIN(__builtin_HEXAGON_C4_cmpneq,"iii","") +BUILTIN(__builtin_HEXAGON_C4_cmplte,"iii","") +BUILTIN(__builtin_HEXAGON_C4_cmplteu,"iii","") +BUILTIN(__builtin_HEXAGON_C2_and,"iii","") +BUILTIN(__builtin_HEXAGON_C2_or,"iii","") +BUILTIN(__builtin_HEXAGON_C2_xor,"iii","") +BUILTIN(__builtin_HEXAGON_C2_andn,"iii","") +BUILTIN(__builtin_HEXAGON_C2_not,"ii","") +BUILTIN(__builtin_HEXAGON_C2_orn,"iii","") +BUILTIN(__builtin_HEXAGON_C4_and_and,"iiii","") +BUILTIN(__builtin_HEXAGON_C4_and_or,"iiii","") +BUILTIN(__builtin_HEXAGON_C4_or_and,"iiii","") +BUILTIN(__builtin_HEXAGON_C4_or_or,"iiii","") +BUILTIN(__builtin_HEXAGON_C4_and_andn,"iiii","") +BUILTIN(__builtin_HEXAGON_C4_and_orn,"iiii","") +BUILTIN(__builtin_HEXAGON_C4_or_andn,"iiii","") +BUILTIN(__builtin_HEXAGON_C4_or_orn,"iiii","") +BUILTIN(__builtin_HEXAGON_C2_pxfer_map,"ii","") +BUILTIN(__builtin_HEXAGON_C2_any8,"ii","") +BUILTIN(__builtin_HEXAGON_C2_all8,"ii","") BUILTIN(__builtin_HEXAGON_C2_vitpack,"iii","") BUILTIN(__builtin_HEXAGON_C2_mux,"iiii","") BUILTIN(__builtin_HEXAGON_C2_muxii,"iiii","") @@ -76,43 +97,43 @@ BUILTIN(__builtin_HEXAGON_C2_muxir,"iiii","") BUILTIN(__builtin_HEXAGON_C2_muxri,"iiii","") BUILTIN(__builtin_HEXAGON_C2_vmux,"LLiiLLiLLi","") BUILTIN(__builtin_HEXAGON_C2_mask,"LLii","") -BUILTIN(__builtin_HEXAGON_A2_vcmpbeq,"bLLiLLi","") -BUILTIN(__builtin_HEXAGON_A4_vcmpbeqi,"bLLii","") -BUILTIN(__builtin_HEXAGON_A4_vcmpbeq_any,"bLLiLLi","") -BUILTIN(__builtin_HEXAGON_A2_vcmpbgtu,"bLLiLLi","") -BUILTIN(__builtin_HEXAGON_A4_vcmpbgtui,"bLLii","") -BUILTIN(__builtin_HEXAGON_A4_vcmpbgt,"bLLiLLi","") -BUILTIN(__builtin_HEXAGON_A4_vcmpbgti,"bLLii","") -BUILTIN(__builtin_HEXAGON_A4_cmpbeq,"bii","") -BUILTIN(__builtin_HEXAGON_A4_cmpbeqi,"bii","") -BUILTIN(__builtin_HEXAGON_A4_cmpbgtu,"bii","") -BUILTIN(__builtin_HEXAGON_A4_cmpbgtui,"bii","") -BUILTIN(__builtin_HEXAGON_A4_cmpbgt,"bii","") -BUILTIN(__builtin_HEXAGON_A4_cmpbgti,"bii","") -BUILTIN(__builtin_HEXAGON_A2_vcmpheq,"bLLiLLi","") -BUILTIN(__builtin_HEXAGON_A2_vcmphgt,"bLLiLLi","") -BUILTIN(__builtin_HEXAGON_A2_vcmphgtu,"bLLiLLi","") -BUILTIN(__builtin_HEXAGON_A4_vcmpheqi,"bLLii","") -BUILTIN(__builtin_HEXAGON_A4_vcmphgti,"bLLii","") -BUILTIN(__builtin_HEXAGON_A4_vcmphgtui,"bLLii","") -BUILTIN(__builtin_HEXAGON_A4_cmpheq,"bii","") -BUILTIN(__builtin_HEXAGON_A4_cmphgt,"bii","") -BUILTIN(__builtin_HEXAGON_A4_cmphgtu,"bii","") -BUILTIN(__builtin_HEXAGON_A4_cmpheqi,"bii","") -BUILTIN(__builtin_HEXAGON_A4_cmphgti,"bii","") -BUILTIN(__builtin_HEXAGON_A4_cmphgtui,"bii","") -BUILTIN(__builtin_HEXAGON_A2_vcmpweq,"bLLiLLi","") -BUILTIN(__builtin_HEXAGON_A2_vcmpwgt,"bLLiLLi","") -BUILTIN(__builtin_HEXAGON_A2_vcmpwgtu,"bLLiLLi","") -BUILTIN(__builtin_HEXAGON_A4_vcmpweqi,"bLLii","") -BUILTIN(__builtin_HEXAGON_A4_vcmpwgti,"bLLii","") -BUILTIN(__builtin_HEXAGON_A4_vcmpwgtui,"bLLii","") -BUILTIN(__builtin_HEXAGON_A4_boundscheck,"biLLi","") -BUILTIN(__builtin_HEXAGON_A4_tlbmatch,"bLLii","") +BUILTIN(__builtin_HEXAGON_A2_vcmpbeq,"iLLiLLi","") +BUILTIN(__builtin_HEXAGON_A4_vcmpbeqi,"iLLii","") +BUILTIN(__builtin_HEXAGON_A4_vcmpbeq_any,"iLLiLLi","") +BUILTIN(__builtin_HEXAGON_A2_vcmpbgtu,"iLLiLLi","") +BUILTIN(__builtin_HEXAGON_A4_vcmpbgtui,"iLLii","") +BUILTIN(__builtin_HEXAGON_A4_vcmpbgt,"iLLiLLi","") +BUILTIN(__builtin_HEXAGON_A4_vcmpbgti,"iLLii","") +BUILTIN(__builtin_HEXAGON_A4_cmpbeq,"iii","") +BUILTIN(__builtin_HEXAGON_A4_cmpbeqi,"iii","") +BUILTIN(__builtin_HEXAGON_A4_cmpbgtu,"iii","") +BUILTIN(__builtin_HEXAGON_A4_cmpbgtui,"iii","") +BUILTIN(__builtin_HEXAGON_A4_cmpbgt,"iii","") +BUILTIN(__builtin_HEXAGON_A4_cmpbgti,"iii","") +BUILTIN(__builtin_HEXAGON_A2_vcmpheq,"iLLiLLi","") +BUILTIN(__builtin_HEXAGON_A2_vcmphgt,"iLLiLLi","") +BUILTIN(__builtin_HEXAGON_A2_vcmphgtu,"iLLiLLi","") +BUILTIN(__builtin_HEXAGON_A4_vcmpheqi,"iLLii","") +BUILTIN(__builtin_HEXAGON_A4_vcmphgti,"iLLii","") +BUILTIN(__builtin_HEXAGON_A4_vcmphgtui,"iLLii","") +BUILTIN(__builtin_HEXAGON_A4_cmpheq,"iii","") +BUILTIN(__builtin_HEXAGON_A4_cmphgt,"iii","") +BUILTIN(__builtin_HEXAGON_A4_cmphgtu,"iii","") +BUILTIN(__builtin_HEXAGON_A4_cmpheqi,"iii","") +BUILTIN(__builtin_HEXAGON_A4_cmphgti,"iii","") +BUILTIN(__builtin_HEXAGON_A4_cmphgtui,"iii","") +BUILTIN(__builtin_HEXAGON_A2_vcmpweq,"iLLiLLi","") +BUILTIN(__builtin_HEXAGON_A2_vcmpwgt,"iLLiLLi","") +BUILTIN(__builtin_HEXAGON_A2_vcmpwgtu,"iLLiLLi","") +BUILTIN(__builtin_HEXAGON_A4_vcmpweqi,"iLLii","") +BUILTIN(__builtin_HEXAGON_A4_vcmpwgti,"iLLii","") +BUILTIN(__builtin_HEXAGON_A4_vcmpwgtui,"iLLii","") +BUILTIN(__builtin_HEXAGON_A4_boundscheck,"iiLLi","") +BUILTIN(__builtin_HEXAGON_A4_tlbmatch,"iLLii","") BUILTIN(__builtin_HEXAGON_C2_tfrpr,"ii","") -BUILTIN(__builtin_HEXAGON_C2_tfrrp,"bi","") -BUILTIN(__builtin_HEXAGON_C4_fastcorner9,"bii","") -BUILTIN(__builtin_HEXAGON_C4_fastcorner9_not,"bii","") +BUILTIN(__builtin_HEXAGON_C2_tfrrp,"ii","") +BUILTIN(__builtin_HEXAGON_C4_fastcorner9,"iii","") +BUILTIN(__builtin_HEXAGON_C4_fastcorner9_not,"iii","") BUILTIN(__builtin_HEXAGON_M2_mpy_acc_hh_s0,"iiii","") BUILTIN(__builtin_HEXAGON_M2_mpy_acc_hh_s1,"iiii","") BUILTIN(__builtin_HEXAGON_M2_mpy_acc_hl_s0,"iiii","") @@ -620,38 +641,25 @@ BUILTIN(__builtin_HEXAGON_F2_sffma_sc,"ffffi","") BUILTIN(__builtin_HEXAGON_F2_sffms,"ffff","") BUILTIN(__builtin_HEXAGON_F2_sffma_lib,"ffff","") BUILTIN(__builtin_HEXAGON_F2_sffms_lib,"ffff","") -BUILTIN(__builtin_HEXAGON_F2_sfcmpeq,"bff","") -BUILTIN(__builtin_HEXAGON_F2_sfcmpgt,"bff","") -BUILTIN(__builtin_HEXAGON_F2_sfcmpge,"bff","") -BUILTIN(__builtin_HEXAGON_F2_sfcmpuo,"bff","") +BUILTIN(__builtin_HEXAGON_F2_sfcmpeq,"iff","") +BUILTIN(__builtin_HEXAGON_F2_sfcmpgt,"iff","") +BUILTIN(__builtin_HEXAGON_F2_sfcmpge,"iff","") +BUILTIN(__builtin_HEXAGON_F2_sfcmpuo,"iff","") BUILTIN(__builtin_HEXAGON_F2_sfmax,"fff","") BUILTIN(__builtin_HEXAGON_F2_sfmin,"fff","") -BUILTIN(__builtin_HEXAGON_F2_sfclass,"bfi","") +BUILTIN(__builtin_HEXAGON_F2_sfclass,"ifi","") BUILTIN(__builtin_HEXAGON_F2_sfimm_p,"fi","") BUILTIN(__builtin_HEXAGON_F2_sfimm_n,"fi","") BUILTIN(__builtin_HEXAGON_F2_sffixupn,"fff","") BUILTIN(__builtin_HEXAGON_F2_sffixupd,"fff","") BUILTIN(__builtin_HEXAGON_F2_sffixupr,"ff","") -BUILTIN(__builtin_HEXAGON_F2_dfadd,"ddd","") -BUILTIN(__builtin_HEXAGON_F2_dfsub,"ddd","") -BUILTIN(__builtin_HEXAGON_F2_dfmpy,"ddd","") -BUILTIN(__builtin_HEXAGON_F2_dffma,"dddd","") -BUILTIN(__builtin_HEXAGON_F2_dffms,"dddd","") -BUILTIN(__builtin_HEXAGON_F2_dffma_lib,"dddd","") -BUILTIN(__builtin_HEXAGON_F2_dffms_lib,"dddd","") -BUILTIN(__builtin_HEXAGON_F2_dffma_sc,"ddddi","") -BUILTIN(__builtin_HEXAGON_F2_dfmax,"ddd","") -BUILTIN(__builtin_HEXAGON_F2_dfmin,"ddd","") -BUILTIN(__builtin_HEXAGON_F2_dfcmpeq,"bdd","") -BUILTIN(__builtin_HEXAGON_F2_dfcmpgt,"bdd","") -BUILTIN(__builtin_HEXAGON_F2_dfcmpge,"bdd","") -BUILTIN(__builtin_HEXAGON_F2_dfcmpuo,"bdd","") -BUILTIN(__builtin_HEXAGON_F2_dfclass,"bdi","") +BUILTIN(__builtin_HEXAGON_F2_dfcmpeq,"idd","") +BUILTIN(__builtin_HEXAGON_F2_dfcmpgt,"idd","") +BUILTIN(__builtin_HEXAGON_F2_dfcmpge,"idd","") +BUILTIN(__builtin_HEXAGON_F2_dfcmpuo,"idd","") +BUILTIN(__builtin_HEXAGON_F2_dfclass,"idi","") BUILTIN(__builtin_HEXAGON_F2_dfimm_p,"di","") BUILTIN(__builtin_HEXAGON_F2_dfimm_n,"di","") -BUILTIN(__builtin_HEXAGON_F2_dffixupn,"ddd","") -BUILTIN(__builtin_HEXAGON_F2_dffixupd,"ddd","") -BUILTIN(__builtin_HEXAGON_F2_dffixupr,"dd","") BUILTIN(__builtin_HEXAGON_F2_conv_sf2df,"df","") BUILTIN(__builtin_HEXAGON_F2_conv_df2sf,"fd","") BUILTIN(__builtin_HEXAGON_F2_conv_uw2sf,"fi","") @@ -797,13 +805,13 @@ BUILTIN(__builtin_HEXAGON_S2_extractu_rp,"iiLLi","") BUILTIN(__builtin_HEXAGON_S2_insertp_rp,"LLiLLiLLiLLi","") BUILTIN(__builtin_HEXAGON_S4_extractp_rp,"LLiLLiLLi","") BUILTIN(__builtin_HEXAGON_S2_extractup_rp,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_S2_tstbit_i,"bii","") -BUILTIN(__builtin_HEXAGON_S4_ntstbit_i,"bii","") +BUILTIN(__builtin_HEXAGON_S2_tstbit_i,"iii","") +BUILTIN(__builtin_HEXAGON_S4_ntstbit_i,"iii","") BUILTIN(__builtin_HEXAGON_S2_setbit_i,"iii","") BUILTIN(__builtin_HEXAGON_S2_togglebit_i,"iii","") BUILTIN(__builtin_HEXAGON_S2_clrbit_i,"iii","") -BUILTIN(__builtin_HEXAGON_S2_tstbit_r,"bii","") -BUILTIN(__builtin_HEXAGON_S4_ntstbit_r,"bii","") +BUILTIN(__builtin_HEXAGON_S2_tstbit_r,"iii","") +BUILTIN(__builtin_HEXAGON_S4_ntstbit_r,"iii","") BUILTIN(__builtin_HEXAGON_S2_setbit_r,"iii","") BUILTIN(__builtin_HEXAGON_S2_togglebit_r,"iii","") BUILTIN(__builtin_HEXAGON_S2_clrbit_r,"iii","") @@ -875,4 +883,623 @@ BUILTIN(__builtin_HEXAGON_S2_ct1p,"iLLi","") BUILTIN(__builtin_HEXAGON_S2_interleave,"LLiLLi","") BUILTIN(__builtin_HEXAGON_S2_deinterleave,"LLiLLi","") +BUILTIN(__builtin_HEXAGON_S6_rol_i_r,"iii","v:60:") +BUILTIN(__builtin_HEXAGON_S6_rol_i_p,"LLiLLii","v:60:") +BUILTIN(__builtin_HEXAGON_S6_rol_i_r_acc,"iiii","v:60:") +BUILTIN(__builtin_HEXAGON_S6_rol_i_p_acc,"LLiLLiLLii","v:60:") +BUILTIN(__builtin_HEXAGON_S6_rol_i_r_nac,"iiii","v:60:") +BUILTIN(__builtin_HEXAGON_S6_rol_i_p_nac,"LLiLLiLLii","v:60:") +BUILTIN(__builtin_HEXAGON_S6_rol_i_r_xacc,"iiii","v:60:") +BUILTIN(__builtin_HEXAGON_S6_rol_i_p_xacc,"LLiLLiLLii","v:60:") +BUILTIN(__builtin_HEXAGON_S6_rol_i_r_and,"iiii","v:60:") +BUILTIN(__builtin_HEXAGON_S6_rol_i_r_or,"iiii","v:60:") +BUILTIN(__builtin_HEXAGON_S6_rol_i_p_and,"LLiLLiLLii","v:60:") +BUILTIN(__builtin_HEXAGON_S6_rol_i_p_or,"LLiLLiLLii","v:60:") +BUILTIN(__builtin_HEXAGON_S2_cabacencbin,"LLiLLiLLii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_valignb,"V16iV16iV16ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_valignb_128B,"V32iV32iV32ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vlalignb,"V16iV16iV16ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vlalignb_128B,"V32iV32iV32ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_valignbi,"V16iV16iV16ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_valignbi_128B,"V32iV32iV32ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vlalignbi,"V16iV16iV16ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vlalignbi_128B,"V32iV32iV32ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vror,"V16iV16ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vror_128B,"V32iV32ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vunpackub,"V32iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vunpackub_128B,"V64iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vunpackb,"V32iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vunpackb_128B,"V64iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vunpackuh,"V32iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vunpackuh_128B,"V64iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vunpackh,"V32iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vunpackh_128B,"V64iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vunpackob,"V32iV32iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vunpackob_128B,"V64iV64iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vunpackoh,"V32iV32iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vunpackoh_128B,"V64iV64iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vpackeb,"V16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vpackeb_128B,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vpackeh,"V16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vpackeh_128B,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vpackob,"V16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vpackob_128B,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vpackoh,"V16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vpackoh_128B,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vpackhub_sat,"V16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vpackhub_sat_128B,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vpackhb_sat,"V16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vpackhb_sat_128B,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vpackwuh_sat,"V16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vpackwuh_sat_128B,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vpackwh_sat,"V16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vpackwh_sat_128B,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vzb,"V32iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vzb_128B,"V64iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vsb,"V32iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vsb_128B,"V64iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vzh,"V32iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vzh_128B,"V64iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vsh,"V32iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vsh_128B,"V64iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vdmpybus,"V16iV16ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vdmpybus_128B,"V32iV32ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vdmpybus_acc,"V16iV16iV16ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vdmpybus_acc_128B,"V32iV32iV32ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vdmpybus_dv,"V32iV32ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vdmpybus_dv_128B,"V64iV64ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vdmpybus_dv_acc,"V32iV32iV32ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vdmpybus_dv_acc_128B,"V64iV64iV64ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vdmpyhb,"V16iV16ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vdmpyhb_128B,"V32iV32ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vdmpyhb_acc,"V16iV16iV16ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vdmpyhb_acc_128B,"V32iV32iV32ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vdmpyhb_dv,"V32iV32ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vdmpyhb_dv_128B,"V64iV64ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vdmpyhb_dv_acc,"V32iV32iV32ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vdmpyhb_dv_acc_128B,"V64iV64iV64ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vdmpyhvsat,"V16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vdmpyhvsat_128B,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vdmpyhvsat_acc,"V16iV16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vdmpyhvsat_acc_128B,"V32iV32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vdmpyhsat,"V16iV16ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vdmpyhsat_128B,"V32iV32ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vdmpyhsat_acc,"V16iV16iV16ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vdmpyhsat_acc_128B,"V32iV32iV32ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vdmpyhisat,"V16iV32ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vdmpyhisat_128B,"V32iV64ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vdmpyhisat_acc,"V16iV16iV32ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vdmpyhisat_acc_128B,"V32iV32iV64ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vdmpyhsusat,"V16iV16ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vdmpyhsusat_128B,"V32iV32ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vdmpyhsusat_acc,"V16iV16iV16ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vdmpyhsusat_acc_128B,"V32iV32iV32ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vdmpyhsuisat,"V16iV32ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vdmpyhsuisat_128B,"V32iV64ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vdmpyhsuisat_acc,"V16iV16iV32ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vdmpyhsuisat_acc_128B,"V32iV32iV64ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vtmpyb,"V32iV32ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vtmpyb_128B,"V64iV64ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vtmpyb_acc,"V32iV32iV32ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vtmpyb_acc_128B,"V64iV64iV64ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vtmpybus,"V32iV32ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vtmpybus_128B,"V64iV64ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vtmpybus_acc,"V32iV32iV32ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vtmpybus_acc_128B,"V64iV64iV64ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vtmpyhb,"V32iV32ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vtmpyhb_128B,"V64iV64ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vtmpyhb_acc,"V32iV32iV32ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vtmpyhb_acc_128B,"V64iV64iV64ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vrmpyub,"V16iV16ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vrmpyub_128B,"V32iV32ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vrmpyub_acc,"V16iV16iV16ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vrmpyub_acc_128B,"V32iV32iV32ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vrmpyubv,"V16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vrmpyubv_128B,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vrmpyubv_acc,"V16iV16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vrmpyubv_acc_128B,"V32iV32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vrmpybv,"V16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vrmpybv_128B,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vrmpybv_acc,"V16iV16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vrmpybv_acc_128B,"V32iV32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vrmpyubi,"V32iV32iii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vrmpyubi_128B,"V64iV64iii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vrmpyubi_acc,"V32iV32iV32iii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vrmpyubi_acc_128B,"V64iV64iV64iii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vrmpybus,"V16iV16ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vrmpybus_128B,"V32iV32ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vrmpybus_acc,"V16iV16iV16ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vrmpybus_acc_128B,"V32iV32iV32ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vrmpybusi,"V32iV32iii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vrmpybusi_128B,"V64iV64iii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vrmpybusi_acc,"V32iV32iV32iii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vrmpybusi_acc_128B,"V64iV64iV64iii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vrmpybusv,"V16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vrmpybusv_128B,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vrmpybusv_acc,"V16iV16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vrmpybusv_acc_128B,"V32iV32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vdsaduh,"V32iV32ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vdsaduh_128B,"V64iV64ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vdsaduh_acc,"V32iV32iV32ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vdsaduh_acc_128B,"V64iV64iV64ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vrsadubi,"V32iV32iii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vrsadubi_128B,"V64iV64iii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vrsadubi_acc,"V32iV32iV32iii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vrsadubi_acc_128B,"V64iV64iV64iii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vasrw,"V16iV16ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vasrw_128B,"V32iV32ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vaslw,"V16iV16ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vaslw_128B,"V32iV32ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vlsrw,"V16iV16ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vlsrw_128B,"V32iV32ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vasrwv,"V16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vasrwv_128B,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vaslwv,"V16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vaslwv_128B,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vlsrwv,"V16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vlsrwv_128B,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vasrh,"V16iV16ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vasrh_128B,"V32iV32ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vaslh,"V16iV16ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vaslh_128B,"V32iV32ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vlsrh,"V16iV16ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vlsrh_128B,"V32iV32ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vasrhv,"V16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vasrhv_128B,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vaslhv,"V16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vaslhv_128B,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vlsrhv,"V16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vlsrhv_128B,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vasrwh,"V16iV16iV16ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vasrwh_128B,"V32iV32iV32ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vasrwhsat,"V16iV16iV16ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vasrwhsat_128B,"V32iV32iV32ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vasrwhrndsat,"V16iV16iV16ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vasrwhrndsat_128B,"V32iV32iV32ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vasrwuhsat,"V16iV16iV16ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vasrwuhsat_128B,"V32iV32iV32ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vroundwh,"V16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vroundwh_128B,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vroundwuh,"V16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vroundwuh_128B,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vasrhubsat,"V16iV16iV16ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vasrhubsat_128B,"V32iV32iV32ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vasrhubrndsat,"V16iV16iV16ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vasrhubrndsat_128B,"V32iV32iV32ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vasrhbrndsat,"V16iV16iV16ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vasrhbrndsat_128B,"V32iV32iV32ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vroundhb,"V16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vroundhb_128B,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vroundhub,"V16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vroundhub_128B,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vaslw_acc,"V16iV16iV16ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vaslw_acc_128B,"V32iV32iV32ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vasrw_acc,"V16iV16iV16ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vasrw_acc_128B,"V32iV32iV32ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vaddb,"V16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vaddb_128B,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vsubb,"V16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vsubb_128B,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vaddb_dv,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vaddb_dv_128B,"V64iV64iV64i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vsubb_dv,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vsubb_dv_128B,"V64iV64iV64i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vaddh,"V16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vaddh_128B,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vsubh,"V16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vsubh_128B,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vaddh_dv,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vaddh_dv_128B,"V64iV64iV64i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vsubh_dv,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vsubh_dv_128B,"V64iV64iV64i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vaddw,"V16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vaddw_128B,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vsubw,"V16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vsubw_128B,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vaddw_dv,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vaddw_dv_128B,"V64iV64iV64i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vsubw_dv,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vsubw_dv_128B,"V64iV64iV64i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vaddubsat,"V16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vaddubsat_128B,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vaddubsat_dv,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vaddubsat_dv_128B,"V64iV64iV64i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vsububsat,"V16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vsububsat_128B,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vsububsat_dv,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vsububsat_dv_128B,"V64iV64iV64i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vadduhsat,"V16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vadduhsat_128B,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vadduhsat_dv,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vadduhsat_dv_128B,"V64iV64iV64i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vsubuhsat,"V16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vsubuhsat_128B,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vsubuhsat_dv,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vsubuhsat_dv_128B,"V64iV64iV64i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vaddhsat,"V16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vaddhsat_128B,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vaddhsat_dv,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vaddhsat_dv_128B,"V64iV64iV64i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vsubhsat,"V16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vsubhsat_128B,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vsubhsat_dv,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vsubhsat_dv_128B,"V64iV64iV64i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vaddwsat,"V16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vaddwsat_128B,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vaddwsat_dv,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vaddwsat_dv_128B,"V64iV64iV64i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vsubwsat,"V16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vsubwsat_128B,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vsubwsat_dv,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vsubwsat_dv_128B,"V64iV64iV64i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vavgub,"V16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vavgub_128B,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vavgubrnd,"V16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vavgubrnd_128B,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vavguh,"V16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vavguh_128B,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vavguhrnd,"V16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vavguhrnd_128B,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vavgh,"V16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vavgh_128B,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vavghrnd,"V16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vavghrnd_128B,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vnavgh,"V16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vnavgh_128B,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vavgw,"V16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vavgw_128B,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vavgwrnd,"V16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vavgwrnd_128B,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vnavgw,"V16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vnavgw_128B,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vabsdiffub,"V16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vabsdiffub_128B,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vabsdiffuh,"V16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vabsdiffuh_128B,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vabsdiffh,"V16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vabsdiffh_128B,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vabsdiffw,"V16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vabsdiffw_128B,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vnavgub,"V16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vnavgub_128B,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vaddubh,"V32iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vaddubh_128B,"V64iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vsububh,"V32iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vsububh_128B,"V64iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vaddhw,"V32iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vaddhw_128B,"V64iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vsubhw,"V32iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vsubhw_128B,"V64iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vadduhw,"V32iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vadduhw_128B,"V64iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vsubuhw,"V32iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vsubuhw_128B,"V64iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vd0,"V16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vd0_128B,"V32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vaddbq,"V16iV16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vaddbq_128B,"V32iV32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vsubbq,"V16iV16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vsubbq_128B,"V32iV32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vaddbnq,"V16iV16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vaddbnq_128B,"V32iV32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vsubbnq,"V16iV16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vsubbnq_128B,"V32iV32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vaddhq,"V16iV16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vaddhq_128B,"V32iV32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vsubhq,"V16iV16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vsubhq_128B,"V32iV32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vaddhnq,"V16iV16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vaddhnq_128B,"V32iV32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vsubhnq,"V16iV16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vsubhnq_128B,"V32iV32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vaddwq,"V16iV16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vaddwq_128B,"V32iV32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vsubwq,"V16iV16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vsubwq_128B,"V32iV32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vaddwnq,"V16iV16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vaddwnq_128B,"V32iV32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vsubwnq,"V16iV16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vsubwnq_128B,"V32iV32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vabsh,"V16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vabsh_128B,"V32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vabsh_sat,"V16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vabsh_sat_128B,"V32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vabsw,"V16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vabsw_128B,"V32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vabsw_sat,"V16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vabsw_sat_128B,"V32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmpybv,"V32iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmpybv_128B,"V64iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmpybv_acc,"V32iV32iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmpybv_acc_128B,"V64iV64iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmpyubv,"V32iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmpyubv_128B,"V64iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmpyubv_acc,"V32iV32iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmpyubv_acc_128B,"V64iV64iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmpybusv,"V32iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmpybusv_128B,"V64iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmpybusv_acc,"V32iV32iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmpybusv_acc_128B,"V64iV64iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmpabusv,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmpabusv_128B,"V64iV64iV64i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmpabuuv,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmpabuuv_128B,"V64iV64iV64i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmpyhv,"V32iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmpyhv_128B,"V64iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmpyhv_acc,"V32iV32iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmpyhv_acc_128B,"V64iV64iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmpyuhv,"V32iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmpyuhv_128B,"V64iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmpyuhv_acc,"V32iV32iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmpyuhv_acc_128B,"V64iV64iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmpyhvsrs,"V16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmpyhvsrs_128B,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmpyhus,"V32iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmpyhus_128B,"V64iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmpyhus_acc,"V32iV32iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmpyhus_acc_128B,"V64iV64iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmpyih,"V16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmpyih_128B,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmpyih_acc,"V16iV16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmpyih_acc_128B,"V32iV32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmpyewuh,"V16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmpyewuh_128B,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmpyowh,"V16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmpyowh_128B,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmpyowh_rnd,"V16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmpyowh_rnd_128B,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmpyowh_sacc,"V16iV16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmpyowh_sacc_128B,"V32iV32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmpyowh_rnd_sacc,"V16iV16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmpyowh_rnd_sacc_128B,"V32iV32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmpyieoh,"V16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmpyieoh_128B,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmpyiewuh,"V16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmpyiewuh_128B,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmpyiowh,"V16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmpyiowh_128B,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmpyiewh_acc,"V16iV16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmpyiewh_acc_128B,"V32iV32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmpyiewuh_acc,"V16iV16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmpyiewuh_acc_128B,"V32iV32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmpyub,"V32iV16ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmpyub_128B,"V64iV32ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmpyub_acc,"V32iV32iV16ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmpyub_acc_128B,"V64iV64iV32ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmpybus,"V32iV16ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmpybus_128B,"V64iV32ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmpybus_acc,"V32iV32iV16ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmpybus_acc_128B,"V64iV64iV32ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmpabus,"V32iV32ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmpabus_128B,"V64iV64ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmpabus_acc,"V32iV32iV32ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmpabus_acc_128B,"V64iV64iV64ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmpahb,"V32iV32ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmpahb_128B,"V64iV64ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmpahb_acc,"V32iV32iV32ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmpahb_acc_128B,"V64iV64iV64ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmpyh,"V32iV16ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmpyh_128B,"V64iV32ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmpyhsat_acc,"V32iV32iV16ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmpyhsat_acc_128B,"V64iV64iV32ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmpyhss,"V16iV16ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmpyhss_128B,"V32iV32ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmpyhsrs,"V16iV16ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmpyhsrs_128B,"V32iV32ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmpyuh,"V32iV16ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmpyuh_128B,"V64iV32ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmpyuh_acc,"V32iV32iV16ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmpyuh_acc_128B,"V64iV64iV32ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmpyihb,"V16iV16ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmpyihb_128B,"V32iV32ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmpyihb_acc,"V16iV16iV16ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmpyihb_acc_128B,"V32iV32iV32ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmpyiwb,"V16iV16ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmpyiwb_128B,"V32iV32ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmpyiwb_acc,"V16iV16iV16ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmpyiwb_acc_128B,"V32iV32iV32ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmpyiwh,"V16iV16ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmpyiwh_128B,"V32iV32ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmpyiwh_acc,"V16iV16iV16ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmpyiwh_acc_128B,"V32iV32iV32ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vand,"V16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vand_128B,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vor,"V16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vor_128B,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vxor,"V16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vxor_128B,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vnot,"V16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vnot_128B,"V32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vandqrt,"V16iV16ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vandqrt_128B,"V32iV32ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vandqrt_acc,"V16iV16iV16ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vandqrt_acc_128B,"V32iV32iV32ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vandvrt,"V16iV16ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vandvrt_128B,"V32iV32ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vandvrt_acc,"V16iV16iV16ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vandvrt_acc_128B,"V32iV32iV32ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vgtw,"V16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vgtw_128B,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vgtw_and,"V16iV16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vgtw_and_128B,"V32iV32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vgtw_or,"V16iV16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vgtw_or_128B,"V32iV32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vgtw_xor,"V16iV16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vgtw_xor_128B,"V32iV32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_veqw,"V16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_veqw_128B,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_veqw_and,"V16iV16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_veqw_and_128B,"V32iV32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_veqw_or,"V16iV16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_veqw_or_128B,"V32iV32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_veqw_xor,"V16iV16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_veqw_xor_128B,"V32iV32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vgth,"V16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vgth_128B,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vgth_and,"V16iV16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vgth_and_128B,"V32iV32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vgth_or,"V16iV16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vgth_or_128B,"V32iV32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vgth_xor,"V16iV16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vgth_xor_128B,"V32iV32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_veqh,"V16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_veqh_128B,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_veqh_and,"V16iV16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_veqh_and_128B,"V32iV32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_veqh_or,"V16iV16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_veqh_or_128B,"V32iV32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_veqh_xor,"V16iV16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_veqh_xor_128B,"V32iV32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vgtb,"V16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vgtb_128B,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vgtb_and,"V16iV16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vgtb_and_128B,"V32iV32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vgtb_or,"V16iV16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vgtb_or_128B,"V32iV32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vgtb_xor,"V16iV16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vgtb_xor_128B,"V32iV32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_veqb,"V16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_veqb_128B,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_veqb_and,"V16iV16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_veqb_and_128B,"V32iV32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_veqb_or,"V16iV16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_veqb_or_128B,"V32iV32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_veqb_xor,"V16iV16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_veqb_xor_128B,"V32iV32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vgtuw,"V16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vgtuw_128B,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vgtuw_and,"V16iV16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vgtuw_and_128B,"V32iV32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vgtuw_or,"V16iV16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vgtuw_or_128B,"V32iV32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vgtuw_xor,"V16iV16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vgtuw_xor_128B,"V32iV32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vgtuh,"V16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vgtuh_128B,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vgtuh_and,"V16iV16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vgtuh_and_128B,"V32iV32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vgtuh_or,"V16iV16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vgtuh_or_128B,"V32iV32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vgtuh_xor,"V16iV16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vgtuh_xor_128B,"V32iV32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vgtub,"V16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vgtub_128B,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vgtub_and,"V16iV16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vgtub_and_128B,"V32iV32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vgtub_or,"V16iV16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vgtub_or_128B,"V32iV32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vgtub_xor,"V16iV16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vgtub_xor_128B,"V32iV32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_pred_or,"V16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_pred_or_128B,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_pred_and,"V16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_pred_and_128B,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_pred_not,"V16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_pred_not_128B,"V32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_pred_xor,"V16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_pred_xor_128B,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_pred_and_n,"V16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_pred_and_n_128B,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_pred_or_n,"V16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_pred_or_n_128B,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_pred_scalar2,"V16ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_pred_scalar2_128B,"V32ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmux,"V16iV16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmux_128B,"V32iV32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vswap,"V32iV16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vswap_128B,"V64iV32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmaxub,"V16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmaxub_128B,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vminub,"V16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vminub_128B,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmaxuh,"V16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmaxuh_128B,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vminuh,"V16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vminuh_128B,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmaxh,"V16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmaxh_128B,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vminh,"V16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vminh_128B,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmaxw,"V16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vmaxw_128B,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vminw,"V16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vminw_128B,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vsathub,"V16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vsathub_128B,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vsatwh,"V16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vsatwh_128B,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vshuffeb,"V16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vshuffeb_128B,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vshuffob,"V16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vshuffob_128B,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vshufeh,"V16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vshufeh_128B,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vshufoh,"V16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vshufoh_128B,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vshuffvdd,"V32iV16iV16ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vshuffvdd_128B,"V64iV32iV32ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vdealvdd,"V32iV16iV16ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vdealvdd_128B,"V64iV32iV32ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vshufoeh,"V32iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vshufoeh_128B,"V64iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vshufoeb,"V32iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vshufoeb_128B,"V64iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vdealh,"V16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vdealh_128B,"V32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vdealb,"V16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vdealb_128B,"V32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vdealb4w,"V16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vdealb4w_128B,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vshuffh,"V16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vshuffh_128B,"V32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vshuffb,"V16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vshuffb_128B,"V32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_extractw,"iV16ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_extractw_128B,"iV32ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vinsertwr,"V16iV16ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vinsertwr_128B,"V32iV32ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_lvsplatw,"V16ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_lvsplatw_128B,"V32ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vassign,"V16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vassign_128B,"V32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vcombine,"V32iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vcombine_128B,"V64iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vlutb,"V16iV16iLLii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vlutb_128B,"V32iV32iLLii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vlutb_acc,"V16iV16iV16iLLii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vlutb_acc_128B,"V32iV32iV32iLLii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vlutb_dv,"V32iV32iLLii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vlutb_dv_128B,"V64iV64iLLii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vlutb_dv_acc,"V32iV32iV32iLLii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vlutb_dv_acc_128B,"V64iV64iV64iLLii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vdelta,"V16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vdelta_128B,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vrdelta,"V16iV16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vrdelta_128B,"V32iV32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vcl0w,"V16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vcl0w_128B,"V32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vcl0h,"V16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vcl0h_128B,"V32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vnormamtw,"V16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vnormamtw_128B,"V32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vnormamth,"V16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vnormamth_128B,"V32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vpopcounth,"V16iV16i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vpopcounth_128B,"V32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vlutvvb,"V16iV16iV16ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vlutvvb_128B,"V32iV32iV32ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vlutvvb_oracc,"V16iV16iV16iV16ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vlutvvb_oracc_128B,"V32iV32iV32iV32ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vlutvwh,"V32iV16iV16ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vlutvwh_128B,"V64iV32iV32ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vlutvwh_oracc,"V32iV32iV16iV16ii","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vlutvwh_oracc_128B,"V64iV64iV32iV32ii","v:60:") + +BUILTIN(__builtin_HEXAGON_V6_hi,"V16iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_lo,"V16iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_hi_128B,"V32iV64i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_lo_128B,"V32iV64i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vassignp,"V32iV32i","v:60:") +BUILTIN(__builtin_HEXAGON_V6_vassignp_128B,"V64iV64i","v:60:") + #undef BUILTIN diff --git a/include/clang/Basic/BuiltinsNVPTX.def b/include/clang/Basic/BuiltinsNVPTX.def index 3ab6413bb0ec3..456d0001a12d4 100644 --- a/include/clang/Basic/BuiltinsNVPTX.def +++ b/include/clang/Basic/BuiltinsNVPTX.def @@ -14,53 +14,50 @@ // The format of this database matches clang/Basic/Builtins.def. -// Builtins retained from previous PTX back-end -BUILTIN(__builtin_ptx_read_tid_x, "i", "nc") -BUILTIN(__builtin_ptx_read_tid_y, "i", "nc") -BUILTIN(__builtin_ptx_read_tid_z, "i", "nc") -BUILTIN(__builtin_ptx_read_tid_w, "i", "nc") +// Special Registers + +BUILTIN(__nvvm_read_ptx_sreg_tid_x, "i", "nc") +BUILTIN(__nvvm_read_ptx_sreg_tid_y, "i", "nc") +BUILTIN(__nvvm_read_ptx_sreg_tid_z, "i", "nc") +BUILTIN(__nvvm_read_ptx_sreg_tid_w, "i", "nc") + +BUILTIN(__nvvm_read_ptx_sreg_ntid_x, "i", "nc") +BUILTIN(__nvvm_read_ptx_sreg_ntid_y, "i", "nc") +BUILTIN(__nvvm_read_ptx_sreg_ntid_z, "i", "nc") +BUILTIN(__nvvm_read_ptx_sreg_ntid_w, "i", "nc") + +BUILTIN(__nvvm_read_ptx_sreg_ctaid_x, "i", "nc") +BUILTIN(__nvvm_read_ptx_sreg_ctaid_y, "i", "nc") +BUILTIN(__nvvm_read_ptx_sreg_ctaid_z, "i", "nc") +BUILTIN(__nvvm_read_ptx_sreg_ctaid_w, "i", "nc") + +BUILTIN(__nvvm_read_ptx_sreg_nctaid_x, "i", "nc") +BUILTIN(__nvvm_read_ptx_sreg_nctaid_y, "i", "nc") +BUILTIN(__nvvm_read_ptx_sreg_nctaid_z, "i", "nc") +BUILTIN(__nvvm_read_ptx_sreg_nctaid_w, "i", "nc") + +BUILTIN(__nvvm_read_ptx_sreg_laneid, "i", "nc") +BUILTIN(__nvvm_read_ptx_sreg_warpid, "i", "nc") +BUILTIN(__nvvm_read_ptx_sreg_nwarpid, "i", "nc") + +BUILTIN(__nvvm_read_ptx_sreg_smid, "i", "nc") +BUILTIN(__nvvm_read_ptx_sreg_nsmid, "i", "nc") +BUILTIN(__nvvm_read_ptx_sreg_gridid, "i", "nc") + +BUILTIN(__nvvm_read_ptx_sreg_lanemask_eq, "i", "nc") +BUILTIN(__nvvm_read_ptx_sreg_lanemask_le, "i", "nc") +BUILTIN(__nvvm_read_ptx_sreg_lanemask_lt, "i", "nc") +BUILTIN(__nvvm_read_ptx_sreg_lanemask_ge, "i", "nc") +BUILTIN(__nvvm_read_ptx_sreg_lanemask_gt, "i", "nc") + +BUILTIN(__nvvm_read_ptx_sreg_clock, "i", "n") +BUILTIN(__nvvm_read_ptx_sreg_clock64, "LLi", "n") + +BUILTIN(__nvvm_read_ptx_sreg_pm0, "i", "n") +BUILTIN(__nvvm_read_ptx_sreg_pm1, "i", "n") +BUILTIN(__nvvm_read_ptx_sreg_pm2, "i", "n") +BUILTIN(__nvvm_read_ptx_sreg_pm3, "i", "n") -BUILTIN(__builtin_ptx_read_ntid_x, "i", "nc") -BUILTIN(__builtin_ptx_read_ntid_y, "i", "nc") -BUILTIN(__builtin_ptx_read_ntid_z, "i", "nc") -BUILTIN(__builtin_ptx_read_ntid_w, "i", "nc") - -BUILTIN(__builtin_ptx_read_ctaid_x, "i", "nc") -BUILTIN(__builtin_ptx_read_ctaid_y, "i", "nc") -BUILTIN(__builtin_ptx_read_ctaid_z, "i", "nc") -BUILTIN(__builtin_ptx_read_ctaid_w, "i", "nc") - -BUILTIN(__builtin_ptx_read_nctaid_x, "i", "nc") -BUILTIN(__builtin_ptx_read_nctaid_y, "i", "nc") -BUILTIN(__builtin_ptx_read_nctaid_z, "i", "nc") -BUILTIN(__builtin_ptx_read_nctaid_w, "i", "nc") - -BUILTIN(__builtin_ptx_read_laneid, "i", "nc") -BUILTIN(__builtin_ptx_read_warpid, "i", "nc") -BUILTIN(__builtin_ptx_read_nwarpid, "i", "nc") - -BUILTIN(__builtin_ptx_read_smid, "i", "nc") -BUILTIN(__builtin_ptx_read_nsmid, "i", "nc") -BUILTIN(__builtin_ptx_read_gridid, "i", "nc") - -BUILTIN(__builtin_ptx_read_lanemask_eq, "i", "nc") -BUILTIN(__builtin_ptx_read_lanemask_le, "i", "nc") -BUILTIN(__builtin_ptx_read_lanemask_lt, "i", "nc") -BUILTIN(__builtin_ptx_read_lanemask_ge, "i", "nc") -BUILTIN(__builtin_ptx_read_lanemask_gt, "i", "nc") - -BUILTIN(__builtin_ptx_read_clock, "i", "n") -BUILTIN(__builtin_ptx_read_clock64, "LLi", "n") - -BUILTIN(__builtin_ptx_read_pm0, "i", "n") -BUILTIN(__builtin_ptx_read_pm1, "i", "n") -BUILTIN(__builtin_ptx_read_pm2, "i", "n") -BUILTIN(__builtin_ptx_read_pm3, "i", "n") - -BUILTIN(__builtin_ptx_bar_sync, "vi", "n") - - -// Builtins exposed as part of NVVM // MISC BUILTIN(__nvvm_clz_i, "ii", "") @@ -397,10 +394,21 @@ BUILTIN(__nvvm_bitcast_d2ll, "LLid", "") // Sync BUILTIN(__syncthreads, "v", "") -BUILTIN(__nvvm_bar0, "v", "") BUILTIN(__nvvm_bar0_popc, "ii", "") BUILTIN(__nvvm_bar0_and, "ii", "") BUILTIN(__nvvm_bar0_or, "ii", "") +BUILTIN(__nvvm_bar_sync, "vi", "n") + +// Shuffle + +BUILTIN(__nvvm_shfl_down_i32, "iiii", "") +BUILTIN(__nvvm_shfl_down_f32, "ffii", "") +BUILTIN(__nvvm_shfl_up_i32, "iiii", "") +BUILTIN(__nvvm_shfl_up_f32, "ffii", "") +BUILTIN(__nvvm_shfl_bfly_i32, "iiii", "") +BUILTIN(__nvvm_shfl_bfly_f32, "ffii", "") +BUILTIN(__nvvm_shfl_idx_i32, "iiii", "") +BUILTIN(__nvvm_shfl_idx_f32, "ffii", "") // Membar @@ -566,4 +574,40 @@ BUILTIN(__nvvm_atom_cas_gen_ll, "LLiLLiD*LLiLLi", "n") BUILTIN(__nvvm_compiler_error, "vcC*4", "n") BUILTIN(__nvvm_compiler_warn, "vcC*4", "n") +// __ldg. This is not implemented as a builtin by nvcc. +BUILTIN(__nvvm_ldg_c, "ccC*", "") +BUILTIN(__nvvm_ldg_s, "ssC*", "") +BUILTIN(__nvvm_ldg_i, "iiC*", "") +BUILTIN(__nvvm_ldg_l, "LiLiC*", "") +BUILTIN(__nvvm_ldg_ll, "LLiLLiC*", "") + +BUILTIN(__nvvm_ldg_uc, "UcUcC*", "") +BUILTIN(__nvvm_ldg_us, "UsUsC*", "") +BUILTIN(__nvvm_ldg_ui, "UiUiC*", "") +BUILTIN(__nvvm_ldg_ul, "ULiULiC*", "") +BUILTIN(__nvvm_ldg_ull, "ULLiULLiC*", "") + +BUILTIN(__nvvm_ldg_f, "ffC*", "") +BUILTIN(__nvvm_ldg_d, "ddC*", "") + +BUILTIN(__nvvm_ldg_c2, "E2cE2cC*", "") +BUILTIN(__nvvm_ldg_c4, "E4cE4cC*", "") +BUILTIN(__nvvm_ldg_s2, "E2sE2sC*", "") +BUILTIN(__nvvm_ldg_s4, "E4sE4sC*", "") +BUILTIN(__nvvm_ldg_i2, "E2iE2iC*", "") +BUILTIN(__nvvm_ldg_i4, "E4iE4iC*", "") +BUILTIN(__nvvm_ldg_ll2, "E2LLiE2LLiC*", "") + +BUILTIN(__nvvm_ldg_uc2, "E2UcE2UcC*", "") +BUILTIN(__nvvm_ldg_uc4, "E4UcE4UcC*", "") +BUILTIN(__nvvm_ldg_us2, "E2UsE2UsC*", "") +BUILTIN(__nvvm_ldg_us4, "E4UsE4UsC*", "") +BUILTIN(__nvvm_ldg_ui2, "E2UiE2UiC*", "") +BUILTIN(__nvvm_ldg_ui4, "E4UiE4UiC*", "") +BUILTIN(__nvvm_ldg_ull2, "E2ULLiE2ULLiC*", "") + +BUILTIN(__nvvm_ldg_f2, "E2fE2fC*", "") +BUILTIN(__nvvm_ldg_f4, "E4fE4fC*", "") +BUILTIN(__nvvm_ldg_d2, "E2dE2dC*", "") + #undef BUILTIN diff --git a/include/clang/Basic/BuiltinsPPC.def b/include/clang/Basic/BuiltinsPPC.def index 5681c1f2ae1a0..365dcc02a46d3 100644 --- a/include/clang/Basic/BuiltinsPPC.def +++ b/include/clang/Basic/BuiltinsPPC.def @@ -336,6 +336,9 @@ BUILTIN(__builtin_vsx_xxleqv, "V4UiV4UiV4Ui", "") BUILTIN(__builtin_vsx_xvcpsgndp, "V2dV2dV2d", "") BUILTIN(__builtin_vsx_xvcpsgnsp, "V4fV4fV4f", "") +BUILTIN(__builtin_vsx_xvabssp, "V4fV4f", "") +BUILTIN(__builtin_vsx_xvabsdp, "V2dV2d", "") + // HTM builtins BUILTIN(__builtin_tbegin, "UiUIi", "") BUILTIN(__builtin_tend, "UiUIi", "") diff --git a/include/clang/Basic/BuiltinsSystemZ.def b/include/clang/Basic/BuiltinsSystemZ.def index 68d5a1c944073..fa96e10b3990c 100644 --- a/include/clang/Basic/BuiltinsSystemZ.def +++ b/include/clang/Basic/BuiltinsSystemZ.def @@ -14,239 +14,244 @@ // The format of this database matches clang/Basic/Builtins.def. +#if defined(BUILTIN) && !defined(TARGET_BUILTIN) +# define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) BUILTIN(ID, TYPE, ATTRS) +#endif + // Transactional-memory intrinsics -BUILTIN(__builtin_tbegin, "iv*", "j") -BUILTIN(__builtin_tbegin_nofloat, "iv*", "j") -BUILTIN(__builtin_tbeginc, "v", "nj") -BUILTIN(__builtin_tabort, "vi", "r") -BUILTIN(__builtin_tend, "i", "n") -BUILTIN(__builtin_tx_nesting_depth, "i", "nc") -BUILTIN(__builtin_tx_assist, "vi", "n") -BUILTIN(__builtin_non_tx_store, "vULi*ULi", "") +TARGET_BUILTIN(__builtin_tbegin, "iv*", "j", "transactional-execution") +TARGET_BUILTIN(__builtin_tbegin_nofloat, "iv*", "j", "transactional-execution") +TARGET_BUILTIN(__builtin_tbeginc, "v", "nj", "transactional-execution") +TARGET_BUILTIN(__builtin_tabort, "vi", "r", "transactional-execution") +TARGET_BUILTIN(__builtin_tend, "i", "n", "transactional-execution") +TARGET_BUILTIN(__builtin_tx_nesting_depth, "i", "nc", "transactional-execution") +TARGET_BUILTIN(__builtin_tx_assist, "vi", "n", "transactional-execution") +TARGET_BUILTIN(__builtin_non_tx_store, "vULi*ULi", "", "transactional-execution") // Vector intrinsics. // These all map directly to z instructions, except that some variants ending // in "s" have a final "int *" that receives the post-instruction CC value. // Vector support instructions (chapter 21 of the PoP) -BUILTIN(__builtin_s390_lcbb, "UivC*Ii", "nc") -BUILTIN(__builtin_s390_vlbb, "V16ScvC*Ii", "") -BUILTIN(__builtin_s390_vll, "V16ScUivC*", "") -BUILTIN(__builtin_s390_vstl, "vV16ScUiv*", "") -BUILTIN(__builtin_s390_vperm, "V16UcV16UcV16UcV16Uc", "nc") -BUILTIN(__builtin_s390_vpdi, "V2ULLiV2ULLiV2ULLiIi", "nc") -BUILTIN(__builtin_s390_vpksh, "V16ScV8SsV8Ss", "nc") -BUILTIN(__builtin_s390_vpkshs, "V16ScV8SsV8Ssi*", "nc") -BUILTIN(__builtin_s390_vpksf, "V8SsV4SiV4Si", "nc") -BUILTIN(__builtin_s390_vpksfs, "V8SsV4SiV4Sii*", "nc") -BUILTIN(__builtin_s390_vpksg, "V4SiV2SLLiV2SLLi", "nc") -BUILTIN(__builtin_s390_vpksgs, "V4SiV2SLLiV2SLLii*", "nc") -BUILTIN(__builtin_s390_vpklsh, "V16UcV8UsV8Us", "nc") -BUILTIN(__builtin_s390_vpklshs, "V16UcV8UsV8Usi*", "nc") -BUILTIN(__builtin_s390_vpklsf, "V8UsV4UiV4Ui", "nc") -BUILTIN(__builtin_s390_vpklsfs, "V8UsV4UiV4Uii*", "nc") -BUILTIN(__builtin_s390_vpklsg, "V4UiV2ULLiV2ULLi", "nc") -BUILTIN(__builtin_s390_vpklsgs, "V4UiV2ULLiV2ULLii*", "nc") -BUILTIN(__builtin_s390_vuphb, "V8SsV16Sc", "nc") -BUILTIN(__builtin_s390_vuphh, "V4SiV8Ss", "nc") -BUILTIN(__builtin_s390_vuphf, "V2SLLiV4Si", "nc") -BUILTIN(__builtin_s390_vuplb, "V8SsV16Sc", "nc") -BUILTIN(__builtin_s390_vuplhw, "V4SiV8Ss", "nc") -BUILTIN(__builtin_s390_vuplf, "V2SLLiV4Si", "nc") -BUILTIN(__builtin_s390_vuplhb, "V8UsV16Uc", "nc") -BUILTIN(__builtin_s390_vuplhh, "V4UiV8Us", "nc") -BUILTIN(__builtin_s390_vuplhf, "V2ULLiV4Ui", "nc") -BUILTIN(__builtin_s390_vupllb, "V8UsV16Uc", "nc") -BUILTIN(__builtin_s390_vupllh, "V4UiV8Us", "nc") -BUILTIN(__builtin_s390_vupllf, "V2ULLiV4Ui", "nc") +TARGET_BUILTIN(__builtin_s390_lcbb, "UivC*Ii", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vlbb, "V16ScvC*Ii", "", "vector") +TARGET_BUILTIN(__builtin_s390_vll, "V16ScUivC*", "", "vector") +TARGET_BUILTIN(__builtin_s390_vstl, "vV16ScUiv*", "", "vector") +TARGET_BUILTIN(__builtin_s390_vperm, "V16UcV16UcV16UcV16Uc", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vpdi, "V2ULLiV2ULLiV2ULLiIi", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vpksh, "V16ScV8SsV8Ss", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vpkshs, "V16ScV8SsV8Ssi*", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vpksf, "V8SsV4SiV4Si", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vpksfs, "V8SsV4SiV4Sii*", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vpksg, "V4SiV2SLLiV2SLLi", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vpksgs, "V4SiV2SLLiV2SLLii*", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vpklsh, "V16UcV8UsV8Us", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vpklshs, "V16UcV8UsV8Usi*", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vpklsf, "V8UsV4UiV4Ui", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vpklsfs, "V8UsV4UiV4Uii*", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vpklsg, "V4UiV2ULLiV2ULLi", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vpklsgs, "V4UiV2ULLiV2ULLii*", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vuphb, "V8SsV16Sc", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vuphh, "V4SiV8Ss", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vuphf, "V2SLLiV4Si", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vuplb, "V8SsV16Sc", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vuplhw, "V4SiV8Ss", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vuplf, "V2SLLiV4Si", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vuplhb, "V8UsV16Uc", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vuplhh, "V4UiV8Us", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vuplhf, "V2ULLiV4Ui", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vupllb, "V8UsV16Uc", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vupllh, "V4UiV8Us", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vupllf, "V2ULLiV4Ui", "nc", "vector") // Vector integer instructions (chapter 22 of the PoP) -BUILTIN(__builtin_s390_vaq, "V16UcV16UcV16Uc", "nc") -BUILTIN(__builtin_s390_vacq, "V16UcV16UcV16UcV16Uc", "nc") -BUILTIN(__builtin_s390_vaccb, "V16UcV16UcV16Uc", "nc") -BUILTIN(__builtin_s390_vacch, "V8UsV8UsV8Us", "nc") -BUILTIN(__builtin_s390_vaccf, "V4UiV4UiV4Ui", "nc") -BUILTIN(__builtin_s390_vaccg, "V2ULLiV2ULLiV2ULLi", "nc") -BUILTIN(__builtin_s390_vaccq, "V16UcV16UcV16Uc", "nc") -BUILTIN(__builtin_s390_vacccq, "V16UcV16UcV16UcV16Uc", "nc") -BUILTIN(__builtin_s390_vavgb, "V16ScV16ScV16Sc", "nc") -BUILTIN(__builtin_s390_vavgh, "V8SsV8SsV8Ss", "nc") -BUILTIN(__builtin_s390_vavgf, "V4SiV4SiV4Si", "nc") -BUILTIN(__builtin_s390_vavgg, "V2SLLiV2SLLiV2SLLi", "nc") -BUILTIN(__builtin_s390_vavglb, "V16UcV16UcV16Uc", "nc") -BUILTIN(__builtin_s390_vavglh, "V8UsV8UsV8Us", "nc") -BUILTIN(__builtin_s390_vavglf, "V4UiV4UiV4Ui", "nc") -BUILTIN(__builtin_s390_vavglg, "V2ULLiV2ULLiV2ULLi", "nc") -BUILTIN(__builtin_s390_vceqbs, "V16ScV16ScV16Sci*", "nc") -BUILTIN(__builtin_s390_vceqhs, "V8SsV8SsV8Ssi*", "nc") -BUILTIN(__builtin_s390_vceqfs, "V4SiV4SiV4Sii*", "nc") -BUILTIN(__builtin_s390_vceqgs, "V2SLLiV2SLLiV2SLLii*", "nc") -BUILTIN(__builtin_s390_vchbs, "V16ScV16ScV16Sci*", "nc") -BUILTIN(__builtin_s390_vchhs, "V8SsV8SsV8Ssi*", "nc") -BUILTIN(__builtin_s390_vchfs, "V4SiV4SiV4Sii*", "nc") -BUILTIN(__builtin_s390_vchgs, "V2SLLiV2SLLiV2SLLii*", "nc") -BUILTIN(__builtin_s390_vchlbs, "V16ScV16UcV16Uci*", "nc") -BUILTIN(__builtin_s390_vchlhs, "V8SsV8UsV8Usi*", "nc") -BUILTIN(__builtin_s390_vchlfs, "V4SiV4UiV4Uii*", "nc") -BUILTIN(__builtin_s390_vchlgs, "V2SLLiV2ULLiV2ULLii*", "nc") -BUILTIN(__builtin_s390_vcksm, "V4UiV4UiV4Ui", "nc") -BUILTIN(__builtin_s390_vclzb, "V16UcV16Uc", "nc") -BUILTIN(__builtin_s390_vclzh, "V8UsV8Us", "nc") -BUILTIN(__builtin_s390_vclzf, "V4UiV4Ui", "nc") -BUILTIN(__builtin_s390_vclzg, "V2ULLiV2ULLi", "nc") -BUILTIN(__builtin_s390_vctzb, "V16UcV16Uc", "nc") -BUILTIN(__builtin_s390_vctzh, "V8UsV8Us", "nc") -BUILTIN(__builtin_s390_vctzf, "V4UiV4Ui", "nc") -BUILTIN(__builtin_s390_vctzg, "V2ULLiV2ULLi", "nc") -BUILTIN(__builtin_s390_verimb, "V16UcV16UcV16UcV16UcIi", "nc") -BUILTIN(__builtin_s390_verimh, "V8UsV8UsV8UsV8UsIi", "nc") -BUILTIN(__builtin_s390_verimf, "V4UiV4UiV4UiV4UiIi", "nc") -BUILTIN(__builtin_s390_verimg, "V2ULLiV2ULLiV2ULLiV2ULLiIi", "nc") -BUILTIN(__builtin_s390_verllb, "V16UcV16UcUi", "nc") -BUILTIN(__builtin_s390_verllh, "V8UsV8UsUi", "nc") -BUILTIN(__builtin_s390_verllf, "V4UiV4UiUi", "nc") -BUILTIN(__builtin_s390_verllg, "V2ULLiV2ULLiUi", "nc") -BUILTIN(__builtin_s390_verllvb, "V16UcV16UcV16Uc", "nc") -BUILTIN(__builtin_s390_verllvh, "V8UsV8UsV8Us", "nc") -BUILTIN(__builtin_s390_verllvf, "V4UiV4UiV4Ui", "nc") -BUILTIN(__builtin_s390_verllvg, "V2ULLiV2ULLiV2ULLi", "nc") -BUILTIN(__builtin_s390_vgfmb, "V8UsV16UcV16Uc", "nc") -BUILTIN(__builtin_s390_vgfmh, "V4UiV8UsV8Us", "nc") -BUILTIN(__builtin_s390_vgfmf, "V2ULLiV4UiV4Ui", "nc") -BUILTIN(__builtin_s390_vgfmg, "V16UcV2ULLiV2ULLi", "nc") -BUILTIN(__builtin_s390_vgfmab, "V8UsV16UcV16UcV8Us", "nc") -BUILTIN(__builtin_s390_vgfmah, "V4UiV8UsV8UsV4Ui", "nc") -BUILTIN(__builtin_s390_vgfmaf, "V2ULLiV4UiV4UiV2ULLi", "nc") -BUILTIN(__builtin_s390_vgfmag, "V16UcV2ULLiV2ULLiV16Uc", "nc") -BUILTIN(__builtin_s390_vmahb, "V16ScV16ScV16ScV16Sc", "nc") -BUILTIN(__builtin_s390_vmahh, "V8SsV8SsV8SsV8Ss", "nc") -BUILTIN(__builtin_s390_vmahf, "V4SiV4SiV4SiV4Si", "nc") -BUILTIN(__builtin_s390_vmalhb, "V16UcV16UcV16UcV16Uc", "nc") -BUILTIN(__builtin_s390_vmalhh, "V8UsV8UsV8UsV8Us", "nc") -BUILTIN(__builtin_s390_vmalhf, "V4UiV4UiV4UiV4Ui", "nc") -BUILTIN(__builtin_s390_vmaeb, "V8SsV16ScV16ScV8Ss", "nc") -BUILTIN(__builtin_s390_vmaeh, "V4SiV8SsV8SsV4Si", "nc") -BUILTIN(__builtin_s390_vmaef, "V2SLLiV4SiV4SiV2SLLi", "nc") -BUILTIN(__builtin_s390_vmaleb, "V8UsV16UcV16UcV8Us", "nc") -BUILTIN(__builtin_s390_vmaleh, "V4UiV8UsV8UsV4Ui", "nc") -BUILTIN(__builtin_s390_vmalef, "V2ULLiV4UiV4UiV2ULLi", "nc") -BUILTIN(__builtin_s390_vmaob, "V8SsV16ScV16ScV8Ss", "nc") -BUILTIN(__builtin_s390_vmaoh, "V4SiV8SsV8SsV4Si", "nc") -BUILTIN(__builtin_s390_vmaof, "V2SLLiV4SiV4SiV2SLLi", "nc") -BUILTIN(__builtin_s390_vmalob, "V8UsV16UcV16UcV8Us", "nc") -BUILTIN(__builtin_s390_vmaloh, "V4UiV8UsV8UsV4Ui", "nc") -BUILTIN(__builtin_s390_vmalof, "V2ULLiV4UiV4UiV2ULLi", "nc") -BUILTIN(__builtin_s390_vmhb, "V16ScV16ScV16Sc", "nc") -BUILTIN(__builtin_s390_vmhh, "V8SsV8SsV8Ss", "nc") -BUILTIN(__builtin_s390_vmhf, "V4SiV4SiV4Si", "nc") -BUILTIN(__builtin_s390_vmlhb, "V16UcV16UcV16Uc", "nc") -BUILTIN(__builtin_s390_vmlhh, "V8UsV8UsV8Us", "nc") -BUILTIN(__builtin_s390_vmlhf, "V4UiV4UiV4Ui", "nc") -BUILTIN(__builtin_s390_vmeb, "V8SsV16ScV16Sc", "nc") -BUILTIN(__builtin_s390_vmeh, "V4SiV8SsV8Ss", "nc") -BUILTIN(__builtin_s390_vmef, "V2SLLiV4SiV4Si", "nc") -BUILTIN(__builtin_s390_vmleb, "V8UsV16UcV16Uc", "nc") -BUILTIN(__builtin_s390_vmleh, "V4UiV8UsV8Us", "nc") -BUILTIN(__builtin_s390_vmlef, "V2ULLiV4UiV4Ui", "nc") -BUILTIN(__builtin_s390_vmob, "V8SsV16ScV16Sc", "nc") -BUILTIN(__builtin_s390_vmoh, "V4SiV8SsV8Ss", "nc") -BUILTIN(__builtin_s390_vmof, "V2SLLiV4SiV4Si", "nc") -BUILTIN(__builtin_s390_vmlob, "V8UsV16UcV16Uc", "nc") -BUILTIN(__builtin_s390_vmloh, "V4UiV8UsV8Us", "nc") -BUILTIN(__builtin_s390_vmlof, "V2ULLiV4UiV4Ui", "nc") -BUILTIN(__builtin_s390_vpopctb, "V16UcV16Uc", "nc") -BUILTIN(__builtin_s390_vpopcth, "V8UsV8Us", "nc") -BUILTIN(__builtin_s390_vpopctf, "V4UiV4Ui", "nc") -BUILTIN(__builtin_s390_vpopctg, "V2ULLiV2ULLi", "nc") -BUILTIN(__builtin_s390_vsq, "V16UcV16UcV16Uc", "nc") -BUILTIN(__builtin_s390_vsbcbiq, "V16UcV16UcV16UcV16Uc", "nc") -BUILTIN(__builtin_s390_vsbiq, "V16UcV16UcV16UcV16Uc", "nc") -BUILTIN(__builtin_s390_vscbib, "V16UcV16UcV16Uc", "nc") -BUILTIN(__builtin_s390_vscbih, "V8UsV8UsV8Us", "nc") -BUILTIN(__builtin_s390_vscbif, "V4UiV4UiV4Ui", "nc") -BUILTIN(__builtin_s390_vscbig, "V2ULLiV2ULLiV2ULLi", "nc") -BUILTIN(__builtin_s390_vscbiq, "V16UcV16UcV16Uc", "nc") -BUILTIN(__builtin_s390_vsl, "V16UcV16UcV16Uc", "nc") -BUILTIN(__builtin_s390_vslb, "V16UcV16UcV16Uc", "nc") -BUILTIN(__builtin_s390_vsldb, "V16UcV16UcV16UcIi", "nc") -BUILTIN(__builtin_s390_vsra, "V16UcV16UcV16Uc", "nc") -BUILTIN(__builtin_s390_vsrab, "V16UcV16UcV16Uc", "nc") -BUILTIN(__builtin_s390_vsrl, "V16UcV16UcV16Uc", "nc") -BUILTIN(__builtin_s390_vsrlb, "V16UcV16UcV16Uc", "nc") -BUILTIN(__builtin_s390_vsumb, "V4UiV16UcV16Uc", "nc") -BUILTIN(__builtin_s390_vsumh, "V4UiV8UsV8Us", "nc") -BUILTIN(__builtin_s390_vsumgh, "V2ULLiV8UsV8Us", "nc") -BUILTIN(__builtin_s390_vsumgf, "V2ULLiV4UiV4Ui", "nc") -BUILTIN(__builtin_s390_vsumqf, "V16UcV4UiV4Ui", "nc") -BUILTIN(__builtin_s390_vsumqg, "V16UcV2ULLiV2ULLi", "nc") -BUILTIN(__builtin_s390_vtm, "iV16UcV16Uc", "nc") +TARGET_BUILTIN(__builtin_s390_vaq, "V16UcV16UcV16Uc", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vacq, "V16UcV16UcV16UcV16Uc", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vaccb, "V16UcV16UcV16Uc", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vacch, "V8UsV8UsV8Us", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vaccf, "V4UiV4UiV4Ui", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vaccg, "V2ULLiV2ULLiV2ULLi", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vaccq, "V16UcV16UcV16Uc", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vacccq, "V16UcV16UcV16UcV16Uc", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vavgb, "V16ScV16ScV16Sc", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vavgh, "V8SsV8SsV8Ss", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vavgf, "V4SiV4SiV4Si", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vavgg, "V2SLLiV2SLLiV2SLLi", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vavglb, "V16UcV16UcV16Uc", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vavglh, "V8UsV8UsV8Us", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vavglf, "V4UiV4UiV4Ui", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vavglg, "V2ULLiV2ULLiV2ULLi", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vceqbs, "V16ScV16ScV16Sci*", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vceqhs, "V8SsV8SsV8Ssi*", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vceqfs, "V4SiV4SiV4Sii*", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vceqgs, "V2SLLiV2SLLiV2SLLii*", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vchbs, "V16ScV16ScV16Sci*", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vchhs, "V8SsV8SsV8Ssi*", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vchfs, "V4SiV4SiV4Sii*", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vchgs, "V2SLLiV2SLLiV2SLLii*", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vchlbs, "V16ScV16UcV16Uci*", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vchlhs, "V8SsV8UsV8Usi*", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vchlfs, "V4SiV4UiV4Uii*", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vchlgs, "V2SLLiV2ULLiV2ULLii*", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vcksm, "V4UiV4UiV4Ui", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vclzb, "V16UcV16Uc", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vclzh, "V8UsV8Us", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vclzf, "V4UiV4Ui", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vclzg, "V2ULLiV2ULLi", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vctzb, "V16UcV16Uc", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vctzh, "V8UsV8Us", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vctzf, "V4UiV4Ui", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vctzg, "V2ULLiV2ULLi", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_verimb, "V16UcV16UcV16UcV16UcIi", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_verimh, "V8UsV8UsV8UsV8UsIi", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_verimf, "V4UiV4UiV4UiV4UiIi", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_verimg, "V2ULLiV2ULLiV2ULLiV2ULLiIi", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_verllb, "V16UcV16UcUi", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_verllh, "V8UsV8UsUi", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_verllf, "V4UiV4UiUi", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_verllg, "V2ULLiV2ULLiUi", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_verllvb, "V16UcV16UcV16Uc", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_verllvh, "V8UsV8UsV8Us", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_verllvf, "V4UiV4UiV4Ui", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_verllvg, "V2ULLiV2ULLiV2ULLi", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vgfmb, "V8UsV16UcV16Uc", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vgfmh, "V4UiV8UsV8Us", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vgfmf, "V2ULLiV4UiV4Ui", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vgfmg, "V16UcV2ULLiV2ULLi", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vgfmab, "V8UsV16UcV16UcV8Us", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vgfmah, "V4UiV8UsV8UsV4Ui", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vgfmaf, "V2ULLiV4UiV4UiV2ULLi", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vgfmag, "V16UcV2ULLiV2ULLiV16Uc", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vmahb, "V16ScV16ScV16ScV16Sc", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vmahh, "V8SsV8SsV8SsV8Ss", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vmahf, "V4SiV4SiV4SiV4Si", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vmalhb, "V16UcV16UcV16UcV16Uc", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vmalhh, "V8UsV8UsV8UsV8Us", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vmalhf, "V4UiV4UiV4UiV4Ui", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vmaeb, "V8SsV16ScV16ScV8Ss", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vmaeh, "V4SiV8SsV8SsV4Si", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vmaef, "V2SLLiV4SiV4SiV2SLLi", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vmaleb, "V8UsV16UcV16UcV8Us", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vmaleh, "V4UiV8UsV8UsV4Ui", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vmalef, "V2ULLiV4UiV4UiV2ULLi", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vmaob, "V8SsV16ScV16ScV8Ss", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vmaoh, "V4SiV8SsV8SsV4Si", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vmaof, "V2SLLiV4SiV4SiV2SLLi", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vmalob, "V8UsV16UcV16UcV8Us", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vmaloh, "V4UiV8UsV8UsV4Ui", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vmalof, "V2ULLiV4UiV4UiV2ULLi", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vmhb, "V16ScV16ScV16Sc", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vmhh, "V8SsV8SsV8Ss", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vmhf, "V4SiV4SiV4Si", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vmlhb, "V16UcV16UcV16Uc", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vmlhh, "V8UsV8UsV8Us", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vmlhf, "V4UiV4UiV4Ui", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vmeb, "V8SsV16ScV16Sc", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vmeh, "V4SiV8SsV8Ss", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vmef, "V2SLLiV4SiV4Si", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vmleb, "V8UsV16UcV16Uc", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vmleh, "V4UiV8UsV8Us", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vmlef, "V2ULLiV4UiV4Ui", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vmob, "V8SsV16ScV16Sc", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vmoh, "V4SiV8SsV8Ss", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vmof, "V2SLLiV4SiV4Si", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vmlob, "V8UsV16UcV16Uc", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vmloh, "V4UiV8UsV8Us", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vmlof, "V2ULLiV4UiV4Ui", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vpopctb, "V16UcV16Uc", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vpopcth, "V8UsV8Us", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vpopctf, "V4UiV4Ui", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vpopctg, "V2ULLiV2ULLi", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vsq, "V16UcV16UcV16Uc", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vsbcbiq, "V16UcV16UcV16UcV16Uc", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vsbiq, "V16UcV16UcV16UcV16Uc", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vscbib, "V16UcV16UcV16Uc", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vscbih, "V8UsV8UsV8Us", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vscbif, "V4UiV4UiV4Ui", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vscbig, "V2ULLiV2ULLiV2ULLi", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vscbiq, "V16UcV16UcV16Uc", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vsl, "V16UcV16UcV16Uc", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vslb, "V16UcV16UcV16Uc", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vsldb, "V16UcV16UcV16UcIi", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vsra, "V16UcV16UcV16Uc", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vsrab, "V16UcV16UcV16Uc", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vsrl, "V16UcV16UcV16Uc", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vsrlb, "V16UcV16UcV16Uc", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vsumb, "V4UiV16UcV16Uc", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vsumh, "V4UiV8UsV8Us", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vsumgh, "V2ULLiV8UsV8Us", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vsumgf, "V2ULLiV4UiV4Ui", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vsumqf, "V16UcV4UiV4Ui", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vsumqg, "V16UcV2ULLiV2ULLi", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vtm, "iV16UcV16Uc", "nc", "vector") // Vector string instructions (chapter 23 of the PoP) -BUILTIN(__builtin_s390_vfaeb, "V16UcV16UcV16UcIi", "nc") -BUILTIN(__builtin_s390_vfaebs, "V16UcV16UcV16UcIii*", "nc") -BUILTIN(__builtin_s390_vfaeh, "V8UsV8UsV8UsIi", "nc") -BUILTIN(__builtin_s390_vfaehs, "V8UsV8UsV8UsIii*", "nc") -BUILTIN(__builtin_s390_vfaef, "V4UiV4UiV4UiIi", "nc") -BUILTIN(__builtin_s390_vfaefs, "V4UiV4UiV4UiIii*", "nc") -BUILTIN(__builtin_s390_vfaezb, "V16UcV16UcV16UcIi", "nc") -BUILTIN(__builtin_s390_vfaezbs, "V16UcV16UcV16UcIii*", "nc") -BUILTIN(__builtin_s390_vfaezh, "V8UsV8UsV8UsIi", "nc") -BUILTIN(__builtin_s390_vfaezhs, "V8UsV8UsV8UsIii*", "nc") -BUILTIN(__builtin_s390_vfaezf, "V4UiV4UiV4UiIi", "nc") -BUILTIN(__builtin_s390_vfaezfs, "V4UiV4UiV4UiIii*", "nc") -BUILTIN(__builtin_s390_vfeeb, "V16UcV16UcV16Uc", "nc") -BUILTIN(__builtin_s390_vfeebs, "V16UcV16UcV16Uci*", "nc") -BUILTIN(__builtin_s390_vfeeh, "V8UsV8UsV8Us", "nc") -BUILTIN(__builtin_s390_vfeehs, "V8UsV8UsV8Usi*", "nc") -BUILTIN(__builtin_s390_vfeef, "V4UiV4UiV4Ui", "nc") -BUILTIN(__builtin_s390_vfeefs, "V4UiV4UiV4Uii*", "nc") -BUILTIN(__builtin_s390_vfeezb, "V16UcV16UcV16Uc", "nc") -BUILTIN(__builtin_s390_vfeezbs, "V16UcV16UcV16Uci*", "nc") -BUILTIN(__builtin_s390_vfeezh, "V8UsV8UsV8Us", "nc") -BUILTIN(__builtin_s390_vfeezhs, "V8UsV8UsV8Usi*", "nc") -BUILTIN(__builtin_s390_vfeezf, "V4UiV4UiV4Ui", "nc") -BUILTIN(__builtin_s390_vfeezfs, "V4UiV4UiV4Uii*", "nc") -BUILTIN(__builtin_s390_vfeneb, "V16UcV16UcV16Uc", "nc") -BUILTIN(__builtin_s390_vfenebs, "V16UcV16UcV16Uci*", "nc") -BUILTIN(__builtin_s390_vfeneh, "V8UsV8UsV8Us", "nc") -BUILTIN(__builtin_s390_vfenehs, "V8UsV8UsV8Usi*", "nc") -BUILTIN(__builtin_s390_vfenef, "V4UiV4UiV4Ui", "nc") -BUILTIN(__builtin_s390_vfenefs, "V4UiV4UiV4Uii*", "nc") -BUILTIN(__builtin_s390_vfenezb, "V16UcV16UcV16Uc", "nc") -BUILTIN(__builtin_s390_vfenezbs, "V16UcV16UcV16Uci*", "nc") -BUILTIN(__builtin_s390_vfenezh, "V8UsV8UsV8Us", "nc") -BUILTIN(__builtin_s390_vfenezhs, "V8UsV8UsV8Usi*", "nc") -BUILTIN(__builtin_s390_vfenezf, "V4UiV4UiV4Ui", "nc") -BUILTIN(__builtin_s390_vfenezfs, "V4UiV4UiV4Uii*", "nc") -BUILTIN(__builtin_s390_vistrb, "V16UcV16Uc", "nc") -BUILTIN(__builtin_s390_vistrbs, "V16UcV16Uci*", "nc") -BUILTIN(__builtin_s390_vistrh, "V8UsV8Us", "nc") -BUILTIN(__builtin_s390_vistrhs, "V8UsV8Usi*", "nc") -BUILTIN(__builtin_s390_vistrf, "V4UiV4Ui", "nc") -BUILTIN(__builtin_s390_vistrfs, "V4UiV4Uii*", "nc") -BUILTIN(__builtin_s390_vstrcb, "V16UcV16UcV16UcV16UcIi", "nc") -BUILTIN(__builtin_s390_vstrcbs, "V16UcV16UcV16UcV16UcIii*", "nc") -BUILTIN(__builtin_s390_vstrch, "V8UsV8UsV8UsV8UsIi", "nc") -BUILTIN(__builtin_s390_vstrchs, "V8UsV8UsV8UsV8UsIii*", "nc") -BUILTIN(__builtin_s390_vstrcf, "V4UiV4UiV4UiV4UiIi", "nc") -BUILTIN(__builtin_s390_vstrcfs, "V4UiV4UiV4UiV4UiIii*", "nc") -BUILTIN(__builtin_s390_vstrczb, "V16UcV16UcV16UcV16UcIi", "nc") -BUILTIN(__builtin_s390_vstrczbs, "V16UcV16UcV16UcV16UcIii*", "nc") -BUILTIN(__builtin_s390_vstrczh, "V8UsV8UsV8UsV8UsIi", "nc") -BUILTIN(__builtin_s390_vstrczhs, "V8UsV8UsV8UsV8UsIii*", "nc") -BUILTIN(__builtin_s390_vstrczf, "V4UiV4UiV4UiV4UiIi", "nc") -BUILTIN(__builtin_s390_vstrczfs, "V4UiV4UiV4UiV4UiIii*", "nc") +TARGET_BUILTIN(__builtin_s390_vfaeb, "V16UcV16UcV16UcIi", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vfaebs, "V16UcV16UcV16UcIii*", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vfaeh, "V8UsV8UsV8UsIi", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vfaehs, "V8UsV8UsV8UsIii*", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vfaef, "V4UiV4UiV4UiIi", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vfaefs, "V4UiV4UiV4UiIii*", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vfaezb, "V16UcV16UcV16UcIi", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vfaezbs, "V16UcV16UcV16UcIii*", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vfaezh, "V8UsV8UsV8UsIi", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vfaezhs, "V8UsV8UsV8UsIii*", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vfaezf, "V4UiV4UiV4UiIi", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vfaezfs, "V4UiV4UiV4UiIii*", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vfeeb, "V16UcV16UcV16Uc", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vfeebs, "V16UcV16UcV16Uci*", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vfeeh, "V8UsV8UsV8Us", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vfeehs, "V8UsV8UsV8Usi*", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vfeef, "V4UiV4UiV4Ui", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vfeefs, "V4UiV4UiV4Uii*", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vfeezb, "V16UcV16UcV16Uc", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vfeezbs, "V16UcV16UcV16Uci*", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vfeezh, "V8UsV8UsV8Us", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vfeezhs, "V8UsV8UsV8Usi*", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vfeezf, "V4UiV4UiV4Ui", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vfeezfs, "V4UiV4UiV4Uii*", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vfeneb, "V16UcV16UcV16Uc", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vfenebs, "V16UcV16UcV16Uci*", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vfeneh, "V8UsV8UsV8Us", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vfenehs, "V8UsV8UsV8Usi*", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vfenef, "V4UiV4UiV4Ui", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vfenefs, "V4UiV4UiV4Uii*", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vfenezb, "V16UcV16UcV16Uc", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vfenezbs, "V16UcV16UcV16Uci*", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vfenezh, "V8UsV8UsV8Us", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vfenezhs, "V8UsV8UsV8Usi*", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vfenezf, "V4UiV4UiV4Ui", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vfenezfs, "V4UiV4UiV4Uii*", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vistrb, "V16UcV16Uc", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vistrbs, "V16UcV16Uci*", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vistrh, "V8UsV8Us", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vistrhs, "V8UsV8Usi*", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vistrf, "V4UiV4Ui", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vistrfs, "V4UiV4Uii*", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vstrcb, "V16UcV16UcV16UcV16UcIi", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vstrcbs, "V16UcV16UcV16UcV16UcIii*", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vstrch, "V8UsV8UsV8UsV8UsIi", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vstrchs, "V8UsV8UsV8UsV8UsIii*", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vstrcf, "V4UiV4UiV4UiV4UiIi", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vstrcfs, "V4UiV4UiV4UiV4UiIii*", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vstrczb, "V16UcV16UcV16UcV16UcIi", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vstrczbs, "V16UcV16UcV16UcV16UcIii*", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vstrczh, "V8UsV8UsV8UsV8UsIi", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vstrczhs, "V8UsV8UsV8UsV8UsIii*", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vstrczf, "V4UiV4UiV4UiV4UiIi", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vstrczfs, "V4UiV4UiV4UiV4UiIii*", "nc", "vector") // Vector floating-point instructions (chapter 24 of the PoP) -BUILTIN(__builtin_s390_vfcedbs, "V2SLLiV2dV2di*", "nc") -BUILTIN(__builtin_s390_vfchdbs, "V2SLLiV2dV2di*", "nc") -BUILTIN(__builtin_s390_vfchedbs, "V2SLLiV2dV2di*", "nc") -BUILTIN(__builtin_s390_vfidb, "V2dV2dIiIi", "nc") -BUILTIN(__builtin_s390_vflndb, "V2dV2d", "nc") -BUILTIN(__builtin_s390_vflpdb, "V2dV2d", "nc") -BUILTIN(__builtin_s390_vfmadb, "V2dV2dV2dV2d", "nc") -BUILTIN(__builtin_s390_vfmsdb, "V2dV2dV2dV2d", "nc") -BUILTIN(__builtin_s390_vfsqdb, "V2dV2d", "nc") -BUILTIN(__builtin_s390_vftcidb, "V2SLLiV2dIii*", "nc") +TARGET_BUILTIN(__builtin_s390_vfcedbs, "V2SLLiV2dV2di*", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vfchdbs, "V2SLLiV2dV2di*", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vfchedbs, "V2SLLiV2dV2di*", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vfidb, "V2dV2dIiIi", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vflndb, "V2dV2d", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vflpdb, "V2dV2d", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vfmadb, "V2dV2dV2dV2d", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vfmsdb, "V2dV2dV2dV2d", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vfsqdb, "V2dV2d", "nc", "vector") +TARGET_BUILTIN(__builtin_s390_vftcidb, "V2SLLiV2dIii*", "nc", "vector") #undef BUILTIN +#undef TARGET_BUILTIN diff --git a/include/clang/Basic/BuiltinsWebAssembly.def b/include/clang/Basic/BuiltinsWebAssembly.def index 975433523ada9..97b59a1fd86cb 100644 --- a/include/clang/Basic/BuiltinsWebAssembly.def +++ b/include/clang/Basic/BuiltinsWebAssembly.def @@ -16,9 +16,9 @@ // The format of this database matches clang/Basic/Builtins.def. -// Note that memory_size is not "c" (readnone) because it must be sequenced with +// Note that current_memory is not "c" (readnone) because it must be sequenced with // respect to grow_memory calls. -BUILTIN(__builtin_wasm_memory_size, "z", "n") +BUILTIN(__builtin_wasm_current_memory, "z", "n") BUILTIN(__builtin_wasm_grow_memory, "vz", "n") #undef BUILTIN diff --git a/include/clang/Basic/BuiltinsX86.def b/include/clang/Basic/BuiltinsX86.def index f738cc12a4312..ff97693c313ed 100644 --- a/include/clang/Basic/BuiltinsX86.def +++ b/include/clang/Basic/BuiltinsX86.def @@ -161,6 +161,8 @@ TARGET_BUILTIN(__builtin_ia32_pmovmskb, "iV8c", "", "sse") TARGET_BUILTIN(__builtin_ia32_pmulhuw, "V4sV4sV4s", "", "sse") TARGET_BUILTIN(__builtin_ia32_psadbw, "V4sV8cV8c", "", "sse") TARGET_BUILTIN(__builtin_ia32_pshufw, "V4sV4sIc", "", "sse") +TARGET_BUILTIN(__builtin_ia32_vec_ext_v4hi, "iV4sIi", "", "sse") +TARGET_BUILTIN(__builtin_ia32_vec_set_v4hi, "V4sV4siIi", "", "sse") // MMX+SSE2 TARGET_BUILTIN(__builtin_ia32_cvtpd2pi, "V2iV2d", "", "sse2") @@ -215,7 +217,6 @@ TARGET_BUILTIN(__builtin_ia32_ucomisdgt, "iV2dV2d", "", "sse2") TARGET_BUILTIN(__builtin_ia32_ucomisdge, "iV2dV2d", "", "sse2") TARGET_BUILTIN(__builtin_ia32_ucomisdneq, "iV2dV2d", "", "sse2") -TARGET_BUILTIN(__builtin_ia32_cmpps, "V4fV4fV4fIc", "", "sse") TARGET_BUILTIN(__builtin_ia32_cmpeqps, "V4fV4fV4f", "", "sse") TARGET_BUILTIN(__builtin_ia32_cmpltps, "V4fV4fV4f", "", "sse") TARGET_BUILTIN(__builtin_ia32_cmpleps, "V4fV4fV4f", "", "sse") @@ -224,7 +225,6 @@ TARGET_BUILTIN(__builtin_ia32_cmpneqps, "V4fV4fV4f", "", "sse") TARGET_BUILTIN(__builtin_ia32_cmpnltps, "V4fV4fV4f", "", "sse") TARGET_BUILTIN(__builtin_ia32_cmpnleps, "V4fV4fV4f", "", "sse") TARGET_BUILTIN(__builtin_ia32_cmpordps, "V4fV4fV4f", "", "sse") -TARGET_BUILTIN(__builtin_ia32_cmpss, "V4fV4fV4fIc", "", "sse") TARGET_BUILTIN(__builtin_ia32_cmpeqss, "V4fV4fV4f", "", "sse") TARGET_BUILTIN(__builtin_ia32_cmpltss, "V4fV4fV4f", "", "sse") TARGET_BUILTIN(__builtin_ia32_cmpless, "V4fV4fV4f", "", "sse") @@ -238,7 +238,6 @@ TARGET_BUILTIN(__builtin_ia32_maxps, "V4fV4fV4f", "", "sse") TARGET_BUILTIN(__builtin_ia32_minss, "V4fV4fV4f", "", "sse") TARGET_BUILTIN(__builtin_ia32_maxss, "V4fV4fV4f", "", "sse") -TARGET_BUILTIN(__builtin_ia32_cmppd, "V2dV2dV2dIc", "", "sse2") TARGET_BUILTIN(__builtin_ia32_cmpeqpd, "V2dV2dV2d", "", "sse2") TARGET_BUILTIN(__builtin_ia32_cmpltpd, "V2dV2dV2d", "", "sse2") TARGET_BUILTIN(__builtin_ia32_cmplepd, "V2dV2dV2d", "", "sse2") @@ -247,7 +246,6 @@ TARGET_BUILTIN(__builtin_ia32_cmpneqpd, "V2dV2dV2d", "", "sse2") TARGET_BUILTIN(__builtin_ia32_cmpnltpd, "V2dV2dV2d", "", "sse2") TARGET_BUILTIN(__builtin_ia32_cmpnlepd, "V2dV2dV2d", "", "sse2") TARGET_BUILTIN(__builtin_ia32_cmpordpd, "V2dV2dV2d", "", "sse2") -TARGET_BUILTIN(__builtin_ia32_cmpsd, "V2dV2dV2dIc", "", "sse2") TARGET_BUILTIN(__builtin_ia32_cmpeqsd, "V2dV2dV2d", "", "sse2") TARGET_BUILTIN(__builtin_ia32_cmpltsd, "V2dV2dV2d", "", "sse2") TARGET_BUILTIN(__builtin_ia32_cmplesd, "V2dV2dV2d", "", "sse2") @@ -306,11 +304,9 @@ TARGET_BUILTIN(__builtin_ia32_ldmxcsr, "vUi", "", "sse") TARGET_BUILTIN(__builtin_ia32_stmxcsr, "Ui", "", "sse") TARGET_BUILTIN(__builtin_ia32_cvtss2si, "iV4f", "", "sse") TARGET_BUILTIN(__builtin_ia32_cvtss2si64, "LLiV4f", "", "sse") -TARGET_BUILTIN(__builtin_ia32_storeups, "vf*V4f", "", "sse") TARGET_BUILTIN(__builtin_ia32_storehps, "vV2i*V4f", "", "sse") TARGET_BUILTIN(__builtin_ia32_storelps, "vV2i*V4f", "", "sse") TARGET_BUILTIN(__builtin_ia32_movmskps, "iV4f", "", "sse") -TARGET_BUILTIN(__builtin_ia32_movntps, "vf*V4f", "", "sse") TARGET_BUILTIN(__builtin_ia32_sfence, "v", "", "sse") TARGET_BUILTIN(__builtin_ia32_rcpps, "V4fV4f", "", "sse") TARGET_BUILTIN(__builtin_ia32_rcpss, "V4fV4f", "", "sse") @@ -320,17 +316,13 @@ TARGET_BUILTIN(__builtin_ia32_sqrtps, "V4fV4f", "", "sse") TARGET_BUILTIN(__builtin_ia32_sqrtss, "V4fV4f", "", "sse") TARGET_BUILTIN(__builtin_ia32_maskmovdqu, "vV16cV16cc*", "", "sse2") -TARGET_BUILTIN(__builtin_ia32_storeupd, "vd*V2d", "", "sse2") TARGET_BUILTIN(__builtin_ia32_movmskpd, "iV2d", "", "sse2") TARGET_BUILTIN(__builtin_ia32_pmovmskb128, "iV16c", "", "sse2") TARGET_BUILTIN(__builtin_ia32_movnti, "vi*i", "", "sse2") TARGET_BUILTIN(__builtin_ia32_movnti64, "vLLi*LLi", "", "sse2") -TARGET_BUILTIN(__builtin_ia32_movntpd, "vd*V2d", "", "sse2") -TARGET_BUILTIN(__builtin_ia32_movntdq, "vV2LLi*V2LLi", "", "sse2") TARGET_BUILTIN(__builtin_ia32_psadbw128, "V2LLiV16cV16c", "", "sse2") TARGET_BUILTIN(__builtin_ia32_sqrtpd, "V2dV2d", "", "sse2") TARGET_BUILTIN(__builtin_ia32_sqrtsd, "V2dV2d", "", "sse2") -TARGET_BUILTIN(__builtin_ia32_cvtdq2pd, "V2dV4i", "", "sse2") TARGET_BUILTIN(__builtin_ia32_cvtdq2ps, "V4fV4i", "", "sse2") TARGET_BUILTIN(__builtin_ia32_cvtpd2dq, "V2LLiV2d", "", "sse2") TARGET_BUILTIN(__builtin_ia32_cvtpd2ps, "V4fV2d", "", "sse2") @@ -338,13 +330,10 @@ TARGET_BUILTIN(__builtin_ia32_cvttpd2dq, "V4iV2d", "", "sse2") TARGET_BUILTIN(__builtin_ia32_cvtsd2si, "iV2d", "", "sse2") TARGET_BUILTIN(__builtin_ia32_cvtsd2si64, "LLiV2d", "", "sse2") TARGET_BUILTIN(__builtin_ia32_cvtps2dq, "V4iV4f", "", "sse2") -TARGET_BUILTIN(__builtin_ia32_cvtps2pd, "V2dV4f", "", "sse2") -TARGET_BUILTIN(__builtin_ia32_cvttps2dq, "V4iV4f", "", "sse2") TARGET_BUILTIN(__builtin_ia32_clflush, "vvC*", "", "sse2") TARGET_BUILTIN(__builtin_ia32_lfence, "v", "", "sse2") TARGET_BUILTIN(__builtin_ia32_mfence, "v", "", "sse2") TARGET_BUILTIN(__builtin_ia32_pause, "v", "", "sse2") -TARGET_BUILTIN(__builtin_ia32_storedqu, "vc*V16c", "", "sse2") TARGET_BUILTIN(__builtin_ia32_pmuludq128, "V2LLiV4iV4i", "", "sse2") TARGET_BUILTIN(__builtin_ia32_psraw128, "V8sV8sV8s", "", "sse2") TARGET_BUILTIN(__builtin_ia32_psrad128, "V4iV4iV4i", "", "sse2") @@ -368,7 +357,7 @@ TARGET_BUILTIN(__builtin_ia32_monitor, "vv*UiUi", "", "sse3") TARGET_BUILTIN(__builtin_ia32_mwait, "vUiUi", "", "sse3") TARGET_BUILTIN(__builtin_ia32_lddqu, "V16ccC*", "", "sse3") -TARGET_BUILTIN(__builtin_ia32_palignr128, "V16cV16cV16cIc", "", "ssse3") +TARGET_BUILTIN(__builtin_ia32_palignr128, "V16cV16cV16cIi", "", "ssse3") TARGET_BUILTIN(__builtin_ia32_insertps128, "V4fV4fV4fIc", "", "sse4.1") TARGET_BUILTIN(__builtin_ia32_pblendvb128, "V16cV16cV16cV16c", "", "sse4.1") @@ -384,14 +373,7 @@ TARGET_BUILTIN(__builtin_ia32_pminsb128, "V16cV16cV16c", "", "sse4.1") TARGET_BUILTIN(__builtin_ia32_pminsd128, "V4iV4iV4i", "", "sse4.1") TARGET_BUILTIN(__builtin_ia32_pminud128, "V4iV4iV4i", "", "sse4.1") TARGET_BUILTIN(__builtin_ia32_pminuw128, "V8sV8sV8s", "", "sse4.1") -TARGET_BUILTIN(__builtin_ia32_pmovzxbd128, "V4iV16c", "", "sse4.1") -TARGET_BUILTIN(__builtin_ia32_pmovzxbq128, "V2LLiV16c", "", "sse4.1") -TARGET_BUILTIN(__builtin_ia32_pmovzxbw128, "V8sV16c", "", "sse4.1") -TARGET_BUILTIN(__builtin_ia32_pmovzxdq128, "V2LLiV4i", "", "sse4.1") -TARGET_BUILTIN(__builtin_ia32_pmovzxwd128, "V4iV8s", "", "sse4.1") -TARGET_BUILTIN(__builtin_ia32_pmovzxwq128, "V2LLiV8s", "", "sse4.1") TARGET_BUILTIN(__builtin_ia32_pmuldq128, "V2LLiV4iV4i", "", "sse4.1") -TARGET_BUILTIN(__builtin_ia32_pmulld128, "V4iV4iV4i", "", "sse4.1") TARGET_BUILTIN(__builtin_ia32_roundps, "V4fV4fIi", "", "sse4.1") TARGET_BUILTIN(__builtin_ia32_roundss, "V4fV4fV4fIi", "", "sse4.1") TARGET_BUILTIN(__builtin_ia32_roundsd, "V2dV2dV2dIi", "", "sse4.1") @@ -464,16 +446,16 @@ TARGET_BUILTIN(__builtin_ia32_vpermilvarps256, "V8fV8fV8i", "", "avx") TARGET_BUILTIN(__builtin_ia32_blendvpd256, "V4dV4dV4dV4d", "", "avx") TARGET_BUILTIN(__builtin_ia32_blendvps256, "V8fV8fV8fV8f", "", "avx") TARGET_BUILTIN(__builtin_ia32_dpps256, "V8fV8fV8fIc", "", "avx") +TARGET_BUILTIN(__builtin_ia32_cmppd, "V2dV2dV2dIc", "", "avx") TARGET_BUILTIN(__builtin_ia32_cmppd256, "V4dV4dV4dIc", "", "avx") +TARGET_BUILTIN(__builtin_ia32_cmpps, "V4fV4fV4fIc", "", "avx") TARGET_BUILTIN(__builtin_ia32_cmpps256, "V8fV8fV8fIc", "", "avx") -TARGET_BUILTIN(__builtin_ia32_cvtdq2pd256, "V4dV4i", "", "avx") +TARGET_BUILTIN(__builtin_ia32_cmpsd, "V2dV2dV2dIc", "", "avx") +TARGET_BUILTIN(__builtin_ia32_cmpss, "V4fV4fV4fIc", "", "avx") TARGET_BUILTIN(__builtin_ia32_cvtdq2ps256, "V8fV8i", "", "avx") TARGET_BUILTIN(__builtin_ia32_cvtpd2ps256, "V4fV4d", "", "avx") TARGET_BUILTIN(__builtin_ia32_cvtps2dq256, "V8iV8f", "", "avx") -TARGET_BUILTIN(__builtin_ia32_cvtps2pd256, "V4dV4f", "", "avx") -TARGET_BUILTIN(__builtin_ia32_cvttpd2dq256, "V4iV4d", "", "avx") TARGET_BUILTIN(__builtin_ia32_cvtpd2dq256, "V4iV4d", "", "avx") -TARGET_BUILTIN(__builtin_ia32_cvttps2dq256, "V8iV8f", "", "avx") TARGET_BUILTIN(__builtin_ia32_vperm2f128_pd256, "V4dV4dV4dIc", "", "avx") TARGET_BUILTIN(__builtin_ia32_vperm2f128_ps256, "V8fV8fV8fIc", "", "avx") TARGET_BUILTIN(__builtin_ia32_vperm2f128_si256, "V8iV8iV8iIc", "", "avx") @@ -504,13 +486,7 @@ TARGET_BUILTIN(__builtin_ia32_vzeroall, "v", "", "avx") TARGET_BUILTIN(__builtin_ia32_vzeroupper, "v", "", "avx") TARGET_BUILTIN(__builtin_ia32_vbroadcastf128_pd256, "V4dV2dC*", "", "avx") TARGET_BUILTIN(__builtin_ia32_vbroadcastf128_ps256, "V8fV4fC*", "", "avx") -TARGET_BUILTIN(__builtin_ia32_storeupd256, "vd*V4d", "", "avx") -TARGET_BUILTIN(__builtin_ia32_storeups256, "vf*V8f", "", "avx") -TARGET_BUILTIN(__builtin_ia32_storedqu256, "vc*V32c", "", "avx") TARGET_BUILTIN(__builtin_ia32_lddqu256, "V32ccC*", "", "avx") -TARGET_BUILTIN(__builtin_ia32_movntdq256, "vV4LLi*V4LLi", "", "avx") -TARGET_BUILTIN(__builtin_ia32_movntpd256, "vd*V4d", "", "avx") -TARGET_BUILTIN(__builtin_ia32_movntps256, "vf*V8f", "", "avx") TARGET_BUILTIN(__builtin_ia32_maskloadpd, "V2dV2dC*V2LLi", "", "avx") TARGET_BUILTIN(__builtin_ia32_maskloadps, "V4fV4fC*V4i", "", "avx") TARGET_BUILTIN(__builtin_ia32_maskloadpd256, "V4dV4dC*V4LLi", "", "avx") @@ -537,7 +513,7 @@ TARGET_BUILTIN(__builtin_ia32_paddusb256, "V32cV32cV32c", "", "avx2") TARGET_BUILTIN(__builtin_ia32_paddusw256, "V16sV16sV16s", "", "avx2") TARGET_BUILTIN(__builtin_ia32_psubusb256, "V32cV32cV32c", "", "avx2") TARGET_BUILTIN(__builtin_ia32_psubusw256, "V16sV16sV16s", "", "avx2") -TARGET_BUILTIN(__builtin_ia32_palignr256, "V32cV32cV32cIc", "", "avx2") +TARGET_BUILTIN(__builtin_ia32_palignr256, "V32cV32cV32cIi", "", "avx2") TARGET_BUILTIN(__builtin_ia32_pavgb256, "V32cV32cV32c", "", "avx2") TARGET_BUILTIN(__builtin_ia32_pavgw256, "V16sV16sV16s", "", "avx2") TARGET_BUILTIN(__builtin_ia32_pblendvb256, "V32cV32cV32cV32c", "", "avx2") @@ -562,18 +538,6 @@ TARGET_BUILTIN(__builtin_ia32_pminsb256, "V32cV32cV32c", "", "avx2") TARGET_BUILTIN(__builtin_ia32_pminsw256, "V16sV16sV16s", "", "avx2") TARGET_BUILTIN(__builtin_ia32_pminsd256, "V8iV8iV8i", "", "avx2") TARGET_BUILTIN(__builtin_ia32_pmovmskb256, "iV32c", "", "avx2") -TARGET_BUILTIN(__builtin_ia32_pmovsxbw256, "V16sV16c", "", "avx2") -TARGET_BUILTIN(__builtin_ia32_pmovsxbd256, "V8iV16c", "", "avx2") -TARGET_BUILTIN(__builtin_ia32_pmovsxbq256, "V4LLiV16c", "", "avx2") -TARGET_BUILTIN(__builtin_ia32_pmovsxwd256, "V8iV8s", "", "avx2") -TARGET_BUILTIN(__builtin_ia32_pmovsxwq256, "V4LLiV8s", "", "avx2") -TARGET_BUILTIN(__builtin_ia32_pmovsxdq256, "V4LLiV4i", "", "avx2") -TARGET_BUILTIN(__builtin_ia32_pmovzxbw256, "V16sV16c", "", "avx2") -TARGET_BUILTIN(__builtin_ia32_pmovzxbd256, "V8iV16c", "", "avx2") -TARGET_BUILTIN(__builtin_ia32_pmovzxbq256, "V4LLiV16c", "", "avx2") -TARGET_BUILTIN(__builtin_ia32_pmovzxwd256, "V8iV8s", "", "avx2") -TARGET_BUILTIN(__builtin_ia32_pmovzxwq256, "V4LLiV8s", "", "avx2") -TARGET_BUILTIN(__builtin_ia32_pmovzxdq256, "V4LLiV4i", "", "avx2") TARGET_BUILTIN(__builtin_ia32_pmuldq256, "V4LLiV8iV8i", "", "avx2") TARGET_BUILTIN(__builtin_ia32_pmulhrsw256, "V16sV16sV16s", "", "avx2") TARGET_BUILTIN(__builtin_ia32_pmulhuw256, "V16sV16sV16s", "", "avx2") @@ -584,7 +548,6 @@ TARGET_BUILTIN(__builtin_ia32_pshufb256, "V32cV32cV32c", "", "avx2") TARGET_BUILTIN(__builtin_ia32_psignb256, "V32cV32cV32c", "", "avx2") TARGET_BUILTIN(__builtin_ia32_psignw256, "V16sV16sV16s", "", "avx2") TARGET_BUILTIN(__builtin_ia32_psignd256, "V8iV8iV8i", "", "avx2") -TARGET_BUILTIN(__builtin_ia32_pslldqi256, "V4LLiV4LLiIi", "", "avx2") TARGET_BUILTIN(__builtin_ia32_psllwi256, "V16sV16si", "", "avx2") TARGET_BUILTIN(__builtin_ia32_psllw256, "V16sV16sV8s", "", "avx2") TARGET_BUILTIN(__builtin_ia32_pslldi256, "V8iV8ii", "", "avx2") @@ -595,7 +558,6 @@ TARGET_BUILTIN(__builtin_ia32_psrawi256, "V16sV16si", "", "avx2") TARGET_BUILTIN(__builtin_ia32_psraw256, "V16sV16sV8s", "", "avx2") TARGET_BUILTIN(__builtin_ia32_psradi256, "V8iV8ii", "", "avx2") TARGET_BUILTIN(__builtin_ia32_psrad256, "V8iV8iV4i", "", "avx2") -TARGET_BUILTIN(__builtin_ia32_psrldqi256, "V4LLiV4LLiIi", "", "avx2") TARGET_BUILTIN(__builtin_ia32_psrlwi256, "V16sV16si", "", "avx2") TARGET_BUILTIN(__builtin_ia32_psrlw256, "V16sV16sV8s", "", "avx2") TARGET_BUILTIN(__builtin_ia32_psrldi256, "V8iV8ii", "", "avx2") @@ -647,10 +609,8 @@ TARGET_BUILTIN(__builtin_ia32_gatherq_d256, "V4iV4iiC*V4LLiV4iIc", "", "avx2") // F16C TARGET_BUILTIN(__builtin_ia32_vcvtps2ph, "V8sV4fIi", "", "f16c") TARGET_BUILTIN(__builtin_ia32_vcvtps2ph256, "V8sV8fIi", "", "f16c") -TARGET_BUILTIN(__builtin_ia32_vcvtps2ph512, "V16sV16fIi", "", "avx512f") TARGET_BUILTIN(__builtin_ia32_vcvtph2ps, "V4fV8s", "", "f16c") TARGET_BUILTIN(__builtin_ia32_vcvtph2ps256, "V8fV8s", "", "f16c") -TARGET_BUILTIN(__builtin_ia32_vcvtph2ps512, "V16fV16s", "", "avx512f") // RDRAND TARGET_BUILTIN(__builtin_ia32_rdrand16_step, "UiUs*", "", "rdrnd") @@ -687,13 +647,16 @@ TARGET_BUILTIN(__builtin_ia32_xsavec64, "vv*ULLi", "", "xsavec") TARGET_BUILTIN(__builtin_ia32_xsaves, "vv*ULLi", "", "xsaves") TARGET_BUILTIN(__builtin_ia32_xsaves64, "vv*ULLi", "", "xsaves") +//CLFLUSHOPT +TARGET_BUILTIN(__builtin_ia32_clflushopt, "vc*", "", "clflushopt") + // ADX TARGET_BUILTIN(__builtin_ia32_addcarryx_u32, "UcUcUiUiUi*", "", "adx") TARGET_BUILTIN(__builtin_ia32_addcarryx_u64, "UcUcULLiULLiULLi*", "", "adx") -TARGET_BUILTIN(__builtin_ia32_addcarry_u32, "UcUcUiUiUi*", "", "adx") -TARGET_BUILTIN(__builtin_ia32_addcarry_u64, "UcUcULLiULLiULLi*", "", "adx") -TARGET_BUILTIN(__builtin_ia32_subborrow_u32, "UcUcUiUiUi*", "", "adx") -TARGET_BUILTIN(__builtin_ia32_subborrow_u64, "UcUcULLiULLiULLi*", "", "adx") +TARGET_BUILTIN(__builtin_ia32_addcarry_u32, "UcUcUiUiUi*", "", "") +TARGET_BUILTIN(__builtin_ia32_addcarry_u64, "UcUcULLiULLiULLi*", "", "") +TARGET_BUILTIN(__builtin_ia32_subborrow_u32, "UcUcUiUiUi*", "", "") +TARGET_BUILTIN(__builtin_ia32_subborrow_u64, "UcUcULLiULLiULLi*", "", "") // RDSEED TARGET_BUILTIN(__builtin_ia32_rdseed16_step, "UiUs*", "", "rdseed") @@ -931,23 +894,23 @@ TARGET_BUILTIN(__builtin_ia32_wrpkru, "vUi", "", "pku") // AVX-512 TARGET_BUILTIN(__builtin_ia32_sqrtpd512_mask, "V8dV8dV8dUcIi", "", "avx512f") TARGET_BUILTIN(__builtin_ia32_sqrtps512_mask, "V16fV16fV16fUsIi", "", "avx512f") -TARGET_BUILTIN(__builtin_ia32_rsqrt14sd, "V2dV2dV2dV2dUc", "", "avx512f") -TARGET_BUILTIN(__builtin_ia32_rsqrt14ss, "V4fV4fV4fV4fUc", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_rsqrt14sd_mask, "V2dV2dV2dV2dUc", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_rsqrt14ss_mask, "V4fV4fV4fV4fUc", "", "avx512f") TARGET_BUILTIN(__builtin_ia32_rsqrt14pd512_mask, "V8dV8dV8dUc", "", "avx512f") TARGET_BUILTIN(__builtin_ia32_rsqrt14ps512_mask, "V16fV16fV16fUs", "", "avx512f") -TARGET_BUILTIN(__builtin_ia32_rsqrt28sd_round, "V2dV2dV2dV2dUcIi", "", "avx512er") -TARGET_BUILTIN(__builtin_ia32_rsqrt28ss_round, "V4fV4fV4fV4fUcIi", "", "avx512er") +TARGET_BUILTIN(__builtin_ia32_rsqrt28sd_round_mask, "V2dV2dV2dV2dUcIi", "", "avx512er") +TARGET_BUILTIN(__builtin_ia32_rsqrt28ss_round_mask, "V4fV4fV4fV4fUcIi", "", "avx512er") TARGET_BUILTIN(__builtin_ia32_rsqrt28pd_mask, "V8dV8dV8dUcIi", "", "avx512er") TARGET_BUILTIN(__builtin_ia32_rsqrt28ps_mask, "V16fV16fV16fUsIi", "", "avx512er") -TARGET_BUILTIN(__builtin_ia32_rcp14sd, "V2dV2dV2dV2dUc", "", "avx512f") -TARGET_BUILTIN(__builtin_ia32_rcp14ss, "V4fV4fV4fV4fUc", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_rcp14sd_mask, "V2dV2dV2dV2dUc", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_rcp14ss_mask, "V4fV4fV4fV4fUc", "", "avx512f") TARGET_BUILTIN(__builtin_ia32_rcp14pd512_mask, "V8dV8dV8dUc", "", "avx512f") TARGET_BUILTIN(__builtin_ia32_rcp14ps512_mask, "V16fV16fV16fUs", "", "avx512f") -TARGET_BUILTIN(__builtin_ia32_rcp28sd_round, "V2dV2dV2dV2dUcIi", "", "avx512er") -TARGET_BUILTIN(__builtin_ia32_rcp28ss_round, "V4fV4fV4fV4fUcIi", "", "avx512er") +TARGET_BUILTIN(__builtin_ia32_rcp28sd_round_mask, "V2dV2dV2dV2dUcIi", "", "avx512er") +TARGET_BUILTIN(__builtin_ia32_rcp28ss_round_mask, "V4fV4fV4fV4fUcIi", "", "avx512er") TARGET_BUILTIN(__builtin_ia32_rcp28pd_mask, "V8dV8dV8dUcIi", "", "avx512er") TARGET_BUILTIN(__builtin_ia32_rcp28ps_mask, "V16fV16fV16fUsIi", "", "avx512er") TARGET_BUILTIN(__builtin_ia32_exp2pd_mask, "V8dV8dV8dUcIi", "", "avx512er") @@ -968,12 +931,12 @@ 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,avx512bw") -TARGET_BUILTIN(__builtin_ia32_pcmpeqq256_mask, "cV4LLiV4LLic", "", "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,avx512bw") -TARGET_BUILTIN(__builtin_ia32_pcmpeqq128_mask, "cV2LLiV2LLic", "", "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") @@ -982,12 +945,12 @@ 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,avx512bw") -TARGET_BUILTIN(__builtin_ia32_pcmpgtq256_mask, "cV4LLiV4LLic", "", "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,avx512bw") -TARGET_BUILTIN(__builtin_ia32_pcmpgtq128_mask, "cV2LLiV2LLic", "", "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") @@ -1011,12 +974,6 @@ TARGET_BUILTIN(__builtin_ia32_cvtudq2pd512_mask, "V8dV8iV8dUc", "", "avx512f") TARGET_BUILTIN(__builtin_ia32_cvtpd2ps512_mask, "V8fV8dV8fUcIi", "", "avx512f") TARGET_BUILTIN(__builtin_ia32_vcvtps2ph512_mask, "V16sV16fIiV16sUs", "", "avx512f") TARGET_BUILTIN(__builtin_ia32_vcvtph2ps512_mask, "V16fV16sV16fUsIi", "", "avx512f") -TARGET_BUILTIN(__builtin_ia32_pandd512_mask, "V16iV16iV16iV16iUs", "", "avx512f") -TARGET_BUILTIN(__builtin_ia32_pandq512_mask, "V8LLiV8LLiV8LLiV8LLiUc", "", "avx512f") -TARGET_BUILTIN(__builtin_ia32_pord512_mask, "V16iV16iV16iV16iUs", "", "avx512f") -TARGET_BUILTIN(__builtin_ia32_porq512_mask, "V8LLiV8LLiV8LLiV8LLiUc", "", "avx512f") -TARGET_BUILTIN(__builtin_ia32_pxord512_mask, "V16iV16iV16iV16iUs", "", "avx512f") -TARGET_BUILTIN(__builtin_ia32_pxorq512_mask, "V8LLiV8LLiV8LLiV8LLiUc", "", "avx512f") TARGET_BUILTIN(__builtin_ia32_pabsd512_mask, "V16iV16iV16iUs", "", "avx512f") TARGET_BUILTIN(__builtin_ia32_pabsq512_mask, "V8LLiV8LLiV8LLiUc", "", "avx512f") TARGET_BUILTIN(__builtin_ia32_pmaxsd512_mask, "V16iV16iV16iV16iUs", "", "avx512f") @@ -1029,61 +986,77 @@ TARGET_BUILTIN(__builtin_ia32_pminud512_mask, "V16iV16iV16iV16iUs", "", "avx512f TARGET_BUILTIN(__builtin_ia32_pminuq512_mask, "V8LLiV8LLiV8LLiV8LLiUc", "", "avx512f") TARGET_BUILTIN(__builtin_ia32_pmuldq512_mask, "V8LLiV16iV16iV8LLiUc", "", "avx512f") TARGET_BUILTIN(__builtin_ia32_pmuludq512_mask, "V8LLiV16iV16iV8LLiUc", "", "avx512f") -TARGET_BUILTIN(__builtin_ia32_blendmd_512_mask, "V16iV16iV16iUs", "", "avx512f") -TARGET_BUILTIN(__builtin_ia32_blendmq_512_mask, "V8LLiV8LLiV8LLiUc", "", "avx512f") -TARGET_BUILTIN(__builtin_ia32_blendmps_512_mask, "V16fV16fV16fUs", "", "avx512f") -TARGET_BUILTIN(__builtin_ia32_blendmpd_512_mask, "V8dV8dV8dUc", "", "avx512f") TARGET_BUILTIN(__builtin_ia32_ptestmd512, "UsV16iV16iUs", "", "avx512f") TARGET_BUILTIN(__builtin_ia32_ptestmq512, "UcV8LLiV8LLiUc", "", "avx512f") TARGET_BUILTIN(__builtin_ia32_pbroadcastd512_gpr_mask, "V16iiV16iUs", "", "avx512f") TARGET_BUILTIN(__builtin_ia32_pbroadcastq512_gpr_mask, "V8LLiLLiV8LLiUc", "", "avx512f") TARGET_BUILTIN(__builtin_ia32_pbroadcastq512_mem_mask, "V8LLiLLiV8LLiUc", "", "avx512f") -TARGET_BUILTIN(__builtin_ia32_loaddqusi512_mask, "V16ivC*V16iUs", "", "avx512f") -TARGET_BUILTIN(__builtin_ia32_loaddqudi512_mask, "V8LLivC*V8LLiUc", "", "avx512f") -TARGET_BUILTIN(__builtin_ia32_loadups512_mask, "V16fvC*V16fUs", "", "avx512f") -TARGET_BUILTIN(__builtin_ia32_loadaps512_mask, "V16fvC*V16fUs", "", "avx512f") -TARGET_BUILTIN(__builtin_ia32_loadupd512_mask, "V8dvC*V8dUc", "", "avx512f") -TARGET_BUILTIN(__builtin_ia32_loadapd512_mask, "V8dvC*V8dUc", "", "avx512f") -TARGET_BUILTIN(__builtin_ia32_storedqudi512_mask, "vv*V8LLiUc", "", "avx512f") -TARGET_BUILTIN(__builtin_ia32_storedqusi512_mask, "vv*V16iUs", "", "avx512f") -TARGET_BUILTIN(__builtin_ia32_storeupd512_mask, "vv*V8dUc", "", "avx512f") -TARGET_BUILTIN(__builtin_ia32_storeapd512_mask, "vv*V8dUc", "", "avx512f") -TARGET_BUILTIN(__builtin_ia32_storeups512_mask, "vv*V16fUs", "", "avx512f") -TARGET_BUILTIN(__builtin_ia32_storeaps512_mask, "vv*V16fUs", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_loaddqusi512_mask, "V16iiC*V16iUs", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_loaddqudi512_mask, "V8LLiLLiC*V8LLiUc", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_loadups512_mask, "V16ffC*V16fUs", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_loadaps512_mask, "V16fV16fC*V16fUs", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_loadupd512_mask, "V8ddC*V8dUc", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_loadapd512_mask, "V8dV8dC*V8dUc", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_storedqudi512_mask, "vLLi*V8LLiUc", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_storedqusi512_mask, "vi*V16iUs", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_storeupd512_mask, "vd*V8dUc", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_storeapd512_mask, "vV8d*V8dUc", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_storeups512_mask, "vf*V16fUs", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_storeaps512_mask, "vV16f*V16fUs", "", "avx512f") TARGET_BUILTIN(__builtin_ia32_vpermt2vard512_mask, "V16iV16iV16iV16iUs", "", "avx512f") TARGET_BUILTIN(__builtin_ia32_vpermt2varq512_mask, "V8LLiV8LLiV8LLiV8LLiUc", "", "avx512f") TARGET_BUILTIN(__builtin_ia32_vpermt2varps512_mask, "V16fV16iV16fV16fUs", "", "avx512f") TARGET_BUILTIN(__builtin_ia32_vpermt2varpd512_mask, "V8dV8LLiV8dV8dUc", "", "avx512f") TARGET_BUILTIN(__builtin_ia32_alignq512_mask, "V8LLiV8LLiV8LLiIiV8LLiUc", "", "avx512f") TARGET_BUILTIN(__builtin_ia32_alignd512_mask, "V16iV16iV16iIiV16iUs", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_alignd128_mask, "V4iV4iV4iIiV4iUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_alignd256_mask, "V8iV8iV8iIiV8iUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_alignq128_mask, "V2LLiV2LLiV2LLiIiV2LLiUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_alignq256_mask, "V4LLiV4LLiV4LLiIiV4LLiUc","","avx512vl") TARGET_BUILTIN(__builtin_ia32_extractf64x4_mask, "V4dV8dIiV4dUc", "", "avx512f") TARGET_BUILTIN(__builtin_ia32_extractf32x4_mask, "V4fV16fIiV4fUc", "", "avx512f") -TARGET_BUILTIN(__builtin_ia32_gathersiv8df, "V8dV8dvC*V8iUcIi", "", "avx512f") -TARGET_BUILTIN(__builtin_ia32_gathersiv16sf, "V16fV16fvC*UsIi", "", "avx512f") -TARGET_BUILTIN(__builtin_ia32_gatherdiv8df, "V8dV8dvC*V8LLiUcIi", "", "avx512f") -TARGET_BUILTIN(__builtin_ia32_gatherdiv16sf, "V8fV8fvC*V8LLiUcIi", "", "avx512f") -TARGET_BUILTIN(__builtin_ia32_gathersiv8di, "V8LLiV8LLivC*V8iUcIi", "", "avx512f") -TARGET_BUILTIN(__builtin_ia32_gathersiv16si, "V16iV16ivC*UsIi", "", "avx512f") -TARGET_BUILTIN(__builtin_ia32_gatherdiv8di, "V8LLiV8LLivC*V8LLiUcIi", "", "avx512f") -TARGET_BUILTIN(__builtin_ia32_gatherdiv16si, "V8iV8ivC*V8LLiUcIi", "", "avx512f") -TARGET_BUILTIN(__builtin_ia32_scattersiv8df, "vv*UcV8iV8dIi", "", "avx512f") -TARGET_BUILTIN(__builtin_ia32_scattersiv16sf, "vv*UsV16iV16fIi", "", "avx512f") -TARGET_BUILTIN(__builtin_ia32_scatterdiv8df, "vv*UcV8LLiV8dIi", "", "avx512f") -TARGET_BUILTIN(__builtin_ia32_scatterdiv16sf, "vv*UcV8LLiV8fIi", "", "avx512f") -TARGET_BUILTIN(__builtin_ia32_scattersiv8di, "vv*UcV8iV8LLiIi", "", "avx512f") -TARGET_BUILTIN(__builtin_ia32_scattersiv16si, "vv*UsV16iV16iIi", "", "avx512f") -TARGET_BUILTIN(__builtin_ia32_scatterdiv8di, "vv*UcV8LLiV8LLiIi", "", "avx512f") -TARGET_BUILTIN(__builtin_ia32_scatterdiv16si, "vv*UcV8LLiV8iIi", "", "avx512f") - -TARGET_BUILTIN(__builtin_ia32_gatherpfdpd, "vUcV8ivC*IiIi", "", "avx512pf") -TARGET_BUILTIN(__builtin_ia32_gatherpfdps, "vUsV16ivC*IiIi", "", "avx512pf") -TARGET_BUILTIN(__builtin_ia32_gatherpfqpd, "vUcV8LLivC*IiIi", "", "avx512pf") -TARGET_BUILTIN(__builtin_ia32_gatherpfqps, "vUcV8LLivC*IiIi", "", "avx512pf") -TARGET_BUILTIN(__builtin_ia32_scatterpfdpd, "vUcV8iv*IiIi", "", "avx512pf") -TARGET_BUILTIN(__builtin_ia32_scatterpfdps, "vUsV16iv*IiIi", "", "avx512pf") -TARGET_BUILTIN(__builtin_ia32_scatterpfqpd, "vUcV8LLiv*IiIi", "", "avx512pf") -TARGET_BUILTIN(__builtin_ia32_scatterpfqps, "vUcV8LLiv*IiIi", "", "avx512pf") +TARGET_BUILTIN(__builtin_ia32_gather3div2df, "V2dV2ddC*V2LLiUci","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_gather3div2di, "V4iV2LLiLLiC*V2LLiUci","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_gather3div4df, "V4dV4ddC*V4LLiUci","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_gather3div4di, "V8iV4LLiLLiC*V4LLiUci","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_gather3div4sf, "V4fV4ffC*V2LLiUci","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_gather3div4si, "V4iV4iiC*V2LLiUci","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_gather3div8sf, "V4fV4ffC*V4LLiUci","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_gather3div8si, "V4iV4iiC*V4LLiUci","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_gather3siv2df, "V2dV2ddC*V4iUci","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_gather3siv2di, "V4iV2LLiLLiC*V4iUci","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_gather3siv4df, "V4dV4ddC*V4iUci","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_gather3siv4di, "V8iV4LLiLLiC*V4iUci","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_gather3siv4sf, "V4fV4ffC*V4iUci","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_gather3siv4si, "V4iV4iiC*V4iUci","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_gather3siv8sf, "V8fV8ffC*V8iUci","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_gather3siv8si, "V8iV8iiC*V8iUci","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_gathersiv8df, "V8dV8ddC*V8iUcIi", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_gathersiv16sf, "V16fV16ffC*V16fUsIi", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_gatherdiv8df, "V8dV8ddC*V8LLiUcIi", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_gatherdiv16sf, "V8fV8ffC*V8LLiUcIi", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_gathersiv8di, "V8LLiV8LLiLLiC*V8iUcIi", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_gathersiv16si, "V16iV16iiC*V16iUsIi", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_gatherdiv8di, "V8LLiV8LLiLLiC*V8LLiUcIi", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_gatherdiv16si, "V8iV8iiC*V8LLiUcIi", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_scattersiv8df, "vd*UcV8iV8dIi", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_scattersiv16sf, "vf*UsV16iV16fIi", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_scatterdiv8df, "vd*UcV8LLiV8dIi", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_scatterdiv16sf, "vf*UcV8LLiV8fIi", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_scattersiv8di, "vLLi*UcV8iV8LLiIi", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_scattersiv16si, "vi*UsV16iV16iIi", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_scatterdiv8di, "vLLi*UcV8LLiV8LLiIi", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_scatterdiv16si, "vi*UcV8LLiV8iIi", "", "avx512f") + +TARGET_BUILTIN(__builtin_ia32_gatherpfdpd, "vUcV8iLLiC*IiIi", "", "avx512pf") +TARGET_BUILTIN(__builtin_ia32_gatherpfdps, "vUsV16iiC*IiIi", "", "avx512pf") +TARGET_BUILTIN(__builtin_ia32_gatherpfqpd, "vUcV8LLiLLiC*IiIi", "", "avx512pf") +TARGET_BUILTIN(__builtin_ia32_gatherpfqps, "vUcV8LLiiC*IiIi", "", "avx512pf") +TARGET_BUILTIN(__builtin_ia32_scatterpfdpd, "vUcV8iLLi*IiIi", "", "avx512pf") +TARGET_BUILTIN(__builtin_ia32_scatterpfdps, "vUsV16ii*IiIi", "", "avx512pf") +TARGET_BUILTIN(__builtin_ia32_scatterpfqpd, "vUcV8LLiLLi*IiIi", "", "avx512pf") +TARGET_BUILTIN(__builtin_ia32_scatterpfqps, "vUcV8LLii*IiIi", "", "avx512pf") TARGET_BUILTIN(__builtin_ia32_knothi, "UsUs", "", "avx512f") @@ -1126,22 +1099,6 @@ TARGET_BUILTIN(__builtin_ia32_pmuludq256_mask, "V4LLiV8iV8iV4LLiUc", "", "avx512 TARGET_BUILTIN(__builtin_ia32_pmuludq128_mask, "V2LLiV4iV4iV2LLiUc", "", "avx512vl") TARGET_BUILTIN(__builtin_ia32_pmulld256_mask, "V8iV8iV8iV8iUc", "", "avx512vl") TARGET_BUILTIN(__builtin_ia32_pmulld128_mask, "V4iV4iV4iV4iUc", "", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pandd256_mask, "V8iV8iV8iV8iUc", "", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pandd128_mask, "V4iV4iV4iV4iUc", "", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pandnd256_mask, "V8iV8iV8iV8iUc", "", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pandnd128_mask, "V4iV4iV4iV4iUc", "", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pord256_mask, "V8iV8iV8iV8iUc", "", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pord128_mask, "V4iV4iV4iV4iUc", "", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pxord256_mask, "V8iV8iV8iV8iUc", "", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pxord128_mask, "V4iV4iV4iV4iUc", "", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pandq256_mask, "V4LLiV4LLiV4LLiV4LLiUc", "", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pandq128_mask, "V2LLiV2LLiV2LLiV2LLiUc", "", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pandnq256_mask, "V4LLiV4LLiV4LLiV4LLiUc", "", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pandnq128_mask, "V2LLiV2LLiV2LLiV2LLiUc", "", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_porq256_mask, "V4LLiV4LLiV4LLiV4LLiUc", "", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_porq128_mask, "V2LLiV2LLiV2LLiV2LLiUc", "", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pxorq256_mask, "V4LLiV4LLiV4LLiV4LLiUc", "", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pxorq128_mask, "V2LLiV2LLiV2LLiV2LLiUc", "", "avx512vl") TARGET_BUILTIN(__builtin_ia32_paddb512_mask, "V64cV64cV64cV64cULLi", "", "avx512bw") TARGET_BUILTIN(__builtin_ia32_psubb512_mask, "V64cV64cV64cV64cULLi", "", "avx512bw") @@ -1159,8 +1116,6 @@ TARGET_BUILTIN(__builtin_ia32_psubw128_mask, "V8sV8sV8sV8sUc", "", "avx512vl,avx TARGET_BUILTIN(__builtin_ia32_pmullw256_mask, "V16sV16sV16sV16sUs", "", "avx512vl,avx512bw") TARGET_BUILTIN(__builtin_ia32_pmullw128_mask, "V8sV8sV8sV8sUc", "", "avx512vl,avx512bw") -TARGET_BUILTIN(__builtin_ia32_pandnd512_mask, "V16iV16iV16iV16iUs", "", "avx512f") -TARGET_BUILTIN(__builtin_ia32_pandnq512_mask, "V8LLiV8LLiV8LLiV8LLiUc", "", "avx512f") TARGET_BUILTIN(__builtin_ia32_paddq512_mask, "V8LLiV8LLiV8LLiV8LLiUc", "", "avx512f") TARGET_BUILTIN(__builtin_ia32_psubq512_mask, "V8LLiV8LLiV8LLiV8LLiUc", "", "avx512f") TARGET_BUILTIN(__builtin_ia32_paddd512_mask, "V16iV16iV16iV16iUs", "", "avx512f") @@ -1195,8 +1150,6 @@ TARGET_BUILTIN(__builtin_ia32_orpd128_mask, "V2dV2dV2dV2dUc", "", "avx512vl,avx5 TARGET_BUILTIN(__builtin_ia32_orps256_mask, "V8fV8fV8fV8fUc", "", "avx512vl,avx512dq") TARGET_BUILTIN(__builtin_ia32_orps128_mask, "V4fV4fV4fV4fUc", "", "avx512vl,avx512dq") -TARGET_BUILTIN(__builtin_ia32_blendmb_512_mask, "V64cV64cV64cULLi", "", "avx512bw") -TARGET_BUILTIN(__builtin_ia32_blendmw_512_mask, "V32sV32sV32sUi", "", "avx512bw") TARGET_BUILTIN(__builtin_ia32_pabsb512_mask, "V64cV64cV64cULLi", "", "avx512bw") TARGET_BUILTIN(__builtin_ia32_pabsw512_mask, "V32sV32sV32sUi", "", "avx512bw") TARGET_BUILTIN(__builtin_ia32_packssdw512_mask, "V32sV16iV16iV32sUi", "", "avx512bw") @@ -1227,15 +1180,15 @@ TARGET_BUILTIN(__builtin_ia32_vpermi2varhi512_mask, "V32sV32sV32sV32sUi", "", "a TARGET_BUILTIN(__builtin_ia32_vpermt2varhi512_mask, "V32sV32sV32sV32sUi", "", "avx512bw") TARGET_BUILTIN(__builtin_ia32_vpermt2varhi512_maskz, "V32sV32sV32sV32sUi", "", "avx512bw") +TARGET_BUILTIN(__builtin_ia32_vpconflictdi_128_mask, "V2LLiV2LLiV2LLiUc","","avx512cd,avx512vl") +TARGET_BUILTIN(__builtin_ia32_vpconflictdi_256_mask, "V4LLiV4LLiV4LLiUc","","avx512cd,avx512vl") +TARGET_BUILTIN(__builtin_ia32_vpconflictsi_128_mask, "V4iV4iV4iUc","","avx512cd,avx512vl") +TARGET_BUILTIN(__builtin_ia32_vpconflictsi_256_mask, "V8iV8iV8iUc","","avx512cd,avx512vl") TARGET_BUILTIN(__builtin_ia32_vpconflictdi_512_mask, "V8LLiV8LLiV8LLiUc", "", "avx512cd") TARGET_BUILTIN(__builtin_ia32_vpconflictsi_512_mask, "V16iV16iV16iUs", "", "avx512cd") TARGET_BUILTIN(__builtin_ia32_vplzcntd_512_mask, "V16iV16iV16iUs", "", "avx512cd") TARGET_BUILTIN(__builtin_ia32_vplzcntq_512_mask, "V8LLiV8LLiV8LLiUc", "", "avx512cd") -TARGET_BUILTIN(__builtin_ia32_blendmb_128_mask, "V16cV16cV16cUs", "", "avx512vl,avx512bw") -TARGET_BUILTIN(__builtin_ia32_blendmb_256_mask, "V32cV32cV32cUi", "", "avx512vl,avx512bw") -TARGET_BUILTIN(__builtin_ia32_blendmw_128_mask, "V8sV8sV8sUc", "", "avx512vl,avx512bw") -TARGET_BUILTIN(__builtin_ia32_blendmw_256_mask, "V16sV16sV16sUs", "", "avx512vl,avx512bw") TARGET_BUILTIN(__builtin_ia32_pabsb128_mask, "V16cV16cV16cUs", "", "avx512vl,avx512bw") TARGET_BUILTIN(__builtin_ia32_pabsb256_mask, "V32cV32cV32cUi", "", "avx512vl,avx512bw") TARGET_BUILTIN(__builtin_ia32_pabsw128_mask, "V8sV8sV8sUc", "", "avx512vl,avx512bw") @@ -1310,31 +1263,23 @@ TARGET_BUILTIN(__builtin_ia32_subps512_mask, "V16fV16fV16fV16fUsIi", "", "avx512 TARGET_BUILTIN(__builtin_ia32_pmaddubsw512_mask, "V32sV64cV64cV32sUi", "", "avx512bw") TARGET_BUILTIN(__builtin_ia32_pmaddwd512_mask, "V16iV32sV32sV16iUs", "", "avx512bw") -TARGET_BUILTIN(__builtin_ia32_addss_round, "V4fV4fV4fV4fUcIi", "", "avx512f") -TARGET_BUILTIN(__builtin_ia32_divss_round, "V4fV4fV4fV4fUcIi", "", "avx512f") -TARGET_BUILTIN(__builtin_ia32_mulss_round, "V4fV4fV4fV4fUcIi", "", "avx512f") -TARGET_BUILTIN(__builtin_ia32_subss_round, "V4fV4fV4fV4fUcIi", "", "avx512f") -TARGET_BUILTIN(__builtin_ia32_maxss_round, "V4fV4fV4fV4fUcIi", "", "avx512f") -TARGET_BUILTIN(__builtin_ia32_minss_round, "V4fV4fV4fV4fUcIi", "", "avx512f") -TARGET_BUILTIN(__builtin_ia32_addsd_round, "V2dV2dV2dV2dUcIi", "", "avx512f") -TARGET_BUILTIN(__builtin_ia32_divsd_round, "V2dV2dV2dV2dUcIi", "", "avx512f") -TARGET_BUILTIN(__builtin_ia32_mulsd_round, "V2dV2dV2dV2dUcIi", "", "avx512f") -TARGET_BUILTIN(__builtin_ia32_subsd_round, "V2dV2dV2dV2dUcIi", "", "avx512f") -TARGET_BUILTIN(__builtin_ia32_maxsd_round, "V2dV2dV2dV2dUcIi", "", "avx512f") -TARGET_BUILTIN(__builtin_ia32_minsd_round, "V2dV2dV2dV2dUcIi", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_addss_round_mask, "V4fV4fV4fV4fUcIi", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_divss_round_mask, "V4fV4fV4fV4fUcIi", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_mulss_round_mask, "V4fV4fV4fV4fUcIi", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_subss_round_mask, "V4fV4fV4fV4fUcIi", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_maxss_round_mask, "V4fV4fV4fV4fUcIi", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_minss_round_mask, "V4fV4fV4fV4fUcIi", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_addsd_round_mask, "V2dV2dV2dV2dUcIi", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_divsd_round_mask, "V2dV2dV2dV2dUcIi", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_mulsd_round_mask, "V2dV2dV2dV2dUcIi", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_subsd_round_mask, "V2dV2dV2dV2dUcIi", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_maxsd_round_mask, "V2dV2dV2dV2dUcIi", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_minsd_round_mask, "V2dV2dV2dV2dUcIi", "", "avx512f") TARGET_BUILTIN(__builtin_ia32_addpd128_mask, "V2dV2dV2dV2dUc", "", "avx512vl") TARGET_BUILTIN(__builtin_ia32_addpd256_mask, "V4dV4dV4dV4dUc", "", "avx512vl") TARGET_BUILTIN(__builtin_ia32_addps128_mask, "V4fV4fV4fV4fUc", "", "avx512vl") TARGET_BUILTIN(__builtin_ia32_addps256_mask, "V8fV8fV8fV8fUc", "", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_blendmd_128_mask, "V4iV4iV4iUc", "", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_blendmd_256_mask, "V8iV8iV8iUc", "", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_blendmpd_128_mask, "V2dV2dV2dUc", "", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_blendmpd_256_mask, "V4dV4dV4dUc", "", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_blendmps_128_mask, "V4fV4fV4fUc", "", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_blendmps_256_mask, "V8fV8fV8fUc", "", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_blendmq_128_mask, "V2LLiV2LLiV2LLiUc", "", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_blendmq_256_mask, "V4LLiV4LLiV4LLiUc", "", "avx512vl") TARGET_BUILTIN(__builtin_ia32_compressdf128_mask, "V2dV2dV2dUc", "", "avx512vl") TARGET_BUILTIN(__builtin_ia32_compressdf256_mask, "V4dV4dV4dUc", "", "avx512vl") TARGET_BUILTIN(__builtin_ia32_compressdi128_mask, "V2LLiV2LLiV2LLiUc", "", "avx512vl") @@ -1444,22 +1389,22 @@ TARGET_BUILTIN(__builtin_ia32_scalefpd256_mask, "V4dV4dV4dV4dUc", "", "avx512vl" TARGET_BUILTIN(__builtin_ia32_scalefps128_mask, "V4fV4fV4fV4fUc", "", "avx512vl") TARGET_BUILTIN(__builtin_ia32_scalefps256_mask, "V8fV8fV8fV8fUc", "", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_scatterdiv2df, "vv*UcV2LLiV2dIi", "", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_scatterdiv2di, "vv*UcV2LLiV2LLiIi", "", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_scatterdiv4df, "vv*UcV4LLiV4dIi", "", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_scatterdiv4di, "vv*UcV4LLiV4LLiIi", "", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_scatterdiv4sf, "vv*UcV2LLiV4fIi", "", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_scatterdiv4si, "vv*UcV2LLiV4iIi", "", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_scatterdiv8sf, "vv*UcV4LLiV4fIi", "", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_scatterdiv8si, "vv*UcV4LLiV4iIi", "", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_scattersiv2df, "vv*UcV4iV2dIi", "", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_scattersiv2di, "vv*UcV4iV2LLiIi", "", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_scattersiv4df, "vv*UcV4iV4dIi", "", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_scattersiv4di, "vv*UcV4iV4LLiIi", "", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_scattersiv4sf, "vv*UcV4iV4fIi", "", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_scattersiv4si, "vv*UcV4iV4iIi", "", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_scattersiv8sf, "vv*UcV8iV8fIi", "", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_scattersiv8si, "vv*UcV8iV8iIi", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_scatterdiv2df, "vd*UcV2LLiV2dIi", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_scatterdiv2di, "vLLi*UcV2LLiV2LLiIi", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_scatterdiv4df, "vd*UcV4LLiV4dIi", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_scatterdiv4di, "vLLi*UcV4LLiV4LLiIi", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_scatterdiv4sf, "vf*UcV2LLiV4fIi", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_scatterdiv4si, "vi*UcV2LLiV4iIi", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_scatterdiv8sf, "vf*UcV4LLiV4fIi", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_scatterdiv8si, "vi*UcV4LLiV4iIi", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_scattersiv2df, "vd*UcV4iV2dIi", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_scattersiv2di, "vLLi*UcV4iV2LLiIi", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_scattersiv4df, "vd*UcV4iV4dIi", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_scattersiv4di, "vLLi*UcV4iV4LLiIi", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_scattersiv4sf, "vf*UcV4iV4fIi", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_scattersiv4si, "vi*UcV4iV4iIi", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_scattersiv8sf, "vf*UcV8iV8fIi", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_scattersiv8si, "vi*UcV8iV8iIi", "", "avx512vl") TARGET_BUILTIN(__builtin_ia32_sqrtpd128_mask, "V2dV2dV2dUc", "", "avx512vl") TARGET_BUILTIN(__builtin_ia32_sqrtpd256_mask, "V4dV4dV4dUc", "", "avx512vl") @@ -1496,10 +1441,6 @@ TARGET_BUILTIN(__builtin_ia32_vpermt2varq256_maskz, "V4LLiV4LLiV4LLiV4LLiUc", "" TARGET_BUILTIN(__builtin_ia32_pmovswb512_mask, "V32cV32sV32cUi", "", "avx512bw") TARGET_BUILTIN(__builtin_ia32_pmovuswb512_mask, "V32cV32sV32cUi", "", "avx512bw") TARGET_BUILTIN(__builtin_ia32_pmovwb512_mask, "V32cV32sV32cUi", "", "avx512bw") -TARGET_BUILTIN(__builtin_ia32_punpckhbw512_mask, "V64cV64cV64cV64cULLi", "", "avx512bw") -TARGET_BUILTIN(__builtin_ia32_punpckhwd512_mask, "V32sV32sV32sV32sUi", "", "avx512bw") -TARGET_BUILTIN(__builtin_ia32_punpcklbw512_mask, "V64cV64cV64cV64cULLi", "", "avx512bw") -TARGET_BUILTIN(__builtin_ia32_punpcklwd512_mask, "V32sV32sV32sV32sUi", "", "avx512bw") TARGET_BUILTIN(__builtin_ia32_cvtpd2qq128_mask, "V2LLiV2dV2LLiUc", "", "avx512vl,avx512dq") TARGET_BUILTIN(__builtin_ia32_cvtpd2qq256_mask, "V4LLiV4dV4LLiUc", "", "avx512vl,avx512dq") TARGET_BUILTIN(__builtin_ia32_cvtpd2uqq128_mask, "V2LLiV2dV2LLiUc", "", "avx512vl,avx512dq") @@ -1528,10 +1469,14 @@ TARGET_BUILTIN(__builtin_ia32_rangepd128_mask, "V2dV2dV2dIiV2dUc", "", "avx512vl TARGET_BUILTIN(__builtin_ia32_rangepd256_mask, "V4dV4dV4dIiV4dUc", "", "avx512vl,avx512dq") TARGET_BUILTIN(__builtin_ia32_rangeps128_mask, "V4fV4fV4fIiV4fUc", "", "avx512vl,avx512dq") TARGET_BUILTIN(__builtin_ia32_rangeps256_mask, "V8fV8fV8fIiV8fUc", "", "avx512vl,avx512dq") +TARGET_BUILTIN(__builtin_ia32_rangesd128_round_mask, "V2dV2dV2dV2dUcIiIi", "", "avx512dq") +TARGET_BUILTIN(__builtin_ia32_rangess128_round_mask, "V4fV4fV4fV4fUcIiIi", "", "avx512dq") TARGET_BUILTIN(__builtin_ia32_reducepd128_mask, "V2dV2dIiV2dUc", "", "avx512vl,avx512dq") TARGET_BUILTIN(__builtin_ia32_reducepd256_mask, "V4dV4dIiV4dUc", "", "avx512vl,avx512dq") TARGET_BUILTIN(__builtin_ia32_reduceps128_mask, "V4fV4fIiV4fUc", "", "avx512vl,avx512dq") TARGET_BUILTIN(__builtin_ia32_reduceps256_mask, "V8fV8fIiV8fUc", "", "avx512vl,avx512dq") +TARGET_BUILTIN(__builtin_ia32_reducesd_mask, "V2dV2dV2dV2dUcIiIi", "", "avx512dq") +TARGET_BUILTIN(__builtin_ia32_reducess_mask, "V4fV4fV4fV4fUcIiIi", "", "avx512dq") TARGET_BUILTIN(__builtin_ia32_pmaddubsw128_mask, "V8sV16cV16cV8sUc", "", "avx512vl,avx512bw") TARGET_BUILTIN(__builtin_ia32_pmaddubsw256_mask, "V16sV32cV32cV16sUs", "", "avx512vl,avx512bw") TARGET_BUILTIN(__builtin_ia32_pmaddwd128_mask, "V4iV8sV8sV4iUc", "", "avx512vl,avx512bw") @@ -1548,14 +1493,6 @@ TARGET_BUILTIN(__builtin_ia32_pmulhuw128_mask, "V8sV8sV8sV8sUc", "", "avx512vl,a TARGET_BUILTIN(__builtin_ia32_pmulhuw256_mask, "V16sV16sV16sV16sUs", "", "avx512vl,avx512bw") TARGET_BUILTIN(__builtin_ia32_pmulhw128_mask, "V8sV8sV8sV8sUc", "", "avx512vl,avx512bw") TARGET_BUILTIN(__builtin_ia32_pmulhw256_mask, "V16sV16sV16sV16sUs", "", "avx512vl,avx512bw") -TARGET_BUILTIN(__builtin_ia32_punpckhbw128_mask, "V16cV16cV16cV16cUs", "", "avx512vl,avx512bw") -TARGET_BUILTIN(__builtin_ia32_punpckhbw256_mask, "V32cV32cV32cV32cUi", "", "avx512vl,avx512bw") -TARGET_BUILTIN(__builtin_ia32_punpckhwd128_mask, "V8sV8sV8sV8sUc", "", "avx512vl,avx512bw") -TARGET_BUILTIN(__builtin_ia32_punpckhwd256_mask, "V16sV16sV16sV16sUs", "", "avx512vl,avx512bw") -TARGET_BUILTIN(__builtin_ia32_punpcklbw128_mask, "V16cV16cV16cV16cUs", "", "avx512vl,avx512bw") -TARGET_BUILTIN(__builtin_ia32_punpcklbw256_mask, "V32cV32cV32cV32cUi", "", "avx512vl,avx512bw") -TARGET_BUILTIN(__builtin_ia32_punpcklwd128_mask, "V8sV8sV8sV8sUc", "", "avx512vl,avx512bw") -TARGET_BUILTIN(__builtin_ia32_punpcklwd256_mask, "V16sV16sV16sV16sUs", "", "avx512vl,avx512bw") TARGET_BUILTIN(__builtin_ia32_cvtpd2qq512_mask, "V8LLiV8dV8LLiUcIi", "", "avx512dq") TARGET_BUILTIN(__builtin_ia32_cvtpd2uqq512_mask, "V8LLiV8dV8LLiUcIi", "", "avx512dq") TARGET_BUILTIN(__builtin_ia32_cvtps2qq512_mask, "V8LLiV8fV8LLiUcIi", "", "avx512dq") @@ -1572,6 +1509,621 @@ TARGET_BUILTIN(__builtin_ia32_rangepd512_mask, "V8dV8dV8dIiV8dUcIi", "", "avx512 TARGET_BUILTIN(__builtin_ia32_rangeps512_mask, "V16fV16fV16fIiV16fUsIi", "", "avx512dq") TARGET_BUILTIN(__builtin_ia32_reducepd512_mask, "V8dV8dIiV8dUcIi", "", "avx512dq") TARGET_BUILTIN(__builtin_ia32_reduceps512_mask, "V16fV16fIiV16fUsIi", "", "avx512dq") +TARGET_BUILTIN(__builtin_ia32_pmovsxbw512_mask, "V32sV32cV32sUi","","avx512bw") +TARGET_BUILTIN(__builtin_ia32_pmovsxbd512_mask, "V16iV16cV16iUs","","avx512f") +TARGET_BUILTIN(__builtin_ia32_pmovsxbq512_mask, "V8LLiV16cV8LLiUc","","avx512f") +TARGET_BUILTIN(__builtin_ia32_pmovsxdq512_mask, "V8LLiV8iV8LLiUc","","avx512f") +TARGET_BUILTIN(__builtin_ia32_pmovsxwd512_mask, "V16iV16sV16iUs","","avx512f") +TARGET_BUILTIN(__builtin_ia32_pmovsxwq512_mask, "V8LLiV8sV8LLiUc","","avx512f") +TARGET_BUILTIN(__builtin_ia32_pmovsxbw128_mask, "V8sV16cV8sUc","","avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_pmovsxbw256_mask, "V16sV16cV16sUs","","avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_pmovsxbd128_mask, "V4iV16cV4iUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovsxbd256_mask, "V8iV16cV8iUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovsxbq128_mask, "V2LLiV16cV2LLiUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovsxbq256_mask, "V4LLiV16cV4LLiUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovsxdq128_mask, "V2LLiV4iV2LLiUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovsxdq256_mask, "V4LLiV4iV4LLiUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovsxwd128_mask, "V4iV8sV4iUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovsxwd256_mask, "V8iV8sV8iUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovsxwq128_mask, "V2LLiV8sV2LLiUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovsxwq256_mask, "V4LLiV8sV4LLiUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovzxbw512_mask, "V32sV32cV32sUi","","avx512bw") +TARGET_BUILTIN(__builtin_ia32_pmovzxbd512_mask, "V16iV16cV16iUs","","avx512f") +TARGET_BUILTIN(__builtin_ia32_pmovzxbq512_mask, "V8LLiV16cV8LLiUc","","avx512f") +TARGET_BUILTIN(__builtin_ia32_pmovzxdq512_mask, "V8LLiV8iV8LLiUc","","avx512f") +TARGET_BUILTIN(__builtin_ia32_pmovzxwd512_mask, "V16iV16sV16iUs","","avx512f") +TARGET_BUILTIN(__builtin_ia32_pmovzxwq512_mask, "V8LLiV8sV8LLiUc","","avx512f") +TARGET_BUILTIN(__builtin_ia32_pmovzxbw128_mask, "V8sV16cV8sUc","","avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_pmovzxbw256_mask, "V16sV16cV16sUs","","avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_pmovzxbd128_mask, "V4iV16cV4iUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovzxbd256_mask, "V8iV16cV8iUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovzxbq128_mask, "V2LLiV16cV2LLiUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovzxbq256_mask, "V4LLiV16cV4LLiUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovzxdq128_mask, "V2LLiV4iV2LLiUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovzxdq256_mask, "V4LLiV4iV4LLiUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovzxwd128_mask, "V4iV8sV4iUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovzxwd256_mask, "V8iV8sV8iUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovzxwq128_mask, "V2LLiV8sV2LLiUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovzxwq256_mask, "V4LLiV8sV4LLiUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_prold512_mask, "V16iV16iIiV16iUs","","avx512f") +TARGET_BUILTIN(__builtin_ia32_prolq512_mask, "V8LLiV8LLiIiV8LLiUc","","avx512f") +TARGET_BUILTIN(__builtin_ia32_prold128_mask, "V4iV4iIiV4iUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_prold256_mask, "V8iV8iIiV8iUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_prolq128_mask, "V2LLiV2LLiIiV2LLiUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_prolq256_mask, "V4LLiV4LLiIiV4LLiUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_prolvd512_mask, "V16iV16iV16iV16iUs","","avx512f") +TARGET_BUILTIN(__builtin_ia32_prolvq512_mask, "V8LLiV8LLiV8LLiV8LLiUc","","avx512f") +TARGET_BUILTIN(__builtin_ia32_prord512_mask, "V16iV16iiV16iUs","","avx512f") +TARGET_BUILTIN(__builtin_ia32_prorq512_mask, "V8LLiV8LLiiV8LLiUc","","avx512f") +TARGET_BUILTIN(__builtin_ia32_prolvd128_mask, "V4iV4iV4iV4iUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_prolvd256_mask, "V8iV8iV8iV8iUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_prolvq128_mask, "V2LLiV2LLiV2LLiV2LLiUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_prolvq256_mask, "V4LLiV4LLiV4LLiV4LLiUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_prord128_mask, "V4iV4iIiV4iUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_prord256_mask, "V8iV8iIiV8iUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_prorq128_mask, "V2LLiV2LLiIiV2LLiUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_prorq256_mask, "V4LLiV4LLiIiV4LLiUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_prorvd512_mask, "V16iV16iV16iV16iUs","","avx512f") +TARGET_BUILTIN(__builtin_ia32_prorvq512_mask, "V8LLiV8LLiV8LLiV8LLiUc","","avx512f") +TARGET_BUILTIN(__builtin_ia32_prorvd128_mask, "V4iV4iV4iV4iUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_prorvd256_mask, "V8iV8iV8iV8iUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_prorvq128_mask, "V2LLiV2LLiV2LLiV2LLiUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_prorvq256_mask, "V4LLiV4LLiV4LLiV4LLiUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_psllv32hi_mask, "V32sV32sV32sV32sUi","","avx512bw") +TARGET_BUILTIN(__builtin_ia32_psllw512_mask, "V32sV32sV8sV32sUi","","avx512bw") +TARGET_BUILTIN(__builtin_ia32_psllwi512_mask, "V32sV32sIiV32sUi","","avx512bw") +TARGET_BUILTIN(__builtin_ia32_psllv16hi_mask, "V16sV16sV16sV16sUs","","avx512bw,avx512vl") +TARGET_BUILTIN(__builtin_ia32_psllv8hi_mask, "V8sV8sV8sV8sUc","","avx512bw,avx512vl") +TARGET_BUILTIN(__builtin_ia32_psllw128_mask, "V8sV8sV8sV8sUc","","avx512bw,avx512vl") +TARGET_BUILTIN(__builtin_ia32_psllw256_mask, "V16sV16sV8sV16sUs","","avx512bw,avx512vl") +TARGET_BUILTIN(__builtin_ia32_psllwi128_mask, "V8sV8sIiV8sUc","","avx512bw,avx512vl") +TARGET_BUILTIN(__builtin_ia32_psllwi256_mask, "V16sV16sIiV16sUs","","avx512bw,avx512vl") +TARGET_BUILTIN(__builtin_ia32_psllv2di_mask, "V2LLiV2LLiV2LLiV2LLiUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_psllv4di_mask, "V4LLiV4LLiV4LLiV4LLiUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_psllv4si_mask, "V4iV4iV4iV4iUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_psllv8si_mask, "V8iV8iV8iV8iUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_pslldi512_mask, "V16iV16iIiV16iUs","","avx512f") +TARGET_BUILTIN(__builtin_ia32_psllqi512_mask, "V8LLiV8LLiIiV8LLiUc","","avx512f") +TARGET_BUILTIN(__builtin_ia32_pslld128_mask, "V4iV4iV4iV4iUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_pslld256_mask, "V8iV8iV4iV8iUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_pslldi128_mask, "V4iV4iIiV4iUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_pslldi256_mask, "V8iV8iIiV8iUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_psllq128_mask, "V2LLiV2LLiV2LLiV2LLiUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_psllq256_mask, "V4LLiV4LLiV2LLiV4LLiUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_psllqi128_mask, "V2LLiV2LLiIiV2LLiUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_psllqi256_mask, "V4LLiV4LLiIiV4LLiUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_psrlv32hi_mask, "V32sV32sV32sV32sUi","","avx512bw") +TARGET_BUILTIN(__builtin_ia32_psrlv16hi_mask, "V16sV16sV16sV16sUs","","avx512bw,avx512vl") +TARGET_BUILTIN(__builtin_ia32_psrlv8hi_mask, "V8sV8sV8sV8sUc","","avx512bw,avx512vl") +TARGET_BUILTIN(__builtin_ia32_psrlv2di_mask, "V2LLiV2LLiV2LLiV2LLiUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_psrlv4di_mask, "V4LLiV4LLiV4LLiV4LLiUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_psrlv4si_mask, "V4iV4iV4iV4iUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_psrlv8si_mask, "V8iV8iV8iV8iUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_psrldi512_mask, "V16iV16iIiV16iUs","","avx512f") +TARGET_BUILTIN(__builtin_ia32_psrlqi512_mask, "V8LLiV8LLiIiV8LLiUc","","avx512f") +TARGET_BUILTIN(__builtin_ia32_psrld128_mask, "V4iV4iV4iV4iUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_psrld256_mask, "V8iV8iV4iV8iUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_psrldi128_mask, "V4iV4iIiV4iUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_psrldi256_mask, "V8iV8iIiV8iUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_psrlq128_mask, "V2LLiV2LLiV2LLiV2LLiUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_psrlq256_mask, "V4LLiV4LLiV2LLiV4LLiUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_psrlqi128_mask, "V2LLiV2LLiIiV2LLiUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_psrlqi256_mask, "V4LLiV4LLiIiV4LLiUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_psrav32hi_mask, "V32sV32sV32sV32sUi","","avx512bw") +TARGET_BUILTIN(__builtin_ia32_psrav16hi_mask, "V16sV16sV16sV16sUs","","avx512bw,avx512vl") +TARGET_BUILTIN(__builtin_ia32_psrav8hi_mask, "V8sV8sV8sV8sUc","","avx512bw,avx512vl") +TARGET_BUILTIN(__builtin_ia32_psrav4si_mask, "V4iV4iV4iV4iUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_psrav8si_mask, "V8iV8iV8iV8iUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_psravq128_mask, "V2LLiV2LLiV2LLiV2LLiUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_psravq256_mask, "V4LLiV4LLiV4LLiV4LLiUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_psraw512_mask, "V32sV32sV8sV32sUi","","avx512bw") +TARGET_BUILTIN(__builtin_ia32_psrawi512_mask, "V32sV32sIiV32sUi","","avx512bw") +TARGET_BUILTIN(__builtin_ia32_psraw128_mask, "V8sV8sV8sV8sUc","","avx512bw,avx512vl") +TARGET_BUILTIN(__builtin_ia32_psraw256_mask, "V16sV16sV8sV16sUs","","avx512bw,avx512vl") +TARGET_BUILTIN(__builtin_ia32_psrawi128_mask, "V8sV8sIiV8sUc","","avx512bw,avx512vl") +TARGET_BUILTIN(__builtin_ia32_psrawi256_mask, "V16sV16sIiV16sUs","","avx512bw,avx512vl") +TARGET_BUILTIN(__builtin_ia32_psrlw512_mask, "V32sV32sV8sV32sUi","","avx512bw") +TARGET_BUILTIN(__builtin_ia32_psrlwi512_mask, "V32sV32sIiV32sUi","","avx512bw") +TARGET_BUILTIN(__builtin_ia32_psrlw128_mask, "V8sV8sV8sV8sUc","","avx512bw,avx512vl") +TARGET_BUILTIN(__builtin_ia32_psrlw256_mask, "V16sV16sV8sV16sUs","","avx512bw,avx512vl") +TARGET_BUILTIN(__builtin_ia32_psrlwi128_mask, "V8sV8sIiV8sUc","","avx512bw,avx512vl") +TARGET_BUILTIN(__builtin_ia32_psrlwi256_mask, "V16sV16sIiV16sUs","","avx512bw,avx512vl") +TARGET_BUILTIN(__builtin_ia32_movdqa32load128_mask, "V4iV4i*V4iUc","","avx512f") +TARGET_BUILTIN(__builtin_ia32_movdqa32load256_mask, "V8iV8i*V8iUc","","avx512f") +TARGET_BUILTIN(__builtin_ia32_movdqa32load512_mask, "V16iV16iC*V16iUs","","avx512f") +TARGET_BUILTIN(__builtin_ia32_movdqa32store512_mask, "vV16i*V16iUs","","avx512f") +TARGET_BUILTIN(__builtin_ia32_movdqa64load512_mask, "V8LLiV8LLiC*V8LLiUc","","avx512f") +TARGET_BUILTIN(__builtin_ia32_movdqa64store512_mask, "vV8LLi*V8LLiUc","","avx512f") +TARGET_BUILTIN(__builtin_ia32_movdqa32store128_mask, "vV4i*V4iUc","","avx512f") +TARGET_BUILTIN(__builtin_ia32_movdqa32store256_mask, "vV8i*V8iUc","","avx512f") +TARGET_BUILTIN(__builtin_ia32_movdqa64load128_mask, "V2LLiV2LLiC*V2LLiUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_movdqa64load256_mask, "V4LLiV4LLiC*V4LLiUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_movdqa64store128_mask, "vV2LLi*V2LLiUc","","avx512f") +TARGET_BUILTIN(__builtin_ia32_movdqa64store256_mask, "vV4LLi*V4LLiUc","","avx512f") +TARGET_BUILTIN(__builtin_ia32_pbroadcastb512_gpr_mask, "V64ccV64cULLi","","avx512bw") +TARGET_BUILTIN(__builtin_ia32_pbroadcastb128_gpr_mask, "V16ccV16cUs","","avx512bw,avx512vl") +TARGET_BUILTIN(__builtin_ia32_pbroadcastb256_gpr_mask, "V32ccV32cUi","","avx512bw,avx512vl") +TARGET_BUILTIN(__builtin_ia32_pbroadcastd128_gpr_mask, "V4iiV4iUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_pbroadcastd256_gpr_mask, "V8iiV8iUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_pbroadcastq128_gpr_mask, "V2LLiULLiV2LLiUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_pbroadcastq256_gpr_mask, "V4LLiULLiV4LLiUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_vpmadd52huq512_mask, "V8LLiV8LLiV8LLiV8LLiUc","","avx512ifma") +TARGET_BUILTIN(__builtin_ia32_vpmadd52huq512_maskz, "V8LLiV8LLiV8LLiV8LLiUc","","avx512ifma") +TARGET_BUILTIN(__builtin_ia32_vpmadd52luq512_mask, "V8LLiV8LLiV8LLiV8LLiUc","","avx512ifma") +TARGET_BUILTIN(__builtin_ia32_vpmadd52luq512_maskz, "V8LLiV8LLiV8LLiV8LLiUc","","avx512ifma") +TARGET_BUILTIN(__builtin_ia32_vpmadd52huq128_mask, "V2LLiV2LLiV2LLiV2LLiUc","","avx512ifma,avx512vl") +TARGET_BUILTIN(__builtin_ia32_vpmadd52huq128_maskz, "V2LLiV2LLiV2LLiV2LLiUc","","avx512ifma,avx512vl") +TARGET_BUILTIN(__builtin_ia32_vpmadd52huq256_mask, "V4LLiV4LLiV4LLiV4LLiUc","","avx512ifma,avx512vl") +TARGET_BUILTIN(__builtin_ia32_vpmadd52huq256_maskz, "V4LLiV4LLiV4LLiV4LLiUc","","avx512ifma,avx512vl") +TARGET_BUILTIN(__builtin_ia32_vpmadd52luq128_mask, "V2LLiV2LLiV2LLiV2LLiUc","","avx512ifma,avx512vl") +TARGET_BUILTIN(__builtin_ia32_vpmadd52luq128_maskz, "V2LLiV2LLiV2LLiV2LLiUc","","avx512ifma,avx512vl") +TARGET_BUILTIN(__builtin_ia32_vpmadd52luq256_mask, "V4LLiV4LLiV4LLiV4LLiUc","","avx512ifma,avx512vl") +TARGET_BUILTIN(__builtin_ia32_vpmadd52luq256_maskz, "V4LLiV4LLiV4LLiV4LLiUc","","avx512ifma,avx512vl") +TARGET_BUILTIN(__builtin_ia32_vpermi2varqi512_mask, "V64cV64cV64cV64cULLi","","avx512vbmi") +TARGET_BUILTIN(__builtin_ia32_vpermt2varqi512_mask, "V64cV64cV64cV64cULLi","","avx512vbmi") +TARGET_BUILTIN(__builtin_ia32_vpermt2varqi512_maskz, "V64cV64cV64cV64cULLi","","avx512vbmi") +TARGET_BUILTIN(__builtin_ia32_vpermi2varqi128_mask, "V16cV16cV16cV16cUs","","avx512vbmi,avx512vl") +TARGET_BUILTIN(__builtin_ia32_vpermi2varqi256_mask, "V32cV32cV32cV32cUi","","avx512vbmi,avx512vl") +TARGET_BUILTIN(__builtin_ia32_vpermt2varqi128_mask, "V16cV16cV16cV16cUs","","avx512vbmi,avx512vl") +TARGET_BUILTIN(__builtin_ia32_vpermt2varqi128_maskz, "V16cV16cV16cV16cUs","","avx512vbmi,avx512vl") +TARGET_BUILTIN(__builtin_ia32_vpermt2varqi256_mask, "V32cV32cV32cV32cUi","","avx512vbmi,avx512vl") +TARGET_BUILTIN(__builtin_ia32_vpermt2varqi256_maskz, "V32cV32cV32cV32cUi","","avx512vbmi,avx512vl") +TARGET_BUILTIN(__builtin_ia32_vcomisd, "iV2dV2dIiIi","","avx512f") +TARGET_BUILTIN(__builtin_ia32_vcomiss, "iV4fV4fIiIi","","avx512f") +TARGET_BUILTIN(__builtin_ia32_kunpckdi, "ULLiULLiULLi","","avx512bw") +TARGET_BUILTIN(__builtin_ia32_kunpcksi, "UiUiUi","","avx512bw") +TARGET_BUILTIN(__builtin_ia32_loaddquhi512_mask, "V32sV32s*V32sUi","","avx512f") +TARGET_BUILTIN(__builtin_ia32_loaddquqi512_mask, "V64cV64c*V64cULLi","","avx512f") +TARGET_BUILTIN(__builtin_ia32_fixupimmpd512_mask, "V8dV8dV8dV8LLiIiUcIi","","avx512f") +TARGET_BUILTIN(__builtin_ia32_fixupimmpd512_maskz, "V8dV8dV8dV8LLiIiUcIi","","avx512f") +TARGET_BUILTIN(__builtin_ia32_fixupimmps512_mask, "V16fV16fV16fV16iIiUsIi","","avx512f") +TARGET_BUILTIN(__builtin_ia32_fixupimmps512_maskz, "V16fV16fV16fV16iIiUsIi","","avx512f") +TARGET_BUILTIN(__builtin_ia32_fixupimmsd_mask, "V2dV2dV2dV2LLiIiUcIi","","avx512f") +TARGET_BUILTIN(__builtin_ia32_fixupimmsd_maskz, "V2dV2dV2dV2LLiIiUcIi","","avx512f") +TARGET_BUILTIN(__builtin_ia32_fixupimmss_mask, "V4fV4fV4fV4iIiUcIi","","avx512f") +TARGET_BUILTIN(__builtin_ia32_fixupimmss_maskz, "V4fV4fV4fV4iIiUcIi","","avx512f") +TARGET_BUILTIN(__builtin_ia32_getexpsd128_round_mask, "V2dV2dV2dV2dUcIi","","avx512f") +TARGET_BUILTIN(__builtin_ia32_getexpss128_round_mask, "V4fV4fV4fV4fUcIi","","avx512f") +TARGET_BUILTIN(__builtin_ia32_getmantsd_round_mask, "V2dV2dV2dIiV2dUcIi","","avx512f") +TARGET_BUILTIN(__builtin_ia32_getmantss_round_mask, "V4fV4fV4fIiV4fUcIi","","avx512f") +TARGET_BUILTIN(__builtin_ia32_loaddquhi128_mask, "V8sV8s*V8sUc","","avx512bw,avx512vl") +TARGET_BUILTIN(__builtin_ia32_loaddquhi256_mask, "V16sV16s*V16sUs","","avx512bw,avx512vl") +TARGET_BUILTIN(__builtin_ia32_loaddquqi128_mask, "V16cV16c*V16cUs","","avx512bw,avx512vl") +TARGET_BUILTIN(__builtin_ia32_loaddquqi256_mask, "V32cV32c*V32cUi","","avx512bw,avx512vl") +TARGET_BUILTIN(__builtin_ia32_fixupimmpd128_mask, "V2dV2dV2dV2LLiIiUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_fixupimmpd128_maskz, "V2dV2dV2dV2LLiIiUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_fixupimmpd256_mask, "V4dV4dV4dV4LLiIiUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_fixupimmpd256_maskz, "V4dV4dV4dV4LLiIiUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_fixupimmps128_mask, "V4fV4fV4fV4iIiUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_fixupimmps128_maskz, "V4fV4fV4fV4iIiUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_fixupimmps256_mask, "V8fV8fV8fV8iIiUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_fixupimmps256_maskz, "V8fV8fV8fV8iIiUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_loadapd128_mask, "V2dV2d*V2dUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_loadapd256_mask, "V4dV4d*V4dUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_loadaps128_mask, "V4fV4f*V4fUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_loadaps256_mask, "V8fV8f*V8fUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_loaddqudi128_mask, "V2LLiV2LLi*V2LLiUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_loaddqudi256_mask, "V4LLiV4LLi*V4LLiUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_loaddqusi128_mask, "V4iV4i*V4iUc","","avx512f") +TARGET_BUILTIN(__builtin_ia32_loaddqusi256_mask, "V8iV8i*V8iUc","","avx512f") +TARGET_BUILTIN(__builtin_ia32_loadupd128_mask, "V2dV2d*V2dUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_loadupd256_mask, "V4dV4d*V4dUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_loadups128_mask, "V4fV4f*V4fUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_loadups256_mask, "V8fV8f*V8fUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_storedquhi512_mask, "vV32s*V32sUi","","avx512bw") +TARGET_BUILTIN(__builtin_ia32_storedquqi512_mask, "vV64c*V64cULLi","","avx512bw") +TARGET_BUILTIN(__builtin_ia32_storedquhi128_mask, "vV8s*V8sUc","","avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_storedquhi256_mask, "vV16s*V16sUs","","avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_storedquqi128_mask, "vV16c*V16cUs","","avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_storedquqi256_mask, "vV32c*V32cUi","","avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_storeapd128_mask, "vV2d*V2dUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_storeapd256_mask, "vV4d*V4dUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_storeaps128_mask, "vV4f*V4fUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_storeaps256_mask, "vV8f*V8fUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_storedqudi128_mask, "vV2LLi*V2LLiUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_storedqudi256_mask, "vV4LLi*V4LLiUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_storedqusi128_mask, "vV4i*V4iUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_storedqusi256_mask, "vV8i*V8iUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_storeupd128_mask, "vV2d*V2dUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_storeupd256_mask, "vV4d*V4dUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_storeups128_mask, "vV4f*V4fUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_storeups256_mask, "vV8f*V8fUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_rcp14pd128_mask, "V2dV2dV2dUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_rcp14pd256_mask, "V4dV4dV4dUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_rcp14ps128_mask, "V4fV4fV4fUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_rcp14ps256_mask, "V8fV8fV8fUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_vplzcntd_128_mask, "V4iV4iV4iUc","","avx512cd,avx512vl") +TARGET_BUILTIN(__builtin_ia32_vplzcntd_256_mask, "V8iV8iV8iUc","","avx512cd,avx512vl") +TARGET_BUILTIN(__builtin_ia32_vplzcntq_128_mask, "V2LLiV2LLiV2LLiUc","","avx512cd,avx512vl") +TARGET_BUILTIN(__builtin_ia32_vplzcntq_256_mask, "V4LLiV4LLiV4LLiUc","","avx512cd,avx512vl") +TARGET_BUILTIN(__builtin_ia32_vcvtsd2si64, "LLiV2dIi","","avx512f") +TARGET_BUILTIN(__builtin_ia32_vcvtsd2si32, "iV2dIi","","avx512f") +TARGET_BUILTIN(__builtin_ia32_vcvtsd2usi32, "UiV2dIi","","avx512f") +TARGET_BUILTIN(__builtin_ia32_vcvtsd2usi64, "ULLiV2dIi","","avx512f") +TARGET_BUILTIN(__builtin_ia32_vcvtss2si32, "iV4fIi","","avx512f") +TARGET_BUILTIN(__builtin_ia32_vcvtss2si64, "LLiV4fIi","","avx512f") +TARGET_BUILTIN(__builtin_ia32_vcvtss2usi32, "UiV4fIi","","avx512f") +TARGET_BUILTIN(__builtin_ia32_vcvtss2usi64, "ULLiV4fIi","","avx512f") +TARGET_BUILTIN(__builtin_ia32_vcvttsd2si32, "iV2dIi","","avx512f") +TARGET_BUILTIN(__builtin_ia32_vcvttsd2si64, "LLiV2dIi","","avx512f") +TARGET_BUILTIN(__builtin_ia32_vcvttsd2usi32, "UiV2dIi","","avx512f") +TARGET_BUILTIN(__builtin_ia32_vcvttsd2usi64, "ULLiV2dIi","","avx512f") +TARGET_BUILTIN(__builtin_ia32_vcvttss2si32, "iV4fIi","","avx512f") +TARGET_BUILTIN(__builtin_ia32_vcvttss2si64, "LLiV4fIi","","avx512f") +TARGET_BUILTIN(__builtin_ia32_vcvttss2usi32, "UiV4fIi","","avx512f") +TARGET_BUILTIN(__builtin_ia32_vcvttss2usi64, "ULLiV4fIi","","avx512f") +TARGET_BUILTIN(__builtin_ia32_vpermi2vard512_mask, "V16iV16iV16iV16iUs","","avx512f") +TARGET_BUILTIN(__builtin_ia32_vpermi2varpd512_mask, "V8dV8dV8LLiV8dUc","","avx512f") +TARGET_BUILTIN(__builtin_ia32_vpermi2varps512_mask, "V16fV16fV16iV16fUs","","avx512f") +TARGET_BUILTIN(__builtin_ia32_vpermi2varq512_mask, "V8LLiV8LLiV8LLiV8LLiUc","","avx512f") +TARGET_BUILTIN(__builtin_ia32_vpermilvarpd512_mask, "V8dV8dV8LLiV8dUc","","avx512f") +TARGET_BUILTIN(__builtin_ia32_vpermilvarps512_mask, "V16fV16fV16iV16fUs","","avx512f") +TARGET_BUILTIN(__builtin_ia32_vpermt2vard512_maskz, "V16iV16iV16iV16iUs","","avx512f") +TARGET_BUILTIN(__builtin_ia32_vpermt2varpd512_maskz, "V8dV8LLiV8dV8dUc","","avx512f") +TARGET_BUILTIN(__builtin_ia32_vpermt2varps512_maskz, "V16fV16iV16fV16fUs","","avx512f") +TARGET_BUILTIN(__builtin_ia32_vpermt2varq512_maskz, "V8LLiV8LLiV8LLiV8LLiUc","","avx512f") +TARGET_BUILTIN(__builtin_ia32_vpermilvarpd_mask, "V2dV2dV2LLiV2dUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_vpermilvarpd256_mask, "V4dV4dV4LLiV4dUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_vpermilvarps_mask, "V4fV4fV4iV4fUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_vpermilvarps256_mask, "V8fV8fV8iV8fUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_ptestmb512, "ULLiV64cV64cULLi","","avx512bw") +TARGET_BUILTIN(__builtin_ia32_ptestmw512, "UiV32sV32sUi","","avx512bw") +TARGET_BUILTIN(__builtin_ia32_ptestnmb512, "ULLiV64cV64cULLi","","avx512bw") +TARGET_BUILTIN(__builtin_ia32_ptestnmw512, "UiV32sV32sUi","","avx512bw") +TARGET_BUILTIN(__builtin_ia32_ptestmb128, "UsV16cV16cUs","","avx512bw,avx512vl") +TARGET_BUILTIN(__builtin_ia32_ptestmb256, "UiV32cV32cUi","","avx512bw,avx512vl") +TARGET_BUILTIN(__builtin_ia32_ptestmw128, "UcV8sV8sUc","","avx512bw,avx512vl") +TARGET_BUILTIN(__builtin_ia32_ptestmw256, "UsV16sV16sUs","","avx512bw,avx512vl") +TARGET_BUILTIN(__builtin_ia32_ptestnmb128, "UsV16cV16cUs","","avx512bw,avx512vl") +TARGET_BUILTIN(__builtin_ia32_ptestnmb256, "UiV32cV32cUi","","avx512bw,avx512vl") +TARGET_BUILTIN(__builtin_ia32_ptestnmw128, "UcV8sV8sUc","","avx512bw,avx512vl") +TARGET_BUILTIN(__builtin_ia32_ptestnmw256, "UsV16sV16sUs","","avx512bw,avx512vl") +TARGET_BUILTIN(__builtin_ia32_ptestmd128, "UcV4iV4iUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_ptestmd256, "UcV8iV8iUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_ptestmq128, "UcV2LLiV2LLiUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_ptestmq256, "UcV4LLiV4LLiUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_ptestnmd128, "UcV4iV4iUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_ptestnmd256, "UcV8iV8iUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_ptestnmq128, "UcV2LLiV2LLiUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_ptestnmq256, "UcV4LLiV4LLiUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_ptestnmd512, "UsV16iV16iUs","","avx512f") +TARGET_BUILTIN(__builtin_ia32_ptestnmq512, "UcV8LLiV8LLiUc","","avx512f") +TARGET_BUILTIN(__builtin_ia32_rndscalesd_round_mask, "V2dV2dV2dV2dUcIiIi","","avx512f") +TARGET_BUILTIN(__builtin_ia32_rndscaless_round_mask, "V4fV4fV4fV4fUcIiIi","","avx512f") +TARGET_BUILTIN(__builtin_ia32_scalefpd512_mask, "V8dV8dV8dV8dUcIi","","avx512f") +TARGET_BUILTIN(__builtin_ia32_scalefps512_mask, "V16fV16fV16fV16fUsIi","","avx512f") +TARGET_BUILTIN(__builtin_ia32_scalefsd_round_mask, "V2dV2dV2dV2dUcIi","","avx512f") +TARGET_BUILTIN(__builtin_ia32_scalefss_round_mask, "V4fV4fV4fV4fUcIi","","avx512f") +TARGET_BUILTIN(__builtin_ia32_psradi512_mask, "V16iV16iIiV16iUs","","avx512f") +TARGET_BUILTIN(__builtin_ia32_psraqi512_mask, "V8LLiV8LLiIiV8LLiUc","","avx512f") +TARGET_BUILTIN(__builtin_ia32_psrad128_mask, "V4iV4iV4iV4iUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_psrad256_mask, "V8iV8iV4iV8iUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_psradi128_mask, "V4iV4iIiV4iUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_psradi256_mask, "V8iV8iIiV8iUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_psraq128_mask, "V2LLiV2LLiV2LLiV2LLiUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_psraq256_mask, "V4LLiV4LLiV2LLiV4LLiUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_psraqi128_mask, "V2LLiV2LLiIiV2LLiUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_psraqi256_mask, "V4LLiV4LLiIiV4LLiUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_pslld512_mask, "V16iV16iV4iV16iUs","","avx512f") +TARGET_BUILTIN(__builtin_ia32_psllq512_mask, "V8LLiV8LLiV2LLiV8LLiUc","","avx512f") +TARGET_BUILTIN(__builtin_ia32_psllv16si_mask, "V16iV16iV16iV16iUs","","avx512f") +TARGET_BUILTIN(__builtin_ia32_psllv8di_mask, "V8LLiV8LLiV8LLiV8LLiUc","","avx512f") +TARGET_BUILTIN(__builtin_ia32_psrad512_mask, "V16iV16iV4iV16iUs","","avx512f") +TARGET_BUILTIN(__builtin_ia32_psraq512_mask, "V8LLiV8LLiV2LLiV8LLiUc","","avx512f") +TARGET_BUILTIN(__builtin_ia32_psrav16si_mask, "V16iV16iV16iV16iUs","","avx512f") +TARGET_BUILTIN(__builtin_ia32_psrav8di_mask, "V8LLiV8LLiV8LLiV8LLiUc","","avx512f") +TARGET_BUILTIN(__builtin_ia32_psrld512_mask, "V16iV16iV4iV16iUs","","avx512f") +TARGET_BUILTIN(__builtin_ia32_psrlq512_mask, "V8LLiV8LLiV2LLiV8LLiUc","","avx512f") +TARGET_BUILTIN(__builtin_ia32_psrlv16si_mask, "V16iV16iV16iV16iUs","","avx512f") +TARGET_BUILTIN(__builtin_ia32_psrlv8di_mask, "V8LLiV8LLiV8LLiV8LLiUc","","avx512f") +TARGET_BUILTIN(__builtin_ia32_pternlogd512_mask, "V16iV16iV16iV16iIiUs","","avx512f") +TARGET_BUILTIN(__builtin_ia32_pternlogd512_maskz, "V16iV16iV16iV16iIiUs","","avx512f") +TARGET_BUILTIN(__builtin_ia32_pternlogq512_mask, "V8LLiV8LLiV8LLiV8LLiIiUc","","avx512f") +TARGET_BUILTIN(__builtin_ia32_pternlogq512_maskz, "V8LLiV8LLiV8LLiV8LLiIiUc","","avx512f") +TARGET_BUILTIN(__builtin_ia32_pternlogd128_mask, "V4iV4iV4iV4iIiUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_pternlogd128_maskz, "V4iV4iV4iV4iIiUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_pternlogd256_mask, "V8iV8iV8iV8iIiUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_pternlogd256_maskz, "V8iV8iV8iV8iIiUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_pternlogq128_mask, "V2LLiV2LLiV2LLiV2LLiIiUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_pternlogq128_maskz, "V2LLiV2LLiV2LLiV2LLiIiUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_pternlogq256_mask, "V4LLiV4LLiV4LLiV4LLiIiUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_pternlogq256_maskz, "V4LLiV4LLiV4LLiV4LLiIiUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_shuf_f32x4_mask, "V16fV16fV16fIiV16fUs","","avx512f") +TARGET_BUILTIN(__builtin_ia32_shuf_f64x2_mask, "V8dV8dV8dIiV8dUc","","avx512f") +TARGET_BUILTIN(__builtin_ia32_shuf_i32x4_mask, "V16iV16iV16iIiV16iUs","","avx512f") +TARGET_BUILTIN(__builtin_ia32_shuf_i64x2_mask, "V8LLiV8LLiV8LLiIiV8LLiUc","","avx512f") +TARGET_BUILTIN(__builtin_ia32_shuf_f32x4_256_mask, "V8fV8fV8fIiV8fUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_shuf_f64x2_256_mask, "V4dV4dV4dIiV4dUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_shuf_i32x4_256_mask, "V8iV8iV8iIiV8iUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_shuf_i64x2_256_mask, "V4LLiV4LLiV4LLiIiV4LLiUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_sqrtsd_round_mask, "V2dV2dV2dV2dUcIi","","avx512f") +TARGET_BUILTIN(__builtin_ia32_sqrtss_round_mask, "V4fV4fV4fV4fUcIi","","avx512f") +TARGET_BUILTIN(__builtin_ia32_rsqrt14pd128_mask, "V2dV2dV2dUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_rsqrt14pd256_mask, "V4dV4dV4dUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_rsqrt14ps128_mask, "V4fV4fV4fUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_rsqrt14ps256_mask, "V8fV8fV8fUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_cvtb2mask512, "ULLiV64c","","avx512bw") +TARGET_BUILTIN(__builtin_ia32_cvtmask2b512, "V64cULLi","","avx512bw") +TARGET_BUILTIN(__builtin_ia32_cvtmask2w512, "V32sUi","","avx512bw") +TARGET_BUILTIN(__builtin_ia32_cvtd2mask512, "UsV16i","","avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvtmask2d512, "V16iUs","","avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvtmask2q512, "V8LLiUc","","avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvtq2mask512, "UcV8LLi","","avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvtb2mask128, "UsV16c","","avx512bw,avx512vl") +TARGET_BUILTIN(__builtin_ia32_cvtb2mask256, "UiV32c","","avx512bw,avx512vl") +TARGET_BUILTIN(__builtin_ia32_cvtmask2b128, "V16cUs","","avx512bw,avx512vl") +TARGET_BUILTIN(__builtin_ia32_cvtmask2b256, "V32cUi","","avx512bw,avx512vl") +TARGET_BUILTIN(__builtin_ia32_cvtmask2w128, "V8sUc","","avx512bw,avx512vl") +TARGET_BUILTIN(__builtin_ia32_cvtmask2w256, "V16sUs","","avx512bw,avx512vl") +TARGET_BUILTIN(__builtin_ia32_cvtd2mask128, "UcV4i","","avx512dq,avx512vl") +TARGET_BUILTIN(__builtin_ia32_cvtd2mask256, "UcV8i","","avx512dq,avx512vl") +TARGET_BUILTIN(__builtin_ia32_cvtmask2d128, "V4iUc","","avx512dq,avx512vl") +TARGET_BUILTIN(__builtin_ia32_cvtmask2d256, "V8iUc","","avx512dq,avx512vl") +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_broadcastf32x4_512, "V16fV4fV16fUs","","avx512f") +TARGET_BUILTIN(__builtin_ia32_broadcastf64x4_512, "V8dV4dV8dUc","","avx512f") +TARGET_BUILTIN(__builtin_ia32_broadcasti32x4_512, "V16iV4iV16iUs","","avx512f") +TARGET_BUILTIN(__builtin_ia32_broadcasti64x4_512, "V8LLiV4LLiV8LLiUc","","avx512f") +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_broadcastf32x2_512_mask, "V16fV4fV16fUs","","avx512dq") +TARGET_BUILTIN(__builtin_ia32_broadcastf32x8_512_mask, "V16fV8fV16fUs","","avx512dq") +TARGET_BUILTIN(__builtin_ia32_broadcastf64x2_512_mask, "V8dV2dV8dUc","","avx512dq") +TARGET_BUILTIN(__builtin_ia32_broadcasti32x2_512_mask, "V16iV4iV16iUs","","avx512dq") +TARGET_BUILTIN(__builtin_ia32_broadcasti32x8_512_mask, "V16iV8iV16iUs","","avx512dq") +TARGET_BUILTIN(__builtin_ia32_broadcasti64x2_512_mask, "V8LLiV2LLiV8LLiUc","","avx512dq") +TARGET_BUILTIN(__builtin_ia32_broadcastf32x2_256_mask, "V8fV4fV8fUc","","avx512dq,avx512vl") +TARGET_BUILTIN(__builtin_ia32_broadcastf64x2_256_mask, "V4dV2dV4dUc","","avx512dq,avx512vl") +TARGET_BUILTIN(__builtin_ia32_broadcasti32x2_128_mask, "V4iV4iV4iUc","","avx512dq,avx512vl") +TARGET_BUILTIN(__builtin_ia32_broadcasti32x2_256_mask, "V8iV4iV8iUc","","avx512dq,avx512vl") +TARGET_BUILTIN(__builtin_ia32_broadcasti64x2_256_mask, "V4LLiV2LLiV4LLiUc","","avx512dq,avx512vl") +TARGET_BUILTIN(__builtin_ia32_broadcastf32x4_256_mask, "V8fV4fV8fUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_broadcasti32x4_256_mask, "V8iV4iV8iUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_pbroadcastw512_gpr_mask, "V32shV32sUi","","avx512bw") +TARGET_BUILTIN(__builtin_ia32_pbroadcastw256_gpr_mask, "V16shV16sUs","","avx512bw,avx512vl") +TARGET_BUILTIN(__builtin_ia32_pbroadcastw128_gpr_mask, "V8ssV8sUc","","avx512bw,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") +TARGET_BUILTIN(__builtin_ia32_pmovsdw512_mask, "V16sV16iV16sUs","","avx512f") +TARGET_BUILTIN(__builtin_ia32_pmovsdw512mem_mask, "vV16s*V16iUs","","avx512f") +TARGET_BUILTIN(__builtin_ia32_pmovsqb512_mask, "V16cV8LLiV16cUc","","avx512f") +TARGET_BUILTIN(__builtin_ia32_pmovsqb512mem_mask, "vV16c*V8LLiUc","","avx512f") +TARGET_BUILTIN(__builtin_ia32_pmovsqd512_mask, "V8iV8LLiV8iUc","","avx512f") +TARGET_BUILTIN(__builtin_ia32_pmovsqd512mem_mask, "vV8i*V8LLiUc","","avx512f") +TARGET_BUILTIN(__builtin_ia32_pmovsqw512_mask, "V8sV8LLiV8sUc","","avx512f") +TARGET_BUILTIN(__builtin_ia32_pmovsqw512mem_mask, "vV8s*V8LLiUc","","avx512f") +TARGET_BUILTIN(__builtin_ia32_pmovsdb128_mask, "V16cV4iV16cUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovsdb128mem_mask, "vV16c*V4iUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovswb128mem_mask, "vV16c*V8sUc","","avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_pmovsdb256_mask, "V16cV8iV16cUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovsdb256mem_mask, "vV16c*V8iUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovswb256mem_mask, "vV16c*V16sUs","","avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_pmovsdw128_mask, "V8sV4iV8sUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovsdw128mem_mask, "vV8s*V4iUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovsdw256_mask, "V8sV8iV8sUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovsdw256mem_mask, "vV8s*V8iUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovsqb128_mask, "V16cV2LLiV16cUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovsqb128mem_mask, "vV16c*V2LLiUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovsqb256_mask, "V16cV4LLiV16cUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovsqb256mem_mask, "vV16c*V4LLiUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovsqd128_mask, "V4iV2LLiV4iUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovsqd128mem_mask, "vV4i*V2LLiUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovsqd256_mask, "V4iV4LLiV4iUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovsqd256mem_mask, "vV4i*V4LLiUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovsqw128_mask, "V8sV2LLiV8sUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovsqw128mem_mask, "vV8s*V2LLiUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovsqw256_mask, "V8sV4LLiV8sUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovsqw256mem_mask, "vV8s*V4LLiUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovusdb512_mask, "V16cV16iV16cUs","","avx512f") +TARGET_BUILTIN(__builtin_ia32_pmovusdb512mem_mask, "vV16c*V16iUs","","avx512f") +TARGET_BUILTIN(__builtin_ia32_pmovuswb512mem_mask, "vV32c*V32sUi","","avx512bw") +TARGET_BUILTIN(__builtin_ia32_pmovusdw512_mask, "V16sV16iV16sUs","","avx512f") +TARGET_BUILTIN(__builtin_ia32_pmovusdw512mem_mask, "vV16s*V16iUs","","avx512f") +TARGET_BUILTIN(__builtin_ia32_pmovusqb512_mask, "V16cV8LLiV16cUc","","avx512f") +TARGET_BUILTIN(__builtin_ia32_pmovusqb512mem_mask, "vV16c*V8LLiUc","","avx512f") +TARGET_BUILTIN(__builtin_ia32_pmovusqd512_mask, "V8iV8LLiV8iUc","","avx512f") +TARGET_BUILTIN(__builtin_ia32_pmovusqd512mem_mask, "vV8i*V8LLiUc","","avx512f") +TARGET_BUILTIN(__builtin_ia32_pmovusqw512_mask, "V8sV8LLiV8sUc","","avx512f") +TARGET_BUILTIN(__builtin_ia32_pmovusqw512mem_mask, "vV8s*V8LLiUc","","avx512f") +TARGET_BUILTIN(__builtin_ia32_pmovusdb128_mask, "V16cV4iV16cUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovusdb128mem_mask, "vV16c*V4iUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovuswb128mem_mask, "vV16c*V8sUc","","avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_pmovusdb256_mask, "V16cV8iV16cUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovusdb256mem_mask, "vV16c*V8iUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovuswb256mem_mask, "vV16c*V16sUs","","avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_pmovusdw128_mask, "V8sV4iV8sUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovusdw128mem_mask, "vV8s*V4iUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovusdw256_mask, "V8sV8iV8sUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovusdw256mem_mask, "vV8s*V8iUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovusqb128_mask, "V16cV2LLiV16cUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovusqb128mem_mask, "vV16c*V2LLiUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovusqb256_mask, "V16cV4LLiV16cUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovusqb256mem_mask, "vV16c*V4LLiUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovusqd128_mask, "V4iV2LLiV4iUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovusqd128mem_mask, "vV4i*V2LLiUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovusqd256_mask, "V4iV4LLiV4iUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovusqd256mem_mask, "vV4i*V4LLiUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovusqw128_mask, "V8sV2LLiV8sUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovusqw128mem_mask, "vV8s*V2LLiUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovusqw256_mask, "V8sV4LLiV8sUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovusqw256mem_mask, "vV8s*V4LLiUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovdb512_mask, "V16cV16iV16cUs","","avx512f") +TARGET_BUILTIN(__builtin_ia32_pmovdb512mem_mask, "vV16c*V16iUs","","avx512f") +TARGET_BUILTIN(__builtin_ia32_pmovwb512mem_mask, "vV32c*V32sUi","","avx512bw") +TARGET_BUILTIN(__builtin_ia32_pmovdw512_mask, "V16sV16iV16sUs","","avx512f") +TARGET_BUILTIN(__builtin_ia32_pmovdw512mem_mask, "vV16s*V16iUs","","avx512f") +TARGET_BUILTIN(__builtin_ia32_pmovqb512_mask, "V16cV8LLiV16cUc","","avx512f") +TARGET_BUILTIN(__builtin_ia32_pmovqb512mem_mask, "vV16c*V8LLiUc","","avx512f") +TARGET_BUILTIN(__builtin_ia32_pmovqd512_mask, "V8iV8LLiV8iUc","","avx512f") +TARGET_BUILTIN(__builtin_ia32_pmovqd512mem_mask, "vV8i*V8LLiUc","","avx512f") +TARGET_BUILTIN(__builtin_ia32_pmovqw512_mask, "V8sV8LLiV8sUc","","avx512f") +TARGET_BUILTIN(__builtin_ia32_pmovqw512mem_mask, "vV8s*V8LLiUc","","avx512f") +TARGET_BUILTIN(__builtin_ia32_pmovdb128_mask, "V16cV4iV16cUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovwb128mem_mask, "vV16c*V8sUc","","avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_pmovdb128mem_mask, "vV16c*V4iUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovdb256_mask, "V16cV8iV16cUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovdb256mem_mask, "vV16c*V8iUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovwb256mem_mask, "vV16c*V16sUs","","avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_pmovdw128_mask, "V8sV4iV8sUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovdw128mem_mask, "vV8s*V4iUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovdw256_mask, "V8sV8iV8sUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovdw256mem_mask, "vV8s*V8iUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovqb128_mask, "V16cV2LLiV16cUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovqb128mem_mask, "vV16c*V2LLiUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovqb256_mask, "V16cV4LLiV16cUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovqb256mem_mask, "vV16c*V4LLiUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovqd128_mask, "V4iV2LLiV4iUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovqd128mem_mask, "vV4i*V2LLiUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovqd256_mask, "V4iV4LLiV4iUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovqd256mem_mask, "vV4i*V4LLiUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovqw128_mask, "V8sV2LLiV8sUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovqw128mem_mask, "vV8s*V2LLiUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovqw256_mask, "V8sV4LLiV8sUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmovqw256mem_mask, "vV8s*V4LLiUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_extractf32x8_mask, "V8fV16fIiV8fUc","","avx512dq") +TARGET_BUILTIN(__builtin_ia32_extractf64x2_512_mask, "V2dV8dIiV2dUc","","avx512dq") +TARGET_BUILTIN(__builtin_ia32_extracti32x8_mask, "V8iV16iIiV8iUc","","avx512dq") +TARGET_BUILTIN(__builtin_ia32_extracti64x2_512_mask, "V2LLiV8LLiIiV2LLiUc","","avx512dq") +TARGET_BUILTIN(__builtin_ia32_extracti32x4_mask, "V4iV16iIiV4iUc","","avx512f") +TARGET_BUILTIN(__builtin_ia32_extracti64x4_mask, "V4LLiV8LLiIiV4LLiUc","","avx512f") +TARGET_BUILTIN(__builtin_ia32_extractf64x2_256_mask, "V2dV4dIiV2dUc","","avx512dq,avx512vl") +TARGET_BUILTIN(__builtin_ia32_extracti64x2_256_mask, "V2LLiV4LLiIiV2LLiUc","","avx512dq,avx512vl") +TARGET_BUILTIN(__builtin_ia32_extractf32x4_256_mask, "V4fV8fIiV4fUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_extracti32x4_256_mask, "V4iV8iIiV4iUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_insertf32x8_mask, "V16fV16fV8fIiV16fUs","","avx512dq") +TARGET_BUILTIN(__builtin_ia32_insertf64x2_512_mask, "V8dV8dV2dIiV8dUc","","avx512dq") +TARGET_BUILTIN(__builtin_ia32_inserti32x8_mask, "V16iV16iV8iIiV16iUs","","avx512dq") +TARGET_BUILTIN(__builtin_ia32_inserti64x2_512_mask, "V8LLiV8LLiV2LLiIiV8LLiUc","","avx512dq") +TARGET_BUILTIN(__builtin_ia32_insertf64x4_mask, "V8dV8dV4dIiV8dUc","","avx512f") +TARGET_BUILTIN(__builtin_ia32_inserti64x4_mask, "V8LLiV8LLiV4LLiIiV8LLiUc","","avx512f") +TARGET_BUILTIN(__builtin_ia32_insertf64x2_256_mask, "V4dV4dV2dIiV4dUc","","avx512dq,avx512vl") +TARGET_BUILTIN(__builtin_ia32_inserti64x2_256_mask, "V4LLiV4LLiV2LLiIiV4LLiUc","","avx512dq,avx512vl") +TARGET_BUILTIN(__builtin_ia32_insertf32x4_256_mask, "V8fV8fV4fIiV8fUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_inserti32x4_256_mask, "V8iV8iV4iIiV8iUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_insertf32x4_mask, "V16fV16fV4fIiV16fUs","","avx512f") +TARGET_BUILTIN(__builtin_ia32_inserti32x4_mask, "V16iV16iV4iIiV16iUs","","avx512f") +TARGET_BUILTIN(__builtin_ia32_getmantpd128_mask, "V2dV2diV2dUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_getmantpd256_mask, "V4dV4diV4dUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_getmantps128_mask, "V4fV4fiV4fUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_getmantps256_mask, "V8fV8fiV8fUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_getmantpd512_mask, "V8dV8diV8dUcIi","","avx512f") +TARGET_BUILTIN(__builtin_ia32_getmantps512_mask, "V16fV16fiV16fUsIi","","avx512f") +TARGET_BUILTIN(__builtin_ia32_getexppd512_mask, "V8dV8dV8dUcIi","","avx512f") +TARGET_BUILTIN(__builtin_ia32_getexpps512_mask, "V16fV16fV16fUsIi","","avx512f") +TARGET_BUILTIN(__builtin_ia32_vfmaddss3_mask, "V4fV4fV4fV4fUcIi", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_vfmaddss3_maskz, "V4fV4fV4fV4fUcIi", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_vfmaddss3_mask3, "V4fV4fV4fV4fUcIi", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_vfmaddsd3_mask, "V2dV2dV2dV2dUcIi", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_vfmaddsd3_maskz, "V2dV2dV2dV2dUcIi", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_vfmaddsd3_mask3, "V2dV2dV2dV2dUcIi", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_permvarhi512_mask, "V32sV32sV32sV32sUi","","avx512bw") +TARGET_BUILTIN(__builtin_ia32_permvardf512_mask, "V8dV8dV8LLiV8dUc","","avx512f") +TARGET_BUILTIN(__builtin_ia32_permvardi512_mask, "V8LLiV8LLiV8LLiV8LLiUc","","avx512f") +TARGET_BUILTIN(__builtin_ia32_permvarsf512_mask, "V16fV16fV16iV16fUs","","avx512f") +TARGET_BUILTIN(__builtin_ia32_permvarsi512_mask, "V16iV16iV16iV16iUs","","avx512f") +TARGET_BUILTIN(__builtin_ia32_permvarqi512_mask, "V64cV64cV64cV64cULLi","","avx512vbmi") +TARGET_BUILTIN(__builtin_ia32_permvarqi128_mask, "V16cV16cV16cV16cUs","","avx512vbmi,avx512vl") +TARGET_BUILTIN(__builtin_ia32_permvarqi256_mask, "V32cV32cV32cV32cUi","","avx512vbmi,avx512vl") +TARGET_BUILTIN(__builtin_ia32_permvarhi128_mask, "V8sV8sV8sV8sUc","","avx512bw,avx512vl") +TARGET_BUILTIN(__builtin_ia32_permvarhi256_mask, "V16sV16sV16sV16sUs","","avx512bw,avx512vl") +TARGET_BUILTIN(__builtin_ia32_permvardf256_mask, "V4dV4dV4LLiV4dUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_permvardi256_mask, "V4LLiV4LLiV4LLiV4LLiUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_permvarsf256_mask, "V8fV8fV8iV8fUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_permvarsi256_mask, "V8iV8iV8iV8iUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_fpclasspd128_mask, "UcV2dIiUc","","avx512dq,avx512vl") +TARGET_BUILTIN(__builtin_ia32_fpclasspd256_mask, "UcV4dIiUc","","avx512dq,avx512vl") +TARGET_BUILTIN(__builtin_ia32_fpclassps128_mask, "UcV4fIiUc","","avx512dq,avx512vl") +TARGET_BUILTIN(__builtin_ia32_fpclassps256_mask, "UcV8fIiUc","","avx512dq,avx512vl") +TARGET_BUILTIN(__builtin_ia32_fpclassps512_mask, "UsV16fIiUs","","avx512dq") +TARGET_BUILTIN(__builtin_ia32_fpclasspd512_mask, "UcV8dIiUc","","avx512dq") +TARGET_BUILTIN(__builtin_ia32_fpclasssd_mask, "UcV2dIiUc","","avx512dq") +TARGET_BUILTIN(__builtin_ia32_fpclassss_mask, "UcV4fIiUc","","avx512dq") +TARGET_BUILTIN(__builtin_ia32_kandhi, "UsUsUs","","avx512f") +TARGET_BUILTIN(__builtin_ia32_kandnhi, "UsUsUs","","avx512f") +TARGET_BUILTIN(__builtin_ia32_korhi, "UsUsUs","","avx512f") +TARGET_BUILTIN(__builtin_ia32_kortestchi, "iUsUs","","avx512f") +TARGET_BUILTIN(__builtin_ia32_kortestzhi, "iUsUs","","avx512f") +TARGET_BUILTIN(__builtin_ia32_kunpckhi, "UsUsUs","","avx512f") +TARGET_BUILTIN(__builtin_ia32_kxnorhi, "UsUsUs","","avx512f") +TARGET_BUILTIN(__builtin_ia32_kxorhi, "UsUsUs","","avx512f") +TARGET_BUILTIN(__builtin_ia32_movntdqa512, "V8LLiV8LLi*","","avx512f") +TARGET_BUILTIN(__builtin_ia32_palignr512_mask, "V64cV64cV64cIiV64cULLi","","avx512bw") +TARGET_BUILTIN(__builtin_ia32_palignr128_mask, "V16cV16cV16cIiV16cUs","","avx512bw,avx512vl") +TARGET_BUILTIN(__builtin_ia32_palignr256_mask, "V32cV32cV32cIiV32cUi","","avx512bw,avx512vl") +TARGET_BUILTIN(__builtin_ia32_dbpsadbw128_mask, "V8sV16cV16cIiV8sUc","","avx512bw,avx512vl") +TARGET_BUILTIN(__builtin_ia32_dbpsadbw256_mask, "V16sV32cV32cIiV16sUs","","avx512bw,avx512vl") +TARGET_BUILTIN(__builtin_ia32_dbpsadbw512_mask, "V32sV64cV64cIiV32sUi","","avx512bw") +TARGET_BUILTIN(__builtin_ia32_psadbw512, "V8LLiV64cV64c","","avx512bw") +TARGET_BUILTIN(__builtin_ia32_compressdf512_mask, "V8dV8dV8dUc","","avx512f") +TARGET_BUILTIN(__builtin_ia32_compressdi512_mask, "V8LLiV8LLiV8LLiUc","","avx512f") +TARGET_BUILTIN(__builtin_ia32_compresssf512_mask, "V16fV16fV16fUs","","avx512f") +TARGET_BUILTIN(__builtin_ia32_compresssi512_mask, "V16iV16iV16iUs","","avx512f") +TARGET_BUILTIN(__builtin_ia32_cmpsd_mask, "UcV2dV2dIiUcIi","","avx512f") +TARGET_BUILTIN(__builtin_ia32_cmpss_mask, "UcV4fV4fIiUcIi","","avx512f") +TARGET_BUILTIN(__builtin_ia32_expanddf512_mask, "V8dV8dV8dUc","","avx512f") +TARGET_BUILTIN(__builtin_ia32_expanddi512_mask, "V8LLiV8LLiV8LLiUc","","avx512f") +TARGET_BUILTIN(__builtin_ia32_expandloaddf512_mask, "V8dV8dC*V8dUc","","avx512f") +TARGET_BUILTIN(__builtin_ia32_expandloaddi512_mask, "V8LLiV8LLiC*V8LLiUc","","avx512f") +TARGET_BUILTIN(__builtin_ia32_expandloadsf512_mask, "V16fV16fC*V16fUs","","avx512f") +TARGET_BUILTIN(__builtin_ia32_expandloadsi512_mask, "V16iV16iC*V16iUs","","avx512f") +TARGET_BUILTIN(__builtin_ia32_expandsf512_mask, "V16fV16fV16fUs","","avx512f") +TARGET_BUILTIN(__builtin_ia32_expandsi512_mask, "V16iV16iV16iUs","","avx512f") +TARGET_BUILTIN(__builtin_ia32_cvtps2pd512_mask, "V8dV8fV8dUcIi","","avx512f") +TARGET_BUILTIN(__builtin_ia32_compressstoredf512_mask, "vV8d*V8dUc","","avx512f") +TARGET_BUILTIN(__builtin_ia32_compressstoredi512_mask, "vV8LLi*V8LLiUc","","avx512f") +TARGET_BUILTIN(__builtin_ia32_compressstoresf512_mask, "vV16f*V16fUs","","avx512f") +TARGET_BUILTIN(__builtin_ia32_compressstoresi512_mask, "vV16i*V16iUs","","avx512f") +TARGET_BUILTIN(__builtin_ia32_vcvtph2ps_mask, "V4fV8sV4fUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_vcvtph2ps256_mask, "V8fV8sV8fUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_vcvtps2ph_mask, "V8sV4fIiV8sUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_vcvtps2ph256_mask, "V8sV8fIiV8sUc","","avx512vl") +TARGET_BUILTIN(__builtin_ia32_cvtw2mask512, "UiV32s","","avx512bw") +TARGET_BUILTIN(__builtin_ia32_cvtw2mask128, "UcV8s","","avx512bw,avx512vl") +TARGET_BUILTIN(__builtin_ia32_cvtw2mask256, "UsV16s","","avx512bw,avx512vl") +TARGET_BUILTIN(__builtin_ia32_cvtsd2ss_round_mask, "V4fV4fV2dV4fUcIi","","avx512f") +TARGET_BUILTIN(__builtin_ia32_cvtsi2sd64, "V2dV2dLLiIi","","avx512f") +TARGET_BUILTIN(__builtin_ia32_cvtsi2ss32, "V4fV4fiIi","","avx512f") +TARGET_BUILTIN(__builtin_ia32_cvtsi2ss64, "V4fV4fLLiIi","","avx512f") +TARGET_BUILTIN(__builtin_ia32_cvtss2sd_round_mask, "V2dV2dV4fV2dUcIi","","avx512f") +TARGET_BUILTIN(__builtin_ia32_cvtusi2sd32, "V2dV2dUi","","avx512f") +TARGET_BUILTIN(__builtin_ia32_cvtusi2sd64, "V2dV2dULLiIi","","avx512f") +TARGET_BUILTIN(__builtin_ia32_cvtusi2ss32, "V4fV4fUiIi","","avx512f") +TARGET_BUILTIN(__builtin_ia32_cvtusi2ss64, "V4fV4fULLiIi","","avx512f") +TARGET_BUILTIN(__builtin_ia32_vpmultishiftqb512_mask, "V64cV64cV64cV64cULLi","","avx512vbmi") +TARGET_BUILTIN(__builtin_ia32_vpmultishiftqb128_mask, "V16cV16cV16cV16cUs","","avx512vbmi,avx512vl") +TARGET_BUILTIN(__builtin_ia32_vpmultishiftqb256_mask, "V32cV32cV32cV32cUi","","avx512vbmi,avx512vl") + +// generic select intrinsics +TARGET_BUILTIN(__builtin_ia32_selectb_128, "V16cUsV16cV16c", "", "") +TARGET_BUILTIN(__builtin_ia32_selectb_256, "V32cUiV32cV32c", "", "") +TARGET_BUILTIN(__builtin_ia32_selectb_512, "V64cULLiV64cV64c", "", "") +TARGET_BUILTIN(__builtin_ia32_selectw_128, "V8sUcV8sV8s", "", "") +TARGET_BUILTIN(__builtin_ia32_selectw_256, "V16sUsV16sV16s", "", "") +TARGET_BUILTIN(__builtin_ia32_selectw_512, "V32sUiV32sV32s", "", "") +TARGET_BUILTIN(__builtin_ia32_selectd_128, "V4iUcV4iV4i", "", "") +TARGET_BUILTIN(__builtin_ia32_selectd_256, "V8iUcV8iV8i", "", "") +TARGET_BUILTIN(__builtin_ia32_selectd_512, "V16iUsV16iV16i", "", "") +TARGET_BUILTIN(__builtin_ia32_selectq_128, "V2LLiUcV2LLiV2LLi", "", "") +TARGET_BUILTIN(__builtin_ia32_selectq_256, "V4LLiUcV4LLiV4LLi", "", "") +TARGET_BUILTIN(__builtin_ia32_selectq_512, "V8LLiUcV8LLiV8LLi", "", "") +TARGET_BUILTIN(__builtin_ia32_selectps_128, "V4fUcV4fV4f", "", "") +TARGET_BUILTIN(__builtin_ia32_selectps_256, "V8fUcV8fV8f", "", "") +TARGET_BUILTIN(__builtin_ia32_selectps_512, "V16fUsV16fV16f", "", "") +TARGET_BUILTIN(__builtin_ia32_selectpd_128, "V2dUcV2dV2d", "", "") +TARGET_BUILTIN(__builtin_ia32_selectpd_256, "V4dUcV4dV4d", "", "") +TARGET_BUILTIN(__builtin_ia32_selectpd_512, "V8dUcV8dV8d", "", "") + +// MONITORX/MWAITX +TARGET_BUILTIN(__builtin_ia32_monitorx, "vv*UiUi", "", "mwaitx") +TARGET_BUILTIN(__builtin_ia32_mwaitx, "vUiUiUi", "", "mwaitx") #undef BUILTIN #undef TARGET_BUILTIN diff --git a/include/clang/Basic/Cuda.h b/include/clang/Basic/Cuda.h new file mode 100644 index 0000000000000..ad1139b8c197e --- /dev/null +++ b/include/clang/Basic/Cuda.h @@ -0,0 +1,77 @@ +//===--- Cuda.h - Utilities for compiling CUDA code ------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_BASIC_CUDA_H +#define LLVM_CLANG_BASIC_CUDA_H + +namespace llvm { +class StringRef; +} // namespace llvm + +namespace clang { + +enum class CudaVersion { + UNKNOWN, + CUDA_70, + CUDA_75, + CUDA_80, +}; +const char *CudaVersionToString(CudaVersion V); + +// No string -> CudaVersion conversion function because there's no canonical +// spelling of the various CUDA versions. + +enum class CudaArch { + UNKNOWN, + SM_20, + SM_21, + SM_30, + SM_32, + SM_35, + SM_37, + SM_50, + SM_52, + SM_53, + SM_60, + SM_61, + SM_62, +}; +const char *CudaArchToString(CudaArch A); + +// The input should have the form "sm_20". +CudaArch StringToCudaArch(llvm::StringRef S); + +enum class CudaVirtualArch { + UNKNOWN, + COMPUTE_20, + COMPUTE_30, + COMPUTE_32, + COMPUTE_35, + COMPUTE_37, + COMPUTE_50, + COMPUTE_52, + COMPUTE_53, + COMPUTE_60, + COMPUTE_61, + COMPUTE_62, +}; +const char *CudaVirtualArchToString(CudaVirtualArch A); + +// The input should have the form "compute_20". +CudaVirtualArch StringToCudaVirtualArch(llvm::StringRef S); + +/// Get the compute_xx corresponding to an sm_yy. +CudaVirtualArch VirtualArchForCudaArch(CudaArch A); + +/// Get the earliest CudaVersion that supports the given CudaArch. +CudaVersion MinVersionForCudaArch(CudaArch A); + +} // namespace clang + +#endif diff --git a/include/clang/Basic/DebugInfoOptions.h b/include/clang/Basic/DebugInfoOptions.h new file mode 100644 index 0000000000000..e7ff4a662b630 --- /dev/null +++ b/include/clang/Basic/DebugInfoOptions.h @@ -0,0 +1,39 @@ +//===--- DebugInfoOptions.h - Debug Info Emission Types ---------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_BASIC_DEBUGINFOOPTIONS_H +#define LLVM_CLANG_BASIC_DEBUGINFOOPTIONS_H + +namespace clang { +namespace codegenoptions { + +enum DebugInfoKind { + NoDebugInfo, /// Don't generate debug info. + LocTrackingOnly, /// Emit location information but do not generate + /// debug info in the output. This is useful in + /// cases where the backend wants to track source + /// locations for instructions without actually + /// emitting debug info for them (e.g., when -Rpass + /// is used). + DebugLineTablesOnly, /// Emit only debug info necessary for generating + /// line number tables (-gline-tables-only). + LimitedDebugInfo, /// Limit generated debug info to reduce size + /// (-fno-standalone-debug). This emits + /// forward decls for types that could be + /// replaced with forward decls in the source + /// code. For dynamic C++ classes type info + /// is only emitted int the module that + /// contains the classe's vtable. + FullDebugInfo /// Generate complete debug info. +}; + +} // end namespace codegenoptions +} // end namespace clang + +#endif diff --git a/include/clang/Basic/DeclNodes.td b/include/clang/Basic/DeclNodes.td index 723ea547d8aaf..4f7bbc078d982 100644 --- a/include/clang/Basic/DeclNodes.td +++ b/include/clang/Basic/DeclNodes.td @@ -11,6 +11,8 @@ class DDecl<Decl base, bit abstract = 0> : Decl<abstract> { class DeclContext { } def TranslationUnit : Decl, DeclContext; +def PragmaComment : Decl; +def PragmaDetectMismatch : Decl; def ExternCContext : Decl, DeclContext; def Named : Decl<1>; def Namespace : DDecl<Named>, DeclContext; @@ -35,6 +37,7 @@ def Named : Decl<1>; def EnumConstant : DDecl<Value>; def UnresolvedUsingValue : DDecl<Value>; def IndirectField : DDecl<Value>; + def OMPDeclareReduction : DDecl<Value>, DeclContext; def Declarator : DDecl<Value, 1>; def Field : DDecl<Declarator>; def ObjCIvar : DDecl<Field>; @@ -51,6 +54,7 @@ def Named : Decl<1>; : DDecl<VarTemplateSpecialization>; def ImplicitParam : DDecl<Var>; def ParmVar : DDecl<Var>; + def OMPCapturedExpr : DDecl<Var>; def NonTypeTemplateParm : DDecl<Declarator>; def Template : DDecl<Named, 1>; def RedeclarableTemplate : DDecl<Template, 1>; @@ -62,6 +66,7 @@ def Named : Decl<1>; def BuiltinTemplate : DDecl<Template>; def Using : DDecl<Named>; def UsingShadow : DDecl<Named>; + def ConstructorUsingShadow : DDecl<UsingShadow>; def ObjCMethod : DDecl<Named>, DeclContext; def ObjCContainer : DDecl<Named, 1>, DeclContext; def ObjCCategory : DDecl<ObjCContainer>; diff --git a/include/clang/Basic/Diagnostic.h b/include/clang/Basic/Diagnostic.h index 1d6c19bc9539d..085faeae4834c 100644 --- a/include/clang/Basic/Diagnostic.h +++ b/include/clang/Basic/Diagnostic.h @@ -173,6 +173,7 @@ private: bool WarningsAsErrors; // Treat warnings like errors. bool EnableAllWarnings; // Enable all warnings. bool ErrorsAsFatal; // Treat errors like fatal errors. + bool FatalsAsError; // Treat fatal errors like errors. bool SuppressSystemWarnings; // Suppress warnings in system headers. bool SuppressAllDiagnostics; // Suppress all diagnostics. bool ElideType; // Elide common types of templates. @@ -455,6 +456,12 @@ public: void setErrorsAsFatal(bool Val) { ErrorsAsFatal = Val; } bool getErrorsAsFatal() const { return ErrorsAsFatal; } + /// \brief When set to true, any fatal error reported is made an error. + /// + /// This setting takes precedence over the setErrorsAsFatal setting above. + void setFatalsAsError(bool Val) { FatalsAsError = Val; } + bool getFatalsAsError() const { return FatalsAsError; } + /// \brief When set to true mask warnings that come from system headers. void setSuppressSystemWarnings(bool Val) { SuppressSystemWarnings = Val; } bool getSuppressSystemWarnings() const { return SuppressSystemWarnings; } @@ -1065,10 +1072,10 @@ inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, // so that we only match those arguments that are (statically) DeclContexts; // other arguments that derive from DeclContext (e.g., RecordDecls) will not // match. -template<typename T> -inline -typename std::enable_if<std::is_same<T, DeclContext>::value, - const DiagnosticBuilder &>::type +template <typename T> +inline typename std::enable_if< + std::is_same<typename std::remove_const<T>::type, DeclContext>::value, + const DiagnosticBuilder &>::type operator<<(const DiagnosticBuilder &DB, T *DC) { DB.AddTaggedVal(reinterpret_cast<intptr_t>(DC), DiagnosticsEngine::ak_declcontext); diff --git a/include/clang/Basic/DiagnosticASTKinds.td b/include/clang/Basic/DiagnosticASTKinds.td index 0b37030d7eeca..03ed8aa745977 100644 --- a/include/clang/Basic/DiagnosticASTKinds.td +++ b/include/clang/Basic/DiagnosticASTKinds.td @@ -26,6 +26,9 @@ def note_constexpr_lshift_discards : Note<"signed left shift discards bits">; def note_constexpr_invalid_function : Note< "%select{non-constexpr|undefined}0 %select{function|constructor}1 %2 cannot " "be used in a constant expression">; +def note_constexpr_invalid_inhctor : Note< + "constructor inherited from base class %0 cannot be used in a " + "constant expression; derived class cannot be implicitly initialized">; def note_constexpr_no_return : Note< "control reached end of constexpr function">; def note_constexpr_virtual_call : Note< @@ -141,6 +144,8 @@ def note_constexpr_calls_suppressed : Note< "(skipping %0 call%s0 in backtrace; use -fconstexpr-backtrace-limit=0 to " "see all)">; def note_constexpr_call_here : Note<"in call to '%0'">; +def note_constexpr_inherited_ctor_call_here : Note< + "in implicit initialization for inherited constructor of %0">; def note_constexpr_baa_insufficient_alignment : Note< "%select{alignment of|offset of the aligned pointer from}0 the base pointee " "object (%1 %plural{1:byte|:bytes}1) is %select{less than|not a multiple of}0 the " @@ -153,6 +158,12 @@ def warn_integer_constant_overflow : Warning< "overflow in expression; result is %0 with type %1">, InGroup<DiagGroup<"integer-overflow">>; +// This is a temporary diagnostic, and shall be removed once our +// implementation is complete, and like the preceding constexpr notes belongs +// in Sema. +def note_unimplemented_constexpr_lambda_feature_ast : Note< + "unimplemented constexpr lambda feature: %0 (coming soon!)">; + // inline asm related. let CategoryName = "Inline Assembly Issue" in { def err_asm_invalid_escape : Error< diff --git a/include/clang/Basic/DiagnosticCommonKinds.td b/include/clang/Basic/DiagnosticCommonKinds.td index ccc271a69f912..1c3bbfc118409 100644 --- a/include/clang/Basic/DiagnosticCommonKinds.td +++ b/include/clang/Basic/DiagnosticCommonKinds.td @@ -89,7 +89,7 @@ def err_module_unavailable : Error< def err_module_header_missing : Error< "%select{|umbrella }0header '%1' not found">; def err_module_lock_failure : Error< - "could not acquire lock file for module '%0'">, DefaultFatal; + "could not acquire lock file for module '%0': %1">, DefaultFatal; def err_module_lock_timeout : Error< "timed out waiting to acquire lock file for module '%0'">, DefaultFatal; def err_module_cycle : Error<"cyclic dependency in module '%0': %1">, @@ -157,6 +157,8 @@ def ext_old_implicitly_unsigned_long_cxx : ExtWarn< "this literal will %select{have type 'long long'|be ill-formed}0 " "in C++11 onwards">, InGroup<CXX11Compat>; +def ext_clang_enable_if : Extension<"'enable_if' is a clang extension">, + InGroup<GccCompat>; // SEH def err_seh_expected_handler : Error< @@ -178,6 +180,9 @@ def err_target_unknown_triple : Error< "unknown target triple '%0', please use -triple or -arch">; def err_target_unknown_cpu : Error<"unknown target CPU '%0'">; def err_target_unknown_abi : Error<"unknown target ABI '%0'">; +def err_target_unsupported_abi : Error<"ABI '%0' is not supported on CPU '%1'">; +def err_target_unsupported_abi_for_triple : Error< + "ABI '%0' is not supported for '%1'">; def err_target_unknown_fpmath : Error<"unknown FP unit '%0'">; def err_target_unsupported_fpmath : Error< "the '%0' unit is not supported with this instruction set">; diff --git a/include/clang/Basic/DiagnosticDriverKinds.td b/include/clang/Basic/DiagnosticDriverKinds.td index b04498f3188c0..6b8db6963daaa 100644 --- a/include/clang/Basic/DiagnosticDriverKinds.td +++ b/include/clang/Basic/DiagnosticDriverKinds.td @@ -23,10 +23,19 @@ def err_drv_unknown_language : Error<"language not recognized: '%0'">; def err_drv_invalid_arch_name : Error< "invalid arch name '%0'">; def err_drv_cuda_bad_gpu_arch : Error<"Unsupported CUDA gpu architecture: %0">; +def err_drv_no_cuda_installation : Error< + "cannot find CUDA installation. Provide its path via --cuda-path, or pass " + "-nocudainc to build without CUDA includes.">; +def err_drv_cuda_version_too_low : Error< + "GPU arch %1 requires CUDA version at least %3, but installation at %0 is %2. " + "Use --cuda-path to specify a different CUDA install, or pass " + "--no-cuda-version-check.">; def err_drv_invalid_thread_model_for_target : Error< "invalid thread model '%0' in '%1' for this target">; def err_drv_invalid_linker_name : Error< "invalid linker name in argument '%0'">; +def err_drv_invalid_pgo_instrumentor : Error< + "invalid PGO instrumentor in argument '%0'">; def err_drv_invalid_rtlib_name : Error< "invalid runtime library name in argument '%0'">; def err_drv_unsupported_rtlib_for_platform : Error< @@ -93,6 +102,23 @@ def err_target_unsupported_arch def err_drv_I_dash_not_supported : Error< "'%0' not supported, please use -iquote instead">; def err_drv_unknown_argument : Error<"unknown argument: '%0'">; +def warn_drv_unknown_argument_clang_cl : Warning< + "unknown argument ignored in clang-cl: '%0'">, + InGroup<UnknownArgument>; + +def warn_drv_ycyu_no_arg_clang_cl : Warning< + "support for '%0' without a filename not implemented yet; flag ignored">, + InGroup<ClangClPch>; +def warn_drv_ycyu_different_arg_clang_cl : Warning< + "support for '/Yc' and '/Yu' with different filenames not implemented yet; flags ignored">, + InGroup<ClangClPch>; +def warn_drv_ycyu_no_fi_arg_clang_cl : Warning< + "support for '%0' without a corresponding /FI flag not implemented yet; flag ignored">, + InGroup<ClangClPch>; +def warn_drv_yc_multiple_inputs_clang_cl : Warning< + "support for '/Yc' with more than one source file not implemented yet; flag ignored">, + InGroup<ClangClPch>; + def err_drv_invalid_value : Error<"invalid value '%1' in '%0'">; def err_drv_invalid_int_value : Error<"invalid integral value '%1' in '%0'">; def err_drv_invalid_remap_file : Error< @@ -127,6 +153,10 @@ def err_drv_no_neon_modifier : Error<"[no]neon is not accepted as modifier, plea def err_drv_invalid_omp_target : Error<"OpenMP target is invalid: '%0'">; def err_drv_omp_host_ir_file_not_found : Error< "The provided host compiler IR file '%0' is required to generate code for OpenMP target regions but cannot be found.">; +def err_drv_omp_host_target_not_supported : Error< + "The target '%0' is not a supported OpenMP host target.">; +def err_drv_bitcode_unsupported_on_toolchain : Error< + "-fembed-bitcode is not supported on versions of iOS prior to 6.0">; def warn_O4_is_O3 : Warning<"-O4 is equivalent to -O3">, InGroup<Deprecated>; def warn_drv_lto_libpath : Warning<"libLTO.dylib relative to clang installed dir not found; using 'ld' default search path instead">, @@ -172,6 +202,8 @@ def warn_drv_pch_not_first_include : Warning< "precompiled header '%0' was ignored because '%1' is not first '-include'">; def warn_missing_sysroot : Warning<"no such sysroot directory: '%0'">, InGroup<DiagGroup<"missing-sysroot">>; +def warn_incompatible_sysroot : Warning<"using sysroot for '%0' but targeting '%1'">, + InGroup<DiagGroup<"incompatible-sysroot">>; def warn_debug_compression_unavailable : Warning<"cannot compress debug sections (zlib not installed)">, InGroup<DiagGroup<"debug-compression-unavailable">>; def warn_drv_enabling_rtti_with_exceptions : Warning< @@ -210,6 +242,9 @@ def warn_target_unsupported_nan2008 : Warning< def warn_target_unsupported_nanlegacy : Warning< "ignoring '-mnan=legacy' option because the '%0' architecture does not support it">, InGroup<UnsupportedNan>; +def warn_target_unsupported_compact_branches : Warning< + "ignoring '-mcompact-branches=' option because the '%0' architecture does not" + " support it">, InGroup<UnsupportedCB>; def warn_drv_unable_to_find_directory_expected : Warning< "unable to find %0 directory, expected to be in '%1'">, @@ -220,7 +255,7 @@ def warn_drv_ps4_force_pic : Warning< InGroup<OptionIgnored>; def warn_drv_ps4_sdk_dir : Warning< - "environment variable SCE_PS4_SDK_DIR is set, but points to invalid or nonexistent directory '%0'">, + "environment variable SCE_ORBIS_SDK_DIR is set, but points to invalid or nonexistent directory '%0'">, InGroup<InvalidOrNonExistentDirectory>; def err_drv_unsupported_linker : Error<"unsupported value '%0' for -linker option">; diff --git a/include/clang/Basic/DiagnosticFrontendKinds.td b/include/clang/Basic/DiagnosticFrontendKinds.td index 033834bc505da..2aa8f103500dc 100644 --- a/include/clang/Basic/DiagnosticFrontendKinds.td +++ b/include/clang/Basic/DiagnosticFrontendKinds.td @@ -58,8 +58,10 @@ def remark_fe_backend_optimization_remark_analysis_aliasing : Remark<"%0; " BackendInfo, InGroup<BackendOptimizationRemarkAnalysis>; def warn_fe_backend_optimization_failure : Warning<"%0">, BackendInfo, InGroup<BackendOptimizationFailure>, DefaultWarn; -def note_fe_backend_optimization_remark_invalid_loc : Note<"could " - "not determine the original source location for %0:%1:%2">; +def note_fe_backend_invalid_loc : Note<"could " + "not determine the original source location for %0:%1:%2">, BackendInfo; + +def err_fe_backend_unsupported : Error<"%0">, BackendInfo; def remark_sanitize_address_insert_extra_padding_accepted : Remark< "-fsanitize-address-field-padding applied to %0">, ShowInSystemHeader, @@ -208,12 +210,11 @@ def err_test_module_file_extension_version : Error< "test module file extension '%0' has different version (%1.%2) than expected " "(%3.%4)">; -def err_conflicting_module_names : Error< - "conflicting module names specified: '-fmodule-name=%0' and " - "'-fmodule-implementation-of %1'">; - def err_missing_vfs_overlay_file : Error< "virtual filesystem overlay file '%0' not found">, DefaultFatal; def err_invalid_vfs_overlay : Error< "invalid virtual filesystem overlay file '%0'">, DefaultFatal; -} + +def warn_option_invalid_ocl_version : Warning< + "OpenCL version %0 does not support the option '%1'">, InGroup<Deprecated>; +}
\ No newline at end of file diff --git a/include/clang/Basic/DiagnosticGroups.td b/include/clang/Basic/DiagnosticGroups.td index 2e4e57b63b8e7..72dfedbbaef03 100644 --- a/include/clang/Basic/DiagnosticGroups.td +++ b/include/clang/Basic/DiagnosticGroups.td @@ -46,10 +46,17 @@ def BoolConversion : DiagGroup<"bool-conversion", [PointerBoolConversion, UndefinedBoolConversion]>; def IntConversion : DiagGroup<"int-conversion">; def EnumConversion : DiagGroup<"enum-conversion">; -def FloatConversion : DiagGroup<"float-conversion">; + +def FloatOverflowConversion : DiagGroup<"float-overflow-conversion">; +def FloatZeroConversion : DiagGroup<"float-zero-conversion">; +def FloatConversion : + DiagGroup<"float-conversion", [FloatOverflowConversion, + FloatZeroConversion]>; + def DoublePromotion : DiagGroup<"double-promotion">; def EnumTooLarge : DiagGroup<"enum-too-large">; def UnsupportedNan : DiagGroup<"unsupported-nan">; +def UnsupportedCB : DiagGroup<"unsupported-cb">; def NonLiteralNullConversion : DiagGroup<"non-literal-null-conversion">; def NullConversion : DiagGroup<"null-conversion">; def ImplicitConversionFloatingPointToBool : @@ -75,6 +82,8 @@ def : DiagGroup<"ctor-dtor-privacy">; def GNUDesignator : DiagGroup<"gnu-designator">; def GNUStringLiteralOperatorTemplate : DiagGroup<"gnu-string-literal-operator-template">; +def UndefinedVarTemplate : DiagGroup<"undefined-var-template">; +def UndefinedFuncTemplate : DiagGroup<"undefined-func-template">; def DeleteIncomplete : DiagGroup<"delete-incomplete">; def DeleteNonVirtualDtor : DiagGroup<"delete-non-virtual-dtor">; @@ -87,6 +96,7 @@ def DeprecatedAttributes : DiagGroup<"deprecated-attributes">; def DeprecatedDeclarations : DiagGroup<"deprecated-declarations">; def UnavailableDeclarations : DiagGroup<"unavailable-declarations">; def PartialAvailability : DiagGroup<"partial-availability">; +def UnguardedAvailability : DiagGroup<"unguarded-availability">; def DeprecatedImplementations :DiagGroup<"deprecated-implementations">; def DeprecatedIncrementBool : DiagGroup<"deprecated-increment-bool">; def DeprecatedRegister : DiagGroup<"deprecated-register">; @@ -204,6 +214,7 @@ def OverloadedShiftOpParentheses: DiagGroup<"overloaded-shift-op-parentheses">; def DanglingElse: DiagGroup<"dangling-else">; def DanglingField : DiagGroup<"dangling-field">; def DistributedObjectModifiers : DiagGroup<"distributed-object-modifiers">; +def ExpansionToDefined : DiagGroup<"expansion-to-defined">; def FlagEnum : DiagGroup<"flag-enum">; def IncrementBool : DiagGroup<"increment-bool", [DeprecatedIncrementBool]>; def InfiniteRecursion : DiagGroup<"infinite-recursion">; @@ -283,8 +294,6 @@ def : DiagGroup<"overflow">; def ForwardClassReceiver : DiagGroup<"receiver-forward-class">; def MethodAccess : DiagGroup<"objc-method-access">; def ObjCReceiver : DiagGroup<"receiver-expr">; -// FIXME: Remove this when Xcode removes the warning setting. -def : DiagGroup<"receiver-is-weak">; def OperatorNewReturnsNull : DiagGroup<"new-returns-null">; def OverlengthStrings : DiagGroup<"overlength-strings">; def OverloadedVirtual : DiagGroup<"overloaded-virtual">; @@ -330,7 +339,16 @@ def SelfMove : DiagGroup<"self-move">; def SemiBeforeMethodBody : DiagGroup<"semicolon-before-method-body">; def Sentinel : DiagGroup<"sentinel">; def MissingMethodReturnType : DiagGroup<"missing-method-return-type">; -def Shadow : DiagGroup<"shadow">; + +def ShadowFieldInConstructorModified : DiagGroup<"shadow-field-in-constructor-modified">; +def ShadowFieldInConstructor : DiagGroup<"shadow-field-in-constructor", + [ShadowFieldInConstructorModified]>; + +// -Wshadow-all is a catch-all for all shadowing. -Wshadow is just the +// shadowing that we think is unsafe. +def Shadow : DiagGroup<"shadow", [ShadowFieldInConstructorModified]>; +def ShadowAll : DiagGroup<"shadow-all", [Shadow, ShadowFieldInConstructor]>; + def Shorten64To32 : DiagGroup<"shorten-64-to-32">; def : DiagGroup<"sign-promo">; def SignCompare : DiagGroup<"sign-compare">; @@ -756,6 +774,7 @@ def MicrosoftEnumValue : DiagGroup<"microsoft-enum-value">; def MicrosoftDefaultArgRedefinition : DiagGroup<"microsoft-default-arg-redefinition">; def MicrosoftTemplate : DiagGroup<"microsoft-template">; +def MicrosoftInconsistentDllImport : DiagGroup<"inconsistent-dllimport">; def MicrosoftRedeclareStatic : DiagGroup<"microsoft-redeclare-static">; def MicrosoftEnumForwardReference : DiagGroup<"microsoft-enum-forward-reference">; @@ -782,7 +801,10 @@ def Microsoft : DiagGroup<"microsoft", MicrosoftRedeclareStatic, MicrosoftEnumForwardReference, MicrosoftGoto, MicrosoftFlexibleArray, MicrosoftExtraQualification, MicrosoftCast, MicrosoftConstInit, MicrosoftVoidPseudoDtor, MicrosoftAnonTag, - MicrosoftCommentPaste, MicrosoftEndOfFile]>; + MicrosoftCommentPaste, MicrosoftEndOfFile, + MicrosoftInconsistentDllImport]>; + +def ClangClPch : DiagGroup<"clang-cl-pch">; def ObjCNonUnifiedException : DiagGroup<"objc-nonunified-exceptions">; @@ -816,6 +838,7 @@ def ASM : DiagGroup<"asm", [ def SourceUsesOpenMP : DiagGroup<"source-uses-openmp">; def OpenMPClauses : DiagGroup<"openmp-clauses">; def OpenMPLoopForm : DiagGroup<"openmp-loop-form">; +def OpenMPTarget : DiagGroup<"openmp-target">; // Backend warnings. def BackendInlineAsm : DiagGroup<"inline-asm">; @@ -847,3 +870,5 @@ def FutureCompat : DiagGroup<"future-compat">; def InvalidOrNonExistentDirectory : DiagGroup<"invalid-or-nonexistent-directory">; def OptionIgnored : DiagGroup<"option-ignored">; + +def UnknownArgument : DiagGroup<"unknown-argument">; diff --git a/include/clang/Basic/DiagnosticIDs.h b/include/clang/Basic/DiagnosticIDs.h index 312b71f4064d5..fcd04a0be187d 100644 --- a/include/clang/Basic/DiagnosticIDs.h +++ b/include/clang/Basic/DiagnosticIDs.h @@ -36,7 +36,7 @@ namespace clang { DIAG_START_AST = DIAG_START_PARSE + 500, DIAG_START_COMMENT = DIAG_START_AST + 110, DIAG_START_SEMA = DIAG_START_COMMENT + 100, - DIAG_START_ANALYSIS = DIAG_START_SEMA + 3000, + DIAG_START_ANALYSIS = DIAG_START_SEMA + 3500, DIAG_UPPER_LIMIT = DIAG_START_ANALYSIS + 100 }; diff --git a/include/clang/Basic/DiagnosticLexKinds.td b/include/clang/Basic/DiagnosticLexKinds.td index 2fc9664f49e55..604d51db1ffec 100644 --- a/include/clang/Basic/DiagnosticLexKinds.td +++ b/include/clang/Basic/DiagnosticLexKinds.td @@ -175,10 +175,17 @@ def err_multichar_utf_character_literal : Error< def err_exponent_has_no_digits : Error<"exponent has no digits">; def ext_imaginary_constant : Extension< "imaginary constants are a GNU extension">, InGroup<GNUImaginaryConstant>; -def err_hexconstant_requires: Error< - "hexadecimal floating constants require %select{an exponent|a significand}0">; -def ext_hexconstant_invalid : Extension< +def err_hex_constant_requires : Error< + "hexadecimal floating %select{constant|literal}0 requires " + "%select{an exponent|a significand}1">; +def ext_hex_constant_invalid : Extension< "hexadecimal floating constants are a C99 feature">, InGroup<C99>; +def ext_hex_literal_invalid : Extension< + "hexadecimal floating literals are a C++1z feature">, InGroup<CXX1z>; +def warn_cxx1z_hex_literal : Warning< + "hexidecimal floating literals are incompatible with " + "C++ standards before C++1z">, + InGroup<CXXPre1zCompatPedantic>, DefaultIgnore; def ext_binary_literal : Extension< "binary integer literals are a GNU extension">, InGroup<GNUBinaryLiteral>; def ext_binary_literal_cxx14 : Extension< @@ -267,6 +274,14 @@ def ext_missing_whitespace_after_macro_name : ExtWarn< "whitespace required after macro name">; def warn_missing_whitespace_after_macro_name : Warning< "whitespace recommended after macro name">; + +class NonportablePath : Warning< + "non-portable path to file '%0'; specified path differs in case from file" + " name on disk">; +def pp_nonportable_path : NonportablePath, + InGroup<DiagGroup<"nonportable-include-path">>; +def pp_nonportable_system_path : NonportablePath, DefaultIgnore, + InGroup<DiagGroup<"nonportable-system-include-path">>; def pp_pragma_once_in_main_file : Warning<"#pragma once in main file">, InGroup<DiagGroup<"pragma-once-outside-header">>; @@ -380,7 +395,7 @@ def err_pp_expected_comma_in_arg_list : Error< def err_pp_duplicate_name_in_arg_list : Error< "duplicate macro parameter name %0">; def err_pp_stringize_not_parameter : Error< - "'#' is not followed by a macro parameter">; + "'%select{#|#@}0' is not followed by a macro parameter">; def err_pp_malformed_ident : Error<"invalid #ident directive">; def err_pp_unterminated_conditional : Error< "unterminated conditional directive">; @@ -394,6 +409,7 @@ def err_pp_expected_rparen : Error<"expected ')' in preprocessor expression">; def err_pp_expected_eol : Error< "expected end of line in preprocessor expression">; def err_pp_expected_after : Error<"missing %1 after %0">; +def err_pp_nested_paren : Error<"nested parentheses not permitted in %0">; def err_pp_colon_without_question : Error<"':' without preceding '?'">; def err_pp_division_by_zero : Error< "division by zero in preprocessor expression">; @@ -401,6 +417,8 @@ def err_pp_remainder_by_zero : Error< "remainder by zero in preprocessor expression">; def err_pp_expr_bad_token_binop : Error< "token is not a valid binary operator in a preprocessor subexpression">; +def err_pp_expr_bad_token_lparen : Error< + "function-like macro %0 is not defined">; def err_pp_expr_bad_token_start_expr : Error< "invalid token at start of a preprocessor expression">; def err_pp_invalid_poison : Error<"can only poison identifier tokens">; @@ -409,8 +427,6 @@ def err_pp_used_poisoned_id : Error<"attempt to use a poisoned identifier">; def err_feature_check_malformed : Error< "builtin feature check macro requires a parenthesized identifier">; -def err_warning_check_malformed : Error< - "builtin warning check macro requires a parenthesized string">; def warn_has_warning_invalid_option : ExtWarn<"__has_warning expected option name (e.g. \"-Wundef\")">, InGroup<MalformedWarningCheck>; @@ -658,6 +674,13 @@ def warn_header_guard : Warning< def note_header_guard : Note< "%0 is defined here; did you mean %1?">; +def warn_defined_in_object_type_macro : Warning< + "macro expansion producing 'defined' has undefined behavior">, + InGroup<ExpansionToDefined>; +def warn_defined_in_function_type_macro : Extension< + "macro expansion producing 'defined' has undefined behavior">, + InGroup<ExpansionToDefined>; + let CategoryName = "Nullability Issue" in { def err_pp_assume_nonnull_syntax : Error<"expected 'begin' or 'end'">; diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td index f8dee2f98cca4..e5c64681e48f2 100644 --- a/include/clang/Basic/DiagnosticParseKinds.td +++ b/include/clang/Basic/DiagnosticParseKinds.td @@ -27,6 +27,8 @@ def err_msasm_unable_to_create_target : Error< "MS-style inline assembly is not available: %0">; def err_gnu_inline_asm_disabled : Error< "GNU-style inline assembly is disabled">; +def err_asm_goto_not_supported_yet : Error< + "'asm goto' constructs are not supported yet">; } let CategoryName = "Parse Issue" in { @@ -510,6 +512,11 @@ def err_function_is_not_record : Error< "unexpected %0 in function call; perhaps remove the %0?">; def err_super_in_using_declaration : Error< "'__super' cannot be used with a using declaration">; +def ext_constexpr_if : ExtWarn< + "constexpr if is a C++1z extension">, InGroup<CXX1z>; +def warn_cxx14_compat_constexpr_if : Warning< + "constexpr if is incompatible with C++ standards before C++1z">, + DefaultIgnore, InGroup<CXXPre1zCompat>; // C++ derived classes def err_dup_virtual : Error<"duplicate 'virtual' in base specifier">; @@ -553,6 +560,14 @@ def err_cxx11_attribute_forbids_ellipsis : Error< "attribute '%0' cannot be used as an attribute pack">; def err_cxx11_attribute_repeated : Error< "attribute %0 cannot appear multiple times in an attribute specifier">; +def warn_cxx14_compat_using_attribute_ns : Warning< + "default scope specifier for attributes is incompatible with C++ standards " + "before C++1z">, InGroup<CXXPre1zCompat>, DefaultIgnore; +def ext_using_attribute_ns : ExtWarn< + "default scope specifier for attributes is a C++1z extension">, + InGroup<CXX1z>; +def err_using_attribute_ns_conflict : Error< + "attribute with scope specifier cannot follow default scope specifier">; def err_attributes_not_allowed : Error<"an attribute list cannot appear here">; def err_l_square_l_square_not_attribute : Error< "C++11 only allows consecutive left square brackets when " @@ -765,7 +780,19 @@ def warn_cxx98_compat_lambda : Warning< InGroup<CXX98Compat>, DefaultIgnore; def err_lambda_missing_parens : Error< "lambda requires '()' before %select{'mutable'|return type|" - "attribute specifier}0">; + "attribute specifier|'constexpr'}0">; +def err_lambda_decl_specifier_repeated : Error< + "%select{'mutable'|'constexpr'}0 cannot appear multiple times in a lambda declarator">; +// C++1z lambda expressions
+def err_expected_star_this_capture : Error< + "expected 'this' following '*' in lambda capture list">; + +// C++1z constexpr lambda expressions +def warn_cxx14_compat_constexpr_on_lambda : Warning< + "constexpr on lambda expressions is incompatible with C++ standards before C++1z">, + InGroup<CXXPre1zCompat>, DefaultIgnore; +def ext_constexpr_on_lambda_cxx1z : ExtWarn< + "'constexpr' on lambda expressions is a C++1z extension">, InGroup<CXX1z>; // Availability attribute def err_expected_version : Error< @@ -776,7 +803,7 @@ def warn_expected_consistent_version_separator : Warning< def err_zero_version : Error< "version number must have non-zero major, minor, or sub-minor version">; def err_availability_expected_platform : Error< - "expected a platform name, e.g., 'macosx'">; + "expected a platform name, e.g., 'macos'">; // objc_bridge_related attribute def err_objcbridge_related_expected_related_class : Error< @@ -796,6 +823,21 @@ def warn_availability_and_unavailable : Warning< "'unavailable' availability overrides all other availability information">, InGroup<Availability>; +// @available(...) +def err_avail_query_expected_condition : Error< + "expected an availability condition here">; +def err_avail_query_expected_platform_name : Error< + "expected a platform name here">; + +def err_avail_query_unrecognized_platform_name : Error< + "unrecognized platform name %0">; +def err_availability_query_wildcard_required: Error< + "must handle potential future platforms with '*'">; +def err_availability_query_repeated_platform: Error< + "version for '%0' already specified">; +def err_availability_query_repeated_star : Error< + "'*' query has already been specified">; + // Type safety attributes def err_type_safety_unknown_flag : Error< "invalid comparison flag %0; use 'layout_compatible' or 'must_be_null'">; @@ -902,6 +944,9 @@ def err_pragma_optimize_invalid_argument : Error< def err_pragma_optimize_extra_argument : Error< "unexpected extra argument '%0' to '#pragma clang optimize'">; +def err_opencl_unroll_hint_on_non_loop : Error< + "OpenCL only supports 'opencl_unroll_hint' attribute on for, while, and do statements">; + // OpenCL EXTENSION pragma (OpenCL 1.1 [9.1]) def warn_pragma_expected_colon : Warning< "missing ':' after %0 - ignoring">, InGroup<IgnoredPragmas>; @@ -909,10 +954,16 @@ def warn_pragma_expected_enable_disable : Warning< "expected 'enable' or 'disable' - ignoring">, InGroup<IgnoredPragmas>; def warn_pragma_unknown_extension : Warning< "unknown OpenCL extension %0 - ignoring">, InGroup<IgnoredPragmas>; +def warn_pragma_unsupported_extension : Warning< + "unsupported OpenCL extension %0 - ignoring">, InGroup<IgnoredPragmas>; +def warn_pragma_extension_is_core : Warning< + "OpenCL extension %0 is core feature or supported optional core feature - ignoring">, InGroup<DiagGroup<"pedantic-core-features">>, DefaultIgnore; -// OpenCL error +// OpenCL errors. def err_opencl_taking_function_address_parser : Error< "taking address of function is not allowed">; +def err_opencl_logical_exclusive_or : Error< + "^^ is a reserved operator in OpenCL">; // OpenMP support. def warn_pragma_omp_ignored : Warning< @@ -934,22 +985,32 @@ def err_omp_immediate_directive : Error< "'#pragma omp %0' %select{|with '%2' clause }1cannot be an immediate substatement">; def err_omp_expected_identifier_for_critical : Error< "expected identifier specifying the name of the 'omp critical' directive">; +def err_omp_expected_reduction_identifier : Error< + "expected identifier or one of the following operators: '+', '-', '*', '&', '|', '^', '&&', or '||'">; +def err_omp_decl_in_declare_simd : Error< + "function declaration is expected after 'declare simd' directive">; def err_omp_unknown_map_type : Error< "incorrect map type, expected one of 'to', 'from', 'tofrom', 'alloc', 'release', or 'delete'">; def err_omp_unknown_map_type_modifier : Error< "incorrect map type modifier, expected 'always'">; def err_omp_map_type_missing : Error< "missing map type">; +def err_omp_declare_simd_inbranch_notinbranch : Error< + "unexpected '%0' clause, '%1' is specified already">; +def err_expected_end_declare_target : Error< + "expected '#pragma omp end declare target'">; +def err_omp_declare_target_unexpected_clause: Error< + "unexpected '%0' clause, only 'to' or 'link' clauses expected">; // Pragma loop support. def err_pragma_loop_missing_argument : Error< "missing argument; expected %select{an integer value|" - "'enable', %select{'assume_safety'|'full'}1 or 'disable'}0">; + "'enable'%select{|, 'full'}1%select{|, 'assume_safety'}2 or 'disable'}0">; def err_pragma_loop_invalid_option : Error< "%select{invalid|missing}0 option%select{ %1|}0; expected vectorize, " - "vectorize_width, interleave, interleave_count, unroll, or unroll_count">; + "vectorize_width, interleave, interleave_count, unroll, unroll_count, or distribute">; def err_pragma_invalid_keyword : Error< - "invalid argument; expected 'enable', %select{'assume_safety'|'full'}0 or 'disable'">; + "invalid argument; expected 'enable'%select{|, 'full'}0%select{|, 'assume_safety'}1 or 'disable'">; // Pragma unroll support. def warn_pragma_unroll_cuda_value_in_parens : Warning< diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 6ba482c78e4a3..1203fe765b524 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -30,23 +30,6 @@ def warn_redundant_loop_iteration : Warning< InGroup<ForLoopAnalysis>, DefaultIgnore; def note_loop_iteration_here : Note<"%select{decremented|incremented}0 here">; -def warn_for_range_const_reference_copy : Warning< - "loop variable %0 " - "%diff{has type $ but is initialized with type $" - "| is initialized with a value of a different type}1,2 resulting in a copy">, - InGroup<RangeLoopAnalysis>, DefaultIgnore; -def note_use_type_or_non_reference : Note< - "use non-reference type %0 to keep the copy or type %1 to prevent copying">; -def warn_for_range_variable_always_copy : Warning< - "loop variable %0 is always a copy because the range of type %1 does not " - "return a reference">, - InGroup<RangeLoopAnalysis>, DefaultIgnore; -def note_use_non_reference_type : Note<"use non-reference type %0">; -def warn_for_range_copy : Warning< - "loop variable %0 of type %1 creates a copy from type %2">, - InGroup<RangeLoopAnalysis>, DefaultIgnore; -def note_use_reference_type : Note<"use reference type %0 to prevent copying">; - def warn_duplicate_enum_values : Warning< "element %0 has been implicitly assigned %1 which another element has " "been assigned">, InGroup<DiagGroup<"duplicate-enum">>, DefaultIgnore; @@ -74,6 +57,10 @@ def warn_infinite_recursive_function : Warning< "all paths through this function will call itself">, InGroup<InfiniteRecursion>, DefaultIgnore; +def warn_comma_operator : Warning<"possible misuse of comma operator here">, + InGroup<DiagGroup<"comma">>, DefaultIgnore; +def note_cast_to_void : Note<"cast expression to void to silence warning">; + // Constant expressions def err_expr_not_ice : Error< "expression is not an %select{integer|integral}0 constant expression">; @@ -88,10 +75,12 @@ def err_typecheck_converted_constant_expression_indirect : Error< "conversion from %0 to %1 in converted constant expression would " "bind reference to a temporary">; def err_expr_not_cce : Error< - "%select{case value|enumerator value|non-type template argument|array size}0 " + "%select{case value|enumerator value|non-type template argument|" + "array size|constexpr if condition}0 " "is not a constant expression">; def ext_cce_narrowing : ExtWarn< - "%select{case value|enumerator value|non-type template argument|array size}0 " + "%select{case value|enumerator value|non-type template argument|" + "array size|constexpr if condition}0 " "%select{cannot be narrowed from type %2 to %3|" "evaluates to %2, which cannot be narrowed to type %3}1">, InGroup<CXX11Narrowing>, DefaultError, SFINAEFailure; @@ -124,13 +113,14 @@ def warn_float_underflow : Warning< InGroup<LiteralRange>; def warn_double_const_requires_fp64 : Warning< "double precision constant requires cl_khr_fp64, casting to single precision">; +def err_half_const_requires_fp16 : Error< + "half precision constant requires cl_khr_fp16">; // C99 variable-length arrays def ext_vla : Extension<"variable length arrays are a C99 feature">, InGroup<VLAExtension>; def warn_vla_used : Warning<"variable length array used">, InGroup<VLA>, DefaultIgnore; -def err_vla_non_pod : Error<"variable length array of non-POD element type %0">; def err_vla_in_sfinae : Error< "variable length array cannot be formed during template argument deduction">; def err_array_star_in_function_definition : Error< @@ -254,6 +244,13 @@ def err_bad_variable_name : Error< def err_bad_parameter_name : Error< "%0 cannot be the name of a parameter">; def err_parameter_name_omitted : Error<"parameter name omitted">; +def err_anyx86_interrupt_attribute : Error< + "%select{x86|x86-64}0 'interrupt' attribute only applies to functions that " + "have %select{a 'void' return type|" + "only a pointer parameter optionally followed by an integer parameter|" + "a pointer as the first parameter|a %2 type as the second parameter}1">; +def err_anyx86_interrupt_called : Error< + "interrupt service routine cannot be called directly">; def warn_mips_interrupt_attribute : Warning< "MIPS 'interrupt' attribute only applies to functions that have " "%select{no parameters|a 'void' return type}0">, @@ -342,12 +339,16 @@ def err_language_linkage_spec_not_ascii : Error< def warn_use_out_of_scope_declaration : Warning< "use of out-of-scope declaration of %0">; def err_inline_non_function : Error< - "'inline' can only appear on functions">; + "'inline' can only appear on functions%select{| and non-local variables}0">; def err_noreturn_non_function : Error< "'_Noreturn' can only appear on functions">; def warn_qual_return_type : Warning< "'%0' type qualifier%s1 on return type %plural{1:has|:have}1 no effect">, InGroup<IgnoredQualifiers>, DefaultIgnore; +def warn_deprecated_redundant_constexpr_static_def : Warning< + "out-of-line definition of constexpr static data member is redundant " + "in C++17 and is deprecated">, + InGroup<Deprecated>, DefaultIgnore; def warn_decl_shadow : Warning<"declaration shadows a %select{" @@ -356,6 +357,14 @@ def warn_decl_shadow : "static data member of %2|" "field of %2}1">, InGroup<Shadow>, DefaultIgnore; +def warn_ctor_parm_shadows_field: + Warning<"constructor parameter %0 shadows the field %1 of %2">, + InGroup<ShadowFieldInConstructor>, DefaultIgnore; +def warn_modifying_shadowing_decl : + Warning<"modifying constructor parameter %0 that shadows a " + "field of %1">, + InGroup<ShadowFieldInConstructorModified>, DefaultIgnore; + // C++ using declarations def err_using_requires_qualname : Error< @@ -372,27 +381,19 @@ def err_using_decl_nested_name_specifier_is_not_base_class : Error< "using declaration refers into '%0', which is not a base class of %1">; def err_using_decl_constructor_not_in_direct_base : Error< "%0 is not a direct base of %1, cannot inherit constructors">; -def err_using_decl_constructor_conflict : Error< - "cannot inherit constructor, already inherited constructor with " - "the same signature">; -def note_using_decl_constructor_conflict_current_ctor : Note< - "conflicting constructor">; -def note_using_decl_constructor_conflict_previous_ctor : Note< - "previous constructor">; -def note_using_decl_constructor_conflict_previous_using : Note< - "previously inherited here">; -def warn_using_decl_constructor_ellipsis : Warning< - "inheriting constructor does not inherit ellipsis">, - InGroup<DiagGroup<"inherited-variadic-ctor">>; -def note_using_decl_constructor_ellipsis : Note< - "constructor declared with ellipsis here">; def err_using_decl_can_not_refer_to_class_member : Error< "using declaration cannot refer to class member">; +def err_ambiguous_inherited_constructor : Error< + "constructor of %0 inherited from multiple base class subobjects">; +def note_ambiguous_inherited_constructor_using : Note< + "inherited from base class %0 here">; def note_using_decl_class_member_workaround : Note< - "use %select{an alias declaration|a typedef declaration|a reference}0 " - "instead">; + "use %select{an alias declaration|a typedef declaration|a reference|" + "a const variable|a constexpr variable}0 instead">; def err_using_decl_can_not_refer_to_namespace : Error< - "using declaration cannot refer to namespace">; + "using declaration cannot refer to a namespace">; +def err_using_decl_can_not_refer_to_scoped_enum : Error< + "using declaration cannot refer to a scoped enumerator">; def err_using_decl_constructor : Error< "using declaration cannot refer to a constructor">; def warn_cxx98_compat_using_decl_constructor : Warning< @@ -404,7 +405,7 @@ def err_using_decl_template_id : Error< "using declaration cannot refer to a template specialization">; def note_using_decl_target : Note<"target of using declaration">; def note_using_decl_conflict : Note<"conflicting declaration">; -def err_using_decl_redeclaration : Error<"redeclaration of using decl">; +def err_using_decl_redeclaration : Error<"redeclaration of using declaration">; def err_using_decl_conflict : Error< "target of using declaration conflicts with declaration already in scope">; def err_using_decl_conflict_reverse : Error< @@ -610,8 +611,8 @@ def err_opencl_half_declaration : Error< "declaring variable of type %0 is not allowed">; def err_opencl_half_param : Error< "declaring function parameter of type %0 is not allowed; did you forget * ?">; -def err_opencl_half_return : Error< - "declaring function return value of type %0 is not allowed; did you forget * ?">; +def err_opencl_invalid_return : Error< + "declaring function return value of type %0 is not allowed %select{; did you forget * ?|}1">; def warn_enum_value_overflow : Warning<"overflow in enumeration value">; def warn_pragma_options_align_reset_failed : Warning< "#pragma options align=reset failed: %0">, @@ -719,6 +720,12 @@ def err_objc_root_class_subclass : Error< def warn_objc_root_class_missing : Warning< "class %0 defined without specifying a base class">, InGroup<ObjCRootClass>; +def err_objc_runtime_visible_category : Error< + "cannot implement a category for class %0 that is only visible via the " + "Objective-C runtime">; +def err_objc_runtime_visible_subclass : Error< + "cannot implement subclass %0 of a superclass %1 that is only visible via the " + "Objective-C runtime">; def note_objc_needs_superclass : Note< "add a super class to fix this problem">; def warn_dup_category_def : Warning< @@ -967,6 +974,8 @@ def note_property_synthesize : Note< "property synthesized here">; def error_synthesize_category_decl : Error< "@synthesize not allowed in a category's implementation">; +def error_synthesize_on_class_property : Error< + "@synthesize not allowed on a class property %0">; def error_reference_property : Error< "property of reference type is not supported">; def error_missing_property_interface : Error< @@ -1071,6 +1080,12 @@ def warn_cxx14_compat_static_assert_no_message : Warning< "static_assert with no message is incompatible with C++ standards before C++1z">, DefaultIgnore, InGroup<CXXPre1zCompat>; +def ext_inline_variable : ExtWarn< + "inline variables are a C++1z extension">, InGroup<CXX1z>; +def warn_cxx14_compat_inline_variable : Warning< + "inline variables are incompatible with C++ standards before C++1z">, + DefaultIgnore, InGroup<CXXPre1zCompat>; + def warn_inline_namespace_reopened_noninline : Warning< "inline namespace cannot be reopened as a non-inline namespace">; def err_inline_namespace_mismatch : Error< @@ -1210,6 +1225,8 @@ def err_distant_exception_spec : Error< def err_incomplete_in_exception_spec : Error< "%select{|pointer to |reference to }0incomplete type %1 is not allowed " "in exception specification">; +def ext_incomplete_in_exception_spec : ExtWarn<err_incomplete_in_exception_spec.Text>, + InGroup<MicrosoftExceptionSpec>; def err_rref_in_exception_spec : Error< "rvalue reference type %0 is not allowed in exception specification">; def err_mismatched_exception_spec : Error< @@ -1409,11 +1426,13 @@ def note_member_synthesized_at : Note< "assignment operator|move assignment operator|destructor}0 for %1 first " "required here">; def note_inhctor_synthesized_at : Note< - "inheriting constructor for %0 first required here">; + "inherited constructor for %0 first required here">; def err_missing_default_ctor : Error< - "%select{|implicit default |inheriting }0constructor for %1 must explicitly " - "initialize the %select{base class|member}2 %3 which does not have a default " - "constructor">; + "%select{constructor for %1 must explicitly initialize the|" + "implicit default constructor for %1 must explicitly initialize the|" + "cannot use constructor inherited from base class %4;}0 " + "%select{base class|member}2 %3 %select{which|which|of %1}0 " + "does not have a default constructor">; def note_due_to_dllexported_class : Note< "due to '%0' being dllexported%select{|; try compiling in C++11 mode}1">; @@ -1663,7 +1682,7 @@ def warn_maybe_uninit_var : Warning< "variable %0 may be uninitialized when " "%select{used here|captured by block}1">, InGroup<UninitializedMaybe>, DefaultIgnore; -def note_uninit_var_def : Note<"variable %0 is declared here">; +def note_var_declared_here : Note<"variable %0 is declared here">; def note_uninit_var_use : Note< "%select{uninitialized use occurs|variable is captured by block}0 here">; def warn_uninit_byref_blockvar_captured_by_block : Warning< @@ -1905,8 +1924,12 @@ def err_for_range_iter_deduction_failure : Error< "cannot use type %0 as an iterator">; def err_for_range_member_begin_end_mismatch : Error< "range type %0 has '%select{begin|end}1' member but no '%select{end|begin}1' member">; -def err_for_range_begin_end_types_differ : Error< - "'begin' and 'end' must return the same type (got %0 and %1)">; +def ext_for_range_begin_end_types_differ : ExtWarn< + "'begin' and 'end' returning different types (%0 and %1) is a C++1z extension">, + InGroup<CXX1z>; +def warn_for_range_begin_end_types_differ : Warning< + "'begin' and 'end' returning different types (%0 and %1) is incompatible " + "with C++ standards before C++1z">, InGroup<CXXPre1zCompat>, DefaultIgnore; def note_in_for_range: Note< "when looking up '%select{begin|end}0' function for range expression " "of type %1">; @@ -1923,6 +1946,22 @@ def note_for_range_invalid_iterator : Note < "in implicit call to 'operator%select{!=|*|++}0' for iterator of type %1">; def note_for_range_begin_end : Note< "selected '%select{begin|end}0' %select{function|template }1%2 with iterator type %3">; +def warn_for_range_const_reference_copy : Warning< + "loop variable %0 " + "%diff{has type $ but is initialized with type $" + "| is initialized with a value of a different type}1,2 resulting in a copy">, + InGroup<RangeLoopAnalysis>, DefaultIgnore; +def note_use_type_or_non_reference : Note< + "use non-reference type %0 to keep the copy or type %1 to prevent copying">; +def warn_for_range_variable_always_copy : Warning< + "loop variable %0 is always a copy because the range of type %1 does not " + "return a reference">, + InGroup<RangeLoopAnalysis>, DefaultIgnore; +def note_use_non_reference_type : Note<"use non-reference type %0">; +def warn_for_range_copy : Warning< + "loop variable %0 of type %1 creates a copy from type %2">, + InGroup<RangeLoopAnalysis>, DefaultIgnore; +def note_use_reference_type : Note<"use reference type %0 to prevent copying">; // C++11 constexpr def warn_cxx98_compat_constexpr : Warning< @@ -2067,6 +2106,16 @@ def err_concept_decl_invalid_specifiers : Error< "'%select{thread_local|inline|friend|constexpr}1'">; def err_function_concept_with_params : Error< "function concept cannot have any parameters">; +def err_function_concept_bool_ret : Error< + "declared return type of function concept must be 'bool'">; +def err_variable_concept_bool_decl : Error< + "declared type of variable concept must be 'bool'">; +def err_concept_specified_specialization : Error< + "'concept' cannot be applied on an " + "%select{explicit instantiation|explicit specialization|partial specialization}0">; +def err_concept_specialized : Error< + "%select{function|variable}0 concept cannot be " + "%select{explicitly instantiated|explicitly specialized|partially specialized}1">; // C++11 char16_t/char32_t def warn_cxx98_compat_unicode_type : Warning< @@ -2079,6 +2128,10 @@ def err_integer_sequence_negative_length : Error< def err_integer_sequence_integral_element_type : Error< "integer sequences must have integral element type">; +// __type_pack_element +def err_type_pack_element_out_of_bounds : Error< + "a parameter pack may not be accessed at an out of bounds index">; + // Objective-C++ def err_objc_decls_may_only_appear_in_global_scope : Error< "Objective-C declarations may only appear in global scope">; @@ -2101,6 +2154,10 @@ def err_attribute_too_few_arguments : Error< def err_attribute_invalid_vector_type : Error<"invalid vector element type %0">; def err_attribute_bad_neon_vector_size : Error< "Neon vector size must be 64 or 128 bits">; +def err_attribute_requires_positive_integer : Error< + "%0 attribute requires a positive integral compile time constant expression">; +def err_attribute_requires_opencl_version : Error< + "%0 attribute requires OpenCL version %1%select{| or above}2">; def warn_unsupported_target_attribute : Warning<"Ignoring unsupported '%0' in the target attribute string">, InGroup<IgnoredAttributes>; @@ -2250,6 +2307,20 @@ def warn_objc_collection_literal_element : Warning< "object of type %0 is not compatible with " "%select{array element type|dictionary key type|dictionary value type}1 %2">, InGroup<ObjCLiteralConversion>; +def err_swift_param_attr_not_swiftcall : Error< + "'%0' parameter can only be used with swiftcall calling convention">; +def err_swift_indirect_result_not_first : Error< + "'swift_indirect_result' parameters must be first parameters of function">; +def err_swift_context_not_before_swift_error_result : Error< + "'swift_context' parameter can only be followed by 'swift_error_result' " + "parameter">; +def err_swift_error_result_not_last : Error< + "'swift_error_result' parameter must be last parameter of function">; +def err_swift_error_result_not_after_swift_context : Error< + "'swift_error_result' parameter must follow 'swift_context' parameter">; +def err_swift_abi_parameter_wrong_type : Error< + "'%0' parameter must have pointer%select{| to unqualified pointer}1 type; " + "type here is %2">; def err_attribute_argument_is_zero : Error< "%0 attribute must be greater than 0">; @@ -2298,7 +2369,10 @@ def err_attribute_aligned_too_great : Error< "requested alignment must be %0 bytes or smaller">; def warn_redeclaration_without_attribute_prev_attribute_ignored : Warning< "%q0 redeclared without %1 attribute: previous %1 ignored">, - InGroup<DiagGroup<"inconsistent-dllimport">>; + InGroup<MicrosoftInconsistentDllImport>; +def warn_redeclaration_without_import_attribute : Warning< + "%q0 redeclared without 'dllimport' attribute: 'dllexport' attribute added">, + InGroup<MicrosoftInconsistentDllImport>; def warn_dllimport_dropped_from_inline_function : Warning< "%q0 redeclared inline; %1 attribute ignored">, InGroup<IgnoredAttributes>; @@ -2318,8 +2392,10 @@ def warn_cxx11_gnu_attribute_on_type : Warning< def warn_unhandled_ms_attribute_ignored : Warning< "__declspec attribute %0 is not supported">, InGroup<IgnoredAttributes>; -def err_attribute_invalid_on_stmt : Error< +def err_decl_attribute_invalid_on_stmt : Error< "%0 attribute cannot be applied to a statement">; +def err_stmt_attribute_invalid_on_decl : Error< + "%0 attribute cannot be applied to a declaration">; def warn_declspec_attribute_ignored : Warning< "attribute %0 is ignored, place it after " "\"%select{class|struct|interface|union|enum}1\" to apply attribute to " @@ -2410,31 +2486,41 @@ def err_attribute_weakref_without_alias : Error< def err_alias_not_supported_on_darwin : Error < "only weak aliases are supported on darwin">; def err_alias_to_undefined : Error< - "alias must point to a defined variable or function">; + "%select{alias|ifunc}0 must point to a defined %select{variable or |}1function">; def warn_alias_to_weak_alias : Warning< - "alias will always resolve to %0 even if weak definition of alias %1 is overridden">, + "%select{alias|ifunc}2 will always resolve to %0 even if weak definition of %1 is overridden">, InGroup<IgnoredAttributes>; def warn_alias_with_section : Warning< - "alias will not be in section '%0' but in the same section as the aliasee">, + "%select{alias|ifunc}1 will not be in section '%0' but in the same section as the %select{aliasee|resolver}2">, InGroup<IgnoredAttributes>; def err_duplicate_mangled_name : Error< "definition with same mangled name as another definition">; def err_cyclic_alias : Error< - "alias definition is part of a cycle">; + "%select{alias|ifunc}0 definition is part of a cycle">; +def err_ifunc_resolver_return : Error< + "ifunc resolver function must return a pointer">; +def err_ifunc_resolver_params : Error< + "ifunc resolver function must have no parameters">; def warn_attribute_wrong_decl_type : Warning< "%0 attribute only applies to %select{functions|unions|" - "variables and functions|functions and methods|parameters|" + "variables and functions|" + "functions, variables, and Objective-C interfaces|" + "functions and methods|parameters|" "functions, methods and blocks|functions, methods, and classes|" "functions, methods, and parameters|classes|enums|variables|methods|" - "variables, functions and labels|fields and global variables|structs|" - "variables and typedefs|thread-local variables|" - "variables and fields|variables, data members and tag types|" + "fields and global variables|structs|parameters and typedefs|variables and typedefs|" + "thread-local variables|variables and fields|variables, data members and tag types|" "types and namespaces|Objective-C interfaces|methods and properties|" "struct or union|struct, union or class|types|" "Objective-C instance methods|init methods of interface or class extension declarations|" - "variables, functions and classes|Objective-C protocols|" + "variables, functions and classes|" + "functions, variables, classes, and Objective-C interfaces|" + "Objective-C protocols|" "functions and global variables|structs, unions, and typedefs|structs and typedefs|" - "interface or protocol declarations|kernel functions|non-K&R-style functions}1">, + "interface or protocol declarations|kernel functions|non-K&R-style functions|" + "variables, enums, fields and typedefs|functions, methods, enums, and classes|" + "structs, classes, variables, functions, and inline namespaces|" + "variables, functions, methods, types, enumerations, enumerators, labels, and non-static data members}1">, InGroup<IgnoredAttributes>; def err_attribute_wrong_decl_type : Error<warn_attribute_wrong_decl_type.Text>; def warn_type_attribute_wrong_type : Warning< @@ -2444,9 +2530,6 @@ def warn_type_attribute_wrong_type : Warning< def warn_incomplete_encoded_type : Warning< "encoding of %0 type is incomplete because %1 component has unknown encoding">, InGroup<DiagGroup<"encode-type">>; -def warn_attribute_requires_functions_or_static_globals : Warning< - "%0 only applies to variables with static storage duration and functions">, - InGroup<IgnoredAttributes>; def warn_gnu_inline_attribute_requires_inline : Warning< "'gnu_inline' attribute requires function to be marked 'inline'," " attribute ignored">, @@ -2516,6 +2599,9 @@ def note_overridden_method : Note< def note_protocol_method : Note< "protocol method is here">; +def warn_available_using_star_case : Warning< + "using '*' case here, platform %0 is not accounted for">, InGroup<UnguardedAvailability>; + // Thread Safety Attributes def warn_invalid_capability_name : Warning< "invalid capability name '%0'; capability name must be 'mutex' or 'role'">, @@ -2682,9 +2768,6 @@ def warn_impcast_float_precision : Warning< def warn_impcast_double_promotion : Warning< "implicit conversion increases floating-point precision: %0 to %1">, InGroup<DoublePromotion>, DefaultIgnore; -def warn_impcast_float_integer : Warning< - "implicit conversion turns floating-point number into integer: %0 to %1">, - InGroup<FloatConversion>, DefaultIgnore; def warn_impcast_integer_sign : Warning< "implicit conversion changes signedness: %0 to %1">, InGroup<SignConversion>, DefaultIgnore; @@ -2703,9 +2786,22 @@ def warn_impcast_integer_precision_constant : Warning< def warn_impcast_bitfield_precision_constant : Warning< "implicit truncation from %2 to bitfield changes value from %0 to %1">, InGroup<BitFieldConstantConversion>; + def warn_impcast_literal_float_to_integer : Warning< "implicit conversion from %0 to %1 changes value from %2 to %3">, InGroup<LiteralConversion>; +def warn_impcast_float_integer : Warning< + "implicit conversion turns floating-point number into integer: %0 to %1">, + InGroup<FloatConversion>, DefaultIgnore; + +def warn_impcast_float_to_integer : Warning< + "implicit conversion of out of range value from %0 to %1 changes value " + "from %2 to %3">, + InGroup<FloatOverflowConversion>, DefaultIgnore; +def warn_impcast_float_to_integer_zero : Warning< + "implicit conversion from %0 to %1 changes non-zero value from %2 to %3">, + InGroup<FloatZeroConversion>, DefaultIgnore; + def warn_impcast_string_literal_to_bool : Warning< "implicit conversion turns string literal into bool: %0 to %1">, InGroup<StringConversion>, DefaultIgnore; @@ -2844,14 +2940,16 @@ def warn_vector_mode_deprecated : Warning< InGroup<DeprecatedAttributes>; def err_complex_mode_vector_type : Error< "type of machine mode does not support base vector types">; -def err_attr_wrong_decl : Error< - "%0 attribute invalid on this declaration, requires typedef or value">; +def err_enum_mode_vector_type : Error< + "mode %0 is not supported for enumeration types">; def warn_attribute_nonnull_no_pointers : Warning< "'nonnull' attribute applied to function with no pointer arguments">, InGroup<IgnoredAttributes>; def warn_attribute_nonnull_parm_no_args : Warning< "'nonnull' attribute when used on parameters takes no arguments">, InGroup<IgnoredAttributes>; +def note_declared_nonnull : Note< + "declared %select{'returns_nonnull'|'nonnull'}0 here">; def warn_attribute_sentinel_named_arguments : Warning< "'sentinel' attribute requires named arguments">, InGroup<IgnoredAttributes>; @@ -2907,6 +3005,9 @@ def warn_ns_attribute_wrong_return_type : Warning< "%0 attribute only applies to %select{functions|methods|properties}1 that " "return %select{an Objective-C object|a pointer|a non-retainable pointer}2">, InGroup<IgnoredAttributes>; +def err_ns_attribute_wrong_parameter_type : Error< + "%0 attribute only applies to " + "%select{Objective-C object|pointer|pointer-to-CF-pointer}1 parameters">; def warn_ns_attribute_wrong_parameter_type : Warning< "%0 attribute only applies to " "%select{Objective-C object|pointer|pointer-to-CF-pointer}1 parameters">, @@ -3013,7 +3114,9 @@ def err_uninitialized_member_for_assign : Error< "non-static %select{reference|const}1 member %2 cannot use copy " "assignment operator">; def err_uninitialized_member_in_ctor : Error< - "%select{|implicit default |inheriting }0constructor for %1 must explicitly " + "%select{constructor for %1|" + "implicit default constructor for %1|" + "cannot use constructor inherited from %1:}0 must explicitly " "initialize the %select{reference|const}2 member %3">; def err_default_arg_makes_ctor_special : Error< "addition of default argument on redeclaration makes this constructor a " @@ -3023,6 +3126,7 @@ def err_use_of_default_argument_to_function_declared_later : Error< "use of default argument to function %0 that is declared later in class %1">; def note_default_argument_declared_here : Note< "default argument declared here">; +def err_recursive_default_argument : Error<"recursive evaluation of default argument">; def ext_param_promoted_not_compatible_with_prototype : ExtWarn< "%diff{promoted type $ of K&R function parameter is not compatible with the " @@ -3061,7 +3165,8 @@ def note_ovl_candidate : Note<"candidate " "is the implicit move constructor|" "is the implicit copy assignment operator|" "is the implicit move assignment operator|" - "is an inherited constructor}0%1" + "inherited constructor|" + "inherited constructor }0%1" "%select{| has different class%diff{ (expected $ but has $)|}3,4" "| has different number of parameters (expected %3 but has %4)" "| has type mismatch at %ordinal3 parameter" @@ -3073,7 +3178,8 @@ def note_ovl_candidate : Note<"candidate " "%select{none|const|restrict|const and restrict|volatile|const and volatile" "|volatile and restrict|const, volatile, and restrict}4)}2">; -def note_ovl_candidate_inherited_constructor : Note<"inherited from here">; +def note_ovl_candidate_inherited_constructor : Note< + "constructor from base class %0 inherited here">; def note_ovl_candidate_illegal_constructor : Note< "candidate %select{constructor|template}0 ignored: " "instantiation %select{takes|would take}0 its own class type by value">; @@ -3133,7 +3239,8 @@ def note_ovl_candidate_arity : Note<"candidate " "constructor (the implicit move constructor)|" "function (the implicit copy assignment operator)|" "function (the implicit move assignment operator)|" - "constructor (inherited)}0 %select{|template }1" + "inherited constructor|" + "inherited constructor}0 %select{|template }1" "not viable: requires%select{ at least| at most|}2 %3 argument%s3, but %4 " "%plural{1:was|:were}4 provided">; @@ -3144,7 +3251,8 @@ def note_ovl_candidate_arity_one : Note<"candidate " "constructor (the implicit move constructor)|" "function (the implicit copy assignment operator)|" "function (the implicit move assignment operator)|" - "constructor (inherited)}0 %select{|template }1not viable: " + "inherited constructor|" + "inherited constructor}0 %select{|template }1not viable: " "%select{requires at least|allows at most single|requires single}2 " "argument %3, but %plural{0:no|:%4}4 arguments were provided">; @@ -3156,7 +3264,8 @@ def note_ovl_candidate_deleted : Note< "constructor (the implicit move constructor)|" "function (the implicit copy assignment operator)|" "function (the implicit move assignment operator)|" - "constructor (inherited)}0%1 has been " + "inherited constructor|" + "inherited constructor }0%1 has been " "%select{explicitly made unavailable|explicitly deleted|" "implicitly deleted}2">; @@ -3173,9 +3282,15 @@ def note_ovl_candidate_bad_conv_incomplete : Note<"candidate " "constructor (the implicit move constructor)|" "function (the implicit copy assignment operator)|" "function (the implicit move assignment operator)|" - "constructor (inherited)}0%1 " + "inherited constructor|" + "inherited constructor }0%1 " "not viable: cannot convert argument of incomplete type " - "%diff{$ to $|to parameter type}2,3">; + "%diff{$ to $|to parameter type}2,3 for " + "%select{%ordinal5 argument|object argument}4" + "%select{|; dereference the argument with *|" + "; take the address of the argument with &|" + "; remove *|" + "; remove &}6">; def note_ovl_candidate_bad_list_argument : Note<"candidate " "%select{function|function|constructor|" "function |function |constructor |" @@ -3184,7 +3299,8 @@ def note_ovl_candidate_bad_list_argument : Note<"candidate " "constructor (the implicit move constructor)|" "function (the implicit copy assignment operator)|" "function (the implicit move assignment operator)|" - "constructor (inherited)}0%1 " + "inherited constructor|" + "inherited constructor }0%1 " "not viable: cannot convert initializer list argument to %3">; def note_ovl_candidate_bad_overload : Note<"candidate " "%select{function|function|constructor|" @@ -3194,7 +3310,8 @@ def note_ovl_candidate_bad_overload : Note<"candidate " "constructor (the implicit move constructor)|" "function (the implicit copy assignment operator)|" "function (the implicit move assignment operator)|" - "constructor (inherited)}0%1" + "inherited constructor|" + "inherited constructor }0%1" " not viable: no overload of %3 matching %2 for %ordinal4 argument">; def note_ovl_candidate_bad_conv : Note<"candidate " "%select{function|function|constructor|" @@ -3204,7 +3321,8 @@ def note_ovl_candidate_bad_conv : Note<"candidate " "constructor (the implicit move constructor)|" "function (the implicit copy assignment operator)|" "function (the implicit move assignment operator)|" - "constructor (inherited)}0%1" + "inherited constructor|" + "inherited constructor }0%1" " not viable: no known conversion " "%diff{from $ to $|from argument type to parameter type}2,3 for " "%select{%ordinal5 argument|object argument}4" @@ -3220,7 +3338,8 @@ def note_ovl_candidate_bad_arc_conv : Note<"candidate " "constructor (the implicit move constructor)|" "function (the implicit copy assignment operator)|" "function (the implicit move assignment operator)|" - "constructor (inherited)}0%1" + "inherited constructor|" + "inherited constructor }0%1" " not viable: cannot implicitly convert argument " "%diff{of type $ to $|type to parameter type}2,3 for " "%select{%ordinal5 argument|object argument}4 under ARC">; @@ -3232,7 +3351,8 @@ def note_ovl_candidate_bad_lvalue : Note<"candidate " "constructor (the implicit move constructor)|" "function (the implicit copy assignment operator)|" "function (the implicit move assignment operator)|" - "constructor (inherited)}0%1" + "inherited constructor|" + "inherited constructor }0%1" " not viable: expects an l-value for " "%select{%ordinal3 argument|object argument}2">; def note_ovl_candidate_bad_addrspace : Note<"candidate " @@ -3243,7 +3363,8 @@ def note_ovl_candidate_bad_addrspace : Note<"candidate " "constructor (the implicit move constructor)|" "function (the implicit copy assignment operator)|" "function (the implicit move assignment operator)|" - "constructor (inherited)}0%1 not viable: " + "inherited constructor|" + "inherited constructor }0%1 not viable: " "%select{%ordinal6|'this'}5 argument (%2) is in " "address space %3, but parameter must be in address space %4">; def note_ovl_candidate_bad_gc : Note<"candidate " @@ -3254,7 +3375,8 @@ def note_ovl_candidate_bad_gc : Note<"candidate " "constructor (the implicit move constructor)|" "function (the implicit copy assignment operator)|" "function (the implicit move assignment operator)|" - "constructor (inherited)}0%1 not viable: " + "inherited constructor|" + "inherited constructor }0%1 not viable: " "%select{%ordinal6|'this'}5 argument (%2) has %select{no|__weak|__strong}3 " "ownership, but parameter has %select{no|__weak|__strong}4 ownership">; def note_ovl_candidate_bad_ownership : Note<"candidate " @@ -3265,7 +3387,8 @@ def note_ovl_candidate_bad_ownership : Note<"candidate " "constructor (the implicit move constructor)|" "function (the implicit copy assignment operator)|" "function (the implicit move assignment operator)|" - "constructor (inherited)}0%1 not viable: " + "inherited constructor|" + "inherited constructor }0%1 not viable: " "%select{%ordinal6|'this'}5 argument (%2) has " "%select{no|__unsafe_unretained|__strong|__weak|__autoreleasing}3 ownership," " but parameter has %select{no|__unsafe_unretained|__strong|__weak|" @@ -3273,7 +3396,7 @@ def note_ovl_candidate_bad_ownership : Note<"candidate " def note_ovl_candidate_bad_cvr_this : Note<"candidate " "%select{|function|||function|||||" "function (the implicit copy assignment operator)|" - "function (the implicit move assignment operator)|}0 not viable: " + "function (the implicit move assignment operator)||}0 not viable: " "'this' argument has type %2, but method is not marked " "%select{const|restrict|const or restrict|volatile|const or volatile|" "volatile or restrict|const, volatile, or restrict}3">; @@ -3285,11 +3408,23 @@ def note_ovl_candidate_bad_cvr : Note<"candidate " "constructor (the implicit move constructor)|" "function (the implicit copy assignment operator)|" "function (the implicit move assignment operator)|" - "constructor (inherited)}0%1 not viable: " + "inherited constructor|" + "inherited constructor }0%1 not viable: " "%ordinal4 argument (%2) would lose " "%select{const|restrict|const and restrict|volatile|const and volatile|" "volatile and restrict|const, volatile, and restrict}3 qualifier" "%select{||s||s|s|s}3">; +def note_ovl_candidate_bad_unaligned : Note<"candidate " + "%select{function|function|constructor|" + "function |function |constructor |" + "constructor (the implicit default constructor)|" + "constructor (the implicit copy constructor)|" + "constructor (the implicit move constructor)|" + "function (the implicit copy assignment operator)|" + "function (the implicit move assignment operator)|" + "inherited constructor|" + "inherited constructor }0%1 not viable: " + "%ordinal4 argument (%2) would lose __unaligned qualifier">; def note_ovl_candidate_bad_base_to_derived_conv : Note<"candidate " "%select{function|function|constructor|" "function |function |constructor |" @@ -3298,20 +3433,23 @@ def note_ovl_candidate_bad_base_to_derived_conv : Note<"candidate " "constructor (the implicit move constructor)|" "function (the implicit copy assignment operator)|" "function (the implicit move assignment operator)|" - "constructor (inherited)}0%1" - " not viable: cannot %select{convert from|convert from|bind}2 " + "inherited constructor|" + "inherited constructor }0%1 not viable: " + "cannot %select{convert from|convert from|bind}2 " "%select{base class pointer|superclass|base class object of type}2 %3 to " "%select{derived class pointer|subclass|derived class reference}2 %4 for " "%ordinal5 argument">; def note_ovl_candidate_bad_target : Note< "candidate %select{function|function|constructor|" - "function |function |constructor |" + "function|function|constructor|" "constructor (the implicit default constructor)|" "constructor (the implicit copy constructor)|" "constructor (the implicit move constructor)|" "function (the implicit copy assignment operator)|" "function (the implicit move assignment operator)|" - "constructor (inherited)}0 not viable: call to " + "inherited constructor|" + "inherited constructor}0 not viable: " + "call to " "%select{__device__|__global__|__host__|__host__ __device__|invalid}1 function from" " %select{__device__|__global__|__host__|__host__ __device__|invalid}2 function">; def note_implicit_member_target_infer_collision : Note< @@ -3515,8 +3653,8 @@ def note_template_unnamed_type_here : Note< "unnamed type used in template argument was declared here">; def err_template_arg_overload_type : Error< "template argument is the type of an unresolved overloaded function">; -def err_template_arg_not_class_template : Error< - "template argument does not refer to a class template or template " +def err_template_arg_not_valid_template : Error< + "template argument does not refer to a class or alias template, or template " "template parameter">; def note_template_arg_refers_here_func : Note< "template argument refers to function template %0, here">; @@ -3627,6 +3765,8 @@ def err_template_spec_unknown_kind : Error< "class template">; def note_specialized_entity : Note< "explicitly specialized declaration is here">; +def note_explicit_specialization_declared_here : Note< + "explicit specialization declared here">; def err_template_spec_decl_function_scope : Error< "explicit specialization of %0 in function scope">; def err_template_spec_decl_class_scope : Error< @@ -3749,6 +3889,8 @@ def err_partial_spec_ordering_ambiguous : Error< def note_partial_spec_match : Note<"partial specialization matches %0">; def err_partial_spec_redeclared : Error< "class template partial specialization %0 cannot be redeclared">; +def note_partial_specialization_declared_here : Note< + "explicit specialization declared here">; def note_prev_partial_spec_here : Note< "previous declaration of class template partial specialization %0 is here">; def err_partial_spec_fully_specialized : Error< @@ -3815,7 +3957,18 @@ def note_template_type_alias_instantiation_here : Note< "in instantiation of template type alias %0 requested here">; def note_template_exception_spec_instantiation_here : Note< "in instantiation of exception specification for %0 requested here">; - +def warn_var_template_missing : Warning<"instantiation of variable %q0 " + "required here, but no definition is available">, + InGroup<UndefinedVarTemplate>; +def warn_func_template_missing : Warning<"instantiation of function %q0 " + "required here, but no definition is available">, + InGroup<UndefinedFuncTemplate>, DefaultIgnore; +def note_forward_template_decl : Note< + "forward declaration of template entity is here">; +def note_inst_declaration_hint : Note<"add an explicit instantiation " + "declaration to suppress this warning if %q0 is explicitly instantiated in " + "another translation unit">; + def note_default_arg_instantiation_here : Note< "in instantiation of default argument for '%0' required here">; def note_default_function_arg_instantiation_here : Note< @@ -4108,8 +4261,6 @@ def note_implicitly_deleted : Note< "explicitly defaulted function was implicitly deleted here">; def note_inherited_deleted_here : Note< "deleted constructor was inherited here">; -def note_cannot_inherit : Note< - "constructor cannot be inherited">; def warn_not_enough_argument : Warning< "not enough variable arguments in %0 declaration to fit a sentinel">, InGroup<Sentinel>; @@ -4132,7 +4283,7 @@ def err_redefinition : Error<"redefinition of %0">; def err_alias_after_tentative : Error<"alias definition of %0 after tentative definition">; def err_alias_is_definition : - Error<"definition %0 cannot also be an alias">; + Error<"definition %0 cannot also be an %select{alias|ifunc}1">; def err_definition_of_implicitly_declared_member : Error< "definition of implicitly declared %select{default constructor|copy " "constructor|move constructor|copy assignment operator|move assignment " @@ -4144,24 +4295,36 @@ def err_definition_of_explicitly_defaulted_member : Error< def err_redefinition_extern_inline : Error< "redefinition of a 'extern inline' function %0 is not supported in " "%select{C99 mode|C++}1">; +def warn_attr_abi_tag_namespace : Warning< + "'abi_tag' attribute on %select{non-inline|anonymous}0 namespace ignored">, + InGroup<IgnoredAttributes>; +def err_abi_tag_on_redeclaration : Error< + "cannot add 'abi_tag' attribute in a redeclaration">; +def err_new_abi_tag_on_redeclaration : Error< + "'abi_tag' %0 missing in original declaration">; def note_deleted_dtor_no_operator_delete : Note< "virtual destructor requires an unambiguous, accessible 'operator delete'">; def note_deleted_special_member_class_subobject : Note< - "%select{default constructor|copy constructor|move constructor|" - "copy assignment operator|move assignment operator|destructor}0 of " + "%select{default constructor of|copy constructor of|move constructor of|" + "copy assignment operator of|move assignment operator of|destructor of|" + "constructor inherited by}0 " "%1 is implicitly deleted because " "%select{base class %3|%select{||||variant }4field %3}2 has " "%select{no|a deleted|multiple|an inaccessible|a non-trivial}4 " "%select{%select{default constructor|copy constructor|move constructor|copy " - "assignment operator|move assignment operator|destructor}0|destructor}5" + "assignment operator|move assignment operator|destructor|" + "%select{default|corresponding|default|default|default}4 constructor}0|" + "destructor}5" "%select{||s||}4">; def note_deleted_default_ctor_uninit_field : Note< - "default constructor of %0 is implicitly deleted because field %1 of " - "%select{reference|const-qualified}3 type %2 would not be initialized">; + "%select{default constructor of|constructor inherited by}0 " + "%1 is implicitly deleted because field %2 of " + "%select{reference|const-qualified}4 type %3 would not be initialized">; def note_deleted_default_ctor_all_const : Note< - "default constructor of %0 is implicitly deleted because all " - "%select{data members|data members of an anonymous union member}1" + "%select{default constructor of|constructor inherited by}0 " + "%1 is implicitly deleted because all " + "%select{data members|data members of an anonymous union member}2" " are const-qualified">; def note_deleted_copy_ctor_rvalue_reference : Note< "copy constructor of %0 is implicitly deleted because field %1 is of " @@ -4179,6 +4342,7 @@ def warn_undefined_internal : Warning< InGroup<DiagGroup<"undefined-internal">>; def warn_undefined_inline : Warning<"inline function %q0 is not defined">, InGroup<DiagGroup<"undefined-inline">>; +def err_undefined_inline_var : Error<"inline variable %q0 is not defined">; def note_used_here : Note<"used here">; def err_internal_linkage_redeclaration : Error< @@ -4254,7 +4418,7 @@ def err_redefinition_different_typedef : Error< "%select{typedef|type alias|type alias template}0 " "redefinition with different types%diff{ ($ vs $)|}1,2">; def err_tag_reference_non_tag : Error< - "elaborated type refers to %select{a non-tag type|a typedef|a type alias|a template|a type alias template}0">; + "elaborated type refers to %select{a non-tag type|a typedef|a type alias|a template|a type alias template|a template template argument}0">; def err_tag_reference_conflict : Error< "implicit declaration introduced by elaborated type conflicts with " "%select{a declaration|a typedef|a type alias|a template}0 of the same name">; @@ -4517,6 +4681,8 @@ def note_protected_by_vla_typedef : Note< "jump bypasses initialization of VLA typedef">; def note_protected_by_vla_type_alias : Note< "jump bypasses initialization of VLA type alias">; +def note_protected_by_constexpr_if : Note< + "jump enters controlled statement of constexpr if">; def note_protected_by_vla : Note< "jump bypasses initialization of variable length array">; def note_protected_by_objc_try : Note< @@ -5171,8 +5337,6 @@ def err_typecheck_pointer_arith_void_type : Error< "arithmetic on%select{ a|}0 pointer%select{|s}0 to void">; def err_typecheck_decl_incomplete_type : Error< "variable has incomplete type %0">; -def err_typecheck_decl_incomplete_type___float128 : Error< - "support for type '__float128' is not yet implemented">; def ext_typecheck_decl_incomplete_type : ExtWarn< "tentative definition of variable with internal linkage has incomplete non-array type %0">, InGroup<DiagGroup<"tentative-definition-incomplete-type">>; @@ -5257,7 +5421,11 @@ def ext_typecheck_indirection_through_void_pointer : ExtWarn< "ISO C++ does not allow indirection on operand of type %0">, InGroup<DiagGroup<"void-ptr-dereference">>; def warn_indirection_through_null : Warning< - "indirection of non-volatile null pointer will be deleted, not trap">, InGroup<NullDereference>; + "indirection of non-volatile null pointer will be deleted, not trap">, + InGroup<NullDereference>; +def warn_binding_null_to_reference : Warning< + "binding dereferenced null pointer to reference has undefined behavior">, + InGroup<NullDereference>; def note_indirection_through_null : Note< "consider using __builtin_trap() or qualifying pointer with 'volatile'">; def warn_pointer_indirection_from_incompatible_type : Warning< @@ -5301,7 +5469,9 @@ def ext_typecheck_comparison_of_distinct_pointers_nonstandard : ExtWarn< "composite pointer type %2">, InGroup<CompareDistinctPointerType>; def err_typecheck_op_on_nonoverlapping_address_space_pointers : Error< "%select{comparison between %diff{ ($ and $)|}0,1" - "|arithmetic operation with operands of type %diff{ ($ and $)|}0,1}2" + "|arithmetic operation with operands of type %diff{ ($ and $)|}0,1" + "|conditional operator with the second and third operands of type " + "%diff{ ($ and $)|}0,1}2" " which are pointers to non-overlapping address spaces">; def err_typecheck_assign_const : Error< @@ -5572,6 +5742,16 @@ def note_parameter_here : Note< def note_method_return_type_change : Note< "compiler has implicitly changed method %0 return type">; +def warn_impl_required_for_class_property : Warning< + "class property %0 requires method %1 to be defined - " + "use @dynamic or provide a method implementation " + "in this class implementation">, + InGroup<ObjCPropertyImpl>; +def warn_impl_required_in_category_for_class_property : Warning< + "class property %0 requires method %1 to be defined - " + "use @dynamic or provide a method implementation in this category">, + InGroup<ObjCPropertyImpl>; + // C++ casts // These messages adhere to the TryCast pattern: %0 is an int specifying the // cast type, %1 is the source type, %2 is the destination type. @@ -5771,6 +5951,8 @@ def err_catch_incomplete_ref : Error< "cannot catch reference to incomplete type %0">; def err_catch_incomplete : Error<"cannot catch incomplete type %0">; def err_catch_rvalue_ref : Error<"cannot catch exceptions by rvalue reference">; +def err_catch_variably_modified : Error< + "cannot catch variably modified type %0">; def err_qualified_catch_declarator : Error< "exception declarator cannot be qualified">; def err_early_catch_all : Error<"catch-all handler must come last">; @@ -5802,12 +5984,14 @@ def warn_non_virtual_dtor : Warning< "%0 has virtual functions but non-virtual destructor">, InGroup<NonVirtualDtor>, DefaultIgnore; def warn_delete_non_virtual_dtor : Warning< - "delete called on non-final %0 that has virtual functions " - "but non-virtual destructor">, + "%select{delete|destructor}0 called on non-final %1 that has " + "virtual functions but non-virtual destructor">, InGroup<DeleteNonVirtualDtor>, DefaultIgnore; +def note_delete_non_virtual : Note< + "qualify call to silence this warning">; def warn_delete_abstract_non_virtual_dtor : Warning< - "delete called on %0 that is abstract but has non-virtual destructor">, - InGroup<DeleteNonVirtualDtor>; + "%select{delete|destructor}0 called on %1 that is abstract but has " + "non-virtual destructor">, InGroup<DeleteNonVirtualDtor>; def warn_overloaded_virtual : Warning< "%q0 hides overloaded virtual %select{function|functions}1">, InGroup<OverloadedVirtual>, DefaultIgnore; @@ -5927,6 +6111,13 @@ let CategoryName = "Lambda Issue" in { "cannot deduce type for lambda capture %0 from initializer of type %2">; def err_init_capture_deduction_failure_from_init_list : Error< "cannot deduce type for lambda capture %0 from initializer list">; + + // C++1z '*this' captures. + def warn_cxx14_compat_star_this_lambda_capture : Warning< + "by value capture of '*this' is incompatible with C++ standards before C++1z">, + InGroup<CXXPre1zCompat>, DefaultIgnore; + def ext_star_this_lambda_capture_cxx1z : ExtWarn< + "capture of '*this' by copy is a C++1z extension">, InGroup<CXX1z>; } def err_return_in_captured_stmt : Error< @@ -6392,9 +6583,13 @@ def err_nontemporal_builtin_must_be_pointer_intfltptr_or_vector : Error< "pointer, or a vector of such types (%0 invalid)">; def err_deleted_function_use : Error<"attempt to use a deleted function">; +def err_deleted_inherited_ctor_use : Error< + "constructor inherited by %0 from base class %1 is implicitly deleted">; def err_kern_type_not_void_return : Error< "kernel function type %0 must have void return type">; +def err_kern_is_nonstatic_method : Error< + "kernel function %0 must be a free function or static member function">; def err_config_scalar_return : Error< "CUDA special function 'cudaConfigureCall' must have scalar return type">; def err_kern_call_not_global_function : Error< @@ -6404,10 +6599,31 @@ def err_global_call_not_config : Error< def err_ref_bad_target : Error< "reference to %select{__device__|__global__|__host__|__host__ __device__}0 " "function %1 in %select{__device__|__global__|__host__|__host__ __device__}2 function">; -def warn_host_calls_from_host_device : Warning< - "calling __host__ function %0 from __host__ __device__ function %1 can lead to runtime errors">, +def warn_kern_is_method : Extension< + "kernel function %0 is a member function; this may not be accepted by nvcc">, InGroup<CudaCompat>; - +def warn_kern_is_inline : Warning< + "ignored 'inline' attribute on kernel function %0">, + InGroup<CudaCompat>; +def err_variadic_device_fn : Error< + "CUDA device code does not support variadic functions">; +def err_va_arg_in_device : Error< + "CUDA device code does not support va_arg">; +def err_alias_not_supported_on_nvptx : Error<"CUDA does not support aliases">; +def err_cuda_unattributed_constexpr_cannot_overload_device : Error< + "constexpr function '%0' without __host__ or __device__ attributes cannot " + "overload __device__ function with same signature. Add a __host__ " + "attribute, or build with -fno-cuda-host-device-constexpr.">; +def note_cuda_conflicting_device_function_declared_here : Note< + "conflicting __device__ function declared here">; +def err_dynamic_var_init : Error< + "dynamic initialization is not supported for " + "__device__, __constant__, and __shared__ variables.">; +def err_shared_var_init : Error< + "initialization is not supported for __shared__ variables.">; +def err_device_static_local_var : Error< + "Within a __device__/__global__ function, " + "only __shared__ variables may be marked \"static\"">; def warn_non_pod_vararg_with_format_string : Warning< "cannot pass %select{non-POD|non-trivial}0 object of type %1 to variadic " "%select{function|block|method|constructor}2; expected type from format " @@ -6473,7 +6689,13 @@ def warn_cast_pointer_from_sel : Warning< def warn_function_def_in_objc_container : Warning< "function definition inside an Objective-C container is deprecated">, InGroup<FunctionDefInObjCContainer>; - + +def warn_cast_calling_conv : Warning< + "cast between incompatible calling conventions '%0' and '%1'; " + "calls through this pointer may abort at runtime">, + InGroup<DiagGroup<"cast-calling-convention">>; +def note_change_calling_conv_fixit : Note< + "consider defining %0 with the '%1' calling convention">; def warn_bad_function_cast : Warning< "cast from function call of type %0 to non-matching type %1">, InGroup<BadFunctionCast>, DefaultIgnore; @@ -6518,12 +6740,17 @@ def warn_side_effects_typeid : Warning< "expression with side effects will be evaluated despite being used as an " "operand to 'typeid'">, InGroup<PotentiallyEvaluatedExpression>; def warn_unused_result : Warning< - "ignoring return value of function declared with warn_unused_result " - "attribute">, InGroup<DiagGroup<"unused-result">>; + "ignoring return value of function declared with %0 attribute">, + InGroup<DiagGroup<"unused-result">>; def warn_unused_volatile : Warning< "expression result unused; assign into a variable to force a volatile load">, InGroup<DiagGroup<"unused-volatile-lvalue">>; +def ext_cxx14_attr : Extension< + "use of the %0 attribute is a C++14 extension">, InGroup<CXX14>; +def ext_cxx1z_attr : Extension< + "use of the %0 attribute is a C++1z extension">, InGroup<CXX1z>; + def warn_unused_comparison : Warning< "%select{%select{|in}1equality|relational}0 comparison result unused">, InGroup<UnusedComparison>; @@ -6849,9 +7076,16 @@ def err_literal_operator_id_outside_namespace : Error< "non-namespace scope '%0' cannot have a literal operator member">; def err_literal_operator_default_argument : Error< "literal operator cannot have a default argument">; -// FIXME: This diagnostic sucks -def err_literal_operator_params : Error< - "parameter declaration for literal operator %0 is not valid">; +def err_literal_operator_bad_param_count : Error< + "non-template literal operator must have one or two parameters">; +def err_literal_operator_invalid_param : Error< + "parameter of literal operator must have type 'unsigned long long', 'long double', 'char', 'wchar_t', 'char16_t', 'char32_t', or 'const char *'">; +def err_literal_operator_param : Error< + "invalid literal operator parameter type %0, did you mean %1?">; +def err_literal_operator_template_with_params : Error< + "literal operator template cannot have any parameters">; +def err_literal_operator_template : Error< + "template parameter list for literal operator must be either 'char...' or 'typename T, T...'">; def err_literal_operator_extern_c : Error< "literal operator must have C++ linkage">; def ext_string_literal_operator_template : ExtWarn< @@ -7061,6 +7295,8 @@ def warn_scanf_scanlist_incomplete : Warning< def note_format_string_defined : Note<"format string is defined here">; def note_format_fix_specifier : Note<"did you mean to use '%0'?">; def note_printf_c_str: Note<"did you mean to call the %0 method?">; +def note_format_security_fixit: Note< + "treat the string as an argument to avoid this">; def warn_null_arg : Warning< "null passed to a callee that requires a non-null argument">, @@ -7159,7 +7395,7 @@ def err_generic_sel_multi_match : Error< // Blocks def err_blocks_disable : Error<"blocks support disabled - compile with -fblocks" - " or pick a deployment target that supports them">; + " or %select{pick a deployment target that supports them|for OpenCL 2.0 or above}0">; def err_block_returning_array_function : Error< "block cannot return %select{array|function}0 type %1">; @@ -7228,16 +7464,15 @@ def note_insert_fallthrough_fixit : Note< def note_insert_break_fixit : Note< "insert 'break;' to avoid fall-through">; def err_fallthrough_attr_wrong_target : Error< - "clang::fallthrough attribute is only allowed on empty statements">; + "%0 attribute is only allowed on empty statements">; def note_fallthrough_insert_semi_fixit : Note<"did you forget ';'?">; def err_fallthrough_attr_outside_switch : Error< "fallthrough annotation is outside switch statement">; -def warn_fallthrough_attr_invalid_placement : Warning< - "fallthrough annotation does not directly precede switch label">, - InGroup<ImplicitFallthrough>; +def err_fallthrough_attr_invalid_placement : Error< + "fallthrough annotation does not directly precede switch label">; def warn_fallthrough_attr_unreachable : Warning< "fallthrough annotation in unreachable code">, - InGroup<ImplicitFallthrough>; + InGroup<ImplicitFallthrough>, DefaultIgnore; def warn_unreachable_default : Warning< "default label in switch which covers all enumeration values">, @@ -7281,10 +7516,13 @@ def err_va_start_used_in_wrong_abi_function : Error< "'va_start' used in %select{System V|Win64}0 ABI function">; def err_ms_va_start_used_in_sysv_function : Error< "'__builtin_ms_va_start' used in System V ABI function">; -def warn_second_parameter_of_va_start_not_last_named_argument : Warning< - "second parameter of 'va_start' not last named argument">, InGroup<Varargs>; -def warn_va_start_of_reference_type_is_undefined : Warning< - "'va_start' has undefined behavior with reference types">, InGroup<Varargs>; +def warn_second_arg_of_va_start_not_last_named_param : Warning< + "second argument to 'va_start' is not the last named parameter">, + InGroup<Varargs>; +def warn_va_start_type_is_undefined : Warning< + "passing %select{an object that undergoes default argument promotion|" + "an object of reference type|a parameter declared with the 'register' " + "keyword}0 to 'va_start' has undefined behavior">, InGroup<Varargs>; def err_first_argument_to_va_arg_not_of_type_va_list : Error< "first argument to 'va_arg' is of type %0 and not 'va_list'">; def err_second_parameter_to_va_arg_incomplete: Error< @@ -7471,8 +7709,8 @@ def err_c99_array_usage_cxx : Error< "feature, not permitted in C++">; def err_type_requires_extension : Error< "use of type %0 requires %1 extension to be enabled">; -def err_int128_unsupported : Error< - "__int128 is not supported on this target">; +def err_type_unsupported : Error< + "%0 is not supported on this target">; def err_nsconsumed_attribute_mismatch : Error< "overriding method has mismatched ns_consumed attribute on its" " parameter">; @@ -7541,6 +7779,8 @@ def err_typecheck_member_reference_ivar_suggest : Error< "%0 does not have a member named %1; did you mean %2?">; def err_property_not_found_suggest : Error< "property %0 not found on object of type %1; did you mean %2?">; +def err_class_property_found : Error< + "property %0 is a class property; did you mean to access it with class '%1'?">; def err_ivar_access_using_property_syntax_suggest : Error< "property %0 not found on object of type %1; did you mean to access instance variable %2?">; def warn_property_access_suggest : Warning< @@ -7600,9 +7840,6 @@ def err_asm_naked_this_ref : Error< def err_asm_naked_parm_ref : Error< "parameter references not allowed in naked functions">; -def ext_deprecated_attr_is_a_cxx14_extension : ExtWarn< - "use of the 'deprecated' attribute is a C++14 extension">, InGroup<CXX14>; - // OpenCL warnings and errors. def err_invalid_astype_of_different_size : Error< "invalid reinterpretation: sizes of %0 and %1 must match">; @@ -7612,8 +7849,8 @@ def err_opencl_ptrptr_kernel_param : Error< "kernel parameter cannot be declared as a pointer to a pointer">; def err_opencl_private_ptr_kernel_param : Error< "kernel parameter cannot be declared as a pointer to the __private address space">; -def err_opencl_non_kernel_variable : Error< - "non-kernel function variable cannot be declared in %0 address space">; +def err_opencl_function_variable : Error< + "%select{non-kernel function|function scope}0 variable cannot be declared in %1 address space">; def err_static_function_scope : Error< "variables in function scope cannot be declared static">; def err_opencl_bitfields : Error< @@ -7630,8 +7867,8 @@ def note_illegal_field_declared_here : Note< "field of illegal %select{type|pointer type}0 %1 declared here">; def err_event_t_global_var : Error< "the event_t type cannot be used to declare a program scope variable">; -def err_event_t_struct_field : Error< - "the event_t type cannot be used to declare a structure or union field">; +def err_opencl_type_struct_or_union_field : Error< + "the %0 type cannot be used to declare a structure or union field">; def err_event_t_addr_space_qual : Error< "the event_t type can only be used with __private address space qualifier">; def err_expected_kernel_void_return_type : Error< @@ -7640,8 +7877,10 @@ def err_sampler_argument_required : Error< "sampler_t variable required - got %0">; def err_wrong_sampler_addressspace: Error< "sampler type cannot be used with the __local and __global address space qualifiers">; +def error_opencl_cast_non_zero_to_event_t : Error< + "cannot cast non-zero value '%0' to 'event_t'">; def err_opencl_global_invalid_addr_space : Error< - "program scope variable must reside in %0 address space">; + "%select{program scope|static local|extern}0 variable must reside in %1 address space">; def err_missing_actual_pipe_type : Error< "missing actual type specifier for pipe">; def err_reference_pipe_type : Error < @@ -7658,11 +7897,71 @@ def err_atomic_init_constant : Error< " in the declaration statement in the program scope">; def err_opencl_implicit_vector_conversion : Error< "implicit conversions between vector types (%0 and %1) are not permitted">; +def err_opencl_block_proto_variadic : Error< + "invalid block prototype, variadic arguments are not allowed in OpenCL">; +def err_opencl_invalid_type_array : Error< + "array of %0 type is invalid in OpenCL">; +def err_opencl_ternary_with_block : Error< + "block type cannot be used as expression in ternary expression in OpenCL">; +def err_opencl_pointer_to_type : Error< + "pointer to type %0 is invalid in OpenCL">; +def err_opencl_type_can_only_be_used_as_function_parameter : Error < + "type %0 can only be used as a function parameter in OpenCL">; +def warn_opencl_attr_deprecated_ignored : Warning < + "%0 attribute is deprecated and ignored in OpenCL version %1">, + InGroup<IgnoredAttributes>; + +// OpenCL v2.0 s6.13.6 -- Builtin Pipe Functions +def err_opencl_builtin_pipe_first_arg : Error< + "first argument to %0 must be a pipe type">; +def err_opencl_builtin_pipe_arg_num : Error< + "invalid number of arguments to function: %0">; +def err_opencl_builtin_pipe_invalid_arg : Error< + "invalid argument type to function %0 (expecting %1 having %2)">; +def err_opencl_builtin_pipe_invalid_access_modifier : Error< + "invalid pipe access modifier (expecting %0)">; + +// OpenCL access qualifier +def err_opencl_invalid_access_qualifier : Error< + "access qualifier can only be used for pipe and image type">; +def err_opencl_invalid_read_write : Error< + "access qualifier %0 can not be used for %1 %select{|prior to OpenCL version 2.0}2">; +def err_opencl_multiple_access_qualifiers : Error< + "multiple access qualifiers">; +def note_opencl_typedef_access_qualifier : Note< + "previously declared '%0' here">; // OpenCL Section 6.8.g def err_opencl_unknown_type_specifier : Error< - "OpenCL does not support the '%0' %select{type qualifier|storage class specifier}1">; - + "OpenCL version %0 does not support the '%1' %select{type qualifier|storage class specifier}2">; + +// OpenCL v2.0 s6.12.5 Blocks restrictions +def err_opencl_block_storage_type : Error< + "the __block storage type is not permitted">; +def err_opencl_invalid_block_declaration : Error< + "invalid block variable declaration - must be %select{const qualified|initialized}0">; +def err_opencl_extern_block_declaration : Error< + "invalid block variable declaration - using 'extern' storage class is disallowed">; + +// OpenCL v2.0 s6.13.9 - Address space qualifier functions. +def err_opencl_builtin_to_addr_arg_num : Error< + "invalid number of arguments to function: %0">; +def err_opencl_builtin_to_addr_invalid_arg : Error< + "invalid argument %0 to function: %1, expecting a generic pointer argument">; + +// OpenCL v2.0 s6.13.17 Enqueue kernel restrictions. +def err_opencl_enqueue_kernel_incorrect_args : Error< + "illegal call to enqueue_kernel, incorrect argument types">; +def err_opencl_enqueue_kernel_expected_type : Error< + "illegal call to enqueue_kernel, expected %0 argument type">; +def err_opencl_enqueue_kernel_local_size_args : Error< + "mismatch in number of block parameters and local size arguments passed">; +def err_opencl_enqueue_kernel_invalid_local_size_type : Error< + "local memory sizes need to be specified as uint">; +def err_opencl_enqueue_kernel_blocks_non_local_void_args : Error< + "blocks used in device side enqueue are expected to have parameters of type 'local void*'">; +def err_opencl_enqueue_kernel_blocks_no_args : Error< + "blocks in this form of device side enqueue call are expected to have have no parameters">; } // end of sema category let CategoryName = "OpenMP Issue" in { @@ -7676,6 +7975,8 @@ def err_omp_global_var_arg : Error< "arguments of '#pragma omp %0' must have %select{global storage|static storage duration}1">; def err_omp_ref_type_arg : Error< "arguments of '#pragma omp %0' cannot be of reference type %1">; +def err_omp_region_not_file_context : Error< + "directive must be at file or namespace scope">; def err_omp_var_scope : Error< "'#pragma omp %0' must appear in the scope of the %q1 variable declaration">; def err_omp_var_used : Error< @@ -7692,10 +7993,28 @@ def err_omp_reduction_incomplete_type : Error< "a reduction list item with incomplete type %0">; def err_omp_unexpected_clause_value : Error< "expected %0 in OpenMP clause '%1'">; -def err_omp_expected_var_name : Error< - "expected variable name">; -def err_omp_expected_var_name_or_array_item : Error< - "expected variable name, array element or array section">; +def err_omp_expected_var_name_member_expr : Error< + "expected variable name%select{| or data member of current class}0">; +def err_omp_expected_var_name_member_expr_or_array_item : Error< + "expected variable name%select{|, data member of current class}0, array element or array section">; +def err_omp_expected_named_var_member_or_array_expression: Error< + "expected expression containing only member accesses and/or array sections based on named variables">; +def err_omp_bit_fields_forbidden_in_clause : Error< + "bit fields cannot be used to specify storage in a '%0' clause">; +def err_array_section_does_not_specify_contiguous_storage : Error< + "array section does not specify contiguous storage">; +def err_omp_union_type_not_allowed : Error< + "mapped storage cannot be derived from a union">; +def err_omp_expected_access_to_data_field : Error< + "expected access to data field">; +def err_omp_multiple_array_items_in_map_clause : Error< + "multiple array elements associated with the same variable are not allowed in map clauses of the same construct">; +def err_omp_pointer_mapped_along_with_derived_section : Error< + "pointer cannot be mapped along with a section derived from itself">; +def err_omp_original_storage_is_shared_and_does_not_contain : Error< + "original storage of expression in data environment is shared but data environment do not fully contain mapped expression storage">; +def err_omp_same_pointer_derreferenced : Error< + "same pointer derreferenced in multiple different ways in map clause expressions">; def note_omp_task_predetermined_firstprivate_here : Note< "predetermined as a firstprivate in a task construct here">; def err_omp_threadprivate_incomplete_type : Error< @@ -7733,6 +8052,8 @@ def err_omp_negative_expression_in_clause : Error< def err_omp_not_integral : Error< "expression must have integral or unscoped enumeration " "type, not %0">; +def err_omp_threadprivate_in_target : Error< + "threadprivate variables cannot be used in target constructs">; def err_omp_incomplete_type : Error< "expression has incomplete class type %0">; def err_omp_explicit_conversion : Error< @@ -7759,12 +8080,23 @@ def warn_omp_linear_step_zero : Warning< def warn_omp_alignment_not_power_of_two : Warning< "aligned clause will be ignored because the requested alignment is not a power of 2">, InGroup<OpenMPClauses>; +def err_omp_enclosed_declare_target : Error< + "declare target region may not be enclosed within another declare target region">; +def err_omp_invalid_target_decl : Error< + "%0 used in declare target directive is not a variable or a function name">; +def err_omp_declare_target_multiple : Error< + "%0 appears multiple times in clauses on the same declare target directive">; +def err_omp_declare_target_to_and_link : Error< + "%0 must not appear in both clauses 'to' and 'link'">; +def warn_omp_not_in_target_context : Warning< + "declaration is not declared in any declare target region">, + InGroup<OpenMPTarget>; def err_omp_aligned_expected_array_or_ptr : Error< "argument of aligned clause should be array" "%select{ or pointer|, pointer, reference to array or reference to pointer}1" ", not %0">; def err_omp_aligned_twice : Error< - "a variable cannot appear in more than one aligned clause">; + "%select{a variable|a parameter|'this'}0 cannot appear in more than one aligned clause">; def err_omp_local_var_in_threadprivate_init : Error< "variable with local storage in initial value of threadprivate variable">; def err_omp_loop_not_canonical_init : Error< @@ -7797,9 +8129,10 @@ def warn_omp_loop_64_bit_var : Warning< "OpenMP loop iteration variable cannot have more than 64 bits size and will be narrowed">, InGroup<OpenMPLoopForm>; def err_omp_unknown_reduction_identifier : Error< - "incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max'">; -def err_omp_reduction_type_array : Error< - "a reduction list item with array type %0">; + "incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', " + "'&&', '||', 'min' or 'max' or declare reduction for type %0">; +def err_omp_not_resolved_reduction_identifier : Error< + "unable to resolve declare reduction construct for type %0">; def err_omp_reduction_ref_type_arg : Error< "argument of OpenMP clause 'reduction' must reference the same object in all threads">; def err_omp_clause_not_arithmetic_type_arg : Error< @@ -7808,6 +8141,8 @@ def err_omp_clause_floating_type_arg : Error< "arguments of OpenMP clause 'reduction' with bitwise operators cannot be of floating type">; def err_omp_once_referenced : Error< "variable can appear only once in OpenMP '%0' clause">; +def err_omp_once_referenced_in_target_update : Error< + "variable can appear only once in OpenMP 'target update' construct">; def note_omp_referenced : Note< "previously referenced here">; def err_omp_reduction_in_task : Error< @@ -7883,12 +8218,19 @@ def err_omp_single_copyprivate_with_nowait : Error< "the 'copyprivate' clause must not be used with the 'nowait' clause">; def note_omp_nowait_clause_here : Note< "'nowait' clause is here">; +def err_omp_single_decl_in_declare_simd : Error< + "single declaration is expected after 'declare simd' directive">; +def err_omp_function_expected : Error< + "'#pragma omp declare simd' can only be applied to functions">; def err_omp_wrong_cancel_region : Error< "one of 'for', 'parallel', 'sections' or 'taskgroup' is expected">; def err_omp_parent_cancel_region_nowait : Error< "parent region for 'omp %select{cancellation point/cancel}0' construct cannot be nowait">; def err_omp_parent_cancel_region_ordered : Error< "parent region for 'omp %select{cancellation point/cancel}0' construct cannot be ordered">; +def err_omp_reduction_wrong_type : Error<"reduction type cannot be %select{qualified with 'const', 'volatile' or 'restrict'|a function|a reference|an array}0 type">; +def err_omp_wrong_var_in_declare_reduction : Error<"only %select{'omp_priv' or 'omp_orig'|'omp_in' or 'omp_out'}0 variables are allowed in %select{initializer|combiner}0 expression">; +def err_omp_declare_reduction_redefinition : Error<"redefinition of user-defined reduction for type %0">; def err_omp_array_section_use : Error<"OpenMP array section is not allowed here">; def err_omp_typecheck_section_value : Error< "subscripted value is not an array or pointer">; @@ -7930,12 +8272,16 @@ def err_omp_map_shared_storage : Error< "variable already marked as mapped in current construct">; def err_omp_not_mappable_type : Error< "type %0 is not mappable to target">; +def err_omp_invalid_map_type_for_directive : Error< + "%select{map type '%1' is not allowed|map type must be specified}0 for '#pragma omp %2'">; +def err_omp_no_map_for_directive : Error< + "expected at least one map clause for '#pragma omp %0'">; def note_omp_polymorphic_in_target : Note< "mappable type cannot be polymorphic">; def note_omp_static_member_in_target : Note< "mappable type cannot contain static members">; -def err_omp_threadprivate_in_map : Error< - "threadprivate variables are not allowed in map clause">; +def err_omp_threadprivate_in_clause : Error< + "threadprivate variables are not allowed in '%0' clause">; def err_omp_wrong_ordered_loop_count : Error< "the parameter of the 'ordered' clause must be greater than or equal to the parameter of the 'collapse' clause">; def note_collapse_loop_count : Note< @@ -7960,8 +8306,6 @@ def err_omp_firstprivate_distribute_in_teams_reduction : Error< "reduction variable in '#pragma omp teams' cannot be firstprivate in '#pragma omp distribute'">; def err_omp_depend_clause_thread_simd : Error< "'depend' clauses cannot be mixed with '%0' clause">; -def err_omp_depend_sink_wrong_expr : Error< - "expected expression form x[+-d], where x is the loop iteration variable and d is a constant non-negative integer">; def err_omp_depend_sink_expected_loop_iteration : Error< "expected %0 loop iteration variable">; def err_omp_depend_sink_unexpected_expr : Error< @@ -7980,6 +8324,23 @@ def err_omp_schedule_nonmonotonic_ordered : Error< "'schedule' clause with 'nonmonotonic' modifier cannot be specified if an 'ordered' clause is specified">; def err_omp_ordered_simd : Error< "'ordered' clause with a parameter can not be specified in '#pragma omp %0' directive">; +def err_omp_variable_in_map_and_dsa : Error< + "%0 variable cannot be in a map clause in '#pragma omp %1' directive">; +def err_omp_param_or_this_in_clause : Error< + "expected reference to one of the parameters of function %0%select{| or 'this'}1">; +def err_omp_expected_uniform_param : Error< + "expected a reference to a parameter specified in a 'uniform' clause">; +def err_omp_expected_int_param : Error< + "expected a reference to an integer-typed parameter">; +def err_omp_at_least_one_motion_clause_required : Error< + "expected at least one 'to' clause or 'from' clause specified to '#pragma omp target update'">; +def err_omp_usedeviceptr_not_a_pointer : Error< + "expected pointer or reference to pointer in 'use_device_ptr' clause">; +def err_omp_argument_type_isdeviceptr : Error < + "expected pointer, array, reference to pointer, or reference to array in 'is_device_ptr clause'">; +def warn_omp_nesting_simd : Warning< + "OpenMP only allows an ordered construct with the simd clause nested in a simd construct">, + InGroup<SourceUsesOpenMP>; } // end of OpenMP category let CategoryName = "Related Result Type Issue" in { @@ -8018,10 +8379,17 @@ def err_module_private_local_class : Error< "local %select{struct|interface|union|class|enum}0 cannot be declared " "__module_private__">; def err_module_unimported_use : Error< - "%select{declaration|definition|default argument}0 of %1 must be imported " + "%select{declaration|definition|default argument|" + "explicit specialization|partial specialization}0 of %1 must be imported " + "from module '%2' before it is required">; +def err_module_unimported_use_header : Error< + "missing '#include %3'; " + "%select{declaration|definition|default argument|" + "explicit specialization|partial specialization}0 of %1 must be imported " "from module '%2' before it is required">; def err_module_unimported_use_multiple : Error< - "%select{declaration|definition|default argument}0 of %1 must be imported " + "%select{declaration|definition|default argument|" + "explicit specialization|partial specialization}0 of %1 must be imported " "from one of the following modules before it is required:%2">; def ext_module_import_in_extern_c : ExtWarn< "import of C++ module '%0' appears within extern \"C\" language linkage " @@ -8221,4 +8589,12 @@ def warn_objc_redundant_qualified_class_type : Warning< "parameterized class %0 already conforms to the protocols listed; did you " "forget a '*'?">, InGroup<ObjCProtocolQualifiers>; +def warn_block_literal_attributes_on_omitted_return_type : Warning< + "attribute %0 ignored, because it cannot be applied to omitted return type">, + InGroup<IgnoredAttributes>; + +def warn_block_literal_qualifiers_on_omitted_return_type : Warning< + "'%0' qualifier on omitted return type %1 has no effect">, + InGroup<IgnoredQualifiers>; + } // end of sema component. diff --git a/include/clang/Basic/FileManager.h b/include/clang/Basic/FileManager.h index 17758ec3f3988..b6a9ca702842c 100644 --- a/include/clang/Basic/FileManager.h +++ b/include/clang/Basic/FileManager.h @@ -52,6 +52,7 @@ public: /// descriptor for the file. class FileEntry { const char *Name; // Name of the file. + std::string RealPathName; // Real path to the file; could be empty. off_t Size; // File size in bytes. time_t ModTime; // Modification time of file. const DirectoryEntry *Dir; // Directory file lives in. @@ -82,6 +83,7 @@ public: } const char *getName() const { return Name; } + StringRef tryGetRealPathName() const { return RealPathName; } bool isValid() const { return IsValid; } off_t getSize() const { return Size; } unsigned getUID() const { return UID; } diff --git a/include/clang/Basic/IdentifierTable.h b/include/clang/Basic/IdentifierTable.h index d672314f56e2d..fffb50493bfe5 100644 --- a/include/clang/Basic/IdentifierTable.h +++ b/include/clang/Basic/IdentifierTable.h @@ -62,6 +62,9 @@ class IdentifierInfo { // partially) from an AST file. bool ChangedAfterLoad : 1; // True if identifier has changed from the // definition loaded from an AST file. + bool FEChangedAfterLoad : 1; // True if identifier's frontend information + // has changed from the definition loaded + // from an AST file. bool RevertedTokenID : 1; // True if revertTokenIDToIdentifier was // called. bool OutOfDate : 1; // True if there may be additional @@ -69,7 +72,7 @@ class IdentifierInfo { // stored externally. bool IsModulesImport : 1; // True if this is the 'import' contextual // keyword. - // 30 bit left in 64-bit word. + // 29 bit left in 64-bit word. void *FETokenInfo; // Managed by the language front-end. llvm::StringMapEntry<IdentifierInfo*> *Entry; @@ -303,6 +306,18 @@ public: ChangedAfterLoad = true; } + /// \brief Determine whether the frontend token information for this + /// identifier has changed since it was loaded from an AST file. + bool hasFETokenInfoChangedSinceDeserialization() const { + return FEChangedAfterLoad; + } + + /// \brief Note that the frontend token information for this identifier has + /// changed since it was loaded from an AST file. + void setFETokenInfoChangedSinceDeserialization() { + FEChangedAfterLoad = true; + } + /// \brief Determine whether the information for this identifier is out of /// date with respect to the external source. bool isOutOfDate() const { return OutOfDate; } diff --git a/include/clang/Basic/Lambda.h b/include/clang/Basic/Lambda.h index e676e726dd7a9..1c19f1dcc8b1c 100644 --- a/include/clang/Basic/Lambda.h +++ b/include/clang/Basic/Lambda.h @@ -32,7 +32,8 @@ enum LambdaCaptureDefault { /// by reference. C++1y also allows "init-capture", where the initializer /// is an expression. enum LambdaCaptureKind { - LCK_This, ///< Capturing the \c this pointer + LCK_This, ///< Capturing the \c *this object by reference + LCK_StarThis, /// < Capturing the \c *this object by copy LCK_ByCopy, ///< Capturing by copy (a.k.a., by value) LCK_ByRef, ///< Capturing by reference LCK_VLAType ///< Capturing variable-length array type diff --git a/include/clang/Basic/LangOptions.def b/include/clang/Basic/LangOptions.def index cc70d6246c036..03561961dd218 100644 --- a/include/clang/Basic/LangOptions.def +++ b/include/clang/Basic/LangOptions.def @@ -24,11 +24,15 @@ // // VALUE_LANGOPT: for options that describe a value rather than a flag. // -// BENIGN_ENUM_LANGOPT, COMPATIBLE_ENUM_LANGOPT: combinations of the above. +// BENIGN_ENUM_LANGOPT, COMPATIBLE_ENUM_LANGOPT, +// BENIGN_VALUE_LANGOPT, COMPATIBLE_VALUE_LANGOPT: combinations of the above. // // FIXME: Clients should be able to more easily select whether they want // different levels of compatibility versus how to handle different kinds // of option. +// +// The Description field should be a noun phrase, for instance "frobbing all +// widgets" or "C's implicit blintz feature". //===----------------------------------------------------------------------===// #ifndef LANGOPT @@ -65,6 +69,16 @@ LANGOPT(Name, Bits, Default, Description) #endif +#ifndef COMPATIBLE_VALUE_LANGOPT +# define COMPATIBLE_VALUE_LANGOPT(Name, Bits, Default, Description) \ + VALUE_LANGOPT(Name, Bits, Default, Description) +#endif + +#ifndef BENIGN_VALUE_LANGOPT +# define BENIGN_VALUE_LANGOPT(Name, Bits, Default, Description) \ + COMPATIBLE_VALUE_LANGOPT(Name, Bits, Default, Description) +#endif + // FIXME: A lot of the BENIGN_ options should be COMPATIBLE_ instead. LANGOPT(C99 , 1, 0, "C99") LANGOPT(C11 , 1, 0, "C11") @@ -110,6 +124,7 @@ LANGOPT(Exceptions , 1, 0, "exception handling") LANGOPT(ObjCExceptions , 1, 0, "Objective-C exceptions") LANGOPT(CXXExceptions , 1, 0, "C++ exceptions") LANGOPT(SjLjExceptions , 1, 0, "setjmp-longjump exception handling") +LANGOPT(ExternCNoUnwind , 1, 0, "Assume extern C functions don't unwind") LANGOPT(TraditionalCPP , 1, 0, "traditional CPP emulation") LANGOPT(RTTI , 1, 1, "run-time type information") LANGOPT(RTTIData , 1, 1, "emit run-time type information data") @@ -123,31 +138,33 @@ LANGOPT(Coroutines , 1, 0, "C++ coroutines") BENIGN_LANGOPT(ThreadsafeStatics , 1, 1, "thread-safe static initializers") LANGOPT(POSIXThreads , 1, 0, "POSIX thread support") LANGOPT(Blocks , 1, 0, "blocks extension to C") -BENIGN_LANGOPT(EmitAllDecls , 1, 0, "support for emitting all declarations") -LANGOPT(MathErrno , 1, 1, "errno support for math functions") -BENIGN_LANGOPT(HeinousExtensions , 1, 0, "Extensions that we really don't like and may be ripped out at any time") +BENIGN_LANGOPT(EmitAllDecls , 1, 0, "emitting all declarations") +LANGOPT(MathErrno , 1, 1, "errno in math functions") +BENIGN_LANGOPT(HeinousExtensions , 1, 0, "extensions that we really don't like and may be ripped out at any time") LANGOPT(Modules , 1, 0, "modules extension to C") +BENIGN_LANGOPT(CompilingModule, 1, 0, "compiling a module interface") COMPATIBLE_LANGOPT(ModulesDeclUse , 1, 0, "require declaration of module uses") -LANGOPT(ModulesSearchAll , 1, 1, "search even non-imported modules to find unresolved references") -COMPATIBLE_LANGOPT(ModulesStrictDeclUse, 1, 0, "require declaration of module uses and all headers to be in modules") -BENIGN_LANGOPT(ModulesErrorRecovery, 1, 1, "automatically import modules as needed when performing error recovery") -BENIGN_LANGOPT(ImplicitModules, 1, 1, "build modules that are not specified via -fmodule-file") +BENIGN_LANGOPT(ModulesSearchAll , 1, 1, "searching even non-imported modules to find unresolved references") +COMPATIBLE_LANGOPT(ModulesStrictDeclUse, 1, 0, "requiring declaration of module uses and all headers to be in modules") +BENIGN_LANGOPT(ModulesErrorRecovery, 1, 1, "automatically importing modules as needed when performing error recovery") +BENIGN_LANGOPT(ImplicitModules, 1, 1, "building modules that are not specified via -fmodule-file") COMPATIBLE_LANGOPT(ModulesLocalVisibility, 1, 0, "local submodule visibility") COMPATIBLE_LANGOPT(Optimize , 1, 0, "__OPTIMIZE__ predefined macro") COMPATIBLE_LANGOPT(OptimizeSize , 1, 0, "__OPTIMIZE_SIZE__ predefined macro") -LANGOPT(Static , 1, 0, "__STATIC__ predefined macro (as opposed to __DYNAMIC__)") +COMPATIBLE_LANGOPT(Static , 1, 0, "__STATIC__ predefined macro (as opposed to __DYNAMIC__)") VALUE_LANGOPT(PackStruct , 32, 0, "default struct packing maximum alignment") VALUE_LANGOPT(MaxTypeAlign , 32, 0, "default maximum alignment for types") -VALUE_LANGOPT(PICLevel , 2, 0, "__PIC__ level") -VALUE_LANGOPT(PIELevel , 2, 0, "__PIE__ level") -LANGOPT(GNUInline , 1, 0, "GNU inline semantics") +VALUE_LANGOPT(AlignDouble , 1, 0, "Controls if doubles should be aligned to 8 bytes (x86 only)") +COMPATIBLE_VALUE_LANGOPT(PICLevel , 2, 0, "__PIC__ level") +COMPATIBLE_VALUE_LANGOPT(PIE , 1, 0, "is pie") +COMPATIBLE_LANGOPT(GNUInline , 1, 0, "GNU inline semantics") COMPATIBLE_LANGOPT(NoInlineDefine , 1, 0, "__NO_INLINE__ predefined macro") COMPATIBLE_LANGOPT(Deprecated , 1, 0, "__DEPRECATED predefined macro") -LANGOPT(FastMath , 1, 0, "__FAST_MATH__ predefined macro") -LANGOPT(FiniteMathOnly , 1, 0, "__FINITE_MATH_ONLY__ predefined macro") -LANGOPT(UnsafeFPMath , 1, 0, "Unsafe Floating Point Math") +COMPATIBLE_LANGOPT(FastMath , 1, 0, "fast FP math optimizations, and __FAST_MATH__ predefined macro") +COMPATIBLE_LANGOPT(FiniteMathOnly , 1, 0, "__FINITE_MATH_ONLY__ predefined macro") +COMPATIBLE_LANGOPT(UnsafeFPMath , 1, 0, "Unsafe Floating Point Math") BENIGN_LANGOPT(ObjCGCBitmapPrint , 1, 0, "printing of GC's bitmap layout for __weak/__strong ivars") @@ -155,24 +172,27 @@ BENIGN_LANGOPT(AccessControl , 1, 1, "C++ access control") LANGOPT(CharIsSigned , 1, 1, "signed char") LANGOPT(ShortWChar , 1, 0, "unsigned short wchar_t") ENUM_LANGOPT(MSPointerToMemberRepresentationMethod, PragmaMSPointersToMembersKind, 2, PPTMK_BestCase, "member-pointer representation method") +ENUM_LANGOPT(DefaultCallingConv, DefaultCallingConvention, 3, DCC_None, "default calling convention") LANGOPT(ShortEnums , 1, 0, "short enum types") LANGOPT(OpenCL , 1, 0, "OpenCL") LANGOPT(OpenCLVersion , 32, 0, "OpenCL version") LANGOPT(NativeHalfType , 1, 0, "Native half type support") +LANGOPT(NativeHalfArgsAndReturns, 1, 0, "Native half args and returns") LANGOPT(HalfArgsAndReturns, 1, 0, "half args and returns") LANGOPT(CUDA , 1, 0, "CUDA") -LANGOPT(OpenMP , 1, 0, "OpenMP support") +LANGOPT(OpenMP , 32, 0, "OpenMP support and version of OpenMP (31, 40 or 45)") LANGOPT(OpenMPUseTLS , 1, 0, "Use TLS for threadprivates or runtime calls") LANGOPT(OpenMPIsDevice , 1, 0, "Generate code only for OpenMP target device") +LANGOPT(RenderScript , 1, 0, "RenderScript") -LANGOPT(CUDAIsDevice , 1, 0, "Compiling for CUDA device") -LANGOPT(CUDAAllowHostCallsFromHostDevice, 1, 0, "Allow host device functions to call host functions") -LANGOPT(CUDADisableTargetCallChecks, 1, 0, "Disable checks for call targets (host, device, etc.)") -LANGOPT(CUDATargetOverloads, 1, 0, "Enable function overloads based on CUDA target attributes") +LANGOPT(CUDAIsDevice , 1, 0, "compiling for CUDA device") +LANGOPT(CUDAAllowVariadicFunctions, 1, 0, "allowing variadic functions in CUDA device code") +LANGOPT(CUDAHostDeviceConstexpr, 1, 1, "treating unattributed constexpr functions as __host__ __device__") +LANGOPT(CUDADeviceFlushDenormalsToZero, 1, 0, "flushing denormals to zero") +LANGOPT(CUDADeviceApproxTranscendentals, 1, 0, "using approximate transcendental functions") -LANGOPT(AssumeSaneOperatorNew , 1, 1, "implicit __attribute__((malloc)) for C++'s new operators") LANGOPT(SizedDeallocation , 1, 0, "enable sized deallocation functions") LANGOPT(ConceptsTS , 1, 0, "enable C++ Extensions for Concepts") BENIGN_LANGOPT(ElideConstructors , 1, 1, "C++ copy constructor elision") @@ -198,8 +218,7 @@ LANGOPT(ObjCWeak , 1, 0, "Objective-C __weak in ARC and MRC files") LANGOPT(ObjCSubscriptingLegacyRuntime , 1, 0, "Subscripting support in legacy ObjectiveC runtime") LANGOPT(FakeAddressSpaceMap , 1, 0, "OpenCL fake address space map") ENUM_LANGOPT(AddressSpaceMapMangling , AddrSpaceMapMangling, 2, ASMM_Target, "OpenCL address space map mangling mode") - -LANGOPT(MRTD , 1, 0, "-mrtd calling convention") +LANGOPT(IncludeDefaultHeader, 1, 0, "Include default header file for OpenCL") BENIGN_LANGOPT(DelayedTemplateParsing , 1, 0, "delayed template parsing") LANGOPT(BlocksRuntimeOptional , 1, 0, "optional blocks runtime") @@ -243,4 +262,6 @@ LANGOPT(SanitizeAddressFieldPadding, 2, 0, "controls how aggressive is ASan " #undef COMPATIBLE_ENUM_LANGOPT #undef BENIGN_ENUM_LANGOPT #undef VALUE_LANGOPT +#undef COMPATIBLE_VALUE_LANGOPT +#undef BENIGN_VALUE_LANGOPT diff --git a/include/clang/Basic/LangOptions.h b/include/clang/Basic/LangOptions.h index 736d4e0930b15..6ec499f1c74aa 100644 --- a/include/clang/Basic/LangOptions.h +++ b/include/clang/Basic/LangOptions.h @@ -65,6 +65,14 @@ public: PPTMK_FullGeneralityVirtualInheritance }; + enum DefaultCallingConvention { + DCC_None, + DCC_CDecl, + DCC_FastCall, + DCC_StdCall, + DCC_VectorCall + }; + enum AddrSpaceMapMangling { ASMM_Target, ASMM_On, ASMM_Off }; enum MSVCMajorVersion { @@ -92,14 +100,12 @@ public: /// If none is specified, abort (GCC-compatible behaviour). std::string OverflowHandler; - /// \brief The name of the current module. + /// \brief The name of the current module, of which the main source file + /// is a part. If CompilingModule is set, we are compiling the interface + /// of this module, otherwise we are compiling an implementation file of + /// it. std::string CurrentModule; - /// \brief The name of the module that the translation unit is an - /// implementation of. Prevents semantic imports, but does not otherwise - /// treat this as the CurrentModule. - std::string ImplementationOfModule; - /// \brief The names of any features to enable in module 'requires' decls /// in addition to the hard-coded list in Module.cpp and the target features. /// @@ -162,18 +168,6 @@ public: fp_contract(LangOpts.DefaultFPContract) {} }; -/// \brief OpenCL volatile options -class OpenCLOptions { -public: -#define OPENCLEXT(nm) unsigned nm : 1; -#include "clang/Basic/OpenCLExtensions.def" - - OpenCLOptions() { -#define OPENCLEXT(nm) nm = 0; -#include "clang/Basic/OpenCLExtensions.def" - } -}; - /// \brief Describes the kind of translation unit being processed. enum TranslationUnitKind { /// \brief The translation unit is a complete translation unit. diff --git a/include/clang/Basic/Makefile b/include/clang/Basic/Makefile deleted file mode 100644 index 5579a99900511..0000000000000 --- a/include/clang/Basic/Makefile +++ /dev/null @@ -1,70 +0,0 @@ -CLANG_LEVEL := ../../.. -BUILT_SOURCES = \ - DiagnosticAnalysisKinds.inc DiagnosticASTKinds.inc \ - DiagnosticCommentKinds.inc \ - DiagnosticCommonKinds.inc DiagnosticDriverKinds.inc \ - DiagnosticFrontendKinds.inc DiagnosticLexKinds.inc \ - DiagnosticParseKinds.inc DiagnosticSemaKinds.inc \ - DiagnosticSerializationKinds.inc \ - AttrHasAttributeImpl.inc \ - DiagnosticIndexName.inc DiagnosticGroups.inc AttrList.inc arm_neon.inc \ - Version.inc - -TABLEGEN_INC_FILES_COMMON = 1 - -include $(CLANG_LEVEL)/Makefile - -INPUT_TDS = $(wildcard $(PROJ_SRC_DIR)/Diagnostic*.td) - -# Compute the Clang version from the LLVM version, unless specified explicitly. -ifndef CLANG_VERSION -CLANG_VERSION := $(subst svn,,$(LLVMVersion)) -CLANG_VERSION := $(subst rc,,$(CLANG_VERSION)) -endif - -CLANG_VERSION_COMPONENTS := $(subst ., ,$(CLANG_VERSION)) -CLANG_VERSION_MAJOR := $(word 1,$(CLANG_VERSION_COMPONENTS)) -CLANG_VERSION_MINOR := $(word 2,$(CLANG_VERSION_COMPONENTS)) -CLANG_VERSION_PATCHLEVEL := $(word 3,$(CLANG_VERSION_COMPONENTS)) -ifeq ($(CLANG_VERSION_PATCHLEVEL),) -CLANG_HAS_VERSION_PATCHLEVEL := 0 -else -CLANG_HAS_VERSION_PATCHLEVEL := 1 -endif - -$(ObjDir)/Diagnostic%Kinds.inc.tmp : Diagnostic.td $(INPUT_TDS) $(CLANG_TBLGEN) $(ObjDir)/.dir - $(Echo) "Building Clang $(patsubst Diagnostic%Kinds.inc.tmp,%,$(@F)) diagnostic tables with tblgen" - $(Verb) $(ClangTableGen) -gen-clang-diags-defs -clang-component=$(patsubst Diagnostic%Kinds.inc.tmp,%,$(@F)) -o $(call SYSPATH, $@) $< - -$(ObjDir)/DiagnosticIndexName.inc.tmp : Diagnostic.td $(INPUT_TDS) $(CLANG_TBLGEN) $(ObjDir)/.dir - $(Echo) "Building Clang diagnostic name index with tblgen" - $(Verb) $(ClangTableGen) -gen-clang-diags-index-name -o $(call SYSPATH, $@) $< - -$(ObjDir)/DiagnosticGroups.inc.tmp : Diagnostic.td DiagnosticGroups.td $(INPUT_TDS) $(CLANG_TBLGEN) $(ObjDir)/.dir - $(Echo) "Building Clang diagnostic groups with tblgen" - $(Verb) $(ClangTableGen) -gen-clang-diag-groups -o $(call SYSPATH, $@) $< - -$(ObjDir)/AttrList.inc.tmp : Attr.td $(CLANG_TBLGEN) $(ObjDir)/.dir - $(Echo) "Building Clang attribute list with tblgen" - $(Verb) $(ClangTableGen) -gen-clang-attr-list -o $(call SYSPATH, $@) \ - -I $(PROJ_SRC_DIR)/../.. $< - -$(ObjDir)/AttrHasAttributeImpl.inc.tmp : Attr.td $(CLANG_TBLGEN) \ - $(ObjDir)/.dir - $(Echo) "Building Clang __has_attribute implementation with tblgen" - $(Verb) $(ClangTableGen) -gen-clang-attr-has-attribute-impl -o $(call SYSPATH, $@) \ - -I $(PROJ_SRC_DIR)/../../ $< - -$(ObjDir)/arm_neon.inc.tmp : arm_neon.td $(CLANG_TBLGEN) $(ObjDir)/.dir - $(Echo) "Building Clang arm_neon.inc with tblgen" - $(Verb) $(ClangTableGen) -gen-arm-neon-sema -o $(call SYSPATH, $@) \ - -I $(PROJ_SRC_DIR)/../.. $< - -$(ObjDir)/Version.inc.tmp : Version.inc.in Makefile $(LLVM_OBJ_ROOT)/Makefile.config $(ObjDir)/.dir - $(Echo) "Updating Clang version info." - $(Verb)sed -e "s#@CLANG_VERSION@#$(CLANG_VERSION)#g" \ - -e "s#@CLANG_VERSION_MAJOR@#$(CLANG_VERSION_MAJOR)#g" \ - -e "s#@CLANG_VERSION_MINOR@#$(CLANG_VERSION_MINOR)#g" \ - -e "s#@CLANG_VERSION_PATCHLEVEL@#$(CLANG_VERSION_PATCHLEVEL)#g" \ - -e "s#@CLANG_HAS_VERSION_PATCHLEVEL@#$(CLANG_HAS_VERSION_PATCHLEVEL)#g" \ - $< > $@ diff --git a/include/clang/Basic/ObjCRuntime.h b/include/clang/Basic/ObjCRuntime.h index cf51b146b1dc2..6975b6c9bb9e0 100644 --- a/include/clang/Basic/ObjCRuntime.h +++ b/include/clang/Basic/ObjCRuntime.h @@ -308,6 +308,23 @@ public: } } + /// Is objc_unsafeClaimAutoreleasedReturnValue available? + bool hasARCUnsafeClaimAutoreleasedReturnValue() const { + switch (getKind()) { + case MacOSX: + return getVersion() >= VersionTuple(10, 11); + case iOS: + return getVersion() >= VersionTuple(9); + case WatchOS: + return getVersion() >= VersionTuple(2); + case GNUstep: + return false; + + default: + return false; + } + } + /// \brief Try to parse an Objective-C runtime specification from the given /// string. /// diff --git a/include/clang/Basic/OpenCLExtensions.def b/include/clang/Basic/OpenCLExtensions.def index 91fd9195b1902..c5776d3bab43f 100644 --- a/include/clang/Basic/OpenCLExtensions.def +++ b/include/clang/Basic/OpenCLExtensions.def @@ -11,25 +11,71 @@ // //===----------------------------------------------------------------------===// +// Macro OPENCLEXT or OPENCLEXT_INTERNAL can be defined to enumerate the +// OpenCL extensions listed in this file. +// +// If the extensions are to be enumerated without the supported OpenCL version, +// define OPENCLEXT(ext) where ext is the name of the extension. +// +// If the extensions are to be enumerated with supported OpenCL version, +// define OPENCLEXT_INTERNAL(ext, avail, core) where +// ext - name of the extension or optional core feature. +// avail - minimum OpenCL version supporting it. +// core - minimum OpenCL version when the extension becomes optional core +// feature or core feature. ~0U indicates not a core feature or an +// optional core feature. + +#ifndef OPENCLEXT_INTERNAL +#ifndef OPENCLEXT +#pragma error "macro OPENCLEXT or OPENCLEXT_INTERNAL is required" +#else +#define OPENCLEXT_INTERNAL(ext, ...) OPENCLEXT(ext) +#endif // OPENCLEXT +#endif // OPENCLEXT_INTERNAL + +// OpenCL 1.0. +OPENCLEXT_INTERNAL(cl_khr_3d_image_writes, 100, 200) +// fprounding mode is special since it is not mentioned beyond 1.0 +OPENCLEXT_INTERNAL(cl_khr_select_fprounding_mode, 100, 110) +OPENCLEXT_INTERNAL(cl_khr_byte_addressable_store, 100, 110) +OPENCLEXT_INTERNAL(cl_khr_fp16, 100, ~0U) +OPENCLEXT_INTERNAL(cl_khr_fp64, 100, 120) +OPENCLEXT_INTERNAL(cl_khr_global_int32_base_atomics, 100, 110) +OPENCLEXT_INTERNAL(cl_khr_global_int32_extended_atomics, 100, 110) +OPENCLEXT_INTERNAL(cl_khr_local_int32_base_atomics, 100, 110) +OPENCLEXT_INTERNAL(cl_khr_local_int32_extended_atomics, 100, 110) +OPENCLEXT_INTERNAL(cl_khr_int64_base_atomics, 100, ~0U) +OPENCLEXT_INTERNAL(cl_khr_int64_extended_atomics, 100, ~0U) +OPENCLEXT_INTERNAL(cl_khr_gl_sharing, 100, ~0U) +OPENCLEXT_INTERNAL(cl_khr_icd, 100, ~0U) + // OpenCL 1.1. -OPENCLEXT(cl_khr_fp64) -OPENCLEXT(cl_khr_int64_base_atomics) -OPENCLEXT(cl_khr_int64_extended_atomics) -OPENCLEXT(cl_khr_fp16) -OPENCLEXT(cl_khr_gl_sharing) -OPENCLEXT(cl_khr_gl_event) -OPENCLEXT(cl_khr_d3d10_sharing) -OPENCLEXT(cl_khr_global_int32_base_atomics) -OPENCLEXT(cl_khr_global_int32_extended_atomics) -OPENCLEXT(cl_khr_local_int32_base_atomics) -OPENCLEXT(cl_khr_local_int32_extended_atomics) -OPENCLEXT(cl_khr_byte_addressable_store) -OPENCLEXT(cl_khr_3d_image_writes) - -// OpenCL 2.0 -OPENCLEXT(cl_khr_gl_msaa_sharing) +OPENCLEXT_INTERNAL(cl_khr_gl_event, 110, ~0U) +OPENCLEXT_INTERNAL(cl_khr_d3d10_sharing, 110, ~0U) + +// OpenCL 1.2. +OPENCLEXT_INTERNAL(cl_khr_context_abort, 120, ~0U) +OPENCLEXT_INTERNAL(cl_khr_d3d11_sharing, 120, ~0U) +OPENCLEXT_INTERNAL(cl_khr_depth_images, 120, ~0U) +OPENCLEXT_INTERNAL(cl_khr_dx9_media_sharing, 120, ~0U) +OPENCLEXT_INTERNAL(cl_khr_image2d_from_buffer, 120, ~0U) +OPENCLEXT_INTERNAL(cl_khr_initialize_memory, 120, ~0U) +OPENCLEXT_INTERNAL(cl_khr_gl_depth_images, 120, ~0U) +OPENCLEXT_INTERNAL(cl_khr_gl_msaa_sharing, 120, ~0U) +OPENCLEXT_INTERNAL(cl_khr_spir, 120, ~0U) + +// OpenCL 2.0. +OPENCLEXT_INTERNAL(cl_khr_egl_event, 200, ~0U) +OPENCLEXT_INTERNAL(cl_khr_egl_image, 200, ~0U) +OPENCLEXT_INTERNAL(cl_khr_srgb_image_writes, 200, ~0U) +OPENCLEXT_INTERNAL(cl_khr_subgroups, 200, ~0U) +OPENCLEXT_INTERNAL(cl_khr_terminate_context, 200, ~0U) // Clang Extensions. -OPENCLEXT(cl_clang_storage_class_specifiers) +OPENCLEXT_INTERNAL(cl_clang_storage_class_specifiers, 100, ~0U) + +#undef OPENCLEXT_INTERNAL +#ifdef OPENCLEXT #undef OPENCLEXT +#endif diff --git a/include/clang/Basic/OpenCLImageTypes.def b/include/clang/Basic/OpenCLImageTypes.def new file mode 100644 index 0000000000000..9b929929e2bac --- /dev/null +++ b/include/clang/Basic/OpenCLImageTypes.def @@ -0,0 +1,82 @@ +//===-- OpenCLImageTypes.def - Metadata about BuiltinTypes ------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// This file extends builtin types database with OpenCL image singleton types. +// Custom code should define one of those two macros: +// GENERIC_IMAGE_TYPE(Type, Id) - a generic image with its Id without an +// access type +// IMAGE_TYPE(Type, Id, SingletonId, AccessType, CGSuffix) - an image type +// with given ID, singleton ID access type and a codegen suffix + +#ifdef GENERIC_IMAGE_TYPE + +#define IMAGE_READ_TYPE(Type, Id) GENERIC_IMAGE_TYPE(Type, Id) +#define IMAGE_WRITE_TYPE(Type, Id) +#define IMAGE_READ_WRITE_TYPE(Type, Id) + +#else + +#ifndef IMAGE_READ_TYPE +#define IMAGE_READ_TYPE(Type, Id) \ + IMAGE_TYPE(Type, Id##RO, Id##ROTy, read_only, ro) +#endif +#ifndef IMAGE_WRITE_TYPE +#define IMAGE_WRITE_TYPE(Type, Id) \ + IMAGE_TYPE(Type, Id##WO, Id##WOTy, write_only, wo) +#endif +#ifndef IMAGE_READ_WRITE_TYPE +#define IMAGE_READ_WRITE_TYPE(Type, Id) \ + IMAGE_TYPE(Type, Id##RW, Id##RWTy, read_write, rw) +#endif + +#endif + +IMAGE_READ_TYPE(image1d, OCLImage1d) +IMAGE_READ_TYPE(image1d_array, OCLImage1dArray) +IMAGE_READ_TYPE(image1d_buffer, OCLImage1dBuffer) +IMAGE_READ_TYPE(image2d, OCLImage2d) +IMAGE_READ_TYPE(image2d_array, OCLImage2dArray) +IMAGE_READ_TYPE(image2d_depth, OCLImage2dDepth) +IMAGE_READ_TYPE(image2d_array_depth, OCLImage2dArrayDepth) +IMAGE_READ_TYPE(image2d_msaa, OCLImage2dMSAA) +IMAGE_READ_TYPE(image2d_array_msaa, OCLImage2dArrayMSAA) +IMAGE_READ_TYPE(image2d_msaa_depth, OCLImage2dMSAADepth) +IMAGE_READ_TYPE(image2d_array_msaa_depth, OCLImage2dArrayMSAADepth) +IMAGE_READ_TYPE(image3d, OCLImage3d) + +IMAGE_WRITE_TYPE(image1d, OCLImage1d) +IMAGE_WRITE_TYPE(image1d_array, OCLImage1dArray) +IMAGE_WRITE_TYPE(image1d_buffer, OCLImage1dBuffer) +IMAGE_WRITE_TYPE(image2d, OCLImage2d) +IMAGE_WRITE_TYPE(image2d_array, OCLImage2dArray) +IMAGE_WRITE_TYPE(image2d_depth, OCLImage2dDepth) +IMAGE_WRITE_TYPE(image2d_array_depth, OCLImage2dArrayDepth) +IMAGE_WRITE_TYPE(image2d_msaa, OCLImage2dMSAA) +IMAGE_WRITE_TYPE(image2d_array_msaa, OCLImage2dArrayMSAA) +IMAGE_WRITE_TYPE(image2d_msaa_depth, OCLImage2dMSAADepth) +IMAGE_WRITE_TYPE(image2d_array_msaa_depth, OCLImage2dArrayMSAADepth) +IMAGE_WRITE_TYPE(image3d, OCLImage3d) + +IMAGE_READ_WRITE_TYPE(image1d, OCLImage1d) +IMAGE_READ_WRITE_TYPE(image1d_array, OCLImage1dArray) +IMAGE_READ_WRITE_TYPE(image1d_buffer, OCLImage1dBuffer) +IMAGE_READ_WRITE_TYPE(image2d, OCLImage2d) +IMAGE_READ_WRITE_TYPE(image2d_array, OCLImage2dArray) +IMAGE_READ_WRITE_TYPE(image2d_depth, OCLImage2dDepth) +IMAGE_READ_WRITE_TYPE(image2d_array_depth, OCLImage2dArrayDepth) +IMAGE_READ_WRITE_TYPE(image2d_msaa, OCLImage2dMSAA) +IMAGE_READ_WRITE_TYPE(image2d_array_msaa, OCLImage2dArrayMSAA) +IMAGE_READ_WRITE_TYPE(image2d_msaa_depth, OCLImage2dMSAADepth) +IMAGE_READ_WRITE_TYPE(image2d_array_msaa_depth, OCLImage2dArrayMSAADepth) +IMAGE_READ_WRITE_TYPE(image3d, OCLImage3d) + +#undef IMAGE_TYPE +#undef GENERIC_IMAGE_TYPE +#undef IMAGE_READ_TYPE +#undef IMAGE_WRITE_TYPE +#undef IMAGE_READ_WRITE_TYPE
\ No newline at end of file diff --git a/include/clang/Basic/OpenCLOptions.h b/include/clang/Basic/OpenCLOptions.h new file mode 100644 index 0000000000000..4aaa3d74ccbf1 --- /dev/null +++ b/include/clang/Basic/OpenCLOptions.h @@ -0,0 +1,68 @@ +//===--- OpenCLOptions.h ----------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// \brief Defines the clang::OpenCLOptions class. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_BASIC_OPENCLOPTIONS_H +#define LLVM_CLANG_BASIC_OPENCLOPTIONS_H + +#include <string> +#include <vector> + +namespace clang { + +/// \brief OpenCL supported extensions and optional core features +class OpenCLOptions { +public: +#define OPENCLEXT(nm) unsigned nm : 1; +#include "clang/Basic/OpenCLExtensions.def" + + OpenCLOptions() { +#define OPENCLEXT(nm) nm = 0; +#include "clang/Basic/OpenCLExtensions.def" + } + + // Enable all options. + void setAll() { +#define OPENCLEXT(nm) nm = 1; +#include "clang/Basic/OpenCLExtensions.def" + } + + // Is supported with OpenCL version \p OCLVer. +#define OPENCLEXT_INTERNAL(Ext, Avail, ...) \ + bool is_##Ext##_supported(unsigned OCLVer) const { \ + return Ext && OCLVer >= Avail; \ + } +#include "clang/Basic/OpenCLExtensions.def" + + + // Is supported OpenCL extension with OpenCL version \p OCLVer. + // For supported optional core feature, return false. +#define OPENCLEXT_INTERNAL(Ext, Avail, Core) \ + bool is_##Ext##_supported_extension(unsigned CLVer) const { \ + return is_##Ext##_supported(CLVer) && (Core == ~0U || CLVer < Core); \ + } +#include "clang/Basic/OpenCLExtensions.def" + + // Is supported OpenCL core features with OpenCL version \p OCLVer. + // For supported extension, return false. +#define OPENCLEXT_INTERNAL(Ext, Avail, Core) \ + bool is_##Ext##_supported_core(unsigned CLVer) const { \ + return is_##Ext##_supported(CLVer) && Core != ~0U && CLVer >= Core; \ + } +#include "clang/Basic/OpenCLExtensions.def" + +}; + +} // end namespace clang + +#endif diff --git a/include/clang/Basic/OpenMPKinds.def b/include/clang/Basic/OpenMPKinds.def index 44f77ad32fd4f..5189779809b8d 100644 --- a/include/clang/Basic/OpenMPKinds.def +++ b/include/clang/Basic/OpenMPKinds.def @@ -60,6 +60,21 @@ #ifndef OPENMP_TARGET_DATA_CLAUSE # define OPENMP_TARGET_DATA_CLAUSE(Name) #endif +#ifndef OPENMP_TARGET_ENTER_DATA_CLAUSE +#define OPENMP_TARGET_ENTER_DATA_CLAUSE(Name) +#endif +#ifndef OPENMP_TARGET_EXIT_DATA_CLAUSE +#define OPENMP_TARGET_EXIT_DATA_CLAUSE(Name) +#endif +#ifndef OPENMP_TARGET_PARALLEL_CLAUSE +# define OPENMP_TARGET_PARALLEL_CLAUSE(Name) +#endif +#ifndef OPENMP_TARGET_PARALLEL_FOR_CLAUSE +# define OPENMP_TARGET_PARALLEL_FOR_CLAUSE(Name) +#endif +#ifndef OPENMP_TARGET_UPDATE_CLAUSE +# define OPENMP_TARGET_UPDATE_CLAUSE(Name) +#endif #ifndef OPENMP_TEAMS_CLAUSE # define OPENMP_TEAMS_CLAUSE(Name) #endif @@ -102,6 +117,27 @@ #ifndef OPENMP_MAP_KIND #define OPENMP_MAP_KIND(Name) #endif +#ifndef OPENMP_DIST_SCHEDULE_KIND +#define OPENMP_DIST_SCHEDULE_KIND(Name) +#endif +#ifndef OPENMP_DEFAULTMAP_KIND +#define OPENMP_DEFAULTMAP_KIND(Name) +#endif +#ifndef OPENMP_DEFAULTMAP_MODIFIER +#define OPENMP_DEFAULTMAP_MODIFIER(Name) +#endif +#ifndef OPENMP_DISTRIBUTE_PARALLEL_FOR_CLAUSE +#define OPENMP_DISTRIBUTE_PARALLEL_FOR_CLAUSE(Name) +#endif +#ifndef OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE +#define OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(Name) +#endif +#ifndef OPENMP_DISTRIBUTE_SIMD_CLAUSE +#define OPENMP_DISTRIBUTE_SIMD_CLAUSE(Name) +#endif +#ifndef OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE +#define OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(Name) +#endif // OpenMP directives. OPENMP_DIRECTIVE(threadprivate) @@ -125,14 +161,27 @@ OPENMP_DIRECTIVE(target) OPENMP_DIRECTIVE(teams) OPENMP_DIRECTIVE(cancel) OPENMP_DIRECTIVE_EXT(target_data, "target data") +OPENMP_DIRECTIVE_EXT(target_enter_data, "target enter data") +OPENMP_DIRECTIVE_EXT(target_exit_data, "target exit data") +OPENMP_DIRECTIVE_EXT(target_parallel, "target parallel") +OPENMP_DIRECTIVE_EXT(target_parallel_for, "target parallel for") +OPENMP_DIRECTIVE_EXT(target_update, "target update") OPENMP_DIRECTIVE_EXT(parallel_for, "parallel for") OPENMP_DIRECTIVE_EXT(parallel_for_simd, "parallel for simd") OPENMP_DIRECTIVE_EXT(parallel_sections, "parallel sections") OPENMP_DIRECTIVE_EXT(for_simd, "for simd") OPENMP_DIRECTIVE_EXT(cancellation_point, "cancellation point") +OPENMP_DIRECTIVE_EXT(declare_reduction, "declare reduction") +OPENMP_DIRECTIVE_EXT(declare_simd, "declare simd") OPENMP_DIRECTIVE(taskloop) OPENMP_DIRECTIVE_EXT(taskloop_simd, "taskloop simd") OPENMP_DIRECTIVE(distribute) +OPENMP_DIRECTIVE_EXT(declare_target, "declare target") +OPENMP_DIRECTIVE_EXT(end_declare_target, "end declare target") +OPENMP_DIRECTIVE_EXT(distribute_parallel_for, "distribute parallel for") +OPENMP_DIRECTIVE_EXT(distribute_parallel_for_simd, "distribute parallel for simd") +OPENMP_DIRECTIVE_EXT(distribute_simd, "distribute simd") +OPENMP_DIRECTIVE_EXT(target_parallel_for_simd, "target parallel for simd") // OpenMP clauses. OPENMP_CLAUSE(if, OMPIfClause) @@ -175,6 +224,12 @@ OPENMP_CLAUSE(grainsize, OMPGrainsizeClause) OPENMP_CLAUSE(nogroup, OMPNogroupClause) OPENMP_CLAUSE(num_tasks, OMPNumTasksClause) OPENMP_CLAUSE(hint, OMPHintClause) +OPENMP_CLAUSE(dist_schedule, OMPDistScheduleClause) +OPENMP_CLAUSE(defaultmap, OMPDefaultmapClause) +OPENMP_CLAUSE(to, OMPToClause) +OPENMP_CLAUSE(from, OMPFromClause) +OPENMP_CLAUSE(use_device_ptr, OMPUseDevicePtrClause) +OPENMP_CLAUSE(is_device_ptr, OMPIsDevicePtrClause) // Clauses allowed for OpenMP directive 'parallel'. OPENMP_PARALLEL_CLAUSE(if) @@ -259,6 +314,12 @@ OPENMP_SCHEDULE_MODIFIER(monotonic) OPENMP_SCHEDULE_MODIFIER(nonmonotonic) OPENMP_SCHEDULE_MODIFIER(simd) +// Static attributes for 'defaultmap' clause. +OPENMP_DEFAULTMAP_KIND(scalar) + +// Modifiers for 'defaultmap' clause. +OPENMP_DEFAULTMAP_MODIFIER(tofrom) + // Static attributes for 'depend' clause. OPENMP_DEPEND_KIND(in) OPENMP_DEPEND_KIND(out) @@ -338,16 +399,82 @@ OPENMP_ATOMIC_CLAUSE(capture) OPENMP_ATOMIC_CLAUSE(seq_cst) // Clauses allowed for OpenMP directive 'target'. -// TODO More clauses for 'target' directive. OPENMP_TARGET_CLAUSE(if) OPENMP_TARGET_CLAUSE(device) OPENMP_TARGET_CLAUSE(map) +OPENMP_TARGET_CLAUSE(private) +OPENMP_TARGET_CLAUSE(nowait) +OPENMP_TARGET_CLAUSE(depend) +OPENMP_TARGET_CLAUSE(defaultmap) +OPENMP_TARGET_CLAUSE(firstprivate) +OPENMP_TARGET_CLAUSE(is_device_ptr) // Clauses allowed for OpenMP directive 'target data'. // TODO More clauses for 'target data' directive. OPENMP_TARGET_DATA_CLAUSE(if) OPENMP_TARGET_DATA_CLAUSE(device) OPENMP_TARGET_DATA_CLAUSE(map) +OPENMP_TARGET_DATA_CLAUSE(use_device_ptr) + +// Clauses allowed for OpenMP directive 'target enter data'. +OPENMP_TARGET_ENTER_DATA_CLAUSE(if) +OPENMP_TARGET_ENTER_DATA_CLAUSE(device) +OPENMP_TARGET_ENTER_DATA_CLAUSE(map) +OPENMP_TARGET_ENTER_DATA_CLAUSE(nowait) +OPENMP_TARGET_ENTER_DATA_CLAUSE(depend) + +// Clauses allowed for OpenMP directive 'target exit data'. +OPENMP_TARGET_EXIT_DATA_CLAUSE(if) +OPENMP_TARGET_EXIT_DATA_CLAUSE(device) +OPENMP_TARGET_EXIT_DATA_CLAUSE(map) +OPENMP_TARGET_EXIT_DATA_CLAUSE(nowait) +OPENMP_TARGET_EXIT_DATA_CLAUSE(depend) + +// Clauses allowed for OpenMP directive 'target parallel'. +// TODO: add target clauses 'is_device_ptr' +OPENMP_TARGET_PARALLEL_CLAUSE(if) +OPENMP_TARGET_PARALLEL_CLAUSE(device) +OPENMP_TARGET_PARALLEL_CLAUSE(map) +OPENMP_TARGET_PARALLEL_CLAUSE(private) +OPENMP_TARGET_PARALLEL_CLAUSE(firstprivate) +OPENMP_TARGET_PARALLEL_CLAUSE(nowait) +OPENMP_TARGET_PARALLEL_CLAUSE(depend) +OPENMP_TARGET_PARALLEL_CLAUSE(defaultmap) +OPENMP_TARGET_PARALLEL_CLAUSE(num_threads) +OPENMP_TARGET_PARALLEL_CLAUSE(default) +OPENMP_TARGET_PARALLEL_CLAUSE(proc_bind) +OPENMP_TARGET_PARALLEL_CLAUSE(shared) +OPENMP_TARGET_PARALLEL_CLAUSE(reduction) + +// Clauses allowed for OpenMP directive 'target parallel for'. +// TODO: add target clauses 'is_device_ptr' +OPENMP_TARGET_PARALLEL_FOR_CLAUSE(if) +OPENMP_TARGET_PARALLEL_FOR_CLAUSE(device) +OPENMP_TARGET_PARALLEL_FOR_CLAUSE(map) +OPENMP_TARGET_PARALLEL_FOR_CLAUSE(private) +OPENMP_TARGET_PARALLEL_FOR_CLAUSE(firstprivate) +OPENMP_TARGET_PARALLEL_FOR_CLAUSE(lastprivate) +OPENMP_TARGET_PARALLEL_FOR_CLAUSE(nowait) +OPENMP_TARGET_PARALLEL_FOR_CLAUSE(depend) +OPENMP_TARGET_PARALLEL_FOR_CLAUSE(defaultmap) +OPENMP_TARGET_PARALLEL_FOR_CLAUSE(num_threads) +OPENMP_TARGET_PARALLEL_FOR_CLAUSE(default) +OPENMP_TARGET_PARALLEL_FOR_CLAUSE(proc_bind) +OPENMP_TARGET_PARALLEL_FOR_CLAUSE(shared) +OPENMP_TARGET_PARALLEL_FOR_CLAUSE(reduction) +OPENMP_TARGET_PARALLEL_FOR_CLAUSE(collapse) +OPENMP_TARGET_PARALLEL_FOR_CLAUSE(schedule) +OPENMP_TARGET_PARALLEL_FOR_CLAUSE(ordered) +OPENMP_TARGET_PARALLEL_FOR_CLAUSE(linear) + +// Clauses allowed for OpenMP directive 'target update'. +// TODO More clauses for 'target update' directive. +OPENMP_TARGET_UPDATE_CLAUSE(if) +OPENMP_TARGET_UPDATE_CLAUSE(device) +OPENMP_TARGET_UPDATE_CLAUSE(to) +OPENMP_TARGET_UPDATE_CLAUSE(from) +OPENMP_TARGET_UPDATE_CLAUSE(nowait) +OPENMP_TARGET_UPDATE_CLAUSE(depend) // Clauses allowed for OpenMP directive 'teams'. // TODO More clauses for 'teams' directive. @@ -418,6 +545,80 @@ OPENMP_DISTRIBUTE_CLAUSE(private) OPENMP_DISTRIBUTE_CLAUSE(firstprivate) OPENMP_DISTRIBUTE_CLAUSE(lastprivate) OPENMP_DISTRIBUTE_CLAUSE(collapse) +OPENMP_DISTRIBUTE_CLAUSE(dist_schedule) + +// Static attributes for 'dist_schedule' clause. +OPENMP_DIST_SCHEDULE_KIND(static) + +// Clauses allowed for OpenMP directive 'distribute parallel for' +OPENMP_DISTRIBUTE_PARALLEL_FOR_CLAUSE(firstprivate) +OPENMP_DISTRIBUTE_PARALLEL_FOR_CLAUSE(lastprivate) +OPENMP_DISTRIBUTE_PARALLEL_FOR_CLAUSE(collapse) +OPENMP_DISTRIBUTE_PARALLEL_FOR_CLAUSE(dist_schedule) +OPENMP_DISTRIBUTE_PARALLEL_FOR_CLAUSE(if) +OPENMP_DISTRIBUTE_PARALLEL_FOR_CLAUSE(num_threads) +OPENMP_DISTRIBUTE_PARALLEL_FOR_CLAUSE(default) +OPENMP_DISTRIBUTE_PARALLEL_FOR_CLAUSE(proc_bind) +OPENMP_DISTRIBUTE_PARALLEL_FOR_CLAUSE(private) +OPENMP_DISTRIBUTE_PARALLEL_FOR_CLAUSE(shared) +OPENMP_DISTRIBUTE_PARALLEL_FOR_CLAUSE(reduction) +OPENMP_DISTRIBUTE_PARALLEL_FOR_CLAUSE(copyin) +OPENMP_DISTRIBUTE_PARALLEL_FOR_CLAUSE(schedule) + +// Clauses allowed for OpenMP directive 'distribute parallel for simd' +OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(firstprivate) +OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(lastprivate) +OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(collapse) +OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(dist_schedule) +OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(if) +OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(num_threads) +OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(default) +OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(proc_bind) +OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(private) +OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(shared) +OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(reduction) +OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(copyin) +OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(schedule) +OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(linear) +OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(aligned) +OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(safelen) +OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(simdlen) + +// Clauses allowed for OpenMP directive 'distribute simd' +OPENMP_DISTRIBUTE_SIMD_CLAUSE(private) +OPENMP_DISTRIBUTE_SIMD_CLAUSE(firstprivate) +OPENMP_DISTRIBUTE_SIMD_CLAUSE(lastprivate) +OPENMP_DISTRIBUTE_SIMD_CLAUSE(collapse) +OPENMP_DISTRIBUTE_SIMD_CLAUSE(dist_schedule) +OPENMP_DISTRIBUTE_SIMD_CLAUSE(linear) +OPENMP_DISTRIBUTE_SIMD_CLAUSE(aligned) +OPENMP_DISTRIBUTE_SIMD_CLAUSE(safelen) +OPENMP_DISTRIBUTE_SIMD_CLAUSE(simdlen) +OPENMP_DISTRIBUTE_SIMD_CLAUSE(reduction) + +// Clauses allowed for OpenMP directive 'target parallel for simd'. +// TODO: add target clauses 'is_device_ptr' +OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(if) +OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(device) +OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(map) +OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(private) +OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(firstprivate) +OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(lastprivate) +OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(nowait) +OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(depend) +OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(defaultmap) +OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(num_threads) +OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(default) +OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(proc_bind) +OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(shared) +OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(reduction) +OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(collapse) +OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(schedule) +OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(ordered) +OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(linear) +OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(safelen) +OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(simdlen) +OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(aligned) #undef OPENMP_TASKLOOP_SIMD_CLAUSE #undef OPENMP_TASKLOOP_CLAUSE @@ -443,9 +644,21 @@ OPENMP_DISTRIBUTE_CLAUSE(collapse) #undef OPENMP_ATOMIC_CLAUSE #undef OPENMP_TARGET_CLAUSE #undef OPENMP_TARGET_DATA_CLAUSE +#undef OPENMP_TARGET_ENTER_DATA_CLAUSE +#undef OPENMP_TARGET_EXIT_DATA_CLAUSE +#undef OPENMP_TARGET_PARALLEL_CLAUSE +#undef OPENMP_TARGET_PARALLEL_FOR_CLAUSE #undef OPENMP_TEAMS_CLAUSE #undef OPENMP_SIMD_CLAUSE #undef OPENMP_FOR_CLAUSE #undef OPENMP_FOR_SIMD_CLAUSE #undef OPENMP_MAP_KIND #undef OPENMP_DISTRIBUTE_CLAUSE +#undef OPENMP_DIST_SCHEDULE_KIND +#undef OPENMP_DEFAULTMAP_KIND +#undef OPENMP_DEFAULTMAP_MODIFIER +#undef OPENMP_TARGET_UPDATE_CLAUSE +#undef OPENMP_DISTRIBUTE_PARALLEL_FOR_CLAUSE +#undef OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE +#undef OPENMP_DISTRIBUTE_SIMD_CLAUSE +#undef OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE diff --git a/include/clang/Basic/OpenMPKinds.h b/include/clang/Basic/OpenMPKinds.h index d4d3db80329d4..0a8e890b7c440 100644 --- a/include/clang/Basic/OpenMPKinds.h +++ b/include/clang/Basic/OpenMPKinds.h @@ -35,6 +35,7 @@ enum OpenMPClauseKind { OMPC_##Name, #include "clang/Basic/OpenMPKinds.def" OMPC_threadprivate, + OMPC_uniform, OMPC_unknown }; @@ -95,6 +96,37 @@ enum OpenMPMapClauseKind { OMPC_MAP_unknown }; +/// \brief OpenMP attributes for 'dist_schedule' clause. +enum OpenMPDistScheduleClauseKind { +#define OPENMP_DIST_SCHEDULE_KIND(Name) OMPC_DIST_SCHEDULE_##Name, +#include "clang/Basic/OpenMPKinds.def" + OMPC_DIST_SCHEDULE_unknown +}; + +/// \brief OpenMP attributes for 'defaultmap' clause. +enum OpenMPDefaultmapClauseKind { +#define OPENMP_DEFAULTMAP_KIND(Name) \ + OMPC_DEFAULTMAP_##Name, +#include "clang/Basic/OpenMPKinds.def" + OMPC_DEFAULTMAP_unknown +}; + +/// \brief OpenMP modifiers for 'defaultmap' clause. +enum OpenMPDefaultmapClauseModifier { + OMPC_DEFAULTMAP_MODIFIER_unknown = OMPC_DEFAULTMAP_unknown, +#define OPENMP_DEFAULTMAP_MODIFIER(Name) \ + OMPC_DEFAULTMAP_MODIFIER_##Name, +#include "clang/Basic/OpenMPKinds.def" + OMPC_DEFAULTMAP_MODIFIER_last +}; + +/// Scheduling data for loop-based OpenMP directives. +struct OpenMPScheduleTy final { + OpenMPScheduleClauseKind Schedule = OMPC_SCHEDULE_unknown; + OpenMPScheduleClauseModifier M1 = OMPC_SCHEDULE_MODIFIER_unknown; + OpenMPScheduleClauseModifier M2 = OMPC_SCHEDULE_MODIFIER_unknown; +}; + OpenMPDirectiveKind getOpenMPDirectiveKind(llvm::StringRef Str); const char *getOpenMPDirectiveName(OpenMPDirectiveKind Kind); @@ -132,11 +164,20 @@ bool isOpenMPTaskLoopDirective(OpenMPDirectiveKind DKind); /// parallel', otherwise - false. bool isOpenMPParallelDirective(OpenMPDirectiveKind DKind); -/// \brief Checks if the specified directive is a target-kind directive. +/// \brief Checks if the specified directive is a target code offload directive. /// \param DKind Specified directive. -/// \return true - the directive is a target-like directive like 'omp target', +/// \return true - the directive is a target code offload directive like +/// 'omp target', 'omp target parallel', 'omp target xxx' /// otherwise - false. -bool isOpenMPTargetDirective(OpenMPDirectiveKind DKind); +bool isOpenMPTargetExecutionDirective(OpenMPDirectiveKind DKind); + +/// \brief Checks if the specified directive is a target data offload directive. +/// \param DKind Specified directive. +/// \return true - the directive is a target data offload directive like +/// 'omp target data', 'omp target update', 'omp target enter data', +/// 'omp target exit data' +/// otherwise - false. +bool isOpenMPTargetDataManagementDirective(OpenMPDirectiveKind DKind); /// \brief Checks if the specified directive is a teams-kind directive. /// \param DKind Specified directive. @@ -169,6 +210,14 @@ bool isOpenMPPrivate(OpenMPClauseKind Kind); /// \return true - the clause is a threadprivate clause, otherwise - false. bool isOpenMPThreadPrivate(OpenMPClauseKind Kind); +/// Checks if the specified directive kind is one of tasking directives - task, +/// taskloop or taksloop simd. +bool isOpenMPTaskingDirective(OpenMPDirectiveKind Kind); + +/// Checks if the specified directive kind is one of the composite or combined +/// directives that need loop bound sharing across loops outlined in nested +/// functions +bool isOpenMPLoopBoundSharingDirective(OpenMPDirectiveKind Kind); } #endif diff --git a/include/clang/Basic/PragmaKinds.h b/include/clang/Basic/PragmaKinds.h new file mode 100644 index 0000000000000..b373a9e4e29e8 --- /dev/null +++ b/include/clang/Basic/PragmaKinds.h @@ -0,0 +1,31 @@ +//===--- PragmaKinds.h - #pragma comment() kinds ---------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_BASIC_PRAGMA_KINDS_H +#define LLVM_CLANG_BASIC_PRAGMA_KINDS_H + +namespace clang { + +enum PragmaMSCommentKind { + PCK_Unknown, + PCK_Linker, // #pragma comment(linker, ...) + PCK_Lib, // #pragma comment(lib, ...) + PCK_Compiler, // #pragma comment(compiler, ...) + PCK_ExeStr, // #pragma comment(exestr, ...) + PCK_User // #pragma comment(user, ...) +}; + +enum PragmaMSStructKind { + PMSST_OFF, // #pragms ms_struct off + PMSST_ON // #pragms ms_struct on +}; + +} + +#endif diff --git a/include/clang/Basic/Sanitizers.def b/include/clang/Basic/Sanitizers.def index 4b68593629109..c81273ea5fd48 100644 --- a/include/clang/Basic/Sanitizers.def +++ b/include/clang/Basic/Sanitizers.def @@ -114,6 +114,13 @@ SANITIZER_GROUP("integer", Integer, SANITIZER("local-bounds", LocalBounds) SANITIZER_GROUP("bounds", Bounds, ArrayBounds | LocalBounds) +// EfficiencySanitizer +SANITIZER("efficiency-cache-frag", EfficiencyCacheFrag) +SANITIZER("efficiency-working-set", EfficiencyWorkingSet) +// Meta-group only used internally. +SANITIZER_GROUP("efficiency-all", Efficiency, + EfficiencyCacheFrag | EfficiencyWorkingSet) + // 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/Sanitizers.h b/include/clang/Basic/Sanitizers.h index 98e70dee45e54..bfa8e516edd3a 100644 --- a/include/clang/Basic/Sanitizers.h +++ b/include/clang/Basic/Sanitizers.h @@ -46,8 +46,6 @@ enum SanitizerOrdinal : uint64_t { } struct SanitizerSet { - SanitizerSet() : Mask(0) {} - /// \brief Check if a certain (single) sanitizer is enabled. bool has(SanitizerMask K) const { assert(llvm::isPowerOf2_64(K)); @@ -70,7 +68,7 @@ struct SanitizerSet { bool empty() const { return Mask == 0; } /// \brief Bitmask of enabled sanitizers. - SanitizerMask Mask; + SanitizerMask Mask = 0; }; /// Parse a single value from a -fsanitize= or -fno-sanitize= value list. diff --git a/include/clang/Basic/SourceLocation.h b/include/clang/Basic/SourceLocation.h index 0aeba5e3f3722..006cf3dc950c6 100644 --- a/include/clang/Basic/SourceLocation.h +++ b/include/clang/Basic/SourceLocation.h @@ -373,22 +373,22 @@ public: /// \brief Return the presumed filename of this location. /// /// This can be affected by \#line etc. - const char *getFilename() const { return Filename; } + const char *getFilename() const { assert(isValid()); return Filename; } /// \brief Return the presumed line number of this location. /// /// This can be affected by \#line etc. - unsigned getLine() const { return Line; } + unsigned getLine() const { assert(isValid()); return Line; } /// \brief Return the presumed column number of this location. /// /// This cannot be affected by \#line, but is packaged here for convenience. - unsigned getColumn() const { return Col; } + unsigned getColumn() const { assert(isValid()); return Col; } /// \brief Return the presumed include location of this location. /// /// This can be affected by GNU linemarker directives. - SourceLocation getIncludeLoc() const { return IncludeLoc; } + SourceLocation getIncludeLoc() const { assert(isValid()); return IncludeLoc; } }; diff --git a/include/clang/Basic/SourceManager.h b/include/clang/Basic/SourceManager.h index 99392a0982743..23ad73894fd36 100644 --- a/include/clang/Basic/SourceManager.h +++ b/include/clang/Basic/SourceManager.h @@ -61,7 +61,6 @@ class SourceManager; class FileManager; class FileEntry; class LineTableInfo; -class LangOptions; class ASTWriter; class ASTReader; @@ -798,6 +797,15 @@ public: IncludeLoc, FileCharacter, LoadedID, LoadedOffset); } + /// \brief Get the FileID for \p SourceFile if it exists. Otherwise, create a + /// new FileID for the \p SourceFile. + FileID getOrCreateFileID(const FileEntry *SourceFile, + SrcMgr::CharacteristicKind FileCharacter) { + FileID ID = translateFile(SourceFile); + return ID.isValid() ? ID : createFileID(SourceFile, SourceLocation(), + FileCharacter); + } + /// \brief Return a new SourceLocation that encodes the /// fact that a token from SpellingLoc should actually be referenced from /// ExpansionLoc, and that it represents the expansion of a macro argument diff --git a/include/clang/Basic/Specifiers.h b/include/clang/Basic/Specifiers.h index e284171f77734..fffd4b1cd20b3 100644 --- a/include/clang/Basic/Specifiers.h +++ b/include/clang/Basic/Specifiers.h @@ -54,6 +54,7 @@ namespace clang { TST_half, // OpenCL half, ARM NEON __fp16 TST_float, TST_double, + TST_float128, TST_bool, // _Bool TST_decimal32, // _Decimal32 TST_decimal64, // _Decimal64 @@ -73,16 +74,18 @@ namespace clang { TST_auto_type, // __auto_type extension TST_unknown_anytype, // __unknown_anytype extension TST_atomic, // C11 _Atomic - TST_error // erroneous type +#define GENERIC_IMAGE_TYPE(ImgType, Id) TST_##ImgType##_t, // OpenCL image types +#include "clang/Basic/OpenCLImageTypes.def" + TST_error // erroneous type }; - + /// \brief Structure that packs information about the type specifiers that /// were written in a particular type specifier sequence. struct WrittenBuiltinSpecs { /*DeclSpec::TST*/ unsigned Type : 5; /*DeclSpec::TSS*/ unsigned Sign : 2; /*DeclSpec::TSW*/ unsigned Width : 2; - bool ModeAttr : 1; + unsigned ModeAttr : 1; }; /// \brief A C++ access specifier (public, private, protected), plus the @@ -238,7 +241,10 @@ namespace clang { CC_AAPCS_VFP, // __attribute__((pcs("aapcs-vfp"))) CC_IntelOclBicc, // __attribute__((intel_ocl_bicc)) CC_SpirFunction, // default for OpenCL functions on SPIR target - CC_SpirKernel // inferred for OpenCL kernels on SPIR target + CC_OpenCLKernel, // inferred for OpenCL kernels + CC_Swift, // __attribute__((swiftcall)) + CC_PreserveMost, // __attribute__((preserve_most)) + CC_PreserveAll, // __attribute__((preserve_all)) }; /// \brief Checks whether the given calling convention supports variadic @@ -251,7 +257,8 @@ namespace clang { case CC_X86Pascal: case CC_X86VectorCall: case CC_SpirFunction: - case CC_SpirKernel: + case CC_OpenCLKernel: + case CC_Swift: return false; default: return true; @@ -283,6 +290,28 @@ namespace clang { /// Retrieve the spelling of the given nullability kind. llvm::StringRef getNullabilitySpelling(NullabilityKind kind, bool isContextSensitive = false); + + /// \brief Kinds of parameter ABI. + enum class ParameterABI { + /// This parameter uses ordinary ABI rules for its type. + Ordinary, + + /// This parameter (which must have pointer type) is a Swift + /// indirect result parameter. + SwiftIndirectResult, + + /// This parameter (which must have pointer-to-pointer type) uses + /// the special Swift error-result ABI treatment. There can be at + /// most one parameter on a given function that uses this treatment. + SwiftErrorResult, + + /// This parameter (which must have pointer type) uses the special + /// Swift context-pointer ABI treatment. There can be at + /// most one parameter on a given function that uses this treatment. + SwiftContext + }; + + llvm::StringRef getParameterABISpelling(ParameterABI kind); } // end namespace clang #endif // LLVM_CLANG_BASIC_SPECIFIERS_H diff --git a/include/clang/Basic/StmtNodes.td b/include/clang/Basic/StmtNodes.td index 36519ea29c98b..973b3bb6fd172 100644 --- a/include/clang/Basic/StmtNodes.td +++ b/include/clang/Basic/StmtNodes.td @@ -126,6 +126,7 @@ def ArrayTypeTraitExpr : DStmt<Expr>; def ExpressionTraitExpr : DStmt<Expr>; def DependentScopeDeclRefExpr : DStmt<Expr>; def CXXConstructExpr : DStmt<Expr>; +def CXXInheritedCtorInitExpr : DStmt<Expr>; def CXXBindTemporaryExpr : DStmt<Expr>; def ExprWithCleanups : DStmt<Expr>; def CXXTemporaryObjectExpr : DStmt<CXXConstructExpr>; @@ -164,6 +165,7 @@ def ObjCIsaExpr : DStmt<Expr>; def ObjCIndirectCopyRestoreExpr : DStmt<Expr>; def ObjCBoolLiteralExpr : DStmt<Expr>; def ObjCSubscriptRefExpr : DStmt<Expr>; +def ObjCAvailabilityCheckExpr : DStmt<Expr>; // Obj-C ARC Expressions. def ObjCBridgedCastExpr : DStmt<ExplicitCastExpr>; @@ -216,9 +218,18 @@ def OMPOrderedDirective : DStmt<OMPExecutableDirective>; def OMPAtomicDirective : DStmt<OMPExecutableDirective>; def OMPTargetDirective : DStmt<OMPExecutableDirective>; def OMPTargetDataDirective : DStmt<OMPExecutableDirective>; +def OMPTargetEnterDataDirective : DStmt<OMPExecutableDirective>; +def OMPTargetExitDataDirective : DStmt<OMPExecutableDirective>; +def OMPTargetParallelDirective : DStmt<OMPExecutableDirective>; +def OMPTargetParallelForDirective : DStmt<OMPExecutableDirective>; +def OMPTargetUpdateDirective : DStmt<OMPExecutableDirective>; def OMPTeamsDirective : DStmt<OMPExecutableDirective>; def OMPCancellationPointDirective : DStmt<OMPExecutableDirective>; def OMPCancelDirective : DStmt<OMPExecutableDirective>; def OMPTaskLoopDirective : DStmt<OMPLoopDirective>; def OMPTaskLoopSimdDirective : DStmt<OMPLoopDirective>; def OMPDistributeDirective : DStmt<OMPLoopDirective>; +def OMPDistributeParallelForDirective : DStmt<OMPLoopDirective>; +def OMPDistributeParallelForSimdDirective : DStmt<OMPLoopDirective>; +def OMPDistributeSimdDirective : DStmt<OMPLoopDirective>; +def OMPTargetParallelForSimdDirective : DStmt<OMPLoopDirective>; diff --git a/include/clang/Basic/TargetCXXABI.h b/include/clang/Basic/TargetCXXABI.h index 67247ead2eb44..f7d4b920ca15b 100644 --- a/include/clang/Basic/TargetCXXABI.h +++ b/include/clang/Basic/TargetCXXABI.h @@ -239,7 +239,7 @@ public: /// \brief Can an out-of-line inline function serve as a key function? /// /// This flag is only useful in ABIs where type data (for example, - /// v-tables and type_info objects) are emitted only after processing + /// vtables and type_info objects) are emitted only after processing /// the definition of a special "key" virtual function. (This is safe /// because the ODR requires that every virtual function be defined /// somewhere in a program.) This usually permits such data to be diff --git a/include/clang/Basic/TargetInfo.h b/include/clang/Basic/TargetInfo.h index f1d8338170778..f458c166a7a80 100644 --- a/include/clang/Basic/TargetInfo.h +++ b/include/clang/Basic/TargetInfo.h @@ -21,13 +21,14 @@ #include "clang/Basic/TargetCXXABI.h" #include "clang/Basic/TargetOptions.h" #include "clang/Basic/VersionTuple.h" -#include "llvm/ADT/IntrusiveRefCntPtr.h" #include "llvm/ADT/APInt.h" +#include "llvm/ADT/IntrusiveRefCntPtr.h" #include "llvm/ADT/SmallSet.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/ADT/Triple.h" +#include "llvm/IR/DataLayout.h" #include "llvm/Support/DataTypes.h" #include <cassert> #include <string> @@ -57,13 +58,14 @@ protected: bool BigEndian; bool TLSSupported; bool NoAsmVariants; // True if {|} are normal characters. + bool HasFloat128; unsigned char PointerWidth, PointerAlign; unsigned char BoolWidth, BoolAlign; unsigned char IntWidth, IntAlign; unsigned char HalfWidth, HalfAlign; unsigned char FloatWidth, FloatAlign; unsigned char DoubleWidth, DoubleAlign; - unsigned char LongDoubleWidth, LongDoubleAlign; + unsigned char LongDoubleWidth, LongDoubleAlign, Float128Align; unsigned char LargeArrayMinWidth, LargeArrayAlign; unsigned char LongWidth, LongAlign; unsigned char LongLongWidth, LongLongAlign; @@ -74,11 +76,10 @@ protected: unsigned short MaxVectorAlign; unsigned short MaxTLSAlign; unsigned short SimdDefaultAlign; - const char *DataLayoutString; - const char *UserLabelPrefix; + std::unique_ptr<llvm::DataLayout> DataLayout; const char *MCountName; const llvm::fltSemantics *HalfFormat, *FloatFormat, *DoubleFormat, - *LongDoubleFormat; + *LongDoubleFormat, *Float128Format; unsigned char RegParmMax, SSERegParmMax; TargetCXXABI TheCXXABI; const LangAS::Map *AddrSpaceMap; @@ -95,6 +96,10 @@ protected: // TargetInfo Constructor. Default initializes all fields. TargetInfo(const llvm::Triple &T); + void resetDataLayout(StringRef DL) { + DataLayout.reset(new llvm::DataLayout(DL)); + } + public: /// \brief Construct a target for the given options. /// @@ -132,7 +137,8 @@ public: NoFloat = 255, Float = 0, Double, - LongDouble + LongDouble, + Float128 }; /// \brief The different kinds of __builtin_va_list types defined by @@ -202,6 +208,9 @@ protected: /// zero-length bitfield. unsigned UseZeroLengthBitfieldAlignment : 1; + /// \brief Whether explicit bit field alignment attributes are honored. + unsigned UseExplicitBitFieldAlignment : 1; + /// If non-zero, specifies a fixed alignment value for bitfields that follow /// zero length bitfield, regardless of the zero length bitfield type. unsigned ZeroLengthBitfieldBoundary; @@ -320,6 +329,9 @@ public: return getPointerWidth(0) >= 64; } // FIXME + /// \brief Determine whether the __float128 type is supported on this target. + virtual bool hasFloat128Type() const { return HasFloat128; } + /// \brief Return the alignment that is suitable for storing any /// object with a fundamental alignment requirement. unsigned getSuitableAlign() const { return SuitableAlign; } @@ -372,6 +384,14 @@ public: return *LongDoubleFormat; } + /// getFloat128Width/Align/Format - Return the size/align/format of + /// '__float128'. + unsigned getFloat128Width() const { return 128; } + unsigned getFloat128Align() const { return Float128Align; } + const llvm::fltSemantics &getFloat128Format() const { + return *Float128Format; + } + /// \brief Return true if the 'long double' type should be mangled like /// __float128. virtual bool useFloat128ManglingForLongDouble() const { return false; } @@ -407,30 +427,37 @@ public: /// types for the given target. unsigned getSimdDefaultAlign() const { return SimdDefaultAlign; } + /// Return the alignment (in bits) of the thrown exception object. This is + /// only meaningful for targets that allocate C++ exceptions in a system + /// runtime, such as those using the Itanium C++ ABI. + virtual unsigned getExnObjectAlignment() const { + // Itanium says that an _Unwind_Exception has to be "double-word" + // aligned (and thus the end of it is also so-aligned), meaning 16 + // bytes. Of course, that was written for the actual Itanium, + // which is a 64-bit platform. Classically, the ABI doesn't really + // specify the alignment on other platforms, but in practice + // libUnwind declares the struct with __attribute__((aligned)), so + // we assume that alignment here. (It's generally 16 bytes, but + // some targets overwrite it.) + return getDefaultAlignForAttributeAligned(); + } + /// \brief Return the size of intmax_t and uintmax_t for this target, in bits. unsigned getIntMaxTWidth() const { return getTypeWidth(IntMaxType); } // Return the size of unwind_word for this target. - unsigned getUnwindWordWidth() const { return getPointerWidth(0); } + virtual unsigned getUnwindWordWidth() const { return getPointerWidth(0); } /// \brief Return the "preferred" register width on this target. - unsigned getRegisterWidth() const { + virtual unsigned getRegisterWidth() const { // Currently we assume the register width on the target matches the pointer // width, we can introduce a new variable for this if/when some target wants // it. return PointerWidth; } - /// \brief Returns the default value of the __USER_LABEL_PREFIX__ macro, - /// which is the prefix given to user symbols by default. - /// - /// On most platforms this is "_", but it is "" on some, and "." on others. - const char *getUserLabelPrefix() const { - return UserLabelPrefix; - } - /// \brief Returns the name of the mcount instrumentation function. const char *getMCountName() const { return MCountName; @@ -466,6 +493,12 @@ public: return ZeroLengthBitfieldBoundary; } + /// \brief Check whether explicit bitfield alignment attributes should be + // honored, as in "__attribute__((aligned(2))) int b : 1;". + bool useExplicitBitFieldAlignment() const { + return UseExplicitBitFieldAlignment; + } + /// \brief Check whether this target support '\#pragma options align=mac68k'. bool hasAlignMac68kSupport() const { return HasAlignMac68kSupport; @@ -712,9 +745,9 @@ public: return Triple; } - const char *getDataLayoutString() const { - assert(DataLayoutString && "Uninitialized DataLayoutString!"); - return DataLayoutString; + const llvm::DataLayout &getDataLayout() const { + assert(DataLayout && "Uninitialized DataLayout!"); + return *DataLayout; } struct GCCRegAlias { @@ -868,6 +901,8 @@ public: /// \brief Return the register number that __builtin_eh_return_regno would /// return with the specified argument. + /// This corresponds with TargetLowering's getExceptionPointerRegister + /// and getExceptionSelectorRegister in the backend. virtual int getEHDataRegisterNumber(unsigned RegNo) const { return -1; } @@ -931,6 +966,27 @@ public: return false; } + /// \brief Whether target allows to overalign ABI-specified prefered alignment + virtual bool allowsLargerPreferedTypeAlignment() const { return true; } + + /// \brief Set supported OpenCL extensions and optional core features. + virtual void setSupportedOpenCLOpts() {} + + /// \brief Get supported OpenCL extensions and optional core features. + OpenCLOptions &getSupportedOpenCLOpts() { + return getTargetOpts().SupportedOpenCLOptions; + } + + /// \brief Get const supported OpenCL extensions and optional core features. + const OpenCLOptions &getSupportedOpenCLOpts() const { + return getTargetOpts().SupportedOpenCLOptions; + } + + /// \brief Check the target is valid after it is fully initialized. + virtual bool validateTarget(DiagnosticsEngine &Diags) const { + return true; + } + protected: virtual uint64_t getPointerWidthV(unsigned AddrSpace) const { return PointerWidth; diff --git a/include/clang/Basic/TargetOptions.h b/include/clang/Basic/TargetOptions.h index ca0cca78bfc8e..fde294c922515 100644 --- a/include/clang/Basic/TargetOptions.h +++ b/include/clang/Basic/TargetOptions.h @@ -17,6 +17,7 @@ #include <string> #include <vector> +#include "clang/Basic/OpenCLOptions.h" namespace clang { @@ -27,6 +28,10 @@ public: /// target will be selected to match the host. std::string Triple; + /// When compiling for the device side, contains the triple used to compile + /// for the host. + std::string HostTriple; + /// If given, the name of the target CPU to generate code for. std::string CPU; @@ -36,6 +41,9 @@ public: /// If given, the name of the target ABI to use. std::string ABI; + /// The EABI version to use + std::string EABIVersion; + /// If given, the version string of the linker in use. std::string LinkerVersion; @@ -45,8 +53,11 @@ public: /// The list of target specific features to enable or disable -- this should /// be a list of strings starting with by '+' or '-'. std::vector<std::string> Features; - + std::vector<std::string> Reciprocals; + + /// Supported OpenCL extensions and optional core features. + OpenCLOptions SupportedOpenCLOptions; }; } // end namespace clang diff --git a/include/clang/Basic/TokenKinds.def b/include/clang/Basic/TokenKinds.def index 026945141d24e..882c6e4cac2c7 100644 --- a/include/clang/Basic/TokenKinds.def +++ b/include/clang/Basic/TokenKinds.def @@ -219,6 +219,9 @@ PUNCTUATOR(at, "@") PUNCTUATOR(lesslessless, "<<<") PUNCTUATOR(greatergreatergreater, ">>>") +// CL support +PUNCTUATOR(caretcaret, "^^") + // C99 6.4.1: Keywords. These turn into kw_* tokens. // Flags allowed: // KEYALL - This is a keyword in all variants of C and C++, or it @@ -377,6 +380,7 @@ KEYWORD(__builtin_offsetof , KEYALL) TYPE_TRAIT_2(__builtin_types_compatible_p, TypeCompatible, KEYNOCXX) KEYWORD(__builtin_va_arg , KEYALL) KEYWORD(__extension__ , KEYALL) +KEYWORD(__float128 , KEYALL) KEYWORD(__imag , KEYALL) KEYWORD(__int128 , KEYALL) KEYWORD(__label__ , KEYALL) @@ -403,6 +407,9 @@ TYPE_TRAIT_2(__is_nothrow_assignable, IsNothrowAssignable, KEYCXX) TYPE_TRAIT_N(__is_constructible, IsConstructible, KEYCXX) TYPE_TRAIT_N(__is_nothrow_constructible, IsNothrowConstructible, KEYCXX) +// MSVC14.0 / VS2015 Type Traits +TYPE_TRAIT_2(__is_assignable, IsAssignable, KEYCXX) + // GNU and MS Type Traits TYPE_TRAIT_1(__has_nothrow_assign, HasNothrowAssign, KEYCXX) TYPE_TRAIT_1(__has_nothrow_move_assign, HasNothrowMoveAssign, KEYCXX) @@ -515,6 +522,8 @@ ALIAS("read_write", __read_write , KEYOPENCL) // OpenCL builtins KEYWORD(__builtin_astype , KEYOPENCL) KEYWORD(vec_step , KEYOPENCL|KEYALTIVEC|KEYZVECTOR) +#define GENERIC_IMAGE_TYPE(ImgType, Id) KEYWORD(ImgType##_t, KEYOPENCL) +#include "clang/Basic/OpenCLImageTypes.def" // OpenMP Type Traits KEYWORD(__builtin_omp_required_simd_align, KEYALL) @@ -621,6 +630,8 @@ KEYWORD(__builtin_convertvector , KEYALL) ALIAS("__char16_t" , char16_t , KEYCXX) ALIAS("__char32_t" , char32_t , KEYCXX) +KEYWORD(__builtin_available , KEYALL) + // Clang-specific keywords enabled only in testing. TESTING_KEYWORD(__unknown_anytype , KEYALL) @@ -659,6 +670,7 @@ OBJC2_AT_KEYWORD(optional) OBJC2_AT_KEYWORD(synthesize) OBJC2_AT_KEYWORD(dynamic) OBJC2_AT_KEYWORD(import) +OBJC2_AT_KEYWORD(available) // TODO: What to do about context-sensitive keywords like: // bycopy/byref/in/inout/oneway/out? diff --git a/include/clang/Basic/TypeTraits.h b/include/clang/Basic/TypeTraits.h index 765246b4cc549..730ecba3d4fa5 100644 --- a/include/clang/Basic/TypeTraits.h +++ b/include/clang/Basic/TypeTraits.h @@ -74,6 +74,7 @@ namespace clang { BTT_IsConvertibleTo, BTT_IsSame, BTT_TypeCompatible, + BTT_IsAssignable, BTT_IsNothrowAssignable, BTT_IsTriviallyAssignable, BTT_Last = BTT_IsTriviallyAssignable, diff --git a/include/clang/Basic/VersionTuple.h b/include/clang/Basic/VersionTuple.h index 784f3f322d697..da3b01903ed93 100644 --- a/include/clang/Basic/VersionTuple.h +++ b/include/clang/Basic/VersionTuple.h @@ -25,39 +25,44 @@ namespace clang { /// \brief Represents a version number in the form major[.minor[.subminor[.build]]]. class VersionTuple { unsigned Major : 31; + + unsigned UsesUnderscores : 1; + unsigned Minor : 31; - unsigned Subminor : 31; - unsigned Build : 31; unsigned HasMinor : 1; + + unsigned Subminor : 31; unsigned HasSubminor : 1; + + unsigned Build : 31; unsigned HasBuild : 1; - unsigned UsesUnderscores : 1; public: VersionTuple() - : Major(0), Minor(0), Subminor(0), Build(0), HasMinor(false), - HasSubminor(false), HasBuild(false), UsesUnderscores(false) {} + : Major(0), UsesUnderscores(false), Minor(0), HasMinor(false), + Subminor(0), HasSubminor(false), Build(0), HasBuild(false) {} explicit VersionTuple(unsigned Major) - : Major(Major), Minor(0), Subminor(0), Build(0), HasMinor(false), - HasSubminor(false), HasBuild(false), UsesUnderscores(false) {} + : Major(Major), UsesUnderscores(false), Minor(0), HasMinor(false), + Subminor(0), HasSubminor(false), Build(0), HasBuild(false) {} explicit VersionTuple(unsigned Major, unsigned Minor, bool UsesUnderscores = false) - : Major(Major), Minor(Minor), Subminor(0), Build(0), HasMinor(true), - HasSubminor(false), HasBuild(false), UsesUnderscores(UsesUnderscores) {} + : Major(Major), UsesUnderscores(UsesUnderscores), Minor(Minor), + HasMinor(true), Subminor(0), HasSubminor(false), Build(0), + HasBuild(false) {} explicit VersionTuple(unsigned Major, unsigned Minor, unsigned Subminor, bool UsesUnderscores = false) - : Major(Major), Minor(Minor), Subminor(Subminor), Build(0), - HasMinor(true), HasSubminor(true), HasBuild(false), - UsesUnderscores(UsesUnderscores) {} + : Major(Major), UsesUnderscores(UsesUnderscores), Minor(Minor), + HasMinor(true), Subminor(Subminor), HasSubminor(true), Build(0), + HasBuild(false) {} explicit VersionTuple(unsigned Major, unsigned Minor, unsigned Subminor, unsigned Build, bool UsesUnderscores = false) - : Major(Major), Minor(Minor), Subminor(Subminor), Build(Build), - HasMinor(true), HasSubminor(true), HasBuild(true), - UsesUnderscores(UsesUnderscores) {} + : Major(Major), UsesUnderscores(UsesUnderscores), Minor(Minor), + HasMinor(true), Subminor(Subminor), HasSubminor(true), Build(Build), + HasBuild(true) {} /// \brief Determine whether this version information is empty /// (e.g., all version components are zero). diff --git a/include/clang/Basic/VirtualFileSystem.h b/include/clang/Basic/VirtualFileSystem.h index bab88c90b0a88..6ac0812dbb17f 100644 --- a/include/clang/Basic/VirtualFileSystem.h +++ b/include/clang/Basic/VirtualFileSystem.h @@ -20,6 +20,7 @@ #include "llvm/Support/FileSystem.h" #include "llvm/Support/SourceMgr.h" #include "llvm/Support/raw_ostream.h" +#include <utility> namespace llvm { class MemoryBuffer; @@ -90,6 +91,13 @@ public: virtual ~File(); /// \brief Get the status of the file. virtual llvm::ErrorOr<Status> status() = 0; + /// \brief Get the name of the file + virtual llvm::ErrorOr<std::string> getName() { + if (auto Status = status()) + return Status->getName().str(); + else + return Status.getError(); + } /// \brief Get the contents of the file as a \p MemoryBuffer. virtual llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> getBuffer(const Twine &Name, int64_t FileSize = -1, @@ -116,7 +124,8 @@ class directory_iterator { std::shared_ptr<detail::DirIterImpl> Impl; // Input iterator semantics on copy public: - directory_iterator(std::shared_ptr<detail::DirIterImpl> I) : Impl(I) { + directory_iterator(std::shared_ptr<detail::DirIterImpl> I) + : Impl(std::move(I)) { assert(Impl.get() != nullptr && "requires non-null implementation"); if (!Impl->CurrentEntry.isStatusKnown()) Impl.reset(); // Normalize the end iterator to Impl == nullptr. @@ -176,6 +185,11 @@ public: bool operator!=(const recursive_directory_iterator &RHS) const { return !(*this == RHS); } + /// \brief Gets the current level. Starting path is at level 0. + int level() const { + assert(State->size() && "Cannot get level without any iteration state"); + return State->size()-1; + } }; /// \brief The virtual file system interface. @@ -310,6 +324,7 @@ llvm::sys::fs::UniqueID getNextVirtualUniqueID(); IntrusiveRefCntPtr<FileSystem> getVFSFromYAML(std::unique_ptr<llvm::MemoryBuffer> Buffer, llvm::SourceMgr::DiagHandlerTy DiagHandler, + StringRef YAMLFilePath, void *DiagContext = nullptr, IntrusiveRefCntPtr<FileSystem> ExternalFS = getRealFileSystem()); @@ -323,6 +338,9 @@ struct YAMLVFSEntry { class YAMLVFSWriter { std::vector<YAMLVFSEntry> Mappings; Optional<bool> IsCaseSensitive; + Optional<bool> IsOverlayRelative; + Optional<bool> UseExternalNames; + std::string OverlayDir; public: YAMLVFSWriter() {} @@ -330,6 +348,14 @@ public: void setCaseSensitivity(bool CaseSensitive) { IsCaseSensitive = CaseSensitive; } + void setUseExternalNames(bool UseExtNames) { + UseExternalNames = UseExtNames; + } + void setOverlayDir(StringRef OverlayDirectory) { + IsOverlayRelative = true; + OverlayDir.assign(OverlayDirectory.str()); + } + void write(llvm::raw_ostream &OS); }; diff --git a/include/clang/Basic/arm_neon.td b/include/clang/Basic/arm_neon.td index 6d95c1ec157a2..5605fc6de2b62 100644 --- a/include/clang/Basic/arm_neon.td +++ b/include/clang/Basic/arm_neon.td @@ -339,6 +339,7 @@ def OP_MLALHi : Op<(call "vmlal", $p0, (call "vget_high", $p1), (call "vget_high", $p2))>; def OP_MLALHi_N : Op<(call "vmlal_n", $p0, (call "vget_high", $p1), $p2)>; def OP_MLS : Op<(op "-", $p0, (op "*", $p1, $p2))>; +def OP_FMLS : Op<(call "vfma", $p0, (op "-", $p1), $p2)>; def OP_MLSL : Op<(op "-", $p0, (call "vmull", $p1, $p2))>; def OP_MLSLHi : Op<(call "vmlsl", $p0, (call "vget_high", $p1), (call "vget_high", $p2))>; @@ -347,7 +348,7 @@ def OP_MUL_N : Op<(op "*", $p0, (dup $p1))>; def OP_MLA_N : Op<(op "+", $p0, (op "*", $p1, (dup $p2)))>; def OP_MLS_N : Op<(op "-", $p0, (op "*", $p1, (dup $p2)))>; def OP_FMLA_N : Op<(call "vfma", $p0, $p1, (dup $p2))>; -def OP_FMLS_N : Op<(call "vfms", $p0, $p1, (dup $p2))>; +def OP_FMLS_N : Op<(call "vfma", $p0, (op "-", $p1), (dup $p2))>; def OP_MLAL_N : Op<(op "+", $p0, (call "vmull", $p1, (dup $p2)))>; def OP_MLSL_N : Op<(op "-", $p0, (call "vmull", $p1, (dup $p2)))>; def OP_MUL_LN : Op<(op "*", $p0, (splat $p1, $p2))>; @@ -377,8 +378,8 @@ def OP_QRDMLAH : Op<(call "vqadd", $p0, (call "vqrdmulh", $p1, $p2))>; def OP_QRDMLSH : Op<(call "vqsub", $p0, (call "vqrdmulh", $p1, $p2))>; def OP_QRDMLAH_LN : Op<(call "vqadd", $p0, (call "vqrdmulh", $p1, (splat $p2, $p3)))>; def OP_QRDMLSH_LN : Op<(call "vqsub", $p0, (call "vqrdmulh", $p1, (splat $p2, $p3)))>; -def OP_FMS_LN : Op<(call "vfma_lane", $p0, $p1, (op "-", $p2), $p3)>; -def OP_FMS_LNQ : Op<(call "vfma_laneq", $p0, $p1, (op "-", $p2), $p3)>; +def OP_FMS_LN : Op<(call "vfma_lane", $p0, (op "-", $p1), $p2, $p3)>; +def OP_FMS_LNQ : Op<(call "vfma_laneq", $p0, (op "-", $p1), $p2, $p3)>; def OP_TRN1 : Op<(shuffle $p0, $p1, (interleave (decimate mask0, 2), (decimate mask1, 2)))>; def OP_ZIP1 : Op<(shuffle $p0, $p1, (lowhalf (interleave mask0, mask1)))>; @@ -703,8 +704,10 @@ def VGET_LOW : NoTestOpInst<"vget_low", "dk", "csilhfUcUsUiUlPcPs", OP_LO>; //////////////////////////////////////////////////////////////////////////////// // E.3.22 Converting vectors -def VCVT_F16_F32 : SInst<"vcvt_f16_f32", "md", "Hf">; -def VCVT_F32_F16 : SInst<"vcvt_f32_f16", "wd", "h">; +let ArchGuard = "(__ARM_FP & 2)" in { + def VCVT_F16_F32 : SInst<"vcvt_f16_f32", "md", "Hf">; + def VCVT_F32_F16 : SInst<"vcvt_f32_f16", "wd", "h">; +} def VCVT_S32 : SInst<"vcvt_s32", "xd", "fQf">; def VCVT_U32 : SInst<"vcvt_u32", "ud", "fQf">; @@ -824,7 +827,10 @@ def VREINTERPRET //////////////////////////////////////////////////////////////////////////////// // Vector fused multiply-add operations -def VFMA : SInst<"vfma", "dddd", "fQf">; +let ArchGuard = "defined(__ARM_FEATURE_FMA)" in { + def VFMA : SInst<"vfma", "dddd", "fQf">; + def VFMS : SOpInst<"vfms", "dddd", "fQf", OP_FMLS>; +} //////////////////////////////////////////////////////////////////////////////// // fp16 vector operations @@ -908,7 +914,7 @@ def FDIV : IOpInst<"vdiv", "ddd", "fdQfQd", OP_DIV>; //////////////////////////////////////////////////////////////////////////////// // Vector fused multiply-add operations def FMLA : SInst<"vfma", "dddd", "dQd">; -def FMLS : SInst<"vfms", "dddd", "fdQfQd">; +def FMLS : SOpInst<"vfms", "dddd", "dQd", OP_FMLS>; //////////////////////////////////////////////////////////////////////////////// // MUL, MLA, MLS, FMA, FMS definitions with scalar argument @@ -961,7 +967,7 @@ def XTN2 : SOpInst<"vmovn_high", "qhk", "silUsUiUl", OP_XTN>; //////////////////////////////////////////////////////////////////////////////// // Signed integer saturating extract and unsigned narrow to high -def SQXTUN2 : SOpInst<"vqmovun_high", "qhk", "sil", OP_SQXTUN>; +def SQXTUN2 : SOpInst<"vqmovun_high", "emd", "HsHiHl", OP_SQXTUN>; //////////////////////////////////////////////////////////////////////////////// // Integer saturating extract and narrow to high diff --git a/include/clang/CMakeLists.txt b/include/clang/CMakeLists.txt index 1d8aecd3b24e4..feb81f0686cac 100644 --- a/include/clang/CMakeLists.txt +++ b/include/clang/CMakeLists.txt @@ -4,3 +4,4 @@ add_subdirectory(Driver) add_subdirectory(Parse) add_subdirectory(Sema) add_subdirectory(Serialization) +add_subdirectory(StaticAnalyzer/Checkers) diff --git a/include/clang/CodeGen/BackendUtil.h b/include/clang/CodeGen/BackendUtil.h index d375a7881313f..01721d3220989 100644 --- a/include/clang/CodeGen/BackendUtil.h +++ b/include/clang/CodeGen/BackendUtil.h @@ -11,11 +11,12 @@ #define LLVM_CLANG_CODEGEN_BACKENDUTIL_H #include "clang/Basic/LLVM.h" -#include "llvm/IR/FunctionInfo.h" +#include "llvm/IR/ModuleSummaryIndex.h" #include <memory> namespace llvm { class Module; + class MemoryBufferRef; } namespace clang { @@ -35,8 +36,12 @@ namespace clang { void EmitBackendOutput(DiagnosticsEngine &Diags, const CodeGenOptions &CGOpts, const TargetOptions &TOpts, const LangOptions &LOpts, - StringRef TDesc, llvm::Module *M, BackendAction Action, - raw_pwrite_stream *OS); + const llvm::DataLayout &TDesc, llvm::Module *M, + BackendAction Action, + std::unique_ptr<raw_pwrite_stream> OS); + + void EmbedBitcode(llvm::Module *M, const CodeGenOptions &CGOpts, + llvm::MemoryBufferRef Buf); } #endif diff --git a/include/clang/CodeGen/CGFunctionInfo.h b/include/clang/CodeGen/CGFunctionInfo.h index bb6ceb43514eb..8dd6ad1c21ee8 100644 --- a/include/clang/CodeGen/CGFunctionInfo.h +++ b/include/clang/CodeGen/CGFunctionInfo.h @@ -16,20 +16,17 @@ #ifndef LLVM_CLANG_CODEGEN_CGFUNCTIONINFO_H #define LLVM_CLANG_CODEGEN_CGFUNCTIONINFO_H +#include "clang/AST/Attr.h" #include "clang/AST/CanonicalType.h" #include "clang/AST/CharUnits.h" +#include "clang/AST/Decl.h" #include "clang/AST/Type.h" +#include "llvm/IR/DerivedTypes.h" #include "llvm/ADT/FoldingSet.h" +#include "llvm/Support/TrailingObjects.h" #include <cassert> -namespace llvm { - class Type; - class StructType; -} - namespace clang { -class Decl; - namespace CodeGen { /// ABIArgInfo - Helper class to encapsulate information about how a @@ -63,6 +60,12 @@ public: /// are all scalar types or are themselves expandable types. Expand, + /// CoerceAndExpand - Only valid for aggregate argument types. The + /// structure should be expanded into consecutive arguments corresponding + /// to the non-array elements of the type stored in CoerceToType. + /// Array elements in the type are assumed to be padding and skipped. + CoerceAndExpand, + /// InAlloca - Pass the argument directly using the LLVM inalloca attribute. /// This is similar to indirect with byval, except it only applies to /// arguments stored in memory and forbids any implicit copies. When @@ -74,8 +77,11 @@ public: }; private: - llvm::Type *TypeData; // isDirect() || isExtend() - llvm::Type *PaddingType; + llvm::Type *TypeData; // canHaveCoerceToType() + union { + llvm::Type *PaddingType; // canHavePaddingType() + llvm::Type *UnpaddedCoerceAndExpandType; // isCoerceAndExpand() + }; union { unsigned DirectOffset; // isDirect() || isExtend() unsigned IndirectAlign; // isIndirect() @@ -90,8 +96,22 @@ private: bool InReg : 1; // isDirect() || isExtend() || isIndirect() bool CanBeFlattened: 1; // isDirect() + bool canHavePaddingType() const { + return isDirect() || isExtend() || isIndirect() || isExpand(); + } + void setPaddingType(llvm::Type *T) { + assert(canHavePaddingType()); + PaddingType = T; + } + + void setUnpaddedCoerceToType(llvm::Type *T) { + assert(isCoerceAndExpand()); + UnpaddedCoerceAndExpandType = T; + } + ABIArgInfo(Kind K) - : PaddingType(nullptr), TheKind(K), PaddingInReg(false), InReg(false) {} + : TheKind(K), PaddingInReg(false), InReg(false) { + } public: ABIArgInfo() @@ -103,8 +123,8 @@ public: bool CanBeFlattened = true) { auto AI = ABIArgInfo(Direct); AI.setCoerceToType(T); - AI.setDirectOffset(Offset); AI.setPaddingType(Padding); + AI.setDirectOffset(Offset); AI.setCanBeFlattened(CanBeFlattened); return AI; } @@ -116,6 +136,7 @@ public: static ABIArgInfo getExtend(llvm::Type *T = nullptr) { auto AI = ABIArgInfo(Extend); AI.setCoerceToType(T); + AI.setPaddingType(nullptr); AI.setDirectOffset(0); return AI; } @@ -150,7 +171,9 @@ public: return AI; } static ABIArgInfo getExpand() { - return ABIArgInfo(Expand); + auto AI = ABIArgInfo(Expand); + AI.setPaddingType(nullptr); + return AI; } static ABIArgInfo getExpandWithPadding(bool PaddingInReg, llvm::Type *Padding) { @@ -160,6 +183,54 @@ public: return AI; } + /// \param unpaddedCoerceToType The coerce-to type with padding elements + /// removed, canonicalized to a single element if it would otherwise + /// have exactly one element. + static ABIArgInfo getCoerceAndExpand(llvm::StructType *coerceToType, + llvm::Type *unpaddedCoerceToType) { +#ifndef NDEBUG + // Sanity checks on unpaddedCoerceToType. + + // Assert that we only have a struct type if there are multiple elements. + auto unpaddedStruct = dyn_cast<llvm::StructType>(unpaddedCoerceToType); + assert(!unpaddedStruct || unpaddedStruct->getNumElements() != 1); + + // Assert that all the non-padding elements have a corresponding element + // in the unpadded type. + unsigned unpaddedIndex = 0; + for (auto eltType : coerceToType->elements()) { + if (isPaddingForCoerceAndExpand(eltType)) continue; + if (unpaddedStruct) { + assert(unpaddedStruct->getElementType(unpaddedIndex) == eltType); + } else { + assert(unpaddedIndex == 0 && unpaddedCoerceToType == eltType); + } + unpaddedIndex++; + } + + // Assert that there aren't extra elements in the unpadded type. + if (unpaddedStruct) { + assert(unpaddedStruct->getNumElements() == unpaddedIndex); + } else { + assert(unpaddedIndex == 1); + } +#endif + + auto AI = ABIArgInfo(CoerceAndExpand); + AI.setCoerceToType(coerceToType); + AI.setUnpaddedCoerceToType(unpaddedCoerceToType); + return AI; + } + + static bool isPaddingForCoerceAndExpand(llvm::Type *eltType) { + if (eltType->isArrayTy()) { + assert(eltType->getArrayElementType()->isIntegerTy(8)); + return true; + } else { + return false; + } + } + Kind getKind() const { return TheKind; } bool isDirect() const { return TheKind == Direct; } bool isInAlloca() const { return TheKind == InAlloca; } @@ -167,8 +238,11 @@ public: bool isIgnore() const { return TheKind == Ignore; } bool isIndirect() const { return TheKind == Indirect; } bool isExpand() const { return TheKind == Expand; } + bool isCoerceAndExpand() const { return TheKind == CoerceAndExpand; } - bool canHaveCoerceToType() const { return isDirect() || isExtend(); } + bool canHaveCoerceToType() const { + return isDirect() || isExtend() || isCoerceAndExpand(); + } // Direct/Extend accessors unsigned getDirectOffset() const { @@ -180,9 +254,9 @@ public: DirectOffset = Offset; } - llvm::Type *getPaddingType() const { return PaddingType; } - - void setPaddingType(llvm::Type *T) { PaddingType = T; } + llvm::Type *getPaddingType() const { + return (canHavePaddingType() ? PaddingType : nullptr); + } bool getPaddingInReg() const { return PaddingInReg; @@ -201,6 +275,26 @@ public: TypeData = T; } + llvm::StructType *getCoerceAndExpandType() const { + assert(isCoerceAndExpand()); + return cast<llvm::StructType>(TypeData); + } + + llvm::Type *getUnpaddedCoerceAndExpandType() const { + assert(isCoerceAndExpand()); + return UnpaddedCoerceAndExpandType; + } + + ArrayRef<llvm::Type *>getCoerceAndExpandTypeSequence() const { + assert(isCoerceAndExpand()); + if (auto structTy = + dyn_cast<llvm::StructType>(UnpaddedCoerceAndExpandType)) { + return structTy->elements(); + } else { + return llvm::makeArrayRef(&UnpaddedCoerceAndExpandType, 1); + } + } + bool getInReg() const { assert((isDirect() || isExtend() || isIndirect()) && "Invalid kind!"); return InReg; @@ -299,23 +393,34 @@ public: /// Compute the arguments required by the given formal prototype, /// given that there may be some additional, non-formal arguments /// in play. + /// + /// If FD is not null, this will consider pass_object_size params in FD. static RequiredArgs forPrototypePlus(const FunctionProtoType *prototype, - unsigned additional) { + unsigned additional, + const FunctionDecl *FD) { if (!prototype->isVariadic()) return All; + if (FD) + additional += + llvm::count_if(FD->parameters(), [](const ParmVarDecl *PVD) { + return PVD->hasAttr<PassObjectSizeAttr>(); + }); return RequiredArgs(prototype->getNumParams() + additional); } - static RequiredArgs forPrototype(const FunctionProtoType *prototype) { - return forPrototypePlus(prototype, 0); + static RequiredArgs forPrototype(const FunctionProtoType *prototype, + const FunctionDecl *FD) { + return forPrototypePlus(prototype, 0, FD); } - static RequiredArgs forPrototype(CanQual<FunctionProtoType> prototype) { - return forPrototype(prototype.getTypePtr()); + static RequiredArgs forPrototype(CanQual<FunctionProtoType> prototype, + const FunctionDecl *FD) { + return forPrototype(prototype.getTypePtr(), FD); } static RequiredArgs forPrototypePlus(CanQual<FunctionProtoType> prototype, - unsigned additional) { - return forPrototypePlus(prototype.getTypePtr(), additional); + unsigned additional, + const FunctionDecl *FD) { + return forPrototypePlus(prototype.getTypePtr(), additional, FD); } bool allowsOptionalArgs() const { return NumRequired != ~0U; } @@ -331,13 +436,21 @@ public: } }; +// Implementation detail of CGFunctionInfo, factored out so it can be named +// in the TrailingObjects base class of CGFunctionInfo. +struct CGFunctionInfoArgInfo { + CanQualType type; + ABIArgInfo info; +}; + /// CGFunctionInfo - Class to encapsulate the information about a /// function definition. -class CGFunctionInfo : public llvm::FoldingSetNode { - struct ArgInfo { - CanQualType type; - ABIArgInfo info; - }; +class CGFunctionInfo final + : public llvm::FoldingSetNode, + private llvm::TrailingObjects<CGFunctionInfo, CGFunctionInfoArgInfo, + FunctionProtoType::ExtParameterInfo> { + typedef CGFunctionInfoArgInfo ArgInfo; + typedef FunctionProtoType::ExtParameterInfo ExtParameterInfo; /// The LLVM::CallingConv to use for this function (as specified by the /// user). @@ -371,14 +484,23 @@ class CGFunctionInfo : public llvm::FoldingSetNode { /// The struct representing all arguments passed in memory. Only used when /// passing non-trivial types with inalloca. Not part of the profile. llvm::StructType *ArgStruct; - unsigned ArgStructAlign; + unsigned ArgStructAlign : 31; + unsigned HasExtParameterInfos : 1; unsigned NumArgs; + ArgInfo *getArgsBuffer() { - return reinterpret_cast<ArgInfo*>(this+1); + return getTrailingObjects<ArgInfo>(); } const ArgInfo *getArgsBuffer() const { - return reinterpret_cast<const ArgInfo*>(this + 1); + return getTrailingObjects<ArgInfo>(); + } + + ExtParameterInfo *getExtParameterInfosBuffer() { + return getTrailingObjects<ExtParameterInfo>(); + } + const ExtParameterInfo *getExtParameterInfosBuffer() const{ + return getTrailingObjects<ExtParameterInfo>(); } CGFunctionInfo() : Required(RequiredArgs::All) {} @@ -388,9 +510,21 @@ public: bool instanceMethod, bool chainCall, const FunctionType::ExtInfo &extInfo, + ArrayRef<ExtParameterInfo> paramInfos, CanQualType resultType, ArrayRef<CanQualType> argTypes, RequiredArgs required); + void operator delete(void *p) { ::operator delete(p); } + + // Friending class TrailingObjects is apparently not good enough for MSVC, + // so these have to be public. + friend class TrailingObjects; + size_t numTrailingObjects(OverloadToken<ArgInfo>) const { + return NumArgs + 1; + } + size_t numTrailingObjects(OverloadToken<ExtParameterInfo>) const { + return (HasExtParameterInfos ? NumArgs : 0); + } typedef const ArgInfo *const_arg_iterator; typedef ArgInfo *arg_iterator; @@ -460,6 +594,16 @@ public: ABIArgInfo &getReturnInfo() { return getArgsBuffer()[0].info; } const ABIArgInfo &getReturnInfo() const { return getArgsBuffer()[0].info; } + ArrayRef<ExtParameterInfo> getExtParameterInfos() const { + if (!HasExtParameterInfos) return {}; + return llvm::makeArrayRef(getExtParameterInfosBuffer(), NumArgs); + } + ExtParameterInfo getExtParameterInfo(unsigned argIndex) const { + assert(argIndex <= NumArgs); + if (!HasExtParameterInfos) return ExtParameterInfo(); + return getExtParameterInfos()[argIndex]; + } + /// \brief Return true if this function uses inalloca arguments. bool usesInAlloca() const { return ArgStruct; } @@ -482,6 +626,11 @@ public: ID.AddBoolean(HasRegParm); ID.AddInteger(RegParm); ID.AddInteger(Required.getOpaqueData()); + ID.AddBoolean(HasExtParameterInfos); + if (HasExtParameterInfos) { + for (auto paramInfo : getExtParameterInfos()) + ID.AddInteger(paramInfo.getOpaqueValue()); + } getReturnType().Profile(ID); for (const auto &I : arguments()) I.type.Profile(ID); @@ -490,6 +639,7 @@ public: bool InstanceMethod, bool ChainCall, const FunctionType::ExtInfo &info, + ArrayRef<ExtParameterInfo> paramInfos, RequiredArgs required, CanQualType resultType, ArrayRef<CanQualType> argTypes) { @@ -501,6 +651,11 @@ public: ID.AddBoolean(info.getHasRegParm()); ID.AddInteger(info.getRegParm()); ID.AddInteger(required.getOpaqueData()); + ID.AddBoolean(!paramInfos.empty()); + if (!paramInfos.empty()) { + for (auto paramInfo : paramInfos) + ID.AddInteger(paramInfo.getOpaqueValue()); + } resultType.Profile(ID); for (ArrayRef<CanQualType>::iterator i = argTypes.begin(), e = argTypes.end(); i != e; ++i) { diff --git a/include/clang/CodeGen/CodeGenABITypes.h b/include/clang/CodeGen/CodeGenABITypes.h index 9d9504ad8e9f2..e7b7435968fb6 100644 --- a/include/clang/CodeGen/CodeGenABITypes.h +++ b/include/clang/CodeGen/CodeGenABITypes.h @@ -48,42 +48,27 @@ namespace CodeGen { class CGFunctionInfo; class CodeGenModule; -class CodeGenABITypes -{ -public: - CodeGenABITypes(ASTContext &C, llvm::Module &M, - CoverageSourceInfo *CoverageInfo = nullptr); - ~CodeGenABITypes(); +const CGFunctionInfo &arrangeObjCMessageSendSignature(CodeGenModule &CGM, + const ObjCMethodDecl *MD, + QualType receiverType); - /// These methods all forward to methods in the private implementation class - /// CodeGenTypes. +const CGFunctionInfo &arrangeFreeFunctionType(CodeGenModule &CGM, + CanQual<FunctionProtoType> Ty, + const FunctionDecl *FD); - const CGFunctionInfo &arrangeObjCMessageSendSignature( - const ObjCMethodDecl *MD, - QualType receiverType); - const CGFunctionInfo &arrangeFreeFunctionType(CanQual<FunctionProtoType> Ty, - const FunctionDecl *FD); - const CGFunctionInfo &arrangeFreeFunctionType( - CanQual<FunctionNoProtoType> Ty); - const CGFunctionInfo &arrangeCXXMethodType(const CXXRecordDecl *RD, - const FunctionProtoType *FTP, - const CXXMethodDecl *MD); - const CGFunctionInfo &arrangeFreeFunctionCall(CanQualType returnType, - ArrayRef<CanQualType> argTypes, - FunctionType::ExtInfo info, - RequiredArgs args); +const CGFunctionInfo &arrangeFreeFunctionType(CodeGenModule &CGM, + CanQual<FunctionNoProtoType> Ty); -private: - /// Default CodeGenOptions object used to initialize the - /// CodeGenModule and otherwise not used. More specifically, it is - /// not used in ABI type generation, so none of the options matter. - std::unique_ptr<CodeGenOptions> CGO; - std::unique_ptr<HeaderSearchOptions> HSO; - std::unique_ptr<PreprocessorOptions> PPO; +const CGFunctionInfo &arrangeCXXMethodType(CodeGenModule &CGM, + const CXXRecordDecl *RD, + const FunctionProtoType *FTP, + const CXXMethodDecl *MD); - /// The CodeGenModule we use get to the CodeGenTypes object. - std::unique_ptr<CodeGen::CodeGenModule> CGM; -}; +const CGFunctionInfo &arrangeFreeFunctionCall(CodeGenModule &CGM, + CanQualType returnType, + ArrayRef<CanQualType> argTypes, + FunctionType::ExtInfo info, + RequiredArgs args); } // end namespace CodeGen } // end namespace clang diff --git a/include/clang/CodeGen/ModuleBuilder.h b/include/clang/CodeGen/ModuleBuilder.h index 52497d9a9ac8a..ce7696dd00cfd 100644 --- a/include/clang/CodeGen/ModuleBuilder.h +++ b/include/clang/CodeGen/ModuleBuilder.h @@ -15,40 +15,83 @@ #define LLVM_CLANG_CODEGEN_MODULEBUILDER_H #include "clang/AST/ASTConsumer.h" -#include <string> namespace llvm { + class Constant; class LLVMContext; class Module; } namespace clang { - class DiagnosticsEngine; + class CodeGenOptions; class CoverageSourceInfo; - class LangOptions; + class Decl; + class DiagnosticsEngine; + class GlobalDecl; class HeaderSearchOptions; + class LangOptions; class PreprocessorOptions; - class CodeGenOptions; - class Decl; - class CodeGenerator : public ASTConsumer { - virtual void anchor(); - public: - virtual llvm::Module* GetModule() = 0; - virtual llvm::Module* ReleaseModule() = 0; - virtual const Decl *GetDeclForMangledName(llvm::StringRef MangledName) = 0; - }; - - /// CreateLLVMCodeGen - Create a CodeGenerator instance. - /// It is the responsibility of the caller to call delete on - /// the allocated CodeGenerator instance. - CodeGenerator *CreateLLVMCodeGen(DiagnosticsEngine &Diags, - const std::string &ModuleName, - const HeaderSearchOptions &HeaderSearchOpts, - const PreprocessorOptions &PreprocessorOpts, - const CodeGenOptions &CGO, - llvm::LLVMContext& C, - CoverageSourceInfo *CoverageInfo = nullptr); +namespace CodeGen { + class CodeGenModule; } +/// The primary public interface to the Clang code generator. +/// +/// This is not really an abstract interface. +class CodeGenerator : public ASTConsumer { + virtual void anchor(); + +public: + /// Return an opaque reference to the CodeGenModule object, which can + /// be used in various secondary APIs. It is valid as long as the + /// CodeGenerator exists. + CodeGen::CodeGenModule &CGM(); + + /// Return the module that this code generator is building into. + /// + /// This may return null after HandleTranslationUnit is called; + /// this signifies that there was an error generating code. A + /// diagnostic will have been generated in this case, and the module + /// will be deleted. + /// + /// It will also return null if the module is released. + llvm::Module *GetModule(); + + /// Release ownership of the module to the caller. + /// + /// It is illegal to call methods other than GetModule on the + /// CodeGenerator after releasing its module. + llvm::Module *ReleaseModule(); + + /// Given a mangled name, return a declaration which mangles that way + /// which has been added to this code generator via a Handle method. + /// + /// This may return null if there was no matching declaration. + const Decl *GetDeclForMangledName(llvm::StringRef MangledName); + + /// Return the LLVM address of the given global entity. + /// + /// \param isForDefinition If true, the caller intends to define the + /// entity; the object returned will be an llvm::GlobalValue of + /// some sort. If false, the caller just intends to use the entity; + /// the object returned may be any sort of constant value, and the + /// code generator will schedule the entity for emission if a + /// definition has been registered with this code generator. + llvm::Constant *GetAddrOfGlobal(GlobalDecl decl, bool isForDefinition); +}; + +/// CreateLLVMCodeGen - Create a CodeGenerator instance. +/// It is the responsibility of the caller to call delete on +/// the allocated CodeGenerator instance. +CodeGenerator *CreateLLVMCodeGen(DiagnosticsEngine &Diags, + llvm::StringRef ModuleName, + const HeaderSearchOptions &HeaderSearchOpts, + const PreprocessorOptions &PreprocessorOpts, + const CodeGenOptions &CGO, + llvm::LLVMContext& C, + CoverageSourceInfo *CoverageInfo = nullptr); + +} // end namespace clang + #endif diff --git a/include/clang/CodeGen/ObjectFilePCHContainerOperations.h b/include/clang/CodeGen/ObjectFilePCHContainerOperations.h index 15132acfc24af..6437f4f9b4f5d 100644 --- a/include/clang/CodeGen/ObjectFilePCHContainerOperations.h +++ b/include/clang/CodeGen/ObjectFilePCHContainerOperations.h @@ -22,10 +22,12 @@ class ObjectFilePCHContainerWriter : public PCHContainerWriter { /// Return an ASTConsumer that can be chained with a /// PCHGenerator that produces a wrapper file format /// that also contains full debug info for the module. - std::unique_ptr<ASTConsumer> CreatePCHContainerGenerator( - CompilerInstance &CI, const std::string &MainFileName, - const std::string &OutputFileName, llvm::raw_pwrite_stream *OS, - std::shared_ptr<PCHBuffer> Buffer) const override; + std::unique_ptr<ASTConsumer> + CreatePCHContainerGenerator(CompilerInstance &CI, + const std::string &MainFileName, + const std::string &OutputFileName, + std::unique_ptr<llvm::raw_pwrite_stream> OS, + std::shared_ptr<PCHBuffer> Buffer) const override; }; /// A PCHContainerReader implementation that uses LLVM to diff --git a/include/clang/CodeGen/SwiftCallingConv.h b/include/clang/CodeGen/SwiftCallingConv.h new file mode 100644 index 0000000000000..f9c2fd94ca8d7 --- /dev/null +++ b/include/clang/CodeGen/SwiftCallingConv.h @@ -0,0 +1,168 @@ +//==-- SwiftCallingConv.h - Swift ABI lowering -----------------------------==// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Defines constants and types related to Swift ABI lowering. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_CODEGEN_SWIFTCALLINGCONV_H +#define LLVM_CLANG_CODEGEN_SWIFTCALLINGCONV_H + +#include "clang/AST/CanonicalType.h" +#include "clang/AST/CharUnits.h" +#include "clang/AST/Type.h" +#include "llvm/ADT/FoldingSet.h" +#include "llvm/Support/TrailingObjects.h" +#include <cassert> + +namespace llvm { + class IntegerType; + class Type; + class StructType; + class VectorType; +} + +namespace clang { +class Decl; +class FieldDecl; +class ASTRecordLayout; + +namespace CodeGen { +class ABIArgInfo; +class CodeGenModule; +class CGFunctionInfo; + +namespace swiftcall { + +class SwiftAggLowering { + CodeGenModule &CGM; + + struct StorageEntry { + CharUnits Begin; + CharUnits End; + llvm::Type *Type; + + CharUnits getWidth() const { + return End - Begin; + } + }; + SmallVector<StorageEntry, 4> Entries; + bool Finished = false; + +public: + SwiftAggLowering(CodeGenModule &CGM) : CGM(CGM) {} + + void addOpaqueData(CharUnits begin, CharUnits end) { + addEntry(nullptr, begin, end); + } + + void addTypedData(QualType type, CharUnits begin); + void addTypedData(const RecordDecl *record, CharUnits begin); + void addTypedData(const RecordDecl *record, CharUnits begin, + const ASTRecordLayout &layout); + void addTypedData(llvm::Type *type, CharUnits begin); + void addTypedData(llvm::Type *type, CharUnits begin, CharUnits end); + + void finish(); + + /// Does this lowering require passing any data? + bool empty() const { + assert(Finished && "didn't finish lowering before calling empty()"); + return Entries.empty(); + } + + /// According to the target Swift ABI, should a value with this lowering + /// be passed indirectly? + /// + /// Note that this decision is based purely on the data layout of the + /// value and does not consider whether the type is address-only, + /// must be passed indirectly to match a function abstraction pattern, or + /// anything else that is expected to be handled by high-level lowering. + /// + /// \param asReturnValue - if true, answer whether it should be passed + /// indirectly as a return value; if false, answer whether it should be + /// passed indirectly as an argument + bool shouldPassIndirectly(bool asReturnValue) const; + + using EnumerationCallback = + llvm::function_ref<void(CharUnits offset, llvm::Type *type)>; + + /// Enumerate the expanded components of this type. + /// + /// The component types will always be legal vector, floating-point, + /// integer, or pointer types. + void enumerateComponents(EnumerationCallback callback) const; + + /// Return the types for a coerce-and-expand operation. + /// + /// The first type matches the memory layout of the data that's been + /// added to this structure, including explicit [N x i8] arrays for any + /// internal padding. + /// + /// The second type removes any internal padding members and, if only + /// one element remains, is simply that element type. + std::pair<llvm::StructType*, llvm::Type*> getCoerceAndExpandTypes() const; + +private: + void addBitFieldData(const FieldDecl *field, CharUnits begin, + uint64_t bitOffset); + void addLegalTypedData(llvm::Type *type, CharUnits begin, CharUnits end); + void addEntry(llvm::Type *type, CharUnits begin, CharUnits end); + void splitVectorEntry(unsigned index); +}; + +/// Return the maximum voluntary integer size for the current target. +CharUnits getMaximumVoluntaryIntegerSize(CodeGenModule &CGM); + +/// Return the Swift CC's notion of the natural alignment of a type. +CharUnits getNaturalAlignment(CodeGenModule &CGM, llvm::Type *type); + +/// Is the given integer type "legal" for Swift's perspective on the +/// current platform? +bool isLegalIntegerType(CodeGenModule &CGM, llvm::IntegerType *type); + +/// Is the given vector type "legal" for Swift's perspective on the +/// current platform? +bool isLegalVectorType(CodeGenModule &CGM, CharUnits vectorSize, + llvm::VectorType *vectorTy); +bool isLegalVectorType(CodeGenModule &CGM, CharUnits vectorSize, + llvm::Type *eltTy, unsigned numElts); + +/// Minimally split a legal vector type. +std::pair<llvm::Type*, unsigned> +splitLegalVectorType(CodeGenModule &CGM, CharUnits vectorSize, + llvm::VectorType *vectorTy); + +/// Turn a vector type in a sequence of legal component vector types. +/// +/// The caller may assume that the sum of the data sizes of the resulting +/// types will equal the data size of the vector type. +void legalizeVectorType(CodeGenModule &CGM, CharUnits vectorSize, + llvm::VectorType *vectorTy, + llvm::SmallVectorImpl<llvm::Type*> &types); + +/// Should a C++ record type be passed and returned indirectly? +bool shouldPassCXXRecordIndirectly(CodeGenModule &CGM, + const CXXRecordDecl *record); + +/// Classify the rules for how to return a particular type. +ABIArgInfo classifyReturnType(CodeGenModule &CGM, CanQualType type); + +/// Classify the rules for how to pass a particular type. +ABIArgInfo classifyArgumentType(CodeGenModule &CGM, CanQualType type); + +/// Compute the ABI information of a swiftcall function. This is a +/// private interface for Clang. +void computeABIInfo(CodeGenModule &CGM, CGFunctionInfo &FI); + +} // end namespace swiftcall +} // end namespace CodeGen +} // end namespace clang + +#endif diff --git a/include/clang/Config/config.h.cmake b/include/clang/Config/config.h.cmake index b7486f34da6b8..e5a1d0dac8371 100644 --- a/include/clang/Config/config.h.cmake +++ b/include/clang/Config/config.h.cmake @@ -8,6 +8,9 @@ /* Bug report URL. */ #define BUG_REPORT_URL "${BUG_REPORT_URL}" +/* Default C++ stdlib to use. */ +#define CLANG_DEFAULT_CXX_STDLIB "${CLANG_DEFAULT_CXX_STDLIB}" + /* Default OpenMP runtime used by -fopenmp. */ #define CLANG_DEFAULT_OPENMP_RUNTIME "${CLANG_DEFAULT_OPENMP_RUNTIME}" @@ -35,4 +38,10 @@ /* Linker version detected at compile time. */ #cmakedefine HOST_LINK_VERSION "${HOST_LINK_VERSION}" +/* pass --build-id to ld */ +#cmakedefine ENABLE_LINKER_BUILD_ID + +/* enable x86 relax relocations by default */ +#cmakedefine01 ENABLE_X86_RELAX_RELOCATIONS + #endif diff --git a/include/clang/Config/config.h.in b/include/clang/Config/config.h.in deleted file mode 100644 index 91983f6430fe2..0000000000000 --- a/include/clang/Config/config.h.in +++ /dev/null @@ -1,40 +0,0 @@ -/* This generated file is for internal use. Do not include it from headers. */ - -#ifdef CLANG_CONFIG_H -#error config.h can only be included once -#else -#define CLANG_CONFIG_H - -/* Bug report URL. */ -#undef BUG_REPORT_URL - -/* Default OpenMP runtime used by -fopenmp. */ -#undef CLANG_DEFAULT_OPENMP_RUNTIME - -/* Multilib suffix for libdir. */ -#undef CLANG_LIBDIR_SUFFIX - -/* Relative directory for resource files */ -#undef CLANG_RESOURCE_DIR - -/* Directories clang will search for headers */ -#undef C_INCLUDE_DIRS - -/* Default <path> to all compiler invocations for --sysroot=<path>. */ -#undef DEFAULT_SYSROOT - -/* Directory where gcc is installed. */ -#undef GCC_INSTALL_PREFIX - -/* Define if we have libxml2 */ -#undef CLANG_HAVE_LIBXML - -#undef PACKAGE_STRING - -/* The LLVM product name and version */ -#define BACKEND_PACKAGE_STRING PACKAGE_STRING - -/* Linker version detected at compile time. */ -#undef HOST_LINK_VERSION - -#endif diff --git a/include/clang/Driver/Action.h b/include/clang/Driver/Action.h index c5b0f4755092f..3fe6510fec98c 100644 --- a/include/clang/Driver/Action.h +++ b/include/clang/Driver/Action.h @@ -10,8 +10,10 @@ #ifndef LLVM_CLANG_DRIVER_ACTION_H #define LLVM_CLANG_DRIVER_ACTION_H +#include "clang/Basic/Cuda.h" #include "clang/Driver/Types.h" #include "clang/Driver/Util.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallVector.h" namespace llvm { @@ -26,6 +28,8 @@ namespace opt { namespace clang { namespace driver { +class ToolChain; + /// Action - Represent an abstract compilation step to perform. /// /// An action represents an edge in the compilation graph; typically @@ -41,14 +45,15 @@ namespace driver { class Action { public: typedef ActionList::size_type size_type; - typedef ActionList::iterator iterator; - typedef ActionList::const_iterator const_iterator; + typedef ActionList::iterator input_iterator; + typedef ActionList::const_iterator input_const_iterator; + typedef llvm::iterator_range<input_iterator> input_range; + typedef llvm::iterator_range<input_const_iterator> input_const_range; enum ActionClass { InputClass = 0, BindArchClass, - CudaDeviceClass, - CudaHostClass, + OffloadClass, PreprocessJobClass, PrecompileJobClass, AnalyzeJobClass, @@ -62,8 +67,19 @@ public: VerifyDebugInfoJobClass, VerifyPCHJobClass, - JobClassFirst=PreprocessJobClass, - JobClassLast=VerifyPCHJobClass + JobClassFirst = PreprocessJobClass, + JobClassLast = VerifyPCHJobClass + }; + + // The offloading kind determines if this action is binded to a particular + // programming model. Each entry reserves one bit. We also have a special kind + // to designate the host offloading tool chain. + enum OffloadKind { + OFK_None = 0x00, + // The host offloading tool chain. + OFK_Host = 0x01, + // The device offloading tool chains - one bit for each programming model. + OFK_Cuda = 0x02, }; static const char *getClassName(ActionClass AC); @@ -77,6 +93,19 @@ private: ActionList Inputs; protected: + /// + /// Offload information. + /// + + /// The host offloading kind - a combination of kinds encoded in a mask. + /// Multiple programming models may be supported simultaneously by the same + /// host. + unsigned ActiveOffloadKindMask = 0u; + /// Offloading kind of the device. + OffloadKind OffloadingDeviceKind = OFK_None; + /// The Offloading architecture associated with this action. + const char *OffloadingArch = nullptr; + Action(ActionClass Kind, types::ID Type) : Action(Kind, ActionList(), Type) {} Action(ActionClass Kind, Action *Input, types::ID Type) : Action(Kind, ActionList({Input}), Type) {} @@ -98,10 +127,49 @@ public: size_type size() const { return Inputs.size(); } - iterator begin() { return Inputs.begin(); } - iterator end() { return Inputs.end(); } - const_iterator begin() const { return Inputs.begin(); } - const_iterator end() const { return Inputs.end(); } + input_iterator input_begin() { return Inputs.begin(); } + input_iterator input_end() { return Inputs.end(); } + input_range inputs() { return input_range(input_begin(), input_end()); } + input_const_iterator input_begin() const { return Inputs.begin(); } + input_const_iterator input_end() const { return Inputs.end(); } + input_const_range inputs() const { + return input_const_range(input_begin(), input_end()); + } + + /// Return a string containing the offload kind of the action. + std::string getOffloadingKindPrefix() const; + /// Return a string that can be used as prefix in order to generate unique + /// files for each offloading kind. + std::string + getOffloadingFileNamePrefix(llvm::StringRef NormalizedTriple) const; + + /// Set the device offload info of this action and propagate it to its + /// dependences. + void propagateDeviceOffloadInfo(OffloadKind OKind, const char *OArch); + /// Append the host offload info of this action and propagate it to its + /// dependences. + void propagateHostOffloadInfo(unsigned OKinds, const char *OArch); + /// Set the offload info of this action to be the same as the provided action, + /// and propagate it to its dependences. + void propagateOffloadInfo(const Action *A); + + unsigned getOffloadingHostActiveKinds() const { + return ActiveOffloadKindMask; + } + OffloadKind getOffloadingDeviceKind() const { return OffloadingDeviceKind; } + const char *getOffloadingArch() const { return OffloadingArch; } + + /// Check if this action have any offload kinds. Note that host offload kinds + /// are only set if the action is a dependence to a host offload action. + bool isHostOffloading(OffloadKind OKind) const { + return ActiveOffloadKindMask & OKind; + } + bool isDeviceOffloading(OffloadKind OKind) const { + return OffloadingDeviceKind == OKind; + } + bool isOffloading(OffloadKind OKind) const { + return isHostOffloading(OKind) || isDeviceOffloading(OKind); + } }; class InputAction : public Action { @@ -134,41 +202,126 @@ public: } }; -class CudaDeviceAction : public Action { +/// An offload action combines host or/and device actions according to the +/// programming model implementation needs and propagates the offloading kind to +/// its dependences. +class OffloadAction final : public Action { virtual void anchor(); - /// GPU architecture to bind. Always of the form /sm_\d+/. - const char *GpuArchName; - /// True when action results are not consumed by the host action (e.g when - /// -fsyntax-only or --cuda-device-only options are used). - bool AtTopLevel; public: - CudaDeviceAction(Action *Input, const char *ArchName, bool AtTopLevel); + /// Type used to communicate device actions. It associates bound architecture, + /// toolchain, and offload kind to each action. + class DeviceDependences final { + public: + typedef SmallVector<const ToolChain *, 3> ToolChainList; + typedef SmallVector<const char *, 3> BoundArchList; + typedef SmallVector<OffloadKind, 3> OffloadKindList; + + private: + // Lists that keep the information for each dependency. All the lists are + // meant to be updated in sync. We are adopting separate lists instead of a + // list of structs, because that simplifies forwarding the actions list to + // initialize the inputs of the base Action class. + + /// The dependence actions. + ActionList DeviceActions; + /// The offloading toolchains that should be used with the action. + ToolChainList DeviceToolChains; + /// The architectures that should be used with this action. + BoundArchList DeviceBoundArchs; + /// The offload kind of each dependence. + OffloadKindList DeviceOffloadKinds; + + public: + /// Add a action along with the associated toolchain, bound arch, and + /// offload kind. + void add(Action &A, const ToolChain &TC, const char *BoundArch, + OffloadKind OKind); + + /// Get each of the individual arrays. + const ActionList &getActions() const { return DeviceActions; }; + const ToolChainList &getToolChains() const { return DeviceToolChains; }; + const BoundArchList &getBoundArchs() const { return DeviceBoundArchs; }; + const OffloadKindList &getOffloadKinds() const { + return DeviceOffloadKinds; + }; + }; - const char *getGpuArchName() const { return GpuArchName; } + /// Type used to communicate host actions. It associates bound architecture, + /// toolchain, and offload kinds to the host action. + class HostDependence final { + /// The dependence action. + Action &HostAction; + /// The offloading toolchain that should be used with the action. + const ToolChain &HostToolChain; + /// The architectures that should be used with this action. + const char *HostBoundArch = nullptr; + /// The offload kind of each dependence. + unsigned HostOffloadKinds = 0u; + + public: + HostDependence(Action &A, const ToolChain &TC, const char *BoundArch, + const unsigned OffloadKinds) + : HostAction(A), HostToolChain(TC), HostBoundArch(BoundArch), + HostOffloadKinds(OffloadKinds){}; + /// Constructor version that obtains the offload kinds from the device + /// dependencies. + HostDependence(Action &A, const ToolChain &TC, const char *BoundArch, + const DeviceDependences &DDeps); + Action *getAction() const { return &HostAction; }; + const ToolChain *getToolChain() const { return &HostToolChain; }; + const char *getBoundArch() const { return HostBoundArch; }; + unsigned getOffloadKinds() const { return HostOffloadKinds; }; + }; - /// Gets the compute_XX that corresponds to getGpuArchName(). - const char *getComputeArchName() const; + typedef llvm::function_ref<void(Action *, const ToolChain *, const char *)> + OffloadActionWorkTy; - bool isAtTopLevel() const { return AtTopLevel; } +private: + /// The host offloading toolchain that should be used with the action. + const ToolChain *HostTC = nullptr; - static bool IsValidGpuArchName(llvm::StringRef ArchName); + /// The tool chains associated with the list of actions. + DeviceDependences::ToolChainList DevToolChains; - static bool classof(const Action *A) { - return A->getKind() == CudaDeviceClass; - } -}; +public: + OffloadAction(const HostDependence &HDep); + OffloadAction(const DeviceDependences &DDeps, types::ID Ty); + OffloadAction(const HostDependence &HDep, const DeviceDependences &DDeps); -class CudaHostAction : public Action { - virtual void anchor(); - ActionList DeviceActions; + /// Execute the work specified in \a Work on the host dependence. + void doOnHostDependence(const OffloadActionWorkTy &Work) const; -public: - CudaHostAction(Action *Input, const ActionList &DeviceActions); + /// Execute the work specified in \a Work on each device dependence. + void doOnEachDeviceDependence(const OffloadActionWorkTy &Work) const; + + /// Execute the work specified in \a Work on each dependence. + void doOnEachDependence(const OffloadActionWorkTy &Work) const; + + /// Execute the work specified in \a Work on each host or device dependence if + /// \a IsHostDependenceto is true or false, respectively. + void doOnEachDependence(bool IsHostDependence, + const OffloadActionWorkTy &Work) const; + + /// Return true if the action has a host dependence. + bool hasHostDependence() const; + + /// Return the host dependence of this action. This function is only expected + /// to be called if the host dependence exists. + Action *getHostDependence() const; + + /// Return true if the action has a single device dependence. If \a + /// DoNotConsiderHostActions is set, ignore the host dependence, if any, while + /// accounting for the number of dependences. + bool hasSingleDeviceDependence(bool DoNotConsiderHostActions = false) const; - const ActionList &getDeviceActions() const { return DeviceActions; } + /// Return the single device dependence of this action. This function is only + /// expected to be called if a single device dependence exists. If \a + /// DoNotConsiderHostActions is set, a host dependence is allowed. + Action * + getSingleDeviceDependence(bool DoNotConsiderHostActions = false) const; - static bool classof(const Action *A) { return A->getKind() == CudaHostClass; } + static bool classof(const Action *A) { return A->getKind() == OffloadClass; } }; class JobAction : public Action { diff --git a/include/clang/Driver/CC1Options.td b/include/clang/Driver/CC1Options.td index 051f903375682..1401984c2a348 100644 --- a/include/clang/Driver/CC1Options.td +++ b/include/clang/Driver/CC1Options.td @@ -143,6 +143,8 @@ def mno_exec_stack : Flag<["-"], "mnoexecstack">, HelpText<"Mark the file as not needing an executable stack">; def massembler_fatal_warnings : Flag<["-"], "massembler-fatal-warnings">, HelpText<"Make assembler warnings fatal">; +def mrelax_relocations : Flag<["--"], "mrelax-relocations">, + HelpText<"Use relaxable elf relocations">; def compress_debug_sections : Flag<["-"], "compress-debug-sections">, HelpText<"Compress DWARF debug sections using zlib">; def msave_temp_labels : Flag<["-"], "msave-temp-labels">, @@ -151,6 +153,8 @@ def msave_temp_labels : Flag<["-"], "msave-temp-labels">, "on compiler-generated code.">; def mrelocation_model : Separate<["-"], "mrelocation-model">, HelpText<"The relocation model to use">; +def fno_math_builtin : Flag<["-"], "fno-math-builtin">, + HelpText<"Disable implicit builtin knowledge of math functions">; } def disable_llvm_optzns : Flag<["-"], "disable-llvm-optzns">, @@ -252,6 +256,8 @@ def vectorize_slp_aggressive : Flag<["-"], "vectorize-slp-aggressive">, HelpText<"Run the BB vectorization passes">; def dependent_lib : Joined<["--"], "dependent-lib=">, HelpText<"Add dependent library">; +def linker_option : Joined<["--"], "linker-option=">, + HelpText<"Add linker option">; def fsanitize_coverage_type : Joined<["-"], "fsanitize-coverage-type=">, HelpText<"Sanitizer coverage type">; def fsanitize_coverage_indirect_calls @@ -266,6 +272,21 @@ def fsanitize_coverage_trace_cmp def fsanitize_coverage_8bit_counters : Flag<["-"], "fsanitize-coverage-8bit-counters">, HelpText<"Enable frequency counters in sanitizer coverage">; +def fsanitize_coverage_trace_pc + : Flag<["-"], "fsanitize-coverage-trace-pc">, + HelpText<"Enable PC tracing in sanitizer coverage">; +def fprofile_instrument_EQ : Joined<["-"], "fprofile-instrument=">, + HelpText<"Enable PGO instrumentation. The accepted value is clang, llvm, " + "or none">; +def fprofile_instrument_path_EQ : Joined<["-"], "fprofile-instrument-path=">, + HelpText<"Generate instrumented code to collect execution counts into " + "<file> (overridden by LLVM_PROFILE_FILE env var)">; +def fprofile_instrument_use_path_EQ : + Joined<["-"], "fprofile-instrument-use-path=">, + HelpText<"Specify the profile path in PGO use compilation">; +def flto_visibility_public_std: + Flag<["-"], "flto-visibility-public-std">, + HelpText<"Use public LTO visibility for classes in std and stdext namespaces">; //===----------------------------------------------------------------------===// // Dependency Output Options @@ -351,6 +372,8 @@ def code_completion_brief_comments : Flag<["-"], "code-completion-brief-comments HelpText<"Include brief documentation comments in code-completion results.">; def disable_free : Flag<["-"], "disable-free">, HelpText<"Disable freeing of memory on exit">; +def discard_value_names : Flag<["-"], "discard-value-names">, + HelpText<"Discard value names in LLVM IR">; def load : Separate<["-"], "load">, MetaVarName<"<dsopath>">, HelpText<"Load the named plugin (dynamic shared object)">; def plugin : Separate<["-"], "plugin">, MetaVarName<"<name>">, @@ -369,9 +392,6 @@ def fno_modules_global_index : Flag<["-"], "fno-modules-global-index">, HelpText<"Do not automatically generate or update the global module index">; def fno_modules_error_recovery : Flag<["-"], "fno-modules-error-recovery">, HelpText<"Do not automatically import modules for error recovery">; -def fmodule_implementation_of : Separate<["-"], "fmodule-implementation-of">, - MetaVarName<"<name>">, - HelpText<"Specify the name of the module whose implementation file this is">; def fmodule_map_file_home_is_cwd : Flag<["-"], "fmodule-map-file-home-is-cwd">, HelpText<"Use the current working directory as the home directory of " "module maps specified by -fmodule-map-file=<FILE>">; @@ -485,6 +505,12 @@ def fixit_to_temp : Flag<["-"], "fixit-to-temporary">, def foverride_record_layout_EQ : Joined<["-"], "foverride-record-layout=">, HelpText<"Override record layouts with those in the given file">; +def find_pch_source_EQ : Joined<["-"], "find-pch-source=">, + HelpText<"When building a pch, try to find the input file in include " + "directories, as if it had been included by the argument passed " + "to this flag.">; +def fno_pch_timestamp : Flag<["-"], "fno-pch-timestamp">, + HelpText<"Disable inclusion of timestamp in precompiled headers">; //===----------------------------------------------------------------------===// // Language Options @@ -501,10 +527,8 @@ def main_file_name : Separate<["-"], "main-file-name">, def fblocks_runtime_optional : Flag<["-"], "fblocks-runtime-optional">, HelpText<"Weakly link in the blocks runtime">; -def fsjlj_exceptions : Flag<["-"], "fsjlj-exceptions">, - HelpText<"Use SjLj style exceptions">; -def fnew_ms_eh: Flag<["-"], "fnew-ms-eh">, - HelpText<"Use the new IR representation for MS exceptions">; +def fexternc_nounwind : Flag<["-"], "fexternc-nounwind">, + HelpText<"Assume all functions with C linkage do not unwind">; def split_dwarf_file : Separate<["-"], "split-dwarf-file">, HelpText<"File name to use for split dwarf debug info output">; def fno_wchar : Flag<["-"], "fno-wchar">, @@ -524,8 +548,8 @@ def fencode_extended_block_signature : Flag<["-"], "fencode-extended-block-signa HelpText<"enable extended encoding of block type signature">; def pic_level : Separate<["-"], "pic-level">, HelpText<"Value for __PIC__">; -def pie_level : Separate<["-"], "pie-level">, - HelpText<"Value for __PIE__">; +def pic_is_pie : Flag<["-"], "pic-is-pie">, + HelpText<"File is for a position independent executable">; def fno_validate_pch : Flag<["-"], "fno-validate-pch">, HelpText<"Disable validation of precompiled headers">; def dump_deserialized_pch_decls : Flag<["-"], "dump-deserialized-decls">, @@ -584,8 +608,14 @@ def fno_rtti_data : Flag<["-"], "fno-rtti-data">, HelpText<"Control emission of RTTI data">; def fnative_half_type: Flag<["-"], "fnative-half-type">, HelpText<"Use the native half type for __fp16 instead of promoting to float">; +def fnative_half_arguments_and_returns : Flag<["-"], "fnative-half-arguments-and-returns">, + HelpText<"Use the native __fp16 type for arguments and returns (and skip ABI-specific lowering)">; 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">; +def finclude_default_header : Flag<["-"], "finclude-default-header">, + HelpText<"Include the default header file for OpenCL">; // C++ TSes. def fcoroutines : Flag<["-"], "fcoroutines">, @@ -636,46 +666,17 @@ def detailed_preprocessing_record : Flag<["-"], "detailed-preprocessing-record"> HelpText<"include a detailed record of preprocessing actions">; //===----------------------------------------------------------------------===// -// OpenCL Options -//===----------------------------------------------------------------------===// - -def cl_opt_disable : Flag<["-"], "cl-opt-disable">, - HelpText<"OpenCL only. This option disables all optimizations. The default is optimizations are enabled.">; -def cl_strict_aliasing : Flag<["-"], "cl-strict-aliasing">, - HelpText<"OpenCL only. This option does nothing and is for compatibility with OpenCL 1.0">; -def cl_single_precision_constant : Flag<["-"], "cl-single-precision-constant">, - HelpText<"OpenCL only. Treat double precision floating-point constant as single precision constant.">; -def cl_finite_math_only : Flag<["-"], "cl-finite-math-only">, - HelpText<"OpenCL only. Allow floating-point optimizations that assume arguments and results are not NaNs or +-Inf.">; -def cl_kernel_arg_info : Flag<["-"], "cl-kernel-arg-info">, - HelpText<"OpenCL only. Generate kernel argument metadata.">; -def cl_unsafe_math_optimizations : Flag<["-"], "cl-unsafe-math-optimizations">, - HelpText<"OpenCL only. Allow unsafe floating-point optimizations. Also implies -cl-no-signed-zeros and -cl-mad-enable">; -def cl_fast_relaxed_math : Flag<["-"], "cl-fast-relaxed-math">, - HelpText<"OpenCL only. Sets -cl-finite-math-only and -cl-unsafe-math-optimizations, and defines __FAST_RELAXED_MATH__">; -def cl_mad_enable : Flag<["-"], "cl-mad-enable">, - HelpText<"OpenCL only. Enable less precise MAD instructions to be generated.">; -def cl_std_EQ : Joined<["-"], "cl-std=">, - HelpText<"OpenCL language standard to compile for">; -def cl_denorms_are_zero : Flag<["-"], "cl-denorms-are-zero">, - HelpText<"OpenCL only. Allow denormals to be flushed to zero">; - -//===----------------------------------------------------------------------===// // CUDA Options //===----------------------------------------------------------------------===// def fcuda_is_device : Flag<["-"], "fcuda-is-device">, HelpText<"Generate code for CUDA device">; -def fcuda_allow_host_calls_from_host_device : Flag<["-"], - "fcuda-allow-host-calls-from-host-device">, - HelpText<"Allow host device functions to call host functions">; -def fcuda_disable_target_call_checks : Flag<["-"], - "fcuda-disable-target-call-checks">, - HelpText<"Disable all cross-target (host, device, etc.) call checks in CUDA">; def fcuda_include_gpubinary : Separate<["-"], "fcuda-include-gpubinary">, HelpText<"Incorporate CUDA device-side binary into host object file.">; -def fcuda_target_overloads : Flag<["-"], "fcuda-target-overloads">, - HelpText<"Enable function overloads based on CUDA target attributes.">; +def fcuda_allow_variadic_functions : Flag<["-"], "fcuda-allow-variadic-functions">, + HelpText<"Allow variadic functions in CUDA device code.">; +def fno_cuda_host_device_constexpr : Flag<["-"], "fno-cuda-host-device-constexpr">, + HelpText<"Don't treat unattributed constexpr functions as __host__ __device__.">; //===----------------------------------------------------------------------===// // OpenMP Options @@ -683,7 +684,7 @@ def fcuda_target_overloads : Flag<["-"], "fcuda-target-overloads">, def fopenmp_is_device : Flag<["-"], "fopenmp-is-device">, HelpText<"Generate code only for an OpenMP target device.">; -def omp_host_ir_file_path : Separate<["-"], "omp-host-ir-file-path">, +def fopenmp_host_ir_file_path : Separate<["-"], "fopenmp-host-ir-file-path">, HelpText<"Path to the IR file produced by the frontend for the host.">; } // let Flags = [CC1Option] diff --git a/include/clang/Driver/CLCompatOptions.td b/include/clang/Driver/CLCompatOptions.td index 16a5b727836c3..b1d2459f71cfb 100644 --- a/include/clang/Driver/CLCompatOptions.td +++ b/include/clang/Driver/CLCompatOptions.td @@ -45,8 +45,8 @@ class CLCompileJoinedOrSeparate<string name> : Option<["/", "-"], name, KIND_JOINED_OR_SEPARATE>, Group<cl_compile_Group>, Flags<[CLOption, DriverOption]>; -class CLRemainingArgs<string name> : Option<["/", "-"], name, - KIND_REMAINING_ARGS>, Group<cl_Group>, Flags<[CLOption, DriverOption]>; +class CLRemainingArgsJoined<string name> : Option<["/", "-"], name, + KIND_REMAINING_ARGS_JOINED>, Group<cl_Group>, Flags<[CLOption, DriverOption]>; // Aliases: // (We don't put any of these in cl_compile_Group as the options they alias are @@ -77,6 +77,8 @@ def _SLASH_GR : CLFlag<"GR">, HelpText<"Enable emission of RTTI data">; def _SLASH_GR_ : CLFlag<"GR-">, HelpText<"Disable emission of RTTI data">; def _SLASH_GF_ : CLFlag<"GF-">, HelpText<"Disable string pooling">, Alias<fwritable_strings>; +def _SLASH_GS : CLFlag<"GS">, HelpText<"Enable buffer security check">; +def _SLASH_GS_ : CLFlag<"GS-">, HelpText<"Disable buffer security check">; def _SLASH_Gs : CLJoined<"Gs">, HelpText<"Set stack probe size">, Alias<mstack_probe_size>; def _SLASH_Gy : CLFlag<"Gy">, HelpText<"Put each function in its own section">, @@ -98,9 +100,8 @@ def _SLASH_I : CLJoinedOrSeparate<"I">, def _SLASH_J : CLFlag<"J">, HelpText<"Make char type unsigned">, Alias<funsigned_char>; def _SLASH_O0 : CLFlag<"O0">, Alias<O0>; +// /Oy- is handled by the /O option because /Oy- only has an effect on 32-bit. def _SLASH_O : CLJoined<"O">, HelpText<"Optimization level">; -def _SLASH_Ob0 : CLFlag<"Ob0">, HelpText<"Disable inlining">, - Alias<fno_inline>; def _SLASH_Od : CLFlag<"Od">, HelpText<"Disable optimization">, Alias<O0>; def _SLASH_Oi : CLFlag<"Oi">, HelpText<"Enable use of builtin functions">, Alias<fbuiltin>; @@ -119,6 +120,8 @@ def _SLASH_Qvec_ : CLFlag<"Qvec-">, def _SLASH_showIncludes : CLFlag<"showIncludes">, HelpText<"Print info about included files to stderr">, Alias<show_includes>; +def _SLASH_std : CLCompileJoined<"std:">, + HelpText<"Language standard to compile for">; def _SLASH_U : CLJoinedOrSeparate<"U">, HelpText<"Undefine macro">, MetaVarName<"<macro>">, Alias<U>; def _SLASH_W0 : CLFlag<"W0">, HelpText<"Disable all warnings">, Alias<w>; @@ -163,6 +166,8 @@ def _SLASH_Zc_trigraphs_off : CLFlag<"Zc:trigraphs-">, HelpText<"Disable trigraphs (default)">, Alias<fno_trigraphs>; def _SLASH_Z7 : CLFlag<"Z7">, HelpText<"Enable CodeView debug information in object files">; +def _SLASH_Zd : CLFlag<"Zd">, + HelpText<"Emit debug line number tables only">; def _SLASH_Zi : CLFlag<"Zi">, Alias<_SLASH_Z7>, HelpText<"Alias for /Z7. Does not produce PDBs.">; def _SLASH_Zp : CLJoined<"Zp">, @@ -205,9 +210,16 @@ def _SLASH_Fi : CLCompileJoined<"Fi">, def _SLASH_Fo : CLCompileJoined<"Fo">, HelpText<"Set output object file, or directory (ends in / or \\) (with /c)">, MetaVarName<"<file or directory>">; +def _SLASH_GX : CLFlag<"GX">, + HelpText<"Enable exception handling">; +def _SLASH_GX_ : CLFlag<"GX-">, + HelpText<"Enable exception handling">; +def _SLASH_imsvc : CLJoinedOrSeparate<"imsvc">, + HelpText<"Add directory to system include search path, as if part of %INCLUDE%">, + MetaVarName<"<dir>">; def _SLASH_LD : CLFlag<"LD">, HelpText<"Create DLL">; def _SLASH_LDd : CLFlag<"LDd">, HelpText<"Create debug DLL">; -def _SLASH_link : CLRemainingArgs<"link">, +def _SLASH_link : CLRemainingArgsJoined<"link">, HelpText<"Forward options to the linker">, MetaVarName<"<options>">; def _SLASH_MD : Option<["/", "-"], "MD", KIND_FLAG>, Group<_SLASH_M_Group>, Flags<[CLOption, DriverOption]>, HelpText<"Use DLL run-time">; @@ -248,22 +260,41 @@ def _SLASH_volatile_ms : Option<["/", "-"], "volatile:ms", KIND_FLAG>, def _SLASH_Zl : CLFlag<"Zl">, HelpText<"Don't mention any default libraries in the object file">; +def _SLASH_Yc : CLJoined<"Yc">, + HelpText<"Generate a pch file for all code up to and including <filename>">, + MetaVarName<"<filename>">; +def _SLASH_Yu : CLJoined<"Yu">, + HelpText<"Load a pch file and use it instead of all code up to " + "and including <filename>">, + MetaVarName<"<filename>">; +def _SLASH_Y_ : CLFlag<"Y-">, + HelpText<"Disable precompiled headers, overrides /Yc and /Yu">; +def _SLASH_Fp : CLJoined<"Fp">, + HelpText<"Set pch filename (with /Yc and /Yu)">, MetaVarName<"<filename>">; + +def _SLASH_Gd : CLFlag<"Gd">, + HelpText<"Set __cdecl as a default calling convention">; +def _SLASH_Gr : CLFlag<"Gr">, + HelpText<"Set __fastcall as a default calling convention">; +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">; + // Ignored: def _SLASH_analyze_ : CLIgnoredFlag<"analyze-">; def _SLASH_bigobj : CLIgnoredFlag<"bigobj">; def _SLASH_cgthreads : CLIgnoredJoined<"cgthreads">; +def _SLASH_d2FastFail : CLIgnoredFlag<"d2FastFail">; def _SLASH_d2Zi_PLUS : CLIgnoredFlag<"d2Zi+">; def _SLASH_errorReport : CLIgnoredJoined<"errorReport">; def _SLASH_Fd : CLIgnoredJoined<"Fd">; +def _SLASH_FC : CLIgnoredFlag<"FC">; def _SLASH_FS : CLIgnoredFlag<"FS">, HelpText<"Force synchronous PDB writes">; -def _SLASH_Gd : CLIgnoredFlag<"Gd">; def _SLASH_GF : CLIgnoredFlag<"GF">; -def _SLASH_GS_ : CLIgnoredFlag<"GS-">; def _SLASH_kernel_ : CLIgnoredFlag<"kernel-">; def _SLASH_nologo : CLIgnoredFlag<"nologo">; -def _SLASH_Ob1 : CLIgnoredFlag<"Ob1">; -def _SLASH_Ob2 : CLIgnoredFlag<"Ob2">; def _SLASH_Og : CLIgnoredFlag<"Og">; def _SLASH_openmp_ : CLIgnoredFlag<"openmp-">; def _SLASH_RTC : CLIgnoredJoined<"RTC">; @@ -287,10 +318,8 @@ def _SLASH_clr : CLJoined<"clr">; def _SLASH_doc : CLJoined<"doc">; def _SLASH_FA_joined : CLJoined<"FA">; def _SLASH_favor : CLJoined<"favor">; -def _SLASH_FC : CLFlag<"FC">; def _SLASH_F : CLFlag<"F">; def _SLASH_Fm : CLJoined<"Fm">; -def _SLASH_Fp : CLJoined<"Fp">; def _SLASH_Fr : CLJoined<"Fr">; def _SLASH_FR : CLJoined<"FR">; def _SLASH_FU : CLJoinedOrSeparate<"FU">; @@ -304,13 +333,8 @@ def _SLASH_GL : CLFlag<"GL">; def _SLASH_GL_ : CLFlag<"GL-">; def _SLASH_Gm : CLFlag<"Gm">; def _SLASH_Gm_ : CLFlag<"Gm-">; -def _SLASH_Gr : CLFlag<"Gr">; -def _SLASH_GS : CLFlag<"GS">; def _SLASH_GT : CLFlag<"GT">; def _SLASH_Guard : CLJoined<"guard:">; -def _SLASH_GX : CLFlag<"GX">; -def _SLASH_Gv : CLFlag<"Gv">; -def _SLASH_Gz : CLFlag<"Gz">; def _SLASH_GZ : CLFlag<"GZ">; def _SLASH_H : CLFlag<"H">; def _SLASH_homeparams : CLFlag<"homeparams">; @@ -329,11 +353,8 @@ def _SLASH_V : CLFlag<"V">; def _SLASH_WL : CLFlag<"WL">; def _SLASH_Wp64 : CLFlag<"Wp64">; def _SLASH_X : CLFlag<"X">; -def _SLASH_Yc : CLJoined<"Yc">; -def _SLASH_Y_ : CLFlag<"Y-">; def _SLASH_Yd : CLFlag<"Yd">; def _SLASH_Yl : CLJoined<"Yl">; -def _SLASH_Yu : CLJoined<"Yu">; def _SLASH_Za : CLFlag<"Za">; def _SLASH_Zc : CLJoined<"Zc:">; def _SLASH_Ze : CLFlag<"Ze">; diff --git a/include/clang/Driver/Compilation.h b/include/clang/Driver/Compilation.h index 3ed19135043af..3f387151a3d4f 100644 --- a/include/clang/Driver/Compilation.h +++ b/include/clang/Driver/Compilation.h @@ -15,6 +15,7 @@ #include "clang/Driver/Util.h" #include "llvm/ADT/DenseMap.h" #include "llvm/Support/Path.h" +#include <map> namespace llvm { namespace opt { @@ -38,8 +39,16 @@ class Compilation { /// The default tool chain. const ToolChain &DefaultToolChain; - const ToolChain *CudaHostToolChain; - const ToolChain *CudaDeviceToolChain; + /// A mask of all the programming models the host has to support in the + /// current compilation. + unsigned ActiveOffloadMask; + + /// Array with the toolchains of offloading host and devices in the order they + /// were requested by the user. We are preserving that order in case the code + /// generation needs to derive a programming-model-specific semantic out of + /// it. + std::multimap<Action::OffloadKind, const ToolChain *> + OrderedOffloadingToolchains; /// The original (untranslated) input argument list. llvm::opt::InputArgList *Args; @@ -89,16 +98,46 @@ public: const Driver &getDriver() const { return TheDriver; } const ToolChain &getDefaultToolChain() const { return DefaultToolChain; } - const ToolChain *getCudaHostToolChain() const { return CudaHostToolChain; } - const ToolChain *getCudaDeviceToolChain() const { - return CudaDeviceToolChain; + + unsigned isOffloadingHostKind(Action::OffloadKind Kind) const { + return ActiveOffloadMask & Kind; + } + + /// Iterator that visits device toolchains of a given kind. + typedef const std::multimap<Action::OffloadKind, + const ToolChain *>::const_iterator + const_offload_toolchains_iterator; + typedef std::pair<const_offload_toolchains_iterator, + const_offload_toolchains_iterator> + const_offload_toolchains_range; + + template <Action::OffloadKind Kind> + const_offload_toolchains_range getOffloadToolChains() const { + return OrderedOffloadingToolchains.equal_range(Kind); } - void setCudaHostToolChain(const ToolChain *HostToolChain) { - CudaHostToolChain = HostToolChain; + /// Return an offload toolchain of the provided kind. Only one is expected to + /// exist. + template <Action::OffloadKind Kind> + const ToolChain *getSingleOffloadToolChain() const { + auto TCs = getOffloadToolChains<Kind>(); + + assert(TCs.first != TCs.second && + "No tool chains of the selected kind exist!"); + assert(std::next(TCs.first) == TCs.second && + "More than one tool chain of the this kind exist."); + return TCs.first->second; } - void setCudaDeviceToolChain(const ToolChain *DeviceToolChain) { - CudaDeviceToolChain = DeviceToolChain; + + void addOffloadDeviceToolChain(const ToolChain *DeviceToolChain, + Action::OffloadKind OffloadKind) { + assert(OffloadKind != Action::OFK_Host && OffloadKind != Action::OFK_None && + "This is not a device tool chain!"); + + // Update the host offload kind to also contain this kind. + ActiveOffloadMask |= OffloadKind; + OrderedOffloadingToolchains.insert( + std::make_pair(OffloadKind, DeviceToolChain)); } const llvm::opt::InputArgList &getInputArgs() const { return *Args; } @@ -208,6 +247,15 @@ public: /// Return true if we're compiling for diagnostics. bool isForDiagnostics() const { return ForDiagnostics; } + + /// Redirect - Redirect output of this compilation. Can only be done once. + /// + /// \param Redirects - array of pointers to paths. The array + /// should have a size of three. The inferior process's + /// stdin(0), stdout(1), and stderr(2) will be redirected to the + /// corresponding paths. This compilation instance becomes + /// the owner of Redirects and will delete the array and StringRef's. + void Redirect(const StringRef** Redirects); }; } // end namespace driver diff --git a/include/clang/Driver/Driver.h b/include/clang/Driver/Driver.h index a229779e1aa1e..9ecf434a87e27 100644 --- a/include/clang/Driver/Driver.h +++ b/include/clang/Driver/Driver.h @@ -21,6 +21,7 @@ #include "llvm/Support/Path.h" // FIXME: Kill when CompilationInfo lands. #include <list> +#include <map> #include <memory> #include <set> #include <string> @@ -82,6 +83,12 @@ class Driver { SaveTempsObj } SaveTemps; + enum BitcodeEmbedMode { + EmbedNone, + EmbedMarker, + EmbedBitcode + } BitcodeEmbed; + /// LTO mode selected via -f(no-)?lto(=.*)? options. LTOKind LTOMode; @@ -189,7 +196,7 @@ public: private: /// Certain options suppress the 'no input files' warning. - bool SuppressMissingInputWarning : 1; + unsigned SuppressMissingInputWarning : 1; std::list<std::string> TempFiles; std::list<std::string> ResultFiles; @@ -241,7 +248,7 @@ public: void setCheckInputsExist(bool Value) { CheckInputsExist = Value; } const std::string &getTitle() { return DriverTitle; } - void setTitle(std::string Value) { DriverTitle = Value; } + void setTitle(std::string Value) { DriverTitle = std::move(Value); } /// \brief Get the path to the main clang executable. const char *getClangProgramPath() const { @@ -261,10 +268,18 @@ public: bool isSaveTempsEnabled() const { return SaveTemps != SaveTempsNone; } bool isSaveTempsObj() const { return SaveTemps == SaveTempsObj; } + bool embedBitcodeEnabled() const { return BitcodeEmbed == EmbedBitcode; } + bool embedBitcodeMarkerOnly() const { return BitcodeEmbed == EmbedMarker; } + /// @} /// @name Primary Functionality /// @{ + /// CreateOffloadingDeviceToolChains - create all the toolchains required to + /// support offloading devices given the programming models specified in the + /// current compilation. Also, update the host tool chain kind accordingly. + void CreateOffloadingDeviceToolChains(Compilation &C, InputList &Inputs); + /// BuildCompilation - Construct a compilation object for a command /// line argument vector. /// @@ -298,12 +313,10 @@ public: /// given arguments, which are only done for a single architecture. /// /// \param C - The compilation that is being built. - /// \param TC - The default host tool chain. /// \param Args - The input arguments. /// \param Actions - The list to store the resulting actions onto. - void BuildActions(Compilation &C, const ToolChain &TC, - llvm::opt::DerivedArgList &Args, const InputList &Inputs, - ActionList &Actions) const; + void BuildActions(Compilation &C, llvm::opt::DerivedArgList &Args, + const InputList &Inputs, ActionList &Actions) const; /// BuildUniversalActions - Construct the list of actions to perform /// for the given arguments, which may require a universal build. @@ -375,16 +388,19 @@ public: /// ConstructAction - Construct the appropriate action to do for /// \p Phase on the \p Input, taking in to account arguments /// like -fsyntax-only or --analyze. - Action *ConstructPhaseAction(Compilation &C, const ToolChain &TC, - const llvm::opt::ArgList &Args, phases::ID Phase, - Action *Input) const; - - /// BuildJobsForAction - Construct the jobs to perform for the - /// action \p A and return an InputInfo for the result of running \p A. - InputInfo BuildJobsForAction(Compilation &C, const Action *A, - const ToolChain *TC, const char *BoundArch, - bool AtTopLevel, bool MultipleArchs, - const char *LinkingOutput) const; + Action *ConstructPhaseAction(Compilation &C, const llvm::opt::ArgList &Args, + phases::ID Phase, Action *Input) const; + + /// BuildJobsForAction - Construct the jobs to perform for the action \p A and + /// return an InputInfo for the result of running \p A. Will only construct + /// jobs for a given (Action, ToolChain, BoundArch) tuple once. + InputInfo + BuildJobsForAction(Compilation &C, const Action *A, const ToolChain *TC, + const char *BoundArch, bool AtTopLevel, bool MultipleArchs, + const char *LinkingOutput, + std::map<std::pair<const Action *, std::string>, InputInfo> + &CachedResults, + bool BuildForOffloadDevice) const; /// Returns the default name for linked images (e.g., "a.out"). const char *getDefaultImageName() const; @@ -400,12 +416,11 @@ public: /// \param BoundArch - The bound architecture. /// \param AtTopLevel - Whether this is a "top-level" action. /// \param MultipleArchs - Whether multiple -arch options were supplied. - const char *GetNamedOutputPath(Compilation &C, - const JobAction &JA, - const char *BaseInput, - const char *BoundArch, - bool AtTopLevel, - bool MultipleArchs) const; + /// \param NormalizedTriple - The normalized triple of the relevant target. + const char *GetNamedOutputPath(Compilation &C, const JobAction &JA, + const char *BaseInput, const char *BoundArch, + bool AtTopLevel, bool MultipleArchs, + StringRef NormalizedTriple) const; /// GetTemporaryPath - Return the pathname of a temporary file to use /// as part of compilation; the file will have the given prefix and suffix. @@ -413,6 +428,9 @@ public: /// GCC goes to extra lengths here to be a bit more robust. std::string GetTemporaryPath(StringRef Prefix, const char *Suffix) const; + /// Return the pathname of the pch file in clang-cl mode. + std::string GetClPchPath(Compilation &C, StringRef BaseName) const; + /// ShouldUseClangCompiler - Should the clang compiler be used to /// handle this action. bool ShouldUseClangCompiler(const JobAction &JA) const; @@ -441,6 +459,17 @@ private: /// the driver mode. std::pair<unsigned, unsigned> getIncludeExcludeOptionFlagMasks() const; + /// Helper used in BuildJobsForAction. Doesn't use the cache when building + /// jobs specifically for the given action, but will use the cache when + /// building jobs for the Action's inputs. + InputInfo BuildJobsForActionNoCache( + Compilation &C, const Action *A, const ToolChain *TC, + const char *BoundArch, bool AtTopLevel, bool MultipleArchs, + const char *LinkingOutput, + std::map<std::pair<const Action *, std::string>, InputInfo> + &CachedResults, + bool BuildForOffloadDevice) const; + public: /// GetReleaseVersion - Parse (([0-9]+)(.([0-9]+)(.([0-9]+)?))?)? and /// return the grouped values as integers. Numbers which are not @@ -452,6 +481,15 @@ public: static bool GetReleaseVersion(const char *Str, unsigned &Major, unsigned &Minor, unsigned &Micro, bool &HadExtra); + + /// Parse digits from a string \p Str and fulfill \p Digits with + /// the parsed numbers. This method assumes that the max number of + /// digits to look for is equal to Digits.size(). + /// + /// \return True if the entire string was parsed and there are + /// no extra characters remaining at the end. + static bool GetReleaseVersion(const char *Str, + MutableArrayRef<unsigned> Digits); }; /// \return True if the last defined optimization level is -Ofast. diff --git a/include/clang/Driver/Job.h b/include/clang/Driver/Job.h index 263356f396f3e..3366fc48d7110 100644 --- a/include/clang/Driver/Job.h +++ b/include/clang/Driver/Job.h @@ -138,6 +138,20 @@ private: std::unique_ptr<Command> Fallback; }; +/// Like Command, but always pretends that the wrapped command succeeded. +class ForceSuccessCommand : public Command { +public: + ForceSuccessCommand(const Action &Source_, const Tool &Creator_, + const char *Executable_, const ArgStringList &Arguments_, + ArrayRef<InputInfo> Inputs); + + void Print(llvm::raw_ostream &OS, const char *Terminator, bool Quote, + CrashReportInfo *CrashInfo = nullptr) const override; + + int Execute(const StringRef **Redirects, std::string *ErrMsg, + bool *ExecutionFailed) const override; +}; + /// JobList - A sequence of jobs to perform. class JobList { public: diff --git a/include/clang/Driver/Makefile b/include/clang/Driver/Makefile deleted file mode 100644 index 8309330d8bd50..0000000000000 --- a/include/clang/Driver/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -CLANG_LEVEL := ../../.. -BUILT_SOURCES = Options.inc - -TABLEGEN_INC_FILES_COMMON = 1 - -include $(CLANG_LEVEL)/Makefile - -$(ObjDir)/Options.inc.tmp : Options.td CC1Options.td CLCompatOptions.td $(LLVM_TBLGEN) $(ObjDir)/.dir - $(Echo) "Building Clang Driver Option tables with tblgen" - $(Verb) $(LLVMTableGen) -gen-opt-parser-defs -o $(call SYSPATH, $@) $< diff --git a/include/clang/Driver/Multilib.h b/include/clang/Driver/Multilib.h index 20bb80dca273f..6b54d72d7c493 100644 --- a/include/clang/Driver/Multilib.h +++ b/include/clang/Driver/Multilib.h @@ -99,15 +99,15 @@ public: typedef multilib_list::iterator iterator; typedef multilib_list::const_iterator const_iterator; - typedef std::function<std::vector<std::string>( - StringRef InstallDir, StringRef Triple, const Multilib &M)> - IncludeDirsFunc; + typedef std::function<std::vector<std::string>(const Multilib &M)> + IncludeDirsFunc; typedef llvm::function_ref<bool(const Multilib &)> FilterCallback; private: multilib_list Multilibs; IncludeDirsFunc IncludeCallback; + IncludeDirsFunc FilePathsCallback; public: MultilibSet() {} @@ -159,6 +159,12 @@ public: } const IncludeDirsFunc &includeDirsCallback() const { return IncludeCallback; } + MultilibSet &setFilePathsCallback(IncludeDirsFunc F) { + FilePathsCallback = std::move(F); + return *this; + } + const IncludeDirsFunc &filePathsCallback() const { return FilePathsCallback; } + private: /// Apply the filter to Multilibs and return the subset that remains static multilib_list filterCopy(FilterCallback F, const multilib_list &Ms); diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td index e4279e80d847e..d03ab0435a6ef 100644 --- a/include/clang/Driver/Options.td +++ b/include/clang/Driver/Options.td @@ -78,6 +78,7 @@ def g_flags_Group : OptionGroup<"<g flags group>">; def i_Group : OptionGroup<"<i group>">, Group<CompileOnly_Group>; def clang_i_Group : OptionGroup<"<clang i group>">, Group<i_Group>; def m_Group : OptionGroup<"<m group>">, Group<CompileOnly_Group>; +def opencl_Group : OptionGroup<"<opencl group>">, Group<CompileOnly_Group>; // Feature groups - these take command line options that correspond directly to // target specific features and can be translated directly from command line @@ -95,6 +96,8 @@ def m_ppc_Features_Group : OptionGroup<"<ppc features group>">, Group<m_Group>; def m_wasm_Features_Group : OptionGroup<"<wasm features group>">, Group<m_Group>; +def m_amdgpu_Features_Group : OptionGroup<"<amdgpu features group>">, + Group<m_Group>; def m_libc_Group : OptionGroup<"<m libc group>">, Group<m_Group>; def u_Group : OptionGroup<"<u group>">; @@ -150,6 +153,9 @@ class InternalDriverOpt : Group<internal_driver_Group>, def driver_mode : Joined<["--"], "driver-mode=">, Group<internal_driver_Group>, Flags<[CoreOption, DriverOption, HelpHidden]>, HelpText<"Set the driver mode to either 'gcc', 'g++', 'cpp', or 'cl'">; +def rsp_quoting : Joined<["--"], "rsp-quoting=">, Group<internal_driver_Group>, + Flags<[CoreOption, DriverOption, HelpHidden]>, + HelpText<"Set the rsp quoting to either 'posix', or 'windows'">; def ccc_gcc_name : Separate<["-"], "ccc-gcc-name">, InternalDriverOpt, HelpText<"Name for native GCC compiler">, MetaVarName<"<gcc-path>">; @@ -335,7 +341,11 @@ def Xassembler : Separate<["-"], "Xassembler">, HelpText<"Pass <arg> to the assembler">, MetaVarName<"<arg>">; def Xclang : Separate<["-"], "Xclang">, HelpText<"Pass <arg> to the clang compiler">, MetaVarName<"<arg>">, - Flags<[DriverOption, CoreOption]>; + Flags<[DriverOption, CoreOption]>, Group<CompileOnly_Group>; +def Xcuda_fatbinary : Separate<["-"], "Xcuda-fatbinary">, + HelpText<"Pass <arg> to fatbinary invocation">, MetaVarName<"<arg>">; +def Xcuda_ptxas : Separate<["-"], "Xcuda-ptxas">, + HelpText<"Pass <arg> to the ptxas assembler">, MetaVarName<"<arg>">; def z : Separate<["-"], "z">, Flags<[LinkerInput, RenderAsInput]>, HelpText<"Pass -z <arg> to the linker">, MetaVarName<"<arg>">; def Xlinker : Separate<["-"], "Xlinker">, Flags<[LinkerInput, RenderAsInput]>, @@ -357,6 +367,28 @@ def bind__at__load : Flag<["-"], "bind_at_load">; def bundle__loader : Separate<["-"], "bundle_loader">; def bundle : Flag<["-"], "bundle">; def b : JoinedOrSeparate<["-"], "b">, Flags<[Unsupported]>; +def cl_opt_disable : Flag<["-"], "cl-opt-disable">, Group<opencl_Group>, Flags<[CC1Option]>, + HelpText<"OpenCL only. This option disables all optimizations. By default optimizations are enabled.">; +def cl_strict_aliasing : Flag<["-"], "cl-strict-aliasing">, Group<opencl_Group>, Flags<[CC1Option]>, + HelpText<"OpenCL only. This option is added for compatibility with OpenCL 1.0.">; +def cl_single_precision_constant : Flag<["-"], "cl-single-precision-constant">, Group<opencl_Group>, Flags<[CC1Option]>, + HelpText<"OpenCL only. Treat double precision floating-point constant as single precision constant.">; +def cl_finite_math_only : Flag<["-"], "cl-finite-math-only">, Group<opencl_Group>, Flags<[CC1Option]>, + HelpText<"OpenCL only. Allow floating-point optimizations that assume arguments and results are not NaNs or +-Inf.">; +def cl_kernel_arg_info : Flag<["-"], "cl-kernel-arg-info">, Group<opencl_Group>, Flags<[CC1Option]>, + HelpText<"OpenCL only. Generate kernel argument metadata.">; +def cl_unsafe_math_optimizations : Flag<["-"], "cl-unsafe-math-optimizations">, Group<opencl_Group>, Flags<[CC1Option]>, + HelpText<"OpenCL only. Allow unsafe floating-point optimizations. Also implies -cl-no-signed-zeros and -cl-mad-enable.">; +def cl_fast_relaxed_math : Flag<["-"], "cl-fast-relaxed-math">, Group<opencl_Group>, Flags<[CC1Option]>, + HelpText<"OpenCL only. Sets -cl-finite-math-only and -cl-unsafe-math-optimizations, and defines __FAST_RELAXED_MATH__.">; +def cl_mad_enable : Flag<["-"], "cl-mad-enable">, Group<opencl_Group>, Flags<[CC1Option]>, + HelpText<"OpenCL only. Allow use of less precise MAD computations in the generated binary.">; +def cl_no_signed_zeros : Flag<["-"], "cl-no-signed-zeros">, Group<opencl_Group>, Flags<[CC1Option]>, + HelpText<"OpenCL only. Allow use of less precise no signed zeros computations in the generated binary.">; +def cl_std_EQ : Joined<["-"], "cl-std=">, Group<opencl_Group>, Flags<[CC1Option]>, + HelpText<"OpenCL language standard to compile for.">; +def cl_denorms_are_zero : Flag<["-"], "cl-denorms-are-zero">, Group<opencl_Group>, Flags<[CC1Option]>, + HelpText<"OpenCL only. Allow denormals to be flushed to zero.">; def client__name : JoinedOrSeparate<["-"], "client_name">; def combine : Flag<["-", "--"], "combine">, Flags<[DriverOption, Unsupported]>; def compatibility__version : JoinedOrSeparate<["-"], "compatibility_version">; @@ -369,13 +401,29 @@ def cxx_isystem : JoinedOrSeparate<["-"], "cxx-isystem">, Group<clang_i_Group>, def c : Flag<["-"], "c">, Flags<[DriverOption]>, HelpText<"Only run preprocess, compile, and assemble steps">; def cuda_device_only : Flag<["--"], "cuda-device-only">, - HelpText<"Do device-side CUDA compilation only">; -def cuda_gpu_arch_EQ : Joined<["--"], "cuda-gpu-arch=">, - Flags<[DriverOption, HelpHidden]>, HelpText<"CUDA GPU architecture">; + HelpText<"Compile CUDA code for device only">; def cuda_host_only : Flag<["--"], "cuda-host-only">, - HelpText<"Do host-side CUDA compilation only">; + HelpText<"Compile CUDA code for host only. Has no effect on non-CUDA " + "compilations.">; +def cuda_compile_host_device : Flag<["--"], "cuda-compile-host-device">, + HelpText<"Compile CUDA code for both host and device (default). Has no " + "effect on non-CUDA compilations.">; +def cuda_gpu_arch_EQ : Joined<["--"], "cuda-gpu-arch=">, Flags<[DriverOption]>, + HelpText<"CUDA GPU architecture (e.g. sm_35). May be specified more than once.">; +def cuda_noopt_device_debug : Flag<["--"], "cuda-noopt-device-debug">, + HelpText<"Enable device-side debug info generation. Disables ptxas optimizations.">; +def no_cuda_version_check : Flag<["--"], "no-cuda-version-check">, + HelpText<"Don't error out if the detected version of the CUDA install is " + "too low for the requested CUDA gpu architecture.">; +def no_cuda_noopt_device_debug : Flag<["--"], "no-cuda-noopt-device-debug">; def cuda_path_EQ : Joined<["--"], "cuda-path=">, Group<i_Group>, HelpText<"CUDA installation path">; +def fcuda_flush_denormals_to_zero : Flag<["-"], "fcuda-flush-denormals-to-zero">, + Flags<[CC1Option]>, HelpText<"Flush denormal floating point values to zero in CUDA device mode.">; +def fno_cuda_flush_denormals_to_zero : Flag<["-"], "fno-cuda-flush-denormals-to-zero">; +def fcuda_approx_transcendentals : Flag<["-"], "fcuda-approx-transcendentals">, + Flags<[CC1Option]>, HelpText<"Use approximate transcendental functions">; +def fno_cuda_approx_transcendentals : Flag<["-"], "fno-cuda-approx-transcendentals">; def dA : Flag<["-"], "dA">, Group<d_Group>; def dD : Flag<["-"], "dD">, Group<d_Group>, Flags<[CC1Option]>, HelpText<"Print macro definitions in -E mode in addition to normal output">; @@ -431,6 +479,15 @@ def fno_autolink : Flag <["-"], "fno-autolink">, Group<f_Group>, Flags<[DriverOption, CC1Option]>, HelpText<"Disable generation of linker directives for automatic library linking">; +def fembed_bitcode_EQ : Joined<["-"], "fembed-bitcode=">, + Group<f_Group>, Flags<[DriverOption, CC1Option]>, MetaVarName<"<option>">, + HelpText<"Embed LLVM bitcode (option: off, all, bitcode, marker)">; +def fembed_bitcode : Flag<["-"], "fembed-bitcode">, Group<f_Group>, + Alias<fembed_bitcode_EQ>, AliasArgs<["all"]>, + HelpText<"Embed LLVM IR bitcode as data">; +def fembed_bitcode_marker : Flag<["-"], "fembed-bitcode-marker">, + Alias<fembed_bitcode_EQ>, AliasArgs<["marker"]>, + HelpText<"Embed placeholder LLVM IR data as a marker">; def fgnu_inline_asm : Flag<["-"], "fgnu-inline-asm">, Group<f_Group>, Flags<[DriverOption]>; def fno_gnu_inline_asm : Flag<["-"], "fno-gnu-inline-asm">, Group<f_Group>, Flags<[DriverOption, CC1Option]>, @@ -442,15 +499,15 @@ def fprofile_sample_use_EQ : Joined<["-"], "fprofile-sample-use=">, def fauto_profile_EQ : Joined<["-"], "fauto-profile=">, Alias<fprofile_sample_use_EQ>; def fprofile_instr_generate : Flag<["-"], "fprofile-instr-generate">, - Group<f_Group>, Flags<[CC1Option]>, + Group<f_Group>, Flags<[DriverOption]>, HelpText<"Generate instrumented code to collect execution counts into default.profraw file (overriden by '=' form of option or LLVM_PROFILE_FILE env var)">; def fprofile_instr_generate_EQ : Joined<["-"], "fprofile-instr-generate=">, - Group<f_Group>, Flags<[CC1Option]>, MetaVarName<"<file>">, + Group<f_Group>, Flags<[DriverOption]>, MetaVarName<"<file>">, HelpText<"Generate instrumented code to collect execution counts into <file> (overridden by LLVM_PROFILE_FILE env var)">; def fprofile_instr_use : Flag<["-"], "fprofile-instr-use">, Group<f_Group>, Flags<[DriverOption]>; def fprofile_instr_use_EQ : Joined<["-"], "fprofile-instr-use=">, - Group<f_Group>, Flags<[CC1Option]>, + Group<f_Group>, Flags<[DriverOption]>, HelpText<"Use instrumentation data for profile-guided optimization">; def fcoverage_mapping : Flag<["-"], "fcoverage-mapping">, Group<f_Group>, Flags<[CC1Option]>, @@ -459,7 +516,8 @@ def fno_coverage_mapping : Flag<["-"], "fno-coverage-mapping">, Group<f_Group>, Flags<[DriverOption]>, HelpText<"Disable code coverage analysis">; def fprofile_generate : Flag<["-"], "fprofile-generate">, - Alias<fprofile_instr_generate>; + Group<f_Group>, Flags<[DriverOption]>, + HelpText<"Generate instrumented code to collect execution counts into default.profraw (overridden by LLVM_PROFILE_FILE env var)">; def fprofile_generate_EQ : Joined<["-"], "fprofile-generate=">, Group<f_Group>, Flags<[DriverOption]>, MetaVarName<"<directory>">, HelpText<"Generate instrumented code to collect execution counts into <directory>/default.profraw (overridden by LLVM_PROFILE_FILE env var)">; @@ -472,7 +530,8 @@ def fno_profile_instr_generate : Flag<["-"], "fno-profile-instr-generate">, Group<f_Group>, Flags<[DriverOption]>, HelpText<"Disable generation of profile instrumentation.">; def fno_profile_generate : Flag<["-"], "fno-profile-generate">, - Alias<fno_profile_instr_generate>; + Group<f_Group>, Flags<[DriverOption]>, + HelpText<"Disable generation of profile instrumentation.">; def fno_profile_instr_use : Flag<["-"], "fno-profile-instr-use">, Group<f_Group>, Flags<[DriverOption]>, HelpText<"Disable using instrumentation data for profile-guided optimization">; @@ -553,6 +612,8 @@ def fencoding_EQ : Joined<["-"], "fencoding=">, Group<f_Group>; def ferror_limit_EQ : Joined<["-"], "ferror-limit=">, Group<f_Group>, Flags<[CoreOption]>; def fexceptions : Flag<["-"], "fexceptions">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Enable support for exception handling">; +def fsjlj_exceptions : Flag<["-"], "fsjlj-exceptions">, Group<f_Group>, + Flags<[CC1Option]>, HelpText<"Use SjLj style exceptions">; def fexcess_precision_EQ : Joined<["-"], "fexcess-precision=">, Group<clang_ignored_gcc_optimization_f_Group>; def : Flag<["-"], "fexpensive-optimizations">, Group<clang_ignored_gcc_optimization_f_Group>; @@ -564,9 +625,7 @@ def : Flag<["-"], "fextended-identifiers">, Group<clang_ignored_f_Group>; def : Flag<["-"], "fno-extended-identifiers">, Group<f_Group>, Flags<[Unsupported]>; def fhosted : Flag<["-"], "fhosted">, Group<f_Group>; def ffast_math : Flag<["-"], "ffast-math">, Group<f_Group>, Flags<[CC1Option]>, - HelpText<"Enable the *frontend*'s 'fast-math' mode. This has no effect on " - "optimizations, but provides a preprocessor macro __FAST_MATH__ the " - "same as GCC's -ffast-math flag">; + HelpText<"Allow aggressive, lossy floating-point optimizations">; def fno_fast_math : Flag<["-"], "fno-fast-math">, Group<f_Group>; def fmath_errno : Flag<["-"], "fmath-errno">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Require math functions to indicate errors by setting errno">; @@ -574,6 +633,9 @@ def fno_math_errno : Flag<["-"], "fno-math-errno">, Group<f_Group>; def fbracket_depth_EQ : Joined<["-"], "fbracket-depth=">, Group<f_Group>; def fsignaling_math : Flag<["-"], "fsignaling-math">, Group<f_Group>; def fno_signaling_math : Flag<["-"], "fno-signaling-math">, Group<f_Group>; +def fjump_tables : Flag<["-"], "fjump-tables">, Group<f_Group>; +def fno_jump_tables : Flag<["-"], "fno-jump-tables">, Group<f_Group>, Flags<[CC1Option]>, + HelpText<"Do not use jump tables for lowering switches">; def fsanitize_EQ : CommaJoined<["-"], "fsanitize=">, Group<f_clang_Group>, Flags<[CC1Option, CoreOption]>, MetaVarName<"<check>">, HelpText<"Turn on runtime checks for various forms of undefined " @@ -610,6 +672,9 @@ def fsanitize_memory_use_after_dtor : Flag<["-"], "fsanitize-memory-use-after-dt def fsanitize_address_field_padding : Joined<["-"], "fsanitize-address-field-padding=">, Group<f_clang_Group>, Flags<[CC1Option]>, HelpText<"Level of field padding for AddressSanitizer">; +def fsanitize_address_use_after_scope : Flag<["-"], "fsanitize-address-use-after-scope">, + Group<f_clang_Group>, Flags<[CC1Option]>, + HelpText<"Enable use-after-scope detection in AddressSanitizer">; def fsanitize_recover : Flag<["-"], "fsanitize-recover">, Group<f_clang_Group>, Flags<[CoreOption]>; def fno_sanitize_recover : Flag<["-"], "fno-sanitize-recover">, @@ -640,6 +705,16 @@ def fsanitize_cfi_cross_dso : Flag<["-"], "fsanitize-cfi-cross-dso">, def fno_sanitize_cfi_cross_dso : Flag<["-"], "fno-sanitize-cfi-cross-dso">, Group<f_clang_Group>, Flags<[CC1Option]>, HelpText<"Disable control flow integrity (CFI) checks for cross-DSO calls.">; +def fsanitize_stats : Flag<["-"], "fsanitize-stats">, + Group<f_clang_Group>, Flags<[CC1Option]>, + HelpText<"Enable sanitizer statistics gathering.">; +def fno_sanitize_stats : Flag<["-"], "fno-sanitize-stats">, + Group<f_clang_Group>, Flags<[CC1Option]>, + HelpText<"Disable sanitizer statistics gathering.">; +def fsanitize_undefined_strip_path_components_EQ : Joined<["-"], "fsanitize-undefined-strip-path-components=">, + Group<f_clang_Group>, Flags<[CC1Option]>, MetaVarName<"<number>">, + HelpText<"Strip (or keep only, if negative) a given number of path components " + "when emitting check metadata.">; def funsafe_math_optimizations : Flag<["-"], "funsafe-math-optimizations">, Group<f_Group>; def fno_unsafe_math_optimizations : Flag<["-"], "fno-unsafe-math-optimizations">, @@ -699,12 +774,30 @@ def fgnu_runtime : Flag<["-"], "fgnu-runtime">, Group<f_Group>, def fheinous_gnu_extensions : Flag<["-"], "fheinous-gnu-extensions">, Flags<[CC1Option]>; def filelist : Separate<["-"], "filelist">, Flags<[LinkerInput]>; def : Flag<["-"], "findirect-virtual-calls">, Alias<fapple_kext>; -def finline_functions : Flag<["-"], "finline-functions">, Group<clang_ignored_gcc_optimization_f_Group>; +def finline_functions : Flag<["-"], "finline-functions">, Group<f_clang_Group>, Flags<[CC1Option]>, + HelpText<"Inline suitable functions">; +def finline_hint_functions: Flag<["-"], "finline-hint-functions">, Group<f_clang_Group>, Flags<[CC1Option]>, + HelpText<"Inline functions wich are (explicitly or implicitly) marked inline">; def finline : Flag<["-"], "finline">, Group<clang_ignored_f_Group>; def finput_charset_EQ : Joined<["-"], "finput-charset=">, Group<f_Group>; def fexec_charset_EQ : Joined<["-"], "fexec-charset=">, Group<f_Group>; def finstrument_functions : Flag<["-"], "finstrument-functions">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Generate calls to instrument function entry and exit">; + +def fxray_instrument : Flag<["-"], "fxray-instrument">, Group<f_Group>, + Flags<[CC1Option]>, + HelpText<"Generate XRay instrumentation sleds on function entry and exit">; +def fnoxray_instrument : Flag<["-"], "fno-xray-instrument">, Group<f_Group>, + Flags<[CC1Option]>; + +def fxray_instruction_threshold_EQ : + JoinedOrSeparate<["-"], "fxray-instruction-threshold=">, + Group<f_Group>, Flags<[CC1Option]>, + HelpText<"Sets the minimum function size to instrument with XRay">; +def fxray_instruction_threshold_ : + JoinedOrSeparate<["-"], "fxray-instruction-threshold">, + Group<f_Group>, Flags<[CC1Option]>; + def flat__namespace : Flag<["-"], "flat_namespace">; def flax_vector_conversions : Flag<["-"], "flax-vector-conversions">, Group<f_Group>; def flimited_precision_EQ : Joined<["-"], "flimited-precision=">, Group<f_Group>; @@ -774,9 +867,12 @@ def fimplicit_module_maps : Flag <["-"], "fimplicit-module-maps">, Group<f_Group Flags<[DriverOption, CC1Option]>, HelpText<"Implicitly search the file system for module map files.">; def fmodule_maps : Flag <["-"], "fmodule-maps">, Alias<fimplicit_module_maps>; -def fmodule_name : JoinedOrSeparate<["-"], "fmodule-name=">, Group<f_Group>, +def fmodule_name_EQ : Joined<["-"], "fmodule-name=">, Group<f_Group>, Flags<[DriverOption,CC1Option]>, MetaVarName<"<name>">, HelpText<"Specify the name of the module to build">; +def fmodule_name : Separate<["-"], "fmodule-name">, Alias<fmodule_name_EQ>; +def fmodule_implementation_of : Separate<["-"], "fmodule-implementation-of">, + Flags<[CC1Option]>, Alias<fmodule_name_EQ>; def fmodule_map_file : Joined<["-"], "fmodule-map-file=">, Group<f_Group>, Flags<[DriverOption,CC1Option]>, MetaVarName<"<file>">, HelpText<"Load this module map file">; @@ -816,8 +912,6 @@ def fno_builtin : Flag<["-"], "fno-builtin">, Group<f_Group>, Flags<[CC1Option]> HelpText<"Disable implicit builtin knowledge of functions">; def fno_builtin_ : Joined<["-"], "fno-builtin-">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Disable implicit builtin knowledge of a specific function">; -def fno_math_builtin : Flag<["-"], "fno-math-builtin">, Group<f_Group>, Flags<[CC1Option]>, - HelpText<"Disable implicit builtin knowledge of math functions">; def fno_caret_diagnostics : Flag<["-"], "fno-caret-diagnostics">, Group<f_Group>, Flags<[CC1Option]>; def fno_color_diagnostics : Flag<["-"], "fno-color-diagnostics">, Group<f_Group>, @@ -898,7 +992,7 @@ def fno_strict_aliasing : Flag<["-"], "fno-strict-aliasing">, Group<f_Group>, def fstruct_path_tbaa : Flag<["-"], "fstruct-path-tbaa">, Group<f_Group>; def fno_struct_path_tbaa : Flag<["-"], "fno-struct-path-tbaa">, Group<f_Group>; def fno_strict_enums : Flag<["-"], "fno-strict-enums">, Group<f_Group>; -def fno_strict_vtable_pointers: Flag<["-"], "fno-strict-vtable-pointers">, +def fno_strict_vtable_pointers: Flag<["-"], "fno-strict-vtable-pointers">, Group<f_Group>; def fno_strict_overflow : Flag<["-"], "fno-strict-overflow">, Group<f_Group>; def fno_threadsafe_statics : Flag<["-"], "fno-threadsafe-statics">, Group<f_Group>, @@ -938,7 +1032,7 @@ def fobjc_gc : Flag<["-"], "fobjc-gc">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Enable Objective-C garbage collection">; def fobjc_legacy_dispatch : Flag<["-"], "fobjc-legacy-dispatch">, Group<f_Group>; def fobjc_new_property : Flag<["-"], "fobjc-new-property">, Group<clang_ignored_f_Group>; -def fobjc_infer_related_result_type : Flag<["-"], "fobjc-infer-related-result-type">, +def fobjc_infer_related_result_type : Flag<["-"], "fobjc-infer-related-result-type">, Group<f_Group>; def fno_objc_infer_related_result_type : Flag<["-"], "fno-objc-infer-related-result-type">, Group<f_Group>, @@ -961,9 +1055,12 @@ def fobjc_sender_dependent_dispatch : Flag<["-"], "fobjc-sender-dependent-dispat def fomit_frame_pointer : Flag<["-"], "fomit-frame-pointer">, Group<f_Group>; def fopenmp : Flag<["-"], "fopenmp">, Group<f_Group>, Flags<[CC1Option, NoArgumentUnused]>; def fno_openmp : Flag<["-"], "fno-openmp">, Group<f_Group>, Flags<[NoArgumentUnused]>; +def fopenmp_version_EQ : Joined<["-"], "fopenmp-version=">, Group<f_Group>, Flags<[CC1Option, NoArgumentUnused]>; def fopenmp_EQ : Joined<["-"], "fopenmp=">, Group<f_Group>; def fopenmp_use_tls : Flag<["-"], "fopenmp-use-tls">, Group<f_Group>, Flags<[NoArgumentUnused]>; def fnoopenmp_use_tls : Flag<["-"], "fnoopenmp-use-tls">, Group<f_Group>, Flags<[CC1Option, NoArgumentUnused]>; +def fopenmp_targets_EQ : CommaJoined<["-"], "fopenmp-targets=">, Flags<[DriverOption, CC1Option]>, + HelpText<"Specify comma-separated list of triples OpenMP offloading targets to be supported">; def fno_optimize_sibling_calls : Flag<["-"], "fno-optimize-sibling-calls">, Group<f_Group>; def foptimize_sibling_calls : Flag<["-"], "foptimize-sibling-calls">, Group<f_Group>; def force__cpusubtype__ALL : Flag<["-"], "force_cpusubtype_ALL">; @@ -1032,7 +1129,7 @@ def fstrict_aliasing : Flag<["-"], "fstrict-aliasing">, Group<f_Group>, def fstrict_enums : Flag<["-"], "fstrict-enums">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Enable optimizations based on the strict definition of an enum's " "value range">; -def fstrict_vtable_pointers: Flag<["-"], "fstrict-vtable-pointers">, +def fstrict_vtable_pointers: Flag<["-"], "fstrict-vtable-pointers">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Enable optimizations based on the strict rules for overwriting " "polymorphic C++ objects">; @@ -1113,6 +1210,10 @@ def fvisibility_inlines_hidden : Flag<["-"], "fvisibility-inlines-hidden">, Grou def fvisibility_ms_compat : Flag<["-"], "fvisibility-ms-compat">, Group<f_Group>, HelpText<"Give global types 'default' visibility and global functions and " "variables 'hidden' visibility by default">; +def fwhole_program_vtables : Flag<["-"], "fwhole-program-vtables">, Group<f_Group>, + Flags<[CC1Option]>, + HelpText<"Enables whole-program vtable optimization. Requires -flto">; +def fno_whole_program_vtables : Flag<["-"], "fno-whole-program-vtables">, Group<f_Group>; def fwrapv : Flag<["-"], "fwrapv">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Treat signed integer overflow as two's complement">; def fwritable_strings : Flag<["-"], "fwritable-strings">, Group<f_Group>, Flags<[CC1Option]>, @@ -1145,7 +1246,7 @@ def fdebug_prefix_map_EQ def g_Flag : Flag<["-"], "g">, Group<g_Group>, HelpText<"Generate source-level debug information">; def gline_tables_only : Flag<["-"], "gline-tables-only">, Group<gN_Group>, - HelpText<"Emit debug line number tables only">; + Flags<[CoreOption]>, HelpText<"Emit debug line number tables only">; def gmlt : Flag<["-"], "gmlt">, Alias<gline_tables_only>; def g0 : Flag<["-"], "g0">, Group<gN_Group>; def g1 : Flag<["-"], "g1">, Group<gN_Group>, Alias<gline_tables_only>; @@ -1221,8 +1322,12 @@ def iquote : JoinedOrSeparate<["-"], "iquote">, Group<clang_i_Group>, Flags<[CC1 HelpText<"Add directory to QUOTE include search path">, MetaVarName<"<directory>">; def isysroot : JoinedOrSeparate<["-"], "isysroot">, Group<clang_i_Group>, Flags<[CC1Option]>, HelpText<"Set the system root directory (usually /)">, MetaVarName<"<dir>">; -def isystem : JoinedOrSeparate<["-"], "isystem">, Group<clang_i_Group>, Flags<[CC1Option]>, +def isystem : JoinedOrSeparate<["-"], "isystem">, Group<clang_i_Group>, + Flags<[CC1Option]>, HelpText<"Add directory to SYSTEM include search path">, MetaVarName<"<directory>">; +def isystem_after : JoinedOrSeparate<["-"], "isystem-after">, + Group<clang_i_Group>, Flags<[DriverOption]>, MetaVarName<"<directory>">, + HelpText<"Add directory to end of the SYSTEM include search path">; def iwithprefixbefore : JoinedOrSeparate<["-"], "iwithprefixbefore">, Group<clang_i_Group>, HelpText<"Set directory to include search path with prefix">, MetaVarName<"<dir>">, Flags<[CC1Option]>; @@ -1252,6 +1357,9 @@ def m3dnow : Flag<["-"], "m3dnow">, Group<m_x86_Features_Group>; def m64 : Flag<["-"], "m64">, Group<m_Group>, Flags<[DriverOption, CoreOption]>; def mx32 : Flag<["-"], "mx32">, Group<m_Group>, Flags<[DriverOption, CoreOption]>; def mabi_EQ : Joined<["-"], "mabi=">, Group<m_Group>; +def miamcu : Flag<["-"], "miamcu">, Group<m_Group>, Flags<[DriverOption, CoreOption]>, + HelpText<"Use Intel MCU ABI">; +def mno_iamcu : Flag<["-"], "mno-iamcu">, Group<m_Group>, Flags<[DriverOption, CoreOption]>; def malign_functions_EQ : Joined<["-"], "malign-functions=">, Group<clang_ignored_m_Group>; def malign_loops_EQ : Joined<["-"], "malign-loops=">, Group<clang_ignored_m_Group>; def malign_jumps_EQ : Joined<["-"], "malign-jumps=">, Group<clang_ignored_m_Group>; @@ -1278,6 +1386,8 @@ def mfix_and_continue : Flag<["-"], "mfix-and-continue">, Group<clang_ignored_m_ def mieee_fp : Flag<["-"], "mieee-fp">, Group<clang_ignored_m_Group>; def minline_all_stringops : Flag<["-"], "minline-all-stringops">, Group<clang_ignored_m_Group>; def mno_inline_all_stringops : Flag<["-"], "mno-inline-all-stringops">, Group<clang_ignored_m_Group>; +def malign_double : Flag<["-"], "malign-double">, Group<m_Group>, Flags<[CC1Option]>, + HelpText<"Align doubles to two words in structs (x86 only)">; def mfloat_abi_EQ : Joined<["-"], "mfloat-abi=">, Group<m_Group>; def mfpmath_EQ : Joined<["-"], "mfpmath=">, Group<m_Group>; def mfpu_EQ : Joined<["-"], "mfpu=">, Group<m_Group>; @@ -1326,6 +1436,8 @@ def mno_relax_all : Flag<["-"], "mno-relax-all">, Group<m_Group>; def mno_rtd: Flag<["-"], "mno-rtd">, Group<m_Group>; def mno_soft_float : Flag<["-"], "mno-soft-float">, Group<m_Group>; def mno_stackrealign : Flag<["-"], "mno-stackrealign">, Group<m_Group>; +def mno_x87 : Flag<["-"], "mno-x87">, Group<m_x86_Features_Group>; +def mno_80387 : Flag<["-"], "mno-80387">, Alias<mno_x87>; def mno_sse2 : Flag<["-"], "mno-sse2">, Group<m_x86_Features_Group>; def mno_sse3 : Flag<["-"], "mno-sse3">, Group<m_x86_Features_Group>; def mno_sse4a : Flag<["-"], "mno-sse4a">, Group<m_x86_Features_Group>; @@ -1347,6 +1459,8 @@ def mno_avx512pf : Flag<["-"], "mno-avx512pf">, Group<m_x86_Features_Group>; def mno_avx512dq : Flag<["-"], "mno-avx512dq">, Group<m_x86_Features_Group>; def mno_avx512bw : Flag<["-"], "mno-avx512bw">, Group<m_x86_Features_Group>; def mno_avx512vl : Flag<["-"], "mno-avx512vl">, Group<m_x86_Features_Group>; +def mno_avx512vbmi : Flag<["-"], "mno-avx512vbmi">, Group<m_x86_Features_Group>; +def mno_avx512ifma : Flag<["-"], "mno-avx512ifma">, Group<m_x86_Features_Group>; def mno_pclmul : Flag<["-"], "mno-pclmul">, Group<m_x86_Features_Group>; def mno_lzcnt : Flag<["-"], "mno-lzcnt">, Group<m_x86_Features_Group>; def mno_rdrnd : Flag<["-"], "mno-rdrnd">, Group<m_x86_Features_Group>; @@ -1364,11 +1478,13 @@ def mno_prfchw : Flag<["-"], "mno-prfchw">, Group<m_x86_Features_Group>; def mno_rdseed : Flag<["-"], "mno-rdseed">, Group<m_x86_Features_Group>; def mno_adx : Flag<["-"], "mno-adx">, Group<m_x86_Features_Group>; def mno_sha : Flag<["-"], "mno-sha">, Group<m_x86_Features_Group>; +def mno_cx16 : Flag<["-"], "mno-cx16">, Group<m_x86_Features_Group>; def mno_fxsr : Flag<["-"], "mno-fxsr">, Group<m_x86_Features_Group>; def mno_xsave : Flag<["-"], "mno-xsave">, Group<m_x86_Features_Group>; def mno_xsaveopt : Flag<["-"], "mno-xsaveopt">, Group<m_x86_Features_Group>; def mno_xsavec : Flag<["-"], "mno-xsavec">, Group<m_x86_Features_Group>; def mno_xsaves : Flag<["-"], "mno-xsaves">, Group<m_x86_Features_Group>; +def mno_mwaitx : Flag<["-"], "mno-mwaitx">, Group<m_x86_Features_Group>; def mno_pku : Flag<["-"], "mno-pku">, Group<m_x86_Features_Group>; def munaligned_access : Flag<["-"], "munaligned-access">, Group<m_arm_Features_Group>, @@ -1411,6 +1527,12 @@ def ffixed_x18 : Flag<["-"], "ffixed-x18">, Group<m_aarch64_Features_Group>, def msimd128 : Flag<["-"], "msimd128">, Group<m_wasm_Features_Group>; def mno_simd128 : Flag<["-"], "mno-simd128">, Group<m_wasm_Features_Group>; +def mamdgpu_debugger_abi : Joined<["-"], "mamdgpu-debugger-abi=">, + Flags<[HelpHidden]>, + Group<m_Group>, + HelpText<"Generate additional code for specified <version> of debugger ABI (AMDGPU only)">, + MetaVarName<"<version>">; + def mvsx : Flag<["-"], "mvsx">, Group<m_ppc_Features_Group>; def mno_vsx : Flag<["-"], "mno-vsx">, Group<m_ppc_Features_Group>; def mpower8_vector : Flag<["-"], "mpower8-vector">, @@ -1448,6 +1570,10 @@ def minvariant_function_descriptors : def mno_invariant_function_descriptors : Flag<["-"], "mno-invariant-function-descriptors">, Group<m_ppc_Features_Group>; +def mfloat128: Flag<["-"], "mfloat128">, + Group<m_ppc_Features_Group>; +def mno_float128 : Flag<["-"], "mno-float128">, + Group<m_ppc_Features_Group>; def faltivec : Flag<["-"], "faltivec">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Enable AltiVec vector initializer syntax">; @@ -1465,6 +1591,10 @@ def fno_zvector : Flag<["-"], "fno-zvector">, Group<f_Group>, def mzvector : Flag<["-"], "mzvector">, Alias<fzvector>; def mno_zvector : Flag<["-"], "mno-zvector">, Alias<fno_zvector>; +def mbackchain : Flag<["-"], "mbackchain">, Group<m_Group>, Flags<[DriverOption,CC1Option]>, + HelpText<"Link stack frames through backchain on System Z">; +def mno_backchain : Flag<["-"], "mno-backchain">, Group<m_Group>, Flags<[DriverOption,CC1Option]>; + def mno_warn_nonportable_cfstrings : Flag<["-"], "mno-warn-nonportable-cfstrings">, Group<m_Group>; def mno_omit_leaf_frame_pointer : Flag<["-"], "mno-omit-leaf-frame-pointer">, Group<m_Group>; def momit_leaf_frame_pointer : Flag<["-"], "momit-leaf-frame-pointer">, Group<m_Group>, @@ -1490,6 +1620,8 @@ def mno_implicit_float : Flag<["-"], "mno-implicit-float">, Group<m_Group>, def mimplicit_float : Flag<["-"], "mimplicit-float">, Group<m_Group>; def mrecip : Flag<["-"], "mrecip">, Group<m_Group>; def mrecip_EQ : CommaJoined<["-"], "mrecip=">, Group<m_Group>, Flags<[CC1Option]>; +def mx87 : Flag<["-"], "mx87">, Group<m_x86_Features_Group>; +def m80387 : Flag<["-"], "m80387">, Alias<mx87>; def msse2 : Flag<["-"], "msse2">, Group<m_x86_Features_Group>; def msse3 : Flag<["-"], "msse3">, Group<m_x86_Features_Group>; def msse4a : Flag<["-"], "msse4a">, Group<m_x86_Features_Group>; @@ -1508,6 +1640,8 @@ def mavx512pf : Flag<["-"], "mavx512pf">, Group<m_x86_Features_Group>; def mavx512dq : Flag<["-"], "mavx512dq">, Group<m_x86_Features_Group>; def mavx512bw : Flag<["-"], "mavx512bw">, Group<m_x86_Features_Group>; def mavx512vl : Flag<["-"], "mavx512vl">, Group<m_x86_Features_Group>; +def mavx512vbmi : Flag<["-"], "mavx512vbmi">, Group<m_x86_Features_Group>; +def mavx512ifma : Flag<["-"], "mavx512ifma">, Group<m_x86_Features_Group>; def mpclmul : Flag<["-"], "mpclmul">, Group<m_x86_Features_Group>; def mlzcnt : Flag<["-"], "mlzcnt">, Group<m_x86_Features_Group>; def mrdrnd : Flag<["-"], "mrdrnd">, Group<m_x86_Features_Group>; @@ -1532,6 +1666,7 @@ def mxsave : Flag<["-"], "mxsave">, Group<m_x86_Features_Group>; def mxsaveopt : Flag<["-"], "mxsaveopt">, Group<m_x86_Features_Group>; def mxsavec : Flag<["-"], "mxsavec">, Group<m_x86_Features_Group>; def mxsaves : Flag<["-"], "mxsaves">, Group<m_x86_Features_Group>; +def mmwaitx : Flag<["-"], "mmwaitx">, Group<m_x86_Features_Group>; def mips16 : Flag<["-"], "mips16">, Group<m_Group>; def mno_mips16 : Flag<["-"], "mno-mips16">, Group<m_Group>; def mmicromips : Flag<["-"], "mmicromips">, Group<m_Group>; @@ -1543,6 +1678,7 @@ def mno_ldc1_sdc1 : Flag<["-"], "mno-ldc1-sdc1">, Group<m_Group>; def mcheck_zero_division : Flag<["-"], "mcheck-zero-division">, Group<m_Group>; def mno_check_zero_division : Flag<["-"], "mno-check-zero-division">, Group<m_Group>; +def mcompact_branches_EQ : Joined<["-"], "mcompact-branches=">, Group<m_Group>; def mdsp : Flag<["-"], "mdsp">, Group<m_Group>; def mno_dsp : Flag<["-"], "mno-dsp">, Group<m_Group>; def mdspr2 : Flag<["-"], "mdspr2">, Group<m_Group>; @@ -1651,8 +1787,6 @@ def nostdlib : Flag<["-"], "nostdlib">; def object : Flag<["-"], "object">; def o : JoinedOrSeparate<["-"], "o">, Flags<[DriverOption, RenderAsInput, CC1Option, CC1AsOption]>, HelpText<"Write output to <file>">, MetaVarName<"<file>">; -def omptargets_EQ : CommaJoined<["-"], "omptargets=">, Flags<[DriverOption, CC1Option]>, - HelpText<"Specify comma-separated list of triples OpenMP offloading targets to be supported">; def pagezero__size : JoinedOrSeparate<["-"], "pagezero_size">; def pass_exit_codes : Flag<["-", "--"], "pass-exit-codes">, Flags<[Unsupported]>; def pedantic_errors : Flag<["-", "--"], "pedantic-errors">, Group<pedantic_Group>, Flags<[CC1Option]>; @@ -1692,7 +1826,7 @@ def rewrite_legacy_objc : Flag<["-"], "rewrite-legacy-objc">, Flags<[DriverOptio HelpText<"Rewrite Legacy Objective-C source to C++">; def rdynamic : Flag<["-"], "rdynamic">; def resource_dir : Separate<["-"], "resource-dir">, - Flags<[DriverOption, CC1Option, HelpHidden]>, + Flags<[DriverOption, CC1Option, CoreOption, HelpHidden]>, HelpText<"The directory which holds the compiler resource files">; def resource_dir_EQ : Joined<["-"], "resource-dir=">, Flags<[DriverOption]>, Alias<resource_dir>; diff --git a/include/clang/Driver/SanitizerArgs.h b/include/clang/Driver/SanitizerArgs.h index c2611b5cd8ee2..7b293e03d3509 100644 --- a/include/clang/Driver/SanitizerArgs.h +++ b/include/clang/Driver/SanitizerArgs.h @@ -28,14 +28,16 @@ class SanitizerArgs { std::vector<std::string> BlacklistFiles; std::vector<std::string> ExtraDeps; - int CoverageFeatures; - int MsanTrackOrigins; - bool MsanUseAfterDtor; - bool CfiCrossDso; - int AsanFieldPadding; - bool AsanSharedRuntime; - bool LinkCXXRuntimes; - bool NeedPIE; + int CoverageFeatures = 0; + int MsanTrackOrigins = 0; + bool MsanUseAfterDtor = false; + bool CfiCrossDso = false; + int AsanFieldPadding = 0; + bool AsanSharedRuntime = false; + bool AsanUseAfterScope = false; + bool LinkCXXRuntimes = false; + bool NeedPIE = false; + bool Stats = false; public: /// Parses the sanitizer arguments from an argument list. @@ -56,15 +58,16 @@ class SanitizerArgs { } bool needsCfiRt() const; bool needsCfiDiagRt() const; + bool needsStatsRt() const { return Stats; } + bool needsEsanRt() const { + return Sanitizers.hasOneOf(SanitizerKind::Efficiency); + } bool requiresPIE() const; bool needsUnwindTables() const; bool linkCXXRuntimes() const { return LinkCXXRuntimes; } void addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs, types::ID InputType) const; - - private: - void clear(); }; } // namespace driver diff --git a/include/clang/Driver/ToolChain.h b/include/clang/Driver/ToolChain.h index 7e68d0a59a094..2a15d7ab061c1 100644 --- a/include/clang/Driver/ToolChain.h +++ b/include/clang/Driver/ToolChain.h @@ -11,6 +11,7 @@ #define LLVM_CLANG_DRIVER_TOOLCHAIN_H #include "clang/Basic/Sanitizers.h" +#include "clang/Basic/VersionTuple.h" #include "clang/Driver/Action.h" #include "clang/Driver/Multilib.h" #include "clang/Driver/Types.h" @@ -228,7 +229,7 @@ public: virtual bool IsIntegratedAssemblerDefault() const { return false; } /// \brief Check if the toolchain should use the integrated assembler. - bool useIntegratedAs() const; + virtual bool useIntegratedAs() const; /// IsMathErrnoDefault - Does this tool chain use -fmath-errno by default. virtual bool IsMathErrnoDefault() const { return true; } @@ -256,6 +257,10 @@ public: return ToolChain::RLT_Libgcc; } + virtual CXXStdlibType GetDefaultCXXStdlibType() const { + return ToolChain::CST_Libstdcxx; + } + virtual std::string getCompilerRT(const llvm::opt::ArgList &Args, StringRef Component, bool Shared = false) const; @@ -315,6 +320,11 @@ public: return false; } + /// SupportsEmbeddedBitcode - Does this tool chain support embedded bitcode. + virtual bool SupportsEmbeddedBitcode() const { + return false; + } + /// getThreadModel() - Which thread model does this target use? virtual std::string getThreadModel() const { return "posix"; } @@ -408,8 +418,19 @@ public: virtual void AddCudaIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const; + /// \brief Add arguments to use MCU GCC toolchain includes. + virtual void AddIAMCUIncludeArgs(const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &CC1Args) const; + /// \brief Return sanitizers which are available in this toolchain. virtual SanitizerMask getSupportedSanitizers() const; + + /// \brief Return sanitizers which are enabled by default. + virtual SanitizerMask getDefaultSanitizers() const { return 0; } + + /// \brief On Windows, returns the version of cl.exe. On other platforms, + /// returns an empty VersionTuple. + virtual VersionTuple getMSVCVersionFromExe() const { return VersionTuple(); } }; } // end namespace driver diff --git a/include/clang/Driver/Types.def b/include/clang/Driver/Types.def index d1b69151b0621..f2ff194ee646b 100644 --- a/include/clang/Driver/Types.def +++ b/include/clang/Driver/Types.def @@ -53,6 +53,7 @@ TYPE("c++", CXX, PP_CXX, "cpp", "u") TYPE("objective-c++-cpp-output", PP_ObjCXX, INVALID, "mii", "u") TYPE("objc++-cpp-output", PP_ObjCXX_Alias, INVALID, "mii", "u") TYPE("objective-c++", ObjCXX, PP_ObjCXX, "mm", "u") +TYPE("renderscript", RenderScript, PP_C, "rs", "u") // C family input files to precompile. TYPE("c-header-cpp-output", PP_CHeader, INVALID, "i", "p") @@ -93,4 +94,5 @@ TYPE("treelang", Treelang, INVALID, nullptr, "u") TYPE("image", Image, INVALID, "out", "") TYPE("dSYM", dSYM, INVALID, "dSYM", "A") TYPE("dependencies", Dependencies, INVALID, "d", "") +TYPE("cuda-fatbin", CUDA_FATBIN, INVALID, "fatbin","A") TYPE("none", Nothing, INVALID, nullptr, "u") diff --git a/include/clang/Format/Format.h b/include/clang/Format/Format.h index 6d051e09cb643..1ff305d030aaa 100644 --- a/include/clang/Format/Format.h +++ b/include/clang/Format/Format.h @@ -26,6 +26,10 @@ class Lexer; class SourceManager; class DiagnosticConsumer; +namespace vfs { +class FileSystem; +} + namespace format { enum class ParseError { Success = 0, Error, Unsuitable }; @@ -37,10 +41,10 @@ public: const std::error_category &getParseCategory(); std::error_code make_error_code(ParseError e); -/// \brief The \c FormatStyle is used to configure the formatting to follow +/// \brief The ``FormatStyle`` is used to configure the formatting to follow /// specific guidelines. struct FormatStyle { - /// \brief The extra indent or outdent of access modifiers, e.g. \c public:. + /// \brief The extra indent or outdent of access modifiers, e.g. ``public:``. int AccessModifierOffset; /// \brief Different styles for aligning after open brackets. @@ -51,7 +55,7 @@ struct FormatStyle { /// argument2); /// \endcode BAS_Align, - /// \brief Don't align, instead use \c ContinuationIndentWidth, e.g.: + /// \brief Don't align, instead use ``ContinuationIndentWidth``, e.g.: /// \code /// someLongFunction(argument1, /// argument2); @@ -66,13 +70,13 @@ struct FormatStyle { BAS_AlwaysBreak, }; - /// \brief If \c true, horizontally aligns arguments after an open bracket. + /// \brief If ``true``, horizontally aligns arguments after an open bracket. /// /// This applies to round brackets (parentheses), angle brackets and square /// brackets. BracketAlignmentStyle AlignAfterOpenBracket; - /// \brief If \c true, aligns consecutive assignments. + /// \brief If ``true``, aligns consecutive assignments. /// /// This will align the assignment operators of consecutive lines. This /// will result in formattings like @@ -83,7 +87,7 @@ struct FormatStyle { /// \endcode bool AlignConsecutiveAssignments; - /// \brief If \c true, aligns consecutive declarations. + /// \brief If ``true``, aligns consecutive declarations. /// /// This will align the declaration names of consecutive lines. This /// will result in formattings like @@ -94,11 +98,11 @@ struct FormatStyle { /// \endcode bool AlignConsecutiveDeclarations; - /// \brief If \c true, aligns escaped newlines as far left as possible. + /// \brief If ``true``, aligns escaped newlines as far left as possible. /// Otherwise puts them into the right-most column. bool AlignEscapedNewlinesLeft; - /// \brief If \c true, horizontally align operands of binary and ternary + /// \brief If ``true``, horizontally align operands of binary and ternary /// expressions. /// /// Specifically, this aligns operands of a single expression that needs to be @@ -109,19 +113,19 @@ struct FormatStyle { /// \endcode bool AlignOperands; - /// \brief If \c true, aligns trailing comments. + /// \brief If ``true``, aligns trailing comments. bool AlignTrailingComments; /// \brief Allow putting all parameters of a function declaration onto - /// the next line even if \c BinPackParameters is \c false. + /// the next line even if ``BinPackParameters`` is ``false``. bool AllowAllParametersOfDeclarationOnNextLine; /// \brief Allows contracting simple braced statements to a single line. /// - /// E.g., this allows <tt>if (a) { return; }</tt> to be put on a single line. + /// E.g., this allows ``if (a) { return; }`` to be put on a single line. bool AllowShortBlocksOnASingleLine; - /// \brief If \c true, short case labels will be contracted to a single line. + /// \brief If ``true``, short case labels will be contracted to a single line. bool AllowShortCaseLabelsOnASingleLine; /// \brief Different styles for merging short functions containing at most one @@ -137,22 +141,21 @@ struct FormatStyle { SFS_All, }; - /// \brief Dependent on the value, <tt>int f() { return 0; }</tt> can be put - /// on a single line. + /// \brief Dependent on the value, ``int f() { return 0; }`` can be put on a + /// single line. ShortFunctionStyle AllowShortFunctionsOnASingleLine; - /// \brief If \c true, <tt>if (a) return;</tt> can be put on a single - /// line. + /// \brief If ``true``, ``if (a) return;`` can be put on a single line. bool AllowShortIfStatementsOnASingleLine; - /// \brief If \c true, <tt>while (true) continue;</tt> can be put on a - /// single line. + /// \brief If ``true``, ``while (true) continue;`` can be put on a single + /// line. bool AllowShortLoopsOnASingleLine; /// \brief Different ways to break after the function definition return type. enum DefinitionReturnTypeBreakingStyle { /// Break after return type automatically. - /// \c PenaltyReturnTypeOnItsOwnLine is taken into account. + /// ``PenaltyReturnTypeOnItsOwnLine`` is taken into account. DRTBS_None, /// Always break after the return type. DRTBS_All, @@ -164,7 +167,7 @@ struct FormatStyle { /// declaration return type. enum ReturnTypeBreakingStyle { /// Break after return type automatically. - /// \c PenaltyReturnTypeOnItsOwnLine is taken into account. + /// ``PenaltyReturnTypeOnItsOwnLine`` is taken into account. RTBS_None, /// Always break after the return type. RTBS_All, @@ -183,23 +186,23 @@ struct FormatStyle { /// \brief The function declaration return type breaking style to use. ReturnTypeBreakingStyle AlwaysBreakAfterReturnType; - /// \brief If \c true, always break before multiline string literals. + /// \brief If ``true``, always break before multiline string literals. /// /// This flag is mean to make cases where there are multiple multiline strings /// in a file look more consistent. Thus, it will only take effect if wrapping /// the string at that point leads to it being indented - /// \c ContinuationIndentWidth spaces from the start of the line. + /// ``ContinuationIndentWidth`` spaces from the start of the line. bool AlwaysBreakBeforeMultilineStrings; - /// \brief If \c true, always break after the <tt>template<...></tt> of a - /// template declaration. + /// \brief If ``true``, always break after the ``template<...>`` of a template + /// declaration. bool AlwaysBreakTemplateDeclarations; - /// \brief If \c false, a function call's arguments will either be all on the + /// \brief If ``false``, a function call's arguments will either be all on the /// same line or will have one line each. bool BinPackArguments; - /// \brief If \c false, a function declaration's or function definition's + /// \brief If ``false``, a function declaration's or function definition's /// parameters will either all be on the same line or will have one line each. bool BinPackParameters; @@ -220,13 +223,14 @@ struct FormatStyle { enum BraceBreakingStyle { /// Always attach braces to surrounding context. BS_Attach, - /// Like \c Attach, but break before braces on function, namespace and + /// Like ``Attach``, but break before braces on function, namespace and /// class definitions. BS_Linux, /// Like ``Attach``, but break before braces on enum, function, and record /// definitions. BS_Mozilla, - /// Like \c Attach, but break before function definitions, 'catch', and 'else'. + /// Like ``Attach``, but break before function definitions, ``catch``, and + /// ``else``. BS_Stroustrup, /// Always break before braces. BS_Allman, @@ -236,7 +240,7 @@ struct FormatStyle { BS_GNU, /// Like ``Attach``, but break before functions. BS_WebKit, - /// Configure each individual brace in \c BraceWrapping. + /// Configure each individual brace in `BraceWrapping`. BS_Custom }; @@ -247,7 +251,7 @@ struct FormatStyle { struct BraceWrappingFlags { /// \brief Wrap class definitions. bool AfterClass; - /// \brief Wrap control statements (if/for/while/switch/..). + /// \brief Wrap control statements (``if``/``for``/``while``/``switch``/..). bool AfterControlStatement; /// \brief Wrap enum definitions. bool AfterEnum; @@ -255,15 +259,15 @@ struct FormatStyle { bool AfterFunction; /// \brief Wrap namespace definitions. bool AfterNamespace; - /// \brief Wrap ObjC definitions (@autoreleasepool, interfaces, ..). + /// \brief Wrap ObjC definitions (``@autoreleasepool``, interfaces, ..). bool AfterObjCDeclaration; /// \brief Wrap struct definitions. bool AfterStruct; /// \brief Wrap union definitions. bool AfterUnion; - /// \brief Wrap before \c catch. + /// \brief Wrap before ``catch``. bool BeforeCatch; - /// \brief Wrap before \c else. + /// \brief Wrap before ``else``. bool BeforeElse; /// \brief Indent the wrapped braces themselves. bool IndentBraces; @@ -271,11 +275,11 @@ struct FormatStyle { /// \brief Control of individual brace wrapping cases. /// - /// If \c BreakBeforeBraces is set to \c custom, use this to specify how each - /// individual brace case should be handled. Otherwise, this is ignored. + /// If ``BreakBeforeBraces`` is set to ``BS_Custom``, use this to specify how + /// each individual brace case should be handled. Otherwise, this is ignored. BraceWrappingFlags BraceWrapping; - /// \brief If \c true, ternary operators will be placed after line breaks. + /// \brief If ``true``, ternary operators will be placed after line breaks. bool BreakBeforeTernaryOperators; /// \brief Always break constructor initializers before commas and align @@ -285,9 +289,12 @@ struct FormatStyle { /// \brief Break after each annotation on a field in Java files. bool BreakAfterJavaFieldAnnotations; + /// \brief Allow breaking string literals when formatting. + bool BreakStringLiterals; + /// \brief The column limit. /// - /// A column limit of \c 0 means that there is no column limit. In this case, + /// A column limit of ``0`` means that there is no column limit. In this case, /// clang-format will respect the input's line breaking decisions within /// statements unless they contradict other rules. unsigned ColumnLimit; @@ -307,7 +314,7 @@ struct FormatStyle { /// \brief Indent width for line continuations. unsigned ContinuationIndentWidth; - /// \brief If \c true, format braced lists as best suited for C++11 braced + /// \brief If ``true``, format braced lists as best suited for C++11 braced /// lists. /// /// Important differences: @@ -317,19 +324,20 @@ struct FormatStyle { /// /// Fundamentally, C++11 braced lists are formatted exactly like function /// calls would be formatted in their place. If the braced list follows a name - /// (e.g. a type or variable name), clang-format formats as if the \c {} were + /// (e.g. a type or variable name), clang-format formats as if the ``{}`` were /// the parentheses of a function call with that name. If there is no name, /// a zero-length name is assumed. bool Cpp11BracedListStyle; - /// \brief If \c true, analyze the formatted file for the most common - /// alignment of & and *. \c PointerAlignment is then used only as fallback. + /// \brief If ``true``, analyze the formatted file for the most common + /// alignment of ``&`` and ``*``. ``PointerAlignment`` is then used only as + /// fallback. bool DerivePointerAlignment; /// \brief Disables formatting completely. bool DisableFormat; - /// \brief If \c true, clang-format detects whether function calls and + /// \brief If ``true``, clang-format detects whether function calls and /// definitions are formatted with one parameter per line. /// /// Each call can be bin-packed, one-per-line or inconclusive. If it is @@ -351,14 +359,14 @@ struct FormatStyle { /// \endcode /// /// In the .clang-format configuration file, this can be configured like: - /// \code + /// \code{.yaml} /// ForEachMacros: ['RANGES_FOR', 'FOREACH'] /// \endcode /// /// For example: BOOST_FOREACH. std::vector<std::string> ForEachMacros; - /// \brief See documentation of \c IncludeCategories. + /// \brief See documentation of ``IncludeCategories``. struct IncludeCategory { /// \brief The regular expression that this category matches. std::string Regex; @@ -369,24 +377,24 @@ struct FormatStyle { } }; - /// \brief Regular expressions denoting the different #include categories used - /// for ordering #includes. + /// \brief Regular expressions denoting the different ``#include`` categories + /// used for ordering ``#includes``. /// /// These regular expressions are matched against the filename of an include /// (including the <> or "") in order. The value belonging to the first - /// matching regular expression is assigned and #includes are sorted first + /// matching regular expression is assigned and ``#includes`` are sorted first /// according to increasing category number and then alphabetically within /// each category. /// /// If none of the regular expressions match, INT_MAX is assigned as /// category. The main header for a source file automatically gets category 0. - /// so that it is generally kept at the beginning of the #includes + /// so that it is generally kept at the beginning of the ``#includes`` /// (http://llvm.org/docs/CodingStandards.html#include-style). However, you /// can also assign negative priorities if you have certain headers that /// always need to be first. /// /// To configure this in the .clang-format file, use: - /// \code + /// \code{.yaml} /// IncludeCategories: /// - Regex: '^"(llvm|llvm-c|clang|clang-c)/' /// Priority: 2 @@ -397,9 +405,22 @@ struct FormatStyle { /// \endcode std::vector<IncludeCategory> IncludeCategories; + /// \brief Specify a regular expression of suffixes that are allowed in the + /// file-to-main-include mapping. + /// + /// When guessing whether a #include is the "main" include (to assign + /// category 0, see above), use this regex of allowed suffixes to the header + /// stem. A partial match is done, so that: + /// - "" means "arbitrary suffix" + /// - "$" means "no suffix" + /// + /// For example, if configured to "(_test)?$", then a header a.h would be seen + /// as the "main" include in both a.cc and a_test.cc. + std::string IncludeIsMainRegex; + /// \brief Indent case labels one level from the switch statement. /// - /// When \c false, use the same indentation level as for the switch statement. + /// When ``false``, use the same indentation level as for the switch statement. /// Switch statement body is always indented one level more than case labels. bool IndentCaseLabels; @@ -410,12 +431,31 @@ struct FormatStyle { /// type. bool IndentWrappedFunctionNames; + /// \brief Quotation styles for JavaScript strings. Does not affect template + /// strings. + enum JavaScriptQuoteStyle { + /// Leave string quotes as they are. + JSQS_Leave, + /// Always use single quotes. + JSQS_Single, + /// Always use double quotes. + JSQS_Double + }; + + /// \brief The JavaScriptQuoteStyle to use for JavaScript strings. + JavaScriptQuoteStyle JavaScriptQuotes; + + /// \brief Whether to wrap JavaScript import/export statements. + bool JavaScriptWrapImports; + /// \brief If true, empty lines at the start of blocks are kept. bool KeepEmptyLinesAtTheStartOfBlocks; - /// \brief Supported languages. When stored in a configuration file, specifies - /// the language, that the configuration targets. When passed to the - /// reformat() function, enables syntax features specific to the language. + /// \brief Supported languages. + /// + /// When stored in a configuration file, specifies the language, that the + /// configuration targets. When passed to the ``reformat()`` function, enables + /// syntax features specific to the language. enum LanguageKind { /// Do not use. LK_None, @@ -460,21 +500,21 @@ struct FormatStyle { /// \brief The number of characters to use for indentation of ObjC blocks. unsigned ObjCBlockIndentWidth; - /// \brief Add a space after \c @property in Objective-C, i.e. use - /// <tt>\@property (readonly)</tt> instead of <tt>\@property(readonly)</tt>. + /// \brief Add a space after ``@property`` in Objective-C, i.e. use + /// ``@property (readonly)`` instead of ``@property(readonly)``. bool ObjCSpaceAfterProperty; /// \brief Add a space in front of an Objective-C protocol list, i.e. use - /// <tt>Foo <Protocol></tt> instead of \c Foo<Protocol>. + /// ``Foo <Protocol>`` instead of ``Foo<Protocol>``. bool ObjCSpaceBeforeProtocolList; - /// \brief The penalty for breaking a function call after "call(". + /// \brief The penalty for breaking a function call after ``call(``. unsigned PenaltyBreakBeforeFirstCallParameter; /// \brief The penalty for each line break introduced inside a comment. unsigned PenaltyBreakComment; - /// \brief The penalty for breaking before the first \c <<. + /// \brief The penalty for breaking before the first ``<<``. unsigned PenaltyBreakFirstLessLess; /// \brief The penalty for each line break introduced inside a string literal. @@ -487,7 +527,7 @@ struct FormatStyle { /// line. unsigned PenaltyReturnTypeOnItsOwnLine; - /// \brief The & and * alignment style. + /// \brief The ``&`` and ``*`` alignment style. enum PointerAlignmentStyle { /// Align pointer to the left. PAS_Left, @@ -500,16 +540,16 @@ struct FormatStyle { /// \brief Pointer and reference alignment style. PointerAlignmentStyle PointerAlignment; - /// \brief If true, clang-format will attempt to re-flow comments. + /// \brief If ``true``, clang-format will attempt to re-flow comments. bool ReflowComments; - /// \brief If true, clang-format will sort #includes. + /// \brief If ``true``, clang-format will sort ``#includes``. bool SortIncludes; - /// \brief If \c true, a space may be inserted after C style casts. + /// \brief If ``true``, a space may be inserted after C style casts. bool SpaceAfterCStyleCast; - /// \brief If \c false, spaces will be removed before assignment operators. + /// \brief If ``false``, spaces will be removed before assignment operators. bool SpaceBeforeAssignmentOperators; /// \brief Different ways to put a space before opening parentheses. @@ -517,7 +557,7 @@ struct FormatStyle { /// Never put a space before opening parentheses. SBPO_Never, /// Put a space before opening parentheses only after control statement - /// keywords (<tt>for/if/while...</tt>). + /// keywords (``for/if/while...``). SBPO_ControlStatements, /// Always put a space before opening parentheses, except when it's /// prohibited by the syntax rules (in function-like macro definitions) or @@ -529,46 +569,46 @@ struct FormatStyle { /// \brief Defines in which cases to put a space before opening parentheses. SpaceBeforeParensOptions SpaceBeforeParens; - /// \brief If \c true, spaces may be inserted into '()'. + /// \brief If ``true``, spaces may be inserted into ``()``. bool SpaceInEmptyParentheses; /// \brief The number of spaces before trailing line comments - /// (\c // - comments). + /// (``//`` - comments). /// - /// This does not affect trailing block comments (\c /**/ - comments) as those - /// commonly have different usage patterns and a number of special cases. + /// This does not affect trailing block comments (``/*`` - comments) as + /// those commonly have different usage patterns and a number of special + /// cases. unsigned SpacesBeforeTrailingComments; - /// \brief If \c true, spaces will be inserted after '<' and before '>' in - /// template argument lists + /// \brief If ``true``, spaces will be inserted after ``<`` and before ``>`` + /// in template argument lists. bool SpacesInAngles; - /// \brief If \c true, spaces are inserted inside container literals (e.g. + /// \brief If ``true``, spaces are inserted inside container literals (e.g. /// ObjC and Javascript array and dict literals). bool SpacesInContainerLiterals; - /// \brief If \c true, spaces may be inserted into C style casts. + /// \brief If ``true``, spaces may be inserted into C style casts. bool SpacesInCStyleCastParentheses; - /// \brief If \c true, spaces will be inserted after '(' and before ')'. + /// \brief If ``true``, spaces will be inserted after ``(`` and before ``)``. bool SpacesInParentheses; - /// \brief If \c true, spaces will be inserted after '[' and before ']'. + /// \brief If ``true``, spaces will be inserted after ``[`` and before ``]``. bool SpacesInSquareBrackets; /// \brief Supported language standards. enum LanguageStandard { /// Use C++03-compatible syntax. LS_Cpp03, - /// Use features of C++11 (e.g. \c A<A<int>> instead of - /// <tt>A<A<int> ></tt>). + /// Use features of C++11 (e.g. ``A<A<int>>`` instead of ``A<A<int> >``). LS_Cpp11, /// Automatic detection based on the input. LS_Auto }; - /// \brief Format compatible with this standard, e.g. use - /// <tt>A<A<int> ></tt> instead of \c A<A<int>> for LS_Cpp03. + /// \brief Format compatible with this standard, e.g. use ``A<A<int> >`` + /// instead of ``A<A<int>>`` for ``LS_Cpp03``. LanguageStandard Standard; /// \brief The number of columns used for tab stops. @@ -580,6 +620,8 @@ struct FormatStyle { UT_Never, /// Use tabs only for indentation. UT_ForIndentation, + /// Use tabs only for line continuation and indentation. + UT_ForContinuationAndIndentation, /// Use tabs whenever we need to fill whitespace that spans at least from /// one tab stop to the next one. UT_Always @@ -619,6 +661,7 @@ struct FormatStyle { BreakConstructorInitializersBeforeComma == R.BreakConstructorInitializersBeforeComma && BreakAfterJavaFieldAnnotations == R.BreakAfterJavaFieldAnnotations && + BreakStringLiterals == R.BreakStringLiterals && ColumnLimit == R.ColumnLimit && CommentPragmas == R.CommentPragmas && ConstructorInitializerAllOnOneLineOrOnePerLine == R.ConstructorInitializerAllOnOneLineOrOnePerLine && @@ -635,6 +678,8 @@ struct FormatStyle { IndentCaseLabels == R.IndentCaseLabels && IndentWidth == R.IndentWidth && Language == R.Language && IndentWrappedFunctionNames == R.IndentWrappedFunctionNames && + JavaScriptQuotes == R.JavaScriptQuotes && + JavaScriptWrapImports == R.JavaScriptWrapImports && KeepEmptyLinesAtTheStartOfBlocks == R.KeepEmptyLinesAtTheStartOfBlocks && MacroBlockBegin == R.MacroBlockBegin && @@ -701,39 +746,55 @@ FormatStyle getNoStyle(); /// Currently supported names: LLVM, Google, Chromium, Mozilla. Names are /// compared case-insensitively. /// -/// Returns \c true if the Style has been set. +/// Returns ``true`` if the Style has been set. bool getPredefinedStyle(StringRef Name, FormatStyle::LanguageKind Language, FormatStyle *Style); /// \brief Parse configuration from YAML-formatted text. /// -/// Style->Language is used to get the base style, if the \c BasedOnStyle +/// Style->Language is used to get the base style, if the ``BasedOnStyle`` /// option is present. /// -/// When \c BasedOnStyle is not present, options not present in the YAML +/// When ``BasedOnStyle`` is not present, options not present in the YAML /// document, are retained in \p Style. std::error_code parseConfiguration(StringRef Text, FormatStyle *Style); /// \brief Gets configuration in a YAML string. std::string configurationAsText(const FormatStyle &Style); -/// \brief Returns the replacements necessary to sort all #include blocks that -/// are affected by 'Ranges'. +/// \brief Returns the replacements necessary to sort all ``#include`` blocks +/// that are affected by ``Ranges``. tooling::Replacements sortIncludes(const FormatStyle &Style, StringRef Code, ArrayRef<tooling::Range> Ranges, StringRef FileName, unsigned *Cursor = nullptr); +/// \brief Returns the replacements corresponding to applying and formatting +/// \p Replaces on success; otheriwse, return an llvm::Error carrying +/// llvm::StringError. +llvm::Expected<tooling::Replacements> +formatReplacements(StringRef Code, const tooling::Replacements &Replaces, + const FormatStyle &Style); + +/// \brief Returns the replacements corresponding to applying \p Replaces and +/// cleaning up the code after that on success; otherwise, return an llvm::Error +/// carrying llvm::StringError. +/// This also inserts a C++ #include directive into the correct block if the +/// replacement corresponding to the header insertion has offset UINT_MAX. +llvm::Expected<tooling::Replacements> +cleanupAroundReplacements(StringRef Code, const tooling::Replacements &Replaces, + const FormatStyle &Style); + /// \brief Reformats the given \p Ranges in the file \p ID. /// /// Each range is extended on either end to its next bigger logic unit, i.e. /// everything that might influence its formatting or might be influenced by its /// formatting. /// -/// Returns the \c Replacements necessary to make all \p Ranges comply with +/// Returns the ``Replacements`` necessary to make all \p Ranges comply with /// \p Style. /// -/// If \c IncompleteFormat is non-null, its value will be set to true if any +/// If ``IncompleteFormat`` is non-null, its value will be set to true if any /// of the affected ranges were not formatted due to a non-recoverable syntax /// error. tooling::Replacements reformat(const FormatStyle &Style, @@ -749,37 +810,71 @@ tooling::Replacements reformat(const FormatStyle &Style, StringRef Code, StringRef FileName = "<stdin>", bool *IncompleteFormat = nullptr); -/// \brief Returns the \c LangOpts that the formatter expects you to set. +/// \brief Clean up any erroneous/redundant code in the given \p Ranges in the +/// file \p ID. +/// +/// Returns the ``Replacements`` that clean up all \p Ranges in the file \p ID. +tooling::Replacements cleanup(const FormatStyle &Style, + SourceManager &SourceMgr, FileID ID, + ArrayRef<CharSourceRange> Ranges); + +/// \brief Clean up any erroneous/redundant code in the given \p Ranges in \p +/// Code. +/// +/// Otherwise identical to the cleanup() function using a file ID. +tooling::Replacements cleanup(const FormatStyle &Style, StringRef Code, + ArrayRef<tooling::Range> Ranges, + StringRef FileName = "<stdin>"); + +/// \brief Returns the ``LangOpts`` that the formatter expects you to set. /// /// \param Style determines specific settings for lexing mode. LangOptions getFormattingLangOpts(const FormatStyle &Style = getLLVMStyle()); -/// \brief Description to be used for help text for a llvm::cl option for +/// \brief Description to be used for help text for a ``llvm::cl`` option for /// specifying format style. The description is closely related to the operation -/// of getStyle(). +/// of ``getStyle()``. extern const char *StyleOptionHelpDescription; -/// \brief Construct a FormatStyle based on \c StyleName. +/// \brief Construct a FormatStyle based on ``StyleName``. /// -/// \c StyleName can take several forms: -/// \li "{<key>: <value>, ...}" - Set specic style parameters. -/// \li "<style name>" - One of the style names supported by +/// ``StyleName`` can take several forms: +/// * "{<key>: <value>, ...}" - Set specic style parameters. +/// * "<style name>" - One of the style names supported by /// getPredefinedStyle(). -/// \li "file" - Load style configuration from a file called '.clang-format' -/// located in one of the parent directories of \c FileName or the current -/// directory if \c FileName is empty. +/// * "file" - Load style configuration from a file called ``.clang-format`` +/// located in one of the parent directories of ``FileName`` or the current +/// directory if ``FileName`` is empty. /// /// \param[in] StyleName Style name to interpret according to the description /// above. -/// \param[in] FileName Path to start search for .clang-format if \c StyleName +/// \param[in] FileName Path to start search for .clang-format if ``StyleName`` /// == "file". /// \param[in] FallbackStyle The name of a predefined style used to fallback to /// in case the style can't be determined from \p StyleName. +/// \param[in] FS The underlying file system, in which the file resides. By +/// default, the file system is the real file system. /// -/// \returns FormatStyle as specified by \c StyleName. If no style could be -/// determined, the default is LLVM Style (see getLLVMStyle()). +/// \returns FormatStyle as specified by ``StyleName``. If no style could be +/// determined, the default is LLVM Style (see ``getLLVMStyle()``). FormatStyle getStyle(StringRef StyleName, StringRef FileName, - StringRef FallbackStyle); + StringRef FallbackStyle, vfs::FileSystem *FS = nullptr); + +// \brief Returns a string representation of ``Language``. +inline StringRef getLanguageName(FormatStyle::LanguageKind Language) { + switch (Language) { + case FormatStyle::LK_Cpp: + return "C++"; + case FormatStyle::LK_Java: + return "Java"; + case FormatStyle::LK_JavaScript: + return "JavaScript"; + case FormatStyle::LK_Proto: + return "Proto"; + default: + return "Unknown"; + } +} } // end namespace format } // end namespace clang diff --git a/include/clang/Frontend/ASTConsumers.h b/include/clang/Frontend/ASTConsumers.h index 757fcae988fc0..b76bfcbe46638 100644 --- a/include/clang/Frontend/ASTConsumers.h +++ b/include/clang/Frontend/ASTConsumers.h @@ -31,7 +31,7 @@ class TargetOptions; // original C code. The output is intended to be in a format such that // clang could re-parse the output back into the same AST, but the // implementation is still incomplete. -std::unique_ptr<ASTConsumer> CreateASTPrinter(raw_ostream *OS, +std::unique_ptr<ASTConsumer> CreateASTPrinter(std::unique_ptr<raw_ostream> OS, StringRef FilterString); // AST dumper: dumps the raw AST in human-readable form to stderr; this is diff --git a/include/clang/Frontend/ASTUnit.h b/include/clang/Frontend/ASTUnit.h index a5f7af5714395..04e6dce5110e8 100644 --- a/include/clang/Frontend/ASTUnit.h +++ b/include/clang/Frontend/ASTUnit.h @@ -60,7 +60,7 @@ class PCHContainerOperations; class PCHContainerReader; class SourceManager; class TargetInfo; -class ASTFrontendAction; +class FrontendAction; class ASTDeserializationListener; /// \brief Utility class for loading a ASTContext from an AST file. @@ -781,7 +781,7 @@ public: CompilerInvocation *CI, std::shared_ptr<PCHContainerOperations> PCHContainerOps, IntrusiveRefCntPtr<DiagnosticsEngine> Diags, - ASTFrontendAction *Action = nullptr, ASTUnit *Unit = nullptr, + FrontendAction *Action = nullptr, ASTUnit *Unit = nullptr, bool Persistent = true, StringRef ResourceFilesPath = StringRef(), bool OnlyLocalDecls = false, bool CaptureDiagnostics = false, unsigned PrecompilePreambleAfterNParses = 0, diff --git a/include/clang/Frontend/CodeGenOptions.def b/include/clang/Frontend/CodeGenOptions.def index d9f6ab7f42d57..6a4474cfe75f8 100644 --- a/include/clang/Frontend/CodeGenOptions.def +++ b/include/clang/Frontend/CodeGenOptions.def @@ -30,9 +30,12 @@ CODEGENOPT(Name, Bits, Default) CODEGENOPT(DisableIntegratedAS, 1, 0) ///< -no-integrated-as CODEGENOPT(CompressDebugSections, 1, 0) ///< -Wa,-compress-debug-sections -CODEGENOPT(Autolink , 1, 1) ///< -fno-autolink +CODEGENOPT(RelaxELFRelocations, 1, 0) ///< -Wa,--mrelax-relocations CODEGENOPT(AsmVerbose , 1, 0) ///< -dA, -fverbose-asm. +CODEGENOPT(AssumeSaneOperatorNew , 1, 1) ///< implicit __attribute__((malloc)) operator new +CODEGENOPT(Autolink , 1, 1) ///< -fno-autolink CODEGENOPT(ObjCAutoRefCountExceptions , 1, 0) ///< Whether ARC should be EH-safe. +CODEGENOPT(Backchain , 1, 0) ///< -mbackchain CODEGENOPT(CoverageExtraChecksum, 1, 0) ///< Whether we need a second checksum for functions in GCNO files. CODEGENOPT(CoverageNoFunctionNamesInData, 1, 0) ///< Do not include function names in GCDA files. CODEGENOPT(CoverageExitBlockBeforeBody, 1, 0) ///< Whether to emit the exit block before the body blocks in GCNO files. @@ -43,6 +46,7 @@ CODEGENOPT(DataSections , 1, 0) ///< Set when -fdata-sections is enabled. CODEGENOPT(UniqueSectionNames, 1, 1) ///< Set for -funique-section-names. CODEGENOPT(DisableFPElim , 1, 0) ///< Set when -fomit-frame-pointer is enabled. CODEGENOPT(DisableFree , 1, 0) ///< Don't free memory. +CODEGENOPT(DiscardValueNames , 1, 0) ///< Discard Value Names from the IR (LLVMContext flag) CODEGENOPT(DisableGCov , 1, 0) ///< Don't run the GCov pass, for testing. CODEGENOPT(DisableLLVMOpts , 1, 0) ///< Don't run any optimizations, for use in ///< getting .bc files that correspond to the @@ -54,7 +58,7 @@ CODEGENOPT(DisableLLVMPasses , 1, 0) ///< Don't run any LLVM IR passes to get CODEGENOPT(DisableRedZone , 1, 0) ///< Set when -mno-red-zone is enabled. CODEGENOPT(DisableTailCalls , 1, 0) ///< Do not emit tail calls. CODEGENOPT(EmitDeclMetadata , 1, 0) ///< Emit special metadata indicating what - ///< Decl* various IR entities came from. + ///< Decl* various IR entities came from. ///< Only useful when running CodeGen as a ///< subroutine. CODEGENOPT(EmitGcovArcs , 1, 0) ///< Emit coverage data files, aka. GCDA. @@ -63,18 +67,28 @@ CODEGENOPT(EmitOpenCLArgMetadata , 1, 0) ///< Emit OpenCL kernel arg metadata. CODEGENOPT(EmulatedTLS , 1, 0) ///< Set when -femulated-tls is enabled. /// \brief FP_CONTRACT mode (on/off/fast). ENUM_CODEGENOPT(FPContractMode, FPContractModeKind, 2, FPC_On) +/// \brief Embed Bitcode mode (off/all/bitcode/marker). +ENUM_CODEGENOPT(EmbedBitcode, EmbedBitcodeKind, 2, Embed_Off) CODEGENOPT(ForbidGuardVariables , 1, 0) ///< Issue errors if C++ guard variables ///< are required. CODEGENOPT(FunctionSections , 1, 0) ///< Set when -ffunction-sections is enabled. CODEGENOPT(InstrumentFunctions , 1, 0) ///< Set when -finstrument-functions is ///< enabled. + +CODEGENOPT(XRayInstrumentFunctions , 1, 0) ///< Set when -fxray-instrument is + ///< enabled. + +///< Set the minimum number of instructions in a function to determine selective +///< XRay instrumentation. +VALUE_CODEGENOPT(XRayInstructionThreshold , 32, 200) + CODEGENOPT(InstrumentForProfiling , 1, 0) ///< Set when -pg is enabled. CODEGENOPT(LessPreciseFPMAD , 1, 0) ///< Enable less precise MAD instructions to ///< be generated. CODEGENOPT(PrepareForLTO , 1, 0) ///< Set when -flto is enabled on the ///< compile step. -CODEGENOPT(EmitFunctionSummary, 1, 0) ///< Set when -flto=thin is enabled on the - ///< compile step. +CODEGENOPT(EmitSummaryIndex, 1, 0) ///< Set when -flto=thin is enabled on the + ///< compile step. CODEGENOPT(IncrementalLinkerCompatible, 1, 0) ///< Emit an object file which can ///< be used with an incremental ///< linker. @@ -97,14 +111,16 @@ CODEGENOPT(NoInline , 1, 0) ///< Set when -fno-inline is enabled. CODEGENOPT(NoNaNsFPMath , 1, 0) ///< Assume FP arguments, results not NaN. CODEGENOPT(NoZeroInitializedInBSS , 1, 0) ///< -fno-zero-initialized-in-bss. /// \brief Method of Objective-C dispatch to use. -ENUM_CODEGENOPT(ObjCDispatchMethod, ObjCDispatchMethodKind, 2, Legacy) +ENUM_CODEGENOPT(ObjCDispatchMethod, ObjCDispatchMethodKind, 2, Legacy) CODEGENOPT(OmitLeafFramePointer , 1, 0) ///< Set when -momit-leaf-frame-pointer is ///< enabled. VALUE_CODEGENOPT(OptimizationLevel, 2, 0) ///< The -O[0-3] option specified. VALUE_CODEGENOPT(OptimizeSize, 2, 0) ///< If -Os (==1) or -Oz (==2) is specified. -CODEGENOPT(ProfileInstrGenerate , 1, 0) ///< Instrument code to generate - ///< execution counts to use with PGO. +/// \brief Choose profile instrumenation kind or no instrumentation. +ENUM_CODEGENOPT(ProfileInstr, ProfileInstrKind, 2, ProfileNone) +/// \brief Choose profile kind for PGO use compilation. +ENUM_CODEGENOPT(ProfileUse, ProfileInstrKind, 2, ProfileNone) CODEGENOPT(CoverageMapping , 1, 0) ///< Generate coverage mapping regions to ///< enable code coverage analysis. CODEGENOPT(DumpCoverageMapping , 1, 0) ///< Dump the generated coverage mapping @@ -117,8 +133,8 @@ CODEGENOPT(RelaxAll , 1, 0) ///< Relax all machine code instructions. CODEGENOPT(RelaxedAliasing , 1, 0) ///< Set when -fno-strict-aliasing is enabled. CODEGENOPT(StructPathTBAA , 1, 0) ///< Whether or not to use struct-path TBAA. CODEGENOPT(SaveTempLabels , 1, 0) ///< Save temporary labels. -CODEGENOPT(SanitizeAddressZeroBaseShadow , 1, 0) ///< Map shadow memory at zero - ///< offset in AddressSanitizer. +CODEGENOPT(SanitizeAddressUseAfterScope , 1, 0) ///< Enable use-after-scope detection + ///< in AddressSanitizer CODEGENOPT(SanitizeMemoryTrackOrigins, 2, 0) ///< Enable tracking origins in ///< MemorySanitizer CODEGENOPT(SanitizeMemoryUseAfterDtor, 1, 0) ///< Enable use-after-delete detection @@ -134,15 +150,17 @@ CODEGENOPT(SanitizeCoverageTraceCmp, 1, 0) ///< Enable cmp instruction tracing ///< in sanitizer coverage. CODEGENOPT(SanitizeCoverage8bitCounters, 1, 0) ///< Use 8-bit frequency counters ///< in sanitizer coverage. +CODEGENOPT(SanitizeCoverageTracePC, 1, 0) ///< Enable PC tracing + ///< in sanitizer coverage. +CODEGENOPT(SanitizeStats , 1, 0) ///< Collect statistics for sanitizers. CODEGENOPT(SimplifyLibCalls , 1, 1) ///< Set when -fbuiltin is enabled. CODEGENOPT(SoftFloat , 1, 0) ///< -soft-float. CODEGENOPT(StrictEnums , 1, 0) ///< Optimize based on strict enum definition. CODEGENOPT(StrictVTablePointers, 1, 0) ///< Optimize based on the strict vtable pointers CODEGENOPT(TimePasses , 1, 0) ///< Set when -ftime-report is enabled. -CODEGENOPT(UnitAtATime , 1, 1) ///< Unused. For mirroring GCC optimization - ///< selection. CODEGENOPT(UnrollLoops , 1, 0) ///< Control whether loops are unrolled. CODEGENOPT(RerollLoops , 1, 0) ///< Control whether loops are rerolled. +CODEGENOPT(NoUseJumpTables , 1, 0) ///< Set when -fno-jump-tables is enabled. CODEGENOPT(UnsafeFPMath , 1, 0) ///< Allow unsafe floating point optzns. CODEGENOPT(UnwindTables , 1, 0) ///< Emit unwind tables. CODEGENOPT(VectorizeBB , 1, 0) ///< Run basic block vectorizer. @@ -160,7 +178,7 @@ CODEGENOPT(StackRealignment , 1, 0) ///< Control whether to force stack ///< realignment. CODEGENOPT(UseInitArray , 1, 0) ///< Control whether to use .init_array or ///< .ctors. -VALUE_CODEGENOPT(StackAlignment , 32, 0) ///< Overrides default stack +VALUE_CODEGENOPT(StackAlignment , 32, 0) ///< Overrides default stack ///< alignment, if not 0. VALUE_CODEGENOPT(StackProbeSize , 32, 4096) ///< Overrides default stack ///< probe size, even if 0. @@ -170,12 +188,19 @@ CODEGENOPT(DebugColumnInfo, 1, 0) ///< Whether or not to use column information CODEGENOPT(DebugTypeExtRefs, 1, 0) ///< Whether or not debug info should contain ///< external references to a PCH or module. -CODEGENOPT(DebugExplicitImport, 1, 0) ///< Whether or not debug info should - ///< contain explicit imports for +CODEGENOPT(DebugExplicitImport, 1, 0) ///< Whether or not debug info should + ///< contain explicit imports for ///< anonymous namespaces CODEGENOPT(EmitLLVMUseLists, 1, 0) ///< Control whether to serialize use-lists. +CODEGENOPT(WholeProgramVTables, 1, 0) ///< Whether to apply whole-program + /// vtable optimization. + +/// Whether to use public LTO visibility for entities in std and stdext +/// namespaces. This is enabled by clang-cl's /MT and /MTd flags. +CODEGENOPT(LTOVisibilityPublicStd, 1, 0) + /// The user specified number of registers to be used for integral arguments, /// or 0 if unspecified. VALUE_CODEGENOPT(NumRegisterParameters, 32, 0) @@ -184,10 +209,11 @@ VALUE_CODEGENOPT(NumRegisterParameters, 32, 0) VALUE_CODEGENOPT(SSPBufferSize, 32, 0) /// The kind of generated debug info. -ENUM_CODEGENOPT(DebugInfo, DebugInfoKind, 3, NoDebugInfo) +ENUM_CODEGENOPT(DebugInfo, codegenoptions::DebugInfoKind, 3, codegenoptions::NoDebugInfo) /// Tune the debug info for this debugger. -ENUM_CODEGENOPT(DebuggerTuning, DebuggerKind, 2, DebuggerKindDefault) +ENUM_CODEGENOPT(DebuggerTuning, llvm::DebuggerKind, 2, + llvm::DebuggerKind::Default) /// Dwarf version. Version zero indicates to LLVM that no DWARF should be /// emitted. @@ -206,6 +232,10 @@ ENUM_CODEGENOPT(VecLib, VectorLibrary, 1, NoLibrary) /// The default TLS model to use. ENUM_CODEGENOPT(DefaultTLSModel, TLSModel, 2, GeneralDynamicTLSModel) +/// Number of path components to strip when emitting checks. (0 == full +/// filename) +VALUE_CODEGENOPT(EmitCheckPathComponentsToStrip, 32, 0) + #undef CODEGENOPT #undef ENUM_CODEGENOPT #undef VALUE_CODEGENOPT diff --git a/include/clang/Frontend/CodeGenOptions.h b/include/clang/Frontend/CodeGenOptions.h index 7550e6f4c7481..4bc3120908f04 100644 --- a/include/clang/Frontend/CodeGenOptions.h +++ b/include/clang/Frontend/CodeGenOptions.h @@ -14,8 +14,10 @@ #ifndef LLVM_CLANG_FRONTEND_CODEGENOPTIONS_H #define LLVM_CLANG_FRONTEND_CODEGENOPTIONS_H +#include "clang/Basic/DebugInfoOptions.h" #include "clang/Basic/Sanitizers.h" #include "llvm/Support/Regex.h" +#include "llvm/Target/TargetOptions.h" #include <map> #include <memory> #include <string> @@ -44,6 +46,7 @@ public: enum InliningMethod { NoInlining, // Perform no inlining whatsoever. NormalInlining, // Use the standard function inlining pass. + OnlyHintInlining, // Inline only (implicitly) hinted functions. OnlyAlwaysInlining // Only run the always inlining pass. }; @@ -58,37 +61,6 @@ public: Mixed = 2 }; - enum DebugInfoKind { - NoDebugInfo, /// Don't generate debug info. - - LocTrackingOnly, /// Emit location information but do not generate - /// debug info in the output. This is useful in - /// cases where the backend wants to track source - /// locations for instructions without actually - /// emitting debug info for them (e.g., when -Rpass - /// is used). - - DebugLineTablesOnly, /// Emit only debug info necessary for generating - /// line number tables (-gline-tables-only). - - LimitedDebugInfo, /// Limit generated debug info to reduce size - /// (-fno-standalone-debug). This emits - /// forward decls for types that could be - /// replaced with forward decls in the source - /// code. For dynamic C++ classes type info - /// is only emitted int the module that - /// contains the classe's vtable. - - FullDebugInfo /// Generate complete debug info. - }; - - enum DebuggerKind { - DebuggerKindDefault, - DebuggerKindGDB, - DebuggerKindLLDB, - DebuggerKindSCE - }; - enum TLSModel { GeneralDynamicTLSModel, LocalDynamicTLSModel, @@ -108,6 +80,20 @@ public: SRCK_InRegs // Small structs in registers (-freg-struct-return). }; + enum ProfileInstrKind { + ProfileNone, // Profile instrumentation is turned off. + ProfileClangInstr, // Clang instrumentation to generate execution counts + // to use with PGO. + ProfileIRInstr, // IR level PGO instrumentation in LLVM. + }; + + enum EmbedBitcodeKind { + Embed_Off, // No embedded bitcode. + Embed_All, // Embed both bitcode and commandline in the output. + Embed_Bitcode, // Embed just the bitcode in the output. + Embed_Marker // Embed a marker as a placeholder for bitcode. + }; + /// The code model to use (-mcmodel). std::string CodeModel; @@ -164,6 +150,9 @@ public: /// A list of dependent libraries. std::vector<std::string> DependentLibraries; + /// A list of linker options to embed in the object file. + std::vector<std::string> LinkerOptions; + /// Name of the profile file to use as output for -fprofile-instr-generate /// and -fprofile-generate. std::string InstrProfileOutput; @@ -172,15 +161,12 @@ public: std::string SampleProfileFile; /// Name of the profile file to use as input for -fprofile-instr-use - std::string InstrProfileInput; + std::string ProfileInstrumentUsePath; /// Name of the function summary index file to use for ThinLTO function /// importing. std::string ThinLTOIndexFile; - /// The EABI version to use - std::string EABIVersion; - /// A list of file names passed with -fcuda-include-gpubinary options to /// forward to CUDA runtime back-end for incorporating them into host-side /// object file. @@ -218,6 +204,9 @@ public: /// Set of sanitizer checks that trap rather than diagnose. SanitizerSet SanitizeTrap; + /// List of backend command-line options for -fembed-bitcode. + std::vector<uint8_t> CmdArgs; + /// \brief A list of all -fno-builtin-* function names (e.g., memset). std::vector<std::string> NoBuiltinFuncs; @@ -238,6 +227,27 @@ public: const std::vector<std::string> &getNoBuiltinFuncs() const { return NoBuiltinFuncs; } + + /// \brief Check if Clang profile instrumenation is on. + bool hasProfileClangInstr() const { + return getProfileInstr() == ProfileClangInstr; + } + + /// \brief Check if IR level profile instrumentation is on. + bool hasProfileIRInstr() const { + return getProfileInstr() == ProfileIRInstr; + } + + /// \brief Check if Clang profile use is on. + bool hasProfileClangUse() const { + return getProfileUse() == ProfileClangInstr; + } + + /// \brief Check if IR level profile use is on. + bool hasProfileIRUse() const { + return getProfileUse() == ProfileIRInstr; + } + }; } // end namespace clang diff --git a/include/clang/Frontend/CompilerInstance.h b/include/clang/Frontend/CompilerInstance.h index 83eed2cdc5921..1228cf4d5fcd2 100644 --- a/include/clang/Frontend/CompilerInstance.h +++ b/include/clang/Frontend/CompilerInstance.h @@ -155,15 +155,10 @@ class CompilerInstance : public ModuleLoader { struct OutputFile { std::string Filename; std::string TempFilename; - std::unique_ptr<raw_ostream> OS; - - OutputFile(std::string filename, std::string tempFilename, - std::unique_ptr<raw_ostream> OS) - : Filename(std::move(filename)), TempFilename(std::move(tempFilename)), - OS(std::move(OS)) {} - OutputFile(OutputFile &&O) - : Filename(std::move(O.Filename)), - TempFilename(std::move(O.TempFilename)), OS(std::move(O.OS)) {} + + OutputFile(std::string filename, std::string tempFilename) + : Filename(std::move(filename)), TempFilename(std::move(tempFilename)) { + } }; /// If the output doesn't support seeking (terminal, pipe). we switch @@ -380,7 +375,7 @@ public: /// \note Most clients should use setFileManager, which will implicitly reset /// the virtual file system to the one contained in the file manager. void setVirtualFileSystem(IntrusiveRefCntPtr<vfs::FileSystem> FS) { - VirtualFileSystem = FS; + VirtualFileSystem = std::move(FS); } /// } @@ -577,8 +572,8 @@ public: /// \param OutFile - The output file info. void addOutputFile(OutputFile &&OutFile); - /// clearOutputFiles - Clear the output file list, destroying the contained - /// output streams. + /// clearOutputFiles - Clear the output file list. The underlying output + /// streams must have been closed beforehand. /// /// \param EraseFiles - If true, attempt to erase the files from disk. void clearOutputFiles(bool EraseFiles); @@ -685,19 +680,18 @@ public: /// atomically replace the target output on success). /// /// \return - Null on error. - raw_pwrite_stream *createDefaultOutputFile(bool Binary = true, - StringRef BaseInput = "", - StringRef Extension = ""); + std::unique_ptr<raw_pwrite_stream> + createDefaultOutputFile(bool Binary = true, StringRef BaseInput = "", + StringRef Extension = ""); /// Create a new output file and add it to the list of tracked output files, /// optionally deriving the output path name. /// /// \return - Null on error. - raw_pwrite_stream *createOutputFile(StringRef OutputPath, bool Binary, - bool RemoveFileOnSignal, - StringRef BaseInput, StringRef Extension, - bool UseTemporary, - bool CreateMissingDirectories = false); + std::unique_ptr<raw_pwrite_stream> + createOutputFile(StringRef OutputPath, bool Binary, bool RemoveFileOnSignal, + StringRef BaseInput, StringRef Extension, bool UseTemporary, + bool CreateMissingDirectories = false); /// Create a new output file, optionally deriving the output path name. /// @@ -731,7 +725,7 @@ public: bool CreateMissingDirectories, std::string *ResultPathName, std::string *TempPathName); - llvm::raw_null_ostream *createNullOutputFile(); + std::unique_ptr<raw_pwrite_stream> createNullOutputFile(); /// } /// @name Initialization Utility Methods @@ -748,10 +742,12 @@ public: /// /// \return True on success. static bool InitializeSourceManager(const FrontendInputFile &Input, - DiagnosticsEngine &Diags, - FileManager &FileMgr, - SourceManager &SourceMgr, - const FrontendOptions &Opts); + DiagnosticsEngine &Diags, + FileManager &FileMgr, + SourceManager &SourceMgr, + HeaderSearch *HS, + DependencyOutputOptions &DepOpts, + const FrontendOptions &Opts); /// } diff --git a/include/clang/Frontend/CompilerInvocation.h b/include/clang/Frontend/CompilerInvocation.h index 0b4a1e587e7e4..0d5008e9a6656 100644 --- a/include/clang/Frontend/CompilerInvocation.h +++ b/include/clang/Frontend/CompilerInvocation.h @@ -47,7 +47,8 @@ class DiagnosticsEngine; /// When errors are encountered, return false and, if Diags is non-null, /// report the error(s). bool ParseDiagnosticArgs(DiagnosticOptions &Opts, llvm::opt::ArgList &Args, - DiagnosticsEngine *Diags = nullptr); + DiagnosticsEngine *Diags = nullptr, + bool DefaultDiagColor = true); class CompilerInvocationBase : public RefCountedBase<CompilerInvocation> { void operator=(const CompilerInvocationBase &) = delete; @@ -153,8 +154,11 @@ public: /// /// \param Opts - The LangOptions object to set up. /// \param IK - The input language. + /// \param T - The target triple. + /// \param PPOpts - The PreprocessorOptions affected. /// \param LangStd - The input language standard. static void setLangDefaults(LangOptions &Opts, InputKind IK, + const llvm::Triple &T, PreprocessorOptions &PPOpts, LangStandard::Kind LangStd = LangStandard::lang_unspecified); /// \brief Retrieve a module hash string that is suitable for uniquely diff --git a/include/clang/Frontend/DependencyOutputOptions.h b/include/clang/Frontend/DependencyOutputOptions.h index 129b5346c7459..0be36cd9aa6ea 100644 --- a/include/clang/Frontend/DependencyOutputOptions.h +++ b/include/clang/Frontend/DependencyOutputOptions.h @@ -50,6 +50,9 @@ public: /// A list of filenames to be used as extra dependencies for every target. std::vector<std::string> ExtraDeps; + /// In /showIncludes mode, pretend the main TU is a header with this name. + std::string ShowIncludesPretendHeader; + /// \brief The file to write GraphViz-formatted header dependencies to. std::string DOTOutputFile; diff --git a/include/clang/Frontend/FrontendAction.h b/include/clang/Frontend/FrontendAction.h index c407ff80ac562..384499a3d82a7 100644 --- a/include/clang/Frontend/FrontendAction.h +++ b/include/clang/Frontend/FrontendAction.h @@ -130,7 +130,7 @@ public: const FrontendInputFile &getCurrentInput() const { return CurrentInput; } - + const StringRef getCurrentFile() const { assert(!CurrentInput.isEmpty() && "No current file!"); return CurrentInput.getFile(); @@ -157,7 +157,7 @@ public: /// @name Supported Modes /// @{ - /// \brief Is this action invoked on a model file? + /// \brief Is this action invoked on a model file? /// /// Model files are incomplete translation units that relies on type /// information from another translation unit. Check ParseModelFileAction for @@ -249,6 +249,19 @@ public: /// CompilerInstance's Diagnostic object to report errors. virtual bool ParseArgs(const CompilerInstance &CI, const std::vector<std::string> &arg) = 0; + + enum ActionType { + Cmdline, ///< Action is determined by the cc1 command-line + ReplaceAction, ///< Replace the main action + AddBeforeMainAction, ///< Execute the action before the main action + AddAfterMainAction ///< Execute the action after the main action + }; + /// \brief Get the action type for this plugin + /// + /// \return The action type. If the type is Cmdline then by default the + /// plugin does nothing and what it does is determined by the cc1 + /// command-line. + virtual ActionType getActionType() { return Cmdline; } }; /// \brief Abstract base class to use for preprocessor-based frontend actions. @@ -283,7 +296,7 @@ protected: public: /// Construct a WrapperFrontendAction from an existing action, taking /// ownership of it. - WrapperFrontendAction(FrontendAction *WrappedAction); + WrapperFrontendAction(std::unique_ptr<FrontendAction> WrappedAction); bool usesPreprocessorOnly() const override; TranslationUnitKind getTranslationUnitKind() override; diff --git a/include/clang/Frontend/FrontendActions.h b/include/clang/Frontend/FrontendActions.h index f61775f014f8a..0cbacbb4b1228 100644 --- a/include/clang/Frontend/FrontendActions.h +++ b/include/clang/Frontend/FrontendActions.h @@ -85,7 +85,7 @@ public: /// create the PCHGenerator instance returned by CreateASTConsumer. /// /// \returns true if an error occurred, false otherwise. - static raw_pwrite_stream * + static std::unique_ptr<raw_pwrite_stream> ComputeASTConsumerArguments(CompilerInstance &CI, StringRef InFile, std::string &Sysroot, std::string &OutputFile); }; @@ -117,10 +117,9 @@ public: /// create the PCHGenerator instance returned by CreateASTConsumer. /// /// \returns true if an error occurred, false otherwise. - raw_pwrite_stream *ComputeASTConsumerArguments(CompilerInstance &CI, - StringRef InFile, - std::string &Sysroot, - std::string &OutputFile); + std::unique_ptr<raw_pwrite_stream> + ComputeASTConsumerArguments(CompilerInstance &CI, StringRef InFile, + std::string &Sysroot, std::string &OutputFile); }; class SyntaxOnlyAction : public ASTFrontendAction { @@ -129,6 +128,7 @@ protected: StringRef InFile) override; public: + ~SyntaxOnlyAction() override; bool hasCodeCompletionSupport() const override { return true; } }; @@ -168,7 +168,7 @@ public: */ class ASTMergeAction : public FrontendAction { /// \brief The action that the merge action adapts. - FrontendAction *AdaptedAction; + std::unique_ptr<FrontendAction> AdaptedAction; /// \brief The set of AST files to merge. std::vector<std::string> ASTFiles; @@ -184,7 +184,8 @@ protected: void EndSourceFileAction() override; public: - ASTMergeAction(FrontendAction *AdaptedAction, ArrayRef<std::string> ASTFiles); + ASTMergeAction(std::unique_ptr<FrontendAction> AdaptedAction, + ArrayRef<std::string> ASTFiles); ~ASTMergeAction() override; bool usesPreprocessorOnly() const override; diff --git a/include/clang/Frontend/FrontendOptions.h b/include/clang/Frontend/FrontendOptions.h index c800a5148e496..a75523f256488 100644 --- a/include/clang/Frontend/FrontendOptions.h +++ b/include/clang/Frontend/FrontendOptions.h @@ -16,6 +16,7 @@ #include "llvm/ADT/StringRef.h" #include <string> #include <vector> +#include <unordered_map> namespace llvm { class MemoryBuffer; @@ -73,6 +74,7 @@ enum InputKind { IK_OpenCL, IK_CUDA, IK_PreprocessedCuda, + IK_RenderScript, IK_AST, IK_LLVM_IR }; @@ -152,6 +154,8 @@ public: ///< implicit module build. unsigned ModulesEmbedAllFiles : 1; ///< Whether we should embed all used ///< files into the PCM file. + unsigned IncludeTimestamps : 1; ///< Whether timestamps should be + ///< written to the produced PCH file. CodeCompleteOptions CodeCompleteOpts; @@ -227,15 +231,12 @@ public: /// The name of the action to run when using a plugin action. std::string ActionName; - /// Args to pass to the plugin - std::vector<std::string> PluginArgs; + /// Args to pass to the plugins + std::unordered_map<std::string,std::vector<std::string>> PluginArgs; /// The list of plugin actions to run in addition to the normal action. std::vector<std::string> AddPluginActions; - /// Args to pass to the additional plugins - std::vector<std::vector<std::string> > AddPluginArgs; - /// The list of plugins to load. std::vector<std::string> Plugins; @@ -266,6 +267,10 @@ public: /// \brief Auxiliary triple for CUDA compilation. std::string AuxTriple; + /// \brief If non-empty, search the pch input file as it was a header + // included by this file. + std::string FindPchSource; + public: FrontendOptions() : DisableFree(false), RelocatablePCH(false), ShowHelp(false), @@ -275,8 +280,8 @@ public: SkipFunctionBodies(false), UseGlobalModuleIndex(true), GenerateGlobalModuleIndex(true), ASTDumpDecls(false), ASTDumpLookups(false), BuildingImplicitModule(false), ModulesEmbedAllFiles(false), - ARCMTAction(ARCMT_None), ObjCMTAction(ObjCMT_None), - ProgramAction(frontend::ParseSyntaxOnly) + IncludeTimestamps(true), ARCMTAction(ARCMT_None), + ObjCMTAction(ObjCMT_None), ProgramAction(frontend::ParseSyntaxOnly) {} /// getInputKindForExtension - Return the appropriate input kind for a file diff --git a/include/clang/Frontend/LangStandards.def b/include/clang/Frontend/LangStandards.def index cac9c3c4155f3..a3036932f049e 100644 --- a/include/clang/Frontend/LangStandards.def +++ b/include/clang/Frontend/LangStandards.def @@ -19,6 +19,14 @@ /// \param FEATURES - The standard features as flags, these are enums from the /// clang::frontend namespace, which is assumed to be be available. +/// LANGSTANDARD_ALIAS(IDENT, ALIAS) +/// \param IDENT - The name of the standard as a C++ identifier. +/// \param ALIAS - The alias of the standard. + +#ifndef LANGSTANDARD_ALIAS +#define LANGSTANDARD_ALIAS(IDENT, ALIAS) +#endif + // C89-ish modes. LANGSTANDARD(c89, "c89", "ISO C 1990", @@ -125,29 +133,36 @@ LANGSTANDARD(gnucxx14, "gnu++14", LANGSTANDARD(cxx1z, "c++1z", "Working draft for ISO C++ 2017", LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus14 | CPlusPlus1z | - Digraphs) + Digraphs | HexFloat) LANGSTANDARD(gnucxx1z, "gnu++1z", "Working draft for ISO C++ 2017 with GNU extensions", LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus14 | CPlusPlus1z | - Digraphs | GNUMode) + Digraphs | HexFloat | GNUMode) // OpenCL LANGSTANDARD(opencl, "cl", "OpenCL 1.0", LineComment | C99 | Digraphs | HexFloat) -LANGSTANDARD(opencl11, "CL1.1", +LANGSTANDARD(opencl11, "cl1.1", "OpenCL 1.1", LineComment | C99 | Digraphs | HexFloat) -LANGSTANDARD(opencl12, "CL1.2", +LANGSTANDARD(opencl12, "cl1.2", "OpenCL 1.2", LineComment | C99 | Digraphs | HexFloat) -LANGSTANDARD(opencl20, "CL2.0", +LANGSTANDARD(opencl20, "cl2.0", "OpenCL 2.0", LineComment | C99 | Digraphs | HexFloat) +LANGSTANDARD_ALIAS(opencl, "CL") +LANGSTANDARD_ALIAS(opencl11, "CL1.1") +LANGSTANDARD_ALIAS(opencl12, "CL1.2") +LANGSTANDARD_ALIAS(opencl20, "CL2.0") + // CUDA LANGSTANDARD(cuda, "cuda", "NVIDIA CUDA(tm)", LineComment | CPlusPlus | Digraphs) #undef LANGSTANDARD +#undef LANGSTANDARD_ALIAS + diff --git a/include/clang/Frontend/MultiplexConsumer.h b/include/clang/Frontend/MultiplexConsumer.h index 873af038f20d0..d13565c27bc33 100644 --- a/include/clang/Frontend/MultiplexConsumer.h +++ b/include/clang/Frontend/MultiplexConsumer.h @@ -36,7 +36,7 @@ public: void Initialize(ASTContext &Context) override; void HandleCXXStaticMemberVarInstantiation(VarDecl *VD) override; bool HandleTopLevelDecl(DeclGroupRef D) override; - void HandleInlineMethodDefinition(CXXMethodDecl *D) override; + void HandleInlineFunctionDefinition(FunctionDecl *D) override; void HandleInterestingDecl(DeclGroupRef D) override; void HandleTranslationUnit(ASTContext &Ctx) override; void HandleTagDeclDefinition(TagDecl *D) override; @@ -44,15 +44,13 @@ public: void HandleCXXImplicitFunctionInstantiation(FunctionDecl *D) override; void HandleTopLevelDeclInObjCContainer(DeclGroupRef D) override; void HandleImplicitImportDecl(ImportDecl *D) override; - void HandleLinkerOptionPragma(llvm::StringRef Opts) override; - void HandleDetectMismatch(llvm::StringRef Name, - llvm::StringRef Value) override; - void HandleDependentLibrary(llvm::StringRef Lib) override; void CompleteTentativeDefinition(VarDecl *D) override; + void AssignInheritanceModel(CXXRecordDecl *RD) override; void HandleVTable(CXXRecordDecl *RD) override; ASTMutationListener *GetASTMutationListener() override; ASTDeserializationListener *GetASTDeserializationListener() override; void PrintStats() override; + bool shouldSkipFunctionBody(Decl *D) override; // SemaConsumer void InitializeSema(Sema &S) override; diff --git a/include/clang/Frontend/PCHContainerOperations.h b/include/clang/Frontend/PCHContainerOperations.h index 67c36cf08eb35..0c1b28e9a51f6 100644 --- a/include/clang/Frontend/PCHContainerOperations.h +++ b/include/clang/Frontend/PCHContainerOperations.h @@ -46,10 +46,12 @@ public: /// Return an ASTConsumer that can be chained with a /// PCHGenerator that produces a wrapper file format containing a /// serialized AST bitstream. - virtual std::unique_ptr<ASTConsumer> CreatePCHContainerGenerator( - CompilerInstance &CI, const std::string &MainFileName, - const std::string &OutputFileName, llvm::raw_pwrite_stream *OS, - std::shared_ptr<PCHBuffer> Buffer) const = 0; + virtual std::unique_ptr<ASTConsumer> + CreatePCHContainerGenerator(CompilerInstance &CI, + const std::string &MainFileName, + const std::string &OutputFileName, + std::unique_ptr<llvm::raw_pwrite_stream> OS, + std::shared_ptr<PCHBuffer> Buffer) const = 0; }; /// This abstract interface provides operations for unwrapping @@ -73,10 +75,12 @@ class RawPCHContainerWriter : public PCHContainerWriter { /// Return an ASTConsumer that can be chained with a /// PCHGenerator that writes the module to a flat file. - std::unique_ptr<ASTConsumer> CreatePCHContainerGenerator( - CompilerInstance &CI, const std::string &MainFileName, - const std::string &OutputFileName, llvm::raw_pwrite_stream *OS, - std::shared_ptr<PCHBuffer> Buffer) const override; + std::unique_ptr<ASTConsumer> + CreatePCHContainerGenerator(CompilerInstance &CI, + const std::string &MainFileName, + const std::string &OutputFileName, + std::unique_ptr<llvm::raw_pwrite_stream> OS, + std::shared_ptr<PCHBuffer> Buffer) const override; }; /// Implements read operations for a raw pass-through PCH container. diff --git a/include/clang/Frontend/TextDiagnosticPrinter.h b/include/clang/Frontend/TextDiagnosticPrinter.h index 04a570559fe06..07cee9f8ad8aa 100644 --- a/include/clang/Frontend/TextDiagnosticPrinter.h +++ b/include/clang/Frontend/TextDiagnosticPrinter.h @@ -45,7 +45,7 @@ public: /// setPrefix - Set the diagnostic printer prefix string, which will be /// printed at the start of any diagnostics. If empty, no prefix string is /// used. - void setPrefix(std::string Value) { Prefix = Value; } + void setPrefix(std::string Value) { Prefix = std::move(Value); } void BeginSourceFile(const LangOptions &LO, const Preprocessor *PP) override; void EndSourceFile() override; diff --git a/include/clang/Frontend/Utils.h b/include/clang/Frontend/Utils.h index a5f667ef7c7d2..cf943a5960bdc 100644 --- a/include/clang/Frontend/Utils.h +++ b/include/clang/Frontend/Utils.h @@ -20,6 +20,7 @@ #include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringSet.h" #include "llvm/Option/OptSpecifier.h" +#include <utility> namespace llvm { class raw_fd_ostream; @@ -73,12 +74,12 @@ void DoPrintPreprocessedInput(Preprocessor &PP, raw_ostream* OS, /// An interface for collecting the dependencies of a compilation. Users should /// use \c attachToPreprocessor and \c attachToASTReader to get all of the /// dependencies. -// FIXME: Migrate DependencyFileGen, DependencyGraphGen, ModuleDepCollectory to -// use this interface. +/// FIXME: Migrate DependencyFileGen and DependencyGraphGen to use this +/// interface. class DependencyCollector { public: - void attachToPreprocessor(Preprocessor &PP); - void attachToASTReader(ASTReader &R); + virtual void attachToPreprocessor(Preprocessor &PP); + virtual void attachToASTReader(ASTReader &R); llvm::ArrayRef<std::string> getDependencies() const { return Dependencies; } /// Called when a new file is seen. Return true if \p Filename should be added @@ -118,39 +119,43 @@ public: /// Collects the dependencies for imported modules into a directory. Users /// should attach to the AST reader whenever a module is loaded. -class ModuleDependencyCollector { +class ModuleDependencyCollector : public DependencyCollector { std::string DestDir; - bool HasErrors; + bool HasErrors = false; llvm::StringSet<> Seen; vfs::YAMLVFSWriter VFSWriter; + llvm::StringMap<std::string> SymLinkMap; + + bool getRealPath(StringRef SrcPath, SmallVectorImpl<char> &Result); + std::error_code copyToRoot(StringRef Src); public: StringRef getDest() { return DestDir; } bool insertSeen(StringRef Filename) { return Seen.insert(Filename).second; } - void setHasErrors() { HasErrors = true; } + void addFile(StringRef Filename); void addFileMapping(StringRef VPath, StringRef RPath) { VFSWriter.addFileMapping(VPath, RPath); } - void attachToASTReader(ASTReader &R); + void attachToPreprocessor(Preprocessor &PP) override; + void attachToASTReader(ASTReader &R) override; + void writeFileMap(); bool hasErrors() { return HasErrors; } ModuleDependencyCollector(std::string DestDir) - : DestDir(DestDir), HasErrors(false) {} + : DestDir(std::move(DestDir)) {} ~ModuleDependencyCollector() { writeFileMap(); } }; /// AttachDependencyGraphGen - Create a dependency graph generator, and attach /// it to the given preprocessor. - void AttachDependencyGraphGen(Preprocessor &PP, StringRef OutputFile, - StringRef SysRoot); +void AttachDependencyGraphGen(Preprocessor &PP, StringRef OutputFile, + StringRef SysRoot); /// AttachHeaderIncludeGen - Create a header include list generator, and attach /// it to the given preprocessor. /// -/// \param ExtraHeaders - If not empty, will write the header filenames, just -/// like they were included during a regular preprocessing. Useful for -/// implicit include dependencies, like sanitizer blacklists. +/// \param DepOpts - Options controlling the output. /// \param ShowAllHeaders - If true, show all header information instead of just /// headers following the predefines buffer. This is useful for making sure /// includes mentioned on the command line are also reported, but differs from @@ -160,7 +165,7 @@ public: /// \param ShowDepth - Whether to indent to show the nesting of the includes. /// \param MSStyle - Whether to print in cl.exe /showIncludes style. void AttachHeaderIncludeGen(Preprocessor &PP, - const std::vector<std::string> &ExtraHeaders, + const DependencyOutputOptions &DepOpts, bool ShowAllHeaders = false, StringRef OutputPath = "", bool ShowDepth = true, bool MSStyle = false); diff --git a/include/clang/Index/CodegenNameGenerator.h b/include/clang/Index/CodegenNameGenerator.h new file mode 100644 index 0000000000000..e8dc196a204de --- /dev/null +++ b/include/clang/Index/CodegenNameGenerator.h @@ -0,0 +1,52 @@ +//===- CodegenNameGenerator.h - Codegen name generation -------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Determines the name that the symbol will get for code generation. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_INDEX_CODEGENNAMEGENERATOR_H +#define LLVM_CLANG_INDEX_CODEGENNAMEGENERATOR_H + +#include "clang/Basic/LLVM.h" +#include <memory> +#include <string> +#include <vector> + +namespace clang { + class ASTContext; + class Decl; + +namespace index { + +class CodegenNameGenerator { +public: + explicit CodegenNameGenerator(ASTContext &Ctx); + ~CodegenNameGenerator(); + + /// \returns true on failure to produce a name for the given decl, false on + /// success. + bool writeName(const Decl *D, raw_ostream &OS); + + /// Version of \c writeName function that returns a string. + std::string getName(const Decl *D); + + /// This can return multiple mangled names when applicable, e.g. for C++ + /// constructors/destructors. + std::vector<std::string> getAllManglings(const Decl *D); + +private: + struct Implementation; + std::unique_ptr<Implementation> Impl; +}; + +} // namespace index +} // namespace clang + +#endif // LLVM_CLANG_INDEX_CODEGENNAMEGENERATOR_H diff --git a/include/clang/Index/IndexDataConsumer.h b/include/clang/Index/IndexDataConsumer.h new file mode 100644 index 0000000000000..315437048345b --- /dev/null +++ b/include/clang/Index/IndexDataConsumer.h @@ -0,0 +1,64 @@ +//===--- IndexDataConsumer.h - Abstract index data consumer ---------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_INDEX_INDEXDATACONSUMER_H +#define LLVM_CLANG_INDEX_INDEXDATACONSUMER_H + +#include "clang/Index/IndexSymbol.h" + +namespace clang { + class ASTContext; + class DeclContext; + class Expr; + class FileID; + class IdentifierInfo; + class ImportDecl; + class MacroInfo; + +namespace index { + +class IndexDataConsumer { +public: + struct ASTNodeInfo { + const Expr *OrigE; + const Decl *OrigD; + const Decl *Parent; + const DeclContext *ContainerDC; + }; + + virtual ~IndexDataConsumer() {} + + virtual void initialize(ASTContext &Ctx) {} + + /// \returns true to continue indexing, or false to abort. + virtual bool handleDeclOccurence(const Decl *D, SymbolRoleSet Roles, + ArrayRef<SymbolRelation> Relations, + FileID FID, unsigned Offset, + ASTNodeInfo ASTNode); + + /// \returns true to continue indexing, or false to abort. + virtual bool handleMacroOccurence(const IdentifierInfo *Name, + const MacroInfo *MI, SymbolRoleSet Roles, + FileID FID, unsigned Offset); + + /// \returns true to continue indexing, or false to abort. + virtual bool handleModuleOccurence(const ImportDecl *ImportD, + SymbolRoleSet Roles, + FileID FID, unsigned Offset); + + virtual void finish() {} + +private: + virtual void _anchor(); +}; + +} // namespace index +} // namespace clang + +#endif diff --git a/include/clang/Index/IndexSymbol.h b/include/clang/Index/IndexSymbol.h new file mode 100644 index 0000000000000..b0bc93e464b41 --- /dev/null +++ b/include/clang/Index/IndexSymbol.h @@ -0,0 +1,129 @@ +//===--- IndexSymbol.h - Types and functions for indexing symbols ---------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_INDEX_INDEXSYMBOL_H +#define LLVM_CLANG_INDEX_INDEXSYMBOL_H + +#include "clang/Basic/LLVM.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/Support/DataTypes.h" + +namespace clang { + class Decl; + class LangOptions; + +namespace index { + +enum class SymbolKind : uint8_t { + Unknown, + + Module, + Namespace, + NamespaceAlias, + Macro, + + Enum, + Struct, + Class, + Protocol, + Extension, + Union, + TypeAlias, + + Function, + Variable, + Field, + EnumConstant, + + InstanceMethod, + ClassMethod, + StaticMethod, + InstanceProperty, + ClassProperty, + StaticProperty, + + Constructor, + Destructor, + ConversionFunction, +}; + +enum class SymbolLanguage { + C, + ObjC, + CXX, +}; + +enum class SymbolSubKind : uint8_t { + Generic = 1 << 0, + TemplatePartialSpecialization = 1 << 1, + TemplateSpecialization = 1 << 2, + UnitTest = 1 << 3, + IBAnnotated = 1 << 4, + IBOutletCollection = 1 << 5, +}; +static const unsigned SymbolSubKindBitNum = 6; +typedef unsigned SymbolSubKindSet; + +/// Set of roles that are attributed to symbol occurrences. +enum class SymbolRole : uint16_t { + Declaration = 1 << 0, + Definition = 1 << 1, + Reference = 1 << 2, + Read = 1 << 3, + Write = 1 << 4, + Call = 1 << 5, + Dynamic = 1 << 6, + AddressOf = 1 << 7, + Implicit = 1 << 8, + + // Relation roles. + RelationChildOf = 1 << 9, + RelationBaseOf = 1 << 10, + RelationOverrideOf = 1 << 11, + RelationReceivedBy = 1 << 12, + RelationCalledBy = 1 << 13, +}; +static const unsigned SymbolRoleBitNum = 14; +typedef unsigned SymbolRoleSet; + +/// Represents a relation to another symbol for a symbol occurrence. +struct SymbolRelation { + SymbolRoleSet Roles; + const Decl *RelatedSymbol; + + SymbolRelation(SymbolRoleSet Roles, const Decl *Sym) + : Roles(Roles), RelatedSymbol(Sym) {} +}; + +struct SymbolInfo { + SymbolKind Kind; + SymbolSubKindSet SubKinds; + SymbolLanguage Lang; +}; + +SymbolInfo getSymbolInfo(const Decl *D); + +void applyForEachSymbolRole(SymbolRoleSet Roles, + llvm::function_ref<void(SymbolRole)> Fn); +void printSymbolRoles(SymbolRoleSet Roles, raw_ostream &OS); + +/// \returns true if no name was printed, false otherwise. +bool printSymbolName(const Decl *D, const LangOptions &LO, raw_ostream &OS); + +StringRef getSymbolKindString(SymbolKind K); +StringRef getSymbolLanguageString(SymbolLanguage K); + +void applyForEachSymbolSubKind(SymbolSubKindSet SubKinds, + llvm::function_ref<void(SymbolSubKind)> Fn); +void printSymbolSubKinds(SymbolSubKindSet SubKinds, raw_ostream &OS); + +} // namespace index +} // namespace clang + +#endif diff --git a/include/clang/Index/IndexingAction.h b/include/clang/Index/IndexingAction.h new file mode 100644 index 0000000000000..e2e63dc6357d2 --- /dev/null +++ b/include/clang/Index/IndexingAction.h @@ -0,0 +1,48 @@ +//===--- IndexingAction.h - Frontend index action -------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_INDEX_INDEXINGACTION_H +#define LLVM_CLANG_INDEX_INDEXINGACTION_H + +#include "clang/Basic/LLVM.h" +#include <memory> + +namespace clang { + class ASTUnit; + class FrontendAction; + +namespace index { + class IndexDataConsumer; + +struct IndexingOptions { + enum class SystemSymbolFilterKind { + None, + DeclarationsOnly, + All, + }; + + SystemSymbolFilterKind SystemSymbolFilter + = SystemSymbolFilterKind::DeclarationsOnly; + bool IndexFunctionLocals = false; +}; + +/// \param WrappedAction another frontend action to wrap over or null. +std::unique_ptr<FrontendAction> +createIndexingAction(std::shared_ptr<IndexDataConsumer> DataConsumer, + IndexingOptions Opts, + std::unique_ptr<FrontendAction> WrappedAction); + +void indexASTUnit(ASTUnit &Unit, + std::shared_ptr<IndexDataConsumer> DataConsumer, + IndexingOptions Opts); + +} // namespace index +} // namespace clang + +#endif diff --git a/include/clang/Index/USRGeneration.h b/include/clang/Index/USRGeneration.h index 55e35cc6d9b6f..be89068469c4d 100644 --- a/include/clang/Index/USRGeneration.h +++ b/include/clang/Index/USRGeneration.h @@ -44,7 +44,7 @@ void generateUSRForObjCMethod(StringRef Sel, bool IsInstanceMethod, raw_ostream &OS); /// \brief Generate a USR fragment for an Objective-C property. -void generateUSRForObjCProperty(StringRef Prop, raw_ostream &OS); +void generateUSRForObjCProperty(StringRef Prop, bool isClassProp, raw_ostream &OS); /// \brief Generate a USR fragment for an Objective-C protocol. void generateUSRForObjCProtocol(StringRef Prot, raw_ostream &OS); diff --git a/include/clang/Lex/DirectoryLookup.h b/include/clang/Lex/DirectoryLookup.h index 20c4bb03ab6e6..ee0af292e6fcc 100644 --- a/include/clang/Lex/DirectoryLookup.h +++ b/include/clang/Lex/DirectoryLookup.h @@ -151,6 +151,9 @@ public: /// /// \param HS The header search instance to search with. /// + /// \param IncludeLoc the source location of the #include or #import + /// directive. + /// /// \param SearchPath If not NULL, will be set to the search path relative /// to which the file was found. /// @@ -172,6 +175,7 @@ public: /// a framework include ("Foo.h" -> "Foo/Foo.h"), set the new name to this /// vector and point Filename to it. const FileEntry *LookupFile(StringRef &Filename, HeaderSearch &HS, + SourceLocation IncludeLoc, SmallVectorImpl<char> *SearchPath, SmallVectorImpl<char> *RelativePath, Module *RequestingModule, diff --git a/include/clang/Lex/HeaderMap.h b/include/clang/Lex/HeaderMap.h index 183361e4f8c0c..8466f1a24d52d 100644 --- a/include/clang/Lex/HeaderMap.h +++ b/include/clang/Lex/HeaderMap.h @@ -15,60 +15,74 @@ #define LLVM_CLANG_LEX_HEADERMAP_H #include "clang/Basic/LLVM.h" +#include "llvm/ADT/Optional.h" #include "llvm/Support/Compiler.h" +#include "llvm/Support/MemoryBuffer.h" #include <memory> -namespace llvm { - class MemoryBuffer; -} namespace clang { - class FileEntry; - class FileManager; - struct HMapBucket; - struct HMapHeader; -/// This class represents an Apple concept known as a 'header map'. To the -/// \#include file resolution process, it basically acts like a directory of -/// symlinks to files. Its advantages are that it is dense and more efficient -/// to create and process than a directory of symlinks. -class HeaderMap { - HeaderMap(const HeaderMap &) = delete; - void operator=(const HeaderMap &) = delete; +class FileEntry; +class FileManager; +struct HMapBucket; +struct HMapHeader; +/// Implementation for \a HeaderMap that doesn't depend on \a FileManager. +class HeaderMapImpl { std::unique_ptr<const llvm::MemoryBuffer> FileBuffer; bool NeedsBSwap; - HeaderMap(std::unique_ptr<const llvm::MemoryBuffer> File, bool BSwap) - : FileBuffer(std::move(File)), NeedsBSwap(BSwap) {} public: - /// HeaderMap::Create - This attempts to load the specified file as a header - /// map. If it doesn't look like a HeaderMap, it gives up and returns null. - static const HeaderMap *Create(const FileEntry *FE, FileManager &FM); + HeaderMapImpl(std::unique_ptr<const llvm::MemoryBuffer> File, bool NeedsBSwap) + : FileBuffer(std::move(File)), NeedsBSwap(NeedsBSwap) {} - /// LookupFile - Check to see if the specified relative filename is located in - /// this HeaderMap. If so, open it and return its FileEntry. - /// If RawPath is not NULL and the file is found, RawPath will be set to the - /// raw path at which the file was found in the file system. For example, - /// for a search path ".." and a filename "../file.h" this would be - /// "../../file.h". - const FileEntry *LookupFile(StringRef Filename, FileManager &FM) const; + // Check for a valid header and extract the byte swap. + static bool checkHeader(const llvm::MemoryBuffer &File, bool &NeedsByteSwap); /// If the specified relative filename is located in this HeaderMap return /// the filename it is mapped to, otherwise return an empty StringRef. StringRef lookupFilename(StringRef Filename, SmallVectorImpl<char> &DestPath) const; - /// getFileName - Return the filename of the headermap. + /// Return the filename of the headermap. const char *getFileName() const; - /// dump - Print the contents of this headermap to stderr. + /// Print the contents of this headermap to stderr. void dump() const; private: unsigned getEndianAdjustedWord(unsigned X) const; const HMapHeader &getHeader() const; HMapBucket getBucket(unsigned BucketNo) const; - const char *getString(unsigned StrTabIdx) const; + + /// Look up the specified string in the string table. If the string index is + /// not valid, return None. + Optional<StringRef> getString(unsigned StrTabIdx) const; +}; + +/// This class represents an Apple concept known as a 'header map'. To the +/// \#include file resolution process, it basically acts like a directory of +/// symlinks to files. Its advantages are that it is dense and more efficient +/// to create and process than a directory of symlinks. +class HeaderMap : private HeaderMapImpl { + HeaderMap(std::unique_ptr<const llvm::MemoryBuffer> File, bool BSwap) + : HeaderMapImpl(std::move(File), BSwap) {} + +public: + /// This attempts to load the specified file as a header map. If it doesn't + /// look like a HeaderMap, it gives up and returns null. + static const HeaderMap *Create(const FileEntry *FE, FileManager &FM); + + /// Check to see if the specified relative filename is located in this + /// HeaderMap. If so, open it and return its FileEntry. If RawPath is not + /// NULL and the file is found, RawPath will be set to the raw path at which + /// the file was found in the file system. For example, for a search path + /// ".." and a filename "../file.h" this would be "../../file.h". + const FileEntry *LookupFile(StringRef Filename, FileManager &FM) const; + + using HeaderMapImpl::lookupFilename; + using HeaderMapImpl::getFileName; + using HeaderMapImpl::dump; }; } // end namespace clang. diff --git a/include/clang/Lex/HeaderMapTypes.h b/include/clang/Lex/HeaderMapTypes.h new file mode 100644 index 0000000000000..fbaf4baee4077 --- /dev/null +++ b/include/clang/Lex/HeaderMapTypes.h @@ -0,0 +1,43 @@ +//===- HeaderMapTypes.h - Types for the header map format -------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_LEX_HEADERMAPTYPES_H +#define LLVM_CLANG_LEX_HEADERMAPTYPES_H + +#include <cstdint> + +namespace clang { + +enum { + HMAP_HeaderMagicNumber = ('h' << 24) | ('m' << 16) | ('a' << 8) | 'p', + HMAP_HeaderVersion = 1, + HMAP_EmptyBucketKey = 0 +}; + +struct HMapBucket { + uint32_t Key; // Offset (into strings) of key. + uint32_t Prefix; // Offset (into strings) of value prefix. + uint32_t Suffix; // Offset (into strings) of value suffix. +}; + +struct HMapHeader { + uint32_t Magic; // Magic word, also indicates byte order. + uint16_t Version; // Version number -- currently 1. + uint16_t Reserved; // Reserved for future use - zero for now. + uint32_t StringsOffset; // Offset to start of string pool. + uint32_t NumEntries; // Number of entries in the string table. + uint32_t NumBuckets; // Number of buckets (always a power of 2). + uint32_t MaxValueLength; // Length of longest result path (excluding nul). + // An array of 'NumBuckets' HMapBucket objects follows this header. + // Strings follow the buckets, at StringsOffset. +}; + +} // end namespace clang. + +#endif diff --git a/include/clang/Lex/HeaderSearch.h b/include/clang/Lex/HeaderSearch.h index 6d592e19c0682..7bac01ef3a4ce 100644 --- a/include/clang/Lex/HeaderSearch.h +++ b/include/clang/Lex/HeaderSearch.h @@ -241,8 +241,6 @@ class HeaderSearch { unsigned NumMultiIncludeFileOptzn; unsigned NumFrameworkLookups, NumSubFrameworkLookups; - const LangOptions &LangOpts; - // HeaderSearch doesn't support default or copy construction. HeaderSearch(const HeaderSearch&) = delete; void operator=(const HeaderSearch&) = delete; @@ -383,7 +381,7 @@ public: ArrayRef<std::pair<const FileEntry *, const DirectoryEntry *>> Includers, SmallVectorImpl<char> *SearchPath, SmallVectorImpl<char> *RelativePath, Module *RequestingModule, ModuleMap::KnownHeader *SuggestedModule, - bool SkipCache = false); + bool SkipCache = false, bool BuildSystemModule = false); /// \brief Look up a subframework for the specified \#include file. /// @@ -582,8 +580,9 @@ private: /// \brief Look up the file with the specified name and determine its owning /// module. const FileEntry * - getFileAndSuggestModule(StringRef FileName, const DirectoryEntry *Dir, - bool IsSystemHeaderDir, Module *RequestingModule, + getFileAndSuggestModule(StringRef FileName, SourceLocation IncludeLoc, + const DirectoryEntry *Dir, bool IsSystemHeaderDir, + Module *RequestingModule, ModuleMap::KnownHeader *SuggestedModule); public: @@ -634,13 +633,18 @@ public: /// \brief Retrieve a uniqued framework name. StringRef getUniqueFrameworkName(StringRef Framework); + /// \brief Suggest a path by which the specified file could be found, for + /// use in diagnostics to suggest a #include. + /// + /// \param IsSystem If non-null, filled in to indicate whether the suggested + /// path is relative to a system header directory. + std::string suggestPathToFileForDiagnostics(const FileEntry *File, + bool *IsSystem = nullptr); + void PrintStats(); size_t getTotalMemory() const; - static std::string NormalizeDashIncludePath(StringRef File, - FileManager &FileMgr); - private: /// \brief Describes what happened when we tried to load a module map file. enum LoadModuleMapResult { diff --git a/include/clang/Lex/Lexer.h b/include/clang/Lex/Lexer.h index 12565d0b14b63..830c25a2e4d29 100644 --- a/include/clang/Lex/Lexer.h +++ b/include/clang/Lex/Lexer.h @@ -410,6 +410,26 @@ public: const SourceManager &SM, const LangOptions &LangOpts); + /// \brief Retrieve the name of the immediate macro expansion. + /// + /// This routine starts from a source location, and finds the name of the + /// macro responsible for its immediate expansion. It looks through any + /// intervening macro argument expansions to compute this. It returns a + /// StringRef which refers to the SourceManager-owned buffer of the source + /// where that macro name is spelled. Thus, the result shouldn't out-live + /// that SourceManager. + /// + /// This differs from Lexer::getImmediateMacroName in that any macro argument + /// location will result in the topmost function macro that accepted it. + /// e.g. + /// \code + /// MAC1( MAC2(foo) ) + /// \endcode + /// for location of 'foo' token, this function will return "MAC1" while + /// Lexer::getImmediateMacroName will return "MAC2". + static StringRef getImmediateMacroNameForDiagnostics( + SourceLocation Loc, const SourceManager &SM, const LangOptions &LangOpts); + /// \brief Compute the preamble of the given file. /// /// The preamble of a file contains the initial comments, include directives, diff --git a/include/clang/Lex/LiteralSupport.h b/include/clang/Lex/LiteralSupport.h index d568614e2ae4e..5f946fc8337e5 100644 --- a/include/clang/Lex/LiteralSupport.h +++ b/include/clang/Lex/LiteralSupport.h @@ -19,6 +19,7 @@ #include "clang/Basic/LLVM.h" #include "clang/Basic/TokenKinds.h" #include "llvm/ADT/APFloat.h" +#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/DataTypes.h" @@ -61,8 +62,10 @@ public: bool isUnsigned : 1; bool isLong : 1; // This is *not* set for long long. bool isLongLong : 1; + bool isHalf : 1; // 1.0h bool isFloat : 1; // 1.0f bool isImaginary : 1; // 1.0i + bool isFloat128 : 1; // 1.0q uint8_t MicrosoftInteger; // Microsoft suffix extension i8, i16, i32, or i64. bool isIntegerLiteral() const { @@ -104,9 +107,16 @@ public: private: void ParseNumberStartingWithZero(SourceLocation TokLoc); + void ParseDecimalOrOctalCommon(SourceLocation TokLoc); static bool isDigitSeparator(char C) { return C == '\''; } + /// \brief Determine whether the sequence of characters [Start, End) contains + /// any real digits (not digit separators). + bool containsDigits(const char *Start, const char *End) { + return Start != End && (Start + 1 != End || !isDigitSeparator(Start[0])); + } + enum CheckSeparatorKind { CSK_BeforeDigits, CSK_AfterDigits }; /// \brief Ensure that we don't have a digit separator here. diff --git a/include/clang/Lex/MacroArgs.h b/include/clang/Lex/MacroArgs.h index 243b143f7af6e..7b2a48561ff63 100644 --- a/include/clang/Lex/MacroArgs.h +++ b/include/clang/Lex/MacroArgs.h @@ -15,13 +15,13 @@ #define LLVM_CLANG_LEX_MACROARGS_H #include "clang/Basic/LLVM.h" +#include "clang/Lex/Token.h" #include "llvm/ADT/ArrayRef.h" #include <vector> namespace clang { class MacroInfo; class Preprocessor; - class Token; class SourceLocation; /// MacroArgs - An instance of this class captures information about diff --git a/include/clang/Lex/MacroInfo.h b/include/clang/Lex/MacroInfo.h index 320645e2380c9..6cc3b0bb26f2c 100644 --- a/include/clang/Lex/MacroInfo.h +++ b/include/clang/Lex/MacroInfo.h @@ -106,7 +106,7 @@ class MacroInfo { bool IsWarnIfUnused : 1; /// \brief Whether this macro info was loaded from an AST file. - unsigned FromASTFile : 1; + bool FromASTFile : 1; /// \brief Whether this macro was used as header guard. bool UsedForHeaderGuard : 1; @@ -318,13 +318,13 @@ protected: unsigned MDKind : 2; /// \brief True if the macro directive was loaded from a PCH file. - bool IsFromPCH : 1; + unsigned IsFromPCH : 1; // Used by VisibilityMacroDirective ----------------------------------------// /// \brief Whether the macro has public visibility (when described in a /// module). - bool IsPublic : 1; + unsigned IsPublic : 1; MacroDirective(Kind K, SourceLocation Loc) : Previous(nullptr), Loc(Loc), MDKind(K), IsFromPCH(false), diff --git a/include/clang/Lex/ModuleMap.h b/include/clang/Lex/ModuleMap.h index 155943e5453c8..1e86f736983f6 100644 --- a/include/clang/Lex/ModuleMap.h +++ b/include/clang/Lex/ModuleMap.h @@ -50,6 +50,18 @@ public: /// \param IsSystem Whether this is a module map from a system include path. virtual void moduleMapFileRead(SourceLocation FileStart, const FileEntry &File, bool IsSystem) {} + + /// \brief Called when a header is added during module map parsing. + /// + /// \param Filename The header file itself. + virtual void moduleMapAddHeader(StringRef Filename) {} + + /// \brief Called when an umbrella header is added during module map parsing. + /// + /// \param FileMgr FileManager instance + /// \param Header The umbrella header to collect. + virtual void moduleMapAddUmbrellaHeader(FileManager *FileMgr, + const FileEntry *Header) {} }; class ModuleMap { @@ -70,15 +82,10 @@ class ModuleMap { /// These are always simple C language options. LangOptions MMapLangOpts; - // The module that we are building; related to \c LangOptions::CurrentModule. - Module *CompilingModule; - -public: - // The module that the .cc source file is associated with. + // The module that the main source file is associated with (the module + // named LangOpts::CurrentModule, if we've loaded it). Module *SourceModule; - std::string SourceModuleName; -private: /// \brief The top-level modules that are known. llvm::StringMap<Module *> Modules; @@ -130,6 +137,12 @@ public: return getModule()->isAvailable(); } + /// \brief Whether this header is accessible from the specified module. + bool isAccessibleFrom(Module *M) const { + return !(getRole() & PrivateHeader) || + (M && M->getTopLevelModule() == getModule()->getTopLevelModule()); + } + // \brief Whether this known header is valid (i.e., it has an // associated module). explicit operator bool() const { @@ -318,12 +331,18 @@ public: /// /// \param RequestingModule The module including a file. /// + /// \param RequestingModuleIsModuleInterface \c true if the inclusion is in + /// the interface of RequestingModule, \c false if it's in the + /// implementation of RequestingModule. Value is ignored and + /// meaningless if RequestingModule is nullptr. + /// /// \param FilenameLoc The location of the inclusion's filename. /// /// \param Filename The included filename as written. /// /// \param File The included file. void diagnoseHeaderInclusion(Module *RequestingModule, + bool RequestingModuleIsModuleInterface, SourceLocation FilenameLoc, StringRef Filename, const FileEntry *File); diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h index f6154b6a49cdf..30cc37f6f884f 100644 --- a/include/clang/Lex/Preprocessor.h +++ b/include/clang/Lex/Preprocessor.h @@ -32,6 +32,7 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/TinyPtrVector.h" #include "llvm/Support/Allocator.h" +#include "llvm/Support/Registry.h" #include <memory> #include <vector> @@ -507,9 +508,10 @@ class Preprocessor : public RefCountedBase<Preprocessor> { /// \brief Information about a submodule that we're currently building. struct BuildingSubmoduleInfo { BuildingSubmoduleInfo(Module *M, SourceLocation ImportLoc, - SubmoduleState *OuterSubmoduleState) - : M(M), ImportLoc(ImportLoc), OuterSubmoduleState(OuterSubmoduleState) { - } + SubmoduleState *OuterSubmoduleState, + unsigned OuterPendingModuleMacroNames) + : M(M), ImportLoc(ImportLoc), OuterSubmoduleState(OuterSubmoduleState), + OuterPendingModuleMacroNames(OuterPendingModuleMacroNames) {} /// The module that we are building. Module *M; @@ -517,6 +519,8 @@ class Preprocessor : public RefCountedBase<Preprocessor> { SourceLocation ImportLoc; /// The previous SubmoduleState. SubmoduleState *OuterSubmoduleState; + /// The number of pending module macro names when we started building this. + unsigned OuterPendingModuleMacroNames; }; SmallVector<BuildingSubmoduleInfo, 8> BuildingSubmoduleStack; @@ -541,6 +545,9 @@ class Preprocessor : public RefCountedBase<Preprocessor> { /// The set of known macros exported from modules. llvm::FoldingSet<ModuleMacro> ModuleMacros; + /// The names of potential module macros that we've not yet processed. + llvm::SmallVector<const IdentifierInfo*, 32> PendingModuleMacroNames; + /// The list of module macros, for each identifier, that are not overridden by /// any other module macro. llvm::DenseMap<const IdentifierInfo *, llvm::TinyPtrVector<ModuleMacro*>> @@ -1018,10 +1025,20 @@ public: /// If \p OwnsTokens is false, this method assumes that the specified stream /// of tokens has a permanent owner somewhere, so they do not need to be /// copied. If it is true, it assumes the array of tokens is allocated with - /// \c new[] and must be freed. + /// \c new[] and the Preprocessor will delete[] it. +private: void EnterTokenStream(const Token *Toks, unsigned NumToks, bool DisableMacroExpansion, bool OwnsTokens); +public: + void EnterTokenStream(std::unique_ptr<Token[]> Toks, unsigned NumToks, + bool DisableMacroExpansion) { + EnterTokenStream(Toks.release(), NumToks, DisableMacroExpansion, true); + } + void EnterTokenStream(ArrayRef<Token> Toks, bool DisableMacroExpansion) { + EnterTokenStream(Toks.data(), Toks.size(), DisableMacroExpansion, false); + } + /// \brief Pop the current lexer/macro exp off the top of the lexer stack. /// /// This should only be used in situations where the current state of the @@ -1185,6 +1202,17 @@ public: return CachedTokens[CachedLexPos-1].getLastLoc(); } + /// \brief Whether \p Tok is the most recent token (`CachedLexPos - 1`) in + /// CachedTokens. + bool IsPreviousCachedToken(const Token &Tok) const; + + /// \brief Replace token in `CachedLexPos - 1` in CachedTokens by the tokens + /// in \p NewToks. + /// + /// Useful when a token needs to be split in smaller ones and CachedTokens + /// most recent token must to be updated to reflect that. + void ReplacePreviousCachedToken(ArrayRef<Token> NewToks); + /// \brief Replace the last token with an annotation token. /// /// Like AnnotateCachedTokens(), this routine replaces an @@ -1683,6 +1711,10 @@ private: void EnterSubmodule(Module *M, SourceLocation ImportLoc); void LeaveSubmodule(); + /// Determine whether we need to create module macros for #defines in the + /// current context. + bool needModuleMacros() const; + /// Update the set of active module macros and ambiguity flag for a module /// macro name. void updateModuleMacroInfo(const IdentifierInfo *II, ModuleMacroInfo &Info); @@ -1859,6 +1891,19 @@ public: /// directly or indirectly. Module *getModuleContainingLocation(SourceLocation Loc); + /// \brief We want to produce a diagnostic at location IncLoc concerning a + /// missing module import. + /// + /// \param IncLoc The location at which the missing import was detected. + /// \param MLoc A location within the desired module at which some desired + /// effect occurred (eg, where a desired entity was declared). + /// + /// \return A file that can be #included to import a module containing MLoc. + /// Null if no such file could be determined or if a #include is not + /// appropriate. + const FileEntry *getModuleHeaderToIncludeForDiagnostics(SourceLocation IncLoc, + SourceLocation MLoc); + private: // Macro handling. void HandleDefineDirective(Token &Tok, bool ImmediatelyAfterTopLevelIfndef); @@ -1906,6 +1951,11 @@ public: virtual bool HandleComment(Preprocessor &PP, SourceRange Comment) = 0; }; +/// \brief Registry of pragma handlers added by plugins +typedef llvm::Registry<PragmaHandler> PragmaHandlerRegistry; + } // end namespace clang +extern template class llvm::Registry<clang::PragmaHandler>; + #endif diff --git a/include/clang/Lex/Token.h b/include/clang/Lex/Token.h index 7ba22b2f626c6..4393e205ffaf5 100644 --- a/include/clang/Lex/Token.h +++ b/include/clang/Lex/Token.h @@ -14,12 +14,10 @@ #ifndef LLVM_CLANG_LEX_TOKEN_H #define LLVM_CLANG_LEX_TOKEN_H -#include "clang/Basic/OperatorKinds.h" #include "clang/Basic/SourceLocation.h" -#include "clang/Basic/TemplateKinds.h" #include "clang/Basic/TokenKinds.h" #include "llvm/ADT/StringRef.h" -#include <cstdlib> +#include <cassert> namespace clang { @@ -69,8 +67,8 @@ class Token { /// Flags - Bits we track about this token, members of the TokenFlags enum. unsigned short Flags; -public: +public: // Various flags set per token: enum TokenFlags { StartOfLine = 0x01, // At start of line or only after whitespace @@ -85,6 +83,7 @@ public: IgnoredComma = 0x80, // This comma is not a macro argument separator (MS). StringifiedInMacro = 0x100, // This string or character literal is formed by // macro stringizing or charizing operator. + CommaAfterElided = 0x200, // The comma following this token was elided (MS). }; tok::TokenKind getKind() const { return Kind; } @@ -235,6 +234,11 @@ public: Flags |= Flag; } + /// \brief Get the specified flag. + bool getFlag(TokenFlags Flag) const { + return (Flags & Flag) != 0; + } + /// \brief Unset the specified flag. void clearFlag(TokenFlags Flag) { Flags &= ~Flag; @@ -258,17 +262,15 @@ public: /// isAtStartOfLine - Return true if this token is at the start of a line. /// - bool isAtStartOfLine() const { return (Flags & StartOfLine) ? true : false; } + bool isAtStartOfLine() const { return getFlag(StartOfLine); } /// \brief Return true if this token has whitespace before it. /// - bool hasLeadingSpace() const { return (Flags & LeadingSpace) ? true : false; } + bool hasLeadingSpace() const { return getFlag(LeadingSpace); } /// \brief Return true if this identifier token should never /// be expanded in the future, due to C99 6.10.3.4p2. - bool isExpandDisabled() const { - return (Flags & DisableExpand) ? true : false; - } + bool isExpandDisabled() const { return getFlag(DisableExpand); } /// \brief Return true if we have an ObjC keyword identifier. bool isObjCAtKeyword(tok::ObjCKeywordKind objcKey) const; @@ -277,26 +279,25 @@ public: tok::ObjCKeywordKind getObjCKeywordID() const; /// \brief Return true if this token has trigraphs or escaped newlines in it. - bool needsCleaning() const { return (Flags & NeedsCleaning) ? true : false; } + bool needsCleaning() const { return getFlag(NeedsCleaning); } /// \brief Return true if this token has an empty macro before it. /// - bool hasLeadingEmptyMacro() const { - return (Flags & LeadingEmptyMacro) ? true : false; - } + bool hasLeadingEmptyMacro() const { return getFlag(LeadingEmptyMacro); } /// \brief Return true if this token is a string or character literal which /// has a ud-suffix. - bool hasUDSuffix() const { return (Flags & HasUDSuffix) ? true : false; } + bool hasUDSuffix() const { return getFlag(HasUDSuffix); } /// Returns true if this token contains a universal character name. - bool hasUCN() const { return (Flags & HasUCN) ? true : false; } + bool hasUCN() const { return getFlag(HasUCN); } /// Returns true if this token is formed by macro by stringizing or charizing /// operator. - bool stringifiedInMacro() const { - return (Flags & StringifiedInMacro) ? true : false; - } + bool stringifiedInMacro() const { return getFlag(StringifiedInMacro); } + + /// Returns true if the comma after this token was elided. + bool commaAfterElided() const { return getFlag(CommaAfterElided); } }; /// \brief Information about the conditional stack (\#if directives) @@ -318,11 +319,11 @@ struct PPConditionalInfo { bool FoundElse; }; -} // end namespace clang +} // end namespace clang namespace llvm { template <> struct isPodLike<clang::Token> { static const bool value = true; }; -} // end namespace llvm +} // end namespace llvm -#endif +#endif // LLVM_CLANG_LEX_TOKEN_H diff --git a/include/clang/Makefile b/include/clang/Makefile deleted file mode 100644 index 5ba2dd2991b82..0000000000000 --- a/include/clang/Makefile +++ /dev/null @@ -1,44 +0,0 @@ -CLANG_LEVEL := ../.. -DIRS := AST Basic Driver Parse Sema Serialization - -include $(CLANG_LEVEL)/Makefile - -install-local:: - $(Echo) Installing Clang include files - $(Verb) $(MKDIR) $(DESTDIR)$(PROJ_includedir) - $(Verb) if test -d "$(PROJ_SRC_DIR)" ; then \ - cd $(PROJ_SRC_DIR)/.. && \ - for hdr in `find clang -type f \ - '(' -name LICENSE.TXT \ - -o -name '*.def' \ - -o -name '*.h' \ - -o -name '*.inc' \ - ')' -print \ - | grep -v CVS | grep -v .svn | grep -v .dir` ; do \ - instdir=$(DESTDIR)`dirname "$(PROJ_includedir)/$$hdr"` ; \ - if test \! -d "$$instdir" ; then \ - $(EchoCmd) Making install directory $$instdir ; \ - $(MKDIR) $$instdir ;\ - fi ; \ - $(DataInstall) $$hdr $(DESTDIR)$(PROJ_includedir)/$$hdr ; \ - done ; \ - fi -ifneq ($(PROJ_SRC_ROOT),$(PROJ_OBJ_ROOT)) - $(Verb) if test -d "$(PROJ_OBJ_ROOT)/tools/clang/include/clang" ; then \ - cd $(PROJ_OBJ_ROOT)/tools/clang/include && \ - for hdr in `find clang -type f \ - '(' -name LICENSE.TXT \ - -o -name '*.def' \ - -o -name '*.h' \ - -o -name '*.inc' \ - ')' -print \ - | grep -v CVS | grep -v .tmp | grep -v .dir` ; do \ - instdir=$(DESTDIR)`dirname "$(PROJ_includedir)/$$hdr"` ; \ - if test \! -d "$$instdir" ; then \ - $(EchoCmd) Making install directory $$instdir ; \ - $(MKDIR) $$instdir ;\ - fi ; \ - $(DataInstall) $$hdr $(DESTDIR)$(PROJ_includedir)/$$hdr ; \ - done ; \ - fi -endif diff --git a/include/clang/Parse/Makefile b/include/clang/Parse/Makefile deleted file mode 100644 index c4770190562d0..0000000000000 --- a/include/clang/Parse/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -CLANG_LEVEL := ../../.. -TD_SRC_DIR = $(PROJ_SRC_DIR)/../Basic -BUILT_SOURCES = AttrParserStringSwitches.inc - -TABLEGEN_INC_FILES_COMMON = 1 - -include $(CLANG_LEVEL)/Makefile - -$(ObjDir)/AttrParserStringSwitches.inc.tmp : $(TD_SRC_DIR)/Attr.td $(CLANG_TBLGEN) \ - $(ObjDir)/.dir - $(Echo) "Building Clang parser-related attribute string switches" - $(Verb) $(ClangTableGen) -gen-clang-attr-parser-string-switches -o $(call SYSPATH, $@) \ - -I $(PROJ_SRC_DIR)/../../ $< diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h index 00885a5c71031..5838a447c3b91 100644 --- a/include/clang/Parse/Parser.h +++ b/include/clang/Parse/Parser.h @@ -14,6 +14,7 @@ #ifndef LLVM_CLANG_PARSE_PARSER_H #define LLVM_CLANG_PARSE_PARSER_H +#include "clang/AST/Availability.h" #include "clang/Basic/OpenMPKinds.h" #include "clang/Basic/OperatorPrecedence.h" #include "clang/Basic/Specifiers.h" @@ -134,6 +135,12 @@ class Parser : public CodeCompletionHandler { /// \brief Identifier for "message". IdentifierInfo *Ident_message; + /// \brief Identifier for "strict". + IdentifierInfo *Ident_strict; + + /// \brief Identifier for "replacement". + IdentifierInfo *Ident_replacement; + /// C++0x contextual keywords. mutable IdentifierInfo *Ident_final; mutable IdentifierInfo *Ident_override; @@ -641,6 +648,8 @@ private: /// Should only be used in Objective-C language modes. bool isObjCInstancetype() { assert(getLangOpts().ObjC1); + if (Tok.isAnnotation()) + return false; if (!Ident_instancetype) Ident_instancetype = PP.getIdentifierInfo("instancetype"); return Tok.getIdentifierInfo() == Ident_instancetype; @@ -707,6 +716,16 @@ private: assert(!isActive && "Forgot to call Commit or Revert!"); } }; + /// A TentativeParsingAction that automatically reverts in its destructor. + /// Useful for disambiguation parses that will always be reverted. + class RevertingTentativeParsingAction + : private Parser::TentativeParsingAction { + public: + RevertingTentativeParsingAction(Parser &P) + : Parser::TentativeParsingAction(P) {} + ~RevertingTentativeParsingAction() { Revert(); } + }; + class UnannotatedTentativeParsingAction; /// ObjCDeclContextSwitch - An object used to switch context from @@ -1580,8 +1599,9 @@ private: //===--------------------------------------------------------------------===// // C++ if/switch/while condition expression. - bool ParseCXXCondition(ExprResult &ExprResult, Decl *&DeclResult, - SourceLocation Loc, bool ConvertToBoolean); + Sema::ConditionResult ParseCXXCondition(StmtResult *InitStmt, + SourceLocation Loc, + Sema::ConditionKind CK); //===--------------------------------------------------------------------===// // C++ Coroutines @@ -1672,10 +1692,10 @@ private: unsigned ScopeFlags); void ParseCompoundStatementLeadingPragmas(); StmtResult ParseCompoundStatementBody(bool isStmtExpr = false); - bool ParseParenExprOrCondition(ExprResult &ExprResult, - Decl *&DeclResult, + bool ParseParenExprOrCondition(StmtResult *InitStmt, + Sema::ConditionResult &CondResult, SourceLocation Loc, - bool ConvertToBoolean); + Sema::ConditionKind CK); StmtResult ParseIfStatement(SourceLocation *TrailingElseLoc); StmtResult ParseSwitchStatement(SourceLocation *TrailingElseLoc); StmtResult ParseWhileStatement(SourceLocation *TrailingElseLoc); @@ -1867,7 +1887,6 @@ private: bool isDeclarationSpecifier(bool DisambiguatingWithExpression = false); bool isTypeSpecifierQualifier(); - bool isTypeQualifier() const; /// isKnownToBeTypeSpecifier - Return true if we know that the specified token /// is definitely a type-specifier. Return false if it isn't part of a type @@ -1968,11 +1987,18 @@ private: /// the function returns true to let the declaration parsing code handle it. bool isCXXFunctionDeclarator(bool *IsAmbiguous = nullptr); - /// isCXXConditionDeclaration - Disambiguates between a declaration or an - /// expression for a condition of a if/switch/while/for statement. - /// If during the disambiguation process a parsing error is encountered, - /// the function returns true to let the declaration parsing code handle it. - bool isCXXConditionDeclaration(); + struct ConditionDeclarationOrInitStatementState; + enum class ConditionOrInitStatement { + Expression, ///< Disambiguated as an expression (either kind). + ConditionDecl, ///< Disambiguated as the declaration form of condition. + InitStmtDecl, ///< Disambiguated as a simple-declaration init-statement. + Error ///< Can't be any of the above! + }; + /// \brief Disambiguates between the different kinds of things that can happen + /// after 'if (' or 'switch ('. This could be one of two different kinds of + /// declaration (depending on whether there is a ';' later) or an expression. + ConditionOrInitStatement + isCXXConditionDeclarationOrInitStatement(bool CanBeInitStmt); bool isCXXTypeId(TentativeCXXTypeIdContext Context, bool &isAmbiguous); bool isCXXTypeId(TentativeCXXTypeIdContext Context) { @@ -2195,8 +2221,19 @@ private: SourceLocation SkipExtendedMicrosoftTypeAttributes(); void ParseMicrosoftInheritanceClassAttributes(ParsedAttributes &attrs); void ParseBorlandTypeAttributes(ParsedAttributes &attrs); - void ParseOpenCLAttributes(ParsedAttributes &attrs); + void ParseOpenCLKernelAttributes(ParsedAttributes &attrs); void ParseOpenCLQualifiers(ParsedAttributes &Attrs); + /// \brief Parses opencl_unroll_hint attribute if language is OpenCL v2.0 + /// or higher. + /// \return false if error happens. + bool MaybeParseOpenCLUnrollHintAttribute(ParsedAttributes &Attrs) { + if (getLangOpts().OpenCL) + return ParseOpenCLUnrollHintAttribute(Attrs); + return true; + } + /// \brief Parses opencl_unroll_hint attribute. + /// \return false if error happens. + bool ParseOpenCLUnrollHintAttribute(ParsedAttributes &Attrs); void ParseNullabilityTypeSpecifiers(ParsedAttributes &attrs); VersionTuple ParseVersionTuple(SourceRange &Range); @@ -2208,6 +2245,9 @@ private: SourceLocation ScopeLoc, AttributeList::Syntax Syntax); + Optional<AvailabilitySpec> ParseAvailabilitySpec(); + ExprResult ParseAvailabilityCheckExpr(SourceLocation StartLoc); + void ParseObjCBridgeRelatedAttribute(IdentifierInfo &ObjCBridgeRelated, SourceLocation ObjCBridgeRelatedLoc, ParsedAttributes &attrs, @@ -2411,7 +2451,7 @@ private: ParsingDeclRAIIObject *DiagsFromTParams = nullptr); DeclGroupPtrTy ParseCXXClassMemberDeclarationWithPragmas( AccessSpecifier &AS, ParsedAttributesWithRange &AccessAttrs, - DeclSpec::TST TagType, Decl *TagDecl); + DeclSpec::TST TagType, Decl *Tag); void ParseConstructorInitializer(Decl *ConstructorDecl); MemInitResult ParseMemInitializer(Decl *ConstructorDecl); void HandleMemberFunctionDeclDelays(Declarator& DeclaratorInfo, @@ -2439,18 +2479,30 @@ private: //===--------------------------------------------------------------------===// // OpenMP: Directives and clauses. + /// Parse clauses for '#pragma omp declare simd'. + DeclGroupPtrTy ParseOMPDeclareSimdClauses(DeclGroupPtrTy Ptr, + CachedTokens &Toks, + SourceLocation Loc); /// \brief Parses declarative OpenMP directives. - DeclGroupPtrTy ParseOpenMPDeclarativeDirective(); + DeclGroupPtrTy ParseOpenMPDeclarativeDirectiveWithExtDecl( + AccessSpecifier &AS, ParsedAttributesWithRange &Attrs, + DeclSpec::TST TagType = DeclSpec::TST_unspecified, + Decl *TagDecl = nullptr); + /// \brief Parse 'omp declare reduction' construct. + DeclGroupPtrTy ParseOpenMPDeclareReductionDirective(AccessSpecifier AS); + /// \brief Parses simple list of variables. /// /// \param Kind Kind of the directive. - /// \param [out] VarList List of referenced variables. + /// \param Callback Callback function to be called for the list elements. /// \param AllowScopeSpecifier true, if the variables can have fully /// qualified names. /// - bool ParseOpenMPSimpleVarList(OpenMPDirectiveKind Kind, - SmallVectorImpl<Expr *> &VarList, - bool AllowScopeSpecifier); + bool ParseOpenMPSimpleVarList( + OpenMPDirectiveKind Kind, + const llvm::function_ref<void(CXXScopeSpec &, DeclarationNameInfo)> & + Callback, + bool AllowScopeSpecifier); /// \brief Parses declarative or executable directive. /// /// \param Allowed ACK_Any, if any directives are allowed, @@ -2498,6 +2550,29 @@ private: OpenMPClauseKind Kind); public: + /// Parses simple expression in parens for single-expression clauses of OpenMP + /// constructs. + /// \param RLoc Returned location of right paren. + ExprResult ParseOpenMPParensExpr(StringRef ClauseName, SourceLocation &RLoc); + + /// Data used for parsing list of variables in OpenMP clauses. + struct OpenMPVarListDataTy { + Expr *TailExpr = nullptr; + SourceLocation ColonLoc; + CXXScopeSpec ReductionIdScopeSpec; + DeclarationNameInfo ReductionId; + OpenMPDependClauseKind DepKind = OMPC_DEPEND_unknown; + OpenMPLinearClauseKind LinKind = OMPC_LINEAR_val; + OpenMPMapClauseKind MapTypeModifier = OMPC_MAP_unknown; + OpenMPMapClauseKind MapType = OMPC_MAP_unknown; + bool IsMapTypeImplicit = false; + SourceLocation DepLinMapLoc; + }; + + /// Parses clauses with list. + bool ParseOpenMPVarList(OpenMPDirectiveKind DKind, OpenMPClauseKind Kind, + SmallVectorImpl<Expr *> &Vars, + OpenMPVarListDataTy &Data); bool ParseUnqualifiedId(CXXScopeSpec &SS, bool EnteringContext, bool AllowDestructorName, bool AllowConstructorName, diff --git a/include/clang/Rewrite/Frontend/ASTConsumers.h b/include/clang/Rewrite/Frontend/ASTConsumers.h index c9df8895041d3..e054e75e95953 100644 --- a/include/clang/Rewrite/Frontend/ASTConsumers.h +++ b/include/clang/Rewrite/Frontend/ASTConsumers.h @@ -28,17 +28,18 @@ class Preprocessor; // ObjC rewriter: attempts to rewrite ObjC constructs into pure C code. // This is considered experimental, and only works with Apple's ObjC runtime. std::unique_ptr<ASTConsumer> -CreateObjCRewriter(const std::string &InFile, raw_ostream *OS, +CreateObjCRewriter(const std::string &InFile, std::unique_ptr<raw_ostream> OS, DiagnosticsEngine &Diags, const LangOptions &LOpts, bool SilenceRewriteMacroWarning); std::unique_ptr<ASTConsumer> -CreateModernObjCRewriter(const std::string &InFile, raw_ostream *OS, +CreateModernObjCRewriter(const std::string &InFile, + std::unique_ptr<raw_ostream> OS, DiagnosticsEngine &Diags, const LangOptions &LOpts, bool SilenceRewriteMacroWarning, bool LineInfo); /// CreateHTMLPrinter - Create an AST consumer which rewrites source code to /// HTML with syntax highlighting suitable for viewing in a web-browser. -std::unique_ptr<ASTConsumer> CreateHTMLPrinter(raw_ostream *OS, +std::unique_ptr<ASTConsumer> CreateHTMLPrinter(std::unique_ptr<raw_ostream> OS, Preprocessor &PP, bool SyntaxHighlight = true, bool HighlightMacros = true); diff --git a/include/clang/Rewrite/Frontend/FrontendActions.h b/include/clang/Rewrite/Frontend/FrontendActions.h index 6c290e4d60584..27976eac4ed23 100644 --- a/include/clang/Rewrite/Frontend/FrontendActions.h +++ b/include/clang/Rewrite/Frontend/FrontendActions.h @@ -50,8 +50,8 @@ public: /// frontend action. class FixItRecompile : public WrapperFrontendAction { public: - FixItRecompile(FrontendAction *WrappedAction) - : WrapperFrontendAction(WrappedAction) {} + FixItRecompile(std::unique_ptr<FrontendAction> WrappedAction) + : WrapperFrontendAction(std::move(WrappedAction)) {} protected: bool BeginInvocation(CompilerInstance &CI) override; diff --git a/include/clang/Sema/AttributeList.h b/include/clang/Sema/AttributeList.h index e32781d35fc73..fcddbecc029cc 100644 --- a/include/clang/Sema/AttributeList.h +++ b/include/clang/Sema/AttributeList.h @@ -46,6 +46,28 @@ struct AvailabilityChange { bool isValid() const { return !Version.empty(); } }; +namespace { +enum AvailabilitySlot { + IntroducedSlot, DeprecatedSlot, ObsoletedSlot, NumAvailabilitySlots +}; + +/// Describes the trailing object for Availability attribute in AttributeList. +struct AvailabilityData { + AvailabilityChange Changes[NumAvailabilitySlots]; + SourceLocation StrictLoc; + const Expr *Replacement; + AvailabilityData(const AvailabilityChange &Introduced, + const AvailabilityChange &Deprecated, + const AvailabilityChange &Obsoleted, + SourceLocation Strict, const Expr *ReplaceExpr) + : StrictLoc(Strict), Replacement(ReplaceExpr) { + Changes[IntroducedSlot] = Introduced; + Changes[DeprecatedSlot] = Deprecated; + Changes[ObsoletedSlot] = Obsoleted; + } +}; +} + /// \brief Wraps an identifier and optional source location for the identifier. struct IdentifierLoc { SourceLocation Loc; @@ -94,9 +116,11 @@ private: SourceLocation ScopeLoc; SourceLocation EllipsisLoc; + unsigned AttrKind : 16; + /// The number of expression arguments this attribute has. /// The expressions themselves are stored after the object. - unsigned NumArgs : 15; + unsigned NumArgs : 16; /// Corresponds to the Syntax enum. unsigned SyntaxUsed : 3; @@ -122,7 +146,11 @@ private: /// True if this has a ParsedType unsigned HasParsedType : 1; - unsigned AttrKind : 8; + /// True if the processing cache is valid. + mutable unsigned HasProcessingCache : 1; + + /// A cached value. + mutable unsigned ProcessingCache : 8; /// \brief The location of the 'unavailable' keyword in an /// availability attribute. @@ -142,19 +170,13 @@ private: return reinterpret_cast<ArgsUnion const *>(this + 1); } - enum AvailabilitySlot { - IntroducedSlot, DeprecatedSlot, ObsoletedSlot - }; - /// Availability information is stored immediately following the arguments, /// if any, at the end of the object. - AvailabilityChange &getAvailabilitySlot(AvailabilitySlot index) { - return reinterpret_cast<AvailabilityChange*>(getArgsBuffer() - + NumArgs)[index]; + AvailabilityData *getAvailabilityData() { + return reinterpret_cast<AvailabilityData*>(getArgsBuffer() + NumArgs); } - const AvailabilityChange &getAvailabilitySlot(AvailabilitySlot index) const { - return reinterpret_cast<const AvailabilityChange*>(getArgsBuffer() - + NumArgs)[index]; + const AvailabilityData *getAvailabilityData() const { + return reinterpret_cast<const AvailabilityData*>(getArgsBuffer() + NumArgs); } public: @@ -220,7 +242,8 @@ private: ScopeLoc(scopeLoc), EllipsisLoc(ellipsisLoc), NumArgs(numArgs), SyntaxUsed(syntaxUsed), Invalid(false), UsedAsTypeAttr(false), IsAvailability(false), IsTypeTagForDatatype(false), IsProperty(false), - HasParsedType(false), NextInPosition(nullptr), NextInPool(nullptr) { + HasParsedType(false), HasProcessingCache(false), + NextInPosition(nullptr), NextInPool(nullptr) { if (numArgs) memcpy(getArgsBuffer(), args, numArgs * sizeof(ArgsUnion)); AttrKind = getKind(getName(), getScopeName(), syntaxUsed); } @@ -233,18 +256,18 @@ private: const AvailabilityChange &obsoleted, SourceLocation unavailable, const Expr *messageExpr, - Syntax syntaxUsed) + Syntax syntaxUsed, SourceLocation strict, + const Expr *replacementExpr) : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange), ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(1), SyntaxUsed(syntaxUsed), Invalid(false), UsedAsTypeAttr(false), IsAvailability(true), IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(false), - UnavailableLoc(unavailable), MessageExpr(messageExpr), - NextInPosition(nullptr), NextInPool(nullptr) { + HasProcessingCache(false), UnavailableLoc(unavailable), + MessageExpr(messageExpr), NextInPosition(nullptr), NextInPool(nullptr) { ArgsUnion PVal(Parm); memcpy(getArgsBuffer(), &PVal, sizeof(ArgsUnion)); - new (&getAvailabilitySlot(IntroducedSlot)) AvailabilityChange(introduced); - new (&getAvailabilitySlot(DeprecatedSlot)) AvailabilityChange(deprecated); - new (&getAvailabilitySlot(ObsoletedSlot)) AvailabilityChange(obsoleted); + new (getAvailabilityData()) AvailabilityData( + introduced, deprecated, obsoleted, strict, replacementExpr); AttrKind = getKind(getName(), getScopeName(), syntaxUsed); } @@ -259,12 +282,11 @@ private: ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(3), SyntaxUsed(syntaxUsed), Invalid(false), UsedAsTypeAttr(false), IsAvailability(false), IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(false), - NextInPosition(nullptr), NextInPool(nullptr) { - ArgsVector Args; - Args.push_back(Parm1); - Args.push_back(Parm2); - Args.push_back(Parm3); - memcpy(getArgsBuffer(), &Args[0], 3 * sizeof(ArgsUnion)); + HasProcessingCache(false), NextInPosition(nullptr), NextInPool(nullptr) { + ArgsUnion *Args = getArgsBuffer(); + Args[0] = Parm1; + Args[1] = Parm2; + Args[2] = Parm3; AttrKind = getKind(getName(), getScopeName(), syntaxUsed); } @@ -277,7 +299,7 @@ private: ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(1), SyntaxUsed(syntaxUsed), Invalid(false), UsedAsTypeAttr(false), IsAvailability(false), IsTypeTagForDatatype(true), IsProperty(false), HasParsedType(false), - NextInPosition(nullptr), NextInPool(nullptr) { + HasProcessingCache(false), NextInPosition(nullptr), NextInPool(nullptr) { ArgsUnion PVal(ArgKind); memcpy(getArgsBuffer(), &PVal, sizeof(ArgsUnion)); TypeTagForDatatypeData &ExtraData = getTypeTagForDatatypeDataSlot(); @@ -295,7 +317,7 @@ private: ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(0), SyntaxUsed(syntaxUsed), Invalid(false), UsedAsTypeAttr(false), IsAvailability(false), IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(true), - NextInPosition(nullptr), NextInPool(nullptr) { + HasProcessingCache(false), NextInPosition(nullptr), NextInPool(nullptr){ new (&getTypeBuffer()) ParsedType(typeArg); AttrKind = getKind(getName(), getScopeName(), syntaxUsed); } @@ -309,7 +331,7 @@ private: ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(0), SyntaxUsed(syntaxUsed), Invalid(false), UsedAsTypeAttr(false), IsAvailability(false), IsTypeTagForDatatype(false), IsProperty(true), HasParsedType(false), - NextInPosition(nullptr), NextInPool(nullptr) { + HasProcessingCache(false), NextInPosition(nullptr), NextInPool(nullptr) { new (&getPropertyDataBuffer()) PropertyData(getterId, setterId); AttrKind = getKind(getName(), getScopeName(), syntaxUsed); } @@ -361,6 +383,16 @@ public: bool isInvalid() const { return Invalid; } void setInvalid(bool b = true) const { Invalid = b; } + bool hasProcessingCache() const { return HasProcessingCache; } + unsigned getProcessingCache() const { + assert(hasProcessingCache()); + return ProcessingCache; + } + void setProcessingCache(unsigned value) const { + ProcessingCache = value; + HasProcessingCache = true; + } + bool isUsedAsTypeAttr() const { return UsedAsTypeAttr; } void setUsedAsTypeAttr() { UsedAsTypeAttr = true; } @@ -399,17 +431,22 @@ public: const AvailabilityChange &getAvailabilityIntroduced() const { assert(getKind() == AT_Availability && "Not an availability attribute"); - return getAvailabilitySlot(IntroducedSlot); + return getAvailabilityData()->Changes[IntroducedSlot]; } const AvailabilityChange &getAvailabilityDeprecated() const { assert(getKind() == AT_Availability && "Not an availability attribute"); - return getAvailabilitySlot(DeprecatedSlot); + return getAvailabilityData()->Changes[DeprecatedSlot]; } const AvailabilityChange &getAvailabilityObsoleted() const { assert(getKind() == AT_Availability && "Not an availability attribute"); - return getAvailabilitySlot(ObsoletedSlot); + return getAvailabilityData()->Changes[ObsoletedSlot]; + } + + SourceLocation getStrictLoc() const { + assert(getKind() == AT_Availability && "Not an availability attribute"); + return getAvailabilityData()->StrictLoc; } SourceLocation getUnavailableLoc() const { @@ -422,6 +459,11 @@ public: return MessageExpr; } + const Expr *getReplacementExpr() const { + assert(getKind() == AT_Availability && "Not an availability attribute"); + return getAvailabilityData()->Replacement; + } + const ParsedType &getMatchingCType() const { assert(getKind() == AT_TypeTagForDatatype && "Not a type_tag_for_datatype attribute"); @@ -457,6 +499,7 @@ public: bool isTargetSpecificAttr() const; bool isTypeAttr() const; + bool isStmtAttr() const; bool hasCustomParsing() const; unsigned getMinArgs() const; @@ -487,8 +530,7 @@ public: /// which we want to ensure is a multiple of sizeof(void*). AvailabilityAllocSize = sizeof(AttributeList) - + ((3 * sizeof(AvailabilityChange) + sizeof(void*) + - sizeof(ArgsUnion) - 1) + + ((sizeof(AvailabilityData) + sizeof(void*) + sizeof(ArgsUnion) - 1) / sizeof(void*) * sizeof(void*)), TypeTagForDatatypeAllocSize = sizeof(AttributeList) @@ -606,13 +648,14 @@ public: const AvailabilityChange &obsoleted, SourceLocation unavailable, const Expr *MessageExpr, - AttributeList::Syntax syntax) { + AttributeList::Syntax syntax, + SourceLocation strict, const Expr *ReplacementExpr) { void *memory = allocate(AttributeFactory::AvailabilityAllocSize); return add(new (memory) AttributeList(attrName, attrRange, scopeName, scopeLoc, Param, introduced, deprecated, obsoleted, unavailable, MessageExpr, - syntax)); + syntax, strict, ReplacementExpr)); } AttributeList *create(IdentifierInfo *attrName, SourceRange attrRange, @@ -741,10 +784,12 @@ public: const AvailabilityChange &obsoleted, SourceLocation unavailable, const Expr *MessageExpr, - AttributeList::Syntax syntax) { + AttributeList::Syntax syntax, + SourceLocation strict, const Expr *ReplacementExpr) { AttributeList *attr = pool.create(attrName, attrRange, scopeName, scopeLoc, Param, introduced, - deprecated, obsoleted, unavailable, MessageExpr, syntax); + deprecated, obsoleted, unavailable, MessageExpr, syntax, + strict, ReplacementExpr); add(attr); return attr; } @@ -824,6 +869,7 @@ enum AttributeDeclKind { ExpectedFunction, ExpectedUnion, ExpectedVariableOrFunction, + ExpectedFunctionVariableOrObjCInterface, ExpectedFunctionOrMethod, ExpectedParameter, ExpectedFunctionMethodOrBlock, @@ -833,9 +879,9 @@ enum AttributeDeclKind { ExpectedEnum, ExpectedVariable, ExpectedMethod, - ExpectedVariableFunctionOrLabel, ExpectedFieldOrGlobalVar, ExpectedStruct, + ExpectedParameterOrTypedef, ExpectedVariableOrTypedef, ExpectedTLSVar, ExpectedVariableOrField, @@ -849,13 +895,18 @@ enum AttributeDeclKind { ExpectedObjCInstanceMethod, ExpectedObjCInterfaceDeclInitMethod, ExpectedFunctionVariableOrClass, + ExpectedFunctionVariableClassOrObjCInterface, ExpectedObjectiveCProtocol, ExpectedFunctionGlobalVarMethodOrProperty, ExpectedStructOrUnionOrTypedef, ExpectedStructOrTypedef, ExpectedObjectiveCInterfaceOrProtocol, ExpectedKernelFunction, - ExpectedFunctionWithProtoType + ExpectedFunctionWithProtoType, + ExpectedVariableEnumFieldOrTypedef, + ExpectedFunctionMethodEnumOrClass, + ExpectedStructClassVariableFunctionOrInlineNamespace, + ExpectedForMaybeUnused }; } // end namespace clang diff --git a/include/clang/Sema/CleanupInfo.h b/include/clang/Sema/CleanupInfo.h new file mode 100644 index 0000000000000..751bfb63b4423 --- /dev/null +++ b/include/clang/Sema/CleanupInfo.h @@ -0,0 +1,47 @@ +//===--- CleanupInfo.cpp - Cleanup Control in Sema ------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements a set of operations on whether generating an +// ExprWithCleanups in a full expression. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_SEMA_CLEANUP_INFO_H +#define LLVM_CLANG_SEMA_CLEANUP_INFO_H + +namespace clang { + +class CleanupInfo { + bool ExprNeedsCleanups = false; + bool CleanupsHaveSideEffects = false; + +public: + bool exprNeedsCleanups() const { return ExprNeedsCleanups; } + + bool cleanupsHaveSideEffects() const { return CleanupsHaveSideEffects; } + + void setExprNeedsCleanups(bool SideEffects) { + ExprNeedsCleanups = true; + CleanupsHaveSideEffects |= SideEffects; + } + + void reset() { + ExprNeedsCleanups = false; + CleanupsHaveSideEffects = false; + } + + void mergeFrom(CleanupInfo Rhs) { + ExprNeedsCleanups |= Rhs.ExprNeedsCleanups; + CleanupsHaveSideEffects |= Rhs.CleanupsHaveSideEffects; + } +}; + +} // end namespace clang + +#endif diff --git a/include/clang/Sema/CodeCompleteConsumer.h b/include/clang/Sema/CodeCompleteConsumer.h index 97022738d03ed..014ea5d61dfd1 100644 --- a/include/clang/Sema/CodeCompleteConsumer.h +++ b/include/clang/Sema/CodeCompleteConsumer.h @@ -15,6 +15,7 @@ #include "clang-c/Index.h" #include "clang/AST/CanonicalType.h" +#include "clang/AST/DeclBase.h" #include "clang/AST/Type.h" #include "clang/Sema/CodeCompleteOptions.h" #include "llvm/ADT/DenseMap.h" @@ -22,6 +23,7 @@ #include "llvm/ADT/StringRef.h" #include "llvm/Support/Allocator.h" #include <string> +#include <utility> namespace clang { @@ -516,8 +518,8 @@ class CodeCompletionTUInfo { public: explicit CodeCompletionTUInfo( - IntrusiveRefCntPtr<GlobalCodeCompletionAllocator> Allocator) - : AllocatorRef(Allocator) { } + IntrusiveRefCntPtr<GlobalCodeCompletionAllocator> Allocator) + : AllocatorRef(std::move(Allocator)) {} IntrusiveRefCntPtr<GlobalCodeCompletionAllocator> getAllocatorRef() const { return AllocatorRef; diff --git a/include/clang/Sema/DeclSpec.h b/include/clang/Sema/DeclSpec.h index 064d37b2a02bf..afcd791bca294 100644 --- a/include/clang/Sema/DeclSpec.h +++ b/include/clang/Sema/DeclSpec.h @@ -280,6 +280,7 @@ public: static const TST TST_half = clang::TST_half; static const TST TST_float = clang::TST_float; static const TST TST_double = clang::TST_double; + static const TST TST_float128 = clang::TST_float128; static const TST TST_bool = clang::TST_bool; static const TST TST_decimal32 = clang::TST_decimal32; static const TST TST_decimal64 = clang::TST_decimal64; @@ -299,6 +300,9 @@ public: static const TST TST_auto_type = clang::TST_auto_type; static const TST TST_unknown_anytype = clang::TST_unknown_anytype; static const TST TST_atomic = clang::TST_atomic; +#define GENERIC_IMAGE_TYPE(ImgType, Id) \ + static const TST TST_##ImgType##_t = clang::TST_##ImgType##_t; +#include "clang/Basic/OpenCLImageTypes.def" static const TST TST_error = clang::TST_error; // type-qualifiers @@ -307,9 +311,10 @@ public: TQ_const = 1, TQ_restrict = 2, TQ_volatile = 4, + TQ_unaligned = 8, // This has no corresponding Qualifiers::TQ value, because it's not treated // as a qualifier in our type system. - TQ_atomic = 8 + TQ_atomic = 16 }; /// ParsedSpecifiers - Flags to query which specifiers were applied. This is @@ -340,7 +345,7 @@ private: unsigned TypeSpecPipe : 1; // type-qualifiers - unsigned TypeQualifiers : 4; // Bitwise OR of TQ. + unsigned TypeQualifiers : 5; // Bitwise OR of TQ. // function-specifier unsigned FS_inline_specified : 1; @@ -382,7 +387,8 @@ private: /// TSTNameLoc provides source range info for tag types. SourceLocation TSTNameLoc; SourceRange TypeofParensRange; - SourceLocation TQ_constLoc, TQ_restrictLoc, TQ_volatileLoc, TQ_atomicLoc; + SourceLocation TQ_constLoc, TQ_restrictLoc, TQ_volatileLoc, TQ_atomicLoc, + TQ_unalignedLoc; SourceLocation FS_inlineLoc, FS_virtualLoc, FS_explicitLoc, FS_noreturnLoc; SourceLocation FS_forceinlineLoc; SourceLocation FriendLoc, ModulePrivateLoc, ConstexprLoc, ConceptLoc; @@ -536,6 +542,7 @@ public: SourceLocation getRestrictSpecLoc() const { return TQ_restrictLoc; } SourceLocation getVolatileSpecLoc() const { return TQ_volatileLoc; } SourceLocation getAtomicSpecLoc() const { return TQ_atomicLoc; } + SourceLocation getUnalignedSpecLoc() const { return TQ_unalignedLoc; } SourceLocation getPipeLoc() const { return TQ_pipeLoc; } /// \brief Clear out all of the type qualifiers. @@ -545,6 +552,7 @@ public: TQ_restrictLoc = SourceLocation(); TQ_volatileLoc = SourceLocation(); TQ_atomicLoc = SourceLocation(); + TQ_unalignedLoc = SourceLocation(); TQ_pipeLoc = SourceLocation(); } @@ -785,6 +793,7 @@ public: }; /// PropertyAttributeKind - list of property attributes. + /// Keep this list in sync with LLVM's Dwarf.h ApplePropertyAttributes. enum ObjCPropertyAttributeKind { DQ_PR_noattr = 0x0, DQ_PR_readonly = 0x01, @@ -800,7 +809,8 @@ public: DQ_PR_strong = 0x400, DQ_PR_unsafe_unretained = 0x800, DQ_PR_nullability = 0x1000, - DQ_PR_null_resettable = 0x2000 + DQ_PR_null_resettable = 0x2000, + DQ_PR_class = 0x4000 }; ObjCDeclSpec() @@ -860,7 +870,7 @@ private: ObjCDeclQualifier objcDeclQualifier : 7; // NOTE: VC++ treats enums as signed, avoid using ObjCPropertyAttributeKind - unsigned PropertyAttributes : 14; + unsigned PropertyAttributes : 15; unsigned Nullability : 2; @@ -1109,8 +1119,8 @@ struct DeclaratorChunk { }; struct PointerTypeInfo : TypeInfoCommon { - /// The type qualifiers: const/volatile/restrict/atomic. - unsigned TypeQuals : 4; + /// The type qualifiers: const/volatile/restrict/unaligned/atomic. + unsigned TypeQuals : 5; /// The location of the const-qualifier, if any. unsigned ConstQualLoc; @@ -1124,6 +1134,9 @@ struct DeclaratorChunk { /// The location of the _Atomic-qualifier, if any. unsigned AtomicQualLoc; + /// The location of the __unaligned-qualifier, if any. + unsigned UnalignedQualLoc; + void destroy() { } }; @@ -1138,14 +1151,15 @@ struct DeclaratorChunk { }; struct ArrayTypeInfo : TypeInfoCommon { - /// The type qualifiers for the array: const/volatile/restrict/_Atomic. - unsigned TypeQuals : 4; + /// The type qualifiers for the array: + /// const/volatile/restrict/__unaligned/_Atomic. + unsigned TypeQuals : 5; /// True if this dimension included the 'static' keyword. - bool hasStatic : 1; + unsigned hasStatic : 1; /// True if this dimension was [*]. In this case, NumElts is null. - bool isStar : 1; + unsigned isStar : 1; /// This is the size of the array, or null if [] or [*] was specified. /// Since the parser is multi-purpose, and we don't want to impose a root @@ -1205,9 +1219,9 @@ struct DeclaratorChunk { /// Otherwise, it's an rvalue reference. unsigned RefQualifierIsLValueRef : 1; - /// The type qualifiers: const/volatile/restrict. + /// The type qualifiers: const/volatile/restrict/__unaligned /// The qualifier bitmask values are the same as in QualType. - unsigned TypeQuals : 3; + unsigned TypeQuals : 4; /// ExceptionSpecType - An ExceptionSpecificationType value. unsigned ExceptionSpecType : 4; @@ -1391,16 +1405,16 @@ struct DeclaratorChunk { struct BlockPointerTypeInfo : TypeInfoCommon { /// For now, sema will catch these as invalid. - /// The type qualifiers: const/volatile/restrict/_Atomic. - unsigned TypeQuals : 4; + /// The type qualifiers: const/volatile/restrict/__unaligned/_Atomic. + unsigned TypeQuals : 5; void destroy() { } }; struct MemberPointerTypeInfo : TypeInfoCommon { - /// The type qualifiers: const/volatile/restrict/_Atomic. - unsigned TypeQuals : 4; + /// The type qualifiers: const/volatile/restrict/__unaligned/_Atomic. + unsigned TypeQuals : 5; // CXXScopeSpec has a constructor, so it can't be a direct member. // So we need some pointer-aligned storage and a bit of trickery. union { @@ -1464,7 +1478,8 @@ struct DeclaratorChunk { SourceLocation ConstQualLoc, SourceLocation VolatileQualLoc, SourceLocation RestrictQualLoc, - SourceLocation AtomicQualLoc) { + SourceLocation AtomicQualLoc, + SourceLocation UnalignedQualLoc) { DeclaratorChunk I; I.Kind = Pointer; I.Loc = Loc; @@ -1473,6 +1488,7 @@ struct DeclaratorChunk { I.Ptr.VolatileQualLoc = VolatileQualLoc.getRawEncoding(); I.Ptr.RestrictQualLoc = RestrictQualLoc.getRawEncoding(); I.Ptr.AtomicQualLoc = AtomicQualLoc.getRawEncoding(); + I.Ptr.UnalignedQualLoc = UnalignedQualLoc.getRawEncoding(); I.Ptr.AttrList = nullptr; return I; } @@ -1551,7 +1567,7 @@ struct DeclaratorChunk { I.Kind = Pipe; I.Loc = Loc; I.Cls.TypeQuals = TypeQuals; - I.Cls.AttrList = 0; + I.Cls.AttrList = nullptr; return I; } @@ -1617,6 +1633,7 @@ public: MemberContext, // Struct/Union field. BlockContext, // Declaration within a block in a function. ForContext, // Declaration within first part of a for loop. + InitStmtContext, // Declaration within optional init stmt of if/switch. ConditionContext, // Condition declaration in a C++ if/switch/while/for. TemplateParamContext,// Within a template parameter list. CXXNewContext, // C++ new-expression. @@ -1648,10 +1665,10 @@ private: SmallVector<DeclaratorChunk, 8> DeclTypeInfo; /// InvalidType - Set by Sema::GetTypeForDeclarator(). - bool InvalidType : 1; + unsigned InvalidType : 1; /// GroupingParens - Set by Parser::ParseParenDeclarator(). - bool GroupingParens : 1; + unsigned GroupingParens : 1; /// FunctionDefinition - Is this Declarator for a function or member /// definition and, if so, what kind? @@ -1660,7 +1677,7 @@ private: unsigned FunctionDefinition : 2; /// \brief Is this Declarator a redeclaration? - bool Redeclaration : 1; + unsigned Redeclaration : 1; /// Attrs - Attributes. ParsedAttributes Attrs; @@ -1795,6 +1812,7 @@ public: case MemberContext: case BlockContext: case ForContext: + case InitStmtContext: case ConditionContext: return false; @@ -1829,6 +1847,7 @@ public: case MemberContext: case BlockContext: case ForContext: + case InitStmtContext: case ConditionContext: case PrototypeContext: case LambdaExprParameterContext: @@ -1862,6 +1881,7 @@ public: case MemberContext: case BlockContext: case ForContext: + case InitStmtContext: case ConditionContext: case PrototypeContext: case LambdaExprParameterContext: @@ -1906,6 +1926,7 @@ public: case FileContext: case BlockContext: case ForContext: + case InitStmtContext: return true; case ConditionContext: @@ -2104,9 +2125,10 @@ public: case FileContext: case MemberContext: case BlockContext: + case ForContext: + case InitStmtContext: return true; - case ForContext: case ConditionContext: case KNRTypeListContext: case TypeNameContext: @@ -2340,4 +2362,4 @@ struct LambdaIntroducer { } // end namespace clang -#endif +#endif // LLVM_CLANG_SEMA_DECLSPEC_H diff --git a/include/clang/Sema/ExternalSemaSource.h b/include/clang/Sema/ExternalSemaSource.h index 97f78f46a613c..c2b13046d7090 100644 --- a/include/clang/Sema/ExternalSemaSource.h +++ b/include/clang/Sema/ExternalSemaSource.h @@ -70,6 +70,10 @@ public: /// selector. virtual void ReadMethodPool(Selector Sel); + /// Load the contents of the global method pool for a given + /// selector if necessary. + virtual void updateOutOfDateSelector(Selector Sel); + /// \brief Load the set of namespaces that are known to the external source, /// which will be used during typo correction. virtual void ReadKnownNamespaces( @@ -77,8 +81,8 @@ public: /// \brief Load the set of used but not defined functions or variables with /// internal linkage, or used but not defined internal functions. - virtual void ReadUndefinedButUsed( - llvm::DenseMap<NamedDecl*, SourceLocation> &Undefined); + virtual void + ReadUndefinedButUsed(llvm::MapVector<NamedDecl *, SourceLocation> &Undefined); virtual void ReadMismatchingDeleteExpressions(llvm::MapVector< FieldDecl *, llvm::SmallVector<std::pair<SourceLocation, bool>, 4>> &); diff --git a/include/clang/Sema/Initialization.h b/include/clang/Sema/Initialization.h index d4f57b701127b..a0bf78bf16881 100644 --- a/include/clang/Sema/Initialization.h +++ b/include/clang/Sema/Initialization.h @@ -284,9 +284,10 @@ public: /// \brief Create the initialization entity for a base class subobject. - static InitializedEntity InitializeBase(ASTContext &Context, - const CXXBaseSpecifier *Base, - bool IsInheritedVirtualBase); + static InitializedEntity + InitializeBase(ASTContext &Context, const CXXBaseSpecifier *Base, + bool IsInheritedVirtualBase, + const InitializedEntity *Parent = nullptr); /// \brief Create the initialization entity for a delegated constructor. static InitializedEntity InitializeDelegation(QualType Type) { @@ -885,14 +886,17 @@ public: /// \param TopLevelOfInitList true if we are initializing from an expression /// at the top level inside an initializer list. This disallows /// narrowing conversions in C++11 onwards. + /// \param TreatUnavailableAsInvalid true if we want to treat unavailable + /// as invalid. InitializationSequence(Sema &S, const InitializedEntity &Entity, const InitializationKind &Kind, MultiExprArg Args, - bool TopLevelOfInitList = false); + bool TopLevelOfInitList = false, + bool TreatUnavailableAsInvalid = true); void InitializeFrom(Sema &S, const InitializedEntity &Entity, const InitializationKind &Kind, MultiExprArg Args, - bool TopLevelOfInitList); + bool TopLevelOfInitList, bool TreatUnavailableAsInvalid); ~InitializationSequence(); @@ -948,6 +952,9 @@ public: step_iterator step_begin() const { return Steps.begin(); } step_iterator step_end() const { return Steps.end(); } + typedef llvm::iterator_range<step_iterator> step_range; + step_range steps() const { return {step_begin(), step_end()}; } + /// \brief Determine whether this initialization is a direct reference /// binding (C++ [dcl.init.ref]). bool isDirectReferenceBinding() const; @@ -1042,8 +1049,8 @@ public: /// \param FromInitList The constructor call is syntactically an initializer /// list. /// \param AsInitList The constructor is called as an init list constructor. - void AddConstructorInitializationStep(CXXConstructorDecl *Constructor, - AccessSpecifier Access, + void AddConstructorInitializationStep(DeclAccessPair FoundDecl, + CXXConstructorDecl *Constructor, QualType T, bool HadMultipleCandidates, bool FromInitList, bool AsInitList); diff --git a/include/clang/Sema/Lookup.h b/include/clang/Sema/Lookup.h index 7efb19f574198..2ed9548b5936a 100644 --- a/include/clang/Sema/Lookup.h +++ b/include/clang/Sema/Lookup.h @@ -185,6 +185,49 @@ public: Shadowed(false) {} + // FIXME: Remove these deleted methods once the default build includes + // -Wdeprecated. + LookupResult(const LookupResult &) = delete; + LookupResult &operator=(const LookupResult &) = delete; + + LookupResult(LookupResult &&Other) + : ResultKind(std::move(Other.ResultKind)), + Ambiguity(std::move(Other.Ambiguity)), Decls(std::move(Other.Decls)), + Paths(std::move(Other.Paths)), + NamingClass(std::move(Other.NamingClass)), + BaseObjectType(std::move(Other.BaseObjectType)), + SemaPtr(std::move(Other.SemaPtr)), NameInfo(std::move(Other.NameInfo)), + NameContextRange(std::move(Other.NameContextRange)), + LookupKind(std::move(Other.LookupKind)), IDNS(std::move(Other.IDNS)), + Redecl(std::move(Other.Redecl)), HideTags(std::move(Other.HideTags)), + Diagnose(std::move(Other.Diagnose)), + AllowHidden(std::move(Other.AllowHidden)), + Shadowed(std::move(Other.Shadowed)) { + Other.Paths = nullptr; + Other.Diagnose = false; + } + LookupResult &operator=(LookupResult &&Other) { + ResultKind = std::move(Other.ResultKind); + Ambiguity = std::move(Other.Ambiguity); + Decls = std::move(Other.Decls); + Paths = std::move(Other.Paths); + NamingClass = std::move(Other.NamingClass); + BaseObjectType = std::move(Other.BaseObjectType); + SemaPtr = std::move(Other.SemaPtr); + NameInfo = std::move(Other.NameInfo); + NameContextRange = std::move(Other.NameContextRange); + LookupKind = std::move(Other.LookupKind); + IDNS = std::move(Other.IDNS); + Redecl = std::move(Other.Redecl); + HideTags = std::move(Other.HideTags); + Diagnose = std::move(Other.Diagnose); + AllowHidden = std::move(Other.AllowHidden); + Shadowed = std::move(Other.Shadowed); + Other.Paths = nullptr; + Other.Diagnose = false; + return *this; + } + ~LookupResult() { if (Diagnose) diagnose(); if (Paths) deletePaths(Paths); @@ -726,7 +769,13 @@ public: class ADLResult { private: /// A map from canonical decls to the 'most recent' decl. - llvm::DenseMap<NamedDecl*, NamedDecl*> Decls; + llvm::MapVector<NamedDecl*, NamedDecl*> Decls; + + struct select_second { + NamedDecl *operator()(std::pair<NamedDecl*, NamedDecl*> P) const { + return P.second; + } + }; public: /// Adds a new ADL candidate to this map. @@ -737,23 +786,11 @@ public: Decls.erase(cast<NamedDecl>(D->getCanonicalDecl())); } - class iterator - : public llvm::iterator_adaptor_base< - iterator, llvm::DenseMap<NamedDecl *, NamedDecl *>::iterator, - std::forward_iterator_tag, NamedDecl *> { - friend class ADLResult; - - iterator(llvm::DenseMap<NamedDecl *, NamedDecl *>::iterator Iter) - : iterator_adaptor_base(std::move(Iter)) {} - - public: - iterator() {} - - value_type operator*() const { return I->second; } - }; + typedef llvm::mapped_iterator<decltype(Decls)::iterator, select_second> + iterator; - iterator begin() { return iterator(Decls.begin()); } - iterator end() { return iterator(Decls.end()); } + iterator begin() { return iterator(Decls.begin(), select_second()); } + iterator end() { return iterator(Decls.end(), select_second()); } }; } diff --git a/include/clang/Sema/Makefile b/include/clang/Sema/Makefile deleted file mode 100644 index 799f789e0eadd..0000000000000 --- a/include/clang/Sema/Makefile +++ /dev/null @@ -1,39 +0,0 @@ -CLANG_LEVEL := ../../.. -TD_SRC_DIR = $(PROJ_SRC_DIR)/../Basic -BUILT_SOURCES = AttrTemplateInstantiate.inc AttrParsedAttrList.inc AttrParsedAttrKinds.inc \ - AttrSpellingListIndex.inc AttrParsedAttrImpl.inc - -TABLEGEN_INC_FILES_COMMON = 1 - -include $(CLANG_LEVEL)/Makefile - -$(ObjDir)/AttrTemplateInstantiate.inc.tmp : $(TD_SRC_DIR)/Attr.td \ - $(CLANG_TBLGEN) $(ObjDir)/.dir - $(Echo) "Building Clang attribute template instantiate code with tablegen" - $(Verb) $(ClangTableGen) -gen-clang-attr-template-instantiate -o \ - $(call SYSPATH, $@) -I $(PROJ_SRC_DIR)/../../ $< - -$(ObjDir)/AttrParsedAttrList.inc.tmp : $(TD_SRC_DIR)/Attr.td \ - $(CLANG_TBLGEN) $(ObjDir)/.dir - $(Echo) "Building Clang parsed attribute list with tablegen" - $(Verb) $(ClangTableGen) -gen-clang-attr-parsed-attr-list -o \ - $(call SYSPATH, $@) -I $(PROJ_SRC_DIR)/../../ $< - -$(ObjDir)/AttrParsedAttrKinds.inc.tmp : $(TD_SRC_DIR)/Attr.td \ - $(CLANG_TBLGEN) $(ObjDir)/.dir - $(Echo) "Building Clang parsed attribute kinds with tablegen" - $(Verb) $(ClangTableGen) -gen-clang-attr-parsed-attr-kinds -o \ - $(call SYSPATH, $@) -I $(PROJ_SRC_DIR)/../../ $< - -$(ObjDir)/AttrSpellingListIndex.inc.tmp : $(TD_SRC_DIR)/Attr.td \ - $(CLANG_TBLGEN) $(ObjDir)/.dir - $(Echo) "Building Clang attribute spelling list index with tablegen" - $(Verb) $(ClangTableGen) -gen-clang-attr-spelling-index -o \ - $(call SYSPATH, $@) -I $(PROJ_SRC_DIR)/../../ $< - -$(ObjDir)/AttrParsedAttrImpl.inc.tmp : $(TD_SRC_DIR)/Attr.td \ - $(CLANG_TBLGEN) $(ObjDir)/.dir - $(Echo) "Building Clang parsed attribute list impl with tablegen" - $(Verb) $(ClangTableGen) -gen-clang-attr-parsed-attr-impl -o \ - $(call SYSPATH, $@) -I $(PROJ_SRC_DIR)/../../ $< - diff --git a/include/clang/Sema/MultiplexExternalSemaSource.h b/include/clang/Sema/MultiplexExternalSemaSource.h index d6daadc89da5f..9bf8cd3d92528 100644 --- a/include/clang/Sema/MultiplexExternalSemaSource.h +++ b/include/clang/Sema/MultiplexExternalSemaSource.h @@ -203,6 +203,10 @@ public: /// selector. void ReadMethodPool(Selector Sel) override; + /// Load the contents of the global method pool for a given + /// selector if necessary. + void updateOutOfDateSelector(Selector Sel) override; + /// \brief Load the set of namespaces that are known to the external source, /// which will be used during typo correction. void @@ -211,7 +215,7 @@ public: /// \brief Load the set of used but not defined functions or variables with /// internal linkage, or used but not defined inline functions. void ReadUndefinedButUsed( - llvm::DenseMap<NamedDecl*, SourceLocation> &Undefined) override; + llvm::MapVector<NamedDecl *, SourceLocation> &Undefined) override; void ReadMismatchingDeleteExpressions(llvm::MapVector< FieldDecl *, llvm::SmallVector<std::pair<SourceLocation, bool>, 4>> & diff --git a/include/clang/Sema/ObjCMethodList.h b/include/clang/Sema/ObjCMethodList.h index b618e38f88cd4..80ccd363d2725 100644 --- a/include/clang/Sema/ObjCMethodList.h +++ b/include/clang/Sema/ObjCMethodList.h @@ -14,6 +14,7 @@ #ifndef LLVM_CLANG_SEMA_OBJCMETHODLIST_H #define LLVM_CLANG_SEMA_OBJCMETHODLIST_H +#include "clang/AST/DeclObjC.h" #include "llvm/ADT/PointerIntPair.h" namespace clang { @@ -32,6 +33,9 @@ struct ObjCMethodList { ObjCMethodList() { } ObjCMethodList(ObjCMethodDecl *M) : MethodAndHasMoreThanOneDecl(M, 0) {} + ObjCMethodList(const ObjCMethodList &L) + : MethodAndHasMoreThanOneDecl(L.MethodAndHasMoreThanOneDecl), + NextAndExtraBits(L.NextAndExtraBits) {} ObjCMethodList *getNext() const { return NextAndExtraBits.getPointer(); } unsigned getBits() const { return NextAndExtraBits.getInt(); } diff --git a/include/clang/Sema/Overload.h b/include/clang/Sema/Overload.h index 62437953b35b1..d0f21cd71f8d6 100644 --- a/include/clang/Sema/Overload.h +++ b/include/clang/Sema/Overload.h @@ -199,6 +199,7 @@ namespace clang { /// conversions are either identity conversions or derived-to-base /// conversions. CXXConstructorDecl *CopyConstructor; + DeclAccessPair FoundCopyConstructor; void setFromType(QualType T) { FromTypePtr = T.getAsOpaquePtr(); } void setToType(unsigned Idx, QualType T) { @@ -282,7 +283,7 @@ namespace clang { /// Represents an ambiguous user-defined conversion sequence. struct AmbiguousConversionSequence { - typedef SmallVector<FunctionDecl*, 4> ConversionSet; + typedef SmallVector<std::pair<NamedDecl*, FunctionDecl*>, 4> ConversionSet; void *FromTypePtr; void *ToTypePtr; @@ -305,8 +306,8 @@ namespace clang { return *reinterpret_cast<const ConversionSet*>(Buffer); } - void addConversion(FunctionDecl *D) { - conversions().push_back(D); + void addConversion(NamedDecl *Found, FunctionDecl *D) { + conversions().push_back(std::make_pair(Found, D)); } typedef ConversionSet::iterator iterator; @@ -396,7 +397,7 @@ namespace clang { /// \brief Whether the target is really a std::initializer_list, and the /// sequence only represents the worst element conversion. - bool StdInitializerListElement : 1; + unsigned StdInitializerListElement : 1; void setKind(Kind K) { destruct(); @@ -797,6 +798,30 @@ namespace clang { const OverloadCandidate& Cand2, SourceLocation Loc, bool UserDefinedConversion = false); + + struct ConstructorInfo { + DeclAccessPair FoundDecl; + CXXConstructorDecl *Constructor; + FunctionTemplateDecl *ConstructorTmpl; + explicit operator bool() const { return Constructor; } + }; + // FIXME: Add an AddOverloadCandidate / AddTemplateOverloadCandidate overload + // that takes one of these. + inline ConstructorInfo getConstructorInfo(NamedDecl *ND) { + if (isa<UsingDecl>(ND)) + return ConstructorInfo{}; + + // For constructors, the access check is performed against the underlying + // declaration, not the found declaration. + auto *D = ND->getUnderlyingDecl(); + ConstructorInfo Info = {DeclAccessPair::make(ND, D->getAccess()), nullptr, + nullptr}; + Info.ConstructorTmpl = dyn_cast<FunctionTemplateDecl>(D); + if (Info.ConstructorTmpl) + D = Info.ConstructorTmpl->getTemplatedDecl(); + Info.Constructor = dyn_cast<CXXConstructorDecl>(D); + return Info; + } } // end namespace clang #endif // LLVM_CLANG_SEMA_OVERLOAD_H diff --git a/include/clang/Sema/Ownership.h b/include/clang/Sema/Ownership.h index 8acf9e82bf95a..68d13f97e2e4f 100644 --- a/include/clang/Sema/Ownership.h +++ b/include/clang/Sema/Ownership.h @@ -14,6 +14,7 @@ #ifndef LLVM_CLANG_SEMA_OWNERSHIP_H #define LLVM_CLANG_SEMA_OWNERSHIP_H +#include "clang/AST/Expr.h" #include "clang/Basic/LLVM.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/PointerIntPair.h" @@ -43,13 +44,13 @@ namespace clang { /// compatible with "Type" pointers for example. template <class PtrTy> class OpaquePtr { - void *Ptr; + void *Ptr = nullptr; explicit OpaquePtr(void *Ptr) : Ptr(Ptr) {} typedef llvm::PointerLikeTypeTraits<PtrTy> Traits; public: - OpaquePtr() : Ptr(nullptr) {} + OpaquePtr(std::nullptr_t = nullptr) {} static OpaquePtr make(PtrTy P) { OpaquePtr OP; OP.set(P); return OP; } diff --git a/include/clang/Sema/ParsedTemplate.h b/include/clang/Sema/ParsedTemplate.h index b36425f1be83d..03de9ff6ae44f 100644 --- a/include/clang/Sema/ParsedTemplate.h +++ b/include/clang/Sema/ParsedTemplate.h @@ -1,4 +1,4 @@ -//===--- ParsedTemplate.h - Template Parsing Data Types -------------------===// +//===--- ParsedTemplate.h - Template Parsing Data Types ---------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -11,12 +11,19 @@ // templates. // //===----------------------------------------------------------------------===// + #ifndef LLVM_CLANG_SEMA_PARSEDTEMPLATE_H #define LLVM_CLANG_SEMA_PARSEDTEMPLATE_H +#include "clang/Basic/OperatorKinds.h" +#include "clang/Basic/SourceLocation.h" +#include "clang/Basic/TemplateKinds.h" #include "clang/Sema/DeclSpec.h" #include "clang/Sema/Ownership.h" +#include "llvm/ADT/SmallVector.h" #include <cassert> +#include <cstdlib> +#include <new> namespace clang { /// \brief Represents the parsed form of a C++ template argument. @@ -114,8 +121,8 @@ namespace clang { KindType Kind; /// \brief The actual template argument representation, which may be - /// an \c ActionBase::TypeTy* (for a type), an Expr* (for an - /// expression), or an ActionBase::TemplateTy (for a template). + /// an \c Sema::TypeTy* (for a type), an Expr* (for an + /// expression), or an Sema::TemplateTy (for a template). void *Arg; /// \brief The nested-name-specifier that can accompany a template template @@ -209,6 +216,6 @@ namespace clang { /// Retrieves the range of the given template parameter lists. SourceRange getTemplateParamsRange(TemplateParameterList const *const *Params, unsigned NumParams); -} +} // end namespace clang -#endif +#endif // LLVM_CLANG_SEMA_PARSEDTEMPLATE_H diff --git a/include/clang/Sema/Scope.h b/include/clang/Sema/Scope.h index dfc6f9c4628f0..d0b006b82ec6e 100644 --- a/include/clang/Sema/Scope.h +++ b/include/clang/Sema/Scope.h @@ -14,6 +14,7 @@ #ifndef LLVM_CLANG_SEMA_SCOPE_H #define LLVM_CLANG_SEMA_SCOPE_H +#include "clang/AST/Decl.h" #include "clang/Basic/Diagnostic.h" #include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/SmallPtrSet.h" @@ -196,6 +197,8 @@ private: /// this scope, or over-defined. The bit is true when over-defined. llvm::PointerIntPair<VarDecl *, 1, bool> NRVO; + void setFlags(Scope *Parent, unsigned F); + public: Scope(Scope *Parent, unsigned ScopeFlags, DiagnosticsEngine &Diag) : ErrorTrap(Diag) { @@ -205,7 +208,7 @@ public: /// getFlags - Return the flags for this scope. /// unsigned getFlags() const { return Flags; } - void setFlags(unsigned F) { Flags = F; } + void setFlags(unsigned F) { setFlags(getParent(), F); } /// isBlockScope - Return true if this scope correspond to a closure. bool isBlockScope() const { return Flags & BlockScope; } diff --git a/include/clang/Sema/ScopeInfo.h b/include/clang/Sema/ScopeInfo.h index d13667e800707..ee724f7d728c9 100644 --- a/include/clang/Sema/ScopeInfo.h +++ b/include/clang/Sema/ScopeInfo.h @@ -19,6 +19,7 @@ #include "clang/AST/Type.h" #include "clang/Basic/CapturedStmt.h" #include "clang/Basic/PartialDiagnostic.h" +#include "clang/Sema/CleanupInfo.h" #include "clang/Sema/Ownership.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallSet.h" @@ -104,6 +105,12 @@ public: /// \brief Whether a statement was dropped because it was invalid. bool HasDroppedStmt : 1; + /// \brief True if current scope is for OpenMP declare reduction combiner. + bool HasOMPDeclareReductionCombiner; + + /// \brief Whether there is a fallthrough statement in this function. + bool HasFallthroughStmt : 1; + /// A flag that is set when parsing a method that must call super's /// implementation, such as \c -dealloc, \c -finalize, or any method marked /// with \c __attribute__((objc_requires_super)). @@ -183,6 +190,7 @@ public: /// [self foo].prop | 0 (unknown) | prop (ObjCPropertyDecl) /// self.prop1.prop2 | prop1 (ObjCPropertyDecl) | prop2 (ObjCPropertyDecl) /// MyClass.prop | MyClass (ObjCInterfaceDecl) | -prop (ObjCMethodDecl) + /// MyClass.foo.prop | +foo (ObjCMethodDecl) | -prop (ObjCPropertyDecl) /// weakVar | 0 (known) | weakVar (VarDecl) /// self->weakIvar | self (VarDecl) | weakIvar (ObjCIvarDecl) /// @@ -341,6 +349,14 @@ public: HasDroppedStmt = true; } + void setHasOMPDeclareReductionCombiner() { + HasOMPDeclareReductionCombiner = true; + } + + void setHasFallthroughStmt() { + HasFallthroughStmt = true; + } + void setHasCXXTry(SourceLocation TryLoc) { setHasBranchProtectedScope(); FirstCXXTryLoc = TryLoc; @@ -363,6 +379,8 @@ public: HasBranchIntoScope(false), HasIndirectGoto(false), HasDroppedStmt(false), + HasOMPDeclareReductionCombiner(false), + HasFallthroughStmt(false), ObjCShouldCallSuper(false), ObjCIsDesignatedInit(false), ObjCWarnForNoDesignatedInitChain(false), @@ -404,19 +422,21 @@ public: // variables of reference type are captured by reference, and other // variables are captured by copy. enum CaptureKind { - Cap_ByCopy, Cap_ByRef, Cap_Block, Cap_This + Cap_ByCopy, Cap_ByRef, Cap_Block, Cap_VLA + }; + enum { + IsNestedCapture = 0x1, + IsThisCaptured = 0x2 }; - /// The variable being captured (if we are not capturing 'this') and whether - /// this is a nested capture. - llvm::PointerIntPair<VarDecl*, 1, bool> VarAndNested; - + /// this is a nested capture, and whether we are capturing 'this' + llvm::PointerIntPair<VarDecl*, 2> VarAndNestedAndThis; /// Expression to initialize a field of the given type, and the kind of /// capture (if this is a capture and not an init-capture). The expression /// is only required if we are capturing ByVal and the variable's type has /// a non-trivial copy constructor. llvm::PointerIntPair<void *, 2, CaptureKind> InitExprAndCaptureKind; - + /// \brief The source location at which the first capture occurred. SourceLocation Loc; @@ -431,27 +451,28 @@ public: Capture(VarDecl *Var, bool Block, bool ByRef, bool IsNested, SourceLocation Loc, SourceLocation EllipsisLoc, QualType CaptureType, Expr *Cpy) - : VarAndNested(Var, IsNested), - InitExprAndCaptureKind(Cpy, Block ? Cap_Block : - ByRef ? Cap_ByRef : Cap_ByCopy), + : VarAndNestedAndThis(Var, IsNested ? IsNestedCapture : 0), + InitExprAndCaptureKind( + Cpy, !Var ? Cap_VLA : Block ? Cap_Block : ByRef ? Cap_ByRef + : Cap_ByCopy), Loc(Loc), EllipsisLoc(EllipsisLoc), CaptureType(CaptureType) {} enum IsThisCapture { ThisCapture }; Capture(IsThisCapture, bool IsNested, SourceLocation Loc, - QualType CaptureType, Expr *Cpy) - : VarAndNested(nullptr, IsNested), - InitExprAndCaptureKind(Cpy, Cap_This), + QualType CaptureType, Expr *Cpy, const bool ByCopy) + : VarAndNestedAndThis( + nullptr, (IsThisCaptured | (IsNested ? IsNestedCapture : 0))), + InitExprAndCaptureKind(Cpy, ByCopy ? Cap_ByCopy : Cap_ByRef), Loc(Loc), EllipsisLoc(), CaptureType(CaptureType) {} bool isThisCapture() const { - return InitExprAndCaptureKind.getInt() == Cap_This; + return VarAndNestedAndThis.getInt() & IsThisCaptured; } bool isVariableCapture() const { - return InitExprAndCaptureKind.getInt() != Cap_This && !isVLATypeCapture(); + return !isThisCapture() && !isVLATypeCapture(); } bool isCopyCapture() const { - return InitExprAndCaptureKind.getInt() == Cap_ByCopy && - !isVLATypeCapture(); + return InitExprAndCaptureKind.getInt() == Cap_ByCopy; } bool isReferenceCapture() const { return InitExprAndCaptureKind.getInt() == Cap_ByRef; @@ -460,13 +481,14 @@ public: return InitExprAndCaptureKind.getInt() == Cap_Block; } bool isVLATypeCapture() const { - return InitExprAndCaptureKind.getInt() == Cap_ByCopy && - getVariable() == nullptr; + return InitExprAndCaptureKind.getInt() == Cap_VLA; + } + bool isNested() const { + return VarAndNestedAndThis.getInt() & IsNestedCapture; } - bool isNested() const { return VarAndNested.getInt(); } VarDecl *getVariable() const { - return VarAndNested.getPointer(); + return VarAndNestedAndThis.getPointer(); } /// \brief Retrieve the location at which this variable was captured. @@ -479,8 +501,11 @@ public: /// \brief Retrieve the capture type for this capture, which is effectively /// the type of the non-static data member in the lambda/block structure /// that would store this capture. - QualType getCaptureType() const { return CaptureType; } - + QualType getCaptureType() const { + assert(!isThisCapture()); + return CaptureType; + } + Expr *getInitExpr() const { assert(!isVLATypeCapture() && "no init expression for type capture"); return static_cast<Expr *>(InitExprAndCaptureKind.getPointer()); @@ -525,8 +550,11 @@ public: /*Cpy*/ nullptr)); } - void addThisCapture(bool isNested, SourceLocation Loc, QualType CaptureType, - Expr *Cpy); + // Note, we do not need to add the type of 'this' since that is always + // retrievable from Sema::getCurrentThisType - and is also encoded within the + // type of the corresponding FieldDecl. + void addThisCapture(bool isNested, SourceLocation Loc, + Expr *Cpy, bool ByCopy); /// \brief Determine whether the C++ 'this' is captured. bool isCXXThisCaptured() const { return CXXThisCaptureIndex != 0; } @@ -604,14 +632,15 @@ public: /// \brief The implicit parameter for the captured variables. ImplicitParamDecl *ContextParam; /// \brief The kind of captured region. - CapturedRegionKind CapRegionKind; + unsigned short CapRegionKind; + unsigned short OpenMPLevel; CapturedRegionScopeInfo(DiagnosticsEngine &Diag, Scope *S, CapturedDecl *CD, RecordDecl *RD, ImplicitParamDecl *Context, - CapturedRegionKind K) + CapturedRegionKind K, unsigned OpenMPLevel) : CapturingScopeInfo(Diag, ImpCap_CapturedRegion), TheCapturedDecl(CD), TheRecordDecl(RD), TheScope(S), - ContextParam(Context), CapRegionKind(K) + ContextParam(Context), CapRegionKind(K), OpenMPLevel(OpenMPLevel) { Kind = SK_CapturedRegion; } @@ -660,7 +689,7 @@ public: bool ExplicitParams; /// \brief Whether any of the capture expressions requires cleanups. - bool ExprNeedsCleanups; + CleanupInfo Cleanup; /// \brief Whether the lambda contains an unexpanded parameter pack. bool ContainsUnexpandedParameterPack; @@ -708,7 +737,7 @@ public: LambdaScopeInfo(DiagnosticsEngine &Diag) : CapturingScopeInfo(Diag, ImpCap_None), Lambda(nullptr), CallOperator(nullptr), NumExplicitCaptures(0), Mutable(false), - ExplicitParams(false), ExprNeedsCleanups(false), + ExplicitParams(false), Cleanup{}, ContainsUnexpandedParameterPack(false), AutoTemplateParameterDepth(0), GLTemplateParameterList(nullptr) { Kind = SK_Lambda; @@ -846,9 +875,10 @@ void FunctionScopeInfo::recordUseOfWeak(const ExprT *E, bool IsRead) { inline void CapturingScopeInfo::addThisCapture(bool isNested, SourceLocation Loc, - QualType CaptureType, Expr *Cpy) { - Captures.push_back(Capture(Capture::ThisCapture, isNested, Loc, CaptureType, - Cpy)); + Expr *Cpy, + const bool ByCopy) { + Captures.push_back(Capture(Capture::ThisCapture, isNested, Loc, QualType(), + Cpy, ByCopy)); CXXThisCaptureIndex = Captures.size(); } diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index 29aa642a9ab87..25aa805dac4bd 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -16,10 +16,12 @@ #define LLVM_CLANG_SEMA_SEMA_H #include "clang/AST/Attr.h" +#include "clang/AST/Availability.h" #include "clang/AST/DeclarationName.h" #include "clang/AST/Expr.h" #include "clang/AST/ExprObjC.h" #include "clang/AST/ExternalASTSource.h" +#include "clang/AST/LocInfoType.h" #include "clang/AST/MangleNumberingContext.h" #include "clang/AST/NSAPI.h" #include "clang/AST/PrettyPrinter.h" @@ -28,14 +30,15 @@ #include "clang/Basic/LangOptions.h" #include "clang/Basic/Module.h" #include "clang/Basic/OpenMPKinds.h" +#include "clang/Basic/PragmaKinds.h" #include "clang/Basic/Specifiers.h" #include "clang/Basic/TemplateKinds.h" #include "clang/Basic/TypeTraits.h" #include "clang/Sema/AnalysisBasedWarnings.h" +#include "clang/Sema/CleanupInfo.h" #include "clang/Sema/DeclSpec.h" #include "clang/Sema/ExternalSemaSource.h" #include "clang/Sema/IdentifierResolver.h" -#include "clang/Sema/LocInfoType.h" #include "clang/Sema/ObjCMethodList.h" #include "clang/Sema/Ownership.h" #include "clang/Sema/Scope.h" @@ -108,7 +111,6 @@ namespace clang { class EnumConstantDecl; class Expr; class ExtVectorType; - class ExternalSemaSource; class FormatAttr; class FriendDecl; class FunctionDecl; @@ -144,6 +146,8 @@ namespace clang { class ObjCPropertyDecl; class ObjCProtocolDecl; class OMPThreadPrivateDecl; + class OMPDeclareReductionDecl; + class OMPDeclareSimdDecl; class OMPClause; struct OverloadCandidate; class OverloadCandidateSet; @@ -314,50 +318,28 @@ public: /// This is used as part of a hack to omit that class from ADL results. DeclarationName VAListTagName; - /// PackContext - Manages the stack for \#pragma pack. An alignment - /// of 0 indicates default alignment. - void *PackContext; // Really a "PragmaPackStack*" - bool MSStructPragmaOn; // True when \#pragma ms_struct on /// \brief Controls member pointer representation format under the MS ABI. LangOptions::PragmaMSPointersToMembersKind MSPointerToMemberRepresentationMethod; - enum PragmaVtorDispKind { - PVDK_Push, ///< #pragma vtordisp(push, mode) - PVDK_Set, ///< #pragma vtordisp(mode) - PVDK_Pop, ///< #pragma vtordisp(pop) - PVDK_Reset ///< #pragma vtordisp() - }; - - enum PragmaMsStackAction { - PSK_Reset, // #pragma () - PSK_Set, // #pragma ("name") - PSK_Push, // #pragma (push[, id]) - PSK_Push_Set, // #pragma (push[, id], "name") - PSK_Pop, // #pragma (pop[, id]) - PSK_Pop_Set, // #pragma (pop[, id], "name") - }; - - /// \brief Whether to insert vtordisps prior to virtual bases in the Microsoft - /// C++ ABI. Possible values are 0, 1, and 2, which mean: - /// - /// 0: Suppress all vtordisps - /// 1: Insert vtordisps in the presence of vbase overrides and non-trivial - /// structors - /// 2: Always insert vtordisps to support RTTI on partially constructed - /// objects - /// - /// The stack always has at least one element in it. - SmallVector<MSVtorDispAttr::Mode, 2> VtorDispModeStack; - /// Stack of active SEH __finally scopes. Can be empty. SmallVector<Scope*, 2> CurrentSEHFinally; /// \brief Source location for newly created implicit MSInheritanceAttrs SourceLocation ImplicitMSInheritanceAttrLoc; + enum PragmaMsStackAction { + PSK_Reset = 0x0, // #pragma () + PSK_Set = 0x1, // #pragma (value) + PSK_Push = 0x2, // #pragma (push[, id]) + PSK_Pop = 0x4, // #pragma (pop[, id]) + PSK_Show = 0x8, // #pragma (show) -- only for "pack"! + PSK_Push_Set = PSK_Push | PSK_Set, // #pragma (push[, id], value) + PSK_Pop_Set = PSK_Pop | PSK_Set, // #pragma (pop[, id], value) + }; + template<typename ValueType> struct PragmaStack { struct Slot { @@ -374,19 +356,71 @@ public: PragmaMsStackAction Action, llvm::StringRef StackSlotLabel, ValueType Value); - explicit PragmaStack(const ValueType &Value) - : CurrentValue(Value) {} + + // MSVC seems to add artificial slots to #pragma stacks on entering a C++ + // method body to restore the stacks on exit, so it works like this: + // + // struct S { + // #pragma <name>(push, InternalPragmaSlot, <current_pragma_value>) + // void Method {} + // #pragma <name>(pop, InternalPragmaSlot) + // }; + // + // It works even with #pragma vtordisp, although MSVC doesn't support + // #pragma vtordisp(push [, id], n) + // syntax. + // + // Push / pop a named sentinel slot. + void SentinelAction(PragmaMsStackAction Action, StringRef Label) { + assert((Action == PSK_Push || Action == PSK_Pop) && + "Can only push / pop #pragma stack sentinels!"); + Act(CurrentPragmaLocation, Action, Label, CurrentValue); + } + + // Constructors. + explicit PragmaStack(const ValueType &Default) + : DefaultValue(Default), CurrentValue(Default) {} + SmallVector<Slot, 2> Stack; + ValueType DefaultValue; // Value used for PSK_Reset action. ValueType CurrentValue; SourceLocation CurrentPragmaLocation; }; // FIXME: We should serialize / deserialize these if they occur in a PCH (but // we shouldn't do so if they're in a module). + + /// \brief Whether to insert vtordisps prior to virtual bases in the Microsoft + /// C++ ABI. Possible values are 0, 1, and 2, which mean: + /// + /// 0: Suppress all vtordisps + /// 1: Insert vtordisps in the presence of vbase overrides and non-trivial + /// structors + /// 2: Always insert vtordisps to support RTTI on partially constructed + /// objects + PragmaStack<MSVtorDispAttr::Mode> VtorDispStack; + // #pragma pack. + // Sentinel to represent when the stack is set to mac68k alignment. + static const unsigned kMac68kAlignmentSentinel = ~0U; + PragmaStack<unsigned> PackStack; + // Segment #pragmas. PragmaStack<StringLiteral *> DataSegStack; PragmaStack<StringLiteral *> BSSSegStack; PragmaStack<StringLiteral *> ConstSegStack; PragmaStack<StringLiteral *> CodeSegStack; + // RAII object to push / pop sentinel slots for all MS #pragma stacks. + // Actions should be performed only if we enter / exit a C++ method body. + class PragmaStackSentinelRAII { + public: + PragmaStackSentinelRAII(Sema &S, StringRef SlotLabel, bool ShouldAct); + ~PragmaStackSentinelRAII(); + + private: + Sema &S; + StringRef SlotLabel; + bool ShouldAct; + }; + /// A mapping that describes the nullability we've seen in each header file. FileNullabilityMap NullabilityMap; @@ -408,9 +442,8 @@ public: /// if Sema is already doing so, which would cause infinite recursions. bool IsBuildingRecoveryCallExpr; - /// ExprNeedsCleanups - True if the current evaluation context - /// requires cleanups to be run at its conclusion. - bool ExprNeedsCleanups; + /// Used to control the generation of ExprWithCleanups. + CleanupInfo Cleanup; /// ExprCleanupObjects - This is the stack of objects requiring /// cleanup that are created by the current full expression. The @@ -765,6 +798,11 @@ public: /// run time. Unevaluated, + /// \brief The current expression occurs within a discarded statement. + /// This behaves largely similarly to an unevaluated operand in preventing + /// definitions from being required, but not in other ways. + DiscardedStatement, + /// \brief The current expression occurs within an unevaluated /// operand that unconditionally permits abstract references to /// fields, such as a SIZE operator in MS-style inline assembly. @@ -798,7 +836,7 @@ public: ExpressionEvaluationContext Context; /// \brief Whether the enclosing context needed a cleanup. - bool ParentNeedsCleanups; + CleanupInfo ParentCleanup; /// \brief Whether we are in a decltype expression. bool IsDecltype; @@ -839,10 +877,10 @@ public: ExpressionEvaluationContextRecord(ExpressionEvaluationContext Context, unsigned NumCleanupObjects, - bool ParentNeedsCleanups, + CleanupInfo ParentCleanup, Decl *ManglingContextDecl, bool IsDecltype) - : Context(Context), ParentNeedsCleanups(ParentNeedsCleanups), + : Context(Context), ParentCleanup(ParentCleanup), IsDecltype(IsDecltype), NumCleanupObjects(NumCleanupObjects), NumTypos(0), ManglingContextDecl(ManglingContextDecl), MangleNumbering() { } @@ -939,7 +977,7 @@ public: /// UndefinedInternals - all the used, undefined objects which require a /// definition in this translation unit. - llvm::DenseMap<NamedDecl *, SourceLocation> UndefinedButUsed; + llvm::MapVector<NamedDecl *, SourceLocation> UndefinedButUsed; /// Obtain a sorted list of functions that are undefined but ODR-used. void getUndefinedButUsed( @@ -984,6 +1022,7 @@ public: llvm::SmallSet<SpecialMemberDecl, 4> SpecialMembersBeingDeclared; void ReadMethodPool(Selector Sel); + void updateOutOfDateSelector(Selector Sel); /// Private Helper predicate to check for 'self'. bool isSelfExpr(Expr *RExpr); @@ -1008,24 +1047,6 @@ public: bool OldFPContractState : 1; }; - /// Records and restores the vtordisp state on entry/exit of C++ method body. - class VtorDispStackRAII { - public: - VtorDispStackRAII(Sema &S, bool ShouldSaveAndRestore) - : S(S), ShouldSaveAndRestore(ShouldSaveAndRestore), OldVtorDispStack() { - if (ShouldSaveAndRestore) - OldVtorDispStack = S.VtorDispModeStack; - } - ~VtorDispStackRAII() { - if (ShouldSaveAndRestore) - S.VtorDispModeStack = OldVtorDispStack; - } - private: - Sema &S; - bool ShouldSaveAndRestore; - SmallVector<MSVtorDispAttr::Mode, 2> OldVtorDispStack; - }; - void addImplicitTypedef(StringRef Name, QualType T); public: @@ -1388,6 +1409,16 @@ public: bool isVisible(const NamedDecl *D) { return !D->isHidden() || isVisibleSlow(D); } + + /// Determine whether any declaration of an entity is visible. + bool + hasVisibleDeclaration(const NamedDecl *D, + llvm::SmallVectorImpl<Module *> *Modules = nullptr) { + return isVisible(D) || hasVisibleDeclarationSlow(D, Modules); + } + bool hasVisibleDeclarationSlow(const NamedDecl *D, + llvm::SmallVectorImpl<Module *> *Modules); + bool hasVisibleMergedDefinition(NamedDecl *Def); /// Determine if \p D has a visible definition. If not, suggest a declaration @@ -1404,6 +1435,11 @@ public: hasVisibleDefaultArgument(const NamedDecl *D, llvm::SmallVectorImpl<Module *> *Modules = nullptr); + /// Determine if there is a visible declaration of \p D that is a member + /// specialization declaration (as opposed to an instantiated declaration). + bool hasVisibleMemberSpecialization( + const NamedDecl *D, llvm::SmallVectorImpl<Module *> *Modules = nullptr); + /// Determine if \p A and \p B are equivalent internal linkage declarations /// from different modules, and thus an ambiguity error can be downgraded to /// an extension warning. @@ -1485,9 +1521,8 @@ public: ParsedType getTypeName(const IdentifierInfo &II, SourceLocation NameLoc, Scope *S, CXXScopeSpec *SS = nullptr, - bool isClassName = false, - bool HasTrailingDot = false, - ParsedType ObjectType = ParsedType(), + bool isClassName = false, bool HasTrailingDot = false, + ParsedType ObjectType = nullptr, bool IsCtorOrDtorName = false, bool WantNontrivialTypeSourceInfo = false, IdentifierInfo **CorrectedII = nullptr); @@ -1500,12 +1535,13 @@ public: ParsedType &SuggestedType, bool AllowClassTemplates = false); - /// \brief For compatibility with MSVC, we delay parsing of some default - /// template type arguments until instantiation time. Emits a warning and - /// returns a synthesized DependentNameType that isn't really dependent on any - /// other template arguments. - ParsedType ActOnDelayedDefaultTemplateArg(const IdentifierInfo &II, - SourceLocation NameLoc); + /// Attempt to behave like MSVC in situations where lookup of an unqualified + /// type name has failed in a dependent context. In these situations, we + /// automatically form a DependentTypeName that will retry lookup in a related + /// scope during instantiation. + ParsedType ActOnMSVCUnknownTypeName(const IdentifierInfo &II, + SourceLocation NameLoc, + bool IsTemplateTypeArg); /// \brief Describes the result of the name lookup and resolution performed /// by \c ClassifyName(). @@ -1645,12 +1681,24 @@ public: SourceLocation ConstQualLoc = SourceLocation(), SourceLocation VolatileQualLoc = SourceLocation(), SourceLocation RestrictQualLoc = SourceLocation(), - SourceLocation AtomicQualLoc = SourceLocation()); + SourceLocation AtomicQualLoc = SourceLocation(), + SourceLocation UnalignedQualLoc = SourceLocation()); static bool adjustContextForLocalExternDecl(DeclContext *&DC); void DiagnoseFunctionSpecifiers(const DeclSpec &DS); void CheckShadow(Scope *S, VarDecl *D, const LookupResult& R); void CheckShadow(Scope *S, VarDecl *D); + + /// Warn if 'E', which is an expression that is about to be modified, refers + /// to a shadowing declaration. + void CheckShadowingDeclModification(Expr *E, SourceLocation Loc); + +private: + /// Map of current shadowing declarations to shadowed declarations. Warn if + /// it looks like the user is trying to modify the shadowing declaration. + llvm::DenseMap<const NamedDecl *, const NamedDecl *> ShadowingDecls; + +public: void CheckCastAlign(Expr *Op, QualType T, SourceRange TRange); void handleTagNumbering(const TagDecl *Tag, Scope *TagScope); void setTagNameForLinkagePurposes(TagDecl *TagFromDeclSpec, @@ -1772,7 +1820,7 @@ public: Decl *ActOnFinishFunctionBody(Decl *Decl, Stmt *Body); Decl *ActOnFinishFunctionBody(Decl *Decl, Stmt *Body, bool IsInstantiation); Decl *ActOnSkippedFunctionBody(Decl *Decl); - void ActOnFinishInlineMethodDef(CXXMethodDecl *D); + void ActOnFinishInlineFunctionDef(FunctionDecl *D); /// ActOnFinishDelayedAttribute - Invoked when we have finished parsing an /// attribute for which parsing is delayed. @@ -1780,16 +1828,14 @@ public: /// \brief Diagnose any unused parameters in the given sequence of /// ParmVarDecl pointers. - void DiagnoseUnusedParameters(ParmVarDecl * const *Begin, - ParmVarDecl * const *End); + void DiagnoseUnusedParameters(ArrayRef<ParmVarDecl *> Parameters); /// \brief Diagnose whether the size of parameters or return value of a /// function or obj-c method definition is pass-by-value and larger than a /// specified threshold. - void DiagnoseSizeOfParametersAndReturnValue(ParmVarDecl * const *Begin, - ParmVarDecl * const *End, - QualType ReturnTy, - NamedDecl *D); + void + DiagnoseSizeOfParametersAndReturnValue(ArrayRef<ParmVarDecl *> Parameters, + QualType ReturnTy, NamedDecl *D); void DiagnoseInvalidJumps(Stmt *Body); Decl *ActOnFileScopeAsmDecl(Expr *expr, @@ -1838,17 +1884,30 @@ public: enum class MissingImportKind { Declaration, Definition, - DefaultArgument + DefaultArgument, + ExplicitSpecialization, + PartialSpecialization }; /// \brief Diagnose that the specified declaration needs to be visible but /// isn't, and suggest a module import that would resolve the problem. void diagnoseMissingImport(SourceLocation Loc, NamedDecl *Decl, - bool NeedDefinition, bool Recover = true); + MissingImportKind MIK, bool Recover = true); void diagnoseMissingImport(SourceLocation Loc, NamedDecl *Decl, SourceLocation DeclLoc, ArrayRef<Module *> Modules, MissingImportKind MIK, bool Recover); + /// \brief We've found a use of a templated declaration that would trigger an + /// implicit instantiation. Check that any relevant explicit specializations + /// and partial specializations are visible, and diagnose if not. + void checkSpecializationVisibility(SourceLocation Loc, NamedDecl *Spec); + + /// \brief We've found a use of a template specialization that would select a + /// partial specialization. Check that the partial specialization is visible, + /// and diagnose if not. + void checkPartialSpecializationVisibility(SourceLocation Loc, + NamedDecl *Spec); + /// \brief Retrieve a suitable printing policy. PrintingPolicy getPrintingPolicy() const { return getPrintingPolicy(Context, PP); @@ -1862,12 +1921,12 @@ public: void ActOnPopScope(SourceLocation Loc, Scope *S); void ActOnTranslationUnitScope(Scope *S); - Decl *ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS, - DeclSpec &DS); - Decl *ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS, - DeclSpec &DS, + Decl *ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS, DeclSpec &DS, + RecordDecl *&AnonRecord); + Decl *ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS, DeclSpec &DS, MultiTemplateParamsArg TemplateParams, - bool IsExplicitInstantiation = false); + bool IsExplicitInstantiation, + RecordDecl *&AnonRecord); Decl *BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS, AccessSpecifier AS, @@ -1981,7 +2040,7 @@ public: /// ActOnTagFinishDefinition - Invoked once we have finished parsing /// the definition of a tag (enumeration, class, struct, or union). void ActOnTagFinishDefinition(Scope *S, Decl *TagDecl, - SourceLocation RBraceLoc); + SourceRange BraceRange); void ActOnTagFinishSkippedDefinition(SkippedDefinitionContext Context); @@ -2018,8 +2077,8 @@ public: SourceLocation IdLoc, IdentifierInfo *Id, AttributeList *Attrs, SourceLocation EqualLoc, Expr *Val); - void ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc, - SourceLocation RBraceLoc, Decl *EnumDecl, + void ActOnEnumBody(SourceLocation EnumLoc, SourceRange BraceRange, + Decl *EnumDecl, ArrayRef<Decl *> Elements, Scope *S, AttributeList *Attr); @@ -2104,11 +2163,13 @@ public: /// Attribute merging methods. Return true if a new attribute was added. AvailabilityAttr *mergeAvailabilityAttr(NamedDecl *D, SourceRange Range, IdentifierInfo *Platform, + bool Implicit, VersionTuple Introduced, VersionTuple Deprecated, VersionTuple Obsoleted, bool IsUnavailable, StringRef Message, + bool IsStrict, StringRef Replacement, AvailabilityMergeKind AMK, unsigned AttrSpellingListIndex); TypeVisibilityAttr *mergeTypeVisibilityAttr(Decl *D, SourceRange Range, @@ -2189,7 +2250,8 @@ public: const LookupResult &OldDecls, NamedDecl *&OldDecl, bool IsForUsingDecl); - bool IsOverload(FunctionDecl *New, FunctionDecl *Old, bool IsForUsingDecl); + bool IsOverload(FunctionDecl *New, FunctionDecl *Old, bool IsForUsingDecl, + bool ConsiderCudaAttrs = true); /// \brief Checks availability of the function depending on the current /// function context.Inside an unavailable function,unavailability is ignored. @@ -2271,7 +2333,8 @@ public: CCEK_CaseValue, ///< Expression in a case label. CCEK_Enumerator, ///< Enumerator value with fixed underlying type. CCEK_TemplateArg, ///< Value of a non-type template parameter. - CCEK_NewExpr ///< Constant expression in a noptr-new-declarator. + CCEK_NewExpr, ///< Constant expression in a noptr-new-declarator. + CCEK_ConstexprIf ///< Condition in a constexpr if statement. }; ExprResult CheckConvertedConstantExpression(Expr *From, QualType T, llvm::APSInt &Value, CCEKind CCE); @@ -2383,8 +2446,8 @@ public: // Members have to be NamespaceDecl* or TranslationUnitDecl*. // TODO: make this is a typesafe union. - typedef llvm::SmallPtrSet<DeclContext *, 16> AssociatedNamespaceSet; - typedef llvm::SmallPtrSet<CXXRecordDecl *, 16> AssociatedClassSet; + typedef llvm::SmallSetVector<DeclContext *, 16> AssociatedNamespaceSet; + typedef llvm::SmallSetVector<CXXRecordDecl *, 16> AssociatedClassSet; void AddOverloadCandidate(FunctionDecl *Function, DeclAccessPair FoundDecl, @@ -2468,7 +2531,8 @@ public: bool PartialOverloading = false); // Emit as a 'note' the specific overload candidate - void NoteOverloadCandidate(FunctionDecl *Fn, QualType DestType = QualType(), + void NoteOverloadCandidate(NamedDecl *Found, FunctionDecl *Fn, + QualType DestType = QualType(), bool TakingAddress = false); // Emit as a series of 'note's all template and non-templates identified by @@ -2505,6 +2569,12 @@ public: bool *pHadMultipleCandidates = nullptr); FunctionDecl * + resolveAddressOfOnlyViableOverloadCandidate(Expr *E, + DeclAccessPair &FoundResult); + + bool resolveAndFixAddressOfOnlyViableOverloadCandidate(ExprResult &SrcExpr); + + FunctionDecl * ResolveSingleFunctionTemplateSpecialization(OverloadExpr *ovl, bool Complain = false, DeclAccessPair *Found = nullptr); @@ -2594,8 +2664,7 @@ public: CallExpr *CE, FunctionDecl *FD); /// Helpers for dealing with blocks and functions. - bool CheckParmsForFunctionDef(ParmVarDecl *const *Param, - ParmVarDecl *const *ParamEnd, + bool CheckParmsForFunctionDef(ArrayRef<ParmVarDecl *> Parameters, bool CheckParameterNames); void CheckCXXDefaultArguments(FunctionDecl *FD); void CheckExtraCXXDefaultArguments(Declarator &D); @@ -2670,6 +2739,8 @@ public: LookupObjCProtocolName, /// Look up implicit 'self' parameter of an objective-c method. LookupObjCImplicitSelfParam, + /// \brief Look up the name of an OpenMP user-defined reduction operation. + LookupOMPReductionName, /// \brief Look up any declaration with any name. LookupAnyName }; @@ -3145,25 +3216,32 @@ private: public: /// \brief - Returns instance or factory methods in global method pool for - /// given selector. If no such method or only one method found, function returns - /// false; otherwise, it returns true - bool CollectMultipleMethodsInGlobalPool(Selector Sel, - SmallVectorImpl<ObjCMethodDecl*>& Methods, - bool instance); + /// given selector. It checks the desired kind first, if none is found, and + /// parameter checkTheOther is set, it then checks the other kind. If no such + /// method or only one method is found, function returns false; otherwise, it + /// returns true. + bool + CollectMultipleMethodsInGlobalPool(Selector Sel, + SmallVectorImpl<ObjCMethodDecl*>& Methods, + bool InstanceFirst, bool CheckTheOther, + const ObjCObjectType *TypeBound = nullptr); - bool AreMultipleMethodsInGlobalPool(Selector Sel, ObjCMethodDecl *BestMethod, - SourceRange R, - bool receiverIdOrClass); + bool + AreMultipleMethodsInGlobalPool(Selector Sel, ObjCMethodDecl *BestMethod, + SourceRange R, bool receiverIdOrClass, + SmallVectorImpl<ObjCMethodDecl*>& Methods); - void DiagnoseMultipleMethodInGlobalPool(SmallVectorImpl<ObjCMethodDecl*> &Methods, - Selector Sel, SourceRange R, - bool receiverIdOrClass); + void + DiagnoseMultipleMethodInGlobalPool(SmallVectorImpl<ObjCMethodDecl*> &Methods, + Selector Sel, SourceRange R, + bool receiverIdOrClass); private: /// \brief - Returns a selector which best matches given argument list or /// nullptr if none could be found ObjCMethodDecl *SelectBestMethod(Selector Sel, MultiExprArg Args, - bool IsInstance); + bool IsInstance, + SmallVectorImpl<ObjCMethodDecl*>& Methods); /// \brief Record the typo correction failure and return an empty correction. @@ -3224,6 +3302,7 @@ public: public: class FullExprArg { public: + FullExprArg() : E(nullptr) { } FullExprArg(Sema &actions) : E(nullptr) { } ExprResult release() { @@ -3317,27 +3396,30 @@ public: ArrayRef<const Attr*> Attrs, Stmt *SubStmt); - StmtResult ActOnIfStmt(SourceLocation IfLoc, - FullExprArg CondVal, Decl *CondVar, - Stmt *ThenVal, + class ConditionResult; + StmtResult ActOnIfStmt(SourceLocation IfLoc, bool IsConstexpr, + Stmt *InitStmt, + ConditionResult Cond, Stmt *ThenVal, + SourceLocation ElseLoc, Stmt *ElseVal); + StmtResult BuildIfStmt(SourceLocation IfLoc, bool IsConstexpr, + Stmt *InitStmt, + ConditionResult Cond, Stmt *ThenVal, SourceLocation ElseLoc, Stmt *ElseVal); StmtResult ActOnStartOfSwitchStmt(SourceLocation SwitchLoc, - Expr *Cond, - Decl *CondVar); + Stmt *InitStmt, + ConditionResult Cond); StmtResult ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch, Stmt *Body); - StmtResult ActOnWhileStmt(SourceLocation WhileLoc, - FullExprArg Cond, - Decl *CondVar, Stmt *Body); + StmtResult ActOnWhileStmt(SourceLocation WhileLoc, ConditionResult Cond, + Stmt *Body); StmtResult ActOnDoStmt(SourceLocation DoLoc, Stmt *Body, - SourceLocation WhileLoc, - SourceLocation CondLParen, Expr *Cond, - SourceLocation CondRParen); + SourceLocation WhileLoc, SourceLocation CondLParen, + Expr *Cond, SourceLocation CondRParen); StmtResult ActOnForStmt(SourceLocation ForLoc, SourceLocation LParenLoc, - Stmt *First, FullExprArg Second, - Decl *SecondVar, + Stmt *First, + ConditionResult Second, FullExprArg Third, SourceLocation RParenLoc, Stmt *Body); @@ -3368,7 +3450,7 @@ public: StmtResult BuildCXXForRangeStmt(SourceLocation ForLoc, SourceLocation CoawaitLoc, SourceLocation ColonLoc, - Stmt *RangeDecl, Stmt *BeginEndDecl, + Stmt *RangeDecl, Stmt *Begin, Stmt *End, Expr *Cond, Expr *Inc, Stmt *LoopVarDecl, SourceLocation RParenLoc, @@ -3396,9 +3478,9 @@ public: SourceLocation Loc, unsigned NumParams); VarDecl *getCopyElisionCandidate(QualType ReturnType, Expr *E, - bool AllowFunctionParameters); + bool AllowParamOrMoveConstructible); bool isCopyElisionCandidate(QualType ReturnType, const VarDecl *VD, - bool AllowFunctionParameters); + bool AllowParamOrMoveConstructible); StmtResult ActOnReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp, Scope *CurScope); @@ -3551,11 +3633,12 @@ public: //===--------------------------------------------------------------------===// // Expression Parsing Callbacks: SemaExpr.cpp. - bool CanUseDecl(NamedDecl *D); + bool CanUseDecl(NamedDecl *D, bool TreatUnavailableAsInvalid); bool DiagnoseUseOfDecl(NamedDecl *D, SourceLocation Loc, const ObjCInterfaceDecl *UnknownObjCClass=nullptr, bool ObjCPropertyAccess=false); void NoteDeletedFunction(FunctionDecl *FD); + void NoteDeletedInheritingConstructor(CXXConstructorDecl *CD); std::string getDeletedOrUnavailableSuffix(const FunctionDecl *FD); bool DiagnosePropertyAccessorMismatch(ObjCPropertyDecl *PD, ObjCMethodDecl *Getter, @@ -3585,9 +3668,15 @@ public: // for expressions referring to a decl; these exist because odr-use marking // needs to be delayed for some constant variables when we build one of the // named expressions. - void MarkAnyDeclReferenced(SourceLocation Loc, Decl *D, bool OdrUse); + // + // MightBeOdrUse indicates whether the use could possibly be an odr-use, and + // should usually be true. This only needs to be set to false if the lack of + // odr-use cannot be determined from the current context (for instance, + // because the name denotes a virtual function and was written without an + // explicit nested-name-specifier). + void MarkAnyDeclReferenced(SourceLocation Loc, Decl *D, bool MightBeOdrUse); void MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func, - bool OdrUse = true); + bool MightBeOdrUse = true); void MarkVariableReferenced(SourceLocation Loc, VarDecl *Var); void MarkDeclRefReferenced(DeclRefExpr *E); void MarkMemberReferenced(MemberExpr *E); @@ -3970,6 +4059,8 @@ public: ExprResult CreateBuiltinBinOp(SourceLocation OpLoc, BinaryOperatorKind Opc, Expr *LHSExpr, Expr *RHSExpr); + void DiagnoseCommaOperator(const Expr *LHS, SourceLocation Loc); + /// ActOnConditionalOp - Parse a ?: operation. Note that 'LHS' may be null /// in the case of a the GNU conditional expr extension. ExprResult ActOnConditionalOp(SourceLocation QuestionLoc, @@ -4170,6 +4261,13 @@ public: bool CheckInheritingConstructorUsingDecl(UsingDecl *UD); + /// Given a derived-class using shadow declaration for a constructor and the + /// correspnding base class constructor, find or create the implicit + /// synthesized derived class constructor to use for this initialization. + CXXConstructorDecl * + findInheritingConstructor(SourceLocation Loc, CXXConstructorDecl *BaseCtor, + ConstructorUsingShadowDecl *DerivedShadow); + Decl *ActOnUsingDeclaration(Scope *CurScope, AccessSpecifier AS, bool HasUsingKeyword, @@ -4194,16 +4292,29 @@ public: /// \param ConstructKind - a CXXConstructExpr::ConstructionKind ExprResult BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType, + NamedDecl *FoundDecl, CXXConstructorDecl *Constructor, MultiExprArg Exprs, bool HadMultipleCandidates, bool IsListInitialization, bool IsStdInitListInitialization, bool RequiresZeroInit, unsigned ConstructKind, SourceRange ParenRange); + /// Build a CXXConstructExpr whose constructor has already been resolved if + /// it denotes an inherited constructor. + ExprResult + BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType, + CXXConstructorDecl *Constructor, bool Elidable, + MultiExprArg Exprs, + bool HadMultipleCandidates, bool IsListInitialization, + bool IsStdInitListInitialization, + bool RequiresZeroInit, unsigned ConstructKind, + SourceRange ParenRange); + // FIXME: Can we remove this and have the above BuildCXXConstructExpr check if // the constructor can be elidable? ExprResult BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType, + NamedDecl *FoundDecl, CXXConstructorDecl *Constructor, bool Elidable, MultiExprArg Exprs, bool HadMultipleCandidates, bool IsListInitialization, @@ -4323,7 +4434,8 @@ public: /// \brief Determine what sort of exception specification an inheriting /// constructor of a class will have. ImplicitExceptionSpecification - ComputeInheritingCtorExceptionSpec(CXXConstructorDecl *CD); + ComputeInheritingCtorExceptionSpec(SourceLocation Loc, + CXXConstructorDecl *CD); /// \brief Evaluate the implicit exception specification for a defaulted /// special member function. @@ -4353,9 +4465,12 @@ public: ArrayRef<SourceRange> DynamicExceptionRanges, Expr *NoexceptExpr); + class InheritedConstructorInfo; + /// \brief Determine if a special member function should have a deleted /// definition when it is defaulted. bool ShouldDeleteSpecialMember(CXXMethodDecl *MD, CXXSpecialMember CSM, + InheritedConstructorInfo *ICI = nullptr, bool Diagnose = false); /// \brief Declare the implicit default constructor for the given class. @@ -4392,12 +4507,6 @@ public: void AdjustDestructorExceptionSpec(CXXRecordDecl *ClassDecl, CXXDestructorDecl *Destructor); - /// \brief Declare all inheriting constructors for the given class. - /// - /// \param ClassDecl The class declaration into which the inheriting - /// constructors will be added. - void DeclareInheritingConstructors(CXXRecordDecl *ClassDecl); - /// \brief Define the specified inheriting constructor. void DefineInheritingConstructor(SourceLocation UseLoc, CXXConstructorDecl *Constructor); @@ -4458,6 +4567,9 @@ public: /// class. void ForceDeclarationOfImplicitMembers(CXXRecordDecl *Class); + /// \brief Check a completed declaration of an implicit special member. + void CheckImplicitSpecialMemberDeclaration(Scope *S, FunctionDecl *FD); + /// \brief Determine whether the given function is an implicitly-deleted /// special member function. bool isImplicitlyDeleted(FunctionDecl *FD); @@ -4613,7 +4725,8 @@ public: /// \return returns 'true' if failed, 'false' if success. bool CheckCXXThisCapture(SourceLocation Loc, bool Explicit = false, bool BuildAndDiagnose = true, - const unsigned *const FunctionScopeIndexToStopAt = nullptr); + const unsigned *const FunctionScopeIndexToStopAt = nullptr, + bool ByCopy = false); /// \brief Determine whether the given type is the type of *this that is used /// outside of the body of a member function for a type that is currently @@ -4627,6 +4740,10 @@ public: /// ActOnObjCBoolLiteral - Parse {__objc_yes,__objc_no} literals. ExprResult ActOnObjCBoolLiteral(SourceLocation OpLoc, tok::TokenKind Kind); + ExprResult + ActOnObjCAvailabilityCheckExpr(llvm::ArrayRef<AvailabilitySpec> AvailSpecs, + SourceLocation AtLoc, SourceLocation RParen); + /// ActOnCXXNullPtrLiteral - Parse 'nullptr'. ExprResult ActOnCXXNullPtrLiteral(SourceLocation Loc); @@ -4684,8 +4801,7 @@ public: void DeclareGlobalNewDelete(); void DeclareGlobalAllocationFunction(DeclarationName Name, QualType Return, QualType Param1, - QualType Param2 = QualType(), - bool addRestrictAttr = false); + QualType Param2 = QualType()); bool FindDeallocationFunction(SourceLocation StartLoc, CXXRecordDecl *RD, DeclarationName Name, FunctionDecl* &Operator, @@ -4698,11 +4814,10 @@ public: ExprResult ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal, bool ArrayForm, Expr *Operand); - - DeclResult ActOnCXXConditionDeclaration(Scope *S, Declarator &D); - ExprResult CheckConditionVariable(VarDecl *ConditionVar, - SourceLocation StmtLoc, - bool ConvertToBoolean); + void CheckVirtualDtorCall(CXXDestructorDecl *dtor, SourceLocation Loc, + bool IsDelete, bool CallCanBeVirtual, + bool WarnOnNonAbstractTypes, + SourceLocation DtorLoc); ExprResult ActOnNoexceptExpr(SourceLocation KeyLoc, SourceLocation LParen, Expr *Operand, SourceLocation RParen); @@ -4781,6 +4896,10 @@ public: Stmt *MaybeCreateStmtWithCleanups(Stmt *SubStmt); ExprResult MaybeCreateExprWithCleanups(ExprResult SubExpr); + MaterializeTemporaryExpr * + CreateMaterializeTemporaryExpr(QualType T, Expr *Temporary, + bool BoundToLvalueReference); + ExprResult ActOnFinishFullExpr(Expr *Expr) { return ActOnFinishFullExpr(Expr, Expr ? Expr->getExprLoc() : SourceLocation()); @@ -4992,7 +5111,8 @@ public: SourceRange IntroducerRange, TypeSourceInfo *MethodType, SourceLocation EndLoc, - ArrayRef<ParmVarDecl *> Params); + ArrayRef<ParmVarDecl *> Params, + bool IsConstexprSpecified); /// \brief Endow the lambda scope info with the relevant properties. void buildLambdaScope(sema::LambdaScopeInfo *LSI, @@ -5289,11 +5409,18 @@ public: ArrayRef<CXXCtorInitializer*> MemInits, bool AnyErrors); + /// \brief Check class-level dllimport/dllexport attribute. The caller must + /// ensure that referenceDLLExportedClassMethods is called some point later + /// when all outer classes of Class are complete. void checkClassLevelDLLAttribute(CXXRecordDecl *Class); + + void referenceDLLExportedClassMethods(); + void propagateDLLAttrToBaseClassTemplate( CXXRecordDecl *Class, Attr *ClassAttr, ClassTemplateSpecializationDecl *BaseTemplateSpec, SourceLocation BaseLoc); + void CheckCompletedCXXClass(CXXRecordDecl *Record); void ActOnFinishCXXMemberSpecification(Scope* S, SourceLocation RLoc, Decl *TagDecl, @@ -5449,13 +5576,13 @@ public: bool Diagnose = true); AccessResult CheckConstructorAccess(SourceLocation Loc, CXXConstructorDecl *D, + DeclAccessPair FoundDecl, const InitializedEntity &Entity, - AccessSpecifier Access, bool IsCopyBindingRefToTemp = false); AccessResult CheckConstructorAccess(SourceLocation Loc, CXXConstructorDecl *D, + DeclAccessPair FoundDecl, const InitializedEntity &Entity, - AccessSpecifier Access, const PartialDiagnostic &PDiag); AccessResult CheckDestructorAccess(SourceLocation Loc, CXXDestructorDecl *Dtor, @@ -5588,7 +5715,8 @@ public: SourceLocation TemplateLoc, SourceLocation LAngleLoc, ArrayRef<Decl *> Params, - SourceLocation RAngleLoc); + SourceLocation RAngleLoc, + Expr *RequiresClause); /// \brief The context in which we are checking a template parameter list. enum TemplateParamListContext { @@ -6540,6 +6668,10 @@ public: /// \brief The number of template arguments in TemplateArgs. unsigned NumTemplateArgs; + ArrayRef<TemplateArgument> template_arguments() const { + return {TemplateArgs, NumTemplateArgs}; + } + /// \brief The template deduction info object associated with the /// substitution or checking of explicit or deduced template arguments. sema::TemplateDeductionInfo *DeductionInfo; @@ -6614,6 +6746,10 @@ public: /// template defined within it. llvm::DenseSet<Module*> &getLookupModules(); + /// \brief Map from the most recent declaration of a namespace to the most + /// recent visible declaration of that namespace. + llvm::DenseMap<NamedDecl*, NamedDecl*> VisibleNamespaceCache; + /// \brief Whether we are in a SFINAE context that is not associated with /// template instantiation. /// @@ -6965,6 +7101,33 @@ public: SavedPendingLocalImplicitInstantiations; }; + /// A helper class for building up ExtParameterInfos. + class ExtParameterInfoBuilder { + SmallVector<FunctionProtoType::ExtParameterInfo, 16> Infos; + bool HasInteresting = false; + + public: + /// Set the ExtParameterInfo for the parameter at the given index, + /// + void set(unsigned index, FunctionProtoType::ExtParameterInfo info) { + assert(Infos.size() <= index); + Infos.resize(index); + Infos.push_back(info); + + if (!HasInteresting) + HasInteresting = (info != FunctionProtoType::ExtParameterInfo()); + } + + /// Return a pointer (suitable for setting in an ExtProtoInfo) to the + /// ExtParameterInfo array we've built up. + const FunctionProtoType::ExtParameterInfo * + getPointerOrNull(unsigned numParams) { + if (!HasInteresting) return nullptr; + Infos.resize(numParams); + return Infos.data(); + } + }; + void PerformPendingInstantiations(bool LocalOnly = false); TypeSourceInfo *SubstType(TypeSourceInfo *T, @@ -6992,11 +7155,12 @@ public: int indexAdjustment, Optional<unsigned> NumExpansions, bool ExpectParameterPack); - bool SubstParmTypes(SourceLocation Loc, - ParmVarDecl **Params, unsigned NumParams, + bool SubstParmTypes(SourceLocation Loc, ArrayRef<ParmVarDecl *> Params, + const FunctionProtoType::ExtParameterInfo *ExtParamInfos, const MultiLevelTemplateArgumentList &TemplateArgs, SmallVectorImpl<QualType> &ParamTypes, - SmallVectorImpl<ParmVarDecl *> *OutParams = nullptr); + SmallVectorImpl<ParmVarDecl *> *OutParams, + ExtParameterInfoBuilder &ParamInfos); ExprResult SubstExpr(Expr *E, const MultiLevelTemplateArgumentList &TemplateArgs); @@ -7101,7 +7265,8 @@ public: void InstantiateFunctionDefinition(SourceLocation PointOfInstantiation, FunctionDecl *Function, bool Recursive = false, - bool DefinitionRequired = false); + bool DefinitionRequired = false, + bool AtEndOfTU = false); VarTemplateSpecializationDecl *BuildVarTemplateInstantiation( VarTemplateDecl *VarTemplate, VarDecl *FromVar, const TemplateArgumentList &TemplateArgList, @@ -7125,7 +7290,8 @@ public: const MultiLevelTemplateArgumentList &TemplateArgs); void InstantiateVariableDefinition(SourceLocation PointOfInstantiation, VarDecl *Var, bool Recursive = false, - bool DefinitionRequired = false); + bool DefinitionRequired = false, + bool AtEndOfTU = false); void InstantiateStaticDataMemberDefinition( SourceLocation PointOfInstantiation, VarDecl *Var, @@ -7254,6 +7420,12 @@ public: ArrayRef<IdentifierLocPair> ProtocolId, SmallVectorImpl<Decl *> &Protocols); + void DiagnoseTypeArgsAndProtocols(IdentifierInfo *ProtocolId, + SourceLocation ProtocolLoc, + IdentifierInfo *TypeArgId, + SourceLocation TypeArgLoc, + bool SelectProtocolFirst = false); + /// Given a list of identifiers (and their locations), resolve the /// names to either Objective-C protocol qualifiers or type /// arguments, as appropriate. @@ -7348,7 +7520,8 @@ public: bool ImplKind, IdentifierInfo *PropertyId, IdentifierInfo *PropertyIvar, - SourceLocation PropertyIvarLoc); + SourceLocation PropertyIvarLoc, + ObjCPropertyQueryKind QueryKind); enum ObjCSpecialMethodKind { OSMK_None, @@ -7556,41 +7729,17 @@ public: void ActOnPragmaOptionsAlign(PragmaOptionsAlignKind Kind, SourceLocation PragmaLoc); - enum PragmaPackKind { - PPK_Default, // #pragma pack([n]) - PPK_Show, // #pragma pack(show), only supported by MSVC. - PPK_Push, // #pragma pack(push, [identifier], [n]) - PPK_Pop // #pragma pack(pop, [identifier], [n]) - }; - - enum PragmaMSStructKind { - PMSST_OFF, // #pragms ms_struct off - PMSST_ON // #pragms ms_struct on - }; - - enum PragmaMSCommentKind { - PCK_Unknown, - PCK_Linker, // #pragma comment(linker, ...) - PCK_Lib, // #pragma comment(lib, ...) - PCK_Compiler, // #pragma comment(compiler, ...) - PCK_ExeStr, // #pragma comment(exestr, ...) - PCK_User // #pragma comment(user, ...) - }; - /// ActOnPragmaPack - Called on well formed \#pragma pack(...). - void ActOnPragmaPack(PragmaPackKind Kind, - IdentifierInfo *Name, - Expr *Alignment, - SourceLocation PragmaLoc, - SourceLocation LParenLoc, - SourceLocation RParenLoc); + void ActOnPragmaPack(SourceLocation PragmaLoc, PragmaMsStackAction Action, + StringRef SlotLabel, Expr *Alignment); /// ActOnPragmaMSStruct - Called on well formed \#pragma ms_struct [on|off]. void ActOnPragmaMSStruct(PragmaMSStructKind Kind); /// ActOnPragmaMSComment - Called on well formed /// \#pragma comment(kind, "arg"). - void ActOnPragmaMSComment(PragmaMSCommentKind Kind, StringRef Arg); + void ActOnPragmaMSComment(SourceLocation CommentLoc, PragmaMSCommentKind Kind, + StringRef Arg); /// ActOnPragmaMSPointersToMembers - called on well formed \#pragma /// pointers_to_members(representation method[, general purpose @@ -7600,7 +7749,8 @@ public: SourceLocation PragmaLoc); /// \brief Called on well formed \#pragma vtordisp(). - void ActOnPragmaMSVtorDisp(PragmaVtorDispKind Kind, SourceLocation PragmaLoc, + void ActOnPragmaMSVtorDisp(PragmaMsStackAction Action, + SourceLocation PragmaLoc, MSVtorDispAttr::Mode Value); enum PragmaSectionKind { @@ -7636,7 +7786,8 @@ public: void ActOnPragmaDump(Scope *S, SourceLocation Loc, IdentifierInfo *II); /// ActOnPragmaDetectMismatch - Call on well-formed \#pragma detect_mismatch - void ActOnPragmaDetectMismatch(StringRef Name, StringRef Value); + void ActOnPragmaDetectMismatch(SourceLocation Loc, StringRef Name, + StringRef Value); /// ActOnPragmaUnused - Called on well-formed '\#pragma unused'. void ActOnPragmaUnused(const Token &Identifier, @@ -7746,6 +7897,17 @@ public: void AddLaunchBoundsAttr(SourceRange AttrRange, Decl *D, Expr *MaxThreads, Expr *MinBlocks, unsigned SpellingListIndex); + /// AddModeAttr - Adds a mode attribute to a particular declaration. + void AddModeAttr(SourceRange AttrRange, Decl *D, IdentifierInfo *Name, + unsigned SpellingListIndex, bool InInstantiation = false); + + void AddParameterABIAttr(SourceRange AttrRange, Decl *D, + ParameterABI ABI, unsigned SpellingListIndex); + + void AddNSConsumedAttr(SourceRange AttrRange, Decl *D, + unsigned SpellingListIndex, bool isNSConsumed, + bool isTemplateInstantiation); + //===--------------------------------------------------------------------===// // C++ Coroutines TS // @@ -7764,34 +7926,40 @@ public: // private: void *VarDataSharingAttributesStack; + /// Set to true inside '#pragma omp declare target' region. + bool IsInOpenMPDeclareTargetContext = false; /// \brief Initialization of data-sharing attributes stack. void InitDataSharingAttributesStack(); void DestroyDataSharingAttributesStack(); ExprResult VerifyPositiveIntegerConstantInClause(Expr *Op, OpenMPClauseKind CKind, bool StrictlyPositive = true); + /// Returns OpenMP nesting level for current directive. + unsigned getOpenMPNestingLevel() const; public: /// \brief Return true if the provided declaration \a VD should be captured by - /// reference in the provided scope \a RSI. This will take into account the - /// semantics of the directive and associated clauses. - bool IsOpenMPCapturedByRef(VarDecl *VD, - const sema::CapturedRegionScopeInfo *RSI); + /// reference. + /// \param Level Relative level of nested OpenMP construct for that the check + /// is performed. + bool IsOpenMPCapturedByRef(ValueDecl *D, unsigned Level); /// \brief Check if the specified variable is used in one of the private /// clauses (private, firstprivate, lastprivate, reduction etc.) in OpenMP /// constructs. - bool IsOpenMPCapturedVar(VarDecl *VD); + VarDecl *IsOpenMPCapturedDecl(ValueDecl *D); + ExprResult getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, + ExprObjectKind OK, SourceLocation Loc); /// \brief Check if the specified variable is used in 'private' clause. /// \param Level Relative level of nested OpenMP construct for that the check /// is performed. - bool isOpenMPPrivateVar(VarDecl *VD, unsigned Level); + bool isOpenMPPrivateDecl(ValueDecl *D, unsigned Level); /// \brief Check if the specified variable is captured by 'target' directive. /// \param Level Relative level of nested OpenMP construct for that the check /// is performed. - bool isOpenMPTargetCapturedVar(VarDecl *VD, unsigned Level); + bool isOpenMPTargetCapturedDecl(ValueDecl *D, unsigned Level); ExprResult PerformOpenMPImplicitIntegerConversion(SourceLocation OpLoc, Expr *Op); @@ -7826,6 +7994,42 @@ public: OMPThreadPrivateDecl *CheckOMPThreadPrivateDecl( SourceLocation Loc, ArrayRef<Expr *> VarList); + /// \brief Check if the specified type is allowed to be used in 'omp declare + /// reduction' construct. + QualType ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, + TypeResult ParsedType); + /// \brief Called on start of '#pragma omp declare reduction'. + DeclGroupPtrTy ActOnOpenMPDeclareReductionDirectiveStart( + Scope *S, DeclContext *DC, DeclarationName Name, + ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes, + AccessSpecifier AS, Decl *PrevDeclInScope = nullptr); + /// \brief Initialize declare reduction construct initializer. + void ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D); + /// \brief Finish current declare reduction construct initializer. + void ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner); + /// \brief Initialize declare reduction construct initializer. + void ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D); + /// \brief Finish current declare reduction construct initializer. + void ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer); + /// \brief Called at the end of '#pragma omp declare reduction'. + DeclGroupPtrTy ActOnOpenMPDeclareReductionDirectiveEnd( + Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid); + + /// Called on the start of target region i.e. '#pragma omp declare target'. + bool ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc); + /// Called at the end of target region i.e. '#pragme omp end declare target'. + void ActOnFinishOpenMPDeclareTargetDirective(); + /// Called on correct id-expression from the '#pragma omp declare target'. + void ActOnOpenMPDeclareTargetName(Scope *CurScope, CXXScopeSpec &ScopeSpec, + const DeclarationNameInfo &Id, + OMPDeclareTargetDeclAttr::MapTypeTy MT, + NamedDeclSetType &SameDirectiveDecls); + /// Check declaration inside target region. + void checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D); + /// Return true inside OpenMP target region. + bool isInOpenMPDeclareTargetContext() const { + return IsInOpenMPDeclareTargetContext; + } /// \brief Initialization of captured region for OpenMP region. void ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope); @@ -7851,19 +8055,19 @@ public: StmtResult ActOnOpenMPSimdDirective( ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, - llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA); + llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA); /// \brief Called on well-formed '\#pragma omp for' after parsing /// of the associated statement. StmtResult ActOnOpenMPForDirective( ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, - llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA); + llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA); /// \brief Called on well-formed '\#pragma omp for simd' after parsing /// of the associated statement. StmtResult ActOnOpenMPForSimdDirective( ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, - llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA); + llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA); /// \brief Called on well-formed '\#pragma omp sections' after parsing /// of the associated statement. StmtResult ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses, @@ -7893,13 +8097,13 @@ public: StmtResult ActOnOpenMPParallelForDirective( ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, - llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA); + llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA); /// \brief Called on well-formed '\#pragma omp parallel for simd' after /// parsing of the associated statement. StmtResult ActOnOpenMPParallelForSimdDirective( ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, - llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA); + llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA); /// \brief Called on well-formed '\#pragma omp parallel sections' after /// parsing of the associated statement. StmtResult ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses, @@ -7947,6 +8151,28 @@ public: StmtResult ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc); + /// \brief Called on well-formed '\#pragma omp target enter data' after + /// parsing of the associated statement. + StmtResult ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses, + SourceLocation StartLoc, + SourceLocation EndLoc); + /// \brief Called on well-formed '\#pragma omp target exit data' after + /// parsing of the associated statement. + StmtResult ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses, + SourceLocation StartLoc, + SourceLocation EndLoc); + /// \brief Called on well-formed '\#pragma omp target parallel' after + /// parsing of the associated statement. + StmtResult ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses, + Stmt *AStmt, + SourceLocation StartLoc, + SourceLocation EndLoc); + /// \brief Called on well-formed '\#pragma omp target parallel for' after + /// parsing of the associated statement. + StmtResult ActOnOpenMPTargetParallelForDirective( + ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, + SourceLocation EndLoc, + llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA); /// \brief Called on well-formed '\#pragma omp teams' after parsing of the /// associated statement. StmtResult ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses, @@ -7967,19 +8193,63 @@ public: StmtResult ActOnOpenMPTaskLoopDirective( ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, - llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA); + llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA); /// \brief Called on well-formed '\#pragma omp taskloop simd' after parsing of /// the associated statement. StmtResult ActOnOpenMPTaskLoopSimdDirective( ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, - llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA); + llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA); /// \brief Called on well-formed '\#pragma omp distribute' after parsing /// of the associated statement. StmtResult ActOnOpenMPDistributeDirective( ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, - llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA); + llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA); + /// \brief Called on well-formed '\#pragma omp target update'. + StmtResult ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses, + SourceLocation StartLoc, + SourceLocation EndLoc); + /// \brief Called on well-formed '\#pragma omp distribute parallel for' after + /// parsing of the associated statement. + StmtResult ActOnOpenMPDistributeParallelForDirective( + ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, + SourceLocation EndLoc, + llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA); + /// \brief Called on well-formed '\#pragma omp distribute parallel for simd' + /// after parsing of the associated statement. + StmtResult ActOnOpenMPDistributeParallelForSimdDirective( + ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, + SourceLocation EndLoc, + llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA); + /// \brief Called on well-formed '\#pragma omp distribute simd' after + /// parsing of the associated statement. + StmtResult ActOnOpenMPDistributeSimdDirective( + ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, + SourceLocation EndLoc, + llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA); + /// \brief Called on well-formed '\#pragma omp target parallel for simd' after + /// parsing of the associated statement. + StmtResult ActOnOpenMPTargetParallelForSimdDirective( + ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, + SourceLocation EndLoc, + llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA); + + /// Checks correctness of linear modifiers. + bool CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, + SourceLocation LinLoc); + /// Checks that the specified declaration matches requirements for the linear + /// decls. + bool CheckOpenMPLinearDecl(ValueDecl *D, SourceLocation ELoc, + OpenMPLinearClauseKind LinKind, QualType Type); + + /// \brief Called on well-formed '\#pragma omp declare simd' after parsing of + /// the associated method/function. + DeclGroupPtrTy ActOnOpenMPDeclareSimdDirective( + DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, + Expr *Simdlen, ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds, + ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears, + ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR); OMPClause *ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, @@ -8108,7 +8378,8 @@ public: CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, OpenMPDependClauseKind DepKind, OpenMPLinearClauseKind LinKind, OpenMPMapClauseKind MapTypeModifier, - OpenMPMapClauseKind MapType, SourceLocation DepLinMapLoc); + OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, + SourceLocation DepLinMapLoc); /// \brief Called on well-formed 'private' clause. OMPClause *ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, SourceLocation StartLoc, @@ -8130,12 +8401,12 @@ public: SourceLocation LParenLoc, SourceLocation EndLoc); /// \brief Called on well-formed 'reduction' clause. - OMPClause * - ActOnOpenMPReductionClause(ArrayRef<Expr *> VarList, SourceLocation StartLoc, - SourceLocation LParenLoc, SourceLocation ColonLoc, - SourceLocation EndLoc, - CXXScopeSpec &ReductionIdScopeSpec, - const DeclarationNameInfo &ReductionId); + OMPClause *ActOnOpenMPReductionClause( + ArrayRef<Expr *> VarList, SourceLocation StartLoc, + SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, + CXXScopeSpec &ReductionIdScopeSpec, + const DeclarationNameInfo &ReductionId, + ArrayRef<Expr *> UnresolvedReductions = llvm::None); /// \brief Called on well-formed 'linear' clause. OMPClause * ActOnOpenMPLinearClause(ArrayRef<Expr *> VarList, Expr *Step, @@ -8175,10 +8446,12 @@ public: SourceLocation LParenLoc, SourceLocation EndLoc); /// \brief Called on well-formed 'map' clause. - OMPClause *ActOnOpenMPMapClause( - OpenMPMapClauseKind MapTypeModifier, OpenMPMapClauseKind MapType, - SourceLocation MapLoc, SourceLocation ColonLoc, ArrayRef<Expr *> VarList, - SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc); + OMPClause * + ActOnOpenMPMapClause(OpenMPMapClauseKind MapTypeModifier, + OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, + SourceLocation MapLoc, SourceLocation ColonLoc, + ArrayRef<Expr *> VarList, SourceLocation StartLoc, + SourceLocation LParenLoc, SourceLocation EndLoc); /// \brief Called on well-formed 'num_teams' clause. OMPClause *ActOnOpenMPNumTeamsClause(Expr *NumTeams, SourceLocation StartLoc, SourceLocation LParenLoc, @@ -8192,6 +8465,36 @@ public: OMPClause *ActOnOpenMPPriorityClause(Expr *Priority, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc); + /// \brief Called on well-formed 'dist_schedule' clause. + OMPClause *ActOnOpenMPDistScheduleClause( + OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, + SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation KindLoc, + SourceLocation CommaLoc, SourceLocation EndLoc); + /// \brief Called on well-formed 'defaultmap' clause. + OMPClause *ActOnOpenMPDefaultmapClause( + OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, + SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, + SourceLocation KindLoc, SourceLocation EndLoc); + /// \brief Called on well-formed 'to' clause. + OMPClause *ActOnOpenMPToClause(ArrayRef<Expr *> VarList, + SourceLocation StartLoc, + SourceLocation LParenLoc, + SourceLocation EndLoc); + /// \brief Called on well-formed 'from' clause. + OMPClause *ActOnOpenMPFromClause(ArrayRef<Expr *> VarList, + SourceLocation StartLoc, + SourceLocation LParenLoc, + SourceLocation EndLoc); + /// Called on well-formed 'use_device_ptr' clause. + OMPClause *ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList, + SourceLocation StartLoc, + SourceLocation LParenLoc, + SourceLocation EndLoc); + /// Called on well-formed 'is_device_ptr' clause. + OMPClause *ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList, + SourceLocation StartLoc, + SourceLocation LParenLoc, + SourceLocation EndLoc); /// \brief The kind of conversion being performed. enum CheckedConversionKind { @@ -8609,7 +8912,7 @@ public: Expr *CastExpr, SourceLocation RParenLoc); - enum ARCConversionResult { ACR_okay, ACR_unbridged }; + enum ARCConversionResult { ACR_okay, ACR_unbridged, ACR_error }; /// \brief Checks for invalid conversions and casts between /// retainable pointers and other pointer kinds. @@ -8670,6 +8973,60 @@ public: /// type, and if so, emit a note describing what happened. void EmitRelatedResultTypeNoteForReturn(QualType destType); + class ConditionResult { + Decl *ConditionVar; + FullExprArg Condition; + bool Invalid; + bool HasKnownValue; + bool KnownValue; + + friend class Sema; + ConditionResult(Sema &S, Decl *ConditionVar, FullExprArg Condition, + bool IsConstexpr) + : ConditionVar(ConditionVar), Condition(Condition), Invalid(false), + HasKnownValue(IsConstexpr && Condition.get() && + !Condition.get()->isValueDependent()), + KnownValue(HasKnownValue && + !!Condition.get()->EvaluateKnownConstInt(S.Context)) {} + explicit ConditionResult(bool Invalid) + : ConditionVar(nullptr), Condition(nullptr), Invalid(Invalid), + HasKnownValue(false), KnownValue(false) {} + + public: + ConditionResult() : ConditionResult(false) {} + bool isInvalid() const { return Invalid; } + std::pair<VarDecl *, Expr *> get() const { + return std::make_pair(cast_or_null<VarDecl>(ConditionVar), + Condition.get()); + } + llvm::Optional<bool> getKnownValue() const { + if (!HasKnownValue) + return None; + return KnownValue; + } + }; + static ConditionResult ConditionError() { return ConditionResult(true); } + + enum class ConditionKind { + Boolean, ///< A boolean condition, from 'if', 'while', 'for', or 'do'. + ConstexprIf, ///< A constant boolean condition from 'if constexpr'. + Switch ///< An integral condition for a 'switch' statement. + }; + + ConditionResult ActOnCondition(Scope *S, SourceLocation Loc, + Expr *SubExpr, ConditionKind CK); + + ConditionResult ActOnConditionVariable(Decl *ConditionVar, + SourceLocation StmtLoc, + ConditionKind CK); + + DeclResult ActOnCXXConditionDeclaration(Scope *S, Declarator &D); + + ExprResult CheckConditionVariable(VarDecl *ConditionVar, + SourceLocation StmtLoc, + ConditionKind CK); + ExprResult CheckSwitchCondition(SourceLocation SwitchLoc, Expr *Cond); + /// CheckBooleanCondition - Diagnose problems involving the use of /// the given expression as a boolean condition (e.g. in an if /// statement). Also performs the standard function and array @@ -8678,10 +9035,8 @@ public: /// \param Loc - A location associated with the condition, e.g. the /// 'if' keyword. /// \return true iff there were any errors - ExprResult CheckBooleanCondition(Expr *E, SourceLocation Loc); - - ExprResult ActOnBooleanCondition(Scope *S, SourceLocation Loc, - Expr *SubExpr); + ExprResult CheckBooleanCondition(SourceLocation Loc, Expr *E, + bool IsConstexpr = false); /// DiagnoseAssignmentAsCondition - Given that an expression is /// being used as a boolean condition, warn if it's an assignment. @@ -8692,7 +9047,7 @@ public: void DiagnoseEqualityWithExtraParens(ParenExpr *ParenE); /// CheckCXXBooleanCondition - Returns true if conversion to bool is invalid. - ExprResult CheckCXXBooleanCondition(Expr *CondExpr); + ExprResult CheckCXXBooleanCondition(Expr *CondExpr, bool IsConstexpr = false); /// ConvertIntegerToTypeWarnOnOverflow - Convert the specified APInt to have /// the specified width and sign. If an overflow occurs, detect it and emit @@ -8749,12 +9104,18 @@ public: CUDAFunctionTarget IdentifyCUDATarget(const FunctionDecl *D); + // CUDA function call preference. Must be ordered numerically from + // worst to best. enum CUDAFunctionPreference { CFP_Never, // Invalid caller/callee combination. - CFP_LastResort, // Lowest priority. Only in effect if + CFP_WrongSide, // Calls from host-device to host or device + // function that do not match current compilation + // mode. Only in effect if // LangOpts.CUDADisableTargetCallChecks is true. - CFP_Fallback, // Low priority caller/callee combination - CFP_Best, // Preferred caller/callee combination + CFP_HostDevice, // Any calls to host/device functions. + CFP_SameSide, // Calls from host-device to host or device + // function matching current compilation mode. + CFP_Native, // host-to-host or device-to-device calls. }; /// Identifies relative preference of a given Caller/Callee @@ -8767,7 +9128,16 @@ public: CUDAFunctionPreference IdentifyCUDAPreference(const FunctionDecl *Caller, const FunctionDecl *Callee); - bool CheckCUDATarget(const FunctionDecl *Caller, const FunctionDecl *Callee); + /// Determines whether Caller may invoke Callee, based on their CUDA + /// host/device attributes. Returns true if the call is not allowed. + bool CheckCUDATarget(const FunctionDecl *Caller, const FunctionDecl *Callee) { + return IdentifyCUDAPreference(Caller, Callee) == CFP_Never; + } + + /// May add implicit CUDAHostAttr and CUDADeviceAttr attributes to FD, + /// depending on FD and the current compilation settings. + void maybeAddCUDAHostDeviceAttrs(Scope *S, FunctionDecl *FD, + const LookupResult &Previous); /// Finds a function in \p Matches with highest calling priority /// from \p Caller context and erases all functions with lower @@ -8797,6 +9167,11 @@ public: bool ConstRHS, bool Diagnose); + /// \return true if \p CD can be considered empty according to CUDA + /// (E.2.3.1 in CUDA 7.5 Programming guide). + bool isEmptyCudaConstructor(SourceLocation Loc, CXXConstructorDecl *CD); + bool isEmptyCudaDestructor(SourceLocation Loc, CXXDestructorDecl *CD); + /// \name Code completion //@{ /// \brief Describes the context in which code completion occurs. @@ -8861,6 +9236,7 @@ public: void CodeCompletePostfixExpression(Scope *S, ExprResult LHS); void CodeCompleteTag(Scope *S, unsigned TagSpec); void CodeCompleteTypeQualifiers(DeclSpec &DS); + void CodeCompleteBracketDeclarator(Scope *S); void CodeCompleteCase(Scope *S); void CodeCompleteCall(Scope *S, Expr *Fn, ArrayRef<Expr *> Args); void CodeCompleteConstructor(Scope *S, QualType Type, SourceLocation Loc, @@ -9048,13 +9424,6 @@ public: }; static FormatStringType GetFormatStringType(const FormatAttr *Format); - void CheckFormatString(const StringLiteral *FExpr, const Expr *OrigFormatExpr, - ArrayRef<const Expr *> Args, bool HasVAListArg, - unsigned format_idx, unsigned firstDataArg, - FormatStringType Type, bool inFunctionCall, - VariadicCallType CallType, - llvm::SmallBitVector &CheckedVarArgs); - bool FormatStringHasSArg(const StringLiteral *FExpr); static bool GetFormatNSStringIdx(const FormatAttr *Format, unsigned &Idx); @@ -9237,15 +9606,18 @@ public: /// \brief RAII object that enters a new expression evaluation context. class EnterExpressionEvaluationContext { Sema &Actions; + bool Entered = true; public: EnterExpressionEvaluationContext(Sema &Actions, Sema::ExpressionEvaluationContext NewContext, Decl *LambdaContextDecl = nullptr, - bool IsDecltype = false) - : Actions(Actions) { - Actions.PushExpressionEvaluationContext(NewContext, LambdaContextDecl, - IsDecltype); + bool IsDecltype = false, + bool ShouldEnter = true) + : Actions(Actions), Entered(ShouldEnter) { + if (Entered) + Actions.PushExpressionEvaluationContext(NewContext, LambdaContextDecl, + IsDecltype); } EnterExpressionEvaluationContext(Sema &Actions, Sema::ExpressionEvaluationContext NewContext, @@ -9258,7 +9630,8 @@ public: } ~EnterExpressionEvaluationContext() { - Actions.PopExpressionEvaluationContext(); + if (Entered) + Actions.PopExpressionEvaluationContext(); } }; diff --git a/include/clang/Sema/SemaInternal.h b/include/clang/Sema/SemaInternal.h index 60c6598287b7d..76567f3b77f40 100644 --- a/include/clang/Sema/SemaInternal.h +++ b/include/clang/Sema/SemaInternal.h @@ -73,10 +73,11 @@ inline void MarkVarDeclODRUsed(VarDecl *Var, // Keep track of used but undefined variables. // FIXME: We shouldn't suppress this warning for static data members. if (Var->hasDefinition(SemaRef.Context) == VarDecl::DeclarationOnly && - !Var->isExternallyVisible() && - !(Var->isStaticDataMember() && Var->hasInit())) { - SourceLocation &old = SemaRef.UndefinedButUsed[Var->getCanonicalDecl()]; - if (old.isInvalid()) old = Loc; + (!Var->isExternallyVisible() || Var->isInline()) && + !(Var->isStaticDataMember() && Var->hasInit())) { + SourceLocation &old = SemaRef.UndefinedButUsed[Var->getCanonicalDecl()]; + if (old.isInvalid()) + old = Loc; } QualType CaptureType, DeclRefType; SemaRef.tryCaptureVariable(Var, Loc, Sema::TryCapture_Implicit, @@ -216,6 +217,9 @@ public: bool isAddressOfOperand() const { return CorrectionValidator->IsAddressOfOperand; } const CXXScopeSpec *getSS() const { return SS.get(); } Scope *getScope() const { return S; } + CorrectionCandidateCallback *getCorrectionValidator() const { + return CorrectionValidator.get(); + } private: class NamespaceSpecifierSet { diff --git a/include/clang/Sema/SemaLambda.h b/include/clang/Sema/SemaLambda.h index d043e2c459b3c..df40b134f0a7d 100644 --- a/include/clang/Sema/SemaLambda.h +++ b/include/clang/Sema/SemaLambda.h @@ -18,7 +18,7 @@ #include "clang/AST/ASTLambda.h" #include "clang/Sema/ScopeInfo.h" namespace clang { - +class Sema; /// \brief Examines the FunctionScopeInfo stack to determine the nearest /// enclosing lambda (to the current lambda) that is 'capture-capable' for diff --git a/include/clang/Sema/TemplateDeduction.h b/include/clang/Sema/TemplateDeduction.h index c22c703ef7322..ed1e768832cce 100644 --- a/include/clang/Sema/TemplateDeduction.h +++ b/include/clang/Sema/TemplateDeduction.h @@ -244,6 +244,10 @@ struct DeductionFailureInfo { /// TODO: In the future, we may need to unify/generalize this with /// OverloadCandidate. struct TemplateSpecCandidate { + /// \brief The declaration that was looked up, together with its access. + /// Might be a UsingShadowDecl, but usually a FunctionTemplateDecl. + DeclAccessPair FoundDecl; + /// Specialization - The actual specialization that this candidate /// represents. When NULL, this may be a built-in candidate. Decl *Specialization; @@ -251,7 +255,8 @@ struct TemplateSpecCandidate { /// Template argument deduction info DeductionFailureInfo DeductionFailure; - void set(Decl *Spec, DeductionFailureInfo Info) { + void set(DeclAccessPair Found, Decl *Spec, DeductionFailureInfo Info) { + FoundDecl = Found; Specialization = Spec; DeductionFailure = Info; } diff --git a/include/clang/Serialization/ASTBitCodes.h b/include/clang/Serialization/ASTBitCodes.h index 0dfb8cf371464..79c6a06222570 100644 --- a/include/clang/Serialization/ASTBitCodes.h +++ b/include/clang/Serialization/ASTBitCodes.h @@ -175,6 +175,12 @@ namespace clang { : Begin(R.getBegin().getRawEncoding()), End(R.getEnd().getRawEncoding()), BitOffset(BitOffset) { } + SourceLocation getBegin() const { + return SourceLocation::getFromRawEncoding(Begin); + } + SourceLocation getEnd() const { + return SourceLocation::getFromRawEncoding(End); + } }; /// \brief Source range/offset of a preprocessed entity. @@ -191,6 +197,9 @@ namespace clang { void setLocation(SourceLocation L) { Loc = L.getRawEncoding(); } + SourceLocation getLocation() const { + return SourceLocation::getFromRawEncoding(Loc); + } }; /// \brief The number of predefined preprocessed entity IDs. @@ -468,12 +477,7 @@ namespace clang { /// \brief Record code for pending implicit instantiations. PENDING_IMPLICIT_INSTANTIATIONS = 26, - /// \brief Record code for a decl replacement block. - /// - /// If a declaration is modified after having been deserialized, and then - /// written to a dependent AST file, its ID and offset must be added to - /// the replacement block. - DECL_REPLACEMENTS = 27, + // ID 27 used to be for a list of replacement decls. /// \brief Record code for an update to a decl context's lookup table. /// @@ -484,13 +488,10 @@ namespace clang { /// that were modified after being deserialized and need updates. DECL_UPDATE_OFFSETS = 29, - /// \brief Record of updates for a declaration that was modified after - /// being deserialized. - DECL_UPDATES = 30, + // ID 30 used to be a decl update record. These are now in the DECLTYPES + // block. - /// \brief Record code for the table of offsets to CXXBaseSpecifier - /// sets. - CXX_BASE_SPECIFIER_OFFSETS = 31, + // ID 31 used to be a list of offsets to DECL_CXX_BASE_SPECIFIERS records. /// \brief Record code for \#pragma diagnostic mappings. DIAG_PRAGMA_MAPPINGS = 32, @@ -570,12 +571,16 @@ namespace clang { /// \brief Record code for potentially unused local typedef names. UNUSED_LOCAL_TYPEDEF_NAME_CANDIDATES = 52, - /// \brief Record code for the table of offsets to CXXCtorInitializers - /// lists. - CXX_CTOR_INITIALIZERS_OFFSETS = 53, + // ID 53 used to be a table of constructor initializer records. /// \brief Delete expressions that will be analyzed later. - DELETE_EXPRS_TO_ANALYZE = 54 + DELETE_EXPRS_TO_ANALYZE = 54, + + /// \brief Record code for \#pragma ms_struct options. + MSSTRUCT_PRAGMA_OPTIONS = 55, + + /// \brief Record code for \#pragma ms_struct options. + POINTERS_TO_MEMBERS_PRAGMA_OPTIONS = 56 }; /// \brief Record types used within a source manager block. @@ -591,9 +596,12 @@ namespace clang { /// 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 = 4 + SM_SLOC_EXPANSION_ENTRY = 5 }; /// \brief Record types used within a preprocessor block. @@ -772,44 +780,26 @@ namespace clang { PREDEF_TYPE_PSEUDO_OBJECT = 35, /// \brief The placeholder type for builtin functions. PREDEF_TYPE_BUILTIN_FN = 36, - /// \brief OpenCL 1d image type. - PREDEF_TYPE_IMAGE1D_ID = 37, - /// \brief OpenCL 1d image array type. - PREDEF_TYPE_IMAGE1D_ARR_ID = 38, - /// \brief OpenCL 1d image buffer type. - PREDEF_TYPE_IMAGE1D_BUFF_ID = 39, - /// \brief OpenCL 2d image type. - PREDEF_TYPE_IMAGE2D_ID = 40, - /// \brief OpenCL 2d image array type. - PREDEF_TYPE_IMAGE2D_ARR_ID = 41, - /// \brief OpenCL 2d image depth type. - PREDEF_TYPE_IMAGE2D_DEP_ID = 42, - /// \brief OpenCL 2d image array depth type. - PREDEF_TYPE_IMAGE2D_ARR_DEP_ID = 43, - /// \brief OpenCL 2d image MSAA type. - PREDEF_TYPE_IMAGE2D_MSAA_ID = 44, - /// \brief OpenCL 2d image array MSAA type. - PREDEF_TYPE_IMAGE2D_ARR_MSAA_ID = 45, - /// \brief OpenCL 2d image MSAA depth type. - PREDEF_TYPE_IMAGE2D_MSAA_DEP_ID = 46, - /// \brief OpenCL 2d image array MSAA depth type. - PREDEF_TYPE_IMAGE2D_ARR_MSAA_DEPTH_ID = 47, - /// \brief OpenCL 3d image type. - PREDEF_TYPE_IMAGE3D_ID = 48, /// \brief OpenCL event type. - PREDEF_TYPE_EVENT_ID = 49, + PREDEF_TYPE_EVENT_ID = 37, /// \brief OpenCL clk event type. - PREDEF_TYPE_CLK_EVENT_ID = 50, + PREDEF_TYPE_CLK_EVENT_ID = 38, /// \brief OpenCL sampler type. - PREDEF_TYPE_SAMPLER_ID = 51, + PREDEF_TYPE_SAMPLER_ID = 39, /// \brief OpenCL queue type. - PREDEF_TYPE_QUEUE_ID = 52, + PREDEF_TYPE_QUEUE_ID = 40, /// \brief OpenCL ndrange type. - PREDEF_TYPE_NDRANGE_ID = 53, + PREDEF_TYPE_NDRANGE_ID = 41, /// \brief OpenCL reserve_id type. - PREDEF_TYPE_RESERVE_ID_ID = 54, + PREDEF_TYPE_RESERVE_ID_ID = 42, /// \brief The placeholder type for OpenMP array section. - PREDEF_TYPE_OMP_ARRAY_SECTION = 55 + PREDEF_TYPE_OMP_ARRAY_SECTION = 43, + /// \brief The '__float128' type + PREDEF_TYPE_FLOAT128_ID = 44, + /// \brief OpenCL image types with auto numeration +#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ + PREDEF_TYPE_##Id##_ID, +#include "clang/Basic/OpenCLImageTypes.def" }; /// \brief The number of predefined type IDs that are reserved for @@ -824,7 +814,7 @@ namespace clang { /// These constants describe the type records that can occur within a /// block identified by DECLTYPES_BLOCK_ID in the AST file. Each /// constant describes a record for a specific type class in the - /// AST. + /// AST. Note that DeclCode values share this code space. enum TypeCode { /// \brief An ExtQualType record. TYPE_EXT_QUAL = 1, @@ -987,23 +977,37 @@ namespace clang { /// \brief The internal '__make_integer_seq' template. PREDEF_DECL_MAKE_INTEGER_SEQ_ID = 13, + + /// \brief The internal '__NSConstantString' typedef. + PREDEF_DECL_CF_CONSTANT_STRING_ID = 14, + + /// \brief The internal '__NSConstantString' tag type. + PREDEF_DECL_CF_CONSTANT_STRING_TAG_ID = 15, + + /// \brief The internal '__type_pack_element' template. + PREDEF_DECL_TYPE_PACK_ELEMENT_ID = 16, }; /// \brief The number of declaration IDs that are predefined. /// /// For more information about predefined declarations, see the /// \c PredefinedDeclIDs type and the PREDEF_DECL_*_ID constants. - const unsigned int NUM_PREDEF_DECL_IDS = 14; + const unsigned int NUM_PREDEF_DECL_IDS = 17; + + /// \brief Record of updates for a declaration that was modified after + /// being deserialized. This can occur within DECLTYPES_BLOCK_ID. + const unsigned int DECL_UPDATES = 49; /// \brief Record code for a list of local redeclarations of a declaration. + /// This can occur within DECLTYPES_BLOCK_ID. const unsigned int LOCAL_REDECLARATIONS = 50; /// \brief Record codes for each kind of declaration. /// /// These constants describe the declaration records that can occur within - /// a declarations block (identified by DECLS_BLOCK_ID). Each + /// a declarations block (identified by DECLTYPES_BLOCK_ID). Each /// constant describes a record for a specific declaration class - /// in the AST. + /// in the AST. Note that TypeCode values share this code space. enum DeclCode { /// \brief A TypedefDecl record. DECL_TYPEDEF = 51, @@ -1082,6 +1086,8 @@ namespace clang { DECL_USING, /// \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. @@ -1096,6 +1102,8 @@ namespace clang { 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. @@ -1154,6 +1162,14 @@ namespace clang { 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, }; /// \brief Record codes for each kind of statement or expression. @@ -1333,8 +1349,10 @@ namespace clang { STMT_OBJC_AT_THROW, /// \brief An ObjCAutoreleasePoolStmt record. STMT_OBJC_AUTORELEASE_POOL, - /// \brief A ObjCBoolLiteralExpr record. + /// \brief An ObjCBoolLiteralExpr record. EXPR_OBJC_BOOL_LITERAL, + /// \brief An ObjCAvailabilityCheckExpr record. + EXPR_OBJC_AVAILABILITY_CHECK, // C++ @@ -1351,6 +1369,8 @@ namespace clang { 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. @@ -1445,6 +1465,10 @@ namespace clang { STMT_OMP_ATOMIC_DIRECTIVE, STMT_OMP_TARGET_DIRECTIVE, STMT_OMP_TARGET_DATA_DIRECTIVE, + STMT_OMP_TARGET_ENTER_DATA_DIRECTIVE, + STMT_OMP_TARGET_EXIT_DATA_DIRECTIVE, + STMT_OMP_TARGET_PARALLEL_DIRECTIVE, + STMT_OMP_TARGET_PARALLEL_FOR_DIRECTIVE, STMT_OMP_TEAMS_DIRECTIVE, STMT_OMP_TASKGROUP_DIRECTIVE, STMT_OMP_CANCELLATION_POINT_DIRECTIVE, @@ -1452,6 +1476,11 @@ namespace clang { STMT_OMP_TASKLOOP_DIRECTIVE, STMT_OMP_TASKLOOP_SIMD_DIRECTIVE, STMT_OMP_DISTRIBUTE_DIRECTIVE, + STMT_OMP_TARGET_UPDATE_DIRECTIVE, + STMT_OMP_DISTRIBUTE_PARALLEL_FOR_DIRECTIVE, + STMT_OMP_DISTRIBUTE_PARALLEL_FOR_SIMD_DIRECTIVE, + STMT_OMP_DISTRIBUTE_SIMD_DIRECTIVE, + STMT_OMP_TARGET_PARALLEL_FOR_SIMD_DIRECTIVE, EXPR_OMP_ARRAY_SECTION, // ARC diff --git a/include/clang/Serialization/ASTReader.h b/include/clang/Serialization/ASTReader.h index 588a6a978c2d3..1b40494fd43ca 100644 --- a/include/clang/Serialization/ASTReader.h +++ b/include/clang/Serialization/ASTReader.h @@ -27,6 +27,7 @@ #include "clang/Lex/HeaderSearch.h" #include "clang/Lex/PreprocessingRecord.h" #include "clang/Sema/ExternalSemaSource.h" +#include "clang/Sema/IdentifierResolver.h" #include "clang/Serialization/ASTBitCodes.h" #include "clang/Serialization/ContinuousRangeMap.h" #include "clang/Serialization/Module.h" @@ -390,6 +391,11 @@ private: /// \brief The module manager which manages modules and their dependencies ModuleManager ModuleMgr; + /// \brief A dummy identifier resolver used to merge TU-scope declarations in + /// C, for the cases where we don't have a Sema object to provide a real + /// identifier resolver. + IdentifierResolver DummyIdResolver; + /// A mapping from extension block names to module file extensions. llvm::StringMap<IntrusiveRefCntPtr<ModuleFileExtension>> ModuleFileExtensions; @@ -469,21 +475,6 @@ private: /// declaration that has an exception specification. llvm::SmallMapVector<Decl *, FunctionDecl *, 4> PendingExceptionSpecUpdates; - struct ReplacedDeclInfo { - ModuleFile *Mod; - uint64_t Offset; - unsigned RawLoc; - - ReplacedDeclInfo() : Mod(nullptr), Offset(0), RawLoc(0) {} - ReplacedDeclInfo(ModuleFile *Mod, uint64_t Offset, unsigned RawLoc) - : Mod(Mod), Offset(Offset), RawLoc(RawLoc) {} - }; - - typedef llvm::DenseMap<serialization::DeclID, ReplacedDeclInfo> - DeclReplacementMap; - /// \brief Declarations that have been replaced in a later file in the chain. - DeclReplacementMap ReplacedDecls; - /// \brief Declarations that have been imported and have typedef names for /// linkage purposes. llvm::DenseMap<std::pair<DeclContext*, IdentifierInfo*>, NamedDecl*> @@ -668,6 +659,10 @@ private: /// global method pool for this selector. llvm::DenseMap<Selector, unsigned> SelectorGeneration; + /// Whether a selector is out of date. We mark a selector as out of date + /// if we load another module after the method pool entry was pulled in. + llvm::DenseMap<Selector, bool> SelectorOutOfDate; + struct PendingMacroInfo { ModuleFile *M; uint64_t MacroDirectivesOffset; @@ -785,6 +780,13 @@ private: /// \brief The pragma clang optimize location (if the pragma state is "off"). SourceLocation OptimizeOffPragmaLocation; + /// \brief The PragmaMSStructKind pragma ms_struct state if set, or -1. + int PragmaMSStructState; + + /// \brief The PragmaMSPointersToMembersKind pragma pointers_to_members state. + int PragmaMSPointersToMembersState; + SourceLocation PointersToMembersPragmaLocation; + /// \brief The OpenCL extension settings. SmallVector<uint64_t, 1> OpenCLExtensions; @@ -1183,7 +1185,7 @@ private: Decl *getMostRecentExistingDecl(Decl *D); RecordLocation DeclCursorForID(serialization::DeclID ID, - unsigned &RawLocation); + SourceLocation &Location); void loadDeclUpdateRecords(serialization::DeclID ID, Decl *D); void loadPendingDeclChain(Decl *D, uint64_t LocalOffset); void loadObjCCategories(serialization::GlobalDeclID ID, ObjCInterfaceDecl *D, @@ -1364,7 +1366,7 @@ public: /// \param ClientLoadCapabilities The set of client load-failure /// capabilities, represented as a bitset of the enumerators of /// LoadFailureCapabilities. - ASTReadResult ReadAST(const std::string &FileName, ModuleKind Type, + ASTReadResult ReadAST(StringRef FileName, ModuleKind Type, SourceLocation ImportLoc, unsigned ClientLoadCapabilities); @@ -1695,11 +1697,6 @@ public: /// redeclaration chain for \p D. void CompleteRedeclChain(const Decl *D) override; - /// \brief Read a CXXBaseSpecifiers ID form the given record and - /// return its global bit offset. - uint64_t readCXXBaseSpecifiers(ModuleFile &M, const RecordData &Record, - unsigned &Idx); - CXXBaseSpecifier *GetExternalCXXBaseSpecifiers(uint64_t Offset) override; /// \brief Resolve the offset of a statement into a statement. @@ -1794,13 +1791,17 @@ public: /// selector. void ReadMethodPool(Selector Sel) override; + /// Load the contents of the global method pool for a given + /// selector if necessary. + void updateOutOfDateSelector(Selector Sel) override; + /// \brief Load the set of namespaces that are known to the external source, /// which will be used during typo correction. void ReadKnownNamespaces( SmallVectorImpl<NamespaceDecl *> &Namespaces) override; void ReadUndefinedButUsed( - llvm::DenseMap<NamedDecl *, SourceLocation> &Undefined) override; + llvm::MapVector<NamedDecl *, SourceLocation> &Undefined) override; void ReadMismatchingDeleteExpressions(llvm::MapVector< FieldDecl *, llvm::SmallVector<std::pair<SourceLocation, bool>, 4>> & @@ -1979,18 +1980,27 @@ public: ReadCXXCtorInitializers(ModuleFile &F, const RecordData &Record, unsigned &Idx); - /// \brief Read a CXXCtorInitializers ID from the given record and - /// return its global bit offset. - uint64_t ReadCXXCtorInitializersRef(ModuleFile &M, const RecordData &Record, - unsigned &Idx); - /// \brief Read the contents of a CXXCtorInitializer array. CXXCtorInitializer **GetExternalCXXCtorInitializers(uint64_t Offset) override; + /// \brief Read a source location from raw form and return it in its + /// originating module file's source location space. + SourceLocation ReadUntranslatedSourceLocation(uint32_t Raw) const { + return SourceLocation::getFromRawEncoding((Raw >> 1) | (Raw << 31)); + } + /// \brief Read a source location from raw form. - SourceLocation ReadSourceLocation(ModuleFile &ModuleFile, unsigned Raw) const { - SourceLocation Loc = SourceLocation::getFromRawEncoding(Raw); - assert(ModuleFile.SLocRemap.find(Loc.getOffset()) != ModuleFile.SLocRemap.end() && + SourceLocation ReadSourceLocation(ModuleFile &ModuleFile, uint32_t Raw) const { + SourceLocation Loc = ReadUntranslatedSourceLocation(Raw); + return TranslateSourceLocation(ModuleFile, Loc); + } + + /// \brief Translate a source location from another module file's source + /// location space into ours. + SourceLocation TranslateSourceLocation(ModuleFile &ModuleFile, + SourceLocation Loc) const { + assert(ModuleFile.SLocRemap.find(Loc.getOffset()) != + ModuleFile.SLocRemap.end() && "Cannot find offset to remap."); int Remap = ModuleFile.SLocRemap.find(Loc.getOffset())->second; return Loc.getLocWithOffset(Remap); @@ -2096,6 +2106,11 @@ public: /// imported. Sema *getSema() { return SemaObj; } + /// \brief Get the identifier resolver used for name lookup / updates + /// in the translation unit scope. We have one of these even if we don't + /// have a Sema object. + IdentifierResolver &getIdResolver(); + /// \brief Retrieve the identifier table associated with the /// preprocessor. IdentifierTable &getIdentifierTable(); diff --git a/include/clang/Serialization/ASTWriter.h b/include/clang/Serialization/ASTWriter.h index ef8c653413882..bfdb9f2262b50 100644 --- a/include/clang/Serialization/ASTWriter.h +++ b/include/clang/Serialization/ASTWriter.h @@ -90,6 +90,8 @@ public: friend class ASTDeclWriter; friend class ASTStmtWriter; + friend class ASTTypeWriter; + friend class ASTRecordWriter; private: /// \brief Map that provides the ID numbers of each type within the /// output stream, plus those deserialized from a chained PCH. @@ -382,25 +384,6 @@ private: /// should serialize. llvm::SetVector<ObjCInterfaceDecl *> ObjCClassesWithCategories; - struct ReplacedDeclInfo { - serialization::DeclID ID; - uint64_t Offset; - unsigned Loc; - - ReplacedDeclInfo() : ID(0), Offset(0), Loc(0) {} - ReplacedDeclInfo(serialization::DeclID ID, uint64_t Offset, - SourceLocation Loc) - : ID(ID), Offset(Offset), Loc(Loc.getRawEncoding()) {} - }; - - /// \brief Decls that have been replaced in the current dependent AST file. - /// - /// When a decl changes fundamentally after being deserialized (this shouldn't - /// happen, but the ObjC AST nodes are designed this way), it will be - /// serialized again. In this case, it is registered here, so that the reader - /// knows to read the updated version. - SmallVector<ReplacedDeclInfo, 16> ReplacedDecls; - /// \brief The set of declarations that may have redeclaration chains that /// need to be serialized. llvm::SmallVector<const Decl *, 16> Redeclarations; @@ -409,14 +392,6 @@ private: /// redeclaration chains. llvm::DenseMap<const Decl *, const Decl *> FirstLocalDeclCache; - /// \brief Statements that we've encountered while serializing a - /// declaration or type. - SmallVector<Stmt *, 16> StmtsToEmit; - - /// \brief Statements collection to use for ASTWriter::AddStmt(). - /// It will point to StmtsToEmit unless it is overriden. - SmallVector<Stmt *, 16> *CollectedStmts; - /// \brief Mapping from SwitchCase statements to IDs. llvm::DenseMap<SwitchCase *, unsigned> SwitchCaseIDs; @@ -434,62 +409,6 @@ private: /// file. unsigned NumVisibleDeclContexts; - /// \brief The offset of each CXXBaseSpecifier set within the AST. - SmallVector<uint32_t, 16> CXXBaseSpecifiersOffsets; - - /// \brief The first ID number we can use for our own base specifiers. - serialization::CXXBaseSpecifiersID FirstCXXBaseSpecifiersID; - - /// \brief The base specifiers ID that will be assigned to the next new - /// set of C++ base specifiers. - serialization::CXXBaseSpecifiersID NextCXXBaseSpecifiersID; - - /// \brief A set of C++ base specifiers that is queued to be written into the - /// AST file. - struct QueuedCXXBaseSpecifiers { - QueuedCXXBaseSpecifiers() : ID(), Bases(), BasesEnd() { } - - QueuedCXXBaseSpecifiers(serialization::CXXBaseSpecifiersID ID, - CXXBaseSpecifier const *Bases, - CXXBaseSpecifier const *BasesEnd) - : ID(ID), Bases(Bases), BasesEnd(BasesEnd) { } - - serialization::CXXBaseSpecifiersID ID; - CXXBaseSpecifier const * Bases; - CXXBaseSpecifier const * BasesEnd; - }; - - /// \brief Queue of C++ base specifiers to be written to the AST file, - /// in the order they should be written. - SmallVector<QueuedCXXBaseSpecifiers, 2> CXXBaseSpecifiersToWrite; - - /// \brief The offset of each CXXCtorInitializer list within the AST. - SmallVector<uint32_t, 16> CXXCtorInitializersOffsets; - - /// \brief The first ID number we can use for our own ctor initializers. - serialization::CXXCtorInitializersID FirstCXXCtorInitializersID; - - /// \brief The ctor initializers ID that will be assigned to the next new - /// list of C++ ctor initializers. - serialization::CXXCtorInitializersID NextCXXCtorInitializersID; - - /// \brief A set of C++ ctor initializers that is queued to be written - /// into the AST file. - struct QueuedCXXCtorInitializers { - QueuedCXXCtorInitializers() : ID() {} - - QueuedCXXCtorInitializers(serialization::CXXCtorInitializersID ID, - ArrayRef<CXXCtorInitializer*> Inits) - : ID(ID), Inits(Inits) {} - - serialization::CXXCtorInitializersID ID; - ArrayRef<CXXCtorInitializer*> Inits; - }; - - /// \brief Queue of C++ ctor initializers to be written to the AST file, - /// in the order they should be written. - SmallVector<QueuedCXXCtorInitializers, 2> CXXCtorInitializersToWrite; - /// \brief A mapping from each known submodule to its ID number, which will /// be a positive integer. llvm::DenseMap<Module *, unsigned> SubmoduleIDs; @@ -502,9 +421,7 @@ private: unsigned getSubmoduleID(Module *Mod); /// \brief Write the given subexpression to the bitstream. - void WriteSubStmt(Stmt *S, - llvm::DenseMap<Stmt *, uint64_t> &SubStmtEntries, - llvm::DenseSet<Stmt *> &ParentStmts); + void WriteSubStmt(Stmt *S); void WriteBlockInfoBlock(); uint64_t WriteControlBlock(Preprocessor &PP, ASTContext &Context, @@ -520,8 +437,6 @@ private: void WritePragmaDiagnosticMappings(const DiagnosticsEngine &Diag, bool isModule); - void WriteCXXBaseSpecifiersOffsets(); - void WriteCXXCtorInitializersOffsets(); unsigned TypeExtQualAbbrev; unsigned TypeFunctionProtoAbbrev; @@ -542,15 +457,15 @@ private: void WriteReferencedSelectorsPool(Sema &SemaRef); void WriteIdentifierTable(Preprocessor &PP, IdentifierResolver &IdResolver, bool IsModule); - void WriteAttributes(ArrayRef<const Attr*> Attrs, RecordDataImpl &Record); void WriteDeclUpdatesBlocks(RecordDataImpl &OffsetsRecord); - void WriteDeclReplacementsBlock(); void WriteDeclContextVisibleUpdate(const DeclContext *DC); void WriteFPPragmaOptions(const FPOptions &Opts); void WriteOpenCLExtensions(Sema &SemaRef); void WriteObjCCategories(); void WriteLateParsedTemplates(Sema &SemaRef); void WriteOptimizePragmaOptions(Sema &SemaRef); + void WriteMSStructPragmaOptions(Sema &SemaRef); + void WriteMSPointersToMembersPragmaOptions(Sema &SemaRef); void WriteModuleFileExtension(Sema &SemaRef, ModuleFileExtensionWriter &Writer); @@ -573,7 +488,6 @@ private: void WriteDeclAbbrevs(); void WriteDecl(ASTContext &Context, Decl *D); - void AddFunctionDefinition(const FunctionDecl *FD, RecordData &Record); uint64_t WriteASTCore(Sema &SemaRef, StringRef isysroot, const std::string &OutputFile, @@ -621,29 +535,9 @@ public: /// \brief Emit a source range. void AddSourceRange(SourceRange Range, RecordDataImpl &Record); - /// \brief Emit an integral value. - void AddAPInt(const llvm::APInt &Value, RecordDataImpl &Record); - - /// \brief Emit a signed integral value. - void AddAPSInt(const llvm::APSInt &Value, RecordDataImpl &Record); - - /// \brief Emit a floating-point value. - void AddAPFloat(const llvm::APFloat &Value, RecordDataImpl &Record); - /// \brief Emit a reference to an identifier. void AddIdentifierRef(const IdentifierInfo *II, RecordDataImpl &Record); - /// \brief Emit a Selector (which is a smart pointer reference). - void AddSelectorRef(Selector, RecordDataImpl &Record); - - /// \brief Emit a CXXTemporary. - void AddCXXTemporary(const CXXTemporary *Temp, RecordDataImpl &Record); - - /// \brief Emit a set of C++ base specifiers to the record. - void AddCXXBaseSpecifiersRef(CXXBaseSpecifier const *Bases, - CXXBaseSpecifier const *BasesEnd, - RecordDataImpl &Record); - /// \brief Get the unique number used to refer to the given selector. serialization::SelectorID getSelectorRef(Selector Sel); @@ -667,30 +561,21 @@ public: /// \brief Determine the type ID of an already-emitted type. serialization::TypeID getTypeID(QualType T) const; - /// \brief Emits a reference to a declarator info. - void AddTypeSourceInfo(TypeSourceInfo *TInfo, RecordDataImpl &Record); - - /// \brief Emits a type with source-location information. - void AddTypeLoc(TypeLoc TL, RecordDataImpl &Record); - - /// \brief Emits a template argument location info. - void AddTemplateArgumentLocInfo(TemplateArgument::ArgKind Kind, - const TemplateArgumentLocInfo &Arg, - RecordDataImpl &Record); - - /// \brief Emits a template argument location. - void AddTemplateArgumentLoc(const TemplateArgumentLoc &Arg, - RecordDataImpl &Record); - - /// \brief Emits an AST template argument list info. - void AddASTTemplateArgumentListInfo( - const ASTTemplateArgumentListInfo *ASTTemplArgList, - RecordDataImpl &Record); - /// \brief Find the first local declaration of a given local redeclarable /// decl. const Decl *getFirstLocalDecl(const Decl *D); + /// \brief Is this a local declaration (that is, one that will be written to + /// our AST file)? This is the case for declarations that are neither imported + /// from another AST file nor predefined. + bool IsLocalDecl(const Decl *D) { + if (D->isFromASTFile()) + return false; + auto I = DeclIDs.find(D); + return (I == DeclIDs.end() || + I->second >= serialization::NUM_PREDEF_DECL_IDS); + }; + /// \brief Emit a reference to a declaration. void AddDeclRef(const Decl *D, RecordDataImpl &Record); @@ -702,57 +587,8 @@ public: /// declaration. serialization::DeclID getDeclID(const Decl *D); - /// \brief Emit a declaration name. - void AddDeclarationName(DeclarationName Name, RecordDataImpl &Record); - void AddDeclarationNameLoc(const DeclarationNameLoc &DNLoc, - DeclarationName Name, RecordDataImpl &Record); - void AddDeclarationNameInfo(const DeclarationNameInfo &NameInfo, - RecordDataImpl &Record); unsigned getAnonymousDeclarationNumber(const NamedDecl *D); - void AddQualifierInfo(const QualifierInfo &Info, RecordDataImpl &Record); - - /// \brief Emit a nested name specifier. - void AddNestedNameSpecifier(NestedNameSpecifier *NNS, RecordDataImpl &Record); - - /// \brief Emit a nested name specifier with source-location information. - void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS, - RecordDataImpl &Record); - - /// \brief Emit a template name. - void AddTemplateName(TemplateName Name, RecordDataImpl &Record); - - /// \brief Emit a template argument. - void AddTemplateArgument(const TemplateArgument &Arg, RecordDataImpl &Record); - - /// \brief Emit a template parameter list. - void AddTemplateParameterList(const TemplateParameterList *TemplateParams, - RecordDataImpl &Record); - - /// \brief Emit a template argument list. - void AddTemplateArgumentList(const TemplateArgumentList *TemplateArgs, - RecordDataImpl &Record); - - /// \brief Emit a UnresolvedSet structure. - void AddUnresolvedSet(const ASTUnresolvedSet &Set, RecordDataImpl &Record); - - /// \brief Emit a C++ base specifier. - void AddCXXBaseSpecifier(const CXXBaseSpecifier &Base, - RecordDataImpl &Record); - - /// \brief Emit the ID for a CXXCtorInitializer array and register the array - /// for later serialization. - void AddCXXCtorInitializersRef(ArrayRef<CXXCtorInitializer *> Inits, - RecordDataImpl &Record); - - /// \brief Emit a CXXCtorInitializer array. - void AddCXXCtorInitializers( - const CXXCtorInitializer * const *CtorInitializers, - unsigned NumCtorInitializers, - RecordDataImpl &Record); - - void AddCXXDefinitionData(const CXXRecordDecl *D, RecordDataImpl &Record); - /// \brief Add a string to the given record. void AddString(StringRef Str, RecordDataImpl &Record); @@ -787,38 +623,6 @@ public: /// within the method pool/selector table. void SetSelectorOffset(Selector Sel, uint32_t Offset); - /// \brief Add the given statement or expression to the queue of - /// statements to emit. - /// - /// This routine should be used when emitting types and declarations - /// that have expressions as part of their formulation. Once the - /// type or declaration has been written, call FlushStmts() to write - /// the corresponding statements just after the type or - /// declaration. - void AddStmt(Stmt *S) { - CollectedStmts->push_back(S); - } - - /// \brief Flush all of the statements and expressions that have - /// been added to the queue via AddStmt(). - void FlushStmts(); - - /// \brief Flush all of the C++ base specifier sets that have been added - /// via \c AddCXXBaseSpecifiersRef(). - void FlushCXXBaseSpecifiers(); - - /// \brief Flush all of the C++ constructor initializer lists that have been - /// added via \c AddCXXCtorInitializersRef(). - void FlushCXXCtorInitializers(); - - /// \brief Flush all pending records that are tacked onto the end of - /// decl and decl update records. - void FlushPendingAfterDecl() { - FlushStmts(); - FlushCXXBaseSpecifiers(); - FlushCXXCtorInitializers(); - } - /// \brief Record an ID for the given switch-case statement. unsigned RecordSwitchCaseID(SwitchCase *S); @@ -851,6 +655,7 @@ public: bool hasChain() const { return Chain; } ASTReader *getChain() const { return Chain; } +private: // ASTDeserializationListener implementation void ReaderInitialized(ASTReader *Reader) override; void IdentifierRead(serialization::IdentID ID, IdentifierInfo *II) override; @@ -877,11 +682,230 @@ public: const ObjCInterfaceDecl *IFD) override; void DeclarationMarkedUsed(const Decl *D) override; void DeclarationMarkedOpenMPThreadPrivate(const Decl *D) override; + void DeclarationMarkedOpenMPDeclareTarget(const Decl *D, + const Attr *Attr) override; void RedefinedHiddenDefinition(const NamedDecl *D, Module *M) override; void AddedAttributeToRecord(const Attr *Attr, const RecordDecl *Record) override; }; +/// \brief An object for streaming information to a record. +class ASTRecordWriter { + ASTWriter *Writer; + ASTWriter::RecordDataImpl *Record; + + /// \brief Statements that we've encountered while serializing a + /// declaration or type. + SmallVector<Stmt *, 16> StmtsToEmit; + + /// \brief Indices of record elements that describe offsets within the + /// bitcode. These will be converted to offsets relative to the current + /// record when emitted. + SmallVector<unsigned, 8> OffsetIndices; + + /// \brief Flush all of the statements and expressions that have + /// been added to the queue via AddStmt(). + void FlushStmts(); + void FlushSubStmts(); + + void PrepareToEmit(uint64_t MyOffset) { + // Convert offsets into relative form. + for (unsigned I : OffsetIndices) { + auto &StoredOffset = (*Record)[I]; + assert(StoredOffset < MyOffset && "invalid offset"); + if (StoredOffset) + StoredOffset = MyOffset - StoredOffset; + } + OffsetIndices.clear(); + } + +public: + /// Construct a ASTRecordWriter that uses the default encoding scheme. + ASTRecordWriter(ASTWriter &Writer, ASTWriter::RecordDataImpl &Record) + : Writer(&Writer), Record(&Record) {} + + /// Construct a ASTRecordWriter that uses the same encoding scheme as another + /// ASTRecordWriter. + ASTRecordWriter(ASTRecordWriter &Parent, ASTWriter::RecordDataImpl &Record) + : Writer(Parent.Writer), Record(&Record) {} + + /// Copying an ASTRecordWriter is almost certainly a bug. + ASTRecordWriter(const ASTRecordWriter&) = delete; + void operator=(const ASTRecordWriter&) = delete; + + /// \brief Extract the underlying record storage. + ASTWriter::RecordDataImpl &getRecordData() const { return *Record; } + + /// \brief Minimal vector-like interface. + /// @{ + void push_back(uint64_t N) { Record->push_back(N); } + template<typename InputIterator> + void append(InputIterator begin, InputIterator end) { + Record->append(begin, end); + } + bool empty() const { return Record->empty(); } + size_t size() const { return Record->size(); } + uint64_t &operator[](size_t N) { return (*Record)[N]; } + /// @} + + /// \brief Emit the record to the stream, followed by its substatements, and + /// return its offset. + // FIXME: Allow record producers to suggest Abbrevs. + uint64_t Emit(unsigned Code, unsigned Abbrev = 0) { + uint64_t Offset = Writer->Stream.GetCurrentBitNo(); + PrepareToEmit(Offset); + Writer->Stream.EmitRecord(Code, *Record, Abbrev); + FlushStmts(); + return Offset; + } + + /// \brief Emit the record to the stream, preceded by its substatements. + uint64_t EmitStmt(unsigned Code, unsigned Abbrev = 0) { + FlushSubStmts(); + PrepareToEmit(Writer->Stream.GetCurrentBitNo()); + Writer->Stream.EmitRecord(Code, *Record, Abbrev); + return Writer->Stream.GetCurrentBitNo(); + } + + /// \brief Add a bit offset into the record. This will be converted into an + /// offset relative to the current record when emitted. + void AddOffset(uint64_t BitOffset) { + OffsetIndices.push_back(Record->size()); + Record->push_back(BitOffset); + } + + /// \brief Add the given statement or expression to the queue of + /// statements to emit. + /// + /// This routine should be used when emitting types and declarations + /// that have expressions as part of their formulation. Once the + /// type or declaration has been written, Emit() will write + /// the corresponding statements just after the record. + void AddStmt(Stmt *S) { + StmtsToEmit.push_back(S); + } + + /// \brief Add a definition for the given function to the queue of statements + /// to emit. + void AddFunctionDefinition(const FunctionDecl *FD); + + /// \brief Emit a source location. + void AddSourceLocation(SourceLocation Loc) { + return Writer->AddSourceLocation(Loc, *Record); + } + + /// \brief Emit a source range. + void AddSourceRange(SourceRange Range) { + return Writer->AddSourceRange(Range, *Record); + } + + /// \brief Emit an integral value. + void AddAPInt(const llvm::APInt &Value); + + /// \brief Emit a signed integral value. + void AddAPSInt(const llvm::APSInt &Value); + + /// \brief Emit a floating-point value. + void AddAPFloat(const llvm::APFloat &Value); + + /// \brief Emit a reference to an identifier. + void AddIdentifierRef(const IdentifierInfo *II) { + return Writer->AddIdentifierRef(II, *Record); + } + + /// \brief Emit a Selector (which is a smart pointer reference). + void AddSelectorRef(Selector S); + + /// \brief Emit a CXXTemporary. + void AddCXXTemporary(const CXXTemporary *Temp); + + /// \brief Emit a C++ base specifier. + void AddCXXBaseSpecifier(const CXXBaseSpecifier &Base); + + /// \brief Emit a set of C++ base specifiers. + void AddCXXBaseSpecifiers(ArrayRef<CXXBaseSpecifier> Bases); + + /// \brief Emit a reference to a type. + void AddTypeRef(QualType T) { + return Writer->AddTypeRef(T, *Record); + } + + /// \brief Emits a reference to a declarator info. + void AddTypeSourceInfo(TypeSourceInfo *TInfo); + + /// \brief Emits a type with source-location information. + void AddTypeLoc(TypeLoc TL); + + /// \brief Emits a template argument location info. + void AddTemplateArgumentLocInfo(TemplateArgument::ArgKind Kind, + const TemplateArgumentLocInfo &Arg); + + /// \brief Emits a template argument location. + void AddTemplateArgumentLoc(const TemplateArgumentLoc &Arg); + + /// \brief Emits an AST template argument list info. + void AddASTTemplateArgumentListInfo( + const ASTTemplateArgumentListInfo *ASTTemplArgList); + + /// \brief Emit a reference to a declaration. + void AddDeclRef(const Decl *D) { + return Writer->AddDeclRef(D, *Record); + } + + /// \brief Emit a declaration name. + void AddDeclarationName(DeclarationName Name); + + void AddDeclarationNameLoc(const DeclarationNameLoc &DNLoc, + DeclarationName Name); + void AddDeclarationNameInfo(const DeclarationNameInfo &NameInfo); + + void AddQualifierInfo(const QualifierInfo &Info); + + /// \brief Emit a nested name specifier. + void AddNestedNameSpecifier(NestedNameSpecifier *NNS); + + /// \brief Emit a nested name specifier with source-location information. + void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS); + + /// \brief Emit a template name. + void AddTemplateName(TemplateName Name); + + /// \brief Emit a template argument. + void AddTemplateArgument(const TemplateArgument &Arg); + + /// \brief Emit a template parameter list. + void AddTemplateParameterList(const TemplateParameterList *TemplateParams); + + /// \brief Emit a template argument list. + void AddTemplateArgumentList(const TemplateArgumentList *TemplateArgs); + + /// \brief Emit a UnresolvedSet structure. + void AddUnresolvedSet(const ASTUnresolvedSet &Set); + + /// \brief Emit a CXXCtorInitializer array. + void AddCXXCtorInitializers(ArrayRef<CXXCtorInitializer*> CtorInits); + + void AddCXXDefinitionData(const CXXRecordDecl *D); + + /// \brief Emit a string. + void AddString(StringRef Str) { + return Writer->AddString(Str, *Record); + } + + /// \brief Emit a path. + void AddPath(StringRef Path) { + return Writer->AddPath(Path, *Record); + } + + /// \brief Emit a version tuple. + void AddVersionTuple(const VersionTuple &Version) { + return Writer->AddVersionTuple(Version, *Record); + } + + /// \brief Emit a list of attributes. + void AddAttributes(ArrayRef<const Attr*> Attrs); +}; + /// \brief AST and semantic-analysis consumer that generates a /// precompiled header from the parsed source code. class PCHGenerator : public SemaConsumer { diff --git a/include/clang/Serialization/Makefile b/include/clang/Serialization/Makefile deleted file mode 100644 index 386f453761750..0000000000000 --- a/include/clang/Serialization/Makefile +++ /dev/null @@ -1,19 +0,0 @@ -CLANG_LEVEL := ../../.. -TD_SRC_DIR = $(PROJ_SRC_DIR)/../Basic -BUILT_SOURCES = AttrPCHRead.inc AttrPCHWrite.inc - -TABLEGEN_INC_FILES_COMMON = 1 - -include $(CLANG_LEVEL)/Makefile - -$(ObjDir)/AttrPCHRead.inc.tmp : $(TD_SRC_DIR)/Attr.td $(CLANG_TBLGEN) \ - $(ObjDir)/.dir - $(Echo) "Building Clang PCH reader with tblgen" - $(Verb) $(ClangTableGen) -gen-clang-attr-pch-read -o $(call SYSPATH, $@) \ - -I $(PROJ_SRC_DIR)/../../ $< - -$(ObjDir)/AttrPCHWrite.inc.tmp : $(TD_SRC_DIR)/Attr.td $(CLANG_TBLGEN) \ - $(ObjDir)/.dir - $(Echo) "Building Clang PCH writer with tblgen" - $(Verb) $(ClangTableGen) -gen-clang-attr-pch-write -o $(call SYSPATH, $@) \ - -I $(PROJ_SRC_DIR)/../../ $< diff --git a/include/clang/Serialization/Module.h b/include/clang/Serialization/Module.h index d6d16a0230441..aa0392f0ecfb2 100644 --- a/include/clang/Serialization/Module.h +++ b/include/clang/Serialization/Module.h @@ -399,20 +399,6 @@ public: /// as a local ID (for this module file). llvm::DenseMap<ModuleFile *, serialization::DeclID> GlobalToLocalDeclIDs; - /// \brief The number of C++ base specifier sets in this AST file. - unsigned LocalNumCXXBaseSpecifiers; - - /// \brief Offset of each C++ base specifier set within the bitstream, - /// indexed by the C++ base specifier set ID (-1). - const uint32_t *CXXBaseSpecifiersOffsets; - - /// \brief The number of C++ ctor initializer lists in this AST file. - unsigned LocalNumCXXCtorInitializers; - - /// \brief Offset of each C++ ctor initializer list within the bitstream, - /// indexed by the C++ ctor initializer list ID minus 1. - const uint32_t *CXXCtorInitializersOffsets; - /// \brief Array of file-level DeclIDs sorted by file. const serialization::DeclID *FileSortedDecls; unsigned NumFileSortedDecls; diff --git a/include/clang/StaticAnalyzer/Checkers/CMakeLists.txt b/include/clang/StaticAnalyzer/Checkers/CMakeLists.txt new file mode 100644 index 0000000000000..37dd9e8482968 --- /dev/null +++ b/include/clang/StaticAnalyzer/Checkers/CMakeLists.txt @@ -0,0 +1,4 @@ +clang_tablegen(Checkers.inc -gen-clang-sa-checkers + -I ${CMAKE_CURRENT_SOURCE_DIR}/../../../ + SOURCE Checkers.td + TARGET ClangSACheckers) diff --git a/include/clang/StaticAnalyzer/Checkers/Checkers.td b/include/clang/StaticAnalyzer/Checkers/Checkers.td new file mode 100644 index 0000000000000..785e064e72a99 --- /dev/null +++ b/include/clang/StaticAnalyzer/Checkers/Checkers.td @@ -0,0 +1,659 @@ +//===--- Checkers.td - Static Analyzer Checkers -===-----------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +include "clang/StaticAnalyzer/Checkers/CheckerBase.td" + +//===----------------------------------------------------------------------===// +// Packages. +//===----------------------------------------------------------------------===// + +// The Alpha package is for checkers that have too many false positives to be +// turned on by default. The hierarchy under Alpha should be organized in the +// hierarchy checkers would have had if they were truly at the top level. +// (For example, a Cocoa-specific checker that is alpha should be in +// alpha.osx.cocoa). +def Alpha : Package<"alpha">; + +def Core : Package<"core">; +def CoreBuiltin : Package<"builtin">, InPackage<Core>; +def CoreUninitialized : Package<"uninitialized">, InPackage<Core>; +def CoreAlpha : Package<"core">, InPackage<Alpha>, Hidden; + +// The OptIn package is for checkers that are not alpha and that would normally +// be on by default but where the driver does not have enough information to +// determine when they are applicable. For example, localizability checkers fit +// this criterion because the driver cannot determine whether a project is +// localized or not -- this is best determined at the IDE or build-system level. +// +// The checker hierarchy under OptIn should mirror that in Alpha: checkers +// should be organized as if they were at the top level. +// +// Note: OptIn is *not* intended for checkers that are too noisy to be on by +// default. Such checkers belong in the alpha package. +def OptIn : Package<"optin">; + +def Nullability : Package<"nullability">; + +def Cplusplus : Package<"cplusplus">; +def CplusplusAlpha : Package<"cplusplus">, InPackage<Alpha>, Hidden; + +def DeadCode : Package<"deadcode">; +def DeadCodeAlpha : Package<"deadcode">, InPackage<Alpha>, Hidden; + +def Performance : Package<"performance">, InPackage<OptIn>; + +def Security : Package <"security">; +def InsecureAPI : Package<"insecureAPI">, InPackage<Security>; +def SecurityAlpha : Package<"security">, InPackage<Alpha>, Hidden; +def Taint : Package<"taint">, InPackage<SecurityAlpha>, Hidden; + +def Unix : Package<"unix">; +def UnixAlpha : Package<"unix">, InPackage<Alpha>, Hidden; +def CString : Package<"cstring">, InPackage<Unix>, Hidden; +def CStringAlpha : Package<"cstring">, InPackage<UnixAlpha>, Hidden; + +def OSX : Package<"osx">; +def OSXAlpha : Package<"osx">, InPackage<Alpha>, Hidden; +def OSXOptIn : Package<"osx">, InPackage<OptIn>; + +def Cocoa : Package<"cocoa">, InPackage<OSX>; +def CocoaAlpha : Package<"cocoa">, InPackage<OSXAlpha>, Hidden; +def CocoaOptIn : Package<"cocoa">, InPackage<OSXOptIn>; + +def CoreFoundation : Package<"coreFoundation">, InPackage<OSX>; +def Containers : Package<"containers">, InPackage<CoreFoundation>; + +def LocalizabilityAlpha : Package<"localizability">, InPackage<CocoaAlpha>; +def LocalizabilityOptIn : Package<"localizability">, InPackage<CocoaOptIn>; + +def MPI : Package<"mpi">, InPackage<OptIn>; + +def LLVM : Package<"llvm">; +def Debug : Package<"debug">; + +//===----------------------------------------------------------------------===// +// Core Checkers. +//===----------------------------------------------------------------------===// + +let ParentPackage = Core in { + +def DereferenceChecker : Checker<"NullDereference">, + HelpText<"Check for dereferences of null pointers">, + DescFile<"DereferenceChecker.cpp">; + +def CallAndMessageChecker : Checker<"CallAndMessage">, + HelpText<"Check for logical errors for function calls and Objective-C message expressions (e.g., uninitialized arguments, null function pointers)">, + DescFile<"CallAndMessageChecker.cpp">; + +def NonNullParamChecker : Checker<"NonNullParamChecker">, + HelpText<"Check for null pointers passed as arguments to a function whose arguments are references or marked with the 'nonnull' attribute">, + DescFile<"NonNullParamChecker.cpp">; + +def VLASizeChecker : Checker<"VLASize">, + HelpText<"Check for declarations of VLA of undefined or zero size">, + DescFile<"VLASizeChecker.cpp">; + +def DivZeroChecker : Checker<"DivideZero">, + HelpText<"Check for division by zero">, + DescFile<"DivZeroChecker.cpp">; + +def UndefResultChecker : Checker<"UndefinedBinaryOperatorResult">, + HelpText<"Check for undefined results of binary operators">, + DescFile<"UndefResultChecker.cpp">; + +def StackAddrEscapeChecker : Checker<"StackAddressEscape">, + HelpText<"Check that addresses to stack memory do not escape the function">, + DescFile<"StackAddrEscapeChecker.cpp">; + +def DynamicTypePropagation : Checker<"DynamicTypePropagation">, + HelpText<"Generate dynamic type information">, + DescFile<"DynamicTypePropagation.cpp">; + +} // end "core" + +let ParentPackage = CoreAlpha in { + +def BoolAssignmentChecker : Checker<"BoolAssignment">, + HelpText<"Warn about assigning non-{0,1} values to Boolean variables">, + DescFile<"BoolAssignmentChecker.cpp">; + +def CastSizeChecker : Checker<"CastSize">, + HelpText<"Check when casting a malloc'ed type T, whether the size is a multiple of the size of T">, + DescFile<"CastSizeChecker.cpp">; + +def CastToStructChecker : Checker<"CastToStruct">, + HelpText<"Check for cast from non-struct pointer to struct pointer">, + DescFile<"CastToStructChecker.cpp">; + +def IdenticalExprChecker : Checker<"IdenticalExpr">, + HelpText<"Warn about unintended use of identical expressions in operators">, + DescFile<"IdenticalExprChecker.cpp">; + +def FixedAddressChecker : Checker<"FixedAddr">, + HelpText<"Check for assignment of a fixed address to a pointer">, + DescFile<"FixedAddressChecker.cpp">; + +def PointerArithChecker : Checker<"PointerArithm">, + HelpText<"Check for pointer arithmetic on locations other than array elements">, + DescFile<"PointerArithChecker">; + +def PointerSubChecker : Checker<"PointerSub">, + HelpText<"Check for pointer subtractions on two pointers pointing to different memory chunks">, + DescFile<"PointerSubChecker">; + +def SizeofPointerChecker : Checker<"SizeofPtr">, + HelpText<"Warn about unintended use of sizeof() on pointer expressions">, + DescFile<"CheckSizeofPointer.cpp">; + +def CallAndMessageUnInitRefArg : Checker<"CallAndMessageUnInitRefArg">, + HelpText<"Check for logical errors for function calls and Objective-C message expressions (e.g., uninitialized arguments, null function pointers, and pointer to undefined variables)">, + DescFile<"CallAndMessageChecker.cpp">; + +def TestAfterDivZeroChecker : Checker<"TestAfterDivZero">, + HelpText<"Check for division by variable that is later compared against 0. Either the comparison is useless or there is division by zero.">, + DescFile<"TestAfterDivZeroChecker.cpp">; + +def DynamicTypeChecker : Checker<"DynamicTypeChecker">, + HelpText<"Check for cases where the dynamic and the static type of an object are unrelated.">, + DescFile<"DynamicTypeChecker.cpp">; + +} // end "alpha.core" + +let ParentPackage = Nullability in { + +def NullPassedToNonnullChecker : Checker<"NullPassedToNonnull">, + HelpText<"Warns when a null pointer is passed to a pointer which has a _Nonnull type.">, + DescFile<"NullabilityChecker.cpp">; + +def NullReturnedFromNonnullChecker : Checker<"NullReturnedFromNonnull">, + HelpText<"Warns when a null pointer is returned from a function that has _Nonnull return type.">, + DescFile<"NullabilityChecker.cpp">; + +def NullableDereferencedChecker : Checker<"NullableDereferenced">, + HelpText<"Warns when a nullable pointer is dereferenced.">, + DescFile<"NullabilityChecker.cpp">; + +def NullablePassedToNonnullChecker : Checker<"NullablePassedToNonnull">, + HelpText<"Warns when a nullable pointer is passed to a pointer which has a _Nonnull type.">, + DescFile<"NullabilityChecker.cpp">; + +def NullableReturnedFromNonnullChecker : Checker<"NullablePassedToNonnull">, + HelpText<"Warns when a nullable pointer is returned from a function that has _Nonnull return type.">, + DescFile<"NullabilityChecker.cpp">; + +} // end "nullability" + +//===----------------------------------------------------------------------===// +// Evaluate "builtin" functions. +//===----------------------------------------------------------------------===// + +let ParentPackage = CoreBuiltin in { + +def NoReturnFunctionChecker : Checker<"NoReturnFunctions">, + HelpText<"Evaluate \"panic\" functions that are known to not return to the caller">, + DescFile<"NoReturnFunctionChecker.cpp">; + +def BuiltinFunctionChecker : Checker<"BuiltinFunctions">, + HelpText<"Evaluate compiler builtin functions (e.g., alloca())">, + DescFile<"BuiltinFunctionChecker.cpp">; + +} // end "core.builtin" + +//===----------------------------------------------------------------------===// +// Uninitialized values checkers. +//===----------------------------------------------------------------------===// + +let ParentPackage = CoreUninitialized in { + +def UndefinedArraySubscriptChecker : Checker<"ArraySubscript">, + HelpText<"Check for uninitialized values used as array subscripts">, + DescFile<"UndefinedArraySubscriptChecker.cpp">; + +def UndefinedAssignmentChecker : Checker<"Assign">, + HelpText<"Check for assigning uninitialized values">, + DescFile<"UndefinedAssignmentChecker.cpp">; + +def UndefBranchChecker : Checker<"Branch">, + HelpText<"Check for uninitialized values used as branch conditions">, + DescFile<"UndefBranchChecker.cpp">; + +def UndefCapturedBlockVarChecker : Checker<"CapturedBlockVariable">, + HelpText<"Check for blocks that capture uninitialized values">, + DescFile<"UndefCapturedBlockVarChecker.cpp">; + +def ReturnUndefChecker : Checker<"UndefReturn">, + HelpText<"Check for uninitialized values being returned to the caller">, + DescFile<"ReturnUndefChecker.cpp">; + +} // end "core.uninitialized" + +//===----------------------------------------------------------------------===// +// C++ checkers. +//===----------------------------------------------------------------------===// + +let ParentPackage = Cplusplus in { + +def NewDeleteChecker : Checker<"NewDelete">, + HelpText<"Check for double-free and use-after-free problems. Traces memory managed by new/delete.">, + DescFile<"MallocChecker.cpp">; + +def NewDeleteLeaksChecker : Checker<"NewDeleteLeaks">, + HelpText<"Check for memory leaks. Traces memory managed by new/delete.">, + DescFile<"MallocChecker.cpp">; + +} // end: "cplusplus" + +let ParentPackage = CplusplusAlpha in { + +def VirtualCallChecker : Checker<"VirtualCall">, + HelpText<"Check virtual function calls during construction or destruction">, + DescFile<"VirtualCallChecker.cpp">; + +} // end: "alpha.cplusplus" + +//===----------------------------------------------------------------------===// +// Deadcode checkers. +//===----------------------------------------------------------------------===// + +let ParentPackage = DeadCode in { + +def DeadStoresChecker : Checker<"DeadStores">, + HelpText<"Check for values stored to variables that are never read afterwards">, + DescFile<"DeadStoresChecker.cpp">; +} // end DeadCode + +let ParentPackage = DeadCodeAlpha in { + +def UnreachableCodeChecker : Checker<"UnreachableCode">, + HelpText<"Check unreachable code">, + DescFile<"UnreachableCodeChecker.cpp">; + +} // end "alpha.deadcode" + +//===----------------------------------------------------------------------===// +// Performance checkers. +//===----------------------------------------------------------------------===// + +let ParentPackage = Performance in { + +def PaddingChecker : Checker<"Padding">, + HelpText<"Check for excessively padded structs.">, + DescFile<"PaddingChecker.cpp">; + +} // end: "padding" + +//===----------------------------------------------------------------------===// +// Security checkers. +//===----------------------------------------------------------------------===// + +let ParentPackage = InsecureAPI in { + def gets : Checker<"gets">, + HelpText<"Warn on uses of the 'gets' function">, + DescFile<"CheckSecuritySyntaxOnly.cpp">; + def getpw : Checker<"getpw">, + HelpText<"Warn on uses of the 'getpw' function">, + DescFile<"CheckSecuritySyntaxOnly.cpp">; + def mktemp : Checker<"mktemp">, + HelpText<"Warn on uses of the 'mktemp' function">, + DescFile<"CheckSecuritySyntaxOnly.cpp">; + def mkstemp : Checker<"mkstemp">, + HelpText<"Warn when 'mkstemp' is passed fewer than 6 X's in the format string">, + DescFile<"CheckSecuritySyntaxOnly.cpp">; + def rand : Checker<"rand">, + HelpText<"Warn on uses of the 'rand', 'random', and related functions">, + DescFile<"CheckSecuritySyntaxOnly.cpp">; + def strcpy : Checker<"strcpy">, + HelpText<"Warn on uses of the 'strcpy' and 'strcat' functions">, + DescFile<"CheckSecuritySyntaxOnly.cpp">; + def vfork : Checker<"vfork">, + HelpText<"Warn on uses of the 'vfork' function">, + DescFile<"CheckSecuritySyntaxOnly.cpp">; + def UncheckedReturn : Checker<"UncheckedReturn">, + HelpText<"Warn on uses of functions whose return values must be always checked">, + DescFile<"CheckSecuritySyntaxOnly.cpp">; +} +let ParentPackage = Security in { + def FloatLoopCounter : Checker<"FloatLoopCounter">, + HelpText<"Warn on using a floating point value as a loop counter (CERT: FLP30-C, FLP30-CPP)">, + DescFile<"CheckSecuritySyntaxOnly.cpp">; +} + +let ParentPackage = SecurityAlpha in { + +def ArrayBoundChecker : Checker<"ArrayBound">, + HelpText<"Warn about buffer overflows (older checker)">, + DescFile<"ArrayBoundChecker.cpp">; + +def ArrayBoundCheckerV2 : Checker<"ArrayBoundV2">, + HelpText<"Warn about buffer overflows (newer checker)">, + DescFile<"ArrayBoundCheckerV2.cpp">; + +def ReturnPointerRangeChecker : Checker<"ReturnPtrRange">, + HelpText<"Check for an out-of-bound pointer being returned to callers">, + DescFile<"ReturnPointerRangeChecker.cpp">; + +def MallocOverflowSecurityChecker : Checker<"MallocOverflow">, + HelpText<"Check for overflows in the arguments to malloc()">, + DescFile<"MallocOverflowSecurityChecker.cpp">; + +} // end "alpha.security" + +//===----------------------------------------------------------------------===// +// Taint checkers. +//===----------------------------------------------------------------------===// + +let ParentPackage = Taint in { + +def GenericTaintChecker : Checker<"TaintPropagation">, + HelpText<"Generate taint information used by other checkers">, + DescFile<"GenericTaintChecker.cpp">; + +} // end "alpha.security.taint" + +//===----------------------------------------------------------------------===// +// Unix API checkers. +//===----------------------------------------------------------------------===// + +let ParentPackage = Unix in { + +def UnixAPIChecker : Checker<"API">, + HelpText<"Check calls to various UNIX/Posix functions">, + DescFile<"UnixAPIChecker.cpp">; + +def MallocChecker: Checker<"Malloc">, + HelpText<"Check for memory leaks, double free, and use-after-free problems. Traces memory managed by malloc()/free().">, + DescFile<"MallocChecker.cpp">; + +def MallocSizeofChecker : Checker<"MallocSizeof">, + HelpText<"Check for dubious malloc arguments involving sizeof">, + DescFile<"MallocSizeofChecker.cpp">; + +def MismatchedDeallocatorChecker : Checker<"MismatchedDeallocator">, + HelpText<"Check for mismatched deallocators.">, + DescFile<"MallocChecker.cpp">; + +def VforkChecker : Checker<"Vfork">, + HelpText<"Check for proper usage of vfork">, + DescFile<"VforkChecker.cpp">; + +} // end "unix" + +let ParentPackage = UnixAlpha in { + +def ChrootChecker : Checker<"Chroot">, + HelpText<"Check improper use of chroot">, + DescFile<"ChrootChecker.cpp">; + +def PthreadLockChecker : Checker<"PthreadLock">, + HelpText<"Simple lock -> unlock checker">, + DescFile<"PthreadLockChecker.cpp">; + +def StreamChecker : Checker<"Stream">, + HelpText<"Check stream handling functions">, + DescFile<"StreamChecker.cpp">; + +def SimpleStreamChecker : Checker<"SimpleStream">, + HelpText<"Check for misuses of stream APIs">, + DescFile<"SimpleStreamChecker.cpp">; + +} // end "alpha.unix" + +let ParentPackage = CString in { + +def CStringNullArg : Checker<"NullArg">, + HelpText<"Check for null pointers being passed as arguments to C string functions">, + DescFile<"CStringChecker.cpp">; + +def CStringSyntaxChecker : Checker<"BadSizeArg">, + HelpText<"Check the size argument passed into C string functions for common erroneous patterns">, + DescFile<"CStringSyntaxChecker.cpp">; +} + +let ParentPackage = CStringAlpha in { + +def CStringOutOfBounds : Checker<"OutOfBounds">, + HelpText<"Check for out-of-bounds access in string functions">, + DescFile<"CStringChecker.cpp">; + +def CStringBufferOverlap : Checker<"BufferOverlap">, + HelpText<"Checks for overlap in two buffer arguments">, + DescFile<"CStringChecker.cpp">; + +def CStringNotNullTerm : Checker<"NotNullTerminated">, + HelpText<"Check for arguments which are not null-terminating strings">, + DescFile<"CStringChecker.cpp">; +} + +//===----------------------------------------------------------------------===// +// Mac OS X, Cocoa, and Core Foundation checkers. +//===----------------------------------------------------------------------===// + +let ParentPackage = OSX in { + +def MacOSXAPIChecker : Checker<"API">, + InPackage<OSX>, + HelpText<"Check for proper uses of various Apple APIs">, + DescFile<"MacOSXAPIChecker.cpp">; + +def MacOSKeychainAPIChecker : Checker<"SecKeychainAPI">, + InPackage<OSX>, + HelpText<"Check for proper uses of Secure Keychain APIs">, + DescFile<"MacOSKeychainAPIChecker.cpp">; + +} // end "osx" + +let ParentPackage = Cocoa in { + +def ObjCAtSyncChecker : Checker<"AtSync">, + HelpText<"Check for nil pointers used as mutexes for @synchronized">, + DescFile<"ObjCAtSyncChecker.cpp">; + +def NilArgChecker : Checker<"NilArg">, + HelpText<"Check for prohibited nil arguments to ObjC method calls">, + DescFile<"BasicObjCFoundationChecks.cpp">; + +def ClassReleaseChecker : Checker<"ClassRelease">, + HelpText<"Check for sending 'retain', 'release', or 'autorelease' directly to a Class">, + DescFile<"BasicObjCFoundationChecks.cpp">; + +def VariadicMethodTypeChecker : Checker<"VariadicMethodTypes">, + HelpText<"Check for passing non-Objective-C types to variadic collection " + "initialization methods that expect only Objective-C types">, + DescFile<"BasicObjCFoundationChecks.cpp">; + +def NSAutoreleasePoolChecker : Checker<"NSAutoreleasePool">, + HelpText<"Warn for suboptimal uses of NSAutoreleasePool in Objective-C GC mode">, + DescFile<"NSAutoreleasePoolChecker.cpp">; + +def ObjCMethSigsChecker : Checker<"IncompatibleMethodTypes">, + HelpText<"Warn about Objective-C method signatures with type incompatibilities">, + DescFile<"CheckObjCInstMethSignature.cpp">; + +def ObjCUnusedIvarsChecker : Checker<"UnusedIvars">, + HelpText<"Warn about private ivars that are never used">, + DescFile<"ObjCUnusedIVarsChecker.cpp">; + +def ObjCSelfInitChecker : Checker<"SelfInit">, + HelpText<"Check that 'self' is properly initialized inside an initializer method">, + DescFile<"ObjCSelfInitChecker.cpp">; + +def ObjCLoopChecker : Checker<"Loops">, + HelpText<"Improved modeling of loops using Cocoa collection types">, + DescFile<"BasicObjCFoundationChecks.cpp">; + +def ObjCNonNilReturnValueChecker : Checker<"NonNilReturnValue">, + HelpText<"Model the APIs that are guaranteed to return a non-nil value">, + DescFile<"BasicObjCFoundationChecks.cpp">; + +def ObjCSuperCallChecker : Checker<"MissingSuperCall">, + HelpText<"Warn about Objective-C methods that lack a necessary call to super">, + DescFile<"ObjCMissingSuperCallChecker.cpp">; + +def NSErrorChecker : Checker<"NSError">, + HelpText<"Check usage of NSError** parameters">, + DescFile<"NSErrorChecker.cpp">; + +def RetainCountChecker : Checker<"RetainCount">, + HelpText<"Check for leaks and improper reference count management">, + DescFile<"RetainCountChecker.cpp">; + +def ObjCGenericsChecker : Checker<"ObjCGenerics">, + HelpText<"Check for type errors when using Objective-C generics">, + DescFile<"DynamicTypePropagation.cpp">; + +def ObjCDeallocChecker : Checker<"Dealloc">, + HelpText<"Warn about Objective-C classes that lack a correct implementation of -dealloc">, + DescFile<"CheckObjCDealloc.cpp">; + +def ObjCSuperDeallocChecker : Checker<"SuperDealloc">, + HelpText<"Warn about improper use of '[super dealloc]' in Objective-C">, + DescFile<"ObjCSuperDeallocChecker.cpp">; + +} // end "osx.cocoa" + +let ParentPackage = CocoaAlpha in { + +def InstanceVariableInvalidation : Checker<"InstanceVariableInvalidation">, + HelpText<"Check that the invalidatable instance variables are invalidated in the methods annotated with objc_instance_variable_invalidator">, + DescFile<"IvarInvalidationChecker.cpp">; + +def MissingInvalidationMethod : Checker<"MissingInvalidationMethod">, + HelpText<"Check that the invalidation methods are present in classes that contain invalidatable instance variables">, + DescFile<"IvarInvalidationChecker.cpp">; + +def DirectIvarAssignment : Checker<"DirectIvarAssignment">, + HelpText<"Check for direct assignments to instance variables">, + DescFile<"DirectIvarAssignment.cpp">; + +def DirectIvarAssignmentForAnnotatedFunctions : Checker<"DirectIvarAssignmentForAnnotatedFunctions">, + HelpText<"Check for direct assignments to instance variables in the methods annotated with objc_no_direct_instance_variable_assignment">, + DescFile<"DirectIvarAssignment.cpp">; + +} // end "alpha.osx.cocoa" + +let ParentPackage = CoreFoundation in { + +def CFNumberCreateChecker : Checker<"CFNumber">, + HelpText<"Check for proper uses of CFNumberCreate">, + DescFile<"BasicObjCFoundationChecks.cpp">; + +def CFRetainReleaseChecker : Checker<"CFRetainRelease">, + HelpText<"Check for null arguments to CFRetain/CFRelease/CFMakeCollectable">, + DescFile<"BasicObjCFoundationChecks.cpp">; + +def CFErrorChecker : Checker<"CFError">, + HelpText<"Check usage of CFErrorRef* parameters">, + DescFile<"NSErrorChecker.cpp">; +} + +let ParentPackage = Containers in { +def ObjCContainersASTChecker : Checker<"PointerSizedValues">, + HelpText<"Warns if 'CFArray', 'CFDictionary', 'CFSet' are created with non-pointer-size values">, + DescFile<"ObjCContainersASTChecker.cpp">; + +def ObjCContainersChecker : Checker<"OutOfBounds">, + HelpText<"Checks for index out-of-bounds when using 'CFArray' API">, + DescFile<"ObjCContainersChecker.cpp">; + +} + +let ParentPackage = LocalizabilityOptIn in { +def NonLocalizedStringChecker : Checker<"NonLocalizedStringChecker">, + HelpText<"Warns about uses of non-localized NSStrings passed to UI methods expecting localized NSStrings">, + DescFile<"LocalizationChecker.cpp">; + +def EmptyLocalizationContextChecker : Checker<"EmptyLocalizationContextChecker">, + HelpText<"Check that NSLocalizedString macros include a comment for context">, + DescFile<"LocalizationChecker.cpp">; +} + +let ParentPackage = LocalizabilityAlpha in { +def PluralMisuseChecker : Checker<"PluralMisuseChecker">, + HelpText<"Warns against using one vs. many plural pattern in code when generating localized strings.">, + DescFile<"LocalizationChecker.cpp">; +} + +let ParentPackage = MPI in { + def MPIChecker : Checker<"MPI-Checker">, + HelpText<"Checks MPI code">, + DescFile<"MPIChecker.cpp">; +} + +//===----------------------------------------------------------------------===// +// Checkers for LLVM development. +//===----------------------------------------------------------------------===// + +def LLVMConventionsChecker : Checker<"Conventions">, + InPackage<LLVM>, + HelpText<"Check code for LLVM codebase conventions">, + DescFile<"LLVMConventionsChecker.cpp">; + +//===----------------------------------------------------------------------===// +// Debugging checkers (for analyzer development). +//===----------------------------------------------------------------------===// + +let ParentPackage = Debug in { + +def DominatorsTreeDumper : Checker<"DumpDominators">, + HelpText<"Print the dominance tree for a given CFG">, + DescFile<"DebugCheckers.cpp">; + +def LiveVariablesDumper : Checker<"DumpLiveVars">, + HelpText<"Print results of live variable analysis">, + DescFile<"DebugCheckers.cpp">; + +def CFGViewer : Checker<"ViewCFG">, + HelpText<"View Control-Flow Graphs using GraphViz">, + DescFile<"DebugCheckers.cpp">; + +def CFGDumper : Checker<"DumpCFG">, + HelpText<"Display Control-Flow Graphs">, + DescFile<"DebugCheckers.cpp">; + +def CallGraphViewer : Checker<"ViewCallGraph">, + HelpText<"View Call Graph using GraphViz">, + DescFile<"DebugCheckers.cpp">; + +def CallGraphDumper : Checker<"DumpCallGraph">, + HelpText<"Display Call Graph">, + DescFile<"DebugCheckers.cpp">; + +def ConfigDumper : Checker<"ConfigDumper">, + HelpText<"Dump config table">, + DescFile<"DebugCheckers.cpp">; + +def TraversalDumper : Checker<"DumpTraversal">, + HelpText<"Print branch conditions as they are traversed by the engine">, + DescFile<"TraversalChecker.cpp">; + +def CallDumper : Checker<"DumpCalls">, + HelpText<"Print calls as they are traversed by the engine">, + DescFile<"TraversalChecker.cpp">; + +def AnalyzerStatsChecker : Checker<"Stats">, + HelpText<"Emit warnings with analyzer statistics">, + DescFile<"AnalyzerStatsChecker.cpp">; + +def TaintTesterChecker : Checker<"TaintTest">, + HelpText<"Mark tainted symbols as such.">, + DescFile<"TaintTesterChecker.cpp">; + +def ExprInspectionChecker : Checker<"ExprInspection">, + HelpText<"Check the analyzer's understanding of expressions">, + DescFile<"ExprInspectionChecker.cpp">; + +def ExplodedGraphViewer : Checker<"ViewExplodedGraph">, + HelpText<"View Exploded Graphs using GraphViz">, + DescFile<"DebugCheckers.cpp">; + +def BugHashDumper : Checker<"DumpBugHash">, + HelpText<"Dump the bug hash for all statements.">, + DescFile<"DebugCheckers.cpp">; + +} // end "debug" diff --git a/include/clang/StaticAnalyzer/Checkers/SValExplainer.h b/include/clang/StaticAnalyzer/Checkers/SValExplainer.h new file mode 100644 index 0000000000000..28cfbef910381 --- /dev/null +++ b/include/clang/StaticAnalyzer/Checkers/SValExplainer.h @@ -0,0 +1,233 @@ +//== SValExplainer.h - Symbolic value explainer -----------------*- C++ -*--==// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines SValExplainer, a class for pretty-printing a +// human-readable description of a symbolic value. For example, +// "reg_$0<x>" is turned into "initial value of variable 'x'". +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_STATICANALYZER_CHECKERS_SVALEXPLAINER_H +#define LLVM_CLANG_STATICANALYZER_CHECKERS_SVALEXPLAINER_H + +#include "clang/AST/DeclCXX.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/SValVisitor.h" + +namespace clang { + +namespace ento { + +class SValExplainer : public FullSValVisitor<SValExplainer, std::string> { +private: + ASTContext &ACtx; + + std::string printStmt(const Stmt *S) { + std::string Str; + llvm::raw_string_ostream OS(Str); + S->printPretty(OS, nullptr, PrintingPolicy(ACtx.getLangOpts())); + return OS.str(); + } + + bool isThisObject(const SymbolicRegion *R) { + if (auto S = dyn_cast<SymbolRegionValue>(R->getSymbol())) + if (isa<CXXThisRegion>(S->getRegion())) + return true; + return false; + } + +public: + SValExplainer(ASTContext &Ctx) : ACtx(Ctx) {} + + std::string VisitUnknownVal(UnknownVal V) { + return "unknown value"; + } + + std::string VisitUndefinedVal(UndefinedVal V) { + return "undefined value"; + } + + std::string VisitLocMemRegionVal(loc::MemRegionVal V) { + const MemRegion *R = V.getRegion(); + // Avoid the weird "pointer to pointee of ...". + if (auto SR = dyn_cast<SymbolicRegion>(R)) { + // However, "pointer to 'this' object" is fine. + if (!isThisObject(SR)) + return Visit(SR->getSymbol()); + } + return "pointer to " + Visit(R); + } + + std::string VisitLocConcreteInt(loc::ConcreteInt V) { + llvm::APSInt I = V.getValue(); + std::string Str; + llvm::raw_string_ostream OS(Str); + OS << "concrete memory address '" << I << "'"; + return OS.str(); + } + + std::string VisitNonLocSymbolVal(nonloc::SymbolVal V) { + return Visit(V.getSymbol()); + } + + std::string VisitNonLocConcreteInt(nonloc::ConcreteInt V) { + llvm::APSInt I = V.getValue(); + std::string Str; + llvm::raw_string_ostream OS(Str); + OS << (I.isSigned() ? "signed " : "unsigned ") << I.getBitWidth() + << "-bit integer '" << I << "'"; + return OS.str(); + } + + std::string VisitNonLocLazyCompoundVal(nonloc::LazyCompoundVal V) { + return "lazily frozen compound value of " + Visit(V.getRegion()); + } + + std::string VisitSymbolRegionValue(const SymbolRegionValue *S) { + const MemRegion *R = S->getRegion(); + // Special handling for argument values. + if (auto V = dyn_cast<VarRegion>(R)) + if (auto D = dyn_cast<ParmVarDecl>(V->getDecl())) + return "argument '" + D->getQualifiedNameAsString() + "'"; + return "initial value of " + Visit(R); + } + + std::string VisitSymbolConjured(const SymbolConjured *S) { + return "symbol of type '" + S->getType().getAsString() + + "' conjured at statement '" + printStmt(S->getStmt()) + "'"; + } + + std::string VisitSymbolDerived(const SymbolDerived *S) { + return "value derived from (" + Visit(S->getParentSymbol()) + + ") for " + Visit(S->getRegion()); + } + + std::string VisitSymbolExtent(const SymbolExtent *S) { + return "extent of " + Visit(S->getRegion()); + } + + std::string VisitSymbolMetadata(const SymbolMetadata *S) { + return "metadata of type '" + S->getType().getAsString() + "' tied to " + + Visit(S->getRegion()); + } + + std::string VisitSymIntExpr(const SymIntExpr *S) { + std::string Str; + llvm::raw_string_ostream OS(Str); + OS << "(" << Visit(S->getLHS()) << ") " + << std::string(BinaryOperator::getOpcodeStr(S->getOpcode())) << " " + << S->getRHS(); + return OS.str(); + } + + // TODO: IntSymExpr doesn't appear in practice. + // Add the relevant code once it does. + + std::string VisitSymSymExpr(const SymSymExpr *S) { + return "(" + Visit(S->getLHS()) + ") " + + std::string(BinaryOperator::getOpcodeStr(S->getOpcode())) + + " (" + Visit(S->getRHS()) + ")"; + } + + // TODO: SymbolCast doesn't appear in practice. + // Add the relevant code once it does. + + std::string VisitSymbolicRegion(const SymbolicRegion *R) { + // Explain 'this' object here. + // TODO: Explain CXXThisRegion itself, find a way to test it. + if (isThisObject(R)) + return "'this' object"; + return "pointee of " + Visit(R->getSymbol()); + } + + std::string VisitAllocaRegion(const AllocaRegion *R) { + return "region allocated by '" + printStmt(R->getExpr()) + "'"; + } + + std::string VisitCompoundLiteralRegion(const CompoundLiteralRegion *R) { + return "compound literal " + printStmt(R->getLiteralExpr()); + } + + std::string VisitStringRegion(const StringRegion *R) { + return "string literal " + R->getString(); + } + + std::string VisitElementRegion(const ElementRegion *R) { + std::string Str; + llvm::raw_string_ostream OS(Str); + OS << "element of type '" << R->getElementType().getAsString() + << "' with index "; + // For concrete index: omit type of the index integer. + if (auto I = R->getIndex().getAs<nonloc::ConcreteInt>()) + OS << I->getValue(); + else + OS << "'" << Visit(R->getIndex()) << "'"; + OS << " of " + Visit(R->getSuperRegion()); + return OS.str(); + } + + std::string VisitVarRegion(const VarRegion *R) { + const VarDecl *VD = R->getDecl(); + std::string Name = VD->getQualifiedNameAsString(); + if (isa<ParmVarDecl>(VD)) + return "parameter '" + Name + "'"; + else if (VD->hasLocalStorage()) + return "local variable '" + Name + "'"; + else if (VD->isStaticLocal()) + return "static local variable '" + Name + "'"; + else if (VD->hasGlobalStorage()) + return "global variable '" + Name + "'"; + else + llvm_unreachable("A variable is either local or global"); + } + + std::string VisitFieldRegion(const FieldRegion *R) { + return "field '" + R->getDecl()->getNameAsString() + "' of " + + Visit(R->getSuperRegion()); + } + + std::string VisitCXXTempObjectRegion(const CXXTempObjectRegion *R) { + return "temporary object constructed at statement '" + + printStmt(R->getExpr()) + "'"; + } + + std::string VisitCXXBaseObjectRegion(const CXXBaseObjectRegion *R) { + return "base object '" + R->getDecl()->getQualifiedNameAsString() + + "' inside " + Visit(R->getSuperRegion()); + } + + std::string VisitSVal(SVal V) { + std::string Str; + llvm::raw_string_ostream OS(Str); + OS << V; + return "a value unsupported by the explainer: (" + + std::string(OS.str()) + ")"; + } + + std::string VisitSymExpr(SymbolRef S) { + std::string Str; + llvm::raw_string_ostream OS(Str); + S->dumpToStream(OS); + return "a symbolic expression unsupported by the explainer: (" + + std::string(OS.str()) + ")"; + } + + std::string VisitMemRegion(const MemRegion *R) { + std::string Str; + llvm::raw_string_ostream OS(Str); + OS << R; + return "a memory region unsupported by the explainer (" + + std::string(OS.str()) + ")"; + } +}; + +} // end namespace ento + +} // end namespace clang + +#endif diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h index 197d27a2f37eb..c954bbfad8cb6 100644 --- a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h +++ b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h @@ -19,6 +19,7 @@ #include "llvm/ADT/FoldingSet.h" namespace clang { +class CFGBlock; namespace ento { diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h b/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h index 35421f9455ea3..c34b14cbf9e2a 100644 --- a/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h +++ b/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h @@ -774,8 +774,8 @@ public: void appendToDesc(StringRef S) { if (!ShortDesc.empty()) - ShortDesc.append(S); - VerboseDesc.append(S); + ShortDesc += S; + VerboseDesc += S; } void resetPath() { diff --git a/include/clang/StaticAnalyzer/Core/Checker.h b/include/clang/StaticAnalyzer/Core/Checker.h index 1410af156815b..137f238cced94 100644 --- a/include/clang/StaticAnalyzer/Core/Checker.h +++ b/include/clang/StaticAnalyzer/Core/Checker.h @@ -238,6 +238,20 @@ public: } }; +class BeginFunction { + template <typename CHECKER> + static void _checkBeginFunction(void *checker, CheckerContext &C) { + ((const CHECKER *)checker)->checkBeginFunction(C); + } + +public: + template <typename CHECKER> + static void _register(CHECKER *checker, CheckerManager &mgr) { + mgr._registerForBeginFunction(CheckerManager::CheckBeginFunctionFunc( + checker, _checkBeginFunction<CHECKER>)); + } +}; + class EndFunction { template <typename CHECKER> static void _checkEndFunction(void *checker, diff --git a/include/clang/StaticAnalyzer/Core/CheckerManager.h b/include/clang/StaticAnalyzer/Core/CheckerManager.h index bc9af496b054a..b06b74d326de1 100644 --- a/include/clang/StaticAnalyzer/Core/CheckerManager.h +++ b/include/clang/StaticAnalyzer/Core/CheckerManager.h @@ -20,6 +20,7 @@ #include "clang/StaticAnalyzer/Core/PathSensitive/Store.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallVector.h" +#include <utility> #include <vector> namespace clang { @@ -105,10 +106,8 @@ class CheckerManager { CheckName CurrentCheckName; public: - CheckerManager(const LangOptions &langOpts, - AnalyzerOptionsRef AOptions) - : LangOpts(langOpts), - AOptions(AOptions) {} + CheckerManager(const LangOptions &langOpts, AnalyzerOptionsRef AOptions) + : LangOpts(langOpts), AOptions(std::move(AOptions)) {} ~CheckerManager(); @@ -287,6 +286,12 @@ public: void runCheckersForEndAnalysis(ExplodedGraph &G, BugReporter &BR, ExprEngine &Eng); + /// \brief Run checkers on begining of function. + void runCheckersForBeginFunction(ExplodedNodeSet &Dst, + const BlockEdge &L, + ExplodedNode *Pred, + ExprEngine &Eng); + /// \brief Run checkers on end of function. void runCheckersForEndFunction(NodeBuilderContext &BC, ExplodedNodeSet &Dst, @@ -425,7 +430,10 @@ public: typedef CheckerFn<void (ExplodedGraph &, BugReporter &, ExprEngine &)> CheckEndAnalysisFunc; - + + typedef CheckerFn<void (CheckerContext &)> + CheckBeginFunctionFunc; + typedef CheckerFn<void (CheckerContext &)> CheckEndFunctionFunc; @@ -484,6 +492,7 @@ public: void _registerForEndAnalysis(CheckEndAnalysisFunc checkfn); + void _registerForBeginFunction(CheckEndFunctionFunc checkfn); void _registerForEndFunction(CheckEndFunctionFunc checkfn); void _registerForBranchCondition(CheckBranchConditionFunc checkfn); @@ -593,6 +602,7 @@ private: std::vector<CheckEndAnalysisFunc> EndAnalysisCheckers; + std::vector<CheckBeginFunctionFunc> BeginFunctionCheckers; std::vector<CheckEndFunctionFunc> EndFunctionCheckers; std::vector<CheckBranchConditionFunc> BranchConditionCheckers; diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h index b09dffaf4e570..89610ef5c17d4 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h @@ -24,6 +24,7 @@ #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h" #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h" #include "llvm/ADT/PointerIntPair.h" +#include <utility> namespace clang { class ProgramPoint; @@ -49,6 +50,30 @@ enum CallEventKind { class CallEvent; class CallEventManager; +/// This class represents a description of a function call using the number of +/// arguments and the name of the function. +class CallDescription { + friend CallEvent; + mutable IdentifierInfo *II; + StringRef FuncName; + unsigned RequiredArgs; + +public: + const static unsigned NoArgRequirement = ~0; + /// \brief Constructs a CallDescription object. + /// + /// @param FuncName The name of the function that will be matched. + /// + /// @param RequiredArgs The number of arguments that is expected to match a + /// call. Omit this parameter to match every occurance of call with a given + /// name regardless the number of arguments. + CallDescription(StringRef FuncName, unsigned RequiredArgs = NoArgRequirement) + : II(nullptr), FuncName(FuncName), RequiredArgs(RequiredArgs) {} + + /// \brief Get the name of the function that this object matches. + StringRef getFunctionName() const { return FuncName; } +}; + template<typename T = CallEvent> class CallEventRef : public IntrusiveRefCntPtr<const T> { public: @@ -141,10 +166,10 @@ protected: friend class CallEventManager; CallEvent(const Expr *E, ProgramStateRef state, const LocationContext *lctx) - : State(state), LCtx(lctx), Origin(E), RefCount(0) {} + : State(std::move(state)), LCtx(lctx), Origin(E), RefCount(0) {} CallEvent(const Decl *D, ProgramStateRef state, const LocationContext *lctx) - : State(state), LCtx(lctx), Origin(D), RefCount(0) {} + : State(std::move(state)), LCtx(lctx), Origin(D), RefCount(0) {} // DO NOT MAKE PUBLIC CallEvent(const CallEvent &Original) @@ -227,6 +252,13 @@ public: return false; } + /// \brief Returns true if the CallEvent is a call to a function that matches + /// the CallDescription. + /// + /// Note that this function is not intended to be used to match Obj-C method + /// calls. + bool isCalled(const CallDescription &CD) const; + /// \brief Returns a source range for the entire call, suitable for /// outputting in diagnostics. virtual SourceRange getSourceRange() const { @@ -929,6 +961,11 @@ public: llvm_unreachable("Unknown message kind"); } + // Returns the property accessed by this method, either explicitly via + // property syntax or implicitly via a getter or setter method. Returns + // nullptr if the call is not a prooperty access. + const ObjCPropertyDecl *getAccessedProperty() const; + RuntimeDefinition getRuntimeDefinition() const override; bool argumentsMayEscape() const override; diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h index d4f014d299842..e380982d43ea7 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h @@ -263,6 +263,10 @@ public: Eng.getBugReporter().emitReport(std::move(R)); } + /// \brief Returns the word that should be used to refer to the declaration + /// in the report. + StringRef getDeclDescription(const Decl *D); + /// \brief Get the declaration of the called function (path-sensitive). const FunctionDecl *getCalleeDecl(const CallExpr *CE) const; diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h index d5822e2244819..0fa736d76c99d 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h @@ -91,6 +91,9 @@ private: void HandleBlockEdge(const BlockEdge &E, ExplodedNode *Pred); void HandleBlockEntrance(const BlockEntrance &E, ExplodedNode *Pred); void HandleBlockExit(const CFGBlock *B, ExplodedNode *Pred); + + void HandleCallEnter(const CallEnter &CE, ExplodedNode *Pred); + void HandlePostStmt(const CFGBlock *B, unsigned StmtIdx, ExplodedNode *Pred); void HandleBranch(const Stmt *Cond, const Stmt *Term, const CFGBlock *B, diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h b/include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h index cc3779d743f2b..a66e1a1aed016 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h @@ -26,6 +26,7 @@ namespace ento { class EnvironmentManager; class SValBuilder; +class SymbolReaper; /// An entry in the environment consists of a Stmt and an LocationContext. /// This allows the environment to manage context-sensitive bindings, diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h index cfb1b921e9a42..bacb42dd176fd 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h @@ -32,6 +32,7 @@ #include "llvm/Support/Allocator.h" #include "llvm/Support/Casting.h" #include <memory> +#include <utility> #include <vector> namespace clang { @@ -121,10 +122,9 @@ class ExplodedNode : public llvm::FoldingSetNode { NodeGroup Succs; public: - explicit ExplodedNode(const ProgramPoint &loc, ProgramStateRef state, bool IsSink) - : Location(loc), State(state), Succs(IsSink) { + : Location(loc), State(std::move(state)), Succs(IsSink) { assert(isSink() == IsSink); } @@ -295,6 +295,14 @@ public: bool IsSink = false, bool* IsNew = nullptr); + /// \brief Create a node for a (Location, State) pair, + /// but don't store it for deduplication later. This + /// is useful when copying an already completed + /// ExplodedGraph for further processing. + ExplodedNode *createUncachedNode(const ProgramPoint &L, + ProgramStateRef State, + bool IsSink = false); + std::unique_ptr<ExplodedGraph> MakeEmptyGraph() const { return llvm::make_unique<ExplodedGraph>(); } @@ -321,6 +329,8 @@ public: bool empty() const { return NumNodes == 0; } unsigned size() const { return NumNodes; } + void reserve(unsigned NodeCount) { Nodes.reserve(NodeCount); } + // Iterators. typedef ExplodedNode NodeTy; typedef llvm::FoldingSet<ExplodedNode> AllNodesTy; diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h index 99083c9d6135b..50d85057041dd 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h @@ -253,8 +253,14 @@ public: /// nodes by processing the 'effects' of a switch statement. void processSwitch(SwitchNodeBuilder& builder) override; - /// Called by CoreEngine. Used to generate end-of-path - /// nodes when the control reaches the end of a function. + /// Called by CoreEngine. Used to notify checkers that processing a + /// function has begun. Called for both inlined and and top-level functions. + void processBeginOfFunction(NodeBuilderContext &BC, + ExplodedNode *Pred, ExplodedNodeSet &Dst, + const BlockEdge &L) override; + + /// Called by CoreEngine. Used to notify checkers that processing a + /// function has ended. Called for both inlined and and top-level functions. void processEndOfFunction(NodeBuilderContext& BC, ExplodedNode *Pred) override; @@ -264,7 +270,8 @@ public: ExplodedNodeSet &Dst); /// Generate the entry node of the callee. - void processCallEnter(CallEnter CE, ExplodedNode *Pred) override; + void processCallEnter(NodeBuilderContext& BC, CallEnter CE, + ExplodedNode *Pred) override; /// Generate the sequence of nodes that simulate the call exit and the post /// visit for CallExpr. @@ -385,6 +392,10 @@ public: void VisitMemberExpr(const MemberExpr *M, ExplodedNode *Pred, ExplodedNodeSet &Dst); + /// VisitMemberExpr - Transfer function for builtin atomic expressions + void VisitAtomicExpr(const AtomicExpr *E, ExplodedNode *Pred, + ExplodedNodeSet &Dst); + /// Transfer function logic for ObjCAtSynchronizedStmts. void VisitObjCAtSynchronizedStmt(const ObjCAtSynchronizedStmt *S, ExplodedNode *Pred, ExplodedNodeSet &Dst); diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h b/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h index 43f6e5cda0dc0..40cd4e4b3c4e8 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h @@ -21,6 +21,7 @@ #include "clang/AST/Decl.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/ExprObjC.h" +#include "clang/Analysis/AnalysisContext.h" #include "clang/Basic/LLVM.h" #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h" #include "llvm/ADT/FoldingSet.h" @@ -76,51 +77,13 @@ public: /// MemRegion - The root abstract class for all memory regions. class MemRegion : public llvm::FoldingSetNode { - friend class MemRegionManager; public: enum Kind { - // Memory spaces. - CodeSpaceRegionKind, - StackLocalsSpaceRegionKind, - StackArgumentsSpaceRegionKind, - HeapSpaceRegionKind, - UnknownSpaceRegionKind, - StaticGlobalSpaceRegionKind, - GlobalInternalSpaceRegionKind, - GlobalSystemSpaceRegionKind, - GlobalImmutableSpaceRegionKind, - BEGIN_NON_STATIC_GLOBAL_MEMSPACES = GlobalInternalSpaceRegionKind, - END_NON_STATIC_GLOBAL_MEMSPACES = GlobalImmutableSpaceRegionKind, - BEGIN_GLOBAL_MEMSPACES = StaticGlobalSpaceRegionKind, - END_GLOBAL_MEMSPACES = GlobalImmutableSpaceRegionKind, - BEGIN_MEMSPACES = CodeSpaceRegionKind, - END_MEMSPACES = GlobalImmutableSpaceRegionKind, - // Untyped regions. - SymbolicRegionKind, - AllocaRegionKind, - // Typed regions. - BEGIN_TYPED_REGIONS, - FunctionCodeRegionKind = BEGIN_TYPED_REGIONS, - BlockCodeRegionKind, - BlockDataRegionKind, - BEGIN_TYPED_VALUE_REGIONS, - CompoundLiteralRegionKind = BEGIN_TYPED_VALUE_REGIONS, - CXXThisRegionKind, - StringRegionKind, - ObjCStringRegionKind, - ElementRegionKind, - // Decl Regions. - BEGIN_DECL_REGIONS, - VarRegionKind = BEGIN_DECL_REGIONS, - FieldRegionKind, - ObjCIvarRegionKind, - END_DECL_REGIONS = ObjCIvarRegionKind, - CXXTempObjectRegionKind, - CXXBaseObjectRegionKind, - END_TYPED_VALUE_REGIONS = CXXBaseObjectRegionKind, - END_TYPED_REGIONS = CXXBaseObjectRegionKind +#define REGION(Id, Parent) Id ## Kind, +#define REGION_RANGE(Id, First, Last) BEGIN_##Id = First, END_##Id = Last, +#include "clang/StaticAnalyzer/Core/PathSensitive/Regions.def" }; - + private: const Kind kind; @@ -187,6 +150,28 @@ public: template<typename RegionTy> const RegionTy* getAs() const; virtual bool isBoundable() const { return false; } + + + /// Get descriptive name for memory region. The name is obtained from + /// the variable/field declaration retrieved from the memory region. + /// Regions that point to an element of an array are returned as: "arr[0]". + /// Regions that point to a struct are returned as: "st.var". + // + /// \param UseQuotes Set if the name should be quoted. + /// + /// \returns variable name for memory region + std::string getDescriptiveName(bool UseQuotes = true) const; + + + /// Retrieve source range from memory region. The range retrieval + /// is based on the decl obtained from the memory region. + /// For a VarRegion the range of the base region is returned. + /// For a FieldRegion the range of the field is returned. + /// If no declaration is found, an empty source range is returned. + /// The client is responsible for checking if the returned range is valid. + /// + /// \returns source range for declaration retrieved from memory region + clang::SourceRange sourceRange() const; }; /// MemSpaceRegion - A memory region that represents a "memory space"; @@ -386,8 +371,7 @@ public: static bool classof(const MemRegion *R) { Kind k = R->getKind(); - return k >= StackLocalsSpaceRegionKind && - k <= StackArgumentsSpaceRegionKind; + return k >= BEGIN_STACK_MEMSPACES && k <= END_STACK_MEMSPACES; } }; @@ -549,7 +533,7 @@ public: static bool classof(const MemRegion* R) { Kind k = R->getKind(); - return k >= FunctionCodeRegionKind && k <= BlockCodeRegionKind; + return k >= BEGIN_CODE_TEXT_REGIONS && k <= END_CODE_TEXT_REGIONS; } }; @@ -1358,8 +1342,8 @@ public: void setTrait(SymbolRef Sym, InvalidationKinds IK); void setTrait(const MemRegion *MR, InvalidationKinds IK); - bool hasTrait(SymbolRef Sym, InvalidationKinds IK); - bool hasTrait(const MemRegion *MR, InvalidationKinds IK); + bool hasTrait(SymbolRef Sym, InvalidationKinds IK) const; + bool hasTrait(const MemRegion *MR, InvalidationKinds IK) const; }; } // end GR namespace diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h index c4a62ecbddd3a..f89747ee17562 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h @@ -26,6 +26,7 @@ #include "llvm/ADT/ImmutableMap.h" #include "llvm/ADT/PointerIntPair.h" #include "llvm/Support/Allocator.h" +#include <utility> namespace llvm { class APSInt; @@ -836,9 +837,8 @@ class ScanReachableSymbols { ProgramStateRef state; SymbolVisitor &visitor; public: - - ScanReachableSymbols(ProgramStateRef st, SymbolVisitor& v) - : state(st), visitor(v) {} + ScanReachableSymbols(ProgramStateRef st, SymbolVisitor &v) + : state(std::move(st)), visitor(v) {} bool scan(nonloc::LazyCompoundVal val); bool scan(nonloc::CompoundVal val); diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/Regions.def b/include/clang/StaticAnalyzer/Core/PathSensitive/Regions.def new file mode 100644 index 0000000000000..c84a1ff13f8b6 --- /dev/null +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/Regions.def @@ -0,0 +1,89 @@ +//===-- Regions.def - Metadata about MemRegion kinds ------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// The list of regions (MemRegion sub-classes) used in the Static Analyzer. +// In order to use this information, users of this file must define one or more +// of the three macros: +// +// REGION(Id, Parent) - for specific MemRegion sub-classes, reserving +// enum value IdKind for their kind. +// +// ABSTRACT_REGION(Id, Parent) - for abstract region classes, +// +// REGION_RANGE(Id, First, Last) - for ranges of kind-enums, +// allowing to determine abstract class of a region +// based on the kind-enum value. +// +//===----------------------------------------------------------------------===// + +#ifndef REGION +#define REGION(Id, Parent) +#endif + +#ifndef ABSTRACT_REGION +#define ABSTRACT_REGION(Id, Parent) +#endif + +#ifndef REGION_RANGE +#define REGION_RANGE(Id, First, Last) +#endif + +ABSTRACT_REGION(MemSpaceRegion, MemRegion) + REGION(CodeSpaceRegion, MemSpaceRegion) + ABSTRACT_REGION(GlobalsSpaceRegion, MemSpaceRegion) + ABSTRACT_REGION(NonStaticGlobalSpaceRegion, GlobalsSpaceRegion) + REGION(GlobalImmutableSpaceRegion, NonStaticGlobalSpaceRegion) + REGION(GlobalInternalSpaceRegion, NonStaticGlobalSpaceRegion) + REGION(GlobalSystemSpaceRegion, NonStaticGlobalSpaceRegion) + REGION_RANGE(NON_STATIC_GLOBAL_MEMSPACES, GlobalImmutableSpaceRegionKind, + GlobalSystemSpaceRegionKind) + REGION(StaticGlobalSpaceRegion, MemSpaceRegion) + REGION_RANGE(GLOBAL_MEMSPACES, GlobalImmutableSpaceRegionKind, + StaticGlobalSpaceRegionKind) + REGION(HeapSpaceRegion, MemSpaceRegion) + ABSTRACT_REGION(StackSpaceRegion, MemSpaceRegion) + REGION(StackArgumentsSpaceRegion, StackSpaceRegion) + REGION(StackLocalsSpaceRegion, StackSpaceRegion) + REGION_RANGE(STACK_MEMSPACES, StackArgumentsSpaceRegionKind, + StackLocalsSpaceRegionKind) + REGION(UnknownSpaceRegion, MemSpaceRegion) + REGION_RANGE(MEMSPACES, CodeSpaceRegionKind, + UnknownSpaceRegionKind) +ABSTRACT_REGION(SubRegion, MemRegion) + REGION(AllocaRegion, SubRegion) + REGION(SymbolicRegion, SubRegion) + ABSTRACT_REGION(TypedRegion, SubRegion) + REGION(BlockDataRegion, TypedRegion) + ABSTRACT_REGION(CodeTextRegion, TypedRegion) + REGION(BlockCodeRegion, CodeTextRegion) + REGION(FunctionCodeRegion, CodeTextRegion) + REGION_RANGE(CODE_TEXT_REGIONS, BlockCodeRegionKind, + FunctionCodeRegionKind) + ABSTRACT_REGION(TypedValueRegion, TypedRegion) + REGION(CompoundLiteralRegion, TypedValueRegion) + REGION(CXXBaseObjectRegion, TypedValueRegion) + REGION(CXXTempObjectRegion, TypedValueRegion) + REGION(CXXThisRegion, TypedValueRegion) + ABSTRACT_REGION(DeclRegion, TypedValueRegion) + REGION(FieldRegion, DeclRegion) + REGION(ObjCIvarRegion, DeclRegion) + REGION(VarRegion, DeclRegion) + REGION_RANGE(DECL_REGIONS, FieldRegionKind, + VarRegionKind) + REGION(ElementRegion, TypedValueRegion) + REGION(ObjCStringRegion, TypedValueRegion) + REGION(StringRegion, TypedValueRegion) + REGION_RANGE(TYPED_VALUE_REGIONS, CompoundLiteralRegionKind, + StringRegionKind) + REGION_RANGE(TYPED_REGIONS, BlockDataRegionKind, + StringRegionKind) + +#undef REGION_RANGE +#undef ABSTRACT_REGION +#undef REGION diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h index 3c47114e2de25..e4be349c02633 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h @@ -21,6 +21,7 @@ #include "clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h" #include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h" #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h" namespace clang { @@ -65,7 +66,7 @@ public: SymMgr(context, BasicVals, alloc), MemMgr(context, alloc), StateMgr(stateMgr), - ArrayIndexTy(context.IntTy), + ArrayIndexTy(context.LongLongTy), ArrayIndexWidth(context.getTypeSize(ArrayIndexTy)) {} virtual ~SValBuilder() {} diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SValVisitor.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SValVisitor.h new file mode 100644 index 0000000000000..f87fdce1561bb --- /dev/null +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SValVisitor.h @@ -0,0 +1,151 @@ +//===--- SValVisitor.h - Visitor for SVal subclasses ------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the SValVisitor, SymExprVisitor, and MemRegionVisitor +// interfaces, and also FullSValVisitor, which visits all three hierarchies. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SVALVISITOR_H +#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SVALVISITOR_H + +#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h" + +namespace clang { + +namespace ento { + +/// SValVisitor - this class implements a simple visitor for SVal +/// subclasses. +template <typename ImplClass, typename RetTy = void> class SValVisitor { +public: + +#define DISPATCH(NAME, CLASS) \ + return static_cast<ImplClass *>(this)->Visit ## NAME(V.castAs<CLASS>()) + + RetTy Visit(SVal V) { + // Dispatch to VisitFooVal for each FooVal. + // Take namespaces (loc:: and nonloc::) into account. + switch (V.getBaseKind()) { +#define BASIC_SVAL(Id, Parent) case SVal::Id ## Kind: DISPATCH(Id, Id); +#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.def" + case SVal::LocKind: + switch (V.getSubKind()) { +#define LOC_SVAL(Id, Parent) \ + case loc::Id ## Kind: DISPATCH(Loc ## Id, loc :: Id); +#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.def" + } + llvm_unreachable("Unknown Loc sub-kind!"); + case SVal::NonLocKind: + switch (V.getSubKind()) { +#define NONLOC_SVAL(Id, Parent) \ + case nonloc::Id ## Kind: DISPATCH(NonLoc ## Id, nonloc :: Id); +#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.def" + } + llvm_unreachable("Unknown NonLoc sub-kind!"); + } + llvm_unreachable("Unknown SVal kind!"); + } + +#define BASIC_SVAL(Id, Parent) \ + RetTy Visit ## Id(Id V) { DISPATCH(Parent, Id); } +#define ABSTRACT_SVAL(Id, Parent) \ + BASIC_SVAL(Id, Parent) +#define LOC_SVAL(Id, Parent) \ + RetTy VisitLoc ## Id(loc::Id V) { DISPATCH(Parent, Parent); } +#define NONLOC_SVAL(Id, Parent) \ + RetTy VisitNonLoc ## Id(nonloc::Id V) { DISPATCH(Parent, Parent); } +#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.def" + + // Base case, ignore it. :) + RetTy VisitSVal(SVal V) { return RetTy(); } + +#undef DISPATCH +}; + +/// SymExprVisitor - this class implements a simple visitor for SymExpr +/// subclasses. +template <typename ImplClass, typename RetTy = void> class SymExprVisitor { +public: + +#define DISPATCH(CLASS) \ + return static_cast<ImplClass *>(this)->Visit ## CLASS(cast<CLASS>(S)) + + RetTy Visit(SymbolRef S) { + // Dispatch to VisitSymbolFoo for each SymbolFoo. + switch (S->getKind()) { +#define SYMBOL(Id, Parent) \ + case SymExpr::Id ## Kind: DISPATCH(Id); +#include "clang/StaticAnalyzer/Core/PathSensitive/Symbols.def" + } + llvm_unreachable("Unknown SymExpr kind!"); + } + + // If the implementation chooses not to implement a certain visit method, fall + // back on visiting the superclass. +#define SYMBOL(Id, Parent) RetTy Visit ## Id(const Id *S) { DISPATCH(Parent); } +#define ABSTRACT_SYMBOL(Id, Parent) SYMBOL(Id, Parent) +#include "clang/StaticAnalyzer/Core/PathSensitive/Symbols.def" + + // Base case, ignore it. :) + RetTy VisitSymExpr(SymbolRef S) { return RetTy(); } + +#undef DISPATCH +}; + +/// MemRegionVisitor - this class implements a simple visitor for MemRegion +/// subclasses. +template <typename ImplClass, typename RetTy = void> class MemRegionVisitor { +public: + +#define DISPATCH(CLASS) \ + return static_cast<ImplClass *>(this)->Visit ## CLASS(cast<CLASS>(R)) + + RetTy Visit(const MemRegion *R) { + // Dispatch to VisitFooRegion for each FooRegion. + switch (R->getKind()) { +#define REGION(Id, Parent) case MemRegion::Id ## Kind: DISPATCH(Id); +#include "clang/StaticAnalyzer/Core/PathSensitive/Regions.def" + } + llvm_unreachable("Unknown MemRegion kind!"); + } + + // If the implementation chooses not to implement a certain visit method, fall + // back on visiting the superclass. +#define REGION(Id, Parent) \ + RetTy Visit ## Id(const Id *R) { DISPATCH(Parent); } +#define ABSTRACT_REGION(Id, Parent) \ + REGION(Id, Parent) +#include "clang/StaticAnalyzer/Core/PathSensitive/Regions.def" + + // Base case, ignore it. :) + RetTy VisitMemRegion(const MemRegion *R) { return RetTy(); } + +#undef DISPATCH +}; + +/// FullSValVisitor - a convenient mixed visitor for all three: +/// SVal, SymExpr and MemRegion subclasses. +template <typename ImplClass, typename RetTy = void> +class FullSValVisitor : public SValVisitor<ImplClass, RetTy>, + public SymExprVisitor<ImplClass, RetTy>, + public MemRegionVisitor<ImplClass, RetTy> { +public: + using SValVisitor<ImplClass, RetTy>::Visit; + using SymExprVisitor<ImplClass, RetTy>::Visit; + using MemRegionVisitor<ImplClass, RetTy>::Visit; +}; + +} // end namespace ento + +} // end namespace clang + +#endif diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.def b/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.def new file mode 100644 index 0000000000000..2faec670b3385 --- /dev/null +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.def @@ -0,0 +1,74 @@ +//===-- SVals.def - Metadata about SVal kinds -------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// The list of symbolic values (SVal kinds and sub-kinds) used in the Static +// Analyzer. The distinction between loc:: and nonloc:: SVal namespaces is +// currently hardcoded, because it is too peculiar and explicit to be handled +// uniformly. In order to use this information, users of this file must define +// one or more of the following macros: +// +// BASIC_SVAL(Id, Parent) - for specific SVal sub-kinds, which are +// neither in loc:: nor in nonloc:: namespace; these classes occupy +// their own base kind IdKind. +// +// ABSTRACT_SVAL(Id, Parent) - for abstract SVal classes which are +// neither in loc:: nor in nonloc:: namespace, +// +// ABSTRACT_SVAL_WITH_KIND(Id, Parent) - for SVal classes which are also +// neither in loc:: nor in nonloc:: namespace, but occupy a whole base kind +// identifier IdKind, much like BASIC_SVALs. +// +// LOC_SVAL(Id, Parent) - for values in loc:: namespace, which occupy a sub-kind +// loc::IdKind. +// +// NONLOC_SVAL(Id, Parent) - for values in nonloc:: namespace, which occupy a +// sub-kind nonloc::IdKind. +// +//===----------------------------------------------------------------------===// + +#ifndef BASIC_SVAL +#define BASIC_SVAL(Id, Parent) +#endif + +#ifndef ABSTRACT_SVAL +#define ABSTRACT_SVAL(Id, Parent) +#endif + +#ifndef ABSTRACT_SVAL_WITH_KIND +#define ABSTRACT_SVAL_WITH_KIND(Id, Parent) ABSTRACT_SVAL(Id, Parent) +#endif + +#ifndef LOC_SVAL +#define LOC_SVAL(Id, Parent) +#endif + +#ifndef NONLOC_SVAL +#define NONLOC_SVAL(Id, Parent) +#endif + +BASIC_SVAL(UndefinedVal, SVal) +ABSTRACT_SVAL(DefinedOrUnknownSVal, SVal) + BASIC_SVAL(UnknownVal, DefinedOrUnknownSVal) + ABSTRACT_SVAL(DefinedSVal, DefinedOrUnknownSVal) + ABSTRACT_SVAL_WITH_KIND(Loc, DefinedSVal) + LOC_SVAL(ConcreteInt, Loc) + LOC_SVAL(GotoLabel, Loc) + LOC_SVAL(MemRegionVal, Loc) + ABSTRACT_SVAL_WITH_KIND(NonLoc, DefinedSVal) + NONLOC_SVAL(CompoundVal, NonLoc) + NONLOC_SVAL(ConcreteInt, NonLoc) + NONLOC_SVAL(LazyCompoundVal, NonLoc) + NONLOC_SVAL(LocAsInteger, NonLoc) + NONLOC_SVAL(SymbolVal, NonLoc) + +#undef NONLOC_SVAL +#undef LOC_SVAL +#undef ABSTRACT_SVAL_WITH_KIND +#undef ABSTRACT_SVAL +#undef BASIC_SVAL diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h index d64425412c894..dbc7c99c61013 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h @@ -15,9 +15,11 @@ #ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SVALS_H #define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SVALS_H +#include "clang/AST/Expr.h" #include "clang/Basic/LLVM.h" #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h" -#include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h" +#include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/ImmutableList.h" //==------------------------------------------------------------------------==// @@ -45,11 +47,9 @@ class SVal { public: enum BaseKind { // The enumerators must be representable using 2 bits. - UndefinedValKind = 0, // for subclass UndefinedVal (an uninitialized value) - UnknownValKind = 1, // for subclass UnknownVal (a void value) - LocKind = 2, // for subclass Loc (an L-value) - NonLocKind = 3 // for subclass NonLoc (an R-value that's not - // an L-value) +#define BASIC_SVAL(Id, Parent) Id ## Kind, +#define ABSTRACT_SVAL_WITH_KIND(Id, Parent) Id ## Kind, +#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.def" }; enum { BaseBits = 2, BaseMask = 0x3 }; @@ -306,8 +306,10 @@ private: namespace nonloc { -enum Kind { ConcreteIntKind, SymbolValKind, - LocAsIntegerKind, CompoundValKind, LazyCompoundValKind }; +enum Kind { +#define NONLOC_SVAL(Id, Parent) Id ## Kind, +#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.def" +}; /// \brief Represents symbolic expression. class SymbolVal : public NonLoc { @@ -465,7 +467,10 @@ private: namespace loc { -enum Kind { GotoLabelKind, MemRegionValKind, ConcreteIntKind }; +enum Kind { +#define LOC_SVAL(Id, Parent) Id ## Kind, +#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.def" +}; class GotoLabel : public Loc { public: diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h index 741ba0e2f290a..1a731cf865ea3 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h @@ -99,13 +99,21 @@ public: /// nodes by processing the 'effects' of a switch statement. virtual void processSwitch(SwitchNodeBuilder& builder) = 0; - /// Called by CoreEngine. Used to generate end-of-path - /// nodes when the control reaches the end of a function. + /// Called by CoreEngine. Used to notify checkers that processing a + /// function has begun. Called for both inlined and and top-level functions. + virtual void processBeginOfFunction(NodeBuilderContext &BC, + ExplodedNode *Pred, + ExplodedNodeSet &Dst, + const BlockEdge &L) = 0; + + /// Called by CoreEngine. Used to notify checkers that processing a + /// function has ended. Called for both inlined and and top-level functions. virtual void processEndOfFunction(NodeBuilderContext& BC, ExplodedNode *Pred) = 0; // Generate the entry node of the callee. - virtual void processCallEnter(CallEnter CE, ExplodedNode *Pred) = 0; + virtual void processCallEnter(NodeBuilderContext& BC, CallEnter CE, + ExplodedNode *Pred) = 0; // Generate the first post callsite node. virtual void processCallExit(ExplodedNode *Pred) = 0; diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h new file mode 100644 index 0000000000000..18bc60754b81a --- /dev/null +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h @@ -0,0 +1,123 @@ +//== SymExpr.h - Management of Symbolic Values ------------------*- C++ -*--==// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines SymExpr and SymbolData. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SYMEXPR_H +#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SYMEXPR_H + +#include "clang/AST/Type.h" +#include "llvm/ADT/FoldingSet.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/Support/raw_ostream.h" + +namespace clang { +namespace ento { + +class MemRegion; + +/// \brief Symbolic value. These values used to capture symbolic execution of +/// the program. +class SymExpr : public llvm::FoldingSetNode { + virtual void anchor(); + +public: + enum Kind { +#define SYMBOL(Id, Parent) Id##Kind, +#define SYMBOL_RANGE(Id, First, Last) BEGIN_##Id = First, END_##Id = Last, +#include "clang/StaticAnalyzer/Core/PathSensitive/Symbols.def" + }; + +private: + Kind K; + +protected: + SymExpr(Kind k) : K(k) {} + +public: + virtual ~SymExpr() {} + + Kind getKind() const { return K; } + + virtual void dump() const; + + virtual void dumpToStream(raw_ostream &os) const {} + + virtual QualType getType() const = 0; + virtual void Profile(llvm::FoldingSetNodeID &profile) = 0; + + /// \brief Iterator over symbols that the current symbol depends on. + /// + /// For SymbolData, it's the symbol itself; for expressions, it's the + /// expression symbol and all the operands in it. Note, SymbolDerived is + /// treated as SymbolData - the iterator will NOT visit the parent region. + class symbol_iterator { + SmallVector<const SymExpr *, 5> itr; + void expand(); + + public: + symbol_iterator() {} + symbol_iterator(const SymExpr *SE); + + symbol_iterator &operator++(); + const SymExpr *operator*(); + + bool operator==(const symbol_iterator &X) const; + bool operator!=(const symbol_iterator &X) const; + }; + + symbol_iterator symbol_begin() const { return symbol_iterator(this); } + static symbol_iterator symbol_end() { return symbol_iterator(); } + + unsigned computeComplexity() const; + + /// \brief Find the region from which this symbol originates. + /// + /// Whenever the symbol was constructed to denote an unknown value of + /// a certain memory region, return this region. This method + /// allows checkers to make decisions depending on the origin of the symbol. + /// Symbol classes for which the origin region is known include + /// SymbolRegionValue which denotes the value of the region before + /// the beginning of the analysis, and SymbolDerived which denotes the value + /// of a certain memory region after its super region (a memory space or + /// a larger record region) is default-bound with a certain symbol. + virtual const MemRegion *getOriginRegion() const { return nullptr; } +}; + +typedef const SymExpr *SymbolRef; +typedef SmallVector<SymbolRef, 2> SymbolRefSmallVectorTy; + +typedef unsigned SymbolID; +/// \brief A symbol representing data which can be stored in a memory location +/// (region). +class SymbolData : public SymExpr { + void anchor() override; + const SymbolID Sym; + +protected: + SymbolData(Kind k, SymbolID sym) : SymExpr(k), Sym(sym) {} + +public: + ~SymbolData() override {} + + SymbolID getSymbolID() const { return Sym; } + + // Implement isa<T> support. + static inline bool classof(const SymExpr *SE) { + Kind k = SE->getKind(); + return k >= BEGIN_SYMBOLS && k <= END_SYMBOLS; + } +}; + +} // namespace ento +} // namespace clang + +#endif diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h index 77d12e5ba666e..087430583e0c2 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h @@ -19,7 +19,9 @@ #include "clang/AST/Expr.h" #include "clang/Analysis/AnalysisContext.h" #include "clang/Basic/LLVM.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h" #include "clang/StaticAnalyzer/Core/PathSensitive/StoreRef.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/FoldingSet.h" @@ -32,102 +34,10 @@ namespace clang { namespace ento { class BasicValueFactory; - class MemRegion; class SubRegion; class TypedValueRegion; class VarRegion; -/// \brief Symbolic value. These values used to capture symbolic execution of -/// the program. -class SymExpr : public llvm::FoldingSetNode { - virtual void anchor(); -public: - enum Kind { - SymbolRegionValueKind, - SymbolConjuredKind, - SymbolDerivedKind, - SymbolExtentKind, - SymbolMetadataKind, - BEGIN_SYMBOLS = SymbolRegionValueKind, - END_SYMBOLS = SymbolMetadataKind, - SymIntExprKind, - IntSymExprKind, - SymSymExprKind, - BEGIN_BINARYSYMEXPRS = SymIntExprKind, - END_BINARYSYMEXPRS = SymSymExprKind, - SymbolCastKind - }; - -private: - Kind K; - -protected: - SymExpr(Kind k) : K(k) {} - -public: - virtual ~SymExpr() {} - - Kind getKind() const { return K; } - - virtual void dump() const; - - virtual void dumpToStream(raw_ostream &os) const {} - - virtual QualType getType() const = 0; - virtual void Profile(llvm::FoldingSetNodeID& profile) = 0; - - /// \brief Iterator over symbols that the current symbol depends on. - /// - /// For SymbolData, it's the symbol itself; for expressions, it's the - /// expression symbol and all the operands in it. Note, SymbolDerived is - /// treated as SymbolData - the iterator will NOT visit the parent region. - class symbol_iterator { - SmallVector<const SymExpr*, 5> itr; - void expand(); - public: - symbol_iterator() {} - symbol_iterator(const SymExpr *SE); - - symbol_iterator &operator++(); - const SymExpr* operator*(); - - bool operator==(const symbol_iterator &X) const; - bool operator!=(const symbol_iterator &X) const; - }; - - symbol_iterator symbol_begin() const { - return symbol_iterator(this); - } - static symbol_iterator symbol_end() { return symbol_iterator(); } - - unsigned computeComplexity() const; -}; - -typedef const SymExpr* SymbolRef; -typedef SmallVector<SymbolRef, 2> SymbolRefSmallVectorTy; - -typedef unsigned SymbolID; -/// \brief A symbol representing data which can be stored in a memory location -/// (region). -class SymbolData : public SymExpr { - void anchor() override; - const SymbolID Sym; - -protected: - SymbolData(Kind k, SymbolID sym) : SymExpr(k), Sym(sym) {} - -public: - ~SymbolData() override {} - - SymbolID getSymbolID() const { return Sym; } - - // Implement isa<T> support. - static inline bool classof(const SymExpr *SE) { - Kind k = SE->getKind(); - return k >= BEGIN_SYMBOLS && k <= END_SYMBOLS; - } -}; - ///\brief A symbol representing the value stored at a MemRegion. class SymbolRegionValue : public SymbolData { const TypedValueRegion *R; @@ -148,6 +58,7 @@ public: } void dumpToStream(raw_ostream &os) const override; + const MemRegion *getOriginRegion() const override { return getRegion(); } QualType getType() const override; @@ -217,6 +128,7 @@ public: QualType getType() const override; void dumpToStream(raw_ostream &os) const override; + const MemRegion *getOriginRegion() const override { return getRegion(); } static void Profile(llvm::FoldingSetNodeID& profile, SymbolRef parent, const TypedValueRegion *r) { diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/Symbols.def b/include/clang/StaticAnalyzer/Core/PathSensitive/Symbols.def new file mode 100644 index 0000000000000..7d4d8fe0a55a2 --- /dev/null +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/Symbols.def @@ -0,0 +1,55 @@ +//===-- Symbols.def - Metadata about SymExpr kinds --------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// The list of symbols (SymExpr sub-classes) used in the Static Analyzer. +// In order to use this information, users of this file must define +// one or more of the three macros: +// +// SYMBOL(Id, Parent) - for specific SymExpr sub-classes, reserving the +// IdKind identifier for its kind enumeration value. +// +// ABSTRACT_SYMBOL(Id, Parent) - for abstract symbol classes, +// +// SYMBOL_RANGE(Id, First, Last) - for ranges of kind-enums, +// allowing to determine abstract class of a symbol +// based on the kind enumeration value. +// +//===----------------------------------------------------------------------===// + +#ifndef SYMBOL +#define SYMBOL(Id, Parent) +#endif + +#ifndef ABSTRACT_SYMBOL +#define ABSTRACT_SYMBOL(Id, Parent) +#endif + +#ifndef SYMBOL_RANGE +#define SYMBOL_RANGE(Id, First, Last) +#endif + +ABSTRACT_SYMBOL(BinarySymExpr, SymExpr) + SYMBOL(IntSymExpr, BinarySymExpr) + SYMBOL(SymIntExpr, BinarySymExpr) + SYMBOL(SymSymExpr, BinarySymExpr) +SYMBOL_RANGE(BINARYSYMEXPRS, IntSymExprKind, SymSymExprKind) + +SYMBOL(SymbolCast, SymExpr) + +ABSTRACT_SYMBOL(SymbolData, SymExpr) + SYMBOL(SymbolConjured, SymbolData) + SYMBOL(SymbolDerived, SymbolData) + SYMBOL(SymbolExtent, SymbolData) + SYMBOL(SymbolMetadata, SymbolData) + SYMBOL(SymbolRegionValue, SymbolData) +SYMBOL_RANGE(SYMBOLS, SymbolConjuredKind, SymbolRegionValueKind) + +#undef SYMBOL +#undef ABSTRACT_SYMBOL +#undef SYMBOL_RANGE diff --git a/include/clang/Tooling/CommonOptionsParser.h b/include/clang/Tooling/CommonOptionsParser.h index 1e8462c631c3e..3d630c5f7609c 100644 --- a/include/clang/Tooling/CommonOptionsParser.h +++ b/include/clang/Tooling/CommonOptionsParser.h @@ -98,7 +98,7 @@ public: } /// Returns a list of source file paths to process. - std::vector<std::string> getSourcePathList() { + const std::vector<std::string> &getSourcePathList() const { return SourcePathList; } diff --git a/include/clang/Tooling/Core/QualTypeNames.h b/include/clang/Tooling/Core/QualTypeNames.h new file mode 100644 index 0000000000000..7248356e748e8 --- /dev/null +++ b/include/clang/Tooling/Core/QualTypeNames.h @@ -0,0 +1,79 @@ +//===--- QualTypeNames.h - Generate Complete QualType Names ----*- C++ -*-===// +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +// ===----------------------------------------------------------------------===// +// +// \file +// Functionality to generate the fully-qualified names of QualTypes, +// including recursively expanding any subtypes and template +// parameters. +// +// More precisely: Generates a name that can be used to name the same +// type if used at the end of the current translation unit--with +// certain limitations. See below. +// +// This code desugars names only very minimally, so in this code: +// +// namespace A { +// struct X {}; +// } +// using A::X; +// namespace B { +// using std::tuple; +// typedef tuple<X> TX; +// TX t; +// } +// +// B::t's type is reported as "B::TX", rather than std::tuple<A::X>. +// +// Also, this code replaces types found via using declarations with +// their more qualified name, so for the code: +// +// using std::tuple; +// tuple<int> TInt; +// +// TInt's type will be named, "std::tuple<int>". +// +// Limitations: +// +// Some types have ambiguous names at the end of a translation unit, +// are not namable at all there, or are special cases in other ways. +// +// 1) Types with only local scope will have their local names: +// +// void foo() { +// struct LocalType {} LocalVar; +// } +// +// LocalVar's type will be named, "struct LocalType", without any +// qualification. +// +// 2) Types that have been shadowed are reported normally, but a +// client using that name at the end of the translation unit will be +// referring to a different type. +// +// ===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLING_CORE_QUALTYPENAMES_H +#define LLVM_CLANG_TOOLING_CORE_QUALTYPENAMES_H + +#include "clang/AST/ASTContext.h" + +namespace clang { +namespace TypeName { +/// \brief Get the fully qualified name for a type. This includes full +/// qualification of all template parameters etc. +/// +/// \param[in] QT - the type for which the fully qualified name will be +/// returned. +/// \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, + bool WithGlobalNsPrefix = false); +} // end namespace TypeName +} // end namespace clang +#endif // LLVM_CLANG_TOOLING_CORE_QUALTYPENAMES_H diff --git a/include/clang/Tooling/Core/Replacement.h b/include/clang/Tooling/Core/Replacement.h index 37389ac91566e..4815302ee455c 100644 --- a/include/clang/Tooling/Core/Replacement.h +++ b/include/clang/Tooling/Core/Replacement.h @@ -22,6 +22,8 @@ #include "clang/Basic/LangOptions.h" #include "clang/Basic/SourceLocation.h" #include "llvm/ADT/StringRef.h" +#include "llvm/Support/Error.h" +#include <map> #include <set> #include <string> #include <vector> @@ -56,6 +58,11 @@ public: return RHS.Offset >= Offset && (RHS.Offset + RHS.Length) <= (Offset + Length); } + + /// \brief Whether this range equals to \p RHS or not. + bool operator==(const Range &RHS) const { + return Offset == RHS.getOffset() && Length == RHS.getLength(); + } /// @} private: @@ -159,9 +166,13 @@ bool applyAllReplacements(const std::vector<Replacement> &Replaces, /// \brief Applies all replacements in \p Replaces to \p Code. /// -/// This completely ignores the path stored in each replacement. If one or more -/// replacements cannot be applied, this returns an empty \c string. -std::string applyAllReplacements(StringRef Code, const Replacements &Replaces); +/// This completely ignores the path stored in each replacement. If all +/// replacements are applied successfully, this returns the code with +/// replacements applied; otherwise, an llvm::Error carrying llvm::StringError +/// is returned (the Error message can be converted to string using +/// `llvm::toString()` and 'std::error_code` in the `Error` should be ignored). +llvm::Expected<std::string> applyAllReplacements(StringRef Code, + const Replacements &Replaces); /// \brief Calculates how a code \p Position is shifted when \p Replaces are /// applied. @@ -197,28 +208,30 @@ struct TranslationUnitReplacements { std::vector<Replacement> Replacements; }; -/// \brief Apply all replacements in \p Replaces to the Rewriter \p Rewrite. +/// \brief Calculates the ranges in a single file that are affected by the +/// Replacements. Overlapping ranges will be merged. /// -/// Replacement applications happen independently of the success of -/// other applications. +/// \pre Replacements must be for the same file. /// -/// \returns true if all replacements apply. false otherwise. -bool applyAllReplacements(const Replacements &Replaces, Rewriter &Rewrite); +/// \returns a non-overlapping and sorted ranges. +std::vector<Range> calculateChangedRanges(const Replacements &Replaces); -/// \brief Apply all replacements in \p Replaces to the Rewriter \p Rewrite. +/// \brief Calculates the new ranges after \p Replaces are applied. These +/// include both the original \p Ranges and the affected ranges of \p Replaces +/// in the new code. /// -/// Replacement applications happen independently of the success of -/// other applications. -/// -/// \returns true if all replacements apply. false otherwise. -bool applyAllReplacements(const std::vector<Replacement> &Replaces, - Rewriter &Rewrite); - -/// \brief Applies all replacements in \p Replaces to \p Code. +/// \pre Replacements must be for the same file. /// -/// This completely ignores the path stored in each replacement. If one or more -/// replacements cannot be applied, this returns an empty \c string. -std::string applyAllReplacements(StringRef Code, const Replacements &Replaces); +/// \return The new ranges after \p Replaces are applied. The new ranges will be +/// sorted and non-overlapping. +std::vector<Range> +calculateRangesAfterReplacements(const Replacements &Replaces, + const std::vector<Range> &Ranges); + +/// \brief Groups a random set of replacements by file path. Replacements +/// related to the same file entry are put into the same vector. +std::map<std::string, Replacements> +groupReplacementsByFile(const Replacements &Replaces); /// \brief Merges two sets of replacements with the second set referring to the /// code after applying the first set. Within both 'First' and 'Second', diff --git a/include/clang/Tooling/FixIt.h b/include/clang/Tooling/FixIt.h new file mode 100644 index 0000000000000..e2259d4357bc6 --- /dev/null +++ b/include/clang/Tooling/FixIt.h @@ -0,0 +1,72 @@ +//===--- FixIt.h - FixIt Hint utilities -------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements functions to ease source rewriting from AST-nodes. +// +// Example swapping A and B expressions: +// +// Expr *A, *B; +// tooling::fixit::createReplacement(*A, *B); +// tooling::fixit::createReplacement(*B, *A); +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLING_FIXIT_H +#define LLVM_CLANG_TOOLING_FIXIT_H + +#include "clang/AST/ASTContext.h" + +namespace clang { +namespace tooling { +namespace fixit { + +namespace internal { +StringRef getText(SourceRange Range, const ASTContext &Context); + +/// \brief Returns the SourceRange of a SourceRange. This identity function is +/// used by the following template abstractions. +inline SourceRange getSourceRange(const SourceRange &Range) { return Range; } + +/// \brief Returns the SourceRange of the token at Location \p Loc. +inline SourceRange getSourceRange(const SourceLocation &Loc) { + return SourceRange(Loc); +} + +/// \brief Returns the SourceRange of an given Node. \p Node is typically a +/// 'Stmt', 'Expr' or a 'Decl'. +template <typename T> SourceRange getSourceRange(const T &Node) { + return Node.getSourceRange(); +} +} // end namespace internal + +// \brief Returns a textual representation of \p Node. +template <typename T> +StringRef getText(const T &Node, const ASTContext &Context) { + return internal::getText(internal::getSourceRange(Node), Context); +} + +// \brief Returns a FixItHint to remove \p Node. +// TODO: Add support for related syntactical elements (i.e. comments, ...). +template <typename T> FixItHint createRemoval(const T &Node) { + return FixItHint::CreateRemoval(internal::getSourceRange(Node)); +} + +// \brief Returns a FixItHint to replace \p Destination by \p Source. +template <typename D, typename S> +FixItHint createReplacement(const D &Destination, const S &Source, + const ASTContext &Context) { + return FixItHint::CreateReplacement(internal::getSourceRange(Destination), + getText(Source, Context)); +} + +} // end namespace fixit +} // end namespace tooling +} // end namespace clang + +#endif // LLVM_CLANG_TOOLING_FIXINT_H diff --git a/include/clang/Tooling/Refactoring.h b/include/clang/Tooling/Refactoring.h index 54deff6e36612..06ec8b0876293 100644 --- a/include/clang/Tooling/Refactoring.h +++ b/include/clang/Tooling/Refactoring.h @@ -68,6 +68,24 @@ private: Replacements Replace; }; +/// \brief Groups \p Replaces by the file path and applies each group of +/// Replacements on the related file in \p Rewriter. In addition to applying +/// given Replacements, this function also formats the changed code. +/// +/// \pre Replacements must be conflict-free. +/// +/// Replacement applications happen independently of the success of other +/// applications. +/// +/// \param[in] Replaces Replacements to apply. +/// \param[in] Rewrite The `Rewritter` to apply replacements on. +/// \param[in] Style The style name used for reformatting. See ```getStyle``` in +/// "include/clang/Format/Format.h" for all possible style forms. +/// +/// \returns true if all replacements applied and formatted. false otherwise. +bool formatAndApplyAllReplacements(const Replacements &Replaces, + Rewriter &Rewrite, StringRef Style = "file"); + } // end namespace tooling } // end namespace clang diff --git a/include/clang/Tooling/Tooling.h b/include/clang/Tooling/Tooling.h index b7a9b25acd0e4..ca232f4098318 100644 --- a/include/clang/Tooling/Tooling.h +++ b/include/clang/Tooling/Tooling.h @@ -163,6 +163,8 @@ typedef std::vector<std::pair<std::string, std::string>> FileContentMappings; /// \param Code C++ code. /// \param Args Additional flags to pass on. /// \param FileName The file name which 'Code' will be mapped as. +/// \param ToolName The name of the binary running the tool. Standard library +/// header paths will be resolved relative to this. /// \param PCHContainerOps The PCHContainerOperations for loading and creating /// clang modules. /// @@ -170,6 +172,7 @@ typedef std::vector<std::pair<std::string, std::string>> FileContentMappings; bool runToolOnCodeWithArgs( clang::FrontendAction *ToolAction, const Twine &Code, const std::vector<std::string> &Args, const Twine &FileName = "input.cc", + const Twine &ToolName = "clang-tool", std::shared_ptr<PCHContainerOperations> PCHContainerOps = std::make_shared<PCHContainerOperations>(), const FileContentMappings &VirtualMappedFiles = FileContentMappings()); @@ -192,13 +195,15 @@ buildASTFromCode(const Twine &Code, const Twine &FileName = "input.cc", /// \param Code C++ code. /// \param Args Additional flags to pass on. /// \param FileName The file name which 'Code' will be mapped as. +/// \param ToolName The name of the binary running the tool. Standard library +/// header paths will be resolved relative to this. /// \param PCHContainerOps The PCHContainerOperations for loading and creating /// clang modules. /// /// \return The resulting AST or null if an error occurred. std::unique_ptr<ASTUnit> buildASTFromCodeWithArgs( const Twine &Code, const std::vector<std::string> &Args, - const Twine &FileName = "input.cc", + const Twine &FileName = "input.cc", const Twine &ToolName = "clang-tool", std::shared_ptr<PCHContainerOperations> PCHContainerOps = std::make_shared<PCHContainerOperations>()); diff --git a/include/clang/module.modulemap b/include/clang/module.modulemap index 28b6d1652c5e1..7fa8b82515ebe 100644 --- a/include/clang/module.modulemap +++ b/include/clang/module.modulemap @@ -12,6 +12,7 @@ module Clang_AST { umbrella "AST" textual header "AST/BuiltinTypes.def" + textual header "AST/OperationKinds.def" textual header "AST/TypeLocNodes.def" textual header "AST/TypeNodes.def" @@ -41,6 +42,7 @@ module Clang_Basic { textual header "Basic/DiagnosticOptions.def" textual header "Basic/LangOptions.def" textual header "Basic/OpenCLExtensions.def" + textual header "Basic/OpenCLImageTypes.def" textual header "Basic/OpenMPKinds.def" textual header "Basic/OperatorKinds.def" textual header "Basic/Sanitizers.def" @@ -108,6 +110,9 @@ module Clang_StaticAnalyzer_Core { umbrella "StaticAnalyzer/Core" textual header "StaticAnalyzer/Core/Analyses.def" + textual header "StaticAnalyzer/Core/PathSensitive/SVals.def" + textual header "StaticAnalyzer/Core/PathSensitive/Symbols.def" + textual header "StaticAnalyzer/Core/PathSensitive/Regions.def" module * { export * } } |