diff options
Diffstat (limited to 'contrib/llvm/tools/clang/include')
182 files changed, 11240 insertions, 7710 deletions
diff --git a/contrib/llvm/tools/clang/include/clang-c/CXCompilationDatabase.h b/contrib/llvm/tools/clang/include/clang-c/CXCompilationDatabase.h index 068a677..9359abf 100644 --- a/contrib/llvm/tools/clang/include/clang-c/CXCompilationDatabase.h +++ b/contrib/llvm/tools/clang/include/clang-c/CXCompilationDatabase.h @@ -126,6 +126,12 @@ CINDEX_LINKAGE CXString clang_CompileCommand_getDirectory(CXCompileCommand); /** + * \brief Get the filename associated with the CompileCommand. + */ +CINDEX_LINKAGE CXString +clang_CompileCommand_getFilename(CXCompileCommand); + +/** * \brief Get the number of arguments in the compiler invocation. * */ diff --git a/contrib/llvm/tools/clang/include/clang-c/CXString.h b/contrib/llvm/tools/clang/include/clang-c/CXString.h index a649cdf..68ab7bc 100644 --- a/contrib/llvm/tools/clang/include/clang-c/CXString.h +++ b/contrib/llvm/tools/clang/include/clang-c/CXString.h @@ -40,6 +40,11 @@ typedef struct { unsigned private_flags; } CXString; +typedef struct { + CXString *Strings; + unsigned Count; +} CXStringSet; + /** * \brief Retrieve the character data associated with the given string. */ @@ -51,6 +56,11 @@ CINDEX_LINKAGE const char *clang_getCString(CXString string); CINDEX_LINKAGE void clang_disposeString(CXString string); /** + * \brief Free the given string set. + */ +CINDEX_LINKAGE void clang_disposeStringSet(CXStringSet *set); + +/** * @} */ diff --git a/contrib/llvm/tools/clang/include/clang-c/Index.h b/contrib/llvm/tools/clang/include/clang-c/Index.h index fad9cfa..09e2160 100644 --- a/contrib/llvm/tools/clang/include/clang-c/Index.h +++ b/contrib/llvm/tools/clang/include/clang-c/Index.h @@ -32,7 +32,7 @@ * compatible, thus CINDEX_VERSION_MAJOR is expected to remain stable. */ #define CINDEX_VERSION_MAJOR 0 -#define CINDEX_VERSION_MINOR 30 +#define CINDEX_VERSION_MINOR 32 #define CINDEX_VERSION_ENCODE(major, minor) ( \ ((major) * 10000) \ @@ -285,7 +285,6 @@ CINDEX_LINKAGE unsigned clang_CXIndex_getGlobalOptions(CXIndex); */ typedef void *CXFile; - /** * \brief Retrieve the complete file and path name of the given file. */ @@ -705,7 +704,6 @@ CINDEX_LINKAGE unsigned clang_getNumDiagnosticsInSet(CXDiagnosticSet Diags); CINDEX_LINKAGE CXDiagnostic clang_getDiagnosticInSet(CXDiagnosticSet Diags, unsigned Index); - /** * \brief Describes the kind of error that occurred (if any) in a call to * \c clang_loadDiagnostics. @@ -1202,7 +1200,15 @@ enum CXTranslationUnit_Flags { * included into the set of code completions returned from this translation * unit. */ - CXTranslationUnit_IncludeBriefCommentsInCodeCompletion = 0x80 + CXTranslationUnit_IncludeBriefCommentsInCodeCompletion = 0x80, + + /** + * \brief Used to indicate that the precompiled preamble should be created on + * the first parse. Otherwise it will be created on the first reparse. This + * trades runtime on the first parse (serializing the preamble takes time) for + * reduced runtime on the second parse (can now reuse the preamble). + */ + CXTranslationUnit_CreatePreambleOnFirstParse = 0x100 }; /** @@ -1289,6 +1295,17 @@ clang_parseTranslationUnit2(CXIndex CIdx, CXTranslationUnit *out_TU); /** + * \brief Same as clang_parseTranslationUnit2 but requires a full command line + * for \c command_line_args including argv[0]. This is useful if the standard + * library paths are relative to the binary. + */ +CINDEX_LINKAGE enum CXErrorCode clang_parseTranslationUnit2FullArgv( + CXIndex CIdx, const char *source_filename, + const char *const *command_line_args, int num_command_line_args, + struct CXUnsavedFile *unsaved_files, unsigned num_unsaved_files, + unsigned options, CXTranslationUnit *out_TU); + +/** * \brief Flags that control how translation units are saved. * * The enumerators in this enumeration type are meant to be bitwise @@ -1573,7 +1590,7 @@ enum CXCursorKind { CXCursor_ObjCImplementationDecl = 18, /** \brief An Objective-C \@implementation for a category. */ CXCursor_ObjCCategoryImplDecl = 19, - /** \brief A typedef */ + /** \brief A typedef. */ CXCursor_TypedefDecl = 20, /** \brief A C++ class method. */ CXCursor_CXXMethod = 21, @@ -1982,7 +1999,11 @@ enum CXCursorKind { */ CXCursor_ObjCSelfExpr = 146, - CXCursor_LastExpr = CXCursor_ObjCSelfExpr, + /** \brief OpenMP 4.0 [2.4, Array Section]. + */ + CXCursor_OMPArraySectionExpr = 147, + + CXCursor_LastExpr = CXCursor_OMPArraySectionExpr, /* Statements */ CXCursor_FirstStmt = 200, @@ -2227,17 +2248,33 @@ enum CXCursorKind { /** \brief OpenMP taskgroup directive. */ - CXCursor_OMPTaskgroupDirective = 254, + CXCursor_OMPTaskgroupDirective = 254, /** \brief OpenMP cancellation point directive. */ - CXCursor_OMPCancellationPointDirective = 255, + CXCursor_OMPCancellationPointDirective = 255, /** \brief OpenMP cancel directive. */ - CXCursor_OMPCancelDirective = 256, + CXCursor_OMPCancelDirective = 256, - CXCursor_LastStmt = CXCursor_OMPCancelDirective, + /** \brief OpenMP target data directive. + */ + CXCursor_OMPTargetDataDirective = 257, + + /** \brief OpenMP taskloop directive. + */ + CXCursor_OMPTaskLoopDirective = 258, + + /** \brief OpenMP taskloop simd directive. + */ + CXCursor_OMPTaskLoopSimdDirective = 259, + + /** \brief OpenMP distribute directive. + */ + CXCursor_OMPDistributeDirective = 260, + + CXCursor_LastStmt = CXCursor_OMPDistributeDirective, /** * \brief Cursor that represents the translation unit itself. @@ -2271,7 +2308,10 @@ enum CXCursorKind { CXCursor_CUDAGlobalAttr = 414, CXCursor_CUDAHostAttr = 415, CXCursor_CUDASharedAttr = 416, - CXCursor_LastAttr = CXCursor_CUDASharedAttr, + CXCursor_VisibilityAttr = 417, + CXCursor_DLLExport = 418, + CXCursor_DLLImport = 419, + CXCursor_LastAttr = CXCursor_DLLImport, /* Preprocessing */ CXCursor_PreprocessingDirective = 500, @@ -2287,8 +2327,9 @@ enum CXCursorKind { * \brief A module import declaration. */ CXCursor_ModuleImportDecl = 600, + CXCursor_TypeAliasTemplateDecl = 601, CXCursor_FirstExtraDecl = CXCursor_ModuleImportDecl, - CXCursor_LastExtraDecl = CXCursor_ModuleImportDecl, + CXCursor_LastExtraDecl = CXCursor_TypeAliasTemplateDecl, /** * \brief A code completion overload candidate. @@ -2439,6 +2480,32 @@ enum CXLinkageKind { */ CINDEX_LINKAGE enum CXLinkageKind clang_getCursorLinkage(CXCursor cursor); +enum CXVisibilityKind { + /** \brief This value indicates that no visibility information is available + * for a provided CXCursor. */ + CXVisibility_Invalid, + + /** \brief Symbol not seen by the linker. */ + CXVisibility_Hidden, + /** \brief Symbol seen by the linker but resolves to a symbol inside this object. */ + CXVisibility_Protected, + /** \brief Symbol seen by the linker and acts like a normal symbol. */ + CXVisibility_Default +}; + +/** + * \brief Describe the visibility of the entity referred to by a cursor. + * + * This returns the default visibility if not explicitly specified by + * a visibility attribute. The default visibility may be changed by + * commandline arguments. + * + * \param cursor The cursor to query. + * + * \returns The visibility of the cursor. + */ +CINDEX_LINKAGE enum CXVisibilityKind clang_getCursorVisibility(CXCursor cursor); + /** * \brief Determine the availability of the entity that this cursor refers to, * taking the current target platform into account. @@ -2558,7 +2625,6 @@ CINDEX_LINKAGE enum CXLanguageKind clang_getCursorLanguage(CXCursor cursor); */ CINDEX_LINKAGE CXTranslationUnit clang_Cursor_getTranslationUnit(CXCursor); - /** * \brief A fast container representing a set of CXCursors. */ @@ -2851,7 +2917,8 @@ enum CXTypeKind { CXType_IncompleteArray = 114, CXType_VariableArray = 115, CXType_DependentSizedArray = 116, - CXType_MemberPointer = 117 + CXType_MemberPointer = 117, + CXType_Auto = 118 }; /** @@ -2876,7 +2943,6 @@ enum CXCallingConv { CXCallingConv_Unexposed = 200 }; - /** * \brief The type of an element in the abstract syntax tree. * @@ -3314,7 +3380,6 @@ CINDEX_LINKAGE long long clang_Cursor_getOffsetOfField(CXCursor C); */ CINDEX_LINKAGE unsigned clang_Cursor_isAnonymous(CXCursor C); - enum CXRefQualifierKind { /** \brief No ref-qualifier was provided. */ CXRefQualifier_None = 0, @@ -3443,7 +3508,6 @@ CINDEX_LINKAGE CXCursor clang_getOverloadedDecl(CXCursor cursor, * @{ */ - /** * \brief For cursors representing an iboutletcollection attribute, * this function returns the collection element type. @@ -3597,7 +3661,6 @@ CINDEX_LINKAGE CXString CINDEX_LINKAGE CXString clang_constructUSR_ObjCProtocol(const char *protocol_name); - /** * \brief Construct a USR for a specified Objective-C instance variable and * the USR for its containing class. @@ -3723,7 +3786,6 @@ CINDEX_LINKAGE unsigned clang_isCursorDefinition(CXCursor); */ CINDEX_LINKAGE CXCursor clang_getCanonicalCursor(CXCursor); - /** * \brief If the cursor points to a selector identifier in an Objective-C * method or message expression, this returns the selector index. @@ -3854,6 +3916,12 @@ CINDEX_LINKAGE CXString clang_Cursor_getBriefCommentText(CXCursor C); CINDEX_LINKAGE CXString clang_Cursor_getMangling(CXCursor); /** + * \brief Retrieve the CXStrings representing the mangled symbols of the C++ + * constructor or destructor at the cursor. + */ +CINDEX_LINKAGE CXStringSet *clang_Cursor_getCXXManglings(CXCursor); + +/** * @} */ @@ -3948,6 +4016,11 @@ CXFile clang_Module_getTopLevelHeader(CXTranslationUnit, */ /** + * \brief Determine if a C++ field is declared 'mutable'. + */ +CINDEX_LINKAGE unsigned clang_CXXField_isMutable(CXCursor C); + +/** * \brief Determine if a C++ member function or member function template is * pure virtual. */ @@ -4939,8 +5012,7 @@ enum CXCursorKind clang_codeCompleteGetContainerKind( */ CINDEX_LINKAGE CXString clang_codeCompleteGetContainerUSR(CXCodeCompleteResults *Results); - - + /** * \brief Returns the currently-entered selector for an Objective-C message * send, formatted like "initWithFoo:bar:". Only guaranteed to return a @@ -4959,7 +5031,6 @@ CXString clang_codeCompleteGetObjCSelector(CXCodeCompleteResults *Results); * @} */ - /** * \defgroup CINDEX_MISC Miscellaneous utility functions * @@ -4972,7 +5043,6 @@ CXString clang_codeCompleteGetObjCSelector(CXCodeCompleteResults *Results); */ CINDEX_LINKAGE CXString clang_getClangVersion(void); - /** * \brief Enable/disable crash recovery. * @@ -5659,6 +5729,18 @@ CINDEX_LINKAGE int clang_indexSourceFile(CXIndexAction, unsigned TU_options); /** + * \brief Same as clang_indexSourceFile but requires a full command line + * for \c command_line_args including argv[0]. This is useful if the standard + * library paths are relative to the binary. + */ +CINDEX_LINKAGE int clang_indexSourceFileFullArgv( + CXIndexAction, CXClientData client_data, IndexerCallbacks *index_callbacks, + unsigned index_callbacks_size, unsigned index_options, + const char *source_filename, const char *const *command_line_args, + int num_command_line_args, struct CXUnsavedFile *unsaved_files, + unsigned num_unsaved_files, CXTranslationUnit *out_TU, unsigned TU_options); + +/** * \brief Index the given translation unit via callbacks implemented through * #IndexerCallbacks. * @@ -5739,7 +5821,6 @@ CINDEX_LINKAGE unsigned clang_Type_visitFields(CXType T, CXFieldVisitor visitor, CXClientData client_data); - /** * @} */ @@ -5752,4 +5833,3 @@ CINDEX_LINKAGE unsigned clang_Type_visitFields(CXType T, } #endif #endif - diff --git a/contrib/llvm/tools/clang/include/clang/AST/ASTContext.h b/contrib/llvm/tools/clang/include/clang/AST/ASTContext.h index a2bd55a..b66009e 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/ASTContext.h +++ b/contrib/llvm/tools/clang/include/clang/AST/ASTContext.h @@ -28,6 +28,7 @@ #include "clang/Basic/AddressSpaces.h" #include "clang/Basic/IdentifierTable.h" #include "clang/Basic/LangOptions.h" +#include "clang/Basic/Module.h" #include "clang/Basic/OperatorKinds.h" #include "clang/Basic/PartialDiagnostic.h" #include "clang/Basic/SanitizerBlacklist.h" @@ -70,6 +71,7 @@ namespace clang { class VTableContextBase; namespace Builtin { class Context; } + enum BuiltinTemplateKind : int; namespace comments { class FullComment; @@ -176,8 +178,9 @@ class ASTContext : public RefCountedBase<ASTContext> { ClassScopeSpecializationPattern; /// \brief Mapping from materialized temporaries with static storage duration - /// that appear in constant initializers to their evaluated values. - llvm::DenseMap<const MaterializeTemporaryExpr*, APValue> + /// that appear in constant initializers to their evaluated values. These are + /// allocated in a std::map because their address must be stable. + llvm::DenseMap<const MaterializeTemporaryExpr *, APValue *> MaterializedTemporaryValues; /// \brief Representation of a "canonical" template template parameter that @@ -215,6 +218,9 @@ class ASTContext : public RefCountedBase<ASTContext> { /// __builtin_va_list type. mutable TypedefDecl *BuiltinVaListDecl; + /// The typedef for the predefined \c __builtin_ms_va_list type. + mutable TypedefDecl *BuiltinMSVaListDecl; + /// \brief The typedef for the predefined \c id type. mutable TypedefDecl *ObjCIdDecl; @@ -242,6 +248,9 @@ class ASTContext : public RefCountedBase<ASTContext> { /// The identifier 'NSCopying'. IdentifierInfo *NSCopyingName = nullptr; + /// The identifier '__make_integer_seq'. + mutable IdentifierInfo *MakeIntegerSeqName = nullptr; + QualType ObjCConstantStringType; mutable RecordDecl *CFConstantStringTypeDecl; @@ -395,6 +404,7 @@ private: TranslationUnitDecl *TUDecl; mutable ExternCContextDecl *ExternCContext; + mutable BuiltinTemplateDecl *MakeIntegerSeqDecl; /// \brief The associated SourceManager object.a SourceManager &SourceMgr; @@ -433,6 +443,7 @@ private: friend class CXXRecordDecl; const TargetInfo *Target; + const TargetInfo *AuxTarget; clang::PrintingPolicy PrintingPolicy; public: @@ -446,10 +457,59 @@ public: /// \brief Contains parents of a node. typedef llvm::SmallVector<ast_type_traits::DynTypedNode, 2> ParentVector; - /// \brief Maps from a node to its parents. + /// \brief Maps from a node to its parents. This is used for nodes that have + /// pointer identity only, which are more common and we can save space by + /// only storing a unique pointer to them. typedef llvm::DenseMap<const void *, - llvm::PointerUnion<ast_type_traits::DynTypedNode *, - ParentVector *>> ParentMap; + llvm::PointerUnion4<const Decl *, const Stmt *, + ast_type_traits::DynTypedNode *, + ParentVector *>> ParentMapPointers; + + /// Parent map for nodes without pointer identity. We store a full + /// DynTypedNode for all keys. + typedef llvm::DenseMap< + ast_type_traits::DynTypedNode, + llvm::PointerUnion4<const Decl *, const Stmt *, + ast_type_traits::DynTypedNode *, ParentVector *>> + ParentMapOtherNodes; + + /// Container for either a single DynTypedNode or for an ArrayRef to + /// DynTypedNode. For use with ParentMap. + class DynTypedNodeList { + typedef ast_type_traits::DynTypedNode DynTypedNode; + llvm::AlignedCharArrayUnion<ast_type_traits::DynTypedNode, + ArrayRef<DynTypedNode>> Storage; + bool IsSingleNode; + + public: + DynTypedNodeList(const DynTypedNode &N) : IsSingleNode(true) { + new (Storage.buffer) DynTypedNode(N); + } + DynTypedNodeList(ArrayRef<DynTypedNode> A) : IsSingleNode(false) { + new (Storage.buffer) ArrayRef<DynTypedNode>(A); + } + + const ast_type_traits::DynTypedNode *begin() const { + if (!IsSingleNode) + return reinterpret_cast<const ArrayRef<DynTypedNode> *>(Storage.buffer) + ->begin(); + return reinterpret_cast<const DynTypedNode *>(Storage.buffer); + } + + const ast_type_traits::DynTypedNode *end() const { + if (!IsSingleNode) + return reinterpret_cast<const ArrayRef<DynTypedNode> *>(Storage.buffer) + ->end(); + return reinterpret_cast<const DynTypedNode *>(Storage.buffer) + 1; + } + + size_t size() const { return end() - begin(); } + bool empty() const { return begin() == end(); } + const DynTypedNode &operator[](size_t N) const { + assert(N < size() && "Out of bounds!"); + return *(begin() + N); + } + }; /// \brief Returns the parents of the given node. /// @@ -475,13 +535,11 @@ public: /// /// 'NodeT' can be one of Decl, Stmt, Type, TypeLoc, /// NestedNameSpecifier or NestedNameSpecifierLoc. - template <typename NodeT> - ArrayRef<ast_type_traits::DynTypedNode> getParents(const NodeT &Node) { + template <typename NodeT> DynTypedNodeList getParents(const NodeT &Node) { return getParents(ast_type_traits::DynTypedNode::create(Node)); } - ArrayRef<ast_type_traits::DynTypedNode> - getParents(const ast_type_traits::DynTypedNode &Node); + DynTypedNodeList getParents(const ast_type_traits::DynTypedNode &Node); const clang::PrintingPolicy &getPrintingPolicy() const { return PrintingPolicy; @@ -501,6 +559,9 @@ public: void *Allocate(size_t Size, unsigned Align = 8) const { return BumpAlloc.Allocate(Size, Align); } + template <typename T> T *Allocate(size_t Num = 1) const { + return static_cast<T *>(Allocate(Num * sizeof(T), llvm::alignOf<T>())); + } void Deallocate(void *Ptr) const { } /// Return the total amount of physical memory allocated for representing @@ -516,7 +577,8 @@ public: } const TargetInfo &getTargetInfo() const { return *Target; } - + const TargetInfo *getAuxTargetInfo() const { return AuxTarget; } + /// getIntTypeForBitwidth - /// sets integer QualTy according to specified details: /// bitwidth, signed/unsigned. @@ -812,6 +874,7 @@ public: TranslationUnitDecl *getTranslationUnitDecl() const { return TUDecl; } ExternCContextDecl *getExternCContextDecl() const; + BuiltinTemplateDecl *getMakeIntegerSeqDecl() const; // Builtin Types. CanQualType VoidTy; @@ -835,17 +898,21 @@ public: CanQualType ObjCBuiltinIdTy, ObjCBuiltinClassTy, ObjCBuiltinSelTy; CanQualType ObjCBuiltinBoolTy; CanQualType OCLImage1dTy, OCLImage1dArrayTy, OCLImage1dBufferTy; - CanQualType OCLImage2dTy, OCLImage2dArrayTy; + CanQualType OCLImage2dTy, OCLImage2dArrayTy, OCLImage2dDepthTy; + CanQualType OCLImage2dArrayDepthTy, OCLImage2dMSAATy, OCLImage2dArrayMSAATy; + CanQualType OCLImage2dMSAADepthTy, OCLImage2dArrayMSAADepthTy; CanQualType OCLImage3dTy; - CanQualType OCLSamplerTy, OCLEventTy; + CanQualType OCLSamplerTy, OCLEventTy, OCLClkEventTy; + CanQualType OCLQueueTy, OCLNDRangeTy, OCLReserveIDTy; + CanQualType OMPArraySectionTy; // Types for deductions in C++0x [stmt.ranged]'s desugaring. Built on demand. mutable QualType AutoDeductTy; // Deduction against 'auto'. mutable QualType AutoRRefDeductTy; // Deduction against 'auto &&'. - // Type used to help define __builtin_va_list for some targets. - // The type is built when constructing 'BuiltinVaListDecl'. - mutable QualType VaListTagTy; + // Decl used to help define __builtin_va_list for some targets. + // The decl is built when constructing 'BuiltinVaListDecl'. + mutable Decl *VaListTagDecl; ASTContext(LangOptions &LOpts, SourceManager &SM, IdentifierTable &idents, SelectorTable &sels, Builtin::Context &builtins); @@ -881,6 +948,9 @@ public: void PrintStats() const; const SmallVectorImpl<Type *>& getTypes() const { return Types; } + BuiltinTemplateDecl *buildBuiltinTemplateDecl(BuiltinTemplateKind BTK, + const IdentifierInfo *II) const; + /// \brief Create a new implicit TU-level CXXRecordDecl or RecordDecl /// declaration. RecordDecl *buildImplicitRecord(StringRef Name, @@ -955,6 +1025,9 @@ public: const FunctionType *adjustFunctionType(const FunctionType *Fn, FunctionType::ExtInfo EInfo); + /// Adjust the given function result type. + CanQualType getCanonicalFunctionResultType(QualType ResultType) const; + /// \brief Change the result type of a function type once it is deduced. void adjustDeducedFunctionResultType(FunctionDecl *FD, QualType ResultType); @@ -1227,7 +1300,7 @@ public: UnaryTransformType::UTTKind UKind) const; /// \brief C++11 deduced auto type. - QualType getAutoType(QualType DeducedType, bool IsDecltypeAuto, + QualType getAutoType(QualType DeducedType, AutoTypeKeyword Keyword, bool IsDependent) const; /// \brief C++11 deduction pattern for 'auto' type. @@ -1381,6 +1454,12 @@ public: return NSCopyingName; } + IdentifierInfo *getMakeIntegerSeqName() const { + if (!MakeIntegerSeqName) + MakeIntegerSeqName = &Idents.get("__make_integer_seq"); + return MakeIntegerSeqName; + } + /// \brief Retrieve the Objective-C "instancetype" type, if already known; /// otherwise, returns a NULL type; QualType getObjCInstanceType() { @@ -1569,7 +1648,16 @@ public: /// \brief Retrieve the C type declaration corresponding to the predefined /// \c __va_list_tag type used to help define the \c __builtin_va_list type /// for some targets. - QualType getVaListTagType() const; + Decl *getVaListTagDecl() const; + + /// Retrieve the C type declaration corresponding to the predefined + /// \c __builtin_ms_va_list type. + TypedefDecl *getBuiltinMSVaListDecl() const; + + /// Retrieve the type of the \c __builtin_ms_va_list type. + QualType getBuiltinMSVaListType() const { + return getTypeDeclType(getBuiltinMSVaListDecl()); + } /// \brief Return a type with additional \c const, \c volatile, or /// \c restrict qualifiers. @@ -1774,7 +1862,6 @@ public: /// record (struct/union/class) \p D, which indicates its size and field /// position information. const ASTRecordLayout &getASTRecordLayout(const RecordDecl *D) const; - const ASTRecordLayout *BuildMicrosoftASTRecordLayout(const RecordDecl *D) const; /// \brief Get or compute information about the layout of the specified /// Objective-C interface. @@ -2170,9 +2257,7 @@ public: const FunctionProtoType *FromFunctionType, const FunctionProtoType *ToFunctionType); - void ResetObjCLayout(const ObjCContainerDecl *CD) { - ObjCLayouts[CD] = nullptr; - } + void ResetObjCLayout(const ObjCContainerDecl *CD); //===--------------------------------------------------------------------===// // Integer Predicates @@ -2188,16 +2273,6 @@ public: QualType getCorrespondingUnsignedType(QualType T) const; //===--------------------------------------------------------------------===// - // Type Iterators. - //===--------------------------------------------------------------------===// - typedef llvm::iterator_range<SmallVectorImpl<Type *>::const_iterator> - type_const_range; - - type_const_range types() const { - return type_const_range(Types.begin(), Types.end()); - } - - //===--------------------------------------------------------------------===// // Integer Values //===--------------------------------------------------------------------===// @@ -2233,16 +2308,11 @@ public: /// \brief Get the duplicate declaration of a ObjCMethod in the same /// interface, or null if none exists. - const ObjCMethodDecl *getObjCMethodRedeclaration( - const ObjCMethodDecl *MD) const { - return ObjCMethodRedecls.lookup(MD); - } + const ObjCMethodDecl * + getObjCMethodRedeclaration(const ObjCMethodDecl *MD) const; void setObjCMethodRedeclaration(const ObjCMethodDecl *MD, - const ObjCMethodDecl *Redecl) { - assert(!getObjCMethodRedeclaration(MD) && "MD already has a redeclaration"); - ObjCMethodRedecls[MD] = Redecl; - } + const ObjCMethodDecl *Redecl); /// \brief Returns the Objective-C interface that \p ND belongs to if it is /// an Objective-C method/property/ivar etc. that is part of an interface, @@ -2307,6 +2377,14 @@ public: Expr *getDefaultArgExprForConstructor(const CXXConstructorDecl *CD, unsigned ParmIdx); + void addTypedefNameForUnnamedTagDecl(TagDecl *TD, TypedefNameDecl *TND); + + TypedefNameDecl *getTypedefNameForUnnamedTagDecl(const TagDecl *TD); + + void addDeclaratorForUnnamedTagDecl(TagDecl *TD, DeclaratorDecl *DD); + + DeclaratorDecl *getDeclaratorForUnnamedTagDecl(const TagDecl *TD); + void setManglingNumber(const NamedDecl *ND, unsigned Number); unsigned getManglingNumber(const NamedDecl *ND) const; @@ -2388,9 +2466,10 @@ public: /// This routine may only be invoked once for a given ASTContext object. /// It is normally invoked after ASTContext construction. /// - /// \param Target The target - void InitBuiltinTypes(const TargetInfo &Target); - + /// \param Target The target + void InitBuiltinTypes(const TargetInfo &Target, + const TargetInfo *AuxTarget = nullptr); + private: void InitBuiltinType(CanQualType &R, BuiltinType::Kind K); @@ -2429,9 +2508,15 @@ private: /// \brief A set of deallocations that should be performed when the /// ASTContext is destroyed. - typedef llvm::SmallDenseMap<void(*)(void*), llvm::SmallVector<void*, 16> > - DeallocationMap; - DeallocationMap Deallocations; + // FIXME: We really should have a better mechanism in the ASTContext to + // manage running destructors for types which do variable sized allocation + // within the AST. In some places we thread the AST bump pointer allocator + // into the datastructures which avoids this mess during deallocation but is + // wasteful of memory, and here we require a lot of error prone book keeping + // in order to track and run destructors while we're tearing things down. + typedef llvm::SmallVector<std::pair<void (*)(void *), void *>, 16> + DeallocationFunctionsAndArguments; + DeallocationFunctionsAndArguments Deallocations; // FIXME: This currently contains the set of StoredDeclMaps used // by DeclContext objects. This probably should not be in ASTContext, @@ -2443,7 +2528,8 @@ private: void ReleaseDeclContextMaps(); void ReleaseParentMapEntries(); - std::unique_ptr<ParentMap> AllParents; + std::unique_ptr<ParentMapPointers> PointerParents; + std::unique_ptr<ParentMapOtherNodes> OtherParents; std::unique_ptr<VTableContextBase> VTContext; diff --git a/contrib/llvm/tools/clang/include/clang/AST/ASTMutationListener.h b/contrib/llvm/tools/clang/include/clang/AST/ASTMutationListener.h index f4026e9..3ff392d 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/ASTMutationListener.h +++ b/contrib/llvm/tools/clang/include/clang/AST/ASTMutationListener.h @@ -92,18 +92,6 @@ public: virtual void AddedObjCCategoryToInterface(const ObjCCategoryDecl *CatD, const ObjCInterfaceDecl *IFD) {} - /// \brief A objc class extension redeclared or introduced a property. - /// - /// \param Prop the property in the class extension - /// - /// \param OrigProp the property from the original interface that was declared - /// or null if the property was introduced. - /// - /// \param ClassExt the class extension. - virtual void AddedObjCPropertyInClassExtension(const ObjCPropertyDecl *Prop, - const ObjCPropertyDecl *OrigProp, - const ObjCCategoryDecl *ClassExt) {} - /// \brief A declaration is marked used which was not previously marked used. /// /// \param D the declaration marked used diff --git a/contrib/llvm/tools/clang/include/clang/AST/ASTTypeTraits.h b/contrib/llvm/tools/clang/include/clang/AST/ASTTypeTraits.h index dc3c34f..dcaac80 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/ASTTypeTraits.h +++ b/contrib/llvm/tools/clang/include/clang/AST/ASTTypeTraits.h @@ -106,18 +106,25 @@ public: } }; + /// Check if the given ASTNodeKind identifies a type that offers pointer + /// identity. This is useful for the fast path in DynTypedNode. + bool hasPointerIdentity() const { + return KindId > NKI_LastKindWithoutPointerIdentity; + } + private: /// \brief Kind ids. /// /// Includes all possible base and derived kinds. enum NodeKindId { NKI_None, - NKI_CXXCtorInitializer, NKI_TemplateArgument, - NKI_NestedNameSpecifier, NKI_NestedNameSpecifierLoc, NKI_QualType, NKI_TypeLoc, + NKI_LastKindWithoutPointerIdentity = NKI_TypeLoc, + NKI_CXXCtorInitializer, + NKI_NestedNameSpecifier, NKI_Decl, #define DECL(DERIVED, BASE) NKI_##DERIVED##Decl, #include "clang/AST/DeclNodes.inc" @@ -238,7 +245,11 @@ public: /// Note that this is not supported by all AST nodes. For AST nodes /// that don't have a pointer-defined identity inside the AST, this /// method returns NULL. - const void *getMemoizationData() const { return MemoizationData; } + const void *getMemoizationData() const { + return NodeKind.hasPointerIdentity() + ? *reinterpret_cast<void *const *>(Storage.buffer) + : nullptr; + } /// \brief Prints the node to the given output stream. void print(llvm::raw_ostream &OS, const PrintingPolicy &PP) const; @@ -257,6 +268,32 @@ public: /// FIXME: Implement comparsion for other node types (currently /// only Stmt, Decl, Type and NestedNameSpecifier return memoization data). bool operator<(const DynTypedNode &Other) const { + if (!NodeKind.isSame(Other.NodeKind)) + return NodeKind < Other.NodeKind; + + if (ASTNodeKind::getFromNodeKind<QualType>().isSame(NodeKind)) + return getUnchecked<QualType>().getAsOpaquePtr() < + Other.getUnchecked<QualType>().getAsOpaquePtr(); + + if (ASTNodeKind::getFromNodeKind<TypeLoc>().isSame(NodeKind)) { + auto TLA = getUnchecked<TypeLoc>(); + auto TLB = Other.getUnchecked<TypeLoc>(); + return std::make_pair(TLA.getType().getAsOpaquePtr(), + TLA.getOpaqueData()) < + std::make_pair(TLB.getType().getAsOpaquePtr(), + TLB.getOpaqueData()); + } + + if (ASTNodeKind::getFromNodeKind<NestedNameSpecifierLoc>().isSame( + NodeKind)) { + auto NNSLA = getUnchecked<NestedNameSpecifierLoc>(); + auto NNSLB = Other.getUnchecked<NestedNameSpecifierLoc>(); + return std::make_pair(NNSLA.getNestedNameSpecifier(), + NNSLA.getOpaqueData()) < + std::make_pair(NNSLB.getNestedNameSpecifier(), + NNSLB.getOpaqueData()); + } + assert(getMemoizationData() && Other.getMemoizationData()); return getMemoizationData() < Other.getMemoizationData(); } @@ -270,6 +307,13 @@ public: if (ASTNodeKind::getFromNodeKind<QualType>().isSame(NodeKind)) return getUnchecked<QualType>() == Other.getUnchecked<QualType>(); + if (ASTNodeKind::getFromNodeKind<TypeLoc>().isSame(NodeKind)) + return getUnchecked<TypeLoc>() == Other.getUnchecked<TypeLoc>(); + + if (ASTNodeKind::getFromNodeKind<NestedNameSpecifierLoc>().isSame(NodeKind)) + return getUnchecked<NestedNameSpecifierLoc>() == + Other.getUnchecked<NestedNameSpecifierLoc>(); + assert(getMemoizationData() && Other.getMemoizationData()); return getMemoizationData() == Other.getMemoizationData(); } @@ -278,6 +322,47 @@ public: } /// @} + /// \brief Hooks for using DynTypedNode as a key in a DenseMap. + struct DenseMapInfo { + static inline DynTypedNode getEmptyKey() { + DynTypedNode Node; + Node.NodeKind = ASTNodeKind::DenseMapInfo::getEmptyKey(); + return Node; + } + static inline DynTypedNode getTombstoneKey() { + DynTypedNode Node; + Node.NodeKind = ASTNodeKind::DenseMapInfo::getTombstoneKey(); + return Node; + } + static unsigned getHashValue(const DynTypedNode &Val) { + // FIXME: Add hashing support for the remaining types. + if (ASTNodeKind::getFromNodeKind<TypeLoc>().isSame(Val.NodeKind)) { + auto TL = Val.getUnchecked<TypeLoc>(); + return llvm::hash_combine(TL.getType().getAsOpaquePtr(), + TL.getOpaqueData()); + } + + if (ASTNodeKind::getFromNodeKind<NestedNameSpecifierLoc>().isSame( + Val.NodeKind)) { + auto NNSL = Val.getUnchecked<NestedNameSpecifierLoc>(); + return llvm::hash_combine(NNSL.getNestedNameSpecifier(), + NNSL.getOpaqueData()); + } + + assert(Val.getMemoizationData()); + return llvm::hash_value(Val.getMemoizationData()); + } + static bool isEqual(const DynTypedNode &LHS, const DynTypedNode &RHS) { + auto Empty = ASTNodeKind::DenseMapInfo::getEmptyKey(); + auto TombStone = ASTNodeKind::DenseMapInfo::getTombstoneKey(); + return (ASTNodeKind::DenseMapInfo::isEqual(LHS.NodeKind, Empty) && + ASTNodeKind::DenseMapInfo::isEqual(RHS.NodeKind, Empty)) || + (ASTNodeKind::DenseMapInfo::isEqual(LHS.NodeKind, TombStone) && + ASTNodeKind::DenseMapInfo::isEqual(RHS.NodeKind, TombStone)) || + LHS == RHS; + } + }; + private: /// \brief Takes care of converting from and to \c T. template <typename T, typename EnablerT = void> struct BaseConverter; @@ -286,18 +371,18 @@ private: template <typename T, typename BaseT> struct DynCastPtrConverter { static const T *get(ASTNodeKind NodeKind, const char Storage[]) { if (ASTNodeKind::getFromNodeKind<T>().isBaseOf(NodeKind)) - return cast<T>(*reinterpret_cast<BaseT *const *>(Storage)); + return &getUnchecked(NodeKind, Storage); return nullptr; } static const T &getUnchecked(ASTNodeKind NodeKind, const char Storage[]) { assert(ASTNodeKind::getFromNodeKind<T>().isBaseOf(NodeKind)); - return *cast<T>(*reinterpret_cast<BaseT *const *>(Storage)); + return *cast<T>(static_cast<const BaseT *>( + *reinterpret_cast<const void *const *>(Storage))); } static DynTypedNode create(const BaseT &Node) { DynTypedNode Result; Result.NodeKind = ASTNodeKind::getFromNode(Node); - Result.MemoizationData = &Node; - new (Result.Storage.buffer) const BaseT * (&Node); + new (Result.Storage.buffer) const void *(&Node); return Result; } }; @@ -306,18 +391,18 @@ private: template <typename T> struct PtrConverter { static const T *get(ASTNodeKind NodeKind, const char Storage[]) { if (ASTNodeKind::getFromNodeKind<T>().isSame(NodeKind)) - return *reinterpret_cast<T *const *>(Storage); + return &getUnchecked(NodeKind, Storage); return nullptr; } static const T &getUnchecked(ASTNodeKind NodeKind, const char Storage[]) { assert(ASTNodeKind::getFromNodeKind<T>().isSame(NodeKind)); - return **reinterpret_cast<T *const *>(Storage); + return *static_cast<const T *>( + *reinterpret_cast<const void *const *>(Storage)); } static DynTypedNode create(const T &Node) { DynTypedNode Result; Result.NodeKind = ASTNodeKind::getFromNodeKind<T>(); - Result.MemoizationData = &Node; - new (Result.Storage.buffer) const T * (&Node); + new (Result.Storage.buffer) const void *(&Node); return Result; } }; @@ -336,14 +421,12 @@ private: static DynTypedNode create(const T &Node) { DynTypedNode Result; Result.NodeKind = ASTNodeKind::getFromNodeKind<T>(); - Result.MemoizationData = nullptr; new (Result.Storage.buffer) T(Node); return Result; } }; ASTNodeKind NodeKind; - const void *MemoizationData; /// \brief Stores the data of the node. /// @@ -353,12 +436,9 @@ private: /// \c QualTypes, \c NestedNameSpecifierLocs, \c TypeLocs and /// \c TemplateArguments on the other hand do not have storage or unique /// pointers and thus need to be stored by value. - typedef llvm::AlignedCharArrayUnion< - Decl *, Stmt *, Type *, NestedNameSpecifier *, CXXCtorInitializer *> - KindsByPointer; - llvm::AlignedCharArrayUnion<KindsByPointer, TemplateArgument, - NestedNameSpecifierLoc, QualType, TypeLoc> - Storage; + llvm::AlignedCharArrayUnion<const void *, TemplateArgument, + NestedNameSpecifierLoc, QualType, + TypeLoc> Storage; }; template <typename T> @@ -420,6 +500,10 @@ template <> struct DenseMapInfo<clang::ast_type_traits::ASTNodeKind> : clang::ast_type_traits::ASTNodeKind::DenseMapInfo {}; +template <> +struct DenseMapInfo<clang::ast_type_traits::DynTypedNode> + : clang::ast_type_traits::DynTypedNode::DenseMapInfo {}; + } // end namespace llvm #endif diff --git a/contrib/llvm/tools/clang/include/clang/AST/Attr.h b/contrib/llvm/tools/clang/include/clang/AST/Attr.h index 4e282d6..8b80e9f 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/Attr.h +++ b/contrib/llvm/tools/clang/include/clang/AST/Attr.h @@ -56,21 +56,21 @@ protected: bool IsLateParsed : 1; bool DuplicatesAllowed : 1; - void* operator new(size_t bytes) throw() { + void *operator new(size_t bytes) LLVM_NOEXCEPT { llvm_unreachable("Attrs cannot be allocated with regular 'new'."); } - void operator delete(void* data) throw() { + void operator delete(void *data) LLVM_NOEXCEPT { llvm_unreachable("Attrs cannot be released with regular 'delete'."); } public: // Forward so that the regular new and delete do not hide global ones. - void* operator new(size_t Bytes, ASTContext &C, - size_t Alignment = 8) throw() { + void *operator new(size_t Bytes, ASTContext &C, + size_t Alignment = 8) LLVM_NOEXCEPT { return ::operator new(Bytes, C, Alignment); } void operator delete(void *Ptr, ASTContext &C, - size_t Alignment) throw() { + size_t Alignment) LLVM_NOEXCEPT { return ::operator delete(Ptr, C, Alignment); } diff --git a/contrib/llvm/tools/clang/include/clang/AST/BuiltinTypes.def b/contrib/llvm/tools/clang/include/clang/AST/BuiltinTypes.def index 488cace..85e237a 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/BuiltinTypes.def +++ b/contrib/llvm/tools/clang/include/clang/AST/BuiltinTypes.def @@ -160,6 +160,12 @@ 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. @@ -168,6 +174,18 @@ BUILTIN_TYPE(OCLSampler, OCLSamplerTy) // OpenCL event_t. BUILTIN_TYPE(OCLEvent, OCLEventTy) +// OpenCL clk_event_t. +BUILTIN_TYPE(OCLClkEvent, OCLClkEventTy) + +// OpenCL queue_t. +BUILTIN_TYPE(OCLQueue, OCLQueueTy) + +// OpenCL ndrange_t. +BUILTIN_TYPE(OCLNDRange, OCLNDRangeTy) + +// OpenCL reserve_id_t. +BUILTIN_TYPE(OCLReserveID, OCLReserveIDTy) + // This represents the type of an expression whose type is // totally unknown, e.g. 'T::foo'. It is permitted for this to // appear in situations where the structure of the type is @@ -227,8 +245,11 @@ PLACEHOLDER_TYPE(BuiltinFn, BuiltinFnTy) // context. PLACEHOLDER_TYPE(ARCUnbridgedCast, ARCUnbridgedCastTy) +// A placeholder type for OpenMP array sections. +PLACEHOLDER_TYPE(OMPArraySection, OMPArraySectionTy) + #ifdef LAST_BUILTIN_TYPE -LAST_BUILTIN_TYPE(ARCUnbridgedCast) +LAST_BUILTIN_TYPE(OMPArraySection) #undef LAST_BUILTIN_TYPE #endif diff --git a/contrib/llvm/tools/clang/include/clang/AST/CXXInheritance.h b/contrib/llvm/tools/clang/include/clang/AST/CXXInheritance.h index f7612f2..8587260 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/CXXInheritance.h +++ b/contrib/llvm/tools/clang/include/clang/AST/CXXInheritance.h @@ -155,17 +155,16 @@ class CXXBasePaths { /// \brief Array of the declarations that have been found. This /// array is constructed only if needed, e.g., to iterate over the /// results within LookupResult. - NamedDecl **DeclsFound; + std::unique_ptr<NamedDecl *[]> DeclsFound; unsigned NumDeclsFound; friend class CXXRecordDecl; void ComputeDeclsFound(); - bool lookupInBases(ASTContext &Context, - const CXXRecordDecl *Record, - CXXRecordDecl::BaseMatchesCallback *BaseMatches, - void *UserData); + bool lookupInBases(ASTContext &Context, const CXXRecordDecl *Record, + CXXRecordDecl::BaseMatchesCallback BaseMatches); + public: typedef std::list<CXXBasePath>::iterator paths_iterator; typedef std::list<CXXBasePath>::const_iterator const_paths_iterator; @@ -173,15 +172,12 @@ public: /// BasePaths - Construct a new BasePaths structure to record the /// paths for a derived-to-base search. - explicit CXXBasePaths(bool FindAmbiguities = true, - bool RecordPaths = true, + explicit CXXBasePaths(bool FindAmbiguities = true, bool RecordPaths = true, bool DetectVirtual = true) - : FindAmbiguities(FindAmbiguities), RecordPaths(RecordPaths), - DetectVirtual(DetectVirtual), DetectedVirtual(nullptr), - DeclsFound(nullptr), NumDeclsFound(0) { } - - ~CXXBasePaths() { delete [] DeclsFound; } - + : FindAmbiguities(FindAmbiguities), RecordPaths(RecordPaths), + DetectVirtual(DetectVirtual), DetectedVirtual(nullptr), + NumDeclsFound(0) {} + paths_iterator begin() { return Paths.begin(); } paths_iterator end() { return Paths.end(); } const_paths_iterator begin() const { return Paths.begin(); } diff --git a/contrib/llvm/tools/clang/include/clang/AST/CharUnits.h b/contrib/llvm/tools/clang/include/clang/AST/CharUnits.h index 72ca9f5..1d22bcc 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/CharUnits.h +++ b/contrib/llvm/tools/clang/include/clang/AST/CharUnits.h @@ -130,6 +130,14 @@ namespace clang { return (Quantity & -Quantity) == Quantity; } + /// Test whether this is a multiple of the other value. + /// + /// Among other things, this promises that + /// self.RoundUpToAlignment(N) will just return self. + bool isMultipleOf(CharUnits N) const { + return (*this % N) == 0; + } + // Arithmetic operators. CharUnits operator* (QuantityType N) const { return CharUnits(Quantity * N); @@ -172,10 +180,20 @@ namespace clang { /// Given that this is a non-zero alignment value, what is the /// alignment at the given offset? - CharUnits alignmentAtOffset(CharUnits offset) { + CharUnits alignmentAtOffset(CharUnits offset) const { + assert(Quantity != 0 && "offsetting from unknown alignment?"); return CharUnits(llvm::MinAlign(Quantity, offset.Quantity)); } + /// Given that this is the alignment of the first element of an + /// array, return the minimum alignment of any element in the array. + CharUnits alignmentOfArrayElement(CharUnits elementSize) const { + // Since we don't track offsetted alignments, the alignment of + // the second element (or any odd element) will be minimally + // aligned. + return alignmentAtOffset(elementSize); + } + }; // class CharUnit } // namespace clang diff --git a/contrib/llvm/tools/clang/include/clang/AST/CommentSema.h b/contrib/llvm/tools/clang/include/clang/AST/CommentSema.h index 9b05d39..6a80383 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/CommentSema.h +++ b/contrib/llvm/tools/clang/include/clang/AST/CommentSema.h @@ -79,12 +79,8 @@ public: /// Returns a copy of array, owned by Sema's allocator. template<typename T> ArrayRef<T> copyArray(ArrayRef<T> Source) { - size_t Size = Source.size(); - if (Size != 0) { - T *Mem = Allocator.Allocate<T>(Size); - std::uninitialized_copy(Source.begin(), Source.end(), Mem); - return llvm::makeArrayRef(Mem, Size); - } + if (!Source.empty()) + return Source.copy(Allocator); return None; } diff --git a/contrib/llvm/tools/clang/include/clang/AST/DataRecursiveASTVisitor.h b/contrib/llvm/tools/clang/include/clang/AST/DataRecursiveASTVisitor.h deleted file mode 100644 index dd167fe..0000000 --- a/contrib/llvm/tools/clang/include/clang/AST/DataRecursiveASTVisitor.h +++ /dev/null @@ -1,2691 +0,0 @@ -//===--- DataRecursiveASTVisitor.h - Data-Recursive AST Visitor -*- 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 DataRecursiveASTVisitor interface, which recursively -// traverses the entire AST, using data recursion for Stmts/Exprs. -// -//===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_AST_DATARECURSIVEASTVISITOR_H -#define LLVM_CLANG_AST_DATARECURSIVEASTVISITOR_H - -#include "clang/AST/Attr.h" -#include "clang/AST/Decl.h" -#include "clang/AST/DeclCXX.h" -#include "clang/AST/DeclFriend.h" -#include "clang/AST/DeclObjC.h" -#include "clang/AST/DeclOpenMP.h" -#include "clang/AST/DeclTemplate.h" -#include "clang/AST/Expr.h" -#include "clang/AST/ExprCXX.h" -#include "clang/AST/ExprObjC.h" -#include "clang/AST/NestedNameSpecifier.h" -#include "clang/AST/Stmt.h" -#include "clang/AST/StmtCXX.h" -#include "clang/AST/StmtObjC.h" -#include "clang/AST/StmtOpenMP.h" -#include "clang/AST/TemplateBase.h" -#include "clang/AST/TemplateName.h" -#include "clang/AST/Type.h" -#include "clang/AST/TypeLoc.h" - -// The following three macros are used for meta programming. The code -// using them is responsible for defining macro OPERATOR(). - -// All unary operators. -#define UNARYOP_LIST() \ - OPERATOR(PostInc) OPERATOR(PostDec) OPERATOR(PreInc) OPERATOR(PreDec) \ - OPERATOR(AddrOf) OPERATOR(Deref) OPERATOR(Plus) OPERATOR(Minus) \ - OPERATOR(Not) OPERATOR(LNot) OPERATOR(Real) OPERATOR(Imag) \ - OPERATOR(Extension) - -// All binary operators (excluding compound assign operators). -#define BINOP_LIST() \ - OPERATOR(PtrMemD) OPERATOR(PtrMemI) OPERATOR(Mul) OPERATOR(Div) \ - OPERATOR(Rem) OPERATOR(Add) OPERATOR(Sub) OPERATOR(Shl) OPERATOR(Shr) \ - OPERATOR(LT) OPERATOR(GT) OPERATOR(LE) OPERATOR(GE) OPERATOR(EQ) \ - OPERATOR(NE) OPERATOR(And) OPERATOR(Xor) OPERATOR(Or) OPERATOR(LAnd) \ - OPERATOR(LOr) OPERATOR(Assign) OPERATOR(Comma) - -// All compound assign operators. -#define CAO_LIST() \ - OPERATOR(Mul) OPERATOR(Div) OPERATOR(Rem) OPERATOR(Add) OPERATOR(Sub) \ - OPERATOR(Shl) OPERATOR(Shr) OPERATOR(And) OPERATOR(Or) OPERATOR(Xor) - -namespace clang { - -// Reduce the diff between RecursiveASTVisitor / DataRecursiveASTVisitor to -// make it easier to track changes and keep the two in sync. -#define RecursiveASTVisitor DataRecursiveASTVisitor - -// A helper macro to implement short-circuiting when recursing. It -// invokes CALL_EXPR, which must be a method call, on the derived -// object (s.t. a user of RecursiveASTVisitor can override the method -// in CALL_EXPR). -#define TRY_TO(CALL_EXPR) \ - do { \ - if (!getDerived().CALL_EXPR) \ - return false; \ - } while (0) - -/// \brief A class that does preorder 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); -/// 2. at a given node, walk up the class hierarchy, starting from -/// the node's dynamic type, until the top-most class (e.g. Stmt, -/// Decl, or Type) is reached. -/// 3. given a (node, class) combination, where 'class' is some base -/// class of the dynamic type of 'node', call a user-overridable -/// function to actually visit the node. -/// -/// These tasks are done by three groups of methods, respectively: -/// 1. TraverseDecl(Decl *x) does task #1. It is the entry point -/// for traversing an AST rooted at x. This method simply -/// dispatches (i.e. forwards) to TraverseFoo(Foo *x) where Foo -/// is the dynamic type of *x, which calls WalkUpFromFoo(x) and -/// then recursively visits the child nodes of x. -/// TraverseStmt(Stmt *x) and TraverseType(QualType x) work -/// similarly. -/// 2. WalkUpFromFoo(Foo *x) does task #2. It does not try to visit -/// any child node of x. Instead, it first calls WalkUpFromBar(x) -/// where Bar is the direct parent class of Foo (unless Foo has -/// no parent), and then calls VisitFoo(x) (see the next list item). -/// 3. VisitFoo(Foo *x) does task #3. -/// -/// These three method groups are tiered (Traverse* > WalkUpFrom* > -/// Visit*). A method (e.g. Traverse*) may call methods from the same -/// tier (e.g. other Traverse*) or one tier lower (e.g. WalkUpFrom*). -/// It may not call methods from a higher tier. -/// -/// Note that since WalkUpFromFoo() calls WalkUpFromBar() (where Bar -/// is Foo's super class) before calling VisitFoo(), the result is -/// that the Visit*() methods for a given node are called in the -/// top-down order (e.g. for a node of type NamespaceDecl, the order will -/// be VisitDecl(), VisitNamedDecl(), and then VisitNamespaceDecl()). -/// -/// This scheme guarantees that all Visit*() calls for the same AST -/// node are grouped together. In other words, Visit*() methods for -/// different nodes are never interleaved. -/// -/// Stmts are traversed internally using a data queue to avoid a stack overflow -/// with hugely nested ASTs. -/// -/// Clients of this visitor should subclass the visitor (providing -/// themselves as the template argument, using the curiously recurring -/// template pattern) and override any of the Traverse*, WalkUpFrom*, -/// and Visit* methods for declarations, types, statements, -/// expressions, or other AST nodes where the visitor should customize -/// behavior. Most users only need to override Visit*. Advanced -/// users may override Traverse* and WalkUpFrom* to implement custom -/// traversal strategies. Returning false from one of these overridden -/// functions will abort the entire traversal. -/// -/// By default, this visitor tries to visit every part of the explicit -/// source code exactly once. The default policy towards templates -/// is to descend into the 'pattern' class or function body, not any -/// explicit or implicit instantiations. Explicit specializations -/// are still visited, and the patterns of partial specializations -/// are visited separately. This behavior can be changed by -/// overriding shouldVisitTemplateInstantiations() in the derived class -/// 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. -template <typename Derived> class RecursiveASTVisitor { -public: - /// \brief Return a reference to the derived class. - Derived &getDerived() { return *static_cast<Derived *>(this); } - - /// \brief Return whether this visitor should recurse into - /// template instantiations. - bool shouldVisitTemplateInstantiations() const { return false; } - - /// \brief Return whether this visitor should recurse into the types of - /// TypeLocs. - bool shouldWalkTypesOfTypeLocs() const { return true; } - - /// \brief Recursively visit a statement or expression, by - /// dispatching to Traverse*() based on the argument's dynamic type. - /// - /// \returns false if the visitation was terminated early, true - /// otherwise (including when the argument is NULL). - bool TraverseStmt(Stmt *S); - - /// \brief Recursively visit a type, by dispatching to - /// Traverse*Type() based on the argument's getTypeClass() property. - /// - /// \returns false if the visitation was terminated early, true - /// otherwise (including when the argument is a Null type). - bool TraverseType(QualType T); - - /// \brief Recursively visit a type with location, by dispatching to - /// Traverse*TypeLoc() based on the argument type's getTypeClass() property. - /// - /// \returns false if the visitation was terminated early, true - /// otherwise (including when the argument is a Null type location). - bool TraverseTypeLoc(TypeLoc TL); - - /// \brief Recursively visit an attribute, by dispatching to - /// Traverse*Attr() based on the argument's dynamic type. - /// - /// \returns false if the visitation was terminated early, true - /// otherwise (including when the argument is a Null type location). - bool TraverseAttr(Attr *At); - - /// \brief Recursively visit a declaration, by dispatching to - /// Traverse*Decl() based on the argument's dynamic type. - /// - /// \returns false if the visitation was terminated early, true - /// otherwise (including when the argument is NULL). - bool TraverseDecl(Decl *D); - - /// \brief Recursively visit a C++ nested-name-specifier. - /// - /// \returns false if the visitation was terminated early, true otherwise. - bool TraverseNestedNameSpecifier(NestedNameSpecifier *NNS); - - /// \brief Recursively visit a C++ nested-name-specifier with location - /// information. - /// - /// \returns false if the visitation was terminated early, true otherwise. - bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS); - - /// \brief Recursively visit a name with its location information. - /// - /// \returns false if the visitation was terminated early, true otherwise. - bool TraverseDeclarationNameInfo(DeclarationNameInfo NameInfo); - - /// \brief Recursively visit a template name and dispatch to the - /// appropriate method. - /// - /// \returns false if the visitation was terminated early, true otherwise. - bool TraverseTemplateName(TemplateName Template); - - /// \brief Recursively visit a template argument and dispatch to the - /// appropriate method for the argument type. - /// - /// \returns false if the visitation was terminated early, true otherwise. - // FIXME: migrate callers to TemplateArgumentLoc instead. - bool TraverseTemplateArgument(const TemplateArgument &Arg); - - /// \brief Recursively visit a template argument location and dispatch to the - /// appropriate method for the argument type. - /// - /// \returns false if the visitation was terminated early, true otherwise. - bool TraverseTemplateArgumentLoc(const TemplateArgumentLoc &ArgLoc); - - /// \brief Recursively visit a set of template arguments. - /// This can be overridden by a subclass, but it's not expected that - /// will be needed -- this visitor always dispatches to another. - /// - /// \returns false if the visitation was terminated early, true otherwise. - // FIXME: take a TemplateArgumentLoc* (or TemplateArgumentListInfo) instead. - bool TraverseTemplateArguments(const TemplateArgument *Args, - unsigned NumArgs); - - /// \brief Recursively visit a constructor initializer. This - /// automatically dispatches to another visitor for the initializer - /// expression, but not for the name of the initializer, so may - /// be overridden for clients that need access to the name. - /// - /// \returns false if the visitation was terminated early, true otherwise. - bool TraverseConstructorInitializer(CXXCtorInitializer *Init); - - /// \brief Recursively visit a lambda capture. - /// - /// \returns false if the visitation was terminated early, true otherwise. - bool TraverseLambdaCapture(LambdaExpr *LE, const LambdaCapture *C); - - /// \brief Recursively visit the body of a lambda expression. - /// - /// This provides a hook for visitors that need more context when visiting - /// \c LE->getBody(). - /// - /// \returns false if the visitation was terminated early, true otherwise. - bool TraverseLambdaBody(LambdaExpr *LE); - - // ---- Methods on Attrs ---- - - // \brief Visit an attribute. - bool VisitAttr(Attr *A) { return true; } - -// Declare Traverse* and empty Visit* for all Attr classes. -#define ATTR_VISITOR_DECLS_ONLY -#include "clang/AST/AttrVisitor.inc" -#undef ATTR_VISITOR_DECLS_ONLY - -// ---- Methods on Stmts ---- - -// Declare Traverse*() for all concrete Stmt classes. -#define ABSTRACT_STMT(STMT) -#define STMT(CLASS, PARENT) bool Traverse##CLASS(CLASS *S); -#include "clang/AST/StmtNodes.inc" - // The above header #undefs ABSTRACT_STMT and STMT upon exit. - - // Define WalkUpFrom*() and empty Visit*() for all Stmt classes. - bool WalkUpFromStmt(Stmt *S) { return getDerived().VisitStmt(S); } - bool VisitStmt(Stmt *S) { return true; } -#define STMT(CLASS, PARENT) \ - bool WalkUpFrom##CLASS(CLASS *S) { \ - TRY_TO(WalkUpFrom##PARENT(S)); \ - TRY_TO(Visit##CLASS(S)); \ - return true; \ - } \ - bool Visit##CLASS(CLASS *S) { return true; } -#include "clang/AST/StmtNodes.inc" - -// Define Traverse*(), WalkUpFrom*(), and Visit*() for unary -// operator methods. Unary operators are not classes in themselves -// (they're all opcodes in UnaryOperator) but do have visitors. -#define OPERATOR(NAME) \ - bool TraverseUnary##NAME(UnaryOperator *S) { \ - TRY_TO(WalkUpFromUnary##NAME(S)); \ - StmtQueueAction StmtQueue(*this); \ - StmtQueue.queue(S->getSubExpr()); \ - return true; \ - } \ - bool WalkUpFromUnary##NAME(UnaryOperator *S) { \ - TRY_TO(WalkUpFromUnaryOperator(S)); \ - TRY_TO(VisitUnary##NAME(S)); \ - return true; \ - } \ - bool VisitUnary##NAME(UnaryOperator *S) { return true; } - - UNARYOP_LIST() -#undef OPERATOR - -// Define Traverse*(), WalkUpFrom*(), and Visit*() for binary -// operator methods. Binary operators are not classes in themselves -// (they're all opcodes in BinaryOperator) but do have visitors. -#define GENERAL_BINOP_FALLBACK(NAME, BINOP_TYPE) \ - bool TraverseBin##NAME(BINOP_TYPE *S) { \ - TRY_TO(WalkUpFromBin##NAME(S)); \ - StmtQueueAction StmtQueue(*this); \ - StmtQueue.queue(S->getLHS()); \ - StmtQueue.queue(S->getRHS()); \ - return true; \ - } \ - bool WalkUpFromBin##NAME(BINOP_TYPE *S) { \ - TRY_TO(WalkUpFrom##BINOP_TYPE(S)); \ - TRY_TO(VisitBin##NAME(S)); \ - return true; \ - } \ - bool VisitBin##NAME(BINOP_TYPE *S) { return true; } - -#define OPERATOR(NAME) GENERAL_BINOP_FALLBACK(NAME, BinaryOperator) - BINOP_LIST() -#undef OPERATOR - -// Define Traverse*(), WalkUpFrom*(), and Visit*() for compound -// assignment methods. Compound assignment operators are not -// classes in themselves (they're all opcodes in -// CompoundAssignOperator) but do have visitors. -#define OPERATOR(NAME) \ - GENERAL_BINOP_FALLBACK(NAME##Assign, CompoundAssignOperator) - - CAO_LIST() -#undef OPERATOR -#undef GENERAL_BINOP_FALLBACK - -// ---- Methods on Types ---- -// FIXME: revamp to take TypeLoc's rather than Types. - -// Declare Traverse*() for all concrete Type classes. -#define ABSTRACT_TYPE(CLASS, BASE) -#define TYPE(CLASS, BASE) bool Traverse##CLASS##Type(CLASS##Type *T); -#include "clang/AST/TypeNodes.def" - // The above header #undefs ABSTRACT_TYPE and TYPE upon exit. - - // Define WalkUpFrom*() and empty Visit*() for all Type classes. - bool WalkUpFromType(Type *T) { return getDerived().VisitType(T); } - bool VisitType(Type *T) { return true; } -#define TYPE(CLASS, BASE) \ - bool WalkUpFrom##CLASS##Type(CLASS##Type *T) { \ - TRY_TO(WalkUpFrom##BASE(T)); \ - TRY_TO(Visit##CLASS##Type(T)); \ - return true; \ - } \ - bool Visit##CLASS##Type(CLASS##Type *T) { return true; } -#include "clang/AST/TypeNodes.def" - -// ---- Methods on TypeLocs ---- -// FIXME: this currently just calls the matching Type methods - -// Declare Traverse*() for all concrete TypeLoc classes. -#define ABSTRACT_TYPELOC(CLASS, BASE) -#define TYPELOC(CLASS, BASE) bool Traverse##CLASS##TypeLoc(CLASS##TypeLoc TL); -#include "clang/AST/TypeLocNodes.def" - // The above header #undefs ABSTRACT_TYPELOC and TYPELOC upon exit. - - // Define WalkUpFrom*() and empty Visit*() for all TypeLoc classes. - bool WalkUpFromTypeLoc(TypeLoc TL) { return getDerived().VisitTypeLoc(TL); } - bool VisitTypeLoc(TypeLoc TL) { return true; } - - // QualifiedTypeLoc and UnqualTypeLoc are not declared in - // TypeNodes.def and thus need to be handled specially. - bool WalkUpFromQualifiedTypeLoc(QualifiedTypeLoc TL) { - return getDerived().VisitUnqualTypeLoc(TL.getUnqualifiedLoc()); - } - bool VisitQualifiedTypeLoc(QualifiedTypeLoc TL) { return true; } - bool WalkUpFromUnqualTypeLoc(UnqualTypeLoc TL) { - return getDerived().VisitUnqualTypeLoc(TL.getUnqualifiedLoc()); - } - bool VisitUnqualTypeLoc(UnqualTypeLoc TL) { return true; } - -// Note that BASE includes trailing 'Type' which CLASS doesn't. -#define TYPE(CLASS, BASE) \ - bool WalkUpFrom##CLASS##TypeLoc(CLASS##TypeLoc TL) { \ - TRY_TO(WalkUpFrom##BASE##Loc(TL)); \ - TRY_TO(Visit##CLASS##TypeLoc(TL)); \ - return true; \ - } \ - bool Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { return true; } -#include "clang/AST/TypeNodes.def" - -// ---- Methods on Decls ---- - -// Declare Traverse*() for all concrete Decl classes. -#define ABSTRACT_DECL(DECL) -#define DECL(CLASS, BASE) bool Traverse##CLASS##Decl(CLASS##Decl *D); -#include "clang/AST/DeclNodes.inc" - // The above header #undefs ABSTRACT_DECL and DECL upon exit. - - // Define WalkUpFrom*() and empty Visit*() for all Decl classes. - bool WalkUpFromDecl(Decl *D) { return getDerived().VisitDecl(D); } - bool VisitDecl(Decl *D) { return true; } -#define DECL(CLASS, BASE) \ - bool WalkUpFrom##CLASS##Decl(CLASS##Decl *D) { \ - TRY_TO(WalkUpFrom##BASE(D)); \ - TRY_TO(Visit##CLASS##Decl(D)); \ - return true; \ - } \ - bool Visit##CLASS##Decl(CLASS##Decl *D) { return true; } -#include "clang/AST/DeclNodes.inc" - -private: - // These are helper methods used by more than one Traverse* method. - bool TraverseTemplateParameterListHelper(TemplateParameterList *TPL); - bool TraverseClassInstantiations(ClassTemplateDecl *D); - bool TraverseVariableInstantiations(VarTemplateDecl *D); - bool TraverseFunctionInstantiations(FunctionTemplateDecl *D); - bool TraverseTemplateArgumentLocsHelper(const TemplateArgumentLoc *TAL, - unsigned Count); - bool TraverseArrayTypeLocHelper(ArrayTypeLoc TL); - bool TraverseRecordHelper(RecordDecl *D); - bool TraverseCXXRecordHelper(CXXRecordDecl *D); - bool TraverseDeclaratorHelper(DeclaratorDecl *D); - bool TraverseDeclContextHelper(DeclContext *DC); - bool TraverseFunctionHelper(FunctionDecl *D); - bool TraverseVarHelper(VarDecl *D); - bool TraverseOMPExecutableDirective(OMPExecutableDirective *S); - bool TraverseOMPLoopDirective(OMPLoopDirective *S); - bool TraverseOMPClause(OMPClause *C); -#define OPENMP_CLAUSE(Name, Class) bool Visit##Class(Class *C); -#include "clang/Basic/OpenMPKinds.def" - /// \brief Process clauses with list of variables. - template <typename T> bool VisitOMPClauseList(T *Node); - - typedef SmallVector<Stmt *, 16> StmtsTy; - typedef SmallVector<StmtsTy *, 4> QueuesTy; - - QueuesTy Queues; - - class NewQueueRAII { - RecursiveASTVisitor &RAV; - - public: - NewQueueRAII(StmtsTy &queue, RecursiveASTVisitor &RAV) : RAV(RAV) { - RAV.Queues.push_back(&queue); - } - ~NewQueueRAII() { RAV.Queues.pop_back(); } - }; - - StmtsTy &getCurrentQueue() { - assert(!Queues.empty() && "base TraverseStmt was never called?"); - return *Queues.back(); - } - -public: - class StmtQueueAction { - StmtsTy &CurrQueue; - - public: - explicit StmtQueueAction(RecursiveASTVisitor &RAV) - : CurrQueue(RAV.getCurrentQueue()) {} - - void queue(Stmt *S) { CurrQueue.push_back(S); } - }; -}; - -#define DISPATCH(NAME, CLASS, VAR) \ - return getDerived().Traverse##NAME(static_cast<CLASS *>(VAR)) - -template <typename Derived> -bool RecursiveASTVisitor<Derived>::TraverseStmt(Stmt *S) { - if (!S) - return true; - - StmtsTy Queue, StmtsToEnqueue; - Queue.push_back(S); - NewQueueRAII NQ(StmtsToEnqueue, *this); - - while (!Queue.empty()) { - S = Queue.pop_back_val(); - if (!S) - continue; - - StmtsToEnqueue.clear(); - -#define DISPATCH_STMT(NAME, CLASS, VAR) \ - TRY_TO(Traverse##NAME(static_cast<CLASS *>(VAR))); \ - break - - // If we have a binary expr, dispatch to the subcode of the binop. A smart - // optimizer (e.g. LLVM) will fold this comparison into the switch stmt - // below. - if (BinaryOperator *BinOp = dyn_cast<BinaryOperator>(S)) { - switch (BinOp->getOpcode()) { -#define OPERATOR(NAME) \ - case BO_##NAME: \ - DISPATCH_STMT(Bin##NAME, BinaryOperator, S); - - BINOP_LIST() -#undef OPERATOR -#undef BINOP_LIST - -#define OPERATOR(NAME) \ - case BO_##NAME##Assign: \ - DISPATCH_STMT(Bin##NAME##Assign, CompoundAssignOperator, S); - - CAO_LIST() -#undef OPERATOR -#undef CAO_LIST - } - } else if (UnaryOperator *UnOp = dyn_cast<UnaryOperator>(S)) { - switch (UnOp->getOpcode()) { -#define OPERATOR(NAME) \ - case UO_##NAME: \ - DISPATCH_STMT(Unary##NAME, UnaryOperator, S); - - UNARYOP_LIST() -#undef OPERATOR -#undef UNARYOP_LIST - } - } else { - - // Top switch stmt: dispatch to TraverseFooStmt for each concrete FooStmt. - switch (S->getStmtClass()) { - case Stmt::NoStmtClass: - break; -#define ABSTRACT_STMT(STMT) -#define STMT(CLASS, PARENT) \ - case Stmt::CLASS##Class: \ - DISPATCH_STMT(CLASS, CLASS, S); -#include "clang/AST/StmtNodes.inc" - } - } - - Queue.append(StmtsToEnqueue.rbegin(), StmtsToEnqueue.rend()); - } - - return true; -} - -#undef DISPATCH_STMT - -template <typename Derived> -bool RecursiveASTVisitor<Derived>::TraverseType(QualType T) { - if (T.isNull()) - return true; - - switch (T->getTypeClass()) { -#define ABSTRACT_TYPE(CLASS, BASE) -#define TYPE(CLASS, BASE) \ - case Type::CLASS: \ - DISPATCH(CLASS##Type, CLASS##Type, const_cast<Type *>(T.getTypePtr())); -#include "clang/AST/TypeNodes.def" - } - - return true; -} - -template <typename Derived> -bool RecursiveASTVisitor<Derived>::TraverseTypeLoc(TypeLoc TL) { - if (TL.isNull()) - return true; - - switch (TL.getTypeLocClass()) { -#define ABSTRACT_TYPELOC(CLASS, BASE) -#define TYPELOC(CLASS, BASE) \ - case TypeLoc::CLASS: \ - return getDerived().Traverse##CLASS##TypeLoc(TL.castAs<CLASS##TypeLoc>()); -#include "clang/AST/TypeLocNodes.def" - } - - return true; -} - -// Define the Traverse*Attr(Attr* A) methods -#define VISITORCLASS RecursiveASTVisitor -#include "clang/AST/AttrVisitor.inc" -#undef VISITORCLASS - -template <typename Derived> -bool RecursiveASTVisitor<Derived>::TraverseDecl(Decl *D) { - if (!D) - return true; - - // As a syntax visitor, we want to ignore declarations for - // implicitly-defined declarations (ones not typed explicitly by the - // user). - if (D->isImplicit()) - return true; - - switch (D->getKind()) { -#define ABSTRACT_DECL(DECL) -#define DECL(CLASS, BASE) \ - case Decl::CLASS: \ - if (!getDerived().Traverse##CLASS##Decl(static_cast<CLASS##Decl *>(D))) \ - return false; \ - break; -#include "clang/AST/DeclNodes.inc" - } - - // Visit any attributes attached to this declaration. - for (auto *I : D->attrs()) { - if (!getDerived().TraverseAttr(I)) - return false; - } - return true; -} - -#undef DISPATCH - -template <typename Derived> -bool RecursiveASTVisitor<Derived>::TraverseNestedNameSpecifier( - NestedNameSpecifier *NNS) { - if (!NNS) - return true; - - if (NNS->getPrefix()) - TRY_TO(TraverseNestedNameSpecifier(NNS->getPrefix())); - - switch (NNS->getKind()) { - case NestedNameSpecifier::Identifier: - case NestedNameSpecifier::Namespace: - case NestedNameSpecifier::NamespaceAlias: - case NestedNameSpecifier::Global: - case NestedNameSpecifier::Super: - return true; - - case NestedNameSpecifier::TypeSpec: - case NestedNameSpecifier::TypeSpecWithTemplate: - TRY_TO(TraverseType(QualType(NNS->getAsType(), 0))); - } - - return true; -} - -template <typename Derived> -bool RecursiveASTVisitor<Derived>::TraverseNestedNameSpecifierLoc( - NestedNameSpecifierLoc NNS) { - if (!NNS) - return true; - - if (NestedNameSpecifierLoc Prefix = NNS.getPrefix()) - TRY_TO(TraverseNestedNameSpecifierLoc(Prefix)); - - switch (NNS.getNestedNameSpecifier()->getKind()) { - case NestedNameSpecifier::Identifier: - case NestedNameSpecifier::Namespace: - case NestedNameSpecifier::NamespaceAlias: - case NestedNameSpecifier::Global: - case NestedNameSpecifier::Super: - return true; - - case NestedNameSpecifier::TypeSpec: - case NestedNameSpecifier::TypeSpecWithTemplate: - TRY_TO(TraverseTypeLoc(NNS.getTypeLoc())); - break; - } - - return true; -} - -template <typename Derived> -bool RecursiveASTVisitor<Derived>::TraverseDeclarationNameInfo( - DeclarationNameInfo NameInfo) { - switch (NameInfo.getName().getNameKind()) { - case DeclarationName::CXXConstructorName: - case DeclarationName::CXXDestructorName: - case DeclarationName::CXXConversionFunctionName: - if (TypeSourceInfo *TSInfo = NameInfo.getNamedTypeInfo()) - TRY_TO(TraverseTypeLoc(TSInfo->getTypeLoc())); - - break; - - case DeclarationName::Identifier: - case DeclarationName::ObjCZeroArgSelector: - case DeclarationName::ObjCOneArgSelector: - case DeclarationName::ObjCMultiArgSelector: - case DeclarationName::CXXOperatorName: - case DeclarationName::CXXLiteralOperatorName: - case DeclarationName::CXXUsingDirective: - break; - } - - return true; -} - -template <typename Derived> -bool RecursiveASTVisitor<Derived>::TraverseTemplateName(TemplateName Template) { - if (DependentTemplateName *DTN = Template.getAsDependentTemplateName()) - TRY_TO(TraverseNestedNameSpecifier(DTN->getQualifier())); - else if (QualifiedTemplateName *QTN = Template.getAsQualifiedTemplateName()) - TRY_TO(TraverseNestedNameSpecifier(QTN->getQualifier())); - - return true; -} - -template <typename Derived> -bool RecursiveASTVisitor<Derived>::TraverseTemplateArgument( - const TemplateArgument &Arg) { - switch (Arg.getKind()) { - case TemplateArgument::Null: - case TemplateArgument::Declaration: - case TemplateArgument::Integral: - case TemplateArgument::NullPtr: - return true; - - case TemplateArgument::Type: - return getDerived().TraverseType(Arg.getAsType()); - - case TemplateArgument::Template: - case TemplateArgument::TemplateExpansion: - return getDerived().TraverseTemplateName( - Arg.getAsTemplateOrTemplatePattern()); - - case TemplateArgument::Expression: - return getDerived().TraverseStmt(Arg.getAsExpr()); - - case TemplateArgument::Pack: - return getDerived().TraverseTemplateArguments(Arg.pack_begin(), - Arg.pack_size()); - } - - return true; -} - -// FIXME: no template name location? -// FIXME: no source locations for a template argument pack? -template <typename Derived> -bool RecursiveASTVisitor<Derived>::TraverseTemplateArgumentLoc( - const TemplateArgumentLoc &ArgLoc) { - const TemplateArgument &Arg = ArgLoc.getArgument(); - - switch (Arg.getKind()) { - case TemplateArgument::Null: - case TemplateArgument::Declaration: - case TemplateArgument::Integral: - case TemplateArgument::NullPtr: - return true; - - case TemplateArgument::Type: { - // FIXME: how can TSI ever be NULL? - if (TypeSourceInfo *TSI = ArgLoc.getTypeSourceInfo()) - return getDerived().TraverseTypeLoc(TSI->getTypeLoc()); - else - return getDerived().TraverseType(Arg.getAsType()); - } - - case TemplateArgument::Template: - case TemplateArgument::TemplateExpansion: - if (ArgLoc.getTemplateQualifierLoc()) - TRY_TO(getDerived().TraverseNestedNameSpecifierLoc( - ArgLoc.getTemplateQualifierLoc())); - return getDerived().TraverseTemplateName( - Arg.getAsTemplateOrTemplatePattern()); - - case TemplateArgument::Expression: - return getDerived().TraverseStmt(ArgLoc.getSourceExpression()); - - case TemplateArgument::Pack: - return getDerived().TraverseTemplateArguments(Arg.pack_begin(), - Arg.pack_size()); - } - - return true; -} - -template <typename Derived> -bool RecursiveASTVisitor<Derived>::TraverseTemplateArguments( - const TemplateArgument *Args, unsigned NumArgs) { - for (unsigned I = 0; I != NumArgs; ++I) { - TRY_TO(TraverseTemplateArgument(Args[I])); - } - - return true; -} - -template <typename Derived> -bool RecursiveASTVisitor<Derived>::TraverseConstructorInitializer( - CXXCtorInitializer *Init) { - if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo()) - TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc())); - - if (Init->isWritten()) - TRY_TO(TraverseStmt(Init->getInit())); - return true; -} - -template <typename Derived> -bool -RecursiveASTVisitor<Derived>::TraverseLambdaCapture(LambdaExpr *LE, - const LambdaCapture *C) { - if (LE->isInitCapture(C)) - TRY_TO(TraverseDecl(C->getCapturedVar())); - return true; -} - -template <typename Derived> -bool RecursiveASTVisitor<Derived>::TraverseLambdaBody(LambdaExpr *LE) { - StmtQueueAction StmtQueue(*this); - StmtQueue.queue(LE->getBody()); - return true; -} - -// ----------------- Type traversal ----------------- - -// This macro makes available a variable T, the passed-in type. -#define DEF_TRAVERSE_TYPE(TYPE, CODE) \ - template <typename Derived> \ - bool RecursiveASTVisitor<Derived>::Traverse##TYPE(TYPE *T) { \ - TRY_TO(WalkUpFrom##TYPE(T)); \ - { CODE; } \ - return true; \ - } - -DEF_TRAVERSE_TYPE(BuiltinType, {}) - -DEF_TRAVERSE_TYPE(ComplexType, { TRY_TO(TraverseType(T->getElementType())); }) - -DEF_TRAVERSE_TYPE(PointerType, { TRY_TO(TraverseType(T->getPointeeType())); }) - -DEF_TRAVERSE_TYPE(BlockPointerType, - { TRY_TO(TraverseType(T->getPointeeType())); }) - -DEF_TRAVERSE_TYPE(LValueReferenceType, - { TRY_TO(TraverseType(T->getPointeeType())); }) - -DEF_TRAVERSE_TYPE(RValueReferenceType, - { TRY_TO(TraverseType(T->getPointeeType())); }) - -DEF_TRAVERSE_TYPE(MemberPointerType, { - TRY_TO(TraverseType(QualType(T->getClass(), 0))); - TRY_TO(TraverseType(T->getPointeeType())); -}) - -DEF_TRAVERSE_TYPE(AdjustedType, { TRY_TO(TraverseType(T->getOriginalType())); }) - -DEF_TRAVERSE_TYPE(DecayedType, { TRY_TO(TraverseType(T->getOriginalType())); }) - -DEF_TRAVERSE_TYPE(ConstantArrayType, - { TRY_TO(TraverseType(T->getElementType())); }) - -DEF_TRAVERSE_TYPE(IncompleteArrayType, - { TRY_TO(TraverseType(T->getElementType())); }) - -DEF_TRAVERSE_TYPE(VariableArrayType, { - TRY_TO(TraverseType(T->getElementType())); - TRY_TO(TraverseStmt(T->getSizeExpr())); -}) - -DEF_TRAVERSE_TYPE(DependentSizedArrayType, { - TRY_TO(TraverseType(T->getElementType())); - if (T->getSizeExpr()) - TRY_TO(TraverseStmt(T->getSizeExpr())); -}) - -DEF_TRAVERSE_TYPE(DependentSizedExtVectorType, { - if (T->getSizeExpr()) - TRY_TO(TraverseStmt(T->getSizeExpr())); - TRY_TO(TraverseType(T->getElementType())); -}) - -DEF_TRAVERSE_TYPE(VectorType, { TRY_TO(TraverseType(T->getElementType())); }) - -DEF_TRAVERSE_TYPE(ExtVectorType, { TRY_TO(TraverseType(T->getElementType())); }) - -DEF_TRAVERSE_TYPE(FunctionNoProtoType, - { TRY_TO(TraverseType(T->getReturnType())); }) - -DEF_TRAVERSE_TYPE(FunctionProtoType, { - TRY_TO(TraverseType(T->getReturnType())); - - for (const auto &A : T->param_types()) { - TRY_TO(TraverseType(A)); - } - - for (const auto &E : T->exceptions()) { - TRY_TO(TraverseType(E)); - } - - if (Expr *NE = T->getNoexceptExpr()) - TRY_TO(TraverseStmt(NE)); -}) - -DEF_TRAVERSE_TYPE(UnresolvedUsingType, {}) -DEF_TRAVERSE_TYPE(TypedefType, {}) - -DEF_TRAVERSE_TYPE(TypeOfExprType, - { TRY_TO(TraverseStmt(T->getUnderlyingExpr())); }) - -DEF_TRAVERSE_TYPE(TypeOfType, { TRY_TO(TraverseType(T->getUnderlyingType())); }) - -DEF_TRAVERSE_TYPE(DecltypeType, - { TRY_TO(TraverseStmt(T->getUnderlyingExpr())); }) - -DEF_TRAVERSE_TYPE(UnaryTransformType, { - TRY_TO(TraverseType(T->getBaseType())); - TRY_TO(TraverseType(T->getUnderlyingType())); -}) - -DEF_TRAVERSE_TYPE(AutoType, { TRY_TO(TraverseType(T->getDeducedType())); }) - -DEF_TRAVERSE_TYPE(RecordType, {}) -DEF_TRAVERSE_TYPE(EnumType, {}) -DEF_TRAVERSE_TYPE(TemplateTypeParmType, {}) -DEF_TRAVERSE_TYPE(SubstTemplateTypeParmType, {}) -DEF_TRAVERSE_TYPE(SubstTemplateTypeParmPackType, {}) - -DEF_TRAVERSE_TYPE(TemplateSpecializationType, { - TRY_TO(TraverseTemplateName(T->getTemplateName())); - TRY_TO(TraverseTemplateArguments(T->getArgs(), T->getNumArgs())); -}) - -DEF_TRAVERSE_TYPE(InjectedClassNameType, {}) - -DEF_TRAVERSE_TYPE(AttributedType, - { TRY_TO(TraverseType(T->getModifiedType())); }) - -DEF_TRAVERSE_TYPE(ParenType, { TRY_TO(TraverseType(T->getInnerType())); }) - -DEF_TRAVERSE_TYPE(ElaboratedType, { - if (T->getQualifier()) { - TRY_TO(TraverseNestedNameSpecifier(T->getQualifier())); - } - TRY_TO(TraverseType(T->getNamedType())); -}) - -DEF_TRAVERSE_TYPE(DependentNameType, - { TRY_TO(TraverseNestedNameSpecifier(T->getQualifier())); }) - -DEF_TRAVERSE_TYPE(DependentTemplateSpecializationType, { - TRY_TO(TraverseNestedNameSpecifier(T->getQualifier())); - TRY_TO(TraverseTemplateArguments(T->getArgs(), T->getNumArgs())); -}) - -DEF_TRAVERSE_TYPE(PackExpansionType, { TRY_TO(TraverseType(T->getPattern())); }) - -DEF_TRAVERSE_TYPE(ObjCInterfaceType, {}) - -DEF_TRAVERSE_TYPE(ObjCObjectType, { - // We have to watch out here because an ObjCInterfaceType's base - // type is itself. - if (T->getBaseType().getTypePtr() != T) - TRY_TO(TraverseType(T->getBaseType())); - for (auto typeArg : T->getTypeArgsAsWritten()) { - TRY_TO(TraverseType(typeArg)); - } -}) - -DEF_TRAVERSE_TYPE(ObjCObjectPointerType, - { TRY_TO(TraverseType(T->getPointeeType())); }) - -DEF_TRAVERSE_TYPE(AtomicType, { TRY_TO(TraverseType(T->getValueType())); }) - -#undef DEF_TRAVERSE_TYPE - -// ----------------- TypeLoc traversal ----------------- - -// This macro makes available a variable TL, the passed-in TypeLoc. -// If requested, it calls WalkUpFrom* for the Type in the given TypeLoc, -// in addition to WalkUpFrom* for the TypeLoc itself, such that existing -// clients that override the WalkUpFrom*Type() and/or Visit*Type() methods -// continue to work. -#define DEF_TRAVERSE_TYPELOC(TYPE, CODE) \ - template <typename Derived> \ - bool RecursiveASTVisitor<Derived>::Traverse##TYPE##Loc(TYPE##Loc TL) { \ - if (getDerived().shouldWalkTypesOfTypeLocs()) \ - TRY_TO(WalkUpFrom##TYPE(const_cast<TYPE *>(TL.getTypePtr()))); \ - TRY_TO(WalkUpFrom##TYPE##Loc(TL)); \ - { CODE; } \ - return true; \ - } - -template <typename Derived> -bool -RecursiveASTVisitor<Derived>::TraverseQualifiedTypeLoc(QualifiedTypeLoc TL) { - // Move this over to the 'main' typeloc tree. Note that this is a - // move -- we pretend that we were really looking at the unqualified - // typeloc all along -- rather than a recursion, so we don't follow - // the normal CRTP plan of going through - // getDerived().TraverseTypeLoc. If we did, we'd be traversing - // twice for the same type (once as a QualifiedTypeLoc version of - // the type, once as an UnqualifiedTypeLoc version of the type), - // which in effect means we'd call VisitTypeLoc twice with the - // 'same' type. This solves that problem, at the cost of never - // seeing the qualified version of the type (unless the client - // subclasses TraverseQualifiedTypeLoc themselves). It's not a - // perfect solution. A perfect solution probably requires making - // QualifiedTypeLoc a wrapper around TypeLoc -- like QualType is a - // wrapper around Type* -- rather than being its own class in the - // type hierarchy. - return TraverseTypeLoc(TL.getUnqualifiedLoc()); -} - -DEF_TRAVERSE_TYPELOC(BuiltinType, {}) - -// FIXME: ComplexTypeLoc is unfinished -DEF_TRAVERSE_TYPELOC(ComplexType, { - TRY_TO(TraverseType(TL.getTypePtr()->getElementType())); -}) - -DEF_TRAVERSE_TYPELOC(PointerType, - { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); }) - -DEF_TRAVERSE_TYPELOC(BlockPointerType, - { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); }) - -DEF_TRAVERSE_TYPELOC(LValueReferenceType, - { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); }) - -DEF_TRAVERSE_TYPELOC(RValueReferenceType, - { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); }) - -// FIXME: location of base class? -// We traverse this in the type case as well, but how is it not reached through -// the pointee type? -DEF_TRAVERSE_TYPELOC(MemberPointerType, { - TRY_TO(TraverseType(QualType(TL.getTypePtr()->getClass(), 0))); - TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); -}) - -DEF_TRAVERSE_TYPELOC(AdjustedType, - { TRY_TO(TraverseTypeLoc(TL.getOriginalLoc())); }) - -DEF_TRAVERSE_TYPELOC(DecayedType, - { TRY_TO(TraverseTypeLoc(TL.getOriginalLoc())); }) - -template <typename Derived> -bool RecursiveASTVisitor<Derived>::TraverseArrayTypeLocHelper(ArrayTypeLoc TL) { - // This isn't available for ArrayType, but is for the ArrayTypeLoc. - TRY_TO(TraverseStmt(TL.getSizeExpr())); - return true; -} - -DEF_TRAVERSE_TYPELOC(ConstantArrayType, { - TRY_TO(TraverseTypeLoc(TL.getElementLoc())); - return TraverseArrayTypeLocHelper(TL); -}) - -DEF_TRAVERSE_TYPELOC(IncompleteArrayType, { - TRY_TO(TraverseTypeLoc(TL.getElementLoc())); - return TraverseArrayTypeLocHelper(TL); -}) - -DEF_TRAVERSE_TYPELOC(VariableArrayType, { - TRY_TO(TraverseTypeLoc(TL.getElementLoc())); - return TraverseArrayTypeLocHelper(TL); -}) - -DEF_TRAVERSE_TYPELOC(DependentSizedArrayType, { - TRY_TO(TraverseTypeLoc(TL.getElementLoc())); - return TraverseArrayTypeLocHelper(TL); -}) - -// FIXME: order? why not size expr first? -// FIXME: base VectorTypeLoc is unfinished -DEF_TRAVERSE_TYPELOC(DependentSizedExtVectorType, { - if (TL.getTypePtr()->getSizeExpr()) - TRY_TO(TraverseStmt(TL.getTypePtr()->getSizeExpr())); - TRY_TO(TraverseType(TL.getTypePtr()->getElementType())); -}) - -// FIXME: VectorTypeLoc is unfinished -DEF_TRAVERSE_TYPELOC(VectorType, { - TRY_TO(TraverseType(TL.getTypePtr()->getElementType())); -}) - -// FIXME: size and attributes -// FIXME: base VectorTypeLoc is unfinished -DEF_TRAVERSE_TYPELOC(ExtVectorType, { - TRY_TO(TraverseType(TL.getTypePtr()->getElementType())); -}) - -DEF_TRAVERSE_TYPELOC(FunctionNoProtoType, - { TRY_TO(TraverseTypeLoc(TL.getReturnLoc())); }) - -// FIXME: location of exception specifications (attributes?) -DEF_TRAVERSE_TYPELOC(FunctionProtoType, { - TRY_TO(TraverseTypeLoc(TL.getReturnLoc())); - - const FunctionProtoType *T = TL.getTypePtr(); - - for (unsigned I = 0, E = TL.getNumParams(); I != E; ++I) { - if (TL.getParam(I)) { - TRY_TO(TraverseDecl(TL.getParam(I))); - } else if (I < T->getNumParams()) { - TRY_TO(TraverseType(T->getParamType(I))); - } - } - - for (const auto &E : T->exceptions()) { - TRY_TO(TraverseType(E)); - } - - if (Expr *NE = T->getNoexceptExpr()) - TRY_TO(TraverseStmt(NE)); -}) - -DEF_TRAVERSE_TYPELOC(UnresolvedUsingType, {}) -DEF_TRAVERSE_TYPELOC(TypedefType, {}) - -DEF_TRAVERSE_TYPELOC(TypeOfExprType, - { TRY_TO(TraverseStmt(TL.getUnderlyingExpr())); }) - -DEF_TRAVERSE_TYPELOC(TypeOfType, { - TRY_TO(TraverseTypeLoc(TL.getUnderlyingTInfo()->getTypeLoc())); -}) - -// FIXME: location of underlying expr -DEF_TRAVERSE_TYPELOC(DecltypeType, { - TRY_TO(TraverseStmt(TL.getTypePtr()->getUnderlyingExpr())); -}) - -DEF_TRAVERSE_TYPELOC(UnaryTransformType, { - TRY_TO(TraverseTypeLoc(TL.getUnderlyingTInfo()->getTypeLoc())); -}) - -DEF_TRAVERSE_TYPELOC(AutoType, { - TRY_TO(TraverseType(TL.getTypePtr()->getDeducedType())); -}) - -DEF_TRAVERSE_TYPELOC(RecordType, {}) -DEF_TRAVERSE_TYPELOC(EnumType, {}) -DEF_TRAVERSE_TYPELOC(TemplateTypeParmType, {}) -DEF_TRAVERSE_TYPELOC(SubstTemplateTypeParmType, {}) -DEF_TRAVERSE_TYPELOC(SubstTemplateTypeParmPackType, {}) - -// FIXME: use the loc for the template name? -DEF_TRAVERSE_TYPELOC(TemplateSpecializationType, { - TRY_TO(TraverseTemplateName(TL.getTypePtr()->getTemplateName())); - for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) { - TRY_TO(TraverseTemplateArgumentLoc(TL.getArgLoc(I))); - } -}) - -DEF_TRAVERSE_TYPELOC(InjectedClassNameType, {}) - -DEF_TRAVERSE_TYPELOC(ParenType, { TRY_TO(TraverseTypeLoc(TL.getInnerLoc())); }) - -DEF_TRAVERSE_TYPELOC(AttributedType, - { TRY_TO(TraverseTypeLoc(TL.getModifiedLoc())); }) - -DEF_TRAVERSE_TYPELOC(ElaboratedType, { - if (TL.getQualifierLoc()) { - TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc())); - } - TRY_TO(TraverseTypeLoc(TL.getNamedTypeLoc())); -}) - -DEF_TRAVERSE_TYPELOC(DependentNameType, { - TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc())); -}) - -DEF_TRAVERSE_TYPELOC(DependentTemplateSpecializationType, { - if (TL.getQualifierLoc()) { - TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc())); - } - - for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) { - TRY_TO(TraverseTemplateArgumentLoc(TL.getArgLoc(I))); - } -}) - -DEF_TRAVERSE_TYPELOC(PackExpansionType, - { TRY_TO(TraverseTypeLoc(TL.getPatternLoc())); }) - -DEF_TRAVERSE_TYPELOC(ObjCInterfaceType, {}) - -DEF_TRAVERSE_TYPELOC(ObjCObjectType, { - // We have to watch out here because an ObjCInterfaceType's base - // type is itself. - if (TL.getTypePtr()->getBaseType().getTypePtr() != TL.getTypePtr()) - TRY_TO(TraverseTypeLoc(TL.getBaseLoc())); - for (unsigned i = 0, n = TL.getNumTypeArgs(); i != n; ++i) - TRY_TO(TraverseTypeLoc(TL.getTypeArgTInfo(i)->getTypeLoc())); -}) - -DEF_TRAVERSE_TYPELOC(ObjCObjectPointerType, - { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); }) - -DEF_TRAVERSE_TYPELOC(AtomicType, { TRY_TO(TraverseTypeLoc(TL.getValueLoc())); }) - -#undef DEF_TRAVERSE_TYPELOC - -// ----------------- Decl traversal ----------------- -// -// For a Decl, we automate (in the DEF_TRAVERSE_DECL macro) traversing -// the children that come from the DeclContext associated with it. -// Therefore each Traverse* only needs to worry about children other -// than those. - -template <typename Derived> -bool RecursiveASTVisitor<Derived>::TraverseDeclContextHelper(DeclContext *DC) { - if (!DC) - return true; - - for (auto *Child : DC->decls()) { - // BlockDecls and CapturedDecls are traversed through BlockExprs and - // CapturedStmts respectively. - if (!isa<BlockDecl>(Child) && !isa<CapturedDecl>(Child)) - TRY_TO(TraverseDecl(Child)); - } - - return true; -} - -// This macro makes available a variable D, the passed-in decl. -#define DEF_TRAVERSE_DECL(DECL, CODE) \ - template <typename Derived> \ - bool RecursiveASTVisitor<Derived>::Traverse##DECL(DECL *D) { \ - TRY_TO(WalkUpFrom##DECL(D)); \ - { CODE; } \ - TRY_TO(TraverseDeclContextHelper(dyn_cast<DeclContext>(D))); \ - return true; \ - } - -DEF_TRAVERSE_DECL(AccessSpecDecl, {}) - -DEF_TRAVERSE_DECL(BlockDecl, { - if (TypeSourceInfo *TInfo = D->getSignatureAsWritten()) - TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc())); - TRY_TO(TraverseStmt(D->getBody())); - for (const auto &I : D->captures()) { - if (I.hasCopyExpr()) { - 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; -}) - -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; -}) - -DEF_TRAVERSE_DECL(EmptyDecl, {}) - -DEF_TRAVERSE_DECL(FileScopeAsmDecl, - { TRY_TO(TraverseStmt(D->getAsmString())); }) - -DEF_TRAVERSE_DECL(ImportDecl, {}) - -DEF_TRAVERSE_DECL(FriendDecl, { - // Friend is either decl or a type. - if (D->getFriendType()) - TRY_TO(TraverseTypeLoc(D->getFriendType()->getTypeLoc())); - else - TRY_TO(TraverseDecl(D->getFriendDecl())); -}) - -DEF_TRAVERSE_DECL(FriendTemplateDecl, { - if (D->getFriendType()) - TRY_TO(TraverseTypeLoc(D->getFriendType()->getTypeLoc())); - else - TRY_TO(TraverseDecl(D->getFriendDecl())); - for (unsigned I = 0, E = D->getNumTemplateParameters(); I < E; ++I) { - TemplateParameterList *TPL = D->getTemplateParameterList(I); - for (TemplateParameterList::iterator ITPL = TPL->begin(), ETPL = TPL->end(); - ITPL != ETPL; ++ITPL) { - TRY_TO(TraverseDecl(*ITPL)); - } - } -}) - -DEF_TRAVERSE_DECL(ClassScopeFunctionSpecializationDecl, - { TRY_TO(TraverseDecl(D->getSpecialization())); }) - -DEF_TRAVERSE_DECL(LinkageSpecDecl, {}) - -DEF_TRAVERSE_DECL(ObjCPropertyImplDecl, {// FIXME: implement this - }) - -DEF_TRAVERSE_DECL(StaticAssertDecl, { - TRY_TO(TraverseStmt(D->getAssertExpr())); - TRY_TO(TraverseStmt(D->getMessage())); -}) - -DEF_TRAVERSE_DECL( - TranslationUnitDecl, - {// Code in an unnamed namespace shows up automatically in - // decls_begin()/decls_end(). Thus we don't need to recurse on - // D->getAnonymousNamespace(). - }) - -DEF_TRAVERSE_DECL(ExternCContextDecl, {}) - -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; -}) - -DEF_TRAVERSE_DECL(LabelDecl, {// There is no code in a LabelDecl. - }) - -DEF_TRAVERSE_DECL( - NamespaceDecl, - {// Code in an unnamed namespace shows up automatically in - // decls_begin()/decls_end(). Thus we don't need to recurse on - // D->getAnonymousNamespace(). - }) - -DEF_TRAVERSE_DECL(ObjCCompatibleAliasDecl, {// FIXME: implement - }) - -DEF_TRAVERSE_DECL(ObjCCategoryDecl, {// FIXME: implement - if (ObjCTypeParamList *typeParamList = D->getTypeParamList()) { - for (auto typeParam : *typeParamList) { - TRY_TO(TraverseObjCTypeParamDecl(typeParam)); - } - } - return true; -}) - -DEF_TRAVERSE_DECL(ObjCCategoryImplDecl, {// FIXME: implement - }) - -DEF_TRAVERSE_DECL(ObjCImplementationDecl, {// FIXME: implement - }) - -DEF_TRAVERSE_DECL(ObjCInterfaceDecl, {// FIXME: implement - if (ObjCTypeParamList *typeParamList = D->getTypeParamListAsWritten()) { - for (auto typeParam : *typeParamList) { - TRY_TO(TraverseObjCTypeParamDecl(typeParam)); - } - } - - if (TypeSourceInfo *superTInfo = D->getSuperClassTInfo()) { - TRY_TO(TraverseTypeLoc(superTInfo->getTypeLoc())); - } -}) - -DEF_TRAVERSE_DECL(ObjCProtocolDecl, {// FIXME: implement - }) - -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)); - } - if (D->isThisDeclarationADefinition()) { - TRY_TO(TraverseStmt(D->getBody())); - } - return true; -}) - -DEF_TRAVERSE_DECL(ObjCTypeParamDecl, { - if (D->hasExplicitBound()) { - TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc())); - // We shouldn't traverse D->getTypeForDecl(); it's a result of - // declaring the type alias, not something that was written in the - // source. - } -}) - -DEF_TRAVERSE_DECL(ObjCPropertyDecl, { - if (D->getTypeSourceInfo()) - TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc())); - else - TRY_TO(TraverseType(D->getType())); - return true; -}) - -DEF_TRAVERSE_DECL(UsingDecl, { - TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc())); - TRY_TO(TraverseDeclarationNameInfo(D->getNameInfo())); -}) - -DEF_TRAVERSE_DECL(UsingDirectiveDecl, { - TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc())); -}) - -DEF_TRAVERSE_DECL(UsingShadowDecl, {}) - -DEF_TRAVERSE_DECL(OMPThreadPrivateDecl, { - for (auto *I : D->varlists()) { - TRY_TO(TraverseStmt(I)); - } -}) - -// A helper method for TemplateDecl's children. -template <typename Derived> -bool RecursiveASTVisitor<Derived>::TraverseTemplateParameterListHelper( - TemplateParameterList *TPL) { - if (TPL) { - for (TemplateParameterList::iterator I = TPL->begin(), E = TPL->end(); - I != E; ++I) { - TRY_TO(TraverseDecl(*I)); - } - } - return true; -} - -// A helper method for traversing the implicit instantiations of a -// class template. -template <typename Derived> -bool RecursiveASTVisitor<Derived>::TraverseClassInstantiations( - ClassTemplateDecl *D) { - for (auto *SD : D->specializations()) { - for (auto *RD : SD->redecls()) { - // We don't want to visit injected-class-names in this traversal. - if (cast<CXXRecordDecl>(RD)->isInjectedClassName()) - continue; - - switch ( - cast<ClassTemplateSpecializationDecl>(RD)->getSpecializationKind()) { - // Visit the implicit instantiations with the requested pattern. - case TSK_Undeclared: - case TSK_ImplicitInstantiation: - TRY_TO(TraverseDecl(RD)); - break; - - // We don't need to do anything on an explicit instantiation - // or explicit specialization because there will be an explicit - // node for it elsewhere. - case TSK_ExplicitInstantiationDeclaration: - case TSK_ExplicitInstantiationDefinition: - case TSK_ExplicitSpecialization: - break; - } - } - } - - return true; -} - -DEF_TRAVERSE_DECL(ClassTemplateDecl, { - CXXRecordDecl *TempDecl = D->getTemplatedDecl(); - TRY_TO(TraverseDecl(TempDecl)); - TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters())); - - // By default, we do not traverse the instantiations of - // class templates since they do not appear in the user code. The - // following code optionally traverses them. - // - // We only traverse the class instantiations when we see the canonical - // declaration of the template, to ensure we only visit them once. - if (getDerived().shouldVisitTemplateInstantiations() && - D == D->getCanonicalDecl()) - TRY_TO(TraverseClassInstantiations(D)); - - // Note that getInstantiatedFromMemberTemplate() is just a link - // from a template instantiation back to the template from which - // it was instantiated, and thus should not be traversed. -}) - -// A helper method for traversing the implicit instantiations of a -// class template. -template <typename Derived> -bool RecursiveASTVisitor<Derived>::TraverseVariableInstantiations( - VarTemplateDecl *D) { - for (auto *SD : D->specializations()) { - for (auto *RD : SD->redecls()) { - switch ( - cast<VarTemplateSpecializationDecl>(RD)->getSpecializationKind()) { - // Visit the implicit instantiations with the requested pattern. - case TSK_Undeclared: - case TSK_ImplicitInstantiation: - TRY_TO(TraverseDecl(RD)); - break; - - // We don't need to do anything on an explicit instantiation - // or explicit specialization because there will be an explicit - // node for it elsewhere. - case TSK_ExplicitInstantiationDeclaration: - case TSK_ExplicitInstantiationDefinition: - case TSK_ExplicitSpecialization: - break; - } - } - } - - return true; -} - -DEF_TRAVERSE_DECL(VarTemplateDecl, { - VarDecl *TempDecl = D->getTemplatedDecl(); - TRY_TO(TraverseDecl(TempDecl)); - TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters())); - - // By default, we do not traverse the instantiations of - // variable templates since they do not appear in the user code. The - // following code optionally traverses them. - // - // We only traverse the variable instantiations when we see the canonical - // declaration of the template, to ensure we only visit them once. - if (getDerived().shouldVisitTemplateInstantiations() && - D == D->getCanonicalDecl()) - TRY_TO(TraverseVariableInstantiations(D)); - - // Note that getInstantiatedFromMemberTemplate() is just a link - // from a template instantiation back to the template from which - // it was instantiated, and thus should not be traversed. -}) - -// A helper method for traversing the instantiations of a -// function while skipping its specializations. -template <typename Derived> -bool RecursiveASTVisitor<Derived>::TraverseFunctionInstantiations( - FunctionTemplateDecl *D) { - for (auto *FD : D->specializations()) { - for (auto *RD : FD->redecls()) { - switch (RD->getTemplateSpecializationKind()) { - case TSK_Undeclared: - case TSK_ImplicitInstantiation: - // We don't know what kind of FunctionDecl this is. - TRY_TO(TraverseDecl(RD)); - break; - - // No need to visit explicit instantiations, we'll find the node - // eventually. - // FIXME: This is incorrect; there is no other node for an explicit - // instantiation of a function template specialization. - case TSK_ExplicitInstantiationDeclaration: - case TSK_ExplicitInstantiationDefinition: - break; - - case TSK_ExplicitSpecialization: - break; - } - } - } - - return true; -} - -DEF_TRAVERSE_DECL(FunctionTemplateDecl, { - TRY_TO(TraverseDecl(D->getTemplatedDecl())); - TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters())); - - // By default, we do not traverse the instantiations of - // function templates since they do not appear in the user code. The - // following code optionally traverses them. - // - // We only traverse the function instantiations when we see the canonical - // declaration of the template, to ensure we only visit them once. - if (getDerived().shouldVisitTemplateInstantiations() && - D == D->getCanonicalDecl()) - TRY_TO(TraverseFunctionInstantiations(D)); -}) - -DEF_TRAVERSE_DECL(TemplateTemplateParmDecl, { - // D is the "T" in something like - // template <template <typename> class T> class container { }; - TRY_TO(TraverseDecl(D->getTemplatedDecl())); - if (D->hasDefaultArgument()) { - TRY_TO(TraverseTemplateArgumentLoc(D->getDefaultArgument())); - } - TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters())); -}) - -DEF_TRAVERSE_DECL(TemplateTypeParmDecl, { - // D is the "T" in something like "template<typename T> class vector;" - if (D->getTypeForDecl()) - TRY_TO(TraverseType(QualType(D->getTypeForDecl(), 0))); - if (D->hasDefaultArgument()) - TRY_TO(TraverseTypeLoc(D->getDefaultArgumentInfo()->getTypeLoc())); -}) - -DEF_TRAVERSE_DECL(TypedefDecl, { - TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc())); - // We shouldn't traverse D->getTypeForDecl(); it's a result of - // declaring the typedef, not something that was written in the - // source. -}) - -DEF_TRAVERSE_DECL(TypeAliasDecl, { - TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc())); - // We shouldn't traverse D->getTypeForDecl(); it's a result of - // declaring the type alias, not something that was written in the - // source. -}) - -DEF_TRAVERSE_DECL(TypeAliasTemplateDecl, { - TRY_TO(TraverseDecl(D->getTemplatedDecl())); - TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters())); -}) - -DEF_TRAVERSE_DECL(UnresolvedUsingTypenameDecl, { - // A dependent using declaration which was marked with 'typename'. - // template<class T> class A : public B<T> { using typename B<T>::foo; }; - TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc())); - // We shouldn't traverse D->getTypeForDecl(); it's a result of - // declaring the type, not something that was written in the - // source. -}) - -DEF_TRAVERSE_DECL(EnumDecl, { - if (D->getTypeForDecl()) - TRY_TO(TraverseType(QualType(D->getTypeForDecl(), 0))); - - TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc())); - // The enumerators are already traversed by - // decls_begin()/decls_end(). -}) - -// Helper methods for RecordDecl and its children. -template <typename Derived> -bool RecursiveASTVisitor<Derived>::TraverseRecordHelper(RecordDecl *D) { - // We shouldn't traverse D->getTypeForDecl(); it's a result of - // declaring the type, not something that was written in the source. - - TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc())); - return true; -} - -template <typename Derived> -bool RecursiveASTVisitor<Derived>::TraverseCXXRecordHelper(CXXRecordDecl *D) { - if (!TraverseRecordHelper(D)) - return false; - if (D->isCompleteDefinition()) { - for (const auto &I : D->bases()) { - TRY_TO(TraverseTypeLoc(I.getTypeSourceInfo()->getTypeLoc())); - } - // We don't traverse the friends or the conversions, as they are - // already in decls_begin()/decls_end(). - } - return true; -} - -DEF_TRAVERSE_DECL(RecordDecl, { TRY_TO(TraverseRecordHelper(D)); }) - -DEF_TRAVERSE_DECL(CXXRecordDecl, { TRY_TO(TraverseCXXRecordHelper(D)); }) - -DEF_TRAVERSE_DECL(ClassTemplateSpecializationDecl, { - // For implicit instantiations ("set<int> x;"), we don't want to - // recurse at all, since the instatiated class isn't written in - // the source code anywhere. (Note the instatiated *type* -- - // set<int> -- is written, and will still get a callback of - // TemplateSpecializationType). For explicit instantiations - // ("template set<int>;"), we do need a callback, since this - // is the only callback that's made for this instantiation. - // We use getTypeAsWritten() to distinguish. - if (TypeSourceInfo *TSI = D->getTypeAsWritten()) - TRY_TO(TraverseTypeLoc(TSI->getTypeLoc())); - - if (!getDerived().shouldVisitTemplateInstantiations() && - D->getTemplateSpecializationKind() != TSK_ExplicitSpecialization) - // Returning from here skips traversing the - // declaration context of the ClassTemplateSpecializationDecl - // (embedded in the DEF_TRAVERSE_DECL() macro) - // which contains the instantiated members of the class. - return true; -}) - -template <typename Derived> -bool RecursiveASTVisitor<Derived>::TraverseTemplateArgumentLocsHelper( - const TemplateArgumentLoc *TAL, unsigned Count) { - for (unsigned I = 0; I < Count; ++I) { - TRY_TO(TraverseTemplateArgumentLoc(TAL[I])); - } - return true; -} - -DEF_TRAVERSE_DECL(ClassTemplatePartialSpecializationDecl, { - // The partial specialization. - if (TemplateParameterList *TPL = D->getTemplateParameters()) { - for (TemplateParameterList::iterator I = TPL->begin(), E = TPL->end(); - I != E; ++I) { - TRY_TO(TraverseDecl(*I)); - } - } - // The args that remains unspecialized. - TRY_TO(TraverseTemplateArgumentLocsHelper( - D->getTemplateArgsAsWritten()->getTemplateArgs(), - D->getTemplateArgsAsWritten()->NumTemplateArgs)); - - // Don't need the ClassTemplatePartialSpecializationHelper, even - // though that's our parent class -- we already visit all the - // template args here. - TRY_TO(TraverseCXXRecordHelper(D)); - - // Instantiations will have been visited with the primary template. -}) - -DEF_TRAVERSE_DECL(EnumConstantDecl, { TRY_TO(TraverseStmt(D->getInitExpr())); }) - -DEF_TRAVERSE_DECL(UnresolvedUsingValueDecl, { - // Like UnresolvedUsingTypenameDecl, but without the 'typename': - // template <class T> Class A : public Base<T> { using Base<T>::foo; }; - TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc())); - TRY_TO(TraverseDeclarationNameInfo(D->getNameInfo())); -}) - -DEF_TRAVERSE_DECL(IndirectFieldDecl, {}) - -template <typename Derived> -bool RecursiveASTVisitor<Derived>::TraverseDeclaratorHelper(DeclaratorDecl *D) { - TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc())); - if (D->getTypeSourceInfo()) - TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc())); - else - TRY_TO(TraverseType(D->getType())); - return true; -} - -DEF_TRAVERSE_DECL(MSPropertyDecl, { TRY_TO(TraverseDeclaratorHelper(D)); }) - -DEF_TRAVERSE_DECL(FieldDecl, { - TRY_TO(TraverseDeclaratorHelper(D)); - if (D->isBitField()) - TRY_TO(TraverseStmt(D->getBitWidth())); - else if (D->hasInClassInitializer()) - TRY_TO(TraverseStmt(D->getInClassInitializer())); -}) - -DEF_TRAVERSE_DECL(ObjCAtDefsFieldDecl, { - TRY_TO(TraverseDeclaratorHelper(D)); - if (D->isBitField()) - TRY_TO(TraverseStmt(D->getBitWidth())); - // FIXME: implement the rest. -}) - -DEF_TRAVERSE_DECL(ObjCIvarDecl, { - TRY_TO(TraverseDeclaratorHelper(D)); - if (D->isBitField()) - TRY_TO(TraverseStmt(D->getBitWidth())); - // FIXME: implement the rest. -}) - -template <typename Derived> -bool RecursiveASTVisitor<Derived>::TraverseFunctionHelper(FunctionDecl *D) { - TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc())); - TRY_TO(TraverseDeclarationNameInfo(D->getNameInfo())); - - // If we're an explicit template specialization, iterate over the - // template args that were explicitly specified. If we were doing - // this in typing order, we'd do it between the return type and - // the function args, but both are handled by the FunctionTypeLoc - // above, so we have to choose one side. I've decided to do before. - if (const FunctionTemplateSpecializationInfo *FTSI = - D->getTemplateSpecializationInfo()) { - if (FTSI->getTemplateSpecializationKind() != TSK_Undeclared && - FTSI->getTemplateSpecializationKind() != TSK_ImplicitInstantiation) { - // A specialization might not have explicit template arguments if it has - // a templated return type and concrete arguments. - if (const ASTTemplateArgumentListInfo *TALI = - FTSI->TemplateArgumentsAsWritten) { - TRY_TO(TraverseTemplateArgumentLocsHelper(TALI->getTemplateArgs(), - TALI->NumTemplateArgs)); - } - } - } - - // Visit the function type itself, which can be either - // FunctionNoProtoType or FunctionProtoType, or a typedef. This - // also covers the return type and the function parameters, - // including exception specifications. - TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc())); - - if (CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(D)) { - // Constructor initializers. - for (auto *I : Ctor->inits()) { - TRY_TO(TraverseConstructorInitializer(I)); - } - } - - if (D->isThisDeclarationADefinition()) { - TRY_TO(TraverseStmt(D->getBody())); // Function body. - } - return true; -} - -DEF_TRAVERSE_DECL(FunctionDecl, { - // We skip decls_begin/decls_end, which are already covered by - // TraverseFunctionHelper(). - return TraverseFunctionHelper(D); -}) - -DEF_TRAVERSE_DECL(CXXMethodDecl, { - // We skip decls_begin/decls_end, which are already covered by - // TraverseFunctionHelper(). - return TraverseFunctionHelper(D); -}) - -DEF_TRAVERSE_DECL(CXXConstructorDecl, { - // We skip decls_begin/decls_end, which are already covered by - // TraverseFunctionHelper(). - return TraverseFunctionHelper(D); -}) - -// CXXConversionDecl is the declaration of a type conversion operator. -// It's not a cast expression. -DEF_TRAVERSE_DECL(CXXConversionDecl, { - // We skip decls_begin/decls_end, which are already covered by - // TraverseFunctionHelper(). - return TraverseFunctionHelper(D); -}) - -DEF_TRAVERSE_DECL(CXXDestructorDecl, { - // We skip decls_begin/decls_end, which are already covered by - // TraverseFunctionHelper(). - return TraverseFunctionHelper(D); -}) - -template <typename Derived> -bool RecursiveASTVisitor<Derived>::TraverseVarHelper(VarDecl *D) { - TRY_TO(TraverseDeclaratorHelper(D)); - // Default params are taken care of when we traverse the ParmVarDecl. - if (!isa<ParmVarDecl>(D)) - TRY_TO(TraverseStmt(D->getInit())); - return true; -} - -DEF_TRAVERSE_DECL(VarDecl, { TRY_TO(TraverseVarHelper(D)); }) - -DEF_TRAVERSE_DECL(VarTemplateSpecializationDecl, { - // For implicit instantiations, we don't want to - // recurse at all, since the instatiated class isn't written in - // the source code anywhere. - if (TypeSourceInfo *TSI = D->getTypeAsWritten()) - TRY_TO(TraverseTypeLoc(TSI->getTypeLoc())); - - if (!getDerived().shouldVisitTemplateInstantiations() && - D->getTemplateSpecializationKind() != TSK_ExplicitSpecialization) - // Returning from here skips traversing the - // declaration context of the VarTemplateSpecializationDecl - // (embedded in the DEF_TRAVERSE_DECL() macro). - return true; -}) - -DEF_TRAVERSE_DECL(VarTemplatePartialSpecializationDecl, { - // The partial specialization. - if (TemplateParameterList *TPL = D->getTemplateParameters()) { - for (TemplateParameterList::iterator I = TPL->begin(), E = TPL->end(); - I != E; ++I) { - TRY_TO(TraverseDecl(*I)); - } - } - // The args that remains unspecialized. - TRY_TO(TraverseTemplateArgumentLocsHelper( - D->getTemplateArgsAsWritten()->getTemplateArgs(), - D->getTemplateArgsAsWritten()->NumTemplateArgs)); - - // Don't need the VarTemplatePartialSpecializationHelper, even - // though that's our parent class -- we already visit all the - // template args here. - TRY_TO(TraverseVarHelper(D)); - - // Instantiations will have been visited with the primary - // template. -}) - -DEF_TRAVERSE_DECL(ImplicitParamDecl, { TRY_TO(TraverseVarHelper(D)); }) - -DEF_TRAVERSE_DECL(NonTypeTemplateParmDecl, { - // A non-type template parameter, e.g. "S" in template<int S> class Foo ... - TRY_TO(TraverseDeclaratorHelper(D)); - TRY_TO(TraverseStmt(D->getDefaultArgument())); -}) - -DEF_TRAVERSE_DECL(ParmVarDecl, { - TRY_TO(TraverseVarHelper(D)); - - if (D->hasDefaultArg() && D->hasUninstantiatedDefaultArg() && - !D->hasUnparsedDefaultArg()) - TRY_TO(TraverseStmt(D->getUninstantiatedDefaultArg())); - - if (D->hasDefaultArg() && !D->hasUninstantiatedDefaultArg() && - !D->hasUnparsedDefaultArg()) - TRY_TO(TraverseStmt(D->getDefaultArg())); -}) - -#undef DEF_TRAVERSE_DECL - -// ----------------- Stmt traversal ----------------- -// -// For stmts, we automate (in the DEF_TRAVERSE_STMT macro) iterating -// over the children defined in children() (every stmt defines these, -// though sometimes the range is empty). Each individual Traverse* -// method only needs to worry about children other than those. To see -// what children() does for a given class, see, e.g., -// http://clang.llvm.org/doxygen/Stmt_8cpp_source.html - -// This macro makes available a variable S, the passed-in stmt. -#define DEF_TRAVERSE_STMT(STMT, CODE) \ - template <typename Derived> \ - bool RecursiveASTVisitor<Derived>::Traverse##STMT(STMT *S) { \ - TRY_TO(WalkUpFrom##STMT(S)); \ - StmtQueueAction StmtQueue(*this); \ - { CODE; } \ - for (Stmt *SubStmt : S->children()) { \ - StmtQueue.queue(SubStmt); \ - } \ - return true; \ - } - -DEF_TRAVERSE_STMT(GCCAsmStmt, { - StmtQueue.queue(S->getAsmString()); - for (unsigned I = 0, E = S->getNumInputs(); I < E; ++I) { - StmtQueue.queue(S->getInputConstraintLiteral(I)); - } - for (unsigned I = 0, E = S->getNumOutputs(); I < E; ++I) { - StmtQueue.queue(S->getOutputConstraintLiteral(I)); - } - for (unsigned I = 0, E = S->getNumClobbers(); I < E; ++I) { - StmtQueue.queue(S->getClobberStringLiteral(I)); - } - // children() iterates over inputExpr and outputExpr. -}) - -DEF_TRAVERSE_STMT( - MSAsmStmt, - {// FIXME: MS Asm doesn't currently parse Constraints, Clobbers, etc. Once - // added this needs to be implemented. - }) - -DEF_TRAVERSE_STMT(CXXCatchStmt, { - TRY_TO(TraverseDecl(S->getExceptionDecl())); - // children() iterates over the handler block. -}) - -DEF_TRAVERSE_STMT(DeclStmt, { - for (auto *I : S->decls()) { - TRY_TO(TraverseDecl(I)); - } - // Suppress the default iteration over children() by - // returning. Here's why: A DeclStmt looks like 'type var [= - // initializer]'. The decls above already traverse over the - // initializers, so we don't have to do it again (which - // children() would do). - return true; -}) - -// These non-expr stmts (most of them), do not need any action except -// iterating over the children. -DEF_TRAVERSE_STMT(BreakStmt, {}) -DEF_TRAVERSE_STMT(CXXTryStmt, {}) -DEF_TRAVERSE_STMT(CaseStmt, {}) -DEF_TRAVERSE_STMT(CompoundStmt, {}) -DEF_TRAVERSE_STMT(ContinueStmt, {}) -DEF_TRAVERSE_STMT(DefaultStmt, {}) -DEF_TRAVERSE_STMT(DoStmt, {}) -DEF_TRAVERSE_STMT(ForStmt, {}) -DEF_TRAVERSE_STMT(GotoStmt, {}) -DEF_TRAVERSE_STMT(IfStmt, {}) -DEF_TRAVERSE_STMT(IndirectGotoStmt, {}) -DEF_TRAVERSE_STMT(LabelStmt, {}) -DEF_TRAVERSE_STMT(AttributedStmt, {}) -DEF_TRAVERSE_STMT(NullStmt, {}) -DEF_TRAVERSE_STMT(ObjCAtCatchStmt, {}) -DEF_TRAVERSE_STMT(ObjCAtFinallyStmt, {}) -DEF_TRAVERSE_STMT(ObjCAtSynchronizedStmt, {}) -DEF_TRAVERSE_STMT(ObjCAtThrowStmt, {}) -DEF_TRAVERSE_STMT(ObjCAtTryStmt, {}) -DEF_TRAVERSE_STMT(ObjCForCollectionStmt, {}) -DEF_TRAVERSE_STMT(ObjCAutoreleasePoolStmt, {}) -DEF_TRAVERSE_STMT(CXXForRangeStmt, {}) -DEF_TRAVERSE_STMT(MSDependentExistsStmt, { - TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc())); - TRY_TO(TraverseDeclarationNameInfo(S->getNameInfo())); -}) -DEF_TRAVERSE_STMT(ReturnStmt, {}) -DEF_TRAVERSE_STMT(SwitchStmt, {}) -DEF_TRAVERSE_STMT(WhileStmt, {}) - -DEF_TRAVERSE_STMT(CXXDependentScopeMemberExpr, { - TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc())); - TRY_TO(TraverseDeclarationNameInfo(S->getMemberNameInfo())); - if (S->hasExplicitTemplateArgs()) { - TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(), - S->getNumTemplateArgs())); - } -}) - -DEF_TRAVERSE_STMT(DeclRefExpr, { - TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc())); - TRY_TO(TraverseDeclarationNameInfo(S->getNameInfo())); - TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(), - S->getNumTemplateArgs())); -}) - -DEF_TRAVERSE_STMT(DependentScopeDeclRefExpr, { - TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc())); - TRY_TO(TraverseDeclarationNameInfo(S->getNameInfo())); - if (S->hasExplicitTemplateArgs()) { - TRY_TO(TraverseTemplateArgumentLocsHelper( - S->getExplicitTemplateArgs().getTemplateArgs(), - S->getNumTemplateArgs())); - } -}) - -DEF_TRAVERSE_STMT(MemberExpr, { - TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc())); - TRY_TO(TraverseDeclarationNameInfo(S->getMemberNameInfo())); - TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(), - S->getNumTemplateArgs())); -}) - -DEF_TRAVERSE_STMT( - ImplicitCastExpr, - {// We don't traverse the cast type, as it's not written in the - // source code. - }) - -DEF_TRAVERSE_STMT(CStyleCastExpr, { - TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc())); -}) - -DEF_TRAVERSE_STMT(CXXFunctionalCastExpr, { - TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc())); -}) - -DEF_TRAVERSE_STMT(CXXConstCastExpr, { - TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc())); -}) - -DEF_TRAVERSE_STMT(CXXDynamicCastExpr, { - TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc())); -}) - -DEF_TRAVERSE_STMT(CXXReinterpretCastExpr, { - TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc())); -}) - -DEF_TRAVERSE_STMT(CXXStaticCastExpr, { - TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc())); -}) - -// InitListExpr is a tricky one, because we want to do all our work on -// the syntactic form of the listexpr, but this method takes the -// semantic form by default. We can't use the macro helper because it -// calls WalkUp*() on the semantic form, before our code can convert -// to the syntactic form. -template <typename Derived> -bool RecursiveASTVisitor<Derived>::TraverseInitListExpr(InitListExpr *S) { - if (InitListExpr *Syn = S->getSyntacticForm()) - S = Syn; - TRY_TO(WalkUpFromInitListExpr(S)); - StmtQueueAction StmtQueue(*this); - // All we need are the default actions. FIXME: use a helper function. - for (Stmt *SubStmt : S->children()) { - StmtQueue.queue(SubStmt); - } - return true; -} - -// GenericSelectionExpr is a special case because the types and expressions -// are interleaved. We also need to watch out for null types (default -// generic associations). -template <typename Derived> -bool RecursiveASTVisitor<Derived>::TraverseGenericSelectionExpr( - GenericSelectionExpr *S) { - TRY_TO(WalkUpFromGenericSelectionExpr(S)); - StmtQueueAction StmtQueue(*this); - StmtQueue.queue(S->getControllingExpr()); - for (unsigned i = 0; i != S->getNumAssocs(); ++i) { - if (TypeSourceInfo *TS = S->getAssocTypeSourceInfo(i)) - TRY_TO(TraverseTypeLoc(TS->getTypeLoc())); - StmtQueue.queue(S->getAssocExpr(i)); - } - return true; -} - -// PseudoObjectExpr is a special case because of the wierdness with -// syntactic expressions and opaque values. -template <typename Derived> -bool -RecursiveASTVisitor<Derived>::TraversePseudoObjectExpr(PseudoObjectExpr *S) { - TRY_TO(WalkUpFromPseudoObjectExpr(S)); - StmtQueueAction StmtQueue(*this); - StmtQueue.queue(S->getSyntacticForm()); - for (PseudoObjectExpr::semantics_iterator i = S->semantics_begin(), - e = S->semantics_end(); - i != e; ++i) { - Expr *sub = *i; - if (OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(sub)) - sub = OVE->getSourceExpr(); - StmtQueue.queue(sub); - } - return true; -} - -DEF_TRAVERSE_STMT(CXXScalarValueInitExpr, { - // This is called for code like 'return T()' where T is a built-in - // (i.e. non-class) type. - TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc())); -}) - -DEF_TRAVERSE_STMT(CXXNewExpr, { - // The child-iterator will pick up the other arguments. - TRY_TO(TraverseTypeLoc(S->getAllocatedTypeSourceInfo()->getTypeLoc())); -}) - -DEF_TRAVERSE_STMT(OffsetOfExpr, { - // The child-iterator will pick up the expression representing - // the field. - // FIMXE: for code like offsetof(Foo, a.b.c), should we get - // making a MemberExpr callbacks for Foo.a, Foo.a.b, and Foo.a.b.c? - TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc())); -}) - -DEF_TRAVERSE_STMT(UnaryExprOrTypeTraitExpr, { - // The child-iterator will pick up the arg if it's an expression, - // but not if it's a type. - if (S->isArgumentType()) - TRY_TO(TraverseTypeLoc(S->getArgumentTypeInfo()->getTypeLoc())); -}) - -DEF_TRAVERSE_STMT(CXXTypeidExpr, { - // The child-iterator will pick up the arg if it's an expression, - // but not if it's a type. - if (S->isTypeOperand()) - TRY_TO(TraverseTypeLoc(S->getTypeOperandSourceInfo()->getTypeLoc())); -}) - -DEF_TRAVERSE_STMT(MSPropertyRefExpr, { - TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc())); -}) - -DEF_TRAVERSE_STMT(CXXUuidofExpr, { - // The child-iterator will pick up the arg if it's an expression, - // but not if it's a type. - if (S->isTypeOperand()) - TRY_TO(TraverseTypeLoc(S->getTypeOperandSourceInfo()->getTypeLoc())); -}) - -DEF_TRAVERSE_STMT(TypeTraitExpr, { - for (unsigned I = 0, N = S->getNumArgs(); I != N; ++I) - TRY_TO(TraverseTypeLoc(S->getArg(I)->getTypeLoc())); -}) - -DEF_TRAVERSE_STMT(ArrayTypeTraitExpr, { - TRY_TO(TraverseTypeLoc(S->getQueriedTypeSourceInfo()->getTypeLoc())); -}) - -DEF_TRAVERSE_STMT(ExpressionTraitExpr, - { StmtQueue.queue(S->getQueriedExpression()); }) - -DEF_TRAVERSE_STMT(VAArgExpr, { - // The child-iterator will pick up the expression argument. - TRY_TO(TraverseTypeLoc(S->getWrittenTypeInfo()->getTypeLoc())); -}) - -DEF_TRAVERSE_STMT(CXXTemporaryObjectExpr, { - // This is called for code like 'return T()' where T is a class type. - TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc())); -}) - -// Walk only the visible parts of lambda expressions. -template <typename Derived> -bool RecursiveASTVisitor<Derived>::TraverseLambdaExpr(LambdaExpr *S) { - TRY_TO(WalkUpFromLambdaExpr(S)); - - for (LambdaExpr::capture_iterator C = S->explicit_capture_begin(), - CEnd = S->explicit_capture_end(); - C != CEnd; ++C) { - TRY_TO(TraverseLambdaCapture(S, C)); - } - - TypeLoc TL = S->getCallOperator()->getTypeSourceInfo()->getTypeLoc(); - FunctionProtoTypeLoc Proto = TL.castAs<FunctionProtoTypeLoc>(); - - if (S->hasExplicitParameters() && S->hasExplicitResultType()) { - // Visit the whole type. - TRY_TO(TraverseTypeLoc(TL)); - } else { - if (S->hasExplicitParameters()) { - // Visit parameters. - for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I) { - TRY_TO(TraverseDecl(Proto.getParam(I))); - } - } else if (S->hasExplicitResultType()) { - TRY_TO(TraverseTypeLoc(Proto.getReturnLoc())); - } - - auto *T = Proto.getTypePtr(); - for (const auto &E : T->exceptions()) { - TRY_TO(TraverseType(E)); - } - - if (Expr *NE = T->getNoexceptExpr()) - TRY_TO(TraverseStmt(NE)); - } - - TRY_TO(TraverseLambdaBody(S)); - return true; -} - -DEF_TRAVERSE_STMT(CXXUnresolvedConstructExpr, { - // This is called for code like 'T()', where T is a template argument. - TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc())); -}) - -// These expressions all might take explicit template arguments. -// We traverse those if so. FIXME: implement these. -DEF_TRAVERSE_STMT(CXXConstructExpr, {}) -DEF_TRAVERSE_STMT(CallExpr, {}) -DEF_TRAVERSE_STMT(CXXMemberCallExpr, {}) - -// These exprs (most of them), do not need any action except iterating -// over the children. -DEF_TRAVERSE_STMT(AddrLabelExpr, {}) -DEF_TRAVERSE_STMT(ArraySubscriptExpr, {}) -DEF_TRAVERSE_STMT(BlockExpr, { - TRY_TO(TraverseDecl(S->getBlockDecl())); - return true; // no child statements to loop through. -}) -DEF_TRAVERSE_STMT(ChooseExpr, {}) -DEF_TRAVERSE_STMT(CompoundLiteralExpr, { - TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc())); -}) -DEF_TRAVERSE_STMT(CXXBindTemporaryExpr, {}) -DEF_TRAVERSE_STMT(CXXBoolLiteralExpr, {}) -DEF_TRAVERSE_STMT(CXXDefaultArgExpr, {}) -DEF_TRAVERSE_STMT(CXXDefaultInitExpr, {}) -DEF_TRAVERSE_STMT(CXXDeleteExpr, {}) -DEF_TRAVERSE_STMT(ExprWithCleanups, {}) -DEF_TRAVERSE_STMT(CXXNullPtrLiteralExpr, {}) -DEF_TRAVERSE_STMT(CXXStdInitializerListExpr, {}) -DEF_TRAVERSE_STMT(CXXPseudoDestructorExpr, { - TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc())); - if (TypeSourceInfo *ScopeInfo = S->getScopeTypeInfo()) - TRY_TO(TraverseTypeLoc(ScopeInfo->getTypeLoc())); - if (TypeSourceInfo *DestroyedTypeInfo = S->getDestroyedTypeInfo()) - TRY_TO(TraverseTypeLoc(DestroyedTypeInfo->getTypeLoc())); -}) -DEF_TRAVERSE_STMT(CXXThisExpr, {}) -DEF_TRAVERSE_STMT(CXXThrowExpr, {}) -DEF_TRAVERSE_STMT(UserDefinedLiteral, {}) -DEF_TRAVERSE_STMT(DesignatedInitExpr, {}) -DEF_TRAVERSE_STMT(DesignatedInitUpdateExpr, {}) -DEF_TRAVERSE_STMT(ExtVectorElementExpr, {}) -DEF_TRAVERSE_STMT(GNUNullExpr, {}) -DEF_TRAVERSE_STMT(ImplicitValueInitExpr, {}) -DEF_TRAVERSE_STMT(NoInitExpr, {}) -DEF_TRAVERSE_STMT(ObjCBoolLiteralExpr, {}) -DEF_TRAVERSE_STMT(ObjCEncodeExpr, { - if (TypeSourceInfo *TInfo = S->getEncodedTypeSourceInfo()) - TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc())); -}) -DEF_TRAVERSE_STMT(ObjCIsaExpr, {}) -DEF_TRAVERSE_STMT(ObjCIvarRefExpr, {}) -DEF_TRAVERSE_STMT(ObjCMessageExpr, { - if (TypeSourceInfo *TInfo = S->getClassReceiverTypeInfo()) - TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc())); -}) -DEF_TRAVERSE_STMT(ObjCPropertyRefExpr, {}) -DEF_TRAVERSE_STMT(ObjCSubscriptRefExpr, {}) -DEF_TRAVERSE_STMT(ObjCProtocolExpr, {}) -DEF_TRAVERSE_STMT(ObjCSelectorExpr, {}) -DEF_TRAVERSE_STMT(ObjCIndirectCopyRestoreExpr, {}) -DEF_TRAVERSE_STMT(ObjCBridgedCastExpr, { - TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc())); -}) -DEF_TRAVERSE_STMT(ParenExpr, {}) -DEF_TRAVERSE_STMT(ParenListExpr, {}) -DEF_TRAVERSE_STMT(PredefinedExpr, {}) -DEF_TRAVERSE_STMT(ShuffleVectorExpr, {}) -DEF_TRAVERSE_STMT(ConvertVectorExpr, {}) -DEF_TRAVERSE_STMT(StmtExpr, {}) -DEF_TRAVERSE_STMT(UnresolvedLookupExpr, { - TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc())); - if (S->hasExplicitTemplateArgs()) { - TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(), - S->getNumTemplateArgs())); - } -}) - -DEF_TRAVERSE_STMT(UnresolvedMemberExpr, { - TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc())); - if (S->hasExplicitTemplateArgs()) { - TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(), - S->getNumTemplateArgs())); - } -}) - -DEF_TRAVERSE_STMT(SEHTryStmt, {}) -DEF_TRAVERSE_STMT(SEHExceptStmt, {}) -DEF_TRAVERSE_STMT(SEHFinallyStmt, {}) -DEF_TRAVERSE_STMT(SEHLeaveStmt, {}) -DEF_TRAVERSE_STMT(CapturedStmt, { TRY_TO(TraverseDecl(S->getCapturedDecl())); }) - -DEF_TRAVERSE_STMT(CXXOperatorCallExpr, {}) -DEF_TRAVERSE_STMT(OpaqueValueExpr, {}) -DEF_TRAVERSE_STMT(TypoExpr, {}) -DEF_TRAVERSE_STMT(CUDAKernelCallExpr, {}) - -// These operators (all of them) do not need any action except -// iterating over the children. -DEF_TRAVERSE_STMT(BinaryConditionalOperator, {}) -DEF_TRAVERSE_STMT(ConditionalOperator, {}) -DEF_TRAVERSE_STMT(UnaryOperator, {}) -DEF_TRAVERSE_STMT(BinaryOperator, {}) -DEF_TRAVERSE_STMT(CompoundAssignOperator, {}) -DEF_TRAVERSE_STMT(CXXNoexceptExpr, {}) -DEF_TRAVERSE_STMT(PackExpansionExpr, {}) -DEF_TRAVERSE_STMT(SizeOfPackExpr, {}) -DEF_TRAVERSE_STMT(SubstNonTypeTemplateParmPackExpr, {}) -DEF_TRAVERSE_STMT(SubstNonTypeTemplateParmExpr, {}) -DEF_TRAVERSE_STMT(FunctionParmPackExpr, {}) -DEF_TRAVERSE_STMT(MaterializeTemporaryExpr, {}) -DEF_TRAVERSE_STMT(CXXFoldExpr, {}) -DEF_TRAVERSE_STMT(AtomicExpr, {}) - -// These literals (all of them) do not need any action. -DEF_TRAVERSE_STMT(IntegerLiteral, {}) -DEF_TRAVERSE_STMT(CharacterLiteral, {}) -DEF_TRAVERSE_STMT(FloatingLiteral, {}) -DEF_TRAVERSE_STMT(ImaginaryLiteral, {}) -DEF_TRAVERSE_STMT(StringLiteral, {}) -DEF_TRAVERSE_STMT(ObjCStringLiteral, {}) -DEF_TRAVERSE_STMT(ObjCBoxedExpr, {}) -DEF_TRAVERSE_STMT(ObjCArrayLiteral, {}) -DEF_TRAVERSE_STMT(ObjCDictionaryLiteral, {}) - -// Traverse OpenCL: AsType, Convert. -DEF_TRAVERSE_STMT(AsTypeExpr, {}) - -// OpenMP directives. -template <typename Derived> -bool RecursiveASTVisitor<Derived>::TraverseOMPExecutableDirective( - OMPExecutableDirective *S) { - for (auto *C : S->clauses()) { - TRY_TO(TraverseOMPClause(C)); - } - return true; -} - -template <typename Derived> -bool -RecursiveASTVisitor<Derived>::TraverseOMPLoopDirective(OMPLoopDirective *S) { - return TraverseOMPExecutableDirective(S); -} - -DEF_TRAVERSE_STMT(OMPParallelDirective, - { TRY_TO(TraverseOMPExecutableDirective(S)); }) - -DEF_TRAVERSE_STMT(OMPSimdDirective, - { TRY_TO(TraverseOMPExecutableDirective(S)); }) - -DEF_TRAVERSE_STMT(OMPForDirective, - { TRY_TO(TraverseOMPExecutableDirective(S)); }) - -DEF_TRAVERSE_STMT(OMPForSimdDirective, - { TRY_TO(TraverseOMPExecutableDirective(S)); }) - -DEF_TRAVERSE_STMT(OMPSectionsDirective, - { TRY_TO(TraverseOMPExecutableDirective(S)); }) - -DEF_TRAVERSE_STMT(OMPSectionDirective, - { TRY_TO(TraverseOMPExecutableDirective(S)); }) - -DEF_TRAVERSE_STMT(OMPSingleDirective, - { TRY_TO(TraverseOMPExecutableDirective(S)); }) - -DEF_TRAVERSE_STMT(OMPMasterDirective, - { TRY_TO(TraverseOMPExecutableDirective(S)); }) - -DEF_TRAVERSE_STMT(OMPCriticalDirective, { - TRY_TO(TraverseDeclarationNameInfo(S->getDirectiveName())); - TRY_TO(TraverseOMPExecutableDirective(S)); -}) - -DEF_TRAVERSE_STMT(OMPParallelForDirective, - { TRY_TO(TraverseOMPExecutableDirective(S)); }) - -DEF_TRAVERSE_STMT(OMPParallelForSimdDirective, - { TRY_TO(TraverseOMPExecutableDirective(S)); }) - -DEF_TRAVERSE_STMT(OMPParallelSectionsDirective, - { TRY_TO(TraverseOMPExecutableDirective(S)); }) - -DEF_TRAVERSE_STMT(OMPTaskDirective, - { TRY_TO(TraverseOMPExecutableDirective(S)); }) - -DEF_TRAVERSE_STMT(OMPTaskyieldDirective, - { TRY_TO(TraverseOMPExecutableDirective(S)); }) - -DEF_TRAVERSE_STMT(OMPBarrierDirective, - { TRY_TO(TraverseOMPExecutableDirective(S)); }) - -DEF_TRAVERSE_STMT(OMPTaskwaitDirective, - { TRY_TO(TraverseOMPExecutableDirective(S)); }) - -DEF_TRAVERSE_STMT(OMPTaskgroupDirective, - { TRY_TO(TraverseOMPExecutableDirective(S)); }) - -DEF_TRAVERSE_STMT(OMPCancellationPointDirective, - { TRY_TO(TraverseOMPExecutableDirective(S)); }) - -DEF_TRAVERSE_STMT(OMPCancelDirective, - { TRY_TO(TraverseOMPExecutableDirective(S)); }) - -DEF_TRAVERSE_STMT(OMPFlushDirective, - { TRY_TO(TraverseOMPExecutableDirective(S)); }) - -DEF_TRAVERSE_STMT(OMPOrderedDirective, - { TRY_TO(TraverseOMPExecutableDirective(S)); }) - -DEF_TRAVERSE_STMT(OMPAtomicDirective, - { TRY_TO(TraverseOMPExecutableDirective(S)); }) - -DEF_TRAVERSE_STMT(OMPTargetDirective, - { TRY_TO(TraverseOMPExecutableDirective(S)); }) - -DEF_TRAVERSE_STMT(OMPTeamsDirective, - { TRY_TO(TraverseOMPExecutableDirective(S)); }) - -// OpenMP clauses. -template <typename Derived> -bool RecursiveASTVisitor<Derived>::TraverseOMPClause(OMPClause *C) { - if (!C) - return true; - switch (C->getClauseKind()) { -#define OPENMP_CLAUSE(Name, Class) \ - case OMPC_##Name: \ - TRY_TO(Visit##Class(static_cast<Class *>(C))); \ - break; -#include "clang/Basic/OpenMPKinds.def" - case OMPC_threadprivate: - case OMPC_unknown: - break; - } - return true; -} - -template <typename Derived> -bool RecursiveASTVisitor<Derived>::VisitOMPIfClause(OMPIfClause *C) { - TRY_TO(TraverseStmt(C->getCondition())); - return true; -} - -template <typename Derived> -bool RecursiveASTVisitor<Derived>::VisitOMPFinalClause(OMPFinalClause *C) { - TRY_TO(TraverseStmt(C->getCondition())); - return true; -} - -template <typename Derived> -bool -RecursiveASTVisitor<Derived>::VisitOMPNumThreadsClause(OMPNumThreadsClause *C) { - TRY_TO(TraverseStmt(C->getNumThreads())); - return true; -} - -template <typename Derived> -bool RecursiveASTVisitor<Derived>::VisitOMPSafelenClause(OMPSafelenClause *C) { - TRY_TO(TraverseStmt(C->getSafelen())); - return true; -} - -template <typename Derived> -bool -RecursiveASTVisitor<Derived>::VisitOMPCollapseClause(OMPCollapseClause *C) { - TRY_TO(TraverseStmt(C->getNumForLoops())); - return true; -} - -template <typename Derived> -bool RecursiveASTVisitor<Derived>::VisitOMPDefaultClause(OMPDefaultClause *) { - return true; -} - -template <typename Derived> -bool RecursiveASTVisitor<Derived>::VisitOMPProcBindClause(OMPProcBindClause *) { - return true; -} - -template <typename Derived> -bool -RecursiveASTVisitor<Derived>::VisitOMPScheduleClause(OMPScheduleClause *C) { - TRY_TO(TraverseStmt(C->getChunkSize())); - TRY_TO(TraverseStmt(C->getHelperChunkSize())); - return true; -} - -template <typename Derived> -bool RecursiveASTVisitor<Derived>::VisitOMPOrderedClause(OMPOrderedClause *) { - return true; -} - -template <typename Derived> -bool RecursiveASTVisitor<Derived>::VisitOMPNowaitClause(OMPNowaitClause *) { - return true; -} - -template <typename Derived> -bool RecursiveASTVisitor<Derived>::VisitOMPUntiedClause(OMPUntiedClause *) { - return true; -} - -template <typename Derived> -bool -RecursiveASTVisitor<Derived>::VisitOMPMergeableClause(OMPMergeableClause *) { - return true; -} - -template <typename Derived> -bool RecursiveASTVisitor<Derived>::VisitOMPReadClause(OMPReadClause *) { - return true; -} - -template <typename Derived> -bool RecursiveASTVisitor<Derived>::VisitOMPWriteClause(OMPWriteClause *) { - return true; -} - -template <typename Derived> -bool RecursiveASTVisitor<Derived>::VisitOMPUpdateClause(OMPUpdateClause *) { - return true; -} - -template <typename Derived> -bool RecursiveASTVisitor<Derived>::VisitOMPCaptureClause(OMPCaptureClause *) { - return true; -} - -template <typename Derived> -bool RecursiveASTVisitor<Derived>::VisitOMPSeqCstClause(OMPSeqCstClause *) { - return true; -} - -template <typename Derived> -template <typename T> -bool RecursiveASTVisitor<Derived>::VisitOMPClauseList(T *Node) { - for (auto *E : Node->varlists()) { - TRY_TO(TraverseStmt(E)); - } - return true; -} - -template <typename Derived> -bool RecursiveASTVisitor<Derived>::VisitOMPPrivateClause(OMPPrivateClause *C) { - TRY_TO(VisitOMPClauseList(C)); - for (auto *E : C->private_copies()) { - TRY_TO(TraverseStmt(E)); - } - return true; -} - -template <typename Derived> -bool RecursiveASTVisitor<Derived>::VisitOMPFirstprivateClause( - OMPFirstprivateClause *C) { - TRY_TO(VisitOMPClauseList(C)); - for (auto *E : C->private_copies()) { - TRY_TO(TraverseStmt(E)); - } - for (auto *E : C->inits()) { - TRY_TO(TraverseStmt(E)); - } - return true; -} - -template <typename Derived> -bool RecursiveASTVisitor<Derived>::VisitOMPLastprivateClause( - OMPLastprivateClause *C) { - TRY_TO(VisitOMPClauseList(C)); - for (auto *E : C->private_copies()) { - TRY_TO(TraverseStmt(E)); - } - for (auto *E : C->source_exprs()) { - TRY_TO(TraverseStmt(E)); - } - for (auto *E : C->destination_exprs()) { - TRY_TO(TraverseStmt(E)); - } - for (auto *E : C->assignment_ops()) { - TRY_TO(TraverseStmt(E)); - } - return true; -} - -template <typename Derived> -bool RecursiveASTVisitor<Derived>::VisitOMPSharedClause(OMPSharedClause *C) { - TRY_TO(VisitOMPClauseList(C)); - return true; -} - -template <typename Derived> -bool RecursiveASTVisitor<Derived>::VisitOMPLinearClause(OMPLinearClause *C) { - TRY_TO(TraverseStmt(C->getStep())); - TRY_TO(TraverseStmt(C->getCalcStep())); - TRY_TO(VisitOMPClauseList(C)); - for (auto *E : C->inits()) { - TRY_TO(TraverseStmt(E)); - } - for (auto *E : C->updates()) { - TRY_TO(TraverseStmt(E)); - } - for (auto *E : C->finals()) { - TRY_TO(TraverseStmt(E)); - } - return true; -} - -template <typename Derived> -bool RecursiveASTVisitor<Derived>::VisitOMPAlignedClause(OMPAlignedClause *C) { - TRY_TO(TraverseStmt(C->getAlignment())); - TRY_TO(VisitOMPClauseList(C)); - return true; -} - -template <typename Derived> -bool RecursiveASTVisitor<Derived>::VisitOMPCopyinClause(OMPCopyinClause *C) { - TRY_TO(VisitOMPClauseList(C)); - for (auto *E : C->source_exprs()) { - TRY_TO(TraverseStmt(E)); - } - for (auto *E : C->destination_exprs()) { - TRY_TO(TraverseStmt(E)); - } - for (auto *E : C->assignment_ops()) { - TRY_TO(TraverseStmt(E)); - } - return true; -} - -template <typename Derived> -bool RecursiveASTVisitor<Derived>::VisitOMPCopyprivateClause( - OMPCopyprivateClause *C) { - TRY_TO(VisitOMPClauseList(C)); - for (auto *E : C->source_exprs()) { - TRY_TO(TraverseStmt(E)); - } - for (auto *E : C->destination_exprs()) { - TRY_TO(TraverseStmt(E)); - } - for (auto *E : C->assignment_ops()) { - TRY_TO(TraverseStmt(E)); - } - return true; -} - -template <typename Derived> -bool -RecursiveASTVisitor<Derived>::VisitOMPReductionClause(OMPReductionClause *C) { - TRY_TO(TraverseNestedNameSpecifierLoc(C->getQualifierLoc())); - TRY_TO(TraverseDeclarationNameInfo(C->getNameInfo())); - TRY_TO(VisitOMPClauseList(C)); - for (auto *E : C->lhs_exprs()) { - TRY_TO(TraverseStmt(E)); - } - for (auto *E : C->rhs_exprs()) { - TRY_TO(TraverseStmt(E)); - } - for (auto *E : C->reduction_ops()) { - TRY_TO(TraverseStmt(E)); - } - return true; -} - -template <typename Derived> -bool RecursiveASTVisitor<Derived>::VisitOMPFlushClause(OMPFlushClause *C) { - TRY_TO(VisitOMPClauseList(C)); - return true; -} - -template <typename Derived> -bool RecursiveASTVisitor<Derived>::VisitOMPDependClause(OMPDependClause *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 -// not sure if they own them -- or just seemed very complicated, or -// had lots of sub-types to explore. -// -// VisitOverloadExpr and its children: recurse on template args? etc? - -// FIXME: go through all the stmts and exprs again, and see which of them -// create new types, and recurse on the types (TypeLocs?) of those. -// Candidates: -// -// http://clang.llvm.org/doxygen/classclang_1_1CXXTypeidExpr.html -// http://clang.llvm.org/doxygen/classclang_1_1UnaryExprOrTypeTraitExpr.html -// http://clang.llvm.org/doxygen/classclang_1_1TypesCompatibleExpr.html -// Every class that has getQualifier. - -#undef DEF_TRAVERSE_STMT - -#undef TRY_TO - -#undef RecursiveASTVisitor - -} // end namespace clang - -#endif // LLVM_CLANG_LIBCLANG_RECURSIVEASTVISITOR_H diff --git a/contrib/llvm/tools/clang/include/clang/AST/Decl.h b/contrib/llvm/tools/clang/include/clang/AST/Decl.h index e06b58b..046ce70 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/Decl.h +++ b/contrib/llvm/tools/clang/include/clang/AST/Decl.h @@ -21,11 +21,13 @@ #include "clang/AST/Redeclarable.h" #include "clang/AST/Type.h" #include "clang/Basic/Linkage.h" +#include "clang/Basic/Module.h" #include "clang/Basic/OperatorKinds.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/Optional.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/raw_ostream.h" +#include "llvm/Support/TrailingObjects.h" namespace clang { struct ASTTemplateArgumentListInfo; @@ -37,7 +39,6 @@ class FunctionTemplateDecl; class FunctionTemplateSpecializationInfo; class LabelStmt; class MemberSpecializationInfo; -class Module; class NestedNameSpecifier; class ParmVarDecl; class Stmt; @@ -318,7 +319,8 @@ public: NamedDecl *getUnderlyingDecl() { // Fast-path the common case. if (this->getKind() != UsingShadow && - this->getKind() != ObjCCompatibleAlias) + this->getKind() != ObjCCompatibleAlias && + this->getKind() != NamespaceAlias) return this; return getUnderlyingDeclImpl(); @@ -462,25 +464,15 @@ public: } /// \brief Get the original (first) namespace declaration. - NamespaceDecl *getOriginalNamespace() { - if (isFirstDecl()) - return this; - - return AnonOrFirstNamespaceAndInline.getPointer(); - } + NamespaceDecl *getOriginalNamespace(); /// \brief Get the original (first) namespace declaration. - const NamespaceDecl *getOriginalNamespace() const { - if (isFirstDecl()) - return this; - - return AnonOrFirstNamespaceAndInline.getPointer(); - } + const NamespaceDecl *getOriginalNamespace() const; /// \brief Return true if this declaration is an original (first) declaration /// of the namespace. This is false for non-original (subsequent) namespace /// declarations and anonymous namespaces. - bool isOriginalNamespace() const { return isFirstDecl(); } + bool isOriginalNamespace() const; /// \brief Retrieve the anonymous namespace nested inside this namespace, /// if any. @@ -572,8 +564,7 @@ struct QualifierInfo { /// setTemplateParameterListsInfo - Sets info about "outer" template /// parameter lists. void setTemplateParameterListsInfo(ASTContext &Context, - unsigned NumTPLists, - TemplateParameterList **TPLists); + ArrayRef<TemplateParameterList *> TPLists); private: // Copy constructor and copy assignment are disabled. @@ -658,8 +649,8 @@ public: assert(index < getNumTemplateParameterLists()); return getExtInfo()->TemplParamLists[index]; } - void setTemplateParameterListsInfo(ASTContext &Context, unsigned NumTPLists, - TemplateParameterList **TPLists); + void setTemplateParameterListsInfo(ASTContext &Context, + ArrayRef<TemplateParameterList *> TPLists); SourceLocation getTypeSpecStartLoc() const; @@ -728,17 +719,14 @@ public: }; protected: - /// \brief Placeholder type used in Init to denote an unparsed C++ default - /// argument. - struct UnparsedDefaultArgument; - - /// \brief Placeholder type used in Init to denote an uninstantiated C++ - /// default argument. - struct UninstantiatedDefaultArgument; - - typedef llvm::PointerUnion4<Stmt *, EvaluatedStmt *, - UnparsedDefaultArgument *, - UninstantiatedDefaultArgument *> InitType; + // A pointer union of Stmt * and EvaluatedStmt *. When an EvaluatedStmt, we + // have allocated the auxilliary struct of information there. + // + // TODO: It is a bit unfortunate to use a PointerUnion inside the VarDecl for + // this as *many* VarDecls are ParmVarDecls that don't have default + // arguments. We could save some space by moving this pointer union to be + // allocated in trailing space when necessary. + typedef llvm::PointerUnion<Stmt *, EvaluatedStmt *> InitType; /// \brief The initializer for this variable or, for a ParmVarDecl, the /// C++ default argument. @@ -762,6 +750,13 @@ private: protected: enum { NumParameterIndexBits = 8 }; + enum DefaultArgKind { + DAK_None, + DAK_Unparsed, + DAK_Uninstantiated, + DAK_Normal + }; + class ParmVarDeclBitfields { friend class ParmVarDecl; friend class ASTDeclReader; @@ -772,6 +767,12 @@ protected: /// prior declaration. unsigned HasInheritedDefaultArg : 1; + /// Describes the kind of default argument for this parameter. By default + /// this is none. If this is normal, then the default argument is stored in + /// the \c VarDecl initalizer expression unless we were unble to parse + /// (even an invalid) expression for the default argument. + unsigned DefaultArgKind : 2; + /// Whether this parameter undergoes K&R argument promotion. unsigned IsKNRPromoted : 1; @@ -815,6 +816,9 @@ protected: /// \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; @@ -1062,47 +1066,14 @@ public: /// declaration it is attached to. Also get that declaration. const Expr *getAnyInitializer(const VarDecl *&D) const; - bool hasInit() const { - return !Init.isNull() && (Init.is<Stmt *>() || Init.is<EvaluatedStmt *>()); - } + bool hasInit() const; const Expr *getInit() const { - if (Init.isNull()) - return nullptr; - - const Stmt *S = Init.dyn_cast<Stmt *>(); - if (!S) { - if (EvaluatedStmt *ES = Init.dyn_cast<EvaluatedStmt*>()) - S = ES->Value; - } - return (const Expr*) S; - } - Expr *getInit() { - if (Init.isNull()) - return nullptr; - - Stmt *S = Init.dyn_cast<Stmt *>(); - if (!S) { - if (EvaluatedStmt *ES = Init.dyn_cast<EvaluatedStmt*>()) - S = ES->Value; - } - - return (Expr*) S; + return const_cast<VarDecl *>(this)->getInit(); } + Expr *getInit(); /// \brief Retrieve the address of the initializer expression. - Stmt **getInitAddress() { - if (EvaluatedStmt *ES = Init.dyn_cast<EvaluatedStmt*>()) - return &ES->Value; - - // This union hack tip-toes around strict-aliasing rules. - union { - InitType *InitPtr; - Stmt **StmtPtr; - }; - - InitPtr = &Init; - return StmtPtr; - } + Stmt **getInitAddress(); void setInit(Expr *I); @@ -1124,33 +1095,18 @@ public: /// \brief Return the already-evaluated value of this variable's /// initializer, or NULL if the value is not yet known. Returns pointer /// to untyped APValue if the value could not be evaluated. - APValue *getEvaluatedValue() const { - if (EvaluatedStmt *Eval = Init.dyn_cast<EvaluatedStmt *>()) - if (Eval->WasEvaluated) - return &Eval->Evaluated; - - return nullptr; - } + APValue *getEvaluatedValue() const; /// \brief Determines whether it is already known whether the /// initializer is an integral constant expression or not. - bool isInitKnownICE() const { - if (EvaluatedStmt *Eval = Init.dyn_cast<EvaluatedStmt *>()) - return Eval->CheckedICE; - - return false; - } + bool isInitKnownICE() const; /// \brief Determines whether the initializer is an integral constant /// expression, or in C++11, whether the initializer is a constant /// expression. /// /// \pre isInitKnownICE() - bool isInitICE() const { - assert(isInitKnownICE() && - "Check whether we already know that the initializer is an ICE"); - return Init.get<EvaluatedStmt *>()->IsICE; - } + bool isInitICE() const; /// \brief Determine whether the value of the initializer attached to this /// declaration is an integral constant expression. @@ -1238,6 +1194,15 @@ 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; @@ -1342,6 +1307,7 @@ protected: TypeSourceInfo *TInfo, StorageClass S, Expr *DefArg) : VarDecl(DK, C, DC, StartLoc, IdLoc, Id, T, TInfo, S) { assert(ParmVarDeclBits.HasInheritedDefaultArg == false); + assert(ParmVarDeclBits.DefaultArgKind == DAK_None); assert(ParmVarDeclBits.IsKNRPromoted == false); assert(ParmVarDeclBits.IsObjCMethodParam == false); setDefaultArg(DefArg); @@ -1416,29 +1382,20 @@ public: return const_cast<ParmVarDecl *>(this)->getDefaultArg(); } - void setDefaultArg(Expr *defarg) { - Init = reinterpret_cast<Stmt *>(defarg); - } + void setDefaultArg(Expr *defarg); /// \brief Retrieve the source range that covers the entire default /// argument. SourceRange getDefaultArgRange() const; - void setUninstantiatedDefaultArg(Expr *arg) { - Init = reinterpret_cast<UninstantiatedDefaultArgument *>(arg); - } - Expr *getUninstantiatedDefaultArg() { - return (Expr *)Init.get<UninstantiatedDefaultArgument *>(); - } + void setUninstantiatedDefaultArg(Expr *arg); + Expr *getUninstantiatedDefaultArg(); const Expr *getUninstantiatedDefaultArg() const { - return (const Expr *)Init.get<UninstantiatedDefaultArgument *>(); + return const_cast<ParmVarDecl *>(this)->getUninstantiatedDefaultArg(); } /// hasDefaultArg - Determines whether this parameter has a default argument, /// either parsed or not. - bool hasDefaultArg() const { - return getInit() || hasUnparsedDefaultArg() || - hasUninstantiatedDefaultArg(); - } + bool hasDefaultArg() const; /// hasUnparsedDefaultArg - Determines whether this parameter has a /// default argument that has not yet been parsed. This will occur @@ -1451,11 +1408,11 @@ public: /// }; // x has a regular default argument now /// @endcode bool hasUnparsedDefaultArg() const { - return Init.is<UnparsedDefaultArgument*>(); + return ParmVarDeclBits.DefaultArgKind == DAK_Unparsed; } bool hasUninstantiatedDefaultArg() const { - return Init.is<UninstantiatedDefaultArgument*>(); + return ParmVarDeclBits.DefaultArgKind == DAK_Uninstantiated; } /// setUnparsedDefaultArg - Specify that this parameter has an @@ -1463,7 +1420,9 @@ public: /// real default argument via setDefaultArg when the class /// definition enclosing the function declaration that owns this /// default argument is completed. - void setUnparsedDefaultArg() { Init = (UnparsedDefaultArgument *)nullptr; } + void setUnparsedDefaultArg() { + ParmVarDeclBits.DefaultArgKind = DAK_Unparsed; + } bool hasInheritedDefaultArg() const { return ParmVarDeclBits.HasInheritedDefaultArg; @@ -1546,25 +1505,25 @@ private: LazyDeclStmtPtr Body; - // FIXME: This can be packed into the bitfields in Decl. - // NOTE: VC++ treats enums as signed, avoid using the StorageClass enum + // FIXME: This can be packed into the bitfields in DeclContext. + // NOTE: VC++ packs bitfields poorly if the types differ. unsigned SClass : 2; - bool IsInline : 1; - bool IsInlineSpecified : 1; - bool IsVirtualAsWritten : 1; - bool IsPure : 1; - bool HasInheritedPrototype : 1; - bool HasWrittenPrototype : 1; - bool IsDeleted : 1; - bool IsTrivial : 1; // sunk from CXXMethodDecl - bool IsDefaulted : 1; // sunk from CXXMethoDecl - bool IsExplicitlyDefaulted : 1; //sunk from CXXMethodDecl - bool HasImplicitReturnZero : 1; - bool IsLateTemplateParsed : 1; - bool IsConstexpr : 1; + unsigned IsInline : 1; + unsigned IsInlineSpecified : 1; + unsigned IsVirtualAsWritten : 1; + unsigned IsPure : 1; + unsigned HasInheritedPrototype : 1; + unsigned HasWrittenPrototype : 1; + unsigned IsDeleted : 1; + unsigned IsTrivial : 1; // sunk from CXXMethodDecl + unsigned IsDefaulted : 1; // sunk from CXXMethoDecl + unsigned IsExplicitlyDefaulted : 1; //sunk from CXXMethodDecl + unsigned HasImplicitReturnZero : 1; + unsigned IsLateTemplateParsed : 1; + unsigned IsConstexpr : 1; /// \brief Indicates if the function uses __try. - bool UsesSEHTry : 1; + unsigned UsesSEHTry : 1; /// \brief Indicates if the function was a definition but its body was /// skipped. @@ -1835,7 +1794,7 @@ public: bool isConstexpr() const { return IsConstexpr; } void setConstexpr(bool IC) { IsConstexpr = IC; } - /// Whether this is a (C++11) constexpr function or constexpr constructor. + /// \brief Indicates the function uses __try. bool usesSEHTry() const { return UsesSEHTry; } void setUsesSEHTry(bool UST) { UsesSEHTry = UST; } @@ -2084,9 +2043,7 @@ public: /// \brief If this function is an instantiation of a member function of a /// class template specialization, retrieves the member specialization /// information. - MemberSpecializationInfo *getMemberSpecializationInfo() const { - return TemplateOrSpecialization.dyn_cast<MemberSpecializationInfo*>(); - } + MemberSpecializationInfo *getMemberSpecializationInfo() const; /// \brief Specify that this record is an instantiation of the /// member function FD. @@ -2107,13 +2064,9 @@ public: /// FunctionDecl that describes the function template, /// getDescribedFunctionTemplate() retrieves the /// FunctionTemplateDecl from a FunctionDecl. - FunctionTemplateDecl *getDescribedFunctionTemplate() const { - return TemplateOrSpecialization.dyn_cast<FunctionTemplateDecl*>(); - } + FunctionTemplateDecl *getDescribedFunctionTemplate() const; - void setDescribedFunctionTemplate(FunctionTemplateDecl *Template) { - TemplateOrSpecialization = Template; - } + void setDescribedFunctionTemplate(FunctionTemplateDecl *Template); /// \brief Determine whether this function is a function template /// specialization. @@ -2128,10 +2081,7 @@ public: /// \brief If this function is actually a function template specialization, /// retrieve information about this function template specialization. /// Otherwise, returns NULL. - FunctionTemplateSpecializationInfo *getTemplateSpecializationInfo() const { - return TemplateOrSpecialization. - dyn_cast<FunctionTemplateSpecializationInfo*>(); - } + FunctionTemplateSpecializationInfo *getTemplateSpecializationInfo() const; /// \brief Determines whether this function is a function template /// specialization or a member of a class template specialization that can @@ -2208,10 +2158,7 @@ public: const TemplateArgumentListInfo &TemplateArgs); DependentFunctionTemplateSpecializationInfo * - getDependentSpecializationInfo() const { - return TemplateOrSpecialization. - dyn_cast<DependentFunctionTemplateSpecializationInfo*>(); - } + getDependentSpecializationInfo() const; /// \brief Determine what kind of template instantiation this function /// represents. @@ -2487,7 +2434,8 @@ public: /// IndirectFieldDecl - An instance of this class is created to represent a /// field injected from an anonymous union/struct into the parent scope. /// IndirectFieldDecl are always implicit. -class IndirectFieldDecl : public ValueDecl { +class IndirectFieldDecl : public ValueDecl, + public Mergeable<IndirectFieldDecl> { void anchor() override; NamedDecl **Chaining; unsigned ChainingSize; @@ -2525,6 +2473,9 @@ public: return dyn_cast<VarDecl>(*chain_begin()); } + IndirectFieldDecl *getCanonicalDecl() override { return getFirstDecl(); } + const IndirectFieldDecl *getCanonicalDecl() const { return getFirstDecl(); } + // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K == IndirectField; } @@ -2762,12 +2713,12 @@ private: /// declaration specifier for variables, it points to the first VarDecl (used /// for mangling); /// otherwise, it is a null (TypedefNameDecl) pointer. - llvm::PointerUnion<NamedDecl *, ExtInfo *> NamedDeclOrQualifier; + llvm::PointerUnion<TypedefNameDecl *, ExtInfo *> TypedefNameDeclOrQualifier; - bool hasExtInfo() const { return NamedDeclOrQualifier.is<ExtInfo *>(); } - ExtInfo *getExtInfo() { return NamedDeclOrQualifier.get<ExtInfo *>(); } + bool hasExtInfo() const { return TypedefNameDeclOrQualifier.is<ExtInfo *>(); } + ExtInfo *getExtInfo() { return TypedefNameDeclOrQualifier.get<ExtInfo *>(); } const ExtInfo *getExtInfo() const { - return NamedDeclOrQualifier.get<ExtInfo *>(); + return TypedefNameDeclOrQualifier.get<ExtInfo *>(); } protected: @@ -2778,7 +2729,7 @@ protected: TagDeclKind(TK), IsCompleteDefinition(false), IsBeingDefined(false), IsEmbeddedInDeclarator(false), IsFreeStanding(false), IsCompleteDefinitionRequired(false), - NamedDeclOrQualifier((NamedDecl *)nullptr) { + TypedefNameDeclOrQualifier((TypedefNameDecl *)nullptr) { assert((DK != Enum || TK == TTK_Enum) && "EnumDecl not matched with TTK_Enum"); setPreviousDecl(PrevDecl); @@ -2925,22 +2876,11 @@ public: return (getDeclName() || getTypedefNameForAnonDecl()); } - bool hasDeclaratorForAnonDecl() const { - return dyn_cast_or_null<DeclaratorDecl>( - NamedDeclOrQualifier.get<NamedDecl *>()); - } - DeclaratorDecl *getDeclaratorForAnonDecl() const { - return hasExtInfo() ? nullptr : dyn_cast_or_null<DeclaratorDecl>( - NamedDeclOrQualifier.get<NamedDecl *>()); - } - TypedefNameDecl *getTypedefNameForAnonDecl() const { - return hasExtInfo() ? nullptr : dyn_cast_or_null<TypedefNameDecl>( - NamedDeclOrQualifier.get<NamedDecl *>()); + return hasExtInfo() ? nullptr + : TypedefNameDeclOrQualifier.get<TypedefNameDecl *>(); } - void setDeclaratorForAnonDecl(DeclaratorDecl *DD) { NamedDeclOrQualifier = DD; } - void setTypedefNameForAnonDecl(TypedefNameDecl *TDD); /// \brief Retrieve the nested-name-specifier that qualifies the name of this @@ -2967,8 +2907,8 @@ public: assert(i < getNumTemplateParameterLists()); return getExtInfo()->TemplParamLists[i]; } - void setTemplateParameterListsInfo(ASTContext &Context, unsigned NumTPLists, - TemplateParameterList **TPLists); + void setTemplateParameterListsInfo(ASTContext &Context, + ArrayRef<TemplateParameterList *> TPLists); // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } @@ -3301,7 +3241,14 @@ public: bool hasVolatileMember() const { return HasVolatileMember; } void setHasVolatileMember (bool val) { HasVolatileMember = val; } - + + bool hasLoadedFieldsFromExternalStorage() const { + return LoadedFieldsFromExternalStorage; + } + void setHasLoadedFieldsFromExternalStorage(bool val) { + LoadedFieldsFromExternalStorage = val; + } + /// \brief Determines whether this declaration represents the /// injected class name. /// @@ -3475,7 +3422,7 @@ private: Stmt *Body; TypeSourceInfo *SignatureAsWritten; - Capture *Captures; + const Capture *Captures; unsigned NumCaptures; unsigned ManglingNumber; @@ -3581,10 +3528,8 @@ public: bool capturesVariable(const VarDecl *var) const; - void setCaptures(ASTContext &Context, - const Capture *begin, - const Capture *end, - bool capturesCXXThis); + void setCaptures(ASTContext &Context, ArrayRef<Capture> Captures, + bool CapturesCXXThis); unsigned getBlockManglingNumber() const { return ManglingNumber; @@ -3613,7 +3558,15 @@ public: /// \brief This represents the body of a CapturedStmt, and serves as its /// DeclContext. -class CapturedDecl : public Decl, public DeclContext { +class CapturedDecl final + : public Decl, + public DeclContext, + private llvm::TrailingObjects<CapturedDecl, ImplicitParamDecl *> { +protected: + size_t numTrailingObjects(OverloadToken<ImplicitParamDecl>) { + return NumParams; + } + private: /// \brief The number of parameters to the outlined function. unsigned NumParams; @@ -3622,13 +3575,14 @@ private: /// \brief The body of the outlined function. llvm::PointerIntPair<Stmt *, 1, bool> BodyAndNothrow; - explicit CapturedDecl(DeclContext *DC, unsigned NumParams) - : Decl(Captured, DC, SourceLocation()), DeclContext(Captured), - NumParams(NumParams), ContextParam(0), BodyAndNothrow(nullptr, false) { } + explicit CapturedDecl(DeclContext *DC, unsigned NumParams); + + ImplicitParamDecl *const *getParams() const { + return getTrailingObjects<ImplicitParamDecl *>(); + } - ImplicitParamDecl **getParams() const { - return reinterpret_cast<ImplicitParamDecl **>( - const_cast<CapturedDecl *>(this) + 1); + ImplicitParamDecl **getParams() { + return getTrailingObjects<ImplicitParamDecl *>(); } public: @@ -3637,11 +3591,11 @@ public: static CapturedDecl *CreateDeserialized(ASTContext &C, unsigned ID, unsigned NumParams); - Stmt *getBody() const override { return BodyAndNothrow.getPointer(); } - void setBody(Stmt *B) { BodyAndNothrow.setPointer(B); } + Stmt *getBody() const override; + void setBody(Stmt *B); - bool isNothrow() const { return BodyAndNothrow.getInt(); } - void setNothrow(bool Nothrow = true) { BodyAndNothrow.setInt(Nothrow); } + bool isNothrow() const; + void setNothrow(bool Nothrow = true); unsigned getNumParams() const { return NumParams; } @@ -3666,7 +3620,7 @@ public: } unsigned getContextParamPosition() const { return ContextParam; } - typedef ImplicitParamDecl **param_iterator; + typedef ImplicitParamDecl *const *param_iterator; typedef llvm::iterator_range<param_iterator> param_range; /// \brief Retrieve an iterator pointing to the first parameter decl. @@ -3689,6 +3643,7 @@ public: friend class ASTDeclReader; friend class ASTDeclWriter; + friend TrailingObjects; }; /// \brief Describes a module import declaration, which makes the contents @@ -3701,7 +3656,8 @@ public: /// /// Import declarations can also be implicitly generated from /// \#include/\#import directives. -class ImportDecl : public Decl { +class ImportDecl final : public Decl, + llvm::TrailingObjects<ImportDecl, SourceLocation> { /// \brief The imported module, along with a bit that indicates whether /// we have source-location information for each identifier in the module /// name. @@ -3717,7 +3673,8 @@ class ImportDecl : public Decl { friend class ASTReader; friend class ASTDeclReader; friend class ASTContext; - + friend TrailingObjects; + ImportDecl(DeclContext *DC, SourceLocation StartLoc, Module *Imported, ArrayRef<SourceLocation> IdentifierLocs); diff --git a/contrib/llvm/tools/clang/include/clang/AST/DeclBase.h b/contrib/llvm/tools/clang/include/clang/AST/DeclBase.h index 6b6ac3f..05b2a12 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/DeclBase.h +++ b/contrib/llvm/tools/clang/include/clang/AST/DeclBase.h @@ -70,8 +70,15 @@ namespace clang { /// Decl - This represents one declaration (or definition), e.g. a variable, /// typedef, function, struct, etc. /// +/// 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 +/// asserted in DeclBase.cpp. class 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, @@ -468,8 +475,7 @@ public: template <typename T> llvm::iterator_range<specific_attr_iterator<T>> specific_attrs() const { - return llvm::iterator_range<specific_attr_iterator<T>>( - specific_attr_begin<T>(), specific_attr_end<T>()); + return llvm::make_range(specific_attr_begin<T>(), specific_attr_end<T>()); } template <typename T> @@ -721,6 +727,15 @@ public: return getParentFunctionOrMethod() == nullptr; } + /// \brief Returns true if this declaration lexically is inside a function. + /// It recognizes non-defining declarations as well as members of local + /// classes: + /// \code + /// void foo() { void bar(); } + /// void foo2() { class ABC { void bar(); }; } + /// \endcode + bool isLexicallyWithinFunctionOrMethod() const; + /// \brief If this decl is defined inside a function/method/block it returns /// the corresponding DeclContext, otherwise it returns null. const DeclContext *getParentFunctionOrMethod() const; @@ -1126,6 +1141,11 @@ class DeclContext { /// that are missing from the lookup table. mutable bool HasLazyExternalLexicalLookups : 1; + /// \brief If \c true, lookups should only return identifier from + /// DeclContext scope (for example TranslationUnit). Used in + /// LookupQualifiedName() + mutable bool UseQualifiedLookup : 1; + /// \brief Pointer to the data structure used to lookup declarations /// within this context (or a DependentStoredDeclsMap if this is a /// dependent context). We maintain the invariant that, if the map @@ -1160,6 +1180,7 @@ protected: ExternalVisibleStorage(false), NeedToReconcileExternalVisibleStorage(false), HasLazyLocalLexicalLookups(false), HasLazyExternalLexicalLookups(false), + UseQualifiedLookup(false), LookupPtr(nullptr), FirstDecl(nullptr), LastDecl(nullptr) {} public: @@ -1740,6 +1761,16 @@ public: D == LastDecl); } + bool setUseQualifiedLookup(bool use = true) { + bool old_value = UseQualifiedLookup; + UseQualifiedLookup = use; + return old_value; + } + + bool shouldUseQualifiedLookup() const { + return UseQualifiedLookup; + } + static bool classof(const Decl *D); static bool classof(const DeclContext *D) { return true; } diff --git a/contrib/llvm/tools/clang/include/clang/AST/DeclCXX.h b/contrib/llvm/tools/clang/include/clang/AST/DeclCXX.h index 08451c0..7c54901 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/DeclCXX.h +++ b/contrib/llvm/tools/clang/include/clang/AST/DeclCXX.h @@ -1344,9 +1344,7 @@ public: /// \brief If this class is an instantiation of a member class of a /// class template specialization, retrieves the member specialization /// information. - MemberSpecializationInfo *getMemberSpecializationInfo() const { - return TemplateOrInstantiation.dyn_cast<MemberSpecializationInfo *>(); - } + MemberSpecializationInfo *getMemberSpecializationInfo() const; /// \brief Specify that this record is an instantiation of the /// member class \p RD. @@ -1364,13 +1362,9 @@ public: /// CXXRecordDecl that from a ClassTemplateDecl, while /// getDescribedClassTemplate() retrieves the ClassTemplateDecl from /// a CXXRecordDecl. - ClassTemplateDecl *getDescribedClassTemplate() const { - return TemplateOrInstantiation.dyn_cast<ClassTemplateDecl*>(); - } + ClassTemplateDecl *getDescribedClassTemplate() const; - void setDescribedClassTemplate(ClassTemplateDecl *Template) { - TemplateOrInstantiation = Template; - } + void setDescribedClassTemplate(ClassTemplateDecl *Template); /// \brief Determine whether this particular class is a specialization or /// instantiation of a class template or member class of a class template, @@ -1468,8 +1462,8 @@ public: /// \param BaseDefinition the definition of the base class /// /// \returns true if this base matched the search criteria - typedef bool ForallBasesCallback(const CXXRecordDecl *BaseDefinition, - void *UserData); + typedef llvm::function_ref<bool(const CXXRecordDecl *BaseDefinition)> + ForallBasesCallback; /// \brief Determines if the given callback holds for all the direct /// or indirect base classes of this type. @@ -1481,13 +1475,10 @@ public: /// class of this type, or if \p AllowShortCircuit is true then until a call /// returns false. /// - /// \param UserData Passed as the second argument of every call to - /// \p BaseMatches. - /// /// \param AllowShortCircuit if false, forces the callback to be called /// for every base class, even if a dependent or non-matching base was /// found. - bool forallBases(ForallBasesCallback *BaseMatches, void *UserData, + bool forallBases(ForallBasesCallback BaseMatches, bool AllowShortCircuit = true) const; /// \brief Function type used by lookupInBases() to determine whether a @@ -1499,13 +1490,9 @@ public: /// \param Path the current path, from the most-derived class down to the /// base named by the \p Specifier. /// - /// \param UserData a single pointer to user-specified data, provided to - /// lookupInBases(). - /// /// \returns true if this base matched the search criteria, false otherwise. - typedef bool BaseMatchesCallback(const CXXBaseSpecifier *Specifier, - CXXBasePath &Path, - void *UserData); + typedef llvm::function_ref<bool(const CXXBaseSpecifier *Specifier, + CXXBasePath &Path)> BaseMatchesCallback; /// \brief Look for entities within the base classes of this C++ class, /// transitively searching all base class subobjects. @@ -1520,14 +1507,12 @@ public: /// \param BaseMatches callback function used to determine whether a given /// base matches the user-defined search criteria. /// - /// \param UserData user data pointer that will be provided to \p BaseMatches. - /// /// \param Paths used to record the paths from this class to its base class /// subobjects that match the search criteria. /// /// \returns true if there exists any path from this class to a base class /// subobject that matches the search criteria. - bool lookupInBases(BaseMatchesCallback *BaseMatches, void *UserData, + bool lookupInBases(BaseMatchesCallback BaseMatches, CXXBasePaths &Paths) const; /// \brief Base-class lookup callback that determines whether the given @@ -1535,10 +1520,10 @@ public: /// /// This callback can be used with \c lookupInBases() to determine whether /// a given derived class has is a base class subobject of a particular type. - /// The user data pointer should refer to the canonical CXXRecordDecl of the + /// The base record pointer should refer to the canonical CXXRecordDecl of the /// base class that we are searching for. static bool FindBaseClass(const CXXBaseSpecifier *Specifier, - CXXBasePath &Path, void *BaseRecord); + CXXBasePath &Path, const CXXRecordDecl *BaseRecord); /// \brief Base-class lookup callback that determines whether the /// given base class specifier refers to a specific class @@ -1546,39 +1531,38 @@ public: /// /// This callback can be used with \c lookupInBases() to determine /// whether a given derived class has is a virtual base class - /// subobject of a particular type. The user data pointer should + /// subobject of a particular type. The base record pointer should /// refer to the canonical CXXRecordDecl of the base class that we /// are searching for. static bool FindVirtualBaseClass(const CXXBaseSpecifier *Specifier, - CXXBasePath &Path, void *BaseRecord); + CXXBasePath &Path, + const CXXRecordDecl *BaseRecord); /// \brief Base-class lookup callback that determines whether there exists /// a tag with the given name. /// /// This callback can be used with \c lookupInBases() to find tag members - /// of the given name within a C++ class hierarchy. The user data pointer - /// is an opaque \c DeclarationName pointer. + /// of the given name within a C++ class hierarchy. static bool FindTagMember(const CXXBaseSpecifier *Specifier, - CXXBasePath &Path, void *Name); + CXXBasePath &Path, DeclarationName Name); /// \brief Base-class lookup callback that determines whether there exists /// a member with the given name. /// /// This callback can be used with \c lookupInBases() to find members - /// of the given name within a C++ class hierarchy. The user data pointer - /// is an opaque \c DeclarationName pointer. + /// of the given name within a C++ class hierarchy. static bool FindOrdinaryMember(const CXXBaseSpecifier *Specifier, - CXXBasePath &Path, void *Name); + 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 membes of + /// This callback can be used with \c lookupInBases() to find members of /// the given name within a C++ class hierarchy that can occur within /// nested-name-specifiers. static bool FindNestedNameSpecifierMember(const CXXBaseSpecifier *Specifier, CXXBasePath &Path, - void *UserData); + DeclarationName Name); /// \brief Retrieve the final overriders for each virtual member /// function in the class hierarchy where this class is the @@ -1898,7 +1882,8 @@ public: /// B(A& a) : A(a), f(3.14159) { } /// }; /// \endcode -class CXXCtorInitializer { +class CXXCtorInitializer final + : private llvm::TrailingObjects<CXXCtorInitializer, VarDecl *> { /// \brief Either the base class name/delegating constructor type (stored as /// a TypeSourceInfo*), an normal field (FieldDecl), or an anonymous field /// (IndirectFieldDecl*) being initialized. @@ -2114,24 +2099,26 @@ public: /// describe an array member initialization. VarDecl *getArrayIndex(unsigned I) { assert(I < getNumArrayIndices() && "Out of bounds member array index"); - return reinterpret_cast<VarDecl **>(this + 1)[I]; + return getTrailingObjects<VarDecl *>()[I]; } const VarDecl *getArrayIndex(unsigned I) const { assert(I < getNumArrayIndices() && "Out of bounds member array index"); - return reinterpret_cast<const VarDecl * const *>(this + 1)[I]; + return getTrailingObjects<VarDecl *>()[I]; } void setArrayIndex(unsigned I, VarDecl *Index) { assert(I < getNumArrayIndices() && "Out of bounds member array index"); - reinterpret_cast<VarDecl **>(this + 1)[I] = Index; + getTrailingObjects<VarDecl *>()[I] = Index; } ArrayRef<VarDecl *> getArrayIndexes() { assert(getNumArrayIndices() != 0 && "Getting indexes for non-array init"); - return llvm::makeArrayRef(reinterpret_cast<VarDecl **>(this + 1), + return llvm::makeArrayRef(getTrailingObjects<VarDecl *>(), getNumArrayIndices()); } /// \brief Get the initializer. Expr *getInit() const { return static_cast<Expr*>(Init); } + + friend TrailingObjects; }; /// \brief Represents a C++ constructor within a class. @@ -2289,14 +2276,14 @@ public: } /// \brief Determine whether this constructor is a move constructor - /// (C++0x [class.copy]p3), which can be used to move values of the class. + /// (C++11 [class.copy]p3), which can be used to move values of the class. /// /// \param TypeQuals If this constructor is a move constructor, will be set /// to the type qualifiers on the referent of the first parameter's type. bool isMoveConstructor(unsigned &TypeQuals) const; /// \brief Determine whether this constructor is a move constructor - /// (C++0x [class.copy]p3), which can be used to move values of the class. + /// (C++11 [class.copy]p3), which can be used to move values of the class. bool isMoveConstructor() const { unsigned TypeQuals = 0; return isMoveConstructor(TypeQuals); @@ -2406,7 +2393,7 @@ class CXXConversionDecl : public CXXMethodDecl { void anchor() override; /// Whether this conversion function declaration is marked /// "explicit", meaning that it can only be applied when the user - /// explicitly wrote a cast. This is a C++0x feature. + /// explicitly wrote a cast. This is a C++11 feature. bool IsExplicitSpecified : 1; CXXConversionDecl(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc, diff --git a/contrib/llvm/tools/clang/include/clang/AST/DeclFriend.h b/contrib/llvm/tools/clang/include/clang/AST/DeclFriend.h index 12b93b4..27b0388 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/DeclFriend.h +++ b/contrib/llvm/tools/clang/include/clang/AST/DeclFriend.h @@ -37,7 +37,9 @@ namespace clang { /// @endcode /// /// The semantic context of a friend decl is its declaring class. -class FriendDecl : public Decl { +class FriendDecl final + : public Decl, + private llvm::TrailingObjects<FriendDecl, TemplateParameterList *> { virtual void anchor(); public: typedef llvm::PointerUnion<NamedDecl*,TypeSourceInfo*> FriendUnion; @@ -62,14 +64,6 @@ private: // template <class T> friend class A<T>::B; unsigned NumTPLists : 31; - // The tail-allocated friend type template parameter lists (if any). - TemplateParameterList* const *getTPLists() const { - return reinterpret_cast<TemplateParameterList* const *>(this + 1); - } - TemplateParameterList **getTPLists() { - return reinterpret_cast<TemplateParameterList**>(this + 1); - } - friend class CXXRecordDecl::friend_iterator; friend class CXXRecordDecl; @@ -83,7 +77,7 @@ private: UnsupportedFriend(false), NumTPLists(FriendTypeTPLists.size()) { for (unsigned i = 0; i < NumTPLists; ++i) - getTPLists()[i] = FriendTypeTPLists[i]; + getTrailingObjects<TemplateParameterList *>()[i] = FriendTypeTPLists[i]; } FriendDecl(EmptyShell Empty, unsigned NumFriendTypeTPLists) @@ -118,7 +112,7 @@ public: } TemplateParameterList *getFriendTypeTemplateParameterList(unsigned N) const { assert(N < NumTPLists); - return getTPLists()[N]; + return getTrailingObjects<TemplateParameterList *>()[N]; } /// If this friend declaration doesn't name a type, return the inner @@ -148,9 +142,10 @@ public: return SourceRange(getFriendLoc(), ND->getLocEnd()); } else if (TypeSourceInfo *TInfo = getFriendType()) { - SourceLocation StartL = (NumTPLists == 0) - ? getFriendLoc() - : getTPLists()[0]->getTemplateLoc(); + SourceLocation StartL = + (NumTPLists == 0) ? getFriendLoc() + : getTrailingObjects<TemplateParameterList *>()[0] + ->getTemplateLoc(); return SourceRange(StartL, TInfo->getTypeLoc().getEndLoc()); } else @@ -171,6 +166,7 @@ public: friend class ASTDeclReader; friend class ASTDeclWriter; + friend TrailingObjects; }; /// An iterator over the friend declarations of a class. diff --git a/contrib/llvm/tools/clang/include/clang/AST/DeclGroup.h b/contrib/llvm/tools/clang/include/clang/AST/DeclGroup.h index bd3dbd8..c84bb5e 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/DeclGroup.h +++ b/contrib/llvm/tools/clang/include/clang/AST/DeclGroup.h @@ -15,6 +15,7 @@ #define LLVM_CLANG_AST_DECLGROUP_H #include "llvm/Support/DataTypes.h" +#include "llvm/Support/TrailingObjects.h" #include <cassert> namespace clang { @@ -24,13 +25,9 @@ class Decl; class DeclGroup; class DeclGroupIterator; -class DeclGroup { +class DeclGroup final : private llvm::TrailingObjects<DeclGroup, Decl *> { // FIXME: Include a TypeSpecifier object. - union { - unsigned NumDecls; - - Decl *Aligner; - }; + unsigned NumDecls; private: DeclGroup() : NumDecls(0) {} @@ -43,13 +40,15 @@ public: Decl*& operator[](unsigned i) { assert (i < NumDecls && "Out-of-bounds access."); - return ((Decl**) (this+1))[i]; + return getTrailingObjects<Decl *>()[i]; } Decl* const& operator[](unsigned i) const { assert (i < NumDecls && "Out-of-bounds access."); - return ((Decl* const*) (this+1))[i]; + return getTrailingObjects<Decl *>()[i]; } + + friend TrailingObjects; }; class DeclGroupRef { diff --git a/contrib/llvm/tools/clang/include/clang/AST/DeclObjC.h b/contrib/llvm/tools/clang/include/clang/AST/DeclObjC.h index c42764b..f46078f 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/DeclObjC.h +++ b/contrib/llvm/tools/clang/include/clang/AST/DeclObjC.h @@ -612,7 +612,8 @@ public: /// @interface NSArray<T> // stores the <T> /// @end /// \endcode -class ObjCTypeParamList { +class ObjCTypeParamList final + : private llvm::TrailingObjects<ObjCTypeParamList, ObjCTypeParamDecl *> { /// Stores the components of a SourceRange as a POD. struct PODSourceRange { unsigned Begin; @@ -644,7 +645,7 @@ public: /// Iterate through the type parameters in the list. typedef ObjCTypeParamDecl **iterator; - iterator begin() { return reinterpret_cast<ObjCTypeParamDecl **>(this + 1); } + iterator begin() { return getTrailingObjects<ObjCTypeParamDecl *>(); } iterator end() { return begin() + size(); } @@ -655,7 +656,7 @@ public: typedef ObjCTypeParamDecl * const *const_iterator; const_iterator begin() const { - return reinterpret_cast<ObjCTypeParamDecl * const *>(this + 1); + return getTrailingObjects<ObjCTypeParamDecl *>(); } const_iterator end() const { @@ -685,6 +686,7 @@ public: /// Gather the default set of type arguments to be substituted for /// these type parameters when dealing with an unspecialized type. void gatherDefaultTypeArgs(SmallVectorImpl<QualType> &typeArgs) const; + friend TrailingObjects; }; /// ObjCContainerDecl - Represents a container for method declarations. @@ -1202,13 +1204,8 @@ public: // might bring in a definition. // Note: a null value indicates that we don't have a definition and that // modules are enabled. - if (!Data.getOpaqueValue()) { - if (IdentifierInfo *II = getIdentifier()) { - if (II->isOutOfDate()) { - updateOutOfDate(*II); - } - } - } + if (!Data.getOpaqueValue()) + getMostRecentDecl(); return Data.getPointer(); } @@ -1851,13 +1848,8 @@ public: // might bring in a definition. // Note: a null value indicates that we don't have a definition and that // modules are enabled. - if (!Data.getOpaqueValue()) { - if (IdentifierInfo *II = getIdentifier()) { - if (II->isOutOfDate()) { - updateOutOfDate(*II); - } - } - } + if (!Data.getOpaqueValue()) + getMostRecentDecl(); return Data.getPointer(); } @@ -2519,26 +2511,18 @@ public: void setPropertyAttributes(PropertyAttributeKind PRVal) { PropertyAttributes |= PRVal; } + void overwritePropertyAttributes(unsigned PRVal) { + PropertyAttributes = PRVal; + } PropertyAttributeKind getPropertyAttributesAsWritten() const { return PropertyAttributeKind(PropertyAttributesAsWritten); } - bool hasWrittenStorageAttribute() const { - return PropertyAttributesAsWritten & (OBJC_PR_assign | OBJC_PR_copy | - OBJC_PR_unsafe_unretained | OBJC_PR_retain | OBJC_PR_strong | - OBJC_PR_weak); - } - void setPropertyAttributesAsWritten(PropertyAttributeKind PRVal) { PropertyAttributesAsWritten = PRVal; } - void makeitReadWriteAttribute() { - PropertyAttributes &= ~OBJC_PR_readonly; - PropertyAttributes |= OBJC_PR_readwrite; - } - // Helper methods for accessing attributes. /// isReadOnly - Return true iff the property has a setter. diff --git a/contrib/llvm/tools/clang/include/clang/AST/DeclOpenMP.h b/contrib/llvm/tools/clang/include/clang/AST/DeclOpenMP.h index 7f0616f..598f418 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/DeclOpenMP.h +++ b/contrib/llvm/tools/clang/include/clang/AST/DeclOpenMP.h @@ -33,8 +33,12 @@ class Expr; /// }; /// \endcode /// -class OMPThreadPrivateDecl : public Decl { +class OMPThreadPrivateDecl final + : public Decl, + private llvm::TrailingObjects<OMPThreadPrivateDecl, Expr *> { friend class ASTDeclReader; + friend TrailingObjects; + unsigned NumVars; virtual void anchor(); @@ -43,14 +47,11 @@ class OMPThreadPrivateDecl : public Decl { Decl(DK, DC, L), NumVars(0) { } ArrayRef<const Expr *> getVars() const { - return llvm::makeArrayRef(reinterpret_cast<const Expr * const *>(this + 1), - NumVars); + return llvm::makeArrayRef(getTrailingObjects<Expr *>(), NumVars); } MutableArrayRef<Expr *> getVars() { - return MutableArrayRef<Expr *>( - reinterpret_cast<Expr **>(this + 1), - NumVars); + return MutableArrayRef<Expr *>(getTrailingObjects<Expr *>(), NumVars); } void setVars(ArrayRef<Expr *> VL); diff --git a/contrib/llvm/tools/clang/include/clang/AST/DeclTemplate.h b/contrib/llvm/tools/clang/include/clang/AST/DeclTemplate.h index 0fc9b49..a9109ef 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/DeclTemplate.h +++ b/contrib/llvm/tools/clang/include/clang/AST/DeclTemplate.h @@ -20,10 +20,12 @@ #include "clang/AST/TemplateBase.h" #include "llvm/ADT/PointerUnion.h" #include "llvm/Support/Compiler.h" +#include "llvm/Support/TrailingObjects.h" #include <limits> namespace clang { +enum BuiltinTemplateKind : int; class TemplateParameterList; class TemplateDecl; class RedeclarableTemplateDecl; @@ -43,7 +45,9 @@ typedef llvm::PointerUnion3<TemplateTypeParmDecl*, NonTypeTemplateParmDecl*, /// \brief Stores a list of template parameters for a TemplateDecl and its /// derived classes. -class TemplateParameterList { +class TemplateParameterList final + : private llvm::TrailingObjects<TemplateParameterList, NamedDecl *> { + /// The location of the 'template' keyword. SourceLocation TemplateLoc; @@ -59,16 +63,18 @@ class TemplateParameterList { unsigned ContainsUnexpandedParameterPack : 1; protected: + size_t numTrailingObjects(OverloadToken<NamedDecl *>) const { + return NumParams; + } + TemplateParameterList(SourceLocation TemplateLoc, SourceLocation LAngleLoc, - NamedDecl **Params, unsigned NumParams, - SourceLocation RAngleLoc); + ArrayRef<NamedDecl *> Params, SourceLocation RAngleLoc); public: static TemplateParameterList *Create(const ASTContext &C, SourceLocation TemplateLoc, SourceLocation LAngleLoc, - NamedDecl **Params, - unsigned NumParams, + ArrayRef<NamedDecl *> Params, SourceLocation RAngleLoc); /// \brief Iterates through the template parameters in this list. @@ -77,10 +83,8 @@ public: /// \brief Iterates through the template parameters in this list. typedef NamedDecl* const* const_iterator; - iterator begin() { return reinterpret_cast<NamedDecl **>(this + 1); } - const_iterator begin() const { - return reinterpret_cast<NamedDecl * const *>(this + 1); - } + iterator begin() { return getTrailingObjects<NamedDecl *>(); } + const_iterator begin() const { return getTrailingObjects<NamedDecl *>(); } iterator end() { return begin() + NumParams; } const_iterator end() const { return begin() + NumParams; } @@ -130,29 +134,45 @@ public: SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(TemplateLoc, RAngleLoc); } + + friend TrailingObjects; + template <size_t N> friend class FixedSizeTemplateParameterListStorage; }; /// \brief Stores a list of template parameters for a TemplateDecl and its /// derived classes. Suitable for creating on the stack. -template<size_t N> -class FixedSizeTemplateParameterList : public TemplateParameterList { +template <size_t N> class FixedSizeTemplateParameterListStorage { + // This is kinda ugly: TemplateParameterList usually gets allocated + // in a block of memory with NamedDecls appended to it. Here, to get + // it stack allocated, we include the params as a separate + // variable. After allocation, the TemplateParameterList object + // treats them as part of itself. + TemplateParameterList List; NamedDecl *Params[N]; public: - FixedSizeTemplateParameterList(SourceLocation TemplateLoc, - SourceLocation LAngleLoc, - NamedDecl **Params, SourceLocation RAngleLoc) : - TemplateParameterList(TemplateLoc, LAngleLoc, Params, N, RAngleLoc) { - } + FixedSizeTemplateParameterListStorage(SourceLocation TemplateLoc, + SourceLocation LAngleLoc, + ArrayRef<NamedDecl *> Params, + SourceLocation RAngleLoc) + : List(TemplateLoc, LAngleLoc, Params, RAngleLoc) { + // Because we're doing an evil layout hack above, have some + // asserts, just to double-check everything is laid out like + // expected. + assert(sizeof(*this) == + TemplateParameterList::totalSizeToAlloc<NamedDecl *>(N) && + "Object layout not as expected"); + assert(this->Params == List.getTrailingObjects<NamedDecl *>() && + "Object layout not as expected"); + } + TemplateParameterList *get() { return &List; } }; /// \brief A template argument list. -class TemplateArgumentList { +class TemplateArgumentList final + : private llvm::TrailingObjects<TemplateArgumentList, TemplateArgument> { /// \brief The template argument list. - /// - /// The integer value will be non-zero to indicate that this - /// template argument list does own the pointer. - llvm::PointerIntPair<const TemplateArgument *, 1> Arguments; + const TemplateArgument *Arguments; /// \brief The number of template arguments in this template /// argument list. @@ -161,9 +181,9 @@ class TemplateArgumentList { TemplateArgumentList(const TemplateArgumentList &Other) = delete; void operator=(const TemplateArgumentList &Other) = delete; - TemplateArgumentList(const TemplateArgument *Args, unsigned NumArgs, - bool Owned) - : Arguments(Args, Owned), NumArguments(NumArgs) { } + // Constructs an instance with an internal Argument list, containing + // a copy of the Args array. (Called by CreateCopy) + TemplateArgumentList(const TemplateArgument *Args, unsigned NumArgs); public: /// \brief Type used to indicate that the template argument list itself is a @@ -180,9 +200,9 @@ public: /// /// The template argument list does not own the template arguments /// provided. - explicit TemplateArgumentList(OnStackType, - const TemplateArgument *Args, unsigned NumArgs) - : Arguments(Args, false), NumArguments(NumArgs) { } + explicit TemplateArgumentList(OnStackType, const TemplateArgument *Args, + unsigned NumArgs) + : Arguments(Args), NumArguments(NumArgs) {} /// \brief Produces a shallow copy of the given template argument list. /// @@ -191,7 +211,7 @@ public: /// constructor, since this really really isn't safe to use that /// way. explicit TemplateArgumentList(const TemplateArgumentList *Other) - : Arguments(Other->data(), false), NumArguments(Other->size()) { } + : Arguments(Other->data()), NumArguments(Other->size()) {} /// \brief Retrieve the template argument at a given index. const TemplateArgument &get(unsigned Idx) const { @@ -212,9 +232,9 @@ public: unsigned size() const { return NumArguments; } /// \brief Retrieve a pointer to the template argument list. - const TemplateArgument *data() const { - return Arguments.getPointer(); - } + const TemplateArgument *data() const { return Arguments; } + + friend TrailingObjects; }; void *allocateDefaultArgStorageChain(const ASTContext &C); @@ -426,17 +446,8 @@ public: /// explicit instantiation declaration, or explicit instantiation /// definition. bool isExplicitInstantiationOrSpecialization() const { - switch (getTemplateSpecializationKind()) { - case TSK_ExplicitSpecialization: - case TSK_ExplicitInstantiationDeclaration: - case TSK_ExplicitInstantiationDefinition: - return true; - - case TSK_Undeclared: - case TSK_ImplicitInstantiation: - return false; - } - llvm_unreachable("bad template specialization kind"); + return isTemplateExplicitInstantiationOrSpecialization( + getTemplateSpecializationKind()); } /// \brief Set the template specialization kind. @@ -542,56 +553,52 @@ public: /// friend void foo<>(T); /// }; /// \endcode -class DependentFunctionTemplateSpecializationInfo { - struct CA { - /// The number of potential template candidates. - unsigned NumTemplates; +class DependentFunctionTemplateSpecializationInfo final + : private llvm::TrailingObjects<DependentFunctionTemplateSpecializationInfo, + TemplateArgumentLoc, + FunctionTemplateDecl *> { + /// The number of potential template candidates. + unsigned NumTemplates; - /// The number of template arguments. - unsigned NumArgs; - }; - - union { - // Force sizeof to be a multiple of sizeof(void*) so that the - // trailing data is aligned. - void *Aligner; - struct CA d; - }; + /// The number of template arguments. + unsigned NumArgs; /// The locations of the left and right angle brackets. SourceRange AngleLocs; - FunctionTemplateDecl * const *getTemplates() const { - return reinterpret_cast<FunctionTemplateDecl*const*>(this+1); + size_t numTrailingObjects(OverloadToken<TemplateArgumentLoc>) const { + return NumArgs; + } + size_t numTrailingObjects(OverloadToken<FunctionTemplateDecl *>) const { + return NumTemplates; } -public: DependentFunctionTemplateSpecializationInfo( const UnresolvedSetImpl &Templates, const TemplateArgumentListInfo &TemplateArgs); +public: + static DependentFunctionTemplateSpecializationInfo * + Create(ASTContext &Context, const UnresolvedSetImpl &Templates, + const TemplateArgumentListInfo &TemplateArgs); + /// \brief Returns the number of function templates that this might /// be a specialization of. - unsigned getNumTemplates() const { - return d.NumTemplates; - } + unsigned getNumTemplates() const { return NumTemplates; } /// \brief Returns the i'th template candidate. FunctionTemplateDecl *getTemplate(unsigned I) const { assert(I < getNumTemplates() && "template index out of range"); - return getTemplates()[I]; + return getTrailingObjects<FunctionTemplateDecl *>()[I]; } /// \brief Returns the explicit template arguments that were given. const TemplateArgumentLoc *getTemplateArgs() const { - return reinterpret_cast<const TemplateArgumentLoc*>( - &getTemplates()[getNumTemplates()]); + return getTrailingObjects<TemplateArgumentLoc>(); } /// \brief Returns the number of explicit template arguments that were given. - unsigned getNumTemplateArgs() const { - return d.NumArgs; - } + unsigned getNumTemplateArgs() const { return NumArgs; } /// \brief Returns the nth template argument. const TemplateArgumentLoc &getTemplateArg(unsigned I) const { @@ -606,6 +613,8 @@ public: SourceLocation getRAngleLoc() const { return AngleLocs.getEnd(); } + + friend TrailingObjects; }; /// Declaration of a redeclarable template. @@ -926,7 +935,7 @@ public: return const_cast<FunctionTemplateDecl*>(this)->getMostRecentDecl(); } - FunctionTemplateDecl *getInstantiatedFromMemberTemplate() { + FunctionTemplateDecl *getInstantiatedFromMemberTemplate() const { return cast_or_null<FunctionTemplateDecl>( RedeclarableTemplateDecl::getInstantiatedFromMemberTemplate()); } @@ -1120,8 +1129,11 @@ public: /// @code /// template<int Size> class array { }; /// @endcode -class NonTypeTemplateParmDecl - : public DeclaratorDecl, protected TemplateParmPosition { +class NonTypeTemplateParmDecl final + : public DeclaratorDecl, + protected TemplateParmPosition, + private llvm::TrailingObjects<NonTypeTemplateParmDecl, + std::pair<QualType, TypeSourceInfo *>> { /// \brief The default template argument, if any, and whether or not /// it was inherited. typedef DefaultArgStorage<NonTypeTemplateParmDecl, Expr*> DefArgStorage; @@ -1141,6 +1153,11 @@ class NonTypeTemplateParmDecl /// \brief The number of types in an expanded parameter pack. unsigned NumExpandedTypes; + size_t numTrailingObjects( + OverloadToken<std::pair<QualType, TypeSourceInfo *>>) const { + return NumExpandedTypes; + } + NonTypeTemplateParmDecl(DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, unsigned D, unsigned P, IdentifierInfo *Id, QualType T, @@ -1159,6 +1176,7 @@ class NonTypeTemplateParmDecl TypeSourceInfo **ExpandedTInfos); friend class ASTDeclReader; + friend TrailingObjects; public: static NonTypeTemplateParmDecl * @@ -1274,16 +1292,18 @@ public: /// pack. QualType getExpansionType(unsigned I) const { assert(I < NumExpandedTypes && "Out-of-range expansion type index"); - void * const *TypesAndInfos = reinterpret_cast<void * const*>(this + 1); - return QualType::getFromOpaquePtr(TypesAndInfos[2*I]); + auto TypesAndInfos = + getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>(); + return TypesAndInfos[I].first; } /// \brief Retrieve a particular expansion type source info within an /// expanded parameter pack. TypeSourceInfo *getExpansionTypeSourceInfo(unsigned I) const { assert(I < NumExpandedTypes && "Out-of-range expansion type index"); - void * const *TypesAndInfos = reinterpret_cast<void * const*>(this + 1); - return static_cast<TypeSourceInfo *>(TypesAndInfos[2*I+1]); + auto TypesAndInfos = + getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>(); + return TypesAndInfos[I].second; } // Implement isa/cast/dyncast/etc. @@ -1298,9 +1318,11 @@ public: /// @endcode /// A template template parameter is a TemplateDecl because it defines the /// name of a template and the template parameters allowable for substitution. -class TemplateTemplateParmDecl : public TemplateDecl, - protected TemplateParmPosition -{ +class TemplateTemplateParmDecl final + : public TemplateDecl, + protected TemplateParmPosition, + private llvm::TrailingObjects<TemplateTemplateParmDecl, + TemplateParameterList *> { void anchor() override; /// \brief The default template argument, if any. @@ -1404,7 +1426,7 @@ public: /// pack. TemplateParameterList *getExpansionTemplateParameters(unsigned I) const { assert(I < NumExpandedParams && "Out-of-range expansion type index"); - return reinterpret_cast<TemplateParameterList *const *>(this + 1)[I]; + return getTrailingObjects<TemplateParameterList *>()[I]; } const DefArgStorage &getDefaultArgStorage() const { return DefaultArgument; } @@ -1454,6 +1476,36 @@ public: friend class ASTDeclReader; friend class ASTDeclWriter; + friend TrailingObjects; +}; + +/// \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. +class BuiltinTemplateDecl : public TemplateDecl { + void anchor() override; + + BuiltinTemplateDecl(const ASTContext &C, DeclContext *DC, + DeclarationName Name, BuiltinTemplateKind BTK); + + BuiltinTemplateKind BTK; + +public: + // Implement isa/cast/dyncast support + static bool classof(const Decl *D) { return classofKind(D->getKind()); } + static bool classofKind(Kind K) { return K == BuiltinTemplate; } + + static BuiltinTemplateDecl *Create(const ASTContext &C, DeclContext *DC, + DeclarationName Name, + BuiltinTemplateKind BTK) { + return new (C, DC) BuiltinTemplateDecl(C, DC, Name, BTK); + } + + SourceRange getSourceRange() const override LLVM_READONLY { + return SourceRange(); + } + + BuiltinTemplateKind getBuiltinTemplateKind() const { return BTK; } }; /// \brief Represents a class template specialization, which refers to @@ -1580,17 +1632,8 @@ public: /// explicit instantiation declaration, or explicit instantiation /// definition. bool isExplicitInstantiationOrSpecialization() const { - switch (getTemplateSpecializationKind()) { - case TSK_ExplicitSpecialization: - case TSK_ExplicitInstantiationDeclaration: - case TSK_ExplicitInstantiationDefinition: - return true; - - case TSK_Undeclared: - case TSK_ImplicitInstantiation: - return false; - } - llvm_unreachable("bad template specialization kind"); + return isTemplateExplicitInstantiationOrSpecialization( + getTemplateSpecializationKind()); } void setSpecializationKind(TemplateSpecializationKind TSK) { @@ -1819,8 +1862,8 @@ public: /// template partial specialization \c Outer<T>::Inner<U*>. Given /// \c Outer<float>::Inner<U*>, this function would return /// \c Outer<T>::Inner<U*>. - ClassTemplatePartialSpecializationDecl *getInstantiatedFromMember() { - ClassTemplatePartialSpecializationDecl *First = + ClassTemplatePartialSpecializationDecl *getInstantiatedFromMember() const { + const ClassTemplatePartialSpecializationDecl *First = cast<ClassTemplatePartialSpecializationDecl>(getFirstDecl()); return First->InstantiatedFromMember.getPointer(); } @@ -2000,7 +2043,7 @@ public: return const_cast<ClassTemplateDecl*>(this)->getMostRecentDecl(); } - ClassTemplateDecl *getInstantiatedFromMemberTemplate() { + ClassTemplateDecl *getInstantiatedFromMemberTemplate() const { return cast_or_null<ClassTemplateDecl>( RedeclarableTemplateDecl::getInstantiatedFromMemberTemplate()); } @@ -2230,7 +2273,7 @@ public: this)->getPreviousDecl()); } - TypeAliasTemplateDecl *getInstantiatedFromMemberTemplate() { + TypeAliasTemplateDecl *getInstantiatedFromMemberTemplate() const { return cast_or_null<TypeAliasTemplateDecl>( RedeclarableTemplateDecl::getInstantiatedFromMemberTemplate()); } @@ -2435,17 +2478,8 @@ public: /// explicit instantiation declaration, or explicit instantiation /// definition. bool isExplicitInstantiationOrSpecialization() const { - switch (getTemplateSpecializationKind()) { - case TSK_ExplicitSpecialization: - case TSK_ExplicitInstantiationDeclaration: - case TSK_ExplicitInstantiationDefinition: - return true; - - case TSK_Undeclared: - case TSK_ImplicitInstantiation: - return false; - } - llvm_unreachable("bad template specialization kind"); + return isTemplateExplicitInstantiationOrSpecialization( + getTemplateSpecializationKind()); } void setSpecializationKind(TemplateSpecializationKind TSK) { @@ -2668,8 +2702,8 @@ public: /// variable template partial specialization \c Outer<T>::Inner<U*>. Given /// \c Outer<float>::Inner<U*>, this function would return /// \c Outer<T>::Inner<U*>. - VarTemplatePartialSpecializationDecl *getInstantiatedFromMember() { - VarTemplatePartialSpecializationDecl *First = + VarTemplatePartialSpecializationDecl *getInstantiatedFromMember() const { + const VarTemplatePartialSpecializationDecl *First = cast<VarTemplatePartialSpecializationDecl>(getFirstDecl()); return First->InstantiatedFromMember.getPointer(); } @@ -2833,7 +2867,7 @@ public: return const_cast<VarTemplateDecl *>(this)->getMostRecentDecl(); } - VarTemplateDecl *getInstantiatedFromMemberTemplate() { + VarTemplateDecl *getInstantiatedFromMemberTemplate() const { return cast_or_null<VarTemplateDecl>( RedeclarableTemplateDecl::getInstantiatedFromMemberTemplate()); } diff --git a/contrib/llvm/tools/clang/include/clang/AST/EvaluatedExprVisitor.h b/contrib/llvm/tools/clang/include/clang/AST/EvaluatedExprVisitor.h index ad52873..aad7726 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/EvaluatedExprVisitor.h +++ b/contrib/llvm/tools/clang/include/clang/AST/EvaluatedExprVisitor.h @@ -88,8 +88,8 @@ public: void VisitLambdaExpr(PTR(LambdaExpr) LE) { // Only visit the capture initializers, and not the body. - for (LambdaExpr::capture_init_iterator I = LE->capture_init_begin(), - E = LE->capture_init_end(); + for (LambdaExpr::const_capture_init_iterator I = LE->capture_init_begin(), + E = LE->capture_init_end(); I != E; ++I) if (*I) this->Visit(*I); diff --git a/contrib/llvm/tools/clang/include/clang/AST/Expr.h b/contrib/llvm/tools/clang/include/clang/AST/Expr.h index 2a5b4c0..f9f1995 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/Expr.h +++ b/contrib/llvm/tools/clang/include/clang/AST/Expr.h @@ -23,6 +23,7 @@ #include "clang/AST/TemplateBase.h" #include "clang/AST/Type.h" #include "clang/Basic/CharInfo.h" +#include "clang/Basic/LangOptions.h" #include "clang/Basic/TypeTraits.h" #include "llvm/ADT/APFloat.h" #include "llvm/ADT/APSInt.h" @@ -61,7 +62,6 @@ struct SubobjectAdjustment { MemberPointerAdjustment } Kind; - struct DTB { const CastExpr *BasePath; const CXXRecordDecl *DerivedClass; @@ -148,8 +148,6 @@ public: /// \brief Set whether this expression is value-dependent or not. void setValueDependent(bool VD) { ExprBits.ValueDependent = VD; - if (VD) - ExprBits.InstantiationDependent = true; } /// isTypeDependent - Determines whether this expression is @@ -168,8 +166,6 @@ public: /// \brief Set whether this expression is type-dependent or not. void setTypeDependent(bool TD) { ExprBits.TypeDependent = TD; - if (TD) - ExprBits.InstantiationDependent = true; } /// \brief Whether this expression is instantiation-dependent, meaning that @@ -458,6 +454,10 @@ public: /// \brief Returns whether this expression refers to a vector element. bool refersToVectorElement() const; + /// \brief Returns whether this expression refers to a global register + /// variable. + bool refersToGlobalRegisterVar() const; + /// \brief Returns whether this expression has a placeholder type. bool hasPlaceholderType() const { return getType()->isPlaceholderType(); @@ -529,10 +529,15 @@ public: /// EvalStatus is a struct with detailed info about an evaluation in progress. struct EvalStatus { - /// HasSideEffects - Whether the evaluated expression has side effects. + /// \brief Whether the evaluated expression has side effects. /// For example, (f() && 0) can be folded, but it still has side effects. bool HasSideEffects; + /// \brief Whether the evaluation hit undefined behavior. + /// For example, 1.0 / 0.0 can be folded to Inf, but has undefined behavior. + /// Likewise, INT_MAX + 1 can be folded to INT_MIN, but has UB. + bool HasUndefinedBehavior; + /// Diag - If this is non-null, it will be filled in with a stack of notes /// indicating why evaluation failed (or why it failed to produce a constant /// expression). @@ -542,7 +547,8 @@ public: /// expression *is* a constant expression, no notes will be produced. SmallVectorImpl<PartialDiagnosticAt> *Diag; - EvalStatus() : HasSideEffects(false), Diag(nullptr) {} + EvalStatus() + : HasSideEffects(false), HasUndefinedBehavior(false), Diag(nullptr) {} // hasSideEffects - Return true if the evaluated expression has // side effects. @@ -575,7 +581,12 @@ public: /// side-effects. bool EvaluateAsBooleanCondition(bool &Result, const ASTContext &Ctx) const; - enum SideEffectsKind { SE_NoSideEffects, SE_AllowSideEffects }; + enum SideEffectsKind { + SE_NoSideEffects, ///< Strictly evaluate the expression. + SE_AllowUndefinedBehavior, ///< Allow UB that we can give a value, but not + ///< arbitrary unmodeled side effects. + SE_AllowSideEffects ///< Allow any unmodeled side effect. + }; /// EvaluateAsInt - Return true if this is a constant which we can fold and /// convert to an integer, using any crazy technique that we want to. @@ -584,7 +595,8 @@ public: /// isEvaluatable - Call EvaluateAsRValue to see if this expression can be /// constant folded without side-effects, but discard the result. - bool isEvaluatable(const ASTContext &Ctx) const; + bool isEvaluatable(const ASTContext &Ctx, + SideEffectsKind AllowSideEffects = SE_NoSideEffects) const; /// HasSideEffects - This routine returns true for all those expressions /// which have any effect other than producing a value. Example is a function @@ -628,6 +640,16 @@ public: const FunctionDecl *Callee, ArrayRef<const Expr*> Args) const; + /// \brief If the current Expr is a pointer, this will try to statically + /// determine the number of bytes available where the pointer is pointing. + /// Returns true if all of the above holds and we were able to figure out the + /// size, false otherwise. + /// + /// \param Type - How to evaluate the size of the Expr, as defined by the + /// "type" parameter of __builtin_object_size + bool tryEvaluateObjectSize(uint64_t &Result, ASTContext &Ctx, + unsigned Type) const; + /// \brief Enumeration used to describe the kind of Null pointer constant /// returned from \c isNullPointerConstant(). enum NullPointerConstantKind { @@ -806,7 +828,6 @@ public: } }; - //===----------------------------------------------------------------------===// // Primary Expressions. //===----------------------------------------------------------------------===// @@ -856,7 +877,9 @@ public: return Loc; } - child_range children() { return child_range(); } + child_range children() { + return child_range(child_iterator(), child_iterator()); + } /// The source expression of an opaque value expression is the /// expression which originally generated the value. This is @@ -896,7 +919,11 @@ public: /// DeclRefExprBits.RefersToEnclosingVariableOrCapture /// Specifies when this declaration reference expression (validly) /// refers to an enclosed local or a captured variable. -class DeclRefExpr : public Expr { +class DeclRefExpr final + : public Expr, + private llvm::TrailingObjects<DeclRefExpr, NestedNameSpecifierLoc, + NamedDecl *, ASTTemplateKWAndArgsInfo, + TemplateArgumentLoc> { /// \brief The declaration that we are referencing. ValueDecl *D; @@ -907,36 +934,22 @@ class DeclRefExpr : public Expr { /// embedded in D. DeclarationNameLoc DNLoc; - /// \brief Helper to retrieve the optional NestedNameSpecifierLoc. - NestedNameSpecifierLoc &getInternalQualifierLoc() { - assert(hasQualifier()); - return *reinterpret_cast<NestedNameSpecifierLoc *>(this + 1); + size_t numTrailingObjects(OverloadToken<NestedNameSpecifierLoc>) const { + return hasQualifier() ? 1 : 0; + } + + size_t numTrailingObjects(OverloadToken<NamedDecl *>) const { + return hasFoundDecl() ? 1 : 0; } - /// \brief Helper to retrieve the optional NestedNameSpecifierLoc. - const NestedNameSpecifierLoc &getInternalQualifierLoc() const { - return const_cast<DeclRefExpr *>(this)->getInternalQualifierLoc(); + size_t numTrailingObjects(OverloadToken<ASTTemplateKWAndArgsInfo>) const { + return hasTemplateKWAndArgsInfo() ? 1 : 0; } /// \brief Test whether there is a distinct FoundDecl attached to the end of /// this DRE. bool hasFoundDecl() const { return DeclRefExprBits.HasFoundDecl; } - /// \brief Helper to retrieve the optional NamedDecl through which this - /// reference occurred. - NamedDecl *&getInternalFoundDecl() { - assert(hasFoundDecl()); - if (hasQualifier()) - return *reinterpret_cast<NamedDecl **>(&getInternalQualifierLoc() + 1); - return *reinterpret_cast<NamedDecl **>(this + 1); - } - - /// \brief Helper to retrieve the optional NamedDecl through which this - /// reference occurred. - NamedDecl *getInternalFoundDecl() const { - return const_cast<DeclRefExpr *>(this)->getInternalFoundDecl(); - } - DeclRefExpr(const ASTContext &Ctx, NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, @@ -1009,21 +1022,17 @@ public: bool hasQualifier() const { return DeclRefExprBits.HasQualifier; } /// \brief If the name was qualified, retrieves the nested-name-specifier - /// that precedes the name. Otherwise, returns NULL. - NestedNameSpecifier *getQualifier() const { - if (!hasQualifier()) - return nullptr; - - return getInternalQualifierLoc().getNestedNameSpecifier(); - } - - /// \brief If the name was qualified, retrieves the nested-name-specifier /// that precedes the name, with source-location information. NestedNameSpecifierLoc getQualifierLoc() const { if (!hasQualifier()) return NestedNameSpecifierLoc(); + return *getTrailingObjects<NestedNameSpecifierLoc>(); + } - return getInternalQualifierLoc(); + /// \brief If the name was qualified, retrieves the nested-name-specifier + /// that precedes the name. Otherwise, returns NULL. + NestedNameSpecifier *getQualifier() const { + return getQualifierLoc().getNestedNameSpecifier(); } /// \brief Get the NamedDecl through which this reference occurred. @@ -1031,60 +1040,40 @@ public: /// This Decl may be different from the ValueDecl actually referred to in the /// presence of using declarations, etc. It always returns non-NULL, and may /// simple return the ValueDecl when appropriate. + NamedDecl *getFoundDecl() { - return hasFoundDecl() ? getInternalFoundDecl() : D; + return hasFoundDecl() ? *getTrailingObjects<NamedDecl *>() : D; } /// \brief Get the NamedDecl through which this reference occurred. /// See non-const variant. const NamedDecl *getFoundDecl() const { - return hasFoundDecl() ? getInternalFoundDecl() : D; + return hasFoundDecl() ? *getTrailingObjects<NamedDecl *>() : D; } bool hasTemplateKWAndArgsInfo() const { return DeclRefExprBits.HasTemplateKWAndArgsInfo; } - /// \brief Return the optional template keyword and arguments info. - ASTTemplateKWAndArgsInfo *getTemplateKWAndArgsInfo() { - if (!hasTemplateKWAndArgsInfo()) - return nullptr; - - if (hasFoundDecl()) - return reinterpret_cast<ASTTemplateKWAndArgsInfo *>( - &getInternalFoundDecl() + 1); - - if (hasQualifier()) - return reinterpret_cast<ASTTemplateKWAndArgsInfo *>( - &getInternalQualifierLoc() + 1); - - return reinterpret_cast<ASTTemplateKWAndArgsInfo *>(this + 1); - } - - /// \brief Return the optional template keyword and arguments info. - const ASTTemplateKWAndArgsInfo *getTemplateKWAndArgsInfo() const { - return const_cast<DeclRefExpr*>(this)->getTemplateKWAndArgsInfo(); - } - /// \brief Retrieve the location of the template keyword preceding /// this name, if any. SourceLocation getTemplateKeywordLoc() const { if (!hasTemplateKWAndArgsInfo()) return SourceLocation(); - return getTemplateKWAndArgsInfo()->getTemplateKeywordLoc(); + return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->TemplateKWLoc; } /// \brief Retrieve the location of the left angle bracket starting the /// explicit template argument list following the name, if any. SourceLocation getLAngleLoc() const { if (!hasTemplateKWAndArgsInfo()) return SourceLocation(); - return getTemplateKWAndArgsInfo()->LAngleLoc; + return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->LAngleLoc; } /// \brief Retrieve the location of the right angle bracket ending the /// explicit template argument list following the name, if any. SourceLocation getRAngleLoc() const { if (!hasTemplateKWAndArgsInfo()) return SourceLocation(); - return getTemplateKWAndArgsInfo()->RAngleLoc; + return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->RAngleLoc; } /// \brief Determines whether the name in this declaration reference @@ -1095,32 +1084,12 @@ public: /// explicit template argument list. bool hasExplicitTemplateArgs() const { return getLAngleLoc().isValid(); } - /// \brief Retrieve the explicit template argument list that followed the - /// member template name. - ASTTemplateArgumentListInfo &getExplicitTemplateArgs() { - assert(hasExplicitTemplateArgs()); - return *getTemplateKWAndArgsInfo(); - } - - /// \brief Retrieve the explicit template argument list that followed the - /// member template name. - const ASTTemplateArgumentListInfo &getExplicitTemplateArgs() const { - return const_cast<DeclRefExpr *>(this)->getExplicitTemplateArgs(); - } - - /// \brief Retrieves the optional explicit template arguments. - /// This points to the same data as getExplicitTemplateArgs(), but - /// returns null if there are no explicit template arguments. - const ASTTemplateArgumentListInfo *getOptionalExplicitTemplateArgs() const { - if (!hasExplicitTemplateArgs()) return nullptr; - return &getExplicitTemplateArgs(); - } - /// \brief Copies the template arguments (if present) into the given /// structure. void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const { if (hasExplicitTemplateArgs()) - getExplicitTemplateArgs().copyInto(List); + getTrailingObjects<ASTTemplateKWAndArgsInfo>()->copyInto( + getTrailingObjects<TemplateArgumentLoc>(), List); } /// \brief Retrieve the template arguments provided as part of this @@ -1129,7 +1098,7 @@ public: if (!hasExplicitTemplateArgs()) return nullptr; - return getExplicitTemplateArgs().getTemplateArgs(); + return getTrailingObjects<TemplateArgumentLoc>(); } /// \brief Retrieve the number of template arguments provided as part of this @@ -1138,7 +1107,7 @@ public: if (!hasExplicitTemplateArgs()) return 0; - return getExplicitTemplateArgs().NumTemplateArgs; + return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->NumTemplateArgs; } /// \brief Returns true if this expression refers to a function that @@ -1164,8 +1133,11 @@ public: } // Iterators - child_range children() { return child_range(); } + child_range children() { + return child_range(child_iterator(), child_iterator()); + } + friend TrailingObjects; friend class ASTStmtReader; friend class ASTStmtWriter; }; @@ -1310,7 +1282,9 @@ public: } // Iterators - child_range children() { return child_range(); } + child_range children() { + return child_range(child_iterator(), child_iterator()); + } }; class CharacterLiteral : public Expr { @@ -1357,7 +1331,9 @@ public: } // Iterators - child_range children() { return child_range(); } + child_range children() { + return child_range(child_iterator(), child_iterator()); + } }; class FloatingLiteral : public Expr, private APFloatStorage { @@ -1419,7 +1395,9 @@ public: } // Iterators - child_range children() { return child_range(); } + child_range children() { + return child_range(child_iterator(), child_iterator()); + } }; /// ImaginaryLiteral - We support imaginary integer and floating point literals, @@ -1596,13 +1574,15 @@ public: /// and can have escape sequences in them in addition to the usual trigraph /// and escaped newline business. This routine handles this complexity. /// - SourceLocation getLocationOfByte(unsigned ByteNo, const SourceManager &SM, - const LangOptions &Features, - const TargetInfo &Target) const; + SourceLocation + getLocationOfByte(unsigned ByteNo, const SourceManager &SM, + const LangOptions &Features, const TargetInfo &Target, + unsigned *StartToken = nullptr, + unsigned *StartTokenByteOffset = nullptr) const; typedef const SourceLocation *tokloc_iterator; tokloc_iterator tokloc_begin() const { return TokLocs; } - tokloc_iterator tokloc_end() const { return TokLocs+NumConcatenated; } + tokloc_iterator tokloc_end() const { return TokLocs + NumConcatenated; } SourceLocation getLocStart() const LLVM_READONLY { return TokLocs[0]; } SourceLocation getLocEnd() const LLVM_READONLY { @@ -1614,7 +1594,9 @@ public: } // Iterators - child_range children() { return child_range(); } + child_range children() { + return child_range(child_iterator(), child_iterator()); + } }; /// ParenExpr - This represents a parethesized expression, e.g. "(1)". This @@ -1658,7 +1640,6 @@ public: child_range children() { return child_range(&Val, &Val+1); } }; - /// UnaryOperator - This represents the unary-expression's (except sizeof and /// alignof), the postinc/postdec operators from postfix-expression, and various /// extensions. @@ -1768,6 +1749,99 @@ public: child_range children() { return child_range(&Val, &Val+1); } }; +/// Helper class for OffsetOfExpr. + +// __builtin_offsetof(type, identifier(.identifier|[expr])*) +class OffsetOfNode { +public: + /// \brief The kind of offsetof node we have. + enum Kind { + /// \brief An index into an array. + Array = 0x00, + /// \brief A field. + Field = 0x01, + /// \brief A field in a dependent type, known only by its name. + Identifier = 0x02, + /// \brief An implicit indirection through a C++ base class, when the + /// field found is in a base class. + Base = 0x03 + }; + +private: + enum { MaskBits = 2, Mask = 0x03 }; + + /// \brief The source range that covers this part of the designator. + SourceRange Range; + + /// \brief The data describing the designator, which comes in three + /// different forms, depending on the lower two bits. + /// - An unsigned index into the array of Expr*'s stored after this node + /// in memory, for [constant-expression] designators. + /// - A FieldDecl*, for references to a known field. + /// - An IdentifierInfo*, for references to a field with a given name + /// when the class type is dependent. + /// - A CXXBaseSpecifier*, for references that look at a field in a + /// base class. + uintptr_t Data; + +public: + /// \brief Create an offsetof node that refers to an array element. + OffsetOfNode(SourceLocation LBracketLoc, unsigned Index, + SourceLocation RBracketLoc) + : Range(LBracketLoc, RBracketLoc), Data((Index << 2) | Array) {} + + /// \brief Create an offsetof node that refers to a field. + OffsetOfNode(SourceLocation DotLoc, FieldDecl *Field, SourceLocation NameLoc) + : Range(DotLoc.isValid() ? DotLoc : NameLoc, NameLoc), + Data(reinterpret_cast<uintptr_t>(Field) | OffsetOfNode::Field) {} + + /// \brief Create an offsetof node that refers to an identifier. + OffsetOfNode(SourceLocation DotLoc, IdentifierInfo *Name, + SourceLocation NameLoc) + : Range(DotLoc.isValid() ? DotLoc : NameLoc, NameLoc), + Data(reinterpret_cast<uintptr_t>(Name) | Identifier) {} + + /// \brief Create an offsetof node that refers into a C++ base class. + explicit OffsetOfNode(const CXXBaseSpecifier *Base) + : Range(), Data(reinterpret_cast<uintptr_t>(Base) | OffsetOfNode::Base) {} + + /// \brief Determine what kind of offsetof node this is. + Kind getKind() const { return static_cast<Kind>(Data & Mask); } + + /// \brief For an array element node, returns the index into the array + /// of expressions. + unsigned getArrayExprIndex() const { + assert(getKind() == Array); + return Data >> 2; + } + + /// \brief For a field offsetof node, returns the field. + FieldDecl *getField() const { + assert(getKind() == Field); + return reinterpret_cast<FieldDecl *>(Data & ~(uintptr_t)Mask); + } + + /// \brief For a field or identifier offsetof node, returns the name of + /// the field. + IdentifierInfo *getFieldName() const; + + /// \brief For a base class node, returns the base specifier. + CXXBaseSpecifier *getBase() const { + assert(getKind() == Base); + return reinterpret_cast<CXXBaseSpecifier *>(Data & ~(uintptr_t)Mask); + } + + /// \brief Retrieve the source range that covers this offsetof node. + /// + /// For an array element node, the source range contains the locations of + /// the square brackets. For a field or identifier node, the source range + /// contains the location of the period (if there is one) and the + /// identifier. + SourceRange getSourceRange() const LLVM_READONLY { return Range; } + SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); } + SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); } +}; + /// OffsetOfExpr - [C99 7.17] - This represents an expression of the form /// offsetof(record-type, member-designator). For example, given: /// @code @@ -1782,104 +1856,9 @@ public: /// @endcode /// we can represent and evaluate the expression @c offsetof(struct T, s[2].d). -class OffsetOfExpr : public Expr { -public: - // __builtin_offsetof(type, identifier(.identifier|[expr])*) - class OffsetOfNode { - public: - /// \brief The kind of offsetof node we have. - enum Kind { - /// \brief An index into an array. - Array = 0x00, - /// \brief A field. - Field = 0x01, - /// \brief A field in a dependent type, known only by its name. - Identifier = 0x02, - /// \brief An implicit indirection through a C++ base class, when the - /// field found is in a base class. - Base = 0x03 - }; - - private: - enum { MaskBits = 2, Mask = 0x03 }; - - /// \brief The source range that covers this part of the designator. - SourceRange Range; - - /// \brief The data describing the designator, which comes in three - /// different forms, depending on the lower two bits. - /// - An unsigned index into the array of Expr*'s stored after this node - /// in memory, for [constant-expression] designators. - /// - A FieldDecl*, for references to a known field. - /// - An IdentifierInfo*, for references to a field with a given name - /// when the class type is dependent. - /// - A CXXBaseSpecifier*, for references that look at a field in a - /// base class. - uintptr_t Data; - - public: - /// \brief Create an offsetof node that refers to an array element. - OffsetOfNode(SourceLocation LBracketLoc, unsigned Index, - SourceLocation RBracketLoc) - : Range(LBracketLoc, RBracketLoc), Data((Index << 2) | Array) { } - - /// \brief Create an offsetof node that refers to a field. - OffsetOfNode(SourceLocation DotLoc, FieldDecl *Field, - SourceLocation NameLoc) - : Range(DotLoc.isValid()? DotLoc : NameLoc, NameLoc), - Data(reinterpret_cast<uintptr_t>(Field) | OffsetOfNode::Field) { } - - /// \brief Create an offsetof node that refers to an identifier. - OffsetOfNode(SourceLocation DotLoc, IdentifierInfo *Name, - SourceLocation NameLoc) - : Range(DotLoc.isValid()? DotLoc : NameLoc, NameLoc), - Data(reinterpret_cast<uintptr_t>(Name) | Identifier) { } - - /// \brief Create an offsetof node that refers into a C++ base class. - explicit OffsetOfNode(const CXXBaseSpecifier *Base) - : Range(), Data(reinterpret_cast<uintptr_t>(Base) | OffsetOfNode::Base) {} - - /// \brief Determine what kind of offsetof node this is. - Kind getKind() const { - return static_cast<Kind>(Data & Mask); - } - - /// \brief For an array element node, returns the index into the array - /// of expressions. - unsigned getArrayExprIndex() const { - assert(getKind() == Array); - return Data >> 2; - } - - /// \brief For a field offsetof node, returns the field. - FieldDecl *getField() const { - assert(getKind() == Field); - return reinterpret_cast<FieldDecl *>(Data & ~(uintptr_t)Mask); - } - - /// \brief For a field or identifier offsetof node, returns the name of - /// the field. - IdentifierInfo *getFieldName() const; - - /// \brief For a base class node, returns the base specifier. - CXXBaseSpecifier *getBase() const { - assert(getKind() == Base); - return reinterpret_cast<CXXBaseSpecifier *>(Data & ~(uintptr_t)Mask); - } - - /// \brief Retrieve the source range that covers this offsetof node. - /// - /// For an array element node, the source range contains the locations of - /// the square brackets. For a field or identifier node, the source range - /// contains the location of the period (if there is one) and the - /// identifier. - SourceRange getSourceRange() const LLVM_READONLY { return Range; } - SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); } - SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); } - }; - -private: - +class OffsetOfExpr final + : public Expr, + private llvm::TrailingObjects<OffsetOfExpr, OffsetOfNode, Expr *> { SourceLocation OperatorLoc, RParenLoc; // Base type; TypeSourceInfo *TSInfo; @@ -1888,6 +1867,10 @@ private: // Number of sub-expressions (i.e. array subscript expressions). unsigned NumExprs; + size_t numTrailingObjects(OverloadToken<OffsetOfNode>) const { + return NumComps; + } + OffsetOfExpr(const ASTContext &C, QualType type, SourceLocation OperatorLoc, TypeSourceInfo *tsi, ArrayRef<OffsetOfNode> comps, ArrayRef<Expr*> exprs, @@ -1924,12 +1907,12 @@ public: const OffsetOfNode &getComponent(unsigned Idx) const { assert(Idx < NumComps && "Subscript out of range"); - return reinterpret_cast<const OffsetOfNode *> (this + 1)[Idx]; + return getTrailingObjects<OffsetOfNode>()[Idx]; } void setComponent(unsigned Idx, OffsetOfNode ON) { assert(Idx < NumComps && "Subscript out of range"); - reinterpret_cast<OffsetOfNode *> (this + 1)[Idx] = ON; + getTrailingObjects<OffsetOfNode>()[Idx] = ON; } unsigned getNumComponents() const { @@ -1938,17 +1921,17 @@ public: Expr* getIndexExpr(unsigned Idx) { assert(Idx < NumExprs && "Subscript out of range"); - return reinterpret_cast<Expr **>( - reinterpret_cast<OffsetOfNode *>(this+1) + NumComps)[Idx]; + return getTrailingObjects<Expr *>()[Idx]; } + const Expr *getIndexExpr(unsigned Idx) const { - return const_cast<OffsetOfExpr*>(this)->getIndexExpr(Idx); + assert(Idx < NumExprs && "Subscript out of range"); + return getTrailingObjects<Expr *>()[Idx]; } void setIndexExpr(unsigned Idx, Expr* E) { assert(Idx < NumComps && "Subscript out of range"); - reinterpret_cast<Expr **>( - reinterpret_cast<OffsetOfNode *>(this+1) + NumComps)[Idx] = E; + getTrailingObjects<Expr *>()[Idx] = E; } unsigned getNumExpressions() const { @@ -1964,11 +1947,10 @@ public: // Iterators child_range children() { - Stmt **begin = - reinterpret_cast<Stmt**>(reinterpret_cast<OffsetOfNode*>(this + 1) - + NumComps); + Stmt **begin = reinterpret_cast<Stmt **>(getTrailingObjects<Expr *>()); return child_range(begin, begin + NumExprs); } + friend TrailingObjects; }; /// UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated) @@ -2142,7 +2124,6 @@ public: } }; - /// CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]). /// CallExpr itself represents a normal function call, e.g., "f(x, 2)", /// while its subclasses may represent alternative syntax that (semantically) @@ -2298,20 +2279,24 @@ public: } }; +/// Extra data stored in some MemberExpr objects. +struct MemberExprNameQualifier { + /// \brief The nested-name-specifier that qualifies the name, including + /// source-location information. + NestedNameSpecifierLoc QualifierLoc; + + /// \brief The DeclAccessPair through which the MemberDecl was found due to + /// name qualifiers. + DeclAccessPair FoundDecl; +}; + /// MemberExpr - [C99 6.5.2.3] Structure and Union Members. X->F and X.F. /// -class MemberExpr : public Expr { - /// Extra data stored in some member expressions. - struct MemberNameQualifier { - /// \brief The nested-name-specifier that qualifies the name, including - /// source-location information. - NestedNameSpecifierLoc QualifierLoc; - - /// \brief The DeclAccessPair through which the MemberDecl was found due to - /// name qualifiers. - DeclAccessPair FoundDecl; - }; - +class MemberExpr final + : public Expr, + private llvm::TrailingObjects<MemberExpr, MemberExprNameQualifier, + ASTTemplateKWAndArgsInfo, + TemplateArgumentLoc> { /// Base - the expression for the base pointer or structure references. In /// X.F, this is "X". Stmt *Base; @@ -2335,7 +2320,7 @@ class MemberExpr : public Expr { /// \brief True if this member expression used a nested-name-specifier to /// refer to the member, e.g., "x->Base::f", or found its member via a using - /// declaration. When true, a MemberNameQualifier + /// declaration. When true, a MemberExprNameQualifier /// structure is allocated immediately after the MemberExpr. bool HasQualifierOrFoundDecl : 1; @@ -2343,24 +2328,19 @@ class MemberExpr : public Expr { /// and/or a template argument list explicitly, e.g., x->f<int>, /// x->template f, x->template f<int>. /// When true, an ASTTemplateKWAndArgsInfo structure and its - /// TemplateArguments (if any) are allocated immediately after - /// the MemberExpr or, if the member expression also has a qualifier, - /// after the MemberNameQualifier structure. + /// TemplateArguments (if any) are present. bool HasTemplateKWAndArgsInfo : 1; /// \brief True if this member expression refers to a method that /// was resolved from an overloaded set having size greater than 1. bool HadMultipleCandidates : 1; - /// \brief Retrieve the qualifier that preceded the member name, if any. - MemberNameQualifier *getMemberQualifier() { - assert(HasQualifierOrFoundDecl); - return reinterpret_cast<MemberNameQualifier *> (this + 1); + size_t numTrailingObjects(OverloadToken<MemberExprNameQualifier>) const { + return HasQualifierOrFoundDecl ? 1 : 0; } - /// \brief Retrieve the qualifier that preceded the member name, if any. - const MemberNameQualifier *getMemberQualifier() const { - return const_cast<MemberExpr *>(this)->getMemberQualifier(); + size_t numTrailingObjects(OverloadToken<ASTTemplateKWAndArgsInfo>) const { + return HasTemplateKWAndArgsInfo ? 1 : 0; } public: @@ -2416,7 +2396,7 @@ public: if (!HasQualifierOrFoundDecl) return DeclAccessPair::make(getMemberDecl(), getMemberDecl()->getAccess()); - return getMemberQualifier()->FoundDecl; + return getTrailingObjects<MemberExprNameQualifier>()->FoundDecl; } /// \brief Determines whether this member expression actually had @@ -2425,61 +2405,41 @@ public: bool hasQualifier() const { return getQualifier() != nullptr; } /// \brief If the member name was qualified, retrieves the - /// nested-name-specifier that precedes the member name. Otherwise, returns - /// NULL. - NestedNameSpecifier *getQualifier() const { - if (!HasQualifierOrFoundDecl) - return nullptr; - - return getMemberQualifier()->QualifierLoc.getNestedNameSpecifier(); - } - - /// \brief If the member name was qualified, retrieves the /// nested-name-specifier that precedes the member name, with source-location /// information. NestedNameSpecifierLoc getQualifierLoc() const { - if (!hasQualifier()) - return NestedNameSpecifierLoc(); - - return getMemberQualifier()->QualifierLoc; - } - - /// \brief Return the optional template keyword and arguments info. - ASTTemplateKWAndArgsInfo *getTemplateKWAndArgsInfo() { - if (!HasTemplateKWAndArgsInfo) - return nullptr; - if (!HasQualifierOrFoundDecl) - return reinterpret_cast<ASTTemplateKWAndArgsInfo *>(this + 1); + return NestedNameSpecifierLoc(); - return reinterpret_cast<ASTTemplateKWAndArgsInfo *>( - getMemberQualifier() + 1); + return getTrailingObjects<MemberExprNameQualifier>()->QualifierLoc; } - /// \brief Return the optional template keyword and arguments info. - const ASTTemplateKWAndArgsInfo *getTemplateKWAndArgsInfo() const { - return const_cast<MemberExpr*>(this)->getTemplateKWAndArgsInfo(); + /// \brief If the member name was qualified, retrieves the + /// nested-name-specifier that precedes the member name. Otherwise, returns + /// NULL. + NestedNameSpecifier *getQualifier() const { + return getQualifierLoc().getNestedNameSpecifier(); } /// \brief Retrieve the location of the template keyword preceding /// the member name, if any. SourceLocation getTemplateKeywordLoc() const { if (!HasTemplateKWAndArgsInfo) return SourceLocation(); - return getTemplateKWAndArgsInfo()->getTemplateKeywordLoc(); + return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->TemplateKWLoc; } /// \brief Retrieve the location of the left angle bracket starting the /// explicit template argument list following the member name, if any. SourceLocation getLAngleLoc() const { if (!HasTemplateKWAndArgsInfo) return SourceLocation(); - return getTemplateKWAndArgsInfo()->LAngleLoc; + return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->LAngleLoc; } /// \brief Retrieve the location of the right angle bracket ending the /// explicit template argument list following the member name, if any. SourceLocation getRAngleLoc() const { if (!HasTemplateKWAndArgsInfo) return SourceLocation(); - return getTemplateKWAndArgsInfo()->RAngleLoc; + return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->RAngleLoc; } /// Determines whether the member name was preceded by the template keyword. @@ -2493,30 +2453,8 @@ public: /// structure. void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const { if (hasExplicitTemplateArgs()) - getExplicitTemplateArgs().copyInto(List); - } - - /// \brief Retrieve the explicit template argument list that - /// follow the member template name. This must only be called on an - /// expression with explicit template arguments. - ASTTemplateArgumentListInfo &getExplicitTemplateArgs() { - assert(hasExplicitTemplateArgs()); - return *getTemplateKWAndArgsInfo(); - } - - /// \brief Retrieve the explicit template argument list that - /// followed the member template name. This must only be called on - /// an expression with explicit template arguments. - const ASTTemplateArgumentListInfo &getExplicitTemplateArgs() const { - return const_cast<MemberExpr *>(this)->getExplicitTemplateArgs(); - } - - /// \brief Retrieves the optional explicit template arguments. - /// This points to the same data as getExplicitTemplateArgs(), but - /// returns null if there are no explicit template arguments. - const ASTTemplateArgumentListInfo *getOptionalExplicitTemplateArgs() const { - if (!hasExplicitTemplateArgs()) return nullptr; - return &getExplicitTemplateArgs(); + getTrailingObjects<ASTTemplateKWAndArgsInfo>()->copyInto( + getTrailingObjects<TemplateArgumentLoc>(), List); } /// \brief Retrieve the template arguments provided as part of this @@ -2525,7 +2463,7 @@ public: if (!hasExplicitTemplateArgs()) return nullptr; - return getExplicitTemplateArgs().getTemplateArgs(); + return getTrailingObjects<TemplateArgumentLoc>(); } /// \brief Retrieve the number of template arguments provided as part of this @@ -2534,7 +2472,7 @@ public: if (!hasExplicitTemplateArgs()) return 0; - return getExplicitTemplateArgs().NumTemplateArgs; + return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->NumTemplateArgs; } /// \brief Retrieve the member declaration name info. @@ -2575,6 +2513,14 @@ public: HadMultipleCandidates = V; } + /// \brief Returns true if virtual dispatch is performed. + /// If the member access is fully qualified, (i.e. X::f()), virtual + /// dispatching is not performed. In -fapple-kext mode qualified + /// calls to virtual method will still go through the vtable. + bool performsVirtualDispatch(const LangOptions &LO) const { + return LO.AppleKext || !hasQualifier(); + } + static bool classof(const Stmt *T) { return T->getStmtClass() == MemberExprClass; } @@ -2582,6 +2528,7 @@ public: // Iterators child_range children() { return child_range(&Base, &Base+1); } + friend TrailingObjects; friend class ASTReader; friend class ASTStmtWriter; }; @@ -2731,8 +2678,6 @@ public: path_const_iterator path_begin() const { return path_buffer(); } path_const_iterator path_end() const { return path_buffer() + path_size(); } - void setCastPath(const CXXCastPath &Path); - static bool classof(const Stmt *T) { return T->getStmtClass() >= firstCastExprConstant && T->getStmtClass() <= lastCastExprConstant; @@ -2762,7 +2707,9 @@ public: /// // to an xvalue of type Base /// } /// @endcode -class ImplicitCastExpr : public CastExpr { +class ImplicitCastExpr final + : public CastExpr, + private llvm::TrailingObjects<ImplicitCastExpr, CXXBaseSpecifier *> { private: ImplicitCastExpr(QualType ty, CastKind kind, Expr *op, unsigned BasePathLength, ExprValueKind VK) @@ -2798,6 +2745,9 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == ImplicitCastExprClass; } + + friend TrailingObjects; + friend class CastExpr; }; inline Expr *Expr::IgnoreImpCasts() { @@ -2857,7 +2807,9 @@ public: /// CStyleCastExpr - An explicit cast in C (C99 6.5.4) or a C-style /// cast in C++ (C++ [expr.cast]), which uses the syntax /// (Type)expr. For example: @c (int)f. -class CStyleCastExpr : public ExplicitCastExpr { +class CStyleCastExpr final + : public ExplicitCastExpr, + private llvm::TrailingObjects<CStyleCastExpr, CXXBaseSpecifier *> { SourceLocation LPLoc; // the location of the left paren SourceLocation RPLoc; // the location of the right paren @@ -2895,6 +2847,9 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == CStyleCastExprClass; } + + friend TrailingObjects; + friend class CastExpr; }; /// \brief A builtin binary operation expression such as "x + y" or "x <= y". @@ -2989,7 +2944,10 @@ public: /// predicates to categorize the respective opcodes. bool isPtrMemOp() const { return Opc == BO_PtrMemD || Opc == BO_PtrMemI; } - bool isMultiplicativeOp() const { return Opc >= BO_Mul && Opc <= BO_Rem; } + static bool isMultiplicativeOp(Opcode Opc) { + return Opc >= BO_Mul && Opc <= BO_Rem; + } + bool isMultiplicativeOp() const { return isMultiplicativeOp(getOpcode()); } static bool isAdditiveOp(Opcode Opc) { return Opc == BO_Add || Opc==BO_Sub; } bool isAdditiveOp() const { return isAdditiveOp(getOpcode()); } static bool isShiftOp(Opcode Opc) { return Opc == BO_Shl || Opc == BO_Shr; } @@ -3384,7 +3342,9 @@ public: } // Iterators - child_range children() { return child_range(); } + child_range children() { + return child_range(child_iterator(), child_iterator()); + } }; /// StmtExpr - This is the GNU Statement Expression extension: ({int X=4; X;}). @@ -3429,7 +3389,6 @@ public: child_range children() { return child_range(&SubStmt, &SubStmt+1); } }; - /// ShuffleVectorExpr - clang-specific builtin-in function /// __builtin_shufflevector. /// This AST node represents a operator that does a constant @@ -3663,36 +3622,40 @@ public: } // Iterators - child_range children() { return child_range(); } + child_range children() { + return child_range(child_iterator(), child_iterator()); + } }; -/// VAArgExpr, used for the builtin function __builtin_va_arg. +/// Represents a call to the builtin function \c __builtin_va_arg. class VAArgExpr : public Expr { Stmt *Val; - TypeSourceInfo *TInfo; + llvm::PointerIntPair<TypeSourceInfo *, 1, bool> TInfo; SourceLocation BuiltinLoc, RParenLoc; public: - VAArgExpr(SourceLocation BLoc, Expr* e, TypeSourceInfo *TInfo, - SourceLocation RPLoc, QualType t) - : Expr(VAArgExprClass, t, VK_RValue, OK_Ordinary, - t->isDependentType(), false, - (TInfo->getType()->isInstantiationDependentType() || - e->isInstantiationDependent()), - (TInfo->getType()->containsUnexpandedParameterPack() || - e->containsUnexpandedParameterPack())), - Val(e), TInfo(TInfo), - BuiltinLoc(BLoc), - RParenLoc(RPLoc) { } - - /// \brief Create an empty __builtin_va_arg expression. - explicit VAArgExpr(EmptyShell Empty) : Expr(VAArgExprClass, Empty) { } + VAArgExpr(SourceLocation BLoc, Expr *e, TypeSourceInfo *TInfo, + SourceLocation RPLoc, QualType t, bool IsMS) + : Expr(VAArgExprClass, t, VK_RValue, OK_Ordinary, t->isDependentType(), + false, (TInfo->getType()->isInstantiationDependentType() || + e->isInstantiationDependent()), + (TInfo->getType()->containsUnexpandedParameterPack() || + e->containsUnexpandedParameterPack())), + Val(e), TInfo(TInfo, IsMS), BuiltinLoc(BLoc), RParenLoc(RPLoc) {} + + /// Create an empty __builtin_va_arg expression. + explicit VAArgExpr(EmptyShell Empty) + : Expr(VAArgExprClass, Empty), Val(nullptr), TInfo(nullptr, false) {} const Expr *getSubExpr() const { return cast<Expr>(Val); } Expr *getSubExpr() { return cast<Expr>(Val); } void setSubExpr(Expr *E) { Val = E; } - TypeSourceInfo *getWrittenTypeInfo() const { return TInfo; } - void setWrittenTypeInfo(TypeSourceInfo *TI) { TInfo = TI; } + /// Returns whether this is really a Win64 ABI va_arg expression. + bool isMicrosoftABI() const { return TInfo.getInt(); } + void setIsMicrosoftABI(bool IsMS) { TInfo.setInt(IsMS); } + + TypeSourceInfo *getWrittenTypeInfo() const { return TInfo.getPointer(); } + void setWrittenTypeInfo(TypeSourceInfo *TI) { TInfo.setPointer(TI); } SourceLocation getBuiltinLoc() const { return BuiltinLoc; } void setBuiltinLoc(SourceLocation L) { BuiltinLoc = L; } @@ -3791,6 +3754,10 @@ public: /// \brief Retrieve the set of initializers. Expr **getInits() { return reinterpret_cast<Expr **>(InitExprs.data()); } + ArrayRef<Expr *> inits() { + return llvm::makeArrayRef(getInits(), getNumInits()); + } + const Expr *getInit(unsigned Init) const { assert(Init < getNumInits() && "Initializer access out of range!"); return cast_or_null<Expr>(InitExprs[Init]); @@ -3916,7 +3883,8 @@ public: // Iterators child_range children() { // FIXME: This does not include the array filler expression. - if (InitExprs.empty()) return child_range(); + if (InitExprs.empty()) + return child_range(child_iterator(), child_iterator()); return child_range(&InitExprs[0], &InitExprs[0] + InitExprs.size()); } @@ -4293,7 +4261,9 @@ public: SourceLocation getLocEnd() const LLVM_READONLY { return SourceLocation(); } // Iterators - child_range children() { return child_range(); } + child_range children() { + return child_range(child_iterator(), child_iterator()); + } }; // In cases like: @@ -4367,10 +4337,11 @@ public: SourceLocation getLocEnd() const LLVM_READONLY { return SourceLocation(); } // Iterators - child_range children() { return child_range(); } + child_range children() { + return child_range(child_iterator(), child_iterator()); + } }; - class ParenListExpr : public Expr { Stmt **Exprs; unsigned NumExprs; @@ -4397,6 +4368,10 @@ public: Expr **getExprs() { return reinterpret_cast<Expr **>(Exprs); } + ArrayRef<Expr *> exprs() { + return llvm::makeArrayRef(getExprs(), getNumExprs()); + } + SourceLocation getLParenLoc() const { return LParenLoc; } SourceLocation getRParenLoc() const { return RParenLoc; } @@ -4416,7 +4391,6 @@ public: friend class ASTStmtWriter; }; - /// \brief Represents a C11 generic selection. /// /// A generic selection (C11 6.5.1.1) contains an unevaluated controlling @@ -4532,7 +4506,6 @@ public: // Clang Extensions //===----------------------------------------------------------------------===// - /// ExtVectorElementExpr - This represents access to specific elements of a /// vector, and may occur on the left hand side or right hand side. For example /// the following is legal: "V.xy = V.zw" if V is a 4 element extended vector. @@ -4577,7 +4550,7 @@ public: /// getEncodedElementAccess - Encode the elements accessed into an llvm /// aggregate Constant of ConstantInt(s). - void getEncodedElementAccess(SmallVectorImpl<unsigned> &Elts) const; + void getEncodedElementAccess(SmallVectorImpl<uint32_t> &Elts) const; SourceLocation getLocStart() const LLVM_READONLY { return getBase()->getLocStart(); @@ -4596,7 +4569,6 @@ public: child_range children() { return child_range(&Base, &Base+1); } }; - /// BlockExpr - Adaptor class for mixing a BlockDecl with expressions. /// ^{ statement-body } or ^(int arg1, float arg2){ statement-body } class BlockExpr : public Expr { @@ -4633,7 +4605,9 @@ public: } // Iterators - child_range children() { return child_range(); } + child_range children() { + return child_range(child_iterator(), child_iterator()); + } }; /// AsTypeExpr - Clang builtin function __builtin_astype [OpenCL 6.2.4.2] @@ -4789,6 +4763,14 @@ public: const_semantics_iterator semantics_end() const { return getSubExprsBuffer() + getNumSubExprs(); } + + llvm::iterator_range<semantics_iterator> semantics() { + return llvm::make_range(semantics_begin(), semantics_end()); + } + llvm::iterator_range<const_semantics_iterator> semantics() const { + return llvm::make_range(semantics_begin(), semantics_end()); + } + Expr *getSemanticExpr(unsigned index) { assert(index + 1 < getNumSubExprs()); return getSubExprsBuffer()[index + 1]; @@ -4935,10 +4917,17 @@ public: assert(T->isDependentType() && "TypoExpr given a non-dependent type"); } - child_range children() { return child_range(); } + child_range children() { + return child_range(child_iterator(), child_iterator()); + } SourceLocation getLocStart() const LLVM_READONLY { return SourceLocation(); } SourceLocation getLocEnd() const LLVM_READONLY { return SourceLocation(); } + + static bool classof(const Stmt *T) { + return T->getStmtClass() == TypoExprClass; + } + }; -} // end namespace clang +} // end namespace clang -#endif +#endif // LLVM_CLANG_AST_EXPR_H diff --git a/contrib/llvm/tools/clang/include/clang/AST/ExprCXX.h b/contrib/llvm/tools/clang/include/clang/AST/ExprCXX.h index 1dbf574..707aeed 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/ExprCXX.h +++ b/contrib/llvm/tools/clang/include/clang/AST/ExprCXX.h @@ -235,7 +235,9 @@ public: /// /// This expression node represents a C++ static cast, e.g., /// \c static_cast<int>(1.0). -class CXXStaticCastExpr : public CXXNamedCastExpr { +class CXXStaticCastExpr final + : public CXXNamedCastExpr, + private llvm::TrailingObjects<CXXStaticCastExpr, CXXBaseSpecifier *> { CXXStaticCastExpr(QualType ty, ExprValueKind vk, CastKind kind, Expr *op, unsigned pathSize, TypeSourceInfo *writtenTy, SourceLocation l, SourceLocation RParenLoc, @@ -259,6 +261,9 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == CXXStaticCastExprClass; } + + friend TrailingObjects; + friend class CastExpr; }; /// \brief A C++ @c dynamic_cast expression (C++ [expr.dynamic.cast]). @@ -266,7 +271,9 @@ public: /// This expression node represents a dynamic cast, e.g., /// \c dynamic_cast<Derived*>(BasePtr). Such a cast may perform a run-time /// check to determine how to perform the type conversion. -class CXXDynamicCastExpr : public CXXNamedCastExpr { +class CXXDynamicCastExpr final + : public CXXNamedCastExpr, + private llvm::TrailingObjects<CXXDynamicCastExpr, CXXBaseSpecifier *> { CXXDynamicCastExpr(QualType ty, ExprValueKind VK, CastKind kind, Expr *op, unsigned pathSize, TypeSourceInfo *writtenTy, SourceLocation l, SourceLocation RParenLoc, @@ -293,6 +300,9 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == CXXDynamicCastExprClass; } + + friend TrailingObjects; + friend class CastExpr; }; /// \brief A C++ @c reinterpret_cast expression (C++ [expr.reinterpret.cast]). @@ -303,7 +313,10 @@ public: /// A reinterpret_cast provides a differently-typed view of a value but /// (in Clang, as in most C++ implementations) performs no actual work at /// run time. -class CXXReinterpretCastExpr : public CXXNamedCastExpr { +class CXXReinterpretCastExpr final + : public CXXNamedCastExpr, + private llvm::TrailingObjects<CXXReinterpretCastExpr, + CXXBaseSpecifier *> { CXXReinterpretCastExpr(QualType ty, ExprValueKind vk, CastKind kind, Expr *op, unsigned pathSize, TypeSourceInfo *writtenTy, SourceLocation l, @@ -328,6 +341,9 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == CXXReinterpretCastExprClass; } + + friend TrailingObjects; + friend class CastExpr; }; /// \brief A C++ \c const_cast expression (C++ [expr.const.cast]). @@ -337,7 +353,9 @@ public: /// /// A const_cast can remove type qualifiers but does not change the underlying /// value. -class CXXConstCastExpr : public CXXNamedCastExpr { +class CXXConstCastExpr final + : public CXXNamedCastExpr, + private llvm::TrailingObjects<CXXConstCastExpr, CXXBaseSpecifier *> { CXXConstCastExpr(QualType ty, ExprValueKind VK, Expr *op, TypeSourceInfo *writtenTy, SourceLocation l, SourceLocation RParenLoc, SourceRange AngleBrackets) @@ -358,6 +376,9 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == CXXConstCastExprClass; } + + friend TrailingObjects; + friend class CastExpr; }; /// \brief A call to a literal operator (C++11 [over.literal]) @@ -457,7 +478,9 @@ public: } // Iterators - child_range children() { return child_range(); } + child_range children() { + return child_range(child_iterator(), child_iterator()); + } }; /// \brief The null pointer literal (C++11 [lex.nullptr]) @@ -484,7 +507,9 @@ public: return T->getStmtClass() == CXXNullPtrLiteralExprClass; } - child_range children() { return child_range(); } + child_range children() { + return child_range(child_iterator(), child_iterator()); + } }; /// \brief Implicit construction of a std::initializer_list<T> object from an @@ -607,7 +632,8 @@ public: // Iterators child_range children() { - if (isTypeOperand()) return child_range(); + if (isTypeOperand()) + return child_range(child_iterator(), child_iterator()); Stmt **begin = reinterpret_cast<Stmt**>(&Operand); return child_range(begin, begin + 1); } @@ -672,6 +698,69 @@ public: friend class ASTStmtReader; }; +/// MS property subscript expression. +/// MSVC supports 'property' attribute and allows to apply it to the +/// declaration of an empty array in a class or structure definition. +/// For example: +/// \code +/// __declspec(property(get=GetX, put=PutX)) int x[]; +/// \endcode +/// The above statement indicates that x[] can be used with one or more array +/// indices. In this case, i=p->x[a][b] will be turned into i=p->GetX(a, b), and +/// p->x[a][b] = i will be turned into p->PutX(a, b, i). +/// This is a syntactic pseudo-object expression. +class MSPropertySubscriptExpr : public Expr { + friend class ASTStmtReader; + enum { BASE_EXPR, IDX_EXPR, NUM_SUBEXPRS = 2 }; + Stmt *SubExprs[NUM_SUBEXPRS]; + SourceLocation RBracketLoc; + + void setBase(Expr *Base) { SubExprs[BASE_EXPR] = Base; } + void setIdx(Expr *Idx) { SubExprs[IDX_EXPR] = Idx; } + +public: + MSPropertySubscriptExpr(Expr *Base, Expr *Idx, QualType Ty, ExprValueKind VK, + ExprObjectKind OK, SourceLocation RBracketLoc) + : Expr(MSPropertySubscriptExprClass, Ty, VK, OK, Idx->isTypeDependent(), + Idx->isValueDependent(), Idx->isInstantiationDependent(), + Idx->containsUnexpandedParameterPack()), + RBracketLoc(RBracketLoc) { + SubExprs[BASE_EXPR] = Base; + SubExprs[IDX_EXPR] = Idx; + } + + /// \brief Create an empty array subscript expression. + explicit MSPropertySubscriptExpr(EmptyShell Shell) + : Expr(MSPropertySubscriptExprClass, Shell) {} + + Expr *getBase() { return cast<Expr>(SubExprs[BASE_EXPR]); } + const Expr *getBase() const { return cast<Expr>(SubExprs[BASE_EXPR]); } + + Expr *getIdx() { return cast<Expr>(SubExprs[IDX_EXPR]); } + const Expr *getIdx() const { return cast<Expr>(SubExprs[IDX_EXPR]); } + + SourceLocation getLocStart() const LLVM_READONLY { + return getBase()->getLocStart(); + } + SourceLocation getLocEnd() const LLVM_READONLY { return RBracketLoc; } + + SourceLocation getRBracketLoc() const { return RBracketLoc; } + void setRBracketLoc(SourceLocation L) { RBracketLoc = L; } + + SourceLocation getExprLoc() const LLVM_READONLY { + return getBase()->getExprLoc(); + } + + static bool classof(const Stmt *T) { + return T->getStmtClass() == MSPropertySubscriptExprClass; + } + + // Iterators + child_range children() { + return child_range(&SubExprs[0], &SubExprs[0] + NUM_SUBEXPRS); + } +}; + /// A Microsoft C++ @c __uuidof expression, which gets /// the _GUID that corresponds to the supplied type or expression. /// @@ -749,7 +838,8 @@ public: // Iterators child_range children() { - if (isTypeOperand()) return child_range(); + if (isTypeOperand()) + return child_range(child_iterator(), child_iterator()); Stmt **begin = reinterpret_cast<Stmt**>(&Operand); return child_range(begin, begin + 1); } @@ -797,7 +887,9 @@ public: } // Iterators - child_range children() { return child_range(); } + child_range children() { + return child_range(child_iterator(), child_iterator()); + } }; /// \brief A C++ throw-expression (C++ [except.throw]). @@ -935,7 +1027,9 @@ public: } // Iterators - child_range children() { return child_range(); } + child_range children() { + return child_range(child_iterator(), child_iterator()); + } friend class ASTStmtReader; friend class ASTStmtWriter; @@ -991,7 +1085,9 @@ public: } // Iterators - child_range children() { return child_range(); } + child_range children() { + return child_range(child_iterator(), child_iterator()); + } friend class ASTReader; friend class ASTStmtReader; @@ -1238,7 +1334,9 @@ public: /// \code /// x = int(0.5); /// \endcode -class CXXFunctionalCastExpr : public ExplicitCastExpr { +class CXXFunctionalCastExpr final + : public ExplicitCastExpr, + private llvm::TrailingObjects<CXXFunctionalCastExpr, CXXBaseSpecifier *> { SourceLocation LParenLoc; SourceLocation RParenLoc; @@ -1275,6 +1373,9 @@ public: static bool classof(const Stmt *T) { return T->getStmtClass() == CXXFunctionalCastExprClass; } + + friend TrailingObjects; + friend class CastExpr; }; /// @brief Represents a C++ functional cast expression that builds a @@ -1401,25 +1502,39 @@ class LambdaExpr : public Expr { ExplicitResultType(false), HasArrayIndexVars(true) { getStoredStmts()[NumCaptures] = nullptr; } - - Stmt **getStoredStmts() const { - return reinterpret_cast<Stmt **>(const_cast<LambdaExpr *>(this) + 1); + + Stmt **getStoredStmts() { return reinterpret_cast<Stmt **>(this + 1); } + + Stmt *const *getStoredStmts() const { + return reinterpret_cast<Stmt *const *>(this + 1); } - + /// \brief Retrieve the mapping from captures to the first array index /// variable. - unsigned *getArrayIndexStarts() const { + unsigned *getArrayIndexStarts() { return reinterpret_cast<unsigned *>(getStoredStmts() + NumCaptures + 1); } + const unsigned *getArrayIndexStarts() const { + return reinterpret_cast<const unsigned *>(getStoredStmts() + NumCaptures + + 1); + } + /// \brief Retrieve the complete set of array-index variables. - VarDecl **getArrayIndexVars() const { + VarDecl **getArrayIndexVars() { unsigned ArrayIndexSize = llvm::RoundUpToAlignment( sizeof(unsigned) * (NumCaptures + 1), llvm::alignOf<VarDecl *>()); return reinterpret_cast<VarDecl **>( reinterpret_cast<char *>(getArrayIndexStarts()) + ArrayIndexSize); } + VarDecl *const *getArrayIndexVars() const { + unsigned ArrayIndexSize = llvm::RoundUpToAlignment( + sizeof(unsigned) * (NumCaptures + 1), llvm::alignOf<VarDecl *>()); + return reinterpret_cast<VarDecl *const *>( + reinterpret_cast<const char *>(getArrayIndexStarts()) + ArrayIndexSize); + } + public: /// \brief Construct a new lambda expression. static LambdaExpr *Create(const ASTContext &C, @@ -1501,31 +1616,52 @@ public: /// arguments. typedef Expr **capture_init_iterator; + /// \brief Const iterator that walks over the capture initialization + /// arguments. + typedef Expr *const *const_capture_init_iterator; + + /// \brief Retrieve the initialization expressions for this lambda's captures. + llvm::iterator_range<capture_init_iterator> capture_inits() { + return llvm::make_range(capture_init_begin(), capture_init_end()); + } + /// \brief Retrieve the initialization expressions for this lambda's captures. - llvm::iterator_range<capture_init_iterator> capture_inits() const { - return llvm::iterator_range<capture_init_iterator>(capture_init_begin(), - capture_init_end()); + llvm::iterator_range<const_capture_init_iterator> capture_inits() const { + return llvm::make_range(capture_init_begin(), capture_init_end()); } /// \brief Retrieve the first initialization argument for this /// lambda expression (which initializes the first capture field). - capture_init_iterator capture_init_begin() const { + capture_init_iterator capture_init_begin() { return reinterpret_cast<Expr **>(getStoredStmts()); } + /// \brief Retrieve the first initialization argument for this + /// lambda expression (which initializes the first capture field). + const_capture_init_iterator capture_init_begin() const { + return reinterpret_cast<Expr *const *>(getStoredStmts()); + } + /// \brief Retrieve the iterator pointing one past the last /// initialization argument for this lambda expression. - capture_init_iterator capture_init_end() const { - return capture_init_begin() + NumCaptures; + capture_init_iterator capture_init_end() { + return capture_init_begin() + NumCaptures; } - /// \brief Retrieve the set of index variables used in the capture + /// \brief Retrieve the iterator pointing one past the last + /// initialization argument for this lambda expression. + const_capture_init_iterator capture_init_end() const { + return capture_init_begin() + NumCaptures; + } + + /// \brief Retrieve the set of index variables used in the capture /// initializer of an array captured by copy. /// - /// \param Iter The iterator that points at the capture initializer for + /// \param Iter The iterator that points at the capture initializer for /// which we are extracting the corresponding index variables. - ArrayRef<VarDecl *> getCaptureInitIndexVars(capture_init_iterator Iter) const; - + ArrayRef<VarDecl *> + getCaptureInitIndexVars(const_capture_init_iterator Iter) const; + /// \brief Retrieve the source range covering the lambda introducer, /// which contains the explicit capture list surrounded by square /// brackets ([...]). @@ -1615,7 +1751,9 @@ public: } // Iterators - child_range children() { return child_range(); } + child_range children() { + return child_range(child_iterator(), child_iterator()); + } }; /// \brief Represents a new-expression for memory allocation and constructor @@ -1770,6 +1908,14 @@ public: typedef ExprIterator arg_iterator; typedef ConstExprIterator const_arg_iterator; + llvm::iterator_range<arg_iterator> placement_arguments() { + return llvm::make_range(placement_arg_begin(), placement_arg_end()); + } + + llvm::iterator_range<const_arg_iterator> placement_arguments() const { + return llvm::make_range(placement_arg_begin(), placement_arg_end()); + } + arg_iterator placement_arg_begin() { return SubExprs + Array + hasInitializer(); } @@ -2164,8 +2310,10 @@ public: } // Iterators - child_range children() { return child_range(); } - + child_range children() { + return child_range(child_iterator(), child_iterator()); + } + friend class ASTStmtReader; friend class ASTStmtWriter; @@ -2237,7 +2385,9 @@ public: } // Iterators - child_range children() { return child_range(); } + child_range children() { + return child_range(child_iterator(), child_iterator()); + } friend class ASTStmtReader; }; @@ -2294,7 +2444,9 @@ public: } // Iterators - child_range children() { return child_range(); } + child_range children() { + return child_range(child_iterator(), child_iterator()); + } friend class ASTStmtReader; }; @@ -2322,13 +2474,18 @@ protected: bool HasTemplateKWAndArgsInfo; /// \brief Return the optional template keyword and arguments info. - ASTTemplateKWAndArgsInfo *getTemplateKWAndArgsInfo(); // defined far below. + ASTTemplateKWAndArgsInfo * + getTrailingASTTemplateKWAndArgsInfo(); // defined far below. /// \brief Return the optional template keyword and arguments info. - const ASTTemplateKWAndArgsInfo *getTemplateKWAndArgsInfo() const { - return const_cast<OverloadExpr*>(this)->getTemplateKWAndArgsInfo(); + const ASTTemplateKWAndArgsInfo *getTrailingASTTemplateKWAndArgsInfo() const { + return const_cast<OverloadExpr *>(this) + ->getTrailingASTTemplateKWAndArgsInfo(); } + /// Return the optional template arguments. + TemplateArgumentLoc *getTrailingTemplateArgumentLoc(); // defined far below + OverloadExpr(StmtClass K, const ASTContext &C, NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, @@ -2391,7 +2548,7 @@ public: return UnresolvedSetIterator(Results + NumResults); } llvm::iterator_range<decls_iterator> decls() const { - return llvm::iterator_range<decls_iterator>(decls_begin(), decls_end()); + return llvm::make_range(decls_begin(), decls_end()); } /// \brief Gets the number of declarations in the unresolved set. @@ -2419,21 +2576,21 @@ public: /// this name, if any. SourceLocation getTemplateKeywordLoc() const { if (!HasTemplateKWAndArgsInfo) return SourceLocation(); - return getTemplateKWAndArgsInfo()->getTemplateKeywordLoc(); + return getTrailingASTTemplateKWAndArgsInfo()->TemplateKWLoc; } /// \brief Retrieve the location of the left angle bracket starting the /// explicit template argument list following the name, if any. SourceLocation getLAngleLoc() const { if (!HasTemplateKWAndArgsInfo) return SourceLocation(); - return getTemplateKWAndArgsInfo()->LAngleLoc; + return getTrailingASTTemplateKWAndArgsInfo()->LAngleLoc; } /// \brief Retrieve the location of the right angle bracket ending the /// explicit template argument list following the name, if any. SourceLocation getRAngleLoc() const { if (!HasTemplateKWAndArgsInfo) return SourceLocation(); - return getTemplateKWAndArgsInfo()->RAngleLoc; + return getTrailingASTTemplateKWAndArgsInfo()->RAngleLoc; } /// \brief Determines whether the name was preceded by the template keyword. @@ -2442,39 +2599,23 @@ public: /// \brief Determines whether this expression had explicit template arguments. bool hasExplicitTemplateArgs() const { return getLAngleLoc().isValid(); } - // Note that, inconsistently with the explicit-template-argument AST - // nodes, users are *forbidden* from calling these methods on objects - // without explicit template arguments. - - ASTTemplateArgumentListInfo &getExplicitTemplateArgs() { - assert(hasExplicitTemplateArgs()); - return *getTemplateKWAndArgsInfo(); - } - - const ASTTemplateArgumentListInfo &getExplicitTemplateArgs() const { - return const_cast<OverloadExpr*>(this)->getExplicitTemplateArgs(); - } - TemplateArgumentLoc const *getTemplateArgs() const { - return getExplicitTemplateArgs().getTemplateArgs(); + if (!hasExplicitTemplateArgs()) + return nullptr; + return const_cast<OverloadExpr *>(this)->getTrailingTemplateArgumentLoc(); } unsigned getNumTemplateArgs() const { - return getExplicitTemplateArgs().NumTemplateArgs; + if (!hasExplicitTemplateArgs()) + return 0; + + return getTrailingASTTemplateKWAndArgsInfo()->NumTemplateArgs; } /// \brief Copies the template arguments into the given structure. void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const { - getExplicitTemplateArgs().copyInto(List); - } - - /// \brief Retrieves the optional explicit template arguments. - /// - /// This points to the same data as getExplicitTemplateArgs(), but - /// returns null if there are no explicit template arguments. - const ASTTemplateArgumentListInfo *getOptionalExplicitTemplateArgs() const { - if (!hasExplicitTemplateArgs()) return nullptr; - return &getExplicitTemplateArgs(); + if (hasExplicitTemplateArgs()) + getTrailingASTTemplateKWAndArgsInfo()->copyInto(getTemplateArgs(), List); } static bool classof(const Stmt *T) { @@ -2497,7 +2638,10 @@ public: /// /// These never include UnresolvedUsingValueDecls, which are always class /// members and therefore appear only in UnresolvedMemberLookupExprs. -class UnresolvedLookupExpr : public OverloadExpr { +class UnresolvedLookupExpr final + : public OverloadExpr, + private llvm::TrailingObjects< + UnresolvedLookupExpr, ASTTemplateKWAndArgsInfo, TemplateArgumentLoc> { /// True if these lookup results should be extended by /// argument-dependent lookup if this is the operand of a function /// call. @@ -2514,6 +2658,10 @@ class UnresolvedLookupExpr : public OverloadExpr { /// against the qualified-lookup bits. CXXRecordDecl *NamingClass; + size_t numTrailingObjects(OverloadToken<ASTTemplateKWAndArgsInfo>) const { + return HasTemplateKWAndArgsInfo ? 1 : 0; + } + UnresolvedLookupExpr(const ASTContext &C, CXXRecordDecl *NamingClass, NestedNameSpecifierLoc QualifierLoc, @@ -2533,6 +2681,8 @@ class UnresolvedLookupExpr : public OverloadExpr { RequiresADL(false), Overloaded(false), NamingClass(nullptr) {} + friend TrailingObjects; + friend class OverloadExpr; friend class ASTStmtReader; public: @@ -2585,7 +2735,9 @@ public: return getNameInfo().getLocEnd(); } - child_range children() { return child_range(); } + child_range children() { + return child_range(child_iterator(), child_iterator()); + } static bool classof(const Stmt *T) { return T->getStmtClass() == UnresolvedLookupExprClass; @@ -2606,7 +2758,11 @@ public: /// qualifier (X<T>::) and the name of the entity being referenced /// ("value"). Such expressions will instantiate to a DeclRefExpr once the /// declaration can be found. -class DependentScopeDeclRefExpr : public Expr { +class DependentScopeDeclRefExpr final + : public Expr, + private llvm::TrailingObjects<DependentScopeDeclRefExpr, + ASTTemplateKWAndArgsInfo, + TemplateArgumentLoc> { /// \brief The nested-name-specifier that qualifies this unresolved /// declaration name. NestedNameSpecifierLoc QualifierLoc; @@ -2618,15 +2774,8 @@ class DependentScopeDeclRefExpr : public Expr { /// keyword and arguments. bool HasTemplateKWAndArgsInfo; - /// \brief Return the optional template keyword and arguments info. - ASTTemplateKWAndArgsInfo *getTemplateKWAndArgsInfo() { - if (!HasTemplateKWAndArgsInfo) return nullptr; - return reinterpret_cast<ASTTemplateKWAndArgsInfo*>(this + 1); - } - /// \brief Return the optional template keyword and arguments info. - const ASTTemplateKWAndArgsInfo *getTemplateKWAndArgsInfo() const { - return const_cast<DependentScopeDeclRefExpr*>(this) - ->getTemplateKWAndArgsInfo(); + size_t numTrailingObjects(OverloadToken<ASTTemplateKWAndArgsInfo>) const { + return HasTemplateKWAndArgsInfo ? 1 : 0; } DependentScopeDeclRefExpr(QualType T, @@ -2671,21 +2820,21 @@ public: /// this name, if any. SourceLocation getTemplateKeywordLoc() const { if (!HasTemplateKWAndArgsInfo) return SourceLocation(); - return getTemplateKWAndArgsInfo()->getTemplateKeywordLoc(); + return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->TemplateKWLoc; } /// \brief Retrieve the location of the left angle bracket starting the /// explicit template argument list following the name, if any. SourceLocation getLAngleLoc() const { if (!HasTemplateKWAndArgsInfo) return SourceLocation(); - return getTemplateKWAndArgsInfo()->LAngleLoc; + return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->LAngleLoc; } /// \brief Retrieve the location of the right angle bracket ending the /// explicit template argument list following the name, if any. SourceLocation getRAngleLoc() const { if (!HasTemplateKWAndArgsInfo) return SourceLocation(); - return getTemplateKWAndArgsInfo()->RAngleLoc; + return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->RAngleLoc; } /// Determines whether the name was preceded by the template keyword. @@ -2694,42 +2843,26 @@ public: /// Determines whether this lookup had explicit template arguments. bool hasExplicitTemplateArgs() const { return getLAngleLoc().isValid(); } - // Note that, inconsistently with the explicit-template-argument AST - // nodes, users are *forbidden* from calling these methods on objects - // without explicit template arguments. - - ASTTemplateArgumentListInfo &getExplicitTemplateArgs() { - assert(hasExplicitTemplateArgs()); - return *reinterpret_cast<ASTTemplateArgumentListInfo*>(this + 1); - } - - /// Gets a reference to the explicit template argument list. - const ASTTemplateArgumentListInfo &getExplicitTemplateArgs() const { - assert(hasExplicitTemplateArgs()); - return *reinterpret_cast<const ASTTemplateArgumentListInfo*>(this + 1); - } - - /// \brief Retrieves the optional explicit template arguments. - /// - /// This points to the same data as getExplicitTemplateArgs(), but - /// returns null if there are no explicit template arguments. - const ASTTemplateArgumentListInfo *getOptionalExplicitTemplateArgs() const { - if (!hasExplicitTemplateArgs()) return nullptr; - return &getExplicitTemplateArgs(); - } - /// \brief Copies the template arguments (if present) into the given /// structure. void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const { - getExplicitTemplateArgs().copyInto(List); + if (hasExplicitTemplateArgs()) + getTrailingObjects<ASTTemplateKWAndArgsInfo>()->copyInto( + getTrailingObjects<TemplateArgumentLoc>(), List); } TemplateArgumentLoc const *getTemplateArgs() const { - return getExplicitTemplateArgs().getTemplateArgs(); + if (!hasExplicitTemplateArgs()) + return nullptr; + + return getTrailingObjects<TemplateArgumentLoc>(); } unsigned getNumTemplateArgs() const { - return getExplicitTemplateArgs().NumTemplateArgs; + if (!hasExplicitTemplateArgs()) + return 0; + + return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->NumTemplateArgs; } /// Note: getLocStart() is the start of the whole DependentScopeDeclRefExpr, @@ -2747,8 +2880,11 @@ public: return T->getStmtClass() == DependentScopeDeclRefExprClass; } - child_range children() { return child_range(); } + child_range children() { + return child_range(child_iterator(), child_iterator()); + } + friend TrailingObjects; friend class ASTStmtReader; friend class ASTStmtWriter; }; @@ -2951,7 +3087,11 @@ public: /// Like UnresolvedMemberExprs, these can be either implicit or /// explicit accesses. It is only possible to get one of these with /// an implicit access if a qualifier is provided. -class CXXDependentScopeMemberExpr : public Expr { +class CXXDependentScopeMemberExpr final + : public Expr, + private llvm::TrailingObjects<CXXDependentScopeMemberExpr, + ASTTemplateKWAndArgsInfo, + TemplateArgumentLoc> { /// \brief The expression for the base pointer or class reference, /// e.g., the \c x in x.f. Can be null in implicit accesses. Stmt *Base; @@ -2989,15 +3129,8 @@ class CXXDependentScopeMemberExpr : public Expr { /// FIXME: could also be a template-id DeclarationNameInfo MemberNameInfo; - /// \brief Return the optional template keyword and arguments info. - ASTTemplateKWAndArgsInfo *getTemplateKWAndArgsInfo() { - if (!HasTemplateKWAndArgsInfo) return nullptr; - return reinterpret_cast<ASTTemplateKWAndArgsInfo*>(this + 1); - } - /// \brief Return the optional template keyword and arguments info. - const ASTTemplateKWAndArgsInfo *getTemplateKWAndArgsInfo() const { - return const_cast<CXXDependentScopeMemberExpr*>(this) - ->getTemplateKWAndArgsInfo(); + size_t numTrailingObjects(OverloadToken<ASTTemplateKWAndArgsInfo>) const { + return HasTemplateKWAndArgsInfo ? 1 : 0; } CXXDependentScopeMemberExpr(const ASTContext &C, Expr *Base, @@ -3093,21 +3226,21 @@ public: /// member name, if any. SourceLocation getTemplateKeywordLoc() const { if (!HasTemplateKWAndArgsInfo) return SourceLocation(); - return getTemplateKWAndArgsInfo()->getTemplateKeywordLoc(); + return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->TemplateKWLoc; } /// \brief Retrieve the location of the left angle bracket starting the /// explicit template argument list following the member name, if any. SourceLocation getLAngleLoc() const { if (!HasTemplateKWAndArgsInfo) return SourceLocation(); - return getTemplateKWAndArgsInfo()->LAngleLoc; + return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->LAngleLoc; } /// \brief Retrieve the location of the right angle bracket ending the /// explicit template argument list following the member name, if any. SourceLocation getRAngleLoc() const { if (!HasTemplateKWAndArgsInfo) return SourceLocation(); - return getTemplateKWAndArgsInfo()->RAngleLoc; + return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->RAngleLoc; } /// Determines whether the member name was preceded by the template keyword. @@ -3117,50 +3250,30 @@ public: /// template argument list explicitly specified, e.g., x.f<int>. bool hasExplicitTemplateArgs() const { return getLAngleLoc().isValid(); } - /// \brief Retrieve the explicit template argument list that followed the - /// member template name, if any. - ASTTemplateArgumentListInfo &getExplicitTemplateArgs() { - assert(hasExplicitTemplateArgs()); - return *reinterpret_cast<ASTTemplateArgumentListInfo *>(this + 1); - } - - /// \brief Retrieve the explicit template argument list that followed the - /// member template name, if any. - const ASTTemplateArgumentListInfo &getExplicitTemplateArgs() const { - return const_cast<CXXDependentScopeMemberExpr *>(this) - ->getExplicitTemplateArgs(); - } - - /// \brief Retrieves the optional explicit template arguments. - /// - /// This points to the same data as getExplicitTemplateArgs(), but - /// returns null if there are no explicit template arguments. - const ASTTemplateArgumentListInfo *getOptionalExplicitTemplateArgs() const { - if (!hasExplicitTemplateArgs()) return nullptr; - return &getExplicitTemplateArgs(); - } - /// \brief Copies the template arguments (if present) into the given /// structure. void copyTemplateArgumentsInto(TemplateArgumentListInfo &List) const { - getExplicitTemplateArgs().copyInto(List); - } - - /// \brief Initializes the template arguments using the given structure. - void initializeTemplateArgumentsFrom(const TemplateArgumentListInfo &List) { - getExplicitTemplateArgs().initializeFrom(List); + if (hasExplicitTemplateArgs()) + getTrailingObjects<ASTTemplateKWAndArgsInfo>()->copyInto( + getTrailingObjects<TemplateArgumentLoc>(), List); } /// \brief Retrieve the template arguments provided as part of this /// template-id. const TemplateArgumentLoc *getTemplateArgs() const { - return getExplicitTemplateArgs().getTemplateArgs(); + if (!hasExplicitTemplateArgs()) + return nullptr; + + return getTrailingObjects<TemplateArgumentLoc>(); } /// \brief Retrieve the number of template arguments provided as part of this /// template-id. unsigned getNumTemplateArgs() const { - return getExplicitTemplateArgs().NumTemplateArgs; + if (!hasExplicitTemplateArgs()) + return 0; + + return getTrailingObjects<ASTTemplateKWAndArgsInfo>()->NumTemplateArgs; } SourceLocation getLocStart() const LLVM_READONLY { @@ -3169,8 +3282,8 @@ public: if (getQualifier()) return getQualifierLoc().getBeginLoc(); return MemberNameInfo.getBeginLoc(); - } + SourceLocation getLocEnd() const LLVM_READONLY { if (hasExplicitTemplateArgs()) return getRAngleLoc(); @@ -3183,10 +3296,12 @@ public: // Iterators child_range children() { - if (isImplicitAccess()) return child_range(); + if (isImplicitAccess()) + return child_range(child_iterator(), child_iterator()); return child_range(&Base, &Base + 1); } + friend TrailingObjects; friend class ASTStmtReader; friend class ASTStmtWriter; }; @@ -3206,7 +3321,10 @@ public: /// In the final AST, an explicit access always becomes a MemberExpr. /// An implicit access may become either a MemberExpr or a /// DeclRefExpr, depending on whether the member is static. -class UnresolvedMemberExpr : public OverloadExpr { +class UnresolvedMemberExpr final + : public OverloadExpr, + private llvm::TrailingObjects< + UnresolvedMemberExpr, ASTTemplateKWAndArgsInfo, TemplateArgumentLoc> { /// \brief Whether this member expression used the '->' operator or /// the '.' operator. bool IsArrow : 1; @@ -3227,6 +3345,10 @@ class UnresolvedMemberExpr : public OverloadExpr { /// \brief The location of the '->' or '.' operator. SourceLocation OperatorLoc; + size_t numTrailingObjects(OverloadToken<ASTTemplateKWAndArgsInfo>) const { + return HasTemplateKWAndArgsInfo ? 1 : 0; + } + UnresolvedMemberExpr(const ASTContext &C, bool HasUnresolvedUsing, Expr *Base, QualType BaseType, bool IsArrow, SourceLocation OperatorLoc, @@ -3240,6 +3362,8 @@ class UnresolvedMemberExpr : public OverloadExpr { : OverloadExpr(UnresolvedMemberExprClass, Empty), IsArrow(false), HasUnresolvedUsing(false), Base(nullptr) { } + friend TrailingObjects; + friend class OverloadExpr; friend class ASTStmtReader; public: @@ -3325,11 +3449,34 @@ public: // Iterators child_range children() { - if (isImplicitAccess()) return child_range(); + if (isImplicitAccess()) + return child_range(child_iterator(), child_iterator()); return child_range(&Base, &Base + 1); } }; +inline ASTTemplateKWAndArgsInfo * +OverloadExpr::getTrailingASTTemplateKWAndArgsInfo() { + if (!HasTemplateKWAndArgsInfo) + return nullptr; + + if (isa<UnresolvedLookupExpr>(this)) + return cast<UnresolvedLookupExpr>(this) + ->getTrailingObjects<ASTTemplateKWAndArgsInfo>(); + else + return cast<UnresolvedMemberExpr>(this) + ->getTrailingObjects<ASTTemplateKWAndArgsInfo>(); +} + +inline TemplateArgumentLoc *OverloadExpr::getTrailingTemplateArgumentLoc() { + if (isa<UnresolvedLookupExpr>(this)) + return cast<UnresolvedLookupExpr>(this) + ->getTrailingObjects<TemplateArgumentLoc>(); + else + return cast<UnresolvedMemberExpr>(this) + ->getTrailingObjects<TemplateArgumentLoc>(); +} + /// \brief Represents a C++11 noexcept expression (C++ [expr.unary.noexcept]). /// /// The noexcept expression tests whether a given expression might throw. Its @@ -3451,15 +3598,6 @@ public: } }; -inline ASTTemplateKWAndArgsInfo *OverloadExpr::getTemplateKWAndArgsInfo() { - if (!HasTemplateKWAndArgsInfo) return nullptr; - if (isa<UnresolvedLookupExpr>(this)) - return reinterpret_cast<ASTTemplateKWAndArgsInfo*> - (cast<UnresolvedLookupExpr>(this) + 1); - else - return reinterpret_cast<ASTTemplateKWAndArgsInfo*> - (cast<UnresolvedMemberExpr>(this) + 1); -} /// \brief Represents an expression that computes the length of a parameter /// pack. @@ -3482,43 +3620,51 @@ class SizeOfPackExpr : public Expr { /// \brief The length of the parameter pack, if known. /// - /// When this expression is value-dependent, the length of the parameter pack - /// is unknown. When this expression is not value-dependent, the length is - /// known. + /// When this expression is not value-dependent, this is the length of + /// the pack. When the expression was parsed rather than instantiated + /// (and thus is value-dependent), this is zero. + /// + /// After partial substitution into a sizeof...(X) expression (for instance, + /// within an alias template or during function template argument deduction), + /// we store a trailing array of partially-substituted TemplateArguments, + /// and this is the length of that array. unsigned Length; - /// \brief The parameter pack itself. + /// \brief The parameter pack. NamedDecl *Pack; friend class ASTStmtReader; friend class ASTStmtWriter; -public: - /// \brief Create a value-dependent expression that computes the length of - /// the given parameter pack. - SizeOfPackExpr(QualType SizeType, SourceLocation OperatorLoc, NamedDecl *Pack, - SourceLocation PackLoc, SourceLocation RParenLoc) - : Expr(SizeOfPackExprClass, SizeType, VK_RValue, OK_Ordinary, - /*TypeDependent=*/false, /*ValueDependent=*/true, - /*InstantiationDependent=*/true, - /*ContainsUnexpandedParameterPack=*/false), - OperatorLoc(OperatorLoc), PackLoc(PackLoc), RParenLoc(RParenLoc), - Length(0), Pack(Pack) { } - /// \brief Create an expression that computes the length of - /// the given parameter pack, which is already known. + /// the given parameter pack. SizeOfPackExpr(QualType SizeType, SourceLocation OperatorLoc, NamedDecl *Pack, SourceLocation PackLoc, SourceLocation RParenLoc, - unsigned Length) - : Expr(SizeOfPackExprClass, SizeType, VK_RValue, OK_Ordinary, - /*TypeDependent=*/false, /*ValueDependent=*/false, - /*InstantiationDependent=*/false, - /*ContainsUnexpandedParameterPack=*/false), - OperatorLoc(OperatorLoc), PackLoc(PackLoc), RParenLoc(RParenLoc), - Length(Length), Pack(Pack) { } + Optional<unsigned> Length, ArrayRef<TemplateArgument> PartialArgs) + : Expr(SizeOfPackExprClass, SizeType, VK_RValue, OK_Ordinary, + /*TypeDependent=*/false, /*ValueDependent=*/!Length, + /*InstantiationDependent=*/!Length, + /*ContainsUnexpandedParameterPack=*/false), + OperatorLoc(OperatorLoc), PackLoc(PackLoc), RParenLoc(RParenLoc), + Length(Length ? *Length : PartialArgs.size()), Pack(Pack) { + assert((!Length || PartialArgs.empty()) && + "have partial args for non-dependent sizeof... expression"); + TemplateArgument *Args = reinterpret_cast<TemplateArgument *>(this + 1); + std::uninitialized_copy(PartialArgs.begin(), PartialArgs.end(), Args); + } /// \brief Create an empty expression. - SizeOfPackExpr(EmptyShell Empty) : Expr(SizeOfPackExprClass, Empty) { } + SizeOfPackExpr(EmptyShell Empty, unsigned NumPartialArgs) + : Expr(SizeOfPackExprClass, Empty), Length(NumPartialArgs), Pack() {} + +public: + static SizeOfPackExpr *Create(ASTContext &Context, SourceLocation OperatorLoc, + NamedDecl *Pack, SourceLocation PackLoc, + SourceLocation RParenLoc, + Optional<unsigned> Length = None, + ArrayRef<TemplateArgument> PartialArgs = None); + static SizeOfPackExpr *CreateDeserialized(ASTContext &Context, + unsigned NumPartialArgs); /// \brief Determine the location of the 'sizeof' keyword. SourceLocation getOperatorLoc() const { return OperatorLoc; } @@ -3542,6 +3688,23 @@ public: return Length; } + /// \brief Determine whether this represents a partially-substituted sizeof... + /// expression, such as is produced for: + /// + /// template<typename ...Ts> using X = int[sizeof...(Ts)]; + /// template<typename ...Us> void f(X<Us..., 1, 2, 3, Us...>); + bool isPartiallySubstituted() const { + return isValueDependent() && Length; + } + + /// \brief Get + ArrayRef<TemplateArgument> getPartialArguments() const { + assert(isPartiallySubstituted()); + const TemplateArgument *Args = + reinterpret_cast<const TemplateArgument *>(this + 1); + return llvm::makeArrayRef(Args, Args + Length); + } + SourceLocation getLocStart() const LLVM_READONLY { return OperatorLoc; } SourceLocation getLocEnd() const LLVM_READONLY { return RParenLoc; } @@ -3550,7 +3713,9 @@ public: } // Iterators - child_range children() { return child_range(); } + child_range children() { + return child_range(child_iterator(), child_iterator()); + } }; /// \brief Represents a reference to a non-type template parameter @@ -3653,7 +3818,9 @@ public: } // Iterators - child_range children() { return child_range(); } + child_range children() { + return child_range(child_iterator(), child_iterator()); + } }; /// \brief Represents a reference to a function parameter pack that has been @@ -3682,7 +3849,7 @@ class FunctionParmPackExpr : public Expr { FunctionParmPackExpr(QualType T, ParmVarDecl *ParamPack, SourceLocation NameLoc, unsigned NumParams, - Decl * const *Params); + ParmVarDecl *const *Params); friend class ASTReader; friend class ASTStmtReader; @@ -3691,7 +3858,7 @@ public: static FunctionParmPackExpr *Create(const ASTContext &Context, QualType T, ParmVarDecl *ParamPack, SourceLocation NameLoc, - ArrayRef<Decl *> Params); + ArrayRef<ParmVarDecl *> Params); static FunctionParmPackExpr *CreateEmpty(const ASTContext &Context, unsigned NumParams); @@ -3720,7 +3887,9 @@ public: return T->getStmtClass() == FunctionParmPackExprClass; } - child_range children() { return child_range(); } + child_range children() { + return child_range(child_iterator(), child_iterator()); + } }; /// \brief Represents a prvalue temporary that is written into memory so that @@ -3901,6 +4070,136 @@ public: child_range children() { return child_range(SubExprs, SubExprs + 2); } }; +/// \brief Represents an expression that might suspend coroutine execution; +/// either a co_await or co_yield expression. +/// +/// Evaluation of this expression first evaluates its 'ready' expression. If +/// that returns 'false': +/// -- execution of the coroutine is suspended +/// -- the 'suspend' expression is evaluated +/// -- if the 'suspend' expression returns 'false', the coroutine is +/// resumed +/// -- otherwise, control passes back to the resumer. +/// If the coroutine is not suspended, or when it is resumed, the 'resume' +/// expression is evaluated, and its result is the result of the overall +/// expression. +class CoroutineSuspendExpr : public Expr { + SourceLocation KeywordLoc; + + enum SubExpr { Common, Ready, Suspend, Resume, Count }; + Stmt *SubExprs[SubExpr::Count]; + + friend class ASTStmtReader; +public: + CoroutineSuspendExpr(StmtClass SC, SourceLocation KeywordLoc, Expr *Common, + Expr *Ready, Expr *Suspend, Expr *Resume) + : Expr(SC, Resume->getType(), Resume->getValueKind(), + Resume->getObjectKind(), Resume->isTypeDependent(), + Resume->isValueDependent(), Common->isInstantiationDependent(), + Common->containsUnexpandedParameterPack()), + KeywordLoc(KeywordLoc) { + SubExprs[SubExpr::Common] = Common; + SubExprs[SubExpr::Ready] = Ready; + SubExprs[SubExpr::Suspend] = Suspend; + SubExprs[SubExpr::Resume] = Resume; + } + CoroutineSuspendExpr(StmtClass SC, SourceLocation KeywordLoc, QualType Ty, + Expr *Common) + : Expr(SC, Ty, VK_RValue, OK_Ordinary, true, true, true, + Common->containsUnexpandedParameterPack()), + KeywordLoc(KeywordLoc) { + assert(Common->isTypeDependent() && Ty->isDependentType() && + "wrong constructor for non-dependent co_await/co_yield expression"); + SubExprs[SubExpr::Common] = Common; + SubExprs[SubExpr::Ready] = nullptr; + SubExprs[SubExpr::Suspend] = nullptr; + SubExprs[SubExpr::Resume] = nullptr; + } + CoroutineSuspendExpr(StmtClass SC, EmptyShell Empty) : Expr(SC, Empty) { + SubExprs[SubExpr::Common] = nullptr; + SubExprs[SubExpr::Ready] = nullptr; + SubExprs[SubExpr::Suspend] = nullptr; + SubExprs[SubExpr::Resume] = nullptr; + } + + SourceLocation getKeywordLoc() const { return KeywordLoc; } + Expr *getCommonExpr() const { + return static_cast<Expr*>(SubExprs[SubExpr::Common]); + } + + Expr *getReadyExpr() const { + return static_cast<Expr*>(SubExprs[SubExpr::Ready]); + } + Expr *getSuspendExpr() const { + return static_cast<Expr*>(SubExprs[SubExpr::Suspend]); + } + Expr *getResumeExpr() const { + return static_cast<Expr*>(SubExprs[SubExpr::Resume]); + } + + SourceLocation getLocStart() const LLVM_READONLY { + return KeywordLoc; + } + SourceLocation getLocEnd() const LLVM_READONLY { + return getCommonExpr()->getLocEnd(); + } + + child_range children() { + return child_range(SubExprs, SubExprs + SubExpr::Count); + } + + static bool classof(const Stmt *T) { + return T->getStmtClass() == CoawaitExprClass || + T->getStmtClass() == CoyieldExprClass; + } +}; + +/// \brief Represents a 'co_await' expression. +class CoawaitExpr : public CoroutineSuspendExpr { + friend class ASTStmtReader; +public: + CoawaitExpr(SourceLocation CoawaitLoc, Expr *Operand, Expr *Ready, + Expr *Suspend, Expr *Resume) + : CoroutineSuspendExpr(CoawaitExprClass, CoawaitLoc, Operand, Ready, + Suspend, Resume) {} + CoawaitExpr(SourceLocation CoawaitLoc, QualType Ty, Expr *Operand) + : CoroutineSuspendExpr(CoawaitExprClass, CoawaitLoc, Ty, Operand) {} + CoawaitExpr(EmptyShell Empty) + : CoroutineSuspendExpr(CoawaitExprClass, Empty) {} + + Expr *getOperand() const { + // FIXME: Dig out the actual operand or store it. + return getCommonExpr(); + } + + static bool classof(const Stmt *T) { + return T->getStmtClass() == CoawaitExprClass; + } +}; + +/// \brief Represents a 'co_yield' expression. +class CoyieldExpr : public CoroutineSuspendExpr { + friend class ASTStmtReader; +public: + CoyieldExpr(SourceLocation CoyieldLoc, Expr *Operand, Expr *Ready, + Expr *Suspend, Expr *Resume) + : CoroutineSuspendExpr(CoyieldExprClass, CoyieldLoc, Operand, Ready, + Suspend, Resume) {} + CoyieldExpr(SourceLocation CoyieldLoc, QualType Ty, Expr *Operand) + : CoroutineSuspendExpr(CoyieldExprClass, CoyieldLoc, Ty, Operand) {} + CoyieldExpr(EmptyShell Empty) + : CoroutineSuspendExpr(CoyieldExprClass, Empty) {} + + Expr *getOperand() const { + // FIXME: Dig out the actual operand or store it. + return getCommonExpr(); + } + + static bool classof(const Stmt *T) { + return T->getStmtClass() == CoyieldExprClass; + } +}; + } // end namespace clang #endif diff --git a/contrib/llvm/tools/clang/include/clang/AST/ExprObjC.h b/contrib/llvm/tools/clang/include/clang/AST/ExprObjC.h index f28e519..38fa718 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/ExprObjC.h +++ b/contrib/llvm/tools/clang/include/clang/AST/ExprObjC.h @@ -82,7 +82,9 @@ public: } // Iterators - child_range children() { return child_range(); } + child_range children() { + return child_range(child_iterator(), child_iterator()); + } }; /// ObjCBoxedExpr - used for generalized expression boxing. @@ -341,6 +343,8 @@ public: child_range children() { // Note: we're taking advantage of the layout of the KeyValuePair struct // here. If that struct changes, this code will need to change as well. + static_assert(sizeof(KeyValuePair) == sizeof(Stmt *) * 2, + "KeyValuePair is expected size"); return child_range(reinterpret_cast<Stmt **>(this + 1), reinterpret_cast<Stmt **>(this + 1) + NumElements * 2); } @@ -389,7 +393,9 @@ public: } // Iterators - child_range children() { return child_range(); } + child_range children() { + return child_range(child_iterator(), child_iterator()); + } }; /// ObjCSelectorExpr used for \@selector in Objective-C. @@ -424,7 +430,9 @@ public: } // Iterators - child_range children() { return child_range(); } + child_range children() { + return child_range(child_iterator(), child_iterator()); + } }; /// ObjCProtocolExpr used for protocol expression in Objective-C. @@ -464,7 +472,9 @@ public: } // Iterators - child_range children() { return child_range(); } + child_range children() { + return child_range(child_iterator(), child_iterator()); + } friend class ASTStmtReader; friend class ASTStmtWriter; @@ -713,7 +723,7 @@ public: Stmt **begin = reinterpret_cast<Stmt**>(&Receiver); // hack! return child_range(begin, begin+1); } - return child_range(); + return child_range(child_iterator(), child_iterator()); } private: @@ -1350,6 +1360,14 @@ public: typedef ExprIterator arg_iterator; typedef ConstExprIterator const_arg_iterator; + llvm::iterator_range<arg_iterator> arguments() { + return llvm::make_range(arg_begin(), arg_end()); + } + + llvm::iterator_range<const_arg_iterator> arguments() const { + return llvm::make_range(arg_begin(), arg_end()); + } + arg_iterator arg_begin() { return reinterpret_cast<Stmt **>(getArgs()); } arg_iterator arg_end() { return reinterpret_cast<Stmt **>(getArgs() + NumArgs); @@ -1503,11 +1521,15 @@ public: /// \code /// NSString *str = (__bridge_transfer NSString *)CFCreateString(); /// \endcode -class ObjCBridgedCastExpr : public ExplicitCastExpr { +class ObjCBridgedCastExpr final + : public ExplicitCastExpr, + private llvm::TrailingObjects<ObjCBridgedCastExpr, CXXBaseSpecifier *> { SourceLocation LParenLoc; SourceLocation BridgeKeywordLoc; unsigned Kind : 2; - + + friend TrailingObjects; + friend class CastExpr; friend class ASTStmtReader; friend class ASTStmtWriter; diff --git a/contrib/llvm/tools/clang/include/clang/AST/ExprOpenMP.h b/contrib/llvm/tools/clang/include/clang/AST/ExprOpenMP.h new file mode 100644 index 0000000..2d71a3a --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/AST/ExprOpenMP.h @@ -0,0 +1,129 @@ +//===--- ExprOpenMP.h - Classes for representing expressions ----*- 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 Expr interface and subclasses. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_AST_EXPROPENMP_H +#define LLVM_CLANG_AST_EXPROPENMP_H + +#include "clang/AST/Expr.h" + +namespace clang { +/// \brief OpenMP 4.0 [2.4, Array Sections]. +/// To specify an array section in an OpenMP construct, array subscript +/// expressions are extended with the following syntax: +/// \code +/// [ lower-bound : length ] +/// [ lower-bound : ] +/// [ : length ] +/// [ : ] +/// \endcode +/// The array section must be a subset of the original array. +/// Array sections are allowed on multidimensional arrays. Base language array +/// subscript expressions can be used to specify length-one dimensions of +/// multidimensional array sections. +/// The lower-bound and length are integral type expressions. When evaluated +/// they represent a set of integer values as follows: +/// \code +/// { lower-bound, lower-bound + 1, lower-bound + 2,... , lower-bound + length - +/// 1 } +/// \endcode +/// The lower-bound and length must evaluate to non-negative integers. +/// When the size of the array dimension is not known, the length must be +/// specified explicitly. +/// When the length is absent, it defaults to the size of the array dimension +/// minus the lower-bound. +/// When the lower-bound is absent it defaults to 0. +class OMPArraySectionExpr : public Expr { + enum { BASE, LOWER_BOUND, LENGTH, END_EXPR }; + Stmt *SubExprs[END_EXPR]; + SourceLocation ColonLoc; + SourceLocation RBracketLoc; + +public: + OMPArraySectionExpr(Expr *Base, Expr *LowerBound, Expr *Length, QualType Type, + ExprValueKind VK, ExprObjectKind OK, + SourceLocation ColonLoc, SourceLocation RBracketLoc) + : Expr( + OMPArraySectionExprClass, Type, VK, OK, + Base->isTypeDependent() || + (LowerBound && LowerBound->isTypeDependent()) || + (Length && Length->isTypeDependent()), + Base->isValueDependent() || + (LowerBound && LowerBound->isValueDependent()) || + (Length && Length->isValueDependent()), + Base->isInstantiationDependent() || + (LowerBound && LowerBound->isInstantiationDependent()) || + (Length && Length->isInstantiationDependent()), + Base->containsUnexpandedParameterPack() || + (LowerBound && LowerBound->containsUnexpandedParameterPack()) || + (Length && Length->containsUnexpandedParameterPack())), + ColonLoc(ColonLoc), RBracketLoc(RBracketLoc) { + SubExprs[BASE] = Base; + SubExprs[LOWER_BOUND] = LowerBound; + SubExprs[LENGTH] = Length; + } + + /// \brief Create an empty array section expression. + explicit OMPArraySectionExpr(EmptyShell Shell) + : Expr(OMPArraySectionExprClass, Shell) {} + + /// An array section can be written only as Base[LowerBound:Length]. + + /// \brief Get base of the array section. + Expr *getBase() { return cast<Expr>(SubExprs[BASE]); } + const Expr *getBase() const { return cast<Expr>(SubExprs[BASE]); } + /// \brief Set base of the array section. + void setBase(Expr *E) { SubExprs[BASE] = E; } + + /// \brief Return original type of the base expression for array section. + static QualType getBaseOriginalType(Expr *Base); + + /// \brief Get lower bound of array section. + Expr *getLowerBound() { return cast_or_null<Expr>(SubExprs[LOWER_BOUND]); } + const Expr *getLowerBound() const { + return cast_or_null<Expr>(SubExprs[LOWER_BOUND]); + } + /// \brief Set lower bound of the array section. + void setLowerBound(Expr *E) { SubExprs[LOWER_BOUND] = E; } + + /// \brief Get length of array section. + Expr *getLength() { return cast_or_null<Expr>(SubExprs[LENGTH]); } + const Expr *getLength() const { return cast_or_null<Expr>(SubExprs[LENGTH]); } + /// \brief Set length of the array section. + void setLength(Expr *E) { SubExprs[LENGTH] = E; } + + SourceLocation getLocStart() const LLVM_READONLY { + return getBase()->getLocStart(); + } + SourceLocation getLocEnd() const LLVM_READONLY { return RBracketLoc; } + + SourceLocation getColonLoc() const { return ColonLoc; } + void setColonLoc(SourceLocation L) { ColonLoc = L; } + + SourceLocation getRBracketLoc() const { return RBracketLoc; } + void setRBracketLoc(SourceLocation L) { RBracketLoc = L; } + + SourceLocation getExprLoc() const LLVM_READONLY { + return getBase()->getExprLoc(); + } + + static bool classof(const Stmt *T) { + return T->getStmtClass() == OMPArraySectionExprClass; + } + + child_range children() { + return child_range(&SubExprs[BASE], &SubExprs[END_EXPR]); + } +}; +} // end namespace clang + +#endif diff --git a/contrib/llvm/tools/clang/include/clang/AST/ExternalASTSource.h b/contrib/llvm/tools/clang/include/clang/AST/ExternalASTSource.h index 08c2e0c..81cf631 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/ExternalASTSource.h +++ b/contrib/llvm/tools/clang/include/clang/AST/ExternalASTSource.h @@ -33,20 +33,6 @@ class Selector; class Stmt; class TagDecl; -/// \brief Enumeration describing the result of loading information from -/// an external source. -enum ExternalLoadResult { - /// \brief Loading the external information has succeeded. - ELR_Success, - - /// \brief Loading the external information has failed. - ELR_Failure, - - /// \brief The external information has already been loaded, and therefore - /// no additional processing is required. - ELR_AlreadyLoaded -}; - /// \brief Abstract interface for external sources of AST nodes. /// /// External AST sources provide AST nodes constructed from some @@ -156,47 +142,50 @@ public: /// \brief Retrieve the module that corresponds to the given module ID. virtual Module *getModule(unsigned ID) { return nullptr; } - /// \brief Holds everything needed to generate debug info for an - /// imported module or precompiled header file. - struct ASTSourceDescriptor { - std::string ModuleName; - std::string Path; - std::string ASTFile; - uint64_t Signature; + /// Abstracts clang modules and precompiled header files and holds + /// everything needed to generate debug info for an imported module + /// or PCH. + class ASTSourceDescriptor { + StringRef PCHModuleName; + StringRef Path; + StringRef ASTFile; + uint64_t Signature = 0; + const Module *ClangModule = nullptr; + + public: + ASTSourceDescriptor(){}; + ASTSourceDescriptor(StringRef Name, StringRef Path, StringRef ASTFile, + uint64_t Signature) + : PCHModuleName(std::move(Name)), Path(std::move(Path)), + ASTFile(std::move(ASTFile)), Signature(Signature){}; + ASTSourceDescriptor(const Module &M); + std::string getModuleName() const; + StringRef getPath() const { return Path; } + StringRef getASTFile() const { return ASTFile; } + uint64_t getSignature() const { return Signature; } + const Module *getModuleOrNull() const { return ClangModule; } }; - /// \brief Return a descriptor for the corresponding module, if one exists. + /// Return a descriptor for the corresponding module, if one exists. virtual llvm::Optional<ASTSourceDescriptor> getSourceDescriptor(unsigned ID); - /// \brief Return a descriptor for the module. - virtual ASTSourceDescriptor getSourceDescriptor(const Module &M); /// \brief Finds all declarations lexically contained within the given /// DeclContext, after applying an optional filter predicate. /// - /// \param isKindWeWant a predicate function that returns true if the passed - /// declaration kind is one we are looking for. If NULL, all declarations - /// are returned. - /// - /// \return an indication of whether the load succeeded or failed. + /// \param IsKindWeWant a predicate function that returns true if the passed + /// declaration kind is one we are looking for. /// /// The default implementation of this method is a no-op. - virtual ExternalLoadResult FindExternalLexicalDecls(const DeclContext *DC, - bool (*isKindWeWant)(Decl::Kind), - SmallVectorImpl<Decl*> &Result); + virtual void + FindExternalLexicalDecls(const DeclContext *DC, + llvm::function_ref<bool(Decl::Kind)> IsKindWeWant, + SmallVectorImpl<Decl *> &Result); /// \brief Finds all declarations lexically contained within the given /// DeclContext. - /// - /// \return true if an error occurred - ExternalLoadResult FindExternalLexicalDecls(const DeclContext *DC, - SmallVectorImpl<Decl*> &Result) { - return FindExternalLexicalDecls(DC, nullptr, Result); - } - - template <typename DeclTy> - ExternalLoadResult FindExternalLexicalDeclsBy(const DeclContext *DC, - SmallVectorImpl<Decl*> &Result) { - return FindExternalLexicalDecls(DC, DeclTy::classofKind, Result); + void FindExternalLexicalDecls(const DeclContext *DC, + SmallVectorImpl<Decl *> &Result) { + FindExternalLexicalDecls(DC, [](Decl::Kind) { return true; }, Result); } /// \brief Get the decls that are contained in a file in the Offset/Length diff --git a/contrib/llvm/tools/clang/include/clang/AST/Mangle.h b/contrib/llvm/tools/clang/include/clang/AST/Mangle.h index 735ae11..7b725b6 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/Mangle.h +++ b/contrib/llvm/tools/clang/include/clang/AST/Mangle.h @@ -144,9 +144,6 @@ public: /// across translation units so it can be used with LTO. virtual void mangleTypeName(QualType T, raw_ostream &) = 0; - virtual void mangleCXXVTableBitSet(const CXXRecordDecl *RD, - raw_ostream &) = 0; - /// @} }; diff --git a/contrib/llvm/tools/clang/include/clang/AST/NestedNameSpecifier.h b/contrib/llvm/tools/clang/include/clang/AST/NestedNameSpecifier.h index 4da17b0..b1ff9bd 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/NestedNameSpecifier.h +++ b/contrib/llvm/tools/clang/include/clang/AST/NestedNameSpecifier.h @@ -217,7 +217,8 @@ public: /// \brief Dump the nested name specifier to standard output to aid /// in debugging. - void dump(const LangOptions &LO); + void dump(const LangOptions &LO) const; + void dump() const; }; /// \brief A C++ nested-name-specifier augmented with source location diff --git a/contrib/llvm/tools/clang/include/clang/AST/OpenMPClause.h b/contrib/llvm/tools/clang/include/clang/AST/OpenMPClause.h index fcfa1dd..bb982f3 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/OpenMPClause.h +++ b/contrib/llvm/tools/clang/include/clang/AST/OpenMPClause.h @@ -57,9 +57,15 @@ public: bool isImplicit() const { return StartLoc.isInvalid(); } - StmtRange children(); - ConstStmtRange children() const { - return const_cast<OMPClause *>(this)->children(); + typedef StmtIterator child_iterator; + typedef ConstStmtIterator const_child_iterator; + typedef llvm::iterator_range<child_iterator> child_range; + typedef llvm::iterator_range<const_child_iterator> const_child_range; + + child_range children(); + const_child_range children() const { + auto Children = const_cast<OMPClause *>(this)->children(); + return const_child_range(Children.begin(), Children.end()); } static bool classof(const OMPClause *) { return true; } }; @@ -146,10 +152,10 @@ public: /// \brief This represents 'if' clause in the '#pragma omp ...' directive. /// /// \code -/// #pragma omp parallel if(a > 5) +/// #pragma omp parallel if(parallel:a > 5) /// \endcode -/// In this example directive '#pragma omp parallel' has simple 'if' -/// clause with condition 'a > 5'. +/// In this example directive '#pragma omp parallel' has simple 'if' clause with +/// condition 'a > 5' and directive name modifier 'parallel'. /// class OMPIfClause : public OMPClause { friend class OMPClauseReader; @@ -157,43 +163,73 @@ class OMPIfClause : public OMPClause { SourceLocation LParenLoc; /// \brief Condition of the 'if' clause. Stmt *Condition; + /// \brief Location of ':' (if any). + SourceLocation ColonLoc; + /// \brief Directive name modifier for the clause. + OpenMPDirectiveKind NameModifier; + /// \brief Name modifier location. + SourceLocation NameModifierLoc; /// \brief Set condition. /// void setCondition(Expr *Cond) { Condition = Cond; } + /// \brief Set directive name modifier for the clause. + /// + void setNameModifier(OpenMPDirectiveKind NM) { NameModifier = NM; } + /// \brief Set location of directive name modifier for the clause. + /// + void setNameModifierLoc(SourceLocation Loc) { NameModifierLoc = Loc; } + /// \brief Set location of ':'. + /// + void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; } public: /// \brief Build 'if' clause with condition \a Cond. /// + /// \param NameModifier [OpenMP 4.1] Directive name modifier of clause. + /// \param Cond Condition of the clause. /// \param StartLoc Starting location of the clause. /// \param LParenLoc Location of '('. - /// \param Cond Condition of the clause. + /// \param NameModifierLoc Location of directive name modifier. + /// \param ColonLoc [OpenMP 4.1] Location of ':'. /// \param EndLoc Ending location of the clause. /// - OMPIfClause(Expr *Cond, SourceLocation StartLoc, SourceLocation LParenLoc, + OMPIfClause(OpenMPDirectiveKind NameModifier, Expr *Cond, + SourceLocation StartLoc, SourceLocation LParenLoc, + SourceLocation NameModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc) : OMPClause(OMPC_if, StartLoc, EndLoc), LParenLoc(LParenLoc), - Condition(Cond) {} + Condition(Cond), ColonLoc(ColonLoc), NameModifier(NameModifier), + NameModifierLoc(NameModifierLoc) {} /// \brief Build an empty clause. /// OMPIfClause() - : OMPClause(OMPC_if, SourceLocation(), SourceLocation()), - LParenLoc(SourceLocation()), Condition(nullptr) {} + : OMPClause(OMPC_if, SourceLocation(), SourceLocation()), LParenLoc(), + Condition(nullptr), ColonLoc(), NameModifier(OMPD_unknown), + NameModifierLoc() {} /// \brief Sets the location of '('. void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } /// \brief Returns the location of '('. SourceLocation getLParenLoc() const { return LParenLoc; } + /// \brief Return the location of ':'. + SourceLocation getColonLoc() const { return ColonLoc; } + /// \brief Returns condition. Expr *getCondition() const { return cast_or_null<Expr>(Condition); } + /// \brief Return directive name modifier associated with the clause. + OpenMPDirectiveKind getNameModifier() const { return NameModifier; } + + /// \brief Return the location of directive name modifier. + SourceLocation getNameModifierLoc() const { return NameModifierLoc; } static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_if; } - StmtRange children() { return StmtRange(&Condition, &Condition + 1); } + child_range children() { return child_range(&Condition, &Condition + 1); } }; /// \brief This represents 'final' clause in the '#pragma omp ...' directive. @@ -246,7 +282,7 @@ public: return T->getClauseKind() == OMPC_final; } - StmtRange children() { return StmtRange(&Condition, &Condition + 1); } + child_range children() { return child_range(&Condition, &Condition + 1); } }; /// \brief This represents 'num_threads' clause in the '#pragma omp ...' @@ -300,7 +336,7 @@ public: return T->getClauseKind() == OMPC_num_threads; } - StmtRange children() { return StmtRange(&NumThreads, &NumThreads + 1); } + child_range children() { return child_range(&NumThreads, &NumThreads + 1); } }; /// \brief This represents 'safelen' clause in the '#pragma omp ...' @@ -356,7 +392,62 @@ public: return T->getClauseKind() == OMPC_safelen; } - StmtRange children() { return StmtRange(&Safelen, &Safelen + 1); } + child_range children() { return child_range(&Safelen, &Safelen + 1); } +}; + +/// \brief This represents 'simdlen' clause in the '#pragma omp ...' +/// directive. +/// +/// \code +/// #pragma omp simd simdlen(4) +/// \endcode +/// In this example directive '#pragma omp simd' has clause 'simdlen' +/// with single expression '4'. +/// If the 'simdlen' clause is used then it specifies the preferred number of +/// iterations to be executed concurrently. The parameter of the 'simdlen' +/// clause must be a constant positive integer expression. +/// +class OMPSimdlenClause : public OMPClause { + friend class OMPClauseReader; + /// \brief Location of '('. + SourceLocation LParenLoc; + /// \brief Safe iteration space distance. + Stmt *Simdlen; + + /// \brief Set simdlen. + void setSimdlen(Expr *Len) { Simdlen = Len; } + +public: + /// \brief Build 'simdlen' clause. + /// + /// \param Len Expression associated with this clause. + /// \param StartLoc Starting location of the clause. + /// \param EndLoc Ending location of the clause. + /// + OMPSimdlenClause(Expr *Len, SourceLocation StartLoc, SourceLocation LParenLoc, + SourceLocation EndLoc) + : OMPClause(OMPC_simdlen, StartLoc, EndLoc), LParenLoc(LParenLoc), + Simdlen(Len) {} + + /// \brief Build an empty clause. + /// + explicit OMPSimdlenClause() + : OMPClause(OMPC_simdlen, SourceLocation(), SourceLocation()), + LParenLoc(SourceLocation()), Simdlen(nullptr) {} + + /// \brief Sets the location of '('. + void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } + /// \brief Returns the location of '('. + SourceLocation getLParenLoc() const { return LParenLoc; } + + /// \brief Return safe iteration space distance. + Expr *getSimdlen() const { return cast_or_null<Expr>(Simdlen); } + + static bool classof(const OMPClause *T) { + return T->getClauseKind() == OMPC_simdlen; + } + + child_range children() { return child_range(&Simdlen, &Simdlen + 1); } }; /// \brief This represents 'collapse' clause in the '#pragma omp ...' @@ -412,7 +503,7 @@ public: return T->getClauseKind() == OMPC_collapse; } - StmtRange children() { return StmtRange(&NumForLoops, &NumForLoops + 1); } + child_range children() { return child_range(&NumForLoops, &NumForLoops + 1); } }; /// \brief This represents 'default' clause in the '#pragma omp ...' directive. @@ -481,7 +572,9 @@ public: return T->getClauseKind() == OMPC_default; } - StmtRange children() { return StmtRange(); } + child_range children() { + return child_range(child_iterator(), child_iterator()); + } }; /// \brief This represents 'proc_bind' clause in the '#pragma omp ...' @@ -552,7 +645,9 @@ public: return T->getClauseKind() == OMPC_proc_bind; } - StmtRange children() { return StmtRange(); } + child_range children() { + return child_range(child_iterator(), child_iterator()); + } }; /// \brief This represents 'schedule' clause in the '#pragma omp ...' directive. @@ -569,6 +664,11 @@ class OMPScheduleClause : public OMPClause { SourceLocation LParenLoc; /// \brief A kind of the 'schedule' clause. OpenMPScheduleClauseKind Kind; + /// \brief Modifiers for 'schedule' clause. + enum {FIRST, SECOND, NUM_MODIFIERS}; + OpenMPScheduleClauseModifier Modifiers[NUM_MODIFIERS]; + /// \brief Locations of modifiers. + SourceLocation ModifiersLoc[NUM_MODIFIERS]; /// \brief Start location of the schedule ind in source code. SourceLocation KindLoc; /// \brief Location of ',' (if any). @@ -583,6 +683,42 @@ class OMPScheduleClause : public OMPClause { /// \param K Schedule kind. /// void setScheduleKind(OpenMPScheduleClauseKind K) { Kind = K; } + /// \brief Set the first schedule modifier. + /// + /// \param M Schedule modifier. + /// + void setFirstScheduleModifier(OpenMPScheduleClauseModifier M) { + Modifiers[FIRST] = M; + } + /// \brief Set the second schedule modifier. + /// + /// \param M Schedule modifier. + /// + void setSecondScheduleModifier(OpenMPScheduleClauseModifier M) { + Modifiers[SECOND] = M; + } + /// \brief Set location of the first schedule modifier. + /// + void setFirstScheduleModifierLoc(SourceLocation Loc) { + ModifiersLoc[FIRST] = Loc; + } + /// \brief Set location of the second schedule modifier. + /// + void setSecondScheduleModifierLoc(SourceLocation Loc) { + ModifiersLoc[SECOND] = Loc; + } + /// \brief Set schedule modifier location. + /// + /// \param M Schedule modifier location. + /// + void setScheduleModifer(OpenMPScheduleClauseModifier M) { + if (Modifiers[FIRST] == OMPC_SCHEDULE_MODIFIER_unknown) + Modifiers[FIRST] = M; + else { + assert(Modifiers[SECOND] == OMPC_SCHEDULE_MODIFIER_unknown); + Modifiers[SECOND] = M; + } + } /// \brief Sets the location of '('. /// /// \param Loc Location of '('. @@ -621,15 +757,25 @@ public: /// \param Kind Schedule kind. /// \param ChunkSize Chunk size. /// \param HelperChunkSize Helper chunk size for combined directives. + /// \param M1 The first modifier applied to 'schedule' clause. + /// \param M1Loc Location of the first modifier + /// \param M2 The second modifier applied to 'schedule' clause. + /// \param M2Loc Location of the second modifier /// OMPScheduleClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation KLoc, SourceLocation CommaLoc, SourceLocation EndLoc, OpenMPScheduleClauseKind Kind, - Expr *ChunkSize, Expr *HelperChunkSize) + Expr *ChunkSize, Expr *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; + Modifiers[FIRST] = M1; + Modifiers[SECOND] = M2; + ModifiersLoc[FIRST] = M1Loc; + ModifiersLoc[SECOND] = M2Loc; } /// \brief Build an empty clause. @@ -639,17 +785,39 @@ public: Kind(OMPC_SCHEDULE_unknown) { ChunkSizes[CHUNK_SIZE] = nullptr; ChunkSizes[HELPER_CHUNK_SIZE] = nullptr; + Modifiers[FIRST] = OMPC_SCHEDULE_MODIFIER_unknown; + Modifiers[SECOND] = OMPC_SCHEDULE_MODIFIER_unknown; } /// \brief Get kind of the clause. /// OpenMPScheduleClauseKind getScheduleKind() const { return Kind; } + /// \brief Get the first modifier of the clause. + /// + OpenMPScheduleClauseModifier getFirstScheduleModifier() const { + return Modifiers[FIRST]; + } + /// \brief Get the second modifier of the clause. + /// + OpenMPScheduleClauseModifier getSecondScheduleModifier() const { + return Modifiers[SECOND]; + } /// \brief Get location of '('. /// SourceLocation getLParenLoc() { return LParenLoc; } /// \brief Get kind location. /// SourceLocation getScheduleKindLoc() { return KindLoc; } + /// \brief Get the first modifier location. + /// + SourceLocation getFirstScheduleModifierLoc() const { + return ModifiersLoc[FIRST]; + } + /// \brief Get the second modifier location. + /// + SourceLocation getSecondScheduleModifierLoc() const { + return ModifiersLoc[SECOND]; + } /// \brief Get location of ','. /// SourceLocation getCommaLoc() { return CommaLoc; } @@ -676,38 +844,61 @@ public: return T->getClauseKind() == OMPC_schedule; } - StmtRange children() { - return StmtRange(&ChunkSizes[CHUNK_SIZE], &ChunkSizes[CHUNK_SIZE] + 1); + child_range children() { + return child_range(&ChunkSizes[CHUNK_SIZE], &ChunkSizes[CHUNK_SIZE] + 1); } }; /// \brief This represents 'ordered' clause in the '#pragma omp ...' directive. /// /// \code -/// #pragma omp for ordered +/// #pragma omp for ordered (2) /// \endcode -/// In this example directive '#pragma omp for' has 'ordered' clause. +/// In this example directive '#pragma omp for' has 'ordered' clause with +/// parameter 2. /// class OMPOrderedClause : public OMPClause { + friend class OMPClauseReader; + /// \brief Location of '('. + SourceLocation LParenLoc; + /// \brief Number of for-loops. + Stmt *NumForLoops; + + /// \brief Set the number of associated for-loops. + void setNumForLoops(Expr *Num) { NumForLoops = Num; } + public: /// \brief Build 'ordered' clause. /// + /// \param Num Expression, possibly associated with this clause. /// \param StartLoc Starting location of the clause. + /// \param LParenLoc Location of '('. /// \param EndLoc Ending location of the clause. /// - OMPOrderedClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(OMPC_ordered, StartLoc, EndLoc) {} + OMPOrderedClause(Expr *Num, SourceLocation StartLoc, + SourceLocation LParenLoc, SourceLocation EndLoc) + : OMPClause(OMPC_ordered, StartLoc, EndLoc), LParenLoc(LParenLoc), + NumForLoops(Num) {} /// \brief Build an empty clause. /// - OMPOrderedClause() - : OMPClause(OMPC_ordered, SourceLocation(), SourceLocation()) {} + explicit OMPOrderedClause() + : OMPClause(OMPC_ordered, SourceLocation(), SourceLocation()), + LParenLoc(SourceLocation()), NumForLoops(nullptr) {} + + /// \brief Sets the location of '('. + void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } + /// \brief Returns the location of '('. + SourceLocation getLParenLoc() const { return LParenLoc; } + + /// \brief Return the number of associated for-loops. + Expr *getNumForLoops() const { return cast_or_null<Expr>(NumForLoops); } static bool classof(const OMPClause *T) { return T->getClauseKind() == OMPC_ordered; } - StmtRange children() { return StmtRange(); } + child_range children() { return child_range(&NumForLoops, &NumForLoops + 1); } }; /// \brief This represents 'nowait' clause in the '#pragma omp ...' directive. @@ -736,7 +927,9 @@ public: return T->getClauseKind() == OMPC_nowait; } - StmtRange children() { return StmtRange(); } + child_range children() { + return child_range(child_iterator(), child_iterator()); + } }; /// \brief This represents 'untied' clause in the '#pragma omp ...' directive. @@ -765,7 +958,9 @@ public: return T->getClauseKind() == OMPC_untied; } - StmtRange children() { return StmtRange(); } + child_range children() { + return child_range(child_iterator(), child_iterator()); + } }; /// \brief This represents 'mergeable' clause in the '#pragma omp ...' @@ -795,7 +990,9 @@ public: return T->getClauseKind() == OMPC_mergeable; } - StmtRange children() { return StmtRange(); } + child_range children() { + return child_range(child_iterator(), child_iterator()); + } }; /// \brief This represents 'read' clause in the '#pragma omp atomic' directive. @@ -823,7 +1020,9 @@ public: return T->getClauseKind() == OMPC_read; } - StmtRange children() { return StmtRange(); } + child_range children() { + return child_range(child_iterator(), child_iterator()); + } }; /// \brief This represents 'write' clause in the '#pragma omp atomic' directive. @@ -852,7 +1051,9 @@ public: return T->getClauseKind() == OMPC_write; } - StmtRange children() { return StmtRange(); } + child_range children() { + return child_range(child_iterator(), child_iterator()); + } }; /// \brief This represents 'update' clause in the '#pragma omp atomic' @@ -882,7 +1083,9 @@ public: return T->getClauseKind() == OMPC_update; } - StmtRange children() { return StmtRange(); } + child_range children() { + return child_range(child_iterator(), child_iterator()); + } }; /// \brief This represents 'capture' clause in the '#pragma omp atomic' @@ -912,7 +1115,9 @@ public: return T->getClauseKind() == OMPC_capture; } - StmtRange children() { return StmtRange(); } + child_range children() { + return child_range(child_iterator(), child_iterator()); + } }; /// \brief This represents 'seq_cst' clause in the '#pragma omp atomic' @@ -942,7 +1147,9 @@ public: return T->getClauseKind() == OMPC_seq_cst; } - StmtRange children() { return StmtRange(); } + child_range children() { + return child_range(child_iterator(), child_iterator()); + } }; /// \brief This represents clause 'private' in the '#pragma omp ...' directives. @@ -1026,9 +1233,9 @@ public: getPrivateCopies().end()); } - StmtRange children() { - return StmtRange(reinterpret_cast<Stmt **>(varlist_begin()), - reinterpret_cast<Stmt **>(varlist_end())); + child_range children() { + return child_range(reinterpret_cast<Stmt **>(varlist_begin()), + reinterpret_cast<Stmt **>(varlist_end())); } static bool classof(const OMPClause *T) { @@ -1147,9 +1354,9 @@ public: return inits_const_range(getInits().begin(), getInits().end()); } - StmtRange children() { - return StmtRange(reinterpret_cast<Stmt **>(varlist_begin()), - reinterpret_cast<Stmt **>(varlist_end())); + child_range children() { + return child_range(reinterpret_cast<Stmt **>(varlist_begin()), + reinterpret_cast<Stmt **>(varlist_end())); } static bool classof(const OMPClause *T) { @@ -1332,9 +1539,9 @@ public: getAssignmentOps().end()); } - StmtRange children() { - return StmtRange(reinterpret_cast<Stmt **>(varlist_begin()), - reinterpret_cast<Stmt **>(varlist_end())); + child_range children() { + return child_range(reinterpret_cast<Stmt **>(varlist_begin()), + reinterpret_cast<Stmt **>(varlist_end())); } static bool classof(const OMPClause *T) { @@ -1391,9 +1598,9 @@ public: /// static OMPSharedClause *CreateEmpty(const ASTContext &C, unsigned N); - StmtRange children() { - return StmtRange(reinterpret_cast<Stmt **>(varlist_begin()), - reinterpret_cast<Stmt **>(varlist_end())); + child_range children() { + return child_range(reinterpret_cast<Stmt **>(varlist_begin()), + reinterpret_cast<Stmt **>(varlist_end())); } static bool classof(const OMPClause *T) { @@ -1455,16 +1662,29 @@ class OMPReductionClause : public OMPVarListClause<OMPReductionClause> { void setQualifierLoc(NestedNameSpecifierLoc NSL) { QualifierLoc = NSL; } /// \brief Set list of helper expressions, required for proper codegen of the + /// clause. These expressions represent private copy of the reduction + /// variable. + void setPrivates(ArrayRef<Expr *> Privates); + + /// \brief Get the list of helper privates. + MutableArrayRef<Expr *> getPrivates() { + return MutableArrayRef<Expr *>(varlist_end(), varlist_size()); + } + ArrayRef<const Expr *> getPrivates() const { + return llvm::makeArrayRef(varlist_end(), varlist_size()); + } + + /// \brief Set list of helper expressions, required for proper codegen of the /// clause. These expressions represent LHS expression in the final /// reduction expression performed by the reduction clause. void setLHSExprs(ArrayRef<Expr *> LHSExprs); /// \brief Get the list of helper LHS expressions. MutableArrayRef<Expr *> getLHSExprs() { - return MutableArrayRef<Expr *>(varlist_end(), varlist_size()); + return MutableArrayRef<Expr *>(getPrivates().end(), varlist_size()); } ArrayRef<const Expr *> getLHSExprs() const { - return llvm::makeArrayRef(varlist_end(), varlist_size()); + return llvm::makeArrayRef(getPrivates().end(), varlist_size()); } /// \brief Set list of helper expressions, required for proper codegen of the @@ -1506,6 +1726,8 @@ public: /// \param VL The variables in the clause. /// \param QualifierLoc The nested-name qualifier with location information /// \param NameInfo The full name info for reduction identifier. + /// \param Privates List of helper expressions for proper generation of + /// private copies. /// \param LHSExprs List of helper expressions for proper generation of /// assignment operation required for copyprivate clause. This list represents /// LHSs of the reduction expressions. @@ -1528,8 +1750,9 @@ public: Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef<Expr *> VL, NestedNameSpecifierLoc QualifierLoc, - const DeclarationNameInfo &NameInfo, ArrayRef<Expr *> LHSExprs, - ArrayRef<Expr *> RHSExprs, ArrayRef<Expr *> ReductionOps); + const DeclarationNameInfo &NameInfo, ArrayRef<Expr *> Privates, + ArrayRef<Expr *> LHSExprs, ArrayRef<Expr *> RHSExprs, + ArrayRef<Expr *> ReductionOps); /// \brief Creates an empty clause with the place for \a N variables. /// /// \param C AST context. @@ -1550,6 +1773,12 @@ public: typedef llvm::iterator_range<helper_expr_const_iterator> helper_expr_const_range; + helper_expr_const_range privates() const { + return helper_expr_const_range(getPrivates().begin(), getPrivates().end()); + } + helper_expr_range privates() { + return helper_expr_range(getPrivates().begin(), getPrivates().end()); + } helper_expr_const_range lhs_exprs() const { return helper_expr_const_range(getLHSExprs().begin(), getLHSExprs().end()); } @@ -1571,9 +1800,9 @@ public: getReductionOps().end()); } - StmtRange children() { - return StmtRange(reinterpret_cast<Stmt **>(varlist_begin()), - reinterpret_cast<Stmt **>(varlist_end())); + child_range children() { + return child_range(reinterpret_cast<Stmt **>(varlist_begin()), + reinterpret_cast<Stmt **>(varlist_end())); } static bool classof(const OMPClause *T) { @@ -1592,6 +1821,10 @@ public: /// class OMPLinearClause : public OMPVarListClause<OMPLinearClause> { friend class OMPClauseReader; + /// \brief Modifier of 'linear' clause. + OpenMPLinearClauseKind Modifier; + /// \brief Location of linear modifier if any. + SourceLocation ModifierLoc; /// \brief Location of ':'. SourceLocation ColonLoc; @@ -1610,11 +1843,12 @@ class OMPLinearClause : public OMPVarListClause<OMPLinearClause> { /// \param NumVars Number of variables. /// OMPLinearClause(SourceLocation StartLoc, SourceLocation LParenLoc, + OpenMPLinearClauseKind Modifier, SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc, unsigned NumVars) : OMPVarListClause<OMPLinearClause>(OMPC_linear, StartLoc, LParenLoc, EndLoc, NumVars), - ColonLoc(ColonLoc) {} + Modifier(Modifier), ModifierLoc(ModifierLoc), ColonLoc(ColonLoc) {} /// \brief Build an empty clause. /// @@ -1624,7 +1858,7 @@ class OMPLinearClause : public OMPVarListClause<OMPLinearClause> { : OMPVarListClause<OMPLinearClause>(OMPC_linear, SourceLocation(), SourceLocation(), SourceLocation(), NumVars), - ColonLoc(SourceLocation()) {} + Modifier(OMPC_LINEAR_val), ModifierLoc(), ColonLoc() {} /// \brief Gets the list of initial values for linear variables. /// @@ -1636,16 +1870,23 @@ class OMPLinearClause : public OMPVarListClause<OMPLinearClause> { /// expressions - linear step and a helper to calculate it before the /// loop body (used when the linear step is not constant): /// - /// { Vars[] /* in OMPVarListClause */; Inits[]; Updates[]; Finals[]; - /// Step; CalcStep; } + /// { Vars[] /* in OMPVarListClause */; Privates[]; Inits[]; Updates[]; + /// Finals[]; Step; CalcStep; } /// - MutableArrayRef<Expr *> getInits() { + MutableArrayRef<Expr *> getPrivates() { return MutableArrayRef<Expr *>(varlist_end(), varlist_size()); } - ArrayRef<const Expr *> getInits() const { + ArrayRef<const Expr *> getPrivates() const { return llvm::makeArrayRef(varlist_end(), varlist_size()); } + MutableArrayRef<Expr *> getInits() { + return MutableArrayRef<Expr *>(getPrivates().end(), varlist_size()); + } + ArrayRef<const Expr *> getInits() const { + return llvm::makeArrayRef(getPrivates().end(), varlist_size()); + } + /// \brief Sets the list of update expressions for linear variables. MutableArrayRef<Expr *> getUpdates() { return MutableArrayRef<Expr *>(getInits().end(), varlist_size()); @@ -1662,6 +1903,10 @@ class OMPLinearClause : public OMPVarListClause<OMPLinearClause> { return llvm::makeArrayRef(getUpdates().end(), varlist_size()); } + /// \brief Sets the list of the copies of original linear variables. + /// \param PL List of expressions. + void setPrivates(ArrayRef<Expr *> PL); + /// \brief Sets the list of the initial values for linear variables. /// \param IL List of expressions. void setInits(ArrayRef<Expr *> IL); @@ -1673,17 +1918,20 @@ public: /// \param C AST Context. /// \param StartLoc Starting location of the clause. /// \param LParenLoc Location of '('. + /// \param Modifier Modifier of 'linear' clause. + /// \param ModifierLoc Modifier location. /// \param ColonLoc Location of ':'. /// \param EndLoc Ending location of the clause. /// \param VL List of references to the variables. + /// \param PL List of private copies of original variables. /// \param IL List of initial values for the variables. /// \param Step Linear step. /// \param CalcStep Calculation of the linear step. - static OMPLinearClause *Create(const ASTContext &C, SourceLocation StartLoc, - SourceLocation LParenLoc, - SourceLocation ColonLoc, SourceLocation EndLoc, - ArrayRef<Expr *> VL, ArrayRef<Expr *> IL, - Expr *Step, Expr *CalcStep); + 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); /// \brief Creates an empty clause with the place for \a NumVars variables. /// @@ -1692,9 +1940,19 @@ public: /// static OMPLinearClause *CreateEmpty(const ASTContext &C, unsigned NumVars); + /// \brief Set modifier. + void setModifier(OpenMPLinearClauseKind Kind) { Modifier = Kind; } + /// \brief Return modifier. + OpenMPLinearClauseKind getModifier() const { return Modifier; } + + /// \brief Set modifier location. + void setModifierLoc(SourceLocation Loc) { ModifierLoc = Loc; } + /// \brief Return modifier location. + SourceLocation getModifierLoc() const { return ModifierLoc; } + /// \brief Sets the location of ':'. void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; } - /// \brief Returns the location of '('. + /// \brief Returns the location of ':'. SourceLocation getColonLoc() const { return ColonLoc; } /// \brief Returns linear step. @@ -1714,6 +1972,18 @@ public: /// \param FL List of expressions. void setFinals(ArrayRef<Expr *> FL); + typedef MutableArrayRef<Expr *>::iterator privates_iterator; + typedef ArrayRef<const Expr *>::iterator privates_const_iterator; + typedef llvm::iterator_range<privates_iterator> privates_range; + typedef llvm::iterator_range<privates_const_iterator> privates_const_range; + + privates_range privates() { + return privates_range(getPrivates().begin(), getPrivates().end()); + } + privates_const_range privates() const { + return privates_const_range(getPrivates().begin(), getPrivates().end()); + } + typedef MutableArrayRef<Expr *>::iterator inits_iterator; typedef ArrayRef<const Expr *>::iterator inits_const_iterator; typedef llvm::iterator_range<inits_iterator> inits_range; @@ -1750,9 +2020,9 @@ public: return finals_const_range(getFinals().begin(), getFinals().end()); } - StmtRange children() { - return StmtRange(reinterpret_cast<Stmt **>(varlist_begin()), - reinterpret_cast<Stmt **>(varlist_end())); + child_range children() { + return child_range(reinterpret_cast<Stmt **>(varlist_begin()), + reinterpret_cast<Stmt **>(varlist_end())); } static bool classof(const OMPClause *T) { @@ -1835,9 +2105,9 @@ public: /// \brief Returns alignment. const Expr *getAlignment() const { return *varlist_end(); } - StmtRange children() { - return StmtRange(reinterpret_cast<Stmt **>(varlist_begin()), - reinterpret_cast<Stmt **>(varlist_end())); + child_range children() { + return child_range(reinterpret_cast<Stmt **>(varlist_begin()), + reinterpret_cast<Stmt **>(varlist_end())); } static bool classof(const OMPClause *T) { @@ -1993,9 +2263,9 @@ public: getAssignmentOps().end()); } - StmtRange children() { - return StmtRange(reinterpret_cast<Stmt **>(varlist_begin()), - reinterpret_cast<Stmt **>(varlist_end())); + child_range children() { + return child_range(reinterpret_cast<Stmt **>(varlist_begin()), + reinterpret_cast<Stmt **>(varlist_end())); } static bool classof(const OMPClause *T) { @@ -2138,9 +2408,9 @@ public: getAssignmentOps().end()); } - StmtRange children() { - return StmtRange(reinterpret_cast<Stmt **>(varlist_begin()), - reinterpret_cast<Stmt **>(varlist_end())); + child_range children() { + return child_range(reinterpret_cast<Stmt **>(varlist_begin()), + reinterpret_cast<Stmt **>(varlist_end())); } static bool classof(const OMPClause *T) { @@ -2202,9 +2472,9 @@ public: /// static OMPFlushClause *CreateEmpty(const ASTContext &C, unsigned N); - StmtRange children() { - return StmtRange(reinterpret_cast<Stmt **>(varlist_begin()), - reinterpret_cast<Stmt **>(varlist_end())); + child_range children() { + return child_range(reinterpret_cast<Stmt **>(varlist_begin()), + reinterpret_cast<Stmt **>(varlist_end())); } static bool classof(const OMPClause *T) { @@ -2290,9 +2560,9 @@ public: /// \brief Get colon location. SourceLocation getColonLoc() const { return ColonLoc; } - StmtRange children() { - return StmtRange(reinterpret_cast<Stmt **>(varlist_begin()), - reinterpret_cast<Stmt **>(varlist_end())); + child_range children() { + return child_range(reinterpret_cast<Stmt **>(varlist_begin()), + reinterpret_cast<Stmt **>(varlist_end())); } static bool classof(const OMPClause *T) { @@ -2300,7 +2570,590 @@ public: } }; -} // end namespace clang +/// \brief This represents 'device' clause in the '#pragma omp ...' +/// directive. +/// +/// \code +/// #pragma omp target device(a) +/// \endcode +/// In this example directive '#pragma omp target' has clause 'device' +/// with single expression 'a'. +/// +class OMPDeviceClause : public OMPClause { + friend class OMPClauseReader; + /// \brief Location of '('. + SourceLocation LParenLoc; + /// \brief Device number. + Stmt *Device; + /// \brief Set the device number. + /// + /// \param E Device number. + /// + void setDevice(Expr *E) { Device = E; } + +public: + /// \brief Build 'device' clause. + /// + /// \param E Expression associated with this clause. + /// \param StartLoc Starting location of the clause. + /// \param LParenLoc Location of '('. + /// \param EndLoc Ending location of the clause. + /// + OMPDeviceClause(Expr *E, SourceLocation StartLoc, SourceLocation LParenLoc, + SourceLocation EndLoc) + : OMPClause(OMPC_device, StartLoc, EndLoc), LParenLoc(LParenLoc), + Device(E) {} + + /// \brief Build an empty clause. + /// + OMPDeviceClause() + : OMPClause(OMPC_device, SourceLocation(), SourceLocation()), + LParenLoc(SourceLocation()), Device(nullptr) {} + /// \brief Sets the location of '('. + void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } + /// \brief Returns the location of '('. + SourceLocation getLParenLoc() const { return LParenLoc; } + /// \brief Return device number. + Expr *getDevice() { return cast<Expr>(Device); } + /// \brief Return device number. + Expr *getDevice() const { return cast<Expr>(Device); } + + static bool classof(const OMPClause *T) { + return T->getClauseKind() == OMPC_device; + } + + child_range children() { return child_range(&Device, &Device + 1); } +}; + +/// \brief This represents 'threads' clause in the '#pragma omp ...' directive. +/// +/// \code +/// #pragma omp ordered threads +/// \endcode +/// In this example directive '#pragma omp ordered' has simple 'threads' clause. +/// +class OMPThreadsClause : public OMPClause { +public: + /// \brief Build 'threads' clause. + /// + /// \param StartLoc Starting location of the clause. + /// \param EndLoc Ending location of the clause. + /// + OMPThreadsClause(SourceLocation StartLoc, SourceLocation EndLoc) + : OMPClause(OMPC_threads, StartLoc, EndLoc) {} + + /// \brief Build an empty clause. + /// + OMPThreadsClause() + : OMPClause(OMPC_threads, SourceLocation(), SourceLocation()) {} + + static bool classof(const OMPClause *T) { + return T->getClauseKind() == OMPC_threads; + } + + child_range children() { + return child_range(child_iterator(), child_iterator()); + } +}; + +/// \brief This represents 'simd' clause in the '#pragma omp ...' directive. +/// +/// \code +/// #pragma omp ordered simd +/// \endcode +/// In this example directive '#pragma omp ordered' has simple 'simd' clause. +/// +class OMPSIMDClause : public OMPClause { +public: + /// \brief Build 'simd' clause. + /// + /// \param StartLoc Starting location of the clause. + /// \param EndLoc Ending location of the clause. + /// + OMPSIMDClause(SourceLocation StartLoc, SourceLocation EndLoc) + : OMPClause(OMPC_simd, StartLoc, EndLoc) {} + + /// \brief Build an empty clause. + /// + OMPSIMDClause() : OMPClause(OMPC_simd, SourceLocation(), SourceLocation()) {} + + static bool classof(const OMPClause *T) { + return T->getClauseKind() == OMPC_simd; + } + + child_range children() { + return child_range(child_iterator(), child_iterator()); + } +}; + +/// \brief This represents clause 'map' in the '#pragma omp ...' +/// directives. +/// +/// \code +/// #pragma omp target map(a,b) +/// \endcode +/// In this example directive '#pragma omp target' has clause 'map' +/// with the variables 'a' and 'b'. +/// +class OMPMapClause : public OMPVarListClause<OMPMapClause> { + friend class OMPClauseReader; + + /// \brief Map type modifier for the 'map' clause. + OpenMPMapClauseKind MapTypeModifier; + /// \brief Map type for the 'map' clause. + OpenMPMapClauseKind MapType; + /// \brief Location of the map type. + SourceLocation MapLoc; + /// \brief Colon location. + SourceLocation ColonLoc; + + /// \brief Set type modifier for the clause. + /// + /// \param T Type Modifier for the clause. + /// + void setMapTypeModifier(OpenMPMapClauseKind T) { MapTypeModifier = T; } + + /// \brief Set type for the clause. + /// + /// \param T Type for the clause. + /// + void setMapType(OpenMPMapClauseKind T) { MapType = T; } + + /// \brief Set type location. + /// + /// \param TLoc Type location. + /// + void setMapLoc(SourceLocation TLoc) { MapLoc = TLoc; } + + /// \brief Set colon location. + void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; } + + /// \brief Build clause with number of variables \a N. + /// + /// \param MapTypeModifier Map type modifier. + /// \param MapType Map type. + /// \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. + /// + 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) {} + + /// \brief Build an empty clause. + /// + /// \param N Number of variables. + /// + explicit OMPMapClause(unsigned N) + : OMPVarListClause<OMPMapClause>(OMPC_map, SourceLocation(), + SourceLocation(), SourceLocation(), N), + MapTypeModifier(OMPC_MAP_unknown), MapType(OMPC_MAP_unknown), MapLoc() {} + +public: + /// \brief Creates clause with a list of variables \a VL. + /// + /// \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 TypeModifier Map type modifier. + /// \param Type Map type. + /// \param TypeLoc Location of the map type. + /// + static OMPMapClause *Create(const ASTContext &C, SourceLocation StartLoc, + SourceLocation LParenLoc, + SourceLocation EndLoc, ArrayRef<Expr *> VL, + OpenMPMapClauseKind TypeModifier, + OpenMPMapClauseKind Type, SourceLocation TypeLoc); + /// \brief Creates an empty clause with the place for \a N variables. + /// + /// \param C AST context. + /// \param N The number of variables. + /// + static OMPMapClause *CreateEmpty(const ASTContext &C, unsigned N); + + /// \brief Fetches mapping kind for the clause. + OpenMPMapClauseKind getMapType() const LLVM_READONLY { return MapType; } + + /// \brief Fetches the map type modifier for the clause. + OpenMPMapClauseKind getMapTypeModifier() const LLVM_READONLY { + return MapTypeModifier; + } + + /// \brief Fetches location of clause mapping kind. + SourceLocation getMapLoc() const LLVM_READONLY { return MapLoc; } + + /// \brief Get colon location. + SourceLocation getColonLoc() const { return ColonLoc; } + + static bool classof(const OMPClause *T) { + return T->getClauseKind() == OMPC_map; + } + + child_range children() { + return child_range( + reinterpret_cast<Stmt **>(varlist_begin()), + reinterpret_cast<Stmt **>(varlist_end())); + } +}; + +/// \brief This represents 'num_teams' clause in the '#pragma omp ...' +/// directive. +/// +/// \code +/// #pragma omp teams num_teams(n) +/// \endcode +/// In this example directive '#pragma omp teams' has clause 'num_teams' +/// with single expression 'n'. +/// +class OMPNumTeamsClause : public OMPClause { + friend class OMPClauseReader; + /// \brief Location of '('. + SourceLocation LParenLoc; + /// \brief NumTeams number. + Stmt *NumTeams; + /// \brief Set the NumTeams number. + /// + /// \param E NumTeams number. + /// + void setNumTeams(Expr *E) { NumTeams = E; } + +public: + /// \brief Build 'num_teams' clause. + /// + /// \param E Expression associated with this clause. + /// \param StartLoc Starting location of the clause. + /// \param LParenLoc Location of '('. + /// \param EndLoc Ending location of the clause. + /// + OMPNumTeamsClause(Expr *E, SourceLocation StartLoc, SourceLocation LParenLoc, + SourceLocation EndLoc) + : OMPClause(OMPC_num_teams, StartLoc, EndLoc), LParenLoc(LParenLoc), + NumTeams(E) {} + + /// \brief Build an empty clause. + /// + OMPNumTeamsClause() + : OMPClause(OMPC_num_teams, SourceLocation(), SourceLocation()), + LParenLoc(SourceLocation()), NumTeams(nullptr) {} + /// \brief Sets the location of '('. + void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } + /// \brief Returns the location of '('. + SourceLocation getLParenLoc() const { return LParenLoc; } + /// \brief Return NumTeams number. + Expr *getNumTeams() { return cast<Expr>(NumTeams); } + /// \brief Return NumTeams number. + Expr *getNumTeams() const { return cast<Expr>(NumTeams); } + + static bool classof(const OMPClause *T) { + return T->getClauseKind() == OMPC_num_teams; + } + + child_range children() { return child_range(&NumTeams, &NumTeams + 1); } +}; + +/// \brief This represents 'thread_limit' clause in the '#pragma omp ...' +/// directive. +/// +/// \code +/// #pragma omp teams thread_limit(n) +/// \endcode +/// In this example directive '#pragma omp teams' has clause 'thread_limit' +/// with single expression 'n'. +/// +class OMPThreadLimitClause : public OMPClause { + friend class OMPClauseReader; + /// \brief Location of '('. + SourceLocation LParenLoc; + /// \brief ThreadLimit number. + Stmt *ThreadLimit; + /// \brief Set the ThreadLimit number. + /// + /// \param E ThreadLimit number. + /// + void setThreadLimit(Expr *E) { ThreadLimit = E; } + +public: + /// \brief Build 'thread_limit' clause. + /// + /// \param E Expression associated with this clause. + /// \param StartLoc Starting location of the clause. + /// \param LParenLoc Location of '('. + /// \param EndLoc Ending location of the clause. + /// + OMPThreadLimitClause(Expr *E, SourceLocation StartLoc, + SourceLocation LParenLoc, SourceLocation EndLoc) + : OMPClause(OMPC_thread_limit, StartLoc, EndLoc), LParenLoc(LParenLoc), + ThreadLimit(E) {} + + /// \brief Build an empty clause. + /// + OMPThreadLimitClause() + : OMPClause(OMPC_thread_limit, SourceLocation(), SourceLocation()), + LParenLoc(SourceLocation()), ThreadLimit(nullptr) {} + /// \brief Sets the location of '('. + void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } + /// \brief Returns the location of '('. + SourceLocation getLParenLoc() const { return LParenLoc; } + /// \brief Return ThreadLimit number. + Expr *getThreadLimit() { return cast<Expr>(ThreadLimit); } + /// \brief Return ThreadLimit number. + Expr *getThreadLimit() const { return cast<Expr>(ThreadLimit); } + + static bool classof(const OMPClause *T) { + return T->getClauseKind() == OMPC_thread_limit; + } + + child_range children() { return child_range(&ThreadLimit, &ThreadLimit + 1); } +}; + +/// \brief This represents 'priority' clause in the '#pragma omp ...' +/// directive. +/// +/// \code +/// #pragma omp task priority(n) +/// \endcode +/// In this example directive '#pragma omp teams' has clause 'priority' with +/// single expression 'n'. +/// +class OMPPriorityClause : public OMPClause { + friend class OMPClauseReader; + /// \brief Location of '('. + SourceLocation LParenLoc; + /// \brief Priority number. + Stmt *Priority; + /// \brief Set the Priority number. + /// + /// \param E Priority number. + /// + void setPriority(Expr *E) { Priority = E; } + +public: + /// \brief Build 'priority' clause. + /// + /// \param E Expression associated with this clause. + /// \param StartLoc Starting location of the clause. + /// \param LParenLoc Location of '('. + /// \param EndLoc Ending location of the clause. + /// + OMPPriorityClause(Expr *E, SourceLocation StartLoc, SourceLocation LParenLoc, + SourceLocation EndLoc) + : OMPClause(OMPC_priority, StartLoc, EndLoc), LParenLoc(LParenLoc), + Priority(E) {} + + /// \brief Build an empty clause. + /// + OMPPriorityClause() + : OMPClause(OMPC_priority, SourceLocation(), SourceLocation()), + LParenLoc(SourceLocation()), Priority(nullptr) {} + /// \brief Sets the location of '('. + void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } + /// \brief Returns the location of '('. + SourceLocation getLParenLoc() const { return LParenLoc; } + /// \brief Return Priority number. + Expr *getPriority() { return cast<Expr>(Priority); } + /// \brief Return Priority number. + Expr *getPriority() const { return cast<Expr>(Priority); } + + static bool classof(const OMPClause *T) { + return T->getClauseKind() == OMPC_priority; + } + + child_range children() { return child_range(&Priority, &Priority + 1); } +}; + +/// \brief This represents 'grainsize' clause in the '#pragma omp ...' +/// directive. +/// +/// \code +/// #pragma omp taskloop grainsize(4) +/// \endcode +/// In this example directive '#pragma omp taskloop' has clause 'grainsize' +/// with single expression '4'. +/// +class OMPGrainsizeClause : public OMPClause { + friend class OMPClauseReader; + /// \brief Location of '('. + SourceLocation LParenLoc; + /// \brief Safe iteration space distance. + Stmt *Grainsize; + + /// \brief Set safelen. + void setGrainsize(Expr *Size) { Grainsize = Size; } + +public: + /// \brief Build 'grainsize' clause. + /// + /// \param Size Expression associated with this clause. + /// \param StartLoc Starting location of the clause. + /// \param EndLoc Ending location of the clause. + /// + OMPGrainsizeClause(Expr *Size, SourceLocation StartLoc, + SourceLocation LParenLoc, SourceLocation EndLoc) + : OMPClause(OMPC_grainsize, StartLoc, EndLoc), LParenLoc(LParenLoc), + Grainsize(Size) {} + + /// \brief Build an empty clause. + /// + explicit OMPGrainsizeClause() + : OMPClause(OMPC_grainsize, SourceLocation(), SourceLocation()), + LParenLoc(SourceLocation()), Grainsize(nullptr) {} + + /// \brief Sets the location of '('. + void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } + /// \brief Returns the location of '('. + SourceLocation getLParenLoc() const { return LParenLoc; } + + /// \brief Return safe iteration space distance. + Expr *getGrainsize() const { return cast_or_null<Expr>(Grainsize); } + + static bool classof(const OMPClause *T) { + return T->getClauseKind() == OMPC_grainsize; + } -#endif + child_range children() { return child_range(&Grainsize, &Grainsize + 1); } +}; + +/// \brief This represents 'nogroup' clause in the '#pragma omp ...' directive. +/// +/// \code +/// #pragma omp taskloop nogroup +/// \endcode +/// In this example directive '#pragma omp taskloop' has 'nogroup' clause. +/// +class OMPNogroupClause : public OMPClause { +public: + /// \brief Build 'nogroup' clause. + /// + /// \param StartLoc Starting location of the clause. + /// \param EndLoc Ending location of the clause. + /// + OMPNogroupClause(SourceLocation StartLoc, SourceLocation EndLoc) + : OMPClause(OMPC_nogroup, StartLoc, EndLoc) {} + + /// \brief Build an empty clause. + /// + OMPNogroupClause() + : OMPClause(OMPC_nogroup, SourceLocation(), SourceLocation()) {} + + static bool classof(const OMPClause *T) { + return T->getClauseKind() == OMPC_nogroup; + } + + child_range children() { + return child_range(child_iterator(), child_iterator()); + } +}; + +/// \brief This represents 'num_tasks' clause in the '#pragma omp ...' +/// directive. +/// +/// \code +/// #pragma omp taskloop num_tasks(4) +/// \endcode +/// In this example directive '#pragma omp taskloop' has clause 'num_tasks' +/// with single expression '4'. +/// +class OMPNumTasksClause : public OMPClause { + friend class OMPClauseReader; + /// \brief Location of '('. + SourceLocation LParenLoc; + /// \brief Safe iteration space distance. + Stmt *NumTasks; + + /// \brief Set safelen. + void setNumTasks(Expr *Size) { NumTasks = Size; } + +public: + /// \brief Build 'num_tasks' clause. + /// + /// \param Size Expression associated with this clause. + /// \param StartLoc Starting location of the clause. + /// \param EndLoc Ending location of the clause. + /// + OMPNumTasksClause(Expr *Size, SourceLocation StartLoc, + SourceLocation LParenLoc, SourceLocation EndLoc) + : OMPClause(OMPC_num_tasks, StartLoc, EndLoc), LParenLoc(LParenLoc), + NumTasks(Size) {} + + /// \brief Build an empty clause. + /// + explicit OMPNumTasksClause() + : OMPClause(OMPC_num_tasks, SourceLocation(), SourceLocation()), + LParenLoc(SourceLocation()), NumTasks(nullptr) {} + + /// \brief Sets the location of '('. + void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } + /// \brief Returns the location of '('. + SourceLocation getLParenLoc() const { return LParenLoc; } + + /// \brief Return safe iteration space distance. + Expr *getNumTasks() const { return cast_or_null<Expr>(NumTasks); } + + static bool classof(const OMPClause *T) { + return T->getClauseKind() == OMPC_num_tasks; + } + + child_range children() { return child_range(&NumTasks, &NumTasks + 1); } +}; + +/// \brief This represents 'hint' clause in the '#pragma omp ...' directive. +/// +/// \code +/// #pragma omp critical (name) hint(6) +/// \endcode +/// In this example directive '#pragma omp critical' has name 'name' and clause +/// 'hint' with argument '6'. +/// +class OMPHintClause : public OMPClause { + friend class OMPClauseReader; + /// \brief Location of '('. + SourceLocation LParenLoc; + /// \brief Hint expression of the 'hint' clause. + Stmt *Hint; + + /// \brief Set hint expression. + /// + void setHint(Expr *H) { Hint = H; } + +public: + /// \brief Build 'hint' clause with expression \a Hint. + /// + /// \param Hint Hint expression. + /// \param StartLoc Starting location of the clause. + /// \param LParenLoc Location of '('. + /// \param EndLoc Ending location of the clause. + /// + OMPHintClause(Expr *Hint, SourceLocation StartLoc, SourceLocation LParenLoc, + SourceLocation EndLoc) + : OMPClause(OMPC_hint, StartLoc, EndLoc), LParenLoc(LParenLoc), + Hint(Hint) {} + + /// \brief Build an empty clause. + /// + OMPHintClause() + : OMPClause(OMPC_hint, SourceLocation(), SourceLocation()), + LParenLoc(SourceLocation()), Hint(nullptr) {} + + /// \brief Sets the location of '('. + void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } + /// \brief Returns the location of '('. + SourceLocation getLParenLoc() const { return LParenLoc; } + + /// \brief Returns number of threads. + Expr *getHint() const { return cast_or_null<Expr>(Hint); } + + static bool classof(const OMPClause *T) { + return T->getClauseKind() == OMPC_hint; + } + + child_range children() { return child_range(&Hint, &Hint + 1); } +}; + +} // end namespace clang +#endif // LLVM_CLANG_AST_OPENMPCLAUSE_H diff --git a/contrib/llvm/tools/clang/include/clang/AST/OperationKinds.h b/contrib/llvm/tools/clang/include/clang/AST/OperationKinds.h index e3f0126..2235c10 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/OperationKinds.h +++ b/contrib/llvm/tools/clang/include/clang/AST/OperationKinds.h @@ -334,7 +334,8 @@ enum UnaryOperatorKind { 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_Extension, // __extension__ marker. + UO_Coawait // [C++ Coroutines] co_await operator }; /// \brief The kind of bridging performed by the Objective-C bridge cast. diff --git a/contrib/llvm/tools/clang/include/clang/AST/PrettyPrinter.h b/contrib/llvm/tools/clang/include/clang/AST/PrettyPrinter.h index 35ceabb..8ab3f617 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/PrettyPrinter.h +++ b/contrib/llvm/tools/clang/include/clang/AST/PrettyPrinter.h @@ -42,7 +42,7 @@ struct PrintingPolicy { SuppressStrongLifetime(false), SuppressLifetimeQualifiers(false), Bool(LO.Bool), TerseOutput(false), PolishForDeclaration(false), Half(LO.Half), MSWChar(LO.MicrosoftExt && !LO.WChar), - IncludeNewlines(true) { } + IncludeNewlines(true), MSVCFormatting(false) { } /// \brief What language we're printing. LangOptions LangOpts; @@ -109,7 +109,7 @@ struct PrintingPolicy { /// \brief Whether we should print the sizes of constant array expressions /// as written in the sources. /// - /// This flag is determines whether arrays types declared as + /// This flag determines whether array types declared as /// /// \code /// int a[4+10*10]; @@ -163,6 +163,11 @@ struct PrintingPolicy { /// \brief When true, include newlines after statements like "break", etc. unsigned IncludeNewlines : 1; + + /// \brief Use whitespace and punctuation like MSVC does. In particular, this + /// prints anonymous namespaces as `anonymous namespace' and does not insert + /// spaces after template arguments. + bool MSVCFormatting : 1; }; } // end namespace clang diff --git a/contrib/llvm/tools/clang/include/clang/AST/RecursiveASTVisitor.h b/contrib/llvm/tools/clang/include/clang/AST/RecursiveASTVisitor.h index 1017656..e6f7583 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/RecursiveASTVisitor.h +++ b/contrib/llvm/tools/clang/include/clang/AST/RecursiveASTVisitor.h @@ -14,6 +14,8 @@ #ifndef LLVM_CLANG_AST_RECURSIVEASTVISITOR_H #define LLVM_CLANG_AST_RECURSIVEASTVISITOR_H +#include <type_traits> + #include "clang/AST/Attr.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclCXX.h" @@ -24,6 +26,7 @@ #include "clang/AST/Expr.h" #include "clang/AST/ExprCXX.h" #include "clang/AST/ExprObjC.h" +#include "clang/AST/ExprOpenMP.h" #include "clang/AST/NestedNameSpecifier.h" #include "clang/AST/Stmt.h" #include "clang/AST/StmtCXX.h" @@ -42,7 +45,7 @@ OPERATOR(PostInc) OPERATOR(PostDec) OPERATOR(PreInc) OPERATOR(PreDec) \ OPERATOR(AddrOf) OPERATOR(Deref) OPERATOR(Plus) OPERATOR(Minus) \ OPERATOR(Not) OPERATOR(LNot) OPERATOR(Real) OPERATOR(Imag) \ - OPERATOR(Extension) + OPERATOR(Extension) OPERATOR(Coawait) // All binary operators (excluding compound assign operators). #define BINOP_LIST() \ @@ -132,6 +135,12 @@ namespace clang { /// from which they were produced. 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; + /// \brief Return a reference to the derived class. Derived &getDerived() { return *static_cast<Derived *>(this); } @@ -147,19 +156,12 @@ public: /// code, e.g., implicit constructors and destructors. bool shouldVisitImplicitCode() const { return false; } - /// \brief Return whether \param S should be traversed using data recursion - /// to avoid a stack overflow with extreme cases. - bool shouldUseDataRecursionFor(Stmt *S) const { - return isa<BinaryOperator>(S) || isa<UnaryOperator>(S) || - isa<CaseStmt>(S) || isa<CXXOperatorCallExpr>(S); - } - /// \brief Recursively visit a statement or expression, by /// dispatching to Traverse*() based on the argument's dynamic type. /// /// \returns false if the visitation was terminated early, true - /// otherwise (including when the argument is NULL). - bool TraverseStmt(Stmt *S); + /// otherwise (including when the argument is nullptr). + bool TraverseStmt(Stmt *S, DataRecursionQueue *Queue = nullptr); /// \brief Recursively visit a type, by dispatching to /// Traverse*Type() based on the argument's getTypeClass() property. @@ -252,7 +254,14 @@ public: /// \c LE->getBody(). /// /// \returns false if the visitation was terminated early, true otherwise. - bool TraverseLambdaBody(LambdaExpr *LE); + bool TraverseLambdaBody(LambdaExpr *LE, DataRecursionQueue *Queue = nullptr); + + /// \brief Recursively visit the syntactic or semantic form of an + /// initialization list. + /// + /// \returns false if the visitation was terminated early, true otherwise. + bool TraverseSynOrSemInitListExpr(InitListExpr *S, + DataRecursionQueue *Queue = nullptr); // ---- Methods on Attrs ---- @@ -266,9 +275,44 @@ public: // ---- Methods on Stmts ---- +private: + template<typename T, typename U> + struct has_same_member_pointer_type : std::false_type {}; + template<typename T, typename U, typename R, typename... P> + struct has_same_member_pointer_type<R (T::*)(P...), R (U::*)(P...)> + : std::true_type {}; + + // Traverse the given statement. If the most-derived traverse function takes a + // data recursion queue, pass it on; otherwise, discard it. Note that the + // first branch of this conditional must compile whether or not the derived + // class can take a queue, so if we're taking the second arm, make the first + // arm call our function rather than the derived class version. +#define TRAVERSE_STMT_BASE(NAME, CLASS, VAR, QUEUE) \ + (has_same_member_pointer_type<decltype( \ + &RecursiveASTVisitor::Traverse##NAME), \ + decltype(&Derived::Traverse##NAME)>::value \ + ? static_cast<typename std::conditional< \ + has_same_member_pointer_type< \ + decltype(&RecursiveASTVisitor::Traverse##NAME), \ + decltype(&Derived::Traverse##NAME)>::value, \ + Derived &, RecursiveASTVisitor &>::type>(*this) \ + .Traverse##NAME(static_cast<CLASS *>(VAR), QUEUE) \ + : getDerived().Traverse##NAME(static_cast<CLASS *>(VAR))) + +// Try to traverse the given statement, or enqueue it if we're performing data +// recursion in the middle of traversing another statement. Can only be called +// from within a DEF_TRAVERSE_STMT body or similar context. +#define TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S) \ + do { \ + if (!TRAVERSE_STMT_BASE(Stmt, Stmt, S, Queue)) \ + return false; \ + } while (0) + +public: // Declare Traverse*() for all concrete Stmt classes. #define ABSTRACT_STMT(STMT) -#define STMT(CLASS, PARENT) bool Traverse##CLASS(CLASS *S); +#define STMT(CLASS, PARENT) \ + bool Traverse##CLASS(CLASS *S, DataRecursionQueue *Queue = nullptr); #include "clang/AST/StmtNodes.inc" // The above header #undefs ABSTRACT_STMT and STMT upon exit. @@ -288,9 +332,10 @@ public: // operator methods. Unary operators are not classes in themselves // (they're all opcodes in UnaryOperator) but do have visitors. #define OPERATOR(NAME) \ - bool TraverseUnary##NAME(UnaryOperator *S) { \ + bool TraverseUnary##NAME(UnaryOperator *S, \ + DataRecursionQueue *Queue = nullptr) { \ TRY_TO(WalkUpFromUnary##NAME(S)); \ - TRY_TO(TraverseStmt(S->getSubExpr())); \ + TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getSubExpr()); \ return true; \ } \ bool WalkUpFromUnary##NAME(UnaryOperator *S) { \ @@ -307,10 +352,10 @@ public: // operator methods. Binary operators are not classes in themselves // (they're all opcodes in BinaryOperator) but do have visitors. #define GENERAL_BINOP_FALLBACK(NAME, BINOP_TYPE) \ - bool TraverseBin##NAME(BINOP_TYPE *S) { \ + bool TraverseBin##NAME(BINOP_TYPE *S, DataRecursionQueue *Queue = nullptr) { \ TRY_TO(WalkUpFromBin##NAME(S)); \ - TRY_TO(TraverseStmt(S->getLHS())); \ - TRY_TO(TraverseStmt(S->getRHS())); \ + TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getLHS()); \ + TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getRHS()); \ return true; \ } \ bool WalkUpFromBin##NAME(BINOP_TYPE *S) { \ @@ -436,98 +481,45 @@ private: /// \brief Process clauses with list of variables. template <typename T> bool VisitOMPClauseList(T *Node); - struct EnqueueJob { - Stmt *S; - Stmt::child_iterator StmtIt; - - EnqueueJob(Stmt *S) : S(S), StmtIt() {} - }; - bool dataTraverse(Stmt *S); - bool dataTraverseNode(Stmt *S, bool &EnqueueChildren); + bool dataTraverseNode(Stmt *S, DataRecursionQueue *Queue); }; template <typename Derived> -bool RecursiveASTVisitor<Derived>::dataTraverse(Stmt *S) { - - SmallVector<EnqueueJob, 16> Queue; - Queue.push_back(S); - - while (!Queue.empty()) { - EnqueueJob &job = Queue.back(); - Stmt *CurrS = job.S; - if (!CurrS) { - Queue.pop_back(); - continue; - } - - if (getDerived().shouldUseDataRecursionFor(CurrS)) { - if (job.StmtIt == Stmt::child_iterator()) { - bool EnqueueChildren = true; - if (!dataTraverseNode(CurrS, EnqueueChildren)) - return false; - if (!EnqueueChildren) { - Queue.pop_back(); - continue; - } - job.StmtIt = CurrS->child_begin(); - } else { - ++job.StmtIt; - } - - if (job.StmtIt != CurrS->child_end()) - Queue.push_back(*job.StmtIt); - else - Queue.pop_back(); - continue; - } - - Queue.pop_back(); - TRY_TO(TraverseStmt(CurrS)); - } - - return true; -} - -template <typename Derived> bool RecursiveASTVisitor<Derived>::dataTraverseNode(Stmt *S, - bool &EnqueueChildren) { - -// Dispatch to the corresponding WalkUpFrom* function only if the derived -// class didn't override Traverse* (and thus the traversal is trivial). -#define DISPATCH_WALK(NAME, CLASS, VAR) \ - { \ - bool (Derived::*DerivedFn)(CLASS *) = &Derived::Traverse##NAME; \ - bool (Derived::*BaseFn)(CLASS *) = &RecursiveASTVisitor::Traverse##NAME; \ - if (DerivedFn == BaseFn) \ - return getDerived().WalkUpFrom##NAME(static_cast<CLASS *>(VAR)); \ - } \ - EnqueueChildren = false; \ - return getDerived().Traverse##NAME(static_cast<CLASS *>(VAR)); + DataRecursionQueue *Queue) { +#define DISPATCH_STMT(NAME, CLASS, VAR) \ + return TRAVERSE_STMT_BASE(NAME, CLASS, VAR, Queue); + // If we have a binary expr, dispatch to the subcode of the binop. A smart + // optimizer (e.g. LLVM) will fold this comparison into the switch stmt + // below. if (BinaryOperator *BinOp = dyn_cast<BinaryOperator>(S)) { switch (BinOp->getOpcode()) { #define OPERATOR(NAME) \ case BO_##NAME: \ - DISPATCH_WALK(Bin##NAME, BinaryOperator, S); + DISPATCH_STMT(Bin##NAME, BinaryOperator, S); BINOP_LIST() #undef OPERATOR +#undef BINOP_LIST #define OPERATOR(NAME) \ case BO_##NAME##Assign: \ - DISPATCH_WALK(Bin##NAME##Assign, CompoundAssignOperator, S); + DISPATCH_STMT(Bin##NAME##Assign, CompoundAssignOperator, S); CAO_LIST() #undef OPERATOR +#undef CAO_LIST } } else if (UnaryOperator *UnOp = dyn_cast<UnaryOperator>(S)) { switch (UnOp->getOpcode()) { #define OPERATOR(NAME) \ case UO_##NAME: \ - DISPATCH_WALK(Unary##NAME, UnaryOperator, S); + DISPATCH_STMT(Unary##NAME, UnaryOperator, S); UNARYOP_LIST() #undef OPERATOR +#undef UNARYOP_LIST } } @@ -538,76 +530,43 @@ bool RecursiveASTVisitor<Derived>::dataTraverseNode(Stmt *S, #define ABSTRACT_STMT(STMT) #define STMT(CLASS, PARENT) \ case Stmt::CLASS##Class: \ - DISPATCH_WALK(CLASS, CLASS, S); + DISPATCH_STMT(CLASS, CLASS, S); #include "clang/AST/StmtNodes.inc" } -#undef DISPATCH_WALK - return true; } -#define DISPATCH(NAME, CLASS, VAR) \ - return getDerived().Traverse##NAME(static_cast<CLASS *>(VAR)) +#undef DISPATCH_STMT template <typename Derived> -bool RecursiveASTVisitor<Derived>::TraverseStmt(Stmt *S) { +bool RecursiveASTVisitor<Derived>::TraverseStmt(Stmt *S, + DataRecursionQueue *Queue) { if (!S) return true; -#define DISPATCH_STMT(NAME, CLASS, VAR) DISPATCH(NAME, CLASS, VAR) - - if (getDerived().shouldUseDataRecursionFor(S)) - return dataTraverse(S); - - // If we have a binary expr, dispatch to the subcode of the binop. A smart - // optimizer (e.g. LLVM) will fold this comparison into the switch stmt - // below. - if (BinaryOperator *BinOp = dyn_cast<BinaryOperator>(S)) { - switch (BinOp->getOpcode()) { -#define OPERATOR(NAME) \ - case BO_##NAME: \ - DISPATCH_STMT(Bin##NAME, BinaryOperator, S); - - BINOP_LIST() -#undef OPERATOR -#undef BINOP_LIST + if (Queue) { + Queue->push_back(S); + return true; + } -#define OPERATOR(NAME) \ - case BO_##NAME##Assign: \ - DISPATCH_STMT(Bin##NAME##Assign, CompoundAssignOperator, S); + SmallVector<Stmt *, 8> LocalQueue; + LocalQueue.push_back(S); - CAO_LIST() -#undef OPERATOR -#undef CAO_LIST - } - } else if (UnaryOperator *UnOp = dyn_cast<UnaryOperator>(S)) { - switch (UnOp->getOpcode()) { -#define OPERATOR(NAME) \ - case UO_##NAME: \ - DISPATCH_STMT(Unary##NAME, UnaryOperator, S); + while (!LocalQueue.empty()) { + Stmt *CurrS = LocalQueue.pop_back_val(); - UNARYOP_LIST() -#undef OPERATOR -#undef UNARYOP_LIST - } - } - - // Top switch stmt: dispatch to TraverseFooStmt for each concrete FooStmt. - switch (S->getStmtClass()) { - case Stmt::NoStmtClass: - break; -#define ABSTRACT_STMT(STMT) -#define STMT(CLASS, PARENT) \ - case Stmt::CLASS##Class: \ - DISPATCH_STMT(CLASS, CLASS, S); -#include "clang/AST/StmtNodes.inc" + 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()); } return true; } -#undef DISPATCH_STMT +#define DISPATCH(NAME, CLASS, VAR) \ + return getDerived().Traverse##NAME(static_cast<CLASS *>(VAR)) template <typename Derived> bool RecursiveASTVisitor<Derived>::TraverseType(QualType T) { @@ -863,8 +822,9 @@ RecursiveASTVisitor<Derived>::TraverseLambdaCapture(LambdaExpr *LE, } template <typename Derived> -bool RecursiveASTVisitor<Derived>::TraverseLambdaBody(LambdaExpr *LE) { - TRY_TO(TraverseStmt(LE->getBody())); +bool RecursiveASTVisitor<Derived>::TraverseLambdaBody( + LambdaExpr *LE, DataRecursionQueue *Queue) { + TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(LE->getBody()); return true; } @@ -1364,6 +1324,8 @@ DEF_TRAVERSE_DECL( DEF_TRAVERSE_DECL(ExternCContextDecl, {}) DEF_TRAVERSE_DECL(NamespaceAliasDecl, { + TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc())); + // We shouldn't traverse an aliased namespace, since it will be // defined (and, therefore, traversed) somewhere else. // @@ -1596,6 +1558,10 @@ DEF_TRAVERSE_DECL(TemplateTemplateParmDecl, { TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters())); }) +DEF_TRAVERSE_DECL(BuiltinTemplateDecl, { + TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters())); +}) + DEF_TRAVERSE_DECL(TemplateTypeParmDecl, { // D is the "T" in something like "template<typename T> class vector;" if (D->getTypeForDecl()) @@ -1906,25 +1872,26 @@ DEF_TRAVERSE_DECL(ParmVarDecl, { // This macro makes available a variable S, the passed-in stmt. #define DEF_TRAVERSE_STMT(STMT, CODE) \ template <typename Derived> \ - bool RecursiveASTVisitor<Derived>::Traverse##STMT(STMT *S) { \ + bool RecursiveASTVisitor<Derived>::Traverse##STMT( \ + STMT *S, DataRecursionQueue *Queue) { \ TRY_TO(WalkUpFrom##STMT(S)); \ { CODE; } \ for (Stmt *SubStmt : S->children()) { \ - TRY_TO(TraverseStmt(SubStmt)); \ + TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(SubStmt); \ } \ return true; \ } DEF_TRAVERSE_STMT(GCCAsmStmt, { - TRY_TO(TraverseStmt(S->getAsmString())); + TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getAsmString()); for (unsigned I = 0, E = S->getNumInputs(); I < E; ++I) { - TRY_TO(TraverseStmt(S->getInputConstraintLiteral(I))); + TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getInputConstraintLiteral(I)); } for (unsigned I = 0, E = S->getNumOutputs(); I < E; ++I) { - TRY_TO(TraverseStmt(S->getOutputConstraintLiteral(I))); + TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getOutputConstraintLiteral(I)); } for (unsigned I = 0, E = S->getNumClobbers(); I < E; ++I) { - TRY_TO(TraverseStmt(S->getClobberStringLiteral(I))); + TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getClobberStringLiteral(I)); } // children() iterates over inputExpr and outputExpr. }) @@ -1977,9 +1944,9 @@ DEF_TRAVERSE_STMT(ObjCForCollectionStmt, {}) DEF_TRAVERSE_STMT(ObjCAutoreleasePoolStmt, {}) DEF_TRAVERSE_STMT(CXXForRangeStmt, { if (!getDerived().shouldVisitImplicitCode()) { - TRY_TO(TraverseStmt(S->getLoopVarStmt())); - TRY_TO(TraverseStmt(S->getRangeInit())); - TRY_TO(TraverseStmt(S->getBody())); + TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getLoopVarStmt()); + TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getRangeInit()); + TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getBody()); // Visit everything else only if shouldVisitImplicitCode(). return true; } @@ -2012,9 +1979,8 @@ DEF_TRAVERSE_STMT(DependentScopeDeclRefExpr, { TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc())); TRY_TO(TraverseDeclarationNameInfo(S->getNameInfo())); if (S->hasExplicitTemplateArgs()) { - TRY_TO(TraverseTemplateArgumentLocsHelper( - S->getExplicitTemplateArgs().getTemplateArgs(), - S->getNumTemplateArgs())); + TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(), + S->getNumTemplateArgs())); } }) @@ -2055,64 +2021,60 @@ DEF_TRAVERSE_STMT(CXXStaticCastExpr, { TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc())); }) -// InitListExpr is a tricky one, because we want to do all our work on -// the syntactic form of the listexpr, but this method takes the -// semantic form by default. We can't use the macro helper because it -// calls WalkUp*() on the semantic form, before our code can convert -// to the syntactic form. template <typename Derived> -bool RecursiveASTVisitor<Derived>::TraverseInitListExpr(InitListExpr *S) { - InitListExpr *Syn = S->isSemanticForm() ? S->getSyntacticForm() : S; - if (Syn) { - TRY_TO(WalkUpFromInitListExpr(Syn)); +bool RecursiveASTVisitor<Derived>::TraverseSynOrSemInitListExpr( + InitListExpr *S, DataRecursionQueue *Queue) { + if (S) { + TRY_TO(WalkUpFromInitListExpr(S)); // All we need are the default actions. FIXME: use a helper function. - for (Stmt *SubStmt : Syn->children()) { - TRY_TO(TraverseStmt(SubStmt)); - } - } - InitListExpr *Sem = S->isSemanticForm() ? S : S->getSemanticForm(); - if (Sem) { - TRY_TO(WalkUpFromInitListExpr(Sem)); - for (Stmt *SubStmt : Sem->children()) { - TRY_TO(TraverseStmt(SubStmt)); + for (Stmt *SubStmt : S->children()) { + TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(SubStmt); } } return true; } +// This method is called once for each pair of syntactic and semantic +// InitListExpr, and it traverses the subtrees defined by the two forms. This +// may cause some of the children to be visited twice, if they appear both in +// the syntactic and the semantic form. +// +// There is no guarantee about which form \p S takes when this method is called. +DEF_TRAVERSE_STMT(InitListExpr, { + TRY_TO(TraverseSynOrSemInitListExpr( + S->isSemanticForm() ? S->getSyntacticForm() : S, Queue)); + TRY_TO(TraverseSynOrSemInitListExpr( + S->isSemanticForm() ? S : S->getSemanticForm(), Queue)); + return true; +}) + // GenericSelectionExpr is a special case because the types and expressions // are interleaved. We also need to watch out for null types (default // generic associations). -template <typename Derived> -bool RecursiveASTVisitor<Derived>::TraverseGenericSelectionExpr( - GenericSelectionExpr *S) { - TRY_TO(WalkUpFromGenericSelectionExpr(S)); +DEF_TRAVERSE_STMT(GenericSelectionExpr, { TRY_TO(TraverseStmt(S->getControllingExpr())); for (unsigned i = 0; i != S->getNumAssocs(); ++i) { if (TypeSourceInfo *TS = S->getAssocTypeSourceInfo(i)) TRY_TO(TraverseTypeLoc(TS->getTypeLoc())); - TRY_TO(TraverseStmt(S->getAssocExpr(i))); + TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getAssocExpr(i)); } return true; -} +}) -// PseudoObjectExpr is a special case because of the wierdness with +// PseudoObjectExpr is a special case because of the weirdness with // syntactic expressions and opaque values. -template <typename Derived> -bool -RecursiveASTVisitor<Derived>::TraversePseudoObjectExpr(PseudoObjectExpr *S) { - TRY_TO(WalkUpFromPseudoObjectExpr(S)); - TRY_TO(TraverseStmt(S->getSyntacticForm())); +DEF_TRAVERSE_STMT(PseudoObjectExpr, { + TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getSyntacticForm()); for (PseudoObjectExpr::semantics_iterator i = S->semantics_begin(), e = S->semantics_end(); i != e; ++i) { Expr *sub = *i; if (OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(sub)) sub = OVE->getSourceExpr(); - TRY_TO(TraverseStmt(sub)); + TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(sub); } return true; -} +}) DEF_TRAVERSE_STMT(CXXScalarValueInitExpr, { // This is called for code like 'return T()' where T is a built-in @@ -2151,6 +2113,8 @@ DEF_TRAVERSE_STMT(MSPropertyRefExpr, { TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc())); }) +DEF_TRAVERSE_STMT(MSPropertySubscriptExpr, {}) + DEF_TRAVERSE_STMT(CXXUuidofExpr, { // The child-iterator will pick up the arg if it's an expression, // but not if it's a type. @@ -2168,7 +2132,7 @@ DEF_TRAVERSE_STMT(ArrayTypeTraitExpr, { }) DEF_TRAVERSE_STMT(ExpressionTraitExpr, - { TRY_TO(TraverseStmt(S->getQueriedExpression())); }) + { TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getQueriedExpression()); }) DEF_TRAVERSE_STMT(VAArgExpr, { // The child-iterator will pick up the expression argument. @@ -2181,10 +2145,7 @@ DEF_TRAVERSE_STMT(CXXTemporaryObjectExpr, { }) // Walk only the visible parts of lambda expressions. -template <typename Derived> -bool RecursiveASTVisitor<Derived>::TraverseLambdaExpr(LambdaExpr *S) { - TRY_TO(WalkUpFromLambdaExpr(S)); - +DEF_TRAVERSE_STMT(LambdaExpr, { for (LambdaExpr::capture_iterator C = S->explicit_capture_begin(), CEnd = S->explicit_capture_end(); C != CEnd; ++C) { @@ -2213,12 +2174,11 @@ bool RecursiveASTVisitor<Derived>::TraverseLambdaExpr(LambdaExpr *S) { } if (Expr *NE = T->getNoexceptExpr()) - TRY_TO(TraverseStmt(NE)); + TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(NE); } - TRY_TO(TraverseLambdaBody(S)); - return true; -} + return TRAVERSE_STMT_BASE(LambdaBody, LambdaExpr, S, Queue); +}) DEF_TRAVERSE_STMT(CXXUnresolvedConstructExpr, { // This is called for code like 'T()', where T is a template argument. @@ -2235,6 +2195,7 @@ DEF_TRAVERSE_STMT(CXXMemberCallExpr, {}) // over the children. DEF_TRAVERSE_STMT(AddrLabelExpr, {}) DEF_TRAVERSE_STMT(ArraySubscriptExpr, {}) +DEF_TRAVERSE_STMT(OMPArraySectionExpr, {}) DEF_TRAVERSE_STMT(BlockExpr, { TRY_TO(TraverseDecl(S->getBlockDecl())); return true; // no child statements to loop through. @@ -2336,6 +2297,34 @@ DEF_TRAVERSE_STMT(MaterializeTemporaryExpr, {}) DEF_TRAVERSE_STMT(CXXFoldExpr, {}) DEF_TRAVERSE_STMT(AtomicExpr, {}) +// For coroutines expressions, traverse either the operand +// as written or the implied calls, depending on what the +// derived class requests. +DEF_TRAVERSE_STMT(CoroutineBodyStmt, { + if (!getDerived().shouldVisitImplicitCode()) { + TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getBody()); + return true; + } +}) +DEF_TRAVERSE_STMT(CoreturnStmt, { + if (!getDerived().shouldVisitImplicitCode()) { + TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getOperand()); + return true; + } +}) +DEF_TRAVERSE_STMT(CoawaitExpr, { + if (!getDerived().shouldVisitImplicitCode()) { + TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getOperand()); + return true; + } +}) +DEF_TRAVERSE_STMT(CoyieldExpr, { + if (!getDerived().shouldVisitImplicitCode()) { + TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getOperand()); + return true; + } +}) + // These literals (all of them) do not need any action. DEF_TRAVERSE_STMT(IntegerLiteral, {}) DEF_TRAVERSE_STMT(CharacterLiteral, {}) @@ -2437,9 +2426,21 @@ DEF_TRAVERSE_STMT(OMPAtomicDirective, DEF_TRAVERSE_STMT(OMPTargetDirective, { TRY_TO(TraverseOMPExecutableDirective(S)); }) +DEF_TRAVERSE_STMT(OMPTargetDataDirective, + { TRY_TO(TraverseOMPExecutableDirective(S)); }) + DEF_TRAVERSE_STMT(OMPTeamsDirective, { TRY_TO(TraverseOMPExecutableDirective(S)); }) +DEF_TRAVERSE_STMT(OMPTaskLoopDirective, + { TRY_TO(TraverseOMPExecutableDirective(S)); }) + +DEF_TRAVERSE_STMT(OMPTaskLoopSimdDirective, + { TRY_TO(TraverseOMPExecutableDirective(S)); }) + +DEF_TRAVERSE_STMT(OMPDistributeDirective, + { TRY_TO(TraverseOMPExecutableDirective(S)); }) + // OpenMP clauses. template <typename Derived> bool RecursiveASTVisitor<Derived>::TraverseOMPClause(OMPClause *C) { @@ -2484,6 +2485,12 @@ bool RecursiveASTVisitor<Derived>::VisitOMPSafelenClause(OMPSafelenClause *C) { } template <typename Derived> +bool RecursiveASTVisitor<Derived>::VisitOMPSimdlenClause(OMPSimdlenClause *C) { + TRY_TO(TraverseStmt(C->getSimdlen())); + return true; +} + +template <typename Derived> bool RecursiveASTVisitor<Derived>::VisitOMPCollapseClause(OMPCollapseClause *C) { TRY_TO(TraverseStmt(C->getNumForLoops())); @@ -2509,7 +2516,8 @@ RecursiveASTVisitor<Derived>::VisitOMPScheduleClause(OMPScheduleClause *C) { } template <typename Derived> -bool RecursiveASTVisitor<Derived>::VisitOMPOrderedClause(OMPOrderedClause *) { +bool RecursiveASTVisitor<Derived>::VisitOMPOrderedClause(OMPOrderedClause *C) { + TRY_TO(TraverseStmt(C->getNumForLoops())); return true; } @@ -2555,6 +2563,21 @@ bool RecursiveASTVisitor<Derived>::VisitOMPSeqCstClause(OMPSeqCstClause *) { } template <typename Derived> +bool RecursiveASTVisitor<Derived>::VisitOMPThreadsClause(OMPThreadsClause *) { + return true; +} + +template <typename Derived> +bool RecursiveASTVisitor<Derived>::VisitOMPSIMDClause(OMPSIMDClause *) { + return true; +} + +template <typename Derived> +bool RecursiveASTVisitor<Derived>::VisitOMPNogroupClause(OMPNogroupClause *) { + return true; +} + +template <typename Derived> template <typename T> bool RecursiveASTVisitor<Derived>::VisitOMPClauseList(T *Node) { for (auto *E : Node->varlists()) { @@ -2615,6 +2638,9 @@ bool RecursiveASTVisitor<Derived>::VisitOMPLinearClause(OMPLinearClause *C) { TRY_TO(TraverseStmt(C->getStep())); TRY_TO(TraverseStmt(C->getCalcStep())); TRY_TO(VisitOMPClauseList(C)); + for (auto *E : C->privates()) { + TRY_TO(TraverseStmt(E)); + } for (auto *E : C->inits()) { TRY_TO(TraverseStmt(E)); } @@ -2671,6 +2697,9 @@ RecursiveASTVisitor<Derived>::VisitOMPReductionClause(OMPReductionClause *C) { TRY_TO(TraverseNestedNameSpecifierLoc(C->getQualifierLoc())); TRY_TO(TraverseDeclarationNameInfo(C->getNameInfo())); TRY_TO(VisitOMPClauseList(C)); + for (auto *E : C->privates()) { + TRY_TO(TraverseStmt(E)); + } for (auto *E : C->lhs_exprs()) { TRY_TO(TraverseStmt(E)); } @@ -2695,6 +2724,59 @@ bool RecursiveASTVisitor<Derived>::VisitOMPDependClause(OMPDependClause *C) { return true; } +template <typename Derived> +bool RecursiveASTVisitor<Derived>::VisitOMPDeviceClause(OMPDeviceClause *C) { + TRY_TO(TraverseStmt(C->getDevice())); + return true; +} + +template <typename Derived> +bool RecursiveASTVisitor<Derived>::VisitOMPMapClause(OMPMapClause *C) { + TRY_TO(VisitOMPClauseList(C)); + return true; +} + +template <typename Derived> +bool RecursiveASTVisitor<Derived>::VisitOMPNumTeamsClause( + OMPNumTeamsClause *C) { + TRY_TO(TraverseStmt(C->getNumTeams())); + return true; +} + +template <typename Derived> +bool RecursiveASTVisitor<Derived>::VisitOMPThreadLimitClause( + OMPThreadLimitClause *C) { + TRY_TO(TraverseStmt(C->getThreadLimit())); + return true; +} + +template <typename Derived> +bool RecursiveASTVisitor<Derived>::VisitOMPPriorityClause( + OMPPriorityClause *C) { + TRY_TO(TraverseStmt(C->getPriority())); + return true; +} + +template <typename Derived> +bool RecursiveASTVisitor<Derived>::VisitOMPGrainsizeClause( + OMPGrainsizeClause *C) { + TRY_TO(TraverseStmt(C->getGrainsize())); + return true; +} + +template <typename Derived> +bool RecursiveASTVisitor<Derived>::VisitOMPNumTasksClause( + OMPNumTasksClause *C) { + TRY_TO(TraverseStmt(C->getNumTasks())); + return true; +} + +template <typename Derived> +bool RecursiveASTVisitor<Derived>::VisitOMPHintClause(OMPHintClause *C) { + TRY_TO(TraverseStmt(C->getHint())); + 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 @@ -2713,6 +2795,8 @@ bool RecursiveASTVisitor<Derived>::VisitOMPDependClause(OMPDependClause *C) { // Every class that has getQualifier. #undef DEF_TRAVERSE_STMT +#undef TRAVERSE_STMT +#undef TRAVERSE_STMT_BASE #undef TRY_TO diff --git a/contrib/llvm/tools/clang/include/clang/AST/Redeclarable.h b/contrib/llvm/tools/clang/include/clang/AST/Redeclarable.h index 92046d5..eaa22f8 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/Redeclarable.h +++ b/contrib/llvm/tools/clang/include/clang/AST/Redeclarable.h @@ -20,6 +20,7 @@ #include <iterator> namespace clang { +class ASTContext; /// \brief Provides common interface for the Decls that can be redeclared. template<typename decl_type> @@ -32,7 +33,11 @@ protected: &ExternalASTSource::CompleteRedeclChain> KnownLatest; - typedef const ASTContext *UninitializedLatest; + /// We store a pointer to the ASTContext in the UninitializedLatest + /// pointer, but to avoid circular type dependencies when we steal the low + /// bits of this pointer, we use a raw void* here. + typedef const void *UninitializedLatest; + typedef Decl *Previous; /// A pointer to either an uninitialized latest declaration (where either @@ -47,7 +52,7 @@ protected: enum LatestTag { LatestLink }; DeclLink(LatestTag, const ASTContext &Ctx) - : Next(NotKnownLatest(&Ctx)) {} + : Next(NotKnownLatest(reinterpret_cast<UninitializedLatest>(&Ctx))) {} DeclLink(PreviousTag, decl_type *D) : Next(NotKnownLatest(Previous(D))) {} @@ -67,7 +72,8 @@ protected: return static_cast<decl_type*>(NKL.get<Previous>()); // Allocate the generational 'most recent' cache now, if needed. - Next = KnownLatest(*NKL.get<UninitializedLatest>(), + Next = KnownLatest(*reinterpret_cast<const ASTContext *>( + NKL.get<UninitializedLatest>()), const_cast<decl_type *>(D)); } @@ -83,7 +89,9 @@ protected: assert(NextIsLatest() && "decl became canonical unexpectedly"); if (Next.is<NotKnownLatest>()) { NotKnownLatest NKL = Next.get<NotKnownLatest>(); - Next = KnownLatest(*NKL.get<UninitializedLatest>(), D); + Next = KnownLatest(*reinterpret_cast<const ASTContext *>( + NKL.get<UninitializedLatest>()), + D); } else { auto Latest = Next.get<KnownLatest>(); Latest.set(D); diff --git a/contrib/llvm/tools/clang/include/clang/AST/Stmt.h b/contrib/llvm/tools/clang/include/clang/AST/Stmt.h index ce9449d..e48b7dc 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/Stmt.h +++ b/contrib/llvm/tools/clang/include/clang/AST/Stmt.h @@ -22,6 +22,7 @@ #include "clang/Basic/SourceLocation.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/PointerIntPair.h" +#include "llvm/ADT/iterator.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/ErrorHandling.h" #include <string> @@ -49,57 +50,6 @@ namespace clang { class Token; class VarDecl; - //===--------------------------------------------------------------------===// - // ExprIterator - Iterators for iterating over Stmt* arrays that contain - // only Expr*. This is needed because AST nodes use Stmt* arrays to store - // references to children (to be compatible with StmtIterator). - //===--------------------------------------------------------------------===// - - class Stmt; - class Expr; - - class ExprIterator : public std::iterator<std::forward_iterator_tag, - Expr *&, ptrdiff_t, - Expr *&, Expr *&> { - Stmt** I; - public: - ExprIterator(Stmt** i) : I(i) {} - ExprIterator() : I(nullptr) {} - ExprIterator& operator++() { ++I; return *this; } - ExprIterator operator-(size_t i) { return I-i; } - ExprIterator operator+(size_t i) { return I+i; } - Expr* operator[](size_t idx); - // FIXME: Verify that this will correctly return a signed distance. - signed operator-(const ExprIterator& R) const { return I - R.I; } - Expr* operator*() const; - Expr* operator->() const; - bool operator==(const ExprIterator& R) const { return I == R.I; } - bool operator!=(const ExprIterator& R) const { return I != R.I; } - bool operator>(const ExprIterator& R) const { return I > R.I; } - bool operator>=(const ExprIterator& R) const { return I >= R.I; } - }; - - class ConstExprIterator : public std::iterator<std::forward_iterator_tag, - const Expr *&, ptrdiff_t, - const Expr *&, - const Expr *&> { - const Stmt * const *I; - public: - ConstExprIterator(const Stmt * const *i) : I(i) {} - ConstExprIterator() : I(nullptr) {} - ConstExprIterator& operator++() { ++I; return *this; } - ConstExprIterator operator+(size_t i) const { return I+i; } - ConstExprIterator operator-(size_t i) const { return I-i; } - const Expr * operator[](size_t idx) const; - signed operator-(const ConstExprIterator& R) const { return I - R.I; } - const Expr * operator*() const; - const Expr * operator->() const; - bool operator==(const ConstExprIterator& R) const { return I == R.I; } - bool operator!=(const ConstExprIterator& R) const { return I != R.I; } - bool operator>(const ConstExprIterator& R) const { return I > R.I; } - bool operator>=(const ConstExprIterator& R) const { return I >= R.I; } - }; - //===----------------------------------------------------------------------===// // AST classes for statements. //===----------------------------------------------------------------------===// @@ -121,10 +71,10 @@ public: // Make vanilla 'new' and 'delete' illegal for Stmts. protected: - void* operator new(size_t bytes) throw() { + void *operator new(size_t bytes) LLVM_NOEXCEPT { llvm_unreachable("Stmts cannot be allocated with regular 'new'."); } - void operator delete(void* data) throw() { + void operator delete(void *data) LLVM_NOEXCEPT { llvm_unreachable("Stmts cannot be released with regular 'delete'."); } @@ -322,14 +272,12 @@ public: return operator new(bytes, *C, alignment); } - void* operator new(size_t bytes, void* mem) throw() { - return mem; - } + void *operator new(size_t bytes, void *mem) LLVM_NOEXCEPT { return mem; } - void operator delete(void*, const ASTContext&, unsigned) throw() { } - void operator delete(void*, const ASTContext*, unsigned) throw() { } - void operator delete(void*, size_t) throw() { } - void operator delete(void*, void*) throw() { } + void operator delete(void *, const ASTContext &, unsigned) LLVM_NOEXCEPT {} + void operator delete(void *, const ASTContext *, unsigned) LLVM_NOEXCEPT {} + void operator delete(void *, size_t) LLVM_NOEXCEPT {} + void operator delete(void *, void *) LLVM_NOEXCEPT {} public: /// \brief A placeholder type used to construct an empty shell of a @@ -337,6 +285,39 @@ public: /// de-serialization). struct EmptyShell { }; +protected: + /// Iterator for iterating over Stmt * arrays that contain only Expr * + /// + /// This is needed because AST nodes use Stmt* arrays to store + /// references to children (to be compatible with StmtIterator). + struct ExprIterator + : llvm::iterator_adaptor_base<ExprIterator, Stmt **, + std::random_access_iterator_tag, Expr *> { + ExprIterator() : iterator_adaptor_base(nullptr) {} + ExprIterator(Stmt **I) : iterator_adaptor_base(I) {} + + reference operator*() const { + assert((*I)->getStmtClass() >= firstExprConstant && + (*I)->getStmtClass() <= lastExprConstant); + return *reinterpret_cast<Expr **>(I); + } + }; + + /// Const iterator for iterating over Stmt * arrays that contain only Expr * + struct ConstExprIterator + : llvm::iterator_adaptor_base<ConstExprIterator, const Stmt *const *, + std::random_access_iterator_tag, + const Expr *const> { + ConstExprIterator() : iterator_adaptor_base(nullptr) {} + ConstExprIterator(const Stmt *const *I) : iterator_adaptor_base(I) {} + + reference operator*() const { + assert((*I)->getStmtClass() >= firstExprConstant && + (*I)->getStmtClass() <= lastExprConstant); + return *reinterpret_cast<const Expr *const *>(I); + } + }; + private: /// \brief Whether statistic collection is enabled. static bool StatisticsEnabled; @@ -411,19 +392,20 @@ public: typedef StmtIterator child_iterator; typedef ConstStmtIterator const_child_iterator; - typedef StmtRange child_range; - typedef ConstStmtRange const_child_range; + typedef llvm::iterator_range<child_iterator> child_range; + typedef llvm::iterator_range<const_child_iterator> const_child_range; child_range children(); const_child_range children() const { - return const_cast<Stmt*>(this)->children(); + auto Children = const_cast<Stmt *>(this)->children(); + return const_child_range(Children.begin(), Children.end()); } - child_iterator child_begin() { return children().first; } - child_iterator child_end() { return children().second; } + child_iterator child_begin() { return children().begin(); } + child_iterator child_end() { return children().end(); } - const_child_iterator child_begin() const { return children().first; } - const_child_iterator child_end() const { return children().second; } + const_child_iterator child_begin() const { return children().begin(); } + const_child_iterator child_end() const { return children().end(); } /// \brief Produce a unique representation of the given statement. /// @@ -544,7 +526,9 @@ public: return T->getStmtClass() == NullStmtClass; } - child_range children() { return child_range(); } + child_range children() { + return child_range(child_iterator(), child_iterator()); + } friend class ASTStmtReader; friend class ASTStmtWriter; @@ -574,7 +558,7 @@ public: CompoundStmtBits.NumStmts = 0; } - void setStmts(const ASTContext &C, Stmt **Stmts, unsigned NumStmts); + void setStmts(const ASTContext &C, ArrayRef<Stmt *> Stmts); bool body_empty() const { return CompoundStmtBits.NumStmts == 0; } unsigned size() const { return CompoundStmtBits.NumStmts; } @@ -643,7 +627,8 @@ public: } const_child_range children() const { - return child_range(Body, Body + CompoundStmtBits.NumStmts); + return const_child_range(child_iterator(Body), + child_iterator(Body + CompoundStmtBits.NumStmts)); } }; @@ -840,18 +825,20 @@ class AttributedStmt : public Stmt { AttributedStmt(SourceLocation Loc, ArrayRef<const Attr*> Attrs, Stmt *SubStmt) : Stmt(AttributedStmtClass), SubStmt(SubStmt), AttrLoc(Loc), NumAttrs(Attrs.size()) { - memcpy(getAttrArrayPtr(), Attrs.data(), Attrs.size() * sizeof(Attr *)); + std::copy(Attrs.begin(), Attrs.end(), getAttrArrayPtr()); } explicit AttributedStmt(EmptyShell Empty, unsigned NumAttrs) : Stmt(AttributedStmtClass, Empty), NumAttrs(NumAttrs) { - memset(getAttrArrayPtr(), 0, NumAttrs * sizeof(Attr *)); + std::fill_n(getAttrArrayPtr(), NumAttrs, nullptr); } - Attr *const *getAttrArrayPtr() const { - return reinterpret_cast<Attr *const *>(this + 1); + const Attr *const *getAttrArrayPtr() const { + return reinterpret_cast<const Attr *const *>(this + 1); + } + const Attr **getAttrArrayPtr() { + return reinterpret_cast<const Attr **>(this + 1); } - Attr **getAttrArrayPtr() { return reinterpret_cast<Attr **>(this + 1); } public: static AttributedStmt *Create(const ASTContext &C, SourceLocation Loc, @@ -1239,7 +1226,9 @@ public: } // Iterators - child_range children() { return child_range(); } + child_range children() { + return child_range(child_iterator(), child_iterator()); + } }; /// IndirectGotoStmt - This represents an indirect goto. @@ -1307,7 +1296,9 @@ public: } // Iterators - child_range children() { return child_range(); } + child_range children() { + return child_range(child_iterator(), child_iterator()); + } }; /// BreakStmt - This represents a break. @@ -1335,7 +1326,9 @@ public: } // Iterators - child_range children() { return child_range(); } + child_range children() { + return child_range(child_iterator(), child_iterator()); + } }; @@ -1390,7 +1383,7 @@ public: // Iterators child_range children() { if (RetExpr) return child_range(&RetExpr, &RetExpr+1); - return child_range(); + return child_range(child_iterator(), child_iterator()); } }; @@ -1974,7 +1967,9 @@ public: } // Iterators - child_range children() { return child_range(); } + child_range children() { + return child_range(child_iterator(), child_iterator()); + } }; /// \brief This captures a statement into a function. For example, the following @@ -1993,6 +1988,7 @@ public: enum VariableCaptureKind { VCK_This, VCK_ByRef, + VCK_ByCopy, VCK_VLAType, }; @@ -2012,24 +2008,10 @@ public: /// \param Var The variable being captured, or null if capturing this. /// Capture(SourceLocation Loc, VariableCaptureKind Kind, - VarDecl *Var = nullptr) - : VarAndKind(Var, Kind), Loc(Loc) { - switch (Kind) { - case VCK_This: - assert(!Var && "'this' capture cannot have a variable!"); - break; - case VCK_ByRef: - assert(Var && "capturing by reference must have a variable!"); - break; - case VCK_VLAType: - assert(!Var && - "Variable-length array type capture cannot have a variable!"); - break; - } - } + VarDecl *Var = nullptr); /// \brief Determine the kind of capture. - VariableCaptureKind getCaptureKind() const { return VarAndKind.getInt(); } + VariableCaptureKind getCaptureKind() const; /// \brief Retrieve the source location at which the variable or 'this' was /// first used. @@ -2038,9 +2020,14 @@ public: /// \brief Determine whether this capture handles the C++ 'this' pointer. bool capturesThis() const { return getCaptureKind() == VCK_This; } - /// \brief Determine whether this capture handles a variable. + /// \brief Determine whether this capture handles a variable (by reference). bool capturesVariable() const { return getCaptureKind() == VCK_ByRef; } + /// \brief Determine whether this capture handles a variable by copy. + bool capturesVariableByCopy() const { + return getCaptureKind() == VCK_ByCopy; + } + /// \brief Determine whether this capture handles a variable-length array /// type. bool capturesVariableArrayType() const { @@ -2050,11 +2037,8 @@ public: /// \brief Retrieve the declaration of the variable being captured. /// /// This operation is only valid if this capture captures a variable. - VarDecl *getCapturedVar() const { - assert(capturesVariable() && - "No variable available for 'this' or VAT capture"); - return VarAndKind.getPointer(); - } + VarDecl *getCapturedVar() const; + friend class ASTStmtReader; }; @@ -2076,8 +2060,10 @@ private: /// \brief Construct an empty captured statement. CapturedStmt(EmptyShell Empty, unsigned NumCaptures); - Stmt **getStoredStmts() const { - return reinterpret_cast<Stmt **>(const_cast<CapturedStmt *>(this) + 1); + Stmt **getStoredStmts() { return reinterpret_cast<Stmt **>(this + 1); } + + Stmt *const *getStoredStmts() const { + return reinterpret_cast<Stmt *const *>(this + 1); } Capture *getStoredCaptures() const; @@ -2096,31 +2082,20 @@ public: /// \brief Retrieve the statement being captured. Stmt *getCapturedStmt() { return getStoredStmts()[NumCaptures]; } - const Stmt *getCapturedStmt() const { - return const_cast<CapturedStmt *>(this)->getCapturedStmt(); - } + const Stmt *getCapturedStmt() const { return getStoredStmts()[NumCaptures]; } /// \brief Retrieve the outlined function declaration. - CapturedDecl *getCapturedDecl() { return CapDeclAndKind.getPointer(); } - const CapturedDecl *getCapturedDecl() const { - return const_cast<CapturedStmt *>(this)->getCapturedDecl(); - } + CapturedDecl *getCapturedDecl(); + const CapturedDecl *getCapturedDecl() const; /// \brief Set the outlined function declaration. - void setCapturedDecl(CapturedDecl *D) { - assert(D && "null CapturedDecl"); - CapDeclAndKind.setPointer(D); - } + void setCapturedDecl(CapturedDecl *D); /// \brief Retrieve the captured region kind. - CapturedRegionKind getCapturedRegionKind() const { - return CapDeclAndKind.getInt(); - } + CapturedRegionKind getCapturedRegionKind() const; /// \brief Set the captured region kind. - void setCapturedRegionKind(CapturedRegionKind Kind) { - CapDeclAndKind.setInt(Kind); - } + void setCapturedRegionKind(CapturedRegionKind Kind); /// \brief Retrieve the record declaration for captured variables. const RecordDecl *getCapturedRecordDecl() const { return TheRecordDecl; } @@ -2164,18 +2139,36 @@ public: typedef Expr **capture_init_iterator; typedef llvm::iterator_range<capture_init_iterator> capture_init_range; - capture_init_range capture_inits() const { + /// \brief Const iterator that walks over the capture initialization + /// arguments. + typedef Expr *const *const_capture_init_iterator; + typedef llvm::iterator_range<const_capture_init_iterator> + const_capture_init_range; + + capture_init_range capture_inits() { return capture_init_range(capture_init_begin(), capture_init_end()); } + const_capture_init_range capture_inits() const { + return const_capture_init_range(capture_init_begin(), capture_init_end()); + } + /// \brief Retrieve the first initialization argument. - capture_init_iterator capture_init_begin() const { + capture_init_iterator capture_init_begin() { return reinterpret_cast<Expr **>(getStoredStmts()); } + const_capture_init_iterator capture_init_begin() const { + return reinterpret_cast<Expr *const *>(getStoredStmts()); + } + /// \brief Retrieve the iterator pointing one past the last initialization /// argument. - capture_init_iterator capture_init_end() const { + capture_init_iterator capture_init_end() { + return capture_init_begin() + NumCaptures; + } + + const_capture_init_iterator capture_init_end() const { return capture_init_begin() + NumCaptures; } diff --git a/contrib/llvm/tools/clang/include/clang/AST/StmtCXX.h b/contrib/llvm/tools/clang/include/clang/AST/StmtCXX.h index 567a772..1ca73e2 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/StmtCXX.h +++ b/contrib/llvm/tools/clang/include/clang/AST/StmtCXX.h @@ -131,12 +131,16 @@ class CXXForRangeStmt : public Stmt { // SubExprs[RANGE] is an expression or declstmt. // SubExprs[COND] and SubExprs[INC] are expressions. Stmt *SubExprs[END]; + SourceLocation CoawaitLoc; SourceLocation ColonLoc; SourceLocation RParenLoc; + + friend class ASTStmtReader; public: CXXForRangeStmt(DeclStmt *Range, DeclStmt *BeginEnd, Expr *Cond, Expr *Inc, DeclStmt *LoopVar, Stmt *Body, - SourceLocation FL, SourceLocation CL, SourceLocation RPL); + SourceLocation FL, SourceLocation CAL, SourceLocation CL, + SourceLocation RPL); CXXForRangeStmt(EmptyShell Empty) : Stmt(CXXForRangeStmtClass, Empty) { } @@ -181,13 +185,10 @@ public: void setLoopVarStmt(Stmt *S) { SubExprs[LOOPVAR] = S; } void setBody(Stmt *S) { SubExprs[BODY] = S; } - SourceLocation getForLoc() const { return ForLoc; } - void setForLoc(SourceLocation Loc) { ForLoc = Loc; } + SourceLocation getCoawaitLoc() const { return CoawaitLoc; } SourceLocation getColonLoc() const { return ColonLoc; } - void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; } SourceLocation getRParenLoc() const { return RParenLoc; } - void setRParenLoc(SourceLocation Loc) { RParenLoc = Loc; } SourceLocation getLocStart() const LLVM_READONLY { return ForLoc; } SourceLocation getLocEnd() const LLVM_READONLY { @@ -287,6 +288,130 @@ public: } }; +/// \brief Represents the body of a coroutine. This wraps the normal function +/// body and holds the additional semantic context required to set up and tear +/// down the coroutine frame. +class CoroutineBodyStmt : public Stmt { + enum SubStmt { + Body, ///< The body of the coroutine. + Promise, ///< The promise statement. + InitSuspend, ///< The initial suspend statement, run before the body. + FinalSuspend, ///< The final suspend statement, run after the body. + OnException, ///< Handler for exceptions thrown in the body. + OnFallthrough, ///< Handler for control flow falling off the body. + ReturnValue, ///< Return value for thunk function. + FirstParamMove ///< First offset for move construction of parameter copies. + }; + Stmt *SubStmts[SubStmt::FirstParamMove]; + + friend class ASTStmtReader; +public: + CoroutineBodyStmt(Stmt *Body, Stmt *Promise, Stmt *InitSuspend, + Stmt *FinalSuspend, Stmt *OnException, Stmt *OnFallthrough, + Expr *ReturnValue, ArrayRef<Expr *> ParamMoves) + : Stmt(CoroutineBodyStmtClass) { + SubStmts[CoroutineBodyStmt::Body] = Body; + SubStmts[CoroutineBodyStmt::Promise] = Promise; + SubStmts[CoroutineBodyStmt::InitSuspend] = InitSuspend; + SubStmts[CoroutineBodyStmt::FinalSuspend] = FinalSuspend; + SubStmts[CoroutineBodyStmt::OnException] = OnException; + SubStmts[CoroutineBodyStmt::OnFallthrough] = OnFallthrough; + SubStmts[CoroutineBodyStmt::ReturnValue] = ReturnValue; + // FIXME: Tail-allocate space for parameter move expressions and store them. + assert(ParamMoves.empty() && "not implemented yet"); + } + + /// \brief Retrieve the body of the coroutine as written. This will be either + /// a CompoundStmt or a TryStmt. + Stmt *getBody() const { + return SubStmts[SubStmt::Body]; + } + + Stmt *getPromiseDeclStmt() const { return SubStmts[SubStmt::Promise]; } + VarDecl *getPromiseDecl() const { + return cast<VarDecl>(cast<DeclStmt>(getPromiseDeclStmt())->getSingleDecl()); + } + + Stmt *getInitSuspendStmt() const { return SubStmts[SubStmt::InitSuspend]; } + Stmt *getFinalSuspendStmt() const { return SubStmts[SubStmt::FinalSuspend]; } + + Stmt *getExceptionHandler() const { return SubStmts[SubStmt::OnException]; } + Stmt *getFallthroughHandler() const { + return SubStmts[SubStmt::OnFallthrough]; + } + + Expr *getReturnValueInit() const { + return cast<Expr>(SubStmts[SubStmt::ReturnValue]); + } + + SourceLocation getLocStart() const LLVM_READONLY { + return getBody()->getLocStart(); + } + SourceLocation getLocEnd() const LLVM_READONLY { + return getBody()->getLocEnd(); + } + + child_range children() { + return child_range(SubStmts, SubStmts + SubStmt::FirstParamMove); + } + + static bool classof(const Stmt *T) { + return T->getStmtClass() == CoroutineBodyStmtClass; + } +}; + +/// \brief Represents a 'co_return' statement in the C++ Coroutines TS. +/// +/// This statament models the initialization of the coroutine promise +/// (encapsulating the eventual notional return value) from an expression +/// (or braced-init-list), followed by termination of the coroutine. +/// +/// This initialization is modeled by the evaluation of the operand +/// followed by a call to one of: +/// <promise>.return_value(<operand>) +/// <promise>.return_void() +/// which we name the "promise call". +class CoreturnStmt : public Stmt { + SourceLocation CoreturnLoc; + + enum SubStmt { Operand, PromiseCall, Count }; + Stmt *SubStmts[SubStmt::Count]; + + friend class ASTStmtReader; +public: + CoreturnStmt(SourceLocation CoreturnLoc, Stmt *Operand, Stmt *PromiseCall) + : Stmt(CoreturnStmtClass), CoreturnLoc(CoreturnLoc) { + SubStmts[SubStmt::Operand] = Operand; + SubStmts[SubStmt::PromiseCall] = PromiseCall; + } + + SourceLocation getKeywordLoc() const { return CoreturnLoc; } + + /// \brief Retrieve the operand of the 'co_return' statement. Will be nullptr + /// if none was specified. + Expr *getOperand() const { return static_cast<Expr*>(SubStmts[Operand]); } + + /// \brief Retrieve the promise call that results from this 'co_return' + /// statement. Will be nullptr if either the coroutine has not yet been + /// finalized or the coroutine has no eventual return type. + Expr *getPromiseCall() const { + return static_cast<Expr*>(SubStmts[PromiseCall]); + } + + SourceLocation getLocStart() const LLVM_READONLY { return CoreturnLoc; } + SourceLocation getLocEnd() const LLVM_READONLY { + return getOperand()->getLocEnd(); + } + + child_range children() { + return child_range(SubStmts, SubStmts + SubStmt::Count); + } + + static bool classof(const Stmt *T) { + return T->getStmtClass() == CoreturnStmtClass; + } +}; + } // end namespace clang #endif diff --git a/contrib/llvm/tools/clang/include/clang/AST/StmtIterator.h b/contrib/llvm/tools/clang/include/clang/AST/StmtIterator.h index a5a57af..81f8ad43 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/StmtIterator.h +++ b/contrib/llvm/tools/clang/include/clang/AST/StmtIterator.h @@ -139,86 +139,6 @@ struct ConstStmtIterator : public StmtIteratorImpl<ConstStmtIterator, StmtIteratorImpl<ConstStmtIterator,const Stmt*>(RHS) {} }; -/// A range of statement iterators. -/// -/// This class provides some extra functionality beyond std::pair -/// in order to allow the following idiom: -/// for (StmtRange range = stmt->children(); range; ++range) -struct StmtRange : std::pair<StmtIterator,StmtIterator> { - StmtRange() {} - StmtRange(const StmtIterator &begin, const StmtIterator &end) - : std::pair<StmtIterator,StmtIterator>(begin, end) {} - - bool empty() const { return first == second; } - explicit operator bool() const { return !empty(); } - - Stmt *operator->() const { return first.operator->(); } - Stmt *&operator*() const { return first.operator*(); } - - StmtRange &operator++() { - assert(!empty() && "incrementing on empty range"); - ++first; - return *this; - } - - StmtRange operator++(int) { - assert(!empty() && "incrementing on empty range"); - StmtRange copy = *this; - ++first; - return copy; - } - - friend const StmtIterator &begin(const StmtRange &range) { - return range.first; - } - friend const StmtIterator &end(const StmtRange &range) { - return range.second; - } -}; - -/// A range of const statement iterators. -/// -/// This class provides some extra functionality beyond std::pair -/// in order to allow the following idiom: -/// for (ConstStmtRange range = stmt->children(); range; ++range) -struct ConstStmtRange : std::pair<ConstStmtIterator,ConstStmtIterator> { - ConstStmtRange() {} - ConstStmtRange(const ConstStmtIterator &begin, - const ConstStmtIterator &end) - : std::pair<ConstStmtIterator,ConstStmtIterator>(begin, end) {} - ConstStmtRange(const StmtRange &range) - : std::pair<ConstStmtIterator,ConstStmtIterator>(range.first, range.second) - {} - ConstStmtRange(const StmtIterator &begin, const StmtIterator &end) - : std::pair<ConstStmtIterator,ConstStmtIterator>(begin, end) {} - - bool empty() const { return first == second; } - explicit operator bool() const { return !empty(); } - - const Stmt *operator->() const { return first.operator->(); } - const Stmt *operator*() const { return first.operator*(); } - - ConstStmtRange &operator++() { - assert(!empty() && "incrementing on empty range"); - ++first; - return *this; - } - - ConstStmtRange operator++(int) { - assert(!empty() && "incrementing on empty range"); - ConstStmtRange copy = *this; - ++first; - return copy; - } - - friend const ConstStmtIterator &begin(const ConstStmtRange &range) { - return range.first; - } - friend const ConstStmtIterator &end(const ConstStmtRange &range) { - return range.second; - } -}; - } // end namespace clang #endif diff --git a/contrib/llvm/tools/clang/include/clang/AST/StmtOpenMP.h b/contrib/llvm/tools/clang/include/clang/AST/StmtOpenMP.h index 708b866..1ba859c 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/StmtOpenMP.h +++ b/contrib/llvm/tools/clang/include/clang/AST/StmtOpenMP.h @@ -92,65 +92,78 @@ public: /// \brief Iterates over a filtered subrange of clauses applied to a /// directive. /// - /// This iterator visits only those declarations that meet some run-time - /// criteria. - template <class FilterPredicate> class filtered_clause_iterator { - protected: - ArrayRef<OMPClause *>::const_iterator Current; + /// This iterator visits only clauses of type SpecificClause. + template <typename SpecificClause> + class specific_clause_iterator + : public llvm::iterator_adaptor_base< + specific_clause_iterator<SpecificClause>, + ArrayRef<OMPClause *>::const_iterator, std::forward_iterator_tag, + const SpecificClause *, ptrdiff_t, const SpecificClause *, + const SpecificClause *> { ArrayRef<OMPClause *>::const_iterator End; - FilterPredicate Pred; + void SkipToNextClause() { - while (Current != End && !Pred(*Current)) - ++Current; + while (this->I != End && !isa<SpecificClause>(*this->I)) + ++this->I; } public: - typedef const OMPClause *value_type; - filtered_clause_iterator() : Current(), End() {} - filtered_clause_iterator(ArrayRef<OMPClause *> Arr, FilterPredicate Pred) - : Current(Arr.begin()), End(Arr.end()), Pred(std::move(Pred)) { + explicit specific_clause_iterator(ArrayRef<OMPClause *> Clauses) + : specific_clause_iterator::iterator_adaptor_base(Clauses.begin()), + End(Clauses.end()) { SkipToNextClause(); } - value_type operator*() const { return *Current; } - value_type operator->() const { return *Current; } - filtered_clause_iterator &operator++() { - ++Current; - SkipToNextClause(); - return *this; - } - filtered_clause_iterator operator++(int) { - filtered_clause_iterator tmp(*this); - ++(*this); - return tmp; + const SpecificClause *operator*() const { + return cast<SpecificClause>(*this->I); } + const SpecificClause *operator->() const { return **this; } - bool operator!() { return Current == End; } - explicit operator bool() { return Current != End; } - bool empty() const { return Current == End; } + specific_clause_iterator &operator++() { + ++this->I; + SkipToNextClause(); + return *this; + } }; - template <typename Fn> - filtered_clause_iterator<Fn> getFilteredClauses(Fn &&fn) const { - return filtered_clause_iterator<Fn>(clauses(), std::move(fn)); + template <typename SpecificClause> + static llvm::iterator_range<specific_clause_iterator<SpecificClause>> + getClausesOfKind(ArrayRef<OMPClause *> Clauses) { + return {specific_clause_iterator<SpecificClause>(Clauses), + specific_clause_iterator<SpecificClause>( + llvm::makeArrayRef(Clauses.end(), 0))}; } - struct ClauseKindFilter { - OpenMPClauseKind Kind; - bool operator()(const OMPClause *clause) const { - return clause->getClauseKind() == Kind; - } - }; - filtered_clause_iterator<ClauseKindFilter> - getClausesOfKind(OpenMPClauseKind Kind) const { - return getFilteredClauses(ClauseKindFilter{Kind}); + + template <typename SpecificClause> + llvm::iterator_range<specific_clause_iterator<SpecificClause>> + getClausesOfKind() const { + return getClausesOfKind<SpecificClause>(clauses()); } - /// \brief Gets a single clause of the specified kind \a K associated with the + /// Gets a single clause of the specified kind associated with the /// current directive iff there is only one clause of this kind (and assertion /// is fired if there is more than one clause is associated with the - /// directive). Returns nullptr if no clause of kind \a K is associated with + /// directive). Returns nullptr if no clause of this kind is associated with /// the directive. - const OMPClause *getSingleClause(OpenMPClauseKind K) const; + template <typename SpecificClause> + const SpecificClause *getSingleClause() const { + auto Clauses = getClausesOfKind<SpecificClause>(); + + if (Clauses.begin() != Clauses.end()) { + assert(std::next(Clauses.begin()) == Clauses.end() && + "There are at least 2 clauses of the specified kind"); + return *Clauses.begin(); + } + return nullptr; + } + + /// Returns true if the current directive has one or more clauses of a + /// specific kind. + template <typename SpecificClause> + bool hasClausesOfKind() const { + auto Clauses = getClausesOfKind<SpecificClause>(); + return Clauses.begin() != Clauses.end(); + } /// \brief Returns starting location of directive kind. SourceLocation getLocStart() const { return StartLoc; } @@ -195,7 +208,7 @@ public: child_range children() { if (!hasAssociatedStmt()) - return child_range(); + return child_range(child_iterator(), child_iterator()); Stmt **ChildStorage = reinterpret_cast<Stmt **>(getClauses().end()); return child_range(ChildStorage, ChildStorage + NumChildren); } @@ -217,6 +230,10 @@ public: /// variables 'c' and 'd'. /// class OMPParallelDirective : public OMPExecutableDirective { + friend class ASTStmtReader; + /// \brief true if the construct has inner cancel directive. + bool HasCancel; + /// \brief Build directive with the given start and end location. /// /// \param StartLoc Starting location of the directive (directive keyword). @@ -225,7 +242,8 @@ class OMPParallelDirective : public OMPExecutableDirective { OMPParallelDirective(SourceLocation StartLoc, SourceLocation EndLoc, unsigned NumClauses) : OMPExecutableDirective(this, OMPParallelDirectiveClass, OMPD_parallel, - StartLoc, EndLoc, NumClauses, 1) {} + StartLoc, EndLoc, NumClauses, 1), + HasCancel(false) {} /// \brief Build an empty directive. /// @@ -234,7 +252,11 @@ class OMPParallelDirective : public OMPExecutableDirective { explicit OMPParallelDirective(unsigned NumClauses) : OMPExecutableDirective(this, OMPParallelDirectiveClass, OMPD_parallel, SourceLocation(), SourceLocation(), NumClauses, - 1) {} + 1), + HasCancel(false) {} + + /// \brief Set cancel state. + void setHasCancel(bool Has) { HasCancel = Has; } public: /// \brief Creates directive with a list of \a Clauses. @@ -244,10 +266,11 @@ public: /// \param EndLoc Ending Location of the directive. /// \param Clauses List of clauses. /// \param AssociatedStmt Statement associated with the directive. + /// \param HasCancel true if this directive has inner cancel directive. /// static OMPParallelDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, - ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); + ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, bool HasCancel); /// \brief Creates an empty directive with the place for \a N clauses. /// @@ -257,6 +280,9 @@ public: static OMPParallelDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses, 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() == OMPParallelDirectiveClass; } @@ -311,11 +337,18 @@ class OMPLoopDirective : public OMPExecutableDirective { return MutableArrayRef<Expr *>(Storage, CollapsedNum); } + /// \brief Get the private counters storage. + MutableArrayRef<Expr *> getPrivateCounters() { + Expr **Storage = reinterpret_cast<Expr **>(&*std::next( + child_begin(), getArraysOffset(getDirectiveKind()) + CollapsedNum)); + return MutableArrayRef<Expr *>(Storage, CollapsedNum); + } + /// \brief Get the updates storage. MutableArrayRef<Expr *> getInits() { Expr **Storage = reinterpret_cast<Expr **>( &*std::next(child_begin(), - getArraysOffset(getDirectiveKind()) + CollapsedNum)); + getArraysOffset(getDirectiveKind()) + 2 * CollapsedNum)); return MutableArrayRef<Expr *>(Storage, CollapsedNum); } @@ -323,7 +356,7 @@ class OMPLoopDirective : public OMPExecutableDirective { MutableArrayRef<Expr *> getUpdates() { Expr **Storage = reinterpret_cast<Expr **>( &*std::next(child_begin(), - getArraysOffset(getDirectiveKind()) + 2 * CollapsedNum)); + getArraysOffset(getDirectiveKind()) + 3 * CollapsedNum)); return MutableArrayRef<Expr *>(Storage, CollapsedNum); } @@ -331,7 +364,7 @@ class OMPLoopDirective : public OMPExecutableDirective { MutableArrayRef<Expr *> getFinals() { Expr **Storage = reinterpret_cast<Expr **>( &*std::next(child_begin(), - getArraysOffset(getDirectiveKind()) + 3 * CollapsedNum)); + getArraysOffset(getDirectiveKind()) + 4 * CollapsedNum)); return MutableArrayRef<Expr *>(Storage, CollapsedNum); } @@ -358,15 +391,19 @@ protected: /// \brief Offset to the start of children expression arrays. static unsigned getArraysOffset(OpenMPDirectiveKind Kind) { - return isOpenMPWorksharingDirective(Kind) ? WorksharingEnd - : DefaultEnd; + return (isOpenMPWorksharingDirective(Kind) || + isOpenMPTaskLoopDirective(Kind) || + isOpenMPDistributeDirective(Kind)) + ? WorksharingEnd + : DefaultEnd; } /// \brief Children number. static unsigned numLoopChildren(unsigned CollapsedNum, OpenMPDirectiveKind Kind) { - return getArraysOffset(Kind) + - 4 * CollapsedNum; // Counters, Inits, Updates and Finals + return getArraysOffset(Kind) + 5 * CollapsedNum; // Counters, + // PrivateCounters, Inits, + // Updates and Finals } void setIterationVariable(Expr *IV) { @@ -387,41 +424,56 @@ protected: void setInit(Expr *Init) { *std::next(child_begin(), InitOffset) = Init; } void setInc(Expr *Inc) { *std::next(child_begin(), IncOffset) = Inc; } void setIsLastIterVariable(Expr *IL) { - assert(isOpenMPWorksharingDirective(getDirectiveKind()) && + assert((isOpenMPWorksharingDirective(getDirectiveKind()) || + isOpenMPTaskLoopDirective(getDirectiveKind()) || + isOpenMPDistributeDirective(getDirectiveKind())) && "expected worksharing loop directive"); *std::next(child_begin(), IsLastIterVariableOffset) = IL; } void setLowerBoundVariable(Expr *LB) { - assert(isOpenMPWorksharingDirective(getDirectiveKind()) && + assert((isOpenMPWorksharingDirective(getDirectiveKind()) || + isOpenMPTaskLoopDirective(getDirectiveKind()) || + isOpenMPDistributeDirective(getDirectiveKind())) && "expected worksharing loop directive"); *std::next(child_begin(), LowerBoundVariableOffset) = LB; } void setUpperBoundVariable(Expr *UB) { - assert(isOpenMPWorksharingDirective(getDirectiveKind()) && + assert((isOpenMPWorksharingDirective(getDirectiveKind()) || + isOpenMPTaskLoopDirective(getDirectiveKind()) || + isOpenMPDistributeDirective(getDirectiveKind())) && "expected worksharing loop directive"); *std::next(child_begin(), UpperBoundVariableOffset) = UB; } void setStrideVariable(Expr *ST) { - assert(isOpenMPWorksharingDirective(getDirectiveKind()) && + assert((isOpenMPWorksharingDirective(getDirectiveKind()) || + isOpenMPTaskLoopDirective(getDirectiveKind()) || + isOpenMPDistributeDirective(getDirectiveKind())) && "expected worksharing loop directive"); *std::next(child_begin(), StrideVariableOffset) = ST; } void setEnsureUpperBound(Expr *EUB) { - assert(isOpenMPWorksharingDirective(getDirectiveKind()) && + assert((isOpenMPWorksharingDirective(getDirectiveKind()) || + isOpenMPTaskLoopDirective(getDirectiveKind()) || + isOpenMPDistributeDirective(getDirectiveKind())) && "expected worksharing loop directive"); *std::next(child_begin(), EnsureUpperBoundOffset) = EUB; } void setNextLowerBound(Expr *NLB) { - assert(isOpenMPWorksharingDirective(getDirectiveKind()) && + assert((isOpenMPWorksharingDirective(getDirectiveKind()) || + isOpenMPTaskLoopDirective(getDirectiveKind()) || + isOpenMPDistributeDirective(getDirectiveKind())) && "expected worksharing loop directive"); *std::next(child_begin(), NextLowerBoundOffset) = NLB; } void setNextUpperBound(Expr *NUB) { - assert(isOpenMPWorksharingDirective(getDirectiveKind()) && + assert((isOpenMPWorksharingDirective(getDirectiveKind()) || + isOpenMPTaskLoopDirective(getDirectiveKind()) || + isOpenMPDistributeDirective(getDirectiveKind())) && "expected worksharing loop directive"); *std::next(child_begin(), NextUpperBoundOffset) = NUB; } void setCounters(ArrayRef<Expr *> A); + void setPrivateCounters(ArrayRef<Expr *> A); void setInits(ArrayRef<Expr *> A); void setUpdates(ArrayRef<Expr *> A); void setFinals(ArrayRef<Expr *> A); @@ -462,6 +514,8 @@ public: Expr *NUB; /// \brief Counters Loop counters. SmallVector<Expr *, 4> Counters; + /// \brief PrivateCounters Loop counters. + SmallVector<Expr *, 4> PrivateCounters; /// \brief Expressions for loop counters inits for CodeGen. SmallVector<Expr *, 4> Inits; /// \brief Expressions for loop counters update for CodeGen. @@ -495,11 +549,13 @@ public: NLB = nullptr; NUB = nullptr; Counters.resize(Size); + PrivateCounters.resize(Size); Inits.resize(Size); Updates.resize(Size); Finals.resize(Size); for (unsigned i = 0; i < Size; ++i) { Counters[i] = nullptr; + PrivateCounters[i] = nullptr; Inits[i] = nullptr; Updates[i] = nullptr; Finals[i] = nullptr; @@ -539,43 +595,50 @@ public: reinterpret_cast<const Expr *>(*std::next(child_begin(), IncOffset))); } Expr *getIsLastIterVariable() const { - assert(isOpenMPWorksharingDirective(getDirectiveKind()) && + assert((isOpenMPWorksharingDirective(getDirectiveKind()) || + isOpenMPTaskLoopDirective(getDirectiveKind())) && "expected worksharing loop directive"); return const_cast<Expr *>(reinterpret_cast<const Expr *>( *std::next(child_begin(), IsLastIterVariableOffset))); } Expr *getLowerBoundVariable() const { - assert(isOpenMPWorksharingDirective(getDirectiveKind()) && + assert((isOpenMPWorksharingDirective(getDirectiveKind()) || + isOpenMPTaskLoopDirective(getDirectiveKind())) && "expected worksharing loop directive"); return const_cast<Expr *>(reinterpret_cast<const Expr *>( *std::next(child_begin(), LowerBoundVariableOffset))); } Expr *getUpperBoundVariable() const { - assert(isOpenMPWorksharingDirective(getDirectiveKind()) && + assert((isOpenMPWorksharingDirective(getDirectiveKind()) || + isOpenMPTaskLoopDirective(getDirectiveKind())) && "expected worksharing loop directive"); return const_cast<Expr *>(reinterpret_cast<const Expr *>( *std::next(child_begin(), UpperBoundVariableOffset))); } Expr *getStrideVariable() const { - assert(isOpenMPWorksharingDirective(getDirectiveKind()) && + assert((isOpenMPWorksharingDirective(getDirectiveKind()) || + isOpenMPTaskLoopDirective(getDirectiveKind())) && "expected worksharing loop directive"); return const_cast<Expr *>(reinterpret_cast<const Expr *>( *std::next(child_begin(), StrideVariableOffset))); } Expr *getEnsureUpperBound() const { - assert(isOpenMPWorksharingDirective(getDirectiveKind()) && + assert((isOpenMPWorksharingDirective(getDirectiveKind()) || + isOpenMPTaskLoopDirective(getDirectiveKind())) && "expected worksharing loop directive"); return const_cast<Expr *>(reinterpret_cast<const Expr *>( *std::next(child_begin(), EnsureUpperBoundOffset))); } Expr *getNextLowerBound() const { - assert(isOpenMPWorksharingDirective(getDirectiveKind()) && + assert((isOpenMPWorksharingDirective(getDirectiveKind()) || + isOpenMPTaskLoopDirective(getDirectiveKind())) && "expected worksharing loop directive"); return const_cast<Expr *>(reinterpret_cast<const Expr *>( *std::next(child_begin(), NextLowerBoundOffset))); } Expr *getNextUpperBound() const { - assert(isOpenMPWorksharingDirective(getDirectiveKind()) && + assert((isOpenMPWorksharingDirective(getDirectiveKind()) || + isOpenMPTaskLoopDirective(getDirectiveKind())) && "expected worksharing loop directive"); return const_cast<Expr *>(reinterpret_cast<const Expr *>( *std::next(child_begin(), NextUpperBoundOffset))); @@ -597,6 +660,12 @@ public: return const_cast<OMPLoopDirective *>(this)->getCounters(); } + ArrayRef<Expr *> private_counters() { return getPrivateCounters(); } + + ArrayRef<Expr *> private_counters() const { + return const_cast<OMPLoopDirective *>(this)->getPrivateCounters(); + } + ArrayRef<Expr *> inits() { return getInits(); } ArrayRef<Expr *> inits() const { @@ -620,7 +689,10 @@ public: T->getStmtClass() == OMPForDirectiveClass || T->getStmtClass() == OMPForSimdDirectiveClass || T->getStmtClass() == OMPParallelForDirectiveClass || - T->getStmtClass() == OMPParallelForSimdDirectiveClass; + T->getStmtClass() == OMPParallelForSimdDirectiveClass || + T->getStmtClass() == OMPTaskLoopDirectiveClass || + T->getStmtClass() == OMPTaskLoopSimdDirectiveClass || + T->getStmtClass() == OMPDistributeDirectiveClass; } }; @@ -700,6 +772,10 @@ public: /// class OMPForDirective : public OMPLoopDirective { friend class ASTStmtReader; + + /// \brief true if current directive has inner cancel directive. + bool HasCancel; + /// \brief Build directive with the given start and end location. /// /// \param StartLoc Starting location of the directive kind. @@ -710,7 +786,8 @@ class OMPForDirective : public OMPLoopDirective { OMPForDirective(SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, unsigned NumClauses) : OMPLoopDirective(this, OMPForDirectiveClass, OMPD_for, StartLoc, EndLoc, - CollapsedNum, NumClauses) {} + CollapsedNum, NumClauses), + HasCancel(false) {} /// \brief Build an empty directive. /// @@ -719,7 +796,11 @@ class OMPForDirective : public OMPLoopDirective { /// explicit OMPForDirective(unsigned CollapsedNum, unsigned NumClauses) : OMPLoopDirective(this, OMPForDirectiveClass, OMPD_for, SourceLocation(), - SourceLocation(), CollapsedNum, NumClauses) {} + 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. @@ -731,12 +812,13 @@ public: /// \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 OMPForDirective *Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, - Stmt *AssociatedStmt, - const HelperExprs &Exprs); + Stmt *AssociatedStmt, const HelperExprs &Exprs, + bool HasCancel); /// \brief Creates an empty directive with the place /// for \a NumClauses clauses. @@ -748,6 +830,9 @@ public: static OMPForDirective *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() == OMPForDirectiveClass; } @@ -829,6 +914,10 @@ public: /// class OMPSectionsDirective : public OMPExecutableDirective { friend class ASTStmtReader; + + /// \brief true if current directive has inner cancel directive. + bool HasCancel; + /// \brief Build directive with the given start and end location. /// /// \param StartLoc Starting location of the directive kind. @@ -838,7 +927,8 @@ class OMPSectionsDirective : public OMPExecutableDirective { OMPSectionsDirective(SourceLocation StartLoc, SourceLocation EndLoc, unsigned NumClauses) : OMPExecutableDirective(this, OMPSectionsDirectiveClass, OMPD_sections, - StartLoc, EndLoc, NumClauses, 1) {} + StartLoc, EndLoc, NumClauses, 1), + HasCancel(false) {} /// \brief Build an empty directive. /// @@ -847,7 +937,11 @@ class OMPSectionsDirective : public OMPExecutableDirective { explicit OMPSectionsDirective(unsigned NumClauses) : OMPExecutableDirective(this, OMPSectionsDirectiveClass, OMPD_sections, SourceLocation(), SourceLocation(), NumClauses, - 1) {} + 1), + HasCancel(false) {} + + /// \brief Set cancel state. + void setHasCancel(bool Has) { HasCancel = Has; } public: /// \brief Creates directive with a list of \a Clauses. @@ -857,10 +951,11 @@ public: /// \param EndLoc Ending Location of the directive. /// \param Clauses List of clauses. /// \param AssociatedStmt Statement, associated with the directive. + /// \param HasCancel true if current directive has inner directive. /// static OMPSectionsDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, - ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); + ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, bool HasCancel); /// \brief Creates an empty directive with the place for \a NumClauses /// clauses. @@ -871,6 +966,9 @@ public: static OMPSectionsDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses, 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() == OMPSectionsDirectiveClass; } @@ -884,6 +982,10 @@ public: /// class OMPSectionDirective : public OMPExecutableDirective { friend class ASTStmtReader; + + /// \brief true if current directive has inner cancel directive. + bool HasCancel; + /// \brief Build directive with the given start and end location. /// /// \param StartLoc Starting location of the directive kind. @@ -891,13 +993,15 @@ class OMPSectionDirective : public OMPExecutableDirective { /// OMPSectionDirective(SourceLocation StartLoc, SourceLocation EndLoc) : OMPExecutableDirective(this, OMPSectionDirectiveClass, OMPD_section, - StartLoc, EndLoc, 0, 1) {} + StartLoc, EndLoc, 0, 1), + HasCancel(false) {} /// \brief Build an empty directive. /// explicit OMPSectionDirective() : OMPExecutableDirective(this, OMPSectionDirectiveClass, OMPD_section, - SourceLocation(), SourceLocation(), 0, 1) {} + SourceLocation(), SourceLocation(), 0, 1), + HasCancel(false) {} public: /// \brief Creates directive. @@ -906,11 +1010,12 @@ public: /// \param StartLoc Starting location of the directive kind. /// \param EndLoc Ending Location of the directive. /// \param AssociatedStmt Statement, associated with the directive. + /// \param HasCancel true if current directive has inner directive. /// static OMPSectionDirective *Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, - Stmt *AssociatedStmt); + Stmt *AssociatedStmt, bool HasCancel); /// \brief Creates an empty directive. /// @@ -918,6 +1023,12 @@ public: /// static OMPSectionDirective *CreateEmpty(const ASTContext &C, EmptyShell); + /// \brief Set cancel state. + void setHasCancel(bool Has) { HasCancel = Has; } + + /// \brief Return true if current directive has inner cancel directive. + bool hasCancel() const { return HasCancel; } + static bool classof(const Stmt *T) { return T->getStmtClass() == OMPSectionDirectiveClass; } @@ -1042,18 +1153,22 @@ class OMPCriticalDirective : public OMPExecutableDirective { /// \param Name Name of the directive. /// \param StartLoc Starting location of the directive kind. /// \param EndLoc Ending location of the directive. + /// \param NumClauses Number of clauses. /// OMPCriticalDirective(const DeclarationNameInfo &Name, SourceLocation StartLoc, - SourceLocation EndLoc) + SourceLocation EndLoc, unsigned NumClauses) : OMPExecutableDirective(this, OMPCriticalDirectiveClass, OMPD_critical, - StartLoc, EndLoc, 0, 1), + StartLoc, EndLoc, NumClauses, 1), DirName(Name) {} /// \brief Build an empty directive. /// - explicit OMPCriticalDirective() + /// \param NumClauses Number of clauses. + /// + explicit OMPCriticalDirective(unsigned NumClauses) : OMPExecutableDirective(this, OMPCriticalDirectiveClass, OMPD_critical, - SourceLocation(), SourceLocation(), 0, 1), + SourceLocation(), SourceLocation(), NumClauses, + 1), DirName() {} /// \brief Set name of the directive. @@ -1069,17 +1184,21 @@ public: /// \param Name Name of the directive. /// \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 OMPCriticalDirective * Create(const ASTContext &C, const DeclarationNameInfo &Name, - SourceLocation StartLoc, SourceLocation EndLoc, Stmt *AssociatedStmt); + SourceLocation StartLoc, SourceLocation EndLoc, + ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); /// \brief Creates an empty directive. /// /// \param C AST context. + /// \param NumClauses Number of clauses. /// - static OMPCriticalDirective *CreateEmpty(const ASTContext &C, EmptyShell); + static OMPCriticalDirective *CreateEmpty(const ASTContext &C, + unsigned NumClauses, EmptyShell); /// \brief Return name of the directive. /// @@ -1101,6 +1220,10 @@ public: /// class OMPParallelForDirective : 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. @@ -1111,7 +1234,8 @@ class OMPParallelForDirective : public OMPLoopDirective { OMPParallelForDirective(SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, unsigned NumClauses) : OMPLoopDirective(this, OMPParallelForDirectiveClass, OMPD_parallel_for, - StartLoc, EndLoc, CollapsedNum, NumClauses) {} + StartLoc, EndLoc, CollapsedNum, NumClauses), + HasCancel(false) {} /// \brief Build an empty directive. /// @@ -1121,7 +1245,11 @@ class OMPParallelForDirective : public OMPLoopDirective { explicit OMPParallelForDirective(unsigned CollapsedNum, unsigned NumClauses) : OMPLoopDirective(this, OMPParallelForDirectiveClass, OMPD_parallel_for, SourceLocation(), SourceLocation(), CollapsedNum, - NumClauses) {} + NumClauses), + HasCancel(false) {} + + /// \brief Set cancel state. + void setHasCancel(bool Has) { HasCancel = Has; } public: /// \brief Creates directive with a list of \a Clauses. @@ -1133,11 +1261,12 @@ public: /// \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 OMPParallelForDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, - Stmt *AssociatedStmt, const HelperExprs &Exprs); + Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel); /// \brief Creates an empty directive with the place /// for \a NumClauses clauses. @@ -1151,6 +1280,9 @@ public: 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() == OMPParallelForDirectiveClass; } @@ -1236,6 +1368,10 @@ public: /// class OMPParallelSectionsDirective : public OMPExecutableDirective { friend class ASTStmtReader; + + /// \brief true if current directive has inner cancel directive. + bool HasCancel; + /// \brief Build directive with the given start and end location. /// /// \param StartLoc Starting location of the directive kind. @@ -1246,7 +1382,8 @@ class OMPParallelSectionsDirective : public OMPExecutableDirective { unsigned NumClauses) : OMPExecutableDirective(this, OMPParallelSectionsDirectiveClass, OMPD_parallel_sections, StartLoc, EndLoc, - NumClauses, 1) {} + NumClauses, 1), + HasCancel(false) {} /// \brief Build an empty directive. /// @@ -1255,7 +1392,11 @@ class OMPParallelSectionsDirective : public OMPExecutableDirective { explicit OMPParallelSectionsDirective(unsigned NumClauses) : OMPExecutableDirective(this, OMPParallelSectionsDirectiveClass, OMPD_parallel_sections, SourceLocation(), - SourceLocation(), NumClauses, 1) {} + SourceLocation(), NumClauses, 1), + HasCancel(false) {} + + /// \brief Set cancel state. + void setHasCancel(bool Has) { HasCancel = Has; } public: /// \brief Creates directive with a list of \a Clauses. @@ -1265,10 +1406,11 @@ public: /// \param EndLoc Ending Location of the directive. /// \param Clauses List of clauses. /// \param AssociatedStmt Statement, associated with the directive. + /// \param HasCancel true if current directive has inner cancel directive. /// static OMPParallelSectionsDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, - ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); + ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, bool HasCancel); /// \brief Creates an empty directive with the place for \a NumClauses /// clauses. @@ -1279,6 +1421,9 @@ public: static OMPParallelSectionsDirective * CreateEmpty(const ASTContext &C, unsigned NumClauses, 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() == OMPParallelSectionsDirectiveClass; } @@ -1294,6 +1439,9 @@ public: /// class OMPTaskDirective : public OMPExecutableDirective { friend class ASTStmtReader; + /// \brief true if this directive has inner cancel directive. + bool HasCancel; + /// \brief Build directive with the given start and end location. /// /// \param StartLoc Starting location of the directive kind. @@ -1303,7 +1451,8 @@ class OMPTaskDirective : public OMPExecutableDirective { OMPTaskDirective(SourceLocation StartLoc, SourceLocation EndLoc, unsigned NumClauses) : OMPExecutableDirective(this, OMPTaskDirectiveClass, OMPD_task, StartLoc, - EndLoc, NumClauses, 1) {} + EndLoc, NumClauses, 1), + HasCancel(false) {} /// \brief Build an empty directive. /// @@ -1312,7 +1461,11 @@ class OMPTaskDirective : public OMPExecutableDirective { explicit OMPTaskDirective(unsigned NumClauses) : OMPExecutableDirective(this, OMPTaskDirectiveClass, OMPD_task, SourceLocation(), SourceLocation(), NumClauses, - 1) {} + 1), + HasCancel(false) {} + + /// \brief Set cancel state. + void setHasCancel(bool Has) { HasCancel = Has; } public: /// \brief Creates directive with a list of \a Clauses. @@ -1322,11 +1475,12 @@ public: /// \param EndLoc Ending Location of the directive. /// \param Clauses List of clauses. /// \param AssociatedStmt Statement, associated with the directive. + /// \param HasCancel true, if current directive has inner cancel directive. /// static OMPTaskDirective *Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef<OMPClause *> Clauses, - Stmt *AssociatedStmt); + Stmt *AssociatedStmt, bool HasCancel); /// \brief Creates an empty directive with the place for \a NumClauses /// clauses. @@ -1337,6 +1491,9 @@ public: static OMPTaskDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses, 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() == OMPTaskDirectiveClass; } @@ -1592,16 +1749,21 @@ class OMPOrderedDirective : public OMPExecutableDirective { /// /// \param StartLoc Starting location of the directive kind. /// \param EndLoc Ending location of the directive. + /// \param NumClauses Number of clauses. /// - OMPOrderedDirective(SourceLocation StartLoc, SourceLocation EndLoc) + OMPOrderedDirective(SourceLocation StartLoc, SourceLocation EndLoc, + unsigned NumClauses) : OMPExecutableDirective(this, OMPOrderedDirectiveClass, OMPD_ordered, - StartLoc, EndLoc, 0, 1) {} + StartLoc, EndLoc, NumClauses, 1) {} /// \brief Build an empty directive. /// - explicit OMPOrderedDirective() + /// \param NumClauses Number of clauses. + /// + explicit OMPOrderedDirective(unsigned NumClauses) : OMPExecutableDirective(this, OMPOrderedDirectiveClass, OMPD_ordered, - SourceLocation(), SourceLocation(), 0, 1) {} + SourceLocation(), SourceLocation(), NumClauses, + 1) {} public: /// \brief Creates directive. @@ -1609,18 +1771,20 @@ public: /// \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 OMPOrderedDirective *Create(const ASTContext &C, - SourceLocation StartLoc, - SourceLocation EndLoc, - Stmt *AssociatedStmt); + static OMPOrderedDirective * + Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, + ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); /// \brief Creates an empty directive. /// /// \param C AST context. + /// \param NumClauses Number of clauses. /// - static OMPOrderedDirective *CreateEmpty(const ASTContext &C, EmptyShell); + static OMPOrderedDirective *CreateEmpty(const ASTContext &C, + unsigned NumClauses, EmptyShell); static bool classof(const Stmt *T) { return T->getStmtClass() == OMPOrderedDirectiveClass; @@ -1817,6 +1981,64 @@ public: } }; +/// \brief This represents '#pragma omp target data' directive. +/// +/// \code +/// #pragma omp target data device(0) if(a) map(b[:]) +/// \endcode +/// In this example directive '#pragma omp target data' has clauses 'device' +/// with the value '0', 'if' with condition 'a' and 'map' with array +/// section 'b[:]'. +/// +class OMPTargetDataDirective : 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. + /// + OMPTargetDataDirective(SourceLocation StartLoc, SourceLocation EndLoc, + unsigned NumClauses) + : OMPExecutableDirective(this, OMPTargetDataDirectiveClass, + OMPD_target_data, StartLoc, EndLoc, NumClauses, + 1) {} + + /// \brief Build an empty directive. + /// + /// \param NumClauses Number of clauses. + /// + explicit OMPTargetDataDirective(unsigned NumClauses) + : OMPExecutableDirective(this, OMPTargetDataDirectiveClass, + OMPD_target_data, SourceLocation(), + SourceLocation(), NumClauses, 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 OMPTargetDataDirective * + Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, + ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); + + /// \brief Creates an empty directive with the place for \a N clauses. + /// + /// \param C AST context. + /// \param N The number of clauses. + /// + static OMPTargetDataDirective *CreateEmpty(const ASTContext &C, unsigned N, + EmptyShell); + + static bool classof(const Stmt *T) { + return T->getStmtClass() == OMPTargetDataDirectiveClass; + } +}; + /// \brief This represents '#pragma omp teams' directive. /// /// \code @@ -1947,17 +2169,21 @@ class OMPCancelDirective : public OMPExecutableDirective { /// /// \param StartLoc Starting location of the directive kind. /// \param EndLoc Ending location of the directive. + /// \param NumClauses Number of clauses. /// - OMPCancelDirective(SourceLocation StartLoc, SourceLocation EndLoc) + OMPCancelDirective(SourceLocation StartLoc, SourceLocation EndLoc, + unsigned NumClauses) : OMPExecutableDirective(this, OMPCancelDirectiveClass, OMPD_cancel, - StartLoc, EndLoc, 0, 0), + StartLoc, EndLoc, NumClauses, 0), CancelRegion(OMPD_unknown) {} /// \brief Build an empty directive. /// - explicit OMPCancelDirective() + /// \param NumClauses Number of clauses. + explicit OMPCancelDirective(unsigned NumClauses) : OMPExecutableDirective(this, OMPCancelDirectiveClass, OMPD_cancel, - SourceLocation(), SourceLocation(), 0, 0), + SourceLocation(), SourceLocation(), NumClauses, + 0), CancelRegion(OMPD_unknown) {} /// \brief Set cancel region for current cancellation point. @@ -1970,17 +2196,19 @@ public: /// \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 OMPCancelDirective *Create(const ASTContext &C, - SourceLocation StartLoc, - SourceLocation EndLoc, - OpenMPDirectiveKind CancelRegion); + static OMPCancelDirective * + Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, + ArrayRef<OMPClause *> Clauses, OpenMPDirectiveKind CancelRegion); /// \brief Creates an empty directive. /// /// \param C AST context. + /// \param NumClauses Number of clauses. /// - static OMPCancelDirective *CreateEmpty(const ASTContext &C, EmptyShell); + static OMPCancelDirective *CreateEmpty(const ASTContext &C, + unsigned NumClauses, EmptyShell); /// \brief Get cancellation region for the current cancellation point. OpenMPDirectiveKind getCancelRegion() const { return CancelRegion; } @@ -1990,6 +2218,205 @@ public: } }; +/// \brief This represents '#pragma omp taskloop' directive. +/// +/// \code +/// #pragma omp taskloop private(a,b) grainsize(val) num_tasks(num) +/// \endcode +/// In this example directive '#pragma omp taskloop' has clauses 'private' +/// with the variables 'a' and 'b', 'grainsize' with expression 'val' and +/// 'num_tasks' with expression 'num'. +/// +class OMPTaskLoopDirective : 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. + /// + OMPTaskLoopDirective(SourceLocation StartLoc, SourceLocation EndLoc, + unsigned CollapsedNum, unsigned NumClauses) + : OMPLoopDirective(this, OMPTaskLoopDirectiveClass, OMPD_taskloop, + StartLoc, EndLoc, CollapsedNum, NumClauses) {} + + /// \brief Build an empty directive. + /// + /// \param CollapsedNum Number of collapsed nested loops. + /// \param NumClauses Number of clauses. + /// + explicit OMPTaskLoopDirective(unsigned CollapsedNum, unsigned NumClauses) + : OMPLoopDirective(this, OMPTaskLoopDirectiveClass, OMPD_taskloop, + 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 OMPTaskLoopDirective * + 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 OMPTaskLoopDirective *CreateEmpty(const ASTContext &C, + unsigned NumClauses, + unsigned CollapsedNum, EmptyShell); + + static bool classof(const Stmt *T) { + return T->getStmtClass() == OMPTaskLoopDirectiveClass; + } +}; + +/// \brief This represents '#pragma omp taskloop simd' directive. +/// +/// \code +/// #pragma omp taskloop simd private(a,b) grainsize(val) num_tasks(num) +/// \endcode +/// In this example directive '#pragma omp taskloop simd' has clauses 'private' +/// with the variables 'a' and 'b', 'grainsize' with expression 'val' and +/// 'num_tasks' with expression 'num'. +/// +class OMPTaskLoopSimdDirective : 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. + /// + OMPTaskLoopSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc, + unsigned CollapsedNum, unsigned NumClauses) + : OMPLoopDirective(this, OMPTaskLoopSimdDirectiveClass, + OMPD_taskloop_simd, StartLoc, EndLoc, CollapsedNum, + NumClauses) {} + + /// \brief Build an empty directive. + /// + /// \param CollapsedNum Number of collapsed nested loops. + /// \param NumClauses Number of clauses. + /// + explicit OMPTaskLoopSimdDirective(unsigned CollapsedNum, unsigned NumClauses) + : OMPLoopDirective(this, OMPTaskLoopSimdDirectiveClass, + OMPD_taskloop_simd, 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 OMPTaskLoopSimdDirective * + 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 OMPTaskLoopSimdDirective *CreateEmpty(const ASTContext &C, + unsigned NumClauses, + unsigned CollapsedNum, + EmptyShell); + + static bool classof(const Stmt *T) { + return T->getStmtClass() == OMPTaskLoopSimdDirectiveClass; + } +}; + +/// \brief This represents '#pragma omp distribute' directive. +/// +/// \code +/// #pragma omp distribute private(a,b) +/// \endcode +/// In this example directive '#pragma omp distribute' has clauses 'private' +/// with the variables 'a' and 'b' +/// +class OMPDistributeDirective : 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. + /// + OMPDistributeDirective(SourceLocation StartLoc, SourceLocation EndLoc, + unsigned CollapsedNum, unsigned NumClauses) + : OMPLoopDirective(this, OMPDistributeDirectiveClass, OMPD_distribute, + StartLoc, EndLoc, CollapsedNum, NumClauses) + {} + + /// \brief Build an empty directive. + /// + /// \param CollapsedNum Number of collapsed nested loops. + /// \param NumClauses Number of clauses. + /// + explicit OMPDistributeDirective(unsigned CollapsedNum, unsigned NumClauses) + : OMPLoopDirective(this, OMPDistributeDirectiveClass, OMPD_distribute, + 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 OMPDistributeDirective * + 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 OMPDistributeDirective *CreateEmpty(const ASTContext &C, + unsigned NumClauses, + unsigned CollapsedNum, EmptyShell); + + static bool classof(const Stmt *T) { + return T->getStmtClass() == OMPDistributeDirectiveClass; + } +}; + } // end namespace clang #endif diff --git a/contrib/llvm/tools/clang/include/clang/AST/StmtVisitor.h b/contrib/llvm/tools/clang/include/clang/AST/StmtVisitor.h index c71af38..df4a2d8 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/StmtVisitor.h +++ b/contrib/llvm/tools/clang/include/clang/AST/StmtVisitor.h @@ -16,6 +16,7 @@ #include "clang/AST/ExprCXX.h" #include "clang/AST/ExprObjC.h" +#include "clang/AST/ExprOpenMP.h" #include "clang/AST/StmtCXX.h" #include "clang/AST/StmtObjC.h" #include "clang/AST/StmtOpenMP.h" @@ -93,6 +94,7 @@ public: case UO_Real: DISPATCH(UnaryReal, UnaryOperator); case UO_Imag: DISPATCH(UnaryImag, UnaryOperator); case UO_Extension: DISPATCH(UnaryExtension, UnaryOperator); + case UO_Coawait: DISPATCH(UnaryCoawait, UnaryOperator); } } @@ -157,7 +159,7 @@ public: UNARYOP_FALLBACK(Plus) UNARYOP_FALLBACK(Minus) UNARYOP_FALLBACK(Not) UNARYOP_FALLBACK(LNot) UNARYOP_FALLBACK(Real) UNARYOP_FALLBACK(Imag) - UNARYOP_FALLBACK(Extension) + UNARYOP_FALLBACK(Extension) UNARYOP_FALLBACK(Coawait) #undef UNARYOP_FALLBACK // Base case, ignore it. :) diff --git a/contrib/llvm/tools/clang/include/clang/AST/TemplateBase.h b/contrib/llvm/tools/clang/include/clang/AST/TemplateBase.h index 1d01753..f87171a 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/TemplateBase.h +++ b/contrib/llvm/tools/clang/include/clang/AST/TemplateBase.h @@ -22,6 +22,7 @@ #include "llvm/ADT/iterator_range.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/TrailingObjects.h" namespace llvm { class FoldingSetNodeID; @@ -198,22 +199,19 @@ public: /// /// We assume that storage for the template arguments provided /// outlives the TemplateArgument itself. - TemplateArgument(const TemplateArgument *Args, unsigned NumArgs) { + explicit TemplateArgument(ArrayRef<TemplateArgument> Args) { this->Args.Kind = Pack; - this->Args.Args = Args; - this->Args.NumArgs = NumArgs; + this->Args.Args = Args.data(); + this->Args.NumArgs = Args.size(); } - static TemplateArgument getEmptyPack() { - return TemplateArgument((TemplateArgument*)nullptr, 0); - } + static TemplateArgument getEmptyPack() { return TemplateArgument(None); } /// \brief Create a new template argument pack by copying the given set of /// template arguments. static TemplateArgument CreatePackCopy(ASTContext &Context, - const TemplateArgument *Args, - unsigned NumArgs); - + ArrayRef<TemplateArgument> Args); + /// \brief Return the kind of stored template argument. ArgKind getKind() const { return (ArgKind)TypeOrValue.Kind; } @@ -523,7 +521,7 @@ class TemplateArgumentListInfo { // This can leak if used in an AST node, use ASTTemplateArgumentListInfo // instead. - void* operator new(size_t bytes, ASTContext& C); + void *operator new(size_t bytes, ASTContext &C) = delete; public: TemplateArgumentListInfo() {} @@ -544,6 +542,10 @@ public: return Arguments.data(); } + llvm::ArrayRef<TemplateArgumentLoc> arguments() const { + return Arguments; + } + const TemplateArgumentLoc &operator[](unsigned I) const { return Arguments[I]; } @@ -561,84 +563,72 @@ public: /// the "<int>" in "sort<int>". /// This is safe to be used inside an AST node, in contrast with /// TemplateArgumentListInfo. -struct ASTTemplateArgumentListInfo { +struct ASTTemplateArgumentListInfo final + : private llvm::TrailingObjects<ASTTemplateArgumentListInfo, + TemplateArgumentLoc> { +private: + friend TrailingObjects; + + ASTTemplateArgumentListInfo(const TemplateArgumentListInfo &List); + +public: /// \brief The source location of the left angle bracket ('<'). SourceLocation LAngleLoc; - + /// \brief The source location of the right angle bracket ('>'). SourceLocation RAngleLoc; - - union { - /// \brief The number of template arguments in TemplateArgs. - /// The actual template arguments (if any) are stored after the - /// ExplicitTemplateArgumentList structure. - unsigned NumTemplateArgs; - - /// Force ASTTemplateArgumentListInfo to the right alignment - /// for the following array of TemplateArgumentLocs. - llvm::AlignedCharArray< - llvm::AlignOf<TemplateArgumentLoc>::Alignment, 1> Aligner; - }; - /// \brief Retrieve the template arguments - TemplateArgumentLoc *getTemplateArgs() { - return reinterpret_cast<TemplateArgumentLoc *> (this + 1); - } - + /// \brief The number of template arguments in TemplateArgs. + unsigned NumTemplateArgs; + /// \brief Retrieve the template arguments const TemplateArgumentLoc *getTemplateArgs() const { - return reinterpret_cast<const TemplateArgumentLoc *> (this + 1); + return getTrailingObjects<TemplateArgumentLoc>(); } const TemplateArgumentLoc &operator[](unsigned I) const { return getTemplateArgs()[I]; } - static const ASTTemplateArgumentListInfo *Create(ASTContext &C, - const TemplateArgumentListInfo &List); - - void initializeFrom(const TemplateArgumentListInfo &List); - void initializeFrom(const TemplateArgumentListInfo &List, - bool &Dependent, bool &InstantiationDependent, - bool &ContainsUnexpandedParameterPack); - void copyInto(TemplateArgumentListInfo &List) const; - static std::size_t sizeFor(unsigned NumTemplateArgs); + static const ASTTemplateArgumentListInfo * + Create(ASTContext &C, const TemplateArgumentListInfo &List); }; -/// \brief Extends ASTTemplateArgumentListInfo with the source location -/// information for the template keyword; this is used as part of the -/// representation of qualified identifiers, such as S<T>::template apply<T>. -struct ASTTemplateKWAndArgsInfo : public ASTTemplateArgumentListInfo { - typedef ASTTemplateArgumentListInfo Base; - - // NOTE: the source location of the (optional) template keyword is - // stored after all template arguments. +/// \brief Represents an explicit template argument list in C++, e.g., +/// the "<int>" in "sort<int>". +/// +/// It is intended to be used as a trailing object on AST nodes, and +/// as such, doesn't contain the array of TemplateArgumentLoc itself, +/// but expects the containing object to also provide storage for +/// that. +struct LLVM_ALIGNAS(LLVM_PTR_SIZE) ASTTemplateKWAndArgsInfo { + /// \brief The source location of the left angle bracket ('<'). + SourceLocation LAngleLoc; - /// \brief Get the source location of the template keyword. - SourceLocation getTemplateKeywordLoc() const { - return *reinterpret_cast<const SourceLocation*> - (getTemplateArgs() + NumTemplateArgs); - } + /// \brief The source location of the right angle bracket ('>'). + SourceLocation RAngleLoc; - /// \brief Sets the source location of the template keyword. - void setTemplateKeywordLoc(SourceLocation TemplateKWLoc) { - *reinterpret_cast<SourceLocation*> - (getTemplateArgs() + NumTemplateArgs) = TemplateKWLoc; - } + /// \brief The source location of the template keyword; this is used + /// as part of the representation of qualified identifiers, such as + /// S<T>::template apply<T>. Will be empty if this expression does + /// not have a template keyword. + SourceLocation TemplateKWLoc; - static const ASTTemplateKWAndArgsInfo* - Create(ASTContext &C, SourceLocation TemplateKWLoc, - const TemplateArgumentListInfo &List); + /// \brief The number of template arguments in TemplateArgs. + unsigned NumTemplateArgs; void initializeFrom(SourceLocation TemplateKWLoc, - const TemplateArgumentListInfo &List); + const TemplateArgumentListInfo &List, + TemplateArgumentLoc *OutArgArray); void initializeFrom(SourceLocation TemplateKWLoc, const TemplateArgumentListInfo &List, - bool &Dependent, bool &InstantiationDependent, + TemplateArgumentLoc *OutArgArray, bool &Dependent, + bool &InstantiationDependent, bool &ContainsUnexpandedParameterPack); void initializeFrom(SourceLocation TemplateKWLoc); - static std::size_t sizeFor(unsigned NumTemplateArgs); + void copyInto(const TemplateArgumentLoc *ArgArray, + TemplateArgumentListInfo &List) const; }; const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, diff --git a/contrib/llvm/tools/clang/include/clang/AST/TemplateName.h b/contrib/llvm/tools/clang/include/clang/AST/TemplateName.h index f3d23b9..3e10d2f 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/TemplateName.h +++ b/contrib/llvm/tools/clang/include/clang/AST/TemplateName.h @@ -180,9 +180,7 @@ class TemplateName { StorageType Storage; - explicit TemplateName(void *Ptr) { - Storage = StorageType::getFromOpaqueValue(Ptr); - } + explicit TemplateName(void *Ptr); public: // \brief Kind of name that is actually stored. @@ -207,17 +205,15 @@ public: }; TemplateName() : Storage() { } - explicit TemplateName(TemplateDecl *Template) : Storage(Template) { } - explicit TemplateName(OverloadedTemplateStorage *Storage) - : Storage(Storage) { } + explicit TemplateName(TemplateDecl *Template); + explicit TemplateName(OverloadedTemplateStorage *Storage); explicit TemplateName(SubstTemplateTemplateParmStorage *Storage); - explicit TemplateName(SubstTemplateTemplateParmPackStorage *Storage) - : Storage(Storage) { } - explicit TemplateName(QualifiedTemplateName *Qual) : Storage(Qual) { } - explicit TemplateName(DependentTemplateName *Dep) : Storage(Dep) { } + explicit TemplateName(SubstTemplateTemplateParmPackStorage *Storage); + explicit TemplateName(QualifiedTemplateName *Qual); + explicit TemplateName(DependentTemplateName *Dep); /// \brief Determine whether this template name is NULL. - bool isNull() const { return Storage.isNull(); } + bool isNull() const; // \brief Get the kind of name that is actually stored. NameKind getKind() const; @@ -238,26 +234,14 @@ public: /// name refers to, if known. If the template name does not refer to a /// specific set of function templates because it is a dependent name or /// refers to a single template, returns NULL. - OverloadedTemplateStorage *getAsOverloadedTemplate() const { - if (UncommonTemplateNameStorage *Uncommon = - Storage.dyn_cast<UncommonTemplateNameStorage *>()) - return Uncommon->getAsOverloadedStorage(); - - return nullptr; - } + OverloadedTemplateStorage *getAsOverloadedTemplate() const; /// \brief Retrieve the substituted template template parameter, if /// known. /// /// \returns The storage for the substituted template template parameter, /// if known. Otherwise, returns NULL. - SubstTemplateTemplateParmStorage *getAsSubstTemplateTemplateParm() const { - if (UncommonTemplateNameStorage *uncommon = - Storage.dyn_cast<UncommonTemplateNameStorage *>()) - return uncommon->getAsSubstTemplateTemplateParm(); - - return nullptr; - } + SubstTemplateTemplateParmStorage *getAsSubstTemplateTemplateParm() const; /// \brief Retrieve the substituted template template parameter pack, if /// known. @@ -265,25 +249,15 @@ public: /// \returns The storage for the substituted template template parameter pack, /// if known. Otherwise, returns NULL. SubstTemplateTemplateParmPackStorage * - getAsSubstTemplateTemplateParmPack() const { - if (UncommonTemplateNameStorage *Uncommon = - Storage.dyn_cast<UncommonTemplateNameStorage *>()) - return Uncommon->getAsSubstTemplateTemplateParmPack(); - - return nullptr; - } + getAsSubstTemplateTemplateParmPack() const; /// \brief Retrieve the underlying qualified template name /// structure, if any. - QualifiedTemplateName *getAsQualifiedTemplateName() const { - return Storage.dyn_cast<QualifiedTemplateName *>(); - } + QualifiedTemplateName *getAsQualifiedTemplateName() const; /// \brief Retrieve the underlying dependent template name /// structure, if any. - DependentTemplateName *getAsDependentTemplateName() const { - return Storage.dyn_cast<DependentTemplateName *>(); - } + DependentTemplateName *getAsDependentTemplateName() const; TemplateName getUnderlying() const; @@ -359,9 +333,6 @@ public: TemplateName replacement); }; -inline TemplateName::TemplateName(SubstTemplateTemplateParmStorage *Storage) - : Storage(Storage) { } - inline TemplateName TemplateName::getUnderlying() const { if (SubstTemplateTemplateParmStorage *subst = getAsSubstTemplateTemplateParm()) diff --git a/contrib/llvm/tools/clang/include/clang/AST/Type.h b/contrib/llvm/tools/clang/include/clang/AST/Type.h index 632d4b9..0c08130 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/Type.h +++ b/contrib/llvm/tools/clang/include/clang/AST/Type.h @@ -6,9 +6,12 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -// -// This file defines the Type interface and subclasses. -// +/// \file +/// \brief C Language Family Type Representation +/// +/// This file defines the clang::Type interface and subclasses, used to +/// represent types for languages in the C family. +/// //===----------------------------------------------------------------------===// #ifndef LLVM_CLANG_AST_TYPE_H @@ -105,7 +108,7 @@ namespace clang { #define TYPE(Class, Base) class Class##Type; #include "clang/AST/TypeNodes.def" -/// Qualifiers - The collection of all-type qualifiers we support. +/// The collection of all-type qualifiers we support. /// Clang supports five independent qualifiers: /// * C99: const, volatile, and restrict /// * Embedded C (TR18037): address spaces @@ -161,7 +164,7 @@ public: Qualifiers() : Mask(0) {} - /// \brief Returns the common set of qualifiers while removing them from + /// Returns the common set of qualifiers while removing them from /// the given sets. static Qualifiers removeCommonQualifiers(Qualifiers &L, Qualifiers &R) { // If both are only CVR-qualified, bit operations are sufficient. @@ -342,8 +345,8 @@ public: Mask |= mask; } - /// hasNonFastQualifiers - Return true if the set contains any - /// qualifiers which require an ExtQuals node to be allocated. + /// Return true if the set contains any qualifiers which require an ExtQuals + /// node to be allocated. bool hasNonFastQualifiers() const { return Mask & ~FastMask; } Qualifiers getNonFastQualifiers() const { Qualifiers Quals = *this; @@ -351,11 +354,11 @@ public: return Quals; } - /// hasQualifiers - Return true if the set contains any qualifiers. + /// Return true if the set contains any qualifiers. bool hasQualifiers() const { return Mask; } bool empty() const { return !Mask; } - /// \brief Add the qualifiers from the given set to this set. + /// Add the qualifiers from the given set to this set. void addQualifiers(Qualifiers Q) { // If the other set doesn't have any non-boolean qualifiers, just // bit-or it in. @@ -389,7 +392,7 @@ public: } } - /// \brief Add the qualifiers from the given set to this set, given that + /// Add the qualifiers from the given set to this set, given that /// they don't conflict. void addConsistentQualifiers(Qualifiers qs) { assert(getAddressSpace() == qs.getAddressSpace() || @@ -401,7 +404,7 @@ public: Mask |= qs.Mask; } - /// \brief Returns true if this address space is a superset of the other one. + /// Returns true if this address space is a superset of the other one. /// OpenCL v2.0 defines conversion rules (OpenCLC v2.0 s6.5.5) and notion of /// overlapping address spaces. /// CL1.1 or CL1.2: @@ -418,7 +421,7 @@ public: other.getAddressSpace() != LangAS::opencl_constant); } - /// \brief Determines if these qualifiers compatibly include another set. + /// Determines if these qualifiers compatibly include another set. /// Generally this answers the question of whether an object with the other /// qualifiers can be safely used as an object with these qualifiers. bool compatiblyIncludes(Qualifiers other) const { @@ -438,7 +441,8 @@ public: /// /// One set of Objective-C lifetime qualifiers compatibly includes the other /// if the lifetime qualifiers match, or if both are non-__weak and the - /// including set also contains the 'const' qualifier. + /// including set also contains the 'const' qualifier, or both are non-__weak + /// and one is None (which can only happen in non-ARC modes). bool compatiblyIncludesObjCLifetime(Qualifiers other) const { if (getObjCLifetime() == other.getObjCLifetime()) return true; @@ -446,6 +450,9 @@ public: if (getObjCLifetime() == OCL_Weak || other.getObjCLifetime() == OCL_Weak) return false; + if (getObjCLifetime() == OCL_None || other.getObjCLifetime() == OCL_None) + return true; + return hasConst(); } @@ -551,8 +558,10 @@ enum class ObjCSubstitutionContext { Superclass, }; -/// QualType - For efficiency, we don't store CV-qualified types as nodes on -/// their own: instead each reference to a type stores the qualifiers. This +/// A (possibly-)qualified type. +/// +/// For efficiency, we don't store CV-qualified types as nodes on their +/// own: instead each reference to a type stores the qualifiers. This /// greatly reduces the number of nodes we need to allocate for types (for /// example we only need one for 'int', 'const int', 'volatile int', /// 'const volatile int', etc). @@ -629,7 +638,7 @@ public: bool isCanonical() const; bool isCanonicalAsParam() const; - /// isNull - Return true if this QualType doesn't point to a type yet. + /// Return true if this QualType doesn't point to a type yet. bool isNull() const { return Value.getPointer().isNull(); } @@ -707,29 +716,25 @@ public: /// \brief Determine whether this is a Plain Old Data (POD) type (C++ 3.9p10). bool isPODType(ASTContext &Context) const; - /// isCXX98PODType() - Return true if this is a POD type according to the - /// rules of the C++98 standard, regardless of the current compilation's - /// language. + /// 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; - /// isCXX11PODType() - 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. + /// 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; - /// isTrivialType - Return true if this is a trivial type - /// (C++0x [basic.types]p9) + /// Return true if this is a trivial type per (C++0x [basic.types]p9) bool isTrivialType(ASTContext &Context) const; - /// isTriviallyCopyableType - Return true if this is a trivially - /// copyable type (C++0x [basic.types]p9) + /// Return true if this is a trivially copyable type (C++0x [basic.types]p9) bool isTriviallyCopyableType(ASTContext &Context) const; // Don't promise in the API that anything besides 'const' can be // easily added. - /// addConst - add the specified type qualifier to this QualType. + /// Add the `const` type qualifier to this QualType. void addConst() { addFastQualifiers(Qualifiers::Const); } @@ -737,15 +742,15 @@ public: return withFastQualifiers(Qualifiers::Const); } - /// addVolatile - add the specified type qualifier to this QualType. + /// Add the `volatile` type qualifier to this QualType. void addVolatile() { addFastQualifiers(Qualifiers::Volatile); } QualType withVolatile() const { return withFastQualifiers(Qualifiers::Volatile); } - - /// Add the restrict qualifier to this QualType. + + /// Add the `restrict` qualifier to this QualType. void addRestrict() { addFastQualifiers(Qualifiers::Restrict); } @@ -822,8 +827,8 @@ public: /// ASTContext::getUnqualifiedArrayType. inline QualType getUnqualifiedType() const; - /// getSplitUnqualifiedType - Retrieve the unqualified variant of the - /// given type, removing as little sugar as possible. + /// Retrieve the unqualified variant of the given type, removing as little + /// sugar as possible. /// /// Like getUnqualifiedType(), but also returns the set of /// qualifiers that were built up. @@ -853,7 +858,7 @@ public: /// from non-class types (in C++) or all types (in C). QualType getNonLValueExprType(const ASTContext &Context) const; - /// getDesugaredType - Return the specified type with any "sugar" removed from + /// Return the specified type with any "sugar" removed from /// the type. This takes off typedefs, typeof's etc. If the outer level of /// the type is already concrete, it returns it unmodified. This is similar /// to getting the canonical type, but it doesn't remove *all* typedefs. For @@ -878,7 +883,7 @@ public: return getSingleStepDesugaredTypeImpl(*this, Context); } - /// IgnoreParens - Returns the specified type after dropping any + /// Returns the specified type after dropping any /// outer-level parentheses. QualType IgnoreParens() const { if (isa<ParenType>(*this)) @@ -886,8 +891,7 @@ public: return *this; } - /// operator==/!= - Indicate whether the specified types and qualifiers are - /// identical. + /// Indicate whether the specified types and qualifiers are identical. friend bool operator==(const QualType &LHS, const QualType &RHS) { return LHS.Value == RHS.Value; } @@ -956,23 +960,23 @@ public: ID.AddPointer(getAsOpaquePtr()); } - /// getAddressSpace - Return the address space of this type. + /// Return the address space of this type. inline unsigned getAddressSpace() const; - /// getObjCGCAttr - Returns gc attribute of this type. + /// Returns gc attribute of this type. inline Qualifiers::GC getObjCGCAttr() const; - /// isObjCGCWeak true when Type is objc's weak. + /// true when Type is objc's weak. bool isObjCGCWeak() const { return getObjCGCAttr() == Qualifiers::Weak; } - /// isObjCGCStrong true when Type is objc's strong. + /// true when Type is objc's strong. bool isObjCGCStrong() const { return getObjCGCAttr() == Qualifiers::Strong; } - /// getObjCLifetime - Returns lifetime attribute of this type. + /// Returns lifetime attribute of this type. Qualifiers::ObjCLifetime getObjCLifetime() const { return getQualifiers().getObjCLifetime(); } @@ -992,7 +996,7 @@ public: DK_objc_weak_lifetime }; - /// isDestructedType - nonzero if objects of this type require + /// Returns a nonzero value if objects of this type require /// non-trivial work to clean up after. Non-zero because it's /// conceivable that qualifiers (objc_gc(weak)?) could make /// something require destruction. @@ -1000,7 +1004,7 @@ public: return isDestructedTypeImpl(*this); } - /// \brief Determine whether expressions of the given type are forbidden + /// Determine whether expressions of the given type are forbidden /// from being lvalues in C. /// /// The expression types that are forbidden to be lvalues are: @@ -1124,7 +1128,7 @@ class ExtQualsTypeCommonBase { friend class ExtQuals; }; -/// ExtQuals - We can encode up to four bits in the low bits of a +/// We can encode up to four bits in the low bits of a /// type pointer, but there are many more type qualifiers that we want /// to be able to apply to an arbitrary type. Therefore we have this /// struct, intended to be heap-allocated and used by QualType to @@ -1148,8 +1152,8 @@ class ExtQuals : public ExtQualsTypeCommonBase, public llvm::FoldingSetNode { // 3. ASTContext: // a) Update get{Volatile,Restrict}Type. - /// Quals - the immutable set of qualifiers applied by this - /// node; always contains extended qualifiers. + /// The immutable set of qualifiers applied by this node. Always contains + /// extended qualifiers. Qualifiers Quals; ExtQuals *this_() { return this; } @@ -1194,8 +1198,8 @@ public: } }; -/// \brief The kind of C++0x ref-qualifier associated with a function type, -/// which determines whether a member function's "this" object can be an +/// The kind of C++11 ref-qualifier associated with a function type. +/// This determines whether a member function's "this" object can be an /// lvalue, rvalue, or neither. enum RefQualifierKind { /// \brief No ref-qualifier was provided. @@ -1206,17 +1210,28 @@ enum RefQualifierKind { RQ_RValue }; -/// Type - This is the base class of the type hierarchy. A central concept -/// with types is that each type always has a canonical type. A canonical type -/// is the type with any typedef names stripped out of it or the types it -/// references. For example, consider: +/// Which keyword(s) were used to create an AutoType. +enum class AutoTypeKeyword { + /// \brief auto + Auto, + /// \brief decltype(auto) + DecltypeAuto, + /// \brief __auto_type (GNU extension) + GNUAutoType +}; + +/// The base class of the type hierarchy. +/// +/// A central concept with types is that each type always has a canonical +/// type. A canonical type is the type with any typedef names stripped out +/// of it or the types it references. For example, consider: /// /// typedef int foo; /// typedef foo* bar; /// 'int *' 'foo *' 'bar' /// /// There will be a Type object created for 'int'. Since int is canonical, its -/// canonicaltype pointer points to itself. There is also a Type for 'foo' (a +/// CanonicalType pointer points to itself. There is also a Type for 'foo' (a /// TypedefType). Its CanonicalType pointer points to the 'int' Type. Next /// there is a PointerType that represents 'int*', which, like 'int', is /// canonical. Finally, there is a PointerType type for 'foo*' whose canonical @@ -1253,18 +1268,18 @@ private: /// TypeClass bitfield - Enum that specifies what subclass this belongs to. unsigned TC : 8; - /// Dependent - Whether this type is a dependent type (C++ [temp.dep.type]). + /// Whether this type is a dependent type (C++ [temp.dep.type]). unsigned Dependent : 1; - /// \brief Whether this type somehow involves a template parameter, even + /// Whether this type somehow involves a template parameter, even /// if the resolution of the type does not depend on a template parameter. unsigned InstantiationDependent : 1; - /// \brief Whether this type is a variably-modified type (C99 6.7.5). + /// Whether this type is a variably-modified type (C99 6.7.5). unsigned VariablyModified : 1; /// \brief Whether this type contains an unexpanded parameter pack - /// (for C++0x variadic templates). + /// (for C++11 variadic templates). unsigned ContainsUnexpandedParameterPack : 1; /// \brief True if the cache (i.e. the bitfields here starting with @@ -1277,7 +1292,7 @@ private: /// \brief Whether this type involves and local or unnamed types. mutable unsigned CachedLocalOrUnnamed : 1; - /// \brief FromAST - Whether this type comes from an AST file. + /// \brief Whether this type comes from an AST file. mutable unsigned FromAST : 1; bool isCacheValid() const { @@ -1303,11 +1318,11 @@ protected: unsigned : NumTypeBits; - /// IndexTypeQuals - CVR qualifiers from declarations like + /// CVR qualifiers from declarations like /// 'int X[static restrict 4]'. For function parameters only. unsigned IndexTypeQuals : 3; - /// SizeModifier - storage class qualifiers from declarations like + /// Storage class qualifiers from declarations like /// 'int X[static restrict 4]'. For function parameters only. /// Actually an ArrayType::ArraySizeModifier. unsigned SizeModifier : 3; @@ -1332,7 +1347,7 @@ protected: /// regparm and the calling convention. unsigned ExtInfo : 9; - /// TypeQuals - Used only by FunctionProtoType, put here to pack with the + /// Used only by FunctionProtoType, put here to pack with the /// other bitfields. /// The qualifiers are part of FunctionProtoType because... /// @@ -1354,8 +1369,7 @@ protected: /// The number of type arguments stored directly on this object type. unsigned NumTypeArgs : 7; - /// NumProtocols - The number of protocols stored directly on this - /// object type. + /// The number of protocols stored directly on this object type. unsigned NumProtocols : 6; /// Whether this is a "kindof" type. @@ -1400,11 +1414,11 @@ protected: unsigned : NumTypeBits; - /// VecKind - The kind of vector, either a generic vector type or some + /// The kind of vector, either a generic vector type or some /// target-specific vector type such as for AltiVec or Neon. unsigned VecKind : 3; - /// NumElements - The number of elements in the vector. + /// The number of elements in the vector. unsigned NumElements : 29 - NumTypeBits; enum { MaxNumElements = (1 << (29 - NumTypeBits)) - 1 }; @@ -1415,7 +1429,7 @@ protected: unsigned : NumTypeBits; - /// AttrKind - an AttributedType::Kind + /// An AttributedType::Kind unsigned AttrKind : 32 - NumTypeBits; }; @@ -1424,8 +1438,9 @@ protected: unsigned : NumTypeBits; - /// Was this placeholder type spelled as 'decltype(auto)'? - unsigned IsDecltypeAuto : 1; + /// Was this placeholder type spelled as 'auto', 'decltype(auto)', + /// or '__auto_type'? AutoTypeKeyword value. + unsigned Keyword : 2; }; union { @@ -1521,17 +1536,17 @@ public: /// Types are partitioned into 3 broad categories (C99 6.2.5p1): /// object types, function types, and incomplete types. - /// isIncompleteType - Return true if this is an incomplete type. + /// Return true if this is an incomplete type. /// A type that can describe objects, but which lacks information needed to /// determine its size (e.g. void, or a fwd declared struct). Clients of this /// routine will need to determine if the size is actually required. /// - /// \brief Def If non-NULL, and the type refers to some kind of declaration + /// \brief Def If non-null, and the type refers to some kind of declaration /// that can be completed (such as a C struct, C++ class, or Objective-C /// class), will be set to the declaration. bool isIncompleteType(NamedDecl **Def = nullptr) const; - /// isIncompleteOrObjectType - Return true if this is an incomplete or object + /// Return true if this is an incomplete or object /// type, in other words, not a function type. bool isIncompleteOrObjectType() const { return !isFunctionType(); @@ -1545,35 +1560,34 @@ public: return !isReferenceType() && !isFunctionType() && !isVoidType(); } - /// isLiteralType - Return true if this is a literal type + /// Return true if this is a literal type /// (C++11 [basic.types]p10) bool isLiteralType(const ASTContext &Ctx) const; - /// \brief Test if this type is a standard-layout type. + /// Test if this type is a standard-layout type. /// (C++0x [basic.type]p9) bool isStandardLayoutType() const; /// Helper methods to distinguish type categories. All type predicates /// operate on the canonical type, ignoring typedefs and qualifiers. - /// isBuiltinType - returns true if the type is a builtin type. + /// Returns true if the type is a builtin type. bool isBuiltinType() const; - /// isSpecificBuiltinType - Test for a particular builtin type. + /// Test for a particular builtin type. bool isSpecificBuiltinType(unsigned K) const; - /// isPlaceholderType - Test for a type which does not represent an - /// actual type-system type but is instead used as a placeholder for - /// various convenient purposes within Clang. All such types are - /// BuiltinTypes. + /// Test for a type which does not represent an actual type-system type but + /// is instead used as a placeholder for various convenient purposes within + /// Clang. All such types are BuiltinTypes. bool isPlaceholderType() const; const BuiltinType *getAsPlaceholderType() const; - /// isSpecificPlaceholderType - Test for a specific placeholder type. + /// Test for a specific placeholder type. bool isSpecificPlaceholderType(unsigned K) const; - /// isNonOverloadPlaceholderType - Test for a placeholder type - /// other than Overload; see BuiltinType::isNonOverloadPlaceholderType. + /// Test for a placeholder type other than Overload; see + /// BuiltinType::isNonOverloadPlaceholderType. bool isNonOverloadPlaceholderType() const; /// isIntegerType() does *not* include complex integers (a GCC extension). @@ -1588,10 +1602,9 @@ public: bool isAnyCharacterType() const; bool isIntegralType(ASTContext &Ctx) const; - /// \brief Determine whether this type is an integral or enumeration type. + /// Determine whether this type is an integral or enumeration type. bool isIntegralOrEnumerationType() const; - /// \brief Determine whether this type is an integral or unscoped enumeration - /// type. + /// Determine whether this type is an integral or unscoped enumeration type. bool isIntegralOrUnscopedEnumerationType() const; /// Floating point categories. @@ -1655,6 +1668,7 @@ public: bool isObjCQualifiedClassType() const; // Class<foo> bool isObjCObjectOrInterfaceType() const; bool isObjCIdType() const; // id + bool isObjCInertUnsafeUnretainedType() const; /// Whether the type is Objective-C 'id' or a __kindof type of an /// object type, e.g., __kindof NSView * or __kindof id @@ -1685,17 +1699,27 @@ 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 isImage3dT() const; // OpenCL image3d_t + 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 bool isImageType() const; // Any OpenCL image type bool isSamplerT() const; // OpenCL sampler_t bool isEventT() const; // OpenCL event_t + bool isClkEventT() const; // OpenCL clk_event_t + bool isQueueT() const; // OpenCL queue_t + bool isNDRangeT() const; // OpenCL ndrange_t + bool isReserveIDT() const; // OpenCL reserve_id_t bool isOpenCLSpecificType() const; // Any OpenCL specific type @@ -1718,12 +1742,11 @@ public: STK_IntegralComplex, STK_FloatingComplex }; - /// getScalarTypeKind - Given that this is a scalar type, classify it. + /// Given that this is a scalar type, classify it. ScalarTypeKind getScalarTypeKind() const; - /// isDependentType - Whether this type is a dependent type, meaning - /// that its definition somehow depends on a template parameter - /// (C++ [temp.dep.type]). + /// Whether this type is a dependent type, meaning that its definition + /// somehow depends on a template parameter (C++ [temp.dep.type]). bool isDependentType() const { return TypeBits.Dependent; } /// \brief Determine whether this type is an instantiation-dependent type, @@ -1755,14 +1778,13 @@ public: bool canDecayToPointerType() const; - /// hasPointerRepresentation - Whether this type is represented - /// natively as a pointer; this includes pointers, references, block - /// pointers, and Objective-C interface, qualified id, and qualified - /// interface types, as well as nullptr_t. + /// Whether this type is represented natively as a pointer. This includes + /// pointers, references, block pointers, and Objective-C interface, + /// qualified id, and qualified interface types, as well as nullptr_t. bool hasPointerRepresentation() const; - /// hasObjCPointerRepresentation - Whether this type can represent - /// an objective pointer type for the purpose of GC'ability + /// Whether this type can represent an objective pointer type for the + /// purpose of GC'ability bool hasObjCPointerRepresentation() const; /// \brief Determine whether this type has an integer representation @@ -1813,7 +1835,7 @@ public: /// not refer to a CXXRecordDecl, returns NULL. const CXXRecordDecl *getPointeeCXXRecordDecl() const; - /// \brief Get the AutoType whose type will be deduced for a variable with + /// Get the AutoType whose type will be deduced for a variable with /// an initializer of this type. This looks through declarators like pointer /// types, but not through decltype or typedefs. AutoType *getContainedAutoType() const; @@ -1842,34 +1864,33 @@ public: /// qualifiers from the outermost type. const ArrayType *castAsArrayTypeUnsafe() const; - /// getBaseElementTypeUnsafe - Get the base element type of this - /// type, potentially discarding type qualifiers. This method - /// should never be used when type qualifiers are meaningful. + /// Get the base element type of this type, potentially discarding type + /// qualifiers. This should never be used when type qualifiers + /// are meaningful. const Type *getBaseElementTypeUnsafe() const; - /// getArrayElementTypeNoTypeQual - If this is an array type, return the - /// element type of the array, potentially with type qualifiers missing. - /// This method should never be used when type qualifiers are meaningful. + /// If this is an array type, return the element type of the array, + /// potentially with type qualifiers missing. + /// This should never be used when type qualifiers are meaningful. const Type *getArrayElementTypeNoTypeQual() const; - /// getPointeeType - If this is a pointer, ObjC object pointer, or block + /// If this is a pointer, ObjC object pointer, or block /// pointer, this returns the respective pointee. QualType getPointeeType() const; - /// getUnqualifiedDesugaredType() - Return the specified type with - /// any "sugar" removed from the type, removing any typedefs, - /// typeofs, etc., as well as any qualifiers. + /// Return the specified type with any "sugar" removed from the type, + /// removing any typedefs, typeofs, etc., as well as any qualifiers. const Type *getUnqualifiedDesugaredType() const; /// More type predicates useful for type checking/promotion bool isPromotableIntegerType() const; // C99 6.3.1.1p2 - /// isSignedIntegerType - Return true if this is an integer type that is + /// Return true if this is an integer type that is /// signed, according to C99 6.2.5p4 [char, signed char, short, int, long..], /// or an enum decl which has a signed representation. bool isSignedIntegerType() const; - /// isUnsignedIntegerType - Return true if this is an integer type that is + /// Return true if this is an integer type that is /// unsigned, according to C99 6.2.5p6 [which returns true for _Bool], /// or an enum decl which has an unsigned representation. bool isUnsignedIntegerType() const; @@ -1882,32 +1903,32 @@ public: /// enumeration types whose underlying type is a unsigned integer type. bool isUnsignedIntegerOrEnumerationType() const; - /// isConstantSizeType - Return true if this is not a variable sized type, + /// Return true if this is not a variable sized type, /// according to the rules of C99 6.7.5p3. It is not legal to call this on /// incomplete types. bool isConstantSizeType() const; - /// isSpecifierType - Returns true if this type can be represented by some + /// Returns true if this type can be represented by some /// set of type specifiers. bool isSpecifierType() const; - /// \brief Determine the linkage of this type. + /// Determine the linkage of this type. Linkage getLinkage() const; - /// \brief Determine the visibility of this type. + /// Determine the visibility of this type. Visibility getVisibility() const { return getLinkageAndVisibility().getVisibility(); } - /// \brief Return true if the visibility was explicitly set is the code. + /// Return true if the visibility was explicitly set is the code. bool isVisibilityExplicit() const { return getLinkageAndVisibility().isVisibilityExplicit(); } - /// \brief Determine the linkage and visibility of this type. + /// Determine the linkage and visibility of this type. LinkageInfo getLinkageAndVisibility() const; - /// \brief True if the computed linkage is valid. Used for consistency + /// True if the computed linkage is valid. Used for consistency /// checking. Should always return true. bool isLinkageValid() const; @@ -1984,7 +2005,7 @@ template <> inline const Class##Type *Type::castAs() const { \ #include "clang/AST/TypeNodes.def" -/// BuiltinType - This class is used for builtin types like 'int'. Builtin +/// This class is used for builtin types like 'int'. Builtin /// types are always canonical and have a literal name field. class BuiltinType : public Type { public: @@ -2059,7 +2080,7 @@ public: static bool classof(const Type *T) { return T->getTypeClass() == Builtin; } }; -/// ComplexType - C99 6.2.5p11 - Complex values. This supports the C99 complex +/// Complex values, per C99 6.2.5p11. This supports the C99 complex /// types (_Complex float etc) as well as the GCC integer complex extensions. /// class ComplexType : public Type, public llvm::FoldingSetNode { @@ -2089,7 +2110,7 @@ public: static bool classof(const Type *T) { return T->getTypeClass() == Complex; } }; -/// ParenType - Sugar for parentheses used when specifying types. +/// Sugar for parentheses used when specifying types. /// class ParenType : public Type, public llvm::FoldingSetNode { QualType Inner; @@ -2138,7 +2159,7 @@ public: QualType getPointeeType() const { return PointeeType; } - /// \brief Returns true if address spaces of pointers overlap. + /// Returns true if address spaces of pointers overlap. /// OpenCL v2.0 defines conversion rules for pointers to different /// address spaces (OpenCLC v2.0 s6.5.5) and notion of overlapping /// address spaces. @@ -2167,7 +2188,7 @@ public: static bool classof(const Type *T) { return T->getTypeClass() == Pointer; } }; -/// \brief Represents a type which was implicitly adjusted by the semantic +/// Represents a type which was implicitly adjusted by the semantic /// engine for arbitrary reasons. For example, array and function types can /// decay, and function types can have their calling conventions adjusted. class AdjustedType : public Type, public llvm::FoldingSetNode { @@ -2205,7 +2226,7 @@ public: } }; -/// \brief Represents a pointer type decayed from an array or function type. +/// Represents a pointer type decayed from an array or function type. class DecayedType : public AdjustedType { DecayedType(QualType OriginalType, QualType DecayedPtr, QualType CanonicalPtr) @@ -2225,7 +2246,7 @@ public: static bool classof(const Type *T) { return T->getTypeClass() == Decayed; } }; -/// BlockPointerType - pointer to a block type. +/// Pointer to a block type. /// This type is to represent types syntactically represented as /// "void (^)(int)", etc. Pointee is required to always be a function type. /// @@ -2260,7 +2281,7 @@ public: } }; -/// ReferenceType - Base for LValueReferenceType and RValueReferenceType +/// Base for LValueReferenceType and RValueReferenceType /// class ReferenceType : public Type, public llvm::FoldingSetNode { QualType PointeeType; @@ -2307,7 +2328,7 @@ public: } }; -/// LValueReferenceType - C++ [dcl.ref] - Lvalue reference +/// An lvalue reference type, per C++11 [dcl.ref]. /// class LValueReferenceType : public ReferenceType { LValueReferenceType(QualType Referencee, QualType CanonicalRef, @@ -2324,7 +2345,7 @@ public: } }; -/// RValueReferenceType - C++0x [dcl.ref] - Rvalue reference +/// An rvalue reference type, per C++11 [dcl.ref]. /// class RValueReferenceType : public ReferenceType { RValueReferenceType(QualType Referencee, QualType CanonicalRef) : @@ -2340,7 +2361,9 @@ public: } }; -/// MemberPointerType - C++ 8.3.3 - Pointers to members +/// A pointer to member type per C++ 8.3.3 - Pointers to members. +/// +/// This includes both pointers to data members and pointer to member functions. /// class MemberPointerType : public Type, public llvm::FoldingSetNode { QualType PointeeType; @@ -2395,11 +2418,11 @@ public: } }; -/// ArrayType - C99 6.7.5.2 - Array Declarators. +/// Represents an array type, per C99 6.7.5.2 - Array Declarators. /// class ArrayType : public Type, public llvm::FoldingSetNode { public: - /// ArraySizeModifier - Capture whether this is a normal array (e.g. int X[4]) + /// Capture whether this is a normal array (e.g. int X[4]) /// an array with a static size (e.g. int X[static 4]), or an array /// with a star size (e.g. int X[*]). /// 'static' is only allowed on function parameters. @@ -2407,7 +2430,7 @@ public: Normal, Static, Star }; private: - /// ElementType - The element type of the array. + /// The element type of the array. QualType ElementType; protected: @@ -2450,10 +2473,9 @@ public: } }; -/// ConstantArrayType - This class represents the canonical version of -/// C arrays with a specified constant size. For example, the canonical -/// type for 'int A[4 + 4*100]' is a ConstantArrayType where the element -/// type is 'int' and the size is 404. +/// Represents the canonical version of C arrays with a specified constant size. +/// For example, the canonical type for 'int A[4 + 4*100]' is a +/// ConstantArrayType where the element type is 'int' and the size is 404. class ConstantArrayType : public ArrayType { llvm::APInt Size; // Allows us to unique the type. @@ -2501,9 +2523,9 @@ public: } }; -/// IncompleteArrayType - This class represents C arrays with an unspecified -/// size. For example 'int A[]' has an IncompleteArrayType where the element -/// type is 'int' and the size is unspecified. +/// Represents a C array with an unspecified size. For example 'int A[]' has +/// an IncompleteArrayType where the element type is 'int' and the size is +/// unspecified. class IncompleteArrayType : public ArrayType { IncompleteArrayType(QualType et, QualType can, @@ -2534,8 +2556,8 @@ public: } }; -/// VariableArrayType - This class represents C arrays with a specified size -/// which is not an integer-constant-expression. For example, 'int s[x+foo()]'. +/// Represents a C array with a specified size that is not an +/// integer-constant-expression. For example, 'int s[x+foo()]'. /// Since the size expression is an arbitrary expression, we store it as such. /// /// Note: VariableArrayType's aren't uniqued (since the expressions aren't) and @@ -2550,10 +2572,10 @@ public: /// } /// class VariableArrayType : public ArrayType { - /// SizeExpr - An assignment expression. VLA's are only permitted within + /// An assignment-expression. VLA's are only permitted within /// a function block. Stmt *SizeExpr; - /// Brackets - The left and right array brackets. + /// The range spanned by the left and right array brackets. SourceRange Brackets; VariableArrayType(QualType et, QualType can, Expr *e, @@ -2588,9 +2610,9 @@ public: } }; -/// DependentSizedArrayType - This type represents an array type in -/// C++ whose size is a value-dependent expression. For example: +/// Represents an array type in C++ whose size is a value-dependent expression. /// +/// For example: /// \code /// template<typename T, int Size> /// class array { @@ -2607,11 +2629,11 @@ class DependentSizedArrayType : public ArrayType { /// \brief An assignment expression that will instantiate to the /// size of the array. /// - /// The expression itself might be NULL, in which case the array + /// The expression itself might be null, in which case the array /// type will have its size deduced from an initializer. Stmt *SizeExpr; - /// Brackets - The left and right array brackets. + /// The range spanned by the left and right array brackets. SourceRange Brackets; DependentSizedArrayType(const ASTContext &Context, QualType et, QualType can, @@ -2650,18 +2672,20 @@ public: unsigned TypeQuals, Expr *E); }; -/// DependentSizedExtVectorType - This type represent an extended vector type -/// where either the type or size is dependent. For example: -/// @code +/// Represents an extended vector type where either the type or size is +/// dependent. +/// +/// For example: +/// \code /// template<typename T, int Size> /// class vector { /// typedef T __attribute__((ext_vector_type(Size))) type; /// } -/// @endcode +/// \endcode class DependentSizedExtVectorType : public Type, public llvm::FoldingSetNode { const ASTContext &Context; Expr *SizeExpr; - /// ElementType - The element type of the array. + /// The element type of the array. QualType ElementType; SourceLocation loc; @@ -2691,7 +2715,7 @@ public: }; -/// VectorType - GCC generic vector type. This type is created using +/// Represents a GCC generic vector type. This type is created using /// __attribute__((vector_size(n)), where "n" specifies the vector size in /// bytes; or from an Altivec __vector or vector declaration. /// Since the constructor takes the number of vector elements, the @@ -2699,15 +2723,15 @@ public: class VectorType : public Type, public llvm::FoldingSetNode { public: enum VectorKind { - GenericVector, // not a target-specific vector type - AltiVecVector, // is AltiVec vector - AltiVecPixel, // is AltiVec 'vector Pixel' - AltiVecBool, // is AltiVec 'vector bool ...' - NeonVector, // is ARM Neon vector - NeonPolyVector // is ARM Neon polynomial vector + GenericVector, ///< not a target-specific vector type + AltiVecVector, ///< is AltiVec vector + AltiVecPixel, ///< is AltiVec 'vector Pixel' + AltiVecBool, ///< is AltiVec 'vector bool ...' + NeonVector, ///< is ARM Neon vector + NeonPolyVector ///< is ARM Neon polynomial vector }; protected: - /// ElementType - The element type of the vector. + /// The element type of the vector. QualType ElementType; VectorType(QualType vecType, unsigned nElements, QualType canonType, @@ -2824,7 +2848,7 @@ class FunctionType : public Type { QualType ResultType; public: - /// ExtInfo - A class which abstracts out some details necessary for + /// A class which abstracts out some details necessary for /// making a call. /// /// It is not actually used directly for storing this information in @@ -2878,7 +2902,7 @@ class FunctionType : public Type { } // Constructor with all defaults. Use when for example creating a - // function know to use defaults. + // function known to use defaults. ExtInfo() : Bits(CC_C) { } // Constructor with just the calling convention, which is an important part @@ -2953,7 +2977,7 @@ public: bool getHasRegParm() const { return getExtInfo().getHasRegParm(); } unsigned getRegParmType() const { return getExtInfo().getRegParm(); } - /// \brief Determine whether this function type includes the GNU noreturn + /// Determine whether this function type includes the GNU noreturn /// attribute. The C++11 [[noreturn]] attribute does not affect the function /// type. bool getNoReturnAttr() const { return getExtInfo().getNoReturn(); } @@ -2977,7 +3001,7 @@ public: } }; -/// FunctionNoProtoType - Represents a K&R-style 'int foo()' function, which has +/// Represents a K&R-style 'int foo()' function, which has /// no information available about its arguments. class FunctionNoProtoType : public FunctionType, public llvm::FoldingSetNode { FunctionNoProtoType(QualType Result, QualType Canonical, ExtInfo Info) @@ -3008,7 +3032,7 @@ public: } }; -/// FunctionProtoType - Represents a prototype with parameter type info, e.g. +/// Represents a prototype with parameter type info, e.g. /// 'int foo(int)' or 'int foo(void)'. 'void' is represented as having no /// parameters, not as having a single void parameter. Such a type can have an /// exception specification, but this specification is not part of the canonical @@ -3038,7 +3062,7 @@ public: FunctionDecl *SourceTemplate; }; - /// ExtProtoInfo - Extra information about a function prototype. + /// Extra information about a function prototype. struct ExtProtoInfo { ExtProtoInfo() : Variadic(false), HasTrailingReturn(false), TypeQuals(0), @@ -3081,19 +3105,19 @@ private: /// The number of parameters this function has, not counting '...'. unsigned NumParams : 15; - /// NumExceptions - The number of types in the exception spec, if any. + /// The number of types in the exception spec, if any. unsigned NumExceptions : 9; - /// ExceptionSpecType - The type of exception specification this function has. + /// The type of exception specification this function has. unsigned ExceptionSpecType : 4; - /// HasAnyConsumedParams - Whether this function has any consumed parameters. + /// Whether this function has any consumed parameters. unsigned HasAnyConsumedParams : 1; - /// Variadic - Whether the function is variadic. + /// Whether the function is variadic. unsigned Variadic : 1; - /// HasTrailingReturn - Whether this function has a trailing return type. + /// Whether this function has a trailing return type. unsigned HasTrailingReturn : 1; // ParamInfo - There is an variable size array after the class in memory that @@ -3120,11 +3144,13 @@ private: assert(hasAnyConsumedParams()); // Find the end of the exceptions. - Expr *const *eh_end = reinterpret_cast<Expr *const *>(param_type_end()); - if (getExceptionSpecType() != EST_ComputedNoexcept) - eh_end += NumExceptions; - else + 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); return reinterpret_cast<const bool*>(eh_end); } @@ -3162,25 +3188,25 @@ public: return EPI; } - /// \brief Get the kind of exception specification on this function. + /// Get the kind of exception specification on this function. ExceptionSpecificationType getExceptionSpecType() const { return static_cast<ExceptionSpecificationType>(ExceptionSpecType); } - /// \brief Return whether this function has any kind of exception spec. + /// Return whether this function has any kind of exception spec. bool hasExceptionSpec() const { return getExceptionSpecType() != EST_None; } - /// \brief Return whether this function has a dynamic (throw) exception spec. + /// Return whether this function has a dynamic (throw) exception spec. bool hasDynamicExceptionSpec() const { return isDynamicExceptionSpec(getExceptionSpecType()); } - /// \brief Return whether this function has a noexcept exception spec. + /// Return whether this function has a noexcept exception spec. bool hasNoexceptExceptionSpec() const { return isNoexceptExceptionSpec(getExceptionSpecType()); } - /// \brief Return whether this function has a dependent exception spec. + /// Return whether this function has a dependent exception spec. bool hasDependentExceptionSpec() const; - /// \brief Result type of getNoexceptSpec(). + /// Result type of getNoexceptSpec(). enum NoexceptResult { NR_NoNoexcept, ///< There is no noexcept specifier. NR_BadNoexcept, ///< The noexcept specifier has a bad expression. @@ -3188,7 +3214,7 @@ public: NR_Throw, ///< The noexcept specifier evaluates to false. NR_Nothrow ///< The noexcept specifier evaluates to true. }; - /// \brief Get the meaning of the noexcept spec on this function, if any. + /// Get the meaning of the noexcept spec on this function, if any. NoexceptResult getNoexceptSpec(const ASTContext &Ctx) const; unsigned getNumExceptions() const { return NumExceptions; } QualType getExceptionType(unsigned i) const { @@ -3220,14 +3246,14 @@ public: return nullptr; return reinterpret_cast<FunctionDecl *const *>(param_type_end())[1]; } - /// \brief Determine whether this function type has a non-throwing exception + /// Determine whether this function type has a non-throwing exception /// specification. If this depends on template arguments, returns /// \c ResultIfDependent. bool isNothrow(const ASTContext &Ctx, bool ResultIfDependent = false) const; bool isVariadic() const { return Variadic; } - /// \brief Determines whether this function prototype contains a + /// Determines whether this function prototype contains a /// parameter pack at the end. /// /// A function template whose last parameter is a parameter pack can be @@ -3240,7 +3266,7 @@ public: unsigned getTypeQuals() const { return FunctionType::getTypeQuals(); } - /// \brief Retrieve the ref-qualifier associated with this function type. + /// Retrieve the ref-qualifier associated with this function type. RefQualifierKind getRefQualifier() const { return static_cast<RefQualifierKind>(FunctionTypeBits.RefQualifier); } @@ -3284,7 +3310,7 @@ public: bool isSugared() const { return false; } QualType desugar() const { return QualType(this, 0); } - void printExceptionSpecification(raw_ostream &OS, + void printExceptionSpecification(raw_ostream &OS, const PrintingPolicy &Policy) const; static bool classof(const Type *T) { @@ -3297,10 +3323,10 @@ public: const ExtProtoInfo &EPI, const ASTContext &Context); }; - /// \brief Represents the dependent type named by a dependently-scoped /// typename using declaration, e.g. /// using typename Base<T>::foo; +/// /// Template instantiation turns these into the underlying type. class UnresolvedUsingType : public Type { UnresolvedUsingTypenameDecl *Decl; @@ -3353,7 +3379,7 @@ public: static bool classof(const Type *T) { return T->getTypeClass() == Typedef; } }; -/// TypeOfExprType (GCC extension). +/// Represents a `typeof` (or __typeof__) expression (a GCC extension). class TypeOfExprType : public Type { Expr *TOExpr; @@ -3373,7 +3399,7 @@ public: }; /// \brief Internal representation of canonical, dependent -/// typeof(expr) types. +/// `typeof(expr)` types. /// /// This class is used internally by the ASTContext to manage /// canonical, dependent types, only. Clients will only see instances @@ -3394,7 +3420,7 @@ public: Expr *E); }; -/// TypeOfType (GCC extension). +/// Represents `typeof(type)`, a GCC extension. class TypeOfType : public Type { QualType TOType; TypeOfType(QualType T, QualType can) @@ -3418,7 +3444,7 @@ public: static bool classof(const Type *T) { return T->getTypeClass() == TypeOf; } }; -/// DecltypeType (C++0x) +/// Represents the type `decltype(expr)` (C++11). class DecltypeType : public Type { Expr *E; QualType UnderlyingType; @@ -3459,7 +3485,7 @@ public: Expr *E); }; -/// \brief A unary type transform, which is a type constructed from another +/// A unary type transform, which is a type constructed from another. class UnaryTransformType : public Type { public: enum UTTKind { @@ -3497,15 +3523,14 @@ class TagType : public Type { TagDecl * decl; friend class ASTReader; - + protected: TagType(TypeClass TC, const TagDecl *D, QualType can); public: TagDecl *getDecl() const; - /// @brief Determines whether this type is in the process of being - /// defined. + /// Determines whether this type is in the process of being defined. bool isBeingDefined() const; static bool classof(const Type *T) { @@ -3513,7 +3538,7 @@ public: } }; -/// RecordType - This is a helper class that allows the use of isa/cast/dyncast +/// A helper class that allows the use of isa/cast/dyncast /// to detect TagType objects of structs/unions/classes. class RecordType : public TagType { protected: @@ -3539,7 +3564,7 @@ public: static bool classof(const Type *T) { return T->getTypeClass() == Record; } }; -/// EnumType - This is a helper class that allows the use of isa/cast/dyncast +/// A helper class that allows the use of isa/cast/dyncast /// to detect TagType objects of enums. class EnumType : public TagType { explicit EnumType(const EnumDecl *D) @@ -3557,12 +3582,12 @@ public: static bool classof(const Type *T) { return T->getTypeClass() == Enum; } }; -/// AttributedType - An attributed type is a type to which a type -/// attribute has been applied. The "modified type" is the -/// fully-sugared type to which the attributed type was applied; -/// generally it is not canonically equivalent to the attributed type. -/// The "equivalent type" is the minimally-desugared type which the -/// type is canonically equivalent to. +/// An attributed type is a type to which a type attribute has been applied. +/// +/// The "modified type" is the fully-sugared type to which the attributed +/// type was applied; generally it is not canonically equivalent to the +/// attributed type. The "equivalent type" is the minimally-desugared type +/// which the type is canonically equivalent to. /// /// For example, in the following attributed type: /// int32_t __attribute__((vector_size(16))) @@ -3612,6 +3637,7 @@ public: attr_nullable, attr_null_unspecified, attr_objc_kindof, + attr_objc_inert_unsafe_unretained, }; private: @@ -3641,6 +3667,23 @@ public: bool isSugared() const { return true; } QualType desugar() const { return getEquivalentType(); } + /// Does this attribute behave like a type qualifier? + /// + /// A type qualifier adjusts a type to provide specialized rules for + /// a specific object, like the standard const and volatile qualifiers. + /// This includes attributes controlling things like nullability, + /// address spaces, and ARC ownership. The value of the object is still + /// largely described by the modified type. + /// + /// In contrast, many type attributes "rewrite" their modified type to + /// produce a fundamentally different type, not necessarily related in any + /// formalizable way to the original type. For example, calling convention + /// and vector attributes are not simple type qualifiers. + /// + /// Type qualifiers are often, but not always, reflected in the canonical + /// type. + bool isQualifier() const; + bool isMSTypeSpec() const; bool isCallingConv() const; @@ -3653,7 +3696,7 @@ public: switch (kind) { case NullabilityKind::NonNull: return attr_nonnull; - + case NullabilityKind::Nullable: return attr_nullable; @@ -3865,29 +3908,33 @@ public: } }; -/// \brief Represents a C++11 auto or C++1y decltype(auto) type. +/// \brief Represents a C++11 auto or C++14 decltype(auto) type. /// /// These types are usually a placeholder for a deduced type. However, before /// the initializer is attached, or if the initializer is type-dependent, there /// is no deduced type and an auto type is canonical. In the latter case, it is /// also a dependent type. class AutoType : public Type, public llvm::FoldingSetNode { - AutoType(QualType DeducedType, bool IsDecltypeAuto, - bool IsDependent) + AutoType(QualType DeducedType, AutoTypeKeyword Keyword, bool IsDependent) : Type(Auto, DeducedType.isNull() ? QualType(this, 0) : DeducedType, /*Dependent=*/IsDependent, /*InstantiationDependent=*/IsDependent, - /*VariablyModified=*/false, - /*ContainsParameterPack=*/DeducedType.isNull() + /*VariablyModified=*/false, + /*ContainsParameterPack=*/DeducedType.isNull() ? false : DeducedType->containsUnexpandedParameterPack()) { assert((DeducedType.isNull() || !IsDependent) && "auto deduced to dependent type"); - AutoTypeBits.IsDecltypeAuto = IsDecltypeAuto; + AutoTypeBits.Keyword = (unsigned)Keyword; } friend class ASTContext; // ASTContext creates these public: - bool isDecltypeAuto() const { return AutoTypeBits.IsDecltypeAuto; } + bool isDecltypeAuto() const { + return getKeyword() == AutoTypeKeyword::DecltypeAuto; + } + AutoTypeKeyword getKeyword() const { + return (AutoTypeKeyword)AutoTypeBits.Keyword; + } bool isSugared() const { return !isCanonicalUnqualified(); } QualType desugar() const { return getCanonicalTypeInternal(); } @@ -3902,14 +3949,13 @@ public: } void Profile(llvm::FoldingSetNodeID &ID) { - Profile(ID, getDeducedType(), isDecltypeAuto(), - isDependentType()); + Profile(ID, getDeducedType(), getKeyword(), isDependentType()); } static void Profile(llvm::FoldingSetNodeID &ID, QualType Deduced, - bool IsDecltypeAuto, bool IsDependent) { + AutoTypeKeyword Keyword, bool IsDependent) { ID.AddPointer(Deduced.getAsOpaquePtr()); - ID.AddBoolean(IsDecltypeAuto); + ID.AddInteger((unsigned)Keyword); ID.AddBoolean(IsDependent); } @@ -3926,9 +3972,9 @@ public: /// @c DependentTemplateSpecializationType. /// /// A non-dependent template specialization type is always "sugar", -/// typically for a @c RecordType. For example, a class template -/// specialization type of @c vector<int> will refer to a tag type for -/// the instantiation @c std::vector<int, std::allocator<int>> +/// typically for a \c RecordType. For example, a class template +/// specialization type of \c vector<int> will refer to a tag type for +/// the instantiation \c std::vector<int, std::allocator<int>> /// /// Template specializations are dependent if either the template or /// any of the template arguments are dependent, in which case the @@ -3938,9 +3984,10 @@ public: /// TemplateArguments, followed by a QualType representing the /// non-canonical aliased type when the template is a type alias /// template. -class TemplateSpecializationType - : public Type, public llvm::FoldingSetNode { - /// \brief The name of the template being specialized. This is +class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) TemplateSpecializationType + : public Type, + public llvm::FoldingSetNode { + /// The name of the template being specialized. This is /// either a TemplateName::Template (in which case it is a /// ClassTemplateDecl*, a TemplateTemplateParmDecl*, or a /// TypeAliasTemplateDecl*), a @@ -3949,14 +3996,13 @@ class TemplateSpecializationType /// replacement must, recursively, be one of these). TemplateName Template; - /// \brief - The number of template arguments named in this class - /// template specialization. + /// The number of template arguments named in this class template + /// specialization. unsigned NumArgs : 31; - /// \brief Whether this template specialization type is a substituted - /// type alias. + /// Whether this template specialization type is a substituted type alias. bool TypeAlias : 1; - + TemplateSpecializationType(TemplateName T, const TemplateArgument *Args, unsigned NumArgs, QualType Canon, @@ -3965,8 +4011,7 @@ class TemplateSpecializationType friend class ASTContext; // ASTContext creates these public: - /// \brief Determine whether any of the given template arguments are - /// dependent. + /// Determine whether any of the given template arguments are dependent. static bool anyDependentTemplateArguments(const TemplateArgumentLoc *Args, unsigned NumArgs, bool &InstantiationDependent); @@ -4013,7 +4058,7 @@ public: /// }; /// \endcode bool isTypeAlias() const { return TypeAlias; } - + /// Get the aliased type, if this is a specialization of a type alias /// template. QualType getAliasedType() const { @@ -4026,19 +4071,19 @@ public: iterator begin() const { return getArgs(); } iterator end() const; // defined inline in TemplateBase.h - /// \brief Retrieve the name of the template that we are specializing. + /// Retrieve the name of the template that we are specializing. TemplateName getTemplateName() const { return Template; } - /// \brief Retrieve the template arguments. + /// Retrieve the template arguments. const TemplateArgument *getArgs() const { return reinterpret_cast<const TemplateArgument *>(this + 1); } - /// \brief Retrieve the number of template arguments. + /// Retrieve the number of template arguments. unsigned getNumArgs() const { return NumArgs; } - /// \brief Retrieve a specific template argument as a type. - /// \pre @c isArgType(Arg) + /// Retrieve a specific template argument as a type. + /// \pre \c isArgType(Arg) const TemplateArgument &getArg(unsigned Idx) const; // in TemplateBase.h bool isSugared() const { @@ -4062,7 +4107,7 @@ public: } }; -/// \brief The injected class name of a C++ class template or class +/// The injected class name of a C++ class template or class /// template partial specialization. Used to record that a type was /// spelled with a bare identifier rather than as a template-id; the /// equivalent for non-templated classes is just RecordType. @@ -4178,21 +4223,18 @@ public: return static_cast<ElaboratedTypeKeyword>(TypeWithKeywordBits.Keyword); } - /// getKeywordForTypeSpec - Converts a type specifier (DeclSpec::TST) - /// into an elaborated type keyword. + /// Converts a type specifier (DeclSpec::TST) into an elaborated type keyword. static ElaboratedTypeKeyword getKeywordForTypeSpec(unsigned TypeSpec); - /// getTagTypeKindForTypeSpec - Converts a type specifier (DeclSpec::TST) - /// into a tag type kind. It is an error to provide a type specifier - /// which *isn't* a tag kind here. + /// Converts a type specifier (DeclSpec::TST) into a tag type kind. + /// It is an error to provide a type specifier which *isn't* a tag kind here. static TagTypeKind getTagTypeKindForTypeSpec(unsigned TypeSpec); - /// getKeywordForTagDeclKind - Converts a TagTypeKind into an - /// elaborated type keyword. + /// Converts a TagTypeKind into an elaborated type keyword. static ElaboratedTypeKeyword getKeywordForTagTypeKind(TagTypeKind Tag); - /// getTagTypeKindForKeyword - Converts an elaborated type keyword into - // a TagTypeKind. It is an error to provide an elaborated type keyword + /// Converts an elaborated type keyword into a TagTypeKind. + /// It is an error to provide an elaborated type keyword /// which *isn't* a tag kind here. static TagTypeKind getTagTypeKindForKeyword(ElaboratedTypeKeyword Keyword); @@ -4218,10 +4260,10 @@ public: /// in the source code but containing no additional semantic information. class ElaboratedType : public TypeWithKeyword, public llvm::FoldingSetNode { - /// \brief The nested name specifier containing the qualifier. + /// The nested name specifier containing the qualifier. NestedNameSpecifier *NNS; - /// \brief The type that this qualified name refers to. + /// The type that this qualified name refers to. QualType NamedType; ElaboratedType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS, @@ -4242,16 +4284,16 @@ class ElaboratedType : public TypeWithKeyword, public llvm::FoldingSetNode { public: ~ElaboratedType(); - /// \brief Retrieve the qualification on this type. + /// Retrieve the qualification on this type. NestedNameSpecifier *getQualifier() const { return NNS; } - /// \brief Retrieve the type named by the qualified-id. + /// Retrieve the type named by the qualified-id. QualType getNamedType() const { return NamedType; } - /// \brief Remove a single level of sugar. + /// Remove a single level of sugar. QualType desugar() const { return getNamedType(); } - /// \brief Returns whether this type directly provides sugar. + /// Returns whether this type directly provides sugar. bool isSugared() const { return true; } void Profile(llvm::FoldingSetNodeID &ID) { @@ -4301,11 +4343,10 @@ class DependentNameType : public TypeWithKeyword, public llvm::FoldingSetNode { friend class ASTContext; // ASTContext creates these public: - /// \brief Retrieve the qualification on this type. + /// Retrieve the qualification on this type. NestedNameSpecifier *getQualifier() const { return NNS; } - /// \brief Retrieve the type named by the typename specifier as an - /// identifier. + /// Retrieve the type named by the typename specifier as an identifier. /// /// This routine will return a non-NULL identifier pointer when the /// form of the original typename was terminated by an identifier, @@ -4333,20 +4374,21 @@ public: } }; -/// DependentTemplateSpecializationType - Represents a template -/// specialization type whose template cannot be resolved, e.g. +/// Represents a template specialization type whose template cannot be +/// resolved, e.g. /// A<T>::template B<T> -class DependentTemplateSpecializationType : - public TypeWithKeyword, public llvm::FoldingSetNode { +class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) DependentTemplateSpecializationType + : public TypeWithKeyword, + public llvm::FoldingSetNode { - /// \brief The nested name specifier containing the qualifier. + /// The nested name specifier containing the qualifier. NestedNameSpecifier *NNS; - /// \brief The identifier of the template. + /// The identifier of the template. const IdentifierInfo *Name; - /// \brief - The number of template arguments named in this class - /// template specialization. + /// \brief The number of template arguments named in this class template + /// specialization. unsigned NumArgs; const TemplateArgument *getArgBuffer() const { @@ -4405,7 +4447,7 @@ public: /// \brief Represents a pack expansion of types. /// -/// Pack expansions are part of C++0x variadic templates. A pack +/// Pack expansions are part of C++11 variadic templates. A pack /// expansion contains a pattern, which itself contains one or more /// "unexpanded" parameter packs. When instantiated, a pack expansion /// produces a series of types, each instantiated from the pattern of @@ -4483,7 +4525,7 @@ public: } }; -/// ObjCObjectType - Represents a class type in Objective C. +/// Represents a class type in Objective C. /// /// Every Objective C type is a combination of a base type, a set of /// type arguments (optional, for parameterized classes) and a list of @@ -4560,8 +4602,8 @@ protected: void computeSuperClassTypeSlow() const; public: - /// getBaseType - Gets the base type of this object type. This is - /// always (possibly sugar for) one of: + /// Gets the base type of this object type. This is always (possibly + /// sugar for) one of: /// - the 'id' builtin type (as opposed to the 'id' type visible to the /// user, which is a typedef for an ObjCObjectPointerType) /// - the 'Class' builtin type (same caveat) @@ -4595,8 +4637,8 @@ public: bool isSpecialized() const; /// Determine whether this object type was written with type arguments. - bool isSpecializedAsWritten() const { - return ObjCObjectTypeBits.NumTypeArgs > 0; + bool isSpecializedAsWritten() const { + return ObjCObjectTypeBits.NumTypeArgs > 0; } /// Determine whether this object type is "unspecialized", meaning @@ -4612,8 +4654,8 @@ public: /// Retrieve the type arguments of this object type as they were /// written. - ArrayRef<QualType> getTypeArgsAsWritten() const { - return ArrayRef<QualType>(getTypeArgStorage(), + ArrayRef<QualType> getTypeArgsAsWritten() const { + return llvm::makeArrayRef(getTypeArgStorage(), ObjCObjectTypeBits.NumTypeArgs); } @@ -4626,11 +4668,11 @@ public: bool qual_empty() const { return getNumProtocols() == 0; } - /// getNumProtocols - Return the number of qualifying protocols in this - /// interface type, or 0 if there are none. + /// Return the number of qualifying protocols in this interface type, + /// or 0 if there are none. unsigned getNumProtocols() const { return ObjCObjectTypeBits.NumProtocols; } - /// \brief Fetch a protocol by index. + /// Fetch a protocol by index. ObjCProtocolDecl *getProtocol(unsigned I) const { assert(I < getNumProtocols() && "Out-of-range protocol access"); return qual_begin()[I]; @@ -4674,7 +4716,7 @@ public: } }; -/// ObjCObjectTypeImpl - A class providing a concrete implementation +/// A class providing a concrete implementation /// of ObjCObjectType, so as to not increase the footprint of /// ObjCInterfaceType. Code outside of ASTContext and the core type /// system should not reference this type. @@ -4708,11 +4750,10 @@ inline ObjCProtocolDecl **ObjCObjectType::getProtocolStorage() { getTypeArgStorage() + ObjCObjectTypeBits.NumTypeArgs); } -/// ObjCInterfaceType - Interfaces are the core concept in Objective-C for -/// object oriented design. They basically correspond to C++ classes. There -/// are two kinds of interface types, normal interfaces like "NSString" and -/// qualified interfaces, which are qualified with a protocol list like -/// "NSString<NSCopyable, NSAmazing>". +/// Interfaces are the core concept in Objective-C for object oriented design. +/// They basically correspond to C++ classes. There are two kinds of interface +/// types: normal interfaces like `NSString`, and qualified interfaces, which +/// are qualified with a protocol list like `NSString<NSCopyable, NSAmazing>`. /// /// ObjCInterfaceType guarantees the following properties when considered /// as a subtype of its superclass, ObjCObjectType: @@ -4732,7 +4773,7 @@ class ObjCInterfaceType : public ObjCObjectType { friend class ObjCInterfaceDecl; public: - /// getDecl - Get the declaration of this interface. + /// Get the declaration of this interface. ObjCInterfaceDecl *getDecl() const { return Decl; } bool isSugared() const { return false; } @@ -4767,12 +4808,12 @@ inline ObjCInterfaceDecl *ObjCObjectType::getInterface() const { return nullptr; } -/// ObjCObjectPointerType - Used to represent a pointer to an -/// Objective C object. These are constructed from pointer -/// declarators when the pointee type is an ObjCObjectType (or sugar -/// for one). In addition, the 'id' and 'Class' types are typedefs -/// for these, and the protocol-qualified types 'id<P>' and 'Class<P>' -/// are translated into these. +/// Represents a pointer to an Objective C object. +/// +/// These are constructed from pointer declarators when the pointee type is +/// an ObjCObjectType (or sugar for one). In addition, the 'id' and 'Class' +/// types are typedefs for these, and the protocol-qualified types 'id<P>' +/// and 'Class<P>' are translated into these. /// /// Pointers to pointers to Objective C objects are still PointerTypes; /// only the first level of pointer gets it own type implementation. @@ -4789,12 +4830,11 @@ class ObjCObjectPointerType : public Type, public llvm::FoldingSetNode { friend class ASTContext; // ASTContext creates these. public: - /// getPointeeType - Gets the type pointed to by this ObjC pointer. + /// Gets the type pointed to by this ObjC pointer. /// The result will always be an ObjCObjectType or sugar thereof. QualType getPointeeType() const { return PointeeType; } - /// getObjCObjectType - Gets the type pointed to by this ObjC - /// pointer. This method always returns non-null. + /// Gets the type pointed to by this ObjC pointer. Always returns non-null. /// /// This method is equivalent to getPointeeType() except that /// it discards any typedefs (or other sugar) between this @@ -4821,14 +4861,14 @@ public: return PointeeType->castAs<ObjCObjectType>(); } - /// getInterfaceType - If this pointer points to an Objective C + /// If this pointer points to an Objective C /// \@interface type, gets the type for that interface. Any protocol /// qualifiers on the interface are ignored. /// /// \return null if the base type for this pointer is 'id' or 'Class' const ObjCInterfaceType *getInterfaceType() const; - /// getInterfaceDecl - If this pointer points to an Objective \@interface + /// If this pointer points to an Objective \@interface /// type, gets the declaration for that interface. /// /// \return null if the base type for this pointer is 'id' or 'Class' @@ -4836,32 +4876,31 @@ public: return getObjectType()->getInterface(); } - /// isObjCIdType - True if this is equivalent to the 'id' type, i.e. if + /// True if this is equivalent to the 'id' type, i.e. if /// its object type is the primitive 'id' type with no protocols. bool isObjCIdType() const { return getObjectType()->isObjCUnqualifiedId(); } - /// isObjCClassType - True if this is equivalent to the 'Class' type, + /// True if this is equivalent to the 'Class' type, /// i.e. if its object tive is the primitive 'Class' type with no protocols. bool isObjCClassType() const { return getObjectType()->isObjCUnqualifiedClass(); } - /// isObjCIdOrClassType - True if this is equivalent to the 'id' or - /// 'Class' type, + /// True if this is equivalent to the 'id' or 'Class' type, bool isObjCIdOrClassType() const { return getObjectType()->isObjCUnqualifiedIdOrClass(); } - /// isObjCQualifiedIdType - True if this is equivalent to 'id<P>' for some - /// non-empty set of protocols. + /// True if this is equivalent to 'id<P>' for some non-empty set of + /// protocols. bool isObjCQualifiedIdType() const { return getObjectType()->isObjCQualifiedId(); } - /// isObjCQualifiedClassType - True if this is equivalent to 'Class<P>' for - /// some non-empty set of protocols. + /// True if this is equivalent to 'Class<P>' for some non-empty set of + /// protocols. bool isObjCQualifiedClassType() const { return getObjectType()->isObjCQualifiedClass(); } @@ -4873,10 +4912,10 @@ public: bool isSpecialized() const { return getObjectType()->isSpecialized(); } /// Whether this type is specialized, meaning that it has type arguments. - bool isSpecializedAsWritten() const { - return getObjectType()->isSpecializedAsWritten(); + bool isSpecializedAsWritten() const { + return getObjectType()->isSpecializedAsWritten(); } - + /// Whether this type is unspecialized, meaning that is has no type arguments. bool isUnspecialized() const { return getObjectType()->isUnspecialized(); } @@ -4885,13 +4924,13 @@ public: bool isUnspecializedAsWritten() const { return !isSpecializedAsWritten(); } /// Retrieve the type arguments for this type. - ArrayRef<QualType> getTypeArgs() const { - return getObjectType()->getTypeArgs(); + ArrayRef<QualType> getTypeArgs() const { + return getObjectType()->getTypeArgs(); } /// Retrieve the type arguments for this type. - ArrayRef<QualType> getTypeArgsAsWritten() const { - return getObjectType()->getTypeArgsAsWritten(); + ArrayRef<QualType> getTypeArgsAsWritten() const { + return getObjectType()->getTypeArgsAsWritten(); } /// An iterator over the qualifiers on the object type. Provided @@ -4909,14 +4948,12 @@ public: } bool qual_empty() const { return getObjectType()->qual_empty(); } - /// getNumProtocols - Return the number of qualifying protocols on - /// the object type. + /// Return the number of qualifying protocols on the object type. unsigned getNumProtocols() const { return getObjectType()->getNumProtocols(); } - /// \brief Retrieve a qualifying protocol by index on the object - /// type. + /// Retrieve a qualifying protocol by index on the object type. ObjCProtocolDecl *getProtocol(unsigned I) const { return getObjectType()->getProtocol(I); } @@ -4960,7 +4997,7 @@ class AtomicType : public Type, public llvm::FoldingSetNode { friend class ASTContext; // ASTContext creates these. public: - /// getValueType - Gets the type contained by this atomic type, i.e. + /// Gets the type contained by this atomic type, i.e. /// the type returned by performing an atomic load of this atomic type. QualType getValueType() const { return ValueType; } @@ -5127,12 +5164,12 @@ inline void QualType::removeLocalCVRQualifiers(unsigned Mask) { removeLocalFastQualifiers(Mask); } -/// getAddressSpace - Return the address space of this type. +/// Return the address space of this type. inline unsigned QualType::getAddressSpace() const { return getQualifiers().getAddressSpace(); } - -/// getObjCGCAttr - Return the gc attribute of this type. + +/// Return the gc attribute of this type. inline Qualifiers::GC QualType::getObjCGCAttr() const { return getQualifiers().getObjCGCAttr(); } @@ -5151,7 +5188,7 @@ inline FunctionType::ExtInfo getFunctionExtInfo(QualType t) { return getFunctionExtInfo(*t); } -/// isMoreQualifiedThan - Determine whether this type is more +/// Determine whether this type is more /// qualified than the Other type. For example, "const volatile int" /// is more qualified than "const int", "volatile int", and /// "int". However, it is not more qualified than "const volatile @@ -5162,7 +5199,7 @@ inline bool QualType::isMoreQualifiedThan(QualType other) const { return (myQuals != otherQuals && myQuals.compatiblyIncludes(otherQuals)); } -/// isAtLeastAsQualifiedAs - Determine whether this type is at last +/// Determine whether this type is at last /// as qualified as the Other type. For example, "const volatile /// int" is at least as qualified as "const int", "volatile int", /// "int", and "const volatile int". @@ -5170,7 +5207,7 @@ inline bool QualType::isAtLeastAsQualifiedAs(QualType other) const { return getQualifiers().compatiblyIncludes(other.getQualifiers()); } -/// getNonReferenceType - If Type is a reference type (e.g., const +/// If Type is a reference type (e.g., const /// int&), returns the type that the reference refers to ("const /// int"). Otherwise, returns the type itself. This routine is used /// throughout Sema to implement C++ 5p6: @@ -5191,7 +5228,7 @@ inline bool QualType::isCForbiddenLValueType() const { getTypePtr()->isFunctionType()); } -/// \brief Tests whether the type is categorized as a fundamental type. +/// Tests whether the type is categorized as a fundamental type. /// /// \returns True for types specified in C++0x [basic.fundamental]. inline bool Type::isFundamentalType() const { @@ -5201,7 +5238,7 @@ inline bool Type::isFundamentalType() const { (isArithmeticType() && !isEnumeralType()); } -/// \brief Tests whether the type is categorized as a compound type. +/// Tests whether the type is categorized as a compound type. /// /// \returns True for types specified in C++0x [basic.compound]. inline bool Type::isCompoundType() const { @@ -5364,6 +5401,30 @@ 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); } @@ -5376,14 +5437,33 @@ inline bool Type::isEventT() const { return isSpecificBuiltinType(BuiltinType::OCLEvent); } +inline bool Type::isClkEventT() const { + return isSpecificBuiltinType(BuiltinType::OCLClkEvent); +} + +inline bool Type::isQueueT() const { + return isSpecificBuiltinType(BuiltinType::OCLQueue); +} + +inline bool Type::isNDRangeT() const { + return isSpecificBuiltinType(BuiltinType::OCLNDRange); +} + +inline bool Type::isReserveIDT() const { + return isSpecificBuiltinType(BuiltinType::OCLReserveID); +} + inline bool Type::isImageType() const { - return isImage3dT() || - isImage2dT() || isImage2dArrayT() || - isImage1dT() || isImage1dArrayT() || isImage1dBufferT(); + return isImage3dT() || isImage2dT() || isImage2dArrayT() || + isImage2dDepthT() || isImage2dArrayDepthT() || isImage2dMSAAT() || + isImage2dArrayMSAAT() || isImage2dMSAATDepth() || + isImage2dArrayMSAATDepth() || isImage1dT() || isImage1dArrayT() || + isImage1dBufferT(); } inline bool Type::isOpenCLSpecificType() const { - return isSamplerT() || isEventT() || isImageType(); + return isSamplerT() || isEventT() || isImageType() || isClkEventT() || + isQueueT() || isNDRangeT() || isReserveIDT(); } inline bool Type::isTemplateTypeParmType() const { diff --git a/contrib/llvm/tools/clang/include/clang/AST/TypeLoc.h b/contrib/llvm/tools/clang/include/clang/AST/TypeLoc.h index f4d20b8..26feda5 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/TypeLoc.h +++ b/contrib/llvm/tools/clang/include/clang/AST/TypeLoc.h @@ -151,6 +151,14 @@ public: TypeLoc IgnoreParens() const; + /// \brief Find a type with the location of an explicit type qualifier. + /// + /// The result, if non-null, will be one of: + /// QualifiedTypeLoc + /// AtomicTypeLoc + /// AttributedTypeLoc, for those type attributes that behave as qualifiers + TypeLoc findExplicitQualifierLoc() const; + /// \brief Initializes this to state that every location in this /// type is the given location. /// @@ -162,19 +170,18 @@ public: /// \brief Initializes this by copying its information from another /// TypeLoc of the same type. - void initializeFullCopy(TypeLoc Other) const { + void initializeFullCopy(TypeLoc Other) { assert(getType() == Other.getType()); - size_t Size = getFullDataSize(); - memcpy(getOpaqueData(), Other.getOpaqueData(), Size); + copy(Other); } /// \brief Initializes this by copying its information from another /// TypeLoc of the same type. The given size must be the full data /// size. - void initializeFullCopy(TypeLoc Other, unsigned Size) const { + void initializeFullCopy(TypeLoc Other, unsigned Size) { assert(getType() == Other.getType()); assert(getFullDataSize() == Size); - memcpy(getOpaqueData(), Other.getOpaqueData(), Size); + copy(Other); } /// Copies the other type loc into this one. @@ -206,6 +213,7 @@ private: /// \brief Return the TypeLoc for a type source info. inline TypeLoc TypeSourceInfo::getTypeLoc() const { + // TODO: is this alignment already sufficient? return TypeLoc(Ty, const_cast<void*>(static_cast<const void*>(this + 1))); } @@ -736,6 +744,10 @@ public: return hasAttrExprOperand() || hasAttrEnumOperand(); } + bool isQualifier() const { + return getTypePtr()->isQualifier(); + } + /// The modified type, which is generally canonically different from /// the attribute type. /// int main(int, char**) __attribute__((noreturn)) diff --git a/contrib/llvm/tools/clang/include/clang/AST/VTableBuilder.h b/contrib/llvm/tools/clang/include/clang/AST/VTableBuilder.h index ebfbb8a..481fd11 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/VTableBuilder.h +++ b/contrib/llvm/tools/clang/include/clang/AST/VTableBuilder.h @@ -51,7 +51,7 @@ public: CK_UnusedFunctionPointer }; - VTableComponent() { } + VTableComponent() = default; static VTableComponent MakeVCallOffset(CharUnits Offset) { return VTableComponent(CK_VCallOffset, Offset); @@ -122,31 +122,56 @@ public: } const CXXRecordDecl *getRTTIDecl() const { - assert(getKind() == CK_RTTI && "Invalid component kind!"); - + assert(isRTTIKind() && "Invalid component kind!"); return reinterpret_cast<CXXRecordDecl *>(getPointer()); } const CXXMethodDecl *getFunctionDecl() const { - assert(getKind() == CK_FunctionPointer); - + assert(isFunctionPointerKind() && "Invalid component kind!"); + if (isDestructorKind()) + return getDestructorDecl(); return reinterpret_cast<CXXMethodDecl *>(getPointer()); } const CXXDestructorDecl *getDestructorDecl() const { - assert((getKind() == CK_CompleteDtorPointer || - getKind() == CK_DeletingDtorPointer) && "Invalid component kind!"); - + assert(isDestructorKind() && "Invalid component kind!"); return reinterpret_cast<CXXDestructorDecl *>(getPointer()); } const CXXMethodDecl *getUnusedFunctionDecl() const { - assert(getKind() == CK_UnusedFunctionPointer); - + assert(getKind() == CK_UnusedFunctionPointer && "Invalid component kind!"); return reinterpret_cast<CXXMethodDecl *>(getPointer()); } + bool isDestructorKind() const { return isDestructorKind(getKind()); } + + bool isUsedFunctionPointerKind() const { + return isUsedFunctionPointerKind(getKind()); + } + + bool isFunctionPointerKind() const { + return isFunctionPointerKind(getKind()); + } + + bool isRTTIKind() const { return isRTTIKind(getKind()); } + private: + static bool isFunctionPointerKind(Kind ComponentKind) { + return isUsedFunctionPointerKind(ComponentKind) || + ComponentKind == CK_UnusedFunctionPointer; + } + static bool isUsedFunctionPointerKind(Kind ComponentKind) { + return ComponentKind == CK_FunctionPointer || + isDestructorKind(ComponentKind); + } + static bool isDestructorKind(Kind ComponentKind) { + return ComponentKind == CK_CompleteDtorPointer || + ComponentKind == CK_DeletingDtorPointer; + } + static bool isRTTIKind(Kind ComponentKind) { + return ComponentKind == CK_RTTI; + } + VTableComponent(Kind ComponentKind, CharUnits Offset) { assert((ComponentKind == CK_VCallOffset || ComponentKind == CK_VBaseOffset || @@ -158,12 +183,8 @@ private: } VTableComponent(Kind ComponentKind, uintptr_t Ptr) { - assert((ComponentKind == CK_RTTI || - ComponentKind == CK_FunctionPointer || - ComponentKind == CK_CompleteDtorPointer || - ComponentKind == CK_DeletingDtorPointer || - ComponentKind == CK_UnusedFunctionPointer) && - "Invalid component kind!"); + assert((isRTTIKind(ComponentKind) || isFunctionPointerKind(ComponentKind)) && + "Invalid component kind!"); assert((Ptr & 7) == 0 && "Pointer not sufficiently aligned!"); @@ -178,11 +199,7 @@ private: } uintptr_t getPointer() const { - assert((getKind() == CK_RTTI || - getKind() == CK_FunctionPointer || - getKind() == CK_CompleteDtorPointer || - getKind() == CK_DeletingDtorPointer || - getKind() == CK_UnusedFunctionPointer) && + assert((getKind() == CK_RTTI || isFunctionPointerKind()) && "Invalid component kind!"); return static_cast<uintptr_t>(Value & ~7ULL); @@ -205,8 +222,11 @@ public: typedef const VTableComponent *vtable_component_iterator; typedef const VTableThunkTy *vtable_thunk_iterator; + typedef llvm::iterator_range<vtable_component_iterator> + vtable_component_range; typedef llvm::DenseMap<BaseSubobject, uint64_t> AddressPointsMapTy; + private: uint64_t NumVTableComponents; std::unique_ptr<VTableComponent[]> VTableComponents; @@ -233,6 +253,11 @@ public: return NumVTableComponents; } + vtable_component_range vtable_components() const { + return vtable_component_range(vtable_component_begin(), + vtable_component_end()); + } + vtable_component_iterator vtable_component_begin() const { return VTableComponents.get(); } @@ -376,10 +401,6 @@ struct VPtrInfo { VPtrInfo(const CXXRecordDecl *RD) : ReusingBase(RD), BaseWithVPtr(RD), NextBaseToMangle(RD) {} - // Copy constructor. - // FIXME: Uncomment when we've moved to C++11. - // VPtrInfo(const VPtrInfo &) = default; - /// The vtable will hold all of the virtual bases or virtual methods of /// ReusingBase. This may or may not be the same class as VPtrSubobject.Base. /// A derived class will reuse the vptr of the first non-virtual base diff --git a/contrib/llvm/tools/clang/include/clang/ASTMatchers/ASTMatchFinder.h b/contrib/llvm/tools/clang/include/clang/ASTMatchers/ASTMatchFinder.h index ce2674e..92ec92c 100644 --- a/contrib/llvm/tools/clang/include/clang/ASTMatchers/ASTMatchFinder.h +++ b/contrib/llvm/tools/clang/include/clang/ASTMatchers/ASTMatchFinder.h @@ -42,6 +42,7 @@ #define LLVM_CLANG_ASTMATCHERS_ASTMATCHFINDER_H #include "clang/ASTMatchers/ASTMatchers.h" +#include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/StringMap.h" #include "llvm/Support/Timer.h" @@ -208,7 +209,7 @@ public: NestedNameSpecifierLoc; std::vector<std::pair<TypeLocMatcher, MatchCallback *>> TypeLoc; /// \brief All the callbacks in one container to simplify iteration. - std::vector<MatchCallback *> AllCallbacks; + llvm::SmallPtrSet<MatchCallback *, 16> AllCallbacks; }; private: diff --git a/contrib/llvm/tools/clang/include/clang/ASTMatchers/ASTMatchers.h b/contrib/llvm/tools/clang/include/clang/ASTMatchers/ASTMatchers.h index 281d637..e6ba877 100644 --- a/contrib/llvm/tools/clang/include/clang/ASTMatchers/ASTMatchers.h +++ b/contrib/llvm/tools/clang/include/clang/ASTMatchers/ASTMatchers.h @@ -14,7 +14,7 @@ // a functional in-language DSL to express queries over the C++ AST. // // For example, to match a class with a certain name, one would call: -// recordDecl(hasName("MyClass")) +// cxxRecordDecl(hasName("MyClass")) // which returns a matcher that can be used to find all AST nodes that declare // a class named 'MyClass'. // @@ -25,13 +25,13 @@ // // For example, when we're interested in child classes of a certain class, we // would write: -// recordDecl(hasName("MyClass"), hasChild(id("child", recordDecl()))) +// cxxRecordDecl(hasName("MyClass"), hasChild(id("child", recordDecl()))) // When the match is found via the MatchFinder, a user provided callback will // be called with a BoundNodes instance that contains a mapping from the // strings that we provided for the id(...) calls to the nodes that were // matched. // In the given example, each time our matcher finds a match we get a callback -// where "child" is bound to the CXXRecordDecl node of the matching child +// where "child" is bound to the RecordDecl node of the matching child // class declaration. // // See ASTMatchersInternal.h for a more in-depth explanation of the @@ -170,7 +170,8 @@ const internal::VariadicDynCastAllOfMatcher<Decl, TypedefDecl> typedefDecl; /// \brief Matches AST nodes that were expanded within the main-file. /// -/// Example matches X but not Y (matcher = recordDecl(isExpansionInMainFile()) +/// Example matches X but not Y +/// (matcher = cxxRecordDecl(isExpansionInMainFile()) /// \code /// #include <Y.h> /// class X {}; @@ -191,7 +192,7 @@ AST_POLYMORPHIC_MATCHER(isExpansionInMainFile, /// \brief Matches AST nodes that were expanded within system-header-files. /// /// Example matches Y but not X -/// (matcher = recordDecl(isExpansionInSystemHeader()) +/// (matcher = cxxRecordDecl(isExpansionInSystemHeader()) /// \code /// #include <SystemHeader.h> /// class X {}; @@ -216,7 +217,7 @@ AST_POLYMORPHIC_MATCHER(isExpansionInSystemHeader, /// partially matching a given regex. /// /// Example matches Y but not X -/// (matcher = recordDecl(isExpansionInFileMatching("AST.*")) +/// (matcher = cxxRecordDecl(isExpansionInFileMatching("AST.*")) /// \code /// #include "ASTMatcher.h" /// class X {}; @@ -292,6 +293,31 @@ const internal::VariadicDynCastAllOfMatcher<Decl, NamedDecl> namedDecl; /// matches "namespace {}" and "namespace test {}" const internal::VariadicDynCastAllOfMatcher<Decl, NamespaceDecl> namespaceDecl; +/// \brief Matches a declaration of a namespace alias. +/// +/// Given +/// \code +/// namespace test {} +/// namespace alias = ::test; +/// \endcode +/// namespaceAliasDecl() +/// matches "namespace alias" but not "namespace test" +const internal::VariadicDynCastAllOfMatcher<Decl, NamespaceAliasDecl> + namespaceAliasDecl; + +/// \brief Matches class, struct, and union declarations. +/// +/// Example matches \c X, \c Z, \c U, and \c S +/// \code +/// class X; +/// template<class T> class Z {}; +/// struct S {}; +/// union U {}; +/// \endcode +const internal::VariadicDynCastAllOfMatcher< + Decl, + RecordDecl> recordDecl; + /// \brief Matches C++ class declarations. /// /// Example matches \c X, \c Z @@ -301,7 +327,7 @@ const internal::VariadicDynCastAllOfMatcher<Decl, NamespaceDecl> namespaceDecl; /// \endcode const internal::VariadicDynCastAllOfMatcher< Decl, - CXXRecordDecl> recordDecl; + CXXRecordDecl> cxxRecordDecl; /// \brief Matches C++ class template declarations. /// @@ -373,7 +399,7 @@ const internal::VariadicDynCastAllOfMatcher< /// int i; /// }; /// \endcode -const internal::VariadicAllOfMatcher<CXXCtorInitializer> ctorInitializer; +const internal::VariadicAllOfMatcher<CXXCtorInitializer> cxxCtorInitializer; /// \brief Matches template arguments. /// @@ -386,6 +412,30 @@ const internal::VariadicAllOfMatcher<CXXCtorInitializer> ctorInitializer; /// matches 'int' in C<int>. const internal::VariadicAllOfMatcher<TemplateArgument> templateArgument; +/// \brief Matches non-type template parameter declarations. +/// +/// Given +/// \code +/// template <typename T, int N> struct C {}; +/// \endcode +/// nonTypeTemplateParmDecl() +/// matches 'N', but not 'T'. +const internal::VariadicDynCastAllOfMatcher< + Decl, + NonTypeTemplateParmDecl> nonTypeTemplateParmDecl; + +/// \brief Matches template type parameter declarations. +/// +/// Given +/// \code +/// template <typename T, int N> struct C {}; +/// \endcode +/// templateTypeParmDecl() +/// matches 'T', but not 'N'. +const internal::VariadicDynCastAllOfMatcher< + Decl, + TemplateTypeParmDecl> templateTypeParmDecl; + /// \brief Matches public C++ declarations. /// /// Given @@ -712,7 +762,7 @@ const internal::VariadicDynCastAllOfMatcher<Decl, ValueDecl> valueDecl; /// \endcode const internal::VariadicDynCastAllOfMatcher< Decl, - CXXConstructorDecl> constructorDecl; + CXXConstructorDecl> cxxConstructorDecl; /// \brief Matches explicit C++ destructor declarations. /// @@ -725,7 +775,7 @@ const internal::VariadicDynCastAllOfMatcher< /// \endcode const internal::VariadicDynCastAllOfMatcher< Decl, - CXXDestructorDecl> destructorDecl; + CXXDestructorDecl> cxxDestructorDecl; /// \brief Matches enum declarations. /// @@ -755,7 +805,7 @@ const internal::VariadicDynCastAllOfMatcher< /// \code /// class X { void y(); }; /// \endcode -const internal::VariadicDynCastAllOfMatcher<Decl, CXXMethodDecl> methodDecl; +const internal::VariadicDynCastAllOfMatcher<Decl, CXXMethodDecl> cxxMethodDecl; /// \brief Matches conversion operator declarations. /// @@ -764,7 +814,7 @@ const internal::VariadicDynCastAllOfMatcher<Decl, CXXMethodDecl> methodDecl; /// class X { operator int() const; }; /// \endcode const internal::VariadicDynCastAllOfMatcher<Decl, CXXConversionDecl> - conversionDecl; + cxxConversionDecl; /// \brief Matches variable declarations. /// @@ -877,7 +927,7 @@ const internal::VariadicDynCastAllOfMatcher<Stmt, LambdaExpr> lambdaExpr; /// \endcode const internal::VariadicDynCastAllOfMatcher< Stmt, - CXXMemberCallExpr> memberCallExpr; + CXXMemberCallExpr> cxxMemberCallExpr; /// \brief Matches ObjectiveC Message invocation expressions. /// @@ -892,6 +942,16 @@ const internal::VariadicDynCastAllOfMatcher< Stmt, ObjCMessageExpr> objcMessageExpr; +/// \brief Matches Objective-C interface declarations. +/// +/// Example matches Foo +/// \code +/// @interface Foo +/// @end +/// \endcode +const internal::VariadicDynCastAllOfMatcher< + Decl, + ObjCInterfaceDecl> objcInterfaceDecl; /// \brief Matches expressions that introduce cleanups to be run at the end /// of the sub-expression's evaluation. @@ -900,8 +960,9 @@ const internal::VariadicDynCastAllOfMatcher< /// \code /// const std::string str = std::string(); /// \endcode -const internal::VariadicDynCastAllOfMatcher<Stmt, ExprWithCleanups> -exprWithCleanups; +const internal::VariadicDynCastAllOfMatcher< + Stmt, + ExprWithCleanups> exprWithCleanups; /// \brief Matches init list expressions. /// @@ -925,8 +986,9 @@ const internal::VariadicDynCastAllOfMatcher<Stmt, InitListExpr> initListExpr; /// \endcode /// substNonTypeTemplateParmExpr() /// matches "N" in the right-hand side of "static const int n = N;" -const internal::VariadicDynCastAllOfMatcher<Stmt, SubstNonTypeTemplateParmExpr> -substNonTypeTemplateParmExpr; +const internal::VariadicDynCastAllOfMatcher< + Stmt, + SubstNonTypeTemplateParmExpr> substNonTypeTemplateParmExpr; /// \brief Matches using declarations. /// @@ -948,8 +1010,9 @@ const internal::VariadicDynCastAllOfMatcher<Decl, UsingDecl> usingDecl; /// \endcode /// usingDirectiveDecl() /// matches \code using namespace X \endcode -const internal::VariadicDynCastAllOfMatcher<Decl, UsingDirectiveDecl> - usingDirectiveDecl; +const internal::VariadicDynCastAllOfMatcher< + Decl, + UsingDirectiveDecl> usingDirectiveDecl; /// \brief Matches unresolved using value declarations. /// @@ -966,10 +1029,29 @@ const internal::VariadicDynCastAllOfMatcher< Decl, UnresolvedUsingValueDecl> unresolvedUsingValueDecl; +/// \brief Matches unresolved using value declarations that involve the +/// typename. +/// +/// Given +/// \code +/// template <typename T> +/// struct Base { typedef T Foo; }; +/// +/// template<typename T> +/// struct S : private Base<T> { +/// using typename Base<T>::Foo; +/// }; +/// \endcode +/// unresolvedUsingTypenameDecl() +/// matches \code using Base<T>::Foo \endcode +const internal::VariadicDynCastAllOfMatcher< + Decl, + UnresolvedUsingTypenameDecl> unresolvedUsingTypenameDecl; + /// \brief Matches constructor call expressions (including implicit ones). /// /// Example matches string(ptr, n) and ptr within arguments of f -/// (matcher = constructExpr()) +/// (matcher = cxxConstructExpr()) /// \code /// void f(const string &a, const string &b); /// char *ptr; @@ -978,43 +1060,43 @@ const internal::VariadicDynCastAllOfMatcher< /// \endcode const internal::VariadicDynCastAllOfMatcher< Stmt, - CXXConstructExpr> constructExpr; + CXXConstructExpr> cxxConstructExpr; /// \brief Matches unresolved constructor call expressions. /// /// Example matches T(t) in return statement of f -/// (matcher = unresolvedConstructExpr()) +/// (matcher = cxxUnresolvedConstructExpr()) /// \code /// template <typename T> /// void f(const T& t) { return T(t); } /// \endcode const internal::VariadicDynCastAllOfMatcher< Stmt, - CXXUnresolvedConstructExpr> unresolvedConstructExpr; + CXXUnresolvedConstructExpr> cxxUnresolvedConstructExpr; /// \brief Matches implicit and explicit this expressions. /// /// Example matches the implicit this expression in "return i". -/// (matcher = thisExpr()) +/// (matcher = cxxThisExpr()) /// \code /// struct foo { /// int i; /// int f() { return i; } /// }; /// \endcode -const internal::VariadicDynCastAllOfMatcher<Stmt, CXXThisExpr> thisExpr; +const internal::VariadicDynCastAllOfMatcher<Stmt, CXXThisExpr> cxxThisExpr; /// \brief Matches nodes where temporaries are created. /// /// Example matches FunctionTakesString(GetStringByValue()) -/// (matcher = bindTemporaryExpr()) +/// (matcher = cxxBindTemporaryExpr()) /// \code /// FunctionTakesString(GetStringByValue()); /// FunctionTakesStringByPointer(GetStringPointer()); /// \endcode const internal::VariadicDynCastAllOfMatcher< Stmt, - CXXBindTemporaryExpr> bindTemporaryExpr; + CXXBindTemporaryExpr> cxxBindTemporaryExpr; /// \brief Matches nodes where temporaries are materialized. /// @@ -1044,9 +1126,9 @@ const internal::VariadicDynCastAllOfMatcher< /// \code /// new X; /// \endcode -/// newExpr() +/// cxxNewExpr() /// matches 'new X'. -const internal::VariadicDynCastAllOfMatcher<Stmt, CXXNewExpr> newExpr; +const internal::VariadicDynCastAllOfMatcher<Stmt, CXXNewExpr> cxxNewExpr; /// \brief Matches delete expressions. /// @@ -1054,9 +1136,9 @@ const internal::VariadicDynCastAllOfMatcher<Stmt, CXXNewExpr> newExpr; /// \code /// delete X; /// \endcode -/// deleteExpr() +/// cxxDeleteExpr() /// matches 'delete X'. -const internal::VariadicDynCastAllOfMatcher<Stmt, CXXDeleteExpr> deleteExpr; +const internal::VariadicDynCastAllOfMatcher<Stmt, CXXDeleteExpr> cxxDeleteExpr; /// \brief Matches array subscript expressions. /// @@ -1074,14 +1156,14 @@ const internal::VariadicDynCastAllOfMatcher< /// /// Example matches the CXXDefaultArgExpr placeholder inserted for the /// default value of the second parameter in the call expression f(42) -/// (matcher = defaultArgExpr()) +/// (matcher = cxxDefaultArgExpr()) /// \code /// void f(int x, int y = 0); /// f(42); /// \endcode const internal::VariadicDynCastAllOfMatcher< Stmt, - CXXDefaultArgExpr> defaultArgExpr; + CXXDefaultArgExpr> cxxDefaultArgExpr; /// \brief Matches overloaded operator calls. /// @@ -1091,7 +1173,7 @@ const internal::VariadicDynCastAllOfMatcher< /// FIXME: figure out why these do not match? /// /// Example matches both operator<<((o << b), c) and operator<<(o, b) -/// (matcher = operatorCallExpr()) +/// (matcher = cxxOperatorCallExpr()) /// \code /// ostream &operator<< (ostream &out, int i) { }; /// ostream &o; int b = 1, c = 1; @@ -1099,7 +1181,7 @@ const internal::VariadicDynCastAllOfMatcher< /// \endcode const internal::VariadicDynCastAllOfMatcher< Stmt, - CXXOperatorCallExpr> operatorCallExpr; + CXXOperatorCallExpr> cxxOperatorCallExpr; /// \brief Matches expressions. /// @@ -1166,12 +1248,14 @@ AST_MATCHER_P(ForStmt, hasLoopInit, internal::Matcher<Stmt>, /// \brief Matches range-based for statements. /// -/// forRangeStmt() matches 'for (auto a : i)' +/// cxxForRangeStmt() matches 'for (auto a : i)' /// \code /// int i[] = {1, 2, 3}; for (auto a : i); /// for(int j = 0; j < 5; ++j); /// \endcode -const internal::VariadicDynCastAllOfMatcher<Stmt, CXXForRangeStmt> forRangeStmt; +const internal::VariadicDynCastAllOfMatcher< + Stmt, + CXXForRangeStmt> cxxForRangeStmt; /// \brief Matches the initialization statement of a for loop. /// @@ -1326,27 +1410,27 @@ const internal::VariadicDynCastAllOfMatcher<Stmt, CompoundStmt> compoundStmt; /// \code /// try {} catch(int i) {} /// \endcode -/// catchStmt() +/// cxxCatchStmt() /// matches 'catch(int i)' -const internal::VariadicDynCastAllOfMatcher<Stmt, CXXCatchStmt> catchStmt; +const internal::VariadicDynCastAllOfMatcher<Stmt, CXXCatchStmt> cxxCatchStmt; /// \brief Matches try statements. /// /// \code /// try {} catch(int i) {} /// \endcode -/// tryStmt() +/// cxxTryStmt() /// matches 'try {}' -const internal::VariadicDynCastAllOfMatcher<Stmt, CXXTryStmt> tryStmt; +const internal::VariadicDynCastAllOfMatcher<Stmt, CXXTryStmt> cxxTryStmt; /// \brief Matches throw expressions. /// /// \code /// try { throw 5; } catch(int i) {} /// \endcode -/// throwExpr() +/// cxxThrowExpr() /// matches 'throw 5' -const internal::VariadicDynCastAllOfMatcher<Stmt, CXXThrowExpr> throwExpr; +const internal::VariadicDynCastAllOfMatcher<Stmt, CXXThrowExpr> cxxThrowExpr; /// \brief Matches null statements. /// @@ -1375,7 +1459,7 @@ const internal::VariadicDynCastAllOfMatcher<Stmt, AsmStmt> asmStmt; /// \endcode const internal::VariadicDynCastAllOfMatcher< Stmt, - CXXBoolLiteralExpr> boolLiteral; + CXXBoolLiteralExpr> cxxBoolLiteral; /// \brief Matches string literals (also matches wide string literals). /// @@ -1439,7 +1523,7 @@ const internal::VariadicDynCastAllOfMatcher< /// \brief Matches nullptr literal. const internal::VariadicDynCastAllOfMatcher< Stmt, - CXXNullPtrLiteralExpr> nullPtrLiteralExpr; + CXXNullPtrLiteralExpr> cxxNullPtrLiteralExpr; /// \brief Matches GNU __null expression. const internal::VariadicDynCastAllOfMatcher< @@ -1505,7 +1589,7 @@ const internal::VariadicDynCastAllOfMatcher< /// \endcode const internal::VariadicDynCastAllOfMatcher< Stmt, - CXXReinterpretCastExpr> reinterpretCastExpr; + CXXReinterpretCastExpr> cxxReinterpretCastExpr; /// \brief Matches a C++ static_cast expression. /// @@ -1513,7 +1597,7 @@ const internal::VariadicDynCastAllOfMatcher< /// \see reinterpretCast /// /// Example: -/// staticCastExpr() +/// cxxStaticCastExpr() /// matches /// static_cast<long>(8) /// in @@ -1522,12 +1606,12 @@ const internal::VariadicDynCastAllOfMatcher< /// \endcode const internal::VariadicDynCastAllOfMatcher< Stmt, - CXXStaticCastExpr> staticCastExpr; + CXXStaticCastExpr> cxxStaticCastExpr; /// \brief Matches a dynamic_cast expression. /// /// Example: -/// dynamicCastExpr() +/// cxxDynamicCastExpr() /// matches /// dynamic_cast<D*>(&b); /// in @@ -1538,7 +1622,7 @@ const internal::VariadicDynCastAllOfMatcher< /// \endcode const internal::VariadicDynCastAllOfMatcher< Stmt, - CXXDynamicCastExpr> dynamicCastExpr; + CXXDynamicCastExpr> cxxDynamicCastExpr; /// \brief Matches a const_cast expression. /// @@ -1550,7 +1634,7 @@ const internal::VariadicDynCastAllOfMatcher< /// \endcode const internal::VariadicDynCastAllOfMatcher< Stmt, - CXXConstCastExpr> constCastExpr; + CXXConstCastExpr> cxxConstCastExpr; /// \brief Matches a C-style cast expression. /// @@ -1620,7 +1704,7 @@ const internal::VariadicDynCastAllOfMatcher<Stmt, CastExpr> castExpr; /// \endcode const internal::VariadicDynCastAllOfMatcher< Stmt, - CXXFunctionalCastExpr> functionalCastExpr; + CXXFunctionalCastExpr> cxxFunctionalCastExpr; /// \brief Matches functional cast expressions having N != 1 arguments /// @@ -1630,7 +1714,7 @@ const internal::VariadicDynCastAllOfMatcher< /// \endcode const internal::VariadicDynCastAllOfMatcher< Stmt, - CXXTemporaryObjectExpr> temporaryObjectExpr; + CXXTemporaryObjectExpr> cxxTemporaryObjectExpr; /// \brief Matches \c QualTypes in the clang AST. const internal::VariadicAllOfMatcher<QualType> qualType; @@ -1652,8 +1736,8 @@ const internal::VariadicAllOfMatcher<TypeLoc> typeLoc; /// \endcode /// The matcher: /// \code -/// recordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")), -/// has(fieldDecl(hasName("b")).bind("v")))) +/// cxxRecordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")), +/// has(fieldDecl(hasName("b")).bind("v")))) /// \endcode /// will generate two results binding "v", the first of which binds /// the field declaration of \c a, the second the field declaration of @@ -1789,9 +1873,10 @@ AST_MATCHER_P(NamedDecl, matchesName, std::string, RegExp) { /// a << a; // <-- This matches /// \endcode /// -/// \c operatorCallExpr(hasOverloadedOperatorName("<<"))) matches the specified -/// line and \c recordDecl(hasMethod(hasOverloadedOperatorName("*"))) matches -/// the declaration of \c A. +/// \c cxxOperatorCallExpr(hasOverloadedOperatorName("<<"))) matches the +/// specified line and +/// \c cxxRecordDecl(hasMethod(hasOverloadedOperatorName("*"))) +/// matches the declaration of \c A. /// /// Usable as: Matcher<CXXOperatorCallExpr>, Matcher<FunctionDecl> inline internal::PolymorphicMatcherWithParam1< @@ -1858,10 +1943,10 @@ AST_MATCHER_P_OVERLOAD(CXXRecordDecl, isSameOrDerivedFrom, std::string, /// \code /// class A { void func(); }; /// class B { void member(); }; -/// \code +/// \endcode /// -/// \c recordDecl(hasMethod(hasName("func"))) matches the declaration of \c A -/// but not \c B. +/// \c cxxRecordDecl(hasMethod(hasName("func"))) matches the declaration of +/// \c A but not \c B. AST_MATCHER_P(CXXRecordDecl, hasMethod, internal::Matcher<CXXMethodDecl>, InnerMatcher) { return matchesFirstInPointerRange(InnerMatcher, Node.method_begin(), @@ -1871,7 +1956,8 @@ AST_MATCHER_P(CXXRecordDecl, hasMethod, internal::Matcher<CXXMethodDecl>, /// \brief Matches AST nodes that have child AST nodes that match the /// provided matcher. /// -/// Example matches X, Y (matcher = recordDecl(has(recordDecl(hasName("X"))) +/// Example matches X, Y +/// (matcher = cxxRecordDecl(has(cxxRecordDecl(hasName("X"))) /// \code /// class X {}; // Matches X, because X::X is a class of name X inside X. /// class Y { class X {}; }; @@ -1888,7 +1974,7 @@ LLVM_ATTRIBUTE_UNUSED has = {}; /// provided matcher. /// /// Example matches X, Y, Z -/// (matcher = recordDecl(hasDescendant(recordDecl(hasName("X"))))) +/// (matcher = cxxRecordDecl(hasDescendant(cxxRecordDecl(hasName("X"))))) /// \code /// class X {}; // Matches X, because X::X is a class of name X inside X. /// class Y { class X {}; }; @@ -1904,7 +1990,8 @@ LLVM_ATTRIBUTE_UNUSED hasDescendant = {}; /// \brief Matches AST nodes that have child AST nodes that match the /// provided matcher. /// -/// Example matches X, Y (matcher = recordDecl(forEach(recordDecl(hasName("X"))) +/// Example matches X, Y +/// (matcher = cxxRecordDecl(forEach(cxxRecordDecl(hasName("X"))) /// \code /// class X {}; // Matches X, because X::X is a class of name X inside X. /// class Y { class X {}; }; @@ -1924,7 +2011,7 @@ LLVM_ATTRIBUTE_UNUSED forEach = {}; /// provided matcher. /// /// Example matches X, A, B, C -/// (matcher = recordDecl(forEachDescendant(recordDecl(hasName("X"))))) +/// (matcher = cxxRecordDecl(forEachDescendant(cxxRecordDecl(hasName("X"))))) /// \code /// class X {}; // Matches X, because X::X is a class of name X inside X. /// class A { class X {}; }; @@ -1937,7 +2024,9 @@ LLVM_ATTRIBUTE_UNUSED forEach = {}; /// each result that matches instead of only on the first one. /// /// Note: Recursively combined ForEachDescendant can cause many matches: -/// recordDecl(forEachDescendant(recordDecl(forEachDescendant(recordDecl())))) +/// cxxRecordDecl(forEachDescendant(cxxRecordDecl( +/// forEachDescendant(cxxRecordDecl()) +/// ))) /// will match 10 times (plus injected class name matches) on: /// \code /// class A { class B { class C { class D { class E {}; }; }; }; }; @@ -1957,7 +2046,8 @@ LLVM_ATTRIBUTE_UNUSED forEachDescendant = {}; /// \endcode /// The matcher: /// \code -/// recordDecl(hasName("::A"), findAll(recordDecl(isDefinition()).bind("m"))) +/// cxxRecordDecl(hasName("::A"), +/// findAll(cxxRecordDecl(isDefinition()).bind("m"))) /// \endcode /// will generate results for \c A, \c B and \c C. /// @@ -1978,8 +2068,10 @@ internal::Matcher<T> findAll(const internal::Matcher<T> &Matcher) { /// /// Usable as: Any Matcher const internal::ArgumentAdaptingMatcherFunc< - internal::HasParentMatcher, internal::TypeList<Decl, Stmt>, - internal::TypeList<Decl, Stmt> > LLVM_ATTRIBUTE_UNUSED hasParent = {}; + internal::HasParentMatcher, + internal::TypeList<Decl, NestedNameSpecifierLoc, Stmt, TypeLoc>, + internal::TypeList<Decl, NestedNameSpecifierLoc, Stmt, TypeLoc>> + LLVM_ATTRIBUTE_UNUSED hasParent = {}; /// \brief Matches AST nodes that have an ancestor that matches the provided /// matcher. @@ -1993,12 +2085,14 @@ const internal::ArgumentAdaptingMatcherFunc< /// /// Usable as: Any Matcher const internal::ArgumentAdaptingMatcherFunc< - internal::HasAncestorMatcher, internal::TypeList<Decl, Stmt>, - internal::TypeList<Decl, Stmt> > LLVM_ATTRIBUTE_UNUSED hasAncestor = {}; + internal::HasAncestorMatcher, + internal::TypeList<Decl, NestedNameSpecifierLoc, Stmt, TypeLoc>, + internal::TypeList<Decl, NestedNameSpecifierLoc, Stmt, TypeLoc>> + LLVM_ATTRIBUTE_UNUSED hasAncestor = {}; /// \brief Matches if the provided matcher does not match. /// -/// Example matches Y (matcher = recordDecl(unless(hasName("X")))) +/// Example matches Y (matcher = cxxRecordDecl(unless(hasName("X")))) /// \code /// class X {}; /// class Y {}; @@ -2038,7 +2132,8 @@ hasDeclaration(const internal::Matcher<Decl> &InnerMatcher) { /// \brief Matches on the implicit object argument of a member call expression. /// -/// Example matches y.x() (matcher = callExpr(on(hasType(recordDecl(hasName("Y")))))) +/// Example matches y.x() +/// (matcher = cxxMemberCallExpr(on(hasType(cxxRecordDecl(hasName("Y")))))) /// \code /// class Y { public: void x(); }; /// void z() { Y y; y.x(); }", @@ -2078,7 +2173,7 @@ AST_MATCHER_P(ObjCMessageExpr, hasReceiverType, internal::Matcher<QualType>, /// \code /// [self.bodyView loadHTMLString:html baseURL:NULL]; /// \endcode - AST_MATCHER_P(ObjCMessageExpr, hasSelector, std::string, BaseName) { +AST_MATCHER_P(ObjCMessageExpr, hasSelector, std::string, BaseName) { Selector Sel = Node.getSelector(); return BaseName.compare(Sel.getAsString()) == 0; } @@ -2131,14 +2226,13 @@ AST_MATCHER(ObjCMessageExpr, hasUnarySelector) { /// webView.frame = bodyFrame; /// // ^---- matches here /// \endcode - AST_MATCHER(ObjCMessageExpr, hasKeywordSelector) { return Node.getSelector().isKeywordSelector(); } /// \brief Matches when the selector has the specified number of arguments /// -/// matcher = objCMessageExpr(numSelectorArgs(1)); +/// matcher = objCMessageExpr(numSelectorArgs(0)); /// matches self.bodyView in the code below /// /// matcher = objCMessageExpr(numSelectorArgs(2)); @@ -2177,7 +2271,8 @@ AST_MATCHER_P(CallExpr, callee, internal::Matcher<Stmt>, /// \brief Matches if the call expression's callee's declaration matches the /// given matcher. /// -/// Example matches y.x() (matcher = callExpr(callee(methodDecl(hasName("x"))))) +/// Example matches y.x() (matcher = callExpr(callee( +/// cxxMethodDecl(hasName("x"))))) /// \code /// class Y { public: void x(); }; /// void z() { Y y; y.x(); } @@ -2190,8 +2285,8 @@ AST_MATCHER_P_OVERLOAD(CallExpr, callee, internal::Matcher<Decl>, InnerMatcher, /// \brief Matches if the expression's or declaration's type matches a type /// matcher. /// -/// Example matches x (matcher = expr(hasType(recordDecl(hasName("X"))))) -/// and z (matcher = varDecl(hasType(recordDecl(hasName("X"))))) +/// Example matches x (matcher = expr(hasType(cxxRecordDecl(hasName("X"))))) +/// and z (matcher = varDecl(hasType(cxxRecordDecl(hasName("X"))))) /// \code /// class X {}; /// void y(X &x) { x; X z; } @@ -2207,12 +2302,12 @@ AST_POLYMORPHIC_MATCHER_P_OVERLOAD( /// /// In case of a value declaration (for example a variable declaration), /// this resolves one layer of indirection. For example, in the value -/// declaration "X x;", recordDecl(hasName("X")) matches the declaration of X, -/// while varDecl(hasType(recordDecl(hasName("X")))) matches the declaration -/// of x." +/// declaration "X x;", cxxRecordDecl(hasName("X")) matches the declaration of +/// X, while varDecl(hasType(cxxRecordDecl(hasName("X")))) matches the +/// declaration of x. /// -/// Example matches x (matcher = expr(hasType(recordDecl(hasName("X"))))) -/// and z (matcher = varDecl(hasType(recordDecl(hasName("X"))))) +/// Example matches x (matcher = expr(hasType(cxxRecordDecl(hasName("X"))))) +/// and z (matcher = varDecl(hasType(cxxRecordDecl(hasName("X"))))) /// \code /// class X {}; /// void y(X &x) { x; X z; } @@ -2250,7 +2345,7 @@ AST_MATCHER_P(DeclaratorDecl, hasTypeLoc, internal::Matcher<TypeLoc>, Inner) { /// class Y { public: void x(); }; /// void z() { Y* y; y->x(); } /// \endcode -/// callExpr(on(hasType(asString("class Y *")))) +/// cxxMemberCallExpr(on(hasType(asString("class Y *")))) /// matches y->x() AST_MATCHER_P(QualType, asString, std::string, Name) { return Name == Node.getAsString(); @@ -2260,7 +2355,8 @@ AST_MATCHER_P(QualType, asString, std::string, Name) { /// matches the specified matcher. /// /// Example matches y->x() -/// (matcher = callExpr(on(hasType(pointsTo(recordDecl(hasName("Y"))))))) +/// (matcher = cxxMemberCallExpr(on(hasType(pointsTo +/// cxxRecordDecl(hasName("Y"))))))) /// \code /// class Y { public: void x(); }; /// void z() { Y *y; y->x(); } @@ -2268,7 +2364,7 @@ AST_MATCHER_P(QualType, asString, std::string, Name) { AST_MATCHER_P( QualType, pointsTo, internal::Matcher<QualType>, InnerMatcher) { - return (!Node.isNull() && Node->isPointerType() && + return (!Node.isNull() && Node->isAnyPointerType() && InnerMatcher.matches(Node->getPointeeType(), Finder, Builder)); } @@ -2283,7 +2379,7 @@ AST_MATCHER_P_OVERLOAD(QualType, pointsTo, internal::Matcher<Decl>, /// type matches the specified matcher. /// /// Example matches X &x and const X &y -/// (matcher = varDecl(hasType(references(recordDecl(hasName("X")))))) +/// (matcher = varDecl(hasType(references(cxxRecordDecl(hasName("X")))))) /// \code /// class X { /// void a(X b) { @@ -2305,7 +2401,7 @@ AST_MATCHER_P(QualType, references, internal::Matcher<QualType>, /// typedef int &int_ref; /// int a; /// int_ref b = a; -/// \code +/// \endcode /// /// \c varDecl(hasType(qualType(referenceType()))))) will not match the /// declaration of b but \c @@ -2367,8 +2463,6 @@ AST_MATCHER_P(DeclRefExpr, to, internal::Matcher<Decl>, /// \brief Matches a \c DeclRefExpr that refers to a declaration through a /// specific using shadow declaration. /// -/// FIXME: This currently only works for functions. Fix. -/// /// Given /// \code /// namespace a { void f() {} } @@ -2378,7 +2472,7 @@ AST_MATCHER_P(DeclRefExpr, to, internal::Matcher<Decl>, /// a::f(); // .. but not this. /// } /// \endcode -/// declRefExpr(throughUsingDeclaration(anything())) +/// declRefExpr(throughUsingDecl(anything())) /// matches \c f() AST_MATCHER_P(DeclRefExpr, throughUsingDecl, internal::Matcher<UsingShadowDecl>, InnerMatcher) { @@ -2450,6 +2544,69 @@ AST_MATCHER(VarDecl, hasGlobalStorage) { return Node.hasGlobalStorage(); } +/// \brief Matches a variable declaration that has automatic storage duration. +/// +/// Example matches x, but not y, z, or a. +/// (matcher = varDecl(hasAutomaticStorageDuration()) +/// \code +/// void f() { +/// int x; +/// static int y; +/// thread_local int z; +/// } +/// int a; +/// \endcode +AST_MATCHER(VarDecl, hasAutomaticStorageDuration) { + return Node.getStorageDuration() == SD_Automatic; +} + +/// \brief Matches a variable declaration that has static storage duration. +/// +/// Example matches y and a, but not x or z. +/// (matcher = varDecl(hasStaticStorageDuration()) +/// \code +/// void f() { +/// int x; +/// static int y; +/// thread_local int z; +/// } +/// int a; +/// \endcode +AST_MATCHER(VarDecl, hasStaticStorageDuration) { + return Node.getStorageDuration() == SD_Static; +} + +/// \brief Matches a variable declaration that has thread storage duration. +/// +/// Example matches z, but not x, z, or a. +/// (matcher = varDecl(hasThreadStorageDuration()) +/// \code +/// void f() { +/// int x; +/// static int y; +/// thread_local int z; +/// } +/// int a; +/// \endcode +AST_MATCHER(VarDecl, hasThreadStorageDuration) { + return Node.getStorageDuration() == SD_Thread; +} + +/// \brief Matches a variable declaration that is an exception variable from +/// a C++ catch block, or an Objective-C \@catch statement. +/// +/// Example matches x (matcher = varDecl(isExceptionVariable()) +/// \code +/// void f(int y) { +/// try { +/// } catch (int x) { +/// } +/// } +/// \endcode +AST_MATCHER(VarDecl, isExceptionVariable) { + return Node.isExceptionVariable(); +} + /// \brief Checks that a call expression or a constructor call expression has /// a specific number of arguments (including absent default arguments). /// @@ -2540,7 +2697,7 @@ AST_MATCHER_P2(DeclStmt, containsDeclaration, unsigned, N, /// // ... /// } /// /endcode -/// catchStmt(isCatchAll()) matches catch(...) but not catch(int). +/// cxxCatchStmt(isCatchAll()) matches catch(...) but not catch(int). AST_MATCHER(CXXCatchStmt, isCatchAll) { return Node.getExceptionDecl() == nullptr; } @@ -2554,7 +2711,9 @@ AST_MATCHER(CXXCatchStmt, isCatchAll) { /// int foo_; /// }; /// \endcode -/// recordDecl(has(constructorDecl(hasAnyConstructorInitializer(anything())))) +/// cxxRecordDecl(has(cxxConstructorDecl( +/// hasAnyConstructorInitializer(anything()) +/// ))) /// record matches Foo, hasAnyConstructorInitializer matches foo_(1) AST_MATCHER_P(CXXConstructorDecl, hasAnyConstructorInitializer, internal::Matcher<CXXCtorInitializer>, InnerMatcher) { @@ -2571,7 +2730,7 @@ AST_MATCHER_P(CXXConstructorDecl, hasAnyConstructorInitializer, /// int foo_; /// }; /// \endcode -/// recordDecl(has(constructorDecl(hasAnyConstructorInitializer( +/// cxxRecordDecl(has(cxxConstructorDecl(hasAnyConstructorInitializer( /// forField(hasName("foo_")))))) /// matches Foo /// with forField matching foo_ @@ -2591,7 +2750,7 @@ AST_MATCHER_P(CXXCtorInitializer, forField, /// int foo_; /// }; /// \endcode -/// recordDecl(has(constructorDecl(hasAnyConstructorInitializer( +/// cxxRecordDecl(has(cxxConstructorDecl(hasAnyConstructorInitializer( /// withInitializer(integerLiteral(equals(1))))))) /// matches Foo /// with withInitializer matching (1) @@ -2613,12 +2772,52 @@ AST_MATCHER_P(CXXCtorInitializer, withInitializer, /// string foo_; /// }; /// \endcode -/// constructorDecl(hasAnyConstructorInitializer(isWritten())) +/// cxxConstructorDecl(hasAnyConstructorInitializer(isWritten())) /// will match Foo(int), but not Foo() AST_MATCHER(CXXCtorInitializer, isWritten) { return Node.isWritten(); } +/// \brief Matches a constructor initializer if it is initializing a base, as +/// opposed to a member. +/// +/// Given +/// \code +/// struct B {}; +/// struct D : B { +/// int I; +/// D(int i) : I(i) {} +/// }; +/// struct E : B { +/// E() : B() {} +/// }; +/// \endcode +/// cxxConstructorDecl(hasAnyConstructorInitializer(isBaseInitializer())) +/// will match E(), but not match D(int). +AST_MATCHER(CXXCtorInitializer, isBaseInitializer) { + return Node.isBaseInitializer(); +} + +/// \brief Matches a constructor initializer if it is initializing a member, as +/// opposed to a base. +/// +/// Given +/// \code +/// struct B {}; +/// struct D : B { +/// int I; +/// D(int i) : I(i) {} +/// }; +/// struct E : B { +/// E() : B() {} +/// }; +/// \endcode +/// cxxConstructorDecl(hasAnyConstructorInitializer(isMemberInitializer())) +/// will match D(int), but not match E(). +AST_MATCHER(CXXCtorInitializer, isMemberInitializer) { + return Node.isMemberInitializer(); +} + /// \brief Matches any argument of a call expression or a constructor call /// expression. /// @@ -2660,7 +2859,7 @@ AST_MATCHER(CXXConstructExpr, isListInitialization) { /// \code /// class X { void f(int x) {} }; /// \endcode -/// methodDecl(hasParameter(0, hasType(varDecl()))) +/// cxxMethodDecl(hasParameter(0, hasType(varDecl()))) /// matches f(int x) {} /// with hasParameter(...) /// matching int x @@ -2680,7 +2879,7 @@ AST_MATCHER_P2(FunctionDecl, hasParameter, /// \code /// class X { void f(int x, int y, int z) {} }; /// \endcode -/// methodDecl(hasAnyParameter(hasName("y"))) +/// cxxMethodDecl(hasAnyParameter(hasName("y"))) /// matches f(int x, int y, int z) {} /// with hasAnyParameter(...) /// matching int y @@ -2709,7 +2908,7 @@ AST_MATCHER_P(FunctionDecl, parameterCountIs, unsigned, N) { /// \code /// class X { int f() { return 1; } }; /// \endcode -/// methodDecl(returns(asString("int"))) +/// cxxMethodDecl(returns(asString("int"))) /// matches int f() { return 1; } AST_MATCHER_P(FunctionDecl, returns, internal::Matcher<QualType>, InnerMatcher) { @@ -2743,6 +2942,34 @@ AST_MATCHER(FunctionDecl, isDeleted) { return Node.isDeleted(); } +/// \brief Matches functions that have a non-throwing exception specification. +/// +/// Given: +/// \code +/// void f(); +/// void g() noexcept; +/// void h() throw(); +/// 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>(); + + // 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 + // specification). + if (!FnTy) + return false; + + // Assume the best for any unresolved exception specification. + if (isUnresolvedExceptionSpec(FnTy->getExceptionSpecType())) + return true; + + return FnTy->isNothrow(Node.getASTContext()); +} + /// \brief Matches constexpr variable and function declarations. /// /// Given: @@ -2763,7 +2990,7 @@ AST_POLYMORPHIC_MATCHER(isConstexpr, /// \brief Matches the condition expression of an if statement, for loop, /// or conditional operator. /// -/// Example matches true (matcher = hasCondition(boolLiteral(equals(true)))) +/// Example matches true (matcher = hasCondition(cxxBoolLiteral(equals(true)))) /// \code /// if (true) {} /// \endcode @@ -2780,7 +3007,7 @@ AST_POLYMORPHIC_MATCHER_P(hasCondition, /// \brief Matches the then-statement of an if statement. /// /// Examples matches the if statement -/// (matcher = ifStmt(hasThen(boolLiteral(equals(true))))) +/// (matcher = ifStmt(hasThen(cxxBoolLiteral(equals(true))))) /// \code /// if (false) true; else false; /// \endcode @@ -2792,7 +3019,7 @@ AST_MATCHER_P(IfStmt, hasThen, internal::Matcher<Stmt>, InnerMatcher) { /// \brief Matches the else-statement of an if statement. /// /// Examples matches the if statement -/// (matcher = ifStmt(hasElse(boolLiteral(equals(true))))) +/// (matcher = ifStmt(hasElse(cxxBoolLiteral(equals(true))))) /// \code /// if (false) false; else true; /// \endcode @@ -2809,7 +3036,7 @@ AST_MATCHER_P(IfStmt, hasElse, internal::Matcher<Stmt>, InnerMatcher) { /// \code /// class X { int a; int b; }; /// \endcode -/// recordDecl( +/// cxxRecordDecl( /// has(fieldDecl(hasName("a"), hasType(type().bind("t")))), /// has(fieldDecl(hasName("b"), hasType(type(equalsBoundNode("t")))))) /// matches the class \c X, as \c a and \c b have the same type. @@ -2941,7 +3168,7 @@ AST_MATCHER_P(CompoundStmt, statementCountIs, unsigned, N) { /// \brief Matches literals that are equal to the given value. /// -/// Example matches true (matcher = boolLiteral(equals(true))) +/// Example matches true (matcher = cxxBoolLiteral(equals(true))) /// \code /// true /// \endcode @@ -2976,9 +3203,11 @@ AST_POLYMORPHIC_MATCHER_P(hasOperatorName, /// \code /// a || b /// \endcode -AST_MATCHER_P(BinaryOperator, hasLHS, - internal::Matcher<Expr>, InnerMatcher) { - Expr *LeftHandSide = Node.getLHS(); +AST_POLYMORPHIC_MATCHER_P(hasLHS, + AST_POLYMORPHIC_SUPPORTED_TYPES(BinaryOperator, + ArraySubscriptExpr), + internal::Matcher<Expr>, InnerMatcher) { + const Expr *LeftHandSide = Node.getLHS(); return (LeftHandSide != nullptr && InnerMatcher.matches(*LeftHandSide, Finder, Builder)); } @@ -2989,9 +3218,11 @@ AST_MATCHER_P(BinaryOperator, hasLHS, /// \code /// a || b /// \endcode -AST_MATCHER_P(BinaryOperator, hasRHS, - internal::Matcher<Expr>, InnerMatcher) { - Expr *RightHandSide = Node.getRHS(); +AST_POLYMORPHIC_MATCHER_P(hasRHS, + AST_POLYMORPHIC_SUPPORTED_TYPES(BinaryOperator, + ArraySubscriptExpr), + internal::Matcher<Expr>, InnerMatcher) { + const Expr *RightHandSide = Node.getRHS(); return (RightHandSide != nullptr && InnerMatcher.matches(*RightHandSide, Finder, Builder)); } @@ -3005,7 +3236,8 @@ inline internal::Matcher<BinaryOperator> hasEitherOperand( /// \brief Matches if the operand of a unary operator matches. /// -/// Example matches true (matcher = hasUnaryOperand(boolLiteral(equals(true)))) +/// Example matches true (matcher = hasUnaryOperand( +/// cxxBoolLiteral(equals(true)))) /// \code /// !true /// \endcode @@ -3019,10 +3251,11 @@ AST_MATCHER_P(UnaryOperator, hasUnaryOperand, /// \brief Matches if the cast's source expression matches the given matcher. /// /// Example: matches "a string" (matcher = -/// hasSourceExpression(constructExpr())) +/// 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(); @@ -3049,6 +3282,42 @@ AST_MATCHER_P(ImplicitCastExpr, hasImplicitDestinationType, return InnerMatcher.matches(Node.getType(), Finder, Builder); } +/// \brief Matches RecordDecl object that are spelled with "struct." +/// +/// Example matches S, but not C or U. +/// \code +/// struct S {}; +/// class C {}; +/// union U {}; +/// \endcode +AST_MATCHER(RecordDecl, isStruct) { + return Node.isStruct(); +} + +/// \brief Matches RecordDecl object that are spelled with "union." +/// +/// Example matches U, but not C or S. +/// \code +/// struct S {}; +/// class C {}; +/// union U {}; +/// \endcode +AST_MATCHER(RecordDecl, isUnion) { + return Node.isUnion(); +} + +/// \brief Matches RecordDecl object that are spelled with "class." +/// +/// Example matches C, but not S or U. +/// \code +/// struct S {}; +/// class C {}; +/// union U {}; +/// \endcode +AST_MATCHER(RecordDecl, isClass) { + return Node.isClass(); +} + /// \brief Matches the true branch expression of a conditional operator. /// /// Example matches a @@ -3057,7 +3326,7 @@ AST_MATCHER_P(ImplicitCastExpr, hasImplicitDestinationType, /// \endcode AST_MATCHER_P(ConditionalOperator, hasTrueExpression, internal::Matcher<Expr>, InnerMatcher) { - Expr *Expression = Node.getTrueExpr(); + const Expr *Expression = Node.getTrueExpr(); return (Expression != nullptr && InnerMatcher.matches(*Expression, Finder, Builder)); } @@ -3070,7 +3339,7 @@ AST_MATCHER_P(ConditionalOperator, hasTrueExpression, /// \endcode AST_MATCHER_P(ConditionalOperator, hasFalseExpression, internal::Matcher<Expr>, InnerMatcher) { - Expr *Expression = Node.getFalseExpr(); + const Expr *Expression = Node.getFalseExpr(); return (Expression != nullptr && InnerMatcher.matches(*Expression, Finder, Builder)); } @@ -3094,6 +3363,20 @@ AST_POLYMORPHIC_MATCHER(isDefinition, return Node.isThisDeclarationADefinition(); } +/// \brief Matches if a function declaration is variadic. +/// +/// Example matches f, but not g or h. The function i will not match, even when +/// compiled in C mode. +/// \code +/// void f(...); +/// void g(int); +/// template <typename... Ts> void h(Ts...); +/// void i(); +/// \endcode +AST_MATCHER(FunctionDecl, isVariadic) { + return Node.isVariadic(); +} + /// \brief Matches the class declaration that the given method declaration /// belongs to. /// @@ -3102,7 +3385,7 @@ AST_POLYMORPHIC_MATCHER(isDefinition, /// this to? /// /// Example matches A() in the last line -/// (matcher = constructExpr(hasDeclaration(methodDecl( +/// (matcher = cxxConstructExpr(hasDeclaration(cxxMethodDecl( /// ofClass(hasName("A")))))) /// \code /// class A { @@ -3132,6 +3415,27 @@ AST_MATCHER(CXXMethodDecl, isVirtual) { return Node.isVirtual(); } +/// \brief Matches if the given method or class declaration is final. +/// +/// Given: +/// \code +/// class A final {}; +/// +/// struct B { +/// virtual void f(); +/// }; +/// +/// struct C : B { +/// void f() final; +/// }; +/// \endcode +/// matches A and C::f, but not B, C, or B::f +AST_POLYMORPHIC_MATCHER(isFinal, + AST_POLYMORPHIC_SUPPORTED_TYPES(CXXRecordDecl, + CXXMethodDecl)) { + return Node.template hasAttr<FinalAttr>(); +} + /// \brief Matches if the given method declaration is pure. /// /// Given @@ -3156,11 +3460,28 @@ AST_MATCHER(CXXMethodDecl, isPure) { /// }; /// \endcode /// -/// methodDecl(isConst()) matches A::foo() but not A::bar() +/// cxxMethodDecl(isConst()) matches A::foo() but not A::bar() AST_MATCHER(CXXMethodDecl, isConst) { return Node.isConst(); } +/// \brief Matches if the given method declaration declares a copy assignment +/// operator. +/// +/// Given +/// \code +/// struct A { +/// A &operator=(const A &); +/// A &operator=(A &&); +/// }; +/// \endcode +/// +/// cxxMethodDecl(isCopyAssignmentOperator()) matches the first method but not +/// the second one. +AST_MATCHER(CXXMethodDecl, isCopyAssignmentOperator) { + return Node.isCopyAssignmentOperator(); +} + /// \brief Matches if the given method declaration overrides another method. /// /// Given @@ -3212,6 +3533,20 @@ AST_MATCHER(QualType, isInteger) { return Node->isIntegerType(); } +/// \brief Matches QualType nodes that are of character type. +/// +/// Given +/// \code +/// void a(char); +/// void b(wchar_t); +/// void c(double); +/// \endcode +/// functionDecl(hasAnyParameter(hasType(isAnyCharacter()))) +/// matches "a(char)", "b(wchar_t)", but not "c(double)". +AST_MATCHER(QualType, isAnyCharacter) { + return Node->isAnyCharacterType(); +} + /// \brief Matches QualType nodes that are const-qualified, i.e., that /// include "top-level" const. /// @@ -3231,6 +3566,25 @@ AST_MATCHER(QualType, isConstQualified) { return Node.isConstQualified(); } +/// \brief Matches QualType nodes that are volatile-qualified, i.e., that +/// include "top-level" volatile. +/// +/// Given +/// \code +/// void a(int); +/// void b(int volatile); +/// void c(volatile int); +/// void d(volatile int*); +/// void e(int volatile) {}; +/// \endcode +/// functionDecl(hasAnyParameter(hasType(isVolatileQualified()))) +/// matches "void b(int volatile)", "void c(volatile int)" and +/// "void e(int volatile) {}". It does not match d as there +/// is no top-level volatile on the parameter type "volatile int *". +AST_MATCHER(QualType, isVolatileQualified) { + return Node.isVolatileQualified(); +} + /// \brief Matches QualType nodes that have local CV-qualifiers attached to /// the node, not hidden within a typedef. /// @@ -3273,7 +3627,7 @@ AST_MATCHER_P(MemberExpr, member, /// struct X { int m; }; /// void f(X x) { x.m; m; } /// \endcode -/// memberExpr(hasObjectExpression(hasType(recordDecl(hasName("X"))))))) +/// memberExpr(hasObjectExpression(hasType(cxxRecordDecl(hasName("X"))))))) /// matches "x.m" and "m" /// with hasObjectExpression(...) /// matching "x" and the implicit object expression of "m" which has type X*. @@ -3325,7 +3679,7 @@ AST_MATCHER_P(UsingShadowDecl, hasTargetDecl, /// \code /// template <typename T> class X {}; class A {}; template class X<A>; /// \endcode -/// recordDecl(hasName("::X"), isTemplateInstantiation()) +/// cxxRecordDecl(hasName("::X"), isTemplateInstantiation()) /// matches the template instantiation of X<A>. /// /// But given @@ -3333,7 +3687,7 @@ AST_MATCHER_P(UsingShadowDecl, hasTargetDecl, /// template <typename T> class X {}; class A {}; /// template <> class X<A> {}; X<A> x; /// \endcode -/// recordDecl(hasName("::X"), isTemplateInstantiation()) +/// cxxRecordDecl(hasName("::X"), isTemplateInstantiation()) /// does not match, as X<A> is an explicit template specialization. /// /// Usable as: Matcher<FunctionDecl>, Matcher<VarDecl>, Matcher<CXXRecordDecl> @@ -3357,7 +3711,7 @@ AST_POLYMORPHIC_MATCHER(isTemplateInstantiation, /// functionDecl(isInstantiated()) /// matches 'A(int) {...};' and 'A(unsigned) {...}'. AST_MATCHER_FUNCTION(internal::Matcher<Decl>, isInstantiated) { - auto IsInstantiation = decl(anyOf(recordDecl(isTemplateInstantiation()), + auto IsInstantiation = decl(anyOf(cxxRecordDecl(isTemplateInstantiation()), functionDecl(isTemplateInstantiation()))); return decl(anyOf(IsInstantiation, hasAncestor(IsInstantiation))); } @@ -3378,7 +3732,7 @@ AST_MATCHER_FUNCTION(internal::Matcher<Decl>, isInstantiated) { /// instantiation. AST_MATCHER_FUNCTION(internal::Matcher<Stmt>, isInTemplateInstantiation) { return stmt( - hasAncestor(decl(anyOf(recordDecl(isTemplateInstantiation()), + hasAncestor(decl(anyOf(cxxRecordDecl(isTemplateInstantiation()), functionDecl(isTemplateInstantiation()))))); } @@ -3408,6 +3762,18 @@ AST_MATCHER_FUNCTION_P_OVERLOAD(internal::BindableMatcher<TypeLoc>, loc, new internal::TypeLocTypeMatcher(InnerMatcher)); } +/// \brief Matches type \c bool. +/// +/// Given +/// \code +/// struct S { bool func(); }; +/// \endcode +/// functionDecl(returns(booleanType())) +/// matches "bool func();" +AST_MATCHER(Type, booleanType) { + return Node.isBooleanType(); +} + /// \brief Matches type \c void. /// /// Given @@ -3665,18 +4031,38 @@ AST_TYPE_MATCHER(BlockPointerType, blockPointerType); /// matches "A::* ptr" AST_TYPE_MATCHER(MemberPointerType, memberPointerType); -/// \brief Matches pointer types. +/// \brief Matches pointer types, but does not match Objective-C object pointer +/// types. /// /// Given /// \code /// int *a; /// int &b = *a; /// int c = 5; +/// +/// @interface Foo +/// @end +/// Foo *f; /// \endcode /// pointerType() -/// matches "int *a" +/// matches "int *a", but does not match "Foo *f". AST_TYPE_MATCHER(PointerType, pointerType); +/// \brief Matches an Objective-C object pointer type, which is different from +/// a pointer type, despite being syntactically similar. +/// +/// Given +/// \code +/// int *a; +/// +/// @interface Foo +/// @end +/// Foo *f; +/// \endcode +/// pointerType() +/// matches "Foo *f", but does not match "int *a". +AST_TYPE_MATCHER(ObjCObjectPointerType, objcObjectPointerType); + /// \brief Matches both lvalue and rvalue reference types. /// /// Given @@ -3766,7 +4152,7 @@ AST_TYPE_MATCHER(TypedefType, typedefType); /// /// template class C<int>; // A /// C<char> var; // B -/// \code +/// \endcode /// /// \c templateSpecializationType() matches the type of the explicit /// instantiation in \c A and the type of the variable declaration in \c B. @@ -3791,7 +4177,7 @@ AST_TYPE_MATCHER(UnaryTransformType, unaryTransformType); /// /// C c; /// S s; -/// \code +/// \endcode /// /// \c recordType() matches the type of the variable declarations of both \c c /// and \c s. @@ -3811,7 +4197,7 @@ AST_TYPE_MATCHER(RecordType, recordType); /// /// class C c; /// N::M::D d; -/// \code +/// \endcode /// /// \c elaboratedType() matches the type of the variable declarations of both /// \c c and \c d. @@ -3828,7 +4214,7 @@ AST_TYPE_MATCHER(ElaboratedType, elaboratedType); /// } /// } /// N::M::D d; -/// \code +/// \endcode /// /// \c elaboratedType(hasQualifier(hasPrefix(specifiesNamespace(hasName("N")))) /// matches the type of the variable declaration of \c d. @@ -3850,7 +4236,7 @@ AST_MATCHER_P(ElaboratedType, hasQualifier, /// } /// } /// N::M::D d; -/// \code +/// \endcode /// /// \c elaboratedType(namesType(recordType( /// hasDeclaration(namedDecl(hasName("D")))))) matches the type of the variable @@ -3860,6 +4246,59 @@ AST_MATCHER_P(ElaboratedType, namesType, internal::Matcher<QualType>, return InnerMatcher.matches(Node.getNamedType(), Finder, Builder); } +/// \brief Matches types that represent the result of substituting a type for a +/// template type parameter. +/// +/// Given +/// \code +/// template <typename T> +/// void F(T t) { +/// int i = 1 + t; +/// } +/// \endcode +/// +/// \c substTemplateTypeParmType() matches the type of 't' but not '1' +AST_TYPE_MATCHER(SubstTemplateTypeParmType, substTemplateTypeParmType); + +/// \brief Matches template type parameter types. +/// +/// Example matches T, but not int. +/// (matcher = templateTypeParmType()) +/// \code +/// template <typename T> void f(int i); +/// \endcode +AST_TYPE_MATCHER(TemplateTypeParmType, templateTypeParmType); + +/// \brief Matches injected class name types. +/// +/// Example matches S s, but not S<T> s. +/// (matcher = parmVarDecl(hasType(injectedClassNameType()))) +/// \code +/// template <typename T> struct S { +/// void f(S s); +/// void g(S<T> s); +/// }; +/// \endcode +AST_TYPE_MATCHER(InjectedClassNameType, injectedClassNameType); + +/// \brief Matches decayed type +/// Example matches i[] in declaration of f. +/// (matcher = valueDecl(hasType(decayedType(hasDecayedType(pointerType()))))) +/// Example matches i[1]. +/// (matcher = expr(hasType(decayedType(hasDecayedType(pointerType()))))) +/// \code +/// void f(int i[]) { +/// i[1] = 0; +/// } +/// \endcode +AST_TYPE_MATCHER(DecayedType, decayedType); + +/// \brief Matches the decayed type, whos decayed type matches \c InnerMatcher +AST_MATCHER_P(DecayedType, hasDecayedType, internal::Matcher<QualType>, + InnerType) { + return InnerType.matches(Node.getDecayedType(), Finder, Builder); +} + /// \brief Matches declarations whose declaration context, interpreted as a /// Decl, matches \c InnerMatcher. /// @@ -3870,9 +4309,9 @@ AST_MATCHER_P(ElaboratedType, namesType, internal::Matcher<QualType>, /// class D {}; /// } /// } -/// \code +/// \endcode /// -/// \c recordDecl(hasDeclContext(namedDecl(hasName("M")))) matches the +/// \c cxxRcordDecl(hasDeclContext(namedDecl(hasName("M")))) matches the /// declaration of \c class \c D. AST_MATCHER_P(Decl, hasDeclContext, internal::Matcher<Decl>, InnerMatcher) { const DeclContext *DC = Node.getDeclContext(); @@ -3917,7 +4356,9 @@ AST_MATCHER_FUNCTION_P_OVERLOAD( /// struct A { struct B { struct C {}; }; }; /// A::B::C c; /// \endcode -/// nestedNameSpecifier(specifiesType(hasDeclaration(recordDecl(hasName("A"))))) +/// nestedNameSpecifier(specifiesType( +/// hasDeclaration(cxxRecordDecl(hasName("A"))) +/// )) /// matches "A::" AST_MATCHER_P(NestedNameSpecifier, specifiesType, internal::Matcher<QualType>, InnerMatcher) { @@ -3935,7 +4376,7 @@ AST_MATCHER_P(NestedNameSpecifier, specifiesType, /// A::B::C c; /// \endcode /// nestedNameSpecifierLoc(specifiesTypeLoc(loc(type( -/// hasDeclaration(recordDecl(hasName("A"))))))) +/// hasDeclaration(cxxRecordDecl(hasName("A"))))))) /// matches "A::" AST_MATCHER_P(NestedNameSpecifierLoc, specifiesTypeLoc, internal::Matcher<TypeLoc>, InnerMatcher) { @@ -3954,7 +4395,7 @@ AST_MATCHER_P(NestedNameSpecifierLoc, specifiesTypeLoc, AST_MATCHER_P_OVERLOAD(NestedNameSpecifier, hasPrefix, internal::Matcher<NestedNameSpecifier>, InnerMatcher, 0) { - NestedNameSpecifier *NextNode = Node.getPrefix(); + const NestedNameSpecifier *NextNode = Node.getPrefix(); if (!NextNode) return false; return InnerMatcher.matches(*NextNode, Finder, Builder); @@ -4008,10 +4449,15 @@ AST_MATCHER_P_OVERLOAD(Decl, equalsNode, const Decl*, Other, 0) { /// \brief Matches if a node equals another node. /// /// \c Stmt has pointer identity in the AST. -/// AST_MATCHER_P_OVERLOAD(Stmt, equalsNode, const Stmt*, Other, 1) { return &Node == Other; } +/// \brief Matches if a node equals another node. +/// +/// \c Type has pointer identity in the AST. +AST_MATCHER_P_OVERLOAD(Type, equalsNode, const Type*, Other, 2) { + return &Node == Other; +} /// @} @@ -4053,7 +4499,9 @@ AST_MATCHER_P(SwitchStmt, forEachSwitchCase, internal::Matcher<SwitchCase>, /// \code /// class A { A() : i(42), j(42) {} int i; int j; }; /// \endcode -/// constructorDecl(forEachConstructorInitializer(forField(decl().bind("x")))) +/// cxxConstructorDecl(forEachConstructorInitializer( +/// forField(decl().bind("x")) +/// )) /// will trigger two matches, binding for 'i' and 'j' respectively. AST_MATCHER_P(CXXConstructorDecl, forEachConstructorInitializer, internal::Matcher<CXXCtorInitializer>, InnerMatcher) { @@ -4070,6 +4518,109 @@ AST_MATCHER_P(CXXConstructorDecl, forEachConstructorInitializer, return Matched; } +/// \brief Matches constructor declarations that are copy constructors. +/// +/// Given +/// \code +/// struct S { +/// S(); // #1 +/// S(const S &); // #2 +/// S(S &&); // #3 +/// }; +/// \endcode +/// cxxConstructorDecl(isCopyConstructor()) will match #2, but not #1 or #3. +AST_MATCHER(CXXConstructorDecl, isCopyConstructor) { + return Node.isCopyConstructor(); +} + +/// \brief Matches constructor declarations that are move constructors. +/// +/// Given +/// \code +/// struct S { +/// S(); // #1 +/// S(const S &); // #2 +/// S(S &&); // #3 +/// }; +/// \endcode +/// cxxConstructorDecl(isMoveConstructor()) will match #3, but not #1 or #2. +AST_MATCHER(CXXConstructorDecl, isMoveConstructor) { + return Node.isMoveConstructor(); +} + +/// \brief Matches constructor declarations that are default constructors. +/// +/// Given +/// \code +/// struct S { +/// S(); // #1 +/// S(const S &); // #2 +/// S(S &&); // #3 +/// }; +/// \endcode +/// cxxConstructorDecl(isDefaultConstructor()) will match #1, but not #2 or #3. +AST_MATCHER(CXXConstructorDecl, isDefaultConstructor) { + return Node.isDefaultConstructor(); +} + +/// \brief Matches constructor and conversion declarations that are marked with +/// the explicit keyword. +/// +/// Given +/// \code +/// struct S { +/// S(int); // #1 +/// explicit S(double); // #2 +/// operator int(); // #3 +/// explicit operator bool(); // #4 +/// }; +/// \endcode +/// cxxConstructorDecl(isExplicit()) will match #2, but not #1. +/// cxxConversionDecl(isExplicit()) will match #4, but not #3. +AST_POLYMORPHIC_MATCHER(isExplicit, + AST_POLYMORPHIC_SUPPORTED_TYPES(CXXConstructorDecl, + CXXConversionDecl)) { + return Node.isExplicit(); +} + +/// \brief Matches function and namespace declarations that are marked with +/// the inline keyword. +/// +/// Given +/// \code +/// inline void f(); +/// void g(); +/// namespace n { +/// inline namespace m {} +/// } +/// \endcode +/// functionDecl(isInline()) will match ::f(). +/// namespaceDecl(isInline()) will match n::m. +AST_POLYMORPHIC_MATCHER(isInline, + AST_POLYMORPHIC_SUPPORTED_TYPES(NamespaceDecl, + FunctionDecl)) { + // This is required because the spelling of the function used to determine + // whether inline is specified or not differs between the polymorphic types. + if (const auto *FD = dyn_cast<FunctionDecl>(&Node)) + return FD->isInlineSpecified(); + else if (const auto *NSD = dyn_cast<NamespaceDecl>(&Node)) + return NSD->isInline(); + llvm_unreachable("Not a valid polymorphic type"); +} + +/// \brief Matches anonymous namespace declarations. +/// +/// Given +/// \code +/// namespace n { +/// namespace {} // #1 +/// } +/// \endcode +/// namespaceDecl(isAnonymous()) will match #1 but not ::n. +AST_MATCHER(NamespaceDecl, isAnonymous) { + return Node.isAnonymousNamespace(); +} + /// \brief If the given case statement does not use the GNU case range /// extension, matches the constant given in the statement. /// @@ -4094,7 +4645,8 @@ AST_MATCHER_P(CaseStmt, hasCaseConstant, internal::Matcher<Expr>, /// __attribute__((device)) void f() { ... } /// \endcode /// decl(hasAttr(clang::attr::CUDADevice)) matches the function declaration of -/// f. +/// f. If the matcher is use from clang-query, attr::Kind parameter should be +/// passed as a quoted string. e.g., hasAttr("attr::CUDADevice"). AST_MATCHER_P(Decl, hasAttr, attr::Kind, AttrKind) { for (const auto *Attr : Node.attrs()) { if (Attr->getKind() == AttrKind) @@ -4109,8 +4661,9 @@ AST_MATCHER_P(Decl, hasAttr, attr::Kind, AttrKind) { /// \code /// kernel<<<i,j>>>(); /// \endcode -const internal::VariadicDynCastAllOfMatcher<Stmt, CUDAKernelCallExpr> - CUDAKernelCallExpr; +const internal::VariadicDynCastAllOfMatcher< + Stmt, + CUDAKernelCallExpr> cudaKernelCallExpr; } // end namespace ast_matchers } // end namespace clang diff --git a/contrib/llvm/tools/clang/include/clang/ASTMatchers/ASTMatchersInternal.h b/contrib/llvm/tools/clang/include/clang/ASTMatchers/ASTMatchersInternal.h index b494647..d499091 100644 --- a/contrib/llvm/tools/clang/include/clang/ASTMatchers/ASTMatchersInternal.h +++ b/contrib/llvm/tools/clang/include/clang/ASTMatchers/ASTMatchersInternal.h @@ -188,8 +188,11 @@ class ASTMatchFinder; /// Used by the implementation of Matcher<T> and DynTypedMatcher. /// In general, implement MatcherInterface<T> or SingleNodeMatcherInterface<T> /// instead. -class DynMatcherInterface : public RefCountedBaseVPTR { +class DynMatcherInterface + : public llvm::ThreadSafeRefCountedBase<DynMatcherInterface> { public: + virtual ~DynMatcherInterface() {} + /// \brief Returns true if \p DynNode can be matched. /// /// May bind \p DynNode to an ID via \p Builder, or recurse into @@ -209,8 +212,6 @@ public: template <typename T> class MatcherInterface : public DynMatcherInterface { public: - ~MatcherInterface() override {} - /// \brief Returns true if 'Node' can be matched. /// /// May bind 'Node' to an ID via 'Builder', or recurse into @@ -281,6 +282,7 @@ public: }; static DynTypedMatcher constructVariadic(VariadicOperator Op, + ast_type_traits::ASTNodeKind SupportedKind, std::vector<DynTypedMatcher> InnerMatchers); /// \brief Get a "true" matcher for \p NodeKind. @@ -556,22 +558,32 @@ bool matchesFirstInPointerRange(const MatcherT &Matcher, IteratorT Start, return false; } -/// \brief Metafunction to determine if type T has a member called getDecl. +// Metafunction to determine if type T has a member called +// getDecl. +#if defined(_MSC_VER) && (_MSC_VER < 1900) && !defined(__clang__) +// For old versions of MSVC, we use a weird nonstandard __if_exists +// statement, since before MSVC2015, it was not standards-conformant +// enough to compile the usual code below. template <typename T> struct has_getDecl { - struct Default { int getDecl; }; - struct Derived : T, Default { }; - - template<typename C, C> struct CheckT; - - // If T::getDecl exists, an ambiguity arises and CheckT will - // not be instantiable. This makes f(...) the only available - // overload. - template<typename C> - static char (&f(CheckT<int Default::*, &C::getDecl>*))[1]; - template<typename C> static char (&f(...))[2]; - - static bool const value = sizeof(f<Derived>(nullptr)) == 2; + __if_exists(T::getDecl) { + enum { value = 1 }; + } + __if_not_exists(T::getDecl) { + enum { value = 0 }; + } }; +#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. /// @@ -667,16 +679,30 @@ private: return matchesDecl(Node.getDecl(), Finder, Builder); } - /// \brief Extracts the CXXRecordDecl or EnumDecl of a QualType and returns - /// whether the inner matcher matches on it. + /// \brief Extracts the TagDecl of a QualType and returns whether the inner + /// matcher matches on it. bool matchesSpecialized(const QualType &Node, ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder) const { - /// FIXME: Add other ways to convert... if (Node.isNull()) return false; - if (const EnumType *AsEnum = dyn_cast<EnumType>(Node.getTypePtr())) - return matchesDecl(AsEnum->getDecl(), Finder, Builder); - return matchesDecl(Node->getAsCXXRecordDecl(), Finder, Builder); + + if (auto *TD = Node->getAsTagDecl()) + return matchesDecl(TD, Finder, Builder); + else if (auto *TT = Node->getAs<TypedefType>()) + return matchesDecl(TT->getDecl(), Finder, Builder); + // Do not use getAs<TemplateTypeParmType> instead of the direct dyn_cast. + // Calling getAs will return the canonical type, but that type does not + // store a TemplateTypeParmDecl. We *need* the uncanonical type, if it is + // available, and using dyn_cast ensures that. + else if (auto *TTP = dyn_cast<TemplateTypeParmType>(Node.getTypePtr())) + return matchesDecl(TTP->getDecl(), Finder, Builder); + else if (auto *OCIT = Node->getAs<ObjCInterfaceType>()) + return matchesDecl(OCIT->getDecl(), Finder, Builder); + else if (auto *UUT = Node->getAs<UnresolvedUsingType>()) + return matchesDecl(UUT->getDecl(), Finder, Builder); + else if (auto *ICNT = Node->getAs<InjectedClassNameType>()) + return matchesDecl(ICNT->getDecl(), Finder, Builder); + return false; } /// \brief Gets the TemplateDecl from a TemplateSpecializationType @@ -753,7 +779,7 @@ const bool IsBaseType<T>::value; /// at least one ancestor matched. /// /// FIXME: Currently we only allow Stmt and Decl nodes to start a traversal. -/// In the future, we wan to implement this for all nodes for which it makes +/// In the future, we want to implement this for all nodes for which it makes /// sense. In the case of matchesAncestorOf, we'll want to implement it for /// all nodes, as all nodes have ancestors. class ASTMatchFinder { @@ -833,8 +859,10 @@ public: BoundNodesTreeBuilder *Builder, AncestorMatchMode MatchMode) { static_assert(std::is_base_of<Decl, T>::value || - std::is_base_of<Stmt, T>::value, - "only Decl or Stmt allowed for recursive matching"); + std::is_base_of<NestedNameSpecifierLoc, T>::value || + std::is_base_of<Stmt, T>::value || + std::is_base_of<TypeLoc, T>::value, + "type not allowed for recursive matching"); return matchesAncestorOf(ast_type_traits::DynTypedNode::create(Node), Matcher, Builder, MatchMode); } @@ -1137,7 +1165,8 @@ public: template <typename T> operator Matcher<T>() const { return DynTypedMatcher::constructVariadic( - Op, getMatchers<T>(llvm::index_sequence_for<Ps...>())) + Op, ast_type_traits::ASTNodeKind::getFromNodeKind<T>(), + getMatchers<T>(llvm::index_sequence_for<Ps...>())) .template unconditionalConvertTo<T>(); } @@ -1191,8 +1220,10 @@ BindableMatcher<T> makeAllOfComposite( std::vector<DynTypedMatcher> DynMatchers(PI(InnerMatchers.begin()), PI(InnerMatchers.end())); return BindableMatcher<T>( - DynTypedMatcher::constructVariadic(DynTypedMatcher::VO_AllOf, - std::move(DynMatchers)) + DynTypedMatcher::constructVariadic( + DynTypedMatcher::VO_AllOf, + ast_type_traits::ASTNodeKind::getFromNodeKind<T>(), + std::move(DynMatchers)) .template unconditionalConvertTo<T>()); } diff --git a/contrib/llvm/tools/clang/include/clang/ASTMatchers/Dynamic/Diagnostics.h b/contrib/llvm/tools/clang/include/clang/ASTMatchers/Dynamic/Diagnostics.h index ef93ac5..2c76dda 100644 --- a/contrib/llvm/tools/clang/include/clang/ASTMatchers/Dynamic/Diagnostics.h +++ b/contrib/llvm/tools/clang/include/clang/ASTMatchers/Dynamic/Diagnostics.h @@ -104,11 +104,11 @@ public: /// \brief About to call the constructor for a matcher. enum ConstructMatcherEnum { ConstructMatcher }; Context(ConstructMatcherEnum, Diagnostics *Error, StringRef MatcherName, - const SourceRange &MatcherRange); + SourceRange MatcherRange); /// \brief About to recurse into parsing one argument for a matcher. enum MatcherArgEnum { MatcherArg }; Context(MatcherArgEnum, Diagnostics *Error, StringRef MatcherName, - const SourceRange &MatcherRange, unsigned ArgNumber); + SourceRange MatcherRange, unsigned ArgNumber); ~Context(); private: @@ -137,7 +137,7 @@ public: /// All the context information will be kept on the error message. /// \return a helper class to allow the caller to pass the arguments for the /// error message, using the << operator. - ArgStream addError(const SourceRange &Range, ErrorType Error); + ArgStream addError(SourceRange Range, ErrorType Error); /// \brief Information stored for one frame of the context. struct ContextFrame { diff --git a/contrib/llvm/tools/clang/include/clang/ASTMatchers/Dynamic/Parser.h b/contrib/llvm/tools/clang/include/clang/ASTMatchers/Dynamic/Parser.h index cdc259e..76926f0 100644 --- a/contrib/llvm/tools/clang/include/clang/ASTMatchers/Dynamic/Parser.h +++ b/contrib/llvm/tools/clang/include/clang/ASTMatchers/Dynamic/Parser.h @@ -81,7 +81,7 @@ public: /// matcher if an error occurred. In that case, \c Error will contain a /// description of the error. virtual VariantMatcher actOnMatcherExpression(MatcherCtor Ctor, - const SourceRange &NameRange, + SourceRange NameRange, StringRef BindID, ArrayRef<ParserValue> Args, Diagnostics *Error) = 0; @@ -129,7 +129,7 @@ public: lookupMatcherCtor(StringRef MatcherName) override; VariantMatcher actOnMatcherExpression(MatcherCtor Ctor, - const SourceRange &NameRange, + SourceRange NameRange, StringRef BindID, ArrayRef<ParserValue> Args, Diagnostics *Error) override; diff --git a/contrib/llvm/tools/clang/include/clang/ASTMatchers/Dynamic/Registry.h b/contrib/llvm/tools/clang/include/clang/ASTMatchers/Dynamic/Registry.h index fc1e783..3808adb 100644 --- a/contrib/llvm/tools/clang/include/clang/ASTMatchers/Dynamic/Registry.h +++ b/contrib/llvm/tools/clang/include/clang/ASTMatchers/Dynamic/Registry.h @@ -106,7 +106,7 @@ public: /// the signature. In that case \c Error will contain the description of /// the error. static VariantMatcher constructMatcher(MatcherCtor Ctor, - const SourceRange &NameRange, + SourceRange NameRange, ArrayRef<ParserValue> Args, Diagnostics *Error); @@ -117,7 +117,7 @@ public: /// If the matcher is not bindable, it sets an error in \c Error and returns /// a null matcher. static VariantMatcher constructBoundMatcher(MatcherCtor Ctor, - const SourceRange &NameRange, + SourceRange NameRange, StringRef BindID, ArrayRef<ParserValue> Args, Diagnostics *Error); diff --git a/contrib/llvm/tools/clang/include/clang/Analysis/Analyses/Consumed.h b/contrib/llvm/tools/clang/include/clang/Analysis/Analyses/Consumed.h index a710923..1f5aa12 100644 --- a/contrib/llvm/tools/clang/include/clang/Analysis/Analyses/Consumed.h +++ b/contrib/llvm/tools/clang/include/clang/Analysis/Analyses/Consumed.h @@ -71,7 +71,7 @@ namespace consumed { virtual void warnParamReturnTypestateMismatch(SourceLocation Loc, StringRef VariableName, StringRef ExpectedState, - StringRef ObservedState) {}; + StringRef ObservedState) {} // FIXME: Add documentation. virtual void warnParamTypestateMismatch(SourceLocation LOC, @@ -162,8 +162,8 @@ namespace consumed { ConsumedState getState(const CXXBindTemporaryExpr *Tmp) const; /// \brief Merge this state map with another map. - void intersect(const ConsumedStateMap *Other); - + void intersect(const ConsumedStateMap &Other); + void intersectAtLoopHead(const CFGBlock *LoopHead, const CFGBlock *LoopBack, const ConsumedStateMap *LoopBackStates, ConsumedWarningsHandlerBase &WarningsHandler); @@ -196,15 +196,19 @@ namespace consumed { }; class ConsumedBlockInfo { - std::vector<ConsumedStateMap*> StateMapsArray; + std::vector<std::unique_ptr<ConsumedStateMap>> StateMapsArray; std::vector<unsigned int> VisitOrder; public: - ConsumedBlockInfo() { } - ~ConsumedBlockInfo() { llvm::DeleteContainerPointers(StateMapsArray); } + ConsumedBlockInfo() = default; + ConsumedBlockInfo &operator=(ConsumedBlockInfo &&Other) { + StateMapsArray = std::move(Other.StateMapsArray); + VisitOrder = std::move(Other.VisitOrder); + return *this; + } ConsumedBlockInfo(unsigned int NumBlocks, PostOrderCFGView *SortedGraph) - : StateMapsArray(NumBlocks, nullptr), VisitOrder(NumBlocks, 0) { + : StateMapsArray(NumBlocks), VisitOrder(NumBlocks, 0) { unsigned int VisitOrderCounter = 0; for (PostOrderCFGView::iterator BI = SortedGraph->begin(), BE = SortedGraph->end(); BI != BE; ++BI) { @@ -214,17 +218,18 @@ namespace consumed { bool allBackEdgesVisited(const CFGBlock *CurrBlock, const CFGBlock *TargetBlock); - + void addInfo(const CFGBlock *Block, ConsumedStateMap *StateMap, - bool &AlreadyOwned); - void addInfo(const CFGBlock *Block, ConsumedStateMap *StateMap); - + std::unique_ptr<ConsumedStateMap> &OwnedStateMap); + void addInfo(const CFGBlock *Block, + std::unique_ptr<ConsumedStateMap> StateMap); + ConsumedStateMap* borrowInfo(const CFGBlock *Block); void discardInfo(const CFGBlock *Block); - - ConsumedStateMap* getInfo(const CFGBlock *Block); - + + std::unique_ptr<ConsumedStateMap> getInfo(const CFGBlock *Block); + bool isBackEdge(const CFGBlock *From, const CFGBlock *To); bool isBackEdgeTarget(const CFGBlock *Block); }; @@ -233,13 +238,12 @@ namespace consumed { class ConsumedAnalyzer { ConsumedBlockInfo BlockInfo; - ConsumedStateMap *CurrStates; - + std::unique_ptr<ConsumedStateMap> CurrStates; + ConsumedState ExpectedReturnState; void determineExpectedReturnState(AnalysisDeclContext &AC, const FunctionDecl *D); - bool hasConsumableAttributes(const CXXRecordDecl *RD); bool splitState(const CFGBlock *CurrBlock, const ConsumedStmtVisitor &Visitor); diff --git a/contrib/llvm/tools/clang/include/clang/Analysis/Analyses/ThreadSafetyCommon.h b/contrib/llvm/tools/clang/include/clang/Analysis/Analyses/ThreadSafetyCommon.h index 9b7725a..e357013 100644 --- a/contrib/llvm/tools/clang/include/clang/Analysis/Analyses/ThreadSafetyCommon.h +++ b/contrib/llvm/tools/clang/include/clang/Analysis/Analyses/ThreadSafetyCommon.h @@ -287,10 +287,12 @@ public: } const ValueDecl* valueDecl() const { - if (Negated) + if (Negated || CapExpr == nullptr) return nullptr; if (auto *P = dyn_cast<til::Project>(CapExpr)) return P->clangDecl(); + if (auto *P = dyn_cast<til::LiteralPtr>(CapExpr)) + return P->clangDecl(); return nullptr; } diff --git a/contrib/llvm/tools/clang/include/clang/Analysis/Analyses/ThreadSafetyTIL.h b/contrib/llvm/tools/clang/include/clang/Analysis/Analyses/ThreadSafetyTIL.h index 4b59466..be8a710 100644 --- a/contrib/llvm/tools/clang/include/clang/Analysis/Analyses/ThreadSafetyTIL.h +++ b/contrib/llvm/tools/clang/include/clang/Analysis/Analyses/ThreadSafetyTIL.h @@ -1395,7 +1395,7 @@ public: /// Return the list of basic blocks that this terminator can branch to. ArrayRef<BasicBlock*> successors() { - return ArrayRef<BasicBlock*>(&TargetBlock, 1); + return TargetBlock; } template <class V> @@ -1445,7 +1445,7 @@ public: /// Return the list of basic blocks that this terminator can branch to. ArrayRef<BasicBlock*> successors() { - return ArrayRef<BasicBlock*>(Branches, 2); + return llvm::makeArrayRef(Branches); } template <class V> @@ -1479,7 +1479,7 @@ public: /// Return an empty list. ArrayRef<BasicBlock*> successors() { - return ArrayRef<BasicBlock*>(); + return None; } SExpr *returnValue() { return Retval; } @@ -1507,7 +1507,7 @@ inline ArrayRef<BasicBlock*> Terminator::successors() { case COP_Branch: return cast<Branch>(this)->successors(); case COP_Return: return cast<Return>(this)->successors(); default: - return ArrayRef<BasicBlock*>(); + return None; } } diff --git a/contrib/llvm/tools/clang/include/clang/Analysis/CFG.h b/contrib/llvm/tools/clang/include/clang/Analysis/CFG.h index 5430c3b..293990c 100644 --- a/contrib/llvm/tools/clang/include/clang/Analysis/CFG.h +++ b/contrib/llvm/tools/clang/include/clang/Analysis/CFG.h @@ -229,7 +229,6 @@ public: return static_cast<CXXDeleteExpr *>(Data2.getPointer()); } - private: friend class CFGElement; CFGDeleteDtor() {} @@ -693,7 +692,7 @@ public: iterator beginAutomaticObjDtorsInsert(iterator I, size_t Cnt, BumpVectorContext &C) { return iterator(Elements.insert(I.base(), Cnt, - CFGAutomaticObjDtor(nullptr, 0), C)); + CFGAutomaticObjDtor(nullptr, nullptr), C)); } iterator insertAutomaticObjDtor(iterator I, VarDecl *VD, Stmt *S) { *I = CFGAutomaticObjDtor(VD, S); @@ -767,7 +766,7 @@ public: /// (not a pointer to CFGBlock). class graph_iterator { public: - typedef const CFGBlock value_type; + typedef CFGBlock value_type; typedef value_type& reference; typedef value_type* pointer; typedef BumpVector<CFGBlock*>::iterator ImplTy; @@ -1110,4 +1109,5 @@ template <> struct GraphTraits<Inverse<const ::clang::CFG*> > } }; } // end llvm namespace -#endif + +#endif // LLVM_CLANG_ANALYSIS_CFG_H diff --git a/contrib/llvm/tools/clang/include/clang/Analysis/ProgramPoint.h b/contrib/llvm/tools/clang/include/clang/Analysis/ProgramPoint.h index f872715..6d816fd 100644 --- a/contrib/llvm/tools/clang/include/clang/Analysis/ProgramPoint.h +++ b/contrib/llvm/tools/clang/include/clang/Analysis/ProgramPoint.h @@ -33,8 +33,31 @@ namespace clang { class AnalysisDeclContext; class FunctionDecl; class LocationContext; -class ProgramPointTag; +/// ProgramPoints can be "tagged" as representing points specific to a given +/// analysis entity. Tags are abstract annotations, with an associated +/// description and potentially other information. +class ProgramPointTag { +public: + ProgramPointTag(void *tagKind = nullptr) : TagKind(tagKind) {} + virtual ~ProgramPointTag(); + virtual StringRef getTagDescription() const = 0; + +protected: + /// Used to implement 'isKind' in subclasses. + const void *getTagKind() { return TagKind; } + +private: + const void *TagKind; +}; + +class SimpleProgramPointTag : public ProgramPointTag { + std::string Desc; +public: + SimpleProgramPointTag(StringRef MsgProvider, StringRef Msg); + StringRef getTagDescription() const override; +}; + class ProgramPoint { public: enum Kind { BlockEdgeKind, @@ -643,30 +666,6 @@ private: } }; -/// ProgramPoints can be "tagged" as representing points specific to a given -/// analysis entity. Tags are abstract annotations, with an associated -/// description and potentially other information. -class ProgramPointTag { -public: - ProgramPointTag(void *tagKind = nullptr) : TagKind(tagKind) {} - virtual ~ProgramPointTag(); - virtual StringRef getTagDescription() const = 0; - -protected: - /// Used to implement 'isKind' in subclasses. - const void *getTagKind() { return TagKind; } - -private: - const void *TagKind; -}; - -class SimpleProgramPointTag : public ProgramPointTag { - std::string Desc; -public: - SimpleProgramPointTag(StringRef MsgProvider, StringRef Msg); - StringRef getTagDescription() const override; -}; - } // end namespace clang diff --git a/contrib/llvm/tools/clang/include/clang/Analysis/Support/BumpVector.h b/contrib/llvm/tools/clang/include/clang/Analysis/Support/BumpVector.h index 3abe32d..591d17b 100644 --- a/contrib/llvm/tools/clang/include/clang/Analysis/Support/BumpVector.h +++ b/contrib/llvm/tools/clang/include/clang/Analysis/Support/BumpVector.h @@ -35,7 +35,12 @@ public: /// Construct a new BumpVectorContext that creates a new BumpPtrAllocator /// and destroys it when the BumpVectorContext object is destroyed. BumpVectorContext() : Alloc(new llvm::BumpPtrAllocator(), 1) {} - + + BumpVectorContext(BumpVectorContext &&Other) : Alloc(Other.Alloc) { + Other.Alloc.setInt(false); + Other.Alloc.setPointer(nullptr); + } + /// Construct a new BumpVectorContext that reuses an existing /// BumpPtrAllocator. This BumpPtrAllocator is not destroyed when the /// BumpVectorContext object is destroyed. diff --git a/contrib/llvm/tools/clang/include/clang/Basic/Attr.td b/contrib/llvm/tools/clang/include/clang/Basic/Attr.td index 6187bcb..d5ba722 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/Attr.td +++ b/contrib/llvm/tools/clang/include/clang/Basic/Attr.td @@ -113,7 +113,7 @@ def GlobalVar : SubsetSubject<Var, // the case of a SubsetSubject, there's no way to express it without this hack. def DeclBase : AttrSubject; def FunctionLike : SubsetSubject<DeclBase, - [{S->getFunctionType(false) != NULL}]>; + [{S->getFunctionType(false) != nullptr}]>; def OpenCLKernelFunction : SubsetSubject<Function, [{ S->hasAttr<OpenCLKernelAttr>() @@ -123,15 +123,19 @@ def OpenCLKernelFunction : SubsetSubject<Function, [{ // never be specified in a Subjects list along with FunctionLike (due to the // inclusive nature of subject testing). def HasFunctionProto : SubsetSubject<DeclBase, - [{(S->getFunctionType(true) != NULL && + [{(S->getFunctionType(true) != nullptr && isa<FunctionProtoType>(S->getFunctionType())) || isa<ObjCMethodDecl>(S) || isa<BlockDecl>(S)}]>; // A single argument to an attribute -class Argument<string name, bit optional> { +class Argument<string name, bit optional, bit fake = 0> { string Name = name; bit Optional = optional; + + /// A fake argument is used to store and serialize additional information + /// in an attribute without actually changing its parsing or pretty-printing. + bit Fake = fake; } class BoolArgument<string name, bit opt = 0> : Argument<name, opt>; @@ -167,7 +171,8 @@ class DefaultIntArgument<string name, int default> : IntArgument<name, 1> { // This argument is more complex, it includes the enumerator type name, // a list of strings to accept, and a list of enumerators to map them to. class EnumArgument<string name, string type, list<string> values, - list<string> enums, bit opt = 0> : Argument<name, opt> { + list<string> enums, bit opt = 0, bit fake = 0> + : Argument<name, opt, fake> { string Type = type; list<string> Values = values; list<string> Enums = enums; @@ -241,14 +246,18 @@ def COnly : LangOpt<"CPlusPlus", 1>; class TargetArch<list<string> arches> { list<string> Arches = arches; list<string> OSes; + list<string> CXXABIs; } def TargetARM : TargetArch<["arm", "thumb"]>; +def TargetMips : TargetArch<["mips", "mipsel"]>; def TargetMSP430 : TargetArch<["msp430"]>; def TargetX86 : TargetArch<["x86"]>; def TargetWindows : TargetArch<["x86", "x86_64", "arm", "thumb"]> { let OSes = ["Win32"]; } -def TargetMips : TargetArch<["mips", "mipsel"]>; +def TargetMicrosoftCXXABI : TargetArch<["x86", "x86_64", "arm", "thumb"]> { + let CXXABIs = ["Microsoft"]; +} class Attr { // The various ways in which an attribute can be spelled in source @@ -286,6 +295,8 @@ class Attr { // attribute to be applicable. If empty, no language options are required. list<LangOpt> LangOpts = []; // Any additional text that should be included verbatim in the class. + // Note: Any additional data members will leak and should be constructed + // externally on the ASTContext. code AdditionalMembers = [{}]; // Any documentation that should be associated with the attribute. Since an // attribute may be documented under multiple categories, more than one @@ -415,8 +426,8 @@ def Annotate : InheritableParamAttr { } def ARMInterrupt : InheritableAttr, TargetSpecificAttr<TargetARM> { - // NOTE: If you add any additional spellings, MSP430Interrupt's spellings - // must match. + // NOTE: If you add any additional spellings, MSP430Interrupt's and + // MipsInterrupt's spellings must match. let Spellings = [GNU<"interrupt">]; let Args = [EnumArgument<"Interrupt", "InterruptType", ["IRQ", "FIQ", "SWI", "ABORT", "UNDEF", ""], @@ -445,8 +456,12 @@ def Availability : InheritableAttr { .Case("android", "Android") .Case("ios", "iOS") .Case("macosx", "OS X") + .Case("tvos", "tvOS") + .Case("watchos", "watchOS") .Case("ios_app_extension", "iOS (App Extension)") .Case("macosx_app_extension", "OS X (App Extension)") + .Case("tvos_app_extension", "tvOS (App Extension)") + .Case("watchos_app_extension", "watchOS (App Extension)") .Default(llvm::StringRef()); } }]; let HasCustomParsing = 1; @@ -553,6 +568,11 @@ def CUDAConstant : InheritableAttr { let Documentation = [Undocumented]; } +def CUDACudartBuiltin : IgnoredAttr { + let Spellings = [GNU<"cudart_builtin">]; + let LangOpts = [CUDA]; +} + def CUDADevice : InheritableAttr { let Spellings = [GNU<"device">]; let Subjects = SubjectList<[Function, Var]>; @@ -560,6 +580,21 @@ def CUDADevice : InheritableAttr { let Documentation = [Undocumented]; } +def CUDADeviceBuiltin : IgnoredAttr { + let Spellings = [GNU<"device_builtin">]; + let LangOpts = [CUDA]; +} + +def CUDADeviceBuiltinSurfaceType : IgnoredAttr { + let Spellings = [GNU<"device_builtin_surface_type">]; + let LangOpts = [CUDA]; +} + +def CUDADeviceBuiltinTextureType : IgnoredAttr { + let Spellings = [GNU<"device_builtin_texture_type">]; + let LangOpts = [CUDA]; +} + def CUDAGlobal : InheritableAttr { let Spellings = [GNU<"global">]; let Subjects = SubjectList<[Function]>; @@ -721,18 +756,6 @@ def FlagEnum : InheritableAttr { let Subjects = SubjectList<[Enum]>; let Documentation = [FlagEnumDocs]; let LangOpts = [COnly]; - let AdditionalMembers = [{ -private: - llvm::APInt FlagBits; -public: - llvm::APInt &getFlagBits() { - return FlagBits; - } - - const llvm::APInt &getFlagBits() const { - return FlagBits; - } -}]; } def Flatten : InheritableAttr { @@ -746,7 +769,7 @@ def Format : InheritableAttr { let Args = [IdentifierArgument<"Type">, IntArgument<"FormatIdx">, IntArgument<"FirstArg">]; let Subjects = SubjectList<[ObjCMethod, Block, HasFunctionProto], WarnDiag, - "ExpectedFunction">; + "ExpectedFunctionWithProtoType">; let Documentation = [FormatDocs]; } @@ -754,7 +777,7 @@ def FormatArg : InheritableAttr { let Spellings = [GCC<"format_arg">]; let Args = [IntArgument<"FormatIdx">]; let Subjects = SubjectList<[ObjCMethod, HasFunctionProto], WarnDiag, - "ExpectedFunction">; + "ExpectedFunctionWithProtoType">; let Documentation = [Undocumented]; } @@ -822,8 +845,8 @@ def MSABI : InheritableAttr { } def MSP430Interrupt : InheritableAttr, TargetSpecificAttr<TargetMSP430> { - // NOTE: If you add any additional spellings, ARMInterrupt's spellings must - // match. + // NOTE: If you add any additional spellings, ARMInterrupt's and + // MipsInterrupt's spellings must match. let Spellings = [GNU<"interrupt">]; let Args = [UnsignedArgument<"Number">]; let ParseKind = "Interrupt"; @@ -837,6 +860,22 @@ def Mips16 : InheritableAttr, TargetSpecificAttr<TargetMips> { let Documentation = [Undocumented]; } +def MipsInterrupt : InheritableAttr, TargetSpecificAttr<TargetMips> { + // NOTE: If you add any additional spellings, ARMInterrupt's and + // MSP430Interrupt's spellings must match. + let Spellings = [GNU<"interrupt">]; + let Subjects = SubjectList<[Function]>; + let Args = [EnumArgument<"Interrupt", "InterruptType", + ["vector=sw0", "vector=sw1", "vector=hw0", + "vector=hw1", "vector=hw2", "vector=hw3", + "vector=hw4", "vector=hw5", "eic", ""], + ["sw0", "sw1", "hw0", "hw1", "hw2", "hw3", + "hw4", "hw5", "eic", "eic"] + >]; + let ParseKind = "Interrupt"; + let Documentation = [MipsInterruptDocs]; +} + def Mode : Attr { let Spellings = [GCC<"mode">]; let Args = [IdentifierArgument<"Mode">]; @@ -867,6 +906,19 @@ def ReturnsTwice : InheritableAttr { let Documentation = [Undocumented]; } +def DisableTailCalls : InheritableAttr { + let Spellings = [GNU<"disable_tail_calls">, + CXX11<"clang", "disable_tail_calls">]; + let Subjects = SubjectList<[Function, ObjCMethod]>; + let Documentation = [DisableTailCallsDocs]; +} + +def NoAlias : InheritableAttr { + let Spellings = [Declspec<"noalias">]; + let Subjects = SubjectList<[Function]>; + let Documentation = [NoAliasDocs]; +} + def NoCommon : InheritableAttr { let Spellings = [GCC<"nocommon">]; let Subjects = SubjectList<[Var]>; @@ -960,6 +1012,15 @@ def ReturnsNonNull : InheritableAttr { let Documentation = [ReturnsNonNullDocs]; } +// pass_object_size(N) indicates that the parameter should have +// __builtin_object_size with Type=N evaluated on the parameter at the callsite. +def PassObjectSize : InheritableParamAttr { + let Spellings = [GNU<"pass_object_size">]; + let Args = [IntArgument<"Type">]; + let Subjects = SubjectList<[ParmVar]>; + let Documentation = [PassObjectSizeDocs]; +} + // Nullability type attributes. def TypeNonNull : TypeAttr { let Spellings = [Keyword<"_Nonnull">]; @@ -1000,11 +1061,22 @@ def NoInstrumentFunction : InheritableAttr { let Documentation = [Undocumented]; } +def NotTailCalled : InheritableAttr { + let Spellings = [GNU<"not_tail_called">, CXX11<"clang", "not_tail_called">]; + let Subjects = SubjectList<[Function]>; + let Documentation = [NotTailCalledDocs]; +} + def NoThrow : InheritableAttr { let Spellings = [GCC<"nothrow">, Declspec<"nothrow">]; let Documentation = [Undocumented]; } +def NvWeak : IgnoredAttr { + let Spellings = [GNU<"nv_weak">]; + let LangOpts = [CUDA]; +} + def ObjCBridge : InheritableAttr { let Spellings = [GNU<"objc_bridge">]; let Subjects = SubjectList<[Record, TypedefName], ErrorDiag, @@ -1024,8 +1096,8 @@ def ObjCBridgeRelated : InheritableAttr { let Spellings = [GNU<"objc_bridge_related">]; let Subjects = SubjectList<[Record], ErrorDiag>; let Args = [IdentifierArgument<"RelatedClass">, - IdentifierArgument<"ClassMethod">, - IdentifierArgument<"InstanceMethod">]; + IdentifierArgument<"ClassMethod", 1>, + IdentifierArgument<"InstanceMethod", 1>]; let HasCustomParsing = 1; let Documentation = [Undocumented]; } @@ -1169,7 +1241,8 @@ def Ownership : InheritableAttr { } }]; let Args = [IdentifierArgument<"Module">, VariadicUnsignedArgument<"Args">]; - let Subjects = SubjectList<[HasFunctionProto], WarnDiag, "ExpectedFunction">; + let Subjects = SubjectList<[HasFunctionProto], WarnDiag, + "ExpectedFunctionWithProtoType">; let Documentation = [Undocumented]; } @@ -1280,9 +1353,41 @@ def Pascal : InheritableAttr { def Target : InheritableAttr { let Spellings = [GCC<"target">]; - let Args = [StringArgument<"features">]; + let Args = [StringArgument<"featuresStr">]; let Subjects = SubjectList<[Function], ErrorDiag>; let Documentation = [TargetDocs]; + let AdditionalMembers = [{ + typedef std::pair<std::vector<std::string>, StringRef> ParsedTargetAttr; + ParsedTargetAttr parse() const { + ParsedTargetAttr Ret; + SmallVector<StringRef, 1> AttrFeatures; + getFeaturesStr().split(AttrFeatures, ","); + + // Grab the various features and prepend a "+" to turn on the feature to + // the backend and add them to our existing set of features. + for (auto &Feature : AttrFeatures) { + // Go ahead and trim whitespace rather than either erroring or + // accepting it weirdly. + Feature = Feature.trim(); + + // We don't support cpu tuning this way currently. + // TODO: Support the fpmath option. It will require checking + // overall feature validity for the function with the rest of the + // attributes on the function. + if (Feature.startswith("fpmath=") || Feature.startswith("tune=")) + continue; + + // While we're here iterating check for a different target cpu. + if (Feature.startswith("arch=")) + Ret.second = Feature.split("=").second.trim(); + else if (Feature.startswith("no-")) + Ret.first.push_back("-" + Feature.split("-").second.str()); + else + Ret.first.push_back("+" + Feature.str()); + } + return Ret; + } + }]; } def TransparentUnion : InheritableAttr { @@ -1293,7 +1398,15 @@ def TransparentUnion : InheritableAttr { def Unavailable : InheritableAttr { let Spellings = [GNU<"unavailable">]; - let Args = [StringArgument<"Message", 1>]; + let Args = [StringArgument<"Message", 1>, + EnumArgument<"ImplicitReason", "ImplicitReason", + ["", "", "", ""], + ["IR_None", + "IR_ARCForbiddenType", + "IR_ForbiddenWeak", + "IR_ARCForbiddenConversion", + "IR_ARCInitReturnsUnrelated", + "IR_ARCFieldWithOwnership"], 1, /*fake*/ 1>]; let Documentation = [Undocumented]; } @@ -1486,8 +1599,8 @@ def Capability : InheritableAttr { let Spellings = [GNU<"capability">, CXX11<"clang", "capability">, GNU<"shared_capability">, CXX11<"clang", "shared_capability">]; - let Subjects = SubjectList<[Struct, TypedefName], ErrorDiag, - "ExpectedStructOrTypedef">; + let Subjects = SubjectList<[Record, TypedefName], ErrorDiag, + "ExpectedStructOrUnionOrTypedef">; let Args = [StringArgument<"Name">]; let Accessors = [Accessor<"isShared", [GNU<"shared_capability">, @@ -1814,7 +1927,7 @@ def TypeTagForDatatype : InheritableAttr { // Microsoft-related attributes -def MSNoVTable : InheritableAttr { +def MSNoVTable : InheritableAttr, TargetSpecificAttr<TargetMicrosoftCXXABI> { let Spellings = [Declspec<"novtable">]; let Subjects = SubjectList<[CXXRecord]>; let Documentation = [MSNoVTableDocs]; @@ -1970,8 +2083,8 @@ def LoopHint : Attr { ["Vectorize", "VectorizeWidth", "Interleave", "InterleaveCount", "Unroll", "UnrollCount"]>, EnumArgument<"State", "LoopHintState", - ["default", "enable", "disable", "assume_safety"], - ["Default", "Enable", "Disable", "AssumeSafety"]>, + ["enable", "disable", "numeric", "assume_safety", "full"], + ["Enable", "Disable", "Numeric", "AssumeSafety", "Full"]>, ExprArgument<"Value">]; let AdditionalMembers = [{ @@ -1991,17 +2104,15 @@ def LoopHint : Attr { unsigned SpellingIndex = getSpellingListIndex(); // For "#pragma unroll" and "#pragma nounroll" the string "unroll" or // "nounroll" is already emitted as the pragma name. - if (SpellingIndex == Pragma_nounroll) { - OS << "\n"; + if (SpellingIndex == Pragma_nounroll) return; - } else if (SpellingIndex == Pragma_unroll) { - OS << getValueString(Policy) << "\n"; + OS << getValueString(Policy); return; } assert(SpellingIndex == Pragma_clang_loop && "Unexpected spelling"); - OS << getOptionName(option) << getValueString(Policy) << "\n"; + OS << getOptionName(option) << getValueString(Policy); } // Return a string containing the loop hint argument including the @@ -2010,13 +2121,12 @@ def LoopHint : Attr { std::string ValueName; llvm::raw_string_ostream OS(ValueName); OS << "("; - if (option == VectorizeWidth || option == InterleaveCount || - option == UnrollCount) + if (state == Numeric) value->printPretty(OS, nullptr, Policy); - else if (state == Default) - return ""; else if (state == Enable) - OS << (option == Unroll ? "full" : "enable"); + OS << "enable"; + else if (state == Full) + OS << "full"; else if (state == AssumeSafety) OS << "assume_safety"; else @@ -2031,7 +2141,7 @@ def LoopHint : Attr { if (SpellingIndex == Pragma_nounroll) return "#pragma nounroll"; else if (SpellingIndex == Pragma_unroll) - return "#pragma unroll" + getValueString(Policy); + return "#pragma unroll" + (option == UnrollCount ? getValueString(Policy) : ""); assert(SpellingIndex == Pragma_clang_loop && "Unexpected spelling"); return getOptionName(option) + getValueString(Policy); @@ -2054,3 +2164,9 @@ def OMPThreadPrivateDecl : InheritableAttr { let SemaHandler = 0; let Documentation = [Undocumented]; } + +def InternalLinkage : InheritableAttr { + let Spellings = [GNU<"internal_linkage">, CXX11<"clang", "internal_linkage">]; + let Subjects = SubjectList<[Var, Function, CXXRecord]>; + let Documentation = [InternalLinkageDocs]; +} diff --git a/contrib/llvm/tools/clang/include/clang/Basic/AttrDocs.td b/contrib/llvm/tools/clang/include/clang/Basic/AttrDocs.td index 4866016..2567d55 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/AttrDocs.td +++ b/contrib/llvm/tools/clang/include/clang/Basic/AttrDocs.td @@ -181,9 +181,9 @@ to enforce the provided alignment assumption. def EnableIfDocs : Documentation { let Category = DocCatFunction; let Content = [{ -.. Note:: Some features of this attribute are experimental. The meaning of
- multiple enable_if attributes on a single declaration is subject to change in
- a future version of clang. Also, the ABI is not standardized and the name
+.. Note:: Some features of this attribute are experimental. The meaning of + multiple enable_if attributes on a single declaration is subject to change in + a future version of clang. Also, the ABI is not standardized and the name mangling may change in future versions. To avoid that, use asm labels. The ``enable_if`` attribute can be placed on function declarations to control @@ -263,6 +263,103 @@ Query for this feature with ``__has_attribute(enable_if)``. }]; } +def PassObjectSizeDocs : Documentation { + let Category = DocCatVariable; // Technically it's a parameter doc, but eh. + let Content = [{ +.. Note:: The mangling of functions with parameters that are annotated with + ``pass_object_size`` is subject to change. You can get around this by + using ``__asm__("foo")`` to explicitly name your functions, thus preserving + your ABI; also, non-overloadable C functions with ``pass_object_size`` are + not mangled. + +The ``pass_object_size(Type)`` attribute can be placed on function parameters to +instruct clang to call ``__builtin_object_size(param, Type)`` at each callsite +of said function, and implicitly pass the result of this call in as an invisible +argument of type ``size_t`` directly after the parameter annotated with +``pass_object_size``. Clang will also replace any calls to +``__builtin_object_size(param, Type)`` in the function by said implicit +parameter. + +Example usage: + +.. code-block:: c + + int bzero1(char *const p __attribute__((pass_object_size(0)))) + __attribute__((noinline)) { + int i = 0; + for (/**/; i < (int)__builtin_object_size(p, 0); ++i) { + p[i] = 0; + } + return i; + } + + int main() { + char chars[100]; + int n = bzero1(&chars[0]); + assert(n == sizeof(chars)); + return 0; + } + +If successfully evaluating ``__builtin_object_size(param, Type)`` at the +callsite is not possible, then the "failed" value is passed in. So, using the +definition of ``bzero1`` from above, the following code would exit cleanly: + +.. code-block:: c + + int main2(int argc, char *argv[]) { + int n = bzero1(argv); + assert(n == -1); + return 0; + } + +``pass_object_size`` plays a part in overload resolution. If two overload +candidates are otherwise equally good, then the overload with one or more +parameters with ``pass_object_size`` is preferred. This implies that the choice +between two identical overloads both with ``pass_object_size`` on one or more +parameters will always be ambiguous; for this reason, having two such overloads +is illegal. For example: + +.. code-block:: c++ + + #define PS(N) __attribute__((pass_object_size(N))) + // OK + void Foo(char *a, char *b); // Overload A + // OK -- overload A has no parameters with pass_object_size. + void Foo(char *a PS(0), char *b PS(0)); // Overload B + // Error -- Same signature (sans pass_object_size) as overload B, and both + // overloads have one or more parameters with the pass_object_size attribute. + void Foo(void *a PS(0), void *b); + + // OK + void Bar(void *a PS(0)); // Overload C + // OK + void Bar(char *c PS(1)); // Overload D + + void main() { + char known[10], *unknown; + Foo(unknown, unknown); // Calls overload B + Foo(known, unknown); // Calls overload B + Foo(unknown, known); // Calls overload B + Foo(known, known); // Calls overload B + + Bar(known); // Calls overload D + Bar(unknown); // Calls overload D + } + +Currently, ``pass_object_size`` is a bit restricted in terms of its usage: + +* Only one use of ``pass_object_size`` is allowed per parameter. + +* It is an error to take the address of a function with ``pass_object_size`` on + any of its parameters. If you wish to do this, you can create an overload + without ``pass_object_size`` on any parameters. + +* It is an error to apply the ``pass_object_size`` attribute to parameters that + are not pointers. Additionally, any parameter that ``pass_object_size`` is + applied to must be marked ``const`` at its function's definition. + }]; +} + def OverloadableDocs : Documentation { let Category = DocCatFunction; let Content = [{ @@ -580,6 +677,14 @@ are: Apple's Mac OS X operating system. The minimum deployment target is specified by the ``-mmacosx-version-min=*version*`` command-line argument. +``tvos`` + Apple's tvOS operating system. The minimum deployment target is specified by + the ``-mtvos-version-min=*version*`` command-line argument. + +``watchos`` + 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 @@ -706,6 +811,46 @@ The semantics are as follows: }]; } +def MipsInterruptDocs : Documentation { + let Category = DocCatFunction; + let Content = [{ +Clang supports the GNU style ``__attribute__((interrupt("ARGUMENT")))`` attribute on +MIPS targets. This attribute may be attached to a function definition and instructs +the backend to generate appropriate function entry/exit code so that it can be used +directly as an interrupt service routine. + +By default, the compiler will produce a function prologue and epilogue suitable for +an interrupt service routine that handles an External Interrupt Controller (eic) +generated interrupt. This behaviour can be explicitly requested with the "eic" +argument. + +Otherwise, for use with vectored interrupt mode, the argument passed should be +of the form "vector=LEVEL" where LEVEL is one of the following values: +"sw0", "sw1", "hw0", "hw1", "hw2", "hw3", "hw4", "hw5". The compiler will +then set the interrupt mask to the corresponding level which will mask all +interrupts up to and including the argument. + +The semantics are as follows: + +- The prologue is modified so that the Exception Program Counter (EPC) and + Status coprocessor registers are saved to the stack. The interrupt mask is + set so that the function can only be interrupted by a higher priority + interrupt. The epilogue will restore the previous values of EPC and Status. + +- The prologue and epilogue are modified to save and restore all non-kernel + registers as necessary. + +- The FPU is disabled in the prologue, as the floating pointer registers are not + spilled to the stack. + +- The function return sequence is changed to use an exception return instruction. + +- The parameter sets the interrupt mask for the function corresponding to the + interrupt level specified. If no mask is specified the interrupt mask + defaults to "eic". + }]; +} + def TargetDocs : Documentation { let Category = DocCatFunction; let Content = [{ @@ -1328,7 +1473,7 @@ def MSNoVTableDocs : Documentation { let Content = [{ This attribute can be added to a class declaration or definition to signal to the compiler that constructors and destructors will not reference the virtual -function table. +function table. It is only supported when using the Microsoft C++ ABI. }]; } @@ -1371,7 +1516,9 @@ Loop unrolling optimization hints can be specified with ``#pragma unroll`` and do-while, or c++11 range-based for loop. Specifying ``#pragma unroll`` without a parameter directs the loop unroller to -attempt to fully unroll the loop if the trip count is known at compile time: +attempt to fully unroll the loop if the trip count is known at compile time and +attempt to partially unroll the loop if the trip count is not known at compile +time: .. code-block:: c++ @@ -1439,7 +1586,6 @@ More details can be found in the OpenCL C language Spec v2.0, Section 6.5. def OpenCLAddressSpaceGenericDocs : Documentation { let Category = DocOpenCLAddressSpaces; - let Heading = "__generic(generic)"; let Content = [{ The generic address space attribute is only available with OpenCL v2.0 and later. It can be used with pointer types. Variables in global and local scope and @@ -1452,7 +1598,6 @@ spaces. def OpenCLAddressSpaceConstantDocs : Documentation { let Category = DocOpenCLAddressSpaces; - let Heading = "__constant(constant)"; let Content = [{ The constant address space attribute signals that an object is located in a constant (non-modifiable) memory region. It is available to all work items. @@ -1464,7 +1609,6 @@ have an initializer. def OpenCLAddressSpaceGlobalDocs : Documentation { let Category = DocOpenCLAddressSpaces; - let Heading = "__global(global)"; let Content = [{ The global address space attribute specifies that an object is allocated in global memory, which is accessible by all work items. The content stored in this @@ -1477,7 +1621,6 @@ scope) variables and static local variable as well. def OpenCLAddressSpaceLocalDocs : Documentation { let Category = DocOpenCLAddressSpaces; - let Heading = "__local(local)"; let Content = [{ The local address space specifies that an object is allocated in the local (work group) memory area, which is accessible to all work items in the same work @@ -1490,7 +1633,6 @@ space are allowed. Local address space variables cannot have an initializer. def OpenCLAddressSpacePrivateDocs : Documentation { let Category = DocOpenCLAddressSpaces; - let Heading = "__private(private)"; let Content = [{ The private address space specifies that an object is allocated in the private (work item) memory. Other work items cannot access the same memory area and its @@ -1534,7 +1676,6 @@ In Objective-C, there is an alternate spelling for the nullability qualifiers th def TypeNonNullDocs : Documentation { let Category = NullabilityDocs; - let Heading = "_Nonnull"; let Content = [{ The ``_Nonnull`` nullability qualifier indicates that null is not a meaningful value for a value of the ``_Nonnull`` pointer type. For example, given a declaration such as: @@ -1548,7 +1689,6 @@ a caller of ``fetch`` should not provide a null value, and the compiler will pro def TypeNullableDocs : Documentation { let Category = NullabilityDocs; - let Heading = "_Nullable"; let Content = [{ The ``_Nullable`` nullability qualifier indicates that a value of the ``_Nullable`` pointer type can be null. For example, given: @@ -1562,7 +1702,6 @@ a caller of ``fetch_or_zero`` can provide null. def TypeNullUnspecifiedDocs : Documentation { let Category = NullabilityDocs; - let Heading = "_Null_unspecified"; let Content = [{ The ``_Null_unspecified`` nullability qualifier indicates that neither the ``_Nonnull`` nor ``_Nullable`` qualifiers make sense for a particular pointer type. It is used primarily to indicate that the role of null with specific pointers in a nullability-annotated header is unclear, e.g., due to overly-complex implementations or historical factors with a long-lived API. }]; @@ -1570,7 +1709,6 @@ The ``_Null_unspecified`` nullability qualifier indicates that neither the ``_No def NonNullDocs : Documentation { let Category = NullabilityDocs; - let Heading = "nonnull"; let Content = [{ The ``nonnull`` attribute indicates that some function parameters must not be null, and can be used in several different ways. It's original usage (`from GCC <https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#Common-Function-Attributes>`_) is as a function (or Objective-C method) attribute that specifies which parameters of the function are nonnull in a comma-separated list. For example: @@ -1600,7 +1738,6 @@ Note that the ``nonnull`` attribute indicates that passing null to a non-null pa def ReturnsNonNullDocs : Documentation { let Category = NullabilityDocs; - let Heading = "returns_nonnull"; let Content = [{ The ``returns_nonnull`` attribute indicates that a particular function (or Objective-C method) always returns a non-null pointer. For example, a particular system ``malloc`` might be defined to terminate a process when memory is not available rather than returning a null pointer: @@ -1611,3 +1748,114 @@ The ``returns_nonnull`` attribute indicates that a particular function (or Objec The ``returns_nonnull`` attribute implies that returning a null pointer is undefined behavior, which the optimizer may take advantage of. The ``_Nonnull`` type qualifier indicates that a pointer cannot be null in a more general manner (because it is part of the type system) and does not imply undefined behavior, making it more widely applicable }]; } + +def NoAliasDocs : Documentation { + let Category = DocCatFunction; + let Content = [{ +The ``noalias`` attribute indicates that the only memory accesses inside +function are loads and stores from objects pointed to by its pointer-typed +arguments, with arbitrary offsets. + }]; +} + +def NotTailCalledDocs : Documentation { + let Category = DocCatFunction; + let Content = [{ +The ``not_tail_called`` attribute prevents tail-call optimization on statically bound calls. It has no effect on indirect calls. Virtual functions, objective-c methods, and functions marked as ``always_inline`` cannot be marked as ``not_tail_called``. + +For example, it prevents tail-call optimization in the following case: + + .. code-block: c + + int __attribute__((not_tail_called)) foo1(int); + + int foo2(int a) { + return foo1(a); // No tail-call optimization on direct calls. + } + +However, it doesn't prevent tail-call optimization in this case: + + .. code-block: c + + int __attribute__((not_tail_called)) foo1(int); + + int foo2(int a) { + int (*fn)(int) = &foo1; + + // not_tail_called has no effect on an indirect call even if the call can be + // resolved at compile time. + return (*fn)(a); + } + +Marking virtual functions as ``not_tail_called`` is an error: + + .. code-block: c++ + + class Base { + public: + // not_tail_called on a virtual function is an error. + [[clang::not_tail_called]] virtual int foo1(); + + virtual int foo2(); + + // Non-virtual functions can be marked ``not_tail_called``. + [[clang::not_tail_called]] int foo3(); + }; + + class Derived1 : public Base { + public: + int foo1() override; + + // not_tail_called on a virtual function is an error. + [[clang::not_tail_called]] int foo2() override; + }; + }]; +} + +def InternalLinkageDocs : Documentation { + let Category = DocCatFunction; + let Content = [{ +The ``internal_linkage`` attribute changes the linkage type of the declaration to internal. +This is similar to C-style ``static``, but can be used on classes and class methods. When applied to a class definition, +this attribute affects all methods and static data members of that class. +This can be used to contain the ABI of a C++ library by excluding unwanted class methods from the export tables. + }]; +} + +def DisableTailCallsDocs : Documentation { + let Category = DocCatFunction; + let Content = [{ +The ``disable_tail_calls`` attribute instructs the backend to not perform tail call optimization inside the marked function. + +For example: + + .. code-block:: c + + int callee(int); + + int foo(int a) __attribute__((disable_tail_calls)) { + return callee(a); // This call is not tail-call optimized. + } + +Marking virtual functions as ``disable_tail_calls`` is legal. + + .. code-block: c++ + + int callee(int); + + class Base { + public: + [[clang::disable_tail_calls]] virtual int foo1() { + return callee(); // This call is not tail-call optimized. + } + }; + + class Derived1 : public Base { + public: + int foo1() override { + return callee(); // This call is tail-call optimized. + } + }; + + }]; +} diff --git a/contrib/llvm/tools/clang/include/clang/Basic/Attributes.h b/contrib/llvm/tools/clang/include/clang/Basic/Attributes.h index a64dd56..a2b8684 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/Attributes.h +++ b/contrib/llvm/tools/clang/include/clang/Basic/Attributes.h @@ -11,7 +11,7 @@ #define LLVM_CLANG_BASIC_ATTRIBUTES_H #include "clang/Basic/LangOptions.h" -#include "llvm/ADT/Triple.h" +#include "clang/Basic/TargetInfo.h" namespace clang { @@ -31,7 +31,7 @@ enum class AttrSyntax { /// \brief Return the version number associated with the attribute if we /// recognize and implement the attribute specified by the given information. int hasAttribute(AttrSyntax Syntax, const IdentifierInfo *Scope, - const IdentifierInfo *Attr, const llvm::Triple &T, + const IdentifierInfo *Attr, const TargetInfo &Target, const LangOptions &LangOpts); } // end namespace clang diff --git a/contrib/llvm/tools/clang/include/clang/Basic/Builtins.def b/contrib/llvm/tools/clang/include/clang/Basic/Builtins.def index bf65b5f..4f474eb 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/Builtins.def +++ b/contrib/llvm/tools/clang/include/clang/Basic/Builtins.def @@ -357,25 +357,25 @@ BUILTIN(__builtin_ctanhf, "XfXf", "Fnc") BUILTIN(__builtin_ctanhl, "XLdXLd", "Fnc") // FP Comparisons. -BUILTIN(__builtin_isgreater , "i.", "nc") -BUILTIN(__builtin_isgreaterequal, "i.", "nc") -BUILTIN(__builtin_isless , "i.", "nc") -BUILTIN(__builtin_islessequal , "i.", "nc") -BUILTIN(__builtin_islessgreater , "i.", "nc") -BUILTIN(__builtin_isunordered , "i.", "nc") +BUILTIN(__builtin_isgreater , "i.", "Fnc") +BUILTIN(__builtin_isgreaterequal, "i.", "Fnc") +BUILTIN(__builtin_isless , "i.", "Fnc") +BUILTIN(__builtin_islessequal , "i.", "Fnc") +BUILTIN(__builtin_islessgreater , "i.", "Fnc") +BUILTIN(__builtin_isunordered , "i.", "Fnc") // Unary FP classification -BUILTIN(__builtin_fpclassify, "iiiii.", "nc") -BUILTIN(__builtin_isfinite, "i.", "nc") -BUILTIN(__builtin_isinf, "i.", "nc") -BUILTIN(__builtin_isinf_sign, "i.", "nc") -BUILTIN(__builtin_isnan, "i.", "nc") -BUILTIN(__builtin_isnormal, "i.", "nc") +BUILTIN(__builtin_fpclassify, "iiiii.", "Fnc") +BUILTIN(__builtin_isfinite, "i.", "Fnc") +BUILTIN(__builtin_isinf, "i.", "Fnc") +BUILTIN(__builtin_isinf_sign, "i.", "Fnc") +BUILTIN(__builtin_isnan, "i.", "Fnc") +BUILTIN(__builtin_isnormal, "i.", "Fnc") // FP signbit builtins -BUILTIN(__builtin_signbit, "id", "nc") -BUILTIN(__builtin_signbitf, "if", "nc") -BUILTIN(__builtin_signbitl, "iLd", "nc") +BUILTIN(__builtin_signbit, "i.", "Fnc") +BUILTIN(__builtin_signbitf, "if", "Fnc") +BUILTIN(__builtin_signbitl, "iLd", "Fnc") // Builtins for arithmetic. BUILTIN(__builtin_clzs , "iUs" , "nc") @@ -388,9 +388,9 @@ BUILTIN(__builtin_ctz , "iUi" , "nc") BUILTIN(__builtin_ctzl , "iULi" , "nc") BUILTIN(__builtin_ctzll, "iULLi", "nc") // TODO: int ctzimax(uintmax_t) -BUILTIN(__builtin_ffs , "ii" , "nc") -BUILTIN(__builtin_ffsl , "iLi" , "nc") -BUILTIN(__builtin_ffsll, "iLLi", "nc") +BUILTIN(__builtin_ffs , "ii" , "Fnc") +BUILTIN(__builtin_ffsl , "iLi" , "Fnc") +BUILTIN(__builtin_ffsll, "iLLi", "Fnc") BUILTIN(__builtin_parity , "iUi" , "nc") BUILTIN(__builtin_parityl , "iULi" , "nc") BUILTIN(__builtin_parityll, "iULLi", "nc") @@ -414,7 +414,7 @@ BUILTIN(__builtin_va_end, "vA", "n") BUILTIN(__builtin_va_copy, "vAA", "n") BUILTIN(__builtin_stdarg_start, "vA.", "n") BUILTIN(__builtin_assume_aligned, "v*vC*z.", "nc") -BUILTIN(__builtin_bcmp, "iv*v*z", "n") +BUILTIN(__builtin_bcmp, "iv*v*z", "Fn") BUILTIN(__builtin_bcopy, "vv*v*z", "n") BUILTIN(__builtin_bzero, "vv*z", "nF") BUILTIN(__builtin_fprintf, "iP*cC*.", "Fp:1:") @@ -489,6 +489,7 @@ BUILTIN(__builtin___printf_chk, "iicC*.", "Fp:1:") BUILTIN(__builtin___vfprintf_chk, "iP*icC*a", "FP:2:") BUILTIN(__builtin___vprintf_chk, "iicC*a", "FP:1:") +BUILTIN(__builtin_unpredictable, "LiLi" , "nc") BUILTIN(__builtin_expect, "LiLiLi" , "nc") BUILTIN(__builtin_prefetch, "vvC*.", "nc") BUILTIN(__builtin_readcyclecounter, "ULLi", "n") @@ -497,7 +498,7 @@ BUILTIN(__builtin_debugtrap, "v", "n") BUILTIN(__builtin_unreachable, "v", "nr") BUILTIN(__builtin_shufflevector, "v." , "nc") BUILTIN(__builtin_convertvector, "v." , "nct") -BUILTIN(__builtin_alloca, "v*z" , "n") +BUILTIN(__builtin_alloca, "v*z" , "Fn") BUILTIN(__builtin_call_with_static_chain, "v.", "nt") // "Overloaded" Atomic operator builtins. These are overloaded to support data @@ -1216,6 +1217,9 @@ BUILTIN(__builtin_subcl, "ULiULiCULiCULiCULi*", "n") BUILTIN(__builtin_subcll, "ULLiULLiCULLiCULLiCULLi*", "n") // Checked Arithmetic Builtins for Security. +BUILTIN(__builtin_add_overflow, "v.", "nt") +BUILTIN(__builtin_sub_overflow, "v.", "nt") +BUILTIN(__builtin_mul_overflow, "v.", "nt") BUILTIN(__builtin_uadd_overflow, "bUiCUiCUi*", "n") BUILTIN(__builtin_uaddl_overflow, "bULiCULiCULi*", "n") BUILTIN(__builtin_uaddll_overflow, "bULLiCULLiCULLi*", "n") @@ -1244,6 +1248,10 @@ BUILTIN(__builtin_operator_delete, "vv*", "n") BUILTIN(__builtin___get_unsafe_stack_start, "v*", "Fn") BUILTIN(__builtin___get_unsafe_stack_ptr, "v*", "Fn") +// Nontemporal loads/stores builtins +BUILTIN(__builtin_nontemporal_store, "v.", "t") +BUILTIN(__builtin_nontemporal_load, "v.", "t") + #undef BUILTIN #undef LIBBUILTIN #undef LANGBUILTIN diff --git a/contrib/llvm/tools/clang/include/clang/Basic/Builtins.h b/contrib/llvm/tools/clang/include/clang/Basic/Builtins.h index 27428ad..41f19e7 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/Builtins.h +++ b/contrib/llvm/tools/clang/include/clang/Basic/Builtins.h @@ -16,7 +16,7 @@ #ifndef LLVM_CLANG_BASIC_BUILTINS_H #define LLVM_CLANG_BASIC_BUILTINS_H -#include "clang/Basic/LLVM.h" +#include "llvm/ADT/ArrayRef.h" #include <cstring> // VC++ defines 'alloca' as an object-like macro, which interferes with our @@ -24,22 +24,22 @@ #undef alloca namespace clang { - class TargetInfo; - class IdentifierTable; - class ASTContext; - 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. - 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. - }; +class TargetInfo; +class IdentifierTable; +class ASTContext; +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. + 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. +}; namespace Builtin { enum ID { @@ -51,112 +51,114 @@ enum ID { struct Info { const char *Name, *Type, *Attributes, *HeaderName; - LanguageID builtin_lang; - - bool operator==(const Info &RHS) const { - return !strcmp(Name, RHS.Name) && - !strcmp(Type, RHS.Type) && - !strcmp(Attributes, RHS.Attributes); - } - bool operator!=(const Info &RHS) const { return !(*this == RHS); } + LanguageID Langs; + const char *Features; }; /// \brief Holds information about both target-independent and /// target-specific builtins, allowing easy queries by clients. +/// +/// Builtins from an optional auxiliary target are stored in +/// AuxTSRecords. Their IDs are shifted up by TSRecords.size() and need to +/// be translated back with getAuxBuiltinID() before use. class Context { - const Info *TSRecords; - unsigned NumTSRecords; + llvm::ArrayRef<Info> TSRecords; + llvm::ArrayRef<Info> AuxTSRecords; + public: - Context(); + Context() {} /// \brief Perform target-specific initialization - void InitializeTarget(const TargetInfo &Target); - + /// \param AuxTarget Target info to incorporate builtins from. May be nullptr. + void InitializeTarget(const TargetInfo &Target, const TargetInfo *AuxTarget); + /// \brief Mark the identifiers for all the builtins with their /// appropriate builtin ID # and mark any non-portable builtin identifiers as /// such. - void InitializeBuiltins(IdentifierTable &Table, const LangOptions& LangOpts); - - /// \brief Populate the vector with the names of all of the builtins. - void GetBuiltinNames(SmallVectorImpl<const char *> &Names); + void initializeBuiltins(IdentifierTable &Table, const LangOptions& LangOpts); /// \brief Return the identifier name for the specified builtin, /// e.g. "__builtin_abs". - const char *GetName(unsigned ID) const { - return GetRecord(ID).Name; + const char *getName(unsigned ID) const { + return getRecord(ID).Name; } /// \brief Get the type descriptor string for the specified builtin. - const char *GetTypeString(unsigned ID) const { - return GetRecord(ID).Type; + const char *getTypeString(unsigned ID) const { + return getRecord(ID).Type; + } + + /// \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 and doesn't /// read memory. bool isConst(unsigned ID) const { - return strchr(GetRecord(ID).Attributes, 'c') != nullptr; + return strchr(getRecord(ID).Attributes, 'c') != nullptr; } /// \brief Return true if we know this builtin never throws an exception. bool isNoThrow(unsigned ID) const { - return strchr(GetRecord(ID).Attributes, 'n') != nullptr; + return strchr(getRecord(ID).Attributes, 'n') != nullptr; } /// \brief Return true if we know this builtin never returns. bool isNoReturn(unsigned ID) const { - return strchr(GetRecord(ID).Attributes, 'r') != nullptr; + return strchr(getRecord(ID).Attributes, 'r') != nullptr; } /// \brief Return true if we know this builtin can return twice. bool isReturnsTwice(unsigned ID) const { - return strchr(GetRecord(ID).Attributes, 'j') != nullptr; + return strchr(getRecord(ID).Attributes, 'j') != nullptr; } /// \brief Returns true if this builtin does not perform the side-effects /// of its arguments. bool isUnevaluated(unsigned ID) const { - return strchr(GetRecord(ID).Attributes, 'u') != nullptr; + return strchr(getRecord(ID).Attributes, 'u') != nullptr; } /// \brief Return true if this is a builtin for a libc/libm function, /// with a "__builtin_" prefix (e.g. __builtin_abs). bool isLibFunction(unsigned ID) const { - return strchr(GetRecord(ID).Attributes, 'F') != nullptr; + return strchr(getRecord(ID).Attributes, 'F') != nullptr; } /// \brief Determines whether this builtin is a predefined libc/libm /// function, such as "malloc", where we know the signature a /// priori. bool isPredefinedLibFunction(unsigned ID) const { - return strchr(GetRecord(ID).Attributes, 'f') != nullptr; + return strchr(getRecord(ID).Attributes, 'f') != nullptr; } /// \brief Determines whether this builtin is a predefined compiler-rt/libgcc /// function, such as "__clear_cache", where we know the signature a /// priori. bool isPredefinedRuntimeFunction(unsigned ID) const { - return strchr(GetRecord(ID).Attributes, 'i') != nullptr; + return strchr(getRecord(ID).Attributes, 'i') != nullptr; } /// \brief Determines whether this builtin has custom typechecking. bool hasCustomTypechecking(unsigned ID) const { - return strchr(GetRecord(ID).Attributes, 't') != nullptr; + return strchr(getRecord(ID).Attributes, 't') != nullptr; } /// \brief Determines whether this builtin has a result or any arguments which /// are pointer types. bool hasPtrArgsOrResult(unsigned ID) const { - return strchr(GetRecord(ID).Type, '*') != nullptr; + return strchr(getRecord(ID).Type, '*') != nullptr; } /// \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); + 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 { - return GetRecord(ID).HeaderName; + return getRecord(ID).HeaderName; } /// \brief Determine whether this builtin is like printf in its @@ -174,14 +176,27 @@ public: /// /// Such functions can be const when the MathErrno lang option is disabled. bool isConstWithoutErrno(unsigned ID) const { - return strchr(GetRecord(ID).Attributes, 'e') != nullptr; + return strchr(getRecord(ID).Attributes, 'e') != nullptr; + } + + const char *getRequiredFeatures(unsigned ID) const { + return getRecord(ID).Features; + } + + /// \brief Return true if builtin ID belongs to AuxTarget. + bool isAuxBuiltinID(unsigned ID) const { + return ID >= (Builtin::FirstTSBuiltin + TSRecords.size()); } + /// Return real buitin ID (i.e. ID it would have furing compilation + /// for AuxTarget). + unsigned getAuxBuiltinID(unsigned ID) const { return ID - TSRecords.size(); } + private: - const Info &GetRecord(unsigned ID) const; + const Info &getRecord(unsigned ID) const; /// \brief Is this builtin supported according to the given language options? - bool BuiltinIsSupported(const Builtin::Info &BuiltinInfo, + bool builtinIsSupported(const Builtin::Info &BuiltinInfo, const LangOptions &LangOpts); /// \brief Helper function for isPrintfLike and isScanfLike. @@ -190,5 +205,12 @@ private: }; } + +/// \brief Kinds of BuiltinTemplateDecl. +enum BuiltinTemplateKind : int { + /// \brief This names the __make_integer_seq BuiltinTemplateDecl. + BTK__make_integer_seq +}; + } // end namespace clang #endif diff --git a/contrib/llvm/tools/clang/include/clang/Basic/BuiltinsAArch64.def b/contrib/llvm/tools/clang/include/clang/Basic/BuiltinsAArch64.def index 1db4c14..b440443 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/BuiltinsAArch64.def +++ b/contrib/llvm/tools/clang/include/clang/Basic/BuiltinsAArch64.def @@ -60,5 +60,6 @@ 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/contrib/llvm/tools/clang/include/clang/Basic/BuiltinsARM.def b/contrib/llvm/tools/clang/include/clang/Basic/BuiltinsARM.def index c9cdb4b..3e8e2bf 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/BuiltinsARM.def +++ b/contrib/llvm/tools/clang/include/clang/Basic/BuiltinsARM.def @@ -48,14 +48,14 @@ BUILTIN(__builtin_arm_vcvtr_f, "ffi", "nc") BUILTIN(__builtin_arm_vcvtr_d, "fdi", "nc") // Coprocessor -BUILTIN(__builtin_arm_mcr, "vUiUiUiUiUiUi", "") -BUILTIN(__builtin_arm_mcr2, "vUiUiUiUiUiUi", "") -BUILTIN(__builtin_arm_mrc, "UiUiUiUiUiUi", "") -BUILTIN(__builtin_arm_mrc2, "UiUiUiUiUiUi", "") +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, "vUiUiUiUiUi", "") -BUILTIN(__builtin_arm_mcrr2, "vUiUiUiUiUi", "") +BUILTIN(__builtin_arm_mcrr, "vUIiUIiUiUiUIi", "") +BUILTIN(__builtin_arm_mcrr2, "vUIiUIiUiUiUIi", "") // CRC32 BUILTIN(__builtin_arm_crc32b, "UiUiUc", "nc") diff --git a/contrib/llvm/tools/clang/include/clang/Basic/BuiltinsNVPTX.def b/contrib/llvm/tools/clang/include/clang/Basic/BuiltinsNVPTX.def index 970f55f..3ab6413 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/BuiltinsNVPTX.def +++ b/contrib/llvm/tools/clang/include/clang/Basic/BuiltinsNVPTX.def @@ -50,7 +50,7 @@ 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, "Li", "n") +BUILTIN(__builtin_ptx_read_clock64, "LLi", "n") BUILTIN(__builtin_ptx_read_pm0, "i", "n") BUILTIN(__builtin_ptx_read_pm1, "i", "n") @@ -453,6 +453,9 @@ BUILTIN(__nvvm_atom_add_gen_ll, "LLiLLiD*LLi", "n") BUILTIN(__nvvm_atom_add_g_f, "ffD*1f", "n") BUILTIN(__nvvm_atom_add_s_f, "ffD*3f", "n") BUILTIN(__nvvm_atom_add_gen_f, "ffD*f", "n") +BUILTIN(__nvvm_atom_add_g_d, "ddD*1d", "n") +BUILTIN(__nvvm_atom_add_s_d, "ddD*3d", "n") +BUILTIN(__nvvm_atom_add_gen_d, "ddD*d", "n") BUILTIN(__nvvm_atom_sub_g_i, "iiD*1i", "n") BUILTIN(__nvvm_atom_sub_s_i, "iiD*3i", "n") diff --git a/contrib/llvm/tools/clang/include/clang/Basic/BuiltinsPPC.def b/contrib/llvm/tools/clang/include/clang/Basic/BuiltinsPPC.def index fdf1cb0..5681c1f2 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/BuiltinsPPC.def +++ b/contrib/llvm/tools/clang/include/clang/Basic/BuiltinsPPC.def @@ -17,6 +17,8 @@ // The format of this database matches clang/Basic/Builtins.def. +BUILTIN(__builtin_ppc_get_timebase, "ULLi", "n") + // This is just a placeholder, the types and attributes are wrong. BUILTIN(__builtin_altivec_vaddcuw, "V4UiV4UiV4Ui", "") @@ -278,12 +280,21 @@ BUILTIN(__builtin_vsx_xvrspip, "V4fV4f", "") BUILTIN(__builtin_vsx_xvcmpeqdp, "V2ULLiV2dV2d", "") BUILTIN(__builtin_vsx_xvcmpeqsp, "V4UiV4fV4f", "") +BUILTIN(__builtin_vsx_xvcmpeqdp_p, "iiV2dV2d", "") +BUILTIN(__builtin_vsx_xvcmpeqsp_p, "iiV4fV4f", "") + BUILTIN(__builtin_vsx_xvcmpgedp, "V2ULLiV2dV2d", "") BUILTIN(__builtin_vsx_xvcmpgesp, "V4UiV4fV4f", "") +BUILTIN(__builtin_vsx_xvcmpgedp_p, "iiV2dV2d", "") +BUILTIN(__builtin_vsx_xvcmpgesp_p, "iiV4fV4f", "") + BUILTIN(__builtin_vsx_xvcmpgtdp, "V2ULLiV2dV2d", "") BUILTIN(__builtin_vsx_xvcmpgtsp, "V4UiV4fV4f", "") +BUILTIN(__builtin_vsx_xvcmpgtdp_p, "iiV2dV2d", "") +BUILTIN(__builtin_vsx_xvcmpgtsp_p, "iiV4fV4f", "") + BUILTIN(__builtin_vsx_xvrdpim, "V2dV2d", "") BUILTIN(__builtin_vsx_xvrspim, "V4fV4f", "") diff --git a/contrib/llvm/tools/clang/include/clang/Basic/BuiltinsWebAssembly.def b/contrib/llvm/tools/clang/include/clang/Basic/BuiltinsWebAssembly.def new file mode 100644 index 0000000..9754335 --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/Basic/BuiltinsWebAssembly.def @@ -0,0 +1,24 @@ +// BuiltinsWebAssembly.def - WebAssembly builtin function database -*- C++ -*-// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// \brief This file defines the WebAssembly-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. + +// Note that memory_size 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_grow_memory, "vz", "n") + +#undef BUILTIN diff --git a/contrib/llvm/tools/clang/include/clang/Basic/BuiltinsX86.def b/contrib/llvm/tools/clang/include/clang/Basic/BuiltinsX86.def index 1cd8973..91111f6 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/BuiltinsX86.def +++ b/contrib/llvm/tools/clang/include/clang/Basic/BuiltinsX86.def @@ -14,14 +14,15 @@ // The format of this database matches clang/Basic/Builtins.def. -// FIXME: In GCC, these builtins are defined depending on whether support for -// MMX/SSE/etc is turned on. We should do this too. - // FIXME: Ideally we would be able to pull this information from what // LLVM already knows about X86 builtins. We need to match the LLVM // definition anyway, since code generation will lower to the // intrinsic if one exists. +#if defined(BUILTIN) && !defined(TARGET_BUILTIN) +# define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) BUILTIN(ID, TYPE, ATTRS) +#endif + // FIXME: Are these nothrow/const? // Miscellaneous builtin for checking x86 cpu features. @@ -29,35 +30,46 @@ // can use it? BUILTIN(__builtin_cpu_supports, "bcC*", "nc") +// Win64-compatible va_list functions +BUILTIN(__builtin_ms_va_start, "vc*&.", "nt") +BUILTIN(__builtin_ms_va_end, "vc*&", "n") +BUILTIN(__builtin_ms_va_copy, "vc*&c*&", "n") + +// Undefined Values +// +TARGET_BUILTIN(__builtin_ia32_undef128, "V2d", "nc", "") +TARGET_BUILTIN(__builtin_ia32_undef256, "V4d", "nc", "") +TARGET_BUILTIN(__builtin_ia32_undef512, "V8d", "nc", "") + // 3DNow! // -BUILTIN(__builtin_ia32_femms, "v", "") -BUILTIN(__builtin_ia32_pavgusb, "V8cV8cV8c", "nc") -BUILTIN(__builtin_ia32_pf2id, "V2iV2f", "nc") -BUILTIN(__builtin_ia32_pfacc, "V2fV2fV2f", "nc") -BUILTIN(__builtin_ia32_pfadd, "V2fV2fV2f", "nc") -BUILTIN(__builtin_ia32_pfcmpeq, "V2iV2fV2f", "nc") -BUILTIN(__builtin_ia32_pfcmpge, "V2iV2fV2f", "nc") -BUILTIN(__builtin_ia32_pfcmpgt, "V2iV2fV2f", "nc") -BUILTIN(__builtin_ia32_pfmax, "V2fV2fV2f", "nc") -BUILTIN(__builtin_ia32_pfmin, "V2fV2fV2f", "nc") -BUILTIN(__builtin_ia32_pfmul, "V2fV2fV2f", "nc") -BUILTIN(__builtin_ia32_pfrcp, "V2fV2f", "nc") -BUILTIN(__builtin_ia32_pfrcpit1, "V2fV2fV2f", "nc") -BUILTIN(__builtin_ia32_pfrcpit2, "V2fV2fV2f", "nc") -BUILTIN(__builtin_ia32_pfrsqrt, "V2fV2f", "nc") -BUILTIN(__builtin_ia32_pfrsqit1, "V2fV2fV2f", "nc") -BUILTIN(__builtin_ia32_pfsub, "V2fV2fV2f", "nc") -BUILTIN(__builtin_ia32_pfsubr, "V2fV2fV2f", "nc") -BUILTIN(__builtin_ia32_pi2fd, "V2fV2i", "nc") -BUILTIN(__builtin_ia32_pmulhrw, "V4sV4sV4s", "nc") +TARGET_BUILTIN(__builtin_ia32_femms, "v", "", "3dnow") +TARGET_BUILTIN(__builtin_ia32_pavgusb, "V8cV8cV8c", "nc", "3dnow") +TARGET_BUILTIN(__builtin_ia32_pf2id, "V2iV2f", "nc", "3dnow") +TARGET_BUILTIN(__builtin_ia32_pfacc, "V2fV2fV2f", "nc", "3dnow") +TARGET_BUILTIN(__builtin_ia32_pfadd, "V2fV2fV2f", "nc", "3dnow") +TARGET_BUILTIN(__builtin_ia32_pfcmpeq, "V2iV2fV2f", "nc", "3dnow") +TARGET_BUILTIN(__builtin_ia32_pfcmpge, "V2iV2fV2f", "nc", "3dnow") +TARGET_BUILTIN(__builtin_ia32_pfcmpgt, "V2iV2fV2f", "nc", "3dnow") +TARGET_BUILTIN(__builtin_ia32_pfmax, "V2fV2fV2f", "nc", "3dnow") +TARGET_BUILTIN(__builtin_ia32_pfmin, "V2fV2fV2f", "nc", "3dnow") +TARGET_BUILTIN(__builtin_ia32_pfmul, "V2fV2fV2f", "nc", "3dnow") +TARGET_BUILTIN(__builtin_ia32_pfrcp, "V2fV2f", "nc", "3dnow") +TARGET_BUILTIN(__builtin_ia32_pfrcpit1, "V2fV2fV2f", "nc", "3dnow") +TARGET_BUILTIN(__builtin_ia32_pfrcpit2, "V2fV2fV2f", "nc", "3dnow") +TARGET_BUILTIN(__builtin_ia32_pfrsqrt, "V2fV2f", "nc", "3dnow") +TARGET_BUILTIN(__builtin_ia32_pfrsqit1, "V2fV2fV2f", "nc", "3dnow") +TARGET_BUILTIN(__builtin_ia32_pfsub, "V2fV2fV2f", "nc", "3dnow") +TARGET_BUILTIN(__builtin_ia32_pfsubr, "V2fV2fV2f", "nc", "3dnow") +TARGET_BUILTIN(__builtin_ia32_pi2fd, "V2fV2i", "nc", "3dnow") +TARGET_BUILTIN(__builtin_ia32_pmulhrw, "V4sV4sV4s", "nc", "3dnow") // 3DNow! Extensions (3dnowa). -BUILTIN(__builtin_ia32_pf2iw, "V2iV2f", "nc") -BUILTIN(__builtin_ia32_pfnacc, "V2fV2fV2f", "nc") -BUILTIN(__builtin_ia32_pfpnacc, "V2fV2fV2f", "nc") -BUILTIN(__builtin_ia32_pi2fw, "V2fV2i", "nc") -BUILTIN(__builtin_ia32_pswapdsf, "V2fV2f", "nc") -BUILTIN(__builtin_ia32_pswapdsi, "V2iV2i", "nc") +TARGET_BUILTIN(__builtin_ia32_pf2iw, "V2iV2f", "nc", "3dnowa") +TARGET_BUILTIN(__builtin_ia32_pfnacc, "V2fV2fV2f", "nc", "3dnowa") +TARGET_BUILTIN(__builtin_ia32_pfpnacc, "V2fV2fV2f", "nc", "3dnowa") +TARGET_BUILTIN(__builtin_ia32_pi2fw, "V2fV2i", "nc", "3dnowa") +TARGET_BUILTIN(__builtin_ia32_pswapdsf, "V2fV2f", "nc", "3dnowa") +TARGET_BUILTIN(__builtin_ia32_pswapdsi, "V2iV2i", "nc", "3dnowa") // MMX // @@ -67,1155 +79,1489 @@ BUILTIN(__builtin_ia32_pswapdsi, "V2iV2i", "nc") // FIXME: _mm_prefetch must be a built-in because it takes a compile-time constant // argument and our prior approach of using a #define to the current built-in // doesn't work in the presence of re-declaration of _mm_prefetch for windows. -BUILTIN(_mm_prefetch, "vcC*i", "nc") -BUILTIN(__builtin_ia32_emms, "v", "") -BUILTIN(__builtin_ia32_paddb, "V8cV8cV8c", "") -BUILTIN(__builtin_ia32_paddw, "V4sV4sV4s", "") -BUILTIN(__builtin_ia32_paddd, "V2iV2iV2i", "") -BUILTIN(__builtin_ia32_paddsb, "V8cV8cV8c", "") -BUILTIN(__builtin_ia32_paddsw, "V4sV4sV4s", "") -BUILTIN(__builtin_ia32_paddusb, "V8cV8cV8c", "") -BUILTIN(__builtin_ia32_paddusw, "V4sV4sV4s", "") -BUILTIN(__builtin_ia32_psubb, "V8cV8cV8c", "") -BUILTIN(__builtin_ia32_psubw, "V4sV4sV4s", "") -BUILTIN(__builtin_ia32_psubd, "V2iV2iV2i", "") -BUILTIN(__builtin_ia32_psubsb, "V8cV8cV8c", "") -BUILTIN(__builtin_ia32_psubsw, "V4sV4sV4s", "") -BUILTIN(__builtin_ia32_psubusb, "V8cV8cV8c", "") -BUILTIN(__builtin_ia32_psubusw, "V4sV4sV4s", "") -BUILTIN(__builtin_ia32_pmulhw, "V4sV4sV4s", "") -BUILTIN(__builtin_ia32_pmullw, "V4sV4sV4s", "") -BUILTIN(__builtin_ia32_pmaddwd, "V2iV4sV4s", "") -BUILTIN(__builtin_ia32_pand, "V1LLiV1LLiV1LLi", "") -BUILTIN(__builtin_ia32_pandn, "V1LLiV1LLiV1LLi", "") -BUILTIN(__builtin_ia32_por, "V1LLiV1LLiV1LLi", "") -BUILTIN(__builtin_ia32_pxor, "V1LLiV1LLiV1LLi", "") -BUILTIN(__builtin_ia32_psllw, "V4sV4sV1LLi", "") -BUILTIN(__builtin_ia32_pslld, "V2iV2iV1LLi", "") -BUILTIN(__builtin_ia32_psllq, "V1LLiV1LLiV1LLi", "") -BUILTIN(__builtin_ia32_psrlw, "V4sV4sV1LLi", "") -BUILTIN(__builtin_ia32_psrld, "V2iV2iV1LLi", "") -BUILTIN(__builtin_ia32_psrlq, "V1LLiV1LLiV1LLi", "") -BUILTIN(__builtin_ia32_psraw, "V4sV4sV1LLi", "") -BUILTIN(__builtin_ia32_psrad, "V2iV2iV1LLi", "") -BUILTIN(__builtin_ia32_psllwi, "V4sV4si", "") -BUILTIN(__builtin_ia32_pslldi, "V2iV2ii", "") -BUILTIN(__builtin_ia32_psllqi, "V1LLiV1LLii", "") -BUILTIN(__builtin_ia32_psrlwi, "V4sV4si", "") -BUILTIN(__builtin_ia32_psrldi, "V2iV2ii", "") -BUILTIN(__builtin_ia32_psrlqi, "V1LLiV1LLii", "") -BUILTIN(__builtin_ia32_psrawi, "V4sV4si", "") -BUILTIN(__builtin_ia32_psradi, "V2iV2ii", "") -BUILTIN(__builtin_ia32_packsswb, "V8cV4sV4s", "") -BUILTIN(__builtin_ia32_packssdw, "V4sV2iV2i", "") -BUILTIN(__builtin_ia32_packuswb, "V8cV4sV4s", "") -BUILTIN(__builtin_ia32_punpckhbw, "V8cV8cV8c", "") -BUILTIN(__builtin_ia32_punpckhwd, "V4sV4sV4s", "") -BUILTIN(__builtin_ia32_punpckhdq, "V2iV2iV2i", "") -BUILTIN(__builtin_ia32_punpcklbw, "V8cV8cV8c", "") -BUILTIN(__builtin_ia32_punpcklwd, "V4sV4sV4s", "") -BUILTIN(__builtin_ia32_punpckldq, "V2iV2iV2i", "") -BUILTIN(__builtin_ia32_pcmpeqb, "V8cV8cV8c", "") -BUILTIN(__builtin_ia32_pcmpeqw, "V4sV4sV4s", "") -BUILTIN(__builtin_ia32_pcmpeqd, "V2iV2iV2i", "") -BUILTIN(__builtin_ia32_pcmpgtb, "V8cV8cV8c", "") -BUILTIN(__builtin_ia32_pcmpgtw, "V4sV4sV4s", "") -BUILTIN(__builtin_ia32_pcmpgtd, "V2iV2iV2i", "") -BUILTIN(__builtin_ia32_maskmovq, "vV8cV8cc*", "") -BUILTIN(__builtin_ia32_movntq, "vV1LLi*V1LLi", "") -BUILTIN(__builtin_ia32_vec_init_v2si, "V2iii", "") -BUILTIN(__builtin_ia32_vec_init_v4hi, "V4sssss", "") -BUILTIN(__builtin_ia32_vec_init_v8qi, "V8ccccccccc", "") -BUILTIN(__builtin_ia32_vec_ext_v2si, "iV2ii", "") +TARGET_BUILTIN(_mm_prefetch, "vcC*i", "nc", "mmx") +TARGET_BUILTIN(__builtin_ia32_emms, "v", "", "mmx") +TARGET_BUILTIN(__builtin_ia32_paddb, "V8cV8cV8c", "", "mmx") +TARGET_BUILTIN(__builtin_ia32_paddw, "V4sV4sV4s", "", "mmx") +TARGET_BUILTIN(__builtin_ia32_paddd, "V2iV2iV2i", "", "mmx") +TARGET_BUILTIN(__builtin_ia32_paddsb, "V8cV8cV8c", "", "mmx") +TARGET_BUILTIN(__builtin_ia32_paddsw, "V4sV4sV4s", "", "mmx") +TARGET_BUILTIN(__builtin_ia32_paddusb, "V8cV8cV8c", "", "mmx") +TARGET_BUILTIN(__builtin_ia32_paddusw, "V4sV4sV4s", "", "mmx") +TARGET_BUILTIN(__builtin_ia32_psubb, "V8cV8cV8c", "", "mmx") +TARGET_BUILTIN(__builtin_ia32_psubw, "V4sV4sV4s", "", "mmx") +TARGET_BUILTIN(__builtin_ia32_psubd, "V2iV2iV2i", "", "mmx") +TARGET_BUILTIN(__builtin_ia32_psubsb, "V8cV8cV8c", "", "mmx") +TARGET_BUILTIN(__builtin_ia32_psubsw, "V4sV4sV4s", "", "mmx") +TARGET_BUILTIN(__builtin_ia32_psubusb, "V8cV8cV8c", "", "mmx") +TARGET_BUILTIN(__builtin_ia32_psubusw, "V4sV4sV4s", "", "mmx") +TARGET_BUILTIN(__builtin_ia32_pmulhw, "V4sV4sV4s", "", "mmx") +TARGET_BUILTIN(__builtin_ia32_pmullw, "V4sV4sV4s", "", "mmx") +TARGET_BUILTIN(__builtin_ia32_pmaddwd, "V2iV4sV4s", "", "mmx") +TARGET_BUILTIN(__builtin_ia32_pand, "V1LLiV1LLiV1LLi", "", "mmx") +TARGET_BUILTIN(__builtin_ia32_pandn, "V1LLiV1LLiV1LLi", "", "mmx") +TARGET_BUILTIN(__builtin_ia32_por, "V1LLiV1LLiV1LLi", "", "mmx") +TARGET_BUILTIN(__builtin_ia32_pxor, "V1LLiV1LLiV1LLi", "", "mmx") +TARGET_BUILTIN(__builtin_ia32_psllw, "V4sV4sV1LLi", "", "mmx") +TARGET_BUILTIN(__builtin_ia32_pslld, "V2iV2iV1LLi", "", "mmx") +TARGET_BUILTIN(__builtin_ia32_psllq, "V1LLiV1LLiV1LLi", "", "mmx") +TARGET_BUILTIN(__builtin_ia32_psrlw, "V4sV4sV1LLi", "", "mmx") +TARGET_BUILTIN(__builtin_ia32_psrld, "V2iV2iV1LLi", "", "mmx") +TARGET_BUILTIN(__builtin_ia32_psrlq, "V1LLiV1LLiV1LLi", "", "mmx") +TARGET_BUILTIN(__builtin_ia32_psraw, "V4sV4sV1LLi", "", "mmx") +TARGET_BUILTIN(__builtin_ia32_psrad, "V2iV2iV1LLi", "", "mmx") +TARGET_BUILTIN(__builtin_ia32_psllwi, "V4sV4si", "", "mmx") +TARGET_BUILTIN(__builtin_ia32_pslldi, "V2iV2ii", "", "mmx") +TARGET_BUILTIN(__builtin_ia32_psllqi, "V1LLiV1LLii", "", "mmx") +TARGET_BUILTIN(__builtin_ia32_psrlwi, "V4sV4si", "", "mmx") +TARGET_BUILTIN(__builtin_ia32_psrldi, "V2iV2ii", "", "mmx") +TARGET_BUILTIN(__builtin_ia32_psrlqi, "V1LLiV1LLii", "", "mmx") +TARGET_BUILTIN(__builtin_ia32_psrawi, "V4sV4si", "", "mmx") +TARGET_BUILTIN(__builtin_ia32_psradi, "V2iV2ii", "", "mmx") +TARGET_BUILTIN(__builtin_ia32_packsswb, "V8cV4sV4s", "", "mmx") +TARGET_BUILTIN(__builtin_ia32_packssdw, "V4sV2iV2i", "", "mmx") +TARGET_BUILTIN(__builtin_ia32_packuswb, "V8cV4sV4s", "", "mmx") +TARGET_BUILTIN(__builtin_ia32_punpckhbw, "V8cV8cV8c", "", "mmx") +TARGET_BUILTIN(__builtin_ia32_punpckhwd, "V4sV4sV4s", "", "mmx") +TARGET_BUILTIN(__builtin_ia32_punpckhdq, "V2iV2iV2i", "", "mmx") +TARGET_BUILTIN(__builtin_ia32_punpcklbw, "V8cV8cV8c", "", "mmx") +TARGET_BUILTIN(__builtin_ia32_punpcklwd, "V4sV4sV4s", "", "mmx") +TARGET_BUILTIN(__builtin_ia32_punpckldq, "V2iV2iV2i", "", "mmx") +TARGET_BUILTIN(__builtin_ia32_pcmpeqb, "V8cV8cV8c", "", "mmx") +TARGET_BUILTIN(__builtin_ia32_pcmpeqw, "V4sV4sV4s", "", "mmx") +TARGET_BUILTIN(__builtin_ia32_pcmpeqd, "V2iV2iV2i", "", "mmx") +TARGET_BUILTIN(__builtin_ia32_pcmpgtb, "V8cV8cV8c", "", "mmx") +TARGET_BUILTIN(__builtin_ia32_pcmpgtw, "V4sV4sV4s", "", "mmx") +TARGET_BUILTIN(__builtin_ia32_pcmpgtd, "V2iV2iV2i", "", "mmx") +TARGET_BUILTIN(__builtin_ia32_maskmovq, "vV8cV8cc*", "", "mmx") +TARGET_BUILTIN(__builtin_ia32_movntq, "vV1LLi*V1LLi", "", "mmx") +TARGET_BUILTIN(__builtin_ia32_vec_init_v2si, "V2iii", "", "mmx") +TARGET_BUILTIN(__builtin_ia32_vec_init_v4hi, "V4sssss", "", "mmx") +TARGET_BUILTIN(__builtin_ia32_vec_init_v8qi, "V8ccccccccc", "", "mmx") +TARGET_BUILTIN(__builtin_ia32_vec_ext_v2si, "iV2ii", "", "mmx") // MMX2 (MMX+SSE) intrinsics -BUILTIN(__builtin_ia32_cvtpi2ps, "V4fV4fV2i", "") -BUILTIN(__builtin_ia32_cvtps2pi, "V2iV4f", "") -BUILTIN(__builtin_ia32_cvttps2pi, "V2iV4f", "") -BUILTIN(__builtin_ia32_pavgb, "V8cV8cV8c", "") -BUILTIN(__builtin_ia32_pavgw, "V4sV4sV4s", "") -BUILTIN(__builtin_ia32_pmaxsw, "V4sV4sV4s", "") -BUILTIN(__builtin_ia32_pmaxub, "V8cV8cV8c", "") -BUILTIN(__builtin_ia32_pminsw, "V4sV4sV4s", "") -BUILTIN(__builtin_ia32_pminub, "V8cV8cV8c", "") -BUILTIN(__builtin_ia32_pmovmskb, "iV8c", "") -BUILTIN(__builtin_ia32_pmulhuw, "V4sV4sV4s", "") -BUILTIN(__builtin_ia32_psadbw, "V4sV8cV8c", "") -BUILTIN(__builtin_ia32_pshufw, "V4sV4sIc", "") +TARGET_BUILTIN(__builtin_ia32_cvtpi2ps, "V4fV4fV2i", "", "sse") +TARGET_BUILTIN(__builtin_ia32_cvtps2pi, "V2iV4f", "", "sse") +TARGET_BUILTIN(__builtin_ia32_cvttps2pi, "V2iV4f", "", "sse") +TARGET_BUILTIN(__builtin_ia32_pavgb, "V8cV8cV8c", "", "sse") +TARGET_BUILTIN(__builtin_ia32_pavgw, "V4sV4sV4s", "", "sse") +TARGET_BUILTIN(__builtin_ia32_pmaxsw, "V4sV4sV4s", "", "sse") +TARGET_BUILTIN(__builtin_ia32_pmaxub, "V8cV8cV8c", "", "sse") +TARGET_BUILTIN(__builtin_ia32_pminsw, "V4sV4sV4s", "", "sse") +TARGET_BUILTIN(__builtin_ia32_pminub, "V8cV8cV8c", "", "sse") +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") // MMX+SSE2 -BUILTIN(__builtin_ia32_cvtpd2pi, "V2iV2d", "") -BUILTIN(__builtin_ia32_cvtpi2pd, "V2dV2i", "") -BUILTIN(__builtin_ia32_cvttpd2pi, "V2iV2d", "") -BUILTIN(__builtin_ia32_paddq, "V1LLiV1LLiV1LLi", "") -BUILTIN(__builtin_ia32_pmuludq, "V1LLiV2iV2i", "") -BUILTIN(__builtin_ia32_psubq, "V1LLiV1LLiV1LLi", "") +TARGET_BUILTIN(__builtin_ia32_cvtpd2pi, "V2iV2d", "", "sse2") +TARGET_BUILTIN(__builtin_ia32_cvtpi2pd, "V2dV2i", "", "sse2") +TARGET_BUILTIN(__builtin_ia32_cvttpd2pi, "V2iV2d", "", "sse2") +TARGET_BUILTIN(__builtin_ia32_paddq, "V1LLiV1LLiV1LLi", "", "sse2") +TARGET_BUILTIN(__builtin_ia32_pmuludq, "V1LLiV2iV2i", "", "sse2") +TARGET_BUILTIN(__builtin_ia32_psubq, "V1LLiV1LLiV1LLi", "", "sse2") // MMX+SSSE3 -BUILTIN(__builtin_ia32_pabsb, "V8cV8c", "") -BUILTIN(__builtin_ia32_pabsd, "V2iV2i", "") -BUILTIN(__builtin_ia32_pabsw, "V4sV4s", "") -BUILTIN(__builtin_ia32_palignr, "V8cV8cV8cIc", "") -BUILTIN(__builtin_ia32_phaddd, "V2iV2iV2i", "") -BUILTIN(__builtin_ia32_phaddsw, "V4sV4sV4s", "") -BUILTIN(__builtin_ia32_phaddw, "V4sV4sV4s", "") -BUILTIN(__builtin_ia32_phsubd, "V2iV2iV2i", "") -BUILTIN(__builtin_ia32_phsubsw, "V4sV4sV4s", "") -BUILTIN(__builtin_ia32_phsubw, "V4sV4sV4s", "") -BUILTIN(__builtin_ia32_pmaddubsw, "V8cV8cV8c", "") -BUILTIN(__builtin_ia32_pmulhrsw, "V4sV4sV4s", "") -BUILTIN(__builtin_ia32_pshufb, "V8cV8cV8c", "") -BUILTIN(__builtin_ia32_psignw, "V4sV4sV4s", "") -BUILTIN(__builtin_ia32_psignb, "V8cV8cV8c", "") -BUILTIN(__builtin_ia32_psignd, "V2iV2iV2i", "") +TARGET_BUILTIN(__builtin_ia32_pabsb, "V8cV8c", "", "ssse3") +TARGET_BUILTIN(__builtin_ia32_pabsd, "V2iV2i", "", "ssse3") +TARGET_BUILTIN(__builtin_ia32_pabsw, "V4sV4s", "", "ssse3") +TARGET_BUILTIN(__builtin_ia32_palignr, "V8cV8cV8cIc", "", "ssse3") +TARGET_BUILTIN(__builtin_ia32_phaddd, "V2iV2iV2i", "", "ssse3") +TARGET_BUILTIN(__builtin_ia32_phaddsw, "V4sV4sV4s", "", "ssse3") +TARGET_BUILTIN(__builtin_ia32_phaddw, "V4sV4sV4s", "", "ssse3") +TARGET_BUILTIN(__builtin_ia32_phsubd, "V2iV2iV2i", "", "ssse3") +TARGET_BUILTIN(__builtin_ia32_phsubsw, "V4sV4sV4s", "", "ssse3") +TARGET_BUILTIN(__builtin_ia32_phsubw, "V4sV4sV4s", "", "ssse3") +TARGET_BUILTIN(__builtin_ia32_pmaddubsw, "V8cV8cV8c", "", "ssse3") +TARGET_BUILTIN(__builtin_ia32_pmulhrsw, "V4sV4sV4s", "", "ssse3") +TARGET_BUILTIN(__builtin_ia32_pshufb, "V8cV8cV8c", "", "ssse3") +TARGET_BUILTIN(__builtin_ia32_psignw, "V4sV4sV4s", "", "ssse3") +TARGET_BUILTIN(__builtin_ia32_psignb, "V8cV8cV8c", "", "ssse3") +TARGET_BUILTIN(__builtin_ia32_psignd, "V2iV2iV2i", "", "ssse3") // SSE intrinsics. -BUILTIN(__builtin_ia32_comieq, "iV4fV4f", "") -BUILTIN(__builtin_ia32_comilt, "iV4fV4f", "") -BUILTIN(__builtin_ia32_comile, "iV4fV4f", "") -BUILTIN(__builtin_ia32_comigt, "iV4fV4f", "") -BUILTIN(__builtin_ia32_comige, "iV4fV4f", "") -BUILTIN(__builtin_ia32_comineq, "iV4fV4f", "") -BUILTIN(__builtin_ia32_ucomieq, "iV4fV4f", "") -BUILTIN(__builtin_ia32_ucomilt, "iV4fV4f", "") -BUILTIN(__builtin_ia32_ucomile, "iV4fV4f", "") -BUILTIN(__builtin_ia32_ucomigt, "iV4fV4f", "") -BUILTIN(__builtin_ia32_ucomige, "iV4fV4f", "") -BUILTIN(__builtin_ia32_ucomineq, "iV4fV4f", "") -BUILTIN(__builtin_ia32_comisdeq, "iV2dV2d", "") -BUILTIN(__builtin_ia32_comisdlt, "iV2dV2d", "") -BUILTIN(__builtin_ia32_comisdle, "iV2dV2d", "") -BUILTIN(__builtin_ia32_comisdgt, "iV2dV2d", "") -BUILTIN(__builtin_ia32_comisdge, "iV2dV2d", "") -BUILTIN(__builtin_ia32_comisdneq, "iV2dV2d", "") -BUILTIN(__builtin_ia32_ucomisdeq, "iV2dV2d", "") -BUILTIN(__builtin_ia32_ucomisdlt, "iV2dV2d", "") -BUILTIN(__builtin_ia32_ucomisdle, "iV2dV2d", "") -BUILTIN(__builtin_ia32_ucomisdgt, "iV2dV2d", "") -BUILTIN(__builtin_ia32_ucomisdge, "iV2dV2d", "") -BUILTIN(__builtin_ia32_ucomisdneq, "iV2dV2d", "") -BUILTIN(__builtin_ia32_cmpps, "V4fV4fV4fIc", "") -BUILTIN(__builtin_ia32_cmpeqps, "V4fV4fV4f", "") -BUILTIN(__builtin_ia32_cmpltps, "V4fV4fV4f", "") -BUILTIN(__builtin_ia32_cmpleps, "V4fV4fV4f", "") -BUILTIN(__builtin_ia32_cmpunordps, "V4fV4fV4f", "") -BUILTIN(__builtin_ia32_cmpneqps, "V4fV4fV4f", "") -BUILTIN(__builtin_ia32_cmpnltps, "V4fV4fV4f", "") -BUILTIN(__builtin_ia32_cmpnleps, "V4fV4fV4f", "") -BUILTIN(__builtin_ia32_cmpordps, "V4fV4fV4f", "") -BUILTIN(__builtin_ia32_cmpss, "V4fV4fV4fIc", "") -BUILTIN(__builtin_ia32_cmpeqss, "V4fV4fV4f", "") -BUILTIN(__builtin_ia32_cmpltss, "V4fV4fV4f", "") -BUILTIN(__builtin_ia32_cmpless, "V4fV4fV4f", "") -BUILTIN(__builtin_ia32_cmpunordss, "V4fV4fV4f", "") -BUILTIN(__builtin_ia32_cmpneqss, "V4fV4fV4f", "") -BUILTIN(__builtin_ia32_cmpnltss, "V4fV4fV4f", "") -BUILTIN(__builtin_ia32_cmpnless, "V4fV4fV4f", "") -BUILTIN(__builtin_ia32_cmpordss, "V4fV4fV4f", "") -BUILTIN(__builtin_ia32_minps, "V4fV4fV4f", "") -BUILTIN(__builtin_ia32_maxps, "V4fV4fV4f", "") -BUILTIN(__builtin_ia32_minss, "V4fV4fV4f", "") -BUILTIN(__builtin_ia32_maxss, "V4fV4fV4f", "") -BUILTIN(__builtin_ia32_cmppd, "V2dV2dV2dIc", "") -BUILTIN(__builtin_ia32_cmpeqpd, "V2dV2dV2d", "") -BUILTIN(__builtin_ia32_cmpltpd, "V2dV2dV2d", "") -BUILTIN(__builtin_ia32_cmplepd, "V2dV2dV2d", "") -BUILTIN(__builtin_ia32_cmpunordpd, "V2dV2dV2d", "") -BUILTIN(__builtin_ia32_cmpneqpd, "V2dV2dV2d", "") -BUILTIN(__builtin_ia32_cmpnltpd, "V2dV2dV2d", "") -BUILTIN(__builtin_ia32_cmpnlepd, "V2dV2dV2d", "") -BUILTIN(__builtin_ia32_cmpordpd, "V2dV2dV2d", "") -BUILTIN(__builtin_ia32_cmpsd, "V2dV2dV2dIc", "") -BUILTIN(__builtin_ia32_cmpeqsd, "V2dV2dV2d", "") -BUILTIN(__builtin_ia32_cmpltsd, "V2dV2dV2d", "") -BUILTIN(__builtin_ia32_cmplesd, "V2dV2dV2d", "") -BUILTIN(__builtin_ia32_cmpunordsd, "V2dV2dV2d", "") -BUILTIN(__builtin_ia32_cmpneqsd, "V2dV2dV2d", "") -BUILTIN(__builtin_ia32_cmpnltsd, "V2dV2dV2d", "") -BUILTIN(__builtin_ia32_cmpnlesd, "V2dV2dV2d", "") -BUILTIN(__builtin_ia32_cmpordsd, "V2dV2dV2d", "") -BUILTIN(__builtin_ia32_minpd, "V2dV2dV2d", "") -BUILTIN(__builtin_ia32_maxpd, "V2dV2dV2d", "") -BUILTIN(__builtin_ia32_minsd, "V2dV2dV2d", "") -BUILTIN(__builtin_ia32_maxsd, "V2dV2dV2d", "") -BUILTIN(__builtin_ia32_paddsb128, "V16cV16cV16c", "") -BUILTIN(__builtin_ia32_paddsw128, "V8sV8sV8s", "") -BUILTIN(__builtin_ia32_psubsb128, "V16cV16cV16c", "") -BUILTIN(__builtin_ia32_psubsw128, "V8sV8sV8s", "") -BUILTIN(__builtin_ia32_paddusb128, "V16cV16cV16c", "") -BUILTIN(__builtin_ia32_paddusw128, "V8sV8sV8s", "") -BUILTIN(__builtin_ia32_psubusb128, "V16cV16cV16c", "") -BUILTIN(__builtin_ia32_psubusw128, "V8sV8sV8s", "") -BUILTIN(__builtin_ia32_pmulhw128, "V8sV8sV8s", "") -BUILTIN(__builtin_ia32_pavgb128, "V16cV16cV16c", "") -BUILTIN(__builtin_ia32_pavgw128, "V8sV8sV8s", "") -BUILTIN(__builtin_ia32_pmaxub128, "V16cV16cV16c", "") -BUILTIN(__builtin_ia32_pmaxsw128, "V8sV8sV8s", "") -BUILTIN(__builtin_ia32_pminub128, "V16cV16cV16c", "") -BUILTIN(__builtin_ia32_pminsw128, "V8sV8sV8s", "") -BUILTIN(__builtin_ia32_packsswb128, "V16cV8sV8s", "") -BUILTIN(__builtin_ia32_packssdw128, "V8sV4iV4i", "") -BUILTIN(__builtin_ia32_packuswb128, "V16cV8sV8s", "") -BUILTIN(__builtin_ia32_pmulhuw128, "V8sV8sV8s", "") -BUILTIN(__builtin_ia32_addsubps, "V4fV4fV4f", "") -BUILTIN(__builtin_ia32_addsubpd, "V2dV2dV2d", "") -BUILTIN(__builtin_ia32_haddps, "V4fV4fV4f", "") -BUILTIN(__builtin_ia32_haddpd, "V2dV2dV2d", "") -BUILTIN(__builtin_ia32_hsubps, "V4fV4fV4f", "") -BUILTIN(__builtin_ia32_hsubpd, "V2dV2dV2d", "") -BUILTIN(__builtin_ia32_phaddw128, "V8sV8sV8s", "") -BUILTIN(__builtin_ia32_phaddd128, "V4iV4iV4i", "") -BUILTIN(__builtin_ia32_phaddsw128, "V8sV8sV8s", "") -BUILTIN(__builtin_ia32_phsubw128, "V8sV8sV8s", "") -BUILTIN(__builtin_ia32_phsubd128, "V4iV4iV4i", "") -BUILTIN(__builtin_ia32_phsubsw128, "V8sV8sV8s", "") -BUILTIN(__builtin_ia32_pmaddubsw128, "V8sV16cV16c", "") -BUILTIN(__builtin_ia32_pmulhrsw128, "V8sV8sV8s", "") -BUILTIN(__builtin_ia32_pshufb128, "V16cV16cV16c", "") -BUILTIN(__builtin_ia32_psignb128, "V16cV16cV16c", "") -BUILTIN(__builtin_ia32_psignw128, "V8sV8sV8s", "") -BUILTIN(__builtin_ia32_psignd128, "V4iV4iV4i", "") -BUILTIN(__builtin_ia32_pabsb128, "V16cV16c", "") -BUILTIN(__builtin_ia32_pabsw128, "V8sV8s", "") -BUILTIN(__builtin_ia32_pabsd128, "V4iV4i", "") -BUILTIN(__builtin_ia32_ldmxcsr, "vUi", "") -BUILTIN(__builtin_ia32_stmxcsr, "Ui", "") -BUILTIN(__builtin_ia32_cvtss2si, "iV4f", "") -BUILTIN(__builtin_ia32_cvtss2si64, "LLiV4f", "") -BUILTIN(__builtin_ia32_storeups, "vf*V4f", "") -BUILTIN(__builtin_ia32_storehps, "vV2i*V4f", "") -BUILTIN(__builtin_ia32_storelps, "vV2i*V4f", "") -BUILTIN(__builtin_ia32_movmskps, "iV4f", "") -BUILTIN(__builtin_ia32_movntps, "vf*V4f", "") -BUILTIN(__builtin_ia32_sfence, "v", "") -BUILTIN(__builtin_ia32_rcpps, "V4fV4f", "") -BUILTIN(__builtin_ia32_rcpss, "V4fV4f", "") -BUILTIN(__builtin_ia32_rsqrtps, "V4fV4f", "") -BUILTIN(__builtin_ia32_rsqrtss, "V4fV4f", "") -BUILTIN(__builtin_ia32_sqrtps, "V4fV4f", "") -BUILTIN(__builtin_ia32_sqrtss, "V4fV4f", "") -BUILTIN(__builtin_ia32_maskmovdqu, "vV16cV16cc*", "") -BUILTIN(__builtin_ia32_storeupd, "vd*V2d", "") -BUILTIN(__builtin_ia32_movmskpd, "iV2d", "") -BUILTIN(__builtin_ia32_pmovmskb128, "iV16c", "") -BUILTIN(__builtin_ia32_movnti, "vi*i", "") -BUILTIN(__builtin_ia32_movnti64, "vLLi*LLi", "") -BUILTIN(__builtin_ia32_movntpd, "vd*V2d", "") -BUILTIN(__builtin_ia32_movntdq, "vV2LLi*V2LLi", "") -BUILTIN(__builtin_ia32_psadbw128, "V2LLiV16cV16c", "") -BUILTIN(__builtin_ia32_sqrtpd, "V2dV2d", "") -BUILTIN(__builtin_ia32_sqrtsd, "V2dV2d", "") -BUILTIN(__builtin_ia32_cvtdq2pd, "V2dV4i", "") -BUILTIN(__builtin_ia32_cvtdq2ps, "V4fV4i", "") -BUILTIN(__builtin_ia32_cvtpd2dq, "V2LLiV2d", "") -BUILTIN(__builtin_ia32_cvtpd2ps, "V4fV2d", "") -BUILTIN(__builtin_ia32_cvttpd2dq, "V4iV2d", "") -BUILTIN(__builtin_ia32_cvtsd2si, "iV2d", "") -BUILTIN(__builtin_ia32_cvtsd2si64, "LLiV2d", "") -BUILTIN(__builtin_ia32_cvtps2dq, "V4iV4f", "") -BUILTIN(__builtin_ia32_cvtps2pd, "V2dV4f", "") -BUILTIN(__builtin_ia32_cvttps2dq, "V4iV4f", "") -BUILTIN(__builtin_ia32_clflush, "vvC*", "") -BUILTIN(__builtin_ia32_lfence, "v", "") -BUILTIN(__builtin_ia32_mfence, "v", "") -BUILTIN(__builtin_ia32_storedqu, "vc*V16c", "") -BUILTIN(__builtin_ia32_pmuludq128, "V2LLiV4iV4i", "") -BUILTIN(__builtin_ia32_psraw128, "V8sV8sV8s", "") -BUILTIN(__builtin_ia32_psrad128, "V4iV4iV4i", "") -BUILTIN(__builtin_ia32_psrlw128, "V8sV8sV8s", "") -BUILTIN(__builtin_ia32_psrld128, "V4iV4iV4i", "") -BUILTIN(__builtin_ia32_psrlq128, "V2LLiV2LLiV2LLi", "") -BUILTIN(__builtin_ia32_psllw128, "V8sV8sV8s", "") -BUILTIN(__builtin_ia32_pslld128, "V4iV4iV4i", "") -BUILTIN(__builtin_ia32_psllq128, "V2LLiV2LLiV2LLi", "") -BUILTIN(__builtin_ia32_psllwi128, "V8sV8si", "") -BUILTIN(__builtin_ia32_pslldi128, "V4iV4ii", "") -BUILTIN(__builtin_ia32_psllqi128, "V2LLiV2LLii", "") -BUILTIN(__builtin_ia32_psrlwi128, "V8sV8si", "") -BUILTIN(__builtin_ia32_psrldi128, "V4iV4ii", "") -BUILTIN(__builtin_ia32_psrlqi128, "V2LLiV2LLii", "") -BUILTIN(__builtin_ia32_psrawi128, "V8sV8si", "") -BUILTIN(__builtin_ia32_psradi128, "V4iV4ii", "") -BUILTIN(__builtin_ia32_pmaddwd128, "V4iV8sV8s", "") -BUILTIN(__builtin_ia32_monitor, "vv*UiUi", "") -BUILTIN(__builtin_ia32_mwait, "vUiUi", "") -BUILTIN(__builtin_ia32_lddqu, "V16ccC*", "") -BUILTIN(__builtin_ia32_palignr128, "V16cV16cV16cIc", "") -BUILTIN(__builtin_ia32_insertps128, "V4fV4fV4fIc", "") - -BUILTIN(__builtin_ia32_pblendvb128, "V16cV16cV16cV16c", "") -BUILTIN(__builtin_ia32_blendvpd, "V2dV2dV2dV2d", "") -BUILTIN(__builtin_ia32_blendvps, "V4fV4fV4fV4f", "") - -BUILTIN(__builtin_ia32_packusdw128, "V8sV4iV4i", "") -BUILTIN(__builtin_ia32_pmaxsb128, "V16cV16cV16c", "") -BUILTIN(__builtin_ia32_pmaxsd128, "V4iV4iV4i", "") -BUILTIN(__builtin_ia32_pmaxud128, "V4iV4iV4i", "") -BUILTIN(__builtin_ia32_pmaxuw128, "V8sV8sV8s", "") -BUILTIN(__builtin_ia32_pminsb128, "V16cV16cV16c", "") -BUILTIN(__builtin_ia32_pminsd128, "V4iV4iV4i", "") -BUILTIN(__builtin_ia32_pminud128, "V4iV4iV4i", "") -BUILTIN(__builtin_ia32_pminuw128, "V8sV8sV8s", "") -BUILTIN(__builtin_ia32_pmovsxbd128, "V4iV16c", "") -BUILTIN(__builtin_ia32_pmovsxbq128, "V2LLiV16c", "") -BUILTIN(__builtin_ia32_pmovsxbw128, "V8sV16c", "") -BUILTIN(__builtin_ia32_pmovsxdq128, "V2LLiV4i", "") -BUILTIN(__builtin_ia32_pmovsxwd128, "V4iV8s", "") -BUILTIN(__builtin_ia32_pmovsxwq128, "V2LLiV8s", "") -BUILTIN(__builtin_ia32_pmovzxbd128, "V4iV16c", "") -BUILTIN(__builtin_ia32_pmovzxbq128, "V2LLiV16c", "") -BUILTIN(__builtin_ia32_pmovzxbw128, "V8sV16c", "") -BUILTIN(__builtin_ia32_pmovzxdq128, "V2LLiV4i", "") -BUILTIN(__builtin_ia32_pmovzxwd128, "V4iV8s", "") -BUILTIN(__builtin_ia32_pmovzxwq128, "V2LLiV8s", "") -BUILTIN(__builtin_ia32_pmuldq128, "V2LLiV4iV4i", "") -BUILTIN(__builtin_ia32_pmulld128, "V4iV4iV4i", "") -BUILTIN(__builtin_ia32_roundps, "V4fV4fi", "") -BUILTIN(__builtin_ia32_roundss, "V4fV4fV4fi", "") -BUILTIN(__builtin_ia32_roundsd, "V2dV2dV2di", "") -BUILTIN(__builtin_ia32_roundpd, "V2dV2di", "") -BUILTIN(__builtin_ia32_dpps, "V4fV4fV4fIc", "") -BUILTIN(__builtin_ia32_dppd, "V2dV2dV2dIc", "") -BUILTIN(__builtin_ia32_movntdqa, "V2LLiV2LLi*", "") -BUILTIN(__builtin_ia32_ptestz128, "iV2LLiV2LLi", "") -BUILTIN(__builtin_ia32_ptestc128, "iV2LLiV2LLi", "") -BUILTIN(__builtin_ia32_ptestnzc128, "iV2LLiV2LLi", "") -BUILTIN(__builtin_ia32_mpsadbw128, "V16cV16cV16cIc", "") -BUILTIN(__builtin_ia32_phminposuw128, "V8sV8s", "") +TARGET_BUILTIN(__builtin_ia32_comieq, "iV4fV4f", "", "sse") +TARGET_BUILTIN(__builtin_ia32_comilt, "iV4fV4f", "", "sse") +TARGET_BUILTIN(__builtin_ia32_comile, "iV4fV4f", "", "sse") +TARGET_BUILTIN(__builtin_ia32_comigt, "iV4fV4f", "", "sse") +TARGET_BUILTIN(__builtin_ia32_comige, "iV4fV4f", "", "sse") +TARGET_BUILTIN(__builtin_ia32_comineq, "iV4fV4f", "", "sse") +TARGET_BUILTIN(__builtin_ia32_ucomieq, "iV4fV4f", "", "sse") +TARGET_BUILTIN(__builtin_ia32_ucomilt, "iV4fV4f", "", "sse") +TARGET_BUILTIN(__builtin_ia32_ucomile, "iV4fV4f", "", "sse") +TARGET_BUILTIN(__builtin_ia32_ucomigt, "iV4fV4f", "", "sse") +TARGET_BUILTIN(__builtin_ia32_ucomige, "iV4fV4f", "", "sse") +TARGET_BUILTIN(__builtin_ia32_ucomineq, "iV4fV4f", "", "sse") + +TARGET_BUILTIN(__builtin_ia32_comisdeq, "iV2dV2d", "", "sse2") +TARGET_BUILTIN(__builtin_ia32_comisdlt, "iV2dV2d", "", "sse2") +TARGET_BUILTIN(__builtin_ia32_comisdle, "iV2dV2d", "", "sse2") +TARGET_BUILTIN(__builtin_ia32_comisdgt, "iV2dV2d", "", "sse2") +TARGET_BUILTIN(__builtin_ia32_comisdge, "iV2dV2d", "", "sse2") +TARGET_BUILTIN(__builtin_ia32_comisdneq, "iV2dV2d", "", "sse2") +TARGET_BUILTIN(__builtin_ia32_ucomisdeq, "iV2dV2d", "", "sse2") +TARGET_BUILTIN(__builtin_ia32_ucomisdlt, "iV2dV2d", "", "sse2") +TARGET_BUILTIN(__builtin_ia32_ucomisdle, "iV2dV2d", "", "sse2") +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") +TARGET_BUILTIN(__builtin_ia32_cmpunordps, "V4fV4fV4f", "", "sse") +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") +TARGET_BUILTIN(__builtin_ia32_cmpunordss, "V4fV4fV4f", "", "sse") +TARGET_BUILTIN(__builtin_ia32_cmpneqss, "V4fV4fV4f", "", "sse") +TARGET_BUILTIN(__builtin_ia32_cmpnltss, "V4fV4fV4f", "", "sse") +TARGET_BUILTIN(__builtin_ia32_cmpnless, "V4fV4fV4f", "", "sse") +TARGET_BUILTIN(__builtin_ia32_cmpordss, "V4fV4fV4f", "", "sse") +TARGET_BUILTIN(__builtin_ia32_minps, "V4fV4fV4f", "", "sse") +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") +TARGET_BUILTIN(__builtin_ia32_cmpunordpd, "V2dV2dV2d", "", "sse2") +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") +TARGET_BUILTIN(__builtin_ia32_cmpunordsd, "V2dV2dV2d", "", "sse2") +TARGET_BUILTIN(__builtin_ia32_cmpneqsd, "V2dV2dV2d", "", "sse2") +TARGET_BUILTIN(__builtin_ia32_cmpnltsd, "V2dV2dV2d", "", "sse2") +TARGET_BUILTIN(__builtin_ia32_cmpnlesd, "V2dV2dV2d", "", "sse2") +TARGET_BUILTIN(__builtin_ia32_cmpordsd, "V2dV2dV2d", "", "sse2") +TARGET_BUILTIN(__builtin_ia32_minpd, "V2dV2dV2d", "", "sse2") +TARGET_BUILTIN(__builtin_ia32_maxpd, "V2dV2dV2d", "", "sse2") +TARGET_BUILTIN(__builtin_ia32_minsd, "V2dV2dV2d", "", "sse2") +TARGET_BUILTIN(__builtin_ia32_maxsd, "V2dV2dV2d", "", "sse2") +TARGET_BUILTIN(__builtin_ia32_paddsb128, "V16cV16cV16c", "", "sse2") +TARGET_BUILTIN(__builtin_ia32_paddsw128, "V8sV8sV8s", "", "sse2") +TARGET_BUILTIN(__builtin_ia32_psubsb128, "V16cV16cV16c", "", "sse2") +TARGET_BUILTIN(__builtin_ia32_psubsw128, "V8sV8sV8s", "", "sse2") +TARGET_BUILTIN(__builtin_ia32_paddusb128, "V16cV16cV16c", "", "sse2") +TARGET_BUILTIN(__builtin_ia32_paddusw128, "V8sV8sV8s", "", "sse2") +TARGET_BUILTIN(__builtin_ia32_psubusb128, "V16cV16cV16c", "", "sse2") +TARGET_BUILTIN(__builtin_ia32_psubusw128, "V8sV8sV8s", "", "sse2") +TARGET_BUILTIN(__builtin_ia32_pmulhw128, "V8sV8sV8s", "", "sse2") +TARGET_BUILTIN(__builtin_ia32_pavgb128, "V16cV16cV16c", "", "sse2") +TARGET_BUILTIN(__builtin_ia32_pavgw128, "V8sV8sV8s", "", "sse2") +TARGET_BUILTIN(__builtin_ia32_pmaxub128, "V16cV16cV16c", "", "sse2") +TARGET_BUILTIN(__builtin_ia32_pmaxsw128, "V8sV8sV8s", "", "sse2") +TARGET_BUILTIN(__builtin_ia32_pminub128, "V16cV16cV16c", "", "sse2") +TARGET_BUILTIN(__builtin_ia32_pminsw128, "V8sV8sV8s", "", "sse2") +TARGET_BUILTIN(__builtin_ia32_packsswb128, "V16cV8sV8s", "", "sse2") +TARGET_BUILTIN(__builtin_ia32_packssdw128, "V8sV4iV4i", "", "sse2") +TARGET_BUILTIN(__builtin_ia32_packuswb128, "V16cV8sV8s", "", "sse2") +TARGET_BUILTIN(__builtin_ia32_pmulhuw128, "V8sV8sV8s", "", "sse2") + +TARGET_BUILTIN(__builtin_ia32_addsubps, "V4fV4fV4f", "", "sse3") +TARGET_BUILTIN(__builtin_ia32_addsubpd, "V2dV2dV2d", "", "sse3") +TARGET_BUILTIN(__builtin_ia32_haddps, "V4fV4fV4f", "", "sse3") +TARGET_BUILTIN(__builtin_ia32_haddpd, "V2dV2dV2d", "", "sse3") +TARGET_BUILTIN(__builtin_ia32_hsubps, "V4fV4fV4f", "", "sse3") +TARGET_BUILTIN(__builtin_ia32_hsubpd, "V2dV2dV2d", "", "sse3") +TARGET_BUILTIN(__builtin_ia32_phaddw128, "V8sV8sV8s", "", "ssse3") +TARGET_BUILTIN(__builtin_ia32_phaddd128, "V4iV4iV4i", "", "ssse3") +TARGET_BUILTIN(__builtin_ia32_phaddsw128, "V8sV8sV8s", "", "ssse3") +TARGET_BUILTIN(__builtin_ia32_phsubw128, "V8sV8sV8s", "", "ssse3") +TARGET_BUILTIN(__builtin_ia32_phsubd128, "V4iV4iV4i", "", "ssse3") +TARGET_BUILTIN(__builtin_ia32_phsubsw128, "V8sV8sV8s", "", "ssse3") +TARGET_BUILTIN(__builtin_ia32_pmaddubsw128, "V8sV16cV16c", "", "ssse3") +TARGET_BUILTIN(__builtin_ia32_pmulhrsw128, "V8sV8sV8s", "", "ssse3") +TARGET_BUILTIN(__builtin_ia32_pshufb128, "V16cV16cV16c", "", "ssse3") +TARGET_BUILTIN(__builtin_ia32_psignb128, "V16cV16cV16c", "", "ssse3") +TARGET_BUILTIN(__builtin_ia32_psignw128, "V8sV8sV8s", "", "ssse3") +TARGET_BUILTIN(__builtin_ia32_psignd128, "V4iV4iV4i", "", "ssse3") +TARGET_BUILTIN(__builtin_ia32_pabsb128, "V16cV16c", "", "ssse3") +TARGET_BUILTIN(__builtin_ia32_pabsw128, "V8sV8s", "", "ssse3") +TARGET_BUILTIN(__builtin_ia32_pabsd128, "V4iV4i", "", "ssse3") + +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") +TARGET_BUILTIN(__builtin_ia32_rsqrtps, "V4fV4f", "", "sse") +TARGET_BUILTIN(__builtin_ia32_rsqrtss, "V4fV4f", "", "sse") +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") +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") +TARGET_BUILTIN(__builtin_ia32_psrlw128, "V8sV8sV8s", "", "sse2") +TARGET_BUILTIN(__builtin_ia32_psrld128, "V4iV4iV4i", "", "sse2") +TARGET_BUILTIN(__builtin_ia32_psrlq128, "V2LLiV2LLiV2LLi", "", "sse2") +TARGET_BUILTIN(__builtin_ia32_psllw128, "V8sV8sV8s", "", "sse2") +TARGET_BUILTIN(__builtin_ia32_pslld128, "V4iV4iV4i", "", "sse2") +TARGET_BUILTIN(__builtin_ia32_psllq128, "V2LLiV2LLiV2LLi", "", "sse2") +TARGET_BUILTIN(__builtin_ia32_psllwi128, "V8sV8si", "", "sse2") +TARGET_BUILTIN(__builtin_ia32_pslldi128, "V4iV4ii", "", "sse2") +TARGET_BUILTIN(__builtin_ia32_psllqi128, "V2LLiV2LLii", "", "sse2") +TARGET_BUILTIN(__builtin_ia32_psrlwi128, "V8sV8si", "", "sse2") +TARGET_BUILTIN(__builtin_ia32_psrldi128, "V4iV4ii", "", "sse2") +TARGET_BUILTIN(__builtin_ia32_psrlqi128, "V2LLiV2LLii", "", "sse2") +TARGET_BUILTIN(__builtin_ia32_psrawi128, "V8sV8si", "", "sse2") +TARGET_BUILTIN(__builtin_ia32_psradi128, "V4iV4ii", "", "sse2") +TARGET_BUILTIN(__builtin_ia32_pmaddwd128, "V4iV8sV8s", "", "sse2") + +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_insertps128, "V4fV4fV4fIc", "", "sse4.1") +TARGET_BUILTIN(__builtin_ia32_pblendvb128, "V16cV16cV16cV16c", "", "sse4.1") +TARGET_BUILTIN(__builtin_ia32_blendvpd, "V2dV2dV2dV2d", "", "sse4.1") +TARGET_BUILTIN(__builtin_ia32_blendvps, "V4fV4fV4fV4f", "", "sse4.1") +TARGET_BUILTIN(__builtin_ia32_packusdw128, "V8sV4iV4i", "", "sse4.1") + +TARGET_BUILTIN(__builtin_ia32_pmaxsb128, "V16cV16cV16c", "", "sse4.1") +TARGET_BUILTIN(__builtin_ia32_pmaxsd128, "V4iV4iV4i", "", "sse4.1") +TARGET_BUILTIN(__builtin_ia32_pmaxud128, "V4iV4iV4i", "", "sse4.1") +TARGET_BUILTIN(__builtin_ia32_pmaxuw128, "V8sV8sV8s", "", "sse4.1") +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") +TARGET_BUILTIN(__builtin_ia32_roundpd, "V2dV2dIi", "", "sse4.1") +TARGET_BUILTIN(__builtin_ia32_dpps, "V4fV4fV4fIc", "", "sse4.1") +TARGET_BUILTIN(__builtin_ia32_dppd, "V2dV2dV2dIc", "", "sse4.1") +TARGET_BUILTIN(__builtin_ia32_movntdqa, "V2LLiV2LLiC*", "", "sse4.1") +TARGET_BUILTIN(__builtin_ia32_ptestz128, "iV2LLiV2LLi", "", "sse4.1") +TARGET_BUILTIN(__builtin_ia32_ptestc128, "iV2LLiV2LLi", "", "sse4.1") +TARGET_BUILTIN(__builtin_ia32_ptestnzc128, "iV2LLiV2LLi", "", "sse4.1") +TARGET_BUILTIN(__builtin_ia32_mpsadbw128, "V16cV16cV16cIc", "", "sse4.1") +TARGET_BUILTIN(__builtin_ia32_phminposuw128, "V8sV8s", "", "sse4.1") // SSE 4.2 -BUILTIN(__builtin_ia32_pcmpistrm128, "V16cV16cV16cIc", "") -BUILTIN(__builtin_ia32_pcmpistri128, "iV16cV16cIc", "") -BUILTIN(__builtin_ia32_pcmpestrm128, "V16cV16ciV16ciIc", "") -BUILTIN(__builtin_ia32_pcmpestri128, "iV16ciV16ciIc","") - -BUILTIN(__builtin_ia32_pcmpistria128, "iV16cV16cIc","") -BUILTIN(__builtin_ia32_pcmpistric128, "iV16cV16cIc","") -BUILTIN(__builtin_ia32_pcmpistrio128, "iV16cV16cIc","") -BUILTIN(__builtin_ia32_pcmpistris128, "iV16cV16cIc","") -BUILTIN(__builtin_ia32_pcmpistriz128, "iV16cV16cIc","") -BUILTIN(__builtin_ia32_pcmpestria128, "iV16ciV16ciIc","") -BUILTIN(__builtin_ia32_pcmpestric128, "iV16ciV16ciIc","") -BUILTIN(__builtin_ia32_pcmpestrio128, "iV16ciV16ciIc","") -BUILTIN(__builtin_ia32_pcmpestris128, "iV16ciV16ciIc","") -BUILTIN(__builtin_ia32_pcmpestriz128, "iV16ciV16ciIc","") - -BUILTIN(__builtin_ia32_crc32qi, "UiUiUc", "") -BUILTIN(__builtin_ia32_crc32hi, "UiUiUs", "") -BUILTIN(__builtin_ia32_crc32si, "UiUiUi", "") -BUILTIN(__builtin_ia32_crc32di, "ULLiULLiULLi", "") +TARGET_BUILTIN(__builtin_ia32_pcmpistrm128, "V16cV16cV16cIc", "", "sse4.2") +TARGET_BUILTIN(__builtin_ia32_pcmpistri128, "iV16cV16cIc", "", "sse4.2") +TARGET_BUILTIN(__builtin_ia32_pcmpestrm128, "V16cV16ciV16ciIc", "", "sse4.2") +TARGET_BUILTIN(__builtin_ia32_pcmpestri128, "iV16ciV16ciIc","", "sse4.2") + +TARGET_BUILTIN(__builtin_ia32_pcmpistria128, "iV16cV16cIc","", "sse4.2") +TARGET_BUILTIN(__builtin_ia32_pcmpistric128, "iV16cV16cIc","", "sse4.2") +TARGET_BUILTIN(__builtin_ia32_pcmpistrio128, "iV16cV16cIc","", "sse4.2") +TARGET_BUILTIN(__builtin_ia32_pcmpistris128, "iV16cV16cIc","", "sse4.2") +TARGET_BUILTIN(__builtin_ia32_pcmpistriz128, "iV16cV16cIc","", "sse4.2") +TARGET_BUILTIN(__builtin_ia32_pcmpestria128, "iV16ciV16ciIc","", "sse4.2") +TARGET_BUILTIN(__builtin_ia32_pcmpestric128, "iV16ciV16ciIc","", "sse4.2") +TARGET_BUILTIN(__builtin_ia32_pcmpestrio128, "iV16ciV16ciIc","", "sse4.2") +TARGET_BUILTIN(__builtin_ia32_pcmpestris128, "iV16ciV16ciIc","", "sse4.2") +TARGET_BUILTIN(__builtin_ia32_pcmpestriz128, "iV16ciV16ciIc","", "sse4.2") + +TARGET_BUILTIN(__builtin_ia32_crc32qi, "UiUiUc", "", "sse4.2") +TARGET_BUILTIN(__builtin_ia32_crc32hi, "UiUiUs", "", "sse4.2") +TARGET_BUILTIN(__builtin_ia32_crc32si, "UiUiUi", "", "sse4.2") +TARGET_BUILTIN(__builtin_ia32_crc32di, "ULLiULLiULLi", "", "sse4.2") // SSE4a -BUILTIN(__builtin_ia32_extrqi, "V2LLiV2LLiIcIc", "") -BUILTIN(__builtin_ia32_extrq, "V2LLiV2LLiV16c", "") -BUILTIN(__builtin_ia32_insertqi, "V2LLiV2LLiV2LLiIcIc", "") -BUILTIN(__builtin_ia32_insertq, "V2LLiV2LLiV2LLi", "") -BUILTIN(__builtin_ia32_movntsd, "vd*V2d", "") -BUILTIN(__builtin_ia32_movntss, "vf*V4f", "") +TARGET_BUILTIN(__builtin_ia32_extrqi, "V2LLiV2LLiIcIc", "", "sse4a") +TARGET_BUILTIN(__builtin_ia32_extrq, "V2LLiV2LLiV16c", "", "sse4a") +TARGET_BUILTIN(__builtin_ia32_insertqi, "V2LLiV2LLiV2LLiIcIc", "", "sse4a") +TARGET_BUILTIN(__builtin_ia32_insertq, "V2LLiV2LLiV2LLi", "", "sse4a") +TARGET_BUILTIN(__builtin_ia32_movntsd, "vd*V2d", "", "sse4a") +TARGET_BUILTIN(__builtin_ia32_movntss, "vf*V4f", "", "sse4a") // AES -BUILTIN(__builtin_ia32_aesenc128, "V2LLiV2LLiV2LLi", "") -BUILTIN(__builtin_ia32_aesenclast128, "V2LLiV2LLiV2LLi", "") -BUILTIN(__builtin_ia32_aesdec128, "V2LLiV2LLiV2LLi", "") -BUILTIN(__builtin_ia32_aesdeclast128, "V2LLiV2LLiV2LLi", "") -BUILTIN(__builtin_ia32_aesimc128, "V2LLiV2LLi", "") -BUILTIN(__builtin_ia32_aeskeygenassist128, "V2LLiV2LLiIc", "") +TARGET_BUILTIN(__builtin_ia32_aesenc128, "V2LLiV2LLiV2LLi", "", "aes") +TARGET_BUILTIN(__builtin_ia32_aesenclast128, "V2LLiV2LLiV2LLi", "", "aes") +TARGET_BUILTIN(__builtin_ia32_aesdec128, "V2LLiV2LLiV2LLi", "", "aes") +TARGET_BUILTIN(__builtin_ia32_aesdeclast128, "V2LLiV2LLiV2LLi", "", "aes") +TARGET_BUILTIN(__builtin_ia32_aesimc128, "V2LLiV2LLi", "", "aes") +TARGET_BUILTIN(__builtin_ia32_aeskeygenassist128, "V2LLiV2LLiIc", "", "aes") // CLMUL -BUILTIN(__builtin_ia32_pclmulqdq128, "V2LLiV2LLiV2LLiIc", "") +TARGET_BUILTIN(__builtin_ia32_pclmulqdq128, "V2LLiV2LLiV2LLiIc", "", "pclmul") // AVX -BUILTIN(__builtin_ia32_addsubpd256, "V4dV4dV4d", "") -BUILTIN(__builtin_ia32_addsubps256, "V8fV8fV8f", "") -BUILTIN(__builtin_ia32_haddpd256, "V4dV4dV4d", "") -BUILTIN(__builtin_ia32_hsubps256, "V8fV8fV8f", "") -BUILTIN(__builtin_ia32_hsubpd256, "V4dV4dV4d", "") -BUILTIN(__builtin_ia32_haddps256, "V8fV8fV8f", "") -BUILTIN(__builtin_ia32_maxpd256, "V4dV4dV4d", "") -BUILTIN(__builtin_ia32_maxps256, "V8fV8fV8f", "") -BUILTIN(__builtin_ia32_minpd256, "V4dV4dV4d", "") -BUILTIN(__builtin_ia32_minps256, "V8fV8fV8f", "") -BUILTIN(__builtin_ia32_vpermilvarpd, "V2dV2dV2LLi", "") -BUILTIN(__builtin_ia32_vpermilvarps, "V4fV4fV4i", "") -BUILTIN(__builtin_ia32_vpermilvarpd256, "V4dV4dV4LLi", "") -BUILTIN(__builtin_ia32_vpermilvarps256, "V8fV8fV8i", "") -BUILTIN(__builtin_ia32_blendvpd256, "V4dV4dV4dV4d", "") -BUILTIN(__builtin_ia32_blendvps256, "V8fV8fV8fV8f", "") -BUILTIN(__builtin_ia32_dpps256, "V8fV8fV8fIc", "") -BUILTIN(__builtin_ia32_cmppd256, "V4dV4dV4dIc", "") -BUILTIN(__builtin_ia32_cmpps256, "V8fV8fV8fIc", "") -BUILTIN(__builtin_ia32_cvtdq2pd256, "V4dV4i", "") -BUILTIN(__builtin_ia32_cvtdq2ps256, "V8fV8i", "") -BUILTIN(__builtin_ia32_cvtpd2ps256, "V4fV4d", "") -BUILTIN(__builtin_ia32_cvtps2dq256, "V8iV8f", "") -BUILTIN(__builtin_ia32_cvtps2pd256, "V4dV4f", "") -BUILTIN(__builtin_ia32_cvttpd2dq256, "V4iV4d", "") -BUILTIN(__builtin_ia32_cvtpd2dq256, "V4iV4d", "") -BUILTIN(__builtin_ia32_cvttps2dq256, "V8iV8f", "") -BUILTIN(__builtin_ia32_vperm2f128_pd256, "V4dV4dV4dIc", "") -BUILTIN(__builtin_ia32_vperm2f128_ps256, "V8fV8fV8fIc", "") -BUILTIN(__builtin_ia32_vperm2f128_si256, "V8iV8iV8iIc", "") -BUILTIN(__builtin_ia32_sqrtpd256, "V4dV4d", "") -BUILTIN(__builtin_ia32_sqrtps256, "V8fV8f", "") -BUILTIN(__builtin_ia32_rsqrtps256, "V8fV8f", "") -BUILTIN(__builtin_ia32_rcpps256, "V8fV8f", "") -BUILTIN(__builtin_ia32_roundpd256, "V4dV4dIi", "") -BUILTIN(__builtin_ia32_roundps256, "V8fV8fIi", "") -BUILTIN(__builtin_ia32_vtestzpd, "iV2dV2d", "") -BUILTIN(__builtin_ia32_vtestcpd, "iV2dV2d", "") -BUILTIN(__builtin_ia32_vtestnzcpd, "iV2dV2d", "") -BUILTIN(__builtin_ia32_vtestzps, "iV4fV4f", "") -BUILTIN(__builtin_ia32_vtestcps, "iV4fV4f", "") -BUILTIN(__builtin_ia32_vtestnzcps, "iV4fV4f", "") -BUILTIN(__builtin_ia32_vtestzpd256, "iV4dV4d", "") -BUILTIN(__builtin_ia32_vtestcpd256, "iV4dV4d", "") -BUILTIN(__builtin_ia32_vtestnzcpd256, "iV4dV4d", "") -BUILTIN(__builtin_ia32_vtestzps256, "iV8fV8f", "") -BUILTIN(__builtin_ia32_vtestcps256, "iV8fV8f", "") -BUILTIN(__builtin_ia32_vtestnzcps256, "iV8fV8f", "") -BUILTIN(__builtin_ia32_ptestz256, "iV4LLiV4LLi", "") -BUILTIN(__builtin_ia32_ptestc256, "iV4LLiV4LLi", "") -BUILTIN(__builtin_ia32_ptestnzc256, "iV4LLiV4LLi", "") -BUILTIN(__builtin_ia32_movmskpd256, "iV4d", "") -BUILTIN(__builtin_ia32_movmskps256, "iV8f", "") -BUILTIN(__builtin_ia32_vzeroall, "v", "") -BUILTIN(__builtin_ia32_vzeroupper, "v", "") -BUILTIN(__builtin_ia32_vbroadcastf128_pd256, "V4dV2dC*", "") -BUILTIN(__builtin_ia32_vbroadcastf128_ps256, "V8fV4fC*", "") -BUILTIN(__builtin_ia32_storeupd256, "vd*V4d", "") -BUILTIN(__builtin_ia32_storeups256, "vf*V8f", "") -BUILTIN(__builtin_ia32_storedqu256, "vc*V32c", "") -BUILTIN(__builtin_ia32_lddqu256, "V32ccC*", "") -BUILTIN(__builtin_ia32_movntdq256, "vV4LLi*V4LLi", "") -BUILTIN(__builtin_ia32_movntpd256, "vd*V4d", "") -BUILTIN(__builtin_ia32_movntps256, "vf*V8f", "") -BUILTIN(__builtin_ia32_maskloadpd, "V2dV2dC*V2d", "") -BUILTIN(__builtin_ia32_maskloadps, "V4fV4fC*V4f", "") -BUILTIN(__builtin_ia32_maskloadpd256, "V4dV4dC*V4d", "") -BUILTIN(__builtin_ia32_maskloadps256, "V8fV8fC*V8f", "") -BUILTIN(__builtin_ia32_maskstorepd, "vV2d*V2dV2d", "") -BUILTIN(__builtin_ia32_maskstoreps, "vV4f*V4fV4f", "") -BUILTIN(__builtin_ia32_maskstorepd256, "vV4d*V4dV4d", "") -BUILTIN(__builtin_ia32_maskstoreps256, "vV8f*V8fV8f", "") +TARGET_BUILTIN(__builtin_ia32_addsubpd256, "V4dV4dV4d", "", "avx") +TARGET_BUILTIN(__builtin_ia32_addsubps256, "V8fV8fV8f", "", "avx") +TARGET_BUILTIN(__builtin_ia32_haddpd256, "V4dV4dV4d", "", "avx") +TARGET_BUILTIN(__builtin_ia32_hsubps256, "V8fV8fV8f", "", "avx") +TARGET_BUILTIN(__builtin_ia32_hsubpd256, "V4dV4dV4d", "", "avx") +TARGET_BUILTIN(__builtin_ia32_haddps256, "V8fV8fV8f", "", "avx") +TARGET_BUILTIN(__builtin_ia32_maxpd256, "V4dV4dV4d", "", "avx") +TARGET_BUILTIN(__builtin_ia32_maxps256, "V8fV8fV8f", "", "avx") +TARGET_BUILTIN(__builtin_ia32_minpd256, "V4dV4dV4d", "", "avx") +TARGET_BUILTIN(__builtin_ia32_minps256, "V8fV8fV8f", "", "avx") +TARGET_BUILTIN(__builtin_ia32_vpermilvarpd, "V2dV2dV2LLi", "", "avx") +TARGET_BUILTIN(__builtin_ia32_vpermilvarps, "V4fV4fV4i", "", "avx") +TARGET_BUILTIN(__builtin_ia32_vpermilvarpd256, "V4dV4dV4LLi", "", "avx") +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_cmppd256, "V4dV4dV4dIc", "", "avx") +TARGET_BUILTIN(__builtin_ia32_cmpps256, "V8fV8fV8fIc", "", "avx") +TARGET_BUILTIN(__builtin_ia32_cvtdq2pd256, "V4dV4i", "", "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") +TARGET_BUILTIN(__builtin_ia32_sqrtpd256, "V4dV4d", "", "avx") +TARGET_BUILTIN(__builtin_ia32_sqrtps256, "V8fV8f", "", "avx") +TARGET_BUILTIN(__builtin_ia32_rsqrtps256, "V8fV8f", "", "avx") +TARGET_BUILTIN(__builtin_ia32_rcpps256, "V8fV8f", "", "avx") +TARGET_BUILTIN(__builtin_ia32_roundpd256, "V4dV4dIi", "", "avx") +TARGET_BUILTIN(__builtin_ia32_roundps256, "V8fV8fIi", "", "avx") +TARGET_BUILTIN(__builtin_ia32_vtestzpd, "iV2dV2d", "", "avx") +TARGET_BUILTIN(__builtin_ia32_vtestcpd, "iV2dV2d", "", "avx") +TARGET_BUILTIN(__builtin_ia32_vtestnzcpd, "iV2dV2d", "", "avx") +TARGET_BUILTIN(__builtin_ia32_vtestzps, "iV4fV4f", "", "avx") +TARGET_BUILTIN(__builtin_ia32_vtestcps, "iV4fV4f", "", "avx") +TARGET_BUILTIN(__builtin_ia32_vtestnzcps, "iV4fV4f", "", "avx") +TARGET_BUILTIN(__builtin_ia32_vtestzpd256, "iV4dV4d", "", "avx") +TARGET_BUILTIN(__builtin_ia32_vtestcpd256, "iV4dV4d", "", "avx") +TARGET_BUILTIN(__builtin_ia32_vtestnzcpd256, "iV4dV4d", "", "avx") +TARGET_BUILTIN(__builtin_ia32_vtestzps256, "iV8fV8f", "", "avx") +TARGET_BUILTIN(__builtin_ia32_vtestcps256, "iV8fV8f", "", "avx") +TARGET_BUILTIN(__builtin_ia32_vtestnzcps256, "iV8fV8f", "", "avx") +TARGET_BUILTIN(__builtin_ia32_ptestz256, "iV4LLiV4LLi", "", "avx") +TARGET_BUILTIN(__builtin_ia32_ptestc256, "iV4LLiV4LLi", "", "avx") +TARGET_BUILTIN(__builtin_ia32_ptestnzc256, "iV4LLiV4LLi", "", "avx") +TARGET_BUILTIN(__builtin_ia32_movmskpd256, "iV4d", "", "avx") +TARGET_BUILTIN(__builtin_ia32_movmskps256, "iV8f", "", "avx") +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") +TARGET_BUILTIN(__builtin_ia32_maskloadps256, "V8fV8fC*V8i", "", "avx") +TARGET_BUILTIN(__builtin_ia32_maskstorepd, "vV2d*V2LLiV2d", "", "avx") +TARGET_BUILTIN(__builtin_ia32_maskstoreps, "vV4f*V4iV4f", "", "avx") +TARGET_BUILTIN(__builtin_ia32_maskstorepd256, "vV4d*V4LLiV4d", "", "avx") +TARGET_BUILTIN(__builtin_ia32_maskstoreps256, "vV8f*V8iV8f", "", "avx") // AVX2 -BUILTIN(__builtin_ia32_mpsadbw256, "V32cV32cV32cIc", "") -BUILTIN(__builtin_ia32_pabsb256, "V32cV32c", "") -BUILTIN(__builtin_ia32_pabsw256, "V16sV16s", "") -BUILTIN(__builtin_ia32_pabsd256, "V8iV8i", "") -BUILTIN(__builtin_ia32_packsswb256, "V32cV16sV16s", "") -BUILTIN(__builtin_ia32_packssdw256, "V16sV8iV8i", "") -BUILTIN(__builtin_ia32_packuswb256, "V32cV16sV16s", "") -BUILTIN(__builtin_ia32_packusdw256, "V16sV8iV8i", "") -BUILTIN(__builtin_ia32_paddsb256, "V32cV32cV32c", "") -BUILTIN(__builtin_ia32_paddsw256, "V16sV16sV16s", "") -BUILTIN(__builtin_ia32_psubsb256, "V32cV32cV32c", "") -BUILTIN(__builtin_ia32_psubsw256, "V16sV16sV16s", "") -BUILTIN(__builtin_ia32_paddusb256, "V32cV32cV32c", "") -BUILTIN(__builtin_ia32_paddusw256, "V16sV16sV16s", "") -BUILTIN(__builtin_ia32_psubusb256, "V32cV32cV32c", "") -BUILTIN(__builtin_ia32_psubusw256, "V16sV16sV16s", "") -BUILTIN(__builtin_ia32_palignr256, "V32cV32cV32cIc", "") -BUILTIN(__builtin_ia32_pavgb256, "V32cV32cV32c", "") -BUILTIN(__builtin_ia32_pavgw256, "V16sV16sV16s", "") -BUILTIN(__builtin_ia32_pblendvb256, "V32cV32cV32cV32c", "") -BUILTIN(__builtin_ia32_phaddw256, "V16sV16sV16s", "") -BUILTIN(__builtin_ia32_phaddd256, "V8iV8iV8i", "") -BUILTIN(__builtin_ia32_phaddsw256, "V16sV16sV16s", "") -BUILTIN(__builtin_ia32_phsubw256, "V16sV16sV16s", "") -BUILTIN(__builtin_ia32_phsubd256, "V8iV8iV8i", "") -BUILTIN(__builtin_ia32_phsubsw256, "V16sV16sV16s", "") -BUILTIN(__builtin_ia32_pmaddubsw256, "V16sV32cV32c", "") -BUILTIN(__builtin_ia32_pmaddwd256, "V8iV16sV16s", "") -BUILTIN(__builtin_ia32_pmaxub256, "V32cV32cV32c", "") -BUILTIN(__builtin_ia32_pmaxuw256, "V16sV16sV16s", "") -BUILTIN(__builtin_ia32_pmaxud256, "V8iV8iV8i", "") -BUILTIN(__builtin_ia32_pmaxsb256, "V32cV32cV32c", "") -BUILTIN(__builtin_ia32_pmaxsw256, "V16sV16sV16s", "") -BUILTIN(__builtin_ia32_pmaxsd256, "V8iV8iV8i", "") -BUILTIN(__builtin_ia32_pminub256, "V32cV32cV32c", "") -BUILTIN(__builtin_ia32_pminuw256, "V16sV16sV16s", "") -BUILTIN(__builtin_ia32_pminud256, "V8iV8iV8i", "") -BUILTIN(__builtin_ia32_pminsb256, "V32cV32cV32c", "") -BUILTIN(__builtin_ia32_pminsw256, "V16sV16sV16s", "") -BUILTIN(__builtin_ia32_pminsd256, "V8iV8iV8i", "") -BUILTIN(__builtin_ia32_pmovmskb256, "iV32c", "") -BUILTIN(__builtin_ia32_pmovsxbw256, "V16sV16c", "") -BUILTIN(__builtin_ia32_pmovsxbd256, "V8iV16c", "") -BUILTIN(__builtin_ia32_pmovsxbq256, "V4LLiV16c", "") -BUILTIN(__builtin_ia32_pmovsxwd256, "V8iV8s", "") -BUILTIN(__builtin_ia32_pmovsxwq256, "V4LLiV8s", "") -BUILTIN(__builtin_ia32_pmovsxdq256, "V4LLiV4i", "") -BUILTIN(__builtin_ia32_pmovzxbw256, "V16sV16c", "") -BUILTIN(__builtin_ia32_pmovzxbd256, "V8iV16c", "") -BUILTIN(__builtin_ia32_pmovzxbq256, "V4LLiV16c", "") -BUILTIN(__builtin_ia32_pmovzxwd256, "V8iV8s", "") -BUILTIN(__builtin_ia32_pmovzxwq256, "V4LLiV8s", "") -BUILTIN(__builtin_ia32_pmovzxdq256, "V4LLiV4i", "") -BUILTIN(__builtin_ia32_pmuldq256, "V4LLiV8iV8i", "") -BUILTIN(__builtin_ia32_pmulhrsw256, "V16sV16sV16s", "") -BUILTIN(__builtin_ia32_pmulhuw256, "V16sV16sV16s", "") -BUILTIN(__builtin_ia32_pmulhw256, "V16sV16sV16s", "") -BUILTIN(__builtin_ia32_pmuludq256, "V4LLiV8iV8i", "") -BUILTIN(__builtin_ia32_psadbw256, "V4LLiV32cV32c", "") -BUILTIN(__builtin_ia32_pshufb256, "V32cV32cV32c", "") -BUILTIN(__builtin_ia32_psignb256, "V32cV32cV32c", "") -BUILTIN(__builtin_ia32_psignw256, "V16sV16sV16s", "") -BUILTIN(__builtin_ia32_psignd256, "V8iV8iV8i", "") -BUILTIN(__builtin_ia32_pslldqi256, "V4LLiV4LLiIi", "") -BUILTIN(__builtin_ia32_psllwi256, "V16sV16si", "") -BUILTIN(__builtin_ia32_psllw256, "V16sV16sV8s", "") -BUILTIN(__builtin_ia32_pslldi256, "V8iV8ii", "") -BUILTIN(__builtin_ia32_pslld256, "V8iV8iV4i", "") -BUILTIN(__builtin_ia32_psllqi256, "V4LLiV4LLii", "") -BUILTIN(__builtin_ia32_psllq256, "V4LLiV4LLiV2LLi", "") -BUILTIN(__builtin_ia32_psrawi256, "V16sV16si", "") -BUILTIN(__builtin_ia32_psraw256, "V16sV16sV8s", "") -BUILTIN(__builtin_ia32_psradi256, "V8iV8ii", "") -BUILTIN(__builtin_ia32_psrad256, "V8iV8iV4i", "") -BUILTIN(__builtin_ia32_psrldqi256, "V4LLiV4LLiIi", "") -BUILTIN(__builtin_ia32_psrlwi256, "V16sV16si", "") -BUILTIN(__builtin_ia32_psrlw256, "V16sV16sV8s", "") -BUILTIN(__builtin_ia32_psrldi256, "V8iV8ii", "") -BUILTIN(__builtin_ia32_psrld256, "V8iV8iV4i", "") -BUILTIN(__builtin_ia32_psrlqi256, "V4LLiV4LLii", "") -BUILTIN(__builtin_ia32_psrlq256, "V4LLiV4LLiV2LLi", "") -BUILTIN(__builtin_ia32_movntdqa256, "V4LLiV4LLi*", "") -BUILTIN(__builtin_ia32_vbroadcastss_ps, "V4fV4f", "") -BUILTIN(__builtin_ia32_vbroadcastss_ps256, "V8fV4f", "") -BUILTIN(__builtin_ia32_vbroadcastsd_pd256, "V4dV2d", "") -BUILTIN(__builtin_ia32_pbroadcastb256, "V32cV16c", "") -BUILTIN(__builtin_ia32_pbroadcastw256, "V16sV8s", "") -BUILTIN(__builtin_ia32_pbroadcastd256, "V8iV4i", "") -BUILTIN(__builtin_ia32_pbroadcastq256, "V4LLiV2LLi", "") -BUILTIN(__builtin_ia32_pbroadcastb128, "V16cV16c", "") -BUILTIN(__builtin_ia32_pbroadcastw128, "V8sV8s", "") -BUILTIN(__builtin_ia32_pbroadcastd128, "V4iV4i", "") -BUILTIN(__builtin_ia32_pbroadcastq128, "V2LLiV2LLi", "") -BUILTIN(__builtin_ia32_permvarsi256, "V8iV8iV8i", "") -BUILTIN(__builtin_ia32_permvarsf256, "V8fV8fV8f", "") -BUILTIN(__builtin_ia32_permti256, "V4LLiV4LLiV4LLiIc", "") -BUILTIN(__builtin_ia32_maskloadd256, "V8iV8iC*V8i", "") -BUILTIN(__builtin_ia32_maskloadq256, "V4LLiV4LLiC*V4LLi", "") -BUILTIN(__builtin_ia32_maskloadd, "V4iV4iC*V4i", "") -BUILTIN(__builtin_ia32_maskloadq, "V2LLiV2LLiC*V2LLi", "") -BUILTIN(__builtin_ia32_maskstored256, "vV8i*V8iV8i", "") -BUILTIN(__builtin_ia32_maskstoreq256, "vV4LLi*V4LLiV4LLi", "") -BUILTIN(__builtin_ia32_maskstored, "vV4i*V4iV4i", "") -BUILTIN(__builtin_ia32_maskstoreq, "vV2LLi*V2LLiV2LLi", "") -BUILTIN(__builtin_ia32_psllv8si, "V8iV8iV8i", "") -BUILTIN(__builtin_ia32_psllv4si, "V4iV4iV4i", "") -BUILTIN(__builtin_ia32_psllv4di, "V4LLiV4LLiV4LLi", "") -BUILTIN(__builtin_ia32_psllv2di, "V2LLiV2LLiV2LLi", "") -BUILTIN(__builtin_ia32_psrav8si, "V8iV8iV8i", "") -BUILTIN(__builtin_ia32_psrav4si, "V4iV4iV4i", "") -BUILTIN(__builtin_ia32_psrlv8si, "V8iV8iV8i", "") -BUILTIN(__builtin_ia32_psrlv4si, "V4iV4iV4i", "") -BUILTIN(__builtin_ia32_psrlv4di, "V4LLiV4LLiV4LLi", "") -BUILTIN(__builtin_ia32_psrlv2di, "V2LLiV2LLiV2LLi", "") +TARGET_BUILTIN(__builtin_ia32_mpsadbw256, "V32cV32cV32cIc", "", "avx2") +TARGET_BUILTIN(__builtin_ia32_pabsb256, "V32cV32c", "", "avx2") +TARGET_BUILTIN(__builtin_ia32_pabsw256, "V16sV16s", "", "avx2") +TARGET_BUILTIN(__builtin_ia32_pabsd256, "V8iV8i", "", "avx2") +TARGET_BUILTIN(__builtin_ia32_packsswb256, "V32cV16sV16s", "", "avx2") +TARGET_BUILTIN(__builtin_ia32_packssdw256, "V16sV8iV8i", "", "avx2") +TARGET_BUILTIN(__builtin_ia32_packuswb256, "V32cV16sV16s", "", "avx2") +TARGET_BUILTIN(__builtin_ia32_packusdw256, "V16sV8iV8i", "", "avx2") +TARGET_BUILTIN(__builtin_ia32_paddsb256, "V32cV32cV32c", "", "avx2") +TARGET_BUILTIN(__builtin_ia32_paddsw256, "V16sV16sV16s", "", "avx2") +TARGET_BUILTIN(__builtin_ia32_psubsb256, "V32cV32cV32c", "", "avx2") +TARGET_BUILTIN(__builtin_ia32_psubsw256, "V16sV16sV16s", "", "avx2") +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_pavgb256, "V32cV32cV32c", "", "avx2") +TARGET_BUILTIN(__builtin_ia32_pavgw256, "V16sV16sV16s", "", "avx2") +TARGET_BUILTIN(__builtin_ia32_pblendvb256, "V32cV32cV32cV32c", "", "avx2") +TARGET_BUILTIN(__builtin_ia32_phaddw256, "V16sV16sV16s", "", "avx2") +TARGET_BUILTIN(__builtin_ia32_phaddd256, "V8iV8iV8i", "", "avx2") +TARGET_BUILTIN(__builtin_ia32_phaddsw256, "V16sV16sV16s", "", "avx2") +TARGET_BUILTIN(__builtin_ia32_phsubw256, "V16sV16sV16s", "", "avx2") +TARGET_BUILTIN(__builtin_ia32_phsubd256, "V8iV8iV8i", "", "avx2") +TARGET_BUILTIN(__builtin_ia32_phsubsw256, "V16sV16sV16s", "", "avx2") +TARGET_BUILTIN(__builtin_ia32_pmaddubsw256, "V16sV32cV32c", "", "avx2") +TARGET_BUILTIN(__builtin_ia32_pmaddwd256, "V8iV16sV16s", "", "avx2") +TARGET_BUILTIN(__builtin_ia32_pmaxub256, "V32cV32cV32c", "", "avx2") +TARGET_BUILTIN(__builtin_ia32_pmaxuw256, "V16sV16sV16s", "", "avx2") +TARGET_BUILTIN(__builtin_ia32_pmaxud256, "V8iV8iV8i", "", "avx2") +TARGET_BUILTIN(__builtin_ia32_pmaxsb256, "V32cV32cV32c", "", "avx2") +TARGET_BUILTIN(__builtin_ia32_pmaxsw256, "V16sV16sV16s", "", "avx2") +TARGET_BUILTIN(__builtin_ia32_pmaxsd256, "V8iV8iV8i", "", "avx2") +TARGET_BUILTIN(__builtin_ia32_pminub256, "V32cV32cV32c", "", "avx2") +TARGET_BUILTIN(__builtin_ia32_pminuw256, "V16sV16sV16s", "", "avx2") +TARGET_BUILTIN(__builtin_ia32_pminud256, "V8iV8iV8i", "", "avx2") +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") +TARGET_BUILTIN(__builtin_ia32_pmulhw256, "V16sV16sV16s", "", "avx2") +TARGET_BUILTIN(__builtin_ia32_pmuludq256, "V4LLiV8iV8i", "", "avx2") +TARGET_BUILTIN(__builtin_ia32_psadbw256, "V4LLiV32cV32c", "", "avx2") +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") +TARGET_BUILTIN(__builtin_ia32_pslld256, "V8iV8iV4i", "", "avx2") +TARGET_BUILTIN(__builtin_ia32_psllqi256, "V4LLiV4LLii", "", "avx2") +TARGET_BUILTIN(__builtin_ia32_psllq256, "V4LLiV4LLiV2LLi", "", "avx2") +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") +TARGET_BUILTIN(__builtin_ia32_psrld256, "V8iV8iV4i", "", "avx2") +TARGET_BUILTIN(__builtin_ia32_psrlqi256, "V4LLiV4LLii", "", "avx2") +TARGET_BUILTIN(__builtin_ia32_psrlq256, "V4LLiV4LLiV2LLi", "", "avx2") +TARGET_BUILTIN(__builtin_ia32_movntdqa256, "V4LLiV4LLiC*", "", "avx2") +TARGET_BUILTIN(__builtin_ia32_permvarsi256, "V8iV8iV8i", "", "avx2") +TARGET_BUILTIN(__builtin_ia32_permvarsf256, "V8fV8fV8i", "", "avx2") +TARGET_BUILTIN(__builtin_ia32_permti256, "V4LLiV4LLiV4LLiIc", "", "avx2") +TARGET_BUILTIN(__builtin_ia32_maskloadd256, "V8iV8iC*V8i", "", "avx2") +TARGET_BUILTIN(__builtin_ia32_maskloadq256, "V4LLiV4LLiC*V4LLi", "", "avx2") +TARGET_BUILTIN(__builtin_ia32_maskloadd, "V4iV4iC*V4i", "", "avx2") +TARGET_BUILTIN(__builtin_ia32_maskloadq, "V2LLiV2LLiC*V2LLi", "", "avx2") +TARGET_BUILTIN(__builtin_ia32_maskstored256, "vV8i*V8iV8i", "", "avx2") +TARGET_BUILTIN(__builtin_ia32_maskstoreq256, "vV4LLi*V4LLiV4LLi", "", "avx2") +TARGET_BUILTIN(__builtin_ia32_maskstored, "vV4i*V4iV4i", "", "avx2") +TARGET_BUILTIN(__builtin_ia32_maskstoreq, "vV2LLi*V2LLiV2LLi", "", "avx2") +TARGET_BUILTIN(__builtin_ia32_psllv8si, "V8iV8iV8i", "", "avx2") +TARGET_BUILTIN(__builtin_ia32_psllv4si, "V4iV4iV4i", "", "avx2") +TARGET_BUILTIN(__builtin_ia32_psllv4di, "V4LLiV4LLiV4LLi", "", "avx2") +TARGET_BUILTIN(__builtin_ia32_psllv2di, "V2LLiV2LLiV2LLi", "", "avx2") +TARGET_BUILTIN(__builtin_ia32_psrav8si, "V8iV8iV8i", "", "avx2") +TARGET_BUILTIN(__builtin_ia32_psrav4si, "V4iV4iV4i", "", "avx2") +TARGET_BUILTIN(__builtin_ia32_psrlv8si, "V8iV8iV8i", "", "avx2") +TARGET_BUILTIN(__builtin_ia32_psrlv4si, "V4iV4iV4i", "", "avx2") +TARGET_BUILTIN(__builtin_ia32_psrlv4di, "V4LLiV4LLiV4LLi", "", "avx2") +TARGET_BUILTIN(__builtin_ia32_psrlv2di, "V2LLiV2LLiV2LLi", "", "avx2") // GATHER -BUILTIN(__builtin_ia32_gatherd_pd, "V2dV2dV2dC*V4iV2dIc", "") -BUILTIN(__builtin_ia32_gatherd_pd256, "V4dV4dV4dC*V4iV4dIc", "") -BUILTIN(__builtin_ia32_gatherq_pd, "V2dV2dV2dC*V2LLiV2dIc", "") -BUILTIN(__builtin_ia32_gatherq_pd256, "V4dV4dV4dC*V4LLiV4dIc", "") -BUILTIN(__builtin_ia32_gatherd_ps, "V4fV4fV4fC*V4iV4fIc", "") -BUILTIN(__builtin_ia32_gatherd_ps256, "V8fV8fV8fC*V8iV8fIc", "") -BUILTIN(__builtin_ia32_gatherq_ps, "V4fV4fV4fC*V2LLiV4fIc", "") -BUILTIN(__builtin_ia32_gatherq_ps256, "V4fV4fV4fC*V4LLiV4fIc", "") - -BUILTIN(__builtin_ia32_gatherd_q, "V2LLiV2LLiV2LLiC*V4iV2LLiIc", "") -BUILTIN(__builtin_ia32_gatherd_q256, "V4LLiV4LLiV4LLiC*V4iV4LLiIc", "") -BUILTIN(__builtin_ia32_gatherq_q, "V2LLiV2LLiV2LLiC*V2LLiV2LLiIc", "") -BUILTIN(__builtin_ia32_gatherq_q256, "V4LLiV4LLiV4LLiC*V4LLiV4LLiIc", "") -BUILTIN(__builtin_ia32_gatherd_d, "V4iV4iV4iC*V4iV4iIc", "") -BUILTIN(__builtin_ia32_gatherd_d256, "V8iV8iV8iC*V8iV8iIc", "") -BUILTIN(__builtin_ia32_gatherq_d, "V4iV4iV4iC*V2LLiV4iIc", "") -BUILTIN(__builtin_ia32_gatherq_d256, "V4iV4iV4iC*V4LLiV4iIc", "") +TARGET_BUILTIN(__builtin_ia32_gatherd_pd, "V2dV2ddC*V4iV2dIc", "", "avx2") +TARGET_BUILTIN(__builtin_ia32_gatherd_pd256, "V4dV4ddC*V4iV4dIc", "", "avx2") +TARGET_BUILTIN(__builtin_ia32_gatherq_pd, "V2dV2ddC*V2LLiV2dIc", "", "avx2") +TARGET_BUILTIN(__builtin_ia32_gatherq_pd256, "V4dV4ddC*V4LLiV4dIc", "", "avx2") +TARGET_BUILTIN(__builtin_ia32_gatherd_ps, "V4fV4ffC*V4iV4fIc", "", "avx2") +TARGET_BUILTIN(__builtin_ia32_gatherd_ps256, "V8fV8ffC*V8iV8fIc", "", "avx2") +TARGET_BUILTIN(__builtin_ia32_gatherq_ps, "V4fV4ffC*V2LLiV4fIc", "", "avx2") +TARGET_BUILTIN(__builtin_ia32_gatherq_ps256, "V4fV4ffC*V4LLiV4fIc", "", "avx2") + +TARGET_BUILTIN(__builtin_ia32_gatherd_q, "V2LLiV2LLiLLiC*V4iV2LLiIc", "", "avx2") +TARGET_BUILTIN(__builtin_ia32_gatherd_q256, "V4LLiV4LLiLLiC*V4iV4LLiIc", "", "avx2") +TARGET_BUILTIN(__builtin_ia32_gatherq_q, "V2LLiV2LLiLLiC*V2LLiV2LLiIc", "", "avx2") +TARGET_BUILTIN(__builtin_ia32_gatherq_q256, "V4LLiV4LLiLLiC*V4LLiV4LLiIc", "", "avx2") +TARGET_BUILTIN(__builtin_ia32_gatherd_d, "V4iV4iiC*V4iV4iIc", "", "avx2") +TARGET_BUILTIN(__builtin_ia32_gatherd_d256, "V8iV8iiC*V8iV8iIc", "", "avx2") +TARGET_BUILTIN(__builtin_ia32_gatherq_d, "V4iV4iiC*V2LLiV4iIc", "", "avx2") +TARGET_BUILTIN(__builtin_ia32_gatherq_d256, "V4iV4iiC*V4LLiV4iIc", "", "avx2") // F16C -BUILTIN(__builtin_ia32_vcvtps2ph, "V8sV4fIi", "") -BUILTIN(__builtin_ia32_vcvtps2ph256, "V8sV8fIi", "") -BUILTIN(__builtin_ia32_vcvtps2ph512, "V16sV16fIi", "") -BUILTIN(__builtin_ia32_vcvtph2ps, "V4fV8s", "") -BUILTIN(__builtin_ia32_vcvtph2ps256, "V8fV8s", "") -BUILTIN(__builtin_ia32_vcvtph2ps512, "V16fV16s", "") +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 -BUILTIN(__builtin_ia32_rdrand16_step, "UiUs*", "") -BUILTIN(__builtin_ia32_rdrand32_step, "UiUi*", "") -BUILTIN(__builtin_ia32_rdrand64_step, "UiULLi*", "") +TARGET_BUILTIN(__builtin_ia32_rdrand16_step, "UiUs*", "", "rdrnd") +TARGET_BUILTIN(__builtin_ia32_rdrand32_step, "UiUi*", "", "rdrnd") +TARGET_BUILTIN(__builtin_ia32_rdrand64_step, "UiULLi*", "", "rdrnd") // FSGSBASE -BUILTIN(__builtin_ia32_rdfsbase32, "Ui", "") -BUILTIN(__builtin_ia32_rdfsbase64, "ULLi", "") -BUILTIN(__builtin_ia32_rdgsbase32, "Ui", "") -BUILTIN(__builtin_ia32_rdgsbase64, "ULLi", "") -BUILTIN(__builtin_ia32_wrfsbase32, "vUi", "") -BUILTIN(__builtin_ia32_wrfsbase64, "vULLi", "") -BUILTIN(__builtin_ia32_wrgsbase32, "vUi", "") -BUILTIN(__builtin_ia32_wrgsbase64, "vULLi", "") +TARGET_BUILTIN(__builtin_ia32_rdfsbase32, "Ui", "", "fsgsbase") +TARGET_BUILTIN(__builtin_ia32_rdfsbase64, "ULLi", "", "fsgsbase") +TARGET_BUILTIN(__builtin_ia32_rdgsbase32, "Ui", "", "fsgsbase") +TARGET_BUILTIN(__builtin_ia32_rdgsbase64, "ULLi", "", "fsgsbase") +TARGET_BUILTIN(__builtin_ia32_wrfsbase32, "vUi", "", "fsgsbase") +TARGET_BUILTIN(__builtin_ia32_wrfsbase64, "vULLi", "", "fsgsbase") +TARGET_BUILTIN(__builtin_ia32_wrgsbase32, "vUi", "", "fsgsbase") +TARGET_BUILTIN(__builtin_ia32_wrgsbase64, "vULLi", "", "fsgsbase") // FXSR -BUILTIN(__builtin_ia32_fxrstor, "vv*", "") -BUILTIN(__builtin_ia32_fxrstor64, "vv*", "") -BUILTIN(__builtin_ia32_fxsave, "vv*", "") -BUILTIN(__builtin_ia32_fxsave64, "vv*", "") +TARGET_BUILTIN(__builtin_ia32_fxrstor, "vv*", "", "fxsr") +TARGET_BUILTIN(__builtin_ia32_fxrstor64, "vv*", "", "fxsr") +TARGET_BUILTIN(__builtin_ia32_fxsave, "vv*", "", "fxsr") +TARGET_BUILTIN(__builtin_ia32_fxsave64, "vv*", "", "fxsr") + +// XSAVE +TARGET_BUILTIN(__builtin_ia32_xsave, "vv*ULLi", "", "xsave") +TARGET_BUILTIN(__builtin_ia32_xsave64, "vv*ULLi", "", "xsave") +TARGET_BUILTIN(__builtin_ia32_xrstor, "vv*ULLi", "", "xsave") +TARGET_BUILTIN(__builtin_ia32_xrstor64, "vv*ULLi", "", "xsave") +TARGET_BUILTIN(__builtin_ia32_xsaveopt, "vv*ULLi", "", "xsaveopt") +TARGET_BUILTIN(__builtin_ia32_xsaveopt64, "vv*ULLi", "", "xsaveopt") +TARGET_BUILTIN(__builtin_ia32_xrstors, "vv*ULLi", "", "xsaves") +TARGET_BUILTIN(__builtin_ia32_xrstors64, "vv*ULLi", "", "xsaves") +TARGET_BUILTIN(__builtin_ia32_xsavec, "vv*ULLi", "", "xsavec") +TARGET_BUILTIN(__builtin_ia32_xsavec64, "vv*ULLi", "", "xsavec") +TARGET_BUILTIN(__builtin_ia32_xsaves, "vv*ULLi", "", "xsaves") +TARGET_BUILTIN(__builtin_ia32_xsaves64, "vv*ULLi", "", "xsaves") // ADX -BUILTIN(__builtin_ia32_addcarryx_u32, "UcUcUiUiUi*", "") -BUILTIN(__builtin_ia32_addcarryx_u64, "UcUcULLiULLiULLi*", "") -BUILTIN(__builtin_ia32_addcarry_u32, "UcUcUiUiUi*", "") -BUILTIN(__builtin_ia32_addcarry_u64, "UcUcULLiULLiULLi*", "") -BUILTIN(__builtin_ia32_subborrow_u32, "UcUcUiUiUi*", "") -BUILTIN(__builtin_ia32_subborrow_u64, "UcUcULLiULLiULLi*", "") +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") // RDSEED -BUILTIN(__builtin_ia32_rdseed16_step, "UiUs*", "") -BUILTIN(__builtin_ia32_rdseed32_step, "UiUi*", "") -BUILTIN(__builtin_ia32_rdseed64_step, "UiULLi*", "") +TARGET_BUILTIN(__builtin_ia32_rdseed16_step, "UiUs*", "", "rdseed") +TARGET_BUILTIN(__builtin_ia32_rdseed32_step, "UiUi*", "", "rdseed") +TARGET_BUILTIN(__builtin_ia32_rdseed64_step, "UiULLi*", "", "rdseed") // BMI -BUILTIN(__builtin_ia32_bextr_u32, "UiUiUi", "") -BUILTIN(__builtin_ia32_bextr_u64, "ULLiULLiULLi", "") +TARGET_BUILTIN(__builtin_ia32_bextr_u32, "UiUiUi", "", "bmi") +TARGET_BUILTIN(__builtin_ia32_bextr_u64, "ULLiULLiULLi", "", "bmi") // BMI2 -BUILTIN(__builtin_ia32_bzhi_si, "UiUiUi", "") -BUILTIN(__builtin_ia32_bzhi_di, "ULLiULLiULLi", "") -BUILTIN(__builtin_ia32_pdep_si, "UiUiUi", "") -BUILTIN(__builtin_ia32_pdep_di, "ULLiULLiULLi", "") -BUILTIN(__builtin_ia32_pext_si, "UiUiUi", "") -BUILTIN(__builtin_ia32_pext_di, "ULLiULLiULLi", "") +TARGET_BUILTIN(__builtin_ia32_bzhi_si, "UiUiUi", "", "bmi2") +TARGET_BUILTIN(__builtin_ia32_bzhi_di, "ULLiULLiULLi", "", "bmi2") +TARGET_BUILTIN(__builtin_ia32_pdep_si, "UiUiUi", "", "bmi2") +TARGET_BUILTIN(__builtin_ia32_pdep_di, "ULLiULLiULLi", "", "bmi2") +TARGET_BUILTIN(__builtin_ia32_pext_si, "UiUiUi", "", "bmi2") +TARGET_BUILTIN(__builtin_ia32_pext_di, "ULLiULLiULLi", "", "bmi2") // TBM -BUILTIN(__builtin_ia32_bextri_u32, "UiUiIUi", "") -BUILTIN(__builtin_ia32_bextri_u64, "ULLiULLiIULLi", "") +TARGET_BUILTIN(__builtin_ia32_bextri_u32, "UiUiIUi", "", "tbm") +TARGET_BUILTIN(__builtin_ia32_bextri_u64, "ULLiULLiIULLi", "", "tbm") // SHA -BUILTIN(__builtin_ia32_sha1rnds4, "V4iV4iV4iIc", "") -BUILTIN(__builtin_ia32_sha1nexte, "V4iV4iV4i", "") -BUILTIN(__builtin_ia32_sha1msg1, "V4iV4iV4i", "") -BUILTIN(__builtin_ia32_sha1msg2, "V4iV4iV4i", "") -BUILTIN(__builtin_ia32_sha256rnds2, "V4iV4iV4iV4i", "") -BUILTIN(__builtin_ia32_sha256msg1, "V4iV4iV4i", "") -BUILTIN(__builtin_ia32_sha256msg2, "V4iV4iV4i", "") +TARGET_BUILTIN(__builtin_ia32_sha1rnds4, "V4iV4iV4iIc", "", "sha") +TARGET_BUILTIN(__builtin_ia32_sha1nexte, "V4iV4iV4i", "", "sha") +TARGET_BUILTIN(__builtin_ia32_sha1msg1, "V4iV4iV4i", "", "sha") +TARGET_BUILTIN(__builtin_ia32_sha1msg2, "V4iV4iV4i", "", "sha") +TARGET_BUILTIN(__builtin_ia32_sha256rnds2, "V4iV4iV4iV4i", "", "sha") +TARGET_BUILTIN(__builtin_ia32_sha256msg1, "V4iV4iV4i", "", "sha") +TARGET_BUILTIN(__builtin_ia32_sha256msg2, "V4iV4iV4i", "", "sha") // FMA -BUILTIN(__builtin_ia32_vfmaddps, "V4fV4fV4fV4f", "") -BUILTIN(__builtin_ia32_vfmaddpd, "V2dV2dV2dV2d", "") -BUILTIN(__builtin_ia32_vfmaddss, "V4fV4fV4fV4f", "") -BUILTIN(__builtin_ia32_vfmaddsd, "V2dV2dV2dV2d", "") -BUILTIN(__builtin_ia32_vfmsubps, "V4fV4fV4fV4f", "") -BUILTIN(__builtin_ia32_vfmsubpd, "V2dV2dV2dV2d", "") -BUILTIN(__builtin_ia32_vfmsubss, "V4fV4fV4fV4f", "") -BUILTIN(__builtin_ia32_vfmsubsd, "V2dV2dV2dV2d", "") -BUILTIN(__builtin_ia32_vfnmaddps, "V4fV4fV4fV4f", "") -BUILTIN(__builtin_ia32_vfnmaddpd, "V2dV2dV2dV2d", "") -BUILTIN(__builtin_ia32_vfnmaddss, "V4fV4fV4fV4f", "") -BUILTIN(__builtin_ia32_vfnmaddsd, "V2dV2dV2dV2d", "") -BUILTIN(__builtin_ia32_vfnmsubps, "V4fV4fV4fV4f", "") -BUILTIN(__builtin_ia32_vfnmsubpd, "V2dV2dV2dV2d", "") -BUILTIN(__builtin_ia32_vfnmsubss, "V4fV4fV4fV4f", "") -BUILTIN(__builtin_ia32_vfnmsubsd, "V2dV2dV2dV2d", "") -BUILTIN(__builtin_ia32_vfmaddsubps, "V4fV4fV4fV4f", "") -BUILTIN(__builtin_ia32_vfmaddsubpd, "V2dV2dV2dV2d", "") -BUILTIN(__builtin_ia32_vfmsubaddps, "V4fV4fV4fV4f", "") -BUILTIN(__builtin_ia32_vfmsubaddpd, "V2dV2dV2dV2d", "") -BUILTIN(__builtin_ia32_vfmaddps256, "V8fV8fV8fV8f", "") -BUILTIN(__builtin_ia32_vfmaddpd256, "V4dV4dV4dV4d", "") -BUILTIN(__builtin_ia32_vfmsubps256, "V8fV8fV8fV8f", "") -BUILTIN(__builtin_ia32_vfmsubpd256, "V4dV4dV4dV4d", "") -BUILTIN(__builtin_ia32_vfnmaddps256, "V8fV8fV8fV8f", "") -BUILTIN(__builtin_ia32_vfnmaddpd256, "V4dV4dV4dV4d", "") -BUILTIN(__builtin_ia32_vfnmsubps256, "V8fV8fV8fV8f", "") -BUILTIN(__builtin_ia32_vfnmsubpd256, "V4dV4dV4dV4d", "") -BUILTIN(__builtin_ia32_vfmaddsubps256, "V8fV8fV8fV8f", "") -BUILTIN(__builtin_ia32_vfmaddsubpd256, "V4dV4dV4dV4d", "") -BUILTIN(__builtin_ia32_vfmsubaddps256, "V8fV8fV8fV8f", "") -BUILTIN(__builtin_ia32_vfmsubaddpd256, "V4dV4dV4dV4d", "") -BUILTIN(__builtin_ia32_vfmaddpd128_mask, "V2dV2dV2dV2dUc", "") -BUILTIN(__builtin_ia32_vfmaddpd128_mask3, "V2dV2dV2dV2dUc", "") -BUILTIN(__builtin_ia32_vfmaddpd128_maskz, "V2dV2dV2dV2dUc", "") -BUILTIN(__builtin_ia32_vfmaddpd256_mask, "V4dV4dV4dV4dUc", "") -BUILTIN(__builtin_ia32_vfmaddpd256_mask3, "V4dV4dV4dV4dUc", "") -BUILTIN(__builtin_ia32_vfmaddpd256_maskz, "V4dV4dV4dV4dUc", "") -BUILTIN(__builtin_ia32_vfmaddpd512_mask, "V8dV8dV8dV8dUcIi", "") -BUILTIN(__builtin_ia32_vfmaddpd512_mask3, "V8dV8dV8dV8dUcIi", "") -BUILTIN(__builtin_ia32_vfmaddpd512_maskz, "V8dV8dV8dV8dUcIi", "") -BUILTIN(__builtin_ia32_vfmaddps128_mask, "V4fV4fV4fV4fUc", "") -BUILTIN(__builtin_ia32_vfmaddps128_mask3, "V4fV4fV4fV4fUc", "") -BUILTIN(__builtin_ia32_vfmaddps128_maskz, "V4fV4fV4fV4fUc", "") -BUILTIN(__builtin_ia32_vfmaddps256_mask, "V8fV8fV8fV8fUc", "") -BUILTIN(__builtin_ia32_vfmaddps256_mask3, "V8fV8fV8fV8fUc", "") -BUILTIN(__builtin_ia32_vfmaddps256_maskz, "V8fV8fV8fV8fUc", "") -BUILTIN(__builtin_ia32_vfmaddps512_mask, "V16fV16fV16fV16fUsIi", "") -BUILTIN(__builtin_ia32_vfmaddps512_mask3, "V16fV16fV16fV16fUsIi", "") -BUILTIN(__builtin_ia32_vfmaddps512_maskz, "V16fV16fV16fV16fUsIi", "") -BUILTIN(__builtin_ia32_vfmaddsubpd128_mask, "V2dV2dV2dV2dUc", "") -BUILTIN(__builtin_ia32_vfmaddsubpd128_mask3, "V2dV2dV2dV2dUc", "") -BUILTIN(__builtin_ia32_vfmaddsubpd128_maskz, "V2dV2dV2dV2dUc", "") -BUILTIN(__builtin_ia32_vfmaddsubpd256_mask, "V4dV4dV4dV4dUc", "") -BUILTIN(__builtin_ia32_vfmaddsubpd256_mask3, "V4dV4dV4dV4dUc", "") -BUILTIN(__builtin_ia32_vfmaddsubpd256_maskz, "V4dV4dV4dV4dUc", "") -BUILTIN(__builtin_ia32_vfmaddsubpd512_mask, "V8dV8dV8dV8dUcIi", "") -BUILTIN(__builtin_ia32_vfmaddsubpd512_mask3, "V8dV8dV8dV8dUcIi", "") -BUILTIN(__builtin_ia32_vfmaddsubpd512_maskz, "V8dV8dV8dV8dUcIi", "") -BUILTIN(__builtin_ia32_vfmaddsubps128_mask, "V4fV4fV4fV4fUc", "") -BUILTIN(__builtin_ia32_vfmaddsubps128_mask3, "V4fV4fV4fV4fUc", "") -BUILTIN(__builtin_ia32_vfmaddsubps128_maskz, "V4fV4fV4fV4fUc", "") -BUILTIN(__builtin_ia32_vfmaddsubps256_mask, "V8fV8fV8fV8fUc", "") -BUILTIN(__builtin_ia32_vfmaddsubps256_mask3, "V8fV8fV8fV8fUc", "") -BUILTIN(__builtin_ia32_vfmaddsubps256_maskz, "V8fV8fV8fV8fUc", "") -BUILTIN(__builtin_ia32_vfmaddsubps512_mask, "V16fV16fV16fV16fUsIi", "") -BUILTIN(__builtin_ia32_vfmaddsubps512_mask3, "V16fV16fV16fV16fUsIi", "") -BUILTIN(__builtin_ia32_vfmaddsubps512_maskz, "V16fV16fV16fV16fUsIi", "") -BUILTIN(__builtin_ia32_vfmsubpd128_mask3, "V2dV2dV2dV2dUc", "") -BUILTIN(__builtin_ia32_vfmsubpd256_mask3, "V4dV4dV4dV4dUc", "") -BUILTIN(__builtin_ia32_vfmsubpd512_mask3, "V8dV8dV8dV8dUcIi", "") -BUILTIN(__builtin_ia32_vfmsubps128_mask3, "V4fV4fV4fV4fUc", "") -BUILTIN(__builtin_ia32_vfmsubps256_mask3, "V8fV8fV8fV8fUc", "") -BUILTIN(__builtin_ia32_vfmsubps512_mask3, "V16fV16fV16fV16fUsIi", "") -BUILTIN(__builtin_ia32_vfmsubaddpd128_mask3, "V2dV2dV2dV2dUc", "") -BUILTIN(__builtin_ia32_vfmsubaddpd256_mask3, "V4dV4dV4dV4dUc", "") -BUILTIN(__builtin_ia32_vfmsubaddpd512_mask3, "V8dV8dV8dV8dUcIi", "") -BUILTIN(__builtin_ia32_vfmsubaddps128_mask3, "V4fV4fV4fV4fUc", "") -BUILTIN(__builtin_ia32_vfmsubaddps256_mask3, "V8fV8fV8fV8fUc", "") -BUILTIN(__builtin_ia32_vfmsubaddps512_mask3, "V16fV16fV16fV16fUsIi", "") -BUILTIN(__builtin_ia32_vfnmaddpd128_mask, "V2dV2dV2dV2dUc", "") -BUILTIN(__builtin_ia32_vfnmaddpd256_mask, "V4dV4dV4dV4dUc", "") -BUILTIN(__builtin_ia32_vfnmaddpd512_mask, "V8dV8dV8dV8dUcIi", "") -BUILTIN(__builtin_ia32_vfnmaddps128_mask, "V4fV4fV4fV4fUc", "") -BUILTIN(__builtin_ia32_vfnmaddps256_mask, "V8fV8fV8fV8fUc", "") -BUILTIN(__builtin_ia32_vfnmaddps512_mask, "V16fV16fV16fV16fUsIi", "") -BUILTIN(__builtin_ia32_vfnmsubpd128_mask, "V2dV2dV2dV2dUc", "") -BUILTIN(__builtin_ia32_vfnmsubpd128_mask3, "V2dV2dV2dV2dUc", "") -BUILTIN(__builtin_ia32_vfnmsubpd256_mask, "V4dV4dV4dV4dUc", "") -BUILTIN(__builtin_ia32_vfnmsubpd256_mask3, "V4dV4dV4dV4dUc", "") -BUILTIN(__builtin_ia32_vfnmsubpd512_mask, "V8dV8dV8dV8dUcIi", "") -BUILTIN(__builtin_ia32_vfnmsubpd512_mask3, "V8dV8dV8dV8dUcIi", "") -BUILTIN(__builtin_ia32_vfnmsubps128_mask, "V4fV4fV4fV4fUc", "") -BUILTIN(__builtin_ia32_vfnmsubps128_mask3, "V4fV4fV4fV4fUc", "") -BUILTIN(__builtin_ia32_vfnmsubps256_mask, "V8fV8fV8fV8fUc", "") -BUILTIN(__builtin_ia32_vfnmsubps256_mask3, "V8fV8fV8fV8fUc", "") -BUILTIN(__builtin_ia32_vfnmsubps512_mask, "V16fV16fV16fV16fUsIi", "") -BUILTIN(__builtin_ia32_vfnmsubps512_mask3, "V16fV16fV16fV16fUsIi", "") +TARGET_BUILTIN(__builtin_ia32_vfmaddps, "V4fV4fV4fV4f", "", "fma|fma4") +TARGET_BUILTIN(__builtin_ia32_vfmaddpd, "V2dV2dV2dV2d", "", "fma|fma4") +TARGET_BUILTIN(__builtin_ia32_vfmaddss, "V4fV4fV4fV4f", "", "fma|fma4") +TARGET_BUILTIN(__builtin_ia32_vfmaddsd, "V2dV2dV2dV2d", "", "fma|fma4") +TARGET_BUILTIN(__builtin_ia32_vfmsubps, "V4fV4fV4fV4f", "", "fma|fma4") +TARGET_BUILTIN(__builtin_ia32_vfmsubpd, "V2dV2dV2dV2d", "", "fma|fma4") +TARGET_BUILTIN(__builtin_ia32_vfmsubss, "V4fV4fV4fV4f", "", "fma|fma4") +TARGET_BUILTIN(__builtin_ia32_vfmsubsd, "V2dV2dV2dV2d", "", "fma|fma4") +TARGET_BUILTIN(__builtin_ia32_vfnmaddps, "V4fV4fV4fV4f", "", "fma|fma4") +TARGET_BUILTIN(__builtin_ia32_vfnmaddpd, "V2dV2dV2dV2d", "", "fma|fma4") +TARGET_BUILTIN(__builtin_ia32_vfnmaddss, "V4fV4fV4fV4f", "", "fma|fma4") +TARGET_BUILTIN(__builtin_ia32_vfnmaddsd, "V2dV2dV2dV2d", "", "fma|fma4") +TARGET_BUILTIN(__builtin_ia32_vfnmsubps, "V4fV4fV4fV4f", "", "fma|fma4") +TARGET_BUILTIN(__builtin_ia32_vfnmsubpd, "V2dV2dV2dV2d", "", "fma|fma4") +TARGET_BUILTIN(__builtin_ia32_vfnmsubss, "V4fV4fV4fV4f", "", "fma|fma4") +TARGET_BUILTIN(__builtin_ia32_vfnmsubsd, "V2dV2dV2dV2d", "", "fma|fma4") +TARGET_BUILTIN(__builtin_ia32_vfmaddsubps, "V4fV4fV4fV4f", "", "fma|fma4") +TARGET_BUILTIN(__builtin_ia32_vfmaddsubpd, "V2dV2dV2dV2d", "", "fma|fma4") +TARGET_BUILTIN(__builtin_ia32_vfmsubaddps, "V4fV4fV4fV4f", "", "fma|fma4") +TARGET_BUILTIN(__builtin_ia32_vfmsubaddpd, "V2dV2dV2dV2d", "", "fma|fma4") +TARGET_BUILTIN(__builtin_ia32_vfmaddps256, "V8fV8fV8fV8f", "", "fma|fma4") +TARGET_BUILTIN(__builtin_ia32_vfmaddpd256, "V4dV4dV4dV4d", "", "fma|fma4") +TARGET_BUILTIN(__builtin_ia32_vfmsubps256, "V8fV8fV8fV8f", "", "fma|fma4") +TARGET_BUILTIN(__builtin_ia32_vfmsubpd256, "V4dV4dV4dV4d", "", "fma|fma4") +TARGET_BUILTIN(__builtin_ia32_vfnmaddps256, "V8fV8fV8fV8f", "", "fma|fma4") +TARGET_BUILTIN(__builtin_ia32_vfnmaddpd256, "V4dV4dV4dV4d", "", "fma|fma4") +TARGET_BUILTIN(__builtin_ia32_vfnmsubps256, "V8fV8fV8fV8f", "", "fma|fma4") +TARGET_BUILTIN(__builtin_ia32_vfnmsubpd256, "V4dV4dV4dV4d", "", "fma|fma4") +TARGET_BUILTIN(__builtin_ia32_vfmaddsubps256, "V8fV8fV8fV8f", "", "fma|fma4") +TARGET_BUILTIN(__builtin_ia32_vfmaddsubpd256, "V4dV4dV4dV4d", "", "fma|fma4") +TARGET_BUILTIN(__builtin_ia32_vfmsubaddps256, "V8fV8fV8fV8f", "", "fma|fma4") +TARGET_BUILTIN(__builtin_ia32_vfmsubaddpd256, "V4dV4dV4dV4d", "", "fma|fma4") + +TARGET_BUILTIN(__builtin_ia32_vfmaddpd128_mask, "V2dV2dV2dV2dUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_vfmaddpd128_mask3, "V2dV2dV2dV2dUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_vfmaddpd128_maskz, "V2dV2dV2dV2dUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_vfmaddpd256_mask, "V4dV4dV4dV4dUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_vfmaddpd256_mask3, "V4dV4dV4dV4dUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_vfmaddpd256_maskz, "V4dV4dV4dV4dUc", "", "avx512vl") + +TARGET_BUILTIN(__builtin_ia32_vfmaddpd512_mask, "V8dV8dV8dV8dUcIi", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_vfmaddpd512_mask3, "V8dV8dV8dV8dUcIi", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_vfmaddpd512_maskz, "V8dV8dV8dV8dUcIi", "", "avx512f") + +TARGET_BUILTIN(__builtin_ia32_vfmaddps128_mask, "V4fV4fV4fV4fUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_vfmaddps128_mask3, "V4fV4fV4fV4fUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_vfmaddps128_maskz, "V4fV4fV4fV4fUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_vfmaddps256_mask, "V8fV8fV8fV8fUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_vfmaddps256_mask3, "V8fV8fV8fV8fUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_vfmaddps256_maskz, "V8fV8fV8fV8fUc", "", "avx512vl") + +TARGET_BUILTIN(__builtin_ia32_vfmaddps512_mask, "V16fV16fV16fV16fUsIi", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_vfmaddps512_mask3, "V16fV16fV16fV16fUsIi", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_vfmaddps512_maskz, "V16fV16fV16fV16fUsIi", "", "avx512f") + +TARGET_BUILTIN(__builtin_ia32_vfmaddsubpd128_mask, "V2dV2dV2dV2dUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_vfmaddsubpd128_mask3, "V2dV2dV2dV2dUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_vfmaddsubpd128_maskz, "V2dV2dV2dV2dUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_vfmaddsubpd256_mask, "V4dV4dV4dV4dUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_vfmaddsubpd256_mask3, "V4dV4dV4dV4dUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_vfmaddsubpd256_maskz, "V4dV4dV4dV4dUc", "", "avx512vl") + +TARGET_BUILTIN(__builtin_ia32_vfmaddsubpd512_mask, "V8dV8dV8dV8dUcIi", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_vfmaddsubpd512_mask3, "V8dV8dV8dV8dUcIi", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_vfmaddsubpd512_maskz, "V8dV8dV8dV8dUcIi", "", "avx512f") + +TARGET_BUILTIN(__builtin_ia32_vfmaddsubps128_mask, "V4fV4fV4fV4fUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_vfmaddsubps128_mask3, "V4fV4fV4fV4fUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_vfmaddsubps128_maskz, "V4fV4fV4fV4fUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_vfmaddsubps256_mask, "V8fV8fV8fV8fUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_vfmaddsubps256_mask3, "V8fV8fV8fV8fUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_vfmaddsubps256_maskz, "V8fV8fV8fV8fUc", "", "avx512vl") + +TARGET_BUILTIN(__builtin_ia32_vfmaddsubps512_mask, "V16fV16fV16fV16fUsIi", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_vfmaddsubps512_mask3, "V16fV16fV16fV16fUsIi", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_vfmaddsubps512_maskz, "V16fV16fV16fV16fUsIi", "", "avx512f") + +TARGET_BUILTIN(__builtin_ia32_vfmsubpd128_mask3, "V2dV2dV2dV2dUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_vfmsubpd256_mask3, "V4dV4dV4dV4dUc", "", "avx512vl") + +TARGET_BUILTIN(__builtin_ia32_vfmsubpd512_mask3, "V8dV8dV8dV8dUcIi", "", "avx512f") + +TARGET_BUILTIN(__builtin_ia32_vfmsubps128_mask3, "V4fV4fV4fV4fUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_vfmsubps256_mask3, "V8fV8fV8fV8fUc", "", "avx512vl") + +TARGET_BUILTIN(__builtin_ia32_vfmsubps512_mask3, "V16fV16fV16fV16fUsIi", "", "avx512f") + +TARGET_BUILTIN(__builtin_ia32_vfmsubaddpd128_mask3, "V2dV2dV2dV2dUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_vfmsubaddpd256_mask3, "V4dV4dV4dV4dUc", "", "avx512vl") + +TARGET_BUILTIN(__builtin_ia32_vfmsubaddpd512_mask3, "V8dV8dV8dV8dUcIi", "", "avx512f") + +TARGET_BUILTIN(__builtin_ia32_vfmsubaddps128_mask3, "V4fV4fV4fV4fUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_vfmsubaddps256_mask3, "V8fV8fV8fV8fUc", "", "avx512vl") + +TARGET_BUILTIN(__builtin_ia32_vfmsubaddps512_mask3, "V16fV16fV16fV16fUsIi", "", "avx512f") + +TARGET_BUILTIN(__builtin_ia32_vfnmaddpd128_mask, "V2dV2dV2dV2dUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_vfnmaddpd256_mask, "V4dV4dV4dV4dUc", "", "avx512vl") + +TARGET_BUILTIN(__builtin_ia32_vfnmaddpd512_mask, "V8dV8dV8dV8dUcIi", "", "avx512f") + +TARGET_BUILTIN(__builtin_ia32_vfnmaddps128_mask, "V4fV4fV4fV4fUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_vfnmaddps256_mask, "V8fV8fV8fV8fUc", "", "avx512vl") + +TARGET_BUILTIN(__builtin_ia32_vfnmaddps512_mask, "V16fV16fV16fV16fUsIi", "", "avx512f") + +TARGET_BUILTIN(__builtin_ia32_vfnmsubpd128_mask, "V2dV2dV2dV2dUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_vfnmsubpd128_mask3, "V2dV2dV2dV2dUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_vfnmsubpd256_mask, "V4dV4dV4dV4dUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_vfnmsubpd256_mask3, "V4dV4dV4dV4dUc", "", "avx512vl") + +TARGET_BUILTIN(__builtin_ia32_vfnmsubpd512_mask, "V8dV8dV8dV8dUcIi", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_vfnmsubpd512_mask3, "V8dV8dV8dV8dUcIi", "", "avx512f") + +TARGET_BUILTIN(__builtin_ia32_vfnmsubps128_mask, "V4fV4fV4fV4fUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_vfnmsubps128_mask3, "V4fV4fV4fV4fUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_vfnmsubps256_mask, "V8fV8fV8fV8fUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_vfnmsubps256_mask3, "V8fV8fV8fV8fUc", "", "avx512vl") + +TARGET_BUILTIN(__builtin_ia32_vfnmsubps512_mask, "V16fV16fV16fV16fUsIi", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_vfnmsubps512_mask3, "V16fV16fV16fV16fUsIi", "", "avx512f") // XOP -BUILTIN(__builtin_ia32_vpmacssww, "V8sV8sV8sV8s", "") -BUILTIN(__builtin_ia32_vpmacsww, "V8sV8sV8sV8s", "") -BUILTIN(__builtin_ia32_vpmacsswd, "V4iV8sV8sV4i", "") -BUILTIN(__builtin_ia32_vpmacswd, "V4iV8sV8sV4i", "") -BUILTIN(__builtin_ia32_vpmacssdd, "V4iV4iV4iV4i", "") -BUILTIN(__builtin_ia32_vpmacsdd, "V4iV4iV4iV4i", "") -BUILTIN(__builtin_ia32_vpmacssdql, "V2LLiV4iV4iV2LLi", "") -BUILTIN(__builtin_ia32_vpmacsdql, "V2LLiV4iV4iV2LLi", "") -BUILTIN(__builtin_ia32_vpmacssdqh, "V2LLiV4iV4iV2LLi", "") -BUILTIN(__builtin_ia32_vpmacsdqh, "V2LLiV4iV4iV2LLi", "") -BUILTIN(__builtin_ia32_vpmadcsswd, "V4iV8sV8sV4i", "") -BUILTIN(__builtin_ia32_vpmadcswd, "V4iV8sV8sV4i", "") - -BUILTIN(__builtin_ia32_vphaddbw, "V8sV16c", "") -BUILTIN(__builtin_ia32_vphaddbd, "V4iV16c", "") -BUILTIN(__builtin_ia32_vphaddbq, "V2LLiV16c", "") -BUILTIN(__builtin_ia32_vphaddwd, "V4iV8s", "") -BUILTIN(__builtin_ia32_vphaddwq, "V2LLiV8s", "") -BUILTIN(__builtin_ia32_vphadddq, "V2LLiV4i", "") -BUILTIN(__builtin_ia32_vphaddubw, "V8sV16c", "") -BUILTIN(__builtin_ia32_vphaddubd, "V4iV16c", "") -BUILTIN(__builtin_ia32_vphaddubq, "V2LLiV16c", "") -BUILTIN(__builtin_ia32_vphadduwd, "V4iV8s", "") -BUILTIN(__builtin_ia32_vphadduwq, "V2LLiV8s", "") -BUILTIN(__builtin_ia32_vphaddudq, "V2LLiV4i", "") -BUILTIN(__builtin_ia32_vphsubbw, "V8sV16c", "") -BUILTIN(__builtin_ia32_vphsubwd, "V4iV8s", "") -BUILTIN(__builtin_ia32_vphsubdq, "V2LLiV4i", "") -BUILTIN(__builtin_ia32_vpcmov, "V2LLiV2LLiV2LLiV2LLi", "") -BUILTIN(__builtin_ia32_vpcmov_256, "V4LLiV4LLiV4LLiV4LLi", "") -BUILTIN(__builtin_ia32_vpperm, "V16cV16cV16cV16c", "") -BUILTIN(__builtin_ia32_vprotb, "V16cV16cV16c", "") -BUILTIN(__builtin_ia32_vprotw, "V8sV8sV8s", "") -BUILTIN(__builtin_ia32_vprotd, "V4iV4iV4i", "") -BUILTIN(__builtin_ia32_vprotq, "V2LLiV2LLiV2LLi", "") -BUILTIN(__builtin_ia32_vprotbi, "V16cV16cIc", "") -BUILTIN(__builtin_ia32_vprotwi, "V8sV8sIc", "") -BUILTIN(__builtin_ia32_vprotdi, "V4iV4iIc", "") -BUILTIN(__builtin_ia32_vprotqi, "V2LLiV2LLiIc", "") -BUILTIN(__builtin_ia32_vpshlb, "V16cV16cV16c", "") -BUILTIN(__builtin_ia32_vpshlw, "V8sV8sV8s", "") -BUILTIN(__builtin_ia32_vpshld, "V4iV4iV4i", "") -BUILTIN(__builtin_ia32_vpshlq, "V2LLiV2LLiV2LLi", "") -BUILTIN(__builtin_ia32_vpshab, "V16cV16cV16c", "") -BUILTIN(__builtin_ia32_vpshaw, "V8sV8sV8s", "") -BUILTIN(__builtin_ia32_vpshad, "V4iV4iV4i", "") -BUILTIN(__builtin_ia32_vpshaq, "V2LLiV2LLiV2LLi", "") -BUILTIN(__builtin_ia32_vpcomub, "V16cV16cV16cIc", "") -BUILTIN(__builtin_ia32_vpcomuw, "V8sV8sV8sIc", "") -BUILTIN(__builtin_ia32_vpcomud, "V4iV4iV4iIc", "") -BUILTIN(__builtin_ia32_vpcomuq, "V2LLiV2LLiV2LLiIc", "") -BUILTIN(__builtin_ia32_vpcomb, "V16cV16cV16cIc", "") -BUILTIN(__builtin_ia32_vpcomw, "V8sV8sV8sIc", "") -BUILTIN(__builtin_ia32_vpcomd, "V4iV4iV4iIc", "") -BUILTIN(__builtin_ia32_vpcomq, "V2LLiV2LLiV2LLiIc", "") -BUILTIN(__builtin_ia32_vpermil2pd, "V2dV2dV2dV2LLiIc", "") -BUILTIN(__builtin_ia32_vpermil2pd256, "V4dV4dV4dV4LLiIc", "") -BUILTIN(__builtin_ia32_vpermil2ps, "V4fV4fV4fV4iIc", "") -BUILTIN(__builtin_ia32_vpermil2ps256, "V8fV8fV8fV8iIc", "") -BUILTIN(__builtin_ia32_vfrczss, "V4fV4f", "") -BUILTIN(__builtin_ia32_vfrczsd, "V2dV2d", "") -BUILTIN(__builtin_ia32_vfrczps, "V4fV4f", "") -BUILTIN(__builtin_ia32_vfrczpd, "V2dV2d", "") -BUILTIN(__builtin_ia32_vfrczps256, "V8fV8f", "") -BUILTIN(__builtin_ia32_vfrczpd256, "V4dV4d", "") -BUILTIN(__builtin_ia32_xbegin, "i", "") -BUILTIN(__builtin_ia32_xend, "v", "") -BUILTIN(__builtin_ia32_xabort, "vIc", "") -BUILTIN(__builtin_ia32_xtest, "i", "") +TARGET_BUILTIN(__builtin_ia32_vpmacssww, "V8sV8sV8sV8s", "", "xop") +TARGET_BUILTIN(__builtin_ia32_vpmacsww, "V8sV8sV8sV8s", "", "xop") +TARGET_BUILTIN(__builtin_ia32_vpmacsswd, "V4iV8sV8sV4i", "", "xop") +TARGET_BUILTIN(__builtin_ia32_vpmacswd, "V4iV8sV8sV4i", "", "xop") +TARGET_BUILTIN(__builtin_ia32_vpmacssdd, "V4iV4iV4iV4i", "", "xop") +TARGET_BUILTIN(__builtin_ia32_vpmacsdd, "V4iV4iV4iV4i", "", "xop") +TARGET_BUILTIN(__builtin_ia32_vpmacssdql, "V2LLiV4iV4iV2LLi", "", "xop") +TARGET_BUILTIN(__builtin_ia32_vpmacsdql, "V2LLiV4iV4iV2LLi", "", "xop") +TARGET_BUILTIN(__builtin_ia32_vpmacssdqh, "V2LLiV4iV4iV2LLi", "", "xop") +TARGET_BUILTIN(__builtin_ia32_vpmacsdqh, "V2LLiV4iV4iV2LLi", "", "xop") +TARGET_BUILTIN(__builtin_ia32_vpmadcsswd, "V4iV8sV8sV4i", "", "xop") +TARGET_BUILTIN(__builtin_ia32_vpmadcswd, "V4iV8sV8sV4i", "", "xop") + +TARGET_BUILTIN(__builtin_ia32_vphaddbw, "V8sV16c", "", "xop") +TARGET_BUILTIN(__builtin_ia32_vphaddbd, "V4iV16c", "", "xop") +TARGET_BUILTIN(__builtin_ia32_vphaddbq, "V2LLiV16c", "", "xop") +TARGET_BUILTIN(__builtin_ia32_vphaddwd, "V4iV8s", "", "xop") +TARGET_BUILTIN(__builtin_ia32_vphaddwq, "V2LLiV8s", "", "xop") +TARGET_BUILTIN(__builtin_ia32_vphadddq, "V2LLiV4i", "", "xop") +TARGET_BUILTIN(__builtin_ia32_vphaddubw, "V8sV16c", "", "xop") +TARGET_BUILTIN(__builtin_ia32_vphaddubd, "V4iV16c", "", "xop") +TARGET_BUILTIN(__builtin_ia32_vphaddubq, "V2LLiV16c", "", "xop") +TARGET_BUILTIN(__builtin_ia32_vphadduwd, "V4iV8s", "", "xop") +TARGET_BUILTIN(__builtin_ia32_vphadduwq, "V2LLiV8s", "", "xop") +TARGET_BUILTIN(__builtin_ia32_vphaddudq, "V2LLiV4i", "", "xop") +TARGET_BUILTIN(__builtin_ia32_vphsubbw, "V8sV16c", "", "xop") +TARGET_BUILTIN(__builtin_ia32_vphsubwd, "V4iV8s", "", "xop") +TARGET_BUILTIN(__builtin_ia32_vphsubdq, "V2LLiV4i", "", "xop") +TARGET_BUILTIN(__builtin_ia32_vpcmov, "V2LLiV2LLiV2LLiV2LLi", "", "xop") +TARGET_BUILTIN(__builtin_ia32_vpcmov_256, "V4LLiV4LLiV4LLiV4LLi", "", "xop") +TARGET_BUILTIN(__builtin_ia32_vpperm, "V16cV16cV16cV16c", "", "xop") +TARGET_BUILTIN(__builtin_ia32_vprotb, "V16cV16cV16c", "", "xop") +TARGET_BUILTIN(__builtin_ia32_vprotw, "V8sV8sV8s", "", "xop") +TARGET_BUILTIN(__builtin_ia32_vprotd, "V4iV4iV4i", "", "xop") +TARGET_BUILTIN(__builtin_ia32_vprotq, "V2LLiV2LLiV2LLi", "", "xop") +TARGET_BUILTIN(__builtin_ia32_vprotbi, "V16cV16cIc", "", "xop") +TARGET_BUILTIN(__builtin_ia32_vprotwi, "V8sV8sIc", "", "xop") +TARGET_BUILTIN(__builtin_ia32_vprotdi, "V4iV4iIc", "", "xop") +TARGET_BUILTIN(__builtin_ia32_vprotqi, "V2LLiV2LLiIc", "", "xop") +TARGET_BUILTIN(__builtin_ia32_vpshlb, "V16cV16cV16c", "", "xop") +TARGET_BUILTIN(__builtin_ia32_vpshlw, "V8sV8sV8s", "", "xop") +TARGET_BUILTIN(__builtin_ia32_vpshld, "V4iV4iV4i", "", "xop") +TARGET_BUILTIN(__builtin_ia32_vpshlq, "V2LLiV2LLiV2LLi", "", "xop") +TARGET_BUILTIN(__builtin_ia32_vpshab, "V16cV16cV16c", "", "xop") +TARGET_BUILTIN(__builtin_ia32_vpshaw, "V8sV8sV8s", "", "xop") +TARGET_BUILTIN(__builtin_ia32_vpshad, "V4iV4iV4i", "", "xop") +TARGET_BUILTIN(__builtin_ia32_vpshaq, "V2LLiV2LLiV2LLi", "", "xop") +TARGET_BUILTIN(__builtin_ia32_vpcomub, "V16cV16cV16cIc", "", "xop") +TARGET_BUILTIN(__builtin_ia32_vpcomuw, "V8sV8sV8sIc", "", "xop") +TARGET_BUILTIN(__builtin_ia32_vpcomud, "V4iV4iV4iIc", "", "xop") +TARGET_BUILTIN(__builtin_ia32_vpcomuq, "V2LLiV2LLiV2LLiIc", "", "xop") +TARGET_BUILTIN(__builtin_ia32_vpcomb, "V16cV16cV16cIc", "", "xop") +TARGET_BUILTIN(__builtin_ia32_vpcomw, "V8sV8sV8sIc", "", "xop") +TARGET_BUILTIN(__builtin_ia32_vpcomd, "V4iV4iV4iIc", "", "xop") +TARGET_BUILTIN(__builtin_ia32_vpcomq, "V2LLiV2LLiV2LLiIc", "", "xop") +TARGET_BUILTIN(__builtin_ia32_vpermil2pd, "V2dV2dV2dV2LLiIc", "", "xop") +TARGET_BUILTIN(__builtin_ia32_vpermil2pd256, "V4dV4dV4dV4LLiIc", "", "xop") +TARGET_BUILTIN(__builtin_ia32_vpermil2ps, "V4fV4fV4fV4iIc", "", "xop") +TARGET_BUILTIN(__builtin_ia32_vpermil2ps256, "V8fV8fV8fV8iIc", "", "xop") +TARGET_BUILTIN(__builtin_ia32_vfrczss, "V4fV4f", "", "xop") +TARGET_BUILTIN(__builtin_ia32_vfrczsd, "V2dV2d", "", "xop") +TARGET_BUILTIN(__builtin_ia32_vfrczps, "V4fV4f", "", "xop") +TARGET_BUILTIN(__builtin_ia32_vfrczpd, "V2dV2d", "", "xop") +TARGET_BUILTIN(__builtin_ia32_vfrczps256, "V8fV8f", "", "xop") +TARGET_BUILTIN(__builtin_ia32_vfrczpd256, "V4dV4d", "", "xop") + +TARGET_BUILTIN(__builtin_ia32_xbegin, "i", "", "rtm") +TARGET_BUILTIN(__builtin_ia32_xend, "v", "", "rtm") +TARGET_BUILTIN(__builtin_ia32_xabort, "vIc", "", "rtm") +TARGET_BUILTIN(__builtin_ia32_xtest, "i", "", "rtm") + BUILTIN(__builtin_ia32_rdpmc, "ULLii", "") BUILTIN(__builtin_ia32_rdtsc, "ULLi", "") BUILTIN(__builtin_ia32_rdtscp, "ULLiUi*", "") // AVX-512 -BUILTIN(__builtin_ia32_sqrtpd512_mask, "V8dV8dV8dUcIi", "") -BUILTIN(__builtin_ia32_sqrtps512_mask, "V16fV16fV16fUsIi", "") -BUILTIN(__builtin_ia32_rsqrt14sd_mask, "V2dV2dV2dV2dUc", "") -BUILTIN(__builtin_ia32_rsqrt14ss_mask, "V4fV4fV4fV4fUc", "") -BUILTIN(__builtin_ia32_rsqrt14pd512_mask, "V8dV8dV8dUc", "") -BUILTIN(__builtin_ia32_rsqrt14ps512_mask, "V16fV16fV16fUs", "") -BUILTIN(__builtin_ia32_rsqrt28sd_mask, "V2dV2dV2dV2dUcIi", "") -BUILTIN(__builtin_ia32_rsqrt28ss_mask, "V4fV4fV4fV4fUcIi", "") -BUILTIN(__builtin_ia32_rsqrt28pd_mask, "V8dV8dV8dUcIi", "") -BUILTIN(__builtin_ia32_rsqrt28ps_mask, "V16fV16fV16fUsIi", "") -BUILTIN(__builtin_ia32_rcp14sd_mask, "V2dV2dV2dV2dUc", "") -BUILTIN(__builtin_ia32_rcp14ss_mask, "V4fV4fV4fV4fUc", "") -BUILTIN(__builtin_ia32_rcp14pd512_mask, "V8dV8dV8dUc", "") -BUILTIN(__builtin_ia32_rcp14ps512_mask, "V16fV16fV16fUs", "") -BUILTIN(__builtin_ia32_rcp28sd_mask, "V2dV2dV2dV2dUcIi", "") -BUILTIN(__builtin_ia32_rcp28ss_mask, "V4fV4fV4fV4fUcIi", "") -BUILTIN(__builtin_ia32_rcp28pd_mask, "V8dV8dV8dUcIi", "") -BUILTIN(__builtin_ia32_rcp28ps_mask, "V16fV16fV16fUsIi", "") -BUILTIN(__builtin_ia32_exp2pd_mask, "V8dV8dV8dUcIi", "") -BUILTIN(__builtin_ia32_exp2ps_mask, "V16fV16fV16fUsIi", "") -BUILTIN(__builtin_ia32_cvttps2dq512_mask, "V16iV16fV16iUsIi", "") -BUILTIN(__builtin_ia32_cvttps2udq512_mask, "V16iV16fV16iUsIi", "") -BUILTIN(__builtin_ia32_cvttpd2dq512_mask, "V8iV8dV8iUcIi", "") -BUILTIN(__builtin_ia32_cvttpd2udq512_mask, "V8iV8dV8iUcIi", "") -BUILTIN(__builtin_ia32_cmpps512_mask, "UsV16fV16fIiUsIi", "") -BUILTIN(__builtin_ia32_cmpps256_mask, "UcV8fV8fIiUc", "") -BUILTIN(__builtin_ia32_cmpps128_mask, "UcV4fV4fIiUc", "") -BUILTIN(__builtin_ia32_pcmpeqb512_mask, "LLiV64cV64cLLi", "") -BUILTIN(__builtin_ia32_pcmpeqd512_mask, "sV16iV16is", "") -BUILTIN(__builtin_ia32_pcmpeqq512_mask, "cV8LLiV8LLic", "") -BUILTIN(__builtin_ia32_pcmpeqw512_mask, "iV32sV32si", "") -BUILTIN(__builtin_ia32_pcmpeqb256_mask, "iV32cV32ci", "") -BUILTIN(__builtin_ia32_pcmpeqd256_mask, "cV8iV8ic", "") -BUILTIN(__builtin_ia32_pcmpeqq256_mask, "cV4LLiV4LLic", "") -BUILTIN(__builtin_ia32_pcmpeqw256_mask, "sV16sV16ss", "") -BUILTIN(__builtin_ia32_pcmpeqb128_mask, "sV16cV16cs", "") -BUILTIN(__builtin_ia32_pcmpeqd128_mask, "cV4iV4ic", "") -BUILTIN(__builtin_ia32_pcmpeqq128_mask, "cV2LLiV2LLic", "") -BUILTIN(__builtin_ia32_pcmpeqw128_mask, "cV8sV8sc", "") -BUILTIN(__builtin_ia32_pcmpgtb512_mask, "LLiV64cV64cLLi", "") -BUILTIN(__builtin_ia32_pcmpgtd512_mask, "sV16iV16is", "") -BUILTIN(__builtin_ia32_pcmpgtq512_mask, "cV8LLiV8LLic", "") -BUILTIN(__builtin_ia32_pcmpgtw512_mask, "iV32sV32si", "") -BUILTIN(__builtin_ia32_pcmpgtb256_mask, "iV32cV32ci", "") -BUILTIN(__builtin_ia32_pcmpgtd256_mask, "cV8iV8ic", "") -BUILTIN(__builtin_ia32_pcmpgtq256_mask, "cV4LLiV4LLic", "") -BUILTIN(__builtin_ia32_pcmpgtw256_mask, "sV16sV16ss", "") -BUILTIN(__builtin_ia32_pcmpgtb128_mask, "sV16cV16cs", "") -BUILTIN(__builtin_ia32_pcmpgtd128_mask, "cV4iV4ic", "") -BUILTIN(__builtin_ia32_pcmpgtq128_mask, "cV2LLiV2LLic", "") -BUILTIN(__builtin_ia32_pcmpgtw128_mask, "cV8sV8sc", "") -BUILTIN(__builtin_ia32_cmppd512_mask, "UcV8dV8dIiUcIi", "") -BUILTIN(__builtin_ia32_cmppd256_mask, "UcV4dV4dIiUc", "") -BUILTIN(__builtin_ia32_cmppd128_mask, "UcV2dV2dIiUc", "") -BUILTIN(__builtin_ia32_rndscaleps_mask, "V16fV16fIiV16fUsIi", "") -BUILTIN(__builtin_ia32_rndscalepd_mask, "V8dV8dIiV8dUcIi", "") -BUILTIN(__builtin_ia32_cvtps2dq512_mask, "V16iV16fV16iUsIi", "") -BUILTIN(__builtin_ia32_cvtpd2dq512_mask, "V8iV8dV8iUcIi", "") -BUILTIN(__builtin_ia32_cvtps2udq512_mask, "V16iV16fV16iUsIi", "") -BUILTIN(__builtin_ia32_cvtpd2udq512_mask, "V8iV8dV8iUcIi", "") -BUILTIN(__builtin_ia32_minps512_mask, "V16fV16fV16fV16fUsIi", "") -BUILTIN(__builtin_ia32_minpd512_mask, "V8dV8dV8dV8dUcIi", "") -BUILTIN(__builtin_ia32_maxps512_mask, "V16fV16fV16fV16fUsIi", "") -BUILTIN(__builtin_ia32_maxpd512_mask, "V8dV8dV8dV8dUcIi", "") -BUILTIN(__builtin_ia32_cvtdq2ps512_mask, "V16fV16iV16fUsIi", "") -BUILTIN(__builtin_ia32_cvtudq2ps512_mask, "V16fV16iV16fUsIi", "") -BUILTIN(__builtin_ia32_cvtdq2pd512_mask, "V8dV8iV8dUc", "") -BUILTIN(__builtin_ia32_cvtudq2pd512_mask, "V8dV8iV8dUc", "") -BUILTIN(__builtin_ia32_cvtpd2ps512_mask, "V8fV8dV8fUcIi", "") -BUILTIN(__builtin_ia32_vcvtps2ph512_mask, "V16sV16fIiV16sUs", "") -BUILTIN(__builtin_ia32_vcvtph2ps512_mask, "V16fV16sV16fUsIi", "") -BUILTIN(__builtin_ia32_pandd512_mask, "V16iV16iV16iV16iUs", "") -BUILTIN(__builtin_ia32_pandq512_mask, "V8LLiV8LLiV8LLiV8LLiUc", "") -BUILTIN(__builtin_ia32_pord512_mask, "V16iV16iV16iV16iUs", "") -BUILTIN(__builtin_ia32_porq512_mask, "V8LLiV8LLiV8LLiV8LLiUc", "") -BUILTIN(__builtin_ia32_pxord512_mask, "V16iV16iV16iV16iUs", "") -BUILTIN(__builtin_ia32_pxorq512_mask, "V8LLiV8LLiV8LLiV8LLiUc", "") -BUILTIN(__builtin_ia32_pabsd512_mask, "V16iV16iV16iUs", "") -BUILTIN(__builtin_ia32_pabsq512_mask, "V8LLiV8LLiV8LLiUc", "") -BUILTIN(__builtin_ia32_pmaxsd512_mask, "V16iV16iV16iV16iUs", "") -BUILTIN(__builtin_ia32_pmaxsq512_mask, "V8LLiV8LLiV8LLiV8LLiUc", "") -BUILTIN(__builtin_ia32_pmaxud512_mask, "V16iV16iV16iV16iUs", "") -BUILTIN(__builtin_ia32_pmaxuq512_mask, "V8LLiV8LLiV8LLiV8LLiUc", "") -BUILTIN(__builtin_ia32_pminsd512_mask, "V16iV16iV16iV16iUs", "") -BUILTIN(__builtin_ia32_pminsq512_mask, "V8LLiV8LLiV8LLiV8LLiUc", "") -BUILTIN(__builtin_ia32_pminud512_mask, "V16iV16iV16iV16iUs", "") -BUILTIN(__builtin_ia32_pminuq512_mask, "V8LLiV8LLiV8LLiV8LLiUc", "") -BUILTIN(__builtin_ia32_pmuldq512_mask, "V8LLiV16iV16iV8LLiUc", "") -BUILTIN(__builtin_ia32_pmuludq512_mask, "V8LLiV16iV16iV8LLiUc", "") -BUILTIN(__builtin_ia32_blendmd_512_mask, "V16iV16iV16iUs", "") -BUILTIN(__builtin_ia32_blendmq_512_mask, "V8LLiV8LLiV8LLiUc", "") -BUILTIN(__builtin_ia32_blendmps_512_mask, "V16fV16fV16fUs", "") -BUILTIN(__builtin_ia32_blendmpd_512_mask, "V8dV8dV8dUc", "") -BUILTIN(__builtin_ia32_ptestmd512, "UsV16iV16iUs", "") -BUILTIN(__builtin_ia32_ptestmq512, "UcV8LLiV8LLiUc", "") -BUILTIN(__builtin_ia32_pbroadcastd512_gpr_mask, "V16iiV16iUs", "") -BUILTIN(__builtin_ia32_pbroadcastq512_gpr_mask, "V8LLiLLiV8LLiUc", "") -BUILTIN(__builtin_ia32_pbroadcastq512_mem_mask, "V8LLiLLiV8LLiUc", "") -BUILTIN(__builtin_ia32_loaddqusi512_mask, "V16ivC*V16iUs", "") -BUILTIN(__builtin_ia32_loaddqudi512_mask, "V8LLivC*V8LLiUc", "") -BUILTIN(__builtin_ia32_loadups512_mask, "V16fvC*V16fUs", "") -BUILTIN(__builtin_ia32_loadaps512_mask, "V16fvC*V16fUs", "") -BUILTIN(__builtin_ia32_loadupd512_mask, "V8dvC*V8dUc", "") -BUILTIN(__builtin_ia32_loadapd512_mask, "V8dvC*V8dUc", "") -BUILTIN(__builtin_ia32_storedqudi512_mask, "vv*V8LLiUc", "") -BUILTIN(__builtin_ia32_storedqusi512_mask, "vv*V16iUs", "") -BUILTIN(__builtin_ia32_storeupd512_mask, "vv*V8dUc", "") -BUILTIN(__builtin_ia32_storeapd512_mask, "vv*V8dUc", "") -BUILTIN(__builtin_ia32_storeups512_mask, "vv*V16fUs", "") -BUILTIN(__builtin_ia32_storeaps512_mask, "vv*V16fUs", "") -BUILTIN(__builtin_ia32_vpermt2vard512_mask, "V16iV16iV16iV16iUs", "") -BUILTIN(__builtin_ia32_vpermt2varq512_mask, "V8LLiV8LLiV8LLiV8LLiUc", "") -BUILTIN(__builtin_ia32_vpermt2varps512_mask, "V16fV16iV16fV16fUs", "") -BUILTIN(__builtin_ia32_vpermt2varpd512_mask, "V8dV8LLiV8dV8dUc", "") -BUILTIN(__builtin_ia32_alignq512_mask, "V8LLiV8LLiV8LLiIcV8LLiUc", "") -BUILTIN(__builtin_ia32_alignd512_mask, "V16iV16iV16iIcV16iUs", "") -BUILTIN(__builtin_ia32_extractf64x4_mask, "V4dV8dIcV4dUc", "") -BUILTIN(__builtin_ia32_extractf32x4_mask, "V4fV16fIcV4fUc", "") -BUILTIN(__builtin_ia32_gathersiv8df, "V8dV8dvC*V8iUcIi", "") -BUILTIN(__builtin_ia32_gathersiv16sf, "V16fV16fvC*UsIi", "") -BUILTIN(__builtin_ia32_gatherdiv8df, "V8dV8dvC*V8LLiUcIi", "") -BUILTIN(__builtin_ia32_gatherdiv16sf, "V8fV8fvC*V8LLiUcIi", "") -BUILTIN(__builtin_ia32_gathersiv8di, "V8LLiV8LLivC*V8iUcIi", "") -BUILTIN(__builtin_ia32_gathersiv16si, "V16iV16ivC*UsIi", "") -BUILTIN(__builtin_ia32_gatherdiv8di, "V8LLiV8LLivC*V8LLiUcIi", "") -BUILTIN(__builtin_ia32_gatherdiv16si, "V8iV8ivC*V8LLiUcIi", "") -BUILTIN(__builtin_ia32_scattersiv8df, "vv*UcV8iV8dIi", "") -BUILTIN(__builtin_ia32_scattersiv16sf, "vv*UsV16iV16fIi", "") -BUILTIN(__builtin_ia32_scatterdiv8df, "vv*UcV8LLiV8dIi", "") -BUILTIN(__builtin_ia32_scatterdiv16sf, "vv*UcV8LLiV8fIi", "") -BUILTIN(__builtin_ia32_scattersiv8di, "vv*UcV8iV8LLiIi", "") -BUILTIN(__builtin_ia32_scattersiv16si, "vv*UsV16iV16iIi", "") -BUILTIN(__builtin_ia32_scatterdiv8di, "vv*UcV8LLiV8LLiIi", "") -BUILTIN(__builtin_ia32_scatterdiv16si, "vv*UcV8LLiV8iIi", "") -BUILTIN(__builtin_ia32_gatherpfdpd, "vUcV8ivC*IiIi", "") -BUILTIN(__builtin_ia32_gatherpfdps, "vUsV16ivC*IiIi", "") -BUILTIN(__builtin_ia32_gatherpfqpd, "vUcV8LLivC*IiIi", "") -BUILTIN(__builtin_ia32_gatherpfqps, "vUcV8LLivC*IiIi", "") -BUILTIN(__builtin_ia32_scatterpfdpd, "vUcV8iv*IiIi", "") -BUILTIN(__builtin_ia32_scatterpfdps, "vUsV16iv*IiIi", "") -BUILTIN(__builtin_ia32_scatterpfqpd, "vUcV8LLiv*IiIi", "") -BUILTIN(__builtin_ia32_scatterpfqps, "vUcV8LLiv*IiIi", "") -BUILTIN(__builtin_ia32_knothi, "UsUs", "") - -BUILTIN(__builtin_ia32_cmpb128_mask, "UsV16cV16cIiUs", "") -BUILTIN(__builtin_ia32_cmpd128_mask, "UcV4iV4iIiUc", "") -BUILTIN(__builtin_ia32_cmpq128_mask, "UcV2LLiV2LLiIiUc", "") -BUILTIN(__builtin_ia32_cmpw128_mask, "UcV8sV8sIiUc", "") -BUILTIN(__builtin_ia32_cmpb256_mask, "UiV32cV32cIiUi", "") -BUILTIN(__builtin_ia32_cmpd256_mask, "UcV8iV8iIiUc", "") -BUILTIN(__builtin_ia32_cmpq256_mask, "UcV4LLiV4LLiIiUc", "") -BUILTIN(__builtin_ia32_cmpw256_mask, "UsV16sV16sIiUs", "") -BUILTIN(__builtin_ia32_cmpb512_mask, "ULLiV64cV64cIiULLi", "") -BUILTIN(__builtin_ia32_cmpd512_mask, "UsV16iV16iIiUs", "") -BUILTIN(__builtin_ia32_cmpq512_mask, "UcV8LLiV8LLiIiUc", "") -BUILTIN(__builtin_ia32_cmpw512_mask, "UiV32sV32sIiUi", "") -BUILTIN(__builtin_ia32_ucmpb128_mask, "UsV16cV16cIiUs", "") -BUILTIN(__builtin_ia32_ucmpd128_mask, "UcV4iV4iIiUc", "") -BUILTIN(__builtin_ia32_ucmpq128_mask, "UcV2LLiV2LLiIiUc", "") -BUILTIN(__builtin_ia32_ucmpw128_mask, "UcV8sV8sIiUc", "") -BUILTIN(__builtin_ia32_ucmpb256_mask, "UiV32cV32cIiUi", "") -BUILTIN(__builtin_ia32_ucmpd256_mask, "UcV8iV8iIiUc", "") -BUILTIN(__builtin_ia32_ucmpq256_mask, "UcV4LLiV4LLiIiUc", "") -BUILTIN(__builtin_ia32_ucmpw256_mask, "UsV16sV16sIiUs", "") -BUILTIN(__builtin_ia32_ucmpb512_mask, "ULLiV64cV64cIiULLi", "") -BUILTIN(__builtin_ia32_ucmpd512_mask, "UsV16iV16iIiUs", "") -BUILTIN(__builtin_ia32_ucmpq512_mask, "UcV8LLiV8LLiIiUc", "") -BUILTIN(__builtin_ia32_ucmpw512_mask, "UiV32sV32sIiUi", "") - -BUILTIN(__builtin_ia32_paddd256_mask, "V8iV8iV8iV8iUc", "") -BUILTIN(__builtin_ia32_paddq256_mask, "V4LLiV4LLiV4LLiV4LLiUc", "") -BUILTIN(__builtin_ia32_psubd256_mask, "V8iV8iV8iV8iUc", "") -BUILTIN(__builtin_ia32_psubq256_mask, "V4LLiV4LLiV4LLiV4LLiUc", "") -BUILTIN(__builtin_ia32_paddd128_mask, "V4iV4iV4iV4iUc", "") -BUILTIN(__builtin_ia32_paddq128_mask, "V2LLiV2LLiV2LLiV2LLiUc", "") -BUILTIN(__builtin_ia32_psubd128_mask, "V4iV4iV4iV4iUc", "") -BUILTIN(__builtin_ia32_psubq128_mask, "V2LLiV2LLiV2LLiV2LLiUc", "") -BUILTIN(__builtin_ia32_pmuldq256_mask, "V4LLiV8iV8iV4LLiUc", "") -BUILTIN(__builtin_ia32_pmuldq128_mask, "V2LLiV4iV4iV2LLiUc", "") -BUILTIN(__builtin_ia32_pmuludq256_mask, "V4LLiV8iV8iV4LLiUc", "") -BUILTIN(__builtin_ia32_pmuludq128_mask, "V2LLiV4iV4iV2LLiUc", "") -BUILTIN(__builtin_ia32_pmulld256_mask, "V8iV8iV8iV8iUc", "") -BUILTIN(__builtin_ia32_pmulld128_mask, "V4iV4iV4iV4iUc", "") -BUILTIN(__builtin_ia32_pandd256_mask, "V8iV8iV8iV8iUc", "") -BUILTIN(__builtin_ia32_pandd128_mask, "V4iV4iV4iV4iUc", "") -BUILTIN(__builtin_ia32_pandnd256_mask, "V8iV8iV8iV8iUc", "") -BUILTIN(__builtin_ia32_pandnd128_mask, "V4iV4iV4iV4iUc", "") -BUILTIN(__builtin_ia32_pord256_mask, "V8iV8iV8iV8iUc", "") -BUILTIN(__builtin_ia32_pord128_mask, "V4iV4iV4iV4iUc", "") -BUILTIN(__builtin_ia32_pxord256_mask, "V8iV8iV8iV8iUc", "") -BUILTIN(__builtin_ia32_pxord128_mask, "V4iV4iV4iV4iUc", "") -BUILTIN(__builtin_ia32_pandq256_mask, "V4LLiV4LLiV4LLiV4LLiUc", "") -BUILTIN(__builtin_ia32_pandq128_mask, "V2LLiV2LLiV2LLiV2LLiUc", "") -BUILTIN(__builtin_ia32_pandnq256_mask, "V4LLiV4LLiV4LLiV4LLiUc", "") -BUILTIN(__builtin_ia32_pandnq128_mask, "V2LLiV2LLiV2LLiV2LLiUc", "") -BUILTIN(__builtin_ia32_porq256_mask, "V4LLiV4LLiV4LLiV4LLiUc", "") -BUILTIN(__builtin_ia32_porq128_mask, "V2LLiV2LLiV2LLiV2LLiUc", "") -BUILTIN(__builtin_ia32_pxorq256_mask, "V4LLiV4LLiV4LLiV4LLiUc", "") -BUILTIN(__builtin_ia32_pxorq128_mask, "V2LLiV2LLiV2LLiV2LLiUc", "") -BUILTIN(__builtin_ia32_paddb512_mask, "V64cV64cV64cV64cULLi", "") -BUILTIN(__builtin_ia32_psubb512_mask, "V64cV64cV64cV64cULLi", "") -BUILTIN(__builtin_ia32_paddw512_mask, "V32sV32sV32sV32sUi", "") -BUILTIN(__builtin_ia32_psubw512_mask, "V32sV32sV32sV32sUi", "") -BUILTIN(__builtin_ia32_pmullw512_mask, "V32sV32sV32sV32sUi", "") -BUILTIN(__builtin_ia32_paddb256_mask, "V32cV32cV32cV32cUi", "") -BUILTIN(__builtin_ia32_paddw256_mask, "V16sV16sV16sV16sUs", "") -BUILTIN(__builtin_ia32_psubb256_mask, "V32cV32cV32cV32cUi", "") -BUILTIN(__builtin_ia32_psubw256_mask, "V16sV16sV16sV16sUs", "") -BUILTIN(__builtin_ia32_paddb128_mask, "V16cV16cV16cV16cUs", "") -BUILTIN(__builtin_ia32_paddw128_mask, "V8sV8sV8sV8sUc", "") -BUILTIN(__builtin_ia32_psubb128_mask, "V16cV16cV16cV16cUs", "") -BUILTIN(__builtin_ia32_psubw128_mask, "V8sV8sV8sV8sUc", "") -BUILTIN(__builtin_ia32_pmullw256_mask, "V16sV16sV16sV16sUs", "") -BUILTIN(__builtin_ia32_pmullw128_mask, "V8sV8sV8sV8sUc", "") -BUILTIN(__builtin_ia32_pandnd512_mask, "V16iV16iV16iV16iUs", "") -BUILTIN(__builtin_ia32_pandnq512_mask, "V8LLiV8LLiV8LLiV8LLiUc", "") -BUILTIN(__builtin_ia32_paddq512_mask, "V8LLiV8LLiV8LLiV8LLiUc", "") -BUILTIN(__builtin_ia32_psubq512_mask, "V8LLiV8LLiV8LLiV8LLiUc", "") -BUILTIN(__builtin_ia32_paddd512_mask, "V16iV16iV16iV16iUs", "") -BUILTIN(__builtin_ia32_psubd512_mask, "V16iV16iV16iV16iUs", "") -BUILTIN(__builtin_ia32_pmulld512_mask, "V16iV16iV16iV16iUs", "") -BUILTIN(__builtin_ia32_pmullq512_mask, "V8LLiV8LLiV8LLiV8LLiUc", "") -BUILTIN(__builtin_ia32_xorpd512_mask, "V8dV8dV8dV8dUc", "") -BUILTIN(__builtin_ia32_xorps512_mask, "V16fV16fV16fV16fUs", "") -BUILTIN(__builtin_ia32_orpd512_mask, "V8dV8dV8dV8dUc", "") -BUILTIN(__builtin_ia32_orps512_mask, "V16fV16fV16fV16fUs", "") -BUILTIN(__builtin_ia32_andpd512_mask, "V8dV8dV8dV8dUc", "") -BUILTIN(__builtin_ia32_andps512_mask, "V16fV16fV16fV16fUs", "") -BUILTIN(__builtin_ia32_andnpd512_mask, "V8dV8dV8dV8dUc", "") -BUILTIN(__builtin_ia32_andnps512_mask, "V16fV16fV16fV16fUs", "") -BUILTIN(__builtin_ia32_pmullq256_mask, "V4LLiV4LLiV4LLiV4LLiUc", "") -BUILTIN(__builtin_ia32_pmullq128_mask, "V2LLiV2LLiV2LLiV2LLiUc", "") -BUILTIN(__builtin_ia32_andnpd256_mask, "V4dV4dV4dV4dUc", "") -BUILTIN(__builtin_ia32_andnpd128_mask, "V2dV2dV2dV2dUc", "") -BUILTIN(__builtin_ia32_andnps256_mask, "V8fV8fV8fV8fUc", "") -BUILTIN(__builtin_ia32_andnps128_mask, "V4fV4fV4fV4fUc", "") -BUILTIN(__builtin_ia32_andpd256_mask, "V4dV4dV4dV4dUc", "") -BUILTIN(__builtin_ia32_andpd128_mask, "V2dV2dV2dV2dUc", "") -BUILTIN(__builtin_ia32_andps256_mask, "V8fV8fV8fV8fUc", "") -BUILTIN(__builtin_ia32_andps128_mask, "V4fV4fV4fV4fUc", "") -BUILTIN(__builtin_ia32_xorpd256_mask, "V4dV4dV4dV4dUc", "") -BUILTIN(__builtin_ia32_xorpd128_mask, "V2dV2dV2dV2dUc", "") -BUILTIN(__builtin_ia32_xorps256_mask, "V8fV8fV8fV8fUc", "") -BUILTIN(__builtin_ia32_xorps128_mask, "V4fV4fV4fV4fUc", "") -BUILTIN(__builtin_ia32_orpd256_mask, "V4dV4dV4dV4dUc", "") -BUILTIN(__builtin_ia32_orpd128_mask, "V2dV2dV2dV2dUc", "") -BUILTIN(__builtin_ia32_orps256_mask, "V8fV8fV8fV8fUc", "") -BUILTIN(__builtin_ia32_orps128_mask, "V4fV4fV4fV4fUc", "") -BUILTIN(__builtin_ia32_blendmb_512_mask, "V64cV64cV64cULLi", "") -BUILTIN(__builtin_ia32_blendmw_512_mask, "V32sV32sV32sUi", "") -BUILTIN(__builtin_ia32_pabsb512_mask, "V64cV64cV64cULLi", "") -BUILTIN(__builtin_ia32_pabsw512_mask, "V32sV32sV32sUi", "") -BUILTIN(__builtin_ia32_packssdw512_mask, "V32sV16iV16iV32sUi", "") -BUILTIN(__builtin_ia32_packsswb512_mask, "V64cV32sV32sV64cULLi", "") -BUILTIN(__builtin_ia32_packusdw512_mask, "V32sV16iV16iV32sUi", "") -BUILTIN(__builtin_ia32_packuswb512_mask, "V64cV32sV32sV64cULLi", "") -BUILTIN(__builtin_ia32_paddsb512_mask, "V64cV64cV64cV64cULLi", "") -BUILTIN(__builtin_ia32_paddsw512_mask, "V32sV32sV32sV32sUi", "") -BUILTIN(__builtin_ia32_paddusb512_mask, "V64cV64cV64cV64cULLi", "") -BUILTIN(__builtin_ia32_paddusw512_mask, "V32sV32sV32sV32sUi", "") -BUILTIN(__builtin_ia32_pavgb512_mask, "V64cV64cV64cV64cULLi", "") -BUILTIN(__builtin_ia32_pavgw512_mask, "V32sV32sV32sV32sUi", "") -BUILTIN(__builtin_ia32_pmaxsb512_mask, "V64cV64cV64cV64cULLi", "") -BUILTIN(__builtin_ia32_pmaxsw512_mask, "V32sV32sV32sV32sUi", "") -BUILTIN(__builtin_ia32_pmaxub512_mask, "V64cV64cV64cV64cULLi", "") -BUILTIN(__builtin_ia32_pmaxuw512_mask, "V32sV32sV32sV32sUi", "") -BUILTIN(__builtin_ia32_pminsb512_mask, "V64cV64cV64cV64cULLi", "") -BUILTIN(__builtin_ia32_pminsw512_mask, "V32sV32sV32sV32sUi", "") -BUILTIN(__builtin_ia32_pminub512_mask, "V64cV64cV64cV64cULLi", "") -BUILTIN(__builtin_ia32_pminuw512_mask, "V32sV32sV32sV32sUi", "") -BUILTIN(__builtin_ia32_pshufb512_mask, "V64cV64cV64cV64cULLi", "") -BUILTIN(__builtin_ia32_psubsb512_mask, "V64cV64cV64cV64cULLi", "") -BUILTIN(__builtin_ia32_psubsw512_mask, "V32sV32sV32sV32sUi", "") -BUILTIN(__builtin_ia32_psubusb512_mask, "V64cV64cV64cV64cULLi", "") -BUILTIN(__builtin_ia32_psubusw512_mask, "V32sV32sV32sV32sUi", "") -BUILTIN(__builtin_ia32_vpermi2varhi512_mask, "V32sV32sV32sV32sUi", "") -BUILTIN(__builtin_ia32_vpermt2varhi512_mask, "V32sV32sV32sV32sUi", "") -BUILTIN(__builtin_ia32_vpermt2varhi512_maskz, "V32sV32sV32sV32sUi", "") -BUILTIN(__builtin_ia32_vpconflictdi_512_mask, "V8LLiV8LLiV8LLiUc", "") -BUILTIN(__builtin_ia32_vpconflictsi_512_mask, "V16iV16iV16iUs", "") -BUILTIN(__builtin_ia32_vplzcntd_512_mask, "V16iV16iV16iUs", "") -BUILTIN(__builtin_ia32_vplzcntq_512_mask, "V8LLiV8LLiV8LLiUc", "") -BUILTIN(__builtin_ia32_blendmb_128_mask, "V16cV16cV16cUs", "") -BUILTIN(__builtin_ia32_blendmb_256_mask, "V32cV32cV32cUi", "") -BUILTIN(__builtin_ia32_blendmw_128_mask, "V8sV8sV8sUc", "") -BUILTIN(__builtin_ia32_blendmw_256_mask, "V16sV16sV16sUs", "") -BUILTIN(__builtin_ia32_pabsb128_mask, "V16cV16cV16cUs", "") -BUILTIN(__builtin_ia32_pabsb256_mask, "V32cV32cV32cUi", "") -BUILTIN(__builtin_ia32_pabsw128_mask, "V8sV8sV8sUc", "") -BUILTIN(__builtin_ia32_pabsw256_mask, "V16sV16sV16sUs", "") -BUILTIN(__builtin_ia32_packssdw128_mask, "V8sV4iV4iV8sUc", "") -BUILTIN(__builtin_ia32_packssdw256_mask, "V16sV8iV8iV16sUs", "") -BUILTIN(__builtin_ia32_packsswb128_mask, "V16cV8sV8sV16cUs", "") -BUILTIN(__builtin_ia32_packsswb256_mask, "V32cV16sV16sV32cUi", "") -BUILTIN(__builtin_ia32_packusdw128_mask, "V8sV4iV4iV8sUc", "") -BUILTIN(__builtin_ia32_packusdw256_mask, "V16sV8iV8iV16sUs", "") -BUILTIN(__builtin_ia32_packuswb128_mask, "V16cV8sV8sV16cUs", "") -BUILTIN(__builtin_ia32_packuswb256_mask, "V32cV16sV16sV32cUi", "") -BUILTIN(__builtin_ia32_paddsb128_mask, "V16cV16cV16cV16cUs", "") -BUILTIN(__builtin_ia32_paddsb256_mask, "V32cV32cV32cV32cUi", "") -BUILTIN(__builtin_ia32_paddsw128_mask, "V8sV8sV8sV8sUc", "") -BUILTIN(__builtin_ia32_paddsw256_mask, "V16sV16sV16sV16sUs", "") -BUILTIN(__builtin_ia32_paddusb128_mask, "V16cV16cV16cV16cUs", "") -BUILTIN(__builtin_ia32_paddusb256_mask, "V32cV32cV32cV32cUi", "") -BUILTIN(__builtin_ia32_paddusw128_mask, "V8sV8sV8sV8sUc", "") -BUILTIN(__builtin_ia32_paddusw256_mask, "V16sV16sV16sV16sUs", "") -BUILTIN(__builtin_ia32_pavgb128_mask, "V16cV16cV16cV16cUs", "") -BUILTIN(__builtin_ia32_pavgb256_mask, "V32cV32cV32cV32cUi", "") -BUILTIN(__builtin_ia32_pavgw128_mask, "V8sV8sV8sV8sUc", "") -BUILTIN(__builtin_ia32_pavgw256_mask, "V16sV16sV16sV16sUs", "") -BUILTIN(__builtin_ia32_pmaxsb128_mask, "V16cV16cV16cV16cUs", "") -BUILTIN(__builtin_ia32_pmaxsb256_mask, "V32cV32cV32cV32cUi", "") -BUILTIN(__builtin_ia32_pmaxsw128_mask, "V8sV8sV8sV8sUc", "") -BUILTIN(__builtin_ia32_pmaxsw256_mask, "V16sV16sV16sV16sUs", "") -BUILTIN(__builtin_ia32_pmaxub128_mask, "V16cV16cV16cV16cUs", "") -BUILTIN(__builtin_ia32_pmaxub256_mask, "V32cV32cV32cV32cUi", "") -BUILTIN(__builtin_ia32_pmaxuw128_mask, "V8sV8sV8sV8sUc", "") -BUILTIN(__builtin_ia32_pmaxuw256_mask, "V16sV16sV16sV16sUs", "") -BUILTIN(__builtin_ia32_pminsb128_mask, "V16cV16cV16cV16cUs", "") -BUILTIN(__builtin_ia32_pminsb256_mask, "V32cV32cV32cV32cUi", "") -BUILTIN(__builtin_ia32_pminsw128_mask, "V8sV8sV8sV8sUc", "") -BUILTIN(__builtin_ia32_pminsw256_mask, "V16sV16sV16sV16sUs", "") -BUILTIN(__builtin_ia32_pminub128_mask, "V16cV16cV16cV16cUs", "") -BUILTIN(__builtin_ia32_pminub256_mask, "V32cV32cV32cV32cUi", "") -BUILTIN(__builtin_ia32_pminuw128_mask, "V8sV8sV8sV8sUc", "") -BUILTIN(__builtin_ia32_pminuw256_mask, "V16sV16sV16sV16sUs", "") -BUILTIN(__builtin_ia32_pshufb128_mask, "V16cV16cV16cV16cUs", "") -BUILTIN(__builtin_ia32_pshufb256_mask, "V32cV32cV32cV32cUi", "") -BUILTIN(__builtin_ia32_psubsb128_mask, "V16cV16cV16cV16cUs", "") -BUILTIN(__builtin_ia32_psubsb256_mask, "V32cV32cV32cV32cUi", "") -BUILTIN(__builtin_ia32_psubsw128_mask, "V8sV8sV8sV8sUc", "") -BUILTIN(__builtin_ia32_psubsw256_mask, "V16sV16sV16sV16sUs", "") -BUILTIN(__builtin_ia32_psubusb128_mask, "V16cV16cV16cV16cUs", "") -BUILTIN(__builtin_ia32_psubusb256_mask, "V32cV32cV32cV32cUi", "") -BUILTIN(__builtin_ia32_psubusw128_mask, "V8sV8sV8sV8sUc", "") -BUILTIN(__builtin_ia32_psubusw256_mask, "V16sV16sV16sV16sUs", "") -BUILTIN(__builtin_ia32_vpermi2varhi128_mask, "V8sV8sV8sV8sUc", "") -BUILTIN(__builtin_ia32_vpermi2varhi256_mask, "V16sV16sV16sV16sUs", "") -BUILTIN(__builtin_ia32_vpermt2varhi128_mask, "V8sV8sV8sV8sUc", "") -BUILTIN(__builtin_ia32_vpermt2varhi128_maskz, "V8sV8sV8sV8sUc", "") -BUILTIN(__builtin_ia32_vpermt2varhi256_mask, "V16sV16sV16sV16sUs", "") -BUILTIN(__builtin_ia32_vpermt2varhi256_maskz, "V16sV16sV16sV16sUs", "") +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_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_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_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_rcp28pd_mask, "V8dV8dV8dUcIi", "", "avx512er") +TARGET_BUILTIN(__builtin_ia32_rcp28ps_mask, "V16fV16fV16fUsIi", "", "avx512er") +TARGET_BUILTIN(__builtin_ia32_exp2pd_mask, "V8dV8dV8dUcIi", "", "avx512er") +TARGET_BUILTIN(__builtin_ia32_exp2ps_mask, "V16fV16fV16fUsIi", "", "avx512er") + +TARGET_BUILTIN(__builtin_ia32_cvttps2dq512_mask, "V16iV16fV16iUsIi", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_cvttps2udq512_mask, "V16iV16fV16iUsIi", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_cvttpd2dq512_mask, "V8iV8dV8iUcIi", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_cvttpd2udq512_mask, "V8iV8dV8iUcIi", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_cmpps512_mask, "UsV16fV16fIiUsIi", "", "avx512f") + +TARGET_BUILTIN(__builtin_ia32_cmpps256_mask, "UcV8fV8fIiUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_cmpps128_mask, "UcV4fV4fIiUc", "", "avx512vl") + +TARGET_BUILTIN(__builtin_ia32_pcmpeqb512_mask, "LLiV64cV64cLLi", "", "avx512bw") +TARGET_BUILTIN(__builtin_ia32_pcmpeqd512_mask, "sV16iV16is", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_pcmpeqq512_mask, "cV8LLiV8LLic", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_pcmpeqw512_mask, "iV32sV32si", "", "avx512bw") + +TARGET_BUILTIN(__builtin_ia32_pcmpeqb256_mask, "iV32cV32ci", "", "avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_pcmpeqd256_mask, "cV8iV8ic", "", "avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_pcmpeqq256_mask, "cV4LLiV4LLic", "", "avx512vl,avx512bw") +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_pcmpeqw128_mask, "cV8sV8sc", "", "avx512vl,avx512bw") + +TARGET_BUILTIN(__builtin_ia32_pcmpgtb512_mask, "LLiV64cV64cLLi", "", "avx512bw") +TARGET_BUILTIN(__builtin_ia32_pcmpgtd512_mask, "sV16iV16is", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_pcmpgtq512_mask, "cV8LLiV8LLic", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_pcmpgtw512_mask, "iV32sV32si", "", "avx512bw") + +TARGET_BUILTIN(__builtin_ia32_pcmpgtb256_mask, "iV32cV32ci", "", "avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_pcmpgtd256_mask, "cV8iV8ic", "", "avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_pcmpgtq256_mask, "cV4LLiV4LLic", "", "avx512vl,avx512bw") +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_pcmpgtw128_mask, "cV8sV8sc", "", "avx512vl,avx512bw") + +TARGET_BUILTIN(__builtin_ia32_cmppd512_mask, "UcV8dV8dIiUcIi", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_cmppd256_mask, "UcV4dV4dIiUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_cmppd128_mask, "UcV2dV2dIiUc", "", "avx512vl") + +TARGET_BUILTIN(__builtin_ia32_rndscaleps_mask, "V16fV16fIiV16fUsIi", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_rndscalepd_mask, "V8dV8dIiV8dUcIi", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_cvtps2dq512_mask, "V16iV16fV16iUsIi", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_cvtpd2dq512_mask, "V8iV8dV8iUcIi", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_cvtps2udq512_mask, "V16iV16fV16iUsIi", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_cvtpd2udq512_mask, "V8iV8dV8iUcIi", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_minps512_mask, "V16fV16fV16fV16fUsIi", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_minpd512_mask, "V8dV8dV8dV8dUcIi", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_maxps512_mask, "V16fV16fV16fV16fUsIi", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_maxpd512_mask, "V8dV8dV8dV8dUcIi", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_cvtdq2ps512_mask, "V16fV16iV16fUsIi", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_cvtudq2ps512_mask, "V16fV16iV16fUsIi", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_cvtdq2pd512_mask, "V8dV8iV8dUc", "", "avx512f") +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") +TARGET_BUILTIN(__builtin_ia32_pmaxsq512_mask, "V8LLiV8LLiV8LLiV8LLiUc", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_pmaxud512_mask, "V16iV16iV16iV16iUs", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_pmaxuq512_mask, "V8LLiV8LLiV8LLiV8LLiUc", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_pminsd512_mask, "V16iV16iV16iV16iUs", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_pminsq512_mask, "V8LLiV8LLiV8LLiV8LLiUc", "", "avx512f") +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_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_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_knothi, "UsUs", "", "avx512f") + +TARGET_BUILTIN(__builtin_ia32_cmpb128_mask, "UsV16cV16cIiUs", "", "avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_cmpd128_mask, "UcV4iV4iIiUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_cmpq128_mask, "UcV2LLiV2LLiIiUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_cmpw128_mask, "UcV8sV8sIiUc", "", "avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_cmpb256_mask, "UiV32cV32cIiUi", "", "avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_cmpd256_mask, "UcV8iV8iIiUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_cmpq256_mask, "UcV4LLiV4LLiIiUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_cmpw256_mask, "UsV16sV16sIiUs", "", "avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_cmpb512_mask, "ULLiV64cV64cIiULLi", "", "avx512bw") +TARGET_BUILTIN(__builtin_ia32_cmpd512_mask, "UsV16iV16iIiUs", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_cmpq512_mask, "UcV8LLiV8LLiIiUc", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_cmpw512_mask, "UiV32sV32sIiUi", "", "avx512bw") +TARGET_BUILTIN(__builtin_ia32_ucmpb128_mask, "UsV16cV16cIiUs", "", "avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_ucmpd128_mask, "UcV4iV4iIiUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_ucmpq128_mask, "UcV2LLiV2LLiIiUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_ucmpw128_mask, "UcV8sV8sIiUc", "", "avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_ucmpb256_mask, "UiV32cV32cIiUi", "", "avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_ucmpd256_mask, "UcV8iV8iIiUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_ucmpq256_mask, "UcV4LLiV4LLiIiUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_ucmpw256_mask, "UsV16sV16sIiUs", "", "avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_ucmpb512_mask, "ULLiV64cV64cIiULLi", "", "avx512bw") +TARGET_BUILTIN(__builtin_ia32_ucmpd512_mask, "UsV16iV16iIiUs", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_ucmpq512_mask, "UcV8LLiV8LLiIiUc", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_ucmpw512_mask, "UiV32sV32sIiUi", "", "avx512bw") + +TARGET_BUILTIN(__builtin_ia32_paddd256_mask, "V8iV8iV8iV8iUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_paddq256_mask, "V4LLiV4LLiV4LLiV4LLiUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_psubd256_mask, "V8iV8iV8iV8iUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_psubq256_mask, "V4LLiV4LLiV4LLiV4LLiUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_paddd128_mask, "V4iV4iV4iV4iUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_paddq128_mask, "V2LLiV2LLiV2LLiV2LLiUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_psubd128_mask, "V4iV4iV4iV4iUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_psubq128_mask, "V2LLiV2LLiV2LLiV2LLiUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmuldq256_mask, "V4LLiV8iV8iV4LLiUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmuldq128_mask, "V2LLiV4iV4iV2LLiUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmuludq256_mask, "V4LLiV8iV8iV4LLiUc", "", "avx512vl") +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") +TARGET_BUILTIN(__builtin_ia32_paddw512_mask, "V32sV32sV32sV32sUi", "", "avx512bw") +TARGET_BUILTIN(__builtin_ia32_psubw512_mask, "V32sV32sV32sV32sUi", "", "avx512bw") +TARGET_BUILTIN(__builtin_ia32_pmullw512_mask, "V32sV32sV32sV32sUi", "", "avx512bw") +TARGET_BUILTIN(__builtin_ia32_paddb256_mask, "V32cV32cV32cV32cUi", "", "avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_paddw256_mask, "V16sV16sV16sV16sUs", "", "avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_psubb256_mask, "V32cV32cV32cV32cUi", "", "avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_psubw256_mask, "V16sV16sV16sV16sUs", "", "avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_paddb128_mask, "V16cV16cV16cV16cUs", "", "avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_paddw128_mask, "V8sV8sV8sV8sUc", "", "avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_psubb128_mask, "V16cV16cV16cV16cUs", "", "avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_psubw128_mask, "V8sV8sV8sV8sUc", "", "avx512vl,avx512bw") +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") +TARGET_BUILTIN(__builtin_ia32_psubd512_mask, "V16iV16iV16iV16iUs", "", "avx512f") + +TARGET_BUILTIN(__builtin_ia32_pmulld512_mask, "V16iV16iV16iV16iUs", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_pmullq512_mask, "V8LLiV8LLiV8LLiV8LLiUc", "", "avx512dq") +TARGET_BUILTIN(__builtin_ia32_xorpd512_mask, "V8dV8dV8dV8dUc", "", "avx512dq") +TARGET_BUILTIN(__builtin_ia32_xorps512_mask, "V16fV16fV16fV16fUs", "", "avx512dq") +TARGET_BUILTIN(__builtin_ia32_orpd512_mask, "V8dV8dV8dV8dUc", "", "avx512dq") +TARGET_BUILTIN(__builtin_ia32_orps512_mask, "V16fV16fV16fV16fUs", "", "avx512dq") +TARGET_BUILTIN(__builtin_ia32_andpd512_mask, "V8dV8dV8dV8dUc", "", "avx512dq") +TARGET_BUILTIN(__builtin_ia32_andps512_mask, "V16fV16fV16fV16fUs", "", "avx512dq") +TARGET_BUILTIN(__builtin_ia32_andnpd512_mask, "V8dV8dV8dV8dUc", "", "avx512dq") +TARGET_BUILTIN(__builtin_ia32_andnps512_mask, "V16fV16fV16fV16fUs", "", "avx512dq") +TARGET_BUILTIN(__builtin_ia32_pmullq256_mask, "V4LLiV4LLiV4LLiV4LLiUc", "", "avx512vl,avx512dq") +TARGET_BUILTIN(__builtin_ia32_pmullq128_mask, "V2LLiV2LLiV2LLiV2LLiUc", "", "avx512vl,avx512dq") +TARGET_BUILTIN(__builtin_ia32_andnpd256_mask, "V4dV4dV4dV4dUc", "", "avx512vl,avx512dq") +TARGET_BUILTIN(__builtin_ia32_andnpd128_mask, "V2dV2dV2dV2dUc", "", "avx512vl,avx512dq") +TARGET_BUILTIN(__builtin_ia32_andnps256_mask, "V8fV8fV8fV8fUc", "", "avx512vl,avx512dq") +TARGET_BUILTIN(__builtin_ia32_andnps128_mask, "V4fV4fV4fV4fUc", "", "avx512vl,avx512dq") +TARGET_BUILTIN(__builtin_ia32_andpd256_mask, "V4dV4dV4dV4dUc", "", "avx512vl,avx512dq") +TARGET_BUILTIN(__builtin_ia32_andpd128_mask, "V2dV2dV2dV2dUc", "", "avx512vl,avx512dq") +TARGET_BUILTIN(__builtin_ia32_andps256_mask, "V8fV8fV8fV8fUc", "", "avx512vl,avx512dq") +TARGET_BUILTIN(__builtin_ia32_andps128_mask, "V4fV4fV4fV4fUc", "", "avx512vl,avx512dq") +TARGET_BUILTIN(__builtin_ia32_xorpd256_mask, "V4dV4dV4dV4dUc", "", "avx512vl,avx512dq") +TARGET_BUILTIN(__builtin_ia32_xorpd128_mask, "V2dV2dV2dV2dUc", "", "avx512vl,avx512dq") +TARGET_BUILTIN(__builtin_ia32_xorps256_mask, "V8fV8fV8fV8fUc", "", "avx512vl,avx512dq") +TARGET_BUILTIN(__builtin_ia32_xorps128_mask, "V4fV4fV4fV4fUc", "", "avx512vl,avx512dq") +TARGET_BUILTIN(__builtin_ia32_orpd256_mask, "V4dV4dV4dV4dUc", "", "avx512vl,avx512dq") +TARGET_BUILTIN(__builtin_ia32_orpd128_mask, "V2dV2dV2dV2dUc", "", "avx512vl,avx512dq") +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") +TARGET_BUILTIN(__builtin_ia32_packsswb512_mask, "V64cV32sV32sV64cULLi", "", "avx512bw") +TARGET_BUILTIN(__builtin_ia32_packusdw512_mask, "V32sV16iV16iV32sUi", "", "avx512bw") +TARGET_BUILTIN(__builtin_ia32_packuswb512_mask, "V64cV32sV32sV64cULLi", "", "avx512bw") +TARGET_BUILTIN(__builtin_ia32_paddsb512_mask, "V64cV64cV64cV64cULLi", "", "avx512bw") +TARGET_BUILTIN(__builtin_ia32_paddsw512_mask, "V32sV32sV32sV32sUi", "", "avx512bw") +TARGET_BUILTIN(__builtin_ia32_paddusb512_mask, "V64cV64cV64cV64cULLi", "", "avx512bw") +TARGET_BUILTIN(__builtin_ia32_paddusw512_mask, "V32sV32sV32sV32sUi", "", "avx512bw") +TARGET_BUILTIN(__builtin_ia32_pavgb512_mask, "V64cV64cV64cV64cULLi", "", "avx512bw") +TARGET_BUILTIN(__builtin_ia32_pavgw512_mask, "V32sV32sV32sV32sUi", "", "avx512bw") +TARGET_BUILTIN(__builtin_ia32_pmaxsb512_mask, "V64cV64cV64cV64cULLi", "", "avx512bw") +TARGET_BUILTIN(__builtin_ia32_pmaxsw512_mask, "V32sV32sV32sV32sUi", "", "avx512bw") +TARGET_BUILTIN(__builtin_ia32_pmaxub512_mask, "V64cV64cV64cV64cULLi", "", "avx512bw") +TARGET_BUILTIN(__builtin_ia32_pmaxuw512_mask, "V32sV32sV32sV32sUi", "", "avx512bw") +TARGET_BUILTIN(__builtin_ia32_pminsb512_mask, "V64cV64cV64cV64cULLi", "", "avx512bw") +TARGET_BUILTIN(__builtin_ia32_pminsw512_mask, "V32sV32sV32sV32sUi", "", "avx512bw") +TARGET_BUILTIN(__builtin_ia32_pminub512_mask, "V64cV64cV64cV64cULLi", "", "avx512bw") +TARGET_BUILTIN(__builtin_ia32_pminuw512_mask, "V32sV32sV32sV32sUi", "", "avx512bw") +TARGET_BUILTIN(__builtin_ia32_pshufb512_mask, "V64cV64cV64cV64cULLi", "", "avx512bw") +TARGET_BUILTIN(__builtin_ia32_psubsb512_mask, "V64cV64cV64cV64cULLi", "", "avx512bw") +TARGET_BUILTIN(__builtin_ia32_psubsw512_mask, "V32sV32sV32sV32sUi", "", "avx512bw") +TARGET_BUILTIN(__builtin_ia32_psubusb512_mask, "V64cV64cV64cV64cULLi", "", "avx512bw") +TARGET_BUILTIN(__builtin_ia32_psubusw512_mask, "V32sV32sV32sV32sUi", "", "avx512bw") + +TARGET_BUILTIN(__builtin_ia32_vpermi2varhi512_mask, "V32sV32sV32sV32sUi", "", "avx512bw") +TARGET_BUILTIN(__builtin_ia32_vpermt2varhi512_mask, "V32sV32sV32sV32sUi", "", "avx512bw") +TARGET_BUILTIN(__builtin_ia32_vpermt2varhi512_maskz, "V32sV32sV32sV32sUi", "", "avx512bw") + +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") +TARGET_BUILTIN(__builtin_ia32_pabsw256_mask, "V16sV16sV16sUs", "", "avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_packssdw128_mask, "V8sV4iV4iV8sUc", "", "avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_packssdw256_mask, "V16sV8iV8iV16sUs", "", "avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_packsswb128_mask, "V16cV8sV8sV16cUs", "", "avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_packsswb256_mask, "V32cV16sV16sV32cUi", "", "avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_packusdw128_mask, "V8sV4iV4iV8sUc", "", "avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_packusdw256_mask, "V16sV8iV8iV16sUs", "", "avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_packuswb128_mask, "V16cV8sV8sV16cUs", "", "avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_packuswb256_mask, "V32cV16sV16sV32cUi", "", "avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_paddsb128_mask, "V16cV16cV16cV16cUs", "", "avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_paddsb256_mask, "V32cV32cV32cV32cUi", "", "avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_paddsw128_mask, "V8sV8sV8sV8sUc", "", "avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_paddsw256_mask, "V16sV16sV16sV16sUs", "", "avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_paddusb128_mask, "V16cV16cV16cV16cUs", "", "avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_paddusb256_mask, "V32cV32cV32cV32cUi", "", "avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_paddusw128_mask, "V8sV8sV8sV8sUc", "", "avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_paddusw256_mask, "V16sV16sV16sV16sUs", "", "avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_pavgb128_mask, "V16cV16cV16cV16cUs", "", "avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_pavgb256_mask, "V32cV32cV32cV32cUi", "", "avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_pavgw128_mask, "V8sV8sV8sV8sUc", "", "avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_pavgw256_mask, "V16sV16sV16sV16sUs", "", "avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_pmaxsb128_mask, "V16cV16cV16cV16cUs", "", "avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_pmaxsb256_mask, "V32cV32cV32cV32cUi", "", "avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_pmaxsw128_mask, "V8sV8sV8sV8sUc", "", "avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_pmaxsw256_mask, "V16sV16sV16sV16sUs", "", "avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_pmaxub128_mask, "V16cV16cV16cV16cUs", "", "avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_pmaxub256_mask, "V32cV32cV32cV32cUi", "", "avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_pmaxuw128_mask, "V8sV8sV8sV8sUc", "", "avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_pmaxuw256_mask, "V16sV16sV16sV16sUs", "", "avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_pminsb128_mask, "V16cV16cV16cV16cUs", "", "avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_pminsb256_mask, "V32cV32cV32cV32cUi", "", "avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_pminsw128_mask, "V8sV8sV8sV8sUc", "", "avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_pminsw256_mask, "V16sV16sV16sV16sUs", "", "avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_pminub128_mask, "V16cV16cV16cV16cUs", "", "avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_pminub256_mask, "V32cV32cV32cV32cUi", "", "avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_pminuw128_mask, "V8sV8sV8sV8sUc", "", "avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_pminuw256_mask, "V16sV16sV16sV16sUs", "", "avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_pshufb128_mask, "V16cV16cV16cV16cUs", "", "avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_pshufb256_mask, "V32cV32cV32cV32cUi", "", "avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_psubsb128_mask, "V16cV16cV16cV16cUs", "", "avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_psubsb256_mask, "V32cV32cV32cV32cUi", "", "avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_psubsw128_mask, "V8sV8sV8sV8sUc", "", "avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_psubsw256_mask, "V16sV16sV16sV16sUs", "", "avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_psubusb128_mask, "V16cV16cV16cV16cUs", "", "avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_psubusb256_mask, "V32cV32cV32cV32cUi", "", "avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_psubusw128_mask, "V8sV8sV8sV8sUc", "", "avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_psubusw256_mask, "V16sV16sV16sV16sUs", "", "avx512vl,avx512bw") + +TARGET_BUILTIN(__builtin_ia32_vpermi2varhi128_mask, "V8sV8sV8sV8sUc", "", "avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_vpermi2varhi256_mask, "V16sV16sV16sV16sUs", "", "avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_vpermt2varhi128_mask, "V8sV8sV8sV8sUc", "", "avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_vpermt2varhi128_maskz, "V8sV8sV8sV8sUc", "", "avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_vpermt2varhi256_mask, "V16sV16sV16sV16sUs", "", "avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_vpermt2varhi256_maskz, "V16sV16sV16sV16sUs", "", "avx512vl,avx512bw") + +TARGET_BUILTIN(__builtin_ia32_pmulhrsw512_mask, "V32sV32sV32sV32sUi", "", "avx512bw") +TARGET_BUILTIN(__builtin_ia32_pmulhuw512_mask, "V32sV32sV32sV32sUi", "", "avx512bw") +TARGET_BUILTIN(__builtin_ia32_pmulhw512_mask, "V32sV32sV32sV32sUi", "", "avx512bw") + +TARGET_BUILTIN(__builtin_ia32_addpd512_mask, "V8dV8dV8dV8dUcIi", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_addps512_mask, "V16fV16fV16fV16fUsIi", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_divpd512_mask, "V8dV8dV8dV8dUcIi", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_divps512_mask, "V16fV16fV16fV16fUsIi", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_mulpd512_mask, "V8dV8dV8dV8dUcIi", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_mulps512_mask, "V16fV16fV16fV16fUsIi", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_subpd512_mask, "V8dV8dV8dV8dUcIi", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_subps512_mask, "V16fV16fV16fV16fUsIi", "", "avx512f") + +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_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") +TARGET_BUILTIN(__builtin_ia32_compressdi256_mask, "V4LLiV4LLiV4LLiUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_compresssf128_mask, "V4fV4fV4fUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_compresssf256_mask, "V8fV8fV8fUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_compresssi128_mask, "V4iV4iV4iUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_compresssi256_mask, "V8iV8iV8iUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_compressstoredf128_mask, "vV2d*V2dUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_compressstoredf256_mask, "vV4d*V4dUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_compressstoredi128_mask, "vV2LLi*V2LLiUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_compressstoredi256_mask, "vV4LLi*V4LLiUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_compressstoresf128_mask, "vV4f*V4fUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_compressstoresf256_mask, "vV8f*V8fUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_compressstoresi128_mask, "vV4i*V4iUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_compressstoresi256_mask, "vV8i*V8iUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_cvtdq2pd128_mask, "V2dV4iV2dUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_cvtdq2pd256_mask, "V4dV4iV4dUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_cvtdq2ps128_mask, "V4fV4iV4fUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_cvtdq2ps256_mask, "V8fV8iV8fUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_cvtpd2dq128_mask, "V4iV2dV4iUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_cvtpd2dq256_mask, "V4iV4dV4iUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_cvtpd2ps_mask, "V4fV2dV4fUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_cvtpd2ps256_mask, "V4fV4dV4fUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_cvtpd2udq128_mask, "V4iV2dV4iUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_cvtpd2udq256_mask, "V4iV4dV4iUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_cvtps2dq128_mask, "V4iV4fV4iUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_cvtps2dq256_mask, "V8iV8fV8iUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_cvtps2pd128_mask, "V2dV4fV2dUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_cvtps2pd256_mask, "V4dV4fV4dUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_cvtps2udq128_mask, "V4iV4fV4iUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_cvtps2udq256_mask, "V8iV8fV8iUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_cvttpd2dq128_mask, "V4iV2dV4iUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_cvttpd2dq256_mask, "V4iV4dV4iUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_cvttpd2udq128_mask, "V4iV2dV4iUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_cvttpd2udq256_mask, "V4iV4dV4iUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_cvttps2dq128_mask, "V4iV4fV4iUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_cvttps2dq256_mask, "V8iV8fV8iUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_cvttps2udq128_mask, "V4iV4fV4iUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_cvttps2udq256_mask, "V8iV8fV8iUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_cvtudq2pd128_mask, "V2dV4iV2dUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_cvtudq2pd256_mask, "V4dV4iV4dUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_cvtudq2ps128_mask, "V4fV4iV4fUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_cvtudq2ps256_mask, "V8fV8iV8fUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_divpd_mask, "V2dV2dV2dV2dUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_divpd256_mask, "V4dV4dV4dV4dUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_divps_mask, "V4fV4fV4fV4fUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_divps256_mask, "V8fV8fV8fV8fUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_expanddf128_mask, "V2dV2dV2dUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_expanddf256_mask, "V4dV4dV4dUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_expanddi128_mask, "V2LLiV2LLiV2LLiUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_expanddi256_mask, "V4LLiV4LLiV4LLiUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_expandloaddf128_mask, "V2dV2d*V2dUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_expandloaddf256_mask, "V4dV4d*V4dUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_expandloaddi128_mask, "V4iV2LLi*V2LLiUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_expandloaddi256_mask, "V4LLiV4LLi*V4LLiUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_expandloadsf128_mask, "V4fV4f*V4fUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_expandloadsf256_mask, "V8fV8f*V8fUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_expandloadsi128_mask, "V4iV4i*V4iUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_expandloadsi256_mask, "V8iV8i*V8iUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_expandsf128_mask, "V4fV4fV4fUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_expandsf256_mask, "V8fV8fV8fUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_expandsi128_mask, "V4iV4iV4iUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_expandsi256_mask, "V8iV8iV8iUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_getexppd128_mask, "V2dV2dV2dUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_getexppd256_mask, "V4dV4dV4dUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_getexpps128_mask, "V4fV4fV4fUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_getexpps256_mask, "V8fV8fV8fUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_maxpd_mask, "V2dV2dV2dV2dUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_maxpd256_mask, "V4dV4dV4dV4dUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_maxps_mask, "V4fV4fV4fV4fUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_maxps256_mask, "V8fV8fV8fV8fUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_minpd_mask, "V2dV2dV2dV2dUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_minpd256_mask, "V4dV4dV4dV4dUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_minps_mask, "V4fV4fV4fV4fUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_minps256_mask, "V8fV8fV8fV8fUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_mulpd_mask, "V2dV2dV2dV2dUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_mulpd256_mask, "V4dV4dV4dV4dUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_mulps_mask, "V4fV4fV4fV4fUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_mulps256_mask, "V8fV8fV8fV8fUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pabsd128_mask, "V4iV4iV4iUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pabsd256_mask, "V8iV8iV8iUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pabsq128_mask, "V2LLiV2LLiV2LLiUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pabsq256_mask, "V4LLiV4LLiV4LLiUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmaxsd128_mask, "V4iV4iV4iV4iUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmaxsd256_mask, "V8iV8iV8iV8iUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmaxsq128_mask, "V2LLiV2LLiV2LLiV2LLiUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmaxsq256_mask, "V4LLiV4LLiV4LLiV4LLiUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmaxud128_mask, "V4iV4iV4iV4iUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmaxud256_mask, "V8iV8iV8iV8iUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmaxuq128_mask, "V2LLiV2LLiV2LLiV2LLiUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pmaxuq256_mask, "V4LLiV4LLiV4LLiV4LLiUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pminsd128_mask, "V4iV4iV4iV4iUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pminsd256_mask, "V8iV8iV8iV8iUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pminsq128_mask, "V2LLiV2LLiV2LLiV2LLiUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pminsq256_mask, "V4LLiV4LLiV4LLiV4LLiUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pminud128_mask, "V4iV4iV4iV4iUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pminud256_mask, "V8iV8iV8iV8iUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pminuq128_mask, "V2LLiV2LLiV2LLiV2LLiUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_pminuq256_mask, "V4LLiV4LLiV4LLiV4LLiUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_rndscalepd_128_mask, "V2dV2dIiV2dUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_rndscalepd_256_mask, "V4dV4dIiV4dUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_rndscaleps_128_mask, "V4fV4fIiV4fUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_rndscaleps_256_mask, "V8fV8fIiV8fUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_scalefpd128_mask, "V2dV2dV2dV2dUc", "", "avx512vl") +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_sqrtpd128_mask, "V2dV2dV2dUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_sqrtpd256_mask, "V4dV4dV4dUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_sqrtps128_mask, "V4fV4fV4fUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_sqrtps256_mask, "V8fV8fV8fUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_subpd128_mask, "V2dV2dV2dV2dUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_subpd256_mask, "V4dV4dV4dV4dUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_subps128_mask, "V4fV4fV4fV4fUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_subps256_mask, "V8fV8fV8fV8fUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_vpermi2vard128_mask, "V4iV4iV4iV4iUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_vpermi2vard256_mask, "V8iV8iV8iV8iUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_vpermi2varpd128_mask, "V2dV2dV2LLiV2dUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_vpermi2varpd256_mask, "V4dV4dV4LLiV4dUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_vpermi2varps128_mask, "V4fV4fV4iV4fUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_vpermi2varps256_mask, "V8fV8fV8iV8fUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_vpermi2varq128_mask, "V2LLiV2LLiV2LLiV2LLiUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_vpermi2varq256_mask, "V4LLiV4LLiV4LLiV4LLiUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_vpermt2vard128_mask, "V4iV4iV4iV4iUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_vpermt2vard128_maskz, "V4iV4iV4iV4iUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_vpermt2vard256_mask, "V8iV8iV8iV8iUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_vpermt2vard256_maskz, "V8iV8iV8iV8iUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_vpermt2varpd128_mask, "V2dV2LLiV2dV2dUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_vpermt2varpd128_maskz, "V2dV2LLiV2dV2dUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_vpermt2varpd256_mask, "V4dV4LLiV4dV4dUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_vpermt2varpd256_maskz, "V4dV4LLiV4dV4dUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_vpermt2varps128_mask, "V4fV4iV4fV4fUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_vpermt2varps128_maskz, "V4fV4iV4fV4fUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_vpermt2varps256_mask, "V8fV8iV8fV8fUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_vpermt2varps256_maskz, "V8fV8iV8fV8fUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_vpermt2varq128_mask, "V2LLiV2LLiV2LLiV2LLiUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_vpermt2varq128_maskz, "V2LLiV2LLiV2LLiV2LLiUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_vpermt2varq256_mask, "V4LLiV4LLiV4LLiV4LLiUc", "", "avx512vl") +TARGET_BUILTIN(__builtin_ia32_vpermt2varq256_maskz, "V4LLiV4LLiV4LLiV4LLiUc", "", "avx512vl") +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") +TARGET_BUILTIN(__builtin_ia32_cvtpd2uqq256_mask, "V4LLiV4dV4LLiUc", "", "avx512vl,avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvtps2qq128_mask, "V2LLiV4fV2LLiUc", "", "avx512vl,avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvtps2qq256_mask, "V4LLiV4fV4LLiUc", "", "avx512vl,avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvtps2uqq128_mask, "V2LLiV4fV2LLiUc", "", "avx512vl,avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvtps2uqq256_mask, "V4LLiV4fV4LLiUc", "", "avx512vl,avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvtqq2pd128_mask, "V2dV2LLiV2dUc", "", "avx512vl,avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvtqq2pd256_mask, "V4dV4LLiV4dUc", "", "avx512vl,avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvtqq2ps128_mask, "V4fV2LLiV4fUc", "", "avx512vl,avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvtqq2ps256_mask, "V4fV4LLiV4fUc", "", "avx512vl,avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvttpd2qq128_mask, "V2LLiV2dV2LLiUc", "", "avx512vl,avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvttpd2qq256_mask, "V4LLiV4dV4LLiUc", "", "avx512vl,avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvttpd2uqq128_mask, "V2LLiV2dV2LLiUc", "", "avx512vl,avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvttpd2uqq256_mask, "V4LLiV4dV4LLiUc", "", "avx512vl,avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvttps2qq128_mask, "V2LLiV4fV2LLiUc", "", "avx512vl,avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvttps2qq256_mask, "V4LLiV4fV4LLiUc", "", "avx512vl,avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvttps2uqq128_mask, "V2LLiV4fV2LLiUc", "", "avx512vl,avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvttps2uqq256_mask, "V4LLiV4fV4LLiUc", "", "avx512vl,avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvtuqq2pd128_mask, "V2dV2LLiV2dUc", "", "avx512vl,avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvtuqq2pd256_mask, "V4dV4LLiV4dUc", "", "avx512vl,avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvtuqq2ps128_mask, "V4fV2LLiV4fUc", "", "avx512vl,avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvtuqq2ps256_mask, "V4fV4LLiV4fUc", "", "avx512vl,avx512dq") +TARGET_BUILTIN(__builtin_ia32_rangepd128_mask, "V2dV2dV2dIiV2dUc", "", "avx512vl,avx512dq") +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_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_pmaddubsw128_mask, "V8sV16cV16cV8sUc", "", "avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_pmaddubsw256_mask, "V16sV32cV32cV16sUs", "", "avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_pmaddwd128_mask, "V4iV8sV8sV4iUc", "", "avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_pmaddwd256_mask, "V8iV16sV16sV8iUc", "", "avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_pmovswb128_mask, "V16cV8sV16cUc", "", "avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_pmovswb256_mask, "V16cV16sV16cUs", "", "avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_pmovuswb128_mask, "V16cV8sV16cUc", "", "avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_pmovuswb256_mask, "V16cV16sV16cUs", "", "avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_pmovwb128_mask, "V16cV8sV16cUc", "", "avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_pmovwb256_mask, "V16cV16sV16cUs", "", "avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_pmulhrsw128_mask, "V8sV8sV8sV8sUc", "", "avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_pmulhrsw256_mask, "V16sV16sV16sV16sUs", "", "avx512vl,avx512bw") +TARGET_BUILTIN(__builtin_ia32_pmulhuw128_mask, "V8sV8sV8sV8sUc", "", "avx512vl,avx512bw") +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") +TARGET_BUILTIN(__builtin_ia32_cvtps2uqq512_mask, "V8LLiV8fV8LLiUcIi", "", "avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvtqq2pd512_mask, "V8dV8LLiV8dUcIi", "", "avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvtqq2ps512_mask, "V8fV8LLiV8fUcIi", "", "avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvttpd2qq512_mask, "V8LLiV8dV8LLiUcIi", "", "avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvttpd2uqq512_mask, "V8LLiV8dV8LLiUcIi", "", "avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvttps2qq512_mask, "V8LLiV8fV8LLiUcIi", "", "avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvttps2uqq512_mask, "V8LLiV8fV8LLiUcIi", "", "avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvtuqq2pd512_mask, "V8dV8LLiV8dUcIi", "", "avx512dq") +TARGET_BUILTIN(__builtin_ia32_cvtuqq2ps512_mask, "V8fV8LLiV8fUcIi", "", "avx512dq") +TARGET_BUILTIN(__builtin_ia32_rangepd512_mask, "V8dV8dV8dIiV8dUcIi", "", "avx512dq") +TARGET_BUILTIN(__builtin_ia32_rangeps512_mask, "V16fV16fV16fIiV16fUsIi", "", "avx512dq") +TARGET_BUILTIN(__builtin_ia32_reducepd512_mask, "V8dV8dIiV8dUcIi", "", "avx512dq") +TARGET_BUILTIN(__builtin_ia32_reduceps512_mask, "V16fV16fIiV16fUsIi", "", "avx512dq") #undef BUILTIN +#undef TARGET_BUILTIN diff --git a/contrib/llvm/tools/clang/include/clang/Basic/DeclNodes.td b/contrib/llvm/tools/clang/include/clang/Basic/DeclNodes.td index e1a2312..723ea54 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/DeclNodes.td +++ b/contrib/llvm/tools/clang/include/clang/Basic/DeclNodes.td @@ -59,6 +59,7 @@ def Named : Decl<1>; def VarTemplate : DDecl<RedeclarableTemplate>; def TypeAliasTemplate : DDecl<RedeclarableTemplate>; def TemplateTemplateParm : DDecl<Template>; + def BuiltinTemplate : DDecl<Template>; def Using : DDecl<Named>; def UsingShadow : DDecl<Named>; def ObjCMethod : DDecl<Named>, DeclContext; diff --git a/contrib/llvm/tools/clang/include/clang/Basic/Diagnostic.h b/contrib/llvm/tools/clang/include/clang/Basic/Diagnostic.h index 3b7c282..1d6c19b 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/Diagnostic.h +++ b/contrib/llvm/tools/clang/include/clang/Basic/Diagnostic.h @@ -864,28 +864,27 @@ public: /// the common fields to registers, eliminating increments of the NumArgs field, /// for example. class DiagnosticBuilder { - mutable DiagnosticsEngine *DiagObj; - mutable unsigned NumArgs; + mutable DiagnosticsEngine *DiagObj = nullptr; + mutable unsigned NumArgs = 0; /// \brief Status variable indicating if this diagnostic is still active. /// // NOTE: This field is redundant with DiagObj (IsActive iff (DiagObj == 0)), // but LLVM is not currently smart enough to eliminate the null check that // Emit() would end up with if we used that as our status variable. - mutable bool IsActive; + mutable bool IsActive = false; /// \brief Flag indicating that this diagnostic is being emitted via a /// call to ForceEmit. - mutable bool IsForceEmit; + mutable bool IsForceEmit = false; void operator=(const DiagnosticBuilder &) = delete; friend class DiagnosticsEngine; - DiagnosticBuilder() - : DiagObj(nullptr), NumArgs(0), IsActive(false), IsForceEmit(false) {} + DiagnosticBuilder() = default; explicit DiagnosticBuilder(DiagnosticsEngine *diagObj) - : DiagObj(diagObj), NumArgs(0), IsActive(true), IsForceEmit(false) { + : DiagObj(diagObj), IsActive(true) { assert(diagObj && "DiagnosticBuilder requires a valid DiagnosticsEngine!"); diagObj->DiagRanges.clear(); diagObj->DiagFixItHints.clear(); @@ -1077,14 +1076,14 @@ operator<<(const DiagnosticBuilder &DB, T *DC) { } inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, - const SourceRange &R) { + SourceRange R) { DB.AddSourceRange(CharSourceRange::getTokenRange(R)); return DB; } inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, ArrayRef<SourceRange> Ranges) { - for (const SourceRange &R: Ranges) + for (SourceRange R : Ranges) DB.AddSourceRange(CharSourceRange::getTokenRange(R)); return DB; } @@ -1264,7 +1263,7 @@ class StoredDiagnostic { std::vector<FixItHint> FixIts; public: - StoredDiagnostic(); + StoredDiagnostic() = default; StoredDiagnostic(DiagnosticsEngine::Level Level, const Diagnostic &Info); StoredDiagnostic(DiagnosticsEngine::Level Level, unsigned ID, StringRef Message); @@ -1272,7 +1271,6 @@ public: StringRef Message, FullSourceLoc Loc, ArrayRef<CharSourceRange> Ranges, ArrayRef<FixItHint> Fixits); - ~StoredDiagnostic(); /// \brief Evaluates true when this object stores a diagnostic. explicit operator bool() const { return Message.size() > 0; } diff --git a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticCommonKinds.td b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticCommonKinds.td index fc3ca62..ccc271a 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticCommonKinds.td +++ b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticCommonKinds.td @@ -84,6 +84,10 @@ def err_module_not_built : Error<"could not build module '%0'">, DefaultFatal; def err_module_build_disabled: Error< "module '%0' is needed but has not been provided, and implicit use of module " "files is disabled">, DefaultFatal; +def err_module_unavailable : Error< + "module '%0' %select{is incompatible with|requires}1 feature '%2'">; +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; def err_module_lock_timeout : Error< @@ -194,9 +198,8 @@ def err_unable_to_make_temp : Error< "unable to make temporary file: %0">; // Modules -def err_module_file_conflict : Error<"module '%0' found in both '%1' and '%2'">; def err_module_format_unhandled : Error< - "no handler registered for module format '%0'">; + "no handler registered for module format '%0'">, DefaultFatal; // TransformActions // TODO: Use a custom category name to distinguish rewriter errors. @@ -208,4 +211,7 @@ def note_mt_message : Note<"[rewriter] %0">; def warn_arcmt_nsalloc_realloc : Warning<"[rewriter] call returns pointer to GC managed memory; it will become unmanaged in ARC">; def err_arcmt_nsinvocation_ownership : Error<"NSInvocation's %0 is not safe to be used with an object with ownership other than __unsafe_unretained">; +// OpenMP +def err_omp_more_one_clause : Error< + "directive '#pragma omp %0' cannot contain more than one '%1' clause%select{| with '%3' name modifier| with 'source' dependence}2">; } diff --git a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticDriverKinds.td b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticDriverKinds.td index f7f09da..7a71285 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticDriverKinds.td +++ b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticDriverKinds.td @@ -81,6 +81,8 @@ def err_drv_invalid_mfloat_abi : Error< "invalid float ABI '%0'">; def err_drv_invalid_libcxx_deployment : Error< "invalid deployment target for -stdlib=libc++ (requires %0 or later)">; +def err_drv_invalid_argument_to_fdebug_prefix_map : Error< + "invalid argument '%0' to -fdebug-prefix-map">; def err_drv_malformed_sanitizer_blacklist : Error< "malformed sanitizer blacklist: '%0'">; @@ -100,12 +102,18 @@ def err_drv_cc_print_options_failure : Error< "unable to open CC_PRINT_OPTIONS file: %0">; def err_drv_preamble_format : Error< "incorrect format for -preamble-bytes=N,END">; +def err_drv_conflicting_deployment_targets : Error< + "conflicting deployment targets, both '%0' and '%1' are present in environment">; def err_drv_objc_gc_arr : Error< "cannot specify both '-fobjc-arc' and '%0'">; def err_arc_unsupported_on_runtime : Error< "-fobjc-arc is not supported on platforms using the legacy runtime">; def err_arc_unsupported_on_toolchain : Error< // feel free to generalize this "-fobjc-arc is not supported on versions of OS X prior to 10.6">; +def err_objc_weak_with_gc : Error< + "-fobjc-weak is not supported in Objective-C garbage collection">; +def err_objc_weak_unsupported : Error< + "-fobjc-weak is not supported on the current deployment target">; def err_drv_mg_requires_m_or_mm : Error< "option '-MG' requires '-M' or '-MM'">; def err_drv_unknown_objc_runtime : Error< @@ -117,6 +125,8 @@ def err_drv_optimization_remark_pattern : Error< def err_drv_no_neon_modifier : Error<"[no]neon is not accepted as modifier, please use [no]simd instead">; 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">, + InGroup<LibLTO>; def warn_drv_optimization_value : Warning<"optimization level '%0' is not supported; using '%1%2' instead">, InGroup<InvalidCommandLineArgument>; def warn_ignored_gcc_optimization : Warning<"optimization flag '%0' is not supported">, @@ -183,6 +193,10 @@ def err_drv_modules_validate_once_requires_timestamp : Error< "option '-fmodules-validate-once-per-build-session' requires " "'-fbuild-session-timestamp=<seconds since Epoch>' or '-fbuild-session-file=<file>'">; +def err_test_module_file_extension_format : Error< + "-ftest-module-file-extension argument '%0' is not of the required form " + "'blockname:major:minor:hashed:user info'">; + def warn_drv_invoking_fallback : Warning<"falling back to %0">, InGroup<Fallback>; @@ -192,4 +206,18 @@ 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_drv_unable_to_find_directory_expected : Warning< + "unable to find %0 directory, expected to be in '%1'">, + InGroup<InvalidOrNonExistentDirectory>, DefaultIgnore; + +def warn_drv_ps4_force_pic : Warning< + "option '%0' was ignored by the PS4 toolchain, using '-fPIC'">, + 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'">, + InGroup<InvalidOrNonExistentDirectory>; + +def err_drv_unsupported_linker : Error<"unsupported value '%0' for -linker option">; } diff --git a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticFrontendKinds.td b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticFrontendKinds.td index f4ab480..033834b 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticFrontendKinds.td +++ b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticFrontendKinds.td @@ -45,6 +45,17 @@ def remark_fe_backend_optimization_remark_missed : Remark<"%0">, BackendInfo, InGroup<BackendOptimizationRemarkMissed>; def remark_fe_backend_optimization_remark_analysis : Remark<"%0">, BackendInfo, InGroup<BackendOptimizationRemarkAnalysis>; +def remark_fe_backend_optimization_remark_analysis_fpcommute : Remark<"%0; " + "allow reordering by specifying '#pragma clang loop vectorize(enable)' " + "before the loop or by providing the compiler option '-ffast-math'.">, + BackendInfo, InGroup<BackendOptimizationRemarkAnalysis>; +def remark_fe_backend_optimization_remark_analysis_aliasing : Remark<"%0; " + "allow reordering by specifying '#pragma clang loop vectorize(enable)' " + "before the loop. If the arrays will always be independent specify " + "'#pragma clang loop vectorize(assume_safety)' before the loop or provide " + "the '__restrict__' qualifier with the independent array arguments. " + "Erroneous results will occur if these options are incorrectly applied!">, + 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 " @@ -161,6 +172,9 @@ def warn_incompatible_analyzer_plugin_api : Warning< def note_incompatible_analyzer_plugin_api : Note< "current API version is '%0', but plugin was compiled with version '%1'">; +def warn_module_config_mismatch : Warning< + "module file %0 cannot be loaded due to a configuration mismatch with the current " + "compilation">, InGroup<DiagGroup<"module-file-config-mismatch">>, DefaultError; def err_module_map_not_found : Error<"module map file '%0' not found">, DefaultFatal; def err_missing_module_name : Error< @@ -173,10 +187,6 @@ def err_no_submodule_suggest : Error< "no submodule named %0 in module '%1'; did you mean '%2'?">; def warn_missing_submodule : Warning<"missing submodule '%0'">, InGroup<IncompleteUmbrella>; -def err_module_unavailable : Error< - "module '%0' %select{is incompatible with|requires}1 feature '%2'">; -def err_module_header_missing : Error< - "%select{|umbrella }0header '%1' not found">; def err_module_cannot_create_includes : Error< "cannot create includes file for module %0: %1">; def warn_module_config_macro_undef : Warning< @@ -190,20 +200,17 @@ def remark_module_build : Remark<"building module '%0' as '%1'">, InGroup<ModuleBuild>; def remark_module_build_done : Remark<"finished building module '%0'">, InGroup<ModuleBuild>; +def err_modules_embed_file_not_found : + Error<"file '%0' specified by '-fmodules-embed-file=' not found">, + DefaultFatal; + +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_conflicting_module_files : Error< - "module '%0' is defined in both '%1' and '%2'">; -def err_module_file_not_found : Error< - "module file '%0' not found">, DefaultFatal; -def err_module_file_invalid : Error< - "file '%0' is not a valid precompiled module file">, DefaultFatal; -def note_module_file_imported_by : Note< - "imported by %select{|module '%2' in }1'%0'">; -def err_module_file_not_module : Error< - "AST file '%0' was not built as a module">, DefaultFatal; def err_missing_vfs_overlay_file : Error< "virtual filesystem overlay file '%0' not found">, DefaultFatal; diff --git a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticGroups.td b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticGroups.td index 4ecd5d5..8e5f57d 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticGroups.td +++ b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticGroups.td @@ -24,14 +24,17 @@ def : DiagGroup<"aggregate-return">; def GNUAlignofExpression : DiagGroup<"gnu-alignof-expression">; def AmbigMemberTemplate : DiagGroup<"ambiguous-member-template">; def GNUAnonymousStruct : DiagGroup<"gnu-anonymous-struct">; +def GNUAutoType : DiagGroup<"gnu-auto-type">; def ArrayBounds : DiagGroup<"array-bounds">; def ArrayBoundsPointerArithmetic : DiagGroup<"array-bounds-pointer-arithmetic">; def Availability : DiagGroup<"availability">; def Section : DiagGroup<"section">; def AutoImport : DiagGroup<"auto-import">; +def CXX14BinaryLiteral : DiagGroup<"c++14-binary-literal">; def GNUBinaryLiteral : DiagGroup<"gnu-binary-literal">; def GNUCompoundLiteralInitializer : DiagGroup<"gnu-compound-literal-initializer">; def BitFieldConstantConversion : DiagGroup<"bitfield-constant-conversion">; +def BitFieldWidth : DiagGroup<"bitfield-width">; def ConstantConversion : DiagGroup<"constant-conversion", [ BitFieldConstantConversion ] >; def LiteralConversion : DiagGroup<"literal-conversion">; @@ -44,6 +47,7 @@ def BoolConversion : DiagGroup<"bool-conversion", [PointerBoolConversion, def IntConversion : DiagGroup<"int-conversion">; def EnumConversion : DiagGroup<"enum-conversion">; def FloatConversion : DiagGroup<"float-conversion">; +def DoublePromotion : DiagGroup<"double-promotion">; def EnumTooLarge : DiagGroup<"enum-too-large">; def UnsupportedNan : DiagGroup<"unsupported-nan">; def NonLiteralNullConversion : DiagGroup<"non-literal-null-conversion">; @@ -79,6 +83,7 @@ def AbstractFinalClass : DiagGroup<"abstract-final-class">; def CXX11CompatDeprecatedWritableStr : DiagGroup<"c++11-compat-deprecated-writable-strings">; +def DeprecatedAttributes : DiagGroup<"deprecated-attributes">; def DeprecatedDeclarations : DiagGroup<"deprecated-declarations">; def UnavailableDeclarations : DiagGroup<"unavailable-declarations">; def PartialAvailability : DiagGroup<"partial-availability">; @@ -88,12 +93,14 @@ def DeprecatedRegister : DiagGroup<"deprecated-register">; def DeprecatedWritableStr : DiagGroup<"deprecated-writable-strings", [CXX11CompatDeprecatedWritableStr]>; // FIXME: Why is DeprecatedImplementations not in this group? -def Deprecated : DiagGroup<"deprecated", [DeprecatedDeclarations, +def Deprecated : DiagGroup<"deprecated", [DeprecatedAttributes, + DeprecatedDeclarations, DeprecatedIncrementBool, DeprecatedRegister, DeprecatedWritableStr]>, DiagCategory<"Deprecations">; +def LibLTO : DiagGroup<"liblto">; def : DiagGroup<"disabled-optimization">; def : DiagGroup<"discard-qual">; def : DiagGroup<"div-by-zero">; @@ -180,6 +187,9 @@ def CXX14Compat : DiagGroup<"c++14-compat", [CXXPre1zCompat]>; def CXX14CompatPedantic : DiagGroup<"c++14-compat-pedantic", [CXXPre1zCompatPedantic]>; +def CXX1zCompat : DiagGroup<"c++1z-compat", [DeprecatedRegister, + DeprecatedIncrementBool]>; + def : DiagGroup<"effc++">; def DivZero : DiagGroup<"division-by-zero">; def ExitTimeDestructors : DiagGroup<"exit-time-destructors">; @@ -195,10 +205,12 @@ def DanglingElse: DiagGroup<"dangling-else">; def DanglingField : DiagGroup<"dangling-field">; def DistributedObjectModifiers : DiagGroup<"distributed-object-modifiers">; def FlagEnum : DiagGroup<"flag-enum">; +def IncrementBool : DiagGroup<"increment-bool", [DeprecatedIncrementBool]>; def InfiniteRecursion : DiagGroup<"infinite-recursion">; def GNUImaginaryConstant : DiagGroup<"gnu-imaginary-constant">; def IgnoredQualifiers : DiagGroup<"ignored-qualifiers">; def : DiagGroup<"import">; +def GNUIncludeNext : DiagGroup<"gnu-include-next">; def IncompatibleMSStruct : DiagGroup<"incompatible-ms-struct">; def IncompatiblePointerTypesDiscardsQualifiers : DiagGroup<"incompatible-pointer-types-discards-qualifiers">; @@ -213,6 +225,7 @@ def NonModularIncludeInModule : DiagGroup<"non-modular-include-in-module", def IncompleteModule : DiagGroup<"incomplete-module", [IncompleteUmbrella, NonModularIncludeInModule]>; +def CXX11InlineNamespace : DiagGroup<"c++11-inline-namespace">; def InvalidNoreturn : DiagGroup<"invalid-noreturn">; def InvalidSourceEncoding : DiagGroup<"invalid-source-encoding">; def KNRPromotedParameter : DiagGroup<"knr-promoted-parameter">; @@ -247,6 +260,7 @@ def MismatchedTags : DiagGroup<"mismatched-tags">; def MissingFieldInitializers : DiagGroup<"missing-field-initializers">; def ModuleBuild : DiagGroup<"module-build">; def ModuleConflict : DiagGroup<"module-conflict">; +def ModuleFileExtension : DiagGroup<"module-file-extension">; def NewlineEOF : DiagGroup<"newline-eof">; def Nullability : DiagGroup<"nullability">; def NullabilityDeclSpec : DiagGroup<"nullability-declspec">; @@ -304,6 +318,7 @@ def : DiagGroup<"redundant-decls">; def RedeclaredClassMember : DiagGroup<"redeclared-class-member">; def GNURedeclaredEnum : DiagGroup<"gnu-redeclared-enum">; def RedundantMove : DiagGroup<"redundant-move">; +def Register : DiagGroup<"register", [DeprecatedRegister]>; def ReturnStackAddress : DiagGroup<"return-stack-address">; def ReturnTypeCLinkage : DiagGroup<"return-type-c-linkage">; def ReturnType : DiagGroup<"return-type", [ReturnTypeCLinkage]>; @@ -648,7 +663,10 @@ def Consumed : DiagGroup<"consumed">; // Note that putting warnings in -Wall will not disable them by default. If a // warning should be active _only_ when -Wall is passed in, mark it as // DefaultIgnore in addition to putting it here. -def : DiagGroup<"all", [Most, Parentheses, Switch, SwitchBool]>; +def All : DiagGroup<"all", [Most, Parentheses, Switch, SwitchBool]>; + +// Warnings that should be in clang-cl /w4. +def : DiagGroup<"CL4", [All, Extra]>; // Warnings enabled by -pedantic. This is magically filled in by TableGen. def Pedantic : DiagGroup<"pedantic">; @@ -675,11 +693,12 @@ def NonGCC : DiagGroup<"non-gcc", // A warning group for warnings about using C++11 features as extensions in // earlier C++ versions. -def CXX11 : DiagGroup<"c++11-extensions", [CXX11ExtraSemi, CXX11LongLong]>; +def CXX11 : DiagGroup<"c++11-extensions", [CXX11ExtraSemi, CXX11InlineNamespace, + CXX11LongLong]>; // A warning group for warnings about using C++14 features as extensions in // earlier C++ versions. -def CXX14 : DiagGroup<"c++14-extensions">; +def CXX14 : DiagGroup<"c++14-extensions", [CXX14BinaryLiteral]>; // A warning group for warnings about using C++1z features as extensions in // earlier C++ versions. @@ -699,13 +718,15 @@ def C99 : DiagGroup<"c99-extensions">; // A warning group for warnings about GCC extensions. def GNU : DiagGroup<"gnu", [GNUAlignofExpression, GNUAnonymousStruct, + GNUAutoType, GNUBinaryLiteral, GNUCaseRange, GNUComplexInteger, GNUCompoundLiteralInitializer, GNUConditionalOmittedOperand, GNUDesignator, GNUEmptyInitializer, GNUEmptyStruct, VLAExtension, GNUFlexibleArrayInitializer, GNUFlexibleArrayUnionMember, GNUFoldingConstant, - GNUImaginaryConstant, GNULabelsAsValue, + GNUImaginaryConstant, GNUIncludeNext, + GNULabelsAsValue, RedeclaredClassMember, GNURedeclaredEnum, GNUStatementExpression, GNUStaticFloatInit, GNUStringLiteralOperatorTemplate, @@ -715,8 +736,52 @@ def GNU : DiagGroup<"gnu", [GNUAlignofExpression, GNUAnonymousStruct, // A warning group for warnings about code that clang accepts but gcc doesn't. def GccCompat : DiagGroup<"gcc-compat">; -// A warning group for warnings about Microsoft extensions. -def Microsoft : DiagGroup<"microsoft">; +// Warnings for Microsoft extensions. +def MicrosoftCharize : DiagGroup<"microsoft-charize">; +def MicrosoftInclude : DiagGroup<"microsoft-include">; +def MicrosoftCppMacro : DiagGroup<"microsoft-cpp-macro">; +def MicrosoftFixedEnum : DiagGroup<"microsoft-fixed-enum">; +def MicrosoftSealed : DiagGroup<"microsoft-sealed">; +def MicrosoftUnqualifiedFriend : DiagGroup<"microsoft-unqualified-friend">; +def MicrosoftExceptionSpec : DiagGroup<"microsoft-exception-spec">; +def MicrosoftUsingDecl : DiagGroup<"microsoft-using-decl">; +def MicrosoftMutableReference : DiagGroup<"microsoft-mutable-reference">; +def MicrosoftPureDefinition : DiagGroup<"microsoft-pure-definition">; +def MicrosoftUnionMemberReference : DiagGroup< + "microsoft-union-member-reference">; +def MicrosoftExplicitConstructorCall : DiagGroup< + "microsoft-explicit-constructor-call">; +def MicrosoftEnumValue : DiagGroup<"microsoft-enum-value">; +def MicrosoftDefaultArgRedefinition : + DiagGroup<"microsoft-default-arg-redefinition">; +def MicrosoftTemplate : DiagGroup<"microsoft-template">; +def MicrosoftRedeclareStatic : DiagGroup<"microsoft-redeclare-static">; +def MicrosoftEnumForwardReference : + DiagGroup<"microsoft-enum-forward-reference">; +def MicrosoftGoto : DiagGroup<"microsoft-goto">; +def MicrosoftFlexibleArray : DiagGroup<"microsoft-flexible-array">; +def MicrosoftExtraQualification : DiagGroup<"microsoft-extra-qualification">; +def MicrosoftCast : DiagGroup<"microsoft-cast">; +def MicrosoftConstInit : DiagGroup<"microsoft-const-init">; +def MicrosoftVoidPseudoDtor : DiagGroup<"microsoft-void-pseudo-dtor">; +def MicrosoftAnonTag : DiagGroup<"microsoft-anon-tag">; +def MicrosoftCommentPaste : DiagGroup<"microsoft-comment-paste">; +def MicrosoftEndOfFile : DiagGroup<"microsoft-end-of-file">; +// Aliases. +def : DiagGroup<"msvc-include", [MicrosoftInclude]>; + // -Wmsvc-include = -Wmicrosoft-include + +// Warnings group for warnings about Microsoft extensions. +def Microsoft : DiagGroup<"microsoft", + [MicrosoftCharize, MicrosoftInclude, MicrosoftCppMacro, MicrosoftFixedEnum, + MicrosoftSealed, MicrosoftUnqualifiedFriend, MicrosoftExceptionSpec, + MicrosoftUsingDecl, MicrosoftMutableReference, MicrosoftPureDefinition, + MicrosoftUnionMemberReference, MicrosoftExplicitConstructorCall, + MicrosoftEnumValue, MicrosoftDefaultArgRedefinition, MicrosoftTemplate, + MicrosoftRedeclareStatic, MicrosoftEnumForwardReference, MicrosoftGoto, + MicrosoftFlexibleArray, MicrosoftExtraQualification, MicrosoftCast, + MicrosoftConstInit, MicrosoftVoidPseudoDtor, MicrosoftAnonTag, + MicrosoftCommentPaste, MicrosoftEndOfFile]>; def ObjCNonUnifiedException : DiagGroup<"objc-nonunified-exceptions">; @@ -777,3 +842,7 @@ def CudaCompat : DiagGroup<"cuda-compat">; // A warning group for things that will change semantics in the future. def FutureCompat : DiagGroup<"future-compat">; + +def InvalidOrNonExistentDirectory : DiagGroup<"invalid-or-nonexistent-directory">; + +def OptionIgnored : DiagGroup<"option-ignored">; diff --git a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticLexKinds.td b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticLexKinds.td index 5dd4ae0..ed6ff20 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticLexKinds.td +++ b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticLexKinds.td @@ -13,9 +13,8 @@ let Component = "Lex", CategoryName = "Lexical or Preprocessor Issue" in { -def null_in_string : Warning<"null character(s) preserved in string literal">, - InGroup<NullCharacter>; -def null_in_char : Warning<"null character(s) preserved in character literal">, +def null_in_char_or_string : Warning< + "null character(s) preserved in %select{char|string}0 literal">, InGroup<NullCharacter>; def null_in_file : Warning<"null character ignored">, InGroup<NullCharacter>; def warn_nested_block_comment : Warning<"'/*' within block comment">, @@ -57,8 +56,15 @@ def warn_cxx98_compat_no_newline_eof : Warning< def ext_dollar_in_identifier : Extension<"'$' in identifier">, InGroup<DiagGroup<"dollar-in-identifier-extension">>; -def ext_charize_microsoft : Extension<"charizing operator #@ is a Microsoft extension">, - InGroup<Microsoft>; +def ext_charize_microsoft : Extension< + "charizing operator #@ is a Microsoft extension">, + InGroup<MicrosoftCharize>; +def ext_comment_paste_microsoft : Extension< + "pasting two '/' tokens into a '//' comment is a Microsoft extension">, + InGroup<MicrosoftCommentPaste>; +def ext_ctrl_z_eof_microsoft : Extension< + "treating Ctrl-Z as end-of-file is a Microsoft extension">, + InGroup<MicrosoftEndOfFile>; def ext_token_used : Extension<"extension used">, InGroup<DiagGroup<"language-extension-token">>; @@ -66,10 +72,8 @@ def ext_token_used : Extension<"extension used">, def warn_cxx11_keyword : Warning<"'%0' is a keyword in C++11">, InGroup<CXX11Compat>, DefaultIgnore; -def ext_unterminated_string : ExtWarn<"missing terminating '\"' character">, - InGroup<InvalidPPToken>; -def ext_unterminated_char : ExtWarn<"missing terminating ' character">, - InGroup<InvalidPPToken>; +def ext_unterminated_char_or_string : ExtWarn< + "missing terminating %select{'|'\"'}0 character">, InGroup<InvalidPPToken>; def ext_empty_character : ExtWarn<"empty character constant">, InGroup<InvalidPPToken>; def err_unterminated_block_comment : Error<"unterminated /* comment">; @@ -153,13 +157,10 @@ def ext_nonstandard_escape : Extension< "use of non-standard escape character '\\%0'">; def ext_unknown_escape : ExtWarn<"unknown escape sequence '\\%0'">, InGroup<DiagGroup<"unknown-escape-sequence">>; -def err_invalid_decimal_digit : Error<"invalid digit '%0' in decimal constant">; -def err_invalid_binary_digit : Error<"invalid digit '%0' in binary constant">; -def err_invalid_octal_digit : Error<"invalid digit '%0' in octal constant">; -def err_invalid_suffix_integer_constant : Error< - "invalid suffix '%0' on integer constant">; -def err_invalid_suffix_float_constant : Error< - "invalid suffix '%0' on floating constant">; +def err_invalid_digit : Error< + "invalid digit '%0' in %select{decimal|octal|binary}1 constant">; +def err_invalid_suffix_constant : Error< + "invalid suffix '%0' on %select{integer|floating}1 constant">; def warn_cxx11_compat_digit_separator : Warning< "digit separators are incompatible with C++ standards before C++14">, InGroup<CXXPre14Compat>, DefaultIgnore; @@ -174,22 +175,20 @@ 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_exponent : Error< - "hexadecimal floating constants require an exponent">; -def err_hexconstant_requires_digits : Error< - "hexadecimal floating constants require a significand">; +def err_hexconstant_requires: Error< + "hexadecimal floating constants require %select{an exponent|a significand}0">; def ext_hexconstant_invalid : Extension< "hexadecimal floating constants are a C99 feature">, InGroup<C99>; def ext_binary_literal : Extension< "binary integer literals are a GNU extension">, InGroup<GNUBinaryLiteral>; def ext_binary_literal_cxx14 : Extension< - "binary integer literals are a C++14 extension">, InGroup<CXX14>; + "binary integer literals are a C++14 extension">, InGroup<CXX14BinaryLiteral>; def warn_cxx11_compat_binary_literal : Warning< "binary integer literals are incompatible with C++ standards before C++14">, InGroup<CXXPre14CompatPedantic>, DefaultIgnore; def err_pascal_string_too_long : Error<"Pascal string is too long">; -def err_octal_escape_too_large : Error<"octal escape sequence out of range">; -def err_hex_escape_too_large : Error<"hex escape sequence out of range">; +def err_escape_too_large : Error< + "%select{hex|octal}0 escape sequence out of range">; def ext_string_too_long : Extension<"string literal of length %0 exceeds " "maximum length %1 that %select{C90|ISO C99|C++}2 compilers are required to " "support">, InGroup<OverlengthStrings>; @@ -255,10 +254,13 @@ def err_pp_hash_error : Error<"%0">; } def pp_include_next_in_primary : Warning< - "#include_next in primary source file">; + "#include_next in primary source file">, + InGroup<DiagGroup<"include-next-outside-header">>; def pp_include_macros_out_of_predefines : Error< "the #__include_macros directive is only for internal use by -imacros">; -def pp_include_next_absolute_path : Warning<"#include_next with absolute path">; +def pp_include_next_absolute_path : Warning< + "#include_next with absolute path">, + InGroup<DiagGroup<"include-next-absolute-path">>; def ext_c99_whitespace_required_after_macro_name : ExtWarn< "ISO C99 requires whitespace after the macro name">, InGroup<C99>; def ext_missing_whitespace_after_macro_name : ExtWarn< @@ -266,9 +268,11 @@ def ext_missing_whitespace_after_macro_name : ExtWarn< def warn_missing_whitespace_after_macro_name : Warning< "whitespace recommended after macro name">; -def pp_pragma_once_in_main_file : Warning<"#pragma once in main file">; +def pp_pragma_once_in_main_file : Warning<"#pragma once in main file">, + InGroup<DiagGroup<"pragma-once-outside-header">>; def pp_pragma_sysheader_in_main_file : Warning< - "#pragma system_header ignored in main file">; + "#pragma system_header ignored in main file">, + InGroup<DiagGroup<"pragma-system-header-outside-header">>; def pp_poisoning_existing_macro : Warning<"poisoning existing macro">; def pp_out_of_date_dependency : Warning< "current file is older than dependency %0">; @@ -295,27 +299,29 @@ def warn_pp_macro_hides_keyword : Extension< def warn_pp_macro_is_reserved_id : Warning< "macro name is a reserved identifier">, DefaultIgnore, InGroup<ReservedIdAsMacro>; +def warn_pp_objc_macro_redef_ignored : Warning< + "ignoring redefinition of Objective-C qualifier macro">, + InGroup<DiagGroup<"objc-macro-redefinition">>; def pp_invalid_string_literal : Warning< "invalid string literal, ignoring final '\\'">; def warn_pp_expr_overflow : Warning< "integer overflow in preprocessor expression">; -def warn_pp_convert_lhs_to_positive : Warning< - "left side of operator converted from negative value to unsigned: %0">; -def warn_pp_convert_rhs_to_positive : Warning< - "right side of operator converted from negative value to unsigned: %0">; +def warn_pp_convert_to_positive : Warning< + "%select{left|right}0 side of operator converted from negative value to " + "unsigned: %1">; def ext_pp_import_directive : Extension<"#import is a language extension">, InGroup<DiagGroup<"import-preprocessor-directive-pedantic">>; def err_pp_import_directive_ms : Error< "#import of type library is an unsupported Microsoft feature">; def ext_pp_include_search_ms : ExtWarn< - "#include resolved using non-portable MSVC search rules as: %0">, - InGroup<DiagGroup<"msvc-include">>; + "#include resolved using non-portable Microsoft search rules as: %0">, + InGroup<MicrosoftInclude>; def ext_pp_ident_directive : Extension<"#ident is a language extension">; def ext_pp_include_next_directive : Extension< - "#include_next is a language extension">; + "#include_next is a language extension">, InGroup<GNUIncludeNext>; def ext_pp_warning_directive : Extension<"#warning is a language extension">; def ext_pp_extra_tokens_at_eol : ExtWarn< @@ -510,7 +516,7 @@ def ext_pp_bad_paste_ms : ExtWarn< def err_pp_operator_used_as_macro_name : Error< "C++ operator %0 (aka %1) used as a macro name">; def ext_pp_operator_used_as_macro_name : Extension< - "C++ operator %0 (aka %1) used as a macro name">, InGroup<Microsoft>; + err_pp_operator_used_as_macro_name.Text>, InGroup<MicrosoftCppMacro>; def err_pp_illegal_floating_literal : Error< "floating point literal in preprocessor expression">; def err_pp_line_requires_integer : Error< @@ -622,6 +628,8 @@ def warn_mmap_unknown_attribute : Warning<"unknown attribute '%0'">, def warn_auto_module_import : Warning< "treating #%select{include|import|include_next|__include_macros}0 as an " "import of module '%1'">, InGroup<AutoImport>, DefaultIgnore; +def note_implicit_top_level_module_import_here : Note< + "submodule of top-level module '%0' implicitly imported here">; def warn_uncovered_module_header : Warning< "umbrella header for module '%0' does not include header '%1'">, InGroup<IncompleteUmbrella>; diff --git a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticParseKinds.td b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticParseKinds.td index e4f8599..446852a 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticParseKinds.td +++ b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticParseKinds.td @@ -51,14 +51,6 @@ def warn_extra_semi_after_mem_fn_def : Warning< "extra ';' after member function definition">, InGroup<ExtraSemi>, DefaultIgnore; -def ext_duplicate_declspec : ExtWarn<"duplicate '%0' declaration specifier">, - InGroup<DuplicateDeclSpecifier>; -def warn_duplicate_declspec : Warning<"duplicate '%0' declaration specifier">, - InGroup<DuplicateDeclSpecifier>; -def ext_plain_complex : ExtWarn< - "plain '_Complex' requires a type specifier; assuming '_Complex double'">; -def ext_integer_complex : Extension< - "complex integer types are a GNU extension">, InGroup<GNUComplexInteger>; def ext_thread_before : Extension<"'__thread' before '%0'">; def ext_keyword_as_ident : ExtWarn< "keyword '%0' will be made available as an identifier " @@ -70,12 +62,6 @@ def ext_nullability : Extension< InGroup<DiagGroup<"nullability-extension">>; def error_empty_enum : Error<"use of empty enum">; -def err_invalid_sign_spec : Error<"'%0' cannot be signed or unsigned">; -def err_invalid_short_spec : Error<"'short %0' is invalid">; -def err_invalid_long_spec : Error<"'long %0' is invalid">; -def err_invalid_longlong_spec : Error<"'long long %0' is invalid">; -def err_invalid_complex_spec : Error<"'_Complex %0' is invalid">; -def err_friend_decl_spec : Error<"'%0' is invalid in friend declarations">; def ext_ident_list_in_param : Extension< "type-less parameter names in function declaration">; @@ -101,7 +87,7 @@ def ext_cxx11_enum_fixed_underlying_type : Extension< InGroup<CXX11>; def ext_c_enum_fixed_underlying_type : Extension< "enumeration types with a fixed underlying type are a Microsoft extension">, - InGroup<Microsoft>; + InGroup<MicrosoftFixedEnum>; def warn_cxx98_compat_enum_fixed_underlying_type : Warning< "enumeration types with a fixed underlying type are incompatible with C++98">, InGroup<CXX98Compat>, DefaultIgnore; @@ -271,7 +257,7 @@ def warn_cxx98_compat_ref_qualifier : Warning< "reference qualifiers on functions are incompatible with C++98">, InGroup<CXX98Compat>, DefaultIgnore; def ext_inline_namespace : ExtWarn< - "inline namespaces are a C++11 feature">, InGroup<CXX11>; + "inline namespaces are a C++11 feature">, InGroup<CXX11InlineNamespace>; def warn_cxx98_compat_inline_namespace : Warning< "inline namespaces are incompatible with C++98">, InGroup<CXX98Compat>, DefaultIgnore; @@ -286,11 +272,6 @@ def err_init_list_bin_op : Error<"initializer list cannot be used on the " def warn_cxx98_compat_trailing_return_type : Warning< "trailing return types are incompatible with C++98">, InGroup<CXX98Compat>, DefaultIgnore; -def ext_auto_type_specifier : ExtWarn< - "'auto' type specifier is a C++11 extension">, InGroup<CXX11>; -def warn_auto_storage_class : Warning< - "'auto' storage class specifier is redundant and incompatible with C++11">, - InGroup<CXX11Compat>, DefaultIgnore; def ext_auto_storage_class : ExtWarn< "'auto' storage class specifier is not permitted in C++11, and will not " "be supported in future releases">, InGroup<DiagGroup<"auto-storage-class">>; @@ -299,6 +280,9 @@ def ext_decltype_auto_type_specifier : ExtWarn< def warn_cxx11_compat_decltype_auto_type_specifier : Warning< "'decltype(auto)' type specifier is incompatible with C++ standards before " "C++14">, InGroup<CXXPre14Compat>, DefaultIgnore; +def ext_auto_type : Extension< + "'__auto_type' is a GNU extension">, + InGroup<GNUAutoType>; def ext_for_range : ExtWarn< "range-based for loop is a C++11 extension">, InGroup<CXX11>; def warn_cxx98_compat_for_range : Warning< @@ -327,9 +311,6 @@ def err_unspecified_vla_size_with_static : Error< "'static' may not be used with an unspecified variable length array size">; def err_unspecified_size_with_static : Error< "'static' may not be used without an array size">; -def warn_deprecated_register : Warning< - "'register' storage class specifier is deprecated">, - InGroup<DeprecatedRegister>; def err_expected_parentheses_around_typename : Error< "expected parentheses around type name in %0 expression">; @@ -348,39 +329,10 @@ def err_typename_invalid_constexpr : Error< def err_typename_identifiers_only : Error< "typename is allowed for identifiers only">; -def err_invalid_decl_spec_combination : Error< - "cannot combine with previous '%0' declaration specifier">; -def err_invalid_vector_decl_spec_combination : Error< - "cannot combine with previous '%0' declaration specifier. " - "'__vector' must be first">; -def err_invalid_pixel_decl_spec_combination : Error< - "'__pixel' must be preceded by '__vector'. " - "'%0' declaration specifier not allowed here">; -def err_invalid_vector_bool_decl_spec : Error< - "cannot use '%0' with '__vector bool'">; -def err_invalid_vector_long_decl_spec : Error< - "cannot use 'long' with '__vector'">; -def err_invalid_vector_float_decl_spec : Error< - "cannot use 'float' with '__vector'">; -def err_invalid_vector_double_decl_spec : Error < - "use of 'double' with '__vector' requires VSX support to be enabled " - "(available on POWER7 or later)">; -def err_invalid_vector_long_long_decl_spec : Error < - "use of 'long long' with '__vector bool' requires VSX support (available on " - "POWER7 or later) or extended Altivec support (available on POWER8 or later) " - "to be enabled">; -def err_invalid_vector_long_double_decl_spec : Error< - "cannot use 'long double' with '__vector'">; -def warn_vector_long_decl_spec_combination : Warning< - "Use of 'long' with '__vector' is deprecated">, InGroup<Deprecated>; def err_friend_invalid_in_context : Error< "'friend' used outside of class">; -def err_use_of_tag_name_without_tag : Error< - "must use '%1' tag to refer to type %0%select{| in this scope}2">; -def err_templated_using_directive : Error< - "cannot template a using directive">; -def err_templated_using_declaration : Error< - "cannot template a using declaration">; +def err_templated_using_directive_declaration : Error< + "cannot template a using %select{directive|declaration}0">; def err_unexpected_colon_in_nested_name_spec : Error< "unexpected ':' in nested name specifier; did you mean '::'?">; def err_unexpected_token_in_nested_name_spec : Error< @@ -512,7 +464,7 @@ def note_missing_end_of_definition_before : Note< "still within definition of %q0 here">; def ext_ellipsis_exception_spec : Extension< "exception specification of '...' is a Microsoft extension">, - InGroup<Microsoft>; + InGroup<MicrosoftExceptionSpec>; def err_dynamic_and_noexcept_specification : Error< "cannot have both throw() and noexcept() clause on the same function">; def err_except_spec_unparsed : Error< @@ -695,12 +647,9 @@ def warn_static_inline_explicit_inst_ignored : Warning< // Constructor template diagnostics. def err_out_of_line_constructor_template_id : Error< "out-of-line constructor for %0 cannot have template arguments">; -def err_out_of_line_template_id_names_constructor : Error< +def err_out_of_line_template_id_type_names_constructor : Error< "qualified reference to %0 is a constructor name rather than a " - "template name wherever a constructor can be declared">; -def err_out_of_line_type_names_constructor : Error< - "qualified reference to %0 is a constructor name rather than a " - "type wherever a constructor can be declared">; + "%select{template name|type}1 wherever a constructor can be declared">; def err_expected_qualified_after_typename : Error< "expected a qualified name after 'typename'">; @@ -740,15 +689,11 @@ def err_missing_whitespace_digraph : Error< "%select{template name|const_cast|dynamic_cast|reinterpret_cast|static_cast}0" " which forms the digraph '<:' (aka '[') and a ':', did you mean '< ::'?">; -def ext_deleted_function : ExtWarn< - "deleted function definitions are a C++11 extension">, InGroup<CXX11>; -def warn_cxx98_compat_deleted_function : Warning< - "deleted function definitions are incompatible with C++98">, - InGroup<CXX98Compat>, DefaultIgnore; -def ext_defaulted_function : ExtWarn< - "defaulted function definitions are a C++11 extension">, InGroup<CXX11>; -def warn_cxx98_compat_defaulted_function : Warning< - "defaulted function definitions are incompatible with C++98">, +def ext_defaulted_deleted_function : ExtWarn< + "%select{defaulted|deleted}0 function definitions are a C++11 extension">, + InGroup<CXX11>; +def warn_cxx98_compat_defaulted_deleted_function : Warning< + "%select{defaulted|deleted}0 function definitions are incompatible with C++98">, InGroup<CXX98Compat>, DefaultIgnore; // C++11 in-class member initialization @@ -784,7 +729,7 @@ def err_override_control_interface : Error< "'%0' keyword not permitted with interface types">; def ext_ms_sealed_keyword : ExtWarn< "'sealed' keyword is a Microsoft extension">, - InGroup<Microsoft>; + InGroup<MicrosoftSealed>; def err_access_specifier_interface : Error< "interface types cannot specify '%select{private|protected}0' access">; @@ -821,10 +766,6 @@ def warn_cxx98_compat_lambda : Warning< def err_lambda_missing_parens : Error< "lambda requires '()' before %select{'mutable'|return type|" "attribute specifier}0">; -def warn_init_capture_direct_list_init : Warning< - "direct list initialization of a lambda init-capture will change meaning in " - "a future version of Clang; insert an '=' to avoid a change in behavior">, - InGroup<FutureCompat>; // Availability attribute def err_expected_version : Error< @@ -945,7 +886,7 @@ def err_pragma_comment_malformed : Error< def err_pragma_comment_unknown_kind : Error<"unknown kind of pragma comment">; // PS4 recognizes only #pragma comment(lib) def warn_pragma_comment_ignored : Warning<"'#pragma comment %0' ignored">, - InGroup<Microsoft>; + InGroup<IgnoredPragmas>; // - #pragma detect_mismatch def err_pragma_detect_mismatch_malformed : Error< "pragma detect_mismatch is malformed; it requires two comma-separated " @@ -961,10 +902,6 @@ def err_pragma_optimize_invalid_argument : Error< def err_pragma_optimize_extra_argument : Error< "unexpected extra argument '%0' to '#pragma clang optimize'">; -// 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 EXTENSION pragma (OpenCL 1.1 [9.1]) def warn_pragma_expected_colon : Warning< "missing ':' after %0 - ignoring">, InGroup<IgnoredPragmas>; @@ -979,6 +916,8 @@ def warn_pragma_omp_ignored : Warning< def warn_omp_extra_tokens_at_eol : Warning< "extra tokens at the end of '#pragma omp %0' are ignored">, InGroup<ExtraTokens>; +def warn_pragma_expected_colon_r_paren : Warning< + "missing ':' or ')' after %0 - ignoring">, InGroup<IgnoredPragmas>; def err_omp_unknown_directive : Error< "expected an OpenMP directive">; def err_omp_unexpected_directive : Error< @@ -987,22 +926,26 @@ def err_omp_expected_punc : Error< "expected ',' or ')' in '%0' %select{clause|directive}1">; def err_omp_unexpected_clause : Error< "unexpected OpenMP clause '%0' in directive '#pragma omp %1'">; -def err_omp_more_one_clause : Error< - "directive '#pragma omp %0' cannot contain more than one '%1' clause">; def err_omp_immediate_directive : Error< - "'#pragma omp %0' cannot be an immediate substatement">; + "'#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_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">; // Pragma loop support. def err_pragma_loop_missing_argument : Error< "missing argument; expected %select{an integer value|" - "%select{'enable', 'assume_safety'|'full'}1 or 'disable'}0">; + "'enable', %select{'assume_safety'|'full'}1 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">; def err_pragma_invalid_keyword : Error< - "invalid argument; expected %select{'enable', 'assume_safety'|'full'}0 or 'disable'">; + "invalid argument; expected 'enable', %select{'assume_safety'|'full'}0 or 'disable'">; // Pragma unroll support. def warn_pragma_unroll_cuda_value_in_parens : Warning< @@ -1015,6 +958,7 @@ def err_module_expected_ident : Error< "expected a module name after module import">; def err_module_expected_semi : Error< "expected ';' after module name">; +def err_missing_before_module_end : Error<"expected %0 at end of module">; } let CategoryName = "Generics Issue" in { @@ -1029,4 +973,9 @@ def err_objc_type_args_after_protocols : Error< "protocol qualifiers must precede type arguments">; } +let CategoryName = "Coroutines Issue" in { +def err_for_co_await_not_range_for : Error< + "'co_await' modifier can only be applied to range-based for loop">; +} + } // end of Parser diagnostics diff --git a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticSemaKinds.td b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticSemaKinds.td index 82f5121..1f2791c 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -67,6 +67,9 @@ def warn_wrong_absolute_value_type : Warning< "when argument is of %select{integer|floating point|complex}2 type">, InGroup<AbsoluteValue>; def note_replace_abs_function : Note<"use function '%0' instead">; +def warn_pointer_abs : Warning< + "taking the absolute value of %select{pointer|function|array}0 type %1 is suspicious">, + InGroup<AbsoluteValue>; def warn_infinite_recursive_function : Warning< "all paths through this function will call itself">, @@ -188,6 +191,63 @@ def ext_flexible_array_init : Extension< "flexible array initialization is a GNU extension">, InGroup<GNUFlexibleArrayInitializer>; // Declarations. +def ext_duplicate_declspec : ExtWarn<"duplicate '%0' declaration specifier">, + InGroup<DuplicateDeclSpecifier>; +def warn_duplicate_declspec : Warning<"duplicate '%0' declaration specifier">, + InGroup<DuplicateDeclSpecifier>; +def ext_plain_complex : ExtWarn< + "plain '_Complex' requires a type specifier; assuming '_Complex double'">; +def ext_integer_complex : Extension< + "complex integer types are a GNU extension">, InGroup<GNUComplexInteger>; + +def err_invalid_sign_spec : Error<"'%0' cannot be signed or unsigned">; +def err_invalid_width_spec : Error< + "'%select{|short|long|long long}0 %1' is invalid">; +def err_invalid_complex_spec : Error<"'_Complex %0' is invalid">; +def err_friend_decl_spec : Error<"'%0' is invalid in friend declarations">; + +def ext_auto_type_specifier : ExtWarn< + "'auto' type specifier is a C++11 extension">, InGroup<CXX11>; +def warn_auto_storage_class : Warning< + "'auto' storage class specifier is redundant and incompatible with C++11">, + InGroup<CXX11Compat>, DefaultIgnore; + +def warn_deprecated_register : Warning< + "'register' storage class specifier is deprecated " + "and incompatible with C++1z">, InGroup<DeprecatedRegister>; +def ext_register_storage_class : ExtWarn< + "ISO C++1z does not allow 'register' storage class specifier">, + DefaultError, InGroup<Register>; + +def err_invalid_decl_spec_combination : Error< + "cannot combine with previous '%0' declaration specifier">; +def err_invalid_vector_decl_spec_combination : Error< + "cannot combine with previous '%0' declaration specifier. " + "'__vector' must be first">; +def err_invalid_pixel_decl_spec_combination : Error< + "'__pixel' must be preceded by '__vector'. " + "'%0' declaration specifier not allowed here">; +def err_invalid_vector_bool_decl_spec : Error< + "cannot use '%0' with '__vector bool'">; +def err_invalid_vector_long_decl_spec : Error< + "cannot use 'long' with '__vector'">; +def err_invalid_vector_float_decl_spec : Error< + "cannot use 'float' with '__vector'">; +def err_invalid_vector_double_decl_spec : Error < + "use of 'double' with '__vector' requires VSX support to be enabled " + "(available on POWER7 or later)">; +def err_invalid_vector_long_long_decl_spec : Error < + "use of 'long long' with '__vector bool' requires VSX support (available on " + "POWER7 or later) or extended Altivec support (available on POWER8 or later) " + "to be enabled">; +def err_invalid_vector_long_double_decl_spec : Error< + "cannot use 'long double' with '__vector'">; +def warn_vector_long_decl_spec_combination : Warning< + "Use of 'long' with '__vector' is deprecated">, InGroup<Deprecated>; + +def err_use_of_tag_name_without_tag : Error< + "must use '%1' tag to refer to type %0%select{| in this scope}2">; + def err_redeclaration_different_type : Error< "redeclaration of %0 with a different type%diff{: $ vs $|}1,2">; def err_bad_variable_name : Error< @@ -195,6 +255,10 @@ 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 warn_mips_interrupt_attribute : Warning< + "MIPS 'interrupt' attribute only applies to functions that have " + "%select{no parameters|a 'void' return type}0">, + InGroup<IgnoredAttributes>; def warn_unused_parameter : Warning<"unused parameter %0">, InGroup<UnusedParameter>, DefaultIgnore; def warn_unused_variable : Warning<"unused variable %0">, @@ -416,7 +480,8 @@ def note_unreachable_silence : Note< /// Built-in functions. def ext_implicit_lib_function_decl : ExtWarn< - "implicitly declaring library function '%0' with type %1">; + "implicitly declaring library function '%0' with type %1">, + InGroup<ImplicitFunctionDeclare>; def note_include_header_or_declare : Note< "include the header <%0> or explicitly provide a declaration for '%1'">; def note_previous_builtin_declaration : Note<"%0 is a builtin with type %1">; @@ -429,6 +494,11 @@ def warn_redecl_library_builtin : Warning< def err_builtin_definition : Error<"definition of builtin function %0">; def err_arm_invalid_specialreg : Error<"invalid special register for builtin">; def err_invalid_cpu_supports : Error<"invalid cpu feature string for builtin">; +def err_builtin_needs_feature : Error<"%0 needs target feature %1">; +def err_function_needs_feature + : Error<"always_inline function %1 requires target feature '%2', but would " + "be inlined into function %0 that is compiled without support for " + "'%2'">; def warn_builtin_unknown : Warning<"use of unknown builtin %0">, InGroup<ImplicitFunctionDeclare>, DefaultError; def warn_dyn_class_memaccess : Warning< @@ -510,6 +580,10 @@ def warn_main_one_arg : Warning<"only one parameter on 'main' declaration">, def err_main_arg_wrong : Error<"%select{first|second|third|fourth}0 " "parameter of 'main' (%select{argument count|argument array|environment|" "platform-specific data}0) must be of type %1">; +def err_main_global_variable : + Error<"main cannot be declared as global variable">; +def warn_main_redefined : Warning<"variable named 'main' with external linkage " + "has undefined behavior">, InGroup<Main>; def ext_main_used : Extension< "ISO C++ does not allow 'main' to be used by a program">, InGroup<Main>; @@ -548,14 +622,14 @@ def err_pragma_options_align_mac68k_target_unsupported : Error< def warn_pragma_pack_invalid_alignment : Warning< "expected #pragma pack parameter to be '1', '2', '4', '8', or '16'">, InGroup<IgnoredPragmas>; -// Follow the MSVC implementation. +// Follow the Microsoft implementation. def warn_pragma_pack_show : Warning<"value of #pragma pack(show) == %0">; def warn_pragma_pack_pop_identifer_and_alignment : Warning< "specifying both a name and alignment to 'pop' is undefined">; def warn_pragma_pop_failed : Warning<"#pragma %0(pop, ...) failed: %1">, InGroup<IgnoredPragmas>; def warn_cxx_ms_struct : - Warning<"ms_struct may not produce MSVC-compatible layouts for classes " + Warning<"ms_struct may not produce Microsoft-compatible layouts for classes " "with base classes or virtual functions">, DefaultError, InGroup<IncompatibleMSStruct>; def err_section_conflict : Error<"%0 causes a section type conflict with %1">; @@ -856,6 +930,9 @@ def warn_missing_explicit_synthesis : Warning < def warn_property_getter_owning_mismatch : Warning< "property declared as returning non-retained objects" "; getter returning retained objects">; +def warn_property_redecl_getter_mismatch : Warning< + "getter name mismatch between property redeclaration (%1) and its original " + "declaration (%0)">, InGroup<PropertyAttr>; def error_property_setter_ambiguous_use : Error< "synthesized properties %0 and %1 both claim setter %2 -" " use of this setter will cause unexpected behavior">; @@ -878,7 +955,8 @@ def err_property_type : Error<"property cannot have array or function type %0">; def error_missing_property_context : Error< "missing context for property implementation declaration">; def error_bad_property_decl : Error< - "property implementation must have its declaration in interface %0">; + "property implementation must have its declaration in interface %0 or one of " + "its extensions">; def error_category_property : Error< "property declared in category %0 cannot be implemented in " "class implementation">; @@ -901,8 +979,6 @@ def error_bad_property_context : Error< def error_missing_property_ivar_decl : Error< "synthesized property %0 must either be named the same as a compatible" " instance variable or must explicitly name an instance variable">; -def error_synthesize_weak_non_arc_or_gc : Error< - "@synthesize of 'weak' property is only allowed in ARC or GC mode">; def err_arc_perform_selector_retains : Error< "performSelector names a selector which retains the object">; def warn_arc_perform_selector_leaks : Warning< @@ -1058,7 +1134,7 @@ def warn_template_qualified_friend_ignored : Warning< def ext_friend_tag_redecl_outside_namespace : ExtWarn< "unqualified friend declaration referring to type outside of the nearest " "enclosing namespace is a Microsoft extension; add a nested name specifier">, - InGroup<Microsoft>; + InGroup<MicrosoftUnqualifiedFriend>; def err_pure_friend : Error<"friend declaration cannot have a pure-specifier">; def err_invalid_member_in_interface : Error< @@ -1096,10 +1172,15 @@ def err_type_defined_in_param_type : Error< "%0 cannot be defined in a parameter type">; def err_type_defined_in_alias_template : Error< "%0 cannot be defined in a type alias template">; +def err_type_defined_in_condition : Error< + "%0 cannot be defined in a condition">; def note_pure_virtual_function : Note< "unimplemented pure virtual method %0 in %1">; +def note_pure_qualified_call_kext : Note< + "qualified call to %0::%1 is treated as a virtual call to %1 due to -fapple-kext">; + def err_deleted_decl_not_first : Error< "deleted definition must be first declaration">; @@ -1134,21 +1215,25 @@ def err_rref_in_exception_spec : Error< "rvalue reference type %0 is not allowed in exception specification">; def err_mismatched_exception_spec : Error< "exception specification in declaration does not match previous declaration">; -def ext_mismatched_exception_spec : ExtWarn< - "exception specification in declaration does not match previous declaration">, - InGroup<Microsoft>; +def ext_mismatched_exception_spec : ExtWarn<err_mismatched_exception_spec.Text>, + InGroup<MicrosoftExceptionSpec>; def err_override_exception_spec : Error< "exception specification of overriding function is more lax than " "base version">; -def ext_override_exception_spec : ExtWarn< - "exception specification of overriding function is more lax than " - "base version">, InGroup<Microsoft>; +def ext_override_exception_spec : ExtWarn<err_override_exception_spec.Text>, + InGroup<MicrosoftExceptionSpec>; def err_incompatible_exception_specs : Error< "target exception specification is not superset of source">; def err_deep_exception_specs_differ : Error< "exception specifications of %select{return|argument}0 types differ">; -def warn_missing_exception_specification : Warning< +def err_missing_exception_specification : Error< "%0 is missing exception specification '%1'">; +def ext_missing_exception_specification : ExtWarn< + err_missing_exception_specification.Text>, + InGroup<DiagGroup<"missing-exception-spec">>; +def ext_ms_missing_exception_specification : ExtWarn< + err_missing_exception_specification.Text>, + InGroup<MicrosoftExceptionSpec>; def err_noexcept_needs_constant_expression : Error< "argument to noexcept specifier must be a constant expression">; def err_exception_spec_not_parsed : Error< @@ -1162,7 +1247,7 @@ def err_access : Error< def ext_ms_using_declaration_inaccessible : ExtWarn< "using declaration referring to inaccessible member '%0' (which refers " "to accessible member '%1') is a Microsoft compatibility extension">, - AccessControl, InGroup<Microsoft>; + AccessControl, InGroup<MicrosoftUsingDecl>; def err_access_ctor : Error< "calling a %select{private|protected}0 constructor of class %2">, AccessControl; @@ -1268,7 +1353,7 @@ def err_mutable_function : Error<"'mutable' cannot be applied to functions">; def err_mutable_reference : Error<"'mutable' cannot be applied to references">; def ext_mutable_reference : ExtWarn< "'mutable' on a reference type is a Microsoft extension">, - InGroup<Microsoft>; + InGroup<MicrosoftMutableReference>; def err_mutable_const : Error<"'mutable' and 'const' cannot be mixed">; def err_mutable_nonmember : Error< "'mutable' can only be applied to member variables">; @@ -1304,7 +1389,7 @@ def err_non_virtual_pure : Error< "%0 is not virtual and cannot be declared pure">; def ext_pure_function_definition : ExtWarn< "function definition with pure-specifier is a Microsoft extension">, - InGroup<Microsoft>; + InGroup<MicrosoftPureDefinition>; def err_implicit_object_parameter_init : Error< "cannot initialize object parameter of type %0 with an expression " "of type %1">; @@ -1312,8 +1397,9 @@ def err_qualified_member_of_unrelated : Error< "%q0 is not a member of class %1">; def warn_call_to_pure_virtual_member_function_from_ctor_dtor : Warning< - "call to pure virtual member function %0; overrides of %0 in subclasses are " - "not available in the %select{constructor|destructor}1 of %2">; + "call to pure virtual member function %0 has undefined behavior; " + "overrides of %0 in subclasses are not available in the " + "%select{constructor|destructor}1 of %2">; def note_member_declared_at : Note<"member is declared here">; def note_ivar_decl : Note<"instance variable is declared here">; @@ -1382,7 +1468,7 @@ def warn_cxx98_compat_static_data_member_in_union : Warning< InGroup<CXX98Compat>, DefaultIgnore; def ext_union_member_of_reference_type : ExtWarn< "union member %0 has reference type %1, which is a Microsoft extension">, - InGroup<Microsoft>; + InGroup<MicrosoftUnionMemberReference>; def err_union_member_of_reference_type : Error< "union member %0 has reference type %1">; def ext_anonymous_struct_union_qualified : Extension< @@ -1437,7 +1523,8 @@ def warn_no_constructor_for_refconst : Warning< def note_refconst_member_not_initialized : Note< "%select{const|reference}0 member %1 will never be initialized">; def ext_ms_explicit_constructor_call : ExtWarn< - "explicit constructor calls are a Microsoft extension">, InGroup<Microsoft>; + "explicit constructor calls are a Microsoft extension">, + InGroup<MicrosoftExplicitConstructorCall>; // C++ destructors def err_destructor_not_member : Error< @@ -1649,18 +1736,22 @@ def warn_cxx98_compat_auto_type_specifier : Warning< "'auto' type specifier is incompatible with C++98">, InGroup<CXX98Compat>, DefaultIgnore; def err_auto_variable_cannot_appear_in_own_initializer : Error< - "variable %0 declared with 'auto' type cannot appear in its own initializer">; + "variable %0 declared with %select{'auto'|'decltype(auto)'|'__auto_type'}1 " + "type cannot appear in its own initializer">; def err_illegal_decl_array_of_auto : Error< "'%0' declared as array of %1">; def err_new_array_of_auto : Error< "cannot allocate array of 'auto'">; def err_auto_not_allowed : Error< - "%select{'auto'|'decltype(auto)'}0 not allowed %select{in function prototype" - "|in non-static struct member" - "|in non-static union member|in non-static class member|in interface member" + "%select{'auto'|'decltype(auto)'|'__auto_type'}0 not allowed " + "%select{in function prototype" + "|in non-static struct member|in struct member" + "|in non-static union member|in union member" + "|in non-static class member|in interface member" "|in exception declaration|in template parameter|in block literal" "|in template argument|in typedef|in type alias|in function return type" - "|in conversion function type|here|in lambda parameter}1">; + "|in conversion function type|here|in lambda parameter" + "|in type allocated by 'new'|in K&R-style function parameter}1">; def err_auto_not_allowed_var_inst : Error< "'auto' variable template instantiation is not allowed">; def err_auto_var_requires_init : Error< @@ -1674,12 +1765,8 @@ def err_auto_var_init_no_expression : Error< def err_auto_var_init_multiple_expressions : Error< "initializer for variable %0 with type %1 contains multiple expressions">; def err_auto_var_init_paren_braces : Error< - "cannot deduce type for variable %0 with type %1 from " - "parenthesized initializer list">; -def warn_auto_var_direct_list_init : Warning< - "direct list initialization of a variable with a deduced type will change " - "meaning in a future version of Clang; insert an '=' to avoid a change in " - "behavior">, InGroup<FutureCompat>; + "cannot deduce type for variable %1 with type %2 from " + "%select{parenthesized|nested}0 initializer list">; def err_auto_new_ctor_multiple_expressions : Error< "new expression for type %0 contains multiple constructor arguments">; def err_auto_missing_trailing_return : Error< @@ -1698,8 +1785,8 @@ def err_auto_var_deduction_failure_from_init_list : Error< def err_auto_new_deduction_failure : Error< "new expression for type %0 has incompatible constructor argument of type %1">; def err_auto_different_deductions : Error< - "'%select{auto|decltype(auto)}0' deduced as %1 in declaration of %2 and " - "deduced as %3 in declaration of %4">; + "'%select{auto|decltype(auto)|__auto_type}0' deduced as %1 in declaration " + "of %2 and deduced as %3 in declaration of %4">; def err_implied_std_initializer_list_not_found : Error< "cannot deduce type of initializer list because std::initializer_list was " "not found; include <initializer_list>">; @@ -1709,6 +1796,10 @@ def warn_dangling_std_initializer_list : Warning< "array backing the initializer list will be destroyed at the end of " "%select{the full-expression|the constructor}0">, InGroup<DiagGroup<"dangling-initializer-list">>; +def err_auto_init_list_from_c : Error< + "cannot use __auto_type with initializer list in C">; +def err_auto_bitfield : Error< + "cannot pass bit-field as __auto_type initializer in C">; // C++1y decltype(auto) type def err_decltype_auto_cannot_be_combined : Error< @@ -1768,7 +1859,7 @@ def err_enumerator_too_large : Error< "enumerator value is not representable in the underlying type %0">; def ext_enumerator_too_large : ExtWarn< "enumerator value is not representable in the underlying type %0">, - InGroup<Microsoft>; + InGroup<MicrosoftEnumValue>; def err_enumerator_wrapped : Error< "enumerator value %0 is not representable in the underlying type %1">; def err_enum_redeclare_type_mismatch : Error< @@ -1961,11 +2052,34 @@ def warn_private_extern : Warning< def note_private_extern : Note< "use __attribute__((visibility(\"hidden\"))) attribute instead">; +// C++ Concepts TS +def err_concept_wrong_decl_kind : Error< + "'concept' can only appear on the definition of a function template or variable template">; +def err_concept_decls_may_only_appear_in_namespace_scope : Error< + "concept declarations may only appear in namespace scope">; +def err_function_concept_not_defined : Error< + "function concept declaration must be a definition">; +def err_var_concept_not_initialized : Error< + "variable concept declaration must be initialized">; +def err_function_concept_exception_spec : Error< + "function concept cannot have exception specification">; +def err_concept_decl_invalid_specifiers : Error< + "%select{variable|function}0 concept cannot be declared " + "'%select{thread_local|inline|friend|constexpr}1'">; +def err_function_concept_with_params : Error< + "function concept cannot have any parameters">; + // C++11 char16_t/char32_t def warn_cxx98_compat_unicode_type : Warning< "'%0' type specifier is incompatible with C++98">, InGroup<CXX98Compat>, DefaultIgnore; - + +// __make_integer_seq +def err_integer_sequence_negative_length : Error< + "integer sequences must have non-negative sequence length">; +def err_integer_sequence_integral_element_type : Error< + "integer sequences must have integral element type">; + // Objective-C++ def err_objc_decls_may_only_appear_in_global_scope : Error< "Objective-C declarations may only appear in global scope">; @@ -2016,8 +2130,7 @@ def err_attribute_argument_type : Error< "%0 attribute requires %select{int or bool|an integer " "constant|a string|an identifier}1">; def err_attribute_argument_outof_range : Error< - "init_priority attribute requires integer constant between " - "101 and 65535 inclusive">; + "%0 attribute requires integer constant between %1 and %2 inclusive">; def err_init_priority_object_attr : Error< "can only use 'init_priority' attribute on file-scope definitions " "of objects of class type">; @@ -2025,10 +2138,12 @@ def err_attribute_argument_vec_type_hint : Error< "invalid attribute argument %0 - expecting a vector or vectorizable scalar type">; def err_attribute_argument_out_of_bounds : Error< "%0 attribute parameter %1 is out of bounds">; +def err_attribute_only_once_per_parameter : Error< + "%0 attribute can only be applied once per parameter">; def err_attribute_uuid_malformed_guid : Error< "uuid attribute contains a malformed GUID">; def warn_attribute_pointers_only : Warning< - "%0 attribute only applies to pointer arguments">, + "%0 attribute only applies to%select{| constant}1 pointer arguments">, InGroup<IgnoredAttributes>; def err_attribute_pointers_only : Error<warn_attribute_pointers_only.Text>; def warn_attribute_return_pointers_only : Warning< @@ -2066,9 +2181,9 @@ def err_attribute_invalid_size : Error< def err_attribute_zero_size : Error<"zero vector size">; def err_attribute_size_too_large : Error<"vector size too large">; def err_typecheck_vector_not_convertable : Error< - "can't convert between vector values of different size (%0 and %1)">; + "cannot convert between vector values of different size (%0 and %1)">; def err_typecheck_vector_not_convertable_non_scalar : Error< - "can't convert between vector and non-scalar values (%0 and %1)">; + "cannot convert between vector and non-scalar values (%0 and %1)">; def err_typecheck_vector_lengths_not_equal : Error< "vector operands do not have the same number of elements (%0 and %1)">; def err_ext_vector_component_exceeds_length : Error< @@ -2091,25 +2206,18 @@ def err_field_with_address_space : Error< "field may not be qualified with an address space">; def err_attr_objc_ownership_redundant : Error< "the type %0 is already explicitly ownership-qualified">; -def err_undeclared_nsnumber : Error< - "NSNumber must be available to use Objective-C literals">; -def err_undeclared_nsvalue : Error< - "NSValue must be available to use Objective-C boxed expressions">; def err_invalid_nsnumber_type : Error< "%0 is not a valid literal type for NSNumber">; -def err_undeclared_nsstring : Error< - "cannot box a string value because NSString has not been declared">; def err_objc_illegal_boxed_expression_type : Error< "illegal type %0 used in a boxed expression">; def err_objc_non_trivially_copyable_boxed_expression_type : Error< "non-trivially copyable type %0 cannot be used in a boxed expression">; def err_objc_incomplete_boxed_expression_type : Error< "incomplete type %0 used in a boxed expression">; -def err_undeclared_nsarray : Error< - "NSArray must be available to use Objective-C array literals">; -def err_undeclared_nsdictionary : Error< - "NSDictionary must be available to use Objective-C dictionary " - "literals">; +def err_undeclared_objc_literal_class : Error< + "definition of class %0 must be available to use Objective-C " + "%select{array literals|dictionary literals|numeric literals|boxed expressions|" + "string literals}1">; def err_undeclared_boxing_method : Error< "declaration of %0 is missing in %1 class">; def err_objc_literal_method_sig : Error< @@ -2258,6 +2366,8 @@ def err_attribute_dll_not_extern : Error< "%q0 must have external linkage when declared %q1">; def err_attribute_dll_thread_local : Error< "%q0 cannot be thread local when declared %q1">; +def err_attribute_dll_lambda : Error< + "lambda cannot be declared %0">; def warn_attribute_invalid_on_definition : Warning< "'%0' attribute cannot be specified on a definition">, InGroup<IgnoredAttributes>; @@ -2323,7 +2433,7 @@ def warn_attribute_wrong_decl_type : Warning< "Objective-C instance methods|init methods of interface or class extension declarations|" "variables, functions and classes|Objective-C protocols|" "functions and global variables|structs, unions, and typedefs|structs and typedefs|" - "interface or protocol declarations|kernel functions}1">, + "interface or protocol declarations|kernel functions|non-K&R-style functions}1">, InGroup<IgnoredAttributes>; def err_attribute_wrong_decl_type : Error<warn_attribute_wrong_decl_type.Text>; def warn_type_attribute_wrong_type : Warning< @@ -2359,6 +2469,9 @@ def err_cconv_varargs : Error< def warn_cconv_varargs : Warning< "%0 calling convention ignored on variadic function">, InGroup<IgnoredAttributes>; +def warn_cconv_structors : Warning< + "%0 calling convention ignored on constructor/destructor">, + InGroup<IgnoredAttributes>; def err_regparm_mismatch : Error<"function declared with regparm(%0) " "attribute was previously declared " "%plural{0:without the regparm|:with the regparm(%1)}1 attribute">; @@ -2375,6 +2488,8 @@ def warn_attribute_not_on_decl : Warning< "%0 attribute ignored when parsing type">, InGroup<IgnoredAttributes>; def err_base_specifier_attribute : Error< "%0 attribute cannot be applied to a base specifier">; +def err_invalid_attribute_on_virtual_function : Error< + "%0 attribute cannot be applied to virtual functions">; // Availability attribute def warn_availability_unknown_platform : Warning< @@ -2386,15 +2501,19 @@ def warn_availability_version_ordering : Warning< def warn_mismatched_availability: Warning< "availability does not match previous declaration">, InGroup<Availability>; def warn_mismatched_availability_override : Warning< - "overriding method %select{introduced after|" - "deprecated before|obsoleted before}0 overridden method on %1 (%2 vs. %3)">, - InGroup<Availability>; + "%select{|overriding }4method %select{introduced after|" + "deprecated before|obsoleted before}0 " + "%select{the protocol method it implements|overridden method}4 " + "on %1 (%2 vs. %3)">, InGroup<Availability>; def warn_mismatched_availability_override_unavail : Warning< - "overriding method cannot be unavailable on %0 when its overridden method is " + "%select{|overriding }1method cannot be unavailable on %0 when " + "%select{the protocol method it implements|its overridden method}1 is " "available">, InGroup<Availability>; def note_overridden_method : Note< "overridden method is here">; +def note_protocol_method : Note< + "protocol method is here">; // Thread Safety Attributes def warn_invalid_capability_name : Warning< @@ -2559,6 +2678,9 @@ def warn_impcast_complex_scalar : Warning< def warn_impcast_float_precision : Warning< "implicit conversion loses floating-point precision: %0 to %1">, InGroup<Conversion>, DefaultIgnore; +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; @@ -2601,13 +2723,16 @@ def warn_impcast_null_pointer_to_integer : Warning< def warn_impcast_floating_point_to_bool : Warning< "implicit conversion turns floating-point number into bool: %0 to %1">, InGroup<ImplicitConversionFloatingPointToBool>; +def ext_ms_impcast_fn_obj : ExtWarn< + "implicit conversion between pointer-to-function and pointer-to-object is a " + "Microsoft extension">, InGroup<MicrosoftCast>; def warn_impcast_pointer_to_bool : Warning< "address of%select{| function| array}0 '%1' will always evaluate to " "'true'">, InGroup<PointerBoolConversion>; def warn_cast_nonnull_to_bool : Warning< - "nonnull parameter '%0' will evaluate to " + "nonnull %select{function call|parameter}0 '%1' will evaluate to " "'true' on first encounter">, InGroup<PointerBoolConversion>; def warn_this_bool_conversion : Warning< @@ -2622,9 +2747,10 @@ def warn_null_pointer_compare : Warning< "comparison of %select{address of|function|array}0 '%1' %select{not |}2" "equal to a null pointer is always %select{true|false}2">, InGroup<TautologicalPointerCompare>; -def warn_nonnull_parameter_compare : Warning< - "comparison of nonnull parameter '%0' %select{not |}1" - "equal to a null pointer is %select{true|false}1 on first encounter">, +def warn_nonnull_expr_compare : Warning< + "comparison of nonnull %select{function call|parameter}0 '%1' " + "%select{not |}2equal to a null pointer is '%select{true|false}2' on first " + "encounter">, InGroup<TautologicalPointerCompare>; def warn_this_null_compare : Warning< "'this' pointer cannot be null in well-defined C++ code; comparison may be " @@ -2664,9 +2790,10 @@ def warn_int_to_void_pointer_cast : Warning< "cast to %1 from smaller integer type %0">, InGroup<IntToVoidPointerCast>; -def warn_attribute_ignored_for_field_of_type : Warning< - "%0 attribute ignored for field of type %1">, - InGroup<IgnoredAttributes>; +def warn_attribute_packed_for_bitfield : Warning< + "'packed' attribute was ignored on bit-fields with single-byte alignment " + "in older versions of GCC and Clang">, + InGroup<DiagGroup<"attribute-packed-for-bitfield">>; def warn_transparent_union_attribute_field_size_align : Warning< "%select{alignment|size}0 of field %1 (%2 bits) does not match the " "%select{alignment|size}0 of the first field in transparent union; " @@ -2710,6 +2837,10 @@ def err_mode_not_primitive : Error< "mode attribute only supported for integer and floating-point types">; def err_mode_wrong_type : Error< "type of machine mode does not match type of base type">; +def warn_vector_mode_deprecated : Warning< + "specifying vector types with the 'mode' attribute is deprecated; " + "use the 'vector_size' attribute instead">, + 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< @@ -2852,7 +2983,8 @@ def err_param_default_argument : Error< def err_param_default_argument_redefinition : Error< "redefinition of default argument">; def ext_param_default_argument_redefinition : ExtWarn< - "redefinition of default argument">, InGroup<Microsoft>; + err_param_default_argument_redefinition.Text>, + InGroup<MicrosoftDefaultArgRedefinition>; def err_param_default_argument_missing : Error< "missing default argument on parameter">; def err_param_default_argument_missing_name : Error< @@ -2877,7 +3009,7 @@ def err_param_default_argument_on_parameter_pack : Error< "parameter pack cannot have a default argument">; def err_uninitialized_member_for_assign : Error< "cannot define the implicit copy assignment operator for %0, because " - "non-static %select{reference|const}1 member %2 can't use copy " + "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 " @@ -2961,14 +3093,22 @@ def note_ovl_candidate_instantiation_depth : Note< "candidate template ignored: substitution exceeded maximum template " "instantiation depth">; def note_ovl_candidate_underqualified : Note< - "candidate template ignored: can't deduce a type for %0 that would " + "candidate template ignored: cannot deduce a type for %0 that would " "make %2 equal %1">; def note_ovl_candidate_substitution_failure : Note< "candidate template ignored: substitution failure%0%1">; def note_ovl_candidate_disabled_by_enable_if : Note< "candidate template ignored: disabled by %0%1">; +def note_ovl_candidate_has_pass_object_size_params: Note< + "candidate address cannot be taken because parameter %0 has " + "pass_object_size attribute">; def note_ovl_candidate_disabled_by_enable_if_attr : Note< "candidate disabled: %0">; +def err_addrof_function_disabled_by_enable_if_attr : Error< + "cannot take address of function %0 becuase it has one or more " + "non-tautological enable_if conditions">; +def note_addrof_ovl_candidate_disabled_by_enable_if_attr : Note< + "candidate function made ineligible by enable_if">; def note_ovl_candidate_failed_overload_resolution : Note< "candidate template ignored: couldn't resolve reference to overloaded " "function %0">; @@ -2979,7 +3119,7 @@ def note_ovl_candidate_non_deduced_mismatch : Note< // can handle that case properly. def note_ovl_candidate_non_deduced_mismatch_qualified : Note< "candidate template ignored: could not match %q0 against %q1">; - + // Note that we don't treat templates differently for this diagnostic. def note_ovl_candidate_arity : Note<"candidate " "%select{function|function|constructor|function|function|constructor|" @@ -3251,7 +3391,7 @@ def err_addr_ovl_ambiguous : Error< def err_addr_ovl_not_func_ptrref : Error< "address of overloaded function %0 cannot be converted to type %1">; def err_addr_ovl_no_qualifier : Error< - "can't form member pointer of type %0 without '&' and class name">; + "cannot form member pointer of type %0 without '&' and class name">; // C++11 Literal Operators def err_ovl_no_viable_literal_operator : Error< @@ -3344,11 +3484,12 @@ def note_template_decl_here : Note<"template is declared here">; def err_template_arg_must_be_type : Error< "template argument for template type parameter must be a type">; def err_template_arg_must_be_type_suggest : Error< - "template argument for template type parameter must be a type; did you forget 'typename'?">; + "template argument for template type parameter must be a type; " + "did you forget 'typename'?">; def ext_ms_template_type_arg_missing_typename : ExtWarn< "template argument for template type parameter must be a type; " "omitted 'typename' is a Microsoft extension">, - InGroup<Microsoft>; + InGroup<MicrosoftTemplate>; def err_template_arg_must_be_expr : Error< "template argument for non-type template parameter must be an expression">; def err_template_arg_nontype_ambig : Error< @@ -3468,10 +3609,10 @@ def err_pointer_to_member_oper_value_classify: Error< "%select{rvalue|lvalue}1">; def ext_ms_deref_template_argument: ExtWarn< "non-type template argument containing a dereference operation is a " - "Microsoft extension">, InGroup<Microsoft>; + "Microsoft extension">, InGroup<MicrosoftTemplate>; def ext_ms_delayed_template_argument: ExtWarn< "using the undeclared type %0 as a default template argument is a " - "Microsoft extension">, InGroup<Microsoft>; + "Microsoft extension">, InGroup<MicrosoftTemplate>; // C++ template specialization def err_template_spec_unknown_kind : Error< @@ -3519,7 +3660,7 @@ def ext_ms_template_spec_redecl_out_of_scope: ExtWarn< "variable template partial|function template|member " "function|static data member|member class|member enumeration}0 " "specialization of %1 outside namespace enclosing %2 " - "is a Microsoft extension">, InGroup<Microsoft>; + "is a Microsoft extension">, InGroup<MicrosoftTemplate>; def err_template_spec_redecl_global_scope : Error< "%select{class template|class template partial|variable template|" "variable template partial|function template|member " @@ -3544,7 +3685,7 @@ def err_function_specialization_in_class : Error< "cannot specialize a function %0 within class scope">; def ext_function_specialization_in_class : ExtWarn< "explicit specialization of %0 within class scope is a Microsoft extension">, - InGroup<Microsoft>; + InGroup<MicrosoftTemplate>; def ext_explicit_specialization_storage_class : ExtWarn< "explicit specialization cannot have a storage class">; def err_explicit_specialization_inconsistent_storage_class : Error< @@ -3705,7 +3846,7 @@ def err_explicit_instantiation_duplicate : Error< "duplicate explicit instantiation of %0">; def ext_explicit_instantiation_duplicate : ExtWarn< "duplicate explicit instantiation of %0 ignored as a Microsoft extension">, - InGroup<Microsoft>; + InGroup<MicrosoftTemplate>; def note_previous_explicit_instantiation : Note< "previous explicit instantiation is here">; def ext_explicit_instantiation_after_specialization : Extension< @@ -3790,10 +3931,11 @@ def err_invalid_var_template_spec_type : Error<"type %2 " "partial specialization|redeclaration}0 of %1 does not match" " expected type %3">; def err_mismatched_exception_spec_explicit_instantiation : Error< - "exception specification in explicit instantiation does not match instantiated one">; + "exception specification in explicit instantiation does not match " + "instantiated one">; def ext_mismatched_exception_spec_explicit_instantiation : ExtWarn< - "exception specification in explicit instantiation does not match instantiated one">, - InGroup<Microsoft>; + err_mismatched_exception_spec_explicit_instantiation.Text>, + InGroup<MicrosoftExceptionSpec>; // C++ typename-specifiers def err_typename_nested_not_found : Error<"no type named %0 in %1">; @@ -3911,10 +4053,10 @@ def err_undeclared_var_use : Error<"use of undeclared identifier %0">; def ext_undeclared_unqual_id_with_dependent_base : ExtWarn< "use of undeclared identifier %0; " "unqualified lookup into dependent bases of class template %1 is a Microsoft extension">, - InGroup<Microsoft>; + InGroup<MicrosoftTemplate>; def ext_found_via_dependent_bases_lookup : ExtWarn<"use of identifier %0 " "found via unqualified lookup into dependent bases of class templates is a " - "Microsoft extension">, InGroup<Microsoft>; + "Microsoft extension">, InGroup<MicrosoftTemplate>; def note_dependent_var_use : Note<"must qualify identifier to find this " "declaration in dependent base class">; def err_not_found_by_two_phase_lookup : Error<"call to function %0 that is neither " @@ -4034,6 +4176,12 @@ def warn_undefined_inline : Warning<"inline function %q0 is not defined">, InGroup<DiagGroup<"undefined-inline">>; def note_used_here : Note<"used here">; +def err_internal_linkage_redeclaration : Error< + "'internal_linkage' attribute does not appear on the first declaration of %0">; +def warn_internal_linkage_local_storage : Warning< + "'internal_linkage' attribute on a non-static local variable is ignored">, + InGroup<IgnoredAttributes>; + def ext_internal_in_extern_inline : ExtWarn< "static %select{function|variable}0 %1 is used in an inline function with " "external linkage">, InGroup<StaticInInline>; @@ -4071,7 +4219,8 @@ def note_extern_c_global_conflict : Note< def warn_weak_import : Warning < "an already-declared variable is made a weak_import declaration %0">; def ext_static_non_static : Extension< - "redeclaring non-static %0 as static is a Microsoft extension">, InGroup<Microsoft>; + "redeclaring non-static %0 as static is a Microsoft extension">, + InGroup<MicrosoftRedeclareStatic>; def err_non_static_static : Error< "non-static declaration of %0 follows static declaration">; def err_extern_non_extern : Error< @@ -4110,6 +4259,11 @@ def err_dependent_tag_decl : Error< def err_tag_definition_of_typedef : Error< "definition of type %0 conflicts with %select{typedef|type alias}1 of the same name">; def err_conflicting_types : Error<"conflicting types for %0">; +def err_different_pass_object_size_params : Error< + "conflicting pass_object_size attributes on parameters">; +def err_late_asm_label_name : Error< + "cannot apply asm label to %select{variable|function}0 after its first use">; +def err_different_asm_label : Error<"conflicting asm label">; def err_nested_redefinition : Error<"nested redefinition of %0">; def err_use_with_wrong_tag : Error< "use of %0 with tag type that does not match previous declaration">; @@ -4129,9 +4283,11 @@ def ext_forward_ref_enum : Extension< def err_forward_ref_enum : Error< "ISO C++ forbids forward references to 'enum' types">; def ext_ms_forward_ref_enum : Extension< - "forward references to 'enum' types are a Microsoft extension">, InGroup<Microsoft>; + "forward references to 'enum' types are a Microsoft extension">, + InGroup<MicrosoftEnumForwardReference>; def ext_forward_ref_enum_def : Extension< - "redeclaration of already-defined enum %0 is a GNU extension">, InGroup<GNURedeclaredEnum>; + "redeclaration of already-defined enum %0 is a GNU extension">, + InGroup<GNURedeclaredEnum>; def err_redefinition_of_enumerator : Error<"redefinition of enumerator %0">; def err_duplicate_member : Error<"duplicate member %0">; @@ -4172,15 +4328,15 @@ def warn_array_new_too_large : Warning<"array is too large (%0 elements)">, // -Wpadded, -Wpacked def warn_padded_struct_field : Warning< "padding %select{struct|interface|class}0 %1 with %2 " - "%select{byte|bit}3%select{|s}4 to align %5">, + "%select{byte|bit}3%s2 to align %4">, InGroup<Padded>, DefaultIgnore; def warn_padded_struct_anon_field : Warning< "padding %select{struct|interface|class}0 %1 with %2 " - "%select{byte|bit}3%select{|s}4 to align anonymous bit-field">, + "%select{byte|bit}3%s2 to align anonymous bit-field">, InGroup<Padded>, DefaultIgnore; def warn_padded_struct_size : Warning< - "padding size of %0 with %1 %select{byte|bit}2%select{|s}3 " - "to alignment boundary">, InGroup<Padded>, DefaultIgnore; + "padding size of %0 with %1 %select{byte|bit}2%s1 to alignment boundary">, + InGroup<Padded>, DefaultIgnore; def warn_unnecessary_packed : Warning< "packed attribute is unnecessary for %0">, InGroup<Packed>, DefaultIgnore; @@ -4292,20 +4448,22 @@ def err_bitfield_has_negative_width : Error< def err_anon_bitfield_has_negative_width : Error< "anonymous bit-field has negative width (%0)">; def err_bitfield_has_zero_width : Error<"named bit-field %0 has zero width">; -def err_bitfield_width_exceeds_type_size : Error< - "size of bit-field %0 (%1 bits) exceeds size of its type (%2 bits)">; -def err_anon_bitfield_width_exceeds_type_size : Error< - "size of anonymous bit-field (%0 bits) exceeds size of its type (%1 bits)">; +def err_bitfield_width_exceeds_type_width : Error< + "width of bit-field %0 (%1 bits) exceeds %select{width|size}2 " + "of its type (%3 bit%s3)">; +def err_anon_bitfield_width_exceeds_type_width : Error< + "width of anonymous bit-field (%0 bits) exceeds %select{width|size}1 " + "of its type (%2 bit%s2)">; def err_incorrect_number_of_vector_initializers : Error< "number of elements must be either one or match the size of the vector">; // Used by C++ which allows bit-fields that are wider than the type. -def warn_bitfield_width_exceeds_type_size: Warning< - "size of bit-field %0 (%1 bits) exceeds the size of its type; value will be " - "truncated to %2 bits">; -def warn_anon_bitfield_width_exceeds_type_size : Warning< - "size of anonymous bit-field (%0 bits) exceeds size of its type; value will " - "be truncated to %1 bits">; +def warn_bitfield_width_exceeds_type_width: Warning< + "width of bit-field %0 (%1 bits) exceeds the width of its type; value will " + "be truncated to %2 bit%s2">, InGroup<BitFieldWidth>; +def warn_anon_bitfield_width_exceeds_type_width : Warning< + "width of anonymous bit-field (%0 bits) exceeds width of its type; value " + "will be truncated to %1 bit%s1">, InGroup<BitFieldWidth>; def warn_missing_braces : Warning< "suggest braces around initialization of subobject">, @@ -4324,7 +4482,7 @@ def err_goto_into_protected_scope : Error< "cannot jump from this goto statement to its label">; def ext_goto_into_protected_scope : ExtWarn< "jump from this goto statement to its label is a Microsoft extension">, - InGroup<Microsoft>; + InGroup<MicrosoftGoto>; def warn_cxx98_compat_goto_into_protected_scope : Warning< "jump from this goto statement to its label is incompatible with C++98">, InGroup<CXX98Compat>, DefaultIgnore; @@ -4378,8 +4536,10 @@ def note_protected_by_seh_finally : Note< "jump bypasses initialization of __finally block">; def note_protected_by___block : Note< "jump bypasses setup of __block variable">; -def note_protected_by_objc_ownership : Note< - "jump bypasses initialization of retaining variable">; +def note_protected_by_objc_strong_init : Note< + "jump bypasses initialization of __strong variable">; +def note_protected_by_objc_weak_init : Note< + "jump bypasses initialization of __weak variable">; def note_enters_block_captures_cxx_obj : Note< "jump enters lifetime of block which captures a destructible C++ object">; def note_enters_block_captures_strong : Note< @@ -4416,8 +4576,10 @@ def note_exits_seh_finally : Note< "jump exits __finally block">; def note_exits_objc_autoreleasepool : Note< "jump exits autoreleasepool block">; -def note_exits_objc_ownership : Note< - "jump exits scope of retaining variable">; +def note_exits_objc_strong : Note< + "jump exits scope of __strong variable">; +def note_exits_objc_weak : Note< + "jump exits scope of __weak variable">; def note_exits_block_captures_cxx_obj : Note< "jump exits lifetime of block which captures a destructible C++ object">; def note_exits_block_captures_strong : Note< @@ -4457,12 +4619,12 @@ def err_flexible_array_init : Error< def ext_flexible_array_empty_aggregate_ms : Extension< "flexible array member %0 in otherwise empty " "%select{struct|interface|union|class|enum}1 is a Microsoft extension">, - InGroup<Microsoft>; + InGroup<MicrosoftFlexibleArray>; def err_flexible_array_union : Error< "flexible array member %0 in a union is not allowed">; def ext_flexible_array_union_ms : Extension< "flexible array member %0 in a union is a Microsoft extension">, - InGroup<Microsoft>; + InGroup<MicrosoftFlexibleArray>; def ext_flexible_array_empty_aggregate_gnu : Extension< "flexible array member %0 in otherwise empty " "%select{struct|interface|union|class|enum}1 is a GNU extension">, @@ -4477,7 +4639,15 @@ let CategoryName = "ARC Semantic Issue" in { let CategoryName = "ARC Weak References" in { def err_arc_weak_no_runtime : Error< - "the current deployment target does not support automated __weak references">; + "cannot create __weak reference because the current deployment target " + "does not support weak references">; +def err_arc_weak_disabled : Error< + "cannot create __weak reference in file using manual reference counting">; +def err_synthesizing_arc_weak_property_disabled : Error< + "cannot synthesize weak property in file using manual reference counting">; +def err_synthesizing_arc_weak_property_no_runtime : Error< + "cannot synthesize weak property because the current deployment target " + "does not support weak references">; def err_arc_unsupported_weak_class : Error< "class is incompatible with __weak references">; def err_arc_weak_unavailable_assign : Error< @@ -4495,6 +4665,21 @@ def err_arc_convesion_of_weak_unavailable : Error< let CategoryName = "ARC Restrictions" in { +def err_unavailable_in_arc : Error< + "%0 is unavailable in ARC">; +def note_arc_forbidden_type : Note< + "declaration uses type that is ill-formed in ARC">; +def note_performs_forbidden_arc_conversion : Note< + "inline function performs a conversion which is forbidden in ARC">; +def note_arc_init_returns_unrelated : Note< + "init method must return a type related to its receiver type">; +def note_arc_weak_disabled : Note< + "declaration uses __weak, but ARC is disabled">; +def note_arc_weak_no_runtime : Note<"declaration uses __weak, which " + "the current deployment target does not support">; +def note_arc_field_with_ownership : Note< + "field has non-trivial ownership qualification">; + def err_arc_illegal_explicit_message : Error< "ARC forbids explicit message send of %0">; def err_arc_unused_init_message : Error< @@ -4540,7 +4725,7 @@ def err_typecheck_arc_assign_self : Error< def err_typecheck_arc_assign_self_class_method : Error< "cannot assign to 'self' in a class method">; def err_typecheck_arr_assign_enumeration : Error< - "fast enumeration variables can't be modified in ARC by default; " + "fast enumeration variables cannot be modified in ARC by default; " "declare the variable __strong to allow this">; def warn_arc_retained_assign : Warning< "assigning retained object to %select{weak|unsafe_unretained}0 " @@ -4620,7 +4805,7 @@ def err_arc_strong_property_ownership : Error< "existing instance variable %1 for strong property %0 may not be " "%select{|__unsafe_unretained||__weak}2">; def err_arc_assign_property_ownership : Error< - "existing instance variable %1 for property %0 with %select{unsafe_unretained| assign}2 " + "existing instance variable %1 for property %0 with %select{unsafe_unretained|assign}2 " "attribute must be __unsafe_unretained">; def err_arc_inconsistent_property_ownership : Error< "%select{|unsafe_unretained|strong|weak}1 property %0 may not also be " @@ -4724,8 +4909,8 @@ def err_sizeof_alignof_function_type : Error< "function type">; def err_openmp_default_simd_align_expr : Error< "invalid application of '__builtin_omp_required_simd_align' to an expression, only type is allowed">; -def err_sizeof_alignof_bitfield : Error< - "invalid application of '%select{sizeof|alignof}0' to bit-field">; +def err_sizeof_alignof_typeof_bitfield : Error< + "invalid application of '%select{sizeof|alignof|typeof}0' to bit-field">; def err_alignof_member_of_incomplete_type : Error< "invalid application of 'alignof' to a field of a class still being defined">; def err_vecstep_non_scalar_vector_type : Error< @@ -4753,9 +4938,8 @@ def warn_floatingpoint_eq : Warning< "comparing floating point with == or != is unsafe">, InGroup<DiagGroup<"float-equal">>, DefaultIgnore; -def warn_division_by_zero : Warning<"division by zero is undefined">, - InGroup<DivZero>; -def warn_remainder_by_zero : Warning<"remainder by zero is undefined">, +def warn_remainder_division_by_zero : Warning< + "%select{remainder|division}0 by zero is undefined">, InGroup<DivZero>; def warn_shift_lhs_negative : Warning<"shifting a negative signed value is undefined">, InGroup<DiagGroup<"shift-negative-value">>; @@ -4793,8 +4977,8 @@ def note_logical_instead_of_bitwise_change_operator : Note< def note_logical_instead_of_bitwise_remove_constant : Note< "remove constant to silence this warning">; -def warn_bitwise_and_in_bitwise_or : Warning< - "'&' within '|'">, InGroup<BitwiseOpParentheses>; +def warn_bitwise_op_in_bitwise_op : Warning< + "'%0' within '%1'">, InGroup<BitwiseOpParentheses>; def warn_logical_and_in_logical_or : Warning< "'&&' within '||'">, InGroup<LogicalOpParentheses>; @@ -4945,10 +5129,10 @@ def err_qualified_param_declarator : Error< def ext_out_of_line_declaration : ExtWarn< "out-of-line declaration of a member must be a definition">, InGroup<OutOfLineDeclaration>, DefaultError; -def warn_member_extra_qualification : Warning< - "extra qualification on member %0">, InGroup<Microsoft>; def err_member_extra_qualification : Error< "extra qualification on member %0">; +def warn_member_extra_qualification : Warning< + err_member_extra_qualification.Text>, InGroup<MicrosoftExtraQualification>; def warn_namespace_member_extra_qualification : Warning< "extra qualification on member %0">, InGroup<DiagGroup<"extra-qualification">>; @@ -5044,6 +5228,9 @@ def err_unqualified_pointer_member_function : Error< "must explicitly qualify name of member function when taking its address">; def err_invalid_form_pointer_member_function : Error< "cannot create a non-constant pointer to member function">; +def err_address_of_function_with_pass_object_size_params: Error< + "cannot take address of function %0 because parameter %1 has " + "pass_object_size attribute">; def err_parens_pointer_member_function : Error< "cannot parenthesize the name of a method when forming a member pointer">; def err_typecheck_invalid_lvalue_addrof_addrof_function : Error< @@ -5197,6 +5384,8 @@ def err_builtin_func_cast_more_than_one_arg : Error< "function-style cast to a builtin type can only take one argument">; def err_value_init_for_array_type : Error< "array types cannot be value-initialized">; +def err_value_init_for_function_type : Error< + "function types cannot be value-initialized">; def warn_format_nonliteral_noargs : Warning< "format string is not a string literal (potentially insecure)">, InGroup<FormatSecurity>; @@ -5354,7 +5543,7 @@ def warn_objc_pointer_cxx_catch_fragile : Warning< "cannot catch an exception thrown with @throw in C++ in the non-unified " "exception model">, InGroup<ObjCNonUnifiedException>; def err_objc_object_catch : Error< - "can't catch an Objective-C object by value">; + "cannot catch an Objective-C object by value">; def err_incomplete_type_objc_at_encode : Error< "'@encode' of incomplete type %0">; def warn_objc_circular_container : Warning< @@ -5423,8 +5612,7 @@ def ext_cast_fn_obj : Extension< "cast between pointer-to-function and pointer-to-object is an extension">; def ext_ms_cast_fn_obj : ExtWarn< "static_cast between pointer-to-function and pointer-to-object is a " - "Microsoft extension">, - InGroup<Microsoft>; + "Microsoft extension">, InGroup<MicrosoftCast>; def warn_cxx98_compat_cast_fn_obj : Warning< "cast between pointer-to-function and pointer-to-object is incompatible with C++98">, InGroup<CXX98CompatPedantic>, DefaultIgnore; @@ -5534,7 +5722,7 @@ def ext_default_init_const : ExtWarn< "default initialization of an object of const type %0" "%select{| without a user-provided default constructor}1 " "is a Microsoft extension">, - InGroup<Microsoft>; + InGroup<MicrosoftConstInit>; def err_delete_operand : Error<"cannot delete expression of type %0">; def ext_delete_void_ptr_operand : ExtWarn< "cannot delete expression with pointer-to-'void' type %0">, @@ -5565,8 +5753,11 @@ def note_member_declared_here : Note< "member %0 declared here">; def err_decrement_bool : Error<"cannot decrement expression of type bool">; def warn_increment_bool : Warning< - "incrementing expression of type bool is deprecated">, - InGroup<DeprecatedIncrementBool>; + "incrementing expression of type bool is deprecated and " + "incompatible with C++1z">, InGroup<DeprecatedIncrementBool>; +def ext_increment_bool : ExtWarn< + "ISO C++1z does not allow incrementing expression of type bool">, + DefaultError, InGroup<IncrementBool>; def err_increment_decrement_enum : Error< "cannot %select{decrement|increment}0 expression of enum type %1">; def err_catch_incomplete_ptr : Error< @@ -5606,7 +5797,8 @@ 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 %0 that has virtual functions but non-virtual destructor">, + "delete called on non-final %0 that has virtual functions " + "but non-virtual destructor">, InGroup<DeleteNonVirtualDtor>, DefaultIgnore; def warn_delete_abstract_non_virtual_dtor : Warning< "delete called on %0 that is abstract but has non-virtual destructor">, @@ -5656,6 +5848,9 @@ def err_throw_incomplete_ptr : Error< "cannot throw pointer to object of incomplete type %0">; def err_return_in_constructor_handler : Error< "return in the catch of a function try block of a constructor is illegal">; +def warn_cdtor_function_try_handler_mem_expr : Warning< + "cannot refer to a non-static member from the handler of a " + "%select{constructor|destructor}0 function try block">, InGroup<Exceptions>; let CategoryName = "Lambda Issue" in { def err_capture_more_than_once : Error< @@ -5721,8 +5916,8 @@ let CategoryName = "Lambda Issue" in { def err_init_capture_multiple_expressions : Error< "initializer for lambda capture %0 contains multiple expressions">; def err_init_capture_paren_braces : Error< - "cannot deduce type for lambda capture %0 from " - "parenthesized initializer list">; + "cannot deduce type for lambda capture %1 from " + "%select{parenthesized|nested}0 initializer list">; def err_init_capture_deduction_failure : Error< "cannot deduce type for lambda capture %0 from initializer of type %2">; def err_init_capture_deduction_failure_from_init_list : Error< @@ -5752,7 +5947,7 @@ def err_pseudo_dtor_base_not_scalar : Error< "pseudo-destructor expression">; def ext_pseudo_dtor_on_void : ExtWarn< "pseudo-destructors on type void are a Microsoft extension">, - InGroup<Microsoft>; + InGroup<MicrosoftVoidPseudoDtor>; def err_pseudo_dtor_type_mismatch : Error< "the type of object expression " "%diff{($) does not match the type being destroyed ($)|" @@ -5769,14 +5964,13 @@ def err_pseudo_dtor_destructor_non_type : Error< def err_invalid_use_of_function_type : Error< "a function type is not allowed here">; def err_invalid_use_of_array_type : Error<"an array type is not allowed here">; -def err_type_defined_in_condition : Error< - "types may not be defined in conditions">; def err_typecheck_bool_condition : Error< "value of type %0 is not contextually convertible to 'bool'">; def err_typecheck_ambiguous_condition : Error< "conversion %diff{from $ to $|between types}0,1 is ambiguous">; def err_typecheck_nonviable_condition : Error< - "no viable conversion%diff{ from $ to $|}0,1">; + "no viable conversion%select{%diff{ from $ to $|}1,2|" + "%diff{ from returned value of type $ to function return type $|}1,2}0">; def err_typecheck_nonviable_condition_incomplete : Error< "no viable conversion%diff{ from $ to incomplete type $|}0,1">; def err_typecheck_deleted_function : Error< @@ -6160,6 +6354,9 @@ def err_atomic_op_needs_atomic : Error< def err_atomic_op_needs_non_const_atomic : Error< "address argument to atomic operation must be a pointer to non-const _Atomic " "type (%0 invalid)">; +def err_atomic_op_needs_non_const_pointer : Error< + "address argument to atomic operation must be a pointer to non-const " + "type (%0 invalid)">; def err_atomic_op_needs_trivial_copy : Error< "address argument to atomic operation must be a pointer to a " "trivially-copyable type (%0 invalid)">; @@ -6173,10 +6370,22 @@ def warn_atomic_op_has_invalid_memory_order : Warning< "memory order argument to atomic operation is invalid">, InGroup<DiagGroup<"atomic-memory-ordering">>; +def err_overflow_builtin_must_be_int : Error< + "operand argument to overflow builtin must be an integer (%0 invalid)">; +def err_overflow_builtin_must_be_ptr_int : Error< + "result argument to overflow builtin must be a pointer " + "to a non-const integer (%0 invalid)">; + def err_atomic_load_store_uses_lib : Error< "atomic %select{load|store}0 requires runtime support that is not " "available for this target">; +def err_nontemporal_builtin_must_be_pointer : Error< + "address argument to nontemporal builtin must be a pointer (%0 invalid)">; +def err_nontemporal_builtin_must_be_pointer_intfltptr_or_vector : Error< + "address argument to nontemporal builtin must be a pointer to integer, float, " + "pointer, or a vector of such types (%0 invalid)">; + def err_deleted_function_use : Error<"attempt to use a deleted function">; def err_kern_type_not_void_return : Error< @@ -6339,6 +6548,10 @@ def warn_cast_qual : Warning<"cast from %0 to %1 drops %select{const and " InGroup<CastQual>, DefaultIgnore; def warn_cast_qual2 : Warning<"cast from %0 to %1 must have all intermediate " "pointers const qualified to be safe">, InGroup<CastQual>, DefaultIgnore; +def warn_redefine_extname_not_applied : Warning< + "#pragma redefine_extname is applicable to external C declarations only; " + "not applied to %select{function|variable}0 %1">, + InGroup<Pragmas>; } // End of general sema category. // inline asm. @@ -6361,6 +6574,10 @@ let CategoryName = "Inline Assembly Issue" in { "asm constraint has an unexpected number of alternatives: %0 vs %1">; def err_asm_incomplete_type : Error<"asm operand has incomplete type %0">; def err_asm_unknown_register_name : Error<"unknown register name '%0' in asm">; + def err_asm_invalid_global_var_reg : Error<"register '%0' unsuitable for " + "global register variables on this target">; + def err_asm_register_size_mismatch : Error<"size of register '%0' does not " + "match variable size">; def err_asm_bad_register_type : Error<"bad type for named register variable">; def err_asm_invalid_input_size : Error< "invalid input size for constraint '%0'">; @@ -6371,9 +6588,11 @@ let CategoryName = "Inline Assembly Issue" in { "remove the cast or build with -fheinous-gnu-extensions">; def err_invalid_asm_value_for_constraint : Error <"value '%0' out of range for constraint '%1'">; - def err_asm_bitfield_in_memory_constraint - : Error <"reference to a bit-field in asm " - "%select{input|output}0 with a memory constraint '%1'">; + def err_asm_non_addr_value_in_memory_constraint : Error < + "reference to a %select{bit-field|vector element|global register variable}0" + " in asm %select{input|output}1 with a memory constraint '%2'">; + def err_asm_input_duplicate_match : Error< + "more than one input constraint matches the same output '%0'">; def warn_asm_label_on_auto_decl : Warning< "ignored asm label '%0' on automatic variable">; @@ -6388,6 +6607,8 @@ let CategoryName = "Inline Assembly Issue" in { def note_asm_missing_constraint_modifier : Note< "use constraint modifier \"%0\"">; + def note_asm_input_duplicate_first : Note< + "constraint '%0' is already present here">; } let CategoryName = "Semantic Issue" in { @@ -6490,15 +6711,13 @@ def err_anonymous_union_with_storage_spec : Error< def err_anonymous_struct_not_member : Error< "anonymous %select{structs|structs and classes}0 must be " "%select{struct or union|class}0 members">; -def err_anonymous_union_member_redecl : Error< - "member of anonymous union redeclares %0">; -def err_anonymous_struct_member_redecl : Error< - "member of anonymous struct redeclares %0">; +def err_anonymous_record_member_redecl : Error< + "member of anonymous %select{struct|union}0 redeclares %1">; def err_anonymous_record_with_type : Error< "types cannot be declared in an anonymous %select{struct|union}0">; def ext_anonymous_record_with_type : Extension< "types declared in an anonymous %select{struct|union}0 are a Microsoft " - "extension">, InGroup<Microsoft>; + "extension">, InGroup<MicrosoftAnonTag>; def ext_anonymous_record_with_anonymous_type : Extension< "anonymous types declared in an anonymous %select{struct|union}0 " "are an extension">, InGroup<DiagGroup<"nested-anon-types">>; @@ -6513,7 +6732,7 @@ def err_anonymous_record_nonpublic_member : Error< "%select{private|protected}1 data member">; def ext_ms_anonymous_record : ExtWarn< "anonymous %select{structs|unions}0 are a Microsoft extension">, - InGroup<Microsoft>; + InGroup<MicrosoftAnonTag>; // C++ local classes def err_reference_to_local_var_in_enclosing_function : Error< @@ -6846,17 +7065,12 @@ def warn_null_ret : Warning< InGroup<NonNull>; // CHECK: returning address/reference of stack memory -def warn_ret_stack_addr : Warning< - "address of stack memory associated with local variable %0 returned">, +def warn_ret_stack_addr_ref : Warning< + "%select{address of|reference to}0 stack memory associated with local " + "variable %1 returned">, InGroup<ReturnStackAddress>; -def warn_ret_stack_ref : Warning< - "reference to stack memory associated with local variable %0 returned">, - InGroup<ReturnStackAddress>; -def warn_ret_local_temp_addr : Warning< - "returning address of local temporary object">, - InGroup<ReturnStackAddress>; -def warn_ret_local_temp_ref : Warning< - "returning reference to local temporary object">, +def warn_ret_local_temp_addr_ref : Warning< + "returning %select{address of|reference to}0 local temporary object">, InGroup<ReturnStackAddress>; def warn_ret_addr_label : Warning< "returning address of label, which is local">, @@ -7058,6 +7272,10 @@ def note_empty_body_on_separate_line : Note< def err_va_start_used_in_non_variadic_function : Error< "'va_start' used in function with fixed args">; +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< @@ -7172,6 +7390,8 @@ def err_64_bit_builtin_32_bit_tgt : Error< "this builtin is only available on 64-bit targets">; def err_ppc_builtin_only_on_pwr7 : Error< "this builtin is only valid on POWER7 or later CPUs">; +def err_x86_builtin_32_bit_tgt : Error< + "this builtin is only available on x86-64 targets">; def err_builtin_longjmp_unsupported : Error< "__builtin_longjmp is not supported for the current target">; @@ -7387,6 +7607,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_static_function_scope : Error< "variables in function scope cannot be declared static">; def err_opencl_bitfields : Error< @@ -7414,7 +7636,7 @@ def err_sampler_argument_required : Error< def err_wrong_sampler_addressspace: Error< "sampler type cannot be used with the __local and __global address space qualifiers">; def err_opencl_global_invalid_addr_space : Error< - "global variables must have a constant address space qualifier">; + "program scope variable must reside in %0 address space">; def err_opencl_no_main : Error<"%select{function|kernel}0 cannot be called 'main'">; def err_opencl_kernel_attr : Error<"attribute %0 can only be applied to a kernel function">; @@ -7422,6 +7644,16 @@ def err_opencl_return_value_with_address_space : Error< "return value cannot be qualified with address space">; def err_opencl_constant_no_init : Error< "variable in constant address space must be initialized">; +def err_atomic_init_constant : Error< + "atomic variable can only be assigned to a compile time constant" + " 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">; + +// 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">; + } // end of sema category let CategoryName = "OpenMP Issue" in { @@ -7448,7 +7680,7 @@ def err_omp_firstprivate_incomplete_type : Error< def err_omp_lastprivate_incomplete_type : Error< "a lastprivate variable with incomplete type %0">; def err_omp_reduction_incomplete_type : Error< - "a reduction variable with incomplete type %0">; + "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< @@ -7457,10 +7689,6 @@ def err_omp_expected_var_name_or_array_item : Error< "expected variable name, array element or array section">; def note_omp_task_predetermined_firstprivate_here : Note< "predetermined as a firstprivate in a task construct here">; -def err_omp_clause_ref_type_arg : Error< - "arguments of OpenMP clause '%0' cannot be of reference type %1">; -def err_omp_task_predetermined_firstprivate_ref_type_arg : Error< - "predetermined as a firstprivate in a task construct variable cannot be of reference type %0">; def err_omp_threadprivate_incomplete_type : Error< "threadprivate variable with incomplete type %0">; def err_omp_no_dsa_for_variable : Error< @@ -7489,10 +7717,10 @@ def err_omp_loop_var_dsa : Error< def err_omp_not_for : Error< "%select{statement after '#pragma omp %1' must be a for loop|" "expected %2 for loops after '#pragma omp %1'%select{|, but found only %4}3}0">; -def note_omp_collapse_expr : Note< - "as specified in 'collapse' clause">; +def note_omp_collapse_ordered_expr : Note< + "as specified in %select{'collapse'|'ordered'|'collapse' and 'ordered'}0 clause%select{||s}0">; def err_omp_negative_expression_in_clause : Error< - "argument to '%0' clause must be a positive integer value">; + "argument to '%0' clause must be a %select{non-negative|strictly positive}1 integer value">; def err_omp_not_integral : Error< "expression must have integral or unscoped enumeration " "type, not %0">; @@ -7509,6 +7737,8 @@ def err_omp_required_access : Error< "%0 variable must be %1">; def err_omp_const_variable : Error< "const-qualified variable cannot be %0">; +def err_omp_const_reduction_list_item : Error< + "const-qualified list item cannot be reduction">; def err_omp_linear_incomplete_type : Error< "a linear variable with incomplete type %0">; def err_omp_linear_expected_int_or_ptr : Error< @@ -7529,8 +7759,8 @@ def err_omp_aligned_twice : Error< 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< - "initialization clause of OpenMP for loop must be of the form " - "'var = init' or 'T var = init'">; + "initialization clause of OpenMP for loop is not in canonical form " + "('var = init' or 'T var = init')">; def ext_omp_loop_not_canonical_init : ExtWarn< "initialization clause of OpenMP for loop is not in canonical form " "('var = init' or 'T var = init')">, InGroup<OpenMPLoopForm>; @@ -7560,7 +7790,7 @@ def warn_omp_loop_64_bit_var : Warning< 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 variable with array type %0">; + "a reduction list item with array 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< @@ -7574,12 +7804,13 @@ def note_omp_referenced : Note< def err_omp_reduction_in_task : Error< "reduction variables may not be accessed in an explicit task">; def err_omp_reduction_id_not_compatible : Error< - "variable of type %0 is not valid for specified reduction operation: unable to provide default initialization value">; + "list item of type %0 is not valid for specified reduction operation: unable to provide default initialization value">; def err_omp_prohibited_region : Error< "region cannot be%select{| closely}0 nested inside '%1' region" "%select{|; perhaps you forget to enclose 'omp %3' directive into a parallel region?|" "; perhaps you forget to enclose 'omp %3' directive into a for or a parallel for region with 'ordered' clause?|" - "; perhaps you forget to enclose 'omp %3' directive into a target region?}2">; + "; perhaps you forget to enclose 'omp %3' directive into a target region?|" + "; perhaps you forget to enclose 'omp %3' directive into a teams region?}2">; def err_omp_prohibited_region_simd : Error< "OpenMP constructs may not be nested inside a simd region">; def err_omp_prohibited_region_atomic : Error< @@ -7649,6 +7880,95 @@ 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_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">; +def err_omp_typecheck_section_not_integer : Error< + "array section %select{lower bound|length}0 is not an integer">; +def err_omp_section_function_type : Error< + "section of pointer to function type %0">; +def warn_omp_section_is_char : Warning<"array section %select{lower bound|length}0 is of type 'char'">, + InGroup<CharSubscript>, DefaultIgnore; +def err_omp_section_incomplete_type : Error< + "section of pointer to incomplete type %0">; +def err_omp_section_negative : Error< + "section %select{lower bound|length}0 is evaluated to a negative value %1">; +def err_omp_section_length_undefined : Error< + "section length is unspecified and cannot be inferred because subscripted value is %select{not an array|an array of unknown bound}0">; +def err_omp_wrong_linear_modifier : Error< + "expected %select{'val' modifier|one of 'ref', val' or 'uval' modifiers}0">; +def err_omp_wrong_linear_modifier_non_reference : Error< + "variable of non-reference type %0 can be used only with 'val' modifier, but used with '%1'">; +def err_omp_wrong_simdlen_safelen_values : Error< + "the value of 'simdlen' parameter must be less than or equal to the value of the 'safelen' parameter">; +def err_omp_wrong_if_directive_name_modifier : Error< + "directive name modifier '%0' is not allowed for '#pragma omp %1'">; +def err_omp_no_more_if_clause : Error< + "no more 'if' clause is allowed">; +def err_omp_unnamed_if_clause : Error< + "expected %select{|one of}0 %1 directive name modifier%select{|s}0">; +def note_omp_previous_named_if_clause : Note< + "previous clause with directive name modifier specified here">; +def err_omp_ordered_directive_with_param : Error< + "'ordered' directive %select{without any clauses|with 'threads' clause}0 cannot be closely nested inside ordered region with specified parameter">; +def err_omp_ordered_directive_without_param : Error< + "'ordered' directive with 'depend' clause cannot be closely nested inside ordered region without specified parameter">; +def note_omp_ordered_param : Note< + "'ordered' clause with specified parameter">; +def err_omp_expected_base_var_name : Error< + "expected variable name as a base of the array %select{subscript|section}0">; +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 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_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< + "parameter of the 'collapse' clause">; +def err_omp_grainsize_num_tasks_mutually_exclusive : Error< + "'%0' and '%1' clause are mutually exclusive and may not appear on the same directive">; +def note_omp_previous_grainsize_num_tasks : Note< + "'%0' clause is specified here">; +def err_omp_hint_clause_no_name : Error< + "the name of the construct must be specified in presence of 'hint' clause">; +def err_omp_critical_with_hint : Error< + "constructs with the same name must have a 'hint' clause with the same value">; +def note_omp_critical_hint_here : Note< + "%select{|previous }0'hint' clause with value '%1'">; +def note_omp_critical_no_hint : Note< + "%select{|previous }0directive with no 'hint' clause specified">; +def err_omp_firstprivate_distribute_private_teams : Error< + "private variable in '#pragma omp teams' cannot be firstprivate in '#pragma omp distribute'">; +def err_omp_firstprivate_and_lastprivate_in_distribute : Error< + "lastprivate variable cannot be firstprivate in '#pragma omp distribute'">; +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< + "unexpected expression: number of expressions is larger than the number of associated loops">; +def err_omp_depend_sink_expected_plus_minus : Error< + "expected '+' or '-' operation">; +def err_omp_depend_sink_source_not_allowed : Error< + "'depend(%select{source|sink:vec}0)' clause%select{|s}0 cannot be mixed with 'depend(%select{sink:vec|source}0)' clause%select{s|}0">; +def err_omp_linear_ordered : Error< + "'linear' clause cannot be specified along with 'ordered' clause with a parameter">; +def err_omp_unexpected_schedule_modifier : Error< + "modifier '%0' cannot be used along with modifier '%1'">; +def err_omp_schedule_nonmonotonic_static : Error< + "'nonmonotonic' modifier can only be specified with 'dynamic' or 'guided' schedule kind">; +def err_omp_schedule_nonmonotonic_ordered : Error< + "'schedule' clause with 'nonmonotonic' modifier cannot be specified if an 'ordered' clause is specified">; } // end of OpenMP category let CategoryName = "Related Result Type Issue" in { @@ -7692,18 +8012,63 @@ def err_module_unimported_use : Error< def err_module_unimported_use_multiple : Error< "%select{declaration|definition|default argument}0 of %1 must be imported " "from one of the following modules before it is required:%2">; -def err_module_import_in_extern_c : Error< +def ext_module_import_in_extern_c : ExtWarn< "import of C++ module '%0' appears within extern \"C\" language linkage " - "specification">; + "specification">, DefaultError, + InGroup<DiagGroup<"module-import-in-extern-c">>; def note_module_import_in_extern_c : Note< "extern \"C\" language linkage specification begins here">; -def err_module_import_not_at_top_level : Error< - "import of module '%0' appears within %1">; +def err_module_import_not_at_top_level_fatal : Error< + "import of module '%0' appears within %1">, DefaultFatal; +def ext_module_import_not_at_top_level_noop : ExtWarn< + "redundant #include of module '%0' appears within %1">, DefaultError, + InGroup<DiagGroup<"modules-import-nested-redundant">>; def note_module_import_not_at_top_level : Note<"%0 begins here">; def err_module_self_import : Error< "import of module '%0' appears within same top-level module '%1'">; def err_module_import_in_implementation : Error< "@import of module '%0' in implementation of '%1'; use #import">; + +def ext_equivalent_internal_linkage_decl_in_modules : ExtWarn< + "ambiguous use of internal linkage declaration %0 defined in multiple modules">, + InGroup<DiagGroup<"modules-ambiguous-internal-linkage">>; +def note_equivalent_internal_linkage_decl : Note< + "declared here%select{ in module '%1'|}0">; +} + +let CategoryName = "Coroutines Issue" in { +def err_return_in_coroutine : Error< + "return statement not allowed in coroutine; did you mean 'co_return'?">; +def note_declared_coroutine_here : Note< + "function is a coroutine due to use of " + "'%select{co_await|co_yield|co_return}0' here">; +def err_coroutine_objc_method : Error< + "Objective-C methods as coroutines are not yet supported">; +def err_coroutine_unevaluated_context : Error< + "'%0' cannot be used in an unevaluated context">; +def err_coroutine_outside_function : Error< + "'%0' cannot be used outside a function">; +def err_coroutine_ctor_dtor : Error< + "'%1' cannot be used in a %select{constructor|destructor}0">; +def err_coroutine_constexpr : Error< + "'%0' cannot be used in a constexpr function">; +def err_coroutine_varargs : Error< + "'%0' cannot be used in a varargs function">; +def ext_coroutine_without_co_await_co_yield : ExtWarn< + "'co_return' used in a function " + "that uses neither 'co_await' nor 'co_yield'">, + InGroup<DiagGroup<"coreturn-without-coawait">>; +def err_implied_std_coroutine_traits_not_found : Error< + "you need to include <coroutine> before defining a coroutine">; +def err_malformed_std_coroutine_traits : Error< + "'std::coroutine_traits' must be a class template">; +def err_implied_std_coroutine_traits_promise_type_not_found : Error< + "this function cannot be a coroutine: %q0 has no member named 'promise_type'">; +def err_implied_std_coroutine_traits_promise_type_not_class : Error< + "this function cannot be a coroutine: %0 is not a class">; +def err_coroutine_traits_missing_specialization : Error< + "this function cannot be a coroutine: missing definition of " + "specialization %q0">; } let CategoryName = "Documentation Issue" in { @@ -7761,10 +8126,10 @@ def warn_nullability_missing : Warning< "type specifier (_Nonnull, _Nullable, or _Null_unspecified)">, InGroup<NullabilityCompleteness>; -def err_type_arg_explicit_nullability : Error< +def err_objc_type_arg_explicit_nullability : Error< "type argument %0 cannot explicitly specify nullability">; -def err_type_param_bound_explicit_nullability : Error< +def err_objc_type_param_bound_explicit_nullability : Error< "type parameter %0 bound %1 cannot explicitly specify nullability">; } @@ -7776,6 +8141,8 @@ def err_objc_type_param_bound_nonobject : Error< def err_objc_type_param_bound_missing_pointer : Error< "missing '*' in type bound %0 for type parameter %1">; +def err_objc_type_param_bound_qualified : Error< + "type bound %1 for type parameter %0 cannot be qualified with '%2'">; def err_objc_type_param_redecl : Error< "redeclaration of type parameter %0">; @@ -7810,6 +8177,8 @@ def err_objc_parameterized_forward_class_first : Error< def err_objc_type_arg_missing_star : Error< "type argument %0 must be a pointer (requires a '*')">; +def err_objc_type_arg_qualified : Error< + "type argument %0 cannot be qualified with '%1'">; def err_objc_type_arg_missing : Error< "no type or protocol named %0">; diff --git a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticSerializationKinds.td b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticSerializationKinds.td index 796027e..16c7743 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticSerializationKinds.td +++ b/contrib/llvm/tools/clang/include/clang/Basic/DiagnosticSerializationKinds.td @@ -53,6 +53,20 @@ def err_pch_different_branch : Error< def err_pch_with_compiler_errors : Error< "PCH file contains compiler errors">; +def err_module_file_conflict : Error< + "module '%0' is defined in both '%1' and '%2'">, DefaultFatal; +def err_module_file_not_found : Error< + "%select{PCH|module|AST}0 file '%1' not found%select{|: %3}2">, DefaultFatal; +def err_module_file_out_of_date : Error< + "%select{PCH|module|AST}0 file '%1' is out of date and " + "needs to be rebuilt%select{|: %3}2">, DefaultFatal; +def err_module_file_invalid : Error< + "file '%1' is not a valid precompiled %select{PCH|module|AST}0 file">, DefaultFatal; +def note_module_file_imported_by : Note< + "imported by %select{|module '%2' in }1'%0'">; +def err_module_file_not_module : Error< + "AST file '%0' was not built as a module">, DefaultFatal; + def err_imported_module_not_found : Error< "module '%0' in AST file '%1' (imported by AST file '%2') " "is not defined in any loaded module map file; " @@ -82,9 +96,6 @@ def err_pch_pp_detailed_record : Error< "'-detailed-preprocessing-record' but %select{precompiled header was not " "built with it|it is not present on the command line}0">; -def err_not_a_pch_file : Error< - "'%0' does not appear to be a precompiled header file">, DefaultFatal; - def err_module_odr_violation_missing_decl : Error< "%q0 from module '%1' is not present in definition of %q2" "%select{ in module '%4'| provided earlier}3">, NoSFINAE; @@ -100,6 +111,14 @@ def note_module_odr_violation_different_definitions : Note< def err_module_odr_violation_different_instantiations : Error< "instantiation of %q0 is different in different modules">; +def warn_module_uses_date_time : Warning< + "%select{precompiled header|module}0 uses __DATE__ or __TIME__">, + InGroup<DiagGroup<"pch-date-time">>; + +def warn_duplicate_module_file_extension : Warning< + "duplicate module file extension block name '%0'">, + InGroup<ModuleFileExtension>; + } // let CategoryName } // let Component diff --git a/contrib/llvm/tools/clang/include/clang/Basic/FileManager.h b/contrib/llvm/tools/clang/include/clang/Basic/FileManager.h index ac0d7a1..17758ec 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/FileManager.h +++ b/contrib/llvm/tools/clang/include/clang/Basic/FileManager.h @@ -126,9 +126,9 @@ class FileManager : public RefCountedBase<FileManager> { /// /// For each virtual file (e.g. foo/bar/baz.cpp), we add all of its parent /// directories (foo/ and foo/bar/) here. - SmallVector<DirectoryEntry*, 4> VirtualDirectoryEntries; + SmallVector<std::unique_ptr<DirectoryEntry>, 4> VirtualDirectoryEntries; /// \brief The virtual files that we have allocated. - SmallVector<FileEntry*, 4> VirtualFileEntries; + SmallVector<std::unique_ptr<FileEntry>, 4> VirtualFileEntries; /// \brief A cache that maps paths to directory entries (either real or /// virtual) we have looked up @@ -218,7 +218,8 @@ public: bool CacheFailure = true); /// \brief Returns the current file system options - const FileSystemOptions &getFileSystemOptions() { return FileSystemOpts; } + FileSystemOptions &getFileSystemOpts() { return FileSystemOpts; } + const FileSystemOptions &getFileSystemOpts() const { return FileSystemOpts; } IntrusiveRefCntPtr<vfs::FileSystem> getVirtualFileSystem() const { return FS; @@ -254,7 +255,13 @@ public: /// \brief If path is not absolute and FileSystemOptions set the working /// directory, the path is modified to be relative to the given /// working directory. - void FixupRelativePath(SmallVectorImpl<char> &path) const; + /// \returns true if \c path changed. + bool FixupRelativePath(SmallVectorImpl<char> &path) const; + + /// Makes \c Path absolute taking into account FileSystemOptions and the + /// working directory option. + /// \returns true if \c Path changed to absolute. + bool makeAbsolutePath(SmallVectorImpl<char> &Path) const; /// \brief Produce an array mapping from the unique IDs assigned to each /// file to the corresponding FileEntry pointer. @@ -266,9 +273,6 @@ public: static void modifyFileEntry(FileEntry *File, off_t Size, time_t ModificationTime); - /// \brief Remove any './' components from a path. - static bool removeDotPaths(SmallVectorImpl<char> &Path); - /// \brief Retrieve the canonical name for a given directory. /// /// This is a very expensive operation, despite its results being cached, diff --git a/contrib/llvm/tools/clang/include/clang/Basic/IdentifierTable.h b/contrib/llvm/tools/clang/include/clang/Basic/IdentifierTable.h index 1785e04..d672314 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/IdentifierTable.h +++ b/contrib/llvm/tools/clang/include/clang/Basic/IdentifierTable.h @@ -62,7 +62,7 @@ class IdentifierInfo { // partially) from an AST file. bool ChangedAfterLoad : 1; // True if identifier has changed from the // definition loaded from an AST file. - bool RevertedTokenID : 1; // True if RevertTokenIDToIdentifier was + bool RevertedTokenID : 1; // True if revertTokenIDToIdentifier was // called. bool OutOfDate : 1; // True if there may be additional // information about this identifier @@ -152,7 +152,7 @@ public: /// tokens. tok::TokenKind getTokenID() const { return (tok::TokenKind)TokenID; } - /// \brief True if RevertTokenIDToIdentifier() was called. + /// \brief True if revertTokenIDToIdentifier() was called. bool hasRevertedTokenIDToIdentifier() const { return RevertedTokenID; } /// \brief Revert TokenID to tok::identifier; used for GNU libstdc++ 4.2 @@ -161,11 +161,16 @@ public: /// TokenID is normally read-only but there are 2 instances where we revert it /// to tok::identifier for libstdc++ 4.2. Keep track of when this happens /// using this method so we can inform serialization about it. - void RevertTokenIDToIdentifier() { + void revertTokenIDToIdentifier() { assert(TokenID != tok::identifier && "Already at tok::identifier"); TokenID = tok::identifier; RevertedTokenID = true; } + void revertIdentifierToTokenID(tok::TokenKind TK) { + assert(TokenID == tok::identifier && "Should be at tok::identifier"); + TokenID = TK; + RevertedTokenID = false; + } /// \brief Return the preprocessor keyword ID for this identifier. /// @@ -183,6 +188,18 @@ public: } void setObjCKeywordID(tok::ObjCKeywordKind ID) { ObjCOrBuiltinID = ID; } + /// \brief True if setNotBuiltin() was called. + bool hasRevertedBuiltin() const { + return ObjCOrBuiltinID == tok::NUM_OBJC_KEYWORDS; + } + + /// \brief Revert the identifier to a non-builtin identifier. We do this if + /// the name of a known builtin library function is used to declare that + /// function, but an unexpected type is specified. + void revertBuiltin() { + setBuiltinID(0); + } + /// \brief Return a value indicating whether this is a builtin function. /// /// 0 is not-built-in. 1 is builtin-for-some-nonprimary-target. diff --git a/contrib/llvm/tools/clang/include/clang/Basic/LangOptions.def b/contrib/llvm/tools/clang/include/clang/Basic/LangOptions.def index c184df7..fdf7e49 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/LangOptions.def +++ b/contrib/llvm/tools/clang/include/clang/Basic/LangOptions.def @@ -90,6 +90,7 @@ LANGOPT(LineComment , 1, 0, "'//' comments") LANGOPT(Bool , 1, 0, "bool, true, and false keywords") LANGOPT(Half , 1, 0, "half keyword") LANGOPT(WChar , 1, CPlusPlus, "wchar_t keyword") +LANGOPT(DeclSpecKeyword , 1, 0, "__declspec keyword") BENIGN_LANGOPT(DollarIdents , 1, 1, "'$' in identifiers") BENIGN_LANGOPT(AsmPreprocessor, 1, 0, "preprocessor in asm mode") BENIGN_LANGOPT(GNUMode , 1, 1, "GNU extensions") @@ -117,6 +118,7 @@ LANGOPT(Freestanding, 1, 0, "freestanding implementation") LANGOPT(NoBuiltin , 1, 0, "disable builtin functions") LANGOPT(NoMathBuiltin , 1, 0, "disable math builtin functions") LANGOPT(GNUAsm , 1, 1, "GNU-style inline assembly") +LANGOPT(Coroutines , 1, 0, "C++ coroutines") BENIGN_LANGOPT(ThreadsafeStatics , 1, 1, "thread-safe static initializers") LANGOPT(POSIXThreads , 1, 0, "POSIX thread support") @@ -131,7 +133,6 @@ COMPATIBLE_LANGOPT(ModulesStrictDeclUse, 1, 0, "require declaration of module us 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") COMPATIBLE_LANGOPT(ModulesLocalVisibility, 1, 0, "local submodule visibility") -COMPATIBLE_LANGOPT(ModulesHideInternalLinkage, 1, 1, "hiding non-visible internal linkage declarations from redeclaration lookup") 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__)") @@ -146,6 +147,7 @@ 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") BENIGN_LANGOPT(ObjCGCBitmapPrint , 1, 0, "printing of GC's bitmap layout for __weak/__strong ivars") @@ -166,6 +168,7 @@ LANGOPT(OpenMPUseTLS , 1, 0, "Use TLS for threadprivates or runtime calls") 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(AssumeSaneOperatorNew , 1, 1, "implicit __attribute__((malloc)) for C++'s new operators") LANGOPT(SizedDeallocation , 1, 0, "enable sized deallocation functions") @@ -188,7 +191,8 @@ LANGOPT(DefaultFPContract , 1, 0, "FP_CONTRACT") LANGOPT(NoBitFieldTypeAlign , 1, 0, "bit-field type alignment") LANGOPT(HexagonQdsp6Compat , 1, 0, "hexagon-qdsp6 backward compatibility") LANGOPT(ObjCAutoRefCount , 1, 0, "Objective-C automated reference counting") -LANGOPT(ObjCARCWeak , 1, 0, "__weak support in the ARC runtime") +LANGOPT(ObjCWeakRuntime , 1, 0, "__weak support in the ARC runtime") +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") diff --git a/contrib/llvm/tools/clang/include/clang/Basic/Module.h b/contrib/llvm/tools/clang/include/clang/Basic/Module.h index 1bc8925..1702fb1 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/Module.h +++ b/contrib/llvm/tools/clang/include/clang/Basic/Module.h @@ -15,6 +15,7 @@ #ifndef LLVM_CLANG_BASIC_MODULE_H #define LLVM_CLANG_BASIC_MODULE_H +#include "clang/Basic/FileManager.h" #include "clang/Basic/SourceLocation.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseSet.h" @@ -35,9 +36,6 @@ namespace llvm { namespace clang { -class DirectoryEntry; -class FileEntry; -class FileManager; class LangOptions; class TargetInfo; class IdentifierInfo; @@ -152,6 +150,9 @@ public: /// \brief Whether this module is missing a feature from \c Requirements. unsigned IsMissingRequirement : 1; + /// \brief Whether we tried and failed to load a module file for this module. + unsigned HasIncompatibleModuleFile : 1; + /// \brief Whether this module is available in the current translation unit. /// /// If the module is missing headers or does not meet all requirements then @@ -356,6 +357,12 @@ public: /// its top-level module. std::string getFullModuleName() const; + /// \brief Whether the full name of this module is equal to joining + /// \p nameParts with "."s. + /// + /// This is more efficient than getFullModuleName(). + bool fullModuleNameIs(ArrayRef<StringRef> nameParts) const; + /// \brief Retrieve the top-level module for this (sub)module, which may /// be this module. Module *getTopLevelModule() { @@ -469,6 +476,13 @@ public: submodule_iterator submodule_end() { return SubModules.end(); } submodule_const_iterator submodule_end() const { return SubModules.end(); } + llvm::iterator_range<submodule_iterator> submodules() { + return llvm::make_range(submodule_begin(), submodule_end()); + } + llvm::iterator_range<submodule_const_iterator> submodules() const { + return llvm::make_range(submodule_begin(), submodule_end()); + } + /// \brief Appends this module's list of exported modules to \p Exported. /// /// This provides a subset of immediately imported modules (the ones that are diff --git a/contrib/llvm/tools/clang/include/clang/Basic/ObjCRuntime.h b/contrib/llvm/tools/clang/include/clang/Basic/ObjCRuntime.h index e33587d..cf51b14 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/ObjCRuntime.h +++ b/contrib/llvm/tools/clang/include/clang/Basic/ObjCRuntime.h @@ -41,6 +41,10 @@ public: /// version of iOS. iOS, + /// 'watchos' is a variant of iOS for Apple's watchOS. The version + /// is a release version of watchOS. + WatchOS, + /// 'gcc' is the Objective-C runtime shipped with GCC, implementing a /// fragile Objective-C ABI GCC, @@ -81,6 +85,7 @@ public: case GNUstep: return true; case ObjFW: return true; case iOS: return true; + case WatchOS: return true; } llvm_unreachable("bad kind"); } @@ -114,6 +119,7 @@ public: case FragileMacOSX: case MacOSX: case iOS: + case WatchOS: return false; case GCC: case GNUstep: @@ -133,9 +139,12 @@ public: /// \brief Does this runtime allow ARC at all? bool allowsARC() const { switch (getKind()) { - case FragileMacOSX: return false; + case FragileMacOSX: + // No stub library for the fragile runtime. + return getVersion() >= VersionTuple(10, 7); case MacOSX: return true; case iOS: return true; + case WatchOS: return true; case GCC: return false; case GNUstep: return true; case ObjFW: return true; @@ -150,9 +159,10 @@ public: /// library. bool hasNativeARC() const { switch (getKind()) { - case FragileMacOSX: return false; + case FragileMacOSX: return getVersion() >= VersionTuple(10, 7); case MacOSX: return getVersion() >= VersionTuple(10, 7); case iOS: return getVersion() >= VersionTuple(5); + case WatchOS: return true; case GCC: return false; case GNUstep: return getVersion() >= VersionTuple(1, 6); @@ -168,6 +178,8 @@ public: return getVersion() >= VersionTuple(10, 8); case iOS: return (getVersion() >= VersionTuple(6)); + case WatchOS: + return true; case GNUstep: return getVersion() >= VersionTuple(1, 7); @@ -197,6 +209,7 @@ public: case FragileMacOSX: return false; case MacOSX: return getVersion() >= VersionTuple(10, 8); case iOS: return getVersion() >= VersionTuple(6); + case WatchOS: return true; // This is really a lie, because some implementations and versions // of the runtime do not support ARC. Probably -fgnu-runtime @@ -224,6 +237,7 @@ public: return true; case MacOSX: case iOS: + case WatchOS: case GNUstep: case ObjFW: return false; @@ -245,6 +259,7 @@ public: case FragileMacOSX: return getVersion() >= VersionTuple(10, 8); case MacOSX: return getVersion() >= VersionTuple(10, 8); case iOS: return getVersion() >= VersionTuple(5); + case WatchOS: return true; case GCC: return false; case GNUstep: return false; case ObjFW: return false; @@ -257,6 +272,7 @@ public: switch (getKind()) { case MacOSX: return true; case iOS: return true; + case WatchOS: return true; case FragileMacOSX: return false; case GCC: return true; case GNUstep: return true; @@ -270,6 +286,7 @@ public: switch (getKind()) { case MacOSX: return true; case iOS: return true; + case WatchOS: return true; case FragileMacOSX: return false; case GCC: return true; case GNUstep: return true; @@ -283,6 +300,7 @@ public: case FragileMacOSX: case MacOSX: case iOS: + case WatchOS: return true; case GNUstep: return getVersion() >= VersionTuple(1, 7); diff --git a/contrib/llvm/tools/clang/include/clang/Basic/OpenCLExtensions.def b/contrib/llvm/tools/clang/include/clang/Basic/OpenCLExtensions.def index 103fa83..91fd919 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/OpenCLExtensions.def +++ b/contrib/llvm/tools/clang/include/clang/Basic/OpenCLExtensions.def @@ -26,6 +26,9 @@ 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) + // Clang Extensions. OPENCLEXT(cl_clang_storage_class_specifiers) diff --git a/contrib/llvm/tools/clang/include/clang/Basic/OpenMPKinds.def b/contrib/llvm/tools/clang/include/clang/Basic/OpenMPKinds.def index 67a5068..313e1c1 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/OpenMPKinds.def +++ b/contrib/llvm/tools/clang/include/clang/Basic/OpenMPKinds.def @@ -57,9 +57,30 @@ #ifndef OPENMP_TARGET_CLAUSE # define OPENMP_TARGET_CLAUSE(Name) #endif +#ifndef OPENMP_TARGET_DATA_CLAUSE +# define OPENMP_TARGET_DATA_CLAUSE(Name) +#endif #ifndef OPENMP_TEAMS_CLAUSE # define OPENMP_TEAMS_CLAUSE(Name) #endif +#ifndef OPENMP_CANCEL_CLAUSE +# define OPENMP_CANCEL_CLAUSE(Name) +#endif +#ifndef OPENMP_ORDERED_CLAUSE +# define OPENMP_ORDERED_CLAUSE(Name) +#endif +#ifndef OPENMP_TASKLOOP_CLAUSE +# define OPENMP_TASKLOOP_CLAUSE(Name) +#endif +#ifndef OPENMP_TASKLOOP_SIMD_CLAUSE +# define OPENMP_TASKLOOP_SIMD_CLAUSE(Name) +#endif +#ifndef OPENMP_CRITICAL_CLAUSE +# define OPENMP_CRITICAL_CLAUSE(Name) +#endif +#ifndef OPENMP_DISTRIBUTE_CLAUSE +#define OPENMP_DISTRIBUTE_CLAUSE(Name) +#endif #ifndef OPENMP_DEFAULT_KIND # define OPENMP_DEFAULT_KIND(Name) #endif @@ -69,9 +90,18 @@ #ifndef OPENMP_SCHEDULE_KIND #define OPENMP_SCHEDULE_KIND(Name) #endif +#ifndef OPENMP_SCHEDULE_MODIFIER +#define OPENMP_SCHEDULE_MODIFIER(Name) +#endif #ifndef OPENMP_DEPEND_KIND #define OPENMP_DEPEND_KIND(Name) #endif +#ifndef OPENMP_LINEAR_KIND +#define OPENMP_LINEAR_KIND(Name) +#endif +#ifndef OPENMP_MAP_KIND +#define OPENMP_MAP_KIND(Name) +#endif // OpenMP directives. OPENMP_DIRECTIVE(threadprivate) @@ -94,17 +124,22 @@ OPENMP_DIRECTIVE(atomic) OPENMP_DIRECTIVE(target) OPENMP_DIRECTIVE(teams) OPENMP_DIRECTIVE(cancel) +OPENMP_DIRECTIVE_EXT(target_data, "target data") 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(taskloop) +OPENMP_DIRECTIVE_EXT(taskloop_simd, "taskloop simd") +OPENMP_DIRECTIVE(distribute) // OpenMP clauses. OPENMP_CLAUSE(if, OMPIfClause) OPENMP_CLAUSE(final, OMPFinalClause) OPENMP_CLAUSE(num_threads, OMPNumThreadsClause) OPENMP_CLAUSE(safelen, OMPSafelenClause) +OPENMP_CLAUSE(simdlen, OMPSimdlenClause) OPENMP_CLAUSE(collapse, OMPCollapseClause) OPENMP_CLAUSE(default, OMPDefaultClause) OPENMP_CLAUSE(private, OMPPrivateClause) @@ -129,6 +164,17 @@ OPENMP_CLAUSE(update, OMPUpdateClause) OPENMP_CLAUSE(capture, OMPCaptureClause) OPENMP_CLAUSE(seq_cst, OMPSeqCstClause) OPENMP_CLAUSE(depend, OMPDependClause) +OPENMP_CLAUSE(device, OMPDeviceClause) +OPENMP_CLAUSE(threads, OMPThreadsClause) +OPENMP_CLAUSE(simd, OMPSIMDClause) +OPENMP_CLAUSE(map, OMPMapClause) +OPENMP_CLAUSE(num_teams, OMPNumTeamsClause) +OPENMP_CLAUSE(thread_limit, OMPThreadLimitClause) +OPENMP_CLAUSE(priority, OMPPriorityClause) +OPENMP_CLAUSE(grainsize, OMPGrainsizeClause) +OPENMP_CLAUSE(nogroup, OMPNogroupClause) +OPENMP_CLAUSE(num_tasks, OMPNumTasksClause) +OPENMP_CLAUSE(hint, OMPHintClause) // Clauses allowed for OpenMP directive 'parallel'. OPENMP_PARALLEL_CLAUSE(if) @@ -147,6 +193,7 @@ OPENMP_SIMD_CLAUSE(lastprivate) OPENMP_SIMD_CLAUSE(linear) OPENMP_SIMD_CLAUSE(aligned) OPENMP_SIMD_CLAUSE(safelen) +OPENMP_SIMD_CLAUSE(simdlen) OPENMP_SIMD_CLAUSE(collapse) OPENMP_SIMD_CLAUSE(reduction) @@ -159,6 +206,7 @@ OPENMP_FOR_CLAUSE(collapse) OPENMP_FOR_CLAUSE(schedule) OPENMP_FOR_CLAUSE(ordered) OPENMP_FOR_CLAUSE(nowait) +OPENMP_FOR_CLAUSE(linear) // Clauses allowed for directive 'omp for simd'. OPENMP_FOR_SIMD_CLAUSE(private) @@ -169,6 +217,7 @@ OPENMP_FOR_SIMD_CLAUSE(schedule) OPENMP_FOR_SIMD_CLAUSE(collapse) OPENMP_FOR_SIMD_CLAUSE(nowait) OPENMP_FOR_SIMD_CLAUSE(safelen) +OPENMP_FOR_SIMD_CLAUSE(simdlen) OPENMP_FOR_SIMD_CLAUSE(linear) OPENMP_FOR_SIMD_CLAUSE(aligned) @@ -185,6 +234,9 @@ OPENMP_SINGLE_CLAUSE(firstprivate) OPENMP_SINGLE_CLAUSE(copyprivate) OPENMP_SINGLE_CLAUSE(nowait) +// Clauses allowed for OpenMP directive 'cancel'. +OPENMP_CANCEL_CLAUSE(if) + // Static attributes for 'default' clause. OPENMP_DEFAULT_KIND(none) OPENMP_DEFAULT_KIND(shared) @@ -201,10 +253,22 @@ OPENMP_SCHEDULE_KIND(guided) OPENMP_SCHEDULE_KIND(auto) OPENMP_SCHEDULE_KIND(runtime) +// Modifiers for 'schedule' clause. +OPENMP_SCHEDULE_MODIFIER(monotonic) +OPENMP_SCHEDULE_MODIFIER(nonmonotonic) +OPENMP_SCHEDULE_MODIFIER(simd) + // Static attributes for 'depend' clause. OPENMP_DEPEND_KIND(in) OPENMP_DEPEND_KIND(out) OPENMP_DEPEND_KIND(inout) +OPENMP_DEPEND_KIND(source) +OPENMP_DEPEND_KIND(sink) + +// Modifiers for 'linear' clause. +OPENMP_LINEAR_KIND(val) +OPENMP_LINEAR_KIND(ref) +OPENMP_LINEAR_KIND(uval) // Clauses allowed for OpenMP directive 'parallel for'. OPENMP_PARALLEL_FOR_CLAUSE(if) @@ -220,6 +284,7 @@ OPENMP_PARALLEL_FOR_CLAUSE(lastprivate) OPENMP_PARALLEL_FOR_CLAUSE(collapse) OPENMP_PARALLEL_FOR_CLAUSE(schedule) OPENMP_PARALLEL_FOR_CLAUSE(ordered) +OPENMP_PARALLEL_FOR_CLAUSE(linear) // Clauses allowed for OpenMP directive 'parallel for simd'. OPENMP_PARALLEL_FOR_SIMD_CLAUSE(if) @@ -235,6 +300,7 @@ OPENMP_PARALLEL_FOR_SIMD_CLAUSE(lastprivate) OPENMP_PARALLEL_FOR_SIMD_CLAUSE(collapse) OPENMP_PARALLEL_FOR_SIMD_CLAUSE(schedule) OPENMP_PARALLEL_FOR_SIMD_CLAUSE(safelen) +OPENMP_PARALLEL_FOR_SIMD_CLAUSE(simdlen) OPENMP_PARALLEL_FOR_SIMD_CLAUSE(linear) OPENMP_PARALLEL_FOR_SIMD_CLAUSE(aligned) @@ -260,6 +326,7 @@ OPENMP_TASK_CLAUSE(shared) OPENMP_TASK_CLAUSE(untied) OPENMP_TASK_CLAUSE(mergeable) OPENMP_TASK_CLAUSE(depend) +OPENMP_TASK_CLAUSE(priority) // Clauses allowed for OpenMP directive 'atomic'. OPENMP_ATOMIC_CLAUSE(read) @@ -271,6 +338,14 @@ 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) + +// 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) // Clauses allowed for OpenMP directive 'teams'. // TODO More clauses for 'teams' directive. @@ -279,14 +354,83 @@ OPENMP_TEAMS_CLAUSE(private) OPENMP_TEAMS_CLAUSE(firstprivate) OPENMP_TEAMS_CLAUSE(shared) OPENMP_TEAMS_CLAUSE(reduction) +OPENMP_TEAMS_CLAUSE(num_teams) +OPENMP_TEAMS_CLAUSE(thread_limit) + +// Clauses allowed for OpenMP directive 'ordered'. +// TODO More clauses for 'ordered' directive. +OPENMP_ORDERED_CLAUSE(threads) +OPENMP_ORDERED_CLAUSE(simd) +OPENMP_ORDERED_CLAUSE(depend) + +// Map types and map type modifier for 'map' clause. +OPENMP_MAP_KIND(alloc) +OPENMP_MAP_KIND(to) +OPENMP_MAP_KIND(from) +OPENMP_MAP_KIND(tofrom) +OPENMP_MAP_KIND(delete) +OPENMP_MAP_KIND(release) +OPENMP_MAP_KIND(always) +// Clauses allowed for OpenMP directive 'taskloop'. +OPENMP_TASKLOOP_CLAUSE(if) +OPENMP_TASKLOOP_CLAUSE(shared) +OPENMP_TASKLOOP_CLAUSE(private) +OPENMP_TASKLOOP_CLAUSE(firstprivate) +OPENMP_TASKLOOP_CLAUSE(lastprivate) +OPENMP_TASKLOOP_CLAUSE(default) +OPENMP_TASKLOOP_CLAUSE(collapse) +OPENMP_TASKLOOP_CLAUSE(final) +OPENMP_TASKLOOP_CLAUSE(untied) +OPENMP_TASKLOOP_CLAUSE(mergeable) +OPENMP_TASKLOOP_CLAUSE(priority) +OPENMP_TASKLOOP_CLAUSE(grainsize) +OPENMP_TASKLOOP_CLAUSE(nogroup) +OPENMP_TASKLOOP_CLAUSE(num_tasks) + +// Clauses allowed for OpenMP directive 'taskloop simd'. +OPENMP_TASKLOOP_SIMD_CLAUSE(if) +OPENMP_TASKLOOP_SIMD_CLAUSE(shared) +OPENMP_TASKLOOP_SIMD_CLAUSE(private) +OPENMP_TASKLOOP_SIMD_CLAUSE(firstprivate) +OPENMP_TASKLOOP_SIMD_CLAUSE(lastprivate) +OPENMP_TASKLOOP_SIMD_CLAUSE(default) +OPENMP_TASKLOOP_SIMD_CLAUSE(collapse) +OPENMP_TASKLOOP_SIMD_CLAUSE(final) +OPENMP_TASKLOOP_SIMD_CLAUSE(untied) +OPENMP_TASKLOOP_SIMD_CLAUSE(mergeable) +OPENMP_TASKLOOP_SIMD_CLAUSE(priority) +OPENMP_TASKLOOP_SIMD_CLAUSE(linear) +OPENMP_TASKLOOP_SIMD_CLAUSE(aligned) +OPENMP_TASKLOOP_SIMD_CLAUSE(safelen) +OPENMP_TASKLOOP_SIMD_CLAUSE(simdlen) +OPENMP_TASKLOOP_SIMD_CLAUSE(grainsize) +OPENMP_TASKLOOP_SIMD_CLAUSE(nogroup) +OPENMP_TASKLOOP_SIMD_CLAUSE(num_tasks) + +// Clauses allowed for OpenMP directive 'critical'. +OPENMP_CRITICAL_CLAUSE(hint) + +// Clauses allowed for OpenMP directive 'distribute' +OPENMP_DISTRIBUTE_CLAUSE(private) +OPENMP_DISTRIBUTE_CLAUSE(firstprivate) +OPENMP_DISTRIBUTE_CLAUSE(lastprivate) +OPENMP_DISTRIBUTE_CLAUSE(collapse) + +#undef OPENMP_TASKLOOP_SIMD_CLAUSE +#undef OPENMP_TASKLOOP_CLAUSE +#undef OPENMP_LINEAR_KIND #undef OPENMP_DEPEND_KIND +#undef OPENMP_SCHEDULE_MODIFIER #undef OPENMP_SCHEDULE_KIND #undef OPENMP_PROC_BIND_KIND #undef OPENMP_DEFAULT_KIND #undef OPENMP_DIRECTIVE #undef OPENMP_DIRECTIVE_EXT #undef OPENMP_CLAUSE +#undef OPENMP_CRITICAL_CLAUSE +#undef OPENMP_ORDERED_CLAUSE +#undef OPENMP_CANCEL_CLAUSE #undef OPENMP_SINGLE_CLAUSE #undef OPENMP_SECTIONS_CLAUSE #undef OPENMP_PARALLEL_CLAUSE @@ -296,8 +440,10 @@ OPENMP_TEAMS_CLAUSE(reduction) #undef OPENMP_TASK_CLAUSE #undef OPENMP_ATOMIC_CLAUSE #undef OPENMP_TARGET_CLAUSE +#undef OPENMP_TARGET_DATA_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 diff --git a/contrib/llvm/tools/clang/include/clang/Basic/OpenMPKinds.h b/contrib/llvm/tools/clang/include/clang/Basic/OpenMPKinds.h index 83939bb..d4d3db8 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/OpenMPKinds.h +++ b/contrib/llvm/tools/clang/include/clang/Basic/OpenMPKinds.h @@ -62,6 +62,15 @@ enum OpenMPScheduleClauseKind { OMPC_SCHEDULE_unknown }; +/// \brief OpenMP modifiers for 'schedule' clause. +enum OpenMPScheduleClauseModifier { + OMPC_SCHEDULE_MODIFIER_unknown = OMPC_SCHEDULE_unknown, +#define OPENMP_SCHEDULE_MODIFIER(Name) \ + OMPC_SCHEDULE_MODIFIER_##Name, +#include "clang/Basic/OpenMPKinds.def" + OMPC_SCHEDULE_MODIFIER_last +}; + /// \brief OpenMP attributes for 'depend' clause. enum OpenMPDependClauseKind { #define OPENMP_DEPEND_KIND(Name) \ @@ -70,6 +79,22 @@ enum OpenMPDependClauseKind { OMPC_DEPEND_unknown }; +/// \brief OpenMP attributes for 'linear' clause. +enum OpenMPLinearClauseKind { +#define OPENMP_LINEAR_KIND(Name) \ + OMPC_LINEAR_##Name, +#include "clang/Basic/OpenMPKinds.def" + OMPC_LINEAR_unknown +}; + +/// \brief OpenMP mapping kind for 'map' clause. +enum OpenMPMapClauseKind { +#define OPENMP_MAP_KIND(Name) \ + OMPC_MAP_##Name, +#include "clang/Basic/OpenMPKinds.def" + OMPC_MAP_unknown +}; + OpenMPDirectiveKind getOpenMPDirectiveKind(llvm::StringRef Str); const char *getOpenMPDirectiveName(OpenMPDirectiveKind Kind); @@ -95,12 +120,24 @@ bool isOpenMPLoopDirective(OpenMPDirectiveKind DKind); /// otherwise - false. bool isOpenMPWorksharingDirective(OpenMPDirectiveKind DKind); +/// \brief Checks if the specified directive is a taskloop directive. +/// \param DKind Specified directive. +/// \return true - the directive is a worksharing directive like 'omp taskloop', +/// otherwise - false. +bool isOpenMPTaskLoopDirective(OpenMPDirectiveKind DKind); + /// \brief Checks if the specified directive is a parallel-kind directive. /// \param DKind Specified directive. /// \return true - the directive is a parallel-like directive like 'omp /// parallel', otherwise - false. bool isOpenMPParallelDirective(OpenMPDirectiveKind DKind); +/// \brief Checks if the specified directive is a target-kind directive. +/// \param DKind Specified directive. +/// \return true - the directive is a target-like directive like 'omp target', +/// otherwise - false. +bool isOpenMPTargetDirective(OpenMPDirectiveKind DKind); + /// \brief Checks if the specified directive is a teams-kind directive. /// \param DKind Specified directive. /// \return true - the directive is a teams-like directive like 'omp teams', @@ -113,6 +150,13 @@ bool isOpenMPTeamsDirective(OpenMPDirectiveKind DKind); /// otherwise - false. bool isOpenMPSimdDirective(OpenMPDirectiveKind DKind); +/// \brief Checks if the specified directive is a distribute directive. +/// \param DKind Specified directive. +/// \return true - the directive is a distribute-directive like 'omp +/// distribute', +/// otherwise - false. +bool isOpenMPDistributeDirective(OpenMPDirectiveKind DKind); + /// \brief Checks if the specified clause is one of private clauses like /// 'private', 'firstprivate', 'reduction' etc.. /// \param Kind Clause kind. diff --git a/contrib/llvm/tools/clang/include/clang/Basic/OperatorKinds.def b/contrib/llvm/tools/clang/include/clang/Basic/OperatorKinds.def index d011e9d..34ad764 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/OperatorKinds.def +++ b/contrib/llvm/tools/clang/include/clang/Basic/OperatorKinds.def @@ -101,6 +101,7 @@ OVERLOADED_OPERATOR_MULTI(Subscript , "[]" , false, t // ?: can *not* be overloaded, but we need the overload // resolution machinery for it. OVERLOADED_OPERATOR_MULTI(Conditional , "?" , false, true , false) +OVERLOADED_OPERATOR(Coawait , "co_await", kw_co_await , true , false, false) #undef OVERLOADED_OPERATOR_MULTI #undef OVERLOADED_OPERATOR diff --git a/contrib/llvm/tools/clang/include/clang/Basic/PartialDiagnostic.h b/contrib/llvm/tools/clang/include/clang/Basic/PartialDiagnostic.h index 84c8dd1..53ce95c 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/PartialDiagnostic.h +++ b/contrib/llvm/tools/clang/include/clang/Basic/PartialDiagnostic.h @@ -377,7 +377,7 @@ public: } friend inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD, - const SourceRange &R) { + SourceRange R) { PD.AddSourceRange(CharSourceRange::getTokenRange(R)); return PD; } diff --git a/contrib/llvm/tools/clang/include/clang/Basic/Sanitizers.def b/contrib/llvm/tools/clang/include/clang/Basic/Sanitizers.def index 1b528c8..4b68593 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/Sanitizers.def +++ b/contrib/llvm/tools/clang/include/clang/Basic/Sanitizers.def @@ -84,11 +84,13 @@ SANITIZER("dataflow", DataFlow) // Control Flow Integrity SANITIZER("cfi-cast-strict", CFICastStrict) SANITIZER("cfi-derived-cast", CFIDerivedCast) +SANITIZER("cfi-icall", CFIICall) SANITIZER("cfi-unrelated-cast", CFIUnrelatedCast) SANITIZER("cfi-nvcall", CFINVCall) SANITIZER("cfi-vcall", CFIVCall) SANITIZER_GROUP("cfi", CFI, - CFIDerivedCast | CFIUnrelatedCast | CFINVCall | CFIVCall) + CFIDerivedCast | CFIICall | CFIUnrelatedCast | CFINVCall | + CFIVCall) // Safe Stack SANITIZER("safe-stack", SafeStack) diff --git a/contrib/llvm/tools/clang/include/clang/Basic/SourceLocation.h b/contrib/llvm/tools/clang/include/clang/Basic/SourceLocation.h index 7aaee1d..0aeba5e 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/SourceLocation.h +++ b/contrib/llvm/tools/clang/include/clang/Basic/SourceLocation.h @@ -43,6 +43,7 @@ class FileID { public: FileID() : ID(0) {} + bool isValid() const { return ID != 0; } bool isInvalid() const { return ID == 0; } bool operator==(const FileID &RHS) const { return ID == RHS.ID; } @@ -252,7 +253,7 @@ public: SourceLocation getBegin() const { return Range.getBegin(); } SourceLocation getEnd() const { return Range.getEnd(); } - const SourceRange &getAsRange() const { return Range; } + SourceRange getAsRange() const { return Range; } void setBegin(SourceLocation b) { Range.setBegin(b); } void setEnd(SourceLocation e) { Range.setEnd(e); } diff --git a/contrib/llvm/tools/clang/include/clang/Basic/SourceManager.h b/contrib/llvm/tools/clang/include/clang/Basic/SourceManager.h index 3aea5ea..99392a0 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/SourceManager.h +++ b/contrib/llvm/tools/clang/include/clang/Basic/SourceManager.h @@ -39,6 +39,7 @@ #include "clang/Basic/LLVM.h" #include "clang/Basic/SourceLocation.h" #include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/BitVector.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/IntrusiveRefCntPtr.h" @@ -121,7 +122,7 @@ namespace SrcMgr { /// \brief The number of lines in this ContentCache. /// /// This is only valid if SourceLineCache is non-null. - unsigned NumLines : 31; + unsigned NumLines; /// \brief Indicates whether the buffer itself was provided to override /// the actual file contents. @@ -134,12 +135,17 @@ namespace SrcMgr { /// file considered as a system one. unsigned IsSystemFile : 1; + /// \brief True if this file may be transient, that is, if it might not + /// exist at some later point in time when this content entry is used, + /// after serialization and deserialization. + unsigned IsTransient : 1; + ContentCache(const FileEntry *Ent = nullptr) : ContentCache(Ent, Ent) {} ContentCache(const FileEntry *Ent, const FileEntry *contentEnt) : Buffer(nullptr, false), OrigEntry(Ent), ContentsEntry(contentEnt), SourceLineCache(nullptr), NumLines(0), BufferOverridden(false), - IsSystemFile(false) {} + IsSystemFile(false), IsTransient(false) {} ~ContentCache(); @@ -148,7 +154,7 @@ namespace SrcMgr { /// is not transferred, so this is a logical error. ContentCache(const ContentCache &RHS) : Buffer(nullptr, false), SourceLineCache(nullptr), - BufferOverridden(false), IsSystemFile(false) { + BufferOverridden(false), IsSystemFile(false), IsTransient(false) { OrigEntry = RHS.OrigEntry; ContentsEntry = RHS.ContentsEntry; @@ -388,15 +394,16 @@ namespace SrcMgr { /// SourceManager keeps an array of these objects, and they are uniquely /// identified by the FileID datatype. class SLocEntry { - unsigned Offset; // low bit is set for expansion info. + unsigned Offset : 31; + unsigned IsExpansion : 1; union { FileInfo File; ExpansionInfo Expansion; }; public: - unsigned getOffset() const { return Offset >> 1; } + unsigned getOffset() const { return Offset; } - bool isExpansion() const { return Offset & 1; } + bool isExpansion() const { return IsExpansion; } bool isFile() const { return !isExpansion(); } const FileInfo &getFile() const { @@ -410,15 +417,19 @@ namespace SrcMgr { } static SLocEntry get(unsigned Offset, const FileInfo &FI) { + assert(!(Offset & (1 << 31)) && "Offset is too large"); SLocEntry E; - E.Offset = Offset << 1; + E.Offset = Offset; + E.IsExpansion = false; E.File = FI; return E; } static SLocEntry get(unsigned Offset, const ExpansionInfo &Expansion) { + assert(!(Offset & (1 << 31)) && "Offset is too large"); SLocEntry E; - E.Offset = (Offset << 1) | 1; + E.Offset = Offset; + E.IsExpansion = true; E.Expansion = Expansion; return E; } @@ -560,6 +571,11 @@ class SourceManager : public RefCountedBase<SourceManager> { /// (likely to change while trying to use them). Defaults to false. bool UserFilesAreVolatile; + /// \brief True if all files read during this compilation should be treated + /// as transient (may not be present in later compilations using a module + /// file created from this compilation). Defaults to false. + bool FilesAreTransient; + struct OverriddenFilesInfoTy { /// \brief Files that have been overridden with the contents from another /// file. @@ -615,7 +631,7 @@ class SourceManager : public RefCountedBase<SourceManager> { /// have already been loaded from the external source. /// /// Same indexing as LoadedSLocEntryTable. - std::vector<bool> SLocEntryLoaded; + llvm::BitVector SLocEntryLoaded; /// \brief An external source for source location entries. ExternalSLocEntrySource *ExternalSLocEntries; @@ -851,6 +867,15 @@ public: /// This should be called before parsing has begun. void disableFileContentsOverride(const FileEntry *File); + /// \brief Specify that a file is transient. + void setFileIsTransient(const FileEntry *SourceFile); + + /// \brief Specify that all files that are read during this compilation are + /// transient. + void setAllFilesAreTransient(bool Transient) { + FilesAreTransient = Transient; + } + //===--------------------------------------------------------------------===// // FileID manipulation methods. //===--------------------------------------------------------------------===// @@ -1139,10 +1164,14 @@ public: /// \brief Tests whether the given source location represents a macro /// argument's expansion into the function-like macro definition. /// + /// \param StartLoc If non-null and function returns true, it is set to the + /// start location of the macro argument expansion. + /// /// Such source locations only appear inside of the expansion /// locations representing where a particular function-like macro was /// expanded. - bool isMacroArgExpansion(SourceLocation Loc) const; + bool isMacroArgExpansion(SourceLocation Loc, + SourceLocation *StartLoc = nullptr) const; /// \brief Tests whether the given source location represents the expansion of /// a macro body. @@ -1463,6 +1492,8 @@ public: /// void PrintStats() const; + void dump() const; + /// \brief Get the number of local SLocEntries we have. unsigned local_sloc_entry_size() const { return LocalSLocEntryTable.size(); } diff --git a/contrib/llvm/tools/clang/include/clang/Basic/Specifiers.h b/contrib/llvm/tools/clang/include/clang/Basic/Specifiers.h index d95a77f..1d59d64 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/Specifiers.h +++ b/contrib/llvm/tools/clang/include/clang/Basic/Specifiers.h @@ -18,6 +18,7 @@ #include "llvm/ADT/StringRef.h" #include "llvm/Support/DataTypes.h" +#include "llvm/Support/ErrorHandling.h" namespace clang { /// \brief Specifies the width of a type, e.g., short, long, or long long. @@ -64,6 +65,7 @@ namespace clang { TST_underlyingType, // __underlying_type for C++11 TST_auto, // C++11 auto TST_decltype_auto, // C++1y decltype(auto) + TST_auto_type, // __auto_type extension TST_unknown_anytype, // __unknown_anytype extension TST_atomic, // C11 _Atomic TST_error // erroneous type @@ -156,6 +158,24 @@ namespace clang { return Kind != TSK_Undeclared && Kind != TSK_ExplicitSpecialization; } + /// \brief True if this template specialization kind is an explicit + /// specialization, explicit instantiation declaration, or explicit + /// instantiation definition. + inline bool isTemplateExplicitInstantiationOrSpecialization( + TemplateSpecializationKind Kind) { + switch (Kind) { + case TSK_ExplicitSpecialization: + case TSK_ExplicitInstantiationDeclaration: + case TSK_ExplicitInstantiationDefinition: + return true; + + case TSK_Undeclared: + case TSK_ImplicitInstantiation: + return false; + } + llvm_unreachable("bad template specialization kind"); + } + /// \brief Thread storage-class-specifier. enum ThreadStorageClassSpecifier { TSCS_unspecified, @@ -178,7 +198,6 @@ namespace clang { SC_PrivateExtern, // These are only legal on variables. - SC_OpenCLWorkGroupLocal, SC_Auto, SC_Register }; diff --git a/contrib/llvm/tools/clang/include/clang/Basic/StmtNodes.td b/contrib/llvm/tools/clang/include/clang/Basic/StmtNodes.td index 9d7b6fb..36519ea 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/StmtNodes.td +++ b/contrib/llvm/tools/clang/include/clang/Basic/StmtNodes.td @@ -48,6 +48,10 @@ def CXXCatchStmt : Stmt; def CXXTryStmt : Stmt; def CXXForRangeStmt : Stmt; +// C++ Coroutines TS statements +def CoroutineBodyStmt : Stmt; +def CoreturnStmt : Stmt; + // Expressions def Expr : Stmt<1>; def PredefinedExpr : DStmt<Expr>; @@ -62,6 +66,7 @@ def UnaryOperator : DStmt<Expr>; def OffsetOfExpr : DStmt<Expr>; def UnaryExprOrTypeTraitExpr : DStmt<Expr>; def ArraySubscriptExpr : DStmt<Expr>; +def OMPArraySectionExpr : DStmt<Expr>; def CallExpr : DStmt<Expr>; def MemberExpr : DStmt<Expr>; def CastExpr : DStmt<Expr, 1>; @@ -139,6 +144,11 @@ def MaterializeTemporaryExpr : DStmt<Expr>; def LambdaExpr : DStmt<Expr>; def CXXFoldExpr : DStmt<Expr>; +// C++ Coroutines TS expressions +def CoroutineSuspendExpr : DStmt<Expr, 1>; +def CoawaitExpr : DStmt<CoroutineSuspendExpr>; +def CoyieldExpr : DStmt<CoroutineSuspendExpr>; + // Obj-C Expressions. def ObjCStringLiteral : DStmt<Expr>; def ObjCBoxedExpr : DStmt<Expr>; @@ -170,6 +180,7 @@ def TypoExpr : DStmt<Expr>; // Microsoft Extensions. def MSPropertyRefExpr : DStmt<Expr>; +def MSPropertySubscriptExpr : DStmt<Expr>; def CXXUuidofExpr : DStmt<Expr>; def SEHTryStmt : Stmt; def SEHExceptStmt : Stmt; @@ -204,6 +215,10 @@ def OMPFlushDirective : DStmt<OMPExecutableDirective>; def OMPOrderedDirective : DStmt<OMPExecutableDirective>; def OMPAtomicDirective : DStmt<OMPExecutableDirective>; def OMPTargetDirective : DStmt<OMPExecutableDirective>; +def OMPTargetDataDirective : 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>; diff --git a/contrib/llvm/tools/clang/include/clang/Basic/TargetBuiltins.h b/contrib/llvm/tools/clang/include/clang/Basic/TargetBuiltins.h index b4740c5..623c0b6 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/TargetBuiltins.h +++ b/contrib/llvm/tools/clang/include/clang/Basic/TargetBuiltins.h @@ -185,6 +185,17 @@ namespace clang { LastTSBuiltin }; } + + /// \brief WebAssembly builtins + namespace WebAssembly { + enum { + LastTIBuiltin = clang::Builtin::FirstTSBuiltin-1, +#define BUILTIN(ID, TYPE, ATTRS) BI##ID, +#include "clang/Basic/BuiltinsWebAssembly.def" + LastTSBuiltin + }; + } + } // end namespace clang. #endif diff --git a/contrib/llvm/tools/clang/include/clang/Basic/TargetCXXABI.h b/contrib/llvm/tools/clang/include/clang/Basic/TargetCXXABI.h index 42a976b..67247ea 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/TargetCXXABI.h +++ b/contrib/llvm/tools/clang/include/clang/Basic/TargetCXXABI.h @@ -71,6 +71,11 @@ public: /// /help/topic/com.arm.doc.ihi0059a/IHI0059A_cppabi64.pdf iOS64, + /// WatchOS is a modernisation of the iOS ABI, which roughly means it's + /// the iOS64 ABI ported to 32-bits. The primary difference from iOS64 is + /// that RTTI objects must still be unique at the moment. + WatchOS, + /// The generic AArch64 ABI is also a modified version of the Itanium ABI, /// but it has fewer divergences than the 32-bit ARM ABI. /// @@ -85,6 +90,21 @@ public: /// - representation of member function pointers adjusted as in ARM. GenericMIPS, + /// The WebAssembly ABI is a modified version of the Itanium ABI. + /// + /// The changes from the Itanium ABI are: + /// - representation of member function pointers is adjusted, as in ARM; + /// - member functions are not specially aligned; + /// - constructors and destructors return 'this', as in ARM; + /// - guard variables are 32-bit on wasm32, as in ARM; + /// - unused bits of guard variables are reserved, as in ARM; + /// - inline functions are never key functions, as in ARM; + /// - C++11 POD rules are used for tail padding, as in iOS64. + /// + /// TODO: At present the WebAssembly ABI is not considered stable, so none + /// of these details is necessarily final yet. + WebAssembly, + /// The Microsoft ABI is the ABI used by Microsoft Visual Studio (and /// compatible compilers). /// @@ -120,7 +140,9 @@ public: case GenericARM: case iOS: case iOS64: + case WatchOS: case GenericMIPS: + case WebAssembly: return true; case Microsoft: @@ -137,7 +159,9 @@ public: case GenericARM: case iOS: case iOS64: + case WatchOS: case GenericMIPS: + case WebAssembly: return false; case Microsoft: @@ -146,6 +170,36 @@ public: llvm_unreachable("bad ABI kind"); } + /// \brief Are member functions differently aligned? + /// + /// Many Itanium-style C++ ABIs require member functions to be aligned, so + /// that a pointer to such a function is guaranteed to have a zero in the + /// least significant bit, so that pointers to member functions can use that + /// bit to distinguish between virtual and non-virtual functions. However, + /// some Itanium-style C++ ABIs differentiate between virtual and non-virtual + /// functions via other means, and consequently don't require that member + /// functions be aligned. + bool areMemberFunctionsAligned() const { + switch (getKind()) { + case WebAssembly: + // WebAssembly doesn't require any special alignment for member functions. + return false; + case GenericARM: + case GenericAArch64: + case GenericMIPS: + // TODO: ARM-style pointers to member functions put the discriminator in + // the this adjustment, so they don't require functions to have any + // special alignment and could therefore also return false. + case GenericItanium: + case iOS: + case iOS64: + case WatchOS: + case Microsoft: + return true; + } + llvm_unreachable("bad ABI kind"); + } + /// \brief Is the default C++ member function calling convention /// the same as the default calling convention? bool isMemberFunctionCCDefault() const { @@ -214,6 +268,8 @@ public: switch (getKind()) { case GenericARM: case iOS64: + case WebAssembly: + case WatchOS: return false; case GenericAArch64: @@ -261,7 +317,7 @@ public: switch (getKind()) { // To preserve binary compatibility, the generic Itanium ABI has // permanently locked the definition of POD to the rules of C++ TR1, - // and that trickles down to all the derived ABIs. + // and that trickles down to derived ABIs. case GenericItanium: case GenericAArch64: case GenericARM: @@ -269,9 +325,11 @@ public: case GenericMIPS: return UseTailPaddingUnlessPOD03; - // iOS on ARM64 uses the C++11 POD rules. It does not honor the - // Itanium exception about classes with over-large bitfields. + // iOS on ARM64 and WebAssembly use the C++11 POD rules. They do not honor + // the Itanium exception about classes with over-large bitfields. case iOS64: + case WebAssembly: + case WatchOS: return UseTailPaddingUnlessPOD11; // MSVC always allocates fields in the tail-padding of a base class @@ -282,9 +340,6 @@ public: llvm_unreachable("bad ABI kind"); } - /// Try to parse an ABI name, returning false on error. - bool tryParse(llvm::StringRef name); - friend bool operator==(const TargetCXXABI &left, const TargetCXXABI &right) { return left.getKind() == right.getKind(); } diff --git a/contrib/llvm/tools/clang/include/clang/Basic/TargetInfo.h b/contrib/llvm/tools/clang/include/clang/Basic/TargetInfo.h index 39f575f..f1d8338 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/TargetInfo.h +++ b/contrib/llvm/tools/clang/include/clang/Basic/TargetInfo.h @@ -22,6 +22,8 @@ #include "clang/Basic/TargetOptions.h" #include "clang/Basic/VersionTuple.h" #include "llvm/ADT/IntrusiveRefCntPtr.h" +#include "llvm/ADT/APInt.h" +#include "llvm/ADT/SmallSet.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringSwitch.h" @@ -72,7 +74,7 @@ protected: unsigned short MaxVectorAlign; unsigned short MaxTLSAlign; unsigned short SimdDefaultAlign; - const char *DescriptionString; + const char *DataLayoutString; const char *UserLabelPrefix; const char *MCountName; const llvm::fltSemantics *HalfFormat, *FloatFormat, *DoubleFormat, @@ -88,6 +90,8 @@ protected: unsigned RealTypeUsesObjCFPRet : 3; unsigned ComplexLongDoubleUsesFP2Ret : 1; + unsigned HasBuiltinMSVaList : 1; + // TargetInfo Constructor. Default initializes all fields. TargetInfo(const llvm::Triple &T); @@ -104,9 +108,9 @@ public: virtual ~TargetInfo(); /// \brief Retrieve the target options. - TargetOptions &getTargetOpts() const { + TargetOptions &getTargetOpts() const { assert(TargetOpts && "Missing target options"); - return *TargetOpts; + return *TargetOpts; } ///===---- Target Data Type Query Methods -------------------------------===// @@ -253,10 +257,11 @@ public: unsigned getTypeWidth(IntType T) const; /// \brief Return integer type with specified width. - IntType getIntTypeByWidth(unsigned BitWidth, bool IsSigned) const; + virtual IntType getIntTypeByWidth(unsigned BitWidth, bool IsSigned) const; /// \brief Return the smallest integer type with at least the specified width. - IntType getLeastIntTypeByWidth(unsigned BitWidth, bool IsSigned) const; + virtual IntType getLeastIntTypeByWidth(unsigned BitWidth, + bool IsSigned) const; /// \brief Return floating point type with specified width. RealType getRealTypeByWidth(unsigned BitWidth) const; @@ -311,7 +316,9 @@ public: unsigned getLongLongAlign() const { return LongLongAlign; } /// \brief Determine whether the __int128 type is supported on this target. - virtual bool hasInt128Type() const { return getPointerWidth(0) >= 64; } // FIXME + virtual bool hasInt128Type() const { + return getPointerWidth(0) >= 64; + } // FIXME /// \brief Return the alignment that is suitable for storing any /// object with a fundamental alignment requirement. @@ -509,8 +516,7 @@ public: /// Return information about target-specific builtins for /// the current primary target, and info about which builtins are non-portable /// across the current set of primary and secondary targets. - virtual void getTargetBuiltins(const Builtin::Info *&Records, - unsigned &NumRecords) const = 0; + virtual ArrayRef<Builtin::Info> getTargetBuiltins() const = 0; /// The __builtin_clz* and __builtin_ctz* built-in /// functions are specified to have undefined results for zero inputs, but @@ -523,6 +529,10 @@ public: /// with this target. virtual BuiltinVaListKind getBuiltinVaListKind() const = 0; + /// Returns whether or not type \c __builtin_ms_va_list type is + /// available on this target. + bool hasBuiltinMSVaList() const { return HasBuiltinMSVaList; } + /// \brief Returns whether the passed in string is a valid clobber in an /// inline asm statement. /// @@ -556,6 +566,7 @@ public: int Min; int Max; } ImmRange; + llvm::SmallSet<int, 4> ImmSet; std::string ConstraintStr; // constraint: "=rm" std::string Name; // Operand name: [foo] with no []'s. @@ -591,8 +602,10 @@ public: bool requiresImmediateConstant() const { return (Flags & CI_ImmediateConstant) != 0; } - int getImmConstantMin() const { return ImmRange.Min; } - int getImmConstantMax() const { return ImmRange.Max; } + bool isValidAsmImmediate(const llvm::APInt &Value) const { + return (Value.sge(ImmRange.Min) && Value.sle(ImmRange.Max)) || + ImmSet.count(Value.getZExtValue()) != 0; + } void setIsReadWrite() { Flags |= CI_ReadWrite; } void setEarlyClobber() { Flags |= CI_EarlyClobber; } @@ -604,9 +617,23 @@ public: ImmRange.Min = Min; ImmRange.Max = Max; } + void setRequiresImmediate(llvm::ArrayRef<int> Exacts) { + Flags |= CI_ImmediateConstant; + for (int Exact : Exacts) + ImmSet.insert(Exact); + } + void setRequiresImmediate(int Exact) { + Flags |= CI_ImmediateConstant; + ImmSet.insert(Exact); + } + void setRequiresImmediate() { + Flags |= CI_ImmediateConstant; + ImmRange.Min = INT_MIN; + ImmRange.Max = INT_MAX; + } /// \brief Indicate that this is an input operand that is tied to - /// the specified output operand. + /// the specified output operand. /// /// Copy over the various constraint information from the output. void setTiedOperand(unsigned N, ConstraintInfo &Output) { @@ -617,15 +644,24 @@ public: } }; - // Validate the contents of the __builtin_cpu_supports(const char*) argument. - virtual bool validateCpuSupports(StringRef Name) const { return false; } + /// \brief Validate register name used for global register variables. + /// + /// This function returns true if the register passed in RegName can be used + /// for global register variables on this target. In addition, it returns + /// true in HasSizeMismatch if the size of the register doesn't match the + /// variable size passed in RegSize. + virtual bool validateGlobalRegisterVariable(StringRef RegName, + unsigned RegSize, + bool &HasSizeMismatch) const { + HasSizeMismatch = false; + return true; + } // validateOutputConstraint, validateInputConstraint - Checks that // a constraint is valid and provides information about it. // FIXME: These should return a real error instead of just true/false. bool validateOutputConstraint(ConstraintInfo &Info) const; - bool validateInputConstraint(ConstraintInfo *OutputConstraints, - unsigned NumOutputs, + bool validateInputConstraint(MutableArrayRef<ConstraintInfo> OutputConstraints, ConstraintInfo &info) const; virtual bool validateOutputSize(StringRef /*Constraint*/, @@ -644,9 +680,13 @@ public: std::string &/*SuggestedModifier*/) const { return true; } + virtual bool + validateAsmConstraint(const char *&Name, + TargetInfo::ConstraintInfo &info) const = 0; + bool resolveSymbolicName(const char *&Name, - ConstraintInfo *OutputConstraints, - unsigned NumOutputs, unsigned &Index) const; + ArrayRef<ConstraintInfo> OutputConstraints, + unsigned &Index) const; // Constraint parm will be left pointing at the last character of // the constraint. In practice, it won't be changed unless the @@ -658,24 +698,23 @@ public: return std::string(1, *Constraint); } + /// \brief Returns a string of target-specific clobbers, in LLVM format. + virtual const char *getClobbers() const = 0; + /// \brief Returns true if NaN encoding is IEEE 754-2008. /// Only MIPS allows a different encoding. virtual bool isNan2008() const { return true; } - /// \brief Returns a string of target-specific clobbers, in LLVM format. - virtual const char *getClobbers() const = 0; - - /// \brief Returns the target triple of the primary target. const llvm::Triple &getTriple() const { return Triple; } - const char *getTargetDescription() const { - assert(DescriptionString); - return DescriptionString; + const char *getDataLayoutString() const { + assert(DataLayoutString && "Uninitialized DataLayoutString!"); + return DataLayoutString; } struct GCCRegAlias { @@ -721,10 +760,13 @@ public: /// language options which change the target configuration. virtual void adjust(const LangOptions &Opts); - /// \brief Get the default set of target features for the CPU; - /// this should include all legal feature strings on the target. - virtual void getDefaultFeatures(llvm::StringMap<bool> &Features) const { - } + /// \brief Initialize the map with the default set of target features for the + /// CPU this should include all legal feature strings on the target. + /// + /// \return False on error (invalid features). + virtual bool initFeatureMap(llvm::StringMap<bool> &Features, + DiagnosticsEngine &Diags, StringRef CPU, + const std::vector<std::string> &FeatureVec) const; /// \brief Get the ABI currently in use. virtual StringRef getABI() const { return StringRef(); } @@ -755,23 +797,6 @@ public: return false; } - /// \brief Use this specified C++ ABI. - /// - /// \return False on error (invalid C++ ABI name). - bool setCXXABI(llvm::StringRef name) { - TargetCXXABI ABI; - if (!ABI.tryParse(name)) return false; - return setCXXABI(ABI); - } - - /// \brief Set the C++ ABI to be used by this implementation. - /// - /// \return False on error (ABI not valid on this target) - virtual bool setCXXABI(TargetCXXABI ABI) { - TheCXXABI = ABI; - return true; - } - /// \brief Enable or disable a specific target feature; /// the feature name must be valid. virtual void setFeatureEnabled(llvm::StringMap<bool> &Features, @@ -787,6 +812,8 @@ public: /// /// The target may modify the features list, to change which options are /// passed onwards to the backend. + /// FIXME: This part should be fixed so that we can change handleTargetFeatures + /// to merely a TargetInfo initialization routine. /// /// \return False on error. virtual bool handleTargetFeatures(std::vector<std::string> &Features, @@ -798,7 +825,11 @@ public: virtual bool hasFeature(StringRef Feature) const { return false; } - + + // \brief Validate the contents of the __builtin_cpu_supports(const char*) + // argument. + virtual bool validateCpuSupports(StringRef Name) const { return false; } + // \brief Returns maximal number of args passed in registers. unsigned getRegParmMax() const { assert(RegParmMax < 7 && "RegParmMax value is larger than AST can handle"); @@ -882,7 +913,7 @@ public: }; /// \brief Determines whether a given calling convention is valid for the - /// target. A calling convention can either be accepted, produce a warning + /// target. A calling convention can either be accepted, produce a warning /// and be substituted with the default calling convention, or (someday) /// produce an error (such as using thiscall on a non-instance function). virtual CallingConvCheckResult checkCallingConvention(CallingConv CC) const { @@ -910,17 +941,11 @@ protected: virtual enum IntType getPtrDiffTypeV(unsigned AddrSpace) const { return PtrDiffType; } - virtual void getGCCRegNames(const char * const *&Names, - unsigned &NumNames) const = 0; - virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, - unsigned &NumAliases) const = 0; - virtual void getGCCAddlRegNames(const AddlRegName *&Addl, - unsigned &NumAddl) const { - Addl = nullptr; - NumAddl = 0; - } - virtual bool validateAsmConstraint(const char *&Name, - TargetInfo::ConstraintInfo &info) const= 0; + virtual ArrayRef<const char *> getGCCRegNames() const = 0; + virtual ArrayRef<GCCRegAlias> getGCCRegAliases() const = 0; + virtual ArrayRef<AddlRegName> getGCCAddlRegNames() const { + return None; + } }; } // end namespace clang diff --git a/contrib/llvm/tools/clang/include/clang/Basic/TokenKinds.def b/contrib/llvm/tools/clang/include/clang/Basic/TokenKinds.def index 8333a4c..9252d99 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/TokenKinds.def +++ b/contrib/llvm/tools/clang/include/clang/Basic/TokenKinds.def @@ -242,6 +242,8 @@ PUNCTUATOR(greatergreatergreater, ">>>") // KEYZVECTOR - This is a keyword for the System z vector extensions, // which are heavily based on AltiVec // KEYBORLAND - This is a keyword if Borland extensions are enabled +// KEYCOROUTINES - This is a keyword if support for the C++ coroutines +// TS is enabled // BOOLSUPPORT - This is a keyword if 'bool' is a built-in type // HALFSUPPORT - This is a keyword if 'half' is a built-in type // WCHARSUPPORT - This is a keyword if 'wchar_t' is a built-in type @@ -282,7 +284,7 @@ KEYWORD(volatile , KEYALL) KEYWORD(while , KEYALL) KEYWORD(_Alignas , KEYALL) KEYWORD(_Alignof , KEYALL) -KEYWORD(_Atomic , KEYALL|KEYNOMS18|KEYNOOPENCL) +KEYWORD(_Atomic , KEYALL|KEYNOOPENCL) KEYWORD(_Bool , KEYNOCXX) KEYWORD(_Complex , KEYALL) KEYWORD(_Generic , KEYALL) @@ -356,6 +358,11 @@ CXX11_KEYWORD(thread_local , 0) CONCEPTS_KEYWORD(concept) CONCEPTS_KEYWORD(requires) +// C++ coroutines TS keywords +KEYWORD(co_await , KEYCOROUTINES) +KEYWORD(co_return , KEYCOROUTINES) +KEYWORD(co_yield , KEYCOROUTINES) + // GNU Extensions (in impl-reserved namespace) KEYWORD(_Decimal32 , KEYALL) KEYWORD(_Decimal64 , KEYALL) @@ -377,6 +384,7 @@ KEYWORD(__real , KEYALL) KEYWORD(__thread , KEYALL) KEYWORD(__FUNCTION__ , KEYALL) KEYWORD(__PRETTY_FUNCTION__ , KEYALL) +KEYWORD(__auto_type , KEYALL) // GNU Extensions (outside impl-reserved namespace) KEYWORD(typeof , KEYGNU) @@ -469,8 +477,11 @@ KEYWORD(__array_extent , KEYCXX) KEYWORD(__private_extern__ , KEYALL) KEYWORD(__module_private__ , KEYALL) +// Extension that will be enabled for Microsoft, Borland and PS4, but can be +// disabled via '-fno-declspec'. +KEYWORD(__declspec , 0) + // Microsoft Extension. -KEYWORD(__declspec , KEYMS|KEYBORLAND) KEYWORD(__cdecl , KEYALL) KEYWORD(__stdcall , KEYALL) KEYWORD(__fastcall , KEYALL) diff --git a/contrib/llvm/tools/clang/include/clang/Basic/VirtualFileSystem.h b/contrib/llvm/tools/clang/include/clang/Basic/VirtualFileSystem.h index 1c65fb5..1df4947 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/VirtualFileSystem.h +++ b/contrib/llvm/tools/clang/include/clang/Basic/VirtualFileSystem.h @@ -45,14 +45,18 @@ public: public: Status() : Type(llvm::sys::fs::file_type::status_error) {} Status(const llvm::sys::fs::file_status &Status); - Status(StringRef Name, StringRef RealName, llvm::sys::fs::UniqueID UID, + Status(StringRef Name, llvm::sys::fs::UniqueID UID, llvm::sys::TimeValue MTime, uint32_t User, uint32_t Group, uint64_t Size, llvm::sys::fs::file_type Type, llvm::sys::fs::perms Perms); + /// Get a copy of a Status with a different name. + static Status copyWithNewName(const Status &In, StringRef NewName); + static Status copyWithNewName(const llvm::sys::fs::file_status &In, + StringRef NewName); + /// \brief Returns the name that should be used for this file or directory. StringRef getName() const { return Name; } - void setName(StringRef N) { Name = N; } /// @name Status interface from llvm::sys::fs /// @{ @@ -63,8 +67,6 @@ public: uint32_t getUser() const { return User; } uint32_t getGroup() const { return Group; } uint64_t getSize() const { return Size; } - void setType(llvm::sys::fs::file_type v) { Type = v; } - void setPermissions(llvm::sys::fs::perms p) { Perms = p; } /// @} /// @name Status queries /// These are static queries in llvm::sys::fs. @@ -94,8 +96,6 @@ public: bool RequiresNullTerminator = true, bool IsVolatile = false) = 0; /// \brief Closes the file. virtual std::error_code close() = 0; - /// \brief Sets the name to use for this file. - virtual void setName(StringRef Name) = 0; }; namespace detail { @@ -199,6 +199,28 @@ public: /// \note The 'end' iterator is directory_iterator(). virtual directory_iterator dir_begin(const Twine &Dir, std::error_code &EC) = 0; + + /// Set the working directory. This will affect all following operations on + /// this file system and may propagate down for nested file systems. + virtual std::error_code setCurrentWorkingDirectory(const Twine &Path) = 0; + /// Get the working directory of this file system. + virtual llvm::ErrorOr<std::string> getCurrentWorkingDirectory() const = 0; + + /// Check whether a file exists. Provided for convenience. + bool exists(const Twine &Path); + + /// Make \a Path an absolute path. + /// + /// Makes \a Path absolute using the current directory if it is not already. + /// An empty \a Path will result in the current directory. + /// + /// /absolute/path => /absolute/path + /// relative/../path => <current-directory>/relative/../path + /// + /// \param Path A path that is modified to be an absolute path. + /// \returns success if \a path has been made absolute, otherwise a + /// platform-specific error_code. + std::error_code makeAbsolute(SmallVectorImpl<char> &Path) const; }; /// \brief Gets an \p vfs::FileSystem for the 'real' file system, as seen by @@ -230,6 +252,8 @@ public: llvm::ErrorOr<std::unique_ptr<File>> openFileForRead(const Twine &Path) override; directory_iterator dir_begin(const Twine &Dir, std::error_code &EC) override; + llvm::ErrorOr<std::string> getCurrentWorkingDirectory() const override; + std::error_code setCurrentWorkingDirectory(const Twine &Path) override; typedef FileSystemList::reverse_iterator iterator; @@ -241,6 +265,46 @@ public: iterator overlays_end() { return FSList.rend(); } }; +namespace detail { +class InMemoryDirectory; +} // end namespace detail + +/// An in-memory file system. +class InMemoryFileSystem : public FileSystem { + std::unique_ptr<detail::InMemoryDirectory> Root; + std::string WorkingDirectory; + bool UseNormalizedPaths = true; + +public: + explicit InMemoryFileSystem(bool UseNormalizedPaths = true); + ~InMemoryFileSystem() override; + /// Add a buffer to the VFS with a path. The VFS owns the buffer. + /// \return true if the file was successfully added, false if the file already + /// exists in the file system with different contents. + bool addFile(const Twine &Path, time_t ModificationTime, + std::unique_ptr<llvm::MemoryBuffer> Buffer); + /// Add a buffer to the VFS with a path. The VFS does not own the buffer. + /// \return true if the file was successfully added, false if the file already + /// exists in the file system with different contents. + bool addFileNoOwn(const Twine &Path, time_t ModificationTime, + llvm::MemoryBuffer *Buffer); + std::string toString() const; + /// Return true if this file system normalizes . and .. in paths. + bool useNormalizedPaths() const { return UseNormalizedPaths; } + + llvm::ErrorOr<Status> status(const Twine &Path) override; + llvm::ErrorOr<std::unique_ptr<File>> + openFileForRead(const Twine &Path) override; + directory_iterator dir_begin(const Twine &Dir, std::error_code &EC) override; + llvm::ErrorOr<std::string> getCurrentWorkingDirectory() const override { + return WorkingDirectory; + } + std::error_code setCurrentWorkingDirectory(const Twine &Path) override { + WorkingDirectory = Path.str(); + return std::error_code(); + } +}; + /// \brief Get a globally unique ID for a virtual file or directory. llvm::sys::fs::UniqueID getNextVirtualUniqueID(); diff --git a/contrib/llvm/tools/clang/include/clang/Basic/arm_neon.td b/contrib/llvm/tools/clang/include/clang/Basic/arm_neon.td index c6f8795..6d95c1e 100644 --- a/contrib/llvm/tools/clang/include/clang/Basic/arm_neon.td +++ b/contrib/llvm/tools/clang/include/clang/Basic/arm_neon.td @@ -373,6 +373,10 @@ def OP_QDMLSLHi_LN : Op<(call "vqdmlsl", $p0, (call "vget_high", $p1), (splat $p2, $p3))>; def OP_QDMULH_LN : Op<(call "vqdmulh", $p0, (splat $p1, $p2))>; def OP_QRDMULH_LN : Op<(call "vqrdmulh", $p0, (splat $p1, $p2))>; +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_TRN1 : Op<(shuffle $p0, $p1, (interleave (decimate mask0, 2), @@ -414,7 +418,7 @@ def OP_XTN : Op<(call "vcombine", $p0, (call "vmovn", $p1))>; def OP_SQXTUN : Op<(call "vcombine", (cast $p0, "U", $p0), (call "vqmovun", $p1))>; def OP_QXTN : Op<(call "vcombine", $p0, (call "vqmovn", $p1))>; -def OP_VCVT_NA_HI_F16 : Op<(call "vcombine", $p0, (call "vcvt_f16", $p1))>; +def OP_VCVT_NA_HI_F16 : Op<(call "vcombine", $p0, (call "vcvt_f16_f32", $p1))>; def OP_VCVT_NA_HI_F32 : Op<(call "vcombine", $p0, (call "vcvt_f32_f64", $p1))>; def OP_VCVT_EX_HI_F32 : Op<(call "vcvt_f32_f16", (call "vget_high", $p0))>; def OP_VCVT_EX_HI_F64 : Op<(call "vcvt_f64_f32", (call "vget_high", $p0))>; @@ -473,6 +477,11 @@ def OP_SCALAR_QDMULL_LN : ScalarMulOp<"vqdmull">; def OP_SCALAR_QDMULH_LN : ScalarMulOp<"vqdmulh">; def OP_SCALAR_QRDMULH_LN : ScalarMulOp<"vqrdmulh">; +def OP_SCALAR_QRDMLAH_LN : Op<(call "vqadd", $p0, (call "vqrdmulh", $p1, + (call "vget_lane", $p2, $p3)))>; +def OP_SCALAR_QRDMLSH_LN : Op<(call "vqsub", $p0, (call "vqrdmulh", $p1, + (call "vget_lane", $p2, $p3)))>; + def OP_SCALAR_HALF_GET_LN : Op<(bitcast "float16_t", (call "vget_lane", (bitcast "int16x4_t", $p0), $p1))>; @@ -514,6 +523,12 @@ def VMLS : IOpInst<"vmls", "dddd", "csifUcUsUiQcQsQiQfQUcQUsQUi", OP_MLS>; def VMLSL : SOpInst<"vmlsl", "wwdd", "csiUcUsUi", OP_MLSL>; def VQDMULH : SInst<"vqdmulh", "ddd", "siQsQi">; def VQRDMULH : SInst<"vqrdmulh", "ddd", "siQsQi">; + +let ArchGuard = "defined(__ARM_FEATURE_QRDMX)" in { +def VQRDMLAH : SOpInst<"vqrdmlah", "dddd", "siQsQi", OP_QRDMLAH>; +def VQRDMLSH : SOpInst<"vqrdmlsh", "dddd", "siQsQi", OP_QRDMLSH>; +} + def VQDMLAL : SInst<"vqdmlal", "wwdd", "si">; def VQDMLSL : SInst<"vqdmlsl", "wwdd", "si">; def VMULL : SInst<"vmull", "wdd", "csiUcUsUiPc">; @@ -687,16 +702,19 @@ 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">; + def VCVT_S32 : SInst<"vcvt_s32", "xd", "fQf">; def VCVT_U32 : SInst<"vcvt_u32", "ud", "fQf">; -def VCVT_F16 : SInst<"vcvt_f16", "hk", "f">; def VCVT_F32 : SInst<"vcvt_f32", "fd", "iUiQiQUi">; -def VCVT_F32_F16 : SInst<"vcvt_f32_f16", "fd", "h">; let isVCVT_N = 1 in { def VCVT_N_S32 : SInst<"vcvt_n_s32", "xdi", "fQf">; def VCVT_N_U32 : SInst<"vcvt_n_u32", "udi", "fQf">; def VCVT_N_F32 : SInst<"vcvt_n_f32", "fdi", "iUiQiQUi">; } + def VMOVN : IInst<"vmovn", "hk", "silUsUiUl">; def VMOVL : SInst<"vmovl", "wd", "csiUcUsUi">; def VQMOVN : SInst<"vqmovn", "hk", "silUsUiUl">; @@ -738,6 +756,12 @@ def VQDMULH_N : SInst<"vqdmulh_n", "dda", "siQsQi">; def VQDMULH_LANE : SOpInst<"vqdmulh_lane", "ddgi", "siQsQi", OP_QDMULH_LN>; def VQRDMULH_N : SInst<"vqrdmulh_n", "dda", "siQsQi">; def VQRDMULH_LANE : SOpInst<"vqrdmulh_lane", "ddgi", "siQsQi", OP_QRDMULH_LN>; + +let ArchGuard = "defined(__ARM_FEATURE_QRDMX)" in { +def VQRDMLAH_LANE : SOpInst<"vqrdmlah_lane", "dddgi", "siQsQi", OP_QRDMLAH_LN>; +def VQRDMLSH_LANE : SOpInst<"vqrdmlsh_lane", "dddgi", "siQsQi", OP_QRDMLSH_LN>; +} + def VMLA_N : IOpInst<"vmla_n", "ddda", "siUsUifQsQiQUsQUiQf", OP_MLA_N>; def VMLAL_N : SOpInst<"vmlal_n", "wwda", "siUsUi", OP_MLAL_N>; def VQDMLAL_N : SInst<"vqdmlal_n", "wwda", "si">; @@ -923,6 +947,9 @@ def USQADD : SInst<"vsqadd", "ddd", "UcUsUiUlQUcQUsQUiQUl">; // Reciprocal/Sqrt def FRECPS : IInst<"vrecps", "ddd", "dQd">; def FRSQRTS : IInst<"vrsqrts", "ddd", "dQd">; +def FRECPE : SInst<"vrecpe", "dd", "dQd">; +def FRSQRTE : SInst<"vrsqrte", "dd", "dQd">; +def FSQRT : SInst<"vsqrt", "dd", "fdQfQd">; //////////////////////////////////////////////////////////////////////////////// // bitwise reverse @@ -942,20 +969,21 @@ def QXTN2 : SOpInst<"vqmovn_high", "qhk", "silUsUiUl", OP_QXTN>; //////////////////////////////////////////////////////////////////////////////// // Converting vectors -def VCVT_HIGH_F16 : SOpInst<"vcvt_high_f16", "qhj", "f", OP_VCVT_NA_HI_F16>; -def VCVT_HIGH_F32_F16 : SOpInst<"vcvt_high_f32", "wk", "h", OP_VCVT_EX_HI_F32>; + def VCVT_F32_F64 : SInst<"vcvt_f32_f64", "md", "Qd">; -def VCVT_HIGH_F32_F64 : SOpInst<"vcvt_high_f32", "qfj", "d", OP_VCVT_NA_HI_F32>; def VCVT_F64_F32 : SInst<"vcvt_f64_f32", "wd", "f">; + +def VCVT_S64 : SInst<"vcvt_s64", "xd", "dQd">; +def VCVT_U64 : SInst<"vcvt_u64", "ud", "dQd">; def VCVT_F64 : SInst<"vcvt_f64", "Fd", "lUlQlQUl">; + +def VCVT_HIGH_F16_F32 : SOpInst<"vcvt_high_f16", "hmj", "Hf", OP_VCVT_NA_HI_F16>; +def VCVT_HIGH_F32_F16 : SOpInst<"vcvt_high_f32", "wk", "h", OP_VCVT_EX_HI_F32>; +def VCVT_HIGH_F32_F64 : SOpInst<"vcvt_high_f32", "qfj", "d", OP_VCVT_NA_HI_F32>; def VCVT_HIGH_F64_F32 : SOpInst<"vcvt_high_f64", "wj", "f", OP_VCVT_EX_HI_F64>; -def VCVTX_F32_F64 : SInst<"vcvtx_f32", "fj", "d">; + +def VCVTX_F32_F64 : SInst<"vcvtx_f32", "fj", "d">; def VCVTX_HIGH_F32_F64 : SOpInst<"vcvtx_high_f32", "qfj", "d", OP_VCVTX_HI>; -def VCVT_S64 : SInst<"vcvt_s64", "xd", "dQd">; -def VCVT_U64 : SInst<"vcvt_u64", "ud", "dQd">; -def FRECPE : SInst<"vrecpe", "dd", "dQd">; -def FRSQRTE : SInst<"vrsqrte", "dd", "dQd">; -def FSQRT : SInst<"vsqrt", "dd", "fdQfQd">; //////////////////////////////////////////////////////////////////////////////// // Comparison @@ -1153,6 +1181,11 @@ def VQDMULL_HIGH_LANEQ : SOpInst<"vqdmull_high_laneq", "wkki", "si", def VQDMULH_LANEQ : SOpInst<"vqdmulh_laneq", "ddji", "siQsQi", OP_QDMULH_LN>; def VQRDMULH_LANEQ : SOpInst<"vqrdmulh_laneq", "ddji", "siQsQi", OP_QRDMULH_LN>; +let ArchGuard = "defined(__ARM_FEATURE_QRDMX) && defined(__aarch64__)" in { +def VQRDMLAH_LANEQ : SOpInst<"vqrdmlah_laneq", "dddji", "siQsQi", OP_QRDMLAH_LN>; +def VQRDMLSH_LANEQ : SOpInst<"vqrdmlsh_laneq", "dddji", "siQsQi", OP_QRDMLSH_LN>; +} + // Note: d type implemented by SCALAR_VMULX_LANE def VMULX_LANE : IOpInst<"vmulx_lane", "ddgi", "fQfQd", OP_MULX_LN>; // Note: d type is implemented by SCALAR_VMULX_LANEQ @@ -1398,6 +1431,16 @@ def SCALAR_SQDMULH : SInst<"vqdmulh", "sss", "SsSi">; // Scalar Integer Saturating Rounding Doubling Multiply Half High def SCALAR_SQRDMULH : SInst<"vqrdmulh", "sss", "SsSi">; +let ArchGuard = "defined(__ARM_FEATURE_QRDMX) && defined(__aarch64__)" in { +//////////////////////////////////////////////////////////////////////////////// +// Signed Saturating Rounding Doubling Multiply Accumulate Returning High Half +def SCALAR_SQRDMLAH : SOpInst<"vqrdmlah", "ssss", "SsSi", OP_QRDMLAH>; + +//////////////////////////////////////////////////////////////////////////////// +// Signed Saturating Rounding Doubling Multiply Subtract Returning High Half +def SCALAR_SQRDMLSH : SOpInst<"vqrdmlsh", "ssss", "SsSi", OP_QRDMLSH>; +} + //////////////////////////////////////////////////////////////////////////////// // Scalar Floating-point Multiply Extended def SCALAR_FMULX : IInst<"vmulx", "sss", "SfSd">; @@ -1599,6 +1642,16 @@ def SCALAR_SQDMULH_LANEQ : SOpInst<"vqdmulh_laneq", "ssji", "SsSi", OP_SCALAR_QD def SCALAR_SQRDMULH_LANE : SOpInst<"vqrdmulh_lane", "ssdi", "SsSi", OP_SCALAR_QRDMULH_LN>; def SCALAR_SQRDMULH_LANEQ : SOpInst<"vqrdmulh_laneq", "ssji", "SsSi", OP_SCALAR_QRDMULH_LN>; +let ArchGuard = "defined(__ARM_FEATURE_QRDMX) && defined(__aarch64__)" in { +// Signed Saturating Rounding Doubling Multiply Accumulate Returning High Half +def SCALAR_SQRDMLAH_LANE : SOpInst<"vqrdmlah_lane", "sssdi", "SsSi", OP_SCALAR_QRDMLAH_LN>; +def SCALAR_SQRDMLAH_LANEQ : SOpInst<"vqrdmlah_laneq", "sssji", "SsSi", OP_SCALAR_QRDMLAH_LN>; + +// Signed Saturating Rounding Doubling Multiply Subtract Returning High Half +def SCALAR_SQRDMLSH_LANE : SOpInst<"vqrdmlsh_lane", "sssdi", "SsSi", OP_SCALAR_QRDMLSH_LN>; +def SCALAR_SQRDMLSH_LANEQ : SOpInst<"vqrdmlsh_laneq", "sssji", "SsSi", OP_SCALAR_QRDMLSH_LN>; +} + def SCALAR_VDUP_LANE : IInst<"vdup_lane", "sdi", "ScSsSiSlSfSdSUcSUsSUiSUlSPcSPs">; def SCALAR_VDUP_LANEQ : IInst<"vdup_laneq", "sji", "ScSsSiSlSfSdSUcSUsSUiSUlSPcSPs">; } diff --git a/contrib/llvm/tools/clang/include/clang/CodeGen/BackendUtil.h b/contrib/llvm/tools/clang/include/clang/CodeGen/BackendUtil.h index 8586e77..ba5dc39 100644 --- a/contrib/llvm/tools/clang/include/clang/CodeGen/BackendUtil.h +++ b/contrib/llvm/tools/clang/include/clang/CodeGen/BackendUtil.h @@ -11,6 +11,8 @@ #define LLVM_CLANG_CODEGEN_BACKENDUTIL_H #include "clang/Basic/LLVM.h" +#include "llvm/IR/FunctionInfo.h" +#include <memory> namespace llvm { class Module; @@ -31,10 +33,12 @@ namespace clang { Backend_EmitObj ///< Emit native object files }; - void EmitBackendOutput(DiagnosticsEngine &Diags, const CodeGenOptions &CGOpts, - const TargetOptions &TOpts, const LangOptions &LOpts, - StringRef TDesc, llvm::Module *M, BackendAction Action, - raw_pwrite_stream *OS); + void + EmitBackendOutput(DiagnosticsEngine &Diags, const CodeGenOptions &CGOpts, + const TargetOptions &TOpts, const LangOptions &LOpts, + StringRef TDesc, llvm::Module *M, BackendAction Action, + raw_pwrite_stream *OS, + std::unique_ptr<llvm::FunctionInfoIndex> Index = nullptr); } #endif diff --git a/contrib/llvm/tools/clang/include/clang/CodeGen/CGFunctionInfo.h b/contrib/llvm/tools/clang/include/clang/CodeGen/CGFunctionInfo.h index e32fb14..bb6ceb4 100644 --- a/contrib/llvm/tools/clang/include/clang/CodeGen/CGFunctionInfo.h +++ b/contrib/llvm/tools/clang/include/clang/CodeGen/CGFunctionInfo.h @@ -17,6 +17,7 @@ #define LLVM_CLANG_CODEGEN_CGFUNCTIONINFO_H #include "clang/AST/CanonicalType.h" +#include "clang/AST/CharUnits.h" #include "clang/AST/Type.h" #include "llvm/ADT/FoldingSet.h" #include <cassert> @@ -126,7 +127,7 @@ public: static ABIArgInfo getIgnore() { return ABIArgInfo(Ignore); } - static ABIArgInfo getIndirect(unsigned Alignment, bool ByVal = true, + static ABIArgInfo getIndirect(CharUnits Alignment, bool ByVal = true, bool Realign = false, llvm::Type *Padding = nullptr) { auto AI = ABIArgInfo(Indirect); @@ -137,7 +138,7 @@ public: AI.setPaddingType(Padding); return AI; } - static ABIArgInfo getIndirectInReg(unsigned Alignment, bool ByVal = true, + static ABIArgInfo getIndirectInReg(CharUnits Alignment, bool ByVal = true, bool Realign = false) { auto AI = getIndirect(Alignment, ByVal, Realign); AI.setInReg(true); @@ -211,20 +212,20 @@ public: } // Indirect accessors - unsigned getIndirectAlign() const { + CharUnits getIndirectAlign() const { assert(isIndirect() && "Invalid kind!"); - return IndirectAlign; + return CharUnits::fromQuantity(IndirectAlign); } - void setIndirectAlign(unsigned IA) { + void setIndirectAlign(CharUnits IA) { assert(isIndirect() && "Invalid kind!"); - IndirectAlign = IA; + IndirectAlign = IA.getQuantity(); } bool getIndirectByVal() const { assert(isIndirect() && "Invalid kind!"); return IndirectByVal; } - void setIndirectByVal(unsigned IBV) { + void setIndirectByVal(bool IBV) { assert(isIndirect() && "Invalid kind!"); IndirectByVal = IBV; } @@ -370,6 +371,7 @@ 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 NumArgs; ArgInfo *getArgsBuffer() { @@ -463,7 +465,13 @@ public: /// \brief Get the struct type used to represent all the arguments in memory. llvm::StructType *getArgStruct() const { return ArgStruct; } - void setArgStruct(llvm::StructType *Ty) { ArgStruct = Ty; } + CharUnits getArgStructAlignment() const { + return CharUnits::fromQuantity(ArgStructAlign); + } + void setArgStruct(llvm::StructType *Ty, CharUnits Align) { + ArgStruct = Ty; + ArgStructAlign = Align.getQuantity(); + } void Profile(llvm::FoldingSetNodeID &ID) { ID.AddInteger(getASTCallingConvention()); @@ -501,6 +509,29 @@ public: } }; +/// CGCalleeInfo - Class to encapsulate the information about a callee to be +/// used during the generation of call/invoke instructions. +class CGCalleeInfo { + /// \brief The function proto type of the callee. + const FunctionProtoType *CalleeProtoTy; + /// \brief The function declaration of the callee. + const Decl *CalleeDecl; + +public: + explicit CGCalleeInfo() : CalleeProtoTy(nullptr), CalleeDecl(nullptr) {} + CGCalleeInfo(const FunctionProtoType *calleeProtoTy, const Decl *calleeDecl) + : CalleeProtoTy(calleeProtoTy), CalleeDecl(calleeDecl) {} + CGCalleeInfo(const FunctionProtoType *calleeProtoTy) + : CalleeProtoTy(calleeProtoTy), CalleeDecl(nullptr) {} + CGCalleeInfo(const Decl *calleeDecl) + : CalleeProtoTy(nullptr), CalleeDecl(calleeDecl) {} + + const FunctionProtoType *getCalleeFunctionProtoType() { + return CalleeProtoTy; + } + const Decl *getCalleeDecl() { return CalleeDecl; } +}; + } // end namespace CodeGen } // end namespace clang diff --git a/contrib/llvm/tools/clang/include/clang/CodeGen/CodeGenABITypes.h b/contrib/llvm/tools/clang/include/clang/CodeGen/CodeGenABITypes.h index 4e76cd4..9d9504a 100644 --- a/contrib/llvm/tools/clang/include/clang/CodeGen/CodeGenABITypes.h +++ b/contrib/llvm/tools/clang/include/clang/CodeGen/CodeGenABITypes.h @@ -36,6 +36,7 @@ namespace llvm { namespace clang { class ASTContext; class CXXRecordDecl; +class CXXMethodDecl; class CodeGenOptions; class CoverageSourceInfo; class DiagnosticsEngine; @@ -50,7 +51,7 @@ class CodeGenModule; class CodeGenABITypes { public: - CodeGenABITypes(ASTContext &C, llvm::Module &M, const llvm::DataLayout &TD, + CodeGenABITypes(ASTContext &C, llvm::Module &M, CoverageSourceInfo *CoverageInfo = nullptr); ~CodeGenABITypes(); @@ -60,12 +61,13 @@ public: const CGFunctionInfo &arrangeObjCMessageSendSignature( const ObjCMethodDecl *MD, QualType receiverType); - const CGFunctionInfo &arrangeFreeFunctionType( - CanQual<FunctionProtoType> Ty); + 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 FunctionProtoType *FTP, + const CXXMethodDecl *MD); const CGFunctionInfo &arrangeFreeFunctionCall(CanQualType returnType, ArrayRef<CanQualType> argTypes, FunctionType::ExtInfo info, @@ -75,12 +77,12 @@ 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. - CodeGenOptions *CGO; - HeaderSearchOptions *HSO; - PreprocessorOptions *PPO; + std::unique_ptr<CodeGenOptions> CGO; + std::unique_ptr<HeaderSearchOptions> HSO; + std::unique_ptr<PreprocessorOptions> PPO; /// The CodeGenModule we use get to the CodeGenTypes object. - CodeGen::CodeGenModule *CGM; + std::unique_ptr<CodeGen::CodeGenModule> CGM; }; } // end namespace CodeGen diff --git a/contrib/llvm/tools/clang/include/clang/CodeGen/CodeGenAction.h b/contrib/llvm/tools/clang/include/clang/CodeGen/CodeGenAction.h index 264780d..cc38e24 100644 --- a/contrib/llvm/tools/clang/include/clang/CodeGen/CodeGenAction.h +++ b/contrib/llvm/tools/clang/include/clang/CodeGen/CodeGenAction.h @@ -25,7 +25,9 @@ class CodeGenAction : public ASTFrontendAction { private: unsigned Act; std::unique_ptr<llvm::Module> TheModule; - llvm::Module *LinkModule; + // Vector of {Linker::Flags, Module*} pairs to specify bitcode + // modules to link in using corresponding linker flags. + SmallVector<std::pair<unsigned, llvm::Module *>, 4> LinkModules; llvm::LLVMContext *VMContext; bool OwnsVMContext; @@ -50,7 +52,9 @@ public: /// setLinkModule - Set the link module to be used by this action. If a link /// module is not provided, and CodeGenOptions::LinkBitcodeFile is non-empty, /// the action will load it from the specified file. - void setLinkModule(llvm::Module *Mod) { LinkModule = Mod; } + void addLinkModule(llvm::Module *Mod, unsigned LinkFlags) { + LinkModules.push_back(std::make_pair(LinkFlags, Mod)); + } /// Take the generated LLVM module, for use after the action has been run. /// The result may be null on failure. diff --git a/contrib/llvm/tools/clang/include/clang/CodeGen/ObjectFilePCHContainerOperations.h b/contrib/llvm/tools/clang/include/clang/CodeGen/ObjectFilePCHContainerOperations.h index e82aab7..15132ac 100644 --- a/contrib/llvm/tools/clang/include/clang/CodeGen/ObjectFilePCHContainerOperations.h +++ b/contrib/llvm/tools/clang/include/clang/CodeGen/ObjectFilePCHContainerOperations.h @@ -23,9 +23,7 @@ class ObjectFilePCHContainerWriter : public PCHContainerWriter { /// PCHGenerator that produces a wrapper file format /// that also contains full debug info for the module. std::unique_ptr<ASTConsumer> CreatePCHContainerGenerator( - DiagnosticsEngine &Diags, const HeaderSearchOptions &HSO, - const PreprocessorOptions &PPO, const TargetOptions &TO, - const LangOptions &LO, const std::string &MainFileName, + CompilerInstance &CI, const std::string &MainFileName, const std::string &OutputFileName, llvm::raw_pwrite_stream *OS, std::shared_ptr<PCHBuffer> Buffer) const override; }; diff --git a/contrib/llvm/tools/clang/include/clang/Driver/Action.h b/contrib/llvm/tools/clang/include/clang/Driver/Action.h index fddd158..fc31d4b 100644 --- a/contrib/llvm/tools/clang/include/clang/Driver/Action.h +++ b/contrib/llvm/tools/clang/include/clang/Driver/Action.h @@ -164,7 +164,6 @@ public: const ActionList &DeviceActions); ~CudaHostAction() override; - ActionList &getDeviceActions() { return DeviceActions; } const ActionList &getDeviceActions() const { return DeviceActions; } static bool classof(const Action *A) { return A->getKind() == CudaHostClass; } @@ -288,7 +287,6 @@ class VerifyJobAction : public JobAction { public: VerifyJobAction(ActionClass Kind, std::unique_ptr<Action> Input, types::ID Type); - VerifyJobAction(ActionClass Kind, ActionList &Inputs, types::ID Type); static bool classof(const Action *A) { return A->getKind() == VerifyDebugInfoJobClass || A->getKind() == VerifyPCHJobClass; diff --git a/contrib/llvm/tools/clang/include/clang/Driver/CC1Options.td b/contrib/llvm/tools/clang/include/clang/Driver/CC1Options.td index d2f0d05..d7f42a9 100644 --- a/contrib/llvm/tools/clang/include/clang/Driver/CC1Options.td +++ b/contrib/llvm/tools/clang/include/clang/Driver/CC1Options.td @@ -132,6 +132,9 @@ def migrator_no_finalize_removal : Flag<["-"], "no-finalize-removal">, let Flags = [CC1Option, CC1AsOption, NoDriverOption] in { +def debug_info_kind_EQ : Joined<["-"], "debug-info-kind=">; +def dwarf_version_EQ : Joined<["-"], "dwarf-version=">; +def debugger_tuning_EQ : Joined<["-"], "debugger-tuning=">; def fdebug_compilation_dir : Separate<["-"], "fdebug-compilation-dir">, HelpText<"The compilation directory to embed in the debug info.">; def dwarf_debug_flags : Separate<["-"], "dwarf-debug-flags">, @@ -146,13 +149,17 @@ def msave_temp_labels : Flag<["-"], "msave-temp-labels">, HelpText<"Save temporary labels in the symbol table. " "Note this may change .s semantics and shouldn't generally be used " "on compiler-generated code.">; - +def mrelocation_model : Separate<["-"], "mrelocation-model">, + HelpText<"The relocation model to use">; } def disable_llvm_optzns : Flag<["-"], "disable-llvm-optzns">, HelpText<"Don't run LLVM optimization passes">; def disable_llvm_verifier : Flag<["-"], "disable-llvm-verifier">, HelpText<"Don't run the LLVM IR verifier pass">; +def disable_llvm_passes : Flag<["-"], "disable-llvm-passes">, + HelpText<"Use together with -emit-llvm to get pristine LLVM IR from the " + "frontend by not running any LLVM passes at all">; def disable_red_zone : Flag<["-"], "disable-red-zone">, HelpText<"Do not emit code that uses the red zone.">; def dwarf_column_info : Flag<["-"], "dwarf-column-info">, @@ -163,6 +170,9 @@ def gnu_pubnames : Flag<["-"], "gnu-pubnames">, HelpText<"Emit newer GNU style pubnames">; def arange_sections : Flag<["-"], "arange_sections">, HelpText<"Emit DWARF .debug_arange sections">; +def dwarf_ext_refs : Flag<["-"], "dwarf-ext-refs">, + HelpText<"Generate debug info with external references to clang modules" + " or precompiled headers">; def fforbid_guard_variables : Flag<["-"], "fforbid-guard-variables">, HelpText<"Emit an error if a C++ static local initializer would need a guard variable">; def no_implicit_float : Flag<["-"], "no-implicit-float">, @@ -225,14 +235,15 @@ def backend_option : Separate<["-"], "backend-option">, HelpText<"Additional arguments to forward to LLVM backend (during code gen)">; def mregparm : Separate<["-"], "mregparm">, HelpText<"Limit the number of registers available for integer arguments">; -def mrelocation_model : Separate<["-"], "mrelocation-model">, - HelpText<"The relocation model to use">; def munwind_tables : Flag<["-"], "munwind-tables">, HelpText<"Generate unwinding tables for all functions">; def mconstructor_aliases : Flag<["-"], "mconstructor-aliases">, HelpText<"Emit complete constructors and destructors as aliases when possible">; def mlink_bitcode_file : Separate<["-"], "mlink-bitcode-file">, HelpText<"Link the given bitcode file before performing optimizations.">; +def mlink_cuda_bitcode : Separate<["-"], "mlink-cuda-bitcode">, + HelpText<"Link and internalize needed symbols from the given bitcode file " + "before performing optimizations.">; def vectorize_loops : Flag<["-"], "vectorize-loops">, HelpText<"Run the Loop vectorization passes">; def vectorize_slp : Flag<["-"], "vectorize-slp">, @@ -320,6 +331,8 @@ def cc1as : Flag<["-"], "cc1as">; def ast_merge : Separate<["-"], "ast-merge">, MetaVarName<"<ast file>">, HelpText<"Merge the given AST file into the translation unit being compiled.">; +def aux_triple : Separate<["-"], "aux-triple">, + HelpText<"Auxiliary target triple.">; def code_completion_at : Separate<["-"], "code-completion-at">, MetaVarName<"<file>:<line>:<column>">, HelpText<"Dump code-completion information at a location">; @@ -365,6 +378,13 @@ def fmodule_map_file_home_is_cwd : Flag<["-"], "fmodule-map-file-home-is-cwd">, def fmodule_feature : Separate<["-"], "fmodule-feature">, MetaVarName<"<feature>">, HelpText<"Enable <feature> in module map requires declarations">; +def fmodules_embed_file_EQ : Joined<["-"], "fmodules-embed-file=">, + MetaVarName<"<file>">, + HelpText<"Embed the contents of the specified file into the module file " + "being compiled.">; +def fmodules_embed_all_files : Joined<["-"], "fmodules-embed-all-files">, + HelpText<"Embed the contents of all files read by this compilation into " + "the produced module file.">; def fmodules_local_submodule_visibility : Flag<["-"], "fmodules-local-submodule-visibility">, HelpText<"Enforce name visibility rules across submodules of the same " @@ -372,10 +392,10 @@ def fmodules_local_submodule_visibility : def fmodule_format_EQ : Joined<["-"], "fmodule-format=">, HelpText<"Select the container format for clang modules and PCH. " "Supported options are 'raw' and 'obj'.">; -def fno_modules_hide_internal_linkage : - Flag<["-"], "fno-modules-hide-internal-linkage">, - HelpText<"Make all declarations visible to redeclaration lookup, " - "even if they have internal linkage.">; +def ftest_module_file_extension_EQ : + Joined<["-"], "ftest-module-file-extension=">, + HelpText<"introduce a module file extension for testing purposes. " + "The argument is parsed as blockname:major:minor:hashed:user info">; def fconcepts_ts : Flag<["-"], "fconcepts-ts">, HelpText<"Enable C++ Extensions for Concepts.">; @@ -483,6 +503,8 @@ 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 split_dwarf_file : Separate<["-"], "split-dwarf-file">, HelpText<"File name to use for split dwarf debug info output">; def fno_wchar : Flag<["-"], "fno-wchar">, @@ -565,6 +587,10 @@ def fnative_half_type: Flag<["-"], "fnative-half-type">, def fallow_half_arguments_and_returns : Flag<["-"], "fallow-half-arguments-and-returns">, HelpText<"Allow function arguments and returns of type half">; +// C++ TSes. +def fcoroutines : Flag<["-"], "fcoroutines">, + HelpText<"Enable support for the C++ Coroutines TS">; + //===----------------------------------------------------------------------===// // Header Search Options //===----------------------------------------------------------------------===// @@ -648,6 +674,8 @@ def fcuda_disable_target_call_checks : Flag<["-"], 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.">; } // let Flags = [CC1Option] diff --git a/contrib/llvm/tools/clang/include/clang/Driver/CLCompatOptions.td b/contrib/llvm/tools/clang/include/clang/Driver/CLCompatOptions.td index 907b16f..16a5b72 100644 --- a/contrib/llvm/tools/clang/include/clang/Driver/CLCompatOptions.td +++ b/contrib/llvm/tools/clang/include/clang/Driver/CLCompatOptions.td @@ -52,6 +52,12 @@ class CLRemainingArgs<string name> : Option<["/", "-"], name, // (We don't put any of these in cl_compile_Group as the options they alias are // already in the right group.) +def _SLASH_Brepro : CLFlag<"Brepro">, + HelpText<"Emit an object file which can be reproduced over time">, + Alias<mincremental_linker_compatible>; +def _SLASH_Brepro_ : CLFlag<"Brepro-">, + HelpText<"Emit an object file which cannot be reproduced over time">, + Alias<mno_incremental_linker_compatible>; def _SLASH_C : CLFlag<"C">, HelpText<"Don't discard comments when preprocessing">, Alias<C>; def _SLASH_c : CLFlag<"c">, HelpText<"Compile only">, Alias<c>; @@ -92,8 +98,7 @@ 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>; -def _SLASH_O : CLJoined<"O">, HelpText<"Optimization level">, - MetaVarName<"<n>">, Alias<O>; +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>; @@ -105,12 +110,6 @@ def _SLASH_Os : CLFlag<"Os">, HelpText<"Optimize for size">, Alias<O>, AliasArgs<["s"]>; def _SLASH_Ot : CLFlag<"Ot">, HelpText<"Optimize for speed">, Alias<O>, AliasArgs<["2"]>; -def _SLASH_Ox : CLFlag<"Ox">, HelpText<"Maximum optimization">, Alias<O>, - AliasArgs<["3"]>; -def _SLASH_Oy : CLFlag<"Oy">, HelpText<"Enable frame pointer omission">, - Alias<fomit_frame_pointer>; -def _SLASH_Oy_ : CLFlag<"Oy-">, HelpText<"Disable frame pointer omission">, - Alias<fno_omit_frame_pointer>; def _SLASH_QUESTION : CLFlag<"?">, Alias<help>, HelpText<"Display available options">; def _SLASH_Qvec : CLFlag<"Qvec">, @@ -126,8 +125,8 @@ def _SLASH_W0 : CLFlag<"W0">, HelpText<"Disable all warnings">, Alias<w>; def _SLASH_W1 : CLFlag<"W1">, HelpText<"Enable -Wall">, Alias<Wall>; def _SLASH_W2 : CLFlag<"W2">, HelpText<"Enable -Wall">, Alias<Wall>; def _SLASH_W3 : CLFlag<"W3">, HelpText<"Enable -Wall">, Alias<Wall>; -def _SLASH_W4 : CLFlag<"W4">, HelpText<"Enable -Wall">, Alias<Wall>; -def _SLASH_Wall : CLFlag<"Wall">, HelpText<"Enable -Wall">, Alias<Wall>; +def _SLASH_W4 : CLFlag<"W4">, HelpText<"Enable -Wall and -Wextra">, Alias<WCL4>; +def _SLASH_Wall : CLFlag<"Wall">, HelpText<"Enable -Wall and -Wextra">, Alias<WCL4>; def _SLASH_WX : CLFlag<"WX">, HelpText<"Treat warnings as errors">, Alias<W_Joined>, AliasArgs<["error"]>; def _SLASH_WX_ : CLFlag<"WX-">, HelpText<"Do not treat warnings as errors">, @@ -135,10 +134,12 @@ def _SLASH_WX_ : CLFlag<"WX-">, HelpText<"Do not treat warnings as errors">, def _SLASH_w_flag : CLFlag<"w">, HelpText<"Disable all warnings">, Alias<w>; def _SLASH_wd4005 : CLFlag<"wd4005">, Alias<W_Joined>, AliasArgs<["no-macro-redefined"]>; -def _SLASH_wd4996 : CLFlag<"wd4996">, Alias<W_Joined>, - AliasArgs<["no-deprecated-declarations"]>; +def _SLASH_wd4100 : CLFlag<"wd4100">, Alias<W_Joined>, + AliasArgs<["no-unused-parameter"]>; def _SLASH_wd4910 : CLFlag<"wd4910">, Alias<W_Joined>, AliasArgs<["no-dllexport-explicit-instantiation-decl"]>; +def _SLASH_wd4996 : CLFlag<"wd4996">, Alias<W_Joined>, + AliasArgs<["no-deprecated-declarations"]>; def _SLASH_vd : CLJoined<"vd">, HelpText<"Control vtordisp placement">, Alias<vtordisp_mode_EQ>; def _SLASH_Zc_sizedDealloc : CLFlag<"Zc:sizedDealloc">, @@ -160,9 +161,10 @@ def _SLASH_Zc_trigraphs : CLFlag<"Zc:trigraphs">, HelpText<"Enable trigraphs">, Alias<ftrigraphs>; def _SLASH_Zc_trigraphs_off : CLFlag<"Zc:trigraphs-">, HelpText<"Disable trigraphs (default)">, Alias<fno_trigraphs>; -def _SLASH_Z7 : CLFlag<"Z7">, Alias<gline_tables_only>; -def _SLASH_Zi : CLFlag<"Zi">, HelpText<"Enable debug information">, - Alias<gline_tables_only>; +def _SLASH_Z7 : CLFlag<"Z7">, + HelpText<"Enable CodeView debug information in object files">; +def _SLASH_Zi : CLFlag<"Zi">, Alias<_SLASH_Z7>, + HelpText<"Alias for /Z7. Does not produce PDBs.">; def _SLASH_Zp : CLJoined<"Zp">, HelpText<"Specify the default maximum struct packing alignment">, Alias<fpack_struct_EQ>; @@ -243,10 +245,13 @@ def _SLASH_vmv : CLFlag<"vmv">, def _SLASH_volatile_ms : Option<["/", "-"], "volatile:ms", KIND_FLAG>, Group<_SLASH_volatile_Group>, Flags<[CLOption, DriverOption]>, HelpText<"Volatile loads and stores have acquire and release semantics">; +def _SLASH_Zl : CLFlag<"Zl">, + HelpText<"Don't mention any default libraries in the object file">; // Ignored: def _SLASH_analyze_ : CLIgnoredFlag<"analyze-">; +def _SLASH_bigobj : CLIgnoredFlag<"bigobj">; def _SLASH_cgthreads : CLIgnoredJoined<"cgthreads">; def _SLASH_d2Zi_PLUS : CLIgnoredFlag<"d2Zi+">; def _SLASH_errorReport : CLIgnoredJoined<"errorReport">; @@ -259,6 +264,7 @@ 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">; def _SLASH_sdl : CLIgnoredFlag<"sdl">; @@ -277,7 +283,6 @@ def _SLASH_Zo_ : CLIgnoredFlag<"Zo-">; // Unsupported: def _SLASH_AI : CLJoined<"AI">; -def _SLASH_bigobj : CLFlag<"bigobj">; def _SLASH_clr : CLJoined<"clr">; def _SLASH_doc : CLJoined<"doc">; def _SLASH_FA_joined : CLJoined<"FA">; @@ -302,6 +307,7 @@ 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">; @@ -333,5 +339,4 @@ def _SLASH_Zc : CLJoined<"Zc:">; def _SLASH_Ze : CLFlag<"Ze">; def _SLASH_Zg : CLFlag<"Zg">; def _SLASH_ZI : CLFlag<"ZI">; -def _SLASH_Zl : CLFlag<"Zl">; def _SLASH_ZW : CLJoined<"ZW">; diff --git a/contrib/llvm/tools/clang/include/clang/Driver/Compilation.h b/contrib/llvm/tools/clang/include/clang/Driver/Compilation.h index f0c1bed..12ff068 100644 --- a/contrib/llvm/tools/clang/include/clang/Driver/Compilation.h +++ b/contrib/llvm/tools/clang/include/clang/Driver/Compilation.h @@ -10,6 +10,7 @@ #ifndef LLVM_CLANG_DRIVER_COMPILATION_H #define LLVM_CLANG_DRIVER_COMPILATION_H +#include "clang/Driver/Action.h" #include "clang/Driver/Job.h" #include "clang/Driver/Util.h" #include "llvm/ADT/DenseMap.h" @@ -25,7 +26,6 @@ namespace opt { namespace clang { namespace driver { class Driver; - class JobAction; class JobList; class ToolChain; @@ -38,6 +38,9 @@ class Compilation { /// The default tool chain. const ToolChain &DefaultToolChain; + const ToolChain *CudaHostToolChain; + const ToolChain *CudaDeviceToolChain; + /// The original (untranslated) input argument list. llvm::opt::InputArgList *Args; @@ -81,6 +84,17 @@ 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; + } + + void setCudaHostToolChain(const ToolChain *HostToolChain) { + CudaHostToolChain = HostToolChain; + } + void setCudaDeviceToolChain(const ToolChain *DeviceToolChain) { + CudaDeviceToolChain = DeviceToolChain; + } const llvm::opt::InputArgList &getInputArgs() const { return *Args; } @@ -179,7 +193,7 @@ public: void initCompilationForDiagnostics(); /// Return true if we're compiling for diagnostics. - bool isForDiagnostics() { return ForDiagnostics; } + bool isForDiagnostics() const { return ForDiagnostics; } }; } // end namespace driver diff --git a/contrib/llvm/tools/clang/include/clang/Driver/Driver.h b/contrib/llvm/tools/clang/include/clang/Driver/Driver.h index 4a67fdb..c9940ba 100644 --- a/contrib/llvm/tools/clang/include/clang/Driver/Driver.h +++ b/contrib/llvm/tools/clang/include/clang/Driver/Driver.h @@ -36,6 +36,11 @@ namespace opt { } namespace clang { + +namespace vfs { +class FileSystem; +} + namespace driver { class Action; @@ -47,6 +52,14 @@ namespace driver { class SanitizerArgs; class ToolChain; +/// Describes the kind of LTO mode selected via -f(no-)?lto(=.*)? options. +enum LTOKind { + LTOK_None, + LTOK_Full, + LTOK_Thin, + LTOK_Unknown +}; + /// Driver - Encapsulate logic for constructing compilation processes /// from a set of gcc-driver-like command line arguments. class Driver { @@ -54,6 +67,8 @@ class Driver { DiagnosticsEngine &Diags; + IntrusiveRefCntPtr<vfs::FileSystem> VFS; + enum DriverMode { GCCMode, GXXMode, @@ -67,6 +82,9 @@ class Driver { SaveTempsObj } SaveTemps; + /// LTO mode selected via -f(no-)?lto(=.*)? options. + LTOKind LTOMode; + public: // Diag - Forwarding function for diagnostics. DiagnosticBuilder Diag(unsigned DiagID) const { @@ -201,9 +219,9 @@ private: SmallVectorImpl<std::string> &Names) const; public: - Driver(StringRef _ClangExecutable, - StringRef _DefaultTargetTriple, - DiagnosticsEngine &_Diags); + Driver(StringRef ClangExecutable, StringRef DefaultTargetTriple, + DiagnosticsEngine &Diags, + IntrusiveRefCntPtr<vfs::FileSystem> VFS = nullptr); ~Driver(); /// @name Accessors @@ -216,6 +234,8 @@ public: const DiagnosticsEngine &getDiags() const { return Diags; } + vfs::FileSystem &getVFS() const { return *VFS; } + bool getCheckInputsExist() const { return CheckInputsExist; } void setCheckInputsExist(bool Value) { CheckInputsExist = Value; } @@ -277,22 +297,21 @@ public: /// BuildActions - Construct the list of actions to perform for the /// 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(const ToolChain &TC, llvm::opt::DerivedArgList &Args, - const InputList &Inputs, ActionList &Actions) const; + void BuildActions(Compilation &C, const ToolChain &TC, + 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. /// + /// \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 BuildUniversalActions(const ToolChain &TC, - llvm::opt::DerivedArgList &Args, - const InputList &BAInputs, - ActionList &Actions) const; + void BuildUniversalActions(Compilation &C, const ToolChain &TC, + const InputList &BAInputs) const; /// BuildJobs - Bind actions to concrete tools and translate /// arguments to form the list of jobs to run. @@ -402,9 +421,17 @@ public: /// handle this action. bool ShouldUseClangCompiler(const JobAction &JA) const; - bool IsUsingLTO(const llvm::opt::ArgList &Args) const; + /// Returns true if we are performing any kind of LTO. + bool isUsingLTO() const { return LTOMode != LTOK_None; } + + /// Get the specific kind of LTO being performed. + LTOKind getLTOMode() const { return LTOMode; } private: + /// Parse the \p Args list for LTO options and record the type of LTO + /// compilation based on which -f(no-)?lto(=.*)? option occurs last. + void setLTOMode(const llvm::opt::ArgList &Args); + /// \brief Retrieves a ToolChain for a particular \p Target triple. /// /// Will cache ToolChains for the life of the driver object, and create them diff --git a/contrib/llvm/tools/clang/include/clang/Driver/Job.h b/contrib/llvm/tools/clang/include/clang/Driver/Job.h index 186244b..263356f 100644 --- a/contrib/llvm/tools/clang/include/clang/Driver/Job.h +++ b/contrib/llvm/tools/clang/include/clang/Driver/Job.h @@ -25,6 +25,7 @@ namespace driver { class Action; class Command; class Tool; +class InputInfo; // Re-export this as clang::driver::ArgStringList. using llvm::opt::ArgStringList; @@ -53,6 +54,9 @@ class Command { /// argument, which will be the executable). llvm::opt::ArgStringList Arguments; + /// The list of program arguments which are inputs. + llvm::opt::ArgStringList InputFilenames; + /// Response file name, if this command is set to use one, or nullptr /// otherwise const char *ResponseFile; @@ -79,7 +83,11 @@ class Command { public: Command(const Action &Source, const Tool &Creator, const char *Executable, - const llvm::opt::ArgStringList &Arguments); + const llvm::opt::ArgStringList &Arguments, + ArrayRef<InputInfo> Inputs); + // FIXME: This really shouldn't be copyable, but is currently copied in some + // error handling in Driver::generateCompilationDiagnostics. + Command(const Command &) = default; virtual ~Command() {} virtual void Print(llvm::raw_ostream &OS, const char *Terminator, bool Quote, @@ -117,6 +125,7 @@ class FallbackCommand : public Command { public: FallbackCommand(const Action &Source_, const Tool &Creator_, const char *Executable_, const ArgStringList &Arguments_, + ArrayRef<InputInfo> Inputs, std::unique_ptr<Command> Fallback_); void Print(llvm::raw_ostream &OS, const char *Terminator, bool Quote, diff --git a/contrib/llvm/tools/clang/include/clang/Driver/Options.td b/contrib/llvm/tools/clang/include/clang/Driver/Options.td index 9d3e2cf..3dbe43f 100644 --- a/contrib/llvm/tools/clang/include/clang/Driver/Options.td +++ b/contrib/llvm/tools/clang/include/clang/Driver/Options.td @@ -71,15 +71,31 @@ def d_Group : OptionGroup<"<d group>">; def f_Group : OptionGroup<"<f group>">, Group<CompileOnly_Group>; def f_clang_Group : OptionGroup<"<f (clang-only) group>">, Group<CompileOnly_Group>; def g_Group : OptionGroup<"<g group>">; +def gN_Group : OptionGroup<"<gN group>">, Group<g_Group>; +def ggdbN_Group : OptionGroup<"<ggdbN group>">, Group<gN_Group>; +def gTune_Group : OptionGroup<"<gTune group>">, Group<g_Group>; 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 m_x86_Features_Group : OptionGroup<"<m x86 features group>">, Group<m_Group>, Flags<[CoreOption]>; -def m_hexagon_Features_Group : OptionGroup<"<m hexagon features group>">, Group<m_Group>; -def m_arm_Features_Group : OptionGroup<"<m arm features group>">, Group<m_Group>; -def m_aarch64_Features_Group : OptionGroup<"<m aarch64 features group>">, Group<m_Group>; -def m_ppc_Features_Group : OptionGroup<"<m ppc features group>">, Group<m_Group>; + +// Feature groups - these take command line options that correspond directly to +// target specific features and can be translated directly from command line +// options. +def m_x86_Features_Group : OptionGroup<"<x86 features group>">, + Group<m_Group>, + Flags<[CoreOption]>; +def m_hexagon_Features_Group : OptionGroup<"<hexagon features group>">, + Group<m_Group>; +def m_arm_Features_Group : OptionGroup<"<arm features group>">, + Group<m_Group>; +def m_aarch64_Features_Group : OptionGroup<"<aarch64 features group>">, + Group<m_Group>; +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_libc_Group : OptionGroup<"<m libc group>">, Group<m_Group>; def u_Group : OptionGroup<"<u group>">; @@ -143,7 +159,7 @@ def ccc_pch_is_pth : Flag<["-"], "ccc-pch-is-pth">, InternalDriverOpt, HelpText<"Use pretokenized headers for precompiled headers">; class InternalDebugOpt : Group<internal_debug_Group>, - Flags<[DriverOption, HelpHidden]>; + Flags<[DriverOption, HelpHidden, CoreOption]>; def ccc_install_dir : Separate<["-"], "ccc-install-dir">, InternalDebugOpt, HelpText<"Simulate installation in the given directory">; def ccc_print_phases : Flag<["-"], "ccc-print-phases">, InternalDebugOpt, @@ -293,6 +309,7 @@ def Wa_COMMA : CommaJoined<["-"], "Wa,">, HelpText<"Pass the comma separated arguments in <arg> to the assembler">, MetaVarName<"<arg>">; def Wall : Flag<["-"], "Wall">, Group<W_Group>, Flags<[CC1Option]>; +def WCL4 : Flag<["-"], "WCL4">, Group<W_Group>, Flags<[CC1Option]>; def Wdeprecated : Flag<["-"], "Wdeprecated">, Group<W_Group>, Flags<[CC1Option]>; def Wno_deprecated : Flag<["-"], "Wno-deprecated">, Group<W_Group>, Flags<[CC1Option]>; def Wextra : Flag<["-"], "Wextra">, Group<W_Group>, Flags<[CC1Option]>; @@ -357,6 +374,8 @@ def cuda_gpu_arch_EQ : Joined<["--"], "cuda-gpu-arch=">, Flags<[DriverOption, HelpHidden]>, HelpText<"CUDA GPU architecture">; def cuda_host_only : Flag<["--"], "cuda-host-only">, HelpText<"Do host-side CUDA compilation only">; +def cuda_path_EQ : Joined<["--"], "cuda-path=">, Group<i_Group>, + HelpText<"CUDA installation path">; 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">; @@ -436,6 +455,9 @@ def fprofile_instr_use_EQ : Joined<["-"], "fprofile-instr-use=">, def fcoverage_mapping : Flag<["-"], "fcoverage-mapping">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Generate coverage mapping to enable code coverage analysis">; +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>; def fprofile_generate_EQ : Joined<["-"], "fprofile-generate=">, @@ -446,6 +468,16 @@ def fprofile_use : Flag<["-"], "fprofile-use">, Group<f_Group>, def fprofile_use_EQ : Joined<["-"], "fprofile-use=">, Group<f_Group>, Flags<[DriverOption]>, MetaVarName<"<pathname>">, HelpText<"Use instrumentation data for profile-guided optimization. If pathname is a directory, it reads from <pathname>/default.profdata. Otherwise, it reads from file <pathname>.">; +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>; +def fno_profile_instr_use : Flag<["-"], "fno-profile-instr-use">, + Group<f_Group>, Flags<[DriverOption]>, + HelpText<"Disable using instrumentation data for profile-guided optimization">; +def fno_profile_use : Flag<["-"], "fno-profile-use">, + Alias<fno_profile_instr_use>; def fblocks : Flag<["-"], "fblocks">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Enable the 'blocks' language feature">; @@ -482,6 +514,8 @@ def fcxx_modules : Flag <["-"], "fcxx-modules">, Group<f_Group>, Flags<[DriverOption]>; def fdebug_pass_arguments : Flag<["-"], "fdebug-pass-arguments">, Group<f_Group>; def fdebug_pass_structure : Flag<["-"], "fdebug-pass-structure">, Group<f_Group>; +def fdepfile_entry : Joined<["-"], "fdepfile-entry=">, + Group<f_clang_Group>, Flags<[CC1Option]>; def fdiagnostics_fixit_info : Flag<["-"], "fdiagnostics-fixit-info">, Group<f_clang_Group>; def fdiagnostics_parseable_fixits : Flag<["-"], "fdiagnostics-parseable-fixits">, Group<f_clang_Group>, Flags<[CoreOption, CC1Option]>, HelpText<"Print fix-its in machine parseable form">; @@ -497,6 +531,8 @@ def fdiagnostics_show_category_EQ : Joined<["-"], "fdiagnostics-show-category="> def fdiagnostics_show_template_tree : Flag<["-"], "fdiagnostics-show-template-tree">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Print a template comparison tree for differing templates">; +def fdeclspec : Flag<["-"], "fdeclspec">, Group<f_clang_Group>, + HelpText<"Allow __declspec as a keyword">, Flags<[CC1Option]>; def fdollars_in_identifiers : Flag<["-"], "fdollars-in-identifiers">, Group<f_Group>, HelpText<"Allow '$' in identifiers">, Flags<[CC1Option]>; def fdwarf2_cfi_asm : Flag<["-"], "fdwarf2-cfi-asm">, Group<clang_ignored_f_Group>; @@ -510,6 +546,9 @@ def fno_elide_type : Flag<["-"], "fno-elide-type">, Group<f_Group>, def feliminate_unused_debug_symbols : Flag<["-"], "feliminate-unused-debug-symbols">, Group<f_Group>; def femit_all_decls : Flag<["-"], "femit-all-decls">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Emit all declarations, even if unused">; +def femulated_tls : Flag<["-"], "femulated-tls">, Group<f_Group>, Flags<[CC1Option]>, + HelpText<"Use emutls functions to access thread_local variables">; +def fno_emulated_tls : Flag<["-"], "fno-emulated-tls">, Group<f_Group>; 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]>, @@ -538,7 +577,7 @@ def fno_signaling_math : Flag<["-"], "fno-signaling-math">, Group<f_Group>; def fsanitize_EQ : CommaJoined<["-"], "fsanitize=">, Group<f_clang_Group>, Flags<[CC1Option, CoreOption]>, MetaVarName<"<check>">, HelpText<"Turn on runtime checks for various forms of undefined " - "or suspicious behavior. See user manual for available checks ">; + "or suspicious behavior. See user manual for available checks">; def fno_sanitize_EQ : CommaJoined<["-"], "fno-sanitize=">, Group<f_clang_Group>, Flags<[CoreOption]>; def fsanitize_blacklist : Joined<["-"], "fsanitize-blacklist=">, @@ -595,6 +634,12 @@ def fno_sanitize_undefined_trap_on_error : Flag<["-"], "fno-sanitize-undefined-t Group<f_clang_Group>; def fsanitize_link_cxx_runtime : Flag<["-"], "fsanitize-link-c++-runtime">, Group<f_clang_Group>; +def fsanitize_cfi_cross_dso : Flag<["-"], "fsanitize-cfi-cross-dso">, + Group<f_clang_Group>, Flags<[CC1Option]>, + HelpText<"Enable control flow integrity (CFI) checks for cross-DSO calls.">; +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 funsafe_math_optimizations : Flag<["-"], "funsafe-math-optimizations">, Group<f_Group>; def fno_unsafe_math_optimizations : Flag<["-"], "fno-unsafe-math-optimizations">, @@ -663,16 +708,22 @@ def finstrument_functions : Flag<["-"], "finstrument-functions">, Group<f_Group> 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>; -def flto_EQ : Joined<["-"], "flto=">, Group<clang_ignored_gcc_optimization_f_Group>; -def flto : Flag<["-"], "flto">, Flags<[CC1Option]>, Group<f_Group>; -def fno_lto : Flag<["-"], "fno-lto">, Group<f_Group>; +def flto_EQ : Joined<["-"], "flto=">, Flags<[CC1Option]>, Group<f_Group>, + HelpText<"Set LTO mode to either 'full' or 'thin'">; +def flto : Flag<["-"], "flto">, Flags<[CC1Option]>, Group<f_Group>, + HelpText<"Enable LTO in 'full' mode">; +def fno_lto : Flag<["-"], "fno-lto">, Group<f_Group>, + HelpText<"Disable LTO mode (default)">; +def fthinlto_index_EQ : Joined<["-"], "fthinlto-index=">, + Flags<[CC1Option]>, Group<f_Group>, + HelpText<"Perform ThinLTO importing using provided function summary index">; def fmacro_backtrace_limit_EQ : Joined<["-"], "fmacro-backtrace-limit=">, Group<f_Group>, Flags<[DriverOption, CoreOption]>; def fmerge_all_constants : Flag<["-"], "fmerge-all-constants">, Group<f_Group>; def fmessage_length_EQ : Joined<["-"], "fmessage-length=">, Group<f_Group>; -def fms_extensions : Flag<["-"], "fms-extensions">, Group<f_Group>, Flags<[CC1Option]>, +def fms_extensions : Flag<["-"], "fms-extensions">, Group<f_Group>, Flags<[CC1Option, CoreOption]>, HelpText<"Accept some non-standard constructs supported by the Microsoft compiler">; -def fms_compatibility : Flag<["-"], "fms-compatibility">, Group<f_Group>, Flags<[CC1Option]>, +def fms_compatibility : Flag<["-"], "fms-compatibility">, Group<f_Group>, Flags<[CC1Option, CoreOption]>, HelpText<"Enable full Microsoft Visual C++ compatibility">; def fms_volatile : Joined<["-"], "fms-volatile">, Group<f_Group>, Flags<[CC1Option]>; def fmsc_version : Joined<["-"], "fmsc-version=">, Group<f_Group>, Flags<[DriverOption, CoreOption]>, @@ -786,6 +837,8 @@ def fno_diagnostics_fixit_info : Flag<["-"], "fno-diagnostics-fixit-info">, Grou def fno_diagnostics_show_option : Flag<["-"], "fno-diagnostics-show-option">, Group<f_Group>; def fno_diagnostics_show_note_include_stack : Flag<["-"], "fno-diagnostics-show-note-include-stack">, Flags<[CC1Option]>, Group<f_Group>; +def fno_declspec : Flag<["-"], "fno-declspec">, Group<f_clang_Group>, + HelpText<"Disallow __declspec as a keyword">, Flags<[CC1Option]>; def fno_dollars_in_identifiers : Flag<["-"], "fno-dollars-in-identifiers">, Group<f_Group>, HelpText<"Disallow '$' in identifiers">, Flags<[CC1Option]>; def fno_elide_constructors : Flag<["-"], "fno-elide-constructors">, Group<f_Group>, @@ -816,11 +869,14 @@ def fmodule_file_deps : Flag <["-"], "fmodule-file-deps">, Group<f_Group>, Flags<[DriverOption]>; def fno_module_file_deps : Flag <["-"], "fno-module-file-deps">, Group<f_Group>, Flags<[DriverOption]>; -def fno_ms_extensions : Flag<["-"], "fno-ms-extensions">, Group<f_Group>; -def fno_ms_compatibility : Flag<["-"], "fno-ms-compatibility">, Group<f_Group>; +def fno_ms_extensions : Flag<["-"], "fno-ms-extensions">, Group<f_Group>, + Flags<[CoreOption]>; +def fno_ms_compatibility : Flag<["-"], "fno-ms-compatibility">, Group<f_Group>, + Flags<[CoreOption]>; def fno_delayed_template_parsing : Flag<["-"], "fno-delayed-template-parsing">, Group<f_Group>; def fno_objc_exceptions: Flag<["-"], "fno-objc-exceptions">, Group<f_Group>; def fno_objc_legacy_dispatch : Flag<["-"], "fno-objc-legacy-dispatch">, Group<f_Group>; +def fno_objc_weak : Flag<["-"], "fno-objc-weak">, Group<f_Group>, Flags<[CC1Option]>; def fno_omit_frame_pointer : Flag<["-"], "fno-omit-frame-pointer">, Group<f_Group>; def fno_operator_names : Flag<["-"], "fno-operator-names">, Group<f_Group>, HelpText<"Do not treat C++ operator name keywords as synonyms for operators">, @@ -842,6 +898,8 @@ 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">, + 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>, Flags<[CC1Option]>, HelpText<"Do not emit code to make initialization of local statics thread safe">; @@ -888,6 +946,8 @@ def fno_objc_infer_related_result_type : Flag<["-"], "do not infer Objective-C related result type based on method family">, Flags<[CC1Option]>; def fobjc_link_runtime: Flag<["-"], "fobjc-link-runtime">, Group<f_Group>; +def fobjc_weak : Flag<["-"], "fobjc-weak">, Group<f_Group>, Flags<[CC1Option]>, + HelpText<"Enable ARC-style weak references in Objective-C">; // Objective-C ABI options. def fobjc_runtime_EQ : Joined<["-"], "fobjc-runtime=">, Group<f_Group>, Flags<[CC1Option]>, @@ -927,6 +987,8 @@ def fpic : Flag<["-"], "fpic">, Group<f_Group>; def fno_pic : Flag<["-"], "fno-pic">, Group<f_Group>; def fpie : Flag<["-"], "fpie">, Group<f_Group>; def fno_pie : Flag<["-"], "fno-pie">, Group<f_Group>; +def fplugin_EQ : Joined<["-"], "fplugin=">, Group<f_Group>, Flags<[DriverOption]>, MetaVarName<"<dsopath>">, + HelpText<"Load the named plugin (dynamic shared object)">; def fprofile_arcs : Flag<["-"], "fprofile-arcs">, Group<f_Group>; def fno_profile_arcs : Flag<["-"], "fno-profile-arcs">, Group<f_Group>; def framework : Separate<["-"], "framework">, Flags<[LinkerInput]>; @@ -959,9 +1021,9 @@ def fstack_protector_strong : Flag<["-"], "fstack-protector-strong">, Group<f_Gr HelpText<"Use a strong heuristic to apply stack protectors to functions">; def fstack_protector : Flag<["-"], "fstack-protector">, Group<f_Group>, HelpText<"Enable stack protectors for functions potentially vulnerable to stack smashing">; -def fstandalone_debug : Flag<["-"], "fstandalone-debug">, Group<f_Group>, Flags<[CC1Option]>, +def fstandalone_debug : Flag<["-"], "fstandalone-debug">, Group<f_Group>, HelpText<"Emit full debug info for all types used by the program">; -def fno_standalone_debug : Flag<["-"], "fno-standalone-debug">, Group<f_Group>, Flags<[CC1Option]>, +def fno_standalone_debug : Flag<["-"], "fno-standalone-debug">, Group<f_Group>, HelpText<"Limit debug information produced to reduce size of debug binary">; def flimit_debug_info : Flag<["-"], "flimit-debug-info">, Alias<fno_standalone_debug>; def fno_limit_debug_info : Flag<["-"], "fno-limit-debug-info">, Alias<fstandalone_debug>; @@ -970,6 +1032,10 @@ 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">, + Group<f_Group>, Flags<[CC1Option]>, + HelpText<"Enable optimizations based on the strict rules for overwriting " + "polymorphic C++ objects">; def fstrict_overflow : Flag<["-"], "fstrict-overflow">, Group<f_Group>; def fsyntax_only : Flag<["-"], "fsyntax-only">, Flags<[DriverOption,CoreOption,CC1Option]>, Group<Action_Group>; @@ -1073,26 +1139,40 @@ def fdebug_types_section: Flag <["-"], "fdebug-types-section">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Place debug types in their own section (ELF Only)">; def fno_debug_types_section: Flag<["-"], "fno-debug-types-section">, Group<f_Group>, Flags<[CC1Option]>; +def fdebug_prefix_map_EQ + : Joined<["-"], "fdebug-prefix-map=">, Group<f_Group>, Flags<[CC1Option]>, + HelpText<"remap file source paths in debug info">; def g_Flag : Flag<["-"], "g">, Group<g_Group>, - HelpText<"Generate source-level debug information">, Flags<[CC1Option,CC1AsOption]>; -def gline_tables_only : Flag<["-"], "gline-tables-only">, Group<g_Group>, - HelpText<"Emit debug line number tables only">, Flags<[CC1Option]>; + HelpText<"Generate source-level debug information">; +def gline_tables_only : Flag<["-"], "gline-tables-only">, Group<gN_Group>, + HelpText<"Emit debug line number tables only">; def gmlt : Flag<["-"], "gmlt">, Alias<gline_tables_only>; -def g0 : Flag<["-"], "g0">, Group<g_Group>; -def g1 : Flag<["-"], "g1">, Group<g_Group>; -def g2 : Flag<["-"], "g2">, Group<g_Group>; -def g3 : Flag<["-"], "g3">, Group<g_Group>; -def ggdb : Flag<["-"], "ggdb">, Group<g_Group>; -def ggdb0 : Flag<["-"], "ggdb0">, Group<g_Group>; -def ggdb1 : Flag<["-"], "ggdb1">, Group<g_Group>; -def ggdb2 : Flag<["-"], "ggdb2">, Group<g_Group>; -def ggdb3 : Flag<["-"], "ggdb3">, Group<g_Group>; +def g0 : Flag<["-"], "g0">, Group<gN_Group>; +def g1 : Flag<["-"], "g1">, Group<gN_Group>, Alias<gline_tables_only>; +def g2 : Flag<["-"], "g2">, Group<gN_Group>; +def g3 : Flag<["-"], "g3">, Group<gN_Group>; +def ggdb : Flag<["-"], "ggdb">, Group<gTune_Group>; +def ggdb0 : Flag<["-"], "ggdb0">, Group<ggdbN_Group>; +def ggdb1 : Flag<["-"], "ggdb1">, Group<ggdbN_Group>; +def ggdb2 : Flag<["-"], "ggdb2">, Group<ggdbN_Group>; +def ggdb3 : Flag<["-"], "ggdb3">, Group<ggdbN_Group>; +def glldb : Flag<["-"], "glldb">, Group<gTune_Group>; +def gsce : Flag<["-"], "gsce">, Group<gTune_Group>; def gdwarf_2 : Flag<["-"], "gdwarf-2">, Group<g_Group>, - HelpText<"Generate source-level debug information with dwarf version 2">, Flags<[CC1Option,CC1AsOption]>; + HelpText<"Generate source-level debug information with dwarf version 2">; def gdwarf_3 : Flag<["-"], "gdwarf-3">, Group<g_Group>, - HelpText<"Generate source-level debug information with dwarf version 3">, Flags<[CC1Option,CC1AsOption]>; + HelpText<"Generate source-level debug information with dwarf version 3">; def gdwarf_4 : Flag<["-"], "gdwarf-4">, Group<g_Group>, - HelpText<"Generate source-level debug information with dwarf version 4">, Flags<[CC1Option,CC1AsOption]>; + HelpText<"Generate source-level debug information with dwarf version 4">; +def gdwarf_5 : Flag<["-"], "gdwarf-5">, Group<g_Group>, + HelpText<"Generate source-level debug information with dwarf version 5">; +def gcodeview : Flag<["-"], "gcodeview">, + HelpText<"Generate CodeView debug information">, + Flags<[CC1Option, CC1AsOption, CoreOption]>; +// Equivalent to our default dwarf version. Forces usual dwarf emission when +// CodeView is enabled. +def gdwarf : Flag<["-"], "gdwarf">, Alias<gdwarf_4>, Flags<[CoreOption]>; + def gfull : Flag<["-"], "gfull">, Group<g_Group>; def gused : Flag<["-"], "gused">, Group<g_Group>; def gstabs : Joined<["-"], "gstabs">, Group<g_Group>, Flags<[Unsupported]>; @@ -1110,6 +1190,9 @@ def gno_column_info : Flag<["-"], "gno-column-info">, Group<g_flags_Group>; def gsplit_dwarf : Flag<["-"], "gsplit-dwarf">, Group<g_flags_Group>; def ggnu_pubnames : Flag<["-"], "ggnu-pubnames">, Group<g_flags_Group>; def gdwarf_aranges : Flag<["-"], "gdwarf-aranges">, Group<g_flags_Group>; +def gmodules : Flag <["-"], "gmodules">, Group<f_Group>, + HelpText<"Generate debug info with external references to clang modules" + " or precompiled headers">; def headerpad__max__install__names : Joined<["-"], "headerpad_max_install_names">; def help : Flag<["-", "--"], "help">, Flags<[CC1Option,CC1AsOption]>, HelpText<"Display available options">; @@ -1173,6 +1256,13 @@ def malign_functions_EQ : Joined<["-"], "malign-functions=">, Group<clang_ignore def malign_loops_EQ : Joined<["-"], "malign-loops=">, Group<clang_ignored_m_Group>; def malign_jumps_EQ : Joined<["-"], "malign-jumps=">, Group<clang_ignored_m_Group>; def mfancy_math_387 : Flag<["-"], "mfancy-math-387">, Group<clang_ignored_m_Group>; +def mtvos_version_min_EQ : Joined<["-"], "mtvos-version-min=">, Group<m_Group>; +def mappletvos_version_min_EQ : Joined<["-"], "mappletvos-version-min=">, Alias<mtvos_version_min_EQ>; +def mtvos_simulator_version_min_EQ : Joined<["-"], "mtvos-simulator-version-min=">, Alias<mtvos_version_min_EQ>; +def mappletvsimulator_version_min_EQ : Joined<["-"], "mappletvsimulator-version-min=">, Alias<mtvos_version_min_EQ>; +def mwatchos_version_min_EQ : Joined<["-"], "mwatchos-version-min=">, Group<m_Group>; +def mwatchos_simulator_version_min_EQ : Joined<["-"], "mwatchos-simulator-version-min=">, Alias<mwatchos_version_min_EQ>; +def mwatchsimulator_version_min_EQ : Joined<["-"], "mwatchsimulator-version-min=">, Alias<mwatchos_version_min_EQ>; def march_EQ : Joined<["-"], "march=">, Group<m_Group>; def masm_EQ : Joined<["-"], "masm=">, Group<m_Group>, Flags<[DriverOption]>; def mcmodel_EQ : Joined<["-"], "mcmodel=">, Group<m_Group>; @@ -1209,6 +1299,8 @@ def mmacosx_version_min_EQ : Joined<["-"], "mmacosx-version-min=">, Group<m_Group>, HelpText<"Set Mac OS X deployment target">; def mms_bitfields : Flag<["-"], "mms-bitfields">, Group<m_Group>, Flags<[CC1Option]>, HelpText<"Set the default structure layout to be compatible with the Microsoft compiler standard">; +def mno_ms_bitfields : Flag<["-"], "mno-ms-bitfields">, Group<m_Group>, + HelpText<"Do not set the default structure layout to be compatible with the Microsoft compiler standard">; def mstackrealign : Flag<["-"], "mstackrealign">, Group<m_Group>, Flags<[CC1Option]>, HelpText<"Force realign the stack at entry to every function">; def mstack_alignment : Joined<["-"], "mstack-alignment=">, Group<m_Group>, Flags<[CC1Option]>, @@ -1217,6 +1309,8 @@ def mstack_probe_size : Joined<["-"], "mstack-probe-size=">, Group<m_Group>, Fla HelpText<"Set the stack probe size">; def mthread_model : Separate<["-"], "mthread-model">, Group<m_Group>, Flags<[CC1Option]>, HelpText<"The thread model to use, e.g. posix, single (posix by default)">; +def meabi : Separate<["-"], "meabi">, Group<m_Group>, Flags<[CC1Option]>, + HelpText<"Set EABI type, e.g. 4, 5 or gnu (default depends on triple)">; def mmmx : Flag<["-"], "mmmx">, Group<m_x86_Features_Group>; def mno_3dnowa : Flag<["-"], "mno-3dnowa">, Group<m_x86_Features_Group>; @@ -1270,6 +1364,11 @@ 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_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 munaligned_access : Flag<["-"], "munaligned-access">, Group<m_arm_Features_Group>, HelpText<"Allow memory accesses to be unaligned (AArch32/AArch64 only)">; @@ -1306,6 +1405,9 @@ def mno_fix_cortex_a53_835769 : Flag<["-"], "mno-fix-cortex-a53-835769">, def ffixed_x18 : Flag<["-"], "ffixed-x18">, Group<m_aarch64_Features_Group>, HelpText<"Reserve the x18 register (AArch64 only)">; +def msimd128 : Flag<["-"], "msimd128">, Group<m_wasm_Features_Group>; +def mno_simd128 : Flag<["-"], "mno-simd128">, Group<m_wasm_Features_Group>; + 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">, @@ -1328,8 +1430,10 @@ def mcmpb : Flag<["-"], "mcmpb">, Group<m_ppc_Features_Group>; def mno_cmpb : Flag<["-"], "mno-cmpb">, Group<m_ppc_Features_Group>; def misel : Flag<["-"], "misel">, Group<m_ppc_Features_Group>; def mno_isel : Flag<["-"], "mno-isel">, Group<m_ppc_Features_Group>; -def mmfcrf : Flag<["-"], "mmfcrf">, Group<m_ppc_Features_Group>; -def mno_mfcrf : Flag<["-"], "mno-mfcrf">, Group<m_ppc_Features_Group>; +def mmfocrf : Flag<["-"], "mmfocrf">, Group<m_ppc_Features_Group>; +def mmfcrf : Flag<["-"], "mmfcrf">, Alias<mmfocrf>; +def mno_mfocrf : Flag<["-"], "mno-mfocrf">, Group<m_ppc_Features_Group>; +def mno_mfcrf : Flag<["-"], "mno-mfcrf">, Alias<mno_mfocrf>; def mpopcntd : Flag<["-"], "mpopcntd">, Group<m_ppc_Features_Group>; def mno_popcntd : Flag<["-"], "mno-popcntd">, Group<m_ppc_Features_Group>; def mqpx : Flag<["-"], "mqpx">, Group<m_ppc_Features_Group>; @@ -1368,6 +1472,11 @@ def mred_zone : Flag<["-"], "mred-zone">, Group<m_Group>; def mregparm_EQ : Joined<["-"], "mregparm=">, Group<m_Group>; def mrelax_all : Flag<["-"], "mrelax-all">, Group<m_Group>, Flags<[CC1Option,CC1AsOption]>, HelpText<"(integrated-as) Relax all machine instructions">; +def mincremental_linker_compatible : Flag<["-"], "mincremental-linker-compatible">, Group<m_Group>, + Flags<[CC1Option,CC1AsOption]>, + HelpText<"(integrated-as) Emit an object file which can be used with an incremental linker">; +def mno_incremental_linker_compatible : Flag<["-"], "mno-incremental-linker-compatible">, Group<m_Group>, + HelpText<"(integrated-as) Emit an object file which cannot be used with an incremental linker">; def mrtd : Flag<["-"], "mrtd">, Group<m_Group>, Flags<[CC1Option]>, HelpText<"Make StdCall calling convention the default">; def msmall_data_threshold_EQ : Joined <["-"], "msmall-data-threshold=">, Group<m_Group>; @@ -1414,6 +1523,11 @@ def mrdseed : Flag<["-"], "mrdseed">, Group<m_x86_Features_Group>; def madx : Flag<["-"], "madx">, Group<m_x86_Features_Group>; def msha : Flag<["-"], "msha">, Group<m_x86_Features_Group>; def mcx16 : Flag<["-"], "mcx16">, Group<m_x86_Features_Group>; +def mfxsr : Flag<["-"], "mfxsr">, Group<m_x86_Features_Group>; +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 mips16 : Flag<["-"], "mips16">, Group<m_Group>; def mno_mips16 : Flag<["-"], "mno-mips16">, Group<m_Group>; def mmicromips : Flag<["-"], "mmicromips">, Group<m_Group>; @@ -1515,6 +1629,8 @@ def no_pedantic : Flag<["-", "--"], "no-pedantic">, Group<pedantic_Group>; def no__dead__strip__inits__and__terms : Flag<["-"], "no_dead_strip_inits_and_terms">; def nobuiltininc : Flag<["-"], "nobuiltininc">, Flags<[CC1Option]>, HelpText<"Disable builtin #include directories">; +def nocudainc : Flag<["-"], "nocudainc">; +def nocudalib : Flag<["-"], "nocudalib">; def nodefaultlibs : Flag<["-"], "nodefaultlibs">; def nofixprebinding : Flag<["-"], "nofixprebinding">; def nolibc : Flag<["-"], "nolibc">; @@ -1576,7 +1692,7 @@ def resource_dir_EQ : Joined<["-"], "resource-dir=">, Flags<[DriverOption]>, Alias<resource_dir>; def rpath : Separate<["-"], "rpath">, Flags<[LinkerInput]>; def rtlib_EQ : Joined<["-", "--"], "rtlib=">; -def r : Flag<["-"], "r">; +def r : Flag<["-"], "r">, Flags<[LinkerInput,NoArgumentUnused]>; def save_temps_EQ : Joined<["-", "--"], "save-temps=">, Flags<[DriverOption]>, HelpText<"Save intermediate compilation results.">; def save_temps : Flag<["-", "--"], "save-temps">, Flags<[DriverOption]>, @@ -1783,16 +1899,22 @@ def _write_user_dependencies : Flag<["--"], "write-user-dependencies">, Alias<MM def _ : Joined<["--"], "">, Flags<[Unsupported]>; def mieee_rnd_near : Flag<["-"], "mieee-rnd-near">, Group<m_hexagon_Features_Group>; -def mv1 : Flag<["-"], "mv1">, Group<m_hexagon_Features_Group>, Alias<march_EQ>, - AliasArgs<["v1"]>; -def mv2 : Flag<["-"], "mv2">, Group<m_hexagon_Features_Group>, Alias<march_EQ>, - AliasArgs<["v2"]>; -def mv3 : Flag<["-"], "mv3">, Group<m_hexagon_Features_Group>, Alias<march_EQ>, - AliasArgs<["v3"]>; -def mv4 : Flag<["-"], "mv4">, Group<m_hexagon_Features_Group>, Alias<march_EQ>, - AliasArgs<["v4"]>; -def mv5 : Flag<["-"], "mv5">, Group<m_hexagon_Features_Group>, Alias<march_EQ>, +def mv4 : Flag<["-"], "mv4">, Group<m_hexagon_Features_Group>, + Alias<mcpu_EQ>, AliasArgs<["v4"]>; +def mv5 : Flag<["-"], "mv5">, Group<m_hexagon_Features_Group>, Alias<mcpu_EQ>, AliasArgs<["v5"]>; +def mv55 : Flag<["-"], "mv55">, Group<m_hexagon_Features_Group>, + Alias<mcpu_EQ>, AliasArgs<["v55"]>; +def mv60 : Flag<["-"], "mv60">, Group<m_hexagon_Features_Group>, + Alias<mcpu_EQ>, AliasArgs<["v60"]>; +def mhexagon_hvx : Flag<["-"], "mhvx">, Group<m_hexagon_Features_Group>, + Flags<[CC1Option]>, HelpText<"Enable Hexagon Vector eXtensions">; +def mno_hexagon_hvx : Flag<["-"], "mno-hvx">, Group<m_hexagon_Features_Group>, + Flags<[CC1Option]>, HelpText<"Disable Hexagon Vector eXtensions">; +def mhexagon_hvx_double : Flag<["-"], "mhvx-double">, Group<m_hexagon_Features_Group>, + Flags<[CC1Option]>, HelpText<"Enable Hexagon Double Vector eXtensions">; +def mno_hexagon_hvx_double : Flag<["-"], "mno-hvx-double">, Group<m_hexagon_Features_Group>, + Flags<[CC1Option]>, HelpText<"Disable Hexagon Double Vector eXtensions">; // These are legacy user-facing driver-level option spellings. They are always // aliases for options that are spelled using the more common Unix / GNU flag diff --git a/contrib/llvm/tools/clang/include/clang/Driver/SanitizerArgs.h b/contrib/llvm/tools/clang/include/clang/Driver/SanitizerArgs.h index 82b668a..c2611b5 100644 --- a/contrib/llvm/tools/clang/include/clang/Driver/SanitizerArgs.h +++ b/contrib/llvm/tools/clang/include/clang/Driver/SanitizerArgs.h @@ -27,13 +27,15 @@ class SanitizerArgs { SanitizerSet TrapSanitizers; std::vector<std::string> BlacklistFiles; + std::vector<std::string> ExtraDeps; int CoverageFeatures; int MsanTrackOrigins; bool MsanUseAfterDtor; + bool CfiCrossDso; int AsanFieldPadding; - bool AsanZeroBaseShadow; bool AsanSharedRuntime; bool LinkCXXRuntimes; + bool NeedPIE; public: /// Parses the sanitizer arguments from an argument list. @@ -52,6 +54,8 @@ class SanitizerArgs { bool needsSafeStackRt() const { return Sanitizers.has(SanitizerKind::SafeStack); } + bool needsCfiRt() const; + bool needsCfiDiagRt() const; bool requiresPIE() const; bool needsUnwindTables() const; diff --git a/contrib/llvm/tools/clang/include/clang/Driver/ToolChain.h b/contrib/llvm/tools/clang/include/clang/Driver/ToolChain.h index aba18c9..ed73107 100644 --- a/contrib/llvm/tools/clang/include/clang/Driver/ToolChain.h +++ b/contrib/llvm/tools/clang/include/clang/Driver/ToolChain.h @@ -18,6 +18,7 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/Triple.h" #include "llvm/Support/Path.h" +#include "llvm/Target/TargetOptions.h" #include <memory> #include <string> @@ -30,7 +31,10 @@ namespace opt { } namespace clang { - class ObjCRuntime; +class ObjCRuntime; +namespace vfs { +class FileSystem; +} namespace driver { class Compilation; @@ -89,6 +93,7 @@ private: protected: MultilibSet Multilibs; + const char *DefaultLinker = "ld"; ToolChain(const Driver &D, const llvm::Triple &T, const llvm::opt::ArgList &Args); @@ -119,7 +124,8 @@ public: // Accessors - const Driver &getDriver() const; + const Driver &getDriver() const { return D; } + vfs::FileSystem &getVFS() const; const llvm::Triple &getTriple() const { return Triple; } llvm::Triple::ArchType getArch() const { return Triple.getArch(); } @@ -151,6 +157,20 @@ public: // Returns the RTTIMode for the toolchain with the current arguments. RTTIMode getRTTIMode() const { return CachedRTTIMode; } + /// \brief Return any implicit target and/or mode flag for an invocation of + /// the compiler driver as `ProgName`. + /// + /// For example, when called with i686-linux-android-g++, the first element + /// of the return value will be set to `"i686-linux-android"` and the second + /// will be set to "--driver-mode=g++"`. + /// + /// \pre `llvm::InitializeAllTargets()` has been called. + /// \param ProgName The name the Clang driver was invoked with (from, + /// e.g., argv[0]) + /// \return A pair of (`target`, `mode-flag`), where one or both may be empty. + static std::pair<std::string, std::string> + getTargetAndModeFromProgramName(StringRef ProgName); + // Tool access. /// TranslateArgs - Create a new derived argument list for any argument @@ -167,7 +187,7 @@ public: /// Choose a tool to use to handle the action \p JA. /// /// This can be overridden when a particular ToolChain needs to use - /// a C compiler other than Clang. + /// a compiler other than Clang. virtual Tool *SelectTool(const JobAction &JA) const; // Helper methods @@ -184,7 +204,7 @@ public: /// This is used when handling the verbose option to print detailed, /// toolchain-specific information useful for understanding the behavior of /// the driver on a specific platform. - virtual void printVerboseInfo(raw_ostream &OS) const {}; + virtual void printVerboseInfo(raw_ostream &OS) const {} // Platform defaults information @@ -236,6 +256,16 @@ public: return ToolChain::RLT_Libgcc; } + virtual std::string getCompilerRT(const llvm::opt::ArgList &Args, + StringRef Component, + bool Shared = false) const; + + const char *getCompilerRTArgString(const llvm::opt::ArgList &Args, + StringRef Component, + bool Shared = false) const; + /// needsProfileRT - returns true if instrumentation profile is on. + static bool needsProfileRT(const llvm::opt::ArgList &Args); + /// IsUnwindTablesDefault - Does this tool chain use -funwind-tables /// by default. virtual bool IsUnwindTablesDefault() const; @@ -265,8 +295,25 @@ public: /// compile unit information. virtual bool UseDwarfDebugFlags() const { return false; } + // Return the DWARF version to emit, in the absence of arguments + // to the contrary. + virtual unsigned GetDefaultDwarfVersion() const { return 4; } + + // True if the driver should assume "-fstandalone-debug" + // in the absence of an option specifying otherwise, + // provided that debugging was requested in the first place. + // i.e. a value of 'true' does not imply that debugging is wanted. + virtual bool GetDefaultStandaloneDebug() const { return false; } + + // Return the default debugger "tuning." + virtual llvm::DebuggerKind getDefaultDebuggerTuning() const { + return llvm::DebuggerKind::GDB; + } + /// UseSjLjExceptions - Does this tool chain use SjLj exceptions. - virtual bool UseSjLjExceptions() const { return false; } + virtual bool UseSjLjExceptions(const llvm::opt::ArgList &Args) const { + return false; + } /// getThreadModel() - Which thread model does this target use? virtual std::string getThreadModel() const { return "posix"; } @@ -337,6 +384,10 @@ public: virtual void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const; + /// AddFilePathLibArgs - Add each thing in getFilePaths() as a "-L" option. + void AddFilePathLibArgs(const llvm::opt::ArgList &Args, + llvm::opt::ArgStringList &CmdArgs) const; + /// AddCCKextLibArgs - Add the system specific linker arguments to use /// for kernel extensions (Darwin-specific). virtual void AddCCKextLibArgs(const llvm::opt::ArgList &Args, @@ -346,10 +397,17 @@ public: /// global flags for unsafe floating point math, add it and return true. /// /// This checks for presence of the -Ofast, -ffast-math or -funsafe-math flags. - virtual bool - AddFastMathRuntimeIfAvailable(const llvm::opt::ArgList &Args, + virtual bool AddFastMathRuntimeIfAvailable( + const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const; + /// addProfileRTLibs - When -fprofile-instr-profile is specified, try to pass + /// a suitable profile runtime library to the linker. + virtual void addProfileRTLibs(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const; + /// \brief Add arguments to use system-specific CUDA includes. + virtual void AddCudaIncludeArgs(const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &CC1Args) const; + /// \brief Return sanitizers which are available in this toolchain. virtual SanitizerMask getSupportedSanitizers() const; }; diff --git a/contrib/llvm/tools/clang/include/clang/Driver/Types.h b/contrib/llvm/tools/clang/include/clang/Driver/Types.h index dd95d65..22122c7 100644 --- a/contrib/llvm/tools/clang/include/clang/Driver/Types.h +++ b/contrib/llvm/tools/clang/include/clang/Driver/Types.h @@ -63,6 +63,9 @@ namespace types { /// isCXX - Is this a "C++" input (C++ and Obj-C++ sources and headers). bool isCXX(ID Id); + /// Is this LLVM IR. + bool isLLVMIR(ID Id); + /// isCuda - Is this a CUDA input. bool isCuda(ID Id); diff --git a/contrib/llvm/tools/clang/include/clang/Edit/Commit.h b/contrib/llvm/tools/clang/include/clang/Edit/Commit.h index 5cc5b9c..ac4bb47 100644 --- a/contrib/llvm/tools/clang/include/clang/Edit/Commit.h +++ b/contrib/llvm/tools/clang/include/clang/Edit/Commit.h @@ -134,12 +134,6 @@ private: SourceLocation *MacroBegin = nullptr) const; bool isAtEndOfMacroExpansion(SourceLocation loc, SourceLocation *MacroEnd = nullptr) const; - - StringRef copyString(StringRef str) { - char *buf = StrAlloc.Allocate<char>(str.size()); - std::memcpy(buf, str.data(), str.size()); - return StringRef(buf, str.size()); - } }; } diff --git a/contrib/llvm/tools/clang/include/clang/Edit/EditedSource.h b/contrib/llvm/tools/clang/include/clang/Edit/EditedSource.h index 150a5b41..b6ec8b8 100644 --- a/contrib/llvm/tools/clang/include/clang/Edit/EditedSource.h +++ b/contrib/llvm/tools/clang/include/clang/Edit/EditedSource.h @@ -10,9 +10,11 @@ #ifndef LLVM_CLANG_EDIT_EDITEDSOURCE_H #define LLVM_CLANG_EDIT_EDITEDSOURCE_H +#include "clang/Basic/IdentifierTable.h" #include "clang/Edit/FileOffset.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/StringRef.h" +#include "llvm/ADT/TinyPtrVector.h" #include "llvm/Support/Allocator.h" #include <map> @@ -39,14 +41,18 @@ class EditedSource { typedef std::map<FileOffset, FileEdit> FileEditsTy; FileEditsTy FileEdits; - llvm::DenseMap<unsigned, SourceLocation> ExpansionToArgMap; + llvm::DenseMap<unsigned, llvm::TinyPtrVector<IdentifierInfo*>> + ExpansionToArgMap; + SmallVector<std::pair<SourceLocation, IdentifierInfo*>, 2> + CurrCommitMacroArgExps; + IdentifierTable IdentTable; llvm::BumpPtrAllocator StrAlloc; public: EditedSource(const SourceManager &SM, const LangOptions &LangOpts, const PPConditionalDirectiveRecord *PPRec = nullptr) - : SourceMgr(SM), LangOpts(LangOpts), PPRec(PPRec), + : SourceMgr(SM), LangOpts(LangOpts), PPRec(PPRec), IdentTable(LangOpts), StrAlloc() { } const SourceManager &getSourceManager() const { return SourceMgr; } @@ -62,11 +68,7 @@ public: void applyRewrites(EditsReceiver &receiver); void clearRewrites(); - StringRef copyString(StringRef str) { - char *buf = StrAlloc.Allocate<char>(str.size()); - std::memcpy(buf, str.data(), str.size()); - return StringRef(buf, str.size()); - } + StringRef copyString(StringRef str) { return str.copy(StrAlloc); } StringRef copyString(const Twine &twine); private: @@ -80,6 +82,12 @@ private: StringRef getSourceText(FileOffset BeginOffs, FileOffset EndOffs, bool &Invalid); FileEditsTy::iterator getActionForOffset(FileOffset Offs); + void deconstructMacroArgLoc(SourceLocation Loc, + SourceLocation &ExpansionLoc, + IdentifierInfo *&II); + + void startingCommit(); + void finishedCommit(); }; } diff --git a/contrib/llvm/tools/clang/include/clang/Format/Format.h b/contrib/llvm/tools/clang/include/clang/Format/Format.h index f8c8c37..6d051e0 100644 --- a/contrib/llvm/tools/clang/include/clang/Format/Format.h +++ b/contrib/llvm/tools/clang/include/clang/Format/Format.h @@ -43,33 +43,70 @@ struct FormatStyle { /// \brief The extra indent or outdent of access modifiers, e.g. \c public:. int AccessModifierOffset; + /// \brief Different styles for aligning after open brackets. + enum BracketAlignmentStyle { + /// \brief Align parameters on the open bracket, e.g.: + /// \code + /// someLongFunction(argument1, + /// argument2); + /// \endcode + BAS_Align, + /// \brief Don't align, instead use \c ContinuationIndentWidth, e.g.: + /// \code + /// someLongFunction(argument1, + /// argument2); + /// \endcode + BAS_DontAlign, + /// \brief Always break after an open bracket, if the parameters don't fit + /// on a single line, e.g.: + /// \code + /// someLongFunction( + /// argument1, argument2); + /// \endcode + BAS_AlwaysBreak, + }; + /// \brief If \c true, horizontally aligns arguments after an open bracket. /// /// This applies to round brackets (parentheses), angle brackets and square - /// brackets. This will result in formattings like - /// \code - /// someLongFunction(argument1, - /// argument2); - /// \endcode - bool AlignAfterOpenBracket; + /// brackets. + BracketAlignmentStyle AlignAfterOpenBracket; /// \brief If \c true, aligns consecutive assignments. /// /// This will align the assignment operators of consecutive lines. This /// will result in formattings like /// \code - /// int aaaa = 12; - /// int b = 23; - /// int ccc = 23; + /// int aaaa = 12; + /// int b = 23; + /// int ccc = 23; /// \endcode bool AlignConsecutiveAssignments; + /// \brief If \c true, aligns consecutive declarations. + /// + /// This will align the declaration names of consecutive lines. This + /// will result in formattings like + /// \code + /// int aaaa = 12; + /// float b = 23; + /// std::string ccc = 23; + /// \endcode + bool AlignConsecutiveDeclarations; + /// \brief If \c 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 /// expressions. + /// + /// Specifically, this aligns operands of a single expression that needs to be + /// split over multiple lines, e.g.: + /// \code + /// int aaa = bbbbbbbbbbbbbbb + + /// ccccccccccccccc; + /// \endcode bool AlignOperands; /// \brief If \c true, aligns trailing comments. @@ -119,13 +156,33 @@ struct FormatStyle { DRTBS_None, /// Always break after the return type. DRTBS_All, - /// Always break after the return types of top level functions. + /// Always break after the return types of top-level functions. DRTBS_TopLevel, }; - /// \brief The function definition return type breaking style to use. + /// \brief Different ways to break after the function definition or + /// declaration return type. + enum ReturnTypeBreakingStyle { + /// Break after return type automatically. + /// \c PenaltyReturnTypeOnItsOwnLine is taken into account. + RTBS_None, + /// Always break after the return type. + RTBS_All, + /// Always break after the return types of top-level functions. + RTBS_TopLevel, + /// Always break after the return type of function definitions. + RTBS_AllDefinitions, + /// Always break after the return type of top-level definitions. + RTBS_TopLevelDefinitions, + }; + + /// \brief The function definition return type breaking style to use. This + /// option is deprecated and is retained for backwards compatibility. DefinitionReturnTypeBreakingStyle AlwaysBreakAfterDefinitionReturnType; + /// \brief The function declaration return type breaking style to use. + ReturnTypeBreakingStyle AlwaysBreakAfterReturnType; + /// \brief If \c true, always break before multiline string literals. /// /// This flag is mean to make cases where there are multiple multiline strings @@ -169,19 +226,55 @@ struct FormatStyle { /// Like ``Attach``, but break before braces on enum, function, and record /// definitions. BS_Mozilla, - /// Like \c Attach, but break before function definitions, and 'else'. + /// Like \c Attach, but break before function definitions, 'catch', and 'else'. BS_Stroustrup, /// Always break before braces. BS_Allman, /// Always break before braces and add an extra level of indentation to /// braces of control statements, not to those of class, function /// or other definitions. - BS_GNU + BS_GNU, + /// Like ``Attach``, but break before functions. + BS_WebKit, + /// Configure each individual brace in \c BraceWrapping. + BS_Custom }; /// \brief The brace breaking style to use. BraceBreakingStyle BreakBeforeBraces; + /// \brief Precise control over the wrapping of braces. + struct BraceWrappingFlags { + /// \brief Wrap class definitions. + bool AfterClass; + /// \brief Wrap control statements (if/for/while/switch/..). + bool AfterControlStatement; + /// \brief Wrap enum definitions. + bool AfterEnum; + /// \brief Wrap function definitions. + bool AfterFunction; + /// \brief Wrap namespace definitions. + bool AfterNamespace; + /// \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. + bool BeforeCatch; + /// \brief Wrap before \c else. + bool BeforeElse; + /// \brief Indent the wrapped braces themselves. + bool IndentBraces; + }; + + /// \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. + BraceWrappingFlags BraceWrapping; + /// \brief If \c true, ternary operators will be placed after line breaks. bool BreakBeforeTernaryOperators; @@ -189,6 +282,9 @@ struct FormatStyle { /// the commas with the colon. bool BreakConstructorInitializersBeforeComma; + /// \brief Break after each annotation on a field in Java files. + bool BreakAfterJavaFieldAnnotations; + /// \brief The column limit. /// /// A column limit of \c 0 means that there is no column limit. In this case, @@ -250,13 +346,57 @@ struct FormatStyle { /// /// These are expected to be macros of the form: /// \code - /// FOREACH(<variable-declaration>, ...) - /// <loop-body> + /// FOREACH(<variable-declaration>, ...) + /// <loop-body> + /// \endcode + /// + /// In the .clang-format configuration file, this can be configured like: + /// \code + /// ForEachMacros: ['RANGES_FOR', 'FOREACH'] /// \endcode /// /// For example: BOOST_FOREACH. std::vector<std::string> ForEachMacros; + /// \brief See documentation of \c IncludeCategories. + struct IncludeCategory { + /// \brief The regular expression that this category matches. + std::string Regex; + /// \brief The priority to assign to this category. + int Priority; + bool operator==(const IncludeCategory &Other) const { + return Regex == Other.Regex && Priority == Other.Priority; + } + }; + + /// \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 + /// 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 + /// (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 + /// IncludeCategories: + /// - Regex: '^"(llvm|llvm-c|clang|clang-c)/' + /// Priority: 2 + /// - Regex: '^(<|"(gtest|isl|json)/)' + /// Priority: 3 + /// - Regex: '.*' + /// Priority: 1 + /// \endcode + std::vector<IncludeCategory> IncludeCategories; + /// \brief Indent case labels one level from the switch statement. /// /// When \c false, use the same indentation level as for the switch statement. @@ -287,7 +427,9 @@ struct FormatStyle { LK_JavaScript, /// Should be used for Protocol Buffers /// (https://developers.google.com/protocol-buffers/). - LK_Proto + LK_Proto, + /// Should be used for TableGen code. + LK_TableGen }; /// \brief Language, this format style is targeted at. @@ -355,9 +497,15 @@ struct FormatStyle { PAS_Middle }; - /// Pointer and reference alignment style. + /// \brief Pointer and reference alignment style. PointerAlignmentStyle PointerAlignment; + /// \brief If true, clang-format will attempt to re-flow comments. + bool ReflowComments; + + /// \brief If true, clang-format will sort #includes. + bool SortIncludes; + /// \brief If \c true, a space may be inserted after C style casts. bool SpaceAfterCStyleCast; @@ -444,6 +592,7 @@ struct FormatStyle { return AccessModifierOffset == R.AccessModifierOffset && AlignAfterOpenBracket == R.AlignAfterOpenBracket && AlignConsecutiveAssignments == R.AlignConsecutiveAssignments && + AlignConsecutiveDeclarations == R.AlignConsecutiveDeclarations && AlignEscapedNewlinesLeft == R.AlignEscapedNewlinesLeft && AlignOperands == R.AlignOperands && AlignTrailingComments == R.AlignTrailingComments && @@ -457,8 +606,7 @@ struct FormatStyle { AllowShortIfStatementsOnASingleLine == R.AllowShortIfStatementsOnASingleLine && AllowShortLoopsOnASingleLine == R.AllowShortLoopsOnASingleLine && - AlwaysBreakAfterDefinitionReturnType == - R.AlwaysBreakAfterDefinitionReturnType && + AlwaysBreakAfterReturnType == R.AlwaysBreakAfterReturnType && AlwaysBreakBeforeMultilineStrings == R.AlwaysBreakBeforeMultilineStrings && AlwaysBreakTemplateDeclarations == @@ -470,8 +618,8 @@ struct FormatStyle { BreakBeforeTernaryOperators == R.BreakBeforeTernaryOperators && BreakConstructorInitializersBeforeComma == R.BreakConstructorInitializersBeforeComma && - ColumnLimit == R.ColumnLimit && - CommentPragmas == R.CommentPragmas && + BreakAfterJavaFieldAnnotations == R.BreakAfterJavaFieldAnnotations && + ColumnLimit == R.ColumnLimit && CommentPragmas == R.CommentPragmas && ConstructorInitializerAllOnOneLineOrOnePerLine == R.ConstructorInitializerAllOnOneLineOrOnePerLine && ConstructorInitializerIndentWidth == @@ -483,6 +631,7 @@ struct FormatStyle { ExperimentalAutoDetectBinPacking == R.ExperimentalAutoDetectBinPacking && ForEachMacros == R.ForEachMacros && + IncludeCategories == R.IncludeCategories && IndentCaseLabels == R.IndentCaseLabels && IndentWidth == R.IndentWidth && Language == R.Language && IndentWrappedFunctionNames == R.IndentWrappedFunctionNames && @@ -513,8 +662,7 @@ struct FormatStyle { SpacesInCStyleCastParentheses == R.SpacesInCStyleCastParentheses && SpacesInParentheses == R.SpacesInParentheses && SpacesInSquareBrackets == R.SpacesInSquareBrackets && - Standard == R.Standard && - TabWidth == R.TabWidth && + Standard == R.Standard && TabWidth == R.TabWidth && UseTab == R.UseTab; } }; @@ -569,6 +717,13 @@ 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'. +tooling::Replacements sortIncludes(const FormatStyle &Style, StringRef Code, + ArrayRef<tooling::Range> Ranges, + StringRef FileName, + unsigned *Cursor = nullptr); + /// \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. diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/ASTUnit.h b/contrib/llvm/tools/clang/include/clang/Frontend/ASTUnit.h index fa4bcf2..a5f7af5 100644 --- a/contrib/llvm/tools/clang/include/clang/Frontend/ASTUnit.h +++ b/contrib/llvm/tools/clang/include/clang/Frontend/ASTUnit.h @@ -719,7 +719,7 @@ public: /// /// \param Filename - The AST file to load. /// - /// \param PCHContainerOps - The PCHContainerOperations to use for loading and + /// \param PCHContainerRdr - The PCHContainerOperations to use for loading and /// creating modules. /// \param Diags - The diagnostics engine to use for reporting errors; its /// lifetime is expected to extend past that of the returned ASTUnit. @@ -728,8 +728,8 @@ public: static std::unique_ptr<ASTUnit> LoadFromASTFile( const std::string &Filename, const PCHContainerReader &PCHContainerRdr, IntrusiveRefCntPtr<DiagnosticsEngine> Diags, - const FileSystemOptions &FileSystemOpts, bool OnlyLocalDecls = false, - ArrayRef<RemappedFile> RemappedFiles = None, + const FileSystemOptions &FileSystemOpts, bool UseDebugInfo = false, + bool OnlyLocalDecls = false, ArrayRef<RemappedFile> RemappedFiles = None, bool CaptureDiagnostics = false, bool AllowPCHWithCompilerErrors = false, bool UserFilesAreVolatile = false); @@ -737,14 +737,15 @@ private: /// \brief Helper function for \c LoadFromCompilerInvocation() and /// \c LoadFromCommandLine(), which loads an AST from a compiler invocation. /// - /// \param PrecompilePreamble Whether to precompile the preamble of this - /// translation unit, to improve the performance of reparsing. + /// \param PrecompilePreambleAfterNParses After how many parses the preamble + /// of this translation unit should be precompiled, to improve the performance + /// of reparsing. Set to zero to disable preambles. /// /// \returns \c true if a catastrophic failure occurred (which means that the /// \c ASTUnit itself is invalid), or \c false otherwise. bool LoadFromCompilerInvocation( std::shared_ptr<PCHContainerOperations> PCHContainerOps, - bool PrecompilePreamble); + unsigned PrecompilePreambleAfterNParses); public: @@ -783,7 +784,8 @@ public: ASTFrontendAction *Action = nullptr, ASTUnit *Unit = nullptr, bool Persistent = true, StringRef ResourceFilesPath = StringRef(), bool OnlyLocalDecls = false, bool CaptureDiagnostics = false, - bool PrecompilePreamble = false, bool CacheCodeCompletionResults = false, + unsigned PrecompilePreambleAfterNParses = 0, + bool CacheCodeCompletionResults = false, bool IncludeBriefCommentsInCodeCompletion = false, bool UserFilesAreVolatile = false, std::unique_ptr<ASTUnit> *ErrAST = nullptr); @@ -805,8 +807,9 @@ public: static std::unique_ptr<ASTUnit> LoadFromCompilerInvocation( CompilerInvocation *CI, std::shared_ptr<PCHContainerOperations> PCHContainerOps, - IntrusiveRefCntPtr<DiagnosticsEngine> Diags, bool OnlyLocalDecls = false, - bool CaptureDiagnostics = false, bool PrecompilePreamble = false, + IntrusiveRefCntPtr<DiagnosticsEngine> Diags, FileManager *FileMgr, + bool OnlyLocalDecls = false, bool CaptureDiagnostics = false, + unsigned PrecompilePreambleAfterNParses = 0, TranslationUnitKind TUKind = TU_Complete, bool CacheCodeCompletionResults = false, bool IncludeBriefCommentsInCodeCompletion = false, @@ -827,6 +830,8 @@ public: /// /// \param ResourceFilesPath - The path to the compiler resource files. /// + /// \param ModuleFormat - If provided, uses the specific module format. + /// /// \param ErrAST - If non-null and parsing failed without any AST to return /// (e.g. because the PCH could not be loaded), this accepts the ASTUnit /// mainly to allow the caller to see the diagnostics. @@ -840,11 +845,13 @@ public: bool OnlyLocalDecls = false, bool CaptureDiagnostics = false, ArrayRef<RemappedFile> RemappedFiles = None, bool RemappedFilesKeepOriginalName = true, - bool PrecompilePreamble = false, TranslationUnitKind TUKind = TU_Complete, + unsigned PrecompilePreambleAfterNParses = 0, + TranslationUnitKind TUKind = TU_Complete, bool CacheCodeCompletionResults = false, bool IncludeBriefCommentsInCodeCompletion = false, bool AllowPCHWithCompilerErrors = false, bool SkipFunctionBodies = false, bool UserFilesAreVolatile = false, bool ForSerialization = false, + llvm::Optional<StringRef> ModuleFormat = llvm::None, std::unique_ptr<ASTUnit> *ErrAST = nullptr); /// \brief Reparse the source files using the same command-line options that @@ -909,7 +916,7 @@ public: GlobalModuleIndex *loadGlobalModuleIndex(SourceLocation TriggerLoc) override { return nullptr; } bool lookupMissingImports(StringRef Name, SourceLocation TriggerLoc) override - { return 0; }; + { return 0; } }; } // namespace clang diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/CodeGenOptions.def b/contrib/llvm/tools/clang/include/clang/Frontend/CodeGenOptions.def index 803d023..d9f6ab7 100644 --- a/contrib/llvm/tools/clang/include/clang/Frontend/CodeGenOptions.def +++ b/contrib/llvm/tools/clang/include/clang/Frontend/CodeGenOptions.def @@ -48,6 +48,9 @@ CODEGENOPT(DisableLLVMOpts , 1, 0) ///< Don't run any optimizations, for use i ///< getting .bc files that correspond to the ///< internal state before optimizations are ///< done. +CODEGENOPT(DisableLLVMPasses , 1, 0) ///< Don't run any LLVM IR passes to get + ///< the pristine IR generated by the + ///< frontend. 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 @@ -57,6 +60,7 @@ CODEGENOPT(EmitDeclMetadata , 1, 0) ///< Emit special metadata indicating what CODEGENOPT(EmitGcovArcs , 1, 0) ///< Emit coverage data files, aka. GCDA. CODEGENOPT(EmitGcovNotes , 1, 0) ///< Emit coverage "notes" files, aka GCNO. 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) CODEGENOPT(ForbidGuardVariables , 1, 0) ///< Issue errors if C++ guard variables @@ -69,6 +73,11 @@ CODEGENOPT(LessPreciseFPMAD , 1, 0) ///< Enable less precise MAD instructions t ///< 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(IncrementalLinkerCompatible, 1, 0) ///< Emit an object file which can + ///< be used with an incremental + ///< linker. CODEGENOPT(MergeAllConstants , 1, 1) ///< Merge identical constants. CODEGENOPT(MergeFunctions , 1, 0) ///< Set when -fmerge-functions is enabled. CODEGENOPT(MSVolatile , 1, 0) ///< Set when /volatile:ms is enabled. @@ -114,6 +123,7 @@ CODEGENOPT(SanitizeMemoryTrackOrigins, 2, 0) ///< Enable tracking origins in ///< MemorySanitizer CODEGENOPT(SanitizeMemoryUseAfterDtor, 1, 0) ///< Enable use-after-delete detection ///< in MemorySanitizer +CODEGENOPT(SanitizeCfiCrossDso, 1, 0) ///< Enable cross-dso support in CFI. CODEGENOPT(SanitizeCoverageType, 2, 0) ///< Type of sanitizer coverage ///< instrumentation. CODEGENOPT(SanitizeCoverageIndirectCalls, 1, 0) ///< Enable sanitizer coverage @@ -127,6 +137,7 @@ CODEGENOPT(SanitizeCoverage8bitCounters, 1, 0) ///< Use 8-bit frequency counters 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. @@ -145,7 +156,7 @@ CODEGENOPT(UseRegisterSizedBitfieldAccess , 1, 0) CODEGENOPT(VerifyModule , 1, 1) ///< Control whether the module should be run ///< through the LLVM Verifier. -CODEGENOPT(StackRealignment , 1, 0) ///< Control whether to permit stack +CODEGENOPT(StackRealignment , 1, 0) ///< Control whether to force stack ///< realignment. CODEGENOPT(UseInitArray , 1, 0) ///< Control whether to use .init_array or ///< .ctors. @@ -156,6 +167,13 @@ VALUE_CODEGENOPT(StackProbeSize , 32, 4096) ///< Overrides default stack CODEGENOPT(DebugColumnInfo, 1, 0) ///< Whether or not to use column information ///< in debug info. +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 + ///< anonymous namespaces + CODEGENOPT(EmitLLVMUseLists, 1, 0) ///< Control whether to serialize use-lists. /// The user specified number of registers to be used for integral arguments, @@ -168,9 +186,17 @@ VALUE_CODEGENOPT(SSPBufferSize, 32, 0) /// The kind of generated debug info. ENUM_CODEGENOPT(DebugInfo, DebugInfoKind, 3, NoDebugInfo) -/// Dwarf version. +/// Tune the debug info for this debugger. +ENUM_CODEGENOPT(DebuggerTuning, DebuggerKind, 2, DebuggerKindDefault) + +/// Dwarf version. Version zero indicates to LLVM that no DWARF should be +/// emitted. VALUE_CODEGENOPT(DwarfVersion, 3, 0) +/// Whether we should emit CodeView debug information. It's possible to emit +/// CodeView and DWARF into the same object. +CODEGENOPT(EmitCodeView, 1, 0) + /// The kind of inlining to perform. ENUM_CODEGENOPT(Inlining, InliningMethod, 2, NoInlining) diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/CodeGenOptions.h b/contrib/llvm/tools/clang/include/clang/Frontend/CodeGenOptions.h index 53246bc..fac6f1a 100644 --- a/contrib/llvm/tools/clang/include/clang/Frontend/CodeGenOptions.h +++ b/contrib/llvm/tools/clang/include/clang/Frontend/CodeGenOptions.h @@ -16,6 +16,7 @@ #include "clang/Basic/Sanitizers.h" #include "llvm/Support/Regex.h" +#include <map> #include <memory> #include <string> #include <vector> @@ -81,6 +82,13 @@ public: FullDebugInfo /// Generate complete debug info. }; + enum DebuggerKind { + DebuggerKindDefault, + DebuggerKindGDB, + DebuggerKindLLDB, + DebuggerKindSCE + }; + enum TLSModel { GeneralDynamicTLSModel, LocalDynamicTLSModel, @@ -120,6 +128,8 @@ public: /// non-empty. std::string DwarfDebugFlags; + std::map<std::string, std::string> DebugPrefixMap; + /// The ABI to use for passing floating point arguments. std::string FloatABI; @@ -127,7 +137,7 @@ public: std::string LimitFloatPrecision; /// The name of the bitcode file to link before optzns. - std::string LinkBitcodeFile; + std::vector<std::pair<unsigned, std::string>> LinkBitcodeFiles; /// The user provided name for the "main file", if non-empty. This is useful /// in situations where the input file name does not match the original input @@ -164,6 +174,13 @@ public: /// Name of the profile file to use as input for -fprofile-instr-use std::string InstrProfileInput; + /// 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. diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/CompilerInstance.h b/contrib/llvm/tools/clang/include/clang/Frontend/CompilerInstance.h index 45e5ed1..83eed2c 100644 --- a/contrib/llvm/tools/clang/include/clang/Frontend/CompilerInstance.h +++ b/contrib/llvm/tools/clang/include/clang/Frontend/CompilerInstance.h @@ -78,6 +78,9 @@ class CompilerInstance : public ModuleLoader { /// The target being compiled for. IntrusiveRefCntPtr<TargetInfo> Target; + /// Auxiliary Target info. + IntrusiveRefCntPtr<TargetInfo> AuxTarget; + /// The virtual file system. IntrusiveRefCntPtr<vfs::FileSystem> VirtualFileSystem; @@ -126,13 +129,6 @@ class CompilerInstance : public ModuleLoader { /// along with the module map llvm::DenseMap<const IdentifierInfo *, Module *> KnownModules; - /// \brief Module names that have an override for the target file. - llvm::StringMap<std::string> ModuleFileOverrides; - - /// \brief Module files that we've explicitly loaded via \ref loadModuleFile, - /// and their dependencies. - llvm::StringSet<> ExplicitlyLoadedModuleFiles; - /// \brief The location of the module-import keyword for the last module /// import. SourceLocation LastModuleImportLoc; @@ -355,10 +351,19 @@ public: return *Target; } - /// Replace the current diagnostics engine. + /// Replace the current Target. void setTarget(TargetInfo *Value); /// } + /// @name AuxTarget Info + /// { + + TargetInfo *getAuxTarget() const { return AuxTarget.get(); } + + /// Replace the current AuxTarget. + void setAuxTarget(TargetInfo *Value); + + /// } /// @name Virtual File System /// { @@ -650,6 +655,7 @@ public: StringRef Path, StringRef Sysroot, bool DisablePCHValidation, bool AllowPCHWithCompilerErrors, Preprocessor &PP, ASTContext &Context, const PCHContainerReader &PCHContainerRdr, + ArrayRef<IntrusiveRefCntPtr<ModuleFileExtension>> Extensions, void *DeserializationListener, bool OwnDeserializationListener, bool Preamble, bool UseGlobalModuleIndex); diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/CompilerInvocation.h b/contrib/llvm/tools/clang/include/clang/Frontend/CompilerInvocation.h index 7d12548..0b4a1e5 100644 --- a/contrib/llvm/tools/clang/include/clang/Frontend/CompilerInvocation.h +++ b/contrib/llvm/tools/clang/include/clang/Frontend/CompilerInvocation.h @@ -72,7 +72,7 @@ public: ~CompilerInvocationBase(); CompilerInvocationBase(const CompilerInvocationBase &X); - + LangOptions *getLangOpts() { return LangOpts.get(); } const LangOptions *getLangOpts() const { return LangOpts.get(); } diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/DependencyOutputOptions.h b/contrib/llvm/tools/clang/include/clang/Frontend/DependencyOutputOptions.h index 2221b54..129b534 100644 --- a/contrib/llvm/tools/clang/include/clang/Frontend/DependencyOutputOptions.h +++ b/contrib/llvm/tools/clang/include/clang/Frontend/DependencyOutputOptions.h @@ -47,6 +47,9 @@ public: /// must contain at least one entry. std::vector<std::string> Targets; + /// A list of filenames to be used as extra dependencies for every target. + std::vector<std::string> ExtraDeps; + /// \brief The file to write GraphViz-formatted header dependencies to. std::string DOTOutputFile; diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/DiagnosticRenderer.h b/contrib/llvm/tools/clang/include/clang/Frontend/DiagnosticRenderer.h index 84a0f50..c372fdd 100644 --- a/contrib/llvm/tools/clang/include/clang/Frontend/DiagnosticRenderer.h +++ b/contrib/llvm/tools/clang/include/clang/Frontend/DiagnosticRenderer.h @@ -117,13 +117,15 @@ private: void emitCaret(SourceLocation Loc, DiagnosticsEngine::Level Level, ArrayRef<CharSourceRange> Ranges, ArrayRef<FixItHint> Hints, const SourceManager &SM); + void emitSingleMacroExpansion(SourceLocation Loc, + DiagnosticsEngine::Level Level, + ArrayRef<CharSourceRange> Ranges, + const SourceManager &SM); void emitMacroExpansions(SourceLocation Loc, DiagnosticsEngine::Level Level, ArrayRef<CharSourceRange> Ranges, ArrayRef<FixItHint> Hints, - const SourceManager &SM, - unsigned &MacroDepth, - unsigned OnMacroInst = 0); + const SourceManager &SM); public: /// \brief Emit a diagnostic. /// diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/FrontendOptions.h b/contrib/llvm/tools/clang/include/clang/Frontend/FrontendOptions.h index c3aa226..c800a51 100644 --- a/contrib/llvm/tools/clang/include/clang/Frontend/FrontendOptions.h +++ b/contrib/llvm/tools/clang/include/clang/Frontend/FrontendOptions.h @@ -11,6 +11,7 @@ #define LLVM_CLANG_FRONTEND_FRONTENDOPTIONS_H #include "clang/Frontend/CommandLineSourceLoc.h" +#include "clang/Serialization/ModuleFileExtension.h" #include "clang/Sema/CodeCompleteOptions.h" #include "llvm/ADT/StringRef.h" #include <string> @@ -91,7 +92,7 @@ class FrontendInputFile { bool IsSystem; public: - FrontendInputFile() : Buffer(nullptr), Kind(IK_None) { } + FrontendInputFile() : Buffer(nullptr), Kind(IK_None), IsSystem(false) { } FrontendInputFile(StringRef File, InputKind Kind, bool IsSystem = false) : File(File.str()), Buffer(nullptr), Kind(Kind), IsSystem(IsSystem) { } FrontendInputFile(llvm::MemoryBuffer *buffer, InputKind Kind, @@ -147,6 +148,10 @@ public: ///< dumps in AST dumps. unsigned ASTDumpLookups : 1; ///< Whether we include lookup table ///< dumps in AST dumps. + unsigned BuildingImplicitModule : 1; ///< Whether we are performing an + ///< implicit module build. + unsigned ModulesEmbedAllFiles : 1; ///< Whether we should embed all used + ///< files into the PCM file. CodeCompleteOptions CodeCompleteOpts; @@ -234,6 +239,9 @@ public: /// The list of plugins to load. std::vector<std::string> Plugins; + /// The list of module file extensions. + std::vector<IntrusiveRefCntPtr<ModuleFileExtension>> ModuleFileExtensions; + /// \brief The list of module map files to load before processing the input. std::vector<std::string> ModuleMapFiles; @@ -241,6 +249,9 @@ public: /// processing the input. std::vector<std::string> ModuleFiles; + /// \brief The list of files to embed into the compiled module file. + std::vector<std::string> ModulesEmbedFiles; + /// \brief The list of AST files to merge. std::vector<std::string> ASTMergeFiles; @@ -251,7 +262,10 @@ public: /// \brief File name of the file that will provide record layouts /// (in the format produced by -fdump-record-layouts). std::string OverrideRecordLayoutsFile; - + + /// \brief Auxiliary triple for CUDA compilation. + std::string AuxTriple; + public: FrontendOptions() : DisableFree(false), RelocatablePCH(false), ShowHelp(false), @@ -260,6 +274,7 @@ public: FixToTemporaries(false), ARCMTMigrateEmitARCErrors(false), SkipFunctionBodies(false), UseGlobalModuleIndex(true), GenerateGlobalModuleIndex(true), ASTDumpDecls(false), ASTDumpLookups(false), + BuildingImplicitModule(false), ModulesEmbedAllFiles(false), ARCMTAction(ARCMT_None), ObjCMTAction(ObjCMT_None), ProgramAction(frontend::ParseSyntaxOnly) {} diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/PCHContainerOperations.h b/contrib/llvm/tools/clang/include/clang/Frontend/PCHContainerOperations.h index 868ea68..67c36cf 100644 --- a/contrib/llvm/tools/clang/include/clang/Frontend/PCHContainerOperations.h +++ b/contrib/llvm/tools/clang/include/clang/Frontend/PCHContainerOperations.h @@ -27,14 +27,12 @@ namespace clang { class ASTConsumer; class CodeGenOptions; class DiagnosticsEngine; -class HeaderSearchOptions; -class LangOptions; -class PreprocessorOptions; -class TargetOptions; +class CompilerInstance; struct PCHBuffer { - bool IsComplete; + uint64_t Signature; llvm::SmallVector<char, 0> Data; + bool IsComplete; }; /// This abstract interface provides operations for creating @@ -49,9 +47,7 @@ public: /// PCHGenerator that produces a wrapper file format containing a /// serialized AST bitstream. virtual std::unique_ptr<ASTConsumer> CreatePCHContainerGenerator( - DiagnosticsEngine &Diags, const HeaderSearchOptions &HSO, - const PreprocessorOptions &PPO, const TargetOptions &TO, - const LangOptions &LO, const std::string &MainFileName, + CompilerInstance &CI, const std::string &MainFileName, const std::string &OutputFileName, llvm::raw_pwrite_stream *OS, std::shared_ptr<PCHBuffer> Buffer) const = 0; }; @@ -78,9 +74,7 @@ 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( - DiagnosticsEngine &Diags, const HeaderSearchOptions &HSO, - const PreprocessorOptions &PPO, const TargetOptions &TO, - const LangOptions &LO, const std::string &MainFileName, + CompilerInstance &CI, const std::string &MainFileName, const std::string &OutputFileName, llvm::raw_pwrite_stream *OS, std::shared_ptr<PCHBuffer> Buffer) const override; }; diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/SerializedDiagnosticReader.h b/contrib/llvm/tools/clang/include/clang/Frontend/SerializedDiagnosticReader.h index 92e99d3..3db362b 100644 --- a/contrib/llvm/tools/clang/include/clang/Frontend/SerializedDiagnosticReader.h +++ b/contrib/llvm/tools/clang/include/clang/Frontend/SerializedDiagnosticReader.h @@ -81,43 +81,43 @@ protected: /// \brief Visit the start of a diagnostic block. virtual std::error_code visitStartOfDiagnostic() { return std::error_code(); - }; + } /// \brief Visit the end of a diagnostic block. - virtual std::error_code visitEndOfDiagnostic() { return std::error_code(); }; + virtual std::error_code visitEndOfDiagnostic() { return std::error_code(); } /// \brief Visit a category. This associates the category \c ID to a \c Name. virtual std::error_code visitCategoryRecord(unsigned ID, StringRef Name) { return std::error_code(); - }; + } /// \brief Visit a flag. This associates the flag's \c ID to a \c Name. virtual std::error_code visitDiagFlagRecord(unsigned ID, StringRef Name) { return std::error_code(); - }; + } /// \brief Visit a diagnostic. virtual std::error_code visitDiagnosticRecord(unsigned Severity, const Location &Location, unsigned Category, unsigned Flag, StringRef Message) { return std::error_code(); - }; + } /// \brief Visit a filename. This associates the file's \c ID to a \c Name. virtual std::error_code visitFilenameRecord(unsigned ID, unsigned Size, unsigned Timestamp, StringRef Name) { return std::error_code(); - }; + } /// \brief Visit a fixit hint. virtual std::error_code visitFixitRecord(const Location &Start, const Location &End, StringRef Text) { return std::error_code(); - }; + } /// \brief Visit a source range. virtual std::error_code visitSourceRangeRecord(const Location &Start, const Location &End) { return std::error_code(); - }; + } /// \brief Visit the version of the set of diagnostics. virtual std::error_code visitVersionRecord(unsigned Version) { return std::error_code(); - }; + } }; } // end serialized_diags namespace diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/Utils.h b/contrib/llvm/tools/clang/include/clang/Frontend/Utils.h index aa567b4..a5f667e 100644 --- a/contrib/llvm/tools/clang/include/clang/Frontend/Utils.h +++ b/contrib/llvm/tools/clang/include/clang/Frontend/Utils.h @@ -148,6 +148,9 @@ public: /// 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 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 @@ -156,7 +159,9 @@ public: /// information to, instead of writing to stderr. /// \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, bool ShowAllHeaders = false, +void AttachHeaderIncludeGen(Preprocessor &PP, + const std::vector<std::string> &ExtraHeaders, + bool ShowAllHeaders = false, StringRef OutputPath = "", bool ShowDepth = true, bool MSStyle = false); diff --git a/contrib/llvm/tools/clang/include/clang/Lex/DirectoryLookup.h b/contrib/llvm/tools/clang/include/clang/Lex/DirectoryLookup.h index 9edf119..20c4bb0 100644 --- a/contrib/llvm/tools/clang/include/clang/Lex/DirectoryLookup.h +++ b/contrib/llvm/tools/clang/include/clang/Lex/DirectoryLookup.h @@ -158,6 +158,8 @@ public: /// SearchPath at which the file was found. This only differs from the /// Filename for framework includes. /// + /// \param RequestingModule The module in which the lookup was performed. + /// /// \param SuggestedModule If non-null, and the file found is semantically /// part of a known module, this will be set to the module that should /// be imported instead of preprocessing/parsing the file found. @@ -172,6 +174,7 @@ public: const FileEntry *LookupFile(StringRef &Filename, HeaderSearch &HS, SmallVectorImpl<char> *SearchPath, SmallVectorImpl<char> *RelativePath, + Module *RequestingModule, ModuleMap::KnownHeader *SuggestedModule, bool &InUserSpecifiedSystemFramework, bool &HasBeenMapped, @@ -182,6 +185,7 @@ private: StringRef Filename, HeaderSearch &HS, SmallVectorImpl<char> *SearchPath, SmallVectorImpl<char> *RelativePath, + Module *RequestingModule, ModuleMap::KnownHeader *SuggestedModule, bool &InUserSpecifiedSystemHeader) const; diff --git a/contrib/llvm/tools/clang/include/clang/Lex/HeaderSearch.h b/contrib/llvm/tools/clang/include/clang/Lex/HeaderSearch.h index 4c13380..6d592e1 100644 --- a/contrib/llvm/tools/clang/include/clang/Lex/HeaderSearch.h +++ b/contrib/llvm/tools/clang/include/clang/Lex/HeaderSearch.h @@ -49,7 +49,8 @@ struct HeaderFileInfo { /// SrcMgr::CharacteristicKind. unsigned DirInfo : 2; - /// \brief Whether this header file info was supplied by an external source. + /// \brief Whether this header file info was supplied by an external source, + /// and has not changed since. unsigned External : 1; /// \brief Whether this header is part of a module. @@ -58,10 +59,6 @@ struct HeaderFileInfo { /// \brief Whether this header is part of the module that we are building. unsigned isCompilingModuleHeader : 1; - /// \brief Whether this header is part of the module that we are building. - /// This is an instance of ModuleMap::ModuleHeaderRole. - unsigned HeaderRole : 2; - /// \brief Whether this structure is considered to already have been /// "resolved", meaning that it was loaded from the external source. unsigned Resolved : 1; @@ -75,7 +72,7 @@ struct HeaderFileInfo { /// those framework headers. unsigned IndexHeaderMapHeader : 1; - /// \brief Whether this file had been looked up as a header. + /// \brief Whether this file has been looked up as a header. unsigned IsValid : 1; /// \brief The number of times the file has been included already. @@ -105,7 +102,6 @@ struct HeaderFileInfo { HeaderFileInfo() : isImport(false), isPragmaOnce(false), DirInfo(SrcMgr::C_User), External(false), isModuleHeader(false), isCompilingModuleHeader(false), - HeaderRole(ModuleMap::NormalHeader), Resolved(false), IndexHeaderMapHeader(false), IsValid(0), NumIncludes(0), ControllingMacroID(0), ControllingMacro(nullptr) {} @@ -120,16 +116,6 @@ struct HeaderFileInfo { return isImport || isPragmaOnce || NumIncludes || ControllingMacro || ControllingMacroID; } - - /// \brief Get the HeaderRole properly typed. - ModuleMap::ModuleHeaderRole getHeaderRole() const { - return static_cast<ModuleMap::ModuleHeaderRole>(HeaderRole); - } - - /// \brief Set the HeaderRole properly typed. - void setHeaderRole(ModuleMap::ModuleHeaderRole Role) { - HeaderRole = Role; - } }; /// \brief An external source of header file information, which may supply @@ -189,7 +175,7 @@ class HeaderSearch { /// \brief All of the preprocessor-specific data about files that are /// included, indexed by the FileEntry's UID. - std::vector<HeaderFileInfo> FileInfo; + mutable std::vector<HeaderFileInfo> FileInfo; /// Keeps track of each lookup performed by LookupFile. struct LookupFileCacheInfo { @@ -396,7 +382,8 @@ public: const DirectoryLookup *FromDir, const DirectoryLookup *&CurDir, ArrayRef<std::pair<const FileEntry *, const DirectoryEntry *>> Includers, SmallVectorImpl<char> *SearchPath, SmallVectorImpl<char> *RelativePath, - ModuleMap::KnownHeader *SuggestedModule, bool SkipCache = false); + Module *RequestingModule, ModuleMap::KnownHeader *SuggestedModule, + bool SkipCache = false); /// \brief Look up a subframework for the specified \#include file. /// @@ -405,11 +392,9 @@ public: /// HIToolbox is a subframework within Carbon.framework. If so, return /// the FileEntry for the designated file, otherwise return null. const FileEntry *LookupSubframeworkHeader( - StringRef Filename, - const FileEntry *RelativeFileEnt, - SmallVectorImpl<char> *SearchPath, - SmallVectorImpl<char> *RelativePath, - ModuleMap::KnownHeader *SuggestedModule); + StringRef Filename, const FileEntry *RelativeFileEnt, + SmallVectorImpl<char> *SearchPath, SmallVectorImpl<char> *RelativePath, + Module *RequestingModule, ModuleMap::KnownHeader *SuggestedModule); /// \brief Look up the specified framework name in our framework cache. /// \returns The DirectoryEntry it is in if we know, null otherwise. @@ -575,20 +560,51 @@ private: /// of the given search directory. void loadSubdirectoryModuleMaps(DirectoryLookup &SearchDir); - /// \brief Return the HeaderFileInfo structure for the specified FileEntry. - const HeaderFileInfo &getFileInfo(const FileEntry *FE) const { - return const_cast<HeaderSearch*>(this)->getFileInfo(FE); - } + /// \brief Find and suggest a usable module for the given file. + /// + /// \return \c true if the file can be used, \c false if we are not permitted to + /// find this file due to requirements from \p RequestingModule. + bool findUsableModuleForHeader(const FileEntry *File, + const DirectoryEntry *Root, + Module *RequestingModule, + ModuleMap::KnownHeader *SuggestedModule, + bool IsSystemHeaderDir); + + /// \brief Find and suggest a usable module for the given file, which is part of + /// the specified framework. + /// + /// \return \c true if the file can be used, \c false if we are not permitted to + /// find this file due to requirements from \p RequestingModule. + bool findUsableModuleForFrameworkHeader( + const FileEntry *File, StringRef FrameworkDir, Module *RequestingModule, + ModuleMap::KnownHeader *SuggestedModule, bool IsSystemFramework); + + /// \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, + ModuleMap::KnownHeader *SuggestedModule); public: /// \brief Retrieve the module map. ModuleMap &getModuleMap() { return ModMap; } + /// \brief Retrieve the module map. + const ModuleMap &getModuleMap() const { return ModMap; } + unsigned header_file_size() const { return FileInfo.size(); } - /// \brief Get a \c HeaderFileInfo structure for the specified \c FileEntry, - /// if one exists. - bool tryGetFileInfo(const FileEntry *FE, HeaderFileInfo &Result) const; + /// \brief Return the HeaderFileInfo structure for the specified FileEntry, + /// in preparation for updating it in some way. + HeaderFileInfo &getFileInfo(const FileEntry *FE); + + /// \brief Return the HeaderFileInfo structure for the specified FileEntry, + /// if it has ever been filled in. + /// \param WantExternal Whether the caller wants purely-external header file + /// info (where \p External is true). + const HeaderFileInfo *getExistingFileInfo(const FileEntry *FE, + bool WantExternal = true) const; // Used by external tools typedef std::vector<DirectoryLookup>::const_iterator search_dir_iterator; @@ -665,9 +681,6 @@ private: /// named directory. LoadModuleMapResult loadModuleMapFile(const DirectoryEntry *Dir, bool IsSystem, bool IsFramework); - - /// \brief Return the HeaderFileInfo structure for the specified FileEntry. - HeaderFileInfo &getFileInfo(const FileEntry *FE); }; } // end namespace clang diff --git a/contrib/llvm/tools/clang/include/clang/Lex/HeaderSearchOptions.h b/contrib/llvm/tools/clang/include/clang/Lex/HeaderSearchOptions.h index 12f0447..915dbf7 100644 --- a/contrib/llvm/tools/clang/include/clang/Lex/HeaderSearchOptions.h +++ b/contrib/llvm/tools/clang/include/clang/Lex/HeaderSearchOptions.h @@ -20,10 +20,11 @@ namespace clang { namespace frontend { - /// IncludeDirGroup - Identifiers the group a include entry belongs to, which - /// represents its relative positive in the search list. A \#include of a "" - /// path starts at the -iquote group, then searches the Angled group, then - /// searches the system group, etc. + /// IncludeDirGroup - Identifies the group an include Entry belongs to, + /// representing its relative positive in the search list. + /// \#include directives whose paths are enclosed by string quotes ("") + /// start searching at the Quoted group (specified by '-iquote'), + /// then search the Angled group, then the System group, etc. enum IncludeDirGroup { Quoted = 0, ///< '\#include ""' paths, added by 'gcc -iquote'. Angled, ///< Paths for '\#include <>' added by '-I'. @@ -140,7 +141,7 @@ public: /// \brief The set of macro names that should be ignored for the purposes /// of computing the module hash. - llvm::SetVector<std::string> ModulesIgnoreMacros; + llvm::SmallSetVector<std::string, 16> ModulesIgnoreMacros; /// \brief The set of user-provided virtual filesystem overlay files. std::vector<std::string> VFSOverlayFiles; @@ -168,7 +169,9 @@ public: /// \brief Whether to validate system input files when a module is loaded. unsigned ModulesValidateSystemHeaders : 1; -public: + /// Whether the module includes debug information (-gmodules). + unsigned UseDebugInfo : 1; + HeaderSearchOptions(StringRef _Sysroot = "/") : Sysroot(_Sysroot), ModuleFormat("raw"), DisableModuleHash(0), ImplicitModuleMaps(0), ModuleMapFileHomeIsCwd(0), @@ -177,7 +180,8 @@ public: UseBuiltinIncludes(true), UseStandardSystemIncludes(true), UseStandardCXXIncludes(true), UseLibcxx(false), Verbose(false), ModulesValidateOncePerBuildSession(false), - ModulesValidateSystemHeaders(false) {} + ModulesValidateSystemHeaders(false), + UseDebugInfo(false) {} /// AddPath - Add the \p Path path to the specified \p Group list. void AddPath(StringRef Path, frontend::IncludeDirGroup Group, diff --git a/contrib/llvm/tools/clang/include/clang/Lex/MacroInfo.h b/contrib/llvm/tools/clang/include/clang/Lex/MacroInfo.h index 8b82a5b..320645e 100644 --- a/contrib/llvm/tools/clang/include/clang/Lex/MacroInfo.h +++ b/contrib/llvm/tools/clang/include/clang/Lex/MacroInfo.h @@ -158,17 +158,16 @@ public: /// \brief Set the specified list of identifiers as the argument list for /// this macro. - void setArgumentList(IdentifierInfo *const *List, unsigned NumArgs, + void setArgumentList(ArrayRef<IdentifierInfo *> List, llvm::BumpPtrAllocator &PPAllocator) { assert(ArgumentList == nullptr && NumArguments == 0 && "Argument list already set!"); - if (NumArgs == 0) + if (List.empty()) return; - NumArguments = NumArgs; - ArgumentList = PPAllocator.Allocate<IdentifierInfo *>(NumArgs); - for (unsigned i = 0; i != NumArgs; ++i) - ArgumentList[i] = List[i]; + NumArguments = List.size(); + ArgumentList = PPAllocator.Allocate<IdentifierInfo *>(List.size()); + std::copy(List.begin(), List.end(), ArgumentList); } /// Arguments - The list of arguments for a function-like macro. This can be diff --git a/contrib/llvm/tools/clang/include/clang/Lex/ModuleMap.h b/contrib/llvm/tools/clang/include/clang/Lex/ModuleMap.h index 0b03c4a..155943e 100644 --- a/contrib/llvm/tools/clang/include/clang/Lex/ModuleMap.h +++ b/contrib/llvm/tools/clang/include/clang/Lex/ModuleMap.h @@ -35,6 +35,22 @@ class DiagnosticConsumer; class DiagnosticsEngine; class HeaderSearch; class ModuleMapParser; + +/// \brief A mechanism to observe the actions of the module map parser as it +/// reads module map files. +class ModuleMapCallbacks { +public: + virtual ~ModuleMapCallbacks() {} + + /// \brief Called when a module map file has been read. + /// + /// \param FileStart A SourceLocation referring to the start of the file's + /// contents. + /// \param File The file itself. + /// \param IsSystem Whether this is a module map from a system include path. + virtual void moduleMapFileRead(SourceLocation FileStart, + const FileEntry &File, bool IsSystem) {} +}; class ModuleMap { SourceManager &SourceMgr; @@ -42,6 +58,8 @@ class ModuleMap { const LangOptions &LangOpts; const TargetInfo *Target; HeaderSearch &HeaderInfo; + + llvm::SmallVector<std::unique_ptr<ModuleMapCallbacks>, 1> Callbacks; /// \brief The directory used for Clang-supplied, builtin include headers, /// such as "stdint.h". @@ -94,6 +112,13 @@ public: KnownHeader() : Storage(nullptr, NormalHeader) { } KnownHeader(Module *M, ModuleHeaderRole Role) : Storage(M, Role) { } + friend bool operator==(const KnownHeader &A, const KnownHeader &B) { + return A.Storage == B.Storage; + } + friend bool operator!=(const KnownHeader &A, const KnownHeader &B) { + return A.Storage != B.Storage; + } + /// \brief Retrieve the module the header is stored in. Module *getModule() const { return Storage.getPointer(); } @@ -224,6 +249,10 @@ private: KnownHeader findHeaderInUmbrellaDirs(const FileEntry *File, SmallVectorImpl<const DirectoryEntry *> &IntermediateDirs); + /// \brief Given that \p File is not in the Headers map, look it up within + /// umbrella directories and find or create a module for it. + KnownHeader findOrCreateModuleForHeaderInUmbrellaDir(const FileEntry *File); + /// \brief A convenience method to determine if \p File is (possibly nested) /// in an umbrella directory. bool isHeaderInUmbrellaDirs(const FileEntry *File) { @@ -263,6 +292,11 @@ public: BuiltinIncludeDir = Dir; } + /// \brief Add a module map callback. + void addModuleMapCallbacks(std::unique_ptr<ModuleMapCallbacks> Callback) { + Callbacks.push_back(std::move(Callback)); + } + /// \brief Retrieve the module that owns the given header file, if any. /// /// \param File The header file that is likely to be included. @@ -272,6 +306,14 @@ public: /// that no module owns this header file. KnownHeader findModuleForHeader(const FileEntry *File); + /// \brief Retrieve all the modules that contain the given header file. This + /// may not include umbrella modules, nor information from external sources, + /// if they have not yet been inferred / loaded. + /// + /// Typically, \ref findModuleForHeader should be used instead, as it picks + /// the preferred module for the header. + ArrayRef<KnownHeader> findAllModulesForHeader(const FileEntry *File) const; + /// \brief Reports errors if a module must not include a specific file. /// /// \param RequestingModule The module including a file. @@ -436,7 +478,7 @@ public: /// \brief Adds this header to the given module. /// \param Role The role of the header wrt the module. void addHeader(Module *Mod, Module::Header Header, - ModuleHeaderRole Role); + ModuleHeaderRole Role, bool Imported = false); /// \brief Marks this header as being excluded from the given module. void excludeHeader(Module *Mod, Module::Header Header); diff --git a/contrib/llvm/tools/clang/include/clang/Lex/PPCallbacks.h b/contrib/llvm/tools/clang/include/clang/Lex/PPCallbacks.h index 3803533..68b8f1c 100644 --- a/contrib/llvm/tools/clang/include/clang/Lex/PPCallbacks.h +++ b/contrib/llvm/tools/clang/include/clang/Lex/PPCallbacks.h @@ -201,19 +201,19 @@ public: PragmaMessageKind Kind, StringRef Str) { } - /// \brief Callback invoked when a \#pragma gcc dianostic push directive + /// \brief Callback invoked when a \#pragma gcc diagnostic push directive /// is read. virtual void PragmaDiagnosticPush(SourceLocation Loc, StringRef Namespace) { } - /// \brief Callback invoked when a \#pragma gcc dianostic pop directive + /// \brief Callback invoked when a \#pragma gcc diagnostic pop directive /// is read. virtual void PragmaDiagnosticPop(SourceLocation Loc, StringRef Namespace) { } - /// \brief Callback invoked when a \#pragma gcc dianostic directive is read. + /// \brief Callback invoked when a \#pragma gcc diagnostic directive is read. virtual void PragmaDiagnostic(SourceLocation Loc, StringRef Namespace, diag::Severity mapping, StringRef Str) {} diff --git a/contrib/llvm/tools/clang/include/clang/Lex/Pragma.h b/contrib/llvm/tools/clang/include/clang/Lex/Pragma.h index 70fcfda..274f0da 100644 --- a/contrib/llvm/tools/clang/include/clang/Lex/Pragma.h +++ b/contrib/llvm/tools/clang/include/clang/Lex/Pragma.h @@ -76,7 +76,7 @@ public: /// used to ignore particular pragmas. class EmptyPragmaHandler : public PragmaHandler { public: - EmptyPragmaHandler(); + explicit EmptyPragmaHandler(StringRef Name = StringRef()); void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer, Token &FirstToken) override; diff --git a/contrib/llvm/tools/clang/include/clang/Lex/PreprocessingRecord.h b/contrib/llvm/tools/clang/include/clang/Lex/PreprocessingRecord.h index 53367ab..87b8ce1 100644 --- a/contrib/llvm/tools/clang/include/clang/Lex/PreprocessingRecord.h +++ b/contrib/llvm/tools/clang/include/clang/Lex/PreprocessingRecord.h @@ -32,12 +32,12 @@ namespace clang { } /// \brief Allocates memory within a Clang preprocessing record. -void* operator new(size_t bytes, clang::PreprocessingRecord& PR, - unsigned alignment = 8) throw(); +void *operator new(size_t bytes, clang::PreprocessingRecord &PR, + unsigned alignment = 8) LLVM_NOEXCEPT; /// \brief Frees memory allocated in a Clang preprocessing record. void operator delete(void *ptr, clang::PreprocessingRecord &PR, - unsigned) throw(); + unsigned) LLVM_NOEXCEPT; namespace clang { class MacroDefinitionRecord; @@ -98,27 +98,25 @@ namespace clang { // Only allow allocation of preprocessed entities using the allocator // in PreprocessingRecord or by doing a placement new. - void* operator new(size_t bytes, PreprocessingRecord& PR, - unsigned alignment = 8) throw() { + void *operator new(size_t bytes, PreprocessingRecord &PR, + unsigned alignment = 8) LLVM_NOEXCEPT { return ::operator new(bytes, PR, alignment); } - - void* operator new(size_t bytes, void* mem) throw() { - return mem; - } - - void operator delete(void* ptr, PreprocessingRecord& PR, - unsigned alignment) throw() { + + void *operator new(size_t bytes, void *mem) LLVM_NOEXCEPT { return mem; } + + void operator delete(void *ptr, PreprocessingRecord &PR, + unsigned alignment) LLVM_NOEXCEPT { return ::operator delete(ptr, PR, alignment); } - - void operator delete(void*, std::size_t) throw() { } - void operator delete(void*, void*) throw() { } - + + void operator delete(void *, std::size_t) LLVM_NOEXCEPT {} + void operator delete(void *, void *) LLVM_NOEXCEPT {} + private: // Make vanilla 'new' and 'delete' illegal for preprocessed entities. - void* operator new(size_t bytes) throw(); - void operator delete(void* data) throw(); + void *operator new(size_t bytes) LLVM_NOEXCEPT; + void operator delete(void *data) LLVM_NOEXCEPT; }; /// \brief Records the presence of a preprocessor directive. @@ -525,13 +523,13 @@ namespace clang { }; } // end namespace clang -inline void* operator new(size_t bytes, clang::PreprocessingRecord& PR, - unsigned alignment) throw() { +inline void *operator new(size_t bytes, clang::PreprocessingRecord &PR, + unsigned alignment) LLVM_NOEXCEPT { return PR.Allocate(bytes, alignment); } -inline void operator delete(void* ptr, clang::PreprocessingRecord& PR, - unsigned) throw() { +inline void operator delete(void *ptr, clang::PreprocessingRecord &PR, + unsigned) LLVM_NOEXCEPT { PR.Deallocate(ptr); } diff --git a/contrib/llvm/tools/clang/include/clang/Lex/Preprocessor.h b/contrib/llvm/tools/clang/include/clang/Lex/Preprocessor.h index b2f58ead..f6154b6 100644 --- a/contrib/llvm/tools/clang/include/clang/Lex/Preprocessor.h +++ b/contrib/llvm/tools/clang/include/clang/Lex/Preprocessor.h @@ -24,7 +24,6 @@ #include "clang/Lex/ModuleMap.h" #include "clang/Lex/PPCallbacks.h" #include "clang/Lex/PTHLexer.h" -#include "clang/Lex/PTHManager.h" #include "clang/Lex/TokenLexer.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" @@ -57,6 +56,7 @@ class CodeCompletionHandler; class DirectoryLookup; class PreprocessingRecord; class ModuleLoader; +class PTHManager; class PreprocessorOptions; /// \brief Stores token information for comparing actual tokens with @@ -98,6 +98,7 @@ class Preprocessor : public RefCountedBase<Preprocessor> { DiagnosticsEngine *Diags; LangOptions &LangOpts; const TargetInfo *Target; + const TargetInfo *AuxTarget; FileManager &FileMgr; SourceManager &SourceMgr; std::unique_ptr<ScratchBuffer> ScratchBuf; @@ -656,7 +657,10 @@ public: /// /// \param Target is owned by the caller and must remain valid for the /// lifetime of the preprocessor. - void Initialize(const TargetInfo &Target); + /// \param AuxTarget is owned by the caller and must remain valid for + /// the lifetime of the preprocessor. + void Initialize(const TargetInfo &Target, + const TargetInfo *AuxTarget = nullptr); /// \brief Initialize the preprocessor to parse a model file /// @@ -678,6 +682,7 @@ public: const LangOptions &getLangOpts() const { return LangOpts; } const TargetInfo &getTargetInfo() const { return *Target; } + const TargetInfo *getAuxTargetInfo() const { return AuxTarget; } FileManager &getFileManager() const { return FileMgr; } SourceManager &getSourceManager() const { return SourceMgr; } HeaderSearch &getHeaderSearchInfo() const { return HeaderInfo; } diff --git a/contrib/llvm/tools/clang/include/clang/Lex/TokenLexer.h b/contrib/llvm/tools/clang/include/clang/Lex/TokenLexer.h index 3119736..fdeed44 100644 --- a/contrib/llvm/tools/clang/include/clang/Lex/TokenLexer.h +++ b/contrib/llvm/tools/clang/include/clang/Lex/TokenLexer.h @@ -175,7 +175,7 @@ private: /// macro, other active macros, and anything left on the current physical /// source line of the expanded buffer. Handle this by returning the /// first token on the next line. - void HandleMicrosoftCommentPaste(Token &Tok); + void HandleMicrosoftCommentPaste(Token &Tok, SourceLocation OpLoc); /// \brief If \p loc is a FileID and points inside the current macro /// definition, returns the appropriate source location pointing at the diff --git a/contrib/llvm/tools/clang/include/clang/Parse/Parser.h b/contrib/llvm/tools/clang/include/clang/Parse/Parser.h index 8719555..82b7798 100644 --- a/contrib/llvm/tools/clang/include/clang/Parse/Parser.h +++ b/contrib/llvm/tools/clang/include/clang/Parse/Parser.h @@ -163,6 +163,7 @@ class Parser : public CodeCompletionHandler { std::unique_ptr<PragmaHandler> MSConstSeg; std::unique_ptr<PragmaHandler> MSCodeSeg; std::unique_ptr<PragmaHandler> MSSection; + std::unique_ptr<PragmaHandler> MSRuntimeChecks; std::unique_ptr<PragmaHandler> OptimizeHandler; std::unique_ptr<PragmaHandler> LoopHintHandler; std::unique_ptr<PragmaHandler> UnrollHintHandler; @@ -1236,6 +1237,7 @@ private: ParsingDeclSpec &DS, AccessSpecifier AS); + void SkipFunctionBody(); Decl *ParseFunctionDefinition(ParsingDeclarator &D, const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo(), LateParsedAttrList *LateParsedAttrs = nullptr); @@ -1251,12 +1253,12 @@ private: DeclGroupPtrTy ParseObjCAtClassDeclaration(SourceLocation atLoc); Decl *ParseObjCAtInterfaceDeclaration(SourceLocation AtLoc, ParsedAttributes &prefixAttrs); + class ObjCTypeParamListScope; ObjCTypeParamList *parseObjCTypeParamList(); ObjCTypeParamList *parseObjCTypeParamListOrProtocolRefs( - SourceLocation &lAngleLoc, - SmallVectorImpl<IdentifierLocPair> &protocolIdents, - SourceLocation &rAngleLoc, - bool mayBeProtocolList = true); + ObjCTypeParamListScope &Scope, SourceLocation &lAngleLoc, + SmallVectorImpl<IdentifierLocPair> &protocolIdents, + SourceLocation &rAngleLoc, bool mayBeProtocolList = true); void HelperActionsForIvarDeclarations(Decl *interfaceDecl, SourceLocation atLoc, BalancedDelimiterTracker &T, @@ -1578,7 +1580,9 @@ private: SourceLocation Loc, bool ConvertToBoolean); //===--------------------------------------------------------------------===// - // C++ types + // C++ Coroutines + + ExprResult ParseCoyieldExpression(); //===--------------------------------------------------------------------===// // C99 6.7.8: Initialization. @@ -2164,8 +2168,7 @@ private: void MaybeParseMicrosoftDeclSpecs(ParsedAttributes &Attrs, SourceLocation *End = nullptr) { const auto &LO = getLangOpts(); - if ((LO.MicrosoftExt || LO.Borland || LO.CUDA) && - Tok.is(tok::kw___declspec)) + if (LO.DeclSpecKeyword && Tok.is(tok::kw___declspec)) ParseMicrosoftDeclSpecs(Attrs, End); } void ParseMicrosoftDeclSpecs(ParsedAttributes &Attrs, @@ -2334,8 +2337,8 @@ private: void DiagnoseUnexpectedNamespace(NamedDecl *Context); - Decl *ParseNamespace(unsigned Context, SourceLocation &DeclEnd, - SourceLocation InlineLoc = SourceLocation()); + DeclGroupPtrTy ParseNamespace(unsigned Context, SourceLocation &DeclEnd, + SourceLocation InlineLoc = SourceLocation()); void ParseInnerNamespace(std::vector<SourceLocation>& IdentLoc, std::vector<IdentifierInfo*>& Ident, std::vector<SourceLocation>& NamespaceLoc, @@ -2388,9 +2391,13 @@ private: LateParsedAttrList &LateAttrs); void MaybeParseAndDiagnoseDeclSpecAfterCXX11VirtSpecifierSeq(Declarator &D, VirtSpecifiers &VS); - void ParseCXXClassMemberDeclaration(AccessSpecifier AS, AttributeList *Attr, - const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo(), - ParsingDeclRAIIObject *DiagsFromTParams = nullptr); + DeclGroupPtrTy ParseCXXClassMemberDeclaration( + AccessSpecifier AS, AttributeList *Attr, + const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo(), + ParsingDeclRAIIObject *DiagsFromTParams = nullptr); + DeclGroupPtrTy ParseCXXClassMemberDeclarationWithPragmas( + AccessSpecifier &AS, ParsedAttributesWithRange &AccessAttrs, + DeclSpec::TST TagType, Decl *TagDecl); void ParseConstructorInitializer(Decl *ConstructorDecl); MemInitResult ParseMemInitializer(Decl *ConstructorDecl); void HandleMemberFunctionDeclDelays(Declarator& DeclaratorInfo, @@ -2471,7 +2478,9 @@ private: /// /// \param Kind Kind of current clause. /// - OMPClause *ParseOpenMPVarListClause(OpenMPClauseKind Kind); + OMPClause *ParseOpenMPVarListClause(OpenMPDirectiveKind DKind, + OpenMPClauseKind Kind); + public: bool ParseUnqualifiedId(CXXScopeSpec &SS, bool EnteringContext, bool AllowDestructorName, @@ -2550,6 +2559,14 @@ private: //===--------------------------------------------------------------------===// // Modules DeclGroupPtrTy ParseModuleImport(SourceLocation AtLoc); + bool parseMisplacedModuleImport(); + bool tryParseMisplacedModuleImport() { + tok::TokenKind Kind = Tok.getKind(); + if (Kind == tok::annot_module_begin || Kind == tok::annot_module_end || + Kind == tok::annot_module_include) + return parseMisplacedModuleImport(); + return false; + } //===--------------------------------------------------------------------===// // C++11/G++: Type Traits [Type-Traits.html in the GCC manual] diff --git a/contrib/llvm/tools/clang/include/clang/Sema/AttributeList.h b/contrib/llvm/tools/clang/include/clang/Sema/AttributeList.h index 4d18633..e32781d 100644 --- a/contrib/llvm/tools/clang/include/clang/Sema/AttributeList.h +++ b/contrib/llvm/tools/clang/include/clang/Sema/AttributeList.h @@ -16,11 +16,11 @@ #define LLVM_CLANG_SEMA_ATTRIBUTELIST_H #include "clang/Basic/SourceLocation.h" +#include "clang/Basic/TargetInfo.h" #include "clang/Basic/VersionTuple.h" #include "clang/Sema/Ownership.h" #include "llvm/ADT/PointerUnion.h" #include "llvm/ADT/SmallVector.h" -#include "llvm/ADT/Triple.h" #include "llvm/Support/Allocator.h" #include <cassert> @@ -137,11 +137,9 @@ private: AttributeList *NextInPool; /// Arguments, if any, are stored immediately following the object. - ArgsUnion *getArgsBuffer() { - return reinterpret_cast<ArgsUnion*>(this+1); - } + ArgsUnion *getArgsBuffer() { return reinterpret_cast<ArgsUnion *>(this + 1); } ArgsUnion const *getArgsBuffer() const { - return reinterpret_cast<ArgsUnion const *>(this+1); + return reinterpret_cast<ArgsUnion const *>(this + 1); } enum AvailabilitySlot { @@ -466,7 +464,7 @@ public: bool hasVariadicArg() const; bool diagnoseAppertainsTo(class Sema &S, const Decl *D) const; bool diagnoseLangOpts(class Sema &S) const; - bool existsInTarget(const llvm::Triple &T) const; + bool existsInTarget(const TargetInfo &Target) const; bool isKnownToGCC() const; /// \brief If the parsed attribute has a semantic equivalent, and it would @@ -559,8 +557,10 @@ public: /// Create a new pool for a factory. AttributePool(AttributeFactory &factory) : Factory(factory), Head(nullptr) {} + AttributePool(const AttributePool &) = delete; + /// Move the given pool's allocations to this pool. - AttributePool(AttributePool &pool) : Factory(pool.Factory), Head(pool.Head) { + AttributePool(AttributePool &&pool) : Factory(pool.Factory), Head(pool.Head) { pool.Head = nullptr; } @@ -854,7 +854,8 @@ enum AttributeDeclKind { ExpectedStructOrUnionOrTypedef, ExpectedStructOrTypedef, ExpectedObjectiveCInterfaceOrProtocol, - ExpectedKernelFunction + ExpectedKernelFunction, + ExpectedFunctionWithProtoType }; } // end namespace clang diff --git a/contrib/llvm/tools/clang/include/clang/Sema/CodeCompleteOptions.h b/contrib/llvm/tools/clang/include/clang/Sema/CodeCompleteOptions.h index e43496f..fc7713c 100644 --- a/contrib/llvm/tools/clang/include/clang/Sema/CodeCompleteOptions.h +++ b/contrib/llvm/tools/clang/include/clang/Sema/CodeCompleteOptions.h @@ -10,6 +10,8 @@ #ifndef LLVM_CLANG_SEMA_CODECOMPLETEOPTIONS_H #define LLVM_CLANG_SEMA_CODECOMPLETEOPTIONS_H +namespace clang { + /// Options controlling the behavior of code completion. class CodeCompleteOptions { public: @@ -33,5 +35,7 @@ public: { } }; +} // namespace clang + #endif diff --git a/contrib/llvm/tools/clang/include/clang/Sema/DeclSpec.h b/contrib/llvm/tools/clang/include/clang/Sema/DeclSpec.h index 41d4900..e9fdb70 100644 --- a/contrib/llvm/tools/clang/include/clang/Sema/DeclSpec.h +++ b/contrib/llvm/tools/clang/include/clang/Sema/DeclSpec.h @@ -31,7 +31,6 @@ #include "clang/Lex/Token.h" #include "clang/Sema/AttributeList.h" #include "clang/Sema/Ownership.h" -#include "llvm/ADT/Optional.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/ErrorHandling.h" @@ -41,14 +40,10 @@ namespace clang { class CXXRecordDecl; class TypeLoc; class LangOptions; - class DiagnosticsEngine; class IdentifierInfo; class NamespaceAliasDecl; class NamespaceDecl; - class NestedNameSpecifier; - class NestedNameSpecifierLoc; class ObjCDeclSpec; - class Preprocessor; class Sema; class Declarator; struct TemplateIdAnnotation; @@ -70,8 +65,8 @@ class CXXScopeSpec { NestedNameSpecifierLocBuilder Builder; public: - const SourceRange &getRange() const { return Range; } - void setRange(const SourceRange &R) { Range = R; } + SourceRange getRange() const { return Range; } + void setRange(SourceRange R) { Range = R; } void setBeginLoc(SourceLocation Loc) { Range.setBegin(Loc); } void setEndLoc(SourceLocation Loc) { Range.setEnd(Loc); } SourceLocation getBeginLoc() const { return Range.getBegin(); } @@ -301,6 +296,7 @@ public: static const TST TST_decltype_auto = clang::TST_decltype_auto; static const TST TST_underlyingType = clang::TST_underlyingType; static const TST TST_auto = clang::TST_auto; + 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; static const TST TST_error = clang::TST_error; @@ -493,7 +489,7 @@ public: CXXScopeSpec &getTypeSpecScope() { return TypeScope; } const CXXScopeSpec &getTypeSpecScope() const { return TypeScope; } - const SourceRange &getSourceRange() const LLVM_READONLY { return Range; } + SourceRange getSourceRange() const LLVM_READONLY { return Range; } SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); } SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); } @@ -512,7 +508,8 @@ public: void setTypeofParensRange(SourceRange range) { TypeofParensRange = range; } bool containsPlaceholderType() const { - return TypeSpecType == TST_auto || TypeSpecType == TST_decltype_auto; + return (TypeSpecType == TST_auto || TypeSpecType == TST_auto_type || + TypeSpecType == TST_decltype_auto); } bool hasTagDefinition() const; @@ -742,8 +739,7 @@ public: /// Finish - This does final analysis of the declspec, issuing diagnostics for /// things like "_Imaginary" (lacking an FP type). After calling this method, /// DeclSpec is guaranteed self-consistent, even if an error occurred. - void Finish(DiagnosticsEngine &D, Preprocessor &PP, - const PrintingPolicy &Policy); + void Finish(Sema &S, const PrintingPolicy &Policy); const WrittenBuiltinSpecs& getWrittenBuiltinSpecs() const { return writtenBS; @@ -1255,8 +1251,11 @@ struct DeclaratorChunk { /// any. unsigned MutableLoc; - /// \brief The location of the keyword introducing the spec, if any. - unsigned ExceptionSpecLoc; + /// \brief The beginning location of the exception specification, if any. + unsigned ExceptionSpecLocBeg; + + /// \brief The end location of the exception specification, if any. + unsigned ExceptionSpecLocEnd; /// Params - This is a pointer to a new[]'d array of ParamInfo objects that /// describe the parameters specified by this function declarator. null if @@ -1323,8 +1322,16 @@ struct DeclaratorChunk { return SourceLocation::getFromRawEncoding(RParenLoc); } - SourceLocation getExceptionSpecLoc() const { - return SourceLocation::getFromRawEncoding(ExceptionSpecLoc); + SourceLocation getExceptionSpecLocBeg() const { + return SourceLocation::getFromRawEncoding(ExceptionSpecLocBeg); + } + + SourceLocation getExceptionSpecLocEnd() const { + return SourceLocation::getFromRawEncoding(ExceptionSpecLocEnd); + } + + SourceRange getExceptionSpecRange() const { + return SourceRange(getExceptionSpecLocBeg(), getExceptionSpecLocEnd()); } /// \brief Retrieve the location of the ref-qualifier, if any. @@ -1496,7 +1503,7 @@ struct DeclaratorChunk { SourceLocation RestrictQualifierLoc, SourceLocation MutableLoc, ExceptionSpecificationType ESpecType, - SourceLocation ESpecLoc, + SourceRange ESpecRange, ParsedType *Exceptions, SourceRange *ExceptionRanges, unsigned NumExceptions, @@ -1704,7 +1711,7 @@ public: } /// \brief Get the source range that spans this declarator. - const SourceRange &getSourceRange() const LLVM_READONLY { return Range; } + SourceRange getSourceRange() const LLVM_READONLY { return Range; } SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); } SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); } @@ -1724,7 +1731,7 @@ public: /// given declspec, unless its location is invalid. Adopts the range start if /// the current range start is invalid. void ExtendWithDeclSpec(const DeclSpec &DS) { - const SourceRange &SR = DS.getSourceRange(); + SourceRange SR = DS.getSourceRange(); if (Range.getBegin().isInvalid()) Range.setBegin(SR.getBegin()); if (!SR.getEnd().isInvalid()) @@ -2197,6 +2204,9 @@ public: /// redeclaration time if the decl is static. bool isStaticMember(); + /// Returns true if this declares a constructor or a destructor. + bool isCtorOrDtor(); + void setRedeclaration(bool Val) { Redeclaration = Val; } bool isRedeclaration() const { return Redeclaration; } }; @@ -2251,6 +2261,13 @@ private: SourceLocation LastLocation; }; +enum class LambdaCaptureInitKind { + NoInit, //!< [a] + CopyInit, //!< [a = b], [a = {b}] + DirectInit, //!< [a(b)] + ListInit //!< [a{b}] +}; + /// \brief Represents a complete lambda introducer. struct LambdaIntroducer { /// \brief An individual capture in a lambda introducer. @@ -2259,13 +2276,15 @@ struct LambdaIntroducer { SourceLocation Loc; IdentifierInfo *Id; SourceLocation EllipsisLoc; + LambdaCaptureInitKind InitKind; ExprResult Init; ParsedType InitCaptureType; LambdaCapture(LambdaCaptureKind Kind, SourceLocation Loc, IdentifierInfo *Id, SourceLocation EllipsisLoc, - ExprResult Init, ParsedType InitCaptureType) - : Kind(Kind), Loc(Loc), Id(Id), EllipsisLoc(EllipsisLoc), Init(Init), - InitCaptureType(InitCaptureType) {} + LambdaCaptureInitKind InitKind, ExprResult Init, + ParsedType InitCaptureType) + : Kind(Kind), Loc(Loc), Id(Id), EllipsisLoc(EllipsisLoc), + InitKind(InitKind), Init(Init), InitCaptureType(InitCaptureType) {} }; SourceRange Range; @@ -2281,10 +2300,11 @@ struct LambdaIntroducer { SourceLocation Loc, IdentifierInfo* Id, SourceLocation EllipsisLoc, + LambdaCaptureInitKind InitKind, ExprResult Init, ParsedType InitCaptureType) { - Captures.push_back(LambdaCapture(Kind, Loc, Id, EllipsisLoc, Init, - InitCaptureType)); + Captures.push_back(LambdaCapture(Kind, Loc, Id, EllipsisLoc, InitKind, Init, + InitCaptureType)); } }; diff --git a/contrib/llvm/tools/clang/include/clang/Sema/ExternalSemaSource.h b/contrib/llvm/tools/clang/include/clang/Sema/ExternalSemaSource.h index ef3d2db..97f78f4 100644 --- a/contrib/llvm/tools/clang/include/clang/Sema/ExternalSemaSource.h +++ b/contrib/llvm/tools/clang/include/clang/Sema/ExternalSemaSource.h @@ -139,7 +139,7 @@ public: /// be invoked multiple times; the external source should take care not to /// introduce the same declarations repeatedly. virtual void ReadUnusedLocalTypedefNameCandidates( - llvm::SmallSetVector<const TypedefNameDecl *, 4> &Decls) {}; + llvm::SmallSetVector<const TypedefNameDecl *, 4> &Decls) {} /// \brief Read the set of referenced selectors known to the /// external Sema source. diff --git a/contrib/llvm/tools/clang/include/clang/Sema/Initialization.h b/contrib/llvm/tools/clang/include/clang/Sema/Initialization.h index 74de00f..d4f57b7 100644 --- a/contrib/llvm/tools/clang/include/clang/Sema/Initialization.h +++ b/contrib/llvm/tools/clang/include/clang/Sema/Initialization.h @@ -828,6 +828,9 @@ public: /// \brief Initializer has a placeholder type which cannot be /// resolved by initialization. FK_PlaceholderType, + /// \brief Trying to take the address of a function that doesn't support + /// having its address taken. + FK_AddressOfUnaddressableFunction, /// \brief List-copy-initialization chose an explicit constructor. FK_ExplicitConstructor }; diff --git a/contrib/llvm/tools/clang/include/clang/Sema/Lookup.h b/contrib/llvm/tools/clang/include/clang/Sema/Lookup.h index 5bfee8b..87c40f0 100644 --- a/contrib/llvm/tools/clang/include/clang/Sema/Lookup.h +++ b/contrib/llvm/tools/clang/include/clang/Sema/Lookup.h @@ -139,7 +139,7 @@ public: Redecl(Redecl != Sema::NotForRedeclaration), HideTags(true), Diagnose(Redecl == Sema::NotForRedeclaration), - AllowHidden(Redecl == Sema::ForRedeclaration), + AllowHidden(false), Shadowed(false) { configure(); @@ -161,7 +161,7 @@ public: Redecl(Redecl != Sema::NotForRedeclaration), HideTags(true), Diagnose(Redecl == Sema::NotForRedeclaration), - AllowHidden(Redecl == Sema::ForRedeclaration), + AllowHidden(false), Shadowed(false) { configure(); @@ -228,10 +228,11 @@ public: /// \brief Determine whether this lookup is permitted to see hidden /// declarations, such as those in modules that have not yet been imported. - bool isHiddenDeclarationVisible() const { - return AllowHidden || LookupKind == Sema::LookupTagName; + bool isHiddenDeclarationVisible(NamedDecl *ND) const { + return AllowHidden || + (isForRedeclaration() && ND->isExternallyVisible()); } - + /// Sets whether tag declarations should be hidden by non-tag /// declarations during resolution. The default is true. void setHideTags(bool Hide) { @@ -302,7 +303,7 @@ public: if (!D->isInIdentifierNamespace(IDNS)) return nullptr; - if (isHiddenDeclarationVisible() || isVisible(getSema(), D)) + if (isVisible(getSema(), D) || isHiddenDeclarationVisible(D)) return D; return getAcceptableDeclSlow(D); @@ -511,7 +512,6 @@ public: /// \brief Change this lookup's redeclaration kind. void setRedeclarationKind(Sema::RedeclarationKind RK) { Redecl = RK; - AllowHidden = (RK == Sema::ForRedeclaration); configure(); } @@ -565,6 +565,11 @@ public: {} public: + Filter(Filter &&F) + : Results(F.Results), I(F.I), Changed(F.Changed), + CalledDone(F.CalledDone) { + F.CalledDone = true; + } ~Filter() { assert(CalledDone && "LookupResult::Filter destroyed without done() call"); diff --git a/contrib/llvm/tools/clang/include/clang/Sema/MultiplexExternalSemaSource.h b/contrib/llvm/tools/clang/include/clang/Sema/MultiplexExternalSemaSource.h index af7083a..d6daadc 100644 --- a/contrib/llvm/tools/clang/include/clang/Sema/MultiplexExternalSemaSource.h +++ b/contrib/llvm/tools/clang/include/clang/Sema/MultiplexExternalSemaSource.h @@ -102,29 +102,12 @@ public: /// \brief Finds all declarations lexically contained within the given /// DeclContext, after applying an optional filter predicate. /// - /// \param isKindWeWant a predicate function that returns true if the passed - /// declaration kind is one we are looking for. If NULL, all declarations - /// are returned. - /// - /// \return an indication of whether the load succeeded or failed. - ExternalLoadResult FindExternalLexicalDecls(const DeclContext *DC, - bool (*isKindWeWant)(Decl::Kind), - SmallVectorImpl<Decl*> &Result) override; - - /// \brief Finds all declarations lexically contained within the given - /// DeclContext. - /// - /// \return true if an error occurred - ExternalLoadResult FindExternalLexicalDecls(const DeclContext *DC, - SmallVectorImpl<Decl*> &Result) { - return FindExternalLexicalDecls(DC, nullptr, Result); - } - - template <typename DeclTy> - ExternalLoadResult FindExternalLexicalDeclsBy(const DeclContext *DC, - SmallVectorImpl<Decl*> &Result) { - return FindExternalLexicalDecls(DC, DeclTy::classofKind, Result); - } + /// \param IsKindWeWant a predicate function that returns true if the passed + /// declaration kind is one we are looking for. + void + FindExternalLexicalDecls(const DeclContext *DC, + llvm::function_ref<bool(Decl::Kind)> IsKindWeWant, + SmallVectorImpl<Decl *> &Result) override; /// \brief Get the decls that are contained in a file in the Offset/Length /// range. \p Length can be 0 to indicate a point at \p Offset instead of diff --git a/contrib/llvm/tools/clang/include/clang/Sema/Overload.h b/contrib/llvm/tools/clang/include/clang/Sema/Overload.h index 2007dcb..20958b0 100644 --- a/contrib/llvm/tools/clang/include/clang/Sema/Overload.h +++ b/contrib/llvm/tools/clang/include/clang/Sema/Overload.h @@ -83,7 +83,8 @@ namespace clang { ICK_TransparentUnionConversion, ///< Transparent Union Conversions ICK_Writeback_Conversion, ///< Objective-C ARC writeback conversion ICK_Zero_Event_Conversion, ///< Zero constant to event (OpenCL1.2 6.12.10) - ICK_Num_Conversion_Kinds ///< The number of conversion kinds + ICK_C_Only_Conversion, ///< Conversions allowed in C, but not C++ + ICK_Num_Conversion_Kinds, ///< The number of conversion kinds }; /// ImplicitConversionRank - The rank of an implicit conversion @@ -95,7 +96,9 @@ namespace clang { ICR_Promotion, ///< Promotion ICR_Conversion, ///< Conversion ICR_Complex_Real_Conversion, ///< Complex <-> Real conversion - ICR_Writeback_Conversion ///< ObjC ARC writeback conversion + ICR_Writeback_Conversion, ///< ObjC ARC writeback conversion + ICR_C_Conversion ///< Conversion only allowed in the C standard. + /// (e.g. void* to char*) }; ImplicitConversionRank GetConversionRank(ImplicitConversionKind Kind); diff --git a/contrib/llvm/tools/clang/include/clang/Sema/ScopeInfo.h b/contrib/llvm/tools/clang/include/clang/Sema/ScopeInfo.h index 15ee8a4..d13667e 100644 --- a/contrib/llvm/tools/clang/include/clang/Sema/ScopeInfo.h +++ b/contrib/llvm/tools/clang/include/clang/Sema/ScopeInfo.h @@ -89,40 +89,43 @@ protected: public: /// \brief What kind of scope we are describing. /// - ScopeKind Kind; + ScopeKind Kind : 3; /// \brief Whether this function contains a VLA, \@try, try, C++ /// initializer, or anything else that can't be jumped past. - bool HasBranchProtectedScope; + bool HasBranchProtectedScope : 1; /// \brief Whether this function contains any switches or direct gotos. - bool HasBranchIntoScope; + bool HasBranchIntoScope : 1; /// \brief Whether this function contains any indirect gotos. - bool HasIndirectGoto; + bool HasIndirectGoto : 1; /// \brief Whether a statement was dropped because it was invalid. - bool HasDroppedStmt; + bool HasDroppedStmt : 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)). - bool ObjCShouldCallSuper; + bool ObjCShouldCallSuper : 1; /// True when this is a method marked as a designated initializer. - bool ObjCIsDesignatedInit; + bool ObjCIsDesignatedInit : 1; /// This starts true for a method marked as designated initializer and will /// be set to false if there is an invocation to a designated initializer of /// the super class. - bool ObjCWarnForNoDesignatedInitChain; + bool ObjCWarnForNoDesignatedInitChain : 1; /// True when this is an initializer method not marked as a designated /// initializer within a class that has at least one initializer marked as a /// designated initializer. - bool ObjCIsSecondaryInit; + bool ObjCIsSecondaryInit : 1; /// This starts true for a secondary initializer method and will be set to /// false if there is an invocation of an initializer on 'self'. - bool ObjCWarnForNoInitDelegation; + bool ObjCWarnForNoInitDelegation : 1; + + /// First 'return' statement in the current function. + SourceLocation FirstReturnLoc; /// First C++ 'try' statement in the current function. SourceLocation FirstCXXTryLoc; @@ -142,6 +145,14 @@ public: /// optimization, or if we need to infer a return type. SmallVector<ReturnStmt*, 4> Returns; + /// \brief The promise object for this coroutine, if any. + VarDecl *CoroutinePromise; + + /// \brief The list of coroutine control flow constructs (co_await, co_yield, + /// co_return) that occur within the function or block. Empty if and only if + /// this function or block is not (yet known to be) a coroutine. + SmallVector<Stmt*, 4> CoroutineStmts; + /// \brief The stack of currently active compound stamement scopes in the /// function. SmallVector<CompoundScopeInfo, 4> CompoundScopes; @@ -153,7 +164,7 @@ public: /// \brief A list of parameters which have the nonnull attribute and are /// modified in the function. - llvm::SmallPtrSet<const ParmVarDecl*, 8> ModifiedNonNullParams; + llvm::SmallPtrSet<const ParmVarDecl*, 8> ModifiedNonNullParams; public: /// Represents a simple identification of a weak object. @@ -291,6 +302,9 @@ private: /// Part of the implementation of -Wrepeated-use-of-weak. WeakObjectUseMap WeakObjectUses; +protected: + FunctionScopeInfo(const FunctionScopeInfo&) = default; + public: /// Record that a weak object was accessed. /// @@ -364,6 +378,9 @@ public: }; class CapturingScopeInfo : public FunctionScopeInfo { +protected: + CapturingScopeInfo(const CapturingScopeInfo&) = default; + public: enum ImplicitCaptureStyle { ImpCap_None, ImpCap_LambdaByval, ImpCap_LambdaByref, ImpCap_Block, @@ -549,7 +566,7 @@ public: }; /// \brief Retains information about a block that is currently being parsed. -class BlockScopeInfo : public CapturingScopeInfo { +class BlockScopeInfo final : public CapturingScopeInfo { public: BlockDecl *TheDecl; @@ -576,7 +593,7 @@ public: }; /// \brief Retains information about a captured region. -class CapturedRegionScopeInfo: public CapturingScopeInfo { +class CapturedRegionScopeInfo final : public CapturingScopeInfo { public: /// \brief The CapturedDecl for this statement. CapturedDecl *TheCapturedDecl; @@ -617,7 +634,7 @@ public: } }; -class LambdaScopeInfo : public CapturingScopeInfo { +class LambdaScopeInfo final : public CapturingScopeInfo { public: /// \brief The class that describes the lambda. CXXRecordDecl *Lambda; @@ -697,8 +714,6 @@ public: Kind = SK_Lambda; } - ~LambdaScopeInfo() override; - /// \brief Note when all explicit captures have been added. void finishedExplicitCaptures() { NumExplicitCaptures = Captures.size(); diff --git a/contrib/llvm/tools/clang/include/clang/Sema/Sema.h b/contrib/llvm/tools/clang/include/clang/Sema/Sema.h index 7204433..7873843 100644 --- a/contrib/llvm/tools/clang/include/clang/Sema/Sema.h +++ b/contrib/llvm/tools/clang/include/clang/Sema/Sema.h @@ -145,6 +145,7 @@ namespace clang { class ObjCProtocolDecl; class OMPThreadPrivateDecl; class OMPClause; + struct OverloadCandidate; class OverloadCandidateSet; class OverloadExpr; class ParenListExpr; @@ -277,10 +278,9 @@ class Sema { // it will keep having external linkage. If it has internal linkage, we // will not link it. Since it has no previous decls, it will remain // with internal linkage. - if (getLangOpts().ModulesHideInternalLinkage) - return isVisible(Old) || New->isExternallyVisible(); - return true; + return isVisible(Old) || New->isExternallyVisible(); } + bool shouldLinkPossiblyHiddenDecl(LookupResult &Old, const NamedDecl *New); public: typedef OpaquePtr<DeclGroupRef> DeclGroupPtrTy; @@ -903,6 +903,10 @@ public: /// for C++ records. llvm::FoldingSet<SpecialMemberOverloadResult> SpecialMemberCache; + /// \brief A cache of the flags available in enumerations with the flag_bits + /// attribute. + mutable llvm::DenseMap<const EnumDecl*, llvm::APInt> FlagBitsCache; + /// \brief The kind of translation unit we are processing. /// /// When we're processing a complete translation unit, Sema will perform @@ -1004,6 +1008,24 @@ 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: @@ -1054,6 +1076,14 @@ public: SemaDiagnosticBuilder(DiagnosticBuilder &DB, Sema &SemaRef, unsigned DiagID) : DiagnosticBuilder(DB), SemaRef(SemaRef), DiagID(DiagID) { } + // This is a cunning lie. DiagnosticBuilder actually performs move + // construction in its copy constructor (but due to varied uses, it's not + // possible to conveniently express this as actual move construction). So + // the default copy ctor here is fine, because the base class disables the + // source anyway, so the user-defined ~SemaDiagnosticBuilder is a safe no-op + // in that case anwyay. + SemaDiagnosticBuilder(const SemaDiagnosticBuilder&) = default; + ~SemaDiagnosticBuilder() { // If we aren't active, there is nothing to do. if (!isActive()) return; @@ -1200,16 +1230,6 @@ public: bool CheckFunctionReturnType(QualType T, SourceLocation Loc); - unsigned deduceWeakPropertyFromType(QualType T) { - if ((getLangOpts().getGC() != LangOptions::NonGC && - T.isObjCGCWeak()) || - (getLangOpts().ObjCAutoRefCount && - T.getObjCLifetime() == Qualifiers::OCL_Weak)) - return ObjCDeclSpec::DQ_PR_weak; - return 0; - } - - /// \brief Build a function type. /// /// This routine checks the function type according to C++ rules and @@ -1266,7 +1286,7 @@ public: const FunctionProtoType *FPT); void UpdateExceptionSpec(FunctionDecl *FD, const FunctionProtoType::ExceptionSpecInfo &ESI); - bool CheckSpecifiedExceptionType(QualType &T, const SourceRange &Range); + bool CheckSpecifiedExceptionType(QualType &T, SourceRange Range); bool CheckDistantExceptionSpec(QualType T); bool CheckEquivalentExceptionSpec(FunctionDecl *Old, FunctionDecl *New); bool CheckEquivalentExceptionSpec( @@ -1296,9 +1316,7 @@ public: /// \brief Abstract class used to diagnose incomplete types. struct TypeDiagnoser { - bool Suppressed; - - TypeDiagnoser(bool Suppressed = false) : Suppressed(Suppressed) { } + TypeDiagnoser() {} virtual void diagnose(Sema &S, SourceLocation Loc, QualType T) = 0; virtual ~TypeDiagnoser() {} @@ -1328,17 +1346,17 @@ public: void emit(const SemaDiagnosticBuilder &DB, llvm::index_sequence<Is...>) const { // Apply all tuple elements to the builder in order. - bool Dummy[] = {(DB << getPrintable(std::get<Is>(Args)))...}; + bool Dummy[] = {false, (DB << getPrintable(std::get<Is>(Args)))...}; (void)Dummy; } public: BoundTypeDiagnoser(unsigned DiagID, const Ts &...Args) - : TypeDiagnoser(DiagID == 0), DiagID(DiagID), Args(Args...) {} + : TypeDiagnoser(), DiagID(DiagID), Args(Args...) { + assert(DiagID != 0 && "no diagnostic for type diagnoser"); + } void diagnose(Sema &S, SourceLocation Loc, QualType T) override { - if (Suppressed) - return; const SemaDiagnosticBuilder &DB = S.Diag(Loc, DiagID); emit(DB, llvm::index_sequence_for<Ts...>()); DB << T; @@ -1347,7 +1365,7 @@ public: private: bool RequireCompleteTypeImpl(SourceLocation Loc, QualType T, - TypeDiagnoser &Diagnoser); + TypeDiagnoser *Diagnoser); VisibleModuleSet VisibleModules; llvm::SmallVector<VisibleModuleSet, 16> VisibleModulesStack; @@ -1384,6 +1402,18 @@ public: hasVisibleDefaultArgument(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. + bool isEquivalentInternalLinkageDeclaration(const NamedDecl *A, + const NamedDecl *B); + void diagnoseEquivalentInternalLinkageDeclarations( + SourceLocation Loc, const NamedDecl *D, + ArrayRef<const NamedDecl *> Equiv); + + bool isCompleteType(SourceLocation Loc, QualType T) { + return !RequireCompleteTypeImpl(Loc, T, nullptr); + } bool RequireCompleteType(SourceLocation Loc, QualType T, TypeDiagnoser &Diagnoser); bool RequireCompleteType(SourceLocation Loc, QualType T, @@ -1396,6 +1426,7 @@ public: return RequireCompleteType(Loc, T, Diagnoser); } + void completeExprArrayBound(Expr *E); bool RequireCompleteExprType(Expr *E, TypeDiagnoser &Diagnoser); bool RequireCompleteExprType(Expr *E, unsigned DiagID); @@ -1432,6 +1463,12 @@ public: // Symbol table / Decl tracking callbacks: SemaDecl.cpp. // + struct SkipBodyInfo { + SkipBodyInfo() : ShouldSkip(false), Previous(nullptr) {} + bool ShouldSkip; + NamedDecl *Previous; + }; + /// List of decls defined in a function prototype. This contains EnumConstants /// that incorrectly end up in translation unit scope because there is no /// function to pin them on. ActOnFunctionDeclarator reads this list and patches @@ -1697,11 +1734,14 @@ public: void ActOnFinishKNRParamDeclarations(Scope *S, Declarator &D, SourceLocation LocAfterDecls); - void CheckForFunctionRedefinition(FunctionDecl *FD, - const FunctionDecl *EffectiveDefinition = - nullptr); - Decl *ActOnStartOfFunctionDef(Scope *S, Declarator &D); - Decl *ActOnStartOfFunctionDef(Scope *S, Decl *D); + void CheckForFunctionRedefinition( + FunctionDecl *FD, const FunctionDecl *EffectiveDefinition = nullptr, + SkipBodyInfo *SkipBody = nullptr); + Decl *ActOnStartOfFunctionDef(Scope *S, Declarator &D, + MultiTemplateParamsArg TemplateParamLists, + SkipBodyInfo *SkipBody = nullptr); + Decl *ActOnStartOfFunctionDef(Scope *S, Decl *D, + SkipBodyInfo *SkipBody = nullptr); void ActOnStartOfObjCMethodDef(Scope *S, Decl *D); bool isObjCMethodDecl(Decl *D) { return D && isa<ObjCMethodDecl>(D); @@ -1778,6 +1818,10 @@ public: /// \brief The parser has left a submodule. void ActOnModuleEnd(SourceLocation DirectiveLoc, Module *Mod); + /// \brief Check if module import may be found in the current context, + /// emit error if not. + void diagnoseMisplacedModuleImport(Module *M, SourceLocation ImportLoc); + /// \brief Create an implicit import of the given module at the given /// source location, for error recovery, if possible. /// @@ -1843,12 +1887,6 @@ public: TUK_Friend // Friend declaration: 'friend struct foo;' }; - struct SkipBodyInfo { - SkipBodyInfo() : ShouldSkip(false), Previous(nullptr) {} - bool ShouldSkip; - NamedDecl *Previous; - }; - Decl *ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc, CXXScopeSpec &SS, IdentifierInfo *Name, SourceLocation NameLoc, @@ -1965,7 +2003,9 @@ public: Expr *val); bool CheckEnumUnderlyingType(TypeSourceInfo *TI); bool CheckEnumRedeclaration(SourceLocation EnumLoc, bool IsScoped, - QualType EnumUnderlyingTy, const EnumDecl *Prev); + QualType EnumUnderlyingTy, + bool EnumUnderlyingIsImplicit, + const EnumDecl *Prev); /// Determine whether the body of an anonymous enumeration should be skipped. /// \param II The name of the first enumerator. @@ -2043,6 +2083,22 @@ public: TypeSourceInfo *TInfo); bool isIncompatibleTypedef(TypeDecl *Old, TypedefNameDecl *New); + /// \brief Describes the kind of merge to perform for availability + /// attributes (including "deprecated", "unavailable", and "availability"). + enum AvailabilityMergeKind { + /// \brief Don't merge availability attributes at all. + AMK_None, + /// \brief Merge availability attributes for a redeclaration, which requires + /// an exact match. + AMK_Redeclaration, + /// \brief Merge availability attributes for an override, which requires + /// an exact match or a weakening of constraints. + AMK_Override, + /// \brief Merge availability attributes for an implementation of + /// a protocol requirement. + AMK_ProtocolImplementation, + }; + /// Attribute merging methods. Return true if a new attribute was added. AvailabilityAttr *mergeAvailabilityAttr(NamedDecl *D, SourceRange Range, IdentifierInfo *Platform, @@ -2051,7 +2107,7 @@ public: VersionTuple Obsoleted, bool IsUnavailable, StringRef Message, - bool Override, + AvailabilityMergeKind AMK, unsigned AttrSpellingListIndex); TypeVisibilityAttr *mergeTypeVisibilityAttr(Decl *D, SourceRange Range, TypeVisibilityAttr::VisibilityType Vis, @@ -2079,23 +2135,16 @@ public: unsigned AttrSpellingListIndex); OptimizeNoneAttr *mergeOptimizeNoneAttr(Decl *D, SourceRange Range, unsigned AttrSpellingListIndex); - - /// \brief Describes the kind of merge to perform for availability - /// attributes (including "deprecated", "unavailable", and "availability"). - enum AvailabilityMergeKind { - /// \brief Don't merge availability attributes at all. - AMK_None, - /// \brief Merge availability attributes for a redeclaration, which requires - /// an exact match. - AMK_Redeclaration, - /// \brief Merge availability attributes for an override, which requires - /// an exact match or a weakening of constraints. - AMK_Override - }; + InternalLinkageAttr *mergeInternalLinkageAttr(Decl *D, SourceRange Range, + IdentifierInfo *Ident, + unsigned AttrSpellingListIndex); + CommonAttr *mergeCommonAttr(Decl *D, SourceRange Range, IdentifierInfo *Ident, + unsigned AttrSpellingListIndex); void mergeDeclAttributes(NamedDecl *New, Decl *Old, AvailabilityMergeKind AMK = AMK_Redeclaration); - void MergeTypedefNameDecl(TypedefNameDecl *New, LookupResult &OldDecls); + void MergeTypedefNameDecl(Scope *S, TypedefNameDecl *New, + LookupResult &OldDecls); bool MergeFunctionDecl(FunctionDecl *New, NamedDecl *&Old, Scope *S, bool MergeTypeWithOld); bool MergeCompatibleFunctionDecls(FunctionDecl *New, FunctionDecl *Old, @@ -2416,17 +2465,27 @@ public: bool PartialOverloading = false); // Emit as a 'note' the specific overload candidate - void NoteOverloadCandidate(FunctionDecl *Fn, QualType DestType = QualType()); + void NoteOverloadCandidate(FunctionDecl *Fn, QualType DestType = QualType(), + bool TakingAddress = false); - // Emit as a series of 'note's all template and non-templates - // identified by the expression Expr - void NoteAllOverloadCandidates(Expr* E, QualType DestType = QualType()); + // Emit as a series of 'note's all template and non-templates identified by + // the expression Expr + void NoteAllOverloadCandidates(Expr *E, QualType DestType = QualType(), + bool TakingAddress = false); /// Check the enable_if expressions on the given function. Returns the first /// failing attribute, or NULL if they were all successful. EnableIfAttr *CheckEnableIf(FunctionDecl *Function, ArrayRef<Expr *> Args, bool MissingImplicitThis = false); + /// Returns whether the given function's address can be taken or not, + /// optionally emitting a diagnostic if the address can't be taken. + /// + /// Returns false if taking the address of the function is illegal. + bool checkAddressOfFunctionIsAvailable(const FunctionDecl *Function, + bool Complain = false, + SourceLocation Loc = SourceLocation()); + // [PossiblyAFunctionType] --> [Return] // NonFunctionType --> NonFunctionType // R (A) --> R(A) @@ -2451,7 +2510,7 @@ public: ExprResult &SrcExpr, bool DoFunctionPointerConverion = false, bool Complain = false, - const SourceRange& OpRangeForComplaining = SourceRange(), + SourceRange OpRangeForComplaining = SourceRange(), QualType DestTypeForComplaining = QualType(), unsigned DiagIDForComplaining = 0); @@ -2476,17 +2535,8 @@ public: FRS_DiagnosticIssued }; - // An enum to represent whether something is dealing with a call to begin() - // or a call to end() in a range-based for loop. - enum BeginEndFunction { - BEF_begin, - BEF_end - }; - - ForRangeStatus BuildForRangeBeginEndCall(Scope *S, SourceLocation Loc, + ForRangeStatus BuildForRangeBeginEndCall(SourceLocation Loc, SourceLocation RangeLoc, - VarDecl *Decl, - BeginEndFunction BEF, const DeclarationNameInfo &NameInfo, LookupResult &MemberLookup, OverloadCandidateSet *CandidateSet, @@ -2506,12 +2556,12 @@ public: ExprResult *Result); ExprResult CreateOverloadedUnaryOp(SourceLocation OpLoc, - unsigned Opc, + UnaryOperatorKind Opc, const UnresolvedSetImpl &Fns, Expr *input); ExprResult CreateOverloadedBinOp(SourceLocation OpLoc, - unsigned Opc, + BinaryOperatorKind Opc, const UnresolvedSetImpl &Fns, Expr *LHS, Expr *RHS); @@ -2904,7 +2954,8 @@ public: /// Adjust the calling convention of a method to be the ABI default if it /// wasn't specified explicitly. This handles method types formed from /// function type typedefs and typename template arguments. - void adjustMemberFunctionCC(QualType &T, bool IsStatic); + void adjustMemberFunctionCC(QualType &T, bool IsStatic, bool IsCtorOrDtor, + SourceLocation Loc); // Check if there is an explicit attribute, but only look through parens. // The intent is to look for an attribute on the current declarator, but not @@ -3008,11 +3059,9 @@ public: FieldDeclarator &FD, Selector GetterSel, Selector SetterSel, - const bool isAssign, const bool isReadWrite, - const unsigned Attributes, + unsigned &Attributes, const unsigned AttributesAsWritten, - bool *isOverridingProperty, QualType T, TypeSourceInfo *TSI, tok::ObjCKeywordKind MethodImplKind); @@ -3026,7 +3075,6 @@ public: FieldDeclarator &FD, Selector GetterSel, Selector SetterSel, - const bool isAssign, const bool isReadWrite, const unsigned Attributes, const unsigned AttributesAsWritten, @@ -3039,7 +3087,7 @@ public: /// warning) when atomic property has one but not the other user-declared /// setter or getter. void AtomicPropertySetterGetterRules(ObjCImplDecl* IMPDecl, - ObjCContainerDecl* IDecl); + ObjCInterfaceDecl* IDecl); void DiagnoseOwningPropertyGetterSynthesis(const ObjCImplementationDecl *D); @@ -3307,11 +3355,14 @@ public: BFRK_Check }; - StmtResult ActOnCXXForRangeStmt(SourceLocation ForLoc, Stmt *LoopVar, + StmtResult ActOnCXXForRangeStmt(Scope *S, SourceLocation ForLoc, + SourceLocation CoawaitLoc, + Stmt *LoopVar, SourceLocation ColonLoc, Expr *Collection, SourceLocation RParenLoc, BuildForRangeKind Kind); StmtResult BuildCXXForRangeStmt(SourceLocation ForLoc, + SourceLocation CoawaitLoc, SourceLocation ColonLoc, Stmt *RangeDecl, Stmt *BeginEndDecl, Expr *Cond, Expr *Inc, @@ -3364,6 +3415,10 @@ public: bool IsUnevaluatedContext); bool LookupInlineAsmField(StringRef Base, StringRef Member, unsigned &Offset, SourceLocation AsmLoc); + ExprResult LookupInlineAsmVarDeclField(Expr *RefExpr, StringRef Member, + unsigned &Offset, + llvm::InlineAsmIdentifierInfo &Info, + SourceLocation AsmLoc); StmtResult ActOnMSAsmStmt(SourceLocation AsmLoc, SourceLocation LBraceLoc, ArrayRef<Token> AsmToks, StringRef AsmString, @@ -3458,6 +3513,11 @@ public: void DiagnoseSelfMove(const Expr *LHSExpr, const Expr *RHSExpr, SourceLocation OpLoc); + /// \brief Warn if we're implicitly casting from a _Nullable pointer type to a + /// _Nonnull one. + void diagnoseNullableToNonnullConversion(QualType DstType, QualType SrcType, + SourceLocation Loc); + ParsingDeclState PushParsingDeclaration(sema::DelayedDiagnosticPool &pool) { return DelayedDiagnostics.push(pool); } @@ -3483,7 +3543,7 @@ public: bool ObjCPropertyAccess); bool makeUnavailableInSystemHeader(SourceLocation loc, - StringRef message); + UnavailableAttr::ImplicitReason reason); //===--------------------------------------------------------------------===// // Expression Parsing Callbacks: SemaExpr.cpp. @@ -3664,19 +3724,23 @@ public: ExprResult BuildPossibleImplicitMemberExpr(const CXXScopeSpec &SS, SourceLocation TemplateKWLoc, LookupResult &R, - const TemplateArgumentListInfo *TemplateArgs); + const TemplateArgumentListInfo *TemplateArgs, + const Scope *S); ExprResult BuildImplicitMemberExpr(const CXXScopeSpec &SS, SourceLocation TemplateKWLoc, LookupResult &R, const TemplateArgumentListInfo *TemplateArgs, - bool IsDefiniteInstance); + bool IsDefiniteInstance, + const Scope *S); bool UseArgumentDependentLookup(const CXXScopeSpec &SS, const LookupResult &R, bool HasTrailingLParen); - ExprResult BuildQualifiedDeclarationNameExpr( - CXXScopeSpec &SS, const DeclarationNameInfo &NameInfo, - bool IsAddressOfOperand, TypeSourceInfo **RecoveryTSI = nullptr); + ExprResult + BuildQualifiedDeclarationNameExpr(CXXScopeSpec &SS, + const DeclarationNameInfo &NameInfo, + bool IsAddressOfOperand, const Scope *S, + TypeSourceInfo **RecoveryTSI = nullptr); ExprResult BuildDependentDeclRefExpr(const CXXScopeSpec &SS, SourceLocation TemplateKWLoc, @@ -3752,7 +3816,7 @@ public: ActOnUnaryExprOrTypeTraitExpr(SourceLocation OpLoc, UnaryExprOrTypeTrait ExprKind, bool IsType, void *TyOrEx, - const SourceRange &ArgRange); + SourceRange ArgRange); ExprResult CheckPlaceholderExpr(Expr *E); bool CheckVecStepExpr(Expr *E); @@ -3773,6 +3837,9 @@ public: Expr *Idx, SourceLocation RLoc); ExprResult CreateBuiltinArraySubscriptExpr(Expr *Base, SourceLocation LLoc, Expr *Idx, SourceLocation RLoc); + ExprResult ActOnOMPArraySectionExpr(Expr *Base, SourceLocation LBLoc, + Expr *LowerBound, SourceLocation ColonLoc, + Expr *Length, SourceLocation RBLoc); // This struct is for use by ActOnMemberAccess to allow // BuildMemberReferenceExpr to be able to reinvoke ActOnMemberAccess after @@ -3790,6 +3857,7 @@ public: CXXScopeSpec &SS, SourceLocation TemplateKWLoc, NamedDecl *FirstQualifierInScope, const DeclarationNameInfo &NameInfo, const TemplateArgumentListInfo *TemplateArgs, + const Scope *S, ActOnMemberAccessExtraArgs *ExtraArgs = nullptr); ExprResult @@ -3798,6 +3866,7 @@ public: SourceLocation TemplateKWLoc, NamedDecl *FirstQualifierInScope, LookupResult &R, const TemplateArgumentListInfo *TemplateArgs, + const Scope *S, bool SuppressQualifierCheck = false, ActOnMemberAccessExtraArgs *ExtraArgs = nullptr); @@ -3926,15 +3995,13 @@ public: /// __builtin_offsetof(type, a.b[123][456].c) ExprResult BuildBuiltinOffsetOf(SourceLocation BuiltinLoc, TypeSourceInfo *TInfo, - OffsetOfComponent *CompPtr, - unsigned NumComponents, + ArrayRef<OffsetOfComponent> Components, SourceLocation RParenLoc); ExprResult ActOnBuiltinOffsetOf(Scope *S, SourceLocation BuiltinLoc, SourceLocation TypeLoc, ParsedType ParsedArgTy, - OffsetOfComponent *CompPtr, - unsigned NumComponents, + ArrayRef<OffsetOfComponent> Components, SourceLocation RParenLoc); // __builtin_choose_expr(constExpr, expr1, expr2) @@ -4030,7 +4097,8 @@ public: SourceLocation IdentLoc, IdentifierInfo *Ident, SourceLocation LBrace, - AttributeList *AttrList); + AttributeList *AttrList, + UsingDirectiveDecl * &UsingDecl); void ActOnFinishNamespaceDef(Decl *Dcl, SourceLocation RBrace); NamespaceDecl *getStdNamespace() const; @@ -4936,15 +5004,25 @@ public: /// \brief Perform initialization analysis of the init-capture and perform /// any implicit conversions such as an lvalue-to-rvalue conversion if /// not being used to initialize a reference. - QualType performLambdaInitCaptureInitialization(SourceLocation Loc, - bool ByRef, IdentifierInfo *Id, Expr *&Init); + ParsedType actOnLambdaInitCaptureInitialization( + SourceLocation Loc, bool ByRef, IdentifierInfo *Id, + LambdaCaptureInitKind InitKind, Expr *&Init) { + return ParsedType::make(buildLambdaInitCaptureInitialization( + Loc, ByRef, Id, InitKind != LambdaCaptureInitKind::CopyInit, Init)); + } + QualType buildLambdaInitCaptureInitialization(SourceLocation Loc, bool ByRef, + IdentifierInfo *Id, + bool DirectInit, Expr *&Init); + /// \brief Create a dummy variable within the declcontext of the lambda's /// call operator, for name lookup purposes for a lambda init capture. /// /// CodeGen handles emission of lambda captures, ignoring these dummy /// variables appropriately. - VarDecl *createLambdaInitCaptureVarDecl(SourceLocation Loc, - QualType InitCaptureType, IdentifierInfo *Id, Expr *Init); + VarDecl *createLambdaInitCaptureVarDecl(SourceLocation Loc, + QualType InitCaptureType, + IdentifierInfo *Id, + unsigned InitStyle, Expr *Init); /// \brief Build the implicit field for an init-capture. FieldDecl *buildInitCaptureField(sema::LambdaScopeInfo *LSI, VarDecl *Var); @@ -5009,8 +5087,7 @@ public: // ParseObjCStringLiteral - Parse Objective-C string literals. ExprResult ParseObjCStringLiteral(SourceLocation *AtLocs, - Expr **Strings, - unsigned NumStrings); + ArrayRef<Expr *> Strings); ExprResult BuildObjCStringLiteral(SourceLocation AtLoc, StringLiteral *S); @@ -5035,8 +5112,7 @@ public: ObjCMethodDecl *setterMethod); ExprResult BuildObjCDictionaryLiteral(SourceRange SR, - ObjCDictionaryElement *Elements, - unsigned NumElements); + MutableArrayRef<ObjCDictionaryElement> Elements); ExprResult BuildObjCEncodeExpression(SourceLocation AtLoc, TypeSourceInfo *EncodedTypeInfo, @@ -5222,7 +5298,7 @@ public: SourceLocation RBrac, AttributeList *AttrList); void ActOnFinishCXXMemberDecls(); - void ActOnFinishCXXMemberDefaultArgs(Decl *D); + void ActOnFinishCXXNonNestedClass(Decl *D); void ActOnReenterCXXMethodParameter(Scope *S, ParmVarDecl *Param); unsigned ActOnReenterTemplateScope(Scope *S, Decl *Template); @@ -5289,13 +5365,14 @@ public: SourceLocation BaseLoc, SourceLocation EllipsisLoc); - bool AttachBaseSpecifiers(CXXRecordDecl *Class, CXXBaseSpecifier **Bases, - unsigned NumBases); - void ActOnBaseSpecifiers(Decl *ClassDecl, CXXBaseSpecifier **Bases, - unsigned NumBases); + bool AttachBaseSpecifiers(CXXRecordDecl *Class, + MutableArrayRef<CXXBaseSpecifier *> Bases); + void ActOnBaseSpecifiers(Decl *ClassDecl, + MutableArrayRef<CXXBaseSpecifier *> Bases); - bool IsDerivedFrom(QualType Derived, QualType Base); - bool IsDerivedFrom(QualType Derived, QualType Base, CXXBasePaths &Paths); + bool IsDerivedFrom(SourceLocation Loc, QualType Derived, QualType Base); + bool IsDerivedFrom(SourceLocation Loc, QualType Derived, QualType Base, + CXXBasePaths &Paths); // FIXME: I don't like this name. void BuildBasePathArray(const CXXBasePaths &Paths, CXXCastPath &BasePath); @@ -5424,6 +5501,7 @@ public: AbstractArrayType }; + bool isAbstractType(SourceLocation Loc, QualType T); bool RequireNonAbstractType(SourceLocation Loc, QualType T, TypeDiagnoser &Diagnoser); template <typename... Ts> @@ -5435,9 +5513,6 @@ public: void DiagnoseAbstractType(const CXXRecordDecl *RD); - bool RequireNonAbstractType(SourceLocation Loc, QualType T, unsigned DiagID, - AbstractDiagSelID SelID = AbstractNone); - //===--------------------------------------------------------------------===// // C++ Overloaded Operators [C++ 13.5] // @@ -5508,7 +5583,7 @@ public: SourceLocation ExportLoc, SourceLocation TemplateLoc, SourceLocation LAngleLoc, - Decl **Params, unsigned NumParams, + ArrayRef<Decl *> Params, SourceLocation RAngleLoc); /// \brief The context in which we are checking a template parameter list. @@ -5622,10 +5697,6 @@ public: MultiTemplateParamsArg TemplateParameterLists, Declarator &D); - Decl *ActOnStartOfFunctionTemplateDef(Scope *FnBodyScope, - MultiTemplateParamsArg TemplateParameterLists, - Declarator &D); - bool CheckSpecializationInstantiationRedecl(SourceLocation NewLoc, TemplateSpecializationKind NewTSK, @@ -6340,6 +6411,11 @@ public: bool DeduceReturnType(FunctionDecl *FD, SourceLocation Loc, bool Diagnose = true); + QualType deduceVarTypeFromInitializer(VarDecl *VDecl, DeclarationName Name, + QualType Type, TypeSourceInfo *TSI, + SourceRange Range, bool DirectInit, + Expr *Init); + TypeLoc getReturnTypeLoc(FunctionDecl *FD) const; bool DeduceFunctionTypeFromReturnExpr(FunctionDecl *FD, @@ -6581,12 +6657,6 @@ public: friend class ArgumentPackSubstitutionRAII; - /// \brief The stack of calls expression undergoing template instantiation. - /// - /// The top of this stack is used by a fixit instantiating unresolved - /// function calls to fix the AST to match the textual change it prints. - SmallVector<CallExpr *, 8> CallsUndergoingInstantiation; - /// \brief For each declaration that involved template argument deduction, the /// set of diagnostics that were suppressed during that template argument /// deduction. @@ -6609,7 +6679,8 @@ public: /// the stack. struct InstantiatingTemplate { /// \brief Note that we are instantiating a class template, - /// function template, or a member thereof. + /// function template, variable template, alias template, + /// or a member thereof. InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, Decl *Entity, SourceRange InstantiationRange = SourceRange()); @@ -6655,6 +6726,8 @@ public: sema::TemplateDeductionInfo &DeductionInfo, SourceRange InstantiationRange = SourceRange()); + /// \brief Note that we are instantiating a default argument for a function + /// parameter. InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, ParmVarDecl *Param, ArrayRef<TemplateArgument> TemplateArgs, @@ -6705,7 +6778,7 @@ public: Sema &SemaRef, ActiveTemplateInstantiation::InstantiationKind Kind, SourceLocation PointOfInstantiation, SourceRange InstantiationRange, Decl *Entity, NamedDecl *Template = nullptr, - ArrayRef<TemplateArgument> TemplateArgs = ArrayRef<TemplateArgument>(), + ArrayRef<TemplateArgument> TemplateArgs = None, sema::TemplateDeductionInfo *DeductionInfo = nullptr); InstantiatingTemplate(const InstantiatingTemplate&) = delete; @@ -6925,8 +6998,6 @@ public: /// /// \param Exprs The list of expressions to substitute into. /// - /// \param NumExprs The number of expressions in \p Exprs. - /// /// \param IsCall Whether this is some form of call, in which case /// default arguments will be dropped. /// @@ -6935,7 +7006,7 @@ public: /// \param Outputs Will receive all of the substituted arguments. /// /// \returns true if an error occurred, false otherwise. - bool SubstExprs(Expr **Exprs, unsigned NumExprs, bool IsCall, + bool SubstExprs(ArrayRef<Expr *> Exprs, bool IsCall, const MultiLevelTemplateArgumentList &TemplateArgs, SmallVectorImpl<Expr *> &Outputs); @@ -7169,13 +7240,11 @@ public: unsigned NumElts); DeclGroupPtrTy ActOnForwardProtocolDeclaration(SourceLocation AtProtoclLoc, - const IdentifierLocPair *IdentList, - unsigned NumElts, + ArrayRef<IdentifierLocPair> IdentList, AttributeList *attrList); void FindProtocolDeclaration(bool WarnOnDeclarations, bool ForObjCContainer, - const IdentifierLocPair *ProtocolId, - unsigned NumProtocols, + ArrayRef<IdentifierLocPair> ProtocolId, SmallVectorImpl<Decl *> &Protocols); /// Given a list of identifiers (and their locations), resolve the @@ -7244,14 +7313,7 @@ public: /// Process the specified property declaration and create decls for the /// setters and getters as needed. /// \param property The property declaration being processed - /// \param CD The semantic container for the property - /// \param redeclaredProperty Declaration for property if redeclared - /// in class extension. - /// \param lexicalDC Container for redeclaredProperty. - void ProcessPropertyDecl(ObjCPropertyDecl *property, - ObjCContainerDecl *CD, - ObjCPropertyDecl *redeclaredProperty = nullptr, - ObjCContainerDecl *lexicalDC = nullptr); + void ProcessPropertyDecl(ObjCPropertyDecl *property); void DiagnosePropertyMismatch(ObjCPropertyDecl *Property, @@ -7270,7 +7332,6 @@ public: SourceLocation LParenLoc, FieldDeclarator &FD, ObjCDeclSpec &ODS, Selector GetterSel, Selector SetterSel, - bool *OverridingProperty, tok::ObjCKeywordKind MethodImplKind, DeclContext *lexicalDC = nullptr); @@ -7674,25 +7735,53 @@ public: void AddLaunchBoundsAttr(SourceRange AttrRange, Decl *D, Expr *MaxThreads, Expr *MinBlocks, unsigned SpellingListIndex); + //===--------------------------------------------------------------------===// + // C++ Coroutines TS + // + ExprResult ActOnCoawaitExpr(Scope *S, SourceLocation KwLoc, Expr *E); + ExprResult ActOnCoyieldExpr(Scope *S, SourceLocation KwLoc, Expr *E); + StmtResult ActOnCoreturnStmt(SourceLocation KwLoc, Expr *E); + + ExprResult BuildCoawaitExpr(SourceLocation KwLoc, Expr *E); + ExprResult BuildCoyieldExpr(SourceLocation KwLoc, Expr *E); + StmtResult BuildCoreturnStmt(SourceLocation KwLoc, Expr *E); + + void CheckCompletedCoroutineBody(FunctionDecl *FD, Stmt *&Body); + + //===--------------------------------------------------------------------===// // OpenMP directives and clauses. + // private: void *VarDataSharingAttributesStack; /// \brief Initialization of data-sharing attributes stack. void InitDataSharingAttributesStack(); void DestroyDataSharingAttributesStack(); - ExprResult VerifyPositiveIntegerConstantInClause(Expr *Op, - OpenMPClauseKind CKind); + ExprResult + VerifyPositiveIntegerConstantInClause(Expr *Op, OpenMPClauseKind CKind, + bool StrictlyPositive = true); + public: - /// \brief Check if the specified variable is used in a private clause in - /// Checks if the specified variable is used in one of the private - /// clauses in OpenMP constructs. + /// \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); + + /// \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); - /// OpenMP constructs. + /// \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); + /// \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); + ExprResult PerformOpenMPImplicitIntegerConversion(SourceLocation OpLoc, Expr *Op); /// \brief Called on start of new data sharing attribute block. @@ -7785,6 +7874,7 @@ public: /// \brief Called on well-formed '\#pragma omp critical' after parsing of the /// associated statement. StmtResult ActOnOpenMPCriticalDirective(const DeclarationNameInfo &DirName, + ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc); /// \brief Called on well-formed '\#pragma omp parallel for' after parsing @@ -7828,7 +7918,8 @@ public: SourceLocation EndLoc); /// \brief Called on well-formed '\#pragma omp ordered' after parsing of the /// associated statement. - StmtResult ActOnOpenMPOrderedDirective(Stmt *AStmt, SourceLocation StartLoc, + StmtResult ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses, + Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc); /// \brief Called on well-formed '\#pragma omp atomic' after parsing of the /// associated statement. @@ -7840,6 +7931,11 @@ public: StmtResult ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc); + /// \brief Called on well-formed '\#pragma omp target data' after parsing of + /// the associated statement. + StmtResult ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses, + Stmt *AStmt, SourceLocation StartLoc, + SourceLocation EndLoc); /// \brief Called on well-formed '\#pragma omp teams' after parsing of the /// associated statement. StmtResult ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses, @@ -7851,9 +7947,28 @@ public: SourceLocation EndLoc, OpenMPDirectiveKind CancelRegion); /// \brief Called on well-formed '\#pragma omp cancel'. - StmtResult ActOnOpenMPCancelDirective(SourceLocation StartLoc, + StmtResult ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses, + SourceLocation StartLoc, SourceLocation EndLoc, OpenMPDirectiveKind CancelRegion); + /// \brief Called on well-formed '\#pragma omp taskloop' after parsing of the + /// associated statement. + StmtResult ActOnOpenMPTaskLoopDirective( + ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, + SourceLocation EndLoc, + llvm::DenseMap<VarDecl *, 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); + /// \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); OMPClause *ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, @@ -7861,8 +7976,11 @@ public: SourceLocation LParenLoc, SourceLocation EndLoc); /// \brief Called on well-formed 'if' clause. - OMPClause *ActOnOpenMPIfClause(Expr *Condition, SourceLocation StartLoc, + OMPClause *ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, + Expr *Condition, SourceLocation StartLoc, SourceLocation LParenLoc, + SourceLocation NameModifierLoc, + SourceLocation ColonLoc, SourceLocation EndLoc); /// \brief Called on well-formed 'final' clause. OMPClause *ActOnOpenMPFinalClause(Expr *Condition, SourceLocation StartLoc, @@ -7878,11 +7996,32 @@ public: SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc); + /// \brief Called on well-formed 'simdlen' clause. + OMPClause *ActOnOpenMPSimdlenClause(Expr *Length, SourceLocation StartLoc, + SourceLocation LParenLoc, + SourceLocation EndLoc); /// \brief Called on well-formed 'collapse' clause. OMPClause *ActOnOpenMPCollapseClause(Expr *NumForLoops, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc); + /// \brief Called on well-formed 'ordered' clause. + OMPClause * + ActOnOpenMPOrderedClause(SourceLocation StartLoc, SourceLocation EndLoc, + SourceLocation LParenLoc = SourceLocation(), + Expr *NumForLoops = nullptr); + /// \brief Called on well-formed 'grainsize' clause. + OMPClause *ActOnOpenMPGrainsizeClause(Expr *Size, SourceLocation StartLoc, + SourceLocation LParenLoc, + SourceLocation EndLoc); + /// \brief Called on well-formed 'num_tasks' clause. + OMPClause *ActOnOpenMPNumTasksClause(Expr *NumTasks, SourceLocation StartLoc, + SourceLocation LParenLoc, + SourceLocation EndLoc); + /// \brief Called on well-formed 'hint' clause. + OMPClause *ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, + SourceLocation LParenLoc, + SourceLocation EndLoc); OMPClause *ActOnOpenMPSimpleClause(OpenMPClauseKind Kind, unsigned Argument, @@ -7903,26 +8042,20 @@ public: SourceLocation LParenLoc, SourceLocation EndLoc); - OMPClause *ActOnOpenMPSingleExprWithArgClause(OpenMPClauseKind Kind, - unsigned Argument, Expr *Expr, - SourceLocation StartLoc, - SourceLocation LParenLoc, - SourceLocation ArgumentLoc, - SourceLocation CommaLoc, - SourceLocation EndLoc); + OMPClause *ActOnOpenMPSingleExprWithArgClause( + OpenMPClauseKind Kind, ArrayRef<unsigned> Arguments, Expr *Expr, + SourceLocation StartLoc, SourceLocation LParenLoc, + ArrayRef<SourceLocation> ArgumentsLoc, SourceLocation DelimLoc, + SourceLocation EndLoc); /// \brief Called on well-formed 'schedule' clause. - OMPClause *ActOnOpenMPScheduleClause(OpenMPScheduleClauseKind Kind, - Expr *ChunkSize, SourceLocation StartLoc, - SourceLocation LParenLoc, - SourceLocation KindLoc, - SourceLocation CommaLoc, - SourceLocation EndLoc); + OMPClause *ActOnOpenMPScheduleClause( + OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, + OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, + SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, + SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc); OMPClause *ActOnOpenMPClause(OpenMPClauseKind Kind, SourceLocation StartLoc, SourceLocation EndLoc); - /// \brief Called on well-formed 'ordered' clause. - OMPClause *ActOnOpenMPOrderedClause(SourceLocation StartLoc, - SourceLocation EndLoc); /// \brief Called on well-formed 'nowait' clause. OMPClause *ActOnOpenMPNowaitClause(SourceLocation StartLoc, SourceLocation EndLoc); @@ -7947,6 +8080,15 @@ public: /// \brief Called on well-formed 'seq_cst' clause. OMPClause *ActOnOpenMPSeqCstClause(SourceLocation StartLoc, SourceLocation EndLoc); + /// \brief Called on well-formed 'threads' clause. + OMPClause *ActOnOpenMPThreadsClause(SourceLocation StartLoc, + SourceLocation EndLoc); + /// \brief Called on well-formed 'simd' clause. + OMPClause *ActOnOpenMPSIMDClause(SourceLocation StartLoc, + SourceLocation EndLoc); + /// \brief Called on well-formed 'nogroup' clause. + OMPClause *ActOnOpenMPNogroupClause(SourceLocation StartLoc, + SourceLocation EndLoc); OMPClause *ActOnOpenMPVarListClause( OpenMPClauseKind Kind, ArrayRef<Expr *> Vars, Expr *TailExpr, @@ -7954,7 +8096,8 @@ public: SourceLocation ColonLoc, SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, OpenMPDependClauseKind DepKind, - SourceLocation DepLoc); + OpenMPLinearClauseKind LinKind, OpenMPMapClauseKind MapTypeModifier, + OpenMPMapClauseKind MapType, SourceLocation DepLinMapLoc); /// \brief Called on well-formed 'private' clause. OMPClause *ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, SourceLocation StartLoc, @@ -7983,12 +8126,11 @@ public: CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId); /// \brief Called on well-formed 'linear' clause. - OMPClause *ActOnOpenMPLinearClause(ArrayRef<Expr *> VarList, - Expr *Step, - SourceLocation StartLoc, - SourceLocation LParenLoc, - SourceLocation ColonLoc, - SourceLocation EndLoc); + OMPClause * + ActOnOpenMPLinearClause(ArrayRef<Expr *> VarList, Expr *Step, + SourceLocation StartLoc, SourceLocation LParenLoc, + OpenMPLinearClauseKind LinKind, SourceLocation LinLoc, + SourceLocation ColonLoc, SourceLocation EndLoc); /// \brief Called on well-formed 'aligned' clause. OMPClause *ActOnOpenMPAlignedClause(ArrayRef<Expr *> VarList, Expr *Alignment, @@ -8017,6 +8159,28 @@ public: SourceLocation ColonLoc, ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc); + /// \brief Called on well-formed 'device' clause. + OMPClause *ActOnOpenMPDeviceClause(Expr *Device, SourceLocation StartLoc, + 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); + /// \brief Called on well-formed 'num_teams' clause. + OMPClause *ActOnOpenMPNumTeamsClause(Expr *NumTeams, SourceLocation StartLoc, + SourceLocation LParenLoc, + SourceLocation EndLoc); + /// \brief Called on well-formed 'thread_limit' clause. + OMPClause *ActOnOpenMPThreadLimitClause(Expr *ThreadLimit, + SourceLocation StartLoc, + SourceLocation LParenLoc, + SourceLocation EndLoc); + /// \brief Called on well-formed 'priority' clause. + OMPClause *ActOnOpenMPPriorityClause(Expr *Priority, SourceLocation StartLoc, + SourceLocation LParenLoc, + SourceLocation EndLoc); /// \brief The kind of conversion being performed. enum CheckedConversionKind { @@ -8058,12 +8222,13 @@ public: // DefaultFunctionArrayConversion - converts functions and arrays // to their respective pointers (C99 6.3.2.1). - ExprResult DefaultFunctionArrayConversion(Expr *E); + ExprResult DefaultFunctionArrayConversion(Expr *E, bool Diagnose = true); // DefaultFunctionArrayLvalueConversion - converts functions and // arrays to their respective pointers and performs the // lvalue-to-rvalue conversion. - ExprResult DefaultFunctionArrayLvalueConversion(Expr *E); + ExprResult DefaultFunctionArrayLvalueConversion(Expr *E, + bool Diagnose = true); // DefaultLvalueConversion - performs lvalue-to-rvalue conversion on // the operand. This is DefaultFunctionArrayLvalueConversion, @@ -8231,19 +8396,23 @@ public: QualType LHSType, QualType RHSType); - /// Check assignment constraints and prepare for a conversion of the - /// RHS to the LHS type. + /// Check assignment constraints and optionally prepare for a conversion of + /// the RHS to the LHS type. The conversion is prepared for if ConvertRHS + /// is true. AssignConvertType CheckAssignmentConstraints(QualType LHSType, ExprResult &RHS, - CastKind &Kind); + CastKind &Kind, + bool ConvertRHS = true); // CheckSingleAssignmentConstraints - Currently used by // CheckAssignmentOperands, and ActOnReturnStmt. Prior to type checking, - // this routine performs the default function/array converions. + // this routine performs the default function/array converions, if ConvertRHS + // is true. AssignConvertType CheckSingleAssignmentConstraints(QualType LHSType, ExprResult &RHS, bool Diagnose = true, - bool DiagnoseCFAudited = false); + bool DiagnoseCFAudited = false, + bool ConvertRHS = true); // \brief If the lhs type is a transparent union, check whether we // can initialize the transparent union with the given expression. @@ -8287,22 +8456,23 @@ public: ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, bool IsCompAssign = false); QualType CheckAdditionOperands( // C99 6.5.6 - ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, unsigned Opc, - QualType* CompLHSTy = nullptr); + ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, + BinaryOperatorKind Opc, QualType* CompLHSTy = nullptr); QualType CheckSubtractionOperands( // C99 6.5.6 ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, QualType* CompLHSTy = nullptr); QualType CheckShiftOperands( // C99 6.5.7 - ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, unsigned Opc, - bool IsCompAssign = false); + ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, + BinaryOperatorKind Opc, bool IsCompAssign = false); QualType CheckCompareOperands( // C99 6.5.8/9 - ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, unsigned OpaqueOpc, - bool isRelational); + ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, + BinaryOperatorKind Opc, bool isRelational); QualType CheckBitwiseOperands( // C99 6.5.[10...12] ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, bool IsCompAssign = false); QualType CheckLogicalOperands( // C99 6.5.[13,14] - ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, unsigned Opc); + ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, + BinaryOperatorKind Opc); // CheckAssignmentOperands is used for both simple and compound assignment. // For simple assignment, pass both expressions and a null converted type. // For compound assignment, pass both expressions and the converted type. @@ -8356,6 +8526,7 @@ public: QualType CheckVectorLogicalOperands(ExprResult &LHS, ExprResult &RHS, SourceLocation Loc); + bool areLaxCompatibleVectorTypes(QualType srcType, QualType destType); bool isLaxVectorConversion(QualType srcType, QualType destType); /// type checking declaration initializers (C99 6.7.8) @@ -8562,8 +8733,37 @@ public: CUDAFunctionTarget IdentifyCUDATarget(const FunctionDecl *D); + enum CUDAFunctionPreference { + CFP_Never, // Invalid caller/callee combination. + CFP_LastResort, // Lowest priority. Only in effect if + // LangOpts.CUDADisableTargetCallChecks is true. + CFP_Fallback, // Low priority caller/callee combination + CFP_Best, // Preferred caller/callee combination + }; + + /// Identifies relative preference of a given Caller/Callee + /// combination, based on their host/device attributes. + /// \param Caller function which needs address of \p Callee. + /// nullptr in case of global context. + /// \param Callee target function + /// + /// \returns preference value for particular Caller/Callee combination. + CUDAFunctionPreference IdentifyCUDAPreference(const FunctionDecl *Caller, + const FunctionDecl *Callee); + bool CheckCUDATarget(const FunctionDecl *Caller, const FunctionDecl *Callee); + /// Finds a function in \p Matches with highest calling priority + /// from \p Caller context and erases all functions with lower + /// calling priority. + void EraseUnwantedCUDAMatches(const FunctionDecl *Caller, + SmallVectorImpl<FunctionDecl *> &Matches); + void EraseUnwantedCUDAMatches(const FunctionDecl *Caller, + SmallVectorImpl<DeclAccessPair> &Matches); + void EraseUnwantedCUDAMatches( + const FunctionDecl *Caller, + SmallVectorImpl<std::pair<DeclAccessPair, FunctionDecl *>> &Matches); + /// Given a implicit special member, infer its CUDA target from the /// calls it needs to make to underlying base/field special members. /// \param ClassDecl the class for which the member is being created. @@ -8693,8 +8893,8 @@ public: DeclGroupPtrTy IterationVar); void CodeCompleteObjCSelector(Scope *S, ArrayRef<IdentifierInfo *> SelIdents); - void CodeCompleteObjCProtocolReferences(IdentifierLocPair *Protocols, - unsigned NumProtocols); + void CodeCompleteObjCProtocolReferences( + ArrayRef<IdentifierLocPair> Protocols); void CodeCompleteObjCProtocolDecl(Scope *S); void CodeCompleteObjCInterfaceDecl(Scope *S); void CodeCompleteObjCSuperclass(Scope *S, @@ -8752,8 +8952,8 @@ private: bool HasVAListArg; }; - bool getFormatStringInfo(const FormatAttr *Format, bool IsCXXMember, - FormatStringInfo *FSI); + static bool getFormatStringInfo(const FormatAttr *Format, bool IsCXXMember, + FormatStringInfo *FSI); bool CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall, const FunctionProtoType *Proto); bool CheckObjCMethodCall(ObjCMethodDecl *Method, SourceLocation loc, @@ -8774,7 +8974,7 @@ private: bool CheckObjCString(Expr *Arg); ExprResult CheckBuiltinFunctionCall(FunctionDecl *FDecl, - unsigned BuiltinID, CallExpr *TheCall); + unsigned BuiltinID, CallExpr *TheCall); bool CheckARMBuiltinExclusiveCall(unsigned BuiltinID, CallExpr *TheCall, unsigned MaxWidth); @@ -8786,8 +8986,10 @@ private: bool CheckSystemZBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); bool CheckX86BuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); bool CheckPPCBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); - + + bool SemaBuiltinVAStartImpl(CallExpr *TheCall); bool SemaBuiltinVAStart(CallExpr *TheCall); + bool SemaBuiltinMSVAStart(CallExpr *TheCall); bool SemaBuiltinVAStartARM(CallExpr *Call); bool SemaBuiltinUnorderedCompare(CallExpr *TheCall); bool SemaBuiltinFPClassification(CallExpr *TheCall, unsigned NumArgs); @@ -8806,6 +9008,7 @@ private: bool SemaBuiltinLongjmp(CallExpr *TheCall); bool SemaBuiltinSetjmp(CallExpr *TheCall); ExprResult SemaBuiltinAtomicOverloaded(ExprResult TheCallResult); + ExprResult SemaBuiltinNontemporalOverloaded(ExprResult TheCallResult); ExprResult SemaAtomicOpsOverloaded(ExprResult TheCallResult, AtomicExpr::AtomicOp Op); bool SemaBuiltinConstantArg(CallExpr *TheCall, int ArgNum, @@ -8815,7 +9018,6 @@ private: bool SemaBuiltinARMSpecialReg(unsigned BuiltinID, CallExpr *TheCall, int ArgNum, unsigned ExpectedFieldNum, bool AllowName); - bool SemaBuiltinCpuSupports(CallExpr *TheCall); public: enum FormatStringType { FST_Scanf, @@ -8839,7 +9041,7 @@ public: bool FormatStringHasSArg(const StringLiteral *FExpr); - bool GetFormatNSStringIdx(const FormatAttr *Format, unsigned &Idx); + static bool GetFormatNSStringIdx(const FormatAttr *Format, unsigned &Idx); private: bool CheckFormatArguments(const FormatAttr *Format, @@ -9010,6 +9212,10 @@ public: return NumArgs + 1 > NumParams; // If so, we view as an extra argument. return NumArgs > NumParams; } + + // Emitting members of dllexported classes is delayed until the class + // (including field initializers) is fully parsed. + SmallVector<CXXRecordDecl*, 4> DelayedDllExportClasses; }; /// \brief RAII object that enters a new expression evaluation context. diff --git a/contrib/llvm/tools/clang/include/clang/Sema/Template.h b/contrib/llvm/tools/clang/include/clang/Sema/Template.h index 416ef7b..c092630 100644 --- a/contrib/llvm/tools/clang/include/clang/Sema/Template.h +++ b/contrib/llvm/tools/clang/include/clang/Sema/Template.h @@ -178,8 +178,8 @@ namespace clang { class LocalInstantiationScope { public: /// \brief A set of declarations. - typedef SmallVector<Decl *, 4> DeclArgumentPack; - + typedef SmallVector<ParmVarDecl *, 4> DeclArgumentPack; + private: /// \brief Reference to the semantic analysis that is performing /// this template instantiation. @@ -332,7 +332,7 @@ namespace clang { findInstantiationOf(const Decl *D); void InstantiatedLocal(const Decl *D, Decl *Inst); - void InstantiatedLocalPackArg(const Decl *D, Decl *Inst); + void InstantiatedLocalPackArg(const Decl *D, ParmVarDecl *Inst); void MakeInstantiatedLocalArgPack(const Decl *D); /// \brief Note that the given parameter pack has been partially substituted diff --git a/contrib/llvm/tools/clang/include/clang/Sema/TemplateDeduction.h b/contrib/llvm/tools/clang/include/clang/Sema/TemplateDeduction.h index 229eb71..9315ddd 100644 --- a/contrib/llvm/tools/clang/include/clang/Sema/TemplateDeduction.h +++ b/contrib/llvm/tools/clang/include/clang/Sema/TemplateDeduction.h @@ -236,7 +236,7 @@ struct TemplateSpecCandidate { } /// Diagnose a template argument deduction failure. - void NoteDeductionFailure(Sema &S); + void NoteDeductionFailure(Sema &S, bool ForTakingAddress); }; /// TemplateSpecCandidateSet - A set of generalized overload candidates, @@ -246,6 +246,10 @@ struct TemplateSpecCandidate { class TemplateSpecCandidateSet { SmallVector<TemplateSpecCandidate, 16> Candidates; SourceLocation Loc; + // Stores whether we're taking the address of these candidates. This helps us + // produce better error messages when dealing with the pass_object_size + // attribute on parameters. + bool ForTakingAddress; TemplateSpecCandidateSet( const TemplateSpecCandidateSet &) = delete; @@ -254,7 +258,8 @@ class TemplateSpecCandidateSet { void destroyCandidates(); public: - TemplateSpecCandidateSet(SourceLocation Loc) : Loc(Loc) {} + TemplateSpecCandidateSet(SourceLocation Loc, bool ForTakingAddress = false) + : Loc(Loc), ForTakingAddress(ForTakingAddress) {} ~TemplateSpecCandidateSet() { destroyCandidates(); } SourceLocation getLocation() const { return Loc; } diff --git a/contrib/llvm/tools/clang/include/clang/Sema/TypoCorrection.h b/contrib/llvm/tools/clang/include/clang/Sema/TypoCorrection.h index 958aab0..3b0385e 100644 --- a/contrib/llvm/tools/clang/include/clang/Sema/TypoCorrection.h +++ b/contrib/llvm/tools/clang/include/clang/Sema/TypoCorrection.h @@ -72,15 +72,15 @@ public: /// \brief Gets the DeclarationName of the typo correction DeclarationName getCorrection() const { return CorrectionName; } - IdentifierInfo* getCorrectionAsIdentifierInfo() const { + IdentifierInfo *getCorrectionAsIdentifierInfo() const { return CorrectionName.getAsIdentifierInfo(); } /// \brief Gets the NestedNameSpecifier needed to use the typo correction - NestedNameSpecifier* getCorrectionSpecifier() const { + NestedNameSpecifier *getCorrectionSpecifier() const { return CorrectionNameSpec; } - void setCorrectionSpecifier(NestedNameSpecifier* NNS) { + void setCorrectionSpecifier(NestedNameSpecifier *NNS) { CorrectionNameSpec = NNS; ForceSpecifierReplacement = (NNS != nullptr); } @@ -129,9 +129,16 @@ public: return Normalized ? NormalizeEditDistance(ED) : ED; } + /// \brief Get the correction declaration found by name lookup (before we + /// looked through using shadow declarations and the like). + NamedDecl *getFoundDecl() const { + return hasCorrectionDecl() ? *(CorrectionDecls.begin()) : nullptr; + } + /// \brief Gets the pointer to the declaration of the typo correction NamedDecl *getCorrectionDecl() const { - return hasCorrectionDecl() ? *(CorrectionDecls.begin()) : nullptr; + auto *D = getFoundDecl(); + return D ? D->getUnderlyingDecl() : nullptr; } template <class DeclClass> DeclClass *getCorrectionDeclAs() const { @@ -180,8 +187,7 @@ public: // Check if this TypoCorrection is a keyword by checking if the first // item in CorrectionDecls is NULL. bool isKeyword() const { - return !CorrectionDecls.empty() && - CorrectionDecls.front() == nullptr; + return !CorrectionDecls.empty() && CorrectionDecls.front() == nullptr; } // Check if this TypoCorrection is the given keyword. diff --git a/contrib/llvm/tools/clang/include/clang/Serialization/ASTBitCodes.h b/contrib/llvm/tools/clang/include/clang/Serialization/ASTBitCodes.h index 4b66207..16bda6e 100644 --- a/contrib/llvm/tools/clang/include/clang/Serialization/ASTBitCodes.h +++ b/contrib/llvm/tools/clang/include/clang/Serialization/ASTBitCodes.h @@ -17,6 +17,7 @@ #ifndef LLVM_CLANG_SERIALIZATION_ASTBITCODES_H #define LLVM_CLANG_SERIALIZATION_ASTBITCODES_H +#include "clang/AST/DeclarationName.h" #include "clang/AST/Type.h" #include "llvm/ADT/DenseMap.h" #include "llvm/Bitcode/BitCodes.h" @@ -61,9 +62,6 @@ namespace clang { /// used for the translation unit declaration. typedef uint32_t DeclID; - /// \brief a Decl::Kind/DeclID pair. - typedef std::pair<uint32_t, DeclID> KindDeclIDPair; - // FIXME: Turn these into classes so we can have some type safety when // we go from local ID to global and vice-versa. typedef DeclID LocalDeclID; @@ -235,7 +233,17 @@ namespace clang { /// to create this AST file. /// /// This block is part of the control block. - INPUT_FILES_BLOCK_ID + INPUT_FILES_BLOCK_ID, + + /// \brief The block of configuration options, used to check that + /// a module is being used in a configuration compatible with the + /// configuration in which it was built. + /// + /// This block is part of the control block. + OPTIONS_BLOCK_ID, + + /// \brief A block containing a module file extension. + EXTENSION_BLOCK_ID, }; /// \brief Record types that occur within the control block. @@ -246,63 +254,72 @@ namespace clang { /// \brief Record code for the list of other AST files imported by /// this AST file. - IMPORTS = 2, - - /// \brief Record code for the language options table. - /// - /// The record with this code contains the contents of the - /// LangOptions structure. We serialize the entire contents of - /// the structure, and let the reader decide which options are - /// actually important to check. - LANGUAGE_OPTIONS = 3, - - /// \brief Record code for the target options table. - TARGET_OPTIONS = 4, + IMPORTS, /// \brief Record code for the original file that was used to /// generate the AST file, including both its file ID and its /// name. - ORIGINAL_FILE = 5, + ORIGINAL_FILE, /// \brief The directory that the PCH was originally created in. - ORIGINAL_PCH_DIR = 6, + ORIGINAL_PCH_DIR, /// \brief Record code for file ID of the file or buffer that was used to /// generate the AST file. - ORIGINAL_FILE_ID = 7, + ORIGINAL_FILE_ID, /// \brief Offsets into the input-files block where input files /// reside. - INPUT_FILE_OFFSETS = 8, - - /// \brief Record code for the diagnostic options table. - DIAGNOSTIC_OPTIONS = 9, - - /// \brief Record code for the filesystem options table. - FILE_SYSTEM_OPTIONS = 10, - - /// \brief Record code for the headers search options table. - HEADER_SEARCH_OPTIONS = 11, - - /// \brief Record code for the preprocessor options table. - PREPROCESSOR_OPTIONS = 12, + INPUT_FILE_OFFSETS, /// \brief Record code for the module name. - MODULE_NAME = 13, + MODULE_NAME, /// \brief Record code for the module map file that was used to build this /// AST file. - MODULE_MAP_FILE = 14, + MODULE_MAP_FILE, /// \brief Record code for the signature that identifiers this AST file. - SIGNATURE = 15, + SIGNATURE, /// \brief Record code for the module build directory. - MODULE_DIRECTORY = 16, + MODULE_DIRECTORY, + }; + + /// \brief Record types that occur within the options block inside + /// the control block. + enum OptionsRecordTypes { + /// \brief Record code for the language options table. + /// + /// The record with this code contains the contents of the + /// LangOptions structure. We serialize the entire contents of + /// the structure, and let the reader decide which options are + /// actually important to check. + LANGUAGE_OPTIONS = 1, - /// \brief Record code for the list of other AST files made available by - /// this AST file but not actually used by it. - KNOWN_MODULE_FILES = 17, + /// \brief Record code for the target options table. + TARGET_OPTIONS, + + /// \brief Record code for the diagnostic options table. + DIAGNOSTIC_OPTIONS, + + /// \brief Record code for the filesystem options table. + FILE_SYSTEM_OPTIONS, + + /// \brief Record code for the headers search options table. + HEADER_SEARCH_OPTIONS, + + /// \brief Record code for the preprocessor options table. + PREPROCESSOR_OPTIONS, + }; + + /// \brief Record code for extension blocks. + enum ExtensionBlockRecordTypes { + /// Metadata describing this particular extension. + EXTENSION_METADATA = 1, + + /// The first record ID allocated to the extensions themselves. + FIRST_EXTENSION_RECORD_ID = 4 }; /// \brief Record types that occur within the input-files block @@ -350,7 +367,7 @@ namespace clang { /// \brief This is so that older clang versions, before the introduction /// of the control block, can read and reject the newer PCH format. - /// *DON"T CHANGE THIS NUMBER*. + /// *DON'T CHANGE THIS NUMBER*. METADATA_OLD_FORMAT = 4, /// \brief Record code for the identifier table. @@ -440,10 +457,7 @@ namespace clang { /// declarations. TU_UPDATE_LEXICAL = 22, - /// \brief Record code for the array describing the locations (in the - /// LOCAL_REDECLARATIONS record) of the redeclaration chains, indexed by - /// the first known ID. - LOCAL_REDECLARATIONS_MAP = 23, + // ID 23 used to be for a list of local redeclarations. /// \brief Record code for declarations that Sema keeps references of. SEMA_DECL_REFS = 24, @@ -521,13 +535,8 @@ namespace clang { /// imported by the AST file. IMPORTED_MODULES = 43, - // ID 40 used to be a table of merged canonical declarations. - - /// \brief Record code for the array of redeclaration chains. - /// - /// This array can only be interpreted properly using the local - /// redeclarations map. - LOCAL_REDECLARATIONS = 45, + // ID 44 used to be a table of merged canonical declarations. + // ID 45 used to be a list of declaration IDs of local redeclarations. /// \brief Record code for the array of Objective-C categories (including /// extensions). @@ -543,7 +552,10 @@ namespace clang { /// macro definition. MACRO_OFFSET = 47, - // ID 48 used to be a table of macros. + /// \brief A list of "interesting" identifiers. Only used in C++ (where we + /// don't normally do lookups into the serialized identifier table). These + /// are eagerly deserialized. + INTERESTING_IDENTIFIERS = 48, /// \brief Record code for undefined but used functions and variables that /// need a definition in this TU. @@ -758,26 +770,46 @@ namespace clang { PREDEF_TYPE_ARC_UNBRIDGED_CAST = 34, /// \brief The pseudo-object placeholder type. PREDEF_TYPE_PSEUDO_OBJECT = 35, - /// \brief The __va_list_tag placeholder type. - PREDEF_TYPE_VA_LIST_TAG = 36, /// \brief The placeholder type for builtin functions. - PREDEF_TYPE_BUILTIN_FN = 37, + PREDEF_TYPE_BUILTIN_FN = 36, /// \brief OpenCL 1d image type. - PREDEF_TYPE_IMAGE1D_ID = 38, + PREDEF_TYPE_IMAGE1D_ID = 37, /// \brief OpenCL 1d image array type. - PREDEF_TYPE_IMAGE1D_ARR_ID = 39, + PREDEF_TYPE_IMAGE1D_ARR_ID = 38, /// \brief OpenCL 1d image buffer type. - PREDEF_TYPE_IMAGE1D_BUFF_ID = 40, + PREDEF_TYPE_IMAGE1D_BUFF_ID = 39, /// \brief OpenCL 2d image type. - PREDEF_TYPE_IMAGE2D_ID = 41, + PREDEF_TYPE_IMAGE2D_ID = 40, /// \brief OpenCL 2d image array type. - PREDEF_TYPE_IMAGE2D_ARR_ID = 42, + 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 = 43, + PREDEF_TYPE_IMAGE3D_ID = 48, /// \brief OpenCL event type. - PREDEF_TYPE_EVENT_ID = 44, + PREDEF_TYPE_EVENT_ID = 49, + /// \brief OpenCL clk event type. + PREDEF_TYPE_CLK_EVENT_ID = 50, /// \brief OpenCL sampler type. - PREDEF_TYPE_SAMPLER_ID = 45 + PREDEF_TYPE_SAMPLER_ID = 51, + /// \brief OpenCL queue type. + PREDEF_TYPE_QUEUE_ID = 52, + /// \brief OpenCL ndrange type. + PREDEF_TYPE_NDRANGE_ID = 53, + /// \brief OpenCL reserve_id type. + PREDEF_TYPE_RESERVE_ID_ID = 54, + /// \brief The placeholder type for OpenMP array section. + PREDEF_TYPE_OMP_ARRAY_SECTION = 55 }; /// \brief The number of predefined type IDs that are reserved for @@ -913,44 +945,56 @@ namespace clang { /// it is created. enum PredefinedDeclIDs { /// \brief The NULL declaration. - PREDEF_DECL_NULL_ID = 0, - + PREDEF_DECL_NULL_ID = 0, + /// \brief The translation unit. PREDEF_DECL_TRANSLATION_UNIT_ID = 1, - + /// \brief The Objective-C 'id' type. PREDEF_DECL_OBJC_ID_ID = 2, - + /// \brief The Objective-C 'SEL' type. PREDEF_DECL_OBJC_SEL_ID = 3, - + /// \brief The Objective-C 'Class' type. PREDEF_DECL_OBJC_CLASS_ID = 4, - + /// \brief The Objective-C 'Protocol' type. PREDEF_DECL_OBJC_PROTOCOL_ID = 5, - + /// \brief The signed 128-bit integer type. PREDEF_DECL_INT_128_ID = 6, /// \brief The unsigned 128-bit integer type. PREDEF_DECL_UNSIGNED_INT_128_ID = 7, - + /// \brief The internal 'instancetype' typedef. PREDEF_DECL_OBJC_INSTANCETYPE_ID = 8, /// \brief The internal '__builtin_va_list' typedef. PREDEF_DECL_BUILTIN_VA_LIST_ID = 9, + /// \brief The internal '__va_list_tag' struct, if any. + PREDEF_DECL_VA_LIST_TAG = 10, + + /// \brief The internal '__builtin_ms_va_list' typedef. + PREDEF_DECL_BUILTIN_MS_VA_LIST_ID = 11, + /// \brief The extern "C" context. - PREDEF_DECL_EXTERN_C_CONTEXT_ID = 10, + PREDEF_DECL_EXTERN_C_CONTEXT_ID = 12, + + /// \brief The internal '__make_integer_seq' template. + PREDEF_DECL_MAKE_INTEGER_SEQ_ID = 13, }; /// \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 = 11; + const unsigned int NUM_PREDEF_DECL_IDS = 14; + + /// \brief Record code for a list of local redeclarations of a declaration. + const unsigned int LOCAL_REDECLARATIONS = 50; /// \brief Record codes for each kind of declaration. /// @@ -1369,6 +1413,7 @@ namespace clang { // Microsoft EXPR_CXX_PROPERTY_REF_EXPR, // MSPropertyRefExpr + EXPR_CXX_PROPERTY_SUBSCRIPT_EXPR, // MSPropertySubscriptExpr EXPR_CXX_UUIDOF_EXPR, // CXXUuidofExpr (of expr). EXPR_CXX_UUIDOF_TYPE, // CXXUuidofExpr (of type). STMT_SEH_LEAVE, // SEHLeaveStmt @@ -1397,10 +1442,15 @@ namespace clang { STMT_OMP_ORDERED_DIRECTIVE, STMT_OMP_ATOMIC_DIRECTIVE, STMT_OMP_TARGET_DIRECTIVE, + STMT_OMP_TARGET_DATA_DIRECTIVE, STMT_OMP_TEAMS_DIRECTIVE, STMT_OMP_TASKGROUP_DIRECTIVE, STMT_OMP_CANCELLATION_POINT_DIRECTIVE, STMT_OMP_CANCEL_DIRECTIVE, + STMT_OMP_TASKLOOP_DIRECTIVE, + STMT_OMP_TASKLOOP_SIMD_DIRECTIVE, + STMT_OMP_DISTRIBUTE_DIRECTIVE, + EXPR_OMP_ARRAY_SECTION, // ARC EXPR_OBJC_BRIDGED_CAST, // ObjCBridgedCastExpr @@ -1484,8 +1534,72 @@ namespace clang { } }; + /// \brief A key used when looking up entities by \ref DeclarationName. + /// + /// Different \ref DeclarationNames are mapped to different keys, but the + /// same key can occasionally represent multiple names (for names that + /// contain types, in particular). + class DeclarationNameKey { + typedef unsigned NameKind; + + NameKind Kind; + uint64_t Data; + + public: + DeclarationNameKey() : Kind(), Data() {} + DeclarationNameKey(DeclarationName Name); + + DeclarationNameKey(NameKind Kind, uint64_t Data) + : Kind(Kind), Data(Data) {} + + NameKind getKind() const { return Kind; } + + IdentifierInfo *getIdentifier() const { + assert(Kind == DeclarationName::Identifier || + Kind == DeclarationName::CXXLiteralOperatorName); + return (IdentifierInfo *)Data; + } + Selector getSelector() const { + assert(Kind == DeclarationName::ObjCZeroArgSelector || + Kind == DeclarationName::ObjCOneArgSelector || + Kind == DeclarationName::ObjCMultiArgSelector); + return Selector(Data); + } + OverloadedOperatorKind getOperatorKind() const { + assert(Kind == DeclarationName::CXXOperatorName); + return (OverloadedOperatorKind)Data; + } + + /// Compute a fingerprint of this key for use in on-disk hash table. + unsigned getHash() const; + + friend bool operator==(const DeclarationNameKey &A, + const DeclarationNameKey &B) { + return A.Kind == B.Kind && A.Data == B.Data; + } + }; + /// @} } } // end namespace clang +namespace llvm { + template <> struct DenseMapInfo<clang::serialization::DeclarationNameKey> { + static clang::serialization::DeclarationNameKey getEmptyKey() { + return clang::serialization::DeclarationNameKey(-1, 1); + } + static clang::serialization::DeclarationNameKey getTombstoneKey() { + return clang::serialization::DeclarationNameKey(-1, 2); + } + static unsigned + getHashValue(const clang::serialization::DeclarationNameKey &Key) { + return Key.getHash(); + } + static bool isEqual(const clang::serialization::DeclarationNameKey &L, + const clang::serialization::DeclarationNameKey &R) { + return L == R; + } + }; +} + #endif diff --git a/contrib/llvm/tools/clang/include/clang/Serialization/ASTReader.h b/contrib/llvm/tools/clang/include/clang/Serialization/ASTReader.h index 840655e..588a6a9 100644 --- a/contrib/llvm/tools/clang/include/clang/Serialization/ASTReader.h +++ b/contrib/llvm/tools/clang/include/clang/Serialization/ASTReader.h @@ -30,6 +30,7 @@ #include "clang/Serialization/ASTBitCodes.h" #include "clang/Serialization/ContinuousRangeMap.h" #include "clang/Serialization/Module.h" +#include "clang/Serialization/ModuleFileExtension.h" #include "clang/Serialization/ModuleManager.h" #include "llvm/ADT/APFloat.h" #include "llvm/ADT/APInt.h" @@ -38,6 +39,7 @@ #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallSet.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/TinyPtrVector.h" #include "llvm/Bitcode/BitstreamReader.h" @@ -179,7 +181,8 @@ public: unsigned Value) {} /// This is called for each AST file loaded. - virtual void visitModuleFile(StringRef Filename) {} + virtual void visitModuleFile(StringRef Filename, + serialization::ModuleKind Kind) {} /// \brief Returns true if this \c ASTReaderListener wants to receive the /// input files of the AST file via \c visitInputFile, false otherwise. @@ -194,7 +197,7 @@ public: /// /// \returns true to continue receiving the next input file, false to stop. virtual bool visitInputFile(StringRef Filename, bool isSystem, - bool isOverridden) { + bool isOverridden, bool isExplicitModule) { return true; } @@ -204,6 +207,10 @@ public: /// \brief If needsImportVisitation returns \c true, this is called for each /// AST file imported by this AST file. virtual void visitImport(StringRef Filename) {} + + /// Indicates that a particular module file extension has been read. + virtual void readModuleFileExtension( + const ModuleFileExtensionMetadata &Metadata) {} }; /// \brief Simple wrapper class for chaining listeners. @@ -242,9 +249,12 @@ public: void ReadCounter(const serialization::ModuleFile &M, unsigned Value) override; bool needsInputFileVisitation() override; bool needsSystemInputFileVisitation() override; - void visitModuleFile(StringRef Filename) override; + void visitModuleFile(StringRef Filename, + serialization::ModuleKind Kind) override; bool visitInputFile(StringRef Filename, bool isSystem, - bool isOverridden) override; + bool isOverridden, bool isExplicitModule) override; + void readModuleFileExtension( + const ModuleFileExtensionMetadata &Metadata) override; }; /// \brief ASTReaderListener implementation to validate the information of @@ -280,9 +290,8 @@ class ReadMethodPoolVisitor; namespace reader { class ASTIdentifierLookupTrait; - /// \brief The on-disk hash table used for the DeclContext's Name lookup table. - typedef llvm::OnDiskIterableChainedHashTable<ASTDeclContextNameLookupTrait> - ASTDeclContextNameLookupTable; + /// \brief The on-disk hash table(s) used for DeclContext name lookup. + struct DeclContextLookupTable; } } // end namespace serialization @@ -381,6 +390,9 @@ private: /// \brief The module manager which manages modules and their dependencies ModuleManager ModuleMgr; + /// A mapping from extension block names to module file extensions. + llvm::StringMap<IntrusiveRefCntPtr<ModuleFileExtension>> ModuleFileExtensions; + /// \brief A timer used to track the time spent deserializing. std::unique_ptr<llvm::Timer> ReadTimer; @@ -494,20 +506,36 @@ private: /// \brief Map from a FileID to the file-level declarations that it contains. llvm::DenseMap<FileID, FileDeclsInfo> FileDeclIDs; + /// \brief An array of lexical contents of a declaration context, as a sequence of + /// Decl::Kind, DeclID pairs. + typedef ArrayRef<llvm::support::unaligned_uint32_t> LexicalContents; + + /// \brief Map from a DeclContext to its lexical contents. + llvm::DenseMap<const DeclContext*, std::pair<ModuleFile*, LexicalContents>> + LexicalDecls; + + /// \brief Map from the TU to its lexical contents from each module file. + std::vector<std::pair<ModuleFile*, LexicalContents>> TULexicalDecls; + + /// \brief Map from a DeclContext to its lookup tables. + llvm::DenseMap<const DeclContext *, + serialization::reader::DeclContextLookupTable> Lookups; + // Updates for visible decls can occur for other contexts than just the - // TU, and when we read those update records, the actual context will not - // be available yet (unless it's the TU), so have this pending map using the - // ID as a key. It will be realized when the context is actually loaded. - typedef - SmallVector<std::pair<serialization::reader::ASTDeclContextNameLookupTable *, - ModuleFile*>, 1> DeclContextVisibleUpdates; - typedef llvm::DenseMap<serialization::DeclID, DeclContextVisibleUpdates> - DeclContextVisibleUpdatesPending; + // TU, and when we read those update records, the actual context may not + // be available yet, so have this pending map using the ID as a key. It + // will be realized when the context is actually loaded. + struct PendingVisibleUpdate { + ModuleFile *Mod; + const unsigned char *Data; + }; + typedef SmallVector<PendingVisibleUpdate, 1> DeclContextVisibleUpdates; /// \brief Updates to the visible declarations of declaration contexts that /// haven't been loaded yet. - DeclContextVisibleUpdatesPending PendingVisibleUpdates; - + llvm::DenseMap<serialization::DeclID, DeclContextVisibleUpdates> + PendingVisibleUpdates; + /// \brief The set of C++ or Objective-C classes that have forward /// declarations that have not yet been linked to their definitions. llvm::SmallPtrSet<Decl *, 4> PendingDefinitions; @@ -524,11 +552,14 @@ private: /// performed deduplication. llvm::SetVector<NamedDecl*> PendingMergedDefinitionsToDeduplicate; - /// \brief Read the records that describe the contents of declcontexts. - bool ReadDeclContextStorage(ModuleFile &M, - llvm::BitstreamCursor &Cursor, - const std::pair<uint64_t, uint64_t> &Offsets, - serialization::DeclContextInfo &Info); + /// \brief Read the record that describes the lexical contents of a DC. + bool ReadLexicalDeclContextStorage(ModuleFile &M, + llvm::BitstreamCursor &Cursor, + uint64_t Offset, DeclContext *DC); + /// \brief Read the record that describes the visible contents of a DC. + bool ReadVisibleDeclContextStorage(ModuleFile &M, + llvm::BitstreamCursor &Cursor, + uint64_t Offset, serialization::DeclID ID); /// \brief A vector containing identifiers that have already been /// loaded. @@ -914,20 +945,10 @@ private: /// Objective-C protocols. std::deque<Decl *> InterestingDecls; - /// \brief The set of redeclarable declarations that have been deserialized - /// since the last time the declaration chains were linked. - llvm::SmallPtrSet<Decl *, 16> RedeclsDeserialized; - /// \brief The list of redeclaration chains that still need to be - /// reconstructed. - /// - /// Each element is the canonical declaration of the chain. - /// Elements in this vector should be unique; use - /// PendingDeclChainsKnown to ensure uniqueness. - SmallVector<Decl *, 16> PendingDeclChains; - - /// \brief Keeps track of the elements added to PendingDeclChains. - llvm::SmallSet<Decl *, 16> PendingDeclChainsKnown; + /// reconstructed, and the local offset to the corresponding list + /// of redeclarations. + SmallVector<std::pair<Decl *, uint64_t>, 16> PendingDeclChains; /// \brief The list of canonical declarations whose redeclaration chains /// need to be marked as incomplete once we're done deserializing things. @@ -972,13 +993,6 @@ private: /// module is loaded. SmallVector<ObjCInterfaceDecl *, 16> ObjCClassesLoaded; - /// \brief A mapping from a primary context for a declaration chain to the - /// other declarations of that entity that also have name lookup tables. - /// Used when we merge together two class definitions that have different - /// sets of declared special member functions. - llvm::DenseMap<const DeclContext*, SmallVector<const DeclContext*, 2>> - MergedLookups; - typedef llvm::DenseMap<Decl *, SmallVector<serialization::DeclID, 2> > KeyDeclsMap; @@ -1044,12 +1058,11 @@ private: off_t StoredSize; time_t StoredTime; bool Overridden; + bool Transient; }; /// \brief Reads the stored information about an input file. InputFileInfo readInputFileInfo(ModuleFile &F, unsigned ID); - /// \brief A convenience method to read the filename from an input file. - std::string getInputFileName(ModuleFile &F, unsigned ID); /// \brief Retrieve the file entry and 'overridden' bit for an input /// file in the given module file. @@ -1090,6 +1103,10 @@ public: Visit(GetExistingDecl(ID)); } + /// \brief Get the loaded lookup tables for \p Primary, if any. + const serialization::reader::DeclContextLookupTable * + getLoadedLookupTables(DeclContext *Primary) const; + private: struct ImportedModule { ModuleFile *Mod; @@ -1112,7 +1129,12 @@ private: SmallVectorImpl<ImportedModule> &Loaded, const ModuleFile *ImportedBy, unsigned ClientLoadCapabilities); + static ASTReadResult ReadOptionsBlock( + llvm::BitstreamCursor &Stream, unsigned ClientLoadCapabilities, + bool AllowCompatibleConfigurationMismatch, ASTReaderListener &Listener, + std::string &SuggestedPredefines); ASTReadResult ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities); + ASTReadResult ReadExtensionBlock(ModuleFile &F); bool ParseLineTable(ModuleFile &F, const RecordData &Record); bool ReadSourceManagerBlock(ModuleFile &F); llvm::BitstreamCursor &SLocCursorForID(int ID); @@ -1163,7 +1185,7 @@ private: RecordLocation DeclCursorForID(serialization::DeclID ID, unsigned &RawLocation); void loadDeclUpdateRecords(serialization::DeclID ID, Decl *D); - void loadPendingDeclChain(Decl *D); + void loadPendingDeclChain(Decl *D, uint64_t LocalOffset); void loadObjCCategories(serialization::GlobalDeclID ID, ObjCInterfaceDecl *D, unsigned PreviousGeneration = 0); @@ -1261,9 +1283,12 @@ public: /// \param Context the AST context that this precompiled header will be /// loaded into. /// - /// \param PCHContainerOps the PCHContainerOperations to use for loading and + /// \param PCHContainerRdr the PCHContainerOperations to use for loading and /// creating modules. /// + /// \param Extensions the list of module file extensions that can be loaded + /// from the AST files. + /// /// \param isysroot If non-NULL, the system include path specified by the /// user. This is only used with relocatable PCH files. If non-NULL, /// a relocatable PCH file will use the default path "/". @@ -1290,6 +1315,7 @@ public: /// deserializing. ASTReader(Preprocessor &PP, ASTContext &Context, const PCHContainerReader &PCHContainerRdr, + ArrayRef<IntrusiveRefCntPtr<ModuleFileExtension>> Extensions, StringRef isysroot = "", bool DisableValidation = false, bool AllowASTWithCompilerErrors = false, bool AllowConfigurationMismatch = false, @@ -1300,6 +1326,7 @@ public: SourceManager &getSourceManager() const { return SourceMgr; } FileManager &getFileManager() const { return FileMgr; } + DiagnosticsEngine &getDiags() const { return Diags; } /// \brief Flags that indicate what kind of AST loading failures the client /// of the AST reader can directly handle. @@ -1467,6 +1494,7 @@ public: static bool readASTFileControlBlock(StringRef Filename, FileManager &FileMgr, const PCHContainerReader &PCHContainerRdr, + bool FindModuleFileExtensions, ASTReaderListener &Listener); /// \brief Determine whether the given AST file is acceptable to load into a @@ -1684,7 +1712,7 @@ public: /// ReadBlockAbbrevs - Enter a subblock of the specified BlockID with the /// specified cursor. Read the abbreviations that are at the top of the block /// and then leave the cursor pointing into the block. - bool ReadBlockAbbrevs(llvm::BitstreamCursor &Cursor, unsigned BlockID); + static bool ReadBlockAbbrevs(llvm::BitstreamCursor &Cursor, unsigned BlockID); /// \brief Finds all the visible declarations with a given name. /// The current implementation of this method just loads the entire @@ -1698,16 +1726,17 @@ public: /// \param DC The declaration context whose declarations will be /// read. /// + /// \param IsKindWeWant A predicate indicating which declaration kinds + /// we are interested in. + /// /// \param Decls Vector that will contain the declarations loaded /// from the external source. The caller is responsible for merging /// these declarations with any declarations already stored in the /// declaration context. - /// - /// \returns true if there was an error while reading the - /// declarations for this declaration context. - ExternalLoadResult FindExternalLexicalDecls(const DeclContext *DC, - bool (*isKindWeWant)(Decl::Kind), - SmallVectorImpl<Decl*> &Decls) override; + void + FindExternalLexicalDecls(const DeclContext *DC, + llvm::function_ref<bool(Decl::Kind)> IsKindWeWant, + SmallVectorImpl<Decl *> &Decls) override; /// \brief Get the decls that are contained in a file in the Offset/Length /// range. \p Length can be 0 to indicate a point at \p Offset instead of @@ -1755,10 +1784,7 @@ public: /// declarations with this name are visible from translation unit scope, their /// declarations will be deserialized and introduced into the declaration /// chain of the identifier. - virtual IdentifierInfo *get(const char *NameStart, const char *NameEnd); - IdentifierInfo *get(StringRef Name) override { - return get(Name.begin(), Name.end()); - } + IdentifierInfo *get(StringRef Name) override; /// \brief Retrieve an iterator into the set of all identifiers /// in all loaded AST files. @@ -1873,10 +1899,15 @@ public: /// Note: overrides method in ExternalASTSource Module *getModule(unsigned ID) override; + /// \brief Retrieve the module file with a given local ID within the specified + /// ModuleFile. + ModuleFile *getLocalModuleFile(ModuleFile &M, unsigned ID); + + /// \brief Get an ID for the given module file. + unsigned getModuleFileID(ModuleFile *M); + /// \brief Return a descriptor for the corresponding module. llvm::Optional<ASTSourceDescriptor> getSourceDescriptor(unsigned ID) override; - /// \brief Return a descriptor for the module. - ASTSourceDescriptor getSourceDescriptor(const Module &M) override; /// \brief Retrieve a selector from the given module with its local ID /// number. @@ -1921,8 +1952,9 @@ public: unsigned &Idx); /// \brief Read a template argument. - TemplateArgument ReadTemplateArgument(ModuleFile &F, - const RecordData &Record,unsigned &Idx); + TemplateArgument ReadTemplateArgument(ModuleFile &F, const RecordData &Record, + unsigned &Idx, + bool Canonicalize = false); /// \brief Read a template parameter list. TemplateParameterList *ReadTemplateParameterList(ModuleFile &F, @@ -1930,10 +1962,9 @@ public: unsigned &Idx); /// \brief Read a template argument array. - void - ReadTemplateArgumentList(SmallVectorImpl<TemplateArgument> &TemplArgs, - ModuleFile &F, const RecordData &Record, - unsigned &Idx); + void ReadTemplateArgumentList(SmallVectorImpl<TemplateArgument> &TemplArgs, + ModuleFile &F, const RecordData &Record, + unsigned &Idx, bool Canonicalize = false); /// \brief Read a UnresolvedSet structure. void ReadUnresolvedSet(ModuleFile &F, LazyASTUnresolvedSet &Set, @@ -2082,12 +2113,8 @@ public: SmallVector<std::pair<llvm::BitstreamCursor, serialization::ModuleFile *>, 8> CommentsCursors; - //RIDErief Loads comments ranges. + /// \brief Loads comments ranges. void ReadComments() override; - - /// Return all input files for the given module file. - void getInputFiles(ModuleFile &F, - SmallVectorImpl<serialization::InputFile> &Files); }; /// \brief Helper class that saves the current stream position and diff --git a/contrib/llvm/tools/clang/include/clang/Serialization/ASTWriter.h b/contrib/llvm/tools/clang/include/clang/Serialization/ASTWriter.h index e830fdc..ed34547 100644 --- a/contrib/llvm/tools/clang/include/clang/Serialization/ASTWriter.h +++ b/contrib/llvm/tools/clang/include/clang/Serialization/ASTWriter.h @@ -58,6 +58,8 @@ class OpaqueValueExpr; class OpenCLOptions; class ASTReader; class Module; +class ModuleFileExtension; +class ModuleFileExtensionWriter; class PreprocessedEntity; class PreprocessingRecord; class Preprocessor; @@ -84,6 +86,7 @@ class ASTWriter : public ASTDeserializationListener, public: typedef SmallVector<uint64_t, 64> RecordData; typedef SmallVectorImpl<uint64_t> RecordDataImpl; + typedef ArrayRef<uint64_t> RecordDataRef; friend class ASTDeclWriter; friend class ASTStmtWriter; @@ -119,6 +122,12 @@ private: /// \brief The base directory for any relative paths we emit. std::string BaseDirectory; + /// \brief Indicates whether timestamps should be written to the produced + /// module file. This is the case for files implicitly written to the + /// module cache, where we need the timestamps to determine if the module + /// file is up to date, but not otherwise. + bool IncludeTimestamps; + /// \brief Indicates when the AST writing is actively performing /// serialization, rather than just queueing updates. bool WritingAST; @@ -369,10 +378,6 @@ private: /// coming from another AST file. SmallVector<const Decl *, 16> UpdatingVisibleDecls; - typedef llvm::SmallSetVector<const Decl *, 16> DeclsToRewriteTy; - /// \brief Decls that will be replaced in the current dependent AST file. - DeclsToRewriteTy DeclsToRewrite; - /// \brief The set of Objective-C class that have categories we /// should serialize. llvm::SetVector<ObjCInterfaceDecl *> ObjCClassesWithCategories; @@ -399,6 +404,10 @@ private: /// \brief The set of declarations that may have redeclaration chains that /// need to be serialized. llvm::SmallVector<const Decl *, 16> Redeclarations; + + /// \brief A cache of the first local declaration for "interesting" + /// redeclaration chains. + llvm::DenseMap<const Decl *, const Decl *> FirstLocalDeclCache; /// \brief Statements that we've encountered while serializing a /// declaration or type. @@ -484,20 +493,23 @@ private: /// \brief A mapping from each known submodule to its ID number, which will /// be a positive integer. llvm::DenseMap<Module *, unsigned> SubmoduleIDs; - + + /// \brief A list of the module file extension writers. + std::vector<std::unique_ptr<ModuleFileExtensionWriter>> + ModuleFileExtensionWriters; + /// \brief Retrieve or create a submodule ID for this module. 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 WriteBlockInfoBlock(); - void WriteControlBlock(Preprocessor &PP, ASTContext &Context, - StringRef isysroot, const std::string &OutputFile); - void WriteInputFiles(SourceManager &SourceMgr, - HeaderSearchOptions &HSOpts, + uint64_t WriteControlBlock(Preprocessor &PP, ASTContext &Context, + StringRef isysroot, const std::string &OutputFile); + void WriteInputFiles(SourceManager &SourceMgr, HeaderSearchOptions &HSOpts, bool Modules); void WriteSourceManagerBlock(SourceManager &SourceMgr, const Preprocessor &PP); @@ -519,8 +531,8 @@ private: bool isLookupResultExternal(StoredDeclsList &Result, DeclContext *DC); bool isLookupResultEntirelyExternal(StoredDeclsList &Result, DeclContext *DC); - uint32_t GenerateNameLookupTable(const DeclContext *DC, - llvm::SmallVectorImpl<char> &LookupTable); + void GenerateNameLookupTable(const DeclContext *DC, + llvm::SmallVectorImpl<char> &LookupTable); uint64_t WriteDeclContextLexicalBlock(ASTContext &Context, DeclContext *DC); uint64_t WriteDeclContextVisibleBlock(ASTContext &Context, DeclContext *DC); void WriteTypeDeclOffsets(); @@ -537,9 +549,10 @@ private: void WriteFPPragmaOptions(const FPOptions &Opts); void WriteOpenCLExtensions(Sema &SemaRef); void WriteObjCCategories(); - void WriteRedeclarations(); void WriteLateParsedTemplates(Sema &SemaRef); void WriteOptimizePragmaOptions(Sema &SemaRef); + void WriteModuleFileExtension(Sema &SemaRef, + ModuleFileExtensionWriter &Writer); unsigned DeclParmVarAbbrev; unsigned DeclContextLexicalAbbrev; @@ -562,18 +575,25 @@ private: void WriteDecl(ASTContext &Context, Decl *D); void AddFunctionDefinition(const FunctionDecl *FD, RecordData &Record); - void WriteASTCore(Sema &SemaRef, - StringRef isysroot, const std::string &OutputFile, - Module *WritingModule); + uint64_t WriteASTCore(Sema &SemaRef, + StringRef isysroot, const std::string &OutputFile, + Module *WritingModule); public: /// \brief Create a new precompiled header writer that outputs to /// the given bitstream. - ASTWriter(llvm::BitstreamWriter &Stream); + ASTWriter(llvm::BitstreamWriter &Stream, + ArrayRef<llvm::IntrusiveRefCntPtr<ModuleFileExtension>> Extensions, + bool IncludeTimestamps = true); ~ASTWriter() override; const LangOptions &getLangOpts() const; + /// \brief Get a timestamp for output into the AST file. The actual timestamp + /// of the specified file may be ignored if we have been instructed to not + /// include timestamps in the output file. + time_t getTimestampForOutput(const FileEntry *E) const; + /// \brief Write a precompiled header for the given semantic analysis. /// /// \param SemaRef a reference to the semantic analysis object that processed @@ -585,10 +605,12 @@ public: /// \param isysroot if non-empty, write a relocatable file whose headers /// are relative to the given system root. If we're writing a module, its /// build directory will be used in preference to this if both are available. - void WriteAST(Sema &SemaRef, - const std::string &OutputFile, - Module *WritingModule, StringRef isysroot, - bool hasErrors = false); + /// + /// \return the module signature, which eventually will be a hash of + /// the module but currently is merely a random 32-bit number. + uint64_t WriteAST(Sema &SemaRef, const std::string &OutputFile, + Module *WritingModule, StringRef isysroot, + bool hasErrors = false); /// \brief Emit a token. void AddToken(const Token &Tok, RecordDataImpl &Record); @@ -665,6 +687,10 @@ public: const ASTTemplateArgumentListInfo *ASTTemplArgList, RecordDataImpl &Record); + /// \brief Find the first local declaration of a given local redeclarable + /// decl. + const Decl *getFirstLocalDecl(const Decl *D); + /// \brief Emit a reference to a declaration. void AddDeclRef(const Decl *D, RecordDataImpl &Record); @@ -738,27 +764,20 @@ public: void AddPath(StringRef Path, RecordDataImpl &Record); /// \brief Emit the current record with the given path as a blob. - void EmitRecordWithPath(unsigned Abbrev, RecordDataImpl &Record, + void EmitRecordWithPath(unsigned Abbrev, RecordDataRef Record, StringRef Path); /// \brief Add a version tuple to the given record void AddVersionTuple(const VersionTuple &Version, RecordDataImpl &Record); - void RewriteDecl(const Decl *D) { - DeclsToRewrite.insert(D); - } - - bool isRewritten(const Decl *D) const { - return DeclsToRewrite.count(D); - } - /// \brief Infer the submodule ID that contains an entity at the given /// source location. serialization::SubmoduleID inferSubmoduleIDFromLocation(SourceLocation Loc); - /// \brief Retrieve a submodule ID for this module. - /// Returns 0 If no ID has been associated with the module. - unsigned getExistingSubmoduleID(Module *Mod) const; + /// \brief Retrieve or create a submodule ID for this module, or return 0 if + /// the submodule is neither local (a submodle of the currently-written module) + /// nor from an imported module. + unsigned getLocalOrImportedSubmoduleID(Module *Mod); /// \brief Note that the identifier II occurs at the given offset /// within the identifier table. @@ -830,6 +849,7 @@ public: unsigned getExprImplicitCastAbbrev() const { return ExprImplicitCastAbbrev; } bool hasChain() const { return Chain; } + ASTReader *getChain() const { return Chain; } // ASTDeserializationListener implementation void ReaderInitialized(ASTReader *Reader) override; @@ -845,12 +865,6 @@ public: void CompletedTagDefinition(const TagDecl *D) override; void AddedVisibleDecl(const DeclContext *DC, const Decl *D) override; void AddedCXXImplicitMember(const CXXRecordDecl *RD, const Decl *D) override; - void AddedCXXTemplateSpecialization(const ClassTemplateDecl *TD, - const ClassTemplateSpecializationDecl *D) override; - void AddedCXXTemplateSpecialization(const VarTemplateDecl *TD, - const VarTemplateSpecializationDecl *D) override; - void AddedCXXTemplateSpecialization(const FunctionTemplateDecl *TD, - const FunctionDecl *D) override; void ResolvedExceptionSpec(const FunctionDecl *FD) override; void DeducedReturnType(const FunctionDecl *FD, QualType ReturnType) override; void ResolvedOperatorDelete(const CXXDestructorDecl *DD, @@ -860,9 +874,6 @@ public: void FunctionDefinitionInstantiated(const FunctionDecl *D) override; void AddedObjCCategoryToInterface(const ObjCCategoryDecl *CatD, const ObjCInterfaceDecl *IFD) override; - void AddedObjCPropertyInClassExtension(const ObjCPropertyDecl *Prop, - const ObjCPropertyDecl *OrigProp, - const ObjCCategoryDecl *ClassExt) override; void DeclarationMarkedUsed(const Decl *D) override; void DeclarationMarkedOpenMPThreadPrivate(const Decl *D) override; void RedefinedHiddenDefinition(const NamedDecl *D, Module *M) override; @@ -889,10 +900,13 @@ protected: SmallVectorImpl<char> &getPCH() const { return Buffer->Data; } public: - PCHGenerator(const Preprocessor &PP, StringRef OutputFile, - clang::Module *Module, StringRef isysroot, - std::shared_ptr<PCHBuffer> Buffer, - bool AllowASTWithErrors = false); + PCHGenerator( + const Preprocessor &PP, StringRef OutputFile, + clang::Module *Module, StringRef isysroot, + std::shared_ptr<PCHBuffer> Buffer, + ArrayRef<llvm::IntrusiveRefCntPtr<ModuleFileExtension>> Extensions, + bool AllowASTWithErrors = false, + bool IncludeTimestamps = true); ~PCHGenerator() override; void InitializeSema(Sema &S) override { SemaPtr = &S; } void HandleTranslationUnit(ASTContext &Ctx) override; diff --git a/contrib/llvm/tools/clang/include/clang/Serialization/GlobalModuleIndex.h b/contrib/llvm/tools/clang/include/clang/Serialization/GlobalModuleIndex.h index ba4f7e2..0f14eca 100644 --- a/contrib/llvm/tools/clang/include/clang/Serialization/GlobalModuleIndex.h +++ b/contrib/llvm/tools/clang/include/clang/Serialization/GlobalModuleIndex.h @@ -36,6 +36,7 @@ class FileEntry; class FileManager; class IdentifierIterator; class PCHContainerOperations; +class PCHContainerReader; namespace serialization { class ModuleFile; @@ -193,7 +194,7 @@ public: /// \brief Write a global index into the given /// /// \param FileMgr The file manager to use to load module files. - /// \param PCHContainerOps - The PCHContainerOperations to use for loading and + /// \param PCHContainerRdr - The PCHContainerOperations to use for loading and /// creating modules. /// \param Path The path to the directory containing module files, into /// which the global index will be written. diff --git a/contrib/llvm/tools/clang/include/clang/Serialization/Module.h b/contrib/llvm/tools/clang/include/clang/Serialization/Module.h index c98ced4..d6d16a0 100644 --- a/contrib/llvm/tools/clang/include/clang/Serialization/Module.h +++ b/contrib/llvm/tools/clang/include/clang/Serialization/Module.h @@ -15,9 +15,11 @@ #ifndef LLVM_CLANG_SERIALIZATION_MODULE_H #define LLVM_CLANG_SERIALIZATION_MODULE_H +#include "clang/Basic/FileManager.h" #include "clang/Basic/SourceLocation.h" #include "clang/Serialization/ASTBitCodes.h" #include "clang/Serialization/ContinuousRangeMap.h" +#include "clang/Serialization/ModuleFileExtension.h" #include "llvm/ADT/SetVector.h" #include "llvm/Bitcode/BitstreamReader.h" #include "llvm/Support/Endian.h" @@ -31,7 +33,6 @@ template <typename Info> class OnDiskIterableChainedHashTable; namespace clang { -class FileEntry; class DeclContext; class Module; @@ -50,17 +51,6 @@ enum ModuleKind { MK_MainFile ///< File is a PCH file treated as the actual main file. }; -/// \brief Information about the contents of a DeclContext. -struct DeclContextInfo { - DeclContextInfo() - : NameLookupTableData(), LexicalDecls(), NumLexicalDecls() {} - - llvm::OnDiskIterableChainedHashTable<reader::ASTDeclContextNameLookupTrait> - *NameLookupTableData; // an ASTDeclContextNameLookupTable. - const KindDeclIDPair *LexicalDecls; - unsigned NumLexicalDecls; -}; - /// \brief The input file that has been loaded from this AST file, along with /// bools indicating whether this was an overridden buffer or if it was /// out-of-date or not-found. @@ -155,6 +145,9 @@ public: /// \brief Whether this precompiled header is a relocatable PCH file. bool RelocatablePCH; + /// \brief Whether timestamps are included in this module file. + bool HasTimestamps; + /// \brief The file entry for the module file. const FileEntry *File; @@ -202,6 +195,10 @@ public: /// \brief The first source location in this module. SourceLocation FirstLoc; + /// The list of extension readers that are attached to this module + /// file. + std::vector<std::unique_ptr<ModuleFileExtensionReader>> ExtensionReaders; + // === Input Files === /// \brief The cursor to the start of the input-files block. llvm::BitstreamCursor InputFilesCursor; @@ -270,6 +267,10 @@ public: /// IdentifierHashTable. void *IdentifierLookupTable; + /// \brief Offsets of identifiers that we're going to preload within + /// IdentifierTableData. + std::vector<unsigned> PreloadIdentifierOffsets; + // === Macros === /// \brief The cursor to the start of the preprocessor block, which stores @@ -412,28 +413,10 @@ public: /// indexed by the C++ ctor initializer list ID minus 1. const uint32_t *CXXCtorInitializersOffsets; - typedef llvm::DenseMap<const DeclContext *, DeclContextInfo> - DeclContextInfosMap; - - /// \brief Information about the lexical and visible declarations - /// for each DeclContext. - DeclContextInfosMap DeclContextInfos; - /// \brief Array of file-level DeclIDs sorted by file. const serialization::DeclID *FileSortedDecls; unsigned NumFileSortedDecls; - /// \brief Array of redeclaration chain location information within this - /// module file, sorted by the first declaration ID. - const serialization::LocalRedeclarationsInfo *RedeclarationsMap; - - /// \brief The number of redeclaration info entries in RedeclarationsMap. - unsigned LocalNumRedeclarationsInMap; - - /// \brief The redeclaration chains for declarations local to this - /// module file. - SmallVector<uint64_t, 1> RedeclarationChains; - /// \brief Array of category list location information within this /// module file, sorted by the definition ID. const serialization::ObjCCategoriesInfo *ObjCCategoriesMap; @@ -476,6 +459,11 @@ public: /// any point during translation. bool isDirectlyImported() const { return DirectlyImported; } + /// \brief Is this a module file for a module (rather than a PCH or similar). + bool isModule() const { + return Kind == MK_ImplicitModule || Kind == MK_ExplicitModule; + } + /// \brief Dump debugging output for this module. void dump(); }; diff --git a/contrib/llvm/tools/clang/include/clang/Serialization/ModuleFileExtension.h b/contrib/llvm/tools/clang/include/clang/Serialization/ModuleFileExtension.h new file mode 100644 index 0000000..ba2e2fd --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/Serialization/ModuleFileExtension.h @@ -0,0 +1,149 @@ +//===-- ModuleFileExtension.h - Module File Extensions ----------*- 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_SERIALIZATION_MODULEFILEEXTENSION_H +#define LLVM_CLANG_SERIALIZATION_MODULEFILEEXTENSION_H + +#include "llvm/ADT/IntrusiveRefCntPtr.h" +#include <memory> +#include <string> + +namespace llvm { +class BitstreamCursor; +class BitstreamWriter; +class hash_code; +class raw_ostream; +} + +namespace clang { + +class ASTReader; +class ASTWriter; +class Sema; + +namespace serialization { + class ModuleFile; +} // end namespace serialization + +/// Metadata for a module file extension. +struct ModuleFileExtensionMetadata { + /// The name used to identify this particular extension block within + /// the resulting module file. It should be unique to the particular + /// extension, because this name will be used to match the name of + /// an extension block to the appropriate reader. + std::string BlockName; + + /// The major version of the extension data. + unsigned MajorVersion; + + /// The minor version of the extension data. + unsigned MinorVersion; + + /// A string containing additional user information that will be + /// stored with the metadata. + std::string UserInfo; +}; + +class ModuleFileExtensionReader; +class ModuleFileExtensionWriter; + +/// An abstract superclass that describes a custom extension to the +/// module/precompiled header file format. +/// +/// A module file extension can introduce additional information into +/// compiled module files (.pcm) and precompiled headers (.pch) via a +/// custom writer that can then be accessed via a custom reader when +/// the module file or precompiled header is loaded. +class ModuleFileExtension : public llvm::RefCountedBase<ModuleFileExtension> { +public: + virtual ~ModuleFileExtension(); + + /// Retrieves the metadata for this module file extension. + virtual ModuleFileExtensionMetadata getExtensionMetadata() const = 0; + + /// Hash information about the presence of this extension into the + /// module hash code. + /// + /// The module hash code is used to distinguish different variants + /// of a module that are incompatible. If the presence, absence, or + /// version of the module file extension should force the creation + /// of a separate set of module files, override this method to + /// combine that distinguishing information into the module hash + /// code. + /// + /// The default implementation of this function simply returns the + /// hash code as given, so the presence/absence of this extension + /// does not distinguish module files. + virtual llvm::hash_code hashExtension(llvm::hash_code c) const; + + /// Create a new module file extension writer, which will be + /// responsible for writing the extension contents into a particular + /// module file. + virtual std::unique_ptr<ModuleFileExtensionWriter> + createExtensionWriter(ASTWriter &Writer) = 0; + + /// Create a new module file extension reader, given the + /// metadata read from the block and the cursor into the extension + /// block. + /// + /// May return null to indicate that an extension block with the + /// given metadata cannot be read. + virtual std::unique_ptr<ModuleFileExtensionReader> + createExtensionReader(const ModuleFileExtensionMetadata &Metadata, + ASTReader &Reader, serialization::ModuleFile &Mod, + const llvm::BitstreamCursor &Stream) = 0; +}; + +/// Abstract base class that writes a module file extension block into +/// a module file. +class ModuleFileExtensionWriter { + ModuleFileExtension *Extension; + +protected: + ModuleFileExtensionWriter(ModuleFileExtension *Extension) + : Extension(Extension) { } + +public: + virtual ~ModuleFileExtensionWriter(); + + /// Retrieve the module file extension with which this writer is + /// associated. + ModuleFileExtension *getExtension() const { return Extension; } + + /// Write the contents of the extension block into the given bitstream. + /// + /// Responsible for writing the contents of the extension into the + /// given stream. All of the contents should be written into custom + /// records with IDs >= FIRST_EXTENSION_RECORD_ID. + virtual void writeExtensionContents(Sema &SemaRef, + llvm::BitstreamWriter &Stream) = 0; +}; + +/// Abstract base class that reads a module file extension block from +/// a module file. +/// +/// Subclasses +class ModuleFileExtensionReader { + ModuleFileExtension *Extension; + +protected: + ModuleFileExtensionReader(ModuleFileExtension *Extension) + : Extension(Extension) { } + +public: + /// Retrieve the module file extension with which this reader is + /// associated. + ModuleFileExtension *getExtension() const { return Extension; } + + virtual ~ModuleFileExtensionReader(); +}; + +} // end namespace clang + +#endif // LLVM_CLANG_FRONTEND_MODULEFILEEXTENSION_H diff --git a/contrib/llvm/tools/clang/include/clang/Serialization/ModuleManager.h b/contrib/llvm/tools/clang/include/clang/Serialization/ModuleManager.h index ab39aef..08e7d40 100644 --- a/contrib/llvm/tools/clang/include/clang/Serialization/ModuleManager.h +++ b/contrib/llvm/tools/clang/include/clang/Serialization/ModuleManager.h @@ -30,23 +30,22 @@ namespace serialization { /// \brief Manages the set of modules loaded by an AST reader. class ModuleManager { - /// \brief The chain of AST files. The first entry is the one named by the - /// user, the last one is the one that doesn't depend on anything further. + /// \brief The chain of AST files, in the order in which we started to load + /// them (this order isn't really useful for anything). SmallVector<ModuleFile *, 2> Chain; + /// \brief The chain of non-module PCH files. The first entry is the one named + /// by the user, the last one is the one that doesn't depend on anything + /// further. + SmallVector<ModuleFile *, 2> PCHChain; + // \brief The roots of the dependency DAG of AST files. This is used // to implement short-circuiting logic when running DFS over the dependencies. SmallVector<ModuleFile *, 2> Roots; - + /// \brief All loaded modules, indexed by name. llvm::DenseMap<const FileEntry *, ModuleFile *> Modules; - typedef llvm::SetVector<const FileEntry *> AdditionalKnownModuleFileSet; - - /// \brief Additional module files that are known but not loaded. Tracked - /// here so that we can re-export them if necessary. - AdditionalKnownModuleFileSet AdditionalKnownModuleFiles; - /// \brief FileManager that handles translating between filenames and /// FileEntry *. FileManager &FileMgr; @@ -121,24 +120,26 @@ public: const PCHContainerReader &PCHContainerRdr); ~ModuleManager(); - /// \brief Forward iterator to traverse all loaded modules. This is reverse - /// source-order. + /// \brief Forward iterator to traverse all loaded modules. ModuleIterator begin() { return Chain.begin(); } /// \brief Forward iterator end-point to traverse all loaded modules ModuleIterator end() { return Chain.end(); } - /// \brief Const forward iterator to traverse all loaded modules. This is - /// in reverse source-order. + /// \brief Const forward iterator to traverse all loaded modules. ModuleConstIterator begin() const { return Chain.begin(); } /// \brief Const forward iterator end-point to traverse all loaded modules ModuleConstIterator end() const { return Chain.end(); } - /// \brief Reverse iterator to traverse all loaded modules. This is in - /// source order. + /// \brief Reverse iterator to traverse all loaded modules. ModuleReverseIterator rbegin() { return Chain.rbegin(); } /// \brief Reverse iterator end-point to traverse all loaded modules. ModuleReverseIterator rend() { return Chain.rend(); } - + + /// \brief A range covering the PCH and preamble module files loaded. + llvm::iterator_range<ModuleConstIterator> pch_modules() const { + return llvm::make_range(PCHChain.begin(), PCHChain.end()); + } + /// \brief Returns the primary module associated with the manager, that is, /// the first module loaded ModuleFile &getPrimaryModule() { return *Chain[0]; } @@ -235,19 +236,6 @@ public: /// has been "accepted", and will not (can not) be unloaded. void moduleFileAccepted(ModuleFile *MF); - /// \brief Notification from the frontend that the given module file is - /// part of this compilation (even if not imported) and, if this compilation - /// is exported, should be made available to importers of it. - bool addKnownModuleFile(StringRef FileName); - - /// \brief Get a list of additional module files that are not currently - /// loaded but are considered to be part of the current compilation. - llvm::iterator_range<AdditionalKnownModuleFileSet::const_iterator> - getAdditionalKnownModuleFiles() { - return llvm::make_range(AdditionalKnownModuleFiles.begin(), - AdditionalKnownModuleFiles.end()); - } - /// \brief Visit each of the modules. /// /// This routine visits each of the modules, starting with the @@ -259,51 +247,17 @@ public: /// operations that can find data in any of the loaded modules. /// /// \param Visitor A visitor function that will be invoked with each - /// module and the given user data pointer. The return value must be - /// convertible to bool; when false, the visitation continues to - /// modules that the current module depends on. When true, the - /// visitation skips any modules that the current module depends on. - /// - /// \param UserData User data associated with the visitor object, which - /// will be passed along to the visitor. + /// module. The return value must be convertible to bool; when false, the + /// visitation continues to modules that the current module depends on. When + /// true, the visitation skips any modules that the current module depends on. /// /// \param ModuleFilesHit If non-NULL, contains the set of module files /// that we know we need to visit because the global module index told us to. /// Any module that is known to both the global module index and the module /// manager that is *not* in this set can be skipped. - void visit(bool (*Visitor)(ModuleFile &M, void *UserData), void *UserData, + void visit(llvm::function_ref<bool(ModuleFile &M)> Visitor, llvm::SmallPtrSetImpl<ModuleFile *> *ModuleFilesHit = nullptr); - /// \brief Control DFS behavior during preorder visitation. - enum DFSPreorderControl { - Continue, /// Continue visiting all nodes. - Abort, /// Stop the visitation immediately. - SkipImports, /// Do not visit imports of the current node. - }; - - /// \brief Visit each of the modules with a depth-first traversal. - /// - /// This routine visits each of the modules known to the module - /// manager using a depth-first search, starting with the first - /// loaded module. The traversal invokes one callback before - /// traversing the imports (preorder traversal) and one after - /// traversing the imports (postorder traversal). - /// - /// \param PreorderVisitor A visitor function that will be invoked with each - /// module before visiting its imports. The visitor can control how to - /// continue the visitation through its return value. - /// - /// \param PostorderVisitor A visitor function taht will be invoked with each - /// module after visiting its imports. The visitor may return true at any time - /// to abort the depth-first visitation. - /// - /// \param UserData User data ssociated with the visitor object, - /// which will be passed along to the user. - void visitDepthFirst(DFSPreorderControl (*PreorderVisitor)(ModuleFile &M, - void *UserData), - bool (*PostorderVisitor)(ModuleFile &M, void *UserData), - void *UserData); - /// \brief Attempt to resolve the given module file name to a file entry. /// /// \param FileName The name of the module file. diff --git a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h index f02e48a4..3959de2 100644 --- a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h +++ b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h @@ -253,9 +253,18 @@ private: /// \sa getMaxTimesInlineLarge Optional<unsigned> MaxTimesInlineLarge; + /// \sa getMinCFGSizeTreatFunctionsAsLarge + Optional<unsigned> MinCFGSizeTreatFunctionsAsLarge; + /// \sa getMaxNodesPerTopLevelFunction Optional<unsigned> MaxNodesPerTopLevelFunction; + /// \sa shouldInlineLambdas + Optional<bool> InlineLambdas; + + /// \sa shouldWidenLoops + Optional<bool> WidenLoops; + /// A helper function that retrieves option for a given full-qualified /// checker name. /// Options for checkers can be specified via 'analyzer-config' command-line @@ -502,6 +511,13 @@ public: /// This is controlled by the 'max-times-inline-large' config option. unsigned getMaxTimesInlineLarge(); + /// Returns the number of basic blocks a function needs to have to be + /// considered large for the 'max-times-inline-large' config option. + /// + /// This is controlled by the 'min-cfg-size-treat-functions-as-large' config + /// option. + unsigned getMinCFGSizeTreatFunctionsAsLarge(); + /// Returns the maximum number of nodes the analyzer can generate while /// exploring a top level function (for each exploded graph). /// 150000 is default; 0 means no limit. @@ -509,6 +525,14 @@ public: /// This is controlled by the 'max-nodes' config option. unsigned getMaxNodesPerTopLevelFunction(); + /// Returns true if lambdas should be inlined. Otherwise a sink node will be + /// generated each time a LambdaExpr is visited. + bool shouldInlineLambdas(); + + /// Returns true if the analysis should try to widen loops. + /// This is controlled by the 'widen-loops' config option. + bool shouldWidenLoops(); + public: AnalyzerOptions() : AnalysisStoreOpt(RegionStoreModel), diff --git a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h index 83b05ec..197d27a 100644 --- a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h +++ b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h @@ -37,6 +37,9 @@ class PathDiagnosticPiece; /// will have to provide your own implementation.) class BugReporterVisitor : public llvm::FoldingSetNode { public: + BugReporterVisitor() = default; + BugReporterVisitor(const BugReporterVisitor &) = default; + BugReporterVisitor(BugReporterVisitor &&) {} virtual ~BugReporterVisitor(); /// \brief Returns a copy of this BugReporter. @@ -92,9 +95,8 @@ class BugReporterVisitorImpl : public BugReporterVisitor { } }; -class FindLastStoreBRVisitor - : public BugReporterVisitorImpl<FindLastStoreBRVisitor> -{ +class FindLastStoreBRVisitor final + : public BugReporterVisitorImpl<FindLastStoreBRVisitor> { const MemRegion *R; SVal V; bool Satisfied; @@ -124,9 +126,8 @@ public: BugReport &BR) override; }; -class TrackConstraintBRVisitor - : public BugReporterVisitorImpl<TrackConstraintBRVisitor> -{ +class TrackConstraintBRVisitor final + : public BugReporterVisitorImpl<TrackConstraintBRVisitor> { DefinedSVal Constraint; bool Assumption; bool IsSatisfied; @@ -161,8 +162,8 @@ private: /// \class NilReceiverBRVisitor /// \brief Prints path notes when a message is sent to a nil receiver. -class NilReceiverBRVisitor - : public BugReporterVisitorImpl<NilReceiverBRVisitor> { +class NilReceiverBRVisitor final + : public BugReporterVisitorImpl<NilReceiverBRVisitor> { public: void Profile(llvm::FoldingSetNodeID &ID) const override { @@ -181,7 +182,8 @@ public: }; /// Visitor that tries to report interesting diagnostics from conditions. -class ConditionBRVisitor : public BugReporterVisitorImpl<ConditionBRVisitor> { +class ConditionBRVisitor final + : public BugReporterVisitorImpl<ConditionBRVisitor> { public: void Profile(llvm::FoldingSetNodeID &ID) const override { static int x = 0; @@ -247,8 +249,8 @@ public: /// \brief Suppress reports that might lead to known false positives. /// /// Currently this suppresses reports based on locations of bugs. -class LikelyFalsePositiveSuppressionBRVisitor - : public BugReporterVisitorImpl<LikelyFalsePositiveSuppressionBRVisitor> { +class LikelyFalsePositiveSuppressionBRVisitor final + : public BugReporterVisitorImpl<LikelyFalsePositiveSuppressionBRVisitor> { public: static void *getTag() { static int Tag = 0; @@ -276,8 +278,8 @@ public: /// /// As a result, BugReporter will not prune the path through the function even /// if the region's contents are not modified/accessed by the call. -class UndefOrNullArgVisitor - : public BugReporterVisitorImpl<UndefOrNullArgVisitor> { +class UndefOrNullArgVisitor final + : public BugReporterVisitorImpl<UndefOrNullArgVisitor> { /// The interesting memory region this visitor is tracking. const MemRegion *R; @@ -297,9 +299,8 @@ public: BugReport &BR) override; }; -class SuppressInlineDefensiveChecksVisitor -: public BugReporterVisitorImpl<SuppressInlineDefensiveChecksVisitor> -{ +class SuppressInlineDefensiveChecksVisitor final + : public BugReporterVisitorImpl<SuppressInlineDefensiveChecksVisitor> { /// The symbolic value for which we are tracking constraints. /// This value is constrained to null in the end of path. DefinedSVal V; diff --git a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h index 941d5240..35421f9 100644 --- a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h +++ b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h @@ -122,7 +122,7 @@ class PathDiagnosticRange : public SourceRange { public: bool isPoint; - PathDiagnosticRange(const SourceRange &R, bool isP = false) + PathDiagnosticRange(SourceRange R, bool isP = false) : SourceRange(R), isPoint(isP) {} PathDiagnosticRange() : isPoint(false) {} @@ -422,7 +422,6 @@ class PathPieces : public std::list<IntrusiveRefCntPtr<PathDiagnosticPiece> > { void flattenTo(PathPieces &Primary, PathPieces &Current, bool ShouldFlattenMacros) const; public: - ~PathPieces(); PathPieces flatten(bool ShouldFlattenMacros) const { PathPieces Result; diff --git a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/Checker.h b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/Checker.h index 099d763..1410af1 100644 --- a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/Checker.h +++ b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/Checker.h @@ -131,6 +131,21 @@ public: } }; +class ObjCMessageNil { + template <typename CHECKER> + static void _checkObjCMessage(void *checker, const ObjCMethodCall &msg, + CheckerContext &C) { + ((const CHECKER *)checker)->checkObjCMessageNil(msg, C); + } + +public: + template <typename CHECKER> + static void _register(CHECKER *checker, CheckerManager &mgr) { + mgr._registerForObjCMessageNil( + CheckerManager::CheckObjCMessageFunc(checker, _checkObjCMessage<CHECKER>)); + } +}; + class PostObjCMessage { template <typename CHECKER> static void _checkObjCMessage(void *checker, const ObjCMethodCall &msg, @@ -514,6 +529,10 @@ struct ImplicitNullDerefEvent { bool IsLoad; ExplodedNode *SinkNode; BugReporter *BR; + // When true, the dereference is in the source code directly. When false, the + // dereference might happen later (for example pointer passed to a parameter + // that is marked with nonnull attribute.) + bool IsDirectDereference; }; /// \brief A helper class which wraps a boolean value set to false by default. diff --git a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/CheckerManager.h b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/CheckerManager.h index 8a1a82b..bc9af49 100644 --- a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/CheckerManager.h +++ b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/CheckerManager.h @@ -89,11 +89,16 @@ class CheckName { explicit CheckName(StringRef Name) : Name(Name) {} public: - CheckName() {} - CheckName(const CheckName &Other) : Name(Other.Name) {} + CheckName() = default; StringRef getName() const { return Name; } }; +enum class ObjCMessageVisitKind { + Pre, + Post, + MessageNil +}; + class CheckerManager { const LangOptions LangOpts; AnalyzerOptionsRef AOptions; @@ -212,7 +217,7 @@ public: const ExplodedNodeSet &Src, const ObjCMethodCall &msg, ExprEngine &Eng) { - runCheckersForObjCMessage(/*isPreVisit=*/true, Dst, Src, msg, Eng); + runCheckersForObjCMessage(ObjCMessageVisitKind::Pre, Dst, Src, msg, Eng); } /// \brief Run checkers for post-visiting obj-c messages. @@ -221,12 +226,22 @@ public: const ObjCMethodCall &msg, ExprEngine &Eng, bool wasInlined = false) { - runCheckersForObjCMessage(/*isPreVisit=*/false, Dst, Src, msg, Eng, + runCheckersForObjCMessage(ObjCMessageVisitKind::Post, Dst, Src, msg, Eng, wasInlined); } + /// \brief Run checkers for visiting an obj-c message to nil. + void runCheckersForObjCMessageNil(ExplodedNodeSet &Dst, + const ExplodedNodeSet &Src, + const ObjCMethodCall &msg, + ExprEngine &Eng) { + runCheckersForObjCMessage(ObjCMessageVisitKind::MessageNil, Dst, Src, msg, + Eng); + } + + /// \brief Run checkers for visiting obj-c messages. - void runCheckersForObjCMessage(bool isPreVisit, + void runCheckersForObjCMessage(ObjCMessageVisitKind visitKind, ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, const ObjCMethodCall &msg, ExprEngine &Eng, @@ -458,6 +473,8 @@ public: void _registerForPreObjCMessage(CheckObjCMessageFunc checkfn); void _registerForPostObjCMessage(CheckObjCMessageFunc checkfn); + void _registerForObjCMessageNil(CheckObjCMessageFunc checkfn); + void _registerForPreCall(CheckCallFunc checkfn); void _registerForPostCall(CheckCallFunc checkfn); @@ -558,8 +575,14 @@ private: const CachedStmtCheckers &getCachedStmtCheckersFor(const Stmt *S, bool isPreVisit); + /// Returns the checkers that have registered for callbacks of the + /// given \p Kind. + const std::vector<CheckObjCMessageFunc> & + getObjCMessageCheckers(ObjCMessageVisitKind Kind); + std::vector<CheckObjCMessageFunc> PreObjCMessageCheckers; std::vector<CheckObjCMessageFunc> PostObjCMessageCheckers; + std::vector<CheckObjCMessageFunc> ObjCMessageNilCheckers; std::vector<CheckCallFunc> PreCallCheckers; std::vector<CheckCallFunc> PostCallCheckers; diff --git a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/IssueHash.h b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/IssueHash.h new file mode 100644 index 0000000..b3c4f14 --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/IssueHash.h @@ -0,0 +1,51 @@ +//===---------- IssueHash.h - Generate identification hashes ----*- 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_STATICANALYZER_CORE_ISSUE_HASH_H +#define LLVM_CLANG_STATICANALYZER_CORE_ISSUE_HASH_H + +#include "llvm/ADT/SmallString.h" + +namespace clang { +class Decl; +class SourceManager; +class FullSourceLoc; +class LangOptions; + +/// \brief Get an MD5 hash to help identify bugs. +/// +/// This function returns a hash that helps identify bugs within a source file. +/// This identification can be utilized to diff diagnostic results on different +/// snapshots of a projects, or maintain a database of suppressed diagnotics. +/// +/// The hash contains the normalized text of the location associated with the +/// diagnostic. Normalization means removing the whitespaces. The associated +/// location is the either the last location of a diagnostic path or a uniqueing +/// location. The bugtype and the name of the checker is also part of the hash. +/// The last component is the string representation of the enclosing declaration +/// of the associated location. +/// +/// In case a new hash is introduced, the old one should still be maintained for +/// a while. One should not introduce a new hash for every change, it is +/// possible to introduce experimental hashes that may change in the future. +/// Such hashes should be marked as experimental using a comment in the plist +/// files. +llvm::SmallString<32> GetIssueHash(const SourceManager &SM, + FullSourceLoc &IssueLoc, + llvm::StringRef CheckerName, + llvm::StringRef BugType, const Decl *D, + const LangOptions &LangOpts); + +/// \brief Get the string representation of issue hash. See GetIssueHash() for +/// more information. +std::string GetIssueString(const SourceManager &SM, FullSourceLoc &IssueLoc, + llvm::StringRef CheckerName, llvm::StringRef BugType, + const Decl *D, const LangOptions &LangOpts); +} // namespace clang + +#endif diff --git a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h index 63b8631..b09dffa 100644 --- a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h +++ b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h @@ -164,7 +164,8 @@ protected: /// \brief Used to specify non-argument regions that will be invalidated as a /// result of this call. - virtual void getExtraInvalidatedValues(ValueList &Values) const {} + virtual void getExtraInvalidatedValues(ValueList &Values, + RegionAndSymbolInvalidationTraits *ETraits) const {} public: virtual ~CallEvent() {} @@ -253,9 +254,16 @@ public: /// which the return value has already been bound to the origin expression. SVal getReturnValue() const; + /// \brief Returns true if the type of any of the non-null arguments satisfies + /// the condition. + bool hasNonNullArgumentsWithType(bool (*Condition)(QualType)) const; + /// \brief Returns true if any of the arguments appear to represent callbacks. bool hasNonZeroCallbackArg() const; + /// \brief Returns true if any of the arguments is void*. + bool hasVoidPointerToNonConstArg() const; + /// \brief Returns true if any of the arguments are known to escape to long- /// term storage, even if this method will not modify them. // NOTE: The exact semantics of this are still being defined! @@ -472,7 +480,8 @@ protected: BlockCall(const BlockCall &Other) : CallEvent(Other) {} void cloneTo(void *Dest) const override { new (Dest) BlockCall(*this); } - void getExtraInvalidatedValues(ValueList &Values) const override; + void getExtraInvalidatedValues(ValueList &Values, + RegionAndSymbolInvalidationTraits *ETraits) const override; public: virtual const CallExpr *getOriginExpr() const { @@ -497,8 +506,55 @@ public: return BR->getDecl(); } + bool isConversionFromLambda() const { + const BlockDecl *BD = getDecl(); + if (!BD) + return false; + + return BD->isConversionFromLambda(); + } + + /// \brief For a block converted from a C++ lambda, returns the block + /// VarRegion for the variable holding the captured C++ lambda record. + const VarRegion *getRegionStoringCapturedLambda() const { + assert(isConversionFromLambda()); + const BlockDataRegion *BR = getBlockRegion(); + assert(BR && "Block converted from lambda must have a block region"); + + auto I = BR->referenced_vars_begin(); + assert(I != BR->referenced_vars_end()); + + return I.getCapturedRegion(); + } + RuntimeDefinition getRuntimeDefinition() const override { - return RuntimeDefinition(getDecl()); + if (!isConversionFromLambda()) + return RuntimeDefinition(getDecl()); + + // Clang converts lambdas to blocks with an implicit user-defined + // conversion operator method on the lambda record that looks (roughly) + // like: + // + // typedef R(^block_type)(P1, P2, ...); + // operator block_type() const { + // auto Lambda = *this; + // return ^(P1 p1, P2 p2, ...){ + // /* return Lambda(p1, p2, ...); */ + // }; + // } + // + // Here R is the return type of the lambda and P1, P2, ... are + // its parameter types. 'Lambda' is a fake VarDecl captured by the block + // that is initialized to a copy of the lambda. + // + // Sema leaves the body of a lambda-converted block empty (it is + // produced by CodeGen), so we can't analyze it directly. Instead, we skip + // the block body and analyze the operator() method on the captured lambda. + const VarDecl *LambdaVD = getRegionStoringCapturedLambda()->getDecl(); + const CXXRecordDecl *LambdaDecl = LambdaVD->getType()->getAsCXXRecordDecl(); + CXXMethodDecl* LambdaCallOperator = LambdaDecl->getLambdaCallOperator(); + + return RuntimeDefinition(LambdaCallOperator); } bool argumentsMayEscape() const override { @@ -521,7 +577,8 @@ public: /// it is written. class CXXInstanceCall : public AnyFunctionCall { protected: - void getExtraInvalidatedValues(ValueList &Values) const override; + void getExtraInvalidatedValues(ValueList &Values, + RegionAndSymbolInvalidationTraits *ETraits) const override; CXXInstanceCall(const CallExpr *CE, ProgramStateRef St, const LocationContext *LCtx) @@ -704,7 +761,8 @@ protected: CXXConstructorCall(const CXXConstructorCall &Other) : AnyFunctionCall(Other){} void cloneTo(void *Dest) const override { new (Dest) CXXConstructorCall(*this); } - void getExtraInvalidatedValues(ValueList &Values) const override; + void getExtraInvalidatedValues(ValueList &Values, + RegionAndSymbolInvalidationTraits *ETraits) const override; public: virtual const CXXConstructExpr *getOriginExpr() const { @@ -803,7 +861,8 @@ protected: ObjCMethodCall(const ObjCMethodCall &Other) : CallEvent(Other) {} void cloneTo(void *Dest) const override { new (Dest) ObjCMethodCall(*this); } - void getExtraInvalidatedValues(ValueList &Values) const override; + void getExtraInvalidatedValues(ValueList &Values, + RegionAndSymbolInvalidationTraits *ETraits) const override; /// Check if the selector may have multiple definitions (may have overrides). virtual bool canBeOverridenInSubclass(ObjCInterfaceDecl *IDecl, diff --git a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h index a4ff133..d4f014d 100644 --- a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h +++ b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h @@ -224,13 +224,39 @@ public: } /// \brief Generate a sink node. Generating a sink stops exploration of the - /// given path. - ExplodedNode *generateSink(ProgramStateRef State = nullptr, - ExplodedNode *Pred = nullptr, + /// given path. To create a sink node for the purpose of reporting an error, + /// checkers should use generateErrorNode() instead. + ExplodedNode *generateSink(ProgramStateRef State, ExplodedNode *Pred, const ProgramPointTag *Tag = nullptr) { return addTransitionImpl(State ? State : getState(), true, Pred, Tag); } + /// \brief Generate a transition to a node that will be used to report + /// an error. This node will be a sink. That is, it will stop exploration of + /// the given path. + /// + /// @param State The state of the generated node. + /// @param Tag The tag to uniquely identify the creation site. If null, + /// the default tag for the checker will be used. + ExplodedNode *generateErrorNode(ProgramStateRef State = nullptr, + const ProgramPointTag *Tag = nullptr) { + return generateSink(State, Pred, + (Tag ? Tag : Location.getTag())); + } + + /// \brief Generate a transition to a node that will be used to report + /// an error. This node will not be a sink. That is, exploration will + /// continue along this path. + /// + /// @param State The state of the generated node. + /// @param Tag The tag to uniquely identify the creation site. If null, + /// the default tag for the checker will be used. + ExplodedNode * + generateNonFatalErrorNode(ProgramStateRef State = nullptr, + const ProgramPointTag *Tag = nullptr) { + return addTransition(State, (Tag ? Tag : Location.getTag())); + } + /// \brief Emit the diagnostics report. void emitReport(std::unique_ptr<BugReport> R) { Changed = true; @@ -287,6 +313,18 @@ private: bool MarkAsSink, ExplodedNode *P = nullptr, const ProgramPointTag *Tag = nullptr) { + // The analyzer may stop exploring if it sees a state it has previously + // visited ("cache out"). The early return here is a defensive check to + // prevent accidental caching out by checker API clients. Unless there is a + // tag or the client checker has requested that the generated node be + // marked as a sink, we assume that a client requesting a transition to a + // state that is the same as the predecessor state has made a mistake. We + // return the predecessor rather than cache out. + // + // TODO: We could potentially change the return to an assertion to alert + // clients to their mistake, but several checkers (including + // DereferenceChecker, CallAndMessageChecker, and DynamicTypePropagation) + // rely upon the defensive behavior and would need to be updated. if (!State || (State == Pred->getState() && !Tag && !MarkAsSink)) return Pred; diff --git a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerHelpers.h b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerHelpers.h index e7ec1f4..8dda636 100644 --- a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerHelpers.h +++ b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerHelpers.h @@ -15,9 +15,13 @@ #define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_CHECKERHELPERS_H #include "clang/AST/Stmt.h" +#include <tuple> namespace clang { +class Expr; +class VarDecl; + namespace ento { bool containsMacro(const Stmt *S); @@ -35,6 +39,9 @@ template <class T> bool containsStmt(const Stmt *S) { return false; } +std::pair<const clang::VarDecl *, const clang::Expr *> +parseAssignment(const Stmt *S); + } // end GR namespace } // end clang namespace diff --git a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h index f876096..9a858c2 100644 --- a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h +++ b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h @@ -99,6 +99,35 @@ public: return ProgramStatePair(StTrue, StFalse); } + virtual ProgramStateRef assumeWithinInclusiveRange(ProgramStateRef State, + NonLoc Value, + const llvm::APSInt &From, + const llvm::APSInt &To, + bool InBound) = 0; + + virtual ProgramStatePair assumeWithinInclusiveRangeDual( + ProgramStateRef State, NonLoc Value, const llvm::APSInt &From, + const llvm::APSInt &To) { + ProgramStateRef StInRange = assumeWithinInclusiveRange(State, Value, From, + To, true); + + // If StTrue is infeasible, asserting the falseness of Cond is unnecessary + // because the existing constraints already establish this. + if (!StInRange) + return ProgramStatePair((ProgramStateRef)nullptr, State); + + ProgramStateRef StOutOfRange = assumeWithinInclusiveRange(State, Value, + From, To, false); + if (!StOutOfRange) { + // We are careful to return the original state, /not/ StTrue, + // because we want to avoid having callers generate a new node + // in the ExplodedGraph. + return ProgramStatePair(State, (ProgramStateRef)nullptr); + } + + return ProgramStatePair(StInRange, StOutOfRange); + } + /// \brief If a symbol is perfectly constrained to a constant, attempt /// to return the concrete value. /// diff --git a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeMap.h b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeMap.h new file mode 100644 index 0000000..555191d --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeMap.h @@ -0,0 +1,57 @@ +//== DynamicTypeMap.h - Dynamic type map ----------------------- -*- C++ -*--=// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file provides APIs for tracking dynamic type information. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_DYNAMICTYPEMAP_H +#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_DYNAMICTYPEMAP_H +#include "clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h" +#include "llvm/ADT/ImmutableMap.h" + +namespace clang { +namespace ento { + +/// The GDM component containing the dynamic type info. This is a map from a +/// symbol to its most likely type. +struct DynamicTypeMap {}; +typedef llvm::ImmutableMap<const MemRegion *, DynamicTypeInfo> + DynamicTypeMapImpl; +template <> +struct ProgramStateTrait<DynamicTypeMap> + : public ProgramStatePartialTrait<DynamicTypeMapImpl> { + static void *GDMIndex() { + static int index = 0; + return &index; + } +}; + +/// \brief Get dynamic type information for a region. +DynamicTypeInfo getDynamicTypeInfo(ProgramStateRef State, + const MemRegion *Reg); + +/// \brief Set dynamic type information of the region; return the new state. +ProgramStateRef setDynamicTypeInfo(ProgramStateRef State, const MemRegion *Reg, + DynamicTypeInfo NewTy); + +/// \brief Set dynamic type information of the region; return the new state. +inline ProgramStateRef setDynamicTypeInfo(ProgramStateRef State, + const MemRegion *Reg, QualType NewTy, + bool CanBeSubClassed = true) { + return setDynamicTypeInfo(State, Reg, + DynamicTypeInfo(NewTy, CanBeSubClassed)); +} + +} // ento +} // clang + +#endif // LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_DYNAMICTYPEMAP_H diff --git a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h index d8f1c34..99083c9 100644 --- a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h +++ b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h @@ -341,6 +341,10 @@ public: void VisitBlockExpr(const BlockExpr *BE, ExplodedNode *Pred, ExplodedNodeSet &Dst); + /// VisitLambdaExpr - Transfer function logic for LambdaExprs. + void VisitLambdaExpr(const LambdaExpr *LE, ExplodedNode *Pred, + ExplodedNodeSet &Dst); + /// VisitBinaryOperator - Transfer function logic for binary operators. void VisitBinaryOperator(const BinaryOperator* B, ExplodedNode *Pred, ExplodedNodeSet &Dst); @@ -600,6 +604,28 @@ private: const LocationContext *LC, const Expr *E, const Expr *ResultE = nullptr); + + /// For a DeclStmt or CXXInitCtorInitializer, walk backward in the current CFG + /// block to find the constructor expression that directly constructed into + /// the storage for this statement. Returns null if the constructor for this + /// statement created a temporary object region rather than directly + /// constructing into an existing region. + const CXXConstructExpr *findDirectConstructorForCurrentCFGElement(); + + /// For a CXXConstructExpr, walk forward in the current CFG block to find the + /// CFGElement for the DeclStmt or CXXInitCtorInitializer for which is + /// directly constructed by this constructor. Returns None if the current + /// constructor expression did not directly construct into an existing + /// region. + Optional<CFGElement> findElementDirectlyInitializedByCurrentConstructor(); + + /// For a given constructor, look forward in the current CFG block to + /// determine the region into which an object will be constructed by \p CE. + /// Returns either a field or local variable region if the object will be + /// directly constructed in an existing region or a temporary object region + /// if not. + const MemRegion *getRegionForConstructedObject(const CXXConstructExpr *CE, + ExplodedNode *Pred); }; /// Traits for storing the call processing policy inside GDM. diff --git a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/FunctionSummary.h b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/FunctionSummary.h index faa3500..ce81c98 100644 --- a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/FunctionSummary.h +++ b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/FunctionSummary.h @@ -14,6 +14,7 @@ #ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_FUNCTIONSUMMARY_H #define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_FUNCTIONSUMMARY_H +#include "clang/AST/Decl.h" #include "clang/Basic/LLVM.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseSet.h" @@ -22,7 +23,6 @@ #include <deque> namespace clang { -class Decl; namespace ento { typedef std::deque<Decl*> SetOfDecls; diff --git a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/LoopWidening.h b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/LoopWidening.h new file mode 100644 index 0000000..3168733 --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/LoopWidening.h @@ -0,0 +1,36 @@ +//===--- LoopWidening.h - Widen loops ---------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// +/// This header contains the declarations of functions which are used to widen +/// loops which do not otherwise exit. The widening is done by invalidating +/// anything which might be modified by the body of the loop. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_LOOPWIDENING_H +#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_LOOPWIDENING_H + +#include "clang/Analysis/CFG.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h" + +namespace clang { +namespace ento { + +/// \brief Get the states that result from widening the loop. +/// +/// Widen the loop by invalidating anything that might be modified +/// by the loop body in any iteration. +ProgramStateRef getWidenedLoopState(ProgramStateRef PrevState, + const LocationContext *LCtx, + unsigned BlockCount, const Stmt *LoopStmt); + +} // end namespace ento +} // end namespace clang + +#endif diff --git a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h index 4f07129..bb835c4 100644 --- a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h +++ b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h @@ -19,6 +19,7 @@ #include "clang/AST/ASTContext.h" #include "clang/AST/CharUnits.h" #include "clang/AST/Decl.h" +#include "clang/AST/DeclCXX.h" #include "clang/AST/ExprObjC.h" #include "clang/Basic/LLVM.h" #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h" @@ -46,7 +47,7 @@ class RegionOffset { /// The base region. const MemRegion *R; - /// The bit offset within the base region. It shouldn't be negative. + /// The bit offset within the base region. Can be negative. int64_t Offset; public: @@ -1333,7 +1334,12 @@ public: /// Tells that a region's contents is not changed. TK_PreserveContents = 0x1, /// Suppress pointer-escaping of a region. - TK_SuppressEscape = 0x2 + TK_SuppressEscape = 0x2, + // Do not invalidate super region. + TK_DoNotInvalidateSuperRegion = 0x4, + /// When applied to a MemSpaceRegion, indicates the entire memory space + /// should be invalidated. + TK_EntireMemSpace = 0x8 // Do not forget to extend StorageTypeForKinds if number of traits exceed // the number of bits StorageTypeForKinds can store. diff --git a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h index ac4e452..c4a62ec 100644 --- a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h +++ b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h @@ -190,6 +190,27 @@ public: DefinedOrUnknownSVal upperBound, bool assumption, QualType IndexType = QualType()) const; + + /// Assumes that the value of \p Val is bounded with [\p From; \p To] + /// (if \p assumption is "true") or it is fully out of this range + /// (if \p assumption is "false"). + /// + /// This returns a new state with the added constraint on \p cond. + /// If no new state is feasible, NULL is returned. + ProgramStateRef assumeWithinInclusiveRange(DefinedOrUnknownSVal Val, + const llvm::APSInt &From, + const llvm::APSInt &To, + bool assumption) const; + + /// Assumes given range both "true" and "false" for \p Val, and returns both + /// corresponding states (respectively). + /// + /// This is more efficient than calling assume() twice. Note that one (but not + /// both) of the returned states may be NULL. + std::pair<ProgramStateRef, ProgramStateRef> + assumeWithinInclusiveRange(DefinedOrUnknownSVal Val, const llvm::APSInt &From, + const llvm::APSInt &To) const; + /// \brief Check if the given SVal is constrained to zero or is a zero /// constant. @@ -337,20 +358,6 @@ public: bool isTainted(SymbolRef Sym, TaintTagType Kind = TaintTagGeneric) const; bool isTainted(const MemRegion *Reg, TaintTagType Kind=TaintTagGeneric) const; - /// \brief Get dynamic type information for a region. - DynamicTypeInfo getDynamicTypeInfo(const MemRegion *Reg) const; - - /// \brief Set dynamic type information of the region; return the new state. - ProgramStateRef setDynamicTypeInfo(const MemRegion *Reg, - DynamicTypeInfo NewTy) const; - - /// \brief Set dynamic type information of the region; return the new state. - ProgramStateRef setDynamicTypeInfo(const MemRegion *Reg, - QualType NewTy, - bool CanBeSubClassed = true) const { - return setDynamicTypeInfo(Reg, DynamicTypeInfo(NewTy, CanBeSubClassed)); - } - //==---------------------------------------------------------------------==// // Accessing the Generic Data Map (GDM). //==---------------------------------------------------------------------==// @@ -650,6 +657,33 @@ ProgramState::assume(DefinedOrUnknownSVal Cond) const { ->assumeDual(this, Cond.castAs<DefinedSVal>()); } +inline ProgramStateRef +ProgramState::assumeWithinInclusiveRange(DefinedOrUnknownSVal Val, + const llvm::APSInt &From, + const llvm::APSInt &To, + bool Assumption) const { + if (Val.isUnknown()) + return this; + + assert(Val.getAs<NonLoc>() && "Only NonLocs are supported!"); + + return getStateManager().ConstraintMgr->assumeWithinInclusiveRange( + this, Val.castAs<NonLoc>(), From, To, Assumption); +} + +inline std::pair<ProgramStateRef, ProgramStateRef> +ProgramState::assumeWithinInclusiveRange(DefinedOrUnknownSVal Val, + const llvm::APSInt &From, + const llvm::APSInt &To) const { + if (Val.isUnknown()) + return std::make_pair(this, this); + + assert(Val.getAs<NonLoc>() && "Only NonLocs are supported!"); + + return getStateManager().ConstraintMgr + ->assumeWithinInclusiveRangeDual(this, Val.castAs<NonLoc>(), From, To); +} + inline ProgramStateRef ProgramState::bindLoc(SVal LV, SVal V) const { if (Optional<Loc> L = LV.getAs<Loc>()) return bindLoc(*L, V); diff --git a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h index 1ca96a2..9dbfab2 100644 --- a/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h +++ b/contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h @@ -639,6 +639,7 @@ public: } void markLive(const MemRegion *region); + void markElementIndicesLive(const MemRegion *region); /// \brief Set to the value of the symbolic store after /// StoreManager::removeDeadBindings has been called. @@ -650,14 +651,20 @@ private: }; class SymbolVisitor { +protected: + ~SymbolVisitor() = default; + public: + SymbolVisitor() = default; + SymbolVisitor(const SymbolVisitor &) = default; + SymbolVisitor(SymbolVisitor &&) {} + /// \brief A visitor method invoked by ProgramStateManager::scanReachableSymbols. /// /// The method returns \c true if symbols should continue be scanned and \c /// false otherwise. virtual bool VisitSymbol(SymbolRef sym) = 0; virtual bool VisitMemRegion(const MemRegion *region) { return true; } - virtual ~SymbolVisitor(); }; } // end GR namespace diff --git a/contrib/llvm/tools/clang/include/clang/Tooling/ArgumentsAdjusters.h b/contrib/llvm/tools/clang/include/clang/Tooling/ArgumentsAdjusters.h index a92e021..1fd7be6 100644 --- a/contrib/llvm/tools/clang/include/clang/Tooling/ArgumentsAdjusters.h +++ b/contrib/llvm/tools/clang/include/clang/Tooling/ArgumentsAdjusters.h @@ -17,6 +17,8 @@ #ifndef LLVM_CLANG_TOOLING_ARGUMENTSADJUSTERS_H #define LLVM_CLANG_TOOLING_ARGUMENTSADJUSTERS_H +#include "clang/Basic/LLVM.h" +#include "llvm/ADT/StringRef.h" #include <functional> #include <string> #include <vector> @@ -31,8 +33,8 @@ typedef std::vector<std::string> CommandLineArguments; /// /// Command line argument adjuster is responsible for command line arguments /// modification before the arguments are used to run a frontend action. -typedef std::function<CommandLineArguments(const CommandLineArguments &)> - ArgumentsAdjuster; +typedef std::function<CommandLineArguments( + const CommandLineArguments &, StringRef Filename)> ArgumentsAdjuster; /// \brief Gets an argument adjuster that converts input command line arguments /// to the "syntax check only" variant. diff --git a/contrib/llvm/tools/clang/include/clang/Tooling/CommonOptionsParser.h b/contrib/llvm/tools/clang/include/clang/Tooling/CommonOptionsParser.h index c23dc92..1e8462c 100644 --- a/contrib/llvm/tools/clang/include/clang/Tooling/CommonOptionsParser.h +++ b/contrib/llvm/tools/clang/include/clang/Tooling/CommonOptionsParser.h @@ -42,6 +42,7 @@ namespace tooling { /// \code /// #include "clang/Frontend/FrontendActions.h" /// #include "clang/Tooling/CommonOptionsParser.h" +/// #include "clang/Tooling/Tooling.h" /// #include "llvm/Support/CommandLine.h" /// /// using namespace clang::tooling; @@ -56,8 +57,8 @@ namespace tooling { /// int main(int argc, const char **argv) { /// CommonOptionsParser OptionsParser(argc, argv, MyToolCategory); /// ClangTool Tool(OptionsParser.getCompilations(), -/// OptionsParser.getSourcePathListi()); -/// return Tool.run(newFrontendActionFactory<clang::SyntaxOnlyAction>()); +/// OptionsParser.getSourcePathList()); +/// return Tool.run(newFrontendActionFactory<SyntaxOnlyAction>().get()); /// } /// \endcode class CommonOptionsParser { @@ -72,6 +73,23 @@ public: /// This constructor exits program in case of error. CommonOptionsParser(int &argc, const char **argv, llvm::cl::OptionCategory &Category, + const char *Overview = nullptr) + : CommonOptionsParser(argc, argv, Category, llvm::cl::OneOrMore, + Overview) {} + + /// \brief Parses command-line, initializes a compilation database. + /// + /// This constructor can change argc and argv contents, e.g. consume + /// command-line options used for creating FixedCompilationDatabase. + /// + /// All options not belonging to \p Category become hidden. + /// + /// I also allows calls to set the required number of positional parameters. + /// + /// This constructor exits program in case of error. + CommonOptionsParser(int &argc, const char **argv, + llvm::cl::OptionCategory &Category, + llvm::cl::NumOccurrencesFlag OccurrencesFlag, const char *Overview = nullptr); /// Returns a reference to the loaded compilations database. diff --git a/contrib/llvm/tools/clang/include/clang/Tooling/CompilationDatabase.h b/contrib/llvm/tools/clang/include/clang/Tooling/CompilationDatabase.h index e5b95af..08a0ffe 100644 --- a/contrib/llvm/tools/clang/include/clang/Tooling/CompilationDatabase.h +++ b/contrib/llvm/tools/clang/include/clang/Tooling/CompilationDatabase.h @@ -42,12 +42,18 @@ namespace tooling { /// \brief Specifies the working directory and command of a compilation. struct CompileCommand { CompileCommand() {} - CompileCommand(Twine Directory, std::vector<std::string> CommandLine) - : Directory(Directory.str()), CommandLine(std::move(CommandLine)) {} + CompileCommand(Twine Directory, Twine Filename, + std::vector<std::string> CommandLine) + : Directory(Directory.str()), + Filename(Filename.str()), + CommandLine(std::move(CommandLine)) {} /// \brief The working directory the command was executed from. std::string Directory; + /// The source file associated with the command. + std::string Filename; + /// \brief The command line that was executed. std::vector<std::string> CommandLine; diff --git a/contrib/llvm/tools/clang/include/clang/Tooling/Core/Lookup.h b/contrib/llvm/tools/clang/include/clang/Tooling/Core/Lookup.h new file mode 100644 index 0000000..bc2b4db --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/Tooling/Core/Lookup.h @@ -0,0 +1,48 @@ +//===--- Lookup.h - Framework for clang refactoring tools --*- 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 helper methods for clang tools performing name lookup. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLING_CORE_LOOKUP_H +#define LLVM_CLANG_TOOLING_CORE_LOOKUP_H + +#include "clang/Basic/LLVM.h" +#include <string> + +namespace clang { + +class DeclContext; +class NamedDecl; +class NestedNameSpecifier; + +namespace tooling { + +/// Emulate a lookup to replace one nested name specifier with another using as +/// few additional namespace qualifications as possible. +/// +/// This does not perform a full C++ lookup so ADL will not work. +/// +/// \param Use The nested name to be replaced. +/// \param UseContext The context in which the nested name is contained. This +/// will be used to minimize namespace qualifications. +/// \param FromDecl The declaration to which the nested name points. +/// \param ReplacementString The replacement nested name. Must be fully +/// qualified including a leading "::". +/// \returns The new name to be inserted in place of the current nested name. +std::string replaceNestedName(const NestedNameSpecifier *Use, + const DeclContext *UseContext, + const NamedDecl *FromDecl, + StringRef ReplacementString); + +} // end namespace tooling +} // end namespace clang + +#endif // LLVM_CLANG_TOOLING_CORE_LOOKUP_H diff --git a/contrib/llvm/tools/clang/include/clang/Tooling/Core/Replacement.h b/contrib/llvm/tools/clang/include/clang/Tooling/Core/Replacement.h index f189e12..37389ac 100644 --- a/contrib/llvm/tools/clang/include/clang/Tooling/Core/Replacement.h +++ b/contrib/llvm/tools/clang/include/clang/Tooling/Core/Replacement.h @@ -220,6 +220,12 @@ bool applyAllReplacements(const std::vector<Replacement> &Replaces, /// replacements cannot be applied, this returns an empty \c string. std::string applyAllReplacements(StringRef Code, 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', +/// replacements must not overlap. +Replacements mergeReplacements(const Replacements &First, + const Replacements &Second); + template <typename Node> Replacement::Replacement(const SourceManager &Sources, const Node &NodeToReplace, StringRef ReplacementText, diff --git a/contrib/llvm/tools/clang/include/clang/Tooling/JSONCompilationDatabase.h b/contrib/llvm/tools/clang/include/clang/Tooling/JSONCompilationDatabase.h index b4edc31..2a13fc1 100644 --- a/contrib/llvm/tools/clang/include/clang/Tooling/JSONCompilationDatabase.h +++ b/contrib/llvm/tools/clang/include/clang/Tooling/JSONCompilationDatabase.h @@ -33,18 +33,26 @@ namespace tooling { /// \brief A JSON based compilation database. /// /// JSON compilation database files must contain a list of JSON objects which -/// provide the command lines in the attributes 'directory', 'command' and -/// 'file': +/// provide the command lines in the attributes 'directory', 'command', +/// 'arguments' and 'file': /// [ /// { "directory": "<working directory of the compile>", /// "command": "<compile command line>", /// "file": "<path to source file>" /// }, +/// { "directory": "<working directory of the compile>", +/// "arguments": ["<raw>", "<command>" "<line>" "<parameters>"], +/// "file": "<path to source file>" +/// }, /// ... /// ] /// Each object entry defines one compile action. The specified file is /// considered to be the main source file for the translation unit. /// +/// 'command' is a full command line that will be unescaped. +/// +/// 'arguments' is a list of command line arguments that will not be unescaped. +/// /// JSON compilation databases can for example be generated in CMake projects /// by setting the flag -DCMAKE_EXPORT_COMPILE_COMMANDS. class JSONCompilationDatabase : public CompilationDatabase { @@ -91,17 +99,26 @@ private: /// failed. bool parse(std::string &ErrorMessage); - // Tuple (directory, commandline) where 'commandline' pointing to the - // corresponding nodes in the YAML stream. - typedef std::pair<llvm::yaml::ScalarNode*, - llvm::yaml::ScalarNode*> CompileCommandRef; + // Tuple (directory, filename, commandline) where 'commandline' points to the + // corresponding scalar nodes in the YAML stream. + // If the command line contains a single argument, it is a shell-escaped + // command line. + // Otherwise, each entry in the command line vector is a literal + // argument to the compiler. + typedef std::tuple<llvm::yaml::ScalarNode *, + llvm::yaml::ScalarNode *, + std::vector<llvm::yaml::ScalarNode *>> CompileCommandRef; /// \brief Converts the given array of CompileCommandRefs to CompileCommands. void getCommands(ArrayRef<CompileCommandRef> CommandsRef, std::vector<CompileCommand> &Commands) const; // Maps file paths to the compile command lines for that file. - llvm::StringMap< std::vector<CompileCommandRef> > IndexByFile; + llvm::StringMap<std::vector<CompileCommandRef>> IndexByFile; + + /// All the compile commands in the order that they were provided in the + /// JSON stream. + std::vector<CompileCommandRef> AllCommands; FileMatchTrie MatchTrie; diff --git a/contrib/llvm/tools/clang/include/clang/Tooling/Tooling.h b/contrib/llvm/tools/clang/include/clang/Tooling/Tooling.h index 92e9065..b7a9b25 100644 --- a/contrib/llvm/tools/clang/include/clang/Tooling/Tooling.h +++ b/contrib/llvm/tools/clang/include/clang/Tooling/Tooling.h @@ -243,6 +243,7 @@ public: /// /// \param FilePath The path at which the content will be mapped. /// \param Content A null terminated buffer of the file's content. + // FIXME: remove this when all users have migrated! void mapVirtualFile(StringRef FilePath, StringRef Content); /// \brief Run the clang invocation. @@ -331,9 +332,12 @@ class ClangTool { std::vector<std::string> SourcePaths; std::shared_ptr<PCHContainerOperations> PCHContainerOps; + llvm::IntrusiveRefCntPtr<vfs::OverlayFileSystem> OverlayFileSystem; + llvm::IntrusiveRefCntPtr<vfs::InMemoryFileSystem> InMemoryFileSystem; llvm::IntrusiveRefCntPtr<FileManager> Files; // Contains a list of pairs (<file name>, <file content>). std::vector< std::pair<StringRef, StringRef> > MappedFileContents; + llvm::StringSet<> SeenWorkingDirectories; ArgumentsAdjuster ArgsAdjuster; @@ -417,6 +421,29 @@ inline std::unique_ptr<FrontendActionFactory> newFrontendActionFactory( /// \param File Either an absolute or relative path. std::string getAbsolutePath(StringRef File); +/// \brief Changes CommandLine to contain implicit flags that would have been +/// defined had the compiler driver been invoked through the path InvokedAs. +/// +/// For example, when called with \c InvokedAs set to `i686-linux-android-g++`, +/// the arguments '-target', 'i686-linux-android`, `--driver-mode=g++` will +/// be inserted after the first argument in \c CommandLine. +/// +/// This function will not add new `-target` or `--driver-mode` flags if they +/// are already present in `CommandLine` (even if they have different settings +/// than would have been inserted). +/// +/// \pre `llvm::InitializeAllTargets()` has been called. +/// +/// \param CommandLine the command line used to invoke the compiler driver or +/// Clang tool, including the path to the executable as \c CommandLine[0]. +/// \param InvokedAs the path to the driver used to infer implicit flags. +/// +/// \note This will not set \c CommandLine[0] to \c InvokedAs. The tooling +/// infrastructure expects that CommandLine[0] is a tool path relative to which +/// the builtin headers can be found. +void addTargetAndModeForProgramName(std::vector<std::string> &CommandLine, + StringRef InvokedAs); + /// \brief Creates a \c CompilerInvocation. clang::CompilerInvocation *newInvocation( clang::DiagnosticsEngine *Diagnostics, diff --git a/contrib/llvm/tools/clang/include/clang/module.modulemap b/contrib/llvm/tools/clang/include/clang/module.modulemap index 6b77adb..28b6d16 100644 --- a/contrib/llvm/tools/clang/include/clang/module.modulemap +++ b/contrib/llvm/tools/clang/include/clang/module.modulemap @@ -25,6 +25,7 @@ module Clang_Basic { umbrella "Basic" textual header "Basic/BuiltinsAArch64.def" + textual header "Basic/BuiltinsAMDGPU.def" textual header "Basic/BuiltinsARM.def" textual header "Basic/Builtins.def" textual header "Basic/BuiltinsHexagon.def" @@ -33,8 +34,8 @@ module Clang_Basic { textual header "Basic/BuiltinsNEON.def" textual header "Basic/BuiltinsNVPTX.def" textual header "Basic/BuiltinsPPC.def" - textual header "Basic/BuiltinsR600.def" textual header "Basic/BuiltinsSystemZ.def" + textual header "Basic/BuiltinsWebAssembly.def" textual header "Basic/BuiltinsX86.def" textual header "Basic/BuiltinsXCore.def" textual header "Basic/DiagnosticOptions.def" @@ -89,6 +90,9 @@ module Clang_Frontend { textual header "Frontend/LangStandards.def" module * { export * } + + // FIXME: This violates layers. + exclude header "Frontend/PCHContainerOperations.h" } module Clang_FrontendTool { requires cplusplus umbrella "FrontendTool" module * { export * } } |