diff options
Diffstat (limited to 'clang/include')
286 files changed, 23450 insertions, 10847 deletions
diff --git a/clang/include/clang-c/BuildSystem.h b/clang/include/clang-c/BuildSystem.h index 4e9f6dee0279..296e61247cef 100644 --- a/clang/include/clang-c/BuildSystem.h +++ b/clang/include/clang-c/BuildSystem.h @@ -117,7 +117,7 @@ clang_ModuleMapDescriptor_setFrameworkModuleName(CXModuleMapDescriptor, const char *name); /** - * Sets the umbrealla header name that the module.map describes. + * Sets the umbrella header name that the module.map describes. * \returns 0 for success, non-zero to indicate an error. */ CINDEX_LINKAGE enum CXErrorCode diff --git a/clang/include/clang-c/Index.h b/clang/include/clang-c/Index.h index b653995ebbd0..5fa728d6d66c 100644 --- a/clang/include/clang-c/Index.h +++ b/clang/include/clang-c/Index.h @@ -33,24 +33,19 @@ * compatible, thus CINDEX_VERSION_MAJOR is expected to remain stable. */ #define CINDEX_VERSION_MAJOR 0 -#define CINDEX_VERSION_MINOR 59 +#define CINDEX_VERSION_MINOR 60 -#define CINDEX_VERSION_ENCODE(major, minor) ( \ - ((major) * 10000) \ - + ((minor) * 1)) +#define CINDEX_VERSION_ENCODE(major, minor) (((major)*10000) + ((minor)*1)) -#define CINDEX_VERSION CINDEX_VERSION_ENCODE( \ - CINDEX_VERSION_MAJOR, \ - CINDEX_VERSION_MINOR ) +#define CINDEX_VERSION \ + CINDEX_VERSION_ENCODE(CINDEX_VERSION_MAJOR, CINDEX_VERSION_MINOR) -#define CINDEX_VERSION_STRINGIZE_(major, minor) \ - #major"."#minor -#define CINDEX_VERSION_STRINGIZE(major, minor) \ - CINDEX_VERSION_STRINGIZE_(major, minor) +#define CINDEX_VERSION_STRINGIZE_(major, minor) #major "." #minor +#define CINDEX_VERSION_STRINGIZE(major, minor) \ + CINDEX_VERSION_STRINGIZE_(major, minor) -#define CINDEX_VERSION_STRING CINDEX_VERSION_STRINGIZE( \ - CINDEX_VERSION_MAJOR, \ - CINDEX_VERSION_MINOR) +#define CINDEX_VERSION_STRING \ + CINDEX_VERSION_STRINGIZE(CINDEX_VERSION_MAJOR, CINDEX_VERSION_MINOR) LLVM_CLANG_C_EXTERN_C_BEGIN @@ -382,7 +377,7 @@ typedef struct { * \param outID stores the returned CXFileUniqueID. * \returns If there was a failure getting the unique ID, returns non-zero, * otherwise returns 0. -*/ + */ CINDEX_LINKAGE int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID); /** @@ -390,8 +385,8 @@ CINDEX_LINKAGE int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID); * multiple inclusions, either with the conventional * \#ifndef/\#define/\#endif macro guards or with \#pragma once. */ -CINDEX_LINKAGE unsigned -clang_isFileMultipleIncludeGuarded(CXTranslationUnit tu, CXFile file); +CINDEX_LINKAGE unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit tu, + CXFile file); /** * Retrieve a file handle within the given translation unit. @@ -496,8 +491,7 @@ CINDEX_LINKAGE unsigned clang_equalLocations(CXSourceLocation loc1, * in a particular translation unit. */ CINDEX_LINKAGE CXSourceLocation clang_getLocation(CXTranslationUnit tu, - CXFile file, - unsigned line, + CXFile file, unsigned line, unsigned column); /** * Retrieves the source location associated with a given character offset @@ -566,8 +560,7 @@ CINDEX_LINKAGE int clang_Range_isNull(CXSourceRange range); * buffer to which the given source location points. */ CINDEX_LINKAGE void clang_getExpansionLocation(CXSourceLocation location, - CXFile *file, - unsigned *line, + CXFile *file, unsigned *line, unsigned *column, unsigned *offset); @@ -613,8 +606,7 @@ CINDEX_LINKAGE void clang_getExpansionLocation(CXSourceLocation location, */ CINDEX_LINKAGE void clang_getPresumedLocation(CXSourceLocation location, CXString *filename, - unsigned *line, - unsigned *column); + unsigned *line, unsigned *column); /** * Legacy API to retrieve the file, line, column, and offset represented @@ -625,8 +617,7 @@ CINDEX_LINKAGE void clang_getPresumedLocation(CXSourceLocation location, * details. */ CINDEX_LINKAGE void clang_getInstantiationLocation(CXSourceLocation location, - CXFile *file, - unsigned *line, + CXFile *file, unsigned *line, unsigned *column, unsigned *offset); @@ -653,8 +644,7 @@ CINDEX_LINKAGE void clang_getInstantiationLocation(CXSourceLocation location, * buffer to which the given source location points. */ CINDEX_LINKAGE void clang_getSpellingLocation(CXSourceLocation location, - CXFile *file, - unsigned *line, + CXFile *file, unsigned *line, unsigned *column, unsigned *offset); @@ -682,10 +672,8 @@ CINDEX_LINKAGE void clang_getSpellingLocation(CXSourceLocation location, * buffer to which the given source location points. */ CINDEX_LINKAGE void clang_getFileLocation(CXSourceLocation location, - CXFile *file, - unsigned *line, - unsigned *column, - unsigned *offset); + CXFile *file, unsigned *line, + unsigned *column, unsigned *offset); /** * Retrieve a source location representing the first character within a @@ -727,7 +715,8 @@ CINDEX_LINKAGE CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit tu, * The preprocessor will skip lines when they are surrounded by an * if/ifdef/ifndef directive whose condition does not evaluate to true. */ -CINDEX_LINKAGE CXSourceRangeList *clang_getAllSkippedRanges(CXTranslationUnit tu); +CINDEX_LINKAGE CXSourceRangeList * +clang_getAllSkippedRanges(CXTranslationUnit tu); /** * Destroy the given \c CXSourceRangeList. @@ -758,7 +747,7 @@ enum CXDiagnosticSeverity { * This diagnostic is a note that should be attached to the * previous (non-note) diagnostic. */ - CXDiagnostic_Note = 1, + CXDiagnostic_Note = 1, /** * This diagnostic indicates suspicious code that may not be @@ -769,14 +758,14 @@ enum CXDiagnosticSeverity { /** * This diagnostic indicates that the code is ill-formed. */ - CXDiagnostic_Error = 3, + CXDiagnostic_Error = 3, /** * This diagnostic indicates that the code is ill-formed such * that future parser recovery is unlikely to produce useful * results. */ - CXDiagnostic_Fatal = 4 + CXDiagnostic_Fatal = 4 }; /** @@ -849,9 +838,8 @@ enum CXLoadDiag_Error { * \returns A loaded CXDiagnosticSet if successful, and NULL otherwise. These * diagnostics should be released using clang_disposeDiagnosticSet(). */ -CINDEX_LINKAGE CXDiagnosticSet clang_loadDiagnostics(const char *file, - enum CXLoadDiag_Error *error, - CXString *errorString); +CINDEX_LINKAGE CXDiagnosticSet clang_loadDiagnostics( + const char *file, enum CXLoadDiag_Error *error, CXString *errorString); /** * Release a CXDiagnosticSet and all of its contained diagnostics. @@ -891,7 +879,7 @@ CINDEX_LINKAGE CXDiagnostic clang_getDiagnostic(CXTranslationUnit Unit, * \param Unit the translation unit to query. */ CINDEX_LINKAGE CXDiagnosticSet - clang_getDiagnosticSetFromTU(CXTranslationUnit Unit); +clang_getDiagnosticSetFromTU(CXTranslationUnit Unit); /** * Destroy a diagnostic. @@ -997,7 +985,7 @@ CINDEX_LINKAGE unsigned clang_defaultDiagnosticDisplayOptions(void); * Determine the severity of the given diagnostic. */ CINDEX_LINKAGE enum CXDiagnosticSeverity -clang_getDiagnosticSeverity(CXDiagnostic); + clang_getDiagnosticSeverity(CXDiagnostic); /** * Retrieve the source location of the given diagnostic. @@ -1049,8 +1037,8 @@ CINDEX_LINKAGE unsigned clang_getDiagnosticCategory(CXDiagnostic); * * \returns The name of the given diagnostic category. */ -CINDEX_DEPRECATED CINDEX_LINKAGE -CXString clang_getDiagnosticCategoryName(unsigned Category); +CINDEX_DEPRECATED CINDEX_LINKAGE CXString +clang_getDiagnosticCategoryName(unsigned Category); /** * Retrieve the diagnostic category text for a given diagnostic. @@ -1112,9 +1100,8 @@ CINDEX_LINKAGE unsigned clang_getDiagnosticNumFixIts(CXDiagnostic Diagnostic); * \returns A string containing text that should be replace the source * code indicated by the \c ReplacementRange. */ -CINDEX_LINKAGE CXString clang_getDiagnosticFixIt(CXDiagnostic Diagnostic, - unsigned FixIt, - CXSourceRange *ReplacementRange); +CINDEX_LINKAGE CXString clang_getDiagnosticFixIt( + CXDiagnostic Diagnostic, unsigned FixIt, CXSourceRange *ReplacementRange); /** * @} @@ -1177,12 +1164,9 @@ clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit); * guarantee their validity until the call to this function returns. */ CINDEX_LINKAGE CXTranslationUnit clang_createTranslationUnitFromSourceFile( - CXIndex CIdx, - const char *source_filename, - int num_clang_command_line_args, - const char * const *clang_command_line_args, - unsigned num_unsaved_files, - struct CXUnsavedFile *unsaved_files); + CXIndex CIdx, const char *source_filename, int num_clang_command_line_args, + const char *const *clang_command_line_args, unsigned num_unsaved_files, + struct CXUnsavedFile *unsaved_files); /** * Same as \c clang_createTranslationUnit2, but returns @@ -1190,9 +1174,8 @@ CINDEX_LINKAGE CXTranslationUnit clang_createTranslationUnitFromSourceFile( * routine returns a \c NULL \c CXTranslationUnit, without further detailed * error codes. */ -CINDEX_LINKAGE CXTranslationUnit clang_createTranslationUnit( - CXIndex CIdx, - const char *ast_filename); +CINDEX_LINKAGE CXTranslationUnit +clang_createTranslationUnit(CXIndex CIdx, const char *ast_filename); /** * Create a translation unit from an AST file (\c -emit-ast). @@ -1202,10 +1185,9 @@ CINDEX_LINKAGE CXTranslationUnit clang_createTranslationUnit( * * \returns Zero on success, otherwise returns an error code. */ -CINDEX_LINKAGE enum CXErrorCode clang_createTranslationUnit2( - CXIndex CIdx, - const char *ast_filename, - CXTranslationUnit *out_TU); +CINDEX_LINKAGE enum CXErrorCode +clang_createTranslationUnit2(CXIndex CIdx, const char *ast_filename, + CXTranslationUnit *out_TU); /** * Flags that control the creation of translation units. @@ -1383,14 +1365,11 @@ CINDEX_LINKAGE unsigned clang_defaultEditingTranslationUnitOptions(void); * routine returns a \c NULL \c CXTranslationUnit, without further detailed * error codes. */ -CINDEX_LINKAGE CXTranslationUnit -clang_parseTranslationUnit(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); +CINDEX_LINKAGE CXTranslationUnit clang_parseTranslationUnit( + 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); /** * Parse the given source file and the translation unit corresponding @@ -1436,15 +1415,11 @@ clang_parseTranslationUnit(CXIndex CIdx, * * \returns Zero on success, otherwise returns an error code. */ -CINDEX_LINKAGE enum CXErrorCode -clang_parseTranslationUnit2(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); +CINDEX_LINKAGE enum CXErrorCode clang_parseTranslationUnit2( + 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); /** * Same as clang_parseTranslationUnit2 but requires a full command line @@ -1623,14 +1598,14 @@ CINDEX_LINKAGE unsigned clang_defaultReparseOptions(CXTranslationUnit TU); * \c clang_disposeTranslationUnit(TU). The error codes returned by this * routine are described by the \c CXErrorCode enum. */ -CINDEX_LINKAGE int clang_reparseTranslationUnit(CXTranslationUnit TU, - unsigned num_unsaved_files, - struct CXUnsavedFile *unsaved_files, - unsigned options); +CINDEX_LINKAGE int +clang_reparseTranslationUnit(CXTranslationUnit TU, unsigned num_unsaved_files, + struct CXUnsavedFile *unsaved_files, + unsigned options); /** - * Categorizes how memory is being used by a translation unit. - */ + * Categorizes how memory is being used by a translation unit. + */ enum CXTUResourceUsageKind { CXTUResourceUsage_AST = 1, CXTUResourceUsage_Identifiers = 2, @@ -1648,16 +1623,16 @@ enum CXTUResourceUsageKind { CXTUResourceUsage_Preprocessor_HeaderSearch = 14, CXTUResourceUsage_MEMORY_IN_BYTES_BEGIN = CXTUResourceUsage_AST, CXTUResourceUsage_MEMORY_IN_BYTES_END = - CXTUResourceUsage_Preprocessor_HeaderSearch, + CXTUResourceUsage_Preprocessor_HeaderSearch, CXTUResourceUsage_First = CXTUResourceUsage_AST, CXTUResourceUsage_Last = CXTUResourceUsage_Preprocessor_HeaderSearch }; /** - * Returns the human-readable null-terminated C string that represents - * the name of the memory category. This string should never be freed. - */ + * Returns the human-readable null-terminated C string that represents + * the name of the memory category. This string should never be freed. + */ CINDEX_LINKAGE const char *clang_getTUResourceUsageName(enum CXTUResourceUsageKind kind); @@ -1670,8 +1645,8 @@ typedef struct CXTUResourceUsageEntry { } CXTUResourceUsageEntry; /** - * The memory usage of a CXTranslationUnit, broken into categories. - */ + * The memory usage of a CXTranslationUnit, broken into categories. + */ typedef struct CXTUResourceUsage { /* Private data member, used for queries. */ void *data; @@ -1686,10 +1661,11 @@ typedef struct CXTUResourceUsage { } CXTUResourceUsage; /** - * Return the memory usage of a translation unit. This object - * should be released with clang_disposeCXTUResourceUsage(). - */ -CINDEX_LINKAGE CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU); + * Return the memory usage of a translation unit. This object + * should be released with clang_disposeCXTUResourceUsage(). + */ +CINDEX_LINKAGE CXTUResourceUsage +clang_getCXTUResourceUsage(CXTranslationUnit TU); CINDEX_LINKAGE void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage); @@ -1704,24 +1680,21 @@ clang_getTranslationUnitTargetInfo(CXTranslationUnit CTUnit); /** * Destroy the CXTargetInfo object. */ -CINDEX_LINKAGE void -clang_TargetInfo_dispose(CXTargetInfo Info); +CINDEX_LINKAGE void clang_TargetInfo_dispose(CXTargetInfo Info); /** * Get the normalized target triple as a string. * * Returns the empty string in case of any error. */ -CINDEX_LINKAGE CXString -clang_TargetInfo_getTriple(CXTargetInfo Info); +CINDEX_LINKAGE CXString clang_TargetInfo_getTriple(CXTargetInfo Info); /** * Get the pointer width of the target in bits. * * Returns -1 in case of error. */ -CINDEX_LINKAGE int -clang_TargetInfo_getPointerWidth(CXTargetInfo Info); +CINDEX_LINKAGE int clang_TargetInfo_getPointerWidth(CXTargetInfo Info); /** * @} @@ -1741,95 +1714,95 @@ enum CXCursorKind { * spelling, find their definitions, etc. However, the specific kind * of the declaration is not reported. */ - CXCursor_UnexposedDecl = 1, + CXCursor_UnexposedDecl = 1, /** A C or C++ struct. */ - CXCursor_StructDecl = 2, + CXCursor_StructDecl = 2, /** A C or C++ union. */ - CXCursor_UnionDecl = 3, + CXCursor_UnionDecl = 3, /** A C++ class. */ - CXCursor_ClassDecl = 4, + CXCursor_ClassDecl = 4, /** An enumeration. */ - CXCursor_EnumDecl = 5, + CXCursor_EnumDecl = 5, /** * A field (in C) or non-static data member (in C++) in a * struct, union, or C++ class. */ - CXCursor_FieldDecl = 6, + CXCursor_FieldDecl = 6, /** An enumerator constant. */ - CXCursor_EnumConstantDecl = 7, + CXCursor_EnumConstantDecl = 7, /** A function. */ - CXCursor_FunctionDecl = 8, + CXCursor_FunctionDecl = 8, /** A variable. */ - CXCursor_VarDecl = 9, + CXCursor_VarDecl = 9, /** A function or method parameter. */ - CXCursor_ParmDecl = 10, + CXCursor_ParmDecl = 10, /** An Objective-C \@interface. */ - CXCursor_ObjCInterfaceDecl = 11, + CXCursor_ObjCInterfaceDecl = 11, /** An Objective-C \@interface for a category. */ - CXCursor_ObjCCategoryDecl = 12, + CXCursor_ObjCCategoryDecl = 12, /** An Objective-C \@protocol declaration. */ - CXCursor_ObjCProtocolDecl = 13, + CXCursor_ObjCProtocolDecl = 13, /** An Objective-C \@property declaration. */ - CXCursor_ObjCPropertyDecl = 14, + CXCursor_ObjCPropertyDecl = 14, /** An Objective-C instance variable. */ - CXCursor_ObjCIvarDecl = 15, + CXCursor_ObjCIvarDecl = 15, /** An Objective-C instance method. */ - CXCursor_ObjCInstanceMethodDecl = 16, + CXCursor_ObjCInstanceMethodDecl = 16, /** An Objective-C class method. */ - CXCursor_ObjCClassMethodDecl = 17, + CXCursor_ObjCClassMethodDecl = 17, /** An Objective-C \@implementation. */ - CXCursor_ObjCImplementationDecl = 18, + CXCursor_ObjCImplementationDecl = 18, /** An Objective-C \@implementation for a category. */ - CXCursor_ObjCCategoryImplDecl = 19, + CXCursor_ObjCCategoryImplDecl = 19, /** A typedef. */ - CXCursor_TypedefDecl = 20, + CXCursor_TypedefDecl = 20, /** A C++ class method. */ - CXCursor_CXXMethod = 21, + CXCursor_CXXMethod = 21, /** A C++ namespace. */ - CXCursor_Namespace = 22, + CXCursor_Namespace = 22, /** A linkage specification, e.g. 'extern "C"'. */ - CXCursor_LinkageSpec = 23, + CXCursor_LinkageSpec = 23, /** A C++ constructor. */ - CXCursor_Constructor = 24, + CXCursor_Constructor = 24, /** A C++ destructor. */ - CXCursor_Destructor = 25, + CXCursor_Destructor = 25, /** A C++ conversion function. */ - CXCursor_ConversionFunction = 26, + CXCursor_ConversionFunction = 26, /** A C++ template type parameter. */ - CXCursor_TemplateTypeParameter = 27, + CXCursor_TemplateTypeParameter = 27, /** A C++ non-type template parameter. */ - CXCursor_NonTypeTemplateParameter = 28, + CXCursor_NonTypeTemplateParameter = 28, /** A C++ template template parameter. */ - CXCursor_TemplateTemplateParameter = 29, + CXCursor_TemplateTemplateParameter = 29, /** A C++ function template. */ - CXCursor_FunctionTemplate = 30, + CXCursor_FunctionTemplate = 30, /** A C++ class template. */ - CXCursor_ClassTemplate = 31, + CXCursor_ClassTemplate = 31, /** A C++ class template partial specialization. */ CXCursor_ClassTemplatePartialSpecialization = 32, /** A C++ namespace alias declaration. */ - CXCursor_NamespaceAlias = 33, + CXCursor_NamespaceAlias = 33, /** A C++ using directive. */ - CXCursor_UsingDirective = 34, + CXCursor_UsingDirective = 34, /** A C++ using declaration. */ - CXCursor_UsingDeclaration = 35, + CXCursor_UsingDeclaration = 35, /** A C++ alias declaration */ - CXCursor_TypeAliasDecl = 36, + CXCursor_TypeAliasDecl = 36, /** An Objective-C \@synthesize definition. */ - CXCursor_ObjCSynthesizeDecl = 37, + CXCursor_ObjCSynthesizeDecl = 37, /** An Objective-C \@dynamic definition. */ - CXCursor_ObjCDynamicDecl = 38, + CXCursor_ObjCDynamicDecl = 38, /** An access specifier. */ - CXCursor_CXXAccessSpecifier = 39, + CXCursor_CXXAccessSpecifier = 39, - CXCursor_FirstDecl = CXCursor_UnexposedDecl, - CXCursor_LastDecl = CXCursor_CXXAccessSpecifier, + CXCursor_FirstDecl = CXCursor_UnexposedDecl, + CXCursor_LastDecl = CXCursor_CXXAccessSpecifier, /* References */ - CXCursor_FirstRef = 40, /* Decl references */ - CXCursor_ObjCSuperClassRef = 40, - CXCursor_ObjCProtocolRef = 41, - CXCursor_ObjCClassRef = 42, + CXCursor_FirstRef = 40, /* Decl references */ + CXCursor_ObjCSuperClassRef = 40, + CXCursor_ObjCProtocolRef = 41, + CXCursor_ObjCClassRef = 42, /** * A reference to a type declaration. * @@ -1845,22 +1818,22 @@ enum CXCursorKind { * while the type of the variable "size" is referenced. The cursor * referenced by the type of size is the typedef for size_type. */ - CXCursor_TypeRef = 43, - CXCursor_CXXBaseSpecifier = 44, + CXCursor_TypeRef = 43, + CXCursor_CXXBaseSpecifier = 44, /** * A reference to a class template, function template, template * template parameter, or class template partial specialization. */ - CXCursor_TemplateRef = 45, + CXCursor_TemplateRef = 45, /** * A reference to a namespace or namespace alias. */ - CXCursor_NamespaceRef = 46, + CXCursor_NamespaceRef = 46, /** * A reference to a member of a struct, union, or class that occurs in * some non-expression context, e.g., a designated initializer. */ - CXCursor_MemberRef = 47, + CXCursor_MemberRef = 47, /** * A reference to a labeled statement. * @@ -1876,7 +1849,7 @@ enum CXCursorKind { * * A label reference cursor refers to a label statement. */ - CXCursor_LabelRef = 48, + CXCursor_LabelRef = 48, /** * A reference to a set of overloaded functions or function templates @@ -1914,26 +1887,26 @@ enum CXCursorKind { * \c clang_getOverloadedDecl() can be used to retrieve the definitions * referenced by this cursor. */ - CXCursor_OverloadedDeclRef = 49, + CXCursor_OverloadedDeclRef = 49, /** * A reference to a variable that occurs in some non-expression * context, e.g., a C++ lambda capture list. */ - CXCursor_VariableRef = 50, + CXCursor_VariableRef = 50, - CXCursor_LastRef = CXCursor_VariableRef, + CXCursor_LastRef = CXCursor_VariableRef, /* Error conditions */ - CXCursor_FirstInvalid = 70, - CXCursor_InvalidFile = 70, - CXCursor_NoDeclFound = 71, - CXCursor_NotImplemented = 72, - CXCursor_InvalidCode = 73, - CXCursor_LastInvalid = CXCursor_InvalidCode, + CXCursor_FirstInvalid = 70, + CXCursor_InvalidFile = 70, + CXCursor_NoDeclFound = 71, + CXCursor_NotImplemented = 72, + CXCursor_InvalidCode = 73, + CXCursor_LastInvalid = CXCursor_InvalidCode, /* Expressions */ - CXCursor_FirstExpr = 100, + CXCursor_FirstExpr = 100, /** * An expression whose specific kind is not exposed via this @@ -1944,104 +1917,104 @@ enum CXCursorKind { * spelling, children, etc. However, the specific kind of the * expression is not reported. */ - CXCursor_UnexposedExpr = 100, + CXCursor_UnexposedExpr = 100, /** * An expression that refers to some value declaration, such * as a function, variable, or enumerator. */ - CXCursor_DeclRefExpr = 101, + CXCursor_DeclRefExpr = 101, /** * An expression that refers to a member of a struct, union, * class, Objective-C class, etc. */ - CXCursor_MemberRefExpr = 102, + CXCursor_MemberRefExpr = 102, /** An expression that calls a function. */ - CXCursor_CallExpr = 103, + CXCursor_CallExpr = 103, /** An expression that sends a message to an Objective-C object or class. */ - CXCursor_ObjCMessageExpr = 104, + CXCursor_ObjCMessageExpr = 104, /** An expression that represents a block literal. */ - CXCursor_BlockExpr = 105, + CXCursor_BlockExpr = 105, /** An integer literal. */ - CXCursor_IntegerLiteral = 106, + CXCursor_IntegerLiteral = 106, /** A floating point number literal. */ - CXCursor_FloatingLiteral = 107, + CXCursor_FloatingLiteral = 107, /** An imaginary number literal. */ - CXCursor_ImaginaryLiteral = 108, + CXCursor_ImaginaryLiteral = 108, /** A string literal. */ - CXCursor_StringLiteral = 109, + CXCursor_StringLiteral = 109, /** A character literal. */ - CXCursor_CharacterLiteral = 110, + CXCursor_CharacterLiteral = 110, /** A parenthesized expression, e.g. "(1)". * * This AST node is only formed if full location information is requested. */ - CXCursor_ParenExpr = 111, + CXCursor_ParenExpr = 111, /** This represents the unary-expression's (except sizeof and * alignof). */ - CXCursor_UnaryOperator = 112, + CXCursor_UnaryOperator = 112, /** [C99 6.5.2.1] Array Subscripting. */ - CXCursor_ArraySubscriptExpr = 113, + CXCursor_ArraySubscriptExpr = 113, /** A builtin binary operation expression such as "x + y" or * "x <= y". */ - CXCursor_BinaryOperator = 114, + CXCursor_BinaryOperator = 114, /** Compound assignment such as "+=". */ - CXCursor_CompoundAssignOperator = 115, + CXCursor_CompoundAssignOperator = 115, /** The ?: ternary operator. */ - CXCursor_ConditionalOperator = 116, + CXCursor_ConditionalOperator = 116, /** 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: (int)f. */ - CXCursor_CStyleCastExpr = 117, + CXCursor_CStyleCastExpr = 117, /** [C99 6.5.2.5] */ - CXCursor_CompoundLiteralExpr = 118, + CXCursor_CompoundLiteralExpr = 118, /** Describes an C or C++ initializer list. */ - CXCursor_InitListExpr = 119, + CXCursor_InitListExpr = 119, /** The GNU address of label extension, representing &&label. */ - CXCursor_AddrLabelExpr = 120, + CXCursor_AddrLabelExpr = 120, /** This is the GNU Statement Expression extension: ({int X=4; X;}) */ - CXCursor_StmtExpr = 121, + CXCursor_StmtExpr = 121, /** Represents a C11 generic selection. */ - CXCursor_GenericSelectionExpr = 122, + CXCursor_GenericSelectionExpr = 122, /** Implements the GNU __null extension, which is a name for a null * pointer constant that has integral type (e.g., int or long) and is the same @@ -2051,23 +2024,23 @@ enum CXCursorKind { * NULL as __null in C++ rather than using 0 (which is an integer that may not * match the size of a pointer). */ - CXCursor_GNUNullExpr = 123, + CXCursor_GNUNullExpr = 123, /** C++'s static_cast<> expression. */ - CXCursor_CXXStaticCastExpr = 124, + CXCursor_CXXStaticCastExpr = 124, /** C++'s dynamic_cast<> expression. */ - CXCursor_CXXDynamicCastExpr = 125, + CXCursor_CXXDynamicCastExpr = 125, /** C++'s reinterpret_cast<> expression. */ - CXCursor_CXXReinterpretCastExpr = 126, + CXCursor_CXXReinterpretCastExpr = 126, /** C++'s const_cast<> expression. */ - CXCursor_CXXConstCastExpr = 127, + CXCursor_CXXConstCastExpr = 127, /** Represents an explicit C++ type conversion that uses "functional" * notion (C++ [expr.type.conv]). @@ -2077,60 +2050,64 @@ enum CXCursorKind { * x = int(0.5); * \endcode */ - CXCursor_CXXFunctionalCastExpr = 128, + CXCursor_CXXFunctionalCastExpr = 128, + + /** OpenCL's addrspace_cast<> expression. + */ + CXCursor_CXXAddrspaceCastExpr = 129, /** A C++ typeid expression (C++ [expr.typeid]). */ - CXCursor_CXXTypeidExpr = 129, + CXCursor_CXXTypeidExpr = 130, /** [C++ 2.13.5] C++ Boolean Literal. */ - CXCursor_CXXBoolLiteralExpr = 130, + CXCursor_CXXBoolLiteralExpr = 131, /** [C++0x 2.14.7] C++ Pointer Literal. */ - CXCursor_CXXNullPtrLiteralExpr = 131, + CXCursor_CXXNullPtrLiteralExpr = 132, /** Represents the "this" expression in C++ */ - CXCursor_CXXThisExpr = 132, + CXCursor_CXXThisExpr = 133, /** [C++ 15] C++ Throw Expression. * * This handles 'throw' and 'throw' assignment-expression. When * assignment-expression isn't present, Op will be null. */ - CXCursor_CXXThrowExpr = 133, + CXCursor_CXXThrowExpr = 134, /** A new expression for memory allocation and constructor calls, e.g: * "new CXXNewExpr(foo)". */ - CXCursor_CXXNewExpr = 134, + CXCursor_CXXNewExpr = 135, /** A delete expression for memory deallocation and destructor calls, * e.g. "delete[] pArray". */ - CXCursor_CXXDeleteExpr = 135, + CXCursor_CXXDeleteExpr = 136, /** A unary expression. (noexcept, sizeof, or other traits) */ - CXCursor_UnaryExpr = 136, + CXCursor_UnaryExpr = 137, /** An Objective-C string literal i.e. @"foo". */ - CXCursor_ObjCStringLiteral = 137, + CXCursor_ObjCStringLiteral = 138, /** An Objective-C \@encode expression. */ - CXCursor_ObjCEncodeExpr = 138, + CXCursor_ObjCEncodeExpr = 139, /** An Objective-C \@selector expression. */ - CXCursor_ObjCSelectorExpr = 139, + CXCursor_ObjCSelectorExpr = 140, /** An Objective-C \@protocol expression. */ - CXCursor_ObjCProtocolExpr = 140, + CXCursor_ObjCProtocolExpr = 141, /** An Objective-C "bridged" cast expression, which casts between * Objective-C pointers and C pointers, transferring ownership in the process. @@ -2139,7 +2116,7 @@ enum CXCursorKind { * NSString *str = (__bridge_transfer NSString *)CFCreateString(); * \endcode */ - CXCursor_ObjCBridgedCastExpr = 141, + CXCursor_ObjCBridgedCastExpr = 142, /** Represents a C++0x pack expansion that produces a sequence of * expressions. @@ -2154,7 +2131,7 @@ enum CXCursorKind { * } * \endcode */ - CXCursor_PackExpansionExpr = 142, + CXCursor_PackExpansionExpr = 143, /** Represents an expression that computes the length of a parameter * pack. @@ -2166,7 +2143,7 @@ enum CXCursorKind { * }; * \endcode */ - CXCursor_SizeOfPackExpr = 143, + CXCursor_SizeOfPackExpr = 144, /* Represents a C++ lambda expression that produces a local function * object. @@ -2180,33 +2157,42 @@ enum CXCursorKind { * } * \endcode */ - CXCursor_LambdaExpr = 144, + CXCursor_LambdaExpr = 145, /** Objective-c Boolean Literal. */ - CXCursor_ObjCBoolLiteralExpr = 145, + CXCursor_ObjCBoolLiteralExpr = 146, /** Represents the "self" expression in an Objective-C method. */ - CXCursor_ObjCSelfExpr = 146, + CXCursor_ObjCSelfExpr = 147, - /** OpenMP 4.0 [2.4, Array Section]. + /** OpenMP 5.0 [2.1.5, Array Section]. */ - CXCursor_OMPArraySectionExpr = 147, + CXCursor_OMPArraySectionExpr = 148, /** Represents an @available(...) check. */ - CXCursor_ObjCAvailabilityCheckExpr = 148, + CXCursor_ObjCAvailabilityCheckExpr = 149, /** * Fixed point literal */ - CXCursor_FixedPointLiteral = 149, + CXCursor_FixedPointLiteral = 150, + + /** OpenMP 5.0 [2.1.4, Array Shaping]. + */ + CXCursor_OMPArrayShapingExpr = 151, - CXCursor_LastExpr = CXCursor_FixedPointLiteral, + /** + * OpenMP 5.0 [2.1.6 Iterators] + */ + CXCursor_OMPIteratorExpr = 152, + + CXCursor_LastExpr = CXCursor_OMPIteratorExpr, /* Statements */ - CXCursor_FirstStmt = 200, + CXCursor_FirstStmt = 200, /** * A statement whose specific kind is not exposed via this * interface. @@ -2216,7 +2202,7 @@ enum CXCursorKind { * children, etc. However, the specific kind of the statement is not * reported. */ - CXCursor_UnexposedStmt = 200, + CXCursor_UnexposedStmt = 200, /** A labelled statement in a function. * @@ -2229,226 +2215,226 @@ enum CXCursorKind { * \endcode * */ - CXCursor_LabelStmt = 201, + CXCursor_LabelStmt = 201, /** A group of statements like { stmt stmt }. * * This cursor kind is used to describe compound statements, e.g. function * bodies. */ - CXCursor_CompoundStmt = 202, + CXCursor_CompoundStmt = 202, /** A case statement. */ - CXCursor_CaseStmt = 203, + CXCursor_CaseStmt = 203, /** A default statement. */ - CXCursor_DefaultStmt = 204, + CXCursor_DefaultStmt = 204, /** An if statement */ - CXCursor_IfStmt = 205, + CXCursor_IfStmt = 205, /** A switch statement. */ - CXCursor_SwitchStmt = 206, + CXCursor_SwitchStmt = 206, /** A while statement. */ - CXCursor_WhileStmt = 207, + CXCursor_WhileStmt = 207, /** A do statement. */ - CXCursor_DoStmt = 208, + CXCursor_DoStmt = 208, /** A for statement. */ - CXCursor_ForStmt = 209, + CXCursor_ForStmt = 209, /** A goto statement. */ - CXCursor_GotoStmt = 210, + CXCursor_GotoStmt = 210, /** An indirect goto statement. */ - CXCursor_IndirectGotoStmt = 211, + CXCursor_IndirectGotoStmt = 211, /** A continue statement. */ - CXCursor_ContinueStmt = 212, + CXCursor_ContinueStmt = 212, /** A break statement. */ - CXCursor_BreakStmt = 213, + CXCursor_BreakStmt = 213, /** A return statement. */ - CXCursor_ReturnStmt = 214, + CXCursor_ReturnStmt = 214, /** A GCC inline assembly statement extension. */ - CXCursor_GCCAsmStmt = 215, - CXCursor_AsmStmt = CXCursor_GCCAsmStmt, + CXCursor_GCCAsmStmt = 215, + CXCursor_AsmStmt = CXCursor_GCCAsmStmt, /** Objective-C's overall \@try-\@catch-\@finally statement. */ - CXCursor_ObjCAtTryStmt = 216, + CXCursor_ObjCAtTryStmt = 216, /** Objective-C's \@catch statement. */ - CXCursor_ObjCAtCatchStmt = 217, + CXCursor_ObjCAtCatchStmt = 217, /** Objective-C's \@finally statement. */ - CXCursor_ObjCAtFinallyStmt = 218, + CXCursor_ObjCAtFinallyStmt = 218, /** Objective-C's \@throw statement. */ - CXCursor_ObjCAtThrowStmt = 219, + CXCursor_ObjCAtThrowStmt = 219, /** Objective-C's \@synchronized statement. */ - CXCursor_ObjCAtSynchronizedStmt = 220, + CXCursor_ObjCAtSynchronizedStmt = 220, /** Objective-C's autorelease pool statement. */ - CXCursor_ObjCAutoreleasePoolStmt = 221, + CXCursor_ObjCAutoreleasePoolStmt = 221, /** Objective-C's collection statement. */ - CXCursor_ObjCForCollectionStmt = 222, + CXCursor_ObjCForCollectionStmt = 222, /** C++'s catch statement. */ - CXCursor_CXXCatchStmt = 223, + CXCursor_CXXCatchStmt = 223, /** C++'s try statement. */ - CXCursor_CXXTryStmt = 224, + CXCursor_CXXTryStmt = 224, /** C++'s for (* : *) statement. */ - CXCursor_CXXForRangeStmt = 225, + CXCursor_CXXForRangeStmt = 225, /** Windows Structured Exception Handling's try statement. */ - CXCursor_SEHTryStmt = 226, + CXCursor_SEHTryStmt = 226, /** Windows Structured Exception Handling's except statement. */ - CXCursor_SEHExceptStmt = 227, + CXCursor_SEHExceptStmt = 227, /** Windows Structured Exception Handling's finally statement. */ - CXCursor_SEHFinallyStmt = 228, + CXCursor_SEHFinallyStmt = 228, /** A MS inline assembly statement extension. */ - CXCursor_MSAsmStmt = 229, + CXCursor_MSAsmStmt = 229, /** The null statement ";": C99 6.8.3p3. * * This cursor kind is used to describe the null statement. */ - CXCursor_NullStmt = 230, + CXCursor_NullStmt = 230, /** Adaptor class for mixing declarations with statements and * expressions. */ - CXCursor_DeclStmt = 231, + CXCursor_DeclStmt = 231, /** OpenMP parallel directive. */ - CXCursor_OMPParallelDirective = 232, + CXCursor_OMPParallelDirective = 232, /** OpenMP SIMD directive. */ - CXCursor_OMPSimdDirective = 233, + CXCursor_OMPSimdDirective = 233, /** OpenMP for directive. */ - CXCursor_OMPForDirective = 234, + CXCursor_OMPForDirective = 234, /** OpenMP sections directive. */ - CXCursor_OMPSectionsDirective = 235, + CXCursor_OMPSectionsDirective = 235, /** OpenMP section directive. */ - CXCursor_OMPSectionDirective = 236, + CXCursor_OMPSectionDirective = 236, /** OpenMP single directive. */ - CXCursor_OMPSingleDirective = 237, + CXCursor_OMPSingleDirective = 237, /** OpenMP parallel for directive. */ - CXCursor_OMPParallelForDirective = 238, + CXCursor_OMPParallelForDirective = 238, /** OpenMP parallel sections directive. */ - CXCursor_OMPParallelSectionsDirective = 239, + CXCursor_OMPParallelSectionsDirective = 239, /** OpenMP task directive. */ - CXCursor_OMPTaskDirective = 240, + CXCursor_OMPTaskDirective = 240, /** OpenMP master directive. */ - CXCursor_OMPMasterDirective = 241, + CXCursor_OMPMasterDirective = 241, /** OpenMP critical directive. */ - CXCursor_OMPCriticalDirective = 242, + CXCursor_OMPCriticalDirective = 242, /** OpenMP taskyield directive. */ - CXCursor_OMPTaskyieldDirective = 243, + CXCursor_OMPTaskyieldDirective = 243, /** OpenMP barrier directive. */ - CXCursor_OMPBarrierDirective = 244, + CXCursor_OMPBarrierDirective = 244, /** OpenMP taskwait directive. */ - CXCursor_OMPTaskwaitDirective = 245, + CXCursor_OMPTaskwaitDirective = 245, /** OpenMP flush directive. */ - CXCursor_OMPFlushDirective = 246, + CXCursor_OMPFlushDirective = 246, /** Windows Structured Exception Handling's leave statement. */ - CXCursor_SEHLeaveStmt = 247, + CXCursor_SEHLeaveStmt = 247, /** OpenMP ordered directive. */ - CXCursor_OMPOrderedDirective = 248, + CXCursor_OMPOrderedDirective = 248, /** OpenMP atomic directive. */ - CXCursor_OMPAtomicDirective = 249, + CXCursor_OMPAtomicDirective = 249, /** OpenMP for SIMD directive. */ - CXCursor_OMPForSimdDirective = 250, + CXCursor_OMPForSimdDirective = 250, /** OpenMP parallel for SIMD directive. */ - CXCursor_OMPParallelForSimdDirective = 251, + CXCursor_OMPParallelForSimdDirective = 251, /** OpenMP target directive. */ - CXCursor_OMPTargetDirective = 252, + CXCursor_OMPTargetDirective = 252, /** OpenMP teams directive. */ - CXCursor_OMPTeamsDirective = 253, + CXCursor_OMPTeamsDirective = 253, /** OpenMP taskgroup directive. */ - CXCursor_OMPTaskgroupDirective = 254, + CXCursor_OMPTaskgroupDirective = 254, /** OpenMP cancellation point directive. */ @@ -2456,35 +2442,35 @@ enum CXCursorKind { /** OpenMP cancel directive. */ - CXCursor_OMPCancelDirective = 256, + CXCursor_OMPCancelDirective = 256, /** OpenMP target data directive. */ - CXCursor_OMPTargetDataDirective = 257, + CXCursor_OMPTargetDataDirective = 257, /** OpenMP taskloop directive. */ - CXCursor_OMPTaskLoopDirective = 258, + CXCursor_OMPTaskLoopDirective = 258, /** OpenMP taskloop simd directive. */ - CXCursor_OMPTaskLoopSimdDirective = 259, + CXCursor_OMPTaskLoopSimdDirective = 259, /** OpenMP distribute directive. */ - CXCursor_OMPDistributeDirective = 260, + CXCursor_OMPDistributeDirective = 260, /** OpenMP target enter data directive. */ - CXCursor_OMPTargetEnterDataDirective = 261, + CXCursor_OMPTargetEnterDataDirective = 261, /** OpenMP target exit data directive. */ - CXCursor_OMPTargetExitDataDirective = 262, + CXCursor_OMPTargetExitDataDirective = 262, /** OpenMP target parallel directive. */ - CXCursor_OMPTargetParallelDirective = 263, + CXCursor_OMPTargetParallelDirective = 263, /** OpenMP target parallel for directive. */ @@ -2492,7 +2478,7 @@ enum CXCursorKind { /** OpenMP target update directive. */ - CXCursor_OMPTargetUpdateDirective = 265, + CXCursor_OMPTargetUpdateDirective = 265, /** OpenMP distribute parallel for directive. */ @@ -2564,17 +2550,25 @@ enum CXCursorKind { /** OpenMP master taskloop simd directive. */ - CXCursor_OMPMasterTaskLoopSimdDirective = 283, + CXCursor_OMPMasterTaskLoopSimdDirective = 283, /** OpenMP parallel master taskloop simd directive. */ - CXCursor_OMPParallelMasterTaskLoopSimdDirective = 284, + CXCursor_OMPParallelMasterTaskLoopSimdDirective = 284, /** OpenMP parallel master directive. */ - CXCursor_OMPParallelMasterDirective = 285, + CXCursor_OMPParallelMasterDirective = 285, + + /** OpenMP depobj directive. + */ + CXCursor_OMPDepobjDirective = 286, + + /** OpenMP scan directive. + */ + CXCursor_OMPScanDirective = 287, - CXCursor_LastStmt = CXCursor_OMPParallelMasterDirective, + CXCursor_LastStmt = CXCursor_OMPScanDirective, /** * Cursor that represents the translation unit itself. @@ -2582,89 +2576,89 @@ enum CXCursorKind { * The translation unit cursor exists primarily to act as the root * cursor for traversing the contents of a translation unit. */ - CXCursor_TranslationUnit = 300, + CXCursor_TranslationUnit = 300, /* Attributes */ - CXCursor_FirstAttr = 400, + CXCursor_FirstAttr = 400, /** * An attribute whose specific kind is not exposed via this * interface. */ - CXCursor_UnexposedAttr = 400, - - CXCursor_IBActionAttr = 401, - CXCursor_IBOutletAttr = 402, - CXCursor_IBOutletCollectionAttr = 403, - CXCursor_CXXFinalAttr = 404, - CXCursor_CXXOverrideAttr = 405, - CXCursor_AnnotateAttr = 406, - CXCursor_AsmLabelAttr = 407, - CXCursor_PackedAttr = 408, - CXCursor_PureAttr = 409, - CXCursor_ConstAttr = 410, - CXCursor_NoDuplicateAttr = 411, - CXCursor_CUDAConstantAttr = 412, - CXCursor_CUDADeviceAttr = 413, - CXCursor_CUDAGlobalAttr = 414, - CXCursor_CUDAHostAttr = 415, - CXCursor_CUDASharedAttr = 416, - CXCursor_VisibilityAttr = 417, - CXCursor_DLLExport = 418, - CXCursor_DLLImport = 419, - CXCursor_NSReturnsRetained = 420, - CXCursor_NSReturnsNotRetained = 421, - CXCursor_NSReturnsAutoreleased = 422, - CXCursor_NSConsumesSelf = 423, - CXCursor_NSConsumed = 424, - CXCursor_ObjCException = 425, - CXCursor_ObjCNSObject = 426, - CXCursor_ObjCIndependentClass = 427, - CXCursor_ObjCPreciseLifetime = 428, - CXCursor_ObjCReturnsInnerPointer = 429, - CXCursor_ObjCRequiresSuper = 430, - CXCursor_ObjCRootClass = 431, - CXCursor_ObjCSubclassingRestricted = 432, - CXCursor_ObjCExplicitProtocolImpl = 433, - CXCursor_ObjCDesignatedInitializer = 434, - CXCursor_ObjCRuntimeVisible = 435, - CXCursor_ObjCBoxable = 436, - CXCursor_FlagEnum = 437, - CXCursor_ConvergentAttr = 438, - CXCursor_WarnUnusedAttr = 439, - CXCursor_WarnUnusedResultAttr = 440, - CXCursor_AlignedAttr = 441, - CXCursor_LastAttr = CXCursor_AlignedAttr, + CXCursor_UnexposedAttr = 400, + + CXCursor_IBActionAttr = 401, + CXCursor_IBOutletAttr = 402, + CXCursor_IBOutletCollectionAttr = 403, + CXCursor_CXXFinalAttr = 404, + CXCursor_CXXOverrideAttr = 405, + CXCursor_AnnotateAttr = 406, + CXCursor_AsmLabelAttr = 407, + CXCursor_PackedAttr = 408, + CXCursor_PureAttr = 409, + CXCursor_ConstAttr = 410, + CXCursor_NoDuplicateAttr = 411, + CXCursor_CUDAConstantAttr = 412, + CXCursor_CUDADeviceAttr = 413, + CXCursor_CUDAGlobalAttr = 414, + CXCursor_CUDAHostAttr = 415, + CXCursor_CUDASharedAttr = 416, + CXCursor_VisibilityAttr = 417, + CXCursor_DLLExport = 418, + CXCursor_DLLImport = 419, + CXCursor_NSReturnsRetained = 420, + CXCursor_NSReturnsNotRetained = 421, + CXCursor_NSReturnsAutoreleased = 422, + CXCursor_NSConsumesSelf = 423, + CXCursor_NSConsumed = 424, + CXCursor_ObjCException = 425, + CXCursor_ObjCNSObject = 426, + CXCursor_ObjCIndependentClass = 427, + CXCursor_ObjCPreciseLifetime = 428, + CXCursor_ObjCReturnsInnerPointer = 429, + CXCursor_ObjCRequiresSuper = 430, + CXCursor_ObjCRootClass = 431, + CXCursor_ObjCSubclassingRestricted = 432, + CXCursor_ObjCExplicitProtocolImpl = 433, + CXCursor_ObjCDesignatedInitializer = 434, + CXCursor_ObjCRuntimeVisible = 435, + CXCursor_ObjCBoxable = 436, + CXCursor_FlagEnum = 437, + CXCursor_ConvergentAttr = 438, + CXCursor_WarnUnusedAttr = 439, + CXCursor_WarnUnusedResultAttr = 440, + CXCursor_AlignedAttr = 441, + CXCursor_LastAttr = CXCursor_AlignedAttr, /* Preprocessing */ - CXCursor_PreprocessingDirective = 500, - CXCursor_MacroDefinition = 501, - CXCursor_MacroExpansion = 502, - CXCursor_MacroInstantiation = CXCursor_MacroExpansion, - CXCursor_InclusionDirective = 503, - CXCursor_FirstPreprocessing = CXCursor_PreprocessingDirective, - CXCursor_LastPreprocessing = CXCursor_InclusionDirective, + CXCursor_PreprocessingDirective = 500, + CXCursor_MacroDefinition = 501, + CXCursor_MacroExpansion = 502, + CXCursor_MacroInstantiation = CXCursor_MacroExpansion, + CXCursor_InclusionDirective = 503, + CXCursor_FirstPreprocessing = CXCursor_PreprocessingDirective, + CXCursor_LastPreprocessing = CXCursor_InclusionDirective, /* Extra Declarations */ /** * A module import declaration. */ - CXCursor_ModuleImportDecl = 600, - CXCursor_TypeAliasTemplateDecl = 601, + CXCursor_ModuleImportDecl = 600, + CXCursor_TypeAliasTemplateDecl = 601, /** * A static_assert or _Static_assert node */ - CXCursor_StaticAssert = 602, + CXCursor_StaticAssert = 602, /** * a friend declaration. */ - CXCursor_FriendDecl = 603, - CXCursor_FirstExtraDecl = CXCursor_ModuleImportDecl, - CXCursor_LastExtraDecl = CXCursor_FriendDecl, + CXCursor_FriendDecl = 603, + CXCursor_FirstExtraDecl = CXCursor_ModuleImportDecl, + CXCursor_LastExtraDecl = CXCursor_FriendDecl, /** * A code completion overload candidate. */ - CXCursor_OverloadCandidate = 700 + CXCursor_OverloadCandidate = 700 }; /** @@ -2935,14 +2929,10 @@ typedef struct CXPlatformAvailability { * platform-availability structures returned. There are * \c min(N, availability_size) such structures. */ -CINDEX_LINKAGE int -clang_getCursorPlatformAvailability(CXCursor cursor, - int *always_deprecated, - CXString *deprecated_message, - int *always_unavailable, - CXString *unavailable_message, - CXPlatformAvailability *availability, - int availability_size); +CINDEX_LINKAGE int clang_getCursorPlatformAvailability( + CXCursor cursor, int *always_deprecated, CXString *deprecated_message, + int *always_unavailable, CXString *unavailable_message, + CXPlatformAvailability *availability, int availability_size); /** * Free the memory associated with a \c CXPlatformAvailability structure. @@ -2969,11 +2959,7 @@ CINDEX_LINKAGE enum CXLanguageKind clang_getCursorLanguage(CXCursor cursor); * Describe the "thread-local storage (TLS) kind" of the declaration * referred to by a cursor. */ -enum CXTLSKind { - CXTLS_None = 0, - CXTLS_Dynamic, - CXTLS_Static -}; +enum CXTLSKind { CXTLS_None = 0, CXTLS_Dynamic, CXTLS_Static }; /** * Determine the "thread-local storage (TLS) kind" of the declaration @@ -3005,7 +2991,7 @@ CINDEX_LINKAGE void clang_disposeCXCursorSet(CXCursorSet cset); * Queries a CXCursorSet to see if it contains a specific CXCursor. * * \returns non-zero if the set contains the specified cursor. -*/ + */ CINDEX_LINKAGE unsigned clang_CXCursorSet_contains(CXCursorSet cset, CXCursor cursor); @@ -3013,7 +2999,7 @@ CINDEX_LINKAGE unsigned clang_CXCursorSet_contains(CXCursorSet cset, * Inserts a CXCursor into a CXCursorSet. * * \returns zero if the CXCursor was already in the set, and non-zero otherwise. -*/ + */ CINDEX_LINKAGE unsigned clang_CXCursorSet_insert(CXCursorSet cset, CXCursor cursor); @@ -3267,8 +3253,9 @@ enum CXTypeKind { CXType_UShortAccum = 36, CXType_UAccum = 37, CXType_ULongAccum = 38, + CXType_BFloat16 = 39, CXType_FirstBuiltin = CXType_Void, - CXType_LastBuiltin = CXType_ULongAccum, + CXType_LastBuiltin = CXType_BFloat16, CXType_Complex = 100, CXType_Pointer = 101, @@ -3360,7 +3347,8 @@ enum CXTypeKind { CXType_OCLIntelSubgroupAVCImeDualRefStreamin = 175, - CXType_ExtVector = 176 + CXType_ExtVector = 176, + CXType_Atomic = 177 }; /** @@ -3433,9 +3421,9 @@ CINDEX_LINKAGE CXType clang_getEnumDeclIntegerType(CXCursor C); * Retrieve the integer value of an enum constant declaration as a signed * long long. * - * If the cursor does not reference an enum constant declaration, LLONG_MIN is returned. - * Since this is also potentially a valid constant value, the kind of the cursor - * must be verified before calling this function. + * If the cursor does not reference an enum constant declaration, LLONG_MIN is + * returned. Since this is also potentially a valid constant value, the kind of + * the cursor must be verified before calling this function. */ CINDEX_LINKAGE long long clang_getEnumConstantDeclValue(CXCursor C); @@ -3443,11 +3431,12 @@ CINDEX_LINKAGE long long clang_getEnumConstantDeclValue(CXCursor C); * Retrieve the integer value of an enum constant declaration as an unsigned * long long. * - * If the cursor does not reference an enum constant declaration, ULLONG_MAX is returned. - * Since this is also potentially a valid constant value, the kind of the cursor - * must be verified before calling this function. + * If the cursor does not reference an enum constant declaration, ULLONG_MAX is + * returned. Since this is also potentially a valid constant value, the kind of + * the cursor must be verified before calling this function. */ -CINDEX_LINKAGE unsigned long long clang_getEnumConstantDeclUnsignedValue(CXCursor C); +CINDEX_LINKAGE unsigned long long +clang_getEnumConstantDeclUnsignedValue(CXCursor C); /** * Retrieve the bit width of a bit field declaration as an integer. @@ -3528,8 +3517,8 @@ CINDEX_LINKAGE int clang_Cursor_getNumTemplateArguments(CXCursor C); * For I = 0, 1, and 2, Type, Integral, and Integral will be returned, * respectively. */ -CINDEX_LINKAGE enum CXTemplateArgumentKind clang_Cursor_getTemplateArgumentKind( - CXCursor C, unsigned I); +CINDEX_LINKAGE enum CXTemplateArgumentKind +clang_Cursor_getTemplateArgumentKind(CXCursor C, unsigned I); /** * Retrieve a CXType representing the type of a TemplateArgument of a @@ -3589,8 +3578,8 @@ CINDEX_LINKAGE long long clang_Cursor_getTemplateArgumentValue(CXCursor C, * If called with I = 1 or 2, 2147483649 or true will be returned, respectively. * For I == 0, this function's behavior is undefined. */ -CINDEX_LINKAGE unsigned long long clang_Cursor_getTemplateArgumentUnsignedValue( - CXCursor C, unsigned I); +CINDEX_LINKAGE unsigned long long +clang_Cursor_getTemplateArgumentUnsignedValue(CXCursor C, unsigned I); /** * Determine whether two CXTypes represent the same type. @@ -3745,7 +3734,7 @@ CINDEX_LINKAGE unsigned clang_Type_getNumObjCProtocolRefs(CXType T); CINDEX_LINKAGE CXCursor clang_Type_getObjCProtocolDecl(CXType T, unsigned i); /** - * Retreive the number of type arguments associated with an ObjC object. + * Retrieve the number of type arguments associated with an ObjC object. * * If the type is not an ObjC object, 0 is returned. */ @@ -3775,7 +3764,8 @@ CINDEX_LINKAGE CXType clang_getCursorResultType(CXCursor C); * Retrieve the exception specification type associated with a given cursor. * This is a value of type CXCursor_ExceptionSpecificationKind. * - * This only returns a valid result if the cursor refers to a function or method. + * This only returns a valid result if the cursor refers to a function or + * method. */ CINDEX_LINKAGE int clang_getCursorExceptionSpecificationType(CXCursor C); @@ -3949,6 +3939,13 @@ CINDEX_LINKAGE long long clang_Type_getOffsetOf(CXType T, const char *S); CINDEX_LINKAGE CXType clang_Type_getModifiedType(CXType T); /** + * Gets the type contained by this atomic type. + * + * If a non-atomic type is passed in, an invalid type is returned. + */ +CINDEX_LINKAGE CXType clang_Type_getValueType(CXType CT); + +/** * Return the offset of the field represented by the Cursor. * * If the cursor is not a field declaration, -1 is returned. @@ -4003,7 +4000,8 @@ CINDEX_LINKAGE int clang_Type_getNumTemplateArguments(CXType T); * This function only returns template type arguments and does not handle * template template arguments or variadic packs. */ -CINDEX_LINKAGE CXType clang_Type_getTemplateArgumentAsType(CXType T, unsigned i); +CINDEX_LINKAGE CXType clang_Type_getTemplateArgumentAsType(CXType T, + unsigned i); /** * Retrieve the ref-qualifier kind of a function or method. @@ -4039,9 +4037,9 @@ enum CX_CXXAccessSpecifier { /** * Returns the access control level for the referenced object. * - * If the cursor refers to a C++ declaration, its access control level within its - * parent scope is returned. Otherwise, if the cursor refers to a base specifier or - * access specifier, the specifier itself is returned. + * If the cursor refers to a C++ declaration, its access control level within + * its parent scope is returned. Otherwise, if the cursor refers to a base + * specifier or access specifier, the specifier itself is returned. */ CINDEX_LINKAGE enum CX_CXXAccessSpecifier clang_getCXXAccessSpecifier(CXCursor); @@ -4192,7 +4190,7 @@ CINDEX_LINKAGE unsigned clang_visitChildren(CXCursor parent, CXCursorVisitor visitor, CXClientData client_data); #ifdef __has_feature -# if __has_feature(blocks) +#if __has_feature(blocks) /** * Visitor invoked for each cursor found by a traversal. * @@ -4203,16 +4201,16 @@ CINDEX_LINKAGE unsigned clang_visitChildren(CXCursor parent, * The visitor should return one of the \c CXChildVisitResult values * to direct clang_visitChildrenWithBlock(). */ -typedef enum CXChildVisitResult - (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent); +typedef enum CXChildVisitResult (^CXCursorVisitorBlock)(CXCursor cursor, + CXCursor parent); /** * Visits the children of a cursor using the specified block. Behaves * identically to clang_visitChildren() in all other respects. */ -CINDEX_LINKAGE unsigned clang_visitChildrenWithBlock(CXCursor parent, - CXCursorVisitorBlock block); -# endif +CINDEX_LINKAGE unsigned +clang_visitChildrenWithBlock(CXCursor parent, CXCursorVisitorBlock block); +#endif #endif /** @@ -4249,15 +4247,14 @@ CINDEX_LINKAGE CXString clang_constructUSR_ObjCClass(const char *class_name); /** * Construct a USR for a specified Objective-C category. */ -CINDEX_LINKAGE CXString - clang_constructUSR_ObjCCategory(const char *class_name, - const char *category_name); +CINDEX_LINKAGE CXString clang_constructUSR_ObjCCategory( + const char *class_name, const char *category_name); /** * Construct a USR for a specified Objective-C protocol. */ CINDEX_LINKAGE CXString - clang_constructUSR_ObjCProtocol(const char *protocol_name); +clang_constructUSR_ObjCProtocol(const char *protocol_name); /** * Construct a USR for a specified Objective-C instance variable and @@ -4297,9 +4294,8 @@ CINDEX_LINKAGE CXString clang_getCursorSpelling(CXCursor); * * \param options Reserved. */ -CINDEX_LINKAGE CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor, - unsigned pieceIndex, - unsigned options); +CINDEX_LINKAGE CXSourceRange clang_Cursor_getSpellingNameRange( + CXCursor, unsigned pieceIndex, unsigned options); /** * Opaque pointer representing a policy that controls pretty printing @@ -4353,9 +4349,10 @@ clang_PrintingPolicy_getProperty(CXPrintingPolicy Policy, /** * Set a property value for the given printing policy. */ -CINDEX_LINKAGE void clang_PrintingPolicy_setProperty(CXPrintingPolicy Policy, - enum CXPrintingPolicyProperty Property, - unsigned Value); +CINDEX_LINKAGE void +clang_PrintingPolicy_setProperty(CXPrintingPolicy Policy, + enum CXPrintingPolicyProperty Property, + unsigned Value); /** * Retrieve the default policy for the cursor. @@ -4503,18 +4500,18 @@ CINDEX_LINKAGE CXType clang_Cursor_getReceiverType(CXCursor C); * Property attributes for a \c CXCursor_ObjCPropertyDecl. */ typedef enum { - CXObjCPropertyAttr_noattr = 0x00, - CXObjCPropertyAttr_readonly = 0x01, - CXObjCPropertyAttr_getter = 0x02, - CXObjCPropertyAttr_assign = 0x04, + CXObjCPropertyAttr_noattr = 0x00, + CXObjCPropertyAttr_readonly = 0x01, + CXObjCPropertyAttr_getter = 0x02, + CXObjCPropertyAttr_assign = 0x04, CXObjCPropertyAttr_readwrite = 0x08, - CXObjCPropertyAttr_retain = 0x10, - CXObjCPropertyAttr_copy = 0x20, + CXObjCPropertyAttr_retain = 0x10, + CXObjCPropertyAttr_copy = 0x20, CXObjCPropertyAttr_nonatomic = 0x40, - CXObjCPropertyAttr_setter = 0x80, - CXObjCPropertyAttr_atomic = 0x100, - CXObjCPropertyAttr_weak = 0x200, - CXObjCPropertyAttr_strong = 0x400, + CXObjCPropertyAttr_setter = 0x80, + CXObjCPropertyAttr_atomic = 0x100, + CXObjCPropertyAttr_weak = 0x200, + CXObjCPropertyAttr_strong = 0x400, CXObjCPropertyAttr_unsafe_unretained = 0x800, CXObjCPropertyAttr_class = 0x1000 } CXObjCPropertyAttrKind; @@ -4526,8 +4523,8 @@ typedef enum { * * \param reserved Reserved for future use, pass 0. */ -CINDEX_LINKAGE unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, - unsigned reserved); +CINDEX_LINKAGE unsigned +clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved); /** * Given a cursor that represents a property declaration, return the @@ -4589,8 +4586,9 @@ CINDEX_LINKAGE unsigned clang_Cursor_isVariadic(CXCursor C); * non-zero if the 'generated_declaration' is set in the attribute. */ CINDEX_LINKAGE unsigned clang_Cursor_isExternalSymbol(CXCursor C, - CXString *language, CXString *definedIn, - unsigned *isGenerated); + CXString *language, + CXString *definedIn, + unsigned *isGenerated); /** * Given a cursor that represents a declaration, return the associated @@ -4716,8 +4714,8 @@ CINDEX_LINKAGE unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit, * \returns the specified top level header associated with the module. */ CINDEX_LINKAGE -CXFile clang_Module_getTopLevelHeader(CXTranslationUnit, - CXModule Module, unsigned Index); +CXFile clang_Module_getTopLevelHeader(CXTranslationUnit, CXModule Module, + unsigned Index); /** * @} @@ -4735,7 +4733,8 @@ CXFile clang_Module_getTopLevelHeader(CXTranslationUnit, /** * Determine if a C++ constructor is a converting constructor. */ -CINDEX_LINKAGE unsigned clang_CXXConstructor_isConvertingConstructor(CXCursor C); +CINDEX_LINKAGE unsigned +clang_CXXConstructor_isConvertingConstructor(CXCursor C); /** * Determine if a C++ constructor is a copy constructor. @@ -4865,9 +4864,8 @@ CINDEX_LINKAGE CXCursor clang_getSpecializedCursorTemplate(CXCursor C); * \returns The piece of the name pointed to by the given cursor. If there is no * name, or if the PieceIndex is out-of-range, a null-cursor will be returned. */ -CINDEX_LINKAGE CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, - unsigned NameFlags, - unsigned PieceIndex); +CINDEX_LINKAGE CXSourceRange clang_getCursorReferenceNameRange( + CXCursor C, unsigned NameFlags, unsigned PieceIndex); enum CXNameRefFlags { /** @@ -5035,15 +5033,14 @@ CINDEX_LINKAGE void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range, * \param Cursors an array of \p NumTokens cursors, whose contents will be * replaced with the cursors corresponding to each token. */ -CINDEX_LINKAGE void clang_annotateTokens(CXTranslationUnit TU, - CXToken *Tokens, unsigned NumTokens, - CXCursor *Cursors); +CINDEX_LINKAGE void clang_annotateTokens(CXTranslationUnit TU, CXToken *Tokens, + unsigned NumTokens, CXCursor *Cursors); /** * Free the given set of tokens. */ -CINDEX_LINKAGE void clang_disposeTokens(CXTranslationUnit TU, - CXToken *Tokens, unsigned NumTokens); +CINDEX_LINKAGE void clang_disposeTokens(CXTranslationUnit TU, CXToken *Tokens, + unsigned NumTokens); /** * @} @@ -5060,15 +5057,11 @@ CINDEX_LINKAGE void clang_disposeTokens(CXTranslationUnit TU, /* for debug/testing */ CINDEX_LINKAGE CXString clang_getCursorKindSpelling(enum CXCursorKind Kind); -CINDEX_LINKAGE void clang_getDefinitionSpellingAndExtent(CXCursor, - const char **startBuf, - const char **endBuf, - unsigned *startLine, - unsigned *startColumn, - unsigned *endLine, - unsigned *endColumn); +CINDEX_LINKAGE void clang_getDefinitionSpellingAndExtent( + CXCursor, const char **startBuf, const char **endBuf, unsigned *startLine, + unsigned *startColumn, unsigned *endLine, unsigned *endColumn); CINDEX_LINKAGE void clang_enableStackTraces(void); -CINDEX_LINKAGE void clang_executeOnThread(void (*fn)(void*), void *user_data, +CINDEX_LINKAGE void clang_executeOnThread(void (*fn)(void *), void *user_data, unsigned stack_size); /** @@ -5319,9 +5312,8 @@ clang_getCompletionChunkKind(CXCompletionString completion_string, * * \returns the text associated with the chunk at index \c chunk_number. */ -CINDEX_LINKAGE CXString -clang_getCompletionChunkText(CXCompletionString completion_string, - unsigned chunk_number); +CINDEX_LINKAGE CXString clang_getCompletionChunkText( + CXCompletionString completion_string, unsigned chunk_number); /** * Retrieve the completion string associated with a particular chunk @@ -5334,9 +5326,8 @@ clang_getCompletionChunkText(CXCompletionString completion_string, * \returns the completion string associated with the chunk at index * \c chunk_number. */ -CINDEX_LINKAGE CXCompletionString -clang_getCompletionChunkCompletionString(CXCompletionString completion_string, - unsigned chunk_number); +CINDEX_LINKAGE CXCompletionString clang_getCompletionChunkCompletionString( + CXCompletionString completion_string, unsigned chunk_number); /** * Retrieve the number of chunks in the given code-completion string. @@ -5393,9 +5384,8 @@ clang_getCompletionNumAnnotations(CXCompletionString completion_string); * \returns annotation string associated with the completion at index * \c annotation_number, or a NULL string if that annotation is not available. */ -CINDEX_LINKAGE CXString -clang_getCompletionAnnotation(CXCompletionString completion_string, - unsigned annotation_number); +CINDEX_LINKAGE CXString clang_getCompletionAnnotation( + CXCompletionString completion_string, unsigned annotation_number); /** * Retrieve the parent context of the given completion string. @@ -5413,9 +5403,8 @@ clang_getCompletionAnnotation(CXCompletionString completion_string, * \returns The name of the completion parent, e.g., "NSObject" if * the completion string represents a method in the NSObject class. */ -CINDEX_LINKAGE CXString -clang_getCompletionParent(CXCompletionString completion_string, - enum CXCursorKind *kind); +CINDEX_LINKAGE CXString clang_getCompletionParent( + CXCompletionString completion_string, enum CXCursorKind *kind); /** * Retrieve the brief documentation comment attached to the declaration @@ -5771,13 +5760,11 @@ CINDEX_LINKAGE unsigned clang_defaultCodeCompleteOptions(void); * completion fails, returns NULL. */ CINDEX_LINKAGE -CXCodeCompleteResults *clang_codeCompleteAt(CXTranslationUnit TU, - const char *complete_filename, - unsigned complete_line, - unsigned complete_column, - struct CXUnsavedFile *unsaved_files, - unsigned num_unsaved_files, - unsigned options); +CXCodeCompleteResults * +clang_codeCompleteAt(CXTranslationUnit TU, const char *complete_filename, + unsigned complete_line, unsigned complete_column, + struct CXUnsavedFile *unsaved_files, + unsigned num_unsaved_files, unsigned options); /** * Sort the code-completion results in case-insensitive alphabetical @@ -5826,8 +5813,8 @@ CXDiagnostic clang_codeCompleteGetDiagnostic(CXCodeCompleteResults *Results, * along with the given code completion results. */ CINDEX_LINKAGE -unsigned long long clang_codeCompleteGetContexts( - CXCodeCompleteResults *Results); +unsigned long long +clang_codeCompleteGetContexts(CXCodeCompleteResults *Results); /** * Returns the cursor kind for the container for the current code @@ -5846,9 +5833,9 @@ unsigned long long clang_codeCompleteGetContexts( * container */ CINDEX_LINKAGE -enum CXCursorKind clang_codeCompleteGetContainerKind( - CXCodeCompleteResults *Results, - unsigned *IsIncomplete); +enum CXCursorKind +clang_codeCompleteGetContainerKind(CXCodeCompleteResults *Results, + unsigned *IsIncomplete); /** * Returns the USR for the container for the current code completion @@ -5900,19 +5887,19 @@ CINDEX_LINKAGE CXString clang_getClangVersion(void); */ CINDEX_LINKAGE void clang_toggleCrashRecovery(unsigned isEnabled); - /** - * Visitor invoked for each file in a translation unit - * (used with clang_getInclusions()). - * - * This visitor function will be invoked by clang_getInclusions() for each - * file included (either at the top-level or by \#include directives) within - * a translation unit. The first argument is the file being included, and - * the second and third arguments provide the inclusion stack. The - * array is sorted in order of immediate inclusion. For example, - * the first element refers to the location that included 'included_file'. - */ +/** + * Visitor invoked for each file in a translation unit + * (used with clang_getInclusions()). + * + * This visitor function will be invoked by clang_getInclusions() for each + * file included (either at the top-level or by \#include directives) within + * a translation unit. The first argument is the file being included, and + * the second and third arguments provide the inclusion stack. The + * array is sorted in order of immediate inclusion. For example, + * the first element refers to the location that included 'included_file'. + */ typedef void (*CXInclusionVisitor)(CXFile included_file, - CXSourceLocation* inclusion_stack, + CXSourceLocation *inclusion_stack, unsigned include_len, CXClientData client_data); @@ -5927,7 +5914,7 @@ CINDEX_LINKAGE void clang_getInclusions(CXTranslationUnit tu, CXClientData client_data); typedef enum { - CXEval_Int = 1 , + CXEval_Int = 1, CXEval_Float = 2, CXEval_ObjCStrLiteral = 3, CXEval_StrLiteral = 4, @@ -5936,17 +5923,18 @@ typedef enum { CXEval_UnExposed = 0 -} CXEvalResultKind ; +} CXEvalResultKind; /** * Evaluation result of a cursor */ -typedef void * CXEvalResult; +typedef void *CXEvalResult; /** * If cursor is a statement declaration tries to evaluate the * statement and if its variable, tries to evaluate its initializer, * into its corresponding type. + * If it's an expression, tries to evaluate the expression. */ CINDEX_LINKAGE CXEvalResult clang_Cursor_Evaluate(CXCursor C); @@ -5978,7 +5966,8 @@ CINDEX_LINKAGE unsigned clang_EvalResult_isUnsignedInt(CXEvalResult E); * Returns the evaluation result as an unsigned integer if * the kind is Int and clang_EvalResult_isUnsignedInt is non-zero. */ -CINDEX_LINKAGE unsigned long long clang_EvalResult_getAsUnsigned(CXEvalResult E); +CINDEX_LINKAGE unsigned long long +clang_EvalResult_getAsUnsigned(CXEvalResult E); /** * Returns the evaluation result as double if the @@ -5992,7 +5981,7 @@ CINDEX_LINKAGE double clang_EvalResult_getAsDouble(CXEvalResult E); * instead call clang_EvalResult_dispose on the CXEvalResult returned * by clang_Cursor_Evaluate. */ -CINDEX_LINKAGE const char* clang_EvalResult_getAsStr(CXEvalResult E); +CINDEX_LINKAGE const char *clang_EvalResult_getAsStr(CXEvalResult E); /** * Disposes the created Eval memory. @@ -6050,7 +6039,8 @@ CINDEX_LINKAGE unsigned clang_remap_getNumFiles(CXRemapping); * is associated with. */ CINDEX_LINKAGE void clang_remap_getFilenames(CXRemapping, unsigned index, - CXString *original, CXString *transformed); + CXString *original, + CXString *transformed); /** * Dispose the remapping. @@ -6066,10 +6056,7 @@ CINDEX_LINKAGE void clang_remap_dispose(CXRemapping); * @{ */ -enum CXVisitorResult { - CXVisit_Break, - CXVisit_Continue -}; +enum CXVisitorResult { CXVisit_Break, CXVisit_Continue }; typedef struct CXCursorAndRangeVisitor { void *context; @@ -6107,8 +6094,8 @@ typedef enum { * * \returns one of the CXResult enumerators. */ -CINDEX_LINKAGE CXResult clang_findReferencesInFile(CXCursor cursor, CXFile file, - CXCursorAndRangeVisitor visitor); +CINDEX_LINKAGE CXResult clang_findReferencesInFile( + CXCursor cursor, CXFile file, CXCursorAndRangeVisitor visitor); /** * Find #import/#include directives in a specific file. @@ -6122,15 +6109,14 @@ CINDEX_LINKAGE CXResult clang_findReferencesInFile(CXCursor cursor, CXFile file, * * \returns one of the CXResult enumerators. */ -CINDEX_LINKAGE CXResult clang_findIncludesInFile(CXTranslationUnit TU, - CXFile file, - CXCursorAndRangeVisitor visitor); +CINDEX_LINKAGE CXResult clang_findIncludesInFile( + CXTranslationUnit TU, CXFile file, CXCursorAndRangeVisitor visitor); #ifdef __has_feature -# if __has_feature(blocks) +#if __has_feature(blocks) -typedef enum CXVisitorResult - (^CXCursorAndRangeVisitorBlock)(CXCursor, CXSourceRange); +typedef enum CXVisitorResult (^CXCursorAndRangeVisitorBlock)(CXCursor, + CXSourceRange); CINDEX_LINKAGE CXResult clang_findReferencesInFileWithBlock(CXCursor, CXFile, @@ -6140,7 +6126,7 @@ CINDEX_LINKAGE CXResult clang_findIncludesInFileWithBlock(CXTranslationUnit, CXFile, CXCursorAndRangeVisitorBlock); -# endif +#endif #endif /** @@ -6223,46 +6209,46 @@ typedef struct { } CXIdxImportedASTFileInfo; typedef enum { - CXIdxEntity_Unexposed = 0, - CXIdxEntity_Typedef = 1, - CXIdxEntity_Function = 2, - CXIdxEntity_Variable = 3, - CXIdxEntity_Field = 4, - CXIdxEntity_EnumConstant = 5, + CXIdxEntity_Unexposed = 0, + CXIdxEntity_Typedef = 1, + CXIdxEntity_Function = 2, + CXIdxEntity_Variable = 3, + CXIdxEntity_Field = 4, + CXIdxEntity_EnumConstant = 5, - CXIdxEntity_ObjCClass = 6, - CXIdxEntity_ObjCProtocol = 7, - CXIdxEntity_ObjCCategory = 8, + CXIdxEntity_ObjCClass = 6, + CXIdxEntity_ObjCProtocol = 7, + CXIdxEntity_ObjCCategory = 8, CXIdxEntity_ObjCInstanceMethod = 9, - CXIdxEntity_ObjCClassMethod = 10, - CXIdxEntity_ObjCProperty = 11, - CXIdxEntity_ObjCIvar = 12, - - CXIdxEntity_Enum = 13, - CXIdxEntity_Struct = 14, - CXIdxEntity_Union = 15, - - CXIdxEntity_CXXClass = 16, - CXIdxEntity_CXXNamespace = 17, - CXIdxEntity_CXXNamespaceAlias = 18, - CXIdxEntity_CXXStaticVariable = 19, - CXIdxEntity_CXXStaticMethod = 20, - CXIdxEntity_CXXInstanceMethod = 21, - CXIdxEntity_CXXConstructor = 22, - CXIdxEntity_CXXDestructor = 23, + CXIdxEntity_ObjCClassMethod = 10, + CXIdxEntity_ObjCProperty = 11, + CXIdxEntity_ObjCIvar = 12, + + CXIdxEntity_Enum = 13, + CXIdxEntity_Struct = 14, + CXIdxEntity_Union = 15, + + CXIdxEntity_CXXClass = 16, + CXIdxEntity_CXXNamespace = 17, + CXIdxEntity_CXXNamespaceAlias = 18, + CXIdxEntity_CXXStaticVariable = 19, + CXIdxEntity_CXXStaticMethod = 20, + CXIdxEntity_CXXInstanceMethod = 21, + CXIdxEntity_CXXConstructor = 22, + CXIdxEntity_CXXDestructor = 23, CXIdxEntity_CXXConversionFunction = 24, - CXIdxEntity_CXXTypeAlias = 25, - CXIdxEntity_CXXInterface = 26 + CXIdxEntity_CXXTypeAlias = 25, + CXIdxEntity_CXXInterface = 26 } CXIdxEntityKind; typedef enum { CXIdxEntityLang_None = 0, - CXIdxEntityLang_C = 1, + CXIdxEntityLang_C = 1, CXIdxEntityLang_ObjC = 2, - CXIdxEntityLang_CXX = 3, - CXIdxEntityLang_Swift = 4 + CXIdxEntityLang_CXX = 3, + CXIdxEntityLang_Swift = 4 } CXIdxEntityLanguage; /** @@ -6276,16 +6262,16 @@ typedef enum { * CXIdxEntity_CXXTypeAlias */ typedef enum { - CXIdxEntity_NonTemplate = 0, - CXIdxEntity_Template = 1, + CXIdxEntity_NonTemplate = 0, + CXIdxEntity_Template = 1, CXIdxEntity_TemplatePartialSpecialization = 2, CXIdxEntity_TemplateSpecialization = 3 } CXIdxEntityCXXTemplateKind; typedef enum { - CXIdxAttr_Unexposed = 0, - CXIdxAttr_IBAction = 1, - CXIdxAttr_IBOutlet = 2, + CXIdxAttr_Unexposed = 0, + CXIdxAttr_IBAction = 1, + CXIdxAttr_IBOutlet = 2, CXIdxAttr_IBOutletCollection = 3 } CXIdxAttrKind; @@ -6317,9 +6303,7 @@ typedef struct { CXIdxLoc classLoc; } CXIdxIBOutletCollectionAttrInfo; -typedef enum { - CXIdxDeclFlag_Skipped = 0x1 -} CXIdxDeclInfoFlags; +typedef enum { CXIdxDeclFlag_Skipped = 0x1 } CXIdxDeclInfoFlags; typedef struct { const CXIdxEntityInfo *entityInfo; @@ -6488,11 +6472,10 @@ typedef struct { /** * Called at the end of indexing; passes the complete diagnostic set. */ - void (*diagnostic)(CXClientData client_data, - CXDiagnosticSet, void *reserved); + void (*diagnostic)(CXClientData client_data, CXDiagnosticSet, void *reserved); - CXIdxClientFile (*enteredMainFile)(CXClientData client_data, - CXFile mainFile, void *reserved); + CXIdxClientFile (*enteredMainFile)(CXClientData client_data, CXFile mainFile, + void *reserved); /** * Called when a file gets \#included/\#imported. @@ -6517,8 +6500,7 @@ typedef struct { CXIdxClientContainer (*startedTranslationUnit)(CXClientData client_data, void *reserved); - void (*indexDeclaration)(CXClientData client_data, - const CXIdxDeclInfo *); + void (*indexDeclaration)(CXClientData client_data, const CXIdxDeclInfo *); /** * Called to index a reference of an entity. @@ -6562,8 +6544,8 @@ clang_index_getClientContainer(const CXIdxContainerInfo *); * For setting a custom CXIdxClientContainer attached to a * container. */ -CINDEX_LINKAGE void -clang_index_setClientContainer(const CXIdxContainerInfo *,CXIdxClientContainer); +CINDEX_LINKAGE void clang_index_setClientContainer(const CXIdxContainerInfo *, + CXIdxClientContainer); /** * For retrieving a custom CXIdxClientEntity attached to an entity. @@ -6574,8 +6556,8 @@ clang_index_getClientEntity(const CXIdxEntityInfo *); /** * For setting a custom CXIdxClientEntity attached to an entity. */ -CINDEX_LINKAGE void -clang_index_setClientEntity(const CXIdxEntityInfo *, CXIdxClientEntity); +CINDEX_LINKAGE void clang_index_setClientEntity(const CXIdxEntityInfo *, + CXIdxClientEntity); /** * An indexing action/session, to be applied to one or multiple @@ -6663,18 +6645,12 @@ typedef enum { * * The rest of the parameters are the same as #clang_parseTranslationUnit. */ -CINDEX_LINKAGE int clang_indexSourceFile(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); +CINDEX_LINKAGE int clang_indexSourceFile( + 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); /** * Same as clang_indexSourceFile but requires a full command line @@ -6704,12 +6680,9 @@ CINDEX_LINKAGE int clang_indexSourceFileFullArgv( * \returns If there is a failure from which there is no recovery, returns * non-zero, otherwise returns 0. */ -CINDEX_LINKAGE int clang_indexTranslationUnit(CXIndexAction, - CXClientData client_data, - IndexerCallbacks *index_callbacks, - unsigned index_callbacks_size, - unsigned index_options, - CXTranslationUnit); +CINDEX_LINKAGE int clang_indexTranslationUnit( + CXIndexAction, CXClientData client_data, IndexerCallbacks *index_callbacks, + unsigned index_callbacks_size, unsigned index_options, CXTranslationUnit); /** * Retrieve the CXIdxFile, file, line, column, and offset represented by @@ -6721,8 +6694,7 @@ CINDEX_LINKAGE int clang_indexTranslationUnit(CXIndexAction, */ CINDEX_LINKAGE void clang_indexLoc_getFileLocation(CXIdxLoc loc, CXIdxClientFile *indexFile, - CXFile *file, - unsigned *line, + CXFile *file, unsigned *line, unsigned *column, unsigned *offset); @@ -6765,8 +6737,7 @@ typedef enum CXVisitorResult (*CXFieldVisitor)(CXCursor C, * \returns a non-zero value if the traversal was terminated * prematurely by the visitor returning \c CXFieldVisit_Break. */ -CINDEX_LINKAGE unsigned clang_Type_visitFields(CXType T, - CXFieldVisitor visitor, +CINDEX_LINKAGE unsigned clang_Type_visitFields(CXType T, CXFieldVisitor visitor, CXClientData client_data); /** diff --git a/clang/include/clang-c/Platform.h b/clang/include/clang-c/Platform.h index 3bb66bb0df48..67c1fff8ff78 100644 --- a/clang/include/clang-c/Platform.h +++ b/clang/include/clang-c/Platform.h @@ -18,14 +18,23 @@ LLVM_CLANG_C_EXTERN_C_BEGIN -/* MSVC DLL import/export. */ -#ifdef _MSC_VER - #ifdef _CINDEX_LIB_ - #define CINDEX_LINKAGE __declspec(dllexport) - #else - #define CINDEX_LINKAGE __declspec(dllimport) +/* Windows DLL import/export. */ +#ifndef CINDEX_NO_EXPORTS + #define CINDEX_EXPORTS +#endif +#ifdef _WIN32 + #ifdef CINDEX_EXPORTS + #ifdef _CINDEX_LIB_ + #define CINDEX_LINKAGE __declspec(dllexport) + #else + #define CINDEX_LINKAGE __declspec(dllimport) + #endif #endif -#else +#elif defined(CINDEX_EXPORTS) && defined(__GNUC__) + #define CINDEX_LINKAGE __attribute__((visibility("default"))) +#endif + +#ifndef CINDEX_LINKAGE #define CINDEX_LINKAGE #endif diff --git a/clang/include/clang/AST/APValue.h b/clang/include/clang/AST/APValue.h index 63359294ef63..cca92b5f8235 100644 --- a/clang/include/clang/AST/APValue.h +++ b/clang/include/clang/AST/APValue.h @@ -372,7 +372,7 @@ public: bool isAddrLabelDiff() const { return Kind == AddrLabelDiff; } void dump() const; - void dump(raw_ostream &OS) const; + void dump(raw_ostream &OS, const ASTContext &Context) const; void printPretty(raw_ostream &OS, const ASTContext &Ctx, QualType Ty) const; std::string getAsString(const ASTContext &Ctx, QualType Ty) const; diff --git a/clang/include/clang/AST/ASTConcept.h b/clang/include/clang/AST/ASTConcept.h index 896d857d8c96..71bf14a87865 100644 --- a/clang/include/clang/AST/ASTConcept.h +++ b/clang/include/clang/AST/ASTConcept.h @@ -22,10 +22,25 @@ #include <utility> namespace clang { class ConceptDecl; +class ConceptSpecializationExpr; + +/// The result of a constraint satisfaction check, containing the necessary +/// information to diagnose an unsatisfied constraint. +class ConstraintSatisfaction : public llvm::FoldingSetNode { + // The template-like entity that 'owns' the constraint checked here (can be a + // constrained entity or a concept). + const NamedDecl *ConstraintOwner = nullptr; + llvm::SmallVector<TemplateArgument, 4> TemplateArgs; + +public: + + ConstraintSatisfaction() = default; + + ConstraintSatisfaction(const NamedDecl *ConstraintOwner, + ArrayRef<TemplateArgument> TemplateArgs) : + ConstraintOwner(ConstraintOwner), TemplateArgs(TemplateArgs.begin(), + TemplateArgs.end()) { } -/// \brief The result of a constraint satisfaction check, containing the -/// necessary information to diagnose an unsatisfied constraint. -struct ConstraintSatisfaction { using SubstitutionDiagnostic = std::pair<SourceLocation, StringRef>; using Detail = llvm::PointerUnion<Expr *, SubstitutionDiagnostic *>; @@ -37,9 +52,13 @@ struct ConstraintSatisfaction { /// invalid expression. llvm::SmallVector<std::pair<const Expr *, Detail>, 4> Details; - // This can leak if used in an AST node, use ASTConstraintSatisfaction - // instead. - void *operator new(size_t bytes, ASTContext &C) = delete; + void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &C) { + Profile(ID, C, ConstraintOwner, TemplateArgs); + } + + static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &C, + const NamedDecl *ConstraintOwner, + ArrayRef<TemplateArgument> TemplateArgs); }; /// Pairs of unsatisfied atomic constraint expressions along with the @@ -174,4 +193,4 @@ public: } // clang -#endif // LLVM_CLANG_AST_ASTCONCEPT_H
\ No newline at end of file +#endif // LLVM_CLANG_AST_ASTCONCEPT_H diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index fb269cef1ce8..2b988be60da9 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -15,7 +15,7 @@ #define LLVM_CLANG_AST_ASTCONTEXT_H #include "clang/AST/ASTContextAllocate.h" -#include "clang/AST/ASTTypeTraits.h" +#include "clang/AST/ASTFwd.h" #include "clang/AST/CanonicalType.h" #include "clang/AST/CommentCommandTraits.h" #include "clang/AST/ComparisonCategories.h" @@ -26,7 +26,6 @@ #include "clang/AST/NestedNameSpecifier.h" #include "clang/AST/PrettyPrinter.h" #include "clang/AST/RawCommentList.h" -#include "clang/AST/TemplateBase.h" #include "clang/AST/TemplateName.h" #include "clang/AST/Type.h" #include "clang/Basic/AddressSpaces.h" @@ -40,7 +39,6 @@ #include "clang/Basic/SanitizerBlacklist.h" #include "clang/Basic/SourceLocation.h" #include "clang/Basic/Specifiers.h" -#include "clang/Basic/TargetInfo.h" #include "clang/Basic/XRayLists.h" #include "llvm/ADT/APSInt.h" #include "llvm/ADT/ArrayRef.h" @@ -75,6 +73,7 @@ namespace llvm { struct fltSemantics; +template <typename T, unsigned N> class SmallPtrSet; } // namespace llvm @@ -88,11 +87,15 @@ class AtomicExpr; class BlockExpr; class BuiltinTemplateDecl; class CharUnits; +class ConceptDecl; class CXXABI; class CXXConstructorDecl; class CXXMethodDecl; class CXXRecordDecl; class DiagnosticsEngine; +class ParentMapContext; +class DynTypedNode; +class DynTypedNodeList; class Expr; class FixedPointSemantics; class GlobalDecl; @@ -101,6 +104,7 @@ class MangleNumberingContext; class MaterializeTemporaryExpr; class MemberSpecializationInfo; class Module; +struct MSGuidDeclParts; class ObjCCategoryDecl; class ObjCCategoryImplDecl; class ObjCContainerDecl; @@ -113,11 +117,13 @@ class ObjCPropertyDecl; class ObjCPropertyImplDecl; class ObjCProtocolDecl; class ObjCTypeParamDecl; +class OMPTraitInfo; struct ParsedTargetAttr; class Preprocessor; class Stmt; class StoredDeclsMap; class TargetAttr; +class TargetInfo; class TemplateDecl; class TemplateParameterList; class TemplateTemplateParmDecl; @@ -135,6 +141,7 @@ class Context; } // namespace Builtin enum BuiltinTemplateKind : int; +enum OpenCLTypeKind : uint8_t; namespace comments { @@ -187,6 +194,8 @@ class ASTContext : public RefCountedBase<ASTContext> { DependentAddressSpaceTypes; mutable llvm::FoldingSet<VectorType> VectorTypes; mutable llvm::FoldingSet<DependentVectorType> DependentVectorTypes; + mutable llvm::FoldingSet<ConstantMatrixType> MatrixTypes; + mutable llvm::FoldingSet<DependentSizedMatrixType> DependentSizedMatrixTypes; mutable llvm::FoldingSet<FunctionNoProtoType> FunctionNoProtoTypes; mutable llvm::ContextualFoldingSet<FunctionProtoType, ASTContext&> FunctionProtoTypes; @@ -211,12 +220,14 @@ class ASTContext : public RefCountedBase<ASTContext> { mutable llvm::FoldingSet<ObjCObjectPointerType> ObjCObjectPointerTypes; mutable llvm::FoldingSet<DependentUnaryTransformType> DependentUnaryTransformTypes; - mutable llvm::FoldingSet<AutoType> AutoTypes; + mutable llvm::ContextualFoldingSet<AutoType, ASTContext&> AutoTypes; mutable llvm::FoldingSet<DeducedTemplateSpecializationType> DeducedTemplateSpecializationTypes; mutable llvm::FoldingSet<AtomicType> AtomicTypes; llvm::FoldingSet<AttributedType> AttributedTypes; mutable llvm::FoldingSet<PipeType> PipeTypes; + mutable llvm::FoldingSet<ExtIntType> ExtIntTypes; + mutable llvm::FoldingSet<DependentExtIntType> DependentExtIntTypes; mutable llvm::FoldingSet<QualifiedTemplateName> QualifiedTemplateNames; mutable llvm::FoldingSet<DependentTemplateName> DependentTemplateNames; @@ -263,6 +274,9 @@ class ASTContext : public RefCountedBase<ASTContext> { /// Mapping from __block VarDecls to BlockVarCopyInit. llvm::DenseMap<const VarDecl *, BlockVarCopyInit> BlockVarCopyInits; + /// Mapping from GUIDs to the corresponding MSGuidDecl. + mutable llvm::FoldingSet<MSGuidDecl> MSGuidDecls; + /// Used to cleanups APValues stored in the AST. mutable llvm::SmallVector<APValue *, 0> APValueCleanups; @@ -564,18 +578,9 @@ private: const TargetInfo *AuxTarget = nullptr; clang::PrintingPolicy PrintingPolicy; std::unique_ptr<interp::Context> InterpContext; - - ast_type_traits::TraversalKind Traversal = ast_type_traits::TK_AsIs; + std::unique_ptr<ParentMapContext> ParentMapCtx; public: - ast_type_traits::TraversalKind getTraversalKind() const { return Traversal; } - void setTraversalKind(ast_type_traits::TraversalKind TK) { Traversal = TK; } - - const Expr *traverseIgnored(const Expr *E) const; - Expr *traverseIgnored(Expr *E) const; - ast_type_traits::DynTypedNode - traverseIgnored(const ast_type_traits::DynTypedNode &N) const; - IdentifierTable &Idents; SelectorTable &Selectors; Builtin::Context &BuiltinInfo; @@ -586,46 +591,8 @@ public: /// Returns the clang bytecode interpreter context. interp::Context &getInterpContext(); - /// Container for either a single DynTypedNode or for an ArrayRef to - /// DynTypedNode. For use with ParentMap. - class DynTypedNodeList { - using DynTypedNode = ast_type_traits::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); - } - }; + /// Returns the dynamic AST node parent map context. + ParentMapContext &getParentMapContext(); // A traversal scope limits the parts of the AST visible to certain analyses. // RecursiveASTVisitor::TraverseAST will only visit reachable nodes, and @@ -637,35 +604,9 @@ public: std::vector<Decl *> getTraversalScope() const { return TraversalScope; } void setTraversalScope(const std::vector<Decl *> &); - /// Returns the parents of the given node (within the traversal scope). - /// - /// Note that this will lazily compute the parents of all nodes - /// and store them for later retrieval. Thus, the first call is O(n) - /// in the number of AST nodes. - /// - /// Caveats and FIXMEs: - /// Calculating the parent map over all AST nodes will need to load the - /// full AST. This can be undesirable in the case where the full AST is - /// expensive to create (for example, when using precompiled header - /// preambles). Thus, there are good opportunities for optimization here. - /// One idea is to walk the given node downwards, looking for references - /// to declaration contexts - once a declaration context is found, compute - /// the parent map for the declaration context; if that can satisfy the - /// request, loading the whole AST can be avoided. Note that this is made - /// more complex by statements in templates having multiple parents - those - /// problems can be solved by building closure over the templated parts of - /// the AST, which also avoids touching large parts of the AST. - /// Additionally, we will want to add an interface to already give a hint - /// where to search for the parents, for example when looking at a statement - /// inside a certain function. - /// - /// 'NodeT' can be one of Decl, Stmt, Type, TypeLoc, - /// NestedNameSpecifier or NestedNameSpecifierLoc. - template <typename NodeT> DynTypedNodeList getParents(const NodeT &Node) { - return getParents(ast_type_traits::DynTypedNode::create(Node)); - } - - DynTypedNodeList getParents(const ast_type_traits::DynTypedNode &Node); + /// Forwards to get node parents from the ParentMapContext. New callers should + /// use ParentMapContext::getParents() directly. + template <typename NodeT> DynTypedNodeList getParents(const NodeT &Node); const clang::PrintingPolicy &getPrintingPolicy() const { return PrintingPolicy; @@ -716,7 +657,7 @@ public: /// getRealTypeForBitwidth - /// sets floating point QualTy according to specified bitwidth. /// Returns empty type if there is no appropriate target types. - QualType getRealTypeForBitwidth(unsigned DestWidth) const; + QualType getRealTypeForBitwidth(unsigned DestWidth, bool ExplicitIEEE) const; bool AtomicUsesUnsupportedLibcall(const AtomicExpr *E) const; @@ -790,15 +731,7 @@ public: RawComment *getRawCommentForDeclNoCache(const Decl *D) const; public: - RawCommentList &getRawCommentList() { - return Comments; - } - - void addComment(const RawComment &RC) { - assert(LangOpts.RetainCommentsFromSystemHeaders || - !SourceMgr.isInSystemHeader(RC.getSourceRange().getBegin())); - Comments.addComment(RC, LangOpts.CommentOpts, BumpAlloc); - } + void addComment(const RawComment &RC); /// Return the documentation comment attached to a given declaration. /// Returns nullptr if no comment is attached. @@ -958,7 +891,7 @@ public: void addedLocalImportDecl(ImportDecl *Import); static ImportDecl *getNextLocalImport(ImportDecl *Import) { - return Import->NextLocalImport; + return Import->getNextLocalImport(); } using import_range = llvm::iterator_range<import_iterator>; @@ -986,13 +919,7 @@ public: /// Get the additional modules in which the definition \p Def has /// been merged. - ArrayRef<Module*> getModulesWithMergedDefinition(const NamedDecl *Def) { - auto MergedIt = - MergedDefModules.find(cast<NamedDecl>(Def->getCanonicalDecl())); - if (MergedIt == MergedDefModules.end()) - return None; - return MergedIt->second; - } + ArrayRef<Module*> getModulesWithMergedDefinition(const NamedDecl *Def); /// Add a declaration to the list of declarations that are initialized /// for a module. This will typically be a global variable (with internal @@ -1037,6 +964,7 @@ public: CanQualType SatUnsignedShortFractTy, SatUnsignedFractTy, SatUnsignedLongFractTy; CanQualType HalfTy; // [OpenCL 6.1.1.1], ARM NEON + CanQualType BFloat16Ty; CanQualType Float16Ty; // C11 extension ISO/IEC TS 18661-3 CanQualType FloatComplexTy, DoubleComplexTy, LongDoubleComplexTy; CanQualType Float128ComplexTy; @@ -1051,7 +979,8 @@ public: #include "clang/Basic/OpenCLImageTypes.def" CanQualType OCLSamplerTy, OCLEventTy, OCLClkEventTy; CanQualType OCLQueueTy, OCLReserveIDTy; - CanQualType OMPArraySectionTy; + CanQualType IncompleteMatrixIdxTy; + CanQualType OMPArraySectionTy, OMPArrayShapingTy, OMPIteratorTy; #define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \ CanQualType Id##Ty; #include "clang/Basic/OpenCLExtensionTypes.def" @@ -1065,7 +994,10 @@ public: // Decl used to help define __builtin_va_list for some targets. // The decl is built when constructing 'BuiltinVaListDecl'. - mutable Decl *VaListTagDecl; + mutable Decl *VaListTagDecl = nullptr; + + // Implicitly-declared type 'struct _GUID'. + mutable TagDecl *MSGuidTagDecl = nullptr; ASTContext(LangOptions &LOpts, SourceManager &SM, IdentifierTable &idents, SelectorTable &sels, Builtin::Context &builtins); @@ -1277,12 +1209,20 @@ public: /// Return a write_only pipe type for the specified type. QualType getWritePipeType(QualType T) const; + /// Return an extended integer type with the specified signedness and bit + /// count. + QualType getExtIntType(bool Unsigned, unsigned NumBits) const; + + /// Return a dependent extended integer type with the specified signedness and + /// bit count. + QualType getDependentExtIntType(bool Unsigned, Expr *BitsExpr) const; + /// Gets the struct used to keep track of the extended descriptor for /// pointer to blocks. QualType getBlockDescriptorExtendedType() const; /// Map an AST Type to an OpenCLTypeKind enum value. - TargetInfo::OpenCLTypeKind getOpenCLTypeKind(const Type *T) const; + OpenCLTypeKind getOpenCLTypeKind(const Type *T) const; /// Get address space for OpenCL type. LangAS getOpenCLTypeAddrSpace(const Type *T) const; @@ -1357,6 +1297,12 @@ public: /// Returns a vla type where known sizes are replaced with [*]. QualType getVariableArrayDecayedType(QualType Ty) const; + /// Return the unique reference to a scalable vector type of the specified + /// element type and scalable number of elements. + /// + /// \pre \p EltTy must be a built-in type. + QualType getScalableVectorType(QualType EltTy, unsigned NumElts) const; + /// Return the unique reference to a vector type of the specified /// element type and size. /// @@ -1384,6 +1330,20 @@ public: Expr *SizeExpr, SourceLocation AttrLoc) const; + /// Return the unique reference to the matrix type of the specified element + /// type and size + /// + /// \pre \p ElementType must be a valid matrix element type (see + /// MatrixType::isValidElementType). + QualType getConstantMatrixType(QualType ElementType, unsigned NumRows, + unsigned NumColumns) const; + + /// Return the unique reference to the matrix type of the specified element + /// type and size + QualType getDependentSizedMatrixType(QualType ElementType, Expr *RowExpr, + Expr *ColumnExpr, + SourceLocation AttrLoc) const; + QualType getDependentAddressSpaceType(QualType PointeeType, Expr *AddrSpaceExpr, SourceLocation AttrLoc) const; @@ -1517,6 +1477,8 @@ public: QualType getObjCTypeParamType(const ObjCTypeParamDecl *Decl, ArrayRef<ObjCProtocolDecl *> protocols) const; + void adjustObjCTypeParamBoundType(const ObjCTypeParamDecl *Orig, + ObjCTypeParamDecl *New) const; bool ObjCObjectAdoptsQTypeProtocols(QualType QT, ObjCInterfaceDecl *Decl); @@ -1542,7 +1504,9 @@ public: /// C++11 deduced auto type. QualType getAutoType(QualType DeducedType, AutoTypeKeyword Keyword, - bool IsDependent, bool IsPack = false) const; + bool IsDependent, bool IsPack = false, + ConceptDecl *TypeConstraintConcept = nullptr, + ArrayRef<TemplateArgument> TypeConstraintArgs ={}) const; /// C++11 deduction pattern for 'auto' type. QualType getAutoDeductType() const; @@ -1710,23 +1674,9 @@ public: return NSCopyingName; } - CanQualType getNSUIntegerType() const { - assert(Target && "Expected target to be initialized"); - const llvm::Triple &T = Target->getTriple(); - // Windows is LLP64 rather than LP64 - if (T.isOSWindows() && T.isArch64Bit()) - return UnsignedLongLongTy; - return UnsignedLongTy; - } + CanQualType getNSUIntegerType() const; - CanQualType getNSIntegerType() const { - assert(Target && "Expected target to be initialized"); - const llvm::Triple &T = Target->getTriple(); - // Windows is LLP64 rather than LP64 - if (T.isOSWindows() && T.isArch64Bit()) - return LongLongTy; - return LongTy; - } + CanQualType getNSIntegerType() const; /// Retrieve the identifier 'bool'. IdentifierInfo *getBoolName() const { @@ -1941,6 +1891,15 @@ public: return getTypeDeclType(getBuiltinMSVaListDecl()); } + /// Retrieve the implicitly-predeclared 'struct _GUID' declaration. + TagDecl *getMSGuidTagDecl() const { return MSGuidTagDecl; } + + /// Retrieve the implicitly-predeclared 'struct _GUID' type. + QualType getMSGuidType() const { + assert(MSGuidTagDecl && "asked for GUID type but MS extensions disabled"); + return getTagDeclType(MSGuidTagDecl); + } + /// Return whether a declaration to a builtin is allowed to be /// overloaded/redeclared. bool canBuiltinBeRedeclared(const FunctionDecl *) const; @@ -2204,9 +2163,7 @@ public: /// Return the alignment (in bytes) of the thrown exception object. This is /// only meaningful for targets that allocate C++ exceptions in a system /// runtime, such as those using the Itanium C++ ABI. - CharUnits getExnObjectAlignment() const { - return toCharUnitsFromBits(Target->getExnObjectAlignment()); - } + CharUnits getExnObjectAlignment() const; /// Get or compute information about the layout of the specified /// record (struct/union/class) \p D, which indicates its size and field @@ -2624,7 +2581,7 @@ public: QualType mergeTypes(QualType, QualType, bool OfBlockPointer=false, bool Unqualified = false, bool BlockReturnType = false); QualType mergeFunctionTypes(QualType, QualType, bool OfBlockPointer=false, - bool Unqualified = false); + bool Unqualified = false, bool AllowCXX = false); QualType mergeFunctionParameterTypes(QualType, QualType, bool OfBlockPointer = false, bool Unqualified = false); @@ -2845,6 +2802,10 @@ public: /// PredefinedExpr to cache evaluated results. StringLiteral *getPredefinedStringLiteralFromCache(StringRef Key) const; + /// Return a declaration for the global GUID object representing the given + /// GUID value. + MSGuidDecl *getMSGuidDecl(MSGuidDeclParts Parts) const; + /// Parses the target attributes passed in, and returns only the ones that are /// valid feature names. ParsedTargetAttr filterFunctionTargetAttrs(const TargetAttr *TD) const; @@ -3023,8 +2984,6 @@ private: llvm::PointerIntPair<StoredDeclsMap *, 1> LastSDM; std::vector<Decl *> TraversalScope; - class ParentMap; - std::map<ast_type_traits::TraversalKind, std::unique_ptr<ParentMap>> Parents; std::unique_ptr<VTableContextBase> VTContext; @@ -3037,6 +2996,7 @@ public: PSF_Write = 0x2, PSF_Execute = 0x4, PSF_Implicit = 0x8, + PSF_ZeroInit = 0x10, PSF_Invalid = 0x80000000U, }; @@ -3054,8 +3014,20 @@ public: }; llvm::StringMap<SectionInfo> SectionInfos; + + /// Return a new OMPTraitInfo object owned by this context. + OMPTraitInfo &getNewOMPTraitInfo(); + +private: + /// All OMPTraitInfo objects live in this collection, one per + /// `pragma omp [begin] declare variant` directive. + SmallVector<std::unique_ptr<OMPTraitInfo>, 4> OMPTraitInfoVector; }; +/// Insertion operator for diagnostics. +const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, + const ASTContext::SectionInfo &Section); + /// Utility function for constructing a nullary selector. inline Selector GetNullarySelector(StringRef name, ASTContext &Ctx) { IdentifierInfo* II = &Ctx.Idents.get(name); @@ -3068,22 +3040,6 @@ inline Selector GetUnarySelector(StringRef name, ASTContext &Ctx) { return Ctx.Selectors.getSelector(1, &II); } -class TraversalKindScope { - ASTContext &Ctx; - ast_type_traits::TraversalKind TK = ast_type_traits::TK_AsIs; - -public: - TraversalKindScope(ASTContext &Ctx, - llvm::Optional<ast_type_traits::TraversalKind> ScopeTK) - : Ctx(Ctx) { - TK = Ctx.getTraversalKind(); - if (ScopeTK) - Ctx.setTraversalKind(*ScopeTK); - } - - ~TraversalKindScope() { Ctx.setTraversalKind(TK); } -}; - } // namespace clang // operator new and delete aren't allowed inside namespaces. diff --git a/clang/include/clang/AST/ASTDumper.h b/clang/include/clang/AST/ASTDumper.h index 61202f057a80..a154bc2db3a7 100644 --- a/clang/include/clang/AST/ASTDumper.h +++ b/clang/include/clang/AST/ASTDumper.h @@ -11,6 +11,7 @@ #include "clang/AST/ASTNodeTraverser.h" #include "clang/AST/TextNodeDumper.h" +#include "clang/Basic/SourceManager.h" namespace clang { @@ -23,18 +24,11 @@ class ASTDumper : public ASTNodeTraverser<ASTDumper, TextNodeDumper> { const bool ShowColors; public: - ASTDumper(raw_ostream &OS, const comments::CommandTraits *Traits, - const SourceManager *SM) - : ASTDumper(OS, Traits, SM, SM && SM->getDiagnostics().getShowColors()) {} - - ASTDumper(raw_ostream &OS, const comments::CommandTraits *Traits, - const SourceManager *SM, bool ShowColors) - : ASTDumper(OS, Traits, SM, ShowColors, LangOptions()) {} - ASTDumper(raw_ostream &OS, const comments::CommandTraits *Traits, - const SourceManager *SM, bool ShowColors, - const PrintingPolicy &PrintPolicy) - : NodeDumper(OS, ShowColors, SM, PrintPolicy, Traits), OS(OS), - ShowColors(ShowColors) {} + ASTDumper(raw_ostream &OS, const ASTContext &Context, bool ShowColors) + : NodeDumper(OS, Context, ShowColors), OS(OS), ShowColors(ShowColors) {} + + ASTDumper(raw_ostream &OS, bool ShowColors) + : NodeDumper(OS, ShowColors), OS(OS), ShowColors(ShowColors) {} TextNodeDumper &doGetNodeDelegate() { return NodeDumper; } diff --git a/clang/include/clang/AST/ASTDumperUtils.h b/clang/include/clang/AST/ASTDumperUtils.h index 55a085449a9b..1dce913049ad 100644 --- a/clang/include/clang/AST/ASTDumperUtils.h +++ b/clang/include/clang/AST/ASTDumperUtils.h @@ -62,6 +62,8 @@ static const TerminalColor LocationColor = {llvm::raw_ostream::YELLOW, false}; static const TerminalColor ValueKindColor = {llvm::raw_ostream::CYAN, false}; // bitfield/objcproperty/objcsubscript/vectorcomponent static const TerminalColor ObjectKindColor = {llvm::raw_ostream::CYAN, false}; +// contains-errors +static const TerminalColor ErrorsColor = {llvm::raw_ostream::RED, true}; // Null statements static const TerminalColor NullColor = {llvm::raw_ostream::BLUE, false}; diff --git a/clang/include/clang/AST/ASTFwd.h b/clang/include/clang/AST/ASTFwd.h index 5a891817b336..65319a19728b 100644 --- a/clang/include/clang/AST/ASTFwd.h +++ b/clang/include/clang/AST/ASTFwd.h @@ -27,8 +27,8 @@ class Type; #include "clang/AST/TypeNodes.inc" class CXXCtorInitializer; class OMPClause; -#define OPENMP_CLAUSE(KIND, CLASSNAME) class CLASSNAME; -#include "clang/Basic/OpenMPKinds.def" +#define OMP_CLAUSE_CLASS(Enum, Str, Class) class Class; +#include "llvm/Frontend/OpenMP/OMPKinds.def" } // end namespace clang diff --git a/clang/include/clang/AST/ASTImporter.h b/clang/include/clang/AST/ASTImporter.h index 490b34bf95e8..205d7ec67754 100644 --- a/clang/include/clang/AST/ASTImporter.h +++ b/clang/include/clang/AST/ASTImporter.h @@ -16,6 +16,7 @@ #include "clang/AST/DeclBase.h" #include "clang/AST/DeclarationName.h" +#include "clang/AST/ExprCXX.h" #include "clang/AST/NestedNameSpecifier.h" #include "clang/AST/TemplateName.h" #include "clang/AST/Type.h" @@ -349,6 +350,10 @@ class TypeSourceInfo; return ToOrErr.takeError(); } + /// Import cleanup objects owned by ExprWithCleanup. + llvm::Expected<ExprWithCleanups::CleanupObject> + Import(ExprWithCleanups::CleanupObject From); + /// Import the given type from the "from" context into the "to" /// context. A null type is imported as a null type (no error). /// diff --git a/clang/include/clang/AST/ASTNodeTraverser.h b/clang/include/clang/AST/ASTNodeTraverser.h index e0ebb020e697..26656b7162b6 100644 --- a/clang/include/clang/AST/ASTNodeTraverser.h +++ b/clang/include/clang/AST/ASTNodeTraverser.h @@ -15,16 +15,20 @@ #ifndef LLVM_CLANG_AST_ASTNODETRAVERSER_H #define LLVM_CLANG_AST_ASTNODETRAVERSER_H +#include "clang/AST/ASTTypeTraits.h" #include "clang/AST/AttrVisitor.h" #include "clang/AST/CommentVisitor.h" #include "clang/AST/DeclVisitor.h" #include "clang/AST/LocInfoType.h" #include "clang/AST/StmtVisitor.h" #include "clang/AST/TemplateArgumentVisitor.h" +#include "clang/AST/Type.h" #include "clang/AST/TypeVisitor.h" namespace clang { +class APValue; + /** ASTNodeTraverser traverses the Clang AST for dumping purposes. @@ -49,6 +53,7 @@ struct { void Visit(const OMPClause *C); void Visit(const BlockDecl::Capture &C); void Visit(const GenericSelectionExpr::ConstAssociation &A); + void Visit(const APValue &Value, QualType Ty); }; */ template <typename Derived, typename NodeDelegateType> @@ -65,8 +70,7 @@ class ASTNodeTraverser /// not already been loaded. bool Deserialize = false; - ast_type_traits::TraversalKind Traversal = - ast_type_traits::TraversalKind::TK_AsIs; + TraversalKind Traversal = TraversalKind::TK_AsIs; NodeDelegateType &getNodeDelegate() { return getDerived().doGetNodeDelegate(); @@ -77,7 +81,7 @@ public: void setDeserialize(bool D) { Deserialize = D; } bool getDeserialize() const { return Deserialize; } - void SetTraversalKind(ast_type_traits::TraversalKind TK) { Traversal = TK; } + void SetTraversalKind(TraversalKind TK) { Traversal = TK; } void Visit(const Decl *D) { getNodeDelegate().AddChild([=] { @@ -108,12 +112,12 @@ public: if (auto *E = dyn_cast_or_null<Expr>(S)) { switch (Traversal) { - case ast_type_traits::TK_AsIs: + case TK_AsIs: break; - case ast_type_traits::TK_IgnoreImplicitCastsAndParentheses: + case TK_IgnoreImplicitCastsAndParentheses: S = E->IgnoreParenImpCasts(); break; - case ast_type_traits::TK_IgnoreUnlessSpelledInSource: + case TK_IgnoreUnlessSpelledInSource: S = E->IgnoreUnlessSpelledInSource(); break; } @@ -131,8 +135,7 @@ public: if (isa<DeclStmt>(S) || isa<GenericSelectionExpr>(S)) return; - if (isa<LambdaExpr>(S) && - Traversal == ast_type_traits::TK_IgnoreUnlessSpelledInSource) + if (isa<LambdaExpr>(S) && Traversal == TK_IgnoreUnlessSpelledInSource) return; for (const Stmt *SubStmt : S->children()) @@ -212,6 +215,10 @@ public: }); } + void Visit(const APValue &Value, QualType Ty) { + getNodeDelegate().AddChild([=] { getNodeDelegate().Visit(Value, Ty); }); + } + void Visit(const comments::Comment *C, const comments::FullComment *FC) { getNodeDelegate().AddChild([=] { getNodeDelegate().Visit(C, FC); @@ -228,7 +235,7 @@ public: }); } - void Visit(const ast_type_traits::DynTypedNode &N) { + void Visit(const DynTypedNode &N) { // FIXME: Improve this with a switch or a visitor pattern. if (const auto *D = N.get<Decl>()) Visit(D); @@ -353,8 +360,6 @@ public: void VisitTemplateSpecializationType(const TemplateSpecializationType *T) { for (const auto &Arg : *T) Visit(Arg); - if (T->isTypeAlias()) - Visit(T->getAliasedType()); } void VisitObjCObjectPointerType(const ObjCObjectPointerType *T) { Visit(T->getPointeeType()); @@ -548,8 +553,8 @@ public: } void VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D) { - if (const auto *TC = D->getPlaceholderTypeConstraint()) - Visit(TC->getImmediatelyDeclaredConstraint()); + if (const auto *E = D->getPlaceholderTypeConstraint()) + Visit(E); if (D->hasDefaultArgument()) Visit(D->getDefaultArgument(), SourceRange(), D->getDefaultArgStorage().getInheritedFrom(), @@ -658,7 +663,7 @@ public: } void VisitLambdaExpr(const LambdaExpr *Node) { - if (Traversal == ast_type_traits::TK_IgnoreUnlessSpelledInSource) { + if (Traversal == TK_IgnoreUnlessSpelledInSource) { for (unsigned I = 0, N = Node->capture_size(); I != N; ++I) { const auto *C = Node->capture_begin() + I; if (!C->isExplicit()) @@ -683,6 +688,15 @@ public: Visit(A); } + void VisitSubstNonTypeTemplateParmExpr(const SubstNonTypeTemplateParmExpr *E) { + Visit(E->getParameter()); + } + void VisitSubstNonTypeTemplateParmPackExpr( + const SubstNonTypeTemplateParmPackExpr *E) { + Visit(E->getParameterPack()); + Visit(E->getArgumentPack()); + } + void VisitObjCAtCatchStmt(const ObjCAtCatchStmt *Node) { if (const VarDecl *CatchParam = Node->getCatchParamDecl()) Visit(CatchParam); @@ -691,6 +705,11 @@ public: void VisitExpressionTemplateArgument(const TemplateArgument &TA) { Visit(TA.getAsExpr()); } + + void VisitTypeTemplateArgument(const TemplateArgument &TA) { + Visit(TA.getAsType()); + } + void VisitPackTemplateArgument(const TemplateArgument &TA) { for (const auto &TArg : TA.pack_elements()) Visit(TArg); diff --git a/clang/include/clang/AST/ASTTypeTraits.h b/clang/include/clang/AST/ASTTypeTraits.h index 1a12281d039d..328b7bce6ba5 100644 --- a/clang/include/clang/AST/ASTTypeTraits.h +++ b/clang/include/clang/AST/ASTTypeTraits.h @@ -16,6 +16,7 @@ #define LLVM_CLANG_AST_ASTTYPETRAITS_H #include "clang/AST/ASTFwd.h" +#include "clang/AST/DeclCXX.h" #include "clang/AST/NestedNameSpecifier.h" #include "clang/AST/TemplateBase.h" #include "clang/AST/TypeLoc.h" @@ -33,8 +34,6 @@ namespace clang { struct PrintingPolicy; -namespace ast_type_traits { - /// Defines how we descend a level in the AST when we pass /// through expressions. enum TraversalKind { @@ -138,6 +137,7 @@ private: NKI_QualType, NKI_TypeLoc, NKI_LastKindWithoutPointerIdentity = NKI_TypeLoc, + NKI_CXXBaseSpecifier, NKI_CXXCtorInitializer, NKI_NestedNameSpecifier, NKI_Decl, @@ -150,8 +150,8 @@ private: #define TYPE(DERIVED, BASE) NKI_##DERIVED##Type, #include "clang/AST/TypeNodes.inc" NKI_OMPClause, -#define OPENMP_CLAUSE(TextualSpelling, Class) NKI_##Class, -#include "clang/Basic/OpenMPKinds.def" +#define OMP_CLAUSE_CLASS(Enum, Str, Class) NKI_##Class, +#include "llvm/Frontend/OpenMP/OMPKinds.def" NKI_NumberOfKinds }; @@ -200,14 +200,15 @@ KIND_TO_KIND_ID(Decl) KIND_TO_KIND_ID(Stmt) KIND_TO_KIND_ID(Type) KIND_TO_KIND_ID(OMPClause) +KIND_TO_KIND_ID(CXXBaseSpecifier) #define DECL(DERIVED, BASE) KIND_TO_KIND_ID(DERIVED##Decl) #include "clang/AST/DeclNodes.inc" #define STMT(DERIVED, BASE) KIND_TO_KIND_ID(DERIVED) #include "clang/AST/StmtNodes.inc" #define TYPE(DERIVED, BASE) KIND_TO_KIND_ID(DERIVED##Type) #include "clang/AST/TypeNodes.inc" -#define OPENMP_CLAUSE(TextualSpelling, Class) KIND_TO_KIND_ID(Class) -#include "clang/Basic/OpenMPKinds.def" +#define OMP_CLAUSE_CLASS(Enum, Str, Class) KIND_TO_KIND_ID(Class) +#include "llvm/Frontend/OpenMP/OMPKinds.def" #undef KIND_TO_KIND_ID inline raw_ostream &operator<<(raw_ostream &OS, ASTNodeKind K) { @@ -277,7 +278,7 @@ public: void print(llvm::raw_ostream &OS, const PrintingPolicy &PP) const; /// Dumps the node to the given output stream. - void dump(llvm::raw_ostream &OS, SourceManager &SM) const; + void dump(llvm::raw_ostream &OS, const ASTContext &Context) const; /// For nodes which represent textual entities in the source code, /// return their SourceRange. For all other nodes, return SourceRange(). @@ -465,22 +466,22 @@ private: template <typename T> struct DynTypedNode::BaseConverter< - T, typename std::enable_if<std::is_base_of<Decl, T>::value>::type> + T, std::enable_if_t<std::is_base_of<Decl, T>::value>> : public DynCastPtrConverter<T, Decl> {}; template <typename T> struct DynTypedNode::BaseConverter< - T, typename std::enable_if<std::is_base_of<Stmt, T>::value>::type> + T, std::enable_if_t<std::is_base_of<Stmt, T>::value>> : public DynCastPtrConverter<T, Stmt> {}; template <typename T> struct DynTypedNode::BaseConverter< - T, typename std::enable_if<std::is_base_of<Type, T>::value>::type> + T, std::enable_if_t<std::is_base_of<Type, T>::value>> : public DynCastPtrConverter<T, Type> {}; template <typename T> struct DynTypedNode::BaseConverter< - T, typename std::enable_if<std::is_base_of<OMPClause, T>::value>::type> + T, std::enable_if_t<std::is_base_of<OMPClause, T>::value>> : public DynCastPtrConverter<T, OMPClause> {}; template <> @@ -512,6 +513,10 @@ template <> struct DynTypedNode::BaseConverter< TypeLoc, void> : public ValueConverter<TypeLoc> {}; +template <> +struct DynTypedNode::BaseConverter<CXXBaseSpecifier, void> + : public PtrConverter<CXXBaseSpecifier> {}; + // The only operation we allow on unsupported types is \c get. // This allows to conveniently use \c DynTypedNode when having an arbitrary // AST node that is not supported, but prevents misuse - a user cannot create @@ -522,18 +527,29 @@ template <typename T, typename EnablerT> struct DynTypedNode::BaseConverter { } }; -} // end namespace ast_type_traits +// Previously these types were defined in the clang::ast_type_traits namespace. +// Provide typedefs so that legacy code can be fixed asynchronously. +namespace ast_type_traits { +using DynTypedNode = ::clang::DynTypedNode; +using ASTNodeKind = ::clang::ASTNodeKind; +using TraversalKind = ::clang::TraversalKind; + +constexpr TraversalKind TK_AsIs = ::clang::TK_AsIs; +constexpr TraversalKind TK_IgnoreImplicitCastsAndParentheses = + ::clang::TK_IgnoreImplicitCastsAndParentheses; +constexpr TraversalKind TK_IgnoreUnlessSpelledInSource = + ::clang::TK_IgnoreUnlessSpelledInSource; +} // namespace ast_type_traits + } // end namespace clang namespace llvm { template <> -struct DenseMapInfo<clang::ast_type_traits::ASTNodeKind> - : clang::ast_type_traits::ASTNodeKind::DenseMapInfo {}; +struct DenseMapInfo<clang::ASTNodeKind> : clang::ASTNodeKind::DenseMapInfo {}; template <> -struct DenseMapInfo<clang::ast_type_traits::DynTypedNode> - : clang::ast_type_traits::DynTypedNode::DenseMapInfo {}; +struct DenseMapInfo<clang::DynTypedNode> : clang::DynTypedNode::DenseMapInfo {}; } // end namespace llvm diff --git a/clang/include/clang/AST/Attr.h b/clang/include/clang/AST/Attr.h index bbaa46363d97..1b457337d658 100644 --- a/clang/include/clang/AST/Attr.h +++ b/clang/include/clang/AST/Attr.h @@ -13,13 +13,13 @@ #ifndef LLVM_CLANG_AST_ATTR_H #define LLVM_CLANG_AST_ATTR_H -#include "clang/AST/ASTContextAllocate.h" // For Attrs.inc +#include "clang/AST/ASTFwd.h" #include "clang/AST/AttrIterator.h" #include "clang/AST/Decl.h" -#include "clang/AST/Expr.h" #include "clang/AST/Type.h" #include "clang/Basic/AttrKinds.h" #include "clang/Basic/AttributeCommonInfo.h" +#include "clang/Basic/LangOptions.h" #include "clang/Basic/LLVM.h" #include "clang/Basic/OpenMPKinds.h" #include "clang/Basic/Sanitizers.h" @@ -40,6 +40,7 @@ class Expr; class QualType; class FunctionDecl; class TypeSourceInfo; +class OMPTraitInfo; /// Attr - This represents one attribute. class Attr : public AttributeCommonInfo { diff --git a/clang/include/clang/AST/BuiltinTypes.def b/clang/include/clang/AST/BuiltinTypes.def index 74a45ee4ccc0..039765dfdfea 100644 --- a/clang/include/clang/AST/BuiltinTypes.def +++ b/clang/include/clang/AST/BuiltinTypes.def @@ -212,6 +212,9 @@ FLOATING_TYPE(LongDouble, LongDoubleTy) // '_Float16' FLOATING_TYPE(Float16, HalfTy) +// '__bf16' +FLOATING_TYPE(BFloat16, BFloat16Ty) + // '__float128' FLOATING_TYPE(Float128, Float128Ty) @@ -310,11 +313,20 @@ PLACEHOLDER_TYPE(BuiltinFn, BuiltinFnTy) // context. PLACEHOLDER_TYPE(ARCUnbridgedCast, ARCUnbridgedCastTy) +// A placeholder type for incomplete matrix index expressions. +PLACEHOLDER_TYPE(IncompleteMatrixIdx, IncompleteMatrixIdxTy) + // A placeholder type for OpenMP array sections. PLACEHOLDER_TYPE(OMPArraySection, OMPArraySectionTy) +// A placeholder type for OpenMP array shaping operation. +PLACEHOLDER_TYPE(OMPArrayShaping, OMPArrayShapingTy) + +// A placeholder type for OpenMP iterators. +PLACEHOLDER_TYPE(OMPIterator, OMPIteratorTy) + #ifdef LAST_BUILTIN_TYPE -LAST_BUILTIN_TYPE(OMPArraySection) +LAST_BUILTIN_TYPE(OMPIterator) #undef LAST_BUILTIN_TYPE #endif diff --git a/clang/include/clang/AST/CXXInheritance.h b/clang/include/clang/AST/CXXInheritance.h index f223c1f2f4f0..8b1bcb367b3b 100644 --- a/clang/include/clang/AST/CXXInheritance.h +++ b/clang/include/clang/AST/CXXInheritance.h @@ -119,7 +119,7 @@ class CXXBasePaths { friend class CXXRecordDecl; /// The type from which this search originated. - CXXRecordDecl *Origin = nullptr; + const CXXRecordDecl *Origin = nullptr; /// Paths - The actual set of paths that can be taken from the /// derived class to the same base class. @@ -225,8 +225,8 @@ public: /// Retrieve the type from which this base-paths search /// began - CXXRecordDecl *getOrigin() const { return Origin; } - void setOrigin(CXXRecordDecl *Rec) { Origin = Rec; } + const CXXRecordDecl *getOrigin() const { return Origin; } + void setOrigin(const CXXRecordDecl *Rec) { Origin = Rec; } /// Clear the base-paths results. void clear(); diff --git a/clang/include/clang/AST/CXXRecordDeclDefinitionBits.def b/clang/include/clang/AST/CXXRecordDeclDefinitionBits.def index bd4d8247aeca..33e65f8ebf44 100644 --- a/clang/include/clang/AST/CXXRecordDeclDefinitionBits.def +++ b/clang/include/clang/AST/CXXRecordDeclDefinitionBits.def @@ -140,6 +140,7 @@ FIELD(HasInheritedAssignment, 1, NO_MERGE) /// @{ FIELD(NeedOverloadResolutionForCopyConstructor, 1, NO_MERGE) FIELD(NeedOverloadResolutionForMoveConstructor, 1, NO_MERGE) +FIELD(NeedOverloadResolutionForCopyAssignment, 1, NO_MERGE) FIELD(NeedOverloadResolutionForMoveAssignment, 1, NO_MERGE) FIELD(NeedOverloadResolutionForDestructor, 1, NO_MERGE) /// @} @@ -149,6 +150,7 @@ FIELD(NeedOverloadResolutionForDestructor, 1, NO_MERGE) /// @{ FIELD(DefaultedCopyConstructorIsDeleted, 1, NO_MERGE) FIELD(DefaultedMoveConstructorIsDeleted, 1, NO_MERGE) +FIELD(DefaultedCopyAssignmentIsDeleted, 1, NO_MERGE) FIELD(DefaultedMoveAssignmentIsDeleted, 1, NO_MERGE) FIELD(DefaultedDestructorIsDeleted, 1, NO_MERGE) /// @} diff --git a/clang/include/clang/AST/CanonicalType.h b/clang/include/clang/AST/CanonicalType.h index 2e00d344533d..488284713bce 100644 --- a/clang/include/clang/AST/CanonicalType.h +++ b/clang/include/clang/AST/CanonicalType.h @@ -74,7 +74,7 @@ public: /// canonical type pointers. template <typename U> CanQual(const CanQual<U> &Other, - typename std::enable_if<std::is_base_of<T, U>::value, int>::type = 0); + std::enable_if_t<std::is_base_of<T, U>::value, int> = 0); /// Retrieve the underlying type pointer, which refers to a /// canonical type. @@ -264,6 +264,8 @@ public: // Type predicates LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjectType) LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIncompleteType) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSizelessType) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSizelessBuiltinType) LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIncompleteOrObjectType) LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVariablyModifiedType) LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isIntegerType) @@ -384,7 +386,7 @@ struct PointerLikeTypeTraits<clang::CanQual<T>> { } // qualifier information is encoded in the low bits. - enum { NumLowBitsAvailable = 0 }; + static constexpr int NumLowBitsAvailable = 0; }; } // namespace llvm diff --git a/clang/include/clang/AST/Comment.h b/clang/include/clang/AST/Comment.h index cd9c1ce2bce0..54a4b0a9cfe6 100644 --- a/clang/include/clang/AST/Comment.h +++ b/clang/include/clang/AST/Comment.h @@ -209,9 +209,7 @@ public: void dump() const; void dumpColor() const; - void dump(const ASTContext &Context) const; - void dump(raw_ostream &OS, const CommandTraits *Traits, - const SourceManager *SM) const; + void dump(raw_ostream &OS, const ASTContext &Context) const; SourceRange getSourceRange() const LLVM_READONLY { return Range; } diff --git a/clang/include/clang/AST/CommentCommands.td b/clang/include/clang/AST/CommentCommands.td index d387df7ce570..fbbfc9f7e0b7 100644 --- a/clang/include/clang/AST/CommentCommands.td +++ b/clang/include/clang/AST/CommentCommands.td @@ -87,6 +87,7 @@ def P : InlineCommand<"p">; def A : InlineCommand<"a">; def E : InlineCommand<"e">; def Em : InlineCommand<"em">; +def Ref : InlineCommand<"ref">; def Anchor : InlineCommand<"anchor">; //===----------------------------------------------------------------------===// @@ -205,7 +206,6 @@ def Paragraph : VerbatimLineCommand<"paragraph">; def Mainpage : VerbatimLineCommand<"mainpage">; def Subpage : VerbatimLineCommand<"subpage">; -def Ref : VerbatimLineCommand<"ref">; def Relates : VerbatimLineCommand<"relates">; def Related : VerbatimLineCommand<"related">; diff --git a/clang/include/clang/AST/CommentSema.h b/clang/include/clang/AST/CommentSema.h index 307618fa5363..6dfe0f4920d0 100644 --- a/clang/include/clang/AST/CommentSema.h +++ b/clang/include/clang/AST/CommentSema.h @@ -217,6 +217,9 @@ public: bool isTemplateOrSpecialization(); bool isRecordLikeDecl(); bool isClassOrStructDecl(); + /// \return \c true if the declaration that this comment is attached to + /// declares either struct, class or tag typedef. + bool isClassOrStructOrTagTypedefDecl(); bool isUnionDecl(); bool isObjCInterfaceDecl(); bool isObjCProtocolDecl(); diff --git a/clang/include/clang/AST/ComputeDependence.h b/clang/include/clang/AST/ComputeDependence.h new file mode 100644 index 000000000000..ac2daf9eb95a --- /dev/null +++ b/clang/include/clang/AST/ComputeDependence.h @@ -0,0 +1,194 @@ +//===--- ComputeDependence.h -------------------------------------- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// Calculate various template dependency flags for the AST. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_AST_COMPUTE_DEPENDENCE_H +#define LLVM_CLANG_AST_COMPUTE_DEPENDENCE_H + +#include "clang/AST/DependenceFlags.h" +#include "clang/Basic/ExceptionSpecificationType.h" +#include "llvm/ADT/ArrayRef.h" + +namespace clang { + +class ASTContext; + +class Expr; +class FullExpr; +class OpaqueValueExpr; +class ParenExpr; +class UnaryOperator; +class UnaryExprOrTypeTraitExpr; +class ArraySubscriptExpr; +class MatrixSubscriptExpr; +class CompoundLiteralExpr; +class CastExpr; +class BinaryOperator; +class ConditionalOperator; +class BinaryConditionalOperator; +class StmtExpr; +class ConvertVectorExpr; +class VAArgExpr; +class ChooseExpr; +class NoInitExpr; +class ArrayInitLoopExpr; +class ImplicitValueInitExpr; +class InitListExpr; +class ExtVectorElementExpr; +class BlockExpr; +class AsTypeExpr; +class DeclRefExpr; +class RecoveryExpr; +class CXXRewrittenBinaryOperator; +class CXXStdInitializerListExpr; +class CXXTypeidExpr; +class MSPropertyRefExpr; +class MSPropertySubscriptExpr; +class CXXUuidofExpr; +class CXXThisExpr; +class CXXThrowExpr; +class CXXBindTemporaryExpr; +class CXXScalarValueInitExpr; +class CXXDeleteExpr; +class ArrayTypeTraitExpr; +class ExpressionTraitExpr; +class CXXNoexceptExpr; +class PackExpansionExpr; +class SubstNonTypeTemplateParmExpr; +class CoroutineSuspendExpr; +class DependentCoawaitExpr; +class CXXNewExpr; +class CXXPseudoDestructorExpr; +class OverloadExpr; +class DependentScopeDeclRefExpr; +class CXXConstructExpr; +class LambdaExpr; +class CXXUnresolvedConstructExpr; +class CXXDependentScopeMemberExpr; +class MaterializeTemporaryExpr; +class CXXFoldExpr; +class TypeTraitExpr; +class ConceptSpecializationExpr; +class PredefinedExpr; +class CallExpr; +class OffsetOfExpr; +class MemberExpr; +class ShuffleVectorExpr; +class GenericSelectionExpr; +class DesignatedInitExpr; +class ParenListExpr; +class PseudoObjectExpr; +class AtomicExpr; +class OMPArraySectionExpr; +class OMPArrayShapingExpr; +class OMPIteratorExpr; +class ObjCArrayLiteral; +class ObjCDictionaryLiteral; +class ObjCBoxedExpr; +class ObjCEncodeExpr; +class ObjCIvarRefExpr; +class ObjCPropertyRefExpr; +class ObjCSubscriptRefExpr; +class ObjCIsaExpr; +class ObjCIndirectCopyRestoreExpr; +class ObjCMessageExpr; + +// The following functions are called from constructors of `Expr`, so they +// should not access anything beyond basic +ExprDependence computeDependence(FullExpr *E); +ExprDependence computeDependence(OpaqueValueExpr *E); +ExprDependence computeDependence(ParenExpr *E); +ExprDependence computeDependence(UnaryOperator *E); +ExprDependence computeDependence(UnaryExprOrTypeTraitExpr *E); +ExprDependence computeDependence(ArraySubscriptExpr *E); +ExprDependence computeDependence(MatrixSubscriptExpr *E); +ExprDependence computeDependence(CompoundLiteralExpr *E); +ExprDependence computeDependence(CastExpr *E); +ExprDependence computeDependence(BinaryOperator *E); +ExprDependence computeDependence(ConditionalOperator *E); +ExprDependence computeDependence(BinaryConditionalOperator *E); +ExprDependence computeDependence(StmtExpr *E, unsigned TemplateDepth); +ExprDependence computeDependence(ConvertVectorExpr *E); +ExprDependence computeDependence(VAArgExpr *E); +ExprDependence computeDependence(ChooseExpr *E); +ExprDependence computeDependence(NoInitExpr *E); +ExprDependence computeDependence(ArrayInitLoopExpr *E); +ExprDependence computeDependence(ImplicitValueInitExpr *E); +ExprDependence computeDependence(InitListExpr *E); +ExprDependence computeDependence(ExtVectorElementExpr *E); +ExprDependence computeDependence(BlockExpr *E); +ExprDependence computeDependence(AsTypeExpr *E); +ExprDependence computeDependence(DeclRefExpr *E, const ASTContext &Ctx); +ExprDependence computeDependence(RecoveryExpr *E); +ExprDependence computeDependence(CXXRewrittenBinaryOperator *E); +ExprDependence computeDependence(CXXStdInitializerListExpr *E); +ExprDependence computeDependence(CXXTypeidExpr *E); +ExprDependence computeDependence(MSPropertyRefExpr *E); +ExprDependence computeDependence(MSPropertySubscriptExpr *E); +ExprDependence computeDependence(CXXUuidofExpr *E); +ExprDependence computeDependence(CXXThisExpr *E); +ExprDependence computeDependence(CXXThrowExpr *E); +ExprDependence computeDependence(CXXBindTemporaryExpr *E); +ExprDependence computeDependence(CXXScalarValueInitExpr *E); +ExprDependence computeDependence(CXXDeleteExpr *E); +ExprDependence computeDependence(ArrayTypeTraitExpr *E); +ExprDependence computeDependence(ExpressionTraitExpr *E); +ExprDependence computeDependence(CXXNoexceptExpr *E, CanThrowResult CT); +ExprDependence computeDependence(PackExpansionExpr *E); +ExprDependence computeDependence(SubstNonTypeTemplateParmExpr *E); +ExprDependence computeDependence(CoroutineSuspendExpr *E); +ExprDependence computeDependence(DependentCoawaitExpr *E); +ExprDependence computeDependence(CXXNewExpr *E); +ExprDependence computeDependence(CXXPseudoDestructorExpr *E); +ExprDependence computeDependence(OverloadExpr *E, bool KnownDependent, + bool KnownInstantiationDependent, + bool KnownContainsUnexpandedParameterPack); +ExprDependence computeDependence(DependentScopeDeclRefExpr *E); +ExprDependence computeDependence(CXXConstructExpr *E); +ExprDependence computeDependence(LambdaExpr *E, + bool ContainsUnexpandedParameterPack); +ExprDependence computeDependence(CXXUnresolvedConstructExpr *E); +ExprDependence computeDependence(CXXDependentScopeMemberExpr *E); +ExprDependence computeDependence(MaterializeTemporaryExpr *E); +ExprDependence computeDependence(CXXFoldExpr *E); +ExprDependence computeDependence(TypeTraitExpr *E); +ExprDependence computeDependence(ConceptSpecializationExpr *E, + bool ValueDependent); + +ExprDependence computeDependence(PredefinedExpr *E); +ExprDependence computeDependence(CallExpr *E, llvm::ArrayRef<Expr *> PreArgs); +ExprDependence computeDependence(OffsetOfExpr *E); +ExprDependence computeDependence(MemberExpr *E); +ExprDependence computeDependence(ShuffleVectorExpr *E); +ExprDependence computeDependence(GenericSelectionExpr *E, + bool ContainsUnexpandedPack); +ExprDependence computeDependence(DesignatedInitExpr *E); +ExprDependence computeDependence(ParenListExpr *E); +ExprDependence computeDependence(PseudoObjectExpr *E); +ExprDependence computeDependence(AtomicExpr *E); + +ExprDependence computeDependence(OMPArraySectionExpr *E); +ExprDependence computeDependence(OMPArrayShapingExpr *E); +ExprDependence computeDependence(OMPIteratorExpr *E); + +ExprDependence computeDependence(ObjCArrayLiteral *E); +ExprDependence computeDependence(ObjCDictionaryLiteral *E); +ExprDependence computeDependence(ObjCBoxedExpr *E); +ExprDependence computeDependence(ObjCEncodeExpr *E); +ExprDependence computeDependence(ObjCIvarRefExpr *E); +ExprDependence computeDependence(ObjCPropertyRefExpr *E); +ExprDependence computeDependence(ObjCSubscriptRefExpr *E); +ExprDependence computeDependence(ObjCIsaExpr *E); +ExprDependence computeDependence(ObjCIndirectCopyRestoreExpr *E); +ExprDependence computeDependence(ObjCMessageExpr *E); + +} // namespace clang +#endif diff --git a/clang/include/clang/AST/DataCollection.h b/clang/include/clang/AST/DataCollection.h index 37f101793ecc..14d1bc188623 100644 --- a/clang/include/clang/AST/DataCollection.h +++ b/clang/include/clang/AST/DataCollection.h @@ -50,10 +50,9 @@ template <class T> void addDataToConsumer(T &DataConsumer, const QualType &QT) { } template <class T, class Type> -typename std::enable_if< - std::is_integral<Type>::value || std::is_enum<Type>::value || - std::is_convertible<Type, size_t>::value // for llvm::hash_code - >::type +std::enable_if_t<std::is_integral<Type>::value || std::is_enum<Type>::value || + std::is_convertible<Type, size_t>::value // for llvm::hash_code + > addDataToConsumer(T &DataConsumer, Type Data) { DataConsumer.update(StringRef(reinterpret_cast<char *>(&Data), sizeof(Data))); } diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h index 43c6c7b85db4..28faa2c1fc78 100644 --- a/clang/include/clang/AST/Decl.h +++ b/clang/include/clang/AST/Decl.h @@ -2030,7 +2030,7 @@ public: /// declaration to the declaration that is a definition (if there is one). bool isDefined(const FunctionDecl *&Definition) const; - virtual bool isDefined() const { + bool isDefined() const { const FunctionDecl* Definition; return isDefined(Definition); } @@ -2125,19 +2125,17 @@ public: bool isTrivialForCall() const { return FunctionDeclBits.IsTrivialForCall; } void setTrivialForCall(bool IT) { FunctionDeclBits.IsTrivialForCall = IT; } - /// Whether this function is defaulted per C++0x. Only valid for - /// special member functions. + /// Whether this function is defaulted. Valid for e.g. + /// special member functions, defaulted comparisions (not methods!). bool isDefaulted() const { return FunctionDeclBits.IsDefaulted; } void setDefaulted(bool D = true) { FunctionDeclBits.IsDefaulted = D; } - /// Whether this function is explicitly defaulted per C++0x. Only valid - /// for special member functions. + /// Whether this function is explicitly defaulted. bool isExplicitlyDefaulted() const { return FunctionDeclBits.IsExplicitlyDefaulted; } - /// State that this function is explicitly defaulted per C++0x. Only valid - /// for special member functions. + /// State that this function is explicitly defaulted. void setExplicitlyDefaulted(bool ED = true) { FunctionDeclBits.IsExplicitlyDefaulted = ED; } @@ -2306,8 +2304,13 @@ public: /// allocation function. [...] /// /// If this function is an aligned allocation/deallocation function, return - /// true through IsAligned. - bool isReplaceableGlobalAllocationFunction(bool *IsAligned = nullptr) const; + /// the parameter number of the requested alignment through AlignmentParam. + /// + /// If this function is an allocation/deallocation function that takes + /// the `std::nothrow_t` tag, return true through IsNothrow, + bool isReplaceableGlobalAllocationFunction( + Optional<unsigned> *AlignmentParam = nullptr, + bool *IsNothrow = nullptr) const; /// Determine if this function provides an inline implementation of a builtin. bool isInlineBuiltinDeclaration() const; @@ -2436,6 +2439,14 @@ public: /// parameters have default arguments (in C++). unsigned getMinRequiredArguments() const; + /// Determine whether this function has a single parameter, or multiple + /// parameters where all but the first have default arguments. + /// + /// This notion is used in the definition of copy/move constructors and + /// initializer list constructors. Note that, unlike getMinRequiredArguments, + /// parameter packs are not treated specially here. + bool hasOneParamOrDefaultArgs() const; + /// Find the source location information for how the type of this function /// was written. May be absent (for example if the function was declared via /// a typedef) and may contain a different type from that of the function @@ -2607,7 +2618,13 @@ public: /// Retrieve the function declaration from which this function could /// be instantiated, if it is an instantiation (rather than a non-template /// or a specialization, for example). - FunctionDecl *getTemplateInstantiationPattern() const; + /// + /// If \p ForDefinition is \c false, explicit specializations will be treated + /// as if they were implicit instantiations. This will then find the pattern + /// corresponding to non-definition portions of the declaration, such as + /// default arguments and the exception specification. + FunctionDecl * + getTemplateInstantiationPattern(bool ForDefinition = true) const; /// Retrieve the primary template that this function template /// specialization either specializes or was instantiated from. @@ -2915,12 +2932,15 @@ public: /// Returns the parent of this field declaration, which /// is the struct in which this field is defined. + /// + /// Returns null if this is not a normal class/struct field declaration, e.g. + /// ObjCAtDefsFieldDecl, ObjCIvarDecl. const RecordDecl *getParent() const { - return cast<RecordDecl>(getDeclContext()); + return dyn_cast<RecordDecl>(getDeclContext()); } RecordDecl *getParent() { - return cast<RecordDecl>(getDeclContext()); + return dyn_cast<RecordDecl>(getDeclContext()); } SourceRange getSourceRange() const override LLVM_READONLY; @@ -3534,6 +3554,7 @@ class EnumDecl : public TagDecl { /// negative enumerators of this enum. (see getNumNegativeBits) void setNumNegativeBits(unsigned Num) { EnumDeclBits.NumNegativeBits = Num; } +public: /// True if this tag declaration is a scoped enumeration. Only /// possible in C++11 mode. void setScoped(bool Scoped = true) { EnumDeclBits.IsScoped = Scoped; } @@ -3550,6 +3571,7 @@ class EnumDecl : public TagDecl { /// Microsoft-style enumeration with a fixed underlying type. void setFixed(bool Fixed = true) { EnumDeclBits.IsFixed = Fixed; } +private: /// True if a valid hash is stored in ODRHash. bool hasODRHash() const { return EnumDeclBits.HasODRHash; } void setHasODRHash(bool Hash = true) { EnumDeclBits.HasODRHash = Hash; } @@ -3954,6 +3976,11 @@ public: return cast_or_null<RecordDecl>(TagDecl::getDefinition()); } + /// Returns whether this record is a union, or contains (at any nesting level) + /// a union member. This is used by CMSE to warn about possible information + /// leaks. + bool isOrContainsUnion() const; + // Iterator access to field members. The field iterator only visits // the non-static data members of this class, ignoring any static // data members, functions, constructors, destructors, etc. @@ -4335,17 +4362,18 @@ class ImportDecl final : public Decl, friend class ASTReader; friend TrailingObjects; - /// The imported module, along with a bit that indicates whether - /// we have source-location information for each identifier in the module - /// name. - /// - /// When the bit is false, we only have a single source location for the - /// end of the import declaration. - llvm::PointerIntPair<Module *, 1, bool> ImportedAndComplete; + /// The imported module. + Module *ImportedModule = nullptr; /// The next import in the list of imports local to the translation /// unit being parsed (not loaded from an AST file). - ImportDecl *NextLocalImport = nullptr; + /// + /// Includes a bit that indicates whether we have source-location information + /// for each identifier in the module name. + /// + /// When the bit is false, we only have a single source location for the + /// end of the import declaration. + llvm::PointerIntPair<ImportDecl *, 1, bool> NextLocalImportAndComplete; ImportDecl(DeclContext *DC, SourceLocation StartLoc, Module *Imported, ArrayRef<SourceLocation> IdentifierLocs); @@ -4355,6 +4383,20 @@ class ImportDecl final : public Decl, ImportDecl(EmptyShell Empty) : Decl(Import, Empty) {} + bool isImportComplete() const { return NextLocalImportAndComplete.getInt(); } + + void setImportComplete(bool C) { NextLocalImportAndComplete.setInt(C); } + + /// The next import in the list of imports local to the translation + /// unit being parsed (not loaded from an AST file). + ImportDecl *getNextLocalImport() const { + return NextLocalImportAndComplete.getPointer(); + } + + void setNextLocalImport(ImportDecl *Import) { + NextLocalImportAndComplete.setPointer(Import); + } + public: /// Create a new module import declaration. static ImportDecl *Create(ASTContext &C, DeclContext *DC, @@ -4372,7 +4414,7 @@ public: unsigned NumLocations); /// Retrieve the module that was imported by the import declaration. - Module *getImportedModule() const { return ImportedAndComplete.getPointer(); } + Module *getImportedModule() const { return ImportedModule; } /// Retrieves the locations of each of the identifiers that make up /// the complete module name in the import declaration. @@ -4520,6 +4562,13 @@ inline bool IsEnumDeclScoped(EnumDecl *ED) { return ED->isScoped(); } +/// OpenMP variants are mangled early based on their OpenMP context selector. +/// The new name looks likes this: +/// <name> + OpenMPVariantManglingSeparatorStr + <mangled OpenMP context> +static constexpr StringRef getOpenMPVariantManglingSeparatorStr() { + return "$ompvariant"; +} + } // namespace clang #endif // LLVM_CLANG_AST_DECL_H diff --git a/clang/include/clang/AST/DeclBase.h b/clang/include/clang/AST/DeclBase.h index 91c372585b07..4f33ff104ffd 100644 --- a/clang/include/clang/AST/DeclBase.h +++ b/clang/include/clang/AST/DeclBase.h @@ -66,6 +66,7 @@ class SourceManager; class Stmt; class StoredDeclsMap; class TemplateDecl; +class TemplateParameterList; class TranslationUnitDecl; class UsingDirectiveDecl; @@ -465,6 +466,10 @@ public: ASTContext &getASTContext() const LLVM_READONLY; + /// Helper to get the language options from the ASTContext. + /// Defined out of line to avoid depending on ASTContext.h. + const LangOptions &getLangOpts() const LLVM_READONLY; + void setAccess(AccessSpecifier AS) { Access = AS; assert(AccessDeclContextSanity()); @@ -514,7 +519,7 @@ public: if (!HasAttrs) return; AttrVec &Vec = getAttrs(); - Vec.erase(std::remove_if(Vec.begin(), Vec.end(), isa<T, Attr*>), Vec.end()); + llvm::erase_if(Vec, [](Attr *A) { return isa<T>(A); }); if (Vec.empty()) HasAttrs = false; @@ -626,7 +631,16 @@ protected: setModuleOwnershipKind(ModuleOwnershipKind::ModulePrivate); } - /// Set the owning module ID. +public: + /// Set the FromASTFile flag. This indicates that this declaration + /// was deserialized and not parsed from source code and enables + /// features such as module ownership information. + void setFromASTFile() { + FromASTFile = true; + } + + /// Set the owning module ID. This may only be called for + /// deserialized Decls. void setOwningModuleID(unsigned ID) { assert(isFromASTFile() && "Only works on a deserialized declaration"); *((unsigned*)this - 2) = ID; @@ -767,18 +781,19 @@ public: /// all declarations in a global module fragment are unowned. Module *getOwningModuleForLinkage(bool IgnoreLinkage = false) const; - /// Determine whether this declaration might be hidden from name - /// lookup. Note that the declaration might be visible even if this returns - /// \c false, if the owning module is visible within the query context. - // FIXME: Rename this to make it clearer what it does. - bool isHidden() const { - return (int)getModuleOwnershipKind() > (int)ModuleOwnershipKind::Visible; + /// Determine whether this declaration is definitely visible to name lookup, + /// independent of whether the owning module is visible. + /// Note: The declaration may be visible even if this returns \c false if the + /// owning module is visible within the query context. This is a low-level + /// helper function; most code should be calling Sema::isVisible() instead. + bool isUnconditionallyVisible() const { + return (int)getModuleOwnershipKind() <= (int)ModuleOwnershipKind::Visible; } /// Set that this declaration is globally visible, even if it came from a /// module that is not visible. void setVisibleDespiteOwningModule() { - if (isHidden()) + if (!isUnconditionallyVisible()) setModuleOwnershipKind(ModuleOwnershipKind::Visible); } @@ -848,6 +863,10 @@ public: // within the scope of a template parameter). bool isTemplated() const; + /// Determine the number of levels of template parameter surrounding this + /// declaration. + unsigned getTemplateDepth() const; + /// isDefinedOutsideFunctionOrMethod - This predicate returns true if this /// scoped decl is defined outside the current function or method. This is /// roughly global variables and functions, but also handles enums (which @@ -856,14 +875,19 @@ public: return getParentFunctionOrMethod() == nullptr; } - /// Returns true if this declaration lexically is inside a function. - /// It recognizes non-defining declarations as well as members of local - /// classes: + /// Determine whether a substitution into this declaration would occur as + /// part of a substitution into a dependent local scope. Such a substitution + /// transitively substitutes into all constructs nested within this + /// declaration. + /// + /// This recognizes non-defining declarations as well as members of local + /// classes and lambdas: /// \code - /// void foo() { void bar(); } - /// void foo2() { class ABC { void bar(); }; } + /// template<typename T> void foo() { void bar(); } + /// template<typename T> void foo2() { class ABC { void bar(); }; } + /// template<typename T> inline int x = [](){ return 0; }(); /// \endcode - bool isLexicallyWithinFunctionOrMethod() const; + bool isInLocalScopeForInstantiation() const; /// If this decl is defined inside a function/method/block it returns /// the corresponding DeclContext, otherwise it returns null. @@ -1023,8 +1047,16 @@ public: /// If this is a declaration that describes some template, this /// method returns that template declaration. + /// + /// Note that this returns nullptr for partial specializations, because they + /// are not modeled as TemplateDecls. Use getDescribedTemplateParams to handle + /// those cases. TemplateDecl *getDescribedTemplate() const; + /// If this is a declaration that describes some template or partial + /// specialization, this returns the corresponding template parameter list. + const TemplateParameterList *getDescribedTemplateParams() const; + /// Returns the function itself, or the templated function if this is a /// function template. FunctionDecl *getAsFunction() LLVM_READONLY; diff --git a/clang/include/clang/AST/DeclCXX.h b/clang/include/clang/AST/DeclCXX.h index b716ea453a5a..2b8d7e879a0a 100644 --- a/clang/include/clang/AST/DeclCXX.h +++ b/clang/include/clang/AST/DeclCXX.h @@ -15,7 +15,6 @@ #ifndef LLVM_CLANG_AST_DECLCXX_H #define LLVM_CLANG_AST_DECLCXX_H -#include "clang/AST/ASTContext.h" #include "clang/AST/ASTUnresolvedSet.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclBase.h" @@ -40,6 +39,7 @@ #include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/PointerUnion.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/TinyPtrVector.h" #include "llvm/ADT/iterator_range.h" #include "llvm/Support/Casting.h" #include "llvm/Support/Compiler.h" @@ -53,6 +53,7 @@ namespace clang { +class ASTContext; class ClassTemplateDecl; class ConstructorUsingShadowDecl; class CXXBasePath; @@ -712,6 +713,13 @@ public: } /// \c true if we know for sure that this class has a single, + /// accessible, unambiguous copy assignment operator that is not deleted. + bool hasSimpleCopyAssignment() const { + return !hasUserDeclaredCopyAssignment() && + !data().DefaultedCopyAssignmentIsDeleted; + } + + /// \c true if we know for sure that this class has a single, /// accessible, unambiguous move assignment operator that is not deleted. bool hasSimpleMoveAssignment() const { return !hasUserDeclaredMoveAssignment() && hasMoveAssignment() && @@ -871,6 +879,15 @@ public: return data().UserDeclaredSpecialMembers & SMF_CopyAssignment; } + /// Set that we attempted to declare an implicit copy assignment + /// operator, but overload resolution failed so we deleted it. + void setImplicitCopyAssignmentIsDeleted() { + assert((data().DefaultedCopyAssignmentIsDeleted || + needsOverloadResolutionForCopyAssignment()) && + "copy assignment should not be deleted"); + data().DefaultedCopyAssignmentIsDeleted = true; + } + /// Determine whether this class needs an implicit copy /// assignment operator to be lazily declared. bool needsImplicitCopyAssignment() const { @@ -880,7 +897,16 @@ public: /// Determine whether we need to eagerly declare a defaulted copy /// assignment operator for this class. bool needsOverloadResolutionForCopyAssignment() const { - return data().HasMutableFields; + // C++20 [class.copy.assign]p2: + // If the class definition declares a move constructor or move assignment + // operator, the implicitly declared copy assignment operator is defined + // as deleted. + // In MSVC mode, sometimes a declared move constructor does not delete an + // implicit copy assignment, so defer this choice to Sema. + if (data().UserDeclaredSpecialMembers & + (SMF_MoveConstructor | SMF_MoveAssignment)) + return true; + return data().NeedOverloadResolutionForCopyAssignment; } /// Determine whether an implicit copy assignment operator for this @@ -998,6 +1024,9 @@ public: return static_cast<LambdaCaptureDefault>(getLambdaData().CaptureDefault); } + /// Set the captures for this lambda closure type. + void setCaptures(ArrayRef<LambdaCapture> Captures); + /// For a closure type, retrieve the mapping from captured /// variables and \c this to the non-static data members that store the /// values or references of the captures. @@ -1029,6 +1058,8 @@ public: : nullptr; } + unsigned capture_size() const { return getLambdaData().NumCaptures; } + using conversion_iterator = UnresolvedSetIterator; conversion_iterator conversion_begin() const { @@ -1166,7 +1197,7 @@ public: bool defaultedDefaultConstructorIsConstexpr() const { return data().DefaultedDefaultConstructorIsConstexpr && (!isUnion() || hasInClassInitializer() || !hasVariantMembers() || - getASTContext().getLangOpts().CPlusPlus2a); + getLangOpts().CPlusPlus20); } /// Determine whether this class has a constexpr default constructor. @@ -1258,7 +1289,7 @@ public: /// would be constexpr. bool defaultedDestructorIsConstexpr() const { return data().DefaultedDestructorIsConstexpr && - getASTContext().getLangOpts().CPlusPlus2a; + getLangOpts().CPlusPlus20; } /// Determine whether this class has a constexpr destructor. @@ -1355,10 +1386,10 @@ public: /// /// Only in C++17 and beyond, are lambdas literal types. bool isLiteral() const { - ASTContext &Ctx = getASTContext(); - return (Ctx.getLangOpts().CPlusPlus2a ? hasConstexprDestructor() + const LangOptions &LangOpts = getLangOpts(); + return (LangOpts.CPlusPlus20 ? hasConstexprDestructor() : hasTrivialDestructor()) && - (!isLambda() || Ctx.getLangOpts().CPlusPlus17) && + (!isLambda() || LangOpts.CPlusPlus17) && !hasNonLiteralTypeFieldsOrBases() && (isAggregate() || isLambda() || hasConstexprNonCopyMoveConstructor() || @@ -1517,14 +1548,8 @@ public: /// returns false if the class has non-computable base classes. /// /// \param BaseMatches Callback invoked for each (direct or indirect) base - /// class of this type, or if \p AllowShortCircuit is true then until a call - /// returns false. - /// - /// \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, - bool AllowShortCircuit = true) const; + /// class of this type until a call returns false. + bool forallBases(ForallBasesCallback BaseMatches) const; /// Function type used by lookupInBases() to determine whether a /// specific base class subobject matches the lookup criteria. @@ -1696,6 +1721,10 @@ public: /// actually abstract. bool mayBeAbstract() const; + /// Determine whether it's impossible for a class to be derived from this + /// class. This is best-effort, and may conservatively return false. + bool isEffectivelyFinal() const; + /// If this is the closure type of a lambda expression, retrieve the /// number to be used for name mangling in the Itanium C++ ABI. /// @@ -1893,6 +1922,37 @@ public: static bool classofKind(Kind K) { return K == CXXDeductionGuide; } }; +/// \brief Represents the body of a requires-expression. +/// +/// This decl exists merely to serve as the DeclContext for the local +/// parameters of the requires expression as well as other declarations inside +/// it. +/// +/// \code +/// template<typename T> requires requires (T t) { {t++} -> regular; } +/// \endcode +/// +/// In this example, a RequiresExpr object will be generated for the expression, +/// and a RequiresExprBodyDecl will be created to hold the parameter t and the +/// template argument list imposed by the compound requirement. +class RequiresExprBodyDecl : public Decl, public DeclContext { + RequiresExprBodyDecl(ASTContext &C, DeclContext *DC, SourceLocation StartLoc) + : Decl(RequiresExprBody, DC, StartLoc), DeclContext(RequiresExprBody) {} + +public: + friend class ASTDeclReader; + friend class ASTDeclWriter; + + static RequiresExprBodyDecl *Create(ASTContext &C, DeclContext *DC, + SourceLocation StartLoc); + + static RequiresExprBodyDecl *CreateDeserialized(ASTContext &C, unsigned ID); + + // Implement isa/cast/dyncast/etc. + static bool classof(const Decl *D) { return classofKind(D->getKind()); } + static bool classofKind(Kind K) { return K == RequiresExprBody; } +}; + /// Represents a static or instance method of a struct/union/class. /// /// In the terminology of the C++ Standard, these are the (static and @@ -2006,7 +2066,8 @@ public: method_iterator end_overridden_methods() const; unsigned size_overridden_methods() const; - using overridden_method_range= ASTContext::overridden_method_range; + using overridden_method_range = llvm::iterator_range< + llvm::TinyPtrVector<const CXXMethodDecl *>::const_iterator>; overridden_method_range overridden_methods() const; @@ -2386,17 +2447,6 @@ class CXXConstructorDecl final : ExplicitSpecKind::ResolvedFalse); } - void setExplicitSpecifier(ExplicitSpecifier ES) { - assert((!ES.getExpr() || - CXXConstructorDeclBits.HasTrailingExplicitSpecifier) && - "cannot set this explicit specifier. no trail-allocated space for " - "explicit"); - if (ES.getExpr()) - *getCanonicalDecl()->getTrailingObjects<ExplicitSpecifier>() = ES; - else - CXXConstructorDeclBits.IsSimpleExplicit = ES.isExplicit(); - } - enum TraillingAllocKind { TAKInheritsConstructor = 1, TAKHasTailExplicit = 1 << 1, @@ -2422,6 +2472,17 @@ public: InheritedConstructor Inherited = InheritedConstructor(), Expr *TrailingRequiresClause = nullptr); + void setExplicitSpecifier(ExplicitSpecifier ES) { + assert((!ES.getExpr() || + CXXConstructorDeclBits.HasTrailingExplicitSpecifier) && + "cannot set this explicit specifier. no trail-allocated space for " + "explicit"); + if (ES.getExpr()) + *getCanonicalDecl()->getTrailingObjects<ExplicitSpecifier>() = ES; + else + CXXConstructorDeclBits.IsSimpleExplicit = ES.isExplicit(); + } + ExplicitSpecifier getExplicitSpecifier() { return getCanonicalDecl()->getExplicitSpecifierInternal(); } @@ -2693,8 +2754,6 @@ class CXXConversionDecl : public CXXMethodDecl { ExplicitSpecifier ExplicitSpec; - void setExplicitSpecifier(ExplicitSpecifier ES) { ExplicitSpec = ES; } - public: friend class ASTDeclReader; friend class ASTDeclWriter; @@ -2716,6 +2775,7 @@ public: /// Return true if the declartion is already resolved to be explicit. bool isExplicit() const { return getExplicitSpecifier().isExplicit(); } + void setExplicitSpecifier(ExplicitSpecifier ES) { ExplicitSpec = ES; } /// Returns the type that this conversion function is converting to. QualType getConversionType() const { @@ -3933,6 +3993,81 @@ public: IdentifierInfo* getSetterId() const { return SetterId; } }; +/// Parts of a decomposed MSGuidDecl. Factored out to avoid unnecessary +/// dependencies on DeclCXX.h. +struct MSGuidDeclParts { + /// {01234567-... + uint32_t Part1; + /// ...-89ab-... + uint16_t Part2; + /// ...-cdef-... + uint16_t Part3; + /// ...-0123-456789abcdef} + uint8_t Part4And5[8]; + + uint64_t getPart4And5AsUint64() const { + uint64_t Val; + memcpy(&Val, &Part4And5, sizeof(Part4And5)); + return Val; + } +}; + +/// A global _GUID constant. These are implicitly created by UuidAttrs. +/// +/// struct _declspec(uuid("01234567-89ab-cdef-0123-456789abcdef")) X{}; +/// +/// X is a CXXRecordDecl that contains a UuidAttr that references the (unique) +/// MSGuidDecl for the specified UUID. +class MSGuidDecl : public ValueDecl, + public Mergeable<MSGuidDecl>, + public llvm::FoldingSetNode { +public: + using Parts = MSGuidDeclParts; + +private: + /// The decomposed form of the UUID. + Parts PartVal; + + /// The resolved value of the UUID as an APValue. Computed on demand and + /// cached. + mutable APValue APVal; + + void anchor() override; + + MSGuidDecl(DeclContext *DC, QualType T, Parts P); + + static MSGuidDecl *Create(const ASTContext &C, QualType T, Parts P); + static MSGuidDecl *CreateDeserialized(ASTContext &C, unsigned ID); + + // Only ASTContext::getMSGuidDecl and deserialization create these. + friend class ASTContext; + friend class ASTReader; + friend class ASTDeclReader; + +public: + /// Print this UUID in a human-readable format. + void printName(llvm::raw_ostream &OS) const override; + + /// Get the decomposed parts of this declaration. + Parts getParts() const { return PartVal; } + + /// Get the value of this MSGuidDecl as an APValue. This may fail and return + /// an absent APValue if the type of the declaration is not of the expected + /// shape. + APValue &getAsAPValue() const; + + static void Profile(llvm::FoldingSetNodeID &ID, Parts P) { + ID.AddInteger(P.Part1); + ID.AddInteger(P.Part2); + ID.AddInteger(P.Part3); + ID.AddInteger(P.getPart4And5AsUint64()); + } + void Profile(llvm::FoldingSetNodeID &ID) { Profile(ID, PartVal); } + + static bool classof(const Decl *D) { return classofKind(D->getKind()); } + static bool classofKind(Kind K) { return K == Decl::MSGuid; } +}; + /// Insertion operator for diagnostics. This allows sending an AccessSpecifier /// into a diagnostic with <<. const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, diff --git a/clang/include/clang/AST/DeclGroup.h b/clang/include/clang/AST/DeclGroup.h index 2be9dae9431e..672b7b0a9fe2 100644 --- a/clang/include/clang/AST/DeclGroup.h +++ b/clang/include/clang/AST/DeclGroup.h @@ -147,7 +147,7 @@ namespace llvm { return clang::DeclGroupRef::getFromOpaquePtr(P); } - enum { NumLowBitsAvailable = 0 }; + static constexpr int NumLowBitsAvailable = 0; }; } // namespace llvm diff --git a/clang/include/clang/AST/DeclObjC.h b/clang/include/clang/AST/DeclObjC.h index b98aef6b499d..5613ed8370c0 100644 --- a/clang/include/clang/AST/DeclObjC.h +++ b/clang/include/clang/AST/DeclObjC.h @@ -15,6 +15,7 @@ #include "clang/AST/Decl.h" #include "clang/AST/DeclBase.h" +#include "clang/AST/DeclObjCCommon.h" #include "clang/AST/ExternalASTSource.h" #include "clang/AST/Redeclarable.h" #include "clang/AST/SelectorLocationsKind.h" @@ -402,7 +403,7 @@ public: } /// createImplicitParams - Used to lazily create the self and cmd - /// implict parameters. This must be called prior to using getSelfDecl() + /// implicit parameters. This must be called prior to using getSelfDecl() /// or getCmdDecl(). The call is ignored if the implicit parameters /// have already been created. void createImplicitParams(ASTContext &Context, const ObjCInterfaceDecl *ID); @@ -742,34 +743,6 @@ class ObjCPropertyDecl : public NamedDecl { void anchor() override; public: - enum PropertyAttributeKind { - OBJC_PR_noattr = 0x00, - OBJC_PR_readonly = 0x01, - OBJC_PR_getter = 0x02, - OBJC_PR_assign = 0x04, - OBJC_PR_readwrite = 0x08, - OBJC_PR_retain = 0x10, - OBJC_PR_copy = 0x20, - OBJC_PR_nonatomic = 0x40, - OBJC_PR_setter = 0x80, - OBJC_PR_atomic = 0x100, - OBJC_PR_weak = 0x200, - OBJC_PR_strong = 0x400, - OBJC_PR_unsafe_unretained = 0x800, - /// Indicates that the nullability of the type was spelled with a - /// property attribute rather than a type qualifier. - OBJC_PR_nullability = 0x1000, - OBJC_PR_null_resettable = 0x2000, - OBJC_PR_class = 0x4000, - OBJC_PR_direct = 0x8000 - // Adding a property should change NumPropertyAttrsBits - }; - - enum { - /// Number of bits fitting all the property attributes. - NumPropertyAttrsBits = 16 - }; - enum SetterKind { Assign, Retain, Copy, Weak }; enum PropertyControl { None, Required, Optional }; @@ -782,8 +755,8 @@ private: QualType DeclType; TypeSourceInfo *DeclTypeSourceInfo; - unsigned PropertyAttributes : NumPropertyAttrsBits; - unsigned PropertyAttributesAsWritten : NumPropertyAttrsBits; + unsigned PropertyAttributes : NumObjCPropertyAttrsBits; + unsigned PropertyAttributesAsWritten : NumObjCPropertyAttrsBits; // \@required/\@optional unsigned PropertyImplementation : 2; @@ -810,15 +783,14 @@ private: ObjCIvarDecl *PropertyIvarDecl = nullptr; ObjCPropertyDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id, - SourceLocation AtLocation, SourceLocation LParenLocation, - QualType T, TypeSourceInfo *TSI, - PropertyControl propControl) - : NamedDecl(ObjCProperty, DC, L, Id), AtLoc(AtLocation), - LParenLoc(LParenLocation), DeclType(T), DeclTypeSourceInfo(TSI), - PropertyAttributes(OBJC_PR_noattr), - PropertyAttributesAsWritten(OBJC_PR_noattr), - PropertyImplementation(propControl), GetterName(Selector()), - SetterName(Selector()) {} + SourceLocation AtLocation, SourceLocation LParenLocation, + QualType T, TypeSourceInfo *TSI, PropertyControl propControl) + : NamedDecl(ObjCProperty, DC, L, Id), AtLoc(AtLocation), + LParenLoc(LParenLocation), DeclType(T), DeclTypeSourceInfo(TSI), + PropertyAttributes(ObjCPropertyAttribute::kind_noattr), + PropertyAttributesAsWritten(ObjCPropertyAttribute::kind_noattr), + PropertyImplementation(propControl), GetterName(Selector()), + SetterName(Selector()) {} public: static ObjCPropertyDecl *Create(ASTContext &C, DeclContext *DC, @@ -850,11 +822,11 @@ public: /// type. QualType getUsageType(QualType objectType) const; - PropertyAttributeKind getPropertyAttributes() const { - return PropertyAttributeKind(PropertyAttributes); + ObjCPropertyAttribute::Kind getPropertyAttributes() const { + return ObjCPropertyAttribute::Kind(PropertyAttributes); } - void setPropertyAttributes(PropertyAttributeKind PRVal) { + void setPropertyAttributes(ObjCPropertyAttribute::Kind PRVal) { PropertyAttributes |= PRVal; } @@ -862,11 +834,11 @@ public: PropertyAttributes = PRVal; } - PropertyAttributeKind getPropertyAttributesAsWritten() const { - return PropertyAttributeKind(PropertyAttributesAsWritten); + ObjCPropertyAttribute::Kind getPropertyAttributesAsWritten() const { + return ObjCPropertyAttribute::Kind(PropertyAttributesAsWritten); } - void setPropertyAttributesAsWritten(PropertyAttributeKind PRVal) { + void setPropertyAttributesAsWritten(ObjCPropertyAttribute::Kind PRVal) { PropertyAttributesAsWritten = PRVal; } @@ -874,23 +846,28 @@ public: /// isReadOnly - Return true iff the property has a setter. bool isReadOnly() const { - return (PropertyAttributes & OBJC_PR_readonly); + return (PropertyAttributes & ObjCPropertyAttribute::kind_readonly); } /// isAtomic - Return true if the property is atomic. bool isAtomic() const { - return (PropertyAttributes & OBJC_PR_atomic); + return (PropertyAttributes & ObjCPropertyAttribute::kind_atomic); } /// isRetaining - Return true if the property retains its value. bool isRetaining() const { - return (PropertyAttributes & - (OBJC_PR_retain | OBJC_PR_strong | OBJC_PR_copy)); + return (PropertyAttributes & (ObjCPropertyAttribute::kind_retain | + ObjCPropertyAttribute::kind_strong | + ObjCPropertyAttribute::kind_copy)); } bool isInstanceProperty() const { return !isClassProperty(); } - bool isClassProperty() const { return PropertyAttributes & OBJC_PR_class; } - bool isDirectProperty() const { return PropertyAttributes & OBJC_PR_direct; } + bool isClassProperty() const { + return PropertyAttributes & ObjCPropertyAttribute::kind_class; + } + bool isDirectProperty() const { + return PropertyAttributes & ObjCPropertyAttribute::kind_direct; + } ObjCPropertyQueryKind getQueryKind() const { return isClassProperty() ? ObjCPropertyQueryKind::OBJC_PR_query_class : @@ -906,13 +883,13 @@ public: /// the property setter. This is only valid if the property has been /// defined to have a setter. SetterKind getSetterKind() const { - if (PropertyAttributes & OBJC_PR_strong) + if (PropertyAttributes & ObjCPropertyAttribute::kind_strong) return getType()->isBlockPointerType() ? Copy : Retain; - if (PropertyAttributes & OBJC_PR_retain) + if (PropertyAttributes & ObjCPropertyAttribute::kind_retain) return Retain; - if (PropertyAttributes & OBJC_PR_copy) + if (PropertyAttributes & ObjCPropertyAttribute::kind_copy) return Copy; - if (PropertyAttributes & OBJC_PR_weak) + if (PropertyAttributes & ObjCPropertyAttribute::kind_weak) return Weak; return Assign; } @@ -2692,9 +2669,7 @@ public: /// Get the name of the class associated with this interface. // // FIXME: Move to StringRef API. - std::string getNameAsString() const { - return getName(); - } + std::string getNameAsString() const { return std::string(getName()); } /// Produce a name to be used for class's metadata. It comes either via /// class's objc_runtime_name attribute or class name. @@ -2908,11 +2883,11 @@ ObjCInterfaceDecl::filtered_category_iterator<Filter>::operator++() { } inline bool ObjCInterfaceDecl::isVisibleCategory(ObjCCategoryDecl *Cat) { - return !Cat->isHidden(); + return Cat->isUnconditionallyVisible(); } inline bool ObjCInterfaceDecl::isVisibleExtension(ObjCCategoryDecl *Cat) { - return Cat->IsClassExtension() && !Cat->isHidden(); + return Cat->IsClassExtension() && Cat->isUnconditionallyVisible(); } inline bool ObjCInterfaceDecl::isKnownExtension(ObjCCategoryDecl *Cat) { diff --git a/clang/include/clang/AST/DeclObjCCommon.h b/clang/include/clang/AST/DeclObjCCommon.h new file mode 100644 index 000000000000..5f03bce6e9a8 --- /dev/null +++ b/clang/include/clang/AST/DeclObjCCommon.h @@ -0,0 +1,55 @@ +//===- DeclObjCCommon.h - Classes for representing declarations -*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file contains common ObjC enums and classes used in AST and +// Sema. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_AST_DECLOBJC_COMMON_H +#define LLVM_CLANG_AST_DECLOBJC_COMMON_H + +namespace clang { + +/// ObjCPropertyAttribute::Kind - list of property attributes. +/// Keep this list in sync with LLVM's Dwarf.h ApplePropertyAttributes.s +namespace ObjCPropertyAttribute { +enum Kind { + kind_noattr = 0x00, + kind_readonly = 0x01, + kind_getter = 0x02, + kind_assign = 0x04, + kind_readwrite = 0x08, + kind_retain = 0x10, + kind_copy = 0x20, + kind_nonatomic = 0x40, + kind_setter = 0x80, + kind_atomic = 0x100, + kind_weak = 0x200, + kind_strong = 0x400, + kind_unsafe_unretained = 0x800, + /// Indicates that the nullability of the type was spelled with a + /// property attribute rather than a type qualifier. + kind_nullability = 0x1000, + kind_null_resettable = 0x2000, + kind_class = 0x4000, + kind_direct = 0x8000, + // Adding a property should change NumObjCPropertyAttrsBits + // Also, don't forget to update the Clang C API at CXObjCPropertyAttrKind and + // clang_Cursor_getObjCPropertyAttributes. +}; +} // namespace ObjCPropertyAttribute::Kind + +enum { + /// Number of bits fitting all the property attributes. + NumObjCPropertyAttrsBits = 16 +}; + +} // namespace clang + +#endif // LLVM_CLANG_AST_DECLOBJC_COMMON_H diff --git a/clang/include/clang/AST/DeclOpenMP.h b/clang/include/clang/AST/DeclOpenMP.h index 437feaba28fb..154ecb977692 100644 --- a/clang/include/clang/AST/DeclOpenMP.h +++ b/clang/include/clang/AST/DeclOpenMP.h @@ -129,7 +129,7 @@ private: /// the declare reduction construct is declared inside compound statement. LazyDeclPtr PrevDeclInScope; - virtual void anchor(); + void anchor() override; OMPDeclareReductionDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName Name, QualType Ty, @@ -228,7 +228,7 @@ class OMPDeclareMapperDecl final : public ValueDecl, public DeclContext { LazyDeclPtr PrevDeclInScope; - virtual void anchor(); + void anchor() override; OMPDeclareMapperDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName Name, QualType Ty, diff --git a/clang/include/clang/AST/DeclTemplate.h b/clang/include/clang/AST/DeclTemplate.h index 7a55d04a0f35..e9c4879b41e8 100644 --- a/clang/include/clang/AST/DeclTemplate.h +++ b/clang/include/clang/AST/DeclTemplate.h @@ -1102,6 +1102,17 @@ public: /// template. ArrayRef<TemplateArgument> getInjectedTemplateArgs(); + /// Return whether this function template is an abbreviated function template, + /// e.g. `void foo(auto x)` or `template<typename T> void foo(auto x)` + bool isAbbreviated() const { + // Since the invented template parameters generated from 'auto' parameters + // are either appended to the end of the explicit template parameter list or + // form a new template paramter list, we can simply observe the last + // parameter to determine if such a thing happened. + const TemplateParameterList *TPL = getTemplateParameters(); + return TPL->getParam(TPL->size() - 1)->isImplicit(); + } + /// Merge \p Prev with our RedeclarableTemplateDecl::Common. void mergePrevDecl(FunctionTemplateDecl *Prev); @@ -1215,7 +1226,6 @@ public: bool ParameterPack, bool HasTypeConstraint = false, Optional<unsigned> NumExpanded = None); - static TemplateTypeParmDecl *CreateDeserialized(const ASTContext &C, unsigned ID); static TemplateTypeParmDecl *CreateDeserialized(const ASTContext &C, @@ -1374,7 +1384,8 @@ class NonTypeTemplateParmDecl final : public DeclaratorDecl, protected TemplateParmPosition, private llvm::TrailingObjects<NonTypeTemplateParmDecl, - std::pair<QualType, TypeSourceInfo *>> { + std::pair<QualType, TypeSourceInfo *>, + Expr *> { friend class ASTDeclReader; friend TrailingObjects; @@ -1429,10 +1440,12 @@ public: ArrayRef<TypeSourceInfo *> ExpandedTInfos); static NonTypeTemplateParmDecl *CreateDeserialized(ASTContext &C, - unsigned ID); + unsigned ID, + bool HasTypeConstraint); static NonTypeTemplateParmDecl *CreateDeserialized(ASTContext &C, unsigned ID, - unsigned NumExpandedTypes); + unsigned NumExpandedTypes, + bool HasTypeConstraint); using TemplateParmPosition::getDepth; using TemplateParmPosition::setDepth; @@ -1543,20 +1556,22 @@ public: return TypesAndInfos[I].second; } - /// Return the type-constraint in the placeholder type of this non-type + /// Return the constraint introduced by the placeholder type of this non-type /// template parameter (if any). - TypeConstraint *getPlaceholderTypeConstraint() const { - // TODO: Concepts: Implement once we have actual placeholders with type - // constraints. - return nullptr; + Expr *getPlaceholderTypeConstraint() const { + return hasPlaceholderTypeConstraint() ? *getTrailingObjects<Expr *>() : + nullptr; + } + + void setPlaceholderTypeConstraint(Expr *E) { + *getTrailingObjects<Expr *>() = E; } /// Determine whether this non-type template parameter's type has a /// placeholder with a type-constraint. bool hasPlaceholderTypeConstraint() const { - // TODO: Concepts: Implement once we have actual placeholders with type - // constraints. - return false; + auto *AT = getType()->getContainedAutoType(); + return AT && AT->isConstrained(); } /// \brief Get the associated-constraints of this template parameter. @@ -1566,8 +1581,8 @@ public: /// Use this instead of getPlaceholderImmediatelyDeclaredConstraint for /// concepts APIs that accept an ArrayRef of constraint expressions. void getAssociatedConstraints(llvm::SmallVectorImpl<const Expr *> &AC) const { - if (TypeConstraint *TC = getPlaceholderTypeConstraint()) - AC.push_back(TC->getImmediatelyDeclaredConstraint()); + if (Expr *E = getPlaceholderTypeConstraint()) + AC.push_back(E); } // Implement isa/cast/dyncast/etc. @@ -1876,6 +1891,10 @@ public: return *TemplateArgs; } + void setTemplateArgs(TemplateArgumentList *Args) { + TemplateArgs = Args; + } + /// Determine the kind of specialization that this /// declaration represents. TemplateSpecializationKind getSpecializationKind() const { @@ -1908,6 +1927,10 @@ public: getTemplateSpecializationKind()); } + void setSpecializedTemplate(ClassTemplateDecl *Specialized) { + SpecializedTemplate = Specialized; + } + void setSpecializationKind(TemplateSpecializationKind TSK) { SpecializationKind = TSK; } diff --git a/clang/include/clang/AST/DependenceFlags.h b/clang/include/clang/AST/DependenceFlags.h new file mode 100644 index 000000000000..14a7ffaecb2b --- /dev/null +++ b/clang/include/clang/AST/DependenceFlags.h @@ -0,0 +1,284 @@ +//===--- DependenceFlags.h ------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +#ifndef LLVM_CLANG_AST_DEPENDENCEFLAGS_H +#define LLVM_CLANG_AST_DEPENDENCEFLAGS_H + +#include "clang/Basic/BitmaskEnum.h" +#include "llvm/ADT/BitmaskEnum.h" +#include <cstdint> + +namespace clang { +struct ExprDependenceScope { + enum ExprDependence : uint8_t { + UnexpandedPack = 1, + // This expr depends in any way on + // - a template parameter, it implies that the resolution of this expr may + // cause instantiation to fail + // - or an error (often in a non-template context) + // + // Note that C++ standard doesn't define the instantiation-dependent term, + // we follow the formal definition coming from the Itanium C++ ABI, and + // extend it to errors. + Instantiation = 2, + // The type of this expr depends on a template parameter, or an error. + Type = 4, + // The value of this expr depends on a template parameter, or an error. + Value = 8, + + // clang extension: this expr contains or references an error, and is + // considered dependent on how that error is resolved. + Error = 16, + + None = 0, + All = 31, + + TypeValue = Type | Value, + TypeInstantiation = Type | Instantiation, + ValueInstantiation = Value | Instantiation, + TypeValueInstantiation = Type | Value | Instantiation, + + LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/Error) + }; +}; +using ExprDependence = ExprDependenceScope::ExprDependence; + +struct TypeDependenceScope { + enum TypeDependence : uint8_t { + /// Whether this type contains an unexpanded parameter pack + /// (for C++11 variadic templates) + UnexpandedPack = 1, + /// Whether this type somehow involves + /// - a template parameter, even if the resolution of the type does not + /// depend on a template parameter. + /// - or an error. + Instantiation = 2, + /// Whether this type + /// - is a dependent type (C++ [temp.dep.type]) + /// - or it somehow involves an error, e.g. decltype(recovery-expr) + Dependent = 4, + /// Whether this type is a variably-modified type (C99 6.7.5). + VariablyModified = 8, + + /// Whether this type references an error, e.g. decltype(err-expression) + /// yields an error type. + Error = 16, + + None = 0, + All = 31, + + DependentInstantiation = Dependent | Instantiation, + + LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/Error) + }; +}; +using TypeDependence = TypeDependenceScope::TypeDependence; + +#define LLVM_COMMON_DEPENDENCE(NAME) \ + struct NAME##Scope { \ + enum NAME : uint8_t { \ + UnexpandedPack = 1, \ + Instantiation = 2, \ + Dependent = 4, \ + Error = 8, \ + \ + None = 0, \ + DependentInstantiation = Dependent | Instantiation, \ + All = 15, \ + \ + LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/Error) \ + }; \ + }; \ + using NAME = NAME##Scope::NAME; + +LLVM_COMMON_DEPENDENCE(NestedNameSpecifierDependence) +LLVM_COMMON_DEPENDENCE(TemplateNameDependence) +LLVM_COMMON_DEPENDENCE(TemplateArgumentDependence) +#undef LLVM_COMMON_DEPENDENCE + +// A combined space of all dependence concepts for all node types. +// Used when aggregating dependence of nodes of different types. +class Dependence { +public: + enum Bits : uint8_t { + None = 0, + + // Contains a template parameter pack that wasn't expanded. + UnexpandedPack = 1, + // Depends on a template parameter or an error in some way. + // Validity depends on how the template is instantiated or the error is + // resolved. + Instantiation = 2, + // Expression type depends on template context, or an error. + // Value and Instantiation should also be set. + Type = 4, + // Expression value depends on template context, or an error. + // Instantiation should also be set. + Value = 8, + // Depends on template context, or an error. + // The type/value distinction is only meaningful for expressions. + Dependent = Type | Value, + // Includes an error, and depends on how it is resolved. + Error = 16, + // Type depends on a runtime value (variable-length array). + VariablyModified = 32, + + LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/VariablyModified) + }; + + Dependence() : V(None) {} + + Dependence(TypeDependence D) + : V(translate(D, TypeDependence::UnexpandedPack, UnexpandedPack) | + translate(D, TypeDependence::Instantiation, Instantiation) | + translate(D, TypeDependence::Dependent, Dependent) | + translate(D, TypeDependence::Error, Error) | + translate(D, TypeDependence::VariablyModified, VariablyModified)) {} + + Dependence(ExprDependence D) + : V(translate(D, ExprDependence::UnexpandedPack, UnexpandedPack) | + translate(D, ExprDependence::Instantiation, Instantiation) | + translate(D, ExprDependence::Type, Type) | + translate(D, ExprDependence::Value, Value) | + translate(D, ExprDependence::Error, Error)) {} + + Dependence(NestedNameSpecifierDependence D) : + V ( translate(D, NNSDependence::UnexpandedPack, UnexpandedPack) | + translate(D, NNSDependence::Instantiation, Instantiation) | + translate(D, NNSDependence::Dependent, Dependent) | + translate(D, NNSDependence::Error, Error)) {} + + Dependence(TemplateArgumentDependence D) + : V(translate(D, TADependence::UnexpandedPack, UnexpandedPack) | + translate(D, TADependence::Instantiation, Instantiation) | + translate(D, TADependence::Dependent, Dependent) | + translate(D, TADependence::Error, Error)) {} + + Dependence(TemplateNameDependence D) + : V(translate(D, TNDependence::UnexpandedPack, UnexpandedPack) | + translate(D, TNDependence::Instantiation, Instantiation) | + translate(D, TNDependence::Dependent, Dependent) | + translate(D, TNDependence::Error, Error)) {} + + TypeDependence type() const { + return translate(V, UnexpandedPack, TypeDependence::UnexpandedPack) | + translate(V, Instantiation, TypeDependence::Instantiation) | + translate(V, Dependent, TypeDependence::Dependent) | + translate(V, Error, TypeDependence::Error) | + translate(V, VariablyModified, TypeDependence::VariablyModified); + } + + ExprDependence expr() const { + return translate(V, UnexpandedPack, ExprDependence::UnexpandedPack) | + translate(V, Instantiation, ExprDependence::Instantiation) | + translate(V, Type, ExprDependence::Type) | + translate(V, Value, ExprDependence::Value) | + translate(V, Error, ExprDependence::Error); + } + + NestedNameSpecifierDependence nestedNameSpecifier() const { + return translate(V, UnexpandedPack, NNSDependence::UnexpandedPack) | + translate(V, Instantiation, NNSDependence::Instantiation) | + translate(V, Dependent, NNSDependence::Dependent) | + translate(V, Error, NNSDependence::Error); + } + + TemplateArgumentDependence templateArgument() const { + return translate(V, UnexpandedPack, TADependence::UnexpandedPack) | + translate(V, Instantiation, TADependence::Instantiation) | + translate(V, Dependent, TADependence::Dependent) | + translate(V, Error, TADependence::Error); + } + + TemplateNameDependence templateName() const { + return translate(V, UnexpandedPack, TNDependence::UnexpandedPack) | + translate(V, Instantiation, TNDependence::Instantiation) | + translate(V, Dependent, TNDependence::Dependent) | + translate(V, Error, TNDependence::Error); + } + +private: + Bits V; + + template <typename T, typename U> + static U translate(T Bits, T FromBit, U ToBit) { + return (Bits & FromBit) ? ToBit : static_cast<U>(0); + } + + // Abbreviations to make conversions more readable. + using NNSDependence = NestedNameSpecifierDependence; + using TADependence = TemplateArgumentDependence; + using TNDependence = TemplateNameDependence; +}; + +/// Computes dependencies of a reference with the name having template arguments +/// with \p TA dependencies. +inline ExprDependence toExprDependence(TemplateArgumentDependence TA) { + return Dependence(TA).expr(); +} +inline ExprDependence toExprDependence(TypeDependence D) { + return Dependence(D).expr(); +} +// Note: it's often necessary to strip `Dependent` from qualifiers. +// If V<T>:: refers to the current instantiation, NNS is considered dependent +// but the containing V<T>::foo likely isn't. +inline ExprDependence toExprDependence(NestedNameSpecifierDependence D) { + return Dependence(D).expr(); +} +inline ExprDependence turnTypeToValueDependence(ExprDependence D) { + // Type-dependent expressions are always be value-dependent, so we simply drop + // type dependency. + return D & ~ExprDependence::Type; +} +inline ExprDependence turnValueToTypeDependence(ExprDependence D) { + // Type-dependent expressions are always be value-dependent. + if (D & ExprDependence::Value) + D |= ExprDependence::Type; + return D; +} + +// Returned type-dependence will never have VariablyModified set. +inline TypeDependence toTypeDependence(ExprDependence D) { + return Dependence(D).type(); +} +inline TypeDependence toTypeDependence(NestedNameSpecifierDependence D) { + return Dependence(D).type(); +} +inline TypeDependence toTypeDependence(TemplateNameDependence D) { + return Dependence(D).type(); +} +inline TypeDependence toTypeDependence(TemplateArgumentDependence D) { + return Dependence(D).type(); +} + +inline NestedNameSpecifierDependence +toNestedNameSpecifierDependendence(TypeDependence D) { + return Dependence(D).nestedNameSpecifier(); +} + +inline TemplateArgumentDependence +toTemplateArgumentDependence(TypeDependence D) { + return Dependence(D).templateArgument(); +} +inline TemplateArgumentDependence +toTemplateArgumentDependence(TemplateNameDependence D) { + return Dependence(D).templateArgument(); +} +inline TemplateArgumentDependence +toTemplateArgumentDependence(ExprDependence D) { + return Dependence(D).templateArgument(); +} + +inline TemplateNameDependence +toTemplateNameDependence(NestedNameSpecifierDependence D) { + return Dependence(D).templateName(); +} + +LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE(); + +} // namespace clang +#endif diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h index 16956c27a114..c13b97119285 100644 --- a/clang/include/clang/AST/Expr.h +++ b/clang/include/clang/AST/Expr.h @@ -15,8 +15,10 @@ #include "clang/AST/APValue.h" #include "clang/AST/ASTVector.h" +#include "clang/AST/ComputeDependence.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclAccessPair.h" +#include "clang/AST/DependenceFlags.h" #include "clang/AST/OperationKinds.h" #include "clang/AST/Stmt.h" #include "clang/AST/TemplateBase.h" @@ -28,10 +30,10 @@ #include "clang/Basic/TypeTraits.h" #include "llvm/ADT/APFloat.h" #include "llvm/ADT/APSInt.h" -#include "llvm/ADT/iterator.h" -#include "llvm/ADT/iterator_range.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" +#include "llvm/ADT/iterator.h" +#include "llvm/ADT/iterator_range.h" #include "llvm/Support/AtomicOrdering.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/TrailingObjects.h" @@ -116,23 +118,26 @@ public: Expr &operator=(Expr&&) = delete; protected: - Expr(StmtClass SC, QualType T, ExprValueKind VK, ExprObjectKind OK, - bool TD, bool VD, bool ID, bool ContainsUnexpandedParameterPack) - : ValueStmt(SC) - { - ExprBits.TypeDependent = TD; - ExprBits.ValueDependent = VD; - ExprBits.InstantiationDependent = ID; + Expr(StmtClass SC, QualType T, ExprValueKind VK, ExprObjectKind OK) + : ValueStmt(SC) { + ExprBits.Dependent = 0; ExprBits.ValueKind = VK; ExprBits.ObjectKind = OK; assert(ExprBits.ObjectKind == OK && "truncated kind"); - ExprBits.ContainsUnexpandedParameterPack = ContainsUnexpandedParameterPack; setType(T); } /// Construct an empty expression. explicit Expr(StmtClass SC, EmptyShell) : ValueStmt(SC) { } + /// Each concrete expr subclass is expected to compute its dependence and call + /// this in the constructor. + void setDependence(ExprDependence Deps) { + ExprBits.Dependent = static_cast<unsigned>(Deps); + } + friend class ASTImporter; // Sets dependence dircetly. + friend class ASTStmtReader; // Sets dependence dircetly. + public: QualType getType() const { return TR; } void setType(QualType t) { @@ -148,24 +153,29 @@ public: TR = t; } - /// isValueDependent - Determines whether this expression is - /// value-dependent (C++ [temp.dep.constexpr]). For example, the - /// array bound of "Chars" in the following example is + ExprDependence getDependence() const { + return static_cast<ExprDependence>(ExprBits.Dependent); + } + + /// Determines whether the value of this expression depends on + /// - a template parameter (C++ [temp.dep.constexpr]) + /// - or an error, whose resolution is unknown + /// + /// For example, the array bound of "Chars" in the following example is /// value-dependent. /// @code /// template<int Size, char (&Chars)[Size]> struct meta_string; /// @endcode - bool isValueDependent() const { return ExprBits.ValueDependent; } - - /// Set whether this expression is value-dependent or not. - void setValueDependent(bool VD) { - ExprBits.ValueDependent = VD; + bool isValueDependent() const { + return static_cast<bool>(getDependence() & ExprDependence::Value); } - /// isTypeDependent - Determines whether this expression is - /// type-dependent (C++ [temp.dep.expr]), which means that its type - /// could change from one template instantiation to the next. For - /// example, the expressions "x" and "x + y" are type-dependent in + /// Determines whether the type of this expression depends on + /// - a template paramter (C++ [temp.dep.expr], which means that its type + /// could change from one template instantiation to the next) + /// - or an error + /// + /// For example, the expressions "x" and "x + y" are type-dependent in /// the following code, but "y" is not type-dependent: /// @code /// template<typename T> @@ -173,16 +183,15 @@ public: /// x + y; /// } /// @endcode - bool isTypeDependent() const { return ExprBits.TypeDependent; } - - /// Set whether this expression is type-dependent or not. - void setTypeDependent(bool TD) { - ExprBits.TypeDependent = TD; + bool isTypeDependent() const { + return static_cast<bool>(getDependence() & ExprDependence::Type); } /// Whether this expression is instantiation-dependent, meaning that - /// it depends in some way on a template parameter, even if neither its type - /// nor (constant) value can change due to the template instantiation. + /// it depends in some way on + /// - a template parameter (even if neither its type nor (constant) value + /// can change due to the template instantiation) + /// - or an error /// /// In the following example, the expression \c sizeof(sizeof(T() + T())) is /// instantiation-dependent (since it involves a template parameter \c T), but @@ -197,13 +206,14 @@ public: /// } /// \endcode /// + /// \code + /// void func(int) { + /// func(); // the expression is instantiation-dependent, because it depends + /// // on an error. + /// } + /// \endcode bool isInstantiationDependent() const { - return ExprBits.InstantiationDependent; - } - - /// Set whether this expression is instantiation-dependent or not. - void setInstantiationDependent(bool ID) { - ExprBits.InstantiationDependent = ID; + return static_cast<bool>(getDependence() & ExprDependence::Instantiation); } /// Whether this expression contains an unexpanded parameter @@ -221,19 +231,24 @@ public: /// The expressions \c args and \c static_cast<Types&&>(args) both /// contain parameter packs. bool containsUnexpandedParameterPack() const { - return ExprBits.ContainsUnexpandedParameterPack; + return static_cast<bool>(getDependence() & ExprDependence::UnexpandedPack); } - /// Set the bit that describes whether this expression - /// contains an unexpanded parameter pack. - void setContainsUnexpandedParameterPack(bool PP = true) { - ExprBits.ContainsUnexpandedParameterPack = PP; + /// Whether this expression contains subexpressions which had errors, e.g. a + /// TypoExpr. + bool containsErrors() const { + return static_cast<bool>(getDependence() & ExprDependence::Error); } /// getExprLoc - Return the preferred location for the arrow when diagnosing /// a problem with a generic expression. SourceLocation getExprLoc() const LLVM_READONLY; + /// Determine whether an lvalue-to-rvalue conversion should implicitly be + /// applied to this expression if it appears as a discarded-value expression + /// in C++11 onwards. This applies to certain forms of volatile glvalues. + bool isReadIfDiscardedInCPlusPlus11() const; + /// isUnusedResultAWarning - Return true if this immediate expression should /// be warned about if the result is unused. If so, fill in expr, location, /// and ranges with expr to warn on and source locations/ranges appropriate @@ -473,6 +488,11 @@ public: /// Returns whether this expression refers to a vector element. bool refersToVectorElement() const; + /// Returns whether this expression refers to a matrix element. + bool refersToMatrixElement() const { + return getObjectKind() == OK_MatrixComponent; + } + /// Returns whether this expression refers to a global register /// variable. bool refersToGlobalRegisterVar() const; @@ -693,7 +713,8 @@ public: /// Evaluate an expression that is required to be a constant expression. bool EvaluateAsConstantExpr(EvalResult &Result, ConstExprUsage Usage, - const ASTContext &Ctx) const; + const ASTContext &Ctx, + bool InPlace = false) const; /// If the current Expr is a pointer, this will try to statically /// determine the number of bytes available where the pointer is pointing. @@ -952,11 +973,11 @@ protected: Stmt *SubExpr; FullExpr(StmtClass SC, Expr *subexpr) - : Expr(SC, subexpr->getType(), - subexpr->getValueKind(), subexpr->getObjectKind(), - subexpr->isTypeDependent(), subexpr->isValueDependent(), - subexpr->isInstantiationDependent(), - subexpr->containsUnexpandedParameterPack()), SubExpr(subexpr) {} + : Expr(SC, subexpr->getType(), subexpr->getValueKind(), + subexpr->getObjectKind()), + SubExpr(subexpr) { + setDependence(computeDependence(this)); + } FullExpr(StmtClass SC, EmptyShell Empty) : Expr(SC, Empty) {} public: @@ -979,11 +1000,14 @@ class ConstantExpr final : public FullExpr, private llvm::TrailingObjects<ConstantExpr, APValue, uint64_t> { static_assert(std::is_same<uint64_t, llvm::APInt::WordType>::value, - "this class assumes llvm::APInt::WordType is uint64_t for " - "trail-allocated storage"); + "ConstantExpr assumes that llvm::APInt::WordType is uint64_t " + "for tail-allocated storage"); + friend TrailingObjects; + friend class ASTStmtReader; + friend class ASTStmtWriter; public: - /// Describes the kind of result that can be trail-allocated. + /// Describes the kind of result that can be tail-allocated. enum ResultStorageKind { RSK_None, RSK_Int64, RSK_APValue }; private: @@ -994,7 +1018,6 @@ private: return ConstantExprBits.ResultKind == ConstantExpr::RSK_Int64; } - void DefaultInit(ResultStorageKind StorageKind); uint64_t &Int64Result() { assert(ConstantExprBits.ResultKind == ConstantExpr::RSK_Int64 && "invalid accessor"); @@ -1008,24 +1031,22 @@ private: "invalid accessor"); return *getTrailingObjects<APValue>(); } - const APValue &APValueResult() const { + APValue &APValueResult() const { return const_cast<ConstantExpr *>(this)->APValueResult(); } - ConstantExpr(Expr *subexpr, ResultStorageKind StorageKind); - ConstantExpr(ResultStorageKind StorageKind, EmptyShell Empty); + ConstantExpr(Expr *SubExpr, ResultStorageKind StorageKind, + bool IsImmediateInvocation); + ConstantExpr(EmptyShell Empty, ResultStorageKind StorageKind); public: - friend TrailingObjects; - friend class ASTStmtReader; - friend class ASTStmtWriter; static ConstantExpr *Create(const ASTContext &Context, Expr *E, const APValue &Result); static ConstantExpr *Create(const ASTContext &Context, Expr *E, - ResultStorageKind Storage = RSK_None); + ResultStorageKind Storage = RSK_None, + bool IsImmediateInvocation = false); static ConstantExpr *CreateEmpty(const ASTContext &Context, - ResultStorageKind StorageKind, - EmptyShell Empty); + ResultStorageKind StorageKind); static ResultStorageKind getStorageKind(const APValue &Value); static ResultStorageKind getStorageKind(const Type *T, @@ -1053,8 +1074,14 @@ public: ResultStorageKind getResultStorageKind() const { return static_cast<ResultStorageKind>(ConstantExprBits.ResultKind); } + bool isImmediateInvocation() const { + return ConstantExprBits.IsImmediateInvocation; + } + bool hasAPValueResult() const { + return ConstantExprBits.APValueKind != APValue::None; + } APValue getAPValueResult() const; - const APValue &getResultAsAPValue() const { return APValueResult(); } + APValue &getResultAsAPValue() const { return APValueResult(); } llvm::APSInt getResultAsAPSInt() const; // Iterators child_range children() { return child_range(&SubExpr, &SubExpr+1); } @@ -1078,19 +1105,11 @@ class OpaqueValueExpr : public Expr { public: OpaqueValueExpr(SourceLocation Loc, QualType T, ExprValueKind VK, - ExprObjectKind OK = OK_Ordinary, - Expr *SourceExpr = nullptr) - : Expr(OpaqueValueExprClass, T, VK, OK, - T->isDependentType() || - (SourceExpr && SourceExpr->isTypeDependent()), - T->isDependentType() || - (SourceExpr && SourceExpr->isValueDependent()), - T->isInstantiationDependentType() || - (SourceExpr && SourceExpr->isInstantiationDependent()), - false), - SourceExpr(SourceExpr) { + ExprObjectKind OK = OK_Ordinary, Expr *SourceExpr = nullptr) + : Expr(OpaqueValueExprClass, T, VK, OK), SourceExpr(SourceExpr) { setIsUnique(false); OpaqueValueExprBits.Loc = Loc; + setDependence(computeDependence(this)); } /// Given an expression which invokes a copy constructor --- i.e. a @@ -1210,10 +1229,6 @@ class DeclRefExpr final /// Construct an empty declaration reference expression. explicit DeclRefExpr(EmptyShell Empty) : Expr(DeclRefExprClass, Empty) {} - /// Computes the type- and value-dependence flags for this - /// declaration reference expression. - void computeDependence(const ASTContext &Ctx); - public: DeclRefExpr(const ASTContext &Ctx, ValueDecl *D, bool RefersToEnclosingVariableOrCapture, QualType T, @@ -1490,7 +1505,7 @@ class FixedPointLiteral : public Expr, public APIntStorage { SourceLocation Loc; unsigned Scale; - /// \brief Construct an empty integer literal. + /// \brief Construct an empty fixed-point literal. explicit FixedPointLiteral(EmptyShell Empty) : Expr(FixedPointLiteralClass, Empty) {} @@ -1504,6 +1519,9 @@ class FixedPointLiteral : public Expr, public APIntStorage { QualType type, SourceLocation l, unsigned Scale); + /// Returns an empty fixed-point literal. + static FixedPointLiteral *Create(const ASTContext &C, EmptyShell Empty); + SourceLocation getBeginLoc() const LLVM_READONLY { return Loc; } SourceLocation getEndLoc() const LLVM_READONLY { return Loc; } @@ -1512,6 +1530,9 @@ class FixedPointLiteral : public Expr, public APIntStorage { void setLocation(SourceLocation Location) { Loc = Location; } + unsigned getScale() const { return Scale; } + void setScale(unsigned S) { Scale = S; } + static bool classof(const Stmt *T) { return T->getStmtClass() == FixedPointLiteralClass; } @@ -1544,10 +1565,10 @@ public: // type should be IntTy CharacterLiteral(unsigned value, CharacterKind kind, QualType type, SourceLocation l) - : Expr(CharacterLiteralClass, type, VK_RValue, OK_Ordinary, false, false, - false, false), - Value(value), Loc(l) { + : Expr(CharacterLiteralClass, type, VK_RValue, OK_Ordinary), Value(value), + Loc(l) { CharacterLiteralBits.Kind = kind; + setDependence(ExprDependence::None); } /// Construct an empty character literal. @@ -1663,9 +1684,9 @@ class ImaginaryLiteral : public Expr { Stmt *Val; public: ImaginaryLiteral(Expr *val, QualType Ty) - : Expr(ImaginaryLiteralClass, Ty, VK_RValue, OK_Ordinary, false, false, - false, false), - Val(val) {} + : Expr(ImaginaryLiteralClass, Ty, VK_RValue, OK_Ordinary), Val(val) { + setDependence(ExprDependence::None); + } /// Build an empty imaginary literal. explicit ImaginaryLiteral(EmptyShell Empty) @@ -1902,13 +1923,17 @@ public: /// [C99 6.4.2.2] - A predefined identifier such as __func__. class PredefinedExpr final : public Expr, - private llvm::TrailingObjects<PredefinedExpr, Stmt *> { + private llvm::TrailingObjects<PredefinedExpr, Stmt *, Expr *, + TypeSourceInfo *> { friend class ASTStmtReader; friend TrailingObjects; // PredefinedExpr is optionally followed by a single trailing // "Stmt *" for the predefined identifier. It is present if and only if // hasFunctionName() is true and is always a "StringLiteral *". + // It can also be followed by a Expr* in the case of a + // __builtin_unique_stable_name with an expression, or TypeSourceInfo * if + // __builtin_unique_stable_name with a type. public: enum IdentKind { @@ -1921,12 +1946,18 @@ public: PrettyFunction, /// The same as PrettyFunction, except that the /// 'virtual' keyword is omitted for virtual member functions. - PrettyFunctionNoVirtual + PrettyFunctionNoVirtual, + UniqueStableNameType, + UniqueStableNameExpr, }; private: PredefinedExpr(SourceLocation L, QualType FNTy, IdentKind IK, StringLiteral *SL); + PredefinedExpr(SourceLocation L, QualType FNTy, IdentKind IK, + TypeSourceInfo *Info); + PredefinedExpr(SourceLocation L, QualType FNTy, IdentKind IK, + Expr *E); explicit PredefinedExpr(EmptyShell Empty, bool HasFunctionName); @@ -1939,10 +1970,39 @@ private: *getTrailingObjects<Stmt *>() = SL; } + void setTypeSourceInfo(TypeSourceInfo *Info) { + assert(!hasFunctionName() && getIdentKind() == UniqueStableNameType && + "TypeSourceInfo only valid for UniqueStableName of a Type"); + *getTrailingObjects<TypeSourceInfo *>() = Info; + } + + void setExpr(Expr *E) { + assert(!hasFunctionName() && getIdentKind() == UniqueStableNameExpr && + "TypeSourceInfo only valid for UniqueStableName of n Expression."); + *getTrailingObjects<Expr *>() = E; + } + + size_t numTrailingObjects(OverloadToken<Stmt *>) const { + return hasFunctionName(); + } + + size_t numTrailingObjects(OverloadToken<TypeSourceInfo *>) const { + return getIdentKind() == UniqueStableNameType && !hasFunctionName(); + } + size_t numTrailingObjects(OverloadToken<Expr *>) const { + return getIdentKind() == UniqueStableNameExpr && !hasFunctionName(); + } + public: /// Create a PredefinedExpr. static PredefinedExpr *Create(const ASTContext &Ctx, SourceLocation L, QualType FNTy, IdentKind IK, StringLiteral *SL); + static PredefinedExpr *Create(const ASTContext &Ctx, SourceLocation L, + QualType FNTy, IdentKind IK, StringLiteral *SL, + TypeSourceInfo *Info); + static PredefinedExpr *Create(const ASTContext &Ctx, SourceLocation L, + QualType FNTy, IdentKind IK, StringLiteral *SL, + Expr *E); /// Create an empty PredefinedExpr. static PredefinedExpr *CreateEmpty(const ASTContext &Ctx, @@ -1967,8 +2027,34 @@ public: : nullptr; } + TypeSourceInfo *getTypeSourceInfo() { + assert(!hasFunctionName() && getIdentKind() == UniqueStableNameType && + "TypeSourceInfo only valid for UniqueStableName of a Type"); + return *getTrailingObjects<TypeSourceInfo *>(); + } + + const TypeSourceInfo *getTypeSourceInfo() const { + assert(!hasFunctionName() && getIdentKind() == UniqueStableNameType && + "TypeSourceInfo only valid for UniqueStableName of a Type"); + return *getTrailingObjects<TypeSourceInfo *>(); + } + + Expr *getExpr() { + assert(!hasFunctionName() && getIdentKind() == UniqueStableNameExpr && + "TypeSourceInfo only valid for UniqueStableName of n Expression."); + return *getTrailingObjects<Expr *>(); + } + + const Expr *getExpr() const { + assert(!hasFunctionName() && getIdentKind() == UniqueStableNameExpr && + "TypeSourceInfo only valid for UniqueStableName of n Expression."); + return *getTrailingObjects<Expr *>(); + } + static StringRef getIdentKindName(IdentKind IK); static std::string ComputeName(IdentKind IK, const Decl *CurrentDecl); + static std::string ComputeName(ASTContext &Context, IdentKind IK, + const QualType Ty); SourceLocation getBeginLoc() const { return getLocation(); } SourceLocation getEndLoc() const { return getLocation(); } @@ -1996,12 +2082,11 @@ class ParenExpr : public Expr { Stmt *Val; public: ParenExpr(SourceLocation l, SourceLocation r, Expr *val) - : Expr(ParenExprClass, val->getType(), - val->getValueKind(), val->getObjectKind(), - val->isTypeDependent(), val->isValueDependent(), - val->isInstantiationDependent(), - val->containsUnexpandedParameterPack()), - L(l), R(r), Val(val) {} + : Expr(ParenExprClass, val->getType(), val->getValueKind(), + val->getObjectKind()), + L(l), R(r), Val(val) { + setDependence(computeDependence(this)); + } /// Construct an empty parenthesized expression. explicit ParenExpr(EmptyShell Empty) @@ -2043,31 +2128,48 @@ public: /// applied to a non-complex value, the former returns its operand and the /// later returns zero in the type of the operand. /// -class UnaryOperator : public Expr { +class UnaryOperator final + : public Expr, + private llvm::TrailingObjects<UnaryOperator, FPOptionsOverride> { Stmt *Val; + size_t numTrailingObjects(OverloadToken<FPOptionsOverride>) const { + return UnaryOperatorBits.HasFPFeatures ? 1 : 0; + } + + FPOptionsOverride &getTrailingFPFeatures() { + assert(UnaryOperatorBits.HasFPFeatures); + return *getTrailingObjects<FPOptionsOverride>(); + } + + const FPOptionsOverride &getTrailingFPFeatures() const { + assert(UnaryOperatorBits.HasFPFeatures); + return *getTrailingObjects<FPOptionsOverride>(); + } + public: typedef UnaryOperatorKind Opcode; - UnaryOperator(Expr *input, Opcode opc, QualType type, ExprValueKind VK, - ExprObjectKind OK, SourceLocation l, bool CanOverflow) - : Expr(UnaryOperatorClass, type, VK, OK, - input->isTypeDependent() || type->isDependentType(), - input->isValueDependent(), - (input->isInstantiationDependent() || - type->isInstantiationDependentType()), - input->containsUnexpandedParameterPack()), - Val(input) { - UnaryOperatorBits.Opc = opc; - UnaryOperatorBits.CanOverflow = CanOverflow; - UnaryOperatorBits.Loc = l; - } +protected: + UnaryOperator(const ASTContext &Ctx, Expr *input, Opcode opc, QualType type, + ExprValueKind VK, ExprObjectKind OK, SourceLocation l, + bool CanOverflow, FPOptionsOverride FPFeatures); /// Build an empty unary operator. - explicit UnaryOperator(EmptyShell Empty) : Expr(UnaryOperatorClass, Empty) { + explicit UnaryOperator(bool HasFPFeatures, EmptyShell Empty) + : Expr(UnaryOperatorClass, Empty) { UnaryOperatorBits.Opc = UO_AddrOf; + UnaryOperatorBits.HasFPFeatures = HasFPFeatures; } +public: + static UnaryOperator *CreateEmpty(const ASTContext &C, bool hasFPFeatures); + + static UnaryOperator *Create(const ASTContext &C, Expr *input, Opcode opc, + QualType type, ExprValueKind VK, + ExprObjectKind OK, SourceLocation l, + bool CanOverflow, FPOptionsOverride FPFeatures); + Opcode getOpcode() const { return static_cast<Opcode>(UnaryOperatorBits.Opc); } @@ -2089,6 +2191,18 @@ public: bool canOverflow() const { return UnaryOperatorBits.CanOverflow; } void setCanOverflow(bool C) { UnaryOperatorBits.CanOverflow = C; } + // Get the FP contractability status of this operator. Only meaningful for + // operations on floating point types. + bool isFPContractableWithinStatement(const LangOptions &LO) const { + return getFPFeaturesInEffect(LO).allowFPContractWithinStatement(); + } + + // Get the FENV_ACCESS status of this operator. Only meaningful for + // operations on floating point types. + bool isFEnvAccessOn(const LangOptions &LO) const { + return getFPFeaturesInEffect(LO).getAllowFEnvAccess(); + } + /// isPostfix - Return true if this is a postfix operation, like x++. static bool isPostfix(Opcode Op) { return Op == UO_PostInc || Op == UO_PostDec; @@ -2155,6 +2269,37 @@ public: const_child_range children() const { return const_child_range(&Val, &Val + 1); } + + /// Is FPFeatures in Trailing Storage? + bool hasStoredFPFeatures() const { return UnaryOperatorBits.HasFPFeatures; } + +protected: + /// Get FPFeatures from trailing storage + FPOptionsOverride getStoredFPFeatures() const { + return getTrailingFPFeatures(); + } + + /// Set FPFeatures in trailing storage, used only by Serialization + void setStoredFPFeatures(FPOptionsOverride F) { getTrailingFPFeatures() = F; } + +public: + // Get the FP features status of this operator. Only meaningful for + // operations on floating point types. + FPOptions getFPFeaturesInEffect(const LangOptions &LO) const { + if (UnaryOperatorBits.HasFPFeatures) + return getStoredFPFeatures().applyOverrides(LO); + return FPOptions::defaultWithoutTrailingStorage(LO); + } + FPOptionsOverride getFPOptionsOverride() const { + if (UnaryOperatorBits.HasFPFeatures) + return getStoredFPFeatures(); + return FPOptionsOverride(); + } + + friend TrailingObjects; + friend class ASTReader; + friend class ASTStmtReader; + friend class ASTStmtWriter; }; /// Helper class for OffsetOfExpr. @@ -2379,17 +2524,17 @@ class UnaryExprOrTypeTraitExpr : public Expr { public: UnaryExprOrTypeTraitExpr(UnaryExprOrTypeTrait ExprKind, TypeSourceInfo *TInfo, QualType resultType, SourceLocation op, - SourceLocation rp) : - Expr(UnaryExprOrTypeTraitExprClass, resultType, VK_RValue, OK_Ordinary, - false, // Never type-dependent (C++ [temp.dep.expr]p3). - // Value-dependent if the argument is type-dependent. - TInfo->getType()->isDependentType(), - TInfo->getType()->isInstantiationDependentType(), - TInfo->getType()->containsUnexpandedParameterPack()), - OpLoc(op), RParenLoc(rp) { + SourceLocation rp) + : Expr(UnaryExprOrTypeTraitExprClass, resultType, VK_RValue, OK_Ordinary), + OpLoc(op), RParenLoc(rp) { + assert(ExprKind <= UETT_Last && "invalid enum value!"); UnaryExprOrTypeTraitExprBits.Kind = ExprKind; + assert(static_cast<unsigned>(ExprKind) == + UnaryExprOrTypeTraitExprBits.Kind && + "UnaryExprOrTypeTraitExprBits.Kind overflow!"); UnaryExprOrTypeTraitExprBits.IsType = true; Argument.Ty = TInfo; + setDependence(computeDependence(this)); } UnaryExprOrTypeTraitExpr(UnaryExprOrTypeTrait ExprKind, Expr *E, @@ -2403,7 +2548,12 @@ public: UnaryExprOrTypeTrait getKind() const { return static_cast<UnaryExprOrTypeTrait>(UnaryExprOrTypeTraitExprBits.Kind); } - void setKind(UnaryExprOrTypeTrait K) { UnaryExprOrTypeTraitExprBits.Kind = K;} + void setKind(UnaryExprOrTypeTrait K) { + assert(K <= UETT_Last && "invalid enum value!"); + UnaryExprOrTypeTraitExprBits.Kind = K; + assert(static_cast<unsigned>(K) == UnaryExprOrTypeTraitExprBits.Kind && + "UnaryExprOrTypeTraitExprBits.Kind overflow!"); + } bool isArgumentType() const { return UnaryExprOrTypeTraitExprBits.IsType; } QualType getArgumentType() const { @@ -2466,19 +2616,13 @@ class ArraySubscriptExpr : public Expr { bool lhsIsBase() const { return getRHS()->getType()->isIntegerType(); } public: - ArraySubscriptExpr(Expr *lhs, Expr *rhs, QualType t, - ExprValueKind VK, ExprObjectKind OK, - SourceLocation rbracketloc) - : Expr(ArraySubscriptExprClass, t, VK, OK, - lhs->isTypeDependent() || rhs->isTypeDependent(), - lhs->isValueDependent() || rhs->isValueDependent(), - (lhs->isInstantiationDependent() || - rhs->isInstantiationDependent()), - (lhs->containsUnexpandedParameterPack() || - rhs->containsUnexpandedParameterPack())) { + ArraySubscriptExpr(Expr *lhs, Expr *rhs, QualType t, ExprValueKind VK, + ExprObjectKind OK, SourceLocation rbracketloc) + : Expr(ArraySubscriptExprClass, t, VK, OK) { SubExprs[LHS] = lhs; SubExprs[RHS] = rhs; - ArraySubscriptExprBits.RBracketLoc = rbracketloc; + ArrayOrMatrixSubscriptExprBits.RBracketLoc = rbracketloc; + setDependence(computeDependence(this)); } /// Create an empty array subscript expression. @@ -2514,10 +2658,10 @@ public: SourceLocation getEndLoc() const { return getRBracketLoc(); } SourceLocation getRBracketLoc() const { - return ArraySubscriptExprBits.RBracketLoc; + return ArrayOrMatrixSubscriptExprBits.RBracketLoc; } void setRBracketLoc(SourceLocation L) { - ArraySubscriptExprBits.RBracketLoc = L; + ArrayOrMatrixSubscriptExprBits.RBracketLoc = L; } SourceLocation getExprLoc() const LLVM_READONLY { @@ -2537,6 +2681,84 @@ public: } }; +/// MatrixSubscriptExpr - Matrix subscript expression for the MatrixType +/// extension. +/// MatrixSubscriptExpr can be either incomplete (only Base and RowIdx are set +/// so far, the type is IncompleteMatrixIdx) or complete (Base, RowIdx and +/// ColumnIdx refer to valid expressions). Incomplete matrix expressions only +/// exist during the initial construction of the AST. +class MatrixSubscriptExpr : public Expr { + enum { BASE, ROW_IDX, COLUMN_IDX, END_EXPR }; + Stmt *SubExprs[END_EXPR]; + +public: + MatrixSubscriptExpr(Expr *Base, Expr *RowIdx, Expr *ColumnIdx, QualType T, + SourceLocation RBracketLoc) + : Expr(MatrixSubscriptExprClass, T, Base->getValueKind(), + OK_MatrixComponent) { + SubExprs[BASE] = Base; + SubExprs[ROW_IDX] = RowIdx; + SubExprs[COLUMN_IDX] = ColumnIdx; + ArrayOrMatrixSubscriptExprBits.RBracketLoc = RBracketLoc; + setDependence(computeDependence(this)); + } + + /// Create an empty matrix subscript expression. + explicit MatrixSubscriptExpr(EmptyShell Shell) + : Expr(MatrixSubscriptExprClass, Shell) {} + + bool isIncomplete() const { + bool IsIncomplete = hasPlaceholderType(BuiltinType::IncompleteMatrixIdx); + assert((SubExprs[COLUMN_IDX] || IsIncomplete) && + "expressions without column index must be marked as incomplete"); + return IsIncomplete; + } + Expr *getBase() { return cast<Expr>(SubExprs[BASE]); } + const Expr *getBase() const { return cast<Expr>(SubExprs[BASE]); } + void setBase(Expr *E) { SubExprs[BASE] = E; } + + Expr *getRowIdx() { return cast<Expr>(SubExprs[ROW_IDX]); } + const Expr *getRowIdx() const { return cast<Expr>(SubExprs[ROW_IDX]); } + void setRowIdx(Expr *E) { SubExprs[ROW_IDX] = E; } + + Expr *getColumnIdx() { return cast_or_null<Expr>(SubExprs[COLUMN_IDX]); } + const Expr *getColumnIdx() const { + assert(!isIncomplete() && + "cannot get the column index of an incomplete expression"); + return cast<Expr>(SubExprs[COLUMN_IDX]); + } + void setColumnIdx(Expr *E) { SubExprs[COLUMN_IDX] = E; } + + SourceLocation getBeginLoc() const LLVM_READONLY { + return getBase()->getBeginLoc(); + } + + SourceLocation getEndLoc() const { return getRBracketLoc(); } + + SourceLocation getExprLoc() const LLVM_READONLY { + return getBase()->getExprLoc(); + } + + SourceLocation getRBracketLoc() const { + return ArrayOrMatrixSubscriptExprBits.RBracketLoc; + } + void setRBracketLoc(SourceLocation L) { + ArrayOrMatrixSubscriptExprBits.RBracketLoc = L; + } + + static bool classof(const Stmt *T) { + return T->getStmtClass() == MatrixSubscriptExprClass; + } + + // Iterators + child_range children() { + return child_range(&SubExprs[0], &SubExprs[0] + END_EXPR); + } + const_child_range children() const { + return const_child_range(&SubExprs[0], &SubExprs[0] + END_EXPR); + } +}; + /// 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) @@ -2553,8 +2775,6 @@ class CallExpr : public Expr { /// the derived classes of CallExpr. SourceLocation RParenLoc; - void updateDependenciesFromArg(Expr *Arg); - // CallExpr store some data in trailing objects. However since CallExpr // is used a base of other expression classes we cannot use // llvm::TrailingObjects. Instead we manually perform the pointer arithmetic @@ -2796,6 +3016,12 @@ public: /// a non-value-dependent constant parameter evaluating as false. bool isBuiltinAssumeFalse(const ASTContext &Ctx) const; + /// Used by Sema to implement MSVC-compatible delayed name lookup. + /// (Usually Exprs themselves should set dependence). + void markDependentForPostponedNameLookup() { + setDependence(getDependence() | ExprDependence::TypeValueInstantiation); + } + bool isCallToStdMove() const { const FunctionDecl *FD = getDirectCallee(); return getNumArgs() == 1 && FD && FD->isInStdNamespace() && @@ -3088,13 +3314,10 @@ class CompoundLiteralExpr : public Expr { public: CompoundLiteralExpr(SourceLocation lparenloc, TypeSourceInfo *tinfo, QualType T, ExprValueKind VK, Expr *init, bool fileScope) - : Expr(CompoundLiteralExprClass, T, VK, OK_Ordinary, - tinfo->getType()->isDependentType(), - init->isValueDependent(), - (init->isInstantiationDependent() || - tinfo->getType()->isInstantiationDependentType()), - init->containsUnexpandedParameterPack()), - LParenLoc(lparenloc), TInfoAndScope(tinfo, fileScope), Init(init) {} + : Expr(CompoundLiteralExprClass, T, VK, OK_Ordinary), + LParenLoc(lparenloc), TInfoAndScope(tinfo, fileScope), Init(init) { + setDependence(computeDependence(this)); + } /// Construct an empty compound literal. explicit CompoundLiteralExpr(EmptyShell Empty) @@ -3160,26 +3383,13 @@ class CastExpr : public Expr { protected: CastExpr(StmtClass SC, QualType ty, ExprValueKind VK, const CastKind kind, Expr *op, unsigned BasePathSize) - : Expr(SC, ty, VK, OK_Ordinary, - // Cast expressions are type-dependent if the type is - // dependent (C++ [temp.dep.expr]p3). - ty->isDependentType(), - // Cast expressions are value-dependent if the type is - // dependent or if the subexpression is value-dependent. - ty->isDependentType() || (op && op->isValueDependent()), - (ty->isInstantiationDependentType() || - (op && op->isInstantiationDependent())), - // An implicit cast expression doesn't (lexically) contain an - // unexpanded pack, even if its target type does. - ((SC != ImplicitCastExprClass && - ty->containsUnexpandedParameterPack()) || - (op && op->containsUnexpandedParameterPack()))), - Op(op) { + : Expr(SC, ty, VK, OK_Ordinary), Op(op) { CastExprBits.Kind = kind; CastExprBits.PartOfExplicitCast = false; CastExprBits.BasePathSize = BasePathSize; assert((CastExprBits.BasePathSize == BasePathSize) && "BasePathSize overflow!"); + setDependence(computeDependence(this)); assert(CastConsistency()); } @@ -3438,30 +3648,39 @@ class BinaryOperator : public Expr { public: typedef BinaryOperatorKind Opcode; - BinaryOperator(Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy, - ExprValueKind VK, ExprObjectKind OK, - SourceLocation opLoc, FPOptions FPFeatures) - : Expr(BinaryOperatorClass, ResTy, VK, OK, - lhs->isTypeDependent() || rhs->isTypeDependent(), - lhs->isValueDependent() || rhs->isValueDependent(), - (lhs->isInstantiationDependent() || - rhs->isInstantiationDependent()), - (lhs->containsUnexpandedParameterPack() || - rhs->containsUnexpandedParameterPack())) { - BinaryOperatorBits.Opc = opc; - BinaryOperatorBits.FPFeatures = FPFeatures.getInt(); - BinaryOperatorBits.OpLoc = opLoc; - SubExprs[LHS] = lhs; - SubExprs[RHS] = rhs; - assert(!isCompoundAssignmentOp() && - "Use CompoundAssignOperator for compound assignments"); +protected: + size_t offsetOfTrailingStorage() const; + + /// Return a pointer to the trailing FPOptions + FPOptionsOverride *getTrailingFPFeatures() { + assert(BinaryOperatorBits.HasFPFeatures); + return reinterpret_cast<FPOptionsOverride *>( + reinterpret_cast<char *>(this) + offsetOfTrailingStorage()); + } + const FPOptionsOverride *getTrailingFPFeatures() const { + assert(BinaryOperatorBits.HasFPFeatures); + return reinterpret_cast<const FPOptionsOverride *>( + reinterpret_cast<const char *>(this) + offsetOfTrailingStorage()); } + /// Build a binary operator, assuming that appropriate storage has been + /// allocated for the trailing objects when needed. + BinaryOperator(const ASTContext &Ctx, Expr *lhs, Expr *rhs, Opcode opc, + QualType ResTy, ExprValueKind VK, ExprObjectKind OK, + SourceLocation opLoc, FPOptionsOverride FPFeatures); + /// Construct an empty binary operator. explicit BinaryOperator(EmptyShell Empty) : Expr(BinaryOperatorClass, Empty) { BinaryOperatorBits.Opc = BO_Comma; } +public: + static BinaryOperator *CreateEmpty(const ASTContext &C, bool hasFPFeatures); + + static BinaryOperator *Create(const ASTContext &C, Expr *lhs, Expr *rhs, + Opcode opc, QualType ResTy, ExprValueKind VK, + ExprObjectKind OK, SourceLocation opLoc, + FPOptionsOverride FPFeatures); SourceLocation getExprLoc() const { return getOperatorLoc(); } SourceLocation getOperatorLoc() const { return BinaryOperatorBits.OpLoc; } void setOperatorLoc(SourceLocation L) { BinaryOperatorBits.OpLoc = L; } @@ -3602,47 +3821,65 @@ public: return const_child_range(&SubExprs[0], &SubExprs[0] + END_EXPR); } - // Set the FP contractability status of this operator. Only meaningful for + /// Set and fetch the bit that shows whether FPFeatures needs to be + /// allocated in Trailing Storage + void setHasStoredFPFeatures(bool B) { BinaryOperatorBits.HasFPFeatures = B; } + bool hasStoredFPFeatures() const { return BinaryOperatorBits.HasFPFeatures; } + + /// Get FPFeatures from trailing storage + FPOptionsOverride getStoredFPFeatures() const { + assert(hasStoredFPFeatures()); + return *getTrailingFPFeatures(); + } + /// Set FPFeatures in trailing storage, used only by Serialization + void setStoredFPFeatures(FPOptionsOverride F) { + assert(BinaryOperatorBits.HasFPFeatures); + *getTrailingFPFeatures() = F; + } + + // Get the FP features status of this operator. Only meaningful for // operations on floating point types. - void setFPFeatures(FPOptions F) { - BinaryOperatorBits.FPFeatures = F.getInt(); + FPOptions getFPFeaturesInEffect(const LangOptions &LO) const { + if (BinaryOperatorBits.HasFPFeatures) + return getStoredFPFeatures().applyOverrides(LO); + return FPOptions::defaultWithoutTrailingStorage(LO); } - FPOptions getFPFeatures() const { - return FPOptions(BinaryOperatorBits.FPFeatures); + // This is used in ASTImporter + FPOptionsOverride getFPFeatures(const LangOptions &LO) const { + if (BinaryOperatorBits.HasFPFeatures) + return getStoredFPFeatures(); + return FPOptionsOverride(); } // Get the FP contractability status of this operator. Only meaningful for // operations on floating point types. - bool isFPContractableWithinStatement() const { - return getFPFeatures().allowFPContractWithinStatement(); + bool isFPContractableWithinStatement(const LangOptions &LO) const { + return getFPFeaturesInEffect(LO).allowFPContractWithinStatement(); } // Get the FENV_ACCESS status of this operator. Only meaningful for // operations on floating point types. - bool isFEnvAccessOn() const { return getFPFeatures().allowFEnvAccess(); } + bool isFEnvAccessOn(const LangOptions &LO) const { + return getFPFeaturesInEffect(LO).getAllowFEnvAccess(); + } protected: - BinaryOperator(Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy, - ExprValueKind VK, ExprObjectKind OK, - SourceLocation opLoc, FPOptions FPFeatures, bool dead2) - : Expr(CompoundAssignOperatorClass, ResTy, VK, OK, - lhs->isTypeDependent() || rhs->isTypeDependent(), - lhs->isValueDependent() || rhs->isValueDependent(), - (lhs->isInstantiationDependent() || - rhs->isInstantiationDependent()), - (lhs->containsUnexpandedParameterPack() || - rhs->containsUnexpandedParameterPack())) { - BinaryOperatorBits.Opc = opc; - BinaryOperatorBits.FPFeatures = FPFeatures.getInt(); - BinaryOperatorBits.OpLoc = opLoc; - SubExprs[LHS] = lhs; - SubExprs[RHS] = rhs; - } + BinaryOperator(const ASTContext &Ctx, Expr *lhs, Expr *rhs, Opcode opc, + QualType ResTy, ExprValueKind VK, ExprObjectKind OK, + SourceLocation opLoc, FPOptionsOverride FPFeatures, + bool dead2); + /// Construct an empty BinaryOperator, SC is CompoundAssignOperator. BinaryOperator(StmtClass SC, EmptyShell Empty) : Expr(SC, Empty) { BinaryOperatorBits.Opc = BO_MulAssign; } + + /// Return the size in bytes needed for the trailing objects. + /// Used to allocate the right amount of storage. + static unsigned sizeOfTrailingObjects(bool HasFPFeatures) { + return HasFPFeatures * sizeof(FPOptionsOverride); + } }; /// CompoundAssignOperator - For compound assignments (e.g. +=), we keep @@ -3654,22 +3891,33 @@ protected: class CompoundAssignOperator : public BinaryOperator { QualType ComputationLHSType; QualType ComputationResultType; -public: - CompoundAssignOperator(Expr *lhs, Expr *rhs, Opcode opc, QualType ResType, - ExprValueKind VK, ExprObjectKind OK, - QualType CompLHSType, QualType CompResultType, - SourceLocation OpLoc, FPOptions FPFeatures) - : BinaryOperator(lhs, rhs, opc, ResType, VK, OK, OpLoc, FPFeatures, - true), - ComputationLHSType(CompLHSType), - ComputationResultType(CompResultType) { + + /// Construct an empty CompoundAssignOperator. + explicit CompoundAssignOperator(const ASTContext &C, EmptyShell Empty, + bool hasFPFeatures) + : BinaryOperator(CompoundAssignOperatorClass, Empty) {} + +protected: + CompoundAssignOperator(const ASTContext &C, Expr *lhs, Expr *rhs, Opcode opc, + QualType ResType, ExprValueKind VK, ExprObjectKind OK, + SourceLocation OpLoc, FPOptionsOverride FPFeatures, + QualType CompLHSType, QualType CompResultType) + : BinaryOperator(C, lhs, rhs, opc, ResType, VK, OK, OpLoc, FPFeatures, + true), + ComputationLHSType(CompLHSType), ComputationResultType(CompResultType) { assert(isCompoundAssignmentOp() && "Only should be used for compound assignments"); } - /// Build an empty compound assignment operator expression. - explicit CompoundAssignOperator(EmptyShell Empty) - : BinaryOperator(CompoundAssignOperatorClass, Empty) { } +public: + static CompoundAssignOperator *CreateEmpty(const ASTContext &C, + bool hasFPFeatures); + + static CompoundAssignOperator * + Create(const ASTContext &C, Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy, + ExprValueKind VK, ExprObjectKind OK, SourceLocation opLoc, + FPOptionsOverride FPFeatures, QualType CompLHSType = QualType(), + QualType CompResultType = QualType()); // The two computation types are the type the LHS is converted // to for the computation and the type of the result; the two are @@ -3685,6 +3933,12 @@ public: } }; +inline size_t BinaryOperator::offsetOfTrailingStorage() const { + assert(BinaryOperatorBits.HasFPFeatures); + return isa<CompoundAssignOperator>(this) ? sizeof(CompoundAssignOperator) + : sizeof(BinaryOperator); +} + /// AbstractConditionalOperator - An abstract base class for /// ConditionalOperator and BinaryConditionalOperator. class AbstractConditionalOperator : public Expr { @@ -3692,14 +3946,10 @@ class AbstractConditionalOperator : public Expr { friend class ASTStmtReader; protected: - AbstractConditionalOperator(StmtClass SC, QualType T, - ExprValueKind VK, ExprObjectKind OK, - bool TD, bool VD, bool ID, - bool ContainsUnexpandedParameterPack, - SourceLocation qloc, + AbstractConditionalOperator(StmtClass SC, QualType T, ExprValueKind VK, + ExprObjectKind OK, SourceLocation qloc, SourceLocation cloc) - : Expr(SC, T, VK, OK, TD, VD, ID, ContainsUnexpandedParameterPack), - QuestionLoc(qloc), ColonLoc(cloc) {} + : Expr(SC, T, VK, OK), QuestionLoc(qloc), ColonLoc(cloc) {} AbstractConditionalOperator(StmtClass SC, EmptyShell Empty) : Expr(SC, Empty) { } @@ -3738,26 +3988,12 @@ public: ConditionalOperator(Expr *cond, SourceLocation QLoc, Expr *lhs, SourceLocation CLoc, Expr *rhs, QualType t, ExprValueKind VK, ExprObjectKind OK) - : AbstractConditionalOperator( - ConditionalOperatorClass, t, VK, OK, - // The type of the conditional operator depends on the type - // of the conditional to support the GCC vector conditional - // extension. Additionally, [temp.dep.expr] does specify state that - // this should be dependent on ALL sub expressions. - (cond->isTypeDependent() || lhs->isTypeDependent() || - rhs->isTypeDependent()), - (cond->isValueDependent() || lhs->isValueDependent() || - rhs->isValueDependent()), - (cond->isInstantiationDependent() || - lhs->isInstantiationDependent() || - rhs->isInstantiationDependent()), - (cond->containsUnexpandedParameterPack() || - lhs->containsUnexpandedParameterPack() || - rhs->containsUnexpandedParameterPack()), - QLoc, CLoc) { + : AbstractConditionalOperator(ConditionalOperatorClass, t, VK, OK, QLoc, + CLoc) { SubExprs[COND] = cond; SubExprs[LHS] = lhs; SubExprs[RHS] = rhs; + setDependence(computeDependence(this)); } /// Build an empty conditional operator. @@ -3822,20 +4058,15 @@ public: Expr *cond, Expr *lhs, Expr *rhs, SourceLocation qloc, SourceLocation cloc, QualType t, ExprValueKind VK, ExprObjectKind OK) - : AbstractConditionalOperator(BinaryConditionalOperatorClass, t, VK, OK, - (common->isTypeDependent() || rhs->isTypeDependent()), - (common->isValueDependent() || rhs->isValueDependent()), - (common->isInstantiationDependent() || - rhs->isInstantiationDependent()), - (common->containsUnexpandedParameterPack() || - rhs->containsUnexpandedParameterPack()), - qloc, cloc), - OpaqueValue(opaqueValue) { + : AbstractConditionalOperator(BinaryConditionalOperatorClass, t, VK, OK, + qloc, cloc), + OpaqueValue(opaqueValue) { SubExprs[COMMON] = common; SubExprs[COND] = cond; SubExprs[LHS] = lhs; SubExprs[RHS] = rhs; assert(OpaqueValue->getSourceExpr() == common && "Wrong opaque value"); + setDependence(computeDependence(this)); } /// Build an empty conditional operator. @@ -3913,9 +4144,10 @@ class AddrLabelExpr : public Expr { public: AddrLabelExpr(SourceLocation AALoc, SourceLocation LLoc, LabelDecl *L, QualType t) - : Expr(AddrLabelExprClass, t, VK_RValue, OK_Ordinary, false, false, false, - false), - AmpAmpLoc(AALoc), LabelLoc(LLoc), Label(L) {} + : Expr(AddrLabelExprClass, t, VK_RValue, OK_Ordinary), AmpAmpLoc(AALoc), + LabelLoc(LLoc), Label(L) { + setDependence(ExprDependence::None); + } /// Build an empty address of a label expression. explicit AddrLabelExpr(EmptyShell Empty) @@ -3955,14 +4187,15 @@ class StmtExpr : public Expr { Stmt *SubStmt; SourceLocation LParenLoc, RParenLoc; public: - // FIXME: Does type-dependence need to be computed differently? - // FIXME: Do we need to compute instantiation instantiation-dependence for - // statements? (ugh!) - StmtExpr(CompoundStmt *substmt, QualType T, - SourceLocation lp, SourceLocation rp) : - Expr(StmtExprClass, T, VK_RValue, OK_Ordinary, - T->isDependentType(), false, false, false), - SubStmt(substmt), LParenLoc(lp), RParenLoc(rp) { } + StmtExpr(CompoundStmt *SubStmt, QualType T, SourceLocation LParenLoc, + SourceLocation RParenLoc, unsigned TemplateDepth) + : Expr(StmtExprClass, T, VK_RValue, OK_Ordinary), SubStmt(SubStmt), + LParenLoc(LParenLoc), RParenLoc(RParenLoc) { + setDependence(computeDependence(this, TemplateDepth)); + // FIXME: A templated statement expression should have an associated + // DeclContext so that nested declarations always have a dependent context. + StmtExprBits.TemplateDepth = TemplateDepth; + } /// Build an empty statement expression. explicit StmtExpr(EmptyShell Empty) : Expr(StmtExprClass, Empty) { } @@ -3979,6 +4212,8 @@ public: SourceLocation getRParenLoc() const { return RParenLoc; } void setRParenLoc(SourceLocation L) { RParenLoc = L; } + unsigned getTemplateDepth() const { return StmtExprBits.TemplateDepth; } + static bool classof(const Stmt *T) { return T->getStmtClass() == StmtExprClass; } @@ -4075,17 +4310,13 @@ private: explicit ConvertVectorExpr(EmptyShell Empty) : Expr(ConvertVectorExprClass, Empty) {} public: - ConvertVectorExpr(Expr* SrcExpr, TypeSourceInfo *TI, QualType DstType, - ExprValueKind VK, ExprObjectKind OK, - SourceLocation BuiltinLoc, SourceLocation RParenLoc) - : Expr(ConvertVectorExprClass, DstType, VK, OK, - DstType->isDependentType(), - DstType->isDependentType() || SrcExpr->isValueDependent(), - (DstType->isInstantiationDependentType() || - SrcExpr->isInstantiationDependent()), - (DstType->containsUnexpandedParameterPack() || - SrcExpr->containsUnexpandedParameterPack())), - SrcExpr(SrcExpr), TInfo(TI), BuiltinLoc(BuiltinLoc), RParenLoc(RParenLoc) {} + ConvertVectorExpr(Expr *SrcExpr, TypeSourceInfo *TI, QualType DstType, + ExprValueKind VK, ExprObjectKind OK, + SourceLocation BuiltinLoc, SourceLocation RParenLoc) + : Expr(ConvertVectorExprClass, DstType, VK, OK), SrcExpr(SrcExpr), + TInfo(TI), BuiltinLoc(BuiltinLoc), RParenLoc(RParenLoc) { + setDependence(computeDependence(this)); + } /// getSrcExpr - Return the Expr to be converted. Expr *getSrcExpr() const { return cast<Expr>(SrcExpr); } @@ -4133,22 +4364,17 @@ class ChooseExpr : public Expr { SourceLocation BuiltinLoc, RParenLoc; bool CondIsTrue; public: - ChooseExpr(SourceLocation BLoc, Expr *cond, Expr *lhs, Expr *rhs, - QualType t, ExprValueKind VK, ExprObjectKind OK, - SourceLocation RP, bool condIsTrue, - bool TypeDependent, bool ValueDependent) - : Expr(ChooseExprClass, t, VK, OK, TypeDependent, ValueDependent, - (cond->isInstantiationDependent() || - lhs->isInstantiationDependent() || - rhs->isInstantiationDependent()), - (cond->containsUnexpandedParameterPack() || - lhs->containsUnexpandedParameterPack() || - rhs->containsUnexpandedParameterPack())), - BuiltinLoc(BLoc), RParenLoc(RP), CondIsTrue(condIsTrue) { - SubExprs[COND] = cond; - SubExprs[LHS] = lhs; - SubExprs[RHS] = rhs; - } + ChooseExpr(SourceLocation BLoc, Expr *cond, Expr *lhs, Expr *rhs, QualType t, + ExprValueKind VK, ExprObjectKind OK, SourceLocation RP, + bool condIsTrue) + : Expr(ChooseExprClass, t, VK, OK), BuiltinLoc(BLoc), RParenLoc(RP), + CondIsTrue(condIsTrue) { + SubExprs[COND] = cond; + SubExprs[LHS] = lhs; + SubExprs[RHS] = rhs; + + setDependence(computeDependence(this)); + } /// Build an empty __builtin_choose_expr. explicit ChooseExpr(EmptyShell Empty) : Expr(ChooseExprClass, Empty) { } @@ -4213,9 +4439,9 @@ class GNUNullExpr : public Expr { public: GNUNullExpr(QualType Ty, SourceLocation Loc) - : Expr(GNUNullExprClass, Ty, VK_RValue, OK_Ordinary, false, false, false, - false), - TokenLoc(Loc) { } + : Expr(GNUNullExprClass, Ty, VK_RValue, OK_Ordinary), TokenLoc(Loc) { + setDependence(ExprDependence::None); + } /// Build an empty GNU __null expression. explicit GNUNullExpr(EmptyShell Empty) : Expr(GNUNullExprClass, Empty) { } @@ -4248,12 +4474,10 @@ class VAArgExpr : public Expr { public: 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) {} + : Expr(VAArgExprClass, t, VK_RValue, OK_Ordinary), Val(e), + TInfo(TInfo, IsMS), BuiltinLoc(BLoc), RParenLoc(RPLoc) { + setDependence(computeDependence(this)); + } /// Create an empty __builtin_va_arg expression. explicit VAArgExpr(EmptyShell Empty) @@ -4462,13 +4686,8 @@ public: assert(Init < getNumInits() && "Initializer access out of range!"); InitExprs[Init] = expr; - if (expr) { - ExprBits.TypeDependent |= expr->isTypeDependent(); - ExprBits.ValueDependent |= expr->isValueDependent(); - ExprBits.InstantiationDependent |= expr->isInstantiationDependent(); - ExprBits.ContainsUnexpandedParameterPack |= - expr->containsUnexpandedParameterPack(); - } + if (expr) + setDependence(getDependence() | expr->getDependence()); } /// Reserve space for some number of initializers. @@ -4937,8 +5156,9 @@ public: class NoInitExpr : public Expr { public: explicit NoInitExpr(QualType ty) - : Expr(NoInitExprClass, ty, VK_RValue, OK_Ordinary, - false, false, ty->isInstantiationDependentType(), false) { } + : Expr(NoInitExprClass, ty, VK_RValue, OK_Ordinary) { + setDependence(computeDependence(this)); + } explicit NoInitExpr(EmptyShell Empty) : Expr(NoInitExprClass, Empty) { } @@ -5032,12 +5252,10 @@ class ArrayInitLoopExpr : public Expr { public: explicit ArrayInitLoopExpr(QualType T, Expr *CommonInit, Expr *ElementInit) - : Expr(ArrayInitLoopExprClass, T, VK_RValue, OK_Ordinary, false, - CommonInit->isValueDependent() || ElementInit->isValueDependent(), - T->isInstantiationDependentType(), - CommonInit->containsUnexpandedParameterPack() || - ElementInit->containsUnexpandedParameterPack()), - SubExprs{CommonInit, ElementInit} {} + : Expr(ArrayInitLoopExprClass, T, VK_RValue, OK_Ordinary), + SubExprs{CommonInit, ElementInit} { + setDependence(computeDependence(this)); + } /// Get the common subexpression shared by all initializations (the source /// array). @@ -5085,8 +5303,9 @@ class ArrayInitIndexExpr : public Expr { public: explicit ArrayInitIndexExpr(QualType T) - : Expr(ArrayInitIndexExprClass, T, VK_RValue, OK_Ordinary, - false, false, false, false) {} + : Expr(ArrayInitIndexExprClass, T, VK_RValue, OK_Ordinary) { + setDependence(ExprDependence::None); + } static bool classof(const Stmt *S) { return S->getStmtClass() == ArrayInitIndexExprClass; @@ -5117,8 +5336,9 @@ public: class ImplicitValueInitExpr : public Expr { public: explicit ImplicitValueInitExpr(QualType ty) - : Expr(ImplicitValueInitExprClass, ty, VK_RValue, OK_Ordinary, - false, false, ty->isInstantiationDependentType(), false) { } + : Expr(ImplicitValueInitExprClass, ty, VK_RValue, OK_Ordinary) { + setDependence(computeDependence(this)); + } /// Construct an empty implicit value initialization. explicit ImplicitValueInitExpr(EmptyShell Empty) @@ -5277,10 +5497,9 @@ class GenericSelectionExpr final template <bool Const> class AssociationTy { friend class GenericSelectionExpr; template <bool OtherConst> friend class AssociationIteratorTy; - using ExprPtrTy = - typename std::conditional<Const, const Expr *, Expr *>::type; - using TSIPtrTy = typename std::conditional<Const, const TypeSourceInfo *, - TypeSourceInfo *>::type; + using ExprPtrTy = std::conditional_t<Const, const Expr *, Expr *>; + using TSIPtrTy = + std::conditional_t<Const, const TypeSourceInfo *, TypeSourceInfo *>; ExprPtrTy E; TSIPtrTy TSI; bool Selected; @@ -5322,10 +5541,9 @@ class GenericSelectionExpr final // const Association &Assoc = *It++; // Oops, Assoc is dangling. using BaseTy = typename AssociationIteratorTy::iterator_facade_base; using StmtPtrPtrTy = - typename std::conditional<Const, const Stmt *const *, Stmt **>::type; - using TSIPtrPtrTy = - typename std::conditional<Const, const TypeSourceInfo *const *, - TypeSourceInfo **>::type; + std::conditional_t<Const, const Stmt *const *, Stmt **>; + using TSIPtrPtrTy = std::conditional_t<Const, const TypeSourceInfo *const *, + TypeSourceInfo **>; StmtPtrPtrTy E; // = nullptr; FIXME: Once support for gcc 4.8 is dropped. TSIPtrPtrTy TSI; // Kept in sync with E. unsigned Offset = 0, SelectedOffset = 0; @@ -5522,12 +5740,11 @@ class ExtVectorElementExpr : public Expr { public: ExtVectorElementExpr(QualType ty, ExprValueKind VK, Expr *base, IdentifierInfo &accessor, SourceLocation loc) - : Expr(ExtVectorElementExprClass, ty, VK, - (VK == VK_RValue ? OK_Ordinary : OK_VectorComponent), - base->isTypeDependent(), base->isValueDependent(), - base->isInstantiationDependent(), - base->containsUnexpandedParameterPack()), - Base(base), Accessor(&accessor), AccessorLoc(loc) {} + : Expr(ExtVectorElementExprClass, ty, VK, + (VK == VK_RValue ? OK_Ordinary : OK_VectorComponent)), + Base(base), Accessor(&accessor), AccessorLoc(loc) { + setDependence(computeDependence(this)); + } /// Build an empty vector element expression. explicit ExtVectorElementExpr(EmptyShell Empty) @@ -5581,11 +5798,9 @@ protected: BlockDecl *TheBlock; public: BlockExpr(BlockDecl *BD, QualType ty) - : Expr(BlockExprClass, ty, VK_RValue, OK_Ordinary, - ty->isDependentType(), ty->isDependentType(), - ty->isInstantiationDependentType() || BD->isDependentContext(), - false), - TheBlock(BD) {} + : Expr(BlockExprClass, ty, VK_RValue, OK_Ordinary), TheBlock(BD) { + setDependence(computeDependence(this)); + } /// Build an empty block expression. explicit BlockExpr(EmptyShell Empty) : Expr(BlockExprClass, Empty) { } @@ -5649,17 +5864,13 @@ private: explicit AsTypeExpr(EmptyShell Empty) : Expr(AsTypeExprClass, Empty) {} public: - AsTypeExpr(Expr* SrcExpr, QualType DstType, - ExprValueKind VK, ExprObjectKind OK, - SourceLocation BuiltinLoc, SourceLocation RParenLoc) - : Expr(AsTypeExprClass, DstType, VK, OK, - DstType->isDependentType(), - DstType->isDependentType() || SrcExpr->isValueDependent(), - (DstType->isInstantiationDependentType() || - SrcExpr->isInstantiationDependent()), - (DstType->containsUnexpandedParameterPack() || - SrcExpr->containsUnexpandedParameterPack())), - SrcExpr(SrcExpr), BuiltinLoc(BuiltinLoc), RParenLoc(RParenLoc) {} + AsTypeExpr(Expr *SrcExpr, QualType DstType, ExprValueKind VK, + ExprObjectKind OK, SourceLocation BuiltinLoc, + SourceLocation RParenLoc) + : Expr(AsTypeExprClass, DstType, VK, OK), SrcExpr(SrcExpr), + BuiltinLoc(BuiltinLoc), RParenLoc(RParenLoc) { + setDependence(computeDependence(this)); + } /// getSrcExpr - Return the Expr to be converted. Expr *getSrcExpr() const { return cast<Expr>(SrcExpr); } @@ -5976,14 +6187,15 @@ public: /// TypoExpr - Internal placeholder for expressions where typo correction /// still needs to be performed and/or an error diagnostic emitted. class TypoExpr : public Expr { + // The location for the typo name. + SourceLocation TypoLoc; + public: - TypoExpr(QualType T) - : Expr(TypoExprClass, T, VK_LValue, OK_Ordinary, - /*isTypeDependent*/ true, - /*isValueDependent*/ true, - /*isInstantiationDependent*/ true, - /*containsUnexpandedParameterPack*/ false) { + TypoExpr(QualType T, SourceLocation TypoLoc) + : Expr(TypoExprClass, T, VK_LValue, OK_Ordinary), TypoLoc(TypoLoc) { assert(T->isDependentType() && "TypoExpr given a non-dependent type"); + setDependence(ExprDependence::TypeValueInstantiation | + ExprDependence::Error); } child_range children() { @@ -5993,14 +6205,88 @@ public: return const_child_range(const_child_iterator(), const_child_iterator()); } - SourceLocation getBeginLoc() const LLVM_READONLY { return SourceLocation(); } - SourceLocation getEndLoc() const LLVM_READONLY { return SourceLocation(); } + SourceLocation getBeginLoc() const LLVM_READONLY { return TypoLoc; } + SourceLocation getEndLoc() const LLVM_READONLY { return TypoLoc; } static bool classof(const Stmt *T) { return T->getStmtClass() == TypoExprClass; } }; + +/// Frontend produces RecoveryExprs on semantic errors that prevent creating +/// other well-formed expressions. E.g. when type-checking of a binary operator +/// fails, we cannot produce a BinaryOperator expression. Instead, we can choose +/// to produce a recovery expression storing left and right operands. +/// +/// RecoveryExpr does not have any semantic meaning in C++, it is only useful to +/// preserve expressions in AST that would otherwise be dropped. It captures +/// subexpressions of some expression that we could not construct and source +/// range covered by the expression. +/// +/// By default, RecoveryExpr uses dependence-bits to take advantage of existing +/// machinery to deal with dependent code in C++, e.g. RecoveryExpr is preserved +/// in `decltype(<broken-expr>)` as part of the `DependentDecltypeType`. In +/// addition to that, clang does not report most errors on dependent +/// expressions, so we get rid of bogus errors for free. However, note that +/// unlike other dependent expressions, RecoveryExpr can be produced in +/// non-template contexts. +/// +/// We will preserve the type in RecoveryExpr when the type is known, e.g. +/// preserving the return type for a broken non-overloaded function call, a +/// overloaded call where all candidates have the same return type. In this +/// case, the expression is not type-dependent (unless the known type is itself +/// dependent) +/// +/// One can also reliably suppress all bogus errors on expressions containing +/// recovery expressions by examining results of Expr::containsErrors(). +/// +/// FIXME: RecoveryExpr is currently generated by default in C++ mode only, as +/// dependence isn't handled properly on several C-only codepaths. +class RecoveryExpr final : public Expr, + private llvm::TrailingObjects<RecoveryExpr, Expr *> { +public: + static RecoveryExpr *Create(ASTContext &Ctx, QualType T, + SourceLocation BeginLoc, SourceLocation EndLoc, + ArrayRef<Expr *> SubExprs); + static RecoveryExpr *CreateEmpty(ASTContext &Ctx, unsigned NumSubExprs); + + ArrayRef<Expr *> subExpressions() { + auto *B = getTrailingObjects<Expr *>(); + return llvm::makeArrayRef(B, B + NumExprs); + } + + ArrayRef<const Expr *> subExpressions() const { + return const_cast<RecoveryExpr *>(this)->subExpressions(); + } + + child_range children() { + Stmt **B = reinterpret_cast<Stmt **>(getTrailingObjects<Expr *>()); + return child_range(B, B + NumExprs); + } + + SourceLocation getBeginLoc() const { return BeginLoc; } + SourceLocation getEndLoc() const { return EndLoc; } + + static bool classof(const Stmt *T) { + return T->getStmtClass() == RecoveryExprClass; + } + +private: + RecoveryExpr(ASTContext &Ctx, QualType T, SourceLocation BeginLoc, + SourceLocation EndLoc, ArrayRef<Expr *> SubExprs); + RecoveryExpr(EmptyShell Empty, unsigned NumSubExprs) + : Expr(RecoveryExprClass, Empty), NumExprs(NumSubExprs) {} + + size_t numTrailingObjects(OverloadToken<Stmt *>) const { return NumExprs; } + + SourceLocation BeginLoc, EndLoc; + unsigned NumExprs; + friend TrailingObjects; + friend class ASTStmtReader; + friend class ASTStmtWriter; +}; + } // end namespace clang #endif // LLVM_CLANG_AST_EXPR_H diff --git a/clang/include/clang/AST/ExprCXX.h b/clang/include/clang/AST/ExprCXX.h index 2c29409e0ca5..6f0b68479b9d 100644 --- a/clang/include/clang/AST/ExprCXX.h +++ b/clang/include/clang/AST/ExprCXX.h @@ -15,15 +15,18 @@ #define LLVM_CLANG_AST_EXPRCXX_H #include "clang/AST/ASTConcept.h" +#include "clang/AST/ComputeDependence.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclBase.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclTemplate.h" #include "clang/AST/DeclarationName.h" +#include "clang/AST/DependenceFlags.h" #include "clang/AST/Expr.h" #include "clang/AST/NestedNameSpecifier.h" #include "clang/AST/OperationKinds.h" #include "clang/AST/Stmt.h" +#include "clang/AST/StmtCXX.h" #include "clang/AST/TemplateBase.h" #include "clang/AST/Type.h" #include "clang/AST/UnresolvedSet.h" @@ -81,6 +84,7 @@ class CXXOperatorCallExpr final : public CallExpr { friend class ASTStmtWriter; SourceRange Range; + FPOptionsOverride Overrides; // CXXOperatorCallExpr has some trailing objects belonging // to CallExpr. See CallExpr for the details. @@ -89,7 +93,7 @@ class CXXOperatorCallExpr final : public CallExpr { CXXOperatorCallExpr(OverloadedOperatorKind OpKind, Expr *Fn, ArrayRef<Expr *> Args, QualType Ty, ExprValueKind VK, - SourceLocation OperatorLoc, FPOptions FPFeatures, + SourceLocation OperatorLoc, FPOptionsOverride FPFeatures, ADLCallKind UsesADL); CXXOperatorCallExpr(unsigned NumArgs, EmptyShell Empty); @@ -98,7 +102,7 @@ public: static CXXOperatorCallExpr * Create(const ASTContext &Ctx, OverloadedOperatorKind OpKind, Expr *Fn, ArrayRef<Expr *> Args, QualType Ty, ExprValueKind VK, - SourceLocation OperatorLoc, FPOptions FPFeatures, + SourceLocation OperatorLoc, FPOptionsOverride FPFeatures, ADLCallKind UsesADL = NotADL); static CXXOperatorCallExpr *CreateEmpty(const ASTContext &Ctx, @@ -119,6 +123,22 @@ public: } bool isAssignmentOp() const { return isAssignmentOp(getOperator()); } + static bool isComparisonOp(OverloadedOperatorKind Opc) { + switch (Opc) { + case OO_EqualEqual: + case OO_ExclaimEqual: + case OO_Greater: + case OO_GreaterEqual: + case OO_Less: + case OO_LessEqual: + case OO_Spaceship: + return true; + default: + return false; + } + } + bool isComparisonOp() const { return isComparisonOp(getOperator()); } + /// Is this written as an infix binary operator? bool isInfixBinaryOp() const; @@ -145,20 +165,10 @@ public: return T->getStmtClass() == CXXOperatorCallExprClass; } - // Set the FP contractability status of this operator. Only meaningful for + // Set the FPFeatures status of this operator. Only meaningful for // operations on floating point types. - void setFPFeatures(FPOptions F) { - CXXOperatorCallExprBits.FPFeatures = F.getInt(); - } - FPOptions getFPFeatures() const { - return FPOptions(CXXOperatorCallExprBits.FPFeatures); - } - - // Get the FP contractability status of this operator. Only meaningful for - // operations on floating point types. - bool isFPContractableWithinStatement() const { - return getFPFeatures().allowFPContractWithinStatement(); - } + void setFPFeatures(FPOptionsOverride F) { Overrides = F; } + FPOptionsOverride getFPFeatures() const { return Overrides; } }; /// Represents a call to a member function that @@ -280,12 +290,10 @@ class CXXRewrittenBinaryOperator : public Expr { public: CXXRewrittenBinaryOperator(Expr *SemanticForm, bool IsReversed) : Expr(CXXRewrittenBinaryOperatorClass, SemanticForm->getType(), - SemanticForm->getValueKind(), SemanticForm->getObjectKind(), - SemanticForm->isTypeDependent(), SemanticForm->isValueDependent(), - SemanticForm->isInstantiationDependent(), - SemanticForm->containsUnexpandedParameterPack()), + SemanticForm->getValueKind(), SemanticForm->getObjectKind()), SemanticForm(SemanticForm) { CXXRewrittenBinaryOperatorBits.IsReversed = IsReversed; + setDependence(computeDependence(this)); } CXXRewrittenBinaryOperator(EmptyShell Empty) : Expr(CXXRewrittenBinaryOperatorClass, Empty), SemanticForm() {} @@ -350,7 +358,8 @@ public: /// This abstract class is inherited by all of the classes /// representing "named" casts: CXXStaticCastExpr for \c static_cast, /// CXXDynamicCastExpr for \c dynamic_cast, CXXReinterpretCastExpr for -/// reinterpret_cast, and CXXConstCastExpr for \c const_cast. +/// reinterpret_cast, CXXConstCastExpr for \c const_cast and +/// CXXAddrspaceCastExpr for addrspace_cast (in OpenCL). class CXXNamedCastExpr : public ExplicitCastExpr { private: // the location of the casting op @@ -396,6 +405,7 @@ public: case CXXDynamicCastExprClass: case CXXReinterpretCastExprClass: case CXXConstCastExprClass: + case CXXAddrspaceCastExprClass: return true; default: return false; @@ -553,6 +563,41 @@ public: } }; +/// A C++ addrspace_cast expression (currently only enabled for OpenCL). +/// +/// This expression node represents a cast between pointers to objects in +/// different address spaces e.g., +/// \c addrspace_cast<global int*>(PtrToGenericInt). +/// +/// A addrspace_cast can cast address space type qualifiers but does not change +/// the underlying value. +class CXXAddrspaceCastExpr final + : public CXXNamedCastExpr, + private llvm::TrailingObjects<CXXAddrspaceCastExpr, CXXBaseSpecifier *> { + CXXAddrspaceCastExpr(QualType ty, ExprValueKind VK, CastKind Kind, Expr *op, + TypeSourceInfo *writtenTy, SourceLocation l, + SourceLocation RParenLoc, SourceRange AngleBrackets) + : CXXNamedCastExpr(CXXAddrspaceCastExprClass, ty, VK, Kind, op, 0, + writtenTy, l, RParenLoc, AngleBrackets) {} + + explicit CXXAddrspaceCastExpr(EmptyShell Empty) + : CXXNamedCastExpr(CXXAddrspaceCastExprClass, Empty, 0) {} + +public: + friend class CastExpr; + friend TrailingObjects; + + static CXXAddrspaceCastExpr * + Create(const ASTContext &Context, QualType T, ExprValueKind VK, CastKind Kind, + Expr *Op, TypeSourceInfo *WrittenTy, SourceLocation L, + SourceLocation RParenLoc, SourceRange AngleBrackets); + static CXXAddrspaceCastExpr *CreateEmpty(const ASTContext &Context); + + static bool classof(const Stmt *T) { + return T->getStmtClass() == CXXAddrspaceCastExprClass; + } +}; + /// A call to a literal operator (C++11 [over.literal]) /// written as a user-defined literal (C++11 [lit.ext]). /// @@ -646,10 +691,10 @@ public: class CXXBoolLiteralExpr : public Expr { public: CXXBoolLiteralExpr(bool Val, QualType Ty, SourceLocation Loc) - : Expr(CXXBoolLiteralExprClass, Ty, VK_RValue, OK_Ordinary, false, false, - false, false) { + : Expr(CXXBoolLiteralExprClass, Ty, VK_RValue, OK_Ordinary) { CXXBoolLiteralExprBits.Value = Val; CXXBoolLiteralExprBits.Loc = Loc; + setDependence(ExprDependence::None); } explicit CXXBoolLiteralExpr(EmptyShell Empty) @@ -684,9 +729,9 @@ public: class CXXNullPtrLiteralExpr : public Expr { public: CXXNullPtrLiteralExpr(QualType Ty, SourceLocation Loc) - : Expr(CXXNullPtrLiteralExprClass, Ty, VK_RValue, OK_Ordinary, false, - false, false, false) { + : Expr(CXXNullPtrLiteralExprClass, Ty, VK_RValue, OK_Ordinary) { CXXNullPtrLiteralExprBits.Loc = Loc; + setDependence(ExprDependence::None); } explicit CXXNullPtrLiteralExpr(EmptyShell Empty) @@ -724,11 +769,10 @@ public: friend class ASTStmtReader; CXXStdInitializerListExpr(QualType Ty, Expr *SubExpr) - : Expr(CXXStdInitializerListExprClass, Ty, VK_RValue, OK_Ordinary, - Ty->isDependentType(), SubExpr->isValueDependent(), - SubExpr->isInstantiationDependent(), - SubExpr->containsUnexpandedParameterPack()), - SubExpr(SubExpr) {} + : Expr(CXXStdInitializerListExprClass, Ty, VK_RValue, OK_Ordinary), + SubExpr(SubExpr) { + setDependence(computeDependence(this)); + } Expr *getSubExpr() { return static_cast<Expr*>(SubExpr); } const Expr *getSubExpr() const { return static_cast<const Expr*>(SubExpr); } @@ -763,32 +807,24 @@ public: /// /// This represents code like \c typeid(int) or \c typeid(*objPtr) class CXXTypeidExpr : public Expr { + friend class ASTStmtReader; + private: llvm::PointerUnion<Stmt *, TypeSourceInfo *> Operand; SourceRange Range; public: CXXTypeidExpr(QualType Ty, TypeSourceInfo *Operand, SourceRange R) - : Expr(CXXTypeidExprClass, Ty, VK_LValue, OK_Ordinary, - // typeid is never type-dependent (C++ [temp.dep.expr]p4) - false, - // typeid is value-dependent if the type or expression are - // dependent - Operand->getType()->isDependentType(), - Operand->getType()->isInstantiationDependentType(), - Operand->getType()->containsUnexpandedParameterPack()), - Operand(Operand), Range(R) {} + : Expr(CXXTypeidExprClass, Ty, VK_LValue, OK_Ordinary), Operand(Operand), + Range(R) { + setDependence(computeDependence(this)); + } CXXTypeidExpr(QualType Ty, Expr *Operand, SourceRange R) - : Expr(CXXTypeidExprClass, Ty, VK_LValue, OK_Ordinary, - // typeid is never type-dependent (C++ [temp.dep.expr]p4) - false, - // typeid is value-dependent if the type or expression are - // dependent - Operand->isTypeDependent() || Operand->isValueDependent(), - Operand->isInstantiationDependent(), - Operand->containsUnexpandedParameterPack()), - Operand(Operand), Range(R) {} + : Expr(CXXTypeidExprClass, Ty, VK_LValue, OK_Ordinary), Operand(Operand), + Range(R) { + setDependence(computeDependence(this)); + } CXXTypeidExpr(EmptyShell Empty, bool isExpr) : Expr(CXXTypeidExprClass, Empty) { @@ -813,22 +849,11 @@ public: assert(isTypeOperand() && "Cannot call getTypeOperand for typeid(expr)"); return Operand.get<TypeSourceInfo *>(); } - - void setTypeOperandSourceInfo(TypeSourceInfo *TSI) { - assert(isTypeOperand() && "Cannot call getTypeOperand for typeid(expr)"); - Operand = TSI; - } - Expr *getExprOperand() const { assert(!isTypeOperand() && "Cannot call getExprOperand for typeid(type)"); return static_cast<Expr*>(Operand.get<Stmt *>()); } - void setExprOperand(Expr *E) { - assert(!isTypeOperand() && "Cannot call getExprOperand for typeid(type)"); - Operand = E; - } - SourceLocation getBeginLoc() const LLVM_READONLY { return Range.getBegin(); } SourceLocation getEndLoc() const LLVM_READONLY { return Range.getEnd(); } SourceRange getSourceRange() const LLVM_READONLY { return Range; } @@ -873,15 +898,12 @@ public: MSPropertyRefExpr(Expr *baseExpr, MSPropertyDecl *decl, bool isArrow, QualType ty, ExprValueKind VK, - NestedNameSpecifierLoc qualifierLoc, - SourceLocation nameLoc) - : Expr(MSPropertyRefExprClass, ty, VK, OK_Ordinary, - /*type-dependent*/ false, baseExpr->isValueDependent(), - baseExpr->isInstantiationDependent(), - baseExpr->containsUnexpandedParameterPack()), - BaseExpr(baseExpr), TheDecl(decl), - MemberLoc(nameLoc), IsArrow(isArrow), - QualifierLoc(qualifierLoc) {} + NestedNameSpecifierLoc qualifierLoc, SourceLocation nameLoc) + : Expr(MSPropertyRefExprClass, ty, VK, OK_Ordinary), BaseExpr(baseExpr), + TheDecl(decl), MemberLoc(nameLoc), IsArrow(isArrow), + QualifierLoc(qualifierLoc) { + setDependence(computeDependence(this)); + } MSPropertyRefExpr(EmptyShell Empty) : Expr(MSPropertyRefExprClass, Empty) {} @@ -949,12 +971,11 @@ class MSPropertySubscriptExpr : public Expr { 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()), + : Expr(MSPropertySubscriptExprClass, Ty, VK, OK), RBracketLoc(RBracketLoc) { SubExprs[BASE_EXPR] = Base; SubExprs[IDX_EXPR] = Idx; + setDependence(computeDependence(this)); } /// Create an empty array subscript expression. @@ -999,25 +1020,26 @@ public: /// /// This represents code like @c __uuidof(COMTYPE) or @c __uuidof(*comPtr) class CXXUuidofExpr : public Expr { + friend class ASTStmtReader; + private: llvm::PointerUnion<Stmt *, TypeSourceInfo *> Operand; - StringRef UuidStr; + MSGuidDecl *Guid; SourceRange Range; public: - CXXUuidofExpr(QualType Ty, TypeSourceInfo *Operand, StringRef UuidStr, + CXXUuidofExpr(QualType Ty, TypeSourceInfo *Operand, MSGuidDecl *Guid, SourceRange R) - : Expr(CXXUuidofExprClass, Ty, VK_LValue, OK_Ordinary, false, - Operand->getType()->isDependentType(), - Operand->getType()->isInstantiationDependentType(), - Operand->getType()->containsUnexpandedParameterPack()), - Operand(Operand), UuidStr(UuidStr), Range(R) {} - - CXXUuidofExpr(QualType Ty, Expr *Operand, StringRef UuidStr, SourceRange R) - : Expr(CXXUuidofExprClass, Ty, VK_LValue, OK_Ordinary, false, - Operand->isTypeDependent(), Operand->isInstantiationDependent(), - Operand->containsUnexpandedParameterPack()), - Operand(Operand), UuidStr(UuidStr), Range(R) {} + : Expr(CXXUuidofExprClass, Ty, VK_LValue, OK_Ordinary), Operand(Operand), + Guid(Guid), Range(R) { + setDependence(computeDependence(this)); + } + + CXXUuidofExpr(QualType Ty, Expr *Operand, MSGuidDecl *Guid, SourceRange R) + : Expr(CXXUuidofExprClass, Ty, VK_LValue, OK_Ordinary), Operand(Operand), + Guid(Guid), Range(R) { + setDependence(computeDependence(this)); + } CXXUuidofExpr(EmptyShell Empty, bool isExpr) : Expr(CXXUuidofExprClass, Empty) { @@ -1038,24 +1060,12 @@ public: assert(isTypeOperand() && "Cannot call getTypeOperand for __uuidof(expr)"); return Operand.get<TypeSourceInfo *>(); } - - void setTypeOperandSourceInfo(TypeSourceInfo *TSI) { - assert(isTypeOperand() && "Cannot call getTypeOperand for __uuidof(expr)"); - Operand = TSI; - } - Expr *getExprOperand() const { assert(!isTypeOperand() && "Cannot call getExprOperand for __uuidof(type)"); return static_cast<Expr*>(Operand.get<Stmt *>()); } - void setExprOperand(Expr *E) { - assert(!isTypeOperand() && "Cannot call getExprOperand for __uuidof(type)"); - Operand = E; - } - - void setUuidStr(StringRef US) { UuidStr = US; } - StringRef getUuidStr() const { return UuidStr; } + MSGuidDecl *getGuidDecl() const { return Guid; } SourceLocation getBeginLoc() const LLVM_READONLY { return Range.getBegin(); } SourceLocation getEndLoc() const LLVM_READONLY { return Range.getEnd(); } @@ -1098,14 +1108,10 @@ public: class CXXThisExpr : public Expr { public: CXXThisExpr(SourceLocation L, QualType Ty, bool IsImplicit) - : Expr(CXXThisExprClass, Ty, VK_RValue, OK_Ordinary, - // 'this' is type-dependent if the class type of the enclosing - // member function is dependent (C++ [temp.dep.expr]p2) - Ty->isDependentType(), Ty->isDependentType(), - Ty->isInstantiationDependentType(), - /*ContainsUnexpandedParameterPack=*/false) { + : Expr(CXXThisExprClass, Ty, VK_RValue, OK_Ordinary) { CXXThisExprBits.IsImplicit = IsImplicit; CXXThisExprBits.Loc = L; + setDependence(computeDependence(this)); } CXXThisExpr(EmptyShell Empty) : Expr(CXXThisExprClass, Empty) {} @@ -1151,12 +1157,10 @@ public: // null if not present. CXXThrowExpr(Expr *Operand, QualType Ty, SourceLocation Loc, bool IsThrownVariableInScope) - : Expr(CXXThrowExprClass, Ty, VK_RValue, OK_Ordinary, false, false, - Operand && Operand->isInstantiationDependent(), - Operand && Operand->containsUnexpandedParameterPack()), - Operand(Operand) { + : Expr(CXXThrowExprClass, Ty, VK_RValue, OK_Ordinary), Operand(Operand) { CXXThrowExprBits.ThrowLoc = Loc; CXXThrowExprBits.IsThrownVariableInScope = IsThrownVariableInScope; + setDependence(computeDependence(this)); } CXXThrowExpr(EmptyShell Empty) : Expr(CXXThrowExprClass, Empty) {} @@ -1210,16 +1214,16 @@ class CXXDefaultArgExpr final : public Expr { DeclContext *UsedContext; CXXDefaultArgExpr(StmtClass SC, SourceLocation Loc, ParmVarDecl *Param, - DeclContext *UsedContext) + DeclContext *UsedContext) : Expr(SC, Param->hasUnparsedDefaultArg() ? Param->getType().getNonReferenceType() : Param->getDefaultArg()->getType(), Param->getDefaultArg()->getValueKind(), - Param->getDefaultArg()->getObjectKind(), false, false, false, - false), + Param->getDefaultArg()->getObjectKind()), Param(Param), UsedContext(UsedContext) { CXXDefaultArgExprBits.Loc = Loc; + setDependence(ExprDependence::None); } public: @@ -1375,13 +1379,12 @@ class CXXBindTemporaryExpr : public Expr { CXXTemporary *Temp = nullptr; Stmt *SubExpr = nullptr; - CXXBindTemporaryExpr(CXXTemporary *temp, Expr* SubExpr) - : Expr(CXXBindTemporaryExprClass, SubExpr->getType(), - VK_RValue, OK_Ordinary, SubExpr->isTypeDependent(), - SubExpr->isValueDependent(), - SubExpr->isInstantiationDependent(), - SubExpr->containsUnexpandedParameterPack()), - Temp(temp), SubExpr(SubExpr) {} + CXXBindTemporaryExpr(CXXTemporary *temp, Expr *SubExpr) + : Expr(CXXBindTemporaryExprClass, SubExpr->getType(), VK_RValue, + OK_Ordinary), + Temp(temp), SubExpr(SubExpr) { + setDependence(computeDependence(this)); + } public: CXXBindTemporaryExpr(EmptyShell Empty) @@ -1632,12 +1635,12 @@ public: CXXInheritedCtorInitExpr(SourceLocation Loc, QualType T, CXXConstructorDecl *Ctor, bool ConstructsVirtualBase, bool InheritedFromVirtualBase) - : Expr(CXXInheritedCtorInitExprClass, T, VK_RValue, OK_Ordinary, false, - false, false, false), + : Expr(CXXInheritedCtorInitExprClass, T, VK_RValue, OK_Ordinary), Constructor(Ctor), Loc(Loc), ConstructsVirtualBase(ConstructsVirtualBase), InheritedFromVirtualBase(InheritedFromVirtualBase) { assert(!T->isDependentType()); + setDependence(ExprDependence::None); } /// Construct an empty C++ inheriting construction expression. @@ -1818,26 +1821,14 @@ Stmt **CXXConstructExpr::getTrailingArgs() { /// and which can never occur implicitly. class LambdaExpr final : public Expr, private llvm::TrailingObjects<LambdaExpr, Stmt *> { + // LambdaExpr has some data stored in LambdaExprBits. + /// The source range that covers the lambda introducer ([...]). SourceRange IntroducerRange; /// The source location of this lambda's capture-default ('=' or '&'). SourceLocation CaptureDefaultLoc; - /// The number of captures. - unsigned NumCaptures : 16; - - /// The default capture kind, which is a value of type - /// LambdaCaptureDefault. - unsigned CaptureDefault : 2; - - /// Whether this lambda had an explicit parameter list vs. an - /// implicit (and empty) parameter list. - unsigned ExplicitParams : 1; - - /// Whether this lambda had the result type explicitly specified. - unsigned ExplicitResultType : 1; - /// The location of the closing brace ('}') that completes /// the lambda. /// @@ -1851,23 +1842,18 @@ class LambdaExpr final : public Expr, /// Construct a lambda expression. LambdaExpr(QualType T, SourceRange IntroducerRange, LambdaCaptureDefault CaptureDefault, - SourceLocation CaptureDefaultLoc, ArrayRef<LambdaCapture> Captures, - bool ExplicitParams, bool ExplicitResultType, - ArrayRef<Expr *> CaptureInits, SourceLocation ClosingBrace, - bool ContainsUnexpandedParameterPack); + SourceLocation CaptureDefaultLoc, bool ExplicitParams, + bool ExplicitResultType, ArrayRef<Expr *> CaptureInits, + SourceLocation ClosingBrace, bool ContainsUnexpandedParameterPack); /// Construct an empty lambda expression. - LambdaExpr(EmptyShell Empty, unsigned NumCaptures) - : Expr(LambdaExprClass, Empty), NumCaptures(NumCaptures), - CaptureDefault(LCD_None), ExplicitParams(false), - ExplicitResultType(false) { - getStoredStmts()[NumCaptures] = nullptr; - } + LambdaExpr(EmptyShell Empty, unsigned NumCaptures); Stmt **getStoredStmts() { return getTrailingObjects<Stmt *>(); } - Stmt *const *getStoredStmts() const { return getTrailingObjects<Stmt *>(); } + void initBodyIfNeeded() const; + public: friend class ASTStmtReader; friend class ASTStmtWriter; @@ -1877,9 +1863,9 @@ public: static LambdaExpr * Create(const ASTContext &C, CXXRecordDecl *Class, SourceRange IntroducerRange, LambdaCaptureDefault CaptureDefault, SourceLocation CaptureDefaultLoc, - ArrayRef<LambdaCapture> Captures, bool ExplicitParams, - bool ExplicitResultType, ArrayRef<Expr *> CaptureInits, - SourceLocation ClosingBrace, bool ContainsUnexpandedParameterPack); + bool ExplicitParams, bool ExplicitResultType, + ArrayRef<Expr *> CaptureInits, SourceLocation ClosingBrace, + bool ContainsUnexpandedParameterPack); /// Construct a new lambda expression that will be deserialized from /// an external source. @@ -1888,13 +1874,11 @@ public: /// Determine the default capture kind for this lambda. LambdaCaptureDefault getCaptureDefault() const { - return static_cast<LambdaCaptureDefault>(CaptureDefault); + return static_cast<LambdaCaptureDefault>(LambdaExprBits.CaptureDefault); } /// Retrieve the location of this lambda's capture-default, if any. - SourceLocation getCaptureDefaultLoc() const { - return CaptureDefaultLoc; - } + SourceLocation getCaptureDefaultLoc() const { return CaptureDefaultLoc; } /// Determine whether one of this lambda's captures is an init-capture. bool isInitCapture(const LambdaCapture *Capture) const; @@ -1917,7 +1901,7 @@ public: capture_iterator capture_end() const; /// Determine the number of captures in this lambda. - unsigned capture_size() const { return NumCaptures; } + unsigned capture_size() const { return LambdaExprBits.NumCaptures; } /// Retrieve this lambda's explicit captures. capture_range explicit_captures() const; @@ -1947,6 +1931,7 @@ public: /// Const iterator that walks over the capture initialization /// arguments. + /// FIXME: This interface is prone to being used incorrectly. using const_capture_init_iterator = Expr *const *; /// Retrieve the initialization expressions for this lambda's captures. @@ -1974,13 +1959,13 @@ public: /// Retrieve the iterator pointing one past the last /// initialization argument for this lambda expression. capture_init_iterator capture_init_end() { - return capture_init_begin() + NumCaptures; + return capture_init_begin() + capture_size(); } /// 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; + return capture_init_begin() + capture_size(); } /// Retrieve the source range covering the lambda introducer, @@ -2014,8 +1999,20 @@ public: /// Whether this is a generic lambda. bool isGenericLambda() const { return getTemplateParameterList(); } - /// Retrieve the body of the lambda. - CompoundStmt *getBody() const; + /// Retrieve the body of the lambda. This will be most of the time + /// a \p CompoundStmt, but can also be \p CoroutineBodyStmt wrapping + /// a \p CompoundStmt. Note that unlike functions, lambda-expressions + /// cannot have a function-try-block. + Stmt *getBody() const; + + /// Retrieve the \p CompoundStmt representing the body of the lambda. + /// This is a convenience function for callers who do not need + /// to handle node(s) which may wrap a \p CompoundStmt. + const CompoundStmt *getCompoundStmtBody() const; + CompoundStmt *getCompoundStmtBody() { + const auto *ConstThis = this; + return const_cast<CompoundStmt *>(ConstThis->getCompoundStmtBody()); + } /// Determine whether the lambda is mutable, meaning that any /// captures values can be modified. @@ -2023,10 +2020,12 @@ public: /// Determine whether this lambda has an explicit parameter /// list vs. an implicit (empty) parameter list. - bool hasExplicitParameters() const { return ExplicitParams; } + bool hasExplicitParameters() const { return LambdaExprBits.ExplicitParams; } /// Whether this lambda had its result type explicitly specified. - bool hasExplicitResultType() const { return ExplicitResultType; } + bool hasExplicitResultType() const { + return LambdaExprBits.ExplicitResultType; + } static bool classof(const Stmt *T) { return T->getStmtClass() == LambdaExprClass; @@ -2038,15 +2037,9 @@ public: SourceLocation getEndLoc() const LLVM_READONLY { return ClosingBrace; } - child_range children() { - // Includes initialization exprs plus body stmt - return child_range(getStoredStmts(), getStoredStmts() + NumCaptures + 1); - } - - const_child_range children() const { - return const_child_range(getStoredStmts(), - getStoredStmts() + NumCaptures + 1); - } + /// Includes the captures and the body of the lambda. + child_range children(); + const_child_range children() const; }; /// An expression "T()" which creates a value-initialized rvalue of type @@ -2061,11 +2054,10 @@ public: /// expression. CXXScalarValueInitExpr(QualType Type, TypeSourceInfo *TypeInfo, SourceLocation RParenLoc) - : Expr(CXXScalarValueInitExprClass, Type, VK_RValue, OK_Ordinary, false, - false, Type->isInstantiationDependentType(), - Type->containsUnexpandedParameterPack()), + : Expr(CXXScalarValueInitExprClass, Type, VK_RValue, OK_Ordinary), TypeInfo(TypeInfo) { CXXScalarValueInitExprBits.RParenLoc = RParenLoc; + setDependence(computeDependence(this)); } explicit CXXScalarValueInitExpr(EmptyShell Shell) @@ -2370,15 +2362,14 @@ public: CXXDeleteExpr(QualType Ty, bool GlobalDelete, bool ArrayForm, bool ArrayFormAsWritten, bool UsualArrayDeleteWantsSize, FunctionDecl *OperatorDelete, Expr *Arg, SourceLocation Loc) - : Expr(CXXDeleteExprClass, Ty, VK_RValue, OK_Ordinary, false, - Arg->isValueDependent(), Arg->isInstantiationDependent(), - Arg->containsUnexpandedParameterPack()), + : Expr(CXXDeleteExprClass, Ty, VK_RValue, OK_Ordinary), OperatorDelete(OperatorDelete), Argument(Arg) { CXXDeleteExprBits.GlobalDelete = GlobalDelete; CXXDeleteExprBits.ArrayForm = ArrayForm; CXXDeleteExprBits.ArrayFormAsWritten = ArrayFormAsWritten; CXXDeleteExprBits.UsualArrayDeleteWantsSize = UsualArrayDeleteWantsSize; CXXDeleteExprBits.Loc = Loc; + setDependence(computeDependence(this)); } explicit CXXDeleteExpr(EmptyShell Shell) : Expr(CXXDeleteExprClass, Shell) {} @@ -2736,15 +2727,15 @@ public: friend class ASTStmtReader; ArrayTypeTraitExpr(SourceLocation loc, ArrayTypeTrait att, - TypeSourceInfo *queried, uint64_t value, - Expr *dimension, SourceLocation rparen, QualType ty) - : Expr(ArrayTypeTraitExprClass, ty, VK_RValue, OK_Ordinary, - false, queried->getType()->isDependentType(), - (queried->getType()->isInstantiationDependentType() || - (dimension && dimension->isInstantiationDependent())), - queried->getType()->containsUnexpandedParameterPack()), - ATT(att), Value(value), Dimension(dimension), - Loc(loc), RParen(rparen), QueriedType(queried) {} + TypeSourceInfo *queried, uint64_t value, Expr *dimension, + SourceLocation rparen, QualType ty) + : Expr(ArrayTypeTraitExprClass, ty, VK_RValue, OK_Ordinary), ATT(att), + Value(value), Dimension(dimension), Loc(loc), RParen(rparen), + QueriedType(queried) { + assert(att <= ATT_Last && "invalid enum value!"); + assert(static_cast<unsigned>(att) == ATT && "ATT overflow!"); + setDependence(computeDependence(this)); + } explicit ArrayTypeTraitExpr(EmptyShell Empty) : Expr(ArrayTypeTraitExprClass, Empty), ATT(0) {} @@ -2802,17 +2793,15 @@ class ExpressionTraitExpr : public Expr { public: friend class ASTStmtReader; - ExpressionTraitExpr(SourceLocation loc, ExpressionTrait et, - Expr *queried, bool value, - SourceLocation rparen, QualType resultType) - : Expr(ExpressionTraitExprClass, resultType, VK_RValue, OK_Ordinary, - false, // Not type-dependent - // Value-dependent if the argument is type-dependent. - queried->isTypeDependent(), - queried->isInstantiationDependent(), - queried->containsUnexpandedParameterPack()), + ExpressionTraitExpr(SourceLocation loc, ExpressionTrait et, Expr *queried, + bool value, SourceLocation rparen, QualType resultType) + : Expr(ExpressionTraitExprClass, resultType, VK_RValue, OK_Ordinary), ET(et), Value(value), Loc(loc), RParen(rparen), - QueriedExpression(queried) {} + QueriedExpression(queried) { + assert(et <= ET_Last && "invalid enum value!"); + assert(static_cast<unsigned>(et) == ET && "ET overflow!"); + setDependence(computeDependence(this)); + } explicit ExpressionTraitExpr(EmptyShell Empty) : Expr(ExpressionTraitExprClass, Empty), ET(0), Value(false) {} @@ -3306,13 +3295,15 @@ public: /// literal is the extent of the enclosing scope. class ExprWithCleanups final : public FullExpr, - private llvm::TrailingObjects<ExprWithCleanups, BlockDecl *> { + private llvm::TrailingObjects< + ExprWithCleanups, + llvm::PointerUnion<BlockDecl *, CompoundLiteralExpr *>> { public: /// The type of objects that are kept in the cleanup. - /// It's useful to remember the set of blocks; we could also - /// remember the set of temporaries, but there's currently - /// no need. - using CleanupObject = BlockDecl *; + /// It's useful to remember the set of blocks and block-scoped compound + /// literals; we could also remember the set of temporaries, but there's + /// currently no need. + using CleanupObject = llvm::PointerUnion<BlockDecl *, CompoundLiteralExpr *>; private: friend class ASTStmtReader; @@ -3965,13 +3956,10 @@ class CXXNoexceptExpr : public Expr { public: CXXNoexceptExpr(QualType Ty, Expr *Operand, CanThrowResult Val, SourceLocation Keyword, SourceLocation RParen) - : Expr(CXXNoexceptExprClass, Ty, VK_RValue, OK_Ordinary, - /*TypeDependent*/ false, - /*ValueDependent*/ Val == CT_Dependent, - Val == CT_Dependent || Operand->isInstantiationDependent(), - Operand->containsUnexpandedParameterPack()), + : Expr(CXXNoexceptExprClass, Ty, VK_RValue, OK_Ordinary), Operand(Operand), Range(Keyword, RParen) { CXXNoexceptExprBits.Value = Val == CT_Cannot; + setDependence(computeDependence(this, Val)); } CXXNoexceptExpr(EmptyShell Empty) : Expr(CXXNoexceptExprClass, Empty) {} @@ -4032,12 +4020,12 @@ public: PackExpansionExpr(QualType T, Expr *Pattern, SourceLocation EllipsisLoc, Optional<unsigned> NumExpansions) : Expr(PackExpansionExprClass, T, Pattern->getValueKind(), - Pattern->getObjectKind(), /*TypeDependent=*/true, - /*ValueDependent=*/true, /*InstantiationDependent=*/true, - /*ContainsUnexpandedParameterPack=*/false), + Pattern->getObjectKind()), EllipsisLoc(EllipsisLoc), NumExpansions(NumExpansions ? *NumExpansions + 1 : 0), - Pattern(Pattern) {} + Pattern(Pattern) { + setDependence(computeDependence(this)); + } PackExpansionExpr(EmptyShell Empty) : Expr(PackExpansionExprClass, Empty) {} @@ -4124,17 +4112,17 @@ class SizeOfPackExpr final /// the given parameter pack. SizeOfPackExpr(QualType SizeType, SourceLocation OperatorLoc, NamedDecl *Pack, SourceLocation PackLoc, SourceLocation RParenLoc, - Optional<unsigned> Length, ArrayRef<TemplateArgument> PartialArgs) - : Expr(SizeOfPackExprClass, SizeType, VK_RValue, OK_Ordinary, - /*TypeDependent=*/false, /*ValueDependent=*/!Length, - /*InstantiationDependent=*/!Length, - /*ContainsUnexpandedParameterPack=*/false), + Optional<unsigned> Length, + ArrayRef<TemplateArgument> PartialArgs) + : Expr(SizeOfPackExprClass, SizeType, VK_RValue, OK_Ordinary), 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"); auto *Args = getTrailingObjects<TemplateArgument>(); std::uninitialized_copy(PartialArgs.begin(), PartialArgs.end(), Args); + setDependence(Length ? ExprDependence::None + : ExprDependence::ValueInstantiation); } /// Create an empty expression. @@ -4225,12 +4213,10 @@ public: SourceLocation Loc, NonTypeTemplateParmDecl *Param, Expr *Replacement) - : Expr(SubstNonTypeTemplateParmExprClass, Ty, ValueKind, OK_Ordinary, - Replacement->isTypeDependent(), Replacement->isValueDependent(), - Replacement->isInstantiationDependent(), - Replacement->containsUnexpandedParameterPack()), + : Expr(SubstNonTypeTemplateParmExprClass, Ty, ValueKind, OK_Ordinary), Param(Param), Replacement(Replacement) { SubstNonTypeTemplateParmExprBits.NameLoc = Loc; + setDependence(computeDependence(this)); } SourceLocation getNameLoc() const { @@ -4544,13 +4530,12 @@ public: CXXFoldExpr(QualType T, SourceLocation LParenLoc, Expr *LHS, BinaryOperatorKind Opcode, SourceLocation EllipsisLoc, Expr *RHS, SourceLocation RParenLoc, Optional<unsigned> NumExpansions) - : Expr(CXXFoldExprClass, T, VK_RValue, OK_Ordinary, - /*Dependent*/ true, true, true, - /*ContainsUnexpandedParameterPack*/ false), - LParenLoc(LParenLoc), EllipsisLoc(EllipsisLoc), RParenLoc(RParenLoc), + : Expr(CXXFoldExprClass, T, VK_RValue, OK_Ordinary), LParenLoc(LParenLoc), + EllipsisLoc(EllipsisLoc), RParenLoc(RParenLoc), NumExpansions(NumExpansions ? *NumExpansions + 1 : 0), Opcode(Opcode) { SubExprs[0] = LHS; SubExprs[1] = RHS; + setDependence(computeDependence(this)); } CXXFoldExpr(EmptyShell Empty) : Expr(CXXFoldExprClass, Empty) {} @@ -4625,27 +4610,25 @@ public: Expr *Ready, Expr *Suspend, Expr *Resume, OpaqueValueExpr *OpaqueValue) : Expr(SC, Resume->getType(), Resume->getValueKind(), - Resume->getObjectKind(), Resume->isTypeDependent(), - Resume->isValueDependent(), Common->isInstantiationDependent(), - Common->containsUnexpandedParameterPack()), + Resume->getObjectKind()), KeywordLoc(KeywordLoc), OpaqueValue(OpaqueValue) { SubExprs[SubExpr::Common] = Common; SubExprs[SubExpr::Ready] = Ready; SubExprs[SubExpr::Suspend] = Suspend; SubExprs[SubExpr::Resume] = Resume; + setDependence(computeDependence(this)); } CoroutineSuspendExpr(StmtClass SC, SourceLocation KeywordLoc, QualType Ty, Expr *Common) - : Expr(SC, Ty, VK_RValue, OK_Ordinary, true, true, true, - Common->containsUnexpandedParameterPack()), - KeywordLoc(KeywordLoc) { + : Expr(SC, Ty, VK_RValue, OK_Ordinary), 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; + setDependence(computeDependence(this)); } CoroutineSuspendExpr(StmtClass SC, EmptyShell Empty) : Expr(SC, Empty) { @@ -4742,10 +4725,7 @@ class DependentCoawaitExpr : public Expr { public: DependentCoawaitExpr(SourceLocation KeywordLoc, QualType Ty, Expr *Op, UnresolvedLookupExpr *OpCoawait) - : Expr(DependentCoawaitExprClass, Ty, VK_RValue, OK_Ordinary, - /*TypeDependent*/ true, /*ValueDependent*/ true, - /*InstantiationDependent*/ true, - Op->containsUnexpandedParameterPack()), + : Expr(DependentCoawaitExprClass, Ty, VK_RValue, OK_Ordinary), KeywordLoc(KeywordLoc) { // NOTE: A co_await expression is dependent on the coroutines promise // type and may be dependent even when the `Op` expression is not. @@ -4753,6 +4733,7 @@ public: "wrong constructor for non-dependent co_await/co_yield expression"); SubExprs[0] = Op; SubExprs[1] = OpCoawait; + setDependence(computeDependence(this)); } DependentCoawaitExpr(EmptyShell Empty) @@ -4827,6 +4808,8 @@ public: : ExplicitCastExpr(BuiltinBitCastExprClass, T, VK, CK, SrcExpr, 0, DstType), KWLoc(KWLoc), RParenLoc(RParenLoc) {} + BuiltinBitCastExpr(EmptyShell Empty) + : ExplicitCastExpr(BuiltinBitCastExprClass, Empty, 0) {} SourceLocation getBeginLoc() const LLVM_READONLY { return KWLoc; } SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; } @@ -4836,99 +4819,6 @@ public: } }; -/// \brief Represents the specialization of a concept - evaluates to a prvalue -/// of type bool. -/// -/// According to C++2a [expr.prim.id]p3 an id-expression that denotes the -/// specialization of a concept results in a prvalue of type bool. -class ConceptSpecializationExpr final : public Expr, public ConceptReference, - private llvm::TrailingObjects<ConceptSpecializationExpr, - TemplateArgument> { - friend class ASTStmtReader; - friend TrailingObjects; -public: - using SubstitutionDiagnostic = std::pair<SourceLocation, std::string>; - -protected: - /// \brief The number of template arguments in the tail-allocated list of - /// converted template arguments. - unsigned NumTemplateArgs; - - /// \brief Information about the satisfaction of the named concept with the - /// given arguments. If this expression is value dependent, this is to be - /// ignored. - ASTConstraintSatisfaction *Satisfaction; - - ConceptSpecializationExpr(const ASTContext &C, NestedNameSpecifierLoc NNS, - SourceLocation TemplateKWLoc, - DeclarationNameInfo ConceptNameInfo, - NamedDecl *FoundDecl, ConceptDecl *NamedConcept, - const ASTTemplateArgumentListInfo *ArgsAsWritten, - ArrayRef<TemplateArgument> ConvertedArgs, - const ConstraintSatisfaction *Satisfaction); - - ConceptSpecializationExpr(EmptyShell Empty, unsigned NumTemplateArgs); - -public: - - static ConceptSpecializationExpr * - Create(const ASTContext &C, NestedNameSpecifierLoc NNS, - SourceLocation TemplateKWLoc, DeclarationNameInfo ConceptNameInfo, - NamedDecl *FoundDecl, ConceptDecl *NamedConcept, - const ASTTemplateArgumentListInfo *ArgsAsWritten, - ArrayRef<TemplateArgument> ConvertedArgs, - const ConstraintSatisfaction *Satisfaction); - - static ConceptSpecializationExpr * - Create(ASTContext &C, EmptyShell Empty, unsigned NumTemplateArgs); - - ArrayRef<TemplateArgument> getTemplateArguments() const { - return ArrayRef<TemplateArgument>(getTrailingObjects<TemplateArgument>(), - NumTemplateArgs); - } - - /// \brief Set new template arguments for this concept specialization. - void setTemplateArguments(ArrayRef<TemplateArgument> Converted); - - /// \brief Whether or not the concept with the given arguments was satisfied - /// when the expression was created. - /// The expression must not be dependent. - bool isSatisfied() const { - assert(!isValueDependent() - && "isSatisfied called on a dependent ConceptSpecializationExpr"); - return Satisfaction->IsSatisfied; - } - - /// \brief Get elaborated satisfaction info about the template arguments' - /// satisfaction of the named concept. - /// The expression must not be dependent. - const ASTConstraintSatisfaction &getSatisfaction() const { - assert(!isValueDependent() - && "getSatisfaction called on dependent ConceptSpecializationExpr"); - return *Satisfaction; - } - - static bool classof(const Stmt *T) { - return T->getStmtClass() == ConceptSpecializationExprClass; - } - - SourceLocation getBeginLoc() const LLVM_READONLY { - return ConceptName.getBeginLoc(); - } - - SourceLocation getEndLoc() const LLVM_READONLY { - return ArgsAsWritten->RAngleLoc; - } - - // Iterators - child_range children() { - return child_range(child_iterator(), child_iterator()); - } - const_child_range children() const { - return const_child_range(const_child_iterator(), const_child_iterator()); - } -}; - } // namespace clang #endif // LLVM_CLANG_AST_EXPRCXX_H diff --git a/clang/include/clang/AST/ExprConcepts.h b/clang/include/clang/AST/ExprConcepts.h new file mode 100644 index 000000000000..2a88ed5175d2 --- /dev/null +++ b/clang/include/clang/AST/ExprConcepts.h @@ -0,0 +1,554 @@ +//===- ExprConcepts.h - C++2a Concepts expressions --------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +/// \file +/// Defines Expressions and AST nodes for C++2a concepts. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_AST_EXPRCONCEPTS_H +#define LLVM_CLANG_AST_EXPRCONCEPTS_H + +#include "clang/AST/ASTContext.h" +#include "clang/AST/ASTConcept.h" +#include "clang/AST/Decl.h" +#include "clang/AST/DeclarationName.h" +#include "clang/AST/DeclTemplate.h" +#include "clang/AST/Expr.h" +#include "clang/AST/NestedNameSpecifier.h" +#include "clang/AST/TemplateBase.h" +#include "clang/AST/Type.h" +#include "clang/Basic/SourceLocation.h" +#include "llvm/Support/TrailingObjects.h" +#include <utility> +#include <string> + +namespace clang { +class ASTStmtReader; +class ASTStmtWriter; + +/// \brief Represents the specialization of a concept - evaluates to a prvalue +/// of type bool. +/// +/// According to C++2a [expr.prim.id]p3 an id-expression that denotes the +/// specialization of a concept results in a prvalue of type bool. +class ConceptSpecializationExpr final : public Expr, public ConceptReference, + private llvm::TrailingObjects<ConceptSpecializationExpr, + TemplateArgument> { + friend class ASTStmtReader; + friend TrailingObjects; +public: + using SubstitutionDiagnostic = std::pair<SourceLocation, std::string>; + +protected: + /// \brief The number of template arguments in the tail-allocated list of + /// converted template arguments. + unsigned NumTemplateArgs; + + /// \brief Information about the satisfaction of the named concept with the + /// given arguments. If this expression is value dependent, this is to be + /// ignored. + ASTConstraintSatisfaction *Satisfaction; + + ConceptSpecializationExpr(const ASTContext &C, NestedNameSpecifierLoc NNS, + SourceLocation TemplateKWLoc, + DeclarationNameInfo ConceptNameInfo, + NamedDecl *FoundDecl, ConceptDecl *NamedConcept, + const ASTTemplateArgumentListInfo *ArgsAsWritten, + ArrayRef<TemplateArgument> ConvertedArgs, + const ConstraintSatisfaction *Satisfaction); + + ConceptSpecializationExpr(const ASTContext &C, ConceptDecl *NamedConcept, + ArrayRef<TemplateArgument> ConvertedArgs, + const ConstraintSatisfaction *Satisfaction, + bool Dependent, + bool ContainsUnexpandedParameterPack); + + ConceptSpecializationExpr(EmptyShell Empty, unsigned NumTemplateArgs); + +public: + + static ConceptSpecializationExpr * + Create(const ASTContext &C, NestedNameSpecifierLoc NNS, + SourceLocation TemplateKWLoc, DeclarationNameInfo ConceptNameInfo, + NamedDecl *FoundDecl, ConceptDecl *NamedConcept, + const ASTTemplateArgumentListInfo *ArgsAsWritten, + ArrayRef<TemplateArgument> ConvertedArgs, + const ConstraintSatisfaction *Satisfaction); + + static ConceptSpecializationExpr * + Create(const ASTContext &C, ConceptDecl *NamedConcept, + ArrayRef<TemplateArgument> ConvertedArgs, + const ConstraintSatisfaction *Satisfaction, + bool Dependent, + bool ContainsUnexpandedParameterPack); + + static ConceptSpecializationExpr * + Create(ASTContext &C, EmptyShell Empty, unsigned NumTemplateArgs); + + ArrayRef<TemplateArgument> getTemplateArguments() const { + return ArrayRef<TemplateArgument>(getTrailingObjects<TemplateArgument>(), + NumTemplateArgs); + } + + /// \brief Set new template arguments for this concept specialization. + void setTemplateArguments(ArrayRef<TemplateArgument> Converted); + + /// \brief Whether or not the concept with the given arguments was satisfied + /// when the expression was created. + /// The expression must not be dependent. + bool isSatisfied() const { + assert(!isValueDependent() + && "isSatisfied called on a dependent ConceptSpecializationExpr"); + return Satisfaction->IsSatisfied; + } + + /// \brief Get elaborated satisfaction info about the template arguments' + /// satisfaction of the named concept. + /// The expression must not be dependent. + const ASTConstraintSatisfaction &getSatisfaction() const { + assert(!isValueDependent() + && "getSatisfaction called on dependent ConceptSpecializationExpr"); + return *Satisfaction; + } + + static bool classof(const Stmt *T) { + return T->getStmtClass() == ConceptSpecializationExprClass; + } + + SourceLocation getBeginLoc() const LLVM_READONLY { + return ConceptName.getBeginLoc(); + } + + SourceLocation getEndLoc() const LLVM_READONLY { + return ArgsAsWritten->RAngleLoc; + } + + // Iterators + child_range children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } +}; + +namespace concepts { + +/// \brief A static requirement that can be used in a requires-expression to +/// check properties of types and expression. +class Requirement { +public: + // Note - simple and compound requirements are both represented by the same + // class (ExprRequirement). + enum RequirementKind { RK_Type, RK_Simple, RK_Compound, RK_Nested }; +private: + const RequirementKind Kind; + // FIXME: use RequirementDependence to model dependence? + bool Dependent : 1; + bool ContainsUnexpandedParameterPack : 1; + bool Satisfied : 1; +public: + struct SubstitutionDiagnostic { + StringRef SubstitutedEntity; + // FIXME: Store diagnostics semantically and not as prerendered strings. + // Fixing this probably requires serialization of PartialDiagnostic + // objects. + SourceLocation DiagLoc; + StringRef DiagMessage; + }; + + Requirement(RequirementKind Kind, bool IsDependent, + bool ContainsUnexpandedParameterPack, bool IsSatisfied = true) : + Kind(Kind), Dependent(IsDependent), + ContainsUnexpandedParameterPack(ContainsUnexpandedParameterPack), + Satisfied(IsSatisfied) {} + + RequirementKind getKind() const { return Kind; } + + bool isSatisfied() const { + assert(!Dependent && + "isSatisfied can only be called on non-dependent requirements."); + return Satisfied; + } + + void setSatisfied(bool IsSatisfied) { + assert(!Dependent && + "setSatisfied can only be called on non-dependent requirements."); + Satisfied = IsSatisfied; + } + + void setDependent(bool IsDependent) { Dependent = IsDependent; } + bool isDependent() const { return Dependent; } + + void setContainsUnexpandedParameterPack(bool Contains) { + ContainsUnexpandedParameterPack = Contains; + } + bool containsUnexpandedParameterPack() const { + return ContainsUnexpandedParameterPack; + } +}; + +/// \brief A requires-expression requirement which queries the existence of a +/// type name or type template specialization ('type' requirements). +class TypeRequirement : public Requirement { +public: + enum SatisfactionStatus { + SS_Dependent, + SS_SubstitutionFailure, + SS_Satisfied + }; +private: + llvm::PointerUnion<SubstitutionDiagnostic *, TypeSourceInfo *> Value; + SatisfactionStatus Status; +public: + friend ASTStmtReader; + friend ASTStmtWriter; + + /// \brief Construct a type requirement from a type. If the given type is not + /// dependent, this indicates that the type exists and the requirement will be + /// satisfied. Otherwise, the SubstitutionDiagnostic constructor is to be + /// used. + TypeRequirement(TypeSourceInfo *T); + + /// \brief Construct a type requirement when the nested name specifier is + /// invalid due to a bad substitution. The requirement is unsatisfied. + TypeRequirement(SubstitutionDiagnostic *Diagnostic) : + Requirement(RK_Type, false, false, false), Value(Diagnostic), + Status(SS_SubstitutionFailure) {} + + SatisfactionStatus getSatisfactionStatus() const { return Status; } + void setSatisfactionStatus(SatisfactionStatus Status) { + this->Status = Status; + } + + bool isSubstitutionFailure() const { + return Status == SS_SubstitutionFailure; + } + + SubstitutionDiagnostic *getSubstitutionDiagnostic() const { + assert(Status == SS_SubstitutionFailure && + "Attempted to get substitution diagnostic when there has been no " + "substitution failure."); + return Value.get<SubstitutionDiagnostic *>(); + } + + TypeSourceInfo *getType() const { + assert(!isSubstitutionFailure() && + "Attempted to get type when there has been a substitution failure."); + return Value.get<TypeSourceInfo *>(); + } + + static bool classof(const Requirement *R) { + return R->getKind() == RK_Type; + } +}; + +/// \brief A requires-expression requirement which queries the validity and +/// properties of an expression ('simple' and 'compound' requirements). +class ExprRequirement : public Requirement { +public: + enum SatisfactionStatus { + SS_Dependent, + SS_ExprSubstitutionFailure, + SS_NoexceptNotMet, + SS_TypeRequirementSubstitutionFailure, + SS_ConstraintsNotSatisfied, + SS_Satisfied + }; + class ReturnTypeRequirement { + llvm::PointerIntPair< + llvm::PointerUnion<TemplateParameterList *, SubstitutionDiagnostic *>, + 1, bool> + TypeConstraintInfo; + public: + friend ASTStmtReader; + friend ASTStmtWriter; + + /// \brief No return type requirement was specified. + ReturnTypeRequirement() : TypeConstraintInfo(nullptr, 0) {} + + /// \brief A return type requirement was specified but it was a + /// substitution failure. + ReturnTypeRequirement(SubstitutionDiagnostic *SubstDiag) : + TypeConstraintInfo(SubstDiag, 0) {} + + /// \brief A 'type constraint' style return type requirement. + /// \param TPL an invented template parameter list containing a single + /// type parameter with a type-constraint. + // TODO: Can we maybe not save the whole template parameter list and just + // the type constraint? Saving the whole TPL makes it easier to handle in + // serialization but is less elegant. + ReturnTypeRequirement(TemplateParameterList *TPL); + + bool isDependent() const { + return TypeConstraintInfo.getInt(); + } + + bool containsUnexpandedParameterPack() const { + if (!isTypeConstraint()) + return false; + return getTypeConstraintTemplateParameterList() + ->containsUnexpandedParameterPack(); + } + + bool isEmpty() const { + return TypeConstraintInfo.getPointer().isNull(); + } + + bool isSubstitutionFailure() const { + return !isEmpty() && + TypeConstraintInfo.getPointer().is<SubstitutionDiagnostic *>(); + } + + bool isTypeConstraint() const { + return !isEmpty() && + TypeConstraintInfo.getPointer().is<TemplateParameterList *>(); + } + + SubstitutionDiagnostic *getSubstitutionDiagnostic() const { + assert(isSubstitutionFailure()); + return TypeConstraintInfo.getPointer().get<SubstitutionDiagnostic *>(); + } + + const TypeConstraint *getTypeConstraint() const; + + TemplateParameterList *getTypeConstraintTemplateParameterList() const { + assert(isTypeConstraint()); + return TypeConstraintInfo.getPointer().get<TemplateParameterList *>(); + } + }; +private: + llvm::PointerUnion<Expr *, SubstitutionDiagnostic *> Value; + SourceLocation NoexceptLoc; // May be empty if noexcept wasn't specified. + ReturnTypeRequirement TypeReq; + ConceptSpecializationExpr *SubstitutedConstraintExpr; + SatisfactionStatus Status; +public: + friend ASTStmtReader; + friend ASTStmtWriter; + + /// \brief Construct a compound requirement. + /// \param E the expression which is checked by this requirement. + /// \param IsSimple whether this was a simple requirement in source. + /// \param NoexceptLoc the location of the noexcept keyword, if it was + /// specified, otherwise an empty location. + /// \param Req the requirement for the type of the checked expression. + /// \param Status the satisfaction status of this requirement. + ExprRequirement( + Expr *E, bool IsSimple, SourceLocation NoexceptLoc, + ReturnTypeRequirement Req, SatisfactionStatus Status, + ConceptSpecializationExpr *SubstitutedConstraintExpr = nullptr); + + /// \brief Construct a compound requirement whose expression was a + /// substitution failure. The requirement is not satisfied. + /// \param E the diagnostic emitted while instantiating the original + /// expression. + /// \param IsSimple whether this was a simple requirement in source. + /// \param NoexceptLoc the location of the noexcept keyword, if it was + /// specified, otherwise an empty location. + /// \param Req the requirement for the type of the checked expression (omit + /// if no requirement was specified). + ExprRequirement(SubstitutionDiagnostic *E, bool IsSimple, + SourceLocation NoexceptLoc, ReturnTypeRequirement Req = {}); + + bool isSimple() const { return getKind() == RK_Simple; } + bool isCompound() const { return getKind() == RK_Compound; } + + bool hasNoexceptRequirement() const { return NoexceptLoc.isValid(); } + SourceLocation getNoexceptLoc() const { return NoexceptLoc; } + + SatisfactionStatus getSatisfactionStatus() const { return Status; } + + bool isExprSubstitutionFailure() const { + return Status == SS_ExprSubstitutionFailure; + } + + const ReturnTypeRequirement &getReturnTypeRequirement() const { + return TypeReq; + } + + ConceptSpecializationExpr * + getReturnTypeRequirementSubstitutedConstraintExpr() const { + assert(Status >= SS_TypeRequirementSubstitutionFailure); + return SubstitutedConstraintExpr; + } + + SubstitutionDiagnostic *getExprSubstitutionDiagnostic() const { + assert(isExprSubstitutionFailure() && + "Attempted to get expression substitution diagnostic when there has " + "been no expression substitution failure"); + return Value.get<SubstitutionDiagnostic *>(); + } + + Expr *getExpr() const { + assert(!isExprSubstitutionFailure() && + "ExprRequirement has no expression because there has been a " + "substitution failure."); + return Value.get<Expr *>(); + } + + static bool classof(const Requirement *R) { + return R->getKind() == RK_Compound || R->getKind() == RK_Simple; + } +}; + +/// \brief A requires-expression requirement which is satisfied when a general +/// constraint expression is satisfied ('nested' requirements). +class NestedRequirement : public Requirement { + llvm::PointerUnion<Expr *, SubstitutionDiagnostic *> Value; + const ASTConstraintSatisfaction *Satisfaction = nullptr; + +public: + friend ASTStmtReader; + friend ASTStmtWriter; + + NestedRequirement(SubstitutionDiagnostic *SubstDiag) : + Requirement(RK_Nested, /*Dependent=*/false, + /*ContainsUnexpandedParameterPack*/false, + /*Satisfied=*/false), Value(SubstDiag) {} + + NestedRequirement(Expr *Constraint) : + Requirement(RK_Nested, /*Dependent=*/true, + Constraint->containsUnexpandedParameterPack()), + Value(Constraint) { + assert(Constraint->isInstantiationDependent() && + "Nested requirement with non-dependent constraint must be " + "constructed with a ConstraintSatisfaction object"); + } + + NestedRequirement(ASTContext &C, Expr *Constraint, + const ConstraintSatisfaction &Satisfaction) : + Requirement(RK_Nested, Constraint->isInstantiationDependent(), + Constraint->containsUnexpandedParameterPack(), + Satisfaction.IsSatisfied), + Value(Constraint), + Satisfaction(ASTConstraintSatisfaction::Create(C, Satisfaction)) {} + + bool isSubstitutionFailure() const { + return Value.is<SubstitutionDiagnostic *>(); + } + + SubstitutionDiagnostic *getSubstitutionDiagnostic() const { + assert(isSubstitutionFailure() && + "getSubstitutionDiagnostic() may not be called when there was no " + "substitution failure."); + return Value.get<SubstitutionDiagnostic *>(); + } + + Expr *getConstraintExpr() const { + assert(!isSubstitutionFailure() && "getConstraintExpr() may not be called " + "on nested requirements with " + "substitution failures."); + return Value.get<Expr *>(); + } + + const ASTConstraintSatisfaction &getConstraintSatisfaction() const { + assert(!isSubstitutionFailure() && "getConstraintSatisfaction() may not be " + "called on nested requirements with " + "substitution failures."); + return *Satisfaction; + } + + static bool classof(const Requirement *R) { + return R->getKind() == RK_Nested; + } +}; + +} // namespace concepts + +/// C++2a [expr.prim.req]: +/// A requires-expression provides a concise way to express requirements on +/// template arguments. A requirement is one that can be checked by name +/// lookup (6.4) or by checking properties of types and expressions. +/// [...] +/// A requires-expression is a prvalue of type bool [...] +class RequiresExpr final : public Expr, + llvm::TrailingObjects<RequiresExpr, ParmVarDecl *, + concepts::Requirement *> { + friend TrailingObjects; + friend class ASTStmtReader; + + unsigned NumLocalParameters; + unsigned NumRequirements; + RequiresExprBodyDecl *Body; + SourceLocation RBraceLoc; + + unsigned numTrailingObjects(OverloadToken<ParmVarDecl *>) const { + return NumLocalParameters; + } + + unsigned numTrailingObjects(OverloadToken<concepts::Requirement *>) const { + return NumRequirements; + } + + RequiresExpr(ASTContext &C, SourceLocation RequiresKWLoc, + RequiresExprBodyDecl *Body, + ArrayRef<ParmVarDecl *> LocalParameters, + ArrayRef<concepts::Requirement *> Requirements, + SourceLocation RBraceLoc); + RequiresExpr(ASTContext &C, EmptyShell Empty, unsigned NumLocalParameters, + unsigned NumRequirements); + +public: + static RequiresExpr * + Create(ASTContext &C, SourceLocation RequiresKWLoc, + RequiresExprBodyDecl *Body, ArrayRef<ParmVarDecl *> LocalParameters, + ArrayRef<concepts::Requirement *> Requirements, + SourceLocation RBraceLoc); + static RequiresExpr * + Create(ASTContext &C, EmptyShell Empty, unsigned NumLocalParameters, + unsigned NumRequirements); + + ArrayRef<ParmVarDecl *> getLocalParameters() const { + return {getTrailingObjects<ParmVarDecl *>(), NumLocalParameters}; + } + + RequiresExprBodyDecl *getBody() const { return Body; } + + ArrayRef<concepts::Requirement *> getRequirements() const { + return {getTrailingObjects<concepts::Requirement *>(), NumRequirements}; + } + + /// \brief Whether or not the requires clause is satisfied. + /// The expression must not be dependent. + bool isSatisfied() const { + assert(!isValueDependent() + && "isSatisfied called on a dependent RequiresExpr"); + return RequiresExprBits.IsSatisfied; + } + + SourceLocation getRequiresKWLoc() const { + return RequiresExprBits.RequiresKWLoc; + } + + SourceLocation getRBraceLoc() const { return RBraceLoc; } + + static bool classof(const Stmt *T) { + return T->getStmtClass() == RequiresExprClass; + } + + SourceLocation getBeginLoc() const LLVM_READONLY { + return RequiresExprBits.RequiresKWLoc; + } + SourceLocation getEndLoc() const LLVM_READONLY { + return RBraceLoc; + } + + // Iterators + child_range children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } +}; + +} // namespace clang + +#endif // LLVM_CLANG_AST_EXPRCONCEPTS_H diff --git a/clang/include/clang/AST/ExprObjC.h b/clang/include/clang/AST/ExprObjC.h index d76b3a26b1f9..4b39d9ab96a6 100644 --- a/clang/include/clang/AST/ExprObjC.h +++ b/clang/include/clang/AST/ExprObjC.h @@ -13,8 +13,10 @@ #ifndef LLVM_CLANG_AST_EXPROBJC_H #define LLVM_CLANG_AST_EXPROBJC_H +#include "clang/AST/ComputeDependence.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclObjC.h" +#include "clang/AST/DependenceFlags.h" #include "clang/AST/Expr.h" #include "clang/AST/OperationKinds.h" #include "clang/AST/SelectorLocationsKind.h" @@ -53,9 +55,10 @@ class ObjCStringLiteral : public Expr { public: ObjCStringLiteral(StringLiteral *SL, QualType T, SourceLocation L) - : Expr(ObjCStringLiteralClass, T, VK_RValue, OK_Ordinary, false, false, - false, false), - String(SL), AtLoc(L) {} + : Expr(ObjCStringLiteralClass, T, VK_RValue, OK_Ordinary), String(SL), + AtLoc(L) { + setDependence(ExprDependence::None); + } explicit ObjCStringLiteral(EmptyShell Empty) : Expr(ObjCStringLiteralClass, Empty) {} @@ -88,9 +91,10 @@ class ObjCBoolLiteralExpr : public Expr { public: ObjCBoolLiteralExpr(bool val, QualType Ty, SourceLocation l) - : Expr(ObjCBoolLiteralExprClass, Ty, VK_RValue, OK_Ordinary, false, false, - false, false), - Value(val), Loc(l) {} + : Expr(ObjCBoolLiteralExprClass, Ty, VK_RValue, OK_Ordinary), Value(val), + Loc(l) { + setDependence(ExprDependence::None); + } explicit ObjCBoolLiteralExpr(EmptyShell Empty) : Expr(ObjCBoolLiteralExprClass, Empty) {} @@ -129,13 +133,11 @@ class ObjCBoxedExpr : public Expr { public: friend class ASTStmtReader; - ObjCBoxedExpr(Expr *E, QualType T, ObjCMethodDecl *method, - SourceRange R) - : Expr(ObjCBoxedExprClass, T, VK_RValue, OK_Ordinary, - E->isTypeDependent(), E->isValueDependent(), - E->isInstantiationDependent(), - E->containsUnexpandedParameterPack()), - SubExpr(E), BoxingMethod(method), Range(R) {} + ObjCBoxedExpr(Expr *E, QualType T, ObjCMethodDecl *method, SourceRange R) + : Expr(ObjCBoxedExprClass, T, VK_RValue, OK_Ordinary), SubExpr(E), + BoxingMethod(method), Range(R) { + setDependence(computeDependence(this)); + } explicit ObjCBoxedExpr(EmptyShell Empty) : Expr(ObjCBoxedExprClass, Empty) {} @@ -409,14 +411,12 @@ class ObjCEncodeExpr : public Expr { SourceLocation AtLoc, RParenLoc; public: - ObjCEncodeExpr(QualType T, TypeSourceInfo *EncodedType, - SourceLocation at, SourceLocation rp) - : Expr(ObjCEncodeExprClass, T, VK_LValue, OK_Ordinary, - EncodedType->getType()->isDependentType(), - EncodedType->getType()->isDependentType(), - EncodedType->getType()->isInstantiationDependentType(), - EncodedType->getType()->containsUnexpandedParameterPack()), - EncodedType(EncodedType), AtLoc(at), RParenLoc(rp) {} + ObjCEncodeExpr(QualType T, TypeSourceInfo *EncodedType, SourceLocation at, + SourceLocation rp) + : Expr(ObjCEncodeExprClass, T, VK_LValue, OK_Ordinary), + EncodedType(EncodedType), AtLoc(at), RParenLoc(rp) { + setDependence(computeDependence(this)); + } explicit ObjCEncodeExpr(EmptyShell Empty) : Expr(ObjCEncodeExprClass, Empty){} @@ -456,11 +456,12 @@ class ObjCSelectorExpr : public Expr { SourceLocation AtLoc, RParenLoc; public: - ObjCSelectorExpr(QualType T, Selector selInfo, - SourceLocation at, SourceLocation rp) - : Expr(ObjCSelectorExprClass, T, VK_RValue, OK_Ordinary, false, false, - false, false), - SelName(selInfo), AtLoc(at), RParenLoc(rp) {} + ObjCSelectorExpr(QualType T, Selector selInfo, SourceLocation at, + SourceLocation rp) + : Expr(ObjCSelectorExprClass, T, VK_RValue, OK_Ordinary), + SelName(selInfo), AtLoc(at), RParenLoc(rp) { + setDependence(ExprDependence::None); + } explicit ObjCSelectorExpr(EmptyShell Empty) : Expr(ObjCSelectorExprClass, Empty) {} @@ -508,11 +509,12 @@ public: friend class ASTStmtReader; friend class ASTStmtWriter; - ObjCProtocolExpr(QualType T, ObjCProtocolDecl *protocol, - SourceLocation at, SourceLocation protoLoc, SourceLocation rp) - : Expr(ObjCProtocolExprClass, T, VK_RValue, OK_Ordinary, false, false, - false, false), - TheProtocol(protocol), AtLoc(at), ProtoLoc(protoLoc), RParenLoc(rp) {} + ObjCProtocolExpr(QualType T, ObjCProtocolDecl *protocol, SourceLocation at, + SourceLocation protoLoc, SourceLocation rp) + : Expr(ObjCProtocolExprClass, T, VK_RValue, OK_Ordinary), + TheProtocol(protocol), AtLoc(at), ProtoLoc(protoLoc), RParenLoc(rp) { + setDependence(ExprDependence::None); + } explicit ObjCProtocolExpr(EmptyShell Empty) : Expr(ObjCProtocolExprClass, Empty) {} @@ -558,17 +560,15 @@ class ObjCIvarRefExpr : public Expr { bool IsFreeIvar : 1; public: - ObjCIvarRefExpr(ObjCIvarDecl *d, QualType t, - SourceLocation l, SourceLocation oploc, - Expr *base, - bool arrow = false, bool freeIvar = false) + ObjCIvarRefExpr(ObjCIvarDecl *d, QualType t, SourceLocation l, + SourceLocation oploc, Expr *base, bool arrow = false, + bool freeIvar = false) : Expr(ObjCIvarRefExprClass, t, VK_LValue, - d->isBitField() ? OK_BitField : OK_Ordinary, - /*TypeDependent=*/false, base->isValueDependent(), - base->isInstantiationDependent(), - base->containsUnexpandedParameterPack()), + d->isBitField() ? OK_BitField : OK_Ordinary), D(d), Base(base), Loc(l), OpLoc(oploc), IsArrow(arrow), - IsFreeIvar(freeIvar) {} + IsFreeIvar(freeIvar) { + setDependence(computeDependence(this)); + } explicit ObjCIvarRefExpr(EmptyShell Empty) : Expr(ObjCIvarRefExprClass, Empty) {} @@ -645,57 +645,53 @@ private: llvm::PointerUnion<Stmt *, const Type *, ObjCInterfaceDecl *> Receiver; public: - ObjCPropertyRefExpr(ObjCPropertyDecl *PD, QualType t, - ExprValueKind VK, ExprObjectKind OK, - SourceLocation l, Expr *base) - : Expr(ObjCPropertyRefExprClass, t, VK, OK, - /*TypeDependent=*/false, base->isValueDependent(), - base->isInstantiationDependent(), - base->containsUnexpandedParameterPack()), - PropertyOrGetter(PD, false), IdLoc(l), Receiver(base) { + ObjCPropertyRefExpr(ObjCPropertyDecl *PD, QualType t, ExprValueKind VK, + ExprObjectKind OK, SourceLocation l, Expr *base) + : Expr(ObjCPropertyRefExprClass, t, VK, OK), PropertyOrGetter(PD, false), + IdLoc(l), Receiver(base) { assert(t->isSpecificPlaceholderType(BuiltinType::PseudoObject)); + setDependence(computeDependence(this)); } - ObjCPropertyRefExpr(ObjCPropertyDecl *PD, QualType t, - ExprValueKind VK, ExprObjectKind OK, - SourceLocation l, SourceLocation sl, QualType st) - : Expr(ObjCPropertyRefExprClass, t, VK, OK, - /*TypeDependent=*/false, false, st->isInstantiationDependentType(), - st->containsUnexpandedParameterPack()), - PropertyOrGetter(PD, false), IdLoc(l), ReceiverLoc(sl), - Receiver(st.getTypePtr()) { + ObjCPropertyRefExpr(ObjCPropertyDecl *PD, QualType t, ExprValueKind VK, + ExprObjectKind OK, SourceLocation l, SourceLocation sl, + QualType st) + : Expr(ObjCPropertyRefExprClass, t, VK, OK), PropertyOrGetter(PD, false), + IdLoc(l), ReceiverLoc(sl), Receiver(st.getTypePtr()) { assert(t->isSpecificPlaceholderType(BuiltinType::PseudoObject)); + setDependence(computeDependence(this)); } ObjCPropertyRefExpr(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter, QualType T, ExprValueKind VK, ExprObjectKind OK, SourceLocation IdLoc, Expr *Base) - : Expr(ObjCPropertyRefExprClass, T, VK, OK, false, - Base->isValueDependent(), Base->isInstantiationDependent(), - Base->containsUnexpandedParameterPack()), + : Expr(ObjCPropertyRefExprClass, T, VK, OK), PropertyOrGetter(Getter, true), SetterAndMethodRefFlags(Setter, 0), IdLoc(IdLoc), Receiver(Base) { assert(T->isSpecificPlaceholderType(BuiltinType::PseudoObject)); + setDependence(computeDependence(this)); } ObjCPropertyRefExpr(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter, QualType T, ExprValueKind VK, ExprObjectKind OK, - SourceLocation IdLoc, - SourceLocation SuperLoc, QualType SuperTy) - : Expr(ObjCPropertyRefExprClass, T, VK, OK, false, false, false, false), + SourceLocation IdLoc, SourceLocation SuperLoc, + QualType SuperTy) + : Expr(ObjCPropertyRefExprClass, T, VK, OK), PropertyOrGetter(Getter, true), SetterAndMethodRefFlags(Setter, 0), IdLoc(IdLoc), ReceiverLoc(SuperLoc), Receiver(SuperTy.getTypePtr()) { assert(T->isSpecificPlaceholderType(BuiltinType::PseudoObject)); + setDependence(computeDependence(this)); } ObjCPropertyRefExpr(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter, QualType T, ExprValueKind VK, ExprObjectKind OK, - SourceLocation IdLoc, - SourceLocation ReceiverLoc, ObjCInterfaceDecl *Receiver) - : Expr(ObjCPropertyRefExprClass, T, VK, OK, false, false, false, false), + SourceLocation IdLoc, SourceLocation ReceiverLoc, + ObjCInterfaceDecl *Receiver) + : Expr(ObjCPropertyRefExprClass, T, VK, OK), PropertyOrGetter(Getter, true), SetterAndMethodRefFlags(Setter, 0), IdLoc(IdLoc), ReceiverLoc(ReceiverLoc), Receiver(Receiver) { assert(T->isSpecificPlaceholderType(BuiltinType::PseudoObject)); + setDependence(computeDependence(this)); } explicit ObjCPropertyRefExpr(EmptyShell Empty) @@ -859,20 +855,14 @@ class ObjCSubscriptRefExpr : public Expr { ObjCMethodDecl *SetAtIndexMethodDecl; public: - ObjCSubscriptRefExpr(Expr *base, Expr *key, QualType T, - ExprValueKind VK, ExprObjectKind OK, - ObjCMethodDecl *getMethod, + ObjCSubscriptRefExpr(Expr *base, Expr *key, QualType T, ExprValueKind VK, + ExprObjectKind OK, ObjCMethodDecl *getMethod, ObjCMethodDecl *setMethod, SourceLocation RB) - : Expr(ObjCSubscriptRefExprClass, T, VK, OK, - base->isTypeDependent() || key->isTypeDependent(), - base->isValueDependent() || key->isValueDependent(), - (base->isInstantiationDependent() || - key->isInstantiationDependent()), - (base->containsUnexpandedParameterPack() || - key->containsUnexpandedParameterPack())), - RBracket(RB), GetAtIndexMethodDecl(getMethod), - SetAtIndexMethodDecl(setMethod) { - SubExprs[BASE] = base; SubExprs[KEY] = key; + : Expr(ObjCSubscriptRefExprClass, T, VK, OK), RBracket(RB), + GetAtIndexMethodDecl(getMethod), SetAtIndexMethodDecl(setMethod) { + SubExprs[BASE] = base; + SubExprs[KEY] = key; + setDependence(computeDependence(this)); } explicit ObjCSubscriptRefExpr(EmptyShell Empty) @@ -1505,11 +1495,10 @@ class ObjCIsaExpr : public Expr { public: ObjCIsaExpr(Expr *base, bool isarrow, SourceLocation l, SourceLocation oploc, QualType ty) - : Expr(ObjCIsaExprClass, ty, VK_LValue, OK_Ordinary, - /*TypeDependent=*/false, base->isValueDependent(), - base->isInstantiationDependent(), - /*ContainsUnexpandedParameterPack=*/false), - Base(base), IsaMemberLoc(l), OpLoc(oploc), IsArrow(isarrow) {} + : Expr(ObjCIsaExprClass, ty, VK_LValue, OK_Ordinary), Base(base), + IsaMemberLoc(l), OpLoc(oploc), IsArrow(isarrow) { + setDependence(computeDependence(this)); + } /// Build an empty expression. explicit ObjCIsaExpr(EmptyShell Empty) : Expr(ObjCIsaExprClass, Empty) {} @@ -1591,12 +1580,10 @@ class ObjCIndirectCopyRestoreExpr : public Expr { public: ObjCIndirectCopyRestoreExpr(Expr *operand, QualType type, bool shouldCopy) - : Expr(ObjCIndirectCopyRestoreExprClass, type, VK_LValue, OK_Ordinary, - operand->isTypeDependent(), operand->isValueDependent(), - operand->isInstantiationDependent(), - operand->containsUnexpandedParameterPack()), + : Expr(ObjCIndirectCopyRestoreExprClass, type, VK_LValue, OK_Ordinary), Operand(operand) { setShouldCopy(shouldCopy); + setDependence(computeDependence(this)); } Expr *getSubExpr() { return cast<Expr>(Operand); } @@ -1705,9 +1692,10 @@ class ObjCAvailabilityCheckExpr : public Expr { public: ObjCAvailabilityCheckExpr(VersionTuple VersionToCheck, SourceLocation AtLoc, SourceLocation RParen, QualType Ty) - : Expr(ObjCAvailabilityCheckExprClass, Ty, VK_RValue, OK_Ordinary, false, - false, false, false), - VersionToCheck(VersionToCheck), AtLoc(AtLoc), RParen(RParen) {} + : Expr(ObjCAvailabilityCheckExprClass, Ty, VK_RValue, OK_Ordinary), + VersionToCheck(VersionToCheck), AtLoc(AtLoc), RParen(RParen) { + setDependence(ExprDependence::None); + } explicit ObjCAvailabilityCheckExpr(EmptyShell Shell) : Expr(ObjCAvailabilityCheckExprClass, Shell) {} diff --git a/clang/include/clang/AST/ExprOpenMP.h b/clang/include/clang/AST/ExprOpenMP.h index 5607d2d1dc58..be5dda992334 100644 --- a/clang/include/clang/AST/ExprOpenMP.h +++ b/clang/include/clang/AST/ExprOpenMP.h @@ -13,62 +13,66 @@ #ifndef LLVM_CLANG_AST_EXPROPENMP_H #define LLVM_CLANG_AST_EXPROPENMP_H +#include "clang/AST/ComputeDependence.h" #include "clang/AST/Expr.h" namespace clang { -/// OpenMP 4.0 [2.4, Array Sections]. +/// OpenMP 5.0 [2.1.5, Array Sections]. /// To specify an array section in an OpenMP construct, array subscript /// expressions are extended with the following syntax: /// \code +/// [ lower-bound : length : stride ] +/// [ lower-bound : length : ] /// [ lower-bound : length ] +/// [ lower-bound : : stride ] +/// [ lower-bound : : ] /// [ lower-bound : ] +/// [ : length : stride ] +/// [ : length : ] /// [ : length ] +/// [ : : stride ] +/// [ : : ] /// [ : ] /// \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 +/// Each of the lower-bound, length, and stride expressions if specified must be +/// an integral type expressions of the base language. When evaluated /// they represent a set of integer values as follows: /// \code -/// { lower-bound, lower-bound + 1, lower-bound + 2,... , lower-bound + length - -/// 1 } +/// { lower-bound, lower-bound + stride, lower-bound + 2 * stride,... , +/// lower-bound + ((length - 1) * stride) } /// \endcode /// The lower-bound and length must evaluate to non-negative integers. +/// The stride must evaluate to a positive integer. /// 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. +/// When the stride is absent it defaults to 1. +/// When the length is absent it defaults to ⌈(size − lower-bound)/stride⌉, +/// where size is the size of the array dimension. When the lower-bound is +/// absent it defaults to 0. class OMPArraySectionExpr : public Expr { - enum { BASE, LOWER_BOUND, LENGTH, END_EXPR }; + enum { BASE, LOWER_BOUND, LENGTH, STRIDE, END_EXPR }; Stmt *SubExprs[END_EXPR]; - SourceLocation ColonLoc; + SourceLocation ColonLocFirst; + SourceLocation ColonLocSecond; 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) { + OMPArraySectionExpr(Expr *Base, Expr *LowerBound, Expr *Length, Expr *Stride, + QualType Type, ExprValueKind VK, ExprObjectKind OK, + SourceLocation ColonLocFirst, + SourceLocation ColonLocSecond, SourceLocation RBracketLoc) + : Expr(OMPArraySectionExprClass, Type, VK, OK), + ColonLocFirst(ColonLocFirst), ColonLocSecond(ColonLocSecond), + RBracketLoc(RBracketLoc) { SubExprs[BASE] = Base; SubExprs[LOWER_BOUND] = LowerBound; SubExprs[LENGTH] = Length; + SubExprs[STRIDE] = Stride; + setDependence(computeDependence(this)); } /// Create an empty array section expression. @@ -100,13 +104,22 @@ public: /// Set length of the array section. void setLength(Expr *E) { SubExprs[LENGTH] = E; } + /// Get stride of array section. + Expr *getStride() { return cast_or_null<Expr>(SubExprs[STRIDE]); } + const Expr *getStride() const { return cast_or_null<Expr>(SubExprs[STRIDE]); } + /// Set length of the array section. + void setStride(Expr *E) { SubExprs[STRIDE] = E; } + SourceLocation getBeginLoc() const LLVM_READONLY { return getBase()->getBeginLoc(); } SourceLocation getEndLoc() const LLVM_READONLY { return RBracketLoc; } - SourceLocation getColonLoc() const { return ColonLoc; } - void setColonLoc(SourceLocation L) { ColonLoc = L; } + SourceLocation getColonLocFirst() const { return ColonLocFirst; } + void setColonLocFirst(SourceLocation L) { ColonLocFirst = L; } + + SourceLocation getColonLocSecond() const { return ColonLocSecond; } + void setColonLocSecond(SourceLocation L) { ColonLocSecond = L; } SourceLocation getRBracketLoc() const { return RBracketLoc; } void setRBracketLoc(SourceLocation L) { RBracketLoc = L; } @@ -127,6 +140,286 @@ public: return const_child_range(&SubExprs[BASE], &SubExprs[END_EXPR]); } }; + +/// An explicit cast in C or a C-style cast in C++, which uses the syntax +/// ([s1][s2]...[sn])expr. For example: @c ([3][3])f. +class OMPArrayShapingExpr final + : public Expr, + private llvm::TrailingObjects<OMPArrayShapingExpr, Expr *, SourceRange> { + friend TrailingObjects; + friend class ASTStmtReader; + friend class ASTStmtWriter; + /// Base node. + SourceLocation LPLoc; /// The location of the left paren + SourceLocation RPLoc; /// The location of the right paren + unsigned NumDims = 0; /// Number of dimensions in the shaping expression. + + /// Construct full expression. + OMPArrayShapingExpr(QualType ExprTy, Expr *Op, SourceLocation L, + SourceLocation R, ArrayRef<Expr *> Dims); + + /// Construct an empty expression. + explicit OMPArrayShapingExpr(EmptyShell Shell, unsigned NumDims) + : Expr(OMPArrayShapingExprClass, Shell), NumDims(NumDims) {} + + /// Sets the dimensions for the array shaping. + void setDimensions(ArrayRef<Expr *> Dims); + + /// Sets the base expression for array shaping operation. + void setBase(Expr *Op) { getTrailingObjects<Expr *>()[NumDims] = Op; } + + /// Sets source ranges for the brackets in the array shaping operation. + void setBracketsRanges(ArrayRef<SourceRange> BR); + + unsigned numTrailingObjects(OverloadToken<Expr *>) const { + // Add an extra one for the base expression. + return NumDims + 1; + } + + unsigned numTrailingObjects(OverloadToken<SourceRange>) const { + return NumDims; + } + +public: + static OMPArrayShapingExpr *Create(const ASTContext &Context, QualType T, + Expr *Op, SourceLocation L, + SourceLocation R, ArrayRef<Expr *> Dims, + ArrayRef<SourceRange> BracketRanges); + + static OMPArrayShapingExpr *CreateEmpty(const ASTContext &Context, + unsigned NumDims); + + SourceLocation getLParenLoc() const { return LPLoc; } + void setLParenLoc(SourceLocation L) { LPLoc = L; } + + SourceLocation getRParenLoc() const { return RPLoc; } + void setRParenLoc(SourceLocation L) { RPLoc = L; } + + SourceLocation getBeginLoc() const LLVM_READONLY { return LPLoc; } + SourceLocation getEndLoc() const LLVM_READONLY { + return getBase()->getEndLoc(); + } + + /// Fetches the dimensions for array shaping expression. + ArrayRef<Expr *> getDimensions() const { + return llvm::makeArrayRef(getTrailingObjects<Expr *>(), NumDims); + } + + /// Fetches source ranges for the brackets os the array shaping expression. + ArrayRef<SourceRange> getBracketsRanges() const { + return llvm::makeArrayRef(getTrailingObjects<SourceRange>(), NumDims); + } + + /// Fetches base expression of array shaping expression. + Expr *getBase() { return getTrailingObjects<Expr *>()[NumDims]; } + const Expr *getBase() const { return getTrailingObjects<Expr *>()[NumDims]; } + + static bool classof(const Stmt *T) { + return T->getStmtClass() == OMPArrayShapingExprClass; + } + + // Iterators + child_range children() { + Stmt **Begin = reinterpret_cast<Stmt **>(getTrailingObjects<Expr *>()); + return child_range(Begin, Begin + NumDims + 1); + } + const_child_range children() const { + Stmt *const *Begin = + reinterpret_cast<Stmt *const *>(getTrailingObjects<Expr *>()); + return const_child_range(Begin, Begin + NumDims + 1); + } +}; + +/// Helper expressions and declaration for OMPIteratorExpr class for each +/// iteration space. +struct OMPIteratorHelperData { + /// Internal normalized counter. + VarDecl *CounterVD = nullptr; + /// Normalized upper bound. Normalized loop iterates from 0 to Upper with + /// step 1. + Expr *Upper = nullptr; + /// Update expression for the originally specified iteration variable, + /// calculated as VD = Begin + CounterVD * Step; + Expr *Update = nullptr; + /// Updater for the internal counter: ++CounterVD; + Expr *CounterUpdate = nullptr; +}; + +/// OpenMP 5.0 [2.1.6 Iterators] +/// Iterators are identifiers that expand to multiple values in the clause on +/// which they appear. +/// The syntax of the iterator modifier is as follows: +/// \code +/// iterator(iterators-definition) +/// \endcode +/// where iterators-definition is one of the following: +/// \code +/// iterator-specifier [, iterators-definition ] +/// \endcode +/// where iterator-specifier is one of the following: +/// \code +/// [ iterator-type ] identifier = range-specification +/// \endcode +/// where identifier is a base language identifier. +/// iterator-type is a type name. +/// range-specification is of the form begin:end[:step], where begin and end are +/// expressions for which their types can be converted to iterator-type and step +/// is an integral expression. +/// In an iterator-specifier, if the iterator-type is not specified then the +/// type of that iterator is of int type. +/// The iterator-type must be an integral or pointer type. +/// The iterator-type must not be const qualified. +class OMPIteratorExpr final + : public Expr, + private llvm::TrailingObjects<OMPIteratorExpr, Decl *, Expr *, + SourceLocation, OMPIteratorHelperData> { +public: + /// Iterator range representation begin:end[:step]. + struct IteratorRange { + Expr *Begin = nullptr; + Expr *End = nullptr; + Expr *Step = nullptr; + }; + /// Iterator definition representation. + struct IteratorDefinition { + Decl *IteratorDecl = nullptr; + IteratorRange Range; + SourceLocation AssignmentLoc; + SourceLocation ColonLoc, SecondColonLoc; + }; + +private: + friend TrailingObjects; + friend class ASTStmtReader; + friend class ASTStmtWriter; + + /// Offset in the list of expressions for subelements of the ranges. + enum class RangeExprOffset { + Begin = 0, + End = 1, + Step = 2, + Total = 3, + }; + /// Offset in the list of locations for subelements of colon symbols + /// locations. + enum class RangeLocOffset { + AssignLoc = 0, + FirstColonLoc = 1, + SecondColonLoc = 2, + Total = 3, + }; + /// Location of 'iterator' keyword. + SourceLocation IteratorKwLoc; + /// Location of '('. + SourceLocation LPLoc; + /// Location of ')'. + SourceLocation RPLoc; + /// Number of iterator definitions. + unsigned NumIterators = 0; + + OMPIteratorExpr(QualType ExprTy, SourceLocation IteratorKwLoc, + SourceLocation L, SourceLocation R, + ArrayRef<IteratorDefinition> Data, + ArrayRef<OMPIteratorHelperData> Helpers); + + /// Construct an empty expression. + explicit OMPIteratorExpr(EmptyShell Shell, unsigned NumIterators) + : Expr(OMPIteratorExprClass, Shell), NumIterators(NumIterators) {} + + /// Sets basic declaration for the specified iterator definition. + void setIteratorDeclaration(unsigned I, Decl *D); + + /// Sets the location of the assignment symbol for the specified iterator + /// definition. + void setAssignmentLoc(unsigned I, SourceLocation Loc); + + /// Sets begin, end and optional step expressions for specified iterator + /// definition. + void setIteratorRange(unsigned I, Expr *Begin, SourceLocation ColonLoc, + Expr *End, SourceLocation SecondColonLoc, Expr *Step); + + /// Sets helpers for the specified iteration space. + void setHelper(unsigned I, const OMPIteratorHelperData &D); + + unsigned numTrailingObjects(OverloadToken<Decl *>) const { + return NumIterators; + } + + unsigned numTrailingObjects(OverloadToken<Expr *>) const { + return NumIterators * static_cast<int>(RangeExprOffset::Total); + } + + unsigned numTrailingObjects(OverloadToken<SourceLocation>) const { + return NumIterators * static_cast<int>(RangeLocOffset::Total); + } + +public: + static OMPIteratorExpr *Create(const ASTContext &Context, QualType T, + SourceLocation IteratorKwLoc, SourceLocation L, + SourceLocation R, + ArrayRef<IteratorDefinition> Data, + ArrayRef<OMPIteratorHelperData> Helpers); + + static OMPIteratorExpr *CreateEmpty(const ASTContext &Context, + unsigned NumIterators); + + SourceLocation getLParenLoc() const { return LPLoc; } + void setLParenLoc(SourceLocation L) { LPLoc = L; } + + SourceLocation getRParenLoc() const { return RPLoc; } + void setRParenLoc(SourceLocation L) { RPLoc = L; } + + SourceLocation getIteratorKwLoc() const { return IteratorKwLoc; } + void setIteratorKwLoc(SourceLocation L) { IteratorKwLoc = L; } + SourceLocation getBeginLoc() const LLVM_READONLY { return IteratorKwLoc; } + SourceLocation getEndLoc() const LLVM_READONLY { return RPLoc; } + + /// Gets the iterator declaration for the given iterator. + Decl *getIteratorDecl(unsigned I); + const Decl *getIteratorDecl(unsigned I) const { + return const_cast<OMPIteratorExpr *>(this)->getIteratorDecl(I); + } + + /// Gets the iterator range for the given iterator. + IteratorRange getIteratorRange(unsigned I); + const IteratorRange getIteratorRange(unsigned I) const { + return const_cast<OMPIteratorExpr *>(this)->getIteratorRange(I); + } + + /// Gets the location of '=' for the given iterator definition. + SourceLocation getAssignLoc(unsigned I) const; + /// Gets the location of the first ':' in the range for the given iterator + /// definition. + SourceLocation getColonLoc(unsigned I) const; + /// Gets the location of the second ':' (if any) in the range for the given + /// iteratori definition. + SourceLocation getSecondColonLoc(unsigned I) const; + + /// Returns number of iterator definitions. + unsigned numOfIterators() const { return NumIterators; } + + /// Fetches helper data for the specified iteration space. + OMPIteratorHelperData &getHelper(unsigned I); + const OMPIteratorHelperData &getHelper(unsigned I) const; + + static bool classof(const Stmt *T) { + return T->getStmtClass() == OMPIteratorExprClass; + } + + // Iterators + child_range children() { + Stmt **Begin = reinterpret_cast<Stmt **>(getTrailingObjects<Expr *>()); + return child_range( + Begin, Begin + NumIterators * static_cast<int>(RangeExprOffset::Total)); + } + const_child_range children() const { + Stmt *const *Begin = + reinterpret_cast<Stmt *const *>(getTrailingObjects<Expr *>()); + return const_child_range( + Begin, Begin + NumIterators * static_cast<int>(RangeExprOffset::Total)); + } +}; + } // end namespace clang #endif diff --git a/clang/include/clang/AST/ExternalASTSource.h b/clang/include/clang/AST/ExternalASTSource.h index 899ac3f66937..def877b91816 100644 --- a/clang/include/clang/AST/ExternalASTSource.h +++ b/clang/include/clang/AST/ExternalASTSource.h @@ -17,7 +17,6 @@ #include "clang/AST/CharUnits.h" #include "clang/AST/DeclBase.h" #include "clang/Basic/LLVM.h" -#include "clang/Basic/Module.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/IntrusiveRefCntPtr.h" @@ -39,6 +38,7 @@ namespace clang { class ASTConsumer; class ASTContext; +class ASTSourceDescriptor; class CXXBaseSpecifier; class CXXCtorInitializer; class CXXRecordDecl; @@ -165,31 +165,6 @@ public: /// object file. virtual bool DeclIsFromPCHWithObjectFile(const Decl *D) { return false; } - /// 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; - ASTFileSignature Signature; - const Module *ClangModule = nullptr; - - public: - ASTSourceDescriptor() = default; - ASTSourceDescriptor(StringRef Name, StringRef Path, StringRef ASTFile, - ASTFileSignature Signature) - : PCHModuleName(std::move(Name)), Path(std::move(Path)), - ASTFile(std::move(ASTFile)), Signature(Signature) {} - ASTSourceDescriptor(const Module &M); - - std::string getModuleName() const; - StringRef getPath() const { return Path; } - StringRef getASTFile() const { return ASTFile; } - ASTFileSignature getSignature() const { return Signature; } - const Module *getModuleOrNull() const { return ClangModule; } - }; - /// Return a descriptor for the corresponding module, if one exists. virtual llvm::Optional<ASTSourceDescriptor> getSourceDescriptor(unsigned ID); @@ -504,9 +479,8 @@ struct PointerLikeTypeTraits< static void *getAsVoidPointer(Ptr P) { return P.getOpaqueValue(); } static Ptr getFromVoidPointer(void *P) { return Ptr::getFromOpaqueValue(P); } - enum { - NumLowBitsAvailable = PointerLikeTypeTraits<T>::NumLowBitsAvailable - 1 - }; + static constexpr int NumLowBitsAvailable = + PointerLikeTypeTraits<T>::NumLowBitsAvailable - 1; }; } // namespace llvm diff --git a/clang/include/clang/AST/GlobalDecl.h b/clang/include/clang/AST/GlobalDecl.h index 145e961a23a3..d8ac498be54f 100644 --- a/clang/include/clang/AST/GlobalDecl.h +++ b/clang/include/clang/AST/GlobalDecl.h @@ -14,6 +14,7 @@ #ifndef LLVM_CLANG_AST_GLOBALDECL_H #define LLVM_CLANG_AST_GLOBALDECL_H +#include "clang/AST/Attr.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclObjC.h" #include "clang/AST/DeclOpenMP.h" @@ -33,17 +34,31 @@ enum class DynamicInitKind : unsigned { AtExit, }; +enum class KernelReferenceKind : unsigned { + Kernel = 0, + Stub = 1, +}; + /// GlobalDecl - represents a global declaration. This can either be a /// CXXConstructorDecl and the constructor type (Base, Complete). -/// a CXXDestructorDecl and the destructor type (Base, Complete) or +/// a CXXDestructorDecl and the destructor type (Base, Complete), +/// a FunctionDecl and the kernel reference type (Kernel, Stub), or /// a VarDecl, a FunctionDecl or a BlockDecl. +/// +/// When a new type of GlobalDecl is added, the following places should +/// be updated to convert a Decl* to a GlobalDecl: +/// PredefinedExpr::ComputeName() in lib/AST/Expr.cpp. +/// getParentOfLocalEntity() in lib/AST/ItaniumMangle.cpp +/// ASTNameGenerator::Implementation::writeFuncOrVarName in lib/AST/Mangle.cpp +/// class GlobalDecl { - llvm::PointerIntPair<const Decl *, 2> Value; + llvm::PointerIntPair<const Decl *, 3> Value; unsigned MultiVersionIndex = 0; void Init(const Decl *D) { assert(!isa<CXXConstructorDecl>(D) && "Use other ctor with ctor decls!"); assert(!isa<CXXDestructorDecl>(D) && "Use other ctor with dtor decls!"); + assert(!D->hasAttr<CUDAGlobalAttr>() && "Use other ctor with GPU kernels!"); Value.setPointer(D); } @@ -53,8 +68,17 @@ public: GlobalDecl(const VarDecl *D) { Init(D);} GlobalDecl(const FunctionDecl *D, unsigned MVIndex = 0) : MultiVersionIndex(MVIndex) { - Init(D); + if (!D->hasAttr<CUDAGlobalAttr>()) { + Init(D); + return; + } + Value.setPointerAndInt(D, unsigned(getDefaultKernelReference(D))); + } + GlobalDecl(const FunctionDecl *D, KernelReferenceKind Kind) + : Value(D, unsigned(Kind)) { + assert(D->hasAttr<CUDAGlobalAttr>() && "Decl is not a GPU kernel!"); } + GlobalDecl(const NamedDecl *D) { Init(D); } GlobalDecl(const BlockDecl *D) { Init(D); } GlobalDecl(const CapturedDecl *D) { Init(D); } GlobalDecl(const ObjCMethodDecl *D) { Init(D); } @@ -94,13 +118,22 @@ public: } unsigned getMultiVersionIndex() const { - assert(isa<FunctionDecl>(getDecl()) && + assert(isa<FunctionDecl>( + getDecl()) && + !cast<FunctionDecl>(getDecl())->hasAttr<CUDAGlobalAttr>() && !isa<CXXConstructorDecl>(getDecl()) && !isa<CXXDestructorDecl>(getDecl()) && "Decl is not a plain FunctionDecl!"); return MultiVersionIndex; } + KernelReferenceKind getKernelReferenceKind() const { + assert(isa<FunctionDecl>(getDecl()) && + cast<FunctionDecl>(getDecl())->hasAttr<CUDAGlobalAttr>() && + "Decl is not a GPU kernel!"); + return static_cast<KernelReferenceKind>(Value.getInt()); + } + friend bool operator==(const GlobalDecl &LHS, const GlobalDecl &RHS) { return LHS.Value == RHS.Value && LHS.MultiVersionIndex == RHS.MultiVersionIndex; @@ -108,12 +141,19 @@ public: void *getAsOpaquePtr() const { return Value.getOpaqueValue(); } + explicit operator bool() const { return getAsOpaquePtr(); } + static GlobalDecl getFromOpaquePtr(void *P) { GlobalDecl GD; GD.Value.setFromOpaqueValue(P); return GD; } + static KernelReferenceKind getDefaultKernelReference(const FunctionDecl *D) { + return D->getLangOpts().CUDAIsDevice ? KernelReferenceKind::Kernel + : KernelReferenceKind::Stub; + } + GlobalDecl getWithDecl(const Decl *D) { GlobalDecl Result(*this); Result.Value.setPointer(D); @@ -136,6 +176,7 @@ public: GlobalDecl getWithMultiVersionIndex(unsigned Index) { assert(isa<FunctionDecl>(getDecl()) && + !cast<FunctionDecl>(getDecl())->hasAttr<CUDAGlobalAttr>() && !isa<CXXConstructorDecl>(getDecl()) && !isa<CXXDestructorDecl>(getDecl()) && "Decl is not a plain FunctionDecl!"); @@ -143,6 +184,15 @@ public: Result.MultiVersionIndex = Index; return Result; } + + GlobalDecl getWithKernelReferenceKind(KernelReferenceKind Kind) { + assert(isa<FunctionDecl>(getDecl()) && + cast<FunctionDecl>(getDecl())->hasAttr<CUDAGlobalAttr>() && + "Decl is not a GPU kernel!"); + GlobalDecl Result(*this); + Result.Value.setInt(unsigned(Kind)); + return Result; + } }; } // namespace clang diff --git a/clang/include/clang/AST/JSONNodeDumper.h b/clang/include/clang/AST/JSONNodeDumper.h index 4023e023e9d5..4e7162992418 100644 --- a/clang/include/clang/AST/JSONNodeDumper.h +++ b/clang/include/clang/AST/JSONNodeDumper.h @@ -23,10 +23,13 @@ #include "clang/AST/CommentVisitor.h" #include "clang/AST/ExprCXX.h" #include "clang/AST/Mangle.h" +#include "clang/AST/Type.h" #include "llvm/Support/JSON.h" namespace clang { +class APValue; + class NodeStreamer { bool FirstChild = true; bool TopLevel = true; @@ -64,7 +67,7 @@ public: // We need to capture an owning-string in the lambda because the lambda // is invoked in a deferred manner. - std::string LabelStr = !Label.empty() ? Label : "inner"; + std::string LabelStr(!Label.empty() ? Label : "inner"); bool WasFirstChild = FirstChild; auto DumpWithIndent = [=](bool IsLastChild) { if (WasFirstChild) { @@ -201,6 +204,7 @@ public: void Visit(const OMPClause *C); void Visit(const BlockDecl::Capture &C); void Visit(const GenericSelectionExpr::ConstAssociation &A); + void Visit(const APValue &Value, QualType Ty); void VisitTypedefType(const TypedefType *TT); void VisitFunctionType(const FunctionType *T); diff --git a/clang/include/clang/AST/LocInfoType.h b/clang/include/clang/AST/LocInfoType.h index 1073174bcf91..7e845ad03587 100644 --- a/clang/include/clang/AST/LocInfoType.h +++ b/clang/include/clang/AST/LocInfoType.h @@ -35,10 +35,7 @@ class LocInfoType : public Type { TypeSourceInfo *DeclInfo; LocInfoType(QualType ty, TypeSourceInfo *TInfo) - : Type((TypeClass)LocInfo, ty, ty->isDependentType(), - ty->isInstantiationDependentType(), ty->isVariablyModifiedType(), - ty->containsUnexpandedParameterPack()), - DeclInfo(TInfo) { + : Type((TypeClass)LocInfo, ty, ty->getDependence()), DeclInfo(TInfo) { assert(getTypeClass() == (TypeClass)LocInfo && "LocInfo didn't fit in TC?"); } friend class Sema; diff --git a/clang/include/clang/AST/Mangle.h b/clang/include/clang/AST/Mangle.h index 5db5c5b977da..011d1faab8ea 100644 --- a/clang/include/clang/AST/Mangle.h +++ b/clang/include/clang/AST/Mangle.h @@ -14,6 +14,7 @@ #define LLVM_CLANG_AST_MANGLE_H #include "clang/AST/Decl.h" +#include "clang/AST/GlobalDecl.h" #include "clang/AST/Type.h" #include "clang/Basic/ABI.h" #include "llvm/ADT/DenseMap.h" @@ -96,8 +97,8 @@ public: virtual bool shouldMangleStringLiteral(const StringLiteral *SL) = 0; // FIXME: consider replacing raw_ostream & with something like SmallString &. - void mangleName(const NamedDecl *D, raw_ostream &); - virtual void mangleCXXName(const NamedDecl *D, raw_ostream &) = 0; + void mangleName(GlobalDecl GD, raw_ostream &); + virtual void mangleCXXName(GlobalDecl GD, raw_ostream &) = 0; virtual void mangleThunk(const CXXMethodDecl *MD, const ThunkInfo &Thunk, raw_ostream &) = 0; @@ -109,11 +110,8 @@ public: raw_ostream &) = 0; virtual void mangleCXXRTTI(QualType T, raw_ostream &) = 0; virtual void mangleCXXRTTIName(QualType T, raw_ostream &) = 0; - virtual void mangleCXXCtor(const CXXConstructorDecl *D, CXXCtorType Type, - raw_ostream &) = 0; - virtual void mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type, - raw_ostream &) = 0; virtual void mangleStringLiteral(const StringLiteral *SL, raw_ostream &) = 0; + virtual void mangleMSGuidDecl(const MSGuidDecl *GD, raw_ostream&); void mangleGlobalBlock(const BlockDecl *BD, const NamedDecl *ID, @@ -151,9 +149,14 @@ public: }; class ItaniumMangleContext : public MangleContext { + bool IsUniqueNameMangler = false; public: explicit ItaniumMangleContext(ASTContext &C, DiagnosticsEngine &D) : MangleContext(C, D, MK_Itanium) {} + explicit ItaniumMangleContext(ASTContext &C, DiagnosticsEngine &D, + bool IsUniqueNameMangler) + : MangleContext(C, D, MK_Itanium), + IsUniqueNameMangler(IsUniqueNameMangler) {} virtual void mangleCXXVTable(const CXXRecordDecl *RD, raw_ostream &) = 0; virtual void mangleCXXVTT(const CXXRecordDecl *RD, raw_ostream &) = 0; @@ -172,12 +175,17 @@ public: virtual void mangleLambdaSig(const CXXRecordDecl *Lambda, raw_ostream &) = 0; + virtual void mangleDynamicStermFinalizer(const VarDecl *D, raw_ostream &) = 0; + + bool isUniqueNameMangler() { return IsUniqueNameMangler; } + static bool classof(const MangleContext *C) { return C->getKind() == MK_Itanium; } static ItaniumMangleContext *create(ASTContext &Context, - DiagnosticsEngine &Diags); + DiagnosticsEngine &Diags, + bool IsUniqueNameMangler = false); }; class MicrosoftMangleContext : public MangleContext { diff --git a/clang/include/clang/AST/NestedNameSpecifier.h b/clang/include/clang/AST/NestedNameSpecifier.h index c6fae6f465ff..540ac3df48fe 100644 --- a/clang/include/clang/AST/NestedNameSpecifier.h +++ b/clang/include/clang/AST/NestedNameSpecifier.h @@ -14,6 +14,7 @@ #ifndef LLVM_CLANG_AST_NESTEDNAMESPECIFIER_H #define LLVM_CLANG_AST_NESTEDNAMESPECIFIER_H +#include "clang/AST/DependenceFlags.h" #include "clang/Basic/Diagnostic.h" #include "clang/Basic/SourceLocation.h" #include "llvm/ADT/FoldingSet.h" @@ -199,6 +200,8 @@ public: return nullptr; } + NestedNameSpecifierDependence getDependence() const; + /// Whether this nested name specifier refers to a dependent /// type or not. bool isDependent() const; @@ -211,6 +214,9 @@ public: /// parameter pack (for C++11 variadic templates). bool containsUnexpandedParameterPack() const; + /// Whether this nested name specifier contains an error. + bool containsErrors() const; + /// Print this nested name specifier to the given output stream. If /// `ResolveTemplateArguments` is true, we'll print actual types, e.g. /// `ns::SomeTemplate<int, MyClass>` instead of diff --git a/clang/include/clang/AST/NonTrivialTypeVisitor.h b/clang/include/clang/AST/NonTrivialTypeVisitor.h index aafcedb9d10b..c95516538ad1 100644 --- a/clang/include/clang/AST/NonTrivialTypeVisitor.h +++ b/clang/include/clang/AST/NonTrivialTypeVisitor.h @@ -1,4 +1,4 @@ -//===-- NonTrivialTypeVisitor.h - Visitor for non-trivial Types *- C++ --*-===// +//===-- NonTrivialTypeVisitor.h - Visitor for non-trivial Types -*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/clang/include/clang/AST/ODRHash.h b/clang/include/clang/AST/ODRHash.h index cd4a6f37f5db..2e8593e0b835 100644 --- a/clang/include/clang/AST/ODRHash.h +++ b/clang/include/clang/AST/ODRHash.h @@ -89,7 +89,7 @@ public: // Save booleans until the end to lower the size of data to process. void AddBoolean(bool value); - static bool isWhitelistedDecl(const Decl* D, const DeclContext *Parent); + static bool isDeclToBeProcessed(const Decl* D, const DeclContext *Parent); private: void AddDeclarationNameImpl(DeclarationName Name); diff --git a/clang/include/clang/AST/OpenMPClause.h b/clang/include/clang/AST/OpenMPClause.h index 26f8389f9cfa..6de7b6deb514 100644 --- a/clang/include/clang/AST/OpenMPClause.h +++ b/clang/include/clang/AST/OpenMPClause.h @@ -31,6 +31,7 @@ #include "llvm/ADT/iterator.h" #include "llvm/ADT/iterator_range.h" #include "llvm/Frontend/OpenMP/OMPConstants.h" +#include "llvm/Frontend/OpenMP/OMPContext.h" #include "llvm/Support/Casting.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/TrailingObjects.h" @@ -284,12 +285,13 @@ public: /// \param EndLoc Ending location of the clause. OMPAllocatorClause(Expr *A, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(OMPC_allocator, StartLoc, EndLoc), LParenLoc(LParenLoc), - Allocator(A) {} + : OMPClause(llvm::omp::OMPC_allocator, StartLoc, EndLoc), + LParenLoc(LParenLoc), Allocator(A) {} /// Build an empty clause. OMPAllocatorClause() - : OMPClause(OMPC_allocator, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_allocator, SourceLocation(), + SourceLocation()) {} /// Sets the location of '('. void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } @@ -314,7 +316,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_allocator; + return T->getClauseKind() == llvm::omp::OMPC_allocator; } }; @@ -349,17 +351,17 @@ class OMPAllocateClause final OMPAllocateClause(SourceLocation StartLoc, SourceLocation LParenLoc, Expr *Allocator, SourceLocation ColonLoc, SourceLocation EndLoc, unsigned N) - : OMPVarListClause<OMPAllocateClause>(OMPC_allocate, StartLoc, LParenLoc, - EndLoc, N), + : OMPVarListClause<OMPAllocateClause>(llvm::omp::OMPC_allocate, StartLoc, + LParenLoc, EndLoc, N), Allocator(Allocator), ColonLoc(ColonLoc) {} /// Build an empty clause. /// /// \param N Number of variables. explicit OMPAllocateClause(unsigned N) - : OMPVarListClause<OMPAllocateClause>(OMPC_allocate, SourceLocation(), + : OMPVarListClause<OMPAllocateClause>(llvm::omp::OMPC_allocate, SourceLocation(), SourceLocation(), - N) {} + SourceLocation(), N) {} /// Sets location of ':' symbol in clause. void setColonLoc(SourceLocation CL) { ColonLoc = CL; } @@ -411,7 +413,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_allocate; + return T->getClauseKind() == llvm::omp::OMPC_allocate; } }; @@ -469,15 +471,16 @@ public: OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation NameModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc) - : OMPClause(OMPC_if, StartLoc, EndLoc), OMPClauseWithPreInit(this), - LParenLoc(LParenLoc), Condition(Cond), ColonLoc(ColonLoc), - NameModifier(NameModifier), NameModifierLoc(NameModifierLoc) { + : OMPClause(llvm::omp::OMPC_if, StartLoc, EndLoc), + OMPClauseWithPreInit(this), LParenLoc(LParenLoc), Condition(Cond), + ColonLoc(ColonLoc), NameModifier(NameModifier), + NameModifierLoc(NameModifierLoc) { setPreInitStmt(HelperCond, CaptureRegion); } /// Build an empty clause. OMPIfClause() - : OMPClause(OMPC_if, SourceLocation(), SourceLocation()), + : OMPClause(llvm::omp::OMPC_if, SourceLocation(), SourceLocation()), OMPClauseWithPreInit(this) {} /// Sets the location of '('. @@ -511,7 +514,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_if; + return T->getClauseKind() == llvm::omp::OMPC_if; } }; @@ -547,14 +550,14 @@ public: OMPFinalClause(Expr *Cond, Stmt *HelperCond, OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(OMPC_final, StartLoc, EndLoc), OMPClauseWithPreInit(this), - LParenLoc(LParenLoc), Condition(Cond) { + : OMPClause(llvm::omp::OMPC_final, StartLoc, EndLoc), + OMPClauseWithPreInit(this), LParenLoc(LParenLoc), Condition(Cond) { setPreInitStmt(HelperCond, CaptureRegion); } /// Build an empty clause. OMPFinalClause() - : OMPClause(OMPC_final, SourceLocation(), SourceLocation()), + : OMPClause(llvm::omp::OMPC_final, SourceLocation(), SourceLocation()), OMPClauseWithPreInit(this) {} /// Sets the location of '('. @@ -579,7 +582,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_final; + return T->getClauseKind() == llvm::omp::OMPC_final; } }; @@ -617,7 +620,7 @@ public: OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(OMPC_num_threads, StartLoc, EndLoc), + : OMPClause(llvm::omp::OMPC_num_threads, StartLoc, EndLoc), OMPClauseWithPreInit(this), LParenLoc(LParenLoc), NumThreads(NumThreads) { setPreInitStmt(HelperNumThreads, CaptureRegion); @@ -625,7 +628,8 @@ public: /// Build an empty clause. OMPNumThreadsClause() - : OMPClause(OMPC_num_threads, SourceLocation(), SourceLocation()), + : OMPClause(llvm::omp::OMPC_num_threads, SourceLocation(), + SourceLocation()), OMPClauseWithPreInit(this) {} /// Sets the location of '('. @@ -651,7 +655,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_num_threads; + return T->getClauseKind() == llvm::omp::OMPC_num_threads; } }; @@ -687,12 +691,13 @@ public: /// \param EndLoc Ending location of the clause. OMPSafelenClause(Expr *Len, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(OMPC_safelen, StartLoc, EndLoc), LParenLoc(LParenLoc), - Safelen(Len) {} + : OMPClause(llvm::omp::OMPC_safelen, StartLoc, EndLoc), + LParenLoc(LParenLoc), Safelen(Len) {} /// Build an empty clause. explicit OMPSafelenClause() - : OMPClause(OMPC_safelen, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_safelen, SourceLocation(), SourceLocation()) { + } /// Sets the location of '('. void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } @@ -717,7 +722,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_safelen; + return T->getClauseKind() == llvm::omp::OMPC_safelen; } }; @@ -752,12 +757,13 @@ public: /// \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) {} + : OMPClause(llvm::omp::OMPC_simdlen, StartLoc, EndLoc), + LParenLoc(LParenLoc), Simdlen(Len) {} /// Build an empty clause. explicit OMPSimdlenClause() - : OMPClause(OMPC_simdlen, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_simdlen, SourceLocation(), SourceLocation()) { + } /// Sets the location of '('. void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } @@ -782,7 +788,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_simdlen; + return T->getClauseKind() == llvm::omp::OMPC_simdlen; } }; @@ -818,12 +824,13 @@ public: /// \param EndLoc Ending location of the clause. OMPCollapseClause(Expr *Num, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(OMPC_collapse, StartLoc, EndLoc), LParenLoc(LParenLoc), - NumForLoops(Num) {} + : OMPClause(llvm::omp::OMPC_collapse, StartLoc, EndLoc), + LParenLoc(LParenLoc), NumForLoops(Num) {} /// Build an empty clause. explicit OMPCollapseClause() - : OMPClause(OMPC_collapse, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_collapse, SourceLocation(), + SourceLocation()) {} /// Sets the location of '('. void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } @@ -848,7 +855,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_collapse; + return T->getClauseKind() == llvm::omp::OMPC_collapse; } }; @@ -866,7 +873,7 @@ class OMPDefaultClause : public OMPClause { SourceLocation LParenLoc; /// A kind of the 'default' clause. - OpenMPDefaultClauseKind Kind = OMPC_DEFAULT_unknown; + llvm::omp::DefaultKind Kind = llvm::omp::OMP_DEFAULT_unknown; /// Start location of the kind in source code. SourceLocation KindKwLoc; @@ -874,7 +881,7 @@ class OMPDefaultClause : public OMPClause { /// Set kind of the clauses. /// /// \param K Argument of clause. - void setDefaultKind(OpenMPDefaultClauseKind K) { Kind = K; } + void setDefaultKind(llvm::omp::DefaultKind K) { Kind = K; } /// Set argument location. /// @@ -889,15 +896,16 @@ public: /// \param StartLoc Starting location of the clause. /// \param LParenLoc Location of '('. /// \param EndLoc Ending location of the clause. - OMPDefaultClause(OpenMPDefaultClauseKind A, SourceLocation ALoc, + OMPDefaultClause(llvm::omp::DefaultKind A, SourceLocation ALoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(OMPC_default, StartLoc, EndLoc), LParenLoc(LParenLoc), - Kind(A), KindKwLoc(ALoc) {} + : OMPClause(llvm::omp::OMPC_default, StartLoc, EndLoc), + LParenLoc(LParenLoc), Kind(A), KindKwLoc(ALoc) {} /// Build an empty clause. OMPDefaultClause() - : OMPClause(OMPC_default, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_default, SourceLocation(), SourceLocation()) { + } /// Sets the location of '('. void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } @@ -906,7 +914,7 @@ public: SourceLocation getLParenLoc() const { return LParenLoc; } /// Returns kind of the clause. - OpenMPDefaultClauseKind getDefaultKind() const { return Kind; } + llvm::omp::DefaultKind getDefaultKind() const { return Kind; } /// Returns location of clause kind. SourceLocation getDefaultKindKwLoc() const { return KindKwLoc; } @@ -927,7 +935,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_default; + return T->getClauseKind() == llvm::omp::OMPC_default; } }; @@ -973,12 +981,13 @@ public: OMPProcBindClause(llvm::omp::ProcBindKind A, SourceLocation ALoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(OMPC_proc_bind, StartLoc, EndLoc), LParenLoc(LParenLoc), - Kind(A), KindKwLoc(ALoc) {} + : OMPClause(llvm::omp::OMPC_proc_bind, StartLoc, EndLoc), + LParenLoc(LParenLoc), Kind(A), KindKwLoc(ALoc) {} /// Build an empty clause. OMPProcBindClause() - : OMPClause(OMPC_proc_bind, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_proc_bind, SourceLocation(), + SourceLocation()) {} /// Sets the location of '('. void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } @@ -1008,7 +1017,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_proc_bind; + return T->getClauseKind() == llvm::omp::OMPC_proc_bind; } }; @@ -1028,11 +1037,12 @@ public: /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPUnifiedAddressClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(OMPC_unified_address, StartLoc, EndLoc) {} + : OMPClause(llvm::omp::OMPC_unified_address, StartLoc, EndLoc) {} /// Build an empty clause. OMPUnifiedAddressClause() - : OMPClause(OMPC_unified_address, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_unified_address, SourceLocation(), + SourceLocation()) {} child_range children() { return child_range(child_iterator(), child_iterator()); @@ -1050,7 +1060,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_unified_address; + return T->getClauseKind() == llvm::omp::OMPC_unified_address; } }; @@ -1070,11 +1080,12 @@ public: /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPUnifiedSharedMemoryClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(OMPC_unified_shared_memory, StartLoc, EndLoc) {} + : OMPClause(llvm::omp::OMPC_unified_shared_memory, StartLoc, EndLoc) {} /// Build an empty clause. OMPUnifiedSharedMemoryClause() - : OMPClause(OMPC_unified_shared_memory, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_unified_shared_memory, SourceLocation(), + SourceLocation()) {} child_range children() { return child_range(child_iterator(), child_iterator()); @@ -1092,7 +1103,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_unified_shared_memory; + return T->getClauseKind() == llvm::omp::OMPC_unified_shared_memory; } }; @@ -1112,11 +1123,12 @@ public: /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPReverseOffloadClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(OMPC_reverse_offload, StartLoc, EndLoc) {} + : OMPClause(llvm::omp::OMPC_reverse_offload, StartLoc, EndLoc) {} /// Build an empty clause. OMPReverseOffloadClause() - : OMPClause(OMPC_reverse_offload, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_reverse_offload, SourceLocation(), + SourceLocation()) {} child_range children() { return child_range(child_iterator(), child_iterator()); @@ -1134,7 +1146,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_reverse_offload; + return T->getClauseKind() == llvm::omp::OMPC_reverse_offload; } }; @@ -1154,12 +1166,12 @@ public: /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPDynamicAllocatorsClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(OMPC_dynamic_allocators, StartLoc, EndLoc) {} + : OMPClause(llvm::omp::OMPC_dynamic_allocators, StartLoc, EndLoc) {} /// Build an empty clause. OMPDynamicAllocatorsClause() - : OMPClause(OMPC_dynamic_allocators, SourceLocation(), SourceLocation()) { - } + : OMPClause(llvm::omp::OMPC_dynamic_allocators, SourceLocation(), + SourceLocation()) {} child_range children() { return child_range(child_iterator(), child_iterator()); @@ -1177,7 +1189,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_dynamic_allocators; + return T->getClauseKind() == llvm::omp::OMPC_dynamic_allocators; } }; @@ -1229,12 +1241,12 @@ public: SourceLocation ALoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(OMPC_atomic_default_mem_order, StartLoc, EndLoc), + : OMPClause(llvm::omp::OMPC_atomic_default_mem_order, StartLoc, EndLoc), LParenLoc(LParenLoc), Kind(A), KindKwLoc(ALoc) {} /// Build an empty clause. OMPAtomicDefaultMemOrderClause() - : OMPClause(OMPC_atomic_default_mem_order, SourceLocation(), + : OMPClause(llvm::omp::OMPC_atomic_default_mem_order, SourceLocation(), SourceLocation()) {} /// Sets the location of '('. @@ -1267,7 +1279,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_atomic_default_mem_order; + return T->getClauseKind() == llvm::omp::OMPC_atomic_default_mem_order; } }; @@ -1386,9 +1398,9 @@ public: Expr *ChunkSize, Stmt *HelperChunkSize, OpenMPScheduleClauseModifier M1, SourceLocation M1Loc, OpenMPScheduleClauseModifier M2, SourceLocation M2Loc) - : OMPClause(OMPC_schedule, StartLoc, EndLoc), OMPClauseWithPreInit(this), - LParenLoc(LParenLoc), Kind(Kind), KindLoc(KLoc), CommaLoc(CommaLoc), - ChunkSize(ChunkSize) { + : OMPClause(llvm::omp::OMPC_schedule, StartLoc, EndLoc), + OMPClauseWithPreInit(this), LParenLoc(LParenLoc), Kind(Kind), + KindLoc(KLoc), CommaLoc(CommaLoc), ChunkSize(ChunkSize) { setPreInitStmt(HelperChunkSize); Modifiers[FIRST] = M1; Modifiers[SECOND] = M2; @@ -1398,7 +1410,7 @@ public: /// Build an empty clause. explicit OMPScheduleClause() - : OMPClause(OMPC_schedule, SourceLocation(), SourceLocation()), + : OMPClause(llvm::omp::OMPC_schedule, SourceLocation(), SourceLocation()), OMPClauseWithPreInit(this) { Modifiers[FIRST] = OMPC_SCHEDULE_MODIFIER_unknown; Modifiers[SECOND] = OMPC_SCHEDULE_MODIFIER_unknown; @@ -1460,7 +1472,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_schedule; + return T->getClauseKind() == llvm::omp::OMPC_schedule; } }; @@ -1495,12 +1507,12 @@ class OMPOrderedClause final /// \param EndLoc Ending location of the clause. OMPOrderedClause(Expr *Num, unsigned NumLoops, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(OMPC_ordered, StartLoc, EndLoc), LParenLoc(LParenLoc), - NumForLoops(Num), NumberOfLoops(NumLoops) {} + : OMPClause(llvm::omp::OMPC_ordered, StartLoc, EndLoc), + LParenLoc(LParenLoc), NumForLoops(Num), NumberOfLoops(NumLoops) {} /// Build an empty clause. explicit OMPOrderedClause(unsigned NumLoops) - : OMPClause(OMPC_ordered, SourceLocation(), SourceLocation()), + : OMPClause(llvm::omp::OMPC_ordered, SourceLocation(), SourceLocation()), NumberOfLoops(NumLoops) {} /// Set the number of associated for-loops. @@ -1556,7 +1568,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_ordered; + return T->getClauseKind() == llvm::omp::OMPC_ordered; } }; @@ -1573,11 +1585,11 @@ public: /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPNowaitClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(OMPC_nowait, StartLoc, EndLoc) {} + : OMPClause(llvm::omp::OMPC_nowait, StartLoc, EndLoc) {} /// Build an empty clause. OMPNowaitClause() - : OMPClause(OMPC_nowait, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_nowait, SourceLocation(), SourceLocation()) {} child_range children() { return child_range(child_iterator(), child_iterator()); @@ -1595,7 +1607,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_nowait; + return T->getClauseKind() == llvm::omp::OMPC_nowait; } }; @@ -1612,11 +1624,11 @@ public: /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPUntiedClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(OMPC_untied, StartLoc, EndLoc) {} + : OMPClause(llvm::omp::OMPC_untied, StartLoc, EndLoc) {} /// Build an empty clause. OMPUntiedClause() - : OMPClause(OMPC_untied, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_untied, SourceLocation(), SourceLocation()) {} child_range children() { return child_range(child_iterator(), child_iterator()); @@ -1634,7 +1646,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_untied; + return T->getClauseKind() == llvm::omp::OMPC_untied; } }; @@ -1652,11 +1664,12 @@ public: /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPMergeableClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(OMPC_mergeable, StartLoc, EndLoc) {} + : OMPClause(llvm::omp::OMPC_mergeable, StartLoc, EndLoc) {} /// Build an empty clause. OMPMergeableClause() - : OMPClause(OMPC_mergeable, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_mergeable, SourceLocation(), + SourceLocation()) {} child_range children() { return child_range(child_iterator(), child_iterator()); @@ -1674,7 +1687,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_mergeable; + return T->getClauseKind() == llvm::omp::OMPC_mergeable; } }; @@ -1691,10 +1704,11 @@ public: /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPReadClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(OMPC_read, StartLoc, EndLoc) {} + : OMPClause(llvm::omp::OMPC_read, StartLoc, EndLoc) {} /// Build an empty clause. - OMPReadClause() : OMPClause(OMPC_read, SourceLocation(), SourceLocation()) {} + OMPReadClause() + : OMPClause(llvm::omp::OMPC_read, SourceLocation(), SourceLocation()) {} child_range children() { return child_range(child_iterator(), child_iterator()); @@ -1712,7 +1726,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_read; + return T->getClauseKind() == llvm::omp::OMPC_read; } }; @@ -1729,11 +1743,11 @@ public: /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPWriteClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(OMPC_write, StartLoc, EndLoc) {} + : OMPClause(llvm::omp::OMPC_write, StartLoc, EndLoc) {} /// Build an empty clause. OMPWriteClause() - : OMPClause(OMPC_write, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_write, SourceLocation(), SourceLocation()) {} child_range children() { return child_range(child_iterator(), child_iterator()); @@ -1751,7 +1765,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_write; + return T->getClauseKind() == llvm::omp::OMPC_write; } }; @@ -1762,18 +1776,95 @@ public: /// #pragma omp atomic update /// \endcode /// In this example directive '#pragma omp atomic' has 'update' clause. -class OMPUpdateClause : public OMPClause { -public: +/// Also, this class represents 'update' clause in '#pragma omp depobj' +/// directive. +/// +/// \code +/// #pragma omp depobj(a) update(in) +/// \endcode +/// In this example directive '#pragma omp depobj' has 'update' clause with 'in' +/// dependence kind. +class OMPUpdateClause final + : public OMPClause, + private llvm::TrailingObjects<OMPUpdateClause, SourceLocation, + OpenMPDependClauseKind> { + friend class OMPClauseReader; + friend TrailingObjects; + + /// true if extended version of the clause for 'depobj' directive. + bool IsExtended = false; + + /// Define the sizes of each trailing object array except the last one. This + /// is required for TrailingObjects to work properly. + size_t numTrailingObjects(OverloadToken<SourceLocation>) const { + // 2 locations: for '(' and argument location. + return IsExtended ? 2 : 0; + } + + /// Sets the the location of '(' in clause for 'depobj' directive. + void setLParenLoc(SourceLocation Loc) { + assert(IsExtended && "Expected extended clause."); + *getTrailingObjects<SourceLocation>() = Loc; + } + + /// Sets the the location of '(' in clause for 'depobj' directive. + void setArgumentLoc(SourceLocation Loc) { + assert(IsExtended && "Expected extended clause."); + *std::next(getTrailingObjects<SourceLocation>(), 1) = Loc; + } + + /// Sets the dependence kind for the clause for 'depobj' directive. + void setDependencyKind(OpenMPDependClauseKind DK) { + assert(IsExtended && "Expected extended clause."); + *getTrailingObjects<OpenMPDependClauseKind>() = DK; + } + /// Build 'update' clause. /// /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. - OMPUpdateClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(OMPC_update, StartLoc, EndLoc) {} + OMPUpdateClause(SourceLocation StartLoc, SourceLocation EndLoc, + bool IsExtended) + : OMPClause(llvm::omp::OMPC_update, StartLoc, EndLoc), + IsExtended(IsExtended) {} /// Build an empty clause. - OMPUpdateClause() - : OMPClause(OMPC_update, SourceLocation(), SourceLocation()) {} + OMPUpdateClause(bool IsExtended) + : OMPClause(llvm::omp::OMPC_update, SourceLocation(), SourceLocation()), + IsExtended(IsExtended) {} + +public: + /// Creates clause for 'atomic' directive. + /// + /// \param C AST context. + /// \param StartLoc Starting location of the clause. + /// \param EndLoc Ending location of the clause. + static OMPUpdateClause *Create(const ASTContext &C, SourceLocation StartLoc, + SourceLocation EndLoc); + + /// Creates clause for 'depobj' directive. + /// + /// \param C AST context. + /// \param StartLoc Starting location of the clause. + /// \param LParenLoc Location of '('. + /// \param ArgumentLoc Location of the argument. + /// \param DK Dependence kind. + /// \param EndLoc Ending location of the clause. + static OMPUpdateClause *Create(const ASTContext &C, SourceLocation StartLoc, + SourceLocation LParenLoc, + SourceLocation ArgumentLoc, + OpenMPDependClauseKind DK, + SourceLocation EndLoc); + + /// Creates an empty clause with the place for \a N variables. + /// + /// \param C AST context. + /// \param IsExtended true if extended clause for 'depobj' directive must be + /// created. + static OMPUpdateClause *CreateEmpty(const ASTContext &C, bool IsExtended); + + /// Checks if the clause is the extended clauses for 'depobj' directive. + bool isExtended() const { return IsExtended; } child_range children() { return child_range(child_iterator(), child_iterator()); @@ -1790,8 +1881,26 @@ public: return const_child_range(const_child_iterator(), const_child_iterator()); } + /// Gets the the location of '(' in clause for 'depobj' directive. + SourceLocation getLParenLoc() const { + assert(IsExtended && "Expected extended clause."); + return *getTrailingObjects<SourceLocation>(); + } + + /// Gets the the location of argument in clause for 'depobj' directive. + SourceLocation getArgumentLoc() const { + assert(IsExtended && "Expected extended clause."); + return *std::next(getTrailingObjects<SourceLocation>(), 1); + } + + /// Gets the dependence kind in clause for 'depobj' directive. + OpenMPDependClauseKind getDependencyKind() const { + assert(IsExtended && "Expected extended clause."); + return *getTrailingObjects<OpenMPDependClauseKind>(); + } + static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_update; + return T->getClauseKind() == llvm::omp::OMPC_update; } }; @@ -1809,11 +1918,12 @@ public: /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPCaptureClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(OMPC_capture, StartLoc, EndLoc) {} + : OMPClause(llvm::omp::OMPC_capture, StartLoc, EndLoc) {} /// Build an empty clause. OMPCaptureClause() - : OMPClause(OMPC_capture, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_capture, SourceLocation(), SourceLocation()) { + } child_range children() { return child_range(child_iterator(), child_iterator()); @@ -1831,7 +1941,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_capture; + return T->getClauseKind() == llvm::omp::OMPC_capture; } }; @@ -1849,11 +1959,12 @@ public: /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPSeqCstClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(OMPC_seq_cst, StartLoc, EndLoc) {} + : OMPClause(llvm::omp::OMPC_seq_cst, StartLoc, EndLoc) {} /// Build an empty clause. OMPSeqCstClause() - : OMPClause(OMPC_seq_cst, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_seq_cst, SourceLocation(), SourceLocation()) { + } child_range children() { return child_range(child_iterator(), child_iterator()); @@ -1871,7 +1982,171 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_seq_cst; + return T->getClauseKind() == llvm::omp::OMPC_seq_cst; + } +}; + +/// This represents 'acq_rel' clause in the '#pragma omp atomic|flush' +/// directives. +/// +/// \code +/// #pragma omp flush acq_rel +/// \endcode +/// In this example directive '#pragma omp flush' has 'acq_rel' clause. +class OMPAcqRelClause final : public OMPClause { +public: + /// Build 'ack_rel' clause. + /// + /// \param StartLoc Starting location of the clause. + /// \param EndLoc Ending location of the clause. + OMPAcqRelClause(SourceLocation StartLoc, SourceLocation EndLoc) + : OMPClause(llvm::omp::OMPC_acq_rel, StartLoc, EndLoc) {} + + /// Build an empty clause. + OMPAcqRelClause() + : OMPClause(llvm::omp::OMPC_acq_rel, SourceLocation(), SourceLocation()) { + } + + child_range children() { + return child_range(child_iterator(), child_iterator()); + } + + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + + static bool classof(const OMPClause *T) { + return T->getClauseKind() == llvm::omp::OMPC_acq_rel; + } +}; + +/// This represents 'acquire' clause in the '#pragma omp atomic|flush' +/// directives. +/// +/// \code +/// #pragma omp flush acquire +/// \endcode +/// In this example directive '#pragma omp flush' has 'acquire' clause. +class OMPAcquireClause final : public OMPClause { +public: + /// Build 'acquire' clause. + /// + /// \param StartLoc Starting location of the clause. + /// \param EndLoc Ending location of the clause. + OMPAcquireClause(SourceLocation StartLoc, SourceLocation EndLoc) + : OMPClause(llvm::omp::OMPC_acquire, StartLoc, EndLoc) {} + + /// Build an empty clause. + OMPAcquireClause() + : OMPClause(llvm::omp::OMPC_acquire, SourceLocation(), SourceLocation()) { + } + + child_range children() { + return child_range(child_iterator(), child_iterator()); + } + + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + + static bool classof(const OMPClause *T) { + return T->getClauseKind() == llvm::omp::OMPC_acquire; + } +}; + +/// This represents 'release' clause in the '#pragma omp atomic|flush' +/// directives. +/// +/// \code +/// #pragma omp flush release +/// \endcode +/// In this example directive '#pragma omp flush' has 'release' clause. +class OMPReleaseClause final : public OMPClause { +public: + /// Build 'release' clause. + /// + /// \param StartLoc Starting location of the clause. + /// \param EndLoc Ending location of the clause. + OMPReleaseClause(SourceLocation StartLoc, SourceLocation EndLoc) + : OMPClause(llvm::omp::OMPC_release, StartLoc, EndLoc) {} + + /// Build an empty clause. + OMPReleaseClause() + : OMPClause(llvm::omp::OMPC_release, SourceLocation(), SourceLocation()) { + } + + child_range children() { + return child_range(child_iterator(), child_iterator()); + } + + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + + static bool classof(const OMPClause *T) { + return T->getClauseKind() == llvm::omp::OMPC_release; + } +}; + +/// This represents 'relaxed' clause in the '#pragma omp atomic' +/// directives. +/// +/// \code +/// #pragma omp atomic relaxed +/// \endcode +/// In this example directive '#pragma omp atomic' has 'relaxed' clause. +class OMPRelaxedClause final : public OMPClause { +public: + /// Build 'relaxed' clause. + /// + /// \param StartLoc Starting location of the clause. + /// \param EndLoc Ending location of the clause. + OMPRelaxedClause(SourceLocation StartLoc, SourceLocation EndLoc) + : OMPClause(llvm::omp::OMPC_relaxed, StartLoc, EndLoc) {} + + /// Build an empty clause. + OMPRelaxedClause() + : OMPClause(llvm::omp::OMPC_relaxed, SourceLocation(), SourceLocation()) { + } + + child_range children() { + return child_range(child_iterator(), child_iterator()); + } + + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + + static bool classof(const OMPClause *T) { + return T->getClauseKind() == llvm::omp::OMPC_relaxed; } }; @@ -1897,16 +2172,16 @@ class OMPPrivateClause final /// \param N Number of the variables in the clause. OMPPrivateClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, unsigned N) - : OMPVarListClause<OMPPrivateClause>(OMPC_private, StartLoc, LParenLoc, - EndLoc, N) {} + : OMPVarListClause<OMPPrivateClause>(llvm::omp::OMPC_private, StartLoc, + LParenLoc, EndLoc, N) {} /// Build an empty clause. /// /// \param N Number of variables. explicit OMPPrivateClause(unsigned N) - : OMPVarListClause<OMPPrivateClause>(OMPC_private, SourceLocation(), + : OMPVarListClause<OMPPrivateClause>(llvm::omp::OMPC_private, SourceLocation(), SourceLocation(), - N) {} + SourceLocation(), N) {} /// Sets the list of references to private copies with initializers for /// new private variables. @@ -1976,7 +2251,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_private; + return T->getClauseKind() == llvm::omp::OMPC_private; } }; @@ -2004,8 +2279,8 @@ class OMPFirstprivateClause final /// \param N Number of the variables in the clause. OMPFirstprivateClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, unsigned N) - : OMPVarListClause<OMPFirstprivateClause>(OMPC_firstprivate, StartLoc, - LParenLoc, EndLoc, N), + : OMPVarListClause<OMPFirstprivateClause>(llvm::omp::OMPC_firstprivate, + StartLoc, LParenLoc, EndLoc, N), OMPClauseWithPreInit(this) {} /// Build an empty clause. @@ -2013,7 +2288,7 @@ class OMPFirstprivateClause final /// \param N Number of variables. explicit OMPFirstprivateClause(unsigned N) : OMPVarListClause<OMPFirstprivateClause>( - OMPC_firstprivate, SourceLocation(), SourceLocation(), + llvm::omp::OMPC_firstprivate, SourceLocation(), SourceLocation(), SourceLocation(), N), OMPClauseWithPreInit(this) {} @@ -2117,7 +2392,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_firstprivate; + return T->getClauseKind() == llvm::omp::OMPC_firstprivate; } }; @@ -2170,8 +2445,8 @@ class OMPLastprivateClause final SourceLocation EndLoc, OpenMPLastprivateModifier LPKind, SourceLocation LPKindLoc, SourceLocation ColonLoc, unsigned N) - : OMPVarListClause<OMPLastprivateClause>(OMPC_lastprivate, StartLoc, - LParenLoc, EndLoc, N), + : OMPVarListClause<OMPLastprivateClause>(llvm::omp::OMPC_lastprivate, + StartLoc, LParenLoc, EndLoc, N), OMPClauseWithPostUpdate(this), LPKind(LPKind), LPKindLoc(LPKindLoc), ColonLoc(ColonLoc) {} @@ -2180,7 +2455,7 @@ class OMPLastprivateClause final /// \param N Number of variables. explicit OMPLastprivateClause(unsigned N) : OMPVarListClause<OMPLastprivateClause>( - OMPC_lastprivate, SourceLocation(), SourceLocation(), + llvm::omp::OMPC_lastprivate, SourceLocation(), SourceLocation(), SourceLocation(), N), OMPClauseWithPostUpdate(this) {} @@ -2356,7 +2631,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_lastprivate; + return T->getClauseKind() == llvm::omp::OMPC_lastprivate; } }; @@ -2381,16 +2656,16 @@ class OMPSharedClause final /// \param N Number of the variables in the clause. OMPSharedClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, unsigned N) - : OMPVarListClause<OMPSharedClause>(OMPC_shared, StartLoc, LParenLoc, - EndLoc, N) {} + : OMPVarListClause<OMPSharedClause>(llvm::omp::OMPC_shared, StartLoc, + LParenLoc, EndLoc, N) {} /// Build an empty clause. /// /// \param N Number of variables. explicit OMPSharedClause(unsigned N) - : OMPVarListClause<OMPSharedClause>(OMPC_shared, SourceLocation(), + : OMPVarListClause<OMPSharedClause>(llvm::omp::OMPC_shared, SourceLocation(), SourceLocation(), - N) {} + SourceLocation(), N) {} public: /// Creates clause with a list of variables \a VL. @@ -2428,7 +2703,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_shared; + return T->getClauseKind() == llvm::omp::OMPC_shared; } }; @@ -2448,6 +2723,12 @@ class OMPReductionClause final friend OMPVarListClause; friend TrailingObjects; + /// Reduction modifier. + OpenMPReductionClauseModifier Modifier = OMPC_REDUCTION_unknown; + + /// Reduction modifier location. + SourceLocation ModifierLoc; + /// Location of ':'. SourceLocation ColonLoc; @@ -2461,29 +2742,39 @@ class OMPReductionClause final /// /// \param StartLoc Starting location of the clause. /// \param LParenLoc Location of '('. - /// \param EndLoc Ending location of the clause. + /// \param ModifierLoc Modifier location. /// \param ColonLoc Location of ':'. + /// \param EndLoc Ending location of the clause. /// \param N Number of the variables in the clause. /// \param QualifierLoc The nested-name qualifier with location information /// \param NameInfo The full name info for reduction identifier. OMPReductionClause(SourceLocation StartLoc, SourceLocation LParenLoc, - SourceLocation ColonLoc, SourceLocation EndLoc, unsigned N, + SourceLocation ModifierLoc, SourceLocation ColonLoc, + SourceLocation EndLoc, + OpenMPReductionClauseModifier Modifier, unsigned N, NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo) - : OMPVarListClause<OMPReductionClause>(OMPC_reduction, StartLoc, - LParenLoc, EndLoc, N), - OMPClauseWithPostUpdate(this), ColonLoc(ColonLoc), + : OMPVarListClause<OMPReductionClause>(llvm::omp::OMPC_reduction, + StartLoc, LParenLoc, EndLoc, N), + OMPClauseWithPostUpdate(this), Modifier(Modifier), + ModifierLoc(ModifierLoc), ColonLoc(ColonLoc), QualifierLoc(QualifierLoc), NameInfo(NameInfo) {} /// Build an empty clause. /// /// \param N Number of variables. explicit OMPReductionClause(unsigned N) - : OMPVarListClause<OMPReductionClause>(OMPC_reduction, SourceLocation(), + : OMPVarListClause<OMPReductionClause>(llvm::omp::OMPC_reduction, SourceLocation(), SourceLocation(), - N), + SourceLocation(), N), OMPClauseWithPostUpdate(this) {} + /// Sets reduction modifier. + void setModifier(OpenMPReductionClauseModifier M) { Modifier = M; } + + /// Sets location of the modifier. + void setModifierLoc(SourceLocation Loc) { ModifierLoc = Loc; } + /// Sets location of ':' symbol in clause. void setColonLoc(SourceLocation CL) { ColonLoc = CL; } @@ -2548,11 +2839,47 @@ class OMPReductionClause final return llvm::makeArrayRef(getRHSExprs().end(), varlist_size()); } + /// Set list of helper copy operations for inscan reductions. + /// The form is: Temps[i] = LHS[i]; + void setInscanCopyOps(ArrayRef<Expr *> Ops); + + /// Get the list of helper inscan copy operations. + MutableArrayRef<Expr *> getInscanCopyOps() { + return MutableArrayRef<Expr *>(getReductionOps().end(), varlist_size()); + } + ArrayRef<const Expr *> getInscanCopyOps() const { + return llvm::makeArrayRef(getReductionOps().end(), varlist_size()); + } + + /// Set list of helper temp vars for inscan copy array operations. + void setInscanCopyArrayTemps(ArrayRef<Expr *> CopyArrayTemps); + + /// Get the list of helper inscan copy temps. + MutableArrayRef<Expr *> getInscanCopyArrayTemps() { + return MutableArrayRef<Expr *>(getInscanCopyOps().end(), varlist_size()); + } + ArrayRef<const Expr *> getInscanCopyArrayTemps() const { + return llvm::makeArrayRef(getInscanCopyOps().end(), varlist_size()); + } + + /// Set list of helper temp elements vars for inscan copy array operations. + void setInscanCopyArrayElems(ArrayRef<Expr *> CopyArrayElems); + + /// Get the list of helper inscan copy temps. + MutableArrayRef<Expr *> getInscanCopyArrayElems() { + return MutableArrayRef<Expr *>(getInscanCopyArrayTemps().end(), + varlist_size()); + } + ArrayRef<const Expr *> getInscanCopyArrayElems() const { + return llvm::makeArrayRef(getInscanCopyArrayTemps().end(), varlist_size()); + } + public: /// Creates clause with a list of variables \a VL. /// /// \param StartLoc Starting location of the clause. /// \param LParenLoc Location of '('. + /// \param ModifierLoc Modifier location. /// \param ColonLoc Location of ':'. /// \param EndLoc Ending location of the clause. /// \param VL The variables in the clause. @@ -2577,23 +2904,41 @@ public: /// \endcode /// Required for proper codegen of final reduction operation performed by the /// reduction clause. + /// \param CopyOps List of copy operations for inscan reductions: + /// \code + /// TempExprs = LHSExprs; + /// \endcode + /// \param CopyArrayTemps Temp arrays for prefix sums. + /// \param CopyArrayElems Temp arrays for prefix sums. /// \param PreInit Statement that must be executed before entering the OpenMP /// region with this clause. /// \param PostUpdate Expression that must be executed after exit from the /// OpenMP region with this clause. static OMPReductionClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, - SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef<Expr *> VL, - NestedNameSpecifierLoc QualifierLoc, + SourceLocation ModifierLoc, SourceLocation ColonLoc, + SourceLocation EndLoc, OpenMPReductionClauseModifier Modifier, + ArrayRef<Expr *> VL, NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, ArrayRef<Expr *> Privates, ArrayRef<Expr *> LHSExprs, ArrayRef<Expr *> RHSExprs, - ArrayRef<Expr *> ReductionOps, Stmt *PreInit, Expr *PostUpdate); + ArrayRef<Expr *> ReductionOps, ArrayRef<Expr *> CopyOps, + ArrayRef<Expr *> CopyArrayTemps, ArrayRef<Expr *> CopyArrayElems, + Stmt *PreInit, Expr *PostUpdate); /// Creates an empty clause with the place for \a N variables. /// /// \param C AST context. /// \param N The number of variables. - static OMPReductionClause *CreateEmpty(const ASTContext &C, unsigned N); + /// \param Modifier Reduction modifier. + static OMPReductionClause * + CreateEmpty(const ASTContext &C, unsigned N, + OpenMPReductionClauseModifier Modifier); + + /// Returns modifier. + OpenMPReductionClauseModifier getModifier() const { return Modifier; } + + /// Returns modifier location. + SourceLocation getModifierLoc() const { return ModifierLoc; } /// Gets location of ':' symbol in clause. SourceLocation getColonLoc() const { return ColonLoc; } @@ -2644,6 +2989,36 @@ public: getReductionOps().end()); } + helper_expr_const_range copy_ops() const { + return helper_expr_const_range(getInscanCopyOps().begin(), + getInscanCopyOps().end()); + } + + helper_expr_range copy_ops() { + return helper_expr_range(getInscanCopyOps().begin(), + getInscanCopyOps().end()); + } + + helper_expr_const_range copy_array_temps() const { + return helper_expr_const_range(getInscanCopyArrayTemps().begin(), + getInscanCopyArrayTemps().end()); + } + + helper_expr_range copy_array_temps() { + return helper_expr_range(getInscanCopyArrayTemps().begin(), + getInscanCopyArrayTemps().end()); + } + + helper_expr_const_range copy_array_elems() const { + return helper_expr_const_range(getInscanCopyArrayElems().begin(), + getInscanCopyArrayElems().end()); + } + + helper_expr_range copy_array_elems() { + return helper_expr_range(getInscanCopyArrayElems().begin(), + getInscanCopyArrayElems().end()); + } + child_range children() { return child_range(reinterpret_cast<Stmt **>(varlist_begin()), reinterpret_cast<Stmt **>(varlist_end())); @@ -2664,7 +3039,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_reduction; + return T->getClauseKind() == llvm::omp::OMPC_reduction; } }; @@ -2706,8 +3081,8 @@ class OMPTaskReductionClause final SourceLocation ColonLoc, SourceLocation EndLoc, unsigned N, NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo) - : OMPVarListClause<OMPTaskReductionClause>(OMPC_task_reduction, StartLoc, - LParenLoc, EndLoc, N), + : OMPVarListClause<OMPTaskReductionClause>( + llvm::omp::OMPC_task_reduction, StartLoc, LParenLoc, EndLoc, N), OMPClauseWithPostUpdate(this), ColonLoc(ColonLoc), QualifierLoc(QualifierLoc), NameInfo(NameInfo) {} @@ -2716,7 +3091,7 @@ class OMPTaskReductionClause final /// \param N Number of variables. explicit OMPTaskReductionClause(unsigned N) : OMPVarListClause<OMPTaskReductionClause>( - OMPC_task_reduction, SourceLocation(), SourceLocation(), + llvm::omp::OMPC_task_reduction, SourceLocation(), SourceLocation(), SourceLocation(), N), OMPClauseWithPostUpdate(this) {} @@ -2896,7 +3271,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_task_reduction; + return T->getClauseKind() == llvm::omp::OMPC_task_reduction; } }; @@ -2937,8 +3312,8 @@ class OMPInReductionClause final SourceLocation ColonLoc, SourceLocation EndLoc, unsigned N, NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo) - : OMPVarListClause<OMPInReductionClause>(OMPC_in_reduction, StartLoc, - LParenLoc, EndLoc, N), + : OMPVarListClause<OMPInReductionClause>(llvm::omp::OMPC_in_reduction, + StartLoc, LParenLoc, EndLoc, N), OMPClauseWithPostUpdate(this), ColonLoc(ColonLoc), QualifierLoc(QualifierLoc), NameInfo(NameInfo) {} @@ -2947,7 +3322,7 @@ class OMPInReductionClause final /// \param N Number of variables. explicit OMPInReductionClause(unsigned N) : OMPVarListClause<OMPInReductionClause>( - OMPC_in_reduction, SourceLocation(), SourceLocation(), + llvm::omp::OMPC_in_reduction, SourceLocation(), SourceLocation(), SourceLocation(), N), OMPClauseWithPostUpdate(this) {} @@ -3151,7 +3526,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_in_reduction; + return T->getClauseKind() == llvm::omp::OMPC_in_reduction; } }; @@ -3197,8 +3572,8 @@ class OMPLinearClause final OpenMPLinearClauseKind Modifier, SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc, unsigned NumVars) - : OMPVarListClause<OMPLinearClause>(OMPC_linear, StartLoc, LParenLoc, - EndLoc, NumVars), + : OMPVarListClause<OMPLinearClause>(llvm::omp::OMPC_linear, StartLoc, + LParenLoc, EndLoc, NumVars), OMPClauseWithPostUpdate(this), Modifier(Modifier), ModifierLoc(ModifierLoc), ColonLoc(ColonLoc) {} @@ -3206,9 +3581,9 @@ class OMPLinearClause final /// /// \param NumVars Number of variables. explicit OMPLinearClause(unsigned NumVars) - : OMPVarListClause<OMPLinearClause>(OMPC_linear, SourceLocation(), + : OMPVarListClause<OMPLinearClause>(llvm::omp::OMPC_linear, SourceLocation(), SourceLocation(), - NumVars), + SourceLocation(), NumVars), OMPClauseWithPostUpdate(this) {} /// Gets the list of initial values for linear variables. @@ -3428,7 +3803,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_linear; + return T->getClauseKind() == llvm::omp::OMPC_linear; } }; @@ -3463,17 +3838,17 @@ class OMPAlignedClause final OMPAlignedClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, unsigned NumVars) - : OMPVarListClause<OMPAlignedClause>(OMPC_aligned, StartLoc, LParenLoc, - EndLoc, NumVars), + : OMPVarListClause<OMPAlignedClause>(llvm::omp::OMPC_aligned, StartLoc, + LParenLoc, EndLoc, NumVars), ColonLoc(ColonLoc) {} /// Build an empty clause. /// /// \param NumVars Number of variables. explicit OMPAlignedClause(unsigned NumVars) - : OMPVarListClause<OMPAlignedClause>(OMPC_aligned, SourceLocation(), + : OMPVarListClause<OMPAlignedClause>(llvm::omp::OMPC_aligned, SourceLocation(), SourceLocation(), - NumVars) {} + SourceLocation(), NumVars) {} public: /// Creates clause with a list of variables \a VL and alignment \a A. @@ -3527,7 +3902,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_aligned; + return T->getClauseKind() == llvm::omp::OMPC_aligned; } }; @@ -3566,16 +3941,16 @@ class OMPCopyinClause final /// \param N Number of the variables in the clause. OMPCopyinClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, unsigned N) - : OMPVarListClause<OMPCopyinClause>(OMPC_copyin, StartLoc, LParenLoc, - EndLoc, N) {} + : OMPVarListClause<OMPCopyinClause>(llvm::omp::OMPC_copyin, StartLoc, + LParenLoc, EndLoc, N) {} /// Build an empty clause. /// /// \param N Number of variables. explicit OMPCopyinClause(unsigned N) - : OMPVarListClause<OMPCopyinClause>(OMPC_copyin, SourceLocation(), + : OMPVarListClause<OMPCopyinClause>(llvm::omp::OMPC_copyin, SourceLocation(), SourceLocation(), - N) {} + SourceLocation(), N) {} /// Set list of helper expressions, required for proper codegen of the /// clause. These expressions represent source expression in the final @@ -3703,7 +4078,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_copyin; + return T->getClauseKind() == llvm::omp::OMPC_copyin; } }; @@ -3730,15 +4105,16 @@ class OMPCopyprivateClause final /// \param N Number of the variables in the clause. OMPCopyprivateClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, unsigned N) - : OMPVarListClause<OMPCopyprivateClause>(OMPC_copyprivate, StartLoc, - LParenLoc, EndLoc, N) {} + : OMPVarListClause<OMPCopyprivateClause>(llvm::omp::OMPC_copyprivate, + StartLoc, LParenLoc, EndLoc, N) { + } /// Build an empty clause. /// /// \param N Number of variables. explicit OMPCopyprivateClause(unsigned N) : OMPVarListClause<OMPCopyprivateClause>( - OMPC_copyprivate, SourceLocation(), SourceLocation(), + llvm::omp::OMPC_copyprivate, SourceLocation(), SourceLocation(), SourceLocation(), N) {} /// Set list of helper expressions, required for proper codegen of the @@ -3866,7 +4242,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_copyprivate; + return T->getClauseKind() == llvm::omp::OMPC_copyprivate; } }; @@ -3896,16 +4272,16 @@ class OMPFlushClause final /// \param N Number of the variables in the clause. OMPFlushClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, unsigned N) - : OMPVarListClause<OMPFlushClause>(OMPC_flush, StartLoc, LParenLoc, - EndLoc, N) {} + : OMPVarListClause<OMPFlushClause>(llvm::omp::OMPC_flush, StartLoc, + LParenLoc, EndLoc, N) {} /// Build an empty clause. /// /// \param N Number of variables. explicit OMPFlushClause(unsigned N) - : OMPVarListClause<OMPFlushClause>(OMPC_flush, SourceLocation(), + : OMPVarListClause<OMPFlushClause>(llvm::omp::OMPC_flush, SourceLocation(), SourceLocation(), - N) {} + SourceLocation(), N) {} public: /// Creates clause with a list of variables \a VL. @@ -3943,7 +4319,94 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_flush; + return T->getClauseKind() == llvm::omp::OMPC_flush; + } +}; + +/// This represents implicit clause 'depobj' for the '#pragma omp depobj' +/// directive. +/// This clause does not exist by itself, it can be only as a part of 'omp +/// depobj' directive. This clause is introduced to keep the original structure +/// of \a OMPExecutableDirective class and its derivatives and to use the +/// existing infrastructure of clauses with the list of variables. +/// +/// \code +/// #pragma omp depobj(a) destroy +/// \endcode +/// In this example directive '#pragma omp depobj' has implicit clause 'depobj' +/// with the depobj 'a'. +class OMPDepobjClause final : public OMPClause { + friend class OMPClauseReader; + + /// Location of '('. + SourceLocation LParenLoc; + + /// Chunk size. + Expr *Depobj = nullptr; + + /// Build clause with number of variables \a N. + /// + /// \param StartLoc Starting location of the clause. + /// \param LParenLoc Location of '('. + /// \param EndLoc Ending location of the clause. + OMPDepobjClause(SourceLocation StartLoc, SourceLocation LParenLoc, + SourceLocation EndLoc) + : OMPClause(llvm::omp::OMPC_depobj, StartLoc, EndLoc), + LParenLoc(LParenLoc) {} + + /// Build an empty clause. + /// + explicit OMPDepobjClause() + : OMPClause(llvm::omp::OMPC_depobj, SourceLocation(), SourceLocation()) {} + + void setDepobj(Expr *E) { Depobj = E; } + + /// Sets the location of '('. + void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } + +public: + /// Creates clause. + /// + /// \param C AST context. + /// \param StartLoc Starting location of the clause. + /// \param LParenLoc Location of '('. + /// \param EndLoc Ending location of the clause. + /// \param Depobj depobj expression associated with the 'depobj' directive. + static OMPDepobjClause *Create(const ASTContext &C, SourceLocation StartLoc, + SourceLocation LParenLoc, + SourceLocation EndLoc, Expr *Depobj); + + /// Creates an empty clause. + /// + /// \param C AST context. + static OMPDepobjClause *CreateEmpty(const ASTContext &C); + + /// Returns depobj expression associated with the clause. + Expr *getDepobj() { return Depobj; } + const Expr *getDepobj() const { return Depobj; } + + /// Returns the location of '('. + SourceLocation getLParenLoc() const { return LParenLoc; } + + child_range children() { + return child_range(reinterpret_cast<Stmt **>(&Depobj), + reinterpret_cast<Stmt **>(&Depobj) + 1); + } + + const_child_range children() const { + auto Children = const_cast<OMPDepobjClause *>(this)->children(); + return const_child_range(Children.begin(), Children.end()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + + static bool classof(const OMPClause *T) { + return T->getClauseKind() == llvm::omp::OMPC_depobj; } }; @@ -3984,8 +4447,9 @@ class OMPDependClause final /// clause. OMPDependClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, unsigned N, unsigned NumLoops) - : OMPVarListClause<OMPDependClause>(OMPC_depend, StartLoc, LParenLoc, - EndLoc, N), NumLoops(NumLoops) {} + : OMPVarListClause<OMPDependClause>(llvm::omp::OMPC_depend, StartLoc, + LParenLoc, EndLoc, N), + NumLoops(NumLoops) {} /// Build an empty clause. /// @@ -3993,9 +4457,9 @@ class OMPDependClause final /// \param NumLoops Number of loops that is associated with this depend /// clause. explicit OMPDependClause(unsigned N, unsigned NumLoops) - : OMPVarListClause<OMPDependClause>(OMPC_depend, SourceLocation(), + : OMPVarListClause<OMPDependClause>(llvm::omp::OMPC_depend, SourceLocation(), SourceLocation(), - N), + SourceLocation(), N), NumLoops(NumLoops) {} /// Set dependency kind. @@ -4007,6 +4471,9 @@ class OMPDependClause final /// Set colon location. void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; } + /// Sets optional dependency modifier. + void setModifier(Expr *DepModifier); + public: /// Creates clause with a list of variables \a VL. /// @@ -4022,7 +4489,7 @@ public: /// clause. static OMPDependClause *Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, - SourceLocation EndLoc, + SourceLocation EndLoc, Expr *DepModifier, OpenMPDependClauseKind DepKind, SourceLocation DepLoc, SourceLocation ColonLoc, ArrayRef<Expr *> VL, unsigned NumLoops); @@ -4039,6 +4506,12 @@ public: /// Get dependency type. OpenMPDependClauseKind getDependencyKind() const { return DepKind; } + /// Return optional depend modifier. + Expr *getModifier(); + const Expr *getModifier() const { + return const_cast<OMPDependClause *>(this)->getModifier(); + } + /// Get dependency type location. SourceLocation getDependencyLoc() const { return DepLoc; } @@ -4074,7 +4547,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_depend; + return T->getClauseKind() == llvm::omp::OMPC_depend; } }; @@ -4092,6 +4565,12 @@ class OMPDeviceClause : public OMPClause, public OMPClauseWithPreInit { /// Location of '('. SourceLocation LParenLoc; + /// Device clause modifier. + OpenMPDeviceClauseModifier Modifier = OMPC_DEVICE_unknown; + + /// Location of the modifier. + SourceLocation ModifierLoc; + /// Device number. Stmt *Device = nullptr; @@ -4100,26 +4579,36 @@ class OMPDeviceClause : public OMPClause, public OMPClauseWithPreInit { /// \param E Device number. void setDevice(Expr *E) { Device = E; } + /// Sets modifier. + void setModifier(OpenMPDeviceClauseModifier M) { Modifier = M; } + + /// Setst modifier location. + void setModifierLoc(SourceLocation Loc) { ModifierLoc = Loc; } + public: /// Build 'device' clause. /// + /// \param Modifier Clause modifier. /// \param E Expression associated with this clause. /// \param CaptureRegion Innermost OpenMP region where expressions in this /// clause must be captured. /// \param StartLoc Starting location of the clause. + /// \param ModifierLoc Modifier location. /// \param LParenLoc Location of '('. /// \param EndLoc Ending location of the clause. - OMPDeviceClause(Expr *E, Stmt *HelperE, OpenMPDirectiveKind CaptureRegion, - SourceLocation StartLoc, SourceLocation LParenLoc, + OMPDeviceClause(OpenMPDeviceClauseModifier Modifier, Expr *E, Stmt *HelperE, + OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc, + SourceLocation LParenLoc, SourceLocation ModifierLoc, SourceLocation EndLoc) - : OMPClause(OMPC_device, StartLoc, EndLoc), OMPClauseWithPreInit(this), - LParenLoc(LParenLoc), Device(E) { + : OMPClause(llvm::omp::OMPC_device, StartLoc, EndLoc), + OMPClauseWithPreInit(this), LParenLoc(LParenLoc), Modifier(Modifier), + ModifierLoc(ModifierLoc), Device(E) { setPreInitStmt(HelperE, CaptureRegion); } /// Build an empty clause. OMPDeviceClause() - : OMPClause(OMPC_device, SourceLocation(), SourceLocation()), + : OMPClause(llvm::omp::OMPC_device, SourceLocation(), SourceLocation()), OMPClauseWithPreInit(this) {} /// Sets the location of '('. @@ -4134,6 +4623,12 @@ public: /// Return device number. Expr *getDevice() const { return cast<Expr>(Device); } + /// Gets modifier. + OpenMPDeviceClauseModifier getModifier() const { return Modifier; } + + /// Gets modifier location. + SourceLocation getModifierLoc() const { return ModifierLoc; } + child_range children() { return child_range(&Device, &Device + 1); } const_child_range children() const { @@ -4148,7 +4643,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_device; + return T->getClauseKind() == llvm::omp::OMPC_device; } }; @@ -4165,11 +4660,12 @@ public: /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPThreadsClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(OMPC_threads, StartLoc, EndLoc) {} + : OMPClause(llvm::omp::OMPC_threads, StartLoc, EndLoc) {} /// Build an empty clause. OMPThreadsClause() - : OMPClause(OMPC_threads, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_threads, SourceLocation(), SourceLocation()) { + } child_range children() { return child_range(child_iterator(), child_iterator()); @@ -4187,7 +4683,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_threads; + return T->getClauseKind() == llvm::omp::OMPC_threads; } }; @@ -4204,10 +4700,11 @@ public: /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPSIMDClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(OMPC_simd, StartLoc, EndLoc) {} + : OMPClause(llvm::omp::OMPC_simd, StartLoc, EndLoc) {} /// Build an empty clause. - OMPSIMDClause() : OMPClause(OMPC_simd, SourceLocation(), SourceLocation()) {} + OMPSIMDClause() + : OMPClause(llvm::omp::OMPC_simd, SourceLocation(), SourceLocation()) {} child_range children() { return child_range(child_iterator(), child_iterator()); @@ -4225,7 +4722,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_simd; + return T->getClauseKind() == llvm::omp::OMPC_simd; } }; @@ -4853,19 +5350,14 @@ class OMPMapClause final : public OMPMappableExprListClause<OMPMapClause>, return getUniqueDeclarationsNum() + getTotalComponentListNum(); } -public: - /// Number of allowed map-type-modifiers. - static constexpr unsigned NumberOfModifiers = - OMPC_MAP_MODIFIER_last - OMPC_MAP_MODIFIER_unknown - 1; - private: /// Map-type-modifiers for the 'map' clause. - OpenMPMapModifierKind MapTypeModifiers[NumberOfModifiers] = { + OpenMPMapModifierKind MapTypeModifiers[NumberOfOMPMapClauseModifiers] = { OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown}; /// Location of map-type-modifiers for the 'map' clause. - SourceLocation MapTypeModifiersLoc[NumberOfModifiers]; + SourceLocation MapTypeModifiersLoc[NumberOfOMPMapClauseModifiers]; /// Map type for the 'map' clause. OpenMPMapClauseKind MapType = OMPC_MAP_unknown; @@ -4906,8 +5398,8 @@ private: OpenMPMapClauseKind MapType, bool MapTypeIsImplicit, SourceLocation MapLoc, const OMPVarListLocTy &Locs, const OMPMappableExprListSizeTy &Sizes) - : OMPMappableExprListClause(OMPC_map, Locs, Sizes, &MapperQualifierLoc, - &MapperIdInfo), + : OMPMappableExprListClause(llvm::omp::OMPC_map, Locs, Sizes, + &MapperQualifierLoc, &MapperIdInfo), MapType(MapType), MapTypeIsImplicit(MapTypeIsImplicit), MapLoc(MapLoc) { assert(llvm::array_lengthof(MapTypeModifiers) == MapModifiers.size() && "Unexpected number of map type modifiers."); @@ -4927,14 +5419,15 @@ private: /// 3) NumComponentLists: number of component lists in this clause; and 4) /// NumComponents: total number of expression components in the clause. explicit OMPMapClause(const OMPMappableExprListSizeTy &Sizes) - : OMPMappableExprListClause(OMPC_map, OMPVarListLocTy(), Sizes) {} + : OMPMappableExprListClause(llvm::omp::OMPC_map, OMPVarListLocTy(), + Sizes) {} /// Set map-type-modifier for the clause. /// /// \param I index for map-type-modifier. /// \param T map-type-modifier for the clause. void setMapTypeModifier(unsigned I, OpenMPMapModifierKind T) { - assert(I < NumberOfModifiers && + assert(I < NumberOfOMPMapClauseModifiers && "Unexpected index to store map type modifier, exceeds array size."); MapTypeModifiers[I] = T; } @@ -4944,7 +5437,7 @@ private: /// \param I index for map-type-modifier location. /// \param TLoc map-type-modifier location. void setMapTypeModifierLoc(unsigned I, SourceLocation TLoc) { - assert(I < NumberOfModifiers && + assert(I < NumberOfOMPMapClauseModifiers && "Index to store map type modifier location exceeds array size."); MapTypeModifiersLoc[I] = TLoc; } @@ -5019,7 +5512,7 @@ public: /// /// \param Cnt index for map-type-modifier. OpenMPMapModifierKind getMapTypeModifier(unsigned Cnt) const LLVM_READONLY { - assert(Cnt < NumberOfModifiers && + assert(Cnt < NumberOfOMPMapClauseModifiers && "Requested modifier exceeds the total number of modifiers."); return MapTypeModifiers[Cnt]; } @@ -5029,7 +5522,7 @@ public: /// /// \param Cnt index for map-type-modifier location. SourceLocation getMapTypeModifierLoc(unsigned Cnt) const LLVM_READONLY { - assert(Cnt < NumberOfModifiers && + assert(Cnt < NumberOfOMPMapClauseModifiers && "Requested modifier location exceeds total number of modifiers."); return MapTypeModifiersLoc[Cnt]; } @@ -5074,7 +5567,7 @@ public: static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_map; + return T->getClauseKind() == llvm::omp::OMPC_map; } }; @@ -5113,14 +5606,15 @@ public: OMPNumTeamsClause(Expr *E, Stmt *HelperE, OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(OMPC_num_teams, StartLoc, EndLoc), OMPClauseWithPreInit(this), - LParenLoc(LParenLoc), NumTeams(E) { + : OMPClause(llvm::omp::OMPC_num_teams, StartLoc, EndLoc), + OMPClauseWithPreInit(this), LParenLoc(LParenLoc), NumTeams(E) { setPreInitStmt(HelperE, CaptureRegion); } /// Build an empty clause. OMPNumTeamsClause() - : OMPClause(OMPC_num_teams, SourceLocation(), SourceLocation()), + : OMPClause(llvm::omp::OMPC_num_teams, SourceLocation(), + SourceLocation()), OMPClauseWithPreInit(this) {} /// Sets the location of '('. @@ -5149,7 +5643,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_num_teams; + return T->getClauseKind() == llvm::omp::OMPC_num_teams; } }; @@ -5189,14 +5683,15 @@ public: OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(OMPC_thread_limit, StartLoc, EndLoc), + : OMPClause(llvm::omp::OMPC_thread_limit, StartLoc, EndLoc), OMPClauseWithPreInit(this), LParenLoc(LParenLoc), ThreadLimit(E) { setPreInitStmt(HelperE, CaptureRegion); } /// Build an empty clause. OMPThreadLimitClause() - : OMPClause(OMPC_thread_limit, SourceLocation(), SourceLocation()), + : OMPClause(llvm::omp::OMPC_thread_limit, SourceLocation(), + SourceLocation()), OMPClauseWithPreInit(this) {} /// Sets the location of '('. @@ -5225,7 +5720,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_thread_limit; + return T->getClauseKind() == llvm::omp::OMPC_thread_limit; } }; @@ -5264,14 +5759,14 @@ public: OMPPriorityClause(Expr *Priority, Stmt *HelperPriority, OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(OMPC_priority, StartLoc, EndLoc), OMPClauseWithPreInit(this), - LParenLoc(LParenLoc), Priority(Priority) { + : OMPClause(llvm::omp::OMPC_priority, StartLoc, EndLoc), + OMPClauseWithPreInit(this), LParenLoc(LParenLoc), Priority(Priority) { setPreInitStmt(HelperPriority, CaptureRegion); } /// Build an empty clause. OMPPriorityClause() - : OMPClause(OMPC_priority, SourceLocation(), SourceLocation()), + : OMPClause(llvm::omp::OMPC_priority, SourceLocation(), SourceLocation()), OMPClauseWithPreInit(this) {} /// Sets the location of '('. @@ -5299,7 +5794,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_priority; + return T->getClauseKind() == llvm::omp::OMPC_priority; } }; @@ -5335,14 +5830,15 @@ public: OMPGrainsizeClause(Expr *Size, Stmt *HelperSize, OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(OMPC_grainsize, StartLoc, EndLoc), OMPClauseWithPreInit(this), - LParenLoc(LParenLoc), Grainsize(Size) { + : OMPClause(llvm::omp::OMPC_grainsize, StartLoc, EndLoc), + OMPClauseWithPreInit(this), LParenLoc(LParenLoc), Grainsize(Size) { setPreInitStmt(HelperSize, CaptureRegion); } /// Build an empty clause. explicit OMPGrainsizeClause() - : OMPClause(OMPC_grainsize, SourceLocation(), SourceLocation()), + : OMPClause(llvm::omp::OMPC_grainsize, SourceLocation(), + SourceLocation()), OMPClauseWithPreInit(this) {} /// Sets the location of '('. @@ -5367,7 +5863,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_grainsize; + return T->getClauseKind() == llvm::omp::OMPC_grainsize; } }; @@ -5384,11 +5880,12 @@ public: /// \param StartLoc Starting location of the clause. /// \param EndLoc Ending location of the clause. OMPNogroupClause(SourceLocation StartLoc, SourceLocation EndLoc) - : OMPClause(OMPC_nogroup, StartLoc, EndLoc) {} + : OMPClause(llvm::omp::OMPC_nogroup, StartLoc, EndLoc) {} /// Build an empty clause. OMPNogroupClause() - : OMPClause(OMPC_nogroup, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_nogroup, SourceLocation(), SourceLocation()) { + } child_range children() { return child_range(child_iterator(), child_iterator()); @@ -5406,7 +5903,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_nogroup; + return T->getClauseKind() == llvm::omp::OMPC_nogroup; } }; @@ -5442,14 +5939,15 @@ public: OMPNumTasksClause(Expr *Size, Stmt *HelperSize, OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(OMPC_num_tasks, StartLoc, EndLoc), OMPClauseWithPreInit(this), - LParenLoc(LParenLoc), NumTasks(Size) { + : OMPClause(llvm::omp::OMPC_num_tasks, StartLoc, EndLoc), + OMPClauseWithPreInit(this), LParenLoc(LParenLoc), NumTasks(Size) { setPreInitStmt(HelperSize, CaptureRegion); } /// Build an empty clause. explicit OMPNumTasksClause() - : OMPClause(OMPC_num_tasks, SourceLocation(), SourceLocation()), + : OMPClause(llvm::omp::OMPC_num_tasks, SourceLocation(), + SourceLocation()), OMPClauseWithPreInit(this) {} /// Sets the location of '('. @@ -5474,7 +5972,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_num_tasks; + return T->getClauseKind() == llvm::omp::OMPC_num_tasks; } }; @@ -5506,11 +6004,12 @@ public: /// \param EndLoc Ending location of the clause. OMPHintClause(Expr *Hint, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) - : OMPClause(OMPC_hint, StartLoc, EndLoc), LParenLoc(LParenLoc), + : OMPClause(llvm::omp::OMPC_hint, StartLoc, EndLoc), LParenLoc(LParenLoc), Hint(Hint) {} /// Build an empty clause. - OMPHintClause() : OMPClause(OMPC_hint, SourceLocation(), SourceLocation()) {} + OMPHintClause() + : OMPClause(llvm::omp::OMPC_hint, SourceLocation(), SourceLocation()) {} /// Sets the location of '('. void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } @@ -5535,7 +6034,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_hint; + return T->getClauseKind() == llvm::omp::OMPC_hint; } }; @@ -5607,7 +6106,7 @@ public: SourceLocation EndLoc, OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, Stmt *HelperChunkSize) - : OMPClause(OMPC_dist_schedule, StartLoc, EndLoc), + : OMPClause(llvm::omp::OMPC_dist_schedule, StartLoc, EndLoc), OMPClauseWithPreInit(this), LParenLoc(LParenLoc), Kind(Kind), KindLoc(KLoc), CommaLoc(CommaLoc), ChunkSize(ChunkSize) { setPreInitStmt(HelperChunkSize); @@ -5615,7 +6114,8 @@ public: /// Build an empty clause. explicit OMPDistScheduleClause() - : OMPClause(OMPC_dist_schedule, SourceLocation(), SourceLocation()), + : OMPClause(llvm::omp::OMPC_dist_schedule, SourceLocation(), + SourceLocation()), OMPClauseWithPreInit(this) {} /// Get kind of the clause. @@ -5654,7 +6154,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_dist_schedule; + return T->getClauseKind() == llvm::omp::OMPC_dist_schedule; } }; @@ -5724,12 +6224,14 @@ public: SourceLocation MLoc, SourceLocation KLoc, SourceLocation EndLoc, OpenMPDefaultmapClauseKind Kind, OpenMPDefaultmapClauseModifier M) - : OMPClause(OMPC_defaultmap, StartLoc, EndLoc), LParenLoc(LParenLoc), - Modifier(M), ModifierLoc(MLoc), Kind(Kind), KindLoc(KLoc) {} + : OMPClause(llvm::omp::OMPC_defaultmap, StartLoc, EndLoc), + LParenLoc(LParenLoc), Modifier(M), ModifierLoc(MLoc), Kind(Kind), + KindLoc(KLoc) {} /// Build an empty clause. explicit OMPDefaultmapClause() - : OMPClause(OMPC_defaultmap, SourceLocation(), SourceLocation()) {} + : OMPClause(llvm::omp::OMPC_defaultmap, SourceLocation(), + SourceLocation()) {} /// Get kind of the clause. OpenMPDefaultmapClauseKind getDefaultmapKind() const { return Kind; } @@ -5766,7 +6268,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_defaultmap; + return T->getClauseKind() == llvm::omp::OMPC_defaultmap; } }; @@ -5804,8 +6306,8 @@ class OMPToClause final : public OMPMappableExprListClause<OMPToClause>, DeclarationNameInfo MapperIdInfo, const OMPVarListLocTy &Locs, const OMPMappableExprListSizeTy &Sizes) - : OMPMappableExprListClause(OMPC_to, Locs, Sizes, &MapperQualifierLoc, - &MapperIdInfo) {} + : OMPMappableExprListClause(llvm::omp::OMPC_to, Locs, Sizes, + &MapperQualifierLoc, &MapperIdInfo) {} /// Build an empty clause. /// @@ -5815,7 +6317,8 @@ class OMPToClause final : public OMPMappableExprListClause<OMPToClause>, /// 3) NumComponentLists: number of component lists in this clause; and 4) /// NumComponents: total number of expression components in the clause. explicit OMPToClause(const OMPMappableExprListSizeTy &Sizes) - : OMPMappableExprListClause(OMPC_to, OMPVarListLocTy(), Sizes) {} + : OMPMappableExprListClause(llvm::omp::OMPC_to, OMPVarListLocTy(), + Sizes) {} /// Define the sizes of each trailing object array except the last one. This /// is required for TrailingObjects to work properly. @@ -5883,7 +6386,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_to; + return T->getClauseKind() == llvm::omp::OMPC_to; } }; @@ -5922,8 +6425,8 @@ class OMPFromClause final DeclarationNameInfo MapperIdInfo, const OMPVarListLocTy &Locs, const OMPMappableExprListSizeTy &Sizes) - : OMPMappableExprListClause(OMPC_from, Locs, Sizes, &MapperQualifierLoc, - &MapperIdInfo) {} + : OMPMappableExprListClause(llvm::omp::OMPC_from, Locs, Sizes, + &MapperQualifierLoc, &MapperIdInfo) {} /// Build an empty clause. /// @@ -5933,7 +6436,8 @@ class OMPFromClause final /// 3) NumComponentLists: number of component lists in this clause; and 4) /// NumComponents: total number of expression components in the clause. explicit OMPFromClause(const OMPMappableExprListSizeTy &Sizes) - : OMPMappableExprListClause(OMPC_from, OMPVarListLocTy(), Sizes) {} + : OMPMappableExprListClause(llvm::omp::OMPC_from, OMPVarListLocTy(), + Sizes) {} /// Define the sizes of each trailing object array except the last one. This /// is required for TrailingObjects to work properly. @@ -6001,7 +6505,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_from; + return T->getClauseKind() == llvm::omp::OMPC_from; } }; @@ -6035,7 +6539,8 @@ class OMPUseDevicePtrClause final /// NumComponents: total number of expression components in the clause. explicit OMPUseDevicePtrClause(const OMPVarListLocTy &Locs, const OMPMappableExprListSizeTy &Sizes) - : OMPMappableExprListClause(OMPC_use_device_ptr, Locs, Sizes) {} + : OMPMappableExprListClause(llvm::omp::OMPC_use_device_ptr, Locs, Sizes) { + } /// Build an empty clause. /// @@ -6045,8 +6550,8 @@ class OMPUseDevicePtrClause final /// 3) NumComponentLists: number of component lists in this clause; and 4) /// NumComponents: total number of expression components in the clause. explicit OMPUseDevicePtrClause(const OMPMappableExprListSizeTy &Sizes) - : OMPMappableExprListClause(OMPC_use_device_ptr, OMPVarListLocTy(), - Sizes) {} + : OMPMappableExprListClause(llvm::omp::OMPC_use_device_ptr, + OMPVarListLocTy(), Sizes) {} /// Define the sizes of each trailing object array except the last one. This /// is required for TrailingObjects to work properly. @@ -6164,7 +6669,111 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_use_device_ptr; + return T->getClauseKind() == llvm::omp::OMPC_use_device_ptr; + } +}; + +/// This represents clause 'use_device_addr' in the '#pragma omp ...' +/// directives. +/// +/// \code +/// #pragma omp target data use_device_addr(a,b) +/// \endcode +/// In this example directive '#pragma omp target data' has clause +/// 'use_device_addr' with the variables 'a' and 'b'. +class OMPUseDeviceAddrClause final + : public OMPMappableExprListClause<OMPUseDeviceAddrClause>, + private llvm::TrailingObjects< + OMPUseDeviceAddrClause, Expr *, ValueDecl *, unsigned, + OMPClauseMappableExprCommon::MappableComponent> { + friend class OMPClauseReader; + friend OMPMappableExprListClause; + friend OMPVarListClause; + friend TrailingObjects; + + /// Build clause with number of variables \a NumVars. + /// + /// \param Locs Locations needed to build a mappable clause. It includes 1) + /// StartLoc: starting location of the clause (the clause keyword); 2) + /// LParenLoc: location of '('; 3) EndLoc: ending location of the clause. + /// \param Sizes All required sizes to build a mappable clause. It includes 1) + /// NumVars: number of expressions listed in this clause; 2) + /// NumUniqueDeclarations: number of unique base declarations in this clause; + /// 3) NumComponentLists: number of component lists in this clause; and 4) + /// NumComponents: total number of expression components in the clause. + explicit OMPUseDeviceAddrClause(const OMPVarListLocTy &Locs, + const OMPMappableExprListSizeTy &Sizes) + : OMPMappableExprListClause(llvm::omp::OMPC_use_device_addr, Locs, + Sizes) {} + + /// Build an empty clause. + /// + /// \param Sizes All required sizes to build a mappable clause. It includes 1) + /// NumVars: number of expressions listed in this clause; 2) + /// NumUniqueDeclarations: number of unique base declarations in this clause; + /// 3) NumComponentLists: number of component lists in this clause; and 4) + /// NumComponents: total number of expression components in the clause. + explicit OMPUseDeviceAddrClause(const OMPMappableExprListSizeTy &Sizes) + : OMPMappableExprListClause(llvm::omp::OMPC_use_device_addr, + OMPVarListLocTy(), Sizes) {} + + /// Define the sizes of each trailing object array except the last one. This + /// is required for TrailingObjects to work properly. + size_t numTrailingObjects(OverloadToken<Expr *>) const { + return varlist_size(); + } + size_t numTrailingObjects(OverloadToken<ValueDecl *>) const { + return getUniqueDeclarationsNum(); + } + size_t numTrailingObjects(OverloadToken<unsigned>) const { + return getUniqueDeclarationsNum() + getTotalComponentListNum(); + } + +public: + /// Creates clause with a list of variables \a Vars. + /// + /// \param C AST context. + /// \param Locs Locations needed to build a mappable clause. It includes 1) + /// StartLoc: starting location of the clause (the clause keyword); 2) + /// LParenLoc: location of '('; 3) EndLoc: ending location of the clause. + /// \param Vars The original expression used in the clause. + /// \param Declarations Declarations used in the clause. + /// \param ComponentLists Component lists used in the clause. + static OMPUseDeviceAddrClause * + Create(const ASTContext &C, const OMPVarListLocTy &Locs, + ArrayRef<Expr *> Vars, ArrayRef<ValueDecl *> Declarations, + MappableExprComponentListsRef ComponentLists); + + /// Creates an empty clause with the place for \a NumVars variables. + /// + /// \param C AST context. + /// \param Sizes All required sizes to build a mappable clause. It includes 1) + /// NumVars: number of expressions listed in this clause; 2) + /// NumUniqueDeclarations: number of unique base declarations in this clause; + /// 3) NumComponentLists: number of component lists in this clause; and 4) + /// NumComponents: total number of expression components in the clause. + static OMPUseDeviceAddrClause * + CreateEmpty(const ASTContext &C, const OMPMappableExprListSizeTy &Sizes); + + child_range children() { + return child_range(reinterpret_cast<Stmt **>(varlist_begin()), + reinterpret_cast<Stmt **>(varlist_end())); + } + + const_child_range children() const { + auto Children = const_cast<OMPUseDeviceAddrClause *>(this)->children(); + return const_child_range(Children.begin(), Children.end()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + + static bool classof(const OMPClause *T) { + return T->getClauseKind() == llvm::omp::OMPC_use_device_addr; } }; @@ -6198,7 +6807,7 @@ class OMPIsDevicePtrClause final /// NumComponents: total number of expression components in the clause. explicit OMPIsDevicePtrClause(const OMPVarListLocTy &Locs, const OMPMappableExprListSizeTy &Sizes) - : OMPMappableExprListClause(OMPC_is_device_ptr, Locs, Sizes) {} + : OMPMappableExprListClause(llvm::omp::OMPC_is_device_ptr, Locs, Sizes) {} /// Build an empty clause. /// @@ -6208,8 +6817,8 @@ class OMPIsDevicePtrClause final /// 3) NumComponentLists: number of component lists in this clause; and 4) /// NumComponents: total number of expression components in the clause. explicit OMPIsDevicePtrClause(const OMPMappableExprListSizeTy &Sizes) - : OMPMappableExprListClause(OMPC_is_device_ptr, OMPVarListLocTy(), - Sizes) {} + : OMPMappableExprListClause(llvm::omp::OMPC_is_device_ptr, + OMPVarListLocTy(), Sizes) {} /// Define the sizes of each trailing object array except the last one. This /// is required for TrailingObjects to work properly. @@ -6267,7 +6876,7 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_is_device_ptr; + return T->getClauseKind() == llvm::omp::OMPC_is_device_ptr; } }; @@ -6293,15 +6902,16 @@ class OMPNontemporalClause final /// \param N Number of the variables in the clause. OMPNontemporalClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, unsigned N) - : OMPVarListClause<OMPNontemporalClause>(OMPC_nontemporal, StartLoc, - LParenLoc, EndLoc, N) {} + : OMPVarListClause<OMPNontemporalClause>(llvm::omp::OMPC_nontemporal, + StartLoc, LParenLoc, EndLoc, N) { + } /// Build an empty clause. /// /// \param N Number of variables. explicit OMPNontemporalClause(unsigned N) : OMPVarListClause<OMPNontemporalClause>( - OMPC_nontemporal, SourceLocation(), SourceLocation(), + llvm::omp::OMPC_nontemporal, SourceLocation(), SourceLocation(), SourceLocation(), N) {} /// Get the list of privatied copies if the member expression was captured by @@ -6363,7 +6973,563 @@ public: } static bool classof(const OMPClause *T) { - return T->getClauseKind() == OMPC_nontemporal; + return T->getClauseKind() == llvm::omp::OMPC_nontemporal; + } +}; + +/// This represents 'order' clause in the '#pragma omp ...' directive. +/// +/// \code +/// #pragma omp simd order(concurrent) +/// \endcode +/// In this example directive '#pragma omp parallel' has simple 'order' +/// clause with kind 'concurrent'. +class OMPOrderClause final : public OMPClause { + friend class OMPClauseReader; + + /// Location of '('. + SourceLocation LParenLoc; + + /// A kind of the 'default' clause. + OpenMPOrderClauseKind Kind = OMPC_ORDER_unknown; + + /// Start location of the kind in source code. + SourceLocation KindKwLoc; + + /// Set kind of the clause. + /// + /// \param K Argument of clause. + void setKind(OpenMPOrderClauseKind K) { Kind = K; } + + /// Set argument location. + /// + /// \param KLoc Argument location. + void setKindKwLoc(SourceLocation KLoc) { KindKwLoc = KLoc; } + +public: + /// Build 'order' clause with argument \p A ('concurrent'). + /// + /// \param A Argument of the clause ('concurrent'). + /// \param ALoc Starting location of the argument. + /// \param StartLoc Starting location of the clause. + /// \param LParenLoc Location of '('. + /// \param EndLoc Ending location of the clause. + OMPOrderClause(OpenMPOrderClauseKind A, SourceLocation ALoc, + SourceLocation StartLoc, SourceLocation LParenLoc, + SourceLocation EndLoc) + : OMPClause(llvm::omp::OMPC_order, StartLoc, EndLoc), + LParenLoc(LParenLoc), Kind(A), KindKwLoc(ALoc) {} + + /// Build an empty clause. + OMPOrderClause() + : OMPClause(llvm::omp::OMPC_order, SourceLocation(), SourceLocation()) {} + + /// Sets the location of '('. + void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } + + /// Returns the location of '('. + SourceLocation getLParenLoc() const { return LParenLoc; } + + /// Returns kind of the clause. + OpenMPOrderClauseKind getKind() const { return Kind; } + + /// Returns location of clause kind. + SourceLocation getKindKwLoc() const { return KindKwLoc; } + + child_range children() { + return child_range(child_iterator(), child_iterator()); + } + + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + + static bool classof(const OMPClause *T) { + return T->getClauseKind() == llvm::omp::OMPC_order; + } +}; + +/// This represents 'destroy' clause in the '#pragma omp depobj' +/// directive. +/// +/// \code +/// #pragma omp depobj(a) destroy +/// \endcode +/// In this example directive '#pragma omp depobj' has 'destroy' clause. +class OMPDestroyClause final : public OMPClause { +public: + /// Build 'destroy' clause. + /// + /// \param StartLoc Starting location of the clause. + /// \param EndLoc Ending location of the clause. + OMPDestroyClause(SourceLocation StartLoc, SourceLocation EndLoc) + : OMPClause(llvm::omp::OMPC_destroy, StartLoc, EndLoc) {} + + /// Build an empty clause. + OMPDestroyClause() + : OMPClause(llvm::omp::OMPC_destroy, SourceLocation(), SourceLocation()) { + } + + child_range children() { + return child_range(child_iterator(), child_iterator()); + } + + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + + static bool classof(const OMPClause *T) { + return T->getClauseKind() == llvm::omp::OMPC_destroy; + } +}; + +/// This represents 'detach' clause in the '#pragma omp task' directive. +/// +/// \code +/// #pragma omp task detach(evt) +/// \endcode +/// In this example directive '#pragma omp detach' has simple 'detach' clause +/// with the variable 'evt'. +class OMPDetachClause final : public OMPClause { + friend class OMPClauseReader; + + /// Location of '('. + SourceLocation LParenLoc; + + /// Expression of the 'detach' clause. + Stmt *Evt = nullptr; + + /// Set condition. + void setEventHandler(Expr *E) { Evt = E; } + + /// Sets the location of '('. + void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } + +public: + /// Build 'detach' clause with event-handler \a Evt. + /// + /// \param Evt Event handler expression. + /// \param StartLoc Starting location of the clause. + /// \param LParenLoc Location of '('. + /// \param EndLoc Ending location of the clause. + OMPDetachClause(Expr *Evt, SourceLocation StartLoc, SourceLocation LParenLoc, + SourceLocation EndLoc) + : OMPClause(llvm::omp::OMPC_detach, StartLoc, EndLoc), + LParenLoc(LParenLoc), Evt(Evt) {} + + /// Build an empty clause. + OMPDetachClause() + : OMPClause(llvm::omp::OMPC_detach, SourceLocation(), SourceLocation()) {} + + /// Returns the location of '('. + SourceLocation getLParenLoc() const { return LParenLoc; } + + /// Returns event-handler expression. + Expr *getEventHandler() const { return cast_or_null<Expr>(Evt); } + + child_range children() { return child_range(&Evt, &Evt + 1); } + + const_child_range children() const { + return const_child_range(&Evt, &Evt + 1); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + + static bool classof(const OMPClause *T) { + return T->getClauseKind() == llvm::omp::OMPC_detach; + } +}; + +/// This represents clause 'inclusive' in the '#pragma omp scan' directive. +/// +/// \code +/// #pragma omp scan inclusive(a,b) +/// \endcode +/// In this example directive '#pragma omp scan' has clause 'inclusive' +/// with the variables 'a' and 'b'. +class OMPInclusiveClause final + : public OMPVarListClause<OMPInclusiveClause>, + private llvm::TrailingObjects<OMPInclusiveClause, Expr *> { + friend class OMPClauseReader; + friend OMPVarListClause; + friend TrailingObjects; + + /// Build clause with number of variables \a N. + /// + /// \param StartLoc Starting location of the clause. + /// \param LParenLoc Location of '('. + /// \param EndLoc Ending location of the clause. + /// \param N Number of the variables in the clause. + OMPInclusiveClause(SourceLocation StartLoc, SourceLocation LParenLoc, + SourceLocation EndLoc, unsigned N) + : OMPVarListClause<OMPInclusiveClause>(llvm::omp::OMPC_inclusive, + StartLoc, LParenLoc, EndLoc, N) {} + + /// Build an empty clause. + /// + /// \param N Number of variables. + explicit OMPInclusiveClause(unsigned N) + : OMPVarListClause<OMPInclusiveClause>(llvm::omp::OMPC_inclusive, + SourceLocation(), SourceLocation(), + SourceLocation(), N) {} + +public: + /// Creates clause with a list of variables \a VL. + /// + /// \param C AST context. + /// \param StartLoc Starting location of the clause. + /// \param LParenLoc Location of '('. + /// \param EndLoc Ending location of the clause. + /// \param VL List of references to the original variables. + static OMPInclusiveClause *Create(const ASTContext &C, + SourceLocation StartLoc, + SourceLocation LParenLoc, + SourceLocation EndLoc, ArrayRef<Expr *> VL); + + /// Creates an empty clause with the place for \a N variables. + /// + /// \param C AST context. + /// \param N The number of variables. + static OMPInclusiveClause *CreateEmpty(const ASTContext &C, unsigned N); + + child_range children() { + return child_range(reinterpret_cast<Stmt **>(varlist_begin()), + reinterpret_cast<Stmt **>(varlist_end())); + } + + const_child_range children() const { + auto Children = const_cast<OMPInclusiveClause *>(this)->children(); + return const_child_range(Children.begin(), Children.end()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + + static bool classof(const OMPClause *T) { + return T->getClauseKind() == llvm::omp::OMPC_inclusive; + } +}; + +/// This represents clause 'exclusive' in the '#pragma omp scan' directive. +/// +/// \code +/// #pragma omp scan exclusive(a,b) +/// \endcode +/// In this example directive '#pragma omp scan' has clause 'exclusive' +/// with the variables 'a' and 'b'. +class OMPExclusiveClause final + : public OMPVarListClause<OMPExclusiveClause>, + private llvm::TrailingObjects<OMPExclusiveClause, Expr *> { + friend class OMPClauseReader; + friend OMPVarListClause; + friend TrailingObjects; + + /// Build clause with number of variables \a N. + /// + /// \param StartLoc Starting location of the clause. + /// \param LParenLoc Location of '('. + /// \param EndLoc Ending location of the clause. + /// \param N Number of the variables in the clause. + OMPExclusiveClause(SourceLocation StartLoc, SourceLocation LParenLoc, + SourceLocation EndLoc, unsigned N) + : OMPVarListClause<OMPExclusiveClause>(llvm::omp::OMPC_exclusive, + StartLoc, LParenLoc, EndLoc, N) {} + + /// Build an empty clause. + /// + /// \param N Number of variables. + explicit OMPExclusiveClause(unsigned N) + : OMPVarListClause<OMPExclusiveClause>(llvm::omp::OMPC_exclusive, + SourceLocation(), SourceLocation(), + SourceLocation(), N) {} + +public: + /// Creates clause with a list of variables \a VL. + /// + /// \param C AST context. + /// \param StartLoc Starting location of the clause. + /// \param LParenLoc Location of '('. + /// \param EndLoc Ending location of the clause. + /// \param VL List of references to the original variables. + static OMPExclusiveClause *Create(const ASTContext &C, + SourceLocation StartLoc, + SourceLocation LParenLoc, + SourceLocation EndLoc, ArrayRef<Expr *> VL); + + /// Creates an empty clause with the place for \a N variables. + /// + /// \param C AST context. + /// \param N The number of variables. + static OMPExclusiveClause *CreateEmpty(const ASTContext &C, unsigned N); + + child_range children() { + return child_range(reinterpret_cast<Stmt **>(varlist_begin()), + reinterpret_cast<Stmt **>(varlist_end())); + } + + const_child_range children() const { + auto Children = const_cast<OMPExclusiveClause *>(this)->children(); + return const_child_range(Children.begin(), Children.end()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + + static bool classof(const OMPClause *T) { + return T->getClauseKind() == llvm::omp::OMPC_exclusive; + } +}; + +/// This represents clause 'uses_allocators' in the '#pragma omp target'-based +/// directives. +/// +/// \code +/// #pragma omp target uses_allocators(default_allocator, my_allocator(traits)) +/// \endcode +/// In this example directive '#pragma omp target' has clause 'uses_allocators' +/// with the allocators 'default_allocator' and user-defined 'my_allocator'. +class OMPUsesAllocatorsClause final + : public OMPClause, + private llvm::TrailingObjects<OMPUsesAllocatorsClause, Expr *, + SourceLocation> { +public: + /// Data for list of allocators. + struct Data { + /// Allocator. + Expr *Allocator = nullptr; + /// Allocator traits. + Expr *AllocatorTraits = nullptr; + /// Locations of '(' and ')' symbols. + SourceLocation LParenLoc, RParenLoc; + }; + +private: + friend class OMPClauseReader; + friend TrailingObjects; + + enum class ExprOffsets { + Allocator, + AllocatorTraits, + Total, + }; + + enum class ParenLocsOffsets { + LParen, + RParen, + Total, + }; + + /// Location of '('. + SourceLocation LParenLoc; + /// Total number of allocators in the clause. + unsigned NumOfAllocators = 0; + + /// Build clause. + /// + /// \param StartLoc Starting location of the clause. + /// \param LParenLoc Location of '('. + /// \param EndLoc Ending location of the clause. + /// \param N Number of allocators asssociated with the clause. + OMPUsesAllocatorsClause(SourceLocation StartLoc, SourceLocation LParenLoc, + SourceLocation EndLoc, unsigned N) + : OMPClause(llvm::omp::OMPC_uses_allocators, StartLoc, EndLoc), + LParenLoc(LParenLoc), NumOfAllocators(N) {} + + /// Build an empty clause. + /// \param N Number of allocators asssociated with the clause. + /// + explicit OMPUsesAllocatorsClause(unsigned N) + : OMPClause(llvm::omp::OMPC_uses_allocators, SourceLocation(), + SourceLocation()), + NumOfAllocators(N) {} + + unsigned numTrailingObjects(OverloadToken<Expr *>) const { + return NumOfAllocators * static_cast<int>(ExprOffsets::Total); + } + + /// Sets the location of '('. + void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; } + + /// Sets the allocators data for the clause. + void setAllocatorsData(ArrayRef<OMPUsesAllocatorsClause::Data> Data); + +public: + /// Creates clause with a list of allocators \p Data. + /// + /// \param C AST context. + /// \param StartLoc Starting location of the clause. + /// \param LParenLoc Location of '('. + /// \param EndLoc Ending location of the clause. + /// \param Data List of allocators. + static OMPUsesAllocatorsClause * + Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, + SourceLocation EndLoc, ArrayRef<OMPUsesAllocatorsClause::Data> Data); + + /// Creates an empty clause with the place for \p N allocators. + /// + /// \param C AST context. + /// \param N The number of allocators. + static OMPUsesAllocatorsClause *CreateEmpty(const ASTContext &C, unsigned N); + + /// Returns the location of '('. + SourceLocation getLParenLoc() const { return LParenLoc; } + + /// Returns number of allocators associated with the clause. + unsigned getNumberOfAllocators() const { return NumOfAllocators; } + + /// Returns data for the specified allocator. + OMPUsesAllocatorsClause::Data getAllocatorData(unsigned I) const; + + // Iterators + child_range children() { + Stmt **Begin = reinterpret_cast<Stmt **>(getTrailingObjects<Expr *>()); + return child_range(Begin, Begin + NumOfAllocators * + static_cast<int>(ExprOffsets::Total)); + } + const_child_range children() const { + Stmt *const *Begin = + reinterpret_cast<Stmt *const *>(getTrailingObjects<Expr *>()); + return const_child_range( + Begin, Begin + NumOfAllocators * static_cast<int>(ExprOffsets::Total)); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + + static bool classof(const OMPClause *T) { + return T->getClauseKind() == llvm::omp::OMPC_uses_allocators; + } +}; + +/// This represents clause 'affinity' in the '#pragma omp task'-based +/// directives. +/// +/// \code +/// #pragma omp task affinity(iterator(i = 0:n) : ([3][n])a, b[:n], c[i]) +/// \endcode +/// In this example directive '#pragma omp task' has clause 'affinity' with the +/// affinity modifer 'iterator(i = 0:n)' and locator items '([3][n])a', 'b[:n]' +/// and 'c[i]'. +class OMPAffinityClause final + : public OMPVarListClause<OMPAffinityClause>, + private llvm::TrailingObjects<OMPAffinityClause, Expr *> { + friend class OMPClauseReader; + friend OMPVarListClause; + friend TrailingObjects; + + /// Location of ':' symbol. + SourceLocation ColonLoc; + + /// Build clause. + /// + /// \param StartLoc Starting location of the clause. + /// \param LParenLoc Location of '('. + /// \param ColonLoc Location of ':'. + /// \param EndLoc Ending location of the clause. + /// \param N Number of locators asssociated with the clause. + OMPAffinityClause(SourceLocation StartLoc, SourceLocation LParenLoc, + SourceLocation ColonLoc, SourceLocation EndLoc, unsigned N) + : OMPVarListClause<OMPAffinityClause>(llvm::omp::OMPC_affinity, StartLoc, + LParenLoc, EndLoc, N) {} + + /// Build an empty clause. + /// \param N Number of locators asssociated with the clause. + /// + explicit OMPAffinityClause(unsigned N) + : OMPVarListClause<OMPAffinityClause>(llvm::omp::OMPC_affinity, + SourceLocation(), SourceLocation(), + SourceLocation(), N) {} + + /// Sets the affinity modifier for the clause, if any. + void setModifier(Expr *E) { + getTrailingObjects<Expr *>()[varlist_size()] = E; + } + + /// Sets the location of ':' symbol. + void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; } + +public: + /// Creates clause with a modifier a list of locator items. + /// + /// \param C AST context. + /// \param StartLoc Starting location of the clause. + /// \param LParenLoc Location of '('. + /// \param ColonLoc Location of ':'. + /// \param EndLoc Ending location of the clause. + /// \param Locators List of locator items. + static OMPAffinityClause *Create(const ASTContext &C, SourceLocation StartLoc, + SourceLocation LParenLoc, + SourceLocation ColonLoc, + SourceLocation EndLoc, Expr *Modifier, + ArrayRef<Expr *> Locators); + + /// Creates an empty clause with the place for \p N locator items. + /// + /// \param C AST context. + /// \param N The number of locator items. + static OMPAffinityClause *CreateEmpty(const ASTContext &C, unsigned N); + + /// Gets affinity modifier. + Expr *getModifier() { return getTrailingObjects<Expr *>()[varlist_size()]; } + Expr *getModifier() const { + return getTrailingObjects<Expr *>()[varlist_size()]; + } + + /// Gets the location of ':' symbol. + SourceLocation getColonLoc() const { return ColonLoc; } + + // Iterators + child_range children() { + int Offset = getModifier() ? 1 : 0; + return child_range(reinterpret_cast<Stmt **>(varlist_begin()), + reinterpret_cast<Stmt **>(varlist_end() + Offset)); + } + + const_child_range children() const { + auto Children = const_cast<OMPAffinityClause *>(this)->children(); + return const_child_range(Children.begin(), Children.end()); + } + + child_range used_children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range used_children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } + + static bool classof(const OMPClause *T) { + return T->getClauseKind() == llvm::omp::OMPC_affinity; } }; @@ -6372,21 +7538,26 @@ public: template<class ImplClass, template <typename> class Ptr, typename RetTy> class OMPClauseVisitorBase { public: -#define PTR(CLASS) typename Ptr<CLASS>::type +#define PTR(CLASS) Ptr<CLASS> #define DISPATCH(CLASS) \ return static_cast<ImplClass*>(this)->Visit##CLASS(static_cast<PTR(CLASS)>(S)) -#define OPENMP_CLAUSE(Name, Class) \ +#define OMP_CLAUSE_CLASS(Enum, Str, Class) \ RetTy Visit ## Class (PTR(Class) S) { DISPATCH(Class); } -#include "clang/Basic/OpenMPKinds.def" +#include "llvm/Frontend/OpenMP/OMPKinds.def" RetTy Visit(PTR(OMPClause) S) { // Top switch clause: visit each OMPClause. switch (S->getClauseKind()) { - default: llvm_unreachable("Unknown clause kind!"); -#define OPENMP_CLAUSE(Name, Class) \ - case OMPC_ ## Name : return Visit ## Class(static_cast<PTR(Class)>(S)); -#include "clang/Basic/OpenMPKinds.def" +#define OMP_CLAUSE_CLASS(Enum, Str, Class) \ + case llvm::omp::Clause::Enum: \ + return Visit##Class(static_cast<PTR(Class)>(S)); +#define OMP_CLAUSE_NO_CLASS(Enum, Str) \ + case llvm::omp::Clause::Enum: \ + break; +#include "llvm/Frontend/OpenMP/OMPKinds.def" + default: + break; } } // Base case, ignore it. :) @@ -6395,12 +7566,11 @@ public: #undef DISPATCH }; -template <typename T> -using const_ptr = typename std::add_pointer<typename std::add_const<T>::type>; +template <typename T> using const_ptr = std::add_pointer_t<std::add_const_t<T>>; -template<class ImplClass, typename RetTy = void> -class OMPClauseVisitor : - public OMPClauseVisitorBase <ImplClass, std::add_pointer, RetTy> {}; +template <class ImplClass, typename RetTy = void> +class OMPClauseVisitor + : public OMPClauseVisitorBase<ImplClass, std::add_pointer_t, RetTy> {}; template<class ImplClass, typename RetTy = void> class ConstOMPClauseVisitor : public OMPClauseVisitorBase <ImplClass, const_ptr, RetTy> {}; @@ -6416,9 +7586,69 @@ public: OMPClausePrinter(raw_ostream &OS, const PrintingPolicy &Policy) : OS(OS), Policy(Policy) {} -#define OPENMP_CLAUSE(Name, Class) void Visit##Class(Class *S); -#include "clang/Basic/OpenMPKinds.def" +#define OMP_CLAUSE_CLASS(Enum, Str, Class) \ + void Visit##Class(Class *S); +#include "llvm/Frontend/OpenMP/OMPKinds.def" +}; + +struct OMPTraitProperty { + llvm::omp::TraitProperty Kind = llvm::omp::TraitProperty::invalid; +}; +struct OMPTraitSelector { + Expr *ScoreOrCondition = nullptr; + llvm::omp::TraitSelector Kind = llvm::omp::TraitSelector::invalid; + llvm::SmallVector<OMPTraitProperty, 1> Properties; +}; +struct OMPTraitSet { + llvm::omp::TraitSet Kind = llvm::omp::TraitSet::invalid; + llvm::SmallVector<OMPTraitSelector, 2> Selectors; +}; + +/// Helper data structure representing the traits in a match clause of an +/// `declare variant` or `metadirective`. The outer level is an ordered +/// collection of selector sets, each with an associated kind and an ordered +/// collection of selectors. A selector has a kind, an optional score/condition, +/// and an ordered collection of properties. +class OMPTraitInfo { + /// Private constructor accesible only by ASTContext. + OMPTraitInfo() {} + friend class ASTContext; + +public: + /// Reconstruct a (partial) OMPTraitInfo object from a mangled name. + OMPTraitInfo(StringRef MangledName); + + /// The outermost level of selector sets. + llvm::SmallVector<OMPTraitSet, 2> Sets; + + bool anyScoreOrCondition( + llvm::function_ref<bool(Expr *&, bool /* IsScore */)> Cond) { + return llvm::any_of(Sets, [&](OMPTraitSet &Set) { + return llvm::any_of( + Set.Selectors, [&](OMPTraitSelector &Selector) { + return Cond(Selector.ScoreOrCondition, + /* IsScore */ Selector.Kind != + llvm::omp::TraitSelector::user_condition); + }); + }); + } + + /// Create a variant match info object from this trait info object. While the + /// former is a flat representation the actual main difference is that the + /// latter uses clang::Expr to store the score/condition while the former is + /// independent of clang. Thus, expressions and conditions are evaluated in + /// this method. + void getAsVariantMatchInfo(ASTContext &ASTCtx, + llvm::omp::VariantMatchInfo &VMI) const; + + /// Return a string representation identifying this context selector. + std::string getMangledName() const; + + /// Print a human readable representation into \p OS. + void print(llvm::raw_ostream &OS, const PrintingPolicy &Policy) const; }; +llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const OMPTraitInfo &TI); +llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const OMPTraitInfo *TI); } // namespace clang diff --git a/clang/include/clang/AST/ParentMapContext.h b/clang/include/clang/AST/ParentMapContext.h new file mode 100644 index 000000000000..be4d75df7b99 --- /dev/null +++ b/clang/include/clang/AST/ParentMapContext.h @@ -0,0 +1,144 @@ +//===- ParentMapContext.h - Map of parents using DynTypedNode -------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// Similar to ParentMap.h, but generalizes to non-Stmt nodes, which can have +// multiple parents. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_AST_PARENTMAPCONTEXT_H +#define LLVM_CLANG_AST_PARENTMAPCONTEXT_H + +#include "clang/AST/ASTContext.h" +#include "clang/AST/ASTTypeTraits.h" + +namespace clang { +class DynTypedNodeList; + +class ParentMapContext { +public: + ParentMapContext(ASTContext &Ctx); + + ~ParentMapContext(); + + /// Returns the parents of the given node (within the traversal scope). + /// + /// Note that this will lazily compute the parents of all nodes + /// and store them for later retrieval. Thus, the first call is O(n) + /// in the number of AST nodes. + /// + /// Caveats and FIXMEs: + /// Calculating the parent map over all AST nodes will need to load the + /// full AST. This can be undesirable in the case where the full AST is + /// expensive to create (for example, when using precompiled header + /// preambles). Thus, there are good opportunities for optimization here. + /// One idea is to walk the given node downwards, looking for references + /// to declaration contexts - once a declaration context is found, compute + /// the parent map for the declaration context; if that can satisfy the + /// request, loading the whole AST can be avoided. Note that this is made + /// more complex by statements in templates having multiple parents - those + /// problems can be solved by building closure over the templated parts of + /// the AST, which also avoids touching large parts of the AST. + /// Additionally, we will want to add an interface to already give a hint + /// where to search for the parents, for example when looking at a statement + /// inside a certain function. + /// + /// 'NodeT' can be one of Decl, Stmt, Type, TypeLoc, + /// NestedNameSpecifier or NestedNameSpecifierLoc. + template <typename NodeT> DynTypedNodeList getParents(const NodeT &Node); + + DynTypedNodeList getParents(const DynTypedNode &Node); + + /// Clear parent maps. + void clear(); + + TraversalKind getTraversalKind() const { return Traversal; } + void setTraversalKind(TraversalKind TK) { Traversal = TK; } + + const Expr *traverseIgnored(const Expr *E) const; + Expr *traverseIgnored(Expr *E) const; + DynTypedNode traverseIgnored(const DynTypedNode &N) const; + +private: + ASTContext &ASTCtx; + class ParentMap; + TraversalKind Traversal = TK_AsIs; + std::unique_ptr<ParentMap> Parents; +}; + +class TraversalKindScope { + ParentMapContext &Ctx; + TraversalKind TK = TK_AsIs; + +public: + TraversalKindScope(ASTContext &ASTCtx, llvm::Optional<TraversalKind> ScopeTK) + : Ctx(ASTCtx.getParentMapContext()) { + TK = Ctx.getTraversalKind(); + if (ScopeTK) + Ctx.setTraversalKind(*ScopeTK); + } + + ~TraversalKindScope() { Ctx.setTraversalKind(TK); } +}; + +/// Container for either a single DynTypedNode or for an ArrayRef to +/// DynTypedNode. For use with ParentMap. +class DynTypedNodeList { + llvm::AlignedCharArrayUnion<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 DynTypedNode *begin() const { + if (!IsSingleNode) + return reinterpret_cast<const ArrayRef<DynTypedNode> *>(Storage.buffer) + ->begin(); + return reinterpret_cast<const DynTypedNode *>(Storage.buffer); + } + + const 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); + } +}; + +template <typename NodeT> +inline DynTypedNodeList ParentMapContext::getParents(const NodeT &Node) { + return getParents(DynTypedNode::create(Node)); +} + +template <typename NodeT> +inline DynTypedNodeList ASTContext::getParents(const NodeT &Node) { + return getParentMapContext().getParents(Node); +} + +template <> +inline DynTypedNodeList ASTContext::getParents(const DynTypedNode &Node) { + return getParentMapContext().getParents(Node); +} + +} // namespace clang + +#endif diff --git a/clang/include/clang/AST/PrettyPrinter.h b/clang/include/clang/AST/PrettyPrinter.h index 80eec6a5a8be..616647f44430 100644 --- a/clang/include/clang/AST/PrettyPrinter.h +++ b/clang/include/clang/AST/PrettyPrinter.h @@ -36,7 +36,9 @@ protected: public: /// Remap a path to a form suitable for printing. - virtual std::string remapPath(StringRef Path) const { return Path; } + virtual std::string remapPath(StringRef Path) const { + return std::string(Path); + } }; /// Describes how types, statements, expressions, and declarations should be @@ -55,12 +57,13 @@ struct PrintingPolicy { SuppressLifetimeQualifiers(false), SuppressTemplateArgsInCXXConstructors(false), Bool(LO.Bool), Restrict(LO.C99), Alignof(LO.CPlusPlus11), UnderscoreAlignof(LO.C11), - UseVoidForZeroParams(!LO.CPlusPlus), TerseOutput(false), + UseVoidForZeroParams(!LO.CPlusPlus), + SplitTemplateClosers(!LO.CPlusPlus11), TerseOutput(false), PolishForDeclaration(false), Half(LO.Half), MSWChar(LO.MicrosoftExt && !LO.WChar), IncludeNewlines(true), MSVCFormatting(false), ConstantsAsWritten(false), SuppressImplicitBase(false), FullyQualifiedName(false), - PrintCanonicalTypes(false) {} + PrintCanonicalTypes(false), PrintInjectedClassNameWithArguments(true) {} /// Adjust this printing policy for cases where it's known that we're /// printing C++ code (for instance, if AST dumping reaches a C++-only @@ -181,6 +184,10 @@ struct PrintingPolicy { /// with zero parameters. unsigned UseVoidForZeroParams : 1; + /// Whether nested templates must be closed like 'a\<b\<c\> \>' rather than + /// 'a\<b\<c\>\>'. + unsigned SplitTemplateClosers : 1; + /// Provide a 'terse' output. /// /// For example, in this mode we don't print function bodies, class members, @@ -237,6 +244,11 @@ struct PrintingPolicy { /// Whether to print types as written or canonically. unsigned PrintCanonicalTypes : 1; + /// Whether to print an InjectedClassNameType with template arguments or as + /// written. When a template argument is unnamed, printing it results in + /// invalid C++ code. + unsigned PrintInjectedClassNameWithArguments : 1; + /// Callbacks to use to allow the behavior of printing to be customized. const PrintingCallbacks *Callbacks = nullptr; }; diff --git a/clang/include/clang/AST/PropertiesBase.td b/clang/include/clang/AST/PropertiesBase.td index 9aacdb9fee36..ba0f237a3bc3 100644 --- a/clang/include/clang/AST/PropertiesBase.td +++ b/clang/include/clang/AST/PropertiesBase.td @@ -99,6 +99,8 @@ def DeclRef : RefPropertyType<"Decl"> { let ConstWhenWriting = 1; } SubclassPropertyType<"TagDecl", DeclRef>; def TemplateDeclRef : SubclassPropertyType<"TemplateDecl", DeclRef>; + def ConceptDeclRef : + SubclassPropertyType<"ConceptDecl", DeclRef>; def TemplateTypeParmDeclRef : SubclassPropertyType<"TemplateTypeParmDecl", DeclRef>; def TemplateTemplateParmDeclRef : diff --git a/clang/include/clang/AST/RawCommentList.h b/clang/include/clang/AST/RawCommentList.h index 1eea56dee622..a18432c2b768 100644 --- a/clang/include/clang/AST/RawCommentList.h +++ b/clang/include/clang/AST/RawCommentList.h @@ -11,9 +11,9 @@ #include "clang/Basic/CommentOptions.h" #include "clang/Basic/SourceLocation.h" -#include "clang/Basic/SourceManager.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/Support/Allocator.h" #include <map> namespace clang { @@ -21,7 +21,9 @@ namespace clang { class ASTContext; class ASTReader; class Decl; +class DiagnosticsEngine; class Preprocessor; +class SourceManager; namespace comments { class FullComment; @@ -173,23 +175,6 @@ private: friend class ASTReader; }; -/// Compare comments' source locations. -template<> -class BeforeThanCompare<RawComment> { - const SourceManager &SM; - -public: - explicit BeforeThanCompare(const SourceManager &SM) : SM(SM) { } - - bool operator()(const RawComment &LHS, const RawComment &RHS) { - return SM.isBeforeInTranslationUnit(LHS.getBeginLoc(), RHS.getBeginLoc()); - } - - bool operator()(const RawComment *LHS, const RawComment *RHS) { - return operator()(*LHS, *RHS); - } -}; - /// This class represents all comments included in the translation unit, /// sorted in order of appearance in the translation unit. class RawCommentList { diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h index f8ab8e451d8c..3dcfc9fee629 100644 --- a/clang/include/clang/AST/RecursiveASTVisitor.h +++ b/clang/include/clang/AST/RecursiveASTVisitor.h @@ -23,6 +23,7 @@ #include "clang/AST/DeclOpenMP.h" #include "clang/AST/DeclTemplate.h" #include "clang/AST/Expr.h" +#include "clang/AST/ExprConcepts.h" #include "clang/AST/ExprCXX.h" #include "clang/AST/ExprObjC.h" #include "clang/AST/ExprOpenMP.h" @@ -47,29 +48,6 @@ #include <cstddef> #include <type_traits> -// 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) OPERATOR(Coawait) - -// 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(Cmp) 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 { // A helper macro to implement short-circuiting when recursing. It @@ -82,6 +60,42 @@ namespace clang { return false; \ } while (false) +namespace detail { + +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 {}; + +template <bool has_same_type> struct is_same_method_impl { + template <typename FirstMethodPtrTy, typename SecondMethodPtrTy> + static bool isSameMethod(FirstMethodPtrTy FirstMethodPtr, + SecondMethodPtrTy SecondMethodPtr) { + return false; + } +}; + +template <> struct is_same_method_impl<true> { + template <typename FirstMethodPtrTy, typename SecondMethodPtrTy> + static bool isSameMethod(FirstMethodPtrTy FirstMethodPtr, + SecondMethodPtrTy SecondMethodPtr) { + return FirstMethodPtr == SecondMethodPtr; + } +}; + +/// Returns true if and only if \p FirstMethodPtr and \p SecondMethodPtr +/// are pointers to the same non-static member function. +template <typename FirstMethodPtrTy, typename SecondMethodPtrTy> +bool isSameMethod(FirstMethodPtrTy FirstMethodPtr, + SecondMethodPtrTy SecondMethodPtr) { + return is_same_method_impl<has_same_member_pointer_type< + FirstMethodPtrTy, + SecondMethodPtrTy>::value>::isSameMethod(FirstMethodPtr, SecondMethodPtr); +} + +} // end namespace detail + /// A class that does preorder or postorder /// depth-first traversal on the entire Clang AST and visits each node. /// @@ -324,26 +338,20 @@ public: Stmt::child_range getStmtChildren(Stmt *S) { return S->children(); } 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< \ + (::clang::detail::has_same_member_pointer_type< \ + decltype(&RecursiveASTVisitor::Traverse##NAME), \ + decltype(&Derived::Traverse##NAME)>::value \ + ? static_cast<std::conditional_t< \ + ::clang::detail::has_same_member_pointer_type< \ decltype(&RecursiveASTVisitor::Traverse##NAME), \ decltype(&Derived::Traverse##NAME)>::value, \ - Derived &, RecursiveASTVisitor &>::type>(*this) \ + Derived &, RecursiveASTVisitor &>>(*this) \ .Traverse##NAME(static_cast<CLASS *>(VAR), QUEUE) \ : getDerived().Traverse##NAME(static_cast<CLASS *>(VAR))) @@ -376,60 +384,6 @@ public: 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, \ - DataRecursionQueue *Queue = nullptr) { \ - if (!getDerived().shouldTraversePostOrder()) \ - TRY_TO(WalkUpFromUnary##NAME(S)); \ - TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(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, DataRecursionQueue *Queue = nullptr) { \ - if (!getDerived().shouldTraversePostOrder()) \ - TRY_TO(WalkUpFromBin##NAME(S)); \ - TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getLHS()); \ - TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getRHS()); \ - return true; \ - } \ - bool WalkUpFromBin##NAME(BINOP_TYPE *S) { \ - 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. @@ -533,8 +487,8 @@ private: 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" +#define OMP_CLAUSE_CLASS(Enum, Str, Class) bool Visit##Class(Class *C); +#include "llvm/Frontend/OpenMP/OMPKinds.def" /// Process clauses with list of variables. template <typename T> bool VisitOMPClauseList(T *Node); /// Process clauses with pre-initis. @@ -548,42 +502,6 @@ private: template <typename Derived> bool RecursiveASTVisitor<Derived>::dataTraverseNode(Stmt *S, 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_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 - } - } - // Top switch stmt: dispatch to TraverseFooStmt for each concrete FooStmt. switch (S->getStmtClass()) { case Stmt::NoStmtClass: @@ -591,7 +509,7 @@ bool RecursiveASTVisitor<Derived>::dataTraverseNode(Stmt *S, #define ABSTRACT_STMT(STMT) #define STMT(CLASS, PARENT) \ case Stmt::CLASS##Class: \ - DISPATCH_STMT(CLASS, CLASS, S); + return TRAVERSE_STMT_BASE(CLASS, CLASS, S, Queue); #include "clang/AST/StmtNodes.inc" } @@ -602,23 +520,44 @@ bool RecursiveASTVisitor<Derived>::dataTraverseNode(Stmt *S, template <typename Derived> bool RecursiveASTVisitor<Derived>::PostVisitStmt(Stmt *S) { + // In pre-order traversal mode, each Traverse##STMT method is responsible for + // calling WalkUpFrom. Therefore, if the user overrides Traverse##STMT and + // does not call the default implementation, the WalkUpFrom callback is not + // called. Post-order traversal mode should provide the same behavior + // regarding method overrides. + // + // In post-order traversal mode the Traverse##STMT method, when it receives a + // DataRecursionQueue, can't call WalkUpFrom after traversing children because + // it only enqueues the children and does not traverse them. TraverseStmt + // traverses the enqueued children, and we call WalkUpFrom here. + // + // However, to make pre-order and post-order modes identical with regards to + // whether they call WalkUpFrom at all, we call WalkUpFrom if and only if the + // user did not override the Traverse##STMT method. We implement the override + // check with isSameMethod calls below. + switch (S->getStmtClass()) { case Stmt::NoStmtClass: break; #define ABSTRACT_STMT(STMT) #define STMT(CLASS, PARENT) \ case Stmt::CLASS##Class: \ - TRY_TO(WalkUpFrom##CLASS(static_cast<CLASS *>(S))); break; + if (::clang::detail::isSameMethod(&RecursiveASTVisitor::Traverse##CLASS, \ + &Derived::Traverse##CLASS)) { \ + TRY_TO(WalkUpFrom##CLASS(static_cast<CLASS *>(S))); \ + } \ + break; #define INITLISTEXPR(CLASS, PARENT) \ case Stmt::CLASS##Class: \ - { \ + if (::clang::detail::isSameMethod(&RecursiveASTVisitor::Traverse##CLASS, \ + &Derived::Traverse##CLASS)) { \ auto ILE = static_cast<CLASS *>(S); \ if (auto Syn = ILE->isSemanticForm() ? ILE->getSyntacticForm() : ILE) \ TRY_TO(WalkUpFrom##CLASS(Syn)); \ if (auto Sem = ILE->isSemanticForm() ? ILE : ILE->getSemanticForm()) \ TRY_TO(WalkUpFrom##CLASS(Sem)); \ - break; \ - } + } \ + break; #include "clang/AST/StmtNodes.inc" } @@ -668,9 +607,6 @@ bool RecursiveASTVisitor<Derived>::TraverseStmt(Stmt *S, return true; } -#define DISPATCH(NAME, CLASS, VAR) \ - return getDerived().Traverse##NAME(static_cast<CLASS *>(VAR)) - template <typename Derived> bool RecursiveASTVisitor<Derived>::TraverseType(QualType T) { if (T.isNull()) @@ -680,7 +616,8 @@ bool RecursiveASTVisitor<Derived>::TraverseType(QualType T) { #define ABSTRACT_TYPE(CLASS, BASE) #define TYPE(CLASS, BASE) \ case Type::CLASS: \ - DISPATCH(CLASS##Type, CLASS##Type, const_cast<Type *>(T.getTypePtr())); + return getDerived().Traverse##CLASS##Type( \ + static_cast<CLASS##Type *>(const_cast<Type *>(T.getTypePtr()))); #include "clang/AST/TypeNodes.inc" } @@ -730,8 +667,6 @@ bool RecursiveASTVisitor<Derived>::TraverseDecl(Decl *D) { return true; } -#undef DISPATCH - template <typename Derived> bool RecursiveASTVisitor<Derived>::TraverseNestedNameSpecifier( NestedNameSpecifier *NNS) { @@ -1005,6 +940,17 @@ DEF_TRAVERSE_TYPE(VectorType, { TRY_TO(TraverseType(T->getElementType())); }) DEF_TRAVERSE_TYPE(ExtVectorType, { TRY_TO(TraverseType(T->getElementType())); }) +DEF_TRAVERSE_TYPE(ConstantMatrixType, + { TRY_TO(TraverseType(T->getElementType())); }) + +DEF_TRAVERSE_TYPE(DependentSizedMatrixType, { + if (T->getRowExpr()) + TRY_TO(TraverseStmt(T->getRowExpr())); + if (T->getColumnExpr()) + TRY_TO(TraverseStmt(T->getColumnExpr())); + TRY_TO(TraverseType(T->getElementType())); +}) + DEF_TRAVERSE_TYPE(FunctionNoProtoType, { TRY_TO(TraverseType(T->getReturnType())); }) @@ -1039,7 +985,13 @@ DEF_TRAVERSE_TYPE(UnaryTransformType, { TRY_TO(TraverseType(T->getUnderlyingType())); }) -DEF_TRAVERSE_TYPE(AutoType, { TRY_TO(TraverseType(T->getDeducedType())); }) +DEF_TRAVERSE_TYPE(AutoType, { + TRY_TO(TraverseType(T->getDeducedType())); + if (T->isConstrained()) { + TRY_TO(TraverseDecl(T->getTypeConstraintConcept())); + TRY_TO(TraverseTemplateArguments(T->getArgs(), T->getNumArgs())); + } +}) DEF_TRAVERSE_TYPE(DeducedTemplateSpecializationType, { TRY_TO(TraverseTemplateName(T->getTemplateName())); TRY_TO(TraverseType(T->getDeducedType())); @@ -1108,6 +1060,10 @@ DEF_TRAVERSE_TYPE(AtomicType, { TRY_TO(TraverseType(T->getValueType())); }) DEF_TRAVERSE_TYPE(PipeType, { TRY_TO(TraverseType(T->getElementType())); }) +DEF_TRAVERSE_TYPE(ExtIntType, {}) +DEF_TRAVERSE_TYPE(DependentExtIntType, + { TRY_TO(TraverseStmt(T->getNumBitsExpr())); }) + #undef DEF_TRAVERSE_TYPE // ----------------- TypeLoc traversal ----------------- @@ -1120,10 +1076,17 @@ DEF_TRAVERSE_TYPE(PipeType, { TRY_TO(TraverseType(T->getElementType())); }) #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)); \ + if (!getDerived().shouldTraversePostOrder()) { \ + TRY_TO(WalkUpFrom##TYPE##Loc(TL)); \ + if (getDerived().shouldWalkTypesOfTypeLocs()) \ + TRY_TO(WalkUpFrom##TYPE(const_cast<TYPE *>(TL.getTypePtr()))); \ + } \ { CODE; } \ + if (getDerived().shouldTraversePostOrder()) { \ + TRY_TO(WalkUpFrom##TYPE##Loc(TL)); \ + if (getDerived().shouldWalkTypesOfTypeLocs()) \ + TRY_TO(WalkUpFrom##TYPE(const_cast<TYPE *>(TL.getTypePtr()))); \ + } \ return true; \ } @@ -1192,22 +1155,22 @@ bool RecursiveASTVisitor<Derived>::TraverseArrayTypeLocHelper(ArrayTypeLoc TL) { DEF_TRAVERSE_TYPELOC(ConstantArrayType, { TRY_TO(TraverseTypeLoc(TL.getElementLoc())); - return TraverseArrayTypeLocHelper(TL); + TRY_TO(TraverseArrayTypeLocHelper(TL)); }) DEF_TRAVERSE_TYPELOC(IncompleteArrayType, { TRY_TO(TraverseTypeLoc(TL.getElementLoc())); - return TraverseArrayTypeLocHelper(TL); + TRY_TO(TraverseArrayTypeLocHelper(TL)); }) DEF_TRAVERSE_TYPELOC(VariableArrayType, { TRY_TO(TraverseTypeLoc(TL.getElementLoc())); - return TraverseArrayTypeLocHelper(TL); + TRY_TO(TraverseArrayTypeLocHelper(TL)); }) DEF_TRAVERSE_TYPELOC(DependentSizedArrayType, { TRY_TO(TraverseTypeLoc(TL.getElementLoc())); - return TraverseArrayTypeLocHelper(TL); + TRY_TO(TraverseArrayTypeLocHelper(TL)); }) DEF_TRAVERSE_TYPELOC(DependentAddressSpaceType, { @@ -1240,6 +1203,18 @@ DEF_TRAVERSE_TYPELOC(ExtVectorType, { TRY_TO(TraverseType(TL.getTypePtr()->getElementType())); }) +DEF_TRAVERSE_TYPELOC(ConstantMatrixType, { + TRY_TO(TraverseStmt(TL.getAttrRowOperand())); + TRY_TO(TraverseStmt(TL.getAttrColumnOperand())); + TRY_TO(TraverseType(TL.getTypePtr()->getElementType())); +}) + +DEF_TRAVERSE_TYPELOC(DependentSizedMatrixType, { + TRY_TO(TraverseStmt(TL.getAttrRowOperand())); + TRY_TO(TraverseStmt(TL.getAttrColumnOperand())); + TRY_TO(TraverseType(TL.getTypePtr()->getElementType())); +}) + DEF_TRAVERSE_TYPELOC(FunctionNoProtoType, { TRY_TO(TraverseTypeLoc(TL.getReturnLoc())); }) @@ -1286,6 +1261,12 @@ DEF_TRAVERSE_TYPELOC(UnaryTransformType, { DEF_TRAVERSE_TYPELOC(AutoType, { TRY_TO(TraverseType(TL.getTypePtr()->getDeducedType())); + if (TL.isConstrained()) { + TRY_TO(TraverseNestedNameSpecifierLoc(TL.getNestedNameSpecifierLoc())); + TRY_TO(TraverseDeclarationNameInfo(TL.getConceptNameInfo())); + for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) + TRY_TO(TraverseTemplateArgumentLoc(TL.getArgLoc(I))); + } }) DEF_TRAVERSE_TYPELOC(DeducedTemplateSpecializationType, { @@ -1365,6 +1346,11 @@ DEF_TRAVERSE_TYPELOC(AtomicType, { TRY_TO(TraverseTypeLoc(TL.getValueLoc())); }) DEF_TRAVERSE_TYPELOC(PipeType, { TRY_TO(TraverseTypeLoc(TL.getValueLoc())); }) +DEF_TRAVERSE_TYPELOC(ExtIntType, {}) +DEF_TRAVERSE_TYPELOC(DependentExtIntType, { + TRY_TO(TraverseStmt(TL.getTypePtr()->getNumBitsExpr())); +}) + #undef DEF_TRAVERSE_TYPELOC // ----------------- Decl traversal ----------------- @@ -1973,6 +1959,8 @@ DEF_TRAVERSE_DECL(BindingDecl, { DEF_TRAVERSE_DECL(MSPropertyDecl, { TRY_TO(TraverseDeclaratorHelper(D)); }) +DEF_TRAVERSE_DECL(MSGuidDecl, {}) + DEF_TRAVERSE_DECL(FieldDecl, { TRY_TO(TraverseDeclaratorHelper(D)); if (D->isBitField()) @@ -2049,11 +2037,11 @@ bool RecursiveASTVisitor<Derived>::TraverseFunctionHelper(FunctionDecl *D) { } } - bool VisitBody = D->isThisDeclarationADefinition(); - // If a method is set to default outside the class definition the compiler - // generates the method body and adds it to the AST. - if (const auto *MD = dyn_cast<CXXMethodDecl>(D)) - VisitBody &= !MD->isDefaulted() || getDerived().shouldVisitImplicitCode(); + bool VisitBody = + D->isThisDeclarationADefinition() && + // Don't visit the function body if the function definition is generated + // by clang. + (!D->isDefaulted() || getDerived().shouldVisitImplicitCode()); if (VisitBody) { TRY_TO(TraverseStmt(D->getBody())); // Function body. @@ -2138,6 +2126,8 @@ DEF_TRAVERSE_DECL(ParmVarDecl, { TRY_TO(TraverseStmt(D->getDefaultArg())); }) +DEF_TRAVERSE_DECL(RequiresExprBodyDecl, {}) + #undef DEF_TRAVERSE_DECL // ----------------- Stmt traversal ----------------- @@ -2164,8 +2154,13 @@ DEF_TRAVERSE_DECL(ParmVarDecl, { TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(SubStmt); \ } \ } \ - if (!Queue && ReturnValue && getDerived().shouldTraversePostOrder()) \ + /* Call WalkUpFrom if TRY_TO_TRAVERSE_OR_ENQUEUE_STMT has traversed the \ + * children already. If TRY_TO_TRAVERSE_OR_ENQUEUE_STMT only enqueued the \ + * children, PostVisitStmt will call WalkUpFrom after we are done visiting \ + * children. */ \ + if (!Queue && ReturnValue && getDerived().shouldTraversePostOrder()) { \ TRY_TO(WalkUpFrom##STMT(S)); \ + } \ return ReturnValue; \ } @@ -2299,6 +2294,10 @@ DEF_TRAVERSE_STMT(CXXFunctionalCastExpr, { TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc())); }) +DEF_TRAVERSE_STMT(CXXAddrspaceCastExpr, { + TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc())); +}) + DEF_TRAVERSE_STMT(CXXConstCastExpr, { TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc())); }) @@ -2332,6 +2331,9 @@ bool RecursiveASTVisitor<Derived>::TraverseSynOrSemInitListExpr( for (Stmt *SubStmt : S->children()) { TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(SubStmt); } + + if (!Queue && getDerived().shouldTraversePostOrder()) + TRY_TO(WalkUpFromInitListExpr(S)); } return true; } @@ -2528,7 +2530,10 @@ DEF_TRAVERSE_STMT(CXXMemberCallExpr, {}) // over the children. DEF_TRAVERSE_STMT(AddrLabelExpr, {}) DEF_TRAVERSE_STMT(ArraySubscriptExpr, {}) +DEF_TRAVERSE_STMT(MatrixSubscriptExpr, {}) DEF_TRAVERSE_STMT(OMPArraySectionExpr, {}) +DEF_TRAVERSE_STMT(OMPArrayShapingExpr, {}) +DEF_TRAVERSE_STMT(OMPIteratorExpr, {}) DEF_TRAVERSE_STMT(BlockExpr, { TRY_TO(TraverseDecl(S->getBlockDecl())); @@ -2646,6 +2651,7 @@ DEF_TRAVERSE_STMT(CXXRewrittenBinaryOperator, { }) DEF_TRAVERSE_STMT(OpaqueValueExpr, {}) DEF_TRAVERSE_STMT(TypoExpr, {}) +DEF_TRAVERSE_STMT(RecoveryExpr, {}) DEF_TRAVERSE_STMT(CUDAKernelCallExpr, {}) // These operators (all of them) do not need any action except @@ -2709,6 +2715,28 @@ DEF_TRAVERSE_STMT(ConceptSpecializationExpr, { TRY_TO(TraverseConceptReference(*S)); }) +DEF_TRAVERSE_STMT(RequiresExpr, { + TRY_TO(TraverseDecl(S->getBody())); + for (ParmVarDecl *Parm : S->getLocalParameters()) + TRY_TO(TraverseDecl(Parm)); + for (concepts::Requirement *Req : S->getRequirements()) + if (auto *TypeReq = dyn_cast<concepts::TypeRequirement>(Req)) { + if (!TypeReq->isSubstitutionFailure()) + TRY_TO(TraverseTypeLoc(TypeReq->getType()->getTypeLoc())); + } else if (auto *ExprReq = dyn_cast<concepts::ExprRequirement>(Req)) { + if (!ExprReq->isExprSubstitutionFailure()) + TRY_TO(TraverseStmt(ExprReq->getExpr())); + auto &RetReq = ExprReq->getReturnTypeRequirement(); + if (RetReq.isTypeConstraint()) + TRY_TO(TraverseTemplateParameterListHelper( + RetReq.getTypeConstraintTemplateParameterList())); + } else { + auto *NestedReq = cast<concepts::NestedRequirement>(Req); + if (!NestedReq->isSubstitutionFailure()) + TRY_TO(TraverseStmt(NestedReq->getConstraintExpr())); + } +}) + // These literals (all of them) do not need any action. DEF_TRAVERSE_STMT(IntegerLiteral, {}) DEF_TRAVERSE_STMT(FixedPointLiteral, {}) @@ -2805,6 +2833,12 @@ DEF_TRAVERSE_STMT(OMPCancelDirective, DEF_TRAVERSE_STMT(OMPFlushDirective, { TRY_TO(TraverseOMPExecutableDirective(S)); }) +DEF_TRAVERSE_STMT(OMPDepobjDirective, + { TRY_TO(TraverseOMPExecutableDirective(S)); }) + +DEF_TRAVERSE_STMT(OMPScanDirective, + { TRY_TO(TraverseOMPExecutableDirective(S)); }) + DEF_TRAVERSE_STMT(OMPOrderedDirective, { TRY_TO(TraverseOMPExecutableDirective(S)); }) @@ -2904,16 +2938,15 @@ bool RecursiveASTVisitor<Derived>::TraverseOMPClause(OMPClause *C) { if (!C) return true; switch (C->getClauseKind()) { -#define OPENMP_CLAUSE(Name, Class) \ - case OMPC_##Name: \ +#define OMP_CLAUSE_CLASS(Enum, Str, Class) \ + case llvm::omp::Clause::Enum: \ TRY_TO(Visit##Class(static_cast<Class *>(C))); \ break; -#include "clang/Basic/OpenMPKinds.def" - case OMPC_threadprivate: - case OMPC_uniform: - case OMPC_device_type: - case OMPC_match: - case OMPC_unknown: +#define OMP_CLAUSE_NO_CLASS(Enum, Str) \ + case llvm::omp::Clause::Enum: \ + break; +#include "llvm/Frontend/OpenMP/OMPKinds.def" + default: break; } return true; @@ -3085,6 +3118,26 @@ bool RecursiveASTVisitor<Derived>::VisitOMPSeqCstClause(OMPSeqCstClause *) { } template <typename Derived> +bool RecursiveASTVisitor<Derived>::VisitOMPAcqRelClause(OMPAcqRelClause *) { + return true; +} + +template <typename Derived> +bool RecursiveASTVisitor<Derived>::VisitOMPAcquireClause(OMPAcquireClause *) { + return true; +} + +template <typename Derived> +bool RecursiveASTVisitor<Derived>::VisitOMPReleaseClause(OMPReleaseClause *) { + return true; +} + +template <typename Derived> +bool RecursiveASTVisitor<Derived>::VisitOMPRelaxedClause(OMPRelaxedClause *) { + return true; +} + +template <typename Derived> bool RecursiveASTVisitor<Derived>::VisitOMPThreadsClause(OMPThreadsClause *) { return true; } @@ -3100,6 +3153,11 @@ bool RecursiveASTVisitor<Derived>::VisitOMPNogroupClause(OMPNogroupClause *) { } template <typename Derived> +bool RecursiveASTVisitor<Derived>::VisitOMPDestroyClause(OMPDestroyClause *) { + return true; +} + +template <typename Derived> template <typename T> bool RecursiveASTVisitor<Derived>::VisitOMPClauseList(T *Node) { for (auto *E : Node->varlists()) { @@ -3109,6 +3167,20 @@ bool RecursiveASTVisitor<Derived>::VisitOMPClauseList(T *Node) { } template <typename Derived> +bool RecursiveASTVisitor<Derived>::VisitOMPInclusiveClause( + OMPInclusiveClause *C) { + TRY_TO(VisitOMPClauseList(C)); + return true; +} + +template <typename Derived> +bool RecursiveASTVisitor<Derived>::VisitOMPExclusiveClause( + OMPExclusiveClause *C) { + TRY_TO(VisitOMPClauseList(C)); + return true; +} + +template <typename Derived> bool RecursiveASTVisitor<Derived>::VisitOMPPrivateClause(OMPPrivateClause *C) { TRY_TO(VisitOMPClauseList(C)); for (auto *E : C->private_copies()) { @@ -3235,6 +3307,17 @@ RecursiveASTVisitor<Derived>::VisitOMPReductionClause(OMPReductionClause *C) { for (auto *E : C->reduction_ops()) { TRY_TO(TraverseStmt(E)); } + if (C->getModifier() == OMPC_REDUCTION_inscan) { + for (auto *E : C->copy_ops()) { + TRY_TO(TraverseStmt(E)); + } + for (auto *E : C->copy_array_temps()) { + TRY_TO(TraverseStmt(E)); + } + for (auto *E : C->copy_array_elems()) { + TRY_TO(TraverseStmt(E)); + } + } return true; } @@ -3291,6 +3374,12 @@ bool RecursiveASTVisitor<Derived>::VisitOMPFlushClause(OMPFlushClause *C) { } template <typename Derived> +bool RecursiveASTVisitor<Derived>::VisitOMPDepobjClause(OMPDepobjClause *C) { + TRY_TO(TraverseStmt(C->getDepobj())); + return true; +} + +template <typename Derived> bool RecursiveASTVisitor<Derived>::VisitOMPDependClause(OMPDependClause *C) { TRY_TO(VisitOMPClauseList(C)); return true; @@ -3389,6 +3478,13 @@ bool RecursiveASTVisitor<Derived>::VisitOMPUseDevicePtrClause( } template <typename Derived> +bool RecursiveASTVisitor<Derived>::VisitOMPUseDeviceAddrClause( + OMPUseDeviceAddrClause *C) { + TRY_TO(VisitOMPClauseList(C)); + return true; +} + +template <typename Derived> bool RecursiveASTVisitor<Derived>::VisitOMPIsDevicePtrClause( OMPIsDevicePtrClause *C) { TRY_TO(VisitOMPClauseList(C)); @@ -3405,6 +3501,37 @@ bool RecursiveASTVisitor<Derived>::VisitOMPNontemporalClause( return true; } +template <typename Derived> +bool RecursiveASTVisitor<Derived>::VisitOMPOrderClause(OMPOrderClause *) { + return true; +} + +template <typename Derived> +bool RecursiveASTVisitor<Derived>::VisitOMPDetachClause(OMPDetachClause *C) { + TRY_TO(TraverseStmt(C->getEventHandler())); + return true; +} + +template <typename Derived> +bool RecursiveASTVisitor<Derived>::VisitOMPUsesAllocatorsClause( + OMPUsesAllocatorsClause *C) { + for (unsigned I = 0, E = C->getNumberOfAllocators(); I < E; ++I) { + const OMPUsesAllocatorsClause::Data Data = C->getAllocatorData(I); + TRY_TO(TraverseStmt(Data.Allocator)); + TRY_TO(TraverseStmt(Data.AllocatorTraits)); + } + return true; +} + +template <typename Derived> +bool RecursiveASTVisitor<Derived>::VisitOMPAffinityClause( + OMPAffinityClause *C) { + TRY_TO(TraverseStmt(C->getModifier())); + for (Expr *E : C->varlists()) + TRY_TO(TraverseStmt(E)); + return true; +} + // FIXME: look at the following tricky-seeming exprs to see if we // need to recurse on anything. These are ones that have methods // returning decls or qualtypes or nestednamespecifier -- though I'm diff --git a/clang/include/clang/AST/Stmt.h b/clang/include/clang/AST/Stmt.h index eaacb1a5b252..d3fad58fcf59 100644 --- a/clang/include/clang/AST/Stmt.h +++ b/clang/include/clang/AST/Stmt.h @@ -14,12 +14,14 @@ #define LLVM_CLANG_AST_STMT_H #include "clang/AST/DeclGroup.h" +#include "clang/AST/DependenceFlags.h" #include "clang/AST/StmtIterator.h" #include "clang/Basic/CapturedStmt.h" #include "clang/Basic/IdentifierTable.h" #include "clang/Basic/LLVM.h" #include "clang/Basic/SourceLocation.h" #include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/BitmaskEnum.h" #include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/iterator.h" @@ -98,14 +100,8 @@ protected: /// The statement class. unsigned sClass : 8; - - /// This bit is set only for the Stmts that are the structured-block of - /// OpenMP executable directives. Directives that have a structured block - /// are called "non-standalone" directives. - /// I.e. those returned by OMPExecutableDirective::getStructuredBlock(). - unsigned IsOMPStructuredBlock : 1; }; - enum { NumStmtBits = 9 }; + enum { NumStmtBits = 8 }; class NullStmtBitfields { friend class ASTStmtReader; @@ -315,12 +311,9 @@ protected: unsigned ValueKind : 2; unsigned ObjectKind : 3; - unsigned TypeDependent : 1; - unsigned ValueDependent : 1; - unsigned InstantiationDependent : 1; - unsigned ContainsUnexpandedParameterPack : 1; + unsigned /*ExprDependence*/ Dependent : llvm::BitWidth<ExprDependence>; }; - enum { NumExprBits = NumStmtBits + 9 }; + enum { NumExprBits = NumStmtBits + 5 + llvm::BitWidth<ExprDependence> }; class ConstantExprBitfields { friend class ASTStmtReader; @@ -329,24 +322,27 @@ protected: unsigned : NumExprBits; - /// The kind of result that is trail-allocated. + /// The kind of result that is tail-allocated. unsigned ResultKind : 2; - /// Kind of Result as defined by APValue::Kind + /// The kind of Result as defined by APValue::Kind. unsigned APValueKind : 4; - /// When ResultKind == RSK_Int64. whether the trail-allocated integer is - /// signed. + /// When ResultKind == RSK_Int64, true if the tail-allocated integer is + /// unsigned. unsigned IsUnsigned : 1; - /// When ResultKind == RSK_Int64. the BitWidth of the trail-allocated - /// integer. 7 bits because it is the minimal number of bit to represent a - /// value from 0 to 64 (the size of the trail-allocated number). + /// When ResultKind == RSK_Int64. the BitWidth of the tail-allocated + /// integer. 7 bits because it is the minimal number of bits to represent a + /// value from 0 to 64 (the size of the tail-allocated integer). unsigned BitWidth : 7; - /// When ResultKind == RSK_APValue. Wether the ASTContext will cleanup the - /// destructor on the trail-allocated APValue. + /// When ResultKind == RSK_APValue, true if the ASTContext will cleanup the + /// tail-allocated APValue. unsigned HasCleanup : 1; + + /// True if this ConstantExpr was created for immediate invocation. + unsigned IsImmediateInvocation : 1; }; class PredefinedExprBitfields { @@ -431,6 +427,11 @@ protected: unsigned Opc : 5; unsigned CanOverflow : 1; + // + /// This is only meaningful for operations on floating point + /// types when additional values need to be in trailing storage. + /// It is 0 otherwise. + unsigned HasFPFeatures : 1; SourceLocation Loc; }; @@ -444,8 +445,9 @@ protected: unsigned IsType : 1; // true if operand is a type, false if an expression. }; - class ArraySubscriptExprBitfields { + class ArrayOrMatrixSubscriptExprBitfields { friend class ArraySubscriptExpr; + friend class MatrixSubscriptExpr; unsigned : NumExprBits; @@ -529,8 +531,9 @@ protected: unsigned Opc : 6; /// This is only meaningful for operations on floating point - /// types and 0 otherwise. - unsigned FPFeatures : 3; + /// types when additional values need to be in trailing storage. + /// It is 0 otherwise. + unsigned HasFPFeatures : 1; SourceLocation OpLoc; }; @@ -588,6 +591,18 @@ protected: unsigned Kind : 2; }; + class StmtExprBitfields { + friend class ASTStmtReader; + friend class StmtExpr; + + unsigned : NumExprBits; + + /// The number of levels of template parameters enclosing this statement + /// expression. Used to determine if a statement expression remains + /// dependent after instantiation. + unsigned TemplateDepth; + }; + //===--- C++ Expression bitfields classes ---===// class CXXOperatorCallExprBitfields { @@ -599,9 +614,6 @@ protected: /// The kind of this overloaded operator. One of the enumerator /// value of OverloadedOperatorKind. unsigned OperatorKind : 6; - - // Only meaningful for floating point types. - unsigned FPFeatures : 3; }; class CXXRewrittenBinaryOperatorBitfields { @@ -760,8 +772,10 @@ protected: /// the trait evaluated true or false. unsigned Value : 1; - /// The number of arguments to this type trait. - unsigned NumArgs : 32 - 8 - 1 - NumExprBits; + /// The number of arguments to this type trait. According to [implimits] + /// 8 bits would be enough, but we require (and test for) at least 16 bits + /// to mirror FunctionType. + unsigned NumArgs; }; class DependentScopeDeclRefExprBitfields { @@ -910,6 +924,39 @@ protected: SourceLocation NameLoc; }; + class LambdaExprBitfields { + friend class ASTStmtReader; + friend class ASTStmtWriter; + friend class LambdaExpr; + + unsigned : NumExprBits; + + /// The default capture kind, which is a value of type + /// LambdaCaptureDefault. + unsigned CaptureDefault : 2; + + /// Whether this lambda had an explicit parameter list vs. an + /// implicit (and empty) parameter list. + unsigned ExplicitParams : 1; + + /// Whether this lambda had the result type explicitly specified. + unsigned ExplicitResultType : 1; + + /// The number of captures. + unsigned NumCaptures : 16; + }; + + class RequiresExprBitfields { + friend class ASTStmtReader; + friend class ASTStmtWriter; + friend class RequiresExpr; + + unsigned : NumExprBits; + + unsigned IsSatisfied : 1; + SourceLocation RequiresKWLoc; + }; + //===--- C++ Coroutines TS bitfields classes ---===// class CoawaitExprBitfields { @@ -974,7 +1021,7 @@ protected: CharacterLiteralBitfields CharacterLiteralBits; UnaryOperatorBitfields UnaryOperatorBits; UnaryExprOrTypeTraitExprBitfields UnaryExprOrTypeTraitExprBits; - ArraySubscriptExprBitfields ArraySubscriptExprBits; + ArrayOrMatrixSubscriptExprBitfields ArrayOrMatrixSubscriptExprBits; CallExprBitfields CallExprBits; MemberExprBitfields MemberExprBits; CastExprBitfields CastExprBits; @@ -985,6 +1032,9 @@ protected: PseudoObjectExprBitfields PseudoObjectExprBits; SourceLocExprBitfields SourceLocExprBits; + // GNU Extensions. + StmtExprBitfields StmtExprBits; + // C++ Expressions CXXOperatorCallExprBitfields CXXOperatorCallExprBits; CXXRewrittenBinaryOperatorBitfields CXXRewrittenBinaryOperatorBits; @@ -1008,6 +1058,8 @@ protected: UnresolvedMemberExprBitfields UnresolvedMemberExprBits; CXXNoexceptExprBitfields CXXNoexceptExprBits; SubstNonTypeTemplateParmExprBitfields SubstNonTypeTemplateParmExprBits; + LambdaExprBitfields LambdaExprBits; + RequiresExprBitfields RequiresExprBits; // C++ Coroutines TS expressions CoawaitExprBitfields CoawaitBits; @@ -1090,7 +1142,6 @@ public: static_assert(sizeof(*this) % alignof(void *) == 0, "Insufficient alignment!"); StmtBits.sClass = SC; - StmtBits.IsOMPStructuredBlock = false; if (StatisticsEnabled) Stmt::addStmtClass(SC); } @@ -1100,11 +1151,6 @@ public: const char *getStmtClassName() const; - bool isOMPStructuredBlock() const { return StmtBits.IsOMPStructuredBlock; } - void setIsOMPStructuredBlock(bool IsOMPStructuredBlock) { - StmtBits.IsOMPStructuredBlock = IsOMPStructuredBlock; - } - /// SourceLocation tokens are not useful in isolation - they are low level /// value objects created/interpreted by SourceManager. We assume AST /// clients will have a pointer to the respective SourceManager. @@ -1120,9 +1166,7 @@ public: /// Dumps the specified AST fragment and all subtrees to /// \c llvm::errs(). void dump() const; - void dump(SourceManager &SM) const; - void dump(raw_ostream &OS, SourceManager &SM) const; - void dump(raw_ostream &OS) const; + void dump(raw_ostream &OS, const ASTContext &Context) const; /// \return Unique reproducible object identifier int64_t getID(const ASTContext &Context) const; @@ -2233,6 +2277,8 @@ class WhileStmt final : public Stmt, enum { VarOffset = 0, BodyOffsetFromCond = 1 }; enum { NumMandatoryStmtPtr = 2 }; + SourceLocation LParenLoc, RParenLoc; + unsigned varOffset() const { return VarOffset; } unsigned condOffset() const { return VarOffset + hasVarStorage(); } unsigned bodyOffset() const { return condOffset() + BodyOffsetFromCond; } @@ -2243,7 +2289,8 @@ class WhileStmt final : public Stmt, /// Build a while statement. WhileStmt(const ASTContext &Ctx, VarDecl *Var, Expr *Cond, Stmt *Body, - SourceLocation WL); + SourceLocation WL, SourceLocation LParenLoc, + SourceLocation RParenLoc); /// Build an empty while statement. explicit WhileStmt(EmptyShell Empty, bool HasVar); @@ -2251,7 +2298,8 @@ class WhileStmt final : public Stmt, public: /// Create a while statement. static WhileStmt *Create(const ASTContext &Ctx, VarDecl *Var, Expr *Cond, - Stmt *Body, SourceLocation WL); + Stmt *Body, SourceLocation WL, + SourceLocation LParenLoc, SourceLocation RParenLoc); /// Create an empty while statement optionally with storage for /// a condition variable. @@ -2315,6 +2363,11 @@ public: SourceLocation getWhileLoc() const { return WhileStmtBits.WhileLoc; } void setWhileLoc(SourceLocation L) { WhileStmtBits.WhileLoc = L; } + SourceLocation getLParenLoc() const { return LParenLoc; } + void setLParenLoc(SourceLocation L) { LParenLoc = L; } + SourceLocation getRParenLoc() const { return RParenLoc; } + void setRParenLoc(SourceLocation L) { RParenLoc = L; } + SourceLocation getBeginLoc() const { return getWhileLoc(); } SourceLocation getEndLoc() const LLVM_READONLY { return getBody()->getEndLoc(); @@ -3017,7 +3070,7 @@ public: } IdentifierInfo *getLabelIdentifier(unsigned i) const { - return Names[i + NumInputs]; + return Names[i + NumOutputs + NumInputs]; } AddrLabelExpr *getLabelExpr(unsigned i) const; @@ -3028,11 +3081,11 @@ public: using labels_const_range = llvm::iterator_range<const_labels_iterator>; labels_iterator begin_labels() { - return &Exprs[0] + NumInputs; + return &Exprs[0] + NumOutputs + NumInputs; } labels_iterator end_labels() { - return &Exprs[0] + NumInputs + NumLabels; + return &Exprs[0] + NumOutputs + NumInputs + NumLabels; } labels_range labels() { @@ -3040,11 +3093,11 @@ public: } const_labels_iterator begin_labels() const { - return &Exprs[0] + NumInputs; + return &Exprs[0] + NumOutputs + NumInputs; } const_labels_iterator end_labels() const { - return &Exprs[0] + NumInputs + NumLabels; + return &Exprs[0] + NumOutputs + NumInputs + NumLabels; } labels_const_range labels() const { diff --git a/clang/include/clang/AST/StmtOpenMP.h b/clang/include/clang/AST/StmtOpenMP.h index 65f0afece224..bd87eafc9034 100644 --- a/clang/include/clang/AST/StmtOpenMP.h +++ b/clang/include/clang/AST/StmtOpenMP.h @@ -356,6 +356,9 @@ public: /// class OMPParallelDirective : public OMPExecutableDirective { friend class ASTStmtReader; + /// Special reference expression for handling task reduction. Used to store + /// the taskgroup descriptor returned by the runtime functions. + Expr *TaskRedRef = nullptr; /// true if the construct has inner cancel directive. bool HasCancel; @@ -381,6 +384,9 @@ class OMPParallelDirective : public OMPExecutableDirective { SourceLocation(), NumClauses, 1), HasCancel(false) {} + /// Sets special task reduction descriptor. + void setTaskReductionRefExpr(Expr *E) { TaskRedRef = E; } + /// Set cancel state. void setHasCancel(bool Has) { HasCancel = Has; } @@ -392,11 +398,14 @@ public: /// \param EndLoc Ending Location of the directive. /// \param Clauses List of clauses. /// \param AssociatedStmt Statement associated with the directive. + /// \param TaskRedRef Task reduction special reference expression to handle + /// taskgroup descriptor. /// \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, bool HasCancel); + ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef, + bool HasCancel); /// Creates an empty directive with the place for \a N clauses. /// @@ -406,6 +415,10 @@ public: static OMPParallelDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell); + /// Returns special task reduction reference expression. + Expr *getTaskReductionRefExpr() { return TaskRedRef; } + const Expr *getTaskReductionRefExpr() const { return TaskRedRef; } + /// Return true if current directive has inner cancel directive. bool hasCancel() const { return HasCancel; } @@ -1258,7 +1271,9 @@ public: /// class OMPForDirective : public OMPLoopDirective { friend class ASTStmtReader; - + /// Special reference expression for handling task reduction. Used to store + /// the taskgroup descriptor returned by the runtime functions. + Expr *TaskRedRef = nullptr; /// true if current directive has inner cancel directive. bool HasCancel; @@ -1286,6 +1301,9 @@ class OMPForDirective : public OMPLoopDirective { NumClauses), HasCancel(false) {} + /// Sets special task reduction descriptor. + void setTaskReductionRefExpr(Expr *E) { TaskRedRef = E; } + /// Set cancel state. void setHasCancel(bool Has) { HasCancel = Has; } @@ -1299,13 +1317,15 @@ public: /// \param Clauses List of clauses. /// \param AssociatedStmt Statement, associated with the directive. /// \param Exprs Helper expressions for CodeGen. + /// \param TaskRedRef Task reduction special reference expression to handle + /// taskgroup descriptor. /// \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, - bool HasCancel); + Expr *TaskRedRef, bool HasCancel); /// Creates an empty directive with the place /// for \a NumClauses clauses. @@ -1317,6 +1337,10 @@ public: static OMPForDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, EmptyShell); + /// Returns special task reduction reference expression. + Expr *getTaskReductionRefExpr() { return TaskRedRef; } + const Expr *getTaskReductionRefExpr() const { return TaskRedRef; } + /// Return true if current directive has inner cancel directive. bool hasCancel() const { return HasCancel; } @@ -1403,6 +1427,9 @@ public: class OMPSectionsDirective : public OMPExecutableDirective { friend class ASTStmtReader; + /// Special reference expression for handling task reduction. Used to store + /// the taskgroup descriptor returned by the runtime functions. + Expr *TaskRedRef = nullptr; /// true if current directive has inner cancel directive. bool HasCancel; @@ -1429,6 +1456,9 @@ class OMPSectionsDirective : public OMPExecutableDirective { SourceLocation(), NumClauses, 1), HasCancel(false) {} + /// Sets special task reduction descriptor. + void setTaskReductionRefExpr(Expr *E) { TaskRedRef = E; } + /// Set cancel state. void setHasCancel(bool Has) { HasCancel = Has; } @@ -1440,11 +1470,14 @@ public: /// \param EndLoc Ending Location of the directive. /// \param Clauses List of clauses. /// \param AssociatedStmt Statement, associated with the directive. + /// \param TaskRedRef Task reduction special reference expression to handle + /// taskgroup descriptor. /// \param HasCancel true if current directive has inner directive. /// static OMPSectionsDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, - ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, bool HasCancel); + ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef, + bool HasCancel); /// Creates an empty directive with the place for \a NumClauses /// clauses. @@ -1455,6 +1488,10 @@ public: static OMPSectionsDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell); + /// Returns special task reduction reference expression. + Expr *getTaskReductionRefExpr() { return TaskRedRef; } + const Expr *getTaskReductionRefExpr() const { return TaskRedRef; } + /// Return true if current directive has inner cancel directive. bool hasCancel() const { return HasCancel; } @@ -1715,6 +1752,9 @@ public: class OMPParallelForDirective : public OMPLoopDirective { friend class ASTStmtReader; + /// Special reference expression for handling task reduction. Used to store + /// the taskgroup descriptor returned by the runtime functions. + Expr *TaskRedRef = nullptr; /// true if current region has inner cancel directive. bool HasCancel; @@ -1743,6 +1783,9 @@ class OMPParallelForDirective : public OMPLoopDirective { SourceLocation(), CollapsedNum, NumClauses), HasCancel(false) {} + /// Sets special task reduction descriptor. + void setTaskReductionRefExpr(Expr *E) { TaskRedRef = E; } + /// Set cancel state. void setHasCancel(bool Has) { HasCancel = Has; } @@ -1756,12 +1799,15 @@ public: /// \param Clauses List of clauses. /// \param AssociatedStmt Statement, associated with the directive. /// \param Exprs Helper expressions for CodeGen. + /// \param TaskRedRef Task reduction special reference expression to handle + /// taskgroup descriptor. /// \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, bool HasCancel); + Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef, + bool HasCancel); /// Creates an empty directive with the place /// for \a NumClauses clauses. @@ -1775,6 +1821,10 @@ public: unsigned CollapsedNum, EmptyShell); + /// Returns special task reduction reference expression. + Expr *getTaskReductionRefExpr() { return TaskRedRef; } + const Expr *getTaskReductionRefExpr() const { return TaskRedRef; } + /// Return true if current directive has inner cancel directive. bool hasCancel() const { return HasCancel; } @@ -1863,6 +1913,10 @@ public: class OMPParallelMasterDirective : public OMPExecutableDirective { friend class ASTStmtReader; + /// Special reference expression for handling task reduction. Used to store + /// the taskgroup descriptor returned by the runtime functions. + Expr *TaskRedRef = nullptr; + OMPParallelMasterDirective(SourceLocation StartLoc, SourceLocation EndLoc, unsigned NumClauses) : OMPExecutableDirective(this, OMPParallelMasterDirectiveClass, @@ -1875,6 +1929,9 @@ class OMPParallelMasterDirective : public OMPExecutableDirective { SourceLocation(), SourceLocation(), NumClauses, 1) {} + /// Sets special task reduction descriptor. + void setTaskReductionRefExpr(Expr *E) { TaskRedRef = E; } + public: /// Creates directive with a list of \a Clauses. /// @@ -1883,10 +1940,12 @@ public: /// \param EndLoc Ending Location of the directive. /// \param Clauses List of clauses. /// \param AssociatedStmt Statement, associated with the directive. + /// \param TaskRedRef Task reduction special reference expression to handle + /// taskgroup descriptor. /// static OMPParallelMasterDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, - ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); + ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef); /// Creates an empty directive with the place for \a NumClauses /// clauses. @@ -1897,6 +1956,10 @@ public: static OMPParallelMasterDirective * CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell); + /// Returns special task reduction reference expression. + Expr *getTaskReductionRefExpr() { return TaskRedRef; } + const Expr *getTaskReductionRefExpr() const { return TaskRedRef; } + static bool classof(const Stmt *T) { return T->getStmtClass() == OMPParallelMasterDirectiveClass; } @@ -1914,6 +1977,9 @@ public: class OMPParallelSectionsDirective : public OMPExecutableDirective { friend class ASTStmtReader; + /// Special reference expression for handling task reduction. Used to store + /// the taskgroup descriptor returned by the runtime functions. + Expr *TaskRedRef = nullptr; /// true if current directive has inner cancel directive. bool HasCancel; @@ -1941,6 +2007,9 @@ class OMPParallelSectionsDirective : public OMPExecutableDirective { 1), HasCancel(false) {} + /// Sets special task reduction descriptor. + void setTaskReductionRefExpr(Expr *E) { TaskRedRef = E; } + /// Set cancel state. void setHasCancel(bool Has) { HasCancel = Has; } @@ -1952,11 +2021,14 @@ public: /// \param EndLoc Ending Location of the directive. /// \param Clauses List of clauses. /// \param AssociatedStmt Statement, associated with the directive. + /// \param TaskRedRef Task reduction special reference expression to handle + /// taskgroup descriptor. /// \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, bool HasCancel); + ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef, + bool HasCancel); /// Creates an empty directive with the place for \a NumClauses /// clauses. @@ -1967,6 +2039,10 @@ public: static OMPParallelSectionsDirective * CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell); + /// Returns special task reduction reference expression. + Expr *getTaskReductionRefExpr() { return TaskRedRef; } + const Expr *getTaskReductionRefExpr() const { return TaskRedRef; } + /// Return true if current directive has inner cancel directive. bool hasCancel() const { return HasCancel; } @@ -2314,6 +2390,64 @@ public: } }; +/// This represents '#pragma omp depobj' directive. +/// +/// \code +/// #pragma omp depobj(a) depend(in:x,y) +/// \endcode +/// In this example directive '#pragma omp depobj' initializes a depobj object +/// 'a' with dependence type 'in' and a list with 'x' and 'y' locators. +class OMPDepobjDirective final : public OMPExecutableDirective { + friend class ASTStmtReader; + + /// Build directive with the given start and end location. + /// + /// \param StartLoc Starting location of the directive kind. + /// \param EndLoc Ending location of the directive. + /// \param NumClauses Number of clauses. + /// + OMPDepobjDirective(SourceLocation StartLoc, SourceLocation EndLoc, + unsigned NumClauses) + : OMPExecutableDirective(this, OMPDepobjDirectiveClass, + llvm::omp::OMPD_depobj, StartLoc, EndLoc, + NumClauses, 0) {} + + /// Build an empty directive. + /// + /// \param NumClauses Number of clauses. + /// + explicit OMPDepobjDirective(unsigned NumClauses) + : OMPExecutableDirective(this, OMPDepobjDirectiveClass, + llvm::omp::OMPD_depobj, SourceLocation(), + SourceLocation(), NumClauses, 0) {} + +public: + /// Creates directive with a list of \a Clauses. + /// + /// \param C AST context. + /// \param StartLoc Starting location of the directive kind. + /// \param EndLoc Ending Location of the directive. + /// \param Clauses List of clauses. + /// + static OMPDepobjDirective *Create(const ASTContext &C, + SourceLocation StartLoc, + SourceLocation EndLoc, + ArrayRef<OMPClause *> Clauses); + + /// Creates an empty directive with the place for \a NumClauses + /// clauses. + /// + /// \param C AST context. + /// \param NumClauses Number of clauses. + /// + static OMPDepobjDirective *CreateEmpty(const ASTContext &C, + unsigned NumClauses, EmptyShell); + + static bool classof(const Stmt *T) { + return T->getStmtClass() == OMPDepobjDirectiveClass; + } +}; + /// This represents '#pragma omp ordered' directive. /// /// \code @@ -2747,6 +2881,12 @@ public: /// class OMPTargetParallelDirective : public OMPExecutableDirective { friend class ASTStmtReader; + /// Special reference expression for handling task reduction. Used to store + /// the taskgroup descriptor returned by the runtime functions. + Expr *TaskRedRef = nullptr; + /// true if the construct has inner cancel directive. + bool HasCancel = false; + /// Build directive with the given start and end location. /// /// \param StartLoc Starting location of the directive kind. @@ -2769,6 +2909,11 @@ class OMPTargetParallelDirective : public OMPExecutableDirective { SourceLocation(), SourceLocation(), NumClauses, /*NumChildren=*/1) {} + /// Sets special task reduction descriptor. + void setTaskReductionRefExpr(Expr *E) { TaskRedRef = E; } + /// Set cancel state. + void setHasCancel(bool Has) { HasCancel = Has; } + public: /// Creates directive with a list of \a Clauses. /// @@ -2777,10 +2922,14 @@ public: /// \param EndLoc Ending Location of the directive. /// \param Clauses List of clauses. /// \param AssociatedStmt Statement, associated with the directive. + /// \param TaskRedRef Task reduction special reference expression to handle + /// taskgroup descriptor. + /// \param HasCancel true if this directive has inner cancel directive. /// static OMPTargetParallelDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, - ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); + ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef, + bool HasCancel); /// Creates an empty directive with the place for \a NumClauses /// clauses. @@ -2791,6 +2940,13 @@ public: static OMPTargetParallelDirective * CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell); + /// Returns special task reduction reference expression. + Expr *getTaskReductionRefExpr() { return TaskRedRef; } + const Expr *getTaskReductionRefExpr() const { return TaskRedRef; } + + /// Return true if current directive has inner cancel directive. + bool hasCancel() const { return HasCancel; } + static bool classof(const Stmt *T) { return T->getStmtClass() == OMPTargetParallelDirectiveClass; } @@ -2808,6 +2964,9 @@ public: class OMPTargetParallelForDirective : public OMPLoopDirective { friend class ASTStmtReader; + /// Special reference expression for handling task reduction. Used to store + /// the taskgroup descriptor returned by the runtime functions. + Expr *TaskRedRef = nullptr; /// true if current region has inner cancel directive. bool HasCancel; @@ -2837,6 +2996,9 @@ class OMPTargetParallelForDirective : public OMPLoopDirective { SourceLocation(), CollapsedNum, NumClauses), HasCancel(false) {} + /// Sets special task reduction descriptor. + void setTaskReductionRefExpr(Expr *E) { TaskRedRef = E; } + /// Set cancel state. void setHasCancel(bool Has) { HasCancel = Has; } @@ -2850,12 +3012,15 @@ public: /// \param Clauses List of clauses. /// \param AssociatedStmt Statement, associated with the directive. /// \param Exprs Helper expressions for CodeGen. + /// \param TaskRedRef Task reduction special reference expression to handle + /// taskgroup descriptor. /// \param HasCancel true if current directive has inner cancel directive. /// static OMPTargetParallelForDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, - Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel); + Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef, + bool HasCancel); /// Creates an empty directive with the place /// for \a NumClauses clauses. @@ -2869,6 +3034,10 @@ public: unsigned CollapsedNum, EmptyShell); + /// Returns special task reduction reference expression. + Expr *getTaskReductionRefExpr() { return TaskRedRef; } + const Expr *getTaskReductionRefExpr() const { return TaskRedRef; } + /// Return true if current directive has inner cancel directive. bool hasCancel() const { return HasCancel; } @@ -3070,6 +3239,9 @@ public: /// class OMPTaskLoopDirective : public OMPLoopDirective { friend class ASTStmtReader; + /// true if the construct has inner cancel directive. + bool HasCancel; + /// Build directive with the given start and end location. /// /// \param StartLoc Starting location of the directive kind. @@ -3081,7 +3253,8 @@ class OMPTaskLoopDirective : public OMPLoopDirective { unsigned CollapsedNum, unsigned NumClauses) : OMPLoopDirective(this, OMPTaskLoopDirectiveClass, llvm::omp::OMPD_taskloop, StartLoc, EndLoc, - CollapsedNum, NumClauses) {} + CollapsedNum, NumClauses), + HasCancel(false) {} /// Build an empty directive. /// @@ -3091,7 +3264,11 @@ class OMPTaskLoopDirective : public OMPLoopDirective { explicit OMPTaskLoopDirective(unsigned CollapsedNum, unsigned NumClauses) : OMPLoopDirective(this, OMPTaskLoopDirectiveClass, llvm::omp::OMPD_taskloop, SourceLocation(), - SourceLocation(), CollapsedNum, NumClauses) {} + SourceLocation(), CollapsedNum, NumClauses), + HasCancel(false) {} + + /// Set cancel state. + void setHasCancel(bool Has) { HasCancel = Has; } public: /// Creates directive with a list of \a Clauses. @@ -3103,11 +3280,12 @@ public: /// \param Clauses List of clauses. /// \param AssociatedStmt Statement, associated with the directive. /// \param Exprs Helper expressions for CodeGen. + /// \param HasCancel true if this directive has inner cancel directive. /// static OMPTaskLoopDirective * 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); /// Creates an empty directive with the place /// for \a NumClauses clauses. @@ -3120,6 +3298,9 @@ public: unsigned NumClauses, unsigned CollapsedNum, EmptyShell); + /// Return true if current directive has inner cancel directive. + bool hasCancel() const { return HasCancel; } + static bool classof(const Stmt *T) { return T->getStmtClass() == OMPTaskLoopDirectiveClass; } @@ -3203,6 +3384,9 @@ public: /// class OMPMasterTaskLoopDirective : public OMPLoopDirective { friend class ASTStmtReader; + /// true if the construct has inner cancel directive. + bool HasCancel; + /// Build directive with the given start and end location. /// /// \param StartLoc Starting location of the directive kind. @@ -3214,7 +3398,8 @@ class OMPMasterTaskLoopDirective : public OMPLoopDirective { unsigned CollapsedNum, unsigned NumClauses) : OMPLoopDirective(this, OMPMasterTaskLoopDirectiveClass, llvm::omp::OMPD_master_taskloop, StartLoc, EndLoc, - CollapsedNum, NumClauses) {} + CollapsedNum, NumClauses), + HasCancel(false) {} /// Build an empty directive. /// @@ -3225,7 +3410,11 @@ class OMPMasterTaskLoopDirective : public OMPLoopDirective { unsigned NumClauses) : OMPLoopDirective(this, OMPMasterTaskLoopDirectiveClass, llvm::omp::OMPD_master_taskloop, SourceLocation(), - SourceLocation(), CollapsedNum, NumClauses) {} + SourceLocation(), CollapsedNum, NumClauses), + HasCancel(false) {} + + /// Set cancel state. + void setHasCancel(bool Has) { HasCancel = Has; } public: /// Creates directive with a list of \a Clauses. @@ -3237,11 +3426,12 @@ public: /// \param Clauses List of clauses. /// \param AssociatedStmt Statement, associated with the directive. /// \param Exprs Helper expressions for CodeGen. + /// \param HasCancel true if this directive has inner cancel directive. /// static OMPMasterTaskLoopDirective * 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); /// Creates an empty directive with the place /// for \a NumClauses clauses. @@ -3255,6 +3445,9 @@ public: unsigned CollapsedNum, EmptyShell); + /// Return true if current directive has inner cancel directive. + bool hasCancel() const { return HasCancel; } + static bool classof(const Stmt *T) { return T->getStmtClass() == OMPMasterTaskLoopDirectiveClass; } @@ -3339,6 +3532,9 @@ public: /// class OMPParallelMasterTaskLoopDirective : public OMPLoopDirective { friend class ASTStmtReader; + /// true if the construct has inner cancel directive. + bool HasCancel; + /// Build directive with the given start and end location. /// /// \param StartLoc Starting location of the directive kind. @@ -3351,7 +3547,8 @@ class OMPParallelMasterTaskLoopDirective : public OMPLoopDirective { unsigned CollapsedNum, unsigned NumClauses) : OMPLoopDirective(this, OMPParallelMasterTaskLoopDirectiveClass, llvm::omp::OMPD_parallel_master_taskloop, StartLoc, - EndLoc, CollapsedNum, NumClauses) {} + EndLoc, CollapsedNum, NumClauses), + HasCancel(false) {} /// Build an empty directive. /// @@ -3363,7 +3560,11 @@ class OMPParallelMasterTaskLoopDirective : public OMPLoopDirective { : OMPLoopDirective(this, OMPParallelMasterTaskLoopDirectiveClass, llvm::omp::OMPD_parallel_master_taskloop, SourceLocation(), SourceLocation(), CollapsedNum, - NumClauses) {} + NumClauses), + HasCancel(false) {} + + /// Set cancel state. + void setHasCancel(bool Has) { HasCancel = Has; } public: /// Creates directive with a list of \a Clauses. @@ -3375,11 +3576,12 @@ public: /// \param Clauses List of clauses. /// \param AssociatedStmt Statement, associated with the directive. /// \param Exprs Helper expressions for CodeGen. + /// \param HasCancel true if this directive has inner cancel directive. /// static OMPParallelMasterTaskLoopDirective * 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); /// Creates an empty directive with the place /// for \a NumClauses clauses. @@ -3393,6 +3595,9 @@ public: unsigned CollapsedNum, EmptyShell); + /// Return true if current directive has inner cancel directive. + bool hasCancel() const { return HasCancel; } + static bool classof(const Stmt *T) { return T->getStmtClass() == OMPParallelMasterTaskLoopDirectiveClass; } @@ -3605,6 +3810,9 @@ public: /// class OMPDistributeParallelForDirective : public OMPLoopDirective { friend class ASTStmtReader; + /// Special reference expression for handling task reduction. Used to store + /// the taskgroup descriptor returned by the runtime functions. + Expr *TaskRedRef = nullptr; /// true if the construct has inner cancel directive. bool HasCancel = false; @@ -3636,6 +3844,9 @@ class OMPDistributeParallelForDirective : public OMPLoopDirective { NumClauses), HasCancel(false) {} + /// Sets special task reduction descriptor. + void setTaskReductionRefExpr(Expr *E) { TaskRedRef = E; } + /// Set cancel state. void setHasCancel(bool Has) { HasCancel = Has; } @@ -3649,12 +3860,15 @@ public: /// \param Clauses List of clauses. /// \param AssociatedStmt Statement, associated with the directive. /// \param Exprs Helper expressions for CodeGen. + /// \param TaskRedRef Task reduction special reference expression to handle + /// taskgroup descriptor. /// \param HasCancel true if this directive has inner cancel directive. /// static OMPDistributeParallelForDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, - Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel); + Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef, + bool HasCancel); /// Creates an empty directive with the place /// for \a NumClauses clauses. @@ -3668,6 +3882,10 @@ public: unsigned CollapsedNum, EmptyShell); + /// Returns special task reduction reference expression. + Expr *getTaskReductionRefExpr() { return TaskRedRef; } + const Expr *getTaskReductionRefExpr() const { return TaskRedRef; } + /// Return true if current directive has inner cancel directive. bool hasCancel() const { return HasCancel; } @@ -4170,6 +4388,9 @@ public: /// class OMPTeamsDistributeParallelForDirective final : public OMPLoopDirective { friend class ASTStmtReader; + /// Special reference expression for handling task reduction. Used to store + /// the taskgroup descriptor returned by the runtime functions. + Expr *TaskRedRef = nullptr; /// true if the construct has inner cancel directive. bool HasCancel = false; @@ -4202,6 +4423,9 @@ class OMPTeamsDistributeParallelForDirective final : public OMPLoopDirective { NumClauses), HasCancel(false) {} + /// Sets special task reduction descriptor. + void setTaskReductionRefExpr(Expr *E) { TaskRedRef = E; } + /// Set cancel state. void setHasCancel(bool Has) { HasCancel = Has; } @@ -4215,12 +4439,15 @@ public: /// \param Clauses List of clauses. /// \param AssociatedStmt Statement, associated with the directive. /// \param Exprs Helper expressions for CodeGen. + /// \param TaskRedRef Task reduction special reference expression to handle + /// taskgroup descriptor. /// \param HasCancel true if this directive has inner cancel directive. /// static OMPTeamsDistributeParallelForDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, - Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel); + Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef, + bool HasCancel); /// Creates an empty directive with the place for \a NumClauses clauses. /// @@ -4232,6 +4459,10 @@ public: CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, EmptyShell); + /// Returns special task reduction reference expression. + Expr *getTaskReductionRefExpr() { return TaskRedRef; } + const Expr *getTaskReductionRefExpr() const { return TaskRedRef; } + /// Return true if current directive has inner cancel directive. bool hasCancel() const { return HasCancel; } @@ -4379,6 +4610,9 @@ public: class OMPTargetTeamsDistributeParallelForDirective final : public OMPLoopDirective { friend class ASTStmtReader; + /// Special reference expression for handling task reduction. Used to store + /// the taskgroup descriptor returned by the runtime functions. + Expr *TaskRedRef = nullptr; /// true if the construct has inner cancel directive. bool HasCancel = false; @@ -4412,6 +4646,9 @@ class OMPTargetTeamsDistributeParallelForDirective final SourceLocation(), SourceLocation(), CollapsedNum, NumClauses), HasCancel(false) {} + /// Sets special task reduction descriptor. + void setTaskReductionRefExpr(Expr *E) { TaskRedRef = E; } + /// Set cancel state. void setHasCancel(bool Has) { HasCancel = Has; } @@ -4425,12 +4662,15 @@ public: /// \param Clauses List of clauses. /// \param AssociatedStmt Statement, associated with the directive. /// \param Exprs Helper expressions for CodeGen. + /// \param TaskRedRef Task reduction special reference expression to handle + /// taskgroup descriptor. /// \param HasCancel true if this directive has inner cancel directive. /// static OMPTargetTeamsDistributeParallelForDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, - Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel); + Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef, + bool HasCancel); /// Creates an empty directive with the place for \a NumClauses clauses. /// @@ -4442,6 +4682,10 @@ public: CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, EmptyShell); + /// Returns special task reduction reference expression. + Expr *getTaskReductionRefExpr() { return TaskRedRef; } + const Expr *getTaskReductionRefExpr() const { return TaskRedRef; } + /// Return true if current directive has inner cancel directive. bool hasCancel() const { return HasCancel; } @@ -4594,6 +4838,63 @@ public: } }; +/// This represents '#pragma omp scan' directive. +/// +/// \code +/// #pragma omp scan inclusive(a) +/// \endcode +/// In this example directive '#pragma omp scan' has clause 'inclusive' with +/// list item 'a'. +class OMPScanDirective final : public OMPExecutableDirective { + friend class ASTStmtReader; + /// Build directive with the given start and end location. + /// + /// \param StartLoc Starting location of the directive kind. + /// \param EndLoc Ending location of the directive. + /// \param NumClauses Number of clauses. + /// + OMPScanDirective(SourceLocation StartLoc, SourceLocation EndLoc, + unsigned NumClauses) + : OMPExecutableDirective(this, OMPScanDirectiveClass, + llvm::omp::OMPD_scan, StartLoc, EndLoc, + NumClauses, 0) {} + + /// Build an empty directive. + /// + /// \param NumClauses Number of clauses. + /// + explicit OMPScanDirective(unsigned NumClauses) + : OMPExecutableDirective(this, OMPScanDirectiveClass, + llvm::omp::OMPD_scan, SourceLocation(), + SourceLocation(), NumClauses, 0) {} + +public: + /// Creates directive with a list of \a Clauses. + /// + /// \param C AST context. + /// \param StartLoc Starting location of the directive kind. + /// \param EndLoc Ending Location of the directive. + /// \param Clauses List of clauses (only single OMPFlushClause clause is + /// allowed). + /// + static OMPScanDirective *Create(const ASTContext &C, SourceLocation StartLoc, + SourceLocation EndLoc, + ArrayRef<OMPClause *> Clauses); + + /// Creates an empty directive with the place for \a NumClauses + /// clauses. + /// + /// \param C AST context. + /// \param NumClauses Number of clauses. + /// + static OMPScanDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses, + EmptyShell); + + static bool classof(const Stmt *T) { + return T->getStmtClass() == OMPScanDirectiveClass; + } +}; + } // end namespace clang #endif diff --git a/clang/include/clang/AST/StmtVisitor.h b/clang/include/clang/AST/StmtVisitor.h index d3be93d228cc..3e5155199eac 100644 --- a/clang/include/clang/AST/StmtVisitor.h +++ b/clang/include/clang/AST/StmtVisitor.h @@ -13,6 +13,7 @@ #ifndef LLVM_CLANG_AST_STMTVISITOR_H #define LLVM_CLANG_AST_STMTVISITOR_H +#include "clang/AST/ExprConcepts.h" #include "clang/AST/ExprCXX.h" #include "clang/AST/ExprObjC.h" #include "clang/AST/ExprOpenMP.h" diff --git a/clang/include/clang/AST/TemplateBase.h b/clang/include/clang/AST/TemplateBase.h index 058a5bc0a067..51fd8ba51034 100644 --- a/clang/include/clang/AST/TemplateBase.h +++ b/clang/include/clang/AST/TemplateBase.h @@ -14,6 +14,7 @@ #ifndef LLVM_CLANG_AST_TEMPLATEBASE_H #define LLVM_CLANG_AST_TEMPLATEBASE_H +#include "clang/AST/DependenceFlags.h" #include "clang/AST/NestedNameSpecifier.h" #include "clang/AST/TemplateName.h" #include "clang/AST/Type.h" @@ -81,8 +82,7 @@ public: /// The template argument is an expression, and we've not resolved it to one /// of the other forms yet, either because it's dependent or because we're /// representing a non-canonical template argument (for instance, in a - /// TemplateSpecializationType). Also used to represent a non-dependent - /// __uuidof expression (a Microsoft extension). + /// TemplateSpecializationType). Expression, /// The template argument is actually a parameter pack. Arguments are stored @@ -236,6 +236,8 @@ public: /// Determine whether this template argument has no value. bool isNull() const { return getKind() == Null; } + TemplateArgumentDependence getDependence() const; + /// Whether this template argument is dependent on a template /// parameter such that its result can change from one instantiation to /// another. @@ -637,7 +639,7 @@ public: } static const ASTTemplateArgumentListInfo * - Create(ASTContext &C, const TemplateArgumentListInfo &List); + Create(const ASTContext &C, const TemplateArgumentListInfo &List); }; /// Represents an explicit template argument list in C++, e.g., @@ -666,11 +668,13 @@ struct alignas(void *) ASTTemplateKWAndArgsInfo { void initializeFrom(SourceLocation TemplateKWLoc, const TemplateArgumentListInfo &List, TemplateArgumentLoc *OutArgArray); + // FIXME: The parameter Deps is the result populated by this method, the + // caller doesn't need it since it is populated by computeDependence. remove + // it. void initializeFrom(SourceLocation TemplateKWLoc, const TemplateArgumentListInfo &List, - TemplateArgumentLoc *OutArgArray, bool &Dependent, - bool &InstantiationDependent, - bool &ContainsUnexpandedParameterPack); + TemplateArgumentLoc *OutArgArray, + TemplateArgumentDependence &Deps); void initializeFrom(SourceLocation TemplateKWLoc); void copyInto(const TemplateArgumentLoc *ArgArray, @@ -702,6 +706,11 @@ inline const TemplateArgument & return getArgs()[Idx]; } +inline const TemplateArgument &AutoType::getArg(unsigned Idx) const { + assert(Idx < getNumArgs() && "Template argument out of range"); + return getArgs()[Idx]; +} + } // namespace clang #endif // LLVM_CLANG_AST_TEMPLATEBASE_H diff --git a/clang/include/clang/AST/TemplateName.h b/clang/include/clang/AST/TemplateName.h index cbbcbf6af8ab..9bcf2838dcf1 100644 --- a/clang/include/clang/AST/TemplateName.h +++ b/clang/include/clang/AST/TemplateName.h @@ -13,6 +13,7 @@ #ifndef LLVM_CLANG_AST_TEMPLATENAME_H #define LLVM_CLANG_AST_TEMPLATENAME_H +#include "clang/AST/DependenceFlags.h" #include "clang/AST/NestedNameSpecifier.h" #include "clang/Basic/LLVM.h" #include "llvm/ADT/FoldingSet.h" @@ -295,6 +296,8 @@ public: /// the template, including any default template arguments. TemplateName getNameToSubstitute() const; + TemplateNameDependence getDependence() const; + /// Determines whether this is a dependent template name. bool isDependent() const; @@ -559,7 +562,7 @@ struct PointerLikeTypeTraits<clang::TemplateName> { } // No bits are available! - enum { NumLowBitsAvailable = 0 }; + static constexpr int NumLowBitsAvailable = 0; }; } // namespace llvm. diff --git a/clang/include/clang/AST/TextNodeDumper.h b/clang/include/clang/AST/TextNodeDumper.h index d293ea190aa4..b4cfb5a380d1 100644 --- a/clang/include/clang/AST/TextNodeDumper.h +++ b/clang/include/clang/AST/TextNodeDumper.h @@ -22,10 +22,13 @@ #include "clang/AST/ExprCXX.h" #include "clang/AST/StmtVisitor.h" #include "clang/AST/TemplateArgumentVisitor.h" +#include "clang/AST/Type.h" #include "clang/AST/TypeVisitor.h" namespace clang { +class APValue; + class TextTreeStructure { raw_ostream &OS; const bool ShowColors; @@ -68,7 +71,7 @@ public: // We need to capture an owning-string in the lambda because the lambda // is invoked in a deferred manner. - std::string LabelStr = Label; + std::string LabelStr(Label); auto DumpWithIndent = [this, DoAddChild, LabelStr](bool IsLastChild) { // Print out the appropriate tree structure and work out the prefix for // children of this node. For instance: @@ -139,19 +142,29 @@ class TextNodeDumper const char *LastLocFilename = ""; unsigned LastLocLine = ~0U; - const SourceManager *SM; + /// \p Context, \p SM, and \p Traits can be null. This is because we want + /// to be able to call \p dump() in a debugger without having to pass the + /// \p ASTContext to \p dump. Not all parts of the AST dump output will be + /// available without the \p ASTContext. + const ASTContext *Context = nullptr; + const SourceManager *SM = nullptr; /// The policy to use for printing; can be defaulted. - PrintingPolicy PrintPolicy; + PrintingPolicy PrintPolicy = LangOptions(); - const comments::CommandTraits *Traits; + const comments::CommandTraits *Traits = nullptr; const char *getCommandName(unsigned CommandID); + void dumpAPValueChildren(const APValue &Value, QualType Ty, + const APValue &(*IdxToChildFun)(const APValue &, + unsigned), + unsigned NumChildren, StringRef LabelSingular, + StringRef LabelPlurial); + public: - TextNodeDumper(raw_ostream &OS, bool ShowColors, const SourceManager *SM, - const PrintingPolicy &PrintPolicy, - const comments::CommandTraits *Traits); + TextNodeDumper(raw_ostream &OS, const ASTContext &Context, bool ShowColors); + TextNodeDumper(raw_ostream &OS, bool ShowColors); void Visit(const comments::Comment *C, const comments::FullComment *FC); @@ -176,6 +189,8 @@ public: void Visit(const GenericSelectionExpr::ConstAssociation &A); + void Visit(const APValue &Value, QualType Ty); + void dumpPointer(const void *Ptr); void dumpLocation(SourceLocation Loc); void dumpSourceRange(SourceRange R); @@ -184,6 +199,7 @@ public: void dumpBareDeclRef(const Decl *D); void dumpName(const NamedDecl *ND); void dumpAccessSpecifier(AccessSpecifier AS); + void dumpCleanupObject(const ExprWithCleanups::CleanupObject &C); void dumpDeclRef(const Decl *D, StringRef Label = {}); @@ -230,6 +246,7 @@ public: void VisitCaseStmt(const CaseStmt *Node); void VisitConstantExpr(const ConstantExpr *Node); void VisitCallExpr(const CallExpr *Node); + void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *Node); void VisitCastExpr(const CastExpr *Node); void VisitImplicitCastExpr(const ImplicitCastExpr *Node); void VisitDeclRefExpr(const DeclRefExpr *Node); @@ -257,6 +274,9 @@ public: void VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *Node); void VisitCXXNewExpr(const CXXNewExpr *Node); void VisitCXXDeleteExpr(const CXXDeleteExpr *Node); + void VisitTypeTraitExpr(const TypeTraitExpr *Node); + void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *Node); + void VisitExpressionTraitExpr(const ExpressionTraitExpr *Node); void VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *Node); void VisitExprWithCleanups(const ExprWithCleanups *Node); void VisitUnresolvedLookupExpr(const UnresolvedLookupExpr *Node); @@ -273,6 +293,7 @@ public: void VisitObjCSubscriptRefExpr(const ObjCSubscriptRefExpr *Node); void VisitObjCIvarRefExpr(const ObjCIvarRefExpr *Node); void VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *Node); + void VisitOMPIteratorExpr(const OMPIteratorExpr *Node); void VisitRValueReferenceType(const ReferenceType *T); void VisitArrayType(const ArrayType *T); diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h index f5955c45fafc..0fc50e0e799f 100644 --- a/clang/include/clang/AST/Type.h +++ b/clang/include/clang/AST/Type.h @@ -17,6 +17,7 @@ #ifndef LLVM_CLANG_AST_TYPE_H #define LLVM_CLANG_AST_TYPE_H +#include "clang/AST/DependenceFlags.h" #include "clang/AST/NestedNameSpecifier.h" #include "clang/AST/TemplateName.h" #include "clang/Basic/AddressSpaces.h" @@ -44,8 +45,8 @@ #include "llvm/Support/Compiler.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/PointerLikeTypeTraits.h" -#include "llvm/Support/type_traits.h" #include "llvm/Support/TrailingObjects.h" +#include "llvm/Support/type_traits.h" #include <cassert> #include <cstddef> #include <cstdint> @@ -58,6 +59,7 @@ namespace clang { class ExtQuals; class QualType; +class ConceptDecl; class TagDecl; class Type; @@ -85,7 +87,7 @@ namespace llvm { return static_cast< ::clang::Type*>(P); } - enum { NumLowBitsAvailable = clang::TypeAlignmentInBits }; + static constexpr int NumLowBitsAvailable = clang::TypeAlignmentInBits; }; template<> @@ -96,7 +98,7 @@ namespace llvm { return static_cast< ::clang::ExtQuals*>(P); } - enum { NumLowBitsAvailable = clang::TypeAlignmentInBits }; + static constexpr int NumLowBitsAvailable = clang::TypeAlignmentInBits; }; } // namespace llvm @@ -942,6 +944,12 @@ public: /// from non-class types (in C++) or all types (in C). QualType getNonLValueExprType(const ASTContext &Context) const; + /// Remove an outer pack expansion type (if any) from this type. Used as part + /// of converting the type of a declaration to the type of an expression that + /// references that expression. It's meaningless for an expression to have a + /// pack expansion type. + QualType getNonPackExpansionType() const; + /// 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 @@ -1050,7 +1058,7 @@ public: void dump(const char *s) const; void dump() const; - void dump(llvm::raw_ostream &OS) const; + void dump(llvm::raw_ostream &OS, const ASTContext &Context) const; void Profile(llvm::FoldingSetNodeID &ID) const { ID.AddPointer(getAsOpaquePtr()); @@ -1062,6 +1070,21 @@ public: /// Return the address space of this type. inline LangAS getAddressSpace() const; + /// Returns true if address space qualifiers overlap with T address space + /// qualifiers. + /// OpenCL C defines conversion rules for pointers to different address spaces + /// and notion of overlapping address spaces. + /// CL1.1 or CL1.2: + /// address spaces overlap iff they are they same. + /// OpenCL C v2.0 s6.5.5 adds: + /// __generic overlaps with any address space except for __constant. + bool isAddressSpaceOverlapping(QualType T) const { + Qualifiers Q = getQualifiers(); + Qualifiers TQ = T.getQualifiers(); + // Address spaces overlap if at least one of them is a superset of another + return Q.isAddressSpaceSupersetOf(TQ) || TQ.isAddressSpaceSupersetOf(Q); + } + /// Returns gc attribute of this type. inline Qualifiers::GC getObjCGCAttr() const; @@ -1295,7 +1318,7 @@ struct PointerLikeTypeTraits<clang::QualType> { } // Various qualifiers go in low bits. - enum { NumLowBitsAvailable = 0 }; + static constexpr int NumLowBitsAvailable = 0; }; } // namespace llvm @@ -1464,19 +1487,8 @@ private: /// TypeClass bitfield - Enum that specifies what subclass this belongs to. unsigned TC : 8; - /// Whether this type is a dependent type (C++ [temp.dep.type]). - unsigned Dependent : 1; - - /// 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; - - /// Whether this type is a variably-modified type (C99 6.7.5). - unsigned VariablyModified : 1; - - /// Whether this type contains an unexpanded parameter pack - /// (for C++11 variadic templates). - unsigned ContainsUnexpandedParameterPack : 1; + /// Store information on the type dependency. + unsigned Dependence : llvm::BitWidth<TypeDependence>; /// True if the cache (i.e. the bitfields here starting with /// 'Cache') is valid. @@ -1505,7 +1517,7 @@ private: return CachedLocalOrUnnamed; } }; - enum { NumTypeBits = 18 }; + enum { NumTypeBits = 8 + llvm::BitWidth<TypeDependence> + 6 }; protected: // These classes allow subclasses to somewhat cleanly pack bitfields @@ -1555,7 +1567,7 @@ protected: /// Extra information which affects how the function is called, like /// regparm and the calling convention. - unsigned ExtInfo : 12; + unsigned ExtInfo : 13; /// The ref-qualifier associated with a \c FunctionProtoType. /// @@ -1659,11 +1671,21 @@ protected: /// The kind of vector, either a generic vector type or some /// target-specific vector type such as for AltiVec or Neon. unsigned VecKind : 3; - /// The number of elements in the vector. - unsigned NumElements : 29 - NumTypeBits; + uint32_t NumElements; + }; + + class ConstantMatrixTypeBitfields { + friend class ConstantMatrixType; + + unsigned : NumTypeBits; - enum { MaxNumElements = (1 << (29 - NumTypeBits)) - 1 }; + /// Number of rows and columns. Using 20 bits allows supporting very large + /// matrixes, while keeping 24 bits to accommodate NumTypeBits. + unsigned NumRows : 20; + unsigned NumColumns : 20; + + static constexpr uint32_t MaxElementsPerDimension = (1 << 20) - 1; }; class AttributedTypeBitfields { @@ -1683,6 +1705,15 @@ protected: /// Was this placeholder type spelled as 'auto', 'decltype(auto)', /// or '__auto_type'? AutoTypeKeyword value. unsigned Keyword : 2; + + /// The number of template arguments in the type-constraints, which is + /// expected to be able to hold at least 1024 according to [implimits]. + /// However as this limit is somewhat easy to hit with template + /// metaprogramming we'd prefer to keep it as large as possible. + /// At the moment it has been left as a non-bitfield since this type + /// safely fits in 64 bits as an unsigned, so there is no reason to + /// introduce the performance impact of a bitfield. + unsigned NumArgs; }; class SubstTemplateTypeParmPackTypeBitfields { @@ -1766,6 +1797,7 @@ protected: TypeWithKeywordBitfields TypeWithKeywordBits; ElaboratedTypeBitfields ElaboratedTypeBits; VectorTypeBitfields VectorTypeBits; + ConstantMatrixTypeBitfields ConstantMatrixTypeBits; SubstTemplateTypeParmPackTypeBitfields SubstTemplateTypeParmPackTypeBits; TemplateSpecializationTypeBitfields TemplateSpecializationTypeBits; DependentTemplateSpecializationTypeBitfields @@ -1818,16 +1850,11 @@ private: protected: friend class ASTContext; - Type(TypeClass tc, QualType canon, bool Dependent, - bool InstantiationDependent, bool VariablyModified, - bool ContainsUnexpandedParameterPack) + Type(TypeClass tc, QualType canon, TypeDependence Dependence) : ExtQualsTypeCommonBase(this, canon.isNull() ? QualType(this_(), 0) : canon) { TypeBits.TC = tc; - TypeBits.Dependent = Dependent; - TypeBits.InstantiationDependent = Dependent || InstantiationDependent; - TypeBits.VariablyModified = VariablyModified; - TypeBits.ContainsUnexpandedParameterPack = ContainsUnexpandedParameterPack; + TypeBits.Dependence = static_cast<unsigned>(Dependence); TypeBits.CacheValid = false; TypeBits.CachedLocalOrUnnamed = false; TypeBits.CachedLinkage = NoLinkage; @@ -1837,20 +1864,11 @@ protected: // silence VC++ warning C4355: 'this' : used in base member initializer list Type *this_() { return this; } - void setDependent(bool D = true) { - TypeBits.Dependent = D; - if (D) - TypeBits.InstantiationDependent = true; + void setDependence(TypeDependence D) { + TypeBits.Dependence = static_cast<unsigned>(D); } - void setInstantiationDependent(bool D = true) { - TypeBits.InstantiationDependent = D; } - - void setVariablyModified(bool VM = true) { TypeBits.VariablyModified = VM; } - - void setContainsUnexpandedParameterPack(bool PP = true) { - TypeBits.ContainsUnexpandedParameterPack = PP; - } + void addDependence(TypeDependence D) { setDependence(getDependence() | D); } public: friend class ASTReader; @@ -1884,7 +1902,7 @@ public: /// /// Note that this routine does not specify which bool containsUnexpandedParameterPack() const { - return TypeBits.ContainsUnexpandedParameterPack; + return getDependence() & TypeDependence::UnexpandedPack; } /// Determines if this type would be canonical if it had no further @@ -1898,6 +1916,15 @@ public: /// or QualType::getSingleStepDesugaredType(const ASTContext&). QualType getLocallyUnqualifiedSingleStepDesugaredType() const; + /// As an extension, we classify types as one of "sized" or "sizeless"; + /// every type is one or the other. Standard types are all sized; + /// sizeless types are purely an extension. + /// + /// Sizeless types contain data with no specified size, alignment, + /// or layout. + bool isSizelessType() const; + bool isSizelessBuiltinType() const; + /// Types are partitioned into 3 broad categories (C99 6.2.5p1): /// object types, function types, and incomplete types. @@ -1987,6 +2014,7 @@ public: bool isFloatingType() const; // C99 6.2.5p11 (real floating + complex) bool isHalfType() const; // OpenCL 6.1.1.1, NEON (IEEE 754-2008 half) bool isFloat16Type() const; // C11 extension ISO/IEC TS 18661 + bool isBFloat16Type() const; bool isFloat128Type() const; bool isRealType() const; // C99 6.2.5p17 (real floating + integer) bool isArithmeticType() const; // C99 6.2.5p18 (integer + floating) @@ -2029,6 +2057,8 @@ public: bool isComplexIntegerType() const; // GCC _Complex integer type. bool isVectorType() const; // GCC vector type. bool isExtVectorType() const; // Extended vector type. + bool isMatrixType() const; // Matrix type. + bool isConstantMatrixType() const; // Constant matrix type. bool isDependentAddressSpaceType() const; // value-dependent address space qualifier bool isObjCObjectPointerType() const; // pointer to ObjC object bool isObjCRetainableType() const; // ObjC object or block pointer @@ -2109,6 +2139,7 @@ public: bool isOCLExtOpaqueType() const; // Any OpenCL extension type bool isPipeType() const; // OpenCL pipe type + bool isExtIntType() const; // Extended Int Type bool isOpenCLSpecificType() const; // Any OpenCL specific type /// Determines if this type, which must satisfy @@ -2116,6 +2147,11 @@ public: /// than implicitly __strong. bool isObjCARCImplicitlyUnretainedType() const; + /// Check if the type is the CUDA device builtin surface type. + bool isCUDADeviceBuiltinSurfaceType() const; + /// Check if the type is the CUDA device builtin texture type. + bool isCUDADeviceBuiltinTextureType() const; + /// Return the implicit lifetime for this type, which must not be dependent. Qualifiers::ObjCLifetime getObjCARCImplicitLifetime() const; @@ -2135,16 +2171,27 @@ public: /// Given that this is a scalar type, classify it. ScalarTypeKind getScalarTypeKind() const; + TypeDependence getDependence() const { + return static_cast<TypeDependence>(TypeBits.Dependence); + } + + /// Whether this type is an error type. + bool containsErrors() const { + return getDependence() & TypeDependence::Error; + } + /// 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; } + bool isDependentType() const { + return getDependence() & TypeDependence::Dependent; + } /// Determine whether this type is an instantiation-dependent type, /// meaning that the type involves a template parameter (even if the /// definition does not actually depend on the type substituted for that /// template parameter). bool isInstantiationDependentType() const { - return TypeBits.InstantiationDependent; + return getDependence() & TypeDependence::Instantiation; } /// Determine whether this type is an undeduced type, meaning that @@ -2153,7 +2200,9 @@ public: bool isUndeducedType() const; /// Whether this type is a variably-modified type (C99 6.7.5). - bool isVariablyModifiedType() const { return TypeBits.VariablyModified; } + bool isVariablyModifiedType() const { + return getDependence() & TypeDependence::VariablyModified; + } /// Whether this type involves a variable-length array type /// with a definite size. @@ -2422,7 +2471,7 @@ public: CanQualType getCanonicalTypeUnqualified() const; // in CanonicalType.h void dump() const; - void dump(llvm::raw_ostream &OS) const; + void dump(llvm::raw_ostream &OS, const ASTContext &Context) const; }; /// This will check for a TypedefType by removing any existing sugar @@ -2474,10 +2523,9 @@ private: friend class ASTContext; // ASTContext creates these. BuiltinType(Kind K) - : Type(Builtin, QualType(), /*Dependent=*/(K == Dependent), - /*InstantiationDependent=*/(K == Dependent), - /*VariablyModified=*/false, - /*Unexpanded parameter pack=*/false) { + : Type(Builtin, QualType(), + K == Dependent ? TypeDependence::DependentInstantiation + : TypeDependence::None) { BuiltinTypeBits.Kind = K; } @@ -2547,10 +2595,7 @@ class ComplexType : public Type, public llvm::FoldingSetNode { QualType ElementType; ComplexType(QualType Element, QualType CanonicalPtr) - : Type(Complex, CanonicalPtr, Element->isDependentType(), - Element->isInstantiationDependentType(), - Element->isVariablyModifiedType(), - Element->containsUnexpandedParameterPack()), + : Type(Complex, CanonicalPtr, Element->getDependence()), ElementType(Element) {} public: @@ -2577,11 +2622,7 @@ class ParenType : public Type, public llvm::FoldingSetNode { QualType Inner; ParenType(QualType InnerType, QualType CanonType) - : Type(Paren, CanonType, InnerType->isDependentType(), - InnerType->isInstantiationDependentType(), - InnerType->isVariablyModifiedType(), - InnerType->containsUnexpandedParameterPack()), - Inner(InnerType) {} + : Type(Paren, CanonType, InnerType->getDependence()), Inner(InnerType) {} public: QualType getInnerType() const { return Inner; } @@ -2607,31 +2648,12 @@ class PointerType : public Type, public llvm::FoldingSetNode { QualType PointeeType; PointerType(QualType Pointee, QualType CanonicalPtr) - : Type(Pointer, CanonicalPtr, Pointee->isDependentType(), - Pointee->isInstantiationDependentType(), - Pointee->isVariablyModifiedType(), - Pointee->containsUnexpandedParameterPack()), + : Type(Pointer, CanonicalPtr, Pointee->getDependence()), PointeeType(Pointee) {} public: QualType getPointeeType() const { return PointeeType; } - /// 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. - /// CL1.1 or CL1.2: - /// address spaces overlap iff they are they same. - /// CL2.0 adds: - /// __generic overlaps with any address space except for __constant. - bool isAddressSpaceOverlapping(const PointerType &other) const { - Qualifiers thisQuals = PointeeType.getQualifiers(); - Qualifiers otherQuals = other.getPointeeType().getQualifiers(); - // Address spaces overlap if at least one of them is a superset of another - return thisQuals.isAddressSpaceSupersetOf(otherQuals) || - otherQuals.isAddressSpaceSupersetOf(thisQuals); - } - bool isSugared() const { return false; } QualType desugar() const { return QualType(this, 0); } @@ -2658,10 +2680,7 @@ protected: AdjustedType(TypeClass TC, QualType OriginalTy, QualType AdjustedTy, QualType CanonicalPtr) - : Type(TC, CanonicalPtr, OriginalTy->isDependentType(), - OriginalTy->isInstantiationDependentType(), - OriginalTy->isVariablyModifiedType(), - OriginalTy->containsUnexpandedParameterPack()), + : Type(TC, CanonicalPtr, OriginalTy->getDependence()), OriginalTy(OriginalTy), AdjustedTy(AdjustedTy) {} public: @@ -2710,10 +2729,7 @@ class BlockPointerType : public Type, public llvm::FoldingSetNode { QualType PointeeType; BlockPointerType(QualType Pointee, QualType CanonicalCls) - : Type(BlockPointer, CanonicalCls, Pointee->isDependentType(), - Pointee->isInstantiationDependentType(), - Pointee->isVariablyModifiedType(), - Pointee->containsUnexpandedParameterPack()), + : Type(BlockPointer, CanonicalCls, Pointee->getDependence()), PointeeType(Pointee) {} public: @@ -2743,10 +2759,7 @@ class ReferenceType : public Type, public llvm::FoldingSetNode { protected: ReferenceType(TypeClass tc, QualType Referencee, QualType CanonicalRef, bool SpelledAsLValue) - : Type(tc, CanonicalRef, Referencee->isDependentType(), - Referencee->isInstantiationDependentType(), - Referencee->isVariablyModifiedType(), - Referencee->containsUnexpandedParameterPack()), + : Type(tc, CanonicalRef, Referencee->getDependence()), PointeeType(Referencee) { ReferenceTypeBits.SpelledAsLValue = SpelledAsLValue; ReferenceTypeBits.InnerRef = Referencee->isReferenceType(); @@ -2831,13 +2844,9 @@ class MemberPointerType : public Type, public llvm::FoldingSetNode { MemberPointerType(QualType Pointee, const Type *Cls, QualType CanonicalPtr) : Type(MemberPointer, CanonicalPtr, - Cls->isDependentType() || Pointee->isDependentType(), - (Cls->isInstantiationDependentType() || - Pointee->isInstantiationDependentType()), - Pointee->isVariablyModifiedType(), - (Cls->containsUnexpandedParameterPack() || - Pointee->containsUnexpandedParameterPack())), - PointeeType(Pointee), Class(Cls) {} + (Cls->getDependence() & ~TypeDependence::VariablyModified) | + Pointee->getDependence()), + PointeeType(Pointee), Class(Cls) {} public: QualType getPointeeType() const { return PointeeType; } @@ -3260,10 +3269,6 @@ public: QualType getElementType() const { return ElementType; } unsigned getNumElements() const { return VectorTypeBits.NumElements; } - static bool isVectorSizeTooLarge(unsigned NumElements) { - return NumElements > VectorTypeBitfields::MaxNumElements; - } - bool isSugared() const { return false; } QualType desugar() const { return QualType(this, 0); } @@ -3407,6 +3412,136 @@ public: } }; +/// Represents a matrix type, as defined in the Matrix Types clang extensions. +/// __attribute__((matrix_type(rows, columns))), where "rows" specifies +/// number of rows and "columns" specifies the number of columns. +class MatrixType : public Type, public llvm::FoldingSetNode { +protected: + friend class ASTContext; + + /// The element type of the matrix. + QualType ElementType; + + MatrixType(QualType ElementTy, QualType CanonElementTy); + + MatrixType(TypeClass TypeClass, QualType ElementTy, QualType CanonElementTy, + const Expr *RowExpr = nullptr, const Expr *ColumnExpr = nullptr); + +public: + /// Returns type of the elements being stored in the matrix + QualType getElementType() const { return ElementType; } + + /// Valid elements types are the following: + /// * an integer type (as in C2x 6.2.5p19), but excluding enumerated types + /// and _Bool + /// * the standard floating types float or double + /// * a half-precision floating point type, if one is supported on the target + static bool isValidElementType(QualType T) { + return T->isDependentType() || + (T->isRealType() && !T->isBooleanType() && !T->isEnumeralType()); + } + + bool isSugared() const { return false; } + QualType desugar() const { return QualType(this, 0); } + + static bool classof(const Type *T) { + return T->getTypeClass() == ConstantMatrix || + T->getTypeClass() == DependentSizedMatrix; + } +}; + +/// Represents a concrete matrix type with constant number of rows and columns +class ConstantMatrixType final : public MatrixType { +protected: + friend class ASTContext; + + /// The element type of the matrix. + QualType ElementType; + + ConstantMatrixType(QualType MatrixElementType, unsigned NRows, + unsigned NColumns, QualType CanonElementType); + + ConstantMatrixType(TypeClass typeClass, QualType MatrixType, unsigned NRows, + unsigned NColumns, QualType CanonElementType); + +public: + /// Returns the number of rows in the matrix. + unsigned getNumRows() const { return ConstantMatrixTypeBits.NumRows; } + + /// Returns the number of columns in the matrix. + unsigned getNumColumns() const { return ConstantMatrixTypeBits.NumColumns; } + + /// Returns the number of elements required to embed the matrix into a vector. + unsigned getNumElementsFlattened() const { + return ConstantMatrixTypeBits.NumRows * ConstantMatrixTypeBits.NumColumns; + } + + /// Returns true if \p NumElements is a valid matrix dimension. + static bool isDimensionValid(uint64_t NumElements) { + return NumElements > 0 && + NumElements <= ConstantMatrixTypeBitfields::MaxElementsPerDimension; + } + + /// Returns the maximum number of elements per dimension. + static unsigned getMaxElementsPerDimension() { + return ConstantMatrixTypeBitfields::MaxElementsPerDimension; + } + + void Profile(llvm::FoldingSetNodeID &ID) { + Profile(ID, getElementType(), getNumRows(), getNumColumns(), + getTypeClass()); + } + + static void Profile(llvm::FoldingSetNodeID &ID, QualType ElementType, + unsigned NumRows, unsigned NumColumns, + TypeClass TypeClass) { + ID.AddPointer(ElementType.getAsOpaquePtr()); + ID.AddInteger(NumRows); + ID.AddInteger(NumColumns); + ID.AddInteger(TypeClass); + } + + static bool classof(const Type *T) { + return T->getTypeClass() == ConstantMatrix; + } +}; + +/// Represents a matrix type where the type and the number of rows and columns +/// is dependent on a template. +class DependentSizedMatrixType final : public MatrixType { + friend class ASTContext; + + const ASTContext &Context; + Expr *RowExpr; + Expr *ColumnExpr; + + SourceLocation loc; + + DependentSizedMatrixType(const ASTContext &Context, QualType ElementType, + QualType CanonicalType, Expr *RowExpr, + Expr *ColumnExpr, SourceLocation loc); + +public: + QualType getElementType() const { return ElementType; } + Expr *getRowExpr() const { return RowExpr; } + Expr *getColumnExpr() const { return ColumnExpr; } + SourceLocation getAttributeLoc() const { return loc; } + + bool isSugared() const { return false; } + QualType desugar() const { return QualType(this, 0); } + + static bool classof(const Type *T) { + return T->getTypeClass() == DependentSizedMatrix; + } + + void Profile(llvm::FoldingSetNodeID &ID) { + Profile(ID, Context, getElementType(), getRowExpr(), getColumnExpr()); + } + + static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, + QualType ElementType, Expr *RowExpr, Expr *ColumnExpr); +}; + /// FunctionType - C99 6.7.5.3 - Function Declarators. This is the common base /// class of FunctionNoProtoType and FunctionProtoType. class FunctionType : public Type { @@ -3523,39 +3658,41 @@ public: class ExtInfo { friend class FunctionType; - // Feel free to rearrange or add bits, but if you go over 12, - // you'll need to adjust both the Bits field below and - // Type::FunctionTypeBitfields. + // Feel free to rearrange or add bits, but if you go over 16, you'll need to + // adjust the Bits field below, and if you add bits, you'll need to adjust + // Type::FunctionTypeBitfields::ExtInfo as well. - // | CC |noreturn|produces|nocallersavedregs|regparm|nocfcheck| - // |0 .. 4| 5 | 6 | 7 |8 .. 10| 11 | + // | CC |noreturn|produces|nocallersavedregs|regparm|nocfcheck|cmsenscall| + // |0 .. 4| 5 | 6 | 7 |8 .. 10| 11 | 12 | // // regparm is either 0 (no regparm attribute) or the regparm value+1. enum { CallConvMask = 0x1F }; enum { NoReturnMask = 0x20 }; enum { ProducesResultMask = 0x40 }; enum { NoCallerSavedRegsMask = 0x80 }; - enum { NoCfCheckMask = 0x800 }; enum { - RegParmMask = ~(CallConvMask | NoReturnMask | ProducesResultMask | - NoCallerSavedRegsMask | NoCfCheckMask), + RegParmMask = 0x700, RegParmOffset = 8 - }; // Assumed to be the last field + }; + enum { NoCfCheckMask = 0x800 }; + enum { CmseNSCallMask = 0x1000 }; uint16_t Bits = CC_C; ExtInfo(unsigned Bits) : Bits(static_cast<uint16_t>(Bits)) {} - public: - // Constructor with no defaults. Use this when you know that you - // have all the elements (when reading an AST file for example). - ExtInfo(bool noReturn, bool hasRegParm, unsigned regParm, CallingConv cc, - bool producesResult, bool noCallerSavedRegs, bool NoCfCheck) { - assert((!hasRegParm || regParm < 7) && "Invalid regparm value"); - Bits = ((unsigned)cc) | (noReturn ? NoReturnMask : 0) | - (producesResult ? ProducesResultMask : 0) | - (noCallerSavedRegs ? NoCallerSavedRegsMask : 0) | - (hasRegParm ? ((regParm + 1) << RegParmOffset) : 0) | - (NoCfCheck ? NoCfCheckMask : 0); + public: + // Constructor with no defaults. Use this when you know that you + // have all the elements (when reading an AST file for example). + ExtInfo(bool noReturn, bool hasRegParm, unsigned regParm, CallingConv cc, + bool producesResult, bool noCallerSavedRegs, bool NoCfCheck, + bool cmseNSCall) { + assert((!hasRegParm || regParm < 7) && "Invalid regparm value"); + Bits = ((unsigned)cc) | (noReturn ? NoReturnMask : 0) | + (producesResult ? ProducesResultMask : 0) | + (noCallerSavedRegs ? NoCallerSavedRegsMask : 0) | + (hasRegParm ? ((regParm + 1) << RegParmOffset) : 0) | + (NoCfCheck ? NoCfCheckMask : 0) | + (cmseNSCall ? CmseNSCallMask : 0); } // Constructor with all defaults. Use when for example creating a @@ -3568,9 +3705,10 @@ public: bool getNoReturn() const { return Bits & NoReturnMask; } bool getProducesResult() const { return Bits & ProducesResultMask; } + bool getCmseNSCall() const { return Bits & CmseNSCallMask; } bool getNoCallerSavedRegs() const { return Bits & NoCallerSavedRegsMask; } bool getNoCfCheck() const { return Bits & NoCfCheckMask; } - bool getHasRegParm() const { return (Bits >> RegParmOffset) != 0; } + bool getHasRegParm() const { return ((Bits & RegParmMask) >> RegParmOffset) != 0; } unsigned getRegParm() const { unsigned RegParm = (Bits & RegParmMask) >> RegParmOffset; @@ -3605,6 +3743,13 @@ public: return ExtInfo(Bits & ~ProducesResultMask); } + ExtInfo withCmseNSCall(bool cmseNSCall) const { + if (cmseNSCall) + return ExtInfo(Bits | CmseNSCallMask); + else + return ExtInfo(Bits & ~CmseNSCallMask); + } + ExtInfo withNoCallerSavedRegs(bool noCallerSavedRegs) const { if (noCallerSavedRegs) return ExtInfo(Bits | NoCallerSavedRegsMask); @@ -3651,14 +3796,9 @@ public: }; protected: - FunctionType(TypeClass tc, QualType res, - QualType Canonical, bool Dependent, - bool InstantiationDependent, - bool VariablyModified, bool ContainsUnexpandedParameterPack, - ExtInfo Info) - : Type(tc, Canonical, Dependent, InstantiationDependent, VariablyModified, - ContainsUnexpandedParameterPack), - ResultType(res) { + FunctionType(TypeClass tc, QualType res, QualType Canonical, + TypeDependence Dependence, ExtInfo Info) + : Type(tc, Canonical, Dependence), ResultType(res) { FunctionTypeBits.ExtInfo = Info.Bits; } @@ -3677,6 +3817,7 @@ public: /// type. bool getNoReturnAttr() const { return getExtInfo().getNoReturn(); } + bool getCmseNSCallAttr() const { return getExtInfo().getCmseNSCall(); } CallingConv getCallConv() const { return getExtInfo().getCC(); } ExtInfo getExtInfo() const { return ExtInfo(FunctionTypeBits.ExtInfo); } @@ -3709,9 +3850,10 @@ class FunctionNoProtoType : public FunctionType, public llvm::FoldingSetNode { FunctionNoProtoType(QualType Result, QualType Canonical, ExtInfo Info) : FunctionType(FunctionNoProto, Result, Canonical, - /*Dependent=*/false, /*InstantiationDependent=*/false, - Result->isVariablyModifiedType(), - /*ContainsUnexpandedParameterPack=*/false, Info) {} + Result->getDependence() & + ~(TypeDependence::DependentInstantiation | + TypeDependence::UnexpandedPack), + Info) {} public: // No additional state past what FunctionType provides. @@ -4203,9 +4345,9 @@ class UnresolvedUsingType : public Type { UnresolvedUsingTypenameDecl *Decl; UnresolvedUsingType(const UnresolvedUsingTypenameDecl *D) - : Type(UnresolvedUsing, QualType(), true, true, false, - /*ContainsUnexpandedParameterPack=*/false), - Decl(const_cast<UnresolvedUsingTypenameDecl*>(D)) {} + : Type(UnresolvedUsing, QualType(), + TypeDependence::DependentInstantiation), + Decl(const_cast<UnresolvedUsingTypenameDecl *>(D)) {} public: UnresolvedUsingTypenameDecl *getDecl() const { return Decl; } @@ -4234,11 +4376,8 @@ protected: friend class ASTContext; // ASTContext creates these. TypedefType(TypeClass tc, const TypedefNameDecl *D, QualType can) - : Type(tc, can, can->isDependentType(), - can->isInstantiationDependentType(), - can->isVariablyModifiedType(), - /*ContainsUnexpandedParameterPack=*/false), - Decl(const_cast<TypedefNameDecl*>(D)) { + : Type(tc, can, can->getDependence() & ~TypeDependence::UnexpandedPack), + Decl(const_cast<TypedefNameDecl *>(D)) { assert(!isa<TypedefType>(can) && "Invalid canonical type"); } @@ -4261,10 +4400,7 @@ class MacroQualifiedType : public Type { MacroQualifiedType(QualType UnderlyingTy, QualType CanonTy, const IdentifierInfo *MacroII) - : Type(MacroQualified, CanonTy, UnderlyingTy->isDependentType(), - UnderlyingTy->isInstantiationDependentType(), - UnderlyingTy->isVariablyModifiedType(), - UnderlyingTy->containsUnexpandedParameterPack()), + : Type(MacroQualified, CanonTy, UnderlyingTy->getDependence()), UnderlyingTy(UnderlyingTy), MacroII(MacroII) { assert(isa<AttributedType>(UnderlyingTy) && "Expected a macro qualified type to only wrap attributed types."); @@ -4336,11 +4472,7 @@ class TypeOfType : public Type { QualType TOType; TypeOfType(QualType T, QualType can) - : Type(TypeOf, can, T->isDependentType(), - T->isInstantiationDependentType(), - T->isVariablyModifiedType(), - T->containsUnexpandedParameterPack()), - TOType(T) { + : Type(TypeOf, can, T->getDependence()), TOType(T) { assert(!isa<TypedefType>(can) && "Invalid canonical type"); } @@ -4549,10 +4681,7 @@ private: AttributedType(QualType canon, attr::Kind attrKind, QualType modified, QualType equivalent) - : Type(Attributed, canon, equivalent->isDependentType(), - equivalent->isInstantiationDependentType(), - equivalent->isVariablyModifiedType(), - equivalent->containsUnexpandedParameterPack()), + : Type(Attributed, canon, equivalent->getDependence()), ModifiedType(modified), EquivalentType(equivalent) { AttributedTypeBits.AttrKind = attrKind; } @@ -4654,18 +4783,16 @@ class TemplateTypeParmType : public Type, public llvm::FoldingSetNode { /// Build a non-canonical type. TemplateTypeParmType(TemplateTypeParmDecl *TTPDecl, QualType Canon) - : Type(TemplateTypeParm, Canon, /*Dependent=*/true, - /*InstantiationDependent=*/true, - /*VariablyModified=*/false, - Canon->containsUnexpandedParameterPack()), + : Type(TemplateTypeParm, Canon, + TypeDependence::DependentInstantiation | + (Canon->getDependence() & TypeDependence::UnexpandedPack)), TTPDecl(TTPDecl) {} /// Build the canonical type. TemplateTypeParmType(unsigned D, unsigned I, bool PP) : Type(TemplateTypeParm, QualType(this, 0), - /*Dependent=*/true, - /*InstantiationDependent=*/true, - /*VariablyModified=*/false, PP) { + TypeDependence::DependentInstantiation | + (PP ? TypeDependence::UnexpandedPack : TypeDependence::None)) { CanTTPTInfo.Depth = D; CanTTPTInfo.Index = I; CanTTPTInfo.ParameterPack = PP; @@ -4722,10 +4849,7 @@ class SubstTemplateTypeParmType : public Type, public llvm::FoldingSetNode { const TemplateTypeParmType *Replaced; SubstTemplateTypeParmType(const TemplateTypeParmType *Param, QualType Canon) - : Type(SubstTemplateTypeParm, Canon, Canon->isDependentType(), - Canon->isInstantiationDependentType(), - Canon->isVariablyModifiedType(), - Canon->containsUnexpandedParameterPack()), + : Type(SubstTemplateTypeParm, Canon, Canon->getDependence()), Replaced(Param) {} public: @@ -4814,8 +4938,7 @@ public: /// Common base class for placeholders for types that get replaced by /// placeholder type deduction: C++11 auto, C++14 decltype(auto), C++17 deduced -/// class template types, and (eventually) constrained type names from the C++ -/// Concepts TS. +/// class template types, and constrained type names. /// /// These types are usually a placeholder for a deduced type. However, before /// the initializer is attached, or (usually) if the initializer is @@ -4823,23 +4946,16 @@ public: /// the latter case, it is also a dependent type. class DeducedType : public Type { protected: - DeducedType(TypeClass TC, QualType DeducedAsType, bool IsDependent, - bool IsInstantiationDependent, bool ContainsParameterPack) + DeducedType(TypeClass TC, QualType DeducedAsType, + TypeDependence ExtraDependence) : Type(TC, // FIXME: Retain the sugared deduced type? DeducedAsType.isNull() ? QualType(this, 0) : DeducedAsType.getCanonicalType(), - IsDependent, IsInstantiationDependent, - /*VariablyModified=*/false, ContainsParameterPack) { - if (!DeducedAsType.isNull()) { - if (DeducedAsType->isDependentType()) - setDependent(); - if (DeducedAsType->isInstantiationDependentType()) - setInstantiationDependent(); - if (DeducedAsType->containsUnexpandedParameterPack()) - setContainsUnexpandedParameterPack(); - } - } + ExtraDependence | (DeducedAsType.isNull() + ? TypeDependence::None + : DeducedAsType->getDependence() & + ~TypeDependence::VariablyModified)) {} public: bool isSugared() const { return !isCanonicalUnqualified(); } @@ -4860,18 +4976,50 @@ public: } }; -/// Represents a C++11 auto or C++14 decltype(auto) type. -class AutoType : public DeducedType, public llvm::FoldingSetNode { +/// Represents a C++11 auto or C++14 decltype(auto) type, possibly constrained +/// by a type-constraint. +class alignas(8) AutoType : public DeducedType, public llvm::FoldingSetNode { friend class ASTContext; // ASTContext creates these + ConceptDecl *TypeConstraintConcept; + AutoType(QualType DeducedAsType, AutoTypeKeyword Keyword, - bool IsDeducedAsDependent, bool IsDeducedAsPack) - : DeducedType(Auto, DeducedAsType, IsDeducedAsDependent, - IsDeducedAsDependent, IsDeducedAsPack) { - AutoTypeBits.Keyword = (unsigned)Keyword; + TypeDependence ExtraDependence, ConceptDecl *CD, + ArrayRef<TemplateArgument> TypeConstraintArgs); + + const TemplateArgument *getArgBuffer() const { + return reinterpret_cast<const TemplateArgument*>(this+1); + } + + TemplateArgument *getArgBuffer() { + return reinterpret_cast<TemplateArgument*>(this+1); } public: + /// Retrieve the template arguments. + const TemplateArgument *getArgs() const { + return getArgBuffer(); + } + + /// Retrieve the number of template arguments. + unsigned getNumArgs() const { + return AutoTypeBits.NumArgs; + } + + const TemplateArgument &getArg(unsigned Idx) const; // in TemplateBase.h + + ArrayRef<TemplateArgument> getTypeConstraintArguments() const { + return {getArgs(), getNumArgs()}; + } + + ConceptDecl *getTypeConstraintConcept() const { + return TypeConstraintConcept; + } + + bool isConstrained() const { + return TypeConstraintConcept != nullptr; + } + bool isDecltypeAuto() const { return getKeyword() == AutoTypeKeyword::DecltypeAuto; } @@ -4880,18 +5028,15 @@ public: return (AutoTypeKeyword)AutoTypeBits.Keyword; } - void Profile(llvm::FoldingSetNodeID &ID) { - Profile(ID, getDeducedType(), getKeyword(), isDependentType(), - containsUnexpandedParameterPack()); + void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) { + Profile(ID, Context, getDeducedType(), getKeyword(), isDependentType(), + getTypeConstraintConcept(), getTypeConstraintArguments()); } - static void Profile(llvm::FoldingSetNodeID &ID, QualType Deduced, - AutoTypeKeyword Keyword, bool IsDependent, bool IsPack) { - ID.AddPointer(Deduced.getAsOpaquePtr()); - ID.AddInteger((unsigned)Keyword); - ID.AddBoolean(IsDependent); - ID.AddBoolean(IsPack); - } + static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, + QualType Deduced, AutoTypeKeyword Keyword, + bool IsDependent, ConceptDecl *CD, + ArrayRef<TemplateArgument> Arguments); static bool classof(const Type *T) { return T->getTypeClass() == Auto; @@ -4910,9 +5055,10 @@ class DeducedTemplateSpecializationType : public DeducedType, QualType DeducedAsType, bool IsDeducedAsDependent) : DeducedType(DeducedTemplateSpecialization, DeducedAsType, - IsDeducedAsDependent || Template.isDependent(), - IsDeducedAsDependent || Template.isInstantiationDependent(), - Template.containsUnexpandedParameterPack()), + toTypeDependence(Template.getDependence()) | + (IsDeducedAsDependent + ? TypeDependence::DependentInstantiation + : TypeDependence::None)), Template(Template) {} public: @@ -5114,10 +5260,8 @@ class InjectedClassNameType : public Type { QualType InjectedType; InjectedClassNameType(CXXRecordDecl *D, QualType TST) - : Type(InjectedClassName, QualType(), /*Dependent=*/true, - /*InstantiationDependent=*/true, - /*VariablyModified=*/false, - /*ContainsUnexpandedParameterPack=*/false), + : Type(InjectedClassName, QualType(), + TypeDependence::DependentInstantiation), Decl(D), InjectedType(TST) { assert(isa<TemplateSpecializationType>(TST)); assert(!TST.hasQualifiers()); @@ -5196,11 +5340,8 @@ enum ElaboratedTypeKeyword { class TypeWithKeyword : public Type { protected: TypeWithKeyword(ElaboratedTypeKeyword Keyword, TypeClass tc, - QualType Canonical, bool Dependent, - bool InstantiationDependent, bool VariablyModified, - bool ContainsUnexpandedParameterPack) - : Type(tc, Canonical, Dependent, InstantiationDependent, VariablyModified, - ContainsUnexpandedParameterPack) { + QualType Canonical, TypeDependence Dependence) + : Type(tc, Canonical, Dependence) { TypeWithKeywordBits.Keyword = Keyword; } @@ -5264,10 +5405,7 @@ class ElaboratedType final ElaboratedType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS, QualType NamedType, QualType CanonType, TagDecl *OwnedTagDecl) : TypeWithKeyword(Keyword, Elaborated, CanonType, - NamedType->isDependentType(), - NamedType->isInstantiationDependentType(), - NamedType->isVariablyModifiedType(), - NamedType->containsUnexpandedParameterPack()), + NamedType->getDependence()), NNS(NNS), NamedType(NamedType) { ElaboratedTypeBits.HasOwnedTagDecl = false; if (OwnedTagDecl) { @@ -5338,10 +5476,9 @@ class DependentNameType : public TypeWithKeyword, public llvm::FoldingSetNode { DependentNameType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS, const IdentifierInfo *Name, QualType CanonType) - : TypeWithKeyword(Keyword, DependentName, CanonType, /*Dependent=*/true, - /*InstantiationDependent=*/true, - /*VariablyModified=*/false, - NNS->containsUnexpandedParameterPack()), + : TypeWithKeyword(Keyword, DependentName, CanonType, + TypeDependence::DependentInstantiation | + toTypeDependence(NNS->getDependence())), NNS(NNS), Name(Name) {} public: @@ -5478,10 +5615,9 @@ class PackExpansionType : public Type, public llvm::FoldingSetNode { PackExpansionType(QualType Pattern, QualType Canon, Optional<unsigned> NumExpansions) - : Type(PackExpansion, Canon, /*Dependent=*/Pattern->isDependentType(), - /*InstantiationDependent=*/true, - /*VariablyModified=*/Pattern->isVariablyModifiedType(), - /*ContainsUnexpandedParameterPack=*/false), + : Type(PackExpansion, Canon, + (Pattern->getDependence() | TypeDependence::Instantiation) & + ~TypeDependence::UnexpandedPack), Pattern(Pattern) { PackExpansionTypeBits.NumExpansions = NumExpansions ? *NumExpansions + 1 : 0; @@ -5620,6 +5756,7 @@ public: void Profile(llvm::FoldingSetNodeID &ID); static void Profile(llvm::FoldingSetNodeID &ID, const ObjCTypeParamDecl *OTPDecl, + QualType CanonicalType, ArrayRef<ObjCProtocolDecl *> protocols); ObjCTypeParamDecl *getDecl() const { return OTPDecl; } @@ -5700,8 +5837,8 @@ protected: bool isKindOf); ObjCObjectType(enum Nonce_ObjCInterface) - : Type(ObjCInterface, QualType(), false, false, false, false), - BaseType(QualType(this_(), 0)) { + : Type(ObjCInterface, QualType(), TypeDependence::None), + BaseType(QualType(this_(), 0)) { ObjCObjectTypeBits.NumProtocols = 0; ObjCObjectTypeBits.NumTypeArgs = 0; ObjCObjectTypeBits.IsKindOf = 0; @@ -5916,11 +6053,7 @@ class ObjCObjectPointerType : public Type, public llvm::FoldingSetNode { QualType PointeeType; ObjCObjectPointerType(QualType Canonical, QualType Pointee) - : Type(ObjCObjectPointer, Canonical, - Pointee->isDependentType(), - Pointee->isInstantiationDependentType(), - Pointee->isVariablyModifiedType(), - Pointee->containsUnexpandedParameterPack()), + : Type(ObjCObjectPointer, Canonical, Pointee->getDependence()), PointeeType(Pointee) {} public: @@ -6090,11 +6223,7 @@ class AtomicType : public Type, public llvm::FoldingSetNode { QualType ValueType; AtomicType(QualType ValTy, QualType Canonical) - : Type(Atomic, Canonical, ValTy->isDependentType(), - ValTy->isInstantiationDependentType(), - ValTy->isVariablyModifiedType(), - ValTy->containsUnexpandedParameterPack()), - ValueType(ValTy) {} + : Type(Atomic, Canonical, ValTy->getDependence()), ValueType(ValTy) {} public: /// Gets the type contained by this atomic type, i.e. @@ -6125,10 +6254,7 @@ class PipeType : public Type, public llvm::FoldingSetNode { bool isRead; PipeType(QualType elemType, QualType CanonicalPtr, bool isRead) - : Type(Pipe, CanonicalPtr, elemType->isDependentType(), - elemType->isInstantiationDependentType(), - elemType->isVariablyModifiedType(), - elemType->containsUnexpandedParameterPack()), + : Type(Pipe, CanonicalPtr, elemType->getDependence()), ElementType(elemType), isRead(isRead) {} public: @@ -6154,6 +6280,64 @@ public: bool isReadOnly() const { return isRead; } }; +/// A fixed int type of a specified bitwidth. +class ExtIntType final : public Type, public llvm::FoldingSetNode { + friend class ASTContext; + unsigned IsUnsigned : 1; + unsigned NumBits : 24; + +protected: + ExtIntType(bool isUnsigned, unsigned NumBits); + +public: + bool isUnsigned() const { return IsUnsigned; } + bool isSigned() const { return !IsUnsigned; } + unsigned getNumBits() const { return NumBits; } + + bool isSugared() const { return false; } + QualType desugar() const { return QualType(this, 0); } + + void Profile(llvm::FoldingSetNodeID &ID) { + Profile(ID, isUnsigned(), getNumBits()); + } + + static void Profile(llvm::FoldingSetNodeID &ID, bool IsUnsigned, + unsigned NumBits) { + ID.AddBoolean(IsUnsigned); + ID.AddInteger(NumBits); + } + + static bool classof(const Type *T) { return T->getTypeClass() == ExtInt; } +}; + +class DependentExtIntType final : public Type, public llvm::FoldingSetNode { + friend class ASTContext; + const ASTContext &Context; + llvm::PointerIntPair<Expr*, 1, bool> ExprAndUnsigned; + +protected: + DependentExtIntType(const ASTContext &Context, bool IsUnsigned, + Expr *NumBits); + +public: + bool isUnsigned() const; + bool isSigned() const { return !isUnsigned(); } + Expr *getNumBitsExpr() const; + + bool isSugared() const { return false; } + QualType desugar() const { return QualType(this, 0); } + + void Profile(llvm::FoldingSetNodeID &ID) { + Profile(ID, Context, isUnsigned(), getNumBitsExpr()); + } + static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, + bool IsUnsigned, Expr *NumBitsExpr); + + static bool classof(const Type *T) { + return T->getTypeClass() == DependentExtInt; + } +}; + /// A qualifier set is used to build a set of qualifiers. class QualifierCollector : public Qualifiers { public: @@ -6573,6 +6757,14 @@ inline bool Type::isExtVectorType() const { return isa<ExtVectorType>(CanonicalType); } +inline bool Type::isMatrixType() const { + return isa<MatrixType>(CanonicalType); +} + +inline bool Type::isConstantMatrixType() const { + return isa<ConstantMatrixType>(CanonicalType); +} + inline bool Type::isDependentAddressSpaceType() const { return isa<DependentAddressSpaceType>(CanonicalType); } @@ -6673,6 +6865,10 @@ inline bool Type::isPipeType() const { return isa<PipeType>(CanonicalType); } +inline bool Type::isExtIntType() const { + return isa<ExtIntType>(CanonicalType); +} + #define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \ inline bool Type::is##Id##Type() const { \ return isSpecificBuiltinType(BuiltinType::Id); \ @@ -6704,9 +6900,9 @@ inline bool Type::isTemplateTypeParmType() const { } inline bool Type::isSpecificBuiltinType(unsigned K) const { - if (const BuiltinType *BT = getAs<BuiltinType>()) - if (BT->getKind() == (BuiltinType::Kind) K) - return true; + if (const BuiltinType *BT = getAs<BuiltinType>()) { + return BT->getKind() == static_cast<BuiltinType::Kind>(K); + } return false; } @@ -6725,9 +6921,7 @@ inline const BuiltinType *Type::getAsPlaceholderType() const { inline bool Type::isSpecificPlaceholderType(unsigned K) const { assert(BuiltinType::isPlaceholderTypeKind((BuiltinType::Kind) K)); - if (const auto *BT = dyn_cast<BuiltinType>(this)) - return (BT->getKind() == (BuiltinType::Kind) K); - return false; + return isSpecificBuiltinType(K); } inline bool Type::isNonOverloadPlaceholderType() const { @@ -6737,34 +6931,28 @@ inline bool Type::isNonOverloadPlaceholderType() const { } inline bool Type::isVoidType() const { - if (const auto *BT = dyn_cast<BuiltinType>(CanonicalType)) - return BT->getKind() == BuiltinType::Void; - return false; + return isSpecificBuiltinType(BuiltinType::Void); } inline bool Type::isHalfType() const { - if (const auto *BT = dyn_cast<BuiltinType>(CanonicalType)) - return BT->getKind() == BuiltinType::Half; // FIXME: Should we allow complex __fp16? Probably not. - return false; + return isSpecificBuiltinType(BuiltinType::Half); } inline bool Type::isFloat16Type() const { - if (const auto *BT = dyn_cast<BuiltinType>(CanonicalType)) - return BT->getKind() == BuiltinType::Float16; - return false; + return isSpecificBuiltinType(BuiltinType::Float16); +} + +inline bool Type::isBFloat16Type() const { + return isSpecificBuiltinType(BuiltinType::BFloat16); } inline bool Type::isFloat128Type() const { - if (const auto *BT = dyn_cast<BuiltinType>(CanonicalType)) - return BT->getKind() == BuiltinType::Float128; - return false; + return isSpecificBuiltinType(BuiltinType::Float128); } inline bool Type::isNullPtrType() const { - if (const auto *BT = getAs<BuiltinType>()) - return BT->getKind() == BuiltinType::NullPtr; - return false; + return isSpecificBuiltinType(BuiltinType::NullPtr); } bool IsEnumDeclComplete(EnumDecl *); @@ -6780,7 +6968,7 @@ inline bool Type::isIntegerType() const { return IsEnumDeclComplete(ET->getDecl()) && !IsEnumDeclScoped(ET->getDecl()); } - return false; + return isExtIntType(); } inline bool Type::isFixedPointType() const { @@ -6837,7 +7025,8 @@ inline bool Type::isScalarType() const { isa<BlockPointerType>(CanonicalType) || isa<MemberPointerType>(CanonicalType) || isa<ComplexType>(CanonicalType) || - isa<ObjCObjectPointerType>(CanonicalType); + isa<ObjCObjectPointerType>(CanonicalType) || + isExtIntType(); } inline bool Type::isIntegralOrEnumerationType() const { @@ -6850,7 +7039,7 @@ inline bool Type::isIntegralOrEnumerationType() const { if (const auto *ET = dyn_cast<EnumType>(CanonicalType)) return IsEnumDeclComplete(ET->getDecl()); - return false; + return isExtIntType(); } inline bool Type::isBooleanType() const { diff --git a/clang/include/clang/AST/TypeLoc.h b/clang/include/clang/AST/TypeLoc.h index c3baaa3e4174..72cc8ef098e7 100644 --- a/clang/include/clang/AST/TypeLoc.h +++ b/clang/include/clang/AST/TypeLoc.h @@ -14,6 +14,7 @@ #ifndef LLVM_CLANG_AST_TYPELOC_H #define LLVM_CLANG_AST_TYPELOC_H +#include "clang/AST/DeclarationName.h" #include "clang/AST/NestedNameSpecifier.h" #include "clang/AST/TemplateBase.h" #include "clang/AST/Type.h" @@ -34,6 +35,7 @@ namespace clang { class Attr; class ASTContext; class CXXRecordDecl; +class ConceptDecl; class Expr; class ObjCInterfaceDecl; class ObjCProtocolDecl; @@ -181,6 +183,11 @@ public: /// AttributedTypeLoc, for those type attributes that behave as qualifiers TypeLoc findExplicitQualifierLoc() const; + /// Get the typeloc of an 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. + AutoTypeLoc getContainedAutoTypeLoc() const; + /// Initializes this to state that every location in this /// type is the given location. /// @@ -1728,6 +1735,7 @@ public: void initializeLocal(ASTContext &Context, SourceLocation loc) { setAttrNameLoc(loc); + setAttrOperandParensRange(loc); setAttrOperandParensRange(SourceRange(loc)); setAttrExprOperand(getTypePtr()->getAddrSpaceExpr()); } @@ -1767,6 +1775,68 @@ class DependentSizedExtVectorTypeLoc : DependentSizedExtVectorType> { }; +struct MatrixTypeLocInfo { + SourceLocation AttrLoc; + SourceRange OperandParens; + Expr *RowOperand; + Expr *ColumnOperand; +}; + +class MatrixTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, MatrixTypeLoc, + MatrixType, MatrixTypeLocInfo> { +public: + /// The location of the attribute name, i.e. + /// float __attribute__((matrix_type(4, 2))) + /// ^~~~~~~~~~~~~~~~~ + SourceLocation getAttrNameLoc() const { return getLocalData()->AttrLoc; } + void setAttrNameLoc(SourceLocation loc) { getLocalData()->AttrLoc = loc; } + + /// The attribute's row operand, if it has one. + /// float __attribute__((matrix_type(4, 2))) + /// ^ + Expr *getAttrRowOperand() const { return getLocalData()->RowOperand; } + void setAttrRowOperand(Expr *e) { getLocalData()->RowOperand = e; } + + /// The attribute's column operand, if it has one. + /// float __attribute__((matrix_type(4, 2))) + /// ^ + Expr *getAttrColumnOperand() const { return getLocalData()->ColumnOperand; } + void setAttrColumnOperand(Expr *e) { getLocalData()->ColumnOperand = e; } + + /// The location of the parentheses around the operand, if there is + /// an operand. + /// float __attribute__((matrix_type(4, 2))) + /// ^ ^ + SourceRange getAttrOperandParensRange() const { + return getLocalData()->OperandParens; + } + void setAttrOperandParensRange(SourceRange range) { + getLocalData()->OperandParens = range; + } + + SourceRange getLocalSourceRange() const { + SourceRange range(getAttrNameLoc()); + range.setEnd(getAttrOperandParensRange().getEnd()); + return range; + } + + void initializeLocal(ASTContext &Context, SourceLocation loc) { + setAttrNameLoc(loc); + setAttrOperandParensRange(loc); + setAttrRowOperand(nullptr); + setAttrColumnOperand(nullptr); + } +}; + +class ConstantMatrixTypeLoc + : public InheritingConcreteTypeLoc<MatrixTypeLoc, ConstantMatrixTypeLoc, + ConstantMatrixType> {}; + +class DependentSizedMatrixTypeLoc + : public InheritingConcreteTypeLoc<MatrixTypeLoc, + DependentSizedMatrixTypeLoc, + DependentSizedMatrixType> {}; + // FIXME: location of the '_Complex' keyword. class ComplexTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, ComplexTypeLoc, @@ -1923,8 +1993,137 @@ class DeducedTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, DeducedTypeLoc, DeducedType> {}; +struct AutoTypeLocInfo : TypeSpecLocInfo { + NestedNameSpecifierLoc NestedNameSpec; + SourceLocation TemplateKWLoc; + SourceLocation ConceptNameLoc; + NamedDecl *FoundDecl; + SourceLocation LAngleLoc; + SourceLocation RAngleLoc; +}; + class AutoTypeLoc - : public InheritingConcreteTypeLoc<DeducedTypeLoc, AutoTypeLoc, AutoType> { + : public ConcreteTypeLoc<DeducedTypeLoc, + AutoTypeLoc, + AutoType, + AutoTypeLocInfo> { +public: + AutoTypeKeyword getAutoKeyword() const { + return getTypePtr()->getKeyword(); + } + + bool isConstrained() const { + return getTypePtr()->isConstrained(); + } + + const NestedNameSpecifierLoc &getNestedNameSpecifierLoc() const { + return getLocalData()->NestedNameSpec; + } + + void setNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) { + getLocalData()->NestedNameSpec = NNS; + } + + SourceLocation getTemplateKWLoc() const { + return getLocalData()->TemplateKWLoc; + } + + void setTemplateKWLoc(SourceLocation Loc) { + getLocalData()->TemplateKWLoc = Loc; + } + + SourceLocation getConceptNameLoc() const { + return getLocalData()->ConceptNameLoc; + } + + void setConceptNameLoc(SourceLocation Loc) { + getLocalData()->ConceptNameLoc = Loc; + } + + NamedDecl *getFoundDecl() const { + return getLocalData()->FoundDecl; + } + + void setFoundDecl(NamedDecl *D) { + getLocalData()->FoundDecl = D; + } + + ConceptDecl *getNamedConcept() const { + return getTypePtr()->getTypeConstraintConcept(); + } + + DeclarationNameInfo getConceptNameInfo() const; + + bool hasExplicitTemplateArgs() const { + return getLocalData()->LAngleLoc.isValid(); + } + + SourceLocation getLAngleLoc() const { + return this->getLocalData()->LAngleLoc; + } + + void setLAngleLoc(SourceLocation Loc) { + this->getLocalData()->LAngleLoc = Loc; + } + + SourceLocation getRAngleLoc() const { + return this->getLocalData()->RAngleLoc; + } + + void setRAngleLoc(SourceLocation Loc) { + this->getLocalData()->RAngleLoc = Loc; + } + + unsigned getNumArgs() const { + return getTypePtr()->getNumArgs(); + } + + void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) { + getArgInfos()[i] = AI; + } + + TemplateArgumentLocInfo getArgLocInfo(unsigned i) const { + return getArgInfos()[i]; + } + + TemplateArgumentLoc getArgLoc(unsigned i) const { + return TemplateArgumentLoc(getTypePtr()->getTypeConstraintArguments()[i], + getArgLocInfo(i)); + } + + SourceRange getLocalSourceRange() const { + return{ + isConstrained() + ? (getNestedNameSpecifierLoc() + ? getNestedNameSpecifierLoc().getBeginLoc() + : (getTemplateKWLoc().isValid() + ? getTemplateKWLoc() + : getConceptNameLoc())) + : getNameLoc(), + getNameLoc() + }; + } + + void copy(AutoTypeLoc Loc) { + unsigned size = getFullDataSize(); + assert(size == Loc.getFullDataSize()); + memcpy(Data, Loc.Data, size); + } + + void initializeLocal(ASTContext &Context, SourceLocation Loc); + + unsigned getExtraLocalDataSize() const { + return getNumArgs() * sizeof(TemplateArgumentLocInfo); + } + + unsigned getExtraLocalDataAlignment() const { + return alignof(TemplateArgumentLocInfo); + } + +private: + TemplateArgumentLocInfo *getArgInfos() const { + return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData()); + } }; class DeducedTemplateSpecializationTypeLoc @@ -2314,6 +2513,12 @@ inline T TypeLoc::getAsAdjusted() const { } return Cur.getAs<T>(); } +class ExtIntTypeLoc final + : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, ExtIntTypeLoc, + ExtIntType> {}; +class DependentExtIntTypeLoc final + : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, DependentExtIntTypeLoc, + DependentExtIntType> {}; } // namespace clang diff --git a/clang/include/clang/AST/TypeLocVisitor.h b/clang/include/clang/AST/TypeLocVisitor.h index ec780884e96c..168e9ac532ee 100644 --- a/clang/include/clang/AST/TypeLocVisitor.h +++ b/clang/include/clang/AST/TypeLocVisitor.h @@ -13,7 +13,6 @@ #define LLVM_CLANG_AST_TYPELOCVISITOR_H #include "clang/AST/TypeLoc.h" -#include "clang/AST/TypeVisitor.h" #include "llvm/Support/ErrorHandling.h" namespace clang { diff --git a/clang/include/clang/AST/TypeProperties.td b/clang/include/clang/AST/TypeProperties.td index 4df2e2f77e2b..4540ea0e1952 100644 --- a/clang/include/clang/AST/TypeProperties.td +++ b/clang/include/clang/AST/TypeProperties.td @@ -224,6 +224,41 @@ let Class = DependentSizedExtVectorType in { }]>; } +let Class = MatrixType in { + def : Property<"elementType", QualType> { + let Read = [{ node->getElementType() }]; + } +} + +let Class = ConstantMatrixType in { + def : Property<"numRows", UInt32> { + let Read = [{ node->getNumRows() }]; + } + def : Property<"numColumns", UInt32> { + let Read = [{ node->getNumColumns() }]; + } + + def : Creator<[{ + return ctx.getConstantMatrixType(elementType, numRows, numColumns); + }]>; +} + +let Class = DependentSizedMatrixType in { + def : Property<"rows", ExprRef> { + let Read = [{ node->getRowExpr() }]; + } + def : Property<"columns", ExprRef> { + let Read = [{ node->getColumnExpr() }]; + } + def : Property<"attributeLoc", SourceLocation> { + let Read = [{ node->getAttributeLoc() }]; + } + + def : Creator<[{ + return ctx.getDependentSizedMatrixType(elementType, rows, columns, attributeLoc); + }]>; +} + let Class = FunctionType in { def : Property<"returnType", QualType> { let Read = [{ node->getReturnType() }]; @@ -249,13 +284,17 @@ let Class = FunctionType in { def : Property<"noCfCheck", Bool> { let Read = [{ node->getExtInfo().getNoCfCheck() }]; } + def : Property<"cmseNSCall", Bool> { + let Read = [{ node->getExtInfo().getCmseNSCall() }]; + } } let Class = FunctionNoProtoType in { def : Creator<[{ auto extInfo = FunctionType::ExtInfo(noReturn, hasRegParm, regParm, callingConvention, producesResult, - noCallerSavedRegs, noCfCheck); + noCallerSavedRegs, noCfCheck, + cmseNSCall); return ctx.getFunctionNoProtoType(returnType, extInfo); }]>; } @@ -288,7 +327,8 @@ let Class = FunctionProtoType in { def : Creator<[{ auto extInfo = FunctionType::ExtInfo(noReturn, hasRegParm, regParm, callingConvention, producesResult, - noCallerSavedRegs, noCfCheck); + noCallerSavedRegs, noCfCheck, + cmseNSCall); FunctionProtoType::ExtProtoInfo epi; epi.ExtInfo = extInfo; epi.Variadic = variadic; @@ -395,6 +435,13 @@ let Class = AutoType in { def : Property<"keyword", AutoTypeKeyword> { let Read = [{ node->getKeyword() }]; } + def : Property<"typeConstraintConcept", Optional<ConceptDeclRef>> { + let Read = [{ makeOptionalFromPointer( + const_cast<const ConceptDecl*>(node->getTypeConstraintConcept())) }]; + } + def : Property<"typeConstraintArguments", Array<TemplateArgument>> { + let Read = [{ node->getTypeConstraintArguments() }]; + } // FIXME: better enumerated value // Only really required when the deduced type is null def : Property<"dependence", UInt32> { @@ -406,7 +453,9 @@ let Class = AutoType in { def : Creator<[{ return ctx.getAutoType(makeNullableFromOptional(deducedType), keyword, /*isDependentWithoutDeducedType*/ dependence > 0, - /*isPackWithoutDeducedType*/ dependence > 1); + /*isPackWithoutDeducedType*/ dependence > 1, + makePointerFromOptional(typeConstraintConcept), + typeConstraintArguments); }]>; } @@ -444,7 +493,9 @@ let Class = TagType in { let Class = EnumType in { def : Creator<[{ QualType result = ctx.getEnumType(cast<EnumDecl>(declaration)); - const_cast<Type*>(result.getTypePtr())->setDependent(dependent); + if (dependent) + const_cast<Type *>(result.getTypePtr()) + ->addDependence(TypeDependence::DependentInstantiation); return result; }]>; } @@ -453,7 +504,9 @@ let Class = RecordType in { def : Creator<[{ auto record = cast<RecordDecl>(declaration); QualType result = ctx.getRecordType(record); - const_cast<Type*>(result.getTypePtr())->setDependent(dependent); + if (dependent) + const_cast<Type *>(result.getTypePtr()) + ->addDependence(TypeDependence::DependentInstantiation); return result; }]>; } @@ -596,7 +649,9 @@ let Class = TemplateSpecializationType in { templateArguments, *underlyingType); } - const_cast<Type*>(result.getTypePtr())->setDependent(dependent); + if (dependent) + const_cast<Type *>(result.getTypePtr()) + ->addDependence(TypeDependence::DependentInstantiation); return result; }]>; } @@ -813,3 +868,28 @@ let Class = PipeType in { return ctx.getPipeType(elementType, isReadOnly); }]>; } + +let Class = ExtIntType in { + def : Property<"isUnsigned", Bool> { + let Read = [{ node->isUnsigned() }]; + } + def : Property <"numBits", UInt32> { + let Read = [{ node->getNumBits() }]; + } + + def : Creator<[{ + return ctx.getExtIntType(isUnsigned, numBits); + }]>; +} + +let Class = DependentExtIntType in { + def : Property<"isUnsigned", Bool> { + let Read = [{ node->isUnsigned() }]; + } + def : Property <"numBitsExpr", ExprRef> { + let Read = [{ node->getNumBitsExpr() }]; + } + def : Creator<[{ + return ctx.getDependentExtIntType(isUnsigned, numBitsExpr); + }]>; +} diff --git a/clang/include/clang/AST/VTableBuilder.h b/clang/include/clang/AST/VTableBuilder.h index 43c84292c091..241dd13f903e 100644 --- a/clang/include/clang/AST/VTableBuilder.h +++ b/clang/include/clang/AST/VTableBuilder.h @@ -238,6 +238,11 @@ public: typedef llvm::DenseMap<BaseSubobject, AddressPointLocation> AddressPointsMapTy; + // Mapping between the VTable index and address point index. This is useful + // when you don't care about the base subobjects and only want the address + // point for a given vtable index. + typedef llvm::SmallVector<unsigned, 4> AddressPointsIndexMapTy; + private: // Stores the component indices of the first component of each virtual table in // the virtual table group. To save a little memory in the common case where @@ -253,6 +258,9 @@ private: /// Address points for all vtables. AddressPointsMapTy AddressPoints; + /// Address points for all vtable indices. + AddressPointsIndexMapTy AddressPointIndices; + public: VTableLayout(ArrayRef<size_t> VTableIndices, ArrayRef<VTableComponent> VTableComponents, @@ -277,6 +285,10 @@ public: return AddressPoints; } + const AddressPointsIndexMapTy &getAddressPointIndices() const { + return AddressPointIndices; + } + size_t getNumVTables() const { if (VTableIndices.empty()) return 1; @@ -342,6 +354,9 @@ public: } bool IsMicrosoftABI; + + /// Determine whether this function should be assigned a vtable slot. + static bool hasVtableSlot(const CXXMethodDecl *MD); }; class ItaniumVTableContext : public VTableContextBase { @@ -371,7 +386,17 @@ private: void computeVTableRelatedInformation(const CXXRecordDecl *RD) override; public: - ItaniumVTableContext(ASTContext &Context); + enum VTableComponentLayout { + /// Components in the vtable are pointers to other structs/functions. + Pointer, + + /// Components in the vtable are relative offsets between the vtable and the + /// other structs/functions. + Relative, + }; + + ItaniumVTableContext(ASTContext &Context, + VTableComponentLayout ComponentLayout = Pointer); ~ItaniumVTableContext() override; const VTableLayout &getVTableLayout(const CXXRecordDecl *RD) { @@ -402,6 +427,16 @@ public: static bool classof(const VTableContextBase *VT) { return !VT->isMicrosoft(); } + + VTableComponentLayout getVTableComponentLayout() const { + return ComponentLayout; + } + + bool isPointerLayout() const { return ComponentLayout == Pointer; } + bool isRelativeLayout() const { return ComponentLayout == Relative; } + +private: + VTableComponentLayout ComponentLayout; }; /// Holds information about the inheritance path to a virtual base or function diff --git a/clang/include/clang/ASTMatchers/ASTMatchFinder.h b/clang/include/clang/ASTMatchers/ASTMatchFinder.h index f8160d552c0d..0af98438ab52 100644 --- a/clang/include/clang/ASTMatchers/ASTMatchFinder.h +++ b/clang/include/clang/ASTMatchers/ASTMatchFinder.h @@ -182,10 +182,9 @@ public: /// /// @{ template <typename T> void match(const T &Node, ASTContext &Context) { - match(clang::ast_type_traits::DynTypedNode::create(Node), Context); + match(clang::DynTypedNode::create(Node), Context); } - void match(const clang::ast_type_traits::DynTypedNode &Node, - ASTContext &Context); + void match(const clang::DynTypedNode &Node, ASTContext &Context); /// @} /// Finds all matches in the given AST. @@ -242,9 +241,8 @@ SmallVector<BoundNodes, 1> match(MatcherT Matcher, const NodeT &Node, ASTContext &Context); template <typename MatcherT> -SmallVector<BoundNodes, 1> -match(MatcherT Matcher, const ast_type_traits::DynTypedNode &Node, - ASTContext &Context); +SmallVector<BoundNodes, 1> match(MatcherT Matcher, const DynTypedNode &Node, + ASTContext &Context); /// @} /// Returns the results of matching \p Matcher on the translation unit of @@ -283,9 +281,8 @@ public: } template <typename MatcherT> -SmallVector<BoundNodes, 1> -match(MatcherT Matcher, const ast_type_traits::DynTypedNode &Node, - ASTContext &Context) { +SmallVector<BoundNodes, 1> match(MatcherT Matcher, const DynTypedNode &Node, + ASTContext &Context) { internal::CollectMatchesCallback Callback; MatchFinder Finder; Finder.addMatcher(Matcher, &Callback); @@ -296,7 +293,7 @@ match(MatcherT Matcher, const ast_type_traits::DynTypedNode &Node, template <typename MatcherT, typename NodeT> SmallVector<BoundNodes, 1> match(MatcherT Matcher, const NodeT &Node, ASTContext &Context) { - return match(Matcher, ast_type_traits::DynTypedNode::create(Node), Context); + return match(Matcher, DynTypedNode::create(Node), Context); } template <typename MatcherT> @@ -310,8 +307,8 @@ match(MatcherT Matcher, ASTContext &Context) { } inline SmallVector<BoundNodes, 1> -matchDynamic(internal::DynTypedMatcher Matcher, - const ast_type_traits::DynTypedNode &Node, ASTContext &Context) { +matchDynamic(internal::DynTypedMatcher Matcher, const DynTypedNode &Node, + ASTContext &Context) { internal::CollectMatchesCallback Callback; MatchFinder Finder; Finder.addDynamicMatcher(Matcher, &Callback); @@ -323,8 +320,7 @@ template <typename NodeT> SmallVector<BoundNodes, 1> matchDynamic(internal::DynTypedMatcher Matcher, const NodeT &Node, ASTContext &Context) { - return matchDynamic(Matcher, ast_type_traits::DynTypedNode::create(Node), - Context); + return matchDynamic(Matcher, DynTypedNode::create(Node), Context); } inline SmallVector<BoundNodes, 1> diff --git a/clang/include/clang/ASTMatchers/ASTMatchers.h b/clang/include/clang/ASTMatchers/ASTMatchers.h index 9a5888b7572b..643419743a11 100644 --- a/clang/include/clang/ASTMatchers/ASTMatchers.h +++ b/clang/include/clang/ASTMatchers/ASTMatchers.h @@ -47,6 +47,7 @@ #include "clang/AST/ASTContext.h" #include "clang/AST/ASTTypeTraits.h" #include "clang/AST/Attr.h" +#include "clang/AST/CXXInheritance.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclFriend.h" @@ -59,6 +60,7 @@ #include "clang/AST/NestedNameSpecifier.h" #include "clang/AST/OpenMPClause.h" #include "clang/AST/OperationKinds.h" +#include "clang/AST/ParentMapContext.h" #include "clang/AST/Stmt.h" #include "clang/AST/StmtCXX.h" #include "clang/AST/StmtObjC.h" @@ -71,6 +73,7 @@ #include "clang/ASTMatchers/ASTMatchersMacros.h" #include "clang/Basic/AttrKinds.h" #include "clang/Basic/ExceptionSpecificationType.h" +#include "clang/Basic/FileManager.h" #include "clang/Basic/IdentifierTable.h" #include "clang/Basic/LLVM.h" #include "clang/Basic/SourceManager.h" @@ -114,7 +117,7 @@ public: /// Type of mapping from binding identifiers to bound nodes. This type /// is an associative container with a key type of \c std::string and a value - /// type of \c clang::ast_type_traits::DynTypedNode + /// type of \c clang::DynTypedNode using IDToNodeMap = internal::BoundNodesMap::IDToNodeMap; /// Retrieve mapping from binding identifiers to bound nodes. @@ -280,9 +283,10 @@ AST_POLYMORPHIC_MATCHER(isExpansionInSystemHeader, /// \endcode /// /// Usable as: Matcher<Decl>, Matcher<Stmt>, Matcher<TypeLoc> -AST_POLYMORPHIC_MATCHER_P(isExpansionInFileMatching, - AST_POLYMORPHIC_SUPPORTED_TYPES(Decl, Stmt, TypeLoc), - std::string, RegExp) { +AST_POLYMORPHIC_MATCHER_REGEX(isExpansionInFileMatching, + AST_POLYMORPHIC_SUPPORTED_TYPES(Decl, Stmt, + TypeLoc), + RegExp) { auto &SourceManager = Finder->getASTContext().getSourceManager(); auto ExpansionLoc = SourceManager.getExpansionLoc(Node.getBeginLoc()); if (ExpansionLoc.isInvalid()) { @@ -295,8 +299,27 @@ AST_POLYMORPHIC_MATCHER_P(isExpansionInFileMatching, } auto Filename = FileEntry->getName(); - llvm::Regex RE(RegExp); - return RE.match(Filename); + return RegExp->match(Filename); +} + +/// Matches statements that are (transitively) expanded from the named macro. +/// Does not match if only part of the statement is expanded from that macro or +/// if different parts of the the statement are expanded from different +/// appearances of the macro. +/// +/// FIXME: Change to be a polymorphic matcher that works on any syntactic +/// node. There's nothing `Stmt`-specific about it. +AST_MATCHER_P(Stmt, isExpandedFromMacro, llvm::StringRef, MacroName) { + // Verifies that the statement' beginning and ending are both expanded from + // the same instance of the given macro. + auto& Context = Finder->getASTContext(); + llvm::Optional<SourceLocation> B = + internal::getExpansionLocOfMacro(MacroName, Node.getBeginLoc(), Context); + if (!B) return false; + llvm::Optional<SourceLocation> E = + internal::getExpansionLocOfMacro(MacroName, Node.getEndLoc(), Context); + if (!E) return false; + return *B == *E; } /// Matches declarations. @@ -526,52 +549,72 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl, extern const internal::VariadicDynCastAllOfMatcher<Decl, TemplateTypeParmDecl> templateTypeParmDecl; -/// Matches public C++ declarations. +/// Matches public C++ declarations and C++ base specifers that specify public +/// inheritance. /// -/// Given +/// Examples: /// \code /// class C { -/// public: int a; +/// public: int a; // fieldDecl(isPublic()) matches 'a' /// protected: int b; /// private: int c; /// }; /// \endcode -/// fieldDecl(isPublic()) -/// matches 'int a;' -AST_MATCHER(Decl, isPublic) { - return Node.getAccess() == AS_public; +/// +/// \code +/// class Base {}; +/// class Derived1 : public Base {}; // matches 'Base' +/// struct Derived2 : Base {}; // matches 'Base' +/// \endcode +AST_POLYMORPHIC_MATCHER(isPublic, + AST_POLYMORPHIC_SUPPORTED_TYPES(Decl, + CXXBaseSpecifier)) { + return getAccessSpecifier(Node) == AS_public; } -/// Matches protected C++ declarations. +/// Matches protected C++ declarations and C++ base specifers that specify +/// protected inheritance. /// -/// Given +/// Examples: /// \code /// class C { /// public: int a; -/// protected: int b; +/// protected: int b; // fieldDecl(isProtected()) matches 'b' /// private: int c; /// }; /// \endcode -/// fieldDecl(isProtected()) -/// matches 'int b;' -AST_MATCHER(Decl, isProtected) { - return Node.getAccess() == AS_protected; +/// +/// \code +/// class Base {}; +/// class Derived : protected Base {}; // matches 'Base' +/// \endcode +AST_POLYMORPHIC_MATCHER(isProtected, + AST_POLYMORPHIC_SUPPORTED_TYPES(Decl, + CXXBaseSpecifier)) { + return getAccessSpecifier(Node) == AS_protected; } -/// Matches private C++ declarations. +/// Matches private C++ declarations and C++ base specifers that specify private +/// inheritance. /// -/// Given +/// Examples: /// \code /// class C { /// public: int a; /// protected: int b; -/// private: int c; +/// private: int c; // fieldDecl(isPrivate()) matches 'c' /// }; /// \endcode -/// fieldDecl(isPrivate()) -/// matches 'int c;' -AST_MATCHER(Decl, isPrivate) { - return Node.getAccess() == AS_private; +/// +/// \code +/// struct Base {}; +/// struct Derived1 : private Base {}; // matches 'Base' +/// class Derived2 : Base {}; // matches 'Base' +/// \endcode +AST_POLYMORPHIC_MATCHER(isPrivate, + AST_POLYMORPHIC_SUPPORTED_TYPES(Decl, + CXXBaseSpecifier)) { + return getAccessSpecifier(Node) == AS_private; } /// Matches non-static data members that are bit-fields. @@ -701,13 +744,13 @@ AST_POLYMORPHIC_MATCHER_P( /// \endcode /// The matcher /// \code -/// traverse(ast_type_traits::TK_IgnoreImplicitCastsAndParentheses, +/// traverse(TK_IgnoreImplicitCastsAndParentheses, /// varDecl(hasInitializer(floatLiteral().bind("init"))) /// ) /// \endcode /// matches the variable declaration with "init" bound to the "3.0". template <typename T> -internal::Matcher<T> traverse(ast_type_traits::TraversalKind TK, +internal::Matcher<T> traverse(TraversalKind TK, const internal::Matcher<T> &InnerMatcher) { return internal::DynTypedMatcher::constructRestrictedWrapper( new internal::TraversalMatcher<T>(TK, InnerMatcher), @@ -717,8 +760,7 @@ internal::Matcher<T> traverse(ast_type_traits::TraversalKind TK, template <typename T> internal::BindableMatcher<T> -traverse(ast_type_traits::TraversalKind TK, - const internal::BindableMatcher<T> &InnerMatcher) { +traverse(TraversalKind TK, const internal::BindableMatcher<T> &InnerMatcher) { return internal::BindableMatcher<T>( internal::DynTypedMatcher::constructRestrictedWrapper( new internal::TraversalMatcher<T>(TK, InnerMatcher), @@ -728,7 +770,7 @@ traverse(ast_type_traits::TraversalKind TK, template <typename... T> internal::TraversalWrapper<internal::VariadicOperatorMatcher<T...>> -traverse(ast_type_traits::TraversalKind TK, +traverse(TraversalKind TK, const internal::VariadicOperatorMatcher<T...> &InnerMatcher) { return internal::TraversalWrapper<internal::VariadicOperatorMatcher<T...>>( TK, InnerMatcher); @@ -738,9 +780,8 @@ template <template <typename ToArg, typename FromArg> class ArgumentAdapterT, typename T, typename ToTypes> internal::TraversalWrapper< internal::ArgumentAdaptingMatcherFuncAdaptor<ArgumentAdapterT, T, ToTypes>> -traverse(ast_type_traits::TraversalKind TK, - const internal::ArgumentAdaptingMatcherFuncAdaptor< - ArgumentAdapterT, T, ToTypes> &InnerMatcher) { +traverse(TraversalKind TK, const internal::ArgumentAdaptingMatcherFuncAdaptor< + ArgumentAdapterT, T, ToTypes> &InnerMatcher) { return internal::TraversalWrapper< internal::ArgumentAdaptingMatcherFuncAdaptor<ArgumentAdapterT, T, ToTypes>>(TK, InnerMatcher); @@ -750,10 +791,8 @@ template <template <typename T, typename P1> class MatcherT, typename P1, typename ReturnTypesF> internal::TraversalWrapper< internal::PolymorphicMatcherWithParam1<MatcherT, P1, ReturnTypesF>> -traverse( - ast_type_traits::TraversalKind TK, - const internal::PolymorphicMatcherWithParam1<MatcherT, P1, ReturnTypesF> - &InnerMatcher) { +traverse(TraversalKind TK, const internal::PolymorphicMatcherWithParam1< + MatcherT, P1, ReturnTypesF> &InnerMatcher) { return internal::TraversalWrapper< internal::PolymorphicMatcherWithParam1<MatcherT, P1, ReturnTypesF>>( TK, InnerMatcher); @@ -763,10 +802,8 @@ template <template <typename T, typename P1, typename P2> class MatcherT, typename P1, typename P2, typename ReturnTypesF> internal::TraversalWrapper< internal::PolymorphicMatcherWithParam2<MatcherT, P1, P2, ReturnTypesF>> -traverse( - ast_type_traits::TraversalKind TK, - const internal::PolymorphicMatcherWithParam2<MatcherT, P1, P2, ReturnTypesF> - &InnerMatcher) { +traverse(TraversalKind TK, const internal::PolymorphicMatcherWithParam2< + MatcherT, P1, P2, ReturnTypesF> &InnerMatcher) { return internal::TraversalWrapper< internal::PolymorphicMatcherWithParam2<MatcherT, P1, P2, ReturnTypesF>>( TK, InnerMatcher); @@ -1194,6 +1231,20 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl, EnumDecl> enumDecl; extern const internal::VariadicDynCastAllOfMatcher<Decl, EnumConstantDecl> enumConstantDecl; +/// Matches tag declarations. +/// +/// Example matches X, Z, U, S, E +/// \code +/// class X; +/// template<class T> class Z {}; +/// struct S {}; +/// union U {}; +/// enum E { +/// A, B, C +/// }; +/// \endcode +extern const internal::VariadicDynCastAllOfMatcher<Decl, TagDecl> tagDecl; + /// Matches method declarations. /// /// Example matches y @@ -1823,6 +1874,22 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXNewExpr> cxxNewExpr; extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXDeleteExpr> cxxDeleteExpr; +/// Matches noexcept expressions. +/// +/// Given +/// \code +/// bool a() noexcept; +/// bool b() noexcept(true); +/// bool c() noexcept(false); +/// bool d() noexcept(noexcept(a())); +/// bool e = noexcept(b()) || noexcept(c()); +/// \endcode +/// cxxNoexceptExpr() +/// matches `noexcept(a())`, `noexcept(b())` and `noexcept(c())`. +/// doesn't match the noexcept specifier in the declarations a, b, c or d. +extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXNoexceptExpr> + cxxNoexceptExpr; + /// Matches array subscript expressions. /// /// Given @@ -2225,6 +2292,10 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, FloatingLiteral> extern const internal::VariadicDynCastAllOfMatcher<Stmt, ImaginaryLiteral> imaginaryLiteral; +/// Matches fixed point literals +extern const internal::VariadicDynCastAllOfMatcher<Stmt, FixedPointLiteral> + fixedPointLiteral; + /// Matches user defined literal operator call. /// /// Example match: "foo"_suffix @@ -2541,13 +2612,11 @@ extern const internal::VariadicOperatorMatcherFunc< 2, std::numeric_limits<unsigned>::max()> allOf; -/// Matches any node regardless of the submatchers. -/// -/// However, \c optionally will generate a result binding for each matching -/// submatcher. +/// Matches any node regardless of the submatcher. /// -/// Useful when additional information which may or may not present about a -/// main matching node is desired. +/// However, \c optionally will retain any bindings generated by the submatcher. +/// Useful when additional information which may or may not present about a main +/// matching node is desired. /// /// For example, in: /// \code @@ -2567,9 +2636,7 @@ extern const internal::VariadicOperatorMatcherFunc< /// member named "bar" in that class. /// /// Usable as: Any Matcher -extern const internal::VariadicOperatorMatcherFunc< - 1, std::numeric_limits<unsigned>::max()> - optionally; +extern const internal::VariadicOperatorMatcherFunc<1, 1> optionally; /// Matches sizeof (C99), alignof (C++11) and vec_step (OpenCL) /// @@ -2616,7 +2683,7 @@ AST_MATCHER_P(UnaryExprOrTypeTraitExpr, ofKind, UnaryExprOrTypeTrait, Kind) { /// Same as unaryExprOrTypeTraitExpr, but only matching /// alignof. -inline internal::Matcher<Stmt> alignOfExpr( +inline internal::BindableMatcher<Stmt> alignOfExpr( const internal::Matcher<UnaryExprOrTypeTraitExpr> &InnerMatcher) { return stmt(unaryExprOrTypeTraitExpr( allOf(anyOf(ofKind(UETT_AlignOf), ofKind(UETT_PreferredAlignOf)), @@ -2625,7 +2692,7 @@ inline internal::Matcher<Stmt> alignOfExpr( /// Same as unaryExprOrTypeTraitExpr, but only matching /// sizeof. -inline internal::Matcher<Stmt> sizeOfExpr( +inline internal::BindableMatcher<Stmt> sizeOfExpr( const internal::Matcher<UnaryExprOrTypeTraitExpr> &InnerMatcher) { return stmt(unaryExprOrTypeTraitExpr( allOf(ofKind(UETT_SizeOf), InnerMatcher))); @@ -2646,8 +2713,9 @@ inline internal::Matcher<Stmt> sizeOfExpr( /// \code /// namespace a { namespace b { class X; } } /// \endcode -inline internal::Matcher<NamedDecl> hasName(const std::string &Name) { - return internal::Matcher<NamedDecl>(new internal::HasNameMatcher({Name})); +inline internal::Matcher<NamedDecl> hasName(StringRef Name) { + return internal::Matcher<NamedDecl>( + new internal::HasNameMatcher({std::string(Name)})); } /// Matches NamedDecl nodes that have any of the specified names. @@ -2680,11 +2748,9 @@ extern const internal::VariadicFunction<internal::Matcher<NamedDecl>, StringRef, /// \code /// namespace foo { namespace bar { class X; } } /// \endcode -AST_MATCHER_P(NamedDecl, matchesName, std::string, RegExp) { - assert(!RegExp.empty()); +AST_MATCHER_REGEX(NamedDecl, matchesName, RegExp) { std::string FullNameString = "::" + Node.getQualifiedNameAsString(); - llvm::Regex RE(RegExp); - return RE.match(FullNameString); + return RegExp->match(FullNameString); } /// Matches overloaded operator names. @@ -2707,14 +2773,30 @@ AST_MATCHER_P(NamedDecl, matchesName, std::string, RegExp) { /// /// Usable as: Matcher<CXXOperatorCallExpr>, Matcher<FunctionDecl> inline internal::PolymorphicMatcherWithParam1< - internal::HasOverloadedOperatorNameMatcher, StringRef, + internal::HasOverloadedOperatorNameMatcher, std::vector<std::string>, AST_POLYMORPHIC_SUPPORTED_TYPES(CXXOperatorCallExpr, FunctionDecl)> hasOverloadedOperatorName(StringRef Name) { return internal::PolymorphicMatcherWithParam1< - internal::HasOverloadedOperatorNameMatcher, StringRef, - AST_POLYMORPHIC_SUPPORTED_TYPES(CXXOperatorCallExpr, FunctionDecl)>(Name); + internal::HasOverloadedOperatorNameMatcher, std::vector<std::string>, + AST_POLYMORPHIC_SUPPORTED_TYPES(CXXOperatorCallExpr, FunctionDecl)>( + {std::string(Name)}); } +/// Matches overloaded operator names. +/// +/// Matches overloaded operator names specified in strings without the +/// "operator" prefix: e.g. "<<". +/// +/// hasAnyOverloadesOperatorName("+", "-") +/// Is equivalent to +/// anyOf(hasOverloadedOperatorName("+"), hasOverloadedOperatorName("-")) +extern const internal::VariadicFunction< + internal::PolymorphicMatcherWithParam1< + internal::HasOverloadedOperatorNameMatcher, std::vector<std::string>, + AST_POLYMORPHIC_SUPPORTED_TYPES(CXXOperatorCallExpr, FunctionDecl)>, + StringRef, internal::hasAnyOverloadedOperatorNameFunc> + hasAnyOverloadedOperatorName; + /// Matches C++ classes that are directly or indirectly derived from a class /// matching \c Base, or Objective-C classes that directly or indirectly /// subclass a class matching \c Base. @@ -2776,6 +2858,46 @@ AST_POLYMORPHIC_MATCHER_P_OVERLOAD( return Matcher<ObjCInterfaceDecl>(M).matches(*InterfaceDecl, Finder, Builder); } +/// Matches C++ classes that have a direct or indirect base matching \p +/// BaseSpecMatcher. +/// +/// Example: +/// matcher hasAnyBase(hasType(cxxRecordDecl(hasName("SpecialBase")))) +/// \code +/// class Foo; +/// class Bar : Foo {}; +/// class Baz : Bar {}; +/// class SpecialBase; +/// class Proxy : SpecialBase {}; // matches Proxy +/// class IndirectlyDerived : Proxy {}; //matches IndirectlyDerived +/// \endcode +/// +// FIXME: Refactor this and isDerivedFrom to reuse implementation. +AST_MATCHER_P(CXXRecordDecl, hasAnyBase, internal::Matcher<CXXBaseSpecifier>, + BaseSpecMatcher) { + return internal::matchesAnyBase(Node, BaseSpecMatcher, Finder, Builder); +} + +/// Matches C++ classes that have a direct base matching \p BaseSpecMatcher. +/// +/// Example: +/// matcher hasDirectBase(hasType(cxxRecordDecl(hasName("SpecialBase")))) +/// \code +/// class Foo; +/// class Bar : Foo {}; +/// class Baz : Bar {}; +/// class SpecialBase; +/// class Proxy : SpecialBase {}; // matches Proxy +/// class IndirectlyDerived : Proxy {}; // doesn't match +/// \endcode +AST_MATCHER_P(CXXRecordDecl, hasDirectBase, internal::Matcher<CXXBaseSpecifier>, + BaseSpecMatcher) { + return Node.hasDefinition() && + llvm::any_of(Node.bases(), [&](const CXXBaseSpecifier &Base) { + return BaseSpecMatcher.matches(Base, Finder, Builder); + }); +} + /// Similar to \c isDerivedFrom(), but also matches classes that directly /// match \c Base. AST_POLYMORPHIC_MATCHER_P_OVERLOAD( @@ -3269,11 +3391,9 @@ extern const internal::VariadicFunction<internal::Matcher<ObjCMessageExpr>, /// \code /// [self.bodyView loadHTMLString:html baseURL:NULL]; /// \endcode -AST_MATCHER_P(ObjCMessageExpr, matchesSelector, std::string, RegExp) { - assert(!RegExp.empty()); +AST_MATCHER_REGEX(ObjCMessageExpr, matchesSelector, RegExp) { std::string SelectorString = Node.getSelector().getAsString(); - llvm::Regex RE(RegExp); - return RE.match(SelectorString); + return RegExp->match(SelectorString); } /// Matches when the selector is the empty selector @@ -3406,9 +3526,19 @@ AST_POLYMORPHIC_MATCHER_P_OVERLOAD( /// class Y { friend class X; }; /// \endcode /// -/// Usable as: Matcher<Expr>, Matcher<ValueDecl> +/// Example matches class Derived +/// (matcher = cxxRecordDecl(hasAnyBase(hasType(cxxRecordDecl(hasName("Base")))))) +/// \code +/// class Base {}; +/// class Derived : Base {}; +/// \endcode +/// +/// Usable as: Matcher<Expr>, Matcher<FriendDecl>, Matcher<ValueDecl>, +/// Matcher<CXXBaseSpecifier> AST_POLYMORPHIC_MATCHER_P_OVERLOAD( - hasType, AST_POLYMORPHIC_SUPPORTED_TYPES(Expr, FriendDecl, ValueDecl), + hasType, + AST_POLYMORPHIC_SUPPORTED_TYPES(Expr, FriendDecl, ValueDecl, + CXXBaseSpecifier), internal::Matcher<Decl>, InnerMatcher, 1) { QualType QT = internal::getUnderlyingType(Node); if (!QT.isNull()) @@ -4194,6 +4324,34 @@ AST_POLYMORPHIC_MATCHER_P2(forEachArgumentWithParam, return Matched; } +/// Matches the ParmVarDecl nodes that are at the N'th position in the parameter +/// list. The parameter list could be that of either a block, function, or +/// objc-method. +/// +/// +/// Given +/// +/// \code +/// void f(int a, int b, int c) { +/// } +/// \endcode +/// +/// ``parmVarDecl(isAtPosition(0))`` matches ``int a``. +/// +/// ``parmVarDecl(isAtPosition(1))`` matches ``int b``. +AST_MATCHER_P(ParmVarDecl, isAtPosition, unsigned, N) { + const clang::DeclContext *Context = Node.getParentFunctionOrMethod(); + + if (const auto *Decl = dyn_cast_or_null<FunctionDecl>(Context)) + return N < Decl->param_size() && Decl->getParamDecl(N) == &Node; + if (const auto *Decl = dyn_cast_or_null<BlockDecl>(Context)) + return N < Decl->param_size() && Decl->getParamDecl(N) == &Node; + if (const auto *Decl = dyn_cast_or_null<ObjCMethodDecl>(Context)) + return N < Decl->param_size() && Decl->getParamDecl(N) == &Node; + + return false; +} + /// Matches any parameter of a function or an ObjC method declaration or a /// block. /// @@ -4532,7 +4690,7 @@ AST_POLYMORPHIC_MATCHER_P(equalsBoundNode, // they're ever reused. internal::NotEqualsBoundNodePredicate Predicate; Predicate.ID = ID; - Predicate.Node = ast_type_traits::DynTypedNode::create(Node); + Predicate.Node = DynTypedNode::create(Node); return Builder->removeBindings(Predicate); } @@ -4716,6 +4874,19 @@ AST_POLYMORPHIC_MATCHER_P(hasOperatorName, return Name == Node.getOpcodeStr(Node.getOpcode()); } +/// Matches operator expressions (binary or unary) that have any of the +/// specified names. +/// +/// hasAnyOperatorName("+", "-") +/// Is equivalent to +/// anyOf(hasOperatorName("+"), hasOperatorName("-")) +extern const internal::VariadicFunction< + internal::PolymorphicMatcherWithParam1< + internal::HasAnyOperatorNameMatcher, std::vector<std::string>, + AST_POLYMORPHIC_SUPPORTED_TYPES(BinaryOperator, UnaryOperator)>, + StringRef, internal::hasAnyOperatorNameFunc> + hasAnyOperatorName; + /// Matches all kinds of assignment operators. /// /// Example 1: matches a += b (matcher = binaryOperator(isAssignmentOperator())) @@ -4728,7 +4899,7 @@ AST_POLYMORPHIC_MATCHER_P(hasOperatorName, /// (matcher = cxxOperatorCallExpr(isAssignmentOperator())) /// \code /// struct S { S& operator=(const S&); }; -/// void x() { S s1, s2; s1 = s2; }) +/// void x() { S s1, s2; s1 = s2; } /// \endcode AST_POLYMORPHIC_MATCHER(isAssignmentOperator, AST_POLYMORPHIC_SUPPORTED_TYPES(BinaryOperator, @@ -4736,6 +4907,26 @@ AST_POLYMORPHIC_MATCHER(isAssignmentOperator, return Node.isAssignmentOp(); } +/// Matches comparison operators. +/// +/// Example 1: matches a == b (matcher = binaryOperator(isComparisonOperator())) +/// \code +/// if (a == b) +/// a += b; +/// \endcode +/// +/// Example 2: matches s1 < s2 +/// (matcher = cxxOperatorCallExpr(isComparisonOperator())) +/// \code +/// struct S { bool operator<(const S& other); }; +/// void x(S s1, S s2) { bool b1 = s1 < s2; } +/// \endcode +AST_POLYMORPHIC_MATCHER(isComparisonOperator, + AST_POLYMORPHIC_SUPPORTED_TYPES(BinaryOperator, + CXXOperatorCallExpr)) { + return Node.isComparisonOp(); +} + /// Matches the left hand side of binary operator expressions. /// /// Example matches a (matcher = binaryOperator(hasLHS())) @@ -4773,6 +4964,23 @@ inline internal::Matcher<BinaryOperator> hasEitherOperand( return anyOf(hasLHS(InnerMatcher), hasRHS(InnerMatcher)); } +/// Matches if both matchers match with opposite sides of the binary operator. +/// +/// Example matcher = binaryOperator(hasOperands(integerLiteral(equals(1), +/// integerLiteral(equals(2))) +/// \code +/// 1 + 2 // Match +/// 2 + 1 // Match +/// 1 + 1 // No match +/// 2 + 2 // No match +/// \endcode +inline internal::Matcher<BinaryOperator> +hasOperands(const internal::Matcher<Expr> &Matcher1, + const internal::Matcher<Expr> &Matcher2) { + return anyOf(allOf(hasLHS(Matcher1), hasRHS(Matcher2)), + allOf(hasLHS(Matcher2), hasRHS(Matcher1))); +} + /// Matches if the operand of a unary operator matches. /// /// Example matches true (matcher = hasUnaryOperand( @@ -4821,7 +5029,7 @@ AST_POLYMORPHIC_MATCHER_P(hasSourceExpression, /// \endcode /// /// If the matcher is use from clang-query, CastKind parameter -/// should be passed as a quoted string. e.g., ofKind("CK_NullToPointer"). +/// should be passed as a quoted string. e.g., hasCastKind("CK_NullToPointer"). AST_MATCHER_P(CastExpr, hasCastKind, CastKind, Kind) { return Node.getCastKind() == Kind; } @@ -4845,42 +5053,58 @@ AST_MATCHER_P(ImplicitCastExpr, hasImplicitDestinationType, return InnerMatcher.matches(Node.getType(), Finder, Builder); } -/// Matches RecordDecl object that are spelled with "struct." +/// Matches TagDecl object that are spelled with "struct." /// -/// Example matches S, but not C or U. +/// Example matches S, but not C, U or E. /// \code /// struct S {}; /// class C {}; /// union U {}; +/// enum E {}; /// \endcode -AST_MATCHER(RecordDecl, isStruct) { +AST_MATCHER(TagDecl, isStruct) { return Node.isStruct(); } -/// Matches RecordDecl object that are spelled with "union." +/// Matches TagDecl object that are spelled with "union." /// -/// Example matches U, but not C or S. +/// Example matches U, but not C, S or E. /// \code /// struct S {}; /// class C {}; /// union U {}; +/// enum E {}; /// \endcode -AST_MATCHER(RecordDecl, isUnion) { +AST_MATCHER(TagDecl, isUnion) { return Node.isUnion(); } -/// Matches RecordDecl object that are spelled with "class." +/// Matches TagDecl object that are spelled with "class." /// -/// Example matches C, but not S or U. +/// Example matches C, but not S, U or E. /// \code /// struct S {}; /// class C {}; /// union U {}; +/// enum E {}; /// \endcode -AST_MATCHER(RecordDecl, isClass) { +AST_MATCHER(TagDecl, isClass) { return Node.isClass(); } +/// Matches TagDecl object that are spelled with "enum." +/// +/// Example matches E, but not C, S or U. +/// \code +/// struct S {}; +/// class C {}; +/// union U {}; +/// enum E {}; +/// \endcode +AST_MATCHER(TagDecl, isEnum) { + return Node.isEnum(); +} + /// Matches the true branch expression of a conditional operator. /// /// Example 1 (conditional ternary operator): matches a @@ -5020,17 +5244,28 @@ AST_MATCHER_P(CXXMethodDecl, forEachOverridden, return Matched; } -/// Matches if the given method declaration is virtual. +/// Matches declarations of virtual methods and C++ base specifers that specify +/// virtual inheritance. /// -/// Given +/// Example: /// \code /// class A { /// public: -/// virtual void x(); +/// virtual void x(); // matches x /// }; /// \endcode -/// matches A::x -AST_MATCHER(CXXMethodDecl, isVirtual) { +/// +/// Example: +/// \code +/// class Base {}; +/// class DirectlyDerived : virtual Base {}; // matches Base +/// class IndirectlyDerived : DirectlyDerived, Base {}; // matches Base +/// \endcode +/// +/// Usable as: Matcher<CXXMethodDecl>, Matcher<CXXBaseSpecifier> +AST_POLYMORPHIC_MATCHER(isVirtual, + AST_POLYMORPHIC_SUPPORTED_TYPES(CXXMethodDecl, + CXXBaseSpecifier)) { return Node.isVirtual(); } @@ -5982,6 +6217,21 @@ extern const AstTypeMatcher<EnumType> enumType; extern const AstTypeMatcher<TemplateSpecializationType> templateSpecializationType; +/// Matches C++17 deduced template specialization types, e.g. deduced class +/// template types. +/// +/// Given +/// \code +/// template <typename T> +/// class C { public: C(T); }; +/// +/// C c(123); +/// \endcode +/// \c deducedTemplateSpecializationType() matches the type in the declaration +/// of the variable \c c. +extern const AstTypeMatcher<DeducedTemplateSpecializationType> + deducedTemplateSpecializationType; + /// Matches types nodes representing unary type transformations. /// /// Given: @@ -6652,8 +6902,7 @@ AST_MATCHER_P(Stmt, forFunction, internal::Matcher<FunctionDecl>, InnerMatcher) { const auto &Parents = Finder->getASTContext().getParents(Node); - llvm::SmallVector<ast_type_traits::DynTypedNode, 8> Stack(Parents.begin(), - Parents.end()); + llvm::SmallVector<DynTypedNode, 8> Stack(Parents.begin(), Parents.end()); while(!Stack.empty()) { const auto &CurNode = Stack.back(); Stack.pop_back(); @@ -6735,6 +6984,35 @@ AST_MATCHER(CXXNewExpr, isArray) { return Node.isArray(); } +/// Matches placement new expression arguments. +/// +/// Given: +/// \code +/// MyClass *p1 = new (Storage, 16) MyClass(); +/// \endcode +/// cxxNewExpr(hasPlacementArg(1, integerLiteral(equals(16)))) +/// matches the expression 'new (Storage, 16) MyClass()'. +AST_MATCHER_P2(CXXNewExpr, hasPlacementArg, unsigned, Index, + internal::Matcher<Expr>, InnerMatcher) { + return Node.getNumPlacementArgs() > Index && + InnerMatcher.matches(*Node.getPlacementArg(Index), Finder, Builder); +} + +/// Matches any placement new expression arguments. +/// +/// Given: +/// \code +/// MyClass *p1 = new (Storage) MyClass(); +/// \endcode +/// cxxNewExpr(hasAnyPlacementArg(anything())) +/// matches the expression 'new (Storage, 16) MyClass()'. +AST_MATCHER_P(CXXNewExpr, hasAnyPlacementArg, internal::Matcher<Expr>, + InnerMatcher) { + return llvm::any_of(Node.placement_arguments(), [&](const Expr *Arg) { + return InnerMatcher.matches(*Arg, Finder, Builder); + }); +} + /// Matches array new expressions with a given array size. /// /// Given: @@ -6865,19 +7143,6 @@ AST_MATCHER(OMPExecutableDirective, isStandaloneDirective) { return Node.isStandaloneDirective(); } -/// Matches the Stmt AST node that is marked as being the structured-block -/// of an OpenMP executable directive. -/// -/// Given -/// -/// \code -/// #pragma omp parallel -/// {} -/// \endcode -/// -/// ``stmt(isOMPStructuredBlock()))`` matches ``{}``. -AST_MATCHER(Stmt, isOMPStructuredBlock) { return Node.isOMPStructuredBlock(); } - /// Matches the structured-block of the OpenMP executable directive /// /// Prerequisite: the executable directive must not be standalone directive. @@ -6925,10 +7190,12 @@ AST_MATCHER_P(OMPExecutableDirective, hasAnyClause, /// \code /// #pragma omp parallel default(none) /// #pragma omp parallel default(shared) +/// #pragma omp parallel default(firstprivate) /// #pragma omp parallel /// \endcode /// -/// ``ompDefaultClause()`` matches ``default(none)`` and ``default(shared)``. +/// ``ompDefaultClause()`` matches ``default(none)``, ``default(shared)``, and +/// ``default(firstprivate)`` extern const internal::VariadicDynCastAllOfMatcher<OMPClause, OMPDefaultClause> ompDefaultClause; @@ -6940,11 +7207,12 @@ extern const internal::VariadicDynCastAllOfMatcher<OMPClause, OMPDefaultClause> /// #pragma omp parallel /// #pragma omp parallel default(none) /// #pragma omp parallel default(shared) +/// #pragma omp parallel default(firstprivate) /// \endcode /// /// ``ompDefaultClause(isNoneKind())`` matches only ``default(none)``. AST_MATCHER(OMPDefaultClause, isNoneKind) { - return Node.getDefaultKind() == OMPC_DEFAULT_none; + return Node.getDefaultKind() == llvm::omp::OMP_DEFAULT_none; } /// Matches if the OpenMP ``default`` clause has ``shared`` kind specified. @@ -6955,11 +7223,30 @@ AST_MATCHER(OMPDefaultClause, isNoneKind) { /// #pragma omp parallel /// #pragma omp parallel default(none) /// #pragma omp parallel default(shared) +/// #pragma omp parallel default(firstprivate) /// \endcode /// /// ``ompDefaultClause(isSharedKind())`` matches only ``default(shared)``. AST_MATCHER(OMPDefaultClause, isSharedKind) { - return Node.getDefaultKind() == OMPC_DEFAULT_shared; + return Node.getDefaultKind() == llvm::omp::OMP_DEFAULT_shared; +} + +/// Matches if the OpenMP ``default`` clause has ``firstprivate`` kind +/// specified. +/// +/// Given +/// +/// \code +/// #pragma omp parallel +/// #pragma omp parallel default(none) +/// #pragma omp parallel default(shared) +/// #pragma omp parallel default(firstprivate) +/// \endcode +/// +/// ``ompDefaultClause(isFirstPrivateKind())`` matches only +/// ``default(firstprivate)``. +AST_MATCHER(OMPDefaultClause, isFirstPrivateKind) { + return Node.getDefaultKind() == llvm::omp::OMP_DEFAULT_firstprivate; } /// Matches if the OpenMP directive is allowed to contain the specified OpenMP @@ -6981,7 +7268,7 @@ AST_MATCHER(OMPDefaultClause, isSharedKind) { /// ``isAllowedToContainClauseKind("OMPC_default").`` AST_MATCHER_P(OMPExecutableDirective, isAllowedToContainClauseKind, OpenMPClauseKind, CKind) { - return isAllowedClauseForDirective( + return llvm::omp::isAllowedClauseForDirective( Node.getDirectiveKind(), CKind, Finder->getASTContext().getLangOpts().OpenMP); } diff --git a/clang/include/clang/ASTMatchers/ASTMatchersInternal.h b/clang/include/clang/ASTMatchers/ASTMatchersInternal.h index c4b449fa9434..3992850c992d 100644 --- a/clang/include/clang/ASTMatchers/ASTMatchersInternal.h +++ b/clang/include/clang/ASTMatchers/ASTMatchersInternal.h @@ -40,7 +40,6 @@ #include "clang/AST/DeclFriend.h" #include "clang/AST/DeclTemplate.h" #include "clang/AST/Expr.h" -#include "clang/AST/ExprObjC.h" #include "clang/AST/ExprCXX.h" #include "clang/AST/ExprObjC.h" #include "clang/AST/NestedNameSpecifier.h" @@ -61,11 +60,13 @@ #include "llvm/ADT/iterator.h" #include "llvm/Support/Casting.h" #include "llvm/Support/ManagedStatic.h" +#include "llvm/Support/Regex.h" #include <algorithm> #include <cassert> #include <cstddef> #include <cstdint> #include <map> +#include <memory> #include <string> #include <tuple> #include <type_traits> @@ -130,6 +131,9 @@ inline QualType getUnderlyingType(const FriendDecl &Node) { return TSI->getType(); return QualType(); } +inline QualType getUnderlyingType(const CXXBaseSpecifier &Node) { + return Node.getType(); +} /// Unifies obtaining the FunctionProtoType pointer from both /// FunctionProtoType and FunctionDecl nodes.. @@ -142,14 +146,23 @@ inline const FunctionProtoType *getFunctionProtoType(const FunctionDecl &Node) { return Node.getType()->getAs<FunctionProtoType>(); } +/// Unifies obtaining the access specifier from Decl and CXXBaseSpecifier nodes. +inline clang::AccessSpecifier getAccessSpecifier(const Decl &Node) { + return Node.getAccess(); +} + +inline clang::AccessSpecifier getAccessSpecifier(const CXXBaseSpecifier &Node) { + return Node.getAccessSpecifier(); +} + /// Internal version of BoundNodes. Holds all the bound nodes. class BoundNodesMap { public: /// Adds \c Node to the map with key \c ID. /// /// The node's base type should be in NodeBaseType or it will be unaccessible. - void addNode(StringRef ID, const ast_type_traits::DynTypedNode& DynNode) { - NodeMap[ID] = DynNode; + void addNode(StringRef ID, const DynTypedNode &DynNode) { + NodeMap[std::string(ID)] = DynNode; } /// Returns the AST node bound to \c ID. @@ -165,10 +178,10 @@ public: return It->second.get<T>(); } - ast_type_traits::DynTypedNode getNode(StringRef ID) const { + DynTypedNode getNode(StringRef ID) const { IDToNodeMap::const_iterator It = NodeMap.find(ID); if (It == NodeMap.end()) { - return ast_type_traits::DynTypedNode(); + return DynTypedNode(); } return It->second; } @@ -183,8 +196,7 @@ public: /// Note that we're using std::map here, as for memoization: /// - we need a comparison operator /// - we need an assignment operator - using IDToNodeMap = - std::map<std::string, ast_type_traits::DynTypedNode, std::less<>>; + using IDToNodeMap = std::map<std::string, DynTypedNode, std::less<>>; const IDToNodeMap &getMap() const { return NodeMap; @@ -223,7 +235,7 @@ public: }; /// Add a binding from an id to a node. - void setBinding(StringRef Id, const ast_type_traits::DynTypedNode &DynNode) { + void setBinding(StringRef Id, const DynTypedNode &DynNode) { if (Bindings.empty()) Bindings.emplace_back(); for (BoundNodesMap &Binding : Bindings) @@ -280,11 +292,10 @@ public: /// /// May bind \p DynNode to an ID via \p Builder, or recurse into /// the AST via \p Finder. - virtual bool dynMatches(const ast_type_traits::DynTypedNode &DynNode, - ASTMatchFinder *Finder, + virtual bool dynMatches(const DynTypedNode &DynNode, ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder) const = 0; - virtual llvm::Optional<ast_type_traits::TraversalKind> TraversalKind() const { + virtual llvm::Optional<clang::TraversalKind> TraversalKind() const { return llvm::None; } }; @@ -307,8 +318,7 @@ public: ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder) const = 0; - bool dynMatches(const ast_type_traits::DynTypedNode &DynNode, - ASTMatchFinder *Finder, + bool dynMatches(const DynTypedNode &DynNode, ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder) const override { return matches(DynNode.getUnchecked<T>(), Finder, Builder); } @@ -347,7 +357,7 @@ public: /// Takes ownership of the provided implementation pointer. template <typename T> DynTypedMatcher(MatcherInterface<T> *Implementation) - : SupportedKind(ast_type_traits::ASTNodeKind::getFromNodeKind<T>()), + : SupportedKind(ASTNodeKind::getFromNodeKind<T>()), RestrictKind(SupportedKind), Implementation(Implementation) {} /// Construct from a variadic function. @@ -375,40 +385,44 @@ public: }; static DynTypedMatcher - constructVariadic(VariadicOperator Op, - ast_type_traits::ASTNodeKind SupportedKind, + constructVariadic(VariadicOperator Op, ASTNodeKind SupportedKind, std::vector<DynTypedMatcher> InnerMatchers); static DynTypedMatcher constructRestrictedWrapper(const DynTypedMatcher &InnerMatcher, - ast_type_traits::ASTNodeKind RestrictKind); + ASTNodeKind RestrictKind); /// Get a "true" matcher for \p NodeKind. /// /// It only checks that the node is of the right kind. - static DynTypedMatcher trueMatcher(ast_type_traits::ASTNodeKind NodeKind); + static DynTypedMatcher trueMatcher(ASTNodeKind NodeKind); void setAllowBind(bool AB) { AllowBind = AB; } /// Check whether this matcher could ever match a node of kind \p Kind. /// \return \c false if this matcher will never match such a node. Otherwise, /// return \c true. - bool canMatchNodesOfKind(ast_type_traits::ASTNodeKind Kind) const; + bool canMatchNodesOfKind(ASTNodeKind Kind) const; /// Return a matcher that points to the same implementation, but /// restricts the node types for \p Kind. - DynTypedMatcher dynCastTo(const ast_type_traits::ASTNodeKind Kind) const; + DynTypedMatcher dynCastTo(const ASTNodeKind Kind) const; + + /// Return a matcher that that points to the same implementation, but sets the + /// traversal kind. + /// + /// If the traversal kind is already set, then \c TK overrides it. + DynTypedMatcher withTraversalKind(TraversalKind TK); /// Returns true if the matcher matches the given \c DynNode. - bool matches(const ast_type_traits::DynTypedNode &DynNode, - ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder) const; + bool matches(const DynTypedNode &DynNode, ASTMatchFinder *Finder, + BoundNodesTreeBuilder *Builder) const; /// Same as matches(), but skips the kind check. /// /// It is faster, but the caller must ensure the node is valid for the /// kind of this matcher. - bool matchesNoKindCheck(const ast_type_traits::DynTypedNode &DynNode, - ASTMatchFinder *Finder, + bool matchesNoKindCheck(const DynTypedNode &DynNode, ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder) const; /// Bind the specified \p ID to the matcher. @@ -423,7 +437,7 @@ public: /// include both in the ID to make it unique. /// /// \c MatcherIDType supports operator< and provides strict weak ordering. - using MatcherIDType = std::pair<ast_type_traits::ASTNodeKind, uint64_t>; + using MatcherIDType = std::pair<ASTNodeKind, uint64_t>; MatcherIDType getID() const { /// FIXME: Document the requirements this imposes on matcher /// implementations (no new() implementation_ during a Matches()). @@ -435,9 +449,7 @@ public: /// /// \c matches() will always return false unless the node passed is of this /// or a derived type. - ast_type_traits::ASTNodeKind getSupportedKind() const { - return SupportedKind; - } + ASTNodeKind getSupportedKind() const { return SupportedKind; } /// Returns \c true if the passed \c DynTypedMatcher can be converted /// to a \c Matcher<T>. @@ -445,9 +457,9 @@ public: /// This method verifies that the underlying matcher in \c Other can process /// nodes of types T. template <typename T> bool canConvertTo() const { - return canConvertTo(ast_type_traits::ASTNodeKind::getFromNodeKind<T>()); + return canConvertTo(ASTNodeKind::getFromNodeKind<T>()); } - bool canConvertTo(ast_type_traits::ASTNodeKind To) const; + bool canConvertTo(ASTNodeKind To) const; /// Construct a \c Matcher<T> interface around the dynamic matcher. /// @@ -465,37 +477,31 @@ public: /// If it is not compatible, then this matcher will never match anything. template <typename T> Matcher<T> unconditionalConvertTo() const; + /// Returns the \c TraversalKind respected by calls to `match()`, if any. + /// + /// Most matchers will not have a traversal kind set, instead relying on the + /// surrounding context. For those, \c llvm::None is returned. + llvm::Optional<clang::TraversalKind> getTraversalKind() const { + return Implementation->TraversalKind(); + } + private: - DynTypedMatcher(ast_type_traits::ASTNodeKind SupportedKind, - ast_type_traits::ASTNodeKind RestrictKind, - IntrusiveRefCntPtr<DynMatcherInterface> Implementation) - : SupportedKind(SupportedKind), RestrictKind(RestrictKind), - Implementation(std::move(Implementation)) {} + DynTypedMatcher(ASTNodeKind SupportedKind, ASTNodeKind RestrictKind, + IntrusiveRefCntPtr<DynMatcherInterface> Implementation) + : SupportedKind(SupportedKind), RestrictKind(RestrictKind), + Implementation(std::move(Implementation)) {} bool AllowBind = false; - ast_type_traits::ASTNodeKind SupportedKind; + ASTNodeKind SupportedKind; /// A potentially stricter node kind. /// /// It allows to perform implicit and dynamic cast of matchers without /// needing to change \c Implementation. - ast_type_traits::ASTNodeKind RestrictKind; + ASTNodeKind RestrictKind; IntrusiveRefCntPtr<DynMatcherInterface> Implementation; }; -/// Wrapper base class for a wrapping matcher. -/// -/// This is just a container for a DynTypedMatcher that can be used as a base -/// class for another matcher. -template <typename T> -class WrapperMatcherInterface : public MatcherInterface<T> { -protected: - explicit WrapperMatcherInterface(DynTypedMatcher &&InnerMatcher) - : InnerMatcher(std::move(InnerMatcher)) {} - - const DynTypedMatcher InnerMatcher; -}; - /// Wrapper of a MatcherInterface<T> *that allows copying. /// /// A Matcher<Base> can be used anywhere a Matcher<Derived> is @@ -516,11 +522,11 @@ public: /// Requires \c T to be derived from \c From. template <typename From> Matcher(const Matcher<From> &Other, - typename std::enable_if<std::is_base_of<From, T>::value && - !std::is_same<From, T>::value>::type * = nullptr) + std::enable_if_t<std::is_base_of<From, T>::value && + !std::is_same<From, T>::value> * = nullptr) : Implementation(restrictMatcher(Other.Implementation)) { assert(Implementation.getSupportedKind().isSame( - ast_type_traits::ASTNodeKind::getFromNodeKind<T>())); + ASTNodeKind::getFromNodeKind<T>())); } /// Implicitly converts \c Matcher<Type> to \c Matcher<QualType>. @@ -528,9 +534,8 @@ public: /// The resulting matcher is not strict, i.e. ignores qualifiers. template <typename TypeT> Matcher(const Matcher<TypeT> &Other, - typename std::enable_if< - std::is_same<T, QualType>::value && - std::is_same<TypeT, Type>::value>::type* = nullptr) + std::enable_if_t<std::is_same<T, QualType>::value && + std::is_same<TypeT, Type>::value> * = nullptr) : Implementation(new TypeToQualType<TypeT>(Other)) {} /// Convert \c this into a \c Matcher<T> by applying dyn_cast<> to the @@ -546,8 +551,7 @@ public: bool matches(const T &Node, ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder) const { - return Implementation.matches(ast_type_traits::DynTypedNode::create(Node), - Finder, Builder); + return Implementation.matches(DynTypedNode::create(Node), Finder, Builder); } /// Returns an ID that uniquely identifies the matcher. @@ -568,17 +572,19 @@ public: /// does only matches in the absence of qualifiers, or not, i.e. simply /// ignores any qualifiers. template <typename TypeT> - class TypeToQualType : public WrapperMatcherInterface<QualType> { + class TypeToQualType : public MatcherInterface<QualType> { + const DynTypedMatcher InnerMatcher; + public: TypeToQualType(const Matcher<TypeT> &InnerMatcher) - : TypeToQualType::WrapperMatcherInterface(InnerMatcher) {} + : InnerMatcher(InnerMatcher) {} bool matches(const QualType &Node, ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder) const override { if (Node.isNull()) return false; - return this->InnerMatcher.matches( - ast_type_traits::DynTypedNode::create(*Node), Finder, Builder); + return this->InnerMatcher.matches(DynTypedNode::create(*Node), Finder, + Builder); } }; @@ -590,13 +596,13 @@ private: friend class DynTypedMatcher; static DynTypedMatcher restrictMatcher(const DynTypedMatcher &Other) { - return Other.dynCastTo(ast_type_traits::ASTNodeKind::getFromNodeKind<T>()); + return Other.dynCastTo(ASTNodeKind::getFromNodeKind<T>()); } explicit Matcher(const DynTypedMatcher &Implementation) : Implementation(restrictMatcher(Implementation)) { - assert(this->Implementation.getSupportedKind() - .isSame(ast_type_traits::ASTNodeKind::getFromNodeKind<T>())); + assert(this->Implementation.getSupportedKind().isSame( + ASTNodeKind::getFromNodeKind<T>())); } DynTypedMatcher Implementation; @@ -616,9 +622,8 @@ inline Matcher<T> makeMatcher(MatcherInterface<T> *Implementation) { template <> inline Matcher<QualType> DynTypedMatcher::convertTo<QualType>() const { assert(canConvertTo<QualType>()); - const ast_type_traits::ASTNodeKind SourceKind = getSupportedKind(); - if (SourceKind.isSame( - ast_type_traits::ASTNodeKind::getFromNodeKind<Type>())) { + const ASTNodeKind SourceKind = getSupportedKind(); + if (SourceKind.isSame(ASTNodeKind::getFromNodeKind<Type>())) { // We support implicit conversion from Matcher<Type> to Matcher<QualType> return unconditionalConvertTo<Type>(); } @@ -681,12 +686,12 @@ class HasOverloadedOperatorNameMatcher : public SingleNodeMatcherInterface<T> { static_assert(std::is_same<T, CXXOperatorCallExpr>::value || std::is_base_of<FunctionDecl, T>::value, "unsupported class for matcher"); - static_assert(std::is_same<ArgT, StringRef>::value, - "argument type must be StringRef"); + static_assert(std::is_same<ArgT, std::vector<std::string>>::value, + "argument type must be std::vector<std::string>"); public: - explicit HasOverloadedOperatorNameMatcher(const StringRef Name) - : SingleNodeMatcherInterface<T>(), Name(Name) {} + explicit HasOverloadedOperatorNameMatcher(std::vector<std::string> Names) + : SingleNodeMatcherInterface<T>(), Names(std::move(Names)) {} bool matchesNode(const T &Node) const override { return matchesSpecialized(Node); @@ -698,17 +703,18 @@ private: /// so this function returns true if the call is to an operator of the given /// name. bool matchesSpecialized(const CXXOperatorCallExpr &Node) const { - return getOperatorSpelling(Node.getOperator()) == Name; + return llvm::is_contained(Names, getOperatorSpelling(Node.getOperator())); } /// Returns true only if CXXMethodDecl represents an overloaded /// operator and has the given operator name. bool matchesSpecialized(const FunctionDecl &Node) const { return Node.isOverloadedOperator() && - getOperatorSpelling(Node.getOverloadedOperator()) == Name; + llvm::is_contained( + Names, getOperatorSpelling(Node.getOverloadedOperator())); } - std::string Name; + const std::vector<std::string> Names; }; /// Matches named declarations with a specific name. @@ -760,13 +766,15 @@ Matcher<ObjCMessageExpr> hasAnySelectorFunc( /// Type argument DeclMatcherT is required by PolymorphicMatcherWithParam1 but /// not actually used. template <typename T, typename DeclMatcherT> -class HasDeclarationMatcher : public WrapperMatcherInterface<T> { +class HasDeclarationMatcher : public MatcherInterface<T> { static_assert(std::is_same<DeclMatcherT, Matcher<Decl>>::value, "instantiated with wrong types"); + const DynTypedMatcher InnerMatcher; + public: explicit HasDeclarationMatcher(const Matcher<Decl> &InnerMatcher) - : HasDeclarationMatcher::WrapperMatcherInterface(InnerMatcher) {} + : InnerMatcher(InnerMatcher) {} bool matches(const T &Node, ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder) const override { @@ -920,9 +928,8 @@ private: /// is \c NULL. bool matchesDecl(const Decl *Node, ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder) const { - return Node != nullptr && - this->InnerMatcher.matches( - ast_type_traits::DynTypedNode::create(*Node), Finder, Builder); + return Node != nullptr && this->InnerMatcher.matches( + DynTypedNode::create(*Node), Finder, Builder); } }; @@ -1004,8 +1011,8 @@ public: template <typename T> bool matchesChildOf(const T &Node, const DynTypedMatcher &Matcher, - BoundNodesTreeBuilder *Builder, - ast_type_traits::TraversalKind Traverse, BindKind Bind) { + BoundNodesTreeBuilder *Builder, TraversalKind Traverse, + BindKind Bind) { static_assert(std::is_base_of<Decl, T>::value || std::is_base_of<Stmt, T>::value || std::is_base_of<NestedNameSpecifier, T>::value || @@ -1013,8 +1020,8 @@ public: std::is_base_of<TypeLoc, T>::value || std::is_base_of<QualType, T>::value, "unsupported type for recursive matching"); - return matchesChildOf(ast_type_traits::DynTypedNode::create(Node), - getASTContext(), Matcher, Builder, Traverse, Bind); + return matchesChildOf(DynTypedNode::create(Node), getASTContext(), Matcher, + Builder, Traverse, Bind); } template <typename T> @@ -1029,8 +1036,8 @@ public: std::is_base_of<TypeLoc, T>::value || std::is_base_of<QualType, T>::value, "unsupported type for recursive matching"); - return matchesDescendantOf(ast_type_traits::DynTypedNode::create(Node), - getASTContext(), Matcher, Builder, Bind); + return matchesDescendantOf(DynTypedNode::create(Node), getASTContext(), + Matcher, Builder, Bind); } // FIXME: Implement support for BindKind. @@ -1044,27 +1051,24 @@ public: 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), - getASTContext(), Matcher, Builder, MatchMode); + return matchesAncestorOf(DynTypedNode::create(Node), getASTContext(), + Matcher, Builder, MatchMode); } virtual ASTContext &getASTContext() const = 0; protected: - virtual bool matchesChildOf(const ast_type_traits::DynTypedNode &Node, - ASTContext &Ctx, const DynTypedMatcher &Matcher, + virtual bool matchesChildOf(const DynTypedNode &Node, ASTContext &Ctx, + const DynTypedMatcher &Matcher, BoundNodesTreeBuilder *Builder, - ast_type_traits::TraversalKind Traverse, - BindKind Bind) = 0; + TraversalKind Traverse, BindKind Bind) = 0; - virtual bool matchesDescendantOf(const ast_type_traits::DynTypedNode &Node, - ASTContext &Ctx, + virtual bool matchesDescendantOf(const DynTypedNode &Node, ASTContext &Ctx, const DynTypedMatcher &Matcher, BoundNodesTreeBuilder *Builder, BindKind Bind) = 0; - virtual bool matchesAncestorOf(const ast_type_traits::DynTypedNode &Node, - ASTContext &Ctx, + virtual bool matchesAncestorOf(const DynTypedNode &Node, ASTContext &Ctx, const DynTypedMatcher &Matcher, BoundNodesTreeBuilder *Builder, AncestorMatchMode MatchMode) = 0; @@ -1181,43 +1185,40 @@ struct ArgumentAdaptingMatcherFunc { } }; -template <typename T> -class TraversalMatcher : public WrapperMatcherInterface<T> { - ast_type_traits::TraversalKind Traversal; +template <typename T> class TraversalMatcher : public MatcherInterface<T> { + const DynTypedMatcher InnerMatcher; + clang::TraversalKind Traversal; public: - explicit TraversalMatcher(ast_type_traits::TraversalKind TK, - const Matcher<T> &ChildMatcher) - : TraversalMatcher::WrapperMatcherInterface(ChildMatcher), Traversal(TK) { - } + explicit TraversalMatcher(clang::TraversalKind TK, + const Matcher<T> &InnerMatcher) + : InnerMatcher(InnerMatcher), Traversal(TK) {} bool matches(const T &Node, ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder) const override { - return this->InnerMatcher.matches( - ast_type_traits::DynTypedNode::create(Node), Finder, Builder); + return this->InnerMatcher.matches(DynTypedNode::create(Node), Finder, + Builder); } - llvm::Optional<ast_type_traits::TraversalKind> - TraversalKind() const override { + llvm::Optional<clang::TraversalKind> TraversalKind() const override { return Traversal; } }; template <typename MatcherType> class TraversalWrapper { public: - TraversalWrapper(ast_type_traits::TraversalKind TK, - const MatcherType &InnerMatcher) + TraversalWrapper(TraversalKind TK, const MatcherType &InnerMatcher) : TK(TK), InnerMatcher(InnerMatcher) {} template <typename T> operator Matcher<T>() const { return internal::DynTypedMatcher::constructRestrictedWrapper( new internal::TraversalMatcher<T>(TK, InnerMatcher), - ast_type_traits::ASTNodeKind::getFromNodeKind<T>()) + ASTNodeKind::getFromNodeKind<T>()) .template unconditionalConvertTo<T>(); } private: - ast_type_traits::TraversalKind TK; + TraversalKind TK; MatcherType InnerMatcher; }; @@ -1300,8 +1301,7 @@ public: template <typename T> operator Matcher<T>() const { - return DynTypedMatcher::trueMatcher( - ast_type_traits::ASTNodeKind::getFromNodeKind<T>()) + return DynTypedMatcher::trueMatcher(ASTNodeKind::getFromNodeKind<T>()) .template unconditionalConvertTo<T>(); } }; @@ -1341,15 +1341,17 @@ public: /// /// ChildT must be an AST base type. template <typename T, typename ChildT> -class HasMatcher : public WrapperMatcherInterface<T> { +class HasMatcher : public MatcherInterface<T> { + const DynTypedMatcher InnerMatcher; + public: - explicit HasMatcher(const Matcher<ChildT> &ChildMatcher) - : HasMatcher::WrapperMatcherInterface(ChildMatcher) {} + explicit HasMatcher(const Matcher<ChildT> &InnerMatcher) + : InnerMatcher(InnerMatcher) {} bool matches(const T &Node, ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder) const override { return Finder->matchesChildOf(Node, this->InnerMatcher, Builder, - ast_type_traits::TraversalKind::TK_AsIs, + TraversalKind::TK_AsIs, ASTMatchFinder::BK_First); } }; @@ -1360,19 +1362,21 @@ public: /// As opposed to the HasMatcher, the ForEachMatcher will produce a match /// for each child that matches. template <typename T, typename ChildT> -class ForEachMatcher : public WrapperMatcherInterface<T> { +class ForEachMatcher : public MatcherInterface<T> { static_assert(IsBaseType<ChildT>::value, "for each only accepts base type matcher"); - public: - explicit ForEachMatcher(const Matcher<ChildT> &ChildMatcher) - : ForEachMatcher::WrapperMatcherInterface(ChildMatcher) {} + const DynTypedMatcher InnerMatcher; - bool matches(const T& Node, ASTMatchFinder* Finder, - BoundNodesTreeBuilder* Builder) const override { +public: + explicit ForEachMatcher(const Matcher<ChildT> &InnerMatcher) + : InnerMatcher(InnerMatcher) {} + + bool matches(const T &Node, ASTMatchFinder *Finder, + BoundNodesTreeBuilder *Builder) const override { return Finder->matchesChildOf( Node, this->InnerMatcher, Builder, - ast_type_traits::TraversalKind::TK_IgnoreImplicitCastsAndParentheses, + TraversalKind::TK_IgnoreImplicitCastsAndParentheses, ASTMatchFinder::BK_All); } }; @@ -1393,7 +1397,7 @@ public: template <typename T> operator Matcher<T>() const { return DynTypedMatcher::constructVariadic( - Op, ast_type_traits::ASTNodeKind::getFromNodeKind<T>(), + Op, ASTNodeKind::getFromNodeKind<T>(), getMatchers<T>(std::index_sequence_for<Ps...>())) .template unconditionalConvertTo<T>(); } @@ -1449,10 +1453,9 @@ BindableMatcher<T> makeAllOfComposite( std::vector<DynTypedMatcher> DynMatchers(PI(InnerMatchers.begin()), PI(InnerMatchers.end())); return BindableMatcher<T>( - DynTypedMatcher::constructVariadic( - DynTypedMatcher::VO_AllOf, - ast_type_traits::ASTNodeKind::getFromNodeKind<T>(), - std::move(DynMatchers)) + DynTypedMatcher::constructVariadic(DynTypedMatcher::VO_AllOf, + ASTNodeKind::getFromNodeKind<T>(), + std::move(DynMatchers)) .template unconditionalConvertTo<T>()); } @@ -1474,17 +1477,19 @@ BindableMatcher<T> makeDynCastAllOfComposite( /// /// DescendantT must be an AST base type. template <typename T, typename DescendantT> -class HasDescendantMatcher : public WrapperMatcherInterface<T> { +class HasDescendantMatcher : public MatcherInterface<T> { static_assert(IsBaseType<DescendantT>::value, "has descendant only accepts base type matcher"); + const DynTypedMatcher DescendantMatcher; + public: explicit HasDescendantMatcher(const Matcher<DescendantT> &DescendantMatcher) - : HasDescendantMatcher::WrapperMatcherInterface(DescendantMatcher) {} + : DescendantMatcher(DescendantMatcher) {} bool matches(const T &Node, ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder) const override { - return Finder->matchesDescendantOf(Node, this->InnerMatcher, Builder, + return Finder->matchesDescendantOf(Node, this->DescendantMatcher, Builder, ASTMatchFinder::BK_First); } }; @@ -1494,17 +1499,19 @@ public: /// /// \c ParentT must be an AST base type. template <typename T, typename ParentT> -class HasParentMatcher : public WrapperMatcherInterface<T> { +class HasParentMatcher : public MatcherInterface<T> { static_assert(IsBaseType<ParentT>::value, "has parent only accepts base type matcher"); + const DynTypedMatcher ParentMatcher; + public: explicit HasParentMatcher(const Matcher<ParentT> &ParentMatcher) - : HasParentMatcher::WrapperMatcherInterface(ParentMatcher) {} + : ParentMatcher(ParentMatcher) {} bool matches(const T &Node, ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder) const override { - return Finder->matchesAncestorOf(Node, this->InnerMatcher, Builder, + return Finder->matchesAncestorOf(Node, this->ParentMatcher, Builder, ASTMatchFinder::AMM_ParentOnly); } }; @@ -1514,17 +1521,19 @@ public: /// /// \c AncestorT must be an AST base type. template <typename T, typename AncestorT> -class HasAncestorMatcher : public WrapperMatcherInterface<T> { +class HasAncestorMatcher : public MatcherInterface<T> { static_assert(IsBaseType<AncestorT>::value, "has ancestor only accepts base type matcher"); + const DynTypedMatcher AncestorMatcher; + public: explicit HasAncestorMatcher(const Matcher<AncestorT> &AncestorMatcher) - : HasAncestorMatcher::WrapperMatcherInterface(AncestorMatcher) {} + : AncestorMatcher(AncestorMatcher) {} bool matches(const T &Node, ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder) const override { - return Finder->matchesAncestorOf(Node, this->InnerMatcher, Builder, + return Finder->matchesAncestorOf(Node, this->AncestorMatcher, Builder, ASTMatchFinder::AMM_All); } }; @@ -1536,18 +1545,20 @@ public: /// As opposed to HasDescendantMatcher, ForEachDescendantMatcher will match /// for each descendant node that matches instead of only for the first. template <typename T, typename DescendantT> -class ForEachDescendantMatcher : public WrapperMatcherInterface<T> { +class ForEachDescendantMatcher : public MatcherInterface<T> { static_assert(IsBaseType<DescendantT>::value, "for each descendant only accepts base type matcher"); + const DynTypedMatcher DescendantMatcher; + public: explicit ForEachDescendantMatcher( const Matcher<DescendantT> &DescendantMatcher) - : ForEachDescendantMatcher::WrapperMatcherInterface(DescendantMatcher) {} + : DescendantMatcher(DescendantMatcher) {} bool matches(const T &Node, ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder) const override { - return Finder->matchesDescendantOf(Node, this->InnerMatcher, Builder, + return Finder->matchesDescendantOf(Node, this->DescendantMatcher, Builder, ASTMatchFinder::BK_All); } }; @@ -1640,10 +1651,12 @@ public: /// Matches nodes of type \c TLoc for which the inner /// \c Matcher<T> matches. template <typename TLoc, typename T> -class LocMatcher : public WrapperMatcherInterface<TLoc> { +class LocMatcher : public MatcherInterface<TLoc> { + const DynTypedMatcher InnerMatcher; + public: explicit LocMatcher(const Matcher<T> &InnerMatcher) - : LocMatcher::WrapperMatcherInterface(InnerMatcher) {} + : InnerMatcher(InnerMatcher) {} bool matches(const TLoc &Node, ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder) const override { @@ -1653,9 +1666,8 @@ public: } private: - static ast_type_traits::DynTypedNode - extract(const NestedNameSpecifierLoc &Loc) { - return ast_type_traits::DynTypedNode::create(*Loc.getNestedNameSpecifier()); + static DynTypedNode extract(const NestedNameSpecifierLoc &Loc) { + return DynTypedNode::create(*Loc.getNestedNameSpecifier()); } }; @@ -1663,38 +1675,40 @@ private: /// \c QualType. /// /// Used to implement the \c loc() matcher. -class TypeLocTypeMatcher : public WrapperMatcherInterface<TypeLoc> { +class TypeLocTypeMatcher : public MatcherInterface<TypeLoc> { + const DynTypedMatcher InnerMatcher; + public: explicit TypeLocTypeMatcher(const Matcher<QualType> &InnerMatcher) - : TypeLocTypeMatcher::WrapperMatcherInterface(InnerMatcher) {} + : InnerMatcher(InnerMatcher) {} bool matches(const TypeLoc &Node, ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder) const override { if (!Node) return false; - return this->InnerMatcher.matches( - ast_type_traits::DynTypedNode::create(Node.getType()), Finder, Builder); + return this->InnerMatcher.matches(DynTypedNode::create(Node.getType()), + Finder, Builder); } }; /// Matches nodes of type \c T for which the inner matcher matches on a /// another node of type \c T that can be reached using a given traverse /// function. -template <typename T> -class TypeTraverseMatcher : public WrapperMatcherInterface<T> { +template <typename T> class TypeTraverseMatcher : public MatcherInterface<T> { + const DynTypedMatcher InnerMatcher; + public: explicit TypeTraverseMatcher(const Matcher<QualType> &InnerMatcher, QualType (T::*TraverseFunction)() const) - : TypeTraverseMatcher::WrapperMatcherInterface(InnerMatcher), - TraverseFunction(TraverseFunction) {} + : InnerMatcher(InnerMatcher), TraverseFunction(TraverseFunction) {} bool matches(const T &Node, ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder) const override { QualType NextNode = (Node.*TraverseFunction)(); if (NextNode.isNull()) return false; - return this->InnerMatcher.matches( - ast_type_traits::DynTypedNode::create(NextNode), Finder, Builder); + return this->InnerMatcher.matches(DynTypedNode::create(NextNode), Finder, + Builder); } private: @@ -1705,20 +1719,21 @@ private: /// matcher matches on a another node of type \c T that can be reached using a /// given traverse function. template <typename T> -class TypeLocTraverseMatcher : public WrapperMatcherInterface<T> { +class TypeLocTraverseMatcher : public MatcherInterface<T> { + const DynTypedMatcher InnerMatcher; + public: explicit TypeLocTraverseMatcher(const Matcher<TypeLoc> &InnerMatcher, TypeLoc (T::*TraverseFunction)() const) - : TypeLocTraverseMatcher::WrapperMatcherInterface(InnerMatcher), - TraverseFunction(TraverseFunction) {} + : InnerMatcher(InnerMatcher), TraverseFunction(TraverseFunction) {} bool matches(const T &Node, ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder) const override { TypeLoc NextNode = (Node.*TraverseFunction)(); if (!NextNode) return false; - return this->InnerMatcher.matches( - ast_type_traits::DynTypedNode::create(NextNode), Finder, Builder); + return this->InnerMatcher.matches(DynTypedNode::create(NextNode), Finder, + Builder); } private: @@ -1818,7 +1833,7 @@ struct NotEqualsBoundNodePredicate { } std::string ID; - ast_type_traits::DynTypedNode Node; + DynTypedNode Node; }; template <typename Ty> @@ -1872,6 +1887,72 @@ CompoundStmtMatcher<StmtExpr>::get(const StmtExpr &Node) { return Node.getSubStmt(); } +/// If \p Loc is (transitively) expanded from macro \p MacroName, returns the +/// location (in the chain of expansions) at which \p MacroName was +/// expanded. Since the macro may have been expanded inside a series of +/// expansions, that location may itself be a MacroID. +llvm::Optional<SourceLocation> +getExpansionLocOfMacro(StringRef MacroName, SourceLocation Loc, + const ASTContext &Context); + +/// Matches overloaded operators with a specific name. +/// +/// The type argument ArgT is not used by this matcher but is used by +/// PolymorphicMatcherWithParam1 and should be std::vector<std::string>>. +template <typename T, typename ArgT = std::vector<std::string>> +class HasAnyOperatorNameMatcher : public SingleNodeMatcherInterface<T> { + static_assert(std::is_same<T, BinaryOperator>::value || + std::is_same<T, UnaryOperator>::value, + "Matcher only supports `BinaryOperator` and `UnaryOperator`"); + static_assert(std::is_same<ArgT, std::vector<std::string>>::value, + "Matcher ArgT must be std::vector<std::string>"); + +public: + explicit HasAnyOperatorNameMatcher(std::vector<std::string> Names) + : SingleNodeMatcherInterface<T>(), Names(std::move(Names)) {} + + bool matchesNode(const T &Node) const override { + StringRef OpName = getOpName(Node); + return llvm::any_of( + Names, [&](const std::string &Name) { return Name == OpName; }); + } + +private: + static StringRef getOpName(const UnaryOperator &Node) { + return Node.getOpcodeStr(Node.getOpcode()); + } + static StringRef getOpName(const BinaryOperator &Node) { + return Node.getOpcodeStr(); + } + + const std::vector<std::string> Names; +}; + +using HasOpNameMatcher = + PolymorphicMatcherWithParam1<HasAnyOperatorNameMatcher, + std::vector<std::string>, + void(TypeList<BinaryOperator, UnaryOperator>)>; + +HasOpNameMatcher hasAnyOperatorNameFunc(ArrayRef<const StringRef *> NameRefs); + +using HasOverloadOpNameMatcher = PolymorphicMatcherWithParam1< + HasOverloadedOperatorNameMatcher, std::vector<std::string>, + void(TypeList<CXXOperatorCallExpr, FunctionDecl>)>; + +HasOverloadOpNameMatcher +hasAnyOverloadedOperatorNameFunc(ArrayRef<const StringRef *> NameRefs); + +/// Returns true if \p Node has a base specifier matching \p BaseSpec. +/// +/// A class is not considered to be derived from itself. +bool matchesAnyBase(const CXXRecordDecl &Node, + const Matcher<CXXBaseSpecifier> &BaseSpecMatcher, + ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder); + +std::shared_ptr<llvm::Regex> createAndVerifyRegex(StringRef Regex, + llvm::Regex::RegexFlags Flags, + StringRef MatcherID); + } // namespace internal } // namespace ast_matchers diff --git a/clang/include/clang/ASTMatchers/ASTMatchersMacros.h b/clang/include/clang/ASTMatchers/ASTMatchersMacros.h index 1d96ba6231cf..45e8b1a88b81 100644 --- a/clang/include/clang/ASTMatchers/ASTMatchersMacros.h +++ b/clang/include/clang/ASTMatchers/ASTMatchersMacros.h @@ -134,9 +134,8 @@ class matcher_##DefineMatcher##OverloadId##Matcher \ : public ::clang::ast_matchers::internal::MatcherInterface<Type> { \ public: \ - explicit matcher_##DefineMatcher##OverloadId##Matcher( \ - ParamType const &A##Param) \ - : Param(A##Param) {} \ + explicit matcher_##DefineMatcher##OverloadId##Matcher(ParamType A##Param) \ + : Param(std::move(A##Param)) {} \ bool matches(const Type &Node, \ ::clang::ast_matchers::internal::ASTMatchFinder *Finder, \ ::clang::ast_matchers::internal::BoundNodesTreeBuilder \ @@ -147,12 +146,13 @@ }; \ } \ inline ::clang::ast_matchers::internal::Matcher<Type> DefineMatcher( \ - ParamType const &Param) { \ + ParamType Param) { \ return ::clang::ast_matchers::internal::makeMatcher( \ - new internal::matcher_##DefineMatcher##OverloadId##Matcher(Param)); \ + new internal::matcher_##DefineMatcher##OverloadId##Matcher( \ + std::move(Param))); \ } \ - typedef ::clang::ast_matchers::internal::Matcher<Type>( \ - &DefineMatcher##_Type##OverloadId)(ParamType const &Param); \ + typedef ::clang::ast_matchers::internal::Matcher<Type> ( \ + &DefineMatcher##_Type##OverloadId)(ParamType Param); \ inline bool internal::matcher_##DefineMatcher##OverloadId##Matcher::matches( \ const Type &Node, \ ::clang::ast_matchers::internal::ASTMatchFinder *Finder, \ @@ -183,9 +183,9 @@ class matcher_##DefineMatcher##OverloadId##Matcher \ : public ::clang::ast_matchers::internal::MatcherInterface<Type> { \ public: \ - matcher_##DefineMatcher##OverloadId##Matcher(ParamType1 const &A##Param1, \ - ParamType2 const &A##Param2) \ - : Param1(A##Param1), Param2(A##Param2) {} \ + matcher_##DefineMatcher##OverloadId##Matcher(ParamType1 A##Param1, \ + ParamType2 A##Param2) \ + : Param1(std::move(A##Param1)), Param2(std::move(A##Param2)) {} \ bool matches(const Type &Node, \ ::clang::ast_matchers::internal::ASTMatchFinder *Finder, \ ::clang::ast_matchers::internal::BoundNodesTreeBuilder \ @@ -197,14 +197,14 @@ }; \ } \ inline ::clang::ast_matchers::internal::Matcher<Type> DefineMatcher( \ - ParamType1 const &Param1, ParamType2 const &Param2) { \ + ParamType1 Param1, ParamType2 Param2) { \ return ::clang::ast_matchers::internal::makeMatcher( \ - new internal::matcher_##DefineMatcher##OverloadId##Matcher(Param1, \ - Param2)); \ + new internal::matcher_##DefineMatcher##OverloadId##Matcher( \ + std::move(Param1), std::move(Param2))); \ } \ - typedef ::clang::ast_matchers::internal::Matcher<Type>( \ - &DefineMatcher##_Type##OverloadId)(ParamType1 const &Param1, \ - ParamType2 const &Param2); \ + typedef ::clang::ast_matchers::internal::Matcher<Type> ( \ + &DefineMatcher##_Type##OverloadId)(ParamType1 Param1, \ + ParamType2 Param2); \ inline bool internal::matcher_##DefineMatcher##OverloadId##Matcher::matches( \ const Type &Node, \ ::clang::ast_matchers::internal::ASTMatchFinder *Finder, \ @@ -272,9 +272,8 @@ class matcher_##DefineMatcher##OverloadId##Matcher \ : public ::clang::ast_matchers::internal::MatcherInterface<NodeType> { \ public: \ - explicit matcher_##DefineMatcher##OverloadId##Matcher( \ - ParamType const &A##Param) \ - : Param(A##Param) {} \ + explicit matcher_##DefineMatcher##OverloadId##Matcher(ParamType A##Param) \ + : Param(std::move(A##Param)) {} \ bool matches(const NodeType &Node, \ ::clang::ast_matchers::internal::ASTMatchFinder *Finder, \ ::clang::ast_matchers::internal::BoundNodesTreeBuilder \ @@ -287,15 +286,14 @@ inline ::clang::ast_matchers::internal::PolymorphicMatcherWithParam1< \ internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType, \ ReturnTypesF> \ - DefineMatcher(ParamType const &Param) { \ + DefineMatcher(ParamType Param) { \ return ::clang::ast_matchers::internal::PolymorphicMatcherWithParam1< \ internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType, \ - ReturnTypesF>(Param); \ + ReturnTypesF>(std::move(Param)); \ } \ typedef ::clang::ast_matchers::internal::PolymorphicMatcherWithParam1< \ internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType, \ - ReturnTypesF>(&DefineMatcher##_Type##OverloadId)( \ - ParamType const &Param); \ + ReturnTypesF> (&DefineMatcher##_Type##OverloadId)(ParamType Param); \ template <typename NodeType, typename ParamT> \ bool internal:: \ matcher_##DefineMatcher##OverloadId##Matcher<NodeType, ParamT>::matches( \ @@ -325,9 +323,9 @@ class matcher_##DefineMatcher##OverloadId##Matcher \ : public ::clang::ast_matchers::internal::MatcherInterface<NodeType> { \ public: \ - matcher_##DefineMatcher##OverloadId##Matcher(ParamType1 const &A##Param1, \ - ParamType2 const &A##Param2) \ - : Param1(A##Param1), Param2(A##Param2) {} \ + matcher_##DefineMatcher##OverloadId##Matcher(ParamType1 A##Param1, \ + ParamType2 A##Param2) \ + : Param1(std::move(A##Param1)), Param2(std::move(A##Param2)) {} \ bool matches(const NodeType &Node, \ ::clang::ast_matchers::internal::ASTMatchFinder *Finder, \ ::clang::ast_matchers::internal::BoundNodesTreeBuilder \ @@ -341,15 +339,15 @@ inline ::clang::ast_matchers::internal::PolymorphicMatcherWithParam2< \ internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType1, \ ParamType2, ReturnTypesF> \ - DefineMatcher(ParamType1 const &Param1, ParamType2 const &Param2) { \ + DefineMatcher(ParamType1 Param1, ParamType2 Param2) { \ return ::clang::ast_matchers::internal::PolymorphicMatcherWithParam2< \ internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType1, \ - ParamType2, ReturnTypesF>(Param1, Param2); \ + ParamType2, ReturnTypesF>(std::move(Param1), std::move(Param2)); \ } \ typedef ::clang::ast_matchers::internal::PolymorphicMatcherWithParam2< \ internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType1, \ - ParamType2, ReturnTypesF>(&DefineMatcher##_Type##OverloadId)( \ - ParamType1 const &Param1, ParamType2 const &Param2); \ + ParamType2, ReturnTypesF> (&DefineMatcher##_Type##OverloadId)( \ + ParamType1 Param1, ParamType2 Param2); \ template <typename NodeType, typename ParamT1, typename ParamT2> \ bool internal::matcher_##DefineMatcher##OverloadId##Matcher< \ NodeType, ParamT1, ParamT2>:: \ @@ -440,4 +438,122 @@ ReturnTypesF>::Func MatcherName##Loc; \ AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName##Type, ReturnTypesF) +/// AST_MATCHER_REGEX(Type, DefineMatcher, Param) { ... } +/// defines a function named DefineMatcher() that takes a regular expression +/// string paramater and an optional RegexFlags parameter and returns a +/// Matcher<Type> object. +/// +/// The code between the curly braces has access to the following variables: +/// +/// Node: the AST node being matched; its type is Type. +/// Param: a pointer to an \ref llvm::Regex object +/// Finder: an ASTMatchFinder*. +/// Builder: a BoundNodesTreeBuilder*. +/// +/// The code should return true if 'Node' matches. +#define AST_MATCHER_REGEX(Type, DefineMatcher, Param) \ + AST_MATCHER_REGEX_OVERLOAD(Type, DefineMatcher, Param, 0) + +#define AST_MATCHER_REGEX_OVERLOAD(Type, DefineMatcher, Param, OverloadId) \ + namespace internal { \ + class matcher_##DefineMatcher##OverloadId##Matcher \ + : public ::clang::ast_matchers::internal::MatcherInterface<Type> { \ + public: \ + explicit matcher_##DefineMatcher##OverloadId##Matcher( \ + std::shared_ptr<llvm::Regex> RE) \ + : Param(std::move(RE)) {} \ + bool matches(const Type &Node, \ + ::clang::ast_matchers::internal::ASTMatchFinder *Finder, \ + ::clang::ast_matchers::internal::BoundNodesTreeBuilder \ + *Builder) const override; \ + \ + private: \ + std::shared_ptr<llvm::Regex> const Param; \ + }; \ + } \ + inline ::clang::ast_matchers::internal::Matcher<Type> DefineMatcher( \ + llvm::StringRef Param, llvm::Regex::RegexFlags RegexFlags) { \ + return ::clang::ast_matchers::internal::makeMatcher( \ + new internal::matcher_##DefineMatcher##OverloadId##Matcher( \ + ::clang::ast_matchers::internal::createAndVerifyRegex( \ + Param, RegexFlags, #DefineMatcher))); \ + } \ + inline ::clang::ast_matchers::internal::Matcher<Type> DefineMatcher( \ + llvm::StringRef Param) { \ + return DefineMatcher(Param, llvm::Regex::NoFlags); \ + } \ + \ + typedef ::clang::ast_matchers::internal::Matcher<Type> ( \ + &DefineMatcher##_Type##OverloadId##Flags)(llvm::StringRef, \ + llvm::Regex::RegexFlags); \ + typedef ::clang::ast_matchers::internal::Matcher<Type> ( \ + &DefineMatcher##_Type##OverloadId)(llvm::StringRef); \ + inline bool internal::matcher_##DefineMatcher##OverloadId##Matcher::matches( \ + const Type &Node, \ + ::clang::ast_matchers::internal::ASTMatchFinder *Finder, \ + ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const + +/// AST_POLYMORPHIC_MATCHER_REGEX(DefineMatcher, ReturnTypesF, Param) { ... } +/// defines a function named DefineMatcher() that takes a regular expression +/// string paramater and an optional RegexFlags parameter that is polymorphic in +/// the return type. +/// +/// The variables are the same as for +/// AST_MATCHER_REGEX, with the addition of NodeType, which specifies the node +/// type of the matcher Matcher<NodeType> returned by the function matcher(). +#define AST_POLYMORPHIC_MATCHER_REGEX(DefineMatcher, ReturnTypesF, Param) \ + AST_POLYMORPHIC_MATCHER_REGEX_OVERLOAD(DefineMatcher, ReturnTypesF, Param, 0) + +#define AST_POLYMORPHIC_MATCHER_REGEX_OVERLOAD(DefineMatcher, ReturnTypesF, \ + Param, OverloadId) \ + namespace internal { \ + template <typename NodeType, typename ParamT> \ + class matcher_##DefineMatcher##OverloadId##Matcher \ + : public ::clang::ast_matchers::internal::MatcherInterface<NodeType> { \ + public: \ + explicit matcher_##DefineMatcher##OverloadId##Matcher( \ + std::shared_ptr<llvm::Regex> RE) \ + : Param(std::move(RE)) {} \ + bool matches(const NodeType &Node, \ + ::clang::ast_matchers::internal::ASTMatchFinder *Finder, \ + ::clang::ast_matchers::internal::BoundNodesTreeBuilder \ + *Builder) const override; \ + \ + private: \ + std::shared_ptr<llvm::Regex> const Param; \ + }; \ + } \ + inline ::clang::ast_matchers::internal::PolymorphicMatcherWithParam1< \ + internal::matcher_##DefineMatcher##OverloadId##Matcher, \ + std::shared_ptr<llvm::Regex>, ReturnTypesF> \ + DefineMatcher(llvm::StringRef Param, llvm::Regex::RegexFlags RegexFlags) { \ + return ::clang::ast_matchers::internal::PolymorphicMatcherWithParam1< \ + internal::matcher_##DefineMatcher##OverloadId##Matcher, \ + std::shared_ptr<llvm::Regex>, ReturnTypesF>( \ + ::clang::ast_matchers::internal::createAndVerifyRegex( \ + Param, RegexFlags, #DefineMatcher)); \ + } \ + inline ::clang::ast_matchers::internal::PolymorphicMatcherWithParam1< \ + internal::matcher_##DefineMatcher##OverloadId##Matcher, \ + std::shared_ptr<llvm::Regex>, ReturnTypesF> \ + DefineMatcher(llvm::StringRef Param) { \ + return DefineMatcher(Param, llvm::Regex::NoFlags); \ + } \ + typedef ::clang::ast_matchers::internal::PolymorphicMatcherWithParam1< \ + internal::matcher_##DefineMatcher##OverloadId##Matcher, \ + std::shared_ptr<llvm::Regex>, ReturnTypesF> ( \ + &DefineMatcher##_Type##OverloadId##Flags)( \ + llvm::StringRef Param, llvm::Regex::RegexFlags RegexFlags); \ + typedef ::clang::ast_matchers::internal::PolymorphicMatcherWithParam1< \ + internal::matcher_##DefineMatcher##OverloadId##Matcher, \ + std::shared_ptr<llvm::Regex>, ReturnTypesF> ( \ + &DefineMatcher##_Type##OverloadId)(llvm::StringRef Param); \ + template <typename NodeType, typename ParamT> \ + bool internal:: \ + matcher_##DefineMatcher##OverloadId##Matcher<NodeType, ParamT>::matches( \ + const NodeType &Node, \ + ::clang::ast_matchers::internal::ASTMatchFinder *Finder, \ + ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder) \ + const + #endif // LLVM_CLANG_ASTMATCHERS_ASTMATCHERSMACROS_H diff --git a/clang/include/clang/ASTMatchers/Dynamic/Diagnostics.h b/clang/include/clang/ASTMatchers/Dynamic/Diagnostics.h index 7dd304797c4f..f095dcdd60b0 100644 --- a/clang/include/clang/ASTMatchers/Dynamic/Diagnostics.h +++ b/clang/include/clang/ASTMatchers/Dynamic/Diagnostics.h @@ -65,6 +65,7 @@ public: ET_RegistryNotBindable = 4, ET_RegistryAmbiguousOverload = 5, ET_RegistryValueNotFound = 6, + ET_RegistryUnknownEnumWithReplace = 7, ET_ParserStringError = 100, ET_ParserNoOpenParen = 101, diff --git a/clang/include/clang/ASTMatchers/Dynamic/VariantValue.h b/clang/include/clang/ASTMatchers/Dynamic/VariantValue.h index 511472a4157c..e47b42a4f38c 100644 --- a/clang/include/clang/ASTMatchers/Dynamic/VariantValue.h +++ b/clang/include/clang/ASTMatchers/Dynamic/VariantValue.h @@ -1,4 +1,5 @@ -//===--- VariantValue.h - Polymorphic value type -*- C++ -*-===/ +//===--- VariantValue.h - Polymorphic value type ----------------*- C++ -*-===// +// // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception @@ -43,11 +44,10 @@ class ArgKind { ArgKind(Kind K) : K(K) { assert(K != AK_Matcher); } /// Constructor for matcher types. - ArgKind(ast_type_traits::ASTNodeKind MatcherKind) - : K(AK_Matcher), MatcherKind(MatcherKind) {} + ArgKind(ASTNodeKind MatcherKind) : K(AK_Matcher), MatcherKind(MatcherKind) {} Kind getArgKind() const { return K; } - ast_type_traits::ASTNodeKind getMatcherKind() const { + ASTNodeKind getMatcherKind() const { assert(K == AK_Matcher); return MatcherKind; } @@ -71,7 +71,7 @@ class ArgKind { private: Kind K; - ast_type_traits::ASTNodeKind MatcherKind; + ASTNodeKind MatcherKind; }; using ast_matchers::internal::DynTypedMatcher; @@ -93,7 +93,7 @@ class VariantMatcher { /// Methods that depend on T from hasTypedMatcher/getTypedMatcher. class MatcherOps { public: - MatcherOps(ast_type_traits::ASTNodeKind NodeKind) : NodeKind(NodeKind) {} + MatcherOps(ASTNodeKind NodeKind) : NodeKind(NodeKind) {} bool canConstructFrom(const DynTypedMatcher &Matcher, bool &IsExactMatch) const; @@ -114,7 +114,7 @@ class VariantMatcher { ~MatcherOps() = default; private: - ast_type_traits::ASTNodeKind NodeKind; + ASTNodeKind NodeKind; }; /// Payload interface to be specialized by each matcher type. @@ -127,7 +127,7 @@ class VariantMatcher { virtual std::string getTypeAsString() const = 0; virtual llvm::Optional<DynTypedMatcher> getTypedMatcher(const MatcherOps &Ops) const = 0; - virtual bool isConvertibleTo(ast_type_traits::ASTNodeKind Kind, + virtual bool isConvertibleTo(ASTNodeKind Kind, unsigned *Specificity) const = 0; }; @@ -184,8 +184,7 @@ public: /// /// \param Specificity value corresponding to the "specificity" of the /// conversion. - bool isConvertibleTo(ast_type_traits::ASTNodeKind Kind, - unsigned *Specificity) const { + bool isConvertibleTo(ASTNodeKind Kind, unsigned *Specificity) const { if (Value) return Value->isConvertibleTo(Kind, Specificity); return false; @@ -223,8 +222,7 @@ private: template <typename T> struct VariantMatcher::TypedMatcherOps final : VariantMatcher::MatcherOps { - TypedMatcherOps() - : MatcherOps(ast_type_traits::ASTNodeKind::getFromNodeKind<T>()) {} + TypedMatcherOps() : MatcherOps(ASTNodeKind::getFromNodeKind<T>()) {} typedef ast_matchers::internal::Matcher<T> MatcherT; DynTypedMatcher diff --git a/clang/include/clang/ASTMatchers/GtestMatchers.h b/clang/include/clang/ASTMatchers/GtestMatchers.h new file mode 100644 index 000000000000..4f8addcf744a --- /dev/null +++ b/clang/include/clang/ASTMatchers/GtestMatchers.h @@ -0,0 +1,45 @@ +//===- GtestMatchers.h - AST Matchers for GTest -----------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file implements matchers specific to structures in the Googletest +// (gtest) framework. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_ASTMATCHERS_GTESTMATCHERS_H +#define LLVM_CLANG_ASTMATCHERS_GTESTMATCHERS_H + +#include "clang/AST/Stmt.h" +#include "clang/ASTMatchers/ASTMatchers.h" + +namespace clang { +namespace ast_matchers { + +/// Gtest's comparison operations. +enum class GtestCmp { + Eq, + Ne, + Ge, + Gt, + Le, + Lt, +}; + +/// Matcher for gtest's ASSERT_... macros. +internal::BindableMatcher<Stmt> gtestAssert(GtestCmp Cmp, StatementMatcher Left, + StatementMatcher Right); + +/// Matcher for gtest's EXPECT_... macros. +internal::BindableMatcher<Stmt> gtestExpect(GtestCmp Cmp, StatementMatcher Left, + StatementMatcher Right); + +} // namespace ast_matchers +} // namespace clang + +#endif // LLVM_CLANG_ASTMATCHERS_GTESTMATCHERS_H + diff --git a/clang/include/clang/Analysis/Analyses/Dominators.h b/clang/include/clang/Analysis/Analyses/Dominators.h index 061c98137da2..95a661138df4 100644 --- a/clang/include/clang/Analysis/Analyses/Dominators.h +++ b/clang/include/clang/Analysis/Analyses/Dominators.h @@ -167,9 +167,7 @@ public: } /// Releases the memory held by the dominator tree. - virtual void releaseMemory() { - DT.releaseMemory(); - } + virtual void releaseMemory() { DT.reset(); } /// Converts the dominator tree to human readable form. virtual void print(raw_ostream &OS, const llvm::Module* M= nullptr) const { @@ -351,7 +349,7 @@ ClangCFGPostDomReverseChildrenGetter::Get( /// template <> struct GraphTraits<clang::DomTreeNode *> { using NodeRef = ::clang::DomTreeNode *; - using ChildIteratorType = ::clang::DomTreeNode::iterator; + using ChildIteratorType = ::clang::DomTreeNode::const_iterator; static NodeRef getEntryNode(NodeRef N) { return N; } static ChildIteratorType child_begin(NodeRef N) { return N->begin(); } diff --git a/clang/include/clang/Analysis/Analyses/LiveVariables.h b/clang/include/clang/Analysis/Analyses/LiveVariables.h index a46c35ee5b30..2e7dd5d81678 100644 --- a/clang/include/clang/Analysis/Analyses/LiveVariables.h +++ b/clang/include/clang/Analysis/Analyses/LiveVariables.h @@ -70,8 +70,8 @@ public: ~LiveVariables() override; /// Compute the liveness information for a given CFG. - static LiveVariables *computeLiveness(AnalysisDeclContext &analysisContext, - bool killAtAssign); + static std::unique_ptr<LiveVariables> + computeLiveness(AnalysisDeclContext &analysisContext, bool killAtAssign); /// Return true if a variable is live at the end of a /// specified block. @@ -97,7 +97,8 @@ public: void runOnAllBlocks(Observer &obs); - static LiveVariables *create(AnalysisDeclContext &analysisContext) { + static std::unique_ptr<LiveVariables> + create(AnalysisDeclContext &analysisContext) { return computeLiveness(analysisContext, true); } @@ -110,7 +111,8 @@ private: class RelaxedLiveVariables : public LiveVariables { public: - static LiveVariables *create(AnalysisDeclContext &analysisContext) { + static std::unique_ptr<LiveVariables> + create(AnalysisDeclContext &analysisContext) { return computeLiveness(analysisContext, false); } diff --git a/clang/include/clang/Analysis/Analyses/PostOrderCFGView.h b/clang/include/clang/Analysis/Analyses/PostOrderCFGView.h index 08fda0982df4..100029894560 100644 --- a/clang/include/clang/Analysis/Analyses/PostOrderCFGView.h +++ b/clang/include/clang/Analysis/Analyses/PostOrderCFGView.h @@ -108,7 +108,8 @@ public: // Used by AnalyisContext to construct this object. static const void *getTag(); - static PostOrderCFGView *create(AnalysisDeclContext &analysisContext); + static std::unique_ptr<PostOrderCFGView> + create(AnalysisDeclContext &analysisContext); }; } // namespace clang diff --git a/clang/include/clang/Analysis/Analyses/ThreadSafety.h b/clang/include/clang/Analysis/Analyses/ThreadSafety.h index 18659aa4e5bb..0d3dda1256fb 100644 --- a/clang/include/clang/Analysis/Analyses/ThreadSafety.h +++ b/clang/include/clang/Analysis/Analyses/ThreadSafety.h @@ -108,8 +108,10 @@ public: /// \param LockName -- A StringRef name for the lock expression, to be printed /// in the error message. /// \param Loc -- The SourceLocation of the Unlock + /// \param LocPreviousUnlock -- If valid, the location of a previous Unlock. virtual void handleUnmatchedUnlock(StringRef Kind, Name LockName, - SourceLocation Loc) {} + SourceLocation Loc, + SourceLocation LocPreviousUnlock) {} /// Warn about an unlock function call that attempts to unlock a lock with /// the incorrect lock kind. For instance, a shared lock being unlocked diff --git a/clang/include/clang/Analysis/Analyses/UninitializedValues.h b/clang/include/clang/Analysis/Analyses/UninitializedValues.h index 479be1fec048..a2b37deddcec 100644 --- a/clang/include/clang/Analysis/Analyses/UninitializedValues.h +++ b/clang/include/clang/Analysis/Analyses/UninitializedValues.h @@ -110,6 +110,10 @@ public: virtual void handleUseOfUninitVariable(const VarDecl *vd, const UninitUse &use) {} + /// Called when the uninitialized variable is used as const refernce argument. + virtual void handleConstRefUseOfUninitVariable(const VarDecl *vd, + const UninitUse &use) {} + /// Called when the uninitialized variable analysis detects the /// idiom 'int x = x'. All other uses of 'x' within the initializer /// are handled by handleUseOfUninitVariable. diff --git a/clang/include/clang/Analysis/AnalysisDeclContext.h b/clang/include/clang/Analysis/AnalysisDeclContext.h index 9faa78cde89c..d12582f4f329 100644 --- a/clang/include/clang/Analysis/AnalysisDeclContext.h +++ b/clang/include/clang/Analysis/AnalysisDeclContext.h @@ -1,4 +1,4 @@ -// AnalysisDeclContext.h - Analysis context for Path Sens analysis -*- C++ -*-// +//===- AnalysisDeclContext.h - Context for path sensitivity -----*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,8 +6,11 @@ // //===----------------------------------------------------------------------===// // -// This file defines AnalysisDeclContext, a class that manages the analysis -// context data for path sensitive analysis. +/// \file +/// This file defines AnalysisDeclContext, a class that manages the analysis +/// context data for context sensitive and path sensitive analysis. +/// It also defines the helper classes to model entering, leaving or inlining +/// function calls. // //===----------------------------------------------------------------------===// @@ -64,14 +67,14 @@ public: // which creates the analysis object given an AnalysisDeclContext. }; -/// AnalysisDeclContext contains the context data for the function or method -/// under analysis. +/// AnalysisDeclContext contains the context data for the function, method +/// or block under analysis. class AnalysisDeclContext { - /// Backpoint to the AnalysisManager object that created this - /// AnalysisDeclContext. This may be null. - AnalysisDeclContextManager *Manager; + // Backpoint to the AnalysisManager object that created this + // AnalysisDeclContext. This may be null. + AnalysisDeclContextManager *ADCMgr; - const Decl * const D; + const Decl *const D; std::unique_ptr<CFG> cfg, completeCFG; std::unique_ptr<CFGStmtMap> cfgStmtMap; @@ -86,45 +89,36 @@ class AnalysisDeclContext { llvm::BumpPtrAllocator A; - llvm::DenseMap<const BlockDecl *,void *> *ReferencedBlockVars = nullptr; + llvm::DenseMap<const BlockDecl *, void *> *ReferencedBlockVars = nullptr; void *ManagedAnalyses = nullptr; public: - AnalysisDeclContext(AnalysisDeclContextManager *Mgr, - const Decl *D); + AnalysisDeclContext(AnalysisDeclContextManager *Mgr, const Decl *D); - AnalysisDeclContext(AnalysisDeclContextManager *Mgr, - const Decl *D, - const CFG::BuildOptions &BuildOptions); + AnalysisDeclContext(AnalysisDeclContextManager *Mgr, const Decl *D, + const CFG::BuildOptions &BuildOptions); ~AnalysisDeclContext(); ASTContext &getASTContext() const { return D->getASTContext(); } + const Decl *getDecl() const { return D; } - /// Return the AnalysisDeclContextManager (if any) that created - /// this AnalysisDeclContext. - AnalysisDeclContextManager *getManager() const { - return Manager; - } + AnalysisDeclContextManager *getManager() const { return ADCMgr; } - /// Return the build options used to construct the CFG. - CFG::BuildOptions &getCFGBuildOptions() { - return cfgBuildOptions; - } + CFG::BuildOptions &getCFGBuildOptions() { return cfgBuildOptions; } const CFG::BuildOptions &getCFGBuildOptions() const { return cfgBuildOptions; } - /// getAddEHEdges - Return true iff we are adding exceptional edges from - /// callExprs. If this is false, then try/catch statements and blocks - /// reachable from them can appear to be dead in the CFG, analysis passes must - /// cope with that. + /// \returns Whether we are adding exception handling edges from CallExprs. + /// If this is false, then try/catch statements and blocks reachable from them + /// can appear to be dead in the CFG, analysis passes must cope with that. bool getAddEHEdges() const { return cfgBuildOptions.AddEHEdges; } bool getUseUnoptimizedCFG() const { - return !cfgBuildOptions.PruneTriviallyFalseEdges; + return !cfgBuildOptions.PruneTriviallyFalseEdges; } bool getAddImplicitDtors() const { return cfgBuildOptions.AddImplicitDtors; } bool getAddInitializers() const { return cfgBuildOptions.AddInitializers; } @@ -132,25 +126,25 @@ public: void registerForcedBlockExpression(const Stmt *stmt); const CFGBlock *getBlockForRegisteredExpression(const Stmt *stmt); - /// Get the body of the Declaration. + /// \returns The body of the stored Decl \c D. Stmt *getBody() const; - /// Get the body of the Declaration. + /// \copydoc AnalysisDeclContext::getBody() /// \param[out] IsAutosynthesized Specifies if the body is auto-generated /// by the BodyFarm. Stmt *getBody(bool &IsAutosynthesized) const; - /// Checks if the body of the Decl is generated by the BodyFarm. + /// \returns Whether the body of the Decl \c D is generated by the BodyFarm. /// - /// Note, the lookup is not free. We are going to call getBody behind + /// \note The lookup is not free. We are going to call getBody behind /// the scenes. /// \sa getBody bool isBodyAutosynthesized() const; - /// Checks if the body of the Decl is generated by the BodyFarm from a - /// model file. + /// \returns Whether the body of the Decl \c D is generated by the BodyFarm + /// from a model file. /// - /// Note, the lookup is not free. We are going to call getBody behind + /// \note The lookup is not free. We are going to call getBody behind /// the scenes. /// \sa getBody bool isBodyAutosynthesizedFromModelFile() const; @@ -161,61 +155,64 @@ public: CFGReverseBlockReachabilityAnalysis *getCFGReachablityAnalysis(); - /// Return a version of the CFG without any edges pruned. + /// \returns A version of the CFG without any edges pruned. CFG *getUnoptimizedCFG(); void dumpCFG(bool ShowColors); - /// Returns true if we have built a CFG for this analysis context. - /// Note that this doesn't correspond to whether or not a valid CFG exists, it + /// \returns Whether we have built a CFG for this analysis context. + /// + /// \note This doesn't correspond to whether or not a valid CFG exists, it /// corresponds to whether we *attempted* to build one. bool isCFGBuilt() const { return builtCFG; } ParentMap &getParentMap(); - using referenced_decls_iterator = const VarDecl * const *; + using referenced_decls_iterator = const VarDecl *const *; llvm::iterator_range<referenced_decls_iterator> getReferencedBlockVars(const BlockDecl *BD); - /// Return the ImplicitParamDecl* associated with 'self' if this - /// AnalysisDeclContext wraps an ObjCMethodDecl. Returns NULL otherwise. + /// \returns The ImplicitParamDecl associated with \c self if this + /// AnalysisDeclContext wraps an ObjCMethodDecl or nullptr otherwise. const ImplicitParamDecl *getSelfDecl() const; - const StackFrameContext *getStackFrame(LocationContext const *Parent, + /// \copydoc LocationContextManager::getStackFrame() + const StackFrameContext *getStackFrame(LocationContext const *ParentLC, const Stmt *S, const CFGBlock *Blk, - unsigned BlockCount, unsigned Idx); + unsigned BlockCount, unsigned Index); + /// \copydoc LocationContextManager::getBlockInvocationContext() const BlockInvocationContext * - getBlockInvocationContext(const LocationContext *parent, - const BlockDecl *BD, - const void *ContextData); - - /// Return the specified analysis object, lazily running the analysis if - /// necessary. Return NULL if the analysis could not run. - template <typename T> - T *getAnalysis() { + getBlockInvocationContext(const LocationContext *ParentLC, + const BlockDecl *BD, const void *Data); + + /// \returns The specified analysis object, lazily running the analysis if + /// necessary or nullptr if the analysis could not run. + template <typename T> T *getAnalysis() { const void *tag = T::getTag(); - ManagedAnalysis *&data = getAnalysisImpl(tag); - if (!data) { + std::unique_ptr<ManagedAnalysis> &data = getAnalysisImpl(tag); + if (!data) data = T::create(*this); - } - return static_cast<T *>(data); + return static_cast<T *>(data.get()); } - /// Returns true if the root namespace of the given declaration is the 'std' - /// C++ namespace. + /// \returns Whether the root namespace of \p D is the \c std C++ namespace. static bool isInStdNamespace(const Decl *D); private: - ManagedAnalysis *&getAnalysisImpl(const void* tag); + std::unique_ptr<ManagedAnalysis> &getAnalysisImpl(const void *tag); LocationContextManager &getLocationContextManager(); }; +/// It wraps the AnalysisDeclContext to represent both the call stack with +/// the help of StackFrameContext and inside the function calls the +/// BlockInvocationContext. It is needed for context sensitive analysis to +/// model entering, leaving or inlining function calls. class LocationContext : public llvm::FoldingSetNode { public: - enum ContextKind { StackFrame, Scope, Block }; + enum ContextKind { StackFrame, Block }; private: ContextKind Kind; @@ -229,8 +226,7 @@ private: protected: LocationContext(ContextKind k, AnalysisDeclContext *ctx, - const LocationContext *parent, - int64_t ID) + const LocationContext *parent, int64_t ID) : Kind(k), Ctx(ctx), Parent(parent), ID(ID) {} public: @@ -238,9 +234,7 @@ public: ContextKind getKind() const { return Kind; } - int64_t getID() const { - return ID; - } + int64_t getID() const { return ID; } AnalysisDeclContext *getAnalysisDeclContext() const { return Ctx; } @@ -248,58 +242,61 @@ public: bool isParentOf(const LocationContext *LC) const; - const Decl *getDecl() const { return getAnalysisDeclContext()->getDecl(); } + const Decl *getDecl() const { return Ctx->getDecl(); } - CFG *getCFG() const { return getAnalysisDeclContext()->getCFG(); } + CFG *getCFG() const { return Ctx->getCFG(); } - template <typename T> - T *getAnalysis() const { - return getAnalysisDeclContext()->getAnalysis<T>(); - } + template <typename T> T *getAnalysis() const { return Ctx->getAnalysis<T>(); } - const ParentMap &getParentMap() const { - return getAnalysisDeclContext()->getParentMap(); - } + const ParentMap &getParentMap() const { return Ctx->getParentMap(); } - const ImplicitParamDecl *getSelfDecl() const { - return Ctx->getSelfDecl(); - } + /// \copydoc AnalysisDeclContext::getSelfDecl() + const ImplicitParamDecl *getSelfDecl() const { return Ctx->getSelfDecl(); } const StackFrameContext *getStackFrame() const; - /// Return true if the current LocationContext has no caller context. + /// \returns Whether the current LocationContext has no caller context. virtual bool inTopFrame() const; virtual void Profile(llvm::FoldingSetNodeID &ID) = 0; - void dumpStack( - raw_ostream &Out, const char *NL = "\n", - std::function<void(const LocationContext *)> printMoreInfoPerContext = - [](const LocationContext *) {}) const; + /// Prints out the call stack. + /// + /// \param Out The out stream. + LLVM_DUMP_METHOD void dumpStack(raw_ostream &Out) const; + /// Prints out the call stack in \c json format. + /// + /// \param Out The out stream. + /// \param NL The newline. + /// \param Space The space count for indentation. + /// \param IsDot Whether the output format is \c dot. + /// \param printMoreInfoPerContext + /// A callback to print more information for each context, for example: + /// \code + /// [&](const LocationContext *LC) { LC->dump(); } + /// \endcode void printJson( raw_ostream &Out, const char *NL = "\n", unsigned int Space = 0, bool IsDot = false, std::function<void(const LocationContext *)> printMoreInfoPerContext = [](const LocationContext *) {}) const; - void dump() const; + LLVM_DUMP_METHOD void dump() const; -public: - static void ProfileCommon(llvm::FoldingSetNodeID &ID, - ContextKind ck, + static void ProfileCommon(llvm::FoldingSetNodeID &ID, ContextKind ck, AnalysisDeclContext *ctx, - const LocationContext *parent, - const void *data); + const LocationContext *parent, const void *data); }; +/// It represents a stack frame of the call stack (based on CallEvent). class StackFrameContext : public LocationContext { friend class LocationContextManager; - // The callsite where this stack frame is established. + // The call site where this stack frame is established. const Stmt *CallSite; - // The parent block of the callsite. + // The parent block of the call site. const CFGBlock *Block; // The number of times the 'Block' has been visited. @@ -307,14 +304,14 @@ class StackFrameContext : public LocationContext { // called multiple times in a loop. const unsigned BlockCount; - // The index of the callsite in the CFGBlock. + // The index of the call site in the CFGBlock. const unsigned Index; - StackFrameContext(AnalysisDeclContext *ctx, const LocationContext *parent, - const Stmt *s, const CFGBlock *blk, unsigned blockCount, - unsigned idx, int64_t ID) - : LocationContext(StackFrame, ctx, parent, ID), CallSite(s), Block(blk), - BlockCount(blockCount), Index(idx) {} + StackFrameContext(AnalysisDeclContext *ADC, const LocationContext *ParentLC, + const Stmt *S, const CFGBlock *Block, unsigned BlockCount, + unsigned Index, int64_t ID) + : LocationContext(StackFrame, ADC, ParentLC, ID), CallSite(S), + Block(Block), BlockCount(BlockCount), Index(Index) {} public: ~StackFrameContext() override = default; @@ -323,117 +320,100 @@ public: const CFGBlock *getCallSiteBlock() const { return Block; } - /// Return true if the current LocationContext has no caller context. - bool inTopFrame() const override { return getParent() == nullptr; } + bool inTopFrame() const override { return getParent() == nullptr; } unsigned getIndex() const { return Index; } + CFGElement getCallSiteCFGElement() const { return (*Block)[Index]; } + void Profile(llvm::FoldingSetNodeID &ID) override; - static void Profile(llvm::FoldingSetNodeID &ID, AnalysisDeclContext *ctx, - const LocationContext *parent, const Stmt *s, - const CFGBlock *blk, unsigned blockCount, unsigned idx) { - ProfileCommon(ID, StackFrame, ctx, parent, s); - ID.AddPointer(blk); - ID.AddInteger(blockCount); - ID.AddInteger(idx); + static void Profile(llvm::FoldingSetNodeID &ID, AnalysisDeclContext *ADC, + const LocationContext *ParentLC, const Stmt *S, + const CFGBlock *Block, unsigned BlockCount, + unsigned Index) { + ProfileCommon(ID, StackFrame, ADC, ParentLC, S); + ID.AddPointer(Block); + ID.AddInteger(BlockCount); + ID.AddInteger(Index); } - static bool classof(const LocationContext *Ctx) { - return Ctx->getKind() == StackFrame; - } -}; - -class ScopeContext : public LocationContext { - friend class LocationContextManager; - - const Stmt *Enter; - - ScopeContext(AnalysisDeclContext *ctx, const LocationContext *parent, - const Stmt *s, int64_t ID) - : LocationContext(Scope, ctx, parent, ID), Enter(s) {} - -public: - ~ScopeContext() override = default; - - void Profile(llvm::FoldingSetNodeID &ID) override; - - static void Profile(llvm::FoldingSetNodeID &ID, AnalysisDeclContext *ctx, - const LocationContext *parent, const Stmt *s) { - ProfileCommon(ID, Scope, ctx, parent, s); - } - - static bool classof(const LocationContext *Ctx) { - return Ctx->getKind() == Scope; + static bool classof(const LocationContext *LC) { + return LC->getKind() == StackFrame; } }; +/// It represents a block invocation (based on BlockCall). class BlockInvocationContext : public LocationContext { friend class LocationContextManager; const BlockDecl *BD; // FIXME: Come up with a more type-safe way to model context-sensitivity. - const void *ContextData; + const void *Data; - BlockInvocationContext(AnalysisDeclContext *ctx, - const LocationContext *parent, const BlockDecl *bd, - const void *contextData, int64_t ID) - : LocationContext(Block, ctx, parent, ID), BD(bd), - ContextData(contextData) {} + BlockInvocationContext(AnalysisDeclContext *ADC, + const LocationContext *ParentLC, const BlockDecl *BD, + const void *Data, int64_t ID) + : LocationContext(Block, ADC, ParentLC, ID), BD(BD), Data(Data) {} public: ~BlockInvocationContext() override = default; const BlockDecl *getBlockDecl() const { return BD; } - const void *getContextData() const { return ContextData; } + const void *getData() const { return Data; } void Profile(llvm::FoldingSetNodeID &ID) override; - static void Profile(llvm::FoldingSetNodeID &ID, AnalysisDeclContext *ctx, - const LocationContext *parent, const BlockDecl *bd, - const void *contextData) { - ProfileCommon(ID, Block, ctx, parent, bd); - ID.AddPointer(contextData); + static void Profile(llvm::FoldingSetNodeID &ID, AnalysisDeclContext *ADC, + const LocationContext *ParentLC, const BlockDecl *BD, + const void *Data) { + ProfileCommon(ID, Block, ADC, ParentLC, BD); + ID.AddPointer(Data); } - static bool classof(const LocationContext *Ctx) { - return Ctx->getKind() == Block; + static bool classof(const LocationContext *LC) { + return LC->getKind() == Block; } }; class LocationContextManager { llvm::FoldingSet<LocationContext> Contexts; - /// ID used for generating a new location context. + // ID used for generating a new location context. int64_t NewID = 0; public: ~LocationContextManager(); - const StackFrameContext *getStackFrame(AnalysisDeclContext *ctx, - const LocationContext *parent, - const Stmt *s, const CFGBlock *blk, - unsigned blockCount, unsigned idx); - - const ScopeContext *getScope(AnalysisDeclContext *ctx, - const LocationContext *parent, - const Stmt *s); - + /// Obtain a context of the call stack using its parent context. + /// + /// \param ADC The AnalysisDeclContext. + /// \param ParentLC The parent context of this newly created context. + /// \param S The call. + /// \param Block The basic block. + /// \param BlockCount The current count of entering into \p Blk. + /// \param Index The index of \p Blk. + /// \returns The context for \p D with parent context \p ParentLC. + const StackFrameContext *getStackFrame(AnalysisDeclContext *ADC, + const LocationContext *ParentLC, + const Stmt *S, const CFGBlock *Block, + unsigned BlockCount, unsigned Index); + + /// Obtain a context of the block invocation using its parent context. + /// + /// \param ADC The AnalysisDeclContext. + /// \param ParentLC The parent context of this newly created context. + /// \param BD The BlockDecl. + /// \param Data The raw data to store as part of the context. const BlockInvocationContext * - getBlockInvocationContext(AnalysisDeclContext *ctx, - const LocationContext *parent, - const BlockDecl *BD, - const void *ContextData); + getBlockInvocationContext(AnalysisDeclContext *ADC, + const LocationContext *ParentLC, + const BlockDecl *BD, const void *Data); /// Discard all previously created LocationContext objects. void clear(); -private: - template <typename LOC, typename DATA> - const LOC *getLocationContext(AnalysisDeclContext *ctx, - const LocationContext *parent, - const DATA *d); }; class AnalysisDeclContextManager { @@ -441,36 +421,31 @@ class AnalysisDeclContextManager { llvm::DenseMap<const Decl *, std::unique_ptr<AnalysisDeclContext>>; ContextMap Contexts; - LocationContextManager LocContexts; + LocationContextManager LocCtxMgr; CFG::BuildOptions cfgBuildOptions; - /// Pointer to an interface that can provide function bodies for - /// declarations from external source. + // Pointer to an interface that can provide function bodies for + // declarations from external source. std::unique_ptr<CodeInjector> Injector; - /// A factory for creating and caching implementations for common - /// methods during the analysis. + // A factory for creating and caching implementations for common + // methods during the analysis. BodyFarm FunctionBodyFarm; - /// Flag to indicate whether or not bodies should be synthesized - /// for well-known functions. + // Flag to indicate whether or not bodies should be synthesized + // for well-known functions. bool SynthesizeBodies; public: - AnalysisDeclContextManager(ASTContext &ASTCtx, bool useUnoptimizedCFG = false, - bool addImplicitDtors = false, - bool addInitializers = false, - bool addTemporaryDtors = false, - bool addLifetime = false, - bool addLoopExit = false, - bool addScopes = false, - bool synthesizeBodies = false, - bool addStaticInitBranches = false, - bool addCXXNewAllocator = true, - bool addRichCXXConstructors = true, - bool markElidedCXXConstructors = true, - bool addVirtualBaseBranches = true, - CodeInjector *injector = nullptr); + AnalysisDeclContextManager( + ASTContext &ASTCtx, bool useUnoptimizedCFG = false, + bool addImplicitDtors = false, bool addInitializers = false, + bool addTemporaryDtors = false, bool addLifetime = false, + bool addLoopExit = false, bool addScopes = false, + bool synthesizeBodies = false, bool addStaticInitBranches = false, + bool addCXXNewAllocator = true, bool addRichCXXConstructors = true, + bool markElidedCXXConstructors = true, bool addVirtualBaseBranches = true, + CodeInjector *injector = nullptr); AnalysisDeclContext *getContext(const Decl *D); @@ -478,37 +453,27 @@ public: return !cfgBuildOptions.PruneTriviallyFalseEdges; } - CFG::BuildOptions &getCFGBuildOptions() { - return cfgBuildOptions; - } + CFG::BuildOptions &getCFGBuildOptions() { return cfgBuildOptions; } - /// Return true if faux bodies should be synthesized for well-known - /// functions. + /// \returns Whether faux bodies should be synthesized for known functions. bool synthesizeBodies() const { return SynthesizeBodies; } - const StackFrameContext *getStackFrame(AnalysisDeclContext *Ctx, - const LocationContext *Parent, - const Stmt *S, const CFGBlock *Blk, - unsigned BlockCount, unsigned Idx) { - return LocContexts.getStackFrame(Ctx, Parent, S, Blk, BlockCount, Idx); - } - - // Get the top level stack frame. + /// Obtain the beginning context of the analysis. + /// + /// \returns The top level stack frame for \p D. const StackFrameContext *getStackFrame(const Decl *D) { - return LocContexts.getStackFrame(getContext(D), nullptr, nullptr, nullptr, - 0, 0); + return LocCtxMgr.getStackFrame(getContext(D), nullptr, nullptr, nullptr, 0, + 0); } - // Get a stack frame with parent. - StackFrameContext const *getStackFrame(const Decl *D, + /// \copydoc LocationContextManager::getStackFrame() + const StackFrameContext *getStackFrame(AnalysisDeclContext *ADC, const LocationContext *Parent, - const Stmt *S, const CFGBlock *Blk, - unsigned BlockCount, unsigned Idx) { - return LocContexts.getStackFrame(getContext(D), Parent, S, Blk, BlockCount, - Idx); + const Stmt *S, const CFGBlock *Block, + unsigned BlockCount, unsigned Index) { + return LocCtxMgr.getStackFrame(ADC, Parent, S, Block, BlockCount, Index); } - /// Get a reference to {@code BodyFarm} instance. BodyFarm &getBodyFarm(); /// Discard all previously created AnalysisDeclContexts. @@ -517,9 +482,7 @@ public: private: friend class AnalysisDeclContext; - LocationContextManager &getLocationContextManager() { - return LocContexts; - } + LocationContextManager &getLocationContextManager() { return LocCtxMgr; } }; } // namespace clang diff --git a/clang/include/clang/Analysis/AnyCall.h b/clang/include/clang/Analysis/AnyCall.h index 97a94d299e64..16371eb1da18 100644 --- a/clang/include/clang/Analysis/AnyCall.h +++ b/clang/include/clang/Analysis/AnyCall.h @@ -41,6 +41,9 @@ public: /// An implicit or explicit C++ constructor call Constructor, + /// A C++ inherited constructor produced by a "using T::T" directive + InheritedConstructor, + /// A C++ allocation function call (operator `new`), via C++ new-expression Allocator, @@ -84,6 +87,9 @@ public: AnyCall(const CXXConstructExpr *NE) : E(NE), D(NE->getConstructor()), K(Constructor) {} + AnyCall(const CXXInheritedCtorInitExpr *CIE) + : E(CIE), D(CIE->getConstructor()), K(InheritedConstructor) {} + AnyCall(const CXXDestructorDecl *D) : E(nullptr), D(D), K(Destructor) {} AnyCall(const CXXConstructorDecl *D) : E(nullptr), D(D), K(Constructor) {} @@ -114,6 +120,8 @@ public: return AnyCall(CXDE); } else if (const auto *CXCE = dyn_cast<CXXConstructExpr>(E)) { return AnyCall(CXCE); + } else if (const auto *CXCIE = dyn_cast<CXXInheritedCtorInitExpr>(E)) { + return AnyCall(CXCIE); } else { return None; } @@ -169,6 +177,7 @@ public: return cast<CallExpr>(E)->getCallReturnType(Ctx); case Destructor: case Constructor: + case InheritedConstructor: case Allocator: case Deallocator: return cast<FunctionDecl>(D)->getReturnType(); diff --git a/clang/include/clang/Analysis/CFG.h b/clang/include/clang/Analysis/CFG.h index 93de3178e661..43fb523c863a 100644 --- a/clang/include/clang/Analysis/CFG.h +++ b/clang/include/clang/Analysis/CFG.h @@ -624,10 +624,10 @@ class CFGBlock { template <bool IsOtherConst> friend class ElementRefImpl; using CFGBlockPtr = - typename std::conditional<IsConst, const CFGBlock *, CFGBlock *>::type; + std::conditional_t<IsConst, const CFGBlock *, CFGBlock *>; - using CFGElementPtr = typename std::conditional<IsConst, const CFGElement *, - CFGElement *>::type; + using CFGElementPtr = + std::conditional_t<IsConst, const CFGElement *, CFGElement *>; protected: CFGBlockPtr Parent; @@ -675,15 +675,14 @@ class CFGBlock { friend class ElementRefIterator; using CFGBlockRef = - typename std::conditional<IsConst, const CFGBlock *, CFGBlock *>::type; + std::conditional_t<IsConst, const CFGBlock *, CFGBlock *>; - using UnderlayingIteratorTy = typename std::conditional< + using UnderlayingIteratorTy = std::conditional_t< IsConst, - typename std::conditional<IsReverse, - ElementList::const_reverse_iterator, - ElementList::const_iterator>::type, - typename std::conditional<IsReverse, ElementList::reverse_iterator, - ElementList::iterator>::type>::type; + std::conditional_t<IsReverse, ElementList::const_reverse_iterator, + ElementList::const_iterator>, + std::conditional_t<IsReverse, ElementList::reverse_iterator, + ElementList::iterator>>; using IteratorTraits = typename std::iterator_traits<UnderlayingIteratorTy>; using ElementRef = typename CFGBlock::ElementRefImpl<IsConst>; diff --git a/clang/include/clang/Analysis/CallGraph.h b/clang/include/clang/Analysis/CallGraph.h index dae2b58ffc10..6f7159330f5d 100644 --- a/clang/include/clang/Analysis/CallGraph.h +++ b/clang/include/clang/Analysis/CallGraph.h @@ -24,6 +24,7 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SetVector.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/iterator_range.h" #include <memory> namespace clang { @@ -65,6 +66,11 @@ public: /// Determine if a declaration should be included in the graph. static bool includeInGraph(const Decl *D); + /// Determine if a declaration should be included in the graph for the + /// purposes of being a callee. This is similar to includeInGraph except + /// it permits declarations, not just definitions. + static bool includeCalleeInGraph(const Decl *D); + /// Lookup the node for the given declaration. CallGraphNode *getNode(const Decl *) const; @@ -136,14 +142,23 @@ public: private: /// Add the given declaration to the call graph. void addNodeForDecl(Decl *D, bool IsGlobal); - - /// Allocate a new node in the graph. - CallGraphNode *allocateNewNode(Decl *); }; class CallGraphNode { public: - using CallRecord = CallGraphNode *; + struct CallRecord { + CallGraphNode *Callee; + Expr *CallExpr; + + CallRecord() = default; + + CallRecord(CallGraphNode *Callee_, Expr *CallExpr_) + : Callee(Callee_), CallExpr(CallExpr_) {} + + // The call destination is the only important data here, + // allow to transparently unwrap into it. + operator CallGraphNode *() const { return Callee; } + }; private: /// The function/method declaration. @@ -164,24 +179,67 @@ public: const_iterator begin() const { return CalledFunctions.begin(); } const_iterator end() const { return CalledFunctions.end(); } + /// Iterator access to callees/children of the node. + llvm::iterator_range<iterator> callees() { + return llvm::make_range(begin(), end()); + } + llvm::iterator_range<const_iterator> callees() const { + return llvm::make_range(begin(), end()); + } + bool empty() const { return CalledFunctions.empty(); } unsigned size() const { return CalledFunctions.size(); } - void addCallee(CallGraphNode *N) { - CalledFunctions.push_back(N); - } + void addCallee(CallRecord Call) { CalledFunctions.push_back(Call); } Decl *getDecl() const { return FD; } + FunctionDecl *getDefinition() const { + return getDecl()->getAsFunction()->getDefinition(); + } + void print(raw_ostream &os) const; void dump() const; }; +// NOTE: we are comparing based on the callee only. So different call records +// (with different call expressions) to the same callee will compare equal! +inline bool operator==(const CallGraphNode::CallRecord &LHS, + const CallGraphNode::CallRecord &RHS) { + return LHS.Callee == RHS.Callee; +} + } // namespace clang -// Graph traits for iteration, viewing. namespace llvm { +// Specialize DenseMapInfo for clang::CallGraphNode::CallRecord. +template <> struct DenseMapInfo<clang::CallGraphNode::CallRecord> { + static inline clang::CallGraphNode::CallRecord getEmptyKey() { + return clang::CallGraphNode::CallRecord( + DenseMapInfo<clang::CallGraphNode *>::getEmptyKey(), + DenseMapInfo<clang::Expr *>::getEmptyKey()); + } + + static inline clang::CallGraphNode::CallRecord getTombstoneKey() { + return clang::CallGraphNode::CallRecord( + DenseMapInfo<clang::CallGraphNode *>::getTombstoneKey(), + DenseMapInfo<clang::Expr *>::getTombstoneKey()); + } + + static unsigned getHashValue(const clang::CallGraphNode::CallRecord &Val) { + // NOTE: we are comparing based on the callee only. + // Different call records with the same callee will compare equal! + return DenseMapInfo<clang::CallGraphNode *>::getHashValue(Val.Callee); + } + + static bool isEqual(const clang::CallGraphNode::CallRecord &LHS, + const clang::CallGraphNode::CallRecord &RHS) { + return LHS == RHS; + } +}; + +// Graph traits for iteration, viewing. template <> struct GraphTraits<clang::CallGraphNode*> { using NodeType = clang::CallGraphNode; using NodeRef = clang::CallGraphNode *; diff --git a/clang/include/clang/Analysis/ConstructionContext.h b/clang/include/clang/Analysis/ConstructionContext.h index f1564f9fe740..4fa5c8b454a0 100644 --- a/clang/include/clang/Analysis/ConstructionContext.h +++ b/clang/include/clang/Analysis/ConstructionContext.h @@ -110,6 +110,9 @@ public: ConstructionContextItem(const CXXConstructExpr *CE, unsigned Index) : Data(CE), Kind(ArgumentKind), Index(Index) {} + ConstructionContextItem(const CXXInheritedCtorInitExpr *CE, unsigned Index) + : Data(CE), Kind(ArgumentKind), Index(Index) {} + ConstructionContextItem(const ObjCMessageExpr *ME, unsigned Index) : Data(ME), Kind(ArgumentKind), Index(Index) {} @@ -117,7 +120,7 @@ public: ConstructionContextItem(const Expr *E, unsigned Index) : Data(E), Kind(ArgumentKind), Index(Index) { assert(isa<CallExpr>(E) || isa<CXXConstructExpr>(E) || - isa<ObjCMessageExpr>(E)); + isa<CXXInheritedCtorInitExpr>(E) || isa<ObjCMessageExpr>(E)); } ConstructionContextItem(const CXXCtorInitializer *Init) diff --git a/clang/include/clang/Analysis/FlowSensitive/DataflowValues.h b/clang/include/clang/Analysis/FlowSensitive/DataflowValues.h index 709753339eb5..68d935c6a400 100644 --- a/clang/include/clang/Analysis/FlowSensitive/DataflowValues.h +++ b/clang/include/clang/Analysis/FlowSensitive/DataflowValues.h @@ -168,4 +168,4 @@ protected: }; } // end namespace clang -#endif +#endif // LLVM_CLANG_ANALYSES_DATAFLOW_VALUES diff --git a/clang/include/clang/Analysis/FlowSensitive/DataflowWorklist.h b/clang/include/clang/Analysis/FlowSensitive/DataflowWorklist.h new file mode 100644 index 000000000000..90095735ad3d --- /dev/null +++ b/clang/include/clang/Analysis/FlowSensitive/DataflowWorklist.h @@ -0,0 +1,94 @@ +//===- DataflowWorklist.h ---------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// A simple and reusable worklist for flow-sensitive analyses. +// +//===----------------------------------------------------------------------===// +#ifndef LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_DATAFLOWWORKLIST_H +#define LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_DATAFLOWWORKLIST_H + +#include "clang/Analysis/Analyses/PostOrderCFGView.h" +#include "clang/Analysis/CFG.h" +#include "llvm/ADT/PriorityQueue.h" + +namespace clang { +/// A worklist implementation where the enqueued blocks will be dequeued based +/// on the order defined by 'Comp'. +template <typename Comp, unsigned QueueSize> class DataflowWorklistBase { + llvm::BitVector EnqueuedBlocks; + PostOrderCFGView *POV; + llvm::PriorityQueue<const CFGBlock *, + SmallVector<const CFGBlock *, QueueSize>, Comp> + WorkList; + +public: + DataflowWorklistBase(const CFG &Cfg, PostOrderCFGView *POV, Comp C) + : EnqueuedBlocks(Cfg.getNumBlockIDs()), POV(POV), WorkList(C) {} + + const PostOrderCFGView *getCFGView() const { return POV; } + + void enqueueBlock(const CFGBlock *Block) { + if (Block && !EnqueuedBlocks[Block->getBlockID()]) { + EnqueuedBlocks[Block->getBlockID()] = true; + WorkList.push(Block); + } + } + + const CFGBlock *dequeue() { + if (WorkList.empty()) + return nullptr; + const CFGBlock *B = WorkList.top(); + WorkList.pop(); + EnqueuedBlocks[B->getBlockID()] = false; + return B; + } +}; + +struct ReversePostOrderCompare { + PostOrderCFGView::BlockOrderCompare Cmp; + bool operator()(const CFGBlock *lhs, const CFGBlock *rhs) const { + return Cmp(rhs, lhs); + } +}; + +/// A worklist implementation for forward dataflow analysis. The enqueued +/// blocks will be dequeued in reverse post order. The worklist cannot contain +/// the same block multiple times at once. +struct ForwardDataflowWorklist + : DataflowWorklistBase<ReversePostOrderCompare, 20> { + ForwardDataflowWorklist(const CFG &Cfg, AnalysisDeclContext &Ctx) + : DataflowWorklistBase( + Cfg, Ctx.getAnalysis<PostOrderCFGView>(), + ReversePostOrderCompare{ + Ctx.getAnalysis<PostOrderCFGView>()->getComparator()}) {} + + void enqueueSuccessors(const CFGBlock *Block) { + for (auto B : Block->succs()) + enqueueBlock(B); + } +}; + +/// A worklist implementation for backward dataflow analysis. The enqueued +/// block will be dequeued in post order. The worklist cannot contain the same +/// block multiple times at once. +struct BackwardDataflowWorklist + : DataflowWorklistBase<PostOrderCFGView::BlockOrderCompare, 20> { + BackwardDataflowWorklist(const CFG &Cfg, AnalysisDeclContext &Ctx) + : DataflowWorklistBase( + Cfg, Ctx.getAnalysis<PostOrderCFGView>(), + Ctx.getAnalysis<PostOrderCFGView>()->getComparator()) {} + + void enqueuePredecessors(const CFGBlock *Block) { + for (auto B : Block->preds()) + enqueueBlock(B); + } +}; + +} // namespace clang + +#endif // LLVM_CLANG_ANALYSIS_ANALYSES_CONSUMED_H diff --git a/clang/include/clang/Analysis/PathDiagnostic.h b/clang/include/clang/Analysis/PathDiagnostic.h index 6730057cf0ad..c4b042a51bb5 100644 --- a/clang/include/clang/Analysis/PathDiagnostic.h +++ b/clang/include/clang/Analysis/PathDiagnostic.h @@ -561,7 +561,7 @@ public: void setCallee(const CallEnter &CE, const SourceManager &SM); bool hasCallStackMessage() { return !CallStackMessage.empty(); } - void setCallStackMessage(StringRef st) { CallStackMessage = st; } + void setCallStackMessage(StringRef st) { CallStackMessage = std::string(st); } PathDiagnosticLocation getLocation() const override { return callEnter; } @@ -806,7 +806,7 @@ public: meta_iterator meta_begin() const { return OtherDesc.begin(); } meta_iterator meta_end() const { return OtherDesc.end(); } - void addMeta(StringRef s) { OtherDesc.push_back(s); } + void addMeta(StringRef s) { OtherDesc.push_back(std::string(s)); } const FilesToLineNumsMap &getExecutedLines() const { return *ExecutedLines; diff --git a/clang/include/clang/Basic/AArch64SVEACLETypes.def b/clang/include/clang/Basic/AArch64SVEACLETypes.def index 7d387587dc29..b98a07436e94 100644 --- a/clang/include/clang/Basic/AArch64SVEACLETypes.def +++ b/clang/include/clang/Basic/AArch64SVEACLETypes.def @@ -35,35 +35,95 @@ // // - IsFP is true for vectors of floating-point elements. // +// - IsBF true for vector of brain float elements. //===----------------------------------------------------------------------===// #ifndef SVE_VECTOR_TYPE -#define SVE_VECTOR_TYPE(Name, Id, SingletonId, ElKind, ElBits, IsSigned, IsFP)\ +#define SVE_VECTOR_TYPE(Name, MangledName, Id, SingletonId, NumEls, ElBits, \ + IsSigned, IsFP, IsBF) \ SVE_TYPE(Name, Id, SingletonId) #endif #ifndef SVE_PREDICATE_TYPE -#define SVE_PREDICATE_TYPE(Name, Id, SingletonId, ElKind)\ +#define SVE_PREDICATE_TYPE(Name, MangledName, Id, SingletonId, NumEls) \ SVE_TYPE(Name, Id, SingletonId) #endif //===- Vector point types -----------------------------------------------===// -SVE_VECTOR_TYPE("__SVInt8_t", SveInt8, SveInt8Ty, SveElSInt8, 8, true, false) -SVE_VECTOR_TYPE("__SVInt16_t", SveInt16, SveInt16Ty, SveElSInt16, 16, true, false) -SVE_VECTOR_TYPE("__SVInt32_t", SveInt32, SveInt32Ty, SveElSInt32, 32, true, false) -SVE_VECTOR_TYPE("__SVInt64_t", SveInt64, SveInt64Ty, SveElSInt64, 64, true, false) -SVE_VECTOR_TYPE("__SVUint8_t", SveUint8, SveUint8Ty, SveElUInt8, 8, false, false) -SVE_VECTOR_TYPE("__SVUint16_t", SveUint16, SveUint16Ty, SveElUInt16, 16, false, false) -SVE_VECTOR_TYPE("__SVUint32_t", SveUint32, SveUint32Ty, SveElUInt32, 32, false, false) -SVE_VECTOR_TYPE("__SVUint64_t", SveUint64, SveUint64Ty, SveElUInt64, 64, false, false) +SVE_VECTOR_TYPE("__SVInt8_t", "__SVInt8_t", SveInt8, SveInt8Ty, 16, 8, true, false, false) +SVE_VECTOR_TYPE("__SVInt16_t", "__SVInt16_t", SveInt16, SveInt16Ty, 8, 16, true, false, false) +SVE_VECTOR_TYPE("__SVInt32_t", "__SVInt32_t", SveInt32, SveInt32Ty, 4, 32, true, false, false) +SVE_VECTOR_TYPE("__SVInt64_t", "__SVInt64_t", SveInt64, SveInt64Ty, 2, 64, true, false, false) -SVE_VECTOR_TYPE("__SVFloat16_t", SveFloat16, SveFloat16Ty, SveElHalf, 16, true, true) -SVE_VECTOR_TYPE("__SVFloat32_t", SveFloat32, SveFloat32Ty, SveElFloat, 32, true, true) -SVE_VECTOR_TYPE("__SVFloat64_t", SveFloat64, SveFloat64Ty, SveElDouble, 64, true, true) +SVE_VECTOR_TYPE("__SVUint8_t", "__SVUint8_t", SveUint8, SveUint8Ty, 16, 8, false, false, false) +SVE_VECTOR_TYPE("__SVUint16_t", "__SVUint16_t", SveUint16, SveUint16Ty, 8, 16, false, false, false) +SVE_VECTOR_TYPE("__SVUint32_t", "__SVUint32_t", SveUint32, SveUint32Ty, 4, 32, false, false, false) +SVE_VECTOR_TYPE("__SVUint64_t", "__SVUint64_t", SveUint64, SveUint64Ty, 2, 64, false, false, false) -SVE_PREDICATE_TYPE("__SVBool_t", SveBool, SveBoolTy, SveElBool) +SVE_VECTOR_TYPE("__SVFloat16_t", "__SVFloat16_t", SveFloat16, SveFloat16Ty, 8, 16, true, true, false) +SVE_VECTOR_TYPE("__SVFloat32_t", "__SVFloat32_t", SveFloat32, SveFloat32Ty, 4, 32, true, true, false) +SVE_VECTOR_TYPE("__SVFloat64_t", "__SVFloat64_t", SveFloat64, SveFloat64Ty, 2, 64, true, true, false) + +SVE_VECTOR_TYPE("__SVBFloat16_t", "__SVBFloat16_t", SveBFloat16, SveBFloat16Ty, 8, 16, true, false, true) + +// +// x2 +// +SVE_VECTOR_TYPE("__clang_svint8x2_t", "svint8x2_t", SveInt8x2, SveInt8x2Ty, 32, 8, true, false, false) +SVE_VECTOR_TYPE("__clang_svint16x2_t", "svint16x2_t", SveInt16x2, SveInt16x2Ty, 16, 16, true, false, false) +SVE_VECTOR_TYPE("__clang_svint32x2_t", "svint32x2_t", SveInt32x2, SveInt32x2Ty, 8, 32, true, false, false) +SVE_VECTOR_TYPE("__clang_svint64x2_t", "svint64x2_t", SveInt64x2, SveInt64x2Ty, 4, 64, true, false, false) + +SVE_VECTOR_TYPE("__clang_svuint8x2_t", "svuint8x2_t", SveUint8x2, SveUint8x2Ty, 32, 8, false, false, false) +SVE_VECTOR_TYPE("__clang_svuint16x2_t", "svuint16x2_t", SveUint16x2, SveUint16x2Ty, 16, 16, false, false, false) +SVE_VECTOR_TYPE("__clang_svuint32x2_t", "svuint32x2_t", SveUint32x2, SveUint32x2Ty, 8, 32, false, false, false) +SVE_VECTOR_TYPE("__clang_svuint64x2_t", "svuint64x2_t", SveUint64x2, SveUint64x2Ty, 4, 64, false, false, false) + +SVE_VECTOR_TYPE("__clang_svfloat16x2_t", "svfloat16x2_t", SveFloat16x2, SveFloat16x2Ty, 16, 16, true, true, false) +SVE_VECTOR_TYPE("__clang_svfloat32x2_t", "svfloat32x2_t", SveFloat32x2, SveFloat32x2Ty, 8, 32, true, true, false) +SVE_VECTOR_TYPE("__clang_svfloat64x2_t", "svfloat64x2_t", SveFloat64x2, SveFloat64x2Ty, 4, 64, true, true, false) + +SVE_VECTOR_TYPE("__clang_svbfloat16x2_t", "svbfloat16x2_t", SveBFloat16x2, SveBFloat16x2Ty, 16, 16, true, false, true) +// +// x3 +// +SVE_VECTOR_TYPE("__clang_svint8x3_t", "svint8x3_t", SveInt8x3, SveInt8x3Ty, 48, 8, true, false, false) +SVE_VECTOR_TYPE("__clang_svint16x3_t", "svint16x3_t", SveInt16x3, SveInt16x3Ty, 24, 16, true, false, false) +SVE_VECTOR_TYPE("__clang_svint32x3_t", "svint32x3_t", SveInt32x3, SveInt32x3Ty, 12, 32, true, false, false) +SVE_VECTOR_TYPE("__clang_svint64x3_t", "svint64x3_t", SveInt64x3, SveInt64x3Ty, 6, 64, true, false, false) + +SVE_VECTOR_TYPE("__clang_svuint8x3_t", "svuint8x3_t", SveUint8x3, SveUint8x3Ty, 48, 8, false, false, false) +SVE_VECTOR_TYPE("__clang_svuint16x3_t", "svuint16x3_t", SveUint16x3, SveUint16x3Ty, 24, 16, false, false, false) +SVE_VECTOR_TYPE("__clang_svuint32x3_t", "svuint32x3_t", SveUint32x3, SveUint32x3Ty, 12, 32, false, false, false) +SVE_VECTOR_TYPE("__clang_svuint64x3_t", "svuint64x3_t", SveUint64x3, SveUint64x3Ty, 6, 64, false, false, false) + +SVE_VECTOR_TYPE("__clang_svfloat16x3_t", "svfloat16x3_t", SveFloat16x3, SveFloat16x3Ty, 24, 16, true, true, false) +SVE_VECTOR_TYPE("__clang_svfloat32x3_t", "svfloat32x3_t", SveFloat32x3, SveFloat32x3Ty, 12, 32, true, true, false) +SVE_VECTOR_TYPE("__clang_svfloat64x3_t", "svfloat64x3_t", SveFloat64x3, SveFloat64x3Ty, 6, 64, true, true, false) + +SVE_VECTOR_TYPE("__clang_svbfloat16x3_t", "svbfloat16x3_t", SveBFloat16x3, SveBFloat16x3Ty, 24, 16, true, false, true) +// +// x4 +// +SVE_VECTOR_TYPE("__clang_svint8x4_t", "svint8x4_t", SveInt8x4, SveInt8x4Ty, 64, 8, true, false, false) +SVE_VECTOR_TYPE("__clang_svint16x4_t", "svint16x4_t", SveInt16x4, SveInt16x4Ty, 32, 16, true, false, false) +SVE_VECTOR_TYPE("__clang_svint32x4_t", "svint32x4_t", SveInt32x4, SveInt32x4Ty, 16, 32, true, false, false) +SVE_VECTOR_TYPE("__clang_svint64x4_t", "svint64x4_t", SveInt64x4, SveInt64x4Ty, 8, 64, true, false, false) + +SVE_VECTOR_TYPE("__clang_svuint8x4_t", "svuint8x4_t", SveUint8x4, SveUint8x4Ty, 64, 8, false, false, false) +SVE_VECTOR_TYPE("__clang_svuint16x4_t", "svuint16x4_t", SveUint16x4, SveUint16x4Ty, 32, 16, false, false, false) +SVE_VECTOR_TYPE("__clang_svuint32x4_t", "svuint32x4_t", SveUint32x4, SveUint32x4Ty, 16, 32, false, false, false) +SVE_VECTOR_TYPE("__clang_svuint64x4_t", "svuint64x4_t", SveUint64x4, SveUint64x4Ty, 8, 64, false, false, false) + +SVE_VECTOR_TYPE("__clang_svfloat16x4_t", "svfloat16x4_t", SveFloat16x4, SveFloat16x4Ty, 32, 16, true, true, false) +SVE_VECTOR_TYPE("__clang_svfloat32x4_t", "svfloat32x4_t", SveFloat32x4, SveFloat32x4Ty, 16, 32, true, true, false) +SVE_VECTOR_TYPE("__clang_svfloat64x4_t", "svfloat64x4_t", SveFloat64x4, SveFloat64x4Ty, 8, 64, true, true, false) + +SVE_VECTOR_TYPE("__clang_svbfloat16x4_t", "svbfloat16x4_t", SveBFloat16x4, SveBFloat16x4Ty, 32, 16, true, false, true) + +SVE_PREDICATE_TYPE("__SVBool_t", "__SVBool_t", SveBool, SveBoolTy, 16) #undef SVE_VECTOR_TYPE #undef SVE_PREDICATE_TYPE diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index 16556b5f0745..bc4a380545af 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -174,12 +174,31 @@ class IdentifierArgument<string name, bit opt = 0> : Argument<name, opt>; class IntArgument<string name, bit opt = 0> : Argument<name, opt>; class StringArgument<string name, bit opt = 0> : Argument<name, opt>; class ExprArgument<string name, bit opt = 0> : Argument<name, opt>; -class FunctionArgument<string name, bit opt = 0, bit fake = 0> : Argument<name, - opt, - fake>; -class NamedArgument<string name, bit opt = 0, bit fake = 0> : Argument<name, - opt, - fake>; +class DeclArgument<DeclNode kind, string name, bit opt = 0, bit fake = 0> + : Argument<name, opt, fake> { + DeclNode Kind = kind; +} + +// An argument of a OMPDeclareVariantAttr that represents the `match` +// clause of the declare variant by keeping the information (incl. nesting) in +// an OMPTraitInfo object. +// +// With some exceptions, the `match(<context-selector>)` clause looks roughly +// as follows: +// context-selector := list<selector-set> +// selector-set := <kind>={list<selector>} +// selector := <kind>([score(<const-expr>):] list<trait>) +// trait := <kind> +// +// The structure of an OMPTraitInfo object is a tree as defined below: +// +// OMPTraitInfo := {list<OMPTraitSet>} +// OMPTraitSet := {Kind, list<OMPTraitSelector>} +// OMPTraitSelector := {Kind, Expr, list<OMPTraitProperty>} +// OMPTraitProperty := {Kind} +// +class OMPTraitInfoArgument<string name> : Argument<name, 0>; + class TypeArgument<string name, bit opt = 0> : Argument<name, opt>; class UnsignedArgument<string name, bit opt = 0> : Argument<name, opt>; class VariadicUnsignedArgument<string name> : Argument<name, 1>; @@ -238,7 +257,6 @@ class VariadicEnumArgument<string name, string type, list<string> values, class Spelling<string name, string variety> { string Name = name; string Variety = variety; - bit KnownToGCC; } class GNU<string name> : Spelling<name, "GNU">; @@ -258,11 +276,11 @@ class Pragma<string namespace, string name> : Spelling<name, "Pragma"> { string Namespace = namespace; } -// The GCC spelling implies GNU<name> and CXX11<"gnu", name> and also sets -// KnownToGCC to 1. This spelling should be used for any GCC-compatible +// The GCC spelling implies GNU<name>, CXX11<"gnu", name>, and optionally, +// C2x<"gnu", name>. This spelling should be used for any GCC-compatible // attributes. -class GCC<string name> : Spelling<name, "GCC"> { - let KnownToGCC = 1; +class GCC<string name, bit allowInC = 1> : Spelling<name, "GCC"> { + bit AllowInC = allowInC; } // The Clang spelling implies GNU<name>, CXX11<"clang", name>, and optionally, @@ -291,6 +309,7 @@ class SubjectList<list<AttrSubject> subjects, SubjectDiag diag = WarnDiag, } class LangOpt<string name, code customCode = [{}]> { + // The language option to test; ignored when custom code is supplied. string Name = name; // A custom predicate, written as an expression evaluated in a context with @@ -300,17 +319,16 @@ class LangOpt<string name, code customCode = [{}]> { def MicrosoftExt : LangOpt<"MicrosoftExt">; def Borland : LangOpt<"Borland">; def CUDA : LangOpt<"CUDA">; -def HIP : LangOpt<"HIP">; def SYCL : LangOpt<"SYCLIsDevice">; -def COnly : LangOpt<"COnly", "!LangOpts.CPlusPlus">; +def COnly : LangOpt<"", "!LangOpts.CPlusPlus">; def CPlusPlus : LangOpt<"CPlusPlus">; def OpenCL : LangOpt<"OpenCL">; def RenderScript : LangOpt<"RenderScript">; def ObjC : LangOpt<"ObjC">; def BlocksSupported : LangOpt<"Blocks">; def ObjCAutoRefCount : LangOpt<"ObjCAutoRefCount">; -def ObjCNonFragileRuntime : LangOpt<"ObjCNonFragileRuntime", - "LangOpts.ObjCRuntime.allowsClassStubs()">; +def ObjCNonFragileRuntime + : LangOpt<"", "LangOpts.ObjCRuntime.allowsClassStubs()">; // Language option for CMSE extensions def Cmse : LangOpt<"Cmse">; @@ -337,6 +355,8 @@ class TargetArch<list<string> arches> : TargetSpec { let Arches = arches; } def TargetARM : TargetArch<["arm", "thumb", "armeb", "thumbeb"]>; +def TargetAArch64 : TargetArch<["aarch64"]>; +def TargetAnyArm : TargetArch<!listconcat(TargetARM.Arches, TargetAArch64.Arches)>; def TargetAVR : TargetArch<["avr"]>; def TargetBPF : TargetArch<["bpfel", "bpfeb"]>; def TargetMips32 : TargetArch<["mips", "mipsel"]>; @@ -420,6 +440,7 @@ def SubjectMatcherForEnumConstant : AttrSubjectMatcherRule<"enum_constant", def SubjectMatcherForVar : AttrSubjectMatcherRule<"variable", [Var], [ AttrSubjectMatcherSubRule<"is_thread_local", [TLSVar]>, AttrSubjectMatcherSubRule<"is_global", [GlobalVar]>, + AttrSubjectMatcherSubRule<"is_local", [LocalVar]>, AttrSubjectMatcherSubRule<"is_parameter", [ParmVar]>, // unless(is_parameter) AttrSubjectMatcherSubRule<"is_parameter", [NonParmVar], 1> @@ -489,6 +510,8 @@ class Attr { bit ASTNode = 1; // Set to true for attributes which have handler in Sema. bit SemaHandler = 1; + // Set to true if this attribute doesn't need custom handling in Sema. + bit SimpleHandler = 0; // Set to true for attributes that are completely ignored. bit Ignored = 0; // Set to true if the attribute's parsing does not match its semantic @@ -581,7 +604,7 @@ class IgnoredAttr : Attr { // def AbiTag : Attr { - let Spellings = [GCC<"abi_tag">]; + let Spellings = [GCC<"abi_tag", /*AllowInC*/0>]; let Args = [VariadicStringArgument<"Tags">]; let Subjects = SubjectList<[Struct, Var, Function, Namespace], ErrorDiag>; let MeaningfulToClassTemplateDefinition = 1; @@ -601,11 +624,11 @@ def Alias : Attr { let Documentation = [Undocumented]; } -def ArmMveAlias : InheritableAttr, TargetSpecificAttr<TargetARM> { - let Spellings = [Clang<"__clang_arm_mve_alias">]; +def ArmBuiltinAlias : InheritableAttr, TargetSpecificAttr<TargetAnyArm> { + let Spellings = [Clang<"__clang_arm_builtin_alias">]; let Args = [IdentifierArgument<"BuiltinName">]; let Subjects = SubjectList<[Function], ErrorDiag>; - let Documentation = [ArmMveAliasDocs]; + let Documentation = [ArmBuiltinAliasDocs]; } def Aligned : InheritableAttr { @@ -655,8 +678,9 @@ def AlwaysInline : InheritableAttr { def Artificial : InheritableAttr { let Spellings = [GCC<"artificial">]; - let Subjects = SubjectList<[InlineFunction], WarnDiag>; + let Subjects = SubjectList<[InlineFunction]>; let Documentation = [ArtificialDocs]; + let SimpleHandler = 1; } def XRayInstrument : InheritableAttr { @@ -668,6 +692,7 @@ def XRayInstrument : InheritableAttr { Accessor<"neverXRayInstrument", [Clang<"xray_never_instrument">]>]; let Documentation = [XRayDocs]; + let SimpleHandler = 1; } def XRayLogArgs : InheritableAttr { @@ -685,7 +710,7 @@ def XRayLogArgs : InheritableAttr { def PatchableFunctionEntry : InheritableAttr, - TargetSpecificAttr<TargetArch<["aarch64", "x86", "x86_64"]>> { + TargetSpecificAttr<TargetArch<["aarch64", "aarch64_be", "x86", "x86_64"]>> { let Spellings = [GCC<"patchable_function_entry">]; let Subjects = SubjectList<[Function, ObjCMethod]>; let Args = [UnsignedArgument<"Count">, DefaultIntArgument<"Offset", 0>]; @@ -924,15 +949,29 @@ def OSConsumesThis : InheritableAttr { let Spellings = [Clang<"os_consumes_this">]; let Subjects = SubjectList<[NonStaticCXXMethod]>; let Documentation = [RetainBehaviorDocs]; + let SimpleHandler = 1; } def Cleanup : InheritableAttr { let Spellings = [GCC<"cleanup">]; - let Args = [FunctionArgument<"FunctionDecl">]; + let Args = [DeclArgument<Function, "FunctionDecl">]; let Subjects = SubjectList<[LocalVar]>; let Documentation = [Undocumented]; } +def CmseNSEntry : InheritableAttr, TargetSpecificAttr<TargetARM> { + let Spellings = [GNU<"cmse_nonsecure_entry">]; + let Subjects = SubjectList<[Function]>; + let LangOpts = [Cmse]; + let Documentation = [ArmCmseNSEntryDocs]; +} + +def CmseNSCall : TypeAttr, TargetSpecificAttr<TargetARM> { + let Spellings = [GNU<"cmse_nonsecure_call">]; + let LangOpts = [Cmse]; + let Documentation = [ArmCmseNSCallDocs]; +} + def Cold : InheritableAttr { let Spellings = [GCC<"cold">]; let Subjects = SubjectList<[Function]>; @@ -948,6 +987,7 @@ def Common : InheritableAttr { def Const : InheritableAttr { let Spellings = [GCC<"const">, GCC<"__const">]; let Documentation = [Undocumented]; + let SimpleHandler = 1; } def ConstInit : InheritableAttr { @@ -959,6 +999,7 @@ def ConstInit : InheritableAttr { let Accessors = [Accessor<"isConstinit", [Keyword<"constinit">]>]; let Documentation = [ConstInitDocs]; let LangOpts = [CPlusPlus]; + let SimpleHandler = 1; } def Constructor : InheritableAttr { @@ -1008,28 +1049,25 @@ def CUDADevice : InheritableAttr { let Documentation = [Undocumented]; } -def HIPPinnedShadow : InheritableAttr { - let Spellings = [GNU<"hip_pinned_shadow">, Declspec<"__hip_pinned_shadow__">]; - let Subjects = SubjectList<[Var]>; - let LangOpts = [HIP]; - let Documentation = [HIPPinnedShadowDocs]; -} - def CUDADeviceBuiltin : IgnoredAttr { let Spellings = [GNU<"device_builtin">, Declspec<"__device_builtin__">]; let LangOpts = [CUDA]; } -def CUDADeviceBuiltinSurfaceType : IgnoredAttr { +def CUDADeviceBuiltinSurfaceType : InheritableAttr { let Spellings = [GNU<"device_builtin_surface_type">, Declspec<"__device_builtin_surface_type__">]; let LangOpts = [CUDA]; + let Subjects = SubjectList<[CXXRecord]>; + let Documentation = [CUDADeviceBuiltinSurfaceTypeDocs]; } -def CUDADeviceBuiltinTextureType : IgnoredAttr { +def CUDADeviceBuiltinTextureType : InheritableAttr { let Spellings = [GNU<"device_builtin_texture_type">, Declspec<"__device_builtin_texture_type__">]; let LangOpts = [CUDA]; + let Subjects = SubjectList<[CXXRecord]>; + let Documentation = [CUDADeviceBuiltinTextureTypeDocs]; } def CUDAGlobal : InheritableAttr { @@ -1089,6 +1127,7 @@ def CXX11NoReturn : InheritableAttr { let Spellings = [CXX11<"", "noreturn", 200809>]; let Subjects = SubjectList<[Function], ErrorDiag>; let Documentation = [CXX11NoReturnDocs]; + let SimpleHandler = 1; } // Similar to CUDA, OpenCL attributes do not receive a [[]] spelling because @@ -1097,6 +1136,7 @@ def OpenCLKernel : InheritableAttr { let Spellings = [Keyword<"__kernel">, Keyword<"kernel">]; let Subjects = SubjectList<[Function], ErrorDiag>; let Documentation = [Undocumented]; + let SimpleHandler = 1; } def OpenCLUnrollHint : InheritableAttr { @@ -1166,6 +1206,7 @@ def RenderScriptKernel : Attr { let Subjects = SubjectList<[Function]>; let Documentation = [RenderScriptKernelAttributeDocs]; let LangOpts = [RenderScript]; + let SimpleHandler = 1; } def Deprecated : InheritableAttr { @@ -1190,6 +1231,7 @@ def EmptyBases : InheritableAttr, TargetSpecificAttr<TargetMicrosoftCXXABI> { let Spellings = [Declspec<"empty_bases">]; let Subjects = SubjectList<[CXXRecord]>; let Documentation = [EmptyBasesDocs]; + let SimpleHandler = 1; } def AllocSize : InheritableAttr { @@ -1232,6 +1274,11 @@ def FallThrough : StmtAttr { let Documentation = [FallthroughDocs]; } +def NoMerge : StmtAttr { + let Spellings = [Clang<"nomerge">]; + let Documentation = [NoMergeDocs]; +} + def FastCall : DeclOrTypeAttr { let Spellings = [GCC<"fastcall">, Keyword<"__fastcall">, Keyword<"_fastcall">]; @@ -1261,6 +1308,7 @@ def FlagEnum : InheritableAttr { let Spellings = [Clang<"flag_enum">]; let Subjects = SubjectList<[Enum]>; let Documentation = [FlagEnumDocs]; + let SimpleHandler = 1; } def EnumExtensibility : InheritableAttr { @@ -1275,6 +1323,7 @@ def Flatten : InheritableAttr { let Spellings = [GCC<"flatten">]; let Subjects = SubjectList<[Function], ErrorDiag>; let Documentation = [FlattenDocs]; + let SimpleHandler = 1; } def Format : InheritableAttr { @@ -1320,6 +1369,7 @@ def IBAction : InheritableAttr { // of the compiler. However, this node needs to exist in the AST because // external tools rely on it. let Documentation = [Undocumented]; + let SimpleHandler = 1; } def IBOutlet : InheritableAttr { @@ -1360,6 +1410,7 @@ def LifetimeBound : DeclOrTypeAttr { let Subjects = SubjectList<[ParmVar, ImplicitObjectParameter], ErrorDiag>; let Documentation = [LifetimeBoundDocs]; let LangOpts = [CPlusPlus]; + let SimpleHandler = 1; } def TrivialABI : InheritableAttr { @@ -1369,6 +1420,7 @@ def TrivialABI : InheritableAttr { let Subjects = SubjectList<[CXXRecord]>; let Documentation = [TrivialABIDocs]; let LangOpts = [CPlusPlus]; + let SimpleHandler = 1; } def MaxFieldAlignment : InheritableAttr { @@ -1383,6 +1435,7 @@ def MayAlias : InheritableAttr { // FIXME: this is a type attribute in GCC, but a declaration attribute here. let Spellings = [GCC<"may_alias">]; let Documentation = [Undocumented]; + let SimpleHandler = 1; } def MIGServerRoutine : InheritableAttr { @@ -1479,16 +1532,23 @@ def NeonVectorType : TypeAttr { let ASTNode = 0; } +def ArmMveStrictPolymorphism : TypeAttr, TargetSpecificAttr<TargetARM> { + let Spellings = [Clang<"__clang_arm_mve_strict_polymorphism">]; + let Documentation = [ArmMveStrictPolymorphismDocs]; +} + def NoUniqueAddress : InheritableAttr, TargetSpecificAttr<TargetItaniumCXXABI> { let Spellings = [CXX11<"", "no_unique_address", 201803>]; let Subjects = SubjectList<[NonBitField], ErrorDiag>; let Documentation = [NoUniqueAddressDocs]; + let SimpleHandler = 1; } def ReturnsTwice : InheritableAttr { let Spellings = [GCC<"returns_twice">]; let Subjects = SubjectList<[Function]>; let Documentation = [Undocumented]; + let SimpleHandler = 1; } def DisableTailCalls : InheritableAttr { @@ -1501,12 +1561,14 @@ def NoAlias : InheritableAttr { let Spellings = [Declspec<"noalias">]; let Subjects = SubjectList<[Function]>; let Documentation = [NoAliasDocs]; + let SimpleHandler = 1; } def NoCommon : InheritableAttr { let Spellings = [GCC<"nocommon">]; let Subjects = SubjectList<[Var]>; let Documentation = [Undocumented]; + let SimpleHandler = 1; } def NoDebug : InheritableAttr { @@ -1519,30 +1581,35 @@ def NoDuplicate : InheritableAttr { let Spellings = [Clang<"noduplicate">]; let Subjects = SubjectList<[Function]>; let Documentation = [NoDuplicateDocs]; + let SimpleHandler = 1; } def Convergent : InheritableAttr { let Spellings = [Clang<"convergent">]; let Subjects = SubjectList<[Function]>; let Documentation = [ConvergentDocs]; + let SimpleHandler = 1; } def NoInline : InheritableAttr { let Spellings = [GCC<"noinline">, Declspec<"noinline">]; let Subjects = SubjectList<[Function]>; let Documentation = [Undocumented]; + let SimpleHandler = 1; } def NoMips16 : InheritableAttr, TargetSpecificAttr<TargetMips32> { let Spellings = [GCC<"nomips16">]; let Subjects = SubjectList<[Function], ErrorDiag>; let Documentation = [Undocumented]; + let SimpleHandler = 1; } def NoMicroMips : InheritableAttr, TargetSpecificAttr<TargetMips32> { let Spellings = [GCC<"nomicromips">]; let Subjects = SubjectList<[Function], ErrorDiag>; let Documentation = [MicroMipsDocs]; + let SimpleHandler = 1; } def RISCVInterrupt : InheritableAttr, TargetSpecificAttr<TargetRISCV> { @@ -1637,6 +1704,7 @@ def NoSplitStack : InheritableAttr { let Spellings = [GCC<"no_split_stack">]; let Subjects = SubjectList<[Function], ErrorDiag>; let Documentation = [NoSplitStackDocs]; + let SimpleHandler = 1; } def NonNull : InheritableParamAttr { @@ -1734,6 +1802,7 @@ def NoInstrumentFunction : InheritableAttr { let Spellings = [GCC<"no_instrument_function">]; let Subjects = SubjectList<[Function]>; let Documentation = [Undocumented]; + let SimpleHandler = 1; } def NotTailCalled : InheritableAttr { @@ -1746,6 +1815,7 @@ def NoStackProtector : InheritableAttr { let Spellings = [Clang<"no_stack_protector">]; let Subjects = SubjectList<[Function]>; let Documentation = [NoStackProtectorDocs]; + let SimpleHandler = 1; } def NoThrow : InheritableAttr { @@ -1808,6 +1878,7 @@ def NSConsumesSelf : InheritableAttr { let Spellings = [Clang<"ns_consumes_self">]; let Subjects = SubjectList<[ObjCMethod]>; let Documentation = [RetainBehaviorDocs]; + let SimpleHandler = 1; } def NSConsumed : InheritableParamAttr { @@ -1820,6 +1891,7 @@ def ObjCException : InheritableAttr { let Spellings = [Clang<"objc_exception">]; let Subjects = SubjectList<[ObjCInterface], ErrorDiag>; let Documentation = [Undocumented]; + let SimpleHandler = 1; } def ObjCMethodFamily : InheritableAttr { @@ -1864,6 +1936,7 @@ def ObjCRootClass : InheritableAttr { let Spellings = [Clang<"objc_root_class">]; let Subjects = SubjectList<[ObjCInterface], ErrorDiag>; let Documentation = [Undocumented]; + let SimpleHandler = 1; } def ObjCNonLazyClass : Attr { @@ -1871,12 +1944,14 @@ def ObjCNonLazyClass : Attr { let Subjects = SubjectList<[ObjCInterface, ObjCImpl], ErrorDiag>; let LangOpts = [ObjC]; let Documentation = [ObjCNonLazyClassDocs]; + let SimpleHandler = 1; } def ObjCSubclassingRestricted : InheritableAttr { let Spellings = [Clang<"objc_subclassing_restricted">]; let Subjects = SubjectList<[ObjCInterface], ErrorDiag>; let Documentation = [ObjCSubclassingRestrictedDocs]; + let SimpleHandler = 1; } def ObjCExplicitProtocolImpl : InheritableAttr { @@ -1900,7 +1975,7 @@ def ObjCDirect : Attr { def ObjCDirectMembers : Attr { let Spellings = [Clang<"objc_direct_members">]; - let Subjects = SubjectList<[ObjCImpl, ObjCCategory], ErrorDiag>; + let Subjects = SubjectList<[ObjCImpl, ObjCInterface, ObjCCategory], ErrorDiag>; let LangOpts = [ObjC]; let Documentation = [ObjCDirectMembersDocs]; } @@ -1916,6 +1991,7 @@ def ObjCRuntimeVisible : Attr { let Spellings = [Clang<"objc_runtime_visible">]; let Subjects = SubjectList<[ObjCInterface], ErrorDiag>; let Documentation = [ObjCRuntimeVisibleDocs]; + let SimpleHandler = 1; } def ObjCClassStub : Attr { @@ -1923,6 +1999,7 @@ def ObjCClassStub : Attr { let Subjects = SubjectList<[ObjCInterface], ErrorDiag>; let Documentation = [ObjCClassStubDocs]; let LangOpts = [ObjCNonFragileRuntime]; + let SimpleHandler = 1; } def ObjCBoxable : Attr { @@ -1941,6 +2018,7 @@ def Overloadable : Attr { let Spellings = [Clang<"overloadable">]; let Subjects = SubjectList<[Function], ErrorDiag>; let Documentation = [OverloadableDocs]; + let SimpleHandler = 1; } def Override : InheritableAttr { @@ -1998,6 +2076,7 @@ def AArch64VectorPcs: DeclOrTypeAttr { def Pure : InheritableAttr { let Spellings = [GCC<"pure">]; let Documentation = [Undocumented]; + let SimpleHandler = 1; } def Regparm : TypeAttr { @@ -2033,7 +2112,7 @@ def WorkGroupSizeHint : InheritableAttr { } def InitPriority : InheritableAttr { - let Spellings = [GCC<"init_priority">]; + let Spellings = [GCC<"init_priority", /*AllowInC*/0>]; let Args = [UnsignedArgument<"Priority">]; let Subjects = SubjectList<[Var], ErrorDiag>; let Documentation = [Undocumented]; @@ -2306,7 +2385,7 @@ def DiagnoseIf : InheritableAttr { ["error", "warning"], ["DT_Error", "DT_Warning"]>, BoolArgument<"ArgDependent", 0, /*fake*/ 1>, - NamedArgument<"Parent", 0, /*fake*/ 1>]; + DeclArgument<Named, "Parent", 0, /*fake*/ 1>]; let InheritEvenIfAlreadyPresent = 1; let LateParsed = 1; let AdditionalMembers = [{ @@ -2321,6 +2400,7 @@ def ArcWeakrefUnavailable : InheritableAttr { let Spellings = [Clang<"objc_arc_weak_reference_unavailable">]; let Subjects = SubjectList<[ObjCInterface], ErrorDiag>; let Documentation = [Undocumented]; + let SimpleHandler = 1; } def ObjCGC : TypeAttr { @@ -2339,6 +2419,7 @@ def ObjCRequiresPropertyDefs : InheritableAttr { let Spellings = [Clang<"objc_requires_property_definitions">]; let Subjects = SubjectList<[ObjCInterface], ErrorDiag>; let Documentation = [Undocumented]; + let SimpleHandler = 1; } def Unused : InheritableAttr { @@ -2353,11 +2434,13 @@ def Used : InheritableAttr { let Spellings = [GCC<"used">]; let Subjects = SubjectList<[NonLocalVar, Function, ObjCMethod]>; let Documentation = [Undocumented]; + let SimpleHandler = 1; } def Uuid : InheritableAttr { let Spellings = [Declspec<"uuid">, Microsoft<"uuid">]; - let Args = [StringArgument<"Guid">]; + let Args = [StringArgument<"Guid">, + DeclArgument<MSGuid, "GuidDecl", 0, /*fake=*/1>]; let Subjects = SubjectList<[Record, Enum]>; // FIXME: Allow expressing logical AND for LangOpts. Our condition should be: // CPlusPlus && (MicrosoftExt || Borland) @@ -2381,6 +2464,15 @@ def VecTypeHint : InheritableAttr { let Documentation = [Undocumented]; } +def MatrixType : TypeAttr { + let Spellings = [Clang<"matrix_type">]; + let Subjects = SubjectList<[TypedefName], ErrorDiag>; + let Args = [ExprArgument<"NumRows">, ExprArgument<"NumColumns">]; + let Documentation = [Undocumented]; + let ASTNode = 0; + let PragmaAttributeSupport = 0; +} + def Visibility : InheritableAttr { let Clone = 0; let Spellings = [GCC<"visibility">]; @@ -2414,6 +2506,7 @@ def WarnUnused : InheritableAttr { let Spellings = [GCC<"warn_unused">]; let Subjects = SubjectList<[Record]>; let Documentation = [Undocumented]; + let SimpleHandler = 1; } def WarnUnusedResult : InheritableAttr { @@ -2436,6 +2529,7 @@ def Weak : InheritableAttr { let Spellings = [GCC<"weak">]; let Subjects = SubjectList<[Var, Function, CXXRecord]>; let Documentation = [Undocumented]; + let SimpleHandler = 1; } def WeakImport : InheritableAttr { @@ -2455,6 +2549,7 @@ def LTOVisibilityPublic : InheritableAttr { let Spellings = [Clang<"lto_visibility_public">]; let Subjects = SubjectList<[Record]>; let Documentation = [LTOVisibilityDocs]; + let SimpleHandler = 1; } def AnyX86Interrupt : InheritableAttr, TargetSpecificAttr<TargetAnyX86> { @@ -2471,6 +2566,7 @@ def AnyX86NoCallerSavedRegisters : InheritableAttr, TargetSpecificAttr<TargetAnyX86> { let Spellings = [GCC<"no_caller_saved_registers">]; let Documentation = [AnyX86NoCallerSavedRegistersDocs]; + let SimpleHandler = 1; } def AnyX86NoCfCheck : DeclOrTypeAttr, TargetSpecificAttr<TargetAnyX86>{ @@ -2522,6 +2618,7 @@ def CFICanonicalJumpTable : InheritableAttr { let Spellings = [Clang<"cfi_canonical_jump_table">]; let Subjects = SubjectList<[Function], ErrorDiag>; let Documentation = [CFICanonicalJumpTableDocs]; + let SimpleHandler = 1; } // C/C++ Thread safety attributes (e.g. for deadlock, data race checking) @@ -2534,6 +2631,7 @@ def GuardedVar : InheritableAttr { let Spellings = [Clang<"guarded_var", 0>]; let Subjects = SubjectList<[Field, SharedVar]>; let Documentation = [Undocumented]; + let SimpleHandler = 1; } def PtGuardedVar : InheritableAttr { @@ -2553,6 +2651,7 @@ def ScopedLockable : InheritableAttr { let Spellings = [Clang<"scoped_lockable", 0>]; let Subjects = SubjectList<[Record]>; let Documentation = [Undocumented]; + let SimpleHandler = 1; } def Capability : InheritableAttr { @@ -2562,10 +2661,6 @@ def Capability : InheritableAttr { let Accessors = [Accessor<"isShared", [Clang<"shared_capability", 0>]>]; let Documentation = [Undocumented]; - let AdditionalMembers = [{ - bool isMutex() const { return getName().equals_lower("mutex"); } - bool isRole() const { return getName().equals_lower("role"); } - }]; } def AssertCapability : InheritableAttr { @@ -2653,6 +2748,7 @@ def NoThreadSafetyAnalysis : InheritableAttr { let Spellings = [Clang<"no_thread_safety_analysis">]; let Subjects = SubjectList<[Function]>; let Documentation = [Undocumented]; + let SimpleHandler = 1; } def GuardedBy : InheritableAttr { @@ -2789,6 +2885,7 @@ def ConsumableAutoCast : InheritableAttr { let Spellings = [Clang<"consumable_auto_cast_state", 0>]; let Subjects = SubjectList<[CXXRecord]>; let Documentation = [Undocumented]; + let SimpleHandler = 1; } def ConsumableSetOnRead : InheritableAttr { @@ -2798,6 +2895,7 @@ def ConsumableSetOnRead : InheritableAttr { let Spellings = [Clang<"consumable_set_state_on_read", 0>]; let Subjects = SubjectList<[CXXRecord]>; let Documentation = [Undocumented]; + let SimpleHandler = 1; } def CallableWhen : InheritableAttr { @@ -2904,6 +3002,7 @@ def MSNoVTable : InheritableAttr, TargetSpecificAttr<TargetMicrosoftCXXABI> { let Spellings = [Declspec<"novtable">]; let Subjects = SubjectList<[CXXRecord]>; let Documentation = [MSNoVTableDocs]; + let SimpleHandler = 1; } def : IgnoredAttr { @@ -2929,6 +3028,7 @@ def MSStruct : InheritableAttr { let Spellings = [GCC<"ms_struct">]; let Subjects = SubjectList<[Record]>; let Documentation = [Undocumented]; + let SimpleHandler = 1; } def DLLExport : InheritableAttr, TargetSpecificAttr<TargetWindows> { @@ -2977,6 +3077,7 @@ def DLLImportStaticLocal : InheritableAttr, TargetSpecificAttr<TargetWindows> { def SelectAny : InheritableAttr { let Spellings = [Declspec<"selectany">, GCC<"selectany">]; let Documentation = [SelectAnyDocs]; + let SimpleHandler = 1; } def Thread : Attr { @@ -3108,57 +3209,14 @@ def LoopHint : Attr { llvm_unreachable("Unhandled LoopHint option."); } - void printPrettyPragma(raw_ostream &OS, const PrintingPolicy &Policy) const { - unsigned SpellingIndex = getAttributeSpellingListIndex(); - // For "#pragma unroll" and "#pragma nounroll" the string "unroll" or - // "nounroll" is already emitted as the pragma name. - if (SpellingIndex == Pragma_nounroll || SpellingIndex == Pragma_nounroll_and_jam) - return; - else if (SpellingIndex == Pragma_unroll || SpellingIndex == Pragma_unroll_and_jam) { - OS << ' ' << getValueString(Policy); - return; - } - - assert(SpellingIndex == Pragma_clang_loop && "Unexpected spelling"); - OS << ' ' << getOptionName(option) << getValueString(Policy); - } + void printPrettyPragma(raw_ostream &OS, const PrintingPolicy &Policy) const; // Return a string containing the loop hint argument including the // enclosing parentheses. - std::string getValueString(const PrintingPolicy &Policy) const { - std::string ValueName; - llvm::raw_string_ostream OS(ValueName); - OS << "("; - if (state == Numeric) - value->printPretty(OS, nullptr, Policy); - else if (state == Enable) - OS << "enable"; - else if (state == Full) - OS << "full"; - else if (state == AssumeSafety) - OS << "assume_safety"; - else - OS << "disable"; - OS << ")"; - return OS.str(); - } + std::string getValueString(const PrintingPolicy &Policy) const; // Return a string suitable for identifying this attribute in diagnostics. - std::string getDiagnosticName(const PrintingPolicy &Policy) const { - unsigned SpellingIndex = getAttributeSpellingListIndex(); - if (SpellingIndex == Pragma_nounroll) - return "#pragma nounroll"; - else if (SpellingIndex == Pragma_unroll) - return "#pragma unroll" + (option == UnrollCount ? getValueString(Policy) : ""); - else if (SpellingIndex == Pragma_nounroll_and_jam) - return "#pragma nounroll_and_jam"; - else if (SpellingIndex == Pragma_unroll_and_jam) - return "#pragma unroll_and_jam" + - (option == UnrollAndJamCount ? getValueString(Policy) : ""); - - assert(SpellingIndex == Pragma_clang_loop && "Unexpected spelling"); - return getOptionName(option) + getValueString(Policy); - } + std::string getDiagnosticName(const PrintingPolicy &Policy) const; }]; let Documentation = [LoopHintDocs, UnrollHintDocs]; @@ -3189,8 +3247,13 @@ def OMPCaptureKind : Attr { // This attribute has no spellings as it is only ever created implicitly. let Spellings = []; let SemaHandler = 0; - let Args = [UnsignedArgument<"CaptureKind">]; + let Args = [UnsignedArgument<"CaptureKindVal">]; let Documentation = [Undocumented]; + let AdditionalMembers = [{ + llvm::omp::Clause getCaptureKind() const { + return static_cast<llvm::omp::Clause>(getCaptureKindVal()); + } + }]; } def OMPReferencedVar : Attr { @@ -3218,53 +3281,7 @@ def OMPDeclareSimdDecl : Attr { ]; let AdditionalMembers = [{ void printPrettyPragma(raw_ostream & OS, const PrintingPolicy &Policy) - const { - if (getBranchState() != BS_Undefined) - OS << ' ' << ConvertBranchStateTyToStr(getBranchState()); - if (auto *E = getSimdlen()) { - OS << " simdlen("; - E->printPretty(OS, nullptr, Policy); - OS << ")"; - } - if (uniforms_size() > 0) { - OS << " uniform"; - StringRef Sep = "("; - for (auto *E : uniforms()) { - OS << Sep; - E->printPretty(OS, nullptr, Policy); - Sep = ", "; - } - OS << ")"; - } - alignments_iterator NI = alignments_begin(); - for (auto *E : aligneds()) { - OS << " aligned("; - E->printPretty(OS, nullptr, Policy); - if (*NI) { - OS << ": "; - (*NI)->printPretty(OS, nullptr, Policy); - } - OS << ")"; - ++NI; - } - steps_iterator I = steps_begin(); - modifiers_iterator MI = modifiers_begin(); - for (auto *E : linears()) { - OS << " linear("; - if (*MI != OMPC_LINEAR_unknown) - OS << getOpenMPSimpleClauseTypeName(OMPC_linear, *MI) << "("; - E->printPretty(OS, nullptr, Policy); - if (*MI != OMPC_LINEAR_unknown) - OS << ")"; - if (*I) { - OS << ": "; - (*I)->printPretty(OS, nullptr, Policy); - } - OS << ")"; - ++I; - ++MI; - } - } + const; }]; } @@ -3282,30 +3299,10 @@ def OMPDeclareTargetDecl : InheritableAttr { [ "DT_Host", "DT_NoHost", "DT_Any" ]> ]; let AdditionalMembers = [{ - void printPrettyPragma(raw_ostream &OS, const PrintingPolicy &Policy) const { - // Use fake syntax because it is for testing and debugging purpose only. - if (getDevType() != DT_Any) - OS << " device_type(" << ConvertDevTypeTyToStr(getDevType()) << ")"; - if (getMapType() != MT_To) - OS << ' ' << ConvertMapTypeTyToStr(getMapType()); - } + void printPrettyPragma(raw_ostream &OS, const PrintingPolicy &Policy) const; static llvm::Optional<MapTypeTy> - isDeclareTargetDeclaration(const ValueDecl *VD) { - if (!VD->hasAttrs()) - return llvm::None; - if (const auto *Attr = VD->getAttr<OMPDeclareTargetDeclAttr>()) - return Attr->getMapType(); - - return llvm::None; - } - static llvm::Optional<DevTypeTy> getDeviceType(const ValueDecl *VD) { - if (!VD->hasAttrs()) - return llvm::None; - if (const auto *Attr = VD->getAttr<OMPDeclareTargetDeclAttr>()) - return Attr->getDevType(); - - return llvm::None; - } + isDeclareTargetDeclaration(const ValueDecl *VD); + static llvm::Optional<DevTypeTy> getDeviceType(const ValueDecl *VD); }]; } @@ -3316,14 +3313,16 @@ def OMPAllocateDecl : InheritableAttr { let Args = [ EnumArgument<"AllocatorType", "AllocatorTypeTy", [ - "omp_default_mem_alloc", "omp_large_cap_mem_alloc", - "omp_const_mem_alloc", "omp_high_bw_mem_alloc", - "omp_low_lat_mem_alloc", "omp_cgroup_mem_alloc", - "omp_pteam_mem_alloc", "omp_thread_mem_alloc", "" + "omp_null_allocator", "omp_default_mem_alloc", + "omp_large_cap_mem_alloc", "omp_const_mem_alloc", + "omp_high_bw_mem_alloc", "omp_low_lat_mem_alloc", + "omp_cgroup_mem_alloc", "omp_pteam_mem_alloc", + "omp_thread_mem_alloc", "" ], [ - "OMPDefaultMemAlloc", "OMPLargeCapMemAlloc", - "OMPConstMemAlloc", "OMPHighBWMemAlloc", "OMPLowLatMemAlloc", + "OMPNullMemAlloc", "OMPDefaultMemAlloc", + "OMPLargeCapMemAlloc", "OMPConstMemAlloc", + "OMPHighBWMemAlloc", "OMPLowLatMemAlloc", "OMPCGroupMemAlloc", "OMPPTeamMemAlloc", "OMPThreadMemAlloc", "OMPUserDefinedMemAlloc" ]>, @@ -3341,89 +3340,12 @@ def OMPDeclareVariant : InheritableAttr { let Documentation = [OMPDeclareVariantDocs]; let Args = [ ExprArgument<"VariantFuncRef">, - VariadicExprArgument<"Scores">, - VariadicUnsignedArgument<"CtxSelectorSets">, - VariadicUnsignedArgument<"CtxSelectors">, - VariadicStringArgument<"ImplVendors">, - VariadicStringArgument<"DeviceKinds"> + OMPTraitInfoArgument<"TraitInfos">, ]; let AdditionalMembers = [{ - void printScore(raw_ostream & OS, const PrintingPolicy &Policy, unsigned I) const { - if (const Expr *E = *std::next(scores_begin(), I)) { - OS << "score("; - E->printPretty(OS, nullptr, Policy); - OS << "):"; - } - } + OMPTraitInfo &getTraitInfo() { return *traitInfos; } void printPrettyPragma(raw_ostream & OS, const PrintingPolicy &Policy) - const { - if (const Expr *E = getVariantFuncRef()) { - OS << "("; - E->printPretty(OS, nullptr, Policy); - OS << ")"; - } - // TODO: add printing of real context selectors. - OS << " match("; - int Used[OMP_CTX_SET_unknown] = {0}; - for (unsigned I = 0, E = ctxSelectorSets_size(); I < E; ++I) { - auto CtxSet = static_cast<OpenMPContextSelectorSetKind>( - *std::next(ctxSelectorSets_begin(), I)); - if (Used[CtxSet]) - continue; - if (I > 0) - OS << ","; - switch (CtxSet) { - case OMP_CTX_SET_implementation: - OS << "implementation={"; - break; - case OMP_CTX_SET_device: - OS << "device={"; - break; - case OMP_CTX_SET_unknown: - llvm_unreachable("Unknown context selector set."); - } - Used[CtxSet] = 1; - for (unsigned K = I, EK = ctxSelectors_size(); K < EK; ++K) { - auto CtxSetK = static_cast<OpenMPContextSelectorSetKind>( - *std::next(ctxSelectorSets_begin(), K)); - if (CtxSet != CtxSetK) - continue; - if (K != I) - OS << ","; - auto Ctx = static_cast<OpenMPContextSelectorKind>( - *std::next(ctxSelectors_begin(), K)); - switch (Ctx) { - case OMP_CTX_vendor: - assert(CtxSet == OMP_CTX_SET_implementation && - "Expected implementation context selector set."); - OS << "vendor("; - printScore(OS, Policy, K); - if (implVendors_size() > 0) { - OS << *implVendors(). begin(); - for (StringRef VendorName : llvm::drop_begin(implVendors(), 1)) - OS << ", " << VendorName; - } - OS << ")"; - break; - case OMP_CTX_kind: - assert(CtxSet == OMP_CTX_SET_device && - "Expected device context selector set."); - OS << "kind("; - if (deviceKinds_size() > 0) { - OS << *deviceKinds().begin(); - for (StringRef KindName : llvm::drop_begin(deviceKinds(), 1)) - OS << ", " << KindName; - } - OS << ")"; - break; - case OMP_CTX_unknown: - llvm_unreachable("Unknown context selector."); - } - } - OS << "}"; - } - OS << ")"; - } + const; }]; } @@ -3438,12 +3360,14 @@ def ExcludeFromExplicitInstantiation : InheritableAttr { let Subjects = SubjectList<[Var, Function, CXXRecord]>; let Documentation = [ExcludeFromExplicitInstantiationDocs]; let MeaningfulToClassTemplateDefinition = 1; + let SimpleHandler = 1; } def Reinitializes : InheritableAttr { let Spellings = [Clang<"reinitializes", 0>]; let Subjects = SubjectList<[NonStaticNonConstCXXMethod], ErrorDiag>; let Documentation = [ReinitializesDocs]; + let SimpleHandler = 1; } def NoDestroy : InheritableAttr { @@ -3473,9 +3397,16 @@ def NoSpeculativeLoadHardening : InheritableAttr { def Uninitialized : InheritableAttr { let Spellings = [Clang<"uninitialized", 0>]; let Subjects = SubjectList<[LocalVar]>; + let PragmaAttributeSupport = 1; let Documentation = [UninitializedDocs]; } +def LoaderUninitialized : Attr { + let Spellings = [Clang<"loader_uninitialized">]; + let Subjects = SubjectList<[GlobalVar]>; + let Documentation = [LoaderUninitializedDocs]; +} + def ObjCExternallyRetained : InheritableAttr { let LangOpts = [ObjCAutoRefCount]; let Spellings = [Clang<"objc_externally_retained">]; diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td index 03d36ae7ab32..3cba3a3d96f9 100644 --- a/clang/include/clang/Basic/AttrDocs.td +++ b/clang/include/clang/Basic/AttrDocs.td @@ -140,7 +140,8 @@ def NoEscapeDocs : Documentation { the compiler that the pointer cannot escape: that is, no reference to the object the pointer points to that is derived from the parameter value will survive after the function returns. Users are responsible for making sure parameters -annotated with ``noescape`` do not actuallly escape. +annotated with ``noescape`` do not actually escape. Calling ``free()`` on such +a parameter does not constitute an escape. For example: @@ -260,6 +261,7 @@ The ``sycl_kernel`` attribute specifies that a function template will be used to outline device code and to generate an OpenCL kernel. Here is a code example of the SYCL program, which demonstrates the compiler's outlining job: + .. code-block:: c++ int foo(int x) { return ++x; } @@ -282,27 +284,29 @@ compilation of functions for the device part can be found in the SYCL 1.2.1 specification Section 6.4. To show to the compiler entry point to the "device part" of the code, the SYCL runtime can use the ``sycl_kernel`` attribute in the following way: + .. code-block:: c++ -namespace cl { -namespace sycl { -class handler { - template <typename KernelName, typename KernelType/*, ...*/> - __attribute__((sycl_kernel)) void sycl_kernel_function(KernelType KernelFuncObj) { - // ... - KernelFuncObj(); - } - template <typename KernelName, typename KernelType, int Dims> - void parallel_for(range<Dims> NumWorkItems, KernelType KernelFunc) { -#ifdef __SYCL_DEVICE_ONLY__ - sycl_kernel_function<KernelName, KernelType, Dims>(KernelFunc); -#else - // Host implementation -#endif - } -}; -} // namespace sycl -} // namespace cl + namespace cl { + namespace sycl { + class handler { + template <typename KernelName, typename KernelType/*, ...*/> + __attribute__((sycl_kernel)) void sycl_kernel_function(KernelType KernelFuncObj) { + // ... + KernelFuncObj(); + } + + template <typename KernelName, typename KernelType, int Dims> + void parallel_for(range<Dims> NumWorkItems, KernelType KernelFunc) { + #ifdef __SYCL_DEVICE_ONLY__ + sycl_kernel_function<KernelName, KernelType, Dims>(KernelFunc); + #else + // Host implementation + #endif + } + }; + } // namespace sycl + } // namespace cl The compiler will also generate an OpenCL kernel using the function marked with the ``sycl_kernel`` attribute. @@ -320,7 +324,7 @@ function marked with the ``sycl_kernel`` attribute: compiler uses function object type fields to generate OpenCL kernel parameters. - The function must return void. The compiler reuses the body of marked functions to - generate the OpenCL kernel body, and the OpenCL kernel must return `void`. + generate the OpenCL kernel body, and the OpenCL kernel must return ``void``. The SYCL kernel in the previous code sample meets these expectations. }]; @@ -346,6 +350,20 @@ that appears to be capable of returning to its caller. }]; } +def NoMergeDocs : Documentation { + let Category = DocCatFunction; + let Content = [{ +If a statement is marked ``nomerge`` and contains call experessions, those call +expressions inside the statement will not be merged during optimization. This +attribute can be used to prevent the optimizer from obscuring the source +location of certain calls. For example, it will prevent tail merging otherwise +identical code sequences that raise an exception or terminate the program. Tail +merging normally reduces the precision of source location information, making +stack traces less useful for debugging. This attribute gives the user control +over the tradeoff between code size and debug information precision. + }]; +} + def AssertCapabilityDocs : Documentation { let Category = DocCatFunction; let Heading = "assert_capability, assert_shared_capability"; @@ -481,7 +499,7 @@ parameter. Note that this attribute merely informs the compiler that a function always returns a sufficiently aligned pointer. It does not cause the compiler to emit code to enforce that alignment. The behavior is undefined if the returned -poitner is not sufficiently aligned. +pointer is not sufficiently aligned. }]; } @@ -939,11 +957,11 @@ The behavior of a function with respect to reference counting for Foundation convention (e.g. functions starting with "get" are assumed to return at ``+0``). -It can be overriden using a family of the following attributes. In +It can be overridden using a family of the following attributes. In Objective-C, the annotation ``__attribute__((ns_returns_retained))`` applied to a function communicates that the object is returned at ``+1``, and the caller is responsible for freeing it. -Similiarly, the annotation ``__attribute__((ns_returns_not_retained))`` +Similarly, the annotation ``__attribute__((ns_returns_not_retained))`` specifies that the object is returned at ``+0`` and the ownership remains with the callee. The annotation ``__attribute__((ns_consumes_self))`` specifies that @@ -1159,7 +1177,7 @@ def ObjCRuntimeNameDocs : Documentation { let Category = DocCatDecl; let Content = [{ By default, the Objective-C interface or protocol identifier is used -in the metadata name for that object. The `objc_runtime_name` +in the metadata name for that object. The ``objc_runtime_name`` attribute allows annotated interfaces or protocols to use the specified string argument in the object's metadata name instead of the default name. @@ -1287,7 +1305,7 @@ correspond to different platforms. For most platforms, the availability attribute with the platform corresponding to the target platform will be used; any others will be ignored. However, the availability for ``watchOS`` and ``tvOS`` can be implicitly inferred from an ``iOS`` availability attribute. -Any explicit availability attributes for those platforms are still prefered over +Any explicit availability attributes for those platforms are still preferred over the implicitly inferred availability attributes. If no availability attribute specifies availability for the current target platform, the availability attributes are ignored. Supported platforms are: @@ -1395,7 +1413,7 @@ pragma rather than using the inferred ``iOS`` availability from the declaration: void getsThePragmaTVOSAvailabilityAttribute(void) __attribute__((availability(iOS,introduced=11.0))); #pragma clang attribute pop -The compiler is also able to apply implicly inferred attributes from a pragma +The compiler is also able to apply implicitly inferred attributes from a pragma as well. For example, when targeting ``tvOS``, the function below will receive a ``tvOS`` availability attribute that is implicitly inferred from the ``iOS`` availability attribute applied by the pragma: @@ -1563,7 +1581,7 @@ expression are discarded under suspicious circumstances. A diagnostic is generated when a function or its return type is marked with ``[[nodiscard]]`` (or ``__attribute__((warn_unused_result))``) and the function call appears as a potentially-evaluated discarded-value expression that is not explicitly cast to -`void`. +``void``. A string literal may optionally be provided to the attribute, which will be reproduced in any resulting diagnostics. Redeclarations using different forms @@ -1713,7 +1731,7 @@ def BPFPreserveAccessIndexDocs : Documentation { Clang supports the ``__attribute__((preserve_access_index))`` attribute for the BPF target. This attribute may be attached to a struct or union declaration, where if -g is specified, it enables -preserving struct or union member access debuginfo indicies of this +preserving struct or union member access debuginfo indices of this struct or union, similar to clang ``__builtin_preserve_acceess_index()``. }]; } @@ -1729,7 +1747,7 @@ 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" +generated interrupt. This behavior can be explicitly requested with the "eic" argument. Otherwise, for use with vectored interrupt mode, the argument passed should be @@ -1767,7 +1785,7 @@ Clang supports the GNU style ``__attribute__((micromips))`` and may be attached to a function definition and instructs the backend to generate or not to generate microMIPS code for that function. -These attributes override the `-mmicromips` and `-mno-micromips` options +These attributes override the ``-mmicromips`` and ``-mno-micromips`` options on the command line. }]; } @@ -2764,11 +2782,13 @@ The ``trivial_abi`` attribute can be applied to a C++ class, struct, or union. It instructs the compiler to pass and return the type using the C ABI for the underlying type when the type would otherwise be considered non-trivial for the purpose of calls. -A class annotated with `trivial_abi` can have non-trivial destructors or copy/move constructors without automatically becoming non-trivial for the purposes of calls. For example: +A class annotated with ``trivial_abi`` can have non-trivial destructors or +copy/move constructors without automatically becoming non-trivial for the +purposes of calls. For example: .. code-block:: c++ - // A is trivial for the purposes of calls because `trivial_abi` makes the + // A is trivial for the purposes of calls because ``trivial_abi`` makes the // user-provided special functions trivial. struct __attribute__((trivial_abi)) A { ~A(); @@ -2790,6 +2810,7 @@ destroy the object before returning. Attribute ``trivial_abi`` has no effect in the following cases: - The class directly declares a virtual base or virtual methods. +- Copy constructors and move constructors of the class are all deleted. - The class has a base class that is non-trivial for the purposes of calls. - The class has a non-static data member whose type is non-trivial for the purposes of calls, which includes: @@ -3296,15 +3317,15 @@ def OMPDeclareSimdDocs : Documentation { let Category = DocCatFunction; let Heading = "#pragma omp declare simd"; let Content = [{ -The `declare simd` construct can be applied to a function to enable the creation +The ``declare simd`` construct can be applied to a function to enable the creation of one or more versions that can process multiple arguments using SIMD -instructions from a single invocation in a SIMD loop. The `declare simd` -directive is a declarative directive. There may be multiple `declare simd` -directives for a function. The use of a `declare simd` construct on a function +instructions from a single invocation in a SIMD loop. The ``declare simd`` +directive is a declarative directive. There may be multiple ``declare simd`` +directives for a function. The use of a ``declare simd`` construct on a function enables the creation of SIMD versions of the associated function that can be used to process multiple arguments from a single invocation from a SIMD loop concurrently. -The syntax of the `declare simd` construct is as follows: +The syntax of the ``declare simd`` construct is as follows: .. code-block:: none @@ -3331,7 +3352,7 @@ def OMPDeclareTargetDocs : Documentation { let Category = DocCatFunction; let Heading = "#pragma omp declare target"; let Content = [{ -The `declare target` directive specifies that variables and functions are mapped +The ``declare target`` directive specifies that variables and functions are mapped to a device for OpenMP offload mechanism. The syntax of the declare target directive is as follows: @@ -3369,10 +3390,10 @@ def OMPDeclareVariantDocs : Documentation { let Category = DocCatFunction; let Heading = "#pragma omp declare variant"; let Content = [{ -The `declare variant` directive declares a specialized variant of a base - function and specifies the context in which that specialized variant is used. - The declare variant directive is a declarative directive. -The syntax of the `declare variant` construct is as follows: +The ``declare variant`` directive declares a specialized variant of a base +function and specifies the context in which that specialized variant is used. +The declare variant directive is a declarative directive. +The syntax of the ``declare variant`` construct is as follows: .. code-block:: none @@ -3387,8 +3408,23 @@ where clause is one of the following: match(context-selector-specification) -and where `variant-func-id` is the name of a function variant that is either a - base language identifier or, for C++, a template-id. +and where ``variant-func-id`` is the name of a function variant that is either a +base language identifier or, for C++, a template-id. + +Clang provides the following context selector extensions, used via +``implementation={extension(EXTENSION)}``: + + .. code-block:: none + + match_all + match_any + match_none + +The match extensions change when the *entire* context selector is considered a +match for an OpenMP context. The default is ``all``, with ``none`` no trait in the +selector is allowed to be in the OpenMP context, with ``any`` a single trait in +both the selector and OpenMP context is sufficient. Only a single match +extension trait is allowed per context selector. }]; } @@ -3473,7 +3509,7 @@ def NoThrowDocs : Documentation { let Category = DocCatFunction; let Content = [{ Clang supports the GNU style ``__attribute__((nothrow))`` and Microsoft style -``__declspec(nothrow)`` attribute as an equivalent of `noexcept` on function +``__declspec(nothrow)`` attribute as an equivalent of ``noexcept`` on function declarations. This attribute informs the compiler that the annotated function does not throw an exception. This prevents exception-unwinding. This attribute is particularly useful on functions in the C Standard Library that are @@ -3676,7 +3712,7 @@ using the Swift calling convention for a function or function pointer. The lowering for the Swift calling convention, as described by the Swift ABI documentation, occurs in multiple phases. The first, "high-level" phase breaks down the formal parameters and results into innately direct -and indirect components, adds implicit paraameters for the generic +and indirect components, adds implicit parameters for the generic signature, and assigns the context and error ABI treatments to parameters where applicable. The second phase breaks down the direct parameters and results from the first phase and assigns them to registers or the @@ -3718,7 +3754,7 @@ of the first phase, as follows: ``swiftcall`` does not support variadic arguments or unprototyped functions. The parameter ABI treatment attributes are aspects of the function type. -A function type which which applies an ABI treatment attribute to a +A function type which applies an ABI treatment attribute to a parameter is a different type from an otherwise-identical function type that does not. A single parameter may not have multiple ABI treatment attributes. @@ -3847,7 +3883,7 @@ with different ABI versions supported. For example, a newer version of a class could have a different set of data members and thus have a different size. Using the ``abi_tag`` attribute, it is possible to have different mangled names for a global variable of the class type. Therefore, the old code could keep using -the old manged name and the new code will use the new mangled name with tags. +the old mangled name and the new code will use the new mangled name with tags. }]; } @@ -3873,10 +3909,10 @@ that have a hot path and a cold path. The hot path is usually a small piece of code that doesn't use many registers. The cold path might need to call out to another function and therefore only needs to preserve the caller-saved registers, which haven't already been saved by the caller. The -`preserve_most` calling convention is very similar to the ``cold`` calling +``preserve_most`` calling convention is very similar to the ``cold`` calling convention in terms of caller/callee-saved registers, but they are used for different types of function calls. ``coldcc`` is for function calls that are -rarely executed, whereas `preserve_most` function calls are intended to be +rarely executed, whereas ``preserve_most`` function calls are intended to be on the hot path and definitely executed a lot. Furthermore ``preserve_most`` doesn't prevent the inliner from inlining the function call. @@ -3930,11 +3966,11 @@ Consider the function declaration for a hypothetical function ``f``: void f(void) __attribute__((deprecated("message", "replacement"))); -When spelled as `__attribute__((deprecated))`, the deprecated attribute can have +When spelled as ``__attribute__((deprecated))``, the deprecated attribute can have two optional string arguments. The first one is the message to display when emitting the warning; the second one enables the compiler to provide a Fix-It to replace the deprecated name with a new name. Otherwise, when spelled as -`[[gnu::deprecated]] or [[deprecated]]`, the attribute can have one optional +``[[gnu::deprecated]]`` or ``[[deprecated]]``, the attribute can have one optional string argument which is the message to display when emitting the warning. }]; } @@ -3995,17 +4031,15 @@ def PatchableFunctionEntryDocs : Documentation { before the function entry and N-M NOPs after the function entry. This attribute takes precedence over the command line option ``-fpatchable-function-entry=N,M``. ``M`` defaults to 0 if omitted. - -Currently, only M=0 is supported. }]; } def TransparentUnionDocs : Documentation { let Category = DocCatDecl; let Content = [{ -This attribute can be applied to a union to change the behaviour of calls to +This attribute can be applied to a union to change the behavior of calls to functions that have an argument with a transparent union type. The compiler -behaviour is changed in the following manner: +behavior is changed in the following manner: - A value whose type is any member of the transparent union can be passed as an argument without the need to cast that value. @@ -4035,7 +4069,7 @@ initialized classes. A non-lazy class will be initialized eagerly when the Objective-C runtime is loaded. This is required for certain system classes which have instances allocated in non-standard ways, such as the classes for blocks and constant strings. Adding this attribute is essentially equivalent to -providing a trivial `+load` method but avoids the (fairly small) load-time +providing a trivial ``+load`` method but avoids the (fairly small) load-time overheads associated with defining and calling such a method. }]; } @@ -4075,8 +4109,8 @@ ways: including calling the ``+initialize`` method if present. - The implicit ``_cmd`` parameter containing the method's selector is still defined. - In order to minimize code-size costs, the implementation will not emit a reference - to the selector if the parameter is unused within the method. + In order to minimize code-size costs, the implementation will not emit a reference + to the selector if the parameter is unused within the method. Symbols for direct method implementations are implicitly given hidden visibility, meaning that they can only be called within the same linkage unit. @@ -4117,7 +4151,7 @@ documentation for more information. def ObjCDirectMembersDocs : Documentation { let Category = DocCatDecl; let Content = [{ -The ``objc_direct_members`` attribute can be placed on an Objective-C +The ``objc_direct_members`` attribute can be placed on an Objective-C ``@interface`` or ``@implementation`` to mark that methods declared therein should be considered direct by default. See the documentation for ``objc_direct`` for more information about direct methods. @@ -4126,9 +4160,7 @@ When ``objc_direct_members`` is placed on an ``@interface`` block, every method in the block is considered to be declared as direct. This includes any implicit method declarations introduced by property declarations. If the method redeclares a non-direct method, the declaration is ill-formed, exactly as if the -method was annotated with the ``objc_direct`` attribute. ``objc_direct_members`` -cannot be placed on the primary interface of a class, only on category or class -extension interfaces. +method was annotated with the ``objc_direct`` attribute. When ``objc_direct_members`` is placed on an ``@implementation`` block, methods defined in the block are considered to be declared as direct unless @@ -4331,7 +4363,7 @@ with this attribute. This is because previously constructed subobjects need to be destroyed if an exception gets thrown before the initialization of the complete object is complete. For instance: -.. code-block::c++ +.. code-block:: c++ void f() { try { @@ -4342,7 +4374,7 @@ complete object is complete. For instance: } } -Here, if the construction of `array[9]` fails with an exception, `array[0..8]` +Here, if the construction of ``array[9]`` fails with an exception, ``array[0..8]`` will be destroyed, so the element's destructor needs to be accessible. }]; } @@ -4359,6 +4391,29 @@ it rather documents the programmer's intent. }]; } +def LoaderUninitializedDocs : Documentation { + let Category = DocCatVariable; + let Content = [{ +The ``loader_uninitialized`` attribute can be placed on global variables to +indicate that the variable does not need to be zero initialized by the loader. +On most targets, zero-initialization does not incur any additional cost. +For example, most general purpose operating systems deliberately ensure +that all memory is properly initialized in order to avoid leaking privileged +information from the kernel or other programs. However, some targets +do not make this guarantee, and on these targets, avoiding an unnecessary +zero-initialization can have a significant impact on load times and/or code +size. + +A declaration with this attribute is a non-tentative definition just as if it +provided an initializer. Variables with this attribute are considered to be +uninitialized in the same sense as a local variable, and the programs must +write to them before reading from them. If the variable's type is a C++ class +type with a non-trivial default constructor, or an array thereof, this attribute +only suppresses the static zero-initialization of the variable, not the dynamic +initialization provided by executing the default constructor. + }]; +} + def CallbackDocs : Documentation { let Category = DocCatFunction; let Content = [{ @@ -4368,7 +4423,7 @@ arguments, are identified by their parameter name or position (starting with 1!) in the annotated function. The first position in the attribute identifies the callback callee, the following positions declare describe its arguments. The callback callee is required to be callable with the number, and order, of -the specified arguments. The index `0`, or the identifier `this`, is used to +the specified arguments. The index ``0``, or the identifier ``this``, is used to represent an implicit "this" pointer in class methods. If there is no implicit "this" pointer it shall not be referenced. The index '-1', or the name "__", represents an unknown callback callee argument. This can be a value which is @@ -4385,13 +4440,13 @@ position, it is undefined if that parameter is used for anything other than the actual callback. Inspected, captured, or modified parameters shall not be listed in the ``callback`` metadata. -Example encodings for the callback performed by `pthread_create` are shown +Example encodings for the callback performed by ``pthread_create`` are shown below. The explicit attribute annotation indicates that the third parameter -(`start_routine`) is called zero or more times by the `pthread_create` function, -and that the fourth parameter (`arg`) is passed along. Note that the callback -behavior of `pthread_create` is automatically recognized by Clang. In addition, -the declarations of `__kmpc_fork_teams` and `__kmpc_fork_call`, generated for -`#pragma omp target teams` and `#pragma omp parallel`, respectively, are also +(``start_routine``) is called zero or more times by the ``pthread_create`` function, +and that the fourth parameter (``arg``) is passed along. Note that the callback +behavior of ``pthread_create`` is automatically recognized by Clang. In addition, +the declarations of ``__kmpc_fork_teams`` and ``__kmpc_fork_call``, generated for +``#pragma omp target teams`` and ``#pragma omp parallel``, respectively, are also automatically recognized as broker functions. Further functions might be added in the future. @@ -4516,7 +4571,7 @@ When applied to the definition of a function, method, or block, every parameter of the function with implicit strong retainable object pointer type is considered externally-retained, and becomes ``const``. By explicitly annotating a parameter with ``__strong``, you can opt back into the default -non-externally-retained behaviour for that parameter. For instance, +non-externally-retained behavior for that parameter. For instance, ``first_param`` is externally-retained below, but not ``second_param``: .. code-block:: objc @@ -4538,7 +4593,7 @@ def MIGConventionDocs : Documentation { The Mach Interface Generator release-on-success convention dictates functions that follow it to only release arguments passed to them when they return "success" (a ``kern_return_t`` error code that indicates that -no errors have occured). Otherwise the release is performed by the MIG client +no errors have occurred). Otherwise the release is performed by the MIG client that called the function. The annotation ``__attribute__((mig_server_routine))`` is applied in order to specify which functions are expected to follow the convention. This allows the Static Analyzer to find bugs caused by violations of @@ -4590,15 +4645,25 @@ only call one function. }]; } -def HIPPinnedShadowDocs : Documentation { +def CUDADeviceBuiltinSurfaceTypeDocs : Documentation { let Category = DocCatType; let Content = [{ -The GNU style attribute __attribute__((hip_pinned_shadow)) or MSVC style attribute -__declspec(hip_pinned_shadow) can be added to the definition of a global variable -to indicate it is a HIP pinned shadow variable. A HIP pinned shadow variable can -be accessed on both device side and host side. It has external linkage and is -not initialized on device side. It has internal linkage and is initialized by -the initializer on host side. +The ``device_builtin_surface_type`` attribute can be applied to a class +template when declaring the surface reference. A surface reference variable +could be accessed on the host side and, on the device side, might be translated +into an internal surface object, which is established through surface bind and +unbind runtime APIs. + }]; +} + +def CUDADeviceBuiltinTextureTypeDocs : Documentation { + let Category = DocCatType; + let Content = [{ +The ``device_builtin_texture_type`` attribute can be applied to a class +template when declaring the texture reference. A texture reference variable +could be accessed on the host side and, on the device side, might be translated +into an internal texture object, which is established through texture bind and +unbind runtime APIs. }]; } @@ -4611,7 +4676,7 @@ def LifetimeOwnerDocs : Documentation { The attribute ``[[gsl::Owner(T)]]`` applies to structs and classes that own an object of type ``T``: -.. code-block:: c++ +.. code:: class [[gsl::Owner(int)]] IntOwner { private: @@ -4637,7 +4702,7 @@ def LifetimePointerDocs : Documentation { The attribute ``[[gsl::Pointer(T)]]`` applies to structs and classes that behave like pointers to an object of type ``T``: -.. code-block:: c++ +.. code:: class [[gsl::Pointer(int)]] IntPointer { private: @@ -4670,11 +4735,11 @@ When the Owner's lifetime ends, it will consider the Pointer to be dangling. }]; } -def ArmMveAliasDocs : Documentation { +def ArmBuiltinAliasDocs : Documentation { let Category = DocCatFunction; let Content = [{ -This attribute is used in the implementation of the ACLE intrinsics -for the Arm MVE instruction set. It allows the intrinsic functions to +This attribute is used in the implementation of the ACLE intrinsics. +It allows the intrinsic functions to be declared using the names defined in ACLE, and still be recognized as clang builtins equivalent to the underlying name. For example, ``arm_mve.h`` declares the function ``vaddq_u32`` with @@ -4685,8 +4750,8 @@ recognized as that clang builtin, and in the latter case, the choice of which builtin to identify the function as can be deferred until after overload resolution. -This attribute can only be used to set up the aliases for the MVE -intrinsic functions; it is intended for use only inside ``arm_mve.h``, +This attribute can only be used to set up the aliases for certain Arm +intrinsic functions; it is intended for use only inside ``arm_*.h`` and is not a general mechanism for declaring arbitrary aliases for clang builtin functions. }]; @@ -4696,7 +4761,7 @@ def NoBuiltinDocs : Documentation { let Category = DocCatFunction; let Content = [{ .. Note:: This attribute is not yet fully implemented, it is validated but has -no effect on the generated code. + no effect on the generated code. The ``__attribute__((no_builtin))`` is similar to the ``-fno-builtin`` flag except it is specific to the body of a function. The attribute may also be @@ -4767,7 +4832,7 @@ def UseHandleDocs : Documentation { let Category = HandleDocs; let Content = [{ A function taking a handle by value might close the handle. If a function -parameter is annotated with `use_handle` it is assumed to not to change +parameter is annotated with ``use_handle`` it is assumed to not to change the state of the handle. It is also assumed to require an open handle to work with. .. code-block:: c++ @@ -4781,7 +4846,7 @@ the state of the handle. It is also assumed to require an open handle to work wi def ReleaseHandleDocs : Documentation { let Category = HandleDocs; let Content = [{ -If a function parameter is annotated with `release_handle` it is assumed to +If a function parameter is annotated with ``release_handle`` it is assumed to close the handle. It is also assumed to require an open handle to work with. .. code-block:: c++ @@ -4789,3 +4854,70 @@ close the handle. It is also assumed to require an open handle to work with. zx_status_t zx_handle_close(zx_handle_t handle [[clang::release_handle]]); }]; } + +def ArmMveStrictPolymorphismDocs : Documentation { + let Category = DocCatType; + let Content = [{ +This attribute is used in the implementation of the ACLE intrinsics for the Arm +MVE instruction set. It is used to define the vector types used by the MVE +intrinsics. + +Its effect is to modify the behavior of a vector type with respect to function +overloading. If a candidate function for overload resolution has a parameter +type with this attribute, then the selection of that candidate function will be +disallowed if the actual argument can only be converted via a lax vector +conversion. The aim is to prevent spurious ambiguity in ARM MVE polymorphic +intrinsics. + +.. code-block:: c++ + + void overloaded(uint16x8_t vector, uint16_t scalar); + void overloaded(int32x4_t vector, int32_t scalar); + uint16x8_t myVector; + uint16_t myScalar; + + // myScalar is promoted to int32_t as a side effect of the addition, + // so if lax vector conversions are considered for myVector, then + // the two overloads are equally good (one argument conversion + // each). But if the vector has the __clang_arm_mve_strict_polymorphism + // attribute, only the uint16x8_t,uint16_t overload will match. + overloaded(myVector, myScalar + 1); + +However, this attribute does not prohibit lax vector conversions in contexts +other than overloading. + +.. code-block:: c++ + + uint16x8_t function(); + + // This is still permitted with lax vector conversion enabled, even + // if the vector types have __clang_arm_mve_strict_polymorphism + int32x4_t result = function(); + + }]; +} + +def ArmCmseNSCallDocs : Documentation { + let Category = DocCatType; + let Content = [{ +This attribute declares a non-secure function type. When compiling for secure +state, a call to such a function would switch from secure to non-secure state. +All non-secure function calls must happen only through a function pointer, and +a non-secure function type should only be used as a base type of a pointer. +See `ARMv8-M Security Extensions: Requirements on Development +Tools - Engineering Specification Documentation +<https://developer.arm.com/docs/ecm0359818/latest/>`_ for more information. + }]; +} + +def ArmCmseNSEntryDocs : Documentation { + let Category = DocCatFunction; + let Content = [{ +This attribute declares a function that can be called from non-secure state, or +from secure state. Entering from and returning to non-secure state would switch +to and from secure state, respectively, and prevent flow of information +to non-secure state, except via return values. See `ARMv8-M Security Extensions: +Requirements on Development Tools - Engineering Specification Documentation +<https://developer.arm.com/docs/ecm0359818/latest/>`_ for more information. + }]; +} diff --git a/clang/include/clang/Basic/AttributeCommonInfo.h b/clang/include/clang/Basic/AttributeCommonInfo.h index 545e7e9a2b47..f4a5db84aa9f 100644 --- a/clang/include/clang/Basic/AttributeCommonInfo.h +++ b/clang/include/clang/Basic/AttributeCommonInfo.h @@ -134,6 +134,11 @@ public: const IdentifierInfo *getScopeName() const { return ScopeName; } SourceLocation getScopeLoc() const { return ScopeLoc; } + /// Gets the normalized full name, which consists of both scope and name and + /// with surrounding underscores removed as appropriate (e.g. + /// __gnu__::__attr__ will be normalized to gnu::attr). + std::string getNormalizedFullName() const; + bool isDeclspecAttribute() const { return SyntaxUsed == AS_Declspec; } bool isMicrosoftAttribute() const { return SyntaxUsed == AS_Microsoft; } diff --git a/clang/include/clang/Basic/Builtins.def b/clang/include/clang/Basic/Builtins.def index d388afe7fae6..1416a64543a4 100644 --- a/clang/include/clang/Basic/Builtins.def +++ b/clang/include/clang/Basic/Builtins.def @@ -36,6 +36,7 @@ // a -> __builtin_va_list // A -> "reference" to __builtin_va_list // V -> Vector, followed by the number of elements and the base type. +// q -> Scalable vector, followed by the number of elements and the base type. // E -> ext_vector, followed by the number of elements and the base type. // X -> _Complex, followed by the base type. // Y -> ptrdiff_t @@ -64,6 +65,7 @@ // & -> reference (optionally followed by an address space number) // C -> const // D -> volatile +// R -> restrict // The third value provided to the macro specifies information about attributes // of the function. These must be kept in sync with the predicates in the @@ -322,6 +324,9 @@ BUILTIN(__builtin_truncf, "ff", "Fnc") BUILTIN(__builtin_truncl, "LdLd", "Fnc") BUILTIN(__builtin_truncf16, "hh", "Fnc") +// Access to floating point environment +BUILTIN(__builtin_flt_rounds, "i", "n") + // C99 complex builtins BUILTIN(__builtin_cabs, "dXd", "Fne") BUILTIN(__builtin_cabsf, "fXf", "Fne") @@ -471,7 +476,7 @@ BUILTIN(__builtin___NSStringMakeConstantString, "FC*cC*", "nc") BUILTIN(__builtin_va_start, "vA.", "nt") BUILTIN(__builtin_va_end, "vA", "n") BUILTIN(__builtin_va_copy, "vAA", "n") -BUILTIN(__builtin_stdarg_start, "vA.", "n") +BUILTIN(__builtin_stdarg_start, "vA.", "nt") BUILTIN(__builtin_assume_aligned, "v*vC*z.", "nc") BUILTIN(__builtin_bcmp, "ivC*vC*z", "Fn") BUILTIN(__builtin_bcopy, "vv*v*z", "n") @@ -480,6 +485,7 @@ BUILTIN(__builtin_fprintf, "iP*cC*.", "Fp:1:") BUILTIN(__builtin_memchr, "v*vC*iz", "nF") BUILTIN(__builtin_memcmp, "ivC*vC*z", "nF") BUILTIN(__builtin_memcpy, "v*v*vC*z", "nF") +BUILTIN(__builtin_memcpy_inline, "vv*vC*Iz", "nt") BUILTIN(__builtin_memmove, "v*v*vC*z", "nF") BUILTIN(__builtin_mempcpy, "v*v*vC*z", "nF") BUILTIN(__builtin_memset, "v*v*iz", "nF") @@ -515,7 +521,6 @@ BUILTIN(__builtin_return_address, "v*IUi", "n") BUILTIN(__builtin_extract_return_addr, "v*v*", "n") BUILTIN(__builtin_frame_address, "v*IUi", "n") BUILTIN(__builtin___clear_cache, "vc*c*", "n") -BUILTIN(__builtin_flt_rounds, "i", "nc") BUILTIN(__builtin_setjmp, "iv**", "j") BUILTIN(__builtin_longjmp, "vv**i", "r") BUILTIN(__builtin_unwind_init, "v", "") @@ -562,6 +567,7 @@ BUILTIN(__builtin___vprintf_chk, "iicC*a", "FP:1:") BUILTIN(__builtin_unpredictable, "LiLi" , "nc") BUILTIN(__builtin_expect, "LiLiLi" , "nc") +BUILTIN(__builtin_expect_with_probability, "LiLiLid", "nc") BUILTIN(__builtin_prefetch, "vvC*.", "nc") BUILTIN(__builtin_readcyclecounter, "ULLi", "n") BUILTIN(__builtin_trap, "v", "nr") @@ -573,6 +579,10 @@ BUILTIN(__builtin_alloca, "v*z" , "Fn") BUILTIN(__builtin_alloca_with_align, "v*zIz", "Fn") BUILTIN(__builtin_call_with_static_chain, "v.", "nt") +BUILTIN(__builtin_matrix_transpose, "v.", "nFt") +BUILTIN(__builtin_matrix_column_major_load, "v.", "nFt") +BUILTIN(__builtin_matrix_column_major_store, "v.", "nFt") + // "Overloaded" Atomic operator builtins. These are overloaded to support data // types of i8, i16, i32, i64, and i128. The front-end sees calls to the // non-suffixed version of these (which has a bogus type) and transforms them to @@ -722,7 +732,7 @@ ATOMIC_BUILTIN(__c11_atomic_fetch_max, "v.", "t") ATOMIC_BUILTIN(__c11_atomic_fetch_min, "v.", "t") BUILTIN(__c11_atomic_thread_fence, "vi", "n") BUILTIN(__c11_atomic_signal_fence, "vi", "n") -BUILTIN(__c11_atomic_is_lock_free, "iz", "n") +BUILTIN(__c11_atomic_is_lock_free, "bz", "n") // GNU atomic builtins. ATOMIC_BUILTIN(__atomic_load, "v.", "t") @@ -751,8 +761,8 @@ BUILTIN(__atomic_test_and_set, "bvD*i", "n") BUILTIN(__atomic_clear, "vvD*i", "n") BUILTIN(__atomic_thread_fence, "vi", "n") BUILTIN(__atomic_signal_fence, "vi", "n") -BUILTIN(__atomic_always_lock_free, "izvCD*", "n") -BUILTIN(__atomic_is_lock_free, "izvCD*", "n") +BUILTIN(__atomic_always_lock_free, "bzvCD*", "n") +BUILTIN(__atomic_is_lock_free, "bzvCD*", "n") // OpenCL 2.0 atomic builtins. ATOMIC_BUILTIN(__opencl_atomic_init, "v.", "t") @@ -788,6 +798,9 @@ BUILTIN(__builtin_abort, "v", "Fnr") BUILTIN(__builtin_index, "c*cC*i", "Fn") BUILTIN(__builtin_rindex, "c*cC*i", "Fn") +// ignored glibc builtin, see https://sourceware.org/bugzilla/show_bug.cgi?id=25399 +BUILTIN(__warn_memset_zero_len, "v", "nU") + // Microsoft builtins. These are only active with -fms-extensions. LANGBUILTIN(_alloca, "v*z", "n", ALL_MS_LANGUAGES) LANGBUILTIN(__annotation, "wC*.","n", ALL_MS_LANGUAGES) diff --git a/clang/include/clang/Basic/BuiltinsAMDGPU.def b/clang/include/clang/Basic/BuiltinsAMDGPU.def index 9b3a0f96798f..042a86368559 100644 --- a/clang/include/clang/Basic/BuiltinsAMDGPU.def +++ b/clang/include/clang/Basic/BuiltinsAMDGPU.def @@ -33,6 +33,10 @@ BUILTIN(__builtin_amdgcn_workitem_id_x, "Ui", "nc") BUILTIN(__builtin_amdgcn_workitem_id_y, "Ui", "nc") BUILTIN(__builtin_amdgcn_workitem_id_z, "Ui", "nc") +BUILTIN(__builtin_amdgcn_workgroup_size_x, "Us", "nc") +BUILTIN(__builtin_amdgcn_workgroup_size_y, "Us", "nc") +BUILTIN(__builtin_amdgcn_workgroup_size_z, "Us", "nc") + BUILTIN(__builtin_amdgcn_mbcnt_hi, "UiUiUi", "nc") BUILTIN(__builtin_amdgcn_mbcnt_lo, "UiUiUi", "nc") @@ -40,6 +44,7 @@ BUILTIN(__builtin_amdgcn_mbcnt_lo, "UiUiUi", "nc") // Instruction builtins. //===----------------------------------------------------------------------===// BUILTIN(__builtin_amdgcn_s_getreg, "UiIi", "n") +BUILTIN(__builtin_amdgcn_s_setreg, "vIiUi", "n") BUILTIN(__builtin_amdgcn_s_getpc, "LUi", "n") BUILTIN(__builtin_amdgcn_s_waitcnt, "vIi", "n") BUILTIN(__builtin_amdgcn_s_sendmsg, "vIiUi", "n") @@ -53,6 +58,13 @@ BUILTIN(__builtin_amdgcn_ds_gws_barrier, "vUiUi", "n") BUILTIN(__builtin_amdgcn_ds_gws_sema_v, "vUi", "n") BUILTIN(__builtin_amdgcn_ds_gws_sema_br, "vUiUi", "n") BUILTIN(__builtin_amdgcn_ds_gws_sema_p, "vUi", "n") +BUILTIN(__builtin_amdgcn_fence, "vUicC*", "n") + +BUILTIN(__builtin_amdgcn_atomic_inc32, "UZiUZiD*UZiUicC*", "n") +BUILTIN(__builtin_amdgcn_atomic_inc64, "UWiUWiD*UWiUicC*", "n") + +BUILTIN(__builtin_amdgcn_atomic_dec32, "UZiUZiD*UZiUicC*", "n") +BUILTIN(__builtin_amdgcn_atomic_dec64, "UWiUWiD*UWiUicC*", "n") // FIXME: Need to disallow constant address space. BUILTIN(__builtin_amdgcn_div_scale, "dddbb*", "n") @@ -65,6 +77,8 @@ BUILTIN(__builtin_amdgcn_trig_preop, "ddi", "nc") BUILTIN(__builtin_amdgcn_trig_preopf, "ffi", "nc") BUILTIN(__builtin_amdgcn_rcp, "dd", "nc") BUILTIN(__builtin_amdgcn_rcpf, "ff", "nc") +BUILTIN(__builtin_amdgcn_sqrt, "dd", "nc") +BUILTIN(__builtin_amdgcn_sqrtf, "ff", "nc") BUILTIN(__builtin_amdgcn_rsq, "dd", "nc") BUILTIN(__builtin_amdgcn_rsqf, "ff", "nc") BUILTIN(__builtin_amdgcn_rsq_clamp, "dd", "nc") @@ -150,6 +164,7 @@ BUILTIN(__builtin_amdgcn_interp_mov, "fUiUiUiUi", "nc") TARGET_BUILTIN(__builtin_amdgcn_div_fixuph, "hhhh", "nc", "16-bit-insts") TARGET_BUILTIN(__builtin_amdgcn_rcph, "hh", "nc", "16-bit-insts") +TARGET_BUILTIN(__builtin_amdgcn_sqrth, "hh", "nc", "16-bit-insts") TARGET_BUILTIN(__builtin_amdgcn_rsqh, "hh", "nc", "16-bit-insts") TARGET_BUILTIN(__builtin_amdgcn_sinh, "hh", "nc", "16-bit-insts") TARGET_BUILTIN(__builtin_amdgcn_cosh, "hh", "nc", "16-bit-insts") @@ -212,5 +227,30 @@ BUILTIN(__builtin_r600_read_tidig_z, "Ui", "nc") BUILTIN(__builtin_r600_recipsqrt_ieee, "dd", "nc") BUILTIN(__builtin_r600_recipsqrt_ieeef, "ff", "nc") +//===----------------------------------------------------------------------===// +// MFMA builtins. +//===----------------------------------------------------------------------===// + +TARGET_BUILTIN(__builtin_amdgcn_mfma_f32_32x32x1f32, "V32fffV32fIiIiIi", "nc", "mai-insts") +TARGET_BUILTIN(__builtin_amdgcn_mfma_f32_16x16x1f32, "V16fffV16fIiIiIi", "nc", "mai-insts") +TARGET_BUILTIN(__builtin_amdgcn_mfma_f32_4x4x1f32, "V4fffV4fIiIiIi", "nc", "mai-insts") +TARGET_BUILTIN(__builtin_amdgcn_mfma_f32_32x32x2f32, "V16fffV16fIiIiIi", "nc", "mai-insts") +TARGET_BUILTIN(__builtin_amdgcn_mfma_f32_16x16x4f32, "V4fffV4fIiIiIi", "nc", "mai-insts") +TARGET_BUILTIN(__builtin_amdgcn_mfma_f32_32x32x4f16, "V32fV4hV4hV32fIiIiIi", "nc", "mai-insts") +TARGET_BUILTIN(__builtin_amdgcn_mfma_f32_16x16x4f16, "V16fV4hV4hV16fIiIiIi", "nc", "mai-insts") +TARGET_BUILTIN(__builtin_amdgcn_mfma_f32_4x4x4f16, "V4fV4hV4hV4fIiIiIi", "nc", "mai-insts") +TARGET_BUILTIN(__builtin_amdgcn_mfma_f32_32x32x8f16, "V16fV4hV4hV16fIiIiIi", "nc", "mai-insts") +TARGET_BUILTIN(__builtin_amdgcn_mfma_f32_16x16x16f16, "V4fV4hV4hV4fIiIiIi", "nc", "mai-insts") +TARGET_BUILTIN(__builtin_amdgcn_mfma_i32_32x32x4i8, "V32iiiV32iIiIiIi", "nc", "mai-insts") +TARGET_BUILTIN(__builtin_amdgcn_mfma_i32_16x16x4i8, "V16iiiV16iIiIiIi", "nc", "mai-insts") +TARGET_BUILTIN(__builtin_amdgcn_mfma_i32_4x4x4i8, "V4iiiV4iIiIiIi", "nc", "mai-insts") +TARGET_BUILTIN(__builtin_amdgcn_mfma_i32_32x32x8i8, "V16iiiV16iIiIiIi", "nc", "mai-insts") +TARGET_BUILTIN(__builtin_amdgcn_mfma_i32_16x16x16i8, "V4iiiV4iIiIiIi", "nc", "mai-insts") +TARGET_BUILTIN(__builtin_amdgcn_mfma_f32_32x32x2bf16, "V32fV2sV2sV32fIiIiIi", "nc", "mai-insts") +TARGET_BUILTIN(__builtin_amdgcn_mfma_f32_16x16x2bf16, "V16fV2sV2sV16fIiIiIi", "nc", "mai-insts") +TARGET_BUILTIN(__builtin_amdgcn_mfma_f32_4x4x2bf16, "V4fV2sV2sV4fIiIiIi", "nc", "mai-insts") +TARGET_BUILTIN(__builtin_amdgcn_mfma_f32_32x32x4bf16, "V16fV2sV2sV16fIiIiIi", "nc", "mai-insts") +TARGET_BUILTIN(__builtin_amdgcn_mfma_f32_16x16x8bf16, "V4fV2sV2sV4fIiIiIi", "nc", "mai-insts") + #undef BUILTIN #undef TARGET_BUILTIN diff --git a/clang/include/clang/Basic/BuiltinsARM.def b/clang/include/clang/Basic/BuiltinsARM.def index 848abb44ad36..be20c24aa28a 100644 --- a/clang/include/clang/Basic/BuiltinsARM.def +++ b/clang/include/clang/Basic/BuiltinsARM.def @@ -202,6 +202,8 @@ BUILTIN(__builtin_arm_wsrp, "vcC*vC*", "nc") // aren't included from both here and BuiltinsAArch64.def.) #include "clang/Basic/arm_mve_builtins.inc" +#include "clang/Basic/arm_cde_builtins.inc" + // MSVC LANGBUILTIN(__emit, "vIUiC", "", ALL_MS_LANGUAGES) diff --git a/clang/include/clang/Basic/BuiltinsBPF.def b/clang/include/clang/Basic/BuiltinsBPF.def index bd96b9ef531b..237e9dc8784b 100644 --- a/clang/include/clang/Basic/BuiltinsBPF.def +++ b/clang/include/clang/Basic/BuiltinsBPF.def @@ -20,5 +20,8 @@ // Get record field information. TARGET_BUILTIN(__builtin_preserve_field_info, "Ui.", "t", "") +// Get BTF type id. +TARGET_BUILTIN(__builtin_btf_type_id, "Ui.", "t", "") + #undef BUILTIN #undef TARGET_BUILTIN diff --git a/clang/include/clang/Basic/BuiltinsHexagon.def b/clang/include/clang/Basic/BuiltinsHexagon.def index 18029af56ff7..28aa222166f5 100644 --- a/clang/include/clang/Basic/BuiltinsHexagon.def +++ b/clang/include/clang/Basic/BuiltinsHexagon.def @@ -13,1805 +13,125 @@ // The format of this database matches clang/Basic/Builtins.def. -// The builtins below are not autogenerated from iset.py. -// Make sure you do not overwrite these. - -BUILTIN(__builtin_brev_ldd, "v*LLi*CLLi*iC", "") -BUILTIN(__builtin_brev_ldw, "v*i*Ci*iC", "") -BUILTIN(__builtin_brev_ldh, "v*s*Cs*iC", "") -BUILTIN(__builtin_brev_lduh, "v*Us*CUs*iC", "") -BUILTIN(__builtin_brev_ldb, "v*Sc*CSc*iC", "") -BUILTIN(__builtin_brev_ldub, "v*Uc*CUc*iC", "") -BUILTIN(__builtin_circ_ldd, "LLi*LLi*LLi*iIi", "") -BUILTIN(__builtin_circ_ldw, "i*i*i*iIi", "") -BUILTIN(__builtin_circ_ldh, "s*s*s*iIi", "") -BUILTIN(__builtin_circ_lduh, "Us*Us*Us*iIi", "") -BUILTIN(__builtin_circ_ldb, "c*c*c*iIi", "") -BUILTIN(__builtin_circ_ldub, "Uc*Uc*Uc*iIi", "") -BUILTIN(__builtin_brev_std, "LLi*CLLi*LLiiC", "") -BUILTIN(__builtin_brev_stw, "i*Ci*iiC", "") -BUILTIN(__builtin_brev_sth, "s*Cs*iiC", "") -BUILTIN(__builtin_brev_sthhi, "s*Cs*iiC", "") -BUILTIN(__builtin_brev_stb, "c*Cc*iiC", "") -BUILTIN(__builtin_circ_std, "LLi*LLi*LLiiIi", "") -BUILTIN(__builtin_circ_stw, "i*i*iiIi", "") -BUILTIN(__builtin_circ_sth, "s*s*iiIi", "") -BUILTIN(__builtin_circ_sthhi, "s*s*iiIi", "") -BUILTIN(__builtin_circ_stb, "c*c*iiIi", "") -BUILTIN(__builtin_HEXAGON_L2_loadrub_pci, "iv*IiivC*", "") -BUILTIN(__builtin_HEXAGON_L2_loadrb_pci, "iv*IiivC*", "") -BUILTIN(__builtin_HEXAGON_L2_loadruh_pci, "iv*IiivC*", "") -BUILTIN(__builtin_HEXAGON_L2_loadrh_pci, "iv*IiivC*", "") -BUILTIN(__builtin_HEXAGON_L2_loadri_pci, "iv*IiivC*", "") -BUILTIN(__builtin_HEXAGON_L2_loadrd_pci, "LLiv*IiivC*", "") -BUILTIN(__builtin_HEXAGON_L2_loadrub_pcr, "iv*ivC*", "") -BUILTIN(__builtin_HEXAGON_L2_loadrb_pcr, "iv*ivC*", "") -BUILTIN(__builtin_HEXAGON_L2_loadruh_pcr, "iv*ivC*", "") -BUILTIN(__builtin_HEXAGON_L2_loadrh_pcr, "iv*ivC*", "") -BUILTIN(__builtin_HEXAGON_L2_loadri_pcr, "iv*ivC*", "") -BUILTIN(__builtin_HEXAGON_L2_loadrd_pcr, "LLiv*ivC*", "") - -BUILTIN(__builtin_HEXAGON_S2_storerb_pci, "vv*IiiivC*", "") -BUILTIN(__builtin_HEXAGON_S2_storerh_pci, "vv*IiiivC*", "") -BUILTIN(__builtin_HEXAGON_S2_storerf_pci, "vv*IiiivC*", "") -BUILTIN(__builtin_HEXAGON_S2_storeri_pci, "vv*IiiivC*", "") -BUILTIN(__builtin_HEXAGON_S2_storerd_pci, "vv*IiiLLivC*", "") -BUILTIN(__builtin_HEXAGON_S2_storerb_pcr, "vv*iivC*", "") -BUILTIN(__builtin_HEXAGON_S2_storerh_pcr, "vv*iivC*", "") -BUILTIN(__builtin_HEXAGON_S2_storerf_pcr, "vv*iivC*", "") -BUILTIN(__builtin_HEXAGON_S2_storeri_pcr, "vv*iivC*", "") -BUILTIN(__builtin_HEXAGON_S2_storerd_pcr, "vv*iLLivC*", "") - -BUILTIN(__builtin_HEXAGON_prefetch,"vv*","") -BUILTIN(__builtin_HEXAGON_Y2_dccleana,"vv*","") -BUILTIN(__builtin_HEXAGON_Y2_dccleaninva,"vv*","") -BUILTIN(__builtin_HEXAGON_Y2_dcinva,"vv*","") -BUILTIN(__builtin_HEXAGON_Y2_dczeroa,"vv*","") -BUILTIN(__builtin_HEXAGON_Y4_l2fetch,"vv*Ui","") -BUILTIN(__builtin_HEXAGON_Y5_l2fetch,"vv*LLUi","") - -BUILTIN(__builtin_HEXAGON_V6_vS32b_qpred_ai,"vV16iv*V16i","") -BUILTIN(__builtin_HEXAGON_V6_vS32b_nqpred_ai,"vV16iv*V16i","") -BUILTIN(__builtin_HEXAGON_V6_vS32b_nt_qpred_ai,"vV16iv*V16i","") -BUILTIN(__builtin_HEXAGON_V6_vS32b_nt_nqpred_ai,"vV16iv*V16i","") -BUILTIN(__builtin_HEXAGON_V6_vS32b_qpred_ai_128B,"vV32iv*V32i","") -BUILTIN(__builtin_HEXAGON_V6_vS32b_nqpred_ai_128B,"vV32iv*V32i","") -BUILTIN(__builtin_HEXAGON_V6_vS32b_nt_qpred_ai_128B,"vV32iv*V32i","") -BUILTIN(__builtin_HEXAGON_V6_vS32b_nt_nqpred_ai_128B,"vV32iv*V32i","") -BUILTIN(__builtin_HEXAGON_V6_vmaskedstoreq,"vV16iv*V16i","") -BUILTIN(__builtin_HEXAGON_V6_vmaskedstorenq,"vV16iv*V16i","") -BUILTIN(__builtin_HEXAGON_V6_vmaskedstorentq,"vV16iv*V16i","") -BUILTIN(__builtin_HEXAGON_V6_vmaskedstorentnq,"vV16iv*V16i","") -BUILTIN(__builtin_HEXAGON_V6_vmaskedstoreq_128B,"vV32iv*V32i","") -BUILTIN(__builtin_HEXAGON_V6_vmaskedstorenq_128B,"vV32iv*V32i","") -BUILTIN(__builtin_HEXAGON_V6_vmaskedstorentq_128B,"vV32iv*V32i","") -BUILTIN(__builtin_HEXAGON_V6_vmaskedstorentnq_128B,"vV32iv*V32i","") - -BUILTIN(__builtin_HEXAGON_V6_vgathermw,"vv*iiV16i","") -BUILTIN(__builtin_HEXAGON_V6_vgathermw_128B,"vv*iiV32i","") -BUILTIN(__builtin_HEXAGON_V6_vgathermh,"vv*iiV16i","") -BUILTIN(__builtin_HEXAGON_V6_vgathermh_128B,"vv*iiV32i","") -BUILTIN(__builtin_HEXAGON_V6_vgathermhw,"vv*iiV32i","") -BUILTIN(__builtin_HEXAGON_V6_vgathermhw_128B,"vv*iiV64i","") -BUILTIN(__builtin_HEXAGON_V6_vgathermwq,"vv*V16iiiV16i","") -BUILTIN(__builtin_HEXAGON_V6_vgathermwq_128B,"vv*V32iiiV32i","") -BUILTIN(__builtin_HEXAGON_V6_vgathermhq,"vv*V16iiiV16i","") -BUILTIN(__builtin_HEXAGON_V6_vgathermhq_128B,"vv*V32iiiV32i","") -BUILTIN(__builtin_HEXAGON_V6_vgathermhwq,"vv*V16iiiV32i","") -BUILTIN(__builtin_HEXAGON_V6_vgathermhwq_128B,"vv*V32iiiV64i","") -BUILTIN(__builtin_HEXAGON_V6_vscattermw,"viiV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vscattermw_128B,"viiV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vscattermh,"viiV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vscattermh_128B,"viiV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vscattermw_add,"viiV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vscattermw_add_128B,"viiV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vscattermh_add,"viiV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vscattermh_add_128B,"viiV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vscattermwq,"vV16iiiV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vscattermwq_128B,"vV32iiiV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vscattermhq,"vV16iiiV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vscattermhq_128B,"vV32iiiV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vscattermhw,"viiV32iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vscattermhw_128B,"viiV64iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vscattermhwq,"vV16iiiV32iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vscattermhwq_128B,"vV32iiiV64iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vscattermhw_add,"viiV32iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vscattermhw_add_128B,"viiV64iV32i","") - -// --------------------------------------------------------------------- -// Auto-generated definitions. - -// V5 Scalar Instructions. - -BUILTIN(__builtin_HEXAGON_S2_asr_r_p_or,"LLiLLiLLii","") -BUILTIN(__builtin_HEXAGON_S2_vsatwh,"iLLi","") -BUILTIN(__builtin_HEXAGON_S2_tableidxd_goodsyntax,"iiiUIiUIi","") -BUILTIN(__builtin_HEXAGON_M2_mpysu_up,"iii","") -BUILTIN(__builtin_HEXAGON_M2_mpyud_acc_ll_s0,"LLiLLiii","") -BUILTIN(__builtin_HEXAGON_M2_mpyud_acc_ll_s1,"LLiLLiii","") -BUILTIN(__builtin_HEXAGON_M2_cmpysc_s1,"LLiii","") -BUILTIN(__builtin_HEXAGON_M2_cmpysc_s0,"LLiii","") -BUILTIN(__builtin_HEXAGON_M4_cmpyi_whc,"iLLii","") -BUILTIN(__builtin_HEXAGON_M2_mpy_sat_rnd_lh_s1,"iii","") -BUILTIN(__builtin_HEXAGON_M2_mpy_sat_rnd_lh_s0,"iii","") -BUILTIN(__builtin_HEXAGON_S2_tableidxb_goodsyntax,"iiiUIiUIi","") -BUILTIN(__builtin_HEXAGON_S2_shuffoh,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_F2_sfmax,"fff","") -BUILTIN(__builtin_HEXAGON_A2_vabswsat,"LLiLLi","") -BUILTIN(__builtin_HEXAGON_S2_asr_i_r,"iiUIi","") -BUILTIN(__builtin_HEXAGON_S2_asr_i_p,"LLiLLiUIi","") -BUILTIN(__builtin_HEXAGON_A4_combineri,"LLiiIi","") -BUILTIN(__builtin_HEXAGON_M2_mpy_nac_sat_hl_s1,"iiii","") -BUILTIN(__builtin_HEXAGON_M4_vpmpyh_acc,"LLiLLiii","") -BUILTIN(__builtin_HEXAGON_M2_vcmpy_s0_sat_i,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_A2_notp,"LLiLLi","") -BUILTIN(__builtin_HEXAGON_M2_mpy_hl_s1,"iii","") -BUILTIN(__builtin_HEXAGON_M2_mpy_hl_s0,"iii","") -BUILTIN(__builtin_HEXAGON_C4_or_and,"iiii","") -BUILTIN(__builtin_HEXAGON_M2_vmac2s_s0,"LLiLLiii","") -BUILTIN(__builtin_HEXAGON_M2_vmac2s_s1,"LLiLLiii","") -BUILTIN(__builtin_HEXAGON_S2_brevp,"LLiLLi","") -BUILTIN(__builtin_HEXAGON_M4_pmpyw_acc,"LLiLLiii","") -BUILTIN(__builtin_HEXAGON_S2_cl1,"ii","") -BUILTIN(__builtin_HEXAGON_C4_cmplte,"iii","") -BUILTIN(__builtin_HEXAGON_M2_mmpyul_s0,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_A2_vaddws,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_A2_maxup,"ULLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_A4_vcmphgti,"iLLiIi","") -BUILTIN(__builtin_HEXAGON_S2_interleave,"LLiLLi","") -BUILTIN(__builtin_HEXAGON_M2_vrcmpyi_s0,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_A2_abssat,"ii","") -BUILTIN(__builtin_HEXAGON_A2_vcmpwgtu,"iLLiLLi","") -BUILTIN(__builtin_HEXAGON_C2_cmpgtu,"iii","") -BUILTIN(__builtin_HEXAGON_C2_cmpgtp,"iLLiLLi","") -BUILTIN(__builtin_HEXAGON_A4_cmphgtui,"iiUIi","") -BUILTIN(__builtin_HEXAGON_C2_cmpgti,"iiIi","") -BUILTIN(__builtin_HEXAGON_M2_mpyi,"iii","") -BUILTIN(__builtin_HEXAGON_F2_conv_df2uw_chop,"id","") -BUILTIN(__builtin_HEXAGON_A4_cmpheq,"iii","") -BUILTIN(__builtin_HEXAGON_M2_mpy_lh_s1,"iii","") -BUILTIN(__builtin_HEXAGON_M2_mpy_lh_s0,"iii","") -BUILTIN(__builtin_HEXAGON_S2_lsr_i_r_xacc,"iiiUIi","") -BUILTIN(__builtin_HEXAGON_S2_vrcnegh,"LLiLLiLLii","") -BUILTIN(__builtin_HEXAGON_S2_extractup,"LLiLLiUIiUIi","") -BUILTIN(__builtin_HEXAGON_S2_asr_i_p_rnd_goodsyntax,"LLiLLiUIi","") -BUILTIN(__builtin_HEXAGON_S4_ntstbit_r,"iii","") -BUILTIN(__builtin_HEXAGON_F2_conv_w2sf,"fi","") -BUILTIN(__builtin_HEXAGON_C2_not,"ii","") -BUILTIN(__builtin_HEXAGON_C2_tfrpr,"ii","") -BUILTIN(__builtin_HEXAGON_M2_mpy_ll_s1,"iii","") -BUILTIN(__builtin_HEXAGON_M2_mpy_ll_s0,"iii","") -BUILTIN(__builtin_HEXAGON_A4_cmpbgt,"iii","") -BUILTIN(__builtin_HEXAGON_S2_asr_r_r_and,"iiii","") -BUILTIN(__builtin_HEXAGON_A4_rcmpneqi,"iiIi","") -BUILTIN(__builtin_HEXAGON_S2_asl_i_r_nac,"iiiUIi","") -BUILTIN(__builtin_HEXAGON_M2_subacc,"iiii","") -BUILTIN(__builtin_HEXAGON_A2_orp,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_M2_mpyu_up,"Uiii","") -BUILTIN(__builtin_HEXAGON_M2_mpy_acc_sat_lh_s1,"iiii","") -BUILTIN(__builtin_HEXAGON_S2_asr_i_vh,"LLiLLiUIi","") -BUILTIN(__builtin_HEXAGON_S2_asr_i_vw,"LLiLLiUIi","") -BUILTIN(__builtin_HEXAGON_A4_cmpbgtu,"iii","") -BUILTIN(__builtin_HEXAGON_A4_vcmpbeq_any,"iLLiLLi","") -BUILTIN(__builtin_HEXAGON_A4_cmpbgti,"iiIi","") -BUILTIN(__builtin_HEXAGON_M2_mpyd_lh_s1,"LLiii","") -BUILTIN(__builtin_HEXAGON_S2_asl_r_p_nac,"LLiLLiLLii","") -BUILTIN(__builtin_HEXAGON_S2_lsr_i_r_nac,"iiiUIi","") -BUILTIN(__builtin_HEXAGON_A2_addsp,"LLiiLLi","") -BUILTIN(__builtin_HEXAGON_S4_vxsubaddw,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_A4_vcmpheqi,"iLLiIi","") -BUILTIN(__builtin_HEXAGON_S4_vxsubaddh,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_M4_pmpyw,"LLiii","") -BUILTIN(__builtin_HEXAGON_S2_vsathb,"iLLi","") -BUILTIN(__builtin_HEXAGON_S2_asr_r_p_and,"LLiLLiLLii","") -BUILTIN(__builtin_HEXAGON_M2_mpyu_acc_lh_s1,"iiii","") -BUILTIN(__builtin_HEXAGON_M2_mpyu_acc_lh_s0,"iiii","") -BUILTIN(__builtin_HEXAGON_S2_lsl_r_p_acc,"LLiLLiLLii","") -BUILTIN(__builtin_HEXAGON_A2_pxorf,"iiii","") -BUILTIN(__builtin_HEXAGON_C2_cmpgei,"iiIi","") -BUILTIN(__builtin_HEXAGON_A2_vsubub,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_S2_asl_i_p,"LLiLLiUIi","") -BUILTIN(__builtin_HEXAGON_S2_asl_i_r,"iiUIi","") -BUILTIN(__builtin_HEXAGON_A4_vrminuw,"LLiLLiLLii","") -BUILTIN(__builtin_HEXAGON_F2_sffma,"ffff","") -BUILTIN(__builtin_HEXAGON_A2_absp,"LLiLLi","") -BUILTIN(__builtin_HEXAGON_C2_all8,"ii","") -BUILTIN(__builtin_HEXAGON_A4_vrminuh,"LLiLLiLLii","") -BUILTIN(__builtin_HEXAGON_F2_sffma_lib,"ffff","") -BUILTIN(__builtin_HEXAGON_M4_vrmpyoh_s0,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_M4_vrmpyoh_s1,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_C2_bitsset,"iii","") -BUILTIN(__builtin_HEXAGON_M2_mpysip,"iiUIi","") -BUILTIN(__builtin_HEXAGON_M2_mpysin,"iiUIi","") -BUILTIN(__builtin_HEXAGON_A4_boundscheck,"iiLLi","") -BUILTIN(__builtin_HEXAGON_M5_vrmpybuu,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_C4_fastcorner9,"iii","") -BUILTIN(__builtin_HEXAGON_M2_vrcmpys_s1rp,"iLLii","") -BUILTIN(__builtin_HEXAGON_A2_neg,"ii","") -BUILTIN(__builtin_HEXAGON_A2_subsat,"iii","") -BUILTIN(__builtin_HEXAGON_S2_asl_r_r,"iii","") -BUILTIN(__builtin_HEXAGON_S2_asl_r_p,"LLiLLii","") -BUILTIN(__builtin_HEXAGON_A2_vnavgh,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_M2_mpy_nac_sat_hl_s0,"iiii","") -BUILTIN(__builtin_HEXAGON_F2_conv_ud2df,"dLLi","") -BUILTIN(__builtin_HEXAGON_A2_vnavgw,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_S2_asl_i_r_acc,"iiiUIi","") -BUILTIN(__builtin_HEXAGON_S4_subi_lsr_ri,"iUIiiUIi","") -BUILTIN(__builtin_HEXAGON_S2_vzxthw,"LLii","") -BUILTIN(__builtin_HEXAGON_F2_sfadd,"fff","") -BUILTIN(__builtin_HEXAGON_A2_sub,"iii","") -BUILTIN(__builtin_HEXAGON_M2_vmac2su_s0,"LLiLLiii","") -BUILTIN(__builtin_HEXAGON_M2_vmac2su_s1,"LLiLLiii","") -BUILTIN(__builtin_HEXAGON_M2_dpmpyss_s0,"LLiii","") -BUILTIN(__builtin_HEXAGON_S2_insert,"iiiUIiUIi","") -BUILTIN(__builtin_HEXAGON_S2_packhl,"LLiii","") -BUILTIN(__builtin_HEXAGON_A4_vcmpwgti,"iLLiIi","") -BUILTIN(__builtin_HEXAGON_A2_vavguwr,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_S2_asl_r_r_and,"iiii","") -BUILTIN(__builtin_HEXAGON_A2_svsubhs,"iii","") -BUILTIN(__builtin_HEXAGON_A2_addh_l16_hl,"iii","") -BUILTIN(__builtin_HEXAGON_M4_and_and,"iiii","") -BUILTIN(__builtin_HEXAGON_F2_conv_d2df,"dLLi","") -BUILTIN(__builtin_HEXAGON_C2_cmpgtui,"iiUIi","") -BUILTIN(__builtin_HEXAGON_A2_vconj,"LLiLLi","") -BUILTIN(__builtin_HEXAGON_S2_lsr_r_vw,"LLiLLii","") -BUILTIN(__builtin_HEXAGON_S2_lsr_r_vh,"LLiLLii","") -BUILTIN(__builtin_HEXAGON_A2_subh_l16_hl,"iii","") -BUILTIN(__builtin_HEXAGON_S4_vxsubaddhr,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_S2_clbp,"iLLi","") -BUILTIN(__builtin_HEXAGON_S2_deinterleave,"LLiLLi","") -BUILTIN(__builtin_HEXAGON_C2_any8,"ii","") -BUILTIN(__builtin_HEXAGON_S2_togglebit_r,"iii","") -BUILTIN(__builtin_HEXAGON_S2_togglebit_i,"iiUIi","") -BUILTIN(__builtin_HEXAGON_F2_conv_uw2sf,"fi","") -BUILTIN(__builtin_HEXAGON_S2_vsathb_nopack,"LLiLLi","") -BUILTIN(__builtin_HEXAGON_M2_cmacs_s0,"LLiLLiii","") -BUILTIN(__builtin_HEXAGON_M2_cmacs_s1,"LLiLLiii","") -BUILTIN(__builtin_HEXAGON_M2_mpy_sat_hh_s0,"iii","") -BUILTIN(__builtin_HEXAGON_M2_mpy_sat_hh_s1,"iii","") -BUILTIN(__builtin_HEXAGON_M2_mmacuhs_s1,"LLiLLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_M2_mmacuhs_s0,"LLiLLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_S2_clrbit_r,"iii","") -BUILTIN(__builtin_HEXAGON_C4_or_andn,"iiii","") -BUILTIN(__builtin_HEXAGON_S2_asl_r_r_nac,"iiii","") -BUILTIN(__builtin_HEXAGON_S2_asl_i_p_acc,"LLiLLiLLiUIi","") -BUILTIN(__builtin_HEXAGON_A4_vcmpwgtui,"iLLiUIi","") -BUILTIN(__builtin_HEXAGON_M4_vrmpyoh_acc_s0,"LLiLLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_M4_vrmpyoh_acc_s1,"LLiLLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_A4_vrmaxh,"LLiLLiLLii","") -BUILTIN(__builtin_HEXAGON_A2_vcmpbeq,"iLLiLLi","") -BUILTIN(__builtin_HEXAGON_A2_vcmphgt,"iLLiLLi","") -BUILTIN(__builtin_HEXAGON_A2_vnavgwcr,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_M2_vrcmacr_s0c,"LLiLLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_A2_vavgwcr,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_S2_asl_i_p_xacc,"LLiLLiLLiUIi","") -BUILTIN(__builtin_HEXAGON_A4_vrmaxw,"LLiLLiLLii","") -BUILTIN(__builtin_HEXAGON_A2_vnavghr,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_M4_cmpyi_wh,"iLLii","") -BUILTIN(__builtin_HEXAGON_A2_tfrsi,"iIi","") -BUILTIN(__builtin_HEXAGON_S2_asr_i_r_acc,"iiiUIi","") -BUILTIN(__builtin_HEXAGON_A2_svnavgh,"iii","") -BUILTIN(__builtin_HEXAGON_S2_lsr_i_r,"iiUIi","") -BUILTIN(__builtin_HEXAGON_M2_vmac2,"LLiLLiii","") -BUILTIN(__builtin_HEXAGON_A4_vcmphgtui,"iLLiUIi","") -BUILTIN(__builtin_HEXAGON_A2_svavgh,"iii","") -BUILTIN(__builtin_HEXAGON_M4_vrmpyeh_acc_s0,"LLiLLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_M4_vrmpyeh_acc_s1,"LLiLLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_S2_lsr_i_p,"LLiLLiUIi","") -BUILTIN(__builtin_HEXAGON_A2_combine_hl,"iii","") -BUILTIN(__builtin_HEXAGON_M2_mpy_up,"iii","") -BUILTIN(__builtin_HEXAGON_A2_combine_hh,"iii","") -BUILTIN(__builtin_HEXAGON_A2_negsat,"ii","") -BUILTIN(__builtin_HEXAGON_M2_mpyd_hl_s0,"LLiii","") -BUILTIN(__builtin_HEXAGON_M2_mpyd_hl_s1,"LLiii","") -BUILTIN(__builtin_HEXAGON_A4_bitsplit,"LLiii","") -BUILTIN(__builtin_HEXAGON_A2_vabshsat,"LLiLLi","") -BUILTIN(__builtin_HEXAGON_M2_mpyui,"iii","") -BUILTIN(__builtin_HEXAGON_A2_addh_l16_sat_ll,"iii","") -BUILTIN(__builtin_HEXAGON_S2_lsl_r_r_and,"iiii","") -BUILTIN(__builtin_HEXAGON_M2_mmpyul_rs0,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_S2_asr_i_r_rnd_goodsyntax,"iiUIi","") -BUILTIN(__builtin_HEXAGON_S2_lsr_r_p_nac,"LLiLLiLLii","") -BUILTIN(__builtin_HEXAGON_C2_cmplt,"iii","") -BUILTIN(__builtin_HEXAGON_M2_cmacr_s0,"LLiLLiii","") -BUILTIN(__builtin_HEXAGON_M4_or_and,"iiii","") -BUILTIN(__builtin_HEXAGON_M4_mpyrr_addi,"iUIiii","") -BUILTIN(__builtin_HEXAGON_S4_or_andi,"iiiIi","") -BUILTIN(__builtin_HEXAGON_M2_mpy_sat_hl_s0,"iii","") -BUILTIN(__builtin_HEXAGON_M2_mpy_sat_hl_s1,"iii","") -BUILTIN(__builtin_HEXAGON_M4_mpyrr_addr,"iiii","") -BUILTIN(__builtin_HEXAGON_M2_mmachs_rs0,"LLiLLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_M2_mmachs_rs1,"LLiLLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_M2_vrcmpyr_s0c,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_M2_mpy_acc_sat_hl_s0,"iiii","") -BUILTIN(__builtin_HEXAGON_M2_mpyd_acc_ll_s1,"LLiLLiii","") -BUILTIN(__builtin_HEXAGON_F2_sffixupn,"fff","") -BUILTIN(__builtin_HEXAGON_M2_mpyd_acc_lh_s0,"LLiLLiii","") -BUILTIN(__builtin_HEXAGON_M2_mpyd_acc_lh_s1,"LLiLLiii","") -BUILTIN(__builtin_HEXAGON_M2_mpy_rnd_hh_s0,"iii","") -BUILTIN(__builtin_HEXAGON_M2_mpy_rnd_hh_s1,"iii","") -BUILTIN(__builtin_HEXAGON_A2_vadduhs,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_A2_vsubuhs,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_A2_subh_h16_hl,"iii","") -BUILTIN(__builtin_HEXAGON_A2_subh_h16_hh,"iii","") -BUILTIN(__builtin_HEXAGON_A2_xorp,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_A4_tfrpcp,"LLiLLi","") -BUILTIN(__builtin_HEXAGON_A2_addh_h16_lh,"iii","") -BUILTIN(__builtin_HEXAGON_A2_addh_h16_sat_hl,"iii","") -BUILTIN(__builtin_HEXAGON_A2_addh_h16_ll,"iii","") -BUILTIN(__builtin_HEXAGON_A2_addh_h16_sat_hh,"iii","") -BUILTIN(__builtin_HEXAGON_A2_zxtb,"ii","") -BUILTIN(__builtin_HEXAGON_A2_zxth,"ii","") -BUILTIN(__builtin_HEXAGON_A2_vnavgwr,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_M4_or_xor,"iiii","") -BUILTIN(__builtin_HEXAGON_M2_mpyud_acc_hh_s0,"LLiLLiii","") -BUILTIN(__builtin_HEXAGON_M2_mpyud_acc_hh_s1,"LLiLLiii","") -BUILTIN(__builtin_HEXAGON_M5_vmacbsu,"LLiLLiii","") -BUILTIN(__builtin_HEXAGON_M2_dpmpyuu_acc_s0,"LLiLLiii","") -BUILTIN(__builtin_HEXAGON_M2_mpy_rnd_hl_s0,"iii","") -BUILTIN(__builtin_HEXAGON_M2_mpy_rnd_hl_s1,"iii","") -BUILTIN(__builtin_HEXAGON_F2_sffms_lib,"ffff","") -BUILTIN(__builtin_HEXAGON_C4_cmpneqi,"iiIi","") -BUILTIN(__builtin_HEXAGON_M4_and_xor,"iiii","") -BUILTIN(__builtin_HEXAGON_A2_sat,"iLLi","") -BUILTIN(__builtin_HEXAGON_M2_mpyd_nac_lh_s1,"LLiLLiii","") -BUILTIN(__builtin_HEXAGON_M2_mpyd_nac_lh_s0,"LLiLLiii","") -BUILTIN(__builtin_HEXAGON_A2_addsat,"iii","") -BUILTIN(__builtin_HEXAGON_A2_svavghs,"iii","") -BUILTIN(__builtin_HEXAGON_A2_vrsadub_acc,"LLiLLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_C2_bitsclri,"iiUIi","") -BUILTIN(__builtin_HEXAGON_A2_subh_h16_sat_hh,"iii","") -BUILTIN(__builtin_HEXAGON_A2_subh_h16_sat_hl,"iii","") -BUILTIN(__builtin_HEXAGON_M2_mmaculs_rs0,"LLiLLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_M2_mmaculs_rs1,"LLiLLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_M2_vradduh,"iLLiLLi","") -BUILTIN(__builtin_HEXAGON_A4_addp_c,"LLiLLiLLiv*","") -BUILTIN(__builtin_HEXAGON_C2_xor,"iii","") -BUILTIN(__builtin_HEXAGON_S2_lsl_r_r_acc,"iiii","") -BUILTIN(__builtin_HEXAGON_M2_mmpyh_rs1,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_M2_mmpyh_rs0,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_F2_conv_df2ud_chop,"LLid","") -BUILTIN(__builtin_HEXAGON_C4_or_or,"iiii","") -BUILTIN(__builtin_HEXAGON_S4_vxaddsubhr,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_S2_vsathub,"iLLi","") -BUILTIN(__builtin_HEXAGON_F2_conv_df2sf,"fd","") -BUILTIN(__builtin_HEXAGON_M2_hmmpyh_rs1,"iii","") -BUILTIN(__builtin_HEXAGON_M2_hmmpyh_s1,"iii","") -BUILTIN(__builtin_HEXAGON_A2_vavgwr,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_S2_tableidxh_goodsyntax,"iiiUIiUIi","") -BUILTIN(__builtin_HEXAGON_A2_sxth,"ii","") -BUILTIN(__builtin_HEXAGON_A2_sxtb,"ii","") -BUILTIN(__builtin_HEXAGON_C4_or_orn,"iiii","") -BUILTIN(__builtin_HEXAGON_M2_vrcmaci_s0c,"LLiLLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_A2_sxtw,"LLii","") -BUILTIN(__builtin_HEXAGON_M2_vabsdiffh,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_M2_mpy_acc_lh_s1,"iiii","") -BUILTIN(__builtin_HEXAGON_M2_mpy_acc_lh_s0,"iiii","") -BUILTIN(__builtin_HEXAGON_M2_hmmpyl_s1,"iii","") -BUILTIN(__builtin_HEXAGON_S2_cl1p,"iLLi","") -BUILTIN(__builtin_HEXAGON_M2_vabsdiffw,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_A4_andnp,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_C2_vmux,"LLiiLLiLLi","") -BUILTIN(__builtin_HEXAGON_S2_parityp,"iLLiLLi","") -BUILTIN(__builtin_HEXAGON_S2_lsr_i_p_and,"LLiLLiLLiUIi","") -BUILTIN(__builtin_HEXAGON_S2_asr_i_r_or,"iiiUIi","") -BUILTIN(__builtin_HEXAGON_M2_mpyu_nac_ll_s0,"iiii","") -BUILTIN(__builtin_HEXAGON_M2_mpyu_nac_ll_s1,"iiii","") -BUILTIN(__builtin_HEXAGON_F2_sfcmpeq,"iff","") -BUILTIN(__builtin_HEXAGON_A2_vaddb_map,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_S2_lsr_r_r_nac,"iiii","") -BUILTIN(__builtin_HEXAGON_A2_vcmpheq,"iLLiLLi","") -BUILTIN(__builtin_HEXAGON_S2_clbnorm,"ii","") -BUILTIN(__builtin_HEXAGON_M2_cnacsc_s1,"LLiLLiii","") -BUILTIN(__builtin_HEXAGON_M2_cnacsc_s0,"LLiLLiii","") -BUILTIN(__builtin_HEXAGON_S4_subaddi,"iiIii","") -BUILTIN(__builtin_HEXAGON_M2_mpyud_nac_hl_s1,"LLiLLiii","") -BUILTIN(__builtin_HEXAGON_M2_mpyud_nac_hl_s0,"LLiLLiii","") -BUILTIN(__builtin_HEXAGON_S5_vasrhrnd_goodsyntax,"LLiLLiUIi","") -BUILTIN(__builtin_HEXAGON_S2_tstbit_r,"iii","") -BUILTIN(__builtin_HEXAGON_S4_vrcrotate,"LLiLLiiUIi","") -BUILTIN(__builtin_HEXAGON_M2_mmachs_s1,"LLiLLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_M2_mmachs_s0,"LLiLLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_S2_tstbit_i,"iiUIi","") -BUILTIN(__builtin_HEXAGON_M2_mpy_up_s1,"iii","") -BUILTIN(__builtin_HEXAGON_S2_extractu_rp,"iiLLi","") -BUILTIN(__builtin_HEXAGON_M2_mmpyuh_rs0,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_S2_lsr_i_vw,"LLiLLiUIi","") -BUILTIN(__builtin_HEXAGON_M2_mpy_rnd_ll_s0,"iii","") -BUILTIN(__builtin_HEXAGON_M2_mpy_rnd_ll_s1,"iii","") -BUILTIN(__builtin_HEXAGON_M4_or_or,"iiii","") -BUILTIN(__builtin_HEXAGON_M2_mpyu_hh_s1,"Uiii","") -BUILTIN(__builtin_HEXAGON_M2_mpyu_hh_s0,"Uiii","") -BUILTIN(__builtin_HEXAGON_S2_asl_r_p_acc,"LLiLLiLLii","") -BUILTIN(__builtin_HEXAGON_M2_mpyu_nac_lh_s0,"iiii","") -BUILTIN(__builtin_HEXAGON_M2_mpyu_nac_lh_s1,"iiii","") -BUILTIN(__builtin_HEXAGON_M2_mpy_sat_ll_s0,"iii","") -BUILTIN(__builtin_HEXAGON_M2_mpy_sat_ll_s1,"iii","") -BUILTIN(__builtin_HEXAGON_F2_conv_w2df,"di","") -BUILTIN(__builtin_HEXAGON_A2_subh_l16_sat_hl,"iii","") -BUILTIN(__builtin_HEXAGON_C2_cmpeqi,"iiIi","") -BUILTIN(__builtin_HEXAGON_S2_asl_i_r_and,"iiiUIi","") -BUILTIN(__builtin_HEXAGON_S2_vcnegh,"LLiLLii","") -BUILTIN(__builtin_HEXAGON_A4_vcmpweqi,"iLLiIi","") -BUILTIN(__builtin_HEXAGON_M2_vdmpyrs_s0,"iLLiLLi","") -BUILTIN(__builtin_HEXAGON_M2_vdmpyrs_s1,"iLLiLLi","") -BUILTIN(__builtin_HEXAGON_M4_xor_xacc,"LLiLLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_M2_vdmpys_s1,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_M2_vdmpys_s0,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_A2_vavgubr,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_M2_mpyu_hl_s1,"Uiii","") -BUILTIN(__builtin_HEXAGON_M2_mpyu_hl_s0,"Uiii","") -BUILTIN(__builtin_HEXAGON_S2_asl_r_r_acc,"iiii","") -BUILTIN(__builtin_HEXAGON_S2_cl0p,"iLLi","") -BUILTIN(__builtin_HEXAGON_S2_valignib,"LLiLLiLLiUIi","") -BUILTIN(__builtin_HEXAGON_F2_sffixupd,"fff","") -BUILTIN(__builtin_HEXAGON_M2_mpy_sat_rnd_hl_s1,"iii","") -BUILTIN(__builtin_HEXAGON_M2_mpy_sat_rnd_hl_s0,"iii","") -BUILTIN(__builtin_HEXAGON_M2_cmacsc_s0,"LLiLLiii","") -BUILTIN(__builtin_HEXAGON_M2_cmacsc_s1,"LLiLLiii","") -BUILTIN(__builtin_HEXAGON_S2_ct1,"ii","") -BUILTIN(__builtin_HEXAGON_S2_ct0,"ii","") -BUILTIN(__builtin_HEXAGON_M2_dpmpyuu_nac_s0,"LLiLLiii","") -BUILTIN(__builtin_HEXAGON_M2_mmpyul_rs1,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_S4_ntstbit_i,"iiUIi","") -BUILTIN(__builtin_HEXAGON_F2_sffixupr,"ff","") -BUILTIN(__builtin_HEXAGON_S2_asr_r_p_xor,"LLiLLiLLii","") -BUILTIN(__builtin_HEXAGON_M2_mpyud_acc_hl_s0,"LLiLLiii","") -BUILTIN(__builtin_HEXAGON_M2_mpyud_acc_hl_s1,"LLiLLiii","") -BUILTIN(__builtin_HEXAGON_A2_vcmphgtu,"iLLiLLi","") -BUILTIN(__builtin_HEXAGON_C2_andn,"iii","") -BUILTIN(__builtin_HEXAGON_M2_vmpy2s_s0pack,"iii","") -BUILTIN(__builtin_HEXAGON_S4_addaddi,"iiiIi","") -BUILTIN(__builtin_HEXAGON_M2_mpyd_acc_ll_s0,"LLiLLiii","") -BUILTIN(__builtin_HEXAGON_M2_mpy_acc_sat_hl_s1,"iiii","") -BUILTIN(__builtin_HEXAGON_A4_rcmpeqi,"iiIi","") -BUILTIN(__builtin_HEXAGON_M4_xor_and,"iiii","") -BUILTIN(__builtin_HEXAGON_S2_asl_i_p_and,"LLiLLiLLiUIi","") -BUILTIN(__builtin_HEXAGON_M2_mmpyuh_rs1,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_S2_asr_r_r_or,"iiii","") -BUILTIN(__builtin_HEXAGON_A4_round_ri,"iiUIi","") -BUILTIN(__builtin_HEXAGON_A2_max,"iii","") -BUILTIN(__builtin_HEXAGON_A4_round_rr,"iii","") -BUILTIN(__builtin_HEXAGON_A4_combineii,"LLiIiUIi","") -BUILTIN(__builtin_HEXAGON_A4_combineir,"LLiIii","") -BUILTIN(__builtin_HEXAGON_C4_and_orn,"iiii","") -BUILTIN(__builtin_HEXAGON_M5_vmacbuu,"LLiLLiii","") -BUILTIN(__builtin_HEXAGON_A4_rcmpeq,"iii","") -BUILTIN(__builtin_HEXAGON_M4_cmpyr_whc,"iLLii","") -BUILTIN(__builtin_HEXAGON_S2_lsr_i_r_acc,"iiiUIi","") -BUILTIN(__builtin_HEXAGON_S2_vzxtbh,"LLii","") -BUILTIN(__builtin_HEXAGON_M2_mmacuhs_rs1,"LLiLLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_S2_asr_r_r_sat,"iii","") -BUILTIN(__builtin_HEXAGON_A2_combinew,"LLiii","") -BUILTIN(__builtin_HEXAGON_M2_mpy_acc_ll_s1,"iiii","") -BUILTIN(__builtin_HEXAGON_M2_mpy_acc_ll_s0,"iiii","") -BUILTIN(__builtin_HEXAGON_M2_cmpyi_s0,"LLiii","") -BUILTIN(__builtin_HEXAGON_S2_asl_r_p_or,"LLiLLiLLii","") -BUILTIN(__builtin_HEXAGON_S4_ori_asl_ri,"iUIiiUIi","") -BUILTIN(__builtin_HEXAGON_C4_nbitsset,"iii","") -BUILTIN(__builtin_HEXAGON_M2_mpyu_acc_hh_s1,"iiii","") -BUILTIN(__builtin_HEXAGON_M2_mpyu_acc_hh_s0,"iiii","") -BUILTIN(__builtin_HEXAGON_M2_mpyu_ll_s1,"Uiii","") -BUILTIN(__builtin_HEXAGON_M2_mpyu_ll_s0,"Uiii","") -BUILTIN(__builtin_HEXAGON_A2_addh_l16_ll,"iii","") -BUILTIN(__builtin_HEXAGON_S2_lsr_r_r_and,"iiii","") -BUILTIN(__builtin_HEXAGON_A4_modwrapu,"iii","") -BUILTIN(__builtin_HEXAGON_A4_rcmpneq,"iii","") -BUILTIN(__builtin_HEXAGON_M2_mpyd_acc_hh_s0,"LLiLLiii","") -BUILTIN(__builtin_HEXAGON_M2_mpyd_acc_hh_s1,"LLiLLiii","") -BUILTIN(__builtin_HEXAGON_F2_sfimm_p,"fUIi","") -BUILTIN(__builtin_HEXAGON_F2_sfimm_n,"fUIi","") -BUILTIN(__builtin_HEXAGON_M4_cmpyr_wh,"iLLii","") -BUILTIN(__builtin_HEXAGON_S2_lsl_r_p_and,"LLiLLiLLii","") -BUILTIN(__builtin_HEXAGON_A2_vavgub,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_F2_conv_d2sf,"fLLi","") -BUILTIN(__builtin_HEXAGON_A2_vavguh,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_A4_cmpbeqi,"iiUIi","") -BUILTIN(__builtin_HEXAGON_F2_sfcmpuo,"iff","") -BUILTIN(__builtin_HEXAGON_A2_vavguw,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_S2_asr_i_p_nac,"LLiLLiLLiUIi","") -BUILTIN(__builtin_HEXAGON_S2_vsatwh_nopack,"LLiLLi","") -BUILTIN(__builtin_HEXAGON_M2_mpyd_hh_s0,"LLiii","") -BUILTIN(__builtin_HEXAGON_M2_mpyd_hh_s1,"LLiii","") -BUILTIN(__builtin_HEXAGON_S2_lsl_r_p_or,"LLiLLiLLii","") -BUILTIN(__builtin_HEXAGON_A2_minu,"Uiii","") -BUILTIN(__builtin_HEXAGON_M2_mpy_sat_lh_s1,"iii","") -BUILTIN(__builtin_HEXAGON_M4_or_andn,"iiii","") -BUILTIN(__builtin_HEXAGON_A2_minp,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_S4_or_andix,"iiiIi","") -BUILTIN(__builtin_HEXAGON_M2_mpy_rnd_lh_s0,"iii","") -BUILTIN(__builtin_HEXAGON_M2_mpy_rnd_lh_s1,"iii","") -BUILTIN(__builtin_HEXAGON_M2_mmpyuh_s0,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_M2_mmpyuh_s1,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_M2_mpy_acc_sat_lh_s0,"iiii","") -BUILTIN(__builtin_HEXAGON_F2_sfcmpge,"iff","") -BUILTIN(__builtin_HEXAGON_F2_sfmin,"fff","") -BUILTIN(__builtin_HEXAGON_F2_sfcmpgt,"iff","") -BUILTIN(__builtin_HEXAGON_M4_vpmpyh,"LLiii","") -BUILTIN(__builtin_HEXAGON_M2_mmacuhs_rs0,"LLiLLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_M2_mpyd_rnd_lh_s1,"LLiii","") -BUILTIN(__builtin_HEXAGON_M2_mpyd_rnd_lh_s0,"LLiii","") -BUILTIN(__builtin_HEXAGON_A2_roundsat,"iLLi","") -BUILTIN(__builtin_HEXAGON_S2_ct1p,"iLLi","") -BUILTIN(__builtin_HEXAGON_S4_extract_rp,"iiLLi","") -BUILTIN(__builtin_HEXAGON_S2_lsl_r_r_or,"iiii","") -BUILTIN(__builtin_HEXAGON_C4_cmplteui,"iiUIi","") -BUILTIN(__builtin_HEXAGON_S4_addi_lsr_ri,"iUIiiUIi","") -BUILTIN(__builtin_HEXAGON_A4_tfrcpp,"LLiLLi","") -BUILTIN(__builtin_HEXAGON_S2_asr_i_svw_trun,"iLLiUIi","") -BUILTIN(__builtin_HEXAGON_A4_cmphgti,"iiIi","") -BUILTIN(__builtin_HEXAGON_A4_vrminh,"LLiLLiLLii","") -BUILTIN(__builtin_HEXAGON_A4_vrminw,"LLiLLiLLii","") -BUILTIN(__builtin_HEXAGON_A4_cmphgtu,"iii","") -BUILTIN(__builtin_HEXAGON_S2_insertp_rp,"LLiLLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_A2_vnavghcr,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_S4_subi_asl_ri,"iUIiiUIi","") -BUILTIN(__builtin_HEXAGON_S2_lsl_r_vh,"LLiLLii","") -BUILTIN(__builtin_HEXAGON_M2_mpy_hh_s0,"iii","") -BUILTIN(__builtin_HEXAGON_A2_vsubws,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_A2_sath,"ii","") -BUILTIN(__builtin_HEXAGON_S2_asl_r_p_xor,"LLiLLiLLii","") -BUILTIN(__builtin_HEXAGON_A2_satb,"ii","") -BUILTIN(__builtin_HEXAGON_C2_cmpltu,"iii","") -BUILTIN(__builtin_HEXAGON_S2_insertp,"LLiLLiLLiUIiUIi","") -BUILTIN(__builtin_HEXAGON_M2_mpyd_rnd_ll_s1,"LLiii","") -BUILTIN(__builtin_HEXAGON_M2_mpyd_rnd_ll_s0,"LLiii","") -BUILTIN(__builtin_HEXAGON_S2_lsr_i_p_nac,"LLiLLiLLiUIi","") -BUILTIN(__builtin_HEXAGON_S2_extractup_rp,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_S4_vxaddsubw,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_S4_vxaddsubh,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_A2_asrh,"ii","") -BUILTIN(__builtin_HEXAGON_S4_extractp_rp,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_S2_lsr_r_r_acc,"iiii","") -BUILTIN(__builtin_HEXAGON_M2_mpyd_nac_ll_s1,"LLiLLiii","") -BUILTIN(__builtin_HEXAGON_M2_mpyd_nac_ll_s0,"LLiLLiii","") -BUILTIN(__builtin_HEXAGON_C2_or,"iii","") -BUILTIN(__builtin_HEXAGON_M2_mmpyul_s1,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_M2_vrcmacr_s0,"LLiLLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_A2_xor,"iii","") -BUILTIN(__builtin_HEXAGON_A2_add,"iii","") -BUILTIN(__builtin_HEXAGON_A2_vsububs,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_M2_vmpy2s_s1,"LLiii","") -BUILTIN(__builtin_HEXAGON_M2_vmpy2s_s0,"LLiii","") -BUILTIN(__builtin_HEXAGON_A2_vraddub_acc,"LLiLLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_F2_sfinvsqrta,"ff","") -BUILTIN(__builtin_HEXAGON_S2_ct0p,"iLLi","") -BUILTIN(__builtin_HEXAGON_A2_svaddh,"iii","") -BUILTIN(__builtin_HEXAGON_S2_vcrotate,"LLiLLii","") -BUILTIN(__builtin_HEXAGON_A2_aslh,"ii","") -BUILTIN(__builtin_HEXAGON_A2_subh_h16_lh,"iii","") -BUILTIN(__builtin_HEXAGON_A2_subh_h16_ll,"iii","") -BUILTIN(__builtin_HEXAGON_M2_hmmpyl_rs1,"iii","") -BUILTIN(__builtin_HEXAGON_S2_asr_r_p,"LLiLLii","") -BUILTIN(__builtin_HEXAGON_S2_vsplatrh,"LLii","") -BUILTIN(__builtin_HEXAGON_S2_asr_r_r,"iii","") -BUILTIN(__builtin_HEXAGON_A2_addh_h16_hl,"iii","") -BUILTIN(__builtin_HEXAGON_S2_vsplatrb,"ii","") -BUILTIN(__builtin_HEXAGON_A2_addh_h16_hh,"iii","") -BUILTIN(__builtin_HEXAGON_M2_cmpyr_s0,"LLiii","") -BUILTIN(__builtin_HEXAGON_M2_dpmpyss_rnd_s0,"iii","") -BUILTIN(__builtin_HEXAGON_C2_muxri,"iiIii","") -BUILTIN(__builtin_HEXAGON_M2_vmac2es_s0,"LLiLLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_M2_vmac2es_s1,"LLiLLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_C2_pxfer_map,"ii","") -BUILTIN(__builtin_HEXAGON_M2_mpyu_lh_s1,"Uiii","") -BUILTIN(__builtin_HEXAGON_M2_mpyu_lh_s0,"Uiii","") -BUILTIN(__builtin_HEXAGON_S2_asl_i_r_or,"iiiUIi","") -BUILTIN(__builtin_HEXAGON_M2_mpyd_acc_hl_s0,"LLiLLiii","") -BUILTIN(__builtin_HEXAGON_M2_mpyd_acc_hl_s1,"LLiLLiii","") -BUILTIN(__builtin_HEXAGON_S2_asr_r_p_nac,"LLiLLiLLii","") -BUILTIN(__builtin_HEXAGON_A2_vaddw,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_S2_asr_i_r_and,"iiiUIi","") -BUILTIN(__builtin_HEXAGON_A2_vaddh,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_M2_mpy_nac_sat_lh_s1,"iiii","") -BUILTIN(__builtin_HEXAGON_M2_mpy_nac_sat_lh_s0,"iiii","") -BUILTIN(__builtin_HEXAGON_C2_cmpeqp,"iLLiLLi","") -BUILTIN(__builtin_HEXAGON_M4_mpyri_addi,"iUIiiUIi","") -BUILTIN(__builtin_HEXAGON_A2_not,"ii","") -BUILTIN(__builtin_HEXAGON_S4_andi_lsr_ri,"iUIiiUIi","") -BUILTIN(__builtin_HEXAGON_M2_macsip,"iiiUIi","") -BUILTIN(__builtin_HEXAGON_A2_tfrcrr,"ii","") -BUILTIN(__builtin_HEXAGON_M2_macsin,"iiiUIi","") -BUILTIN(__builtin_HEXAGON_C2_orn,"iii","") -BUILTIN(__builtin_HEXAGON_M4_and_andn,"iiii","") -BUILTIN(__builtin_HEXAGON_F2_sfmpy,"fff","") -BUILTIN(__builtin_HEXAGON_M2_mpyud_nac_hh_s1,"LLiLLiii","") -BUILTIN(__builtin_HEXAGON_M2_mpyud_nac_hh_s0,"LLiLLiii","") -BUILTIN(__builtin_HEXAGON_S2_lsr_r_p_acc,"LLiLLiLLii","") -BUILTIN(__builtin_HEXAGON_S2_asr_r_vw,"LLiLLii","") -BUILTIN(__builtin_HEXAGON_M4_and_or,"iiii","") -BUILTIN(__builtin_HEXAGON_S2_asr_r_vh,"LLiLLii","") -BUILTIN(__builtin_HEXAGON_C2_mask,"LLii","") -BUILTIN(__builtin_HEXAGON_M2_mpy_nac_hh_s0,"iiii","") -BUILTIN(__builtin_HEXAGON_M2_mpy_nac_hh_s1,"iiii","") -BUILTIN(__builtin_HEXAGON_M2_mpy_up_s1_sat,"iii","") -BUILTIN(__builtin_HEXAGON_A4_vcmpbgt,"iLLiLLi","") -BUILTIN(__builtin_HEXAGON_M5_vrmacbsu,"LLiLLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_S2_tableidxw_goodsyntax,"iiiUIiUIi","") -BUILTIN(__builtin_HEXAGON_A2_vrsadub,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_A2_tfrrcr,"ii","") -BUILTIN(__builtin_HEXAGON_M2_vrcmpys_acc_s1,"LLiLLiLLii","") -BUILTIN(__builtin_HEXAGON_F2_dfcmpge,"idd","") -BUILTIN(__builtin_HEXAGON_M2_accii,"iiiIi","") -BUILTIN(__builtin_HEXAGON_A5_vaddhubs,"iLLiLLi","") -BUILTIN(__builtin_HEXAGON_A2_vmaxw,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_A2_vmaxb,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_A2_vmaxh,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_S2_vsxthw,"LLii","") -BUILTIN(__builtin_HEXAGON_S4_andi_asl_ri,"iUIiiUIi","") -BUILTIN(__builtin_HEXAGON_S2_asl_i_p_nac,"LLiLLiLLiUIi","") -BUILTIN(__builtin_HEXAGON_S2_lsl_r_p_xor,"LLiLLiLLii","") -BUILTIN(__builtin_HEXAGON_C2_cmpgt,"iii","") -BUILTIN(__builtin_HEXAGON_F2_conv_df2d_chop,"LLid","") -BUILTIN(__builtin_HEXAGON_M2_mpyu_nac_hl_s0,"iiii","") -BUILTIN(__builtin_HEXAGON_M2_mpyu_nac_hl_s1,"iiii","") -BUILTIN(__builtin_HEXAGON_F2_conv_sf2w,"if","") -BUILTIN(__builtin_HEXAGON_S2_lsr_r_p_or,"LLiLLiLLii","") -BUILTIN(__builtin_HEXAGON_F2_sfclass,"ifUIi","") -BUILTIN(__builtin_HEXAGON_M2_mpyud_acc_lh_s0,"LLiLLiii","") -BUILTIN(__builtin_HEXAGON_M4_xor_andn,"iiii","") -BUILTIN(__builtin_HEXAGON_S2_addasl_rrri,"iiiUIi","") -BUILTIN(__builtin_HEXAGON_M5_vdmpybsu,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_M2_mpyu_nac_hh_s0,"iiii","") -BUILTIN(__builtin_HEXAGON_M2_mpyu_nac_hh_s1,"iiii","") -BUILTIN(__builtin_HEXAGON_A2_addi,"iiIi","") -BUILTIN(__builtin_HEXAGON_A2_addp,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_M2_vmpy2s_s1pack,"iii","") -BUILTIN(__builtin_HEXAGON_S4_clbpnorm,"iLLi","") -BUILTIN(__builtin_HEXAGON_A4_round_rr_sat,"iii","") -BUILTIN(__builtin_HEXAGON_M2_nacci,"iiii","") -BUILTIN(__builtin_HEXAGON_S2_shuffeh,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_S2_lsr_i_r_and,"iiiUIi","") -BUILTIN(__builtin_HEXAGON_M2_mpy_sat_rnd_hh_s1,"iii","") -BUILTIN(__builtin_HEXAGON_M2_mpy_sat_rnd_hh_s0,"iii","") -BUILTIN(__builtin_HEXAGON_F2_conv_sf2uw,"if","") -BUILTIN(__builtin_HEXAGON_A2_vsubh,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_F2_conv_sf2ud,"LLif","") -BUILTIN(__builtin_HEXAGON_A2_vsubw,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_A2_vcmpwgt,"iLLiLLi","") -BUILTIN(__builtin_HEXAGON_M4_xor_or,"iiii","") -BUILTIN(__builtin_HEXAGON_F2_conv_sf2uw_chop,"if","") -BUILTIN(__builtin_HEXAGON_S2_asl_r_vw,"LLiLLii","") -BUILTIN(__builtin_HEXAGON_S2_vsatwuh_nopack,"LLiLLi","") -BUILTIN(__builtin_HEXAGON_S2_asl_r_vh,"LLiLLii","") -BUILTIN(__builtin_HEXAGON_A2_svsubuhs,"iii","") -BUILTIN(__builtin_HEXAGON_M5_vmpybsu,"LLiii","") -BUILTIN(__builtin_HEXAGON_A2_subh_l16_sat_ll,"iii","") -BUILTIN(__builtin_HEXAGON_C4_and_and,"iiii","") -BUILTIN(__builtin_HEXAGON_M2_mpyu_acc_hl_s1,"iiii","") -BUILTIN(__builtin_HEXAGON_M2_mpyu_acc_hl_s0,"iiii","") -BUILTIN(__builtin_HEXAGON_S2_lsr_r_p,"LLiLLii","") -BUILTIN(__builtin_HEXAGON_S2_lsr_r_r,"iii","") -BUILTIN(__builtin_HEXAGON_A4_subp_c,"LLiLLiLLiv*","") -BUILTIN(__builtin_HEXAGON_A2_vsubhs,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_C2_vitpack,"iii","") -BUILTIN(__builtin_HEXAGON_A2_vavguhr,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_S2_vsplicerb,"LLiLLiLLii","") -BUILTIN(__builtin_HEXAGON_C4_nbitsclr,"iii","") -BUILTIN(__builtin_HEXAGON_A2_vcmpbgtu,"iLLiLLi","") -BUILTIN(__builtin_HEXAGON_M2_cmpys_s1,"LLiii","") -BUILTIN(__builtin_HEXAGON_M2_cmpys_s0,"LLiii","") -BUILTIN(__builtin_HEXAGON_F2_dfcmpuo,"idd","") -BUILTIN(__builtin_HEXAGON_S2_shuffob,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_C2_and,"iii","") -BUILTIN(__builtin_HEXAGON_S5_popcountp,"iLLi","") -BUILTIN(__builtin_HEXAGON_S4_extractp,"LLiLLiUIiUIi","") -BUILTIN(__builtin_HEXAGON_S2_cl0,"ii","") -BUILTIN(__builtin_HEXAGON_A4_vcmpbgti,"iLLiIi","") -BUILTIN(__builtin_HEXAGON_M2_mmacls_s1,"LLiLLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_M2_mmacls_s0,"LLiLLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_C4_cmpneq,"iii","") -BUILTIN(__builtin_HEXAGON_M2_vmac2es,"LLiLLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_M2_vdmacs_s0,"LLiLLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_M2_vdmacs_s1,"LLiLLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_M2_mpyud_ll_s0,"ULLiii","") -BUILTIN(__builtin_HEXAGON_M2_mpyud_ll_s1,"ULLiii","") -BUILTIN(__builtin_HEXAGON_S2_clb,"ii","") -BUILTIN(__builtin_HEXAGON_M2_mpy_nac_ll_s0,"iiii","") -BUILTIN(__builtin_HEXAGON_M2_mpy_nac_ll_s1,"iiii","") -BUILTIN(__builtin_HEXAGON_M2_mpyd_nac_hl_s1,"LLiLLiii","") -BUILTIN(__builtin_HEXAGON_M2_mpyd_nac_hl_s0,"LLiLLiii","") -BUILTIN(__builtin_HEXAGON_M2_maci,"iiii","") -BUILTIN(__builtin_HEXAGON_A2_vmaxuh,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_A4_bitspliti,"LLiiUIi","") -BUILTIN(__builtin_HEXAGON_A2_vmaxub,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_M2_mpyud_hh_s0,"ULLiii","") -BUILTIN(__builtin_HEXAGON_M2_mpyud_hh_s1,"ULLiii","") -BUILTIN(__builtin_HEXAGON_M2_vrmac_s0,"LLiLLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_M2_mpy_sat_lh_s0,"iii","") -BUILTIN(__builtin_HEXAGON_S2_asl_r_r_sat,"iii","") -BUILTIN(__builtin_HEXAGON_F2_conv_sf2d,"LLif","") -BUILTIN(__builtin_HEXAGON_S2_asr_r_r_nac,"iiii","") -BUILTIN(__builtin_HEXAGON_F2_dfimm_n,"dUIi","") -BUILTIN(__builtin_HEXAGON_A4_cmphgt,"iii","") -BUILTIN(__builtin_HEXAGON_F2_dfimm_p,"dUIi","") -BUILTIN(__builtin_HEXAGON_M2_mpyud_acc_lh_s1,"LLiLLiii","") -BUILTIN(__builtin_HEXAGON_M2_vcmpy_s1_sat_r,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_M4_mpyri_addr_u2,"iiUIii","") -BUILTIN(__builtin_HEXAGON_M2_vcmpy_s1_sat_i,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_S2_lsl_r_p_nac,"LLiLLiLLii","") -BUILTIN(__builtin_HEXAGON_M5_vrmacbuu,"LLiLLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_S5_asrhub_rnd_sat_goodsyntax,"iLLiUIi","") -BUILTIN(__builtin_HEXAGON_S2_vspliceib,"LLiLLiLLiUIi","") -BUILTIN(__builtin_HEXAGON_M2_dpmpyss_acc_s0,"LLiLLiii","") -BUILTIN(__builtin_HEXAGON_M2_cnacs_s1,"LLiLLiii","") -BUILTIN(__builtin_HEXAGON_M2_cnacs_s0,"LLiLLiii","") -BUILTIN(__builtin_HEXAGON_A2_maxu,"Uiii","") -BUILTIN(__builtin_HEXAGON_A2_maxp,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_A2_andir,"iiIi","") -BUILTIN(__builtin_HEXAGON_F2_sfrecipa,"fff","") -BUILTIN(__builtin_HEXAGON_A2_combineii,"LLiIiIi","") -BUILTIN(__builtin_HEXAGON_A4_orn,"iii","") -BUILTIN(__builtin_HEXAGON_A4_cmpbgtui,"iiUIi","") -BUILTIN(__builtin_HEXAGON_S2_lsr_r_r_or,"iiii","") -BUILTIN(__builtin_HEXAGON_A4_vcmpbeqi,"iLLiUIi","") -BUILTIN(__builtin_HEXAGON_S2_lsl_r_r,"iii","") -BUILTIN(__builtin_HEXAGON_S2_lsl_r_p,"LLiLLii","") -BUILTIN(__builtin_HEXAGON_A2_or,"iii","") -BUILTIN(__builtin_HEXAGON_F2_dfcmpeq,"idd","") -BUILTIN(__builtin_HEXAGON_C2_cmpeq,"iii","") -BUILTIN(__builtin_HEXAGON_A2_tfrp,"LLiLLi","") -BUILTIN(__builtin_HEXAGON_C4_and_andn,"iiii","") -BUILTIN(__builtin_HEXAGON_S2_vsathub_nopack,"LLiLLi","") -BUILTIN(__builtin_HEXAGON_A2_satuh,"ii","") -BUILTIN(__builtin_HEXAGON_A2_satub,"ii","") -BUILTIN(__builtin_HEXAGON_M2_vrcmpys_s1,"LLiLLii","") -BUILTIN(__builtin_HEXAGON_S4_or_ori,"iiiIi","") -BUILTIN(__builtin_HEXAGON_C4_fastcorner9_not,"iii","") -BUILTIN(__builtin_HEXAGON_A2_tfrih,"iiUIi","") -BUILTIN(__builtin_HEXAGON_A2_tfril,"iiUIi","") -BUILTIN(__builtin_HEXAGON_M4_mpyri_addr,"iiiUIi","") -BUILTIN(__builtin_HEXAGON_S2_vtrunehb,"iLLi","") -BUILTIN(__builtin_HEXAGON_A2_vabsw,"LLiLLi","") -BUILTIN(__builtin_HEXAGON_A2_vabsh,"LLiLLi","") -BUILTIN(__builtin_HEXAGON_F2_sfsub,"fff","") -BUILTIN(__builtin_HEXAGON_C2_muxii,"iiIiIi","") -BUILTIN(__builtin_HEXAGON_C2_muxir,"iiiIi","") -BUILTIN(__builtin_HEXAGON_A2_swiz,"ii","") -BUILTIN(__builtin_HEXAGON_S2_asr_i_p_and,"LLiLLiLLiUIi","") -BUILTIN(__builtin_HEXAGON_M2_cmpyrsc_s0,"iii","") -BUILTIN(__builtin_HEXAGON_M2_cmpyrsc_s1,"iii","") -BUILTIN(__builtin_HEXAGON_A2_vraddub,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_A4_tlbmatch,"iLLii","") -BUILTIN(__builtin_HEXAGON_F2_conv_df2w_chop,"id","") -BUILTIN(__builtin_HEXAGON_A2_and,"iii","") -BUILTIN(__builtin_HEXAGON_S2_lsr_r_p_and,"LLiLLiLLii","") -BUILTIN(__builtin_HEXAGON_M2_mpy_nac_sat_ll_s1,"iiii","") -BUILTIN(__builtin_HEXAGON_M2_mpy_nac_sat_ll_s0,"iiii","") -BUILTIN(__builtin_HEXAGON_S4_extract,"iiUIiUIi","") -BUILTIN(__builtin_HEXAGON_A2_vcmpweq,"iLLiLLi","") -BUILTIN(__builtin_HEXAGON_M2_acci,"iiii","") -BUILTIN(__builtin_HEXAGON_S2_lsr_i_p_acc,"LLiLLiLLiUIi","") -BUILTIN(__builtin_HEXAGON_S2_lsr_i_p_or,"LLiLLiLLiUIi","") -BUILTIN(__builtin_HEXAGON_F2_conv_ud2sf,"fLLi","") -BUILTIN(__builtin_HEXAGON_A2_tfr,"ii","") -BUILTIN(__builtin_HEXAGON_S2_asr_i_p_or,"LLiLLiLLiUIi","") -BUILTIN(__builtin_HEXAGON_A2_subri,"iIii","") -BUILTIN(__builtin_HEXAGON_A4_vrmaxuw,"LLiLLiLLii","") -BUILTIN(__builtin_HEXAGON_M5_vmpybuu,"LLiii","") -BUILTIN(__builtin_HEXAGON_A4_vrmaxuh,"LLiLLiLLii","") -BUILTIN(__builtin_HEXAGON_S2_asl_i_vw,"LLiLLiUIi","") -BUILTIN(__builtin_HEXAGON_A2_vavgw,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_S2_brev,"ii","") -BUILTIN(__builtin_HEXAGON_A2_vavgh,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_S2_clrbit_i,"iiUIi","") -BUILTIN(__builtin_HEXAGON_S2_asl_i_vh,"LLiLLiUIi","") -BUILTIN(__builtin_HEXAGON_S2_lsr_i_r_or,"iiiUIi","") -BUILTIN(__builtin_HEXAGON_S2_lsl_r_r_nac,"iiii","") -BUILTIN(__builtin_HEXAGON_M2_mmpyl_rs1,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_M2_mpyud_hl_s1,"ULLiii","") -BUILTIN(__builtin_HEXAGON_M2_mmpyl_s0,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_M2_mmpyl_s1,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_M2_naccii,"iiiIi","") -BUILTIN(__builtin_HEXAGON_S2_vrndpackwhs,"iLLi","") -BUILTIN(__builtin_HEXAGON_S2_vtrunewh,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_M2_dpmpyss_nac_s0,"LLiLLiii","") -BUILTIN(__builtin_HEXAGON_M2_mpyd_ll_s0,"LLiii","") -BUILTIN(__builtin_HEXAGON_M2_mpyd_ll_s1,"LLiii","") -BUILTIN(__builtin_HEXAGON_M4_mac_up_s1_sat,"iiii","") -BUILTIN(__builtin_HEXAGON_S4_vrcrotate_acc,"LLiLLiLLiiUIi","") -BUILTIN(__builtin_HEXAGON_F2_conv_uw2df,"di","") -BUILTIN(__builtin_HEXAGON_A2_vaddubs,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_S2_asr_r_r_acc,"iiii","") -BUILTIN(__builtin_HEXAGON_A2_orir,"iiIi","") -BUILTIN(__builtin_HEXAGON_A2_andp,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_S2_lfsp,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_A2_min,"iii","") -BUILTIN(__builtin_HEXAGON_M2_mpysmi,"iiIi","") -BUILTIN(__builtin_HEXAGON_M2_vcmpy_s0_sat_r,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_M2_mpyu_acc_ll_s1,"iiii","") -BUILTIN(__builtin_HEXAGON_M2_mpyu_acc_ll_s0,"iiii","") -BUILTIN(__builtin_HEXAGON_S2_asr_r_svw_trun,"iLLii","") -BUILTIN(__builtin_HEXAGON_M2_mmpyh_s0,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_M2_mmpyh_s1,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_F2_conv_sf2df,"df","") -BUILTIN(__builtin_HEXAGON_S2_vtrunohb,"iLLi","") -BUILTIN(__builtin_HEXAGON_F2_conv_sf2d_chop,"LLif","") -BUILTIN(__builtin_HEXAGON_M2_mpyd_lh_s0,"LLiii","") -BUILTIN(__builtin_HEXAGON_F2_conv_df2w,"id","") -BUILTIN(__builtin_HEXAGON_S5_asrhub_sat,"iLLiUIi","") -BUILTIN(__builtin_HEXAGON_S2_asl_i_r_xacc,"iiiUIi","") -BUILTIN(__builtin_HEXAGON_F2_conv_df2d,"LLid","") -BUILTIN(__builtin_HEXAGON_M2_mmaculs_s1,"LLiLLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_M2_mmaculs_s0,"LLiLLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_A2_svadduhs,"iii","") -BUILTIN(__builtin_HEXAGON_F2_conv_sf2w_chop,"if","") -BUILTIN(__builtin_HEXAGON_S2_svsathub,"ii","") -BUILTIN(__builtin_HEXAGON_M2_mpyd_rnd_hl_s1,"LLiii","") -BUILTIN(__builtin_HEXAGON_M2_mpyd_rnd_hl_s0,"LLiii","") -BUILTIN(__builtin_HEXAGON_S2_setbit_r,"iii","") -BUILTIN(__builtin_HEXAGON_A2_vavghr,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_F2_sffma_sc,"ffffi","") -BUILTIN(__builtin_HEXAGON_F2_dfclass,"idUIi","") -BUILTIN(__builtin_HEXAGON_F2_conv_df2ud,"LLid","") -BUILTIN(__builtin_HEXAGON_F2_conv_df2uw,"id","") -BUILTIN(__builtin_HEXAGON_M2_cmpyrs_s0,"iii","") -BUILTIN(__builtin_HEXAGON_M2_cmpyrs_s1,"iii","") -BUILTIN(__builtin_HEXAGON_C4_cmpltei,"iiIi","") -BUILTIN(__builtin_HEXAGON_C4_cmplteu,"iii","") -BUILTIN(__builtin_HEXAGON_A2_vsubb_map,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_A2_subh_l16_ll,"iii","") -BUILTIN(__builtin_HEXAGON_S2_asr_i_r_rnd,"iiUIi","") -BUILTIN(__builtin_HEXAGON_M2_vrmpy_s0,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_M2_mpyd_rnd_hh_s1,"LLiii","") -BUILTIN(__builtin_HEXAGON_M2_mpyd_rnd_hh_s0,"LLiii","") -BUILTIN(__builtin_HEXAGON_A2_minup,"ULLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_S2_valignrb,"LLiLLiLLii","") -BUILTIN(__builtin_HEXAGON_S2_asr_r_p_acc,"LLiLLiLLii","") -BUILTIN(__builtin_HEXAGON_M2_mmpyl_rs0,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_M2_vrcmaci_s0,"LLiLLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_A2_vaddub,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_A2_combine_lh,"iii","") -BUILTIN(__builtin_HEXAGON_M5_vdmacbsu,"LLiLLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_A2_combine_ll,"iii","") -BUILTIN(__builtin_HEXAGON_M2_mpyud_hl_s0,"ULLiii","") -BUILTIN(__builtin_HEXAGON_M2_vrcmpyi_s0c,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_S2_asr_i_p_rnd,"LLiLLiUIi","") -BUILTIN(__builtin_HEXAGON_A2_addpsat,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_A2_svaddhs,"iii","") -BUILTIN(__builtin_HEXAGON_S4_ori_lsr_ri,"iUIiiUIi","") -BUILTIN(__builtin_HEXAGON_M2_mpy_sat_rnd_ll_s1,"iii","") -BUILTIN(__builtin_HEXAGON_M2_mpy_sat_rnd_ll_s0,"iii","") -BUILTIN(__builtin_HEXAGON_A2_vminw,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_A2_vminh,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_M2_vrcmpyr_s0,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_A2_vminb,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_M2_vcmac_s0_sat_i,"LLiLLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_M2_mpyud_lh_s0,"ULLiii","") -BUILTIN(__builtin_HEXAGON_M2_mpyud_lh_s1,"ULLiii","") -BUILTIN(__builtin_HEXAGON_S2_asl_r_r_or,"iiii","") -BUILTIN(__builtin_HEXAGON_S4_lsli,"iIii","") -BUILTIN(__builtin_HEXAGON_S2_lsl_r_vw,"LLiLLii","") -BUILTIN(__builtin_HEXAGON_M2_mpy_hh_s1,"iii","") -BUILTIN(__builtin_HEXAGON_M4_vrmpyeh_s0,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_M4_vrmpyeh_s1,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_M2_mpy_nac_lh_s0,"iiii","") -BUILTIN(__builtin_HEXAGON_M2_mpy_nac_lh_s1,"iiii","") -BUILTIN(__builtin_HEXAGON_M2_vraddh,"iLLiLLi","") -BUILTIN(__builtin_HEXAGON_C2_tfrrp,"ii","") -BUILTIN(__builtin_HEXAGON_M2_mpy_acc_sat_ll_s0,"iiii","") -BUILTIN(__builtin_HEXAGON_M2_mpy_acc_sat_ll_s1,"iiii","") -BUILTIN(__builtin_HEXAGON_S2_vtrunowh,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_A2_abs,"ii","") -BUILTIN(__builtin_HEXAGON_A4_cmpbeq,"iii","") -BUILTIN(__builtin_HEXAGON_A2_negp,"LLiLLi","") -BUILTIN(__builtin_HEXAGON_S2_asl_i_r_sat,"iiUIi","") -BUILTIN(__builtin_HEXAGON_A2_addh_l16_sat_hl,"iii","") -BUILTIN(__builtin_HEXAGON_S2_vsatwuh,"iLLi","") -BUILTIN(__builtin_HEXAGON_F2_dfcmpgt,"idd","") -BUILTIN(__builtin_HEXAGON_S2_svsathb,"ii","") -BUILTIN(__builtin_HEXAGON_C2_cmpgtup,"iLLiLLi","") -BUILTIN(__builtin_HEXAGON_A4_cround_ri,"iiUIi","") -BUILTIN(__builtin_HEXAGON_S4_clbpaddi,"iLLiIi","") -BUILTIN(__builtin_HEXAGON_A4_cround_rr,"iii","") -BUILTIN(__builtin_HEXAGON_C2_mux,"iiii","") -BUILTIN(__builtin_HEXAGON_M2_dpmpyuu_s0,"ULLiii","") -BUILTIN(__builtin_HEXAGON_S2_shuffeb,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_A2_vminuw,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_A2_vaddhs,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_S2_insert_rp,"iiiLLi","") -BUILTIN(__builtin_HEXAGON_A2_vminuh,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_A2_vminub,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_S2_extractu,"iiUIiUIi","") -BUILTIN(__builtin_HEXAGON_A2_svsubh,"iii","") -BUILTIN(__builtin_HEXAGON_S4_clbaddi,"iiIi","") -BUILTIN(__builtin_HEXAGON_F2_sffms,"ffff","") -BUILTIN(__builtin_HEXAGON_S2_vsxtbh,"LLii","") -BUILTIN(__builtin_HEXAGON_M2_mpyud_nac_ll_s1,"LLiLLiii","") -BUILTIN(__builtin_HEXAGON_M2_mpyud_nac_ll_s0,"LLiLLiii","") -BUILTIN(__builtin_HEXAGON_A2_subp,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_M2_vmpy2es_s1,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_M2_vmpy2es_s0,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_S4_parity,"iii","") -BUILTIN(__builtin_HEXAGON_M2_mpy_acc_hh_s1,"iiii","") -BUILTIN(__builtin_HEXAGON_M2_mpy_acc_hh_s0,"iiii","") -BUILTIN(__builtin_HEXAGON_S4_addi_asl_ri,"iUIiiUIi","") -BUILTIN(__builtin_HEXAGON_M2_mpyd_nac_hh_s1,"LLiLLiii","") -BUILTIN(__builtin_HEXAGON_M2_mpyd_nac_hh_s0,"LLiLLiii","") -BUILTIN(__builtin_HEXAGON_S2_asr_i_r_nac,"iiiUIi","") -BUILTIN(__builtin_HEXAGON_A4_cmpheqi,"iiIi","") -BUILTIN(__builtin_HEXAGON_S2_lsr_r_p_xor,"LLiLLiLLii","") -BUILTIN(__builtin_HEXAGON_M2_mpy_acc_hl_s1,"iiii","") -BUILTIN(__builtin_HEXAGON_M2_mpy_acc_hl_s0,"iiii","") -BUILTIN(__builtin_HEXAGON_F2_conv_sf2ud_chop,"LLif","") -BUILTIN(__builtin_HEXAGON_C2_cmpgeui,"iiUIi","") -BUILTIN(__builtin_HEXAGON_M2_mpy_acc_sat_hh_s0,"iiii","") -BUILTIN(__builtin_HEXAGON_M2_mpy_acc_sat_hh_s1,"iiii","") -BUILTIN(__builtin_HEXAGON_S2_asl_r_p_and,"LLiLLiLLii","") -BUILTIN(__builtin_HEXAGON_A2_addh_h16_sat_lh,"iii","") -BUILTIN(__builtin_HEXAGON_A2_addh_h16_sat_ll,"iii","") -BUILTIN(__builtin_HEXAGON_M4_nac_up_s1_sat,"iiii","") -BUILTIN(__builtin_HEXAGON_M2_mpyud_nac_lh_s1,"LLiLLiii","") -BUILTIN(__builtin_HEXAGON_M2_mpyud_nac_lh_s0,"LLiLLiii","") -BUILTIN(__builtin_HEXAGON_A4_round_ri_sat,"iiUIi","") -BUILTIN(__builtin_HEXAGON_M2_mpy_nac_hl_s0,"iiii","") -BUILTIN(__builtin_HEXAGON_M2_mpy_nac_hl_s1,"iiii","") -BUILTIN(__builtin_HEXAGON_A2_vavghcr,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_M2_mmacls_rs0,"LLiLLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_M2_mmacls_rs1,"LLiLLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_M2_cmaci_s0,"LLiLLiii","") -BUILTIN(__builtin_HEXAGON_S2_setbit_i,"iiUIi","") -BUILTIN(__builtin_HEXAGON_S2_asl_i_p_or,"LLiLLiLLiUIi","") -BUILTIN(__builtin_HEXAGON_A4_andn,"iii","") -BUILTIN(__builtin_HEXAGON_M5_vrmpybsu,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_S2_vrndpackwh,"iLLi","") -BUILTIN(__builtin_HEXAGON_M2_vcmac_s0_sat_r,"LLiLLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_A2_vmaxuw,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_C2_bitsclr,"iii","") -BUILTIN(__builtin_HEXAGON_M2_xor_xacc,"iiii","") -BUILTIN(__builtin_HEXAGON_A4_vcmpbgtui,"iLLiUIi","") -BUILTIN(__builtin_HEXAGON_A4_ornp,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_A2_tfrpi,"LLiIi","") -BUILTIN(__builtin_HEXAGON_C4_and_or,"iiii","") -BUILTIN(__builtin_HEXAGON_M2_mpy_nac_sat_hh_s1,"iiii","") -BUILTIN(__builtin_HEXAGON_M2_mpy_nac_sat_hh_s0,"iiii","") -BUILTIN(__builtin_HEXAGON_A2_subh_h16_sat_ll,"iii","") -BUILTIN(__builtin_HEXAGON_A2_subh_h16_sat_lh,"iii","") -BUILTIN(__builtin_HEXAGON_M2_vmpy2su_s1,"LLiii","") -BUILTIN(__builtin_HEXAGON_M2_vmpy2su_s0,"LLiii","") -BUILTIN(__builtin_HEXAGON_S2_asr_i_p_acc,"LLiLLiLLiUIi","") -BUILTIN(__builtin_HEXAGON_C4_nbitsclri,"iiUIi","") -BUILTIN(__builtin_HEXAGON_S2_lsr_i_vh,"LLiLLiUIi","") -BUILTIN(__builtin_HEXAGON_S2_lsr_i_p_xacc,"LLiLLiLLiUIi","") - -// V55 Scalar Instructions. - -BUILTIN(__builtin_HEXAGON_A5_ACS,"LLiLLiLLiLLi","") - -// V60 Scalar Instructions. - -BUILTIN(__builtin_HEXAGON_S6_rol_i_p_and,"LLiLLiLLiUIi","") -BUILTIN(__builtin_HEXAGON_S6_rol_i_r_xacc,"iiiUIi","") -BUILTIN(__builtin_HEXAGON_S6_rol_i_r_and,"iiiUIi","") -BUILTIN(__builtin_HEXAGON_S6_rol_i_r_acc,"iiiUIi","") -BUILTIN(__builtin_HEXAGON_S6_rol_i_p_xacc,"LLiLLiLLiUIi","") -BUILTIN(__builtin_HEXAGON_S6_rol_i_p,"LLiLLiUIi","") -BUILTIN(__builtin_HEXAGON_S6_rol_i_p_nac,"LLiLLiLLiUIi","") -BUILTIN(__builtin_HEXAGON_S6_rol_i_p_acc,"LLiLLiLLiUIi","") -BUILTIN(__builtin_HEXAGON_S6_rol_i_r_or,"iiiUIi","") -BUILTIN(__builtin_HEXAGON_S6_rol_i_r,"iiUIi","") -BUILTIN(__builtin_HEXAGON_S6_rol_i_r_nac,"iiiUIi","") -BUILTIN(__builtin_HEXAGON_S6_rol_i_p_or,"LLiLLiLLiUIi","") - -// V62 Scalar Instructions. +#if defined(BUILTIN) && !defined(TARGET_BUILTIN) +# define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) BUILTIN(ID, TYPE, ATTRS) +#endif + +#pragma push_macro("V67") +#define V67 "v67" +#pragma push_macro("V66") +#define V66 "v66|" V67 +#pragma push_macro("V65") +#define V65 "v65|" V66 +#pragma push_macro("V62") +#define V62 "v62|" V65 +#pragma push_macro("V60") +#define V60 "v60|" V62 +#pragma push_macro("V55") +#define V55 "v55|" V60 +#pragma push_macro("V5") +#define V5 "v5|" V55 + +#pragma push_macro("HVXV67") +#define HVXV67 "hvxv67" +#pragma push_macro("HVXV66") +#define HVXV66 "hvxv66|" HVXV67 +#pragma push_macro("HVXV65") +#define HVXV65 "hvxv65|" HVXV66 +#pragma push_macro("HVXV62") +#define HVXV62 "hvxv62|" HVXV65 +#pragma push_macro("HVXV60") +#define HVXV60 "hvxv60|" HVXV62 -BUILTIN(__builtin_HEXAGON_S6_vtrunehb_ppp,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_V6_ldntnt0,"V16ii","") -BUILTIN(__builtin_HEXAGON_M6_vabsdiffub,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_S6_vtrunohb_ppp,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_M6_vabsdiffb,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_A6_vminub_RdP,"LLiLLiLLi","") -BUILTIN(__builtin_HEXAGON_S6_vsplatrbp,"LLii","") -// V65 Scalar Instructions. - -BUILTIN(__builtin_HEXAGON_A6_vcmpbeq_notany,"iLLiLLi","") - -// V66 Scalar Instructions. - -BUILTIN(__builtin_HEXAGON_F2_dfsub,"ddd","") -BUILTIN(__builtin_HEXAGON_F2_dfadd,"ddd","") -BUILTIN(__builtin_HEXAGON_M2_mnaci,"iiii","") -BUILTIN(__builtin_HEXAGON_S2_mask,"iUIiUIi","") - -// V60 HVX Instructions. - -BUILTIN(__builtin_HEXAGON_V6_veqb_or,"V16iV16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_veqb_or_128B,"V32iV32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vminub,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vminub_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vaslw_acc,"V16iV16iV16ii","") -BUILTIN(__builtin_HEXAGON_V6_vaslw_acc_128B,"V32iV32iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_vmpyhvsrs,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vmpyhvsrs_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vsathub,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vsathub_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vaddh_dv,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vaddh_dv_128B,"V64iV64iV64i","") -BUILTIN(__builtin_HEXAGON_V6_vrmpybusi,"V32iV32iiUIi","") -BUILTIN(__builtin_HEXAGON_V6_vrmpybusi_128B,"V64iV64iiUIi","") -BUILTIN(__builtin_HEXAGON_V6_vshufoh,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vshufoh_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vasrwv,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vasrwv_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vdmpyhsuisat,"V16iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_vdmpyhsuisat_128B,"V32iV64ii","") -BUILTIN(__builtin_HEXAGON_V6_vrsadubi_acc,"V32iV32iV32iiUIi","") -BUILTIN(__builtin_HEXAGON_V6_vrsadubi_acc_128B,"V64iV64iV64iiUIi","") -BUILTIN(__builtin_HEXAGON_V6_vnavgw,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vnavgw_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vnavgh,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vnavgh_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vavgub,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vavgub_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vsubb,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vsubb_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vgtw_and,"V16iV16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vgtw_and_128B,"V32iV32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vavgubrnd,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vavgubrnd_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vrmpybusv,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vrmpybusv_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vsubbnq,"V16iV16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vsubbnq_128B,"V32iV32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vroundhb,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vroundhb_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vadduhsat_dv,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vadduhsat_dv_128B,"V64iV64iV64i","") -BUILTIN(__builtin_HEXAGON_V6_vsububsat,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vsububsat_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vmpabus_acc,"V32iV32iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_vmpabus_acc_128B,"V64iV64iV64ii","") -BUILTIN(__builtin_HEXAGON_V6_vmux,"V16iV16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vmux_128B,"V32iV32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vmpyhus,"V32iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vmpyhus_128B,"V64iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vpackeb,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vpackeb_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vsubhnq,"V16iV16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vsubhnq_128B,"V32iV32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vavghrnd,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vavghrnd_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vtran2x2_map,"V16iV16iv*i","") -BUILTIN(__builtin_HEXAGON_V6_vtran2x2_map_128B,"V32iV32iv*i","") -BUILTIN(__builtin_HEXAGON_V6_vdelta,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vdelta_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vgtuh_and,"V16iV16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vgtuh_and_128B,"V32iV32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vtmpyhb,"V32iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_vtmpyhb_128B,"V64iV64ii","") -BUILTIN(__builtin_HEXAGON_V6_vpackob,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vpackob_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vmaxh,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vmaxh_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vtmpybus_acc,"V32iV32iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_vtmpybus_acc_128B,"V64iV64iV64ii","") -BUILTIN(__builtin_HEXAGON_V6_vsubuhsat,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vsubuhsat_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vasrw_acc,"V16iV16iV16ii","") -BUILTIN(__builtin_HEXAGON_V6_vasrw_acc_128B,"V32iV32iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_pred_or,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_pred_or_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vrmpyub_acc,"V16iV16iV16ii","") -BUILTIN(__builtin_HEXAGON_V6_vrmpyub_acc_128B,"V32iV32iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_lo,"V16iV32i","") -BUILTIN(__builtin_HEXAGON_V6_lo_128B,"V32iV64i","") -BUILTIN(__builtin_HEXAGON_V6_vsubb_dv,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vsubb_dv_128B,"V64iV64iV64i","") -BUILTIN(__builtin_HEXAGON_V6_vsubhsat_dv,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vsubhsat_dv_128B,"V64iV64iV64i","") -BUILTIN(__builtin_HEXAGON_V6_vmpyiwh,"V16iV16ii","") -BUILTIN(__builtin_HEXAGON_V6_vmpyiwh_128B,"V32iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_vmpyiwb,"V16iV16ii","") -BUILTIN(__builtin_HEXAGON_V6_vmpyiwb_128B,"V32iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_ldu0,"V16ii","") -BUILTIN(__builtin_HEXAGON_V6_ldu0_128B,"V32ii","") -BUILTIN(__builtin_HEXAGON_V6_vgtuh_xor,"V16iV16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vgtuh_xor_128B,"V32iV32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vgth_or,"V16iV16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vgth_or_128B,"V32iV32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vavgh,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vavgh_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vlalignb,"V16iV16iV16ii","") -BUILTIN(__builtin_HEXAGON_V6_vlalignb_128B,"V32iV32iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_vsh,"V32iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vsh_128B,"V64iV32i","") -BUILTIN(__builtin_HEXAGON_V6_pred_and_n,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_pred_and_n_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vsb,"V32iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vsb_128B,"V64iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vroundwuh,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vroundwuh_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vasrhv,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vasrhv_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vshuffh,"V16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vshuffh_128B,"V32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vaddhsat_dv,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vaddhsat_dv_128B,"V64iV64iV64i","") -BUILTIN(__builtin_HEXAGON_V6_vnavgub,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vnavgub_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vrmpybv,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vrmpybv_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vnormamth,"V16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vnormamth_128B,"V32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vdmpyhb,"V16iV16ii","") -BUILTIN(__builtin_HEXAGON_V6_vdmpyhb_128B,"V32iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_vavguh,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vavguh_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vlsrwv,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vlsrwv_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vlsrhv,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vlsrhv_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vdmpyhisat,"V16iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_vdmpyhisat_128B,"V32iV64ii","") -BUILTIN(__builtin_HEXAGON_V6_vdmpyhvsat,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vdmpyhvsat_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vaddw,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vaddw_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vzh,"V32iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vzh_128B,"V64iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vaddh,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vaddh_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vmaxub,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vmaxub_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vmpyhv_acc,"V32iV32iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vmpyhv_acc_128B,"V64iV64iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vadduhsat,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vadduhsat_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vshufoeh,"V32iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vshufoeh_128B,"V64iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vmpyuhv_acc,"V32iV32iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vmpyuhv_acc_128B,"V64iV64iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_veqh,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_veqh_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vmpabuuv,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vmpabuuv_128B,"V64iV64iV64i","") -BUILTIN(__builtin_HEXAGON_V6_vasrwhsat,"V16iV16iV16ii","") -BUILTIN(__builtin_HEXAGON_V6_vasrwhsat_128B,"V32iV32iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_vminuh,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vminuh_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vror,"V16iV16ii","") -BUILTIN(__builtin_HEXAGON_V6_vror_128B,"V32iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_vmpyowh_rnd_sacc,"V16iV16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vmpyowh_rnd_sacc_128B,"V32iV32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vmaxuh,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vmaxuh_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vabsh_sat,"V16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vabsh_sat_128B,"V32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_pred_or_n,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_pred_or_n_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vdealb,"V16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vdealb_128B,"V32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vmpybusv,"V32iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vmpybusv_128B,"V64iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vzb,"V32iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vzb_128B,"V64iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vdmpybus_dv,"V32iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_vdmpybus_dv_128B,"V64iV64ii","") -BUILTIN(__builtin_HEXAGON_V6_vaddbq,"V16iV16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vaddbq_128B,"V32iV32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vaddb,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vaddb_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vaddwq,"V16iV16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vaddwq_128B,"V32iV32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vasrhubrndsat,"V16iV16iV16ii","") -BUILTIN(__builtin_HEXAGON_V6_vasrhubrndsat_128B,"V32iV32iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_vasrhubsat,"V16iV16iV16ii","") -BUILTIN(__builtin_HEXAGON_V6_vasrhubsat_128B,"V32iV32iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_vshufoeb,"V32iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vshufoeb_128B,"V64iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vpackhub_sat,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vpackhub_sat_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vmpyiwh_acc,"V16iV16iV16ii","") -BUILTIN(__builtin_HEXAGON_V6_vmpyiwh_acc_128B,"V32iV32iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_vtmpyb,"V32iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_vtmpyb_128B,"V64iV64ii","") -BUILTIN(__builtin_HEXAGON_V6_vmpabusv,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vmpabusv_128B,"V64iV64iV64i","") -BUILTIN(__builtin_HEXAGON_V6_pred_and,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_pred_and_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vsubwnq,"V16iV16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vsubwnq_128B,"V32iV32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vpackwuh_sat,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vpackwuh_sat_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vswap,"V32iV16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vswap_128B,"V64iV32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vrmpyubv_acc,"V16iV16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vrmpyubv_acc_128B,"V32iV32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vgtb_and,"V16iV16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vgtb_and_128B,"V32iV32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vaslw,"V16iV16ii","") -BUILTIN(__builtin_HEXAGON_V6_vaslw_128B,"V32iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_vpackhb_sat,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vpackhb_sat_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vmpyih_acc,"V16iV16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vmpyih_acc_128B,"V32iV32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vshuffvdd,"V32iV16iV16ii","") -BUILTIN(__builtin_HEXAGON_V6_vshuffvdd_128B,"V64iV32iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_vaddb_dv,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vaddb_dv_128B,"V64iV64iV64i","") -BUILTIN(__builtin_HEXAGON_V6_vunpackub,"V32iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vunpackub_128B,"V64iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vgtuw,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vgtuw_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vlutvwh,"V32iV16iV16ii","") -BUILTIN(__builtin_HEXAGON_V6_vlutvwh_128B,"V64iV32iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_vgtub,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vgtub_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vmpyowh,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vmpyowh_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vmpyieoh,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vmpyieoh_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_extractw,"iV16ii","") -BUILTIN(__builtin_HEXAGON_V6_extractw_128B,"iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_vavgwrnd,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vavgwrnd_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vdmpyhsat_acc,"V16iV16iV16ii","") -BUILTIN(__builtin_HEXAGON_V6_vdmpyhsat_acc_128B,"V32iV32iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_vgtub_xor,"V16iV16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vgtub_xor_128B,"V32iV32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vmpyub,"V32iV16ii","") -BUILTIN(__builtin_HEXAGON_V6_vmpyub_128B,"V64iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_vmpyuh,"V32iV16ii","") -BUILTIN(__builtin_HEXAGON_V6_vmpyuh_128B,"V64iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_vunpackob,"V32iV32iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vunpackob_128B,"V64iV64iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vmpahb,"V32iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_vmpahb_128B,"V64iV64ii","") -BUILTIN(__builtin_HEXAGON_V6_veqw_or,"V16iV16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_veqw_or_128B,"V32iV32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vandqrt,"V16iV16ii","") -BUILTIN(__builtin_HEXAGON_V6_vandqrt_128B,"V32iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_vxor,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vxor_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vasrwhrndsat,"V16iV16iV16ii","") -BUILTIN(__builtin_HEXAGON_V6_vasrwhrndsat_128B,"V32iV32iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_vmpyhsat_acc,"V32iV32iV16ii","") -BUILTIN(__builtin_HEXAGON_V6_vmpyhsat_acc_128B,"V64iV64iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_vrmpybus_acc,"V16iV16iV16ii","") -BUILTIN(__builtin_HEXAGON_V6_vrmpybus_acc_128B,"V32iV32iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_vsubhw,"V32iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vsubhw_128B,"V64iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vdealb4w,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vdealb4w_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vmpyowh_sacc,"V16iV16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vmpyowh_sacc_128B,"V32iV32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vmpybv,"V32iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vmpybv_128B,"V64iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vabsdiffh,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vabsdiffh_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vshuffob,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vshuffob_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vmpyub_acc,"V32iV32iV16ii","") -BUILTIN(__builtin_HEXAGON_V6_vmpyub_acc_128B,"V64iV64iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_vnormamtw,"V16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vnormamtw_128B,"V32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vunpackuh,"V32iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vunpackuh_128B,"V64iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vgtuh_or,"V16iV16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vgtuh_or_128B,"V32iV32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vmpyiewuh_acc,"V16iV16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vmpyiewuh_acc_128B,"V32iV32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vunpackoh,"V32iV32iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vunpackoh_128B,"V64iV64iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vdmpyhsat,"V16iV16ii","") -BUILTIN(__builtin_HEXAGON_V6_vdmpyhsat_128B,"V32iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_vmpyubv,"V32iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vmpyubv_128B,"V64iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vmpyhss,"V16iV16ii","") -BUILTIN(__builtin_HEXAGON_V6_vmpyhss_128B,"V32iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_hi,"V16iV32i","") -BUILTIN(__builtin_HEXAGON_V6_hi_128B,"V32iV64i","") -BUILTIN(__builtin_HEXAGON_V6_vasrwuhsat,"V16iV16iV16ii","") -BUILTIN(__builtin_HEXAGON_V6_vasrwuhsat_128B,"V32iV32iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_veqw,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_veqw_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vdsaduh,"V32iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_vdsaduh_128B,"V64iV64ii","") -BUILTIN(__builtin_HEXAGON_V6_vsubw,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vsubw_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vsubw_dv,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vsubw_dv_128B,"V64iV64iV64i","") -BUILTIN(__builtin_HEXAGON_V6_veqb_and,"V16iV16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_veqb_and_128B,"V32iV32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vmpyih,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vmpyih_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vtmpyb_acc,"V32iV32iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_vtmpyb_acc_128B,"V64iV64iV64ii","") -BUILTIN(__builtin_HEXAGON_V6_vrmpybus,"V16iV16ii","") -BUILTIN(__builtin_HEXAGON_V6_vrmpybus_128B,"V32iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_vmpybus_acc,"V32iV32iV16ii","") -BUILTIN(__builtin_HEXAGON_V6_vmpybus_acc_128B,"V64iV64iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_vgth_xor,"V16iV16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vgth_xor_128B,"V32iV32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vsubhsat,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vsubhsat_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vrmpyubi_acc,"V32iV32iV32iiUIi","") -BUILTIN(__builtin_HEXAGON_V6_vrmpyubi_acc_128B,"V64iV64iV64iiUIi","") -BUILTIN(__builtin_HEXAGON_V6_vabsw,"V16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vabsw_128B,"V32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vaddwsat_dv,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vaddwsat_dv_128B,"V64iV64iV64i","") -BUILTIN(__builtin_HEXAGON_V6_vlsrw,"V16iV16ii","") -BUILTIN(__builtin_HEXAGON_V6_vlsrw_128B,"V32iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_vabsh,"V16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vabsh_128B,"V32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vlsrh,"V16iV16ii","") -BUILTIN(__builtin_HEXAGON_V6_vlsrh_128B,"V32iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_valignb,"V16iV16iV16ii","") -BUILTIN(__builtin_HEXAGON_V6_valignb_128B,"V32iV32iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_vsubhq,"V16iV16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vsubhq_128B,"V32iV32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vpackoh,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vpackoh_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vdmpybus_acc,"V16iV16iV16ii","") -BUILTIN(__builtin_HEXAGON_V6_vdmpybus_acc_128B,"V32iV32iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_vdmpyhvsat_acc,"V16iV16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vdmpyhvsat_acc_128B,"V32iV32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vrmpybv_acc,"V16iV16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vrmpybv_acc_128B,"V32iV32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vaddhsat,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vaddhsat_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vcombine,"V32iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vcombine_128B,"V64iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vandqrt_acc,"V16iV16iV16ii","") -BUILTIN(__builtin_HEXAGON_V6_vandqrt_acc_128B,"V32iV32iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_vaslhv,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vaslhv_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vinsertwr,"V16iV16ii","") -BUILTIN(__builtin_HEXAGON_V6_vinsertwr_128B,"V32iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_vsubh_dv,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vsubh_dv_128B,"V64iV64iV64i","") -BUILTIN(__builtin_HEXAGON_V6_vshuffb,"V16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vshuffb_128B,"V32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vand,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vand_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vmpyhv,"V32iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vmpyhv_128B,"V64iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vdmpyhsuisat_acc,"V16iV16iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_vdmpyhsuisat_acc_128B,"V32iV32iV64ii","") -BUILTIN(__builtin_HEXAGON_V6_vsububsat_dv,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vsububsat_dv_128B,"V64iV64iV64i","") -BUILTIN(__builtin_HEXAGON_V6_vgtb_xor,"V16iV16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vgtb_xor_128B,"V32iV32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vdsaduh_acc,"V32iV32iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_vdsaduh_acc_128B,"V64iV64iV64ii","") -BUILTIN(__builtin_HEXAGON_V6_vrmpyub,"V16iV16ii","") -BUILTIN(__builtin_HEXAGON_V6_vrmpyub_128B,"V32iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_vmpyuh_acc,"V32iV32iV16ii","") -BUILTIN(__builtin_HEXAGON_V6_vmpyuh_acc_128B,"V64iV64iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_vcl0h,"V16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vcl0h_128B,"V32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vmpyhus_acc,"V32iV32iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vmpyhus_acc_128B,"V64iV64iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vmpybv_acc,"V32iV32iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vmpybv_acc_128B,"V64iV64iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vrsadubi,"V32iV32iiUIi","") -BUILTIN(__builtin_HEXAGON_V6_vrsadubi_128B,"V64iV64iiUIi","") -BUILTIN(__builtin_HEXAGON_V6_vdmpyhb_dv_acc,"V32iV32iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_vdmpyhb_dv_acc_128B,"V64iV64iV64ii","") -BUILTIN(__builtin_HEXAGON_V6_vshufeh,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vshufeh_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vmpyewuh,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vmpyewuh_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vmpyhsrs,"V16iV16ii","") -BUILTIN(__builtin_HEXAGON_V6_vmpyhsrs_128B,"V32iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_vdmpybus_dv_acc,"V32iV32iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_vdmpybus_dv_acc_128B,"V64iV64iV64ii","") -BUILTIN(__builtin_HEXAGON_V6_vaddubh,"V32iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vaddubh_128B,"V64iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vasrwh,"V16iV16iV16ii","") -BUILTIN(__builtin_HEXAGON_V6_vasrwh_128B,"V32iV32iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_ld0,"V16ii","") -BUILTIN(__builtin_HEXAGON_V6_ld0_128B,"V32ii","") -BUILTIN(__builtin_HEXAGON_V6_vpopcounth,"V16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vpopcounth_128B,"V32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_ldnt0,"V16ii","") -BUILTIN(__builtin_HEXAGON_V6_ldnt0_128B,"V32ii","") -BUILTIN(__builtin_HEXAGON_V6_vgth_and,"V16iV16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vgth_and_128B,"V32iV32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vaddubsat_dv,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vaddubsat_dv_128B,"V64iV64iV64i","") -BUILTIN(__builtin_HEXAGON_V6_vpackeh,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vpackeh_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vmpyh,"V32iV16ii","") -BUILTIN(__builtin_HEXAGON_V6_vmpyh_128B,"V64iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_vminh,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vminh_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_pred_scalar2,"V16ii","") -BUILTIN(__builtin_HEXAGON_V6_pred_scalar2_128B,"V32ii","") -BUILTIN(__builtin_HEXAGON_V6_vdealh,"V16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vdealh_128B,"V32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vpackwh_sat,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vpackwh_sat_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vaslh,"V16iV16ii","") -BUILTIN(__builtin_HEXAGON_V6_vaslh_128B,"V32iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_vgtuw_and,"V16iV16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vgtuw_and_128B,"V32iV32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vor,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vor_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vlutvvb,"V16iV16iV16ii","") -BUILTIN(__builtin_HEXAGON_V6_vlutvvb_128B,"V32iV32iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_vmpyiowh,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vmpyiowh_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vlutvvb_oracc,"V16iV16iV16iV16ii","") -BUILTIN(__builtin_HEXAGON_V6_vlutvvb_oracc_128B,"V32iV32iV32iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_vandvrt,"V16iV16ii","") -BUILTIN(__builtin_HEXAGON_V6_vandvrt_128B,"V32iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_veqh_xor,"V16iV16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_veqh_xor_128B,"V32iV32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vadduhw,"V32iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vadduhw_128B,"V64iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vcl0w,"V16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vcl0w_128B,"V32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vmpyihb,"V16iV16ii","") -BUILTIN(__builtin_HEXAGON_V6_vmpyihb_128B,"V32iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_vtmpybus,"V32iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_vtmpybus_128B,"V64iV64ii","") -BUILTIN(__builtin_HEXAGON_V6_vd0,"V16i","") -BUILTIN(__builtin_HEXAGON_V6_vd0_128B,"V32i","") -BUILTIN(__builtin_HEXAGON_V6_veqh_or,"V16iV16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_veqh_or_128B,"V32iV32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vgtw_or,"V16iV16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vgtw_or_128B,"V32iV32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vdmpybus,"V16iV16ii","") -BUILTIN(__builtin_HEXAGON_V6_vdmpybus_128B,"V32iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_vgtub_or,"V16iV16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vgtub_or_128B,"V32iV32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vmpybus,"V32iV16ii","") -BUILTIN(__builtin_HEXAGON_V6_vmpybus_128B,"V64iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_vdmpyhb_acc,"V16iV16iV16ii","") -BUILTIN(__builtin_HEXAGON_V6_vdmpyhb_acc_128B,"V32iV32iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_vandvrt_acc,"V16iV16iV16ii","") -BUILTIN(__builtin_HEXAGON_V6_vandvrt_acc_128B,"V32iV32iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_vassign,"V16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vassign_128B,"V32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vaddwnq,"V16iV16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vaddwnq_128B,"V32iV32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vgtub_and,"V16iV16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vgtub_and_128B,"V32iV32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vdmpyhb_dv,"V32iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_vdmpyhb_dv_128B,"V64iV64ii","") -BUILTIN(__builtin_HEXAGON_V6_vunpackb,"V32iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vunpackb_128B,"V64iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vunpackh,"V32iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vunpackh_128B,"V64iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vmpahb_acc,"V32iV32iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_vmpahb_acc_128B,"V64iV64iV64ii","") -BUILTIN(__builtin_HEXAGON_V6_vaddbnq,"V16iV16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vaddbnq_128B,"V32iV32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vlalignbi,"V16iV16iV16iUIi","") -BUILTIN(__builtin_HEXAGON_V6_vlalignbi_128B,"V32iV32iV32iUIi","") -BUILTIN(__builtin_HEXAGON_V6_vsatwh,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vsatwh_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vgtuh,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vgtuh_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vmpyihb_acc,"V16iV16iV16ii","") -BUILTIN(__builtin_HEXAGON_V6_vmpyihb_acc_128B,"V32iV32iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_vrmpybusv_acc,"V16iV16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vrmpybusv_acc_128B,"V32iV32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vrdelta,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vrdelta_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vroundwh,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vroundwh_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vaddw_dv,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vaddw_dv_128B,"V64iV64iV64i","") -BUILTIN(__builtin_HEXAGON_V6_vmpyiwb_acc,"V16iV16iV16ii","") -BUILTIN(__builtin_HEXAGON_V6_vmpyiwb_acc_128B,"V32iV32iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_vsubbq,"V16iV16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vsubbq_128B,"V32iV32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_veqh_and,"V16iV16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_veqh_and_128B,"V32iV32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_valignbi,"V16iV16iV16iUIi","") -BUILTIN(__builtin_HEXAGON_V6_valignbi_128B,"V32iV32iV32iUIi","") -BUILTIN(__builtin_HEXAGON_V6_vaddwsat,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vaddwsat_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_veqw_and,"V16iV16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_veqw_and_128B,"V32iV32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vabsdiffub,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vabsdiffub_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vshuffeb,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vshuffeb_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vabsdiffuh,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vabsdiffuh_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_veqw_xor,"V16iV16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_veqw_xor_128B,"V32iV32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vgth,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vgth_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vgtuw_xor,"V16iV16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vgtuw_xor_128B,"V32iV32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vgtb,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vgtb_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vgtw,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vgtw_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vsubwq,"V16iV16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vsubwq_128B,"V32iV32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vnot,"V16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vnot_128B,"V32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vgtb_or,"V16iV16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vgtb_or_128B,"V32iV32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vgtuw_or,"V16iV16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vgtuw_or_128B,"V32iV32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vaddubsat,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vaddubsat_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vmaxw,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vmaxw_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vaslwv,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vaslwv_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vabsw_sat,"V16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vabsw_sat_128B,"V32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vsubwsat_dv,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vsubwsat_dv_128B,"V64iV64iV64i","") -BUILTIN(__builtin_HEXAGON_V6_vroundhub,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vroundhub_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vdmpyhisat_acc,"V16iV16iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_vdmpyhisat_acc_128B,"V32iV32iV64ii","") -BUILTIN(__builtin_HEXAGON_V6_vmpabus,"V32iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_vmpabus_128B,"V64iV64ii","") -BUILTIN(__builtin_HEXAGON_V6_vassignp,"V32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vassignp_128B,"V64iV64i","") -BUILTIN(__builtin_HEXAGON_V6_veqb,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_veqb_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vsububh,"V32iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vsububh_128B,"V64iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_lvsplatw,"V16ii","") -BUILTIN(__builtin_HEXAGON_V6_lvsplatw_128B,"V32ii","") -BUILTIN(__builtin_HEXAGON_V6_vaddhnq,"V16iV16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vaddhnq_128B,"V32iV32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vdmpyhsusat,"V16iV16ii","") -BUILTIN(__builtin_HEXAGON_V6_vdmpyhsusat_128B,"V32iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_pred_not,"V16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_pred_not_128B,"V32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vlutvwh_oracc,"V32iV32iV16iV16ii","") -BUILTIN(__builtin_HEXAGON_V6_vlutvwh_oracc_128B,"V64iV64iV32iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_vmpyiewh_acc,"V16iV16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vmpyiewh_acc_128B,"V32iV32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vdealvdd,"V32iV16iV16ii","") -BUILTIN(__builtin_HEXAGON_V6_vdealvdd_128B,"V64iV32iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_vavgw,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vavgw_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vdmpyhsusat_acc,"V16iV16iV16ii","") -BUILTIN(__builtin_HEXAGON_V6_vdmpyhsusat_acc_128B,"V32iV32iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_vgtw_xor,"V16iV16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vgtw_xor_128B,"V32iV32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vtmpyhb_acc,"V32iV32iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_vtmpyhb_acc_128B,"V64iV64iV64ii","") -BUILTIN(__builtin_HEXAGON_V6_vaddhw,"V32iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vaddhw_128B,"V64iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vaddhq,"V16iV16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vaddhq_128B,"V32iV32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vrmpyubv,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vrmpyubv_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vsubh,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vsubh_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vrmpyubi,"V32iV32iiUIi","") -BUILTIN(__builtin_HEXAGON_V6_vrmpyubi_128B,"V64iV64iiUIi","") -BUILTIN(__builtin_HEXAGON_V6_vminw,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vminw_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vmpyubv_acc,"V32iV32iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vmpyubv_acc_128B,"V64iV64iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_pred_xor,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_pred_xor_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_veqb_xor,"V16iV16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_veqb_xor_128B,"V32iV32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vmpyiewuh,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vmpyiewuh_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vmpybusv_acc,"V32iV32iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vmpybusv_acc_128B,"V64iV64iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vavguhrnd,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vavguhrnd_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vmpyowh_rnd,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vmpyowh_rnd_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vsubwsat,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vsubwsat_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vsubuhw,"V32iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vsubuhw_128B,"V64iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vrmpybusi_acc,"V32iV32iV32iiUIi","") -BUILTIN(__builtin_HEXAGON_V6_vrmpybusi_acc_128B,"V64iV64iV64iiUIi","") -BUILTIN(__builtin_HEXAGON_V6_vasrw,"V16iV16ii","") -BUILTIN(__builtin_HEXAGON_V6_vasrw_128B,"V32iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_vasrh,"V16iV16ii","") -BUILTIN(__builtin_HEXAGON_V6_vasrh_128B,"V32iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_vmpyuhv,"V32iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vmpyuhv_128B,"V64iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vasrhbrndsat,"V16iV16iV16ii","") -BUILTIN(__builtin_HEXAGON_V6_vasrhbrndsat_128B,"V32iV32iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_vsubuhsat_dv,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vsubuhsat_dv_128B,"V64iV64iV64i","") -BUILTIN(__builtin_HEXAGON_V6_vabsdiffw,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vabsdiffw_128B,"V32iV32iV32i","") - -// V62 HVX Instructions. - -BUILTIN(__builtin_HEXAGON_V6_vandnqrt_acc,"V16iV16iV16ii","") -BUILTIN(__builtin_HEXAGON_V6_vandnqrt_acc_128B,"V32iV32iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_vaddclbh,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vaddclbh_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vmpyowh_64_acc,"V32iV32iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vmpyowh_64_acc_128B,"V64iV64iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vmpyewuh_64,"V32iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vmpyewuh_64_128B,"V64iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vsatuwuh,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vsatuwuh_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_shuffeqh,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_shuffeqh_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_shuffeqw,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_shuffeqw_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_ldcnpnt0,"V16iii","") -BUILTIN(__builtin_HEXAGON_V6_ldcnpnt0_128B,"V32iii","") -BUILTIN(__builtin_HEXAGON_V6_vsubcarry,"V16iV16iV16iv*","") -BUILTIN(__builtin_HEXAGON_V6_vsubcarry_128B,"V32iV32iV32iv*","") -BUILTIN(__builtin_HEXAGON_V6_vasrhbsat,"V16iV16iV16ii","") -BUILTIN(__builtin_HEXAGON_V6_vasrhbsat_128B,"V32iV32iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_vminb,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vminb_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vmpauhb_acc,"V32iV32iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_vmpauhb_acc_128B,"V64iV64iV64ii","") -BUILTIN(__builtin_HEXAGON_V6_vaddhw_acc,"V32iV32iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vaddhw_acc_128B,"V64iV64iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vlsrb,"V16iV16ii","") -BUILTIN(__builtin_HEXAGON_V6_vlsrb_128B,"V32iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_vlutvwhi,"V32iV16iV16iUIi","") -BUILTIN(__builtin_HEXAGON_V6_vlutvwhi_128B,"V64iV32iV32iUIi","") -BUILTIN(__builtin_HEXAGON_V6_vaddububb_sat,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vaddububb_sat_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vsubbsat_dv,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vsubbsat_dv_128B,"V64iV64iV64i","") -BUILTIN(__builtin_HEXAGON_V6_ldtp0,"V16iii","") -BUILTIN(__builtin_HEXAGON_V6_ldtp0_128B,"V32iii","") -BUILTIN(__builtin_HEXAGON_V6_vlutvvb_oracci,"V16iV16iV16iV16iUIi","") -BUILTIN(__builtin_HEXAGON_V6_vlutvvb_oracci_128B,"V32iV32iV32iV32iUIi","") -BUILTIN(__builtin_HEXAGON_V6_vsubuwsat_dv,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vsubuwsat_dv_128B,"V64iV64iV64i","") -BUILTIN(__builtin_HEXAGON_V6_ldpnt0,"V16iii","") -BUILTIN(__builtin_HEXAGON_V6_ldpnt0_128B,"V32iii","") -BUILTIN(__builtin_HEXAGON_V6_vandvnqv,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vandvnqv_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_lvsplatb,"V16ii","") -BUILTIN(__builtin_HEXAGON_V6_lvsplatb_128B,"V32ii","") -BUILTIN(__builtin_HEXAGON_V6_lvsplath,"V16ii","") -BUILTIN(__builtin_HEXAGON_V6_lvsplath_128B,"V32ii","") -BUILTIN(__builtin_HEXAGON_V6_ldtpnt0,"V16iii","") -BUILTIN(__builtin_HEXAGON_V6_ldtpnt0_128B,"V32iii","") -BUILTIN(__builtin_HEXAGON_V6_vlutvwh_nm,"V32iV16iV16ii","") -BUILTIN(__builtin_HEXAGON_V6_vlutvwh_nm_128B,"V64iV32iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_ldnpnt0,"V16iii","") -BUILTIN(__builtin_HEXAGON_V6_ldnpnt0_128B,"V32iii","") -BUILTIN(__builtin_HEXAGON_V6_vmpauhb,"V32iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_vmpauhb_128B,"V64iV64ii","") -BUILTIN(__builtin_HEXAGON_V6_ldtnp0,"V16iii","") -BUILTIN(__builtin_HEXAGON_V6_ldtnp0_128B,"V32iii","") -BUILTIN(__builtin_HEXAGON_V6_vrounduhub,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vrounduhub_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vadduhw_acc,"V32iV32iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vadduhw_acc_128B,"V64iV64iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_ldcp0,"V16iii","") -BUILTIN(__builtin_HEXAGON_V6_ldcp0_128B,"V32iii","") -BUILTIN(__builtin_HEXAGON_V6_vadduwsat,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vadduwsat_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_ldtnpnt0,"V16iii","") -BUILTIN(__builtin_HEXAGON_V6_ldtnpnt0_128B,"V32iii","") -BUILTIN(__builtin_HEXAGON_V6_vaddbsat,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vaddbsat_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vandnqrt,"V16iV16ii","") -BUILTIN(__builtin_HEXAGON_V6_vandnqrt_128B,"V32iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_vmpyiwub_acc,"V16iV16iV16ii","") -BUILTIN(__builtin_HEXAGON_V6_vmpyiwub_acc_128B,"V32iV32iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_vmaxb,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vmaxb_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vandvqv,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vandvqv_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vaddcarry,"V16iV16iV16iv*","") -BUILTIN(__builtin_HEXAGON_V6_vaddcarry_128B,"V32iV32iV32iv*","") -BUILTIN(__builtin_HEXAGON_V6_vasrwuhrndsat,"V16iV16iV16ii","") -BUILTIN(__builtin_HEXAGON_V6_vasrwuhrndsat_128B,"V32iV32iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_vlutvvbi,"V16iV16iV16iUIi","") -BUILTIN(__builtin_HEXAGON_V6_vlutvvbi_128B,"V32iV32iV32iUIi","") -BUILTIN(__builtin_HEXAGON_V6_vsubuwsat,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vsubuwsat_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vaddbsat_dv,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vaddbsat_dv_128B,"V64iV64iV64i","") -BUILTIN(__builtin_HEXAGON_V6_ldnp0,"V16iii","") -BUILTIN(__builtin_HEXAGON_V6_ldnp0_128B,"V32iii","") -BUILTIN(__builtin_HEXAGON_V6_vasruwuhrndsat,"V16iV16iV16ii","") -BUILTIN(__builtin_HEXAGON_V6_vasruwuhrndsat_128B,"V32iV32iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_vrounduwuh,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vrounduwuh_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vlutvvb_nm,"V16iV16iV16ii","") -BUILTIN(__builtin_HEXAGON_V6_vlutvvb_nm_128B,"V32iV32iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_pred_scalar2v2,"V16ii","") -BUILTIN(__builtin_HEXAGON_V6_pred_scalar2v2_128B,"V32ii","") -BUILTIN(__builtin_HEXAGON_V6_ldp0,"V16iii","") -BUILTIN(__builtin_HEXAGON_V6_ldp0_128B,"V32iii","") -BUILTIN(__builtin_HEXAGON_V6_vaddubh_acc,"V32iV32iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vaddubh_acc_128B,"V64iV64iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vaddclbw,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vaddclbw_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_ldcpnt0,"V16iii","") -BUILTIN(__builtin_HEXAGON_V6_ldcpnt0_128B,"V32iii","") -BUILTIN(__builtin_HEXAGON_V6_vadduwsat_dv,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vadduwsat_dv_128B,"V64iV64iV64i","") -BUILTIN(__builtin_HEXAGON_V6_vmpyiwub,"V16iV16ii","") -BUILTIN(__builtin_HEXAGON_V6_vmpyiwub_128B,"V32iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_vsubububb_sat,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vsubububb_sat_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_ldcnp0,"V16iii","") -BUILTIN(__builtin_HEXAGON_V6_ldcnp0_128B,"V32iii","") -BUILTIN(__builtin_HEXAGON_V6_vlutvwh_oracci,"V32iV32iV16iV16iUIi","") -BUILTIN(__builtin_HEXAGON_V6_vlutvwh_oracci_128B,"V64iV64iV32iV32iUIi","") -BUILTIN(__builtin_HEXAGON_V6_vsubbsat,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vsubbsat_128B,"V32iV32iV32i","") - -// V65 HVX Instructions. - -BUILTIN(__builtin_HEXAGON_V6_vasruhubrndsat,"V16iV16iV16ii","") -BUILTIN(__builtin_HEXAGON_V6_vasruhubrndsat_128B,"V32iV32iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_vrmpybub_rtt,"V32iV16iLLi","") -BUILTIN(__builtin_HEXAGON_V6_vrmpybub_rtt_128B,"V64iV32iLLi","") -BUILTIN(__builtin_HEXAGON_V6_vmpahhsat,"V16iV16iV16iLLi","") -BUILTIN(__builtin_HEXAGON_V6_vmpahhsat_128B,"V32iV32iV32iLLi","") -BUILTIN(__builtin_HEXAGON_V6_vavguwrnd,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vavguwrnd_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vnavgb,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vnavgb_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vasrh_acc,"V16iV16iV16ii","") -BUILTIN(__builtin_HEXAGON_V6_vasrh_acc_128B,"V32iV32iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_vmpauhuhsat,"V16iV16iV16iLLi","") -BUILTIN(__builtin_HEXAGON_V6_vmpauhuhsat_128B,"V32iV32iV32iLLi","") -BUILTIN(__builtin_HEXAGON_V6_vmpyh_acc,"V32iV32iV16ii","") -BUILTIN(__builtin_HEXAGON_V6_vmpyh_acc_128B,"V64iV64iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_vrmpybub_rtt_acc,"V32iV32iV16iLLi","") -BUILTIN(__builtin_HEXAGON_V6_vrmpybub_rtt_acc_128B,"V64iV64iV32iLLi","") -BUILTIN(__builtin_HEXAGON_V6_vavgb,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vavgb_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vaslh_acc,"V16iV16iV16ii","") -BUILTIN(__builtin_HEXAGON_V6_vaslh_acc_128B,"V32iV32iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_vavguw,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vavguw_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vlut4,"V16iV16iLLi","") -BUILTIN(__builtin_HEXAGON_V6_vlut4_128B,"V32iV32iLLi","") -BUILTIN(__builtin_HEXAGON_V6_vmpyuhe_acc,"V16iV16iV16ii","") -BUILTIN(__builtin_HEXAGON_V6_vmpyuhe_acc_128B,"V32iV32iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_vrmpyub_rtt,"V32iV16iLLi","") -BUILTIN(__builtin_HEXAGON_V6_vrmpyub_rtt_128B,"V64iV32iLLi","") -BUILTIN(__builtin_HEXAGON_V6_vmpsuhuhsat,"V16iV16iV16iLLi","") -BUILTIN(__builtin_HEXAGON_V6_vmpsuhuhsat_128B,"V32iV32iV32iLLi","") -BUILTIN(__builtin_HEXAGON_V6_vasruhubsat,"V16iV16iV16ii","") -BUILTIN(__builtin_HEXAGON_V6_vasruhubsat_128B,"V32iV32iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_vmpyuhe,"V16iV16ii","") -BUILTIN(__builtin_HEXAGON_V6_vmpyuhe_128B,"V32iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_vrmpyub_rtt_acc,"V32iV32iV16iLLi","") -BUILTIN(__builtin_HEXAGON_V6_vrmpyub_rtt_acc_128B,"V64iV64iV32iLLi","") -BUILTIN(__builtin_HEXAGON_V6_vasruwuhsat,"V16iV16iV16ii","") -BUILTIN(__builtin_HEXAGON_V6_vasruwuhsat_128B,"V32iV32iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_vmpabuu_acc,"V32iV32iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_vmpabuu_acc_128B,"V64iV64iV64ii","") -BUILTIN(__builtin_HEXAGON_V6_vprefixqw,"V16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vprefixqw_128B,"V32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vprefixqh,"V16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vprefixqh_128B,"V32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vprefixqb,"V16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vprefixqb_128B,"V32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vabsb,"V16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vabsb_128B,"V32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vavgbrnd,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vavgbrnd_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vdd0,"V32i","") -BUILTIN(__builtin_HEXAGON_V6_vdd0_128B,"V64i","") -BUILTIN(__builtin_HEXAGON_V6_vmpabuu,"V32iV32ii","") -BUILTIN(__builtin_HEXAGON_V6_vmpabuu_128B,"V64iV64ii","") -BUILTIN(__builtin_HEXAGON_V6_vabsb_sat,"V16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vabsb_sat_128B,"V32iV32i","") - -// V66 HVX Instructions. - -BUILTIN(__builtin_HEXAGON_V6_vaddcarrysat,"V16iV16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vaddcarrysat_128B,"V32iV32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vasr_into,"V32iV32iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vasr_into_128B,"V64iV64iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vsatdw,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vsatdw_128B,"V32iV32iV32i","") -BUILTIN(__builtin_HEXAGON_V6_vrotr,"V16iV16iV16i","") -BUILTIN(__builtin_HEXAGON_V6_vrotr_128B,"V32iV32iV32i","") +// The builtins below are not autogenerated from iset.py. +// Make sure you do not overwrite these. +TARGET_BUILTIN(__builtin_SI_to_SXTHI_asrh, "ii", "", V5) +TARGET_BUILTIN(__builtin_brev_ldd, "v*LLi*CLLi*iC", "", V5) +TARGET_BUILTIN(__builtin_brev_ldw, "v*i*Ci*iC", "", V5) +TARGET_BUILTIN(__builtin_brev_ldh, "v*s*Cs*iC", "", V5) +TARGET_BUILTIN(__builtin_brev_lduh, "v*Us*CUs*iC", "", V5) +TARGET_BUILTIN(__builtin_brev_ldb, "v*Sc*CSc*iC", "", V5) +TARGET_BUILTIN(__builtin_brev_ldub, "v*Uc*CUc*iC", "", V5) +TARGET_BUILTIN(__builtin_circ_ldd, "LLi*LLi*LLi*iIi", "", V5) +TARGET_BUILTIN(__builtin_circ_ldw, "i*i*i*iIi", "", V5) +TARGET_BUILTIN(__builtin_circ_ldh, "s*s*s*iIi", "", V5) +TARGET_BUILTIN(__builtin_circ_lduh, "Us*Us*Us*iIi", "", V5) +TARGET_BUILTIN(__builtin_circ_ldb, "c*c*c*iIi", "", V5) +TARGET_BUILTIN(__builtin_circ_ldub, "Uc*Uc*Uc*iIi", "", V5) +TARGET_BUILTIN(__builtin_brev_std, "LLi*CLLi*LLiiC", "", V5) +TARGET_BUILTIN(__builtin_brev_stw, "i*Ci*iiC", "", V5) +TARGET_BUILTIN(__builtin_brev_sth, "s*Cs*iiC", "", V5) +TARGET_BUILTIN(__builtin_brev_sthhi, "s*Cs*iiC", "", V5) +TARGET_BUILTIN(__builtin_brev_stb, "c*Cc*iiC", "", V5) +TARGET_BUILTIN(__builtin_circ_std, "LLi*LLi*LLiiIi", "", V5) +TARGET_BUILTIN(__builtin_circ_stw, "i*i*iiIi", "", V5) +TARGET_BUILTIN(__builtin_circ_sth, "s*s*iiIi", "", V5) +TARGET_BUILTIN(__builtin_circ_sthhi, "s*s*iiIi", "", V5) +TARGET_BUILTIN(__builtin_circ_stb, "c*c*iiIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_L2_loadrub_pci, "iv*IiivC*", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_L2_loadrb_pci, "iv*IiivC*", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_L2_loadruh_pci, "iv*IiivC*", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_L2_loadrh_pci, "iv*IiivC*", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_L2_loadri_pci, "iv*IiivC*", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_L2_loadrd_pci, "LLiv*IiivC*", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_L2_loadrub_pcr, "iv*ivC*", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_L2_loadrb_pcr, "iv*ivC*", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_L2_loadruh_pcr, "iv*ivC*", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_L2_loadrh_pcr, "iv*ivC*", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_L2_loadri_pcr, "iv*ivC*", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_L2_loadrd_pcr, "LLiv*ivC*", "", V5) + +TARGET_BUILTIN(__builtin_HEXAGON_S2_storerb_pci, "vv*IiiivC*", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_storerh_pci, "vv*IiiivC*", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_storerf_pci, "vv*IiiivC*", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_storeri_pci, "vv*IiiivC*", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_storerd_pci, "vv*IiiLLivC*", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_storerb_pcr, "vv*iivC*", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_storerh_pcr, "vv*iivC*", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_storerf_pcr, "vv*iivC*", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_storeri_pcr, "vv*iivC*", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_storerd_pcr, "vv*iLLivC*", "", V5) + +TARGET_BUILTIN(__builtin_HEXAGON_prefetch,"vv*","", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A6_vminub_RdP,"LLiLLiLLi","", V62) + +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmaskedstoreq,"vV64bv*V16i","", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmaskedstorenq,"vV64bv*V16i","", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmaskedstorentq,"vV64bv*V16i","", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmaskedstorentnq,"vV64bv*V16i","", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmaskedstoreq_128B,"vV128bv*V32i","", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmaskedstorenq_128B,"vV128bv*V32i","", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmaskedstorentq_128B,"vV128bv*V32i","", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmaskedstorentnq_128B,"vV128bv*V32i","", HVXV60) + + +// These are only valid on v65 +TARGET_BUILTIN(__builtin_HEXAGON_V6_vrmpybub_rtt,"V32iV16iLLi","", "hvxv65") +TARGET_BUILTIN(__builtin_HEXAGON_V6_vrmpybub_rtt_128B,"V64iV32iLLi","", "hvxv65") +TARGET_BUILTIN(__builtin_HEXAGON_V6_vrmpybub_rtt_acc,"V32iV32iV16iLLi","", "hvxv65") +TARGET_BUILTIN(__builtin_HEXAGON_V6_vrmpybub_rtt_acc_128B,"V64iV64iV32iLLi","", "hvxv65") +TARGET_BUILTIN(__builtin_HEXAGON_V6_vrmpyub_rtt,"V32iV16iLLi","", "hvxv65") +TARGET_BUILTIN(__builtin_HEXAGON_V6_vrmpyub_rtt_128B,"V64iV32iLLi","", "hvxv65") +TARGET_BUILTIN(__builtin_HEXAGON_V6_vrmpyub_rtt_acc,"V32iV32iV16iLLi","", "hvxv65") +TARGET_BUILTIN(__builtin_HEXAGON_V6_vrmpyub_rtt_acc_128B,"V64iV64iV32iLLi","", "hvxv65") + +#include "clang/Basic/BuiltinsHexagonDep.def" + +#pragma pop_macro("HVXV60") +#pragma pop_macro("HVXV62") +#pragma pop_macro("HVXV65") +#pragma pop_macro("HVXV66") +#pragma pop_macro("HVXV67") + +#pragma pop_macro("V5") +#pragma pop_macro("V55") +#pragma pop_macro("V60") +#pragma pop_macro("V62") +#pragma pop_macro("V65") +#pragma pop_macro("V66") +#pragma pop_macro("V67") #undef BUILTIN +#undef TARGET_BUILTIN + diff --git a/clang/include/clang/Basic/BuiltinsHexagonDep.def b/clang/include/clang/Basic/BuiltinsHexagonDep.def new file mode 100644 index 000000000000..b694e4c35d3b --- /dev/null +++ b/clang/include/clang/Basic/BuiltinsHexagonDep.def @@ -0,0 +1,1721 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// Automatically generated file, do not edit! +//===----------------------------------------------------------------------===// + + +// V5 Scalar Instructions. + +TARGET_BUILTIN(__builtin_HEXAGON_C2_cmpeq, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_C2_cmpgt, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_C2_cmpgtu, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_C2_cmpeqp, "iLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_C2_cmpgtp, "iLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_C2_cmpgtup, "iLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A4_rcmpeqi, "iiIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A4_rcmpneqi, "iiIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A4_rcmpeq, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A4_rcmpneq, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_C2_bitsset, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_C2_bitsclr, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_C4_nbitsset, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_C4_nbitsclr, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_C2_cmpeqi, "iiIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_C2_cmpgti, "iiIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_C2_cmpgtui, "iiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_C2_cmpgei, "iiIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_C2_cmpgeui, "iiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_C2_cmplt, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_C2_cmpltu, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_C2_bitsclri, "iiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_C4_nbitsclri, "iiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_C4_cmpneqi, "iiIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_C4_cmpltei, "iiIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_C4_cmplteui, "iiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_C4_cmpneq, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_C4_cmplte, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_C4_cmplteu, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_C2_and, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_C2_or, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_C2_xor, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_C2_andn, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_C2_not, "ii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_C2_orn, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_C4_and_and, "iiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_C4_and_or, "iiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_C4_or_and, "iiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_C4_or_or, "iiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_C4_and_andn, "iiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_C4_and_orn, "iiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_C4_or_andn, "iiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_C4_or_orn, "iiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_C2_pxfer_map, "ii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_C2_any8, "ii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_C2_all8, "ii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_C2_vitpack, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_C2_mux, "iiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_C2_muxii, "iiIiIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_C2_muxir, "iiiIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_C2_muxri, "iiIii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_C2_vmux, "LLiiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_C2_mask, "LLii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_vcmpbeq, "iLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A4_vcmpbeqi, "iLLiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A4_vcmpbeq_any, "iLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_vcmpbgtu, "iLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A4_vcmpbgtui, "iLLiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A4_vcmpbgt, "iLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A4_vcmpbgti, "iLLiIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A4_cmpbeq, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A4_cmpbeqi, "iiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A4_cmpbgtu, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A4_cmpbgtui, "iiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A4_cmpbgt, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A4_cmpbgti, "iiIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_vcmpheq, "iLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_vcmphgt, "iLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_vcmphgtu, "iLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A4_vcmpheqi, "iLLiIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A4_vcmphgti, "iLLiIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A4_vcmphgtui, "iLLiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A4_cmpheq, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A4_cmphgt, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A4_cmphgtu, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A4_cmpheqi, "iiIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A4_cmphgti, "iiIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A4_cmphgtui, "iiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_vcmpweq, "iLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_vcmpwgt, "iLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_vcmpwgtu, "iLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A4_vcmpweqi, "iLLiIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A4_vcmpwgti, "iLLiIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A4_vcmpwgtui, "iLLiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A4_boundscheck, "iiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A4_tlbmatch, "iLLii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_C2_tfrpr, "ii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_C2_tfrrp, "ii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_C4_fastcorner9, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_C4_fastcorner9_not, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_acc_hh_s0, "iiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_acc_hh_s1, "iiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_acc_hl_s0, "iiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_acc_hl_s1, "iiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_acc_lh_s0, "iiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_acc_lh_s1, "iiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_acc_ll_s0, "iiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_acc_ll_s1, "iiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_nac_hh_s0, "iiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_nac_hh_s1, "iiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_nac_hl_s0, "iiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_nac_hl_s1, "iiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_nac_lh_s0, "iiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_nac_lh_s1, "iiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_nac_ll_s0, "iiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_nac_ll_s1, "iiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_acc_sat_hh_s0, "iiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_acc_sat_hh_s1, "iiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_acc_sat_hl_s0, "iiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_acc_sat_hl_s1, "iiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_acc_sat_lh_s0, "iiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_acc_sat_lh_s1, "iiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_acc_sat_ll_s0, "iiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_acc_sat_ll_s1, "iiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_nac_sat_hh_s0, "iiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_nac_sat_hh_s1, "iiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_nac_sat_hl_s0, "iiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_nac_sat_hl_s1, "iiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_nac_sat_lh_s0, "iiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_nac_sat_lh_s1, "iiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_nac_sat_ll_s0, "iiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_nac_sat_ll_s1, "iiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_hh_s0, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_hh_s1, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_hl_s0, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_hl_s1, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_lh_s0, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_lh_s1, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_ll_s0, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_ll_s1, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_sat_hh_s0, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_sat_hh_s1, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_sat_hl_s0, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_sat_hl_s1, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_sat_lh_s0, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_sat_lh_s1, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_sat_ll_s0, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_sat_ll_s1, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_rnd_hh_s0, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_rnd_hh_s1, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_rnd_hl_s0, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_rnd_hl_s1, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_rnd_lh_s0, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_rnd_lh_s1, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_rnd_ll_s0, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_rnd_ll_s1, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_sat_rnd_hh_s0, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_sat_rnd_hh_s1, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_sat_rnd_hl_s0, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_sat_rnd_hl_s1, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_sat_rnd_lh_s0, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_sat_rnd_lh_s1, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_sat_rnd_ll_s0, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_sat_rnd_ll_s1, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyd_acc_hh_s0, "LLiLLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyd_acc_hh_s1, "LLiLLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyd_acc_hl_s0, "LLiLLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyd_acc_hl_s1, "LLiLLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyd_acc_lh_s0, "LLiLLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyd_acc_lh_s1, "LLiLLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyd_acc_ll_s0, "LLiLLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyd_acc_ll_s1, "LLiLLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyd_nac_hh_s0, "LLiLLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyd_nac_hh_s1, "LLiLLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyd_nac_hl_s0, "LLiLLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyd_nac_hl_s1, "LLiLLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyd_nac_lh_s0, "LLiLLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyd_nac_lh_s1, "LLiLLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyd_nac_ll_s0, "LLiLLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyd_nac_ll_s1, "LLiLLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyd_hh_s0, "LLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyd_hh_s1, "LLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyd_hl_s0, "LLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyd_hl_s1, "LLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyd_lh_s0, "LLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyd_lh_s1, "LLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyd_ll_s0, "LLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyd_ll_s1, "LLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyd_rnd_hh_s0, "LLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyd_rnd_hh_s1, "LLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyd_rnd_hl_s0, "LLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyd_rnd_hl_s1, "LLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyd_rnd_lh_s0, "LLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyd_rnd_lh_s1, "LLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyd_rnd_ll_s0, "LLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyd_rnd_ll_s1, "LLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyu_acc_hh_s0, "iiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyu_acc_hh_s1, "iiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyu_acc_hl_s0, "iiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyu_acc_hl_s1, "iiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyu_acc_lh_s0, "iiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyu_acc_lh_s1, "iiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyu_acc_ll_s0, "iiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyu_acc_ll_s1, "iiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyu_nac_hh_s0, "iiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyu_nac_hh_s1, "iiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyu_nac_hl_s0, "iiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyu_nac_hl_s1, "iiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyu_nac_lh_s0, "iiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyu_nac_lh_s1, "iiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyu_nac_ll_s0, "iiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyu_nac_ll_s1, "iiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyu_hh_s0, "Uiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyu_hh_s1, "Uiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyu_hl_s0, "Uiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyu_hl_s1, "Uiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyu_lh_s0, "Uiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyu_lh_s1, "Uiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyu_ll_s0, "Uiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyu_ll_s1, "Uiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyud_acc_hh_s0, "LLiLLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyud_acc_hh_s1, "LLiLLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyud_acc_hl_s0, "LLiLLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyud_acc_hl_s1, "LLiLLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyud_acc_lh_s0, "LLiLLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyud_acc_lh_s1, "LLiLLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyud_acc_ll_s0, "LLiLLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyud_acc_ll_s1, "LLiLLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyud_nac_hh_s0, "LLiLLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyud_nac_hh_s1, "LLiLLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyud_nac_hl_s0, "LLiLLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyud_nac_hl_s1, "LLiLLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyud_nac_lh_s0, "LLiLLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyud_nac_lh_s1, "LLiLLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyud_nac_ll_s0, "LLiLLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyud_nac_ll_s1, "LLiLLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyud_hh_s0, "ULLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyud_hh_s1, "ULLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyud_hl_s0, "ULLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyud_hl_s1, "ULLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyud_lh_s0, "ULLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyud_lh_s1, "ULLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyud_ll_s0, "ULLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyud_ll_s1, "ULLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpysmi, "iiIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_macsip, "iiiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_macsin, "iiiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_dpmpyss_s0, "LLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_dpmpyss_acc_s0, "LLiLLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_dpmpyss_nac_s0, "LLiLLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_dpmpyuu_s0, "ULLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_dpmpyuu_acc_s0, "LLiLLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_dpmpyuu_nac_s0, "LLiLLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_up, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_up_s1, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpy_up_s1_sat, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyu_up, "Uiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpysu_up, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_dpmpyss_rnd_s0, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M4_mac_up_s1_sat, "iiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M4_nac_up_s1_sat, "iiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyi, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mpyui, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_maci, "iiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_acci, "iiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_accii, "iiiIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_nacci, "iiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_naccii, "iiiIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_subacc, "iiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M4_mpyrr_addr, "iiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M4_mpyri_addr_u2, "iiUIii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M4_mpyri_addr, "iiiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M4_mpyri_addi, "iUIiiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M4_mpyrr_addi, "iUIiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_vmpy2s_s0, "LLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_vmpy2s_s1, "LLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_vmac2s_s0, "LLiLLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_vmac2s_s1, "LLiLLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_vmpy2su_s0, "LLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_vmpy2su_s1, "LLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_vmac2su_s0, "LLiLLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_vmac2su_s1, "LLiLLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_vmpy2s_s0pack, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_vmpy2s_s1pack, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_vmac2, "LLiLLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_vmpy2es_s0, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_vmpy2es_s1, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_vmac2es_s0, "LLiLLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_vmac2es_s1, "LLiLLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_vmac2es, "LLiLLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_vrmac_s0, "LLiLLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_vrmpy_s0, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_vdmpyrs_s0, "iLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_vdmpyrs_s1, "iLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M5_vrmpybuu, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M5_vrmacbuu, "LLiLLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M5_vrmpybsu, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M5_vrmacbsu, "LLiLLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M5_vmpybuu, "LLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M5_vmpybsu, "LLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M5_vmacbuu, "LLiLLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M5_vmacbsu, "LLiLLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M5_vdmpybsu, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M5_vdmacbsu, "LLiLLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_vdmacs_s0, "LLiLLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_vdmacs_s1, "LLiLLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_vdmpys_s0, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_vdmpys_s1, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_cmpyrs_s0, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_cmpyrs_s1, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_cmpyrsc_s0, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_cmpyrsc_s1, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_cmacs_s0, "LLiLLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_cmacs_s1, "LLiLLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_cmacsc_s0, "LLiLLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_cmacsc_s1, "LLiLLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_cmpys_s0, "LLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_cmpys_s1, "LLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_cmpysc_s0, "LLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_cmpysc_s1, "LLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_cnacs_s0, "LLiLLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_cnacs_s1, "LLiLLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_cnacsc_s0, "LLiLLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_cnacsc_s1, "LLiLLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_vrcmpys_s1, "LLiLLii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_vrcmpys_acc_s1, "LLiLLiLLii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_vrcmpys_s1rp, "iLLii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mmacls_s0, "LLiLLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mmacls_s1, "LLiLLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mmachs_s0, "LLiLLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mmachs_s1, "LLiLLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mmpyl_s0, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mmpyl_s1, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mmpyh_s0, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mmpyh_s1, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mmacls_rs0, "LLiLLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mmacls_rs1, "LLiLLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mmachs_rs0, "LLiLLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mmachs_rs1, "LLiLLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mmpyl_rs0, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mmpyl_rs1, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mmpyh_rs0, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mmpyh_rs1, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M4_vrmpyeh_s0, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M4_vrmpyeh_s1, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M4_vrmpyeh_acc_s0, "LLiLLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M4_vrmpyeh_acc_s1, "LLiLLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M4_vrmpyoh_s0, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M4_vrmpyoh_s1, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M4_vrmpyoh_acc_s0, "LLiLLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M4_vrmpyoh_acc_s1, "LLiLLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_hmmpyl_rs1, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_hmmpyh_rs1, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_hmmpyl_s1, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_hmmpyh_s1, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mmaculs_s0, "LLiLLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mmaculs_s1, "LLiLLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mmacuhs_s0, "LLiLLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mmacuhs_s1, "LLiLLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mmpyul_s0, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mmpyul_s1, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mmpyuh_s0, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mmpyuh_s1, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mmaculs_rs0, "LLiLLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mmaculs_rs1, "LLiLLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mmacuhs_rs0, "LLiLLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mmacuhs_rs1, "LLiLLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mmpyul_rs0, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mmpyul_rs1, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mmpyuh_rs0, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_mmpyuh_rs1, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_vrcmaci_s0, "LLiLLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_vrcmacr_s0, "LLiLLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_vrcmaci_s0c, "LLiLLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_vrcmacr_s0c, "LLiLLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_cmaci_s0, "LLiLLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_cmacr_s0, "LLiLLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_vrcmpyi_s0, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_vrcmpyr_s0, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_vrcmpyi_s0c, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_vrcmpyr_s0c, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_cmpyi_s0, "LLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_cmpyr_s0, "LLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M4_cmpyi_wh, "iLLii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M4_cmpyr_wh, "iLLii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M4_cmpyi_whc, "iLLii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M4_cmpyr_whc, "iLLii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_vcmpy_s0_sat_i, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_vcmpy_s0_sat_r, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_vcmpy_s1_sat_i, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_vcmpy_s1_sat_r, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_vcmac_s0_sat_i, "LLiLLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_vcmac_s0_sat_r, "LLiLLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_vcrotate, "LLiLLii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S4_vrcrotate_acc, "LLiLLiLLiiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S4_vrcrotate, "LLiLLiiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_vcnegh, "LLiLLii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_vrcnegh, "LLiLLiLLii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M4_pmpyw, "LLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M4_vpmpyh, "LLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M4_pmpyw_acc, "LLiLLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M4_vpmpyh_acc, "LLiLLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_add, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_sub, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_addsat, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_subsat, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_addi, "iiIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_addh_l16_ll, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_addh_l16_hl, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_addh_l16_sat_ll, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_addh_l16_sat_hl, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_subh_l16_ll, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_subh_l16_hl, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_subh_l16_sat_ll, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_subh_l16_sat_hl, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_addh_h16_ll, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_addh_h16_lh, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_addh_h16_hl, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_addh_h16_hh, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_addh_h16_sat_ll, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_addh_h16_sat_lh, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_addh_h16_sat_hl, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_addh_h16_sat_hh, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_subh_h16_ll, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_subh_h16_lh, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_subh_h16_hl, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_subh_h16_hh, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_subh_h16_sat_ll, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_subh_h16_sat_lh, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_subh_h16_sat_hl, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_subh_h16_sat_hh, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_aslh, "ii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_asrh, "ii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_addp, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_addpsat, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_addsp, "LLiiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_subp, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_neg, "ii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_negsat, "ii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_abs, "ii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_abssat, "ii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_vconj, "LLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_negp, "LLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_absp, "LLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_max, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_maxu, "Uiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_min, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_minu, "Uiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_maxp, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_maxup, "ULLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_minp, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_minup, "ULLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_tfr, "ii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_tfrsi, "iIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_tfrp, "LLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_tfrpi, "LLiIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_zxtb, "ii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_sxtb, "ii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_zxth, "ii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_sxth, "ii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_combinew, "LLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A4_combineri, "LLiiIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A4_combineir, "LLiIii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_combineii, "LLiIiIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_combine_hh, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_combine_hl, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_combine_lh, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_combine_ll, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_tfril, "iiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_tfrih, "iiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_and, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_or, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_xor, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_not, "ii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_xor_xacc, "iiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M4_xor_xacc, "LLiLLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A4_andn, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A4_orn, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A4_andnp, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A4_ornp, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S4_addaddi, "iiiIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S4_subaddi, "iiIii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M4_and_and, "iiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M4_and_andn, "iiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M4_and_or, "iiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M4_and_xor, "iiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M4_or_and, "iiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M4_or_andn, "iiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M4_or_or, "iiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M4_or_xor, "iiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S4_or_andix, "iiiIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S4_or_andi, "iiiIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S4_or_ori, "iiiIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M4_xor_and, "iiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M4_xor_or, "iiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M4_xor_andn, "iiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_subri, "iIii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_andir, "iiIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_orir, "iiIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_andp, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_orp, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_xorp, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_notp, "LLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_sxtw, "LLii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_sat, "iLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_roundsat, "iLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_sath, "ii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_satuh, "ii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_satub, "ii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_satb, "ii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_vaddub, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_vaddb_map, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_vaddubs, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_vaddh, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_vaddhs, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_vadduhs, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A5_vaddhubs, "iLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_vaddw, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_vaddws, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S4_vxaddsubw, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S4_vxsubaddw, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S4_vxaddsubh, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S4_vxsubaddh, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S4_vxaddsubhr, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S4_vxsubaddhr, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_svavgh, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_svavghs, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_svnavgh, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_svaddh, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_svaddhs, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_svadduhs, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_svsubh, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_svsubhs, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_svsubuhs, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_vraddub, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_vraddub_acc, "LLiLLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_vraddh, "iLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_vradduh, "iLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_vsubub, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_vsubb_map, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_vsububs, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_vsubh, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_vsubhs, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_vsubuhs, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_vsubw, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_vsubws, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_vabsh, "LLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_vabshsat, "LLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_vabsw, "LLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_vabswsat, "LLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_vabsdiffw, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_M2_vabsdiffh, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_vrsadub, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_vrsadub_acc, "LLiLLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_vavgub, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_vavguh, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_vavgh, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_vnavgh, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_vavgw, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_vnavgw, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_vavgwr, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_vnavgwr, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_vavgwcr, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_vnavgwcr, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_vavghcr, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_vnavghcr, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_vavguw, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_vavguwr, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_vavgubr, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_vavguhr, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_vavghr, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_vnavghr, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A4_round_ri, "iiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A4_round_rr, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A4_round_ri_sat, "iiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A4_round_rr_sat, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A4_cround_ri, "iiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A4_cround_rr, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A4_vrminh, "LLiLLiLLii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A4_vrmaxh, "LLiLLiLLii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A4_vrminuh, "LLiLLiLLii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A4_vrmaxuh, "LLiLLiLLii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A4_vrminw, "LLiLLiLLii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A4_vrmaxw, "LLiLLiLLii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A4_vrminuw, "LLiLLiLLii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A4_vrmaxuw, "LLiLLiLLii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_vminb, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_vmaxb, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_vminub, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_vmaxub, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_vminh, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_vmaxh, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_vminuh, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_vmaxuh, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_vminw, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_vmaxw, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_vminuw, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_vmaxuw, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A4_modwrapu, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_F2_sfadd, "fff", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_F2_sfsub, "fff", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_F2_sfmpy, "fff", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_F2_sffma, "ffff", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_F2_sffma_sc, "ffffi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_F2_sffms, "ffff", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_F2_sffma_lib, "ffff", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_F2_sffms_lib, "ffff", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_F2_sfcmpeq, "iff", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_F2_sfcmpgt, "iff", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_F2_sfcmpge, "iff", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_F2_sfcmpuo, "iff", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_F2_sfmax, "fff", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_F2_sfmin, "fff", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_F2_sfclass, "ifUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_F2_sfimm_p, "fUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_F2_sfimm_n, "fUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_F2_sffixupn, "fff", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_F2_sffixupd, "fff", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_F2_sffixupr, "ff", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_F2_dfcmpeq, "idd", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_F2_dfcmpgt, "idd", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_F2_dfcmpge, "idd", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_F2_dfcmpuo, "idd", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_F2_dfclass, "idUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_F2_dfimm_p, "dUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_F2_dfimm_n, "dUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_F2_conv_sf2df, "df", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_F2_conv_df2sf, "fd", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_F2_conv_uw2sf, "fi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_F2_conv_uw2df, "di", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_F2_conv_w2sf, "fi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_F2_conv_w2df, "di", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_F2_conv_ud2sf, "fLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_F2_conv_ud2df, "dLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_F2_conv_d2sf, "fLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_F2_conv_d2df, "dLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_F2_conv_sf2uw, "if", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_F2_conv_sf2w, "if", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_F2_conv_sf2ud, "LLif", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_F2_conv_sf2d, "LLif", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_F2_conv_df2uw, "id", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_F2_conv_df2w, "id", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_F2_conv_df2ud, "LLid", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_F2_conv_df2d, "LLid", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_F2_conv_sf2uw_chop, "if", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_F2_conv_sf2w_chop, "if", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_F2_conv_sf2ud_chop, "LLif", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_F2_conv_sf2d_chop, "LLif", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_F2_conv_df2uw_chop, "id", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_F2_conv_df2w_chop, "id", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_F2_conv_df2ud_chop, "LLid", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_F2_conv_df2d_chop, "LLid", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_asr_r_r, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_asl_r_r, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_lsr_r_r, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_lsl_r_r, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_asr_r_p, "LLiLLii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_asl_r_p, "LLiLLii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_lsr_r_p, "LLiLLii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_lsl_r_p, "LLiLLii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_asr_r_r_acc, "iiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_asl_r_r_acc, "iiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_lsr_r_r_acc, "iiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_lsl_r_r_acc, "iiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_asr_r_p_acc, "LLiLLiLLii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_asl_r_p_acc, "LLiLLiLLii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_lsr_r_p_acc, "LLiLLiLLii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_lsl_r_p_acc, "LLiLLiLLii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_asr_r_r_nac, "iiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_asl_r_r_nac, "iiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_lsr_r_r_nac, "iiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_lsl_r_r_nac, "iiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_asr_r_p_nac, "LLiLLiLLii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_asl_r_p_nac, "LLiLLiLLii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_lsr_r_p_nac, "LLiLLiLLii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_lsl_r_p_nac, "LLiLLiLLii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_asr_r_r_and, "iiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_asl_r_r_and, "iiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_lsr_r_r_and, "iiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_lsl_r_r_and, "iiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_asr_r_r_or, "iiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_asl_r_r_or, "iiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_lsr_r_r_or, "iiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_lsl_r_r_or, "iiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_asr_r_p_and, "LLiLLiLLii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_asl_r_p_and, "LLiLLiLLii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_lsr_r_p_and, "LLiLLiLLii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_lsl_r_p_and, "LLiLLiLLii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_asr_r_p_or, "LLiLLiLLii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_asl_r_p_or, "LLiLLiLLii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_lsr_r_p_or, "LLiLLiLLii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_lsl_r_p_or, "LLiLLiLLii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_asr_r_p_xor, "LLiLLiLLii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_asl_r_p_xor, "LLiLLiLLii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_lsr_r_p_xor, "LLiLLiLLii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_lsl_r_p_xor, "LLiLLiLLii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_asr_r_r_sat, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_asl_r_r_sat, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_asr_i_r, "iiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_lsr_i_r, "iiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_asl_i_r, "iiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_asr_i_p, "LLiLLiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_lsr_i_p, "LLiLLiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_asl_i_p, "LLiLLiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_asr_i_r_acc, "iiiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_lsr_i_r_acc, "iiiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_asl_i_r_acc, "iiiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_asr_i_p_acc, "LLiLLiLLiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_lsr_i_p_acc, "LLiLLiLLiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_asl_i_p_acc, "LLiLLiLLiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_asr_i_r_nac, "iiiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_lsr_i_r_nac, "iiiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_asl_i_r_nac, "iiiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_asr_i_p_nac, "LLiLLiLLiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_lsr_i_p_nac, "LLiLLiLLiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_asl_i_p_nac, "LLiLLiLLiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_lsr_i_r_xacc, "iiiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_asl_i_r_xacc, "iiiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_lsr_i_p_xacc, "LLiLLiLLiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_asl_i_p_xacc, "LLiLLiLLiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_asr_i_r_and, "iiiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_lsr_i_r_and, "iiiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_asl_i_r_and, "iiiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_asr_i_r_or, "iiiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_lsr_i_r_or, "iiiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_asl_i_r_or, "iiiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_asr_i_p_and, "LLiLLiLLiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_lsr_i_p_and, "LLiLLiLLiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_asl_i_p_and, "LLiLLiLLiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_asr_i_p_or, "LLiLLiLLiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_lsr_i_p_or, "LLiLLiLLiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_asl_i_p_or, "LLiLLiLLiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_asl_i_r_sat, "iiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_asr_i_r_rnd, "iiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_asr_i_r_rnd_goodsyntax, "iiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_asr_i_p_rnd, "LLiLLiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_asr_i_p_rnd_goodsyntax, "LLiLLiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S4_lsli, "iIii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_addasl_rrri, "iiiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S4_andi_asl_ri, "iUIiiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S4_ori_asl_ri, "iUIiiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S4_addi_asl_ri, "iUIiiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S4_subi_asl_ri, "iUIiiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S4_andi_lsr_ri, "iUIiiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S4_ori_lsr_ri, "iUIiiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S4_addi_lsr_ri, "iUIiiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S4_subi_lsr_ri, "iUIiiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_valignib, "LLiLLiLLiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_valignrb, "LLiLLiLLii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_vspliceib, "LLiLLiLLiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_vsplicerb, "LLiLLiLLii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_vsplatrh, "LLii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_vsplatrb, "ii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_insert, "iiiUIiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_tableidxb_goodsyntax, "iiiUIiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_tableidxh_goodsyntax, "iiiUIiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_tableidxw_goodsyntax, "iiiUIiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_tableidxd_goodsyntax, "iiiUIiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A4_bitspliti, "LLiiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A4_bitsplit, "LLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S4_extract, "iiUIiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_extractu, "iiUIiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_insertp, "LLiLLiLLiUIiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S4_extractp, "LLiLLiUIiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_extractup, "LLiLLiUIiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_insert_rp, "iiiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S4_extract_rp, "iiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_extractu_rp, "iiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_insertp_rp, "LLiLLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S4_extractp_rp, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_extractup_rp, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_tstbit_i, "iiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S4_ntstbit_i, "iiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_setbit_i, "iiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_togglebit_i, "iiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_clrbit_i, "iiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_tstbit_r, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S4_ntstbit_r, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_setbit_r, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_togglebit_r, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_clrbit_r, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_asr_i_vh, "LLiLLiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_lsr_i_vh, "LLiLLiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_asl_i_vh, "LLiLLiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_asr_r_vh, "LLiLLii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S5_asrhub_rnd_sat_goodsyntax, "iLLiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S5_asrhub_sat, "iLLiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S5_vasrhrnd_goodsyntax, "LLiLLiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_asl_r_vh, "LLiLLii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_lsr_r_vh, "LLiLLii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_lsl_r_vh, "LLiLLii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_asr_i_vw, "LLiLLiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_asr_i_svw_trun, "iLLiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_asr_r_svw_trun, "iLLii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_lsr_i_vw, "LLiLLiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_asl_i_vw, "LLiLLiUIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_asr_r_vw, "LLiLLii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_asl_r_vw, "LLiLLii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_lsr_r_vw, "LLiLLii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_lsl_r_vw, "LLiLLii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_vrndpackwh, "iLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_vrndpackwhs, "iLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_vsxtbh, "LLii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_vzxtbh, "LLii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_vsathub, "iLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_svsathub, "ii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_svsathb, "ii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_vsathb, "iLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_vtrunohb, "iLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_vtrunewh, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_vtrunowh, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_vtrunehb, "iLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_vsxthw, "LLii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_vzxthw, "LLii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_vsatwh, "iLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_vsatwuh, "iLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_packhl, "LLiii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_A2_swiz, "ii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_vsathub_nopack, "LLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_vsathb_nopack, "LLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_vsatwh_nopack, "LLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_vsatwuh_nopack, "LLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_shuffob, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_shuffeb, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_shuffoh, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_shuffeh, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S5_popcountp, "iLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S4_parity, "iii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_parityp, "iLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_lfsp, "LLiLLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_clbnorm, "ii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S4_clbaddi, "iiIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S4_clbpnorm, "iLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S4_clbpaddi, "iLLiIi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_clb, "ii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_cl0, "ii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_cl1, "ii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_clbp, "iLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_cl0p, "iLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_cl1p, "iLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_brev, "ii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_brevp, "LLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_ct0, "ii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_ct1, "ii", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_ct0p, "iLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_ct1p, "iLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_interleave, "LLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_S2_deinterleave, "LLiLLi", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_Y2_dcfetch, "vv*", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_Y2_dczeroa, "vv*", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_Y2_dccleana, "vv*", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_Y2_dccleaninva, "vv*", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_Y2_dcinva, "vv*", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_Y4_l2fetch, "vv*i", "", V5) +TARGET_BUILTIN(__builtin_HEXAGON_Y5_l2fetch, "vv*LLi", "", V5) + +// V60 Scalar Instructions. + +TARGET_BUILTIN(__builtin_HEXAGON_S6_rol_i_r, "iiUIi", "", V60) +TARGET_BUILTIN(__builtin_HEXAGON_S6_rol_i_p, "LLiLLiUIi", "", V60) +TARGET_BUILTIN(__builtin_HEXAGON_S6_rol_i_r_acc, "iiiUIi", "", V60) +TARGET_BUILTIN(__builtin_HEXAGON_S6_rol_i_p_acc, "LLiLLiLLiUIi", "", V60) +TARGET_BUILTIN(__builtin_HEXAGON_S6_rol_i_r_nac, "iiiUIi", "", V60) +TARGET_BUILTIN(__builtin_HEXAGON_S6_rol_i_p_nac, "LLiLLiLLiUIi", "", V60) +TARGET_BUILTIN(__builtin_HEXAGON_S6_rol_i_r_xacc, "iiiUIi", "", V60) +TARGET_BUILTIN(__builtin_HEXAGON_S6_rol_i_p_xacc, "LLiLLiLLiUIi", "", V60) +TARGET_BUILTIN(__builtin_HEXAGON_S6_rol_i_r_and, "iiiUIi", "", V60) +TARGET_BUILTIN(__builtin_HEXAGON_S6_rol_i_r_or, "iiiUIi", "", V60) +TARGET_BUILTIN(__builtin_HEXAGON_S6_rol_i_p_and, "LLiLLiLLiUIi", "", V60) +TARGET_BUILTIN(__builtin_HEXAGON_S6_rol_i_p_or, "LLiLLiLLiUIi", "", V60) + +// V62 Scalar Instructions. + +TARGET_BUILTIN(__builtin_HEXAGON_M6_vabsdiffb, "LLiLLiLLi", "", V62) +TARGET_BUILTIN(__builtin_HEXAGON_M6_vabsdiffub, "LLiLLiLLi", "", V62) +TARGET_BUILTIN(__builtin_HEXAGON_S6_vsplatrbp, "LLii", "", V62) +TARGET_BUILTIN(__builtin_HEXAGON_S6_vtrunehb_ppp, "LLiLLiLLi", "", V62) +TARGET_BUILTIN(__builtin_HEXAGON_S6_vtrunohb_ppp, "LLiLLiLLi", "", V62) + +// V65 Scalar Instructions. + +TARGET_BUILTIN(__builtin_HEXAGON_A6_vcmpbeq_notany, "iLLiLLi", "", V65) + +// V66 Scalar Instructions. + +TARGET_BUILTIN(__builtin_HEXAGON_M2_mnaci, "iiii", "", V66) +TARGET_BUILTIN(__builtin_HEXAGON_F2_dfadd, "ddd", "", V66) +TARGET_BUILTIN(__builtin_HEXAGON_F2_dfsub, "ddd", "", V66) +TARGET_BUILTIN(__builtin_HEXAGON_S2_mask, "iUIiUIi", "", V66) + +// V67 Scalar Instructions. + +TARGET_BUILTIN(__builtin_HEXAGON_M7_dcmpyrw, "LLiLLiLLi", "", "audio") +TARGET_BUILTIN(__builtin_HEXAGON_M7_dcmpyrw_acc, "LLiLLiLLiLLi", "", "audio") +TARGET_BUILTIN(__builtin_HEXAGON_M7_dcmpyrwc, "LLiLLiLLi", "", "audio") +TARGET_BUILTIN(__builtin_HEXAGON_M7_dcmpyrwc_acc, "LLiLLiLLiLLi", "", "audio") +TARGET_BUILTIN(__builtin_HEXAGON_M7_dcmpyiw, "LLiLLiLLi", "", "audio") +TARGET_BUILTIN(__builtin_HEXAGON_M7_dcmpyiw_acc, "LLiLLiLLiLLi", "", "audio") +TARGET_BUILTIN(__builtin_HEXAGON_M7_dcmpyiwc, "LLiLLiLLi", "", "audio") +TARGET_BUILTIN(__builtin_HEXAGON_M7_dcmpyiwc_acc, "LLiLLiLLiLLi", "", "audio") +TARGET_BUILTIN(__builtin_HEXAGON_M7_vdmpy, "LLiLLiLLi", "", V67) +TARGET_BUILTIN(__builtin_HEXAGON_M7_vdmpy_acc, "LLiLLiLLiLLi", "", V67) +TARGET_BUILTIN(__builtin_HEXAGON_M7_wcmpyrw, "iLLiLLi", "", "audio") +TARGET_BUILTIN(__builtin_HEXAGON_M7_wcmpyrwc, "iLLiLLi", "", "audio") +TARGET_BUILTIN(__builtin_HEXAGON_M7_wcmpyiw, "iLLiLLi", "", "audio") +TARGET_BUILTIN(__builtin_HEXAGON_M7_wcmpyiwc, "iLLiLLi", "", "audio") +TARGET_BUILTIN(__builtin_HEXAGON_M7_wcmpyrw_rnd, "iLLiLLi", "", "audio") +TARGET_BUILTIN(__builtin_HEXAGON_M7_wcmpyrwc_rnd, "iLLiLLi", "", "audio") +TARGET_BUILTIN(__builtin_HEXAGON_M7_wcmpyiw_rnd, "iLLiLLi", "", "audio") +TARGET_BUILTIN(__builtin_HEXAGON_M7_wcmpyiwc_rnd, "iLLiLLi", "", "audio") +TARGET_BUILTIN(__builtin_HEXAGON_A7_croundd_ri, "LLiLLiUIi", "", "audio") +TARGET_BUILTIN(__builtin_HEXAGON_A7_croundd_rr, "LLiLLii", "", "audio") +TARGET_BUILTIN(__builtin_HEXAGON_A7_clip, "iiUIi", "", "audio") +TARGET_BUILTIN(__builtin_HEXAGON_A7_vclip, "LLiLLiUIi", "", "audio") +TARGET_BUILTIN(__builtin_HEXAGON_F2_dfmax, "ddd", "", V67) +TARGET_BUILTIN(__builtin_HEXAGON_F2_dfmin, "ddd", "", V67) +TARGET_BUILTIN(__builtin_HEXAGON_F2_dfmpyfix, "ddd", "", V67) +TARGET_BUILTIN(__builtin_HEXAGON_F2_dfmpyll, "ddd", "", V67) +TARGET_BUILTIN(__builtin_HEXAGON_F2_dfmpylh, "dddd", "", V67) +TARGET_BUILTIN(__builtin_HEXAGON_F2_dfmpyhh, "dddd", "", V67) + +// V60 HVX Instructions. + +TARGET_BUILTIN(__builtin_HEXAGON_V6_vS32b_qpred_ai, "vV64bv*V16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vS32b_qpred_ai_128B, "vV128bv*V32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vS32b_nqpred_ai, "vV64bv*V16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vS32b_nqpred_ai_128B, "vV128bv*V32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vS32b_nt_qpred_ai, "vV64bv*V16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vS32b_nt_qpred_ai_128B, "vV128bv*V32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vS32b_nt_nqpred_ai, "vV64bv*V16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vS32b_nt_nqpred_ai_128B, "vV128bv*V32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_valignb, "V16iV16iV16ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_valignb_128B, "V32iV32iV32ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vlalignb, "V16iV16iV16ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vlalignb_128B, "V32iV32iV32ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_valignbi, "V16iV16iV16iUIi", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_valignbi_128B, "V32iV32iV32iUIi", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vlalignbi, "V16iV16iV16iUIi", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vlalignbi_128B, "V32iV32iV32iUIi", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vror, "V16iV16ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vror_128B, "V32iV32ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vunpackub, "V32iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vunpackub_128B, "V64iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vunpackb, "V32iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vunpackb_128B, "V64iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vunpackuh, "V32iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vunpackuh_128B, "V64iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vunpackh, "V32iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vunpackh_128B, "V64iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vunpackob, "V32iV32iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vunpackob_128B, "V64iV64iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vunpackoh, "V32iV32iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vunpackoh_128B, "V64iV64iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vpackeb, "V16iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vpackeb_128B, "V32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vpackeh, "V16iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vpackeh_128B, "V32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vpackob, "V16iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vpackob_128B, "V32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vpackoh, "V16iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vpackoh_128B, "V32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vpackhub_sat, "V16iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vpackhub_sat_128B, "V32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vpackhb_sat, "V16iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vpackhb_sat_128B, "V32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vpackwuh_sat, "V16iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vpackwuh_sat_128B, "V32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vpackwh_sat, "V16iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vpackwh_sat_128B, "V32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vzb, "V32iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vzb_128B, "V64iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vsb, "V32iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vsb_128B, "V64iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vzh, "V32iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vzh_128B, "V64iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vsh, "V32iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vsh_128B, "V64iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vdmpybus, "V16iV16ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vdmpybus_128B, "V32iV32ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vdmpybus_acc, "V16iV16iV16ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vdmpybus_acc_128B, "V32iV32iV32ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vdmpybus_dv, "V32iV32ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vdmpybus_dv_128B, "V64iV64ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vdmpybus_dv_acc, "V32iV32iV32ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vdmpybus_dv_acc_128B, "V64iV64iV64ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vdmpyhb, "V16iV16ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vdmpyhb_128B, "V32iV32ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vdmpyhb_acc, "V16iV16iV16ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vdmpyhb_acc_128B, "V32iV32iV32ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vdmpyhb_dv, "V32iV32ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vdmpyhb_dv_128B, "V64iV64ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vdmpyhb_dv_acc, "V32iV32iV32ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vdmpyhb_dv_acc_128B, "V64iV64iV64ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vdmpyhvsat, "V16iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vdmpyhvsat_128B, "V32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vdmpyhvsat_acc, "V16iV16iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vdmpyhvsat_acc_128B, "V32iV32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vdmpyhsat, "V16iV16ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vdmpyhsat_128B, "V32iV32ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vdmpyhsat_acc, "V16iV16iV16ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vdmpyhsat_acc_128B, "V32iV32iV32ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vdmpyhisat, "V16iV32ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vdmpyhisat_128B, "V32iV64ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vdmpyhisat_acc, "V16iV16iV32ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vdmpyhisat_acc_128B, "V32iV32iV64ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vdmpyhsusat, "V16iV16ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vdmpyhsusat_128B, "V32iV32ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vdmpyhsusat_acc, "V16iV16iV16ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vdmpyhsusat_acc_128B, "V32iV32iV32ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vdmpyhsuisat, "V16iV32ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vdmpyhsuisat_128B, "V32iV64ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vdmpyhsuisat_acc, "V16iV16iV32ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vdmpyhsuisat_acc_128B, "V32iV32iV64ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vtmpyb, "V32iV32ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vtmpyb_128B, "V64iV64ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vtmpyb_acc, "V32iV32iV32ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vtmpyb_acc_128B, "V64iV64iV64ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vtmpybus, "V32iV32ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vtmpybus_128B, "V64iV64ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vtmpybus_acc, "V32iV32iV32ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vtmpybus_acc_128B, "V64iV64iV64ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vtmpyhb, "V32iV32ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vtmpyhb_128B, "V64iV64ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vtmpyhb_acc, "V32iV32iV32ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vtmpyhb_acc_128B, "V64iV64iV64ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vrmpyub, "V16iV16ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vrmpyub_128B, "V32iV32ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vrmpyub_acc, "V16iV16iV16ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vrmpyub_acc_128B, "V32iV32iV32ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vrmpyubv, "V16iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vrmpyubv_128B, "V32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vrmpyubv_acc, "V16iV16iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vrmpyubv_acc_128B, "V32iV32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vrmpybv, "V16iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vrmpybv_128B, "V32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vrmpybv_acc, "V16iV16iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vrmpybv_acc_128B, "V32iV32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vrmpyubi, "V32iV32iiUIi", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vrmpyubi_128B, "V64iV64iiUIi", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vrmpyubi_acc, "V32iV32iV32iiUIi", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vrmpyubi_acc_128B, "V64iV64iV64iiUIi", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vrmpybus, "V16iV16ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vrmpybus_128B, "V32iV32ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vrmpybus_acc, "V16iV16iV16ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vrmpybus_acc_128B, "V32iV32iV32ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vrmpybusi, "V32iV32iiUIi", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vrmpybusi_128B, "V64iV64iiUIi", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vrmpybusi_acc, "V32iV32iV32iiUIi", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vrmpybusi_acc_128B, "V64iV64iV64iiUIi", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vrmpybusv, "V16iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vrmpybusv_128B, "V32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vrmpybusv_acc, "V16iV16iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vrmpybusv_acc_128B, "V32iV32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vdsaduh, "V32iV32ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vdsaduh_128B, "V64iV64ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vdsaduh_acc, "V32iV32iV32ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vdsaduh_acc_128B, "V64iV64iV64ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vrsadubi, "V32iV32iiUIi", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vrsadubi_128B, "V64iV64iiUIi", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vrsadubi_acc, "V32iV32iV32iiUIi", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vrsadubi_acc_128B, "V64iV64iV64iiUIi", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vasrw, "V16iV16ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vasrw_128B, "V32iV32ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vaslw, "V16iV16ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vaslw_128B, "V32iV32ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vlsrw, "V16iV16ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vlsrw_128B, "V32iV32ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vasrwv, "V16iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vasrwv_128B, "V32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vaslwv, "V16iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vaslwv_128B, "V32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vlsrwv, "V16iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vlsrwv_128B, "V32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vasrh, "V16iV16ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vasrh_128B, "V32iV32ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vaslh, "V16iV16ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vaslh_128B, "V32iV32ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vlsrh, "V16iV16ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vlsrh_128B, "V32iV32ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vasrhv, "V16iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vasrhv_128B, "V32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vaslhv, "V16iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vaslhv_128B, "V32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vlsrhv, "V16iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vlsrhv_128B, "V32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vasrwh, "V16iV16iV16ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vasrwh_128B, "V32iV32iV32ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vasrwhsat, "V16iV16iV16ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vasrwhsat_128B, "V32iV32iV32ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vasrwhrndsat, "V16iV16iV16ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vasrwhrndsat_128B, "V32iV32iV32ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vasrwuhsat, "V16iV16iV16ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vasrwuhsat_128B, "V32iV32iV32ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vroundwh, "V16iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vroundwh_128B, "V32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vroundwuh, "V16iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vroundwuh_128B, "V32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vasrhubsat, "V16iV16iV16ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vasrhubsat_128B, "V32iV32iV32ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vasrhubrndsat, "V16iV16iV16ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vasrhubrndsat_128B, "V32iV32iV32ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vasrhbrndsat, "V16iV16iV16ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vasrhbrndsat_128B, "V32iV32iV32ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vroundhb, "V16iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vroundhb_128B, "V32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vroundhub, "V16iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vroundhub_128B, "V32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vaslw_acc, "V16iV16iV16ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vaslw_acc_128B, "V32iV32iV32ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vasrw_acc, "V16iV16iV16ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vasrw_acc_128B, "V32iV32iV32ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddb, "V16iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddb_128B, "V32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubb, "V16iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubb_128B, "V32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddb_dv, "V32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddb_dv_128B, "V64iV64iV64i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubb_dv, "V32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubb_dv_128B, "V64iV64iV64i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddh, "V16iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddh_128B, "V32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubh, "V16iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubh_128B, "V32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddh_dv, "V32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddh_dv_128B, "V64iV64iV64i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubh_dv, "V32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubh_dv_128B, "V64iV64iV64i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddw, "V16iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddw_128B, "V32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubw, "V16iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubw_128B, "V32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddw_dv, "V32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddw_dv_128B, "V64iV64iV64i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubw_dv, "V32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubw_dv_128B, "V64iV64iV64i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddubsat, "V16iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddubsat_128B, "V32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddubsat_dv, "V32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddubsat_dv_128B, "V64iV64iV64i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vsububsat, "V16iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vsububsat_128B, "V32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vsububsat_dv, "V32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vsububsat_dv_128B, "V64iV64iV64i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vadduhsat, "V16iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vadduhsat_128B, "V32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vadduhsat_dv, "V32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vadduhsat_dv_128B, "V64iV64iV64i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubuhsat, "V16iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubuhsat_128B, "V32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubuhsat_dv, "V32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubuhsat_dv_128B, "V64iV64iV64i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddhsat, "V16iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddhsat_128B, "V32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddhsat_dv, "V32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddhsat_dv_128B, "V64iV64iV64i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubhsat, "V16iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubhsat_128B, "V32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubhsat_dv, "V32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubhsat_dv_128B, "V64iV64iV64i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddwsat, "V16iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddwsat_128B, "V32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddwsat_dv, "V32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddwsat_dv_128B, "V64iV64iV64i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubwsat, "V16iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubwsat_128B, "V32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubwsat_dv, "V32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubwsat_dv_128B, "V64iV64iV64i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vavgub, "V16iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vavgub_128B, "V32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vavgubrnd, "V16iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vavgubrnd_128B, "V32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vavguh, "V16iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vavguh_128B, "V32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vavguhrnd, "V16iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vavguhrnd_128B, "V32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vavgh, "V16iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vavgh_128B, "V32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vavghrnd, "V16iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vavghrnd_128B, "V32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vnavgh, "V16iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vnavgh_128B, "V32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vavgw, "V16iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vavgw_128B, "V32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vavgwrnd, "V16iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vavgwrnd_128B, "V32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vnavgw, "V16iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vnavgw_128B, "V32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vabsdiffub, "V16iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vabsdiffub_128B, "V32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vabsdiffuh, "V16iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vabsdiffuh_128B, "V32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vabsdiffh, "V16iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vabsdiffh_128B, "V32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vabsdiffw, "V16iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vabsdiffw_128B, "V32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vnavgub, "V16iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vnavgub_128B, "V32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddubh, "V32iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddubh_128B, "V64iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vsububh, "V32iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vsububh_128B, "V64iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddhw, "V32iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddhw_128B, "V64iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubhw, "V32iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubhw_128B, "V64iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vadduhw, "V32iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vadduhw_128B, "V64iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubuhw, "V32iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubuhw_128B, "V64iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vd0, "V16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vd0_128B, "V32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddbq, "V16iV64bV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddbq_128B, "V32iV128bV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubbq, "V16iV64bV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubbq_128B, "V32iV128bV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddbnq, "V16iV64bV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddbnq_128B, "V32iV128bV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubbnq, "V16iV64bV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubbnq_128B, "V32iV128bV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddhq, "V16iV64bV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddhq_128B, "V32iV128bV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubhq, "V16iV64bV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubhq_128B, "V32iV128bV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddhnq, "V16iV64bV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddhnq_128B, "V32iV128bV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubhnq, "V16iV64bV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubhnq_128B, "V32iV128bV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddwq, "V16iV64bV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddwq_128B, "V32iV128bV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubwq, "V16iV64bV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubwq_128B, "V32iV128bV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddwnq, "V16iV64bV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddwnq_128B, "V32iV128bV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubwnq, "V16iV64bV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubwnq_128B, "V32iV128bV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vabsh, "V16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vabsh_128B, "V32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vabsh_sat, "V16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vabsh_sat_128B, "V32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vabsw, "V16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vabsw_128B, "V32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vabsw_sat, "V16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vabsw_sat_128B, "V32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpybv, "V32iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpybv_128B, "V64iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpybv_acc, "V32iV32iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpybv_acc_128B, "V64iV64iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyubv, "V32iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyubv_128B, "V64iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyubv_acc, "V32iV32iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyubv_acc_128B, "V64iV64iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpybusv, "V32iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpybusv_128B, "V64iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpybusv_acc, "V32iV32iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpybusv_acc_128B, "V64iV64iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpabusv, "V32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpabusv_128B, "V64iV64iV64i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpabuuv, "V32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpabuuv_128B, "V64iV64iV64i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyhv, "V32iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyhv_128B, "V64iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyhv_acc, "V32iV32iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyhv_acc_128B, "V64iV64iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyuhv, "V32iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyuhv_128B, "V64iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyuhv_acc, "V32iV32iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyuhv_acc_128B, "V64iV64iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyhvsrs, "V16iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyhvsrs_128B, "V32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyhus, "V32iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyhus_128B, "V64iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyhus_acc, "V32iV32iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyhus_acc_128B, "V64iV64iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyih, "V16iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyih_128B, "V32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyih_acc, "V16iV16iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyih_acc_128B, "V32iV32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyewuh, "V16iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyewuh_128B, "V32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyowh, "V16iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyowh_128B, "V32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyowh_rnd, "V16iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyowh_rnd_128B, "V32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyowh_sacc, "V16iV16iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyowh_sacc_128B, "V32iV32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyowh_rnd_sacc, "V16iV16iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyowh_rnd_sacc_128B, "V32iV32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyieoh, "V16iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyieoh_128B, "V32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyiewuh, "V16iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyiewuh_128B, "V32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyiowh, "V16iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyiowh_128B, "V32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyiewh_acc, "V16iV16iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyiewh_acc_128B, "V32iV32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyiewuh_acc, "V16iV16iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyiewuh_acc_128B, "V32iV32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyub, "V32iV16ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyub_128B, "V64iV32ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyub_acc, "V32iV32iV16ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyub_acc_128B, "V64iV64iV32ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpybus, "V32iV16ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpybus_128B, "V64iV32ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpybus_acc, "V32iV32iV16ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpybus_acc_128B, "V64iV64iV32ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpabus, "V32iV32ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpabus_128B, "V64iV64ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpabus_acc, "V32iV32iV32ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpabus_acc_128B, "V64iV64iV64ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpahb, "V32iV32ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpahb_128B, "V64iV64ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpahb_acc, "V32iV32iV32ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpahb_acc_128B, "V64iV64iV64ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyh, "V32iV16ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyh_128B, "V64iV32ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyhsat_acc, "V32iV32iV16ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyhsat_acc_128B, "V64iV64iV32ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyhss, "V16iV16ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyhss_128B, "V32iV32ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyhsrs, "V16iV16ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyhsrs_128B, "V32iV32ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyuh, "V32iV16ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyuh_128B, "V64iV32ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyuh_acc, "V32iV32iV16ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyuh_acc_128B, "V64iV64iV32ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyihb, "V16iV16ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyihb_128B, "V32iV32ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyihb_acc, "V16iV16iV16ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyihb_acc_128B, "V32iV32iV32ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyiwb, "V16iV16ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyiwb_128B, "V32iV32ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyiwb_acc, "V16iV16iV16ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyiwb_acc_128B, "V32iV32iV32ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyiwh, "V16iV16ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyiwh_128B, "V32iV32ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyiwh_acc, "V16iV16iV16ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyiwh_acc_128B, "V32iV32iV32ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vand, "V16iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vand_128B, "V32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vor, "V16iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vor_128B, "V32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vxor, "V16iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vxor_128B, "V32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vnot, "V16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vnot_128B, "V32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vandqrt, "V16iV64bi", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vandqrt_128B, "V32iV128bi", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vandqrt_acc, "V16iV16iV64bi", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vandqrt_acc_128B, "V32iV32iV128bi", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vandvrt, "V64bV16ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vandvrt_128B, "V128bV32ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vandvrt_acc, "V64bV64bV16ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vandvrt_acc_128B, "V128bV128bV32ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtw, "V64bV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtw_128B, "V128bV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtw_and, "V64bV64bV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtw_and_128B, "V128bV128bV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtw_or, "V64bV64bV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtw_or_128B, "V128bV128bV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtw_xor, "V64bV64bV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtw_xor_128B, "V128bV128bV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_veqw, "V64bV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_veqw_128B, "V128bV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_veqw_and, "V64bV64bV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_veqw_and_128B, "V128bV128bV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_veqw_or, "V64bV64bV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_veqw_or_128B, "V128bV128bV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_veqw_xor, "V64bV64bV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_veqw_xor_128B, "V128bV128bV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vgth, "V64bV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vgth_128B, "V128bV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vgth_and, "V64bV64bV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vgth_and_128B, "V128bV128bV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vgth_or, "V64bV64bV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vgth_or_128B, "V128bV128bV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vgth_xor, "V64bV64bV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vgth_xor_128B, "V128bV128bV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_veqh, "V64bV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_veqh_128B, "V128bV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_veqh_and, "V64bV64bV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_veqh_and_128B, "V128bV128bV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_veqh_or, "V64bV64bV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_veqh_or_128B, "V128bV128bV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_veqh_xor, "V64bV64bV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_veqh_xor_128B, "V128bV128bV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtb, "V64bV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtb_128B, "V128bV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtb_and, "V64bV64bV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtb_and_128B, "V128bV128bV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtb_or, "V64bV64bV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtb_or_128B, "V128bV128bV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtb_xor, "V64bV64bV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtb_xor_128B, "V128bV128bV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_veqb, "V64bV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_veqb_128B, "V128bV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_veqb_and, "V64bV64bV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_veqb_and_128B, "V128bV128bV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_veqb_or, "V64bV64bV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_veqb_or_128B, "V128bV128bV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_veqb_xor, "V64bV64bV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_veqb_xor_128B, "V128bV128bV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtuw, "V64bV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtuw_128B, "V128bV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtuw_and, "V64bV64bV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtuw_and_128B, "V128bV128bV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtuw_or, "V64bV64bV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtuw_or_128B, "V128bV128bV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtuw_xor, "V64bV64bV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtuw_xor_128B, "V128bV128bV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtuh, "V64bV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtuh_128B, "V128bV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtuh_and, "V64bV64bV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtuh_and_128B, "V128bV128bV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtuh_or, "V64bV64bV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtuh_or_128B, "V128bV128bV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtuh_xor, "V64bV64bV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtuh_xor_128B, "V128bV128bV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtub, "V64bV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtub_128B, "V128bV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtub_and, "V64bV64bV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtub_and_128B, "V128bV128bV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtub_or, "V64bV64bV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtub_or_128B, "V128bV128bV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtub_xor, "V64bV64bV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vgtub_xor_128B, "V128bV128bV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_pred_or, "V64bV64bV64b", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_pred_or_128B, "V128bV128bV128b", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_pred_and, "V64bV64bV64b", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_pred_and_128B, "V128bV128bV128b", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_pred_not, "V64bV64b", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_pred_not_128B, "V128bV128b", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_pred_xor, "V64bV64bV64b", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_pred_xor_128B, "V128bV128bV128b", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_pred_and_n, "V64bV64bV64b", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_pred_and_n_128B, "V128bV128bV128b", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_pred_or_n, "V64bV64bV64b", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_pred_or_n_128B, "V128bV128bV128b", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_pred_scalar2, "V64bi", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_pred_scalar2_128B, "V128bi", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmux, "V16iV64bV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmux_128B, "V32iV128bV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vswap, "V32iV64bV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vswap_128B, "V64iV128bV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmaxub, "V16iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmaxub_128B, "V32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vminub, "V16iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vminub_128B, "V32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmaxuh, "V16iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmaxuh_128B, "V32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vminuh, "V16iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vminuh_128B, "V32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmaxh, "V16iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmaxh_128B, "V32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vminh, "V16iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vminh_128B, "V32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmaxw, "V16iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmaxw_128B, "V32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vminw, "V16iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vminw_128B, "V32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vsathub, "V16iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vsathub_128B, "V32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vsatwh, "V16iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vsatwh_128B, "V32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vshuffeb, "V16iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vshuffeb_128B, "V32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vshuffob, "V16iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vshuffob_128B, "V32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vshufeh, "V16iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vshufeh_128B, "V32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vshufoh, "V16iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vshufoh_128B, "V32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vshuffvdd, "V32iV16iV16ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vshuffvdd_128B, "V64iV32iV32ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vdealvdd, "V32iV16iV16ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vdealvdd_128B, "V64iV32iV32ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vshufoeh, "V32iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vshufoeh_128B, "V64iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vshufoeb, "V32iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vshufoeb_128B, "V64iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vdealh, "V16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vdealh_128B, "V32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vdealb, "V16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vdealb_128B, "V32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vdealb4w, "V16iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vdealb4w_128B, "V32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vshuffh, "V16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vshuffh_128B, "V32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vshuffb, "V16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vshuffb_128B, "V32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_extractw, "iV16ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_extractw_128B, "iV32ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vinsertwr, "V16iV16ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vinsertwr_128B, "V32iV32ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_lvsplatw, "V16ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_lvsplatw_128B, "V32ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vassignp, "V32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vassignp_128B, "V64iV64i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vassign, "V16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vassign_128B, "V32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vcombine, "V32iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vcombine_128B, "V64iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vdelta, "V16iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vdelta_128B, "V32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vrdelta, "V16iV16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vrdelta_128B, "V32iV32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vcl0w, "V16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vcl0w_128B, "V32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vcl0h, "V16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vcl0h_128B, "V32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vnormamtw, "V16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vnormamtw_128B, "V32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vnormamth, "V16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vnormamth_128B, "V32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vpopcounth, "V16iV16i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vpopcounth_128B, "V32iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vlutvvb, "V16iV16iV16ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vlutvvb_128B, "V32iV32iV32ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vlutvvb_oracc, "V16iV16iV16iV16ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vlutvvb_oracc_128B, "V32iV32iV32iV32ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vlutvwh, "V32iV16iV16ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vlutvwh_128B, "V64iV32iV32ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vlutvwh_oracc, "V32iV32iV16iV16ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vlutvwh_oracc_128B, "V64iV64iV32iV32ii", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_hi, "V16iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_hi_128B, "V32iV64i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_lo, "V16iV32i", "", HVXV60) +TARGET_BUILTIN(__builtin_HEXAGON_V6_lo_128B, "V32iV64i", "", HVXV60) + +// V62 HVX Instructions. + +TARGET_BUILTIN(__builtin_HEXAGON_V6_vlsrb, "V16iV16ii", "", HVXV62) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vlsrb_128B, "V32iV32ii", "", HVXV62) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vasrwuhrndsat, "V16iV16iV16ii", "", HVXV62) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vasrwuhrndsat_128B, "V32iV32iV32ii", "", HVXV62) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vasruwuhrndsat, "V16iV16iV16ii", "", HVXV62) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vasruwuhrndsat_128B, "V32iV32iV32ii", "", HVXV62) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vasrhbsat, "V16iV16iV16ii", "", HVXV62) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vasrhbsat_128B, "V32iV32iV32ii", "", HVXV62) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vrounduwuh, "V16iV16iV16i", "", HVXV62) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vrounduwuh_128B, "V32iV32iV32i", "", HVXV62) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vrounduhub, "V16iV16iV16i", "", HVXV62) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vrounduhub_128B, "V32iV32iV32i", "", HVXV62) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vadduwsat, "V16iV16iV16i", "", HVXV62) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vadduwsat_128B, "V32iV32iV32i", "", HVXV62) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vadduwsat_dv, "V32iV32iV32i", "", HVXV62) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vadduwsat_dv_128B, "V64iV64iV64i", "", HVXV62) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubuwsat, "V16iV16iV16i", "", HVXV62) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubuwsat_128B, "V32iV32iV32i", "", HVXV62) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubuwsat_dv, "V32iV32iV32i", "", HVXV62) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubuwsat_dv_128B, "V64iV64iV64i", "", HVXV62) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddbsat, "V16iV16iV16i", "", HVXV62) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddbsat_128B, "V32iV32iV32i", "", HVXV62) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddbsat_dv, "V32iV32iV32i", "", HVXV62) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddbsat_dv_128B, "V64iV64iV64i", "", HVXV62) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubbsat, "V16iV16iV16i", "", HVXV62) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubbsat_128B, "V32iV32iV32i", "", HVXV62) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubbsat_dv, "V32iV32iV32i", "", HVXV62) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubbsat_dv_128B, "V64iV64iV64i", "", HVXV62) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddcarry, "V16iV16iV16iv*", "", HVXV62) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddcarry_128B, "V32iV32iV32iv*", "", HVXV62) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubcarry, "V16iV16iV16iv*", "", HVXV62) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubcarry_128B, "V32iV32iV32iv*", "", HVXV62) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddububb_sat, "V16iV16iV16i", "", HVXV62) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddububb_sat_128B, "V32iV32iV32i", "", HVXV62) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubububb_sat, "V16iV16iV16i", "", HVXV62) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vsubububb_sat_128B, "V32iV32iV32i", "", HVXV62) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddhw_acc, "V32iV32iV16iV16i", "", HVXV62) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddhw_acc_128B, "V64iV64iV32iV32i", "", HVXV62) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vadduhw_acc, "V32iV32iV16iV16i", "", HVXV62) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vadduhw_acc_128B, "V64iV64iV32iV32i", "", HVXV62) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddubh_acc, "V32iV32iV16iV16i", "", HVXV62) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddubh_acc_128B, "V64iV64iV32iV32i", "", HVXV62) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyewuh_64, "V32iV16iV16i", "", HVXV62) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyewuh_64_128B, "V64iV32iV32i", "", HVXV62) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyowh_64_acc, "V32iV32iV16iV16i", "", HVXV62) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyowh_64_acc_128B, "V64iV64iV32iV32i", "", HVXV62) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpauhb, "V32iV32ii", "", HVXV62) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpauhb_128B, "V64iV64ii", "", HVXV62) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpauhb_acc, "V32iV32iV32ii", "", HVXV62) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpauhb_acc_128B, "V64iV64iV64ii", "", HVXV62) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyiwub, "V16iV16ii", "", HVXV62) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyiwub_128B, "V32iV32ii", "", HVXV62) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyiwub_acc, "V16iV16iV16ii", "", HVXV62) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyiwub_acc_128B, "V32iV32iV32ii", "", HVXV62) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vandnqrt, "V16iV64bi", "", HVXV62) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vandnqrt_128B, "V32iV128bi", "", HVXV62) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vandnqrt_acc, "V16iV16iV64bi", "", HVXV62) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vandnqrt_acc_128B, "V32iV32iV128bi", "", HVXV62) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vandvqv, "V16iV64bV16i", "", HVXV62) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vandvqv_128B, "V32iV128bV32i", "", HVXV62) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vandvnqv, "V16iV64bV16i", "", HVXV62) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vandvnqv_128B, "V32iV128bV32i", "", HVXV62) +TARGET_BUILTIN(__builtin_HEXAGON_V6_pred_scalar2v2, "V64bi", "", HVXV62) +TARGET_BUILTIN(__builtin_HEXAGON_V6_pred_scalar2v2_128B, "V128bi", "", HVXV62) +TARGET_BUILTIN(__builtin_HEXAGON_V6_shuffeqw, "V64bV64bV64b", "", HVXV62) +TARGET_BUILTIN(__builtin_HEXAGON_V6_shuffeqw_128B, "V128bV128bV128b", "", HVXV62) +TARGET_BUILTIN(__builtin_HEXAGON_V6_shuffeqh, "V64bV64bV64b", "", HVXV62) +TARGET_BUILTIN(__builtin_HEXAGON_V6_shuffeqh_128B, "V128bV128bV128b", "", HVXV62) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmaxb, "V16iV16iV16i", "", HVXV62) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmaxb_128B, "V32iV32iV32i", "", HVXV62) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vminb, "V16iV16iV16i", "", HVXV62) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vminb_128B, "V32iV32iV32i", "", HVXV62) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vsatuwuh, "V16iV16iV16i", "", HVXV62) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vsatuwuh_128B, "V32iV32iV32i", "", HVXV62) +TARGET_BUILTIN(__builtin_HEXAGON_V6_lvsplath, "V16ii", "", HVXV62) +TARGET_BUILTIN(__builtin_HEXAGON_V6_lvsplath_128B, "V32ii", "", HVXV62) +TARGET_BUILTIN(__builtin_HEXAGON_V6_lvsplatb, "V16ii", "", HVXV62) +TARGET_BUILTIN(__builtin_HEXAGON_V6_lvsplatb_128B, "V32ii", "", HVXV62) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddclbw, "V16iV16iV16i", "", HVXV62) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddclbw_128B, "V32iV32iV32i", "", HVXV62) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddclbh, "V16iV16iV16i", "", HVXV62) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddclbh_128B, "V32iV32iV32i", "", HVXV62) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vlutvvbi, "V16iV16iV16iUIi", "", HVXV62) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vlutvvbi_128B, "V32iV32iV32iUIi", "", HVXV62) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vlutvvb_oracci, "V16iV16iV16iV16iUIi", "", HVXV62) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vlutvvb_oracci_128B, "V32iV32iV32iV32iUIi", "", HVXV62) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vlutvwhi, "V32iV16iV16iUIi", "", HVXV62) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vlutvwhi_128B, "V64iV32iV32iUIi", "", HVXV62) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vlutvwh_oracci, "V32iV32iV16iV16iUIi", "", HVXV62) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vlutvwh_oracci_128B, "V64iV64iV32iV32iUIi", "", HVXV62) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vlutvvb_nm, "V16iV16iV16ii", "", HVXV62) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vlutvvb_nm_128B, "V32iV32iV32ii", "", HVXV62) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vlutvwh_nm, "V32iV16iV16ii", "", HVXV62) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vlutvwh_nm_128B, "V64iV32iV32ii", "", HVXV62) + +// V65 HVX Instructions. + +TARGET_BUILTIN(__builtin_HEXAGON_V6_vasruwuhsat, "V16iV16iV16ii", "", HVXV65) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vasruwuhsat_128B, "V32iV32iV32ii", "", HVXV65) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vasruhubsat, "V16iV16iV16ii", "", HVXV65) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vasruhubsat_128B, "V32iV32iV32ii", "", HVXV65) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vasruhubrndsat, "V16iV16iV16ii", "", HVXV65) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vasruhubrndsat_128B, "V32iV32iV32ii", "", HVXV65) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vaslh_acc, "V16iV16iV16ii", "", HVXV65) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vaslh_acc_128B, "V32iV32iV32ii", "", HVXV65) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vasrh_acc, "V16iV16iV16ii", "", HVXV65) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vasrh_acc_128B, "V32iV32iV32ii", "", HVXV65) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vavguw, "V16iV16iV16i", "", HVXV65) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vavguw_128B, "V32iV32iV32i", "", HVXV65) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vavguwrnd, "V16iV16iV16i", "", HVXV65) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vavguwrnd_128B, "V32iV32iV32i", "", HVXV65) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vavgb, "V16iV16iV16i", "", HVXV65) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vavgb_128B, "V32iV32iV32i", "", HVXV65) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vavgbrnd, "V16iV16iV16i", "", HVXV65) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vavgbrnd_128B, "V32iV32iV32i", "", HVXV65) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vnavgb, "V16iV16iV16i", "", HVXV65) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vnavgb_128B, "V32iV32iV32i", "", HVXV65) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vdd0, "V32i", "", HVXV65) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vdd0_128B, "V64i", "", HVXV65) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vabsb, "V16iV16i", "", HVXV65) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vabsb_128B, "V32iV32i", "", HVXV65) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vabsb_sat, "V16iV16i", "", HVXV65) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vabsb_sat_128B, "V32iV32i", "", HVXV65) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpabuu, "V32iV32ii", "", HVXV65) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpabuu_128B, "V64iV64ii", "", HVXV65) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpabuu_acc, "V32iV32iV32ii", "", HVXV65) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpabuu_acc_128B, "V64iV64iV64ii", "", HVXV65) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyh_acc, "V32iV32iV16ii", "", HVXV65) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyh_acc_128B, "V64iV64iV32ii", "", HVXV65) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpahhsat, "V16iV16iV16iLLi", "", HVXV65) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpahhsat_128B, "V32iV32iV32iLLi", "", HVXV65) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpauhuhsat, "V16iV16iV16iLLi", "", HVXV65) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpauhuhsat_128B, "V32iV32iV32iLLi", "", HVXV65) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpsuhuhsat, "V16iV16iV16iLLi", "", HVXV65) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpsuhuhsat_128B, "V32iV32iV32iLLi", "", HVXV65) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vlut4, "V16iV16iLLi", "", HVXV65) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vlut4_128B, "V32iV32iLLi", "", HVXV65) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyuhe, "V16iV16ii", "", HVXV65) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyuhe_128B, "V32iV32ii", "", HVXV65) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyuhe_acc, "V16iV16iV16ii", "", HVXV65) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vmpyuhe_acc_128B, "V32iV32iV32ii", "", HVXV65) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vgathermw, "vv*iiV16i", "", HVXV65) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vgathermw_128B, "vv*iiV32i", "", HVXV65) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vgathermh, "vv*iiV16i", "", HVXV65) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vgathermh_128B, "vv*iiV32i", "", HVXV65) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vgathermhw, "vv*iiV32i", "", HVXV65) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vgathermhw_128B, "vv*iiV64i", "", HVXV65) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vgathermwq, "vv*V64biiV16i", "", HVXV65) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vgathermwq_128B, "vv*V128biiV32i", "", HVXV65) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vgathermhq, "vv*V64biiV16i", "", HVXV65) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vgathermhq_128B, "vv*V128biiV32i", "", HVXV65) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vgathermhwq, "vv*V64biiV32i", "", HVXV65) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vgathermhwq_128B, "vv*V128biiV64i", "", HVXV65) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vscattermw, "viiV16iV16i", "", HVXV65) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vscattermw_128B, "viiV32iV32i", "", HVXV65) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vscattermh, "viiV16iV16i", "", HVXV65) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vscattermh_128B, "viiV32iV32i", "", HVXV65) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vscattermw_add, "viiV16iV16i", "", HVXV65) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vscattermw_add_128B, "viiV32iV32i", "", HVXV65) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vscattermh_add, "viiV16iV16i", "", HVXV65) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vscattermh_add_128B, "viiV32iV32i", "", HVXV65) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vscattermwq, "vV64biiV16iV16i", "", HVXV65) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vscattermwq_128B, "vV128biiV32iV32i", "", HVXV65) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vscattermhq, "vV64biiV16iV16i", "", HVXV65) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vscattermhq_128B, "vV128biiV32iV32i", "", HVXV65) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vscattermhw, "viiV32iV16i", "", HVXV65) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vscattermhw_128B, "viiV64iV32i", "", HVXV65) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vscattermhwq, "vV64biiV32iV16i", "", HVXV65) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vscattermhwq_128B, "vV128biiV64iV32i", "", HVXV65) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vscattermhw_add, "viiV32iV16i", "", HVXV65) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vscattermhw_add_128B, "viiV64iV32i", "", HVXV65) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vprefixqb, "V16iV64b", "", HVXV65) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vprefixqb_128B, "V32iV128b", "", HVXV65) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vprefixqh, "V16iV64b", "", HVXV65) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vprefixqh_128B, "V32iV128b", "", HVXV65) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vprefixqw, "V16iV64b", "", HVXV65) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vprefixqw_128B, "V32iV128b", "", HVXV65) + +// V66 HVX Instructions. + +TARGET_BUILTIN(__builtin_HEXAGON_V6_vrotr, "V16iV16iV16i", "", HVXV66) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vrotr_128B, "V32iV32iV32i", "", HVXV66) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vasr_into, "V32iV32iV16iV16i", "", HVXV66) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vasr_into_128B, "V64iV64iV32iV32i", "", HVXV66) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddcarrysat, "V16iV16iV16iV64b", "", HVXV66) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vaddcarrysat_128B, "V32iV32iV32iV128b", "", HVXV66) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vsatdw, "V16iV16iV16i", "", HVXV66) +TARGET_BUILTIN(__builtin_HEXAGON_V6_vsatdw_128B, "V32iV32iV32i", "", HVXV66) diff --git a/clang/include/clang/Basic/BuiltinsHexagonMapCustomDep.def b/clang/include/clang/Basic/BuiltinsHexagonMapCustomDep.def new file mode 100644 index 000000000000..9478a1b3fd14 --- /dev/null +++ b/clang/include/clang/Basic/BuiltinsHexagonMapCustomDep.def @@ -0,0 +1,206 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// Automatically generated file, do not edit! +//===----------------------------------------------------------------------===// + +CUSTOM_BUILTIN_MAPPING(M2_mpysmi, 0) +CUSTOM_BUILTIN_MAPPING(M2_dpmpyss_s0, 0) +CUSTOM_BUILTIN_MAPPING(M2_dpmpyuu_s0, 0) +CUSTOM_BUILTIN_MAPPING(M2_mpyi, 0) +CUSTOM_BUILTIN_MAPPING(M2_mpyui, 0) +CUSTOM_BUILTIN_MAPPING(A2_add, 0) +CUSTOM_BUILTIN_MAPPING(A2_sub, 0) +CUSTOM_BUILTIN_MAPPING(A2_addi, 0) +CUSTOM_BUILTIN_MAPPING(A2_addp, 0) +CUSTOM_BUILTIN_MAPPING(A2_subp, 0) +CUSTOM_BUILTIN_MAPPING(A2_neg, 0) +CUSTOM_BUILTIN_MAPPING(A2_zxtb, 0) +CUSTOM_BUILTIN_MAPPING(A2_sxtb, 0) +CUSTOM_BUILTIN_MAPPING(A2_zxth, 0) +CUSTOM_BUILTIN_MAPPING(A2_sxth, 0) +CUSTOM_BUILTIN_MAPPING(A2_and, 0) +CUSTOM_BUILTIN_MAPPING(A2_or, 0) +CUSTOM_BUILTIN_MAPPING(A2_xor, 0) +CUSTOM_BUILTIN_MAPPING(A2_not, 0) +CUSTOM_BUILTIN_MAPPING(A2_subri, 0) +CUSTOM_BUILTIN_MAPPING(A2_andir, 0) +CUSTOM_BUILTIN_MAPPING(A2_orir, 0) +CUSTOM_BUILTIN_MAPPING(S2_asr_i_r, 0) +CUSTOM_BUILTIN_MAPPING(S2_lsr_i_r, 0) +CUSTOM_BUILTIN_MAPPING(S2_asl_i_r, 0) +CUSTOM_BUILTIN_MAPPING(S2_asr_i_p, 0) +CUSTOM_BUILTIN_MAPPING(S2_lsr_i_p, 0) +CUSTOM_BUILTIN_MAPPING(S2_asl_i_p, 0) +CUSTOM_BUILTIN_MAPPING(V6_vS32b_qpred_ai, 64) +CUSTOM_BUILTIN_MAPPING(V6_vS32b_qpred_ai_128B, 128) +CUSTOM_BUILTIN_MAPPING(V6_vS32b_nqpred_ai, 64) +CUSTOM_BUILTIN_MAPPING(V6_vS32b_nqpred_ai_128B, 128) +CUSTOM_BUILTIN_MAPPING(V6_vS32b_nt_qpred_ai, 64) +CUSTOM_BUILTIN_MAPPING(V6_vS32b_nt_qpred_ai_128B, 128) +CUSTOM_BUILTIN_MAPPING(V6_vS32b_nt_nqpred_ai, 64) +CUSTOM_BUILTIN_MAPPING(V6_vS32b_nt_nqpred_ai_128B, 128) +CUSTOM_BUILTIN_MAPPING(V6_vaddbq, 64) +CUSTOM_BUILTIN_MAPPING(V6_vaddbq_128B, 128) +CUSTOM_BUILTIN_MAPPING(V6_vsubbq, 64) +CUSTOM_BUILTIN_MAPPING(V6_vsubbq_128B, 128) +CUSTOM_BUILTIN_MAPPING(V6_vaddbnq, 64) +CUSTOM_BUILTIN_MAPPING(V6_vaddbnq_128B, 128) +CUSTOM_BUILTIN_MAPPING(V6_vsubbnq, 64) +CUSTOM_BUILTIN_MAPPING(V6_vsubbnq_128B, 128) +CUSTOM_BUILTIN_MAPPING(V6_vaddhq, 64) +CUSTOM_BUILTIN_MAPPING(V6_vaddhq_128B, 128) +CUSTOM_BUILTIN_MAPPING(V6_vsubhq, 64) +CUSTOM_BUILTIN_MAPPING(V6_vsubhq_128B, 128) +CUSTOM_BUILTIN_MAPPING(V6_vaddhnq, 64) +CUSTOM_BUILTIN_MAPPING(V6_vaddhnq_128B, 128) +CUSTOM_BUILTIN_MAPPING(V6_vsubhnq, 64) +CUSTOM_BUILTIN_MAPPING(V6_vsubhnq_128B, 128) +CUSTOM_BUILTIN_MAPPING(V6_vaddwq, 64) +CUSTOM_BUILTIN_MAPPING(V6_vaddwq_128B, 128) +CUSTOM_BUILTIN_MAPPING(V6_vsubwq, 64) +CUSTOM_BUILTIN_MAPPING(V6_vsubwq_128B, 128) +CUSTOM_BUILTIN_MAPPING(V6_vaddwnq, 64) +CUSTOM_BUILTIN_MAPPING(V6_vaddwnq_128B, 128) +CUSTOM_BUILTIN_MAPPING(V6_vsubwnq, 64) +CUSTOM_BUILTIN_MAPPING(V6_vsubwnq_128B, 128) +CUSTOM_BUILTIN_MAPPING(V6_vandqrt, 64) +CUSTOM_BUILTIN_MAPPING(V6_vandqrt_128B, 128) +CUSTOM_BUILTIN_MAPPING(V6_vandqrt_acc, 64) +CUSTOM_BUILTIN_MAPPING(V6_vandqrt_acc_128B, 128) +CUSTOM_BUILTIN_MAPPING(V6_vandvrt, 64) +CUSTOM_BUILTIN_MAPPING(V6_vandvrt_128B, 128) +CUSTOM_BUILTIN_MAPPING(V6_vandvrt_acc, 64) +CUSTOM_BUILTIN_MAPPING(V6_vandvrt_acc_128B, 128) +CUSTOM_BUILTIN_MAPPING(V6_vgtw, 64) +CUSTOM_BUILTIN_MAPPING(V6_vgtw_128B, 128) +CUSTOM_BUILTIN_MAPPING(V6_vgtw_and, 64) +CUSTOM_BUILTIN_MAPPING(V6_vgtw_and_128B, 128) +CUSTOM_BUILTIN_MAPPING(V6_vgtw_or, 64) +CUSTOM_BUILTIN_MAPPING(V6_vgtw_or_128B, 128) +CUSTOM_BUILTIN_MAPPING(V6_vgtw_xor, 64) +CUSTOM_BUILTIN_MAPPING(V6_vgtw_xor_128B, 128) +CUSTOM_BUILTIN_MAPPING(V6_veqw, 64) +CUSTOM_BUILTIN_MAPPING(V6_veqw_128B, 128) +CUSTOM_BUILTIN_MAPPING(V6_veqw_and, 64) +CUSTOM_BUILTIN_MAPPING(V6_veqw_and_128B, 128) +CUSTOM_BUILTIN_MAPPING(V6_veqw_or, 64) +CUSTOM_BUILTIN_MAPPING(V6_veqw_or_128B, 128) +CUSTOM_BUILTIN_MAPPING(V6_veqw_xor, 64) +CUSTOM_BUILTIN_MAPPING(V6_veqw_xor_128B, 128) +CUSTOM_BUILTIN_MAPPING(V6_vgth, 64) +CUSTOM_BUILTIN_MAPPING(V6_vgth_128B, 128) +CUSTOM_BUILTIN_MAPPING(V6_vgth_and, 64) +CUSTOM_BUILTIN_MAPPING(V6_vgth_and_128B, 128) +CUSTOM_BUILTIN_MAPPING(V6_vgth_or, 64) +CUSTOM_BUILTIN_MAPPING(V6_vgth_or_128B, 128) +CUSTOM_BUILTIN_MAPPING(V6_vgth_xor, 64) +CUSTOM_BUILTIN_MAPPING(V6_vgth_xor_128B, 128) +CUSTOM_BUILTIN_MAPPING(V6_veqh, 64) +CUSTOM_BUILTIN_MAPPING(V6_veqh_128B, 128) +CUSTOM_BUILTIN_MAPPING(V6_veqh_and, 64) +CUSTOM_BUILTIN_MAPPING(V6_veqh_and_128B, 128) +CUSTOM_BUILTIN_MAPPING(V6_veqh_or, 64) +CUSTOM_BUILTIN_MAPPING(V6_veqh_or_128B, 128) +CUSTOM_BUILTIN_MAPPING(V6_veqh_xor, 64) +CUSTOM_BUILTIN_MAPPING(V6_veqh_xor_128B, 128) +CUSTOM_BUILTIN_MAPPING(V6_vgtb, 64) +CUSTOM_BUILTIN_MAPPING(V6_vgtb_128B, 128) +CUSTOM_BUILTIN_MAPPING(V6_vgtb_and, 64) +CUSTOM_BUILTIN_MAPPING(V6_vgtb_and_128B, 128) +CUSTOM_BUILTIN_MAPPING(V6_vgtb_or, 64) +CUSTOM_BUILTIN_MAPPING(V6_vgtb_or_128B, 128) +CUSTOM_BUILTIN_MAPPING(V6_vgtb_xor, 64) +CUSTOM_BUILTIN_MAPPING(V6_vgtb_xor_128B, 128) +CUSTOM_BUILTIN_MAPPING(V6_veqb, 64) +CUSTOM_BUILTIN_MAPPING(V6_veqb_128B, 128) +CUSTOM_BUILTIN_MAPPING(V6_veqb_and, 64) +CUSTOM_BUILTIN_MAPPING(V6_veqb_and_128B, 128) +CUSTOM_BUILTIN_MAPPING(V6_veqb_or, 64) +CUSTOM_BUILTIN_MAPPING(V6_veqb_or_128B, 128) +CUSTOM_BUILTIN_MAPPING(V6_veqb_xor, 64) +CUSTOM_BUILTIN_MAPPING(V6_veqb_xor_128B, 128) +CUSTOM_BUILTIN_MAPPING(V6_vgtuw, 64) +CUSTOM_BUILTIN_MAPPING(V6_vgtuw_128B, 128) +CUSTOM_BUILTIN_MAPPING(V6_vgtuw_and, 64) +CUSTOM_BUILTIN_MAPPING(V6_vgtuw_and_128B, 128) +CUSTOM_BUILTIN_MAPPING(V6_vgtuw_or, 64) +CUSTOM_BUILTIN_MAPPING(V6_vgtuw_or_128B, 128) +CUSTOM_BUILTIN_MAPPING(V6_vgtuw_xor, 64) +CUSTOM_BUILTIN_MAPPING(V6_vgtuw_xor_128B, 128) +CUSTOM_BUILTIN_MAPPING(V6_vgtuh, 64) +CUSTOM_BUILTIN_MAPPING(V6_vgtuh_128B, 128) +CUSTOM_BUILTIN_MAPPING(V6_vgtuh_and, 64) +CUSTOM_BUILTIN_MAPPING(V6_vgtuh_and_128B, 128) +CUSTOM_BUILTIN_MAPPING(V6_vgtuh_or, 64) +CUSTOM_BUILTIN_MAPPING(V6_vgtuh_or_128B, 128) +CUSTOM_BUILTIN_MAPPING(V6_vgtuh_xor, 64) +CUSTOM_BUILTIN_MAPPING(V6_vgtuh_xor_128B, 128) +CUSTOM_BUILTIN_MAPPING(V6_vgtub, 64) +CUSTOM_BUILTIN_MAPPING(V6_vgtub_128B, 128) +CUSTOM_BUILTIN_MAPPING(V6_vgtub_and, 64) +CUSTOM_BUILTIN_MAPPING(V6_vgtub_and_128B, 128) +CUSTOM_BUILTIN_MAPPING(V6_vgtub_or, 64) +CUSTOM_BUILTIN_MAPPING(V6_vgtub_or_128B, 128) +CUSTOM_BUILTIN_MAPPING(V6_vgtub_xor, 64) +CUSTOM_BUILTIN_MAPPING(V6_vgtub_xor_128B, 128) +CUSTOM_BUILTIN_MAPPING(V6_pred_or, 64) +CUSTOM_BUILTIN_MAPPING(V6_pred_or_128B, 128) +CUSTOM_BUILTIN_MAPPING(V6_pred_and, 64) +CUSTOM_BUILTIN_MAPPING(V6_pred_and_128B, 128) +CUSTOM_BUILTIN_MAPPING(V6_pred_not, 64) +CUSTOM_BUILTIN_MAPPING(V6_pred_not_128B, 128) +CUSTOM_BUILTIN_MAPPING(V6_pred_xor, 64) +CUSTOM_BUILTIN_MAPPING(V6_pred_xor_128B, 128) +CUSTOM_BUILTIN_MAPPING(V6_pred_and_n, 64) +CUSTOM_BUILTIN_MAPPING(V6_pred_and_n_128B, 128) +CUSTOM_BUILTIN_MAPPING(V6_pred_or_n, 64) +CUSTOM_BUILTIN_MAPPING(V6_pred_or_n_128B, 128) +CUSTOM_BUILTIN_MAPPING(V6_pred_scalar2, 64) +CUSTOM_BUILTIN_MAPPING(V6_pred_scalar2_128B, 128) +CUSTOM_BUILTIN_MAPPING(V6_vmux, 64) +CUSTOM_BUILTIN_MAPPING(V6_vmux_128B, 128) +CUSTOM_BUILTIN_MAPPING(V6_vswap, 64) +CUSTOM_BUILTIN_MAPPING(V6_vswap_128B, 128) +CUSTOM_BUILTIN_MAPPING(V6_vaddcarry, 64) +CUSTOM_BUILTIN_MAPPING(V6_vaddcarry_128B, 128) +CUSTOM_BUILTIN_MAPPING(V6_vsubcarry, 64) +CUSTOM_BUILTIN_MAPPING(V6_vsubcarry_128B, 128) +CUSTOM_BUILTIN_MAPPING(V6_vandnqrt, 64) +CUSTOM_BUILTIN_MAPPING(V6_vandnqrt_128B, 128) +CUSTOM_BUILTIN_MAPPING(V6_vandnqrt_acc, 64) +CUSTOM_BUILTIN_MAPPING(V6_vandnqrt_acc_128B, 128) +CUSTOM_BUILTIN_MAPPING(V6_vandvqv, 64) +CUSTOM_BUILTIN_MAPPING(V6_vandvqv_128B, 128) +CUSTOM_BUILTIN_MAPPING(V6_vandvnqv, 64) +CUSTOM_BUILTIN_MAPPING(V6_vandvnqv_128B, 128) +CUSTOM_BUILTIN_MAPPING(V6_pred_scalar2v2, 64) +CUSTOM_BUILTIN_MAPPING(V6_pred_scalar2v2_128B, 128) +CUSTOM_BUILTIN_MAPPING(V6_shuffeqw, 64) +CUSTOM_BUILTIN_MAPPING(V6_shuffeqw_128B, 128) +CUSTOM_BUILTIN_MAPPING(V6_shuffeqh, 64) +CUSTOM_BUILTIN_MAPPING(V6_shuffeqh_128B, 128) +CUSTOM_BUILTIN_MAPPING(V6_vgathermwq, 64) +CUSTOM_BUILTIN_MAPPING(V6_vgathermwq_128B, 128) +CUSTOM_BUILTIN_MAPPING(V6_vgathermhq, 64) +CUSTOM_BUILTIN_MAPPING(V6_vgathermhq_128B, 128) +CUSTOM_BUILTIN_MAPPING(V6_vgathermhwq, 64) +CUSTOM_BUILTIN_MAPPING(V6_vgathermhwq_128B, 128) +CUSTOM_BUILTIN_MAPPING(V6_vscattermwq, 64) +CUSTOM_BUILTIN_MAPPING(V6_vscattermwq_128B, 128) +CUSTOM_BUILTIN_MAPPING(V6_vscattermhq, 64) +CUSTOM_BUILTIN_MAPPING(V6_vscattermhq_128B, 128) +CUSTOM_BUILTIN_MAPPING(V6_vscattermhwq, 64) +CUSTOM_BUILTIN_MAPPING(V6_vscattermhwq_128B, 128) +CUSTOM_BUILTIN_MAPPING(V6_vprefixqb, 64) +CUSTOM_BUILTIN_MAPPING(V6_vprefixqb_128B, 128) +CUSTOM_BUILTIN_MAPPING(V6_vprefixqh, 64) +CUSTOM_BUILTIN_MAPPING(V6_vprefixqh_128B, 128) +CUSTOM_BUILTIN_MAPPING(V6_vprefixqw, 64) +CUSTOM_BUILTIN_MAPPING(V6_vprefixqw_128B, 128) +CUSTOM_BUILTIN_MAPPING(V6_vaddcarrysat, 64) +CUSTOM_BUILTIN_MAPPING(V6_vaddcarrysat_128B, 128) diff --git a/clang/include/clang/Basic/BuiltinsMips.def b/clang/include/clang/Basic/BuiltinsMips.def index 9ac75b7a174e..2aca4cb226bc 100644 --- a/clang/include/clang/Basic/BuiltinsMips.def +++ b/clang/include/clang/Basic/BuiltinsMips.def @@ -635,6 +635,9 @@ BUILTIN(__builtin_msa_ld_h, "V8Ssv*Ii", "nc") BUILTIN(__builtin_msa_ld_w, "V4Siv*Ii", "nc") BUILTIN(__builtin_msa_ld_d, "V2SLLiv*Ii", "nc") +BUILTIN(__builtin_msa_ldr_d, "V2SLLiv*Ii", "nc") +BUILTIN(__builtin_msa_ldr_w, "V4Siv*Ii", "nc") + BUILTIN(__builtin_msa_ldi_b, "V16cIi", "nc") BUILTIN(__builtin_msa_ldi_h, "V8sIi", "nc") BUILTIN(__builtin_msa_ldi_w, "V4iIi", "nc") @@ -857,6 +860,9 @@ BUILTIN(__builtin_msa_st_h, "vV8Ssv*Ii", "nc") BUILTIN(__builtin_msa_st_w, "vV4Siv*Ii", "nc") BUILTIN(__builtin_msa_st_d, "vV2SLLiv*Ii", "nc") +BUILTIN(__builtin_msa_str_d, "vV2SLLiv*Ii", "nc") +BUILTIN(__builtin_msa_str_w, "vV4Siv*Ii", "nc") + BUILTIN(__builtin_msa_subs_s_b, "V16ScV16ScV16Sc", "nc") BUILTIN(__builtin_msa_subs_s_h, "V8SsV8SsV8Ss", "nc") BUILTIN(__builtin_msa_subs_s_w, "V4SiV4SiV4Si", "nc") diff --git a/clang/include/clang/Basic/BuiltinsNVPTX.def b/clang/include/clang/Basic/BuiltinsNVPTX.def index 70be6182c7ac..759c91290a60 100644 --- a/clang/include/clang/Basic/BuiltinsNVPTX.def +++ b/clang/include/clang/Basic/BuiltinsNVPTX.def @@ -20,7 +20,9 @@ #pragma push_macro("SM_70") #pragma push_macro("SM_72") #pragma push_macro("SM_75") -#define SM_75 "sm_75" +#pragma push_macro("SM_80") +#define SM_80 "sm_80" +#define SM_75 "sm_75|" SM_80 #define SM_72 "sm_72|" SM_75 #define SM_70 "sm_70|" SM_72 @@ -31,7 +33,11 @@ #pragma push_macro("PTX61") #pragma push_macro("PTX63") #pragma push_macro("PTX64") -#define PTX64 "ptx64" +#pragma push_macro("PTX65") +#pragma push_macro("PTX70") +#define PTX70 "ptx70" +#define PTX65 "ptx65|" PTX70 +#define PTX64 "ptx64|" PTX65 #define PTX63 "ptx63|" PTX64 #define PTX61 "ptx61|" PTX63 #define PTX60 "ptx60|" PTX61 @@ -721,7 +727,10 @@ TARGET_BUILTIN(__imma_m8n8k32_st_c_i32, "vi*iC*UiIi", "", AND(SM_75,PTX63)) #pragma pop_macro("SM_70") #pragma pop_macro("SM_72") #pragma pop_macro("SM_75") +#pragma pop_macro("SM_80") #pragma pop_macro("PTX60") #pragma pop_macro("PTX61") #pragma pop_macro("PTX63") #pragma pop_macro("PTX64") +#pragma pop_macro("PTX65") +#pragma pop_macro("PTX70") diff --git a/clang/include/clang/Basic/BuiltinsPPC.def b/clang/include/clang/Basic/BuiltinsPPC.def index 314e1cc05907..6b291e6b0806 100644 --- a/clang/include/clang/Basic/BuiltinsPPC.def +++ b/clang/include/clang/Basic/BuiltinsPPC.def @@ -298,6 +298,44 @@ BUILTIN(__builtin_altivec_vrldmi, "V2ULLiV2ULLiV2ULLiV2ULLi", "") BUILTIN(__builtin_altivec_vrlwnm, "V4UiV4UiV4Ui", "") BUILTIN(__builtin_altivec_vrldnm, "V2ULLiV2ULLiV2ULLi", "") +// P10 Vector Parallel Bits built-ins. +BUILTIN(__builtin_altivec_vpdepd, "V2ULLiV2ULLiV2ULLi", "") +BUILTIN(__builtin_altivec_vpextd, "V2ULLiV2ULLiV2ULLi", "") + +// P10 Vector Centrifuge built-in. +BUILTIN(__builtin_altivec_vcfuged, "V2ULLiV2ULLiV2ULLi", "") + +// P10 Vector Gather Every N-th Bit built-in. +BUILTIN(__builtin_altivec_vgnb, "ULLiV1ULLLiIi", "") + +// P10 Vector Clear Bytes built-ins. +BUILTIN(__builtin_altivec_vclrlb, "V16cV16cUi", "") +BUILTIN(__builtin_altivec_vclrrb, "V16cV16cUi", "") + +// P10 Vector Count Leading / Trailing Zeroes under bit Mask built-ins. +BUILTIN(__builtin_altivec_vclzdm, "V2ULLiV2ULLiV2ULLi", "") +BUILTIN(__builtin_altivec_vctzdm, "V2ULLiV2ULLiV2ULLi", "") + +// P10 Vector Shift built-ins. +BUILTIN(__builtin_altivec_vsldbi, "V16UcV16UcV16UcIi", "") +BUILTIN(__builtin_altivec_vsrdbi, "V16UcV16UcV16UcIi", "") + +// P10 Vector Insert built-ins. +BUILTIN(__builtin_altivec_vinsblx, "V16UcV16UcULLiULLi", "") +BUILTIN(__builtin_altivec_vinsbrx, "V16UcV16UcULLiULLi", "") +BUILTIN(__builtin_altivec_vinshlx, "V8UsV8UsULLiULLi", "") +BUILTIN(__builtin_altivec_vinshrx, "V8UsV8UsULLiULLi", "") +BUILTIN(__builtin_altivec_vinswlx, "V4UiV4UiULLiULLi", "") +BUILTIN(__builtin_altivec_vinswrx, "V4UiV4UiULLiULLi", "") +BUILTIN(__builtin_altivec_vinsdlx, "V2ULLiV2ULLiULLiULLi", "") +BUILTIN(__builtin_altivec_vinsdrx, "V2ULLiV2ULLiULLiULLi", "") +BUILTIN(__builtin_altivec_vinsbvlx, "V16UcV16UcULLiV16Uc", "") +BUILTIN(__builtin_altivec_vinsbvrx, "V16UcV16UcULLiV16Uc", "") +BUILTIN(__builtin_altivec_vinshvlx, "V8UsV8UsULLiV8Us", "") +BUILTIN(__builtin_altivec_vinshvrx, "V8UsV8UsULLiV8Us", "") +BUILTIN(__builtin_altivec_vinswvlx, "V4UiV4UiULLiV4Ui", "") +BUILTIN(__builtin_altivec_vinswvrx, "V4UiV4UiULLiV4Ui", "") + // VSX built-ins. BUILTIN(__builtin_vsx_lxvd2x, "V2divC*", "") @@ -391,6 +429,11 @@ BUILTIN(__builtin_vsx_xvcpsgnsp, "V4fV4fV4f", "") BUILTIN(__builtin_vsx_xvabssp, "V4fV4f", "") BUILTIN(__builtin_vsx_xvabsdp, "V2dV2d", "") +BUILTIN(__builtin_vsx_xxgenpcvbm, "V16UcV16Uci", "") +BUILTIN(__builtin_vsx_xxgenpcvhm, "V8UsV8Usi", "") +BUILTIN(__builtin_vsx_xxgenpcvwm, "V4UiV4Uii", "") +BUILTIN(__builtin_vsx_xxgenpcvdm, "V2ULLiV2ULLii", "") + // vector Insert/Extract exponent/significand builtins BUILTIN(__builtin_vsx_xviexpdp, "V2dV2ULLiV2ULLi", "") BUILTIN(__builtin_vsx_xviexpsp, "V4fV4UiV4Ui", "") @@ -422,6 +465,19 @@ BUILTIN(__builtin_vsx_extractuword, "V2ULLiV16UcIi", "") BUILTIN(__builtin_vsx_xxpermdi, "v.", "t") BUILTIN(__builtin_vsx_xxsldwi, "v.", "t") +BUILTIN(__builtin_vsx_xxeval, "V2ULLiV2ULLiV2ULLiV2ULLiIi", "") + +BUILTIN(__builtin_vsx_xvtlsbb, "iV16Ucb", "") + +// P10 Vector Permute Extended built-in. +BUILTIN(__builtin_vsx_xxpermx, "V16UcV16UcV16UcV16UcIi", "") + +// P10 Vector Blend built-ins. +BUILTIN(__builtin_vsx_xxblendvb, "V16UcV16UcV16UcV16Uc", "") +BUILTIN(__builtin_vsx_xxblendvh, "V8UsV8UsV8UsV8Us", "") +BUILTIN(__builtin_vsx_xxblendvw, "V4UiV4UiV4UiV4Ui", "") +BUILTIN(__builtin_vsx_xxblendvd, "V2ULLiV2ULLiV2ULLiV2ULLi", "") + // Float 128 built-ins BUILTIN(__builtin_sqrtf128_round_to_odd, "LLdLLd", "") BUILTIN(__builtin_addf128_round_to_odd, "LLdLLdLLd", "") @@ -470,6 +526,11 @@ BUILTIN(__builtin_divweu, "UiUiUi", "") BUILTIN(__builtin_divde, "SLLiSLLiSLLi", "") BUILTIN(__builtin_divdeu, "ULLiULLiULLi", "") BUILTIN(__builtin_bpermd, "SLLiSLLiSLLi", "") +BUILTIN(__builtin_pdepd, "ULLiULLiULLi", "") +BUILTIN(__builtin_pextd, "ULLiULLiULLi", "") +BUILTIN(__builtin_cfuged, "ULLiULLiULLi", "") +BUILTIN(__builtin_cntlzdm, "ULLiULLiULLi", "") +BUILTIN(__builtin_cnttzdm, "ULLiULLiULLi", "") // Vector int128 (un)pack BUILTIN(__builtin_unpack_vector_int128, "ULLiV1LLLii", "") diff --git a/clang/include/clang/Basic/BuiltinsSVE.def b/clang/include/clang/Basic/BuiltinsSVE.def new file mode 100644 index 000000000000..2839ca992d98 --- /dev/null +++ b/clang/include/clang/Basic/BuiltinsSVE.def @@ -0,0 +1,20 @@ +//===--- BuiltinsSVE.def - SVE Builtin function database --------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file defines the SVE-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. + +#define GET_SVE_BUILTINS +#include "clang/Basic/arm_sve_builtins.inc" +#undef GET_SVE_BUILTINS + +#undef BUILTIN diff --git a/clang/include/clang/Basic/BuiltinsWebAssembly.def b/clang/include/clang/Basic/BuiltinsWebAssembly.def index 38a2441b5fd4..ecee7782920f 100644 --- a/clang/include/clang/Basic/BuiltinsWebAssembly.def +++ b/clang/include/clang/Basic/BuiltinsWebAssembly.def @@ -25,10 +25,6 @@ BUILTIN(__builtin_wasm_memory_size, "zIi", "n") BUILTIN(__builtin_wasm_memory_grow, "zIiz", "n") -// Bulk memory builtins -TARGET_BUILTIN(__builtin_wasm_memory_init, "vIUiIUiv*UiUi", "", "bulk-memory") -TARGET_BUILTIN(__builtin_wasm_data_drop, "vIUi", "", "bulk-memory") - // Thread-local storage TARGET_BUILTIN(__builtin_wasm_tls_size, "z", "nc", "bulk-memory") TARGET_BUILTIN(__builtin_wasm_tls_align, "z", "nc", "bulk-memory") @@ -45,9 +41,9 @@ TARGET_BUILTIN(__builtin_wasm_throw, "vIUiv*", "r", "exception-handling") TARGET_BUILTIN(__builtin_wasm_rethrow_in_catch, "v", "r", "exception-handling") // Atomic wait and notify. -BUILTIN(__builtin_wasm_atomic_wait_i32, "ii*iLLi", "n") -BUILTIN(__builtin_wasm_atomic_wait_i64, "iLLi*LLiLLi", "n") -BUILTIN(__builtin_wasm_atomic_notify, "Uii*Ui", "n") +TARGET_BUILTIN(__builtin_wasm_atomic_wait_i32, "ii*iLLi", "n", "atomics") +TARGET_BUILTIN(__builtin_wasm_atomic_wait_i64, "iLLi*LLiLLi", "n", "atomics") +TARGET_BUILTIN(__builtin_wasm_atomic_notify, "Uii*Ui", "n", "atomics") // Trapping fp-to-int conversions BUILTIN(__builtin_wasm_trunc_s_i32_f32, "if", "nc") @@ -70,23 +66,23 @@ TARGET_BUILTIN(__builtin_wasm_trunc_saturate_s_i64_f64, "LLid", "nc", "nontrappi TARGET_BUILTIN(__builtin_wasm_trunc_saturate_u_i64_f64, "LLid", "nc", "nontrapping-fptoint") // SIMD builtins -TARGET_BUILTIN(__builtin_wasm_swizzle_v8x16, "V16cV16cV16c", "nc", "unimplemented-simd128") +TARGET_BUILTIN(__builtin_wasm_swizzle_v8x16, "V16cV16cV16c", "nc", "simd128") TARGET_BUILTIN(__builtin_wasm_extract_lane_s_i8x16, "iV16cIi", "nc", "simd128") -TARGET_BUILTIN(__builtin_wasm_extract_lane_u_i8x16, "iV16cIi", "nc", "unimplemented-simd128") +TARGET_BUILTIN(__builtin_wasm_extract_lane_u_i8x16, "iV16cIi", "nc", "simd128") TARGET_BUILTIN(__builtin_wasm_extract_lane_s_i16x8, "iV8sIi", "nc", "simd128") -TARGET_BUILTIN(__builtin_wasm_extract_lane_u_i16x8, "iV8sIi", "nc", "unimplemented-simd128") +TARGET_BUILTIN(__builtin_wasm_extract_lane_u_i16x8, "iV8sIi", "nc", "simd128") TARGET_BUILTIN(__builtin_wasm_extract_lane_i32x4, "iV4iIi", "nc", "simd128") -TARGET_BUILTIN(__builtin_wasm_extract_lane_i64x2, "LLiV2LLiIi", "nc", "unimplemented-simd128") +TARGET_BUILTIN(__builtin_wasm_extract_lane_i64x2, "LLiV2LLiIi", "nc", "simd128") TARGET_BUILTIN(__builtin_wasm_extract_lane_f32x4, "fV4fIi", "nc", "simd128") -TARGET_BUILTIN(__builtin_wasm_extract_lane_f64x2, "dV2dIi", "nc", "unimplemented-simd128") +TARGET_BUILTIN(__builtin_wasm_extract_lane_f64x2, "dV2dIi", "nc", "simd128") TARGET_BUILTIN(__builtin_wasm_replace_lane_i8x16, "V16cV16cIii", "nc", "simd128") TARGET_BUILTIN(__builtin_wasm_replace_lane_i16x8, "V8sV8sIii", "nc", "simd128") TARGET_BUILTIN(__builtin_wasm_replace_lane_i32x4, "V4iV4iIii", "nc", "simd128") -TARGET_BUILTIN(__builtin_wasm_replace_lane_i64x2, "V2LLiV2LLiIiLLi", "nc", "unimplemented-simd128") +TARGET_BUILTIN(__builtin_wasm_replace_lane_i64x2, "V2LLiV2LLiIiLLi", "nc", "simd128") TARGET_BUILTIN(__builtin_wasm_replace_lane_f32x4, "V4fV4fIif", "nc", "simd128") -TARGET_BUILTIN(__builtin_wasm_replace_lane_f64x2, "V2dV2dIid", "nc", "unimplemented-simd128") +TARGET_BUILTIN(__builtin_wasm_replace_lane_f64x2, "V2dV2dIid", "nc", "simd128") TARGET_BUILTIN(__builtin_wasm_add_saturate_s_i8x16, "V16cV16cV16c", "nc", "simd128") TARGET_BUILTIN(__builtin_wasm_add_saturate_u_i8x16, "V16cV16cV16c", "nc", "simd128") @@ -98,10 +94,28 @@ TARGET_BUILTIN(__builtin_wasm_sub_saturate_u_i8x16, "V16cV16cV16c", "nc", "simd1 TARGET_BUILTIN(__builtin_wasm_sub_saturate_s_i16x8, "V8sV8sV8s", "nc", "simd128") TARGET_BUILTIN(__builtin_wasm_sub_saturate_u_i16x8, "V8sV8sV8s", "nc", "simd128") -TARGET_BUILTIN(__builtin_wasm_avgr_u_i8x16, "V16cV16cV16c", "nc", "unimplemented-simd128") -TARGET_BUILTIN(__builtin_wasm_avgr_u_i16x8, "V8sV8sV8s", "nc", "unimplemented-simd128") +TARGET_BUILTIN(__builtin_wasm_abs_i8x16, "V16cV16c", "nc", "simd128") +TARGET_BUILTIN(__builtin_wasm_abs_i16x8, "V8sV8s", "nc", "simd128") +TARGET_BUILTIN(__builtin_wasm_abs_i32x4, "V4iV4i", "nc", "simd128") + +TARGET_BUILTIN(__builtin_wasm_min_s_i8x16, "V16cV16cV16c", "nc", "simd128") +TARGET_BUILTIN(__builtin_wasm_min_u_i8x16, "V16cV16cV16c", "nc", "simd128") +TARGET_BUILTIN(__builtin_wasm_max_s_i8x16, "V16cV16cV16c", "nc", "simd128") +TARGET_BUILTIN(__builtin_wasm_max_u_i8x16, "V16cV16cV16c", "nc", "simd128") +TARGET_BUILTIN(__builtin_wasm_min_s_i16x8, "V8sV8sV8s", "nc", "simd128") +TARGET_BUILTIN(__builtin_wasm_min_u_i16x8, "V8sV8sV8s", "nc", "simd128") +TARGET_BUILTIN(__builtin_wasm_max_s_i16x8, "V8sV8sV8s", "nc", "simd128") +TARGET_BUILTIN(__builtin_wasm_max_u_i16x8, "V8sV8sV8s", "nc", "simd128") +TARGET_BUILTIN(__builtin_wasm_min_s_i32x4, "V4iV4iV4i", "nc", "simd128") +TARGET_BUILTIN(__builtin_wasm_min_u_i32x4, "V4iV4iV4i", "nc", "simd128") +TARGET_BUILTIN(__builtin_wasm_max_s_i32x4, "V4iV4iV4i", "nc", "simd128") +TARGET_BUILTIN(__builtin_wasm_max_u_i32x4, "V4iV4iV4i", "nc", "simd128") + +TARGET_BUILTIN(__builtin_wasm_avgr_u_i8x16, "V16cV16cV16c", "nc", "simd128") +TARGET_BUILTIN(__builtin_wasm_avgr_u_i16x8, "V8sV8sV8s", "nc", "simd128") TARGET_BUILTIN(__builtin_wasm_bitselect, "V4iV4iV4iV4i", "nc", "simd128") +TARGET_BUILTIN(__builtin_wasm_shuffle_v8x16, "V16cV16cV16cIiIiIiIiIiIiIiIiIiIiIiIiIiIiIiIi", "nc", "simd128") TARGET_BUILTIN(__builtin_wasm_any_true_i8x16, "iV16c", "nc", "simd128") TARGET_BUILTIN(__builtin_wasm_any_true_i16x8, "iV8s", "nc", "simd128") @@ -112,28 +126,43 @@ TARGET_BUILTIN(__builtin_wasm_all_true_i16x8, "iV8s", "nc", "simd128") TARGET_BUILTIN(__builtin_wasm_all_true_i32x4, "iV4i", "nc", "simd128") TARGET_BUILTIN(__builtin_wasm_all_true_i64x2, "iV2LLi", "nc", "unimplemented-simd128") +TARGET_BUILTIN(__builtin_wasm_bitmask_i8x16, "iV16c", "nc", "simd128") +TARGET_BUILTIN(__builtin_wasm_bitmask_i16x8, "iV8s", "nc", "simd128") +TARGET_BUILTIN(__builtin_wasm_bitmask_i32x4, "iV4i", "nc", "simd128") + TARGET_BUILTIN(__builtin_wasm_abs_f32x4, "V4fV4f", "nc", "simd128") -TARGET_BUILTIN(__builtin_wasm_abs_f64x2, "V2dV2d", "nc", "unimplemented-simd128") +TARGET_BUILTIN(__builtin_wasm_abs_f64x2, "V2dV2d", "nc", "simd128") TARGET_BUILTIN(__builtin_wasm_min_f32x4, "V4fV4fV4f", "nc", "simd128") TARGET_BUILTIN(__builtin_wasm_max_f32x4, "V4fV4fV4f", "nc", "simd128") -TARGET_BUILTIN(__builtin_wasm_min_f64x2, "V2dV2dV2d", "nc", "unimplemented-simd128") -TARGET_BUILTIN(__builtin_wasm_max_f64x2, "V2dV2dV2d", "nc", "unimplemented-simd128") +TARGET_BUILTIN(__builtin_wasm_pmin_f32x4, "V4fV4fV4f", "nc", "simd128") +TARGET_BUILTIN(__builtin_wasm_pmax_f32x4, "V4fV4fV4f", "nc", "simd128") +TARGET_BUILTIN(__builtin_wasm_min_f64x2, "V2dV2dV2d", "nc", "simd128") +TARGET_BUILTIN(__builtin_wasm_max_f64x2, "V2dV2dV2d", "nc", "simd128") +TARGET_BUILTIN(__builtin_wasm_pmin_f64x2, "V2dV2dV2d", "nc", "simd128") +TARGET_BUILTIN(__builtin_wasm_pmax_f64x2, "V2dV2dV2d", "nc", "simd128") + +TARGET_BUILTIN(__builtin_wasm_ceil_f32x4, "V4fV4f", "nc", "simd128") +TARGET_BUILTIN(__builtin_wasm_floor_f32x4, "V4fV4f", "nc", "simd128") +TARGET_BUILTIN(__builtin_wasm_trunc_f32x4, "V4fV4f", "nc", "simd128") +TARGET_BUILTIN(__builtin_wasm_nearest_f32x4, "V4fV4f", "nc", "simd128") +TARGET_BUILTIN(__builtin_wasm_ceil_f64x2, "V2dV2d", "nc", "simd128") +TARGET_BUILTIN(__builtin_wasm_floor_f64x2, "V2dV2d", "nc", "simd128") +TARGET_BUILTIN(__builtin_wasm_trunc_f64x2, "V2dV2d", "nc", "simd128") +TARGET_BUILTIN(__builtin_wasm_nearest_f64x2, "V2dV2d", "nc", "simd128") TARGET_BUILTIN(__builtin_wasm_dot_s_i32x4_i16x8, "V4iV8sV8s", "nc", "simd128") -TARGET_BUILTIN(__builtin_wasm_sqrt_f32x4, "V4fV4f", "nc", "unimplemented-simd128") -TARGET_BUILTIN(__builtin_wasm_sqrt_f64x2, "V2dV2d", "nc", "unimplemented-simd128") +TARGET_BUILTIN(__builtin_wasm_sqrt_f32x4, "V4fV4f", "nc", "simd128") +TARGET_BUILTIN(__builtin_wasm_sqrt_f64x2, "V2dV2d", "nc", "simd128") -TARGET_BUILTIN(__builtin_wasm_qfma_f32x4, "V4fV4fV4fV4f", "nc", "simd128") -TARGET_BUILTIN(__builtin_wasm_qfms_f32x4, "V4fV4fV4fV4f", "nc", "simd128") +TARGET_BUILTIN(__builtin_wasm_qfma_f32x4, "V4fV4fV4fV4f", "nc", "unimplemented-simd128") +TARGET_BUILTIN(__builtin_wasm_qfms_f32x4, "V4fV4fV4fV4f", "nc", "unimplemented-simd128") TARGET_BUILTIN(__builtin_wasm_qfma_f64x2, "V2dV2dV2dV2d", "nc", "unimplemented-simd128") TARGET_BUILTIN(__builtin_wasm_qfms_f64x2, "V2dV2dV2dV2d", "nc", "unimplemented-simd128") TARGET_BUILTIN(__builtin_wasm_trunc_saturate_s_i32x4_f32x4, "V4iV4f", "nc", "simd128") TARGET_BUILTIN(__builtin_wasm_trunc_saturate_u_i32x4_f32x4, "V4iV4f", "nc", "simd128") -TARGET_BUILTIN(__builtin_wasm_trunc_saturate_s_i64x2_f64x2, "V2LLiV2d", "nc", "unimplemented-simd128") -TARGET_BUILTIN(__builtin_wasm_trunc_saturate_u_i64x2_f64x2, "V2LLiV2d", "nc", "unimplemented-simd128") TARGET_BUILTIN(__builtin_wasm_narrow_s_i8x16_i16x8, "V16cV8sV8s", "nc", "simd128") TARGET_BUILTIN(__builtin_wasm_narrow_u_i8x16_i16x8, "V16cV8sV8s", "nc", "simd128") diff --git a/clang/include/clang/Basic/BuiltinsX86.def b/clang/include/clang/Basic/BuiltinsX86.def index d6aa46de02f9..35fb98352ec2 100644 --- a/clang/include/clang/Basic/BuiltinsX86.def +++ b/clang/include/clang/Basic/BuiltinsX86.def @@ -1900,6 +1900,13 @@ TARGET_BUILTIN(__builtin_ia32_invpcid, "vUiv*", "nc", "invpcid") TARGET_BUILTIN(__builtin_ia32_enqcmd, "Ucv*vC*", "n", "enqcmd") TARGET_BUILTIN(__builtin_ia32_enqcmds, "Ucv*vC*", "n", "enqcmd") +// SERIALIZE +TARGET_BUILTIN(__builtin_ia32_serialize, "v", "n", "serialize") + +// TSXLDTRK +TARGET_BUILTIN(__builtin_ia32_xsusldtrk, "v", "n", "tsxldtrk") +TARGET_BUILTIN(__builtin_ia32_xresldtrk, "v", "n", "tsxldtrk") + // MSVC TARGET_HEADER_BUILTIN(_BitScanForward, "UcUNi*UNi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") TARGET_HEADER_BUILTIN(_BitScanReverse, "UcUNi*UNi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") @@ -1927,6 +1934,15 @@ TARGET_HEADER_BUILTIN(__readgsword, "UsUNi", "nh", "intrin.h", ALL_MS_LANGUAGES TARGET_HEADER_BUILTIN(__readgsdword, "UNiUNi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") TARGET_HEADER_BUILTIN(__readgsqword, "ULLiUNi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(_InterlockedAnd64, "WiWiD*Wi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(_InterlockedDecrement64, "WiWiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(_InterlockedExchange64, "WiWiD*Wi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd64, "WiWiD*Wi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(_InterlockedExchangeSub64, "WiWiD*Wi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(_InterlockedIncrement64, "WiWiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(_InterlockedOr64, "WiWiD*Wi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") +TARGET_HEADER_BUILTIN(_InterlockedXor64, "WiWiD*Wi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") + #undef BUILTIN #undef TARGET_BUILTIN #undef TARGET_HEADER_BUILTIN diff --git a/clang/include/clang/Basic/BuiltinsX86_64.def b/clang/include/clang/Basic/BuiltinsX86_64.def index c535f43203e5..f66ae78f7e81 100644 --- a/clang/include/clang/Basic/BuiltinsX86_64.def +++ b/clang/include/clang/Basic/BuiltinsX86_64.def @@ -33,14 +33,6 @@ TARGET_HEADER_BUILTIN(__faststorefence, "v", "nh", "intrin.h", ALL_MS_LANGUAGES, TARGET_HEADER_BUILTIN(__shiftleft128, "ULLiULLiULLiUc", "nch", "intrin.h", ALL_MS_LANGUAGES, "") TARGET_HEADER_BUILTIN(__shiftright128, "ULLiULLiULLiUc", "nch", "intrin.h", ALL_MS_LANGUAGES, "") -TARGET_HEADER_BUILTIN(_InterlockedAnd64, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") -TARGET_HEADER_BUILTIN(_InterlockedDecrement64, "LLiLLiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "") -TARGET_HEADER_BUILTIN(_InterlockedExchange64, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") -TARGET_HEADER_BUILTIN(_InterlockedExchangeAdd64, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") -TARGET_HEADER_BUILTIN(_InterlockedExchangeSub64, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") -TARGET_HEADER_BUILTIN(_InterlockedIncrement64, "LLiLLiD*", "nh", "intrin.h", ALL_MS_LANGUAGES, "") -TARGET_HEADER_BUILTIN(_InterlockedOr64, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") -TARGET_HEADER_BUILTIN(_InterlockedXor64, "LLiLLiD*LLi", "nh", "intrin.h", ALL_MS_LANGUAGES, "") TARGET_HEADER_BUILTIN(_InterlockedCompareExchange128, "UcLLiD*LLiLLiLLi*", "nh", "intrin.h", ALL_MS_LANGUAGES, "cx16") TARGET_BUILTIN(__builtin_ia32_readeflags_u64, "UOi", "n", "") @@ -101,6 +93,22 @@ TARGET_BUILTIN(__builtin_ia32_cvtsi2ss64, "V4fV4fOiIi", "ncV:128:", "avx512f") TARGET_BUILTIN(__builtin_ia32_cvtusi2sd64, "V2dV2dUOiIi", "ncV:128:", "avx512f") TARGET_BUILTIN(__builtin_ia32_cvtusi2ss64, "V4fV4fUOiIi", "ncV:128:", "avx512f") TARGET_BUILTIN(__builtin_ia32_directstore_u64, "vULi*ULi", "n", "movdiri") + +// AMX +TARGET_BUILTIN(__builtin_ia32_tile_loadconfig, "vvC*", "n", "amx-tile") +TARGET_BUILTIN(__builtin_ia32_tile_storeconfig, "vvC*", "n", "amx-tile") +TARGET_BUILTIN(__builtin_ia32_tilerelease, "v", "n", "amx-tile") +TARGET_BUILTIN(__builtin_ia32_tilezero, "vUc", "n", "amx-tile") + +TARGET_BUILTIN(__builtin_ia32_tileloadd64, "vIUcvC*z", "n", "amx-tile") +TARGET_BUILTIN(__builtin_ia32_tileloaddt164, "vIUcvC*z", "n", "amx-tile") +TARGET_BUILTIN(__builtin_ia32_tilestored64, "vIUcv*z", "n", "amx-tile") + +TARGET_BUILTIN(__builtin_ia32_tdpbssd, "vIUcIUcIUc", "n", "amx-int8") +TARGET_BUILTIN(__builtin_ia32_tdpbsud, "vIUcIUcIUc", "n", "amx-int8") +TARGET_BUILTIN(__builtin_ia32_tdpbusd, "vIUcIUcIUc", "n", "amx-int8") +TARGET_BUILTIN(__builtin_ia32_tdpbuud, "vIUcIUcIUc", "n", "amx-int8") +TARGET_BUILTIN(__builtin_ia32_tdpbf16ps, "vIUcIUcIUc", "n", "amx-bf16") TARGET_BUILTIN(__builtin_ia32_ptwrite64, "vUOi", "n", "ptwrite") #undef BUILTIN diff --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def index 50fc1836282f..c7e01eb12851 100644 --- a/clang/include/clang/Basic/CodeGenOptions.def +++ b/clang/include/clang/Basic/CodeGenOptions.def @@ -39,15 +39,15 @@ CODEGENOPT(ObjCAutoRefCountExceptions , 1, 0) ///< Whether ARC should be EH-safe CODEGENOPT(Backchain , 1, 0) ///< -mbackchain CODEGENOPT(ControlFlowGuardNoChecks , 1, 0) ///< -cfguard-no-checks CODEGENOPT(ControlFlowGuard , 1, 0) ///< -cfguard -CODEGENOPT(CoverageExtraChecksum, 1, 0) ///< Whether we need a second checksum for functions in GCNO files. -CODEGENOPT(CoverageNoFunctionNamesInData, 1, 0) ///< Do not include function names in GCDA files. -CODEGENOPT(CoverageExitBlockBeforeBody, 1, 0) ///< Whether to emit the exit block before the body blocks in GCNO files. CODEGENOPT(CXAAtExit , 1, 1) ///< Use __cxa_atexit for calling destructors. CODEGENOPT(RegisterGlobalDtorsWithAtExit, 1, 1) ///< Use atexit or __cxa_atexit to register global destructors. CODEGENOPT(CXXCtorDtorAliases, 1, 0) ///< Emit complete ctors/dtors as linker ///< aliases to base ctors when possible. CODEGENOPT(DataSections , 1, 0) ///< Set when -fdata-sections is enabled. CODEGENOPT(UniqueSectionNames, 1, 1) ///< Set for -funique-section-names. +CODEGENOPT(UniqueBasicBlockSectionNames, 1, 1) ///< Set for -funique-basic-block-section-names, + ///< Produce unique section names with + ///< basic block sections. ENUM_CODEGENOPT(FramePointer, FramePointerKind, 2, FramePointerKind::None) /// frame-pointer: all,non-leaf,none CODEGENOPT(DisableFree , 1, 0) ///< Don't free memory. @@ -58,12 +58,15 @@ CODEGENOPT(DisableLLVMPasses , 1, 0) ///< Don't run any LLVM IR passes to get ///< frontend. CODEGENOPT(DisableLifetimeMarkers, 1, 0) ///< Don't emit any lifetime markers CODEGENOPT(DisableO0ImplyOptNone , 1, 0) ///< Don't annonate function with optnone at O0 +CODEGENOPT(ExperimentalStrictFloatingPoint, 1, 0) ///< Enables the new, experimental + ///< strict floating point. CODEGENOPT(ExperimentalNewPassManager, 1, 0) ///< Enables the new, experimental ///< pass manager. CODEGENOPT(DebugPassManager, 1, 0) ///< Prints debug information for the new ///< pass manager. CODEGENOPT(DisableRedZone , 1, 0) ///< Set when -mno-red-zone is enabled. -CODEGENOPT(EnableDebugEntryValues, 1, 0) ///< Emit call site parameter dbg info +CODEGENOPT(EmitCallSiteInfo, 1, 0) ///< Emit call site info only in the case of + ///< '-g' + 'O>0' level. CODEGENOPT(IndirectTlsSegRefs, 1, 0) ///< Set when -mno-tls-direct-seg-refs ///< is specified. CODEGENOPT(DisableTailCalls , 1, 0) ///< Do not emit tail calls. @@ -106,11 +109,19 @@ CODEGENOPT(XRayAlwaysEmitCustomEvents , 1, 0) ///< Set when -fxray-always-emit-typedevents is enabled. CODEGENOPT(XRayAlwaysEmitTypedEvents , 1, 0) +///< Set when -fxray-ignore-loops is enabled. +CODEGENOPT(XRayIgnoreLoops , 1, 0) + +///< Set with -fno-xray-function-index to omit the index section. +CODEGENOPT(XRayOmitFunctionIndex , 1, 0) + + ///< Set the minimum number of instructions in a function to determine selective ///< XRay instrumentation. VALUE_CODEGENOPT(XRayInstructionThreshold , 32, 200) VALUE_CODEGENOPT(PatchableFunctionEntryCount , 32, 0) ///< Number of NOPs at function entry +VALUE_CODEGENOPT(PatchableFunctionEntryOffset , 32, 0) CODEGENOPT(InstrumentForProfiling , 1, 0) ///< Set when -pg is enabled. CODEGENOPT(CallFEntry , 1, 0) ///< Set when -mfentry is enabled. @@ -145,16 +156,11 @@ CODEGENOPT(NoWarn , 1, 0) ///< Set when -Wa,--no-warn is enabled. CODEGENOPT(EnableSegmentedStacks , 1, 0) ///< Set when -fsplit-stack is enabled. CODEGENOPT(NoInlineLineTables, 1, 0) ///< Whether debug info should contain ///< inline line tables. +CODEGENOPT(StackClashProtector, 1, 0) ///< Set when -fstack-clash-protection is enabled. CODEGENOPT(NoImplicitFloat , 1, 0) ///< Set when -mno-implicit-float is enabled. -CODEGENOPT(NoInfsFPMath , 1, 0) ///< Assume FP arguments, results not +-Inf. -CODEGENOPT(NoSignedZeros , 1, 0) ///< Allow ignoring the signedness of FP zero CODEGENOPT(NullPointerIsValid , 1, 0) ///< Assume Null pointer deference is defined. -CODEGENOPT(Reassociate , 1, 0) ///< Allow reassociation of FP math ops -CODEGENOPT(ReciprocalMath , 1, 0) ///< Allow FP divisions to be reassociated. -CODEGENOPT(NoTrappingMath , 1, 0) ///< Set when -fno-trapping-math is enabled. -CODEGENOPT(NoNaNsFPMath , 1, 0) ///< Assume FP arguments, results not NaN. -CODEGENOPT(FlushDenorm , 1, 0) ///< Allow FP denorm numbers to be flushed to zero CODEGENOPT(CorrectlyRoundedDivSqrt, 1, 0) ///< -cl-fp32-correctly-rounded-divide-sqrt +CODEGENOPT(UniqueInternalLinkageNames, 1, 0) ///< Internal Linkage symbols get unique names. /// When false, this attempts to generate code as if the result of an /// overflowing conversion matches the overflowing behavior of a target's native @@ -226,6 +232,7 @@ CODEGENOPT(SanitizeCoverageTracePC, 1, 0) ///< Enable PC tracing CODEGENOPT(SanitizeCoverageTracePCGuard, 1, 0) ///< Enable PC tracing with guard ///< in sanitizer coverage. CODEGENOPT(SanitizeCoverageInline8bitCounters, 1, 0) ///< Use inline 8bit counters. +CODEGENOPT(SanitizeCoverageInlineBoolFlag, 1, 0) ///< Use inline bool flag. CODEGENOPT(SanitizeCoveragePCTable, 1, 0) ///< Create a PC Table. CODEGENOPT(SanitizeCoverageNoPrune, 1, 0) ///< Disable coverage pruning. CODEGENOPT(SanitizeCoverageStackDepth, 1, 0) ///< Enable max stack depth tracing @@ -243,7 +250,6 @@ VALUE_CODEGENOPT(TimeTraceGranularity, 32, 500) ///< Minimum time granularity (i CODEGENOPT(UnrollLoops , 1, 0) ///< Control whether loops are unrolled. CODEGENOPT(RerollLoops , 1, 0) ///< Control whether loops are rerolled. CODEGENOPT(NoUseJumpTables , 1, 0) ///< Set when -fno-jump-tables is enabled. -CODEGENOPT(UnsafeFPMath , 1, 0) ///< Allow unsafe floating point optzns. CODEGENOPT(UnwindTables , 1, 0) ///< Emit unwind tables. CODEGENOPT(VectorizeLoop , 1, 0) ///< Run loop vectorizer. CODEGENOPT(VectorizeSLP , 1, 0) ///< Run SLP vectorizer. @@ -300,6 +306,9 @@ CODEGENOPT(LTOVisibilityPublicStd, 1, 0) /// or 0 if unspecified. VALUE_CODEGENOPT(NumRegisterParameters, 32, 0) +/// The threshold to put data into small data section. +VALUE_CODEGENOPT(SmallDataLimit, 32, 0) + /// The lower bound for a buffer to be considered for stack protection. VALUE_CODEGENOPT(SSPBufferSize, 32, 0) @@ -377,14 +386,12 @@ CODEGENOPT(ForceEmitVTables, 1, 0) /// Whether to emit an address-significance table into the object file. CODEGENOPT(Addrsig, 1, 0) -ENUM_CODEGENOPT(SignReturnAddress, SignReturnAddressScope, 2, SignReturnAddressScope::None) -ENUM_CODEGENOPT(SignReturnAddressKey, SignReturnAddressKeyValue, 1, SignReturnAddressKeyValue::AKey) -CODEGENOPT(BranchTargetEnforcement, 1, 0) - /// Whether to emit unused static constants. CODEGENOPT(KeepStaticConsts, 1, 0) +/// Whether to not follow the AAPCS that enforce at least one read before storing to a volatile bitfield +CODEGENOPT(ForceAAPCSBitfieldLoad, 1, 0) + #undef CODEGENOPT #undef ENUM_CODEGENOPT #undef VALUE_CODEGENOPT - diff --git a/clang/include/clang/Basic/CodeGenOptions.h b/clang/include/clang/Basic/CodeGenOptions.h index 21ac54e8ee12..83c4463c3639 100644 --- a/clang/include/clang/Basic/CodeGenOptions.h +++ b/clang/include/clang/Basic/CodeGenOptions.h @@ -110,13 +110,21 @@ public: Embed_Marker // Embed a marker as a placeholder for bitcode. }; - enum class SignReturnAddressScope { - None, // No signing for any function - NonLeaf, // Sign the return address of functions that spill LR - All // Sign the return address of all functions - }; - - enum class SignReturnAddressKeyValue { AKey, BKey }; + // This field stores one of the allowed values for the option + // -fbasic-block-sections=. The allowed values with this option are: + // {"labels", "all", "list=<file>", "none"}. + // + // "labels": Only generate basic block symbols (labels) for all basic + // blocks, do not generate unique sections for basic blocks. + // Use the machine basic block id in the symbol name to + // associate profile info from virtual address to machine + // basic block. + // "all" : Generate basic block sections for all basic blocks. + // "list=<file>": Generate basic block sections for a subset of basic blocks. + // The functions and the machine basic block ids are specified + // in the file. + // "none": Disable sections/labels for basic blocks. + std::string BBSections; enum class FramePointerKind { None, // Omit all frame pointers. @@ -164,7 +172,10 @@ public: std::string FloatABI; /// The floating-point denormal mode to use. - llvm::DenormalMode FPDenormalMode = llvm::DenormalMode::Invalid; + llvm::DenormalMode FPDenormalMode = llvm::DenormalMode::getIEEE(); + + /// The floating-point denormal mode to use, for float. + llvm::DenormalMode FP32DenormalMode = llvm::DenormalMode::getIEEE(); /// The float precision limit to use, if non-empty. std::string LimitFloatPrecision; @@ -311,6 +322,21 @@ public: /// List of dynamic shared object files to be loaded as pass plugins. std::vector<std::string> PassPlugins; + /// Path to allowlist file specifying which objects + /// (files, functions) should exclusively be instrumented + /// by sanitizer coverage pass. + std::vector<std::string> SanitizeCoverageAllowlistFiles; + + /// Path to blocklist file specifying which objects + /// (files, functions) listed for instrumentation by sanitizer + /// coverage pass should actually not be instrumented. + std::vector<std::string> SanitizeCoverageBlocklistFiles; + + /// Executable and command-line used to create a given CompilerInvocation. + /// Most of the time this will be the full -cc1 command. + const char *Argv0 = nullptr; + ArrayRef<const char *> CommandLineArgs; + public: // Define accessors/mutators for code generation options of enumeration type. #define CODEGENOPT(Name, Bits, Default) diff --git a/clang/include/clang/Basic/Cuda.h b/clang/include/clang/Basic/Cuda.h index ef5d24dcf888..1716325a9931 100644 --- a/clang/include/clang/Basic/Cuda.h +++ b/clang/include/clang/Basic/Cuda.h @@ -11,6 +11,7 @@ namespace llvm { class StringRef; +class Twine; class VersionTuple; } // namespace llvm @@ -26,11 +27,14 @@ enum class CudaVersion { CUDA_92, CUDA_100, CUDA_101, - LATEST = CUDA_101, + CUDA_102, + CUDA_110, + LATEST = CUDA_110, + LATEST_SUPPORTED = CUDA_101, }; const char *CudaVersionToString(CudaVersion V); // Input is "Major.Minor" -CudaVersion CudaStringToVersion(llvm::StringRef S); +CudaVersion CudaStringToVersion(const llvm::Twine &S); enum class CudaArch { UNKNOWN, @@ -49,6 +53,7 @@ enum class CudaArch { SM_70, SM_72, SM_75, + SM_80, GFX600, GFX601, GFX700, @@ -69,38 +74,23 @@ enum class CudaArch { GFX1010, GFX1011, GFX1012, + GFX1030, LAST, }; -const char *CudaArchToString(CudaArch A); -// The input should have the form "sm_20". -CudaArch StringToCudaArch(llvm::StringRef S); +static inline bool IsNVIDIAGpuArch(CudaArch A) { + return A >= CudaArch::SM_20 && A < CudaArch::GFX600; +} -enum class CudaVirtualArch { - UNKNOWN, - COMPUTE_20, - COMPUTE_30, - COMPUTE_32, - COMPUTE_35, - COMPUTE_37, - COMPUTE_50, - COMPUTE_52, - COMPUTE_53, - COMPUTE_60, - COMPUTE_61, - COMPUTE_62, - COMPUTE_70, - COMPUTE_72, - COMPUTE_75, - COMPUTE_AMDGCN, -}; -const char *CudaVirtualArchToString(CudaVirtualArch A); +static inline bool IsAMDGpuArch(CudaArch A) { + return A >= CudaArch::GFX600 && A < CudaArch::LAST; +} -// The input should have the form "compute_20". -CudaVirtualArch StringToCudaVirtualArch(llvm::StringRef S); +const char *CudaArchToString(CudaArch A); +const char *CudaArchToVirtualArchString(CudaArch A); -/// Get the compute_xx corresponding to an sm_yy. -CudaVirtualArch VirtualArchForCudaArch(CudaArch A); +// The input should have the form "sm_20". +CudaArch StringToCudaArch(llvm::StringRef S); /// Get the earliest CudaVersion that supports the given CudaArch. CudaVersion MinVersionForCudaArch(CudaArch A); @@ -116,6 +106,7 @@ enum class CudaFeature { CUDA_USES_FATBIN_REGISTER_END, }; +CudaVersion ToCudaVersion(llvm::VersionTuple); bool CudaFeatureEnabled(llvm::VersionTuple, CudaFeature); bool CudaFeatureEnabled(CudaVersion, CudaFeature); diff --git a/clang/include/clang/Basic/DeclNodes.td b/clang/include/clang/Basic/DeclNodes.td index c2c23237285b..866988ee3f01 100644 --- a/clang/include/clang/Basic/DeclNodes.td +++ b/clang/include/clang/Basic/DeclNodes.td @@ -40,6 +40,7 @@ def Named : DeclNode<Decl, "named declarations", 1>; def Binding : DeclNode<Value>; def OMPDeclareReduction : DeclNode<Value>, DeclContext; def OMPDeclareMapper : DeclNode<Value>, DeclContext; + def MSGuid : DeclNode<Value>; def Declarator : DeclNode<Value, "declarators", 1>; def Field : DeclNode<Declarator, "non-static data members">; def ObjCIvar : DeclNode<Field>; @@ -100,5 +101,6 @@ def OMPThreadPrivate : DeclNode<Decl>; def OMPAllocate : DeclNode<Decl>; def OMPRequires : DeclNode<Decl>; def Empty : DeclNode<Decl>; +def RequiresExprBody : DeclNode<Decl>, DeclContext; def LifetimeExtendedTemporary : DeclNode<Decl>; diff --git a/clang/include/clang/Basic/Diagnostic.h b/clang/include/clang/Basic/Diagnostic.h index ce996b615bba..304207779c0f 100644 --- a/clang/include/clang/Basic/Diagnostic.h +++ b/clang/include/clang/Basic/Diagnostic.h @@ -21,11 +21,11 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/IntrusiveRefCntPtr.h" +#include "llvm/ADT/Optional.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/iterator_range.h" #include "llvm/Support/Compiler.h" -#include "llvm/Support/Error.h" #include <cassert> #include <cstdint> #include <limits> @@ -37,6 +37,10 @@ #include <utility> #include <vector> +namespace llvm { +class Error; +} + namespace clang { class DeclContext; @@ -95,7 +99,7 @@ public: FixItHint Hint; Hint.RemoveRange = CharSourceRange::getCharRange(InsertionLoc, InsertionLoc); - Hint.CodeToInsert = Code; + Hint.CodeToInsert = std::string(Code); Hint.BeforePreviousInsertions = BeforePreviousInsertions; return Hint; } @@ -130,7 +134,7 @@ public: StringRef Code) { FixItHint Hint; Hint.RemoveRange = RemoveRange; - Hint.CodeToInsert = Code; + Hint.CodeToInsert = std::string(Code); return Hint; } @@ -1006,6 +1010,11 @@ protected: /// RAII class that determines when any errors have occurred /// between the time the instance was created and the time it was /// queried. +/// +/// Note that you almost certainly do not want to use this. It's usually +/// meaningless to ask whether a particular scope triggered an error message, +/// because error messages outside that scope can mark things invalid (or cause +/// us to reach an error limit), which can suppress errors within that scope. class DiagnosticErrorTrap { DiagnosticsEngine &Diag; unsigned NumErrors; @@ -1155,7 +1164,7 @@ public: assert(NumArgs < DiagnosticsEngine::MaxArguments && "Too many arguments to diagnostic!"); DiagObj->DiagArgumentsKind[NumArgs] = DiagnosticsEngine::ak_std_string; - DiagObj->DiagArgumentsStr[NumArgs++] = S; + DiagObj->DiagArgumentsStr[NumArgs++] = std::string(S); } void AddTaggedVal(intptr_t V, DiagnosticsEngine::ArgumentKind Kind) const { @@ -1177,7 +1186,7 @@ public: DiagObj->DiagFixItHints.push_back(Hint); } - void addFlagValue(StringRef V) const { DiagObj->FlagValue = V; } + void addFlagValue(StringRef V) const { DiagObj->FlagValue = std::string(V); } }; struct AddFlagValue { @@ -1217,9 +1226,7 @@ inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, int I) { // We use enable_if here to prevent that this overload is selected for // pointers or other arguments that are implicitly convertible to bool. template <typename T> -inline -typename std::enable_if<std::is_same<T, bool>::value, - const DiagnosticBuilder &>::type +inline std::enable_if_t<std::is_same<T, bool>::value, const DiagnosticBuilder &> operator<<(const DiagnosticBuilder &DB, T I) { DB.AddTaggedVal(I, DiagnosticsEngine::ak_sint); return DB; @@ -1249,9 +1256,9 @@ inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, // other arguments that derive from DeclContext (e.g., RecordDecls) will not // match. template <typename T> -inline typename std::enable_if< - std::is_same<typename std::remove_const<T>::type, DeclContext>::value, - const DiagnosticBuilder &>::type +inline std::enable_if_t< + std::is_same<std::remove_const_t<T>, DeclContext>::value, + const DiagnosticBuilder &> operator<<(const DiagnosticBuilder &DB, T *DC) { DB.AddTaggedVal(reinterpret_cast<intptr_t>(DC), DiagnosticsEngine::ak_declcontext); @@ -1290,6 +1297,29 @@ inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, return DB; } +inline const DiagnosticBuilder & +operator<<(const DiagnosticBuilder &DB, + const llvm::Optional<SourceRange> &Opt) { + if (Opt) + DB << *Opt; + return DB; +} + +inline const DiagnosticBuilder & +operator<<(const DiagnosticBuilder &DB, + const llvm::Optional<CharSourceRange> &Opt) { + if (Opt) + DB << *Opt; + return DB; +} + +inline const DiagnosticBuilder & +operator<<(const DiagnosticBuilder &DB, const llvm::Optional<FixItHint> &Opt) { + if (Opt) + DB << *Opt; + return DB; +} + /// A nullability kind paired with a bit indicating whether it used a /// context-sensitive keyword. using DiagNullabilityKind = std::pair<NullabilityKind, bool>; @@ -1307,11 +1337,8 @@ inline DiagnosticBuilder DiagnosticsEngine::Report(SourceLocation Loc, return DiagnosticBuilder(this); } -inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, - llvm::Error &&E) { - DB.AddString(toString(std::move(E))); - return DB; -} +const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, + llvm::Error &&E); inline DiagnosticBuilder DiagnosticsEngine::Report(unsigned DiagID) { return Report(SourceLocation(), DiagID); diff --git a/clang/include/clang/Basic/DiagnosticASTKinds.td b/clang/include/clang/Basic/DiagnosticASTKinds.td index 95505b00344f..10bedaaf7aba 100644 --- a/clang/include/clang/Basic/DiagnosticASTKinds.td +++ b/clang/include/clang/Basic/DiagnosticASTKinds.td @@ -13,7 +13,7 @@ def note_expr_divide_by_zero : Note<"division by zero">; def note_constexpr_invalid_cast : Note< "%select{reinterpret_cast|dynamic_cast|cast that performs the conversions of" " a reinterpret_cast|cast from %1}0 is not allowed in a constant expression" - "%select{| in C++ standards before C++2a||}0">; + "%select{| in C++ standards before C++20||}0">; def note_constexpr_invalid_downcast : Note< "cannot cast object of dynamic type %0 to type %1">; def note_constexpr_overflow : Note< @@ -33,7 +33,7 @@ def note_constexpr_no_return : Note< "control reached end of constexpr function">; def note_constexpr_virtual_call : Note< "cannot evaluate call to virtual function in a constant expression " - "in C++ standards before C++2a">; + "in C++ standards before C++20">; def note_constexpr_pure_virtual_call : Note< "pure virtual function %q0 called">; def note_constexpr_polymorphic_unknown_dynamic_type : Note< @@ -57,6 +57,9 @@ def note_constexpr_non_global : Note< def note_constexpr_dynamic_alloc : Note< "%select{pointer|reference}0 to %select{|subobject of }1" "heap-allocated object is not a constant expression">; +def note_consteval_address_accessible : Note< + "%select{pointer|reference}0 to a consteval declaration " + "is not a constant expression">; def note_constexpr_uninitialized : Note< "%select{|sub}0object of type %1 is not initialized">; def note_constexpr_subobject_declared_here : Note< @@ -98,11 +101,19 @@ def note_constexpr_null_subobject : Note< "access array element of|perform pointer arithmetic on|" "access real component of|" "access imaginary component of}0 null pointer">; +def note_constexpr_function_param_value_unknown : Note< + "function parameter %0 with unknown value cannot be used in a constant " + "expression">; +def note_constexpr_var_init_unknown : Note< + "initializer of %0 is unknown">; def note_constexpr_var_init_non_constant : Note< "initializer of %0 is not a constant expression">; +def note_constexpr_var_init_weak : Note< + "initializer of weak variable %0 is not considered constant because " + "it may be different at runtime">; def note_constexpr_typeid_polymorphic : Note< "typeid applied to expression of polymorphic type %0 is " - "not allowed in a constant expression in C++ standards before C++2a">; + "not allowed in a constant expression in C++ standards before C++20">; def note_constexpr_void_comparison : Note< "comparison between unequal pointers to void has unspecified result">; def note_constexpr_temporary_here : Note<"temporary created here">; @@ -156,6 +167,9 @@ def note_constexpr_access_mutable : Note< "mutable member %1 is not allowed in a constant expression">; def note_constexpr_ltor_non_const_int : Note< "read of non-const variable %0 is not allowed in a constant expression">; +def note_constexpr_ltor_non_integral : Note< + "read of variable %0 of non-integral, non-enumeration type %1 " + "is not allowed in a constant expression">; def note_constexpr_ltor_non_constexpr : Note< "read of non-constexpr variable %0 is not allowed in a constant expression">; def note_constexpr_ltor_incomplete_type : Note< @@ -183,6 +197,9 @@ def note_constexpr_access_inactive_union_member : Note< "construction of subobject of|destruction of}0 " "member %1 of union with %select{active member %3|no active member}2 " "is not allowed in a constant expression">; +def note_constexpr_union_member_change_during_init : Note< + "assignment would change active union member during the initialization of " + "a different member of the same union">; def note_constexpr_access_static_temporary : Note< "%select{read of|read of|assignment to|increment of|decrement of|" "member call on|dynamic_cast of|typeid applied to|reconstruction of|" @@ -238,6 +255,12 @@ def note_constexpr_unsupported_unsized_array : Note< def note_constexpr_unsized_array_indexed : Note< "indexing of array without known bound is not allowed " "in a constant expression">; +def note_constexpr_memcmp_unsupported : Note< + "constant evaluation of %0 between arrays of types %1 and %2 " + "is not supported; only arrays of narrow character types can be compared">; +def note_constexpr_memchr_unsupported : Note< + "constant evaluation of %0 on array of type %1 " + "is not supported; only arrays of narrow character types can be searched">; def note_constexpr_memcpy_null : Note< "%select{source|destination}2 of " "'%select{%select{memcpy|wmemcpy}1|%select{memmove|wmemmove}1}0' " @@ -326,12 +349,17 @@ def note_constexpr_delete_base_nonvirt_dtor : Note< def note_constexpr_memory_leak : Note< "allocation performed here was not deallocated" "%plural{0:|: (along with %0 other memory leak%s0)}0">; +def note_constexpr_unsupported_layout : Note< + "type %0 has unexpected layout">; def err_experimental_clang_interp_failed : Error< "the experimental clang interpreter failed to evaluate an expression">; def warn_integer_constant_overflow : Warning< "overflow in expression; result is %0 with type %1">, InGroup<DiagGroup<"integer-overflow">>; +def warn_fixedpoint_constant_overflow : Warning< + "overflow in expression; result is %0 with type %1">, + InGroup<DiagGroup<"fixed-point-overflow">>; // This is a temporary diagnostic, and shall be removed once our // implementation is complete, and like the preceding constexpr notes belongs diff --git a/clang/include/clang/Basic/DiagnosticCommonKinds.td b/clang/include/clang/Basic/DiagnosticCommonKinds.td index d6281f157eea..65e3755efd22 100644 --- a/clang/include/clang/Basic/DiagnosticCommonKinds.td +++ b/clang/include/clang/Basic/DiagnosticCommonKinds.td @@ -120,7 +120,7 @@ def err_enum_template : Error<"enumeration cannot be a template">; def warn_cxx20_compat_consteval : Warning< "'consteval' specifier is incompatible with C++ standards before C++20">, - InGroup<CXX2aCompat>, DefaultIgnore; + InGroup<CXX20Compat>, DefaultIgnore; } @@ -239,6 +239,18 @@ def note_invalid_subexpr_in_const_expr : Note< let CategoryName = "Inline Assembly Issue" in { def err_asm_invalid_type_in_input : Error< "invalid type %0 in asm input for constraint '%1'">; + + def err_asm_invalid_type : Error< + "invalid type %0 in asm %select{input|output}1">; + + def warn_stack_clash_protection_inline_asm : Warning< + "Unable to protect inline asm that clobbers stack pointer against stack clash">, + InGroup<DiagGroup<"stack-protector">>; + + def warn_slh_does_not_support_asm_goto + : Warning<"Speculative load hardening does not protect functions with " + "asm goto">, + InGroup<DiagGroup<"slh-asm-goto">>; } // Sema && Serialization @@ -282,6 +294,9 @@ def err_file_modified : Error< "file '%0' modified since it was first processed">, DefaultFatal; def err_file_too_large : Error< "sorry, unsupported: file '%0' is too large for Clang to process">; +def err_include_too_large : Error< + "sorry, this include generates a translation unit too large for" + " Clang to process.">, DefaultFatal; def err_unsupported_bom : Error<"%0 byte order mark detected in '%1', but " "encoding is not supported">, DefaultFatal; def err_unable_to_rename_temp : Error< diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td index 0fe14e4e05be..558639ecad6a 100644 --- a/clang/include/clang/Basic/DiagnosticDriverKinds.td +++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td @@ -50,16 +50,27 @@ def warn_drv_avr_stdlib_not_linked: Warning< InGroup<AVRRtlibLinkingQuirks>; def err_drv_cuda_bad_gpu_arch : Error<"Unsupported CUDA gpu architecture: %0">; def err_drv_no_cuda_installation : Error< - "cannot find CUDA installation. Provide its path via --cuda-path, or pass " + "cannot find CUDA installation. Provide its path via --cuda-path, or pass " "-nocudainc to build without CUDA includes.">; def err_drv_no_cuda_libdevice : Error< "cannot find libdevice for %0. Provide path to different CUDA installation " "via --cuda-path, or pass -nocudalib to build without linking with libdevice.">; + +def err_drv_no_rocm_device_lib : Error< + "cannot find ROCm device library%select{| for %1}0. Provide its path via --rocm-path or " + "--rocm-device-lib-path, or pass -nogpulib to build without ROCm device library.">; +def err_drv_no_hip_runtime : Error< + "cannot find HIP runtime. Provide its path via --rocm-path, or pass " + "-nogpuinc to build without HIP runtime.">; + def err_drv_cuda_version_unsupported : Error< "GPU arch %0 is supported by CUDA versions between %1 and %2 (inclusive), " - "but installation at %3 is %4. Use --cuda-path to specify a different CUDA " + "but installation at %3 is %4. Use --cuda-path to specify a different CUDA " "install, pass a different GPU arch with --cuda-gpu-arch, or pass " "--no-cuda-version-check.">; +def warn_drv_unknown_cuda_version: Warning< + "Unknown CUDA version %0. Assuming the latest supported version %1">, + InGroup<CudaUnknownVersion>; def err_drv_cuda_host_arch : Error<"unsupported architecture '%0' for host compilation.">; def err_drv_mix_cuda_hip : Error<"Mixed Cuda and HIP compilation is not supported.">; def err_drv_invalid_thread_model_for_target : Error< @@ -147,6 +158,10 @@ def err_drv_invalid_argument_to_option : Error< "invalid argument '%0' to -%1">; def err_drv_malformed_sanitizer_blacklist : Error< "malformed sanitizer blacklist: '%0'">; +def err_drv_malformed_sanitizer_coverage_whitelist : Error< + "malformed sanitizer coverage whitelist: '%0'">; +def err_drv_malformed_sanitizer_coverage_blacklist : Error< + "malformed sanitizer coverage blacklist: '%0'">; def err_drv_duplicate_config : Error< "no more than one option '--config' is allowed">; def err_drv_config_file_not_exist : Error< @@ -268,6 +283,9 @@ def warn_drv_unsupported_debug_info_opt_for_target : Warning< InGroup<UnsupportedTargetOpt>; def warn_c_kext : Warning< "ignoring -fapple-kext which is valid for C++ and Objective-C++ only">; +def warn_ignoring_fdiscard_for_bitcode : Warning< + "ignoring -fdiscard-value-names for LLVM Bitcode">, + InGroup<UnusedCommandLineArgument>; def warn_drv_input_file_unused : Warning< "%0: '%1' input unused%select{ when '%3' is present|}2">, InGroup<UnusedCommandLineArgument>; @@ -316,6 +334,8 @@ def warn_drv_object_size_disabled_O0 : Warning< InGroup<InvalidCommandLineArgument>, DefaultWarnNoWerror; def err_invalid_branch_protection: Error < "invalid branch protection option '%0' in '%1'">; +def err_invalid_sls_hardening : Error< + "invalid sls hardening option '%0' in '%1'">; def note_drv_command_failed_diag_msg : Note< "diagnostic msg: %0">; @@ -338,6 +358,8 @@ def err_analyzer_checker_option_unknown : Error< "checker '%0' has no option called '%1'">; def err_analyzer_checker_option_invalid_input : Error< "invalid input for checker option '%0', that expects %1">; +def err_analyzer_checker_incompatible_analyzer_option : Error< + "checker cannot be enabled with analyzer option '%0' == %1">; def err_drv_invalid_hvx_length : Error< "-mhvx-length is not supported without a -mhvx/-mhvx= flag">; @@ -371,6 +393,9 @@ def err_drv_ropi_incompatible_with_cxx : Error< def err_stack_tagging_requires_hardware_feature : Error< "'-fsanitize=memtag' requires hardware support (+memtag)">; +def err_cmse_pi_are_incompatible : Error< + "cmse is not compatible with %select{RWPI|ROPI}0">; + def warn_target_unsupported_nan2008 : Warning< "ignoring '-mnan=2008' option because the '%0' architecture does not support it">, InGroup<UnsupportedNan>; @@ -393,6 +418,9 @@ def warn_drv_unsupported_gpopt : Warning< "ignoring '-mgpopt' option as it cannot be used with %select{|the implicit" " usage of }0-mabicalls">, InGroup<UnsupportedGPOpt>; +def warn_drv_unsupported_sdata : Warning< + "ignoring '-msmall-data-limit=' with -mcmodel=large for -fpic or RV64">, + InGroup<OptionIgnored>; def warn_drv_unsupported_longcalls : Warning< "ignoring '-mlong-calls' option as it is not currently supported with " "%select{|the implicit usage of }0-mabicalls">, @@ -408,7 +436,7 @@ def err_drv_unsupported_indirect_jump_opt : Error< def err_drv_unknown_indirect_jump_opt : Error< "unknown '-mindirect-jump=' option '%0'">; def err_drv_unsupported_fpatchable_function_entry_argument : Error< - "the second argument of '-fpatchable-function-entry' must be 0 or omitted">; + "the second argument of '-fpatchable-function-entry' must be smaller than the first argument">; def warn_drv_unable_to_find_directory_expected : Warning< "unable to find %0 directory, expected to be in '%1'">, @@ -438,13 +466,13 @@ def note_drv_verify_prefix_spelling : Note< "-verify prefixes must start with a letter and contain only alphanumeric" " characters, hyphens, and underscores">; -def warn_drv_experimental_isel_incomplete : Warning< - "-fexperimental-isel support for the '%0' architecture is incomplete">, - InGroup<ExperimentalISel>; +def warn_drv_global_isel_incomplete : Warning< + "-fglobal-isel support for the '%0' architecture is incomplete">, + InGroup<GlobalISel>; -def warn_drv_experimental_isel_incomplete_opt : Warning< - "-fexperimental-isel support is incomplete for this architecture at the current optimization level">, - InGroup<ExperimentalISel>; +def warn_drv_global_isel_incomplete_opt : Warning< + "-fglobal-isel support is incomplete for this architecture at the current optimization level">, + InGroup<GlobalISel>; def warn_drv_moutline_unsupported_opt : Warning< "The '%0' architecture does not support -moutline; flag ignored">, @@ -458,6 +486,12 @@ def err_drv_trivial_auto_var_init_zero_disabled : Error< "-ftrivial-auto-var-init=zero hasn't been enabled. Enable it at your own peril for benchmarking purpose only with " "-enable-trivial-auto-var-init-zero-knowing-it-will-be-removed-from-clang">; +def err_drv_trivial_auto_var_init_stop_after_missing_dependency : Error< + "-ftrivial-auto-var-init-stop-after=* is used without -ftrivial-auto-var-init=zero or -ftrivial-auto-var-init=pattern.">; + +def err_drv_trivial_auto_var_init_stop_after_invalid_value : Error< + "-ftrivial-auto-var-init-stop-after=* only accepts positive integers.">; + def warn_drv_msp430_hwmult_unsupported : Warning<"the given MCU does not " "support hardware multiply, but -mhwmult is set to %0.">, InGroup<InvalidCommandLineArgument>; @@ -475,4 +509,6 @@ def warn_drv_libstdcxx_not_found : Warning< InGroup<DiagGroup<"stdlibcxx-not-found">>; def err_drv_cannot_mix_options : Error<"cannot specify '%1' along with '%0'">; + +def err_drv_invalid_object_mode : Error<"OBJECT_MODE setting %0 is not recognized and is not a valid setting.">; } diff --git a/clang/include/clang/Basic/DiagnosticFrontendKinds.td b/clang/include/clang/Basic/DiagnosticFrontendKinds.td index a798b498d4e9..b202d2abffa0 100644 --- a/clang/include/clang/Basic/DiagnosticFrontendKinds.td +++ b/clang/include/clang/Basic/DiagnosticFrontendKinds.td @@ -37,6 +37,12 @@ def note_fe_backend_plugin: Note<"%0">, BackendInfo; def warn_fe_override_module : Warning< "overriding the module target triple with %0">, InGroup<DiagGroup<"override-module">>; +def warn_fe_backend_unsupported_fp_rounding : Warning< + "overriding currently unsupported rounding mode on this target">, + InGroup<UnsupportedFPOpt>; +def warn_fe_backend_unsupported_fp_exceptions : Warning< + "overriding currently unsupported use of floating point exceptions " + "on this target">, InGroup<UnsupportedFPOpt>; def remark_fe_backend_optimization_remark : Remark<"%0">, BackendInfo, InGroup<BackendOptimizationRemark>; @@ -61,6 +67,7 @@ def note_fe_backend_invalid_loc : Note<"could " "not determine the original source location for %0:%1:%2">, BackendInfo; def err_fe_backend_unsupported : Error<"%0">, BackendInfo; +def warn_fe_backend_unsupported : Warning<"%0">, BackendInfo; def err_fe_invalid_code_complete_file : Error< "cannot locate code-completion file %0">, DefaultFatal; @@ -105,6 +112,12 @@ def err_fe_invalid_wchar_type : Error<"invalid wchar_t type '%0'; must be one of 'char', 'short', 'int'">; def err_fe_invalid_exception_model : Error<"invalid exception model '%0' for target '%1'">; +def warn_fe_concepts_ts_flag : Warning< + "-fconcepts-ts is deprecated - use '-std=c++20' for Concepts support">, + InGroup<Deprecated>; + +def err_fe_unable_to_load_basic_block_sections_file : Error< + "unable to load basic block sections function list: '%0'">; def warn_fe_serialized_diag_merge_failure : Warning< "unable to merge a subprocess's serialized diagnostics">, @@ -112,6 +125,9 @@ def warn_fe_serialized_diag_merge_failure : Warning< def warn_fe_serialized_diag_failure : Warning< "unable to open file %0 for serializing diagnostics (%1)">, InGroup<SerializedDiagnostics>; +def warn_fe_serialized_diag_failure_during_finalisation : Warning< + "Received warning after diagnostic serialization teardown was underway: %0">, + InGroup<SerializedDiagnostics>; def err_verify_missing_line : Error< "missing or invalid line number following '@' in expected %0">; @@ -172,9 +188,9 @@ def note_incompatible_analyzer_plugin_api : Note< def err_module_build_requires_fmodules : Error< "module compilation requires '-fmodules'">; def err_module_interface_requires_cpp_modules : Error< - "module interface compilation requires '-std=c++2a' or '-fmodules-ts'">; + "module interface compilation requires '-std=c++20' or '-fmodules-ts'">; def err_header_module_requires_modules : Error< - "header module compilation requires '-fmodules', '-std=c++2a', or " + "header module compilation requires '-fmodules', '-std=c++20', or " "'-fmodules-ts'">; def warn_module_config_mismatch : Warning< "module file %0 cannot be loaded due to a configuration mismatch with the current " @@ -233,6 +249,12 @@ 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_avx_calling_convention + : Warning<"AVX vector %select{return|argument}0 of type %1 without '%2' " + "enabled changes the ABI">, + InGroup<DiagGroup<"psabi">>; +def err_avx_calling_convention : Error<warn_avx_calling_convention.Text>; + def err_alias_to_undefined : Error< "%select{alias|ifunc}0 must point to a defined " "%select{variable or |}1function">; diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td index a15fb908c537..1e829be4028e 100644 --- a/clang/include/clang/Basic/DiagnosticGroups.td +++ b/clang/include/clang/Basic/DiagnosticGroups.td @@ -60,6 +60,7 @@ def UndefinedBoolConversion : DiagGroup<"undefined-bool-conversion">; def BoolConversion : DiagGroup<"bool-conversion", [PointerBoolConversion, UndefinedBoolConversion]>; def IntConversion : DiagGroup<"int-conversion">; +def ClassConversion: DiagGroup<"class-conversion">; def DeprecatedEnumCompareConditional : DiagGroup<"deprecated-enum-compare-conditional">; def EnumCompareConditional : DiagGroup<"enum-compare-conditional", @@ -85,7 +86,9 @@ def ObjCSignedCharBoolImplicitIntConversion : DiagGroup<"objc-signed-char-bool-implicit-int-conversion">; def ImplicitIntConversion : DiagGroup<"implicit-int-conversion", [ObjCSignedCharBoolImplicitIntConversion]>; -def ImplicitIntFloatConversion : DiagGroup<"implicit-int-float-conversion">; +def ImplicitConstIntFloatConversion : DiagGroup<"implicit-const-int-float-conversion">; +def ImplicitIntFloatConversion : DiagGroup<"implicit-int-float-conversion", + [ImplicitConstIntFloatConversion]>; def ObjCSignedCharBoolImplicitFloatConversion : DiagGroup<"objc-signed-char-bool-implicit-float-conversion">; def ImplicitFloatConversion : DiagGroup<"implicit-float-conversion", @@ -99,10 +102,12 @@ def FloatConversion : DiagGroup<"float-conversion", [FloatOverflowConversion, FloatZeroConversion]>; +def FrameAddress : DiagGroup<"frame-address">; def DoublePromotion : DiagGroup<"double-promotion">; def EnumTooLarge : DiagGroup<"enum-too-large">; def UnsupportedNan : DiagGroup<"unsupported-nan">; def UnsupportedAbs : DiagGroup<"unsupported-abs">; +def UnsupportedFPOpt : DiagGroup<"unsupported-floating-point-opt">; def UnsupportedCB : DiagGroup<"unsupported-cb">; def UnsupportedGPOpt : DiagGroup<"unsupported-gpopt">; def UnsupportedTargetOpt : DiagGroup<"unsupported-target-opt">; @@ -187,11 +192,12 @@ def Deprecated : DiagGroup<"deprecated", [DeprecatedAnonEnumEnumConversion, DeprecatedWritableStr]>, DiagCategory<"Deprecations">; -def CXX2aDesignator : DiagGroup<"c++2a-designator">; +def CXX20Designator : DiagGroup<"c++20-designator">; // Allow -Wno-c99-designator to be used to turn off all warnings on valid C99 -// designators (including the warning controlled by -Wc++2a-designator). -def C99Designator : DiagGroup<"c99-designator", [CXX2aDesignator]>; +// designators (including the warning controlled by -Wc++20-designator). +def C99Designator : DiagGroup<"c99-designator", [CXX20Designator]>; def GNUDesignator : DiagGroup<"gnu-designator">; +def DtorName : DiagGroup<"dtor-name">; def DynamicExceptionSpec : DiagGroup<"dynamic-exception-spec", [DeprecatedDynamicExceptionSpec]>; @@ -246,9 +252,9 @@ def CXXPre14CompatPedantic : DiagGroup<"c++98-c++11-compat-pedantic", def CXXPre17Compat : DiagGroup<"c++98-c++11-c++14-compat">; def CXXPre17CompatPedantic : DiagGroup<"c++98-c++11-c++14-compat-pedantic", [CXXPre17Compat]>; -def CXXPre2aCompat : DiagGroup<"c++98-c++11-c++14-c++17-compat">; -def CXXPre2aCompatPedantic : DiagGroup<"c++98-c++11-c++14-c++17-compat-pedantic", - [CXXPre2aCompat]>; +def CXXPre20Compat : DiagGroup<"c++98-c++11-c++14-c++17-compat">; +def CXXPre20CompatPedantic : DiagGroup<"c++98-c++11-c++14-c++17-compat-pedantic", + [CXXPre20Compat]>; def CXX98CompatBindToTemporaryCopy : DiagGroup<"c++98-compat-bind-to-temporary-copy">; @@ -262,7 +268,7 @@ def CXX98Compat : DiagGroup<"c++98-compat", CXX98CompatUnnamedTypeTemplateArgs, CXXPre14Compat, CXXPre17Compat, - CXXPre2aCompat]>; + CXXPre20Compat]>; // Warnings for C++11 features which are Extensions in C++98 mode. def CXX98CompatPedantic : DiagGroup<"c++98-compat-pedantic", [CXX98Compat, @@ -270,13 +276,16 @@ def CXX98CompatPedantic : DiagGroup<"c++98-compat-pedantic", CXX98CompatExtraSemi, CXXPre14CompatPedantic, CXXPre17CompatPedantic, - CXXPre2aCompatPedantic]>; + CXXPre20CompatPedantic]>; def CXX11Narrowing : DiagGroup<"c++11-narrowing">; -def CXX11WarnOverrideDestructor : +def CXX11WarnInconsistentOverrideDestructor : DiagGroup<"inconsistent-missing-destructor-override">; -def CXX11WarnOverrideMethod : DiagGroup<"inconsistent-missing-override">; +def CXX11WarnInconsistentOverrideMethod : + DiagGroup<"inconsistent-missing-override">; +def CXX11WarnSuggestOverrideDestructor : DiagGroup<"suggest-destructor-override">; +def CXX11WarnSuggestOverride : DiagGroup<"suggest-override">; // Original name of this warning in Clang def : DiagGroup<"c++0x-narrowing", [CXX11Narrowing]>; @@ -296,33 +305,35 @@ def CXX11Compat : DiagGroup<"c++11-compat", CXX11CompatDeprecatedWritableStr, CXXPre14Compat, CXXPre17Compat, - CXXPre2aCompat]>; + CXXPre20Compat]>; def : DiagGroup<"c++0x-compat", [CXX11Compat]>; def CXX11CompatPedantic : DiagGroup<"c++11-compat-pedantic", [CXX11Compat, CXXPre14CompatPedantic, CXXPre17CompatPedantic, - CXXPre2aCompatPedantic]>; + CXXPre20CompatPedantic]>; def CXX14Compat : DiagGroup<"c++14-compat", [CXXPre17Compat, - CXXPre2aCompat]>; + CXXPre20Compat]>; def CXX14CompatPedantic : DiagGroup<"c++14-compat-pedantic", [CXX14Compat, CXXPre17CompatPedantic, - CXXPre2aCompatPedantic]>; + CXXPre20CompatPedantic]>; def CXX17Compat : DiagGroup<"c++17-compat", [DeprecatedRegister, DeprecatedIncrementBool, CXX17CompatMangling, - CXXPre2aCompat]>; + CXXPre20Compat]>; def CXX17CompatPedantic : DiagGroup<"c++17-compat-pedantic", [CXX17Compat, - CXXPre2aCompatPedantic]>; + CXXPre20CompatPedantic]>; def : DiagGroup<"c++1z-compat", [CXX17Compat]>; -def CXX2aCompat : DiagGroup<"c++2a-compat">; -def CXX2aCompatPedantic : DiagGroup<"c++2a-compat-pedantic", - [CXX2aCompat]>; +def CXX20Compat : DiagGroup<"c++20-compat">; +def CXX20CompatPedantic : DiagGroup<"c++20-compat-pedantic", + [CXX20Compat]>; +def : DiagGroup<"c++2a-compat", [CXX20Compat]>; +def : DiagGroup<"c++2a-compat-pedantic", [CXX20CompatPedantic]>; def ExitTimeDestructors : DiagGroup<"exit-time-destructors">; def FlexibleArrayExtensions : DiagGroup<"flexible-array-extensions">; @@ -344,6 +355,7 @@ def Dangling : DiagGroup<"dangling", [DanglingField, DanglingGsl, ReturnStackAddress]>; def DistributedObjectModifiers : DiagGroup<"distributed-object-modifiers">; +def ExcessInitializers : DiagGroup<"excess-initializers">; def ExpansionToDefined : DiagGroup<"expansion-to-defined">; def FlagEnum : DiagGroup<"flag-enum">; def IncrementBool : DiagGroup<"increment-bool", [DeprecatedIncrementBool]>; @@ -374,6 +386,8 @@ def IncompleteModule : DiagGroup<"incomplete-module", def PrivateModule : DiagGroup<"private-module">; def CXX11InlineNamespace : DiagGroup<"c++11-inline-namespace">; +def InlineNamespaceReopenedNoninline + : DiagGroup<"inline-namespace-reopened-noninline">; def InvalidNoreturn : DiagGroup<"invalid-noreturn">; def InvalidSourceEncoding : DiagGroup<"invalid-source-encoding">; def KNRPromotedParameter : DiagGroup<"knr-promoted-parameter">; @@ -384,7 +398,10 @@ def GNULabelsAsValue : DiagGroup<"gnu-label-as-value">; def LiteralRange : DiagGroup<"literal-range">; def LocalTypeTemplateArgs : DiagGroup<"local-type-template-args", [CXX98CompatLocalTypeTemplateArgs]>; -def RangeLoopAnalysis : DiagGroup<"range-loop-analysis">; +def RangeLoopConstruct : DiagGroup<"range-loop-construct">; +def RangeLoopBindReference : DiagGroup<"range-loop-bind-reference">; +def RangeLoopAnalysis : DiagGroup<"range-loop-analysis", + [RangeLoopConstruct, RangeLoopBindReference]>; def ForLoopAnalysis : DiagGroup<"for-loop-analysis">; def LoopAnalysis : DiagGroup<"loop-analysis", [ForLoopAnalysis, RangeLoopAnalysis]>; @@ -614,8 +631,10 @@ def Unicode : DiagGroup<"unicode">; def UninitializedMaybe : DiagGroup<"conditional-uninitialized">; def UninitializedSometimes : DiagGroup<"sometimes-uninitialized">; def UninitializedStaticSelfInit : DiagGroup<"static-self-init">; +def UninitializedConstReference : DiagGroup<"uninitialized-const-reference">; def Uninitialized : DiagGroup<"uninitialized", [UninitializedSometimes, - UninitializedStaticSelfInit]>; + UninitializedStaticSelfInit, + UninitializedConstReference]>; def IgnoredPragmaIntrinsic : DiagGroup<"ignored-pragma-intrinsic">; // #pragma optimize is often used to avoid to work around MSVC codegen bugs or // to disable inlining. It's not completely clear what alternative to suggest @@ -832,6 +851,13 @@ def IncompatibleExceptionSpec : DiagGroup<"incompatible-exception-spec">; def IntToVoidPointerCast : DiagGroup<"int-to-void-pointer-cast">; def IntToPointerCast : DiagGroup<"int-to-pointer-cast", [IntToVoidPointerCast]>; +def VoidPointerToEnumCast : DiagGroup<"void-pointer-to-enum-cast">; +def VoidPointerToIntCast : DiagGroup<"void-pointer-to-int-cast", + [VoidPointerToEnumCast]>; +def PointerToEnumCast : DiagGroup<"pointer-to-enum-cast", + [VoidPointerToEnumCast]>; +def PointerToIntCast : DiagGroup<"pointer-to-int-cast", + [PointerToEnumCast, VoidPointerToIntCast]>; def Move : DiagGroup<"move", [ PessimizingMove, @@ -858,14 +884,16 @@ def Most : DiagGroup<"most", [ Comment, DeleteNonVirtualDtor, Format, + ForLoopAnalysis, + FrameAddress, Implicit, InfiniteRecursion, IntInBoolContext, - LoopAnalysis, MismatchedTags, MissingBraces, Move, MultiChar, + RangeLoopConstruct, Reorder, ReturnType, SelfAssignment, @@ -951,13 +979,14 @@ def CXX14 : DiagGroup<"c++14-extensions", [CXX14BinaryLiteral]>; // earlier C++ versions. def CXX17 : DiagGroup<"c++17-extensions">; -// A warning group for warnings about using C++2a features as extensions in +// A warning group for warnings about using C++20 features as extensions in // earlier C++ versions. -def CXX2a : DiagGroup<"c++2a-extensions", [CXX2aDesignator]>; +def CXX20 : DiagGroup<"c++20-extensions", [CXX20Designator]>; def : DiagGroup<"c++0x-extensions", [CXX11]>; def : DiagGroup<"c++1y-extensions", [CXX14]>; def : DiagGroup<"c++1z-extensions", [CXX17]>; +def : DiagGroup<"c++2a-extensions", [CXX20]>; def DelegatingCtorCycles : DiagGroup<"delegating-ctor-cycles">; @@ -968,6 +997,9 @@ def C11 : DiagGroup<"c11-extensions">; // A warning group for warnings about using C99 features as extensions. def C99 : DiagGroup<"c99-extensions", [C99Designator]>; +// A warning group for warnings about using C2x features as extensions. +def C2x : DiagGroup<"c2x-extensions">; + // A warning group for warnings about GCC extensions. def GNU : DiagGroup<"gnu", [GNUAlignofExpression, GNUAnonymousStruct, GNUAutoType, @@ -1007,7 +1039,8 @@ def MicrosoftExplicitConstructorCall : DiagGroup< def MicrosoftEnumValue : DiagGroup<"microsoft-enum-value">; def MicrosoftDefaultArgRedefinition : DiagGroup<"microsoft-default-arg-redefinition">; -def MicrosoftTemplate : DiagGroup<"microsoft-template">; +def MicrosoftTemplateShadow : DiagGroup<"microsoft-template-shadow">; +def MicrosoftTemplate : DiagGroup<"microsoft-template", [MicrosoftTemplateShadow]>; def MicrosoftInconsistentDllImport : DiagGroup<"inconsistent-dllimport">; def MicrosoftRedeclareStatic : DiagGroup<"microsoft-redeclare-static">; def MicrosoftEnumForwardReference : @@ -1070,11 +1103,15 @@ def ObjCSignedCharBool : DiagGroup<"objc-signed-char-bool", ObjCBoolConstantConversion, TautologicalObjCBoolCompare]>; +def ObjCPotentiallyDirectSelector : DiagGroup<"potentially-direct-selector">; +def ObjCStrictPotentiallyDirectSelector : + DiagGroup<"strict-potentially-direct-selector", + [ObjCPotentiallyDirectSelector]>; + // Inline ASM warnings. def ASMOperandWidths : DiagGroup<"asm-operand-widths">; -def ASMIgnoredQualifier : DiagGroup<"asm-ignored-qualifier">; def ASM : DiagGroup<"asm", [ - ASMOperandWidths, ASMIgnoredQualifier + ASMOperandWidths ]>; // OpenMP warnings. @@ -1113,6 +1150,9 @@ def SerializedDiagnostics : DiagGroup<"serialized-diagnostics">; // compiling CUDA C/C++ but which is not compatible with the CUDA spec. def CudaCompat : DiagGroup<"cuda-compat">; +// Warning about unknown CUDA SDK version. +def CudaUnknownVersion: DiagGroup<"unknown-cuda-version">; + // A warning group for warnings about features supported by HIP but // ignored by CUDA. def HIPOnly : DiagGroup<"hip-only">; @@ -1134,8 +1174,8 @@ def UnknownArgument : DiagGroup<"unknown-argument">; // compiling OpenCL C/C++ but which is not compatible with the SPIR spec. def SpirCompat : DiagGroup<"spir-compat">; -// Warning for the experimental-isel options. -def ExperimentalISel : DiagGroup<"experimental-isel">; +// Warning for the GlobalISel options. +def GlobalISel : DiagGroup<"global-isel">; // A warning group specifically for warnings related to function // multiversioning. @@ -1149,3 +1189,37 @@ def CrossTU : DiagGroup<"ctu">; def CTADMaybeUnsupported : DiagGroup<"ctad-maybe-unsupported">; def FortifySource : DiagGroup<"fortify-source">; + +def MaxTokens : DiagGroup<"max-tokens"> { + code Documentation = [{ +The warning is issued if the number of pre-processor tokens exceeds +the token limit, which can be set in three ways: + +1. As a limit at a specific point in a file, using the ``clang max_tokens_here`` + pragma: + + .. code-block: c++ + #pragma clang max_tokens_here 1234 + +2. As a per-translation unit limit, using the ``-fmax-tokens=`` command-line + flag: + + .. code-block: console + clang -c a.cpp -fmax-tokens=1234 + +3. As a per-translation unit limit using the ``clang max_tokens_total`` pragma, + which works like and overrides the ``-fmax-tokens=`` flag: + + .. code-block: c++ + #pragma clang max_tokens_total 1234 + +These limits can be helpful in limiting code growth through included files. + +Setting a token limit of zero means no limit. + +Note that the warning is disabled by default, so -Wmax-tokens must be used +in addition with the pragmas or -fmax-tokens flag to get any warnings. +}]; +} + +def WebAssemblyExceptionSpec : DiagGroup<"wasm-exception-spec">; diff --git a/clang/include/clang/Basic/DiagnosticIDs.h b/clang/include/clang/Basic/DiagnosticIDs.h index 5b9391b5a452..00c939650e54 100644 --- a/clang/include/clang/Basic/DiagnosticIDs.h +++ b/clang/include/clang/Basic/DiagnosticIDs.h @@ -28,12 +28,12 @@ namespace clang { // Size of each of the diagnostic categories. enum { DIAG_SIZE_COMMON = 300, - DIAG_SIZE_DRIVER = 200, + DIAG_SIZE_DRIVER = 250, DIAG_SIZE_FRONTEND = 150, DIAG_SIZE_SERIALIZATION = 120, DIAG_SIZE_LEX = 400, DIAG_SIZE_PARSE = 600, - DIAG_SIZE_AST = 200, + DIAG_SIZE_AST = 250, DIAG_SIZE_COMMENT = 100, DIAG_SIZE_CROSSTU = 100, DIAG_SIZE_SEMA = 4000, diff --git a/clang/include/clang/Basic/DiagnosticLexKinds.td b/clang/include/clang/Basic/DiagnosticLexKinds.td index b64cbc23f810..9cb06cf5b5e1 100644 --- a/clang/include/clang/Basic/DiagnosticLexKinds.td +++ b/clang/include/clang/Basic/DiagnosticLexKinds.td @@ -31,12 +31,12 @@ def warn_cxx98_compat_less_colon_colon : Warning< InGroup<CXX98Compat>, DefaultIgnore; def warn_cxx17_compat_spaceship : Warning< - "'<=>' operator is incompatible with C++ standards before C++2a">, - InGroup<CXXPre2aCompat>, DefaultIgnore; -def warn_cxx2a_compat_spaceship : Warning< - "'<=>' is a single token in C++2a; " + "'<=>' operator is incompatible with C++ standards before C++20">, + InGroup<CXXPre20Compat>, DefaultIgnore; +def warn_cxx20_compat_spaceship : Warning< + "'<=>' is a single token in C++20; " "add a space to avoid a change in behavior">, - InGroup<CXX2aCompat>; + InGroup<CXX20Compat>; // Trigraphs. def trigraph_ignored : Warning<"trigraph ignored">, InGroup<Trigraphs>; @@ -78,8 +78,8 @@ def ext_token_used : Extension<"extension used">, def warn_cxx11_keyword : Warning<"'%0' is a keyword in C++11">, InGroup<CXX11Compat>, DefaultIgnore; -def warn_cxx2a_keyword : Warning<"'%0' is a keyword in C++2a">, - InGroup<CXX2aCompat>, DefaultIgnore; +def warn_cxx20_keyword : Warning<"'%0' is a keyword in C++20">, + InGroup<CXX20Compat>, DefaultIgnore; def ext_unterminated_char_or_string : ExtWarn< "missing terminating %select{'|'\"'}0 character">, InGroup<InvalidPPToken>; @@ -175,7 +175,7 @@ def ext_unknown_escape : ExtWarn<"unknown escape sequence '\\%0'">, 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">; + "invalid suffix '%0' on %select{integer|floating|fixed-point}1 constant">; def warn_cxx11_compat_digit_separator : Warning< "digit separators are incompatible with C++ standards before C++14">, InGroup<CXXPre14Compat>, DefaultIgnore; @@ -312,6 +312,9 @@ def pp_macro_not_used : Warning<"macro is not used">, DefaultIgnore, def warn_pp_undef_identifier : Warning< "%0 is not defined, evaluates to 0">, InGroup<DiagGroup<"undef">>, DefaultIgnore; +def warn_pp_undef_prefix : Warning< + "%0 is not defined, evaluates to 0">, + InGroup<DiagGroup<"undef-prefix">>, DefaultIgnore; def warn_pp_ambiguous_macro : Warning< "ambiguous expansion of macro %0">, InGroup<AmbiguousMacro>; def note_pp_ambiguous_macro_chosen : Note< diff --git a/clang/include/clang/Basic/DiagnosticOptions.def b/clang/include/clang/Basic/DiagnosticOptions.def index 6d1a1af92821..a946b5c6be8e 100644 --- a/clang/include/clang/Basic/DiagnosticOptions.def +++ b/clang/include/clang/Basic/DiagnosticOptions.def @@ -65,6 +65,7 @@ VALUE_DIAGOPT(ShowCategories, 2, 0) /// Show categories: 0 -> none, 1 -> Number, ENUM_DIAGOPT(Format, TextDiagnosticFormat, 2, Clang) /// Format for diagnostics: DIAGOPT(ShowColors, 1, 0) /// Show diagnostics with ANSI color sequences. +DIAGOPT(UseANSIEscapeCodes, 1, 0) ENUM_DIAGOPT(ShowOverloads, OverloadsShown, 1, Ovl_All) /// Overload candidates to show. DIAGOPT(VerifyDiagnostics, 1, 0) /// Check that diagnostics match the expected diff --git a/clang/include/clang/Basic/DiagnosticOptions.h b/clang/include/clang/Basic/DiagnosticOptions.h index 3e3c4e50a9e0..7fbe534c5994 100644 --- a/clang/include/clang/Basic/DiagnosticOptions.h +++ b/clang/include/clang/Basic/DiagnosticOptions.h @@ -98,6 +98,10 @@ public: /// prefixes removed. std::vector<std::string> Warnings; + /// The list of prefixes from -Wundef-prefix=... used to generate warnings + /// for undefined macros. + std::vector<std::string> UndefPrefixes; + /// The list of -R... options used to alter the diagnostic mappings, with the /// prefixes removed. std::vector<std::string> Remarks; diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td index cc6a74ac3e6d..1038a4119d4c 100644 --- a/clang/include/clang/Basic/DiagnosticParseKinds.td +++ b/clang/include/clang/Basic/DiagnosticParseKinds.td @@ -12,11 +12,10 @@ let Component = "Parse" in { -def warn_asm_qualifier_ignored : Warning< - "ignored %0 qualifier on asm">, CatInlineAsm, InGroup<ASMIgnoredQualifier>; -def warn_file_asm_volatile : Warning< - "meaningless 'volatile' on asm outside function">, CatInlineAsm, - InGroup<ASMIgnoredQualifier>; +def err_asm_qualifier_ignored : Error< + "expected 'volatile', 'inline', 'goto', or '('">, CatInlineAsm; +def err_global_asm_qualifier_ignored : Error< + "meaningless '%0' on asm outside function">, CatInlineAsm; let CategoryName = "Inline Assembly Issue" in { def err_asm_empty : Error<"__asm used with no assembly instructions">; @@ -27,16 +26,11 @@ def err_msasm_unable_to_create_target : Error< "MS-style inline assembly is not available: %0">; def err_gnu_inline_asm_disabled : Error< "GNU-style inline assembly is disabled">; -def err_asm_goto_cannot_have_output : Error< - "'asm goto' cannot have output constraints">; +def err_asm_duplicate_qual : Error<"duplicate asm qualifier '%0'">; } let CategoryName = "Parse Issue" in { -def warn_cxx2a_compat_explicit_bool : Warning< - "this expression will be parsed as explicit(bool) in C++2a">, - InGroup<CXX2aCompat>, DefaultIgnore; - def ext_empty_translation_unit : Extension< "ISO C requires a translation unit to contain at least one declaration">, InGroup<DiagGroup<"empty-translation-unit">>; @@ -111,6 +105,25 @@ def ext_clang_c_enum_fixed_underlying_type : Extension< def warn_cxx98_compat_enum_fixed_underlying_type : Warning< "enumeration types with a fixed underlying type are incompatible with C++98">, InGroup<CXX98Compat>, DefaultIgnore; +def ext_enum_base_in_type_specifier : ExtWarn< + "non-defining declaration of enumeration with a fixed underlying type is " + "only permitted as a standalone declaration" + "%select{|; missing list of enumerators?}0">, + InGroup<DiagGroup<"elaborated-enum-base">>, DefaultError; +def ext_elaborated_enum_class : ExtWarn< + "reference to enumeration must use 'enum' not 'enum %select{struct|class}0'">, + InGroup<DiagGroup<"elaborated-enum-class">>, DefaultError; +def err_scoped_enum_missing_identifier : Error< + "scoped enumeration requires a name">; +def ext_scoped_enum : ExtWarn< + "scoped enumerations are a C++11 extension">, InGroup<CXX11>; +def warn_cxx98_compat_scoped_enum : Warning< + "scoped enumerations are incompatible with C++98">, + InGroup<CXX98Compat>, DefaultIgnore; +def err_anonymous_enum_bitfield : Error< + "ISO C++ only allows ':' in member enumeration declaration to introduce " + "a fixed underlying type, not an anonymous bit-field">; + def warn_cxx98_compat_alignof : Warning< "alignof expressions are incompatible with C++98">, InGroup<CXX98Compat>, DefaultIgnore; @@ -181,13 +194,12 @@ def err_function_declared_typedef : Error< def err_at_defs_cxx : Error<"@defs is not supported in Objective-C++">; def err_at_in_class : Error<"unexpected '@' in member specification">; def err_unexpected_semi : Error<"unexpected ';' before %0">; +def err_postfix_after_unary_requires_parens : Error< + "expression cannot be followed by a postfix %0 operator; add parentheses">; def err_unparenthesized_non_primary_expr_in_requires_clause : Error< "parentheses are required around this expression in a requires clause">; def note_unparenthesized_non_primary_expr_in_requires_clause : Note< "parentheses are required around this expression in a requires clause">; -def err_potential_function_call_in_constraint_logical_or : Error< - "function call must be parenthesized to be considered part of the requires " - "clause">; def err_expected_fn_body : Error< "expected function body after function declarator">; @@ -215,7 +227,6 @@ def err_invalid_token_after_declarator_suggest_equal : Error< "invalid %0 at end of declaration; did you mean '='?">; def err_expected_statement : Error<"expected statement">; def err_expected_lparen_after : Error<"expected '(' after '%0'">; -def err_expected_lbrace_after : Error<"expected '{' after '%0'">; def err_expected_rparen_after : Error<"expected ')' after '%0'">; def err_expected_punc : Error<"expected ')' or ',' after '%0'">; def err_expected_less_after : Error<"expected '<' after '%0'">; @@ -245,10 +256,10 @@ def warn_cxx14_compat_nested_namespace_definition : Warning< "nested namespace definition is incompatible with C++ standards before C++17">, InGroup<CXXPre17Compat>, DefaultIgnore; def ext_inline_nested_namespace_definition : ExtWarn< - "inline nested namespace definition is a C++2a extension">, InGroup<CXX2a>; + "inline nested namespace definition is a C++20 extension">, InGroup<CXX20>; def warn_cxx17_compat_inline_nested_namespace_definition : Warning< "inline nested namespace definition is incompatible with C++ standards before" - " C++2a">, InGroup<CXXPre2aCompat>, DefaultIgnore; + " C++20">, InGroup<CXXPre20Compat>, DefaultIgnore; def err_inline_nested_namespace_definition : Error< "nested namespace definition cannot be 'inline'">; def err_expected_semi_after_attribute_list : Error< @@ -593,14 +604,16 @@ def warn_cxx14_compat_init_statement : Warning< "%select{if|switch}0 initialization statements are incompatible with " "C++ standards before C++17">, DefaultIgnore, InGroup<CXXPre17Compat>; def ext_for_range_init_stmt : ExtWarn< - "range-based for loop initialization statements are a C++2a extension">, - InGroup<CXX2a>; + "range-based for loop initialization statements are a C++20 extension">, + InGroup<CXX20>; def warn_cxx17_compat_for_range_init_stmt : Warning< "range-based for loop initialization statements are incompatible with " - "C++ standards before C++2a">, DefaultIgnore, InGroup<CXXPre2aCompat>; + "C++ standards before C++20">, DefaultIgnore, InGroup<CXXPre20Compat>; def warn_empty_init_statement : Warning< "empty initialization statement of '%select{if|switch|range-based for}0' " "has no effect">, InGroup<EmptyInitStatement>, DefaultIgnore; +def err_keyword_as_parameter : Error < + "invalid parameter name: '%0' is a keyword">; // C++ derived classes def err_dup_virtual : Error<"duplicate 'virtual' in base specifier">; @@ -684,6 +697,15 @@ def err_ms_property_expected_comma_or_rparen : Error< def err_ms_property_initializer : Error< "property declaration cannot have an in-class initializer">; +def warn_cxx20_compat_explicit_bool : Warning< + "this expression will be parsed as explicit(bool) in C++20">, + InGroup<CXX20Compat>, DefaultIgnore; +def warn_cxx17_compat_explicit_bool : Warning< + "explicit(bool) is incompatible with C++ standards before C++20">, + InGroup<CXXPre20Compat>, DefaultIgnore; +def ext_explicit_bool : ExtWarn<"explicit(bool) is a C++20 extension">, + InGroup<CXX20>; + /// C++ Templates def err_expected_template : Error<"expected template">; def err_unknown_template_name : Error< @@ -707,6 +729,8 @@ def err_id_after_template_in_nested_name_spec : Error< "expected template name after 'template' keyword in nested name specifier">; def err_unexpected_template_in_unqualified_id : Error< "'template' keyword not permitted here">; +def err_unexpected_template_in_destructor_name : Error< + "'template' keyword not permitted in destructor name">; def err_unexpected_template_after_using : Error< "'template' keyword not permitted after 'using' keyword">; def err_two_right_angle_brackets_need_space : Error< @@ -739,6 +763,23 @@ def err_friend_explicit_instantiation : Error< def err_explicit_instantiation_enum : Error< "enumerations cannot be explicitly instantiated">; def err_expected_template_parameter : Error<"expected template parameter">; +def err_empty_requires_expr : Error< + "a requires expression must contain at least one requirement">; +def err_requires_expr_parameter_list_ellipsis : Error< + "varargs not allowed in requires expression">; +def err_expected_semi_requirement : Error< + "expected ';' at end of requirement">; +def err_requires_expr_missing_arrow : Error< + "expected '->' before expression type requirement">; +def err_requires_expr_expected_type_constraint : Error< + "expected concept name with optional arguments">; +def err_requires_expr_simple_requirement_noexcept : Error< + "'noexcept' can only be used in a compound requirement (with '{' '}' around " + "the expression)">; +def warn_requires_expr_in_simple_requirement : Warning< + "this requires expression will only be checked for syntactic validity; did " + "you intend to place it in a nested requirement? (add another 'requires' " + "before the expression)">, InGroup<DiagGroup<"requires-expression">>; def err_missing_dependent_template_keyword : Error< "use 'template' keyword to treat '%0' as a dependent template name">; @@ -794,7 +835,7 @@ def err_friend_decl_defines_type : Error< "cannot define a type in a friend declaration">; def err_missing_whitespace_digraph : Error< "found '<::' after a " - "%select{template name|const_cast|dynamic_cast|reinterpret_cast|static_cast}0" + "%select{template name|addrspace_cast|const_cast|dynamic_cast|reinterpret_cast|static_cast}0" " which forms the digraph '<:' (aka '[') and a ':', did you mean '< ::'?">; def ext_defaulted_deleted_function : ExtWarn< @@ -812,11 +853,11 @@ def warn_cxx98_compat_nonstatic_member_init : Warning< "in-class initialization of non-static data members is incompatible with C++98">, InGroup<CXX98Compat>, DefaultIgnore; def ext_bitfield_member_init: ExtWarn< - "default member initializer for bit-field is a C++2a extension">, - InGroup<CXX2a>; + "default member initializer for bit-field is a C++20 extension">, + InGroup<CXX20>; def warn_cxx17_compat_bitfield_member_init: Warning< "default member initializer for bit-field is incompatible with " - "C++ standards before C++2a">, InGroup<CXXPre2aCompat>, DefaultIgnore; + "C++ standards before C++20">, InGroup<CXXPre20Compat>, DefaultIgnore; def err_incomplete_array_member_init: Error< "array bound cannot be deduced from an in-class initializer">; @@ -865,14 +906,6 @@ def err_access_specifier_interface : Error< def err_duplicate_virt_specifier : Error< "class member already marked '%0'">; -def err_scoped_enum_missing_identifier : Error< - "scoped enumeration requires a name">; -def ext_scoped_enum : ExtWarn< - "scoped enumerations are a C++11 extension">, InGroup<CXX11>; -def warn_cxx98_compat_scoped_enum : Warning< - "scoped enumerations are incompatible with C++98">, - InGroup<CXX98Compat>, DefaultIgnore; - def err_expected_parameter_pack : Error< "expected the name of a parameter pack">; def err_paren_sizeof_parameter_pack : Error< @@ -912,13 +945,13 @@ def warn_cxx14_compat_constexpr_on_lambda : Warning< def ext_constexpr_on_lambda_cxx17 : ExtWarn< "'constexpr' on lambda expressions is a C++17 extension">, InGroup<CXX17>; -// C++2a template lambdas +// C++20 template lambdas def ext_lambda_template_parameter_list: ExtWarn< - "explicit template parameter list for lambdas is a C++2a extension">, - InGroup<CXX2a>; + "explicit template parameter list for lambdas is a C++20 extension">, + InGroup<CXX20>; def warn_cxx17_compat_lambda_template_parameter_list: Warning< "explicit template parameter list for lambdas is incompatible with " - "C++ standards before C++2a">, InGroup<CXXPre2aCompat>, DefaultIgnore; + "C++ standards before C++20">, InGroup<CXXPre20Compat>, DefaultIgnore; def err_lambda_template_parameter_list_empty : Error< "lambda template parameter list cannot be empty">; @@ -1014,6 +1047,8 @@ def warn_pragma_expected_section_label_or_name : Warning< def warn_pragma_expected_init_seg : Warning< "expected 'compiler', 'lib', 'user', or a string literal for the section name in '#pragma %0' - ignored">, InGroup<IgnoredPragmas>; + +def err_pragma_expected_integer : Error<"expected an integer argument in '#pragma %0'">; def warn_pragma_expected_integer : Warning< "expected integer between %0 and %1 inclusive in '#pragma %2' - ignored">, InGroup<IgnoredPragmas>; @@ -1075,9 +1110,9 @@ def warn_pragma_init_seg_unsupported_target : Warning< "'#pragma init_seg' is only supported when targeting a " "Microsoft environment">, InGroup<IgnoredPragmas>; -// - #pragma fp_contract -def err_pragma_fp_contract_scope : Error< - "'#pragma fp_contract' can only appear at file scope or at the start of a " +// - #pragma restricted to file scope or start of compound statement +def err_pragma_file_or_compound_scope : Error< + "'#pragma %0' can only appear at file scope or at the start of a " "compound statement">; // - #pragma stdc unknown def ext_stdc_pragma_ignored : ExtWarn<"unknown pragma in STDC namespace">, @@ -1096,6 +1131,10 @@ def warn_pragma_comment_ignored : Warning<"'#pragma comment %0' ignored">, def err_pragma_detect_mismatch_malformed : Error< "pragma detect_mismatch is malformed; it requires two comma-separated " "string literals">; +// - #pragma float_control +def err_pragma_float_control_malformed : Error< + "pragma float_control is malformed; use 'float_control({push|pop})' or " + "'float_control({precise|except}, {on|off} [,push])'">; // - #pragma pointers_to_members def err_pragma_pointers_to_members_unknown_kind : Error< "unexpected %0, expected to see one of %select{|'best_case', 'full_generality', }1" @@ -1200,6 +1239,10 @@ def err_omp_expected_identifier_for_critical : Error< "expected identifier specifying the name of the 'omp critical' directive">; def err_omp_expected_reduction_identifier : Error< "expected identifier or one of the following operators: '+', '-', '*', '&', '|', '^', '&&', or '||'">; +def err_omp_expected_equal_in_iterator : Error< + "expected '=' in iterator specifier">; +def err_omp_expected_punc_after_iterator : Error< + "expected ',' or ')' after iterator specifier">; def err_omp_decl_in_declare_simd_variant : Error< "function declaration is expected after 'declare %select{simd|variant}0' directive">; def err_omp_unknown_map_type : Error< @@ -1212,8 +1255,11 @@ def err_omp_map_type_modifier_missing : Error< "missing map type modifier">; def err_omp_declare_simd_inbranch_notinbranch : Error< "unexpected '%0' clause, '%1' is specified already">; -def err_expected_end_declare_target : Error< - "expected '#pragma omp end declare target'">; +def err_expected_end_declare_target_or_variant : Error< + "expected '#pragma omp end declare %select{target|variant}0'">; +def err_expected_begin_declare_variant + : Error<"'#pragma omp end declare variant' with no matching '#pragma omp " + "begin declare variant'">; def err_omp_declare_target_unexpected_clause: Error< "unexpected '%0' clause, only %select{'to' or 'link'|'to', 'link' or 'device_type'}1 clauses expected">; def err_omp_expected_clause: Error< @@ -1224,30 +1270,72 @@ def err_omp_mapper_expected_declarator : Error< "expected declarator on 'omp declare mapper' directive">; def err_omp_declare_variant_wrong_clause : Error< "expected '%0' clause on 'omp declare variant' directive">; -def err_omp_declare_variant_no_ctx_selector : Error< - "expected context selector in '%0' clause on 'omp declare variant' directive">; -def err_omp_declare_variant_equal_expected : Error< - "expected '=' after '%0' context selector set name on 'omp declare variant' directive">; -def warn_omp_declare_variant_cs_name_expected : Warning< - "unknown context selector in '%0' context selector set of 'omp declare variant' directive, ignored">, - InGroup<OpenMPClauses>; -def err_omp_declare_variant_item_expected : Error< - "expected %0 in '%1' context selector of '%2' selector set of 'omp declare variant' directive">; -def err_omp_declare_variant_ctx_set_mutiple_use : Error< - "context selector set '%0' is used already in the same 'omp declare variant' directive">; -def note_omp_declare_variant_ctx_set_used_here : Note< - "previously context selector set '%0' used here">; -def err_omp_expected_comma_brace : Error<"expected '}' or ',' after '%0'">; -def err_omp_declare_variant_ctx_mutiple_use : Error< - "context trait selector '%0' is used already in the same '%1' context selector set of 'omp declare variant' directive">; -def note_omp_declare_variant_ctx_used_here : Note< - "previously context trait selector '%0' used here">; -def warn_omp_more_one_device_type_clause : Warning< - "more than one 'device_type' clause is specified">, - InGroup<OpenMPClauses>; -def err_omp_wrong_device_kind_trait : Error< - "unknown '%0' device kind trait in the 'device' context selector set, expected" - " one of 'host', 'nohost', 'cpu', 'gpu' or 'fpga'">; +def warn_omp_declare_variant_string_literal_or_identifier + : Warning<"expected identifier or string literal describing a context " + "%select{set|selector|property}0; " + "%select{set|selector|property}0 skipped">, + InGroup<OpenMPClauses>; +def note_omp_declare_variant_ctx_options + : Note<"context %select{set|selector|property}0 options are: %1">; +def warn_omp_declare_variant_expected + : Warning<"expected '%0' after the %1; '%0' assumed">, + InGroup<OpenMPClauses>; +def warn_omp_declare_variant_ctx_not_a_property + : Warning<"'%0' is not a valid context property for the context selector " + "'%1' and the context set '%2'; property ignored">, + InGroup<OpenMPClauses>; +def note_omp_declare_variant_ctx_is_a + : Note<"'%0' is a context %select{set|selector|property}1 not a context " + "%select{set|selector|property}2">; +def note_omp_declare_variant_ctx_try : Note<"try 'match(%0={%1%2})'">; +def warn_omp_declare_variant_ctx_not_a_selector + : Warning<"'%0' is not a valid context selector for the context set '%1'; " + "selector ignored">, + InGroup<OpenMPClauses>; +def warn_omp_declare_variant_ctx_not_a_set + : Warning<"'%0' is not a valid context set in a `declare variant`; set " + "ignored">, + InGroup<OpenMPClauses>; +def warn_omp_declare_variant_ctx_mutiple_use + : Warning<"the context %select{set|selector|property}0 '%1' was used " + "already in the same 'omp declare variant' directive; " + "%select{set|selector|property}0 ignored">, + InGroup<OpenMPClauses>; +def note_omp_declare_variant_ctx_used_here + : Note<"the previous context %select{set|selector|property}0 '%1' used " + "here">; +def note_omp_declare_variant_ctx_continue_here + : Note<"the ignored %select{set|selector|property}0 spans until here">; +def warn_omp_ctx_incompatible_selector_for_set + : Warning<"the context selector '%0' is not valid for the context set " + "'%1'; selector ignored">, + InGroup<OpenMPClauses>; +def note_omp_ctx_compatible_set_for_selector + : Note<"the context selector '%0' can be nested in the context set '%1'; " + "try 'match(%1={%0%select{|(property)}2})'">; +def warn_omp_ctx_selector_without_properties + : Warning<"the context selector '%0' in context set '%1' requires a " + "context property defined in parentheses; selector ignored">, + InGroup<OpenMPClauses>; +def warn_omp_ctx_incompatible_property_for_selector + : Warning<"the context property '%0' is not valid for the context selector " + "'%1' and the context set '%2'; property ignored">, + InGroup<OpenMPClauses>; +def note_omp_ctx_compatible_set_and_selector_for_property + : Note<"the context property '%0' can be nested in the context selector " + "'%1' which is nested in the context set '%2'; try " + "'match(%2={%1(%0)})'">; +def warn_omp_ctx_incompatible_score_for_property + : Warning<"the context selector '%0' in the context set '%1' cannot have a " + "score ('%2'); score ignored">, + InGroup<OpenMPClauses>; +def warn_omp_more_one_device_type_clause + : Warning<"more than one 'device_type' clause is specified">, + InGroup<OpenMPClauses>; +def err_omp_variant_ctx_second_match_extension : Error< + "only a single match extension allowed per OpenMP context selector">; +def err_omp_invalid_dsa: Error< + "data-sharing attribute '%0' in '%1' clause requires OpenMP version %2 or above">; // Pragma loop support. def err_pragma_loop_missing_argument : Error< @@ -1259,13 +1347,12 @@ def err_pragma_loop_invalid_option : Error< "pipeline, pipeline_initiation_interval, vectorize_predicate, or distribute">; def err_pragma_fp_invalid_option : Error< - "%select{invalid|missing}0 option%select{ %1|}0; expected contract">; + "%select{invalid|missing}0 option%select{ %1|}0; expected 'contract' or 'reassociate'">; def err_pragma_fp_invalid_argument : Error< "unexpected argument '%0' to '#pragma clang fp %1'; " - "expected 'on', 'fast' or 'off'">; -def err_pragma_fp_scope : Error< - "'#pragma clang fp' can only appear at file scope or at the start of a " - "compound statement">; + "%select{" + "expected 'fast' or 'on' or 'off'|" + "expected 'on' or 'off'}2">; def err_pragma_invalid_keyword : Error< "invalid argument; expected 'enable'%select{|, 'full'}0%select{|, 'assume_safety'}1 or 'disable'">; @@ -1337,8 +1424,20 @@ let CategoryName = "Concepts Issue" in { def err_concept_definition_not_identifier : Error< "name defined in concept definition must be an identifier">; def ext_concept_legacy_bool_keyword : ExtWarn< - "ISO C++2a does not permit the 'bool' keyword after 'concept'">, + "ISO C++20 does not permit the 'bool' keyword after 'concept'">, InGroup<DiagGroup<"concepts-ts-compat">>; +def err_placeholder_expected_auto_or_decltype_auto : Error< + "expected 'auto' or 'decltype(auto)' after concept name">; } +def warn_max_tokens : Warning< + "the number of preprocessor source tokens (%0) exceeds this token limit (%1)">, + InGroup<MaxTokens>, DefaultIgnore; + +def warn_max_tokens_total : Warning< + "the total number of preprocessor source tokens (%0) exceeds the token limit (%1)">, + InGroup<MaxTokens>, DefaultIgnore; + +def note_max_tokens_total_override : Note<"total token limit set here">; + } // end of Parser diagnostics diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 7d8231d140e4..aa4de2812312 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -171,8 +171,9 @@ def err_field_designator_unknown : Error< def err_field_designator_nonfield : Error< "field designator %0 does not refer to a non-static data member">; def note_field_designator_found : Note<"field designator refers here">; -def err_designator_for_scalar_init : Error< - "designator in initializer for scalar type %0">; +def err_designator_for_scalar_or_sizeless_init : Error< + "designator in initializer for %select{scalar|indivisible sizeless}0 " + "type %1">; def warn_initializer_overrides : Warning< "initializer %select{partially |}0overrides prior initialization of " "this subobject">, InGroup<InitializerOverrides>; @@ -193,10 +194,10 @@ def ext_flexible_array_init : Extension< // C++20 designated initializers def ext_cxx_designated_init : Extension< - "designated initializers are a C++20 extension">, InGroup<CXX2aDesignator>; + "designated initializers are a C++20 extension">, InGroup<CXX20Designator>; def warn_cxx17_compat_designated_init : Warning< "designated initializers are incompatible with C++ standards before C++20">, - InGroup<CXXPre2aCompatPedantic>, DefaultIgnore; + InGroup<CXXPre20CompatPedantic>, DefaultIgnore; def ext_designated_init_mixed : ExtWarn< "mixture of designated and non-designated initializers in the same " "initializer list is a C99 extension">, InGroup<C99Designator>; @@ -258,6 +259,9 @@ def err_invalid_vector_float_decl_spec : Error< 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_bool_int128_decl_spec : Error < + "use of '__int128' with '__vector bool' requires VSX support enabled (on " + "POWER10 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) " @@ -275,7 +279,9 @@ def err_bad_parameter_name : Error< "%0 cannot be the name of a parameter">; def err_bad_parameter_name_template_id : Error< "parameter name cannot have template arguments">; -def err_parameter_name_omitted : Error<"parameter name omitted">; +def ext_parameter_name_omitted_c2x : ExtWarn< + "omitting the parameter name in a function definition is a C2x extension">, + InGroup<C2x>; def err_anyx86_interrupt_attribute : Error< "%select{x86|x86-64}0 'interrupt' attribute only applies to functions that " "have %select{a 'void' return type|" @@ -444,13 +450,13 @@ def err_decomp_decl_spec : Error< "%plural{1:'%1'|:with '%1' specifiers}0">; def ext_decomp_decl_spec : ExtWarn< "decomposition declaration declared " - "%plural{1:'%1'|:with '%1' specifiers}0 is a C++2a extension">, - InGroup<CXX2a>; + "%plural{1:'%1'|:with '%1' specifiers}0 is a C++20 extension">, + InGroup<CXX20>; def warn_cxx17_compat_decomp_decl_spec : Warning< "decomposition declaration declared " "%plural{1:'%1'|:with '%1' specifiers}0 " - "is incompatible with C++ standards before C++2a">, - InGroup<CXXPre2aCompat>, DefaultIgnore; + "is incompatible with C++ standards before C++20">, + InGroup<CXXPre20Compat>, DefaultIgnore; def err_decomp_decl_type : Error< "decomposition declaration cannot be declared with type %0; " "declared type must be 'auto' or reference to 'auto'">; @@ -639,6 +645,8 @@ def warn_redecl_library_builtin : Warning< def err_builtin_definition : Error<"definition of builtin function %0">; def err_builtin_redeclare : Error<"cannot redeclare builtin function %0">; def err_arm_invalid_specialreg : Error<"invalid special register for builtin">; +def err_arm_invalid_coproc : Error<"coprocessor %0 must be configured as " + "%select{GCP|CDE}1">; def err_invalid_cpu_supports : Error<"invalid cpu feature string for builtin">; def err_invalid_cpu_is : Error<"invalid cpu name for builtin">; def err_invalid_cpu_specific_dispatch_value : Error< @@ -741,6 +749,12 @@ def warn_fortify_source_size_mismatch : Warning< "'%0' size argument is too large; destination buffer has size %1," " but size argument is %2">, InGroup<FortifySource>; +def warn_fortify_source_format_overflow : Warning< + "'%0' will always overflow; destination buffer has size %1," + " but format string expands to at least %2">, + InGroup<FortifySource>; + + /// main() // static main() is not an error in C, just in C++. def warn_static_main : Warning<"'main' should not be declared static">, @@ -782,10 +796,27 @@ def ext_no_declarators : ExtWarn<"declaration does not declare anything">, def ext_typedef_without_a_name : ExtWarn<"typedef requires a name">, InGroup<MissingDeclarations>; def err_typedef_not_identifier : Error<"typedef name must be an identifier">; -def err_typedef_changes_linkage : Error<"unsupported: typedef changes linkage" - " of anonymous type, but linkage was already computed">; -def note_typedef_changes_linkage : Note<"use a tag name here to establish " - "linkage prior to definition">; + +def ext_non_c_like_anon_struct_in_typedef : ExtWarn< + "anonymous non-C-compatible type given name for linkage purposes " + "by %select{typedef|alias}0 declaration; " + "add a tag name here">, InGroup<DiagGroup<"non-c-typedef-for-linkage">>; +def err_non_c_like_anon_struct_in_typedef : Error< + "anonymous non-C-compatible type given name for linkage purposes " + "by %select{typedef|alias}0 declaration after its linkage was computed; " + "add a tag name here to establish linkage prior to definition">; +def err_typedef_changes_linkage : Error< + "unsupported: anonymous type given name for linkage purposes " + "by %select{typedef|alias}0 declaration after its linkage was computed; " + "add a tag name here to establish linkage prior to definition">; +def note_non_c_like_anon_struct : Note< + "type is not C-compatible due to this " + "%select{base class|default member initializer|lambda expression|" + "friend declaration|member declaration}0">; +def note_typedef_for_linkage_here : Note< + "type is given name %0 for linkage purposes by this " + "%select{typedef|alias}1 declaration">; + def err_statically_allocated_object : Error< "interface type cannot be statically allocated">; def err_object_cannot_be_passed_returned_by_value : Error< @@ -799,8 +830,8 @@ def err_opencl_half_load_store : Error< def err_opencl_cast_to_half : Error<"casting to type %0 is not allowed">; def err_opencl_half_declaration : Error< "declaring variable of type %0 is not allowed">; -def err_opencl_half_param : Error< - "declaring function parameter of type %0 is not allowed; did you forget * ?">; +def err_opencl_invalid_param : Error< + "declaring function parameter of type %0 is not allowed%select{; did you forget * ?|}1">; def err_opencl_invalid_return : Error< "declaring function return value of type %0 is not allowed %select{; did you forget * ?|}1">; def warn_enum_value_overflow : Warning<"overflow in enumeration value">; @@ -831,6 +862,16 @@ def warn_pragma_pack_pop_identifier_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 err_pragma_fc_pp_scope : Error< + "'#pragma float_control push/pop' can only appear at file scope or namespace scope">; +def err_pragma_fc_noprecise_requires_nofenv : Error< + "'#pragma float_control(precise, off)' is illegal when fenv_access is enabled">; +def err_pragma_fc_except_requires_precise : Error< + "'#pragma float_control(except, on)' is illegal when precise is disabled">; +def err_pragma_fc_noprecise_requires_noexcept : Error< + "'#pragma float_control(precise, off)' is illegal when except is enabled">; +def err_pragma_fenv_requires_precise : Error< + "'#pragma STDC FENV_ACCESS ON' is illegal when precise is disabled">; def warn_cxx_ms_struct : Warning<"ms_struct may not produce Microsoft-compatible layouts for classes " "with base classes or virtual functions">, @@ -996,8 +1037,8 @@ def err_objc_direct_on_protocol : Error< "'objc_direct' attribute cannot be applied to %select{methods|properties}0 " "declared in an Objective-C protocol">; def err_objc_direct_duplicate_decl : Error< - "%select{|direct }0method declaration conflicts " - "with previous %select{|direct }1declaration of method %2">; + "%select{|direct }0%select{method|property}1 declaration conflicts " + "with previous %select{|direct }2declaration of %select{method|property}1 %3">; def err_objc_direct_impl_decl_mismatch : Error< "direct method was declared in %select{the primary interface|an extension|a category}0 " "but is implemented in %select{the primary interface|a category|a different category}1">; @@ -1013,6 +1054,8 @@ def warn_objc_direct_ignored : Warning< def warn_objc_direct_property_ignored : Warning< "direct attribute on property %0 ignored (not implemented by this Objective-C runtime)">, InGroup<IgnoredAttributes>; +def err_objc_direct_dynamic_property : Error< + "direct property cannot be @dynamic">; def warn_conflicting_overriding_ret_types : Warning< "conflicting return type in " @@ -1335,8 +1378,14 @@ def warn_multiple_selectors: Warning< "several methods with selector %0 of mismatched types are found " "for the @selector expression">, InGroup<SelectorTypeMismatch>, DefaultIgnore; -def err_direct_selector_expression: Error< +def err_direct_selector_expression : Error< "@selector expression formed with direct selector %0">; +def warn_potentially_direct_selector_expression : Warning< + "@selector expression formed with potentially direct selector %0">, + InGroup<ObjCPotentiallyDirectSelector>; +def warn_strict_potentially_direct_selector_expression : Warning< + warn_potentially_direct_selector_expression.Text>, + InGroup<ObjCStrictPotentiallyDirectSelector>, DefaultIgnore; def err_objc_kindof_nonobject : Error< "'__kindof' specifier cannot be applied to non-object type %0">; @@ -1371,7 +1420,8 @@ def warn_cxx14_compat_inline_variable : Warning< DefaultIgnore, InGroup<CXXPre17Compat>; def warn_inline_namespace_reopened_noninline : Warning< - "inline namespace reopened as a non-inline namespace">; + "inline namespace reopened as a non-inline namespace">, + InGroup<InlineNamespaceReopenedNoninline>; def err_inline_namespace_mismatch : Error< "non-inline namespace cannot be reopened as inline">; @@ -1449,8 +1499,8 @@ def err_throw_abstract_type : Error< def err_array_of_abstract_type : Error<"array of abstract class type %0">; def err_capture_of_abstract_type : Error< "by-copy capture of value of abstract type %0">; -def err_capture_of_incomplete_type : Error< - "by-copy capture of variable %0 with incomplete type %1">; +def err_capture_of_incomplete_or_sizeless_type : Error< + "by-copy capture of variable %0 with %select{incomplete|sizeless}1 type %2">; def err_capture_default_non_local : Error< "non-local lambda expression cannot have a capture-default">; @@ -1482,9 +1532,12 @@ def err_deleted_decl_not_first : Error< def err_deleted_override : Error< "deleted function %0 cannot override a non-deleted function">; - def err_non_deleted_override : Error< "non-deleted function %0 cannot override a deleted function">; +def err_consteval_override : Error< + "consteval function %0 cannot override a non-consteval function">; +def err_non_consteval_override : Error< + "non-consteval function %0 cannot override a consteval function">; def warn_weak_vtable : Warning< "%0 has no out-of-line virtual method definitions; its vtable will be " @@ -1507,6 +1560,9 @@ def err_distant_exception_spec : Error< def err_incomplete_in_exception_spec : Error< "%select{|pointer to |reference to }0incomplete type %1 is not allowed " "in exception specification">; +def err_sizeless_in_exception_spec : Error< + "%select{|reference to }0sizeless type %1 is not allowed " + "in exception specification">; def ext_incomplete_in_exception_spec : ExtWarn<err_incomplete_in_exception_spec.Text>, InGroup<MicrosoftExceptionSpec>; def err_rref_in_exception_spec : Error< @@ -1544,6 +1600,9 @@ def err_exception_spec_cycle : Error< "exception specification of %0 uses itself">; def err_exception_spec_incomplete_type : Error< "exception specification needed for member of incomplete class %0">; +def warn_wasm_dynamic_exception_spec_ignored : ExtWarn< + "dynamic exception specifications with types are currently ignored in wasm">, + InGroup<WebAssemblyExceptionSpec>; // C++ access checking def err_class_redeclared_with_different_access : Error< @@ -1755,6 +1814,11 @@ def note_due_to_dllexported_class : Note< def err_illegal_union_or_anon_struct_member : Error< "%select{anonymous struct|union}0 member %1 has a non-trivial " "%sub{select_special_member_kind}2">; + +def warn_frame_address : Warning< + "calling '%0' with a nonzero argument is unsafe">, + InGroup<FrameAddress>, DefaultIgnore; + def warn_cxx98_compat_nontrivial_union_or_anon_struct_member : Warning< "%select{anonymous struct|union}0 member %1 with a non-trivial " "%sub{select_special_member_kind}2 is incompatible with C++98">, @@ -1790,8 +1854,13 @@ def note_nontrivial_objc_ownership : Note< "because type %0 has a member with %select{no|no|__strong|__weak|" "__autoreleasing}1 ownership">; +/// Selector for a TagTypeKind value. +def select_tag_type_kind : TextSubstitution< + "%select{struct|interface|union|class|enum}0">; + def err_static_data_member_not_allowed_in_anon_struct : Error< - "static data member %0 not allowed in anonymous struct">; + "static data member %0 not allowed in anonymous " + "%sub{select_tag_type_kind}1">; def ext_static_data_member_in_union : ExtWarn< "static data member %0 in union is a C++11 extension">, InGroup<CXX11>; def warn_cxx98_compat_static_data_member_in_union : Warning< @@ -1881,19 +1950,36 @@ def err_destructor_return_type : Error<"destructor cannot have a return type">; def err_destructor_redeclared : Error<"destructor cannot be redeclared">; def err_destructor_with_params : Error<"destructor cannot have any parameters">; def err_destructor_variadic : Error<"destructor cannot be variadic">; -def err_destructor_typedef_name : Error< - "destructor cannot be declared using a %select{typedef|type alias}1 %0 of the class name">; +def ext_destructor_typedef_name : ExtWarn< + "destructor cannot be declared using a %select{typedef|type alias}1 %0 " + "of the class name">, DefaultError, InGroup<DiagGroup<"dtor-typedef">>; +def err_undeclared_destructor_name : Error< + "undeclared identifier %0 in destructor name">; def err_destructor_name : Error< "expected the class name after '~' to name the enclosing class">; -def err_destructor_class_name : Error< - "expected the class name after '~' to name a destructor">; -def err_ident_in_dtor_not_a_type : Error< +def err_destructor_name_nontype : Error< + "identifier %0 after '~' in destructor name does not name a type">; +def err_destructor_expr_mismatch : Error< + "identifier %0 in object destruction expression does not name the type " + "%1 of the object being destroyed">; +def err_destructor_expr_nontype : Error< "identifier %0 in object destruction expression does not name a type">; def err_destructor_expr_type_mismatch : Error< "destructor type %0 in object destruction expression does not match the " "type %1 of the object being destroyed">; def note_destructor_type_here : Note< - "type %0 is declared here">; + "type %0 found by destructor name lookup">; +def note_destructor_nontype_here : Note< + "non-type declaration found by destructor name lookup">; +def ext_dtor_named_in_wrong_scope : Extension< + "ISO C++ requires the name after '::~' to be found in the same scope as " + "the name before '::~'">, InGroup<DtorName>; +def ext_qualified_dtor_named_in_lexical_scope : ExtWarn< + "qualified destructor name only found in lexical scope; omit the qualifier " + "to find this type name by unqualified lookup">, InGroup<DtorName>; +def ext_dtor_name_ambiguous : Extension< + "ISO C++ considers this destructor name lookup to be ambiguous">, + InGroup<DtorName>; def err_destroy_attr_on_non_static_var : Error< "%select{no_destroy|always_destroy}0 attribute can only be applied to a" @@ -1947,15 +2033,17 @@ def err_reference_bind_init_list : Error< def err_init_list_bad_dest_type : Error< "%select{|non-aggregate }0type %1 cannot be initialized with an initializer " "list">; -def warn_cxx2a_compat_aggregate_init_with_ctors : Warning< +def warn_cxx20_compat_aggregate_init_with_ctors : Warning< "aggregate initialization of type %0 with user-declared constructors " - "is incompatible with C++2a">, DefaultIgnore, InGroup<CXX2aCompat>; + "is incompatible with C++20">, DefaultIgnore, InGroup<CXX20Compat>; def err_reference_bind_to_bitfield : Error< "%select{non-const|volatile}0 reference cannot bind to " "bit-field%select{| %1}2">; def err_reference_bind_to_vector_element : Error< "%select{non-const|volatile}0 reference cannot bind to vector element">; +def err_reference_bind_to_matrix_element : Error< + "%select{non-const|volatile}0 reference cannot bind to matrix element">; def err_reference_var_requires_init : Error< "declaration of reference variable %0 requires an initializer">; def err_reference_without_init : Error< @@ -2033,6 +2121,10 @@ def err_list_init_in_parens : Error< "cannot initialize %select{non-class|reference}0 type %1 with a " "parenthesized initializer list">; +def warn_uninit_const_reference : Warning< + "variable %0 is uninitialized when passed as a const reference argument " + "here">, InGroup<UninitializedConstReference>, DefaultIgnore; + def warn_unsequenced_mod_mod : Warning< "multiple unsequenced modifications to %0">, InGroup<Unsequenced>; def warn_unsequenced_mod_use : Warning< @@ -2102,12 +2194,18 @@ def err_auto_not_allowed : Error< "|in template argument|in typedef|in type alias|in function return type" "|in conversion function type|here|in lambda parameter" "|in type allocated by 'new'|in K&R-style function parameter" - "|in template parameter|in friend declaration}1">; + "|in template parameter|in friend declaration|in function prototype that is " + "not a function declaration|in requires expression parameter}1">; def err_dependent_deduced_tst : Error< "typename specifier refers to " "%select{class template|function template|variable template|alias template|" "template template parameter|template}0 member in %1; " "argument deduction not allowed here">; +def err_deduced_tst : Error< + "typename specifier refers to " + "%select{class template|function template|variable template|alias template|" + "template template parameter|template}0; argument deduction not allowed " + "here">; def err_auto_not_allowed_var_inst : Error< "'auto' variable template instantiation is not allowed">; def err_auto_var_requires_init : Error< @@ -2269,12 +2367,22 @@ def override_keyword_hides_virtual_member_function : Error< "%select{function|functions}1">; def err_function_marked_override_not_overriding : Error< "%0 marked 'override' but does not override any member functions">; -def warn_destructor_marked_not_override_overriding : Warning < - "%0 overrides a destructor but is not marked 'override'">, - InGroup<CXX11WarnOverrideDestructor>, DefaultIgnore; -def warn_function_marked_not_override_overriding : Warning < - "%0 overrides a member function but is not marked 'override'">, - InGroup<CXX11WarnOverrideMethod>; +def warn_destructor_marked_not_override_overriding : TextSubstitution < + "%0 overrides a destructor but is not marked 'override'">; +def warn_function_marked_not_override_overriding : TextSubstitution < + "%0 overrides a member function but is not marked 'override'">; +def warn_inconsistent_destructor_marked_not_override_overriding : Warning < + "%sub{warn_destructor_marked_not_override_overriding}0">, + InGroup<CXX11WarnInconsistentOverrideDestructor>, DefaultIgnore; +def warn_inconsistent_function_marked_not_override_overriding : Warning < + "%sub{warn_function_marked_not_override_overriding}0">, + InGroup<CXX11WarnInconsistentOverrideMethod>; +def warn_suggest_destructor_marked_not_override_overriding : Warning < + "%sub{warn_destructor_marked_not_override_overriding}0">, + InGroup<CXX11WarnSuggestOverrideDestructor>, DefaultIgnore; +def warn_suggest_function_marked_not_override_overriding : Warning < + "%sub{warn_function_marked_not_override_overriding}0">, + InGroup<CXX11WarnSuggestOverride>, DefaultIgnore; def err_class_marked_final_used_as_base : Error< "base %0 is marked '%select{final|sealed}1'">; def warn_abstract_final_class : Warning< @@ -2308,9 +2416,6 @@ def err_enum_redeclare_fixed_mismatch : Error< "enumeration previously declared with %select{non|}0fixed underlying type">; def err_enum_redeclare_scoped_mismatch : Error< "enumeration previously declared as %select{un|}0scoped">; -def err_enum_class_reference : Error< - "reference to %select{|scoped }0enumeration must use 'enum' " - "not 'enum class'">; def err_only_enums_have_underlying_types : Error< "only enumeration types have underlying types">; def err_underlying_type_of_incomplete_enum : Error< @@ -2368,21 +2473,20 @@ def note_for_range_invalid_iterator : Note < "in implicit call to 'operator%select{!=|*|++}0' for iterator of type %1">; def note_for_range_begin_end : Note< "selected '%select{begin|end}0' %select{function|template }1%2 with iterator type %3">; -def warn_for_range_const_reference_copy : Warning< +def warn_for_range_const_ref_binds_temp_built_from_ref : Warning< "loop variable %0 " - "%diff{has type $ but is initialized with type $" - "| is initialized with a value of a different type}1,2 resulting in a copy">, - InGroup<RangeLoopAnalysis>, DefaultIgnore; + "%diff{of type $ binds to a temporary constructed from type $" + "|binds to a temporary constructed from a different type}1,2">, + InGroup<RangeLoopConstruct>, DefaultIgnore; def note_use_type_or_non_reference : Note< - "use non-reference type %0 to keep the copy or type %1 to prevent copying">; -def warn_for_range_variable_always_copy : Warning< - "loop variable %0 is always a copy because the range of type %1 does not " - "return a reference">, - InGroup<RangeLoopAnalysis>, DefaultIgnore; + "use non-reference type %0 to make construction explicit or type %1 to prevent copying">; +def warn_for_range_ref_binds_ret_temp : Warning< + "loop variable %0 binds to a temporary value produced by a range of type %1">, + InGroup<RangeLoopBindReference>, DefaultIgnore; def note_use_non_reference_type : Note<"use non-reference type %0">; def warn_for_range_copy : Warning< - "loop variable %0 of type %1 creates a copy from type %2">, - InGroup<RangeLoopAnalysis>, DefaultIgnore; + "loop variable %0 creates a copy from type %1">, + InGroup<RangeLoopConstruct>, DefaultIgnore; def note_use_reference_type : Note<"use reference type %0 to prevent copying">; def err_objc_for_range_init_stmt : Error< "initialization statement is not supported when iterating over Objective-C " @@ -2397,6 +2501,13 @@ def warn_cxx14_compat_constexpr_not_const : Warning< "'constexpr' non-static member function will not be implicitly 'const' " "in C++14; add 'const' to avoid a change in behavior">, InGroup<DiagGroup<"constexpr-not-const">>; +def err_invalid_consteval_take_address : Error< + "cannot take address of consteval function %0 outside" + " of an immediate invocation">; +def err_invalid_consteval_call : Error< + "call to consteval function %q0 is not a constant expression">; +def err_invalid_consteval_decl_kind : Error< + "%0 cannot be declared consteval">; def err_invalid_constexpr : Error< "%select{function parameter|typedef}0 " "cannot be %sub{select_constexpr_spec_kind}1">; @@ -2432,7 +2543,7 @@ def err_constexpr_redecl_mismatch : Error< def err_constexpr_virtual : Error<"virtual function cannot be constexpr">; def warn_cxx17_compat_constexpr_virtual : Warning< "virtual constexpr functions are incompatible with " - "C++ standards before C++2a">, InGroup<CXXPre2aCompat>, DefaultIgnore; + "C++ standards before C++20">, InGroup<CXXPre20Compat>, DefaultIgnore; def err_constexpr_virtual_base : Error< "constexpr %select{member function|constructor}0 not allowed in " "%select{struct|interface|class}1 with virtual base " @@ -2456,13 +2567,13 @@ def warn_cxx11_compat_constexpr_body_invalid_stmt : Warning< "use of this statement in a constexpr %select{function|constructor}0 " "is incompatible with C++ standards before C++14">, InGroup<CXXPre14Compat>, DefaultIgnore; -def ext_constexpr_body_invalid_stmt_cxx2a : ExtWarn< +def ext_constexpr_body_invalid_stmt_cxx20 : ExtWarn< "use of this statement in a constexpr %select{function|constructor}0 " - "is a C++2a extension">, InGroup<CXX2a>; + "is a C++20 extension">, InGroup<CXX20>; def warn_cxx17_compat_constexpr_body_invalid_stmt : Warning< "use of this statement in a constexpr %select{function|constructor}0 " - "is incompatible with C++ standards before C++2a">, - InGroup<CXXPre2aCompat>, DefaultIgnore; + "is incompatible with C++ standards before C++20">, + InGroup<CXXPre20Compat>, DefaultIgnore; def ext_constexpr_type_definition : ExtWarn< "type definition in a constexpr %select{function|constructor}0 " "is a C++14 extension">, InGroup<CXX14>; @@ -2488,13 +2599,13 @@ def err_constexpr_local_var_non_literal_type : Error< "%select{function|constructor}0">; def ext_constexpr_local_var_no_init : ExtWarn< "uninitialized variable in a constexpr %select{function|constructor}0 " - "is a C++20 extension">, InGroup<CXX2a>; + "is a C++20 extension">, InGroup<CXX20>; def warn_cxx17_compat_constexpr_local_var_no_init : Warning< "uninitialized variable in a constexpr %select{function|constructor}0 " "is incompatible with C++ standards before C++20">, - InGroup<CXXPre2aCompat>, DefaultIgnore; + InGroup<CXXPre20Compat>, DefaultIgnore; def ext_constexpr_function_never_constant_expr : ExtWarn< - "constexpr %select{function|constructor}0 never produces a " + "%select{constexpr|consteval}1 %select{function|constructor}0 never produces a " "constant expression">, InGroup<DiagGroup<"invalid-constexpr">>, DefaultError; def err_attr_cond_never_constant_expr : Error< "%0 attribute expression never produces a constant expression">; @@ -2518,29 +2629,29 @@ def warn_cxx11_compat_constexpr_body_multiple_return : Warning< def note_constexpr_body_previous_return : Note< "previous return statement is here">; -// C++2a function try blocks in constexpr -def ext_constexpr_function_try_block_cxx2a : ExtWarn< +// C++20 function try blocks in constexpr +def ext_constexpr_function_try_block_cxx20 : ExtWarn< "function try block in constexpr %select{function|constructor}0 is " - "a C++2a extension">, InGroup<CXX2a>; + "a C++20 extension">, InGroup<CXX20>; def warn_cxx17_compat_constexpr_function_try_block : Warning< "function try block in constexpr %select{function|constructor}0 is " - "incompatible with C++ standards before C++2a">, - InGroup<CXXPre2aCompat>, DefaultIgnore; + "incompatible with C++ standards before C++20">, + InGroup<CXXPre20Compat>, DefaultIgnore; def ext_constexpr_union_ctor_no_init : ExtWarn< "constexpr union constructor that does not initialize any member " - "is a C++20 extension">, InGroup<CXX2a>; + "is a C++20 extension">, InGroup<CXX20>; def warn_cxx17_compat_constexpr_union_ctor_no_init : Warning< "constexpr union constructor that does not initialize any member " "is incompatible with C++ standards before C++20">, - InGroup<CXXPre2aCompat>, DefaultIgnore; + InGroup<CXXPre20Compat>, DefaultIgnore; def ext_constexpr_ctor_missing_init : ExtWarn< "constexpr constructor that does not initialize all members " - "is a C++20 extension">, InGroup<CXX2a>; + "is a C++20 extension">, InGroup<CXX20>; def warn_cxx17_compat_constexpr_ctor_missing_init : Warning< "constexpr constructor that does not initialize all members " "is incompatible with C++ standards before C++20">, - InGroup<CXXPre2aCompat>, DefaultIgnore; + InGroup<CXXPre20Compat>, DefaultIgnore; def note_constexpr_ctor_missing_init : Note< "member not initialized by constructor">; def note_non_literal_no_constexpr_ctors : Note< @@ -2575,8 +2686,6 @@ def err_concept_extra_headers : Error< "extraneous template parameter list in concept definition">; def err_concept_no_associated_constraints : Error< "concept cannot have associated constraints">; -def err_concept_not_implemented : Error< - "sorry, unimplemented concepts feature %0 used">; def err_non_constant_constraint_expression : Error< "substitution into constraint expression resulted in a non-constant " "expression">; @@ -2585,30 +2694,57 @@ def err_non_bool_atomic_constraint : Error< def err_template_arg_list_constraints_not_satisfied : Error< "constraints not satisfied for %select{class template|function template|variable template|alias template|" "template template parameter|template}0 %1%2">; -def note_constraints_not_satisfied : Note< - "constraints not satisfied">; def note_substituted_constraint_expr_is_ill_formed : Note< "because substituted constraint expression is ill-formed%0">; def note_atomic_constraint_evaluated_to_false : Note< - "%select{and |because }0'%1' evaluated to false">; + "%select{and|because}0 '%1' evaluated to false">; def note_concept_specialization_constraint_evaluated_to_false : Note< - "%select{and |because }0'%1' evaluated to false">; + "%select{and|because}0 '%1' evaluated to false">; def note_single_arg_concept_specialization_constraint_evaluated_to_false : Note< - "%select{and |because }0%1 does not satisfy %2">; + "%select{and|because}0 %1 does not satisfy %2">; def note_atomic_constraint_evaluated_to_false_elaborated : Note< - "%select{and |because }0'%1' (%2 %3 %4) evaluated to false">; + "%select{and|because}0 '%1' (%2 %3 %4) evaluated to false">; def err_constrained_virtual_method : Error< "virtual function cannot have a requires clause">; def err_trailing_requires_clause_on_deduction_guide : Error< "deduction guide cannot have a requires clause">; def err_reference_to_function_with_unsatisfied_constraints : Error< "invalid reference to function %0: constraints not satisfied">; +def err_requires_expr_local_parameter_default_argument : Error< + "default arguments not allowed for parameters of a requires expression">; +def err_requires_expr_parameter_referenced_in_evaluated_context : Error< + "constraint variable %0 cannot be used in an evaluated context">; +def note_expr_requirement_expr_substitution_error : Note< + "%select{and|because}0 '%1' would be invalid: %2">; +def note_expr_requirement_expr_unknown_substitution_error : Note< + "%select{and|because}0 '%1' would be invalid">; +def note_expr_requirement_noexcept_not_met : Note< + "%select{and|because}0 '%1' may throw an exception">; +def note_expr_requirement_type_requirement_substitution_error : Note< + "%select{and|because}0 '%1' would be invalid: %2">; +def note_expr_requirement_type_requirement_unknown_substitution_error : Note< + "%select{and|because}0 '%1' would be invalid">; +def note_expr_requirement_constraints_not_satisfied : Note< + "%select{and|because}0 type constraint '%1' was not satisfied:">; +def note_expr_requirement_constraints_not_satisfied_simple : Note< + "%select{and|because}0 %1 does not satisfy %2:">; +def note_type_requirement_substitution_error : Note< + "%select{and|because}0 '%1' would be invalid: %2">; +def note_type_requirement_unknown_substitution_error : Note< + "%select{and|because}0 '%1' would be invalid">; +def note_nested_requirement_substitution_error : Note< + "%select{and|because}0 '%1' would be invalid: %2">; +def note_nested_requirement_unknown_substitution_error : Note< + "%select{and|because}0 '%1' would be invalid">; def note_ambiguous_atomic_constraints : Note< "similar constraint expressions not considered equivalent; constraint " "expressions cannot be considered equivalent unless they originate from the " "same concept">; def note_ambiguous_atomic_constraints_similar_expression : Note< "similar constraint expression here">; +def err_unsupported_placeholder_constraint : Error< + "constrained placeholder types other than simple 'auto' on non-type template " + "parameters not supported yet">; def err_template_different_requires_clause : Error< "requires clause differs in template redeclaration">; @@ -2623,6 +2759,8 @@ def err_type_constraint_non_type_concept : Error< def err_type_constraint_missing_arguments : Error< "%0 requires more than 1 template argument; provide the remaining arguments " "explicitly to use it here">; +def err_placeholder_constraints_not_satisfied : Error< + "deduced type %0 does not satisfy %1">; // C++11 char16_t/char32_t def warn_cxx98_compat_unicode_type : Warning< @@ -2630,7 +2768,7 @@ def warn_cxx98_compat_unicode_type : Warning< InGroup<CXX98Compat>, DefaultIgnore; def warn_cxx17_compat_unicode_type : Warning< "'char8_t' type specifier is incompatible with C++ standards before C++20">, - InGroup<CXXPre2aCompat>, DefaultIgnore; + InGroup<CXXPre20Compat>, DefaultIgnore; // __make_integer_seq def err_integer_sequence_negative_length : Error< @@ -2650,6 +2788,10 @@ def warn_auto_var_is_id : Warning< InGroup<DiagGroup<"auto-var-id">>; // Attributes +def warn_nomerge_attribute_ignored_in_stmt: Warning< + "%0 attribute is ignored because there exists no call expression inside the " + "statement">, + InGroup<IgnoredAttributes>; def err_nsobject_attribute : Error< "'NSObject' attribute is for pointer types only">; def err_attributes_are_not_compatible : Error< @@ -2665,6 +2807,7 @@ def err_attribute_too_many_arguments : Error< def err_attribute_too_few_arguments : Error< "%0 attribute takes at least %1 argument%s1">; def err_attribute_invalid_vector_type : Error<"invalid vector element type %0">; +def err_attribute_invalid_matrix_type : Error<"invalid matrix element type %0">; def err_attribute_bad_neon_vector_size : Error< "Neon vector size must be 64 or 128 bits">; def err_attribute_requires_positive_integer : Error< @@ -2696,6 +2839,8 @@ def err_alignas_mismatch : Error< "redeclaration has different alignment requirement (%1 vs %0)">; def err_alignas_underaligned : Error< "requested alignment is less than minimum alignment of %1 for type %0">; +def err_attribute_sizeless_type : Error< + "%0 attribute cannot be applied to sizeless type %1">; def err_attribute_argument_n_type : Error< "%0 attribute requires parameter %1 to be %select{int or bool|an integer " "constant|a string|an identifier}2">; @@ -2766,8 +2911,8 @@ def err_init_method_bad_return_type : Error< "init methods must return an object pointer type, not %0">; def err_attribute_invalid_size : Error< "vector size not an integral multiple of component size">; -def err_attribute_zero_size : Error<"zero vector size">; -def err_attribute_size_too_large : Error<"vector size too large">; +def err_attribute_zero_size : Error<"zero %0 size">; +def err_attribute_size_too_large : Error<"%0 size too large">; def err_typecheck_vector_not_convertable_implict_truncation : Error< "cannot convert between %select{scalar|vector}0 type %1 and vector type" " %2 as implicit conversion would cause truncation">; @@ -2793,6 +2938,10 @@ def err_attribute_address_multiple_qualifiers : Error< def warn_attribute_address_multiple_identical_qualifiers : Warning< "multiple identical address spaces specified for type">, InGroup<DuplicateDeclSpecifier>; +def err_attribute_not_clinkage : Error< + "function type with %0 attribute must have C linkage">; +def err_function_decl_cmse_ns_call : Error< + "functions may not be declared with 'cmse_nonsecure_call' attribute">; def err_attribute_address_function_type : Error< "function type may not be qualified with an address space">; def err_as_qualified_auto_decl : Error< @@ -2838,7 +2987,7 @@ def warn_objc_literal_comparison : Warning< "a numeric literal|a boxed expression|}0 has undefined behavior">, InGroup<ObjCLiteralComparison>; def err_missing_atsign_prefix : Error< - "string literal must be prefixed by '@' ">; + "%select{string|numeric}0 literal must be prefixed by '@'">; def warn_objc_string_literal_comparison : Warning< "direct comparison of a string literal has undefined behavior">, InGroup<ObjCStringComparison>; @@ -2852,6 +3001,11 @@ def warn_objc_collection_literal_element : Warning< "object of type %0 is not compatible with " "%select{array element type|dictionary key type|dictionary value type}1 %2">, InGroup<ObjCLiteralConversion>; +def warn_nsdictionary_duplicate_key : Warning< + "duplicate key in dictionary literal">, + InGroup<DiagGroup<"objc-dictionary-duplicate-keys">>; +def note_nsdictionary_duplicate_key_here : Note< + "previous equal key is here">; def err_swift_param_attr_not_swiftcall : Error< "'%0' parameter can only be used with swiftcall calling convention">; def err_swift_indirect_result_not_first : Error< @@ -2931,6 +3085,9 @@ def err_alignment_too_big : Error< "requested alignment must be %0 or smaller">; def err_alignment_not_power_of_two : Error< "requested alignment is not a power of 2">; +def warn_alignment_not_power_of_two : Warning< + err_alignment_not_power_of_two.Text>, + InGroup<DiagGroup<"non-power-of-two-alignment">>; def err_alignment_dependent_typedef_name : Error< "requested alignment is dependent but declaration is not dependent">; @@ -3010,6 +3167,13 @@ def warn_attribute_weak_on_local : Warning< InGroup<IgnoredAttributes>; def warn_weak_identifier_undeclared : Warning< "weak identifier %0 never declared">; +def warn_attribute_cmse_entry_static : Warning< + "'cmse_nonsecure_entry' cannot be applied to functions with internal linkage">, + InGroup<IgnoredAttributes>; +def warn_cmse_nonsecure_union : Warning< + "passing union across security boundary via %select{parameter %1|return value}0 " + "may leak information">, + InGroup<DiagGroup<"cmse-union-leak">>; def err_attribute_weak_static : Error< "weak declaration cannot have internal linkage">; def err_attribute_selectany_non_extern_data : Error< @@ -3157,6 +3321,12 @@ def err_attribute_output_parameter : Error< def ext_cannot_use_trivial_abi : ExtWarn< "'trivial_abi' cannot be applied to %0">, InGroup<IgnoredAttributes>; +def note_cannot_use_trivial_abi_reason : Note< + "'trivial_abi' is disallowed on %0 because %select{" + "its copy constructors and move constructors are all deleted|" + "it is polymorphic|" + "it has a base of a non-trivial class type|it has a virtual base|" + "it has a __weak field|it has a field of a non-trivial class type}1">; // Availability attribute def warn_availability_unknown_platform : Warning< @@ -3206,9 +3376,6 @@ def warn_at_available_unchecked_use : Warning< InGroup<DiagGroup<"unsupported-availability-guard">>; // Thread Safety Attributes -def warn_invalid_capability_name : Warning< - "invalid capability name '%0'; capability name must be 'mutex' or 'role'">, - InGroup<ThreadSafetyAttributes>, DefaultIgnore; def warn_thread_attribute_ignored : Warning< "ignoring %0 attribute because its argument is invalid">, InGroup<ThreadSafetyAttributes>, DefaultIgnore; @@ -3226,7 +3393,7 @@ def warn_thread_attribute_argument_not_lockable : Warning< InGroup<ThreadSafetyAttributes>, DefaultIgnore; def warn_thread_attribute_decl_not_lockable : Warning< "%0 attribute can only be applied in a context annotated " - "with 'capability(\"mutex\")' attribute">, + "with 'capability' attribute">, InGroup<ThreadSafetyAttributes>, DefaultIgnore; def warn_thread_attribute_decl_not_pointer : Warning< "%0 only applies to pointer types; type here is %1">, @@ -3260,6 +3427,7 @@ def warn_expecting_lock_held_on_loop : Warning< "expecting %0 '%1' to be held at start of each loop">, InGroup<ThreadSafetyAnalysis>, DefaultIgnore; def note_locked_here : Note<"%0 acquired here">; +def note_unlocked_here : Note<"%0 released here">; def warn_lock_exclusive_and_shared : Warning< "%0 '%1' is acquired exclusively and shared in the same scope">, InGroup<ThreadSafetyAnalysis>, DefaultIgnore; @@ -3345,7 +3513,7 @@ def warn_use_of_temp_in_invalid_state : Warning< "invalid invocation of method '%0' on a temporary object while it is in the " "'%1' state">, InGroup<Consumed>, DefaultIgnore; def warn_attr_on_unconsumable_class : Warning< - "consumed analysis attribute is attached to member of class '%0' which isn't " + "consumed analysis attribute is attached to member of class %0 which isn't " "marked as consumable">, InGroup<Consumed>, DefaultIgnore; def warn_return_typestate_for_unconsumable_type : Warning< "return state set for an unconsumable type '%0'">, InGroup<Consumed>, @@ -3439,7 +3607,7 @@ def warn_impcast_integer_float_precision : Warning< InGroup<ImplicitIntFloatConversion>, DefaultIgnore; def warn_impcast_integer_float_precision_constant : Warning< "implicit conversion from %2 to %3 changes value from %0 to %1">, - InGroup<ImplicitIntFloatConversion>; + InGroup<ImplicitConstIntFloatConversion>; def warn_impcast_float_to_integer : Warning< "implicit conversion from %0 to %1 changes value from %2 to %3">, @@ -3561,6 +3729,18 @@ def warn_int_to_pointer_cast : Warning< def warn_int_to_void_pointer_cast : Warning< "cast to %1 from smaller integer type %0">, InGroup<IntToVoidPointerCast>; +def warn_pointer_to_int_cast : Warning< + "cast to smaller integer type %1 from %0">, + InGroup<PointerToIntCast>; +def warn_pointer_to_enum_cast : Warning< + warn_pointer_to_int_cast.Text>, + InGroup<PointerToEnumCast>; +def warn_void_pointer_to_int_cast : Warning< + "cast to smaller integer type %1 from %0">, + InGroup<VoidPointerToIntCast>; +def warn_void_pointer_to_enum_cast : Warning< + warn_void_pointer_to_int_cast.Text>, + InGroup<VoidPointerToEnumCast>; def warn_attribute_ignored_for_field_of_type : Warning< "%0 attribute ignored for field of type %1">, @@ -3832,6 +4012,8 @@ def err_use_of_default_argument_to_function_declared_later : Error< def note_default_argument_declared_here : Note< "default argument declared here">; def err_recursive_default_argument : Error<"recursive evaluation of default argument">; +def note_recursive_default_argument_used_here : Note< + "default argument used here">; def ext_param_promoted_not_compatible_with_prototype : ExtWarn< "%diff{promoted type $ of K&R function parameter is not compatible with the " @@ -4079,13 +4261,13 @@ def err_ovl_no_conversion_in_cast : Error< "cannot convert %1 to %2 without a conversion operator">; def err_ovl_no_viable_conversion_in_cast : Error< "no matching conversion for %select{|static_cast|reinterpret_cast|" - "dynamic_cast|C-style cast|functional-style cast}0 from %1 to %2">; + "dynamic_cast|C-style cast|functional-style cast|}0 from %1 to %2">; def err_ovl_ambiguous_conversion_in_cast : Error< "ambiguous conversion for %select{|static_cast|reinterpret_cast|" - "dynamic_cast|C-style cast|functional-style cast}0 from %1 to %2">; + "dynamic_cast|C-style cast|functional-style cast|}0 from %1 to %2">; def err_ovl_deleted_conversion_in_cast : Error< "%select{|static_cast|reinterpret_cast|dynamic_cast|C-style cast|" - "functional-style cast}0 from %1 to %2 uses deleted function">; + "functional-style cast|}0 from %1 to %2 uses deleted function">; def err_ovl_ambiguous_init : Error<"call to constructor of %0 is ambiguous">; def err_ref_init_ambiguous : Error< "reference initialization of type %0 with initializer of type %1 is ambiguous">; @@ -4101,11 +4283,16 @@ def err_ovl_ambiguous_oper_binary : Error< "use of overloaded operator '%0' is ambiguous (with operand types %1 and %2)">; def ext_ovl_ambiguous_oper_binary_reversed : ExtWarn< "ISO C++20 considers use of overloaded operator '%0' (with operand types %1 " - "and %2) to be ambiguous despite there being a unique best viable function">, + "and %2) to be ambiguous despite there being a unique best viable function" + "%select{ with non-reversed arguments|}3">, InGroup<DiagGroup<"ambiguous-reversed-operator">>, SFINAEFailure; -def note_ovl_ambiguous_oper_binary_reversed_candidate : Note< +def note_ovl_ambiguous_oper_binary_reversed_self : Note< "ambiguity is between a regular call to this operator and a call with the " "argument order reversed">; +def note_ovl_ambiguous_oper_binary_selected_candidate : Note< + "candidate function with non-reversed arguments">; +def note_ovl_ambiguous_oper_binary_reversed_candidate : Note< + "ambiguous candidate function with reversed arguments">; def err_ovl_no_viable_oper : Error<"no viable overloaded '%0'">; def note_assign_lhs_incomplete : Note<"type %0 is incomplete">; def err_ovl_deleted_oper : Error< @@ -4119,6 +4306,10 @@ def err_ovl_deleted_comparison : Error< def err_ovl_rewrite_equalequal_not_bool : Error< "return type %0 of selected 'operator==' function for rewritten " "'%1' comparison is not 'bool'">; +def ext_ovl_rewrite_equalequal_not_bool : ExtWarn< + "ISO C++20 requires return type of selected 'operator==' function for " + "rewritten '%1' comparison to be 'bool', not %0">, + InGroup<DiagGroup<"rewrite-not-bool">>, SFINAEFailure; def err_ovl_no_viable_subscript : Error<"no viable overloaded operator[] for type %0">; def err_ovl_no_oper : @@ -4162,7 +4353,7 @@ def err_ovl_no_viable_literal_operator : Error< def err_template_param_shadow : Error< "declaration of %0 shadows template parameter">; def ext_template_param_shadow : ExtWarn< - err_template_param_shadow.Text>, InGroup<MicrosoftTemplate>; + err_template_param_shadow.Text>, InGroup<MicrosoftTemplateShadow>; def note_template_param_here : Note<"template parameter is declared here">; def warn_template_export_unsupported : Warning< "exported templates are unsupported">; @@ -4241,11 +4432,11 @@ def err_template_tag_noparams : Error< def warn_cxx17_compat_adl_only_template_id : Warning< "use of function template name with no prior function template " "declaration in function call with explicit template arguments " - "is incompatible with C++ standards before C++2a">, - InGroup<CXXPre2aCompat>, DefaultIgnore; + "is incompatible with C++ standards before C++20">, + InGroup<CXXPre20Compat>, DefaultIgnore; def ext_adl_only_template_id : ExtWarn< "use of function template name with no prior declaration in function call " - "with explicit template arguments is a C++2a extension">, InGroup<CXX2a>; + "with explicit template arguments is a C++20 extension">, InGroup<CXX20>; // C++ Template Argument Lists def err_template_missing_args : Error< @@ -4387,12 +4578,12 @@ def err_pointer_to_member_oper_value_classify: Error< "pointer-to-member function type %0 can only be called on an " "%select{rvalue|lvalue}1">; def ext_pointer_to_const_ref_member_on_rvalue : Extension< - "invoking a pointer to a 'const &' member function on an rvalue is a C++2a extension">, - InGroup<CXX2a>, SFINAEFailure; + "invoking a pointer to a 'const &' member function on an rvalue is a C++20 extension">, + InGroup<CXX20>, SFINAEFailure; def warn_cxx17_compat_pointer_to_const_ref_member_on_rvalue : Warning< "invoking a pointer to a 'const &' member function on an rvalue is " - "incompatible with C++ standards before C++2a">, - InGroup<CXXPre2aCompatPedantic>, DefaultIgnore; + "incompatible with C++ standards before C++20">, + InGroup<CXXPre20CompatPedantic>, DefaultIgnore; def ext_ms_deref_template_argument: ExtWarn< "non-type template argument containing a dereference operation is a " "Microsoft extension">, InGroup<MicrosoftTemplate>; @@ -4588,6 +4779,8 @@ def note_template_type_alias_instantiation_here : Note< "in instantiation of template type alias %0 requested here">; def note_template_exception_spec_instantiation_here : Note< "in instantiation of exception specification for %0 requested here">; +def note_template_requirement_instantiation_here : Note< + "in instantiation of requirement here">; def warn_var_template_missing : Warning<"instantiation of variable %q0 " "required here, but no definition is available">, InGroup<UndefinedVarTemplate>; @@ -4623,6 +4816,8 @@ def note_template_default_arg_checking : Note< "while checking a default template argument used here">; def note_concept_specialization_here : Note< "while checking the satisfaction of concept '%0' requested here">; +def note_nested_requirement_here : Note< + "while checking the satisfaction of nested requirement requested here">; def note_checking_constraints_for_template_id_here : Note< "while checking constraint satisfaction for template '%0' required here">; def note_checking_constraints_for_var_spec_id_here : Note< @@ -4631,6 +4826,8 @@ def note_checking_constraints_for_var_spec_id_here : Note< def note_checking_constraints_for_class_spec_id_here : Note< "while checking constraint satisfaction for class template partial " "specialization '%0' required here">; +def note_checking_constraints_for_function_here : Note< + "while checking constraint satisfaction for function '%0' required here">; def note_constraint_substitution_here : Note< "while substituting template arguments into constraint expression here">; def note_constraint_normalization_here : Note< @@ -4756,8 +4953,12 @@ def err_typename_nested_not_found_requirement : Error< "declaration">; def err_typename_nested_not_type : Error< "typename specifier refers to non-type member %0 in %1">; -def note_typename_refers_here : Note< +def err_typename_not_type : Error< + "typename specifier refers to non-type %0">; +def note_typename_member_refers_here : Note< "referenced member %0 is declared here">; +def note_typename_refers_here : Note< + "referenced %0 is declared here">; def err_typename_missing : Error< "missing 'typename' prior to dependent type name '%0%1'">; def err_typename_missing_template : Error< @@ -4777,9 +4978,13 @@ def note_using_value_decl_missing_typename : Note< "add 'typename' to treat this using declaration as a type">; def err_template_kw_refers_to_non_template : Error< - "%0 following the 'template' keyword does not refer to a template">; + "%0%select{| following the 'template' keyword}1 " + "does not refer to a template">; def note_template_kw_refers_to_non_template : Note< "declared as a non-template here">; +def err_template_kw_refers_to_dependent_non_template : Error< + "%0%select{| following the 'template' keyword}1 " + "cannot refer to a dependent template">; def err_template_kw_refers_to_class_template : Error< "'%0%1' instantiated to a class template, not a function template">; def note_referenced_class_template : Note< @@ -5200,9 +5405,6 @@ def ext_typecheck_zero_array_size : Extension< "zero size arrays are an extension">, InGroup<ZeroLengthArray>; def err_typecheck_zero_array_size : Error< "zero-length arrays are not permitted in C++">; -def warn_typecheck_zero_static_array_size : Warning< - "'static' has no effect on zero-length arrays">, - InGroup<ArrayBounds>; def err_array_size_non_int : Error<"size of array has non-integer type %0">; def err_init_element_not_constant : Error< "initializer element is not a compile-time constant">; @@ -5210,6 +5412,17 @@ def ext_aggregate_init_not_constant : Extension< "initializer for aggregate is not a compile-time constant">, InGroup<C99>; def err_local_cant_init : Error< "'__local' variable cannot have an initializer">; +def err_loader_uninitialized_cant_init + : Error<"variable with 'loader_uninitialized' attribute cannot have an " + "initializer">; +def err_loader_uninitialized_trivial_ctor + : Error<"variable with 'loader_uninitialized' attribute must have a " + "trivial default constructor">; +def err_loader_uninitialized_redeclaration + : Error<"redeclaration cannot add 'loader_uninitialized' attribute">; +def err_loader_uninitialized_extern_decl + : Error<"variable %0 cannot be declared both 'extern' and with the " + "'loader_uninitialized' attribute">; def err_block_extern_cant_init : Error< "'extern' variable cannot have an initializer">; def warn_extern_init : Warning<"'extern' variable has an initializer">, @@ -5219,30 +5432,44 @@ def err_variable_object_no_init : Error< def err_excess_initializers : Error< "excess elements in %select{array|vector|scalar|union|struct}0 initializer">; def ext_excess_initializers : ExtWarn< - "excess elements in %select{array|vector|scalar|union|struct}0 initializer">; + "excess elements in %select{array|vector|scalar|union|struct}0 initializer">, + InGroup<ExcessInitializers>; +def err_excess_initializers_for_sizeless_type : Error< + "excess elements in initializer for indivisible sizeless type %0">; +def ext_excess_initializers_for_sizeless_type : ExtWarn< + "excess elements in initializer for indivisible sizeless type %0">, + InGroup<ExcessInitializers>; def err_excess_initializers_in_char_array_initializer : Error< "excess elements in char array initializer">; def ext_excess_initializers_in_char_array_initializer : ExtWarn< - "excess elements in char array initializer">; + "excess elements in char array initializer">, + InGroup<ExcessInitializers>; def err_initializer_string_for_char_array_too_long : Error< "initializer-string for char array is too long">; def ext_initializer_string_for_char_array_too_long : ExtWarn< - "initializer-string for char array is too long">; + "initializer-string for char array is too long">, + InGroup<ExcessInitializers>; def warn_missing_field_initializers : Warning< "missing field %0 initializer">, InGroup<MissingFieldInitializers>, DefaultIgnore; -def warn_braces_around_scalar_init : Warning< - "braces around scalar initializer">, InGroup<DiagGroup<"braced-scalar-init">>; -def ext_many_braces_around_scalar_init : ExtWarn< - "too many braces around scalar initializer">, +def warn_braces_around_init : Warning< + "braces around %select{scalar |}0initializer">, + InGroup<DiagGroup<"braced-scalar-init">>; +def ext_many_braces_around_init : ExtWarn< + "too many braces around %select{scalar |}0initializer">, InGroup<DiagGroup<"many-braces-around-scalar-init">>, SFINAEFailure; def ext_complex_component_init : Extension< "complex initialization specifying real and imaginary components " "is an extension">, InGroup<DiagGroup<"complex-component-init">>; def err_empty_scalar_initializer : Error<"scalar initializer cannot be empty">; +def err_empty_sizeless_initializer : Error< + "initializer for sizeless type %0 cannot be empty">; def warn_cxx98_compat_empty_scalar_initializer : Warning< "scalar initialized from empty initializer list is incompatible with C++98">, InGroup<CXX98Compat>, DefaultIgnore; +def warn_cxx98_compat_empty_sizeless_initializer : Warning< + "initializing %0 from an empty initializer list is incompatible with C++98">, + InGroup<CXX98Compat>, DefaultIgnore; def warn_cxx98_compat_reference_list_init : Warning< "reference initialized from initializer list is incompatible with C++98">, InGroup<CXX98Compat>, DefaultIgnore; @@ -5292,6 +5519,8 @@ def err_bitfield_width_exceeds_type_width : Error< 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_anon_bitfield_init : Error< + "anonymous bit-field cannot have a default member initializer">; def err_incorrect_number_of_vector_initializers : Error< "number of elements must be either one or match the size of the vector">; @@ -5410,6 +5639,8 @@ def note_enters_block_captures_weak : Note< def note_enters_block_captures_non_trivial_c_struct : Note< "jump enters lifetime of block which captures a C struct that is non-trivial " "to destroy">; +def note_enters_compound_literal_scope : Note< + "jump enters lifetime of a compound literal that is non-trivial to destruct">; def note_exits_cleanup : Note< "jump exits scope of variable with __attribute__((cleanup))">; @@ -5453,6 +5684,8 @@ def note_exits_block_captures_weak : Note< def note_exits_block_captures_non_trivial_c_struct : Note< "jump exits lifetime of block which captures a C struct that is non-trivial " "to destroy">; +def note_exits_compound_literal_scope : Note< + "jump exits lifetime of a compound literal that is non-trivial to destruct">; def err_func_returning_qualified_void : ExtWarn< "function cannot return qualified void type %0">, @@ -5460,7 +5693,8 @@ def err_func_returning_qualified_void : ExtWarn< def err_func_returning_array_function : Error< "function cannot return %select{array|function}0 type %1">; def err_field_declared_as_function : Error<"field %0 declared as a function">; -def err_field_incomplete : Error<"field has incomplete type %0">; +def err_field_incomplete_or_sizeless : Error< + "field has %select{incomplete|sizeless}0 type %1">; def ext_variable_sized_type_in_struct : ExtWarn< "field %0 with variable sized type %1 not at the end of a struct or class is" " a GNU extension">, InGroup<GNUVariableSizedTypeNotAtEnd>; @@ -5752,8 +5986,8 @@ def err_flexible_array_init_needs_braces : Error< "flexible array requires brace-enclosed initializer">; def err_illegal_decl_array_of_functions : Error< "'%0' declared as array of functions of type %1">; -def err_illegal_decl_array_incomplete_type : Error< - "array has incomplete element type %0">; +def err_array_incomplete_or_sizeless_type : Error< + "array has %select{incomplete|sizeless}0 element type %1">; def err_illegal_message_expr_incomplete_type : Error< "Objective-C message has incomplete result type %0">; def err_illegal_decl_array_of_references : Error< @@ -5784,30 +6018,24 @@ def err_block_return_missing_expr : Error< "non-void block should return a value">; def err_func_def_incomplete_result : Error< "incomplete result type %0 in function definition">; -def err_atomic_specifier_bad_type : Error< - "_Atomic cannot be applied to " - "%select{incomplete |array |function |reference |atomic |qualified |}0type " - "%1 %select{||||||which is not trivially copyable}0">; +def err_atomic_specifier_bad_type + : Error<"_Atomic cannot be applied to " + "%select{incomplete |array |function |reference |atomic |qualified " + "|sizeless ||integer |integer }0type " + "%1 %select{|||||||which is not trivially copyable|with less than " + "1 byte of precision|with a non power of 2 precision}0">; // Expressions. -def select_unary_expr_or_type_trait_kind : TextSubstitution< - "%select{sizeof|alignof|vec_step|__builtin_omp_required_simd_align|" - "__alignof}0">; def ext_sizeof_alignof_function_type : Extension< - "invalid application of '%sub{select_unary_expr_or_type_trait_kind}0' " - "to a function type">, InGroup<PointerArith>; + "invalid application of '%0' to a function type">, InGroup<PointerArith>; def ext_sizeof_alignof_void_type : Extension< - "invalid application of '%sub{select_unary_expr_or_type_trait_kind}0' " - "to a void type">, InGroup<PointerArith>; + "invalid application of '%0' to a void type">, InGroup<PointerArith>; def err_opencl_sizeof_alignof_type : Error< - "invalid application of '%sub{select_unary_expr_or_type_trait_kind}0' " - "to a void type">; -def err_sizeof_alignof_incomplete_type : Error< - "invalid application of '%sub{select_unary_expr_or_type_trait_kind}0' " - "to an incomplete type %1">; + "invalid application of '%0' to a void type">; +def err_sizeof_alignof_incomplete_or_sizeless_type : Error< + "invalid application of '%0' to %select{an incomplete|sizeless}1 type %2">; def err_sizeof_alignof_function_type : Error< - "invalid application of '%sub{select_unary_expr_or_type_trait_kind}0' " - "to a function type">; + "invalid application of '%0' to a 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_typeof_bitfield : Error< @@ -5983,8 +6211,8 @@ def err_typecheck_subscript_not_integer : Error< "array subscript is not an integer">; def err_subscript_function_type : Error< "subscript of pointer to function type %0">; -def err_subscript_incomplete_type : Error< - "subscript of pointer to incomplete type %0">; +def err_subscript_incomplete_or_sizeless_type : Error< + "subscript of pointer to %select{incomplete|sizeless}0 type %1">; def err_dereference_incomplete_type : Error< "dereference of pointer to incomplete type %0">; def ext_gnu_subscript_void_type : Extension< @@ -6094,8 +6322,8 @@ def err_typecheck_illegal_increment_decrement : Error< "cannot %select{decrement|increment}1 value of type %0">; def err_typecheck_expect_int : Error< "used type %0 where integer is required">; -def err_typecheck_arithmetic_incomplete_type : Error< - "arithmetic on a pointer to an incomplete type %0">; +def err_typecheck_arithmetic_incomplete_or_sizeless_type : Error< + "arithmetic on a pointer to %select{an incomplete|sizeless}0 type %1">; def err_typecheck_pointer_arith_function_type : Error< "arithmetic on%select{ a|}0 pointer%select{|s}0 to%select{ the|}2 " "function type%select{|s}2 %1%select{| and %3}2">; @@ -6129,10 +6357,10 @@ def note_array_init_plain_string_into_char8_t : Note< def err_array_init_utf8_string_into_char : Error< "%select{|ISO C++20 does not permit }0initialization of char array with " "UTF-8 string literal%select{ is not permitted by '-fchar8_t'|}0">; -def warn_cxx2a_compat_utf8_string : Warning< +def warn_cxx20_compat_utf8_string : Warning< "type of UTF-8 string literal will change from array of const char to " - "array of const char8_t in C++2a">, InGroup<CXX2aCompat>, DefaultIgnore; -def note_cxx2a_compat_utf8_string_remove_u8 : Note< + "array of const char8_t in C++20">, InGroup<CXX20Compat>, DefaultIgnore; +def note_cxx20_compat_utf8_string_remove_u8 : Note< "remove 'u8' prefix to avoid a change of behavior; " "Clang encodes unprefixed narrow string literals as UTF-8">; def err_array_init_different_type : Error< @@ -6169,7 +6397,7 @@ def err_typecheck_sclass_func : Error<"illegal storage class on function">; def err_static_block_func : Error< "function declared in block scope cannot have 'static' storage class">; def err_typecheck_address_of : Error<"address of %select{bit-field" - "|vector element|property expression|register variable}0 requested">; + "|vector element|property expression|register variable|matrix element}0 requested">; def ext_typecheck_addrof_void : Extension< "ISO C forbids taking the address of an expression of type 'void'">; def err_unqualified_pointer_member_function : Error< @@ -6235,6 +6463,12 @@ def err_typecheck_ordered_comparison_of_pointer_and_zero : Error< "ordered comparison between pointer and zero (%0 and %1)">; def err_typecheck_three_way_comparison_of_pointer_and_zero : Error< "three-way comparison between pointer and zero">; +def ext_typecheck_compare_complete_incomplete_pointers : Extension< + "pointer comparisons before C11 " + "need to be between two complete or two incomplete types; " + "%0 is %select{|in}2complete and " + "%1 is %select{|in}3complete">, + InGroup<C11>; def ext_typecheck_ordered_comparison_of_function_pointers : ExtWarn< "ordered comparison of function pointers (%0 and %1)">, InGroup<DiagGroup<"ordered-compare-function-pointers">>; @@ -6273,7 +6507,7 @@ def warn_arith_conv_enum_float : Warning< "%plural{2:with|4:from|:and}0 " "%select{enumeration|floating-point}1 type %3">, InGroup<EnumFloatConversion>, DefaultIgnore; -def warn_arith_conv_enum_float_cxx2a : Warning< +def warn_arith_conv_enum_float_cxx20 : Warning< "%sub{select_arith_conv_kind}0 " "%select{floating-point|enumeration}1 type %2 " "%plural{2:with|4:from|:and}0 " @@ -6283,27 +6517,27 @@ def warn_arith_conv_mixed_enum_types : Warning< "%sub{select_arith_conv_kind}0 " "different enumeration types%diff{ ($ and $)|}1,2">, InGroup<EnumEnumConversion>, DefaultIgnore; -def warn_arith_conv_mixed_enum_types_cxx2a : Warning< +def warn_arith_conv_mixed_enum_types_cxx20 : Warning< "%sub{select_arith_conv_kind}0 " "different enumeration types%diff{ ($ and $)|}1,2 is deprecated">, InGroup<DeprecatedEnumEnumConversion>; def warn_arith_conv_mixed_anon_enum_types : Warning< warn_arith_conv_mixed_enum_types.Text>, InGroup<AnonEnumEnumConversion>, DefaultIgnore; -def warn_arith_conv_mixed_anon_enum_types_cxx2a : Warning< - warn_arith_conv_mixed_enum_types_cxx2a.Text>, +def warn_arith_conv_mixed_anon_enum_types_cxx20 : Warning< + warn_arith_conv_mixed_enum_types_cxx20.Text>, InGroup<DeprecatedAnonEnumEnumConversion>; def warn_conditional_mixed_enum_types : Warning< warn_arith_conv_mixed_enum_types.Text>, InGroup<EnumCompareConditional>, DefaultIgnore; -def warn_conditional_mixed_enum_types_cxx2a : Warning< - warn_arith_conv_mixed_enum_types_cxx2a.Text>, +def warn_conditional_mixed_enum_types_cxx20 : Warning< + warn_arith_conv_mixed_enum_types_cxx20.Text>, InGroup<DeprecatedEnumCompareConditional>; def warn_comparison_mixed_enum_types : Warning< warn_arith_conv_mixed_enum_types.Text>, InGroup<EnumCompare>; -def warn_comparison_mixed_enum_types_cxx2a : Warning< - warn_arith_conv_mixed_enum_types_cxx2a.Text>, +def warn_comparison_mixed_enum_types_cxx20 : Warning< + warn_arith_conv_mixed_enum_types_cxx20.Text>, InGroup<DeprecatedEnumCompare>; def warn_comparison_of_mixed_enum_types_switch : Warning< "comparison of different enumeration types in switch statement" @@ -6591,8 +6825,10 @@ def warn_objc_unsafe_perform_selector : Warning< InGroup<DiagGroup<"objc-unsafe-perform-selector">>; def note_objc_unsafe_perform_selector_method_declared_here : Note< "method %0 that returns %1 declared here">; -def err_attribute_arm_mve_alias : Error< - "'__clang_arm_mve_alias' attribute can only be applied to an ARM MVE builtin">; +def err_attribute_arm_builtin_alias : Error< + "'__clang_arm_builtin_alias' attribute can only be applied to an ARM builtin">; +def err_attribute_arm_mve_polymorphism : Error< + "'__clang_arm_mve_strict_polymorphism' attribute can only be applied to an MVE/NEON vector type">; def warn_setter_getter_impl_required : Warning< "property %0 requires method %1 to be defined - " @@ -6642,34 +6878,34 @@ def err_bad_cstyle_cast_overload : Error< def err_bad_cxx_cast_generic : Error< - "%select{const_cast|static_cast|reinterpret_cast|dynamic_cast|C-style cast|" - "functional-style cast}0 from %1 to %2 is not allowed">; + "%select{const_cast|static_cast|reinterpret_cast|dynamic_cast|" + "C-style cast|functional-style cast|addrspace_cast}0 from %1 to %2 is not allowed">; def err_bad_cxx_cast_unrelated_class : Error< "%select{const_cast|static_cast|reinterpret_cast|dynamic_cast|C-style cast|" - "functional-style cast}0 from %1 to %2, which are not related by " + "functional-style cast|}0 from %1 to %2, which are not related by " "inheritance, is not allowed">; def note_type_incomplete : Note<"%0 is incomplete">; def err_bad_cxx_cast_rvalue : Error< "%select{const_cast|static_cast|reinterpret_cast|dynamic_cast|C-style cast|" - "functional-style cast}0 from rvalue to reference type %2">; + "functional-style cast|addrspace_cast}0 from rvalue to reference type %2">; def err_bad_cxx_cast_bitfield : Error< "%select{const_cast|static_cast|reinterpret_cast|dynamic_cast|C-style cast|" - "functional-style cast}0 from bit-field lvalue to reference type %2">; + "functional-style cast|}0 from bit-field lvalue to reference type %2">; def err_bad_cxx_cast_qualifiers_away : Error< "%select{const_cast|static_cast|reinterpret_cast|dynamic_cast|C-style cast|" - "functional-style cast}0 from %1 to %2 casts away qualifiers">; + "functional-style cast|}0 from %1 to %2 casts away qualifiers">; def err_bad_cxx_cast_addr_space_mismatch : Error< - "%select{const_cast|static_cast|reinterpret_cast|dynamic_cast|C-style cast|" - "functional-style cast}0 from %1 to %2 converts between mismatching address" + "%select{const_cast|static_cast|reinterpret_cast|dynamic_cast|" + "C-style cast|functional-style cast|addrspace_cast}0 from %1 to %2 converts between mismatching address" " spaces">; def ext_bad_cxx_cast_qualifiers_away_incoherent : ExtWarn< "ISO C++ does not allow " "%select{const_cast|static_cast|reinterpret_cast|dynamic_cast|C-style cast|" - "functional-style cast}0 from %1 to %2 because it casts away qualifiers, " + "functional-style cast|}0 from %1 to %2 because it casts away qualifiers, " "even though the source and destination types are unrelated">, SFINAEFailure, InGroup<DiagGroup<"cast-qual-unrelated">>; def err_bad_const_cast_dest : Error< - "%select{const_cast||||C-style cast|functional-style cast}0 to %2, " + "%select{const_cast||||C-style cast|functional-style cast|}0 to %2, " "which is not a reference, pointer-to-object, or pointer-to-data-member">; def ext_cast_fn_obj : Extension< "cast between pointer-to-function and pointer-to-object is an extension">; @@ -6682,14 +6918,18 @@ def warn_cxx98_compat_cast_fn_obj : Warning< def err_bad_reinterpret_cast_small_int : Error< "cast from pointer to smaller type %2 loses information">; def err_bad_cxx_cast_vector_to_scalar_different_size : Error< - "%select{||reinterpret_cast||C-style cast|}0 from vector %1 " + "%select{||reinterpret_cast||C-style cast||}0 from vector %1 " "to scalar %2 of different size">; def err_bad_cxx_cast_scalar_to_vector_different_size : Error< - "%select{||reinterpret_cast||C-style cast|}0 from scalar %1 " + "%select{||reinterpret_cast||C-style cast||}0 from scalar %1 " "to vector %2 of different size">; def err_bad_cxx_cast_vector_to_vector_different_size : Error< - "%select{||reinterpret_cast||C-style cast|}0 from vector %1 " + "%select{||reinterpret_cast||C-style cast||}0 from vector %1 " "to vector %2 of different size">; +def warn_bad_cxx_cast_nested_pointer_addr_space : Warning< + "%select{reinterpret_cast|C-style cast}0 from %1 to %2 " + "changes address space of nested pointers">, + InGroup<IncompatiblePointerTypesDiscardsQualifiers>; def err_bad_lvalue_to_rvalue_cast : Error< "cannot cast from lvalue of type %1 to rvalue reference type %2; types are " "not compatible">; @@ -6701,7 +6941,7 @@ def err_bad_static_cast_pointer_nonpointer : Error< def err_bad_static_cast_member_pointer_nonmp : Error< "cannot cast from type %1 to member pointer type %2">; def err_bad_cxx_cast_member_pointer_size : Error< - "cannot %select{||reinterpret_cast||C-style cast|}0 from member pointer " + "cannot %select{||reinterpret_cast||C-style cast||}0 from member pointer " "type %1 to member pointer type %2 of different size">; def err_bad_reinterpret_cast_reference : Error< "reinterpret_cast of a %0 to %1 needs its address, which is not allowed">; @@ -6745,8 +6985,8 @@ def err_array_new_needs_size : Error< "array size must be specified in new expression with no initializer">; def err_bad_new_type : Error< "cannot allocate %select{function|reference}1 type %0 with new">; -def err_new_incomplete_type : Error< - "allocation of incomplete type %0">; +def err_new_incomplete_or_sizeless_type : Error< + "allocation of %select{incomplete|sizeless}0 type %1">; def err_new_array_nonconst : Error< "only the first dimension of an allocated array may have dynamic size">; def err_new_array_size_unknown_from_init : Error< @@ -6863,6 +7103,8 @@ def err_catch_incomplete_ptr : Error< def err_catch_incomplete_ref : Error< "cannot catch reference to incomplete type %0">; def err_catch_incomplete : Error<"cannot catch incomplete type %0">; +def err_catch_sizeless : Error< + "cannot catch %select{|reference to }0sizeless type %1">; def err_catch_rvalue_ref : Error<"cannot catch exceptions by rvalue reference">; def err_catch_variably_modified : Error< "cannot catch variably modified type %0">; @@ -6968,6 +7210,8 @@ def err_throw_incomplete : Error< "cannot throw object of incomplete type %0">; def err_throw_incomplete_ptr : Error< "cannot throw pointer to object of incomplete type %0">; +def err_throw_sizeless : Error< + "cannot throw object of sizeless type %0">; def warn_throw_underaligned_obj : Warning< "underaligned exception object thrown">, InGroup<UnderalignedExceptionObject>; @@ -7054,9 +7298,9 @@ let CategoryName = "Lambda Issue" in { "cannot deduce type for lambda capture %0 from initializer list">; def warn_cxx17_compat_init_capture_pack : Warning< "initialized lambda capture packs are incompatible with C++ standards " - "before C++2a">, InGroup<CXXPre2aCompat>, DefaultIgnore; + "before C++20">, InGroup<CXXPre20Compat>, DefaultIgnore; def ext_init_capture_pack : ExtWarn< - "initialized lambda pack captures are a C++2a extension">, InGroup<CXX2a>; + "initialized lambda pack captures are a C++20 extension">, InGroup<CXX20>; // C++14 generic lambdas. def warn_cxx11_compat_generic_lambda : Warning< @@ -7074,23 +7318,23 @@ let CategoryName = "Lambda Issue" in { def err_parameter_shadow_capture : Error< "a lambda parameter cannot shadow an explicitly captured entity">; - // C++2a [=, this] captures. + // C++20 [=, this] captures. def warn_cxx17_compat_equals_this_lambda_capture : Warning< "explicit capture of 'this' with a capture default of '=' is incompatible " - "with C++ standards before C++2a">, InGroup<CXXPre2aCompat>, DefaultIgnore; - def ext_equals_this_lambda_capture_cxx2a : ExtWarn< + "with C++ standards before C++20">, InGroup<CXXPre20Compat>, DefaultIgnore; + def ext_equals_this_lambda_capture_cxx20 : ExtWarn< "explicit capture of 'this' with a capture default of '=' " - "is a C++2a extension">, InGroup<CXX2a>; + "is a C++20 extension">, InGroup<CXX20>; def warn_deprecated_this_capture : Warning< "implicit capture of 'this' with a capture default of '=' is deprecated">, InGroup<DeprecatedThisCapture>, DefaultIgnore; def note_deprecated_this_capture : Note< "add an explicit capture of 'this' to capture '*this' by reference">; - // C++2a default constructible / assignable lambdas. + // C++20 default constructible / assignable lambdas. def warn_cxx17_compat_lambda_def_ctor_assign : Warning< "%select{default construction|assignment}0 of lambda is incompatible with " - "C++ standards before C++2a">, InGroup<CXXPre2aCompat>, DefaultIgnore; + "C++ standards before C++20">, InGroup<CXXPre20Compat>, DefaultIgnore; } def err_return_in_captured_stmt : Error< @@ -7240,6 +7484,21 @@ def warn_incompatible_qualified_id : Warning< "sending type to parameter of incompatible type}0,1" "|%diff{casting $ to incompatible type $|" "casting type to incompatible type}0,1}2">; +def err_incompatible_qualified_id : Error< + "%select{%diff{assigning to $ from incompatible type $|" + "assigning to type from incompatible type}0,1" + "|%diff{passing $ to parameter of incompatible type $|" + "passing type to parameter of incompatible type}0,1" + "|%diff{returning $ from a function with incompatible result type $|" + "returning type from a function with incompatible result type}0,1" + "|%diff{converting $ to incompatible type $|" + "converting type to incompatible type}0,1" + "|%diff{initializing $ with an expression of incompatible type $|" + "initializing type with an expression of incompatible type}0,1" + "|%diff{sending $ to parameter of incompatible type $|" + "sending type to parameter of incompatible type}0,1" + "|%diff{casting $ to incompatible type $|" + "casting type to incompatible type}0,1}2">; def ext_typecheck_convert_pointer_int : ExtWarn< "incompatible pointer to integer conversion " "%select{%diff{assigning to $ from $|assigning to different types}0,1" @@ -7258,6 +7517,23 @@ def ext_typecheck_convert_pointer_int : ExtWarn< "; remove *|" "; remove &}3">, InGroup<IntConversion>; +def err_typecheck_convert_pointer_int : Error< + "incompatible pointer to integer conversion " + "%select{%diff{assigning to $ from $|assigning to different types}0,1" + "|%diff{passing $ to parameter of type $|" + "passing to parameter of different type}0,1" + "|%diff{returning $ from a function with result type $|" + "returning from function with different return type}0,1" + "|%diff{converting $ to type $|converting between types}0,1" + "|%diff{initializing $ with an expression of type $|" + "initializing with expression of different type}0,1" + "|%diff{sending $ to parameter of type $|" + "sending to parameter of different type}0,1" + "|%diff{casting $ to type $|casting between types}0,1}2" + "%select{|; dereference with *|" + "; take the address with &|" + "; remove *|" + "; remove &}3">; def ext_typecheck_convert_int_pointer : ExtWarn< "incompatible integer to pointer conversion " "%select{%diff{assigning to $ from $|assigning to different types}0,1" @@ -7276,6 +7552,23 @@ def ext_typecheck_convert_int_pointer : ExtWarn< "; remove *|" "; remove &}3">, InGroup<IntConversion>, SFINAEFailure; +def err_typecheck_convert_int_pointer : Error< + "incompatible integer to pointer conversion " + "%select{%diff{assigning to $ from $|assigning to different types}0,1" + "|%diff{passing $ to parameter of type $|" + "passing to parameter of different type}0,1" + "|%diff{returning $ from a function with result type $|" + "returning from function with different return type}0,1" + "|%diff{converting $ to type $|converting between types}0,1" + "|%diff{initializing $ with an expression of type $|" + "initializing with expression of different type}0,1" + "|%diff{sending $ to parameter of type $|" + "sending to parameter of different type}0,1" + "|%diff{casting $ to type $|casting between types}0,1}2" + "%select{|; dereference with *|" + "; take the address with &|" + "; remove *|" + "; remove &}3">; def ext_typecheck_convert_pointer_void_func : Extension< "%select{%diff{assigning to $ from $|assigning to different types}0,1" "|%diff{passing $ to parameter of type $|" @@ -7289,6 +7582,19 @@ def ext_typecheck_convert_pointer_void_func : Extension< "sending to parameter of different type}0,1" "|%diff{casting $ to type $|casting between types}0,1}2" " converts between void pointer and function pointer">; +def err_typecheck_convert_pointer_void_func : Error< + "%select{%diff{assigning to $ from $|assigning to different types}0,1" + "|%diff{passing $ to parameter of type $|" + "passing to parameter of different type}0,1" + "|%diff{returning $ from a function with result type $|" + "returning from function with different return type}0,1" + "|%diff{converting $ to type $|converting between types}0,1" + "|%diff{initializing $ with an expression of type $|" + "initializing with expression of different type}0,1" + "|%diff{sending $ to parameter of type $|" + "sending to parameter of different type}0,1" + "|%diff{casting $ to type $|casting between types}0,1}2" + " converts between void pointer and function pointer">; def ext_typecheck_convert_incompatible_pointer_sign : ExtWarn< "%select{%diff{assigning to $ from $|assigning to different types}0,1" "|%diff{passing $ to parameter of type $|" @@ -7303,6 +7609,19 @@ def ext_typecheck_convert_incompatible_pointer_sign : ExtWarn< "|%diff{casting $ to type $|casting between types}0,1}2" " converts between pointers to integer types with different sign">, InGroup<DiagGroup<"pointer-sign">>; +def err_typecheck_convert_incompatible_pointer_sign : Error< + "%select{%diff{assigning to $ from $|assigning to different types}0,1" + "|%diff{passing $ to parameter of type $|" + "passing to parameter of different type}0,1" + "|%diff{returning $ from a function with result type $|" + "returning from function with different return type}0,1" + "|%diff{converting $ to type $|converting between types}0,1" + "|%diff{initializing $ with an expression of type $|" + "initializing with expression of different type}0,1" + "|%diff{sending $ to parameter of type $|" + "sending to parameter of different type}0,1" + "|%diff{casting $ to type $|casting between types}0,1}2" + " converts between pointers to integer types with different sign">; def ext_typecheck_convert_incompatible_pointer : ExtWarn< "incompatible pointer types " "%select{%diff{assigning to $ from $|assigning to different types}0,1" @@ -7321,6 +7640,23 @@ def ext_typecheck_convert_incompatible_pointer : ExtWarn< "; remove *|" "; remove &}3">, InGroup<IncompatiblePointerTypes>; +def err_typecheck_convert_incompatible_pointer : Error< + "incompatible pointer types " + "%select{%diff{assigning to $ from $|assigning to different types}0,1" + "|%diff{passing $ to parameter of type $|" + "passing to parameter of different type}0,1" + "|%diff{returning $ from a function with result type $|" + "returning from function with different return type}0,1" + "|%diff{converting $ to type $|converting between types}0,1" + "|%diff{initializing $ with an expression of type $|" + "initializing with expression of different type}0,1" + "|%diff{sending $ to parameter of type $|" + "sending to parameter of different type}0,1" + "|%diff{casting $ to type $|casting between types}0,1}2" + "%select{|; dereference with *|" + "; take the address with &|" + "; remove *|" + "; remove &}3">; def ext_typecheck_convert_incompatible_function_pointer : ExtWarn< "incompatible function pointer types " "%select{%diff{assigning to $ from $|assigning to different types}0,1" @@ -7339,6 +7675,23 @@ def ext_typecheck_convert_incompatible_function_pointer : ExtWarn< "; remove *|" "; remove &}3">, InGroup<IncompatibleFunctionPointerTypes>; +def err_typecheck_convert_incompatible_function_pointer : Error< + "incompatible function pointer types " + "%select{%diff{assigning to $ from $|assigning to different types}0,1" + "|%diff{passing $ to parameter of type $|" + "passing to parameter of different type}0,1" + "|%diff{returning $ from a function with result type $|" + "returning from function with different return type}0,1" + "|%diff{converting $ to type $|converting between types}0,1" + "|%diff{initializing $ with an expression of type $|" + "initializing with expression of different type}0,1" + "|%diff{sending $ to parameter of type $|" + "sending to parameter of different type}0,1" + "|%diff{casting $ to type $|casting between types}0,1}2" + "%select{|; dereference with *|" + "; take the address with &|" + "; remove *|" + "; remove &}3">; def ext_typecheck_convert_discards_qualifiers : ExtWarn< "%select{%diff{assigning to $ from $|assigning to different types}0,1" "|%diff{passing $ to parameter of type $|" @@ -7353,6 +7706,19 @@ def ext_typecheck_convert_discards_qualifiers : ExtWarn< "|%diff{casting $ to type $|casting between types}0,1}2" " discards qualifiers">, InGroup<IncompatiblePointerTypesDiscardsQualifiers>; +def err_typecheck_convert_discards_qualifiers : Error< + "%select{%diff{assigning to $ from $|assigning to different types}0,1" + "|%diff{passing $ to parameter of type $|" + "passing to parameter of different type}0,1" + "|%diff{returning $ from a function with result type $|" + "returning from function with different return type}0,1" + "|%diff{converting $ to type $|converting between types}0,1" + "|%diff{initializing $ with an expression of type $|" + "initializing with expression of different type}0,1" + "|%diff{sending $ to parameter of type $|" + "sending to parameter of different type}0,1" + "|%diff{casting $ to type $|casting between types}0,1}2" + " discards qualifiers">; def ext_nested_pointer_qualifier_mismatch : ExtWarn< "%select{%diff{assigning to $ from $|assigning to different types}0,1" "|%diff{passing $ to parameter of type $|" @@ -7367,6 +7733,19 @@ def ext_nested_pointer_qualifier_mismatch : ExtWarn< "|%diff{casting $ to type $|casting between types}0,1}2" " discards qualifiers in nested pointer types">, InGroup<IncompatiblePointerTypesDiscardsQualifiers>; +def err_nested_pointer_qualifier_mismatch : Error< + "%select{%diff{assigning to $ from $|assigning to different types}0,1" + "|%diff{passing $ to parameter of type $|" + "passing to parameter of different type}0,1" + "|%diff{returning $ from a function with result type $|" + "returning from function with different return type}0,1" + "|%diff{converting $ to type $|converting between types}0,1" + "|%diff{initializing $ with an expression of type $|" + "initializing with expression of different type}0,1" + "|%diff{sending $ to parameter of type $|" + "sending to parameter of different type}0,1" + "|%diff{casting $ to type $|casting between types}0,1}2" + " discards qualifiers in nested pointer types">; def warn_incompatible_vectors : Warning< "incompatible vector types " "%select{%diff{assigning to $ from $|assigning to different types}0,1" @@ -7381,6 +7760,19 @@ def warn_incompatible_vectors : Warning< "sending to parameter of different type}0,1" "|%diff{casting $ to type $|casting between types}0,1}2">, InGroup<VectorConversion>, DefaultIgnore; +def err_incompatible_vectors : Error< + "incompatible vector types " + "%select{%diff{assigning to $ from $|assigning to different types}0,1" + "|%diff{passing $ to parameter of type $|" + "passing to parameter of different type}0,1" + "|%diff{returning $ from a function with result type $|" + "returning from function with different return type}0,1" + "|%diff{converting $ to type $|converting between types}0,1" + "|%diff{initializing $ with an expression of type $|" + "initializing with expression of different type}0,1" + "|%diff{sending $ to parameter of type $|" + "sending to parameter of different type}0,1" + "|%diff{casting $ to type $|casting between types}0,1}2">; def err_int_to_block_pointer : Error< "invalid block pointer conversion " "%select{%diff{assigning to $ from $|assigning to different types}0,1" @@ -7547,6 +7939,8 @@ def err_atomic_builtin_pointer_size : Error< def err_atomic_exclusive_builtin_pointer_size : Error< "address argument to load or store exclusive builtin must be a pointer to" " 1,2,4 or 8 byte type (%0 invalid)">; +def err_atomic_builtin_ext_int_size : Error< + "Atomic memory operand must have a power-of-two size">; def err_atomic_op_needs_atomic : Error< "address argument to atomic operation must be a pointer to _Atomic " "type (%0 invalid)">; @@ -7579,6 +7973,9 @@ def err_overflow_builtin_must_be_int : Error< 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_overflow_builtin_ext_int_max_size : Error< + "__builtin_mul_overflow does not support signed _ExtInt operands of more " + "than %0 bits">; def err_atomic_load_store_uses_lib : Error< "atomic %select{load|store}0 requires runtime support that is not " @@ -7611,6 +8008,10 @@ def err_ref_bad_target : Error< def err_ref_bad_target_global_initializer : Error< "reference to %select{__device__|__global__|__host__|__host__ __device__}0 " "function %1 in global initializer">; +def err_capture_bad_target : Error< + "capture host variable %0 by reference in device or host device lambda function">; +def err_capture_bad_target_this_ptr : Error< + "capture host side class data member by this pointer in device or host device lambda function">; def warn_kern_is_method : Extension< "kernel function %0 is a member function; this may not be accepted by nvcc">, InGroup<CudaCompat>; @@ -7654,6 +8055,22 @@ def err_cuda_ovl_target : Error< def note_cuda_ovl_candidate_target_mismatch : Note< "candidate template ignored: target attributes do not match">; +def err_cuda_device_builtin_surftex_cls_template : Error< + "illegal device builtin %select{surface|texture}0 reference " + "class template %1 declared here">; +def note_cuda_device_builtin_surftex_cls_should_have_n_args : Note< + "%0 needs to have exactly %1 template parameters">; +def note_cuda_device_builtin_surftex_cls_should_have_match_arg : Note< + "the %select{1st|2nd|3rd}1 template parameter of %0 needs to be " + "%select{a type|an integer or enum value}2">; + +def err_cuda_device_builtin_surftex_ref_decl : Error< + "illegal device builtin %select{surface|texture}0 reference " + "type %1 declared here">; +def note_cuda_device_builtin_surftex_should_be_template_class : Note< + "%0 needs to be instantiated from a class template with proper " + "template arguments">; + def warn_non_pod_vararg_with_format_string : Warning< "cannot pass %select{non-POD|non-trivial}0 object of type %1 to variadic " "%select{function|block|method|constructor}2; expected type from format " @@ -7735,6 +8152,8 @@ def warn_bad_function_cast : Warning< InGroup<BadFunctionCast>, DefaultIgnore; def err_cast_pointer_to_non_pointer_int : Error< "pointer cannot be cast to type %0">; +def err_cast_to_bfloat16 : Error<"cannot type-cast to __bf16">; +def err_cast_from_bfloat16 : Error<"cannot type-cast from __bf16">; def err_typecheck_expect_scalar_operand : Error< "operand of type %0 where arithmetic or pointer type is required">; def err_typecheck_cond_incompatible_operands : Error< @@ -7790,8 +8209,8 @@ def ext_cxx14_attr : Extension< "use of the %0 attribute is a C++14 extension">, InGroup<CXX14>; def ext_cxx17_attr : Extension< "use of the %0 attribute is a C++17 extension">, InGroup<CXX17>; -def ext_cxx2a_attr : Extension< - "use of the %0 attribute is a C++2a extension">, InGroup<CXX2a>; +def ext_cxx20_attr : Extension< + "use of the %0 attribute is a C++20 extension">, InGroup<CXX20>; def warn_unused_comparison : Warning< "%select{equality|inequality|relational|three-way}0 comparison result unused">, @@ -7805,7 +8224,7 @@ def err_incomplete_type_used_in_type_trait_expr : Error< // C++20 constinit and require_constant_initialization attribute def warn_cxx20_compat_constinit : Warning< "'constinit' specifier is incompatible with C++ standards before C++20">, - InGroup<CXX2aCompat>, DefaultIgnore; + InGroup<CXX20Compat>, DefaultIgnore; def err_constinit_local_variable : Error< "local variable cannot be declared 'constinit'">; def err_require_constant_init_failed : Error< @@ -8044,7 +8463,7 @@ def err_reference_to_local_in_enclosing_context : Error< "%select{%3|block literal|lambda expression|context}2">; def err_static_data_member_not_allowed_in_local_class : Error< - "static data member %0 not allowed in local class %1">; + "static data member %0 not allowed in local %sub{select_tag_type_kind}2 %1">; // C++ derived classes def err_base_clause_on_union : Error<"unions cannot have base classes">; @@ -8200,11 +8619,14 @@ def err_conv_function_with_complex_decl : Error< def err_conv_function_redeclared : Error< "conversion function cannot be redeclared">; def warn_conv_to_self_not_used : Warning< - "conversion function converting %0 to itself will never be used">; + "conversion function converting %0 to itself will never be used">, + InGroup<ClassConversion>; def warn_conv_to_base_not_used : Warning< - "conversion function converting %0 to its base class %1 will never be used">; + "conversion function converting %0 to its base class %1 will never be used">, + InGroup<ClassConversion>; def warn_conv_to_void_not_used : Warning< - "conversion function converting %0 to %1 will never be used">; + "conversion function converting %0 to %1 will never be used">, + InGroup<ClassConversion>; def warn_not_compound_assign : Warning< "use of unary operator that may be intended as compound assignment (%0=)">; @@ -8260,7 +8682,7 @@ def note_deleted_type_mismatch : Note< def warn_cxx17_compat_defaulted_method_type_mismatch : Warning< "explicitly defaulting this %sub{select_special_member_kind}0 with a type " "different from the implicit type is incompatible with C++ standards before " - "C++2a">, InGroup<CXXPre2aCompat>, DefaultIgnore; + "C++20">, InGroup<CXXPre20Compat>, DefaultIgnore; def warn_vbase_moved_multiple_times : Warning< "defaulted move assignment operator of %0 will move assign virtual base " "class %1 multiple times">, InGroup<DiagGroup<"multiple-move-vbase">>; @@ -8274,10 +8696,10 @@ def select_defaulted_comparison_kind : TextSubstitution< "%select{<ERROR>|equality|three-way|equality|relational}0 comparison " "operator">; def ext_defaulted_comparison : ExtWarn< - "defaulted comparison operators are a C++20 extension">, InGroup<CXX2a>; + "defaulted comparison operators are a C++20 extension">, InGroup<CXX20>; def warn_cxx17_compat_defaulted_comparison : Warning< "defaulted comparison operators are incompatible with C++ standards " - "before C++20">, InGroup<CXXPre2aCompat>, DefaultIgnore; + "before C++20">, InGroup<CXXPre20Compat>, DefaultIgnore; def err_defaulted_comparison_template : Error< "comparison operator template cannot be defaulted">; def err_defaulted_comparison_out_of_class : Error< @@ -8334,6 +8756,12 @@ def note_defaulted_comparison_cannot_deduce : Note< "return type of defaulted 'operator<=>' cannot be deduced because " "return type %2 of three-way comparison for %select{|member|base class}0 %1 " "is not a standard comparison category type">; +def err_defaulted_comparison_cannot_deduce_undeduced_auto : Error< + "return type of defaulted 'operator<=>' cannot be deduced because " + "three-way comparison for %select{|member|base class}0 %1 " + "has a deduced return type and is not yet defined">; +def note_defaulted_comparison_cannot_deduce_undeduced_auto : Note< + "%select{|member|base class}0 %1 declared here">; def note_defaulted_comparison_cannot_deduce_callee : Note< "selected 'operator<=>' for %select{|member|base class}0 %1 declared here">; def err_incorrect_defaulted_comparison_constexpr : Error< @@ -8846,6 +9274,8 @@ def err_block_on_nonlocal : Error< "__block attribute not allowed, only allowed on local variables">; def err_block_on_vm : Error< "__block attribute not allowed on declaration with a variably modified type">; +def err_sizeless_nonlocal : Error< + "non-local variable with sizeless type %0">; def err_vec_builtin_non_vector : Error< "first two arguments to %0 must be vectors">; @@ -8897,6 +9327,10 @@ def err_argument_not_shifted_byte : Error< "argument should be an 8-bit value shifted by a multiple of 8 bits">; def err_argument_not_shifted_byte_or_xxff : Error< "argument should be an 8-bit value shifted by a multiple of 8 bits, or in the form 0x??FF">; +def err_rotation_argument_to_cadd + : Error<"argument should be the value 90 or 270">; +def err_rotation_argument_to_cmla + : Error<"argument should be the value 0, 90, 180 or 270">; def warn_neon_vector_initializer_non_portable : Warning< "vector initializers are not compatible with NEON intrinsics in big endian " "mode">, InGroup<DiagGroup<"nonportable-vector-initialization">>; @@ -8927,12 +9361,8 @@ def err_x86_builtin_invalid_rounding : Error< "invalid rounding argument">; def err_x86_builtin_invalid_scale : Error< "scale argument must be 1, 2, 4, or 8">; -def err_hexagon_builtin_unsupported_cpu : Error< - "builtin is not supported on this CPU">; -def err_hexagon_builtin_requires_hvx : Error< - "builtin requires HVX">; -def err_hexagon_builtin_unsupported_hvx : Error< - "builtin is not supported on this version of HVX">; +def err_x86_builtin_tile_arg_duplicate : Error< + "tile arguments must refer to different tiles">; def err_builtin_target_unsupported : Error< "builtin is not supported on this target">; @@ -9350,7 +9780,7 @@ def err_omp_expected_var_name_member_expr : Error< def err_omp_expected_var_name_member_expr_or_array_item : Error< "expected variable name%select{|, data member of current class}0, array element or array section">; def err_omp_expected_addressable_lvalue_or_array_item : Error< - "expected addressable lvalue expression, array element or array section">; + "expected addressable lvalue expression, array element%select{ or array section|, array section or array shaping expression}0%select{| of non 'omp_depend_t' type}1">; def err_omp_expected_named_var_member_or_array_expression: Error< "expected expression containing only member accesses and/or array sections based on named variables">; def err_omp_bit_fields_forbidden_in_clause : Error< @@ -9425,6 +9855,12 @@ def note_omp_conversion_here : Note< def err_omp_ambiguous_conversion : Error< "ambiguous conversion from type %0 to an integral or unscoped " "enumeration type">; +def err_omp_iterator_not_integral_or_pointer : Error< + "expected integral or pointer type as the iterator-type, not %0">; +def err_omp_iterator_step_not_integral : Error< + "iterator step expression %0 is not the integral expression">; +def err_omp_iterator_step_constant_zero : Error< + "iterator step expression %0 evaluates to 0">; def err_omp_required_access : Error< "%0 variable must be %1">; def err_omp_const_variable : Error< @@ -9513,8 +9949,6 @@ 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< "list item of type %0 is not valid for specified reduction operation: unable to provide default initialization value">; -def err_omp_in_reduction_not_task_reduction : Error< - "in_reduction variable must appear in a task_reduction clause">; def err_omp_reduction_identifier_mismatch : Error< "in_reduction variable must have the same reduction operation as in a task_reduction clause">; def note_omp_previous_reduction_identifier : Note< @@ -9524,15 +9958,20 @@ def err_omp_prohibited_region : Error< "%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?|" - "; perhaps you forget to enclose 'omp %3' directive into a teams region?}2">; + "; perhaps you forget to enclose 'omp %3' directive into a teams region?|" + "; perhaps you forget to enclose 'omp %3' directive into a for, simd, for simd, parallel for, or parallel for simd region?}2">; def err_omp_prohibited_region_simd : Error< - "OpenMP constructs may not be nested inside a simd region%select{| except for ordered simd, simd or atomic directive}0">; + "OpenMP constructs may not be nested inside a simd region%select{| except for ordered simd, simd, scan, or atomic directive}0">; def err_omp_prohibited_region_atomic : Error< "OpenMP constructs may not be nested inside an atomic region">; def err_omp_prohibited_region_critical_same_name : Error< "cannot nest 'critical' regions having the same name %0">; def note_omp_previous_critical_region : Note< "previous 'critical' region starts here">; +def err_omp_several_directives_in_region : Error< + "exactly one '%0' directive must appear in the loop body of an enclosing directive">; +def note_omp_previous_directive : Note< + "previous '%0' directive used here">; def err_omp_sections_not_compound_stmt : Error< "the statement for '#pragma omp sections' must be a compound statement">; def err_omp_parallel_sections_not_compound_stmt : Error< @@ -9576,7 +10015,11 @@ def note_omp_atomic_capture: Note< "%select{expected assignment expression|expected compound statement|expected exactly two expression statements|expected in right hand side of the first expression}0">; def err_omp_atomic_several_clauses : Error< "directive '#pragma omp atomic' cannot contain more than one 'read', 'write', 'update' or 'capture' clause">; -def note_omp_atomic_previous_clause : Note< +def err_omp_several_mem_order_clauses : Error< + "directive '#pragma omp %0' cannot contain more than one %select{'seq_cst', 'relaxed', |}1'acq_rel', 'acquire' or 'release' clause">; +def err_omp_atomic_incompatible_mem_order_clause : Error< + "directive '#pragma omp atomic%select{ %0|}1' cannot be used with '%2' clause">; +def note_omp_previous_mem_order_clause : Note< "'%0' clause used here">; def err_omp_target_contains_not_only_teams : Error< "target construct with nested teams region contains statements outside of the teams construct">; @@ -9610,10 +10053,16 @@ def err_omp_declare_mapper_redefinition : Error< def err_omp_invalid_mapper: Error< "cannot find a valid user-defined mapper for type %0 with name %1">; def err_omp_array_section_use : Error<"OpenMP array section is not allowed here">; +def err_omp_array_shaping_use : Error<"OpenMP array shaping operation is not allowed here">; +def err_omp_iterator_use : Error<"OpenMP iterator 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_typecheck_shaping_not_integer : Error< + "array shaping operation dimension is not an integer">; +def err_omp_shaping_dimension_not_positive : Error< + "array shaping dimension is evaluated to a non-positive value %0">; 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'">, @@ -9624,6 +10073,8 @@ def err_omp_section_not_subset_of_array : Error< "array section must be a subset of the original array">; def err_omp_section_length_negative : Error< "section length is evaluated to a negative value %0">; +def err_omp_section_stride_non_positive : Error< + "section stride is evaluated to a non-positive value %0">; 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< @@ -9645,7 +10096,7 @@ def err_omp_ordered_directive_with_param : Error< 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">; + "'ordered' clause%select{| with specified parameter}0">; 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< @@ -9660,9 +10111,9 @@ 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< +def err_omp_clauses_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< +def note_omp_previous_clause : 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">; @@ -9684,14 +10135,18 @@ 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_depend_zero_length_array_section_not_allowed : Error< "zero-length array section is not allowed in 'depend' clause">; +def err_omp_depend_sink_source_with_modifier : Error< + "depend modifier cannot be used with 'sink' or 'source' depend type">; +def err_omp_depend_modifier_not_iterator : Error< + "expected iterator specification as depend modifier">; 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">; +def err_omp_simple_clause_incompatible_with_ordered : Error< + "'%0' clause with '%1' modifier cannot be specified if an 'ordered' clause is specified">; def err_omp_ordered_simd : Error< "'ordered' clause with a parameter can not be specified in '#pragma omp %0' directive">; def err_omp_variable_in_given_clause_and_dsa : Error< @@ -9713,7 +10168,8 @@ def warn_omp_nesting_simd : Warning< InGroup<SourceUsesOpenMP>; def err_omp_orphaned_device_directive : Error< "orphaned 'omp %0' directives are prohibited" - "; perhaps you forget to enclose the directive into a %select{|||target |teams }1region?">; + "; perhaps you forget to enclose the directive into a " + "%select{|||target |teams|for, simd, for simd, parallel for, or parallel for simd }1region?">; def err_omp_reduction_non_addressable_expression : Error< "expected addressable reduction item for the task-based directives">; def err_omp_reduction_with_nogroup : Error< @@ -9729,10 +10185,10 @@ def err_omp_requires_clause_redeclaration : Error < "Only one %0 clause can appear on a requires directive in a single translation unit">; def note_omp_requires_previous_clause : Note < "%0 clause previously used here">; -def err_omp_target_before_requires : Error < - "target region encountered before requires directive with '%0' clause">; -def note_omp_requires_encountered_target : Note < - "target previously encountered here">; +def err_omp_directive_before_requires : Error < + "'%0' region encountered before requires directive with '%1' clause">; +def note_omp_requires_encountered_directive : Note < + "'%0' previously encountered here">; def err_omp_invalid_scope : Error < "'#pragma omp %0' directive must appear only in file scope">; def note_omp_invalid_length_on_this_ptr_mapping : Note < @@ -9743,8 +10199,29 @@ def note_omp_invalid_subscript_on_this_ptr_map : Note < "expected 'this' subscript expression on map clause to be 'this[0]'">; def err_omp_invalid_map_this_expr : Error < "invalid 'this' expression on 'map' clause">; -def err_implied_omp_allocator_handle_t_not_found : Error< - "omp_allocator_handle_t type not found; include <omp.h>">; +def err_omp_implied_type_not_found : Error< + "'%0' type not found; include <omp.h>">; +def err_omp_expected_omp_depend_t_lvalue : Error< + "expected lvalue expression%select{ of 'omp_depend_t' type, not %1|}0">; +def err_omp_depobj_expected : Error< + "expected depobj expression">; +def err_omp_depobj_single_clause_expected : Error< + "exactly one of 'depend', 'destroy', or 'update' clauses is expected">; +def err_omp_scan_single_clause_expected : Error< + "exactly one of 'inclusive' or 'exclusive' clauses is expected">; +def err_omp_inclusive_exclusive_not_reduction : Error< + "the list item must appear in 'reduction' clause with the 'inscan' modifier " + "of the parent directive">; +def err_omp_reduction_not_inclusive_exclusive : Error< + "the inscan reduction list item must appear as a list item in an 'inclusive' or" + " 'exclusive' clause on an inner 'omp scan' directive">; +def err_omp_wrong_inscan_reduction : Error< + "'inscan' modifier can be used only in 'omp for', 'omp simd', 'omp for simd'," + " 'omp parallel for', or 'omp parallel for simd' directive">; +def err_omp_inscan_reduction_expected : Error< + "expected 'reduction' clause with the 'inscan' modifier">; +def note_omp_previous_inscan_reduction : Note< + "'reduction' clause with 'inscan' modifier is used here">; def err_omp_expected_predefined_allocator : Error< "expected one of the predefined allocators for the variables with the static " "storage: 'omp_default_mem_alloc', 'omp_large_cap_mem_alloc', " @@ -9773,8 +10250,8 @@ def err_omp_invariant_or_linear_dependency : Error< "expected loop invariant expression or '<invariant1> * %0 + <invariant2>' kind of expression">; def err_omp_wrong_dependency_iterator_type : Error< "expected an integer or a pointer type of the outer loop counter '%0' for non-rectangular nests">; -def err_omp_unsupported_type : Error < - "host requires %0 bit size %1 type support, but device '%2' does not support it">; +def err_device_unsupported_type : Error < + "%0 requires %1 bit size %2 type support, but device '%3' does not support it">; def err_omp_lambda_capture_in_declare_target_not_to : Error< "variable captured in declare target region must appear in a to clause">; def err_omp_device_type_mismatch : Error< @@ -9787,6 +10264,13 @@ def warn_omp_declare_target_after_first_use : Warning< InGroup<OpenMPTarget>; def err_omp_declare_variant_incompat_attributes : Error< "'#pragma omp declare variant' is not compatible with any target-specific attributes">; +def warn_omp_declare_variant_score_not_constant + : Warning<"score expressions in the OpenMP context selector need to be " + "constant; %0 is not and will be ignored">, + InGroup<SourceUsesOpenMP>; +def err_omp_declare_variant_user_condition_not_constant + : Error<"the user condition in the OpenMP context selector needs to be " + "constant; %0 is not">; def warn_omp_declare_variant_after_used : Warning< "'#pragma omp declare variant' cannot be applied for function after first " "usage; the original function might be used">, InGroup<SourceUsesOpenMP>; @@ -9814,6 +10298,37 @@ def err_omp_one_defaultmap_each_category: Error< def err_omp_lastprivate_conditional_non_scalar : Error< "expected list item of scalar type in 'lastprivate' clause with 'conditional' modifier" >; +def err_omp_flush_order_clause_and_list : Error< + "'flush' directive with memory order clause '%0' cannot have the list">; +def note_omp_flush_order_clause_here : Note< + "memory order clause '%0' is specified here">; +def err_omp_non_lvalue_in_map_or_motion_clauses: Error< + "expected addressable lvalue in '%0' clause">; +def err_omp_var_expected : Error< + "expected variable of the '%0' type%select{|, not %2}1">; +def warn_nested_declare_variant + : Warning<"nesting `omp begin/end declare variant` is not supported yet; " + "nested context ignored">, + InGroup<SourceUsesOpenMP>; +def err_omp_non_pointer_type_array_shaping_base : Error< + "expected expression with a pointer to a complete type as a base of an array " + "shaping operation">; +def err_omp_reduction_task_not_parallel_or_worksharing : Error< + "'reduction' clause with 'task' modifier allowed only on non-simd parallel or" + " worksharing constructs">; +def err_omp_expected_array_alloctraits : Error< + "expected constant sized array of 'omp_alloctrait_t' elements, not %0">; +def err_omp_predefined_allocator_with_traits : Error< + "predefined allocator cannot have traits specified">; +def note_omp_predefined_allocator : Note< + "predefined trait '%0' used here">; +def err_omp_nonpredefined_allocator_without_traits : Error< + "non-predefined allocator must have traits specified">; +def err_omp_allocator_used_in_clauses : Error< + "allocators used in 'uses_allocators' clause cannot appear in other " + "data-sharing or data-mapping attribute clauses">; +def err_omp_allocator_not_in_uses_allocators : Error< + "allocator must be specified in the 'uses_allocators' clause">; } // end of OpenMP category let CategoryName = "Related Result Type Issue" in { @@ -9882,11 +10397,6 @@ def err_module_unimported_use : Error< "explicit specialization|partial specialization}0 of %1 must be imported " "from module '%2' before it is required">; def err_module_unimported_use_header : Error< - "missing '#include %3'; " - "%select{declaration|definition|default argument|" - "explicit specialization|partial specialization}0 of %1 must be imported " - "from module '%2' before it is required">; -def err_module_unimported_use_global_module_fragment : Error< "%select{missing '#include'|missing '#include %3'}2; " "%select{||default argument of |explicit specialization of |" "partial specialization of }0%1 must be " @@ -9896,6 +10406,10 @@ def err_module_unimported_use_multiple : Error< "%select{declaration|definition|default argument|" "explicit specialization|partial specialization}0 of %1 must be imported " "from one of the following modules before it is required:%2">; +def note_unreachable_entity : Note< + "%select{declaration|definition|default argument declared|" + "explicit specialization declared|partial specialization declared}0 here " + "is not %select{visible|reachable|reachable|reachable|reachable|reachable}0">; def ext_module_import_in_extern_c : ExtWarn< "import of C++ module '%0' appears within extern \"C\" language linkage " "specification">, DefaultError, @@ -10036,7 +10550,16 @@ def err_await_suspend_invalid_return_type : Error< def note_await_ready_no_bool_conversion : Note< "return type of 'await_ready' is required to be contextually convertible to 'bool'" >; -} +def warn_coroutine_handle_address_invalid_return_type : Warning < + "return type of 'coroutine_handle<>::address should be 'void*' (have %0) in order to get capability with existing async C API.">, + InGroup<Coroutine>; +def err_coroutine_promise_final_suspend_requires_nothrow : Error< + "the expression 'co_await __promise.final_suspend()' is required to be non-throwing" +>; +def note_coroutine_function_declare_noexcept : Note< + "must be declared with 'noexcept'" +>; +} // end of coroutines issue category let CategoryName = "Documentation Issue" in { def warn_not_a_doxygen_trailing_member_comment : Warning< @@ -10281,10 +10804,46 @@ def err_builtin_launder_invalid_arg : Error< "%select{non-pointer|function pointer|void pointer}0 argument to " "'__builtin_launder' is not allowed">; +def err_builtin_matrix_disabled: Error< + "matrix types extension is disabled. Pass -fenable-matrix to enable it">; +def err_matrix_index_not_integer: Error< + "matrix %select{row|column}0 index is not an integer">; +def err_matrix_index_outside_range: Error< + "matrix %select{row|column}0 index is outside the allowed range [0, %1)">; +def err_matrix_incomplete_index: Error< + "single subscript expressions are not allowed for matrix values">; +def err_matrix_separate_incomplete_index: Error< + "matrix row and column subscripts cannot be separated by any expression">; +def err_matrix_subscript_comma: Error< + "comma expressions are not allowed as indices in matrix subscript expressions">; +def err_builtin_matrix_arg: Error<"1st argument must be a matrix">; +def err_builtin_matrix_scalar_unsigned_arg: Error< + "%0 argument must be a constant unsigned integer expression">; +def err_builtin_matrix_pointer_arg: Error< + "%ordinal0 argument must be a pointer to a valid matrix element type">; +def err_builtin_matrix_pointer_arg_mismatch: Error< + "the pointee of the 2nd argument must match the element type of the 1st argument (%0 != %1)">; +def err_builtin_matrix_store_to_const: Error< + "cannot store matrix to read-only pointer">; +def err_builtin_matrix_stride_too_small: Error< + "stride must be greater or equal to the number of rows">; +def err_builtin_matrix_invalid_dimension: Error< + "%0 dimension is outside the allowed range [1, %1]">; + +def warn_mismatched_import : Warning< + "import %select{module|name}0 (%1) does not match the import %select{module|name}0 (%2) of the " + "previous declaration">, + InGroup<IgnoredAttributes>; +def warn_import_on_definition : Warning< + "import %select{module|name}0 cannot be applied to a function with a definition">, + InGroup<IgnoredAttributes>; + def err_preserve_field_info_not_field : Error< "__builtin_preserve_field_info argument %0 not a field access">; def err_preserve_field_info_not_const: Error< "__builtin_preserve_field_info argument %0 not a constant">; +def err_btf_type_id_not_const: Error< + "__builtin_btf_type_id argument %0 not a constant">; def err_bit_cast_non_trivially_copyable : Error< "__builtin_bit_cast %select{source|destination}0 type must be trivially copyable">; @@ -10305,4 +10864,16 @@ def warn_sycl_kernel_return_type : Warning< "function template with 'sycl_kernel' attribute must have a 'void' return type">, InGroup<IgnoredAttributes>; +def err_ext_int_bad_size : Error<"%select{signed|unsigned}0 _ExtInt must " + "have a bit size of at least %select{2|1}0">; +def err_ext_int_max_size : Error<"%select{signed|unsigned}0 _ExtInt of bit " + "sizes greater than %1 not supported">; + +// errors of expect.with.probability +def err_probability_not_constant_float : Error< + "probability argument to __builtin_expect_with_probability must be constant " + "floating-point expression">; +def err_probability_out_of_range : Error< + "probability argument to __builtin_expect_with_probability is outside the " + "range [0.0, 1.0]">; } // end of sema component. diff --git a/clang/include/clang/Basic/ExpressionTraits.h b/clang/include/clang/Basic/ExpressionTraits.h index 85005330a0af..b38ebd9ac60b 100644 --- a/clang/include/clang/Basic/ExpressionTraits.h +++ b/clang/include/clang/Basic/ExpressionTraits.h @@ -14,12 +14,24 @@ #ifndef LLVM_CLANG_BASIC_EXPRESSIONTRAITS_H #define LLVM_CLANG_BASIC_EXPRESSIONTRAITS_H +#include "llvm/Support/Compiler.h" + namespace clang { - enum ExpressionTrait { - ET_IsLValueExpr, - ET_IsRValueExpr - }; -} +enum ExpressionTrait { +#define EXPRESSION_TRAIT(Spelling, Name, Key) ET_##Name, +#include "clang/Basic/TokenKinds.def" + ET_Last = -1 // ET_Last == last ET_XX in the enum. +#define EXPRESSION_TRAIT(Spelling, Name, Key) +1 +#include "clang/Basic/TokenKinds.def" +}; + +/// Return the internal name of type trait \p T. Never null. +const char *getTraitName(ExpressionTrait T) LLVM_READONLY; + +/// Return the spelling of the type trait \p TT. Never null. +const char *getTraitSpelling(ExpressionTrait T) LLVM_READONLY; + +} // namespace clang #endif diff --git a/clang/include/clang/Basic/FPOptions.def b/clang/include/clang/Basic/FPOptions.def new file mode 100644 index 000000000000..6b6789b8ecc8 --- /dev/null +++ b/clang/include/clang/Basic/FPOptions.def @@ -0,0 +1,26 @@ +//===--- FPOptions.def - Floating Point Options database --------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// This file defines the Floating Point language options. Users of this file +// must define the FPOPT macro to make use of this information. +#ifndef OPTION +# error Define the OPTION macro to handle floating point language options +#endif + +// OPTION(name, type, width, previousName) +OPTION(FPContractMode, LangOptions::FPModeKind, 2, First) +OPTION(RoundingMode, RoundingMode, 3, FPContractMode) +OPTION(FPExceptionMode, LangOptions::FPExceptionModeKind, 2, RoundingMode) +OPTION(AllowFEnvAccess, bool, 1, FPExceptionMode) +OPTION(AllowFPReassociate, bool, 1, AllowFEnvAccess) +OPTION(NoHonorNaNs, bool, 1, AllowFPReassociate) +OPTION(NoHonorInfs, bool, 1, NoHonorNaNs) +OPTION(NoSignedZero, bool, 1, NoHonorInfs) +OPTION(AllowReciprocal, bool, 1, NoSignedZero) +OPTION(AllowApproxFunc, bool, 1, AllowReciprocal) +#undef OPTION diff --git a/clang/include/clang/Basic/Features.def b/clang/include/clang/Basic/Features.def index 28eb694ba9a8..999bcb7e2e29 100644 --- a/clang/include/clang/Basic/Features.def +++ b/clang/include/clang/Basic/Features.def @@ -36,6 +36,7 @@ #define EXTENSION(Name, Predicate) #endif +FEATURE(speculative_load_hardening, LangOpts.SpeculativeLoadHardening) FEATURE(address_sanitizer, LangOpts.Sanitize.hasOneOf(SanitizerKind::Address | SanitizerKind::KernelAddress)) @@ -252,6 +253,8 @@ EXTENSION(overloadable_unmarked, true) EXTENSION(pragma_clang_attribute_namespaces, true) EXTENSION(pragma_clang_attribute_external_declaration, true) EXTENSION(gnu_asm, LangOpts.GNUAsm) +EXTENSION(gnu_asm_goto_with_outputs, LangOpts.GNUAsm) +EXTENSION(matrix_types, LangOpts.MatrixTypes) #undef EXTENSION #undef FEATURE diff --git a/clang/include/clang/Basic/FileManager.h b/clang/include/clang/Basic/FileManager.h index fed43786d410..089304e1d1e6 100644 --- a/clang/include/clang/Basic/FileManager.h +++ b/clang/include/clang/Basic/FileManager.h @@ -18,6 +18,7 @@ #include "clang/Basic/LLVM.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/IntrusiveRefCntPtr.h" +#include "llvm/ADT/PointerUnion.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" @@ -378,15 +379,19 @@ public: /// Open the specified file as a MemoryBuffer, returning a new /// MemoryBuffer if successful, otherwise returning null. llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> - getBufferForFile(const FileEntry *Entry, bool isVolatile = false); + getBufferForFile(const FileEntry *Entry, bool isVolatile = false, + bool RequiresNullTerminator = true); llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> - getBufferForFile(StringRef Filename, bool isVolatile = false) { - return getBufferForFileImpl(Filename, /*FileSize=*/-1, isVolatile); + getBufferForFile(StringRef Filename, bool isVolatile = false, + bool RequiresNullTerminator = true) { + return getBufferForFileImpl(Filename, /*FileSize=*/-1, isVolatile, + RequiresNullTerminator); } private: llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> - getBufferForFileImpl(StringRef Filename, int64_t FileSize, bool isVolatile); + getBufferForFileImpl(StringRef Filename, int64_t FileSize, bool isVolatile, + bool RequiresNullTerminator); public: /// Get the 'stat' information for the given \p Path. diff --git a/clang/include/clang/Basic/FixedPoint.h b/clang/include/clang/Basic/FixedPoint.h index a931e21e18f1..0d181f30907f 100644 --- a/clang/include/clang/Basic/FixedPoint.h +++ b/clang/include/clang/Basic/FixedPoint.h @@ -28,8 +28,8 @@ class QualType; /// The fixed point semantics work similarly to llvm::fltSemantics. The width /// specifies the whole bit width of the underlying scaled integer (with padding /// if any). The scale represents the number of fractional bits in this type. -/// When HasUnsignedPadding is true and this type is signed, the first bit -/// in the value this represents is treaded as padding. +/// When HasUnsignedPadding is true and this type is unsigned, the first bit +/// in the value this represents is treated as padding. class FixedPointSemantics { public: FixedPointSemantics(unsigned Width, unsigned Scale, bool IsSigned, @@ -75,11 +75,11 @@ public: } private: - unsigned Width; - unsigned Scale; - bool IsSigned; - bool IsSaturated; - bool HasUnsignedPadding; + unsigned Width : 16; + unsigned Scale : 13; + unsigned IsSigned : 1; + unsigned IsSaturated : 1; + unsigned HasUnsignedPadding : 1; }; /// The APFixedPoint class works similarly to APInt/APSInt in that it is a @@ -93,49 +93,52 @@ private: /// point types and should eventually be moved to LLVM if fixed point types gain /// native IR support. class APFixedPoint { - public: - APFixedPoint(const llvm::APInt &Val, const FixedPointSemantics &Sema) - : Val(Val, !Sema.isSigned()), Sema(Sema) { - assert(Val.getBitWidth() == Sema.getWidth() && - "The value should have a bit width that matches the Sema width"); - } - - APFixedPoint(uint64_t Val, const FixedPointSemantics &Sema) - : APFixedPoint(llvm::APInt(Sema.getWidth(), Val, Sema.isSigned()), - Sema) {} - - // Zero initialization. - APFixedPoint(const FixedPointSemantics &Sema) : APFixedPoint(0, Sema) {} - - llvm::APSInt getValue() const { return llvm::APSInt(Val, !Sema.isSigned()); } - inline unsigned getWidth() const { return Sema.getWidth(); } - inline unsigned getScale() const { return Sema.getScale(); } - inline bool isSaturated() const { return Sema.isSaturated(); } - inline bool isSigned() const { return Sema.isSigned(); } - inline bool hasPadding() const { return Sema.hasUnsignedPadding(); } - FixedPointSemantics getSemantics() const { return Sema; } - - bool getBoolValue() const { return Val.getBoolValue(); } - - // Convert this number to match the semantics provided. If the overflow - // parameter is provided, set this value to true or false to indicate if this - // operation results in an overflow. - APFixedPoint convert(const FixedPointSemantics &DstSema, - bool *Overflow = nullptr) const; - - // Perform binary operations on a fixed point type. The resulting fixed point - // value will be in the common, full precision semantics that can represent - // the precision and ranges os both input values. See convert() for an - // explanation of the Overflow parameter. - APFixedPoint add(const APFixedPoint &Other, bool *Overflow = nullptr) const; - - /// Perform a unary negation (-X) on this fixed point type, taking into - /// account saturation if applicable. - APFixedPoint negate(bool *Overflow = nullptr) const; - - APFixedPoint shr(unsigned Amt) const { - return APFixedPoint(Val >> Amt, Sema); - } +public: + APFixedPoint(const llvm::APInt &Val, const FixedPointSemantics &Sema) + : Val(Val, !Sema.isSigned()), Sema(Sema) { + assert(Val.getBitWidth() == Sema.getWidth() && + "The value should have a bit width that matches the Sema width"); + } + + APFixedPoint(uint64_t Val, const FixedPointSemantics &Sema) + : APFixedPoint(llvm::APInt(Sema.getWidth(), Val, Sema.isSigned()), + Sema) {} + + // Zero initialization. + APFixedPoint(const FixedPointSemantics &Sema) : APFixedPoint(0, Sema) {} + + llvm::APSInt getValue() const { return llvm::APSInt(Val, !Sema.isSigned()); } + inline unsigned getWidth() const { return Sema.getWidth(); } + inline unsigned getScale() const { return Sema.getScale(); } + inline bool isSaturated() const { return Sema.isSaturated(); } + inline bool isSigned() const { return Sema.isSigned(); } + inline bool hasPadding() const { return Sema.hasUnsignedPadding(); } + FixedPointSemantics getSemantics() const { return Sema; } + + bool getBoolValue() const { return Val.getBoolValue(); } + + // Convert this number to match the semantics provided. If the overflow + // parameter is provided, set this value to true or false to indicate if this + // operation results in an overflow. + APFixedPoint convert(const FixedPointSemantics &DstSema, + bool *Overflow = nullptr) const; + + // Perform binary operations on a fixed point type. The resulting fixed point + // value will be in the common, full precision semantics that can represent + // the precision and ranges of both input values. See convert() for an + // explanation of the Overflow parameter. + APFixedPoint add(const APFixedPoint &Other, bool *Overflow = nullptr) const; + APFixedPoint sub(const APFixedPoint &Other, bool *Overflow = nullptr) const; + APFixedPoint mul(const APFixedPoint &Other, bool *Overflow = nullptr) const; + APFixedPoint div(const APFixedPoint &Other, bool *Overflow = nullptr) const; + + /// Perform a unary negation (-X) on this fixed point type, taking into + /// account saturation if applicable. + APFixedPoint negate(bool *Overflow = nullptr) const; + + APFixedPoint shr(unsigned Amt) const { + return APFixedPoint(Val >> Amt, Sema); + } APFixedPoint shl(unsigned Amt) const { return APFixedPoint(Val << Amt, Sema); @@ -165,7 +168,7 @@ class APFixedPoint { std::string toString() const { llvm::SmallString<40> S; toString(S); - return S.str(); + return std::string(S.str()); } // If LHS > RHS, return 1. If LHS == RHS, return 0. If LHS < RHS, return -1. diff --git a/clang/include/clang/Basic/IdentifierTable.h b/clang/include/clang/Basic/IdentifierTable.h index ea5d7adeb2da..fc554a35e721 100644 --- a/clang/include/clang/Basic/IdentifierTable.h +++ b/clang/include/clang/Basic/IdentifierTable.h @@ -48,6 +48,8 @@ using IdentifierLocPair = std::pair<IdentifierInfo *, SourceLocation>; /// of a pointer to one of these classes. enum { IdentifierInfoAlignment = 8 }; +static constexpr int ObjCOrBuiltinIDBits = 15; + /// One of these records is kept for each identifier that /// is lexed. This contains information about whether the token was \#define'd, /// is a language keyword, or if it is a front-end token of some sort (e.g. a @@ -63,7 +65,7 @@ class alignas(IdentifierInfoAlignment) IdentifierInfo { // ObjC keyword ('protocol' in '@protocol') or builtin (__builtin_inf). // First NUM_OBJC_KEYWORDS values are for Objective-C, // the remaining values are for builtins. - unsigned ObjCOrBuiltinID : 13; + unsigned ObjCOrBuiltinID : ObjCOrBuiltinIDBits; // True if there is a #define for this. unsigned HasMacro : 1; @@ -108,7 +110,10 @@ class alignas(IdentifierInfoAlignment) IdentifierInfo { // True if this is the 'import' contextual keyword. unsigned IsModulesImport : 1; - // 29 bits left in a 64-bit word. + // True if this is a mangled OpenMP variant name. + unsigned IsMangledOpenMPVariantName : 1; + + // 28 bits left in a 64-bit word. // Managed by the language front-end. void *FETokenInfo = nullptr; @@ -121,7 +126,7 @@ class alignas(IdentifierInfoAlignment) IdentifierInfo { IsPoisoned(false), IsCPPOperatorKeyword(false), NeedsHandleIdentifier(false), IsFromAST(false), ChangedAfterLoad(false), FEChangedAfterLoad(false), RevertedTokenID(false), OutOfDate(false), - IsModulesImport(false) {} + IsModulesImport(false), IsMangledOpenMPVariantName(false) {} public: IdentifierInfo(const IdentifierInfo &) = delete; @@ -371,6 +376,12 @@ public: RecomputeNeedsHandleIdentifier(); } + /// Determine whether this is the mangled name of an OpenMP variant. + bool isMangledOpenMPVariantName() const { return IsMangledOpenMPVariantName; } + + /// Set whether this is the mangled name of an OpenMP variant. + void setMangledOpenMPVariantName(bool I) { IsMangledOpenMPVariantName = I; } + /// Return true if this identifier is an editor placeholder. /// /// Editor placeholders are produced by the code-completion engine and are @@ -967,7 +978,7 @@ struct PointerLikeTypeTraits<clang::Selector> { return clang::Selector(reinterpret_cast<uintptr_t>(P)); } - enum { NumLowBitsAvailable = 0 }; + static constexpr int NumLowBitsAvailable = 0; }; // Provide PointerLikeTypeTraits for IdentifierInfo pointers, which @@ -982,7 +993,7 @@ struct PointerLikeTypeTraits<clang::IdentifierInfo*> { return static_cast<clang::IdentifierInfo*>(P); } - enum { NumLowBitsAvailable = 1 }; + static constexpr int NumLowBitsAvailable = 1; }; template<> @@ -995,7 +1006,7 @@ struct PointerLikeTypeTraits<const clang::IdentifierInfo*> { return static_cast<const clang::IdentifierInfo*>(P); } - enum { NumLowBitsAvailable = 1 }; + static constexpr int NumLowBitsAvailable = 1; }; } // namespace llvm diff --git a/clang/include/clang/Basic/JsonSupport.h b/clang/include/clang/Basic/JsonSupport.h index bbcc747e6847..8b02e440df44 100644 --- a/clang/include/clang/Basic/JsonSupport.h +++ b/clang/include/clang/Basic/JsonSupport.h @@ -13,7 +13,7 @@ #include "clang/Basic/SourceManager.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/raw_ostream.h" - +#include <iterator> namespace clang { @@ -97,9 +97,22 @@ inline void printSourceLocationAsJson(raw_ostream &Out, SourceLocation Loc, // The macro expansion and spelling pos is identical for file locs. if (AddBraces) Out << "{ "; + std::string filename(PLoc.getFilename()); +#ifdef _WIN32 + // Remove forbidden Windows path characters + auto RemoveIt = + std::remove_if(filename.begin(), filename.end(), [](auto Char) { + static const char ForbiddenChars[] = "<>*?\"|"; + return std::find(std::begin(ForbiddenChars), std::end(ForbiddenChars), + Char) != std::end(ForbiddenChars); + }); + filename.erase(RemoveIt, filename.end()); + // Handle windows-specific path delimiters. + std::replace(filename.begin(), filename.end(), '\\', '/'); +#endif Out << "\"line\": " << PLoc.getLine() << ", \"column\": " << PLoc.getColumn() - << ", \"file\": \"" << PLoc.getFilename() << "\""; + << ", \"file\": \"" << filename << "\""; if (AddBraces) Out << " }"; return; diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def index 068f206f4484..70f68d664bb7 100644 --- a/clang/include/clang/Basic/LangOptions.def +++ b/clang/include/clang/Basic/LangOptions.def @@ -91,7 +91,7 @@ LANGOPT(CPlusPlus , 1, 0, "C++") LANGOPT(CPlusPlus11 , 1, 0, "C++11") LANGOPT(CPlusPlus14 , 1, 0, "C++14") LANGOPT(CPlusPlus17 , 1, 0, "C++17") -LANGOPT(CPlusPlus2a , 1, 0, "C++2a") +LANGOPT(CPlusPlus20 , 1, 0, "C++20") LANGOPT(ObjC , 1, 0, "Objective-C") BENIGN_LANGOPT(ObjCDefaultSynthProperties , 1, 0, "Objective-C auto-synthesized properties") @@ -132,6 +132,7 @@ LANGOPT(DWARFExceptions , 1, 0, "dwarf exception handling") LANGOPT(SjLjExceptions , 1, 0, "setjmp-longjump exception handling") LANGOPT(SEHExceptions , 1, 0, "SEH .xdata exception handling") LANGOPT(WasmExceptions , 1, 0, "WebAssembly exception handling") +LANGOPT(IgnoreExceptions , 1, 0, "ignore exceptions") LANGOPT(ExternCNoUnwind , 1, 0, "Assume extern C functions don't unwind") LANGOPT(TraditionalCPP , 1, 0, "traditional CPP emulation") LANGOPT(RTTI , 1, 1, "run-time type information") @@ -147,6 +148,9 @@ LANGOPT(RelaxedTemplateTemplateArgs, 1, 0, "C++17 relaxed matching of template t LANGOPT(DoubleSquareBracketAttributes, 1, 0, "'[[]]' attributes extension for all language standard modes") +COMPATIBLE_LANGOPT(RecoveryAST, 1, 0, "Preserve expressions in AST when encountering errors") +COMPATIBLE_LANGOPT(RecoveryASTType, 1, 0, "Preserve the type in recovery expressions") + BENIGN_LANGOPT(ThreadsafeStatics , 1, 1, "thread-safe static initializers") LANGOPT(POSIXThreads , 1, 0, "POSIX thread support") LANGOPT(Blocks , 1, 0, "blocks extension to C") @@ -161,6 +165,7 @@ BENIGN_ENUM_LANGOPT(CompilingModule, CompilingModuleKind, 2, CMK_None, BENIGN_LANGOPT(CompilingPCH, 1, 0, "building a pch") BENIGN_LANGOPT(BuildingPCHWithObjectFile, 1, 0, "building a pch which has a corresponding object file") BENIGN_LANGOPT(CacheGeneratedPCH, 1, 0, "cache generated PCH files in memory") +BENIGN_LANGOPT(PCHInstantiateTemplates, 1, 0, "instantiate templates while building a PCH") COMPATIBLE_LANGOPT(ModulesDeclUse , 1, 0, "require declaration of module uses") BENIGN_LANGOPT(ModulesSearchAll , 1, 1, "searching even non-imported modules to find unresolved references") COMPATIBLE_LANGOPT(ModulesStrictDeclUse, 1, 0, "requiring declaration of module uses and all headers to be in modules") @@ -175,6 +180,7 @@ VALUE_LANGOPT(PackStruct , 32, 0, VALUE_LANGOPT(MaxTypeAlign , 32, 0, "default maximum alignment for types") VALUE_LANGOPT(AlignDouble , 1, 0, "Controls if doubles should be aligned to 8 bytes (x86 only)") +VALUE_LANGOPT(DoubleSize , 32, 0, "width of double") VALUE_LANGOPT(LongDoubleSize , 32, 0, "width of long double") LANGOPT(PPCIEEELongDouble , 1, 0, "use IEEE 754 quadruple-precision for long double") COMPATIBLE_VALUE_LANGOPT(PICLevel , 2, 0, "__PIC__ level") @@ -187,6 +193,12 @@ COMPATIBLE_LANGOPT(Deprecated , 1, 0, "__DEPRECATED predefined macro") COMPATIBLE_LANGOPT(FastMath , 1, 0, "fast FP math optimizations, and __FAST_MATH__ predefined macro") COMPATIBLE_LANGOPT(FiniteMathOnly , 1, 0, "__FINITE_MATH_ONLY__ predefined macro") COMPATIBLE_LANGOPT(UnsafeFPMath , 1, 0, "Unsafe Floating Point Math") +BENIGN_LANGOPT(AllowFPReassoc , 1, 0, "Permit Floating Point reassociation") +BENIGN_LANGOPT(NoHonorNaNs , 1, 0, "Permit Floating Point optimization without regard to NaN") +BENIGN_LANGOPT(NoHonorInfs , 1, 0, "Permit Floating Point optimization without regard to infinities") +BENIGN_LANGOPT(NoSignedZero , 1, 0, "Permit Floating Point optimization without regard to signed zeros") +BENIGN_LANGOPT(AllowRecip , 1, 0, "Permit Floating Point reciprocal") +BENIGN_LANGOPT(ApproxFunc , 1, 0, "Permit Floating Point approximation") BENIGN_LANGOPT(ObjCGCBitmapPrint , 1, 0, "printing of GC's bitmap layout for __weak/__strong ivars") @@ -219,6 +231,7 @@ LANGOPT(OpenMPCUDANumSMs , 32, 0, "Number of SMs for CUDA devices.") LANGOPT(OpenMPCUDABlocksPerSM , 32, 0, "Number of blocks per SM for CUDA devices.") LANGOPT(OpenMPCUDAReductionBufNum , 32, 1024, "Number of the reduction records in the intermediate reduction buffer used for the teams reductions.") LANGOPT(OpenMPOptimisticCollapse , 1, 0, "Use at most 32 bits to represent the collapsed loop nest counter.") +LANGOPT(OpenMPCUDATargetParallel, 1, 0, "Support parallel execution of target region on Cuda-based devices.") LANGOPT(RenderScript , 1, 0, "RenderScript") LANGOPT(CUDAIsDevice , 1, 0, "compiling for CUDA device") @@ -227,9 +240,11 @@ LANGOPT(CUDAHostDeviceConstexpr, 1, 1, "treating unattributed constexpr function LANGOPT(CUDADeviceApproxTranscendentals, 1, 0, "using approximate transcendental functions") LANGOPT(GPURelocatableDeviceCode, 1, 0, "generate relocatable device code") LANGOPT(GPUAllowDeviceInit, 1, 0, "allowing device side global init functions for HIP") -LANGOPT(GPUMaxThreadsPerBlock, 32, 256, "default max threads per block for kernel launch bounds for HIP") +LANGOPT(GPUMaxThreadsPerBlock, 32, 1024, "default max threads per block for kernel launch bounds for HIP") +LANGOPT(SYCL , 1, 0, "SYCL") LANGOPT(SYCLIsDevice , 1, 0, "Generate code for SYCL device") +LANGOPT(SYCLVersion , 32, 0, "Version of the SYCL standard used") LANGOPT(HIPUseNewLaunchAPI, 1, 0, "Use new kernel launching API for HIP") @@ -237,7 +252,7 @@ LANGOPT(SizedDeallocation , 1, 0, "sized deallocation") LANGOPT(AlignedAllocation , 1, 0, "aligned allocation") LANGOPT(AlignedAllocationUnavailable, 1, 0, "aligned allocation functions are unavailable") LANGOPT(NewAlignOverride , 32, 0, "maximum alignment guaranteed by '::operator new(size_t)'") -LANGOPT(ConceptsTS , 1, 0, "enable C++ Extensions for Concepts") +LANGOPT(ConceptSatisfactionCaching , 1, 1, "enable satisfaction caching for C++20 Concepts") BENIGN_LANGOPT(ModulesCodegen , 1, 0, "Modules code generation") BENIGN_LANGOPT(ModulesDebugInfo , 1, 0, "Modules debug info") BENIGN_LANGOPT(ElideConstructors , 1, 1, "C++ copy constructor elision") @@ -256,15 +271,19 @@ BENIGN_LANGOPT(SpellChecking , 1, 1, "spell-checking") LANGOPT(SinglePrecisionConstants , 1, 0, "treating double-precision floating point constants as single precision constants") LANGOPT(FastRelaxedMath , 1, 0, "OpenCL fast relaxed math") /// FP_CONTRACT mode (on/off/fast). -ENUM_LANGOPT(DefaultFPContractMode, FPContractModeKind, 2, FPC_Off, "FP contraction type") -ENUM_LANGOPT(FPRoundingMode, FPRoundingModeKind, 3, FPR_ToNearest, "FP Rounding Mode type") -ENUM_LANGOPT(FPExceptionMode, FPExceptionModeKind, 2, FPE_Ignore, "FP Exception Behavior Mode type") +BENIGN_ENUM_LANGOPT(DefaultFPContractMode, FPModeKind, 2, FPM_Off, "FP contraction type") +COMPATIBLE_LANGOPT(ExpStrictFP, 1, false, "Enable experimental strict floating point") +BENIGN_ENUM_LANGOPT(FPRoundingMode, RoundingMode, 3, RoundingMode::NearestTiesToEven, "FP Rounding Mode type") +BENIGN_ENUM_LANGOPT(FPExceptionMode, FPExceptionModeKind, 2, FPE_Ignore, "FP Exception Behavior Mode type") 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(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") +BENIGN_LANGOPT(CompatibilityQualifiedIdBlockParamTypeChecking, 1, 0, + "compatibility mode for type checking block parameters " + "involving qualified id types") LANGOPT(CFProtectionBranch , 1, 0, "Control-Flow Branch Protection enabled") LANGOPT(FakeAddressSpaceMap , 1, 0, "OpenCL fake address space map") ENUM_LANGOPT(AddressSpaceMapMangling , AddrSpaceMapMangling, 2, ASMM_Target, "OpenCL address space map mangling mode") @@ -284,10 +303,14 @@ ENUM_LANGOPT(TypeVisibilityMode, Visibility, 3, DefaultVisibility, "default visibility for types [-ftype-visibility]") LANGOPT(SetVisibilityForExternDecls, 1, 0, "apply global symbol visibility to external declarations without an explicit visibility") +BENIGN_LANGOPT(SemanticInterposition , 1, 0, "semantic interposition") +BENIGN_LANGOPT(ExplicitNoSemanticInterposition, 1, 0, "explicitly no semantic interposition") ENUM_LANGOPT(StackProtector, StackProtectorMode, 2, SSPOff, "stack protector mode") ENUM_LANGOPT(TrivialAutoVarInit, TrivialAutoVarInitKind, 2, TrivialAutoVarInitKind::Uninitialized, "trivial automatic variable initialization") +VALUE_LANGOPT(TrivialAutoVarInitStopAfter, 32, 0, + "stop trivial automatic variable initialization after the specified number of instances. Must be greater than 0.") ENUM_LANGOPT(SignedOverflowBehavior, SignedOverflowBehaviorTy, 2, SOB_Undefined, "signed integer overflow handling") @@ -344,6 +367,21 @@ LANGOPT(PaddingOnUnsignedFixedPoint, 1, 0, LANGOPT(RegisterStaticDestructors, 1, 1, "Register C++ static destructors") +LANGOPT(MatrixTypes, 1, 0, "Enable or disable the builtin matrix type") + +COMPATIBLE_VALUE_LANGOPT(MaxTokens, 32, 0, "Max number of tokens per TU or 0") + +ENUM_LANGOPT(SignReturnAddressScope, SignReturnAddressScopeKind, 2, SignReturnAddressScopeKind::None, + "Scope of return address signing") +ENUM_LANGOPT(SignReturnAddressKey, SignReturnAddressKeyKind, 1, SignReturnAddressKeyKind::AKey, + "Key used for return address signing") +LANGOPT(BranchTargetEnforcement, 1, 0, "Branch-target enforcement enabled") + +LANGOPT(SpeculativeLoadHardening, 1, 0, "Speculative load hardening enabled") + +LANGOPT(RelativeCXXABIVTables, 1, 0, + "Use an ABI-incompatible v-table layout that uses relative references") + #undef LANGOPT #undef COMPATIBLE_LANGOPT #undef BENIGN_LANGOPT diff --git a/clang/include/clang/Basic/LangOptions.h b/clang/include/clang/Basic/LangOptions.h index ae4a4b2b9e87..a9213b7d8668 100644 --- a/clang/include/clang/Basic/LangOptions.h +++ b/clang/include/clang/Basic/LangOptions.h @@ -19,6 +19,7 @@ #include "clang/Basic/ObjCRuntime.h" #include "clang/Basic/Sanitizers.h" #include "clang/Basic/Visibility.h" +#include "llvm/ADT/FloatingPointMode.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/Triple.h" #include <string> @@ -53,6 +54,7 @@ enum class MSVtorDispMode { Never, ForVBaseOverride, ForVFTable }; class LangOptions : public LangOptionsBase { public: using Visibility = clang::Visibility; + using RoundingMode = llvm::RoundingMode; enum GCMode { NonGC, GCOnly, HybridGC }; enum StackProtectorMode { SSPOff, SSPOn, SSPStrong, SSPReq }; @@ -172,41 +174,20 @@ public: Swift4_1, }; - enum FPContractModeKind { - // Form fused FP ops only where result will not be affected. - FPC_Off, + enum FPModeKind { + // Disable the floating point pragma + FPM_Off, - // Form fused FP ops according to FP_CONTRACT rules. - FPC_On, + // Enable the floating point pragma + FPM_On, // Aggressively fuse FP ops (E.g. FMA). - FPC_Fast + FPM_Fast }; - // TODO: merge FEnvAccessModeKind and FPContractModeKind - enum FEnvAccessModeKind { - FEA_Off, - - FEA_On - }; - - // Values of the following enumerations correspond to metadata arguments - // specified for constrained floating-point intrinsics: - // http://llvm.org/docs/LangRef.html#constrained-floating-point-intrinsics. - - /// Possible rounding modes. - enum FPRoundingModeKind { - /// Rounding to nearest, corresponds to "round.tonearest". - FPR_ToNearest, - /// Rounding toward -Inf, corresponds to "round.downward". - FPR_Downward, - /// Rounding toward +Inf, corresponds to "round.upward". - FPR_Upward, - /// Rounding toward zero, corresponds to "round.towardzero". - FPR_TowardZero, - /// Is determined by runtime environment, corresponds to "round.dynamic". - FPR_Dynamic - }; + /// Alias for RoundingMode::NearestTiesToEven. + static constexpr unsigned FPR_ToNearest = + static_cast<unsigned>(llvm::RoundingMode::NearestTiesToEven); /// Possible floating point exception behavior. enum FPExceptionModeKind { @@ -229,6 +210,22 @@ public: All, }; + enum class SignReturnAddressScopeKind { + /// No signing for any function. + None, + /// Sign the return address of functions that spill LR. + NonLeaf, + /// Sign the return address of all functions, + All + }; + + enum class SignReturnAddressKeyKind { + /// Return address signing uses APIA key. + AKey, + /// Return address signing uses APIB key. + BKey + }; + public: /// Set of enabled sanitizers. SanitizerSet Sanitize; @@ -351,61 +348,193 @@ public: /// Return the OpenCL C or C++ version as a VersionTuple. VersionTuple getOpenCLVersionTuple() const; + + /// Check if return address signing is enabled. + bool hasSignReturnAddress() const { + return getSignReturnAddressScope() != SignReturnAddressScopeKind::None; + } + + /// Check if return address signing uses AKey. + bool isSignReturnAddressWithAKey() const { + return getSignReturnAddressKey() == SignReturnAddressKeyKind::AKey; + } + + /// Check if leaf functions are also signed. + bool isSignReturnAddressScopeAll() const { + return getSignReturnAddressScope() == SignReturnAddressScopeKind::All; + } }; /// Floating point control options +class FPOptionsOverride; class FPOptions { public: - FPOptions() : fp_contract(LangOptions::FPC_Off), - fenv_access(LangOptions::FEA_Off) {} + // We start by defining the layout. + using storage_type = uint16_t; + + using RoundingMode = llvm::RoundingMode; + + // Define a fake option named "First" so that we have a PREVIOUS even for the + // real first option. + static constexpr storage_type FirstShift = 0, FirstWidth = 0; +#define OPTION(NAME, TYPE, WIDTH, PREVIOUS) \ + static constexpr storage_type NAME##Shift = \ + PREVIOUS##Shift + PREVIOUS##Width; \ + static constexpr storage_type NAME##Width = WIDTH; \ + static constexpr storage_type NAME##Mask = ((1 << NAME##Width) - 1) \ + << NAME##Shift; +#include "clang/Basic/FPOptions.def" - // Used for serializing. - explicit FPOptions(unsigned I) - : fp_contract(static_cast<LangOptions::FPContractModeKind>(I & 3)), - fenv_access(static_cast<LangOptions::FEnvAccessModeKind>((I >> 2) & 1)) - {} +private: + storage_type Value; - explicit FPOptions(const LangOptions &LangOpts) - : fp_contract(LangOpts.getDefaultFPContractMode()), - fenv_access(LangOptions::FEA_Off) {} - // FIXME: Use getDefaultFEnvAccessMode() when available. +public: + FPOptions() : Value(0) { + setFPContractMode(LangOptions::FPM_Off); + setRoundingMode(static_cast<RoundingMode>(LangOptions::FPR_ToNearest)); + setFPExceptionMode(LangOptions::FPE_Ignore); + } + // Used for serializing. + explicit FPOptions(unsigned I) { getFromOpaqueInt(I); } + + explicit FPOptions(const LangOptions &LO) { + Value = 0; + setFPContractMode(LO.getDefaultFPContractMode()); + setRoundingMode(LO.getFPRoundingMode()); + setFPExceptionMode(LO.getFPExceptionMode()); + setAllowFEnvAccess(LangOptions::FPM_Off), + setAllowFPReassociate(LO.AllowFPReassoc); + setNoHonorNaNs(LO.NoHonorNaNs); + setNoHonorInfs(LO.NoHonorInfs); + setNoSignedZero(LO.NoSignedZero); + setAllowReciprocal(LO.AllowRecip); + setAllowApproxFunc(LO.ApproxFunc); + } bool allowFPContractWithinStatement() const { - return fp_contract == LangOptions::FPC_On; + return getFPContractMode() == LangOptions::FPM_On; + } + void setAllowFPContractWithinStatement() { + setFPContractMode(LangOptions::FPM_On); } bool allowFPContractAcrossStatement() const { - return fp_contract == LangOptions::FPC_Fast; + return getFPContractMode() == LangOptions::FPM_Fast; } + void setAllowFPContractAcrossStatement() { + setFPContractMode(LangOptions::FPM_Fast); + } + + bool isFPConstrained() const { + return getRoundingMode() != + static_cast<unsigned>(RoundingMode::NearestTiesToEven) || + getFPExceptionMode() != LangOptions::FPE_Ignore || + getAllowFEnvAccess(); + } + + bool operator==(FPOptions other) const { return Value == other.Value; } + + /// Return the default value of FPOptions that's used when trailing + /// storage isn't required. + static FPOptions defaultWithoutTrailingStorage(const LangOptions &LO); + + storage_type getAsOpaqueInt() const { return Value; } + void getFromOpaqueInt(storage_type value) { Value = value; } + + // We can define most of the accessors automatically: +#define OPTION(NAME, TYPE, WIDTH, PREVIOUS) \ + unsigned get##NAME() const { \ + return static_cast<unsigned>(TYPE((Value & NAME##Mask) >> NAME##Shift)); \ + } \ + void set##NAME(TYPE value) { \ + Value = (Value & ~NAME##Mask) | (storage_type(value) << NAME##Shift); \ + } +#include "clang/Basic/FPOptions.def" + LLVM_DUMP_METHOD void dump(); +}; + +/// The FPOptions override type is value of the new FPOptions +/// plus a mask showing which fields are actually set in it: +class FPOptionsOverride { + FPOptions Options; + FPOptions::storage_type OverrideMask = 0; + +public: + using RoundingMode = llvm::RoundingMode; + FPOptionsOverride() {} + + // Used for serializing. + explicit FPOptionsOverride(unsigned I) { getFromOpaqueInt(I); } + + bool requiresTrailingStorage() const { return OverrideMask != 0; } void setAllowFPContractWithinStatement() { - fp_contract = LangOptions::FPC_On; + setFPContractModeOverride(LangOptions::FPM_On); } void setAllowFPContractAcrossStatement() { - fp_contract = LangOptions::FPC_Fast; + setFPContractModeOverride(LangOptions::FPM_Fast); } - void setDisallowFPContract() { fp_contract = LangOptions::FPC_Off; } - - bool allowFEnvAccess() const { - return fenv_access == LangOptions::FEA_On; + void setDisallowFPContract() { + setFPContractModeOverride(LangOptions::FPM_Off); } - void setAllowFEnvAccess() { - fenv_access = LangOptions::FEA_On; + void setFPPreciseEnabled(bool Value) { + setAllowFPReassociateOverride(!Value); + setNoHonorNaNsOverride(!Value); + setNoHonorInfsOverride(!Value); + setNoSignedZeroOverride(!Value); + setAllowReciprocalOverride(!Value); + setAllowApproxFuncOverride(!Value); + if (Value) + /* Precise mode implies fp_contract=on and disables ffast-math */ + setAllowFPContractWithinStatement(); + else + /* Precise mode disabled sets fp_contract=fast and enables ffast-math */ + setAllowFPContractAcrossStatement(); } - void setDisallowFEnvAccess() { fenv_access = LangOptions::FEA_Off; } + unsigned getAsOpaqueInt() const { + return Options.getAsOpaqueInt() << 16 | OverrideMask; + } + void getFromOpaqueInt(unsigned I) { + OverrideMask = I & 0xffff; + Options.getFromOpaqueInt(I >> 16); + } - /// Used to serialize this. - unsigned getInt() const { return fp_contract | (fenv_access << 2); } + FPOptions applyOverrides(const LangOptions &LO) { + FPOptions Base(LO); + FPOptions result((Base.getAsOpaqueInt() & ~OverrideMask) | + (Options.getAsOpaqueInt() & OverrideMask)); + return result; + } -private: - /// Adjust BinaryOperator::FPFeatures to match the total bit-field size - /// of these two. - unsigned fp_contract : 2; - unsigned fenv_access : 1; + bool operator==(FPOptionsOverride other) const { + return Options == other.Options && OverrideMask == other.OverrideMask; + } + bool operator!=(FPOptionsOverride other) const { return !(*this == other); } + +#define OPTION(NAME, TYPE, WIDTH, PREVIOUS) \ + bool has##NAME##Override() const { \ + return OverrideMask & FPOptions::NAME##Mask; \ + } \ + unsigned get##NAME##Override() const { \ + assert(has##NAME##Override()); \ + return Options.get##NAME(); \ + } \ + void clear##NAME##Override() { \ + /* Clear the actual value so that we don't have spurious differences when \ + * testing equality. */ \ + Options.set##NAME(TYPE(0)); \ + OverrideMask &= ~FPOptions::NAME##Mask; \ + } \ + void set##NAME##Override(TYPE value) { \ + Options.set##NAME(value); \ + OverrideMask |= FPOptions::NAME##Mask; \ + } +#include "clang/Basic/FPOptions.def" + LLVM_DUMP_METHOD void dump(); }; /// Describes the kind of translation unit being processed. diff --git a/clang/include/clang/Basic/LangStandard.h b/clang/include/clang/Basic/LangStandard.h index e7deb7d64638..ad7f7510b234 100644 --- a/clang/include/clang/Basic/LangStandard.h +++ b/clang/include/clang/Basic/LangStandard.h @@ -48,7 +48,7 @@ enum LangFeatures { CPlusPlus11 = (1 << 6), CPlusPlus14 = (1 << 7), CPlusPlus17 = (1 << 8), - CPlusPlus2a = (1 << 9), + CPlusPlus20 = (1 << 9), Digraphs = (1 << 10), GNUMode = (1 << 11), HexFloat = (1 << 12), @@ -108,8 +108,8 @@ public: /// isCPlusPlus17 - Language is a C++17 variant (or later). bool isCPlusPlus17() const { return Flags & CPlusPlus17; } - /// isCPlusPlus2a - Language is a post-C++17 variant (or later). - bool isCPlusPlus2a() const { return Flags & CPlusPlus2a; } + /// isCPlusPlus20 - Language is a C++20 variant (or later). + bool isCPlusPlus20() const { return Flags & CPlusPlus20; } /// hasDigraphs - Language supports digraphs. bool hasDigraphs() const { return Flags & Digraphs; } diff --git a/clang/include/clang/Basic/LangStandards.def b/clang/include/clang/Basic/LangStandards.def index 427691fb71e9..b09568e8b3e8 100644 --- a/clang/include/clang/Basic/LangStandards.def +++ b/clang/include/clang/Basic/LangStandards.def @@ -140,15 +140,17 @@ LANGSTANDARD(gnucxx17, "gnu++17", Digraphs | HexFloat | GNUMode) LANGSTANDARD_ALIAS_DEPR(gnucxx17, "gnu++1z") -LANGSTANDARD(cxx2a, "c++2a", - CXX, "Working draft for ISO C++ 2020", +LANGSTANDARD(cxx20, "c++20", + CXX, "ISO C++ 2020 DIS", LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus14 | CPlusPlus17 | - CPlusPlus2a | Digraphs | HexFloat) + CPlusPlus20 | Digraphs | HexFloat) +LANGSTANDARD_ALIAS_DEPR(cxx20, "c++2a") -LANGSTANDARD(gnucxx2a, "gnu++2a", - CXX, "Working draft for ISO C++ 2020 with GNU extensions", +LANGSTANDARD(gnucxx20, "gnu++20", + CXX, "ISO C++ 2020 DIS with GNU extensions", LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus14 | CPlusPlus17 | - CPlusPlus2a | Digraphs | HexFloat | GNUMode) + CPlusPlus20 | Digraphs | HexFloat | GNUMode) +LANGSTANDARD_ALIAS_DEPR(gnucxx20, "gnu++2a") // OpenCL LANGSTANDARD(opencl10, "cl1.0", diff --git a/clang/include/clang/Basic/Module.h b/clang/include/clang/Basic/Module.h index 0f2549f09943..6b932a9a84d0 100644 --- a/clang/include/clang/Basic/Module.h +++ b/clang/include/clang/Basic/Module.h @@ -15,16 +15,14 @@ #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" #include "llvm/ADT/Optional.h" #include "llvm/ADT/PointerIntPair.h" -#include "llvm/ADT/PointerUnion.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SetVector.h" #include "llvm/ADT/SmallVector.h" -#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/iterator_range.h" @@ -32,6 +30,7 @@ #include <cassert> #include <cstdint> #include <ctime> +#include <iterator> #include <string> #include <utility> #include <vector> @@ -44,6 +43,9 @@ class raw_ostream; namespace clang { +class DirectoryEntry; +class FileEntry; +class FileManager; class LangOptions; class TargetInfo; @@ -51,12 +53,33 @@ class TargetInfo; using ModuleId = SmallVector<std::pair<std::string, SourceLocation>, 2>; /// The signature of a module, which is a hash of the AST content. -struct ASTFileSignature : std::array<uint32_t, 5> { - ASTFileSignature(std::array<uint32_t, 5> S = {{0}}) - : std::array<uint32_t, 5>(std::move(S)) {} +struct ASTFileSignature : std::array<uint8_t, 20> { + using BaseT = std::array<uint8_t, 20>; + + static constexpr size_t size = std::tuple_size<BaseT>::value; + + ASTFileSignature(BaseT S = {{0}}) : BaseT(std::move(S)) {} - explicit operator bool() const { - return *this != std::array<uint32_t, 5>({{0}}); + explicit operator bool() const { return *this != BaseT({{0}}); } + + static ASTFileSignature create(StringRef Bytes) { + return create(Bytes.bytes_begin(), Bytes.bytes_end()); + } + + static ASTFileSignature createDISentinel() { + ASTFileSignature Sentinel; + Sentinel.fill(0xFF); + return Sentinel; + } + + template <typename InputIt> + static ASTFileSignature create(InputIt First, InputIt Last) { + assert(std::distance(First, Last) == size && + "Wrong amount of bytes to create an ASTFileSignature"); + + ASTFileSignature Signature; + std::copy(First, Last, Signature.begin()); + return Signature; } }; @@ -101,7 +124,7 @@ public: std::string PresumedModuleMapFile; /// The umbrella header or directory. - llvm::PointerUnion<const DirectoryEntry *, const FileEntry *> Umbrella; + const void *Umbrella = nullptr; /// The module signature. ASTFileSignature Signature; @@ -206,8 +229,10 @@ public: /// A module with the same name that shadows this module. Module *ShadowingModule = nullptr; - /// Whether this module is missing a feature from \c Requirements. - unsigned IsMissingRequirement : 1; + /// Whether this module has declared itself unimportable, either because + /// it's missing a requirement from \p Requirements or because it's been + /// shadowed by another module. + unsigned IsUnimportable : 1; /// Whether we tried and failed to load a module file for this module. unsigned HasIncompatibleModuleFile : 1; @@ -268,6 +293,9 @@ public: /// to a regular (public) module map. unsigned ModuleMapIsPrivate : 1; + /// Whether Umbrella is a directory or header. + unsigned HasUmbrellaDir : 1; + /// Describes the visibility of the various names within a /// particular module. enum NameVisibilityKind { @@ -380,6 +408,25 @@ public: ~Module(); + /// Determine whether this module has been declared unimportable. + bool isUnimportable() const { return IsUnimportable; } + + /// Determine whether this module has been declared unimportable. + /// + /// \param LangOpts The language options used for the current + /// translation unit. + /// + /// \param Target The target options used for the current translation unit. + /// + /// \param Req If this module is unimportable because of a missing + /// requirement, this parameter will be set to one of the requirements that + /// is not met for use of this module. + /// + /// \param ShadowingModule If this module is unimportable because it is + /// shadowed, this parameter will be set to the shadowing module. + bool isUnimportable(const LangOptions &LangOpts, const TargetInfo &Target, + Requirement &Req, Module *&ShadowingModule) const; + /// Determine whether this module is available for use within the /// current translation unit. bool isAvailable() const { return IsAvailable; } @@ -487,26 +534,22 @@ public: /// Retrieve the header that serves as the umbrella header for this /// module. Header getUmbrellaHeader() const { - if (auto *E = Umbrella.dyn_cast<const FileEntry *>()) - return Header{UmbrellaAsWritten, E}; + if (!HasUmbrellaDir) + return Header{UmbrellaAsWritten, + static_cast<const FileEntry *>(Umbrella)}; return Header{}; } /// Determine whether this module has an umbrella directory that is /// not based on an umbrella header. - bool hasUmbrellaDir() const { - return Umbrella && Umbrella.is<const DirectoryEntry *>(); - } + bool hasUmbrellaDir() const { return Umbrella && HasUmbrellaDir; } /// Add a top-level header associated with this module. - void addTopHeader(const FileEntry *File) { - assert(File); - TopHeaders.insert(File); - } + void addTopHeader(const FileEntry *File); /// Add a top-level header filename associated with this module. void addTopHeaderFilename(StringRef Filename) { - TopHeaderNames.push_back(Filename); + TopHeaderNames.push_back(std::string(Filename)); } /// The top-level headers associated with this module. @@ -535,7 +578,7 @@ public: const TargetInfo &Target); /// Mark this module and all of its submodules as unavailable. - void markUnavailable(bool MissingRequirement = false); + void markUnavailable(bool Unimportable); /// Find the submodule with the given name. /// @@ -654,6 +697,32 @@ private: unsigned Generation = 0; }; +/// 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; + ASTFileSignature Signature; + Module *ClangModule = nullptr; + +public: + ASTSourceDescriptor() = default; + ASTSourceDescriptor(StringRef Name, StringRef Path, StringRef ASTFile, + ASTFileSignature Signature) + : PCHModuleName(std::move(Name)), Path(std::move(Path)), + ASTFile(std::move(ASTFile)), Signature(Signature) {} + ASTSourceDescriptor(Module &M); + + std::string getModuleName() const; + StringRef getPath() const { return Path; } + StringRef getASTFile() const { return ASTFile; } + ASTFileSignature getSignature() const { return Signature; } + Module *getModuleOrNull() const { return ClangModule; } +}; + + } // namespace clang #endif // LLVM_CLANG_BASIC_MODULE_H diff --git a/clang/include/clang/Basic/ObjCRuntime.h b/clang/include/clang/Basic/ObjCRuntime.h index 1c4a69269dee..26403bfa98c9 100644 --- a/clang/include/clang/Basic/ObjCRuntime.h +++ b/clang/include/clang/Basic/ObjCRuntime.h @@ -476,6 +476,10 @@ public: friend bool operator!=(const ObjCRuntime &left, const ObjCRuntime &right) { return !(left == right); } + + friend llvm::hash_code hash_value(const ObjCRuntime &OCR) { + return llvm::hash_combine(OCR.getKind(), OCR.getVersion()); + } }; raw_ostream &operator<<(raw_ostream &out, const ObjCRuntime &value); diff --git a/clang/include/clang/Basic/OpenCLExtensions.def b/clang/include/clang/Basic/OpenCLExtensions.def index 5536a6e8e4df..1ae36b32fb0a 100644 --- a/clang/include/clang/Basic/OpenCLExtensions.def +++ b/clang/include/clang/Basic/OpenCLExtensions.def @@ -70,9 +70,17 @@ OPENCLEXT_INTERNAL(cl_khr_spir, 120, ~0U) OPENCLEXT_INTERNAL(cl_khr_egl_event, 200, ~0U) OPENCLEXT_INTERNAL(cl_khr_egl_image, 200, ~0U) OPENCLEXT_INTERNAL(cl_khr_mipmap_image, 200, ~0U) +OPENCLEXT_INTERNAL(cl_khr_mipmap_image_writes, 200, ~0U) OPENCLEXT_INTERNAL(cl_khr_srgb_image_writes, 200, ~0U) OPENCLEXT_INTERNAL(cl_khr_subgroups, 200, ~0U) OPENCLEXT_INTERNAL(cl_khr_terminate_context, 200, ~0U) +OPENCLEXT_INTERNAL(cl_khr_subgroup_extended_types, 200, ~0U) +OPENCLEXT_INTERNAL(cl_khr_subgroup_non_uniform_vote, 200, ~0U) +OPENCLEXT_INTERNAL(cl_khr_subgroup_ballot, 200, ~0U) +OPENCLEXT_INTERNAL(cl_khr_subgroup_non_uniform_arithmetic, 200, ~0U) +OPENCLEXT_INTERNAL(cl_khr_subgroup_shuffle, 200, ~0U) +OPENCLEXT_INTERNAL(cl_khr_subgroup_shuffle_relative, 200, ~0U) +OPENCLEXT_INTERNAL(cl_khr_subgroup_clustered_reduce, 200, ~0U) // Clang Extensions. OPENCLEXT_INTERNAL(cl_clang_storage_class_specifiers, 100, ~0U) diff --git a/clang/include/clang/Basic/OpenMPKinds.def b/clang/include/clang/Basic/OpenMPKinds.def index 38e8c3204475..9f2bf1abc287 100644 --- a/clang/include/clang/Basic/OpenMPKinds.def +++ b/clang/include/clang/Basic/OpenMPKinds.def @@ -11,105 +11,6 @@ /// //===----------------------------------------------------------------------===// -#ifndef OPENMP_CLAUSE -# define OPENMP_CLAUSE(Name, Class) -#endif -#ifndef OPENMP_PARALLEL_CLAUSE -# define OPENMP_PARALLEL_CLAUSE(Name) -#endif -#ifndef OPENMP_SIMD_CLAUSE -# define OPENMP_SIMD_CLAUSE(Name) -#endif -#ifndef OPENMP_FOR_CLAUSE -# define OPENMP_FOR_CLAUSE(Name) -#endif -#ifndef OPENMP_FOR_SIMD_CLAUSE -# define OPENMP_FOR_SIMD_CLAUSE(Name) -#endif -#ifndef OPENMP_SECTIONS_CLAUSE -# define OPENMP_SECTIONS_CLAUSE(Name) -#endif -#ifndef OPENMP_SINGLE_CLAUSE -# define OPENMP_SINGLE_CLAUSE(Name) -#endif -#ifndef OPENMP_PARALLEL_FOR_CLAUSE -# define OPENMP_PARALLEL_FOR_CLAUSE(Name) -#endif -#ifndef OPENMP_PARALLEL_FOR_SIMD_CLAUSE -# define OPENMP_PARALLEL_FOR_SIMD_CLAUSE(Name) -#endif -#ifndef OPENMP_PARALLEL_MASTER_CLAUSE -# define OPENMP_PARALLEL_MASTER_CLAUSE(Name) -#endif -#ifndef OPENMP_PARALLEL_SECTIONS_CLAUSE -# define OPENMP_PARALLEL_SECTIONS_CLAUSE(Name) -#endif -#ifndef OPENMP_TASK_CLAUSE -# define OPENMP_TASK_CLAUSE(Name) -#endif -#ifndef OPENMP_ATOMIC_CLAUSE -# define OPENMP_ATOMIC_CLAUSE(Name) -#endif -#ifndef OPENMP_TARGET_CLAUSE -# define OPENMP_TARGET_CLAUSE(Name) -#endif -#ifndef OPENMP_REQUIRES_CLAUSE -# define OPENMP_REQUIRES_CLAUSE(Name) -#endif -#ifndef OPENMP_TARGET_DATA_CLAUSE -# define OPENMP_TARGET_DATA_CLAUSE(Name) -#endif -#ifndef OPENMP_TARGET_ENTER_DATA_CLAUSE -#define OPENMP_TARGET_ENTER_DATA_CLAUSE(Name) -#endif -#ifndef OPENMP_TARGET_EXIT_DATA_CLAUSE -#define OPENMP_TARGET_EXIT_DATA_CLAUSE(Name) -#endif -#ifndef OPENMP_TARGET_PARALLEL_CLAUSE -# define OPENMP_TARGET_PARALLEL_CLAUSE(Name) -#endif -#ifndef OPENMP_TARGET_PARALLEL_FOR_CLAUSE -# define OPENMP_TARGET_PARALLEL_FOR_CLAUSE(Name) -#endif -#ifndef OPENMP_TARGET_UPDATE_CLAUSE -# define OPENMP_TARGET_UPDATE_CLAUSE(Name) -#endif -#ifndef OPENMP_TEAMS_CLAUSE -# define OPENMP_TEAMS_CLAUSE(Name) -#endif -#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_MASTER_TASKLOOP_CLAUSE -# define OPENMP_MASTER_TASKLOOP_CLAUSE(Name) -#endif -#ifndef OPENMP_MASTER_TASKLOOP_SIMD_CLAUSE -# define OPENMP_MASTER_TASKLOOP_SIMD_CLAUSE(Name) -#endif -#ifndef OPENMP_PARALLEL_MASTER_TASKLOOP_CLAUSE -# define OPENMP_PARALLEL_MASTER_TASKLOOP_CLAUSE(Name) -#endif -#ifndef OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE -# define OPENMP_PARALLEL_MASTER_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 #ifndef OPENMP_SCHEDULE_KIND #define OPENMP_SCHEDULE_KIND(Name) #endif @@ -146,215 +47,22 @@ #ifndef OPENMP_DEFAULTMAP_MODIFIER #define OPENMP_DEFAULTMAP_MODIFIER(Name) #endif -#ifndef OPENMP_DISTRIBUTE_PARALLEL_FOR_CLAUSE -#define OPENMP_DISTRIBUTE_PARALLEL_FOR_CLAUSE(Name) -#endif -#ifndef OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE -#define OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(Name) -#endif -#ifndef OPENMP_DISTRIBUTE_SIMD_CLAUSE -#define OPENMP_DISTRIBUTE_SIMD_CLAUSE(Name) -#endif -#ifndef OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE -#define OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(Name) -#endif -#ifndef OPENMP_TARGET_SIMD_CLAUSE -#define OPENMP_TARGET_SIMD_CLAUSE(Name) -#endif -#ifndef OPENMP_TEAMS_DISTRIBUTE_CLAUSE -#define OPENMP_TEAMS_DISTRIBUTE_CLAUSE(Name) -#endif -#ifndef OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE -#define OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(Name) -#endif -#ifndef OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE -#define OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(Name) -#endif -#ifndef OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE -#define OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(Name) -#endif -#ifndef OPENMP_TARGET_TEAMS_CLAUSE -#define OPENMP_TARGET_TEAMS_CLAUSE(Name) -#endif -#ifndef OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE -#define OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(Name) -#endif -#ifndef OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE -#define OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(Name) -#endif -#ifndef OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE -#define OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(Name) -#endif -#ifndef OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE -#define OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(Name) -#endif -#ifndef OPENMP_TASKGROUP_CLAUSE -#define OPENMP_TASKGROUP_CLAUSE(Name) -#endif -#ifndef OPENMP_DECLARE_MAPPER_CLAUSE -#define OPENMP_DECLARE_MAPPER_CLAUSE(Name) -#endif -#ifndef OPENMP_ALLOCATE_CLAUSE -# define OPENMP_ALLOCATE_CLAUSE(Name) -#endif #ifndef OPENMP_DEVICE_TYPE_KIND #define OPENMP_DEVICE_TYPE_KIND(Name) #endif -#ifndef OPENMP_DECLARE_VARIANT_CLAUSE -#define OPENMP_DECLARE_VARIANT_CLAUSE(Name) +#ifndef OPENMP_LASTPRIVATE_KIND +#define OPENMP_LASTPRIVATE_KIND(Name) #endif -#ifndef OPENMP_CONTEXT_SELECTOR_SET -#define OPENMP_CONTEXT_SELECTOR_SET(Name) +#ifndef OPENMP_ORDER_KIND +#define OPENMP_ORDER_KIND(Name) #endif -#ifndef OPENMP_CONTEXT_SELECTOR -#define OPENMP_CONTEXT_SELECTOR(Name) +#ifndef OPENMP_DEVICE_MODIFIER +#define OPENMP_DEVICE_MODIFIER(Name) #endif -#ifndef OPENMP_LASTPRIVATE_KIND -#define OPENMP_LASTPRIVATE_KIND(Name) +#ifndef OPENMP_REDUCTION_MODIFIER +#define OPENMP_REDUCTION_MODIFIER(Name) #endif -// OpenMP context selector sets. -OPENMP_CONTEXT_SELECTOR_SET(implementation) -OPENMP_CONTEXT_SELECTOR_SET(device) - -// OpenMP context selectors. -OPENMP_CONTEXT_SELECTOR(vendor) -OPENMP_CONTEXT_SELECTOR(kind) - -// OpenMP clauses. -OPENMP_CLAUSE(allocator, OMPAllocatorClause) -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) -OPENMP_CLAUSE(firstprivate, OMPFirstprivateClause) -OPENMP_CLAUSE(lastprivate, OMPLastprivateClause) -OPENMP_CLAUSE(shared, OMPSharedClause) -OPENMP_CLAUSE(reduction, OMPReductionClause) -OPENMP_CLAUSE(linear, OMPLinearClause) -OPENMP_CLAUSE(aligned, OMPAlignedClause) -OPENMP_CLAUSE(copyin, OMPCopyinClause) -OPENMP_CLAUSE(copyprivate, OMPCopyprivateClause) -OPENMP_CLAUSE(proc_bind, OMPProcBindClause) -OPENMP_CLAUSE(schedule, OMPScheduleClause) -OPENMP_CLAUSE(ordered, OMPOrderedClause) -OPENMP_CLAUSE(nowait, OMPNowaitClause) -OPENMP_CLAUSE(untied, OMPUntiedClause) -OPENMP_CLAUSE(mergeable, OMPMergeableClause) -OPENMP_CLAUSE(flush, OMPFlushClause) -OPENMP_CLAUSE(read, OMPReadClause) -OPENMP_CLAUSE(write, OMPWriteClause) -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) -OPENMP_CLAUSE(dist_schedule, OMPDistScheduleClause) -OPENMP_CLAUSE(defaultmap, OMPDefaultmapClause) -OPENMP_CLAUSE(to, OMPToClause) -OPENMP_CLAUSE(from, OMPFromClause) -OPENMP_CLAUSE(use_device_ptr, OMPUseDevicePtrClause) -OPENMP_CLAUSE(is_device_ptr, OMPIsDevicePtrClause) -OPENMP_CLAUSE(task_reduction, OMPTaskReductionClause) -OPENMP_CLAUSE(in_reduction, OMPInReductionClause) -OPENMP_CLAUSE(unified_address, OMPUnifiedAddressClause) -OPENMP_CLAUSE(unified_shared_memory, OMPUnifiedSharedMemoryClause) -OPENMP_CLAUSE(reverse_offload, OMPReverseOffloadClause) -OPENMP_CLAUSE(dynamic_allocators, OMPDynamicAllocatorsClause) -OPENMP_CLAUSE(atomic_default_mem_order, OMPAtomicDefaultMemOrderClause) -OPENMP_CLAUSE(allocate, OMPAllocateClause) -OPENMP_CLAUSE(nontemporal, OMPNontemporalClause) - -// Clauses allowed for OpenMP directive 'parallel'. -OPENMP_PARALLEL_CLAUSE(if) -OPENMP_PARALLEL_CLAUSE(num_threads) -OPENMP_PARALLEL_CLAUSE(default) -OPENMP_PARALLEL_CLAUSE(proc_bind) -OPENMP_PARALLEL_CLAUSE(private) -OPENMP_PARALLEL_CLAUSE(firstprivate) -OPENMP_PARALLEL_CLAUSE(shared) -OPENMP_PARALLEL_CLAUSE(reduction) -OPENMP_PARALLEL_CLAUSE(copyin) -OPENMP_PARALLEL_CLAUSE(allocate) - -// Clauses allowed for directive 'omp simd'. -OPENMP_SIMD_CLAUSE(private) -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) -OPENMP_SIMD_CLAUSE(allocate) -OPENMP_SIMD_CLAUSE(if) -OPENMP_SIMD_CLAUSE(nontemporal) - -// Clauses allowed for directive 'omp for'. -OPENMP_FOR_CLAUSE(private) -OPENMP_FOR_CLAUSE(lastprivate) -OPENMP_FOR_CLAUSE(firstprivate) -OPENMP_FOR_CLAUSE(reduction) -OPENMP_FOR_CLAUSE(collapse) -OPENMP_FOR_CLAUSE(schedule) -OPENMP_FOR_CLAUSE(ordered) -OPENMP_FOR_CLAUSE(nowait) -OPENMP_FOR_CLAUSE(linear) -OPENMP_FOR_CLAUSE(allocate) - -// Clauses allowed for directive 'omp for simd'. -OPENMP_FOR_SIMD_CLAUSE(private) -OPENMP_FOR_SIMD_CLAUSE(firstprivate) -OPENMP_FOR_SIMD_CLAUSE(lastprivate) -OPENMP_FOR_SIMD_CLAUSE(reduction) -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) -OPENMP_FOR_SIMD_CLAUSE(ordered) -OPENMP_FOR_SIMD_CLAUSE(allocate) -OPENMP_FOR_SIMD_CLAUSE(if) -OPENMP_FOR_SIMD_CLAUSE(nontemporal) - -// Clauses allowed for OpenMP directive 'omp sections'. -OPENMP_SECTIONS_CLAUSE(private) -OPENMP_SECTIONS_CLAUSE(lastprivate) -OPENMP_SECTIONS_CLAUSE(firstprivate) -OPENMP_SECTIONS_CLAUSE(reduction) -OPENMP_SECTIONS_CLAUSE(nowait) -OPENMP_SECTIONS_CLAUSE(allocate) - -// Clauses allowed for directive 'omp single'. -OPENMP_SINGLE_CLAUSE(private) -OPENMP_SINGLE_CLAUSE(firstprivate) -OPENMP_SINGLE_CLAUSE(copyprivate) -OPENMP_SINGLE_CLAUSE(nowait) -OPENMP_SINGLE_CLAUSE(allocate) - -// Clauses allowed for OpenMP directive 'cancel'. -OPENMP_CANCEL_CLAUSE(if) - -// Static attributes for 'default' clause. -OPENMP_DEFAULT_KIND(none) -OPENMP_DEFAULT_KIND(shared) - // Static attributes for 'schedule' clause. OPENMP_SCHEDULE_KIND(static) OPENMP_SCHEDULE_KIND(dynamic) @@ -367,6 +75,10 @@ OPENMP_SCHEDULE_MODIFIER(monotonic) OPENMP_SCHEDULE_MODIFIER(nonmonotonic) OPENMP_SCHEDULE_MODIFIER(simd) +// Modifiers for 'device' clause. +OPENMP_DEVICE_MODIFIER(ancestor) +OPENMP_DEVICE_MODIFIER(device_num) + // Static attributes for 'defaultmap' clause. OPENMP_DEFAULTMAP_KIND(scalar) OPENMP_DEFAULTMAP_KIND(aggregate) @@ -386,6 +98,7 @@ OPENMP_DEPEND_KIND(in) OPENMP_DEPEND_KIND(out) OPENMP_DEPEND_KIND(inout) OPENMP_DEPEND_KIND(mutexinoutset) +OPENMP_DEPEND_KIND(depobj) OPENMP_DEPEND_KIND(source) OPENMP_DEPEND_KIND(sink) @@ -394,200 +107,11 @@ OPENMP_LINEAR_KIND(val) OPENMP_LINEAR_KIND(ref) OPENMP_LINEAR_KIND(uval) -// Clauses allowed for OpenMP directive 'parallel for'. -OPENMP_PARALLEL_FOR_CLAUSE(if) -OPENMP_PARALLEL_FOR_CLAUSE(num_threads) -OPENMP_PARALLEL_FOR_CLAUSE(default) -OPENMP_PARALLEL_FOR_CLAUSE(proc_bind) -OPENMP_PARALLEL_FOR_CLAUSE(private) -OPENMP_PARALLEL_FOR_CLAUSE(firstprivate) -OPENMP_PARALLEL_FOR_CLAUSE(shared) -OPENMP_PARALLEL_FOR_CLAUSE(reduction) -OPENMP_PARALLEL_FOR_CLAUSE(copyin) -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) -OPENMP_PARALLEL_FOR_CLAUSE(allocate) - -// Clauses allowed for OpenMP directive 'parallel for simd'. -OPENMP_PARALLEL_FOR_SIMD_CLAUSE(if) -OPENMP_PARALLEL_FOR_SIMD_CLAUSE(num_threads) -OPENMP_PARALLEL_FOR_SIMD_CLAUSE(default) -OPENMP_PARALLEL_FOR_SIMD_CLAUSE(proc_bind) -OPENMP_PARALLEL_FOR_SIMD_CLAUSE(private) -OPENMP_PARALLEL_FOR_SIMD_CLAUSE(firstprivate) -OPENMP_PARALLEL_FOR_SIMD_CLAUSE(shared) -OPENMP_PARALLEL_FOR_SIMD_CLAUSE(reduction) -OPENMP_PARALLEL_FOR_SIMD_CLAUSE(copyin) -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) -OPENMP_PARALLEL_FOR_SIMD_CLAUSE(ordered) -OPENMP_PARALLEL_FOR_SIMD_CLAUSE(allocate) -OPENMP_PARALLEL_FOR_SIMD_CLAUSE(nontemporal) - -// Clauses allowed for OpenMP directive 'parallel master'. -OPENMP_PARALLEL_MASTER_CLAUSE(if) -OPENMP_PARALLEL_MASTER_CLAUSE(num_threads) -OPENMP_PARALLEL_MASTER_CLAUSE(default) -OPENMP_PARALLEL_MASTER_CLAUSE(private) -OPENMP_PARALLEL_MASTER_CLAUSE(firstprivate) -OPENMP_PARALLEL_MASTER_CLAUSE(shared) -OPENMP_PARALLEL_MASTER_CLAUSE(copyin) -OPENMP_PARALLEL_MASTER_CLAUSE(reduction) -OPENMP_PARALLEL_MASTER_CLAUSE(proc_bind) -OPENMP_PARALLEL_MASTER_CLAUSE(allocate) - -// Clauses allowed for OpenMP directive 'parallel sections'. -OPENMP_PARALLEL_SECTIONS_CLAUSE(if) -OPENMP_PARALLEL_SECTIONS_CLAUSE(num_threads) -OPENMP_PARALLEL_SECTIONS_CLAUSE(default) -OPENMP_PARALLEL_SECTIONS_CLAUSE(proc_bind) -OPENMP_PARALLEL_SECTIONS_CLAUSE(private) -OPENMP_PARALLEL_SECTIONS_CLAUSE(firstprivate) -OPENMP_PARALLEL_SECTIONS_CLAUSE(shared) -OPENMP_PARALLEL_SECTIONS_CLAUSE(reduction) -OPENMP_PARALLEL_SECTIONS_CLAUSE(copyin) -OPENMP_PARALLEL_SECTIONS_CLAUSE(lastprivate) -OPENMP_PARALLEL_SECTIONS_CLAUSE(allocate) - -// Clauses allowed for OpenMP directive 'task'. -OPENMP_TASK_CLAUSE(if) -OPENMP_TASK_CLAUSE(final) -OPENMP_TASK_CLAUSE(default) -OPENMP_TASK_CLAUSE(private) -OPENMP_TASK_CLAUSE(firstprivate) -OPENMP_TASK_CLAUSE(shared) -OPENMP_TASK_CLAUSE(untied) -OPENMP_TASK_CLAUSE(mergeable) -OPENMP_TASK_CLAUSE(depend) -OPENMP_TASK_CLAUSE(priority) -OPENMP_TASK_CLAUSE(in_reduction) -OPENMP_TASK_CLAUSE(allocate) - -// Clauses allowed for OpenMP directive 'atomic'. -OPENMP_ATOMIC_CLAUSE(read) -OPENMP_ATOMIC_CLAUSE(write) -OPENMP_ATOMIC_CLAUSE(update) -OPENMP_ATOMIC_CLAUSE(capture) -OPENMP_ATOMIC_CLAUSE(seq_cst) - -// Clauses allowed for OpenMP directive 'target'. -OPENMP_TARGET_CLAUSE(if) -OPENMP_TARGET_CLAUSE(device) -OPENMP_TARGET_CLAUSE(map) -OPENMP_TARGET_CLAUSE(private) -OPENMP_TARGET_CLAUSE(nowait) -OPENMP_TARGET_CLAUSE(depend) -OPENMP_TARGET_CLAUSE(defaultmap) -OPENMP_TARGET_CLAUSE(firstprivate) -OPENMP_TARGET_CLAUSE(is_device_ptr) -OPENMP_TARGET_CLAUSE(reduction) -OPENMP_TARGET_CLAUSE(allocate) - -// Clauses allowed for OpenMP directive 'requires'. -OPENMP_REQUIRES_CLAUSE(unified_address) -OPENMP_REQUIRES_CLAUSE(unified_shared_memory) -OPENMP_REQUIRES_CLAUSE(reverse_offload) -OPENMP_REQUIRES_CLAUSE(dynamic_allocators) -OPENMP_REQUIRES_CLAUSE(atomic_default_mem_order) - -// Clauses allowed for OpenMP directive 'allocate'. -OPENMP_ALLOCATE_CLAUSE(allocator) - // Modifiers for 'atomic_default_mem_order' clause. OPENMP_ATOMIC_DEFAULT_MEM_ORDER_KIND(seq_cst) OPENMP_ATOMIC_DEFAULT_MEM_ORDER_KIND(acq_rel) OPENMP_ATOMIC_DEFAULT_MEM_ORDER_KIND(relaxed) -// Clauses allowed for OpenMP directive 'target data'. -OPENMP_TARGET_DATA_CLAUSE(if) -OPENMP_TARGET_DATA_CLAUSE(device) -OPENMP_TARGET_DATA_CLAUSE(map) -OPENMP_TARGET_DATA_CLAUSE(use_device_ptr) - -// Clauses allowed for OpenMP directive 'target enter data'. -OPENMP_TARGET_ENTER_DATA_CLAUSE(if) -OPENMP_TARGET_ENTER_DATA_CLAUSE(device) -OPENMP_TARGET_ENTER_DATA_CLAUSE(map) -OPENMP_TARGET_ENTER_DATA_CLAUSE(nowait) -OPENMP_TARGET_ENTER_DATA_CLAUSE(depend) - -// Clauses allowed for OpenMP directive 'target exit data'. -OPENMP_TARGET_EXIT_DATA_CLAUSE(if) -OPENMP_TARGET_EXIT_DATA_CLAUSE(device) -OPENMP_TARGET_EXIT_DATA_CLAUSE(map) -OPENMP_TARGET_EXIT_DATA_CLAUSE(nowait) -OPENMP_TARGET_EXIT_DATA_CLAUSE(depend) - -// Clauses allowed for OpenMP directive 'target parallel'. -OPENMP_TARGET_PARALLEL_CLAUSE(if) -OPENMP_TARGET_PARALLEL_CLAUSE(device) -OPENMP_TARGET_PARALLEL_CLAUSE(map) -OPENMP_TARGET_PARALLEL_CLAUSE(private) -OPENMP_TARGET_PARALLEL_CLAUSE(firstprivate) -OPENMP_TARGET_PARALLEL_CLAUSE(nowait) -OPENMP_TARGET_PARALLEL_CLAUSE(depend) -OPENMP_TARGET_PARALLEL_CLAUSE(defaultmap) -OPENMP_TARGET_PARALLEL_CLAUSE(num_threads) -OPENMP_TARGET_PARALLEL_CLAUSE(default) -OPENMP_TARGET_PARALLEL_CLAUSE(proc_bind) -OPENMP_TARGET_PARALLEL_CLAUSE(shared) -OPENMP_TARGET_PARALLEL_CLAUSE(reduction) -OPENMP_TARGET_PARALLEL_CLAUSE(is_device_ptr) -OPENMP_TARGET_PARALLEL_CLAUSE(allocate) - -// Clauses allowed for OpenMP directive 'target parallel for'. -OPENMP_TARGET_PARALLEL_FOR_CLAUSE(if) -OPENMP_TARGET_PARALLEL_FOR_CLAUSE(device) -OPENMP_TARGET_PARALLEL_FOR_CLAUSE(map) -OPENMP_TARGET_PARALLEL_FOR_CLAUSE(private) -OPENMP_TARGET_PARALLEL_FOR_CLAUSE(firstprivate) -OPENMP_TARGET_PARALLEL_FOR_CLAUSE(lastprivate) -OPENMP_TARGET_PARALLEL_FOR_CLAUSE(nowait) -OPENMP_TARGET_PARALLEL_FOR_CLAUSE(depend) -OPENMP_TARGET_PARALLEL_FOR_CLAUSE(defaultmap) -OPENMP_TARGET_PARALLEL_FOR_CLAUSE(num_threads) -OPENMP_TARGET_PARALLEL_FOR_CLAUSE(default) -OPENMP_TARGET_PARALLEL_FOR_CLAUSE(proc_bind) -OPENMP_TARGET_PARALLEL_FOR_CLAUSE(shared) -OPENMP_TARGET_PARALLEL_FOR_CLAUSE(reduction) -OPENMP_TARGET_PARALLEL_FOR_CLAUSE(collapse) -OPENMP_TARGET_PARALLEL_FOR_CLAUSE(schedule) -OPENMP_TARGET_PARALLEL_FOR_CLAUSE(ordered) -OPENMP_TARGET_PARALLEL_FOR_CLAUSE(linear) -OPENMP_TARGET_PARALLEL_FOR_CLAUSE(is_device_ptr) -OPENMP_TARGET_PARALLEL_FOR_CLAUSE(allocate) - -// Clauses allowed for OpenMP directive 'target update'. -OPENMP_TARGET_UPDATE_CLAUSE(if) -OPENMP_TARGET_UPDATE_CLAUSE(device) -OPENMP_TARGET_UPDATE_CLAUSE(to) -OPENMP_TARGET_UPDATE_CLAUSE(from) -OPENMP_TARGET_UPDATE_CLAUSE(nowait) -OPENMP_TARGET_UPDATE_CLAUSE(depend) - -// Clauses allowed for OpenMP directive 'teams'. -OPENMP_TEAMS_CLAUSE(default) -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) -OPENMP_TEAMS_CLAUSE(allocate) - -// Clauses allowed for OpenMP directive 'ordered'. -OPENMP_ORDERED_CLAUSE(threads) -OPENMP_ORDERED_CLAUSE(simd) -OPENMP_ORDERED_CLAUSE(depend) - // Map types for 'map' clause. OPENMP_MAP_KIND(alloc) OPENMP_MAP_KIND(to) @@ -607,518 +131,40 @@ OPENMP_TO_MODIFIER_KIND(mapper) // Modifiers for 'from' clause. OPENMP_FROM_MODIFIER_KIND(mapper) -// 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) -OPENMP_TASKLOOP_CLAUSE(reduction) -OPENMP_TASKLOOP_CLAUSE(in_reduction) -OPENMP_TASKLOOP_CLAUSE(allocate) - -// 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) -OPENMP_TASKLOOP_SIMD_CLAUSE(reduction) -OPENMP_TASKLOOP_SIMD_CLAUSE(in_reduction) -OPENMP_TASKLOOP_SIMD_CLAUSE(allocate) -OPENMP_TASKLOOP_SIMD_CLAUSE(nontemporal) - -// Clauses allowed for OpenMP directive 'master taskloop'. -OPENMP_MASTER_TASKLOOP_CLAUSE(if) -OPENMP_MASTER_TASKLOOP_CLAUSE(shared) -OPENMP_MASTER_TASKLOOP_CLAUSE(private) -OPENMP_MASTER_TASKLOOP_CLAUSE(firstprivate) -OPENMP_MASTER_TASKLOOP_CLAUSE(lastprivate) -OPENMP_MASTER_TASKLOOP_CLAUSE(default) -OPENMP_MASTER_TASKLOOP_CLAUSE(collapse) -OPENMP_MASTER_TASKLOOP_CLAUSE(final) -OPENMP_MASTER_TASKLOOP_CLAUSE(untied) -OPENMP_MASTER_TASKLOOP_CLAUSE(mergeable) -OPENMP_MASTER_TASKLOOP_CLAUSE(priority) -OPENMP_MASTER_TASKLOOP_CLAUSE(grainsize) -OPENMP_MASTER_TASKLOOP_CLAUSE(nogroup) -OPENMP_MASTER_TASKLOOP_CLAUSE(num_tasks) -OPENMP_MASTER_TASKLOOP_CLAUSE(reduction) -OPENMP_MASTER_TASKLOOP_CLAUSE(in_reduction) -OPENMP_MASTER_TASKLOOP_CLAUSE(allocate) - -// Clauses allowed for OpenMP directive 'master taskloop simd'. -OPENMP_MASTER_TASKLOOP_SIMD_CLAUSE(if) -OPENMP_MASTER_TASKLOOP_SIMD_CLAUSE(shared) -OPENMP_MASTER_TASKLOOP_SIMD_CLAUSE(private) -OPENMP_MASTER_TASKLOOP_SIMD_CLAUSE(firstprivate) -OPENMP_MASTER_TASKLOOP_SIMD_CLAUSE(lastprivate) -OPENMP_MASTER_TASKLOOP_SIMD_CLAUSE(default) -OPENMP_MASTER_TASKLOOP_SIMD_CLAUSE(collapse) -OPENMP_MASTER_TASKLOOP_SIMD_CLAUSE(final) -OPENMP_MASTER_TASKLOOP_SIMD_CLAUSE(untied) -OPENMP_MASTER_TASKLOOP_SIMD_CLAUSE(mergeable) -OPENMP_MASTER_TASKLOOP_SIMD_CLAUSE(priority) -OPENMP_MASTER_TASKLOOP_SIMD_CLAUSE(linear) -OPENMP_MASTER_TASKLOOP_SIMD_CLAUSE(aligned) -OPENMP_MASTER_TASKLOOP_SIMD_CLAUSE(safelen) -OPENMP_MASTER_TASKLOOP_SIMD_CLAUSE(simdlen) -OPENMP_MASTER_TASKLOOP_SIMD_CLAUSE(grainsize) -OPENMP_MASTER_TASKLOOP_SIMD_CLAUSE(nogroup) -OPENMP_MASTER_TASKLOOP_SIMD_CLAUSE(num_tasks) -OPENMP_MASTER_TASKLOOP_SIMD_CLAUSE(reduction) -OPENMP_MASTER_TASKLOOP_SIMD_CLAUSE(in_reduction) -OPENMP_MASTER_TASKLOOP_SIMD_CLAUSE(allocate) -OPENMP_MASTER_TASKLOOP_SIMD_CLAUSE(nontemporal) - -// Clauses allowed for OpenMP directive 'parallel master taskloop'. -OPENMP_PARALLEL_MASTER_TASKLOOP_CLAUSE(if) -OPENMP_PARALLEL_MASTER_TASKLOOP_CLAUSE(shared) -OPENMP_PARALLEL_MASTER_TASKLOOP_CLAUSE(private) -OPENMP_PARALLEL_MASTER_TASKLOOP_CLAUSE(firstprivate) -OPENMP_PARALLEL_MASTER_TASKLOOP_CLAUSE(lastprivate) -OPENMP_PARALLEL_MASTER_TASKLOOP_CLAUSE(default) -OPENMP_PARALLEL_MASTER_TASKLOOP_CLAUSE(collapse) -OPENMP_PARALLEL_MASTER_TASKLOOP_CLAUSE(final) -OPENMP_PARALLEL_MASTER_TASKLOOP_CLAUSE(untied) -OPENMP_PARALLEL_MASTER_TASKLOOP_CLAUSE(mergeable) -OPENMP_PARALLEL_MASTER_TASKLOOP_CLAUSE(priority) -OPENMP_PARALLEL_MASTER_TASKLOOP_CLAUSE(grainsize) -OPENMP_PARALLEL_MASTER_TASKLOOP_CLAUSE(nogroup) -OPENMP_PARALLEL_MASTER_TASKLOOP_CLAUSE(num_tasks) -OPENMP_PARALLEL_MASTER_TASKLOOP_CLAUSE(reduction) -OPENMP_PARALLEL_MASTER_TASKLOOP_CLAUSE(allocate) -OPENMP_PARALLEL_MASTER_TASKLOOP_CLAUSE(num_threads) -OPENMP_PARALLEL_MASTER_TASKLOOP_CLAUSE(proc_bind) -OPENMP_PARALLEL_MASTER_TASKLOOP_CLAUSE(copyin) - -// Clauses allowed for OpenMP directive 'parallel master taskloop simd'. -OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(if) -OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(shared) -OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(private) -OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(firstprivate) -OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(lastprivate) -OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(default) -OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(collapse) -OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(final) -OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(untied) -OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(mergeable) -OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(priority) -OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(grainsize) -OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(nogroup) -OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(num_tasks) -OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(reduction) -OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(allocate) -OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(num_threads) -OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(proc_bind) -OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(copyin) -OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(linear) -OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(aligned) -OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(safelen) -OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(simdlen) -OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE(nontemporal) - -// 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) -OPENMP_DISTRIBUTE_CLAUSE(dist_schedule) -OPENMP_DISTRIBUTE_CLAUSE(allocate) - // Static attributes for 'dist_schedule' clause. OPENMP_DIST_SCHEDULE_KIND(static) -// Clauses allowed for OpenMP directive 'distribute parallel for' -OPENMP_DISTRIBUTE_PARALLEL_FOR_CLAUSE(firstprivate) -OPENMP_DISTRIBUTE_PARALLEL_FOR_CLAUSE(lastprivate) -OPENMP_DISTRIBUTE_PARALLEL_FOR_CLAUSE(collapse) -OPENMP_DISTRIBUTE_PARALLEL_FOR_CLAUSE(dist_schedule) -OPENMP_DISTRIBUTE_PARALLEL_FOR_CLAUSE(if) -OPENMP_DISTRIBUTE_PARALLEL_FOR_CLAUSE(num_threads) -OPENMP_DISTRIBUTE_PARALLEL_FOR_CLAUSE(default) -OPENMP_DISTRIBUTE_PARALLEL_FOR_CLAUSE(proc_bind) -OPENMP_DISTRIBUTE_PARALLEL_FOR_CLAUSE(private) -OPENMP_DISTRIBUTE_PARALLEL_FOR_CLAUSE(shared) -OPENMP_DISTRIBUTE_PARALLEL_FOR_CLAUSE(reduction) -OPENMP_DISTRIBUTE_PARALLEL_FOR_CLAUSE(copyin) -OPENMP_DISTRIBUTE_PARALLEL_FOR_CLAUSE(schedule) -OPENMP_DISTRIBUTE_PARALLEL_FOR_CLAUSE(allocate) - -// Clauses allowed for OpenMP directive 'distribute parallel for simd' -OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(firstprivate) -OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(lastprivate) -OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(collapse) -OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(dist_schedule) -OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(if) -OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(num_threads) -OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(default) -OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(proc_bind) -OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(private) -OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(shared) -OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(reduction) -OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(copyin) -OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(schedule) -OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(linear) -OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(aligned) -OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(safelen) -OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(simdlen) -OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(allocate) -OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(nontemporal) - -// Clauses allowed for OpenMP directive 'distribute simd' -OPENMP_DISTRIBUTE_SIMD_CLAUSE(private) -OPENMP_DISTRIBUTE_SIMD_CLAUSE(firstprivate) -OPENMP_DISTRIBUTE_SIMD_CLAUSE(lastprivate) -OPENMP_DISTRIBUTE_SIMD_CLAUSE(collapse) -OPENMP_DISTRIBUTE_SIMD_CLAUSE(dist_schedule) -OPENMP_DISTRIBUTE_SIMD_CLAUSE(linear) -OPENMP_DISTRIBUTE_SIMD_CLAUSE(aligned) -OPENMP_DISTRIBUTE_SIMD_CLAUSE(safelen) -OPENMP_DISTRIBUTE_SIMD_CLAUSE(simdlen) -OPENMP_DISTRIBUTE_SIMD_CLAUSE(reduction) -OPENMP_DISTRIBUTE_SIMD_CLAUSE(allocate) -OPENMP_DISTRIBUTE_SIMD_CLAUSE(if) -OPENMP_DISTRIBUTE_SIMD_CLAUSE(nontemporal) - -// Clauses allowed for OpenMP directive 'target parallel for simd'. -OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(if) -OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(device) -OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(map) -OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(private) -OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(firstprivate) -OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(lastprivate) -OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(nowait) -OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(depend) -OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(defaultmap) -OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(num_threads) -OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(default) -OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(proc_bind) -OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(shared) -OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(reduction) -OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(collapse) -OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(schedule) -OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(ordered) -OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(linear) -OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(safelen) -OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(simdlen) -OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(aligned) -OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(is_device_ptr) -OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(allocate) -OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE(nontemporal) - -// Clauses allowed for OpenMP directive 'target simd'. -OPENMP_TARGET_SIMD_CLAUSE(if) -OPENMP_TARGET_SIMD_CLAUSE(device) -OPENMP_TARGET_SIMD_CLAUSE(map) -OPENMP_TARGET_SIMD_CLAUSE(private) -OPENMP_TARGET_SIMD_CLAUSE(nowait) -OPENMP_TARGET_SIMD_CLAUSE(depend) -OPENMP_TARGET_SIMD_CLAUSE(defaultmap) -OPENMP_TARGET_SIMD_CLAUSE(firstprivate) -OPENMP_TARGET_SIMD_CLAUSE(is_device_ptr) -OPENMP_TARGET_SIMD_CLAUSE(lastprivate) -OPENMP_TARGET_SIMD_CLAUSE(linear) -OPENMP_TARGET_SIMD_CLAUSE(aligned) -OPENMP_TARGET_SIMD_CLAUSE(safelen) -OPENMP_TARGET_SIMD_CLAUSE(simdlen) -OPENMP_TARGET_SIMD_CLAUSE(collapse) -OPENMP_TARGET_SIMD_CLAUSE(reduction) -OPENMP_TARGET_SIMD_CLAUSE(allocate) -OPENMP_TARGET_SIMD_CLAUSE(nontemporal) - -// Clauses allowed for OpenMP directive 'teams distribute'. -OPENMP_TEAMS_DISTRIBUTE_CLAUSE(default) -OPENMP_TEAMS_DISTRIBUTE_CLAUSE(private) -OPENMP_TEAMS_DISTRIBUTE_CLAUSE(firstprivate) -OPENMP_TEAMS_DISTRIBUTE_CLAUSE(shared) -OPENMP_TEAMS_DISTRIBUTE_CLAUSE(reduction) -OPENMP_TEAMS_DISTRIBUTE_CLAUSE(num_teams) -OPENMP_TEAMS_DISTRIBUTE_CLAUSE(thread_limit) -OPENMP_TEAMS_DISTRIBUTE_CLAUSE(lastprivate) -OPENMP_TEAMS_DISTRIBUTE_CLAUSE(collapse) -OPENMP_TEAMS_DISTRIBUTE_CLAUSE(dist_schedule) -OPENMP_TEAMS_DISTRIBUTE_CLAUSE(allocate) - -// Clauses allowed for OpenMP directive 'teams distribute simd' -OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(default) -OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(private) -OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(firstprivate) -OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(shared) -OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(reduction) -OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(num_teams) -OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(thread_limit) -OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(lastprivate) -OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(collapse) -OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(dist_schedule) -OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(linear) -OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(aligned) -OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(safelen) -OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(simdlen) -OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(allocate) -OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(if) -OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE(nontemporal) - -// Clauses allowed for OpenMP directive 'teams distribute parallel for simd' -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(firstprivate) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(lastprivate) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(collapse) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(dist_schedule) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(if) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(num_threads) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(default) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(proc_bind) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(private) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(shared) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(reduction) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(schedule) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(linear) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(aligned) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(safelen) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(simdlen) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(num_teams) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(thread_limit) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(allocate) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(nontemporal) - -// Clauses allowed for OpenMP directive 'teams distribute parallel for' -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(firstprivate) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(lastprivate) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(collapse) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(dist_schedule) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(if) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(num_threads) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(default) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(proc_bind) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(private) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(shared) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(reduction) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(schedule) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(num_teams) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(thread_limit) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(copyin) -OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(allocate) - -// Clauses allowed for OpenMP directive 'target teams'. -OPENMP_TARGET_TEAMS_CLAUSE(if) -OPENMP_TARGET_TEAMS_CLAUSE(device) -OPENMP_TARGET_TEAMS_CLAUSE(map) -OPENMP_TARGET_TEAMS_CLAUSE(private) -OPENMP_TARGET_TEAMS_CLAUSE(nowait) -OPENMP_TARGET_TEAMS_CLAUSE(depend) -OPENMP_TARGET_TEAMS_CLAUSE(defaultmap) -OPENMP_TARGET_TEAMS_CLAUSE(firstprivate) -OPENMP_TARGET_TEAMS_CLAUSE(is_device_ptr) -OPENMP_TARGET_TEAMS_CLAUSE(default) -OPENMP_TARGET_TEAMS_CLAUSE(shared) -OPENMP_TARGET_TEAMS_CLAUSE(reduction) -OPENMP_TARGET_TEAMS_CLAUSE(num_teams) -OPENMP_TARGET_TEAMS_CLAUSE(thread_limit) -OPENMP_TARGET_TEAMS_CLAUSE(allocate) - -// Clauses allowed for OpenMP directive 'target teams distribute'. -OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(if) -OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(device) -OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(map) -OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(private) -OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(nowait) -OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(depend) -OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(defaultmap) -OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(firstprivate) -OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(is_device_ptr) -OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(default) -OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(shared) -OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(reduction) -OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(num_teams) -OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(thread_limit) -OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(lastprivate) -OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(collapse) -OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(dist_schedule) -OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE(allocate) - -// Clauses allowed for OpenMP directive 'target teams distribute parallel for'. -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(if) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(device) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(map) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(private) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(nowait) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(depend) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(defaultmap) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(firstprivate) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(is_device_ptr) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(default) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(shared) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(reduction) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(num_teams) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(thread_limit) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(lastprivate) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(collapse) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(dist_schedule) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(num_threads) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(proc_bind) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(schedule) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE(allocate) - -// Clauses allowed for OpenMP directive -// 'target teams distribute parallel for simd'. -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(if) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(device) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(map) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(private) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(nowait) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(depend) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(defaultmap) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(firstprivate) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(is_device_ptr) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(default) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(shared) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(reduction) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(num_teams) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(thread_limit) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(lastprivate) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(collapse) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(dist_schedule) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(num_threads) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(proc_bind) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(schedule) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(linear) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(aligned) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(safelen) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(simdlen) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(allocate) -OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE(nontemporal) - -// Clauses allowed for OpenMP directive 'target teams distribute simd'. -OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(if) -OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(device) -OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(map) -OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(private) -OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(nowait) -OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(depend) -OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(defaultmap) -OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(firstprivate) -OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(lastprivate) -OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(is_device_ptr) -OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(shared) -OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(reduction) -OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(num_teams) -OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(thread_limit) -OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(collapse) -OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(dist_schedule) -OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(linear) -OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(aligned) -OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(safelen) -OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(simdlen) -OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(allocate) -OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(nontemporal) - -// Clauses allowed for OpenMP directive 'taskgroup'. -OPENMP_TASKGROUP_CLAUSE(task_reduction) -OPENMP_TASKGROUP_CLAUSE(allocate) - -// Clauses allowed for OpenMP directive 'declare mapper'. -OPENMP_DECLARE_MAPPER_CLAUSE(map) - // Device types for 'device_type' clause. OPENMP_DEVICE_TYPE_KIND(host) OPENMP_DEVICE_TYPE_KIND(nohost) OPENMP_DEVICE_TYPE_KIND(any) -// Clauses allowed for OpenMP directive 'declare variant'. -OPENMP_DECLARE_VARIANT_CLAUSE(match) - // Type of the 'lastprivate' clause. OPENMP_LASTPRIVATE_KIND(conditional) +// Type of the 'order' clause. +OPENMP_ORDER_KIND(concurrent) + +// Modifiers for 'reduction' clause. +OPENMP_REDUCTION_MODIFIER(default) +OPENMP_REDUCTION_MODIFIER(inscan) +OPENMP_REDUCTION_MODIFIER(task) + +#undef OPENMP_REDUCTION_MODIFIER +#undef OPENMP_DEVICE_MODIFIER +#undef OPENMP_ORDER_KIND #undef OPENMP_LASTPRIVATE_KIND -#undef OPENMP_CONTEXT_SELECTOR -#undef OPENMP_CONTEXT_SELECTOR_SET -#undef OPENMP_DECLARE_VARIANT_CLAUSE #undef OPENMP_DEVICE_TYPE_KIND -#undef OPENMP_ALLOCATE_CLAUSE -#undef OPENMP_DECLARE_MAPPER_CLAUSE -#undef OPENMP_TASKGROUP_CLAUSE -#undef OPENMP_PARALLEL_MASTER_TASKLOOP_SIMD_CLAUSE -#undef OPENMP_PARALLEL_MASTER_TASKLOOP_CLAUSE -#undef OPENMP_MASTER_TASKLOOP_SIMD_CLAUSE -#undef OPENMP_MASTER_TASKLOOP_CLAUSE -#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_DEFAULT_KIND -#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 -#undef OPENMP_PARALLEL_FOR_CLAUSE -#undef OPENMP_PARALLEL_FOR_SIMD_CLAUSE -#undef OPENMP_PARALLEL_MASTER_CLAUSE -#undef OPENMP_PARALLEL_SECTIONS_CLAUSE -#undef OPENMP_TASK_CLAUSE -#undef OPENMP_ATOMIC_CLAUSE -#undef OPENMP_TARGET_CLAUSE -#undef OPENMP_REQUIRES_CLAUSE #undef OPENMP_ATOMIC_DEFAULT_MEM_ORDER_KIND -#undef OPENMP_TARGET_DATA_CLAUSE -#undef OPENMP_TARGET_ENTER_DATA_CLAUSE -#undef OPENMP_TARGET_EXIT_DATA_CLAUSE -#undef OPENMP_TARGET_PARALLEL_CLAUSE -#undef OPENMP_TARGET_PARALLEL_FOR_CLAUSE -#undef OPENMP_TEAMS_CLAUSE -#undef OPENMP_SIMD_CLAUSE -#undef OPENMP_FOR_CLAUSE -#undef OPENMP_FOR_SIMD_CLAUSE #undef OPENMP_MAP_KIND #undef OPENMP_MAP_MODIFIER_KIND #undef OPENMP_TO_MODIFIER_KIND #undef OPENMP_FROM_MODIFIER_KIND -#undef OPENMP_DISTRIBUTE_CLAUSE #undef OPENMP_DIST_SCHEDULE_KIND #undef OPENMP_DEFAULTMAP_KIND #undef OPENMP_DEFAULTMAP_MODIFIER -#undef OPENMP_TARGET_UPDATE_CLAUSE -#undef OPENMP_DISTRIBUTE_PARALLEL_FOR_CLAUSE -#undef OPENMP_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE -#undef OPENMP_DISTRIBUTE_SIMD_CLAUSE -#undef OPENMP_TARGET_PARALLEL_FOR_SIMD_CLAUSE -#undef OPENMP_TARGET_SIMD_CLAUSE -#undef OPENMP_TEAMS_DISTRIBUTE_CLAUSE -#undef OPENMP_TEAMS_DISTRIBUTE_SIMD_CLAUSE -#undef OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE -#undef OPENMP_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE -#undef OPENMP_TARGET_TEAMS_CLAUSE -#undef OPENMP_TARGET_TEAMS_DISTRIBUTE_CLAUSE -#undef OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_CLAUSE -#undef OPENMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_CLAUSE -#undef OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE + diff --git a/clang/include/clang/Basic/OpenMPKinds.h b/clang/include/clang/Basic/OpenMPKinds.h index 302312325308..08aaf2d43bfd 100644 --- a/clang/include/clang/Basic/OpenMPKinds.h +++ b/clang/include/clang/Basic/OpenMPKinds.h @@ -19,67 +19,11 @@ namespace clang { -/// OpenMP context selector sets. -enum OpenMPContextSelectorSetKind { -#define OPENMP_CONTEXT_SELECTOR_SET(Name) OMP_CTX_SET_##Name, -#include "clang/Basic/OpenMPKinds.def" - OMP_CTX_SET_unknown, -}; - -/// OpenMP context selectors. -enum OpenMPContextSelectorKind { -#define OPENMP_CONTEXT_SELECTOR(Name) OMP_CTX_##Name, -#include "clang/Basic/OpenMPKinds.def" - OMP_CTX_unknown, -}; - -OpenMPContextSelectorSetKind getOpenMPContextSelectorSet(llvm::StringRef Str); -llvm::StringRef -getOpenMPContextSelectorSetName(OpenMPContextSelectorSetKind Kind); -OpenMPContextSelectorKind getOpenMPContextSelector(llvm::StringRef Str); -llvm::StringRef getOpenMPContextSelectorName(OpenMPContextSelectorKind Kind); - -/// Struct to store the context selectors info. -template <typename VectorType, typename ScoreT> struct OpenMPCtxSelectorData { - OpenMPContextSelectorSetKind CtxSet = OMP_CTX_SET_unknown; - OpenMPContextSelectorKind Ctx = OMP_CTX_unknown; - ScoreT Score; - VectorType Names; - explicit OpenMPCtxSelectorData() = default; - explicit OpenMPCtxSelectorData(OpenMPContextSelectorSetKind CtxSet, - OpenMPContextSelectorKind Ctx, - const ScoreT &Score, VectorType &&Names) - : CtxSet(CtxSet), Ctx(Ctx), Score(Score), Names(Names) {} - template <typename U> - explicit OpenMPCtxSelectorData(OpenMPContextSelectorSetKind CtxSet, - OpenMPContextSelectorKind Ctx, - const ScoreT &Score, const U &Names) - : CtxSet(CtxSet), Ctx(Ctx), Score(Score), - Names(Names.begin(), Names.end()) {} -}; - /// OpenMP directives. using OpenMPDirectiveKind = llvm::omp::Directive; /// OpenMP clauses. -enum OpenMPClauseKind { -#define OPENMP_CLAUSE(Name, Class) \ - OMPC_##Name, -#include "clang/Basic/OpenMPKinds.def" - OMPC_threadprivate, - OMPC_uniform, - OMPC_device_type, - OMPC_match, - OMPC_unknown -}; - -/// OpenMP attributes for 'default' clause. -enum OpenMPDefaultClauseKind { -#define OPENMP_DEFAULT_KIND(Name) \ - OMPC_DEFAULT_##Name, -#include "clang/Basic/OpenMPKinds.def" - OMPC_DEFAULT_unknown -}; +using OpenMPClauseKind = llvm::omp::Clause; /// OpenMP attributes for 'schedule' clause. enum OpenMPScheduleClauseKind { @@ -98,6 +42,13 @@ enum OpenMPScheduleClauseModifier { OMPC_SCHEDULE_MODIFIER_last }; +/// OpenMP modifiers for 'device' clause. +enum OpenMPDeviceClauseModifier { +#define OPENMP_DEVICE_MODIFIER(Name) OMPC_DEVICE_##Name, +#include "clang/Basic/OpenMPKinds.def" + OMPC_DEVICE_unknown, +}; + /// OpenMP attributes for 'depend' clause. enum OpenMPDependClauseKind { #define OPENMP_DEPEND_KIND(Name) \ @@ -131,6 +82,10 @@ enum OpenMPMapModifierKind { OMPC_MAP_MODIFIER_last }; + /// Number of allowed map-type-modifiers. +static constexpr unsigned NumberOfOMPMapClauseModifiers = + OMPC_MAP_MODIFIER_last - OMPC_MAP_MODIFIER_unknown - 1; + /// OpenMP modifier kind for 'to' clause. enum OpenMPToModifierKind { #define OPENMP_TO_MODIFIER_KIND(Name) \ @@ -194,6 +149,13 @@ enum OpenMPLastprivateModifier { OMPC_LASTPRIVATE_unknown, }; +/// OpenMP attributes for 'order' clause. +enum OpenMPOrderClauseKind { +#define OPENMP_ORDER_KIND(Name) OMPC_ORDER_##Name, +#include "clang/Basic/OpenMPKinds.def" + OMPC_ORDER_unknown, +}; + /// Scheduling data for loop-based OpenMP directives. struct OpenMPScheduleTy final { OpenMPScheduleClauseKind Schedule = OMPC_SCHEDULE_unknown; @@ -201,16 +163,16 @@ struct OpenMPScheduleTy final { OpenMPScheduleClauseModifier M2 = OMPC_SCHEDULE_MODIFIER_unknown; }; -OpenMPClauseKind getOpenMPClauseKind(llvm::StringRef Str); -const char *getOpenMPClauseName(OpenMPClauseKind Kind); +/// OpenMP modifiers for 'reduction' clause. +enum OpenMPReductionClauseModifier { +#define OPENMP_REDUCTION_MODIFIER(Name) OMPC_REDUCTION_##Name, +#include "clang/Basic/OpenMPKinds.def" + OMPC_REDUCTION_unknown, +}; unsigned getOpenMPSimpleClauseType(OpenMPClauseKind Kind, llvm::StringRef Str); const char *getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind, unsigned Type); -bool isAllowedClauseForDirective(OpenMPDirectiveKind DKind, - OpenMPClauseKind CKind, - unsigned OpenMPVersion); - /// Checks if the specified directive is a directive with an associated /// loop construct. /// \param DKind Specified directive. diff --git a/clang/include/clang/Basic/PartialDiagnostic.h b/clang/include/clang/Basic/PartialDiagnostic.h index 799951b82a6c..107d621f0dec 100644 --- a/clang/include/clang/Basic/PartialDiagnostic.h +++ b/clang/include/clang/Basic/PartialDiagnostic.h @@ -285,7 +285,7 @@ public: "Too many arguments to diagnostic!"); DiagStorage->DiagArgumentsKind[DiagStorage->NumDiagArgs] = DiagnosticsEngine::ak_std_string; - DiagStorage->DiagArgumentsStr[DiagStorage->NumDiagArgs++] = V; + DiagStorage->DiagArgumentsStr[DiagStorage->NumDiagArgs++] = std::string(V); } void Emit(const DiagnosticBuilder &DB) const { @@ -378,10 +378,9 @@ public: // so that we only match those arguments that are (statically) DeclContexts; // other arguments that derive from DeclContext (e.g., RecordDecls) will not // match. - template<typename T> - friend inline - typename std::enable_if<std::is_same<T, DeclContext>::value, - const PartialDiagnostic &>::type + template <typename T> + friend inline std::enable_if_t<std::is_same<T, DeclContext>::value, + const PartialDiagnostic &> operator<<(const PartialDiagnostic &PD, T *DC) { PD.AddTaggedVal(reinterpret_cast<intptr_t>(DC), DiagnosticsEngine::ak_declcontext); diff --git a/clang/include/clang/Basic/PragmaKinds.h b/clang/include/clang/Basic/PragmaKinds.h index 103b97db718b..82c0d5f0a551 100644 --- a/clang/include/clang/Basic/PragmaKinds.h +++ b/clang/include/clang/Basic/PragmaKinds.h @@ -25,6 +25,15 @@ enum PragmaMSStructKind { PMSST_ON // #pragms ms_struct on }; +enum PragmaFloatControlKind { + PFC_Unknown, + PFC_Precise, // #pragma float_control(precise, [,on]) + PFC_NoPrecise, // #pragma float_control(precise, off) + PFC_Except, // #pragma float_control(except [,on]) + PFC_NoExcept, // #pragma float_control(except, off) + PFC_Push, // #pragma float_control(push) + PFC_Pop // #pragma float_control(pop) +}; } #endif diff --git a/clang/include/clang/Basic/SanitizerBlacklist.h b/clang/include/clang/Basic/SanitizerBlacklist.h index 29af28b84365..c874ff28aacc 100644 --- a/clang/include/clang/Basic/SanitizerBlacklist.h +++ b/clang/include/clang/Basic/SanitizerBlacklist.h @@ -14,15 +14,17 @@ #define LLVM_CLANG_BASIC_SANITIZERBLACKLIST_H #include "clang/Basic/LLVM.h" -#include "clang/Basic/SanitizerSpecialCaseList.h" -#include "clang/Basic/Sanitizers.h" #include "clang/Basic/SourceLocation.h" -#include "clang/Basic/SourceManager.h" #include "llvm/ADT/StringRef.h" #include <memory> +#include <vector> namespace clang { +class SanitizerMask; +class SourceManager; +class SanitizerSpecialCaseList; + class SanitizerBlacklist { std::unique_ptr<SanitizerSpecialCaseList> SSCL; SourceManager &SM; @@ -30,6 +32,7 @@ class SanitizerBlacklist { public: SanitizerBlacklist(const std::vector<std::string> &BlacklistPaths, SourceManager &SM); + ~SanitizerBlacklist(); bool isBlacklistedGlobal(SanitizerMask Mask, StringRef GlobalName, StringRef Category = StringRef()) const; bool isBlacklistedType(SanitizerMask Mask, StringRef MangledTypeName, diff --git a/clang/include/clang/Basic/SanitizerSpecialCaseList.h b/clang/include/clang/Basic/SanitizerSpecialCaseList.h index 88d31a6cbcce..c84894dae298 100644 --- a/clang/include/clang/Basic/SanitizerSpecialCaseList.h +++ b/clang/include/clang/Basic/SanitizerSpecialCaseList.h @@ -10,6 +10,7 @@ // SanitizerMask. // //===----------------------------------------------------------------------===// + #ifndef LLVM_CLANG_BASIC_SANITIZERSPECIALCASELIST_H #define LLVM_CLANG_BASIC_SANITIZERSPECIALCASELIST_H @@ -17,8 +18,14 @@ #include "clang/Basic/Sanitizers.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/SpecialCaseList.h" -#include "llvm/Support/VirtualFileSystem.h" #include <memory> +#include <vector> + +namespace llvm { +namespace vfs { +class FileSystem; +} +} // namespace llvm namespace clang { diff --git a/clang/include/clang/Basic/Sanitizers.def b/clang/include/clang/Basic/Sanitizers.def index 0037cc2146f2..2912bdd44b2d 100644 --- a/clang/include/clang/Basic/Sanitizers.def +++ b/clang/include/clang/Basic/Sanitizers.def @@ -156,6 +156,8 @@ SANITIZER_GROUP("implicit-integer-arithmetic-value-change", ImplicitIntegerArithmeticValueChange, ImplicitIntegerSignChange | ImplicitSignedIntegerTruncation) +SANITIZER("objc-cast", ObjCCast) + // FIXME: //SANITIZER_GROUP("implicit-integer-conversion", ImplicitIntegerConversion, // ImplicitIntegerArithmeticValueChange | diff --git a/clang/include/clang/Basic/SourceLocation.h b/clang/include/clang/Basic/SourceLocation.h index d3d18537dcc1..3735b904ef47 100644 --- a/clang/include/clang/Basic/SourceLocation.h +++ b/clang/include/clang/Basic/SourceLocation.h @@ -482,7 +482,7 @@ namespace llvm { // Teach SmallPtrSet how to handle SourceLocation. template<> struct PointerLikeTypeTraits<clang::SourceLocation> { - enum { NumLowBitsAvailable = 0 }; + static constexpr int NumLowBitsAvailable = 0; static void *getAsVoidPointer(clang::SourceLocation L) { return L.getPtrEncoding(); diff --git a/clang/include/clang/Basic/SourceManager.h b/clang/include/clang/Basic/SourceManager.h index d87e9ac810fa..5c666c1760b4 100644 --- a/clang/include/clang/Basic/SourceManager.h +++ b/clang/include/clang/Basic/SourceManager.h @@ -35,7 +35,6 @@ #define LLVM_CLANG_BASIC_SOURCEMANAGER_H #include "clang/Basic/Diagnostic.h" -#include "clang/Basic/FileManager.h" #include "clang/Basic/SourceLocation.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/BitVector.h" @@ -60,6 +59,9 @@ namespace clang { class ASTReader; class ASTWriter; +class FileManager; +class FileEntry; +class FileEntryRef; class LineTableInfo; class SourceManager; @@ -811,6 +813,11 @@ public: MainFileID = FID; } + /// Returns true when the given FileEntry corresponds to the main file. + /// + /// The main file should be set prior to calling this function. + bool isMainFile(FileEntryRef SourceFile); + /// Set the file ID for the precompiled preamble. void setPreambleFileID(FileID Preamble) { assert(PreambleFileID.isInvalid() && "PreambleFileID already set!"); @@ -830,24 +837,11 @@ public: /// This translates NULL into standard input. FileID createFileID(const FileEntry *SourceFile, SourceLocation IncludePos, SrcMgr::CharacteristicKind FileCharacter, - int LoadedID = 0, unsigned LoadedOffset = 0) { - assert(SourceFile && "Null source file!"); - const SrcMgr::ContentCache *IR = - getOrCreateContentCache(SourceFile, isSystem(FileCharacter)); - assert(IR && "getOrCreateContentCache() cannot return NULL"); - return createFileID(IR, SourceFile->getName(), IncludePos, FileCharacter, - LoadedID, LoadedOffset); - } + int LoadedID = 0, unsigned LoadedOffset = 0); FileID createFileID(FileEntryRef SourceFile, SourceLocation IncludePos, SrcMgr::CharacteristicKind FileCharacter, - int LoadedID = 0, unsigned LoadedOffset = 0) { - const SrcMgr::ContentCache *IR = getOrCreateContentCache( - &SourceFile.getFileEntry(), isSystem(FileCharacter)); - assert(IR && "getOrCreateContentCache() cannot return NULL"); - return createFileID(IR, SourceFile.getName(), IncludePos, FileCharacter, - LoadedID, LoadedOffset); - } + int LoadedID = 0, unsigned LoadedOffset = 0); /// Create a new FileID that represents the specified memory buffer. /// @@ -856,12 +850,7 @@ public: FileID createFileID(std::unique_ptr<llvm::MemoryBuffer> Buffer, SrcMgr::CharacteristicKind FileCharacter = SrcMgr::C_User, int LoadedID = 0, unsigned LoadedOffset = 0, - SourceLocation IncludeLoc = SourceLocation()) { - StringRef Name = Buffer->getBufferIdentifier(); - return createFileID( - createMemBufferContentCache(Buffer.release(), /*DoNotFree*/ false), - Name, IncludeLoc, FileCharacter, LoadedID, LoadedOffset); - } + SourceLocation IncludeLoc = SourceLocation()); enum UnownedTag { Unowned }; @@ -872,20 +861,12 @@ public: FileID createFileID(UnownedTag, const llvm::MemoryBuffer *Buffer, SrcMgr::CharacteristicKind FileCharacter = SrcMgr::C_User, int LoadedID = 0, unsigned LoadedOffset = 0, - SourceLocation IncludeLoc = SourceLocation()) { - return createFileID(createMemBufferContentCache(Buffer, /*DoNotFree*/ true), - Buffer->getBufferIdentifier(), IncludeLoc, - FileCharacter, LoadedID, LoadedOffset); - } + SourceLocation IncludeLoc = SourceLocation()); /// Get the FileID for \p SourceFile if it exists. Otherwise, create a /// new FileID for the \p SourceFile. FileID getOrCreateFileID(const FileEntry *SourceFile, - SrcMgr::CharacteristicKind FileCharacter) { - FileID ID = translateFile(SourceFile); - return ID.isValid() ? ID : createFileID(SourceFile, SourceLocation(), - FileCharacter); - } + SrcMgr::CharacteristicKind FileCharacter); /// Return a new SourceLocation that encodes the /// fact that a token from SpellingLoc should actually be referenced from @@ -1025,17 +1006,7 @@ public: } /// Returns the FileEntryRef for the provided FileID. - Optional<FileEntryRef> getFileEntryRefForID(FileID FID) const { - bool Invalid = false; - const SrcMgr::SLocEntry &Entry = getSLocEntry(FID, &Invalid); - if (Invalid || !Entry.isFile()) - return None; - - const SrcMgr::ContentCache *Content = Entry.getFile().getContentCache(); - if (!Content || !Content->OrigEntry) - return None; - return FileEntryRef(Entry.getFile().getName(), *Content->OrigEntry); - } + Optional<FileEntryRef> getFileEntryRefForID(FileID FID) const; /// Returns the FileEntry record for the provided SLocEntry. const FileEntry *getFileEntryForSLocEntry(const SrcMgr::SLocEntry &sloc) const @@ -1098,11 +1069,7 @@ public: } /// Return the filename of the file containing a SourceLocation. - StringRef getFilename(SourceLocation SpellingLoc) const { - if (const FileEntry *F = getFileEntryForID(getFileID(SpellingLoc))) - return F->getName(); - return StringRef(); - } + StringRef getFilename(SourceLocation SpellingLoc) const; /// Return the source location corresponding to the first byte of /// the specified file. @@ -1678,8 +1645,7 @@ public: unsigned local_sloc_entry_size() const { return LocalSLocEntryTable.size(); } /// Get a local SLocEntry. This is exposed for indexing. - const SrcMgr::SLocEntry &getLocalSLocEntry(unsigned Index, - bool *Invalid = nullptr) const { + const SrcMgr::SLocEntry &getLocalSLocEntry(unsigned Index) const { assert(Index < LocalSLocEntryTable.size() && "Invalid index"); return LocalSLocEntryTable[Index]; } @@ -1772,12 +1738,13 @@ private: const SrcMgr::SLocEntry &loadSLocEntry(unsigned Index, bool *Invalid) const; /// Get the entry with the given unwrapped FileID. + /// Invalid will not be modified for Local IDs. const SrcMgr::SLocEntry &getSLocEntryByID(int ID, bool *Invalid = nullptr) const { assert(ID != -1 && "Using FileID sentinel value"); if (ID < 0) return getLoadedSLocEntryByID(ID, Invalid); - return getLocalSLocEntry(static_cast<unsigned>(ID), Invalid); + return getLocalSLocEntry(static_cast<unsigned>(ID)); } const SrcMgr::SLocEntry & diff --git a/clang/include/clang/Basic/Specifiers.h b/clang/include/clang/Basic/Specifiers.h index 73823dc01ec7..2834dea20d00 100644 --- a/clang/include/clang/Basic/Specifiers.h +++ b/clang/include/clang/Basic/Specifiers.h @@ -67,10 +67,12 @@ namespace clang { TST_char32, // C++11 char32_t TST_int, TST_int128, + TST_extint, // Extended Int types. TST_half, // OpenCL half, ARM NEON __fp16 TST_Float16, // C11 extension ISO/IEC TS 18661-3 TST_Accum, // ISO/IEC JTC1 SC22 WG14 N1169 Extension TST_Fract, + TST_BFloat16, TST_float, TST_double, TST_float128, @@ -153,7 +155,10 @@ namespace clang { /// An Objective-C array/dictionary subscripting which reads an /// object or writes at the subscripted array/dictionary element via /// Objective-C method calls. - OK_ObjCSubscript + OK_ObjCSubscript, + + /// A matrix component is a single element of a matrix. + OK_MatrixComponent }; /// The reason why a DeclRefExpr does not constitute an odr-use. @@ -364,6 +369,20 @@ namespace clang { }; llvm::StringRef getParameterABISpelling(ParameterABI kind); + + inline llvm::StringRef getAccessSpelling(AccessSpecifier AS) { + switch (AS) { + case AccessSpecifier::AS_public: + return "public"; + case AccessSpecifier::AS_protected: + return "protected"; + case AccessSpecifier::AS_private: + return "private"; + case AccessSpecifier::AS_none: + return {}; + } + llvm_unreachable("Unknown AccessSpecifier"); + } } // end namespace clang #endif // LLVM_CLANG_BASIC_SPECIFIERS_H diff --git a/clang/include/clang/Basic/StmtNodes.td b/clang/include/clang/Basic/StmtNodes.td index 294993298a18..5965e8b9902a 100644 --- a/clang/include/clang/Basic/StmtNodes.td +++ b/clang/include/clang/Basic/StmtNodes.td @@ -69,7 +69,9 @@ def UnaryOperator : StmtNode<Expr>; def OffsetOfExpr : StmtNode<Expr>; def UnaryExprOrTypeTraitExpr : StmtNode<Expr>; def ArraySubscriptExpr : StmtNode<Expr>; +def MatrixSubscriptExpr : StmtNode<Expr>; def OMPArraySectionExpr : StmtNode<Expr>; +def OMPIteratorExpr : StmtNode<Expr>; def CallExpr : StmtNode<Expr>; def MemberExpr : StmtNode<Expr>; def CastExpr : StmtNode<Expr, 1>; @@ -81,6 +83,7 @@ def BinaryConditionalOperator : StmtNode<AbstractConditionalOperator>; def ImplicitCastExpr : StmtNode<CastExpr>; def ExplicitCastExpr : StmtNode<CastExpr, 1>; def CStyleCastExpr : StmtNode<ExplicitCastExpr>; +def OMPArrayShapingExpr : StmtNode<Expr>; def CompoundLiteralExpr : StmtNode<Expr>; def ExtVectorElementExpr : StmtNode<Expr>; def InitListExpr : StmtNode<Expr>; @@ -118,6 +121,7 @@ def CXXStaticCastExpr : StmtNode<CXXNamedCastExpr>; def CXXDynamicCastExpr : StmtNode<CXXNamedCastExpr>; def CXXReinterpretCastExpr : StmtNode<CXXNamedCastExpr>; def CXXConstCastExpr : StmtNode<CXXNamedCastExpr>; +def CXXAddrspaceCastExpr : StmtNode<CXXNamedCastExpr>; def CXXFunctionalCastExpr : StmtNode<ExplicitCastExpr>; def CXXTypeidExpr : StmtNode<Expr>; def UserDefinedLiteral : StmtNode<CallExpr>; @@ -162,8 +166,9 @@ def CoawaitExpr : StmtNode<CoroutineSuspendExpr>; def DependentCoawaitExpr : StmtNode<Expr>; def CoyieldExpr : StmtNode<CoroutineSuspendExpr>; -// C++2a Concepts expressions +// C++20 Concepts expressions def ConceptSpecializationExpr : StmtNode<Expr>; +def RequiresExpr : StmtNode<Expr>; // Obj-C Expressions. def ObjCStringLiteral : StmtNode<Expr>; @@ -194,6 +199,7 @@ def ConvertVectorExpr : StmtNode<Expr>; def BlockExpr : StmtNode<Expr>; def OpaqueValueExpr : StmtNode<Expr>; def TypoExpr : StmtNode<Expr>; +def RecoveryExpr : StmtNode<Expr>; def BuiltinBitCastExpr : StmtNode<ExplicitCastExpr>; // Microsoft Extensions. @@ -231,6 +237,8 @@ def OMPBarrierDirective : StmtNode<OMPExecutableDirective>; def OMPTaskwaitDirective : StmtNode<OMPExecutableDirective>; def OMPTaskgroupDirective : StmtNode<OMPExecutableDirective>; def OMPFlushDirective : StmtNode<OMPExecutableDirective>; +def OMPDepobjDirective : StmtNode<OMPExecutableDirective>; +def OMPScanDirective : StmtNode<OMPExecutableDirective>; def OMPOrderedDirective : StmtNode<OMPExecutableDirective>; def OMPAtomicDirective : StmtNode<OMPExecutableDirective>; def OMPTargetDirective : StmtNode<OMPExecutableDirective>; diff --git a/clang/include/clang/Basic/TargetBuiltins.h b/clang/include/clang/Basic/TargetBuiltins.h index 0e2f0753b0c5..b472547012f0 100644 --- a/clang/include/clang/Basic/TargetBuiltins.h +++ b/clang/include/clang/Basic/TargetBuiltins.h @@ -15,8 +15,10 @@ #ifndef LLVM_CLANG_BASIC_TARGETBUILTINS_H #define LLVM_CLANG_BASIC_TARGETBUILTINS_H +#include <algorithm> #include <stdint.h> #include "clang/Basic/Builtins.h" +#include "llvm/Support/MathExtras.h" #undef PPC namespace clang { @@ -41,11 +43,22 @@ namespace clang { }; } + namespace SVE { + enum { + LastNEONBuiltin = NEON::FirstTSBuiltin - 1, +#define BUILTIN(ID, TYPE, ATTRS) BI##ID, +#include "clang/Basic/BuiltinsSVE.def" + FirstTSBuiltin, + }; + } + /// AArch64 builtins namespace AArch64 { enum { LastTIBuiltin = clang::Builtin::FirstTSBuiltin - 1, LastNEONBuiltin = NEON::FirstTSBuiltin - 1, + FirstSVEBuiltin = NEON::FirstTSBuiltin, + LastSVEBuiltin = SVE::FirstTSBuiltin - 1, #define BUILTIN(ID, TYPE, ATTRS) BI##ID, #include "clang/Basic/BuiltinsAArch64.def" LastTSBuiltin @@ -106,6 +119,11 @@ namespace clang { }; } + /// VE builtins + namespace VE { + enum { LastTIBuiltin = clang::Builtin::FirstTSBuiltin - 1, LastTSBuiltin }; + } + /// Flags to identify the types for overloaded Neon builtins. /// /// These must be kept in sync with the flags in utils/TableGen/NeonEmitter.h. @@ -129,7 +147,8 @@ namespace clang { Poly128, Float16, Float32, - Float64 + Float64, + BFloat16 }; NeonTypeFlags(unsigned F) : Flags(F) {} @@ -143,12 +162,104 @@ namespace clang { EltType getEltType() const { return (EltType)(Flags & EltTypeMask); } bool isPoly() const { EltType ET = getEltType(); - return ET == Poly8 || ET == Poly16; + return ET == Poly8 || ET == Poly16 || ET == Poly64; } bool isUnsigned() const { return (Flags & UnsignedFlag) != 0; } bool isQuad() const { return (Flags & QuadFlag) != 0; } }; + /// Flags to identify the types for overloaded SVE builtins. + class SVETypeFlags { + uint64_t Flags; + unsigned EltTypeShift; + unsigned MemEltTypeShift; + unsigned MergeTypeShift; + unsigned SplatOperandMaskShift; + + public: +#define LLVM_GET_SVE_TYPEFLAGS +#include "clang/Basic/arm_sve_typeflags.inc" +#undef LLVM_GET_SVE_TYPEFLAGS + + enum EltType { +#define LLVM_GET_SVE_ELTTYPES +#include "clang/Basic/arm_sve_typeflags.inc" +#undef LLVM_GET_SVE_ELTTYPES + }; + + enum MemEltType { +#define LLVM_GET_SVE_MEMELTTYPES +#include "clang/Basic/arm_sve_typeflags.inc" +#undef LLVM_GET_SVE_MEMELTTYPES + }; + + enum MergeType { +#define LLVM_GET_SVE_MERGETYPES +#include "clang/Basic/arm_sve_typeflags.inc" +#undef LLVM_GET_SVE_MERGETYPES + }; + + enum ImmCheckType { +#define LLVM_GET_SVE_IMMCHECKTYPES +#include "clang/Basic/arm_sve_typeflags.inc" +#undef LLVM_GET_SVE_IMMCHECKTYPES + }; + + SVETypeFlags(uint64_t F) : Flags(F) { + EltTypeShift = llvm::countTrailingZeros(EltTypeMask); + MemEltTypeShift = llvm::countTrailingZeros(MemEltTypeMask); + MergeTypeShift = llvm::countTrailingZeros(MergeTypeMask); + SplatOperandMaskShift = llvm::countTrailingZeros(SplatOperandMask); + } + + EltType getEltType() const { + return (EltType)((Flags & EltTypeMask) >> EltTypeShift); + } + + MemEltType getMemEltType() const { + return (MemEltType)((Flags & MemEltTypeMask) >> MemEltTypeShift); + } + + MergeType getMergeType() const { + return (MergeType)((Flags & MergeTypeMask) >> MergeTypeShift); + } + + unsigned getSplatOperand() const { + return ((Flags & SplatOperandMask) >> SplatOperandMaskShift) - 1; + } + + bool hasSplatOperand() const { + return Flags & SplatOperandMask; + } + + bool isLoad() const { return Flags & IsLoad; } + bool isStore() const { return Flags & IsStore; } + bool isGatherLoad() const { return Flags & IsGatherLoad; } + bool isScatterStore() const { return Flags & IsScatterStore; } + bool isStructLoad() const { return Flags & IsStructLoad; } + bool isStructStore() const { return Flags & IsStructStore; } + bool isZExtReturn() const { return Flags & IsZExtReturn; } + bool isByteIndexed() const { return Flags & IsByteIndexed; } + bool isOverloadNone() const { return Flags & IsOverloadNone; } + bool isOverloadWhile() const { return Flags & IsOverloadWhile; } + bool isOverloadDefault() const { return !(Flags & OverloadKindMask); } + bool isOverloadWhileRW() const { return Flags & IsOverloadWhileRW; } + bool isOverloadCvt() const { return Flags & IsOverloadCvt; } + bool isPrefetch() const { return Flags & IsPrefetch; } + bool isReverseCompare() const { return Flags & ReverseCompare; } + bool isAppendSVALL() const { return Flags & IsAppendSVALL; } + bool isInsertOp1SVALL() const { return Flags & IsInsertOp1SVALL; } + bool isGatherPrefetch() const { return Flags & IsGatherPrefetch; } + bool isReverseUSDOT() const { return Flags & ReverseUSDOT; } + bool isUndef() const { return Flags & IsUndef; } + bool isTupleCreate() const { return Flags & IsTupleCreate; } + bool isTupleGet() const { return Flags & IsTupleGet; } + bool isTupleSet() const { return Flags & IsTupleSet; } + + uint64_t getBits() const { return Flags; } + bool isFlagSet(uint64_t Flag) const { return Flags & Flag; } + }; + /// Hexagon builtins namespace Hexagon { enum { @@ -209,6 +320,14 @@ namespace clang { }; } + static constexpr uint64_t LargestBuiltinID = std::max<uint64_t>( + {NEON::FirstTSBuiltin, ARM::LastTSBuiltin, SVE::FirstTSBuiltin, + AArch64::LastTSBuiltin, BPF::LastTSBuiltin, PPC::LastTSBuiltin, + NVPTX::LastTSBuiltin, AMDGPU::LastTSBuiltin, X86::LastTSBuiltin, + Hexagon::LastTSBuiltin, Mips::LastTSBuiltin, XCore::LastTSBuiltin, + Le64::LastTSBuiltin, SystemZ::LastTSBuiltin, + WebAssembly::LastTSBuiltin}); + } // end namespace clang. #endif diff --git a/clang/include/clang/Basic/TargetCXXABI.h b/clang/include/clang/Basic/TargetCXXABI.h index 1ab45d2ce9a1..93f70fc70dd8 100644 --- a/clang/include/clang/Basic/TargetCXXABI.h +++ b/clang/include/clang/Basic/TargetCXXABI.h @@ -109,6 +109,13 @@ public: /// - constructors and destructors return 'this', as in ARM. Fuchsia, + /// The XL ABI is the ABI used by IBM xlclang compiler and is a modified + /// version of the Itanium ABI. + /// + /// The relevant changes from the Itanium ABI are: + /// - static initialization is adjusted to use sinit and sterm functions; + XL, + /// The Microsoft ABI is the ABI used by Microsoft Visual Studio (and /// compatible compilers). /// @@ -148,6 +155,7 @@ public: case WatchOS: case GenericMIPS: case WebAssembly: + case XL: return true; case Microsoft: @@ -168,6 +176,7 @@ public: case WatchOS: case GenericMIPS: case WebAssembly: + case XL: return false; case Microsoft: @@ -202,6 +211,7 @@ public: case iOS64: case WatchOS: case Microsoft: + case XL: return true; } llvm_unreachable("bad ABI kind"); @@ -278,6 +288,7 @@ public: case iOS: // old iOS compilers did not follow this rule case Microsoft: case GenericMIPS: + case XL: return true; } llvm_unreachable("bad ABI kind"); @@ -315,6 +326,7 @@ public: case GenericARM: case iOS: case GenericMIPS: + case XL: return UseTailPaddingUnlessPOD03; // iOS on ARM64 and WebAssembly use the C++11 POD rules. They do not honor diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h index 3a8e35524695..2ee3b1659630 100644 --- a/clang/include/clang/Basic/TargetInfo.h +++ b/clang/include/clang/Basic/TargetInfo.h @@ -15,8 +15,9 @@ #define LLVM_CLANG_BASIC_TARGETINFO_H #include "clang/Basic/AddressSpaces.h" -#include "clang/Basic/LLVM.h" #include "clang/Basic/CodeGenOptions.h" +#include "clang/Basic/LLVM.h" +#include "clang/Basic/LangOptions.h" #include "clang/Basic/Specifiers.h" #include "clang/Basic/TargetCXXABI.h" #include "clang/Basic/TargetOptions.h" @@ -29,6 +30,7 @@ #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/Triple.h" +#include "llvm/Frontend/OpenMP/OMPGridValues.h" #include "llvm/Support/DataTypes.h" #include "llvm/Support/VersionTuple.h" #include <cassert> @@ -59,6 +61,7 @@ struct TransferrableTargetInfo { unsigned char BoolWidth, BoolAlign; unsigned char IntWidth, IntAlign; unsigned char HalfWidth, HalfAlign; + unsigned char BFloat16Width, BFloat16Align; unsigned char FloatWidth, FloatAlign; unsigned char DoubleWidth, DoubleAlign; unsigned char LongDoubleWidth, LongDoubleAlign, Float128Align; @@ -100,8 +103,8 @@ struct TransferrableTargetInfo { unsigned short MaxVectorAlign; unsigned short MaxTLSAlign; - const llvm::fltSemantics *HalfFormat, *FloatFormat, *DoubleFormat, - *LongDoubleFormat, *Float128Format; + const llvm::fltSemantics *HalfFormat, *BFloat16Format, *FloatFormat, + *DoubleFormat, *LongDoubleFormat, *Float128Format; ///===---- Target Data Type Query Methods -------------------------------===// enum IntType { @@ -159,6 +162,18 @@ protected: unsigned ZeroLengthBitfieldBoundary; }; +/// OpenCL type kinds. +enum OpenCLTypeKind : uint8_t { + OCLTK_Default, + OCLTK_ClkEvent, + OCLTK_Event, + OCLTK_Image, + OCLTK_Pipe, + OCLTK_Queue, + OCLTK_ReserveID, + OCLTK_Sampler, +}; + /// Exposes information about the current target. /// class TargetInfo : public virtual TransferrableTargetInfo, @@ -176,6 +191,8 @@ protected: // LLVM IR type. bool HasFloat128; bool HasFloat16; + bool HasBFloat16; + bool HasStrictFP; unsigned char MaxAtomicPromoteWidth, MaxAtomicInlineWidth; unsigned short SimdDefaultAlign; @@ -184,6 +201,9 @@ protected: unsigned char RegParmMax, SSERegParmMax; TargetCXXABI TheCXXABI; const LangASMap *AddrSpaceMap; + const unsigned *GridValues = + nullptr; // Array of target-specific GPU grid values that must be + // consistent between host RTL (plugin), device RTL, and clang. mutable StringRef PlatformName; mutable VersionTuple PlatformMinVersion; @@ -198,6 +218,10 @@ protected: unsigned HasAArch64SVETypes : 1; + unsigned ARMCDECoprocMask : 8; + + unsigned MaxOpenCLWorkGroupSize; + // TargetInfo Constructor. Default initializes all fields. TargetInfo(const llvm::Triple &T); @@ -259,7 +283,14 @@ public: // void *__overflow_arg_area; // void *__reg_save_area; // } va_list[1]; - SystemZBuiltinVaList + SystemZBuiltinVaList, + + // typedef struct __va_list_tag { + // void *__current_saved_reg_area_pointer; + // void *__saved_reg_area_end_pointer; + // void *__overflow_area_pointer; + //} va_list; + HexagonBuiltinVaList }; protected: @@ -345,8 +376,13 @@ public: virtual IntType getLeastIntTypeByWidth(unsigned BitWidth, bool IsSigned) const; - /// Return floating point type with specified width. - RealType getRealTypeByWidth(unsigned BitWidth) const; + /// Return floating point type with specified width. On PPC, there are + /// three possible types for 128-bit floating point: "PPC double-double", + /// IEEE 754R quad precision, and "long double" (which under the covers + /// is represented as one of those two). At this time, there is no support + /// for an explicit "PPC double-double" type (i.e. __ibm128) so we only + /// need to differentiate between "long double" and IEEE quad precision. + RealType getRealTypeByWidth(unsigned BitWidth, bool ExplicitIEEE) const; /// Return the alignment (in bits) of the specified integer type enum. /// @@ -524,6 +560,12 @@ public: return (getPointerWidth(0) >= 64) || getTargetOpts().ForceEnableInt128; } // FIXME + /// Determine whether the _ExtInt type is supported on this target. This + /// limitation is put into place for ABI reasons. + virtual bool hasExtIntType() const { + return false; + } + /// Determine whether _Float16 is supported on this target. virtual bool hasLegalHalfType() const { return HasLegalHalfType; } @@ -533,6 +575,12 @@ public: /// Determine whether the _Float16 type is supported on this target. virtual bool hasFloat16Type() const { return HasFloat16; } + /// Determine whether the _BFloat16 type is supported on this target. + virtual bool hasBFloat16Type() const { return HasBFloat16; } + + /// Determine whether constrained floating point is supported on this target. + virtual bool hasStrictFP() const { return HasStrictFP; } + /// Return the alignment that is suitable for storing any /// object with a fundamental alignment requirement. unsigned getSuitableAlign() const { return SuitableAlign; } @@ -581,6 +629,11 @@ public: unsigned getFloatAlign() const { return FloatAlign; } const llvm::fltSemantics &getFloatFormat() const { return *FloatFormat; } + /// getBFloat16Width/Align/Format - Return the size/align/format of '__bf16'. + unsigned getBFloat16Width() const { return BFloat16Width; } + unsigned getBFloat16Align() const { return BFloat16Align; } + const llvm::fltSemantics &getBFloat16Format() const { return *BFloat16Format; } + /// getDoubleWidth/Align/Format - Return the size/align/format of 'double'. unsigned getDoubleWidth() const { return DoubleWidth; } unsigned getDoubleAlign() const { return DoubleAlign; } @@ -608,6 +661,11 @@ public: /// Return the mangled code of __float128. virtual const char *getFloat128Mangling() const { return "g"; } + /// Return the mangled code of bfloat. + virtual const char *getBFloat16Mangling() const { + llvm_unreachable("bfloat not implemented on this target"); + } + /// Return the value for the C99 FLT_EVAL_METHOD macro. virtual unsigned getFloatEvalMethod() const { return 0; } @@ -642,6 +700,8 @@ public: /// types for the given target. unsigned getSimdDefaultAlign() const { return SimdDefaultAlign; } + unsigned getMaxOpenCLWorkGroupSize() const { return MaxOpenCLWorkGroupSize; } + /// Return the alignment (in bits) of the thrown exception object. This is /// only meaningful for targets that allocate C++ exceptions in a system /// runtime, such as those using the Itanium C++ ABI. @@ -796,6 +856,10 @@ public: /// available on this target. bool hasAArch64SVETypes() const { return HasAArch64SVETypes; } + /// For ARM targets returns a mask defining which coprocessors are configured + /// as Custom Datapath. + uint32_t getARMCDECoprocMask() const { return ARMCDECoprocMask; } + /// Returns whether the passed in string is a valid clobber in an /// inline asm statement. /// @@ -816,6 +880,8 @@ public: StringRef getNormalizedGCCRegisterName(StringRef Name, bool ReturnCanonical = false) const; + virtual bool isSPRegName(StringRef) const { return false; } + /// Extracts a register from the passed constraint (if it is a /// single-register constraint) and the asm label expression related to a /// variable in the input or output list of an inline asm statement. @@ -1107,10 +1173,10 @@ public: } struct BranchProtectionInfo { - CodeGenOptions::SignReturnAddressScope SignReturnAddr = - CodeGenOptions::SignReturnAddressScope::None; - CodeGenOptions::SignReturnAddressKeyValue SignKey = - CodeGenOptions::SignReturnAddressKeyValue::AKey; + LangOptions::SignReturnAddressScopeKind SignReturnAddr = + LangOptions::SignReturnAddressScopeKind::None; + LangOptions::SignReturnAddressKeyKind SignKey = + LangOptions::SignReturnAddressKeyKind::AKey; bool BranchTargetEnforcement = false; }; @@ -1186,6 +1252,10 @@ public: "cpu_specific Multiversioning not implemented on this target"); } + // Get the cache line size of a given cpu. This method switches over + // the given cpu and returns "None" if the CPU is not found. + virtual Optional<unsigned> getCPUCacheLineSize() const { return None; } + // Returns maximal number of args passed in registers. unsigned getRegParmMax() const { assert(RegParmMax < 7 && "RegParmMax value is larger than AST can handle"); @@ -1260,6 +1330,12 @@ public: return LangAS::Default; } + /// Return a target-specific GPU grid value based on the GVIDX enum \p gv + unsigned getGridValue(llvm::omp::GVIDX gv) const { + assert(GridValues != nullptr && "GridValues not initialized"); + return GridValues[gv]; + } + /// Retrieve the name of the platform as it is used in the /// availability attribute. StringRef getPlatformName() const { return PlatformName; } @@ -1345,17 +1421,6 @@ public: return getTargetOpts().SupportedOpenCLOptions; } - enum OpenCLTypeKind { - OCLTK_Default, - OCLTK_ClkEvent, - OCLTK_Event, - OCLTK_Image, - OCLTK_Pipe, - OCLTK_Queue, - OCLTK_ReserveID, - OCLTK_Sampler, - }; - /// Get address space for OpenCL type. virtual LangAS getOpenCLTypeAddrSpace(OpenCLTypeKind TK) const; diff --git a/clang/include/clang/Basic/TokenKinds.def b/clang/include/clang/Basic/TokenKinds.def index d58b0d987d71..2b353269ed52 100644 --- a/clang/include/clang/Basic/TokenKinds.def +++ b/clang/include/clang/Basic/TokenKinds.def @@ -26,14 +26,14 @@ #ifndef CXX11_KEYWORD #define CXX11_KEYWORD(X,Y) KEYWORD(X,KEYCXX11|(Y)) #endif -#ifndef CXX2A_KEYWORD -#define CXX2A_KEYWORD(X,Y) KEYWORD(X,KEYCXX2A|(Y)) +#ifndef CXX20_KEYWORD +#define CXX20_KEYWORD(X,Y) KEYWORD(X,KEYCXX20|(Y)) #endif #ifndef CONCEPTS_KEYWORD -#define CONCEPTS_KEYWORD(X) CXX2A_KEYWORD(X,KEYCONCEPTS) +#define CONCEPTS_KEYWORD(X) CXX20_KEYWORD(X,KEYCONCEPTS) #endif #ifndef COROUTINES_KEYWORD -#define COROUTINES_KEYWORD(X) CXX2A_KEYWORD(X,KEYCOROUTINES) +#define COROUTINES_KEYWORD(X) CXX20_KEYWORD(X,KEYCOROUTINES) #endif #ifndef MODULES_KEYWORD #define MODULES_KEYWORD(X) KEYWORD(X,KEYMODULES) @@ -50,6 +50,18 @@ #ifndef TYPE_TRAIT_N #define TYPE_TRAIT_N(I,E,K) TYPE_TRAIT(0,I,K) #endif +#ifndef ARRAY_TYPE_TRAIT +#define ARRAY_TYPE_TRAIT(I,E,K) KEYWORD(I,K) +#endif +#ifndef UNARY_EXPR_OR_TYPE_TRAIT +#define UNARY_EXPR_OR_TYPE_TRAIT(I,E,K) KEYWORD(I,K) +#endif +#ifndef CXX11_UNARY_EXPR_OR_TYPE_TRAIT +#define CXX11_UNARY_EXPR_OR_TYPE_TRAIT(I,E,K) CXX11_KEYWORD(I,K) +#endif +#ifndef EXPRESSION_TRAIT +#define EXPRESSION_TRAIT(I,E,K) KEYWORD(I,K) +#endif #ifndef ALIAS #define ALIAS(X,Y,Z) #endif @@ -244,7 +256,7 @@ PUNCTUATOR(caretcaret, "^^") // implementation namespace // KEYNOCXX - This is a keyword in every non-C++ dialect. // KEYCXX11 - This is a C++ keyword introduced to C++ in C++11 -// KEYCXX2A - This is a C++ keyword introduced to C++ in C++2a +// KEYCXX20 - This is a C++ keyword introduced to C++ in C++20 // KEYCONCEPTS - This is a keyword if the C++ extensions for concepts // are enabled. // KEYMODULES - This is a keyword if the C++ extensions for modules @@ -285,13 +297,14 @@ KEYWORD(goto , KEYALL) KEYWORD(if , KEYALL) KEYWORD(inline , KEYC99|KEYCXX|KEYGNU) KEYWORD(int , KEYALL) +KEYWORD(_ExtInt , KEYALL) KEYWORD(long , KEYALL) KEYWORD(register , KEYALL) KEYWORD(restrict , KEYC99) KEYWORD(return , KEYALL) KEYWORD(short , KEYALL) KEYWORD(signed , KEYALL) -KEYWORD(sizeof , KEYALL) +UNARY_EXPR_OR_TYPE_TRAIT(sizeof, SizeOf, KEYALL) KEYWORD(static , KEYALL) KEYWORD(struct , KEYALL) KEYWORD(switch , KEYALL) @@ -363,7 +376,8 @@ CXX_KEYWORD_OPERATOR(xor_eq , caretequal) // C++11 keywords CXX11_KEYWORD(alignas , 0) -CXX11_KEYWORD(alignof , 0) +// alignof and _Alignof return the required ABI alignment +CXX11_UNARY_EXPR_OR_TYPE_TRAIT(alignof, AlignOf, 0) CXX11_KEYWORD(char16_t , KEYNOMS18) CXX11_KEYWORD(char32_t , KEYNOMS18) CXX11_KEYWORD(constexpr , 0) @@ -373,11 +387,11 @@ CXX11_KEYWORD(nullptr , 0) CXX11_KEYWORD(static_assert , KEYMSCOMPAT) CXX11_KEYWORD(thread_local , 0) -// C++2a / concepts TS keywords +// C++20 keywords CONCEPTS_KEYWORD(concept) CONCEPTS_KEYWORD(requires) -// C++2a / coroutines TS keywords +// C++20 / coroutines TS keywords COROUTINES_KEYWORD(co_await) COROUTINES_KEYWORD(co_return) COROUTINES_KEYWORD(co_yield) @@ -387,9 +401,10 @@ MODULES_KEYWORD(module) MODULES_KEYWORD(import) // C++20 keywords. -CXX2A_KEYWORD(char8_t , CHAR8SUPPORT) -CXX2A_KEYWORD(consteval , 0) -CXX2A_KEYWORD(constinit , 0) +CXX20_KEYWORD(consteval , 0) +CXX20_KEYWORD(constinit , 0) +// Not a CXX20_KEYWORD because it is disabled by -fno-char8_t. +KEYWORD(char8_t , CHAR8SUPPORT) // C11 Extension KEYWORD(_Float16 , KEYALL) @@ -404,7 +419,9 @@ KEYWORD(_Decimal32 , KEYALL) KEYWORD(_Decimal64 , KEYALL) KEYWORD(_Decimal128 , KEYALL) KEYWORD(__null , KEYCXX) -KEYWORD(__alignof , KEYALL) +// __alignof returns the preferred alignment of a type, the alignment +// clang will attempt to give an object of the type if allowed by ABI. +UNARY_EXPR_OR_TYPE_TRAIT(__alignof, PreferredAlignOf, KEYALL) KEYWORD(__attribute , KEYALL) KEYWORD(__builtin_choose_expr , KEYALL) KEYWORD(__builtin_offsetof , KEYALL) @@ -492,8 +509,8 @@ KEYWORD(__underlying_type , KEYCXX) TYPE_TRAIT_2(__reference_binds_to_temporary, ReferenceBindsToTemporary, KEYCXX) // Embarcadero Expression Traits -KEYWORD(__is_lvalue_expr , KEYCXX) -KEYWORD(__is_rvalue_expr , KEYCXX) +EXPRESSION_TRAIT(__is_lvalue_expr, IsLValueExpr, KEYCXX) +EXPRESSION_TRAIT(__is_rvalue_expr, IsRValueExpr, KEYCXX) // Embarcadero Unary Type Traits TYPE_TRAIT_1(__is_arithmetic, IsArithmetic, KEYCXX) @@ -522,8 +539,8 @@ TYPE_TRAIT_1(__is_unsigned, IsUnsigned, KEYCXX) // Embarcadero Binary Type Traits TYPE_TRAIT_2(__is_same, IsSame, KEYCXX) TYPE_TRAIT_2(__is_convertible, IsConvertible, KEYCXX) -KEYWORD(__array_rank , KEYCXX) -KEYWORD(__array_extent , KEYCXX) +ARRAY_TYPE_TRAIT(__array_rank, ArrayRank, KEYCXX) +ARRAY_TYPE_TRAIT(__array_extent, ArrayExtent, KEYCXX) // Name for GCC 6 compatibility. ALIAS("__is_same_as", __is_same, KEYCXX) @@ -569,14 +586,15 @@ ALIAS("write_only", __write_only , KEYOPENCLC | KEYOPENCLCXX) ALIAS("read_write", __read_write , KEYOPENCLC | KEYOPENCLCXX) // OpenCL builtins KEYWORD(__builtin_astype , KEYOPENCLC | KEYOPENCLCXX) -KEYWORD(vec_step , KEYOPENCLC | KEYALTIVEC | KEYZVECTOR) +UNARY_EXPR_OR_TYPE_TRAIT(vec_step, VecStep, KEYOPENCLC | KEYALTIVEC | KEYZVECTOR) #define GENERIC_IMAGE_TYPE(ImgType, Id) KEYWORD(ImgType##_t, KEYOPENCLC | KEYOPENCLCXX) #include "clang/Basic/OpenCLImageTypes.def" +KEYWORD(pipe , KEYOPENCLC | KEYOPENCLCXX) +// C++ for OpenCL s2.3.1: addrspace_cast operator +KEYWORD(addrspace_cast , KEYOPENCLCXX) // OpenMP Type Traits -KEYWORD(__builtin_omp_required_simd_align, KEYALL) - -KEYWORD(pipe , KEYOPENCLC | KEYOPENCLCXX) +UNARY_EXPR_OR_TYPE_TRAIT(__builtin_omp_required_simd_align, OpenMPRequiredSimdAlign, KEYALL) // Borland Extensions. KEYWORD(__pascal , KEYALL) @@ -588,6 +606,7 @@ KEYWORD(__bool , KEYALTIVEC|KEYZVECTOR) // ARM NEON extensions. ALIAS("__fp16", half , KEYALL) +KEYWORD(__bf16 , KEYALL) // OpenCL Extension. KEYWORD(half , HALFSUPPORT) @@ -674,11 +693,12 @@ ALIAS("_declspec" , __declspec , KEYMS) ALIAS("_pascal" , __pascal , KEYBORLAND) // Clang Extensions. -KEYWORD(__builtin_convertvector , KEYALL) -ALIAS("__char16_t" , char16_t , KEYCXX) -ALIAS("__char32_t" , char32_t , KEYCXX) -KEYWORD(__builtin_bit_cast , KEYALL) -KEYWORD(__builtin_available , KEYALL) +KEYWORD(__builtin_convertvector , KEYALL) +ALIAS("__char16_t" , char16_t , KEYCXX) +ALIAS("__char32_t" , char32_t , KEYCXX) +KEYWORD(__builtin_bit_cast , KEYALL) +KEYWORD(__builtin_available , KEYALL) +KEYWORD(__builtin_unique_stable_name, KEYALL) // Clang-specific keywords enabled only in testing. TESTING_KEYWORD(__unknown_anytype , KEYALL) @@ -738,6 +758,9 @@ ANNOTATION(non_type_undeclared) // annotation for an undeclared identifier that ANNOTATION(non_type_dependent) // annotation for an assumed non-type member of // a dependent base class ANNOTATION(primary_expr) // annotation for a primary expression +ANNOTATION( + uneval_primary_expr) // annotation for a primary expression which should be + // transformed to potentially evaluated ANNOTATION(decltype) // annotation for a decltype expression, // e.g., "decltype(foo.bar())" @@ -806,6 +829,11 @@ PRAGMA_ANNOTATION(pragma_fp_contract) // handles them. PRAGMA_ANNOTATION(pragma_fenv_access) +// Annotation for #pragma float_control +// The lexer produces these so that they only take effect when the parser +// handles them. +PRAGMA_ANNOTATION(pragma_float_control) + // Annotation for #pragma pointers_to_members... // The lexer produces these so that they only take effect when the parser // handles them. @@ -858,12 +886,16 @@ ANNOTATION(header_unit) #undef CXX_KEYWORD_OPERATOR #undef PPKEYWORD #undef ALIAS +#undef EXPRESSION_TRAIT +#undef CXX11_UNARY_EXPR_OR_TYPE_TRAIT +#undef UNARY_EXPR_OR_TYPE_TRAIT +#undef ARRAY_TYPE_TRAIT #undef TYPE_TRAIT_N #undef TYPE_TRAIT_2 #undef TYPE_TRAIT_1 #undef TYPE_TRAIT #undef CONCEPTS_KEYWORD -#undef CXX2A_KEYWORD +#undef CXX20_KEYWORD #undef CXX11_KEYWORD #undef KEYWORD #undef PUNCTUATOR diff --git a/clang/include/clang/Basic/TokenKinds.h b/clang/include/clang/Basic/TokenKinds.h index c25181e6827c..4e66aa1c8c2d 100644 --- a/clang/include/clang/Basic/TokenKinds.h +++ b/clang/include/clang/Basic/TokenKinds.h @@ -14,6 +14,7 @@ #ifndef LLVM_CLANG_BASIC_TOKENKINDS_H #define LLVM_CLANG_BASIC_TOKENKINDS_H +#include "llvm/ADT/DenseMapInfo.h" #include "llvm/Support/Compiler.h" namespace clang { @@ -95,7 +96,25 @@ bool isAnnotation(TokenKind K); /// Return true if this is an annotation token representing a pragma. bool isPragmaAnnotation(TokenKind K); -} // end namespace tok -} // end namespace clang +} // end namespace tok +} // end namespace clang + +namespace llvm { +template <> struct DenseMapInfo<clang::tok::PPKeywordKind> { + static inline clang::tok::PPKeywordKind getEmptyKey() { + return clang::tok::PPKeywordKind::pp_not_keyword; + } + static inline clang::tok::PPKeywordKind getTombstoneKey() { + return clang::tok::PPKeywordKind::NUM_PP_KEYWORDS; + } + static unsigned getHashValue(const clang::tok::PPKeywordKind &Val) { + return static_cast<unsigned>(Val); + } + static bool isEqual(const clang::tok::PPKeywordKind &LHS, + const clang::tok::PPKeywordKind &RHS) { + return LHS == RHS; + } +}; +} // namespace llvm #endif diff --git a/clang/include/clang/Basic/TypeNodes.td b/clang/include/clang/Basic/TypeNodes.td index 96d9472a488a..a4e3002b9075 100644 --- a/clang/include/clang/Basic/TypeNodes.td +++ b/clang/include/clang/Basic/TypeNodes.td @@ -69,6 +69,9 @@ def DependentAddressSpaceType : TypeNode<Type>, AlwaysDependent; def VectorType : TypeNode<Type>; def DependentVectorType : TypeNode<Type>, AlwaysDependent; def ExtVectorType : TypeNode<VectorType>; +def MatrixType : TypeNode<Type, 1>; +def ConstantMatrixType : TypeNode<MatrixType>; +def DependentSizedMatrixType : TypeNode<MatrixType>, AlwaysDependent; def FunctionType : TypeNode<Type, 1>; def FunctionProtoType : TypeNode<FunctionType>; def FunctionNoProtoType : TypeNode<FunctionType>; @@ -104,3 +107,5 @@ def ObjCInterfaceType : TypeNode<ObjCObjectType>, LeafType; def ObjCObjectPointerType : TypeNode<Type>; def PipeType : TypeNode<Type>; def AtomicType : TypeNode<Type>; +def ExtIntType : TypeNode<Type>; +def DependentExtIntType : TypeNode<Type>, AlwaysDependent; diff --git a/clang/include/clang/Basic/TypeTraits.h b/clang/include/clang/Basic/TypeTraits.h index 7c1b571f640c..a0f06bec6697 100644 --- a/clang/include/clang/Basic/TypeTraits.h +++ b/clang/include/clang/Basic/TypeTraits.h @@ -14,97 +14,59 @@ #ifndef LLVM_CLANG_BASIC_TYPETRAITS_H #define LLVM_CLANG_BASIC_TYPETRAITS_H +#include "llvm/Support/Compiler.h" + namespace clang { +/// Names for traits that operate specifically on types. +enum TypeTrait { +#define TYPE_TRAIT_1(Spelling, Name, Key) UTT_##Name, +#include "clang/Basic/TokenKinds.def" + UTT_Last = -1 // UTT_Last == last UTT_XX in the enum. +#define TYPE_TRAIT_1(Spelling, Name, Key) +1 +#include "clang/Basic/TokenKinds.def" + , +#define TYPE_TRAIT_2(Spelling, Name, Key) BTT_##Name, +#include "clang/Basic/TokenKinds.def" + BTT_Last = UTT_Last // BTT_Last == last BTT_XX in the enum. +#define TYPE_TRAIT_2(Spelling, Name, Key) +1 +#include "clang/Basic/TokenKinds.def" + , +#define TYPE_TRAIT_N(Spelling, Name, Key) TT_##Name, +#include "clang/Basic/TokenKinds.def" + TT_Last = BTT_Last // TT_Last == last TT_XX in the enum. +#define TYPE_TRAIT_N(Spelling, Name, Key) +1 +#include "clang/Basic/TokenKinds.def" +}; + +/// Names for the array type traits. +enum ArrayTypeTrait { +#define ARRAY_TYPE_TRAIT(Spelling, Name, Key) ATT_##Name, +#include "clang/Basic/TokenKinds.def" + ATT_Last = -1 // ATT_Last == last ATT_XX in the enum. +#define ARRAY_TYPE_TRAIT(Spelling, Name, Key) +1 +#include "clang/Basic/TokenKinds.def" +}; - /// Names for traits that operate specifically on types. - enum TypeTrait { - UTT_HasNothrowAssign, - UTT_HasNothrowMoveAssign, - UTT_HasNothrowCopy, - UTT_HasNothrowConstructor, - UTT_HasTrivialAssign, - UTT_HasTrivialMoveAssign, - UTT_HasTrivialCopy, - UTT_HasTrivialDefaultConstructor, - UTT_HasTrivialMoveConstructor, - UTT_HasTrivialDestructor, - UTT_HasVirtualDestructor, - UTT_IsAbstract, - UTT_IsAggregate, - UTT_IsArithmetic, - UTT_IsArray, - UTT_IsClass, - UTT_IsCompleteType, - UTT_IsCompound, - UTT_IsConst, - UTT_IsDestructible, - UTT_IsEmpty, - UTT_IsEnum, - UTT_IsFinal, - UTT_IsFloatingPoint, - UTT_IsFunction, - UTT_IsFundamental, - UTT_IsIntegral, - UTT_IsInterfaceClass, - UTT_IsLiteral, - UTT_IsLvalueReference, - UTT_IsMemberFunctionPointer, - UTT_IsMemberObjectPointer, - UTT_IsMemberPointer, - UTT_IsNothrowDestructible, - UTT_IsObject, - UTT_IsPOD, - UTT_IsPointer, - UTT_IsPolymorphic, - UTT_IsReference, - UTT_IsRvalueReference, - UTT_IsScalar, - UTT_IsSealed, - UTT_IsSigned, - UTT_IsStandardLayout, - UTT_IsTrivial, - UTT_IsTriviallyCopyable, - UTT_IsTriviallyDestructible, - UTT_IsUnion, - UTT_IsUnsigned, - UTT_IsVoid, - UTT_IsVolatile, - UTT_HasUniqueObjectRepresentations, - UTT_Last = UTT_HasUniqueObjectRepresentations, - BTT_IsBaseOf, - BTT_IsConvertible, - BTT_IsConvertibleTo, - BTT_IsSame, - BTT_TypeCompatible, - BTT_IsAssignable, - BTT_IsNothrowAssignable, - BTT_IsTriviallyAssignable, - BTT_ReferenceBindsToTemporary, - BTT_Last = BTT_ReferenceBindsToTemporary, - TT_IsConstructible, - TT_IsNothrowConstructible, - TT_IsTriviallyConstructible - }; +/// Names for the "expression or type" traits. +enum UnaryExprOrTypeTrait { +#define UNARY_EXPR_OR_TYPE_TRAIT(Spelling, Name, Key) UETT_##Name, +#define CXX11_UNARY_EXPR_OR_TYPE_TRAIT(Spelling, Name, Key) UETT_##Name, +#include "clang/Basic/TokenKinds.def" + UETT_Last = -1 // UETT_Last == last UETT_XX in the enum. +#define UNARY_EXPR_OR_TYPE_TRAIT(Spelling, Name, Key) +1 +#define CXX11_UNARY_EXPR_OR_TYPE_TRAIT(Spelling, Name, Key) +1 +#include "clang/Basic/TokenKinds.def" +}; - /// Names for the array type traits. - enum ArrayTypeTrait { - ATT_ArrayRank, - ATT_ArrayExtent - }; +/// Return the internal name of type trait \p T. Never null. +const char *getTraitName(TypeTrait T) LLVM_READONLY; +const char *getTraitName(ArrayTypeTrait T) LLVM_READONLY; +const char *getTraitName(UnaryExprOrTypeTrait T) LLVM_READONLY; - /// Names for the "expression or type" traits. - enum UnaryExprOrTypeTrait { - UETT_SizeOf, - /// Used for C's _Alignof and C++'s alignof. - /// _Alignof and alignof return the required ABI alignment. - UETT_AlignOf, - UETT_VecStep, - UETT_OpenMPRequiredSimdAlign, - /// Used for GCC's __alignof. - /// __alignof returns the preferred alignment of a type, the alignment - /// clang will attempt to give an object of the type if allowed by ABI. - UETT_PreferredAlignOf, - }; -} +/// Return the spelling of the type trait \p TT. Never null. +const char *getTraitSpelling(TypeTrait T) LLVM_READONLY; +const char *getTraitSpelling(ArrayTypeTrait T) LLVM_READONLY; +const char *getTraitSpelling(UnaryExprOrTypeTrait T) LLVM_READONLY; +} // namespace clang #endif diff --git a/clang/include/clang/Basic/X86Target.def b/clang/include/clang/Basic/X86Target.def index ba4e5981e7dc..70f3879f33a1 100644 --- a/clang/include/clang/Basic/X86Target.def +++ b/clang/include/clang/Basic/X86Target.def @@ -11,19 +11,6 @@ // //===----------------------------------------------------------------------===// -#ifndef PROC_WITH_FEAT -#define PROC_WITH_FEAT(ENUM, STRING, IS64BIT, KEYFEATURE) \ - PROC(ENUM, STRING, IS64BIT) -#endif - -#ifndef PROC -#define PROC(ENUM, STRING, IS64BIT) -#endif - -#ifndef PROC_ALIAS -#define PROC_ALIAS(ENUM, ALIAS) -#endif - #ifndef FEATURE #define FEATURE(ENUM) #endif @@ -36,230 +23,6 @@ #define CPU_SPECIFIC_ALIAS(NEW_NAME, NAME) #endif -#define PROC_64_BIT true -#define PROC_32_BIT false - -/// \name i386 -/// i386-generation processors. -//@{ -PROC(i386, "i386", PROC_32_BIT) -//@} - -/// \name i486 -/// i486-generation processors. -//@{ -PROC(i486, "i486", PROC_32_BIT) -PROC(WinChipC6, "winchip-c6", PROC_32_BIT) -PROC(WinChip2, "winchip2", PROC_32_BIT) -PROC(C3, "c3", PROC_32_BIT) -//@} - -/// \name i586 -/// i586-generation processors, P5 microarchitecture based. -//@{ -PROC(i586, "i586", PROC_32_BIT) -PROC(Pentium, "pentium", PROC_32_BIT) -PROC(PentiumMMX, "pentium-mmx", PROC_32_BIT) -//@} - -/// \name i686 -/// i686-generation processors, P6 / Pentium M microarchitecture based. -//@{ -PROC(PentiumPro, "pentiumpro", PROC_32_BIT) -PROC(i686, "i686", PROC_32_BIT) -PROC(Pentium2, "pentium2", PROC_32_BIT) -PROC(Pentium3, "pentium3", PROC_32_BIT) -PROC_ALIAS(Pentium3, "pentium3m") -PROC(PentiumM, "pentium-m", PROC_32_BIT) -PROC(C3_2, "c3-2", PROC_32_BIT) - -/// This enumerator is a bit odd, as GCC no longer accepts -march=yonah. -/// Clang however has some logic to support this. -// FIXME: Warn, deprecate, and potentially remove this. -PROC(Yonah, "yonah", PROC_32_BIT) -//@} - -/// \name Netburst -/// Netburst microarchitecture based processors. -//@{ -PROC(Pentium4, "pentium4", PROC_32_BIT) -PROC_ALIAS(Pentium4, "pentium4m") - -PROC(Prescott, "prescott", PROC_32_BIT) -PROC(Nocona, "nocona", PROC_64_BIT) -//@} - -/// \name Core -/// Core microarchitecture based processors. -//@{ -PROC_WITH_FEAT(Core2, "core2", PROC_64_BIT, FEATURE_SSSE3) - -/// This enumerator, like Yonah, is a bit odd. It is another -/// codename which GCC no longer accepts as an option to -march, but Clang -/// has some logic for recognizing it. -// FIXME: Warn, deprecate, and potentially remove this. -PROC(Penryn, "penryn", PROC_64_BIT) -//@} - -/// \name Atom -/// Atom processors -//@{ -PROC_WITH_FEAT(Bonnell, "bonnell", PROC_64_BIT, FEATURE_SSSE3) -PROC_ALIAS(Bonnell, "atom") - -PROC_WITH_FEAT(Silvermont, "silvermont", PROC_64_BIT, FEATURE_SSE4_2) -PROC_ALIAS(Silvermont, "slm") - -PROC(Goldmont, "goldmont", PROC_64_BIT) -PROC(GoldmontPlus, "goldmont-plus", PROC_64_BIT) - -PROC(Tremont, "tremont", PROC_64_BIT) -//@} - -/// \name Nehalem -/// Nehalem microarchitecture based processors. -PROC_WITH_FEAT(Nehalem, "nehalem", PROC_64_BIT, FEATURE_SSE4_2) -PROC_ALIAS(Nehalem, "corei7") - -/// \name Westmere -/// Westmere microarchitecture based processors. -PROC_WITH_FEAT(Westmere, "westmere", PROC_64_BIT, FEATURE_PCLMUL) - -/// \name Sandy Bridge -/// Sandy Bridge microarchitecture based processors. -PROC_WITH_FEAT(SandyBridge, "sandybridge", PROC_64_BIT, FEATURE_AVX) -PROC_ALIAS(SandyBridge, "corei7-avx") - -/// \name Ivy Bridge -/// Ivy Bridge microarchitecture based processors. -PROC_WITH_FEAT(IvyBridge, "ivybridge", PROC_64_BIT, FEATURE_AVX) -PROC_ALIAS(IvyBridge, "core-avx-i") - -/// \name Haswell -/// Haswell microarchitecture based processors. -PROC_WITH_FEAT(Haswell, "haswell", PROC_64_BIT, FEATURE_AVX2) -PROC_ALIAS(Haswell, "core-avx2") - -/// \name Broadwell -/// Broadwell microarchitecture based processors. -PROC_WITH_FEAT(Broadwell, "broadwell", PROC_64_BIT, FEATURE_AVX2) - -/// \name Skylake Client -/// Skylake client microarchitecture based processors. -PROC_WITH_FEAT(SkylakeClient, "skylake", PROC_64_BIT, FEATURE_AVX2) - -/// \name Skylake Server -/// Skylake server microarchitecture based processors. -PROC_WITH_FEAT(SkylakeServer, "skylake-avx512", PROC_64_BIT, FEATURE_AVX512F) -PROC_ALIAS(SkylakeServer, "skx") - -/// \name Cascadelake Server -/// Cascadelake Server microarchitecture based processors. -PROC_WITH_FEAT(Cascadelake, "cascadelake", PROC_64_BIT, FEATURE_AVX512VNNI) - -/// \name Cooperlake Server -/// Cooperlake Server microarchitecture based processors. -PROC_WITH_FEAT(Cooperlake, "cooperlake", PROC_64_BIT, FEATURE_AVX512BF16) - -/// \name Cannonlake Client -/// Cannonlake client microarchitecture based processors. -PROC_WITH_FEAT(Cannonlake, "cannonlake", PROC_64_BIT, FEATURE_AVX512VBMI) - -/// \name Icelake Client -/// Icelake client microarchitecture based processors. -PROC(IcelakeClient, "icelake-client", PROC_64_BIT) - -/// \name Icelake Server -/// Icelake server microarchitecture based processors. -PROC(IcelakeServer, "icelake-server", PROC_64_BIT) - -/// \name Tigerlake -/// Tigerlake microarchitecture based processors. -PROC(Tigerlake, "tigerlake", PROC_64_BIT) - -/// \name Knights Landing -/// Knights Landing processor. -PROC_WITH_FEAT(KNL, "knl", PROC_64_BIT, FEATURE_AVX512F) - -/// \name Knights Mill -/// Knights Mill processor. -PROC_WITH_FEAT(KNM, "knm", PROC_64_BIT, FEATURE_AVX5124FMAPS) - -/// \name Lakemont -/// Lakemont microarchitecture based processors. -PROC(Lakemont, "lakemont", PROC_32_BIT) - -/// \name K6 -/// K6 architecture processors. -//@{ -PROC(K6, "k6", PROC_32_BIT) -PROC(K6_2, "k6-2", PROC_32_BIT) -PROC(K6_3, "k6-3", PROC_32_BIT) -//@} - -/// \name K7 -/// K7 architecture processors. -//@{ -PROC(Athlon, "athlon", PROC_32_BIT) -PROC_ALIAS(Athlon, "athlon-tbird") - -PROC(AthlonXP, "athlon-xp", PROC_32_BIT) -PROC_ALIAS(AthlonXP, "athlon-mp") -PROC_ALIAS(AthlonXP, "athlon-4") -//@} - -/// \name K8 -/// K8 architecture processors. -//@{ -PROC(K8, "k8", PROC_64_BIT) -PROC_ALIAS(K8, "athlon64") -PROC_ALIAS(K8, "athlon-fx") -PROC_ALIAS(K8, "opteron") - -PROC(K8SSE3, "k8-sse3", PROC_64_BIT) -PROC_ALIAS(K8SSE3, "athlon64-sse3") -PROC_ALIAS(K8SSE3, "opteron-sse3") - -PROC_WITH_FEAT(AMDFAM10, "amdfam10", PROC_64_BIT, FEATURE_SSE4_A) -PROC_ALIAS(AMDFAM10, "barcelona") -//@} - -/// \name Bobcat -/// Bobcat architecture processors. -//@{ -PROC_WITH_FEAT(BTVER1, "btver1", PROC_64_BIT, FEATURE_SSE4_A) -PROC_WITH_FEAT(BTVER2, "btver2", PROC_64_BIT, FEATURE_BMI) -//@} - -/// \name Bulldozer -/// Bulldozer architecture processors. -//@{ -PROC_WITH_FEAT(BDVER1, "bdver1", PROC_64_BIT, FEATURE_XOP) -PROC_WITH_FEAT(BDVER2, "bdver2", PROC_64_BIT, FEATURE_FMA) -PROC_WITH_FEAT(BDVER3, "bdver3", PROC_64_BIT, FEATURE_FMA) -PROC_WITH_FEAT(BDVER4, "bdver4", PROC_64_BIT, FEATURE_AVX2) -//@} - -/// \name zen -/// Zen architecture processors. -//@{ -PROC_WITH_FEAT(ZNVER1, "znver1", PROC_64_BIT, FEATURE_AVX2) -PROC_WITH_FEAT(ZNVER2, "znver2", PROC_64_BIT, FEATURE_AVX2) -//@} - -/// This specification is deprecated and will be removed in the future. -/// Users should prefer K8. -// FIXME: Warn on this when the CPU is set to it. -//@{ -PROC(x86_64, "x86-64", PROC_64_BIT) -//@} - -/// \name Geode -/// Geode processors. -//@{ -PROC(Geode, "geode", PROC_32_BIT) -//@} - // List of CPU Supports features in order. These need to remain in the order // required by attribute 'target' checking. Note that not all are supported/ // prioritized by GCC, so synchronization with GCC's implementation may require @@ -345,6 +108,3 @@ CPU_SPECIFIC("knm", 'j', "+cmov,+mmx,+sse,+sse2,+sse3,+ssse3,+sse4.1,+sse4.2,+mo #undef PROC_64_BIT #undef PROC_32_BIT #undef FEATURE -#undef PROC -#undef PROC_ALIAS -#undef PROC_WITH_FEAT diff --git a/clang/include/clang/Basic/XRayInstr.h b/clang/include/clang/Basic/XRayInstr.h index 48e88848f580..42ca7773fcce 100644 --- a/clang/include/clang/Basic/XRayInstr.h +++ b/clang/include/clang/Basic/XRayInstr.h @@ -28,17 +28,19 @@ namespace XRayInstrKind { // TODO: Auto-generate these as we add more instrumentation kinds. enum XRayInstrOrdinal : XRayInstrMask { - XRIO_Function, + XRIO_FunctionEntry, + XRIO_FunctionExit, XRIO_Custom, XRIO_Typed, XRIO_Count }; constexpr XRayInstrMask None = 0; -constexpr XRayInstrMask Function = 1U << XRIO_Function; +constexpr XRayInstrMask FunctionEntry = 1U << XRIO_FunctionEntry; +constexpr XRayInstrMask FunctionExit = 1U << XRIO_FunctionExit; constexpr XRayInstrMask Custom = 1U << XRIO_Custom; constexpr XRayInstrMask Typed = 1U << XRIO_Typed; -constexpr XRayInstrMask All = Function | Custom | Typed; +constexpr XRayInstrMask All = FunctionEntry | FunctionExit | Custom | Typed; } // namespace XRayInstrKind @@ -51,7 +53,6 @@ struct XRayInstrSet { bool hasOneOf(XRayInstrMask K) const { return Mask & K; } void set(XRayInstrMask K, bool Value) { - assert(llvm::isPowerOf2_32(K)); Mask = Value ? (Mask | K) : (Mask & ~K); } diff --git a/clang/include/clang/Basic/XRayLists.h b/clang/include/clang/Basic/XRayLists.h index cf464f9e5478..7ea9d9789aab 100644 --- a/clang/include/clang/Basic/XRayLists.h +++ b/clang/include/clang/Basic/XRayLists.h @@ -14,14 +14,18 @@ #include "clang/Basic/LLVM.h" #include "clang/Basic/SourceLocation.h" -#include "clang/Basic/SourceManager.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/StringRef.h" -#include "llvm/Support/SpecialCaseList.h" #include <memory> +namespace llvm { +class SpecialCaseList; +} + namespace clang { +class SourceManager; + class XRayFunctionFilter { std::unique_ptr<llvm::SpecialCaseList> AlwaysInstrument; std::unique_ptr<llvm::SpecialCaseList> NeverInstrument; @@ -32,6 +36,7 @@ public: XRayFunctionFilter(ArrayRef<std::string> AlwaysInstrumentPaths, ArrayRef<std::string> NeverInstrumentPaths, ArrayRef<std::string> AttrListPaths, SourceManager &SM); + ~XRayFunctionFilter(); enum class ImbueAttribute { NONE, diff --git a/clang/include/clang/Basic/arm_bf16.td b/clang/include/clang/Basic/arm_bf16.td new file mode 100644 index 000000000000..d837a7666d40 --- /dev/null +++ b/clang/include/clang/Basic/arm_bf16.td @@ -0,0 +1,14 @@ +//===--- arm_fp16.td - ARM BF16 compiler interface ------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file defines the TableGen definitions from which the ARM BF16 header +// file will be generated. +// +//===----------------------------------------------------------------------===// + +include "arm_neon_incl.td" diff --git a/clang/include/clang/Basic/arm_cde.td b/clang/include/clang/Basic/arm_cde.td new file mode 100644 index 000000000000..6a00e669864c --- /dev/null +++ b/clang/include/clang/Basic/arm_cde.td @@ -0,0 +1,232 @@ +//===--- arm_cde.td - ACLE intrinsic functions for CDE --------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file defines the set of ACLE-specified source-level intrinsic +// functions wrapping the CDE instructions. +// +//===----------------------------------------------------------------------===// + +include "arm_mve_defs.td" + +// f64 is not defined in arm_mve_defs.td because MVE instructions only work with +// f16 and f32 +def f64: PrimitiveType<"f", 64>; + +// Float<t> expects t to be a scalar type, and expands to the floating-point +// type of the same width. +class Float<Type t>: ComplexType<(CTO_CopyKind t, f32)>; +def FScalar: Float<Scalar>; + +// ACLE CDE intrinsic +class CDEIntrinsic<Type ret, dag args, dag codegen> + : Intrinsic<ret, args, codegen> { + let builtinExtension = "cde"; +} + +// Immediate (in range [0, 2^numBits - 1]) +class IB_ConstBits<int numBits> : IB_ConstRange<0, !add(!shl(1, numBits), -1)>; +// numBits-wide immediate of type u32 +class CDEImmediateBits<int numBits> : Immediate<u32, IB_ConstBits<numBits>>; + +// LLVM IR CDE intrinsic +class CDEIRInt<string name, list<Type> params = [], bit appendKind = 0> + : IRIntBase<"arm_cde_" # name, params, appendKind>; + +// Class for generating function macros in arm_cde.h: +// "#define <name>(<params>) <definition>" +class FunctionMacro<list<string> params_, string definition_> { + list<string> params = params_; + string definition = definition_; +} + +// Coprocessor immediate +def imm_coproc : Immediate<sint, IB_ConstRange<0, 7>>; + +// Immediate integer parameters +def imm_3b : CDEImmediateBits<3>; +def imm_4b : CDEImmediateBits<4>; +def imm_6b : CDEImmediateBits<6>; +def imm_7b : CDEImmediateBits<7>; +def imm_9b : CDEImmediateBits<9>; +def imm_11b : CDEImmediateBits<11>; +def imm_12b : CDEImmediateBits<12>; +def imm_13b : CDEImmediateBits<13>; + +// CX* instructions operating on GPRs +multiclass CDE_CX_m<dag argsImm, dag argsReg, dag cgArgs> { + defvar cp = (args imm_coproc:$cp); + let pnt = PNT_None, params = T.None in { + def "" : CDEIntrinsic<u32, !con(cp, argsReg, argsImm), + !con((CDEIRInt<NAME> $cp), cgArgs, (? $imm))>; + def a : CDEIntrinsic<u32, !con(cp, (args u32:$acc), argsReg, argsImm), + !con((CDEIRInt<NAME # "a"> $cp, $acc), + cgArgs, (? $imm))>; + + def d : + CDEIntrinsic<u64, !con(cp, argsReg, argsImm), + (seq !con((CDEIRInt<NAME # "d"> $cp), cgArgs, (? $imm)):$pair, + (or (shl (u64 (xval $pair, 1)), (u64 32)), + (u64 (xval $pair, 0))))>; + def da : + CDEIntrinsic<u64, !con(cp, (args u64:$acc), argsReg, argsImm), + (seq (u32 (lshr $acc, (u64 32))):$acc_hi, + (u32 $acc):$acc_lo, + !con((CDEIRInt<NAME # "da"> $cp, $acc_lo, $acc_hi), cgArgs, + (? $imm)):$pair, + (or (shl (u64 (xval $pair, 1)), (u64 32)), + (u64 (xval $pair, 0))))>; + } +} + +defm cx1 : CDE_CX_m<(args imm_13b:$imm), (args), (?)>; +defm cx2 : CDE_CX_m<(args imm_9b:$imm), (args u32:$n), (? $n)>; +defm cx3 : CDE_CX_m<(args imm_6b:$imm), (args u32:$n, u32:$m), (? $n, $m)>; + +// VCX* instructions operating on VFP registers +multiclass CDE_VCXFP_m<dag argsImm, dag argsReg32, dag argsReg64, dag cgArgs> { + defvar cp = (args imm_coproc:$cp); + let pnt = PNT_None, params = [u32] in { + def "" : CDEIntrinsic<u32, !con(cp, argsReg32, argsImm), + (bitcast !con((CDEIRInt<NAME, [f32]> $cp), cgArgs, (? $imm)), + Scalar)>; + def a : CDEIntrinsic<u32, !con(cp, (args u32:$acc), argsReg32, argsImm), + (bitcast !con((CDEIRInt<NAME # "a", [f32]> $cp, + (bitcast $acc, FScalar)), cgArgs, (? $imm)), Scalar)>; + } + let pnt = PNT_None, params = [u64] in { + def d : CDEIntrinsic<u64, !con(cp, argsReg64, argsImm), + (bitcast !con((CDEIRInt<NAME, [f64]> $cp), cgArgs, (? $imm)), + Scalar)>; + def da : CDEIntrinsic<u64, !con(cp, (args u64:$acc), argsReg64, argsImm), + (bitcast !con((CDEIRInt<NAME # "a", [f64]> $cp, + (bitcast $acc, FScalar)), cgArgs, (? $imm)), Scalar)>; + } +} + +defm vcx1: CDE_VCXFP_m<(args imm_11b:$imm), (args), (args), (?)>; +defm vcx2: CDE_VCXFP_m<(args imm_6b:$imm), (args u32:$n), (args u64:$n), + (? (bitcast $n, FScalar))>; +defm vcx3: CDE_VCXFP_m<(args imm_3b:$imm), + (args u32:$n, u32:$m), (args u64:$n, u64:$m), + (? (bitcast $n, FScalar), (bitcast $m, FScalar))>; + +// VCX* instructions operating on Q vector registers + +def v16u8 : VecOf<u8>; + +let pnt = PNT_None, params = [u8] in +def vcx1q : CDEIntrinsic<Vector, (args imm_coproc:$cp, imm_12b:$imm), + (CDEIRInt<"vcx1q"> $cp, $imm)>; + +let pnt = PNT_Type, params = T.All, polymorphicOnly = 1 in { + def vcx1qa : + CDEIntrinsic<Vector, (args imm_coproc:$cp, Vector:$acc, imm_12b:$imm), + (bitcast (CDEIRInt<"vcx1qa"> $cp, (bitcast $acc, v16u8), $imm), + Vector)>; + + def vcx2q : + CDEIntrinsic<Vector, (args imm_coproc:$cp, Vector:$n, imm_7b:$imm), + (bitcast (CDEIRInt<"vcx2q"> $cp, (bitcast $n, VecOf<u8>), $imm), + Vector)>; + def vcx2q_u8 : + CDEIntrinsic<v16u8, (args imm_coproc:$cp, Vector:$n, imm_7b:$imm), + (CDEIRInt<"vcx2q"> $cp, (bitcast $n, VecOf<u8>), $imm)>; + + def vcx2qa_impl : + CDEIntrinsic<Vector, + (args imm_coproc:$cp, Vector:$acc, v16u8:$n, imm_7b:$imm), + (bitcast (CDEIRInt<"vcx2qa"> $cp, (bitcast $acc, v16u8), $n, $imm), + Vector)>; + + def vcx3q_impl : + CDEIntrinsic<Vector, + (args imm_coproc:$cp, Vector:$n, v16u8:$m, imm_4b:$imm), + (bitcast (CDEIRInt<"vcx3q"> $cp, (bitcast $n, v16u8), $m, $imm), + Vector)>; + def vcx3q_u8_impl : + CDEIntrinsic<v16u8, + (args imm_coproc:$cp, Vector:$n, v16u8:$m, imm_4b:$imm), + (CDEIRInt<"vcx3q"> $cp, (bitcast $n, v16u8), $m, $imm)>; + def vcx3qa_impl : + CDEIntrinsic<Vector, + (args imm_coproc:$cp, Vector:$acc, v16u8:$n, v16u8:$m, imm_4b:$imm), + (bitcast (CDEIRInt<"vcx3qa"> $cp, (bitcast $acc, v16u8), $n, $m, + $imm), + Vector)>; +} + +// Reinterpret intrinsics required to implement __arm_vcx*q with 2 or 3 +// polymorphic paramters. +let params = [/* no u8 */ s8, u16, s16, u32, s32, u64, s64, f16, f32], + headerOnly = 1, polymorphicOnly = 1 in +def vreinterpretq_u8 : + Intrinsic<v16u8, (args Vector:$x), (vreinterpret $x, v16u8)>; + +// We need vreinterpretq_u8_u8 to avoid doing smart tricks in the macros +let params = [u8], polymorphicOnly = 1 in +def vreinterpretq_u8_cde : + CDEIntrinsic<v16u8, (args Vector:$x), (id $x)>, + NameOverride<"vreinterpretq_u8">; + + +def vcx2qa : FunctionMacro< + ["cp", "acc", "n", "imm"], + "__arm_vcx2qa_impl((cp), (acc), __arm_vreinterpretq_u8(n), (imm))">; + +def vcx3q : FunctionMacro< + ["cp", "n", "m", "imm"], + "__arm_vcx3q_impl((cp), (n), __arm_vreinterpretq_u8(m), (imm))">; +def vcx3q_u8 : FunctionMacro< + ["cp", "n", "m", "imm"], + "__arm_vcx3q_u8_impl((cp), (n), __arm_vreinterpretq_u8(m), (imm))">; +def vcx3qa : FunctionMacro< + ["cp", "acc", "n", "m", "imm"], + "__arm_vcx3qa_impl((cp), (acc), __arm_vreinterpretq_u8(n), " + "__arm_vreinterpretq_u8(m), (imm))">; + +class CDEIntrinsicMasked<string irname, dag argsReg, dag imm, dag cgArgs> + : CDEIntrinsic<Vector, + !con((args imm_coproc:$cp, Vector:$inactive_or_acc), + argsReg, imm, (args Predicate:$pred)), + !con((CDEIRInt<irname # "_predicated", [Vector,Predicate]> + $cp, $inactive_or_acc), cgArgs, (? $imm, $pred))> { + let params = T.All; + let polymorphicOnly = 1; +} + +def vcx1q_m : CDEIntrinsicMasked<"vcx1q", (args), (args imm_12b:$imm), (?)>; +def vcx1qa_m : CDEIntrinsicMasked<"vcx1qa", (args), (args imm_12b:$imm), (?)>; + +multiclass VCXPredicated<dag argsReg, dag imm, dag cgArgs, + list<string> macroArgs, string macro> { + def _m_impl : CDEIntrinsicMasked<NAME, argsReg, imm, cgArgs>; + def a_m_impl : CDEIntrinsicMasked<NAME#"a", argsReg, imm, cgArgs>; + + def _m: FunctionMacro< + !listconcat(["cp", "inactive"], macroArgs, ["imm", "pred"]), + "__arm_"#NAME#"_m_impl((cp), (inactive), "#macro#" (imm), (pred))">; + def a_m: FunctionMacro< + !listconcat(["cp", "acc"], macroArgs, ["imm", "pred"]), + "__arm_"#NAME#"a_m_impl((cp), (acc), "#macro#" (imm), (pred))">; +} + +defm vcx2q : + VCXPredicated<(args v16u8:$n), (args imm_7b:$imm), (? $n), ["n"], + "__arm_vreinterpretq_u8(n),">; +defm vcx3q : + VCXPredicated<(args v16u8:$n, v16u8:$m), (args imm_4b:$imm), (? $n, $m), + ["n", "m"], "__arm_vreinterpretq_u8(n), " + "__arm_vreinterpretq_u8(m),">; + +// vreinterpretq intrinsics required by the ACLE CDE specification + +foreach desttype = [/* no u8 */ s8, u16, s16, u32, s32, u64, s64, f16, f32] in { + let params = [u8], headerOnly = 1, pnt = PNT_None in + def "vreinterpretq_" # desttype : Intrinsic< + VecOf<desttype>, (args Vector:$x), (vreinterpret $x, VecOf<desttype>)>; +} diff --git a/clang/include/clang/Basic/arm_mve.td b/clang/include/clang/Basic/arm_mve.td index 0e023b85459c..25daae2a0a25 100644 --- a/clang/include/clang/Basic/arm_mve.td +++ b/clang/include/clang/Basic/arm_mve.td @@ -43,6 +43,12 @@ def vqaddq: Intrinsic<Vector, (args Vector:$a, Vector:$b), (IRIntBase<"sadd_sat", [Vector]> $a, $b)>; def vqsubq: Intrinsic<Vector, (args Vector:$a, Vector:$b), (IRIntBase<"ssub_sat", [Vector]> $a, $b)>; +let pnt = PNT_NType in { + def vqaddq_n: Intrinsic<Vector, (args Vector:$a, unpromoted<Scalar>:$b), + (IRIntBase<"sadd_sat", [Vector]> $a, (splat $b))>; + def vqsubq_n: Intrinsic<Vector, (args Vector:$a, unpromoted<Scalar>:$b), + (IRIntBase<"ssub_sat", [Vector]> $a, (splat $b))>; +} } let params = T.Unsigned in { def vqaddq_u: Intrinsic<Vector, (args Vector:$a, Vector:$b), @@ -51,6 +57,14 @@ def vqaddq_u: Intrinsic<Vector, (args Vector:$a, Vector:$b), def vqsubq_u: Intrinsic<Vector, (args Vector:$a, Vector:$b), (IRIntBase<"usub_sat", [Vector]> $a, $b)>, NameOverride<"vqsubq">; +let pnt = PNT_NType in { + def vqaddq_u_n: Intrinsic<Vector, (args Vector:$a, unpromoted<Scalar>:$b), + (IRIntBase<"uadd_sat", [Vector]> $a, (splat $b))>, + NameOverride<"vqaddq_n">; + def vqsubq_u_n: Intrinsic<Vector, (args Vector:$a, unpromoted<Scalar>:$b), + (IRIntBase<"usub_sat", [Vector]> $a, (splat $b))>, + NameOverride<"vqsubq_n">; +} } // Some intrinsics below are implemented not as IR fragments, but as @@ -85,12 +99,32 @@ def vmullbq_int: Intrinsic<DblVector, (args Vector:$a, Vector:$b), def vmulltq_int: Intrinsic<DblVector, (args Vector:$a, Vector:$b), (IRInt<"vmull", [DblVector, Vector]> $a, $b, (unsignedflag Scalar), 1)>; +let pnt = PNT_NType in { + def vaddq_n: Intrinsic<Vector, (args Vector:$a, unpromoted<Scalar>:$b), + (add $a, (splat $b))>; + def vsubq_n: Intrinsic<Vector, (args Vector:$a, unpromoted<Scalar>:$b), + (sub $a, (splat $b))>; + def vmulq_n: Intrinsic<Vector, (args Vector:$a, unpromoted<Scalar>:$b), + (mul $a, (splat $b))>; + def vhaddq_n: Intrinsic<Vector, (args Vector:$a, unpromoted<Scalar>:$b), + (IRInt<"vhadd", [Vector]> $a, (splat $b), + (unsignedflag Scalar))>; + def vhsubq_n: Intrinsic<Vector, (args Vector:$a, unpromoted<Scalar>:$b), + (IRInt<"vhsub", [Vector]> $a, (splat $b), + (unsignedflag Scalar))>; +} } let params = T.Signed in { def vqdmulhq: Intrinsic<Vector, (args Vector:$a, Vector:$b), (IRInt<"vqdmulh", [Vector]> $a, $b)>; def vqrdmulhq: Intrinsic<Vector, (args Vector:$a, Vector:$b), (IRInt<"vqrdmulh", [Vector]> $a, $b)>; +let pnt = PNT_NType in { + def vqdmulhq_n: Intrinsic<Vector, (args Vector:$a, unpromoted<Scalar>:$b), + (IRInt<"vqdmulh", [Vector]> $a, (splat $b))>; + def vqrdmulhq_n: Intrinsic<Vector, (args Vector:$a, unpromoted<Scalar>:$b), + (IRInt<"vqrdmulh", [Vector]> $a, (splat $b))>; +} } let params = T.Poly, overrideKindLetter = "p" in { @@ -114,6 +148,240 @@ def vsubqf: Intrinsic<Vector, (args Vector:$a, Vector:$b), (fsub $a, $b)>, NameOverride<"vsubq">; def vmulqf: Intrinsic<Vector, (args Vector:$a, Vector:$b), (fmul $a, $b)>, NameOverride<"vmulq">; + +let pnt = PNT_NType in { + def vaddqf_n: Intrinsic<Vector, (args Vector:$a, unpromoted<Scalar>:$b), + (fadd $a, (splat $b))>, + NameOverride<"vaddq_n">; + def vsubqf_n: Intrinsic<Vector, (args Vector:$a, unpromoted<Scalar>:$b), + (fsub $a, (splat $b))>, + NameOverride<"vsubq_n">; + def vmulqf_n: Intrinsic<Vector, (args Vector:$a, unpromoted<Scalar>:$b), + (fmul $a, (splat $b))>, + NameOverride<"vmulq_n">; +} +} + +multiclass FMA<bit add> { + // FMS instructions are defined in the ArmARM as if they negate the + // second multiply input. + defvar m2_cg = !if(add, (id $m2), (fneg $m2)); + + defvar unpred_cg = (IRIntBase<"fma", [Vector]> $m1, m2_cg, $addend); + defvar pred_cg = (IRInt<"fma_predicated", [Vector, Predicate]> + $m1, m2_cg, $addend, $pred); + + def q: Intrinsic<Vector, (args Vector:$addend, Vector:$m1, Vector:$m2), + unpred_cg>; + + def q_m: Intrinsic<Vector, (args Vector:$addend, Vector:$m1, Vector:$m2, + Predicate:$pred), pred_cg>; + + // Only FMA has the vector/scalar variants, not FMS + if add then let pnt = PNT_NType in { + + def q_n: Intrinsic<Vector, (args Vector:$addend, Vector:$m1, + unpromoted<Scalar>:$m2_s), + (seq (splat $m2_s):$m2, unpred_cg)>; + def sq_n: Intrinsic<Vector, (args Vector:$m1, Vector:$m2, + unpromoted<Scalar>:$addend_s), + (seq (splat $addend_s):$addend, unpred_cg)>; + def q_m_n: Intrinsic<Vector, (args Vector:$addend, Vector:$m1, + unpromoted<Scalar>:$m2_s, + Predicate:$pred), + (seq (splat $m2_s):$m2, pred_cg)>; + def sq_m_n: Intrinsic<Vector, (args Vector:$m1, Vector:$m2, + unpromoted<Scalar>:$addend_s, + Predicate:$pred), + (seq (splat $addend_s):$addend, pred_cg)>; + } +} + +let params = T.Float in { + defm vfma: FMA<1>; + defm vfms: FMA<0>; +} + +let params = T.Int, pnt = PNT_NType in { + def vmlaq_n: Intrinsic< + Vector, (args Vector:$addend, Vector:$m1, unpromoted<Scalar>:$m2_s), + (add (mul $m1, (splat $m2_s)), $addend)>; + def vmlasq_n: Intrinsic< + Vector, (args Vector:$m1, Vector:$m2, unpromoted<Scalar>:$addend_s), + (add (mul $m1, $m2), (splat $addend_s))>; + + def vmlaq_m_n: Intrinsic< + Vector, (args Vector:$addend, Vector:$m1, Scalar:$m2_s, Predicate:$pred), + (IRInt<"vmla_n_predicated", [Vector, Predicate]> + $addend, $m1, $m2_s, $pred)>; + def vmlasq_m_n: Intrinsic< + Vector, (args Vector:$m1, Vector:$m2, Scalar:$addend_s, Predicate:$pred), + (IRInt<"vmlas_n_predicated", [Vector, Predicate]> + $m1, $m2, $addend_s, $pred)>; +} + +multiclass VQDMLA { + def hq_n: Intrinsic< + Vector, (args Vector:$addend, Vector:$m1, Scalar:$m2_s), + (IRInt<NAME # "h", [Vector]> $addend, $m1, $m2_s)>; + def shq_n: Intrinsic< + Vector, (args Vector:$m1, Vector:$m2, Scalar:$addend_s), + (IRInt<NAME # "sh", [Vector]> $m1, $m2, $addend_s)>; + + def hq_m_n: Intrinsic< + Vector, (args Vector:$addend, Vector:$m1, Scalar:$m2_s, Predicate:$pred), + (IRInt<NAME # "h_predicated", [Vector, Predicate]> + $addend, $m1, $m2_s, $pred)>; + def shq_m_n: Intrinsic< + Vector, (args Vector:$m1, Vector:$m2, Scalar:$addend_s, Predicate:$pred), + (IRInt<NAME # "sh_predicated", [Vector, Predicate]> + $m1, $m2, $addend_s, $pred)>; +} + +let params = T.Signed, pnt = PNT_NType in { + defm vqdmla: VQDMLA; + defm vqrdmla: VQDMLA; +} + +multiclass VQDMLAD<int exchange, int round, int subtract> { + def "": Intrinsic<Vector, (args Vector:$a, Vector:$b, Vector:$c), + (IRInt<"vqdmlad", [Vector]> $a, $b, $c, + (u32 exchange), (u32 round), (u32 subtract))>; + def _m: Intrinsic<Vector, (args Vector:$a, Vector:$b, Vector:$c, + Predicate:$pred), + (IRInt<"vqdmlad_predicated", [Vector, Predicate]> $a, $b, $c, + (u32 exchange), (u32 round), (u32 subtract), $pred)>; +} +let params = T.Signed in { + defm vqdmladhq: VQDMLAD<0, 0, 0>; + defm vqdmladhxq: VQDMLAD<1, 0, 0>; + defm vqdmlsdhq: VQDMLAD<0, 0, 1>; + defm vqdmlsdhxq: VQDMLAD<1, 0, 1>; + defm vqrdmladhq: VQDMLAD<0, 1, 0>; + defm vqrdmladhxq: VQDMLAD<1, 1, 0>; + defm vqrdmlsdhq: VQDMLAD<0, 1, 1>; + defm vqrdmlsdhxq: VQDMLAD<1, 1, 1>; +} + +let params = !listconcat(T.Int16, T.Int32) in { + let pnt = PNT_None in { + def vmvnq_n: Intrinsic<Vector, (args imm_simd_vmvn:$imm), + (not (splat (Scalar $imm)))>; + } + defm vmvnq: IntrinsicMX<Vector, (args imm_simd_vmvn:$imm, Predicate:$pred), + (select $pred, (not (splat (Scalar $imm))), $inactive), + 1, "_n", PNT_NType, PNT_None>; + let pnt = PNT_NType in { + def vbicq_n: Intrinsic<Vector, (args Vector:$v, imm_simd_restrictive:$imm), + (and $v, (not (splat (Scalar $imm))))>; + def vorrq_n: Intrinsic<Vector, (args Vector:$v, imm_simd_restrictive:$imm), + (or $v, (splat (Scalar $imm)))>; + } + def vbicq_m_n: Intrinsic< + Vector, (args Vector:$v, imm_simd_restrictive:$imm, Predicate:$pred), + (select $pred, (and $v, (not (splat (Scalar $imm)))), $v)>; + def vorrq_m_n: Intrinsic< + Vector, (args Vector:$v, imm_simd_restrictive:$imm, Predicate:$pred), + (select $pred, (or $v, (splat (Scalar $imm))), $v)>; +} + +let params = T.Usual in { + let pnt = PNT_None in + def vdupq_n: Intrinsic<Vector, (args unpromoted<Scalar>:$s), (splat $s)>; + + defm vdupq: IntrinsicMX< + Vector, (args unpromoted<Scalar>:$s, Predicate:$pred), + (select $pred, (splat $s), $inactive), 1, "_n", PNT_NType, PNT_None>; +} + +multiclass vxdup_mc<dag paramsIn, dag paramsOut> { + defvar UnpredInt = IRInt<NAME, [Vector]>; + defvar PredInt = IRInt<NAME # "_predicated", [Vector, Predicate]>; + defvar UnpredIntCall = !con((UnpredInt $base), paramsOut); + defvar PredIntCall = !con((PredInt $inactive, $base), paramsOut, (? $pred)); + + // Straightforward case with neither writeback nor predication + let pnt = PNT_N in + def q_n: Intrinsic<Vector, !con((args u32:$base), paramsIn), + (xval UnpredIntCall, 0)>; + + // Predicated form without writeback + defm q: IntrinsicMX< + Vector, !con((args u32:$base), paramsIn, (? Predicate:$pred)), + (xval PredIntCall, 0), 1, "_n", PNT_NType, PNT_N>; + + // Writeback without predication + let pnt = PNT_WB in + def q_wb: Intrinsic< + Vector, !con((args Ptr<u32>:$baseaddr), paramsIn), + (seq (load $baseaddr):$base, + UnpredIntCall:$pair, + (store (xval $pair, 1), $baseaddr), + (xval $pair, 0))>; + + // Both writeback and predicated + defm q: IntrinsicMX< + Vector, !con((args Ptr<u32>:$baseaddr), paramsIn, (? Predicate:$pred)), + (seq (load $baseaddr):$base, + PredIntCall:$pair, + (store (xval $pair, 1), $baseaddr), + (xval $pair, 0)), 1, "_wb", PNT_WBType, PNT_WB>; +} + +let params = T.Unsigned in { + defm vidup: vxdup_mc<(? imm_1248:$step), (? $step)>; + defm vddup: vxdup_mc<(? imm_1248:$step), (? $step)>; + defm viwdup: vxdup_mc<(? u32:$limit, imm_1248:$step), (? $limit, $step)>; + defm vdwdup: vxdup_mc<(? u32:$limit, imm_1248:$step), (? $limit, $step)>; +} + +let params = T.Int in { + def vmvnq: Intrinsic<Vector, (args Vector:$a), + (xor $a, (uint_max Vector))>; + defm vmvnq: IntrinsicMX<Vector, (args Vector:$a, Predicate:$pred), + (IRInt<"mvn_predicated", [Vector, Predicate]> $a, $pred, $inactive)>; + def vclzq: Intrinsic<Vector, (args Vector:$a), + (IRIntBase<"ctlz", [Vector]> $a, (i1 0))>; + defm vclzq: IntrinsicMX<Vector, (args Vector:$a, Predicate:$pred), + (IRInt<"clz_predicated", [Vector, Predicate]> $a, $pred, $inactive)>; +} +let params = T.Signed in { + def vclsq: Intrinsic<Vector, (args Vector:$a), (IRInt<"vcls", [Vector]> $a)>; + defm vclsq: IntrinsicMX<Vector, (args Vector:$a, Predicate:$pred), + (IRInt<"cls_predicated", [Vector, Predicate]> $a, $pred, $inactive)>; + + def vnegq: Intrinsic<Vector, (args Vector:$a), + (sub (zeroinit Vector), $a)>; + def vabsq: Intrinsic<Vector, (args Vector:$a), + (select (icmp_slt $a, (zeroinit Vector)), + (sub (zeroinit Vector), $a), $a)>; + def vqnegq: Intrinsic<Vector, (args Vector:$a), + (select (icmp_eq $a, (int_min Vector)), + (int_max Vector), + (sub (zeroinit Vector), $a))>; + def vqabsq: Intrinsic<Vector, (args Vector:$a), + (select (icmp_sgt $a, (zeroinit Vector)), $a, + (select (icmp_eq $a, (int_min Vector)), + (int_max Vector), + (sub (zeroinit Vector), $a)))>; + + foreach name = ["qneg", "qabs"] in { + defm v#name#q: IntrinsicMX<Vector, (args Vector:$a, Predicate:$pred), + (IRInt<name#"_predicated", [Vector, Predicate]> $a, $pred, $inactive), + 0 /* no _x variant for saturating intrinsics */>; + } +} +let params = !listconcat(T.Signed, T.Float) in { + foreach name = ["neg", "abs"] in { + defm v#name#q: IntrinsicMX<Vector, (args Vector:$a, Predicate:$pred), + (IRInt<name#"_predicated", [Vector, Predicate]> $a, $pred, $inactive)>; + } +} +let params = T.Float in { + def vnegq_f: Intrinsic<Vector, (args Vector:$a), (fneg $a)>, + NameOverride<"vnegq">; + def vabsq_f: Intrinsic<Vector, (args Vector:$a), + (IRIntBase<"fabs", [Vector]> $a)>, NameOverride<"vabsq">; } // The bitcasting below is not overcomplicating the IR because while @@ -145,6 +413,16 @@ multiclass VectorVectorArithmetic<string operation, dag extraArgs = (?), extraArgs, (? $pred, $inactive)), wantXVariant>; } +multiclass VectorScalarArithmetic<string operation, string basename, + dag extraArgs = (?), + int wantXVariant = 1> { + defm "" : IntrinsicMXNameOverride< + Vector, (args Vector:$a, unpromoted<Scalar>:$b, Predicate:$pred), + !con((IRInt<operation, [Vector, Predicate]> $a, (splat $b)), + extraArgs, (? $pred, $inactive)), basename, wantXVariant, "_n", + PNT_NType, PNT_NType>; +} + multiclass VectorVectorArithmeticBitcast<string operation> { defm "" : IntrinsicMX<Vector, (args Vector:$a, Vector:$b, Predicate:$pred), @@ -166,13 +444,28 @@ let params = T.Usual in { defm veorq : VectorVectorArithmeticBitcast<"eor_predicated">; defm vornq : VectorVectorArithmeticBitcast<"orn_predicated">; defm vorrq : VectorVectorArithmeticBitcast<"orr_predicated">; + + defm : VectorScalarArithmetic<"add_predicated", "vaddq">; + defm : VectorScalarArithmetic<"sub_predicated", "vsubq">; + defm : VectorScalarArithmetic<"mul_predicated", "vmulq">; } -multiclass DblVectorVectorArithmetic<string operation, dag extraArgs = (?)> { +multiclass DblVectorVectorArithmetic<string operation, dag extraArgs = (?), + int wantXVariant = 1> { defm "" : IntrinsicMX< - DblVector, (args Vector:$a, Vector:$b, Predicate:$pred), - !con((IRInt<operation, [DblVector, Vector, Predicate]> $a, $b), - extraArgs, (? $pred, $inactive))>; + DblVector, (args Vector:$a, Vector:$b, DblPredicate:$pred), + !con((IRInt<operation, [DblVector, Vector, DblPredicate]> $a, $b), + extraArgs, (? $pred, $inactive)), wantXVariant>; +} + +multiclass DblVectorScalarArithmetic<string operation, string basename, + dag extraArgs = (?), + int wantXVariant = 1> { + defm "" : IntrinsicMXNameOverride< + DblVector, (args Vector:$a, unpromoted<Scalar>:$b, DblPredicate:$pred), + !con((IRInt<operation, [DblVector, Vector, DblPredicate]> $a, (splat $b)), + extraArgs, (? $pred, $inactive)), basename, wantXVariant, "_n", + PNT_NType, PNT_NType>; } // Predicated intrinsics - Int types only @@ -188,10 +481,22 @@ let params = T.Int in { defm vhsubq : VectorVectorArithmetic<"hsub_predicated", (? (unsignedflag Scalar))>; defm vmullbq_int : DblVectorVectorArithmetic<"mull_int_predicated", (? (unsignedflag Scalar), (u32 0))>; defm vmulltq_int : DblVectorVectorArithmetic<"mull_int_predicated", (? (unsignedflag Scalar), (u32 1))>; + + defm : VectorScalarArithmetic<"qadd_predicated", "vqaddq", (? (unsignedflag Scalar)), 0>; + defm : VectorScalarArithmetic<"hadd_predicated", "vhaddq", (? (unsignedflag Scalar))>; + defm : VectorScalarArithmetic<"qsub_predicated", "vqsubq", (? (unsignedflag Scalar)), 0>; + defm : VectorScalarArithmetic<"hsub_predicated", "vhsubq", (? (unsignedflag Scalar))>; } let params = T.Signed in { defm vqdmulhq : VectorVectorArithmetic<"qdmulh_predicated", (?), 0>; defm vqrdmulhq : VectorVectorArithmetic<"qrdmulh_predicated", (?), 0>; + def vminaq_m: Intrinsic<UVector, (args UVector:$a, Vector:$b, Predicate:$pred), + (IRInt<"vmina_predicated", [UVector,Predicate]> $a, $b, $pred)>; + def vmaxaq_m: Intrinsic<UVector, (args UVector:$a, Vector:$b, Predicate:$pred), + (IRInt<"vmaxa_predicated", [UVector,Predicate]> $a, $b, $pred)>; + + defm : VectorScalarArithmetic<"qdmulh_predicated", "vqdmulhq", (?), 0>; + defm : VectorScalarArithmetic<"qrdmulh_predicated", "vqrdmulhq", (?), 0>; } let params = T.Poly, overrideKindLetter = "p" in { @@ -199,17 +504,74 @@ let params = T.Poly, overrideKindLetter = "p" in { defm vmulltq_poly : DblVectorVectorArithmetic<"mull_poly_predicated", (? (u32 1))>; } +let params = [s16, s32] in { + def vqdmullbq: Intrinsic<DblVector, (args Vector:$a, Vector:$b), + (IRInt<"vqdmull", [DblVector, Vector]> $a, $b, 0)>; + def vqdmulltq: Intrinsic<DblVector, (args Vector:$a, Vector:$b), + (IRInt<"vqdmull", [DblVector, Vector]> $a, $b, 1)>; + defm vqdmullbq: DblVectorVectorArithmetic<"vqdmull_predicated", (? (u32 0)), 0>; + defm vqdmulltq: DblVectorVectorArithmetic<"vqdmull_predicated", (? (u32 1)), 0>; + + let pnt = PNT_NType in { + def vqdmullbq_n: Intrinsic<DblVector, (args Vector:$a, unpromoted<Scalar>:$b), + (IRInt<"vqdmull", [DblVector, Vector]> + $a, (splat $b), 0)>; + def vqdmulltq_n: Intrinsic<DblVector, (args Vector:$a, unpromoted<Scalar>:$b), + (IRInt<"vqdmull", [DblVector, Vector]> + $a, (splat $b), 1)>; + } + defm vqdmullbq_n: DblVectorScalarArithmetic<"vqdmull_predicated", + "vqdmullbq", (? (u32 0)), 0>; + defm vqdmulltq_n: DblVectorScalarArithmetic<"vqdmull_predicated", + "vqdmulltq", (? (u32 1)), 0>; +} + // Predicated intrinsics - Float types only let params = T.Float in { defm vminnmq : VectorVectorArithmetic<"min_predicated", (? (u32 0))>; defm vmaxnmq : VectorVectorArithmetic<"max_predicated", (? (u32 0))>; + def vminnmaq_m: Intrinsic<Vector, (args Vector:$a, Vector:$b, Predicate:$pred), + (IRInt<"vminnma_predicated", [Vector,Predicate]> $a, $b, $pred)>; + def vmaxnmaq_m: Intrinsic<Vector, (args Vector:$a, Vector:$b, Predicate:$pred), + (IRInt<"vmaxnma_predicated", [Vector,Predicate]> $a, $b, $pred)>; +} + +multiclass Reduction<Type Accumulator, string basename, list<Type> basetypes, + bit needSign = 0, + dag postCG = (seq (id $ret)), + dag accArg = (args Accumulator:$prev), + dag preCG = (seq)> { + defvar intArgsBase = (? $prev, $vec); + defvar intArgsUnpred = !con(intArgsBase, + !if(needSign, (? (unsignedflag Scalar)), (?))); + defvar intArgsPred = !con(intArgsUnpred, (? $pred)); + defvar intUnpred = !setop(intArgsUnpred, IRInt<basename, basetypes>); + defvar intPred = !setop(intArgsPred, IRInt< + basename#"_predicated", !listconcat(basetypes, [Predicate])>); + + def "": Intrinsic< + Accumulator, !con(accArg, (args Vector:$vec)), + !con(preCG, (seq intUnpred:$ret), postCG)>; + def _p: Intrinsic< + Accumulator, !con(accArg, (args Vector:$vec, Predicate:$pred)), + !con(preCG, (seq intPred:$ret), postCG)>; } let params = T.Int in { -def vminvq: Intrinsic<Scalar, (args Scalar:$prev, Vector:$vec), - (Scalar (IRInt<"minv", [Vector], 1> $prev, $vec))>; -def vmaxvq: Intrinsic<Scalar, (args Scalar:$prev, Vector:$vec), - (Scalar (IRInt<"maxv", [Vector], 1> $prev, $vec))>; +defm vminvq: Reduction<Scalar, "minv", [Vector], 1, (seq (Scalar $ret))>; +defm vmaxvq: Reduction<Scalar, "maxv", [Vector], 1, (seq (Scalar $ret))>; +} + +let params = T.Signed in { +defm vminavq: Reduction<UScalar, "minav", [Vector], 0, (seq (UScalar $ret))>; +defm vmaxavq: Reduction<UScalar, "maxav", [Vector], 0, (seq (UScalar $ret))>; +} + +let params = T.Float in { +defm vminnmvq: Reduction<Scalar, "minnmv", [Scalar, Vector]>; +defm vmaxnmvq: Reduction<Scalar, "maxnmv", [Scalar, Vector]>; +defm vminnmavq: Reduction<Scalar, "minnmav", [Scalar, Vector]>; +defm vmaxnmavq: Reduction<Scalar, "maxnmav", [Scalar, Vector]>; } foreach half = [ "b", "t" ] in { @@ -223,8 +585,133 @@ foreach half = [ "b", "t" ] in { VecOf<f16>, (args VecOf<f16>:$inactive, Vector:$a, PredOf<f32>:$pred), (IRInt<"vcvt_narrow_predicated"> $inactive, $a, halfconst, $pred)>; } // params = [f32], pnt = PNT_None + + let params = [f16], pnt = PNT_None in { + def vcvt#half#q_f32: Intrinsic<VecOf<f32>, (args Vector:$a), + (IRInt<"vcvt_widen"> $a, halfconst)>; + defm vcvt#half#q: IntrinsicMX< + VecOf<f32>, (args Vector:$a, PredOf<f32>:$pred), + (IRInt<"vcvt_widen_predicated"> $inactive, $a, halfconst, $pred), + 1, "_f32">; + } // params = [f16], pnt = PNT_None } // loop over half = "b", "t" +multiclass float_int_conversions<Type FScalar, Type IScalar, IRBuilderBase ftoi, IRBuilderBase itof> { + defvar FVector = VecOf<FScalar>; + defvar IVector = VecOf<IScalar>; + + let params = [IScalar] in { + let pnt = PNT_2Type in { + def : Intrinsic<FVector, (args IVector:$a), (itof $a, FVector)>, + NameOverride<"vcvtq_" # FScalar>; + } + defm vcvtq: IntrinsicMX<FVector, (args IVector:$a, Predicate:$pred), + (IRInt<"vcvt_fp_int_predicated", [FVector, IVector, Predicate]> + $a, (unsignedflag IScalar), $pred, $inactive), + 1, "_" # FScalar, PNT_2Type, PNT_2Type>; + } + let params = [FScalar] in { + let pnt = PNT_None in { + def : Intrinsic<IVector, (args FVector:$a), (ftoi $a, IVector)>, + NameOverride<"vcvtq_" # IScalar>; + + foreach suffix = ["a","n","p","m"] in + def : Intrinsic<IVector, (args FVector:$a), + (IRInt<"vcvt"#suffix, [IVector, FVector]> + (unsignedflag IScalar), $a)>, + NameOverride<"vcvt"#suffix#"q_" # IScalar>; + } + defm vcvtq: IntrinsicMX<IVector, (args FVector:$a, Predicate:$pred), + (IRInt<"vcvt_fp_int_predicated", [IVector, FVector, Predicate]> + $a, (unsignedflag IScalar), $pred, $inactive), + 1, "_" # IScalar, PNT_2Type, PNT_None>; + + foreach suffix = ["a","n","p","m"] in { + defm "vcvt"#suffix#"q" : IntrinsicMX< + IVector, (args FVector:$a, Predicate:$pred), + (IRInt<"vcvt"#suffix#"_predicated", [IVector, FVector, Predicate]> + (unsignedflag IScalar), $inactive, $a, $pred), + 1, "_" # IScalar, PNT_2Type, PNT_None>; + } + } +} + +defm "" : float_int_conversions<f32, u32, fptoui, uitofp>; +defm "" : float_int_conversions<f16, u16, fptoui, uitofp>; +defm "" : float_int_conversions<f32, s32, fptosi, sitofp>; +defm "" : float_int_conversions<f16, s16, fptosi, sitofp>; + +multiclass vmovl<bit top> { + let params = [s8, u8, s16, u16] in { + def "": Intrinsic<DblVector, (args Vector:$a), + (extend (unzip $a, top), DblVector, (unsignedflag Scalar))>; + defm "": IntrinsicMX<DblVector, (args Vector:$a, DblPredicate:$pred), + (IRInt<"vmovl_predicated", [DblVector, Vector, DblPredicate]> + $a, (unsignedflag Scalar), top, $pred, $inactive)>; + } +} + +defm vmovlbq: vmovl<0>; +defm vmovltq: vmovl<1>; + +multiclass vmovn<bit top, dag wide_result> { + let params = [s16, u16, s32, u32] in { + def "": Intrinsic<HalfVector, (args HalfVector:$inactive, Vector:$a), + (trunc wide_result, HalfVector)>; + def _m: Intrinsic<HalfVector, (args HalfVector:$inactive, Vector:$a, + Predicate:$pred), + (IRInt<"vmovn_predicated", [HalfVector, Vector, Predicate]> + $inactive, $a, top, $pred)>; + } +} + +defm vmovntq: vmovn<1, (zip (vreinterpret $inactive, Vector), $a)>; +defm vmovnbq: vmovn<0, + (zip $a, (vreinterpret (vrev $inactive, (bitsize Scalar)), Vector))>; + +multiclass vqmovn<bit top, Type RetScalar> { + defvar RetVector = VecOf<RetScalar>; + + let params = [s16, u16, s32, u32] in { + def : Intrinsic< + RetVector, (args RetVector:$inactive, Vector:$a), + (IRInt<"vqmovn", [RetVector, Vector]> + $inactive, $a, (unsignedflag RetScalar), (unsignedflag Scalar), top)>, + NameOverride<NAME>; + def: Intrinsic< + RetVector, (args RetVector:$inactive, Vector:$a, Predicate:$pred), + (IRInt<"vqmovn_predicated", [RetVector, Vector, Predicate]> + $inactive, $a, (unsignedflag RetScalar), (unsignedflag Scalar), + top, $pred)>, + NameOverride<NAME # "_m">; + } +} + +let params = [s16, s32, u16, u32] in { + defm vqmovntq: vqmovn<1, HalfScalar>; + defm vqmovnbq: vqmovn<0, HalfScalar>; +} +let params = [s16, s32] in { + defm vqmovuntq: vqmovn<1, UHalfScalar>; + defm vqmovunbq: vqmovn<0, UHalfScalar>; +} + +multiclass vrnd<IRIntBase ir_int, string suffix> { + let params = T.Float in { + def "": Intrinsic<Vector, (args Vector:$a), (ir_int $a)>; + defm "": IntrinsicMX<Vector, (args Vector:$a, Predicate:$pred), + (IRInt<"vrint"#suffix#"_predicated", [Vector, Predicate]> + $a, $pred, $inactive)>; + } +} + +defm vrndq: vrnd<IRIntBase<"trunc", [Vector]>, "z">; +defm vrndmq: vrnd<IRIntBase<"floor", [Vector]>, "m">; +defm vrndpq: vrnd<IRIntBase<"ceil", [Vector]>, "p">; +defm vrndaq: vrnd<IRIntBase<"round", [Vector]>, "a">; +defm vrndxq: vrnd<IRIntBase<"rint", [Vector]>, "x">; +defm vrndnq: vrnd<IRInt<"vrintn", [Vector]>, "n">; + multiclass compare_with_pred<string condname, dag arguments, dag cmp, string suffix> { // Make the predicated and unpredicated versions of a single comparison. @@ -275,6 +762,14 @@ let params = T.Signed in { (select (icmp_sle $a, $b), $a, $b)>; def vmaxq: Intrinsic<Vector, (args Vector:$a, Vector:$b), (select (icmp_sge $a, $b), $a, $b)>; + def vminaq: Intrinsic<UVector, (args UVector:$a, Vector:$b), + (seq (select (icmp_slt $b, (zeroinit Vector)), + (sub (zeroinit Vector), $b), $b):$absb, + (select (icmp_ule $a, $absb), $a, $absb))>; + def vmaxaq: Intrinsic<UVector, (args UVector:$a, Vector:$b), + (seq (select (icmp_slt $b, (zeroinit Vector)), + (sub (zeroinit Vector), $b), $b):$absb, + (select (icmp_uge $a, $absb), $a, $absb))>; } let params = T.Unsigned in { def vminqu: Intrinsic<Vector, (args Vector:$a, Vector:$b), @@ -286,9 +781,17 @@ let params = T.Unsigned in { } let params = T.Float in { def vminnmq: Intrinsic<Vector, (args Vector:$a, Vector:$b), - (IRIntBase<"minnum", [Vector]> $a, $b)>; + (IRIntBase<"minnum", [Vector]> $a, $b)>; def vmaxnmq: Intrinsic<Vector, (args Vector:$a, Vector:$b), - (IRIntBase<"maxnum", [Vector]> $a, $b)>; + (IRIntBase<"maxnum", [Vector]> $a, $b)>; + def vminnmaq: Intrinsic<Vector, (args Vector:$a, Vector:$b), + (IRIntBase<"minnum", [Vector]> + (IRIntBase<"fabs", [Vector]> $a), + (IRIntBase<"fabs", [Vector]> $b))>; + def vmaxnmaq: Intrinsic<Vector, (args Vector:$a, Vector:$b), + (IRIntBase<"maxnum", [Vector]> + (IRIntBase<"fabs", [Vector]> $a), + (IRIntBase<"fabs", [Vector]> $b))>; } def vpselq: Intrinsic<Vector, (args Vector:$t, Vector:$f, Predicate:$pred), @@ -640,8 +1143,8 @@ multiclass vshll_imm<int top> { (IRInt<"vshll_imm", [DblVector, Vector]> $v, $sh, (unsignedflag Scalar), top)>; defm "": IntrinsicMX<DblVector, (args Vector:$v, imm_1toN:$sh, - Predicate:$pred), - (IRInt<"vshll_imm_predicated", [DblVector, Vector, Predicate]> + DblPredicate:$pred), + (IRInt<"vshll_imm_predicated", [DblVector, Vector, DblPredicate]> $v, $sh, (unsignedflag Scalar), top, $pred, $inactive), 1, "_n">; } } @@ -768,27 +1271,47 @@ defm sqrshr: ScalarSaturatingShiftReg<s32, s64>; def lsll: LongScalarShift<u64, (args s32:$sh), (IRInt<"lsll"> $lo, $hi, $sh)>; def asrl: LongScalarShift<s64, (args s32:$sh), (IRInt<"asrl"> $lo, $hi, $sh)>; +multiclass vadcsbc { + def q: Intrinsic<Vector, (args Vector:$a, Vector:$b, Ptr<uint>:$carry), + (seq (IRInt<NAME, [Vector]> $a, $b, (shl (load $carry), 29)):$pair, + (store (and 1, (lshr (xval $pair, 1), 29)), $carry), + (xval $pair, 0))>; + def iq: Intrinsic<Vector, (args Vector:$a, Vector:$b, Ptr<uint>:$carry), + (seq (IRInt<NAME, [Vector]> $a, $b, 0):$pair, + (store (and 1, (lshr (xval $pair, 1), 29)), $carry), + (xval $pair, 0))>; + def q_m: Intrinsic<Vector, (args Vector:$inactive, Vector:$a, Vector:$b, + Ptr<uint>:$carry, Predicate:$pred), + (seq (IRInt<NAME # "_predicated", [Vector, Predicate]> $inactive, $a, $b, + (shl (load $carry), 29), $pred):$pair, + (store (and 1, (lshr (xval $pair, 1), 29)), $carry), + (xval $pair, 0))>; + def iq_m: Intrinsic<Vector, (args Vector:$inactive, Vector:$a, Vector:$b, + Ptr<uint>:$carry, Predicate:$pred), + (seq (IRInt<NAME # "_predicated", [Vector, Predicate]> $inactive, $a, $b, + 0, $pred):$pair, + (store (and 1, (lshr (xval $pair, 1), 29)), $carry), + (xval $pair, 0))>; +} let params = T.Int32 in { -def vadcq: Intrinsic<Vector, (args Vector:$a, Vector:$b, Ptr<uint>:$carry), - (seq (IRInt<"vadc", [Vector]> $a, $b, (shl (load $carry), 29)):$pair, - (store (and 1, (lshr (xval $pair, 1), 29)), $carry), - (xval $pair, 0))>; -def vadciq: Intrinsic<Vector, (args Vector:$a, Vector:$b, Ptr<uint>:$carry), - (seq (IRInt<"vadc", [Vector]> $a, $b, 0):$pair, - (store (and 1, (lshr (xval $pair, 1), 29)), $carry), - (xval $pair, 0))>; -def vadcq_m: Intrinsic<Vector, (args Vector:$inactive, Vector:$a, Vector:$b, - Ptr<uint>:$carry, Predicate:$pred), - (seq (IRInt<"vadc_predicated", [Vector, Predicate]> $inactive, $a, $b, - (shl (load $carry), 29), $pred):$pair, - (store (and 1, (lshr (xval $pair, 1), 29)), $carry), - (xval $pair, 0))>; -def vadciq_m: Intrinsic<Vector, (args Vector:$inactive, Vector:$a, Vector:$b, - Ptr<uint>:$carry, Predicate:$pred), - (seq (IRInt<"vadc_predicated", [Vector, Predicate]> $inactive, $a, $b, - 0, $pred):$pair, - (store (and 1, (lshr (xval $pair, 1), 29)), $carry), - (xval $pair, 0))>; + defm vadc: vadcsbc; + defm vsbc: vadcsbc; +} + +let params = T.Int in { + def vshlcq: Intrinsic< + Vector, (args Vector:$v, Ptr<u32>:$ps, imm_1to32:$imm), + (seq (load $ps):$s, + (IRInt<"vshlc", [Vector]> $v, $s, $imm):$pair, + (store (xval $pair, 0), $ps), + (xval $pair, 1))>; + def vshlcq_m: Intrinsic< + Vector, (args Vector:$v, Ptr<u32>:$ps, imm_1to32:$imm, Predicate:$pred), + (seq (load $ps):$s, + (IRInt<"vshlc_predicated", [Vector, Predicate]> + $v, $s, $imm, $pred):$pair, + (store (xval $pair, 0), $ps), + (xval $pair, 1))>; } multiclass VectorComplexAddPred<dag not_halving, dag angle> { @@ -922,6 +1445,33 @@ multiclass MVEBinaryVectorHoriz64R<dag subtract, dag exchange, string xsuffix> { "vrmlldavha">; } +multiclass VADDV<bit acc, bit pred, string intbase, Type Scalar> { + defvar accArg = !if(acc, (args Scalar:$acc), (args)); + defvar predArg = !if(pred, (args Predicate:$pred), (args)); + defvar intrinsic = !if(pred, + IRInt<intbase # "_predicated", [Vector, Predicate]>, + IRInt<intbase, [Vector]>); + defvar intCG = !con((intrinsic $v, (unsignedflag Scalar)), + !if(pred, (? $pred), (?))); + defvar accCG = !if(acc, (add intCG, $acc), intCG); + + def "": Intrinsic<Scalar, !con(accArg, (args Vector:$v), predArg), accCG>; +} + +let params = T.Int in { +defm vaddvq : VADDV<0, 0, "addv", Scalar32>; +defm vaddvaq : VADDV<1, 0, "addv", Scalar32>; +defm vaddvq_p : VADDV<0, 1, "addv", Scalar32>; +defm vaddvaq_p : VADDV<1, 1, "addv", Scalar32>; +} + +let params = [s32, u32] in { +defm vaddlvq : VADDV<0, 0, "addlv", Scalar64>; +defm vaddlvaq : VADDV<1, 0, "addlv", Scalar64>; +defm vaddlvq_p : VADDV<0, 1, "addlv", Scalar64>; +defm vaddlvaq_p : VADDV<1, 1, "addlv", Scalar64>; +} + let params = T.Int in { def vabavq : Intrinsic<u32, (args u32:$a, Vector:$b, Vector:$c), (IRInt<"vabav", [Vector]> (unsignedflag Scalar), $a, $b, $c)>; @@ -957,6 +1507,25 @@ defm vrmlsldavh : MVEBinaryVectorHoriz64R<V.True, V.False, "">; defm vrmlsldavh : MVEBinaryVectorHoriz64R<V.True, V.True, "x">; } +multiclass vrev_predicated<int revsize> { + defm "" : IntrinsicMX<Vector, (args Vector:$a, Predicate:$pred), + (IRInt<"vrev_predicated", [Vector, Predicate]> + $a, revsize, $pred, $inactive)>; +} + +let params = T.All8 in { + def vrev16q : Intrinsic<Vector, (args Vector:$a), (vrev $a, 16)>; + defm vrev16q: vrev_predicated<16>; +} +let params = !listconcat(T.All8, T.All16) in { + def vrev32q : Intrinsic<Vector, (args Vector:$a), (vrev $a, 32)>; + defm vrev32q: vrev_predicated<32>; +} +let params = T.Usual in { + def vrev64q : Intrinsic<Vector, (args Vector:$a), (vrev $a, 64)>; + defm vrev64q: vrev_predicated<64>; +} + foreach desttype = T.All in { // We want a vreinterpretq between every pair of supported vector types // _except_ that there shouldn't be one from a type to itself. @@ -967,7 +1536,7 @@ foreach desttype = T.All in { !if(!eq(!cast<string>(desttype),!cast<string>(srctype)),[],[srctype]))) in { def "vreinterpretq_" # desttype: Intrinsic< - VecOf<desttype>, (args Vector:$x), (bitcast $x, VecOf<desttype>)>; + VecOf<desttype>, (args Vector:$x), (vreinterpret $x, VecOf<desttype>)>; } } @@ -1002,3 +1571,39 @@ let params = T.All in { def vsetq_lane: Intrinsic<Vector, (args unpromoted<Scalar>:$e, Vector:$v, imm_lane:$lane), (ielt_var $v, $e, $lane)>; } + +foreach desttype = !listconcat(T.Int16, T.Int32, T.Float) in { + defvar is_dest_float = !eq(desttype.kind, "f"); + defvar is_dest_unsigned = !eq(desttype.kind, "u"); + // First immediate operand of the LLVM intrinsic + defvar unsigned_flag = !if(is_dest_float, (unsignedflag Scalar), + !if(is_dest_unsigned, V.True, V.False)); + // For float->int conversions _n and _x_n intrinsics are not polymorphic + // because the signedness of the destination type cannot be inferred. + defvar pnt_nx = !if(is_dest_float, PNT_2Type, PNT_None); + + let params = !if(is_dest_float, + !if(!eq(desttype.size, 16), T.Int16, T.Int32), + !if(!eq(desttype.size, 16), [f16], [f32])) in { + let pnt = pnt_nx in + def "vcvtq_n_"#desttype : Intrinsic<VecOf<desttype>, + (args Vector:$a, imm_1toN:$b), + (IRInt<"vcvt_fix", [VecOf<desttype>, Vector]> unsigned_flag, $a, $b)>; + + defm "vcvtq" : IntrinsicMX<VecOf<desttype>, + (args Vector:$a, imm_1toN:$b, Predicate:$p), + (IRInt<"vcvt_fix_predicated", [VecOf<desttype>, Vector, Predicate]> + unsigned_flag, $inactive, $a, $b, $p), + 1, "_n_"#desttype, PNT_2Type, pnt_nx>; + } +} + +let params = T.Usual in { +let pnt = PNT_NType in +def vbrsrq_n: Intrinsic<Vector, (args Vector:$a, s32:$b), + (IRInt<"vbrsr", [Vector]> $a, $b)>; +defm vbrsrq : IntrinsicMX<Vector, (args Vector:$a, s32:$b, Predicate:$pred), + (IRInt<"vbrsr_predicated", [Vector, Predicate]> + $inactive, $a, $b, $pred), 1, "_n", + PNT_NType, PNT_NType>; +} diff --git a/clang/include/clang/Basic/arm_mve_defs.td b/clang/include/clang/Basic/arm_mve_defs.td index a9afddb57968..4038a18027f8 100644 --- a/clang/include/clang/Basic/arm_mve_defs.td +++ b/clang/include/clang/Basic/arm_mve_defs.td @@ -57,6 +57,10 @@ class CGHelperFn<string func> : IRBuilderBase { // an argument. let prefix = func # "(Builder, "; } +class CGFHelperFn<string func> : IRBuilderBase { + // Like CGHelperFn, but also takes the CodeGenFunction itself. + let prefix = func # "(Builder, this, "; +} def add: IRBuilder<"CreateAdd">; def mul: IRBuilder<"CreateMul">; def not: IRBuilder<"CreateNot">; @@ -89,10 +93,14 @@ def ielt_var: IRBuilder<"CreateInsertElement">; def xelt_var: IRBuilder<"CreateExtractElement">; def trunc: IRBuilder<"CreateTrunc">; def bitcast: IRBuilder<"CreateBitCast">; +def vreinterpret: CGFHelperFn<"ARMMVEVectorReinterpret">; def extend: CGHelperFn<"SignOrZeroExtend"> { let special_params = [IRBuilderIntParam<2, "bool">]; } def zeroinit: IRFunction<"llvm::Constant::getNullValue">; +def int_min: CGHelperFn<"ARMMVEConstantSplat<1,0>">; +def int_max: CGHelperFn<"ARMMVEConstantSplat<0,1>">; +def uint_max: CGHelperFn<"ARMMVEConstantSplat<1,1>">; def undef: IRFunction<"UndefValue::get">; def icmp_eq: IRBuilder<"CreateICmpEQ">; def icmp_ne: IRBuilder<"CreateICmpNE">; @@ -112,6 +120,36 @@ def fcmp_lt: IRBuilder<"CreateFCmpOLT">; def fcmp_le: IRBuilder<"CreateFCmpOLE">; def splat: CGHelperFn<"ARMMVEVectorSplat">; def select: IRBuilder<"CreateSelect">; +def fneg: IRBuilder<"CreateFNeg">; +def sitofp: IRBuilder<"CreateSIToFP">; +def uitofp: IRBuilder<"CreateUIToFP">; +def fptosi: IRBuilder<"CreateFPToSI">; +def fptoui: IRBuilder<"CreateFPToUI">; +def vrev: CGHelperFn<"ARMMVEVectorElementReverse"> { + let special_params = [IRBuilderIntParam<1, "unsigned">]; +} +def unzip: CGHelperFn<"VectorUnzip"> { + let special_params = [IRBuilderIntParam<1, "bool">]; +} +def zip: CGHelperFn<"VectorZip">; + +// Trivial 'codegen' function that just returns its argument. Useful +// for wrapping up a variable name like $foo into a thing you can pass +// around as type 'dag'. +def id: IRBuilderBase { + // All the other cases of IRBuilderBase use 'prefix' to specify a function + // call, including the open parenthesis. MveEmitter puts the closing paren on + // the end. So if we _just_ specify an open paren with no function name + // before it, then the generated C++ code will simply wrap the input value in + // parentheses, returning it unchanged. + let prefix = "("; +} + +// Helper for making boolean flags in IR +def i1: IRBuilderBase { + let prefix = "llvm::ConstantInt::get(Builder.getInt1Ty(), "; + let special_params = [IRBuilderIntParam<0, "bool">]; +} // A node that makes an Address out of a pointer-typed Value, by // providing an alignment as the second argument. @@ -162,6 +200,10 @@ def seq; // and 0 for a signed (or floating) one. def unsignedflag; +// 'bitsize' also takes a scalar type, and expands into an integer +// constant giving its size in bits. +def bitsize; + // If you put CustomCodegen<"foo"> in an intrinsic's codegen field, it // indicates that the IR generation for that intrinsic is done by handwritten // C++ and not autogenerated at all. The effect in the MVE builtin codegen @@ -288,11 +330,15 @@ def SScalar: Signed<Scalar>; def SVector: VecOf<SScalar>; // DblVector expands to a vector of scalars of size twice the size of Scalar. +// DblPredicate expands to a predicate corresponding to DblVector // HalfVector, similarly, expands to a vector of half-sized scalars. And // UHalfVector is a vector of half-sized _unsigned integers_. def DblVector: VecOf<DoubleSize<Scalar>>; -def HalfVector: VecOf<HalfSize<Scalar>>; -def UHalfVector: VecOf<Unsigned<HalfSize<Scalar>>>; +def DblPredicate: PredOf<DoubleSize<Scalar>>; +def HalfScalar: HalfSize<Scalar>; +def HalfVector: VecOf<HalfScalar>; +def UHalfScalar: Unsigned<HalfSize<Scalar>>; +def UHalfVector: VecOf<UHalfScalar>; // Expands to the 32-bit integer of the same signedness as Scalar. def Scalar32: CopyKind<u32, Scalar>; @@ -319,6 +365,7 @@ class IB_EltBit<int base_, Type type_ = Scalar> : ImmediateBounds { int base = base_; Type type = type_; } +def IB_ExtraArg_LaneSize; // ----------------------------------------------------------------------------- // End-user definitions for immediate arguments. @@ -327,11 +374,13 @@ class IB_EltBit<int base_, Type type_ = Scalar> : ImmediateBounds { // intrinsics like vmvnq or vorrq. imm_simd_restrictive has to be an 8-bit // value shifted left by a whole number of bytes; imm_simd_vmvn can also be of // the form 0xXXFF for some byte value XX. -def imm_simd_restrictive : Immediate<u32, IB_UEltValue> { +def imm_simd_restrictive : Immediate<Scalar, IB_UEltValue> { let extra = "ShiftedByte"; + let extraarg = "!lanesize"; } -def imm_simd_vmvn : Immediate<u32, IB_UEltValue> { +def imm_simd_vmvn : Immediate<Scalar, IB_UEltValue> { let extra = "ShiftedByteOrXXFF"; + let extraarg = "!lanesize"; } // imm_1toN can take any value from 1 to N inclusive, where N is the number of @@ -356,7 +405,7 @@ def imm_lane : Immediate<sint, IB_LaneIndex>; def imm_1to32 : Immediate<sint, IB_ConstRange<1, 32>>; // imm_1248 can be 1, 2, 4 or 8. (e.g. vidupq) -def imm_1248 : Immediate<u32, IB_ConstRange<1, 8>> { +def imm_1248 : Immediate<sint, IB_ConstRange<1, 8>> { let extra = "Power2"; } @@ -439,9 +488,16 @@ class Intrinsic<Type ret_, dag args_, dag codegen_> { // True if the builtin has to avoid evaluating its arguments. bit nonEvaluating = 0; + // True if the intrinsic needs only the C header part (no codegen, semantic + // checks, etc). Used for redeclaring MVE intrinsics in the arm_cde.h header. + bit headerOnly = 0; + // Use to override the suffix letter to make e.g.vfooq_p16 // with an override suffix letter of "p". string overrideKindLetter = ""; + + // Name of the architecture extension, used in the Clang builtin name + string builtinExtension = "mve"; } // Sometimes you have to use two separate Intrinsic declarations to @@ -457,37 +513,66 @@ class NameOverride<string basename_> { // A wrapper to define both _m and _x versions of a predicated // intrinsic. +// +// We provide optional parameters to override the polymorphic name +// types separately for the _m and _x variants, because sometimes they +// polymorph differently (typically because the type of the inactive +// parameter can be used as a disambiguator if it's present). multiclass IntrinsicMX<Type rettype, dag arguments, dag cg, int wantXVariant = 1, string nameSuffix = "", + PolymorphicNameType pnt_m = PNT_Type, PolymorphicNameType pnt_x = PNT_Type> { // The _m variant takes an initial parameter called $inactive, which // provides the input value of the output register, i.e. all the // inactive lanes in the predicated operation take their values from // this. - def "_m" # nameSuffix: - Intrinsic<rettype, !con((args rettype:$inactive), arguments), cg>; + def : Intrinsic<rettype, !con((args rettype:$inactive), arguments), cg>, + NameOverride<NAME # "_m" # nameSuffix> { + let pnt = pnt_m; + } foreach unusedVar = !if(!eq(wantXVariant, 1), [1], []<int>) in { // The _x variant leaves off that parameter, and simply uses an // undef value of the same type. + + def : Intrinsic<rettype, arguments, (seq (undef rettype):$inactive, cg)>, + NameOverride<NAME # "_x" # nameSuffix> { + let pnt = pnt_x; + } + } +} + +// Same as above, but with an additional parameter 'basename' which overrides +// the C intrinsic base name +multiclass IntrinsicMXNameOverride<Type rettype, dag arguments, dag cg, + string basename, int wantXVariant = 1, + string nameSuffix = "", + PolymorphicNameType pnt_m = PNT_Type, + PolymorphicNameType pnt_x = PNT_Type> { + def "_m" # nameSuffix: + Intrinsic<rettype, !con((args rettype:$inactive), arguments), cg>, + NameOverride<basename # "_m" # nameSuffix> { + let pnt = pnt_m; + } + + foreach unusedVar = !if(!eq(wantXVariant, 1), [1], []<int>) in { def "_x" # nameSuffix: - Intrinsic<rettype, arguments, (seq (undef rettype):$inactive, cg)> { - // Allow overriding of the polymorphic name type, because - // sometimes the _m and _x variants polymorph differently - // (typically because the type of the inactive parameter can be - // used as a disambiguator if it's present). + Intrinsic<rettype, arguments, (seq (undef rettype):$inactive, cg)>, + NameOverride<basename # "_x" # nameSuffix> { let pnt = pnt_x; } } } + // ----------------------------------------------------------------------------- // Convenience lists of parameter types. 'T' is just a container record, so you // can define a typical intrinsic with 'let Params = T.Usual', or similar, // instead of having to repeat a long list every time. def T { + list<Type> None = [Void]; list<Type> Signed = [s8, s16, s32]; list<Type> Unsigned = [u8, u16, u32]; list<Type> Int = Signed # Unsigned; diff --git a/clang/include/clang/Basic/arm_neon.td b/clang/include/clang/Basic/arm_neon.td index a4dc21b64311..d0269f31c32d 100644 --- a/clang/include/clang/Basic/arm_neon.td +++ b/clang/include/clang/Basic/arm_neon.td @@ -51,39 +51,39 @@ def OP_FMLA_N : Op<(call "vfma", $p0, $p1, (dup $p2))>; def OP_FMLS_N : Op<(call "vfma", $p0, (op "-", $p1), (dup $p2))>; def OP_MLAL_N : Op<(op "+", $p0, (call "vmull", $p1, (dup $p2)))>; def OP_MLSL_N : Op<(op "-", $p0, (call "vmull", $p1, (dup $p2)))>; -def OP_MUL_LN : Op<(op "*", $p0, (splat $p1, $p2))>; -def OP_MULX_LN : Op<(call "vmulx", $p0, (splat $p1, $p2))>; +def OP_MUL_LN : Op<(op "*", $p0, (call_mangled "splat_lane", $p1, $p2))>; +def OP_MULX_LN : Op<(call "vmulx", $p0, (call_mangled "splat_lane", $p1, $p2))>; def OP_MULL_N : Op<(call "vmull", $p0, (dup $p1))>; -def OP_MULL_LN : Op<(call "vmull", $p0, (splat $p1, $p2))>; -def OP_MULLHi_LN: Op<(call "vmull", (call "vget_high", $p0), (splat $p1, $p2))>; -def OP_MLA_LN : Op<(op "+", $p0, (op "*", $p1, (splat $p2, $p3)))>; -def OP_MLS_LN : Op<(op "-", $p0, (op "*", $p1, (splat $p2, $p3)))>; -def OP_MLAL_LN : Op<(op "+", $p0, (call "vmull", $p1, (splat $p2, $p3)))>; +def OP_MULL_LN : Op<(call "vmull", $p0, (call_mangled "splat_lane", $p1, $p2))>; +def OP_MULLHi_LN: Op<(call "vmull", (call "vget_high", $p0), (call_mangled "splat_lane", $p1, $p2))>; +def OP_MLA_LN : Op<(op "+", $p0, (op "*", $p1, (call_mangled "splat_lane", $p2, $p3)))>; +def OP_MLS_LN : Op<(op "-", $p0, (op "*", $p1, (call_mangled "splat_lane", $p2, $p3)))>; +def OP_MLAL_LN : Op<(op "+", $p0, (call "vmull", $p1, (call_mangled "splat_lane", $p2, $p3)))>; def OP_MLALHi_LN: Op<(op "+", $p0, (call "vmull", (call "vget_high", $p1), - (splat $p2, $p3)))>; -def OP_MLSL_LN : Op<(op "-", $p0, (call "vmull", $p1, (splat $p2, $p3)))>; + (call_mangled "splat_lane", $p2, $p3)))>; +def OP_MLSL_LN : Op<(op "-", $p0, (call "vmull", $p1, (call_mangled "splat_lane", $p2, $p3)))>; def OP_MLSLHi_LN : Op<(op "-", $p0, (call "vmull", (call "vget_high", $p1), - (splat $p2, $p3)))>; + (call_mangled "splat_lane", $p2, $p3)))>; def OP_QDMULL_N : Op<(call "vqdmull", $p0, (dup $p1))>; -def OP_QDMULL_LN : Op<(call "vqdmull", $p0, (splat $p1, $p2))>; +def OP_QDMULL_LN : Op<(call "vqdmull", $p0, (call_mangled "splat_lane", $p1, $p2))>; def OP_QDMULLHi_LN : Op<(call "vqdmull", (call "vget_high", $p0), - (splat $p1, $p2))>; + (call_mangled "splat_lane", $p1, $p2))>; def OP_QDMLAL_N : Op<(call "vqdmlal", $p0, $p1, (dup $p2))>; -def OP_QDMLAL_LN : Op<(call "vqdmlal", $p0, $p1, (splat $p2, $p3))>; +def OP_QDMLAL_LN : Op<(call "vqdmlal", $p0, $p1, (call_mangled "splat_lane", $p2, $p3))>; def OP_QDMLALHi_LN : Op<(call "vqdmlal", $p0, (call "vget_high", $p1), - (splat $p2, $p3))>; + (call_mangled "splat_lane", $p2, $p3))>; def OP_QDMLSL_N : Op<(call "vqdmlsl", $p0, $p1, (dup $p2))>; -def OP_QDMLSL_LN : Op<(call "vqdmlsl", $p0, $p1, (splat $p2, $p3))>; +def OP_QDMLSL_LN : Op<(call "vqdmlsl", $p0, $p1, (call_mangled "splat_lane", $p2, $p3))>; def OP_QDMLSLHi_LN : Op<(call "vqdmlsl", $p0, (call "vget_high", $p1), - (splat $p2, $p3))>; + (call_mangled "splat_lane", $p2, $p3))>; def OP_QDMULH_N : Op<(call "vqdmulh", $p0, (dup $p1))>; -def OP_QDMULH_LN : Op<(call "vqdmulh", $p0, (splat $p1, $p2))>; -def OP_QRDMULH_LN : Op<(call "vqrdmulh", $p0, (splat $p1, $p2))>; +def OP_QDMULH_LN : Op<(call "vqdmulh", $p0, (call_mangled "splat_lane", $p1, $p2))>; +def OP_QRDMULH_LN : Op<(call "vqrdmulh", $p0, (call_mangled "splat_lane", $p1, $p2))>; def OP_QRDMULH_N : Op<(call "vqrdmulh", $p0, (dup $p1))>; 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_QRDMLAH_LN : Op<(call "vqadd", $p0, (call "vqrdmulh", $p1, (call_mangled "splat_lane", $p2, $p3)))>; +def OP_QRDMLSH_LN : Op<(call "vqsub", $p0, (call "vqrdmulh", $p1, (call_mangled "splat_lane", $p2, $p3)))>; def OP_FMS_LN : Op<(call "vfma_lane", $p0, (op "-", $p1), $p2, $p3)>; def OP_FMS_LNQ : Op<(call "vfma_laneq", $p0, (op "-", $p1), $p2, $p3)>; def OP_TRN1 : Op<(shuffle $p0, $p1, (interleave (decimate mask0, 2), @@ -115,7 +115,7 @@ def OP_HI : Op<(shuffle $p0, $p0, (highhalf mask0))>; def OP_LO : Op<(shuffle $p0, $p0, (lowhalf mask0))>; def OP_CONC : Op<(shuffle $p0, $p1, (add mask0, mask1))>; def OP_DUP : Op<(dup $p0)>; -def OP_DUP_LN : Op<(splat $p0, $p1)>; +def OP_DUP_LN : Op<(call_mangled "splat_lane", $p0, $p1)>; def OP_SEL : Op<(cast "R", (op "|", (op "&", $p0, (cast $p0, $p1)), (op "&", (op "~", $p0), (cast $p0, $p2))))>; @@ -207,10 +207,10 @@ def OP_SCALAR_HALF_SET_LNQ : Op<(bitcast "float16x8_t", def OP_DOT_LN : Op<(call "vdot", $p0, $p1, - (bitcast $p1, (splat(bitcast "uint32x2_t", $p2), $p3)))>; + (bitcast $p1, (call_mangled "splat_lane", (bitcast "32", $p2), $p3)))>; def OP_DOT_LNQ : Op<(call "vdot", $p0, $p1, - (bitcast $p1, (splat(bitcast "uint32x4_t", $p2), $p3)))>; + (bitcast $p1, (call_mangled "splat_lane", (bitcast "32", $p2), $p3)))>; def OP_FMLAL_LN : Op<(call "vfmlal_low", $p0, $p1, (dup_typed $p1, (call "vget_lane", $p2, $p3)))>; @@ -221,8 +221,85 @@ def OP_FMLAL_LN_Hi : Op<(call "vfmlal_high", $p0, $p1, def OP_FMLSL_LN_Hi : Op<(call "vfmlsl_high", $p0, $p1, (dup_typed $p1, (call "vget_lane", $p2, $p3)))>; +def OP_USDOT_LN + : Op<(call "vusdot", $p0, $p1, + (cast "8", "S", (call_mangled "splat_lane", (bitcast "int32x2_t", $p2), $p3)))>; +def OP_USDOT_LNQ + : Op<(call "vusdot", $p0, $p1, + (cast "8", "S", (call_mangled "splat_lane", (bitcast "int32x4_t", $p2), $p3)))>; + +// sudot splats the second vector and then calls vusdot +def OP_SUDOT_LN + : Op<(call "vusdot", $p0, + (cast "8", "U", (call_mangled "splat_lane", (bitcast "int32x2_t", $p2), $p3)), $p1)>; +def OP_SUDOT_LNQ + : Op<(call "vusdot", $p0, + (cast "8", "U", (call_mangled "splat_lane", (bitcast "int32x4_t", $p2), $p3)), $p1)>; + +def OP_BFDOT_LN + : Op<(call "vbfdot", $p0, $p1, + (bitcast $p1, (call_mangled "splat_lane", (bitcast "float32x2_t", $p2), $p3)))>; + +def OP_BFDOT_LNQ + : Op<(call "vbfdot", $p0, $p1, + (bitcast $p1, (call_mangled "splat_lane", (bitcast "float32x4_t", $p2), $p3)))>; + +def OP_BFMLALB_LN + : Op<(call "vbfmlalb", $p0, $p1, + (dup_typed $p1, (call "vget_lane", $p2, $p3)))>; + +def OP_BFMLALT_LN + : Op<(call "vbfmlalt", $p0, $p1, + (dup_typed $p1, (call "vget_lane", $p2, $p3)))>; + +def OP_VCVT_F32_BF16 + : Op<(bitcast "R", + (call "vshll_n", (bitcast "int16x4_t", $p0), + (literal "int32_t", "16")))>; +def OP_VCVT_F32_BF16_LO + : Op<(call "vcvt_f32_bf16", (call "vget_low", $p0))>; +def OP_VCVT_F32_BF16_HI + : Op<(call "vcvt_f32_bf16", (call "vget_high", $p0))>; + +def OP_VCVT_BF16_F32_LO_A64 + : Op<(call "__a64_vcvtq_low_bf16", $p0)>; +def OP_VCVT_BF16_F32_A64 + : Op<(call "vget_low", (call "__a64_vcvtq_low_bf16", $p0))>; + +def OP_VCVT_BF16_F32_A32 + : Op<(call "__a32_vcvt_bf16", $p0)>; + +def OP_VCVT_BF16_F32_LO_A32 + : Op<(call "vcombine", (cast "bfloat16x4_t", (literal "uint64_t", "0ULL")), + (call "__a32_vcvt_bf16", $p0))>; +def OP_VCVT_BF16_F32_HI_A32 + : Op<(call "vcombine", (call "__a32_vcvt_bf16", $p1), + (call "vget_low", $p0))>; + +def OP_CVT_F32_BF16 + : Op<(bitcast "R", (op "<<", (bitcast "int32_t", $p0), + (literal "int32_t", "16")))>; + +//===----------------------------------------------------------------------===// +// Auxiliary Instructions +//===----------------------------------------------------------------------===// + +// Splat operation - performs a range-checked splat over a vector +def SPLAT : WInst<"splat_lane", ".(!q)I", + "UcUsUicsilPcPsfQUcQUsQUiQcQsQiQPcQPsQflUlQlQUlhdQhQdPlQPl">; +def SPLATQ : WInst<"splat_laneq", ".(!Q)I", + "UcUsUicsilPcPsfQUcQUsQUiQcQsQiQPcQPsQflUlQlQUlhdQhQdPlQPl"> { + let isLaneQ = 1; +} +let ArchGuard = "defined(__ARM_FEATURE_BF16_VECTOR_ARITHMETIC)" in { + def SPLAT_BF : WInst<"splat_lane", ".(!q)I", "bQb">; + def SPLATQ_BF : WInst<"splat_laneq", ".(!Q)I", "bQb"> { + let isLaneQ = 1; + } +} + //===----------------------------------------------------------------------===// -// Instructions +// Intrinsics //===----------------------------------------------------------------------===// //////////////////////////////////////////////////////////////////////////////// @@ -528,9 +605,16 @@ def VMULL_LANE : SOpInst<"vmull_lane", "(>Q)..I", "siUsUi", OP_MULL_LN>; def VQDMULL_N : SOpInst<"vqdmull_n", "(>Q).1", "si", OP_QDMULL_N>; def VQDMULL_LANE : SOpInst<"vqdmull_lane", "(>Q)..I", "si", OP_QDMULL_LN>; def VQDMULH_N : SOpInst<"vqdmulh_n", "..1", "siQsQi", OP_QDMULH_N>; -def VQDMULH_LANE : SOpInst<"vqdmulh_lane", "..qI", "siQsQi", OP_QDMULH_LN>; def VQRDMULH_N : SOpInst<"vqrdmulh_n", "..1", "siQsQi", OP_QRDMULH_N>; + +let ArchGuard = "!defined(__aarch64__)" in { +def VQDMULH_LANE : SOpInst<"vqdmulh_lane", "..qI", "siQsQi", OP_QDMULH_LN>; def VQRDMULH_LANE : SOpInst<"vqrdmulh_lane", "..qI", "siQsQi", OP_QRDMULH_LN>; +} +let ArchGuard = "defined(__aarch64__)" in { +def A64_VQDMULH_LANE : SInst<"vqdmulh_lane", "..(!q)I", "siQsQi">; +def A64_VQRDMULH_LANE : SInst<"vqrdmulh_lane", "..(!q)I", "siQsQi">; +} let ArchGuard = "defined(__ARM_FEATURE_QRDMX)" in { def VQRDMLAH_LANE : SOpInst<"vqrdmlah_lane", "...qI", "siQsQi", OP_QRDMLAH_LN>; @@ -587,11 +671,23 @@ def VZIP : WInst<"vzip", "2..", "csiUcUsUifPcPsQcQsQiQUcQUsQUiQfQPcQPs">; def VUZP : WInst<"vuzp", "2..", "csiUcUsUifPcPsQcQsQiQUcQUsQUiQfQPcQPs">; //////////////////////////////////////////////////////////////////////////////// + +class REINTERPRET_CROSS_SELF<string Types> : + NoTestOpInst<"vreinterpret", "..", Types, OP_REINT> { + let CartesianProductWith = Types; +} + +multiclass REINTERPRET_CROSS_TYPES<string TypesA, string TypesB> { + def AXB: NoTestOpInst<"vreinterpret", "..", TypesA, OP_REINT> { + let CartesianProductWith = TypesB; + } + def BXA: NoTestOpInst<"vreinterpret", "..", TypesB, OP_REINT> { + let CartesianProductWith = TypesA; + } +} + // E.3.31 Vector reinterpret cast operations -def VREINTERPRET - : NoTestOpInst<"vreinterpret", "..", - "csilUcUsUiUlhfPcPsQcQsQiQlQUcQUsQUiQUlQhQfQPcQPs", OP_REINT> { - let CartesianProductOfTypes = 1; +def VREINTERPRET : REINTERPRET_CROSS_SELF<"csilUcUsUiUlhfPcPsQcQsQiQlQUcQUsQUiQUlQhQfQPcQPs"> { let ArchGuard = "!defined(__aarch64__)"; let BigEndianSafe = 1; } @@ -874,16 +970,22 @@ def COPY_LANE : IOpInst<"vcopy_lane", "..I.I", def COPYQ_LANE : IOpInst<"vcopy_lane", "..IqI", "QcQsQiQlQUcQUsQUiQUlQPcQPsQfQdQPl", OP_COPY_LN>; def COPY_LANEQ : IOpInst<"vcopy_laneq", "..IQI", - "csilPcPsPlUcUsUiUlfd", OP_COPY_LN>; + "csilPcPsPlUcUsUiUlfd", OP_COPY_LN> { + let isLaneQ = 1; +} def COPYQ_LANEQ : IOpInst<"vcopy_laneq", "..I.I", - "QcQsQiQlQUcQUsQUiQUlQPcQPsQfQdQPl", OP_COPY_LN>; + "QcQsQiQlQUcQUsQUiQUlQPcQPsQfQdQPl", OP_COPY_LN> { + let isLaneQ = 1; +} //////////////////////////////////////////////////////////////////////////////// // Set all lanes to same value def VDUP_LANE1: WOpInst<"vdup_lane", ".qI", "hdQhQdPlQPl", OP_DUP_LN>; def VDUP_LANE2: WOpInst<"vdup_laneq", ".QI", "csilUcUsUiUlPcPshfdQcQsQiQlQPcQPsQUcQUsQUiQUlQhQfQdPlQPl", - OP_DUP_LN>; + OP_DUP_LN> { + let isLaneQ = 1; +} def DUP_N : WOpInst<"vdup_n", ".1", "dQdPlQPl", OP_DUP>; def MOV_N : WOpInst<"vmov_n", ".1", "dQdPlQPl", OP_DUP>; @@ -899,38 +1001,60 @@ def CREATE : NoTestOpInst<"vcreate", ".(IU>)", "dPl", OP_CAST> { //////////////////////////////////////////////////////////////////////////////// def VMLA_LANEQ : IOpInst<"vmla_laneq", "...QI", - "siUsUifQsQiQUsQUiQf", OP_MLA_LN>; + "siUsUifQsQiQUsQUiQf", OP_MLA_LN> { + let isLaneQ = 1; +} def VMLS_LANEQ : IOpInst<"vmls_laneq", "...QI", - "siUsUifQsQiQUsQUiQf", OP_MLS_LN>; + "siUsUifQsQiQUsQUiQf", OP_MLS_LN> { + let isLaneQ = 1; +} def VFMA_LANE : IInst<"vfma_lane", "...qI", "fdQfQd">; def VFMA_LANEQ : IInst<"vfma_laneq", "...QI", "fdQfQd"> { let isLaneQ = 1; } def VFMS_LANE : IOpInst<"vfms_lane", "...qI", "fdQfQd", OP_FMS_LN>; -def VFMS_LANEQ : IOpInst<"vfms_laneq", "...QI", "fdQfQd", OP_FMS_LNQ>; +def VFMS_LANEQ : IOpInst<"vfms_laneq", "...QI", "fdQfQd", OP_FMS_LNQ> { + let isLaneQ = 1; +} -def VMLAL_LANEQ : SOpInst<"vmlal_laneq", "(>Q)(>Q).QI", "siUsUi", OP_MLAL_LN>; +def VMLAL_LANEQ : SOpInst<"vmlal_laneq", "(>Q)(>Q).QI", "siUsUi", OP_MLAL_LN> { + let isLaneQ = 1; +} def VMLAL_HIGH_LANE : SOpInst<"vmlal_high_lane", "(>Q)(>Q)Q.I", "siUsUi", OP_MLALHi_LN>; def VMLAL_HIGH_LANEQ : SOpInst<"vmlal_high_laneq", "(>Q)(>Q)QQI", "siUsUi", - OP_MLALHi_LN>; -def VMLSL_LANEQ : SOpInst<"vmlsl_laneq", "(>Q)(>Q).QI", "siUsUi", OP_MLSL_LN>; + OP_MLALHi_LN> { + let isLaneQ = 1; +} +def VMLSL_LANEQ : SOpInst<"vmlsl_laneq", "(>Q)(>Q).QI", "siUsUi", OP_MLSL_LN> { + let isLaneQ = 1; +} def VMLSL_HIGH_LANE : SOpInst<"vmlsl_high_lane", "(>Q)(>Q)Q.I", "siUsUi", OP_MLSLHi_LN>; def VMLSL_HIGH_LANEQ : SOpInst<"vmlsl_high_laneq", "(>Q)(>Q)QQI", "siUsUi", - OP_MLSLHi_LN>; + OP_MLSLHi_LN> { + let isLaneQ = 1; +} -def VQDMLAL_LANEQ : SOpInst<"vqdmlal_laneq", "(>Q)(>Q).QI", "si", OP_QDMLAL_LN>; +def VQDMLAL_LANEQ : SOpInst<"vqdmlal_laneq", "(>Q)(>Q).QI", "si", OP_QDMLAL_LN> { + let isLaneQ = 1; +} def VQDMLAL_HIGH_LANE : SOpInst<"vqdmlal_high_lane", "(>Q)(>Q)Q.I", "si", OP_QDMLALHi_LN>; def VQDMLAL_HIGH_LANEQ : SOpInst<"vqdmlal_high_laneq", "(>Q)(>Q)QQI", "si", - OP_QDMLALHi_LN>; -def VQDMLSL_LANEQ : SOpInst<"vqdmlsl_laneq", "(>Q)(>Q).QI", "si", OP_QDMLSL_LN>; + OP_QDMLALHi_LN> { + let isLaneQ = 1; +} +def VQDMLSL_LANEQ : SOpInst<"vqdmlsl_laneq", "(>Q)(>Q).QI", "si", OP_QDMLSL_LN> { + let isLaneQ = 1; +} def VQDMLSL_HIGH_LANE : SOpInst<"vqdmlsl_high_lane", "(>Q)(>Q)Q.I", "si", OP_QDMLSLHi_LN>; def VQDMLSL_HIGH_LANEQ : SOpInst<"vqdmlsl_high_laneq", "(>Q)(>Q)QQI", "si", - OP_QDMLSLHi_LN>; + OP_QDMLSLHi_LN> { + let isLaneQ = 1; +} // Newly add double parameter for vmul_lane in aarch64 // Note: d type is handled by SCALAR_VMUL_LANE @@ -938,31 +1062,48 @@ def VMUL_LANE_A64 : IOpInst<"vmul_lane", "..qI", "Qd", OP_MUL_LN>; // Note: d type is handled by SCALAR_VMUL_LANEQ def VMUL_LANEQ : IOpInst<"vmul_laneq", "..QI", - "sifUsUiQsQiQUsQUiQfQd", OP_MUL_LN>; -def VMULL_LANEQ : SOpInst<"vmull_laneq", "(>Q).QI", "siUsUi", OP_MULL_LN>; + "sifUsUiQsQiQUsQUiQfQd", OP_MUL_LN> { + let isLaneQ = 1; +} +def VMULL_LANEQ : SOpInst<"vmull_laneq", "(>Q).QI", "siUsUi", OP_MULL_LN> { + let isLaneQ = 1; +} def VMULL_HIGH_LANE : SOpInst<"vmull_high_lane", "(>Q)Q.I", "siUsUi", OP_MULLHi_LN>; def VMULL_HIGH_LANEQ : SOpInst<"vmull_high_laneq", "(>Q)QQI", "siUsUi", - OP_MULLHi_LN>; + OP_MULLHi_LN> { + let isLaneQ = 1; +} -def VQDMULL_LANEQ : SOpInst<"vqdmull_laneq", "(>Q).QI", "si", OP_QDMULL_LN>; +def VQDMULL_LANEQ : SOpInst<"vqdmull_laneq", "(>Q).QI", "si", OP_QDMULL_LN> { + let isLaneQ = 1; +} def VQDMULL_HIGH_LANE : SOpInst<"vqdmull_high_lane", "(>Q)Q.I", "si", OP_QDMULLHi_LN>; def VQDMULL_HIGH_LANEQ : SOpInst<"vqdmull_high_laneq", "(>Q)QQI", "si", - OP_QDMULLHi_LN>; - -def VQDMULH_LANEQ : SOpInst<"vqdmulh_laneq", "..QI", "siQsQi", OP_QDMULH_LN>; -def VQRDMULH_LANEQ : SOpInst<"vqrdmulh_laneq", "..QI", "siQsQi", OP_QRDMULH_LN>; + OP_QDMULLHi_LN> { + let isLaneQ = 1; +} +let isLaneQ = 1 in { +def VQDMULH_LANEQ : SInst<"vqdmulh_laneq", "..QI", "siQsQi">; +def VQRDMULH_LANEQ : SInst<"vqrdmulh_laneq", "..QI", "siQsQi">; +} let ArchGuard = "defined(__ARM_FEATURE_QRDMX) && defined(__aarch64__)" in { -def VQRDMLAH_LANEQ : SOpInst<"vqrdmlah_laneq", "...QI", "siQsQi", OP_QRDMLAH_LN>; -def VQRDMLSH_LANEQ : SOpInst<"vqrdmlsh_laneq", "...QI", "siQsQi", OP_QRDMLSH_LN>; +def VQRDMLAH_LANEQ : SOpInst<"vqrdmlah_laneq", "...QI", "siQsQi", OP_QRDMLAH_LN> { + let isLaneQ = 1; +} +def VQRDMLSH_LANEQ : SOpInst<"vqrdmlsh_laneq", "...QI", "siQsQi", OP_QRDMLSH_LN> { + let isLaneQ = 1; +} } // Note: d type implemented by SCALAR_VMULX_LANE def VMULX_LANE : IOpInst<"vmulx_lane", "..qI", "fQfQd", OP_MULX_LN>; // Note: d type is implemented by SCALAR_VMULX_LANEQ -def VMULX_LANEQ : IOpInst<"vmulx_laneq", "..QI", "fQfQd", OP_MULX_LN>; +def VMULX_LANEQ : IOpInst<"vmulx_laneq", "..QI", "fQfQd", OP_MULX_LN> { + let isLaneQ = 1; +} //////////////////////////////////////////////////////////////////////////////// // Across vectors class @@ -1095,12 +1236,9 @@ def VQTBX4_A64 : WInst<"vqtbx4", "..(4Q)U", "UccPcQUcQcQPc">; // NeonEmitter implicitly takes the cartesian product of the type string with // itself during generation so, unlike all other intrinsics, this one should // include *all* types, not just additional ones. -def VVREINTERPRET - : NoTestOpInst<"vreinterpret", "..", - "csilUcUsUiUlhfdPcPsPlQcQsQiQlQUcQUsQUiQUlQhQfQdQPcQPsQPlQPk", OP_REINT> { - let CartesianProductOfTypes = 1; - let BigEndianSafe = 1; +def VVREINTERPRET : REINTERPRET_CROSS_SELF<"csilUcUsUiUlhfdPcPsPlQcQsQiQlQUcQUsQUiQUlQhQfQdQPcQPsQPlQPk"> { let ArchGuard = "__ARM_ARCH >= 8 && defined(__aarch64__)"; + let BigEndianSafe = 1; } //////////////////////////////////////////////////////////////////////////////// @@ -1372,11 +1510,15 @@ def SCALAR_UQXTN : SInst<"vqmovn", "(1<)1", "SUsSUiSUl">; // Scalar Floating Point multiply (scalar, by element) def SCALAR_FMUL_LANE : IOpInst<"vmul_lane", "11.I", "SfSd", OP_SCALAR_MUL_LN>; -def SCALAR_FMUL_LANEQ : IOpInst<"vmul_laneq", "11QI", "SfSd", OP_SCALAR_MUL_LN>; +def SCALAR_FMUL_LANEQ : IOpInst<"vmul_laneq", "11QI", "SfSd", OP_SCALAR_MUL_LN> { + let isLaneQ = 1; +} // Scalar Floating Point multiply extended (scalar, by element) def SCALAR_FMULX_LANE : IOpInst<"vmulx_lane", "11.I", "SfSd", OP_SCALAR_MULX_LN>; -def SCALAR_FMULX_LANEQ : IOpInst<"vmulx_laneq", "11QI", "SfSd", OP_SCALAR_MULX_LN>; +def SCALAR_FMULX_LANEQ : IOpInst<"vmulx_laneq", "11QI", "SfSd", OP_SCALAR_MULX_LN> { + let isLaneQ = 1; +} def SCALAR_VMUL_N : IInst<"vmul_n", "..1", "d">; @@ -1392,48 +1534,70 @@ def SCALAR_VMUL_LANEQ : IInst<"vmul_laneq", "..QI", "d"> { def SCALAR_VMULX_LANE : IOpInst<"vmulx_lane", "..qI", "d", OP_SCALAR_VMULX_LN>; // VMULX_LANEQ d type implemented using scalar vmulx_laneq -def SCALAR_VMULX_LANEQ : IOpInst<"vmulx_laneq", "..QI", "d", OP_SCALAR_VMULX_LNQ>; +def SCALAR_VMULX_LANEQ : IOpInst<"vmulx_laneq", "..QI", "d", OP_SCALAR_VMULX_LNQ> { + let isLaneQ = 1; +} // Scalar Floating Point fused multiply-add (scalar, by element) def SCALAR_FMLA_LANE : IInst<"vfma_lane", "111.I", "SfSd">; -def SCALAR_FMLA_LANEQ : IInst<"vfma_laneq", "111QI", "SfSd">; +def SCALAR_FMLA_LANEQ : IInst<"vfma_laneq", "111QI", "SfSd"> { + let isLaneQ = 1; +} // Scalar Floating Point fused multiply-subtract (scalar, by element) def SCALAR_FMLS_LANE : IOpInst<"vfms_lane", "111.I", "SfSd", OP_FMS_LN>; -def SCALAR_FMLS_LANEQ : IOpInst<"vfms_laneq", "111QI", "SfSd", OP_FMS_LNQ>; +def SCALAR_FMLS_LANEQ : IOpInst<"vfms_laneq", "111QI", "SfSd", OP_FMS_LNQ> { + let isLaneQ = 1; +} // Signed Saturating Doubling Multiply Long (scalar by element) def SCALAR_SQDMULL_LANE : SOpInst<"vqdmull_lane", "(1>)1.I", "SsSi", OP_SCALAR_QDMULL_LN>; -def SCALAR_SQDMULL_LANEQ : SOpInst<"vqdmull_laneq", "(1>)1QI", "SsSi", OP_SCALAR_QDMULL_LN>; +def SCALAR_SQDMULL_LANEQ : SOpInst<"vqdmull_laneq", "(1>)1QI", "SsSi", OP_SCALAR_QDMULL_LN> { + let isLaneQ = 1; +} // Signed Saturating Doubling Multiply-Add Long (scalar by element) def SCALAR_SQDMLAL_LANE : SInst<"vqdmlal_lane", "(1>)(1>)1.I", "SsSi">; -def SCALAR_SQDMLAL_LANEQ : SInst<"vqdmlal_laneq", "(1>)(1>)1QI", "SsSi">; +def SCALAR_SQDMLAL_LANEQ : SInst<"vqdmlal_laneq", "(1>)(1>)1QI", "SsSi"> { + let isLaneQ = 1; +} // Signed Saturating Doubling Multiply-Subtract Long (scalar by element) def SCALAR_SQDMLS_LANE : SInst<"vqdmlsl_lane", "(1>)(1>)1.I", "SsSi">; -def SCALAR_SQDMLS_LANEQ : SInst<"vqdmlsl_laneq", "(1>)(1>)1QI", "SsSi">; +def SCALAR_SQDMLS_LANEQ : SInst<"vqdmlsl_laneq", "(1>)(1>)1QI", "SsSi"> { + let isLaneQ = 1; +} // Scalar Integer Saturating Doubling Multiply Half High (scalar by element) def SCALAR_SQDMULH_LANE : SOpInst<"vqdmulh_lane", "11.I", "SsSi", OP_SCALAR_QDMULH_LN>; -def SCALAR_SQDMULH_LANEQ : SOpInst<"vqdmulh_laneq", "11QI", "SsSi", OP_SCALAR_QDMULH_LN>; +def SCALAR_SQDMULH_LANEQ : SOpInst<"vqdmulh_laneq", "11QI", "SsSi", OP_SCALAR_QDMULH_LN> { + let isLaneQ = 1; +} // Scalar Integer Saturating Rounding Doubling Multiply Half High def SCALAR_SQRDMULH_LANE : SOpInst<"vqrdmulh_lane", "11.I", "SsSi", OP_SCALAR_QRDMULH_LN>; -def SCALAR_SQRDMULH_LANEQ : SOpInst<"vqrdmulh_laneq", "11QI", "SsSi", OP_SCALAR_QRDMULH_LN>; +def SCALAR_SQRDMULH_LANEQ : SOpInst<"vqrdmulh_laneq", "11QI", "SsSi", OP_SCALAR_QRDMULH_LN> { + let isLaneQ = 1; +} 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", "111.I", "SsSi", OP_SCALAR_QRDMLAH_LN>; -def SCALAR_SQRDMLAH_LANEQ : SOpInst<"vqrdmlah_laneq", "111QI", "SsSi", OP_SCALAR_QRDMLAH_LN>; +def SCALAR_SQRDMLAH_LANEQ : SOpInst<"vqrdmlah_laneq", "111QI", "SsSi", OP_SCALAR_QRDMLAH_LN> { + let isLaneQ = 1; +} // Signed Saturating Rounding Doubling Multiply Subtract Returning High Half def SCALAR_SQRDMLSH_LANE : SOpInst<"vqrdmlsh_lane", "111.I", "SsSi", OP_SCALAR_QRDMLSH_LN>; -def SCALAR_SQRDMLSH_LANEQ : SOpInst<"vqrdmlsh_laneq", "111QI", "SsSi", OP_SCALAR_QRDMLSH_LN>; +def SCALAR_SQRDMLSH_LANEQ : SOpInst<"vqrdmlsh_laneq", "111QI", "SsSi", OP_SCALAR_QRDMLSH_LN> { + let isLaneQ = 1; +} } def SCALAR_VDUP_LANE : IInst<"vdup_lane", "1.I", "ScSsSiSlSfSdSUcSUsSUiSUlSPcSPs">; -def SCALAR_VDUP_LANEQ : IInst<"vdup_laneq", "1QI", "ScSsSiSlSfSdSUcSUsSUiSUlSPcSPs">; +def SCALAR_VDUP_LANEQ : IInst<"vdup_laneq", "1QI", "ScSsSiSlSfSdSUcSUsSUiSUlSPcSPs"> { + let isLaneQ = 1; +} } // ARMv8.2-A FP16 vector intrinsics for A32/A64. @@ -1597,36 +1761,52 @@ let ArchGuard = "defined(__ARM_FEATURE_FP16_VECTOR_ARITHMETIC) && defined(__aarc // FMA lane def VFMA_LANEH : IInst<"vfma_lane", "...qI", "hQh">; - def VFMA_LANEQH : IInst<"vfma_laneq", "...QI", "hQh">; + def VFMA_LANEQH : IInst<"vfma_laneq", "...QI", "hQh"> { + let isLaneQ = 1; + } // FMA lane with scalar argument def FMLA_NH : SOpInst<"vfma_n", "...1", "hQh", OP_FMLA_N>; // Scalar floating point fused multiply-add (scalar, by element) def SCALAR_FMLA_LANEH : IInst<"vfma_lane", "111.I", "Sh">; - def SCALAR_FMLA_LANEQH : IInst<"vfma_laneq", "111QI", "Sh">; + def SCALAR_FMLA_LANEQH : IInst<"vfma_laneq", "111QI", "Sh"> { + let isLaneQ = 1; + } // FMS lane def VFMS_LANEH : IOpInst<"vfms_lane", "...qI", "hQh", OP_FMS_LN>; - def VFMS_LANEQH : IOpInst<"vfms_laneq", "...QI", "hQh", OP_FMS_LNQ>; + def VFMS_LANEQH : IOpInst<"vfms_laneq", "...QI", "hQh", OP_FMS_LNQ> { + let isLaneQ = 1; + } // FMS lane with scalar argument def FMLS_NH : SOpInst<"vfms_n", "...1", "hQh", OP_FMLS_N>; // Scalar floating foint fused multiply-subtract (scalar, by element) def SCALAR_FMLS_LANEH : IOpInst<"vfms_lane", "111.I", "Sh", OP_FMS_LN>; - def SCALAR_FMLS_LANEQH : IOpInst<"vfms_laneq", "111QI", "Sh", OP_FMS_LNQ>; + def SCALAR_FMLS_LANEQH : IOpInst<"vfms_laneq", "111QI", "Sh", OP_FMS_LNQ> { + let isLaneQ = 1; + } // Mul lane - def VMUL_LANEQH : IOpInst<"vmul_laneq", "..QI", "hQh", OP_MUL_LN>; + def VMUL_LANEQH : IOpInst<"vmul_laneq", "..QI", "hQh", OP_MUL_LN> { + let isLaneQ = 1; + } // Scalar floating point multiply (scalar, by element) def SCALAR_FMUL_LANEH : IOpInst<"vmul_lane", "11.I", "Sh", OP_SCALAR_MUL_LN>; - def SCALAR_FMUL_LANEQH : IOpInst<"vmul_laneq", "11QI", "Sh", OP_SCALAR_MUL_LN>; + def SCALAR_FMUL_LANEQH : IOpInst<"vmul_laneq", "11QI", "Sh", OP_SCALAR_MUL_LN> { + let isLaneQ = 1; + } // Mulx lane def VMULX_LANEH : IOpInst<"vmulx_lane", "..qI", "hQh", OP_MULX_LN>; - def VMULX_LANEQH : IOpInst<"vmulx_laneq", "..QI", "hQh", OP_MULX_LN>; + def VMULX_LANEQH : IOpInst<"vmulx_laneq", "..QI", "hQh", OP_MULX_LN> { + let isLaneQ = 1; + } def VMULX_NH : IOpInst<"vmulx_n", "..1", "hQh", OP_MULX_N>; // Scalar floating point mulx (scalar, by element) def SCALAR_FMULX_LANEH : IInst<"vmulx_lane", "11.I", "Sh">; - def SCALAR_FMULX_LANEQH : IInst<"vmulx_laneq", "11QI", "Sh">; + def SCALAR_FMULX_LANEQH : IInst<"vmulx_laneq", "11QI", "Sh"> { + let isLaneQ = 1; + } // ARMv8.2-A FP16 reduction vector intrinsics. def VMAXVH : SInst<"vmaxv", "1.", "hQh">; @@ -1643,7 +1823,9 @@ let ArchGuard = "defined(__ARM_FEATURE_FP16_VECTOR_ARITHMETIC) && defined(__aarc def VUZP2H : SOpInst<"vuzp2", "...", "hQh", OP_UZP2>; def SCALAR_VDUP_LANEH : IInst<"vdup_lane", "1.I", "Sh">; - def SCALAR_VDUP_LANEQH : IInst<"vdup_laneq", "1QI", "Sh">; + def SCALAR_VDUP_LANEQH : IInst<"vdup_laneq", "1QI", "Sh"> { + let isLaneQ = 1; + } } // v8.2-A dot product instructions. @@ -1653,7 +1835,9 @@ let ArchGuard = "defined(__ARM_FEATURE_DOTPROD)" in { } let ArchGuard = "defined(__ARM_FEATURE_DOTPROD) && defined(__aarch64__)" in { // Variants indexing into a 128-bit vector are A64 only. - def UDOT_LANEQ : SOpInst<"vdot_laneq", "..(<<)(<<Q)I", "iUiQiQUi", OP_DOT_LNQ>; + def UDOT_LANEQ : SOpInst<"vdot_laneq", "..(<<)(<<Q)I", "iUiQiQUi", OP_DOT_LNQ> { + let isLaneQ = 1; + } } // v8.2-A FP16 fused multiply-add long instructions. @@ -1668,10 +1852,54 @@ let ArchGuard = "defined(__ARM_FEATURE_FP16FML) && defined(__aarch64__)" in { def VFMLAL_LANE_HIGH : SOpInst<"vfmlal_lane_high", "(F>)(F>)F(Fq)I", "hQh", OP_FMLAL_LN_Hi>; def VFMLSL_LANE_HIGH : SOpInst<"vfmlsl_lane_high", "(F>)(F>)F(Fq)I", "hQh", OP_FMLSL_LN_Hi>; - def VFMLAL_LANEQ_LOW : SOpInst<"vfmlal_laneq_low", "(F>)(F>)F(FQ)I", "hQh", OP_FMLAL_LN>; - def VFMLSL_LANEQ_LOW : SOpInst<"vfmlsl_laneq_low", "(F>)(F>)F(FQ)I", "hQh", OP_FMLSL_LN>; - def VFMLAL_LANEQ_HIGH : SOpInst<"vfmlal_laneq_high", "(F>)(F>)F(FQ)I", "hQh", OP_FMLAL_LN_Hi>; - def VFMLSL_LANEQ_HIGH : SOpInst<"vfmlsl_laneq_high", "(F>)(F>)F(FQ)I", "hQh", OP_FMLSL_LN_Hi>; + def VFMLAL_LANEQ_LOW : SOpInst<"vfmlal_laneq_low", "(F>)(F>)F(FQ)I", "hQh", OP_FMLAL_LN> { + let isLaneQ = 1; + } + def VFMLSL_LANEQ_LOW : SOpInst<"vfmlsl_laneq_low", "(F>)(F>)F(FQ)I", "hQh", OP_FMLSL_LN> { + let isLaneQ = 1; + } + def VFMLAL_LANEQ_HIGH : SOpInst<"vfmlal_laneq_high", "(F>)(F>)F(FQ)I", "hQh", OP_FMLAL_LN_Hi> { + let isLaneQ = 1; + } + def VFMLSL_LANEQ_HIGH : SOpInst<"vfmlsl_laneq_high", "(F>)(F>)F(FQ)I", "hQh", OP_FMLSL_LN_Hi> { + let isLaneQ = 1; + } +} + +let ArchGuard = "defined(__ARM_FEATURE_MATMUL_INT8)" in { + def VMMLA : SInst<"vmmla", "..(<<)(<<)", "QUiQi">; + def VUSMMLA : SInst<"vusmmla", "..(<<U)(<<)", "Qi">; + + def VUSDOT : SInst<"vusdot", "..(<<U)(<<)", "iQi">; + + def VUSDOT_LANE : SOpInst<"vusdot_lane", "..(<<U)(<<q)I", "iQi", OP_USDOT_LN>; + def VSUDOT_LANE : SOpInst<"vsudot_lane", "..(<<)(<<qU)I", "iQi", OP_SUDOT_LN>; + + let ArchGuard = "defined(__aarch64__)" in { + let isLaneQ = 1 in { + def VUSDOT_LANEQ : SOpInst<"vusdot_laneq", "..(<<U)(<<Q)I", "iQi", OP_USDOT_LNQ>; + def VSUDOT_LANEQ : SOpInst<"vsudot_laneq", "..(<<)(<<QU)I", "iQi", OP_SUDOT_LNQ>; + } + } +} + +let ArchGuard = "defined(__ARM_FEATURE_BF16_VECTOR_ARITHMETIC)" in { + def VDOT_BF : SInst<"vbfdot", "..BB", "fQf">; + def VDOT_LANE_BF : SOpInst<"vbfdot_lane", "..B(Bq)I", "fQf", OP_BFDOT_LN>; + def VDOT_LANEQ_BF : SOpInst<"vbfdot_laneq", "..B(BQ)I", "fQf", OP_BFDOT_LNQ> { + let isLaneQ = 1; + } + + def VFMMLA_BF : SInst<"vbfmmla", "..BB", "Qf">; + + def VFMLALB_BF : SInst<"vbfmlalb", "..BB", "Qf">; + def VFMLALT_BF : SInst<"vbfmlalt", "..BB", "Qf">; + + def VFMLALB_LANE_BF : SOpInst<"vbfmlalb_lane", "..B(Bq)I", "Qf", OP_BFMLALB_LN>; + def VFMLALB_LANEQ_BF : SOpInst<"vbfmlalb_laneq", "..B(BQ)I", "Qf", OP_BFMLALB_LN>; + + def VFMLALT_LANE_BF : SOpInst<"vbfmlalt_lane", "..B(Bq)I", "Qf", OP_BFMLALT_LN>; + def VFMLALT_LANEQ_BF : SOpInst<"vbfmlalt_laneq", "..B(BQ)I", "Qf", OP_BFMLALT_LN>; } // v8.3-A Vector complex addition intrinsics @@ -1690,4 +1918,102 @@ let ArchGuard = "defined(__ARM_FEATURE_COMPLEX)" in { let ArchGuard = "defined(__ARM_FEATURE_COMPLEX) && defined(__aarch64__)" in { def VCADDQ_ROT90_FP64 : SInst<"vcaddq_rot90", "QQQ", "d">; def VCADDQ_ROT270_FP64 : SInst<"vcaddq_rot270", "QQQ", "d">; -}
\ No newline at end of file +} + +// V8.2-A BFloat intrinsics +let ArchGuard = "defined(__ARM_FEATURE_BF16_VECTOR_ARITHMETIC)" in { + def VCREATE_BF : NoTestOpInst<"vcreate", ".(IU>)", "b", OP_CAST> { + let BigEndianSafe = 1; + } + + def VDUP_N_BF : WOpInst<"vdup_n", ".1", "bQb", OP_DUP>; + + def VDUP_LANE_BF : WOpInst<"vdup_lane", ".qI", "bQb", OP_DUP_LN>; + def VDUP_LANEQ_BF: WOpInst<"vdup_laneq", ".QI", "bQb", OP_DUP_LN> { + let isLaneQ = 1; + } + + def VCOMBINE_BF : NoTestOpInst<"vcombine", "Q..", "b", OP_CONC>; + + def VGET_HIGH_BF : NoTestOpInst<"vget_high", ".Q", "b", OP_HI>; + def VGET_LOW_BF : NoTestOpInst<"vget_low", ".Q", "b", OP_LO>; + + def VGET_LANE_BF : IInst<"vget_lane", "1.I", "bQb">; + def VSET_LANE_BF : IInst<"vset_lane", ".1.I", "bQb">; + def SCALAR_VDUP_LANE_BF : IInst<"vdup_lane", "1.I", "Sb">; + def SCALAR_VDUP_LANEQ_BF : IInst<"vdup_laneq", "1QI", "Sb"> { + let isLaneQ = 1; + } + + def VLD1_BF : WInst<"vld1", ".(c*!)", "bQb">; + def VLD2_BF : WInst<"vld2", "2(c*!)", "bQb">; + def VLD3_BF : WInst<"vld3", "3(c*!)", "bQb">; + def VLD4_BF : WInst<"vld4", "4(c*!)", "bQb">; + + def VST1_BF : WInst<"vst1", "v*(.!)", "bQb">; + def VST2_BF : WInst<"vst2", "v*(2!)", "bQb">; + def VST3_BF : WInst<"vst3", "v*(3!)", "bQb">; + def VST4_BF : WInst<"vst4", "v*(4!)", "bQb">; + + def VLD1_X2_BF : WInst<"vld1_x2", "2(c*!)", "bQb">; + def VLD1_X3_BF : WInst<"vld1_x3", "3(c*!)", "bQb">; + def VLD1_X4_BF : WInst<"vld1_x4", "4(c*!)", "bQb">; + + def VST1_X2_BF : WInst<"vst1_x2", "v*(2!)", "bQb">; + def VST1_X3_BF : WInst<"vst1_x3", "v*(3!)", "bQb">; + def VST1_X4_BF : WInst<"vst1_x4", "v*(4!)", "bQb">; + + def VLD1_LANE_BF : WInst<"vld1_lane", ".(c*!).I", "bQb">; + def VLD2_LANE_BF : WInst<"vld2_lane", "2(c*!)2I", "bQb">; + def VLD3_LANE_BF : WInst<"vld3_lane", "3(c*!)3I", "bQb">; + def VLD4_LANE_BF : WInst<"vld4_lane", "4(c*!)4I", "bQb">; + def VST1_LANE_BF : WInst<"vst1_lane", "v*(.!)I", "bQb">; + def VST2_LANE_BF : WInst<"vst2_lane", "v*(2!)I", "bQb">; + def VST3_LANE_BF : WInst<"vst3_lane", "v*(3!)I", "bQb">; + def VST4_LANE_BF : WInst<"vst4_lane", "v*(4!)I", "bQb">; + + def VLD1_DUP_BF : WInst<"vld1_dup", ".(c*!)", "bQb">; + def VLD2_DUP_BF : WInst<"vld2_dup", "2(c*!)", "bQb">; + def VLD3_DUP_BF : WInst<"vld3_dup", "3(c*!)", "bQb">; + def VLD4_DUP_BF : WInst<"vld4_dup", "4(c*!)", "bQb">; + + def VCVT_F32_BF16 : SOpInst<"vcvt_f32_bf16", "(F>)(Bq!)", "Qb", OP_VCVT_F32_BF16>; + def VCVT_LOW_F32_BF16 : SOpInst<"vcvt_low_f32", "(F>)(BQ!)", "Qb", OP_VCVT_F32_BF16_LO>; + def VCVT_HIGH_F32_BF16 : SOpInst<"vcvt_high_f32", "(F>)(BQ!)", "Qb", OP_VCVT_F32_BF16_HI>; + + def SCALAR_CVT_BF16_F32 : SInst<"vcvth_bf16", "(1B)1", "f">; + def SCALAR_CVT_F32_BF16 : SOpInst<"vcvtah_f32", "(1F>)(1!)", "b", OP_CVT_F32_BF16>; +} + +let ArchGuard = "defined(__ARM_FEATURE_BF16_VECTOR_ARITHMETIC) && !defined(__aarch64__)" in { + def VCVT_BF16_F32_A32_INTERNAL : WInst<"__a32_vcvt_bf16", "BQ", "f">; + def VCVT_BF16_F32_A32 : SOpInst<"vcvt_bf16", "BQ", "f", OP_VCVT_BF16_F32_A32>; + def VCVT_LOW_BF16_F32_A32 : SOpInst<"vcvt_low_bf16", "BQ", "Qf", OP_VCVT_BF16_F32_LO_A32>; + def VCVT_HIGH_BF16_F32_A32 : SOpInst<"vcvt_high_bf16", "BBQ", "Qf", OP_VCVT_BF16_F32_HI_A32>; +} + +let ArchGuard = "defined(__ARM_FEATURE_BF16_VECTOR_ARITHMETIC) && defined(__aarch64__)" in { + def VCVT_LOW_BF16_F32_A64_INTERNAL : WInst<"__a64_vcvtq_low_bf16", "BQ", "Hf">; + def VCVT_LOW_BF16_F32_A64 : SOpInst<"vcvt_low_bf16", "BQ", "Qf", OP_VCVT_BF16_F32_LO_A64>; + def VCVT_HIGH_BF16_F32_A64 : SInst<"vcvt_high_bf16", "BBQ", "Qf">; + def VCVT_BF16_F32 : SOpInst<"vcvt_bf16", "BQ", "f", OP_VCVT_BF16_F32_A64>; + + def COPY_LANE_BF16 : IOpInst<"vcopy_lane", "..I.I", "b", OP_COPY_LN>; + def COPYQ_LANE_BF16 : IOpInst<"vcopy_lane", "..IqI", "Qb", OP_COPY_LN>; + def COPY_LANEQ_BF16 : IOpInst<"vcopy_laneq", "..IQI", "b", OP_COPY_LN>; + def COPYQ_LANEQ_BF16 : IOpInst<"vcopy_laneq", "..I.I", "Qb", OP_COPY_LN>; +} + +let ArchGuard = "defined(__ARM_FEATURE_BF16) && !defined(__aarch64__)" in { + let BigEndianSafe = 1 in { + defm VREINTERPRET_BF : REINTERPRET_CROSS_TYPES< + "csilUcUsUiUlhfPcPsPlQcQsQiQlQUcQUsQUiQUlQhQfQPcQPsQPl", "bQb">; + } +} + +let ArchGuard = "defined(__ARM_FEATURE_BF16) && defined(__aarch64__)" in { + let BigEndianSafe = 1 in { + defm VVREINTERPRET_BF : REINTERPRET_CROSS_TYPES< + "csilUcUsUiUlhfdPcPsPlQcQsQiQlQUcQUsQUiQUlQhQfQdQPcQPsQPlQPk", "bQb">; + } +} diff --git a/clang/include/clang/Basic/arm_neon_incl.td b/clang/include/clang/Basic/arm_neon_incl.td index 28b00d162a00..dd20b70433ef 100644 --- a/clang/include/clang/Basic/arm_neon_incl.td +++ b/clang/include/clang/Basic/arm_neon_incl.td @@ -35,7 +35,7 @@ class LOp<list<dag> ops> : Operation<ops>; // These defs and classes are used internally to implement the SetTheory // expansion and should be ignored. foreach Index = 0-63 in - def sv##Index; + def sv#Index; class MaskExpand; //===----------------------------------------------------------------------===// @@ -60,6 +60,15 @@ def op; // example: (call "vget_high", $p0) -> "vgetq_high_s16(__p0)" // (assuming $p0 has type int16x8_t). def call; +// call_mangled - Invoke another intrinsic matching the mangled name variation +// of the caller's base type. If there is no intrinsic defined +// that has the variation and takes the given types, an error +// is generated at tblgen time. +// example: (call_mangled "vfma_lane", $p0, $p1) -> "vfma_lane(__p0, __p1)" +// (assuming non-LaneQ caller) +// (call_mangled "vfma_lane", $p0, $p1) -> "vfma_laneq(__p0, __p1)" +// (assuming LaneQ caller) +def call_mangled; // cast - Perform a cast to a different type. This gets emitted as a static // C-style cast. For a pure reinterpret cast (T x = *(T*)&y), use // "bitcast". @@ -79,6 +88,7 @@ def call; // - "D" - Double the number of lanes in the type. // - "8" - Convert type to an equivalent vector of 8-bit signed // integers. +// - "32" - Convert type to an equivalent vector of 32-bit integers. // example: (cast "R", "U", $p0) -> "(uint32x4_t)__p0" (assuming the return // value is of type "int32x4_t". // (cast $p0, "D", "8", $p1) -> "(int8x16_t)__p1" (assuming __p0 @@ -100,12 +110,6 @@ def dup; // example: (dup_typed $p1, $p2) -> "(float16x4_t) {__p2, __p2, __p2, __p2}" // (assuming __p1 is float16x4_t, and __p2 is a compatible scalar). def dup_typed; -// splat - Take a vector and a lane index, and return a vector of the same type -// containing repeated instances of the source vector at the lane index. -// example: (splat $p0, $p1) -> -// "__builtin_shufflevector(__p0, __p0, __p1, __p1, __p1, __p1)" -// (assuming __p0 has four elements). -def splat; // save_temp - Create a temporary (local) variable. The variable takes a name // based on the zero'th parameter and can be referenced using // using that name in subsequent DAGs in the same @@ -211,6 +215,7 @@ def OP_UNAVAILABLE : Operation { // f: float // h: half-float // d: double +// b: bfloat16 // // Typespec modifiers // ------------------ @@ -232,6 +237,7 @@ def OP_UNAVAILABLE : Operation { // S: change to signed integer category. // U: change to unsigned integer category. // F: change to floating category. +// B: change to BFloat16 // P: change to polynomial category. // p: change polynomial to equivalent integer category. Otherwise nop. // @@ -261,7 +267,6 @@ class Inst <string n, string p, string t, Operation o> { string ArchGuard = ""; Operation Operation = o; - bit CartesianProductOfTypes = 0; bit BigEndianSafe = 0; bit isShift = 0; bit isScalarShift = 0; @@ -283,6 +288,8 @@ class Inst <string n, string p, string t, Operation o> { // this. Ex: vset_lane which outputs vmov instructions. bit isHiddenWInst = 0; bit isHiddenLInst = 0; + + string CartesianProductWith = ""; } // The following instruction classes are implemented via builtins. diff --git a/clang/include/clang/Basic/arm_sve.td b/clang/include/clang/Basic/arm_sve.td new file mode 100644 index 000000000000..19a42e79c36a --- /dev/null +++ b/clang/include/clang/Basic/arm_sve.td @@ -0,0 +1,2083 @@ +//===--- arm_sve.td - ARM SVE compiler interface ------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file defines the TableGen definitions from which the ARM SVE header +// file will be generated. See: +// +// https://developer.arm.com/architectures/system-architectures/software-standards/acle +// +//===----------------------------------------------------------------------===// + +//===----------------------------------------------------------------------===// +// Instruction definitions +//===----------------------------------------------------------------------===// +// Every intrinsic subclasses "Inst". An intrinsic has a name, a prototype and +// a sequence of typespecs. +// +// The name is the base name of the intrinsic, for example "svld1". This is +// then mangled by the tblgen backend to add type information ("svld1_s16"). +// +// A typespec is a sequence of uppercase characters (modifiers) followed by one +// lowercase character. A typespec encodes a particular "base type" of the +// intrinsic. +// +// An example typespec is "Us" - unsigned short - svuint16_t. The available +// typespec codes are given below. +// +// The string given to an Inst class is a sequence of typespecs. The intrinsic +// is instantiated for every typespec in the sequence. For example "sdUsUd". +// +// The prototype is a string that defines the return type of the intrinsic +// and the type of each argument. The return type and every argument gets a +// "modifier" that can change in some way the "base type" of the intrinsic. +// +// The modifier 'd' means "default" and does not modify the base type in any +// way. The available modifiers are given below. +// +// Typespecs +// --------- +// c: char +// s: short +// i: int +// l: long +// f: float +// h: half-float +// d: double +// b: bfloat + +// Typespec modifiers +// ------------------ +// P: boolean +// U: unsigned + +// Prototype modifiers +// ------------------- +// prototype: return (arg, arg, ...) +// +// 2,3,4: array of default vectors +// v: void +// x: vector of signed integers +// u: vector of unsigned integers +// d: default +// c: const pointer type +// P: predicate type +// s: scalar of element type +// a: scalar of element type (splat to vector type) +// R: scalar of 1/2 width element type (splat to vector type) +// r: scalar of 1/4 width element type (splat to vector type) +// @: unsigned scalar of 1/4 width element type (splat to vector type) +// e: 1/2 width unsigned elements, 2x element count +// b: 1/4 width unsigned elements, 4x element count +// h: 1/2 width elements, 2x element count +// q: 1/4 width elements, 4x element count +// o: 4x width elements, 1/4 element count +// +// w: vector of element type promoted to 64bits, vector maintains +// signedness of its element type. +// f: element type promoted to uint64_t (splat to vector type) +// j: element type promoted to 64bits (splat to vector type) +// K: element type bitcast to a signed integer (splat to vector type) +// L: element type bitcast to an unsigned integer (splat to vector type) +// +// i: constant uint64_t +// k: int32_t +// l: int64_t +// m: uint32_t +// n: uint64_t + +// t: svint32_t +// z: svuint32_t +// g: svuint64_t +// O: svfloat16_t +// M: svfloat32_t +// N: svfloat64_t + +// J: Prefetch type (sv_prfop) +// A: pointer to int8_t +// B: pointer to int16_t +// C: pointer to int32_t +// D: pointer to int64_t + +// E: pointer to uint8_t +// F: pointer to uint16_t +// G: pointer to uint32_t +// H: pointer to uint64_t + +// Q: const pointer to void + +// S: const pointer to int8_t +// T: const pointer to int16_t +// U: const pointer to int32_t +// V: const pointer to int64_t +// +// W: const pointer to uint8_t +// X: const pointer to uint16_t +// Y: const pointer to uint32_t +// Z: const pointer to uint64_t + +class MergeType<int val, string suffix=""> { + int Value = val; + string Suffix = suffix; +} +def MergeNone : MergeType<0>; +def MergeAny : MergeType<1, "_x">; +def MergeOp1 : MergeType<2, "_m">; +def MergeZero : MergeType<3, "_z">; +def MergeAnyExp : MergeType<4, "_x">; // Use merged builtin with explicit +def MergeZeroExp : MergeType<5, "_z">; // generation of its inactive argument. + +class EltType<int val> { + int Value = val; +} +def EltTyInvalid : EltType<0>; +def EltTyInt8 : EltType<1>; +def EltTyInt16 : EltType<2>; +def EltTyInt32 : EltType<3>; +def EltTyInt64 : EltType<4>; +def EltTyFloat16 : EltType<5>; +def EltTyFloat32 : EltType<6>; +def EltTyFloat64 : EltType<7>; +def EltTyBool8 : EltType<8>; +def EltTyBool16 : EltType<9>; +def EltTyBool32 : EltType<10>; +def EltTyBool64 : EltType<11>; +def EltTyBFloat16 : EltType<12>; + +class MemEltType<int val> { + int Value = val; +} +def MemEltTyDefault : MemEltType<0>; +def MemEltTyInt8 : MemEltType<1>; +def MemEltTyInt16 : MemEltType<2>; +def MemEltTyInt32 : MemEltType<3>; +def MemEltTyInt64 : MemEltType<4>; + +class FlagType<int val> { + int Value = val; +} + +// These must be kept in sync with the flags in utils/TableGen/SveEmitter.h +// and include/clang/Basic/TargetBuiltins.h +def NoFlags : FlagType<0x00000000>; +def FirstEltType : FlagType<0x00000001>; +// : : +// : : +def EltTypeMask : FlagType<0x0000000f>; +def FirstMemEltType : FlagType<0x00000010>; +// : : +// : : +def MemEltTypeMask : FlagType<0x00000070>; +def FirstMergeTypeMask : FlagType<0x00000080>; +// : : +// : : +def MergeTypeMask : FlagType<0x00000380>; +def FirstSplatOperand : FlagType<0x00000400>; +// : : +// These flags are used to specify which scalar operand +// needs to be duplicated/splatted into a vector. +// : : +def SplatOperandMask : FlagType<0x00001C00>; +def IsLoad : FlagType<0x00002000>; +def IsStore : FlagType<0x00004000>; +def IsGatherLoad : FlagType<0x00008000>; +def IsScatterStore : FlagType<0x00010000>; +def IsStructLoad : FlagType<0x00020000>; +def IsStructStore : FlagType<0x00040000>; +def IsZExtReturn : FlagType<0x00080000>; // Return value is sign-extend by default +def IsOverloadNone : FlagType<0x00100000>; // Intrinsic does not take any overloaded types. +def IsOverloadWhile : FlagType<0x00200000>; // Use {default type, typeof(operand1)} as overloaded types. +def IsOverloadWhileRW : FlagType<0x00400000>; // Use {pred(default type), typeof(operand0)} as overloaded types. +def IsOverloadCvt : FlagType<0x00800000>; // Use {typeof(operand0), typeof(last operand)} as overloaded types. +def OverloadKindMask : FlagType<0x00E00000>; // When the masked values are all '0', the default type is used as overload type. +def IsByteIndexed : FlagType<0x01000000>; +def IsAppendSVALL : FlagType<0x02000000>; // Appends SV_ALL as the last operand. +def IsInsertOp1SVALL : FlagType<0x04000000>; // Inserts SV_ALL as the second operand. +def IsPrefetch : FlagType<0x08000000>; // Contiguous prefetches. +def IsGatherPrefetch : FlagType<0x10000000>; +def ReverseCompare : FlagType<0x20000000>; // Compare operands must be swapped. +def ReverseUSDOT : FlagType<0x40000000>; // Unsigned/signed operands must be swapped. +def IsUndef : FlagType<0x80000000>; // Codegen `undef` of given type. +def IsTupleCreate : FlagType<0x100000000>; +def IsTupleGet : FlagType<0x200000000>; +def IsTupleSet : FlagType<0x400000000>; + +// These must be kept in sync with the flags in include/clang/Basic/TargetBuiltins.h +class ImmCheckType<int val> { + int Value = val; +} +def ImmCheck0_31 : ImmCheckType<0>; // 0..31 (used for e.g. predicate patterns) +def ImmCheck1_16 : ImmCheckType<1>; // 1..16 +def ImmCheckExtract : ImmCheckType<2>; // 0..(2048/sizeinbits(elt) - 1) +def ImmCheckShiftRight : ImmCheckType<3>; // 1..sizeinbits(elt) +def ImmCheckShiftRightNarrow : ImmCheckType<4>; // 1..sizeinbits(elt)/2 +def ImmCheckShiftLeft : ImmCheckType<5>; // 0..(sizeinbits(elt) - 1) +def ImmCheck0_7 : ImmCheckType<6>; // 0..7 +def ImmCheckLaneIndex : ImmCheckType<7>; // 0..(128/(1*sizeinbits(elt)) - 1) +def ImmCheckLaneIndexCompRotate : ImmCheckType<8>; // 0..(128/(2*sizeinbits(elt)) - 1) +def ImmCheckLaneIndexDot : ImmCheckType<9>; // 0..(128/(4*sizeinbits(elt)) - 1) +def ImmCheckComplexRot90_270 : ImmCheckType<10>; // [90,270] +def ImmCheckComplexRotAll90 : ImmCheckType<11>; // [0, 90, 180,270] +def ImmCheck0_13 : ImmCheckType<12>; // 0..13 +def ImmCheck0_1 : ImmCheckType<13>; // 0..1 +def ImmCheck0_2 : ImmCheckType<14>; // 0..2 +def ImmCheck0_3 : ImmCheckType<15>; // 0..3 + +class ImmCheck<int arg, ImmCheckType kind, int eltSizeArg = -1> { + int Arg = arg; + int EltSizeArg = eltSizeArg; + ImmCheckType Kind = kind; +} + +class Inst<string n, string p, string t, MergeType mt, string i, + list<FlagType> ft, list<ImmCheck> ch, MemEltType met> { + string Name = n; + string Prototype = p; + string Types = t; + string ArchGuard = ""; + int Merge = mt.Value; + string MergeSuffix = mt.Suffix; + string LLVMIntrinsic = i; + list<FlagType> Flags = ft; + list<ImmCheck> ImmChecks = ch; + int MemEltType = met.Value; +} + +// SInst: Instruction with signed/unsigned suffix (e.g., "s8", "u8") +class SInst<string n, string p, string t, MergeType mt, string i = "", + list<FlagType> ft = [], list<ImmCheck> ch = []> + : Inst<n, p, t, mt, i, ft, ch, MemEltTyDefault> { +} + +// MInst: Instructions which access memory +class MInst<string n, string p, string t, list<FlagType> f, + MemEltType met = MemEltTyDefault, string i = ""> + : Inst<n, p, t, MergeNone, i, f, [], met> { +} + +//////////////////////////////////////////////////////////////////////////////// +// Loads + +// Load one vector (scalar base) +def SVLD1 : MInst<"svld1[_{2}]", "dPc", "csilUcUsUiUlhfd", [IsLoad], MemEltTyDefault, "aarch64_sve_ld1">; +def SVLD1SB : MInst<"svld1sb_{d}", "dPS", "silUsUiUl", [IsLoad], MemEltTyInt8, "aarch64_sve_ld1">; +def SVLD1UB : MInst<"svld1ub_{d}", "dPW", "silUsUiUl", [IsLoad, IsZExtReturn], MemEltTyInt8, "aarch64_sve_ld1">; +def SVLD1SH : MInst<"svld1sh_{d}", "dPT", "ilUiUl", [IsLoad], MemEltTyInt16, "aarch64_sve_ld1">; +def SVLD1UH : MInst<"svld1uh_{d}", "dPX", "ilUiUl", [IsLoad, IsZExtReturn], MemEltTyInt16, "aarch64_sve_ld1">; +def SVLD1SW : MInst<"svld1sw_{d}", "dPU", "lUl", [IsLoad], MemEltTyInt32, "aarch64_sve_ld1">; +def SVLD1UW : MInst<"svld1uw_{d}", "dPY", "lUl", [IsLoad, IsZExtReturn], MemEltTyInt32, "aarch64_sve_ld1">; + +let ArchGuard = "defined(__ARM_FEATURE_SVE_BF16)" in { + def SVLD1_BF : MInst<"svld1[_{2}]", "dPc", "b", [IsLoad], MemEltTyDefault, "aarch64_sve_ld1">; + def SVLD1_VNUM_BF : MInst<"svld1_vnum[_{2}]", "dPcl", "b", [IsLoad], MemEltTyDefault, "aarch64_sve_ld1">; +} + +// Load one vector (scalar base, VL displacement) +def SVLD1_VNUM : MInst<"svld1_vnum[_{2}]", "dPcl", "csilUcUsUiUlhfd", [IsLoad], MemEltTyDefault, "aarch64_sve_ld1">; +def SVLD1SB_VNUM : MInst<"svld1sb_vnum_{d}", "dPSl", "silUsUiUl", [IsLoad], MemEltTyInt8, "aarch64_sve_ld1">; +def SVLD1UB_VNUM : MInst<"svld1ub_vnum_{d}", "dPWl", "silUsUiUl", [IsLoad, IsZExtReturn], MemEltTyInt8, "aarch64_sve_ld1">; +def SVLD1SH_VNUM : MInst<"svld1sh_vnum_{d}", "dPTl", "ilUiUl", [IsLoad], MemEltTyInt16, "aarch64_sve_ld1">; +def SVLD1UH_VNUM : MInst<"svld1uh_vnum_{d}", "dPXl", "ilUiUl", [IsLoad, IsZExtReturn], MemEltTyInt16, "aarch64_sve_ld1">; +def SVLD1SW_VNUM : MInst<"svld1sw_vnum_{d}", "dPUl", "lUl", [IsLoad], MemEltTyInt32, "aarch64_sve_ld1">; +def SVLD1UW_VNUM : MInst<"svld1uw_vnum_{d}", "dPYl", "lUl", [IsLoad, IsZExtReturn], MemEltTyInt32, "aarch64_sve_ld1">; + +// Load one vector (vector base) +def SVLD1_GATHER_BASES_U : MInst<"svld1_gather[_{2}base]_{d}", "dPu", "ilUiUlfd", [IsGatherLoad], MemEltTyDefault, "aarch64_sve_ld1_gather_scalar_offset">; +def SVLD1SB_GATHER_BASES_U : MInst<"svld1sb_gather[_{2}base]_{d}", "dPu", "ilUiUl", [IsGatherLoad], MemEltTyInt8, "aarch64_sve_ld1_gather_scalar_offset">; +def SVLD1UB_GATHER_BASES_U : MInst<"svld1ub_gather[_{2}base]_{d}", "dPu", "ilUiUl", [IsGatherLoad, IsZExtReturn], MemEltTyInt8, "aarch64_sve_ld1_gather_scalar_offset">; +def SVLD1SH_GATHER_BASES_U : MInst<"svld1sh_gather[_{2}base]_{d}", "dPu", "ilUiUl", [IsGatherLoad], MemEltTyInt16, "aarch64_sve_ld1_gather_scalar_offset">; +def SVLD1UH_GATHER_BASES_U : MInst<"svld1uh_gather[_{2}base]_{d}", "dPu", "ilUiUl", [IsGatherLoad, IsZExtReturn], MemEltTyInt16, "aarch64_sve_ld1_gather_scalar_offset">; +def SVLD1SW_GATHER_BASES_U : MInst<"svld1sw_gather[_{2}base]_{d}", "dPu", "lUl", [IsGatherLoad], MemEltTyInt32, "aarch64_sve_ld1_gather_scalar_offset">; +def SVLD1UW_GATHER_BASES_U : MInst<"svld1uw_gather[_{2}base]_{d}", "dPu", "lUl", [IsGatherLoad, IsZExtReturn], MemEltTyInt32, "aarch64_sve_ld1_gather_scalar_offset">; + +// Load one vector (scalar base, signed vector offset in bytes) +def SVLD1_GATHER_64B_OFFSETS_S : MInst<"svld1_gather_[{3}]offset[_{d}]", "dPcx", "lUld", [IsGatherLoad, IsByteIndexed], MemEltTyDefault, "aarch64_sve_ld1_gather">; +def SVLD1SB_GATHER_64B_OFFSETS_S : MInst<"svld1sb_gather_[{3}]offset_{d}", "dPSx", "lUl", [IsGatherLoad, IsByteIndexed], MemEltTyInt8, "aarch64_sve_ld1_gather">; +def SVLD1UB_GATHER_64B_OFFSETS_S : MInst<"svld1ub_gather_[{3}]offset_{d}", "dPWx", "lUl", [IsGatherLoad, IsByteIndexed, IsZExtReturn], MemEltTyInt8, "aarch64_sve_ld1_gather">; +def SVLD1SH_GATHER_64B_OFFSETS_S : MInst<"svld1sh_gather_[{3}]offset_{d}", "dPTx", "lUl", [IsGatherLoad, IsByteIndexed], MemEltTyInt16, "aarch64_sve_ld1_gather">; +def SVLD1UH_GATHER_64B_OFFSETS_S : MInst<"svld1uh_gather_[{3}]offset_{d}", "dPXx", "lUl", [IsGatherLoad, IsByteIndexed, IsZExtReturn], MemEltTyInt16, "aarch64_sve_ld1_gather">; +def SVLD1SW_GATHER_64B_OFFSETS_S : MInst<"svld1sw_gather_[{3}]offset_{d}", "dPUx", "lUl", [IsGatherLoad, IsByteIndexed], MemEltTyInt32, "aarch64_sve_ld1_gather">; +def SVLD1UW_GATHER_64B_OFFSETS_S : MInst<"svld1uw_gather_[{3}]offset_{d}", "dPYx", "lUl", [IsGatherLoad, IsByteIndexed, IsZExtReturn], MemEltTyInt32, "aarch64_sve_ld1_gather">; + +def SVLD1_GATHER_32B_OFFSETS_S : MInst<"svld1_gather_[{3}]offset[_{d}]", "dPcx", "iUif", [IsGatherLoad, IsByteIndexed], MemEltTyDefault, "aarch64_sve_ld1_gather_sxtw">; +def SVLD1SB_GATHER_32B_OFFSETS_S : MInst<"svld1sb_gather_[{3}]offset_{d}", "dPSx", "iUi", [IsGatherLoad, IsByteIndexed], MemEltTyInt8, "aarch64_sve_ld1_gather_sxtw">; +def SVLD1UB_GATHER_32B_OFFSETS_S : MInst<"svld1ub_gather_[{3}]offset_{d}", "dPWx", "iUi", [IsGatherLoad, IsByteIndexed, IsZExtReturn], MemEltTyInt8, "aarch64_sve_ld1_gather_sxtw">; +def SVLD1SH_GATHER_32B_OFFSETS_S : MInst<"svld1sh_gather_[{3}]offset_{d}", "dPTx", "iUi", [IsGatherLoad, IsByteIndexed], MemEltTyInt16, "aarch64_sve_ld1_gather_sxtw">; +def SVLD1UH_GATHER_32B_OFFSETS_S : MInst<"svld1uh_gather_[{3}]offset_{d}", "dPXx", "iUi", [IsGatherLoad, IsByteIndexed, IsZExtReturn], MemEltTyInt16, "aarch64_sve_ld1_gather_sxtw">; + +// Load one vector (scalar base, unsigned vector offset in bytes) +def SVLD1_GATHER_64B_OFFSETS_U : MInst<"svld1_gather_[{3}]offset[_{d}]", "dPcu", "lUld", [IsGatherLoad, IsByteIndexed], MemEltTyDefault, "aarch64_sve_ld1_gather">; +def SVLD1SB_GATHER_64B_OFFSETS_U : MInst<"svld1sb_gather_[{3}]offset_{d}", "dPSu", "lUl", [IsGatherLoad, IsByteIndexed], MemEltTyInt8, "aarch64_sve_ld1_gather">; +def SVLD1UB_GATHER_64B_OFFSETS_U : MInst<"svld1ub_gather_[{3}]offset_{d}", "dPWu", "lUl", [IsGatherLoad, IsByteIndexed, IsZExtReturn], MemEltTyInt8, "aarch64_sve_ld1_gather">; +def SVLD1SH_GATHER_64B_OFFSETS_U : MInst<"svld1sh_gather_[{3}]offset_{d}", "dPTu", "lUl", [IsGatherLoad, IsByteIndexed], MemEltTyInt16, "aarch64_sve_ld1_gather">; +def SVLD1UH_GATHER_64B_OFFSETS_U : MInst<"svld1uh_gather_[{3}]offset_{d}", "dPXu", "lUl", [IsGatherLoad, IsByteIndexed, IsZExtReturn], MemEltTyInt16, "aarch64_sve_ld1_gather">; +def SVLD1SW_GATHER_64B_OFFSETS_U : MInst<"svld1sw_gather_[{3}]offset_{d}", "dPUu", "lUl", [IsGatherLoad, IsByteIndexed], MemEltTyInt32, "aarch64_sve_ld1_gather">; +def SVLD1UW_GATHER_64B_OFFSETS_U : MInst<"svld1uw_gather_[{3}]offset_{d}", "dPYu", "lUl", [IsGatherLoad, IsByteIndexed, IsZExtReturn], MemEltTyInt32, "aarch64_sve_ld1_gather">; + +def SVLD1_GATHER_32B_OFFSETS_U : MInst<"svld1_gather_[{3}]offset[_{d}]", "dPcu", "iUif", [IsGatherLoad, IsByteIndexed], MemEltTyDefault, "aarch64_sve_ld1_gather_uxtw">; +def SVLD1SB_GATHER_32B_OFFSETS_U : MInst<"svld1sb_gather_[{3}]offset_{d}", "dPSu", "iUi", [IsGatherLoad, IsByteIndexed], MemEltTyInt8, "aarch64_sve_ld1_gather_uxtw">; +def SVLD1UB_GATHER_32B_OFFSETS_U : MInst<"svld1ub_gather_[{3}]offset_{d}", "dPWu", "iUi", [IsGatherLoad, IsByteIndexed, IsZExtReturn], MemEltTyInt8, "aarch64_sve_ld1_gather_uxtw">; +def SVLD1SH_GATHER_32B_OFFSETS_U : MInst<"svld1sh_gather_[{3}]offset_{d}", "dPTu", "iUi", [IsGatherLoad, IsByteIndexed], MemEltTyInt16, "aarch64_sve_ld1_gather_uxtw">; +def SVLD1UH_GATHER_32B_OFFSETS_U : MInst<"svld1uh_gather_[{3}]offset_{d}", "dPXu", "iUi", [IsGatherLoad, IsByteIndexed, IsZExtReturn], MemEltTyInt16, "aarch64_sve_ld1_gather_uxtw">; + +// Load one vector (vector base, signed scalar offset in bytes) +def SVLD1_GATHER_OFFSET_S : MInst<"svld1_gather[_{2}base]_offset_{d}", "dPul", "ilUiUlfd", [IsGatherLoad, IsByteIndexed], MemEltTyDefault, "aarch64_sve_ld1_gather_scalar_offset">; +def SVLD1SB_GATHER_OFFSET_S : MInst<"svld1sb_gather[_{2}base]_offset_{d}", "dPul", "ilUiUl", [IsGatherLoad, IsByteIndexed], MemEltTyInt8, "aarch64_sve_ld1_gather_scalar_offset">; +def SVLD1UB_GATHER_OFFSET_S : MInst<"svld1ub_gather[_{2}base]_offset_{d}", "dPul", "ilUiUl", [IsGatherLoad, IsByteIndexed, IsZExtReturn], MemEltTyInt8, "aarch64_sve_ld1_gather_scalar_offset">; +def SVLD1SH_GATHER_OFFSET_S : MInst<"svld1sh_gather[_{2}base]_offset_{d}", "dPul", "ilUiUl", [IsGatherLoad, IsByteIndexed], MemEltTyInt16, "aarch64_sve_ld1_gather_scalar_offset">; +def SVLD1UH_GATHER_OFFSET_S : MInst<"svld1uh_gather[_{2}base]_offset_{d}", "dPul", "ilUiUl", [IsGatherLoad, IsByteIndexed, IsZExtReturn], MemEltTyInt16, "aarch64_sve_ld1_gather_scalar_offset">; +def SVLD1SW_GATHER_OFFSET_S : MInst<"svld1sw_gather[_{2}base]_offset_{d}", "dPul", "lUl", [IsGatherLoad, IsByteIndexed], MemEltTyInt32, "aarch64_sve_ld1_gather_scalar_offset">; +def SVLD1UW_GATHER_OFFSET_S : MInst<"svld1uw_gather[_{2}base]_offset_{d}", "dPul", "lUl", [IsGatherLoad, IsByteIndexed, IsZExtReturn], MemEltTyInt32, "aarch64_sve_ld1_gather_scalar_offset">; + +// Load one vector (scalar base, signed vector index) +def SVLD1_GATHER_64B_INDICES_S : MInst<"svld1_gather_[{3}]index[_{d}]", "dPcx", "lUld", [IsGatherLoad], MemEltTyDefault, "aarch64_sve_ld1_gather_index">; +def SVLD1SH_GATHER_64B_INDICES_S : MInst<"svld1sh_gather_[{3}]index_{d}", "dPTx", "lUl", [IsGatherLoad], MemEltTyInt16, "aarch64_sve_ld1_gather_index">; +def SVLD1UH_GATHER_64B_INDICES_S : MInst<"svld1uh_gather_[{3}]index_{d}", "dPXx", "lUl", [IsGatherLoad, IsZExtReturn], MemEltTyInt16, "aarch64_sve_ld1_gather_index">; +def SVLD1SW_GATHER_64B_INDICES_S : MInst<"svld1sw_gather_[{3}]index_{d}", "dPUx", "lUl", [IsGatherLoad], MemEltTyInt32, "aarch64_sve_ld1_gather_index">; +def SVLD1UW_GATHER_64B_INDICES_S : MInst<"svld1uw_gather_[{3}]index_{d}", "dPYx", "lUl", [IsGatherLoad, IsZExtReturn], MemEltTyInt32, "aarch64_sve_ld1_gather_index">; + +def SVLD1_GATHER_32B_INDICES_S : MInst<"svld1_gather_[{3}]index[_{d}]", "dPcx", "iUif", [IsGatherLoad], MemEltTyDefault, "aarch64_sve_ld1_gather_sxtw_index">; +def SVLD1SH_GATHER_32B_INDICES_S : MInst<"svld1sh_gather_[{3}]index_{d}", "dPTx", "iUi", [IsGatherLoad], MemEltTyInt16, "aarch64_sve_ld1_gather_sxtw_index">; +def SVLD1UH_GATHER_32B_INDICES_S : MInst<"svld1uh_gather_[{3}]index_{d}", "dPXx", "iUi", [IsGatherLoad, IsZExtReturn], MemEltTyInt16, "aarch64_sve_ld1_gather_sxtw_index">; + +// Load one vector (scalar base, unsigned vector index) +def SVLD1_GATHER_64B_INDICES_U : MInst<"svld1_gather_[{3}]index[_{d}]", "dPcu", "lUld", [IsGatherLoad], MemEltTyDefault, "aarch64_sve_ld1_gather_index">; +def SVLD1SH_GATHER_64B_INDICES_U : MInst<"svld1sh_gather_[{3}]index_{d}", "dPTu", "lUl", [IsGatherLoad], MemEltTyInt16, "aarch64_sve_ld1_gather_index">; +def SVLD1UH_GATHER_64B_INDICES_U : MInst<"svld1uh_gather_[{3}]index_{d}", "dPXu", "lUl", [IsGatherLoad, IsZExtReturn], MemEltTyInt16, "aarch64_sve_ld1_gather_index">; +def SVLD1SW_GATHER_64B_INDICES_U : MInst<"svld1sw_gather_[{3}]index_{d}", "dPUu", "lUl", [IsGatherLoad], MemEltTyInt32, "aarch64_sve_ld1_gather_index">; +def SVLD1UW_GATHER_64B_INDICES_U : MInst<"svld1uw_gather_[{3}]index_{d}", "dPYu", "lUl", [IsGatherLoad, IsZExtReturn], MemEltTyInt32, "aarch64_sve_ld1_gather_index">; + +def SVLD1_GATHER_32B_INDICES_U : MInst<"svld1_gather_[{3}]index[_{d}]", "dPcu", "iUif", [IsGatherLoad], MemEltTyDefault, "aarch64_sve_ld1_gather_uxtw_index">; +def SVLD1SH_GATHER_32B_INDICES_U : MInst<"svld1sh_gather_[{3}]index_{d}", "dPTu", "iUi", [IsGatherLoad], MemEltTyInt16, "aarch64_sve_ld1_gather_uxtw_index">; +def SVLD1UH_GATHER_32B_INDICES_U : MInst<"svld1uh_gather_[{3}]index_{d}", "dPXu", "iUi", [IsGatherLoad, IsZExtReturn], MemEltTyInt16, "aarch64_sve_ld1_gather_uxtw_index">; + +// Load one vector (vector base, signed scalar index) +def SVLD1_GATHER_INDEX_S : MInst<"svld1_gather[_{2}base]_index_{d}", "dPul", "ilUiUlfd", [IsGatherLoad], MemEltTyDefault, "aarch64_sve_ld1_gather_scalar_offset">; +def SVLD1SH_GATHER_INDEX_S : MInst<"svld1sh_gather[_{2}base]_index_{d}", "dPul", "ilUiUl", [IsGatherLoad], MemEltTyInt16, "aarch64_sve_ld1_gather_scalar_offset">; +def SVLD1UH_GATHER_INDEX_S : MInst<"svld1uh_gather[_{2}base]_index_{d}", "dPul", "ilUiUl", [IsGatherLoad, IsZExtReturn], MemEltTyInt16, "aarch64_sve_ld1_gather_scalar_offset">; +def SVLD1SW_GATHER_INDEX_S : MInst<"svld1sw_gather[_{2}base]_index_{d}", "dPul", "lUl", [IsGatherLoad], MemEltTyInt32, "aarch64_sve_ld1_gather_scalar_offset">; +def SVLD1UW_GATHER_INDEX_S : MInst<"svld1uw_gather[_{2}base]_index_{d}", "dPul", "lUl", [IsGatherLoad, IsZExtReturn], MemEltTyInt32, "aarch64_sve_ld1_gather_scalar_offset">; + + +// First-faulting load one vector (scalar base) +def SVLDFF1 : MInst<"svldff1[_{2}]", "dPc", "csilUcUsUiUlhfd", [IsLoad], MemEltTyDefault, "aarch64_sve_ldff1">; +def SVLDFF1SB : MInst<"svldff1sb_{d}", "dPS", "silUsUiUl", [IsLoad], MemEltTyInt8, "aarch64_sve_ldff1">; +def SVLDFF1UB : MInst<"svldff1ub_{d}", "dPW", "silUsUiUl", [IsLoad, IsZExtReturn], MemEltTyInt8, "aarch64_sve_ldff1">; +def SVLDFF1SH : MInst<"svldff1sh_{d}", "dPT", "ilUiUl", [IsLoad], MemEltTyInt16, "aarch64_sve_ldff1">; +def SVLDFF1UH : MInst<"svldff1uh_{d}", "dPX", "ilUiUl", [IsLoad, IsZExtReturn], MemEltTyInt16, "aarch64_sve_ldff1">; +def SVLDFF1SW : MInst<"svldff1sw_{d}", "dPU", "lUl", [IsLoad], MemEltTyInt32, "aarch64_sve_ldff1">; +def SVLDFF1UW : MInst<"svldff1uw_{d}", "dPY", "lUl", [IsLoad, IsZExtReturn], MemEltTyInt32, "aarch64_sve_ldff1">; + +// First-faulting load one vector (scalar base, VL displacement) +def SVLDFF1_VNUM : MInst<"svldff1_vnum[_{2}]", "dPcl", "csilUcUsUiUlhfd", [IsLoad], MemEltTyDefault, "aarch64_sve_ldff1">; +def SVLDFF1SB_VNUM : MInst<"svldff1sb_vnum_{d}", "dPSl", "silUsUiUl", [IsLoad], MemEltTyInt8, "aarch64_sve_ldff1">; +def SVLDFF1UB_VNUM : MInst<"svldff1ub_vnum_{d}", "dPWl", "silUsUiUl", [IsLoad, IsZExtReturn], MemEltTyInt8, "aarch64_sve_ldff1">; +def SVLDFF1SH_VNUM : MInst<"svldff1sh_vnum_{d}", "dPTl", "ilUiUl", [IsLoad], MemEltTyInt16, "aarch64_sve_ldff1">; +def SVLDFF1UH_VNUM : MInst<"svldff1uh_vnum_{d}", "dPXl", "ilUiUl", [IsLoad, IsZExtReturn], MemEltTyInt16, "aarch64_sve_ldff1">; +def SVLDFF1SW_VNUM : MInst<"svldff1sw_vnum_{d}", "dPUl", "lUl", [IsLoad], MemEltTyInt32, "aarch64_sve_ldff1">; +def SVLDFF1UW_VNUM : MInst<"svldff1uw_vnum_{d}", "dPYl", "lUl", [IsLoad, IsZExtReturn], MemEltTyInt32, "aarch64_sve_ldff1">; + +let ArchGuard = "defined(__ARM_FEATURE_SVE_BF16)" in { + def SVLDFF1_BF : MInst<"svldff1[_{2}]", "dPc", "b", [IsLoad], MemEltTyDefault, "aarch64_sve_ldff1">; + def SVLDFF1_VNUM_BF : MInst<"svldff1_vnum[_{2}]", "dPcl", "b", [IsLoad], MemEltTyDefault, "aarch64_sve_ldff1">; +} + +// First-faulting load one vector (vector base) +def SVLDFF1_GATHER_BASES_U : MInst<"svldff1_gather[_{2}base]_{d}", "dPu", "ilUiUlfd", [IsGatherLoad], MemEltTyDefault, "aarch64_sve_ldff1_gather_scalar_offset">; +def SVLDFF1SB_GATHER_BASES_U : MInst<"svldff1sb_gather[_{2}base]_{d}", "dPu", "ilUiUl", [IsGatherLoad], MemEltTyInt8, "aarch64_sve_ldff1_gather_scalar_offset">; +def SVLDFF1UB_GATHER_BASES_U : MInst<"svldff1ub_gather[_{2}base]_{d}", "dPu", "ilUiUl", [IsGatherLoad, IsZExtReturn], MemEltTyInt8, "aarch64_sve_ldff1_gather_scalar_offset">; +def SVLDFF1SH_GATHER_BASES_U : MInst<"svldff1sh_gather[_{2}base]_{d}", "dPu", "ilUiUl", [IsGatherLoad], MemEltTyInt16, "aarch64_sve_ldff1_gather_scalar_offset">; +def SVLDFF1UH_GATHER_BASES_U : MInst<"svldff1uh_gather[_{2}base]_{d}", "dPu", "ilUiUl", [IsGatherLoad, IsZExtReturn], MemEltTyInt16, "aarch64_sve_ldff1_gather_scalar_offset">; +def SVLDFF1SW_GATHER_BASES_U : MInst<"svldff1sw_gather[_{2}base]_{d}", "dPu", "lUl", [IsGatherLoad], MemEltTyInt32, "aarch64_sve_ldff1_gather_scalar_offset">; +def SVLDFF1UW_GATHER_BASES_U : MInst<"svldff1uw_gather[_{2}base]_{d}", "dPu", "lUl", [IsGatherLoad, IsZExtReturn], MemEltTyInt32, "aarch64_sve_ldff1_gather_scalar_offset">; + +// First-faulting load one vector (scalar base, signed vector offset in bytes) +def SVLDFF1_GATHER_64B_OFFSETS_S : MInst<"svldff1_gather_[{3}]offset[_{d}]", "dPcx", "lUld", [IsGatherLoad, IsByteIndexed], MemEltTyDefault, "aarch64_sve_ldff1_gather">; +def SVLDFF1SB_GATHER_64B_OFFSETS_S : MInst<"svldff1sb_gather_[{3}]offset_{d}", "dPSx", "lUl", [IsGatherLoad, IsByteIndexed], MemEltTyInt8, "aarch64_sve_ldff1_gather">; +def SVLDFF1UB_GATHER_64B_OFFSETS_S : MInst<"svldff1ub_gather_[{3}]offset_{d}", "dPWx", "lUl", [IsGatherLoad, IsByteIndexed, IsZExtReturn], MemEltTyInt8, "aarch64_sve_ldff1_gather">; +def SVLDFF1SH_GATHER_64B_OFFSETS_S : MInst<"svldff1sh_gather_[{3}]offset_{d}", "dPTx", "lUl", [IsGatherLoad, IsByteIndexed], MemEltTyInt16, "aarch64_sve_ldff1_gather">; +def SVLDFF1UH_GATHER_64B_OFFSETS_S : MInst<"svldff1uh_gather_[{3}]offset_{d}", "dPXx", "lUl", [IsGatherLoad, IsByteIndexed, IsZExtReturn], MemEltTyInt16, "aarch64_sve_ldff1_gather">; +def SVLDFF1SW_GATHER_64B_OFFSETS_S : MInst<"svldff1sw_gather_[{3}]offset_{d}", "dPUx", "lUl", [IsGatherLoad, IsByteIndexed], MemEltTyInt32, "aarch64_sve_ldff1_gather">; +def SVLDFF1UW_GATHER_64B_OFFSETS_S : MInst<"svldff1uw_gather_[{3}]offset_{d}", "dPYx", "lUl", [IsGatherLoad, IsByteIndexed, IsZExtReturn], MemEltTyInt32, "aarch64_sve_ldff1_gather">; + +def SVLDFF1_GATHER_32B_OFFSETS_S : MInst<"svldff1_gather_[{3}]offset[_{d}]", "dPcx", "iUif", [IsGatherLoad, IsByteIndexed], MemEltTyDefault, "aarch64_sve_ldff1_gather_sxtw">; +def SVLDFF1SB_GATHER_32B_OFFSETS_S : MInst<"svldff1sb_gather_[{3}]offset_{d}", "dPSx", "iUi", [IsGatherLoad, IsByteIndexed], MemEltTyInt8, "aarch64_sve_ldff1_gather_sxtw">; +def SVLDFF1UB_GATHER_32B_OFFSETS_S : MInst<"svldff1ub_gather_[{3}]offset_{d}", "dPWx", "iUi", [IsGatherLoad, IsByteIndexed, IsZExtReturn], MemEltTyInt8, "aarch64_sve_ldff1_gather_sxtw">; +def SVLDFF1SH_GATHER_32B_OFFSETS_S : MInst<"svldff1sh_gather_[{3}]offset_{d}", "dPTx", "iUi", [IsGatherLoad, IsByteIndexed], MemEltTyInt16, "aarch64_sve_ldff1_gather_sxtw">; +def SVLDFF1UH_GATHER_32B_OFFSETS_S : MInst<"svldff1uh_gather_[{3}]offset_{d}", "dPXx", "iUi", [IsGatherLoad, IsByteIndexed, IsZExtReturn], MemEltTyInt16, "aarch64_sve_ldff1_gather_sxtw">; + +// First-faulting load one vector (scalar base, unsigned vector offset in bytes) +def SVLDFF1_GATHER_64B_OFFSETS_U : MInst<"svldff1_gather_[{3}]offset[_{d}]", "dPcu", "lUld", [IsGatherLoad, IsByteIndexed], MemEltTyDefault, "aarch64_sve_ldff1_gather">; +def SVLDFF1SB_GATHER_64B_OFFSETS_U : MInst<"svldff1sb_gather_[{3}]offset_{d}", "dPSu", "lUl", [IsGatherLoad, IsByteIndexed], MemEltTyInt8, "aarch64_sve_ldff1_gather">; +def SVLDFF1UB_GATHER_64B_OFFSETS_U : MInst<"svldff1ub_gather_[{3}]offset_{d}", "dPWu", "lUl", [IsGatherLoad, IsByteIndexed, IsZExtReturn], MemEltTyInt8, "aarch64_sve_ldff1_gather">; +def SVLDFF1SH_GATHER_64B_OFFSETS_U : MInst<"svldff1sh_gather_[{3}]offset_{d}", "dPTu", "lUl", [IsGatherLoad, IsByteIndexed], MemEltTyInt16, "aarch64_sve_ldff1_gather">; +def SVLDFF1UH_GATHER_64B_OFFSETS_U : MInst<"svldff1uh_gather_[{3}]offset_{d}", "dPXu", "lUl", [IsGatherLoad, IsByteIndexed, IsZExtReturn], MemEltTyInt16, "aarch64_sve_ldff1_gather">; +def SVLDFF1SW_GATHER_64B_OFFSETS_U : MInst<"svldff1sw_gather_[{3}]offset_{d}", "dPUu", "lUl", [IsGatherLoad, IsByteIndexed], MemEltTyInt32, "aarch64_sve_ldff1_gather">; +def SVLDFF1UW_GATHER_64B_OFFSETS_U : MInst<"svldff1uw_gather_[{3}]offset_{d}", "dPYu", "lUl", [IsGatherLoad, IsByteIndexed, IsZExtReturn], MemEltTyInt32, "aarch64_sve_ldff1_gather">; + +def SVLDFF1_GATHER_32B_OFFSETS_U : MInst<"svldff1_gather_[{3}]offset[_{d}]", "dPcu", "iUif", [IsGatherLoad, IsByteIndexed], MemEltTyDefault, "aarch64_sve_ldff1_gather_uxtw">; +def SVLDFF1SB_GATHER_32B_OFFSETS_U : MInst<"svldff1sb_gather_[{3}]offset_{d}", "dPSu", "iUi", [IsGatherLoad, IsByteIndexed], MemEltTyInt8, "aarch64_sve_ldff1_gather_uxtw">; +def SVLDFF1UB_GATHER_32B_OFFSETS_U : MInst<"svldff1ub_gather_[{3}]offset_{d}", "dPWu", "iUi", [IsGatherLoad, IsByteIndexed, IsZExtReturn], MemEltTyInt8, "aarch64_sve_ldff1_gather_uxtw">; +def SVLDFF1SH_GATHER_32B_OFFSETS_U : MInst<"svldff1sh_gather_[{3}]offset_{d}", "dPTu", "iUi", [IsGatherLoad, IsByteIndexed], MemEltTyInt16, "aarch64_sve_ldff1_gather_uxtw">; +def SVLDFF1UH_GATHER_32B_OFFSETS_U : MInst<"svldff1uh_gather_[{3}]offset_{d}", "dPXu", "iUi", [IsGatherLoad, IsByteIndexed, IsZExtReturn], MemEltTyInt16, "aarch64_sve_ldff1_gather_uxtw">; + +// First-faulting load one vector (vector base, signed scalar offset in bytes) +def SVLDFF1_GATHER_OFFSET_S : MInst<"svldff1_gather[_{2}base]_offset_{d}", "dPul", "ilUiUlfd", [IsGatherLoad, IsByteIndexed], MemEltTyDefault, "aarch64_sve_ldff1_gather_scalar_offset">; +def SVLDFF1SB_GATHER_OFFSET_S : MInst<"svldff1sb_gather[_{2}base]_offset_{d}", "dPul", "ilUiUl", [IsGatherLoad, IsByteIndexed], MemEltTyInt8, "aarch64_sve_ldff1_gather_scalar_offset">; +def SVLDFF1UB_GATHER_OFFSET_S : MInst<"svldff1ub_gather[_{2}base]_offset_{d}", "dPul", "ilUiUl", [IsGatherLoad, IsByteIndexed, IsZExtReturn], MemEltTyInt8, "aarch64_sve_ldff1_gather_scalar_offset">; +def SVLDFF1SH_GATHER_OFFSET_S : MInst<"svldff1sh_gather[_{2}base]_offset_{d}", "dPul", "ilUiUl", [IsGatherLoad, IsByteIndexed], MemEltTyInt16, "aarch64_sve_ldff1_gather_scalar_offset">; +def SVLDFF1UH_GATHER_OFFSET_S : MInst<"svldff1uh_gather[_{2}base]_offset_{d}", "dPul", "ilUiUl", [IsGatherLoad, IsByteIndexed, IsZExtReturn], MemEltTyInt16, "aarch64_sve_ldff1_gather_scalar_offset">; +def SVLDFF1SW_GATHER_OFFSET_S : MInst<"svldff1sw_gather[_{2}base]_offset_{d}", "dPul", "lUl", [IsGatherLoad, IsByteIndexed], MemEltTyInt32, "aarch64_sve_ldff1_gather_scalar_offset">; +def SVLDFF1UW_GATHER_OFFSET_S : MInst<"svldff1uw_gather[_{2}base]_offset_{d}", "dPul", "lUl", [IsGatherLoad, IsByteIndexed, IsZExtReturn], MemEltTyInt32, "aarch64_sve_ldff1_gather_scalar_offset">; + +// First-faulting load one vector (scalar base, signed vector index) +def SVLDFF1_GATHER_64B_INDICES_S : MInst<"svldff1_gather_[{3}]index[_{d}]", "dPcx", "lUld", [IsGatherLoad], MemEltTyDefault, "aarch64_sve_ldff1_gather_index">; +def SVLDFF1SH_GATHER_64B_INDICES_S : MInst<"svldff1sh_gather_[{3}]index_{d}", "dPTx", "lUl", [IsGatherLoad], MemEltTyInt16, "aarch64_sve_ldff1_gather_index">; +def SVLDFF1UH_GATHER_64B_INDICES_S : MInst<"svldff1uh_gather_[{3}]index_{d}", "dPXx", "lUl", [IsGatherLoad, IsZExtReturn], MemEltTyInt16, "aarch64_sve_ldff1_gather_index">; +def SVLDFF1SW_GATHER_64B_INDICES_S : MInst<"svldff1sw_gather_[{3}]index_{d}", "dPUx", "lUl", [IsGatherLoad], MemEltTyInt32, "aarch64_sve_ldff1_gather_index">; +def SVLDFF1UW_GATHER_64B_INDICES_S : MInst<"svldff1uw_gather_[{3}]index_{d}", "dPYx", "lUl", [IsGatherLoad, IsZExtReturn], MemEltTyInt32, "aarch64_sve_ldff1_gather_index">; + +def SVLDFF1_GATHER_32B_INDICES_S : MInst<"svldff1_gather_[{3}]index[_{d}]", "dPcx", "iUif", [IsGatherLoad], MemEltTyDefault, "aarch64_sve_ldff1_gather_sxtw_index">; +def SVLDFF1SH_GATHER_32B_INDICES_S : MInst<"svldff1sh_gather_[{3}]index_{d}", "dPTx", "iUi", [IsGatherLoad], MemEltTyInt16, "aarch64_sve_ldff1_gather_sxtw_index">; +def SVLDFF1UH_GATHER_32B_INDICES_S : MInst<"svldff1uh_gather_[{3}]index_{d}", "dPXx", "iUi", [IsGatherLoad, IsZExtReturn], MemEltTyInt16, "aarch64_sve_ldff1_gather_sxtw_index">; + +// First-faulting load one vector (scalar base, unsigned vector index) +def SVLDFF1_GATHER_64B_INDICES_U : MInst<"svldff1_gather_[{3}]index[_{d}]", "dPcu", "lUld", [IsGatherLoad], MemEltTyDefault, "aarch64_sve_ldff1_gather_index">; +def SVLDFF1SH_GATHER_64B_INDICES_U : MInst<"svldff1sh_gather_[{3}]index_{d}", "dPTu", "lUl", [IsGatherLoad], MemEltTyInt16, "aarch64_sve_ldff1_gather_index">; +def SVLDFF1UH_GATHER_64B_INDICES_U : MInst<"svldff1uh_gather_[{3}]index_{d}", "dPXu", "lUl", [IsGatherLoad, IsZExtReturn], MemEltTyInt16, "aarch64_sve_ldff1_gather_index">; +def SVLDFF1SW_GATHER_64B_INDICES_U : MInst<"svldff1sw_gather_[{3}]index_{d}", "dPUu", "lUl", [IsGatherLoad], MemEltTyInt32, "aarch64_sve_ldff1_gather_index">; +def SVLDFF1UW_GATHER_64B_INDICES_U : MInst<"svldff1uw_gather_[{3}]index_{d}", "dPYu", "lUl", [IsGatherLoad, IsZExtReturn], MemEltTyInt32, "aarch64_sve_ldff1_gather_index">; + +def SVLDFF1_GATHER_32B_INDICES_U : MInst<"svldff1_gather_[{3}]index[_{d}]", "dPcu", "iUif", [IsGatherLoad], MemEltTyDefault, "aarch64_sve_ldff1_gather_uxtw_index">; +def SVLDFF1SH_GATHER_32B_INDICES_U : MInst<"svldff1sh_gather_[{3}]index_{d}", "dPTu", "iUi", [IsGatherLoad], MemEltTyInt16, "aarch64_sve_ldff1_gather_uxtw_index">; +def SVLDFF1UH_GATHER_32B_INDICES_U : MInst<"svldff1uh_gather_[{3}]index_{d}", "dPXu", "iUi", [IsGatherLoad, IsZExtReturn], MemEltTyInt16, "aarch64_sve_ldff1_gather_uxtw_index">; + +// First-faulting load one vector (vector base, signed scalar index) +def SVLDFF1_GATHER_INDEX_S : MInst<"svldff1_gather[_{2}base]_index_{d}", "dPul", "ilUiUlfd", [IsGatherLoad], MemEltTyDefault, "aarch64_sve_ldff1_gather_scalar_offset">; +def SVLDFF1SH_GATHER_INDEX_S : MInst<"svldff1sh_gather[_{2}base]_index_{d}", "dPul", "ilUiUl", [IsGatherLoad], MemEltTyInt16, "aarch64_sve_ldff1_gather_scalar_offset">; +def SVLDFF1UH_GATHER_INDEX_S : MInst<"svldff1uh_gather[_{2}base]_index_{d}", "dPul", "ilUiUl", [IsGatherLoad, IsZExtReturn], MemEltTyInt16, "aarch64_sve_ldff1_gather_scalar_offset">; +def SVLDFF1SW_GATHER_INDEX_S : MInst<"svldff1sw_gather[_{2}base]_index_{d}", "dPul", "lUl", [IsGatherLoad], MemEltTyInt32, "aarch64_sve_ldff1_gather_scalar_offset">; +def SVLDFF1UW_GATHER_INDEX_S : MInst<"svldff1uw_gather[_{2}base]_index_{d}", "dPul", "lUl", [IsGatherLoad, IsZExtReturn], MemEltTyInt32, "aarch64_sve_ldff1_gather_scalar_offset">; + +// Non-faulting load one vector (scalar base) +def SVLDNF1 : MInst<"svldnf1[_{2}]", "dPc", "csilUcUsUiUlhfd", [IsLoad], MemEltTyDefault, "aarch64_sve_ldnf1">; +def SVLDNF1SB : MInst<"svldnf1sb_{d}", "dPS", "silUsUiUl", [IsLoad], MemEltTyInt8, "aarch64_sve_ldnf1">; +def SVLDNF1UB : MInst<"svldnf1ub_{d}", "dPW", "silUsUiUl", [IsLoad, IsZExtReturn], MemEltTyInt8, "aarch64_sve_ldnf1">; +def SVLDNF1SH : MInst<"svldnf1sh_{d}", "dPT", "ilUiUl", [IsLoad], MemEltTyInt16, "aarch64_sve_ldnf1">; +def SVLDNF1UH : MInst<"svldnf1uh_{d}", "dPX", "ilUiUl", [IsLoad, IsZExtReturn], MemEltTyInt16, "aarch64_sve_ldnf1">; +def SVLDNF1SW : MInst<"svldnf1sw_{d}", "dPU", "lUl", [IsLoad], MemEltTyInt32, "aarch64_sve_ldnf1">; +def SVLDNF1UW : MInst<"svldnf1uw_{d}", "dPY", "lUl", [IsLoad, IsZExtReturn], MemEltTyInt32, "aarch64_sve_ldnf1">; + +// Non-faulting load one vector (scalar base, VL displacement) +def SVLDNF1_VNUM : MInst<"svldnf1_vnum[_{2}]", "dPcl", "csilUcUsUiUlhfd", [IsLoad], MemEltTyDefault, "aarch64_sve_ldnf1">; +def SVLDNF1SB_VNUM : MInst<"svldnf1sb_vnum_{d}", "dPSl", "silUsUiUl", [IsLoad], MemEltTyInt8, "aarch64_sve_ldnf1">; +def SVLDNF1UB_VNUM : MInst<"svldnf1ub_vnum_{d}", "dPWl", "silUsUiUl", [IsLoad, IsZExtReturn], MemEltTyInt8, "aarch64_sve_ldnf1">; +def SVLDNF1SH_VNUM : MInst<"svldnf1sh_vnum_{d}", "dPTl", "ilUiUl", [IsLoad], MemEltTyInt16, "aarch64_sve_ldnf1">; +def SVLDNF1UH_VNUM : MInst<"svldnf1uh_vnum_{d}", "dPXl", "ilUiUl", [IsLoad, IsZExtReturn], MemEltTyInt16, "aarch64_sve_ldnf1">; +def SVLDNF1SW_VNUM : MInst<"svldnf1sw_vnum_{d}", "dPUl", "lUl", [IsLoad], MemEltTyInt32, "aarch64_sve_ldnf1">; +def SVLDNF1UW_VNUM : MInst<"svldnf1uw_vnum_{d}", "dPYl", "lUl", [IsLoad, IsZExtReturn], MemEltTyInt32, "aarch64_sve_ldnf1">; + +let ArchGuard = "defined(__ARM_FEATURE_SVE_BF16)" in { + def SVLDNF1_BF : MInst<"svldnf1[_{2}]", "dPc", "b", [IsLoad], MemEltTyDefault, "aarch64_sve_ldnf1">; + def SVLDNF1_VNUM_BF : MInst<"svldnf1_vnum[_{2}]", "dPcl", "b", [IsLoad], MemEltTyDefault, "aarch64_sve_ldnf1">; +} + +// Load one vector, unextended load, non-temporal (scalar base) +def SVLDNT1 : MInst<"svldnt1[_{2}]", "dPc", "csilUcUsUiUlhfd", [IsLoad], MemEltTyDefault, "aarch64_sve_ldnt1">; + +// Load one vector, unextended load, non-temporal (scalar base, VL displacement) +def SVLDNT1_VNUM : MInst<"svldnt1_vnum[_{2}]", "dPcl", "csilUcUsUiUlhfd", [IsLoad], MemEltTyDefault, "aarch64_sve_ldnt1">; + +let ArchGuard = "defined(__ARM_FEATURE_SVE_BF16)" in { + def SVLDNT1_BF : MInst<"svldnt1[_{2}]", "dPc", "b", [IsLoad], MemEltTyDefault, "aarch64_sve_ldnt1">; + def SVLDNT1_VNUM_BF : MInst<"svldnt1_vnum[_{2}]", "dPcl", "b", [IsLoad], MemEltTyDefault, "aarch64_sve_ldnt1">; +} + +// Load one quadword and replicate (scalar base) +def SVLD1RQ : SInst<"svld1rq[_{2}]", "dPc", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_ld1rq">; + +let ArchGuard = "defined(__ARM_FEATURE_SVE_BF16)" in { + def SVLD1RQ_BF : SInst<"svld1rq[_{2}]", "dPc", "b", MergeNone, "aarch64_sve_ld1rq">; +} + +multiclass StructLoad<string name, string proto, string i> { + def : SInst<name, proto, "csilUcUsUiUlhfd", MergeNone, i, [IsStructLoad]>; + let ArchGuard = "defined(__ARM_FEATURE_SVE_BF16)" in { + def: SInst<name, proto, "b", MergeNone, i, [IsStructLoad]>; + } +} + +// Load N-element structure into N vectors (scalar base) +defm SVLD2 : StructLoad<"svld2[_{2}]", "2Pc", "aarch64_sve_ld2">; +defm SVLD3 : StructLoad<"svld3[_{2}]", "3Pc", "aarch64_sve_ld3">; +defm SVLD4 : StructLoad<"svld4[_{2}]", "4Pc", "aarch64_sve_ld4">; + +// Load N-element structure into N vectors (scalar base, VL displacement) +defm SVLD2_VNUM : StructLoad<"svld2_vnum[_{2}]", "2Pcl", "aarch64_sve_ld2">; +defm SVLD3_VNUM : StructLoad<"svld3_vnum[_{2}]", "3Pcl", "aarch64_sve_ld3">; +defm SVLD4_VNUM : StructLoad<"svld4_vnum[_{2}]", "4Pcl", "aarch64_sve_ld4">; + +// Load one octoword and replicate (scalar base) +let ArchGuard = "defined(__ARM_FEATURE_SVE_MATMUL_FP64)" in { + def SVLD1RO : SInst<"svld1ro[_{2}]", "dPc", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_ld1ro">; +} +let ArchGuard = "defined(__ARM_FEATURE_SVE_MATMUL_FP64) && defined(__ARM_FEATURE_SVE_BF16)" in { + def SVLD1RO_BF16 : SInst<"svld1ro[_{2}]", "dPc", "b", MergeNone, "aarch64_sve_ld1ro">; +} + +let ArchGuard = "defined(__ARM_FEATURE_SVE_BF16)" in { + def SVBFDOT : SInst<"svbfdot[_{0}]", "MMdd", "b", MergeNone, "aarch64_sve_bfdot", [IsOverloadNone]>; + def SVBFMLALB : SInst<"svbfmlalb[_{0}]", "MMdd", "b", MergeNone, "aarch64_sve_bfmlalb", [IsOverloadNone]>; + def SVBFMLALT : SInst<"svbfmlalt[_{0}]", "MMdd", "b", MergeNone, "aarch64_sve_bfmlalt", [IsOverloadNone]>; + def SVBFMMLA : SInst<"svbfmmla[_{0}]", "MMdd", "b", MergeNone, "aarch64_sve_bfmmla", [IsOverloadNone]>; + def SVBFDOT_N : SInst<"svbfdot[_n_{0}]", "MMda", "b", MergeNone, "aarch64_sve_bfdot", [IsOverloadNone]>; + def SVBFMLAL_N : SInst<"svbfmlalb[_n_{0}]", "MMda", "b", MergeNone, "aarch64_sve_bfmlalb", [IsOverloadNone]>; + def SVBFMLALT_N : SInst<"svbfmlalt[_n_{0}]", "MMda", "b", MergeNone, "aarch64_sve_bfmlalt", [IsOverloadNone]>; + def SVBFDOT_LANE : SInst<"svbfdot_lane[_{0}]", "MMddn", "b", MergeNone, "aarch64_sve_bfdot_lane", [IsOverloadNone], [ImmCheck<3, ImmCheck0_3>]>; + def SVBFMLALB_LANE : SInst<"svbfmlalb_lane[_{0}]", "MMddn", "b", MergeNone, "aarch64_sve_bfmlalb_lane", [IsOverloadNone], [ImmCheck<3, ImmCheck0_7>]>; + def SVBFMLALT_LANE : SInst<"svbfmlalt_lane[_{0}]", "MMddn", "b", MergeNone, "aarch64_sve_bfmlalt_lane", [IsOverloadNone], [ImmCheck<3, ImmCheck0_7>]>; +} + +//////////////////////////////////////////////////////////////////////////////// +// Stores + +// Store one vector (scalar base) +def SVST1 : MInst<"svst1[_{d}]", "vPpd", "csilUcUsUiUlhfd", [IsStore], MemEltTyDefault, "aarch64_sve_st1">; +def SVST1B_S : MInst<"svst1b[_{d}]", "vPAd", "sil", [IsStore], MemEltTyInt8, "aarch64_sve_st1">; +def SVST1B_U : MInst<"svst1b[_{d}]", "vPEd", "UsUiUl", [IsStore], MemEltTyInt8, "aarch64_sve_st1">; +def SVST1H_S : MInst<"svst1h[_{d}]", "vPBd", "il", [IsStore], MemEltTyInt16, "aarch64_sve_st1">; +def SVST1H_U : MInst<"svst1h[_{d}]", "vPFd", "UiUl", [IsStore], MemEltTyInt16, "aarch64_sve_st1">; +def SVST1W_S : MInst<"svst1w[_{d}]", "vPCd", "l", [IsStore], MemEltTyInt32, "aarch64_sve_st1">; +def SVST1W_U : MInst<"svst1w[_{d}]", "vPGd", "Ul", [IsStore], MemEltTyInt32, "aarch64_sve_st1">; + +// Store one vector (scalar base, VL displacement) +def SVST1_VNUM : MInst<"svst1_vnum[_{d}]", "vPpld", "csilUcUsUiUlhfd", [IsStore], MemEltTyDefault, "aarch64_sve_st1">; +def SVST1B_VNUM_S : MInst<"svst1b_vnum[_{d}]", "vPAld", "sil", [IsStore], MemEltTyInt8, "aarch64_sve_st1">; +def SVST1B_VNUM_U : MInst<"svst1b_vnum[_{d}]", "vPEld", "UsUiUl", [IsStore], MemEltTyInt8, "aarch64_sve_st1">; +def SVST1H_VNUM_S : MInst<"svst1h_vnum[_{d}]", "vPBld", "il", [IsStore], MemEltTyInt16, "aarch64_sve_st1">; +def SVST1H_VNUM_U : MInst<"svst1h_vnum[_{d}]", "vPFld", "UiUl", [IsStore], MemEltTyInt16, "aarch64_sve_st1">; +def SVST1W_VNUM_S : MInst<"svst1w_vnum[_{d}]", "vPCld", "l", [IsStore], MemEltTyInt32, "aarch64_sve_st1">; +def SVST1W_VNUM_U : MInst<"svst1w_vnum[_{d}]", "vPGld", "Ul", [IsStore], MemEltTyInt32, "aarch64_sve_st1">; + +let ArchGuard = "defined(__ARM_FEATURE_SVE_BF16)" in { + def SVST1_BF : MInst<"svst1[_{d}]", "vPpd", "b", [IsStore], MemEltTyDefault, "aarch64_sve_st1">; + def SVST1_VNUM_BF : MInst<"svst1_vnum[_{d}]", "vPpld", "b", [IsStore], MemEltTyDefault, "aarch64_sve_st1">; +} + +// Store one vector (vector base) +def SVST1_SCATTER_BASES_U : MInst<"svst1_scatter[_{2}base_{d}]", "vPud", "ilUiUlfd", [IsScatterStore], MemEltTyDefault, "aarch64_sve_st1_scatter_scalar_offset">; +def SVST1B_SCATTER_BASES_U : MInst<"svst1b_scatter[_{2}base_{d}]", "vPud", "ilUiUl", [IsScatterStore], MemEltTyInt8, "aarch64_sve_st1_scatter_scalar_offset">; +def SVST1H_SCATTER_BASES_U : MInst<"svst1h_scatter[_{2}base_{d}]", "vPud", "ilUiUl", [IsScatterStore], MemEltTyInt16, "aarch64_sve_st1_scatter_scalar_offset">; +def SVST1W_SCATTER_BASES_U : MInst<"svst1w_scatter[_{2}base_{d}]", "vPud", "lUl", [IsScatterStore], MemEltTyInt32, "aarch64_sve_st1_scatter_scalar_offset">; + +// Store one vector (scalar base, signed vector offset in bytes) +def SVST1_SCATTER_64B_OFFSETS_S : MInst<"svst1_scatter_[{3}]offset[_{d}]", "vPpxd", "lUld", [IsScatterStore, IsByteIndexed], MemEltTyDefault, "aarch64_sve_st1_scatter">; +def SVST1B_SCATTER_64B_OFFSETS_SS : MInst<"svst1b_scatter_[{3}]offset[_{d}]", "vPAxd", "l", [IsScatterStore, IsByteIndexed], MemEltTyInt8, "aarch64_sve_st1_scatter">; +def SVST1B_SCATTER_64B_OFFSETS_SU : MInst<"svst1b_scatter_[{3}]offset[_{d}]", "vPExd", "Ul", [IsScatterStore, IsByteIndexed], MemEltTyInt8, "aarch64_sve_st1_scatter">; +def SVST1H_SCATTER_64B_OFFSETS_SS : MInst<"svst1h_scatter_[{3}]offset[_{d}]", "vPBxd", "l", [IsScatterStore, IsByteIndexed], MemEltTyInt16, "aarch64_sve_st1_scatter">; +def SVST1H_SCATTER_64B_OFFSETS_SU : MInst<"svst1h_scatter_[{3}]offset[_{d}]", "vPFxd", "Ul", [IsScatterStore, IsByteIndexed], MemEltTyInt16, "aarch64_sve_st1_scatter">; +def SVST1W_SCATTER_64B_OFFSETS_SS : MInst<"svst1w_scatter_[{3}]offset[_{d}]", "vPCxd", "l", [IsScatterStore, IsByteIndexed], MemEltTyInt32, "aarch64_sve_st1_scatter">; +def SVST1W_SCATTER_64B_OFFSETS_SU : MInst<"svst1w_scatter_[{3}]offset[_{d}]", "vPGxd", "Ul", [IsScatterStore, IsByteIndexed], MemEltTyInt32, "aarch64_sve_st1_scatter">; + +def SVST1_SCATTER_32B_OFFSETS_S : MInst<"svst1_scatter_[{3}]offset[_{d}]", "vPpxd", "iUif", [IsScatterStore, IsByteIndexed], MemEltTyDefault, "aarch64_sve_st1_scatter_sxtw">; +def SVST1B_SCATTER_32B_OFFSETS_SS : MInst<"svst1b_scatter_[{3}]offset[_{d}]", "vPAxd", "i", [IsScatterStore, IsByteIndexed], MemEltTyInt8, "aarch64_sve_st1_scatter_sxtw">; +def SVST1B_SCATTER_32B_OFFSETS_SU : MInst<"svst1b_scatter_[{3}]offset[_{d}]", "vPExd", "Ui", [IsScatterStore, IsByteIndexed], MemEltTyInt8, "aarch64_sve_st1_scatter_sxtw">; +def SVST1H_SCATTER_32B_OFFSETS_SS : MInst<"svst1h_scatter_[{3}]offset[_{d}]", "vPBxd", "i", [IsScatterStore, IsByteIndexed], MemEltTyInt16, "aarch64_sve_st1_scatter_sxtw">; +def SVST1H_SCATTER_32B_OFFSETS_SU : MInst<"svst1h_scatter_[{3}]offset[_{d}]", "vPFxd", "Ui", [IsScatterStore, IsByteIndexed], MemEltTyInt16, "aarch64_sve_st1_scatter_sxtw">; + +// Store one vector (scalar base, unsigned vector offset in bytes) +def SVST1_SCATTER_64B_OFFSETS_U : MInst<"svst1_scatter_[{3}]offset[_{d}]", "vPpud", "lUld", [IsScatterStore, IsByteIndexed], MemEltTyDefault, "aarch64_sve_st1_scatter">; +def SVST1B_SCATTER_64B_OFFSETS_US : MInst<"svst1b_scatter_[{3}]offset[_{d}]", "vPAud", "l", [IsScatterStore, IsByteIndexed], MemEltTyInt8, "aarch64_sve_st1_scatter">; +def SVST1B_SCATTER_64B_OFFSETS_UU : MInst<"svst1b_scatter_[{3}]offset[_{d}]", "vPEud", "Ul", [IsScatterStore, IsByteIndexed], MemEltTyInt8, "aarch64_sve_st1_scatter">; +def SVST1H_SCATTER_64B_OFFSETS_US : MInst<"svst1h_scatter_[{3}]offset[_{d}]", "vPBud", "l", [IsScatterStore, IsByteIndexed], MemEltTyInt16, "aarch64_sve_st1_scatter">; +def SVST1H_SCATTER_64B_OFFSETS_UU : MInst<"svst1h_scatter_[{3}]offset[_{d}]", "vPFud", "Ul", [IsScatterStore, IsByteIndexed], MemEltTyInt16, "aarch64_sve_st1_scatter">; +def SVST1W_SCATTER_64B_OFFSETS_US : MInst<"svst1w_scatter_[{3}]offset[_{d}]", "vPCud", "l", [IsScatterStore, IsByteIndexed], MemEltTyInt32, "aarch64_sve_st1_scatter">; +def SVST1W_SCATTER_64B_OFFSETS_UU : MInst<"svst1w_scatter_[{3}]offset[_{d}]", "vPGud", "Ul", [IsScatterStore, IsByteIndexed], MemEltTyInt32, "aarch64_sve_st1_scatter">; + +def SVST1_SCATTER_32B_OFFSETS_U : MInst<"svst1_scatter_[{3}]offset[_{d}]", "vPpud", "iUif", [IsScatterStore, IsByteIndexed], MemEltTyDefault, "aarch64_sve_st1_scatter_uxtw">; +def SVST1B_SCATTER_32B_OFFSETS_US : MInst<"svst1b_scatter_[{3}]offset[_{d}]", "vPAud", "i", [IsScatterStore, IsByteIndexed], MemEltTyInt8, "aarch64_sve_st1_scatter_uxtw">; +def SVST1B_SCATTER_32B_OFFSETS_UU : MInst<"svst1b_scatter_[{3}]offset[_{d}]", "vPEud", "Ui", [IsScatterStore, IsByteIndexed], MemEltTyInt8, "aarch64_sve_st1_scatter_uxtw">; +def SVST1H_SCATTER_32B_OFFSETS_US : MInst<"svst1h_scatter_[{3}]offset[_{d}]", "vPBud", "i", [IsScatterStore, IsByteIndexed], MemEltTyInt16, "aarch64_sve_st1_scatter_uxtw">; +def SVST1H_SCATTER_32B_OFFSETS_UU : MInst<"svst1h_scatter_[{3}]offset[_{d}]", "vPFud", "Ui", [IsScatterStore, IsByteIndexed], MemEltTyInt16, "aarch64_sve_st1_scatter_uxtw">; + +// Store one vector (vector base, signed scalar offset in bytes) +def SVST1_SCATTER_OFFSET_S : MInst<"svst1_scatter[_{2}base]_offset[_{d}]", "vPuld", "ilUiUlfd", [IsScatterStore, IsByteIndexed], MemEltTyDefault, "aarch64_sve_st1_scatter_scalar_offset">; +def SVST1B_SCATTER_OFFSET_S : MInst<"svst1b_scatter[_{2}base]_offset[_{d}]", "vPuld", "ilUiUl", [IsScatterStore, IsByteIndexed], MemEltTyInt8, "aarch64_sve_st1_scatter_scalar_offset">; +def SVST1H_SCATTER_OFFSET_S : MInst<"svst1h_scatter[_{2}base]_offset[_{d}]", "vPuld", "ilUiUl", [IsScatterStore, IsByteIndexed], MemEltTyInt16, "aarch64_sve_st1_scatter_scalar_offset">; +def SVST1W_SCATTER_OFFSET_S : MInst<"svst1w_scatter[_{2}base]_offset[_{d}]", "vPuld", "lUl", [IsScatterStore, IsByteIndexed], MemEltTyInt32, "aarch64_sve_st1_scatter_scalar_offset">; + +// Store one vector (scalar base, signed vector index) +def SVST1_SCATTER_64B_INDICES_S : MInst<"svst1_scatter_[{3}]index[_{d}]", "vPpxd", "lUld", [IsScatterStore], MemEltTyDefault, "aarch64_sve_st1_scatter_index">; +def SVST1H_SCATTER_64B_INDICES_SS : MInst<"svst1h_scatter_[{3}]index[_{d}]", "vPBxd", "l", [IsScatterStore], MemEltTyInt16, "aarch64_sve_st1_scatter_index">; +def SVST1H_SCATTER_64B_INDICES_SU : MInst<"svst1h_scatter_[{3}]index[_{d}]", "vPFxd", "Ul", [IsScatterStore], MemEltTyInt16, "aarch64_sve_st1_scatter_index">; +def SVST1W_SCATTER_64B_INDICES_SS : MInst<"svst1w_scatter_[{3}]index[_{d}]", "vPCxd", "l", [IsScatterStore], MemEltTyInt32, "aarch64_sve_st1_scatter_index">; +def SVST1W_SCATTER_64B_INDICES_SU : MInst<"svst1w_scatter_[{3}]index[_{d}]", "vPGxd", "Ul", [IsScatterStore], MemEltTyInt32, "aarch64_sve_st1_scatter_index">; + +def SVST1_SCATTER_32B_INDICES_S : MInst<"svst1_scatter_[{3}]index[_{d}]", "vPpxd", "iUif", [IsScatterStore], MemEltTyDefault, "aarch64_sve_st1_scatter_sxtw_index">; +def SVST1H_SCATTER_32B_INDICES_SS : MInst<"svst1h_scatter_[{3}]index[_{d}]", "vPBxd", "i", [IsScatterStore], MemEltTyInt16, "aarch64_sve_st1_scatter_sxtw_index">; +def SVST1H_SCATTER_32B_INDICES_SU : MInst<"svst1h_scatter_[{3}]index[_{d}]", "vPFxd", "Ui", [IsScatterStore], MemEltTyInt16, "aarch64_sve_st1_scatter_sxtw_index">; + +// Store one vector (scalar base, unsigned vector index) +def SVST1_SCATTER_64B_INDICES_U : MInst<"svst1_scatter_[{3}]index[_{d}]", "vPpud", "lUld", [IsScatterStore], MemEltTyDefault, "aarch64_sve_st1_scatter_index">; +def SVST1H_SCATTER_64B_INDICES_US : MInst<"svst1h_scatter_[{3}]index[_{d}]", "vPBud", "l", [IsScatterStore], MemEltTyInt16, "aarch64_sve_st1_scatter_index">; +def SVST1H_SCATTER_64B_INDICES_UU : MInst<"svst1h_scatter_[{3}]index[_{d}]", "vPFud", "Ul", [IsScatterStore], MemEltTyInt16, "aarch64_sve_st1_scatter_index">; +def SVST1W_SCATTER_64B_INDICES_US : MInst<"svst1w_scatter_[{3}]index[_{d}]", "vPCud", "l", [IsScatterStore], MemEltTyInt32, "aarch64_sve_st1_scatter_index">; +def SVST1W_SCATTER_64B_INDICES_UU : MInst<"svst1w_scatter_[{3}]index[_{d}]", "vPGud", "Ul", [IsScatterStore], MemEltTyInt32, "aarch64_sve_st1_scatter_index">; + +def SVST1_SCATTER_32B_INDICES_U : MInst<"svst1_scatter_[{3}]index[_{d}]", "vPpud", "iUif", [IsScatterStore], MemEltTyDefault, "aarch64_sve_st1_scatter_uxtw_index">; +def SVST1H_SCATTER_32B_INDICES_US : MInst<"svst1h_scatter_[{3}]index[_{d}]", "vPBud", "i", [IsScatterStore], MemEltTyInt16, "aarch64_sve_st1_scatter_uxtw_index">; +def SVST1H_SCATTER_32B_INDICES_UU : MInst<"svst1h_scatter_[{3}]index[_{d}]", "vPFud", "Ui", [IsScatterStore], MemEltTyInt16, "aarch64_sve_st1_scatter_uxtw_index">; + +// Store one vector (vector base, signed scalar index) +def SVST1_SCATTER_INDEX_S : MInst<"svst1_scatter[_{2}base]_index[_{d}]", "vPuld", "ilUiUlfd", [IsScatterStore], MemEltTyDefault, "aarch64_sve_st1_scatter_scalar_offset">; +def SVST1H_SCATTER_INDEX_S : MInst<"svst1h_scatter[_{2}base]_index[_{d}]", "vPuld", "ilUiUl", [IsScatterStore], MemEltTyInt16, "aarch64_sve_st1_scatter_scalar_offset">; +def SVST1W_SCATTER_INDEX_S : MInst<"svst1w_scatter[_{2}base]_index[_{d}]", "vPuld", "lUl", [IsScatterStore], MemEltTyInt32, "aarch64_sve_st1_scatter_scalar_offset">; + +multiclass StructStore<string name, string proto, string i> { + def : SInst<name, proto, "csilUcUsUiUlhfd", MergeNone, i, [IsStructStore]>; + let ArchGuard = "defined(__ARM_FEATURE_SVE_BF16)" in { + def: SInst<name, proto, "b", MergeNone, i, [IsStructStore]>; + } +} +// Store N vectors into N-element structure (scalar base) +defm SVST2 : StructStore<"svst2[_{d}]", "vPp2", "aarch64_sve_st2">; +defm SVST3 : StructStore<"svst3[_{d}]", "vPp3", "aarch64_sve_st3">; +defm SVST4 : StructStore<"svst4[_{d}]", "vPp4", "aarch64_sve_st4">; + +// Store N vectors into N-element structure (scalar base, VL displacement) +defm SVST2_VNUM : StructStore<"svst2_vnum[_{d}]", "vPpl2", "aarch64_sve_st2">; +defm SVST3_VNUM : StructStore<"svst3_vnum[_{d}]", "vPpl3", "aarch64_sve_st3">; +defm SVST4_VNUM : StructStore<"svst4_vnum[_{d}]", "vPpl4", "aarch64_sve_st4">; + +// Store one vector, with no truncation, non-temporal (scalar base) +def SVSTNT1 : MInst<"svstnt1[_{d}]", "vPpd", "csilUcUsUiUlhfd", [IsStore], MemEltTyDefault, "aarch64_sve_stnt1">; + +// Store one vector, with no truncation, non-temporal (scalar base, VL displacement) +def SVSTNT1_VNUM : MInst<"svstnt1_vnum[_{d}]", "vPpld", "csilUcUsUiUlhfd", [IsStore], MemEltTyDefault, "aarch64_sve_stnt1">; + +let ArchGuard = "defined(__ARM_FEATURE_SVE_BF16)" in { + def SVSTNT1_BF : MInst<"svstnt1[_{d}]", "vPpd", "b", [IsStore], MemEltTyDefault, "aarch64_sve_stnt1">; + def SVSTNT1_VNUM_BF : MInst<"svstnt1_vnum[_{d}]", "vPpld", "b", [IsStore], MemEltTyDefault, "aarch64_sve_stnt1">; +} + +//////////////////////////////////////////////////////////////////////////////// +// Prefetches + +// Prefetch (Scalar base) +def SVPRFB : MInst<"svprfb", "vPcJ", "c", [IsPrefetch], MemEltTyInt8, "aarch64_sve_prf">; +def SVPRFH : MInst<"svprfh", "vPcJ", "s", [IsPrefetch], MemEltTyInt16, "aarch64_sve_prf">; +def SVPRFW : MInst<"svprfw", "vPcJ", "i", [IsPrefetch], MemEltTyInt32, "aarch64_sve_prf">; +def SVPRFD : MInst<"svprfd", "vPcJ", "l", [IsPrefetch], MemEltTyInt64, "aarch64_sve_prf">; + +// Prefetch (Scalar base, VL displacement) +def SVPRFB_VNUM : MInst<"svprfb_vnum", "vPclJ", "c", [IsPrefetch], MemEltTyInt8, "aarch64_sve_prf">; +def SVPRFH_VNUM : MInst<"svprfh_vnum", "vPclJ", "s", [IsPrefetch], MemEltTyInt16, "aarch64_sve_prf">; +def SVPRFW_VNUM : MInst<"svprfw_vnum", "vPclJ", "i", [IsPrefetch], MemEltTyInt32, "aarch64_sve_prf">; +def SVPRFD_VNUM : MInst<"svprfd_vnum", "vPclJ", "l", [IsPrefetch], MemEltTyInt64, "aarch64_sve_prf">; + +// Prefetch (Vector bases) +def SVPRFB_GATHER_BASES : MInst<"svprfb_gather[_{2}base]", "vPdJ", "UiUl", [IsGatherPrefetch], MemEltTyInt8, "aarch64_sve_prfb_gather_scalar_offset">; +def SVPRFH_GATHER_BASES : MInst<"svprfh_gather[_{2}base]", "vPdJ", "UiUl", [IsGatherPrefetch], MemEltTyInt16, "aarch64_sve_prfh_gather_scalar_offset">; +def SVPRFW_GATHER_BASES : MInst<"svprfw_gather[_{2}base]", "vPdJ", "UiUl", [IsGatherPrefetch], MemEltTyInt32, "aarch64_sve_prfw_gather_scalar_offset">; +def SVPRFD_GATHER_BASES : MInst<"svprfd_gather[_{2}base]", "vPdJ", "UiUl", [IsGatherPrefetch], MemEltTyInt64, "aarch64_sve_prfd_gather_scalar_offset">; + +// Prefetch (Scalar base, Vector offsets) +def SVPRFB_GATHER_32B_OFFSETS_S : MInst<"svprfb_gather_[{3}]offset", "vPQdJ", "i", [IsGatherPrefetch], MemEltTyInt8, "aarch64_sve_prfb_gather_sxtw_index">; +def SVPRFH_GATHER_32B_OFFSETS_S : MInst<"svprfh_gather_[{3}]index", "vPQdJ", "i", [IsGatherPrefetch], MemEltTyInt16, "aarch64_sve_prfh_gather_sxtw_index">; +def SVPRFW_GATHER_32B_OFFSETS_S : MInst<"svprfw_gather_[{3}]index", "vPQdJ", "i", [IsGatherPrefetch], MemEltTyInt32, "aarch64_sve_prfw_gather_sxtw_index">; +def SVPRFD_GATHER_32B_OFFSETS_S : MInst<"svprfd_gather_[{3}]index", "vPQdJ", "i", [IsGatherPrefetch], MemEltTyInt64, "aarch64_sve_prfd_gather_sxtw_index">; + +def SVPRFB_GATHER_64B_OFFSETS_S : MInst<"svprfb_gather_[{3}]offset", "vPQdJ", "l", [IsGatherPrefetch], MemEltTyInt8, "aarch64_sve_prfb_gather_index">; +def SVPRFH_GATHER_64B_OFFSETS_S : MInst<"svprfh_gather_[{3}]index", "vPQdJ", "l", [IsGatherPrefetch], MemEltTyInt16, "aarch64_sve_prfh_gather_index">; +def SVPRFW_GATHER_64B_OFFSETS_S : MInst<"svprfw_gather_[{3}]index", "vPQdJ", "l", [IsGatherPrefetch], MemEltTyInt32, "aarch64_sve_prfw_gather_index">; +def SVPRFD_GATHER_64B_OFFSETS_S : MInst<"svprfd_gather_[{3}]index", "vPQdJ", "l", [IsGatherPrefetch], MemEltTyInt64, "aarch64_sve_prfd_gather_index">; + +def SVPRFB_GATHER_32B_OFFSETS_U : MInst<"svprfb_gather_[{3}]offset", "vPQdJ", "Ui", [IsGatherPrefetch], MemEltTyInt8, "aarch64_sve_prfb_gather_uxtw_index">; +def SVPRFH_GATHER_32B_OFFSETS_U : MInst<"svprfh_gather_[{3}]index", "vPQdJ", "Ui", [IsGatherPrefetch], MemEltTyInt16, "aarch64_sve_prfh_gather_uxtw_index">; +def SVPRFW_GATHER_32B_OFFSETS_U : MInst<"svprfw_gather_[{3}]index", "vPQdJ", "Ui", [IsGatherPrefetch], MemEltTyInt32, "aarch64_sve_prfw_gather_uxtw_index">; +def SVPRFD_GATHER_32B_OFFSETS_U : MInst<"svprfd_gather_[{3}]index", "vPQdJ", "Ui", [IsGatherPrefetch], MemEltTyInt64, "aarch64_sve_prfd_gather_uxtw_index">; + +def SVPRFB_GATHER_64B_OFFSETS_U : MInst<"svprfb_gather_[{3}]offset", "vPQdJ", "Ul", [IsGatherPrefetch], MemEltTyInt8, "aarch64_sve_prfb_gather_index">; +def SVPRFH_GATHER_64B_OFFSETS_U : MInst<"svprfh_gather_[{3}]index", "vPQdJ", "Ul", [IsGatherPrefetch], MemEltTyInt16, "aarch64_sve_prfh_gather_index">; +def SVPRFW_GATHER_64B_OFFSETS_U : MInst<"svprfw_gather_[{3}]index", "vPQdJ", "Ul", [IsGatherPrefetch], MemEltTyInt32, "aarch64_sve_prfw_gather_index">; +def SVPRFD_GATHER_64B_OFFSETS_U : MInst<"svprfd_gather_[{3}]index", "vPQdJ", "Ul", [IsGatherPrefetch], MemEltTyInt64, "aarch64_sve_prfd_gather_index">; + +// Prefetch (Vector bases, scalar offset) +def SVPRFB_GATHER_BASES_OFFSET : MInst<"svprfb_gather[_{2}base]_offset", "vPdlJ", "UiUl", [IsGatherPrefetch], MemEltTyInt8, "aarch64_sve_prfb_gather_scalar_offset">; +def SVPRFH_GATHER_BASES_OFFSET : MInst<"svprfh_gather[_{2}base]_index", "vPdlJ", "UiUl", [IsGatherPrefetch], MemEltTyInt16, "aarch64_sve_prfh_gather_scalar_offset">; +def SVPRFW_GATHER_BASES_OFFSET : MInst<"svprfw_gather[_{2}base]_index", "vPdlJ", "UiUl", [IsGatherPrefetch], MemEltTyInt32, "aarch64_sve_prfw_gather_scalar_offset">; +def SVPRFD_GATHER_BASES_OFFSET : MInst<"svprfd_gather[_{2}base]_index", "vPdlJ", "UiUl", [IsGatherPrefetch], MemEltTyInt64, "aarch64_sve_prfd_gather_scalar_offset">; + +//////////////////////////////////////////////////////////////////////////////// +// Address calculations + +def SVADRB : SInst<"svadrb[_{0}base]_[{2}]offset", "uud", "ilUiUl", MergeNone, "aarch64_sve_adrb">; +def SVADRH : SInst<"svadrh[_{0}base]_[{2}]index", "uud", "ilUiUl", MergeNone, "aarch64_sve_adrh">; +def SVADRW : SInst<"svadrw[_{0}base]_[{2}]index", "uud", "ilUiUl", MergeNone, "aarch64_sve_adrw">; +def SVADRD : SInst<"svadrd[_{0}base]_[{2}]index", "uud", "ilUiUl", MergeNone, "aarch64_sve_adrd">; + +//////////////////////////////////////////////////////////////////////////////// +// Scalar to vector + +def SVDUPQ_8 : SInst<"svdupq[_n]_{d}", "dssssssssssssssss", "cUc", MergeNone>; +def SVDUPQ_16 : SInst<"svdupq[_n]_{d}", "dssssssss", "sUsh", MergeNone>; +let ArchGuard = "defined(__ARM_FEATURE_SVE_BF16)" in { + def SVDUPQ_BF16 : SInst<"svdupq[_n]_{d}", "dssssssss", "b", MergeNone>; +} +def SVDUPQ_32 : SInst<"svdupq[_n]_{d}", "dssss", "iUif", MergeNone>; +def SVDUPQ_64 : SInst<"svdupq[_n]_{d}", "dss", "lUld", MergeNone>; + +multiclass svdup_base<string n, string p, MergeType mt, string i> { + def NAME : SInst<n, p, "csilUcUsUiUlhfd", mt, i>; + let ArchGuard = "defined(__ARM_FEATURE_SVE_BF16)" in { + def _BF16: SInst<n, p, "b", mt, i>; + } +} + +defm SVDUP : svdup_base<"svdup[_n]_{d}", "ds", MergeNone, "aarch64_sve_dup_x">; +defm SVDUP_M : svdup_base<"svdup[_n]_{d}", "ddPs", MergeOp1, "aarch64_sve_dup">; +defm SVDUP_X : svdup_base<"svdup[_n]_{d}", "dPs", MergeAnyExp, "aarch64_sve_dup">; +defm SVDUP_Z : svdup_base<"svdup[_n]_{d}", "dPs", MergeZeroExp, "aarch64_sve_dup">; + +def SVINDEX : SInst<"svindex_{d}", "dss", "csilUcUsUiUl", MergeNone, "aarch64_sve_index">; + +// Integer arithmetic + +multiclass SInstZPZ<string name, string types, string intrinsic, list<FlagType> flags=[]> { + def _M : SInst<name # "[_{d}]", "ddPd", types, MergeOp1, intrinsic, flags>; + def _X : SInst<name # "[_{d}]", "dPd", types, MergeAnyExp, intrinsic, flags>; + def _Z : SInst<name # "[_{d}]", "dPd", types, MergeZeroExp, intrinsic, flags>; +} + +defm SVABS : SInstZPZ<"svabs", "csil", "aarch64_sve_abs">; +defm SVNEG : SInstZPZ<"svneg", "csil", "aarch64_sve_neg">; + +//------------------------------------------------------------------------------ + +multiclass SInstZPZZ<string name, string types, string intrinsic, list<FlagType> flags=[]> { + def _M : SInst<name # "[_{d}]", "dPdd", types, MergeOp1, intrinsic, flags>; + def _X : SInst<name # "[_{d}]", "dPdd", types, MergeAny, intrinsic, flags>; + def _Z : SInst<name # "[_{d}]", "dPdd", types, MergeZero, intrinsic, flags>; + + def _N_M : SInst<name # "[_n_{d}]", "dPda", types, MergeOp1, intrinsic, flags>; + def _N_X : SInst<name # "[_n_{d}]", "dPda", types, MergeAny, intrinsic, flags>; + def _N_Z : SInst<name # "[_n_{d}]", "dPda", types, MergeZero, intrinsic, flags>; +} + +defm SVABD_S : SInstZPZZ<"svabd", "csil", "aarch64_sve_sabd">; +defm SVABD_U : SInstZPZZ<"svabd", "UcUsUiUl", "aarch64_sve_uabd">; +defm SVADD : SInstZPZZ<"svadd", "csilUcUsUiUl", "aarch64_sve_add">; +defm SVDIV_S : SInstZPZZ<"svdiv", "il", "aarch64_sve_sdiv">; +defm SVDIV_U : SInstZPZZ<"svdiv", "UiUl", "aarch64_sve_udiv">; +defm SVDIVR_S : SInstZPZZ<"svdivr", "il", "aarch64_sve_sdivr">; +defm SVDIVR_U : SInstZPZZ<"svdivr", "UiUl", "aarch64_sve_udivr">; +defm SVMAX_S : SInstZPZZ<"svmax", "csil", "aarch64_sve_smax">; +defm SVMAX_U : SInstZPZZ<"svmax", "UcUsUiUl", "aarch64_sve_umax">; +defm SVMIN_S : SInstZPZZ<"svmin", "csil", "aarch64_sve_smin">; +defm SVMIN_U : SInstZPZZ<"svmin", "UcUsUiUl", "aarch64_sve_umin">; +defm SVMUL : SInstZPZZ<"svmul", "csilUcUsUiUl", "aarch64_sve_mul">; +defm SVMULH_S : SInstZPZZ<"svmulh", "csil", "aarch64_sve_smulh">; +defm SVMULH_U : SInstZPZZ<"svmulh", "UcUsUiUl", "aarch64_sve_umulh">; +defm SVSUB : SInstZPZZ<"svsub", "csilUcUsUiUl", "aarch64_sve_sub">; +defm SVSUBR : SInstZPZZ<"svsubr", "csilUcUsUiUl", "aarch64_sve_subr">; + +//------------------------------------------------------------------------------ + +multiclass SInstZPZZZ<string name, string types, string intrinsic, list<FlagType> flags=[]> { + def _M : SInst<name # "[_{d}]", "dPddd", types, MergeOp1, intrinsic, flags>; + def _X : SInst<name # "[_{d}]", "dPddd", types, MergeAny, intrinsic, flags>; + def _Z : SInst<name # "[_{d}]", "dPddd", types, MergeZero, intrinsic, flags>; + + def _N_M : SInst<name # "[_n_{d}]", "dPdda", types, MergeOp1, intrinsic, flags>; + def _N_X : SInst<name # "[_n_{d}]", "dPdda", types, MergeAny, intrinsic, flags>; + def _N_Z : SInst<name # "[_n_{d}]", "dPdda", types, MergeZero, intrinsic, flags>; +} + +defm SVMAD : SInstZPZZZ<"svmad", "csilUcUsUiUl", "aarch64_sve_mad">; +defm SVMLA : SInstZPZZZ<"svmla", "csilUcUsUiUl", "aarch64_sve_mla">; +defm SVMLS : SInstZPZZZ<"svmls", "csilUcUsUiUl", "aarch64_sve_mls">; +defm SVMSB : SInstZPZZZ<"svmsb", "csilUcUsUiUl", "aarch64_sve_msb">; + +//------------------------------------------------------------------------------ + +def SVDOT_S : SInst<"svdot[_{0}]", "ddqq", "il", MergeNone, "aarch64_sve_sdot">; +def SVDOT_U : SInst<"svdot[_{0}]", "ddqq", "UiUl", MergeNone, "aarch64_sve_udot">; +def SVQADD_S : SInst<"svqadd[_{d}]", "ddd", "csil", MergeNone, "aarch64_sve_sqadd_x">; +def SVQADD_U : SInst<"svqadd[_{d}]", "ddd", "UcUsUiUl", MergeNone, "aarch64_sve_uqadd_x">; +def SVQSUB_S : SInst<"svqsub[_{d}]", "ddd", "csil", MergeNone, "aarch64_sve_sqsub_x">; +def SVQSUB_U : SInst<"svqsub[_{d}]", "ddd", "UcUsUiUl", MergeNone, "aarch64_sve_uqsub_x">; + +def SVDOT_N_S : SInst<"svdot[_n_{0}]", "ddqr", "il", MergeNone, "aarch64_sve_sdot">; +def SVDOT_N_U : SInst<"svdot[_n_{0}]", "ddqr", "UiUl", MergeNone, "aarch64_sve_udot">; +def SVQADD_N_S : SInst<"svqadd[_n_{d}]", "dda", "csil", MergeNone, "aarch64_sve_sqadd_x">; +def SVQADD_N_U : SInst<"svqadd[_n_{d}]", "dda", "UcUsUiUl", MergeNone, "aarch64_sve_uqadd_x">; +def SVQSUB_N_S : SInst<"svqsub[_n_{d}]", "dda", "csil", MergeNone, "aarch64_sve_sqsub_x">; +def SVQSUB_N_U : SInst<"svqsub[_n_{d}]", "dda", "UcUsUiUl", MergeNone, "aarch64_sve_uqsub_x">; + +def SVDOT_LANE_S : SInst<"svdot_lane[_{d}]", "ddqqi", "il", MergeNone, "aarch64_sve_sdot_lane", [], [ImmCheck<3, ImmCheckLaneIndexDot, 2>]>; +def SVDOT_LANE_U : SInst<"svdot_lane[_{d}]", "ddqqi", "UiUl", MergeNone, "aarch64_sve_udot_lane", [], [ImmCheck<3, ImmCheckLaneIndexDot, 2>]>; + +//////////////////////////////////////////////////////////////////////////////// +// Logical operations + +defm SVAND : SInstZPZZ<"svand", "csilUcUsUiUl", "aarch64_sve_and">; +defm SVBIC : SInstZPZZ<"svbic", "csilUcUsUiUl", "aarch64_sve_bic">; +defm SVEOR : SInstZPZZ<"sveor", "csilUcUsUiUl", "aarch64_sve_eor">; +defm SVORR : SInstZPZZ<"svorr", "csilUcUsUiUl", "aarch64_sve_orr">; + +defm SVCNOT : SInstZPZ<"svcnot", "csilUcUsUiUl", "aarch64_sve_cnot">; +defm SVNOT : SInstZPZ<"svnot", "csilUcUsUiUl", "aarch64_sve_not">; + +//////////////////////////////////////////////////////////////////////////////// +// Shifts + +multiclass SInst_SHIFT<string name, string intrinsic, string ts, string wide_ts> { + def _M : SInst<name # "[_{d}]", "dPdu", ts, MergeOp1, intrinsic>; + def _X : SInst<name # "[_{d}]", "dPdu", ts, MergeAny, intrinsic>; + def _Z : SInst<name # "[_{d}]", "dPdu", ts, MergeZero, intrinsic>; + + def _N_M : SInst<name # "[_n_{d}]", "dPdL", ts, MergeOp1, intrinsic>; + def _N_X : SInst<name # "[_n_{d}]", "dPdL", ts, MergeAny, intrinsic>; + def _N_Z : SInst<name # "[_n_{d}]", "dPdL", ts, MergeZero, intrinsic>; + + def _WIDE_M : SInst<name # _wide # "[_{d}]", "dPdg", wide_ts, MergeOp1, intrinsic # _wide>; + def _WIDE_X : SInst<name # _wide # "[_{d}]", "dPdg", wide_ts, MergeAny, intrinsic # _wide>; + def _WIDE_Z : SInst<name # _wide # "[_{d}]", "dPdg", wide_ts, MergeZero, intrinsic # _wide>; + + def _WIDE_N_M : SInst<name # _wide # "[_n_{d}]", "dPdf", wide_ts, MergeOp1, intrinsic # _wide>; + def _WIDE_N_X : SInst<name # _wide # "[_n_{d}]", "dPdf", wide_ts, MergeAny, intrinsic # _wide>; + def _WIDE_N_Z : SInst<name # _wide # "[_n_{d}]", "dPdf", wide_ts, MergeZero, intrinsic # _wide>; +} + +defm SVASR : SInst_SHIFT<"svasr", "aarch64_sve_asr", "csil", "csi">; +defm SVLSL : SInst_SHIFT<"svlsl", "aarch64_sve_lsl", "csilUcUsUiUl", "csiUcUsUi">; +defm SVLSR : SInst_SHIFT<"svlsr", "aarch64_sve_lsr", "UcUsUiUl", "UcUsUi">; + +def SVASRD_M : SInst<"svasrd[_n_{d}]", "dPdi", "csil", MergeOp1, "aarch64_sve_asrd", [], [ImmCheck<2, ImmCheckShiftRight, 1>]>; +def SVASRD_X : SInst<"svasrd[_n_{d}]", "dPdi", "csil", MergeAny, "aarch64_sve_asrd", [], [ImmCheck<2, ImmCheckShiftRight, 1>]>; +def SVASRD_Z : SInst<"svasrd[_n_{d}]", "dPdi", "csil", MergeZero, "aarch64_sve_asrd", [], [ImmCheck<2, ImmCheckShiftRight, 1>]>; + +def SVINSR : SInst<"svinsr[_n_{d}]", "dds", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_insr">; +let ArchGuard = "defined(__ARM_FEATURE_SVE_BF16)" in { + def SVINSR_BF16 : SInst<"svinsr[_n_{d}]", "dds", "b", MergeNone, "aarch64_sve_insr">; +} + +//////////////////////////////////////////////////////////////////////////////// +// Integer reductions + +def SVADDV_S : SInst<"svaddv[_{d}]", "lPd", "csil", MergeNone, "aarch64_sve_saddv">; +def SVADDV_U : SInst<"svaddv[_{d}]", "nPd", "UcUsUiUl", MergeNone, "aarch64_sve_uaddv">; +def SVANDV : SInst<"svandv[_{d}]", "sPd", "csilUcUsUiUl", MergeNone, "aarch64_sve_andv">; +def SVEORV : SInst<"sveorv[_{d}]", "sPd", "csilUcUsUiUl", MergeNone, "aarch64_sve_eorv">; +def SVMAXV_S : SInst<"svmaxv[_{d}]", "sPd", "csil", MergeNone, "aarch64_sve_smaxv">; +def SVMAXV_U : SInst<"svmaxv[_{d}]", "sPd", "UcUsUiUl", MergeNone, "aarch64_sve_umaxv">; +def SVMINV_S : SInst<"svminv[_{d}]", "sPd", "csil", MergeNone, "aarch64_sve_sminv">; +def SVMINV_U : SInst<"svminv[_{d}]", "sPd", "UcUsUiUl", MergeNone, "aarch64_sve_uminv">; +def SVORV : SInst<"svorv[_{d}]", "sPd", "csilUcUsUiUl", MergeNone, "aarch64_sve_orv">; + +//////////////////////////////////////////////////////////////////////////////// +// Integer comparisons + +def SVCMPEQ : SInst<"svcmpeq[_{d}]", "PPdd", "csilUcUsUiUl", MergeNone, "aarch64_sve_cmpeq">; +def SVCMPNE : SInst<"svcmpne[_{d}]", "PPdd", "csilUcUsUiUl", MergeNone, "aarch64_sve_cmpne">; +def SVCMPGE : SInst<"svcmpge[_{d}]", "PPdd", "csil", MergeNone, "aarch64_sve_cmpge">; +def SVCMPGT : SInst<"svcmpgt[_{d}]", "PPdd", "csil", MergeNone, "aarch64_sve_cmpgt">; +def SVCMPLE : SInst<"svcmple[_{d}]", "PPdd", "csil", MergeNone, "aarch64_sve_cmpge", [ReverseCompare]>; +def SVCMPLT : SInst<"svcmplt[_{d}]", "PPdd", "csil", MergeNone, "aarch64_sve_cmpgt", [ReverseCompare]>; +def SVCMPHI : SInst<"svcmpgt[_{d}]", "PPdd", "UcUsUiUl", MergeNone, "aarch64_sve_cmphi">; +def SVCMPHS : SInst<"svcmpge[_{d}]", "PPdd", "UcUsUiUl", MergeNone, "aarch64_sve_cmphs">; +def SVCMPLO : SInst<"svcmplt[_{d}]", "PPdd", "UcUsUiUl", MergeNone, "aarch64_sve_cmphi", [ReverseCompare]>; +def SVCMPLS : SInst<"svcmple[_{d}]", "PPdd", "UcUsUiUl", MergeNone, "aarch64_sve_cmphs", [ReverseCompare]>; + +def SVCMPEQ_N : SInst<"svcmpeq[_n_{d}]", "PPda", "csilUcUsUiUl", MergeNone, "aarch64_sve_cmpeq">; +def SVCMPNE_N : SInst<"svcmpne[_n_{d}]", "PPda", "csilUcUsUiUl", MergeNone, "aarch64_sve_cmpne">; +def SVCMPGE_N : SInst<"svcmpge[_n_{d}]", "PPda", "csil", MergeNone, "aarch64_sve_cmpge">; +def SVCMPGT_N : SInst<"svcmpgt[_n_{d}]", "PPda", "csil", MergeNone, "aarch64_sve_cmpgt">; +def SVCMPLE_N : SInst<"svcmple[_n_{d}]", "PPda", "csil", MergeNone, "aarch64_sve_cmpge", [ReverseCompare]>; +def SVCMPLT_N : SInst<"svcmplt[_n_{d}]", "PPda", "csil", MergeNone, "aarch64_sve_cmpgt", [ReverseCompare]>; +def SVCMPHS_N : SInst<"svcmpge[_n_{d}]", "PPda", "UcUsUiUl", MergeNone, "aarch64_sve_cmphs">; +def SVCMPHI_N : SInst<"svcmpgt[_n_{d}]", "PPda", "UcUsUiUl", MergeNone, "aarch64_sve_cmphi">; +def SVCMPLS_N : SInst<"svcmple[_n_{d}]", "PPda", "UcUsUiUl", MergeNone, "aarch64_sve_cmphs", [ReverseCompare]>; +def SVCMPLO_N : SInst<"svcmplt[_n_{d}]", "PPda", "UcUsUiUl", MergeNone, "aarch64_sve_cmphi", [ReverseCompare]>; + +def SVCMPEQ_WIDE : SInst<"svcmpeq_wide[_{d}]", "PPdw", "csi", MergeNone, "aarch64_sve_cmpeq_wide">; +def SVCMPNE_WIDE : SInst<"svcmpne_wide[_{d}]", "PPdw", "csi", MergeNone, "aarch64_sve_cmpne_wide">; +def SVCMPGE_WIDE : SInst<"svcmpge_wide[_{d}]", "PPdw", "csi", MergeNone, "aarch64_sve_cmpge_wide">; +def SVCMPGT_WIDE : SInst<"svcmpgt_wide[_{d}]", "PPdw", "csi", MergeNone, "aarch64_sve_cmpgt_wide">; +def SVCMPLE_WIDE : SInst<"svcmple_wide[_{d}]", "PPdw", "csi", MergeNone, "aarch64_sve_cmple_wide">; +def SVCMPLT_WIDE : SInst<"svcmplt_wide[_{d}]", "PPdw", "csi", MergeNone, "aarch64_sve_cmplt_wide">; +def SVCMPHI_WIDE : SInst<"svcmpgt_wide[_{d}]", "PPdw", "UcUsUi", MergeNone, "aarch64_sve_cmphi_wide">; +def SVCMPHS_WIDE : SInst<"svcmpge_wide[_{d}]", "PPdw", "UcUsUi", MergeNone, "aarch64_sve_cmphs_wide">; +def SVCMPLO_WIDE : SInst<"svcmplt_wide[_{d}]", "PPdw", "UcUsUi", MergeNone, "aarch64_sve_cmplo_wide">; +def SVCMPLS_WIDE : SInst<"svcmple_wide[_{d}]", "PPdw", "UcUsUi", MergeNone, "aarch64_sve_cmpls_wide">; + +def SVCMPEQ_WIDE_N : SInst<"svcmpeq_wide[_n_{d}]", "PPdj", "csi", MergeNone, "aarch64_sve_cmpeq_wide">; +def SVCMPNE_WIDE_N : SInst<"svcmpne_wide[_n_{d}]", "PPdj", "csi", MergeNone, "aarch64_sve_cmpne_wide">; +def SVCMPGE_WIDE_N : SInst<"svcmpge_wide[_n_{d}]", "PPdj", "csi", MergeNone, "aarch64_sve_cmpge_wide">; +def SVCMPGT_WIDE_N : SInst<"svcmpgt_wide[_n_{d}]", "PPdj", "csi", MergeNone, "aarch64_sve_cmpgt_wide">; +def SVCMPLE_WIDE_N : SInst<"svcmple_wide[_n_{d}]", "PPdj", "csi", MergeNone, "aarch64_sve_cmple_wide">; +def SVCMPLT_WIDE_N : SInst<"svcmplt_wide[_n_{d}]", "PPdj", "csi", MergeNone, "aarch64_sve_cmplt_wide">; +def SVCMPHS_WIDE_N : SInst<"svcmpge_wide[_n_{d}]", "PPdj", "UcUsUi", MergeNone, "aarch64_sve_cmphs_wide">; +def SVCMPHI_WIDE_N : SInst<"svcmpgt_wide[_n_{d}]", "PPdj", "UcUsUi", MergeNone, "aarch64_sve_cmphi_wide">; +def SVCMPLO_WIDE_N : SInst<"svcmplt_wide[_n_{d}]", "PPdj", "UcUsUi", MergeNone, "aarch64_sve_cmplo_wide">; +def SVCMPLS_WIDE_N : SInst<"svcmple_wide[_n_{d}]", "PPdj", "UcUsUi", MergeNone, "aarch64_sve_cmpls_wide">; + +//////////////////////////////////////////////////////////////////////////////// +// While comparisons + +def SVWHILELE_S32 : SInst<"svwhilele_{d}[_{1}]", "Pkk", "PcPsPiPl", MergeNone, "aarch64_sve_whilele", [IsOverloadWhile]>; +def SVWHILELE_S64 : SInst<"svwhilele_{d}[_{1}]", "Pll", "PcPsPiPl", MergeNone, "aarch64_sve_whilele", [IsOverloadWhile]>; +def SVWHILELO_U32 : SInst<"svwhilelt_{d}[_{1}]", "Pmm", "PUcPUsPUiPUl", MergeNone, "aarch64_sve_whilelo", [IsOverloadWhile]>; +def SVWHILELO_U64 : SInst<"svwhilelt_{d}[_{1}]", "Pnn", "PUcPUsPUiPUl", MergeNone, "aarch64_sve_whilelo", [IsOverloadWhile]>; +def SVWHILELS_U32 : SInst<"svwhilele_{d}[_{1}]", "Pmm", "PUcPUsPUiPUl", MergeNone, "aarch64_sve_whilels", [IsOverloadWhile]>; +def SVWHILELS_U64 : SInst<"svwhilele_{d}[_{1}]", "Pnn", "PUcPUsPUiPUl", MergeNone, "aarch64_sve_whilels", [IsOverloadWhile]>; +def SVWHILELT_S32 : SInst<"svwhilelt_{d}[_{1}]", "Pkk", "PcPsPiPl", MergeNone, "aarch64_sve_whilelt", [IsOverloadWhile]>; +def SVWHILELT_S64 : SInst<"svwhilelt_{d}[_{1}]", "Pll", "PcPsPiPl", MergeNone, "aarch64_sve_whilelt", [IsOverloadWhile]>; + +//////////////////////////////////////////////////////////////////////////////// +// Counting bit + +multiclass SInstCLS<string name, string types, string intrinsic, list<FlagType> flags=[]> { + def _M : SInst<name # "[_{d}]", "uuPd", types, MergeOp1, intrinsic, flags>; + def _X : SInst<name # "[_{d}]", "uPd", types, MergeAnyExp, intrinsic, flags>; + def _Z : SInst<name # "[_{d}]", "uPd", types, MergeZeroExp, intrinsic, flags>; +} + +defm SVCLS : SInstCLS<"svcls", "csil", "aarch64_sve_cls">; +defm SVCLZ : SInstCLS<"svclz", "csilUcUsUiUl", "aarch64_sve_clz">; +defm SVCNT : SInstCLS<"svcnt", "csilUcUsUiUlhfd", "aarch64_sve_cnt">; + +let ArchGuard = "defined(__ARM_FEATURE_SVE_BF16)" in { + defm SVCNT_BF16 : SInstCLS<"svcnt", "b", "aarch64_sve_cnt">; +} + +//////////////////////////////////////////////////////////////////////////////// +// Conversion + +defm SVEXTB_S : SInstZPZ<"svextb", "sil", "aarch64_sve_sxtb">; +defm SVEXTB_U : SInstZPZ<"svextb", "UsUiUl", "aarch64_sve_uxtb">; +defm SVEXTH_S : SInstZPZ<"svexth", "il", "aarch64_sve_sxth">; +defm SVEXTH_U : SInstZPZ<"svexth", "UiUl", "aarch64_sve_uxth">; +defm SVEXTW_S : SInstZPZ<"svextw", "l", "aarch64_sve_sxtw">; +defm SVEXTW_U : SInstZPZ<"svextw", "Ul", "aarch64_sve_uxtw">; + +//////////////////////////////////////////////////////////////////////////////// +// Reversal + +defm SVRBIT : SInstZPZ<"svrbit", "csilUcUsUiUl", "aarch64_sve_rbit">; +defm SVREVB : SInstZPZ<"svrevb", "silUsUiUl", "aarch64_sve_revb">; +defm SVREVH : SInstZPZ<"svrevh", "ilUiUl", "aarch64_sve_revh">; +defm SVREVW : SInstZPZ<"svrevw", "lUl", "aarch64_sve_revw">; + +//////////////////////////////////////////////////////////////////////////////// +// Floating-point arithmetic + +defm SVABS_F : SInstZPZ<"svabs", "hfd", "aarch64_sve_fabs">; +defm SVNEG_F : SInstZPZ<"svneg", "hfd", "aarch64_sve_fneg">; + +defm SVABD_F : SInstZPZZ<"svabd", "hfd", "aarch64_sve_fabd">; +defm SVADD_F : SInstZPZZ<"svadd", "hfd", "aarch64_sve_fadd">; +defm SVDIV_F : SInstZPZZ<"svdiv", "hfd", "aarch64_sve_fdiv">; +defm SVDIVR_F : SInstZPZZ<"svdivr", "hfd", "aarch64_sve_fdivr">; +defm SVMAX_F : SInstZPZZ<"svmax", "hfd", "aarch64_sve_fmax">; +defm SVMAXNM : SInstZPZZ<"svmaxnm","hfd", "aarch64_sve_fmaxnm">; +defm SVMIN_F : SInstZPZZ<"svmin", "hfd", "aarch64_sve_fmin">; +defm SVMINNM : SInstZPZZ<"svminnm","hfd", "aarch64_sve_fminnm">; +defm SVMUL_F : SInstZPZZ<"svmul", "hfd", "aarch64_sve_fmul">; +defm SVMULX : SInstZPZZ<"svmulx", "hfd", "aarch64_sve_fmulx">; +defm SVSUB_F : SInstZPZZ<"svsub", "hfd", "aarch64_sve_fsub">; +defm SVSUBR_F : SInstZPZZ<"svsubr", "hfd", "aarch64_sve_fsubr">; + +defm SVRECPX : SInstZPZ<"svrecpx", "hfd", "aarch64_sve_frecpx">; +defm SVRINTA : SInstZPZ<"svrinta", "hfd", "aarch64_sve_frinta">; +defm SVRINTI : SInstZPZ<"svrinti", "hfd", "aarch64_sve_frinti">; +defm SVRINTM : SInstZPZ<"svrintm", "hfd", "aarch64_sve_frintm">; +defm SVRINTN : SInstZPZ<"svrintn", "hfd", "aarch64_sve_frintn">; +defm SVRINTP : SInstZPZ<"svrintp", "hfd", "aarch64_sve_frintp">; +defm SVRINTX : SInstZPZ<"svrintx", "hfd", "aarch64_sve_frintx">; +defm SVRINTZ : SInstZPZ<"svrintz", "hfd", "aarch64_sve_frintz">; +defm SVSQRT : SInstZPZ<"svsqrt", "hfd", "aarch64_sve_fsqrt">; + +def SVEXPA : SInst<"svexpa[_{d}]", "du", "hfd", MergeNone, "aarch64_sve_fexpa_x">; +def SVTMAD : SInst<"svtmad[_{d}]", "dddi", "hfd", MergeNone, "aarch64_sve_ftmad_x", [], [ImmCheck<2, ImmCheck0_7>]>; +def SVTSMUL : SInst<"svtsmul[_{d}]", "ddu", "hfd", MergeNone, "aarch64_sve_ftsmul_x">; +def SVTSSEL : SInst<"svtssel[_{d}]", "ddu", "hfd", MergeNone, "aarch64_sve_ftssel_x">; + +def SVSCALE_M : SInst<"svscale[_{d}]", "dPdx", "hfd", MergeOp1, "aarch64_sve_fscale">; +def SVSCALE_X : SInst<"svscale[_{d}]", "dPdx", "hfd", MergeAny, "aarch64_sve_fscale">; +def SVSCALE_Z : SInst<"svscale[_{d}]", "dPdx", "hfd", MergeZero, "aarch64_sve_fscale">; + +def SVSCALE_N_M : SInst<"svscale[_n_{d}]", "dPdK", "hfd", MergeOp1, "aarch64_sve_fscale">; +def SVSCALE_N_X : SInst<"svscale[_n_{d}]", "dPdK", "hfd", MergeAny, "aarch64_sve_fscale">; +def SVSCALE_N_Z : SInst<"svscale[_n_{d}]", "dPdK", "hfd", MergeZero, "aarch64_sve_fscale">; + +defm SVMAD_F : SInstZPZZZ<"svmad", "hfd", "aarch64_sve_fmad">; +defm SVMLA_F : SInstZPZZZ<"svmla", "hfd", "aarch64_sve_fmla">; +defm SVMLS_F : SInstZPZZZ<"svmls", "hfd", "aarch64_sve_fmls">; +defm SVMSB_F : SInstZPZZZ<"svmsb", "hfd", "aarch64_sve_fmsb">; +defm SVNMAD_F : SInstZPZZZ<"svnmad", "hfd", "aarch64_sve_fnmad">; +defm SVNMLA_F : SInstZPZZZ<"svnmla", "hfd", "aarch64_sve_fnmla">; +defm SVNMLS_F : SInstZPZZZ<"svnmls", "hfd", "aarch64_sve_fnmls">; +defm SVNMSB_F : SInstZPZZZ<"svnmsb", "hfd", "aarch64_sve_fnmsb">; + +def SVCADD_M : SInst<"svcadd[_{d}]", "dPddi", "hfd", MergeOp1, "aarch64_sve_fcadd", [], [ImmCheck<3, ImmCheckComplexRot90_270>]>; +def SVCADD_X : SInst<"svcadd[_{d}]", "dPddi", "hfd", MergeAny, "aarch64_sve_fcadd", [], [ImmCheck<3, ImmCheckComplexRot90_270>]>; +def SVCADD_Z : SInst<"svcadd[_{d}]", "dPddi", "hfd", MergeZero, "aarch64_sve_fcadd", [], [ImmCheck<3, ImmCheckComplexRot90_270>]>; +def SVCMLA_M : SInst<"svcmla[_{d}]", "dPdddi", "hfd", MergeOp1, "aarch64_sve_fcmla", [], [ImmCheck<4, ImmCheckComplexRotAll90>]>; +def SVCMLA_X : SInst<"svcmla[_{d}]", "dPdddi", "hfd", MergeAny, "aarch64_sve_fcmla", [], [ImmCheck<4, ImmCheckComplexRotAll90>]>; +def SVCMLA_Z : SInst<"svcmla[_{d}]", "dPdddi", "hfd", MergeZero, "aarch64_sve_fcmla", [], [ImmCheck<4, ImmCheckComplexRotAll90>]>; + +def SVCMLA_LANE : SInst<"svcmla_lane[_{d}]", "ddddii", "hf", MergeNone, "aarch64_sve_fcmla_lane", [], [ImmCheck<3, ImmCheckLaneIndexCompRotate, 2>, + ImmCheck<4, ImmCheckComplexRotAll90>]>; +def SVMLA_LANE : SInst<"svmla_lane[_{d}]", "ddddi", "hfd", MergeNone, "aarch64_sve_fmla_lane", [], [ImmCheck<3, ImmCheckLaneIndex, 2>]>; +def SVMLS_LANE : SInst<"svmls_lane[_{d}]", "ddddi", "hfd", MergeNone, "aarch64_sve_fmls_lane", [], [ImmCheck<3, ImmCheckLaneIndex, 2>]>; +def SVMUL_LANE : SInst<"svmul_lane[_{d}]", "dddi", "hfd", MergeNone, "aarch64_sve_fmul_lane", [], [ImmCheck<2, ImmCheckLaneIndex, 1>]>; + +def SVRECPE : SInst<"svrecpe[_{d}]", "dd", "hfd", MergeNone, "aarch64_sve_frecpe_x">; +def SVRECPS : SInst<"svrecps[_{d}]", "ddd", "hfd", MergeNone, "aarch64_sve_frecps_x">; +def SVRSQRTE : SInst<"svrsqrte[_{d}]", "dd", "hfd", MergeNone, "aarch64_sve_frsqrte_x">; +def SVRSQRTS : SInst<"svrsqrts[_{d}]", "ddd", "hfd", MergeNone, "aarch64_sve_frsqrts_x">; + +//////////////////////////////////////////////////////////////////////////////// +// Floating-point reductions + +def SVFADDA : SInst<"svadda[_{d}]", "sPsd", "hfd", MergeNone, "aarch64_sve_fadda">; +def SVFADDV : SInst<"svaddv[_{d}]", "sPd", "hfd", MergeNone, "aarch64_sve_faddv">; +def SVFMAXV : SInst<"svmaxv[_{d}]", "sPd", "hfd", MergeNone, "aarch64_sve_fmaxv">; +def SVFMAXNMV : SInst<"svmaxnmv[_{d}]", "sPd", "hfd", MergeNone, "aarch64_sve_fmaxnmv">; +def SVFMINV : SInst<"svminv[_{d}]", "sPd", "hfd", MergeNone, "aarch64_sve_fminv">; +def SVFMINNMV : SInst<"svminnmv[_{d}]", "sPd", "hfd", MergeNone, "aarch64_sve_fminnmv">; + +//////////////////////////////////////////////////////////////////////////////// +// Floating-point comparisons + +def SVACGE : SInst<"svacge[_{d}]", "PPdd", "hfd", MergeNone, "aarch64_sve_facge">; +def SVACGT : SInst<"svacgt[_{d}]", "PPdd", "hfd", MergeNone, "aarch64_sve_facgt">; +def SVACLE : SInst<"svacle[_{d}]", "PPdd", "hfd", MergeNone, "aarch64_sve_facge", [ReverseCompare]>; +def SVACLT : SInst<"svaclt[_{d}]", "PPdd", "hfd", MergeNone, "aarch64_sve_facgt", [ReverseCompare]>; +def SVCMPUO : SInst<"svcmpuo[_{d}]", "PPdd", "hfd", MergeNone, "aarch64_sve_fcmpuo">; + +def SVACGE_N : SInst<"svacge[_n_{d}]", "PPda", "hfd", MergeNone, "aarch64_sve_facge">; +def SVACGT_N : SInst<"svacgt[_n_{d}]", "PPda", "hfd", MergeNone, "aarch64_sve_facgt">; +def SVACLE_N : SInst<"svacle[_n_{d}]", "PPda", "hfd", MergeNone, "aarch64_sve_facge", [ReverseCompare]>; +def SVACLT_N : SInst<"svaclt[_n_{d}]", "PPda", "hfd", MergeNone, "aarch64_sve_facgt", [ReverseCompare]>; +def SVCMPUO_N : SInst<"svcmpuo[_n_{d}]", "PPda", "hfd", MergeNone, "aarch64_sve_fcmpuo">; + +def SVCMPEQ_F : SInst<"svcmpeq[_{d}]", "PPdd", "hfd", MergeNone, "aarch64_sve_fcmpeq">; +def SVCMPNE_F : SInst<"svcmpne[_{d}]", "PPdd", "hfd", MergeNone, "aarch64_sve_fcmpne">; +def SVCMPGE_F : SInst<"svcmpge[_{d}]", "PPdd", "hfd", MergeNone, "aarch64_sve_fcmpge">; +def SVCMPGT_F : SInst<"svcmpgt[_{d}]", "PPdd", "hfd", MergeNone, "aarch64_sve_fcmpgt">; +def SVCMPLE_F : SInst<"svcmple[_{d}]", "PPdd", "hfd", MergeNone, "aarch64_sve_fcmpge", [ReverseCompare]>; +def SVCMPLT_F : SInst<"svcmplt[_{d}]", "PPdd", "hfd", MergeNone, "aarch64_sve_fcmpgt", [ReverseCompare]>; + +def SVCMPEQ_F_N : SInst<"svcmpeq[_n_{d}]", "PPda", "hfd", MergeNone, "aarch64_sve_fcmpeq">; +def SVCMPNE_F_N : SInst<"svcmpne[_n_{d}]", "PPda", "hfd", MergeNone, "aarch64_sve_fcmpne">; +def SVCMPGE_F_N : SInst<"svcmpge[_n_{d}]", "PPda", "hfd", MergeNone, "aarch64_sve_fcmpge">; +def SVCMPGT_F_N : SInst<"svcmpgt[_n_{d}]", "PPda", "hfd", MergeNone, "aarch64_sve_fcmpgt">; +def SVCMPLE_F_N : SInst<"svcmple[_n_{d}]", "PPda", "hfd", MergeNone, "aarch64_sve_fcmpge", [ReverseCompare]>; +def SVCMPLT_F_N : SInst<"svcmplt[_n_{d}]", "PPda", "hfd", MergeNone, "aarch64_sve_fcmpgt", [ReverseCompare]>; + +//////////////////////////////////////////////////////////////////////////////// +// Floating-point conversions + +multiclass SInstCvtMXZ< + string name, string m_types, string xz_types, string types, + string intrinsic, list<FlagType> flags = [IsOverloadNone]> { + def _M : SInst<name, m_types, types, MergeOp1, intrinsic, flags>; + def _X : SInst<name, xz_types, types, MergeAnyExp, intrinsic, flags>; + def _Z : SInst<name, xz_types, types, MergeZeroExp, intrinsic, flags>; +} + +multiclass SInstCvtMX<string name, string m_types, string xz_types, + string types, string intrinsic, + list<FlagType> flags = [IsOverloadNone]> { + def _M : SInst<name, m_types, types, MergeOp1, intrinsic, flags>; + def _X : SInst<name, xz_types, types, MergeAnyExp, intrinsic, flags>; +} + +// svcvt_s##_f16 +defm SVFCVTZS_S16_F16 : SInstCvtMXZ<"svcvt_s16[_f16]", "ddPO", "dPO", "s", "aarch64_sve_fcvtzs", [IsOverloadCvt]>; +defm SVFCVTZS_S32_F16 : SInstCvtMXZ<"svcvt_s32[_f16]", "ddPO", "dPO", "i", "aarch64_sve_fcvtzs_i32f16">; +defm SVFCVTZS_S64_F16 : SInstCvtMXZ<"svcvt_s64[_f16]", "ddPO", "dPO", "l", "aarch64_sve_fcvtzs_i64f16">; + +// svcvt_s##_f32 +defm SVFCVTZS_S32_F32 : SInstCvtMXZ<"svcvt_s32[_f32]", "ddPM", "dPM", "i", "aarch64_sve_fcvtzs", [IsOverloadCvt]>; +defm SVFCVTZS_S64_F32 : SInstCvtMXZ<"svcvt_s64[_f32]", "ddPM", "dPM", "l", "aarch64_sve_fcvtzs_i64f32">; + +let ArchGuard = "defined(__ARM_FEATURE_SVE_BF16)" in { + defm SVCVT_BF16_F32 : SInstCvtMXZ<"svcvt_bf16[_f32]", "ddPM", "dPM", "b", "aarch64_sve_fcvt_bf16f32">; + def SVCVTNT_BF16_F32 : SInst<"svcvtnt_bf16[_f32]", "ddPM", "b", MergeOp1, "aarch64_sve_fcvtnt_bf16f32", [IsOverloadNone]>; +} + +// svcvt_s##_f64 +defm SVFCVTZS_S32_F64 : SInstCvtMXZ<"svcvt_s32[_f64]", "ttPd", "tPd", "d", "aarch64_sve_fcvtzs_i32f64">; +defm SVFCVTZS_S64_F64 : SInstCvtMXZ<"svcvt_s64[_f64]", "ddPN", "dPN", "l", "aarch64_sve_fcvtzs", [IsOverloadCvt]>; + +// svcvt_u##_f16 +defm SVFCVTZU_U16_F16 : SInstCvtMXZ<"svcvt_u16[_f16]", "ddPO", "dPO", "Us", "aarch64_sve_fcvtzu", [IsOverloadCvt]>; +defm SVFCVTZU_U32_F16 : SInstCvtMXZ<"svcvt_u32[_f16]", "ddPO", "dPO", "Ui", "aarch64_sve_fcvtzu_i32f16">; +defm SVFCVTZU_U64_F16 : SInstCvtMXZ<"svcvt_u64[_f16]", "ddPO", "dPO", "Ul", "aarch64_sve_fcvtzu_i64f16">; + +// svcvt_u##_f32 +defm SVFCVTZU_U32_F32 : SInstCvtMXZ<"svcvt_u32[_f32]", "ddPM", "dPM", "Ui", "aarch64_sve_fcvtzu", [IsOverloadCvt]>; +defm SVFCVTZU_U64_F32 : SInstCvtMXZ<"svcvt_u64[_f32]", "ddPM", "dPM", "Ul", "aarch64_sve_fcvtzu_i64f32">; + +// svcvt_u##_f64 +defm SVFCVTZU_U32_F64 : SInstCvtMXZ<"svcvt_u32[_f64]", "zzPd", "zPd", "d", "aarch64_sve_fcvtzu_i32f64">; +defm SVFCVTZU_U64_F64 : SInstCvtMXZ<"svcvt_u64[_f64]", "ddPN", "dPN", "Ul", "aarch64_sve_fcvtzu", [IsOverloadCvt]>; + +// svcvt_f16_s## +defm SVFCVTZS_F16_S16 : SInstCvtMXZ<"svcvt_f16[_s16]", "OOPd", "OPd", "s", "aarch64_sve_scvtf", [IsOverloadCvt]>; +defm SVFCVTZS_F16_S32 : SInstCvtMXZ<"svcvt_f16[_s32]", "OOPd", "OPd", "i", "aarch64_sve_scvtf_f16i32">; +defm SVFCVTZS_F16_S64 : SInstCvtMXZ<"svcvt_f16[_s64]", "OOPd", "OPd", "l", "aarch64_sve_scvtf_f16i64">; + +// svcvt_f32_s## +defm SVFCVTZS_F32_S32 : SInstCvtMXZ<"svcvt_f32[_s32]", "MMPd", "MPd", "i", "aarch64_sve_scvtf", [IsOverloadCvt]>; +defm SVFCVTZS_F32_S64 : SInstCvtMXZ<"svcvt_f32[_s64]", "MMPd", "MPd", "l", "aarch64_sve_scvtf_f32i64">; + +// svcvt_f64_s## +defm SVFCVTZS_F64_S32 : SInstCvtMXZ<"svcvt_f64[_s32]", "ddPt", "dPt", "d", "aarch64_sve_scvtf_f64i32">; +defm SVFCVTZS_F64_S64 : SInstCvtMXZ<"svcvt_f64[_s64]", "NNPd", "NPd", "l", "aarch64_sve_scvtf", [IsOverloadCvt]>; + +// svcvt_f16_u## +defm SVFCVTZU_F16_U16 : SInstCvtMXZ<"svcvt_f16[_u16]", "OOPd", "OPd", "Us", "aarch64_sve_ucvtf", [IsOverloadCvt]>; +defm SVFCVTZU_F16_U32 : SInstCvtMXZ<"svcvt_f16[_u32]", "OOPd", "OPd", "Ui", "aarch64_sve_ucvtf_f16i32">; +defm SVFCVTZU_F16_U64 : SInstCvtMXZ<"svcvt_f16[_u64]", "OOPd", "OPd", "Ul", "aarch64_sve_ucvtf_f16i64">; + +// svcvt_f32_u## +defm SVFCVTZU_F32_U32 : SInstCvtMXZ<"svcvt_f32[_u32]", "MMPd", "MPd", "Ui", "aarch64_sve_ucvtf", [IsOverloadCvt]>; +defm SVFCVTZU_F32_U64 : SInstCvtMXZ<"svcvt_f32[_u64]", "MMPd", "MPd", "Ul", "aarch64_sve_ucvtf_f32i64">; + +// svcvt_f64_u## +defm SVFCVTZU_F64_U32 : SInstCvtMXZ<"svcvt_f64[_u32]", "ddPz", "dPz", "d", "aarch64_sve_ucvtf_f64i32">; +defm SVFCVTZU_F64_U64 : SInstCvtMXZ<"svcvt_f64[_u64]", "NNPd", "NPd", "Ul", "aarch64_sve_ucvtf", [IsOverloadCvt]>; + +// svcvt_f16_f## +defm SVFCVT_F16_F32 : SInstCvtMXZ<"svcvt_f16[_f32]", "OOPd", "OPd", "f", "aarch64_sve_fcvt_f16f32">; +defm SVFCVT_F16_F64 : SInstCvtMXZ<"svcvt_f16[_f64]", "OOPd", "OPd", "d", "aarch64_sve_fcvt_f16f64">; + +// svcvt_f32_f## +defm SVFCVT_F32_F16 : SInstCvtMXZ<"svcvt_f32[_f16]", "ddPO", "dPO", "f", "aarch64_sve_fcvt_f32f16">; +defm SVFCVT_F32_F64 : SInstCvtMXZ<"svcvt_f32[_f64]", "MMPd", "MPd", "d", "aarch64_sve_fcvt_f32f64">; + +// svcvt_f64_f## +defm SVFCVT_F64_F16 : SInstCvtMXZ<"svcvt_f64[_f16]", "ddPO", "dPO", "d", "aarch64_sve_fcvt_f64f16">; +defm SVFCVT_F64_F32 : SInstCvtMXZ<"svcvt_f64[_f32]", "ddPM", "dPM", "d", "aarch64_sve_fcvt_f64f32">; + +let ArchGuard = "defined(__ARM_FEATURE_SVE2)" in { +defm SVCVTLT_F32 : SInstCvtMX<"svcvtlt_f32[_f16]", "ddPh", "dPh", "f", "aarch64_sve_fcvtlt_f32f16">; +defm SVCVTLT_F64 : SInstCvtMX<"svcvtlt_f64[_f32]", "ddPh", "dPh", "d", "aarch64_sve_fcvtlt_f64f32">; + +defm SVCVTX_F32 : SInstCvtMXZ<"svcvtx_f32[_f64]", "MMPd", "MPd", "d", "aarch64_sve_fcvtx_f32f64">; + +def SVCVTNT_F32 : SInst<"svcvtnt_f16[_f32]", "hhPd", "f", MergeOp1, "aarch64_sve_fcvtnt_f16f32", [IsOverloadNone]>; +def SVCVTNT_F64 : SInst<"svcvtnt_f32[_f64]", "hhPd", "d", MergeOp1, "aarch64_sve_fcvtnt_f32f64", [IsOverloadNone]>; +// SVCVTNT_X : Implemented as macro by SveEmitter.cpp + +def SVCVTXNT_F32 : SInst<"svcvtxnt_f32[_f64]", "MMPd", "d", MergeOp1, "aarch64_sve_fcvtxnt_f32f64", [IsOverloadNone]>; +// SVCVTXNT_X_F32 : Implemented as macro by SveEmitter.cpp + +} + +//////////////////////////////////////////////////////////////////////////////// +// Permutations and selection + +multiclass SVEPerm<string name, string proto, string i> { + def : SInst<name, proto, "csilUcUsUiUlhfd", MergeNone, i>; + let ArchGuard = "defined(__ARM_FEATURE_SVE_BF16)" in { + def: SInst<name, proto, "b", MergeNone, i>; + } +} + +defm SVCLASTA : SVEPerm<"svclasta[_{d}]", "dPdd", "aarch64_sve_clasta">; +defm SVCLASTA_N : SVEPerm<"svclasta[_n_{d}]", "sPsd", "aarch64_sve_clasta_n">; +defm SVCLASTB : SVEPerm<"svclastb[_{d}]", "dPdd", "aarch64_sve_clastb">; +defm SVCLASTB_N : SVEPerm<"svclastb[_n_{d}]", "sPsd", "aarch64_sve_clastb_n">; + +def SVCOMPACT : SInst<"svcompact[_{d}]", "dPd", "ilUiUlfd", MergeNone, "aarch64_sve_compact">; +// Note: svdup_lane is implemented using the intrinsic for TBL to represent a +// splat of any possible lane. It is upto LLVM to pick a more efficient +// instruction such as DUP (indexed) if the lane index fits the range of the +// instruction's immediate. +def SVDUP_LANE : SInst<"svdup_lane[_{d}]", "ddL", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_tbl">; +let ArchGuard = "defined(__ARM_FEATURE_SVE_BF16)" in { +def SVDUP_LANE_BF16 : + SInst<"svdup_lane[_{d}]", "ddL", "b", MergeNone, "aarch64_sve_tbl">; +} + +def SVDUPQ_LANE : SInst<"svdupq_lane[_{d}]", "ddn", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_dupq_lane">; +let ArchGuard = "defined(__ARM_FEATURE_SVE_BF16)" in { + def SVDUPQ_LANE_BF16 : SInst<"svdupq_lane[_{d}]", "ddn", "b", MergeNone, "aarch64_sve_dupq_lane">; +} +def SVEXT : SInst<"svext[_{d}]", "dddi", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_ext", [], [ImmCheck<2, ImmCheckExtract, 1>]>; +defm SVLASTA : SVEPerm<"svlasta[_{d}]", "sPd", "aarch64_sve_lasta">; +defm SVLASTB : SVEPerm<"svlastb[_{d}]", "sPd", "aarch64_sve_lastb">; +def SVREV : SInst<"svrev[_{d}]", "dd", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_rev">; +def SVSEL : SInst<"svsel[_{d}]", "dPdd", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_sel">; +def SVSPLICE : SInst<"svsplice[_{d}]", "dPdd", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_splice">; +def SVTBL : SInst<"svtbl[_{d}]", "ddu", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_tbl">; + +let ArchGuard = "defined(__ARM_FEATURE_SVE_BF16)" in { + def SVTBL_BF16 : SInst<"svtbl[_{d}]", "ddu", "b", MergeNone, "aarch64_sve_tbl">; +} + +def SVTRN1 : SInst<"svtrn1[_{d}]", "ddd", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_trn1">; +def SVTRN2 : SInst<"svtrn2[_{d}]", "ddd", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_trn2">; +def SVUNPKHI_S : SInst<"svunpkhi[_{d}]", "dh", "sil", MergeNone, "aarch64_sve_sunpkhi">; +def SVUNPKHI_U : SInst<"svunpkhi[_{d}]", "dh", "UsUiUl", MergeNone, "aarch64_sve_uunpkhi">; +def SVUNPKLO_S : SInst<"svunpklo[_{d}]", "dh", "sil", MergeNone, "aarch64_sve_sunpklo">; +def SVUNPKLO_U : SInst<"svunpklo[_{d}]", "dh", "UsUiUl", MergeNone, "aarch64_sve_uunpklo">; +def SVUZP1 : SInst<"svuzp1[_{d}]", "ddd", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_uzp1">; +def SVUZP2 : SInst<"svuzp2[_{d}]", "ddd", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_uzp2">; +def SVZIP1 : SInst<"svzip1[_{d}]", "ddd", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_zip1">; +def SVZIP2 : SInst<"svzip2[_{d}]", "ddd", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_zip2">; + +let ArchGuard = "defined(__ARM_FEATURE_SVE_BF16)" in { +def SVEXT_BF16 : SInst<"svext[_{d}]", "dddi", "b", MergeNone, "aarch64_sve_ext", [], [ImmCheck<2, ImmCheckExtract, 1>]>; +def SVREV_BF16 : SInst<"svrev[_{d}]", "dd", "b", MergeNone, "aarch64_sve_rev">; +def SVSEL_BF16 : SInst<"svsel[_{d}]", "dPdd", "b", MergeNone, "aarch64_sve_sel">; +def SVSPLICE_BF16 : SInst<"svsplice[_{d}]", "dPdd", "b", MergeNone, "aarch64_sve_splice">; +def SVTRN1_BF16 : SInst<"svtrn1[_{d}]", "ddd", "b", MergeNone, "aarch64_sve_trn1">; +def SVTRN2_BF16 : SInst<"svtrn2[_{d}]", "ddd", "b", MergeNone, "aarch64_sve_trn2">; +def SVUZP1_BF16 : SInst<"svuzp1[_{d}]", "ddd", "b", MergeNone, "aarch64_sve_uzp1">; +def SVUZP2_BF16 : SInst<"svuzp2[_{d}]", "ddd", "b", MergeNone, "aarch64_sve_uzp2">; +def SVZIP1_BF16 : SInst<"svzip1[_{d}]", "ddd", "b", MergeNone, "aarch64_sve_zip1">; +def SVZIP2_BF16 : SInst<"svzip2[_{d}]", "ddd", "b", MergeNone, "aarch64_sve_zip2">; +} + +def SVREV_B : SInst<"svrev_{d}", "PP", "PcPsPiPl", MergeNone, "aarch64_sve_rev">; +def SVSEL_B : SInst<"svsel[_b]", "PPPP", "Pc", MergeNone, "aarch64_sve_sel">; +def SVTRN1_B : SInst<"svtrn1_{d}", "PPP", "PcPsPiPl", MergeNone, "aarch64_sve_trn1">; +def SVTRN2_B : SInst<"svtrn2_{d}", "PPP", "PcPsPiPl", MergeNone, "aarch64_sve_trn2">; +def SVPUNPKHI : SInst<"svunpkhi[_b]", "PP", "Pc", MergeNone, "aarch64_sve_punpkhi">; +def SVPUNPKLO : SInst<"svunpklo[_b]", "PP", "Pc", MergeNone, "aarch64_sve_punpklo">; +def SVUZP1_B : SInst<"svuzp1_{d}", "PPP", "PcPsPiPl", MergeNone, "aarch64_sve_uzp1">; +def SVUZP2_B : SInst<"svuzp2_{d}", "PPP", "PcPsPiPl", MergeNone, "aarch64_sve_uzp2">; +def SVZIP1_B : SInst<"svzip1_{d}", "PPP", "PcPsPiPl", MergeNone, "aarch64_sve_zip1">; +def SVZIP2_B : SInst<"svzip2_{d}", "PPP", "PcPsPiPl", MergeNone, "aarch64_sve_zip2">; + +//////////////////////////////////////////////////////////////////////////////// +// Predicate creation + +def SVPFALSE : SInst<"svpfalse[_b]", "P", "", MergeNone, "", [IsOverloadNone]>; + +def SVPTRUE_PAT : SInst<"svptrue_pat_{d}", "PI", "PcPsPiPl", MergeNone, "aarch64_sve_ptrue">; +def SVPTRUE : SInst<"svptrue_{d}", "P", "PcPsPiPl", MergeNone, "aarch64_sve_ptrue", [IsAppendSVALL]>; + +def SVDUPQ_B8 : SInst<"svdupq[_n]_{d}", "Pssssssssssssssss", "Pc", MergeNone>; +def SVDUPQ_B16 : SInst<"svdupq[_n]_{d}", "Pssssssss", "Ps", MergeNone>; +def SVDUPQ_B32 : SInst<"svdupq[_n]_{d}", "Pssss", "Pi", MergeNone>; +def SVDUPQ_B64 : SInst<"svdupq[_n]_{d}", "Pss", "Pl", MergeNone>; +def SVDUP_N_B : SInst<"svdup[_n]_{d}", "Ps", "PcPsPiPl", MergeNone>; + + +//////////////////////////////////////////////////////////////////////////////// +// Predicate operations + +def SVAND_B_Z : SInst<"svand[_b]_z", "PPPP", "Pc", MergeNone, "aarch64_sve_and_z">; +def SVBIC_B_Z : SInst<"svbic[_b]_z", "PPPP", "Pc", MergeNone, "aarch64_sve_bic_z">; +def SVEOR_B_Z : SInst<"sveor[_b]_z", "PPPP", "Pc", MergeNone, "aarch64_sve_eor_z">; +def SVMOV_B_Z : SInst<"svmov[_b]_z", "PPP", "Pc", MergeNone>; // Uses custom expansion +def SVNAND_B_Z : SInst<"svnand[_b]_z", "PPPP", "Pc", MergeNone, "aarch64_sve_nand_z">; +def SVNOR_B_Z : SInst<"svnor[_b]_z", "PPPP", "Pc", MergeNone, "aarch64_sve_nor_z">; +def SVNOT_B_Z : SInst<"svnot[_b]_z", "PPP", "Pc", MergeNone>; // Uses custom expansion +def SVORN_B_Z : SInst<"svorn[_b]_z", "PPPP", "Pc", MergeNone, "aarch64_sve_orn_z">; +def SVORR_B_Z : SInst<"svorr[_b]_z", "PPPP", "Pc", MergeNone, "aarch64_sve_orr_z">; + +def SVBRKA : SInst<"svbrka[_b]_m", "PPPP", "Pc", MergeNone, "aarch64_sve_brka">; +def SVBRKA_Z : SInst<"svbrka[_b]_z", "PPP", "Pc", MergeNone, "aarch64_sve_brka_z">; +def SVBRKB : SInst<"svbrkb[_b]_m", "PPPP", "Pc", MergeNone, "aarch64_sve_brkb">; +def SVBRKB_Z : SInst<"svbrkb[_b]_z", "PPP", "Pc", MergeNone, "aarch64_sve_brkb_z">; +def SVBRKN_Z : SInst<"svbrkn[_b]_z", "PPPP", "Pc", MergeNone, "aarch64_sve_brkn_z">; +def SVBRKPA_Z : SInst<"svbrkpa[_b]_z", "PPPP", "Pc", MergeNone, "aarch64_sve_brkpa_z">; +def SVBRKPB_Z : SInst<"svbrkpb[_b]_z", "PPPP", "Pc", MergeNone, "aarch64_sve_brkpb_z">; + +def SVPFIRST : SInst<"svpfirst[_b]", "PPP", "Pc", MergeNone, "aarch64_sve_pfirst">; +def SVPNEXT : SInst<"svpnext_{d}", "PPP", "PcPsPiPl", MergeNone, "aarch64_sve_pnext">; + +//////////////////////////////////////////////////////////////////////////////// +// Testing predicates + +def SVPTEST_ANY : SInst<"svptest_any", "sPP", "Pc", MergeNone, "aarch64_sve_ptest_any">; +def SVPTEST_FIRST : SInst<"svptest_first", "sPP", "Pc", MergeNone, "aarch64_sve_ptest_first">; +def SVPTEST_LAST : SInst<"svptest_last", "sPP", "Pc", MergeNone, "aarch64_sve_ptest_last">; + +//////////////////////////////////////////////////////////////////////////////// +// FFR manipulation + +def SVRDFFR : SInst<"svrdffr", "P", "Pc", MergeNone, "", [IsOverloadNone]>; +def SVRDFFR_Z : SInst<"svrdffr_z", "PP", "Pc", MergeNone, "", [IsOverloadNone]>; +def SVSETFFR : SInst<"svsetffr", "v", "", MergeNone, "", [IsOverloadNone]>; +def SVWRFFR : SInst<"svwrffr", "vP", "Pc", MergeNone, "", [IsOverloadNone]>; + +//////////////////////////////////////////////////////////////////////////////// +// Counting elements + +def SVCNTB_PAT : SInst<"svcntb_pat", "nI", "", MergeNone, "aarch64_sve_cntb", [IsOverloadNone]>; +def SVCNTH_PAT : SInst<"svcnth_pat", "nI", "", MergeNone, "aarch64_sve_cnth", [IsOverloadNone]>; +def SVCNTW_PAT : SInst<"svcntw_pat", "nI", "", MergeNone, "aarch64_sve_cntw", [IsOverloadNone]>; +def SVCNTD_PAT : SInst<"svcntd_pat", "nI", "", MergeNone, "aarch64_sve_cntd", [IsOverloadNone]>; + +def SVCNTB : SInst<"svcntb", "n", "", MergeNone, "aarch64_sve_cntb", [IsAppendSVALL, IsOverloadNone]>; +def SVCNTH : SInst<"svcnth", "n", "", MergeNone, "aarch64_sve_cnth", [IsAppendSVALL, IsOverloadNone]>; +def SVCNTW : SInst<"svcntw", "n", "", MergeNone, "aarch64_sve_cntw", [IsAppendSVALL, IsOverloadNone]>; +def SVCNTD : SInst<"svcntd", "n", "", MergeNone, "aarch64_sve_cntd", [IsAppendSVALL, IsOverloadNone]>; + +def SVCNTP : SInst<"svcntp_{d}", "nPP", "PcPsPiPl", MergeNone, "aarch64_sve_cntp">; +def SVLEN : SInst<"svlen[_{d}]", "nd", "csilUcUsUiUlhfd", MergeNone>; + +let ArchGuard = "defined(__ARM_FEATURE_SVE_BF16)" in { +def SVLEN_BF16 : SInst<"svlen[_{d}]", "nd", "b", MergeNone>; +} + +//////////////////////////////////////////////////////////////////////////////// +// Saturating scalar arithmetic + +class sat_type<string u, string t> { string U = u; string T = t; } +def SignedByte : sat_type<"", "c">; +def SignedHalf : sat_type<"", "s">; +def SignedWord : sat_type<"", "i">; +def SignedDoubleWord : sat_type<"", "l">; +def UnsignedByte : sat_type<"U", "Uc">; +def UnsignedHalf : sat_type<"U", "Us">; +def UnsignedWord : sat_type<"U", "Ui">; +def UnsignedDoubleWord : sat_type<"U", "Ul">; + +multiclass SInst_SAT1<string name, string intrinsic, sat_type type> { + def _N32 : SInst<name # "_pat[_n_{d}]", "ssIi", type.U # "i", MergeNone, intrinsic # "_n32", [IsOverloadNone], [ImmCheck<2, ImmCheck1_16>]>; + def _N64 : SInst<name # "_pat[_n_{d}]", "ssIi", type.U # "l", MergeNone, intrinsic # "_n64", [IsOverloadNone], [ImmCheck<2, ImmCheck1_16>]>; + def _N32_ALL : SInst<name # "[_n_{d}]", "ssi", type.U # "i", MergeNone, intrinsic # "_n32", [IsOverloadNone, IsInsertOp1SVALL], [ImmCheck<1, ImmCheck1_16>]>; + def _N64_ALL : SInst<name # "[_n_{d}]", "ssi", type.U # "l", MergeNone, intrinsic # "_n64", [IsOverloadNone, IsInsertOp1SVALL], [ImmCheck<1, ImmCheck1_16>]>; +} + +multiclass SInst_SAT2<string name, string intrinsic, sat_type type> { + def "" : SInst<name # "_pat[_{d}]", "ddIi", type.T, MergeNone, intrinsic, [], [ImmCheck<2, ImmCheck1_16>]>; + def _ALL : SInst<name # "[_{d}]", "ddi", type.T, MergeNone, intrinsic, [IsInsertOp1SVALL], [ImmCheck<1, ImmCheck1_16>]>; + + def _N32 : SInst<name # "_pat[_n_{d}]", "ssIi", type.U # "i", MergeNone, intrinsic # "_n32", [IsOverloadNone], [ImmCheck<2, ImmCheck1_16>]>; + def _N64 : SInst<name # "_pat[_n_{d}]", "ssIi", type.U # "l", MergeNone, intrinsic # "_n64", [IsOverloadNone], [ImmCheck<2, ImmCheck1_16>]>; + def _N32_ALL : SInst<name # "[_n_{d}]", "ssi", type.U # "i", MergeNone, intrinsic # "_n32", [IsOverloadNone, IsInsertOp1SVALL], [ImmCheck<1, ImmCheck1_16>]>; + def _N64_ALL : SInst<name # "[_n_{d}]", "ssi", type.U # "l", MergeNone, intrinsic # "_n64", [IsOverloadNone, IsInsertOp1SVALL], [ImmCheck<1, ImmCheck1_16>]>; +} + +defm SVQDECB_S : SInst_SAT1<"svqdecb", "aarch64_sve_sqdecb", SignedByte>; +defm SVQDECB_U : SInst_SAT1<"svqdecb", "aarch64_sve_uqdecb", UnsignedByte>; +defm SVQDECH_S : SInst_SAT2<"svqdech", "aarch64_sve_sqdech", SignedHalf>; +defm SVQDECH_U : SInst_SAT2<"svqdech", "aarch64_sve_uqdech", UnsignedHalf>; +defm SVQDECW_S : SInst_SAT2<"svqdecw", "aarch64_sve_sqdecw", SignedWord>; +defm SVQDECW_U : SInst_SAT2<"svqdecw", "aarch64_sve_uqdecw", UnsignedWord>; +defm SVQDECD_S : SInst_SAT2<"svqdecd", "aarch64_sve_sqdecd", SignedDoubleWord>; +defm SVQDECD_U : SInst_SAT2<"svqdecd", "aarch64_sve_uqdecd", UnsignedDoubleWord>; + +defm SVQINCB_S : SInst_SAT1<"svqincb", "aarch64_sve_sqincb", SignedByte>; +defm SVQINCB_U : SInst_SAT1<"svqincb", "aarch64_sve_uqincb", UnsignedByte>; +defm SVQINCH_S : SInst_SAT2<"svqinch", "aarch64_sve_sqinch", SignedHalf>; +defm SVQINCH_U : SInst_SAT2<"svqinch", "aarch64_sve_uqinch", UnsignedHalf>; +defm SVQINCW_S : SInst_SAT2<"svqincw", "aarch64_sve_sqincw", SignedWord>; +defm SVQINCW_U : SInst_SAT2<"svqincw", "aarch64_sve_uqincw", UnsignedWord>; +defm SVQINCD_S : SInst_SAT2<"svqincd", "aarch64_sve_sqincd", SignedDoubleWord>; +defm SVQINCD_U : SInst_SAT2<"svqincd", "aarch64_sve_uqincd", UnsignedDoubleWord>; + +def SVQDECP_S : SInst<"svqdecp[_{d}]", "ddP", "sil", MergeNone, "aarch64_sve_sqdecp">; +def SVQDECP_U : SInst<"svqdecp[_{d}]", "ddP", "UsUiUl", MergeNone, "aarch64_sve_uqdecp">; +def SVQINCP_S : SInst<"svqincp[_{d}]", "ddP", "sil", MergeNone, "aarch64_sve_sqincp">; +def SVQINCP_U : SInst<"svqincp[_{d}]", "ddP", "UsUiUl", MergeNone, "aarch64_sve_uqincp">; + +def SVQDECP_N_S32 : SInst<"svqdecp[_n_s32]_{d}", "kkP", "PcPsPiPl", MergeNone, "aarch64_sve_sqdecp_n32">; +def SVQDECP_N_S64 : SInst<"svqdecp[_n_s64]_{d}", "llP", "PcPsPiPl", MergeNone, "aarch64_sve_sqdecp_n64">; +def SVQDECP_N_U32 : SInst<"svqdecp[_n_u32]_{d}", "mmP", "PcPsPiPl", MergeNone, "aarch64_sve_uqdecp_n32">; +def SVQDECP_N_U64 : SInst<"svqdecp[_n_u64]_{d}", "nnP", "PcPsPiPl", MergeNone, "aarch64_sve_uqdecp_n64">; +def SVQINCP_N_S32 : SInst<"svqincp[_n_s32]_{d}", "kkP", "PcPsPiPl", MergeNone, "aarch64_sve_sqincp_n32">; +def SVQINCP_N_S64 : SInst<"svqincp[_n_s64]_{d}", "llP", "PcPsPiPl", MergeNone, "aarch64_sve_sqincp_n64">; +def SVQINCP_N_U32 : SInst<"svqincp[_n_u32]_{d}", "mmP", "PcPsPiPl", MergeNone, "aarch64_sve_uqincp_n32">; +def SVQINCP_N_U64 : SInst<"svqincp[_n_u64]_{d}", "nnP", "PcPsPiPl", MergeNone, "aarch64_sve_uqincp_n64">; + +let ArchGuard = "defined(__ARM_FEATURE_SVE_MATMUL_INT8)" in { +def SVMLLA_S32 : SInst<"svmmla[_s32]", "ddqq","i", MergeNone, "aarch64_sve_smmla">; +def SVMLLA_U32 : SInst<"svmmla[_u32]", "ddqq","Ui", MergeNone, "aarch64_sve_ummla">; +def SVUSMLLA_S32 : SInst<"svusmmla[_s32]", "ddbq","i", MergeNone, "aarch64_sve_usmmla">; + +def SVUSDOT_S : SInst<"svusdot[_s32]", "ddbq", "i", MergeNone, "aarch64_sve_usdot">; +def SVUSDOT_N_S : SInst<"svusdot[_n_s32]", "ddbr", "i", MergeNone, "aarch64_sve_usdot">; +def SVSUDOT_S : SInst<"svsudot[_s32]", "ddqb", "i", MergeNone, "aarch64_sve_usdot", [ReverseUSDOT]>; +def SVSUDOT_N_S : SInst<"svsudot[_n_s32]", "ddq@", "i", MergeNone, "aarch64_sve_usdot", [ReverseUSDOT]>; + +def SVUSDOT_LANE_S : SInst<"svusdot_lane[_s32]", "ddbqi", "i", MergeNone, "aarch64_sve_usdot_lane", [], [ImmCheck<3, ImmCheckLaneIndexDot, 2>]>; +def SVSUDOT_LANE_S : SInst<"svsudot_lane[_s32]", "ddqbi", "i", MergeNone, "aarch64_sve_sudot_lane", [], [ImmCheck<3, ImmCheckLaneIndexDot, 2>]>; +} + +let ArchGuard = "defined(__ARM_FEATURE_SVE_MATMUL_FP32)" in { +def SVMLLA_F32 : SInst<"svmmla[_f32]", "dddd","f", MergeNone, "aarch64_sve_fmmla">; +} + +let ArchGuard = "defined(__ARM_FEATURE_SVE_MATMUL_FP64)" in { +def SVMLLA_F64 : SInst<"svmmla[_f64]", "dddd","d", MergeNone, "aarch64_sve_fmmla">; +def SVTRN1Q : SInst<"svtrn1q[_{d}]", "ddd", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_trn1q">; +def SVTRN2Q : SInst<"svtrn2q[_{d}]", "ddd", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_trn2q">; +def SVUZP1Q : SInst<"svuzp1q[_{d}]", "ddd", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_uzp1q">; +def SVUZP2Q : SInst<"svuzp2q[_{d}]", "ddd", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_uzp2q">; +def SVZIP1Q : SInst<"svzip1q[_{d}]", "ddd", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_zip1q">; +def SVZIP2Q : SInst<"svzip2q[_{d}]", "ddd", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_zip2q">; +} + +let ArchGuard = "defined(__ARM_FEATURE_SVE_MATMUL_FP64) && defined(__ARM_FEATURE_SVE_BF16)" in { +def SVTRN1Q_BF16 : SInst<"svtrn1q[_{d}]", "ddd", "b", MergeNone, "aarch64_sve_trn1q">; +def SVTRN2Q_BF16 : SInst<"svtrn2q[_{d}]", "ddd", "b", MergeNone, "aarch64_sve_trn2q">; +def SVUZP1Q_BF16 : SInst<"svuzp1q[_{d}]", "ddd", "b", MergeNone, "aarch64_sve_uzp1q">; +def SVUZP2Q_BF16 : SInst<"svuzp2q[_{d}]", "ddd", "b", MergeNone, "aarch64_sve_uzp2q">; +def SVZIP1Q_BF16 : SInst<"svzip1q[_{d}]", "ddd", "b", MergeNone, "aarch64_sve_zip1q">; +def SVZIP2Q_BF16 : SInst<"svzip2q[_{d}]", "ddd", "b", MergeNone, "aarch64_sve_zip2q">; +} + +//////////////////////////////////////////////////////////////////////////////// +// Vector creation +def SVUNDEF_1 : SInst<"svundef_{d}", "d", "csilUcUsUiUlhfd", MergeNone, "", [IsUndef]>; +def SVUNDEF_2 : SInst<"svundef2_{d}", "2", "csilUcUsUiUlhfd", MergeNone, "", [IsUndef]>; +def SVUNDEF_3 : SInst<"svundef3_{d}", "3", "csilUcUsUiUlhfd", MergeNone, "", [IsUndef]>; +def SVUNDEF_4 : SInst<"svundef4_{d}", "4", "csilUcUsUiUlhfd", MergeNone, "", [IsUndef]>; + +def SVCREATE_2 : SInst<"svcreate2[_{d}]", "2dd", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_tuple_create2", [IsTupleCreate]>; +def SVCREATE_3 : SInst<"svcreate3[_{d}]", "3ddd", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_tuple_create3", [IsTupleCreate]>; +def SVCREATE_4 : SInst<"svcreate4[_{d}]", "4dddd", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_tuple_create4", [IsTupleCreate]>; + +let ArchGuard = "defined(__ARM_FEATURE_SVE_BF16)" in { +def SVUNDEF_1_BF16 : SInst<"svundef_{d}", "d", "b", MergeNone, "", [IsUndef]>; +def SVUNDEF_2_BF16 : SInst<"svundef2_{d}", "2", "b", MergeNone, "", [IsUndef]>; +def SVUNDEF_3_BF16 : SInst<"svundef3_{d}", "3", "b", MergeNone, "", [IsUndef]>; +def SVUNDEF_4_BF16 : SInst<"svundef4_{d}", "4", "b", MergeNone, "", [IsUndef]>; + +def SVCREATE_2_BF16 : SInst<"svcreate2[_{d}]", "2dd", "b", MergeNone, "aarch64_sve_tuple_create2", [IsTupleCreate]>; +def SVCREATE_3_BF16 : SInst<"svcreate3[_{d}]", "3ddd", "b", MergeNone, "aarch64_sve_tuple_create3", [IsTupleCreate]>; +def SVCREATE_4_BF16 : SInst<"svcreate4[_{d}]", "4dddd", "b", MergeNone, "aarch64_sve_tuple_create4", [IsTupleCreate]>; +} + +//////////////////////////////////////////////////////////////////////////////// +// Vector insertion and extraction +def SVGET_2 : SInst<"svget2[_{d}]", "d2i", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_tuple_get", [IsTupleGet], [ImmCheck<1, ImmCheck0_1>]>; +def SVGET_3 : SInst<"svget3[_{d}]", "d3i", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_tuple_get", [IsTupleGet], [ImmCheck<1, ImmCheck0_2>]>; +def SVGET_4 : SInst<"svget4[_{d}]", "d4i", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_tuple_get", [IsTupleGet], [ImmCheck<1, ImmCheck0_3>]>; + +def SVSET_2 : SInst<"svset2[_{d}]", "22id", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_tuple_set", [IsTupleSet], [ImmCheck<1, ImmCheck0_1>]>; +def SVSET_3 : SInst<"svset3[_{d}]", "33id", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_tuple_set", [IsTupleSet], [ImmCheck<1, ImmCheck0_2>]>; +def SVSET_4 : SInst<"svset4[_{d}]", "44id", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_tuple_set", [IsTupleSet], [ImmCheck<1, ImmCheck0_3>]>; + +let ArchGuard = "defined(__ARM_FEATURE_SVE_BF16)" in { +def SVGET_2_BF16 : SInst<"svget2[_{d}]", "d2i", "b", MergeNone, "aarch64_sve_tuple_get", [IsTupleGet], [ImmCheck<1, ImmCheck0_1>]>; +def SVGET_3_BF16 : SInst<"svget3[_{d}]", "d3i", "b", MergeNone, "aarch64_sve_tuple_get", [IsTupleGet], [ImmCheck<1, ImmCheck0_2>]>; +def SVGET_4_BF16 : SInst<"svget4[_{d}]", "d4i", "b", MergeNone, "aarch64_sve_tuple_get", [IsTupleGet], [ImmCheck<1, ImmCheck0_3>]>; + +def SVSET_2_BF16 : SInst<"svset2[_{d}]", "22id", "b", MergeNone, "aarch64_sve_tuple_set", [IsTupleSet], [ImmCheck<1, ImmCheck0_1>]>; +def SVSET_3_BF16 : SInst<"svset3[_{d}]", "33id", "b", MergeNone, "aarch64_sve_tuple_set", [IsTupleSet], [ImmCheck<1, ImmCheck0_2>]>; +def SVSET_4_BF16 : SInst<"svset4[_{d}]", "44id", "b", MergeNone, "aarch64_sve_tuple_set", [IsTupleSet], [ImmCheck<1, ImmCheck0_3>]>; +} + +//////////////////////////////////////////////////////////////////////////////// +// SVE2 WhileGE/GT +let ArchGuard = "defined(__ARM_FEATURE_SVE2)" in { +def SVWHILEGE_S32 : SInst<"svwhilege_{d}[_{1}]", "Pkk", "PcPsPiPl", MergeNone, "aarch64_sve_whilege", [IsOverloadWhile]>; +def SVWHILEGE_S64 : SInst<"svwhilege_{d}[_{1}]", "Pll", "PcPsPiPl", MergeNone, "aarch64_sve_whilege", [IsOverloadWhile]>; +def SVWHILEGT_S32 : SInst<"svwhilegt_{d}[_{1}]", "Pkk", "PcPsPiPl", MergeNone, "aarch64_sve_whilegt", [IsOverloadWhile]>; +def SVWHILEGT_S64 : SInst<"svwhilegt_{d}[_{1}]", "Pll", "PcPsPiPl", MergeNone, "aarch64_sve_whilegt", [IsOverloadWhile]>; +def SVWHILEHI_U32 : SInst<"svwhilegt_{d}[_{1}]", "Pmm", "PUcPUsPUiPUl", MergeNone, "aarch64_sve_whilehi", [IsOverloadWhile]>; +def SVWHILEHI_U64 : SInst<"svwhilegt_{d}[_{1}]", "Pnn", "PUcPUsPUiPUl", MergeNone, "aarch64_sve_whilehi", [IsOverloadWhile]>; +def SVWHILEHS_U32 : SInst<"svwhilege_{d}[_{1}]", "Pmm", "PUcPUsPUiPUl", MergeNone, "aarch64_sve_whilehs", [IsOverloadWhile]>; +def SVWHILEHS_U64 : SInst<"svwhilege_{d}[_{1}]", "Pnn", "PUcPUsPUiPUl", MergeNone, "aarch64_sve_whilehs", [IsOverloadWhile]>; +} + +//////////////////////////////////////////////////////////////////////////////// +// SVE2 - Uniform DSP operations + +let ArchGuard = "defined(__ARM_FEATURE_SVE2)" in { +defm SVQADD_S : SInstZPZZ<"svqadd", "csli", "aarch64_sve_sqadd">; +defm SVQADD_U : SInstZPZZ<"svqadd", "UcUsUiUl", "aarch64_sve_uqadd">; +defm SVHADD_S : SInstZPZZ<"svhadd", "csli", "aarch64_sve_shadd">; +defm SVHADD_U : SInstZPZZ<"svhadd", "UcUsUiUl", "aarch64_sve_uhadd">; +defm SVRHADD_S : SInstZPZZ<"svrhadd", "csli", "aarch64_sve_srhadd">; +defm SVRHADD_U : SInstZPZZ<"svrhadd", "UcUsUiUl", "aarch64_sve_urhadd">; + +defm SVQSUB_S : SInstZPZZ<"svqsub", "csli", "aarch64_sve_sqsub">; +defm SVQSUB_U : SInstZPZZ<"svqsub", "UcUsUiUl", "aarch64_sve_uqsub">; +defm SVQSUBR_S : SInstZPZZ<"svqsubr", "csli", "aarch64_sve_sqsubr">; +defm SVQSUBR_U : SInstZPZZ<"svqsubr", "UcUsUiUl", "aarch64_sve_uqsubr">; +defm SVHSUB_S : SInstZPZZ<"svhsub", "csli", "aarch64_sve_shsub">; +defm SVHSUB_U : SInstZPZZ<"svhsub", "UcUsUiUl", "aarch64_sve_uhsub">; +defm SVHSUBR_S : SInstZPZZ<"svhsubr", "csli", "aarch64_sve_shsubr">; +defm SVHSUBR_U : SInstZPZZ<"svhsubr", "UcUsUiUl", "aarch64_sve_uhsubr">; + +defm SVQABS : SInstZPZ<"svqabs", "csil", "aarch64_sve_sqabs">; +defm SVQNEG : SInstZPZ<"svqneg", "csil", "aarch64_sve_sqneg">; +defm SVRECPE : SInstZPZ<"svrecpe", "Ui", "aarch64_sve_urecpe">; +defm SVRSQRTE : SInstZPZ<"svrsqrte", "Ui", "aarch64_sve_ursqrte">; +} + +//------------------------------------------------------------------------------ + +multiclass SInstZPZxZ<string name, string types, string pat_v, string pat_n, string intrinsic, list<FlagType> flags=[]> { + def _M : SInst<name # "[_{d}]", pat_v, types, MergeOp1, intrinsic, flags>; + def _X : SInst<name # "[_{d}]", pat_v, types, MergeAny, intrinsic, flags>; + def _Z : SInst<name # "[_{d}]", pat_v, types, MergeZero, intrinsic, flags>; + + def _N_M : SInst<name # "[_n_{d}]", pat_n, types, MergeOp1, intrinsic, flags>; + def _N_X : SInst<name # "[_n_{d}]", pat_n, types, MergeAny, intrinsic, flags>; + def _N_Z : SInst<name # "[_n_{d}]", pat_n, types, MergeZero, intrinsic, flags>; +} + +let ArchGuard = "defined(__ARM_FEATURE_SVE2)" in { +defm SVQRSHL_S : SInstZPZxZ<"svqrshl", "csil", "dPdx", "dPdK", "aarch64_sve_sqrshl">; +defm SVQRSHL_U : SInstZPZxZ<"svqrshl", "UcUsUiUl", "dPdx", "dPdK", "aarch64_sve_uqrshl">; +defm SVQSHL_S : SInstZPZxZ<"svqshl", "csil", "dPdx", "dPdK", "aarch64_sve_sqshl">; +defm SVQSHL_U : SInstZPZxZ<"svqshl", "UcUsUiUl", "dPdx", "dPdK", "aarch64_sve_uqshl">; +defm SVRSHL_S : SInstZPZxZ<"svrshl", "csil", "dPdx", "dPdK", "aarch64_sve_srshl">; +defm SVRSHL_U : SInstZPZxZ<"svrshl", "UcUsUiUl", "dPdx", "dPdK", "aarch64_sve_urshl">; +defm SVSQADD : SInstZPZxZ<"svsqadd", "UcUsUiUl", "dPdx", "dPdK", "aarch64_sve_usqadd">; +defm SVUQADD : SInstZPZxZ<"svuqadd", "csil", "dPdu", "dPdL", "aarch64_sve_suqadd">; + +def SVABA_S : SInst<"svaba[_{d}]", "dddd", "csil" , MergeNone, "aarch64_sve_saba">; +def SVABA_U : SInst<"svaba[_{d}]", "dddd", "UcUsUiUl", MergeNone, "aarch64_sve_uaba">; +def SVQDMULH : SInst<"svqdmulh[_{d}]", "ddd", "csil", MergeNone, "aarch64_sve_sqdmulh">; +def SVQRDMULH : SInst<"svqrdmulh[_{d}]", "ddd", "csil", MergeNone, "aarch64_sve_sqrdmulh">; +def SVQRDMLAH : SInst<"svqrdmlah[_{d}]", "dddd", "csil", MergeNone, "aarch64_sve_sqrdmlah">; +def SVQRDMLSH : SInst<"svqrdmlsh[_{d}]", "dddd", "csil", MergeNone, "aarch64_sve_sqrdmlsh">; + +def SVABA_S_N : SInst<"svaba[_n_{d}]", "ddda", "csil", MergeNone, "aarch64_sve_saba">; +def SVABA_U_N : SInst<"svaba[_n_{d}]", "ddda", "UcUsUiUl", MergeNone, "aarch64_sve_uaba">; +def SVQDMULH_N : SInst<"svqdmulh[_n_{d}]", "dda", "csil", MergeNone, "aarch64_sve_sqdmulh">; +def SVQRDMULH_N : SInst<"svqrdmulh[_n_{d}]", "dda", "csil", MergeNone, "aarch64_sve_sqrdmulh">; +def SVQRDMLAH_N : SInst<"svqrdmlah[_n_{d}]", "ddda", "csil", MergeNone, "aarch64_sve_sqrdmlah">; +def SVQRDMLSH_N : SInst<"svqrdmlsh[_n_{d}]", "ddda", "csil", MergeNone, "aarch64_sve_sqrdmlsh">; + +def SVQDMULH_LANE : SInst<"svqdmulh_lane[_{d}]", "dddi", "sil", MergeNone, "aarch64_sve_sqdmulh_lane", [], [ImmCheck<2, ImmCheckLaneIndex, 1>]>; +def SVQRDMULH_LANE : SInst<"svqrdmulh_lane[_{d}]", "dddi", "sil", MergeNone, "aarch64_sve_sqrdmulh_lane", [], [ImmCheck<2, ImmCheckLaneIndex, 1>]>; +def SVQRDMLAH_LANE : SInst<"svqrdmlah_lane[_{d}]", "ddddi", "sil", MergeNone, "aarch64_sve_sqrdmlah_lane", [], [ImmCheck<3, ImmCheckLaneIndex, 2>]>; +def SVQRDMLSH_LANE : SInst<"svqrdmlsh_lane[_{d}]", "ddddi", "sil", MergeNone, "aarch64_sve_sqrdmlsh_lane", [], [ImmCheck<3, ImmCheckLaneIndex, 2>]>; + +def SVQSHLU_M : SInst<"svqshlu[_n_{d}]", "uPdi", "csil", MergeOp1, "aarch64_sve_sqshlu", [], [ImmCheck<2, ImmCheckShiftLeft, 1>]>; +def SVQSHLU_X : SInst<"svqshlu[_n_{d}]", "uPdi", "csil", MergeAny, "aarch64_sve_sqshlu", [], [ImmCheck<2, ImmCheckShiftLeft, 1>]>; +def SVQSHLU_Z : SInst<"svqshlu[_n_{d}]", "uPdi", "csil", MergeZero, "aarch64_sve_sqshlu", [], [ImmCheck<2, ImmCheckShiftLeft, 1>]>; +def SVRSHR_M_S : SInst<"svrshr[_n_{d}]", "dPdi", "csil", MergeOp1, "aarch64_sve_srshr", [], [ImmCheck<2, ImmCheckShiftRight, 1>]>; +def SVRSHR_M_U : SInst<"svrshr[_n_{d}]", "dPdi", "UcUsUiUl", MergeOp1, "aarch64_sve_urshr", [], [ImmCheck<2, ImmCheckShiftRight, 1>]>; +def SVRSHR_X_S : SInst<"svrshr[_n_{d}]", "dPdi", "csil", MergeAny, "aarch64_sve_srshr", [], [ImmCheck<2, ImmCheckShiftRight, 1>]>; +def SVRSHR_X_U : SInst<"svrshr[_n_{d}]", "dPdi", "UcUsUiUl", MergeAny, "aarch64_sve_urshr", [], [ImmCheck<2, ImmCheckShiftRight, 1>]>; +def SVRSHR_Z_S : SInst<"svrshr[_n_{d}]", "dPdi", "csil", MergeZero, "aarch64_sve_srshr", [], [ImmCheck<2, ImmCheckShiftRight, 1>]>; +def SVRSHR_Z_U : SInst<"svrshr[_n_{d}]", "dPdi", "UcUsUiUl", MergeZero, "aarch64_sve_urshr", [], [ImmCheck<2, ImmCheckShiftRight, 1>]>; +def SVRSRA_S : SInst<"svrsra[_n_{d}]", "dddi", "csil", MergeNone, "aarch64_sve_srsra", [], [ImmCheck<2, ImmCheckShiftRight, 1>]>; +def SVRSRA_U : SInst<"svrsra[_n_{d}]", "dddi", "UcUsUiUl", MergeNone, "aarch64_sve_ursra", [], [ImmCheck<2, ImmCheckShiftRight, 1>]>; +def SVSLI : SInst<"svsli[_n_{d}]", "dddi", "csilUcUsUiUl", MergeNone, "aarch64_sve_sli", [], [ImmCheck<2, ImmCheckShiftLeft, 1>]>; +def SVSRA_S : SInst<"svsra[_n_{d}]", "dddi", "csil", MergeNone, "aarch64_sve_ssra", [], [ImmCheck<2, ImmCheckShiftRight, 1>]>; +def SVSRA_U : SInst<"svsra[_n_{d}]", "dddi", "UcUsUiUl", MergeNone, "aarch64_sve_usra", [], [ImmCheck<2, ImmCheckShiftRight, 1>]>; +def SVSRI : SInst<"svsri[_n_{d}]", "dddi", "csilUcUsUiUl", MergeNone, "aarch64_sve_sri", [], [ImmCheck<2, ImmCheckShiftRight, 1>]>; +} + +//////////////////////////////////////////////////////////////////////////////// +// SVE2 - Non-widening pairwise arithmetic + +multiclass SInstPairwise<string name, string types, string intrinsic, list<FlagType> flags=[]> { + def _M : SInst<name # "[_{d}]", "dPdd", types, MergeOp1, intrinsic, flags>; + def _X : SInst<name # "[_{d}]", "dPdd", types, MergeAny, intrinsic, flags>; +} + +let ArchGuard = "defined(__ARM_FEATURE_SVE2)" in { +defm SVADDP : SInstPairwise<"svaddp", "csliUcUsUiUl", "aarch64_sve_addp">; +defm SVADDP_F : SInstPairwise<"svaddp", "hfd", "aarch64_sve_faddp">; +defm SVMAXNMP : SInstPairwise<"svmaxnmp", "hfd", "aarch64_sve_fmaxnmp">; +defm SVMAXP_F : SInstPairwise<"svmaxp", "hfd", "aarch64_sve_fmaxp">; +defm SVMAXP_S : SInstPairwise<"svmaxp", "csli", "aarch64_sve_smaxp">; +defm SVMAXP_U : SInstPairwise<"svmaxp", "UcUsUiUl", "aarch64_sve_umaxp">; +defm SVMINNMP : SInstPairwise<"svminnmp", "hfd", "aarch64_sve_fminnmp">; +defm SVMINP_F : SInstPairwise<"svminp", "hfd", "aarch64_sve_fminp">; +defm SVMINP_S : SInstPairwise<"svminp", "csli", "aarch64_sve_sminp">; +defm SVMINP_U : SInstPairwise<"svminp", "UcUsUiUl", "aarch64_sve_uminp">; +} + +//////////////////////////////////////////////////////////////////////////////// +// SVE2 - Widening pairwise arithmetic + +let ArchGuard = "defined(__ARM_FEATURE_SVE2)" in { +def SVADALP_S_M : SInst<"svadalp[_{d}]", "dPdh", "sil", MergeOp1, "aarch64_sve_sadalp">; +def SVADALP_S_X : SInst<"svadalp[_{d}]", "dPdh", "sil", MergeAny, "aarch64_sve_sadalp">; +def SVADALP_S_Z : SInst<"svadalp[_{d}]", "dPdh", "sil", MergeZero, "aarch64_sve_sadalp">; + +def SVADALP_U_M : SInst<"svadalp[_{d}]", "dPdh", "UsUiUl", MergeOp1, "aarch64_sve_uadalp">; +def SVADALP_U_X : SInst<"svadalp[_{d}]", "dPdh", "UsUiUl", MergeAny, "aarch64_sve_uadalp">; +def SVADALP_U_Z : SInst<"svadalp[_{d}]", "dPdh", "UsUiUl", MergeZero, "aarch64_sve_uadalp">; +} + +//////////////////////////////////////////////////////////////////////////////// +// SVE2 - Bitwise ternary logical instructions +// + +let ArchGuard = "defined(__ARM_FEATURE_SVE2)" in { +def SVBCAX : SInst<"svbcax[_{d}]", "dddd", "csilUcUsUiUl", MergeNone, "aarch64_sve_bcax">; +def SVBSL : SInst<"svbsl[_{d}]", "dddd", "csilUcUsUiUl", MergeNone, "aarch64_sve_bsl">; +def SVBSL1N : SInst<"svbsl1n[_{d}]", "dddd", "csilUcUsUiUl", MergeNone, "aarch64_sve_bsl1n">; +def SVBSL2N : SInst<"svbsl2n[_{d}]", "dddd", "csilUcUsUiUl", MergeNone, "aarch64_sve_bsl2n">; +def SVEOR3 : SInst<"sveor3[_{d}]", "dddd", "csilUcUsUiUl", MergeNone, "aarch64_sve_eor3">; +def SVNBSL : SInst<"svnbsl[_{d}]", "dddd", "csilUcUsUiUl", MergeNone, "aarch64_sve_nbsl">; + +def SVBCAX_N : SInst<"svbcax[_n_{d}]", "ddda", "csilUcUsUiUl", MergeNone, "aarch64_sve_bcax">; +def SVBSL_N : SInst<"svbsl[_n_{d}]", "ddda", "csilUcUsUiUl", MergeNone, "aarch64_sve_bsl">; +def SVBSL1N_N : SInst<"svbsl1n[_n_{d}]", "ddda", "csilUcUsUiUl", MergeNone, "aarch64_sve_bsl1n">; +def SVBSL2N_N : SInst<"svbsl2n[_n_{d}]", "ddda", "csilUcUsUiUl", MergeNone, "aarch64_sve_bsl2n">; +def SVEOR3_N : SInst<"sveor3[_n_{d}]", "ddda", "csilUcUsUiUl", MergeNone, "aarch64_sve_eor3">; +def SVNBSL_N : SInst<"svnbsl[_n_{d}]", "ddda", "csilUcUsUiUl", MergeNone, "aarch64_sve_nbsl">; +def SVXAR_N : SInst<"svxar[_n_{d}]", "dddi", "csilUcUsUiUl", MergeNone, "aarch64_sve_xar", [], [ImmCheck<2, ImmCheckShiftRight, 1>]>; +} + +//////////////////////////////////////////////////////////////////////////////// +// SVE2 - Large integer arithmetic + +let ArchGuard = "defined(__ARM_FEATURE_SVE2)" in { +def SVADCLB : SInst<"svadclb[_{d}]", "dddd", "UiUl", MergeNone, "aarch64_sve_adclb">; +def SVADCLT : SInst<"svadclt[_{d}]", "dddd", "UiUl", MergeNone, "aarch64_sve_adclt">; +def SVSBCLB : SInst<"svsbclb[_{d}]", "dddd", "UiUl", MergeNone, "aarch64_sve_sbclb">; +def SVSBCLT : SInst<"svsbclt[_{d}]", "dddd", "UiUl", MergeNone, "aarch64_sve_sbclt">; + +def SVADCLB_N : SInst<"svadclb[_n_{d}]", "ddda", "UiUl", MergeNone, "aarch64_sve_adclb">; +def SVADCLT_N : SInst<"svadclt[_n_{d}]", "ddda", "UiUl", MergeNone, "aarch64_sve_adclt">; +def SVSBCLB_N : SInst<"svsbclb[_n_{d}]", "ddda", "UiUl", MergeNone, "aarch64_sve_sbclb">; +def SVSBCLT_N : SInst<"svsbclt[_n_{d}]", "ddda", "UiUl", MergeNone, "aarch64_sve_sbclt">; +} + +//////////////////////////////////////////////////////////////////////////////// +// SVE2 - Multiplication by indexed elements + +let ArchGuard = "defined(__ARM_FEATURE_SVE2)" in { +def SVMLA_LANE_2 : SInst<"svmla_lane[_{d}]", "ddddi", "silUsUiUl", MergeNone, "aarch64_sve_mla_lane", [], [ImmCheck<3, ImmCheckLaneIndex, 2>]>; +def SVMLS_LANE_2 : SInst<"svmls_lane[_{d}]", "ddddi", "silUsUiUl", MergeNone, "aarch64_sve_mls_lane", [], [ImmCheck<3, ImmCheckLaneIndex, 2>]>; +def SVMUL_LANE_2 : SInst<"svmul_lane[_{d}]", "dddi", "silUsUiUl", MergeNone, "aarch64_sve_mul_lane", [], [ImmCheck<2, ImmCheckLaneIndex, 1>]>; +} + +//////////////////////////////////////////////////////////////////////////////// +// SVE2 - Uniform complex integer arithmetic +let ArchGuard = "defined(__ARM_FEATURE_SVE2)" in { +def SVCADD : SInst<"svcadd[_{d}]", "dddi", "csilUcUsUiUl", MergeNone, "aarch64_sve_cadd_x", [], [ImmCheck<2, ImmCheckComplexRot90_270>]>; +def SVSQCADD : SInst<"svqcadd[_{d}]", "dddi", "csil", MergeNone, "aarch64_sve_sqcadd_x", [], [ImmCheck<2, ImmCheckComplexRot90_270>]>; +def SVCMLA : SInst<"svcmla[_{d}]", "ddddi", "csilUcUsUiUl", MergeNone, "aarch64_sve_cmla_x", [], [ImmCheck<3, ImmCheckComplexRotAll90>]>; +def SVCMLA_LANE_X : SInst<"svcmla_lane[_{d}]", "ddddii", "siUsUi", MergeNone, "aarch64_sve_cmla_lane_x", [], [ImmCheck<3, ImmCheckLaneIndexCompRotate, 2>, + ImmCheck<4, ImmCheckComplexRotAll90>]>; +def SVSQRDCMLAH_X : SInst<"svqrdcmlah[_{d}]", "ddddi", "csil", MergeNone, "aarch64_sve_sqrdcmlah_x", [], [ImmCheck<3, ImmCheckComplexRotAll90>]>; +def SVSQRDCMLAH_LANE_X : SInst<"svqrdcmlah_lane[_{d}]", "ddddii", "si", MergeNone, "aarch64_sve_sqrdcmlah_lane_x", [], [ImmCheck<3, ImmCheckLaneIndexCompRotate, 2>, + ImmCheck<4, ImmCheckComplexRotAll90>]>; +} + +//////////////////////////////////////////////////////////////////////////////// +// SVE2 - Widening DSP operations + +multiclass SInstWideDSPAcc<string name, string types, string intrinsic> { + def : SInst<name # "[_{d}]", "ddhh", types, MergeNone, intrinsic>; + def _N : SInst<name # "[_n_{d}]", "ddhR", types, MergeNone, intrinsic>; +} + +multiclass SInstWideDSPLong<string name, string types, string intrinsic> { + def : SInst<name # "[_{d}]", "dhh", types, MergeNone, intrinsic>; + def _N : SInst<name # "[_n_{d}]", "dhR", types, MergeNone, intrinsic>; +} + +multiclass SInstWideDSPWide<string name, string types, string intrinsic> { + def : SInst<name # "[_{d}]", "ddh", types, MergeNone, intrinsic>; + def _N : SInst<name # "[_n_{d}]", "ddR", types, MergeNone, intrinsic>; +} + +let ArchGuard = "defined(__ARM_FEATURE_SVE2)" in { +defm SVABALB_S : SInstWideDSPAcc<"svabalb", "sil", "aarch64_sve_sabalb">; +defm SVABALB_U : SInstWideDSPAcc<"svabalb", "UsUiUl", "aarch64_sve_uabalb">; +defm SVABALT_S : SInstWideDSPAcc<"svabalt", "sil", "aarch64_sve_sabalt">; +defm SVABALT_U : SInstWideDSPAcc<"svabalt", "UsUiUl", "aarch64_sve_uabalt">; +defm SVMLALB_S : SInstWideDSPAcc<"svmlalb", "sil", "aarch64_sve_smlalb">; +defm SVMLALB_U : SInstWideDSPAcc<"svmlalb", "UsUiUl", "aarch64_sve_umlalb">; +defm SVMLALT_S : SInstWideDSPAcc<"svmlalt", "sil", "aarch64_sve_smlalt">; +defm SVMLALT_U : SInstWideDSPAcc<"svmlalt", "UsUiUl", "aarch64_sve_umlalt">; +defm SVMLSLB_S : SInstWideDSPAcc<"svmlslb", "sil", "aarch64_sve_smlslb">; +defm SVMLSLB_U : SInstWideDSPAcc<"svmlslb", "UsUiUl", "aarch64_sve_umlslb">; +defm SVMLSLT_S : SInstWideDSPAcc<"svmlslt", "sil", "aarch64_sve_smlslt">; +defm SVMLSLT_U : SInstWideDSPAcc<"svmlslt", "UsUiUl", "aarch64_sve_umlslt">; +defm SVQDMLALB : SInstWideDSPAcc<"svqdmlalb", "sil", "aarch64_sve_sqdmlalb">; +defm SVQDMLALT : SInstWideDSPAcc<"svqdmlalt", "sil", "aarch64_sve_sqdmlalt">; +defm SVQDMLSLB : SInstWideDSPAcc<"svqdmlslb", "sil", "aarch64_sve_sqdmlslb">; +defm SVQDMLSLT : SInstWideDSPAcc<"svqdmlslt", "sil", "aarch64_sve_sqdmlslt">; + +defm SVABDLB_S : SInstWideDSPLong<"svabdlb", "sil", "aarch64_sve_sabdlb">; +defm SVABDLB_U : SInstWideDSPLong<"svabdlb", "UsUiUl", "aarch64_sve_uabdlb">; +defm SVABDLT_S : SInstWideDSPLong<"svabdlt", "sil", "aarch64_sve_sabdlt">; +defm SVABDLT_U : SInstWideDSPLong<"svabdlt", "UsUiUl", "aarch64_sve_uabdlt">; +defm SVADDLB_S : SInstWideDSPLong<"svaddlb", "sil", "aarch64_sve_saddlb">; +defm SVADDLB_U : SInstWideDSPLong<"svaddlb", "UsUiUl", "aarch64_sve_uaddlb">; +defm SVADDLT_S : SInstWideDSPLong<"svaddlt", "sil", "aarch64_sve_saddlt">; +defm SVADDLT_U : SInstWideDSPLong<"svaddlt", "UsUiUl", "aarch64_sve_uaddlt">; +defm SVMULLB_S : SInstWideDSPLong<"svmullb", "sil", "aarch64_sve_smullb">; +defm SVMULLB_U : SInstWideDSPLong<"svmullb", "UsUiUl", "aarch64_sve_umullb">; +defm SVMULLT_S : SInstWideDSPLong<"svmullt", "sil", "aarch64_sve_smullt">; +defm SVMULLT_U : SInstWideDSPLong<"svmullt", "UsUiUl", "aarch64_sve_umullt">; +defm SVQDMULLB : SInstWideDSPLong<"svqdmullb", "sil", "aarch64_sve_sqdmullb">; +defm SVQDMULLT : SInstWideDSPLong<"svqdmullt", "sil", "aarch64_sve_sqdmullt">; +defm SVSUBLB_S : SInstWideDSPLong<"svsublb", "sil", "aarch64_sve_ssublb">; +defm SVSUBLB_U : SInstWideDSPLong<"svsublb", "UsUiUl", "aarch64_sve_usublb">; +defm SVSUBLT_S : SInstWideDSPLong<"svsublt", "sil", "aarch64_sve_ssublt">; +defm SVSUBLT_U : SInstWideDSPLong<"svsublt", "UsUiUl", "aarch64_sve_usublt">; + +defm SVADDWB_S : SInstWideDSPWide<"svaddwb", "sil", "aarch64_sve_saddwb">; +defm SVADDWB_U : SInstWideDSPWide<"svaddwb", "UsUiUl", "aarch64_sve_uaddwb">; +defm SVADDWT_S : SInstWideDSPWide<"svaddwt", "sil", "aarch64_sve_saddwt">; +defm SVADDWT_U : SInstWideDSPWide<"svaddwt", "UsUiUl", "aarch64_sve_uaddwt">; +defm SVSUBWB_S : SInstWideDSPWide<"svsubwb", "sil", "aarch64_sve_ssubwb">; +defm SVSUBWB_U : SInstWideDSPWide<"svsubwb", "UsUiUl", "aarch64_sve_usubwb">; +defm SVSUBWT_S : SInstWideDSPWide<"svsubwt", "sil", "aarch64_sve_ssubwt">; +defm SVSUBWT_U : SInstWideDSPWide<"svsubwt", "UsUiUl", "aarch64_sve_usubwt">; + +def SVSHLLB_S_N : SInst<"svshllb[_n_{d}]", "dhi", "sil", MergeNone, "aarch64_sve_sshllb", [], [ImmCheck<1, ImmCheckShiftLeft, 0>]>; +def SVSHLLB_U_N : SInst<"svshllb[_n_{d}]", "dhi", "UsUiUl", MergeNone, "aarch64_sve_ushllb", [], [ImmCheck<1, ImmCheckShiftLeft, 0>]>; +def SVSHLLT_S_N : SInst<"svshllt[_n_{d}]", "dhi", "sil", MergeNone, "aarch64_sve_sshllt", [], [ImmCheck<1, ImmCheckShiftLeft, 0>]>; +def SVSHLLT_U_N : SInst<"svshllt[_n_{d}]", "dhi", "UsUiUl", MergeNone, "aarch64_sve_ushllt", [], [ImmCheck<1, ImmCheckShiftLeft, 0>]>; + +def SVMOVLB_S_N : SInst<"svmovlb[_{d}]", "dh", "sil", MergeNone>; +def SVMOVLB_U_N : SInst<"svmovlb[_{d}]", "dh", "UsUiUl", MergeNone>; +def SVMOVLT_S_N : SInst<"svmovlt[_{d}]", "dh", "sil", MergeNone>; +def SVMOVLT_U_N : SInst<"svmovlt[_{d}]", "dh", "UsUiUl", MergeNone>; + +def SVMLALB_S_LANE : SInst<"svmlalb_lane[_{d}]", "ddhhi", "il", MergeNone, "aarch64_sve_smlalb_lane", [], [ImmCheck<3, ImmCheckLaneIndex, 2>]>; +def SVMLALB_U_LANE : SInst<"svmlalb_lane[_{d}]", "ddhhi", "UiUl", MergeNone, "aarch64_sve_umlalb_lane", [], [ImmCheck<3, ImmCheckLaneIndex, 2>]>; +def SVMLALT_S_LANE : SInst<"svmlalt_lane[_{d}]", "ddhhi", "il", MergeNone, "aarch64_sve_smlalt_lane", [], [ImmCheck<3, ImmCheckLaneIndex, 2>]>; +def SVMLALT_U_LANE : SInst<"svmlalt_lane[_{d}]", "ddhhi", "UiUl", MergeNone, "aarch64_sve_umlalt_lane", [], [ImmCheck<3, ImmCheckLaneIndex, 2>]>; +def SVMLSLB_S_LANE : SInst<"svmlslb_lane[_{d}]", "ddhhi", "il", MergeNone, "aarch64_sve_smlslb_lane", [], [ImmCheck<3, ImmCheckLaneIndex, 2>]>; +def SVMLSLB_U_LANE : SInst<"svmlslb_lane[_{d}]", "ddhhi", "UiUl", MergeNone, "aarch64_sve_umlslb_lane", [], [ImmCheck<3, ImmCheckLaneIndex, 2>]>; +def SVMLSLT_S_LANE : SInst<"svmlslt_lane[_{d}]", "ddhhi", "il", MergeNone, "aarch64_sve_smlslt_lane", [], [ImmCheck<3, ImmCheckLaneIndex, 2>]>; +def SVMLSLT_U_LANE : SInst<"svmlslt_lane[_{d}]", "ddhhi", "UiUl", MergeNone, "aarch64_sve_umlslt_lane", [], [ImmCheck<3, ImmCheckLaneIndex, 2>]>; +def SVMULLB_S_LANE : SInst<"svmullb_lane[_{d}]", "dhhi", "il", MergeNone, "aarch64_sve_smullb_lane", [], [ImmCheck<2, ImmCheckLaneIndex, 1>]>; +def SVMULLB_U_LANE : SInst<"svmullb_lane[_{d}]", "dhhi", "UiUl", MergeNone, "aarch64_sve_umullb_lane", [], [ImmCheck<2, ImmCheckLaneIndex, 1>]>; +def SVMULLT_S_LANE : SInst<"svmullt_lane[_{d}]", "dhhi", "il", MergeNone, "aarch64_sve_smullt_lane", [], [ImmCheck<2, ImmCheckLaneIndex, 1>]>; +def SVMULLT_U_LANE : SInst<"svmullt_lane[_{d}]", "dhhi", "UiUl", MergeNone, "aarch64_sve_umullt_lane", [], [ImmCheck<2, ImmCheckLaneIndex, 1>]>; +def SVQDMLALB_LANE : SInst<"svqdmlalb_lane[_{d}]", "ddhhi", "il", MergeNone, "aarch64_sve_sqdmlalb_lane", [], [ImmCheck<3, ImmCheckLaneIndex, 2>]>; +def SVQDMLALT_LANE : SInst<"svqdmlalt_lane[_{d}]", "ddhhi", "il", MergeNone, "aarch64_sve_sqdmlalt_lane", [], [ImmCheck<3, ImmCheckLaneIndex, 2>]>; +def SVQDMLSLB_LANE : SInst<"svqdmlslb_lane[_{d}]", "ddhhi", "il", MergeNone, "aarch64_sve_sqdmlslb_lane", [], [ImmCheck<3, ImmCheckLaneIndex, 2>]>; +def SVQDMLSLT_LANE : SInst<"svqdmlslt_lane[_{d}]", "ddhhi", "il", MergeNone, "aarch64_sve_sqdmlslt_lane", [], [ImmCheck<3, ImmCheckLaneIndex, 2>]>; +def SVQDMULLB_LANE : SInst<"svqdmullb_lane[_{d}]", "dhhi", "il", MergeNone, "aarch64_sve_sqdmullb_lane", [], [ImmCheck<2, ImmCheckLaneIndex, 1>]>; +def SVQDMULLT_LANE : SInst<"svqdmullt_lane[_{d}]", "dhhi", "il", MergeNone, "aarch64_sve_sqdmullt_lane", [], [ImmCheck<2, ImmCheckLaneIndex, 1>]>; +} + +//////////////////////////////////////////////////////////////////////////////// +// SVE2 - Narrowing DSP operations + +let ArchGuard = "defined(__ARM_FEATURE_SVE2)" in { +def SVADDHNB : SInst<"svaddhnb[_{d}]", "hdd", "silUsUiUl", MergeNone, "aarch64_sve_addhnb">; +def SVADDHNT : SInst<"svaddhnt[_{d}]", "hhdd", "silUsUiUl", MergeNone, "aarch64_sve_addhnt">; +def SVRADDHNB : SInst<"svraddhnb[_{d}]", "hdd", "silUsUiUl", MergeNone, "aarch64_sve_raddhnb">; +def SVRADDHNT : SInst<"svraddhnt[_{d}]", "hhdd", "silUsUiUl", MergeNone, "aarch64_sve_raddhnt">; +def SVRSUBHNB : SInst<"svrsubhnb[_{d}]", "hdd", "silUsUiUl", MergeNone, "aarch64_sve_rsubhnb">; +def SVRSUBHNT : SInst<"svrsubhnt[_{d}]", "hhdd", "silUsUiUl", MergeNone, "aarch64_sve_rsubhnt">; +def SVSUBHNB : SInst<"svsubhnb[_{d}]", "hdd", "silUsUiUl", MergeNone, "aarch64_sve_subhnb">; +def SVSUBHNT : SInst<"svsubhnt[_{d}]", "hhdd", "silUsUiUl", MergeNone, "aarch64_sve_subhnt">; + +def SVADDHNB_N : SInst<"svaddhnb[_n_{d}]", "hda", "silUsUiUl", MergeNone, "aarch64_sve_addhnb">; +def SVADDHNT_N : SInst<"svaddhnt[_n_{d}]", "hhda", "silUsUiUl", MergeNone, "aarch64_sve_addhnt">; +def SVRADDHNB_N : SInst<"svraddhnb[_n_{d}]", "hda", "silUsUiUl", MergeNone, "aarch64_sve_raddhnb">; +def SVRADDHNT_N : SInst<"svraddhnt[_n_{d}]", "hhda", "silUsUiUl", MergeNone, "aarch64_sve_raddhnt">; +def SVRSUBHNB_N : SInst<"svrsubhnb[_n_{d}]", "hda", "silUsUiUl", MergeNone, "aarch64_sve_rsubhnb">; +def SVRSUBHNT_N : SInst<"svrsubhnt[_n_{d}]", "hhda", "silUsUiUl", MergeNone, "aarch64_sve_rsubhnt">; +def SVSUBHNB_N : SInst<"svsubhnb[_n_{d}]", "hda", "silUsUiUl", MergeNone, "aarch64_sve_subhnb">; +def SVSUBHNT_N : SInst<"svsubhnt[_n_{d}]", "hhda", "silUsUiUl", MergeNone, "aarch64_sve_subhnt">; + +def SVSHRNB : SInst<"svshrnb[_n_{d}]", "hdi", "silUsUiUl", MergeNone, "aarch64_sve_shrnb", [], [ImmCheck<1, ImmCheckShiftRightNarrow, 0>]>; +def SVRSHRNB : SInst<"svrshrnb[_n_{d}]", "hdi", "silUsUiUl", MergeNone, "aarch64_sve_rshrnb", [], [ImmCheck<1, ImmCheckShiftRightNarrow, 0>]>; +def SVQSHRUNB : SInst<"svqshrunb[_n_{d}]", "edi", "sil", MergeNone, "aarch64_sve_sqshrunb", [], [ImmCheck<1, ImmCheckShiftRightNarrow, 0>]>; +def SVQRSHRUNB : SInst<"svqrshrunb[_n_{d}]", "edi", "sil", MergeNone, "aarch64_sve_sqrshrunb", [], [ImmCheck<1, ImmCheckShiftRightNarrow, 0>]>; +def SVQSHRNB_S : SInst<"svqshrnb[_n_{d}]", "hdi", "sil", MergeNone, "aarch64_sve_sqshrnb", [], [ImmCheck<1, ImmCheckShiftRightNarrow, 0>]>; +def SVQSHRNB_U : SInst<"svqshrnb[_n_{d}]", "hdi", "UsUiUl", MergeNone, "aarch64_sve_uqshrnb", [], [ImmCheck<1, ImmCheckShiftRightNarrow, 0>]>; +def SVQRSHRNB_S : SInst<"svqrshrnb[_n_{d}]", "hdi", "sil", MergeNone, "aarch64_sve_sqrshrnb", [], [ImmCheck<1, ImmCheckShiftRightNarrow, 0>]>; +def SVQRSHRNB_U : SInst<"svqrshrnb[_n_{d}]", "hdi", "UsUiUl", MergeNone, "aarch64_sve_uqrshrnb", [], [ImmCheck<1, ImmCheckShiftRightNarrow, 0>]>; + +def SVSHRNT : SInst<"svshrnt[_n_{d}]", "hhdi", "silUsUiUl", MergeNone, "aarch64_sve_shrnt", [], [ImmCheck<2, ImmCheckShiftRightNarrow, 1>]>; +def SVRSHRNT : SInst<"svrshrnt[_n_{d}]", "hhdi", "silUsUiUl", MergeNone, "aarch64_sve_rshrnt", [], [ImmCheck<2, ImmCheckShiftRightNarrow, 1>]>; +def SVQSHRUNT : SInst<"svqshrunt[_n_{d}]", "eedi", "sil", MergeNone, "aarch64_sve_sqshrunt", [], [ImmCheck<2, ImmCheckShiftRightNarrow, 1>]>; +def SVQRSHRUNT : SInst<"svqrshrunt[_n_{d}]", "eedi", "sil", MergeNone, "aarch64_sve_sqrshrunt", [], [ImmCheck<2, ImmCheckShiftRightNarrow, 1>]>; +def SVQSHRNT_S : SInst<"svqshrnt[_n_{d}]", "hhdi", "sil", MergeNone, "aarch64_sve_sqshrnt", [], [ImmCheck<2, ImmCheckShiftRightNarrow, 1>]>; +def SVQSHRNT_U : SInst<"svqshrnt[_n_{d}]", "hhdi", "UsUiUl", MergeNone, "aarch64_sve_uqshrnt", [], [ImmCheck<2, ImmCheckShiftRightNarrow, 1>]>; +def SVQRSHRNT_S : SInst<"svqrshrnt[_n_{d}]", "hhdi", "sil", MergeNone, "aarch64_sve_sqrshrnt", [], [ImmCheck<2, ImmCheckShiftRightNarrow, 1>]>; +def SVQRSHRNT_U : SInst<"svqrshrnt[_n_{d}]", "hhdi", "UsUiUl", MergeNone, "aarch64_sve_uqrshrnt", [], [ImmCheck<2, ImmCheckShiftRightNarrow, 1>]>; +} +//////////////////////////////////////////////////////////////////////////////// +// SVE2 - Unary narrowing operations + +let ArchGuard = "defined(__ARM_FEATURE_SVE2)" in { +def SVQXTNB_S : SInst<"svqxtnb[_{d}]", "hd", "sil", MergeNone, "aarch64_sve_sqxtnb">; +def SVQXTNB_U : SInst<"svqxtnb[_{d}]", "hd", "UsUiUl", MergeNone, "aarch64_sve_uqxtnb">; +def SVQXTUNB_S : SInst<"svqxtunb[_{d}]", "ed", "sil", MergeNone, "aarch64_sve_sqxtunb">; + +def SVQXTNT_S : SInst<"svqxtnt[_{d}]", "hhd", "sil", MergeNone, "aarch64_sve_sqxtnt">; +def SVQXTNT_U : SInst<"svqxtnt[_{d}]", "hhd", "UsUiUl", MergeNone, "aarch64_sve_uqxtnt">; +def SVQXTUNT_S : SInst<"svqxtunt[_{d}]", "eed", "sil", MergeNone, "aarch64_sve_sqxtunt">; +} + +//////////////////////////////////////////////////////////////////////////////// +// SVE2 - Widening complex integer arithmetic + +let ArchGuard = "defined(__ARM_FEATURE_SVE2)" in { +defm SVADDLBT : SInstWideDSPLong<"svaddlbt", "sil", "aarch64_sve_saddlbt">; +defm SVSUBLBT : SInstWideDSPLong<"svsublbt", "sil", "aarch64_sve_ssublbt">; +defm SVSUBLTB : SInstWideDSPLong<"svsubltb", "sil", "aarch64_sve_ssubltb">; + +defm SVQDMLALBT : SInstWideDSPAcc<"svqdmlalbt", "sil", "aarch64_sve_sqdmlalbt">; +defm SVQDMLSLBT : SInstWideDSPAcc<"svqdmlslbt", "sil", "aarch64_sve_sqdmlslbt">; +} + +//////////////////////////////////////////////////////////////////////////////// +// SVE2 - Non-temporal gather/scatter +let ArchGuard = "defined(__ARM_FEATURE_SVE2)" in { +// Non-temporal gather load one vector (vector base) +def SVLDNT1_GATHER_BASES_U : MInst<"svldnt1_gather[_{2}base]_{0}", "dPu", "ilUiUlfd", [IsGatherLoad], MemEltTyDefault, "aarch64_sve_ldnt1_gather_scalar_offset">; +def SVLDNT1SB_GATHER_BASES_U : MInst<"svldnt1sb_gather[_{2}base]_{0}", "dPu", "ilUiUl", [IsGatherLoad], MemEltTyInt8, "aarch64_sve_ldnt1_gather_scalar_offset">; +def SVLDNT1UB_GATHER_BASES_U : MInst<"svldnt1ub_gather[_{2}base]_{0}", "dPu", "ilUiUl", [IsGatherLoad, IsZExtReturn], MemEltTyInt8, "aarch64_sve_ldnt1_gather_scalar_offset">; +def SVLDNT1SH_GATHER_BASES_U : MInst<"svldnt1sh_gather[_{2}base]_{0}", "dPu", "ilUiUl", [IsGatherLoad], MemEltTyInt16, "aarch64_sve_ldnt1_gather_scalar_offset">; +def SVLDNT1UH_GATHER_BASES_U : MInst<"svldnt1uh_gather[_{2}base]_{0}", "dPu", "ilUiUl", [IsGatherLoad, IsZExtReturn], MemEltTyInt16, "aarch64_sve_ldnt1_gather_scalar_offset">; +def SVLDNT1SW_GATHER_BASES_U : MInst<"svldnt1sw_gather[_{2}base]_{0}", "dPu", "lUl", [IsGatherLoad], MemEltTyInt32, "aarch64_sve_ldnt1_gather_scalar_offset">; +def SVLDNT1UW_GATHER_BASES_U : MInst<"svldnt1uw_gather[_{2}base]_{0}", "dPu", "lUl", [IsGatherLoad, IsZExtReturn], MemEltTyInt32, "aarch64_sve_ldnt1_gather_scalar_offset">; + +// Non-temporal gather load one vector (scalar base, signed vector offset in bytes) +def SVLDNT1_GATHER_64B_OFFSETS_S : MInst<"svldnt1_gather_[{3}]offset[_{0}]", "dPcx", "lUld", [IsGatherLoad, IsByteIndexed], MemEltTyDefault, "aarch64_sve_ldnt1_gather">; +def SVLDNT1SB_GATHER_64B_OFFSETS_S : MInst<"svldnt1sb_gather_[{3}]offset_{0}", "dPSx", "lUl", [IsGatherLoad, IsByteIndexed], MemEltTyInt8, "aarch64_sve_ldnt1_gather">; +def SVLDNT1UB_GATHER_64B_OFFSETS_S : MInst<"svldnt1ub_gather_[{3}]offset_{0}", "dPWx", "lUl", [IsGatherLoad, IsByteIndexed, IsZExtReturn], MemEltTyInt8, "aarch64_sve_ldnt1_gather">; +def SVLDNT1SH_GATHER_64B_OFFSETS_S : MInst<"svldnt1sh_gather_[{3}]offset_{0}", "dPTx", "lUl", [IsGatherLoad, IsByteIndexed], MemEltTyInt16, "aarch64_sve_ldnt1_gather">; +def SVLDNT1UH_GATHER_64B_OFFSETS_S : MInst<"svldnt1uh_gather_[{3}]offset_{0}", "dPXx", "lUl", [IsGatherLoad, IsByteIndexed, IsZExtReturn], MemEltTyInt16, "aarch64_sve_ldnt1_gather">; +def SVLDNT1SW_GATHER_64B_OFFSETS_S : MInst<"svldnt1sw_gather_[{3}]offset_{0}", "dPUx", "lUl", [IsGatherLoad, IsByteIndexed], MemEltTyInt32, "aarch64_sve_ldnt1_gather">; +def SVLDNT1UW_GATHER_64B_OFFSETS_S : MInst<"svldnt1uw_gather_[{3}]offset_{0}", "dPYx", "lUl", [IsGatherLoad, IsByteIndexed, IsZExtReturn], MemEltTyInt32, "aarch64_sve_ldnt1_gather">; + +// Non-temporal gather load one vector (scalar base, unsigned vector offset in bytes) +def SVLDNT1_GATHER_64B_OFFSETS_U : MInst<"svldnt1_gather_[{3}]offset[_{0}]", "dPcu", "lUld", [IsGatherLoad, IsByteIndexed], MemEltTyDefault, "aarch64_sve_ldnt1_gather">; +def SVLDNT1SB_GATHER_64B_OFFSETS_U : MInst<"svldnt1sb_gather_[{3}]offset_{0}", "dPSu", "lUl", [IsGatherLoad, IsByteIndexed], MemEltTyInt8, "aarch64_sve_ldnt1_gather">; +def SVLDNT1UB_GATHER_64B_OFFSETS_U : MInst<"svldnt1ub_gather_[{3}]offset_{0}", "dPWu", "lUl", [IsGatherLoad, IsByteIndexed, IsZExtReturn], MemEltTyInt8, "aarch64_sve_ldnt1_gather">; +def SVLDNT1SH_GATHER_64B_OFFSETS_U : MInst<"svldnt1sh_gather_[{3}]offset_{0}", "dPTu", "lUl", [IsGatherLoad, IsByteIndexed], MemEltTyInt16, "aarch64_sve_ldnt1_gather">; +def SVLDNT1UH_GATHER_64B_OFFSETS_U : MInst<"svldnt1uh_gather_[{3}]offset_{0}", "dPXu", "lUl", [IsGatherLoad, IsByteIndexed, IsZExtReturn], MemEltTyInt16, "aarch64_sve_ldnt1_gather">; +def SVLDNT1SW_GATHER_64B_OFFSETS_U : MInst<"svldnt1sw_gather_[{3}]offset_{0}", "dPUu", "lUl", [IsGatherLoad, IsByteIndexed], MemEltTyInt32, "aarch64_sve_ldnt1_gather">; +def SVLDNT1UW_GATHER_64B_OFFSETS_U : MInst<"svldnt1uw_gather_[{3}]offset_{0}", "dPYu", "lUl", [IsGatherLoad, IsByteIndexed, IsZExtReturn], MemEltTyInt32, "aarch64_sve_ldnt1_gather">; + +def SVLDNT1_GATHER_32B_OFFSETS_U : MInst<"svldnt1_gather_[{3}]offset[_{0}]", "dPcu", "iUif", [IsGatherLoad, IsByteIndexed], MemEltTyDefault, "aarch64_sve_ldnt1_gather_uxtw">; +def SVLDNT1SB_GATHER_32B_OFFSETS_U : MInst<"svldnt1sb_gather_[{3}]offset_{0}", "dPSu", "iUi", [IsGatherLoad, IsByteIndexed], MemEltTyInt8, "aarch64_sve_ldnt1_gather_uxtw">; +def SVLDNT1UB_GATHER_32B_OFFSETS_U : MInst<"svldnt1ub_gather_[{3}]offset_{0}", "dPWu", "iUi", [IsGatherLoad, IsByteIndexed, IsZExtReturn], MemEltTyInt8, "aarch64_sve_ldnt1_gather_uxtw">; +def SVLDNT1SH_GATHER_32B_OFFSETS_U : MInst<"svldnt1sh_gather_[{3}]offset_{0}", "dPTu", "iUi", [IsGatherLoad, IsByteIndexed], MemEltTyInt16, "aarch64_sve_ldnt1_gather_uxtw">; +def SVLDNT1UH_GATHER_32B_OFFSETS_U : MInst<"svldnt1uh_gather_[{3}]offset_{0}", "dPXu", "iUi", [IsGatherLoad, IsByteIndexed, IsZExtReturn], MemEltTyInt16, "aarch64_sve_ldnt1_gather_uxtw">; + +// Non-temporal gather load one vector (vector base, scalar offset in bytes) +def SVLDNT1_GATHER_OFFSET_S : MInst<"svldnt1_gather[_{2}base]_offset_{0}", "dPul", "ilUiUlfd", [IsGatherLoad, IsByteIndexed], MemEltTyDefault, "aarch64_sve_ldnt1_gather_scalar_offset">; +def SVLDNT1SB_GATHER_OFFSET_S : MInst<"svldnt1sb_gather[_{2}base]_offset_{0}", "dPul", "ilUiUl", [IsGatherLoad, IsByteIndexed], MemEltTyInt8, "aarch64_sve_ldnt1_gather_scalar_offset">; +def SVLDNT1UB_GATHER_OFFSET_S : MInst<"svldnt1ub_gather[_{2}base]_offset_{0}", "dPul", "ilUiUl", [IsGatherLoad, IsByteIndexed, IsZExtReturn], MemEltTyInt8, "aarch64_sve_ldnt1_gather_scalar_offset">; +def SVLDNT1SH_GATHER_OFFSET_S : MInst<"svldnt1sh_gather[_{2}base]_offset_{0}", "dPul", "ilUiUl", [IsGatherLoad, IsByteIndexed], MemEltTyInt16, "aarch64_sve_ldnt1_gather_scalar_offset">; +def SVLDNT1UH_GATHER_OFFSET_S : MInst<"svldnt1uh_gather[_{2}base]_offset_{0}", "dPul", "ilUiUl", [IsGatherLoad, IsByteIndexed, IsZExtReturn], MemEltTyInt16, "aarch64_sve_ldnt1_gather_scalar_offset">; +def SVLDNT1SW_GATHER_OFFSET_S : MInst<"svldnt1sw_gather[_{2}base]_offset_{0}", "dPul", "lUl", [IsGatherLoad, IsByteIndexed], MemEltTyInt32, "aarch64_sve_ldnt1_gather_scalar_offset">; +def SVLDNT1UW_GATHER_OFFSET_S : MInst<"svldnt1uw_gather[_{2}base]_offset_{0}", "dPul", "lUl", [IsGatherLoad, IsByteIndexed, IsZExtReturn], MemEltTyInt32, "aarch64_sve_ldnt1_gather_scalar_offset">; + +// Non-temporal gather load one vector (scalar base, signed vector index) +def SVLDNT1_GATHER_64B_INDICES_S : MInst<"svldnt1_gather_[{3}]index[_{0}]", "dPcx", "lUld", [IsGatherLoad], MemEltTyDefault, "aarch64_sve_ldnt1_gather_index">; +def SVLDNT1SH_GATHER_64B_INDICES_S : MInst<"svldnt1sh_gather_[{3}]index_{0}", "dPTx", "lUl", [IsGatherLoad], MemEltTyInt16, "aarch64_sve_ldnt1_gather_index">; +def SVLDNT1UH_GATHER_64B_INDICES_S : MInst<"svldnt1uh_gather_[{3}]index_{0}", "dPXx", "lUl", [IsGatherLoad, IsZExtReturn], MemEltTyInt16, "aarch64_sve_ldnt1_gather_index">; +def SVLDNT1SW_GATHER_64B_INDICES_S : MInst<"svldnt1sw_gather_[{3}]index_{0}", "dPUx", "lUl", [IsGatherLoad], MemEltTyInt32, "aarch64_sve_ldnt1_gather_index">; +def SVLDNT1UW_GATHER_64B_INDICES_S : MInst<"svldnt1uw_gather_[{3}]index_{0}", "dPYx", "lUl", [IsGatherLoad, IsZExtReturn], MemEltTyInt32, "aarch64_sve_ldnt1_gather_index">; + +// Non temporal gather load one vector (scalar base, unsigned vector index) +def SVLDNT1_GATHER_64B_INDICES_U : MInst<"svldnt1_gather_[{3}]index[_{0}]", "dPcu", "lUld", [IsGatherLoad], MemEltTyDefault, "aarch64_sve_ldnt1_gather_index">; +def SVLDNT1SH_GATHER_64B_INDICES_U : MInst<"svldnt1sh_gather_[{3}]index_{0}", "dPTu", "lUl", [IsGatherLoad], MemEltTyInt16, "aarch64_sve_ldnt1_gather_index">; +def SVLDNT1UH_GATHER_64B_INDICES_U : MInst<"svldnt1uh_gather_[{3}]index_{0}", "dPXu", "lUl", [IsGatherLoad, IsZExtReturn], MemEltTyInt16, "aarch64_sve_ldnt1_gather_index">; +def SVLDNT1SW_GATHER_64B_INDICES_U : MInst<"svldnt1sw_gather_[{3}]index_{0}", "dPUu", "lUl", [IsGatherLoad], MemEltTyInt32, "aarch64_sve_ldnt1_gather_index">; +def SVLDNT1UW_GATHER_64B_INDICES_U : MInst<"svldnt1uw_gather_[{3}]index_{0}", "dPYu", "lUl", [IsGatherLoad, IsZExtReturn], MemEltTyInt32, "aarch64_sve_ldnt1_gather_index">; + +// Non-temporal gather load one vector (vector base, signed scalar index) +def SVLDNT1_GATHER_INDEX_S : MInst<"svldnt1_gather[_{2}base]_index_{0}", "dPul", "ilUiUlfd", [IsGatherLoad], MemEltTyDefault, "aarch64_sve_ldnt1_gather_scalar_offset">; +def SVLDNT1SH_GATHER_INDEX_S : MInst<"svldnt1sh_gather[_{2}base]_index_{0}", "dPul", "ilUiUl", [IsGatherLoad], MemEltTyInt16, "aarch64_sve_ldnt1_gather_scalar_offset">; +def SVLDNT1UH_GATHER_INDEX_S : MInst<"svldnt1uh_gather[_{2}base]_index_{0}", "dPul", "ilUiUl", [IsGatherLoad, IsZExtReturn], MemEltTyInt16, "aarch64_sve_ldnt1_gather_scalar_offset">; +def SVLDNT1SW_GATHER_INDEX_S : MInst<"svldnt1sw_gather[_{2}base]_index_{0}", "dPul", "lUl", [IsGatherLoad], MemEltTyInt32, "aarch64_sve_ldnt1_gather_scalar_offset">; +def SVLDNT1UW_GATHER_INDEX_S : MInst<"svldnt1uw_gather[_{2}base]_index_{0}", "dPul", "lUl", [IsGatherLoad, IsZExtReturn], MemEltTyInt32, "aarch64_sve_ldnt1_gather_scalar_offset">; + +// Non-temporal scatter store one vector (vector base) +def SVSTNT1_SCATTER_BASES_U : MInst<"svstnt1_scatter[_{2}base_{d}]", "vPud", "ilUiUlfd", [IsScatterStore], MemEltTyDefault, "aarch64_sve_stnt1_scatter_scalar_offset">; +def SVSTNT1B_SCATTER_BASES_U : MInst<"svstnt1b_scatter[_{2}base_{d}]", "vPud", "ilUiUl", [IsScatterStore], MemEltTyInt8, "aarch64_sve_stnt1_scatter_scalar_offset">; +def SVSTNT1H_SCATTER_BASES_U : MInst<"svstnt1h_scatter[_{2}base_{d}]", "vPud", "ilUiUl", [IsScatterStore], MemEltTyInt16, "aarch64_sve_stnt1_scatter_scalar_offset">; +def SVSTNT1W_SCATTER_BASES_U : MInst<"svstnt1w_scatter[_{2}base_{d}]", "vPud", "lUl", [IsScatterStore], MemEltTyInt32, "aarch64_sve_stnt1_scatter_scalar_offset">; + +// Non-temporal scatter store one vector (scalar base, signed vector offset in bytes) +def SVSTNT1_SCATTER_64B_OFFSETS_S : MInst<"svstnt1_scatter_[{3}]offset[_{d}]", "vPpxd", "lUld", [IsScatterStore, IsByteIndexed], MemEltTyDefault, "aarch64_sve_stnt1_scatter">; +def SVSTNT1B_SCATTER_64B_OFFSETS_SS : MInst<"svstnt1b_scatter_[{3}]offset[_{d}]", "vPAxd", "l", [IsScatterStore, IsByteIndexed], MemEltTyInt8, "aarch64_sve_stnt1_scatter">; +def SVSTNT1B_SCATTER_64B_OFFSETS_SU : MInst<"svstnt1b_scatter_[{3}]offset[_{d}]", "vPExd", "Ul", [IsScatterStore, IsByteIndexed], MemEltTyInt8, "aarch64_sve_stnt1_scatter">; +def SVSTNT1H_SCATTER_64B_OFFSETS_SS : MInst<"svstnt1h_scatter_[{3}]offset[_{d}]", "vPBxd", "l", [IsScatterStore, IsByteIndexed], MemEltTyInt16, "aarch64_sve_stnt1_scatter">; +def SVSTNT1H_SCATTER_64B_OFFSETS_SU : MInst<"svstnt1h_scatter_[{3}]offset[_{d}]", "vPFxd", "Ul", [IsScatterStore, IsByteIndexed], MemEltTyInt16, "aarch64_sve_stnt1_scatter">; +def SVSTNT1W_SCATTER_64B_OFFSETS_SS : MInst<"svstnt1w_scatter_[{3}]offset[_{d}]", "vPCxd", "l", [IsScatterStore, IsByteIndexed], MemEltTyInt32, "aarch64_sve_stnt1_scatter">; +def SVSTNT1W_SCATTER_64B_OFFSETS_SU : MInst<"svstnt1w_scatter_[{3}]offset[_{d}]", "vPGxd", "Ul", [IsScatterStore, IsByteIndexed], MemEltTyInt32, "aarch64_sve_stnt1_scatter">; + +// Non-temporal scatter store one vector (scalar base, unsigned vector offset in bytes) +def SVSTNT1_SCATTER_64B_OFFSETS_U : MInst<"svstnt1_scatter_[{3}]offset[_{d}]", "vPpud", "lUld", [IsScatterStore, IsByteIndexed], MemEltTyDefault, "aarch64_sve_stnt1_scatter">; +def SVSTNT1B_SCATTER_64B_OFFSETS_US : MInst<"svstnt1b_scatter_[{3}]offset[_{d}]", "vPAud", "l", [IsScatterStore, IsByteIndexed], MemEltTyInt8, "aarch64_sve_stnt1_scatter">; +def SVSTNT1B_SCATTER_64B_OFFSETS_UU : MInst<"svstnt1b_scatter_[{3}]offset[_{d}]", "vPEud", "Ul", [IsScatterStore, IsByteIndexed], MemEltTyInt8, "aarch64_sve_stnt1_scatter">; +def SVSTNT1H_SCATTER_64B_OFFSETS_US : MInst<"svstnt1h_scatter_[{3}]offset[_{d}]", "vPBud", "l", [IsScatterStore, IsByteIndexed], MemEltTyInt16, "aarch64_sve_stnt1_scatter">; +def SVSTNT1H_SCATTER_64B_OFFSETS_UU : MInst<"svstnt1h_scatter_[{3}]offset[_{d}]", "vPFud", "Ul", [IsScatterStore, IsByteIndexed], MemEltTyInt16, "aarch64_sve_stnt1_scatter">; +def SVSTNT1W_SCATTER_64B_OFFSETS_US : MInst<"svstnt1w_scatter_[{3}]offset[_{d}]", "vPCud", "l", [IsScatterStore, IsByteIndexed], MemEltTyInt32, "aarch64_sve_stnt1_scatter">; +def SVSTNT1W_SCATTER_64B_OFFSETS_UU : MInst<"svstnt1w_scatter_[{3}]offset[_{d}]", "vPGud", "Ul", [IsScatterStore, IsByteIndexed], MemEltTyInt32, "aarch64_sve_stnt1_scatter">; + +def SVSTNT1_SCATTER_32B_OFFSETS_U : MInst<"svstnt1_scatter_[{3}]offset[_{d}]", "vPpud", "iUif", [IsScatterStore, IsByteIndexed], MemEltTyDefault, "aarch64_sve_stnt1_scatter_uxtw">; +def SVSTNT1B_SCATTER_32B_OFFSETS_US : MInst<"svstnt1b_scatter_[{3}]offset[_{d}]", "vPAud", "i", [IsScatterStore, IsByteIndexed], MemEltTyInt8, "aarch64_sve_stnt1_scatter_uxtw">; +def SVSTNT1B_SCATTER_32B_OFFSETS_UU : MInst<"svstnt1b_scatter_[{3}]offset[_{d}]", "vPEud", "Ui", [IsScatterStore, IsByteIndexed], MemEltTyInt8, "aarch64_sve_stnt1_scatter_uxtw">; +def SVSTNT1H_SCATTER_32B_OFFSETS_US : MInst<"svstnt1h_scatter_[{3}]offset[_{d}]", "vPBud", "i", [IsScatterStore, IsByteIndexed], MemEltTyInt16, "aarch64_sve_stnt1_scatter_uxtw">; +def SVSTNT1H_SCATTER_32B_OFFSETS_UU : MInst<"svstnt1h_scatter_[{3}]offset[_{d}]", "vPFud", "Ui", [IsScatterStore, IsByteIndexed], MemEltTyInt16, "aarch64_sve_stnt1_scatter_uxtw">; + +// Non-temporal scatter store one vector (vector base, scalar offset in bytes) +def SVSTNT1_SCATTER_OFFSET_S : MInst<"svstnt1_scatter[_{2}base]_offset[_{d}]", "vPuld", "ilUiUlfd", [IsScatterStore, IsByteIndexed], MemEltTyDefault, "aarch64_sve_stnt1_scatter_scalar_offset">; +def SVSTNT1B_SCATTER_OFFSET_S : MInst<"svstnt1b_scatter[_{2}base]_offset[_{d}]", "vPuld", "ilUiUl", [IsScatterStore, IsByteIndexed], MemEltTyInt8, "aarch64_sve_stnt1_scatter_scalar_offset">; +def SVSTNT1H_SCATTER_OFFSET_S : MInst<"svstnt1h_scatter[_{2}base]_offset[_{d}]", "vPuld", "ilUiUl", [IsScatterStore, IsByteIndexed], MemEltTyInt16, "aarch64_sve_stnt1_scatter_scalar_offset">; +def SVSTNT1W_SCATTER_OFFSET_S : MInst<"svstnt1w_scatter[_{2}base]_offset[_{d}]", "vPuld", "lUl", [IsScatterStore, IsByteIndexed], MemEltTyInt32, "aarch64_sve_stnt1_scatter_scalar_offset">; + +// Non-temporal scatter store one vector (scalar base, signed vector index) +def SVSTNT1_SCATTER_INDICES_S : MInst<"svstnt1_scatter_[{3}]index[_{d}]", "vPpxd", "lUld", [IsScatterStore], MemEltTyDefault, "aarch64_sve_stnt1_scatter_index">; +def SVSTNT1H_SCATTER_INDICES_SS : MInst<"svstnt1h_scatter_[{3}]index[_{d}]", "vPBxd", "l", [IsScatterStore], MemEltTyInt16, "aarch64_sve_stnt1_scatter_index">; +def SVSTNT1H_SCATTER_INDICES_SU : MInst<"svstnt1h_scatter_[{3}]index[_{d}]", "vPFxd", "Ul", [IsScatterStore], MemEltTyInt16, "aarch64_sve_stnt1_scatter_index">; +def SVSTNT1W_SCATTER_INDICES_SS : MInst<"svstnt1w_scatter_[{3}]index[_{d}]", "vPCxd", "l", [IsScatterStore], MemEltTyInt32, "aarch64_sve_stnt1_scatter_index">; +def SVSTNT1W_SCATTER_INDICES_SU : MInst<"svstnt1w_scatter_[{3}]index[_{d}]", "vPGxd", "Ul", [IsScatterStore], MemEltTyInt32, "aarch64_sve_stnt1_scatter_index">; + +// Non-temporal scatter store one vector (scalar base, unsigned vector index) +def SVSTNT1_SCATTER_INDICES_U : MInst<"svstnt1_scatter_[{3}]index[_{d}]", "vPpud", "lUld", [IsScatterStore], MemEltTyDefault, "aarch64_sve_stnt1_scatter_index">; +def SVSTNT1H_SCATTER_INDICES_US : MInst<"svstnt1h_scatter_[{3}]index[_{d}]", "vPBud", "l", [IsScatterStore], MemEltTyInt16, "aarch64_sve_stnt1_scatter_index">; +def SVSTNT1H_SCATTER_INDICES_UU : MInst<"svstnt1h_scatter_[{3}]index[_{d}]", "vPFud", "Ul", [IsScatterStore], MemEltTyInt16, "aarch64_sve_stnt1_scatter_index">; +def SVSTNT1W_SCATTER_INDICES_US : MInst<"svstnt1w_scatter_[{3}]index[_{d}]", "vPCud", "l", [IsScatterStore], MemEltTyInt32, "aarch64_sve_stnt1_scatter_index">; +def SVSTNT1W_SCATTER_INDICES_UU : MInst<"svstnt1w_scatter_[{3}]index[_{d}]", "vPGud", "Ul", [IsScatterStore], MemEltTyInt32, "aarch64_sve_stnt1_scatter_index">; + +// Non-temporal scatter store one vector (vector base, signed scalar index) +def SVSTNT1_SCATTER_INDEX_S : MInst<"svstnt1_scatter[_{2}base]_index[_{d}]", "vPuld", "ilUiUlfd", [IsScatterStore], MemEltTyDefault, "aarch64_sve_stnt1_scatter_scalar_offset">; +def SVSTNT1H_SCATTER_INDEX_S : MInst<"svstnt1h_scatter[_{2}base]_index[_{d}]", "vPuld", "ilUiUl", [IsScatterStore], MemEltTyInt16, "aarch64_sve_stnt1_scatter_scalar_offset">; +def SVSTNT1W_SCATTER_INDEX_S : MInst<"svstnt1w_scatter[_{2}base]_index[_{d}]", "vPuld", "lUl", [IsScatterStore], MemEltTyInt32, "aarch64_sve_stnt1_scatter_scalar_offset">; +} + +//////////////////////////////////////////////////////////////////////////////// +// SVE2 - Polynomial arithmetic + +let ArchGuard = "defined(__ARM_FEATURE_SVE2)" in { +def SVEORBT : SInst<"sveorbt[_{d}]", "dddd", "csilUcUsUiUl", MergeNone, "aarch64_sve_eorbt">; +def SVEORBT_N : SInst<"sveorbt[_n_{d}]", "ddda", "csilUcUsUiUl", MergeNone, "aarch64_sve_eorbt">; +def SVEORTB : SInst<"sveortb[_{d}]", "dddd", "csilUcUsUiUl", MergeNone, "aarch64_sve_eortb">; +def SVEORTB_N : SInst<"sveortb[_n_{d}]", "ddda", "csilUcUsUiUl", MergeNone, "aarch64_sve_eortb">; +def SVPMUL : SInst<"svpmul[_{d}]", "ddd", "Uc", MergeNone, "aarch64_sve_pmul">; +def SVPMUL_N : SInst<"svpmul[_n_{d}]", "dda", "Uc", MergeNone, "aarch64_sve_pmul">; +def SVPMULLB : SInst<"svpmullb[_{d}]", "dhh", "UsUl", MergeNone>; +def SVPMULLB_N : SInst<"svpmullb[_n_{d}]", "dhR", "UsUl", MergeNone>; +def SVPMULLB_PAIR : SInst<"svpmullb_pair[_{d}]", "ddd", "UcUi", MergeNone, "aarch64_sve_pmullb_pair">; +def SVPMULLB_PAIR_N : SInst<"svpmullb_pair[_n_{d}]", "dda", "UcUi", MergeNone, "aarch64_sve_pmullb_pair">; +def SVPMULLT : SInst<"svpmullt[_{d}]", "dhh", "UsUl", MergeNone>; +def SVPMULLT_N : SInst<"svpmullt[_n_{d}]", "dhR", "UsUl", MergeNone>; +def SVPMULLT_PAIR : SInst<"svpmullt_pair[_{d}]", "ddd", "UcUi", MergeNone, "aarch64_sve_pmullt_pair">; +def SVPMULLT_PAIR_N : SInst<"svpmullt_pair[_n_{d}]", "dda", "UcUi", MergeNone, "aarch64_sve_pmullt_pair">; +} + +//////////////////////////////////////////////////////////////////////////////// +// SVE2 - Complex integer dot product + +let ArchGuard = "defined(__ARM_FEATURE_SVE2)" in { +def SVCDOT : SInst<"svcdot[_{d}]", "ddqqi", "il", MergeNone, "aarch64_sve_cdot", [], [ImmCheck<3, ImmCheckComplexRotAll90>]>; +def SVCDOT_LANE : SInst<"svcdot_lane[_{d}]", "ddqqii", "il", MergeNone, "aarch64_sve_cdot_lane", [], [ImmCheck<4, ImmCheckComplexRotAll90>, + ImmCheck<3, ImmCheckLaneIndexDot, 2>]>; +} + +//////////////////////////////////////////////////////////////////////////////// +// SVE2 - Floating-point widening multiply-accumulate + +let ArchGuard = "defined(__ARM_FEATURE_SVE2)" in { +def SVMLALB_F : SInst<"svmlalb[_{d}]", "ddhh", "f", MergeNone, "aarch64_sve_fmlalb">; +def SVMLALB_F_N : SInst<"svmlalb[_n_{d}]", "ddhR", "f", MergeNone, "aarch64_sve_fmlalb">; +def SVMLALB_F_LANE : SInst<"svmlalb_lane[_{d}]", "ddhhi", "f", MergeNone, "aarch64_sve_fmlalb_lane", [], [ImmCheck<3, ImmCheckLaneIndex, 2>]>; +def SVMLALT_F : SInst<"svmlalt[_{d}]", "ddhh", "f", MergeNone, "aarch64_sve_fmlalt">; +def SVMLALT_F_N : SInst<"svmlalt[_n_{d}]", "ddhR", "f", MergeNone, "aarch64_sve_fmlalt">; +def SVMLALT_F_LANE : SInst<"svmlalt_lane[_{d}]", "ddhhi", "f", MergeNone, "aarch64_sve_fmlalt_lane", [], [ImmCheck<3, ImmCheckLaneIndex, 2>]>; +def SVMLSLB_F : SInst<"svmlslb[_{d}]", "ddhh", "f", MergeNone, "aarch64_sve_fmlslb">; +def SVMLSLB_F_N : SInst<"svmlslb[_n_{d}]", "ddhR", "f", MergeNone, "aarch64_sve_fmlslb">; +def SVMLSLB_F_LANE : SInst<"svmlslb_lane[_{d}]", "ddhhi", "f", MergeNone, "aarch64_sve_fmlslb_lane", [], [ImmCheck<3, ImmCheckLaneIndex, 2>]>; +def SVMLSLT_F : SInst<"svmlslt[_{d}]", "ddhh", "f", MergeNone, "aarch64_sve_fmlslt">; +def SVMLSLT_F_N : SInst<"svmlslt[_n_{d}]", "ddhR", "f", MergeNone, "aarch64_sve_fmlslt">; +def SVMLSLT_F_LANE : SInst<"svmlslt_lane[_{d}]", "ddhhi", "f", MergeNone, "aarch64_sve_fmlslt_lane", [], [ImmCheck<3, ImmCheckLaneIndex, 2>]>; +} + +//////////////////////////////////////////////////////////////////////////////// +// SVE2 - Floating-point integer binary logarithm + +let ArchGuard = "defined(__ARM_FEATURE_SVE2)" in { +def SVLOGB_M : SInst<"svlogb[_{d}]", "xxPd", "hfd", MergeOp1, "aarch64_sve_flogb">; +def SVLOGB_X : SInst<"svlogb[_{d}]", "xPd", "hfd", MergeAnyExp, "aarch64_sve_flogb">; +def SVLOGB_Z : SInst<"svlogb[_{d}]", "xPd", "hfd", MergeZeroExp, "aarch64_sve_flogb">; +} + +//////////////////////////////////////////////////////////////////////////////// +// SVE2 - Vector Histogram count + +let ArchGuard = "defined(__ARM_FEATURE_SVE2)" in { +def SVHISTCNT : SInst<"svhistcnt[_{d}]_z", "uPdd", "ilUiUl", MergeNone, "aarch64_sve_histcnt">; +def SVHISTSEG : SInst<"svhistseg[_{d}]", "udd", "cUc", MergeNone, "aarch64_sve_histseg">; +} + +//////////////////////////////////////////////////////////////////////////////// +// SVE2 - Character match + +let ArchGuard = "defined(__ARM_FEATURE_SVE2)" in { +def SVMATCH : SInst<"svmatch[_{d}]", "PPdd", "csUcUs", MergeNone, "aarch64_sve_match">; +def SVNMATCH : SInst<"svnmatch[_{d}]", "PPdd", "csUcUs", MergeNone, "aarch64_sve_nmatch">; +} + +//////////////////////////////////////////////////////////////////////////////// +// SVE2 - Contiguous conflict detection +let ArchGuard = "defined(__ARM_FEATURE_SVE2)" in { +def SVWHILERW_B : SInst<"svwhilerw[_{1}]", "Pcc", "cUc", MergeNone, "aarch64_sve_whilerw_b", [IsOverloadWhileRW]>; +def SVWHILERW_H : SInst<"svwhilerw[_{1}]", "Pcc", "sUsh", MergeNone, "aarch64_sve_whilerw_h", [IsOverloadWhileRW]>; +def SVWHILERW_S : SInst<"svwhilerw[_{1}]", "Pcc", "iUif", MergeNone, "aarch64_sve_whilerw_s", [IsOverloadWhileRW]>; +def SVWHILERW_D : SInst<"svwhilerw[_{1}]", "Pcc", "lUld", MergeNone, "aarch64_sve_whilerw_d", [IsOverloadWhileRW]>; + +def SVWHILEWR_B : SInst<"svwhilewr[_{1}]", "Pcc", "cUc", MergeNone, "aarch64_sve_whilewr_b", [IsOverloadWhileRW]>; +def SVWHILEWR_H : SInst<"svwhilewr[_{1}]", "Pcc", "sUsh", MergeNone, "aarch64_sve_whilewr_h", [IsOverloadWhileRW]>; +def SVWHILEWR_S : SInst<"svwhilewr[_{1}]", "Pcc", "iUif", MergeNone, "aarch64_sve_whilewr_s", [IsOverloadWhileRW]>; +def SVWHILEWR_D : SInst<"svwhilewr[_{1}]", "Pcc", "lUld", MergeNone, "aarch64_sve_whilewr_d", [IsOverloadWhileRW]>; +} + +let ArchGuard = "defined(__ARM_FEATURE_SVE2) && defined(__ARM_FEATURE_BF16_SCALAR_ARITHMETIC)" in { +def SVWHILERW_H_BF16 : SInst<"svwhilerw[_{1}]", "Pcc", "b", MergeNone, "aarch64_sve_whilerw_h", [IsOverloadWhileRW]>; +def SVWHILEWR_H_BF16 : SInst<"svwhilewr[_{1}]", "Pcc", "b", MergeNone, "aarch64_sve_whilewr_h", [IsOverloadWhileRW]>; +} + +//////////////////////////////////////////////////////////////////////////////// +// SVE2 - Extended table lookup/permute +let ArchGuard = "defined(__ARM_FEATURE_SVE2)" in { +def SVTBL2 : SInst<"svtbl2[_{d}]", "d2u", "csilUcUsUiUlhfd", MergeNone>; +def SVTBX : SInst<"svtbx[_{d}]", "dddu", "csilUcUsUiUlhfd", MergeNone, "aarch64_sve_tbx">; +} + +let ArchGuard = "defined(__ARM_FEATURE_SVE2) && defined(__ARM_FEATURE_SVE_BF16)" in { +def SVTBL2_BF16 : SInst<"svtbl2[_{d}]", "d2u", "b", MergeNone>; +def SVTBX_BF16 : SInst<"svtbx[_{d}]", "dddu", "b", MergeNone, "aarch64_sve_tbx">; +} + +//////////////////////////////////////////////////////////////////////////////// +// SVE2 - Optional + +let ArchGuard = "defined(__ARM_FEATURE_SVE2_AES)" in { +def SVAESD : SInst<"svaesd[_{d}]", "ddd", "Uc", MergeNone, "aarch64_sve_aesd", [IsOverloadNone]>; +def SVAESIMC : SInst<"svaesimc[_{d}]", "dd", "Uc", MergeNone, "aarch64_sve_aesimc", [IsOverloadNone]>; +def SVAESE : SInst<"svaese[_{d}]", "ddd", "Uc", MergeNone, "aarch64_sve_aese", [IsOverloadNone]>; +def SVAESMC : SInst<"svaesmc[_{d}]", "dd", "Uc", MergeNone, "aarch64_sve_aesmc", [IsOverloadNone]>; + +def SVPMULLB_PAIR_U64 : SInst<"svpmullb_pair[_{d}]", "ddd", "Ul", MergeNone, "aarch64_sve_pmullb_pair">; +def SVPMULLB_PAIR_N_U64 : SInst<"svpmullb_pair[_n_{d}]", "dda", "Ul", MergeNone, "aarch64_sve_pmullb_pair">; + +def SVPMULLT_PAIR_U64 : SInst<"svpmullt_pair[_{d}]", "ddd", "Ul", MergeNone, "aarch64_sve_pmullt_pair">; +def SVPMULLT_PAIR_N_U64 : SInst<"svpmullt_pair[_n_{d}]", "dda", "Ul", MergeNone, "aarch64_sve_pmullt_pair">; +} + +let ArchGuard = "defined(__ARM_FEATURE_SVE2_SHA3)" in { +def SVRAX1 : SInst<"svrax1[_{d}]", "ddd", "lUl", MergeNone, "aarch64_sve_rax1", [IsOverloadNone]>; +} + +let ArchGuard = "defined(__ARM_FEATURE_SVE2_SM4)" in { +def SVSM4E : SInst<"svsm4e[_{d}]", "ddd", "Ui", MergeNone, "aarch64_sve_sm4e", [IsOverloadNone]>; +def SVSM4EKEY : SInst<"svsm4ekey[_{d}]", "ddd", "Ui", MergeNone, "aarch64_sve_sm4ekey", [IsOverloadNone]>; +} + +let ArchGuard = "__ARM_FEATURE_SVE2_BITPERM" in { +def SVBDEP : SInst<"svbdep[_{d}]", "ddd", "UcUsUiUl", MergeNone, "aarch64_sve_bdep_x">; +def SVBDEP_N : SInst<"svbdep[_n_{d}]", "dda", "UcUsUiUl", MergeNone, "aarch64_sve_bdep_x">; +def SVBEXT : SInst<"svbext[_{d}]", "ddd", "UcUsUiUl", MergeNone, "aarch64_sve_bext_x">; +def SVBEXT_N : SInst<"svbext[_n_{d}]", "dda", "UcUsUiUl", MergeNone, "aarch64_sve_bext_x">; +def SVBGRP : SInst<"svbgrp[_{d}]", "ddd", "UcUsUiUl", MergeNone, "aarch64_sve_bgrp_x">; +def SVBGRP_N : SInst<"svbgrp[_n_{d}]", "dda", "UcUsUiUl", MergeNone, "aarch64_sve_bgrp_x">; +} diff --git a/clang/include/clang/CodeGen/CGFunctionInfo.h b/clang/include/clang/CodeGen/CGFunctionInfo.h index 2a41ab9eece7..eaf5a3d5aad7 100644 --- a/clang/include/clang/CodeGen/CGFunctionInfo.h +++ b/clang/include/clang/CodeGen/CGFunctionInfo.h @@ -88,6 +88,7 @@ private: Kind TheKind; bool PaddingInReg : 1; bool InAllocaSRet : 1; // isInAlloca() + bool InAllocaIndirect : 1;// isInAlloca() bool IndirectByVal : 1; // isIndirect() bool IndirectRealign : 1; // isIndirect() bool SRetAfterThis : 1; // isIndirect() @@ -110,8 +111,8 @@ private: public: ABIArgInfo(Kind K = Direct) - : TypeData(nullptr), PaddingType(nullptr), DirectOffset(0), - TheKind(K), PaddingInReg(false), InAllocaSRet(false), + : TypeData(nullptr), PaddingType(nullptr), DirectOffset(0), TheKind(K), + PaddingInReg(false), InAllocaSRet(false), InAllocaIndirect(false), IndirectByVal(false), IndirectRealign(false), SRetAfterThis(false), InReg(false), CanBeFlattened(false), SignExt(false) {} @@ -185,9 +186,10 @@ public: AI.setInReg(true); return AI; } - static ABIArgInfo getInAlloca(unsigned FieldIndex) { + static ABIArgInfo getInAlloca(unsigned FieldIndex, bool Indirect = false) { auto AI = ABIArgInfo(InAlloca); AI.setInAllocaFieldIndex(FieldIndex); + AI.setInAllocaIndirect(Indirect); return AI; } static ABIArgInfo getExpand() { @@ -380,6 +382,15 @@ public: AllocaFieldIndex = FieldIndex; } + unsigned getInAllocaIndirect() const { + assert(isInAlloca() && "Invalid kind!"); + return InAllocaIndirect; + } + void setInAllocaIndirect(bool Indirect) { + assert(isInAlloca() && "Invalid kind!"); + InAllocaIndirect = Indirect; + } + /// Return true if this field of an inalloca struct should be returned /// to implement a struct return calling convention. bool getInAllocaSRet() const { @@ -497,6 +508,9 @@ class CGFunctionInfo final /// Whether this is a chain call. unsigned ChainCall : 1; + /// Whether this function is a CMSE nonsecure call + unsigned CmseNSCall : 1; + /// Whether this function is noreturn. unsigned NoReturn : 1; @@ -587,6 +601,8 @@ public: bool isChainCall() const { return ChainCall; } + bool isCmseNSCall() const { return CmseNSCall; } + bool isNoReturn() const { return NoReturn; } /// In ARC, whether this function retains its return value. This @@ -624,7 +640,8 @@ public: FunctionType::ExtInfo getExtInfo() const { return FunctionType::ExtInfo(isNoReturn(), getHasRegParm(), getRegParm(), getASTCallingConvention(), isReturnsRetained(), - isNoCallerSavedRegs(), isNoCfCheck()); + isNoCallerSavedRegs(), isNoCfCheck(), + isCmseNSCall()); } CanQualType getReturnType() const { return getArgsBuffer()[0].type; } @@ -665,6 +682,7 @@ public: ID.AddBoolean(HasRegParm); ID.AddInteger(RegParm); ID.AddBoolean(NoCfCheck); + ID.AddBoolean(CmseNSCall); ID.AddInteger(Required.getOpaqueData()); ID.AddBoolean(HasExtParameterInfos); if (HasExtParameterInfos) { @@ -692,6 +710,7 @@ public: ID.AddBoolean(info.getHasRegParm()); ID.AddInteger(info.getRegParm()); ID.AddBoolean(info.getNoCfCheck()); + ID.AddBoolean(info.getCmseNSCall()); ID.AddInteger(required.getOpaqueData()); ID.AddBoolean(!paramInfos.empty()); if (!paramInfos.empty()) { diff --git a/clang/include/clang/CodeGen/CodeGenABITypes.h b/clang/include/clang/CodeGen/CodeGenABITypes.h index 31f0cea57232..3c745fadbe78 100644 --- a/clang/include/clang/CodeGen/CodeGenABITypes.h +++ b/clang/include/clang/CodeGen/CodeGenABITypes.h @@ -25,18 +25,24 @@ #include "clang/AST/CanonicalType.h" #include "clang/AST/Type.h" +#include "clang/Basic/ABI.h" #include "clang/CodeGen/CGFunctionInfo.h" +#include "llvm/IR/BasicBlock.h" namespace llvm { - class DataLayout; - class Module; - class Function; - class FunctionType; - class Type; +class AttrBuilder; +class Constant; +class DataLayout; +class Module; +class Function; +class FunctionType; +class Type; } namespace clang { class ASTContext; +class CXXConstructorDecl; +class CXXDestructorDecl; class CXXRecordDecl; class CXXMethodDecl; class CodeGenOptions; @@ -44,12 +50,23 @@ class CoverageSourceInfo; class DiagnosticsEngine; class HeaderSearchOptions; class ObjCMethodDecl; +class ObjCProtocolDecl; class PreprocessorOptions; namespace CodeGen { class CGFunctionInfo; class CodeGenModule; +/// Additional implicit arguments to add to a constructor argument list. +struct ImplicitCXXConstructorArgs { + /// Implicit arguments to add before the explicit arguments, but after the + /// `*this` argument (which always comes first). + SmallVector<llvm::Value *, 1> Prefix; + + /// Implicit arguments to add after the explicit arguments. + SmallVector<llvm::Value *, 1> Suffix; +}; + const CGFunctionInfo &arrangeObjCMessageSendSignature(CodeGenModule &CGM, const ObjCMethodDecl *MD, QualType receiverType); @@ -71,6 +88,17 @@ const CGFunctionInfo &arrangeFreeFunctionCall(CodeGenModule &CGM, FunctionType::ExtInfo info, RequiredArgs args); +/// Returns the implicit arguments to add to a complete, non-delegating C++ +/// constructor call. +ImplicitCXXConstructorArgs +getImplicitCXXConstructorArgs(CodeGenModule &CGM, const CXXConstructorDecl *D); + +llvm::Value * +getCXXDestructorImplicitParam(CodeGenModule &CGM, llvm::BasicBlock *InsertBlock, + llvm::BasicBlock::iterator InsertPoint, + const CXXDestructorDecl *D, CXXDtorType Type, + bool ForVirtualBase, bool Delegating); + /// Returns null if the function type is incomplete and can't be lowered. llvm::FunctionType *convertFreeFunctionType(CodeGenModule &CGM, const FunctionDecl *FD); @@ -84,6 +112,25 @@ llvm::Type *convertTypeForMemory(CodeGenModule &CGM, QualType T); unsigned getLLVMFieldNumber(CodeGenModule &CGM, const RecordDecl *RD, const FieldDecl *FD); +/// Given the language and code-generation options that Clang was configured +/// with, set the default LLVM IR attributes for a function definition. +/// The attributes set here are mostly global target-configuration and +/// pipeline-configuration options like the target CPU, variant stack +/// rules, whether to optimize for size, and so on. This is useful for +/// frontends (such as Swift) that generally intend to interoperate with +/// C code and rely on Clang's target configuration logic. +/// +/// As a general rule, this function assumes that meaningful attributes +/// haven't already been added to the builder. It won't intentionally +/// displace any existing attributes, but it also won't check to avoid +/// overwriting them. Callers should generally apply customizations after +/// making this call. +/// +/// This function assumes that the caller is not defining a function that +/// requires special no-builtin treatment. +void addDefaultFunctionDefinitionAttributes(CodeGenModule &CGM, + llvm::AttrBuilder &attrs); + /// Returns the default constructor for a C struct with non-trivially copyable /// fields, generating it if necessary. The returned function uses the `cdecl` /// calling convention, returns void, and takes a single argument that is a @@ -137,6 +184,13 @@ llvm::Function *getNonTrivialCStructDestructor(CodeGenModule &CGM, CharUnits DstAlignment, bool IsVolatile, QualType QT); +/// Get a pointer to a protocol object for the given declaration, emitting it if +/// it hasn't already been emitted in this translation unit. Note that the ABI +/// for emitting a protocol reference in code (e.g. for a protocol expression) +/// in most runtimes is not as simple as just materializing a pointer to this +/// object. +llvm::Constant *emitObjCProtocolObject(CodeGenModule &CGM, + const ObjCProtocolDecl *p); } // end namespace CodeGen } // end namespace clang diff --git a/clang/include/clang/CodeGen/ConstantInitBuilder.h b/clang/include/clang/CodeGen/ConstantInitBuilder.h index fd07e91ba6ae..88e357a0c29c 100644 --- a/clang/include/clang/CodeGen/ConstantInitBuilder.h +++ b/clang/include/clang/CodeGen/ConstantInitBuilder.h @@ -226,6 +226,13 @@ public: add(getRelativeOffset(type, target)); } + /// Same as addRelativeOffset(), but instead relative to an element in this + /// aggregate, identified by its index. + void addRelativeOffsetToPosition(llvm::IntegerType *type, + llvm::Constant *target, size_t position) { + add(getRelativeOffsetToPosition(type, target, position)); + } + /// Add a relative offset to the target address, plus a small /// constant offset. This is primarily useful when the relative /// offset is known to be a multiple of (say) four and therefore @@ -298,10 +305,18 @@ public: /// position to be filled. This is computed with an indexed /// getelementptr rather than by computing offsets. /// - /// The returned pointer will have type T*, where T is the given - /// position. + /// The returned pointer will have type T*, where T is the given type. This + /// type can differ from the type of the actual element. llvm::Constant *getAddrOfCurrentPosition(llvm::Type *type); + /// Produce an address which points to a position in the aggregate being + /// constructed. This is computed with an indexed getelementptr rather than by + /// computing offsets. + /// + /// The returned pointer will have type T*, where T is the given type. This + /// type can differ from the type of the actual element. + llvm::Constant *getAddrOfPosition(llvm::Type *type, size_t position); + llvm::ArrayRef<llvm::Constant*> getGEPIndicesToCurrentPosition( llvm::SmallVectorImpl<llvm::Constant*> &indices) { getGEPIndicesTo(indices, Builder.Buffer.size()); @@ -319,6 +334,10 @@ private: llvm::Constant *getRelativeOffset(llvm::IntegerType *offsetType, llvm::Constant *target); + llvm::Constant *getRelativeOffsetToPosition(llvm::IntegerType *offsetType, + llvm::Constant *target, + size_t position); + CharUnits getOffsetFromGlobalTo(size_t index) const; }; diff --git a/clang/include/clang/CodeGen/ConstantInitFuture.h b/clang/include/clang/CodeGen/ConstantInitFuture.h index b08f52872290..452ba36d2087 100644 --- a/clang/include/clang/CodeGen/ConstantInitFuture.h +++ b/clang/include/clang/CodeGen/ConstantInitFuture.h @@ -35,7 +35,7 @@ struct PointerLikeTypeTraits< ::clang::CodeGen::ConstantInitBuilderBase*> { static inline void *getAsVoidPointer(T p) { return p; } static inline T getFromVoidPointer(void *p) {return static_cast<T>(p);} - enum { NumLowBitsAvailable = 2 }; + static constexpr int NumLowBitsAvailable = 2; }; } @@ -79,10 +79,8 @@ public: result.Data = PairTy::getFromOpaqueValue(value); return result; } - enum { - NumLowBitsAvailable = - llvm::PointerLikeTypeTraits<PairTy>::NumLowBitsAvailable - }; + static constexpr int NumLowBitsAvailable = + llvm::PointerLikeTypeTraits<PairTy>::NumLowBitsAvailable; }; } // end namespace CodeGen @@ -100,7 +98,7 @@ struct PointerLikeTypeTraits< ::clang::CodeGen::ConstantInitFuture> { static inline T getFromVoidPointer(void *p) { return T::getFromOpaqueValue(p); } - enum { NumLowBitsAvailable = T::NumLowBitsAvailable }; + static constexpr int NumLowBitsAvailable = T::NumLowBitsAvailable; }; } // end namespace llvm diff --git a/clang/include/clang/CrossTU/CrossTranslationUnit.h b/clang/include/clang/CrossTU/CrossTranslationUnit.h index 4d2b7109c62a..027c6f16430b 100644 --- a/clang/include/clang/CrossTU/CrossTranslationUnit.h +++ b/clang/include/clang/CrossTU/CrossTranslationUnit.h @@ -21,6 +21,7 @@ #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/StringMap.h" #include "llvm/Support/Error.h" +#include "llvm/Support/Path.h" namespace clang { class CompilerInstance; @@ -47,7 +48,12 @@ enum class index_error_code { triple_mismatch, lang_mismatch, lang_dialect_mismatch, - load_threshold_reached + load_threshold_reached, + invocation_list_ambiguous, + invocation_list_file_not_found, + invocation_list_empty, + invocation_list_wrong_format, + invocation_list_lookup_unsuccessful }; class IndexError : public llvm::ErrorInfo<IndexError> { @@ -78,7 +84,8 @@ private: }; /// This function parses an index file that determines which -/// translation unit contains which definition. +/// translation unit contains which definition. The IndexPath is not prefixed +/// with CTUDir, so an absolute path is expected for consistent results. /// /// The index file format is the following: /// each line consists of an USR and a filepath separated by a space. @@ -86,17 +93,27 @@ private: /// \return Returns a map where the USR is the key and the filepath is the value /// or an error. llvm::Expected<llvm::StringMap<std::string>> -parseCrossTUIndex(StringRef IndexPath, StringRef CrossTUDir); +parseCrossTUIndex(StringRef IndexPath); std::string createCrossTUIndexString(const llvm::StringMap<std::string> &Index); +using InvocationListTy = llvm::StringMap<llvm::SmallVector<std::string, 32>>; +/// Parse the YAML formatted invocation list file content \p FileContent. +/// The format is expected to be a mapping from from absolute source file +/// paths in the filesystem to a list of command-line parts, which +/// constitute the invocation needed to compile that file. That invocation +/// will be used to produce the AST of the TU. +llvm::Expected<InvocationListTy> parseInvocationList( + StringRef FileContent, + llvm::sys::path::Style PathStyle = llvm::sys::path::Style::posix); + // Returns true if the variable or any field of a record variable is const. bool containsConst(const VarDecl *VD, const ASTContext &ACtx); /// This class is used for tools that requires cross translation /// unit capability. /// -/// This class can load definitions from external AST files. +/// This class can load definitions from external AST sources. /// The loaded definition will be merged back to the original AST using the /// AST Importer. /// In order to use this class, an index file is required that describes @@ -116,7 +133,7 @@ public: /// the current translation unit. A function definition with the same /// declaration will be looked up in the index file which should be in the /// \p CrossTUDir directory, called \p IndexName. In case the declaration is - /// found in the index the corresponding AST file will be loaded and the + /// found in the index the corresponding AST will be loaded and the /// definition will be merged into the original AST using the AST Importer. /// /// \return The declaration with the definition will be returned. @@ -136,7 +153,7 @@ public: /// A definition with the same declaration will be looked up in the /// index file which should be in the \p CrossTUDir directory, called /// \p IndexName. In case the declaration is found in the index the - /// corresponding AST file will be loaded. If the number of TUs imported + /// corresponding AST will be loaded. If the number of TUs imported /// reaches \p CTULoadTreshold, no loading is performed. /// /// \return Returns a pointer to the ASTUnit that contains the definition of @@ -209,14 +226,43 @@ private: /// imported the FileID. ImportedFileIDMap ImportedFileIDs; - /// Functor for loading ASTUnits from AST-dump files. - class ASTFileLoader { + using LoadResultTy = llvm::Expected<std::unique_ptr<ASTUnit>>; + + /// Loads ASTUnits from AST-dumps or source-files. + class ASTLoader { public: - ASTFileLoader(const CompilerInstance &CI); - std::unique_ptr<ASTUnit> operator()(StringRef ASTFilePath); + ASTLoader(CompilerInstance &CI, StringRef CTUDir, + StringRef InvocationListFilePath); + + /// Load the ASTUnit by its identifier found in the index file. If the + /// indentifier is suffixed with '.ast' it is considered a dump. Otherwise + /// it is treated as source-file, and on-demand parsed. Relative paths are + /// prefixed with CTUDir. + LoadResultTy load(StringRef Identifier); + + /// Lazily initialize the invocation list information, which is needed for + /// on-demand parsing. + llvm::Error lazyInitInvocationList(); private: - const CompilerInstance &CI; + /// The style used for storage and lookup of filesystem paths. + /// Defaults to posix. + const llvm::sys::path::Style PathStyle = llvm::sys::path::Style::posix; + + /// Loads an AST from a pch-dump. + LoadResultTy loadFromDump(StringRef Identifier); + /// Loads an AST from a source-file. + LoadResultTy loadFromSource(StringRef Identifier); + + CompilerInstance &CI; + StringRef CTUDir; + /// The path to the file containing the invocation list, which is in YAML + /// format, and contains a mapping from source files to compiler invocations + /// that produce the AST used for analysis. + StringRef InvocationListFilePath; + /// In case of on-demand parsing, the invocations for parsing the source + /// files is stored. + llvm::Optional<InvocationListTy> InvocationList; }; /// Maintain number of AST loads and check for reaching the load limit. @@ -242,7 +288,7 @@ private: /// are the concerns of ASTUnitStorage class. class ASTUnitStorage { public: - ASTUnitStorage(const CompilerInstance &CI); + ASTUnitStorage(CompilerInstance &CI); /// Loads an ASTUnit for a function. /// /// \param FunctionName USR name of the function. @@ -287,18 +333,17 @@ private: using IndexMapTy = BaseMapTy<std::string>; IndexMapTy NameFileMap; - ASTFileLoader FileAccessor; + /// Loads the AST based on the identifier found in the index. + ASTLoader Loader; - /// Limit the number of loaded ASTs. Used to limit the memory usage of the - /// CrossTranslationUnitContext. - /// The ASTUnitStorage has the knowledge about if the AST to load is - /// actually loaded or returned from cache. This information is needed to - /// maintain the counter. + /// Limit the number of loaded ASTs. It is used to limit the memory usage + /// of the CrossTranslationUnitContext. The ASTUnitStorage has the + /// information whether the AST to load is actually loaded or returned from + /// cache. This information is needed to maintain the counter. ASTLoadGuard LoadGuard; }; ASTUnitStorage ASTStorage; - }; } // namespace cross_tu diff --git a/clang/include/clang/Driver/Action.h b/clang/include/clang/Driver/Action.h index 8ccbb6c2bbfa..27c95c6f89d4 100644 --- a/clang/include/clang/Driver/Action.h +++ b/clang/include/clang/Driver/Action.h @@ -73,9 +73,10 @@ public: OffloadBundlingJobClass, OffloadUnbundlingJobClass, OffloadWrapperJobClass, + StaticLibJobClass, JobClassFirst = PreprocessJobClass, - JobClassLast = OffloadWrapperJobClass + JobClassLast = StaticLibJobClass }; // The offloading kind determines if this action is binded to a particular @@ -637,6 +638,17 @@ public: } }; +class StaticLibJobAction : public JobAction { + void anchor() override; + +public: + StaticLibJobAction(ActionList &Inputs, types::ID Type); + + static bool classof(const Action *A) { + return A->getKind() == StaticLibJobClass; + } +}; + } // namespace driver } // namespace clang diff --git a/clang/include/clang/Driver/CC1Options.td b/clang/include/clang/Driver/CC1Options.td deleted file mode 100644 index 1d550eb15ea8..000000000000 --- a/clang/include/clang/Driver/CC1Options.td +++ /dev/null @@ -1,923 +0,0 @@ -//===--- CC1Options.td - Options for clang -cc1 ---------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// This file defines the options accepted by clang -cc1 and clang -cc1as. -// -//===----------------------------------------------------------------------===// - -let Flags = [CC1Option, NoDriverOption] in { - -//===----------------------------------------------------------------------===// -// Target Options -//===----------------------------------------------------------------------===// - -let Flags = [CC1Option, CC1AsOption, NoDriverOption] in { - -def target_cpu : Separate<["-"], "target-cpu">, - HelpText<"Target a specific cpu type">; -def target_feature : Separate<["-"], "target-feature">, - HelpText<"Target specific attributes">; -def triple : Separate<["-"], "triple">, - HelpText<"Specify target triple (e.g. i686-apple-darwin9)">; -def target_abi : Separate<["-"], "target-abi">, - HelpText<"Target a particular ABI type">; -def target_sdk_version_EQ : Joined<["-"], "target-sdk-version=">, - HelpText<"The version of target SDK used for compilation">; - -} - -def target_linker_version : Separate<["-"], "target-linker-version">, - HelpText<"Target linker version">; -def triple_EQ : Joined<["-"], "triple=">, Alias<triple>; -def mfpmath : Separate<["-"], "mfpmath">, - HelpText<"Which unit to use for fp math">; - -def fpadding_on_unsigned_fixed_point : Flag<["-"], "fpadding-on-unsigned-fixed-point">, - HelpText<"Force each unsigned fixed point type to have an extra bit of padding to align their scales with those of signed fixed point types">; -def fno_padding_on_unsigned_fixed_point : Flag<["-"], "fno-padding-on-unsigned-fixed-point">; - -//===----------------------------------------------------------------------===// -// Analyzer Options -//===----------------------------------------------------------------------===// - -def analysis_UnoptimizedCFG : Flag<["-"], "unoptimized-cfg">, - HelpText<"Generate unoptimized CFGs for all analyses">; -def analysis_CFGAddImplicitDtors : Flag<["-"], "cfg-add-implicit-dtors">, - HelpText<"Add C++ implicit destructors to CFGs for all analyses">; - -def analyzer_store : Separate<["-"], "analyzer-store">, - HelpText<"Source Code Analysis - Abstract Memory Store Models">; -def analyzer_store_EQ : Joined<["-"], "analyzer-store=">, Alias<analyzer_store>; - -def analyzer_constraints : Separate<["-"], "analyzer-constraints">, - HelpText<"Source Code Analysis - Symbolic Constraint Engines">; -def analyzer_constraints_EQ : Joined<["-"], "analyzer-constraints=">, - Alias<analyzer_constraints>; - -def analyzer_output : Separate<["-"], "analyzer-output">, - HelpText<"Source Code Analysis - Output Options">; -def analyzer_output_EQ : Joined<["-"], "analyzer-output=">, - Alias<analyzer_output>; - -def analyzer_purge : Separate<["-"], "analyzer-purge">, - HelpText<"Source Code Analysis - Dead Symbol Removal Frequency">; -def analyzer_purge_EQ : Joined<["-"], "analyzer-purge=">, Alias<analyzer_purge>; - -def analyzer_opt_analyze_headers : Flag<["-"], "analyzer-opt-analyze-headers">, - HelpText<"Force the static analyzer to analyze functions defined in header files">; -def analyzer_opt_analyze_nested_blocks : Flag<["-"], "analyzer-opt-analyze-nested-blocks">, - HelpText<"Analyze the definitions of blocks in addition to functions">; -def analyzer_display_progress : Flag<["-"], "analyzer-display-progress">, - HelpText<"Emit verbose output about the analyzer's progress">; -def analyze_function : Separate<["-"], "analyze-function">, - HelpText<"Run analysis on specific function (for C++ include parameters in name)">; -def analyze_function_EQ : Joined<["-"], "analyze-function=">, Alias<analyze_function>; -def trim_egraph : Flag<["-"], "trim-egraph">, - HelpText<"Only show error-related paths in the analysis graph">; -def analyzer_viz_egraph_graphviz : Flag<["-"], "analyzer-viz-egraph-graphviz">, - HelpText<"Display exploded graph using GraphViz">; -def analyzer_dump_egraph : Separate<["-"], "analyzer-dump-egraph">, - HelpText<"Dump exploded graph to the specified file">; -def analyzer_dump_egraph_EQ : Joined<["-"], "analyzer-dump-egraph=">, Alias<analyzer_dump_egraph>; - -def analyzer_inline_max_stack_depth : Separate<["-"], "analyzer-inline-max-stack-depth">, - HelpText<"Bound on stack depth while inlining (4 by default)">; -def analyzer_inline_max_stack_depth_EQ : Joined<["-"], "analyzer-inline-max-stack-depth=">, - Alias<analyzer_inline_max_stack_depth>; - -def analyzer_inlining_mode : Separate<["-"], "analyzer-inlining-mode">, - HelpText<"Specify the function selection heuristic used during inlining">; -def analyzer_inlining_mode_EQ : Joined<["-"], "analyzer-inlining-mode=">, Alias<analyzer_inlining_mode>; - -def analyzer_disable_retry_exhausted : Flag<["-"], "analyzer-disable-retry-exhausted">, - HelpText<"Do not re-analyze paths leading to exhausted nodes with a different strategy (may decrease code coverage)">; - -def analyzer_max_loop : Separate<["-"], "analyzer-max-loop">, - HelpText<"The maximum number of times the analyzer will go through a loop">; -def analyzer_stats : Flag<["-"], "analyzer-stats">, - HelpText<"Print internal analyzer statistics.">; - -def analyzer_checker : Separate<["-"], "analyzer-checker">, - HelpText<"Choose analyzer checkers to enable">, - ValuesCode<[{ - const char *Values = - #define GET_CHECKERS - #define CHECKER(FULLNAME, CLASS, HT, DOC_URI, IS_HIDDEN) FULLNAME "," - #include "clang/StaticAnalyzer/Checkers/Checkers.inc" - #undef GET_CHECKERS - #define GET_PACKAGES - #define PACKAGE(FULLNAME) FULLNAME "," - #include "clang/StaticAnalyzer/Checkers/Checkers.inc" - #undef GET_PACKAGES - ; - }]>; -def analyzer_checker_EQ : Joined<["-"], "analyzer-checker=">, - Alias<analyzer_checker>; - -def analyzer_disable_checker : Separate<["-"], "analyzer-disable-checker">, - HelpText<"Choose analyzer checkers to disable">; -def analyzer_disable_checker_EQ : Joined<["-"], "analyzer-disable-checker=">, - Alias<analyzer_disable_checker>; - -def analyzer_disable_all_checks : Flag<["-"], "analyzer-disable-all-checks">, - HelpText<"Disable all static analyzer checks">; - -def analyzer_checker_help : Flag<["-"], "analyzer-checker-help">, - HelpText<"Display the list of analyzer checkers that are available">; - -def analyzer_checker_help_alpha : Flag<["-"], "analyzer-checker-help-alpha">, - HelpText<"Display the list of in development analyzer checkers. These " - "are NOT considered safe, they are unstable and will emit incorrect " - "reports. Enable ONLY FOR DEVELOPMENT purposes">; - -def analyzer_checker_help_developer : Flag<["-"], "analyzer-checker-help-developer">, - HelpText<"Display the list of developer-only checkers such as modeling " - "and debug checkers">; - -def analyzer_config_help : Flag<["-"], "analyzer-config-help">, - HelpText<"Display the list of -analyzer-config options. These are meant for " - "development purposes only!">; - -def analyzer_list_enabled_checkers : Flag<["-"], "analyzer-list-enabled-checkers">, - HelpText<"Display the list of enabled analyzer checkers">; - -def analyzer_config : Separate<["-"], "analyzer-config">, - HelpText<"Choose analyzer options to enable">; - -def analyzer_checker_option_help : Flag<["-"], "analyzer-checker-option-help">, - HelpText<"Display the list of checker and package options">; - -def analyzer_checker_option_help_alpha : Flag<["-"], "analyzer-checker-option-help-alpha">, - HelpText<"Display the list of in development checker and package options. " - "These are NOT considered safe, they are unstable and will emit " - "incorrect reports. Enable ONLY FOR DEVELOPMENT purposes">; - -def analyzer_checker_option_help_developer : Flag<["-"], "analyzer-checker-option-help-developer">, - HelpText<"Display the list of checker and package options meant for " - "development purposes only">; - -def analyzer_config_compatibility_mode : Separate<["-"], "analyzer-config-compatibility-mode">, - HelpText<"Don't emit errors on invalid analyzer-config inputs">; - -def analyzer_config_compatibility_mode_EQ : Joined<["-"], "analyzer-config-compatibility-mode=">, - Alias<analyzer_config_compatibility_mode>; - -def analyzer_werror : Flag<["-"], "analyzer-werror">, - HelpText<"Emit analyzer results as errors rather than warnings">; - -//===----------------------------------------------------------------------===// -// Migrator Options -//===----------------------------------------------------------------------===// -def migrator_no_nsalloc_error : Flag<["-"], "no-ns-alloc-error">, - HelpText<"Do not error on use of NSAllocateCollectable/NSReallocateCollectable">; - -def migrator_no_finalize_removal : Flag<["-"], "no-finalize-removal">, - HelpText<"Do not remove finalize method in gc mode">; - -//===----------------------------------------------------------------------===// -// CodeGen Options -//===----------------------------------------------------------------------===// - -let Flags = [CC1Option, CC1AsOption, NoDriverOption] in { -def debug_info_kind_EQ : Joined<["-"], "debug-info-kind=">; -def debug_info_macro : Flag<["-"], "debug-info-macro">, - HelpText<"Emit macro debug information">; -def default_function_attr : Separate<["-"], "default-function-attr">, - HelpText<"Apply given attribute to all functions">; -def dwarf_version_EQ : Joined<["-"], "dwarf-version=">; -def debugger_tuning_EQ : Joined<["-"], "debugger-tuning=">; -def dwarf_debug_flags : Separate<["-"], "dwarf-debug-flags">, - HelpText<"The string to embed in the Dwarf debug flags record.">; -def record_command_line : Separate<["-"], "record-command-line">, - HelpText<"The string to embed in the .LLVM.command.line section.">; -def compress_debug_sections : Flag<["-", "--"], "compress-debug-sections">, - HelpText<"DWARF debug sections compression">; -def compress_debug_sections_EQ : Joined<["-", "--"], "compress-debug-sections=">, - HelpText<"DWARF debug sections compression type">; -def mno_exec_stack : Flag<["-"], "mnoexecstack">, - HelpText<"Mark the file as not needing an executable stack">; -def massembler_no_warn : Flag<["-"], "massembler-no-warn">, - HelpText<"Make assembler not emit warnings">; -def massembler_fatal_warnings : Flag<["-"], "massembler-fatal-warnings">, - HelpText<"Make assembler warnings fatal">; -def mrelax_relocations : Flag<["--"], "mrelax-relocations">, - HelpText<"Use relaxable elf relocations">; -def 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">, Values<"static,pic,ropi,rwpi,ropi-rwpi,dynamic-no-pic">; -def fno_math_builtin : Flag<["-"], "fno-math-builtin">, - HelpText<"Disable implicit builtin knowledge of math functions">; -} - -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_llvm_optzns : Flag<["-"], "disable-llvm-optzns">, - Alias<disable_llvm_passes>; -def disable_lifetimemarkers : Flag<["-"], "disable-lifetime-markers">, - HelpText<"Disable lifetime-markers emission even when optimizations are " - "enabled">; -def disable_O0_optnone : Flag<["-"], "disable-O0-optnone">, - HelpText<"Disable adding the optnone attribute to functions at O0">; -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">, - HelpText<"Turn on column location information.">; -def dwarf_ext_refs : Flag<["-"], "dwarf-ext-refs">, - HelpText<"Generate debug info with external references to clang modules" - " or precompiled headers">; -def dwarf_explicit_import : Flag<["-"], "dwarf-explicit-import">, - HelpText<"Generate explicit import from anonymous namespace to containing" - " scope">; -def debug_forward_template_params : Flag<["-"], "debug-forward-template-params">, - HelpText<"Emit complete descriptions of template parameters in forward" - " declarations">; -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">, - HelpText<"Don't generate implicit floating point instructions">; -def fdump_vtable_layouts : Flag<["-"], "fdump-vtable-layouts">, - HelpText<"Dump the layouts of all vtables that will be emitted in a translation unit">; -def fmerge_functions : Flag<["-"], "fmerge-functions">, - HelpText<"Permit merging of identical functions when optimizing.">; -def femit_coverage_notes : Flag<["-"], "femit-coverage-notes">, - HelpText<"Emit a gcov coverage notes file when compiling.">; -def femit_coverage_data: Flag<["-"], "femit-coverage-data">, - HelpText<"Instrument the program to emit gcov coverage data when run.">; -def coverage_data_file : Separate<["-"], "coverage-data-file">, - HelpText<"Emit coverage data to this filename.">; -def coverage_data_file_EQ : Joined<["-"], "coverage-data-file=">, - Alias<coverage_data_file>; -def coverage_notes_file : Separate<["-"], "coverage-notes-file">, - HelpText<"Emit coverage notes to this filename.">; -def coverage_notes_file_EQ : Joined<["-"], "coverage-notes-file=">, - Alias<coverage_notes_file>; -def coverage_cfg_checksum : Flag<["-"], "coverage-cfg-checksum">, - HelpText<"Emit CFG checksum for functions in .gcno files.">; -def coverage_no_function_names_in_data : Flag<["-"], "coverage-no-function-names-in-data">, - HelpText<"Emit function names in .gcda files.">; -def coverage_exit_block_before_body : Flag<["-"], "coverage-exit-block-before-body">, - HelpText<"Emit the exit block before the body blocks in .gcno files.">; -def coverage_version_EQ : Joined<["-"], "coverage-version=">, - HelpText<"Four-byte version string for gcov files.">; -def test_coverage : Flag<["-"], "test-coverage">, - HelpText<"Do not generate coverage files or remove coverage changes from IR">; -def dump_coverage_mapping : Flag<["-"], "dump-coverage-mapping">, - HelpText<"Dump the coverage mapping records, for testing">; -def fuse_register_sized_bitfield_access: Flag<["-"], "fuse-register-sized-bitfield-access">, - HelpText<"Use register sized accesses to bit-fields, when possible.">; -def relaxed_aliasing : Flag<["-"], "relaxed-aliasing">, - HelpText<"Turn off Type Based Alias Analysis">; -def no_struct_path_tbaa : Flag<["-"], "no-struct-path-tbaa">, - HelpText<"Turn off struct-path aware Type Based Alias Analysis">; -def new_struct_path_tbaa : Flag<["-"], "new-struct-path-tbaa">, - HelpText<"Enable enhanced struct-path aware Type Based Alias Analysis">; -def masm_verbose : Flag<["-"], "masm-verbose">, - HelpText<"Generate verbose assembly output">; -def mcode_model : Separate<["-"], "mcode-model">, - HelpText<"The code model to use">, Values<"tiny,small,kernel,medium,large">; -def mdebug_pass : Separate<["-"], "mdebug-pass">, - HelpText<"Enable additional debug output">; -def mframe_pointer_EQ : Joined<["-"], "mframe-pointer=">, - HelpText<"Specify which frame pointers to retain (all, non-leaf, none).">, Values<"all,non-leaf,none">; -def mdisable_tail_calls : Flag<["-"], "mdisable-tail-calls">, - HelpText<"Disable tail call optimization, keeping the call stack accurate">; -def menable_no_infinities : Flag<["-"], "menable-no-infs">, - HelpText<"Allow optimization to assume there are no infinities.">; -def menable_no_nans : Flag<["-"], "menable-no-nans">, - HelpText<"Allow optimization to assume there are no NaNs.">; -def menable_unsafe_fp_math : Flag<["-"], "menable-unsafe-fp-math">, - HelpText<"Allow unsafe floating-point math optimizations which may decrease " - "precision">; -def mreassociate : Flag<["-"], "mreassociate">, - HelpText<"Allow reassociation transformations for floating-point instructions">; -def mabi_EQ_ieeelongdouble : Flag<["-"], "mabi=ieeelongdouble">, - HelpText<"Use IEEE 754 quadruple-precision for long double">; -def mfloat_abi : Separate<["-"], "mfloat-abi">, - HelpText<"The float ABI to use">; -def mtp : Separate<["-"], "mtp">, - HelpText<"Mode for reading thread pointer">; -def mlimit_float_precision : Separate<["-"], "mlimit-float-precision">, - HelpText<"Limit float precision to the given value">; -def split_stacks : Flag<["-"], "split-stacks">, - HelpText<"Try to use a split stack if possible.">; -def mno_zero_initialized_in_bss : Flag<["-"], "mno-zero-initialized-in-bss">, - HelpText<"Do not put zero initialized data in the BSS">; -def mregparm : Separate<["-"], "mregparm">, - HelpText<"Limit the number of registers available for integer arguments">; -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_builtin_bitcode : Separate<["-"], "mlink-builtin-bitcode">, - HelpText<"Link and internalize needed symbols from the given bitcode file " - "before performing optimizations.">; -def mlink_cuda_bitcode : Separate<["-"], "mlink-cuda-bitcode">, - Alias<mlink_builtin_bitcode>; -def vectorize_loops : Flag<["-"], "vectorize-loops">, - HelpText<"Run the Loop vectorization passes">; -def vectorize_slp : Flag<["-"], "vectorize-slp">, - HelpText<"Run the SLP vectorization passes">; -def dependent_lib : Joined<["--"], "dependent-lib=">, - HelpText<"Add dependent library">; -def linker_option : Joined<["--"], "linker-option=">, - HelpText<"Add linker option">; -def fsanitize_coverage_type : Joined<["-"], "fsanitize-coverage-type=">, - HelpText<"Sanitizer coverage type">; -def fsanitize_coverage_indirect_calls - : Flag<["-"], "fsanitize-coverage-indirect-calls">, - HelpText<"Enable sanitizer coverage for indirect calls">; -def fsanitize_coverage_trace_bb - : Flag<["-"], "fsanitize-coverage-trace-bb">, - HelpText<"Enable basic block tracing in sanitizer coverage">; -def fsanitize_coverage_trace_cmp - : Flag<["-"], "fsanitize-coverage-trace-cmp">, - HelpText<"Enable cmp instruction tracing in sanitizer coverage">; -def fsanitize_coverage_trace_div - : Flag<["-"], "fsanitize-coverage-trace-div">, - HelpText<"Enable div instruction tracing in sanitizer coverage">; -def fsanitize_coverage_trace_gep - : Flag<["-"], "fsanitize-coverage-trace-gep">, - HelpText<"Enable gep instruction tracing in sanitizer coverage">; -def fsanitize_coverage_8bit_counters - : Flag<["-"], "fsanitize-coverage-8bit-counters">, - HelpText<"Enable frequency counters in sanitizer coverage">; -def fsanitize_coverage_inline_8bit_counters - : Flag<["-"], "fsanitize-coverage-inline-8bit-counters">, - HelpText<"Enable inline 8-bit counters in sanitizer coverage">; -def fsanitize_coverage_pc_table - : Flag<["-"], "fsanitize-coverage-pc-table">, - HelpText<"Create a table of coverage-instrumented PCs">; -def fsanitize_coverage_trace_pc - : Flag<["-"], "fsanitize-coverage-trace-pc">, - HelpText<"Enable PC tracing in sanitizer coverage">; -def fsanitize_coverage_trace_pc_guard - : Flag<["-"], "fsanitize-coverage-trace-pc-guard">, - HelpText<"Enable PC tracing with guard in sanitizer coverage">; -def fsanitize_coverage_no_prune - : Flag<["-"], "fsanitize-coverage-no-prune">, - HelpText<"Disable coverage pruning (i.e. instrument all blocks/edges)">; -def fsanitize_coverage_stack_depth - : Flag<["-"], "fsanitize-coverage-stack-depth">, - HelpText<"Enable max stack depth tracing">; -def fprofile_instrument_EQ : Joined<["-"], "fprofile-instrument=">, - HelpText<"Enable PGO instrumentation. The accepted value is clang, llvm, " - "or none">, Values<"none,clang,llvm">; -def fprofile_instrument_path_EQ : Joined<["-"], "fprofile-instrument-path=">, - HelpText<"Generate instrumented code to collect execution counts into " - "<file> (overridden by LLVM_PROFILE_FILE env var)">; -def fprofile_instrument_use_path_EQ : - Joined<["-"], "fprofile-instrument-use-path=">, - HelpText<"Specify the profile path in PGO use compilation">; -def flto_visibility_public_std: - Flag<["-"], "flto-visibility-public-std">, - HelpText<"Use public LTO visibility for classes in std and stdext namespaces">; -def flto_unit: Flag<["-"], "flto-unit">, - HelpText<"Emit IR to support LTO unit features (CFI, whole program vtable opt)">; -def fno_lto_unit: Flag<["-"], "fno-lto-unit">; -def femit_debug_entry_values : Flag<["-"], "femit-debug-entry-values">, - HelpText<"Enables debug info about call site parameter's entry values">; -def fdebug_pass_manager : Flag<["-"], "fdebug-pass-manager">, - HelpText<"Prints debug information for the new pass manager">; -def fno_debug_pass_manager : Flag<["-"], "fno-debug-pass-manager">, - HelpText<"Disables debug printing for the new pass manager">; -// The driver option takes the key as a parameter to the -msign-return-address= -// and -mbranch-protection= options, but CC1 has a separate option so we -// don't have to parse the parameter twice. -def msign_return_address_key_EQ : Joined<["-"], "msign-return-address-key=">, - Values<"a_key,b_key">; -def mbranch_target_enforce : Flag<["-"], "mbranch-target-enforce">; -def fno_dllexport_inlines : Flag<["-"], "fno-dllexport-inlines">; -def cfguard_no_checks : Flag<["-"], "cfguard-no-checks">, - HelpText<"Emit Windows Control Flow Guard tables only (no checks)">; -def cfguard : Flag<["-"], "cfguard">, - HelpText<"Emit Windows Control Flow Guard tables and checks">; - -//===----------------------------------------------------------------------===// -// Dependency Output Options -//===----------------------------------------------------------------------===// - -def sys_header_deps : Flag<["-"], "sys-header-deps">, - HelpText<"Include system headers in dependency output">; -def module_file_deps : Flag<["-"], "module-file-deps">, - HelpText<"Include module files in dependency output">; -def header_include_file : Separate<["-"], "header-include-file">, - HelpText<"Filename (or -) to write header include output to">; -def show_includes : Flag<["--"], "show-includes">, - HelpText<"Print cl.exe style /showIncludes to stdout">; - -//===----------------------------------------------------------------------===// -// Diagnostic Options -//===----------------------------------------------------------------------===// - -def diagnostic_log_file : Separate<["-"], "diagnostic-log-file">, - HelpText<"Filename (or -) to log diagnostics to">; -def diagnostic_serialized_file : Separate<["-"], "serialize-diagnostic-file">, - MetaVarName<"<filename>">, - HelpText<"File for serializing diagnostics in a binary format">; - -def fdiagnostics_format : Separate<["-"], "fdiagnostics-format">, - HelpText<"Change diagnostic formatting to match IDE and command line tools">, Values<"clang,msvc,msvc-fallback,vi">; -def fdiagnostics_show_category : Separate<["-"], "fdiagnostics-show-category">, - HelpText<"Print diagnostic category">, Values<"none,id,name">; -def fno_diagnostics_use_presumed_location : Flag<["-"], "fno-diagnostics-use-presumed-location">, - HelpText<"Ignore #line directives when displaying diagnostic locations">; -def ftabstop : Separate<["-"], "ftabstop">, MetaVarName<"<N>">, - HelpText<"Set the tab stop distance.">; -def ferror_limit : Separate<["-"], "ferror-limit">, MetaVarName<"<N>">, - HelpText<"Set the maximum number of errors to emit before stopping (0 = no limit).">; -def fmacro_backtrace_limit : Separate<["-"], "fmacro-backtrace-limit">, MetaVarName<"<N>">, - HelpText<"Set the maximum number of entries to print in a macro expansion backtrace (0 = no limit).">; -def ftemplate_backtrace_limit : Separate<["-"], "ftemplate-backtrace-limit">, MetaVarName<"<N>">, - HelpText<"Set the maximum number of entries to print in a template instantiation backtrace (0 = no limit).">; -def fconstexpr_backtrace_limit : Separate<["-"], "fconstexpr-backtrace-limit">, MetaVarName<"<N>">, - HelpText<"Set the maximum number of entries to print in a constexpr evaluation backtrace (0 = no limit).">; -def fspell_checking_limit : Separate<["-"], "fspell-checking-limit">, MetaVarName<"<N>">, - HelpText<"Set the maximum number of times to perform spell checking on unrecognized identifiers (0 = no limit).">; -def fcaret_diagnostics_max_lines : - Separate<["-"], "fcaret-diagnostics-max-lines">, MetaVarName<"<N>">, - HelpText<"Set the maximum number of source lines to show in a caret diagnostic">; -def fmessage_length : Separate<["-"], "fmessage-length">, MetaVarName<"<N>">, - HelpText<"Format message diagnostics so that they fit within N columns or fewer, when possible.">; -def verify_EQ : CommaJoined<["-"], "verify=">, - MetaVarName<"<prefixes>">, - HelpText<"Verify diagnostic output using comment directives that start with" - " prefixes in the comma-separated sequence <prefixes>">; -def verify : Flag<["-"], "verify">, - HelpText<"Equivalent to -verify=expected">; -def verify_ignore_unexpected : Flag<["-"], "verify-ignore-unexpected">, - HelpText<"Ignore unexpected diagnostic messages">; -def verify_ignore_unexpected_EQ : CommaJoined<["-"], "verify-ignore-unexpected=">, - HelpText<"Ignore unexpected diagnostic messages">; -def Wno_rewrite_macros : Flag<["-"], "Wno-rewrite-macros">, - HelpText<"Silence ObjC rewriting warnings">; - -//===----------------------------------------------------------------------===// -// Frontend Options -//===----------------------------------------------------------------------===// - -// This isn't normally used, it is just here so we can parse a -// CompilerInvocation out of a driver-derived argument vector. -def cc1 : Flag<["-"], "cc1">; -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">; -def remap_file : Separate<["-"], "remap-file">, - MetaVarName<"<from>;<to>">, - HelpText<"Replace the contents of the <from> file with the contents of the <to> file">; -def code_completion_at_EQ : Joined<["-"], "code-completion-at=">, - Alias<code_completion_at>; -def code_completion_macros : Flag<["-"], "code-completion-macros">, - HelpText<"Include macros in code-completion results">; -def code_completion_patterns : Flag<["-"], "code-completion-patterns">, - HelpText<"Include code patterns in code-completion results">; -def no_code_completion_globals : Flag<["-"], "no-code-completion-globals">, - HelpText<"Do not include global declarations in code-completion results.">; -def no_code_completion_ns_level_decls : Flag<["-"], "no-code-completion-ns-level-decls">, - HelpText<"Do not include declarations inside namespaces (incl. global namespace) in the code-completion results.">; -def code_completion_brief_comments : Flag<["-"], "code-completion-brief-comments">, - HelpText<"Include brief documentation comments in code-completion results.">; -def code_completion_with_fixits : Flag<["-"], "code-completion-with-fixits">, - HelpText<"Include code completion results which require small fix-its.">; -def disable_free : Flag<["-"], "disable-free">, - HelpText<"Disable freeing of memory on exit">; -def discard_value_names : Flag<["-"], "discard-value-names">, - HelpText<"Discard value names in LLVM IR">; -def load : Separate<["-"], "load">, MetaVarName<"<dsopath>">, - HelpText<"Load the named plugin (dynamic shared object)">; -def plugin : Separate<["-"], "plugin">, MetaVarName<"<name>">, - HelpText<"Use the named plugin action instead of the default action (use \"help\" to list available options)">; -def plugin_arg : JoinedAndSeparate<["-"], "plugin-arg-">, - MetaVarName<"<name> <arg>">, - HelpText<"Pass <arg> to plugin <name>">; -def add_plugin : Separate<["-"], "add-plugin">, MetaVarName<"<name>">, - HelpText<"Use the named plugin action in addition to the default action">; -def ast_dump_filter : Separate<["-"], "ast-dump-filter">, - MetaVarName<"<dump_filter>">, - HelpText<"Use with -ast-dump or -ast-print to dump/print only AST declaration" - " nodes having a certain substring in a qualified name. Use" - " -ast-list to list all filterable declaration node names.">; -def fno_modules_global_index : Flag<["-"], "fno-modules-global-index">, - HelpText<"Do not automatically generate or update the global module index">; -def fno_modules_error_recovery : Flag<["-"], "fno-modules-error-recovery">, - HelpText<"Do not automatically import modules for error recovery">; -def fmodule_map_file_home_is_cwd : Flag<["-"], "fmodule-map-file-home-is-cwd">, - HelpText<"Use the current working directory as the home directory of " - "module maps specified by -fmodule-map-file=<FILE>">; -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 " - "top-level module.">; -def fmodules_codegen : - Flag<["-"], "fmodules-codegen">, - HelpText<"Generate code for uses of this module that assumes an explicit " - "object file will be built for the module">; -def fmodules_debuginfo : - Flag<["-"], "fmodules-debuginfo">, - HelpText<"Generate debug info for types in an object file built from this " - "module and do not generate them elsewhere">; -def fmodule_format_EQ : Joined<["-"], "fmodule-format=">, - HelpText<"Select the container format for clang modules and PCH. " - "Supported options are 'raw' and 'obj'.">; -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.">; - -let Group = Action_Group in { - -def Eonly : Flag<["-"], "Eonly">, - HelpText<"Just run preprocessor, no output (for timings)">; -def dump_raw_tokens : Flag<["-"], "dump-raw-tokens">, - HelpText<"Lex file in raw mode and dump raw tokens">; -def analyze : Flag<["-"], "analyze">, - HelpText<"Run static analysis engine">; -def dump_tokens : Flag<["-"], "dump-tokens">, - HelpText<"Run preprocessor, dump internal rep of tokens">; -def init_only : Flag<["-"], "init-only">, - HelpText<"Only execute frontend initialization">; -def fixit : Flag<["-"], "fixit">, - HelpText<"Apply fix-it advice to the input source">; -def fixit_EQ : Joined<["-"], "fixit=">, - HelpText<"Apply fix-it advice creating a file with the given suffix">; -def print_preamble : Flag<["-"], "print-preamble">, - HelpText<"Print the \"preamble\" of a file, which is a candidate for implicit" - " precompiled headers.">; -def emit_html : Flag<["-"], "emit-html">, - HelpText<"Output input source as HTML">; -def ast_print : Flag<["-"], "ast-print">, - HelpText<"Build ASTs and then pretty-print them">; -def ast_list : Flag<["-"], "ast-list">, - HelpText<"Build ASTs and print the list of declaration node qualified names">; -def ast_dump : Flag<["-"], "ast-dump">, - HelpText<"Build ASTs and then debug dump them">; -def ast_dump_EQ : Joined<["-"], "ast-dump=">, - HelpText<"Build ASTs and then debug dump them in the specified format. " - "Supported formats include: default, json">; -def ast_dump_all : Flag<["-"], "ast-dump-all">, - HelpText<"Build ASTs and then debug dump them, forcing deserialization">; -def ast_dump_all_EQ : Joined<["-"], "ast-dump-all=">, - HelpText<"Build ASTs and then debug dump them in the specified format, " - "forcing deserialization. Supported formats include: default, json">; -def templight_dump : Flag<["-"], "templight-dump">, - HelpText<"Dump templight information to stdout">; -def ast_dump_lookups : Flag<["-"], "ast-dump-lookups">, - HelpText<"Build ASTs and then debug dump their name lookup tables">; -def ast_view : Flag<["-"], "ast-view">, - HelpText<"Build ASTs and view them with GraphViz">; -def emit_module : Flag<["-"], "emit-module">, - HelpText<"Generate pre-compiled module file from a module map">; -def emit_module_interface : Flag<["-"], "emit-module-interface">, - HelpText<"Generate pre-compiled module file from a C++ module interface">; -def emit_header_module : Flag<["-"], "emit-header-module">, - HelpText<"Generate pre-compiled module file from a set of header files">; -def emit_pch : Flag<["-"], "emit-pch">, - HelpText<"Generate pre-compiled header file">; -def emit_llvm_bc : Flag<["-"], "emit-llvm-bc">, - HelpText<"Build ASTs then convert to LLVM, emit .bc file">; -def emit_llvm_only : Flag<["-"], "emit-llvm-only">, - HelpText<"Build ASTs and convert to LLVM, discarding output">; -def emit_codegen_only : Flag<["-"], "emit-codegen-only">, - HelpText<"Generate machine code, but discard output">; -def emit_obj : Flag<["-"], "emit-obj">, - HelpText<"Emit native object files">; -def rewrite_test : Flag<["-"], "rewrite-test">, - HelpText<"Rewriter playground">; -def rewrite_macros : Flag<["-"], "rewrite-macros">, - HelpText<"Expand macros without full preprocessing">; -def migrate : Flag<["-"], "migrate">, - HelpText<"Migrate source code">; -def compiler_options_dump : Flag<["-"], "compiler-options-dump">, - HelpText<"Dump the compiler configuration options">; -def print_dependency_directives_minimized_source : Flag<["-"], - "print-dependency-directives-minimized-source">, - HelpText<"Print the output of the dependency directives source minimizer">; -} - -def emit_llvm_uselists : Flag<["-"], "emit-llvm-uselists">, - HelpText<"Preserve order of LLVM use-lists when serializing">; -def no_emit_llvm_uselists : Flag<["-"], "no-emit-llvm-uselists">, - HelpText<"Don't preserve order of LLVM use-lists when serializing">; - -def mt_migrate_directory : Separate<["-"], "mt-migrate-directory">, - HelpText<"Directory for temporary files produced during ARC or ObjC migration">; -def arcmt_check : Flag<["-"], "arcmt-check">, - HelpText<"Check for ARC migration issues that need manual handling">; -def arcmt_modify : Flag<["-"], "arcmt-modify">, - HelpText<"Apply modifications to files to conform to ARC">; -def arcmt_migrate : Flag<["-"], "arcmt-migrate">, - HelpText<"Apply modifications and produces temporary files that conform to ARC">; - -def opt_record_file : Separate<["-"], "opt-record-file">, - HelpText<"File name to use for YAML optimization record output">; -def opt_record_passes : Separate<["-"], "opt-record-passes">, - HelpText<"Only record remark information for passes whose names match the given regular expression">; -def opt_record_format : Separate<["-"], "opt-record-format">, - HelpText<"The format used for serializing remarks (default: YAML)">; - -def print_stats : Flag<["-"], "print-stats">, - HelpText<"Print performance metrics and statistics">; -def stats_file : Joined<["-"], "stats-file=">, - HelpText<"Filename to write statistics to">; -def fdump_record_layouts : Flag<["-"], "fdump-record-layouts">, - HelpText<"Dump record layout information">; -def fdump_record_layouts_simple : Flag<["-"], "fdump-record-layouts-simple">, - HelpText<"Dump record layout information in a simple form used for testing">; -def fix_what_you_can : Flag<["-"], "fix-what-you-can">, - HelpText<"Apply fix-it advice even in the presence of unfixable errors">; -def fix_only_warnings : Flag<["-"], "fix-only-warnings">, - HelpText<"Apply fix-it advice only for warnings, not errors">; -def fixit_recompile : Flag<["-"], "fixit-recompile">, - HelpText<"Apply fix-it changes and recompile">; -def fixit_to_temp : Flag<["-"], "fixit-to-temporary">, - HelpText<"Apply fix-it changes to temporary files">; - -def foverride_record_layout_EQ : Joined<["-"], "foverride-record-layout=">, - HelpText<"Override record layouts with those in the given file">; -def pch_through_header_EQ : Joined<["-"], "pch-through-header=">, - HelpText<"Stop PCH generation after including this file. When using a PCH, " - "skip tokens until after this file is included.">; -def pch_through_hdrstop_create : Flag<["-"], "pch-through-hdrstop-create">, - HelpText<"When creating a PCH, stop PCH generation after #pragma hdrstop.">; -def pch_through_hdrstop_use : Flag<["-"], "pch-through-hdrstop-use">, - HelpText<"When using a PCH, skip tokens until after a #pragma hdrstop.">; -def fno_pch_timestamp : Flag<["-"], "fno-pch-timestamp">, - HelpText<"Disable inclusion of timestamp in precompiled headers">; -def building_pch_with_obj : Flag<["-"], "building-pch-with-obj">, - HelpText<"This compilation is part of building a PCH with corresponding object file.">; - -def aligned_alloc_unavailable : Flag<["-"], "faligned-alloc-unavailable">, - HelpText<"Aligned allocation/deallocation functions are unavailable">; - -//===----------------------------------------------------------------------===// -// Language Options -//===----------------------------------------------------------------------===// - -let Flags = [CC1Option, CC1AsOption, NoDriverOption] in { - -def version : Flag<["-"], "version">, - HelpText<"Print the compiler version">; -def main_file_name : Separate<["-"], "main-file-name">, - HelpText<"Main file name to use for debug info and source if missing">; -def split_dwarf_output : Separate<["-"], "split-dwarf-output">, - HelpText<"File name to use for split dwarf debug info output">; - -} - -def fblocks_runtime_optional : Flag<["-"], "fblocks-runtime-optional">, - HelpText<"Weakly link in the blocks runtime">; -def fexternc_nounwind : Flag<["-"], "fexternc-nounwind">, - HelpText<"Assume all functions with C linkage do not unwind">; -def split_dwarf_file : Separate<["-"], "split-dwarf-file">, - HelpText<"Name of the split dwarf debug info file to encode in the object file">; -def fno_wchar : Flag<["-"], "fno-wchar">, - HelpText<"Disable C++ builtin type wchar_t">; -def fconstant_string_class : Separate<["-"], "fconstant-string-class">, - MetaVarName<"<class name>">, - HelpText<"Specify the class to use for constant Objective-C string objects.">; -def fobjc_arc_cxxlib_EQ : Joined<["-"], "fobjc-arc-cxxlib=">, - HelpText<"Objective-C++ Automatic Reference Counting standard library kind">, Values<"libc++,libstdc++,none">; -def fobjc_runtime_has_weak : Flag<["-"], "fobjc-runtime-has-weak">, - HelpText<"The target Objective-C runtime supports ARC weak operations">; -def fobjc_dispatch_method_EQ : Joined<["-"], "fobjc-dispatch-method=">, - HelpText<"Objective-C dispatch method to use">, Values<"legacy,non-legacy,mixed">; -def disable_objc_default_synthesize_properties : Flag<["-"], "disable-objc-default-synthesize-properties">, - HelpText<"disable the default synthesis of Objective-C properties">; -def fencode_extended_block_signature : Flag<["-"], "fencode-extended-block-signature">, - HelpText<"enable extended encoding of block type signature">; -def function_alignment : Separate<["-"], "function-alignment">, - HelpText<"default alignment for functions">; -def pic_level : Separate<["-"], "pic-level">, - HelpText<"Value for __PIC__">; -def pic_is_pie : Flag<["-"], "pic-is-pie">, - HelpText<"File is for a position independent executable">; -def fno_validate_pch : Flag<["-"], "fno-validate-pch">, - HelpText<"Disable validation of precompiled headers">; -def fallow_pch_with_errors : Flag<["-"], "fallow-pch-with-compiler-errors">, - HelpText<"Accept a PCH file that was created with compiler errors">; -def dump_deserialized_pch_decls : Flag<["-"], "dump-deserialized-decls">, - HelpText<"Dump declarations that are deserialized from PCH, for testing">; -def error_on_deserialized_pch_decl : Separate<["-"], "error-on-deserialized-decl">, - HelpText<"Emit error if a specific declaration is deserialized from PCH, for testing">; -def error_on_deserialized_pch_decl_EQ : Joined<["-"], "error-on-deserialized-decl=">, - Alias<error_on_deserialized_pch_decl>; -def static_define : Flag<["-"], "static-define">, - HelpText<"Should __STATIC__ be defined">; -def stack_protector : Separate<["-"], "stack-protector">, - HelpText<"Enable stack protectors">; -def stack_protector_buffer_size : Separate<["-"], "stack-protector-buffer-size">, - HelpText<"Lower bound for a buffer to be considered for stack protection">; -def fvisibility : Separate<["-"], "fvisibility">, - HelpText<"Default type and symbol visibility">; -def ftype_visibility : Separate<["-"], "ftype-visibility">, - HelpText<"Default type visibility">; -def fapply_global_visibility_to_externs : Flag<["-"], "fapply-global-visibility-to-externs">, - HelpText<"Apply global symbol visibility to external declarations without an explicit visibility">; -def ftemplate_depth : Separate<["-"], "ftemplate-depth">, - HelpText<"Maximum depth of recursive template instantiation">; -def foperator_arrow_depth : Separate<["-"], "foperator-arrow-depth">, - HelpText<"Maximum number of 'operator->'s to call for a member access">; -def fconstexpr_depth : Separate<["-"], "fconstexpr-depth">, - HelpText<"Maximum depth of recursive constexpr function calls">; -def fconstexpr_steps : Separate<["-"], "fconstexpr-steps">, - HelpText<"Maximum number of steps in constexpr function evaluation">; -def fbracket_depth : Separate<["-"], "fbracket-depth">, - HelpText<"Maximum nesting level for parentheses, brackets, and braces">; -def fconst_strings : Flag<["-"], "fconst-strings">, - HelpText<"Use a const qualified type for string literals in C and ObjC">; -def fno_const_strings : Flag<["-"], "fno-const-strings">, - HelpText<"Don't use a const qualified type for string literals in C and ObjC">; -def fno_bitfield_type_align : Flag<["-"], "fno-bitfield-type-align">, - HelpText<"Ignore bit-field types when aligning structures">; -def ffake_address_space_map : Flag<["-"], "ffake-address-space-map">, - HelpText<"Use a fake address space map; OpenCL testing purposes only">; -def faddress_space_map_mangling_EQ : Joined<["-"], "faddress-space-map-mangling=">, MetaVarName<"<yes|no|target>">, - HelpText<"Set the mode for address space map based mangling; OpenCL testing purposes only">; -def funknown_anytype : Flag<["-"], "funknown-anytype">, - HelpText<"Enable parser support for the __unknown_anytype type; for testing purposes only">; -def fdebugger_support : Flag<["-"], "fdebugger-support">, - HelpText<"Enable special debugger support behavior">; -def fdebugger_cast_result_to_id : Flag<["-"], "fdebugger-cast-result-to-id">, - HelpText<"Enable casting unknown expression results to id">; -def fdebugger_objc_literal : Flag<["-"], "fdebugger-objc-literal">, - HelpText<"Enable special debugger support for Objective-C subscripting and literals">; -def fdeprecated_macro : Flag<["-"], "fdeprecated-macro">, - HelpText<"Defines the __DEPRECATED macro">; -def fno_deprecated_macro : Flag<["-"], "fno-deprecated-macro">, - HelpText<"Undefines the __DEPRECATED macro">; -def fobjc_subscripting_legacy_runtime : Flag<["-"], "fobjc-subscripting-legacy-runtime">, - HelpText<"Allow Objective-C array and dictionary subscripting in legacy runtime">; -def vtordisp_mode_EQ : Joined<["-"], "vtordisp-mode=">, - HelpText<"Control vtordisp placement on win32 targets">; -def fnative_half_type: Flag<["-"], "fnative-half-type">, - HelpText<"Use the native half type for __fp16 instead of promoting to float">; -def fnative_half_arguments_and_returns : Flag<["-"], "fnative-half-arguments-and-returns">, - HelpText<"Use the native __fp16 type for arguments and returns (and skip ABI-specific lowering)">; -def fallow_half_arguments_and_returns : Flag<["-"], "fallow-half-arguments-and-returns">, - HelpText<"Allow function arguments and returns of type half">; -def fdefault_calling_conv_EQ : Joined<["-"], "fdefault-calling-conv=">, - HelpText<"Set default calling convention">, Values<"cdecl,fastcall,stdcall,vectorcall,regcall">; -def finclude_default_header : Flag<["-"], "finclude-default-header">, - HelpText<"Include default header file for OpenCL">; -def fdeclare_opencl_builtins : Flag<["-"], "fdeclare-opencl-builtins">, - HelpText<"Add OpenCL builtin function declarations (experimental)">; -def fpreserve_vec3_type : Flag<["-"], "fpreserve-vec3-type">, - HelpText<"Preserve 3-component vector type">; -def fwchar_type_EQ : Joined<["-"], "fwchar-type=">, - HelpText<"Select underlying type for wchar_t">, Values<"char,short,int">; -def fsigned_wchar : Flag<["-"], "fsigned-wchar">, - HelpText<"Use a signed type for wchar_t">; -def fno_signed_wchar : Flag<["-"], "fno-signed-wchar">, - HelpText<"Use an unsigned type for wchar_t">; - -// FIXME: Remove these entirely once functionality/tests have been excised. -def fobjc_gc_only : Flag<["-"], "fobjc-gc-only">, Group<f_Group>, - HelpText<"Use GC exclusively for Objective-C related memory management">; -def fobjc_gc : Flag<["-"], "fobjc-gc">, Group<f_Group>, - HelpText<"Enable Objective-C garbage collection">; - -//===----------------------------------------------------------------------===// -// Header Search Options -//===----------------------------------------------------------------------===// - -def nostdsysteminc : Flag<["-"], "nostdsysteminc">, - HelpText<"Disable standard system #include directories">; -def fdisable_module_hash : Flag<["-"], "fdisable-module-hash">, - HelpText<"Disable the module hash">; -def fmodules_hash_content : Flag<["-"], "fmodules-hash-content">, - HelpText<"Enable hashing the content of a module file">; -def fmodules_strict_context_hash : Flag<["-"], "fmodules-strict-context-hash">, - HelpText<"Enable hashing of all compiler options that could impact the " - "semantics of a module in an implicit build">; -def c_isystem : JoinedOrSeparate<["-"], "c-isystem">, MetaVarName<"<directory>">, - HelpText<"Add directory to the C SYSTEM include search path">; -def objc_isystem : JoinedOrSeparate<["-"], "objc-isystem">, - MetaVarName<"<directory>">, - HelpText<"Add directory to the ObjC SYSTEM include search path">; -def objcxx_isystem : JoinedOrSeparate<["-"], "objcxx-isystem">, - MetaVarName<"<directory>">, - HelpText<"Add directory to the ObjC++ SYSTEM include search path">; -def internal_isystem : JoinedOrSeparate<["-"], "internal-isystem">, - MetaVarName<"<directory>">, - HelpText<"Add directory to the internal system include search path; these " - "are assumed to not be user-provided and are used to model system " - "and standard headers' paths.">; -def internal_externc_isystem : JoinedOrSeparate<["-"], "internal-externc-isystem">, - MetaVarName<"<directory>">, - HelpText<"Add directory to the internal system include search path with " - "implicit extern \"C\" semantics; these are assumed to not be " - "user-provided and are used to model system and standard headers' " - "paths.">; - -//===----------------------------------------------------------------------===// -// Preprocessor Options -//===----------------------------------------------------------------------===// - -def chain_include : Separate<["-"], "chain-include">, MetaVarName<"<file>">, - HelpText<"Include and chain a header file after turning it into PCH">; -def preamble_bytes_EQ : Joined<["-"], "preamble-bytes=">, - HelpText<"Assume that the precompiled header is a precompiled preamble " - "covering the first N bytes of the main file">; -def detailed_preprocessing_record : Flag<["-"], "detailed-preprocessing-record">, - HelpText<"include a detailed record of preprocessing actions">; -def setup_static_analyzer : Flag<["-"], "setup-static-analyzer">, - HelpText<"Set up preprocessor for static analyzer (done automatically when static analyzer is run).">; - -//===----------------------------------------------------------------------===// -// OpenCL Options -//===----------------------------------------------------------------------===// - -def cl_ext_EQ : CommaJoined<["-"], "cl-ext=">, - HelpText<"OpenCL only. Enable or disable OpenCL extensions. The argument is a comma-separated sequence of one or more extension names, each prefixed by '+' or '-'.">; - -//===----------------------------------------------------------------------===// -// CUDA Options -//===----------------------------------------------------------------------===// - -def fcuda_is_device : Flag<["-"], "fcuda-is-device">, - HelpText<"Generate code for CUDA device">; -def fcuda_include_gpubinary : Separate<["-"], "fcuda-include-gpubinary">, - HelpText<"Incorporate CUDA device-side binary into host object file.">; -def fcuda_allow_variadic_functions : Flag<["-"], "fcuda-allow-variadic-functions">, - HelpText<"Allow variadic functions in CUDA device code.">; -def fno_cuda_host_device_constexpr : Flag<["-"], "fno-cuda-host-device-constexpr">, - HelpText<"Don't treat unattributed constexpr functions as __host__ __device__.">; - -//===----------------------------------------------------------------------===// -// OpenMP Options -//===----------------------------------------------------------------------===// - -def fopenmp_is_device : Flag<["-"], "fopenmp-is-device">, - HelpText<"Generate code only for an OpenMP target device.">; -def fopenmp_host_ir_file_path : Separate<["-"], "fopenmp-host-ir-file-path">, - HelpText<"Path to the IR file produced by the frontend for the host.">; - -//===----------------------------------------------------------------------===// -// SYCL Options -//===----------------------------------------------------------------------===// - -def fsycl_is_device : Flag<["-"], "fsycl-is-device">, - HelpText<"Generate code for SYCL device.">; - -} // let Flags = [CC1Option] - -//===----------------------------------------------------------------------===// -// cc1as-only Options -//===----------------------------------------------------------------------===// - -let Flags = [CC1AsOption, NoDriverOption] in { - -// Language Options -def n : Flag<["-"], "n">, - HelpText<"Don't automatically start assembly file with a text section">; - -// Frontend Options -def filetype : Separate<["-"], "filetype">, - HelpText<"Specify the output file type ('asm', 'null', or 'obj')">; - -// Transliterate Options -def output_asm_variant : Separate<["-"], "output-asm-variant">, - HelpText<"Select the asm variant index to use for output">; -def show_encoding : Flag<["-"], "show-encoding">, - HelpText<"Show instruction encoding information in transliterate mode">; -def show_inst : Flag<["-"], "show-inst">, - HelpText<"Show internal instruction representation in transliterate mode">; - -// Assemble Options -def dwarf_debug_producer : Separate<["-"], "dwarf-debug-producer">, - HelpText<"The string to embed in the Dwarf debug AT_producer record.">; - -def defsym : Separate<["-"], "defsym">, - HelpText<"Define a value for a symbol">; -} // let Flags = [CC1AsOption] diff --git a/clang/include/clang/Driver/CLCompatOptions.td b/clang/include/clang/Driver/CLCompatOptions.td deleted file mode 100644 index 50d4622009c9..000000000000 --- a/clang/include/clang/Driver/CLCompatOptions.td +++ /dev/null @@ -1,466 +0,0 @@ -//===--- CLCompatOptions.td - Options for clang-cl ------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// This file defines the options accepted by clang-cl. -// -//===----------------------------------------------------------------------===// - -def cl_Group : OptionGroup<"<clang-cl options>">, Flags<[CLOption]>, - HelpText<"CL.EXE COMPATIBILITY OPTIONS">; - -def cl_compile_Group : OptionGroup<"<clang-cl compile-only options>">, - Group<cl_Group>; - -def cl_ignored_Group : OptionGroup<"<clang-cl ignored options>">, - Group<cl_Group>; - -class CLFlag<string name> : Option<["/", "-"], name, KIND_FLAG>, - Group<cl_Group>, Flags<[CLOption, DriverOption]>; - -class CLCompileFlag<string name> : Option<["/", "-"], name, KIND_FLAG>, - Group<cl_compile_Group>, Flags<[CLOption, DriverOption]>; - -class CLIgnoredFlag<string name> : Option<["/", "-"], name, KIND_FLAG>, - Group<cl_ignored_Group>, Flags<[CLOption, DriverOption]>; - -class CLJoined<string name> : Option<["/", "-"], name, KIND_JOINED>, - Group<cl_Group>, Flags<[CLOption, DriverOption]>; - -class CLCompileJoined<string name> : Option<["/", "-"], name, KIND_JOINED>, - Group<cl_compile_Group>, Flags<[CLOption, DriverOption]>; - -class CLIgnoredJoined<string name> : Option<["/", "-"], name, KIND_JOINED>, - Group<cl_ignored_Group>, Flags<[CLOption, DriverOption, HelpHidden]>; - -class CLJoinedOrSeparate<string name> : Option<["/", "-"], name, - KIND_JOINED_OR_SEPARATE>, Group<cl_Group>, Flags<[CLOption, DriverOption]>; - -class CLCompileJoinedOrSeparate<string name> : Option<["/", "-"], name, - KIND_JOINED_OR_SEPARATE>, Group<cl_compile_Group>, - Flags<[CLOption, DriverOption]>; - -class CLRemainingArgsJoined<string name> : Option<["/", "-"], name, - KIND_REMAINING_ARGS_JOINED>, Group<cl_Group>, Flags<[CLOption, DriverOption]>; - -// Aliases: -// (We don't put any of these in cl_compile_Group as the options they alias are -// already in the right group.) - -def _SLASH_Brepro : CLFlag<"Brepro">, - HelpText<"Do not write current time into COFF output (breaks link.exe /incremental)">, - Alias<mno_incremental_linker_compatible>; -def _SLASH_Brepro_ : CLFlag<"Brepro-">, - HelpText<"Write current time into COFF output (default)">, - Alias<mincremental_linker_compatible>; -def _SLASH_C : CLFlag<"C">, - HelpText<"Do not discard comments when preprocessing">, Alias<C>; -def _SLASH_c : CLFlag<"c">, HelpText<"Compile only">, Alias<c>; -def _SLASH_d1PP : CLFlag<"d1PP">, - HelpText<"Retain macro definitions in /E mode">, Alias<dD>; -def _SLASH_d1reportAllClassLayout : CLFlag<"d1reportAllClassLayout">, - HelpText<"Dump record layout information">, - Alias<Xclang>, AliasArgs<["-fdump-record-layouts"]>; -def _SLASH_diagnostics_caret : CLFlag<"diagnostics:caret">, - HelpText<"Enable caret and column diagnostics (default)">; -def _SLASH_diagnostics_column : CLFlag<"diagnostics:column">, - HelpText<"Disable caret diagnostics but keep column info">; -def _SLASH_diagnostics_classic : CLFlag<"diagnostics:classic">, - HelpText<"Disable column and caret diagnostics">; -def _SLASH_D : CLJoinedOrSeparate<"D">, HelpText<"Define macro">, - MetaVarName<"<macro[=value]>">, Alias<D>; -def _SLASH_E : CLFlag<"E">, HelpText<"Preprocess to stdout">, Alias<E>; -def _SLASH_fp_except : CLFlag<"fp:except">, HelpText<"">, Alias<ftrapping_math>; -def _SLASH_fp_except_ : CLFlag<"fp:except-">, - HelpText<"">, Alias<fno_trapping_math>; -def _SLASH_fp_fast : CLFlag<"fp:fast">, HelpText<"">, Alias<ffast_math>; -def _SLASH_fp_precise : CLFlag<"fp:precise">, - HelpText<"">, Alias<fno_fast_math>; -def _SLASH_fp_strict : CLFlag<"fp:strict">, HelpText<"">, Alias<fno_fast_math>; -def _SLASH_GA : CLFlag<"GA">, Alias<ftlsmodel_EQ>, AliasArgs<["local-exec"]>, - HelpText<"Assume thread-local variables are defined in the executable">; -def _SLASH_GR : CLFlag<"GR">, HelpText<"Emit RTTI data (default)">; -def _SLASH_GR_ : CLFlag<"GR-">, HelpText<"Do not emit RTTI data">; -def _SLASH_GF : CLIgnoredFlag<"GF">, - HelpText<"Enable string pooling (default)">; -def _SLASH_GF_ : CLFlag<"GF-">, HelpText<"Disable string pooling">, - Alias<fwritable_strings>; -def _SLASH_GS : CLFlag<"GS">, - HelpText<"Enable buffer security check (default)">; -def _SLASH_GS_ : CLFlag<"GS-">, HelpText<"Disable buffer security check">; -def : CLFlag<"Gs">, HelpText<"Use stack probes (default)">, - Alias<mstack_probe_size>, AliasArgs<["4096"]>; -def _SLASH_Gs : CLJoined<"Gs">, - HelpText<"Set stack probe size (default 4096)">, Alias<mstack_probe_size>; -def _SLASH_Gy : CLFlag<"Gy">, HelpText<"Put each function in its own section">, - Alias<ffunction_sections>; -def _SLASH_Gy_ : CLFlag<"Gy-">, - HelpText<"Do not put each function in its own section (default)">, - Alias<fno_function_sections>; -def _SLASH_Gw : CLFlag<"Gw">, HelpText<"Put each data item in its own section">, - Alias<fdata_sections>; -def _SLASH_Gw_ : CLFlag<"Gw-">, - HelpText<"Do not put each data item in its own section (default)">, - Alias<fno_data_sections>; -def _SLASH_help : CLFlag<"help">, Alias<help>, - HelpText<"Display available options">; -def _SLASH_HELP : CLFlag<"HELP">, Alias<help>; -def _SLASH_I : CLJoinedOrSeparate<"I">, - HelpText<"Add directory to include search path">, MetaVarName<"<dir>">, - Alias<I>; -def _SLASH_J : CLFlag<"J">, HelpText<"Make char type unsigned">, - Alias<funsigned_char>; - -// The _SLASH_O option handles all the /O flags, but we also provide separate -// aliased options to provide separate help messages. -def _SLASH_O : CLJoined<"O">, - HelpText<"Set multiple /O flags at once; e.g. '/O2y-' for '/O2 /Oy-'">, - MetaVarName<"<flags>">; -def : CLFlag<"O1">, Alias<_SLASH_O>, AliasArgs<["1"]>, - HelpText<"Optimize for size (like /Og /Os /Oy /Ob2 /GF /Gy)">; -def : CLFlag<"O2">, Alias<_SLASH_O>, AliasArgs<["2"]>, - HelpText<"Optimize for speed (like /Og /Oi /Ot /Oy /Ob2 /GF /Gy)">; -def : CLFlag<"Ob0">, Alias<_SLASH_O>, AliasArgs<["b0"]>, - HelpText<"Disable function inlining">; -def : CLFlag<"Ob1">, Alias<_SLASH_O>, AliasArgs<["b1"]>, - HelpText<"Only inline functions explicitly or implicitly marked inline">; -def : CLFlag<"Ob2">, Alias<_SLASH_O>, AliasArgs<["b2"]>, - HelpText<"Inline functions as deemed beneficial by the compiler">; -def : CLFlag<"Od">, Alias<_SLASH_O>, AliasArgs<["d"]>, - HelpText<"Disable optimization">; -def : CLFlag<"Og">, Alias<_SLASH_O>, AliasArgs<["g"]>, - HelpText<"No effect">; -def : CLFlag<"Oi">, Alias<_SLASH_O>, AliasArgs<["i"]>, - HelpText<"Enable use of builtin functions">; -def : CLFlag<"Oi-">, Alias<_SLASH_O>, AliasArgs<["i-"]>, - HelpText<"Disable use of builtin functions">; -def : CLFlag<"Os">, Alias<_SLASH_O>, AliasArgs<["s"]>, - HelpText<"Optimize for size">; -def : CLFlag<"Ot">, Alias<_SLASH_O>, AliasArgs<["t"]>, - HelpText<"Optimize for speed">; -def : CLFlag<"Ox">, Alias<_SLASH_O>, AliasArgs<["x"]>, - HelpText<"Deprecated (like /Og /Oi /Ot /Oy /Ob2); use /O2">; -def : CLFlag<"Oy">, Alias<_SLASH_O>, AliasArgs<["y"]>, - HelpText<"Enable frame pointer omission (x86 only)">; -def : CLFlag<"Oy-">, Alias<_SLASH_O>, AliasArgs<["y-"]>, - HelpText<"Disable frame pointer omission (x86 only, default)">; - -def _SLASH_QUESTION : CLFlag<"?">, Alias<help>, - HelpText<"Display available options">; -def _SLASH_Qvec : CLFlag<"Qvec">, - HelpText<"Enable the loop vectorization passes">, Alias<fvectorize>; -def _SLASH_Qvec_ : CLFlag<"Qvec-">, - HelpText<"Disable the loop vectorization passes">, Alias<fno_vectorize>; -def _SLASH_showIncludes : CLFlag<"showIncludes">, - HelpText<"Print info about included files to stderr">, - Alias<show_includes>; -def _SLASH_showFilenames : CLFlag<"showFilenames">, - HelpText<"Print the name of each compiled file">; -def _SLASH_showFilenames_ : CLFlag<"showFilenames-">, - HelpText<"Do not print the name of each compiled file (default)">; -def _SLASH_source_charset : CLCompileJoined<"source-charset:">, - HelpText<"Set source encoding, supports only UTF-8">, - Alias<finput_charset_EQ>; -def _SLASH_execution_charset : CLCompileJoined<"execution-charset:">, - HelpText<"Set runtime encoding, supports only UTF-8">, - Alias<fexec_charset_EQ>; -def _SLASH_std : CLCompileJoined<"std:">, - HelpText<"Set C++ version (c++14,c++17,c++latest)">; -def _SLASH_U : CLJoinedOrSeparate<"U">, HelpText<"Undefine macro">, - MetaVarName<"<macro>">, Alias<U>; -def _SLASH_validate_charset : CLFlag<"validate-charset">, - Alias<W_Joined>, AliasArgs<["invalid-source-encoding"]>; -def _SLASH_validate_charset_ : CLFlag<"validate-charset-">, - Alias<W_Joined>, AliasArgs<["no-invalid-source-encoding"]>; -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 and -Wextra">, Alias<WCL4>; -def _SLASH_Wall : CLFlag<"Wall">, HelpText<"Enable -Weverything">, - Alias<W_Joined>, AliasArgs<["everything"]>; -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 (default)">, - Alias<W_Joined>, AliasArgs<["no-error"]>; -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_wd4018 : CLFlag<"wd4018">, Alias<W_Joined>, - AliasArgs<["no-sign-compare"]>; -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_X : CLFlag<"X">, - HelpText<"Do not add %INCLUDE% to include search path">, Alias<nostdlibinc>; -def _SLASH_Zc_sizedDealloc : CLFlag<"Zc:sizedDealloc">, - HelpText<"Enable C++14 sized global deallocation functions">, - Alias<fsized_deallocation>; -def _SLASH_Zc_sizedDealloc_ : CLFlag<"Zc:sizedDealloc-">, - HelpText<"Disable C++14 sized global deallocation functions">, - Alias<fno_sized_deallocation>; -def _SLASH_Zc_alignedNew : CLFlag<"Zc:alignedNew">, - HelpText<"Enable C++17 aligned allocation functions">, - Alias<faligned_allocation>; -def _SLASH_Zc_alignedNew_ : CLFlag<"Zc:alignedNew-">, - HelpText<"Disable C++17 aligned allocation functions">, - Alias<fno_aligned_allocation>; -def _SLASH_Zc_char8_t : CLFlag<"Zc:char8_t">, - HelpText<"Enable char8_t from C++2a">, - Alias<fchar8__t>; -def _SLASH_Zc_char8_t_ : CLFlag<"Zc:char8_t-">, - HelpText<"Disable char8_t from c++2a">, - Alias<fno_char8__t>; -def _SLASH_Zc_strictStrings : CLFlag<"Zc:strictStrings">, - HelpText<"Treat string literals as const">, Alias<W_Joined>, - AliasArgs<["error=c++11-compat-deprecated-writable-strings"]>; -def _SLASH_Zc_threadSafeInit : CLFlag<"Zc:threadSafeInit">, - HelpText<"Enable thread-safe initialization of static variables">, - Alias<fthreadsafe_statics>; -def _SLASH_Zc_threadSafeInit_ : CLFlag<"Zc:threadSafeInit-">, - HelpText<"Disable thread-safe initialization of static variables">, - Alias<fno_threadsafe_statics>; -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_Zc_twoPhase : CLFlag<"Zc:twoPhase">, - HelpText<"Enable two-phase name lookup in templates">, - Alias<fno_delayed_template_parsing>; -def _SLASH_Zc_twoPhase_ : CLFlag<"Zc:twoPhase-">, - HelpText<"Disable two-phase name lookup in templates (default)">, - Alias<fdelayed_template_parsing>; -def _SLASH_Z7 : CLFlag<"Z7">, - HelpText<"Enable CodeView debug information in object files">; -def _SLASH_Zd : CLFlag<"Zd">, - HelpText<"Emit debug line number tables only">; -def _SLASH_Zi : CLFlag<"Zi">, Alias<_SLASH_Z7>, - HelpText<"Like /Z7">; -def _SLASH_Zp : CLJoined<"Zp">, - HelpText<"Set default maximum struct packing alignment">, - Alias<fpack_struct_EQ>; -def _SLASH_Zp_flag : CLFlag<"Zp">, - HelpText<"Set default maximum struct packing alignment to 1">, - Alias<fpack_struct_EQ>, AliasArgs<["1"]>; -def _SLASH_Zs : CLFlag<"Zs">, HelpText<"Syntax-check only">, - Alias<fsyntax_only>; -def _SLASH_openmp_ : CLFlag<"openmp-">, - HelpText<"Disable OpenMP support">, Alias<fno_openmp>; -def _SLASH_openmp : CLFlag<"openmp">, HelpText<"Enable OpenMP support">, - Alias<fopenmp>; -def _SLASH_openmp_experimental : CLFlag<"openmp:experimental">, - HelpText<"Enable OpenMP support with experimental SIMD support">, - Alias<fopenmp>; - -// Non-aliases: - -def _SLASH_arch : CLCompileJoined<"arch:">, - HelpText<"Set architecture for code generation">; - -def _SLASH_M_Group : OptionGroup<"</M group>">, Group<cl_compile_Group>; -def _SLASH_volatile_Group : OptionGroup<"</volatile group>">, - Group<cl_compile_Group>; - -def _SLASH_EH : CLJoined<"EH">, HelpText<"Set exception handling model">; -def _SLASH_EP : CLFlag<"EP">, - HelpText<"Disable linemarker output and preprocess to stdout">; -def _SLASH_FA : CLFlag<"FA">, - HelpText<"Output assembly code file during compilation">; -def _SLASH_Fa : CLJoined<"Fa">, - HelpText<"Set assembly output file name (with /FA)">, - MetaVarName<"<file or dir/>">; -def _SLASH_fallback : CLCompileFlag<"fallback">, - HelpText<"Fall back to cl.exe if clang-cl fails to compile">; -def _SLASH_FI : CLJoinedOrSeparate<"FI">, - HelpText<"Include file before parsing">, Alias<include_>; -def _SLASH_Fe : CLJoined<"Fe">, - HelpText<"Set output executable file name">, - MetaVarName<"<file or dir/>">; -def _SLASH_Fi : CLCompileJoined<"Fi">, - HelpText<"Set preprocess output file name (with /P)">, - MetaVarName<"<file>">; -def _SLASH_Fo : CLCompileJoined<"Fo">, - HelpText<"Set output object file (with /c)">, - MetaVarName<"<file or dir/>">; -def _SLASH_guard : CLJoined<"guard:">, - HelpText<"Enable Control Flow Guard with /guard:cf, or only the table with /guard:cf,nochecks">; -def _SLASH_GX : CLFlag<"GX">, - HelpText<"Deprecated; use /EHsc">; -def _SLASH_GX_ : CLFlag<"GX-">, - HelpText<"Deprecated (like not passing /EH)">; -def _SLASH_imsvc : CLJoinedOrSeparate<"imsvc">, - HelpText<"Add <dir> to system include search path, as if in %INCLUDE%">, - MetaVarName<"<dir>">; -def _SLASH_LD : CLFlag<"LD">, HelpText<"Create DLL">; -def _SLASH_LDd : CLFlag<"LDd">, HelpText<"Create debug DLL">; -def _SLASH_link : CLRemainingArgsJoined<"link">, - HelpText<"Forward options to the linker">, MetaVarName<"<options>">; -def _SLASH_MD : Option<["/", "-"], "MD", KIND_FLAG>, Group<_SLASH_M_Group>, - Flags<[CLOption, DriverOption]>, HelpText<"Use DLL run-time">; -def _SLASH_MDd : Option<["/", "-"], "MDd", KIND_FLAG>, Group<_SLASH_M_Group>, - Flags<[CLOption, DriverOption]>, HelpText<"Use DLL debug run-time">; -def _SLASH_MT : Option<["/", "-"], "MT", KIND_FLAG>, Group<_SLASH_M_Group>, - Flags<[CLOption, DriverOption]>, HelpText<"Use static run-time">; -def _SLASH_MTd : Option<["/", "-"], "MTd", KIND_FLAG>, Group<_SLASH_M_Group>, - Flags<[CLOption, DriverOption]>, HelpText<"Use static debug run-time">; -def _SLASH_o : CLJoinedOrSeparate<"o">, - HelpText<"Deprecated (set output file name); use /Fe or /Fe">, - MetaVarName<"<file or dir/>">; -def _SLASH_P : CLFlag<"P">, HelpText<"Preprocess to file">; -def _SLASH_Tc : CLCompileJoinedOrSeparate<"Tc">, - HelpText<"Treat <file> as C source file">, MetaVarName<"<file>">; -def _SLASH_TC : CLCompileFlag<"TC">, HelpText<"Treat all source files as C">; -def _SLASH_Tp : CLCompileJoinedOrSeparate<"Tp">, - HelpText<"Treat <file> as C++ source file">, MetaVarName<"<file>">; -def _SLASH_TP : CLCompileFlag<"TP">, HelpText<"Treat all source files as C++">; -def _SLASH_volatile_iso : Option<["/", "-"], "volatile:iso", KIND_FLAG>, - Group<_SLASH_volatile_Group>, Flags<[CLOption, DriverOption]>, - HelpText<"Volatile loads and stores have standard semantics">; -def _SLASH_vmb : CLFlag<"vmb">, - HelpText<"Use a best-case representation method for member pointers">; -def _SLASH_vmg : CLFlag<"vmg">, - HelpText<"Use a most-general representation for member pointers">; -def _SLASH_vms : CLFlag<"vms">, - HelpText<"Set the default most-general representation to single inheritance">; -def _SLASH_vmm : CLFlag<"vmm">, - HelpText<"Set the default most-general representation to " - "multiple inheritance">; -def _SLASH_vmv : CLFlag<"vmv">, - HelpText<"Set the default most-general representation to " - "virtual inheritance">; -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_clang : CLJoined<"clang:">, - HelpText<"Pass <arg> to the clang driver">, MetaVarName<"<arg>">; -def _SLASH_Zl : CLFlag<"Zl">, - HelpText<"Do not let object file auto-link default libraries">; - -def _SLASH_Yc : CLJoined<"Yc">, - HelpText<"Generate a pch file for all code up to and including <filename>">, - MetaVarName<"<filename>">; -def _SLASH_Yu : CLJoined<"Yu">, - HelpText<"Load a pch file and use it instead of all code up to " - "and including <filename>">, - MetaVarName<"<filename>">; -def _SLASH_Y_ : CLFlag<"Y-">, - HelpText<"Disable precompiled headers, overrides /Yc and /Yu">; -def _SLASH_Zc_dllexportInlines : CLFlag<"Zc:dllexportInlines">, - HelpText<"dllexport/dllimport inline member functions of dllexport/import classes (default)">; -def _SLASH_Zc_dllexportInlines_ : CLFlag<"Zc:dllexportInlines-">, - HelpText<"Do not dllexport/dllimport inline member functions of dllexport/import classes">; -def _SLASH_Fp : CLJoined<"Fp">, - HelpText<"Set pch file name (with /Yc and /Yu)">, MetaVarName<"<file>">; - -def _SLASH_Gd : CLFlag<"Gd">, - HelpText<"Set __cdecl as a default calling convention">; -def _SLASH_Gr : CLFlag<"Gr">, - HelpText<"Set __fastcall as a default calling convention">; -def _SLASH_Gz : CLFlag<"Gz">, - HelpText<"Set __stdcall as a default calling convention">; -def _SLASH_Gv : CLFlag<"Gv">, - HelpText<"Set __vectorcall as a default calling convention">; -def _SLASH_Gregcall : CLFlag<"Gregcall">, - HelpText<"Set __regcall as a default calling convention">; - -// Ignored: - -def _SLASH_analyze_ : CLIgnoredFlag<"analyze-">; -def _SLASH_bigobj : CLIgnoredFlag<"bigobj">; -def _SLASH_cgthreads : CLIgnoredJoined<"cgthreads">; -def _SLASH_d2FastFail : CLIgnoredFlag<"d2FastFail">; -def _SLASH_d2Zi_PLUS : CLIgnoredFlag<"d2Zi+">; -def _SLASH_errorReport : CLIgnoredJoined<"errorReport">; -def _SLASH_FC : CLIgnoredFlag<"FC">; -def _SLASH_Fd : CLIgnoredJoined<"Fd">; -def _SLASH_FS : CLIgnoredFlag<"FS">; -def _SLASH_JMC : CLIgnoredFlag<"JMC">; -def _SLASH_kernel_ : CLIgnoredFlag<"kernel-">; -def _SLASH_nologo : CLIgnoredFlag<"nologo">; -def _SLASH_permissive_ : CLIgnoredFlag<"permissive-">; -def _SLASH_RTC : CLIgnoredJoined<"RTC">; -def _SLASH_sdl : CLIgnoredFlag<"sdl">; -def _SLASH_sdl_ : CLIgnoredFlag<"sdl-">; -def _SLASH_utf8 : CLIgnoredFlag<"utf-8">, - HelpText<"Set source and runtime encoding to UTF-8 (default)">; -def _SLASH_w : CLIgnoredJoined<"w">; -def _SLASH_Zc___cplusplus : CLIgnoredFlag<"Zc:__cplusplus">; -def _SLASH_Zc_auto : CLIgnoredFlag<"Zc:auto">; -def _SLASH_Zc_forScope : CLIgnoredFlag<"Zc:forScope">; -def _SLASH_Zc_inline : CLIgnoredFlag<"Zc:inline">; -def _SLASH_Zc_rvalueCast : CLIgnoredFlag<"Zc:rvalueCast">; -def _SLASH_Zc_ternary : CLIgnoredFlag<"Zc:ternary">; -def _SLASH_Zc_wchar_t : CLIgnoredFlag<"Zc:wchar_t">; -def _SLASH_ZH_MD5 : CLIgnoredFlag<"ZH:MD5">; -def _SLASH_ZH_SHA1 : CLIgnoredFlag<"ZH:SHA1">; -def _SLASH_ZH_SHA_256 : CLIgnoredFlag<"ZH:SHA_256">; -def _SLASH_Zm : CLIgnoredJoined<"Zm">; -def _SLASH_Zo : CLIgnoredFlag<"Zo">; -def _SLASH_Zo_ : CLIgnoredFlag<"Zo-">; - - -// Unsupported: - -def _SLASH_await : CLFlag<"await">; -def _SLASH_constexpr : CLJoined<"constexpr:">; -def _SLASH_AI : CLJoinedOrSeparate<"AI">; -def _SLASH_Bt : CLFlag<"Bt">; -def _SLASH_Bt_plus : CLFlag<"Bt+">; -def _SLASH_clr : CLJoined<"clr">; -def _SLASH_d2 : CLJoined<"d2">; -def _SLASH_doc : CLJoined<"doc">; -def _SLASH_FA_joined : CLJoined<"FA">; -def _SLASH_favor : CLJoined<"favor">; -def _SLASH_F : CLJoinedOrSeparate<"F">; -def _SLASH_Fm : CLJoined<"Fm">; -def _SLASH_Fr : CLJoined<"Fr">; -def _SLASH_FR : CLJoined<"FR">; -def _SLASH_FU : CLJoinedOrSeparate<"FU">; -def _SLASH_Fx : CLFlag<"Fx">; -def _SLASH_G1 : CLFlag<"G1">; -def _SLASH_G2 : CLFlag<"G2">; -def _SLASH_Ge : CLFlag<"Ge">; -def _SLASH_Gh : CLFlag<"Gh">; -def _SLASH_GH : CLFlag<"GH">; -def _SLASH_GL : CLFlag<"GL">; -def _SLASH_GL_ : CLFlag<"GL-">; -def _SLASH_Gm : CLFlag<"Gm">; -def _SLASH_Gm_ : CLFlag<"Gm-">; -def _SLASH_GT : CLFlag<"GT">; -def _SLASH_GZ : CLFlag<"GZ">; -def _SLASH_H : CLFlag<"H">; -def _SLASH_homeparams : CLFlag<"homeparams">; -def _SLASH_hotpatch : CLFlag<"hotpatch">; -def _SLASH_kernel : CLFlag<"kernel">; -def _SLASH_LN : CLFlag<"LN">; -def _SLASH_MP : CLJoined<"MP">; -def _SLASH_Qfast_transcendentals : CLFlag<"Qfast_transcendentals">; -def _SLASH_QIfist : CLFlag<"QIfist">; -def _SLASH_Qimprecise_fwaits : CLFlag<"Qimprecise_fwaits">; -def _SLASH_Qpar : CLFlag<"Qpar">; -def _SLASH_Qpar_report : CLJoined<"Qpar-report">; -def _SLASH_Qsafe_fp_loads : CLFlag<"Qsafe_fp_loads">; -def _SLASH_Qspectre : CLFlag<"Qspectre">; -def _SLASH_Qvec_report : CLJoined<"Qvec-report">; -def _SLASH_u : CLFlag<"u">; -def _SLASH_V : CLFlag<"V">; -def _SLASH_WL : CLFlag<"WL">; -def _SLASH_Wp64 : CLFlag<"Wp64">; -def _SLASH_Yd : CLFlag<"Yd">; -def _SLASH_Yl : CLJoined<"Yl">; -def _SLASH_Za : CLFlag<"Za">; -def _SLASH_Zc : CLJoined<"Zc:">; -def _SLASH_Ze : CLFlag<"Ze">; -def _SLASH_Zg : CLFlag<"Zg">; -def _SLASH_ZI : CLFlag<"ZI">; -def _SLASH_ZW : CLJoined<"ZW">; diff --git a/clang/include/clang/Driver/Distro.h b/clang/include/clang/Driver/Distro.h index d382cf77a8b2..038d4ce75d80 100644 --- a/clang/include/clang/Driver/Distro.h +++ b/clang/include/clang/Driver/Distro.h @@ -67,6 +67,7 @@ public: UbuntuDisco, UbuntuEoan, UbuntuFocal, + UbuntuGroovy, UnknownDistro }; @@ -120,7 +121,7 @@ public: } bool IsUbuntu() const { - return DistroVal >= UbuntuHardy && DistroVal <= UbuntuFocal; + return DistroVal >= UbuntuHardy && DistroVal <= UbuntuGroovy; } bool IsAlpineLinux() const { diff --git a/clang/include/clang/Driver/Driver.h b/clang/include/clang/Driver/Driver.h index fd25663bd358..dc18f1314f81 100644 --- a/clang/include/clang/Driver/Driver.h +++ b/clang/include/clang/Driver/Driver.h @@ -208,7 +208,7 @@ public: /// When the clangDriver lib is used through clang.exe, this provides a /// shortcut for executing the -cc1 command-line directly, in the same /// process. - typedef int (*CC1ToolFunc)(ArrayRef<const char *> argv); + typedef int (*CC1ToolFunc)(SmallVectorImpl<const char *> &ArgV); CC1ToolFunc CC1Main = nullptr; private: @@ -340,9 +340,7 @@ public: return InstalledDir.c_str(); return Dir.c_str(); } - void setInstalledDir(StringRef Value) { - InstalledDir = Value; - } + void setInstalledDir(StringRef Value) { InstalledDir = std::string(Value); } bool isSaveTempsEnabled() const { return SaveTemps != SaveTempsNone; } bool isSaveTempsObj() const { return SaveTemps == SaveTempsObj; } @@ -550,6 +548,9 @@ public: /// handle this action. bool ShouldUseFlangCompiler(const JobAction &JA) const; + /// ShouldEmitStaticLibrary - Should the linker emit a static library. + bool ShouldEmitStaticLibrary(const llvm::opt::ArgList &Args) const; + /// Returns true if we are performing any kind of LTO. bool isUsingLTO() const { return LTOMode != LTOK_None; } @@ -620,7 +621,8 @@ public: static bool GetReleaseVersion(StringRef Str, MutableArrayRef<unsigned> Digits); /// Compute the default -fmodule-cache-path. - static void getDefaultModuleCachePath(SmallVectorImpl<char> &Result); + /// \return True if the system provides a default cache directory. + static bool getDefaultModuleCachePath(SmallVectorImpl<char> &Result); }; /// \return True if the last defined optimization level is -Ofast. diff --git a/clang/include/clang/Driver/Job.h b/clang/include/clang/Driver/Job.h index 0765b3c67d4e..6173b9d314b4 100644 --- a/clang/include/clang/Driver/Job.h +++ b/clang/include/clang/Driver/Job.h @@ -16,6 +16,7 @@ #include "llvm/ADT/StringRef.h" #include "llvm/ADT/iterator.h" #include "llvm/Option/Option.h" +#include "llvm/Support/Program.h" #include <memory> #include <string> #include <utility> @@ -36,6 +37,69 @@ struct CrashReportInfo { : Filename(Filename), VFSPath(VFSPath) {} }; +// Encodes the kind of response file supported for a command invocation. +// Response files are necessary if the command line gets too large, requiring +// the arguments to be transferred to a file. +struct ResponseFileSupport { + enum ResponseFileKind { + // Provides full support for response files, which means we can transfer + // all tool input arguments to a file. + RF_Full, + // Input file names can live in a file, but flags can't. This is a special + // case for old versions of Apple's ld64. + RF_FileList, + // Does not support response files: all arguments must be passed via + // command line. + RF_None + }; + /// The level of support for response files. + ResponseFileKind ResponseKind; + + /// The encoding to use when writing response files on Windows. Ignored on + /// other host OSes. + /// + /// Windows use cases: - GCC and Binutils on mingw only accept ANSI response + /// files encoded with the system current code page. + /// - MSVC's CL.exe and LINK.exe accept UTF16 on Windows. + /// - Clang accepts both UTF8 and UTF16. + /// + /// FIXME: When GNU tools learn how to parse UTF16 on Windows, we should + /// always use UTF16 for Windows, which is the Windows official encoding for + /// international characters. + llvm::sys::WindowsEncodingMethod ResponseEncoding; + + /// What prefix to use for the command-line argument when passing a response + /// file. + const char *ResponseFlag; + + /// Returns a ResponseFileSupport indicating that response files are not + /// supported. + static constexpr ResponseFileSupport None() { + return {RF_None, llvm::sys::WEM_UTF8, nullptr}; + } + + /// Returns a ResponseFileSupport indicating that response files are + /// supported, using the @file syntax. On windows, the file is written in the + /// UTF8 encoding. On other OSes, no re-encoding occurs. + static constexpr ResponseFileSupport AtFileUTF8() { + return {RF_Full, llvm::sys::WEM_UTF8, "@"}; + } + + /// Returns a ResponseFileSupport indicating that response files are + /// supported, using the @file syntax. On windows, the file is written in the + /// current ANSI code-page encoding. On other OSes, no re-encoding occurs. + static constexpr ResponseFileSupport AtFileCurCP() { + return {RF_Full, llvm::sys::WEM_CurrentCodePage, "@"}; + } + + /// Returns a ResponseFileSupport indicating that response files are + /// supported, using the @file syntax. On windows, the file is written in the + /// UTF-16 encoding. On other OSes, no re-encoding occurs. + static constexpr ResponseFileSupport AtFileUTF16() { + return {RF_Full, llvm::sys::WEM_UTF16, "@"}; + } +}; + /// Command - An executable path/name and argument vector to /// execute. class Command { @@ -45,6 +109,9 @@ class Command { /// Tool - The tool which caused the creation of this job. const Tool &Creator; + /// Whether and how to generate response files if the arguments are too long. + ResponseFileSupport ResponseSupport; + /// The executable to run. const char *Executable; @@ -55,9 +122,6 @@ class Command { /// The list of program arguments which are inputs. llvm::opt::ArgStringList InputFilenames; - /// Whether to print the input filenames when executing. - bool PrintInputFilenames = false; - /// Response file name, if this command is set to use one, or nullptr /// otherwise const char *ResponseFile = nullptr; @@ -86,7 +150,14 @@ class Command { void writeResponseFile(raw_ostream &OS) const; public: - Command(const Action &Source, const Tool &Creator, const char *Executable, + /// Whether to print the input filenames when executing. + bool PrintInputFilenames = false; + + /// Whether the command will be executed in this process or not. + bool InProcess = false; + + Command(const Action &Source, const Tool &Creator, + ResponseFileSupport ResponseSupport, const char *Executable, const llvm::opt::ArgStringList &Arguments, ArrayRef<InputInfo> Inputs); // FIXME: This really shouldn't be copyable, but is currently copied in some @@ -106,11 +177,16 @@ public: /// getCreator - Return the Tool which caused the creation of this job. const Tool &getCreator() const { return Creator; } + /// Returns the kind of response file supported by the current invocation. + const ResponseFileSupport &getResponseFileSupport() { + return ResponseSupport; + } + /// Set to pass arguments via a response file when launching the command void setResponseFile(const char *FileName); - /// Set an input file list, necessary if we need to use a response file but - /// the tool being called only supports input files lists. + /// Set an input file list, necessary if you specified an RF_FileList response + /// file support. void setInputFileList(llvm::opt::ArgStringList List) { InputFileList = std::move(List); } @@ -125,12 +201,6 @@ public: const llvm::opt::ArgStringList &getArguments() const { return Arguments; } - /// Print a command argument, and optionally quote it. - static void printArg(llvm::raw_ostream &OS, StringRef Arg, bool Quote); - - /// Set whether to print the input filenames when executing. - void setPrintInputFilenames(bool P) { PrintInputFilenames = P; } - protected: /// Optionally print the filenames to be compiled void PrintFileNames() const; @@ -139,7 +209,10 @@ protected: /// Use the CC1 tool callback when available, to avoid creating a new process class CC1Command : public Command { public: - using Command::Command; + CC1Command(const Action &Source, const Tool &Creator, + ResponseFileSupport ResponseSupport, const char *Executable, + const llvm::opt::ArgStringList &Arguments, + ArrayRef<InputInfo> Inputs); void Print(llvm::raw_ostream &OS, const char *Terminator, bool Quote, CrashReportInfo *CrashInfo = nullptr) const override; @@ -155,7 +228,7 @@ public: class FallbackCommand : public Command { public: FallbackCommand(const Action &Source_, const Tool &Creator_, - const char *Executable_, + ResponseFileSupport ResponseSupport, const char *Executable_, const llvm::opt::ArgStringList &Arguments_, ArrayRef<InputInfo> Inputs, std::unique_ptr<Command> Fallback_); @@ -174,6 +247,7 @@ private: class ForceSuccessCommand : public Command { public: ForceSuccessCommand(const Action &Source_, const Tool &Creator_, + ResponseFileSupport ResponseSupport, const char *Executable_, const llvm::opt::ArgStringList &Arguments_, ArrayRef<InputInfo> Inputs); diff --git a/clang/include/clang/Driver/Multilib.h b/clang/include/clang/Driver/Multilib.h index abf0d5fa6ea2..cf2dbf6ff58a 100644 --- a/clang/include/clang/Driver/Multilib.h +++ b/clang/include/clang/Driver/Multilib.h @@ -91,7 +91,7 @@ public: /// otherwise '-print-multi-lib' will not emit them correctly. Multilib &flag(StringRef F) { assert(F.front() == '+' || F.front() == '-'); - Flags.push_back(F); + Flags.push_back(std::string(F)); return *this; } diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 1218172fd5b6..f4556c15d744 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -124,6 +124,9 @@ def pedantic_Group : OptionGroup<"<pedantic group>">, Group<f_Group>, def opencl_Group : OptionGroup<"<opencl group>">, Group<f_Group>, DocName<"OpenCL flags">; +def sycl_Group : OptionGroup<"<SYCL group>">, Group<f_Group>, + DocName<"SYCL flags">; + def m_Group : OptionGroup<"<m group>">, Group<CompileOnly_Group>, DocName<"Target-dependent compilation options">; @@ -148,6 +151,10 @@ def m_ppc_Features_Group : OptionGroup<"<ppc features group>">, Group<m_Group>, DocName<"PowerPC">; def m_wasm_Features_Group : OptionGroup<"<wasm features group>">, Group<m_Group>, DocName<"WebAssembly">; +// The features added by this group will not be added to target features. +// These are explicitly handled. +def m_wasm_Features_Driver_Group : OptionGroup<"<wasm driver features group>">, + Group<m_Group>, DocName<"WebAssembly Driver">; def m_x86_Features_Group : OptionGroup<"<x86 features group>">, Group<m_Group>, Flags<[CoreOption]>, DocName<"X86">; def m_riscv_Features_Group : OptionGroup<"<riscv features group>">, @@ -219,6 +226,27 @@ def mno_mpx : Flag<["-"], "mno-mpx">, Group<clang_ignored_legacy_options_Group>; def clang_ignored_gcc_optimization_f_Group : OptionGroup< "<clang_ignored_gcc_optimization_f_Group>">, Group<f_Group>, Flags<[Ignored]>; +// A boolean option which is opt-in in CC1. The positive option exists in CC1 and +// Args.hasArg(OPT_ffoo) is used to check that the flag is enabled. +// This is useful if the option is usually disabled. +multiclass OptInFFlag<string name, string pos_prefix, string neg_prefix="", + string help="", list<OptionFlag> flags=[]> { + def f#NAME : Flag<["-"], "f"#name>, Flags<!listconcat([CC1Option], flags)>, + Group<f_Group>, HelpText<!strconcat(pos_prefix, help)>; + def fno_#NAME : Flag<["-"], "fno-"#name>, Flags<flags>, + Group<f_Group>, HelpText<!strconcat(neg_prefix, help)>; +} + +// A boolean option which is opt-out in CC1. The negative option exists in CC1 and +// Args.hasArg(OPT_fno_foo) is used to check that the flag is disabled. +multiclass OptOutFFlag<string name, string pos_prefix, string neg_prefix, + string help="", list<OptionFlag> flags=[]> { + def f#NAME : Flag<["-"], "f"#name>, Flags<flags>, + Group<f_Group>, HelpText<!strconcat(pos_prefix, help)>; + def fno_#NAME : Flag<["-"], "fno-"#name>, Flags<!listconcat([CC1Option], flags)>, + Group<f_Group>, HelpText<!strconcat(neg_prefix, help)>; +} + ///////// // Options @@ -397,7 +425,7 @@ def ObjCXX : Flag<["-"], "ObjC++">, Flags<[DriverOption]>, def ObjC : Flag<["-"], "ObjC">, Flags<[DriverOption]>, HelpText<"Treat source input files as Objective-C inputs">; def O : Joined<["-"], "O">, Group<O_Group>, Flags<[CC1Option]>; -def O_flag : Flag<["-"], "O">, Flags<[CC1Option]>, Alias<O>, AliasArgs<["2"]>; +def O_flag : Flag<["-"], "O">, Flags<[CC1Option]>, Alias<O>, AliasArgs<["1"]>; def Ofast : Joined<["-"], "Ofast">, Group<O_Group>, Flags<[CC1Option]>; def P : Flag<["-"], "P">, Flags<[CC1Option]>, Group<Preprocessor_Group>, HelpText<"Disable linemarker output in -E mode">; @@ -455,6 +483,9 @@ def Wnonportable_cfstrings : Joined<["-"], "Wnonportable-cfstrings">, Group<W_Gr def Wp_COMMA : CommaJoined<["-"], "Wp,">, HelpText<"Pass the comma separated arguments in <arg> to the preprocessor">, MetaVarName<"<arg>">, Group<Preprocessor_Group>; +def Wundef_prefix_EQ : CommaJoined<["-"], "Wundef-prefix=">, Group<W_value_Group>, + Flags<[CC1Option, CoreOption, HelpHidden]>, MetaVarName<"<arg>">, + HelpText<"Enable warnings for undefined macros with a prefix in the comma separated list <arg>">; def Wwrite_strings : Flag<["-"], "Wwrite-strings">, Group<W_Group>, Flags<[CC1Option, HelpHidden]>; def Wno_write_strings : Flag<["-"], "Wno-write-strings">, Group<W_Group>, Flags<[CC1Option, HelpHidden]>; def W_Joined : Joined<["-"], "W">, Group<W_Group>, Flags<[CC1Option, CoreOption]>, @@ -463,6 +494,10 @@ def Xanalyzer : Separate<["-"], "Xanalyzer">, HelpText<"Pass <arg> to the static analyzer">, MetaVarName<"<arg>">, Group<StaticAnalyzer_Group>; def Xarch__ : JoinedAndSeparate<["-"], "Xarch_">, Flags<[DriverOption]>; +def Xarch_host : Separate<["-"], "Xarch_host">, Flags<[DriverOption]>, + HelpText<"Pass <arg> to the CUDA/HIP host compilation">, MetaVarName<"<arg>">; +def Xarch_device : Separate<["-"], "Xarch_device">, Flags<[DriverOption]>, + HelpText<"Pass <arg> to the CUDA/HIP device compilation">, MetaVarName<"<arg>">; def Xassembler : Separate<["-"], "Xassembler">, HelpText<"Pass <arg> to the assembler">, MetaVarName<"<arg>">, Group<CompileOnly_Group>; @@ -523,7 +558,7 @@ def cl_no_signed_zeros : Flag<["-"], "cl-no-signed-zeros">, Group<opencl_Group>, HelpText<"OpenCL only. Allow use of less precise no signed zeros computations in the generated binary.">; def cl_std_EQ : Joined<["-"], "cl-std=">, Group<opencl_Group>, Flags<[CC1Option]>, HelpText<"OpenCL language standard to compile for.">, Values<"cl,CL,cl1.1,CL1.1,cl1.2,CL1.2,cl2.0,CL2.0,clc++,CLC++">; -def cl_denorms_are_zero : Flag<["-"], "cl-denorms-are-zero">, Group<opencl_Group>, Flags<[CC1Option]>, +def cl_denorms_are_zero : Flag<["-"], "cl-denorms-are-zero">, Group<opencl_Group>, HelpText<"OpenCL only. Allow denormals to be flushed to zero.">; def cl_fp32_correctly_rounded_divide_sqrt : Flag<["-"], "cl-fp32-correctly-rounded-divide-sqrt">, Group<opencl_Group>, Flags<[CC1Option]>, HelpText<"OpenCL only. Specify that single precision floating-point divide and sqrt used in the program source are correctly rounded.">; @@ -549,6 +584,9 @@ def c : Flag<["-"], "c">, Flags<[DriverOption]>, Group<Action_Group>, def fconvergent_functions : Flag<["-"], "fconvergent-functions">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Assume functions may be convergent">; +def gpu_use_aux_triple_only : Flag<["--"], "gpu-use-aux-triple-only">, + InternalDriverOpt, HelpText<"Prepare '-aux-triple' only without populating " + "'-aux-target-cpu' and '-aux-target-feature'.">; def cuda_device_only : Flag<["--"], "cuda-device-only">, HelpText<"Compile CUDA code for device only">; def cuda_host_only : Flag<["--"], "cuda-host-only">, @@ -561,13 +599,19 @@ def cuda_include_ptx_EQ : Joined<["--"], "cuda-include-ptx=">, Flags<[DriverOpti HelpText<"Include PTX for the following GPU architecture (e.g. sm_35) or 'all'. May be specified more than once.">; def no_cuda_include_ptx_EQ : Joined<["--"], "no-cuda-include-ptx=">, Flags<[DriverOption]>, HelpText<"Do not include PTX for the following GPU architecture (e.g. sm_35) or 'all'. May be specified more than once.">; +def offload_arch_EQ : Joined<["--"], "offload-arch=">, Flags<[DriverOption]>, + HelpText<"CUDA/HIP offloading device architecture (e.g. sm_35, gfx906). May be specified more than once.">; def cuda_gpu_arch_EQ : Joined<["--"], "cuda-gpu-arch=">, Flags<[DriverOption]>, - HelpText<"CUDA GPU architecture (e.g. sm_35). May be specified more than once.">; + Alias<offload_arch_EQ>; def hip_link : Flag<["--"], "hip-link">, HelpText<"Link clang-offload-bundler bundles for HIP">; -def no_cuda_gpu_arch_EQ : Joined<["--"], "no-cuda-gpu-arch=">, Flags<[DriverOption]>, - HelpText<"Remove GPU architecture (e.g. sm_35) from the list of GPUs to compile for. " +def no_offload_arch_EQ : Joined<["--"], "no-offload-arch=">, Flags<[DriverOption]>, + HelpText<"Remove CUDA/HIP offloading device architecture (e.g. sm_35, gfx906) from the list of devices to compile for. " "'all' resets the list to its default value.">; +def emit_static_lib : Flag<["--"], "emit-static-lib">, + HelpText<"Enable linker job to emit a static library.">; +def no_cuda_gpu_arch_EQ : Joined<["--"], "no-cuda-gpu-arch=">, Flags<[DriverOption]>, + Alias<no_offload_arch_EQ>; def cuda_noopt_device_debug : Flag<["--"], "cuda-noopt-device-debug">, HelpText<"Enable device-side debug info generation. Disables ptxas optimizations.">; def no_cuda_version_check : Flag<["--"], "no-cuda-version-check">, @@ -581,31 +625,31 @@ def cuda_path_ignore_env : Flag<["--"], "cuda-path-ignore-env">, Group<i_Group>, def ptxas_path_EQ : Joined<["--"], "ptxas-path=">, Group<i_Group>, HelpText<"Path to ptxas (used for compiling CUDA code)">; def fcuda_flush_denormals_to_zero : Flag<["-"], "fcuda-flush-denormals-to-zero">, - Flags<[CC1Option]>, HelpText<"Flush denormal floating point values to zero in CUDA device mode.">; + HelpText<"Flush denormal floating point values to zero in CUDA device mode.">; def fno_cuda_flush_denormals_to_zero : Flag<["-"], "fno-cuda-flush-denormals-to-zero">; -def fcuda_approx_transcendentals : Flag<["-"], "fcuda-approx-transcendentals">, - Flags<[CC1Option]>, HelpText<"Use approximate transcendental functions">; -def fno_cuda_approx_transcendentals : Flag<["-"], "fno-cuda-approx-transcendentals">; -def fgpu_rdc : Flag<["-"], "fgpu-rdc">, Flags<[CC1Option]>, - HelpText<"Generate relocatable device code, also known as separate compilation mode.">; -def fno_gpu_rdc : Flag<["-"], "fno-gpu-rdc">; +defm cuda_approx_transcendentals : OptInFFlag<"cuda-approx-transcendentals", "Use", "Don't use", + " approximate transcendental functions">; +defm gpu_rdc : OptInFFlag<"gpu-rdc", + "Generate relocatable device code, also known as separate compilation mode", "", "">; def : Flag<["-"], "fcuda-rdc">, Alias<fgpu_rdc>; def : Flag<["-"], "fno-cuda-rdc">, Alias<fno_gpu_rdc>; -def fcuda_short_ptr : Flag<["-"], "fcuda-short-ptr">, Flags<[CC1Option]>, - HelpText<"Use 32-bit pointers for accessing const/local/shared address spaces.">; -def fno_cuda_short_ptr : Flag<["-"], "fno-cuda-short-ptr">; -def hip_device_lib_path_EQ : Joined<["--"], "hip-device-lib-path=">, Group<Link_Group>, - HelpText<"HIP device library path">; +defm cuda_short_ptr : OptInFFlag<"cuda-short-ptr", + "Use 32-bit pointers for accessing const/local/shared address spaces">; +def rocm_path_EQ : Joined<["--"], "rocm-path=">, Group<i_Group>, + HelpText<"ROCm installation path, used for finding and automatically linking required bitcode libraries.">; +def rocm_device_lib_path_EQ : Joined<["--"], "rocm-device-lib-path=">, Group<Link_Group>, + HelpText<"ROCm device library path. Alternative to rocm-path.">; +def : Joined<["--"], "hip-device-lib-path=">, Alias<rocm_device_lib_path_EQ>; def hip_device_lib_EQ : Joined<["--"], "hip-device-lib=">, Group<Link_Group>, HelpText<"HIP device library">; +def hip_version_EQ : Joined<["--"], "hip-version=">, + HelpText<"HIP version in the format of major.minor.patch">; def fhip_dump_offload_linker_script : Flag<["-"], "fhip-dump-offload-linker-script">, Group<f_Group>, Flags<[NoArgumentUnused, HelpHidden]>; -def fhip_new_launch_api : Flag<["-"], "fhip-new-launch-api">, - Flags<[CC1Option]>, HelpText<"Use new kernel launching API for HIP.">; -def fno_hip_new_launch_api : Flag<["-"], "fno-hip-new-launch-api">; -def fgpu_allow_device_init : Flag<["-"], "fgpu-allow-device-init">, - Flags<[CC1Option]>, HelpText<"Allow device side init function in HIP">; -def fno_gpu_allow_device_init : Flag<["-"], "fno-gpu-allow-device-init">; +defm hip_new_launch_api : OptInFFlag<"hip-new-launch-api", + "Use", "Don't use", " new kernel launching API for HIP">; +defm gpu_allow_device_init : OptInFFlag<"gpu-allow-device-init", + "Allow", "Don't allow", " device side init function in HIP">; def gpu_max_threads_per_block_EQ : Joined<["--"], "gpu-max-threads-per-block=">, Flags<[CC1Option]>, HelpText<"Default max threads per block for kernel launch bounds for HIP">; @@ -646,14 +690,17 @@ def emit_merged_ifs : Flag<["-"], "emit-merged-ifs">, def interface_stub_version_EQ : JoinedOrSeparate<["-"], "interface-stub-version=">, Flags<[CC1Option]>; def exported__symbols__list : Separate<["-"], "exported_symbols_list">; def e : JoinedOrSeparate<["-"], "e">, Group<Link_Group>; +def fmax_tokens_EQ : Joined<["-"], "fmax-tokens=">, Group<f_Group>, Flags<[CC1Option]>, + HelpText<"Max total number of preprocessed tokens for -Wmax-tokens.">; 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 faccess_control : Flag<["-"], "faccess-control">, Group<f_Group>; +defm access_control : OptOutFFlag<"no-access-control", "", "Disable C++ access control">; def falign_functions : Flag<["-"], "falign-functions">, Group<f_Group>; def falign_functions_EQ : Joined<["-"], "falign-functions=">, Group<f_Group>; def fno_align_functions: Flag<["-"], "fno-align-functions">, Group<f_Group>; +defm allow_editor_placeholders : OptInFFlag<"allow-editor-placeholders", "Treat editor placeholders as valid source code">; def fallow_unsupported : Flag<["-"], "fallow-unsupported">, Group<f_Group>; def fapple_kext : Flag<["-"], "fapple-kext">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Use Apple's kernel extensions ABI">; @@ -666,8 +713,7 @@ def static_libsan : Flag<["-"], "static-libsan">, def : Flag<["-"], "shared-libasan">, Alias<shared_libsan>; def fasm : Flag<["-"], "fasm">, Group<f_Group>; -def fasm_blocks : Flag<["-"], "fasm-blocks">, Group<f_Group>, Flags<[CC1Option]>; -def fno_asm_blocks : Flag<["-"], "fno-asm-blocks">, Group<f_Group>; +defm asm_blocks : OptInFFlag<"asm-blocks", "">; def fassume_sane_operator_new : Flag<["-"], "fassume-sane-operator-new">, Group<f_Group>; def fastcp : Flag<["-"], "fastcp">, Group<f_Group>; @@ -682,17 +728,10 @@ def fno_double_square_bracket_attributes : Flag<[ "-" ], "fno-double-square-brac Group<f_Group>, Flags<[DriverOption, CC1Option]>, HelpText<"Disable '[[]]' attributes in all C and C++ language modes">; -def fautolink : Flag <["-"], "fautolink">, Group<f_Group>; -def fno_autolink : Flag <["-"], "fno-autolink">, Group<f_Group>, - Flags<[DriverOption, CC1Option]>, - HelpText<"Disable generation of linker directives for automatic library linking">; +defm autolink : OptOutFFlag<"autolink", "", "Disable generation of linker directives for automatic library linking">; // C++ Coroutines TS -def fcoroutines_ts : Flag <["-"], "fcoroutines-ts">, Group<f_Group>, - Flags<[DriverOption, CC1Option]>, - HelpText<"Enable support for the C++ Coroutines TS">; -def fno_coroutines_ts : Flag <["-"], "fno-coroutines-ts">, Group<f_Group>, - Flags<[DriverOption]>; +defm coroutines_ts : OptInFFlag<"coroutines-ts", "Enable support for the C++ Coroutines TS">; def fembed_bitcode_EQ : Joined<["-"], "fembed-bitcode=">, Group<f_Group>, Flags<[DriverOption, CC1Option, CC1AsOption]>, MetaVarName<"<option>">, @@ -703,10 +742,7 @@ def fembed_bitcode : Flag<["-"], "fembed-bitcode">, Group<f_Group>, def fembed_bitcode_marker : Flag<["-"], "fembed-bitcode-marker">, Alias<fembed_bitcode_EQ>, AliasArgs<["marker"]>, HelpText<"Embed placeholder LLVM IR data as a marker">; -def fgnu_inline_asm : Flag<["-"], "fgnu-inline-asm">, Group<f_Group>, Flags<[DriverOption]>; -def fno_gnu_inline_asm : Flag<["-"], "fno-gnu-inline-asm">, Group<f_Group>, - Flags<[DriverOption, CC1Option]>, - HelpText<"Disable GNU style inline asm">; +defm gnu_inline_asm : OptOutFFlag<"gnu-inline-asm", "", "Disable GNU style inline asm">; def fprofile_sample_use : Flag<["-"], "fprofile-sample-use">, Group<f_Group>, Flags<[CoreOption]>; @@ -740,12 +776,8 @@ def fdebug_compilation_dir : Separate<["-"], "fdebug-compilation-dir">, def fdebug_compilation_dir_EQ : Joined<["-"], "fdebug-compilation-dir=">, Group<f_Group>, Flags<[CC1Option, CC1AsOption, CoreOption]>, Alias<fdebug_compilation_dir>; -def fdebug_info_for_profiling : Flag<["-"], "fdebug-info-for-profiling">, - Group<f_Group>, Flags<[CC1Option]>, - HelpText<"Emit extra debug info to make sample profile more accurate.">; -def fno_debug_info_for_profiling : Flag<["-"], "fno-debug-info-for-profiling">, - Group<f_Group>, Flags<[DriverOption]>, - HelpText<"Do not emit extra debug info for sample profiler.">; +defm debug_info_for_profiling : OptInFFlag<"debug-info-for-profiling", + "Emit extra debug info to make sample profile more accurate">; def fprofile_instr_generate : Flag<["-"], "fprofile-instr-generate">, Group<f_Group>, Flags<[CoreOption]>, HelpText<"Generate instrumented code to collect execution counts into default.profraw file (overridden by '=' form of option or LLVM_PROFILE_FILE env var)">; @@ -762,12 +794,9 @@ def fprofile_remapping_file_EQ : Joined<["-"], "fprofile-remapping-file=">, HelpText<"Use the remappings described in <file> to match the profile data against names in the program">; def fprofile_remapping_file : Separate<["-"], "fprofile-remapping-file">, Group<f_Group>, Flags<[CoreOption]>, Alias<fprofile_remapping_file_EQ>; -def fcoverage_mapping : Flag<["-"], "fcoverage-mapping">, - Group<f_Group>, Flags<[CC1Option, CoreOption]>, - HelpText<"Generate coverage mapping to enable code coverage analysis">; -def fno_coverage_mapping : Flag<["-"], "fno-coverage-mapping">, - Group<f_Group>, Flags<[DriverOption, CoreOption]>, - HelpText<"Disable code coverage analysis">; +defm coverage_mapping : OptInFFlag<"coverage-mapping", + "Generate coverage mapping to enable code coverage analysis", "Disable code coverage analysis", "", + [CoreOption]>; def fprofile_generate : Flag<["-"], "fprofile-generate">, Group<f_Group>, Flags<[CoreOption]>, HelpText<"Generate instrumented code to collect execution counts into default.profraw (overridden by LLVM_PROFILE_FILE env var)">; @@ -806,30 +835,26 @@ def forder_file_instrumentation : Flag<["-"], "forder-file-instrumentation">, Group<f_Group>, Flags<[CC1Option, CoreOption]>, HelpText<"Generate instrumented code to collect order file into default.profraw file (overridden by '=' form of option or LLVM_PROFILE_FILE env var)">; -def faddrsig : Flag<["-"], "faddrsig">, Group<f_Group>, Flags<[CoreOption, CC1Option]>, - HelpText<"Emit an address-significance table">; -def fno_addrsig : Flag<["-"], "fno-addrsig">, Group<f_Group>, Flags<[CoreOption]>, - HelpText<"Don't emit an address-significance table">; -def fblocks : Flag<["-"], "fblocks">, Group<f_Group>, Flags<[CoreOption, CC1Option]>, - HelpText<"Enable the 'blocks' language feature">; +defm addrsig : OptInFFlag<"addrsig", "Emit", "Don't emit", " an address-significance table", [CoreOption]>; +defm blocks : OptInFFlag<"blocks", "Enable the 'blocks' language feature", "", "", [CoreOption]>; def fbootclasspath_EQ : Joined<["-"], "fbootclasspath=">, Group<f_Group>; def fborland_extensions : Flag<["-"], "fborland-extensions">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Accept non-standard constructs supported by the Borland compiler">; def fbuiltin : Flag<["-"], "fbuiltin">, Group<f_Group>, Flags<[CoreOption]>; def fbuiltin_module_map : Flag <["-"], "fbuiltin-module-map">, Group<f_Group>, Flags<[DriverOption]>, HelpText<"Load the clang builtins module map file.">; -def fcaret_diagnostics : Flag<["-"], "fcaret-diagnostics">, Group<f_Group>; +defm caret_diagnostics : OptOutFFlag<"caret-diagnostics", "", "">; def fclang_abi_compat_EQ : Joined<["-"], "fclang-abi-compat=">, Group<f_clang_Group>, Flags<[CC1Option]>, MetaVarName<"<version>">, Values<"<major>.<minor>,latest">, HelpText<"Attempt to match the ABI of Clang <version>">; def fclasspath_EQ : Joined<["-"], "fclasspath=">, Group<f_Group>; -def fcolor_diagnostics : Flag<["-"], "fcolor-diagnostics">, Group<f_Group>, - Flags<[CoreOption, CC1Option]>, HelpText<"Use colors in diagnostics">; +defm color_diagnostics : OptInFFlag<"color-diagnostics", "Enable", "Disable", " colors in diagnostics", [CoreOption]>; def fdiagnostics_color : Flag<["-"], "fdiagnostics-color">, Group<f_Group>, Flags<[CoreOption, DriverOption]>; def fdiagnostics_color_EQ : Joined<["-"], "fdiagnostics-color=">, Group<f_Group>; def fansi_escape_codes : Flag<["-"], "fansi-escape-codes">, Group<f_Group>, - Flags<[CoreOption, CC1Option]>, HelpText<"Use ANSI escape codes for diagnostics">; + Flags<[CoreOption, CC1Option]>, HelpText<"Use ANSI escape codes for diagnostics">, + MarshallingInfoFlag<"DiagnosticOpts->UseANSIEscapeCodes", "false">; def fcomment_block_commands : CommaJoined<["-"], "fcomment-block-commands=">, Group<f_clang_Group>, Flags<[CC1Option]>, HelpText<"Treat each comma separated argument in <arg> as a documentation comment block command">, MetaVarName<"<arg>">; @@ -840,7 +865,8 @@ def fno_record_command_line : Flag<["-"], "fno-record-command-line">, Group<f_clang_Group>; def : Flag<["-"], "frecord-gcc-switches">, Alias<frecord_command_line>; def : Flag<["-"], "fno-record-gcc-switches">, Alias<fno_record_command_line>; -def fcommon : Flag<["-"], "fcommon">, Group<f_Group>; +def fcommon : Flag<["-"], "fcommon">, Group<f_Group>, + Flags<[CoreOption, CC1Option]>, HelpText<"Place uninitialized global variables in a common block">; def fcompile_resource_EQ : Joined<["-"], "fcompile-resource=">, Group<f_Group>; def fcomplete_member_pointers : Flag<["-"], "fcomplete-member-pointers">, Group<f_clang_Group>, Flags<[CoreOption, CC1Option]>, @@ -862,8 +888,7 @@ def fno_crash_diagnostics : Flag<["-"], "fno-crash-diagnostics">, Group<f_clang_ HelpText<"Disable auto-generation of preprocessed source files and a script for reproduction during a clang crash">; def fcrash_diagnostics_dir : Joined<["-"], "fcrash-diagnostics-dir=">, Group<f_clang_Group>, Flags<[NoArgumentUnused, CoreOption]>; def fcreate_profile : Flag<["-"], "fcreate-profile">, Group<f_Group>; -def fcxx_exceptions: Flag<["-"], "fcxx-exceptions">, Group<f_Group>, - HelpText<"Enable C++ exceptions">, Flags<[CC1Option]>; +defm cxx_exceptions: OptInFFlag<"cxx-exceptions", "Enable C++ exceptions">; def fcxx_modules : Flag <["-"], "fcxx-modules">, Group<f_Group>, Flags<[DriverOption]>; def fdebug_pass_arguments : Flag<["-"], "fdebug-pass-arguments">, Group<f_Group>; @@ -882,9 +907,9 @@ def fdiagnostics_hotness_threshold_EQ : Joined<["-"], "fdiagnostics-hotness-thre Group<f_Group>, Flags<[CC1Option]>, MetaVarName<"<number>">, HelpText<"Prevent optimization remarks from being output if they do not have at least this profile count">; def fdiagnostics_show_option : Flag<["-"], "fdiagnostics-show-option">, Group<f_Group>, - Flags<[CC1Option]>, HelpText<"Print option name with mappable diagnostics">; + HelpText<"Print option name with mappable diagnostics">; def fdiagnostics_show_note_include_stack : Flag<["-"], "fdiagnostics-show-note-include-stack">, - Group<f_Group>, Flags<[CC1Option]>, HelpText<"Display include stacks for diagnostic notes">; + Group<f_Group>, Flags<[CC1Option]>, HelpText<"Display include stacks for diagnostic notes">; def fdiagnostics_format_EQ : Joined<["-"], "fdiagnostics-format=">, Group<f_clang_Group>; def fdiagnostics_show_category_EQ : Joined<["-"], "fdiagnostics-show-category=">, Group<f_clang_Group>; def fdiagnostics_show_template_tree : Flag<["-"], "fdiagnostics-show-template-tree">, @@ -900,8 +925,7 @@ def fdollars_in_identifiers : Flag<["-"], "fdollars-in-identifiers">, Group<f_Gr HelpText<"Allow '$' in identifiers">, Flags<[CC1Option]>; def fdwarf2_cfi_asm : Flag<["-"], "fdwarf2-cfi-asm">, Group<clang_ignored_f_Group>; def fno_dwarf2_cfi_asm : Flag<["-"], "fno-dwarf2-cfi-asm">, Group<clang_ignored_f_Group>; -def fdwarf_directory_asm : Flag<["-"], "fdwarf-directory-asm">, Group<f_Group>; -def fno_dwarf_directory_asm : Flag<["-"], "fno-dwarf-directory-asm">, Group<f_Group>, Flags<[CC1Option]>; +defm dwarf_directory_asm : OptOutFFlag<"dwarf-directory-asm", "", "">; def felide_constructors : Flag<["-"], "felide-constructors">, Group<f_Group>; def fno_elide_type : Flag<["-"], "fno-elide-type">, Group<f_Group>, Flags<[CC1Option]>, @@ -914,8 +938,7 @@ def femulated_tls : Flag<["-"], "femulated-tls">, Group<f_Group>, Flags<[CC1Opti def fno_emulated_tls : Flag<["-"], "fno-emulated-tls">, Group<f_Group>, Flags<[CC1Option]>; def fencoding_EQ : Joined<["-"], "fencoding=">, Group<f_Group>; def ferror_limit_EQ : Joined<["-"], "ferror-limit=">, Group<f_Group>, Flags<[CoreOption]>; -def fexceptions : Flag<["-"], "fexceptions">, Group<f_Group>, Flags<[CC1Option]>, - HelpText<"Enable support for exception handling">; +defm exceptions : OptInFFlag<"exceptions", "Enable", "Disable", " support for exception handling">; def fdwarf_exceptions : Flag<["-"], "fdwarf-exceptions">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Use DWARF style exceptions">; def fsjlj_exceptions : Flag<["-"], "fsjlj-exceptions">, Group<f_Group>, @@ -924,6 +947,8 @@ def fseh_exceptions : Flag<["-"], "fseh-exceptions">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Use SEH style exceptions">; def fwasm_exceptions : Flag<["-"], "fwasm-exceptions">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Use WebAssembly style exceptions">; +def fignore_exceptions : Flag<["-"], "fignore-exceptions">, Group<f_Group>, Flags<[CC1Option]>, + HelpText<"Enable support for ignoring exception handling constructs">; def fexcess_precision_EQ : Joined<["-"], "fexcess-precision=">, Group<clang_ignored_gcc_optimization_f_Group>; def : Flag<["-"], "fexpensive-optimizations">, Group<clang_ignored_gcc_optimization_f_Group>; @@ -939,37 +964,17 @@ def ffp_model_EQ : Joined<["-"], "ffp-model=">, Group<f_Group>, Flags<[DriverOpt HelpText<"Controls the semantics of floating-point calculations.">; def ffp_exception_behavior_EQ : Joined<["-"], "ffp-exception-behavior=">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Specifies the exception behavior of floating-point operations.">; -def ffast_math : Flag<["-"], "ffast-math">, Group<f_Group>, Flags<[CC1Option]>, - HelpText<"Allow aggressive, lossy floating-point optimizations">; -def fno_fast_math : Flag<["-"], "fno-fast-math">, Group<f_Group>; -def fmath_errno : Flag<["-"], "fmath-errno">, Group<f_Group>, Flags<[CC1Option]>, - HelpText<"Require math functions to indicate errors by setting errno">; -def fno_math_errno : Flag<["-"], "fno-math-errno">, Group<f_Group>; +defm fast_math : OptInFFlag<"fast-math", "Allow aggressive, lossy floating-point optimizations">; +defm math_errno : OptInFFlag<"math-errno", "Require math functions to indicate errors by setting errno">; def fbracket_depth_EQ : Joined<["-"], "fbracket-depth=">, Group<f_Group>, Flags<[CoreOption]>; def fsignaling_math : Flag<["-"], "fsignaling-math">, Group<f_Group>; def fno_signaling_math : Flag<["-"], "fno-signaling-math">, Group<f_Group>; -def fjump_tables : Flag<["-"], "fjump-tables">, Group<f_Group>; -def fno_jump_tables : Flag<["-"], "fno-jump-tables">, Group<f_Group>, Flags<[CC1Option]>, - HelpText<"Do not use jump tables for lowering switches">; -def fforce_enable_int128 : Flag<["-"], "fforce-enable-int128">, - Group<f_Group>, Flags<[CC1Option]>, - HelpText<"Enable support for int128_t type">; -def fno_force_enable_int128 : Flag<["-"], "fno-force-enable-int128">, - Group<f_Group>, Flags<[CC1Option]>, - HelpText<"Disable support for int128_t type">; -def fkeep_static_consts : Flag<["-"], "fkeep-static-consts">, Group<f_Group>, Flags<[CC1Option]>, - HelpText<"Keep static const variables even if unused">; -def ffixed_point : Flag<["-"], "ffixed-point">, Group<f_Group>, - Flags<[CC1Option]>, HelpText<"Enable fixed point types">; -def fno_fixed_point : Flag<["-"], "fno-fixed-point">, Group<f_Group>, - HelpText<"Disable fixed point types">; -def fcxx_static_destructors : Flag<["-"], "fc++-static-destructors">, - Group<f_Group>, - HelpText<"Enable C++ static destructor registration (the default)">; -def fno_cxx_static_destructors : Flag<["-"], "fno-c++-static-destructors">, - Group<f_Group>, - Flags<[CC1Option]>, - HelpText<"Disable C++ static destructor registration">; +defm jump_tables : OptOutFFlag<"jump-tables", "Use", "Do not use", " jump tables for lowering switches">; +defm force_enable_int128 : OptInFFlag<"force-enable-int128", "Enable", "Disable", " support for int128_t type">; +defm keep_static_consts : OptInFFlag<"keep-static-consts", "Keep", "Don't keep", " static const variables if unused", [DriverOption]>; +defm fixed_point : OptInFFlag<"fixed-point", "Enable", "Disable", " fixed point types">; +defm cxx_static_destructors : OptOutFFlag<"c++-static-destructors", "", + "Disable C++ static destructor registration">; def fsymbol_partition_EQ : Joined<["-"], "fsymbol-partition=">, Group<f_Group>, Flags<[CC1Option]>; @@ -1000,7 +1005,19 @@ def fno_sanitize_coverage : CommaJoined<["-"], "fno-sanitize-coverage=">, Group<f_clang_Group>, Flags<[CoreOption, DriverOption]>, HelpText<"Disable specified features of coverage instrumentation for " - "Sanitizers">, Values<"func,bb,edge,indirect-calls,trace-bb,trace-cmp,trace-div,trace-gep,8bit-counters,trace-pc,trace-pc-guard,no-prune,inline-8bit-counters">; + "Sanitizers">, Values<"func,bb,edge,indirect-calls,trace-bb,trace-cmp,trace-div,trace-gep,8bit-counters,trace-pc,trace-pc-guard,no-prune,inline-8bit-counters,inline-bool-flag">; +def fsanitize_coverage_allowlist : Joined<["-"], "fsanitize-coverage-allowlist=">, + Group<f_clang_Group>, Flags<[CoreOption, DriverOption]>, + HelpText<"Restrict sanitizer coverage instrumentation exclusively to modules and functions that match the provided special case list, except the blocked ones">; +def : Joined<["-"], "fsanitize-coverage-whitelist=">, + Group<f_clang_Group>, Flags<[CoreOption, HelpHidden]>, Alias<fsanitize_coverage_allowlist>, + HelpText<"Deprecated, use -fsanitize-coverage-allowlist= instead">; +def fsanitize_coverage_blocklist : Joined<["-"], "fsanitize-coverage-blocklist=">, + Group<f_clang_Group>, Flags<[CoreOption, DriverOption]>, + HelpText<"Disable sanitizer coverage instrumentation for modules and functions that match the provided special case list, even the allowed ones">; +def : Joined<["-"], "fsanitize-coverage-blacklist=">, + Group<f_clang_Group>, Flags<[CoreOption, HelpHidden]>, Alias<fsanitize_coverage_blocklist>, + HelpText<"Deprecated, use -fsanitize-coverage-blocklist= instead">; def fsanitize_memory_track_origins_EQ : Joined<["-"], "fsanitize-memory-track-origins=">, Group<f_clang_Group>, HelpText<"Enable origins tracking in MemorySanitizer">; @@ -1056,27 +1073,35 @@ def fsanitize_hwaddress_abi_EQ : Joined<["-"], "fsanitize-hwaddress-abi=">, Group<f_clang_Group>, HelpText<"Select the HWAddressSanitizer ABI to target (interceptor or platform, default interceptor). This option is currently unused.">; -def fsanitize_recover : Flag<["-"], "fsanitize-recover">, Group<f_clang_Group>; -def fno_sanitize_recover : Flag<["-"], "fno-sanitize-recover">, - Flags<[CoreOption, DriverOption]>, - Group<f_clang_Group>; def fsanitize_recover_EQ : CommaJoined<["-"], "fsanitize-recover=">, Group<f_clang_Group>, HelpText<"Enable recovery for specified sanitizers">; -def fno_sanitize_recover_EQ - : CommaJoined<["-"], "fno-sanitize-recover=">, - Group<f_clang_Group>, - Flags<[CoreOption, DriverOption]>, - HelpText<"Disable recovery for specified sanitizers">; +def fno_sanitize_recover_EQ : CommaJoined<["-"], "fno-sanitize-recover=">, + Group<f_clang_Group>, Flags<[CoreOption, DriverOption]>, + HelpText<"Disable recovery for specified sanitizers">; +def fsanitize_recover : Flag<["-"], "fsanitize-recover">, Group<f_clang_Group>, + Alias<fsanitize_recover_EQ>, AliasArgs<["all"]>; +def fno_sanitize_recover : Flag<["-"], "fno-sanitize-recover">, + Flags<[CoreOption, DriverOption]>, Group<f_clang_Group>, + Alias<fno_sanitize_recover_EQ>, AliasArgs<["all"]>; def fsanitize_trap_EQ : CommaJoined<["-"], "fsanitize-trap=">, Group<f_clang_Group>, HelpText<"Enable trapping for specified sanitizers">; def fno_sanitize_trap_EQ : CommaJoined<["-"], "fno-sanitize-trap=">, Group<f_clang_Group>, Flags<[CoreOption, DriverOption]>, HelpText<"Disable trapping for specified sanitizers">; -def fsanitize_undefined_trap_on_error : Flag<["-"], "fsanitize-undefined-trap-on-error">, - Group<f_clang_Group>; -def fno_sanitize_undefined_trap_on_error : Flag<["-"], "fno-sanitize-undefined-trap-on-error">, - Group<f_clang_Group>; +def fsanitize_trap : Flag<["-"], "fsanitize-trap">, Group<f_clang_Group>, + Alias<fsanitize_trap_EQ>, AliasArgs<["all"]>, + HelpText<"Enable trapping for all sanitizers">; +def fno_sanitize_trap : Flag<["-"], "fno-sanitize-trap">, Group<f_clang_Group>, + Alias<fno_sanitize_trap_EQ>, AliasArgs<["all"]>, + Flags<[CoreOption, DriverOption]>, + HelpText<"Disable trapping for all sanitizers">; +def fsanitize_undefined_trap_on_error + : Flag<["-"], "fsanitize-undefined-trap-on-error">, Group<f_clang_Group>, + Alias<fsanitize_trap_EQ>, AliasArgs<["undefined"]>; +def fno_sanitize_undefined_trap_on_error + : Flag<["-"], "fno-sanitize-undefined-trap-on-error">, Group<f_clang_Group>, + Alias<fno_sanitize_trap_EQ>, AliasArgs<["undefined"]>; def fsanitize_minimal_runtime : Flag<["-"], "fsanitize-minimal-runtime">, Group<f_clang_Group>; def fno_sanitize_minimal_runtime : Flag<["-"], "fno-sanitize-minimal-runtime">, @@ -1173,30 +1198,19 @@ def ffp_contract : Joined<["-"], "ffp-contract=">, Group<f_Group>, " | on (according to FP_CONTRACT pragma) | off (never fuse). Default" " is 'fast' for CUDA/HIP and 'on' otherwise.">, Values<"fast,on,off">; -def fstrict_float_cast_overflow : Flag<["-"], - "fstrict-float-cast-overflow">, Group<f_Group>, Flags<[CC1Option]>, - HelpText<"Assume that overflowing float-to-int casts are undefined (default)">; -def fno_strict_float_cast_overflow : Flag<["-"], - "fno-strict-float-cast-overflow">, Group<f_Group>, Flags<[CC1Option]>, - HelpText<"Relax language rules and try to match the behavior of the target's native float-to-int conversion instructions">; +defm strict_float_cast_overflow : OptOutFFlag<"strict-float-cast-overflow", + "Assume that overflowing float-to-int casts are undefined (default)", + "Relax language rules and try to match the behavior of the target's native float-to-int conversion instructions">; def ffor_scope : Flag<["-"], "ffor-scope">, Group<f_Group>; def fno_for_scope : Flag<["-"], "fno-for-scope">, Group<f_Group>; -def frewrite_includes : Flag<["-"], "frewrite-includes">, Group<f_Group>, - Flags<[CC1Option]>; -def fno_rewrite_includes : Flag<["-"], "fno-rewrite-includes">, Group<f_Group>; - -def frewrite_imports : Flag<["-"], "frewrite-imports">, Group<f_Group>, - Flags<[CC1Option]>; -def fno_rewrite_imports : Flag<["-"], "fno-rewrite-imports">, Group<f_Group>; +defm rewrite_imports : OptInFFlag<"rewrite-imports", "">; +defm rewrite_includes : OptInFFlag<"rewrite-includes", "">; -def fdelete_null_pointer_checks : Flag<["-"], - "fdelete-null-pointer-checks">, Group<f_Group>, - HelpText<"Treat usage of null pointers as undefined behavior.">; -def fno_delete_null_pointer_checks : Flag<["-"], - "fno-delete-null-pointer-checks">, Group<f_Group>, Flags<[CC1Option]>, - HelpText<"Do not treat usage of null pointers as undefined behavior.">; +defm delete_null_pointer_checks : OptOutFFlag<"delete-null-pointer-checks", + "Treat usage of null pointers as undefined behavior (default)", + "Do not treat usage of null pointers as undefined behavior">; def frewrite_map_file : Separate<["-"], "frewrite-map-file">, Group<f_Group>, @@ -1205,9 +1219,7 @@ def frewrite_map_file_EQ : Joined<["-"], "frewrite-map-file=">, Group<f_Group>, Flags<[DriverOption]>; -def fuse_line_directives : Flag<["-"], "fuse-line-directives">, Group<f_Group>, - Flags<[CC1Option]>; -def fno_use_line_directives : Flag<["-"], "fno-use-line-directives">, Group<f_Group>; +defm use_line_directives : OptInFFlag<"use-line-directives", "Use #line in preprocessed output">; def ffreestanding : Flag<["-"], "ffreestanding">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Assert that the compilation takes place in a freestanding environment">; @@ -1216,9 +1228,7 @@ def fgnuc_version_EQ : Joined<["-"], "fgnuc-version=">, Group<f_Group>, Flags<[CC1Option, CoreOption]>; def fgnu_keywords : Flag<["-"], "fgnu-keywords">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Allow GNU-extension keywords regardless of language standard">; -def fgnu89_inline : Flag<["-"], "fgnu89-inline">, Group<f_Group>, Flags<[CC1Option]>, - HelpText<"Use the gnu89 inline semantics">; -def fno_gnu89_inline : Flag<["-"], "fno-gnu89-inline">, Group<f_Group>; +defm gnu89_inline : OptInFFlag<"gnu89-inline", "Use the gnu89 inline semantics">; def fgnu_runtime : Flag<["-"], "fgnu-runtime">, Group<f_Group>, HelpText<"Generate output compatible with the standard GNU Objective-C runtime">; def fheinous_gnu_extensions : Flag<["-"], "fheinous-gnu-extensions">, Flags<[CC1Option]>; @@ -1230,11 +1240,16 @@ def finline_functions : Flag<["-"], "finline-functions">, Group<f_clang_Group>, def finline_hint_functions: Flag<["-"], "finline-hint-functions">, Group<f_clang_Group>, Flags<[CC1Option]>, HelpText<"Inline functions which are (explicitly or implicitly) marked inline">; def finline : Flag<["-"], "finline">, Group<clang_ignored_f_Group>; +def fglobal_isel : Flag<["-"], "fglobal-isel">, Group<f_clang_Group>, + HelpText<"Enables the global instruction selector">; def fexperimental_isel : Flag<["-"], "fexperimental-isel">, Group<f_clang_Group>, - HelpText<"Enables the experimental global instruction selector">; + Alias<fglobal_isel>; def fexperimental_new_pass_manager : Flag<["-"], "fexperimental-new-pass-manager">, Group<f_clang_Group>, Flags<[CC1Option]>, HelpText<"Enables an experimental new pass manager in LLVM.">; +def fexperimental_strict_floating_point : Flag<["-"], "fexperimental-strict-floating-point">, + Group<f_clang_Group>, Flags<[CC1Option]>, + HelpText<"Enables experimental strict floating point in LLVM.">; def finput_charset_EQ : Joined<["-"], "finput-charset=">, Group<f_Group>; def fexec_charset_EQ : Joined<["-"], "fexec-charset=">, Group<f_Group>; def finstrument_functions : Flag<["-"], "finstrument-functions">, Group<f_Group>, Flags<[CC1Option]>, @@ -1249,11 +1264,7 @@ def fcf_protection : Flag<["-"], "fcf-protection">, Group<f_Group>, Flags<[CoreO Alias<fcf_protection_EQ>, AliasArgs<["full"]>, HelpText<"Enable cf-protection in 'full' mode">; -def fxray_instrument : Flag<["-"], "fxray-instrument">, Group<f_Group>, - Flags<[CC1Option]>, - HelpText<"Generate XRay instrumentation sleds on function entry and exit">; -def fnoxray_instrument : Flag<["-"], "fno-xray-instrument">, Group<f_Group>, - Flags<[CC1Option]>; +defm xray_instrument : OptInFFlag<"xray-instrument", "Generate XRay instrumentation sleds on function entry and exit">; def fxray_instruction_threshold_EQ : JoinedOrSeparate<["-"], "fxray-instruction-threshold=">, @@ -1280,17 +1291,16 @@ def fxray_modes : Group<f_Group>, Flags<[CC1Option]>, HelpText<"List of modes to link in by default into XRay instrumented binaries.">; -def fxray_always_emit_customevents : Flag<["-"], "fxray-always-emit-customevents">, Group<f_Group>, - Flags<[CC1Option]>, - HelpText<"Determine whether to always emit __xray_customevent(...) calls even if the function it appears in is not always instrumented.">; -def fnoxray_always_emit_customevents : Flag<["-"], "fno-xray-always-emit-customevents">, Group<f_Group>, - Flags<[CC1Option]>; +defm xray_always_emit_customevents : OptInFFlag<"xray-always-emit-customevents", + "Always emit __xray_customevent(...) calls even if the containing function is not always instrumented">; -def fxray_always_emit_typedevents : Flag<["-"], "fxray-always-emit-typedevents">, Group<f_Group>, - Flags<[CC1Option]>, - HelpText<"Determine whether to always emit __xray_typedevent(...) calls even if the function it appears in is not always instrumented.">; -def fnoxray_always_emit_typedevents : Flag<["-"], "fno-xray-always-emit-typedevents">, Group<f_Group>, - Flags<[CC1Option]>; +defm xray_always_emit_typedevents : OptInFFlag<"xray-always-emit-typedevents", + "Always emit __xray_typedevent(...) calls even if the containing function is not always instrumented">; + +defm xray_ignore_loops : OptInFFlag<"xray-ignore-loops", + "Don't instrument functions with loops unless they also meet the minimum function size">; +defm xray_function_index : OptOutFFlag<"xray-function-index", "", + "Omit function index section at the expense of single-function patching performance">; def fxray_link_deps : Flag<["-"], "fxray-link-deps">, Group<f_Group>, Flags<[CC1Option]>, @@ -1301,7 +1311,7 @@ def fnoxray_link_deps : Flag<["-"], "fnoxray-link-deps">, Group<f_Group>, def fxray_instrumentation_bundle : JoinedOrSeparate<["-"], "fxray-instrumentation-bundle=">, Group<f_Group>, Flags<[CC1Option]>, - HelpText<"Select which XRay instrumentation points to emit. Options: all, none, function, custom. Default is 'all'.">; + HelpText<"Select which XRay instrumentation points to emit. Options: all, none, function-entry, function-exit, function, custom. Default is 'all'. 'function' includes both 'function-entry' and 'function-exit'.">; def ffine_grained_bitfield_accesses : Flag<["-"], "ffine-grained-bitfield-accesses">, Group<f_clang_Group>, Flags<[CC1Option]>, @@ -1310,6 +1320,13 @@ def fno_fine_grained_bitfield_accesses : Flag<["-"], "fno-fine-grained-bitfield-accesses">, Group<f_clang_Group>, Flags<[CC1Option]>, HelpText<"Use large-integer access for consecutive bitfield runs.">; +def fexperimental_relative_cxx_abi_vtables : Flag<["-"], "fexperimental-relative-c++-abi-vtables">, + Group<f_Group>, Flags<[CC1Option]>, + HelpText<"Use the experimental C++ class ABI for classes with virtual tables">; +def fno_experimental_relative_cxx_abi_vtables : Flag<["-"], "fno-experimental-relative-c++-abi-vtables">, + Group<f_Group>, Flags<[CC1Option]>, + HelpText<"Do not use the experimental C++ class ABI for classes with virtual tables">; + def flat__namespace : Flag<["-"], "flat_namespace">; def flax_vector_conversions_EQ : Joined<["-"], "flax-vector-conversions=">, Group<f_Group>, HelpText<"Enable implicit vector bit-casts">, Values<"none,integer,all">, Flags<[CC1Option]>; @@ -1339,7 +1356,8 @@ 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>, Flags<[CC1Option, CoreOption]>, HelpText<"Allow merging of constants">; -def fmessage_length_EQ : Joined<["-"], "fmessage-length=">, Group<f_Group>; +def fmessage_length_EQ : Joined<["-"], "fmessage-length=">, Group<f_Group>, Flags<[CC1Option]>, + HelpText<"Format message diagnostics so that they fit within N columns">; 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, CoreOption]>, @@ -1415,6 +1433,13 @@ def fpch_validate_input_files_content: def fno_pch_validate_input_files_content: Flag <["-"], "fno_pch-validate-input-files-content">, Group<f_Group>, Flags<[DriverOption]>; +def fpch_instantiate_templates: + Flag <["-"], "fpch-instantiate-templates">, + Group<f_Group>, Flags<[CC1Option]>, + HelpText<"Instantiate templates already while building a PCH">; +def fno_pch_instantiate_templates: + Flag <["-"], "fno-pch-instantiate-templates">, + Group<f_Group>, Flags<[CC1Option]>; def fmodules : Flag <["-"], "fmodules">, Group<f_Group>, Flags<[DriverOption, CC1Option]>, @@ -1431,6 +1456,8 @@ def fmodule_name_EQ : Joined<["-"], "fmodule-name=">, Group<f_Group>, def fmodule_name : Separate<["-"], "fmodule-name">, Alias<fmodule_name_EQ>; def fmodule_implementation_of : Separate<["-"], "fmodule-implementation-of">, Flags<[CC1Option]>, Alias<fmodule_name_EQ>; +def fsystem_module : Flag<["-"], "fsystem-module">, Flags<[CC1Option]>, + HelpText<"Build this module as a system module. Only used with -emit-module">; def fmodule_map_file : Joined<["-"], "fmodule-map-file=">, Group<f_Group>, Flags<[DriverOption,CC1Option]>, MetaVarName<"<file>">, HelpText<"Load this module map file">; @@ -1456,24 +1483,17 @@ def fmudflapth : Flag<["-"], "fmudflapth">, Group<f_Group>; def fmudflap : Flag<["-"], "fmudflap">, Group<f_Group>; def fnested_functions : Flag<["-"], "fnested-functions">, Group<f_Group>; def fnext_runtime : Flag<["-"], "fnext-runtime">, Group<f_Group>; -def fno_access_control : Flag<["-"], "fno-access-control">, Group<f_Group>, Flags<[CC1Option]>, - HelpText<"Disable C++ access control">; def fno_apple_pragma_pack : Flag<["-"], "fno-apple-pragma-pack">, Group<f_Group>; def fno_asm : Flag<["-"], "fno-asm">, Group<f_Group>; def fno_asynchronous_unwind_tables : Flag<["-"], "fno-asynchronous-unwind-tables">, Group<f_Group>; def fno_assume_sane_operator_new : Flag<["-"], "fno-assume-sane-operator-new">, Group<f_Group>, HelpText<"Don't assume that C++'s global operator new can't alias any pointer">, Flags<[CC1Option]>; -def fno_blocks : Flag<["-"], "fno-blocks">, Group<f_Group>, Flags<[CoreOption]>; def fno_borland_extensions : Flag<["-"], "fno-borland-extensions">, Group<f_Group>; def fno_builtin : Flag<["-"], "fno-builtin">, Group<f_Group>, Flags<[CC1Option, CoreOption]>, HelpText<"Disable implicit builtin knowledge of functions">; def fno_builtin_ : Joined<["-"], "fno-builtin-">, Group<f_Group>, Flags<[CC1Option, CoreOption]>, HelpText<"Disable implicit builtin knowledge of a specific function">; -def fno_caret_diagnostics : Flag<["-"], "fno-caret-diagnostics">, Group<f_Group>, - Flags<[CC1Option]>; -def fno_color_diagnostics : Flag<["-"], "fno-color-diagnostics">, Group<f_Group>, - Flags<[CoreOption, CC1Option]>; def fno_diagnostics_color : Flag<["-"], "fno-diagnostics-color">, Group<f_Group>, Flags<[CoreOption, DriverOption]>; def fno_common : Flag<["-"], "fno-common">, Group<f_Group>, Flags<[CC1Option]>, @@ -1481,13 +1501,12 @@ def fno_common : Flag<["-"], "fno-common">, Group<f_Group>, Flags<[CC1Option]>, def fno_constant_cfstrings : Flag<["-"], "fno-constant-cfstrings">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Disable creation of CodeFoundation-type constant strings">; -def fno_cxx_exceptions: Flag<["-"], "fno-cxx-exceptions">, Group<f_Group>; def fno_cxx_modules : Flag <["-"], "fno-cxx-modules">, Group<f_Group>, Flags<[DriverOption]>; def fno_diagnostics_fixit_info : Flag<["-"], "fno-diagnostics-fixit-info">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Do not include fixit information in diagnostics">; def fno_diagnostics_show_hotness : Flag<["-"], "fno-diagnostics-show-hotness">, Group<f_Group>; -def fno_diagnostics_show_option : Flag<["-"], "fno-diagnostics-show-option">, Group<f_Group>; +def fno_diagnostics_show_option : Flag<["-"], "fno-diagnostics-show-option">, Group<f_Group>, Flags<[CC1Option]>; def fno_diagnostics_show_note_include_stack : Flag<["-"], "fno-diagnostics-show-note-include-stack">, Flags<[CC1Option]>, Group<f_Group>; def fdigraphs : Flag<["-"], "fdigraphs">, Group<f_Group>, Flags<[CC1Option]>, @@ -1501,12 +1520,13 @@ def fno_dollars_in_identifiers : Flag<["-"], "fno-dollars-in-identifiers">, Grou def fno_elide_constructors : Flag<["-"], "fno-elide-constructors">, Group<f_Group>, HelpText<"Disable C++ copy constructor elision">, Flags<[CC1Option]>; def fno_eliminate_unused_debug_symbols : Flag<["-"], "fno-eliminate-unused-debug-symbols">, Group<f_Group>; -def fno_exceptions : Flag<["-"], "fno-exceptions">, Group<f_Group>; def fno_gnu_keywords : Flag<["-"], "fno-gnu-keywords">, Group<f_Group>, Flags<[CC1Option]>; def fno_inline_functions : Flag<["-"], "fno-inline-functions">, Group<f_clang_Group>, Flags<[CC1Option]>; def fno_inline : Flag<["-"], "fno-inline">, Group<f_clang_Group>, Flags<[CC1Option]>; +def fno_global_isel : Flag<["-"], "fno-global-isel">, Group<f_clang_Group>, + HelpText<"Disables the global instruction selector">; def fno_experimental_isel : Flag<["-"], "fno-experimental-isel">, Group<f_clang_Group>, - HelpText<"Disables the experimental global instruction selector">; + Alias<fno_global_isel>; def fno_experimental_new_pass_manager : Flag<["-"], "fno-experimental-new-pass-manager">, Group<f_clang_Group>, Flags<[CC1Option]>, HelpText<"Disables an experimental new pass manager in LLVM.">; @@ -1546,13 +1566,7 @@ def fno_operator_names : Flag<["-"], "fno-operator-names">, Group<f_Group>, HelpText<"Do not treat C++ operator name keywords as synonyms for operators">, Flags<[CC1Option]>; def fno_pascal_strings : Flag<["-"], "fno-pascal-strings">, Group<f_Group>; -def fno_rtti : Flag<["-"], "fno-rtti">, Group<f_Group>, Flags<[CC1Option]>, - HelpText<"Disable generation of rtti information">; -def fno_rtti_data : Flag<["-"], "fno-rtti-data">, Group<f_Group>, Flags<[CC1Option]>, - HelpText<"Control emission of RTTI data">; def fno_short_enums : Flag<["-"], "fno-short-enums">, Group<f_Group>; -def fno_show_column : Flag<["-"], "fno-show-column">, Group<f_Group>, Flags<[CC1Option]>, - HelpText<"Do not include column number on diagnostics">; def fno_show_source_location : Flag<["-"], "fno-show-source-location">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Do not include source location information with diagnostics">; def fdiagnostics_absolute_paths : Flag<["-"], "fdiagnostics-absolute-paths">, Group<f_Group>, @@ -1578,14 +1592,11 @@ def fno_use_cxa_atexit : Flag<["-"], "fno-use-cxa-atexit">, Group<f_Group>, Flag HelpText<"Don't use __cxa_atexit for calling destructors">; def fno_register_global_dtors_with_atexit : Flag<["-"], "fno-register-global-dtors-with-atexit">, Group<f_Group>, HelpText<"Don't use atexit or __cxa_atexit to register global destructors">; -def fno_use_init_array : Flag<["-"], "fno-use-init-array">, Group<f_Group>, Flags<[CC1Option]>, - HelpText<"Don't use .init_array instead of .ctors">; def fno_unit_at_a_time : Flag<["-"], "fno-unit-at-a-time">, Group<f_Group>; def fno_unwind_tables : Flag<["-"], "fno-unwind-tables">, Group<f_Group>; -def fno_verbose_asm : Flag<["-"], "fno-verbose-asm">, Group<f_Group>; +def fno_verbose_asm : Flag<["-"], "fno-verbose-asm">, Group<f_Group>, Flags<[CC1Option]>; def fno_working_directory : Flag<["-"], "fno-working-directory">, Group<f_Group>; def fno_wrapv : Flag<["-"], "fno-wrapv">, Group<f_Group>; -def fno_zero_initialized_in_bss : Flag<["-"], "fno-zero-initialized-in-bss">, Group<f_Group>; def fobjc_arc : Flag<["-"], "fobjc-arc">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Synthesize retain and release calls for Objective-C pointers">; def fno_objc_arc : Flag<["-"], "fno-objc-arc">, Group<f_Group>; @@ -1686,6 +1697,12 @@ def fopenmp_optimistic_collapse : Flag<["-"], "fopenmp-optimistic-collapse">, Gr Flags<[CC1Option, NoArgumentUnused, HelpHidden]>; def fno_openmp_optimistic_collapse : Flag<["-"], "fno-openmp-optimistic-collapse">, Group<f_Group>, Flags<[NoArgumentUnused, HelpHidden]>; +def fopenmp_cuda_parallel_target_regions : Flag<["-"], "fopenmp-cuda-parallel-target-regions">, Group<f_Group>, + Flags<[CC1Option, NoArgumentUnused, HelpHidden]>, + HelpText<"Support parallel execution of target regions on Cuda-based devices.">; +def fno_openmp_cuda_parallel_target_regions : Flag<["-"], "fno-openmp-cuda-parallel-target-regions">, Group<f_Group>, + Flags<[NoArgumentUnused, HelpHidden]>, + HelpText<"Support only serial execution of target regions on Cuda-based devices.">; def static_openmp: Flag<["-"], "static-openmp">, HelpText<"Use the static host OpenMP runtime while linking.">; def fno_optimize_sibling_calls : Flag<["-"], "fno-optimize-sibling-calls">, Group<f_Group>; @@ -1707,7 +1724,7 @@ def fno_max_type_align : Flag<["-"], "fno-max-type-align">, Group<f_Group>; def fpascal_strings : Flag<["-"], "fpascal-strings">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Recognize and construct Pascal-style string literals">; def fpatchable_function_entry_EQ : Joined<["-"], "fpatchable-function-entry=">, Group<f_Group>, Flags<[CC1Option]>, - HelpText<"Generate N NOPs at function entry">; + MetaVarName<"<N,M>">, HelpText<"Generate M NOPs before function entry and N-M NOPs after function entry">; def fpcc_struct_return : Flag<["-"], "fpcc-struct-return">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Override the default ABI to return all structs on the stack">; def fpch_preprocess : Flag<["-"], "fpch-preprocess">, Group<f_Group>; @@ -1715,29 +1732,25 @@ def fpic : Flag<["-"], "fpic">, Group<f_Group>; def fno_pic : Flag<["-"], "fno-pic">, Group<f_Group>; def fpie : Flag<["-"], "fpie">, Group<f_Group>; def fno_pie : Flag<["-"], "fno-pie">, Group<f_Group>; -def fplt : Flag<["-"], "fplt">, Group<f_Group>, Flags<[CC1Option]>, - HelpText<"Use the PLT to make function calls">; -def fno_plt : Flag<["-"], "fno-plt">, Group<f_Group>, Flags<[CC1Option]>, - HelpText<"Do not use the PLT to make function calls">; -def fropi : Flag<["-"], "fropi">, Group<f_Group>, Flags<[CC1Option]>; -def fno_ropi : Flag<["-"], "fno-ropi">, Group<f_Group>; -def frwpi : Flag<["-"], "frwpi">, Group<f_Group>, Flags<[CC1Option]>; -def fno_rwpi : Flag<["-"], "fno-rwpi">, Group<f_Group>; +defm plt : OptOutFFlag<"plt", "", + "Use GOT indirection instead of PLT to make external function calls (x86 only)">; +defm ropi : OptInFFlag<"ropi", "Generate read-only position independent code (ARM only)">; +defm rwpi : OptInFFlag<"rwpi", "Generate read-write position independent code (ARM only)">; def fplugin_EQ : Joined<["-"], "fplugin=">, Group<f_Group>, Flags<[DriverOption]>, MetaVarName<"<dsopath>">, HelpText<"Load the named plugin (dynamic shared object)">; def fpass_plugin_EQ : Joined<["-"], "fpass-plugin=">, Group<f_Group>, Flags<[CC1Option]>, MetaVarName<"<dsopath>">, HelpText<"Load pass plugin from a dynamic shared object file (only with new pass manager).">; -def fpreserve_as_comments : Flag<["-"], "fpreserve-as-comments">, Group<f_Group>; -def fno_preserve_as_comments : Flag<["-"], "fno-preserve-as-comments">, Group<f_Group>, Flags<[CC1Option]>, - HelpText<"Do not preserve comments in inline assembly">; +defm preserve_as_comments : OptOutFFlag<"preserve-as-comments", "", + "Do not preserve comments in inline assembly">; 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]>; def frandom_seed_EQ : Joined<["-"], "frandom-seed=">, Group<clang_ignored_f_Group>; def freg_struct_return : Flag<["-"], "freg-struct-return">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Override the default ABI to return small structs in registers">; -def frtti : Flag<["-"], "frtti">, Group<f_Group>; +defm rtti : OptOutFFlag<"rtti", "", "Disable generation of rtti information">; +defm rtti_data : OptOutFFlag<"rtti-data", "", "Disable generation of RTTI data">; def : Flag<["-"], "fsched-interblock">, Group<clang_ignored_f_Group>; def fshort_enums : Flag<["-"], "fshort-enums">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Allocate to an enum type only as many bytes as it needs for the declared range of possible values">; @@ -1752,17 +1765,19 @@ def fno_short_wchar : Flag<["-"], "fno-short-wchar">, Group<f_Group>, def fshow_overloads_EQ : Joined<["-"], "fshow-overloads=">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Which overload candidates to show when overload resolution fails: " "best|all; defaults to all">, Values<"best,all">; -def fshow_column : Flag<["-"], "fshow-column">, Group<f_Group>, Flags<[CC1Option]>; +defm show_column : OptOutFFlag<"show-column", "", "Do not include column number on diagnostics">; def fshow_source_location : Flag<["-"], "fshow-source-location">, Group<f_Group>; def fspell_checking : Flag<["-"], "fspell-checking">, Group<f_Group>; def fspell_checking_limit_EQ : Joined<["-"], "fspell-checking-limit=">, Group<f_Group>; def fsigned_bitfields : Flag<["-"], "fsigned-bitfields">, Group<f_Group>; -def fsigned_char : Flag<["-"], "fsigned-char">, Group<f_Group>; -def fno_signed_char : Flag<["-"], "fno-signed-char">, Group<f_Group>, - Flags<[CC1Option]>, HelpText<"Char is unsigned">; +defm signed_char : OptOutFFlag<"signed-char", "char is signed", "char is unsigned">; def fsplit_stack : Flag<["-"], "fsplit-stack">, Group<f_Group>; def fstack_protector_all : Flag<["-"], "fstack-protector-all">, Group<f_Group>, HelpText<"Enable stack protectors for all functions">; +def fstack_clash_protection : Flag<["-"], "fstack-clash-protection">, Group<f_Group>, Flags<[CC1Option]>, + HelpText<"Enable stack clash protection">; +def fnostack_clash_protection : Flag<["-"], "fnostack-clash-protection">, Group<f_Group>, + HelpText<"Disable stack clash protection">; def fstack_protector_strong : Flag<["-"], "fstack-protector-strong">, Group<f_Group>, HelpText<"Enable stack protectors for some functions vulnerable to stack smashing. " "Compared to -fstack-protector, this uses a stronger heuristic " @@ -1780,6 +1795,8 @@ def ftrivial_auto_var_init : Joined<["-"], "ftrivial-auto-var-init=">, Group<f_G def enable_trivial_var_init_zero : Flag<["-"], "enable-trivial-auto-var-init-zero-knowing-it-will-be-removed-from-clang">, Flags<[CC1Option, CoreOption]>, HelpText<"Trivial automatic variable initialization to zero is only here for benchmarks, it'll eventually be removed, and I'm OK with that because I'm only using it to benchmark">; +def ftrivial_auto_var_init_stop_after : Joined<["-"], "ftrivial-auto-var-init-stop-after=">, Group<f_Group>, + Flags<[CC1Option, CoreOption]>, HelpText<"Stop initializing trivial automatic stack variables after the specified number of instances">; def fstandalone_debug : Flag<["-"], "fstandalone-debug">, Group<f_Group>, Flags<[CoreOption]>, HelpText<"Emit full debug info for all types used by the program">; def fno_standalone_debug : Flag<["-"], "fno-standalone-debug">, Group<f_Group>, Flags<[CoreOption]>, @@ -1827,6 +1844,7 @@ def foptimization_record_passes_EQ : Joined<["-"], "foptimization-record-passes= MetaVarName<"<regex>">; def ftest_coverage : Flag<["-"], "ftest-coverage">, Group<f_Group>; +def fno_test_coverage : Flag<["-"], "fno-test-coverage">, Group<f_Group>; def fvectorize : Flag<["-"], "fvectorize">, Group<f_Group>, HelpText<"Enable the loop vectorization passes">; def fno_vectorize : Flag<["-"], "fno-vectorize">, Group<f_Group>; @@ -1875,10 +1893,7 @@ def funroll_loops : Flag<["-"], "funroll-loops">, Group<f_Group>, HelpText<"Turn on loop unroller">, Flags<[CC1Option]>; def fno_unroll_loops : Flag<["-"], "fno-unroll-loops">, Group<f_Group>, HelpText<"Turn off loop unroller">, Flags<[CC1Option]>; -def freroll_loops : Flag<["-"], "freroll-loops">, Group<f_Group>, - HelpText<"Turn on loop reroller">, Flags<[CC1Option]>; -def fno_reroll_loops : Flag<["-"], "fno-reroll-loops">, Group<f_Group>, - HelpText<"Turn off loop reroller">; +defm reroll_loops : OptInFFlag<"reroll-loops", "Turn on loop reroller">; def ftrigraphs : Flag<["-"], "ftrigraphs">, Group<f_Group>, HelpText<"Process trigraph sequences">, Flags<[CC1Option]>; def fno_trigraphs : Flag<["-"], "fno-trigraphs">, Group<f_Group>, @@ -1890,10 +1905,10 @@ def funwind_tables : Flag<["-"], "funwind-tables">, Group<f_Group>; def fuse_cxa_atexit : Flag<["-"], "fuse-cxa-atexit">, Group<f_Group>; def fregister_global_dtors_with_atexit : Flag<["-"], "fregister-global-dtors-with-atexit">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Use atexit or __cxa_atexit to register global destructors">; -def fuse_init_array : Flag<["-"], "fuse-init-array">, Group<f_Group>, Flags<[CC1Option]>, - HelpText<"Use .init_array instead of .ctors">; +defm use_init_array : OptOutFFlag<"use-init-array", "", "Use .ctors/.dtors instead of .init_array/.fini_array">; def fno_var_tracking : Flag<["-"], "fno-var-tracking">, Group<clang_ignored_f_Group>; -def fverbose_asm : Flag<["-"], "fverbose-asm">, Group<f_Group>; +def fverbose_asm : Flag<["-"], "fverbose-asm">, Group<f_Group>, + HelpText<"Generate verbose assembly output">; def dA : Flag<["-"], "dA">, Alias<fverbose_asm>; def fvisibility_EQ : Joined<["-"], "fvisibility=">, Group<f_Group>, HelpText<"Set the default symbol visibility for all global declarations">, Values<"hidden,default">; @@ -1905,76 +1920,51 @@ def fvisibility_ms_compat : Flag<["-"], "fvisibility-ms-compat">, Group<f_Group> "variables 'hidden' visibility by default">; def fvisibility_global_new_delete_hidden : Flag<["-"], "fvisibility-global-new-delete-hidden">, Group<f_Group>, HelpText<"Give global C++ operator new and delete declarations hidden visibility">, Flags<[CC1Option]>; -def fwhole_program_vtables : Flag<["-"], "fwhole-program-vtables">, Group<f_Group>, - Flags<[CoreOption, CC1Option]>, - HelpText<"Enables whole-program vtable optimization. Requires -flto">; -def fno_whole_program_vtables : Flag<["-"], "fno-whole-program-vtables">, Group<f_Group>, - Flags<[CoreOption]>; -def fsplit_lto_unit : Flag<["-"], "fsplit-lto-unit">, Group<f_Group>, - Flags<[CoreOption, CC1Option]>, - HelpText<"Enables splitting of the LTO unit.">; -def fno_split_lto_unit : Flag<["-"], "fno-split-lto-unit">, Group<f_Group>, - Flags<[CoreOption]>; -def fforce_emit_vtables : Flag<["-"], "fforce-emit-vtables">, Group<f_Group>, - Flags<[CC1Option]>, - HelpText<"Emits more virtual tables to improve devirtualization">; -def fno_force_emit_vtables : Flag<["-"], "fno-force-emit-vtables">, Group<f_Group>, - Flags<[CoreOption]>; - -def fvirtual_function_elimination : Flag<["-"], "fvirtual-function-elimination">, Group<f_Group>, - Flags<[CoreOption, CC1Option]>, - HelpText<"Enables dead virtual function elimination optimization. Requires -flto=full">; -def fno_virtual_function_elimination : Flag<["-"], "fno-virtual-function_elimination">, Group<f_Group>, - Flags<[CoreOption]>; +defm whole_program_vtables : OptInFFlag<"whole-program-vtables", + "Enables whole-program vtable optimization. Requires -flto", "", "", [CoreOption]>; +defm split_lto_unit : OptInFFlag<"split-lto-unit", + "Enables splitting of the LTO unit", "", "", [CoreOption]>; +defm force_emit_vtables : OptInFFlag<"force-emit-vtables", + "Emits more virtual tables to improve devirtualization", "", "", [CoreOption]>; +defm virtual_function_elimination : OptInFFlag<"virtual-function-elimination", + "Enables dead virtual function elimination optimization. Requires -flto=full", "", "", [CoreOption]>; def fwrapv : Flag<["-"], "fwrapv">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Treat signed integer overflow as two's complement">; def fwritable_strings : Flag<["-"], "fwritable-strings">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Store string literals as writable data">; -def fzero_initialized_in_bss : Flag<["-"], "fzero-initialized-in-bss">, Group<f_Group>; -def ffunction_sections : Flag<["-"], "ffunction-sections">, Group<f_Group>, - Flags<[CC1Option]>, - HelpText<"Place each function in its own section (ELF Only)">; -def fno_function_sections : Flag<["-"], "fno-function-sections">, - Group<f_Group>, Flags<[CC1Option]>; -def fdata_sections : Flag <["-"], "fdata-sections">, Group<f_Group>, - Flags<[CC1Option]>, HelpText<"Place each data in its own section (ELF Only)">; -def fno_data_sections : Flag <["-"], "fno-data-sections">, Group<f_Group>, - Flags<[CC1Option]>; -def fstack_size_section : Flag<["-"], "fstack-size-section">, Group<f_Group>, Flags<[CC1Option]>, - HelpText<"Emit section containing metadata on function stack sizes">; -def fno_stack_size_section : Flag<["-"], "fno-stack-size-section">, Group<f_Group>, Flags<[CC1Option]>, - HelpText<"Don't emit section containing metadata on function stack sizes">; - -def funique_section_names : Flag <["-"], "funique-section-names">, - Group<f_Group>, Flags<[CC1Option]>, - HelpText<"Use unique names for text and data sections (ELF Only)">; -def fno_unique_section_names : Flag <["-"], "fno-unique-section-names">, - Group<f_Group>, Flags<[CC1Option]>; +defm zero_initialized_in_bss : OptOutFFlag<"zero-initialized-in-bss", "", "Don't place zero initialized data in BSS">; +defm function_sections : OptInFFlag<"function-sections", "Place each function in its own section">; +def fbasic_block_sections_EQ : Joined<["-"], "fbasic-block-sections=">, Group<f_Group>, + Flags<[CC1Option, CC1AsOption]>, + HelpText<"Place each function's basic blocks in unique sections (ELF Only) : all | labels | none | list=<file>">, + DocBrief<[{Generate labels for each basic block or place each basic block or a subset of basic blocks in its own section.}]>, + Values<"all,labels,none,list=">; +defm data_sections : OptInFFlag<"data-sections", "Place each data in its own section">; +defm stack_size_section : OptInFFlag<"stack-size-section", "Emit section containing metadata on function stack sizes">; + +defm unique_basic_block_section_names : OptInFFlag<"unique-basic-block-section-names", + "Use unique names for basic block sections (ELF Only)">; +defm unique_internal_linkage_names : OptInFFlag<"unique-internal-linkage-names", + "Uniqueify Internal Linkage Symbol Names by appending the MD5 hash of the module path">; +defm unique_section_names : OptOutFFlag<"unique-section-names", + "", "Don't use unique names for text and data sections">; + +defm strict_return : OptOutFFlag<"strict-return", "", + "Don't treat control flow paths that fall off the end of a non-void function as unreachable">; + +def fenable_matrix : Flag<["-"], "fenable-matrix">, Group<f_Group>, + Flags<[CC1Option]>, + HelpText<"Enable matrix data type and related builtin functions">; -def fstrict_return : Flag<["-"], "fstrict-return">, Group<f_Group>, - Flags<[CC1Option]>, - HelpText<"Always treat control flow paths that fall off the end of a " - "non-void function as unreachable">; -def fno_strict_return : Flag<["-"], "fno-strict-return">, Group<f_Group>, - Flags<[CC1Option]>; - -def fallow_editor_placeholders : Flag<["-"], "fallow-editor-placeholders">, - Group<f_Group>, Flags<[CC1Option]>, - HelpText<"Treat editor placeholders as valid source code">; -def fno_allow_editor_placeholders : Flag<["-"], - "fno-allow-editor-placeholders">, Group<f_Group>; 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_ranges_base_address: Flag <["-"], "fdebug-ranges-base-address">, Group<f_Group>, - Flags<[CC1Option]>, HelpText<"Use DWARF base address selection entries in debug_ranges">; -def fno_debug_ranges_base_address: Flag <["-"], "fno-debug-ranges-base-address">, 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>; +defm debug_ranges_base_address : OptInFFlag<"debug-ranges-base-address", + "Use DWARF base address selection entries in .debug_ranges">; def fsplit_dwarf_inlining: Flag <["-"], "fsplit-dwarf-inlining">, Group<f_Group>, - Flags<[CC1Option]>, HelpText<"Provide minimal debug info in the object/executable to facilitate online symbolication/stack traces in the absence of .dwo/.dwp files when using Split DWARF">; + HelpText<"Provide minimal debug info in the object/executable to facilitate online symbolication/stack traces in the absence of .dwo/.dwp files when using Split DWARF">; def fno_split_dwarf_inlining: Flag<["-"], "fno-split-dwarf-inlining">, Group<f_Group>, Flags<[CC1Option]>; def fdebug_default_version: Joined<["-"], "fdebug-default-version=">, Group<f_Group>, @@ -1984,15 +1974,12 @@ def fdebug_prefix_map_EQ Flags<[CC1Option,CC1AsOption]>, HelpText<"remap file source paths in debug info">; def ffile_prefix_map_EQ - : Joined<["-"], "ffile-prefix-map=">, Group<f_Group>, Flags<[CC1Option]>, + : Joined<["-"], "ffile-prefix-map=">, Group<f_Group>, HelpText<"remap file source paths in debug info and predefined preprocessor macros">; def fmacro_prefix_map_EQ : Joined<["-"], "fmacro-prefix-map=">, Group<Preprocessor_Group>, Flags<[CC1Option]>, HelpText<"remap file source paths in predefined preprocessor macros">; -def fforce_dwarf_frame : Flag<["-"], "fforce-dwarf-frame">, Group<f_Group>, Flags<[CC1Option]>, - HelpText<"Always emit a debug frame section">; -def fno_force_dwarf_frame : Flag<["-"], "fno-force-dwarf-frame">, Group<f_Group>, Flags<[CC1Option]>, - HelpText<"Don't always emit a debug frame section">; +defm force_dwarf_frame : OptInFFlag<"force-dwarf-frame", "Always emit a debug frame section">; def g_Flag : Flag<["-"], "g">, Group<g_Group>, HelpText<"Generate source-level debug information">; def gline_tables_only : Flag<["-"], "gline-tables-only">, Group<gN_Group>, @@ -2051,15 +2038,15 @@ def : Flag<["-"], "gno-record-gcc-switches">, Alias<gno_record_command_line>; def gstrict_dwarf : Flag<["-"], "gstrict-dwarf">, Group<g_flags_Group>; def gno_strict_dwarf : Flag<["-"], "gno-strict-dwarf">, Group<g_flags_Group>; def gcolumn_info : Flag<["-"], "gcolumn-info">, Group<g_flags_Group>, Flags<[CoreOption]>; -def gno_column_info : Flag<["-"], "gno-column-info">, Group<g_flags_Group>, Flags<[CoreOption]>; +def gno_column_info : Flag<["-"], "gno-column-info">, Group<g_flags_Group>, Flags<[CoreOption, CC1Option]>; def gsplit_dwarf : Flag<["-"], "gsplit-dwarf">, Group<g_flags_Group>; def gsplit_dwarf_EQ : Joined<["-"], "gsplit-dwarf=">, Group<g_flags_Group>, HelpText<"Set DWARF fission mode to either 'split' or 'single'">, Values<"split,single">; def ggnu_pubnames : Flag<["-"], "ggnu-pubnames">, Group<g_flags_Group>, Flags<[CC1Option]>; -def gno_gnu_pubnames : Flag<["-"], "gno-gnu-pubnames">, Group<g_flags_Group>, Flags<[CC1Option]>; +def gno_gnu_pubnames : Flag<["-"], "gno-gnu-pubnames">, Group<g_flags_Group>; def gpubnames : Flag<["-"], "gpubnames">, Group<g_flags_Group>, Flags<[CC1Option]>; -def gno_pubnames : Flag<["-"], "gno-pubnames">, Group<g_flags_Group>, Flags<[CC1Option]>; +def gno_pubnames : Flag<["-"], "gno-pubnames">, Group<g_flags_Group>; def gdwarf_aranges : Flag<["-"], "gdwarf-aranges">, Group<g_flags_Group>; def gmodules : Flag <["-"], "gmodules">, Group<gN_Group>, HelpText<"Generate debug info with external references to clang modules" @@ -2076,6 +2063,10 @@ def gno_embed_source : Flag<["-"], "gno-embed-source">, Group<g_flags_Group>, def headerpad__max__install__names : Joined<["-"], "headerpad_max_install_names">; def help : Flag<["-", "--"], "help">, Flags<[CC1Option,CC1AsOption]>, HelpText<"Display available options">; +def ibuiltininc : Flag<["-"], "ibuiltininc">, + HelpText<"Enable builtin #include directories even when -nostdinc is used " + "before or after -ibuiltininc. " + "Using -nobuiltininc after the option disables it">; def index_header_map : Flag<["-"], "index-header-map">, Flags<[CC1Option]>, HelpText<"Make the next included directory (-I or -F) an indexer header map">; def idirafter : JoinedOrSeparate<["-"], "idirafter">, Group<clang_i_Group>, Flags<[CC1Option]>, @@ -2146,13 +2137,19 @@ def mno_iamcu : Flag<["-"], "mno-iamcu">, Group<m_Group>, Flags<[DriverOption, C def malign_functions_EQ : Joined<["-"], "malign-functions=">, Group<clang_ignored_m_Group>; def malign_loops_EQ : Joined<["-"], "malign-loops=">, Group<clang_ignored_m_Group>; def malign_jumps_EQ : Joined<["-"], "malign-jumps=">, Group<clang_ignored_m_Group>; -def malign_branch_EQ : CommaJoined<["-"], "malign-branch=">, Group<m_Group>; -def malign_branch_boundary_EQ : Joined<["-"], "malign-branch-boundary=">, Group<m_Group>; -def malign_branch_prefix_size_EQ : Joined<["-"], "malign-branch-prefix-size=">, Group<m_Group>; -def mbranches_within_32B_boundaries : Flag<["-"], "mbranches-within-32B-boundaries">, Flags<[DriverOption]>, Group<m_Group>; +def malign_branch_EQ : CommaJoined<["-"], "malign-branch=">, Group<m_Group>, Flags<[DriverOption]>, + HelpText<"Specify types of branches to align">; +def malign_branch_boundary_EQ : Joined<["-"], "malign-branch-boundary=">, Group<m_Group>, Flags<[DriverOption]>, + HelpText<"Specify the boundary's size to align branches">; +def mpad_max_prefix_size_EQ : Joined<["-"], "mpad-max-prefix-size=">, Group<m_Group>, Flags<[DriverOption]>, + HelpText<"Specify maximum number of prefixes to use for padding">; +def mbranches_within_32B_boundaries : Flag<["-"], "mbranches-within-32B-boundaries">, Flags<[DriverOption]>, Group<m_Group>, + HelpText<"Align selected branches (fused, jcc, jmp) within 32-byte boundary">; def mfancy_math_387 : Flag<["-"], "mfancy-math-387">, Group<clang_ignored_m_Group>; def mlong_calls : Flag<["-"], "mlong-calls">, Group<m_Group>, HelpText<"Generate branches with extended addressability, usually via indirect jumps.">; +def mdouble_EQ : Joined<["-"], "mdouble=">, Group<m_Group>, Values<"32,64">, Flags<[CC1Option]>, + HelpText<"Force double to be 32 bits or 64 bits">; def LongDouble_Group : OptionGroup<"<LongDouble group>">, Group<m_Group>, DocName<"Long double flags">, DocBrief<[{Selects the long double implementation}]>; @@ -2181,7 +2178,7 @@ def mwatchos_simulator_version_min_EQ : Joined<["-"], "mwatchos-simulator-versio def mwatchsimulator_version_min_EQ : Joined<["-"], "mwatchsimulator-version-min=">, Alias<mwatchos_simulator_version_min_EQ>; def march_EQ : Joined<["-"], "march=">, Group<m_Group>, Flags<[CoreOption]>; def masm_EQ : Joined<["-"], "masm=">, Group<m_Group>, Flags<[DriverOption]>; -def mcmodel_EQ : Joined<["-"], "mcmodel=">, Group<m_Group>; +def mcmodel_EQ : Joined<["-"], "mcmodel=">, Group<m_Group>, Flags<[CC1Option]>; def mtls_size_EQ : Joined<["-"], "mtls-size=">, Group<m_Group>, Flags<[DriverOption, CC1Option]>, HelpText<"Specify bit size of immediate TLS offsets (AArch64 ELF only): " "12 (for 4KB) | 24 (for 16MB, default) | 32 (for 4GB) | 48 (for 256TB, needs -mcmodel=large)">; @@ -2267,11 +2264,27 @@ def mspeculative_load_hardening : Flag<["-"], "mspeculative-load-hardening">, Group<m_Group>, Flags<[CoreOption,CC1Option]>; def mno_speculative_load_hardening : Flag<["-"], "mno-speculative-load-hardening">, Group<m_Group>, Flags<[CoreOption]>; +def mlvi_hardening : Flag<["-"], "mlvi-hardening">, Group<m_Group>, Flags<[CoreOption,DriverOption]>, + HelpText<"Enable all mitigations for Load Value Injection (LVI)">; +def mno_lvi_hardening : Flag<["-"], "mno-lvi-hardening">, Group<m_Group>, Flags<[CoreOption,DriverOption]>, + HelpText<"Disable mitigations for Load Value Injection (LVI)">; +def mlvi_cfi : Flag<["-"], "mlvi-cfi">, Group<m_Group>, Flags<[CoreOption,DriverOption]>, + HelpText<"Enable only control-flow mitigations for Load Value Injection (LVI)">; +def mno_lvi_cfi : Flag<["-"], "mno-lvi-cfi">, Group<m_Group>, Flags<[CoreOption,DriverOption]>, + HelpText<"Disable control-flow mitigations for Load Value Injection (LVI)">; +def m_seses : Flag<["-"], "mseses">, Group<m_Group>, Flags<[CoreOption, DriverOption]>, + HelpText<"Enable speculative execution side effect suppression (SESES). " + "Includes LVI control flow integrity mitigations">; +def mno_seses : Flag<["-"], "mno-seses">, Group<m_Group>, Flags<[CoreOption, DriverOption]>, + HelpText<"Disable speculative execution side effect suppression (SESES)">; def mrelax : Flag<["-"], "mrelax">, Group<m_riscv_Features_Group>, HelpText<"Enable linker relaxation">; def mno_relax : Flag<["-"], "mno-relax">, Group<m_riscv_Features_Group>, HelpText<"Disable linker relaxation">; +def msmall_data_limit_EQ : Joined<["-"], "msmall-data-limit=">, Group<m_Group>, + Alias<G>, + HelpText<"Put global and static data smaller than the limit into a special section">; def msave_restore : Flag<["-"], "msave-restore">, Group<m_riscv_Features_Group>, HelpText<"Enable using library calls for save and restore">; def mno_save_restore : Flag<["-"], "mno-save-restore">, Group<m_riscv_Features_Group>, @@ -2282,6 +2295,8 @@ def mcmodel_EQ_medlow : Flag<["-"], "mcmodel=medlow">, Group<m_riscv_Features_Gr def mcmodel_EQ_medany : Flag<["-"], "mcmodel=medany">, Group<m_riscv_Features_Group>, Flags<[CC1Option]>, Alias<mcmodel_EQ>, AliasArgs<["medium"]>, HelpText<"Equivalent to -mcmodel=medium, compatible with RISC-V gcc.">; +def menable_experimental_extensions : Flag<["-"], "menable-experimental-extensions">, Group<m_Group>, + HelpText<"Enable use of experimental RISC-V extensions.">; def munaligned_access : Flag<["-"], "munaligned-access">, Group<m_arm_Features_Group>, HelpText<"Allow memory accesses to be unaligned (AArch32/AArch64 only)">; @@ -2308,6 +2323,9 @@ def mno_neg_immediates: Flag<["-"], "mno-neg-immediates">, Group<m_arm_Features_ def mcmse : Flag<["-"], "mcmse">, Group<m_arm_Features_Group>, Flags<[DriverOption,CC1Option]>, HelpText<"Allow use of CMSE (Armv8-M Security Extensions)">; +def ForceAAPCSBitfieldLoad : Flag<["-"], "fAAPCSBitfieldLoad">, Group<m_arm_Features_Group>, + Flags<[DriverOption,CC1Option]>, + HelpText<"Follows the AAPCS standard that all volatile bit-field write generates at least one load. (ARM only).">; def mgeneral_regs_only : Flag<["-"], "mgeneral-regs-only">, Group<m_aarch64_Features_Group>, HelpText<"Generate code which only uses the general purpose registers (AArch64 only)">; @@ -2319,7 +2337,7 @@ def mno_fix_cortex_a53_835769 : Flag<["-"], "mno-fix-cortex-a53-835769">, HelpText<"Don't workaround Cortex-A53 erratum 835769 (AArch64 only)">; foreach i = {1-31} in def ffixed_x#i : Flag<["-"], "ffixed-x"#i>, Group<m_Group>, - HelpText<"Reserve the "#i#" register (AArch64/RISC-V only)">; + HelpText<"Reserve the x"#i#" register (AArch64/RISC-V only)">; foreach i = {8-15,18} in def fcall_saved_x#i : Flag<["-"], "fcall-saved-x"#i>, Group<m_aarch64_Features_Group>, @@ -2331,6 +2349,9 @@ def msign_return_address_EQ : Joined<["-"], "msign-return-address=">, def mbranch_protection_EQ : Joined<["-"], "mbranch-protection=">, HelpText<"Enforce targets of indirect branches and function returns">; +def mharden_sls_EQ : Joined<["-"], "mharden-sls=">, + HelpText<"Select straight-line speculation hardening scope">; + def msimd128 : Flag<["-"], "msimd128">, Group<m_wasm_Features_Group>; def munimplemented_simd128 : Flag<["-"], "munimplemented-simd128">, Group<m_wasm_Features_Group>; def mno_unimplemented_simd128 : Flag<["-"], "mno-unimplemented-simd128">, Group<m_wasm_Features_Group>; @@ -2353,6 +2374,9 @@ def mtail_call : Flag<["-"], "mtail-call">, Group<m_wasm_Features_Group>; def mno_tail_call : Flag<["-"], "mno-tail-call">, Group<m_wasm_Features_Group>; def mreference_types : Flag<["-"], "mreference-types">, Group<m_wasm_Features_Group>; def mno_reference_types : Flag<["-"], "mno-reference-types">, Group<m_wasm_Features_Group>; +def mexec_model_EQ : Joined<["-"], "mexec-model=">, Group<m_wasm_Features_Driver_Group>, + Values<"command,reactor">, + HelpText<"Execution model (WebAssembly only)">; def mamdgpu_debugger_abi : Joined<["-"], "mamdgpu-debugger-abi=">, Flags<[HelpHidden]>, @@ -2387,6 +2411,8 @@ def faltivec : Flag<["-"], "faltivec">, Group<f_Group>, Flags<[DriverOption]>; def fno_altivec : Flag<["-"], "fno-altivec">, Group<f_Group>, Flags<[DriverOption]>; def maltivec : Flag<["-"], "maltivec">, Group<m_ppc_Features_Group>; def mno_altivec : Flag<["-"], "mno-altivec">, Group<m_ppc_Features_Group>; +def mpcrel: Flag<["-"], "mpcrel">, Group<m_ppc_Features_Group>; +def mno_pcrel: Flag<["-"], "mno-pcrel">, Group<m_ppc_Features_Group>; def mspe : Flag<["-"], "mspe">, Group<m_ppc_Features_Group>; def mno_spe : Flag<["-"], "mno-spe">, Group<m_ppc_Features_Group>; def mvsx : Flag<["-"], "mvsx">, Group<m_ppc_Features_Group>; @@ -2400,6 +2426,10 @@ def mpower9_vector : Flag<["-"], "mpower9-vector">, Group<m_ppc_Features_Group>; def mno_power9_vector : Flag<["-"], "mno-power9-vector">, Group<m_ppc_Features_Group>; +def mpower10_vector : Flag<["-"], "mpower10-vector">, + Group<m_ppc_Features_Group>; +def mno_power10_vector : Flag<["-"], "mno-power10-vector">, + Group<m_ppc_Features_Group>; def mpower8_crypto : Flag<["-"], "mcrypto">, Group<m_ppc_Features_Group>; def mnopower8_crypto : Flag<["-"], "mno-crypto">, @@ -2439,14 +2469,17 @@ def mlongcall: Flag<["-"], "mlongcall">, Group<m_ppc_Features_Group>; def mno_longcall : Flag<["-"], "mno-longcall">, Group<m_ppc_Features_Group>; +def maix_struct_return : Flag<["-"], "maix-struct-return">, + Group<m_Group>, Flags<[CC1Option]>, + HelpText<"Return all structs in memory (PPC32 only)">; +def msvr4_struct_return : Flag<["-"], "msvr4-struct-return">, + Group<m_Group>, Flags<[CC1Option]>, + HelpText<"Return small structs in registers (PPC32 only)">; def mvx : Flag<["-"], "mvx">, Group<m_Group>; def mno_vx : Flag<["-"], "mno-vx">, Group<m_Group>; -def fzvector : Flag<["-"], "fzvector">, Group<f_Group>, Flags<[CC1Option]>, - HelpText<"Enable System z vector language extension">; -def fno_zvector : Flag<["-"], "fno-zvector">, Group<f_Group>, - Flags<[CC1Option]>; +defm zvector : OptInFFlag<"zvector", "Enable System z vector language extension">; def mzvector : Flag<["-"], "mzvector">, Alias<fzvector>; def mno_zvector : Flag<["-"], "mno-zvector">, Alias<fno_zvector>; @@ -2647,7 +2680,8 @@ def muclibc : Flag<["-"], "muclibc">, Group<m_libc_Group>, Flags<[HelpHidden]>; def module_file_info : Flag<["-"], "module-file-info">, Flags<[DriverOption,CC1Option]>, Group<Action_Group>, HelpText<"Provide information about a particular module file">; def mthumb : Flag<["-"], "mthumb">, Group<m_Group>; -def mtune_EQ : Joined<["-"], "mtune=">, Group<m_Group>; +def mtune_EQ : Joined<["-"], "mtune=">, Group<m_Group>, + HelpText<"Accepted for compatibility with GCC. Currently has no effect.">; def multi__module : Flag<["-"], "multi_module">; def multiply__defined__unused : Separate<["-"], "multiply_defined_unused">; def multiply__defined : Separate<["-"], "multiply_defined">; @@ -2660,7 +2694,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, CoreOption]>, HelpText<"Disable builtin #include directories">; -def nocudainc : Flag<["-"], "nocudainc">; +def nogpuinc : Flag<["-"], "nogpuinc">; +def : Flag<["-"], "nocudainc">, Alias<nogpuinc>; def nogpulib : Flag<["-"], "nogpulib">, HelpText<"Do not link device library for CUDA/HIP device compilation">; def : Flag<["-"], "nocudalib">, Alias<nogpulib>; @@ -2714,6 +2749,8 @@ def print_resource_dir : Flag<["-", "--"], "print-resource-dir">, HelpText<"Print the resource directory pathname">; def print_search_dirs : Flag<["-", "--"], "print-search-dirs">, HelpText<"Print the paths used for finding libraries and programs">; +def print_targets : Flag<["-", "--"], "print-targets">, + HelpText<"Print the registered targets">; def private__bundle : Flag<["-"], "private_bundle">; def pthreads : Flag<["-"], "pthreads">; def pthread : Flag<["-"], "pthread">, Flags<[CC1Option]>, @@ -2850,11 +2887,15 @@ def x : JoinedOrSeparate<["-"], "x">, Flags<[DriverOption,CC1Option]>, MetaVarName<"<language>">; def y : Joined<["-"], "y">; -def fintegrated_as : Flag<["-"], "fintegrated-as">, Flags<[DriverOption]>, - Group<f_Group>, HelpText<"Enable the integrated assembler">; -def fno_integrated_as : Flag<["-"], "fno-integrated-as">, - Flags<[CC1Option, DriverOption]>, Group<f_Group>, - HelpText<"Disable the integrated assembler">; +defm integrated_as : OptOutFFlag<"integrated-as", "Enable the integrated assembler", "Disable the integrated assembler">; + +def fintegrated_cc1 : Flag<["-"], "fintegrated-cc1">, + Flags<[CoreOption, DriverOption]>, Group<f_Group>, + HelpText<"Run cc1 in-process">; +def fno_integrated_cc1 : Flag<["-"], "fno-integrated-cc1">, + Flags<[CoreOption, DriverOption]>, Group<f_Group>, + HelpText<"Spawn a separate process for each cc1">; + def : Flag<["-"], "integrated-as">, Alias<fintegrated_as>, Flags<[DriverOption]>; def : Flag<["-"], "no-integrated-as">, Alias<fno_integrated_as>, Flags<[CC1Option, DriverOption]>; @@ -2991,6 +3032,10 @@ def mv65 : Flag<["-"], "mv65">, Group<m_hexagon_Features_Group>, Alias<mcpu_EQ>, AliasArgs<["hexagonv65"]>; def mv66 : Flag<["-"], "mv66">, Group<m_hexagon_Features_Group>, Alias<mcpu_EQ>, AliasArgs<["hexagonv66"]>; +def mv67 : Flag<["-"], "mv67">, Group<m_hexagon_Features_Group>, + Alias<mcpu_EQ>, AliasArgs<["hexagonv67"]>; +def mv67t : Flag<["-"], "mv67t">, Group<m_hexagon_Features_Group>, + Alias<mcpu_EQ>, AliasArgs<["hexagonv67t"]>; def mhexagon_hvx : Flag<["-"], "mhvx">, Group<m_hexagon_Features_HVX_Group>, HelpText<"Enable Hexagon Vector eXtensions">; def mhexagon_hvx_EQ : Joined<["-"], "mhvx=">, @@ -3033,6 +3078,12 @@ def m3dnow : Flag<["-"], "m3dnow">, Group<m_x86_Features_Group>; def mno_3dnow : Flag<["-"], "mno-3dnow">, Group<m_x86_Features_Group>; def m3dnowa : Flag<["-"], "m3dnowa">, Group<m_x86_Features_Group>; def mno_3dnowa : Flag<["-"], "mno-3dnowa">, Group<m_x86_Features_Group>; +def mamx_bf16 : Flag<["-"], "mamx-bf16">, Group<m_x86_Features_Group>; +def mno_amx_bf16 : Flag<["-"], "mno-amx-bf16">, Group<m_x86_Features_Group>; +def mtamx_int8 : Flag<["-"], "mamx-int8">, Group<m_x86_Features_Group>; +def mno_amx_int8 : Flag<["-"], "mno-amx-int8">, Group<m_x86_Features_Group>; +def mamx_tile : Flag<["-"], "mamx-tile">, Group<m_x86_Features_Group>; +def mno_amx_tile : Flag<["-"], "mno-amx-tile">, Group<m_x86_Features_Group>; def msse : Flag<["-"], "msse">, Group<m_x86_Features_Group>; def mno_sse : Flag<["-"], "mno-sse">, Group<m_x86_Features_Group>; def msse2 : Flag<["-"], "msse2">, Group<m_x86_Features_Group>; @@ -3158,12 +3209,16 @@ def mrdseed : Flag<["-"], "mrdseed">, Group<m_x86_Features_Group>; def mno_rdseed : Flag<["-"], "mno-rdseed">, Group<m_x86_Features_Group>; def msahf : Flag<["-"], "msahf">, Group<m_x86_Features_Group>; def mno_sahf : Flag<["-"], "mno-sahf">, Group<m_x86_Features_Group>; +def mserialize : Flag<["-"], "mserialize">, Group<m_x86_Features_Group>; +def mno_serialize : Flag<["-"], "mno-serialize">, Group<m_x86_Features_Group>; def msgx : Flag<["-"], "msgx">, Group<m_x86_Features_Group>; def mno_sgx : Flag<["-"], "mno-sgx">, Group<m_x86_Features_Group>; def msha : Flag<["-"], "msha">, Group<m_x86_Features_Group>; def mno_sha : Flag<["-"], "mno-sha">, Group<m_x86_Features_Group>; def mtbm : Flag<["-"], "mtbm">, Group<m_x86_Features_Group>; def mno_tbm : Flag<["-"], "mno-tbm">, Group<m_x86_Features_Group>; +def mtsxldtrk : Flag<["-"], "mtsxldtrk">, Group<m_x86_Features_Group>; +def mno_tsxldtrk : Flag<["-"], "mno-tsxldtrk">, Group<m_x86_Features_Group>; def mvaes : Flag<["-"], "mvaes">, Group<m_x86_Features_Group>; def mno_vaes : Flag<["-"], "mno-vaes">, Group<m_x86_Features_Group>; def mvpclmulqdq : Flag<["-"], "mvpclmulqdq">, Group<m_x86_Features_Group>; @@ -3208,11 +3263,9 @@ def Z_reserved_lib_cckext : Flag<["-"], "Z-reserved-lib-cckext">, Flags<[LinkerInput, NoArgumentUnused, Unsupported]>, Group<reserved_lib_Group>; // Ignored options -// FIXME: multiclasess produce suffixes, not prefixes. This is fine for now -// since it is only used in ignored options. multiclass BooleanFFlag<string name> { - def _f : Flag<["-"], "f"#name>; - def _fno : Flag<["-"], "fno-"#name>; + def f#NAME : Flag<["-"], "f"#name>; + def fno_#NAME : Flag<["-"], "fno-"#name>; } defm : BooleanFFlag<"keep-inline-functions">, Group<clang_ignored_gcc_optimization_f_Group>; @@ -3262,7 +3315,8 @@ defm inline_small_functions : BooleanFFlag<"inline-small-functions">, defm ipa_cp : BooleanFFlag<"ipa-cp">, Group<clang_ignored_gcc_optimization_f_Group>; defm ivopts : BooleanFFlag<"ivopts">, Group<clang_ignored_gcc_optimization_f_Group>; -def : Flag<["-"], "fno-semantic-interposition">, Group<clang_ignored_f_Group>; +def fsemantic_interposition : Flag<["-"], "fsemantic-interposition">, Group<f_Group>, Flags<[CC1Option]>; +def fno_semantic_interposition: Flag<["-"], "fno-semantic-interposition">, Group<f_Group>, Flags<[CC1Option]>; defm non_call_exceptions : BooleanFFlag<"non-call-exceptions">, Group<clang_ignored_f_Group>; defm peel_loops : BooleanFFlag<"peel-loops">, Group<clang_ignored_gcc_optimization_f_Group>; defm permissive : BooleanFFlag<"permissive">, Group<clang_ignored_f_Group>; @@ -3289,9 +3343,6 @@ defm strength_reduce : defm tls_model : BooleanFFlag<"tls-model">, Group<clang_ignored_f_Group>; defm tracer : BooleanFFlag<"tracer">, Group<clang_ignored_gcc_optimization_f_Group>; defm tree_dce : BooleanFFlag<"tree-dce">, Group<clang_ignored_gcc_optimization_f_Group>; -defm tree_loop_im : BooleanFFlag<"tree_loop_im">, Group<clang_ignored_gcc_optimization_f_Group>; -defm tree_loop_ivcanon : BooleanFFlag<"tree_loop_ivcanon">, Group<clang_ignored_gcc_optimization_f_Group>; -defm tree_loop_linear : BooleanFFlag<"tree_loop_linear">, Group<clang_ignored_gcc_optimization_f_Group>; defm tree_salias : BooleanFFlag<"tree-salias">, Group<clang_ignored_f_Group>; defm tree_ter : BooleanFFlag<"tree-ter">, Group<clang_ignored_gcc_optimization_f_Group>; defm tree_vectorizer_verbose : BooleanFFlag<"tree-vectorizer-verbose">, Group<clang_ignored_f_Group>; @@ -3383,7 +3434,1413 @@ defm stack_arrays : BooleanFFlag<"stack-arrays">, Group<gfortran_Group>; defm underscoring : BooleanFFlag<"underscoring">, Group<gfortran_Group>; defm whole_file : BooleanFFlag<"whole-file">, Group<gfortran_Group>; +// C++ SYCL options +def fsycl : Flag<["-"], "fsycl">, Group<sycl_Group>, Flags<[CC1Option, CoreOption]>, + HelpText<"Enable SYCL kernels compilation for device">; +def fno_sycl : Flag<["-"], "fno-sycl">, Group<sycl_Group>, Flags<[CoreOption]>, + HelpText<"Disable SYCL kernels compilation for device">; +def sycl_std_EQ : Joined<["-"], "sycl-std=">, Group<sycl_Group>, Flags<[CC1Option, NoArgumentUnused, CoreOption]>, + HelpText<"SYCL language standard to compile for.">, Values<"2017, 121, 1.2.1, sycl-1.2.1">; + +//===----------------------------------------------------------------------===// +// CC1 Options +//===----------------------------------------------------------------------===// + +let Flags = [CC1Option, NoDriverOption] in { + +//===----------------------------------------------------------------------===// +// Target Options +//===----------------------------------------------------------------------===// + +let Flags = [CC1Option, CC1AsOption, NoDriverOption] in { + +def target_cpu : Separate<["-"], "target-cpu">, + HelpText<"Target a specific cpu type">; +def target_feature : Separate<["-"], "target-feature">, + HelpText<"Target specific attributes">; +def triple : Separate<["-"], "triple">, + HelpText<"Specify target triple (e.g. i686-apple-darwin9)">, + MarshallingInfoString<"TargetOpts->Triple", "llvm::Triple::normalize(llvm::sys::getDefaultTargetTriple())", "std::string">, + AlwaysEmit, Normalizer<"normalizeTriple">, DenormalizeString; +def target_abi : Separate<["-"], "target-abi">, + HelpText<"Target a particular ABI type">; +def target_sdk_version_EQ : Joined<["-"], "target-sdk-version=">, + HelpText<"The version of target SDK used for compilation">; + +} + +def target_linker_version : Separate<["-"], "target-linker-version">, + HelpText<"Target linker version">; +def triple_EQ : Joined<["-"], "triple=">, Alias<triple>; +def mfpmath : Separate<["-"], "mfpmath">, + HelpText<"Which unit to use for fp math">; + +def fpadding_on_unsigned_fixed_point : Flag<["-"], "fpadding-on-unsigned-fixed-point">, + HelpText<"Force each unsigned fixed point type to have an extra bit of padding to align their scales with those of signed fixed point types">; +def fno_padding_on_unsigned_fixed_point : Flag<["-"], "fno-padding-on-unsigned-fixed-point">; + +//===----------------------------------------------------------------------===// +// Analyzer Options +//===----------------------------------------------------------------------===// + +def analysis_UnoptimizedCFG : Flag<["-"], "unoptimized-cfg">, + HelpText<"Generate unoptimized CFGs for all analyses">; +def analysis_CFGAddImplicitDtors : Flag<["-"], "cfg-add-implicit-dtors">, + HelpText<"Add C++ implicit destructors to CFGs for all analyses">; + +def analyzer_store : Separate<["-"], "analyzer-store">, + HelpText<"Source Code Analysis - Abstract Memory Store Models">; +def analyzer_store_EQ : Joined<["-"], "analyzer-store=">, Alias<analyzer_store>; + +def analyzer_constraints : Separate<["-"], "analyzer-constraints">, + HelpText<"Source Code Analysis - Symbolic Constraint Engines">; +def analyzer_constraints_EQ : Joined<["-"], "analyzer-constraints=">, + Alias<analyzer_constraints>; + +def analyzer_output : Separate<["-"], "analyzer-output">, + HelpText<"Source Code Analysis - Output Options">; +def analyzer_output_EQ : Joined<["-"], "analyzer-output=">, + Alias<analyzer_output>; + +def analyzer_purge : Separate<["-"], "analyzer-purge">, + HelpText<"Source Code Analysis - Dead Symbol Removal Frequency">; +def analyzer_purge_EQ : Joined<["-"], "analyzer-purge=">, Alias<analyzer_purge>; + +def analyzer_opt_analyze_headers : Flag<["-"], "analyzer-opt-analyze-headers">, + HelpText<"Force the static analyzer to analyze functions defined in header files">; +def analyzer_opt_analyze_nested_blocks : Flag<["-"], "analyzer-opt-analyze-nested-blocks">, + HelpText<"Analyze the definitions of blocks in addition to functions">; +def analyzer_display_progress : Flag<["-"], "analyzer-display-progress">, + HelpText<"Emit verbose output about the analyzer's progress">; +def analyze_function : Separate<["-"], "analyze-function">, + HelpText<"Run analysis on specific function (for C++ include parameters in name)">; +def analyze_function_EQ : Joined<["-"], "analyze-function=">, Alias<analyze_function>; +def trim_egraph : Flag<["-"], "trim-egraph">, + HelpText<"Only show error-related paths in the analysis graph">; +def analyzer_viz_egraph_graphviz : Flag<["-"], "analyzer-viz-egraph-graphviz">, + HelpText<"Display exploded graph using GraphViz">; +def analyzer_dump_egraph : Separate<["-"], "analyzer-dump-egraph">, + HelpText<"Dump exploded graph to the specified file">; +def analyzer_dump_egraph_EQ : Joined<["-"], "analyzer-dump-egraph=">, Alias<analyzer_dump_egraph>; + +def analyzer_inline_max_stack_depth : Separate<["-"], "analyzer-inline-max-stack-depth">, + HelpText<"Bound on stack depth while inlining (4 by default)">; +def analyzer_inline_max_stack_depth_EQ : Joined<["-"], "analyzer-inline-max-stack-depth=">, + Alias<analyzer_inline_max_stack_depth>; + +def analyzer_inlining_mode : Separate<["-"], "analyzer-inlining-mode">, + HelpText<"Specify the function selection heuristic used during inlining">; +def analyzer_inlining_mode_EQ : Joined<["-"], "analyzer-inlining-mode=">, Alias<analyzer_inlining_mode>; + +def analyzer_disable_retry_exhausted : Flag<["-"], "analyzer-disable-retry-exhausted">, + HelpText<"Do not re-analyze paths leading to exhausted nodes with a different strategy (may decrease code coverage)">; + +def analyzer_max_loop : Separate<["-"], "analyzer-max-loop">, + HelpText<"The maximum number of times the analyzer will go through a loop">; +def analyzer_stats : Flag<["-"], "analyzer-stats">, + HelpText<"Print internal analyzer statistics.">; + +def analyzer_checker : Separate<["-"], "analyzer-checker">, + HelpText<"Choose analyzer checkers to enable">, + ValuesCode<[{ + const char *Values = + #define GET_CHECKERS + #define CHECKER(FULLNAME, CLASS, HT, DOC_URI, IS_HIDDEN) FULLNAME "," + #include "clang/StaticAnalyzer/Checkers/Checkers.inc" + #undef GET_CHECKERS + #define GET_PACKAGES + #define PACKAGE(FULLNAME) FULLNAME "," + #include "clang/StaticAnalyzer/Checkers/Checkers.inc" + #undef GET_PACKAGES + ; + }]>; +def analyzer_checker_EQ : Joined<["-"], "analyzer-checker=">, + Alias<analyzer_checker>; + +def analyzer_disable_checker : Separate<["-"], "analyzer-disable-checker">, + HelpText<"Choose analyzer checkers to disable">; +def analyzer_disable_checker_EQ : Joined<["-"], "analyzer-disable-checker=">, + Alias<analyzer_disable_checker>; + +def analyzer_disable_all_checks : Flag<["-"], "analyzer-disable-all-checks">, + HelpText<"Disable all static analyzer checks">; + +def analyzer_checker_help : Flag<["-"], "analyzer-checker-help">, + HelpText<"Display the list of analyzer checkers that are available">; + +def analyzer_checker_help_alpha : Flag<["-"], "analyzer-checker-help-alpha">, + HelpText<"Display the list of in development analyzer checkers. These " + "are NOT considered safe, they are unstable and will emit incorrect " + "reports. Enable ONLY FOR DEVELOPMENT purposes">; -include "CC1Options.td" +def analyzer_checker_help_developer : Flag<["-"], "analyzer-checker-help-developer">, + HelpText<"Display the list of developer-only checkers such as modeling " + "and debug checkers">; -include "CLCompatOptions.td" +def analyzer_config_help : Flag<["-"], "analyzer-config-help">, + HelpText<"Display the list of -analyzer-config options. These are meant for " + "development purposes only!">; + +def analyzer_list_enabled_checkers : Flag<["-"], "analyzer-list-enabled-checkers">, + HelpText<"Display the list of enabled analyzer checkers">; + +def analyzer_config : Separate<["-"], "analyzer-config">, + HelpText<"Choose analyzer options to enable">; + +def analyzer_checker_option_help : Flag<["-"], "analyzer-checker-option-help">, + HelpText<"Display the list of checker and package options">; + +def analyzer_checker_option_help_alpha : Flag<["-"], "analyzer-checker-option-help-alpha">, + HelpText<"Display the list of in development checker and package options. " + "These are NOT considered safe, they are unstable and will emit " + "incorrect reports. Enable ONLY FOR DEVELOPMENT purposes">; + +def analyzer_checker_option_help_developer : Flag<["-"], "analyzer-checker-option-help-developer">, + HelpText<"Display the list of checker and package options meant for " + "development purposes only">; + +def analyzer_config_compatibility_mode : Separate<["-"], "analyzer-config-compatibility-mode">, + HelpText<"Don't emit errors on invalid analyzer-config inputs">; + +def analyzer_config_compatibility_mode_EQ : Joined<["-"], "analyzer-config-compatibility-mode=">, + Alias<analyzer_config_compatibility_mode>; + +def analyzer_werror : Flag<["-"], "analyzer-werror">, + HelpText<"Emit analyzer results as errors rather than warnings">; + +//===----------------------------------------------------------------------===// +// Migrator Options +//===----------------------------------------------------------------------===// +def migrator_no_nsalloc_error : Flag<["-"], "no-ns-alloc-error">, + HelpText<"Do not error on use of NSAllocateCollectable/NSReallocateCollectable">; + +def migrator_no_finalize_removal : Flag<["-"], "no-finalize-removal">, + HelpText<"Do not remove finalize method in gc mode">; + +//===----------------------------------------------------------------------===// +// CodeGen Options +//===----------------------------------------------------------------------===// + +let Flags = [CC1Option, CC1AsOption, NoDriverOption] in { +def debug_info_kind_EQ : Joined<["-"], "debug-info-kind=">; +def debug_info_macro : Flag<["-"], "debug-info-macro">, + HelpText<"Emit macro debug information">; +def default_function_attr : Separate<["-"], "default-function-attr">, + HelpText<"Apply given attribute to all functions">; +def dwarf_version_EQ : Joined<["-"], "dwarf-version=">; +def debugger_tuning_EQ : Joined<["-"], "debugger-tuning=">; +def dwarf_debug_flags : Separate<["-"], "dwarf-debug-flags">, + HelpText<"The string to embed in the Dwarf debug flags record.">; +def record_command_line : Separate<["-"], "record-command-line">, + HelpText<"The string to embed in the .LLVM.command.line section.">; +def compress_debug_sections : Flag<["-", "--"], "compress-debug-sections">, + HelpText<"DWARF debug sections compression">; +def compress_debug_sections_EQ : Joined<["-", "--"], "compress-debug-sections=">, + HelpText<"DWARF debug sections compression type">; +def mno_exec_stack : Flag<["-"], "mnoexecstack">, + HelpText<"Mark the file as not needing an executable stack">; +def massembler_no_warn : Flag<["-"], "massembler-no-warn">, + HelpText<"Make assembler not emit warnings">; +def massembler_fatal_warnings : Flag<["-"], "massembler-fatal-warnings">, + HelpText<"Make assembler warnings fatal">; +def mrelax_relocations : Flag<["--"], "mrelax-relocations">, + HelpText<"Use relaxable elf relocations">; +def 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">, Values<"static,pic,ropi,rwpi,ropi-rwpi,dynamic-no-pic">, + NormalizedValuesScope<"llvm::Reloc">, + NormalizedValues<["Static", "PIC_", "ROPI", "RWPI", "ROPI_RWPI", "DynamicNoPIC"]>, + MarshallingInfoString<"CodeGenOpts.RelocationModel", "PIC_", "Model">, + AutoNormalizeEnum; +def fno_math_builtin : Flag<["-"], "fno-math-builtin">, + HelpText<"Disable implicit builtin knowledge of math functions">; +} + +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_llvm_optzns : Flag<["-"], "disable-llvm-optzns">, + Alias<disable_llvm_passes>; +def disable_lifetimemarkers : Flag<["-"], "disable-lifetime-markers">, + HelpText<"Disable lifetime-markers emission even when optimizations are " + "enabled">; +def disable_O0_optnone : Flag<["-"], "disable-O0-optnone">, + HelpText<"Disable adding the optnone attribute to functions at O0">; +def disable_red_zone : Flag<["-"], "disable-red-zone">, + HelpText<"Do not emit code that uses the red zone.">; +def dwarf_ext_refs : Flag<["-"], "dwarf-ext-refs">, + HelpText<"Generate debug info with external references to clang modules" + " or precompiled headers">; +def dwarf_explicit_import : Flag<["-"], "dwarf-explicit-import">, + HelpText<"Generate explicit import from anonymous namespace to containing" + " scope">; +def debug_forward_template_params : Flag<["-"], "debug-forward-template-params">, + HelpText<"Emit complete descriptions of template parameters in forward" + " declarations">; +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">, + HelpText<"Don't generate implicit floating point instructions">; +def fdump_vtable_layouts : Flag<["-"], "fdump-vtable-layouts">, + HelpText<"Dump the layouts of all vtables that will be emitted in a translation unit">; +def fmerge_functions : Flag<["-"], "fmerge-functions">, + HelpText<"Permit merging of identical functions when optimizing.">; +def femit_coverage_notes : Flag<["-"], "femit-coverage-notes">, + HelpText<"Emit a gcov coverage notes file when compiling.">; +def femit_coverage_data: Flag<["-"], "femit-coverage-data">, + HelpText<"Instrument the program to emit gcov coverage data when run.">; +def coverage_data_file : Separate<["-"], "coverage-data-file">, + HelpText<"Emit coverage data to this filename.">; +def coverage_data_file_EQ : Joined<["-"], "coverage-data-file=">, + Alias<coverage_data_file>; +def coverage_notes_file : Separate<["-"], "coverage-notes-file">, + HelpText<"Emit coverage notes to this filename.">; +def coverage_notes_file_EQ : Joined<["-"], "coverage-notes-file=">, + Alias<coverage_notes_file>; +def coverage_version_EQ : Joined<["-"], "coverage-version=">, + HelpText<"Four-byte version string for gcov files.">; +def test_coverage : Flag<["-"], "test-coverage">, + HelpText<"Do not generate coverage files or remove coverage changes from IR">; +def dump_coverage_mapping : Flag<["-"], "dump-coverage-mapping">, + HelpText<"Dump the coverage mapping records, for testing">; +def fuse_register_sized_bitfield_access: Flag<["-"], "fuse-register-sized-bitfield-access">, + HelpText<"Use register sized accesses to bit-fields, when possible.">; +def relaxed_aliasing : Flag<["-"], "relaxed-aliasing">, + HelpText<"Turn off Type Based Alias Analysis">; +def no_struct_path_tbaa : Flag<["-"], "no-struct-path-tbaa">, + HelpText<"Turn off struct-path aware Type Based Alias Analysis">; +def new_struct_path_tbaa : Flag<["-"], "new-struct-path-tbaa">, + HelpText<"Enable enhanced struct-path aware Type Based Alias Analysis">; +def mdebug_pass : Separate<["-"], "mdebug-pass">, + HelpText<"Enable additional debug output">; +def mframe_pointer_EQ : Joined<["-"], "mframe-pointer=">, + HelpText<"Specify which frame pointers to retain (all, non-leaf, none).">, Values<"all,non-leaf,none">; +def mdisable_tail_calls : Flag<["-"], "mdisable-tail-calls">, + HelpText<"Disable tail call optimization, keeping the call stack accurate">; +def menable_no_infinities : Flag<["-"], "menable-no-infs">, + HelpText<"Allow optimization to assume there are no infinities.">; +def menable_no_nans : Flag<["-"], "menable-no-nans">, + HelpText<"Allow optimization to assume there are no NaNs.">; +def menable_unsafe_fp_math : Flag<["-"], "menable-unsafe-fp-math">, + HelpText<"Allow unsafe floating-point math optimizations which may decrease " + "precision">; +def mreassociate : Flag<["-"], "mreassociate">, + HelpText<"Allow reassociation transformations for floating-point instructions">; +def mabi_EQ_ieeelongdouble : Flag<["-"], "mabi=ieeelongdouble">, + HelpText<"Use IEEE 754 quadruple-precision for long double">; +def mfloat_abi : Separate<["-"], "mfloat-abi">, + HelpText<"The float ABI to use">; +def mtp : Separate<["-"], "mtp">, + HelpText<"Mode for reading thread pointer">; +def mlimit_float_precision : Separate<["-"], "mlimit-float-precision">, + HelpText<"Limit float precision to the given value">; +def split_stacks : Flag<["-"], "split-stacks">, + HelpText<"Try to use a split stack if possible.">; +def mregparm : Separate<["-"], "mregparm">, + HelpText<"Limit the number of registers available for integer arguments">; +def msmall_data_limit : Separate<["-"], "msmall-data-limit">, + HelpText<"Put global and static data smaller than the limit into a special section">; +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_builtin_bitcode : Separate<["-"], "mlink-builtin-bitcode">, + HelpText<"Link and internalize needed symbols from the given bitcode file " + "before performing optimizations.">; +def mlink_cuda_bitcode : Separate<["-"], "mlink-cuda-bitcode">, + Alias<mlink_builtin_bitcode>; +def vectorize_loops : Flag<["-"], "vectorize-loops">, + HelpText<"Run the Loop vectorization passes">; +def vectorize_slp : Flag<["-"], "vectorize-slp">, + HelpText<"Run the SLP vectorization passes">; +def dependent_lib : Joined<["--"], "dependent-lib=">, + HelpText<"Add dependent library">; +def linker_option : Joined<["--"], "linker-option=">, + HelpText<"Add linker option">; +def fsanitize_coverage_type : Joined<["-"], "fsanitize-coverage-type=">, + HelpText<"Sanitizer coverage type">; +def fsanitize_coverage_indirect_calls + : Flag<["-"], "fsanitize-coverage-indirect-calls">, + HelpText<"Enable sanitizer coverage for indirect calls">; +def fsanitize_coverage_trace_bb + : Flag<["-"], "fsanitize-coverage-trace-bb">, + HelpText<"Enable basic block tracing in sanitizer coverage">; +def fsanitize_coverage_trace_cmp + : Flag<["-"], "fsanitize-coverage-trace-cmp">, + HelpText<"Enable cmp instruction tracing in sanitizer coverage">; +def fsanitize_coverage_trace_div + : Flag<["-"], "fsanitize-coverage-trace-div">, + HelpText<"Enable div instruction tracing in sanitizer coverage">; +def fsanitize_coverage_trace_gep + : Flag<["-"], "fsanitize-coverage-trace-gep">, + HelpText<"Enable gep instruction tracing in sanitizer coverage">; +def fsanitize_coverage_8bit_counters + : Flag<["-"], "fsanitize-coverage-8bit-counters">, + HelpText<"Enable frequency counters in sanitizer coverage">; +def fsanitize_coverage_inline_8bit_counters + : Flag<["-"], "fsanitize-coverage-inline-8bit-counters">, + HelpText<"Enable inline 8-bit counters in sanitizer coverage">; +def fsanitize_coverage_inline_bool_flag + : Flag<["-"], "fsanitize-coverage-inline-bool-flag">, + HelpText<"Enable inline bool flag in sanitizer coverage">; +def fsanitize_coverage_pc_table + : Flag<["-"], "fsanitize-coverage-pc-table">, + HelpText<"Create a table of coverage-instrumented PCs">; +def fsanitize_coverage_trace_pc + : Flag<["-"], "fsanitize-coverage-trace-pc">, + HelpText<"Enable PC tracing in sanitizer coverage">; +def fsanitize_coverage_trace_pc_guard + : Flag<["-"], "fsanitize-coverage-trace-pc-guard">, + HelpText<"Enable PC tracing with guard in sanitizer coverage">; +def fsanitize_coverage_no_prune + : Flag<["-"], "fsanitize-coverage-no-prune">, + HelpText<"Disable coverage pruning (i.e. instrument all blocks/edges)">; +def fsanitize_coverage_stack_depth + : Flag<["-"], "fsanitize-coverage-stack-depth">, + HelpText<"Enable max stack depth tracing">; +def fpatchable_function_entry_offset_EQ + : Joined<["-"], "fpatchable-function-entry-offset=">, MetaVarName<"<M>">, + HelpText<"Generate M NOPs before function entry">; +def fprofile_instrument_EQ : Joined<["-"], "fprofile-instrument=">, + HelpText<"Enable PGO instrumentation. The accepted value is clang, llvm, " + "or none">, Values<"none,clang,llvm">; +def fprofile_instrument_path_EQ : Joined<["-"], "fprofile-instrument-path=">, + HelpText<"Generate instrumented code to collect execution counts into " + "<file> (overridden by LLVM_PROFILE_FILE env var)">; +def fprofile_instrument_use_path_EQ : + Joined<["-"], "fprofile-instrument-use-path=">, + HelpText<"Specify the profile path in PGO use compilation">; +def flto_visibility_public_std: + Flag<["-"], "flto-visibility-public-std">, + HelpText<"Use public LTO visibility for classes in std and stdext namespaces">; +def flto_unit: Flag<["-"], "flto-unit">, + HelpText<"Emit IR to support LTO unit features (CFI, whole program vtable opt)">; +def fno_lto_unit: Flag<["-"], "fno-lto-unit">; +def fdebug_pass_manager : Flag<["-"], "fdebug-pass-manager">, + HelpText<"Prints debug information for the new pass manager">; +def fno_debug_pass_manager : Flag<["-"], "fno-debug-pass-manager">, + HelpText<"Disables debug printing for the new pass manager">; +// The driver option takes the key as a parameter to the -msign-return-address= +// and -mbranch-protection= options, but CC1 has a separate option so we +// don't have to parse the parameter twice. +def msign_return_address_key_EQ : Joined<["-"], "msign-return-address-key=">, + Values<"a_key,b_key">; +def mbranch_target_enforce : Flag<["-"], "mbranch-target-enforce">; +def fno_dllexport_inlines : Flag<["-"], "fno-dllexport-inlines">; +def cfguard_no_checks : Flag<["-"], "cfguard-no-checks">, + HelpText<"Emit Windows Control Flow Guard tables only (no checks)">; +def cfguard : Flag<["-"], "cfguard">, + HelpText<"Emit Windows Control Flow Guard tables and checks">; + +def fdenormal_fp_math_f32_EQ : Joined<["-"], "fdenormal-fp-math-f32=">, + Group<f_Group>; + +//===----------------------------------------------------------------------===// +// Dependency Output Options +//===----------------------------------------------------------------------===// + +def sys_header_deps : Flag<["-"], "sys-header-deps">, + HelpText<"Include system headers in dependency output">; +def module_file_deps : Flag<["-"], "module-file-deps">, + HelpText<"Include module files in dependency output">; +def header_include_file : Separate<["-"], "header-include-file">, + HelpText<"Filename (or -) to write header include output to">; +def show_includes : Flag<["--"], "show-includes">, + HelpText<"Print cl.exe style /showIncludes to stdout">; + +//===----------------------------------------------------------------------===// +// Diagnostic Options +//===----------------------------------------------------------------------===// + +def diagnostic_log_file : Separate<["-"], "diagnostic-log-file">, + HelpText<"Filename (or -) to log diagnostics to">; +def diagnostic_serialized_file : Separate<["-"], "serialize-diagnostic-file">, + MetaVarName<"<filename>">, + HelpText<"File for serializing diagnostics in a binary format">; + +def fdiagnostics_format : Separate<["-"], "fdiagnostics-format">, + HelpText<"Change diagnostic formatting to match IDE and command line tools">, Values<"clang,msvc,msvc-fallback,vi">; +def fdiagnostics_show_category : Separate<["-"], "fdiagnostics-show-category">, + HelpText<"Print diagnostic category">, Values<"none,id,name">; +def fno_diagnostics_use_presumed_location : Flag<["-"], "fno-diagnostics-use-presumed-location">, + HelpText<"Ignore #line directives when displaying diagnostic locations">; +def ftabstop : Separate<["-"], "ftabstop">, MetaVarName<"<N>">, + HelpText<"Set the tab stop distance.">; +def ferror_limit : Separate<["-"], "ferror-limit">, MetaVarName<"<N>">, + HelpText<"Set the maximum number of errors to emit before stopping (0 = no limit).">; +def fmacro_backtrace_limit : Separate<["-"], "fmacro-backtrace-limit">, MetaVarName<"<N>">, + HelpText<"Set the maximum number of entries to print in a macro expansion backtrace (0 = no limit).">; +def ftemplate_backtrace_limit : Separate<["-"], "ftemplate-backtrace-limit">, MetaVarName<"<N>">, + HelpText<"Set the maximum number of entries to print in a template instantiation backtrace (0 = no limit).">; +def fconstexpr_backtrace_limit : Separate<["-"], "fconstexpr-backtrace-limit">, MetaVarName<"<N>">, + HelpText<"Set the maximum number of entries to print in a constexpr evaluation backtrace (0 = no limit).">; +def fspell_checking_limit : Separate<["-"], "fspell-checking-limit">, MetaVarName<"<N>">, + HelpText<"Set the maximum number of times to perform spell checking on unrecognized identifiers (0 = no limit).">; +def fcaret_diagnostics_max_lines : + Separate<["-"], "fcaret-diagnostics-max-lines">, MetaVarName<"<N>">, + HelpText<"Set the maximum number of source lines to show in a caret diagnostic">; +def verify_EQ : CommaJoined<["-"], "verify=">, + MetaVarName<"<prefixes>">, + HelpText<"Verify diagnostic output using comment directives that start with" + " prefixes in the comma-separated sequence <prefixes>">; +def verify : Flag<["-"], "verify">, + HelpText<"Equivalent to -verify=expected">; +def verify_ignore_unexpected : Flag<["-"], "verify-ignore-unexpected">, + HelpText<"Ignore unexpected diagnostic messages">; +def verify_ignore_unexpected_EQ : CommaJoined<["-"], "verify-ignore-unexpected=">, + HelpText<"Ignore unexpected diagnostic messages">; +def Wno_rewrite_macros : Flag<["-"], "Wno-rewrite-macros">, + HelpText<"Silence ObjC rewriting warnings">; + +//===----------------------------------------------------------------------===// +// Frontend Options +//===----------------------------------------------------------------------===// + +// This isn't normally used, it is just here so we can parse a +// CompilerInvocation out of a driver-derived argument vector. +def cc1 : Flag<["-"], "cc1">; +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_target_cpu : Separate<["-"], "aux-target-cpu">, + HelpText<"Target a specific auxiliary cpu type">; +def aux_target_feature : Separate<["-"], "aux-target-feature">, + HelpText<"Target specific auxiliary attributes">; +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">; +def remap_file : Separate<["-"], "remap-file">, + MetaVarName<"<from>;<to>">, + HelpText<"Replace the contents of the <from> file with the contents of the <to> file">; +def code_completion_at_EQ : Joined<["-"], "code-completion-at=">, + Alias<code_completion_at>; +def code_completion_macros : Flag<["-"], "code-completion-macros">, + HelpText<"Include macros in code-completion results">; +def code_completion_patterns : Flag<["-"], "code-completion-patterns">, + HelpText<"Include code patterns in code-completion results">; +def no_code_completion_globals : Flag<["-"], "no-code-completion-globals">, + HelpText<"Do not include global declarations in code-completion results.">; +def no_code_completion_ns_level_decls : Flag<["-"], "no-code-completion-ns-level-decls">, + HelpText<"Do not include declarations inside namespaces (incl. global namespace) in the code-completion results.">; +def code_completion_brief_comments : Flag<["-"], "code-completion-brief-comments">, + HelpText<"Include brief documentation comments in code-completion results.">; +def code_completion_with_fixits : Flag<["-"], "code-completion-with-fixits">, + HelpText<"Include code completion results which require small fix-its.">; +def disable_free : Flag<["-"], "disable-free">, + HelpText<"Disable freeing of memory on exit">; +def discard_value_names : Flag<["-"], "discard-value-names">, + HelpText<"Discard value names in LLVM IR">; +def load : Separate<["-"], "load">, MetaVarName<"<dsopath>">, + HelpText<"Load the named plugin (dynamic shared object)">; +def plugin : Separate<["-"], "plugin">, MetaVarName<"<name>">, + HelpText<"Use the named plugin action instead of the default action (use \"help\" to list available options)">; +def plugin_arg : JoinedAndSeparate<["-"], "plugin-arg-">, + MetaVarName<"<name> <arg>">, + HelpText<"Pass <arg> to plugin <name>">; +def add_plugin : Separate<["-"], "add-plugin">, MetaVarName<"<name>">, + HelpText<"Use the named plugin action in addition to the default action">; +def ast_dump_filter : Separate<["-"], "ast-dump-filter">, + MetaVarName<"<dump_filter>">, + HelpText<"Use with -ast-dump or -ast-print to dump/print only AST declaration" + " nodes having a certain substring in a qualified name. Use" + " -ast-list to list all filterable declaration node names.">; +def fno_modules_global_index : Flag<["-"], "fno-modules-global-index">, + HelpText<"Do not automatically generate or update the global module index">; +def fno_modules_error_recovery : Flag<["-"], "fno-modules-error-recovery">, + HelpText<"Do not automatically import modules for error recovery">; +def fmodule_map_file_home_is_cwd : Flag<["-"], "fmodule-map-file-home-is-cwd">, + HelpText<"Use the current working directory as the home directory of " + "module maps specified by -fmodule-map-file=<FILE>">; +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 " + "top-level module.">; +def fmodules_codegen : + Flag<["-"], "fmodules-codegen">, + HelpText<"Generate code for uses of this module that assumes an explicit " + "object file will be built for the module">; +def fmodules_debuginfo : + Flag<["-"], "fmodules-debuginfo">, + HelpText<"Generate debug info for types in an object file built from this " + "module and do not generate them elsewhere">; +def fmodule_format_EQ : Joined<["-"], "fmodule-format=">, + HelpText<"Select the container format for clang modules and PCH. " + "Supported options are 'raw' and 'obj'.">; +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. (deprecated - use -std=c++2a)">; +def fno_concept_satisfaction_caching : Flag<["-"], + "fno-concept-satisfaction-caching">, + HelpText<"Disable satisfaction caching for C++2a Concepts.">; + +def frecovery_ast : Flag<["-"], "frecovery-ast">, + HelpText<"Preserve expressions in AST rather than dropping them when " + "encountering semantic errors">; +def fno_recovery_ast : Flag<["-"], "fno-recovery-ast">; +def frecovery_ast_type : Flag<["-"], "frecovery-ast-type">, + HelpText<"Preserve the type for recovery expressions when possible " + "(experimental)">; +def fno_recovery_ast_type : Flag<["-"], "fno-recovery-ast-type">; + +let Group = Action_Group in { + +def Eonly : Flag<["-"], "Eonly">, + HelpText<"Just run preprocessor, no output (for timings)">; +def dump_raw_tokens : Flag<["-"], "dump-raw-tokens">, + HelpText<"Lex file in raw mode and dump raw tokens">; +def analyze : Flag<["-"], "analyze">, + HelpText<"Run static analysis engine">; +def dump_tokens : Flag<["-"], "dump-tokens">, + HelpText<"Run preprocessor, dump internal rep of tokens">; +def init_only : Flag<["-"], "init-only">, + HelpText<"Only execute frontend initialization">; +def fixit : Flag<["-"], "fixit">, + HelpText<"Apply fix-it advice to the input source">; +def fixit_EQ : Joined<["-"], "fixit=">, + HelpText<"Apply fix-it advice creating a file with the given suffix">; +def print_preamble : Flag<["-"], "print-preamble">, + HelpText<"Print the \"preamble\" of a file, which is a candidate for implicit" + " precompiled headers.">; +def emit_html : Flag<["-"], "emit-html">, + HelpText<"Output input source as HTML">; +def ast_print : Flag<["-"], "ast-print">, + HelpText<"Build ASTs and then pretty-print them">; +def ast_list : Flag<["-"], "ast-list">, + HelpText<"Build ASTs and print the list of declaration node qualified names">; +def ast_dump : Flag<["-"], "ast-dump">, + HelpText<"Build ASTs and then debug dump them">; +def ast_dump_EQ : Joined<["-"], "ast-dump=">, + HelpText<"Build ASTs and then debug dump them in the specified format. " + "Supported formats include: default, json">; +def ast_dump_all : Flag<["-"], "ast-dump-all">, + HelpText<"Build ASTs and then debug dump them, forcing deserialization">; +def ast_dump_all_EQ : Joined<["-"], "ast-dump-all=">, + HelpText<"Build ASTs and then debug dump them in the specified format, " + "forcing deserialization. Supported formats include: default, json">; +def ast_dump_decl_types : Flag<["-"], "ast-dump-decl-types">, + HelpText<"Include declaration types in AST dumps">; +def templight_dump : Flag<["-"], "templight-dump">, + HelpText<"Dump templight information to stdout">; +def ast_dump_lookups : Flag<["-"], "ast-dump-lookups">, + HelpText<"Build ASTs and then debug dump their name lookup tables">; +def ast_view : Flag<["-"], "ast-view">, + HelpText<"Build ASTs and view them with GraphViz">; +def emit_module : Flag<["-"], "emit-module">, + HelpText<"Generate pre-compiled module file from a module map">; +def emit_module_interface : Flag<["-"], "emit-module-interface">, + HelpText<"Generate pre-compiled module file from a C++ module interface">; +def emit_header_module : Flag<["-"], "emit-header-module">, + HelpText<"Generate pre-compiled module file from a set of header files">; +def emit_pch : Flag<["-"], "emit-pch">, + HelpText<"Generate pre-compiled header file">; +def emit_llvm_bc : Flag<["-"], "emit-llvm-bc">, + HelpText<"Build ASTs then convert to LLVM, emit .bc file">; +def emit_llvm_only : Flag<["-"], "emit-llvm-only">, + HelpText<"Build ASTs and convert to LLVM, discarding output">; +def emit_codegen_only : Flag<["-"], "emit-codegen-only">, + HelpText<"Generate machine code, but discard output">; +def emit_obj : Flag<["-"], "emit-obj">, + HelpText<"Emit native object files">; +def rewrite_test : Flag<["-"], "rewrite-test">, + HelpText<"Rewriter playground">; +def rewrite_macros : Flag<["-"], "rewrite-macros">, + HelpText<"Expand macros without full preprocessing">; +def migrate : Flag<["-"], "migrate">, + HelpText<"Migrate source code">; +def compiler_options_dump : Flag<["-"], "compiler-options-dump">, + HelpText<"Dump the compiler configuration options">; +def print_dependency_directives_minimized_source : Flag<["-"], + "print-dependency-directives-minimized-source">, + HelpText<"Print the output of the dependency directives source minimizer">; +} + +def emit_llvm_uselists : Flag<["-"], "emit-llvm-uselists">, + HelpText<"Preserve order of LLVM use-lists when serializing">; +def no_emit_llvm_uselists : Flag<["-"], "no-emit-llvm-uselists">, + HelpText<"Don't preserve order of LLVM use-lists when serializing">; + +def mt_migrate_directory : Separate<["-"], "mt-migrate-directory">, + HelpText<"Directory for temporary files produced during ARC or ObjC migration">; +def arcmt_check : Flag<["-"], "arcmt-check">, + HelpText<"Check for ARC migration issues that need manual handling">; +def arcmt_modify : Flag<["-"], "arcmt-modify">, + HelpText<"Apply modifications to files to conform to ARC">; +def arcmt_migrate : Flag<["-"], "arcmt-migrate">, + HelpText<"Apply modifications and produces temporary files that conform to ARC">; + +def opt_record_file : Separate<["-"], "opt-record-file">, + HelpText<"File name to use for YAML optimization record output">; +def opt_record_passes : Separate<["-"], "opt-record-passes">, + HelpText<"Only record remark information for passes whose names match the given regular expression">; +def opt_record_format : Separate<["-"], "opt-record-format">, + HelpText<"The format used for serializing remarks (default: YAML)">; + +def print_stats : Flag<["-"], "print-stats">, + HelpText<"Print performance metrics and statistics">; +def stats_file : Joined<["-"], "stats-file=">, + HelpText<"Filename to write statistics to">; +def fdump_record_layouts : Flag<["-"], "fdump-record-layouts">, + HelpText<"Dump record layout information">; +def fdump_record_layouts_simple : Flag<["-"], "fdump-record-layouts-simple">, + HelpText<"Dump record layout information in a simple form used for testing">; +def fix_what_you_can : Flag<["-"], "fix-what-you-can">, + HelpText<"Apply fix-it advice even in the presence of unfixable errors">; +def fix_only_warnings : Flag<["-"], "fix-only-warnings">, + HelpText<"Apply fix-it advice only for warnings, not errors">; +def fixit_recompile : Flag<["-"], "fixit-recompile">, + HelpText<"Apply fix-it changes and recompile">; +def fixit_to_temp : Flag<["-"], "fixit-to-temporary">, + HelpText<"Apply fix-it changes to temporary files">; + +def foverride_record_layout_EQ : Joined<["-"], "foverride-record-layout=">, + HelpText<"Override record layouts with those in the given file">; +def pch_through_header_EQ : Joined<["-"], "pch-through-header=">, + HelpText<"Stop PCH generation after including this file. When using a PCH, " + "skip tokens until after this file is included.">; +def pch_through_hdrstop_create : Flag<["-"], "pch-through-hdrstop-create">, + HelpText<"When creating a PCH, stop PCH generation after #pragma hdrstop.">; +def pch_through_hdrstop_use : Flag<["-"], "pch-through-hdrstop-use">, + HelpText<"When using a PCH, skip tokens until after a #pragma hdrstop.">; +def fno_pch_timestamp : Flag<["-"], "fno-pch-timestamp">, + HelpText<"Disable inclusion of timestamp in precompiled headers">; +def building_pch_with_obj : Flag<["-"], "building-pch-with-obj">, + HelpText<"This compilation is part of building a PCH with corresponding object file.">; + +def aligned_alloc_unavailable : Flag<["-"], "faligned-alloc-unavailable">, + HelpText<"Aligned allocation/deallocation functions are unavailable">; + +//===----------------------------------------------------------------------===// +// Language Options +//===----------------------------------------------------------------------===// + +let Flags = [CC1Option, CC1AsOption, NoDriverOption] in { + +def version : Flag<["-"], "version">, + HelpText<"Print the compiler version">; +def main_file_name : Separate<["-"], "main-file-name">, + HelpText<"Main file name to use for debug info and source if missing">; +def split_dwarf_output : Separate<["-"], "split-dwarf-output">, + HelpText<"File name to use for split dwarf debug info output">; + +} + +def fblocks_runtime_optional : Flag<["-"], "fblocks-runtime-optional">, + HelpText<"Weakly link in the blocks runtime">; +def fexternc_nounwind : Flag<["-"], "fexternc-nounwind">, + HelpText<"Assume all functions with C linkage do not unwind">; +def split_dwarf_file : Separate<["-"], "split-dwarf-file">, + HelpText<"Name of the split dwarf debug info file to encode in the object file">; +def fno_wchar : Flag<["-"], "fno-wchar">, + HelpText<"Disable C++ builtin type wchar_t">; +def fconstant_string_class : Separate<["-"], "fconstant-string-class">, + MetaVarName<"<class name>">, + HelpText<"Specify the class to use for constant Objective-C string objects.">; +def fobjc_arc_cxxlib_EQ : Joined<["-"], "fobjc-arc-cxxlib=">, + HelpText<"Objective-C++ Automatic Reference Counting standard library kind">, Values<"libc++,libstdc++,none">; +def fobjc_runtime_has_weak : Flag<["-"], "fobjc-runtime-has-weak">, + HelpText<"The target Objective-C runtime supports ARC weak operations">; +def fobjc_dispatch_method_EQ : Joined<["-"], "fobjc-dispatch-method=">, + HelpText<"Objective-C dispatch method to use">, Values<"legacy,non-legacy,mixed">; +def disable_objc_default_synthesize_properties : Flag<["-"], "disable-objc-default-synthesize-properties">, + HelpText<"disable the default synthesis of Objective-C properties">; +def fencode_extended_block_signature : Flag<["-"], "fencode-extended-block-signature">, + HelpText<"enable extended encoding of block type signature">; +def function_alignment : Separate<["-"], "function-alignment">, + HelpText<"default alignment for functions">; +def pic_level : Separate<["-"], "pic-level">, + HelpText<"Value for __PIC__">; +def pic_is_pie : Flag<["-"], "pic-is-pie">, + HelpText<"File is for a position independent executable">; +def fno_validate_pch : Flag<["-"], "fno-validate-pch">, + HelpText<"Disable validation of precompiled headers">; +def fallow_pch_with_errors : Flag<["-"], "fallow-pch-with-compiler-errors">, + HelpText<"Accept a PCH file that was created with compiler errors">; +def dump_deserialized_pch_decls : Flag<["-"], "dump-deserialized-decls">, + HelpText<"Dump declarations that are deserialized from PCH, for testing">; +def error_on_deserialized_pch_decl : Separate<["-"], "error-on-deserialized-decl">, + HelpText<"Emit error if a specific declaration is deserialized from PCH, for testing">; +def error_on_deserialized_pch_decl_EQ : Joined<["-"], "error-on-deserialized-decl=">, + Alias<error_on_deserialized_pch_decl>; +def static_define : Flag<["-"], "static-define">, + HelpText<"Should __STATIC__ be defined">; +def stack_protector : Separate<["-"], "stack-protector">, + HelpText<"Enable stack protectors">; +def stack_protector_buffer_size : Separate<["-"], "stack-protector-buffer-size">, + HelpText<"Lower bound for a buffer to be considered for stack protection">; +def fvisibility : Separate<["-"], "fvisibility">, + HelpText<"Default type and symbol visibility">; +def ftype_visibility : Separate<["-"], "ftype-visibility">, + HelpText<"Default type visibility">; +def fapply_global_visibility_to_externs : Flag<["-"], "fapply-global-visibility-to-externs">, + HelpText<"Apply global symbol visibility to external declarations without an explicit visibility">; +def ftemplate_depth : Separate<["-"], "ftemplate-depth">, + HelpText<"Maximum depth of recursive template instantiation">; +def foperator_arrow_depth : Separate<["-"], "foperator-arrow-depth">, + HelpText<"Maximum number of 'operator->'s to call for a member access">; +def fconstexpr_depth : Separate<["-"], "fconstexpr-depth">, + HelpText<"Maximum depth of recursive constexpr function calls">; +def fconstexpr_steps : Separate<["-"], "fconstexpr-steps">, + HelpText<"Maximum number of steps in constexpr function evaluation">; +def fbracket_depth : Separate<["-"], "fbracket-depth">, + HelpText<"Maximum nesting level for parentheses, brackets, and braces">; +def fconst_strings : Flag<["-"], "fconst-strings">, + HelpText<"Use a const qualified type for string literals in C and ObjC">; +def fno_const_strings : Flag<["-"], "fno-const-strings">, + HelpText<"Don't use a const qualified type for string literals in C and ObjC">; +def fno_bitfield_type_align : Flag<["-"], "fno-bitfield-type-align">, + HelpText<"Ignore bit-field types when aligning structures">; +def ffake_address_space_map : Flag<["-"], "ffake-address-space-map">, + HelpText<"Use a fake address space map; OpenCL testing purposes only">; +def faddress_space_map_mangling_EQ : Joined<["-"], "faddress-space-map-mangling=">, MetaVarName<"<yes|no|target>">, + HelpText<"Set the mode for address space map based mangling; OpenCL testing purposes only">; +def funknown_anytype : Flag<["-"], "funknown-anytype">, + HelpText<"Enable parser support for the __unknown_anytype type; for testing purposes only">; +def fdebugger_support : Flag<["-"], "fdebugger-support">, + HelpText<"Enable special debugger support behavior">; +def fdebugger_cast_result_to_id : Flag<["-"], "fdebugger-cast-result-to-id">, + HelpText<"Enable casting unknown expression results to id">; +def fdebugger_objc_literal : Flag<["-"], "fdebugger-objc-literal">, + HelpText<"Enable special debugger support for Objective-C subscripting and literals">; +def fdeprecated_macro : Flag<["-"], "fdeprecated-macro">, + HelpText<"Defines the __DEPRECATED macro">; +def fno_deprecated_macro : Flag<["-"], "fno-deprecated-macro">, + HelpText<"Undefines the __DEPRECATED macro">; +def fobjc_subscripting_legacy_runtime : Flag<["-"], "fobjc-subscripting-legacy-runtime">, + HelpText<"Allow Objective-C array and dictionary subscripting in legacy runtime">; +def vtordisp_mode_EQ : Joined<["-"], "vtordisp-mode=">, + HelpText<"Control vtordisp placement on win32 targets">; +def fnative_half_type: Flag<["-"], "fnative-half-type">, + HelpText<"Use the native half type for __fp16 instead of promoting to float">; +def fnative_half_arguments_and_returns : Flag<["-"], "fnative-half-arguments-and-returns">, + HelpText<"Use the native __fp16 type for arguments and returns (and skip ABI-specific lowering)">; +def fallow_half_arguments_and_returns : Flag<["-"], "fallow-half-arguments-and-returns">, + HelpText<"Allow function arguments and returns of type half">; +def fdefault_calling_conv_EQ : Joined<["-"], "fdefault-calling-conv=">, + HelpText<"Set default calling convention">, Values<"cdecl,fastcall,stdcall,vectorcall,regcall">; +def finclude_default_header : Flag<["-"], "finclude-default-header">, + HelpText<"Include default header file for OpenCL">; +def fdeclare_opencl_builtins : Flag<["-"], "fdeclare-opencl-builtins">, + HelpText<"Add OpenCL builtin function declarations (experimental)">; +def fpreserve_vec3_type : Flag<["-"], "fpreserve-vec3-type">, + HelpText<"Preserve 3-component vector type">; +def fwchar_type_EQ : Joined<["-"], "fwchar-type=">, + HelpText<"Select underlying type for wchar_t">, Values<"char,short,int">; +def fsigned_wchar : Flag<["-"], "fsigned-wchar">, + HelpText<"Use a signed type for wchar_t">; +def fno_signed_wchar : Flag<["-"], "fno-signed-wchar">, + HelpText<"Use an unsigned type for wchar_t">; +def fcompatibility_qualified_id_block_param_type_checking : Flag<["-"], "fcompatibility-qualified-id-block-type-checking">, + HelpText<"Allow using blocks with parameters of more specific type than " + "the type system guarantees when a parameter is qualified id">; + +// FIXME: Remove these entirely once functionality/tests have been excised. +def fobjc_gc_only : Flag<["-"], "fobjc-gc-only">, Group<f_Group>, + HelpText<"Use GC exclusively for Objective-C related memory management">; +def fobjc_gc : Flag<["-"], "fobjc-gc">, Group<f_Group>, + HelpText<"Enable Objective-C garbage collection">; + +//===----------------------------------------------------------------------===// +// Header Search Options +//===----------------------------------------------------------------------===// + +def nostdsysteminc : Flag<["-"], "nostdsysteminc">, + HelpText<"Disable standard system #include directories">; +def fdisable_module_hash : Flag<["-"], "fdisable-module-hash">, + HelpText<"Disable the module hash">; +def fmodules_hash_content : Flag<["-"], "fmodules-hash-content">, + HelpText<"Enable hashing the content of a module file">; +def fmodules_strict_context_hash : Flag<["-"], "fmodules-strict-context-hash">, + HelpText<"Enable hashing of all compiler options that could impact the " + "semantics of a module in an implicit build">, + MarshallingInfoFlag<"HeaderSearchOpts->ModulesStrictContextHash", "false">; +def c_isystem : JoinedOrSeparate<["-"], "c-isystem">, MetaVarName<"<directory>">, + HelpText<"Add directory to the C SYSTEM include search path">; +def objc_isystem : JoinedOrSeparate<["-"], "objc-isystem">, + MetaVarName<"<directory>">, + HelpText<"Add directory to the ObjC SYSTEM include search path">; +def objcxx_isystem : JoinedOrSeparate<["-"], "objcxx-isystem">, + MetaVarName<"<directory>">, + HelpText<"Add directory to the ObjC++ SYSTEM include search path">; +def internal_isystem : JoinedOrSeparate<["-"], "internal-isystem">, + MetaVarName<"<directory>">, + HelpText<"Add directory to the internal system include search path; these " + "are assumed to not be user-provided and are used to model system " + "and standard headers' paths.">; +def internal_externc_isystem : JoinedOrSeparate<["-"], "internal-externc-isystem">, + MetaVarName<"<directory>">, + HelpText<"Add directory to the internal system include search path with " + "implicit extern \"C\" semantics; these are assumed to not be " + "user-provided and are used to model system and standard headers' " + "paths.">; + +//===----------------------------------------------------------------------===// +// Preprocessor Options +//===----------------------------------------------------------------------===// + +def chain_include : Separate<["-"], "chain-include">, MetaVarName<"<file>">, + HelpText<"Include and chain a header file after turning it into PCH">; +def preamble_bytes_EQ : Joined<["-"], "preamble-bytes=">, + HelpText<"Assume that the precompiled header is a precompiled preamble " + "covering the first N bytes of the main file">; +def detailed_preprocessing_record : Flag<["-"], "detailed-preprocessing-record">, + HelpText<"include a detailed record of preprocessing actions">; +def setup_static_analyzer : Flag<["-"], "setup-static-analyzer">, + HelpText<"Set up preprocessor for static analyzer (done automatically when static analyzer is run).">; +def disable_pragma_debug_crash : Flag<["-"], "disable-pragma-debug-crash">, + HelpText<"Disable any #pragma clang __debug that can lead to crashing behavior. This is meant for testing.">; + +//===----------------------------------------------------------------------===// +// OpenCL Options +//===----------------------------------------------------------------------===// + +def cl_ext_EQ : CommaJoined<["-"], "cl-ext=">, + HelpText<"OpenCL only. Enable or disable OpenCL extensions. The argument is a comma-separated sequence of one or more extension names, each prefixed by '+' or '-'.">; + +//===----------------------------------------------------------------------===// +// CUDA Options +//===----------------------------------------------------------------------===// + +def fcuda_is_device : Flag<["-"], "fcuda-is-device">, + HelpText<"Generate code for CUDA device">; +def fcuda_include_gpubinary : Separate<["-"], "fcuda-include-gpubinary">, + HelpText<"Incorporate CUDA device-side binary into host object file.">; +def fcuda_allow_variadic_functions : Flag<["-"], "fcuda-allow-variadic-functions">, + HelpText<"Allow variadic functions in CUDA device code.">; +def fno_cuda_host_device_constexpr : Flag<["-"], "fno-cuda-host-device-constexpr">, + HelpText<"Don't treat unattributed constexpr functions as __host__ __device__.">; + +//===----------------------------------------------------------------------===// +// OpenMP Options +//===----------------------------------------------------------------------===// + +def fopenmp_is_device : Flag<["-"], "fopenmp-is-device">, + HelpText<"Generate code only for an OpenMP target device.">; +def fopenmp_host_ir_file_path : Separate<["-"], "fopenmp-host-ir-file-path">, + HelpText<"Path to the IR file produced by the frontend for the host.">; + +//===----------------------------------------------------------------------===// +// SYCL Options +//===----------------------------------------------------------------------===// + +def fsycl_is_device : Flag<["-"], "fsycl-is-device">, + HelpText<"Generate code for SYCL device.">; + +} // let Flags = [CC1Option] + +//===----------------------------------------------------------------------===// +// cc1as-only Options +//===----------------------------------------------------------------------===// + +let Flags = [CC1AsOption, NoDriverOption] in { + +// Language Options +def n : Flag<["-"], "n">, + HelpText<"Don't automatically start assembly file with a text section">; + +// Frontend Options +def filetype : Separate<["-"], "filetype">, + HelpText<"Specify the output file type ('asm', 'null', or 'obj')">; + +// Transliterate Options +def output_asm_variant : Separate<["-"], "output-asm-variant">, + HelpText<"Select the asm variant index to use for output">; +def show_encoding : Flag<["-"], "show-encoding">, + HelpText<"Show instruction encoding information in transliterate mode">; +def show_inst : Flag<["-"], "show-inst">, + HelpText<"Show internal instruction representation in transliterate mode">; + +// Assemble Options +def dwarf_debug_producer : Separate<["-"], "dwarf-debug-producer">, + HelpText<"The string to embed in the Dwarf debug AT_producer record.">; + +def defsym : Separate<["-"], "defsym">, + HelpText<"Define a value for a symbol">; + +} // let Flags = [CC1AsOption] + +//===----------------------------------------------------------------------===// +// clang-cl Options +//===----------------------------------------------------------------------===// + +def cl_Group : OptionGroup<"<clang-cl options>">, Flags<[CLOption]>, + HelpText<"CL.EXE COMPATIBILITY OPTIONS">; + +def cl_compile_Group : OptionGroup<"<clang-cl compile-only options>">, + Group<cl_Group>; + +def cl_ignored_Group : OptionGroup<"<clang-cl ignored options>">, + Group<cl_Group>; + +class CLFlag<string name> : Option<["/", "-"], name, KIND_FLAG>, + Group<cl_Group>, Flags<[CLOption, DriverOption]>; + +class CLCompileFlag<string name> : Option<["/", "-"], name, KIND_FLAG>, + Group<cl_compile_Group>, Flags<[CLOption, DriverOption]>; + +class CLIgnoredFlag<string name> : Option<["/", "-"], name, KIND_FLAG>, + Group<cl_ignored_Group>, Flags<[CLOption, DriverOption]>; + +class CLJoined<string name> : Option<["/", "-"], name, KIND_JOINED>, + Group<cl_Group>, Flags<[CLOption, DriverOption]>; + +class CLCompileJoined<string name> : Option<["/", "-"], name, KIND_JOINED>, + Group<cl_compile_Group>, Flags<[CLOption, DriverOption]>; + +class CLIgnoredJoined<string name> : Option<["/", "-"], name, KIND_JOINED>, + Group<cl_ignored_Group>, Flags<[CLOption, DriverOption, HelpHidden]>; + +class CLJoinedOrSeparate<string name> : Option<["/", "-"], name, + KIND_JOINED_OR_SEPARATE>, Group<cl_Group>, Flags<[CLOption, DriverOption]>; + +class CLCompileJoinedOrSeparate<string name> : Option<["/", "-"], name, + KIND_JOINED_OR_SEPARATE>, Group<cl_compile_Group>, + Flags<[CLOption, DriverOption]>; + +class CLRemainingArgsJoined<string name> : Option<["/", "-"], name, + KIND_REMAINING_ARGS_JOINED>, Group<cl_Group>, Flags<[CLOption, DriverOption]>; + +// Aliases: +// (We don't put any of these in cl_compile_Group as the options they alias are +// already in the right group.) + +def _SLASH_Brepro : CLFlag<"Brepro">, + HelpText<"Do not write current time into COFF output (breaks link.exe /incremental)">, + Alias<mno_incremental_linker_compatible>; +def _SLASH_Brepro_ : CLFlag<"Brepro-">, + HelpText<"Write current time into COFF output (default)">, + Alias<mincremental_linker_compatible>; +def _SLASH_C : CLFlag<"C">, + HelpText<"Do not discard comments when preprocessing">, Alias<C>; +def _SLASH_c : CLFlag<"c">, HelpText<"Compile only">, Alias<c>; +def _SLASH_d1PP : CLFlag<"d1PP">, + HelpText<"Retain macro definitions in /E mode">, Alias<dD>; +def _SLASH_d1reportAllClassLayout : CLFlag<"d1reportAllClassLayout">, + HelpText<"Dump record layout information">, + Alias<Xclang>, AliasArgs<["-fdump-record-layouts"]>; +def _SLASH_diagnostics_caret : CLFlag<"diagnostics:caret">, + HelpText<"Enable caret and column diagnostics (default)">; +def _SLASH_diagnostics_column : CLFlag<"diagnostics:column">, + HelpText<"Disable caret diagnostics but keep column info">; +def _SLASH_diagnostics_classic : CLFlag<"diagnostics:classic">, + HelpText<"Disable column and caret diagnostics">; +def _SLASH_D : CLJoinedOrSeparate<"D">, HelpText<"Define macro">, + MetaVarName<"<macro[=value]>">, Alias<D>; +def _SLASH_E : CLFlag<"E">, HelpText<"Preprocess to stdout">, Alias<E>; +def _SLASH_fp_except : CLFlag<"fp:except">, HelpText<"">, Alias<ftrapping_math>; +def _SLASH_fp_except_ : CLFlag<"fp:except-">, + HelpText<"">, Alias<fno_trapping_math>; +def _SLASH_fp_fast : CLFlag<"fp:fast">, HelpText<"">, Alias<ffast_math>; +def _SLASH_fp_precise : CLFlag<"fp:precise">, + HelpText<"">, Alias<fno_fast_math>; +def _SLASH_fp_strict : CLFlag<"fp:strict">, HelpText<"">, Alias<fno_fast_math>; +def _SLASH_GA : CLFlag<"GA">, Alias<ftlsmodel_EQ>, AliasArgs<["local-exec"]>, + HelpText<"Assume thread-local variables are defined in the executable">; +def _SLASH_GR : CLFlag<"GR">, HelpText<"Emit RTTI data (default)">; +def _SLASH_GR_ : CLFlag<"GR-">, HelpText<"Do not emit RTTI data">; +def _SLASH_GF : CLIgnoredFlag<"GF">, + HelpText<"Enable string pooling (default)">; +def _SLASH_GF_ : CLFlag<"GF-">, HelpText<"Disable string pooling">, + Alias<fwritable_strings>; +def _SLASH_GS : CLFlag<"GS">, + HelpText<"Enable buffer security check (default)">; +def _SLASH_GS_ : CLFlag<"GS-">, HelpText<"Disable buffer security check">; +def : CLFlag<"Gs">, HelpText<"Use stack probes (default)">, + Alias<mstack_probe_size>, AliasArgs<["4096"]>; +def _SLASH_Gs : CLJoined<"Gs">, + HelpText<"Set stack probe size (default 4096)">, Alias<mstack_probe_size>; +def _SLASH_Gy : CLFlag<"Gy">, HelpText<"Put each function in its own section">, + Alias<ffunction_sections>; +def _SLASH_Gy_ : CLFlag<"Gy-">, + HelpText<"Do not put each function in its own section (default)">, + Alias<fno_function_sections>; +def _SLASH_Gw : CLFlag<"Gw">, HelpText<"Put each data item in its own section">, + Alias<fdata_sections>; +def _SLASH_Gw_ : CLFlag<"Gw-">, + HelpText<"Do not put each data item in its own section (default)">, + Alias<fno_data_sections>; +def _SLASH_help : CLFlag<"help">, Alias<help>, + HelpText<"Display available options">; +def _SLASH_HELP : CLFlag<"HELP">, Alias<help>; +def _SLASH_I : CLJoinedOrSeparate<"I">, + HelpText<"Add directory to include search path">, MetaVarName<"<dir>">, + Alias<I>; +def _SLASH_J : CLFlag<"J">, HelpText<"Make char type unsigned">, + Alias<funsigned_char>; + +// The _SLASH_O option handles all the /O flags, but we also provide separate +// aliased options to provide separate help messages. +def _SLASH_O : CLJoined<"O">, + HelpText<"Set multiple /O flags at once; e.g. '/O2y-' for '/O2 /Oy-'">, + MetaVarName<"<flags>">; +def : CLFlag<"O1">, Alias<_SLASH_O>, AliasArgs<["1"]>, + HelpText<"Optimize for size (like /Og /Os /Oy /Ob2 /GF /Gy)">; +def : CLFlag<"O2">, Alias<_SLASH_O>, AliasArgs<["2"]>, + HelpText<"Optimize for speed (like /Og /Oi /Ot /Oy /Ob2 /GF /Gy)">; +def : CLFlag<"Ob0">, Alias<_SLASH_O>, AliasArgs<["b0"]>, + HelpText<"Disable function inlining">; +def : CLFlag<"Ob1">, Alias<_SLASH_O>, AliasArgs<["b1"]>, + HelpText<"Only inline functions explicitly or implicitly marked inline">; +def : CLFlag<"Ob2">, Alias<_SLASH_O>, AliasArgs<["b2"]>, + HelpText<"Inline functions as deemed beneficial by the compiler">; +def : CLFlag<"Od">, Alias<_SLASH_O>, AliasArgs<["d"]>, + HelpText<"Disable optimization">; +def : CLFlag<"Og">, Alias<_SLASH_O>, AliasArgs<["g"]>, + HelpText<"No effect">; +def : CLFlag<"Oi">, Alias<_SLASH_O>, AliasArgs<["i"]>, + HelpText<"Enable use of builtin functions">; +def : CLFlag<"Oi-">, Alias<_SLASH_O>, AliasArgs<["i-"]>, + HelpText<"Disable use of builtin functions">; +def : CLFlag<"Os">, Alias<_SLASH_O>, AliasArgs<["s"]>, + HelpText<"Optimize for size">; +def : CLFlag<"Ot">, Alias<_SLASH_O>, AliasArgs<["t"]>, + HelpText<"Optimize for speed">; +def : CLFlag<"Ox">, Alias<_SLASH_O>, AliasArgs<["x"]>, + HelpText<"Deprecated (like /Og /Oi /Ot /Oy /Ob2); use /O2">; +def : CLFlag<"Oy">, Alias<_SLASH_O>, AliasArgs<["y"]>, + HelpText<"Enable frame pointer omission (x86 only)">; +def : CLFlag<"Oy-">, Alias<_SLASH_O>, AliasArgs<["y-"]>, + HelpText<"Disable frame pointer omission (x86 only, default)">; + +def _SLASH_QUESTION : CLFlag<"?">, Alias<help>, + HelpText<"Display available options">; +def _SLASH_Qvec : CLFlag<"Qvec">, + HelpText<"Enable the loop vectorization passes">, Alias<fvectorize>; +def _SLASH_Qvec_ : CLFlag<"Qvec-">, + HelpText<"Disable the loop vectorization passes">, Alias<fno_vectorize>; +def _SLASH_showIncludes : CLFlag<"showIncludes">, + HelpText<"Print info about included files to stderr">; +def _SLASH_showIncludes_user : CLFlag<"showIncludes:user">, + HelpText<"Like /showIncludes but omit system headers">; +def _SLASH_showFilenames : CLFlag<"showFilenames">, + HelpText<"Print the name of each compiled file">; +def _SLASH_showFilenames_ : CLFlag<"showFilenames-">, + HelpText<"Do not print the name of each compiled file (default)">; +def _SLASH_source_charset : CLCompileJoined<"source-charset:">, + HelpText<"Set source encoding, supports only UTF-8">, + Alias<finput_charset_EQ>; +def _SLASH_execution_charset : CLCompileJoined<"execution-charset:">, + HelpText<"Set runtime encoding, supports only UTF-8">, + Alias<fexec_charset_EQ>; +def _SLASH_std : CLCompileJoined<"std:">, + HelpText<"Set C++ version (c++14,c++17,c++latest)">; +def _SLASH_U : CLJoinedOrSeparate<"U">, HelpText<"Undefine macro">, + MetaVarName<"<macro>">, Alias<U>; +def _SLASH_validate_charset : CLFlag<"validate-charset">, + Alias<W_Joined>, AliasArgs<["invalid-source-encoding"]>; +def _SLASH_validate_charset_ : CLFlag<"validate-charset-">, + Alias<W_Joined>, AliasArgs<["no-invalid-source-encoding"]>; +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 and -Wextra">, Alias<WCL4>; +def _SLASH_Wall : CLFlag<"Wall">, HelpText<"Enable -Weverything">, + Alias<W_Joined>, AliasArgs<["everything"]>; +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 (default)">, + Alias<W_Joined>, AliasArgs<["no-error"]>; +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_wd4018 : CLFlag<"wd4018">, Alias<W_Joined>, + AliasArgs<["no-sign-compare"]>; +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_X : CLFlag<"X">, + HelpText<"Do not add %INCLUDE% to include search path">, Alias<nostdlibinc>; +def _SLASH_Zc_sizedDealloc : CLFlag<"Zc:sizedDealloc">, + HelpText<"Enable C++14 sized global deallocation functions">, + Alias<fsized_deallocation>; +def _SLASH_Zc_sizedDealloc_ : CLFlag<"Zc:sizedDealloc-">, + HelpText<"Disable C++14 sized global deallocation functions">, + Alias<fno_sized_deallocation>; +def _SLASH_Zc_alignedNew : CLFlag<"Zc:alignedNew">, + HelpText<"Enable C++17 aligned allocation functions">, + Alias<faligned_allocation>; +def _SLASH_Zc_alignedNew_ : CLFlag<"Zc:alignedNew-">, + HelpText<"Disable C++17 aligned allocation functions">, + Alias<fno_aligned_allocation>; +def _SLASH_Zc_char8_t : CLFlag<"Zc:char8_t">, + HelpText<"Enable char8_t from C++2a">, + Alias<fchar8__t>; +def _SLASH_Zc_char8_t_ : CLFlag<"Zc:char8_t-">, + HelpText<"Disable char8_t from c++2a">, + Alias<fno_char8__t>; +def _SLASH_Zc_strictStrings : CLFlag<"Zc:strictStrings">, + HelpText<"Treat string literals as const">, Alias<W_Joined>, + AliasArgs<["error=c++11-compat-deprecated-writable-strings"]>; +def _SLASH_Zc_threadSafeInit : CLFlag<"Zc:threadSafeInit">, + HelpText<"Enable thread-safe initialization of static variables">, + Alias<fthreadsafe_statics>; +def _SLASH_Zc_threadSafeInit_ : CLFlag<"Zc:threadSafeInit-">, + HelpText<"Disable thread-safe initialization of static variables">, + Alias<fno_threadsafe_statics>; +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_Zc_twoPhase : CLFlag<"Zc:twoPhase">, + HelpText<"Enable two-phase name lookup in templates">, + Alias<fno_delayed_template_parsing>; +def _SLASH_Zc_twoPhase_ : CLFlag<"Zc:twoPhase-">, + HelpText<"Disable two-phase name lookup in templates (default)">, + Alias<fdelayed_template_parsing>; +def _SLASH_Z7 : CLFlag<"Z7">, + HelpText<"Enable CodeView debug information in object files">; +def _SLASH_Zd : CLFlag<"Zd">, + HelpText<"Emit debug line number tables only">; +def _SLASH_Zi : CLFlag<"Zi">, Alias<_SLASH_Z7>, + HelpText<"Like /Z7">; +def _SLASH_Zp : CLJoined<"Zp">, + HelpText<"Set default maximum struct packing alignment">, + Alias<fpack_struct_EQ>; +def _SLASH_Zp_flag : CLFlag<"Zp">, + HelpText<"Set default maximum struct packing alignment to 1">, + Alias<fpack_struct_EQ>, AliasArgs<["1"]>; +def _SLASH_Zs : CLFlag<"Zs">, HelpText<"Syntax-check only">, + Alias<fsyntax_only>; +def _SLASH_openmp_ : CLFlag<"openmp-">, + HelpText<"Disable OpenMP support">, Alias<fno_openmp>; +def _SLASH_openmp : CLFlag<"openmp">, HelpText<"Enable OpenMP support">, + Alias<fopenmp>; +def _SLASH_openmp_experimental : CLFlag<"openmp:experimental">, + HelpText<"Enable OpenMP support with experimental SIMD support">, + Alias<fopenmp>; + +// Non-aliases: + +def _SLASH_arch : CLCompileJoined<"arch:">, + HelpText<"Set architecture for code generation">; + +def _SLASH_M_Group : OptionGroup<"</M group>">, Group<cl_compile_Group>; +def _SLASH_volatile_Group : OptionGroup<"</volatile group>">, + Group<cl_compile_Group>; + +def _SLASH_EH : CLJoined<"EH">, HelpText<"Set exception handling model">; +def _SLASH_EP : CLFlag<"EP">, + HelpText<"Disable linemarker output and preprocess to stdout">; +def _SLASH_FA : CLFlag<"FA">, + HelpText<"Output assembly code file during compilation">; +def _SLASH_Fa : CLJoined<"Fa">, + HelpText<"Set assembly output file name (with /FA)">, + MetaVarName<"<file or dir/>">; +def _SLASH_fallback : CLCompileFlag<"fallback">, + HelpText<"Fall back to cl.exe if clang-cl fails to compile">; +def _SLASH_FI : CLJoinedOrSeparate<"FI">, + HelpText<"Include file before parsing">, Alias<include_>; +def _SLASH_Fe : CLJoined<"Fe">, + HelpText<"Set output executable file name">, + MetaVarName<"<file or dir/>">; +def _SLASH_Fi : CLCompileJoined<"Fi">, + HelpText<"Set preprocess output file name (with /P)">, + MetaVarName<"<file>">; +def _SLASH_Fo : CLCompileJoined<"Fo">, + HelpText<"Set output object file (with /c)">, + MetaVarName<"<file or dir/>">; +def _SLASH_guard : CLJoined<"guard:">, + HelpText<"Enable Control Flow Guard with /guard:cf, or only the table with /guard:cf,nochecks">; +def _SLASH_GX : CLFlag<"GX">, + HelpText<"Deprecated; use /EHsc">; +def _SLASH_GX_ : CLFlag<"GX-">, + HelpText<"Deprecated (like not passing /EH)">; +def _SLASH_imsvc : CLJoinedOrSeparate<"imsvc">, + HelpText<"Add <dir> to system include search path, as if in %INCLUDE%">, + MetaVarName<"<dir>">; +def _SLASH_LD : CLFlag<"LD">, HelpText<"Create DLL">; +def _SLASH_LDd : CLFlag<"LDd">, HelpText<"Create debug DLL">; +def _SLASH_link : CLRemainingArgsJoined<"link">, + HelpText<"Forward options to the linker">, MetaVarName<"<options>">; +def _SLASH_MD : Option<["/", "-"], "MD", KIND_FLAG>, Group<_SLASH_M_Group>, + Flags<[CLOption, DriverOption]>, HelpText<"Use DLL run-time">; +def _SLASH_MDd : Option<["/", "-"], "MDd", KIND_FLAG>, Group<_SLASH_M_Group>, + Flags<[CLOption, DriverOption]>, HelpText<"Use DLL debug run-time">; +def _SLASH_MT : Option<["/", "-"], "MT", KIND_FLAG>, Group<_SLASH_M_Group>, + Flags<[CLOption, DriverOption]>, HelpText<"Use static run-time">; +def _SLASH_MTd : Option<["/", "-"], "MTd", KIND_FLAG>, Group<_SLASH_M_Group>, + Flags<[CLOption, DriverOption]>, HelpText<"Use static debug run-time">; +def _SLASH_o : CLJoinedOrSeparate<"o">, + HelpText<"Deprecated (set output file name); use /Fe or /Fe">, + MetaVarName<"<file or dir/>">; +def _SLASH_P : CLFlag<"P">, HelpText<"Preprocess to file">; +def _SLASH_Tc : CLCompileJoinedOrSeparate<"Tc">, + HelpText<"Treat <file> as C source file">, MetaVarName<"<file>">; +def _SLASH_TC : CLCompileFlag<"TC">, HelpText<"Treat all source files as C">; +def _SLASH_Tp : CLCompileJoinedOrSeparate<"Tp">, + HelpText<"Treat <file> as C++ source file">, MetaVarName<"<file>">; +def _SLASH_TP : CLCompileFlag<"TP">, HelpText<"Treat all source files as C++">; +def _SLASH_volatile_iso : Option<["/", "-"], "volatile:iso", KIND_FLAG>, + Group<_SLASH_volatile_Group>, Flags<[CLOption, DriverOption]>, + HelpText<"Volatile loads and stores have standard semantics">; +def _SLASH_vmb : CLFlag<"vmb">, + HelpText<"Use a best-case representation method for member pointers">; +def _SLASH_vmg : CLFlag<"vmg">, + HelpText<"Use a most-general representation for member pointers">; +def _SLASH_vms : CLFlag<"vms">, + HelpText<"Set the default most-general representation to single inheritance">; +def _SLASH_vmm : CLFlag<"vmm">, + HelpText<"Set the default most-general representation to " + "multiple inheritance">; +def _SLASH_vmv : CLFlag<"vmv">, + HelpText<"Set the default most-general representation to " + "virtual inheritance">; +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_clang : CLJoined<"clang:">, + HelpText<"Pass <arg> to the clang driver">, MetaVarName<"<arg>">; +def _SLASH_Zl : CLFlag<"Zl">, + HelpText<"Do not let object file auto-link default libraries">; + +def _SLASH_Yc : CLJoined<"Yc">, + HelpText<"Generate a pch file for all code up to and including <filename>">, + MetaVarName<"<filename>">; +def _SLASH_Yu : CLJoined<"Yu">, + HelpText<"Load a pch file and use it instead of all code up to " + "and including <filename>">, + MetaVarName<"<filename>">; +def _SLASH_Y_ : CLFlag<"Y-">, + HelpText<"Disable precompiled headers, overrides /Yc and /Yu">; +def _SLASH_Zc_dllexportInlines : CLFlag<"Zc:dllexportInlines">, + HelpText<"dllexport/dllimport inline member functions of dllexport/import classes (default)">; +def _SLASH_Zc_dllexportInlines_ : CLFlag<"Zc:dllexportInlines-">, + HelpText<"Do not dllexport/dllimport inline member functions of dllexport/import classes">; +def _SLASH_Fp : CLJoined<"Fp">, + HelpText<"Set pch file name (with /Yc and /Yu)">, MetaVarName<"<file>">; + +def _SLASH_Gd : CLFlag<"Gd">, + HelpText<"Set __cdecl as a default calling convention">; +def _SLASH_Gr : CLFlag<"Gr">, + HelpText<"Set __fastcall as a default calling convention">; +def _SLASH_Gz : CLFlag<"Gz">, + HelpText<"Set __stdcall as a default calling convention">; +def _SLASH_Gv : CLFlag<"Gv">, + HelpText<"Set __vectorcall as a default calling convention">; +def _SLASH_Gregcall : CLFlag<"Gregcall">, + HelpText<"Set __regcall as a default calling convention">; + +// Ignored: + +def _SLASH_analyze_ : CLIgnoredFlag<"analyze-">; +def _SLASH_bigobj : CLIgnoredFlag<"bigobj">; +def _SLASH_cgthreads : CLIgnoredJoined<"cgthreads">; +def _SLASH_d2FastFail : CLIgnoredFlag<"d2FastFail">; +def _SLASH_d2Zi_PLUS : CLIgnoredFlag<"d2Zi+">; +def _SLASH_errorReport : CLIgnoredJoined<"errorReport">; +def _SLASH_FC : CLIgnoredFlag<"FC">; +def _SLASH_Fd : CLIgnoredJoined<"Fd">; +def _SLASH_FS : CLIgnoredFlag<"FS">; +def _SLASH_JMC : CLIgnoredFlag<"JMC">; +def _SLASH_kernel_ : CLIgnoredFlag<"kernel-">; +def _SLASH_nologo : CLIgnoredFlag<"nologo">; +def _SLASH_permissive_ : CLIgnoredFlag<"permissive-">; +def _SLASH_RTC : CLIgnoredJoined<"RTC">; +def _SLASH_sdl : CLIgnoredFlag<"sdl">; +def _SLASH_sdl_ : CLIgnoredFlag<"sdl-">; +def _SLASH_utf8 : CLIgnoredFlag<"utf-8">, + HelpText<"Set source and runtime encoding to UTF-8 (default)">; +def _SLASH_w : CLIgnoredJoined<"w">; +def _SLASH_Zc___cplusplus : CLIgnoredFlag<"Zc:__cplusplus">; +def _SLASH_Zc_auto : CLIgnoredFlag<"Zc:auto">; +def _SLASH_Zc_forScope : CLIgnoredFlag<"Zc:forScope">; +def _SLASH_Zc_inline : CLIgnoredFlag<"Zc:inline">; +def _SLASH_Zc_rvalueCast : CLIgnoredFlag<"Zc:rvalueCast">; +def _SLASH_Zc_ternary : CLIgnoredFlag<"Zc:ternary">; +def _SLASH_Zc_wchar_t : CLIgnoredFlag<"Zc:wchar_t">; +def _SLASH_ZH_MD5 : CLIgnoredFlag<"ZH:MD5">; +def _SLASH_ZH_SHA1 : CLIgnoredFlag<"ZH:SHA1">; +def _SLASH_ZH_SHA_256 : CLIgnoredFlag<"ZH:SHA_256">; +def _SLASH_Zm : CLIgnoredJoined<"Zm">; +def _SLASH_Zo : CLIgnoredFlag<"Zo">; +def _SLASH_Zo_ : CLIgnoredFlag<"Zo-">; + + +// Unsupported: + +def _SLASH_await : CLFlag<"await">; +def _SLASH_constexpr : CLJoined<"constexpr:">; +def _SLASH_AI : CLJoinedOrSeparate<"AI">; +def _SLASH_Bt : CLFlag<"Bt">; +def _SLASH_Bt_plus : CLFlag<"Bt+">; +def _SLASH_clr : CLJoined<"clr">; +def _SLASH_d2 : CLJoined<"d2">; +def _SLASH_doc : CLJoined<"doc">; +def _SLASH_FA_joined : CLJoined<"FA">; +def _SLASH_favor : CLJoined<"favor">; +def _SLASH_F : CLJoinedOrSeparate<"F">; +def _SLASH_Fm : CLJoined<"Fm">; +def _SLASH_Fr : CLJoined<"Fr">; +def _SLASH_FR : CLJoined<"FR">; +def _SLASH_FU : CLJoinedOrSeparate<"FU">; +def _SLASH_Fx : CLFlag<"Fx">; +def _SLASH_G1 : CLFlag<"G1">; +def _SLASH_G2 : CLFlag<"G2">; +def _SLASH_Ge : CLFlag<"Ge">; +def _SLASH_Gh : CLFlag<"Gh">; +def _SLASH_GH : CLFlag<"GH">; +def _SLASH_GL : CLFlag<"GL">; +def _SLASH_GL_ : CLFlag<"GL-">; +def _SLASH_Gm : CLFlag<"Gm">; +def _SLASH_Gm_ : CLFlag<"Gm-">; +def _SLASH_GT : CLFlag<"GT">; +def _SLASH_GZ : CLFlag<"GZ">; +def _SLASH_H : CLFlag<"H">; +def _SLASH_homeparams : CLFlag<"homeparams">; +def _SLASH_hotpatch : CLFlag<"hotpatch">; +def _SLASH_kernel : CLFlag<"kernel">; +def _SLASH_LN : CLFlag<"LN">; +def _SLASH_MP : CLJoined<"MP">; +def _SLASH_Qfast_transcendentals : CLFlag<"Qfast_transcendentals">; +def _SLASH_QIfist : CLFlag<"QIfist">; +def _SLASH_QIntel_jcc_erratum : CLFlag<"QIntel-jcc-erratum">; +def _SLASH_Qimprecise_fwaits : CLFlag<"Qimprecise_fwaits">; +def _SLASH_Qpar : CLFlag<"Qpar">; +def _SLASH_Qpar_report : CLJoined<"Qpar-report">; +def _SLASH_Qsafe_fp_loads : CLFlag<"Qsafe_fp_loads">; +def _SLASH_Qspectre : CLFlag<"Qspectre">; +def _SLASH_Qspectre_load : CLFlag<"Qspectre-load">; +def _SLASH_Qspectre_load_cf : CLFlag<"Qspectre-load-cf">; +def _SLASH_Qvec_report : CLJoined<"Qvec-report">; +def _SLASH_u : CLFlag<"u">; +def _SLASH_V : CLFlag<"V">; +def _SLASH_WL : CLFlag<"WL">; +def _SLASH_Wp64 : CLFlag<"Wp64">; +def _SLASH_Yd : CLFlag<"Yd">; +def _SLASH_Yl : CLJoined<"Yl">; +def _SLASH_Za : CLFlag<"Za">; +def _SLASH_Zc : CLJoined<"Zc:">; +def _SLASH_Ze : CLFlag<"Ze">; +def _SLASH_Zg : CLFlag<"Zg">; +def _SLASH_ZI : CLFlag<"ZI">; +def _SLASH_ZW : CLJoined<"ZW">; diff --git a/clang/include/clang/Driver/Phases.h b/clang/include/clang/Driver/Phases.h index 63931c00c890..ce914dd70514 100644 --- a/clang/include/clang/Driver/Phases.h +++ b/clang/include/clang/Driver/Phases.h @@ -22,10 +22,11 @@ namespace phases { Assemble, Link, IfsMerge, + LastPhase = IfsMerge, }; enum { - MaxNumberOfPhases = Link + 1 + MaxNumberOfPhases = LastPhase + 1 }; const char *getPhaseName(ID Id); diff --git a/clang/include/clang/Driver/SanitizerArgs.h b/clang/include/clang/Driver/SanitizerArgs.h index 0aebf8cb225d..934dab808e82 100644 --- a/clang/include/clang/Driver/SanitizerArgs.h +++ b/clang/include/clang/Driver/SanitizerArgs.h @@ -27,6 +27,8 @@ class SanitizerArgs { std::vector<std::string> UserBlacklistFiles; std::vector<std::string> SystemBlacklistFiles; + std::vector<std::string> CoverageAllowlistFiles; + std::vector<std::string> CoverageBlocklistFiles; int CoverageFeatures = 0; int MsanTrackOrigins = 0; bool MsanUseAfterDtor = true; diff --git a/clang/include/clang/Driver/Tool.h b/clang/include/clang/Driver/Tool.h index 8d0491606978..cc0a09fb2747 100644 --- a/clang/include/clang/Driver/Tool.h +++ b/clang/include/clang/Driver/Tool.h @@ -10,7 +10,6 @@ #define LLVM_CLANG_DRIVER_TOOL_H #include "clang/Basic/LLVM.h" -#include "llvm/Support/Program.h" namespace llvm { namespace opt { @@ -31,24 +30,6 @@ namespace driver { /// Tool - Information on a specific compilation tool. class Tool { -public: - // Documents the level of support for response files in this tool. - // Response files are necessary if the command line gets too large, - // requiring the arguments to be transferred to a file. - enum ResponseFileSupport { - // Provides full support for response files, which means we can transfer - // all tool input arguments to a file. E.g.: clang, gcc, binutils and MSVC - // tools. - RF_Full, - // Input file names can live in a file, but flags can't. E.g.: ld64 (Mac - // OS X linker). - RF_FileList, - // Does not support response files: all arguments must be passed via - // command line. - RF_None - }; - -private: /// The tool name (for debugging). const char *Name; @@ -58,20 +39,8 @@ private: /// The tool chain this tool is a part of. const ToolChain &TheToolChain; - /// The level of support for response files seen in this tool - const ResponseFileSupport ResponseSupport; - - /// The encoding to use when writing response files for this tool on Windows - const llvm::sys::WindowsEncodingMethod ResponseEncoding; - - /// The flag used to pass a response file via command line to this tool - const char *const ResponseFlag; - public: - Tool(const char *Name, const char *ShortName, const ToolChain &TC, - ResponseFileSupport ResponseSupport = RF_None, - llvm::sys::WindowsEncodingMethod ResponseEncoding = llvm::sys::WEM_UTF8, - const char *ResponseFlag = "@"); + Tool(const char *Name, const char *ShortName, const ToolChain &TC); public: virtual ~Tool(); @@ -87,29 +56,6 @@ public: virtual bool hasIntegratedCPP() const = 0; virtual bool isLinkJob() const { return false; } virtual bool isDsymutilJob() const { return false; } - /// Returns the level of support for response files of this tool, - /// whether it accepts arguments to be passed via a file on disk. - ResponseFileSupport getResponseFilesSupport() const { - return ResponseSupport; - } - /// Returns which encoding the response file should use. This is only - /// relevant on Windows platforms where there are different encodings being - /// accepted for different tools. On UNIX, UTF8 is universal. - /// - /// Windows use cases: - GCC and Binutils on mingw only accept ANSI response - /// files encoded with the system current code page. - /// - MSVC's CL.exe and LINK.exe accept UTF16 on Windows. - /// - Clang accepts both UTF8 and UTF16. - /// - /// FIXME: When GNU tools learn how to parse UTF16 on Windows, we should - /// always use UTF16 for Windows, which is the Windows official encoding for - /// international characters. - llvm::sys::WindowsEncodingMethod getResponseFileEncoding() const { - return ResponseEncoding; - } - /// Returns which prefix to use when passing the name of a response - /// file as a parameter to this tool. - const char *getResponseFileFlag() const { return ResponseFlag; } /// Does this tool have "good" standardized diagnostics, or should the /// driver add an additional "command failed" diagnostic on failures. diff --git a/clang/include/clang/Driver/ToolChain.h b/clang/include/clang/Driver/ToolChain.h index 26d8d43dd2fc..7495e08fe6e6 100644 --- a/clang/include/clang/Driver/ToolChain.h +++ b/clang/include/clang/Driver/ToolChain.h @@ -16,7 +16,9 @@ #include "clang/Driver/Action.h" #include "clang/Driver/Multilib.h" #include "clang/Driver/Types.h" +#include "llvm/ADT/APFloat.h" #include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/FloatingPointMode.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/Triple.h" @@ -137,6 +139,7 @@ private: mutable std::unique_ptr<Tool> Flang; mutable std::unique_ptr<Tool> Assemble; mutable std::unique_ptr<Tool> Link; + mutable std::unique_ptr<Tool> StaticLibTool; mutable std::unique_ptr<Tool> IfsMerge; mutable std::unique_ptr<Tool> OffloadBundler; mutable std::unique_ptr<Tool> OffloadWrapper; @@ -145,6 +148,7 @@ private: Tool *getFlang() const; Tool *getAssemble() const; Tool *getLink() const; + Tool *getStaticLibTool() const; Tool *getIfsMerge() const; Tool *getClangAs() const; Tool *getOffloadBundler() const; @@ -172,6 +176,7 @@ protected: virtual Tool *buildAssembler() const; virtual Tool *buildLinker() const; + virtual Tool *buildStaticLibTool() const; virtual Tool *getTool(Action::ActionClass AC) const; /// \name Utilities for implementing subclasses. @@ -293,6 +298,22 @@ public: const llvm::opt::DerivedArgList &Args, bool SameTripleAsHost, SmallVectorImpl<llvm::opt::Arg *> &AllocatedArgs) const; + /// Append the argument following \p A to \p DAL assuming \p A is an Xarch + /// argument. If \p AllocatedArgs is null pointer, synthesized arguments are + /// added to \p DAL, otherwise they are appended to \p AllocatedArgs. + virtual void TranslateXarchArgs( + const llvm::opt::DerivedArgList &Args, llvm::opt::Arg *&A, + llvm::opt::DerivedArgList *DAL, + SmallVectorImpl<llvm::opt::Arg *> *AllocatedArgs = nullptr) const; + + /// Translate -Xarch_ arguments. If there are no such arguments, return + /// a null pointer, otherwise return a DerivedArgList containing the + /// translated arguments. + virtual llvm::opt::DerivedArgList * + TranslateXarchArgs(const llvm::opt::DerivedArgList &Args, StringRef BoundArch, + Action::OffloadKind DeviceOffloadKind, + SmallVectorImpl<llvm::opt::Arg *> *AllocatedArgs) const; + /// Choose a tool to use to handle the action \p JA. /// /// This can be overridden when a particular ToolChain needs to use @@ -308,6 +329,9 @@ public: /// the linker suffix or name. std::string GetLinkerPath() const; + /// Returns the linker path for emitting a static library. + std::string GetStaticLibToolPath() const; + /// Dispatch to the specific toolchain for verbose printing. /// /// This is used when handling the verbose option to print detailed, @@ -395,6 +419,11 @@ public: getCompilerRTArgString(const llvm::opt::ArgList &Args, StringRef Component, FileType Type = ToolChain::FT_Static) const; + std::string getCompilerRTBasename(const llvm::opt::ArgList &Args, + StringRef Component, + FileType Type = ToolChain::FT_Static, + bool AddArch = true) const; + // Returns target specific runtime path if it exists. virtual Optional<std::string> getRuntimePath() const; @@ -513,6 +542,10 @@ public: /// FIXME: this really belongs on some sort of DeploymentTarget abstraction virtual bool hasBlocksRuntime() const { return true; } + /// Return the sysroot, possibly searching for a default sysroot using + /// target-specific logic. + virtual std::string computeSysRoot() const; + /// Add the clang cc1 arguments for system include paths. /// /// This routine is responsible for adding the necessary cc1 arguments to @@ -571,12 +604,19 @@ public: virtual void AddCCKextLibArgs(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const; + /// If a runtime library exists that sets global flags for unsafe floating + /// point math, return true. + /// + /// This checks for presence of the -Ofast, -ffast-math or -funsafe-math flags. + virtual bool isFastMathRuntimeAvailable( + const llvm::opt::ArgList &Args, std::string &Path) const; + /// AddFastMathRuntimeIfAvailable - If a runtime library exists that sets /// 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, llvm::opt::ArgStringList &CmdArgs) const; + 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. @@ -587,6 +627,10 @@ public: virtual void AddCudaIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const; + /// Add arguments to use system-specific HIP includes. + virtual void AddHIPIncludeArgs(const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &CC1Args) const; + /// Add arguments to use MCU GCC toolchain includes. virtual void AddIAMCUIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const; @@ -606,6 +650,15 @@ public: /// Returns true when it's possible to split LTO unit to use whole /// program devirtualization and CFI santiizers. virtual bool canSplitThinLTOUnit() const { return true; } + + /// Returns the output denormal handling type in the default floating point + /// environment for the given \p FPType if given. Otherwise, the default + /// assumed mode for any floating point type. + virtual llvm::DenormalMode getDefaultDenormalModeForType( + const llvm::opt::ArgList &DriverArgs, const JobAction &JA, + const llvm::fltSemantics *FPType = nullptr) const { + return llvm::DenormalMode::getIEEE(); + } }; /// Set a ToolChain's effective triple. Reset it when the registration object diff --git a/clang/include/clang/Driver/Types.h b/clang/include/clang/Driver/Types.h index c7c38fa52593..97bf5fd672ab 100644 --- a/clang/include/clang/Driver/Types.h +++ b/clang/include/clang/Driver/Types.h @@ -45,9 +45,6 @@ namespace types { /// temp file of this type, or null if unspecified. const char *getTypeTempSuffix(ID Id, bool CLMode = false); - /// onlyAssembleType - Should this type only be assembled. - bool onlyAssembleType(ID Id); - /// onlyPrecompileType - Should this type only be precompiled. bool onlyPrecompileType(ID Id); @@ -101,13 +98,12 @@ namespace types { ID lookupTypeForTypeSpecifier(const char *Name); /// getCompilationPhases - Get the list of compilation phases ('Phases') to be - /// done for type 'Id'. - void getCompilationPhases( - ID Id, - llvm::SmallVectorImpl<phases::ID> &Phases); - void getCompilationPhases(const clang::driver::Driver &Driver, - llvm::opt::DerivedArgList &DAL, ID Id, - llvm::SmallVectorImpl<phases::ID> &Phases); + /// done for type 'Id' up until including LastPhase. + llvm::SmallVector<phases::ID, phases::MaxNumberOfPhases> + getCompilationPhases(ID Id, phases::ID LastPhase = phases::LastPhase); + llvm::SmallVector<phases::ID, phases::MaxNumberOfPhases> + getCompilationPhases(const clang::driver::Driver &Driver, + llvm::opt::DerivedArgList &DAL, ID Id); /// lookupCXXTypeForCType - Lookup CXX input type that corresponds to given /// C type (used for clang++ emulation of g++ behaviour) diff --git a/clang/include/clang/Driver/XRayArgs.h b/clang/include/clang/Driver/XRayArgs.h index fa2583f4b966..2f055e5c6d7d 100644 --- a/clang/include/clang/Driver/XRayArgs.h +++ b/clang/include/clang/Driver/XRayArgs.h @@ -30,6 +30,8 @@ class XRayArgs { bool XRayAlwaysEmitCustomEvents = false; bool XRayAlwaysEmitTypedEvents = false; bool XRayRT = true; + bool XRayIgnoreLoops = false; + bool XRayFunctionIndex; public: /// Parses the XRay arguments from an argument list. diff --git a/clang/include/clang/Format/Format.h b/clang/include/clang/Format/Format.h index add2937f3b43..3549ec9eee0e 100644 --- a/clang/include/clang/Format/Format.h +++ b/clang/include/clang/Format/Format.h @@ -35,7 +35,12 @@ class DiagnosticConsumer; namespace format { -enum class ParseError { Success = 0, Error, Unsuitable }; +enum class ParseError { + Success = 0, + Error, + Unsuitable, + BinPackTrailingCommaConflict +}; class ParseErrorCategory final : public std::error_category { public: const char *name() const noexcept override; @@ -103,6 +108,17 @@ struct FormatStyle { /// \endcode bool AlignConsecutiveAssignments; + /// If ``true``, aligns consecutive bitfield members. + /// + /// This will align the bitfield separators of consecutive lines. This + /// will result in formattings like + /// \code + /// int aaaa : 1; + /// int b : 12; + /// int ccc : 8; + /// \endcode + bool AlignConsecutiveBitFields; + /// If ``true``, aligns consecutive declarations. /// /// This will align the declaration names of consecutive lines. This @@ -148,16 +164,43 @@ struct FormatStyle { /// Options for aligning backslashes in escaped newlines. EscapedNewlineAlignmentStyle AlignEscapedNewlines; + /// Different styles for aligning operands. + enum OperandAlignmentStyle { + /// Do not align operands of binary and ternary expressions. + /// The wrapped lines are indented ``ContinuationIndentWidth`` spaces from + /// the start of the line. + OAS_DontAlign, + /// 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 + /// + /// When ``BreakBeforeBinaryOperators`` is set, the wrapped operator is + /// aligned with the operand on the first line. + /// \code + /// int aaa = bbbbbbbbbbbbbbb + /// + ccccccccccccccc; + /// \endcode + OAS_Align, + /// Horizontally align operands of binary and ternary expressions. + /// + /// This is similar to ``AO_Align``, except when + /// ``BreakBeforeBinaryOperators`` is set, the operator is un-indented so + /// that the wrapped operand is aligned with the operand on the first line. + /// \code + /// int aaa = bbbbbbbbbbbbbbb + /// + ccccccccccccccc; + /// \endcode + OAS_AlignAfterOperator, + }; + /// If ``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; + OperandAlignmentStyle AlignOperands; /// If ``true``, aligns trailing comments. /// \code @@ -216,6 +259,20 @@ struct FormatStyle { /// \endcode bool AllowAllParametersOfDeclarationOnNextLine; + /// Allow short enums on a single line. + /// \code + /// true: + /// enum { A, B } myEnum; + /// + /// false: + /// enum + /// { + /// A, + /// B + /// } myEnum; + /// \endcode + bool AllowShortEnumsOnASingleLine; + /// Different styles for merging short blocks containing at most one /// statement. enum ShortBlockStyle { @@ -544,6 +601,35 @@ struct FormatStyle { /// \endcode bool BinPackArguments; + /// The style of inserting trailing commas into container literals. + enum TrailingCommaStyle { + /// Do not insert trailing commas. + TCS_None, + /// Insert trailing commas in container literals that were wrapped over + /// multiple lines. Note that this is conceptually incompatible with + /// bin-packing, because the trailing comma is used as an indicator + /// that a container should be formatted one-per-line (i.e. not bin-packed). + /// So inserting a trailing comma counteracts bin-packing. + TCS_Wrapped, + }; + + /// If set to ``TCS_Wrapped`` will insert trailing commas in container + /// literals (arrays and objects) that wrap across multiple lines. + /// It is currently only available for JavaScript + /// and disabled by default ``TCS_None``. + /// ``InsertTrailingCommas`` cannot be used together with ``BinPackArguments`` + /// as inserting the comma disables bin-packing. + /// \code + /// TSC_Wrapped: + /// const someArray = [ + /// aaaaaaaaaaaaaaaaaaaaaaaaaa, + /// aaaaaaaaaaaaaaaaaaaaaaaaaa, + /// aaaaaaaaaaaaaaaaaaaaaaaaaa, + /// // ^ inserted + /// ] + /// \endcode + TrailingCommaStyle InsertTrailingCommas; + /// If ``false``, a function declaration's or function definition's /// parameters will either all be on the same line or will have one line each. /// \code @@ -942,7 +1028,7 @@ struct FormatStyle { /// int foo(); /// } /// \endcode - bool AfterExternBlock; + bool AfterExternBlock; // Partially superseded by IndentExternBlock /// Wrap before ``catch``. /// \code /// true: @@ -973,6 +1059,37 @@ struct FormatStyle { /// } /// \endcode bool BeforeElse; + /// Wrap lambda block. + /// \code + /// true: + /// connect( + /// []() + /// { + /// foo(); + /// bar(); + /// }); + /// + /// false: + /// connect([]() { + /// foo(); + /// bar(); + /// }); + /// \endcode + bool BeforeLambdaBody; + /// Wrap before ``while``. + /// \code + /// true: + /// do { + /// foo(); + /// } + /// while (1); + /// + /// false: + /// do { + /// foo(); + /// } while (1); + /// \endcode + bool BeforeWhile; /// Indent the wrapped braces themselves. bool IndentBraces; /// If ``false``, empty function body can be put on a single line. @@ -1308,13 +1425,25 @@ struct FormatStyle { /// For example: TESTSUITE std::vector<std::string> NamespaceMacros; + /// A vector of macros which are whitespace-sensitive and shouldn't be + /// touched. + /// + /// These are expected to be macros of the form: + /// \code + /// STRINGIZE(...) + /// \endcode + /// + /// For example: STRINGIZE + std::vector<std::string> WhitespaceSensitiveMacros; + tooling::IncludeStyle IncludeStyle; /// Indent case labels one level from the switch statement. /// /// When ``false``, use the same indentation level as for the switch /// statement. Switch statement body is always indented one level more than - /// case labels. + /// case labels (except the first block following the case label, which + /// itself indents the code - unless IndentCaseBlocks is enabled). /// \code /// false: true: /// switch (fool) { vs. switch (fool) { @@ -1327,6 +1456,28 @@ struct FormatStyle { /// \endcode bool IndentCaseLabels; + /// Indent case label blocks one level from the case label. + /// + /// When ``false``, the block following the case label uses the same + /// indentation level as for the case label, treating the case label the same + /// as an if-statement. + /// When ``true``, the block gets indented as a scope block. + /// \code + /// false: true: + /// switch (fool) { vs. switch (fool) { + /// case 1: { case 1: + /// bar(); { + /// } break; bar(); + /// default: { } + /// plop(); break; + /// } default: + /// } { + /// plop(); + /// } + /// } + /// \endcode + bool IndentCaseBlocks; + /// Indent goto labels. /// /// When ``false``, goto labels are flushed left. @@ -1377,6 +1528,45 @@ struct FormatStyle { /// The preprocessor directive indenting style to use. PPDirectiveIndentStyle IndentPPDirectives; + /// Indents extern blocks + enum IndentExternBlockStyle { + /// Backwards compatible with AfterExternBlock's indenting. + /// \code + /// IndentExternBlock: AfterExternBlock + /// BraceWrapping.AfterExternBlock: true + /// extern "C" + /// { + /// void foo(); + /// } + /// \endcode + /// + /// \code + /// IndentExternBlock: AfterExternBlock + /// BraceWrapping.AfterExternBlock: false + /// extern "C" { + /// void foo(); + /// } + /// \endcode + IEBS_AfterExternBlock, + /// Does not indent extern blocks. + /// \code + /// extern "C" { + /// void foo(); + /// } + /// \endcode + IEBS_NoIndent, + /// Indents extern blocks. + /// \code + /// extern "C" { + /// void foo(); + /// } + /// \endcode + IEBS_Indent, + }; + + /// IndentExternBlockStyle is the type of indenting of extern blocks. + IndentExternBlockStyle IndentExternBlock; + /// The number of columns to use for indentation. /// \code /// IndentWidth: 3 @@ -1646,6 +1836,29 @@ struct FormatStyle { /// ``@property (readonly)`` instead of ``@property(readonly)``. bool ObjCSpaceAfterProperty; + /// Break parameters list into lines when there is nested block + /// parameters in a fuction call. + /// \code + /// false: + /// - (void)_aMethod + /// { + /// [self.test1 t:self w:self callback:^(typeof(self) self, NSNumber + /// *u, NSNumber *v) { + /// u = c; + /// }] + /// } + /// true: + /// - (void)_aMethod + /// { + /// [self.test1 t:self + /// w:self + /// callback:^(typeof(self) self, NSNumber *u, NSNumber *v) { + /// u = c; + /// }] + /// } + /// \endcode + bool ObjCBreakBeforeNestedBlockParam; + /// Add a space in front of an Objective-C protocol list, i.e. use /// ``Foo <Protocol>`` instead of ``Foo<Protocol>``. bool ObjCSpaceBeforeProtocolList; @@ -1872,6 +2085,17 @@ struct FormatStyle { /// } /// \endcode SBPO_ControlStatements, + /// Same as ``SBPO_ControlStatements`` except this option doesn't apply to + /// ForEach macros. This is useful in projects where ForEach macros are + /// treated as function calls instead of control statements. + /// \code + /// void f() { + /// Q_FOREACH(...) { + /// f(); + /// } + /// } + /// \endcode + SBPO_ControlStatementsExceptForEachMacros, /// Put a space before opening parentheses only if the parentheses are not /// empty i.e. '()' /// \code @@ -2047,8 +2271,12 @@ struct FormatStyle { UT_Never, /// Use tabs only for indentation. UT_ForIndentation, - /// Use tabs only for line continuation and indentation. + /// Fill all leading whitespace with tabs, and use spaces for alignment that + /// appears within a line (e.g. consecutive assignments and declarations). UT_ForContinuationAndIndentation, + /// Use tabs for line continuation and indentation, and spaces for + /// alignment. + UT_AlignWithSpaces, /// Use tabs whenever we need to fill whitespace that spans at least from /// one tab stop to the next one. UT_Always @@ -2065,6 +2293,7 @@ struct FormatStyle { return AccessModifierOffset == R.AccessModifierOffset && AlignAfterOpenBracket == R.AlignAfterOpenBracket && AlignConsecutiveAssignments == R.AlignConsecutiveAssignments && + AlignConsecutiveBitFields == R.AlignConsecutiveBitFields && AlignConsecutiveDeclarations == R.AlignConsecutiveDeclarations && AlignEscapedNewlines == R.AlignEscapedNewlines && AlignOperands == R.AlignOperands && @@ -2074,6 +2303,7 @@ struct FormatStyle { R.AllowAllConstructorInitializersOnNextLine && AllowAllParametersOfDeclarationOnNextLine == R.AllowAllParametersOfDeclarationOnNextLine && + AllowShortEnumsOnASingleLine == R.AllowShortEnumsOnASingleLine && AllowShortBlocksOnASingleLine == R.AllowShortBlocksOnASingleLine && AllowShortCaseLabelsOnASingleLine == R.AllowShortCaseLabelsOnASingleLine && @@ -2119,8 +2349,10 @@ struct FormatStyle { IncludeStyle.IncludeIsMainSourceRegex == R.IncludeStyle.IncludeIsMainSourceRegex && IndentCaseLabels == R.IndentCaseLabels && + IndentCaseBlocks == R.IndentCaseBlocks && IndentGotoLabels == R.IndentGotoLabels && IndentPPDirectives == R.IndentPPDirectives && + IndentExternBlock == R.IndentExternBlock && IndentWidth == R.IndentWidth && Language == R.Language && IndentWrappedFunctionNames == R.IndentWrappedFunctionNames && JavaImportGroups == R.JavaImportGroups && @@ -2135,6 +2367,8 @@ struct FormatStyle { NamespaceMacros == R.NamespaceMacros && ObjCBinPackProtocolList == R.ObjCBinPackProtocolList && ObjCBlockIndentWidth == R.ObjCBlockIndentWidth && + ObjCBreakBeforeNestedBlockParam == + R.ObjCBreakBeforeNestedBlockParam && ObjCSpaceAfterProperty == R.ObjCSpaceAfterProperty && ObjCSpaceBeforeProtocolList == R.ObjCSpaceBeforeProtocolList && PenaltyBreakAssignment == R.PenaltyBreakAssignment && diff --git a/clang/include/clang/Frontend/ASTConsumers.h b/clang/include/clang/Frontend/ASTConsumers.h index af8c4a517dcd..98cfc7cadc0d 100644 --- a/clang/include/clang/Frontend/ASTConsumers.h +++ b/clang/include/clang/Frontend/ASTConsumers.h @@ -39,7 +39,7 @@ std::unique_ptr<ASTConsumer> CreateASTPrinter(std::unique_ptr<raw_ostream> OS, std::unique_ptr<ASTConsumer> CreateASTDumper(std::unique_ptr<raw_ostream> OS, StringRef FilterString, bool DumpDecls, bool Deserialize, bool DumpLookups, - ASTDumpOutputFormat Format); + bool DumpDeclTypes, ASTDumpOutputFormat Format); // AST Decl node lister: prints qualified names of all filterable AST Decl // nodes. diff --git a/clang/include/clang/Frontend/ASTUnit.h b/clang/include/clang/Frontend/ASTUnit.h index a36655150d4e..50ab86ebad97 100644 --- a/clang/include/clang/Frontend/ASTUnit.h +++ b/clang/include/clang/Frontend/ASTUnit.h @@ -172,7 +172,7 @@ private: /// Sorted (by file offset) vector of pairs of file offset/Decl. using LocDeclsTy = SmallVector<std::pair<unsigned, Decl *>, 64>; - using FileDeclsTy = llvm::DenseMap<FileID, LocDeclsTy *>; + using FileDeclsTy = llvm::DenseMap<FileID, std::unique_ptr<LocDeclsTy>>; /// Map from FileID to the file-level declarations that it contains. /// The files and decls are only local (and non-preamble) ones. diff --git a/clang/include/clang/Frontend/CommandLineSourceLoc.h b/clang/include/clang/Frontend/CommandLineSourceLoc.h index e95d100f6a76..0827433462e1 100644 --- a/clang/include/clang/Frontend/CommandLineSourceLoc.h +++ b/clang/include/clang/Frontend/CommandLineSourceLoc.h @@ -38,7 +38,7 @@ public: // If both tail splits were valid integers, return success. if (!ColSplit.second.getAsInteger(10, PSL.Column) && !LineSplit.second.getAsInteger(10, PSL.Line)) { - PSL.FileName = LineSplit.first; + PSL.FileName = std::string(LineSplit.first); // On the command-line, stdin may be specified via "-". Inside the // compiler, stdin is called "<stdin>". diff --git a/clang/include/clang/Frontend/CompilerInstance.h b/clang/include/clang/Frontend/CompilerInstance.h index e501dde465cc..cb935becaef1 100644 --- a/clang/include/clang/Frontend/CompilerInstance.h +++ b/clang/include/clang/Frontend/CompilerInstance.h @@ -128,7 +128,7 @@ class CompilerInstance : public ModuleLoader { /// The set of top-level modules that has already been built on the /// fly as part of this overall compilation action. - std::map<std::string, std::string> BuiltModules; + std::map<std::string, std::string, std::less<>> BuiltModules; /// Should we delete the BuiltModules when we're done? bool DeleteBuiltModules = true; @@ -390,9 +390,7 @@ public: /// @name Virtual File System /// { - llvm::vfs::FileSystem &getVirtualFileSystem() const { - return getFileManager().getVirtualFileSystem(); - } + llvm::vfs::FileSystem &getVirtualFileSystem() const; /// } /// @name File Manager @@ -515,7 +513,7 @@ public: /// { IntrusiveRefCntPtr<ASTReader> getASTReader() const; - void setModuleManager(IntrusiveRefCntPtr<ASTReader> Reader); + void setASTReader(IntrusiveRefCntPtr<ASTReader> Reader); std::shared_ptr<ModuleDependencyCollector> getModuleDepCollector() const; void setModuleDepCollector( @@ -766,10 +764,7 @@ public: static bool InitializeSourceManager(const FrontendInputFile &Input, DiagnosticsEngine &Diags, FileManager &FileMgr, - SourceManager &SourceMgr, - HeaderSearch *HS, - DependencyOutputOptions &DepOpts, - const FrontendOptions &Opts); + SourceManager &SourceMgr); /// } @@ -781,7 +776,6 @@ public: return std::move(OutputStream); } - // Create module manager. void createASTReader(); bool loadModuleFile(StringRef FileName); diff --git a/clang/include/clang/Frontend/CompilerInvocation.h b/clang/include/clang/Frontend/CompilerInvocation.h index f3253d5b40e3..c723fc084c85 100644 --- a/clang/include/clang/Frontend/CompilerInvocation.h +++ b/clang/include/clang/Frontend/CompilerInvocation.h @@ -59,8 +59,7 @@ class TargetOptions; /// report the error(s). bool ParseDiagnosticArgs(DiagnosticOptions &Opts, llvm::opt::ArgList &Args, DiagnosticsEngine *Diags = nullptr, - bool DefaultDiagColor = true, - bool DefaultShowOpt = true); + bool DefaultDiagColor = true); class CompilerInvocationBase { public: @@ -154,9 +153,12 @@ public: /// one of the vaild-to-access (albeit arbitrary) states. /// /// \param [out] Res - The resulting invocation. + /// \param [in] CommandLineArgs - Array of argument strings, this must not + /// contain "-cc1". static bool CreateFromArgs(CompilerInvocation &Res, ArrayRef<const char *> CommandLineArgs, - DiagnosticsEngine &Diags); + DiagnosticsEngine &Diags, + const char *Argv0 = nullptr); /// Get the directory where the compiler headers /// reside, relative to the compiler binary (found by the passed in @@ -184,6 +186,18 @@ public: /// identifying the conditions under which the module was built. std::string getModuleHash() const; + using StringAllocator = llvm::function_ref<const char *(const llvm::Twine &)>; + /// Generate a cc1-compatible command line arguments from this instance. + /// + /// \param [out] Args - The generated arguments. Note that the caller is + /// responsible for inserting the path to the clang executable and "-cc1" if + /// desired. + /// \param SA - A function that given a Twine can allocate storage for a given + /// command line argument and return a pointer to the newly allocated string. + /// The returned pointer is what gets appended to Args. + void generateCC1CommandLine(llvm::SmallVectorImpl<const char *> &Args, + StringAllocator SA) const; + /// @} /// @name Option Subgroups /// @{ @@ -222,6 +236,16 @@ public: } /// @} + +private: + /// Parse options for flags that expose marshalling information in their + /// table-gen definition + /// + /// \param Args - The argument list containing the arguments to parse + /// \param Diags - The DiagnosticsEngine associated with CreateFromArgs + /// \returns - True if parsing was successful, false otherwise + bool parseSimpleArgs(const llvm::opt::ArgList &Args, + DiagnosticsEngine &Diags); }; IntrusiveRefCntPtr<llvm::vfs::FileSystem> diff --git a/clang/include/clang/Frontend/FrontendAction.h b/clang/include/clang/Frontend/FrontendAction.h index e994e24cf5af..c9f9f080c141 100644 --- a/clang/include/clang/Frontend/FrontendAction.h +++ b/clang/include/clang/Frontend/FrontendAction.h @@ -312,6 +312,7 @@ protected: bool BeginSourceFileAction(CompilerInstance &CI) override; void ExecuteAction() override; void EndSourceFileAction() override; + bool shouldEraseOutputFiles() override; public: /// Construct a WrapperFrontendAction from an existing action, taking diff --git a/clang/include/clang/Frontend/FrontendActions.h b/clang/include/clang/Frontend/FrontendActions.h index 89ac20075fa4..9ca2bfda2138 100644 --- a/clang/include/clang/Frontend/FrontendActions.h +++ b/clang/include/clang/Frontend/FrontendActions.h @@ -119,17 +119,13 @@ protected: bool hasASTFileSupport() const override { return false; } }; -class GenerateInterfaceStubAction : public ASTFrontendAction { -protected: - TranslationUnitKind getTranslationUnitKind() override { return TU_Module; } - - bool hasASTFileSupport() const override { return false; } -}; - -class GenerateInterfaceIfsExpV1Action : public GenerateInterfaceStubAction { +class GenerateInterfaceStubsAction : public ASTFrontendAction { protected: std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI, StringRef InFile) override; + + TranslationUnitKind getTranslationUnitKind() override { return TU_Module; } + bool hasASTFileSupport() const override { return false; } }; class GenerateModuleFromModuleMapAction : public GenerateModuleAction { diff --git a/clang/include/clang/Frontend/FrontendOptions.h b/clang/include/clang/Frontend/FrontendOptions.h index 09969b596d63..b2be33032c08 100644 --- a/clang/include/clang/Frontend/FrontendOptions.h +++ b/clang/include/clang/Frontend/FrontendOptions.h @@ -90,7 +90,7 @@ enum ActionKind { GeneratePCH, /// Generate Interface Stub Files. - GenerateInterfaceIfsExpV1, + GenerateInterfaceStubs, /// Only execute frontend initialization. InitOnly, @@ -285,6 +285,9 @@ public: /// Whether we include lookup table dumps in AST dumps. unsigned ASTDumpLookups : 1; + /// Whether we include declaration type dumps in AST dumps. + unsigned ASTDumpDeclTypes : 1; + /// Whether we are performing an implicit module build. unsigned BuildingImplicitModule : 1; @@ -297,6 +300,9 @@ public: /// Should a temporary file be used during compilation. unsigned UseTemporary : 1; + /// When using -emit-module, treat the modulemap as a system module. + unsigned IsSystemModule : 1; + CodeCompleteOptions CodeCompleteOpts; /// Specifies the output format of the AST. @@ -426,9 +432,15 @@ public: /// (in the format produced by -fdump-record-layouts). std::string OverrideRecordLayoutsFile; - /// Auxiliary triple for CUDA compilation. + /// Auxiliary triple for CUDA/HIP compilation. std::string AuxTriple; + /// Auxiliary target CPU for CUDA/HIP compilation. + Optional<std::string> AuxTargetCPU; + + /// Auxiliary target features for CUDA/HIP compilation. + Optional<std::vector<std::string>> AuxTargetFeatures; + /// Filename to write statistics to. std::string StatsFile; diff --git a/clang/include/clang/Frontend/LogDiagnosticPrinter.h b/clang/include/clang/Frontend/LogDiagnosticPrinter.h index 4816275cdc60..ec22a8b6cc5f 100644 --- a/clang/include/clang/Frontend/LogDiagnosticPrinter.h +++ b/clang/include/clang/Frontend/LogDiagnosticPrinter.h @@ -66,7 +66,7 @@ public: std::unique_ptr<raw_ostream> StreamOwner); void setDwarfDebugFlags(StringRef Value) { - DwarfDebugFlags = Value; + DwarfDebugFlags = std::string(Value); } void BeginSourceFile(const LangOptions &LO, const Preprocessor *PP) override { diff --git a/clang/include/clang/Frontend/PrecompiledPreamble.h b/clang/include/clang/Frontend/PrecompiledPreamble.h index 5ae77735576c..0f7e9d895a00 100644 --- a/clang/include/clang/Frontend/PrecompiledPreamble.h +++ b/clang/include/clang/Frontend/PrecompiledPreamble.h @@ -16,6 +16,7 @@ #include "clang/Lex/Lexer.h" #include "clang/Lex/Preprocessor.h" #include "llvm/ADT/IntrusiveRefCntPtr.h" +#include "llvm/ADT/StringRef.h" #include "llvm/Support/AlignOf.h" #include "llvm/Support/MD5.h" #include <cstddef> @@ -33,12 +34,13 @@ class FileSystem; namespace clang { class CompilerInstance; class CompilerInvocation; +class Decl; class DeclGroupRef; class PCHContainerOperations; /// Runs lexer to compute suggested preamble bounds. PreambleBounds ComputePreambleBounds(const LangOptions &LangOpts, - llvm::MemoryBuffer *Buffer, + const llvm::MemoryBuffer *Buffer, unsigned MaxLines); class PreambleCallbacks; @@ -94,6 +96,11 @@ public: /// be used for logging and debugging purposes only. std::size_t getSize() const; + /// Returned string is not null-terminated. + llvm::StringRef getContents() const { + return {PreambleBytes.data(), PreambleBytes.size()}; + } + /// Check whether PrecompiledPreamble can be reused for the new contents(\p /// MainFileBuffer) of the main file. bool CanReuse(const CompilerInvocation &Invocation, @@ -122,7 +129,8 @@ public: private: PrecompiledPreamble(PCHStorage Storage, std::vector<char> PreambleBytes, bool PreambleEndsAtStartOfLine, - llvm::StringMap<PreambleFileHash> FilesInPreamble); + llvm::StringMap<PreambleFileHash> FilesInPreamble, + llvm::StringSet<> MissingFiles); /// A temp file that would be deleted on destructor call. If destructor is not /// called for any reason, the file will be deleted at static objects' @@ -243,6 +251,15 @@ private: /// If any of the files have changed from one compile to the next, /// the preamble must be thrown away. llvm::StringMap<PreambleFileHash> FilesInPreamble; + /// Files that were not found during preamble building. If any of these now + /// exist then the preamble should not be reused. + /// + /// Storing *all* the missing files that could invalidate the preamble would + /// make it too expensive to revalidate (when the include path has many + /// entries, each #include will miss half of them on average). + /// Instead, we track only files that could have satisfied an #include that + /// was ultimately not found. + llvm::StringSet<> MissingFiles; /// The contents of the file that was used to precompile the preamble. Only /// contains first PreambleBounds::Size bytes. Used to compare if the relevant /// part of the file has not changed, so that preamble can be reused. @@ -277,6 +294,10 @@ public: virtual std::unique_ptr<PPCallbacks> createPPCallbacks(); /// The returned CommentHandler will be added to the preprocessor if not null. virtual CommentHandler *getCommentHandler(); + /// Determines which function bodies are parsed, by default skips everything. + /// Only used if FrontendOpts::SkipFunctionBodies is true. + /// See ASTConsumer::shouldSkipFunctionBody. + virtual bool shouldSkipFunctionBody(Decl *D) { return true; } }; enum class BuildPreambleError { diff --git a/clang/include/clang/Frontend/VerifyDiagnosticConsumer.h b/clang/include/clang/Frontend/VerifyDiagnosticConsumer.h index 965a14410832..a97cd138d159 100644 --- a/clang/include/clang/Frontend/VerifyDiagnosticConsumer.h +++ b/clang/include/clang/Frontend/VerifyDiagnosticConsumer.h @@ -10,6 +10,7 @@ #define LLVM_CLANG_FRONTEND_VERIFYDIAGNOSTICCONSUMER_H #include "clang/Basic/Diagnostic.h" +#include "clang/Basic/FileManager.h" #include "clang/Basic/LLVM.h" #include "clang/Basic/SourceLocation.h" #include "clang/Lex/Preprocessor.h" @@ -189,11 +190,10 @@ public: /// class Directive { public: - static std::unique_ptr<Directive> create(bool RegexKind, - SourceLocation DirectiveLoc, - SourceLocation DiagnosticLoc, - bool MatchAnyLine, StringRef Text, - unsigned Min, unsigned Max); + static std::unique_ptr<Directive> + create(bool RegexKind, SourceLocation DirectiveLoc, + SourceLocation DiagnosticLoc, bool MatchAnyFileAndLine, + bool MatchAnyLine, StringRef Text, unsigned Min, unsigned Max); public: /// Constant representing n or more matches. @@ -204,6 +204,7 @@ public: const std::string Text; unsigned Min, Max; bool MatchAnyLine; + bool MatchAnyFileAndLine; // `MatchAnyFileAndLine` implies `MatchAnyLine`. Directive(const Directive &) = delete; Directive &operator=(const Directive &) = delete; @@ -218,9 +219,11 @@ public: protected: Directive(SourceLocation DirectiveLoc, SourceLocation DiagnosticLoc, - bool MatchAnyLine, StringRef Text, unsigned Min, unsigned Max) - : DirectiveLoc(DirectiveLoc), DiagnosticLoc(DiagnosticLoc), - Text(Text), Min(Min), Max(Max), MatchAnyLine(MatchAnyLine) { + bool MatchAnyFileAndLine, bool MatchAnyLine, StringRef Text, + unsigned Min, unsigned Max) + : DirectiveLoc(DirectiveLoc), DiagnosticLoc(DiagnosticLoc), Text(Text), + Min(Min), Max(Max), MatchAnyLine(MatchAnyLine || MatchAnyFileAndLine), + MatchAnyFileAndLine(MatchAnyFileAndLine) { assert(!DirectiveLoc.isInvalid() && "DirectiveLoc is invalid!"); assert((!DiagnosticLoc.isInvalid() || MatchAnyLine) && "DiagnosticLoc is invalid!"); diff --git a/clang/include/clang/Index/IndexSymbol.h b/clang/include/clang/Index/IndexSymbol.h index 2e1e6005d68a..de98b8147e8a 100644 --- a/clang/include/clang/Index/IndexSymbol.h +++ b/clang/include/clang/Index/IndexSymbol.h @@ -54,6 +54,9 @@ enum class SymbolKind : uint8_t { Parameter, Using, + TemplateTypeParm, + TemplateTemplateParm, + NonTypeTemplateParm, }; enum class SymbolLanguage : uint8_t { diff --git a/clang/include/clang/Index/IndexingAction.h b/clang/include/clang/Index/IndexingAction.h index 9ed2a018f161..4baa2d5e7260 100644 --- a/clang/include/clang/Index/IndexingAction.h +++ b/clang/include/clang/Index/IndexingAction.h @@ -30,22 +30,21 @@ namespace serialization { } namespace index { - class IndexDataConsumer; +class IndexDataConsumer; /// Creates an ASTConsumer that indexes all symbols (macros and AST decls). +std::unique_ptr<ASTConsumer> +createIndexingASTConsumer(std::shared_ptr<IndexDataConsumer> DataConsumer, + const IndexingOptions &Opts, + std::shared_ptr<Preprocessor> PP); + std::unique_ptr<ASTConsumer> createIndexingASTConsumer( std::shared_ptr<IndexDataConsumer> DataConsumer, const IndexingOptions &Opts, std::shared_ptr<Preprocessor> PP, + // Prefer to set Opts.ShouldTraverseDecl and use the above overload. + // This version is only needed if used to *track* function body parsing. std::function<bool(const Decl *)> ShouldSkipFunctionBody); -inline std::unique_ptr<ASTConsumer> createIndexingASTConsumer( - std::shared_ptr<IndexDataConsumer> DataConsumer, - const IndexingOptions &Opts, std::shared_ptr<Preprocessor> PP) { - return createIndexingASTConsumer( - std::move(DataConsumer), Opts, std::move(PP), - /*ShouldSkipFunctionBody=*/[](const Decl *) { return false; }); -} - /// Creates a frontend action that indexes all symbols (macros and AST decls). std::unique_ptr<FrontendAction> createIndexingAction(std::shared_ptr<IndexDataConsumer> DataConsumer, diff --git a/clang/include/clang/Index/IndexingOptions.h b/clang/include/clang/Index/IndexingOptions.h index bbfd6e4a72c6..9f5c03d1b3b9 100644 --- a/clang/include/clang/Index/IndexingOptions.h +++ b/clang/include/clang/Index/IndexingOptions.h @@ -14,6 +14,7 @@ #include <string> namespace clang { +class Decl; namespace index { struct IndexingOptions { @@ -34,6 +35,12 @@ struct IndexingOptions { // Has no effect if IndexFunctionLocals are false. bool IndexParametersInDeclarations = false; bool IndexTemplateParameters = false; + + // If set, skip indexing inside some declarations for performance. + // This prevents traversal, so skipping a struct means its declaration an + // members won't be indexed, but references elsewhere to that struct will be. + // Currently this is only checked for top-level declarations. + std::function<bool(const Decl *)> ShouldTraverseDecl; }; } // namespace index diff --git a/clang/include/clang/Lex/DirectoryLookup.h b/clang/include/clang/Lex/DirectoryLookup.h index d526319a68c6..da2ae9fce1aa 100644 --- a/clang/include/clang/Lex/DirectoryLookup.h +++ b/clang/include/clang/Lex/DirectoryLookup.h @@ -14,13 +14,12 @@ #define LLVM_CLANG_LEX_DIRECTORYLOOKUP_H #include "clang/Basic/LLVM.h" +#include "clang/Basic/FileManager.h" #include "clang/Basic/SourceManager.h" #include "clang/Lex/ModuleMap.h" namespace clang { class HeaderMap; -class DirectoryEntry; -class FileEntry; class HeaderSearch; class Module; diff --git a/clang/include/clang/Lex/HeaderSearch.h b/clang/include/clang/Lex/HeaderSearch.h index 0d20dafe2cb1..28c57dbe3b8e 100644 --- a/clang/include/clang/Lex/HeaderSearch.h +++ b/clang/include/clang/Lex/HeaderSearch.h @@ -302,7 +302,7 @@ public: void AddIncludeAlias(StringRef Source, StringRef Dest) { if (!IncludeAliases) IncludeAliases.reset(new IncludeAliasMap); - (*IncludeAliases)[Source] = Dest; + (*IncludeAliases)[Source] = std::string(Dest); } /// Maps one header file name to a different header @@ -321,7 +321,7 @@ public: /// Set the path to the module cache. void setModuleCachePath(StringRef CachePath) { - ModuleCachePath = CachePath; + ModuleCachePath = std::string(CachePath); } /// Retrieve the path to the module cache. @@ -476,6 +476,13 @@ public: /// This routine does not consider the effect of \#import bool isFileMultipleIncludeGuarded(const FileEntry *File); + /// Determine whether the given file is known to have ever been \#imported + /// (or if it has been \#included and we've encountered a \#pragma once). + bool hasFileBeenImported(const FileEntry *File) { + const HeaderFileInfo *FI = getExistingFileInfo(File); + return FI && FI->isImport; + } + /// This method returns a HeaderMap for the specified /// FileEntry, uniquing them through the 'HeaderMaps' datastructure. const HeaderMap *CreateHeaderMap(const FileEntry *FE); @@ -559,6 +566,12 @@ public: ModuleMap::KnownHeader findModuleForHeader(const FileEntry *File, bool AllowTextual = false) const; + /// Retrieve all the modules corresponding to the given file. + /// + /// \ref findModuleForHeader should typically be used instead of this. + ArrayRef<ModuleMap::KnownHeader> + findAllModulesForHeader(const FileEntry *File) const; + /// Read the contents of the given module map file. /// /// \param File The module map file. diff --git a/clang/include/clang/Lex/HeaderSearchOptions.h b/clang/include/clang/Lex/HeaderSearchOptions.h index 5c19a41986b5..3af49e175395 100644 --- a/clang/include/clang/Lex/HeaderSearchOptions.h +++ b/clang/include/clang/Lex/HeaderSearchOptions.h @@ -115,7 +115,7 @@ public: std::string ModuleUserBuildPath; /// The mapping of module names to prebuilt module files. - std::map<std::string, std::string> PrebuiltModuleFiles; + std::map<std::string, std::string, std::less<>> PrebuiltModuleFiles; /// The directories used to load prebuilt module files. std::vector<std::string> PrebuiltModulePaths; @@ -239,11 +239,11 @@ public: } void AddVFSOverlayFile(StringRef Name) { - VFSOverlayFiles.push_back(Name); + VFSOverlayFiles.push_back(std::string(Name)); } void AddPrebuiltModulePath(StringRef Name) { - PrebuiltModulePaths.push_back(Name); + PrebuiltModulePaths.push_back(std::string(Name)); } }; diff --git a/clang/include/clang/Lex/LiteralSupport.h b/clang/include/clang/Lex/LiteralSupport.h index b9d64c24a00b..0c4f0fe277b7 100644 --- a/clang/include/clang/Lex/LiteralSupport.h +++ b/clang/include/clang/Lex/LiteralSupport.h @@ -40,7 +40,9 @@ void expandUCNs(SmallVectorImpl<char> &Buf, StringRef Input); /// of a ppnumber, classifying it as either integer, floating, or erroneous, /// determines the radix of the value and can convert it to a useful value. class NumericLiteralParser { - Preprocessor &PP; // needed for diagnostics + const SourceManager &SM; + const LangOptions &LangOpts; + DiagnosticsEngine &Diags; const char *const ThisTokBegin; const char *const ThisTokEnd; @@ -54,9 +56,9 @@ class NumericLiteralParser { SmallString<32> UDSuffixBuf; public: - NumericLiteralParser(StringRef TokSpelling, - SourceLocation TokLoc, - Preprocessor &PP); + NumericLiteralParser(StringRef TokSpelling, SourceLocation TokLoc, + const SourceManager &SM, const LangOptions &LangOpts, + const TargetInfo &Target, DiagnosticsEngine &Diags); bool hadError : 1; bool isUnsigned : 1; bool isLong : 1; // This is *not* set for long long. @@ -71,7 +73,9 @@ public: bool isFract : 1; // 1.0hr/r/lr/uhr/ur/ulr bool isAccum : 1; // 1.0hk/k/lk/uhk/uk/ulk - bool isFixedPointLiteral() const { return saw_fixed_point_suffix; } + bool isFixedPointLiteral() const { + return (saw_period || saw_exponent) && saw_fixed_point_suffix; + } bool isIntegerLiteral() const { return !saw_period && !saw_exponent && !isFixedPointLiteral(); diff --git a/clang/include/clang/Lex/ModuleMap.h b/clang/include/clang/Lex/ModuleMap.h index 1e6b28d4aa3d..5b164039080b 100644 --- a/clang/include/clang/Lex/ModuleMap.h +++ b/clang/include/clang/Lex/ModuleMap.h @@ -413,13 +413,17 @@ public: /// Is this a compiler builtin header? static bool isBuiltinHeader(StringRef FileName); + bool isBuiltinHeader(const FileEntry *File); /// Add a module map callback. void addModuleMapCallbacks(std::unique_ptr<ModuleMapCallbacks> Callback) { Callbacks.push_back(std::move(Callback)); } - /// Retrieve the module that owns the given header file, if any. + /// Retrieve the module that owns the given header file, if any. Note that + /// this does not implicitly load module maps, except for builtin headers, + /// and does not consult the external source. (Those checks are the + /// responsibility of \ref HeaderSearch.) /// /// \param File The header file that is likely to be included. /// @@ -433,13 +437,19 @@ public: KnownHeader findModuleForHeader(const FileEntry *File, bool AllowTextual = false); - /// 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. + /// Retrieve all the modules that contain the given header file. Note that + /// this does not implicitly load module maps, except for builtin headers, + /// and does not consult the external source. (Those checks are the + /// responsibility of \ref HeaderSearch.) /// /// Typically, \ref findModuleForHeader should be used instead, as it picks /// the preferred module for the header. - ArrayRef<KnownHeader> findAllModulesForHeader(const FileEntry *File) const; + ArrayRef<KnownHeader> findAllModulesForHeader(const FileEntry *File); + + /// Like \ref findAllModulesForHeader, but do not attempt to infer module + /// ownership from umbrella headers if we've not already done so. + ArrayRef<KnownHeader> + findResolvedModulesForHeader(const FileEntry *File) const; /// Resolve all lazy header directives for the specified file. /// @@ -605,9 +615,7 @@ public: return &I->second; } - void addAdditionalModuleMapFile(const Module *M, const FileEntry *ModuleMap) { - AdditionalModMaps[M].insert(ModuleMap); - } + void addAdditionalModuleMapFile(const Module *M, const FileEntry *ModuleMap); /// Resolve all of the unresolved exports in the given module. /// diff --git a/clang/include/clang/Lex/PPCallbacks.h b/clang/include/clang/Lex/PPCallbacks.h index 1edcb567de66..de5e8eb2ca22 100644 --- a/clang/include/clang/Lex/PPCallbacks.h +++ b/clang/include/clang/Lex/PPCallbacks.h @@ -308,7 +308,7 @@ public: /// read. virtual void HasInclude(SourceLocation Loc, StringRef FileName, bool IsAngled, Optional<FileEntryRef> File, - SrcMgr::CharacteristicKind FileType) {} + SrcMgr::CharacteristicKind FileType); /// Hook called when a source range is skipped. /// \param Range The SourceRange that was skipped. The range begins at the @@ -374,7 +374,6 @@ public: /// Simple wrapper class for chaining callbacks. class PPChainedCallbacks : public PPCallbacks { - virtual void anchor(); std::unique_ptr<PPCallbacks> First, Second; public: @@ -382,6 +381,8 @@ public: std::unique_ptr<PPCallbacks> _Second) : First(std::move(_First)), Second(std::move(_Second)) {} + ~PPChainedCallbacks() override; + void FileChanged(SourceLocation Loc, FileChangeReason Reason, SrcMgr::CharacteristicKind FileType, FileID PrevFID) override { @@ -490,10 +491,7 @@ public: void HasInclude(SourceLocation Loc, StringRef FileName, bool IsAngled, Optional<FileEntryRef> File, - SrcMgr::CharacteristicKind FileType) override { - First->HasInclude(Loc, FileName, IsAngled, File, FileType); - Second->HasInclude(Loc, FileName, IsAngled, File, FileType); - } + SrcMgr::CharacteristicKind FileType) override; void PragmaOpenCLExtension(SourceLocation NameLoc, const IdentifierInfo *Name, SourceLocation StateLoc, unsigned State) override { diff --git a/clang/include/clang/Lex/Pragma.h b/clang/include/clang/Lex/Pragma.h index e9434269c19c..cf8cca5414ea 100644 --- a/clang/include/clang/Lex/Pragma.h +++ b/clang/include/clang/Lex/Pragma.h @@ -96,11 +96,10 @@ public: class PragmaNamespace : public PragmaHandler { /// Handlers - This is a map of the handlers in this namespace with their name /// as key. - llvm::StringMap<PragmaHandler *> Handlers; + llvm::StringMap<std::unique_ptr<PragmaHandler>> Handlers; public: explicit PragmaNamespace(StringRef Name) : PragmaHandler(Name) {} - ~PragmaNamespace() override; /// FindHandler - Check to see if there is already a handler for the /// specified name. If not, return the handler for the null name if it diff --git a/clang/include/clang/Lex/Preprocessor.h b/clang/include/clang/Lex/Preprocessor.h index 9716196b95c2..5cd017fa925f 100644 --- a/clang/include/clang/Lex/Preprocessor.h +++ b/clang/include/clang/Lex/Preprocessor.h @@ -416,6 +416,14 @@ class Preprocessor { /// of phase 4 of translation or for some other situation. unsigned LexLevel = 0; + /// The number of (LexLevel 0) preprocessor tokens. + unsigned TokenCount = 0; + + /// The maximum number of (LexLevel 0) tokens before issuing a -Wmax-tokens + /// warning, or zero for unlimited. + unsigned MaxTokens = 0; + SourceLocation MaxTokensOverrideLoc; + public: struct PreambleSkipInfo { SourceLocation HashTokenLoc; @@ -1010,6 +1018,19 @@ public: } /// \} + /// Get the number of tokens processed so far. + unsigned getTokenCount() const { return TokenCount; } + + /// Get the max number of tokens before issuing a -Wmax-tokens warning. + unsigned getMaxTokens() const { return MaxTokens; } + + void overrideMaxTokens(unsigned Value, SourceLocation Loc) { + MaxTokens = Value; + MaxTokensOverrideLoc = Loc; + }; + + SourceLocation getMaxTokensOverrideLoc() const { return MaxTokensOverrideLoc; } + /// Register a function that would be called on each token in the final /// expanded token stream. /// This also reports annotation tokens produced by the parser. @@ -1163,7 +1184,7 @@ public: /// /// These predefines are automatically injected when parsing the main file. void setPredefines(const char *P) { Predefines = P; } - void setPredefines(StringRef P) { Predefines = P; } + void setPredefines(StringRef P) { Predefines = std::string(P); } /// Return information about the specified preprocessor /// identifier token. @@ -1541,6 +1562,12 @@ public: void EnterAnnotationToken(SourceRange Range, tok::TokenKind Kind, void *AnnotationVal); + /// Determine whether it's possible for a future call to Lex to produce an + /// annotation token created by a previous call to EnterAnnotationToken. + bool mightHavePendingAnnotationTokens() { + return CurLexerKind != CLK_Lexer; + } + /// Update the current token to represent the provided /// identifier, in order to cache an action performed by typo correction. void TypoCorrectToken(const Token &Tok) { @@ -2203,21 +2230,23 @@ private: ModuleBegin, ModuleImport, SkippedModuleImport, + Failure, } Kind; Module *ModuleForHeader = nullptr; ImportAction(ActionKind AK, Module *Mod = nullptr) : Kind(AK), ModuleForHeader(Mod) { - assert((AK == None || Mod) && "no module for module action"); + assert((AK == None || Mod || AK == Failure) && + "no module for module action"); } }; Optional<FileEntryRef> LookupHeaderIncludeOrImport( - const DirectoryLookup *&CurDir, StringRef Filename, + const DirectoryLookup *&CurDir, StringRef &Filename, SourceLocation FilenameLoc, CharSourceRange FilenameRange, const Token &FilenameTok, bool &IsFrameworkFound, bool IsImportDecl, bool &IsMapped, const DirectoryLookup *LookupFrom, - const FileEntry *LookupFromFile, StringRef LookupFilename, + const FileEntry *LookupFromFile, StringRef &LookupFilename, SmallVectorImpl<char> &RelativePath, SmallVectorImpl<char> &SearchPath, ModuleMap::KnownHeader &SuggestedModule, bool isAngled); @@ -2249,20 +2278,22 @@ public: /// into a module, or is outside any module, returns nullptr. Module *getModuleForLocation(SourceLocation Loc); - /// We want to produce a diagnostic at location IncLoc concerning a - /// missing module import. - /// - /// \param IncLoc The location at which the missing import was detected. - /// \param M The desired module. - /// \param MLoc A location within the desired module at which some desired - /// effect occurred (eg, where a desired entity was declared). - /// - /// \return A file that can be #included to import a module containing MLoc. - /// Null if no such file could be determined or if a #include is not - /// appropriate. - const FileEntry *getModuleHeaderToIncludeForDiagnostics(SourceLocation IncLoc, - Module *M, - SourceLocation MLoc); + /// We want to produce a diagnostic at location IncLoc concerning an + /// unreachable effect at location MLoc (eg, where a desired entity was + /// declared or defined). Determine whether the right way to make MLoc + /// reachable is by #include, and if so, what header should be included. + /// + /// This is not necessarily fast, and might load unexpected module maps, so + /// should only be called by code that intends to produce an error. + /// + /// \param IncLoc The location at which the missing effect was detected. + /// \param MLoc A location within an unimported module at which the desired + /// effect occurred. + /// \return A file that can be #included to provide the desired effect. Null + /// if no such file could be determined or if a #include is not + /// appropriate (eg, if a module should be imported instead). + const FileEntry *getHeaderToIncludeForDiagnostics(SourceLocation IncLoc, + SourceLocation MLoc); bool isRecordingPreamble() const { return PreambleConditionalStack.isRecording(); diff --git a/clang/include/clang/Lex/PreprocessorOptions.h b/clang/include/clang/Lex/PreprocessorOptions.h index abffbd03c3b4..c551f87e0d7b 100644 --- a/clang/include/clang/Lex/PreprocessorOptions.h +++ b/clang/include/clang/Lex/PreprocessorOptions.h @@ -189,18 +189,25 @@ public: /// Set up preprocessor for RunAnalysis action. bool SetUpStaticAnalyzer = false; + /// Prevents intended crashes when using #pragma clang __debug. For testing. + bool DisablePragmaDebugCrash = false; + public: PreprocessorOptions() : PrecompiledPreambleBytes(0, false) {} - void addMacroDef(StringRef Name) { Macros.emplace_back(Name, false); } - void addMacroUndef(StringRef Name) { Macros.emplace_back(Name, true); } + void addMacroDef(StringRef Name) { + Macros.emplace_back(std::string(Name), false); + } + void addMacroUndef(StringRef Name) { + Macros.emplace_back(std::string(Name), true); + } void addRemappedFile(StringRef From, StringRef To) { - RemappedFiles.emplace_back(From, To); + RemappedFiles.emplace_back(std::string(From), std::string(To)); } void addRemappedFile(StringRef From, llvm::MemoryBuffer *To) { - RemappedFileBuffers.emplace_back(From, To); + RemappedFileBuffers.emplace_back(std::string(From), To); } void clearRemappedFiles() { diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h index e320c9647818..e809d87b59a0 100644 --- a/clang/include/clang/Parse/Parser.h +++ b/clang/include/clang/Parse/Parser.h @@ -13,7 +13,6 @@ #ifndef LLVM_CLANG_PARSE_PARSER_H #define LLVM_CLANG_PARSE_PARSER_H -#include "clang/AST/OpenMPClause.h" #include "clang/AST/Availability.h" #include "clang/Basic/BitmaskEnum.h" #include "clang/Basic/OpenMPKinds.h" @@ -24,6 +23,7 @@ #include "clang/Sema/DeclSpec.h" #include "clang/Sema/Sema.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/Frontend/OpenMP/OMPContext.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/PrettyStackTrace.h" #include "llvm/Support/SaveAndRestore.h" @@ -49,6 +49,10 @@ namespace clang { class OMPClause; class ObjCTypeParamList; class ObjCTypeParameter; + struct OMPTraitProperty; + struct OMPTraitSelector; + struct OMPTraitSet; + class OMPTraitInfo; /// Parser - This implements a parser for the C family of languages. After /// parsing units of the grammar, productions are invoked to handle whatever has @@ -178,6 +182,7 @@ class Parser : public CodeCompletionHandler { std::unique_ptr<PragmaHandler> PCSectionHandler; std::unique_ptr<PragmaHandler> MSCommentHandler; std::unique_ptr<PragmaHandler> MSDetectMismatchHandler; + std::unique_ptr<PragmaHandler> FloatControlHandler; std::unique_ptr<PragmaHandler> MSPointersToMembers; std::unique_ptr<PragmaHandler> MSVtorDisp; std::unique_ptr<PragmaHandler> MSInitSeg; @@ -201,6 +206,8 @@ class Parser : public CodeCompletionHandler { std::unique_ptr<PragmaHandler> STDCCXLIMITHandler; std::unique_ptr<PragmaHandler> STDCUnknownHandler; std::unique_ptr<PragmaHandler> AttributePragmaHandler; + std::unique_ptr<PragmaHandler> MaxTokensHerePragmaHandler; + std::unique_ptr<PragmaHandler> MaxTokensTotalPragmaHandler; std::unique_ptr<CommentHandler> CommentSemaHandler; @@ -234,6 +241,9 @@ class Parser : public CodeCompletionHandler { /// The "depth" of the template parameters currently being parsed. unsigned TemplateParameterDepth; + /// Current kind of OpenMP clause + OpenMPClauseKind OMPClauseKind = llvm::omp::OMPC_unknown; + /// RAII class that manages the template parameter depth. class TemplateParameterDepthRAII { unsigned &Depth; @@ -270,6 +280,22 @@ class Parser : public CodeCompletionHandler { /// top-level declaration is finished. SmallVector<TemplateIdAnnotation *, 16> TemplateIds; + void MaybeDestroyTemplateIds() { + if (!TemplateIds.empty() && + (Tok.is(tok::eof) || !PP.mightHavePendingAnnotationTokens())) + DestroyTemplateIds(); + } + void DestroyTemplateIds(); + + /// RAII object to destroy TemplateIdAnnotations where possible, from a + /// likely-good position during parsing. + struct DestroyTemplateIdAnnotationsRAIIObj { + Parser &Self; + + DestroyTemplateIdAnnotationsRAIIObj(Parser &Self) : Self(Self) {} + ~DestroyTemplateIdAnnotationsRAIIObj() { Self.MaybeDestroyTemplateIds(); } + }; + /// Identifiers which have been declared within a tentative parse. SmallVector<IdentifierInfo *, 8> TentativelyDeclaredIdentifiers; @@ -719,6 +745,10 @@ private: /// #pragma STDC FENV_ACCESS... void HandlePragmaFEnvAccess(); + /// Handle the annotation token produced for + /// #pragma float_control + void HandlePragmaFloatControl(); + /// \brief Handle the annotation token produced for /// #pragma clang fp ... void HandlePragmaFP(); @@ -761,13 +791,17 @@ public: } /// getTypeAnnotation - Read a parsed type out of an annotation token. - static ParsedType getTypeAnnotation(const Token &Tok) { + static TypeResult getTypeAnnotation(const Token &Tok) { + if (!Tok.getAnnotationValue()) + return TypeError(); return ParsedType::getFromOpaquePtr(Tok.getAnnotationValue()); } private: - static void setTypeAnnotation(Token &Tok, ParsedType T) { - Tok.setAnnotationValue(T.getAsOpaquePtr()); + static void setTypeAnnotation(Token &Tok, TypeResult T) { + assert((T.isInvalid() || T.get()) && + "produced a valid-but-null type annotation?"); + Tok.setAnnotationValue(T.isInvalid() ? nullptr : T.get().getAsOpaquePtr()); } static NamedDecl *getNonTypeAnnotation(const Token &Tok) { @@ -806,6 +840,16 @@ public: bool IsNewScope); bool TryAnnotateCXXScopeToken(bool EnteringContext = false); + bool MightBeCXXScopeToken() { + return Tok.is(tok::identifier) || Tok.is(tok::coloncolon) || + (Tok.is(tok::annot_template_id) && + NextToken().is(tok::coloncolon)) || + Tok.is(tok::kw_decltype) || Tok.is(tok::kw___super); + } + bool TryAnnotateOptionalCXXScopeToken(bool EnteringContext = false) { + return MightBeCXXScopeToken() && TryAnnotateCXXScopeToken(EnteringContext); + } + private: enum AnnotatedNameKind { /// Annotation has failed and emitted an error. @@ -1047,12 +1091,40 @@ public: } }; + /// Introduces zero or more scopes for parsing. The scopes will all be exited + /// when the object is destroyed. + class MultiParseScope { + Parser &Self; + unsigned NumScopes = 0; + + MultiParseScope(const MultiParseScope&) = delete; + + public: + MultiParseScope(Parser &Self) : Self(Self) {} + void Enter(unsigned ScopeFlags) { + Self.EnterScope(ScopeFlags); + ++NumScopes; + } + void Exit() { + while (NumScopes) { + Self.ExitScope(); + --NumScopes; + } + } + ~MultiParseScope() { + Exit(); + } + }; + /// EnterScope - Start a new scope. void EnterScope(unsigned ScopeFlags); /// ExitScope - Pop a scope off the scope stack. void ExitScope(); + /// Re-enter the template scopes for a declaration that might be a template. + unsigned ReenterTemplateScopes(MultiParseScope &S, Decl *D); + private: /// RAII object used to modify the scope flags for the current scope. class ParseScopeFlags { @@ -1101,7 +1173,8 @@ public: /// it (unless StopBeforeMatch is specified). Because we cannot guarantee /// that the token will ever occur, this skips to the next token, or to some /// likely good stopping point. If Flags has StopAtSemi flag, skipping will - /// stop at a ';' character. + /// stop at a ';' character. Balances (), [], and {} delimiter tokens while + /// skipping. /// /// If SkipUntil finds the specified token, it returns true, otherwise it /// returns false. @@ -1236,13 +1309,7 @@ private: Decl *D; CachedTokens Toks; - /// Whether this member function had an associated template - /// scope. When true, D is a template declaration. - /// otherwise, it is a member function declaration. - bool TemplateScope; - - explicit LexedMethod(Parser* P, Decl *MD) - : Self(P), D(MD), TemplateScope(false) {} + explicit LexedMethod(Parser *P, Decl *MD) : Self(P), D(MD) {} void ParseLexedMethodDefs() override; }; @@ -1272,8 +1339,7 @@ private: /// argument (C++ [class.mem]p2). struct LateParsedMethodDeclaration : public LateParsedDeclaration { explicit LateParsedMethodDeclaration(Parser *P, Decl *M) - : Self(P), Method(M), TemplateScope(false), - ExceptionSpecTokens(nullptr) {} + : Self(P), Method(M), ExceptionSpecTokens(nullptr) {} void ParseLexedMethodDeclarations() override; @@ -1282,11 +1348,6 @@ private: /// Method - The method declaration. Decl *Method; - /// Whether this member function had an associated template - /// scope. When true, D is a template declaration. - /// otherwise, it is a member function declaration. - bool TemplateScope; - /// DefaultArgs - Contains the parameters of the function and /// their default arguments. At least one of the parameters will /// have a default argument, but all of the parameters of the @@ -1331,18 +1392,13 @@ private: /// parsed after the corresponding top-level class is complete. struct ParsingClass { ParsingClass(Decl *TagOrTemplate, bool TopLevelClass, bool IsInterface) - : TopLevelClass(TopLevelClass), TemplateScope(false), - IsInterface(IsInterface), TagOrTemplate(TagOrTemplate) { } + : TopLevelClass(TopLevelClass), IsInterface(IsInterface), + TagOrTemplate(TagOrTemplate) {} /// Whether this is a "top-level" class, meaning that it is /// not nested within another class. bool TopLevelClass : 1; - /// Whether this class had an associated template - /// scope. When true, TagOrTemplate is a template declaration; - /// otherwise, it is a tag declaration. - bool TemplateScope : 1; - /// Whether this class is an __interface. bool IsInterface : 1; @@ -1441,11 +1497,14 @@ private: SourceRange getSourceRange() const LLVM_READONLY; }; + // In ParseCXXInlineMethods.cpp. + struct ReenterTemplateScopeRAII; + struct ReenterClassScopeRAII; + void LexTemplateFunctionForLateParsing(CachedTokens &Toks); void ParseLateTemplatedFuncDef(LateParsedTemplate &LPT); static void LateTemplateParserCallback(void *P, LateParsedTemplate &LPT); - static void LateTemplateParserCleanupCallback(void *P); Sema::ParsingClassState PushParsingClass(Decl *TagOrTemplate, bool TopLevelClass, bool IsInterface); @@ -1689,6 +1748,8 @@ public: unsigned &NumLineToksConsumed, bool IsUnevaluated); + ExprResult ParseStringLiteralExpression(bool AllowUserDefinedLiteral = false); + private: ExprResult ParseExpressionWithLeadingAt(SourceLocation AtLoc); @@ -1739,6 +1800,7 @@ private: ExprResult ParsePostfixExpressionSuffix(ExprResult LHS); ExprResult ParseUnaryExprOrTypeTraitExpression(); ExprResult ParseBuiltinPrimaryExpression(); + ExprResult ParseUniqueStableNameExpression(); ExprResult ParseExprAfterUnaryExprOrTypeTrait(const Token &OpTok, bool &isCastExpr, @@ -1781,8 +1843,6 @@ private: SourceLocation LParenLoc, SourceLocation RParenLoc); - ExprResult ParseStringLiteralExpression(bool AllowUserDefinedLiteral = false); - ExprResult ParseGenericSelectionExpression(); ExprResult ParseObjCBoolLiteral(); @@ -1801,7 +1861,9 @@ private: bool EnteringContext, IdentifierInfo &II, CXXScopeSpec &SS); - bool ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS, ParsedType ObjectType, + bool ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS, + ParsedType ObjectType, + bool ObjectHasErrors, bool EnteringContext, bool *MayBePseudoDestructor = nullptr, bool IsTypename = false, @@ -1923,6 +1985,7 @@ private: //===--------------------------------------------------------------------===// // C++ Concepts + ExprResult ParseRequiresExpression(); void ParseTrailingRequiresClause(Declarator &D); //===--------------------------------------------------------------------===// @@ -1939,7 +2002,8 @@ private: } bool MayBeDesignationStart(); ExprResult ParseBraceInitializer(); - ExprResult ParseInitializerWithPotentialDesignator(); + ExprResult ParseInitializerWithPotentialDesignator( + llvm::function_ref<void(const Designation &)> CodeCompleteCB); //===--------------------------------------------------------------------===// // clang Expressions @@ -2007,8 +2071,9 @@ private: StmtResult ParseCompoundStatementBody(bool isStmtExpr = false); bool ParseParenExprOrCondition(StmtResult *InitStmt, Sema::ConditionResult &CondResult, - SourceLocation Loc, - Sema::ConditionKind CK); + SourceLocation Loc, Sema::ConditionKind CK, + SourceLocation *LParenLoc = nullptr, + SourceLocation *RParenLoc = nullptr); StmtResult ParseIfStatement(SourceLocation *TrailingElseLoc); StmtResult ParseSwitchStatement(SourceLocation *TrailingElseLoc); StmtResult ParseWhileStatement(SourceLocation *TrailingElseLoc); @@ -2135,6 +2200,68 @@ private: llvm_unreachable("Missing DeclSpecContext case"); } + /// Whether a defining-type-specifier is permitted in a given context. + enum class AllowDefiningTypeSpec { + /// The grammar doesn't allow a defining-type-specifier here, and we must + /// not parse one (eg, because a '{' could mean something else). + No, + /// The grammar doesn't allow a defining-type-specifier here, but we permit + /// one for error recovery purposes. Sema will reject. + NoButErrorRecovery, + /// The grammar allows a defining-type-specifier here, even though it's + /// always invalid. Sema will reject. + YesButInvalid, + /// The grammar allows a defining-type-specifier here, and one can be valid. + Yes + }; + + /// Is this a context in which we are parsing defining-type-specifiers (and + /// so permit class and enum definitions in addition to non-defining class and + /// enum elaborated-type-specifiers)? + static AllowDefiningTypeSpec + isDefiningTypeSpecifierContext(DeclSpecContext DSC) { + switch (DSC) { + case DeclSpecContext::DSC_normal: + case DeclSpecContext::DSC_class: + case DeclSpecContext::DSC_top_level: + case DeclSpecContext::DSC_alias_declaration: + case DeclSpecContext::DSC_objc_method_result: + return AllowDefiningTypeSpec::Yes; + + case DeclSpecContext::DSC_condition: + case DeclSpecContext::DSC_template_param: + return AllowDefiningTypeSpec::YesButInvalid; + + case DeclSpecContext::DSC_template_type_arg: + case DeclSpecContext::DSC_type_specifier: + return AllowDefiningTypeSpec::NoButErrorRecovery; + + case DeclSpecContext::DSC_trailing: + return AllowDefiningTypeSpec::No; + } + llvm_unreachable("Missing DeclSpecContext case"); + } + + /// Is this a context in which an opaque-enum-declaration can appear? + static bool isOpaqueEnumDeclarationContext(DeclSpecContext DSC) { + switch (DSC) { + case DeclSpecContext::DSC_normal: + case DeclSpecContext::DSC_class: + case DeclSpecContext::DSC_top_level: + return true; + + case DeclSpecContext::DSC_alias_declaration: + case DeclSpecContext::DSC_objc_method_result: + case DeclSpecContext::DSC_condition: + case DeclSpecContext::DSC_template_param: + case DeclSpecContext::DSC_template_type_arg: + case DeclSpecContext::DSC_type_specifier: + case DeclSpecContext::DSC_trailing: + return false; + } + llvm_unreachable("Missing DeclSpecContext case"); + } + /// Is this a context in which we can perform class template argument /// deduction? static bool isClassTemplateDeductionContext(DeclSpecContext DSC) { @@ -2225,7 +2352,7 @@ private: AccessSpecifier AS, DeclSpecContext DSC); void ParseEnumBody(SourceLocation StartLoc, Decl *TagDecl); void ParseStructUnionBody(SourceLocation StartLoc, DeclSpec::TST TagType, - Decl *TagDecl); + RecordDecl *TagDecl); void ParseStructDeclaration( ParsingDeclSpec &DS, @@ -2362,17 +2489,14 @@ private: True, False, Ambiguous, Error }; - /// Based only on the given token kind, determine whether we know that - /// we're at the start of an expression or a type-specifier-seq (which may - /// be an expression, in C++). + /// Determine whether we could have an enum-base. /// - /// This routine does not attempt to resolve any of the trick cases, e.g., - /// those involving lookup of identifiers. + /// \p AllowSemi If \c true, then allow a ';' after the enum-base; otherwise + /// only consider this to be an enum-base if the next token is a '{'. /// - /// \returns \c TPR_true if this token starts an expression, \c TPR_false if - /// this token starts a type-specifier-seq, or \c TPR_ambiguous if it cannot - /// tell. - TPResult isExpressionOrTypeSpecifierSimple(tok::TokenKind Kind); + /// \return \c false if this cannot possibly be an enum base; \c true + /// otherwise. + bool isEnumBase(bool AllowSemi); /// isCXXDeclarationSpecifier - Returns TPResult::True if it is a /// declaration specifier, TPResult::False if it is not, @@ -2395,6 +2519,11 @@ private: /// rather than a less-than expression. TPResult isTemplateArgumentList(unsigned TokensToSkip); + /// Determine whether an '(' after an 'explicit' keyword is part of a C++20 + /// 'explicit(bool)' declaration, in earlier language modes where that is an + /// extension. + TPResult isExplicitBool(); + /// Determine whether an identifier has been tentatively declared as a /// non-type. Such tentative declarations should not be found to name a type /// during a tentative parse, but also should not be annotated as a non-type. @@ -2422,6 +2551,10 @@ private: TPResult TryParseBracketDeclarator(); TPResult TryConsumeDeclarationSpecifier(); + /// Try to skip a possibly empty sequence of 'attribute-specifier's without + /// full validation of the syntactic structure of attributes. + bool TrySkipAttributes(); + public: TypeResult ParseTypeName(SourceRange *Range = nullptr, DeclaratorContext Context @@ -2548,13 +2681,15 @@ private: D.takeAttributes(attrs, endLoc); } } - void MaybeParseCXX11Attributes(ParsedAttributes &attrs, + bool MaybeParseCXX11Attributes(ParsedAttributes &attrs, SourceLocation *endLoc = nullptr) { if (standardAttributesAllowed() && isCXX11AttributeSpecifier()) { ParsedAttributesWithRange attrsWithRange(AttrFactory); ParseCXX11Attributes(attrsWithRange, endLoc); attrs.takeAllFrom(attrsWithRange); + return true; } + return false; } void MaybeParseCXX11Attributes(ParsedAttributesWithRange &attrs, SourceLocation *endLoc = nullptr, @@ -2671,6 +2806,7 @@ private: SourceLocation &EllipsisLoc); void ParseAlignmentSpecifier(ParsedAttributes &Attrs, SourceLocation *endLoc = nullptr); + ExprResult ParseExtIntegerArgument(); VirtSpecifiers::Specifier isCXX11VirtSpecifier(const Token &Tok) const; VirtSpecifiers::Specifier isCXX11VirtSpecifier() const { @@ -2756,7 +2892,7 @@ private: Declarator &D, SmallVectorImpl<DeclaratorChunk::ParamInfo> &ParamInfo); void ParseParameterDeclarationClause( - Declarator &D, + DeclaratorContext DeclaratorContext, ParsedAttributes &attrs, SmallVectorImpl<DeclaratorChunk::ParamInfo> &ParamInfo, SourceLocation &EllipsisLoc); @@ -2884,11 +3020,12 @@ private: AccessSpecifier getAccessSpecifierIfPresent() const; bool ParseUnqualifiedIdTemplateId(CXXScopeSpec &SS, + ParsedType ObjectType, + bool ObjectHadErrors, SourceLocation TemplateKWLoc, IdentifierInfo *Name, SourceLocation NameLoc, bool EnteringContext, - ParsedType ObjectType, UnqualifiedId &Id, bool AssumeTemplateId); bool ParseUnqualifiedIdOperator(CXXScopeSpec &SS, bool EnteringContext, @@ -2901,20 +3038,69 @@ private: DeclGroupPtrTy ParseOMPDeclareSimdClauses(DeclGroupPtrTy Ptr, CachedTokens &Toks, SourceLocation Loc); - /// Parses OpenMP context selectors and calls \p Callback for each - /// successfully parsed context selector. - bool - parseOpenMPContextSelectors(SourceLocation Loc, - SmallVectorImpl<Sema::OMPCtxSelectorData> &Data); + + /// Parse a property kind into \p TIProperty for the selector set \p Set and + /// selector \p Selector. + void parseOMPTraitPropertyKind(OMPTraitProperty &TIProperty, + llvm::omp::TraitSet Set, + llvm::omp::TraitSelector Selector, + llvm::StringMap<SourceLocation> &Seen); + + /// Parse a selector kind into \p TISelector for the selector set \p Set. + void parseOMPTraitSelectorKind(OMPTraitSelector &TISelector, + llvm::omp::TraitSet Set, + llvm::StringMap<SourceLocation> &Seen); + + /// Parse a selector set kind into \p TISet. + void parseOMPTraitSetKind(OMPTraitSet &TISet, + llvm::StringMap<SourceLocation> &Seen); + + /// Parses an OpenMP context property. + void parseOMPContextProperty(OMPTraitSelector &TISelector, + llvm::omp::TraitSet Set, + llvm::StringMap<SourceLocation> &Seen); + + /// Parses an OpenMP context selector. + void parseOMPContextSelector(OMPTraitSelector &TISelector, + llvm::omp::TraitSet Set, + llvm::StringMap<SourceLocation> &SeenSelectors); + + /// Parses an OpenMP context selector set. + void parseOMPContextSelectorSet(OMPTraitSet &TISet, + llvm::StringMap<SourceLocation> &SeenSets); + + /// Parses OpenMP context selectors. + bool parseOMPContextSelectors(SourceLocation Loc, OMPTraitInfo &TI); + + /// Parse a `match` clause for an '#pragma omp declare variant'. Return true + /// if there was an error. + bool parseOMPDeclareVariantMatchClause(SourceLocation Loc, OMPTraitInfo &TI); /// Parse clauses for '#pragma omp declare variant'. void ParseOMPDeclareVariantClauses(DeclGroupPtrTy Ptr, CachedTokens &Toks, SourceLocation Loc); + /// Parse clauses for '#pragma omp declare target'. DeclGroupPtrTy ParseOMPDeclareTargetClauses(); /// Parse '#pragma omp end declare target'. void ParseOMPEndDeclareTargetDirective(OpenMPDirectiveKind DKind, SourceLocation Loc); + + /// Skip tokens until a `annot_pragma_openmp_end` was found. Emit a warning if + /// it is not the current token. + void skipUntilPragmaOpenMPEnd(OpenMPDirectiveKind DKind); + + /// Check the \p FoundKind against the \p ExpectedKind, if not issue an error + /// that the "end" matching the "begin" directive of kind \p BeginKind was not + /// found. Finally, if the expected kind was found or if \p SkipUntilOpenMPEnd + /// is set, skip ahead using the helper `skipUntilPragmaOpenMPEnd`. + void parseOMPEndDirective(OpenMPDirectiveKind BeginKind, + OpenMPDirectiveKind ExpectedKind, + OpenMPDirectiveKind FoundKind, + SourceLocation MatchingLoc, + SourceLocation FoundLoc, + bool SkipUntilOpenMPEnd); + /// Parses declarative OpenMP directives. DeclGroupPtrTy ParseOpenMPDeclarativeDirectiveWithExtDecl( AccessSpecifier &AS, ParsedAttributesWithRange &Attrs, @@ -2933,6 +3119,10 @@ private: DeclarationName &Name, AccessSpecifier AS = AS_none); + /// Tries to parse cast part of OpenMP array shaping operation: + /// '[' expression ']' { '[' expression ']' } ')'. + bool tryParseOpenMPArrayShapingCastPart(); + /// Parses simple list of variables. /// /// \param Kind Kind of the directive. @@ -2977,11 +3167,13 @@ private: /// Parses clause with a single expression and an additional argument /// of a kind \a Kind. /// + /// \param DKind Directive kind. /// \param Kind Kind of current clause. /// \param ParseOnly true to skip the clause's semantic actions and return /// nullptr. /// - OMPClause *ParseOpenMPSingleExprWithArgClause(OpenMPClauseKind Kind, + OMPClause *ParseOpenMPSingleExprWithArgClause(OpenMPDirectiveKind DKind, + OpenMPClauseKind Kind, bool ParseOnly); /// Parses clause without any additional arguments. /// @@ -2999,6 +3191,16 @@ private: OMPClause *ParseOpenMPVarListClause(OpenMPDirectiveKind DKind, OpenMPClauseKind Kind, bool ParseOnly); + /// Parses and creates OpenMP 5.0 iterators expression: + /// <iterators> = 'iterator' '(' { [ <iterator-type> ] identifier = + /// <range-specification> }+ ')' + ExprResult ParseOpenMPIteratorsExpr(); + + /// Parses allocators and traits in the context of the uses_allocator clause. + /// Expected format: + /// '(' { <allocator> [ '(' <allocator_traits> ')' ] }+ ')' + OMPClause *ParseOpenMPUsesAllocatorClause(OpenMPDirectiveKind DKind); + public: /// Parses simple expression in parens for single-expression clauses of OpenMP /// constructs. @@ -3008,32 +3210,31 @@ public: /// Data used for parsing list of variables in OpenMP clauses. struct OpenMPVarListDataTy { - Expr *TailExpr = nullptr; + Expr *DepModOrTailExpr = nullptr; SourceLocation ColonLoc; SourceLocation RLoc; CXXScopeSpec ReductionOrMapperIdScopeSpec; DeclarationNameInfo ReductionOrMapperId; int ExtraModifier = -1; ///< Additional modifier for linear, map, depend or ///< lastprivate clause. - SmallVector<OpenMPMapModifierKind, OMPMapClause::NumberOfModifiers> + SmallVector<OpenMPMapModifierKind, NumberOfOMPMapClauseModifiers> MapTypeModifiers; - SmallVector<SourceLocation, OMPMapClause::NumberOfModifiers> + SmallVector<SourceLocation, NumberOfOMPMapClauseModifiers> MapTypeModifiersLoc; bool IsMapTypeImplicit = false; - SourceLocation DepLinMapLastLoc; + SourceLocation ExtraModifierLoc; }; /// Parses clauses with list. bool ParseOpenMPVarList(OpenMPDirectiveKind DKind, OpenMPClauseKind Kind, SmallVectorImpl<Expr *> &Vars, OpenMPVarListDataTy &Data); - bool ParseUnqualifiedId(CXXScopeSpec &SS, bool EnteringContext, - bool AllowDestructorName, - bool AllowConstructorName, + bool ParseUnqualifiedId(CXXScopeSpec &SS, ParsedType ObjectType, + bool ObjectHadErrors, bool EnteringContext, + bool AllowDestructorName, bool AllowConstructorName, bool AllowDeductionGuide, - ParsedType ObjectType, - SourceLocation *TemplateKWLoc, - UnqualifiedId &Result); + SourceLocation *TemplateKWLoc, UnqualifiedId &Result); + /// Parses the mapper modifier in map, to, and from clauses. bool parseMapperModifier(OpenMPVarListDataTy &Data); /// Parses map-type-modifiers in map clause. @@ -3058,19 +3259,19 @@ private: DeclaratorContext Context, const ParsedTemplateInfo &TemplateInfo, ParsingDeclRAIIObject &DiagsFromParams, SourceLocation &DeclEnd, ParsedAttributes &AccessAttrs, AccessSpecifier AS = AS_none); - bool ParseTemplateParameters(unsigned Depth, + bool ParseTemplateParameters(MultiParseScope &TemplateScopes, unsigned Depth, SmallVectorImpl<NamedDecl *> &TemplateParams, SourceLocation &LAngleLoc, SourceLocation &RAngleLoc); bool ParseTemplateParameterList(unsigned Depth, SmallVectorImpl<NamedDecl*> &TemplateParams); - bool isStartOfTemplateTypeParameter(bool &ScopeError); + TPResult isStartOfTemplateTypeParameter(); NamedDecl *ParseTemplateParameter(unsigned Depth, unsigned Position); NamedDecl *ParseTypeParameter(unsigned Depth, unsigned Position); NamedDecl *ParseTemplateTemplateParameter(unsigned Depth, unsigned Position); NamedDecl *ParseNonTypeTemplateParameter(unsigned Depth, unsigned Position); bool isTypeConstraintAnnotation(); - bool TryAnnotateTypeConstraint(CXXScopeSpec &SS); + bool TryAnnotateTypeConstraint(); NamedDecl * ParseConstrainedTemplateTypeParameter(unsigned Depth, unsigned Position); void DiagnoseMisplacedEllipsis(SourceLocation EllipsisLoc, @@ -3082,7 +3283,8 @@ private: // C++ 14.3: Template arguments [temp.arg] typedef SmallVector<ParsedTemplateArgument, 16> TemplateArgList; - bool ParseGreaterThanInTemplateList(SourceLocation &RAngleLoc, + bool ParseGreaterThanInTemplateList(SourceLocation LAngleLoc, + SourceLocation &RAngleLoc, bool ConsumeLastToken, bool ObjCGenericList); bool ParseTemplateIdAfterTemplateName(bool ConsumeLastToken, @@ -3096,7 +3298,8 @@ private: UnqualifiedId &TemplateName, bool AllowTypeAnnotation = true, bool TypeConstraint = false); - void AnnotateTemplateIdTokenAsType(bool IsClassName = false); + void AnnotateTemplateIdTokenAsType(CXXScopeSpec &SS, + bool IsClassName = false); bool ParseTemplateArgumentList(TemplateArgList &TemplateArgs); ParsedTemplateArgument ParseTemplateTemplateArgument(); ParsedTemplateArgument ParseTemplateArgument(); @@ -3148,6 +3351,27 @@ private: unsigned ArgumentIndex) override; void CodeCompleteIncludedFile(llvm::StringRef Dir, bool IsAngled) override; void CodeCompleteNaturalLanguage() override; + + class GNUAsmQualifiers { + unsigned Qualifiers = AQ_unspecified; + + public: + enum AQ { + AQ_unspecified = 0, + AQ_volatile = 1, + AQ_inline = 2, + AQ_goto = 4, + }; + static const char *getQualifierName(AQ Qualifier); + bool setAsmQualifier(AQ Qualifier); + inline bool isVolatile() const { return Qualifiers & AQ_volatile; }; + inline bool isInline() const { return Qualifiers & AQ_inline; }; + inline bool isGoto() const { return Qualifiers & AQ_goto; } + }; + bool isGCCAsmStatement(const Token &TokAfterAsm) const; + bool isGNUAsmQualifier(const Token &TokAfterAsm) const; + GNUAsmQualifiers::AQ getGNUAsmQualifier(const Token &Tok) const; + bool parseGNUAsmQualifierListOpt(GNUAsmQualifiers &AQ); }; } // end namespace clang diff --git a/clang/include/clang/Parse/RAIIObjectsForParser.h b/clang/include/clang/Parse/RAIIObjectsForParser.h index fb092c050783..bc1754614ad9 100644 --- a/clang/include/clang/Parse/RAIIObjectsForParser.h +++ b/clang/include/clang/Parse/RAIIObjectsForParser.h @@ -294,9 +294,9 @@ namespace clang { bool OldVal; public: - ParsingOpenMPDirectiveRAII(Parser &P) + ParsingOpenMPDirectiveRAII(Parser &P, bool Value = true) : P(P), OldVal(P.OpenMPDirectiveParsing) { - P.OpenMPDirectiveParsing = true; + P.OpenMPDirectiveParsing = Value; } /// This can be used to restore the state early, before the dtor @@ -459,26 +459,6 @@ namespace clang { } void skipToEnd(); }; - - /// RAIIObject to destroy the contents of a SmallVector of - /// TemplateIdAnnotation pointers and clear the vector. - class DestroyTemplateIdAnnotationsRAIIObj { - SmallVectorImpl<TemplateIdAnnotation *> &Container; - - public: - DestroyTemplateIdAnnotationsRAIIObj( - SmallVectorImpl<TemplateIdAnnotation *> &Container) - : Container(Container) {} - - ~DestroyTemplateIdAnnotationsRAIIObj() { - for (SmallVectorImpl<TemplateIdAnnotation *>::iterator I = - Container.begin(), - E = Container.end(); - I != E; ++I) - (*I)->Destroy(); - Container.clear(); - } - }; } // end namespace clang #endif diff --git a/clang/include/clang/Sema/DeclSpec.h b/clang/include/clang/Sema/DeclSpec.h index aceec9cbe1c9..8db03babfb1e 100644 --- a/clang/include/clang/Sema/DeclSpec.h +++ b/clang/include/clang/Sema/DeclSpec.h @@ -23,6 +23,7 @@ #define LLVM_CLANG_SEMA_DECLSPEC_H #include "clang/AST/DeclCXX.h" +#include "clang/AST/DeclObjCCommon.h" #include "clang/AST/NestedNameSpecifier.h" #include "clang/Basic/ExceptionSpecificationType.h" #include "clang/Basic/Lambda.h" @@ -186,14 +187,14 @@ public: SourceLocation getLastQualifierNameLoc() const; /// No scope specifier. - bool isEmpty() const { return !Range.isValid(); } + bool isEmpty() const { return Range.isInvalid() && getScopeRep() == nullptr; } /// A scope specifier is present, but may be valid or invalid. bool isNotEmpty() const { return !isEmpty(); } /// An error occurred during parsing of the scope specifier. - bool isInvalid() const { return isNotEmpty() && getScopeRep() == nullptr; } + bool isInvalid() const { return Range.isValid() && getScopeRep() == nullptr; } /// A scope specifier is present, and it refers to a real scope. - bool isValid() const { return isNotEmpty() && getScopeRep() != nullptr; } + bool isValid() const { return getScopeRep() != nullptr; } /// Indicate that this nested-name-specifier is invalid. void SetInvalid(SourceRange R) { @@ -278,7 +279,9 @@ public: static const TST TST_char32 = clang::TST_char32; static const TST TST_int = clang::TST_int; static const TST TST_int128 = clang::TST_int128; + static const TST TST_extint = clang::TST_extint; static const TST TST_half = clang::TST_half; + static const TST TST_BFloat16 = clang::TST_BFloat16; static const TST TST_float = clang::TST_float; static const TST TST_double = clang::TST_double; static const TST TST_float16 = clang::TST_Float16; @@ -349,6 +352,7 @@ private: unsigned TypeSpecOwned : 1; unsigned TypeSpecPipe : 1; unsigned TypeSpecSat : 1; + unsigned ConstrainedAuto : 1; // type-qualifiers unsigned TypeQualifiers : 5; // Bitwise OR of TQ. @@ -369,6 +373,7 @@ private: UnionParsedType TypeRep; Decl *DeclRep; Expr *ExprRep; + TemplateIdAnnotation *TemplateIdRep; }; /// ExplicitSpecifier - Store information about explicit spicifer. @@ -411,7 +416,10 @@ private: T == TST_underlyingType || T == TST_atomic); } static bool isExprRep(TST T) { - return (T == TST_typeofExpr || T == TST_decltype); + return (T == TST_typeofExpr || T == TST_decltype || T == TST_extint); + } + static bool isTemplateIdRep(TST T) { + return (T == TST_auto || T == TST_decltype_auto); } DeclSpec(const DeclSpec &) = delete; @@ -430,7 +438,8 @@ public: TypeSpecComplex(TSC_unspecified), TypeSpecSign(TSS_unspecified), TypeSpecType(TST_unspecified), TypeAltiVecVector(false), TypeAltiVecPixel(false), TypeAltiVecBool(false), TypeSpecOwned(false), - TypeSpecPipe(false), TypeSpecSat(false), TypeQualifiers(TQ_unspecified), + TypeSpecPipe(false), TypeSpecSat(false), ConstrainedAuto(false), + TypeQualifiers(TQ_unspecified), FS_inline_specified(false), FS_forceinline_specified(false), FS_virtual_specified(false), FS_noreturn_specified(false), Friend_specified(false), ConstexprSpecifier(CSK_unspecified), @@ -478,6 +487,7 @@ public: bool isTypeRep() const { return isTypeRep((TST) TypeSpecType); } bool isTypeSpecPipe() const { return TypeSpecPipe; } bool isTypeSpecSat() const { return TypeSpecSat; } + bool isConstrainedAuto() const { return ConstrainedAuto; } ParsedType getRepAsType() const { assert(isTypeRep((TST) TypeSpecType) && "DeclSpec does not store a type"); @@ -491,6 +501,11 @@ public: assert(isExprRep((TST) TypeSpecType) && "DeclSpec does not store an expr"); return ExprRep; } + TemplateIdAnnotation *getRepAsTemplateId() const { + assert(isTemplateIdRep((TST) TypeSpecType) && + "DeclSpec does not store a template id"); + return TemplateIdRep; + } CXXScopeSpec &getTypeSpecScope() { return TypeScope; } const CXXScopeSpec &getTypeSpecScope() const { return TypeScope; } @@ -656,6 +671,13 @@ public: unsigned &DiagID, ParsedType Rep, const PrintingPolicy &Policy); bool SetTypeSpecType(TST T, SourceLocation Loc, const char *&PrevSpec, + unsigned &DiagID, TypeResult Rep, + const PrintingPolicy &Policy) { + if (Rep.isInvalid()) + return SetTypeSpecError(); + return SetTypeSpecType(T, Loc, PrevSpec, DiagID, Rep.get(), Policy); + } + bool SetTypeSpecType(TST T, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, Decl *Rep, bool Owned, const PrintingPolicy &Policy); bool SetTypeSpecType(TST T, SourceLocation TagKwLoc, @@ -666,6 +688,9 @@ public: SourceLocation TagNameLoc, const char *&PrevSpec, unsigned &DiagID, Decl *Rep, bool Owned, const PrintingPolicy &Policy); + bool SetTypeSpecType(TST T, SourceLocation Loc, const char *&PrevSpec, + unsigned &DiagID, TemplateIdAnnotation *Rep, + const PrintingPolicy &Policy); bool SetTypeSpecType(TST T, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, Expr *Rep, @@ -682,6 +707,9 @@ public: bool SetTypePipe(bool isPipe, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy); + bool SetExtIntType(SourceLocation KWLoc, Expr *BitWidth, + const char *&PrevSpec, unsigned &DiagID, + const PrintingPolicy &Policy); bool SetTypeSpecSat(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID); bool SetTypeSpecError(); @@ -815,31 +843,10 @@ public: DQ_CSNullability = 0x40 }; - /// PropertyAttributeKind - list of property attributes. - /// Keep this list in sync with LLVM's Dwarf.h ApplePropertyAttributes. - enum ObjCPropertyAttributeKind { - DQ_PR_noattr = 0x0, - DQ_PR_readonly = 0x01, - DQ_PR_getter = 0x02, - DQ_PR_assign = 0x04, - DQ_PR_readwrite = 0x08, - DQ_PR_retain = 0x10, - DQ_PR_copy = 0x20, - DQ_PR_nonatomic = 0x40, - DQ_PR_setter = 0x80, - DQ_PR_atomic = 0x100, - DQ_PR_weak = 0x200, - DQ_PR_strong = 0x400, - DQ_PR_unsafe_unretained = 0x800, - DQ_PR_nullability = 0x1000, - DQ_PR_null_resettable = 0x2000, - DQ_PR_class = 0x4000, - DQ_PR_direct = 0x8000, - }; - ObjCDeclSpec() - : objcDeclQualifier(DQ_None), PropertyAttributes(DQ_PR_noattr), - Nullability(0), GetterName(nullptr), SetterName(nullptr) { } + : objcDeclQualifier(DQ_None), + PropertyAttributes(ObjCPropertyAttribute::kind_noattr), Nullability(0), + GetterName(nullptr), SetterName(nullptr) {} ObjCDeclQualifier getObjCDeclQualifier() const { return (ObjCDeclQualifier)objcDeclQualifier; @@ -851,32 +858,35 @@ public: objcDeclQualifier = (ObjCDeclQualifier) (objcDeclQualifier & ~DQVal); } - ObjCPropertyAttributeKind getPropertyAttributes() const { - return ObjCPropertyAttributeKind(PropertyAttributes); + ObjCPropertyAttribute::Kind getPropertyAttributes() const { + return ObjCPropertyAttribute::Kind(PropertyAttributes); } - void setPropertyAttributes(ObjCPropertyAttributeKind PRVal) { + void setPropertyAttributes(ObjCPropertyAttribute::Kind PRVal) { PropertyAttributes = - (ObjCPropertyAttributeKind)(PropertyAttributes | PRVal); + (ObjCPropertyAttribute::Kind)(PropertyAttributes | PRVal); } NullabilityKind getNullability() const { - assert(((getObjCDeclQualifier() & DQ_CSNullability) || - (getPropertyAttributes() & DQ_PR_nullability)) && - "Objective-C declspec doesn't have nullability"); + assert( + ((getObjCDeclQualifier() & DQ_CSNullability) || + (getPropertyAttributes() & ObjCPropertyAttribute::kind_nullability)) && + "Objective-C declspec doesn't have nullability"); return static_cast<NullabilityKind>(Nullability); } SourceLocation getNullabilityLoc() const { - assert(((getObjCDeclQualifier() & DQ_CSNullability) || - (getPropertyAttributes() & DQ_PR_nullability)) && - "Objective-C declspec doesn't have nullability"); + assert( + ((getObjCDeclQualifier() & DQ_CSNullability) || + (getPropertyAttributes() & ObjCPropertyAttribute::kind_nullability)) && + "Objective-C declspec doesn't have nullability"); return NullabilityLoc; } void setNullability(SourceLocation loc, NullabilityKind kind) { - assert(((getObjCDeclQualifier() & DQ_CSNullability) || - (getPropertyAttributes() & DQ_PR_nullability)) && - "Set the nullability declspec or property attribute first"); + assert( + ((getObjCDeclQualifier() & DQ_CSNullability) || + (getPropertyAttributes() & ObjCPropertyAttribute::kind_nullability)) && + "Set the nullability declspec or property attribute first"); Nullability = static_cast<unsigned>(kind); NullabilityLoc = loc; } @@ -903,8 +913,8 @@ private: // (space saving is negligible). unsigned objcDeclQualifier : 7; - // NOTE: VC++ treats enums as signed, avoid using ObjCPropertyAttributeKind - unsigned PropertyAttributes : 16; + // NOTE: VC++ treats enums as signed, avoid using ObjCPropertyAttribute::Kind + unsigned PropertyAttributes : NumObjCPropertyAttrsBits; unsigned Nullability : 2; @@ -1503,6 +1513,8 @@ struct DeclaratorChunk { struct MemberPointerTypeInfo { /// The type qualifiers: const/volatile/restrict/__unaligned/_Atomic. unsigned TypeQuals : 5; + /// Location of the '*' token. + unsigned StarLoc; // CXXScopeSpec has a constructor, so it can't be a direct member. // So we need some pointer-aligned storage and a bit of trickery. alignas(CXXScopeSpec) char ScopeMem[sizeof(CXXScopeSpec)]; @@ -1645,11 +1657,13 @@ struct DeclaratorChunk { static DeclaratorChunk getMemberPointer(const CXXScopeSpec &SS, unsigned TypeQuals, - SourceLocation Loc) { + SourceLocation StarLoc, + SourceLocation EndLoc) { DeclaratorChunk I; I.Kind = MemberPointer; I.Loc = SS.getBeginLoc(); - I.EndLoc = Loc; + I.EndLoc = EndLoc; + I.Mem.StarLoc = StarLoc.getRawEncoding(); I.Mem.TypeQuals = TypeQuals; new (I.Mem.ScopeMem) CXXScopeSpec(SS); return I; @@ -1757,7 +1771,8 @@ enum class DeclaratorContext { TemplateArgContext, // Any template argument (in template argument list). TemplateTypeArgContext, // Template type argument (in default argument). AliasDeclContext, // C++11 alias-declaration. - AliasTemplateContext // C++11 alias-declaration template. + AliasTemplateContext, // C++11 alias-declaration template. + RequiresExprContext // C++2a requires-expression. }; @@ -1830,6 +1845,14 @@ private: /// requires-clause, or null if no such clause was specified. Expr *TrailingRequiresClause; + /// If this declarator declares a template, its template parameter lists. + ArrayRef<TemplateParameterList *> TemplateParameterLists; + + /// If the declarator declares an abbreviated function template, the innermost + /// template parameter list containing the invented and explicit template + /// parameters (if any). + TemplateParameterList *InventedTemplateParameterList; + #ifndef _MSC_VER union { #endif @@ -1860,7 +1883,8 @@ public: Redeclaration(false), Extension(false), ObjCIvar(false), ObjCWeakProperty(false), InlineStorageUsed(false), Attrs(ds.getAttributePool().getFactory()), AsmLabel(nullptr), - TrailingRequiresClause(nullptr) {} + TrailingRequiresClause(nullptr), + InventedTemplateParameterList(nullptr) {} ~Declarator() { clear(); @@ -1981,6 +2005,7 @@ public: case DeclaratorContext::TemplateTypeArgContext: case DeclaratorContext::TrailingReturnContext: case DeclaratorContext::TrailingReturnVarContext: + case DeclaratorContext::RequiresExprContext: return true; } llvm_unreachable("unknown context kind!"); @@ -2003,6 +2028,7 @@ public: case DeclaratorContext::TemplateParamContext: case DeclaratorContext::CXXCatchContext: case DeclaratorContext::ObjCCatchContext: + case DeclaratorContext::RequiresExprContext: return true; case DeclaratorContext::TypeNameContext: @@ -2039,6 +2065,7 @@ public: case DeclaratorContext::MemberContext: case DeclaratorContext::PrototypeContext: case DeclaratorContext::TemplateParamContext: + case DeclaratorContext::RequiresExprContext: // Maybe one day... return false; @@ -2116,6 +2143,7 @@ public: case DeclaratorContext::TemplateArgContext: case DeclaratorContext::TemplateTypeArgContext: case DeclaratorContext::TrailingReturnContext: + case DeclaratorContext::RequiresExprContext: return false; } llvm_unreachable("unknown context kind!"); @@ -2337,6 +2365,7 @@ public: case DeclaratorContext::TemplateTypeArgContext: case DeclaratorContext::TrailingReturnContext: case DeclaratorContext::TrailingReturnVarContext: + case DeclaratorContext::RequiresExprContext: return false; } llvm_unreachable("unknown context kind!"); @@ -2370,6 +2399,7 @@ public: case DeclaratorContext::TrailingReturnContext: case DeclaratorContext::TrailingReturnVarContext: case DeclaratorContext::TemplateTypeArgContext: + case DeclaratorContext::RequiresExprContext: return false; case DeclaratorContext::BlockContext: @@ -2422,6 +2452,30 @@ public: return TrailingRequiresClause != nullptr; } + /// Sets the template parameter lists that preceded the declarator. + void setTemplateParameterLists(ArrayRef<TemplateParameterList *> TPLs) { + TemplateParameterLists = TPLs; + } + + /// The template parameter lists that preceded the declarator. + ArrayRef<TemplateParameterList *> getTemplateParameterLists() const { + return TemplateParameterLists; + } + + /// Sets the template parameter list generated from the explicit template + /// parameters along with any invented template parameters from + /// placeholder-typed parameters. + void setInventedTemplateParameterList(TemplateParameterList *Invented) { + InventedTemplateParameterList = Invented; + } + + /// The template parameter list generated from the explicit template + /// parameters along with any invented template parameters from + /// placeholder-typed parameters, if there were any such parameters. + TemplateParameterList * getInventedTemplateParameterList() const { + return InventedTemplateParameterList; + } + /// takeAttributes - Takes attributes from the given parsed-attributes /// set and add them to this declarator. /// @@ -2622,6 +2676,26 @@ struct LambdaIntroducer { } }; +struct InventedTemplateParameterInfo { + /// The number of parameters in the template parameter list that were + /// explicitly specified by the user, as opposed to being invented by use + /// of an auto parameter. + unsigned NumExplicitTemplateParams = 0; + + /// If this is a generic lambda or abbreviated function template, use this + /// as the depth of each 'auto' parameter, during initial AST construction. + unsigned AutoTemplateParameterDepth = 0; + + /// Store the list of the template parameters for a generic lambda or an + /// abbreviated function template. + /// If this is a generic lambda or abbreviated function template, this holds + /// the explicit template parameters followed by the auto parameters + /// converted into TemplateTypeParmDecls. + /// It can be used to construct the generic lambda or abbreviated template's + /// template parameter list during initial AST construction. + SmallVector<NamedDecl*, 4> TemplateParams; +}; + } // end namespace clang #endif // LLVM_CLANG_SEMA_DECLSPEC_H diff --git a/clang/include/clang/Sema/ExternalSemaSource.h b/clang/include/clang/Sema/ExternalSemaSource.h index c79ca0e71df5..2854b4893484 100644 --- a/clang/include/clang/Sema/ExternalSemaSource.h +++ b/clang/include/clang/Sema/ExternalSemaSource.h @@ -193,6 +193,15 @@ public: llvm::MapVector<const FunctionDecl *, std::unique_ptr<LateParsedTemplate>> &LPTMap) {} + /// Read the set of decls to be checked for deferred diags. + /// + /// The external source should append its own potentially emitted function + /// and variable decls which may cause deferred diags. Note that this routine + /// may be invoked multiple times; the external source should take care not to + /// introduce the same declarations repeatedly. + virtual void ReadDeclsToCheckForDeferredDiags( + llvm::SmallVector<Decl *, 4> &Decls) {} + /// \copydoc Sema::CorrectTypo /// \note LookupKind must correspond to a valid Sema::LookupNameKind /// diff --git a/clang/include/clang/Sema/Initialization.h b/clang/include/clang/Sema/Initialization.h index f726f3836307..ca9e0a198cb9 100644 --- a/clang/include/clang/Sema/Initialization.h +++ b/clang/include/clang/Sema/Initialization.h @@ -689,6 +689,9 @@ public: return Context >= IC_StaticCast; } + /// Determine whether this initialization is a static cast. + bool isStaticCast() const { return Context == IC_StaticCast; } + /// Determine whether this initialization is a C-style cast. bool isCStyleOrFunctionalCast() const { return Context >= IC_CStyleCast; @@ -999,6 +1002,9 @@ public: /// Non-const lvalue reference binding to a vector element. FK_NonConstLValueReferenceBindingToVectorElement, + /// Non-const lvalue reference binding to a matrix element. + FK_NonConstLValueReferenceBindingToMatrixElement, + /// Non-const lvalue reference binding to an lvalue of unrelated /// type. FK_NonConstLValueReferenceBindingToUnrelated, diff --git a/clang/include/clang/Sema/Lookup.h b/clang/include/clang/Sema/Lookup.h index 0466d06d753b..c6edc2df5b9f 100644 --- a/clang/include/clang/Sema/Lookup.h +++ b/clang/include/clang/Sema/Lookup.h @@ -348,7 +348,7 @@ public: /// program. static bool isVisible(Sema &SemaRef, NamedDecl *D) { // If this declaration is not hidden, it's visible. - if (!D->isHidden()) + if (D->isUnconditionallyVisible()) return true; // During template instantiation, we can refer to hidden declarations, if diff --git a/clang/include/clang/Sema/MultiplexExternalSemaSource.h b/clang/include/clang/Sema/MultiplexExternalSemaSource.h index dcbac9f0ba10..e94dd5d46871 100644 --- a/clang/include/clang/Sema/MultiplexExternalSemaSource.h +++ b/clang/include/clang/Sema/MultiplexExternalSemaSource.h @@ -332,6 +332,15 @@ public: llvm::MapVector<const FunctionDecl *, std::unique_ptr<LateParsedTemplate>> &LPTMap) override; + /// Read the set of decls to be checked for deferred diags. + /// + /// The external source should append its own potentially emitted function + /// and variable decls which may cause deferred diags. Note that this routine + /// may be invoked multiple times; the external source should take care not to + /// introduce the same declarations repeatedly. + void ReadDeclsToCheckForDeferredDiags( + llvm::SmallVector<Decl *, 4> &Decls) override; + /// \copydoc ExternalSemaSource::CorrectTypo /// \note Returns the first nonempty correction. TypoCorrection CorrectTypo(const DeclarationNameInfo &Typo, diff --git a/clang/include/clang/Sema/Overload.h b/clang/include/clang/Sema/Overload.h index 1394c6236965..5023525aa41b 100644 --- a/clang/include/clang/Sema/Overload.h +++ b/clang/include/clang/Sema/Overload.h @@ -677,6 +677,24 @@ class Sema; StdInitializerListElement = V; } + /// Form an "implicit" conversion sequence from nullptr_t to bool, for a + /// direct-initialization of a bool object from nullptr_t. + static ImplicitConversionSequence getNullptrToBool(QualType SourceType, + QualType DestType, + bool NeedLValToRVal) { + ImplicitConversionSequence ICS; + ICS.setStandard(); + ICS.Standard.setAsIdentityConversion(); + ICS.Standard.setFromType(SourceType); + if (NeedLValToRVal) + ICS.Standard.First = ICK_Lvalue_To_Rvalue; + ICS.Standard.setToType(0, SourceType); + ICS.Standard.Second = ICK_Boolean_Conversion; + ICS.Standard.setToType(1, DestType); + ICS.Standard.setToType(2, DestType); + return ICS; + } + // The result of a comparison between implicit conversion // sequences. Use Sema::CompareImplicitConversionSequences to // actually perform the comparison. @@ -850,6 +868,8 @@ class Sema; return static_cast<OverloadCandidateRewriteKind>(RewriteKind); } + bool isReversed() const { return getRewriteKind() & CRK_Reversed; } + /// hasAmbiguousConversion - Returns whether this overload /// candidate requires an ambiguous conversion or not. bool hasAmbiguousConversion() const { @@ -888,7 +908,7 @@ class Sema; private: friend class OverloadCandidateSet; OverloadCandidate() - : IsADLCandidate(CallExpr::NotADL), RewriteKind(CRK_None) {} + : IsSurrogate(false), IsADLCandidate(CallExpr::NotADL), RewriteKind(CRK_None) {} }; /// OverloadCandidateSet - A set of overload candidates, used in C++ @@ -963,6 +983,14 @@ class Sema; return CRK; } + /// Determines whether this operator could be implemented by a function + /// with reversed parameter order. + bool isReversible() { + return AllowRewrittenCandidates && OriginalOperator && + (getRewrittenOverloadedOperator(OriginalOperator) != OO_None || + shouldAddReversed(OriginalOperator)); + } + /// Determine whether we should consider looking for and adding reversed /// candidates for operator Op. bool shouldAddReversed(OverloadedOperatorKind Op); diff --git a/clang/include/clang/Sema/Ownership.h b/clang/include/clang/Sema/Ownership.h index f395282c0c52..7c7b1d35c9fd 100644 --- a/clang/include/clang/Sema/Ownership.h +++ b/clang/include/clang/Sema/Ownership.h @@ -116,7 +116,7 @@ namespace llvm { template <class T> struct PointerLikeTypeTraits<clang::OpaquePtr<T>> { - enum { NumLowBitsAvailable = 0 }; + static constexpr int NumLowBitsAvailable = 0; static inline void *getAsVoidPointer(clang::OpaquePtr<T> P) { // FIXME: Doesn't work? return P.getAs< void >(); @@ -278,6 +278,7 @@ namespace clang { inline ExprResult ExprError() { return ExprResult(true); } inline StmtResult StmtError() { return StmtResult(true); } + inline TypeResult TypeError() { return TypeResult(true); } inline ExprResult ExprError(const DiagnosticBuilder&) { return ExprError(); } inline StmtResult StmtError(const DiagnosticBuilder&) { return StmtError(); } diff --git a/clang/include/clang/Sema/ParsedAttr.h b/clang/include/clang/Sema/ParsedAttr.h index d9d8585970d9..21e030fe5134 100644 --- a/clang/include/clang/Sema/ParsedAttr.h +++ b/clang/include/clang/Sema/ParsedAttr.h @@ -18,12 +18,12 @@ #include "clang/Basic/AttributeCommonInfo.h" #include "clang/Basic/Diagnostic.h" #include "clang/Basic/SourceLocation.h" -#include "clang/Basic/TargetInfo.h" #include "clang/Sema/Ownership.h" #include "llvm/ADT/PointerUnion.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/TinyPtrVector.h" #include "llvm/Support/Allocator.h" +#include "llvm/Support/Registry.h" #include "llvm/Support/VersionTuple.h" #include <cassert> #include <cstddef> @@ -37,6 +37,85 @@ class Decl; class Expr; class IdentifierInfo; class LangOptions; +class ParsedAttr; +class Sema; +class TargetInfo; + +struct ParsedAttrInfo { + /// Corresponds to the Kind enum. + unsigned AttrKind : 16; + /// The number of required arguments of this attribute. + unsigned NumArgs : 4; + /// The number of optional arguments of this attributes. + unsigned OptArgs : 4; + /// True if the parsing does not match the semantic content. + unsigned HasCustomParsing : 1; + /// True if this attribute is only available for certain targets. + unsigned IsTargetSpecific : 1; + /// True if this attribute applies to types. + unsigned IsType : 1; + /// True if this attribute applies to statements. + unsigned IsStmt : 1; + /// True if this attribute has any spellings that are known to gcc. + unsigned IsKnownToGCC : 1; + /// True if this attribute is supported by #pragma clang attribute. + unsigned IsSupportedByPragmaAttribute : 1; + /// The syntaxes supported by this attribute and how they're spelled. + struct Spelling { + AttributeCommonInfo::Syntax Syntax; + const char *NormalizedFullName; + }; + ArrayRef<Spelling> Spellings; + + ParsedAttrInfo(AttributeCommonInfo::Kind AttrKind = + AttributeCommonInfo::NoSemaHandlerAttribute) + : AttrKind(AttrKind), NumArgs(0), OptArgs(0), HasCustomParsing(0), + IsTargetSpecific(0), IsType(0), IsStmt(0), IsKnownToGCC(0), + IsSupportedByPragmaAttribute(0) {} + + virtual ~ParsedAttrInfo() = default; + + /// Check if this attribute appertains to D, and issue a diagnostic if not. + virtual bool diagAppertainsToDecl(Sema &S, const ParsedAttr &Attr, + const Decl *D) const { + return true; + } + /// Check if this attribute is allowed by the language we are compiling, and + /// issue a diagnostic if not. + virtual bool diagLangOpts(Sema &S, const ParsedAttr &Attr) const { + return true; + } + /// Check if this attribute is allowed when compiling for the given target. + virtual bool existsInTarget(const TargetInfo &Target) const { + return true; + } + /// Convert the spelling index of Attr to a semantic spelling enum value. + virtual unsigned + spellingIndexToSemanticSpelling(const ParsedAttr &Attr) const { + return UINT_MAX; + } + /// Populate Rules with the match rules of this attribute. + virtual void getPragmaAttributeMatchRules( + llvm::SmallVectorImpl<std::pair<attr::SubjectMatchRule, bool>> &Rules, + const LangOptions &LangOpts) const { + } + enum AttrHandling { + NotHandled, + AttributeApplied, + AttributeNotApplied + }; + /// If this ParsedAttrInfo knows how to handle this ParsedAttr applied to this + /// Decl then do so and return either AttributeApplied if it was applied or + /// AttributeNotApplied if it wasn't. Otherwise return NotHandled. + virtual AttrHandling handleDeclAttribute(Sema &S, Decl *D, + const ParsedAttr &Attr) const { + return NotHandled; + } + + static const ParsedAttrInfo &get(const AttributeCommonInfo &A); +}; + +typedef llvm::Registry<ParsedAttrInfo> ParsedAttrInfoRegistry; /// Represents information about a change in availability for /// an entity, which is part of the encoding of the 'availability' @@ -181,6 +260,8 @@ private: const Expr *MessageExpr; + const ParsedAttrInfo &Info; + ArgsUnion *getArgsBuffer() { return getTrailingObjects<ArgsUnion>(); } ArgsUnion const *getArgsBuffer() const { return getTrailingObjects<ArgsUnion>(); @@ -207,7 +288,8 @@ private: EllipsisLoc(ellipsisLoc), NumArgs(numArgs), Invalid(false), UsedAsTypeAttr(false), IsAvailability(false), IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(false), - HasProcessingCache(false), IsPragmaClangAttribute(false) { + HasProcessingCache(false), IsPragmaClangAttribute(false), + Info(ParsedAttrInfo::get(*this)) { if (numArgs) memcpy(getArgsBuffer(), args, numArgs * sizeof(ArgsUnion)); } @@ -225,7 +307,8 @@ private: NumArgs(1), Invalid(false), UsedAsTypeAttr(false), IsAvailability(true), IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(false), HasProcessingCache(false), IsPragmaClangAttribute(false), - UnavailableLoc(unavailable), MessageExpr(messageExpr) { + UnavailableLoc(unavailable), MessageExpr(messageExpr), + Info(ParsedAttrInfo::get(*this)) { ArgsUnion PVal(Parm); memcpy(getArgsBuffer(), &PVal, sizeof(ArgsUnion)); new (getAvailabilityData()) detail::AvailabilityData( @@ -242,7 +325,7 @@ private: NumArgs(3), Invalid(false), UsedAsTypeAttr(false), IsAvailability(false), IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(false), HasProcessingCache(false), - IsPragmaClangAttribute(false) { + IsPragmaClangAttribute(false), Info(ParsedAttrInfo::get(*this)) { ArgsUnion *Args = getArgsBuffer(); Args[0] = Parm1; Args[1] = Parm2; @@ -259,7 +342,7 @@ private: NumArgs(1), Invalid(false), UsedAsTypeAttr(false), IsAvailability(false), IsTypeTagForDatatype(true), IsProperty(false), HasParsedType(false), HasProcessingCache(false), - IsPragmaClangAttribute(false) { + IsPragmaClangAttribute(false), Info(ParsedAttrInfo::get(*this)) { ArgsUnion PVal(ArgKind); memcpy(getArgsBuffer(), &PVal, sizeof(ArgsUnion)); detail::TypeTagForDatatypeData &ExtraData = getTypeTagForDatatypeDataSlot(); @@ -277,7 +360,7 @@ private: NumArgs(0), Invalid(false), UsedAsTypeAttr(false), IsAvailability(false), IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(true), HasProcessingCache(false), - IsPragmaClangAttribute(false) { + IsPragmaClangAttribute(false), Info(ParsedAttrInfo::get(*this)) { new (&getTypeBuffer()) ParsedType(typeArg); } @@ -291,7 +374,7 @@ private: NumArgs(0), Invalid(false), UsedAsTypeAttr(false), IsAvailability(false), IsTypeTagForDatatype(false), IsProperty(true), HasParsedType(false), HasProcessingCache(false), - IsPragmaClangAttribute(false) { + IsPragmaClangAttribute(false), Info(ParsedAttrInfo::get(*this)) { new (&getPropertyDataBuffer()) detail::PropertyData(getterId, setterId); } @@ -534,7 +617,10 @@ public: } } - AttributeCommonInfo::Kind getKind() const { return getParsedKind(); } + AttributeCommonInfo::Kind getKind() const { + return AttributeCommonInfo::Kind(Info.AttrKind); + } + const ParsedAttrInfo &getInfo() const { return Info; } }; class AttributePool; diff --git a/clang/include/clang/Sema/ParsedTemplate.h b/clang/include/clang/Sema/ParsedTemplate.h index 0874905b38a5..f0245b93c7eb 100644 --- a/clang/include/clang/Sema/ParsedTemplate.h +++ b/clang/include/clang/Sema/ParsedTemplate.h @@ -139,9 +139,8 @@ namespace clang { /// Information about a template-id annotation /// token. /// - /// A template-id annotation token contains the template declaration, - /// template arguments, whether those template arguments were types, - /// expressions, or template names, and the source locations for important + /// A template-id annotation token contains the template name, + /// template arguments, and the source locations for important /// tokens. All of the information about template arguments is allocated /// directly after this structure. /// A template-id annotation token can also be generated by a type-constraint @@ -152,9 +151,6 @@ namespace clang { : private llvm::TrailingObjects<TemplateIdAnnotation, ParsedTemplateArgument> { friend TrailingObjects; - /// The nested-name-specifier that precedes the template name. - CXXScopeSpec SS; - /// TemplateKWLoc - The location of the template keyword. /// For e.g. typename T::template Y<U> SourceLocation TemplateKWLoc; @@ -173,7 +169,9 @@ namespace clang { /// template-name. ParsedTemplateTy Template; - /// The kind of template that Template refers to. + /// The kind of template that Template refers to. If this is + /// TNK_Non_template, an error was encountered and diagnosed + /// when parsing or looking up the template name. TemplateNameKind Kind; /// The location of the '<' before the template argument @@ -187,6 +185,10 @@ namespace clang { /// NumArgs - The number of template arguments. unsigned NumArgs; + /// Whether an error was encountered in the template arguments. + /// If so, NumArgs and the trailing arguments are best-effort. + bool ArgsInvalid; + /// Retrieves a pointer to the template arguments ParsedTemplateArgument *getTemplateArgs() { return getTrailingObjects<ParsedTemplateArgument>(); @@ -195,18 +197,17 @@ namespace clang { /// Creates a new TemplateIdAnnotation with NumArgs arguments and /// appends it to List. static TemplateIdAnnotation * - Create(CXXScopeSpec SS, SourceLocation TemplateKWLoc, - SourceLocation TemplateNameLoc, IdentifierInfo *Name, - OverloadedOperatorKind OperatorKind, + Create(SourceLocation TemplateKWLoc, SourceLocation TemplateNameLoc, + IdentifierInfo *Name, OverloadedOperatorKind OperatorKind, ParsedTemplateTy OpaqueTemplateName, TemplateNameKind TemplateKind, SourceLocation LAngleLoc, SourceLocation RAngleLoc, - ArrayRef<ParsedTemplateArgument> TemplateArgs, + ArrayRef<ParsedTemplateArgument> TemplateArgs, bool ArgsInvalid, SmallVectorImpl<TemplateIdAnnotation *> &CleanupList) { TemplateIdAnnotation *TemplateId = new (llvm::safe_malloc( totalSizeToAlloc<ParsedTemplateArgument>(TemplateArgs.size()))) - TemplateIdAnnotation(SS, TemplateKWLoc, TemplateNameLoc, Name, + TemplateIdAnnotation(TemplateKWLoc, TemplateNameLoc, Name, OperatorKind, OpaqueTemplateName, TemplateKind, - LAngleLoc, RAngleLoc, TemplateArgs); + LAngleLoc, RAngleLoc, TemplateArgs, ArgsInvalid); CleanupList.push_back(TemplateId); return TemplateId; } @@ -218,21 +219,35 @@ namespace clang { this->~TemplateIdAnnotation(); free(this); } + + /// Determine whether this might be a type template. + bool mightBeType() const { + return Kind == TNK_Non_template || + Kind == TNK_Type_template || + Kind == TNK_Dependent_template_name || + Kind == TNK_Undeclared_template; + } + + bool hasInvalidName() const { return Kind == TNK_Non_template; } + bool hasInvalidArgs() const { return ArgsInvalid; } + + bool isInvalid() const { return hasInvalidName() || hasInvalidArgs(); } + private: TemplateIdAnnotation(const TemplateIdAnnotation &) = delete; - TemplateIdAnnotation(CXXScopeSpec SS, SourceLocation TemplateKWLoc, + TemplateIdAnnotation(SourceLocation TemplateKWLoc, SourceLocation TemplateNameLoc, IdentifierInfo *Name, OverloadedOperatorKind OperatorKind, ParsedTemplateTy OpaqueTemplateName, TemplateNameKind TemplateKind, SourceLocation LAngleLoc, SourceLocation RAngleLoc, - ArrayRef<ParsedTemplateArgument> TemplateArgs) noexcept - : SS(SS), TemplateKWLoc(TemplateKWLoc), - TemplateNameLoc(TemplateNameLoc), Name(Name), Operator(OperatorKind), - Template(OpaqueTemplateName), Kind(TemplateKind), - LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc), - NumArgs(TemplateArgs.size()) { + ArrayRef<ParsedTemplateArgument> TemplateArgs, + bool ArgsInvalid) noexcept + : TemplateKWLoc(TemplateKWLoc), TemplateNameLoc(TemplateNameLoc), + Name(Name), Operator(OperatorKind), Template(OpaqueTemplateName), + Kind(TemplateKind), LAngleLoc(LAngleLoc), RAngleLoc(RAngleLoc), + NumArgs(TemplateArgs.size()), ArgsInvalid(ArgsInvalid) { std::uninitialized_copy(TemplateArgs.begin(), TemplateArgs.end(), getTemplateArgs()); diff --git a/clang/include/clang/Sema/Scope.h b/clang/include/clang/Sema/Scope.h index 7848df8f70d9..b7260f15fe1b 100644 --- a/clang/include/clang/Sema/Scope.h +++ b/clang/include/clang/Sema/Scope.h @@ -320,15 +320,28 @@ public: /// isDeclScope - Return true if this is the scope that the specified decl is /// declared in. - bool isDeclScope(Decl *D) { - return DeclsInScope.count(D) != 0; + bool isDeclScope(const Decl *D) const { return DeclsInScope.count(D) != 0; } + + /// Get the entity corresponding to this scope. + DeclContext *getEntity() const { + return isTemplateParamScope() ? nullptr : Entity; } - DeclContext *getEntity() const { return Entity; } - void setEntity(DeclContext *E) { Entity = E; } + /// Get the DeclContext in which to continue unqualified lookup after a + /// lookup in this scope. + DeclContext *getLookupEntity() const { return Entity; } - bool hasErrorOccurred() const { return ErrorTrap.hasErrorOccurred(); } + void setEntity(DeclContext *E) { + assert(!isTemplateParamScope() && + "entity associated with template param scope"); + Entity = E; + } + void setLookupEntity(DeclContext *E) { Entity = E; } + /// Determine whether any unrecoverable errors have occurred within this + /// scope. Note that this may return false even if the scope contains invalid + /// declarations or statements, if the errors for those invalid constructs + /// were suppressed because some prior invalid construct was referenced. bool hasUnrecoverableErrorOccurred() const { return ErrorTrap.hasUnrecoverableErrorOccurred(); } @@ -385,6 +398,12 @@ public: return getFlags() & Scope::FunctionPrototypeScope; } + /// isFunctionDeclarationScope - Return true if this scope is a + /// function prototype scope. + bool isFunctionDeclarationScope() const { + return getFlags() & Scope::FunctionDeclarationScope; + } + /// isAtCatchScope - Return true if this scope is \@catch. bool isAtCatchScope() const { return getFlags() & Scope::AtCatchScope; diff --git a/clang/include/clang/Sema/ScopeInfo.h b/clang/include/clang/Sema/ScopeInfo.h index 4f7534f9ef1a..f0f9cb9e40ae 100644 --- a/clang/include/clang/Sema/ScopeInfo.h +++ b/clang/include/clang/Sema/ScopeInfo.h @@ -22,6 +22,7 @@ #include "clang/Basic/PartialDiagnostic.h" #include "clang/Basic/SourceLocation.h" #include "clang/Sema/CleanupInfo.h" +#include "clang/Sema/DeclSpec.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseMapInfo.h" #include "llvm/ADT/MapVector.h" @@ -173,9 +174,11 @@ public: /// First SEH '__try' statement in the current function. SourceLocation FirstSEHTryLoc; +private: /// Used to determine if errors occurred in this function or block. DiagnosticErrorTrap ErrorTrap; +public: /// A SwitchStmt, along with a flag indicating if its list of case statements /// is incomplete (because we dropped an invalid one while parsing). using SwitchInfo = llvm::PointerIntPair<SwitchStmt*, 1, bool>; @@ -374,6 +377,17 @@ public: virtual ~FunctionScopeInfo(); + /// Determine whether an unrecoverable error has occurred within this + /// function. Note that this may return false even if the function body is + /// invalid, because the errors may be suppressed if they're caused by prior + /// invalid declarations. + /// + /// FIXME: Migrate the caller of this to use containsErrors() instead once + /// it's ready. + bool hasUnrecoverableErrorOccurred() const { + return ErrorTrap.hasUnrecoverableErrorOccurred(); + } + /// Record that a weak object was accessed. /// /// Part of the implementation of -Wrepeated-use-of-weak. @@ -789,7 +803,8 @@ public: } }; -class LambdaScopeInfo final : public CapturingScopeInfo { +class LambdaScopeInfo final : + public CapturingScopeInfo, public InventedTemplateParameterInfo { public: /// The class that describes the lambda. CXXRecordDecl *Lambda = nullptr; @@ -823,25 +838,9 @@ public: /// Packs introduced by this lambda, if any. SmallVector<NamedDecl*, 4> LocalPacks; - /// If this is a generic lambda, use this as the depth of - /// each 'auto' parameter, during initial AST construction. - unsigned AutoTemplateParameterDepth = 0; - - /// The number of parameters in the template parameter list that were - /// explicitly specified by the user, as opposed to being invented by use - /// of an auto parameter. - unsigned NumExplicitTemplateParams = 0; - /// Source range covering the explicit template parameter list (if it exists). SourceRange ExplicitTemplateParamsRange; - /// Store the list of the template parameters for a generic lambda. - /// If this is a generic lambda, this holds the explicit template parameters - /// followed by the auto parameters converted into TemplateTypeParmDecls. - /// It can be used to construct the generic lambda's template parameter list - /// during initial AST construction. - SmallVector<NamedDecl*, 4> TemplateParams; - /// If this is a generic lambda, and the template parameter /// list has been created (from the TemplateParams) then store /// a reference to it (cache it to avoid reconstructing it). diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 47a055f696b1..6f7ad8076718 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -15,6 +15,7 @@ #define LLVM_CLANG_SEMA_SEMA_H #include "clang/AST/ASTConcept.h" +#include "clang/AST/ASTFwd.h" #include "clang/AST/Attr.h" #include "clang/AST/Availability.h" #include "clang/AST/ComparisonCategories.h" @@ -22,7 +23,9 @@ #include "clang/AST/DeclarationName.h" #include "clang/AST/Expr.h" #include "clang/AST/ExprCXX.h" +#include "clang/AST/ExprConcepts.h" #include "clang/AST/ExprObjC.h" +#include "clang/AST/ExprOpenMP.h" #include "clang/AST/ExternalASTSource.h" #include "clang/AST/LocInfoType.h" #include "clang/AST/MangleNumberingContext.h" @@ -34,6 +37,7 @@ #include "clang/Basic/BitmaskEnum.h" #include "clang/Basic/ExpressionTraits.h" #include "clang/Basic/Module.h" +#include "clang/Basic/OpenCLOptions.h" #include "clang/Basic/OpenMPKinds.h" #include "clang/Basic/PragmaKinds.h" #include "clang/Basic/Specifiers.h" @@ -54,6 +58,7 @@ #include "llvm/ADT/Optional.h" #include "llvm/ADT/SetVector.h" #include "llvm/ADT/SmallBitVector.h" +#include "llvm/ADT/SmallSet.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/TinyPtrVector.h" @@ -372,12 +377,22 @@ class Sema final { ArrayRef<QualType> Args); public: + /// The maximum alignment, same as in llvm::Value. We duplicate them here + /// because that allows us not to duplicate the constants in clang code, + /// which we must to since we can't directly use the llvm constants. + /// The value is verified against llvm here: lib/CodeGen/CGDecl.cpp + /// + /// This is the greatest alignment value supported by load, store, and alloca + /// instructions, and global values. + static const unsigned MaxAlignmentExponent = 29; + static const unsigned MaximumAlignment = 1u << MaxAlignmentExponent; + typedef OpaquePtr<DeclGroupRef> DeclGroupPtrTy; typedef OpaquePtr<TemplateName> TemplateTy; typedef OpaquePtr<QualType> TypeTy; OpenCLOptions OpenCLFeatures; - FPOptions FPFeatures; + FPOptions CurFPFeatures; const LangOptions &LangOpts; Preprocessor &PP; @@ -475,10 +490,41 @@ public: PragmaLocation(PragmaLocation), PragmaPushLocation(PragmaPushLocation) {} }; - void Act(SourceLocation PragmaLocation, - PragmaMsStackAction Action, - llvm::StringRef StackSlotLabel, - ValueType Value); + + void Act(SourceLocation PragmaLocation, PragmaMsStackAction Action, + llvm::StringRef StackSlotLabel, ValueType Value) { + if (Action == PSK_Reset) { + CurrentValue = DefaultValue; + CurrentPragmaLocation = PragmaLocation; + return; + } + if (Action & PSK_Push) + Stack.emplace_back(StackSlotLabel, CurrentValue, CurrentPragmaLocation, + PragmaLocation); + else if (Action & PSK_Pop) { + if (!StackSlotLabel.empty()) { + // If we've got a label, try to find it and jump there. + auto I = llvm::find_if(llvm::reverse(Stack), [&](const Slot &x) { + return x.StackSlotLabel == StackSlotLabel; + }); + // If we found the label so pop from there. + if (I != Stack.rend()) { + CurrentValue = I->Value; + CurrentPragmaLocation = I->PragmaLocation; + Stack.erase(std::prev(I.base()), Stack.end()); + } + } else if (!Stack.empty()) { + // We do not have a label, just pop the last entry. + CurrentValue = Stack.back().Value; + CurrentPragmaLocation = Stack.back().PragmaLocation; + Stack.pop_back(); + } + } + if (Action & PSK_Set) { + CurrentValue = Value; + CurrentPragmaLocation = PragmaLocation; + } + } // MSVC seems to add artificial slots to #pragma stacks on entering a C++ // method body to restore the stacks on exit, so it works like this: @@ -540,6 +586,18 @@ public: PragmaStack<StringLiteral *> ConstSegStack; PragmaStack<StringLiteral *> CodeSegStack; + // This stack tracks the current state of Sema.CurFPFeatures. + PragmaStack<unsigned> FpPragmaStack; + FPOptionsOverride CurFPFeatureOverrides() { + FPOptionsOverride result; + if (!FpPragmaStack.hasValue()) { + result = FPOptionsOverride(); + } else { + result = FPOptionsOverride(FpPragmaStack.CurrentValue); + } + return result; + } + // RAII object to push / pop sentinel slots for all MS #pragma stacks. // Actions should be performed only if we enter / exit a C++ method body. class PragmaStackSentinelRAII { @@ -601,16 +659,16 @@ public: CleanupInfo Cleanup; /// ExprCleanupObjects - This is the stack of objects requiring - /// cleanup that are created by the current full expression. The - /// element type here is ExprWithCleanups::Object. - SmallVector<BlockDecl*, 8> ExprCleanupObjects; + /// cleanup that are created by the current full expression. + SmallVector<ExprWithCleanups::CleanupObject, 8> ExprCleanupObjects; /// Store a set of either DeclRefExprs or MemberExprs that contain a reference /// to a variable (constant) that may or may not be odr-used in this Expr, and /// we won't know until all lvalue-to-rvalue and discarded value conversions /// have been applied to all subexpressions of the enclosing full expression. /// This is cleared at the end of each full expression. - using MaybeODRUseExprSet = llvm::SmallPtrSet<Expr *, 2>; + using MaybeODRUseExprSet = llvm::SetVector<Expr *, SmallVector<Expr *, 4>, + llvm::SmallPtrSet<Expr *, 4>>; MaybeODRUseExprSet MaybeODRUseExprs; std::unique_ptr<sema::FunctionScopeInfo> CachedFunctionScope; @@ -619,6 +677,32 @@ public: /// function, block, and method scopes that are currently active. SmallVector<sema::FunctionScopeInfo *, 4> FunctionScopes; + /// The index of the first FunctionScope that corresponds to the current + /// context. + unsigned FunctionScopesStart = 0; + + ArrayRef<sema::FunctionScopeInfo*> getFunctionScopes() const { + return llvm::makeArrayRef(FunctionScopes.begin() + FunctionScopesStart, + FunctionScopes.end()); + } + + /// Stack containing information needed when in C++2a an 'auto' is encountered + /// in a function declaration parameter type specifier in order to invent a + /// corresponding template parameter in the enclosing abbreviated function + /// template. This information is also present in LambdaScopeInfo, stored in + /// the FunctionScopes stack. + SmallVector<InventedTemplateParameterInfo, 4> InventedParameterInfos; + + /// The index of the first InventedParameterInfo that refers to the current + /// context. + unsigned InventedParameterInfosStart = 0; + + ArrayRef<InventedTemplateParameterInfo> getInventedParameterInfos() const { + return llvm::makeArrayRef(InventedParameterInfos.begin() + + InventedParameterInfosStart, + InventedParameterInfos.end()); + } + typedef LazyVector<TypedefNameDecl *, ExternalSemaSource, &ExternalSemaSource::ReadExtVectorDecls, 2, 2> ExtVectorDeclsType; @@ -792,17 +876,24 @@ public: DeclContext *SavedContext; ProcessingContextState SavedContextState; QualType SavedCXXThisTypeOverride; + unsigned SavedFunctionScopesStart; + unsigned SavedInventedParameterInfosStart; public: ContextRAII(Sema &S, DeclContext *ContextToPush, bool NewThisContext = true) : S(S), SavedContext(S.CurContext), SavedContextState(S.DelayedDiagnostics.pushUndelayed()), - SavedCXXThisTypeOverride(S.CXXThisTypeOverride) + SavedCXXThisTypeOverride(S.CXXThisTypeOverride), + SavedFunctionScopesStart(S.FunctionScopesStart), + SavedInventedParameterInfosStart(S.InventedParameterInfosStart) { assert(ContextToPush && "pushing null context"); S.CurContext = ContextToPush; if (NewThisContext) S.CXXThisTypeOverride = QualType(); + // Any saved FunctionScopes do not refer to this context. + S.FunctionScopesStart = S.FunctionScopes.size(); + S.InventedParameterInfosStart = S.InventedParameterInfos.size(); } void pop() { @@ -810,6 +901,8 @@ public: S.CurContext = SavedContext; S.DelayedDiagnostics.popUndelayed(SavedContextState); S.CXXThisTypeOverride = SavedCXXThisTypeOverride; + S.FunctionScopesStart = SavedFunctionScopesStart; + S.InventedParameterInfosStart = SavedInventedParameterInfosStart; SavedContext = nullptr; } @@ -818,6 +911,11 @@ public: } }; + /// Whether the AST is currently being rebuilt to correct immediate + /// invocations. Immediate invocation candidates and references to consteval + /// functions aren't tracked when this is set. + bool RebuildingImmediateInvocation = false; + /// Used to change context to isConstantEvaluated without pushing a heavy /// ExpressionEvaluationContextRecord object. bool isConstantEvaluatedOverride; @@ -1029,6 +1127,8 @@ public: PotentiallyEvaluatedIfUsed }; + using ImmediateInvocationCandidate = llvm::PointerIntPair<ConstantExpr *, 1>; + /// Data structure used to record current or nested /// expression evaluation contexts. struct ExpressionEvaluationContextRecord { @@ -1075,6 +1175,13 @@ public: /// they are not discarded-value expressions nor unevaluated operands. SmallVector<Expr*, 2> VolatileAssignmentLHSs; + /// Set of candidates for starting an immediate invocation. + llvm::SmallVector<ImmediateInvocationCandidate, 4> ImmediateInvocationCandidates; + + /// Set of DeclRefExprs referencing a consteval function when used in a + /// context not already known to be immediately invoked. + llvm::SmallPtrSet<DeclRefExpr *, 4> ReferenceToConsteval; + /// \brief Describes whether we are in an expression constext which we have /// to handle differently. enum ExpressionKind { @@ -1287,16 +1394,23 @@ public: /// should not be used elsewhere. void EmitCurrentDiagnostic(unsigned DiagID); - /// Records and restores the FP_CONTRACT state on entry/exit of compound + /// Records and restores the CurFPFeatures state on entry/exit of compound /// statements. - class FPContractStateRAII { + class FPFeaturesStateRAII { public: - FPContractStateRAII(Sema &S) : S(S), OldFPFeaturesState(S.FPFeatures) {} - ~FPContractStateRAII() { S.FPFeatures = OldFPFeaturesState; } + FPFeaturesStateRAII(Sema &S) : S(S), OldFPFeaturesState(S.CurFPFeatures) { + OldOverrides = S.FpPragmaStack.CurrentValue; + } + ~FPFeaturesStateRAII() { + S.CurFPFeatures = OldFPFeaturesState; + S.FpPragmaStack.CurrentValue = OldOverrides; + } + unsigned getOverrides() { return OldOverrides; } private: Sema& S; FPOptions OldFPFeaturesState; + unsigned OldOverrides; }; void addImplicitTypedef(StringRef Name, QualType T); @@ -1315,7 +1429,7 @@ public: const LangOptions &getLangOpts() const { return LangOpts; } OpenCLOptions &getOpenCLOptions() { return OpenCLFeatures; } - FPOptions &getFPOptions() { return FPFeatures; } + FPOptions &getCurFPFeatures() { return CurFPFeatures; } DiagnosticsEngine &getDiagnostics() const { return Diags; } SourceManager &getSourceManager() const { return SourceMgr; } @@ -1424,8 +1538,22 @@ public: /// Retrieve the module loader associated with the preprocessor. ModuleLoader &getModuleLoader() const; + /// Invent a new identifier for parameters of abbreviated templates. + IdentifierInfo * + InventAbbreviatedTemplateParameterTypeName(IdentifierInfo *ParamName, + unsigned Index); + void emitAndClearUnusedLocalTypedefWarnings(); + private: + /// Function or variable declarations to be checked for whether the deferred + /// diagnostics should be emitted. + SmallVector<Decl *, 4> DeclsToCheckForDeferredDiags; + + public: + // Emit all deferred diagnostics. + void emitDeferredDiags(); + enum TUFragmentKind { /// The global module fragment, between 'module;' and a module-declaration. Global, @@ -1518,6 +1646,15 @@ public: /// WeakTopLevelDeclDecls - access to \#pragma weak-generated Decls SmallVectorImpl<Decl *> &WeakTopLevelDecls() { return WeakTopLevelDecl; } + /// Called before parsing a function declarator belonging to a function + /// declaration. + void ActOnStartFunctionDeclarationDeclarator(Declarator &D, + unsigned TemplateParameterDepth); + + /// Called after parsing a function declarator belonging to a function + /// declaration. + void ActOnFinishFunctionDeclarationDeclarator(Declarator &D); + void ActOnComment(SourceRange Comment); //===--------------------------------------------------------------------===// @@ -1538,6 +1675,9 @@ public: QualType BuildVectorType(QualType T, Expr *VecSize, SourceLocation AttrLoc); QualType BuildExtVectorType(QualType T, Expr *ArraySize, SourceLocation AttrLoc); + QualType BuildMatrixType(QualType T, Expr *NumRows, Expr *NumColumns, + SourceLocation AttrLoc); + QualType BuildAddressSpaceAttr(QualType &T, LangAS ASIdx, Expr *AddrSpace, SourceLocation AttrLoc); @@ -1592,6 +1732,7 @@ public: SourceLocation Loc); QualType BuildWritePipeType(QualType T, SourceLocation Loc); + QualType BuildExtIntType(bool IsUnsigned, Expr *BitWidth, SourceLocation Loc); TypeSourceInfo *GetTypeForDeclarator(Declarator &D, Scope *S); TypeSourceInfo *GetTypeForDeclaratorCast(Declarator &D, QualType FromTy); @@ -1603,6 +1744,10 @@ public: static QualType GetTypeFromParser(ParsedType Ty, TypeSourceInfo **TInfo = nullptr); CanThrowResult canThrow(const Stmt *E); + /// Determine whether the callee of a particular function call can throw. + /// E, D and Loc are all optional. + static CanThrowResult canCalleeThrow(Sema &S, const Expr *E, const Decl *D, + SourceLocation Loc = SourceLocation()); const FunctionProtoType *ResolveExceptionSpec(SourceLocation Loc, const FunctionProtoType *FPT); void UpdateExceptionSpec(FunctionDecl *FD, @@ -1664,6 +1809,7 @@ public: static SourceRange getPrintable(TypeLoc TL) { return TL.getSourceRange();} template <typename... Ts> class BoundTypeDiagnoser : public TypeDiagnoser { + protected: unsigned DiagID; std::tuple<const Ts &...> Args; @@ -1688,6 +1834,37 @@ public: } }; + /// A derivative of BoundTypeDiagnoser for which the diagnostic's type + /// parameter is preceded by a 0/1 enum that is 1 if the type is sizeless. + /// For example, a diagnostic with no other parameters would generally have + /// the form "...%select{incomplete|sizeless}0 type %1...". + template <typename... Ts> + class SizelessTypeDiagnoser : public BoundTypeDiagnoser<Ts...> { + public: + SizelessTypeDiagnoser(unsigned DiagID, const Ts &... Args) + : BoundTypeDiagnoser<Ts...>(DiagID, Args...) {} + + void diagnose(Sema &S, SourceLocation Loc, QualType T) override { + const SemaDiagnosticBuilder &DB = S.Diag(Loc, this->DiagID); + this->emit(DB, std::index_sequence_for<Ts...>()); + DB << T->isSizelessType() << T; + } + }; + + enum class CompleteTypeKind { + /// Apply the normal rules for complete types. In particular, + /// treat all sizeless types as incomplete. + Normal, + + /// Relax the normal rules for complete types so that they include + /// sizeless built-in types. + AcceptSizeless, + + // FIXME: Eventually we should flip the default to Normal and opt in + // to AcceptSizeless rather than opt out of it. + Default = AcceptSizeless + }; + private: /// Methods for marking which expressions involve dereferencing a pointer /// marked with the 'noderef' attribute. Expressions are checked bottom up as @@ -1701,7 +1878,7 @@ private: void CheckMemberAccessOfNoDeref(const MemberExpr *E); bool RequireCompleteTypeImpl(SourceLocation Loc, QualType T, - TypeDiagnoser *Diagnoser); + CompleteTypeKind Kind, TypeDiagnoser *Diagnoser); struct ModuleScope { SourceLocation BeginLoc; @@ -1737,7 +1914,7 @@ public: /// Determine whether a declaration is visible to name lookup. bool isVisible(const NamedDecl *D) { - return !D->isHidden() || isVisibleSlow(D); + return D->isUnconditionallyVisible() || isVisibleSlow(D); } /// Determine whether any declaration of an entity is visible. @@ -1792,13 +1969,22 @@ public: bool isUsualDeallocationFunction(const CXXMethodDecl *FD); - bool isCompleteType(SourceLocation Loc, QualType T) { - return !RequireCompleteTypeImpl(Loc, T, nullptr); + bool isCompleteType(SourceLocation Loc, QualType T, + CompleteTypeKind Kind = CompleteTypeKind::Default) { + return !RequireCompleteTypeImpl(Loc, T, Kind, nullptr); } bool RequireCompleteType(SourceLocation Loc, QualType T, - TypeDiagnoser &Diagnoser); + CompleteTypeKind Kind, TypeDiagnoser &Diagnoser); bool RequireCompleteType(SourceLocation Loc, QualType T, - unsigned DiagID); + CompleteTypeKind Kind, unsigned DiagID); + + bool RequireCompleteType(SourceLocation Loc, QualType T, + TypeDiagnoser &Diagnoser) { + return RequireCompleteType(Loc, T, CompleteTypeKind::Default, Diagnoser); + } + bool RequireCompleteType(SourceLocation Loc, QualType T, unsigned DiagID) { + return RequireCompleteType(Loc, T, CompleteTypeKind::Default, DiagID); + } template <typename... Ts> bool RequireCompleteType(SourceLocation Loc, QualType T, unsigned DiagID, @@ -1807,14 +1993,29 @@ public: return RequireCompleteType(Loc, T, Diagnoser); } + template <typename... Ts> + bool RequireCompleteSizedType(SourceLocation Loc, QualType T, unsigned DiagID, + const Ts &... Args) { + SizelessTypeDiagnoser<Ts...> Diagnoser(DiagID, Args...); + return RequireCompleteType(Loc, T, CompleteTypeKind::Normal, Diagnoser); + } + void completeExprArrayBound(Expr *E); - bool RequireCompleteExprType(Expr *E, TypeDiagnoser &Diagnoser); + bool RequireCompleteExprType(Expr *E, CompleteTypeKind Kind, + TypeDiagnoser &Diagnoser); bool RequireCompleteExprType(Expr *E, unsigned DiagID); template <typename... Ts> bool RequireCompleteExprType(Expr *E, unsigned DiagID, const Ts &...Args) { BoundTypeDiagnoser<Ts...> Diagnoser(DiagID, Args...); - return RequireCompleteExprType(E, Diagnoser); + return RequireCompleteExprType(E, CompleteTypeKind::Default, Diagnoser); + } + + template <typename... Ts> + bool RequireCompleteSizedExprType(Expr *E, unsigned DiagID, + const Ts &... Args) { + SizelessTypeDiagnoser<Ts...> Diagnoser(DiagID, Args...); + return RequireCompleteExprType(E, CompleteTypeKind::Normal, Diagnoser); } bool RequireLiteralType(SourceLocation Loc, QualType T, @@ -1921,6 +2122,8 @@ public: NC_FunctionTemplate, /// The name was classified as an ADL-only function template name. NC_UndeclaredTemplate, + /// The name was classified as a concept name. + NC_Concept, }; class NameClassification { @@ -1985,6 +2188,12 @@ public: return Result; } + static NameClassification Concept(TemplateName Name) { + NameClassification Result(NC_Concept); + Result.Template = Name; + return Result; + } + static NameClassification UndeclaredTemplate(TemplateName Name) { NameClassification Result(NC_UndeclaredTemplate); Result.Template = Name; @@ -2010,7 +2219,8 @@ public: TemplateName getTemplateName() const { assert(Kind == NC_TypeTemplate || Kind == NC_FunctionTemplate || - Kind == NC_VarTemplate || Kind == NC_UndeclaredTemplate); + Kind == NC_VarTemplate || Kind == NC_Concept || + Kind == NC_UndeclaredTemplate); return Template; } @@ -2022,6 +2232,8 @@ public: return TNK_Function_template; case NC_VarTemplate: return TNK_Var_template; + case NC_Concept: + return TNK_Concept_template; case NC_UndeclaredTemplate: return TNK_Undeclared_template; default: @@ -2221,11 +2433,13 @@ public: void ActOnParamDefaultArgument(Decl *param, SourceLocation EqualLoc, Expr *defarg); - void ActOnParamUnparsedDefaultArgument(Decl *param, - SourceLocation EqualLoc, + void ActOnParamUnparsedDefaultArgument(Decl *param, SourceLocation EqualLoc, SourceLocation ArgLoc); void ActOnParamDefaultArgumentError(Decl *param, SourceLocation EqualLoc); - bool SetParamDefaultArgument(ParmVarDecl *Param, Expr *DefaultArg, + ExprResult ConvertParamDefaultArgument(const ParmVarDecl *Param, + Expr *DefaultArg, + SourceLocation EqualLoc); + void SetParamDefaultArgument(ParmVarDecl *Param, Expr *DefaultArg, SourceLocation EqualLoc); // Contexts where using non-trivial C union types can be disallowed. This is @@ -2699,8 +2913,6 @@ public: Decl *EnumDecl, ArrayRef<Decl *> Elements, Scope *S, const ParsedAttributesView &Attr); - DeclContext *getContainingDC(DeclContext *DC); - /// Set the current declaration context until it gets popped. void PushDeclContext(Scope *S, DeclContext *DC); void PopDeclContext(); @@ -2710,6 +2922,11 @@ public: void EnterDeclaratorContext(Scope *S, DeclContext *DC); void ExitDeclaratorContext(Scope *S); + /// Enter a template parameter scope, after it's been associated with a particular + /// DeclContext. Causes lookup within the scope to chain through enclosing contexts + /// in the correct order. + void EnterTemplatedContext(Scope *S, DeclContext *DC); + /// Push the parameters of D, which must be a function, into scope. void ActOnReenterFunctionContext(Scope* S, Decl* D); void ActOnExitFunctionContext(); @@ -2808,7 +3025,7 @@ public: VisibilityAttr *mergeVisibilityAttr(Decl *D, const AttributeCommonInfo &CI, VisibilityAttr::VisibilityType Vis); UuidAttr *mergeUuidAttr(Decl *D, const AttributeCommonInfo &CI, - StringRef Uuid); + StringRef UuidAsWritten, MSGuidDecl *GuidDecl); DLLImportAttr *mergeDLLImportAttr(Decl *D, const AttributeCommonInfo &CI); DLLExportAttr *mergeDLLExportAttr(Decl *D, const AttributeCommonInfo &CI); MSInheritanceAttr *mergeMSInheritanceAttr(Decl *D, @@ -2839,6 +3056,10 @@ public: const InternalLinkageAttr &AL); CommonAttr *mergeCommonAttr(Decl *D, const ParsedAttr &AL); CommonAttr *mergeCommonAttr(Decl *D, const CommonAttr &AL); + WebAssemblyImportNameAttr *mergeImportNameAttr( + Decl *D, const WebAssemblyImportNameAttr &AL); + WebAssemblyImportModuleAttr *mergeImportModuleAttr( + Decl *D, const WebAssemblyImportModuleAttr &AL); void mergeDeclAttributes(NamedDecl *New, Decl *Old, AvailabilityMergeKind AMK = AMK_Redeclaration); @@ -2892,10 +3113,19 @@ public: bool ConsiderCudaAttrs = true, bool ConsiderRequiresClauses = true); + enum class AllowedExplicit { + /// Allow no explicit functions to be used. + None, + /// Allow explicit conversion functions but not explicit constructors. + Conversions, + /// Allow both explicit conversion functions and explicit constructors. + All + }; + ImplicitConversionSequence TryImplicitConversion(Expr *From, QualType ToType, bool SuppressUserConversions, - bool AllowExplicit, + AllowedExplicit AllowExplicit, bool InOverloadResolution, bool CStyle, bool AllowObjCWritebackConversion); @@ -3202,7 +3432,8 @@ public: /// 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, + EnableIfAttr *CheckEnableIf(FunctionDecl *Function, SourceLocation CallLoc, + ArrayRef<Expr *> Args, bool MissingImplicitThis = false); /// Find the failed Boolean condition within a given Boolean @@ -3412,6 +3643,9 @@ public: /// operator overloading. This lookup is similar to ordinary name /// lookup, but will ignore any declarations that are class members. LookupOperatorName, + /// Look up a name following ~ in a destructor name. This is an ordinary + /// lookup, but prefers tags to typedefs. + LookupDestructorName, /// Look up of a name that precedes the '::' scope resolution /// operator in C++. This lookup completely ignores operator, object, /// function, and enumerator names (C++ [basic.lookup.qual]p1). @@ -3522,7 +3756,7 @@ private: /// Creates a new TypoExpr AST node. TypoExpr *createDelayedTypo(std::unique_ptr<TypoCorrectionConsumer> TCC, TypoDiagnosticGenerator TDG, - TypoRecoveryCallback TRC); + TypoRecoveryCallback TRC, SourceLocation TypoLoc); // The set of known/encountered (unique, canonicalized) NamespaceDecls. // @@ -3613,7 +3847,8 @@ public: TemplateDiscarded, // Discarded due to uninstantiated templates Unknown, }; - FunctionEmissionStatus getEmissionStatus(FunctionDecl *Decl); + FunctionEmissionStatus getEmissionStatus(FunctionDecl *Decl, + bool Final = false); // Whether the callee should be ignored in CUDA/HIP/OpenMP host/device check. bool shouldIgnoreInHostDeviceCheck(FunctionDecl *Callee); @@ -3666,32 +3901,28 @@ public: /// \param InitDecl A VarDecl to avoid because the Expr being corrected is its /// initializer. /// + /// \param RecoverUncorrectedTypos If true, when typo correction fails, it + /// will rebuild the given Expr with all TypoExprs degraded to RecoveryExprs. + /// /// \param Filter A function applied to a newly rebuilt Expr to determine if /// it is an acceptable/usable result from a single combination of typo /// corrections. As long as the filter returns ExprError, different /// combinations of corrections will be tried until all are exhausted. - ExprResult - CorrectDelayedTyposInExpr(Expr *E, VarDecl *InitDecl = nullptr, - llvm::function_ref<ExprResult(Expr *)> Filter = - [](Expr *E) -> ExprResult { return E; }); - - ExprResult - CorrectDelayedTyposInExpr(Expr *E, - llvm::function_ref<ExprResult(Expr *)> Filter) { - return CorrectDelayedTyposInExpr(E, nullptr, Filter); - } - - ExprResult - CorrectDelayedTyposInExpr(ExprResult ER, VarDecl *InitDecl = nullptr, - llvm::function_ref<ExprResult(Expr *)> Filter = - [](Expr *E) -> ExprResult { return E; }) { - return ER.isInvalid() ? ER : CorrectDelayedTyposInExpr(ER.get(), Filter); - } - - ExprResult - CorrectDelayedTyposInExpr(ExprResult ER, - llvm::function_ref<ExprResult(Expr *)> Filter) { - return CorrectDelayedTyposInExpr(ER, nullptr, Filter); + ExprResult CorrectDelayedTyposInExpr( + Expr *E, VarDecl *InitDecl = nullptr, + bool RecoverUncorrectedTypos = false, + llvm::function_ref<ExprResult(Expr *)> Filter = + [](Expr *E) -> ExprResult { return E; }); + + ExprResult CorrectDelayedTyposInExpr( + ExprResult ER, VarDecl *InitDecl = nullptr, + bool RecoverUncorrectedTypos = false, + llvm::function_ref<ExprResult(Expr *)> Filter = + [](Expr *E) -> ExprResult { return E; }) { + return ER.isInvalid() + ? ER + : CorrectDelayedTyposInExpr(ER.get(), InitDecl, + RecoverUncorrectedTypos, Filter); } void diagnoseTypo(const TypoCorrection &Correction, @@ -3718,6 +3949,11 @@ public: void DiagnoseAmbiguousLookup(LookupResult &Result); //@} + /// Attempts to produce a RecoveryExpr after some AST node cannot be created. + ExprResult CreateRecoveryExpr(SourceLocation Begin, SourceLocation End, + ArrayRef<Expr *> SubExprs, + QualType T = QualType()); + ObjCInterfaceDecl *getObjCInterfaceDecl(IdentifierInfo *&Id, SourceLocation IdLoc, bool TypoCorrection = false); @@ -3726,6 +3962,8 @@ public: SourceLocation Loc); NamedDecl *ImplicitlyDefineFunction(SourceLocation Loc, IdentifierInfo &II, Scope *S); + void AddKnownFunctionAttributesForReplaceableGlobalAllocationFunction( + FunctionDecl *FD); void AddKnownFunctionAttributes(FunctionDecl *FD); // More parsing and symbol table subroutines. @@ -4139,7 +4377,8 @@ public: ConditionResult Cond); StmtResult ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch, Stmt *Body); - StmtResult ActOnWhileStmt(SourceLocation WhileLoc, ConditionResult Cond, + StmtResult ActOnWhileStmt(SourceLocation WhileLoc, SourceLocation LParenLoc, + ConditionResult Cond, SourceLocation RParenLoc, Stmt *Body); StmtResult ActOnDoStmt(SourceLocation DoLoc, Stmt *Body, SourceLocation WhileLoc, SourceLocation CondLParen, @@ -4380,6 +4619,8 @@ public: /// Issue any -Wunguarded-availability warnings in \c FD void DiagnoseUnguardedAvailabilityViolations(Decl *FD); + void handleDelayedAvailabilityCheck(sema::DelayedDiagnostic &DD, Decl *Ctx); + //===--------------------------------------------------------------------===// // Expression Parsing Callbacks: SemaExpr.cpp. @@ -4516,6 +4757,10 @@ public: bool tryExprAsCall(Expr &E, QualType &ZeroArgCallReturnTy, UnresolvedSetImpl &NonTemplateOverloads); + /// Try to convert an expression \p E to type \p Ty. Returns the result of the + /// conversion. + ExprResult tryConvertExprToType(Expr *E, QualType Ty); + /// Conditionally issue a diagnostic based on the current /// evaluation context. /// @@ -4642,6 +4887,15 @@ public: ExprResult ActOnPredefinedExpr(SourceLocation Loc, tok::TokenKind Kind); ExprResult ActOnIntegerConstant(SourceLocation Loc, uint64_t Val); + ExprResult BuildUniqueStableName(SourceLocation Loc, TypeSourceInfo *Operand); + ExprResult BuildUniqueStableName(SourceLocation Loc, Expr *E); + ExprResult ActOnUniqueStableNameExpr(SourceLocation OpLoc, + SourceLocation LParen, + SourceLocation RParen, ParsedType Ty); + ExprResult ActOnUniqueStableNameExpr(SourceLocation OpLoc, + SourceLocation LParen, + SourceLocation RParen, Expr *E); + bool CheckLoopHintExpr(Expr *E, SourceLocation Loc); ExprResult ActOnNumericConstant(const Token &Tok, Scope *UDLScope = nullptr); @@ -4712,9 +4966,36 @@ public: Expr *Idx, SourceLocation RLoc); ExprResult CreateBuiltinArraySubscriptExpr(Expr *Base, SourceLocation LLoc, Expr *Idx, SourceLocation RLoc); + + ExprResult CreateBuiltinMatrixSubscriptExpr(Expr *Base, Expr *RowIdx, + Expr *ColumnIdx, + SourceLocation RBLoc); + ExprResult ActOnOMPArraySectionExpr(Expr *Base, SourceLocation LBLoc, - Expr *LowerBound, SourceLocation ColonLoc, - Expr *Length, SourceLocation RBLoc); + Expr *LowerBound, + SourceLocation ColonLocFirst, + SourceLocation ColonLocSecond, + Expr *Length, Expr *Stride, + SourceLocation RBLoc); + ExprResult ActOnOMPArrayShapingExpr(Expr *Base, SourceLocation LParenLoc, + SourceLocation RParenLoc, + ArrayRef<Expr *> Dims, + ArrayRef<SourceRange> Brackets); + + /// Data structure for iterator expression. + struct OMPIteratorData { + IdentifierInfo *DeclIdent = nullptr; + SourceLocation DeclIdentLoc; + ParsedType Type; + OMPIteratorExpr::IteratorRange Range; + SourceLocation AssignLoc; + SourceLocation ColonLoc; + SourceLocation SecColonLoc; + }; + + ExprResult ActOnOMPIteratorExpr(Scope *S, SourceLocation IteratorKwLoc, + SourceLocation LLoc, SourceLocation RLoc, + ArrayRef<OMPIteratorData> Data); // This struct is for use by ActOnMemberAccess to allow // BuildMemberReferenceExpr to be able to reinvoke ActOnMemberAccess after @@ -4890,8 +5171,10 @@ public: LabelDecl *TheDecl); void ActOnStartStmtExpr(); - ExprResult ActOnStmtExpr(SourceLocation LPLoc, Stmt *SubStmt, - SourceLocation RPLoc); // "({..})" + ExprResult ActOnStmtExpr(Scope *S, SourceLocation LPLoc, Stmt *SubStmt, + SourceLocation RPLoc); + ExprResult BuildStmtExpr(SourceLocation LPLoc, Stmt *SubStmt, + SourceLocation RPLoc, unsigned TemplateDepth); // Handle the final expression in a statement expression. ExprResult ActOnStmtExprResult(ExprResult E); void ActOnStmtExprError(); @@ -5467,6 +5750,10 @@ public: /// it simply returns the passed in expression. ExprResult MaybeBindToTemporary(Expr *E); + /// Wrap the expression in a ConstantExpr if it is a potential immediate + /// invocation. + ExprResult CheckForImmediateInvocation(ExprResult E, FunctionDecl *Decl); + bool CompleteConstructorCall(CXXConstructorDecl *Constructor, MultiExprArg ArgsPtr, SourceLocation Loc, @@ -5494,7 +5781,8 @@ public: void CheckCompatibleReinterpretCast(QualType SrcType, QualType DestType, bool IsDereference, SourceRange Range); - /// ActOnCXXNamedCast - Parse {dynamic,static,reinterpret,const}_cast's. + /// ActOnCXXNamedCast - Parse + /// {dynamic,static,reinterpret,const,addrspace}_cast's. ExprResult ActOnCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind, SourceLocation LAngleBracketLoc, @@ -6178,15 +6466,10 @@ public: /// A diagnostic is emitted if it is not, false is returned, and /// PossibleNonPrimary will be set to true if the failure might be due to a /// non-primary expression being used as an atomic constraint. - bool CheckConstraintExpression(Expr *CE, Token NextToken = Token(), + bool CheckConstraintExpression(const Expr *CE, Token NextToken = Token(), bool *PossibleNonPrimary = nullptr, bool IsTrailingRequiresClause = false); - /// Check whether the given type-dependent expression will be the name of a - /// function or another callable function-like entity (e.g. a function - // template or overload set) for any substitution. - bool IsDependentFunctionNameExpr(Expr *E); - private: /// Caches pairs of template-like decls whose associated constraints were /// checked for subsumption and whether or not the first's constraints did in @@ -6199,6 +6482,9 @@ private: llvm::DenseMap<NamedDecl *, NormalizedConstraint *> NormalizationCache; + llvm::ContextualFoldingSet<ConstraintSatisfaction, const ASTContext &> + SatisfactionCache; + public: const NormalizedConstraint * getNormalizedAssociatedConstraints( @@ -6225,6 +6511,8 @@ public: /// \brief Check whether the given list of constraint expressions are /// satisfied (as if in a 'conjunction') given template arguments. + /// \param Template the template-like entity that triggered the constraints + /// check (either a concept or a constrained entity). /// \param ConstraintExprs a list of constraint expressions, treated as if /// they were 'AND'ed together. /// \param TemplateArgs the list of template arguments to substitute into the @@ -6236,23 +6524,10 @@ public: /// expression. /// \returns true if an error occurred and satisfaction could not be checked, /// false otherwise. - bool CheckConstraintSatisfaction(TemplateDecl *Template, - ArrayRef<const Expr *> ConstraintExprs, - ArrayRef<TemplateArgument> TemplateArgs, - SourceRange TemplateIDRange, - ConstraintSatisfaction &Satisfaction); - - bool CheckConstraintSatisfaction(ClassTemplatePartialSpecializationDecl *TD, - ArrayRef<const Expr *> ConstraintExprs, - ArrayRef<TemplateArgument> TemplateArgs, - SourceRange TemplateIDRange, - ConstraintSatisfaction &Satisfaction); - - bool CheckConstraintSatisfaction(VarTemplatePartialSpecializationDecl *TD, - ArrayRef<const Expr *> ConstraintExprs, - ArrayRef<TemplateArgument> TemplateArgs, - SourceRange TemplateIDRange, - ConstraintSatisfaction &Satisfaction); + bool CheckConstraintSatisfaction( + const NamedDecl *Template, ArrayRef<const Expr *> ConstraintExprs, + ArrayRef<TemplateArgument> TemplateArgs, + SourceRange TemplateIDRange, ConstraintSatisfaction &Satisfaction); /// \brief Check whether the given non-dependent constraint expression is /// satisfied. Returns false and updates Satisfaction with the satisfaction @@ -6263,6 +6538,17 @@ public: bool CheckConstraintSatisfaction(const Expr *ConstraintExpr, ConstraintSatisfaction &Satisfaction); + /// Check whether the given function decl's trailing requires clause is + /// satisfied, if any. Returns false and updates Satisfaction with the + /// satisfaction verdict if successful, emits a diagnostic and returns true if + /// an error occured and satisfaction could not be determined. + /// + /// \returns true if an error occurred, false otherwise. + bool CheckFunctionConstraints(const FunctionDecl *FD, + ConstraintSatisfaction &Satisfaction, + SourceLocation UsageLoc = SourceLocation()); + + /// \brief Ensure that the given template arguments satisfy the constraints /// associated with the given template, emitting a diagnostic if they do not. /// @@ -6282,13 +6568,17 @@ public: /// \brief Emit diagnostics explaining why a constraint expression was deemed /// unsatisfied. + /// \param First whether this is the first time an unsatisfied constraint is + /// diagnosed for this error. void - DiagnoseUnsatisfiedConstraint(const ConstraintSatisfaction& Satisfaction); + DiagnoseUnsatisfiedConstraint(const ConstraintSatisfaction &Satisfaction, + bool First = true); /// \brief Emit diagnostics explaining why a constraint expression was deemed /// unsatisfied. void - DiagnoseUnsatisfiedConstraint(const ASTConstraintSatisfaction& Satisfaction); + DiagnoseUnsatisfiedConstraint(const ASTConstraintSatisfaction &Satisfaction, + bool First = true); /// \brief Emit diagnostics explaining why a constraint expression was deemed /// unsatisfied because it was ill-formed. @@ -6452,6 +6742,22 @@ public: void MarkBaseAndMemberDestructorsReferenced(SourceLocation Loc, CXXRecordDecl *Record); + /// Mark destructors of virtual bases of this class referenced. In the Itanium + /// C++ ABI, this is done when emitting a destructor for any non-abstract + /// class. In the Microsoft C++ ABI, this is done any time a class's + /// destructor is referenced. + void MarkVirtualBaseDestructorsReferenced( + SourceLocation Location, CXXRecordDecl *ClassDecl, + llvm::SmallPtrSetImpl<const RecordType *> *DirectVirtualBases = nullptr); + + /// Do semantic checks to allow the complete destructor variant to be emitted + /// when the destructor is defined in another translation unit. In the Itanium + /// C++ ABI, destructor variants are emitted together. In the MS C++ ABI, they + /// can be emitted in separate TUs. To emit the complete variant, run a subset + /// of the checks performed when emitting a regular destructor. + void CheckCompleteDestructorVariant(SourceLocation CurrentLocation, + CXXDestructorDecl *Dtor); + /// The list of classes whose vtables have been used within /// this translation unit, and the source locations at which the /// first use occurred. @@ -6537,7 +6843,8 @@ public: void ActOnFinishCXXNonNestedClass(); void ActOnReenterCXXMethodParameter(Scope *S, ParmVarDecl *Param); - unsigned ActOnReenterTemplateScope(Scope *S, Decl *Template); + unsigned ActOnReenterTemplateScope(Decl *Template, + llvm::function_ref<Scope *()> EnterScope); void ActOnStartDelayedMemberDeclarations(Scope *S, Decl *Record); void ActOnStartDelayedCXXMethodDeclaration(Scope *S, Decl *Method); void ActOnDelayedCXXMethodParameter(Scope *S, Decl *Param); @@ -6630,7 +6937,7 @@ public: bool IgnoreAccess = false); bool CheckDerivedToBaseConversion(QualType Derived, QualType Base, unsigned InaccessibleBaseID, - unsigned AmbigiousBaseConvID, + unsigned AmbiguousBaseConvID, SourceLocation Loc, SourceRange Range, DeclarationName Name, CXXCastPath *BasePath, @@ -6658,7 +6965,7 @@ public: /// DiagnoseAbsenceOfOverrideControl - Diagnose if 'override' keyword was /// not used in the declaration of an overriding method. - void DiagnoseAbsenceOfOverrideControl(NamedDecl *D); + void DiagnoseAbsenceOfOverrideControl(NamedDecl *D, bool Inconsistent); /// CheckForFunctionMarkedFinal - Checks whether a virtual member function /// overrides a virtual member function marked 'final', according to @@ -6802,6 +7109,27 @@ public: bool AllowFunctionTemplates = true, bool AllowDependent = true); + enum TemplateNameIsRequiredTag { TemplateNameIsRequired }; + /// Whether and why a template name is required in this lookup. + class RequiredTemplateKind { + public: + /// Template name is required if TemplateKWLoc is valid. + RequiredTemplateKind(SourceLocation TemplateKWLoc = SourceLocation()) + : TemplateKW(TemplateKWLoc) {} + /// Template name is unconditionally required. + RequiredTemplateKind(TemplateNameIsRequiredTag) : TemplateKW() {} + + SourceLocation getTemplateKeywordLoc() const { + return TemplateKW.getValueOr(SourceLocation()); + } + bool hasTemplateKeyword() const { return getTemplateKeywordLoc().isValid(); } + bool isRequired() const { return TemplateKW != SourceLocation(); } + explicit operator bool() const { return isRequired(); } + + private: + llvm::Optional<SourceLocation> TemplateKW; + }; + enum class AssumedTemplateKind { /// This is not assumed to be a template name. None, @@ -6811,11 +7139,11 @@ public: /// functions (but no function templates). FoundFunctions, }; - bool LookupTemplateName(LookupResult &R, Scope *S, CXXScopeSpec &SS, - QualType ObjectType, bool EnteringContext, - bool &MemberOfUnknownSpecialization, - SourceLocation TemplateKWLoc = SourceLocation(), - AssumedTemplateKind *ATK = nullptr); + bool LookupTemplateName( + LookupResult &R, Scope *S, CXXScopeSpec &SS, QualType ObjectType, + bool EnteringContext, bool &MemberOfUnknownSpecialization, + RequiredTemplateKind RequiredTemplate = SourceLocation(), + AssumedTemplateKind *ATK = nullptr, bool AllowTypoCorrection = true); TemplateNameKind isTemplateName(Scope *S, CXXScopeSpec &SS, @@ -6824,7 +7152,8 @@ public: ParsedType ObjectType, bool EnteringContext, TemplateTy &Template, - bool &MemberOfUnknownSpecialization); + bool &MemberOfUnknownSpecialization, + bool Disambiguation = false); /// Try to resolve an undeclared template name as a type template. /// @@ -6873,7 +7202,8 @@ public: SourceLocation EqualLoc, ParsedType DefaultArg, bool HasTypeConstraint); - bool ActOnTypeConstraint(TemplateIdAnnotation *TypeConstraint, + bool ActOnTypeConstraint(const CXXScopeSpec &SS, + TemplateIdAnnotation *TypeConstraint, TemplateTypeParmDecl *ConstrainedParameter, SourceLocation EllipsisLoc); @@ -6884,6 +7214,10 @@ public: TemplateTypeParmDecl *ConstrainedParameter, SourceLocation EllipsisLoc); + bool AttachTypeConstraint(AutoTypeLoc TL, + NonTypeTemplateParmDecl *ConstrainedParameter, + SourceLocation EllipsisLoc); + QualType CheckNonTypeTemplateParameterType(TypeSourceInfo *&TSI, SourceLocation Loc); QualType CheckNonTypeTemplateParameterType(QualType T, SourceLocation Loc); @@ -6933,7 +7267,8 @@ public: SourceLocation DeclStartLoc, SourceLocation DeclLoc, const CXXScopeSpec &SS, TemplateIdAnnotation *TemplateId, ArrayRef<TemplateParameterList *> ParamLists, - bool IsFriend, bool &IsMemberSpecialization, bool &Invalid); + bool IsFriend, bool &IsMemberSpecialization, bool &Invalid, + bool SuppressDiagnostic = false); DeclResult CheckClassTemplate( Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc, @@ -6951,7 +7286,7 @@ public: /// Get a template argument mapping the given template parameter to itself, /// e.g. for X in \c template<int X>, this would return an expression template /// argument referencing X. - TemplateArgumentLoc getIdentityTemplateArgumentLoc(Decl *Param, + TemplateArgumentLoc getIdentityTemplateArgumentLoc(NamedDecl *Param, SourceLocation Location); void translateTemplateArguments(const ASTTemplateArgsPtr &In, @@ -7021,15 +7356,15 @@ public: const DeclarationNameInfo &NameInfo, const TemplateArgumentListInfo *TemplateArgs); - TemplateNameKind ActOnDependentTemplateName( + TemplateNameKind ActOnTemplateName( Scope *S, CXXScopeSpec &SS, SourceLocation TemplateKWLoc, const UnqualifiedId &Name, ParsedType ObjectType, bool EnteringContext, TemplateTy &Template, bool AllowInjectedClassName = false); DeclResult ActOnClassTemplateSpecialization( Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc, - SourceLocation ModulePrivateLoc, TemplateIdAnnotation &TemplateId, - const ParsedAttributesView &Attr, + SourceLocation ModulePrivateLoc, CXXScopeSpec &SS, + TemplateIdAnnotation &TemplateId, const ParsedAttributesView &Attr, MultiTemplateParamsArg TemplateParameterLists, SkipBodyInfo *SkipBody = nullptr); @@ -7261,7 +7596,17 @@ public: SourceLocation KeywordLoc, NestedNameSpecifierLoc QualifierLoc, const IdentifierInfo &II, - SourceLocation IILoc); + SourceLocation IILoc, + TypeSourceInfo **TSI, + bool DeducedTSTContext); + + QualType CheckTypenameType(ElaboratedTypeKeyword Keyword, + SourceLocation KeywordLoc, + NestedNameSpecifierLoc QualifierLoc, + const IdentifierInfo &II, + SourceLocation IILoc, + bool DeducedTSTContext = true); + TypeSourceInfo *RebuildTypeInCurrentInstantiation(TypeSourceInfo *T, SourceLocation Loc, @@ -7281,11 +7626,52 @@ public: const TemplateArgument *Args, unsigned NumArgs); - // Concepts + //===--------------------------------------------------------------------===// + // C++ Concepts + //===--------------------------------------------------------------------===// Decl *ActOnConceptDefinition( Scope *S, MultiTemplateParamsArg TemplateParameterLists, IdentifierInfo *Name, SourceLocation NameLoc, Expr *ConstraintExpr); + RequiresExprBodyDecl * + ActOnStartRequiresExpr(SourceLocation RequiresKWLoc, + ArrayRef<ParmVarDecl *> LocalParameters, + Scope *BodyScope); + void ActOnFinishRequiresExpr(); + concepts::Requirement *ActOnSimpleRequirement(Expr *E); + concepts::Requirement *ActOnTypeRequirement( + SourceLocation TypenameKWLoc, CXXScopeSpec &SS, SourceLocation NameLoc, + IdentifierInfo *TypeName, TemplateIdAnnotation *TemplateId); + concepts::Requirement *ActOnCompoundRequirement(Expr *E, + SourceLocation NoexceptLoc); + concepts::Requirement * + ActOnCompoundRequirement( + Expr *E, SourceLocation NoexceptLoc, CXXScopeSpec &SS, + TemplateIdAnnotation *TypeConstraint, unsigned Depth); + concepts::Requirement *ActOnNestedRequirement(Expr *Constraint); + concepts::ExprRequirement * + BuildExprRequirement( + Expr *E, bool IsSatisfied, SourceLocation NoexceptLoc, + concepts::ExprRequirement::ReturnTypeRequirement ReturnTypeRequirement); + concepts::ExprRequirement * + BuildExprRequirement( + concepts::Requirement::SubstitutionDiagnostic *ExprSubstDiag, + bool IsSatisfied, SourceLocation NoexceptLoc, + concepts::ExprRequirement::ReturnTypeRequirement ReturnTypeRequirement); + concepts::TypeRequirement *BuildTypeRequirement(TypeSourceInfo *Type); + concepts::TypeRequirement * + BuildTypeRequirement( + concepts::Requirement::SubstitutionDiagnostic *SubstDiag); + concepts::NestedRequirement *BuildNestedRequirement(Expr *E); + concepts::NestedRequirement * + BuildNestedRequirement( + concepts::Requirement::SubstitutionDiagnostic *SubstDiag); + ExprResult ActOnRequiresExpr(SourceLocation RequiresKWLoc, + RequiresExprBodyDecl *Body, + ArrayRef<ParmVarDecl *> LocalParameters, + ArrayRef<concepts::Requirement *> Requirements, + SourceLocation ClosingBraceLoc); + //===--------------------------------------------------------------------===// // C++ Variadic Templates (C++0x [temp.variadic]) //===--------------------------------------------------------------------===// @@ -7794,10 +8180,12 @@ public: DeduceAutoResult DeduceAutoType(TypeSourceInfo *AutoType, Expr *&Initializer, QualType &Result, - Optional<unsigned> DependentDeductionDepth = None); + Optional<unsigned> DependentDeductionDepth = None, + bool IgnoreConstraints = false); DeduceAutoResult DeduceAutoType(TypeLoc AutoTypeLoc, Expr *&Initializer, QualType &Result, - Optional<unsigned> DependentDeductionDepth = None); + Optional<unsigned> DependentDeductionDepth = None, + bool IgnoreConstraints = false); void DiagnoseAutoDeductionFailure(VarDecl *VDecl, Expr *Init); bool DeduceReturnType(FunctionDecl *FD, SourceLocation Loc, bool Diagnose = true); @@ -7822,12 +8210,10 @@ public: SourceLocation ReturnLoc, Expr *&RetExpr, AutoType *AT); - FunctionTemplateDecl *getMoreSpecializedTemplate(FunctionTemplateDecl *FT1, - FunctionTemplateDecl *FT2, - SourceLocation Loc, - TemplatePartialOrderingContext TPOC, - unsigned NumCallArguments1, - unsigned NumCallArguments2); + FunctionTemplateDecl *getMoreSpecializedTemplate( + FunctionTemplateDecl *FT1, FunctionTemplateDecl *FT2, SourceLocation Loc, + TemplatePartialOrderingContext TPOC, unsigned NumCallArguments1, + unsigned NumCallArguments2, bool Reversed = false); UnresolvedSetIterator getMostSpecialized(UnresolvedSetIterator SBegin, UnresolvedSetIterator SEnd, TemplateSpecCandidateSet &FailedCandidates, @@ -7932,6 +8318,13 @@ public: /// template which was deferred until it was needed. ExceptionSpecInstantiation, + /// We are instantiating a requirement of a requires expression. + RequirementInstantiation, + + /// We are checking the satisfaction of a nested requirement of a requires + /// expression. + NestedRequirementConstraintsCheck, + /// We are declaring an implicit special member function. DeclaringSpecialMember, @@ -7962,6 +8355,12 @@ public: /// We are rewriting a comparison operator in terms of an operator<=>. RewritingOperatorAsSpaceship, + /// We are initializing a structured binding. + InitializingStructuredBinding, + + /// We are marking a class as __dllexport. + MarkingClassDllexported, + /// Added for Template instantiation observation. /// Memoization means we are _not_ instantiating a template because /// it is already instantiated (but we entered a context where we @@ -8253,6 +8652,19 @@ public: ParameterMappingSubstitution, NamedDecl *Template, SourceRange InstantiationRange); + /// \brief Note that we are substituting template arguments into a part of + /// a requirement of a requires expression. + InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, + concepts::Requirement *Req, + sema::TemplateDeductionInfo &DeductionInfo, + SourceRange InstantiationRange = SourceRange()); + + /// \brief Note that we are checking the satisfaction of the constraint + /// expression inside of a nested requirement. + InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation, + concepts::NestedRequirement *Req, ConstraintsCheck, + SourceRange InstantiationRange = SourceRange()); + /// Note that we have finished instantiating this template. void Clear(); @@ -8451,9 +8863,17 @@ public: S.VTableUses.swap(SavedVTableUses); // Restore the set of pending implicit instantiations. - assert(S.PendingInstantiations.empty() && - "PendingInstantiations should be empty before it is discarded."); - S.PendingInstantiations.swap(SavedPendingInstantiations); + if (S.TUKind != TU_Prefix || !S.LangOpts.PCHInstantiateTemplates) { + assert(S.PendingInstantiations.empty() && + "PendingInstantiations should be empty before it is discarded."); + S.PendingInstantiations.swap(SavedPendingInstantiations); + } else { + // Template instantiations in the PCH may be delayed until the TU. + S.PendingInstantiations.swap(SavedPendingInstantiations); + S.PendingInstantiations.insert(S.PendingInstantiations.end(), + SavedPendingInstantiations.begin(), + SavedPendingInstantiations.end()); + } } private: @@ -8682,6 +9102,8 @@ public: TemplateArgumentListInfo &Result, const MultiLevelTemplateArgumentList &TemplateArgs); + bool InstantiateDefaultArgument(SourceLocation CallLoc, FunctionDecl *FD, + ParmVarDecl *Param); void InstantiateExceptionSpec(SourceLocation PointOfInstantiation, FunctionDecl *Function); bool CheckInstantiatedFunctionTemplateConstraints( @@ -9124,8 +9546,8 @@ public: QualType DestType, QualType SrcType, Expr *&SrcExpr, bool Diagnose = true); - bool ConversionToObjCStringLiteralCheck(QualType DstType, Expr *&SrcExpr, - bool Diagnose = true); + bool CheckConversionToObjCLiteral(QualType DstType, Expr *&SrcExpr, + bool Diagnose = true); bool checkInitMethod(ObjCMethodDecl *method, QualType receiverTypeIfCall); @@ -9235,6 +9657,18 @@ public: void ActOnPragmaDetectMismatch(SourceLocation Loc, StringRef Name, StringRef Value); + /// Are precise floating point semantics currently enabled? + bool isPreciseFPEnabled() { + return !CurFPFeatures.getAllowFPReassociate() && + !CurFPFeatures.getNoSignedZero() && + !CurFPFeatures.getAllowReciprocal() && + !CurFPFeatures.getAllowApproxFunc(); + } + + /// ActOnPragmaFloatControl - Call on well-formed \#pragma float_control + void ActOnPragmaFloatControl(SourceLocation Loc, PragmaMsStackAction Action, + PragmaFloatControlKind Value); + /// ActOnPragmaUnused - Called on well-formed '\#pragma unused'. void ActOnPragmaUnused(const Token &Identifier, Scope *curScope, @@ -9271,11 +9705,21 @@ public: /// ActOnPragmaFPContract - Called on well formed /// \#pragma {STDC,OPENCL} FP_CONTRACT and /// \#pragma clang fp contract - void ActOnPragmaFPContract(LangOptions::FPContractModeKind FPC); + void ActOnPragmaFPContract(SourceLocation Loc, LangOptions::FPModeKind FPC); + + /// Called on well formed + /// \#pragma clang fp reassociate + void ActOnPragmaFPReassociate(SourceLocation Loc, bool IsEnabled); /// ActOnPragmaFenvAccess - Called on well formed /// \#pragma STDC FENV_ACCESS - void ActOnPragmaFEnvAccess(LangOptions::FEnvAccessModeKind FPC); + void ActOnPragmaFEnvAccess(SourceLocation Loc, bool IsEnabled); + + /// Called to set rounding mode for floating point operations. + void setRoundingMode(SourceLocation Loc, llvm::RoundingMode); + + /// Called to set exception behavior for floating point operations. + void setExceptionMode(SourceLocation Loc, LangOptions::FPExceptionModeKind); /// AddAlignmentAttributesForRecord - Adds any needed alignment attributes to /// a the record decl, to handle '\#pragma pack' and '\#pragma options align'. @@ -9413,6 +9857,9 @@ public: void CheckCompletedCoroutineBody(FunctionDecl *FD, Stmt *&Body); ClassTemplateDecl *lookupCoroutineTraits(SourceLocation KwLoc, SourceLocation FuncLoc); + /// Check that the expression co_await promise.final_suspend() shall not be + /// potentially-throwing. + bool checkFinalSuspendNoThrow(const Stmt *FinalSuspend); //===--------------------------------------------------------------------===// // OpenCL extensions. @@ -9443,7 +9890,7 @@ public: std::string getOpenCLExtensionsFromExtMap(T* FT, MapT &Map); void setCurrentOpenCLExtension(llvm::StringRef Ext) { - CurrOpenCLExtension = Ext; + CurrOpenCLExtension = std::string(Ext); } /// Set OpenCL extensions for a type which can only be used when these @@ -9511,22 +9958,6 @@ private: /// Pop OpenMP function region for non-capturing function. void popOpenMPFunctionRegion(const sema::FunctionScopeInfo *OldFSI); - /// Check whether we're allowed to call Callee from the current function. - void checkOpenMPDeviceFunction(SourceLocation Loc, FunctionDecl *Callee, - bool CheckForDelayedContext = true); - - /// Check whether we're allowed to call Callee from the current function. - void checkOpenMPHostFunction(SourceLocation Loc, FunctionDecl *Callee, - bool CheckCaller = true); - - /// Check if the expression is allowed to be used in expressions for the - /// OpenMP devices. - void checkOpenMPDeviceExpr(const Expr *E); - - /// Finishes analysis of the deferred functions calls that may be declared as - /// host/nohost during device/host compilation. - void finalizeOpenMPDelayedAnalysis(); - /// Checks if a type or a declaration is disabled due to the owning extension /// being disabled, and emits diagnostic messages if it is disabled. /// \param D type or declaration to be checked. @@ -9542,17 +9973,54 @@ private: MapT &Map, unsigned Selector = 0, SourceRange SrcRange = SourceRange()); - /// Marks all the functions that might be required for the currently active - /// OpenMP context. - void markOpenMPDeclareVariantFuncsReferenced(SourceLocation Loc, - FunctionDecl *Func, - bool MightBeOdrUse); + /// Helper to keep information about the current `omp begin/end declare + /// variant` nesting. + struct OMPDeclareVariantScope { + /// The associated OpenMP context selector. + OMPTraitInfo *TI; + + /// The associated OpenMP context selector mangling. + std::string NameSuffix; + + OMPDeclareVariantScope(OMPTraitInfo &TI); + }; + + /// The current `omp begin/end declare variant` scopes. + SmallVector<OMPDeclareVariantScope, 4> OMPDeclareVariantScopes; + + /// The declarator \p D defines a function in the scope \p S which is nested + /// in an `omp begin/end declare variant` scope. In this method we create a + /// declaration for \p D and rename \p D according to the OpenMP context + /// selector of the surrounding scope. + FunctionDecl * + ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope(Scope *S, + Declarator &D); + + /// Register \p FD as specialization of \p BaseFD in the current `omp + /// begin/end declare variant` scope. + void ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope( + FunctionDecl *FD, FunctionDecl *BaseFD); public: - /// Struct to store the context selectors info for declare variant directive. - using OMPCtxStringType = SmallString<8>; - using OMPCtxSelectorData = - OpenMPCtxSelectorData<SmallVector<OMPCtxStringType, 4>, ExprResult>; + + /// Can we exit a scope at the moment. + bool isInOpenMPDeclareVariantScope() { + return !OMPDeclareVariantScopes.empty(); + } + + /// Given the potential call expression \p Call, determine if there is a + /// specialization via the OpenMP declare variant mechanism available. If + /// there is, return the specialized call expression, otherwise return the + /// original \p Call. + ExprResult ActOnOpenMPCall(ExprResult Call, Scope *Scope, + SourceLocation LParenLoc, MultiExprArg ArgExprs, + SourceLocation RParenLoc, Expr *ExecConfig); + + /// Handle a `omp begin declare variant`. + void ActOnOpenMPBeginDeclareVariant(SourceLocation Loc, OMPTraitInfo &TI); + + /// Handle a `omp end declare variant`. + void ActOnOpenMPEndDeclareVariant(); /// Checks if the variant/multiversion functions are compatible. bool areMultiversionVariantFunctionsCompatible( @@ -9594,7 +10062,8 @@ public: /// 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 isOpenMPPrivateDecl(const ValueDecl *D, unsigned Level) const; + OpenMPClauseKind isOpenMPPrivateDecl(ValueDecl *D, unsigned Level, + unsigned CapLevel) const; /// Sets OpenMP capture kind (OMPC_private, OMPC_firstprivate, OMPC_map etc.) /// for \p FD based on DSA for the provided corresponding captured declaration @@ -9604,7 +10073,15 @@ public: /// 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 isOpenMPTargetCapturedDecl(const ValueDecl *D, unsigned Level) const; + bool isOpenMPTargetCapturedDecl(const ValueDecl *D, unsigned Level, + unsigned CaptureLevel) const; + + /// Check if the specified global variable must be captured by outer capture + /// regions. + /// \param Level Relative level of nested OpenMP construct for that + /// the check is performed. + bool isOpenMPGlobalCapturedDecl(ValueDecl *D, unsigned Level, + unsigned CaptureLevel) const; ExprResult PerformOpenMPImplicitIntegerConversion(SourceLocation OpLoc, Expr *Op); @@ -9711,6 +10188,11 @@ public: void checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D, SourceLocation IdLoc = SourceLocation()); + /// Finishes analysis of the deferred functions calls that may be declared as + /// host/nohost during device/host compilation. + void finalizeOpenMPDelayedAnalysis(const FunctionDecl *Caller, + const FunctionDecl *Callee, + SourceLocation Loc); /// Return true inside OpenMP declare target region. bool isInOpenMPDeclareTargetContext() const { return DeclareTargetNestingLevel > 0; @@ -9828,6 +10310,14 @@ public: StmtResult ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses, SourceLocation StartLoc, SourceLocation EndLoc); + /// Called on well-formed '\#pragma omp depobj'. + StmtResult ActOnOpenMPDepobjDirective(ArrayRef<OMPClause *> Clauses, + SourceLocation StartLoc, + SourceLocation EndLoc); + /// Called on well-formed '\#pragma omp scan'. + StmtResult ActOnOpenMPScanDirective(ArrayRef<OMPClause *> Clauses, + SourceLocation StartLoc, + SourceLocation EndLoc); /// Called on well-formed '\#pragma omp ordered' after parsing of the /// associated statement. StmtResult ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses, @@ -10007,7 +10497,8 @@ public: /// Checks that the specified declaration matches requirements for the linear /// decls. bool CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc, - OpenMPLinearClauseKind LinKind, QualType Type); + OpenMPLinearClauseKind LinKind, QualType Type, + bool IsDeclareSimd = false); /// Called on well-formed '\#pragma omp declare simd' after parsing of /// the associated method/function. @@ -10023,10 +10514,12 @@ public: /// applied to. /// \param VariantRef Expression that references the variant function, which /// must be used instead of the original one, specified in \p DG. + /// \param TI The trait info object representing the match clause. /// \returns None, if the function/variant function are not compatible with /// the pragma, pair of original function/variant ref expression otherwise. - Optional<std::pair<FunctionDecl *, Expr *>> checkOpenMPDeclareVariantFunction( - DeclGroupPtrTy DG, Expr *VariantRef, SourceRange SR); + Optional<std::pair<FunctionDecl *, Expr *>> + checkOpenMPDeclareVariantFunction(DeclGroupPtrTy DG, Expr *VariantRef, + OMPTraitInfo &TI, SourceRange SR); /// Called on well-formed '\#pragma omp declare variant' after parsing of /// the associated method/function. @@ -10034,11 +10527,9 @@ public: /// applied to. /// \param VariantRef Expression that references the variant function, which /// must be used instead of the original one, specified in \p DG. - /// \param Data Set of context-specific data for the specified context - /// selector. + /// \param TI The context traits associated with the function variant. void ActOnOpenMPDeclareVariantDirective(FunctionDecl *FD, Expr *VariantRef, - SourceRange SR, - ArrayRef<OMPCtxSelectorData> Data); + OMPTraitInfo &TI, SourceRange SR); OMPClause *ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, @@ -10097,6 +10588,10 @@ public: OMPClause *ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc); + /// Called on well-formed 'detach' clause. + OMPClause *ActOnOpenMPDetachClause(Expr *Evt, SourceLocation StartLoc, + SourceLocation LParenLoc, + SourceLocation EndLoc); OMPClause *ActOnOpenMPSimpleClause(OpenMPClauseKind Kind, unsigned Argument, @@ -10105,7 +10600,7 @@ public: SourceLocation LParenLoc, SourceLocation EndLoc); /// Called on well-formed 'default' clause. - OMPClause *ActOnOpenMPDefaultClause(OpenMPDefaultClauseKind Kind, + OMPClause *ActOnOpenMPDefaultClause(llvm::omp::DefaultKind Kind, SourceLocation KindLoc, SourceLocation StartLoc, SourceLocation LParenLoc, @@ -10116,6 +10611,18 @@ public: SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc); + /// Called on well-formed 'order' clause. + OMPClause *ActOnOpenMPOrderClause(OpenMPOrderClauseKind Kind, + SourceLocation KindLoc, + SourceLocation StartLoc, + SourceLocation LParenLoc, + SourceLocation EndLoc); + /// Called on well-formed 'update' clause. + OMPClause *ActOnOpenMPUpdateClause(OpenMPDependClauseKind Kind, + SourceLocation KindLoc, + SourceLocation StartLoc, + SourceLocation LParenLoc, + SourceLocation EndLoc); OMPClause *ActOnOpenMPSingleExprWithArgClause( OpenMPClauseKind Kind, ArrayRef<unsigned> Arguments, Expr *Expr, @@ -10155,6 +10662,21 @@ public: /// Called on well-formed 'seq_cst' clause. OMPClause *ActOnOpenMPSeqCstClause(SourceLocation StartLoc, SourceLocation EndLoc); + /// Called on well-formed 'acq_rel' clause. + OMPClause *ActOnOpenMPAcqRelClause(SourceLocation StartLoc, + SourceLocation EndLoc); + /// Called on well-formed 'acquire' clause. + OMPClause *ActOnOpenMPAcquireClause(SourceLocation StartLoc, + SourceLocation EndLoc); + /// Called on well-formed 'release' clause. + OMPClause *ActOnOpenMPReleaseClause(SourceLocation StartLoc, + SourceLocation EndLoc); + /// Called on well-formed 'relaxed' clause. + OMPClause *ActOnOpenMPRelaxedClause(SourceLocation StartLoc, + SourceLocation EndLoc); + /// Called on well-formed 'destroy' clause. + OMPClause *ActOnOpenMPDestroyClause(SourceLocation StartLoc, + SourceLocation EndLoc); /// Called on well-formed 'threads' clause. OMPClause *ActOnOpenMPThreadsClause(SourceLocation StartLoc, SourceLocation EndLoc); @@ -10186,13 +10708,23 @@ public: SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc); OMPClause *ActOnOpenMPVarListClause( - OpenMPClauseKind Kind, ArrayRef<Expr *> Vars, Expr *TailExpr, + OpenMPClauseKind Kind, ArrayRef<Expr *> Vars, Expr *DepModOrTailExpr, const OMPVarListLocTy &Locs, SourceLocation ColonLoc, CXXScopeSpec &ReductionOrMapperIdScopeSpec, DeclarationNameInfo &ReductionOrMapperId, int ExtraModifier, ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, ArrayRef<SourceLocation> MapTypeModifiersLoc, bool IsMapTypeImplicit, - SourceLocation DepLinMapLastLoc); + SourceLocation ExtraModifierLoc); + /// Called on well-formed 'inclusive' clause. + OMPClause *ActOnOpenMPInclusiveClause(ArrayRef<Expr *> VarList, + SourceLocation StartLoc, + SourceLocation LParenLoc, + SourceLocation EndLoc); + /// Called on well-formed 'exclusive' clause. + OMPClause *ActOnOpenMPExclusiveClause(ArrayRef<Expr *> VarList, + SourceLocation StartLoc, + SourceLocation LParenLoc, + SourceLocation EndLoc); /// Called on well-formed 'allocate' clause. OMPClause * ActOnOpenMPAllocateClause(Expr *Allocator, ArrayRef<Expr *> VarList, @@ -10220,9 +10752,10 @@ public: SourceLocation EndLoc); /// Called on well-formed 'reduction' clause. OMPClause *ActOnOpenMPReductionClause( - ArrayRef<Expr *> VarList, SourceLocation StartLoc, - SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, - CXXScopeSpec &ReductionIdScopeSpec, + ArrayRef<Expr *> VarList, OpenMPReductionClauseModifier Modifier, + SourceLocation StartLoc, SourceLocation LParenLoc, + SourceLocation ModifierLoc, SourceLocation ColonLoc, + SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, ArrayRef<Expr *> UnresolvedReductions = llvm::None); /// Called on well-formed 'task_reduction' clause. @@ -10267,15 +10800,21 @@ public: SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc); + /// Called on well-formed 'depobj' pseudo clause. + OMPClause *ActOnOpenMPDepobjClause(Expr *Depobj, SourceLocation StartLoc, + SourceLocation LParenLoc, + SourceLocation EndLoc); /// Called on well-formed 'depend' clause. OMPClause * - ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind, SourceLocation DepLoc, - SourceLocation ColonLoc, ArrayRef<Expr *> VarList, - SourceLocation StartLoc, SourceLocation LParenLoc, - SourceLocation EndLoc); + ActOnOpenMPDependClause(Expr *DepModifier, OpenMPDependClauseKind DepKind, + SourceLocation DepLoc, SourceLocation ColonLoc, + ArrayRef<Expr *> VarList, SourceLocation StartLoc, + SourceLocation LParenLoc, SourceLocation EndLoc); /// Called on well-formed 'device' clause. - OMPClause *ActOnOpenMPDeviceClause(Expr *Device, SourceLocation StartLoc, + OMPClause *ActOnOpenMPDeviceClause(OpenMPDeviceClauseModifier Modifier, + Expr *Device, SourceLocation StartLoc, SourceLocation LParenLoc, + SourceLocation ModifierLoc, SourceLocation EndLoc); /// Called on well-formed 'map' clause. OMPClause * @@ -10324,6 +10863,9 @@ public: /// Called on well-formed 'use_device_ptr' clause. OMPClause *ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList, const OMPVarListLocTy &Locs); + /// Called on well-formed 'use_device_addr' clause. + OMPClause *ActOnOpenMPUseDeviceAddrClause(ArrayRef<Expr *> VarList, + const OMPVarListLocTy &Locs); /// Called on well-formed 'is_device_ptr' clause. OMPClause *ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList, const OMPVarListLocTy &Locs); @@ -10333,6 +10875,27 @@ public: SourceLocation LParenLoc, SourceLocation EndLoc); + /// Data for list of allocators. + struct UsesAllocatorsData { + /// Allocator. + Expr *Allocator = nullptr; + /// Allocator traits. + Expr *AllocatorTraits = nullptr; + /// Locations of '(' and ')' symbols. + SourceLocation LParenLoc, RParenLoc; + }; + /// Called on well-formed 'uses_allocators' clause. + OMPClause *ActOnOpenMPUsesAllocatorClause(SourceLocation StartLoc, + SourceLocation LParenLoc, + SourceLocation EndLoc, + ArrayRef<UsesAllocatorsData> Data); + /// Called on well-formed 'affinity' clause. + OMPClause *ActOnOpenMPAffinityClause(SourceLocation StartLoc, + SourceLocation LParenLoc, + SourceLocation ColonLoc, + SourceLocation EndLoc, Expr *Modifier, + ArrayRef<Expr *> Locators); + /// The kind of conversion being performed. enum CheckedConversionKind { /// An implicit conversion. @@ -10389,9 +10952,8 @@ public: bool Diagnose = true); // DefaultLvalueConversion - performs lvalue-to-rvalue conversion on - // the operand. This is DefaultFunctionArrayLvalueConversion, - // except that it assumes the operand isn't of function or array - // type. + // the operand. This function is a no-op if the operand has a function type + // or an array type. ExprResult DefaultLvalueConversion(Expr *E); // DefaultArgumentPromotion (C99 6.5.2.2p6). Used for function calls that @@ -10499,6 +11061,11 @@ public: /// are not compatible, but we accept them as an extension. IncompatiblePointer, + /// IncompatibleFunctionPointer - The assignment is between two function + /// pointers types that are not compatible, but we accept them as an + /// extension. + IncompatibleFunctionPointer, + /// IncompatiblePointerSign - The assignment is between two pointers types /// which point to integers which have a different sign, but are otherwise /// identical. This is a subset of the above, but broken out because it's by @@ -10728,6 +11295,13 @@ public: QualType CheckVectorLogicalOperands(ExprResult &LHS, ExprResult &RHS, SourceLocation Loc); + /// Type checking for matrix binary operators. + QualType CheckMatrixElementwiseOperands(ExprResult &LHS, ExprResult &RHS, + SourceLocation Loc, + bool IsCompAssign); + QualType CheckMatrixMultiplyOperands(ExprResult &LHS, ExprResult &RHS, + SourceLocation Loc, bool IsCompAssign); + bool areLaxCompatibleVectorTypes(QualType srcType, QualType destType); bool isLaxVectorConversion(QualType srcType, QualType destType); @@ -11041,18 +11615,6 @@ public: /* Caller = */ FunctionDeclAndLoc> DeviceKnownEmittedFns; - /// A partial call graph maintained during CUDA/OpenMP device code compilation - /// to support deferred diagnostics. - /// - /// Functions are only added here if, at the time they're considered, they are - /// not known-emitted. As soon as we discover that a function is - /// known-emitted, we remove it and everything it transitively calls from this - /// set and add those functions to DeviceKnownEmittedFns. - llvm::DenseMap</* Caller = */ CanonicalDeclPtr<FunctionDecl>, - /* Callees = */ llvm::MapVector<CanonicalDeclPtr<FunctionDecl>, - SourceLocation>> - DeviceCallGraph; - /// Diagnostic builder for CUDA/OpenMP devices errors which may or may not be /// deferred. /// @@ -11127,14 +11689,6 @@ public: llvm::Optional<unsigned> PartialDiagId; }; - /// Indicate that this function (and thus everything it transtively calls) - /// will be codegen'ed, and emit any deferred diagnostics on this function and - /// its (transitive) callees. - void markKnownEmitted( - Sema &S, FunctionDecl *OrigCaller, FunctionDecl *OrigCallee, - SourceLocation OrigLoc, - const llvm::function_ref<bool(Sema &, FunctionDecl *)> IsKnownEmitted); - /// Creates a DeviceDiagBuilder that emits the diagnostic if the current context /// is "used as device code". /// @@ -11193,6 +11747,10 @@ public: DeviceDiagBuilder targetDiag(SourceLocation Loc, unsigned DiagID); + /// Check if the expression is allowed to be used in expressions for the + /// offloading devices. + void checkDeviceDecl(const ValueDecl *D, SourceLocation Loc); + enum CUDAFunctionTarget { CFT_Device, CFT_Global, @@ -11215,6 +11773,8 @@ public: return IdentifyCUDATarget(dyn_cast<FunctionDecl>(CurContext)); } + static bool isCUDAImplicitHostDeviceFunction(const FunctionDecl *D); + // CUDA function call preference. Must be ordered numerically from // worst to best. enum CUDAFunctionPreference { @@ -11253,6 +11813,10 @@ public: void maybeAddCUDAHostDeviceAttrs(FunctionDecl *FD, const LookupResult &Previous); + /// May add implicit CUDAConstantAttr attribute to VD, depending on VD + /// and current compilation settings. + void MaybeAddCUDAConstantAttr(VarDecl *VD); + public: /// Check whether we're allowed to call Callee from the current context. /// @@ -11270,12 +11834,13 @@ public: /// - Otherwise, returns true without emitting any diagnostics. bool CheckCUDACall(SourceLocation Loc, FunctionDecl *Callee); + void CUDACheckLambdaCapture(CXXMethodDecl *D, const sema::Capture &Capture); + /// Set __device__ or __host__ __device__ attributes on the given lambda /// operator() method. /// - /// CUDA lambdas declared inside __device__ or __global__ functions inherit - /// the __device__ attribute. Similarly, lambdas inside __host__ __device__ - /// functions become __host__ __device__ themselves. + /// CUDA lambdas by default is host device function unless it has explicit + /// host or device attribute. void CUDASetLambdaAttrs(CXXMethodDecl *Method); /// Finds a function in \p Matches with highest calling priority @@ -11416,7 +11981,13 @@ public: IdentifierInfo *II, SourceLocation OpenParLoc); void CodeCompleteInitializer(Scope *S, Decl *D); - void CodeCompleteAfterIf(Scope *S); + /// Trigger code completion for a record of \p BaseType. \p InitExprs are + /// expressions in the initializer list seen so far and \p D is the current + /// Designation being parsed. + void CodeCompleteDesignator(const QualType BaseType, + llvm::ArrayRef<Expr *> InitExprs, + const Designation &D); + void CodeCompleteAfterIf(Scope *S, bool IsBracedThen); void CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS, bool EnteringContext, bool IsUsingDeclaration, QualType BaseType, @@ -11432,6 +12003,7 @@ public: void CodeCompleteLambdaIntroducer(Scope *S, LambdaIntroducer &Intro, bool AfterAmpersand); + void CodeCompleteAfterFunctionEquals(Declarator &D); void CodeCompleteObjCAtDirective(Scope *S); void CodeCompleteObjCAtVisibility(Scope *S); @@ -11545,27 +12117,50 @@ private: ExprResult CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID, CallExpr *TheCall); + + bool CheckTSBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, + CallExpr *TheCall); + void checkFortifiedBuiltinMemoryFunction(FunctionDecl *FD, CallExpr *TheCall); bool CheckARMBuiltinExclusiveCall(unsigned BuiltinID, CallExpr *TheCall, unsigned MaxWidth); - bool CheckNeonBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); + bool CheckNeonBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, + CallExpr *TheCall); bool CheckMVEBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); - bool CheckARMBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); - - bool CheckAArch64BuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); + bool CheckSVEBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); + bool CheckCDEBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, + CallExpr *TheCall); + bool CheckARMCoprocessorImmediate(const TargetInfo &TI, const Expr *CoprocArg, + bool WantCDE); + bool CheckARMBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, + CallExpr *TheCall); + + bool CheckAArch64BuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, + CallExpr *TheCall); bool CheckBPFBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); bool CheckHexagonBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); - bool CheckHexagonBuiltinCpu(unsigned BuiltinID, CallExpr *TheCall); bool CheckHexagonBuiltinArgument(unsigned BuiltinID, CallExpr *TheCall); - bool CheckMipsBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); - bool CheckMipsBuiltinCpu(unsigned BuiltinID, CallExpr *TheCall); + bool CheckMipsBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, + CallExpr *TheCall); + bool CheckMipsBuiltinCpu(const TargetInfo &TI, unsigned BuiltinID, + CallExpr *TheCall); bool CheckMipsBuiltinArgument(unsigned BuiltinID, CallExpr *TheCall); bool CheckSystemZBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); bool CheckX86BuiltinRoundingOrSAE(unsigned BuiltinID, CallExpr *TheCall); bool CheckX86BuiltinGatherScatterScale(unsigned BuiltinID, CallExpr *TheCall); - bool CheckX86BuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); - bool CheckPPCBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); + bool CheckX86BuiltinTileArguments(unsigned BuiltinID, CallExpr *TheCall); + bool CheckX86BuiltinTileArgumentsRange(CallExpr *TheCall, + ArrayRef<int> ArgNums); + bool CheckX86BuiltinTileArgumentsRange(CallExpr *TheCall, int ArgNum); + bool CheckX86BuiltinTileDuplicate(CallExpr *TheCall, ArrayRef<int> ArgNums); + bool CheckX86BuiltinTileRangeAndDuplicate(CallExpr *TheCall, + ArrayRef<int> ArgNums); + bool CheckX86BuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, + CallExpr *TheCall); + bool CheckPPCBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, + CallExpr *TheCall); + bool CheckAMDGCNBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); bool SemaBuiltinVAStart(unsigned BuiltinID, CallExpr *TheCall); bool SemaBuiltinVAStartARMMicrosoft(CallExpr *Call); @@ -11601,12 +12196,23 @@ private: bool SemaBuiltinConstantArgMultiple(CallExpr *TheCall, int ArgNum, unsigned Multiple); bool SemaBuiltinConstantArgPower2(CallExpr *TheCall, int ArgNum); - bool SemaBuiltinConstantArgShiftedByte(CallExpr *TheCall, int ArgNum); - bool SemaBuiltinConstantArgShiftedByteOrXXFF(CallExpr *TheCall, int ArgNum); + bool SemaBuiltinConstantArgShiftedByte(CallExpr *TheCall, int ArgNum, + unsigned ArgBits); + bool SemaBuiltinConstantArgShiftedByteOrXXFF(CallExpr *TheCall, int ArgNum, + unsigned ArgBits); bool SemaBuiltinARMSpecialReg(unsigned BuiltinID, CallExpr *TheCall, int ArgNum, unsigned ExpectedFieldNum, bool AllowName); bool SemaBuiltinARMMemoryTaggingCall(unsigned BuiltinID, CallExpr *TheCall); + + // Matrix builtin handling. + ExprResult SemaBuiltinMatrixTranspose(CallExpr *TheCall, + ExprResult CallResult); + ExprResult SemaBuiltinMatrixColumnMajorLoad(CallExpr *TheCall, + ExprResult CallResult); + ExprResult SemaBuiltinMatrixColumnMajorStore(CallExpr *TheCall, + ExprResult CallResult); + public: enum FormatStringType { FST_Scanf, @@ -11805,6 +12411,13 @@ public: return DC; } + /// Determine the number of levels of enclosing template parameters. This is + /// only usable while parsing. Note that this does not include dependent + /// contexts in which no template parameters have yet been declared, such as + /// in a terse function template or generic lambda before the first 'auto' is + /// encountered. + unsigned getTemplateDepth(Scope *S) const; + /// To be used for checking whether the arguments being passed to /// function exceeds the number of parameters expected for it. static bool TooManyArguments(size_t NumParams, size_t NumArgs, @@ -11904,6 +12517,40 @@ public: ConstructorDestructor, BuiltinFunction }; + /// Creates a DeviceDiagBuilder that emits the diagnostic if the current + /// context is "used as device code". + /// + /// - If CurLexicalContext is a kernel function or it is known that the + /// function will be emitted for the device, emits the diagnostics + /// immediately. + /// - If CurLexicalContext is a function and we are compiling + /// for the device, but we don't know that this function will be codegen'ed + /// for devive yet, creates a diagnostic which is emitted if and when we + /// realize that the function will be codegen'ed. + /// + /// Example usage: + /// + /// Diagnose __float128 type usage only from SYCL device code if the current + /// target doesn't support it + /// if (!S.Context.getTargetInfo().hasFloat128Type() && + /// S.getLangOpts().SYCLIsDevice) + /// SYCLDiagIfDeviceCode(Loc, diag::err_type_unsupported) << "__float128"; + DeviceDiagBuilder SYCLDiagIfDeviceCode(SourceLocation Loc, unsigned DiagID); + + /// Check whether we're allowed to call Callee from the current context. + /// + /// - If the call is never allowed in a semantically-correct program + /// emits an error and returns false. + /// + /// - If the call is allowed in semantically-correct programs, but only if + /// it's never codegen'ed, creates a deferred diagnostic to be emitted if + /// and when the caller is codegen'ed, and returns true. + /// + /// - Otherwise, returns true without emitting any diagnostics. + /// + /// Adds Callee to DeviceCallGraph if we don't know if its caller will be + /// codegen'ed yet. + bool checkSYCLDeviceFunction(SourceLocation Loc, FunctionDecl *Callee); }; /// RAII object that enters a new expression evaluation context. diff --git a/clang/include/clang/Sema/SemaConcept.h b/clang/include/clang/Sema/SemaConcept.h index acd1e604211a..c5f9fc45612a 100644 --- a/clang/include/clang/Sema/SemaConcept.h +++ b/clang/include/clang/Sema/SemaConcept.h @@ -13,10 +13,17 @@ #ifndef LLVM_CLANG_SEMA_SEMACONCEPT_H #define LLVM_CLANG_SEMA_SEMACONCEPT_H +#include "clang/AST/ASTConcept.h" #include "clang/AST/ASTContext.h" #include "clang/AST/Expr.h" +#include "clang/AST/DeclTemplate.h" +#include "clang/Basic/SourceLocation.h" +#include "llvm/ADT/PointerUnion.h" #include "llvm/ADT/Optional.h" #include "llvm/ADT/SmallVector.h" +#include <string> +#include <utility> + namespace clang { class Sema; @@ -36,11 +43,15 @@ struct AtomicConstraint { if (ParameterMapping->size() != Other.ParameterMapping->size()) return false; - for (unsigned I = 0, S = ParameterMapping->size(); I < S; ++I) - if (!C.getCanonicalTemplateArgument((*ParameterMapping)[I].getArgument()) - .structurallyEquals(C.getCanonicalTemplateArgument( - (*Other.ParameterMapping)[I].getArgument()))) + for (unsigned I = 0, S = ParameterMapping->size(); I < S; ++I) { + llvm::FoldingSetNodeID IDA, IDB; + C.getCanonicalTemplateArgument((*ParameterMapping)[I].getArgument()) + .Profile(IDA, C); + C.getCanonicalTemplateArgument((*Other.ParameterMapping)[I].getArgument()) + .Profile(IDB, C); + if (IDA != IDB) return false; + } return true; } diff --git a/clang/include/clang/Sema/Template.h b/clang/include/clang/Sema/Template.h index 4c1cfecd4de6..91d175fdd050 100644 --- a/clang/include/clang/Sema/Template.h +++ b/clang/include/clang/Sema/Template.h @@ -42,6 +42,17 @@ class TypedefNameDecl; class TypeSourceInfo; class VarDecl; +/// The kind of template substitution being performed. +enum class TemplateSubstitutionKind : char { + /// We are substituting template parameters for template arguments in order + /// to form a template specialization. + Specialization, + /// We are substituting template parameters for (typically) other template + /// parameters in order to rewrite a declaration as a different declaration + /// (for example, when forming a deduction guide from a constructor). + Rewrite, +}; + /// Data structure that captures multiple levels of template argument /// lists for use in template instantiation. /// @@ -73,6 +84,9 @@ class VarDecl; /// being substituted. unsigned NumRetainedOuterLevels = 0; + /// The kind of substitution described by this argument list. + TemplateSubstitutionKind Kind = TemplateSubstitutionKind::Specialization; + public: /// Construct an empty set of template argument lists. MultiLevelTemplateArgumentList() = default; @@ -83,6 +97,18 @@ class VarDecl; addOuterTemplateArguments(&TemplateArgs); } + void setKind(TemplateSubstitutionKind K) { Kind = K; } + + /// Determine the kind of template substitution being performed. + TemplateSubstitutionKind getKind() const { return Kind; } + + /// Determine whether we are rewriting template parameters rather than + /// substituting for them. If so, we should not leave references to the + /// original template parameters behind. + bool isRewrite() const { + return Kind == TemplateSubstitutionKind::Rewrite; + } + /// Determine the number of levels in this template argument /// list. unsigned getNumLevels() const { @@ -95,6 +121,20 @@ class VarDecl; return TemplateArgumentLists.size(); } + unsigned getNumRetainedOuterLevels() const { + return NumRetainedOuterLevels; + } + + /// Determine how many of the \p OldDepth outermost template parameter + /// lists would be removed by substituting these arguments. + unsigned getNewDepth(unsigned OldDepth) const { + if (OldDepth < NumRetainedOuterLevels) + return OldDepth; + if (OldDepth < getNumLevels()) + return NumRetainedOuterLevels; + return OldDepth - TemplateArgumentLists.size(); + } + /// Retrieve the template argument at a given depth and index. const TemplateArgument &operator()(unsigned Depth, unsigned Index) const { assert(NumRetainedOuterLevels <= Depth && Depth < getNumLevels()); @@ -149,6 +189,9 @@ class VarDecl; void addOuterRetainedLevel() { ++NumRetainedOuterLevels; } + void addOuterRetainedLevels(unsigned Num) { + NumRetainedOuterLevels += Num; + } /// Retrieve the innermost template argument list. const ArgList &getInnermost() const { @@ -412,6 +455,9 @@ class VarDecl; NamedDecl * getPartiallySubstitutedPack(const TemplateArgument **ExplicitArgs = nullptr, unsigned *NumExplicitArgs = nullptr) const; + + /// Determine whether D is a pack expansion created in this scope. + bool isLocalPackExpansion(const Decl *D); }; class TemplateDeclInstantiator diff --git a/clang/include/clang/Sema/TemplateDeduction.h b/clang/include/clang/Sema/TemplateDeduction.h index b60939c97872..c0af9f3260b6 100644 --- a/clang/include/clang/Sema/TemplateDeduction.h +++ b/clang/include/clang/Sema/TemplateDeduction.h @@ -15,6 +15,7 @@ #define LLVM_CLANG_SEMA_TEMPLATEDEDUCTION_H #include "clang/Sema/Ownership.h" +#include "clang/Sema/SemaConcept.h" #include "clang/AST/ASTConcept.h" #include "clang/AST/DeclAccessPair.h" #include "clang/AST/DeclTemplate.h" @@ -66,6 +67,13 @@ public: TemplateDeductionInfo(const TemplateDeductionInfo &) = delete; TemplateDeductionInfo &operator=(const TemplateDeductionInfo &) = delete; + enum ForBaseTag { ForBase }; + /// Create temporary template deduction info for speculatively deducing + /// against a base class of an argument's type. + TemplateDeductionInfo(ForBaseTag, const TemplateDeductionInfo &Info) + : Deduced(Info.Deduced), Loc(Info.Loc), DeducedDepth(Info.DeducedDepth), + ExplicitArgs(Info.ExplicitArgs) {} + /// Returns the location at which template argument is /// occurring. SourceLocation getLocation() const { diff --git a/clang/include/clang/Serialization/ASTBitCodes.h b/clang/include/clang/Serialization/ASTBitCodes.h index 1bfcbda8c9f1..c6f9f1d1a08f 100644 --- a/clang/include/clang/Serialization/ASTBitCodes.h +++ b/clang/include/clang/Serialization/ASTBitCodes.h @@ -30,84 +30,84 @@ namespace clang { namespace serialization { - /// AST file major version number supported by this version of - /// Clang. - /// - /// Whenever the AST file format changes in a way that makes it - /// incompatible with previous versions (such that a reader - /// designed for the previous version could not support reading - /// the new version), this number should be increased. - /// - /// Version 4 of AST files also requires that the version control branch and - /// revision match exactly, since there is no backward compatibility of - /// AST files at this time. - const unsigned VERSION_MAJOR = 8; - - /// AST file minor version number supported by this version of - /// Clang. - /// - /// Whenever the AST format changes in a way that is still - /// compatible with previous versions (such that a reader designed - /// for the previous version could still support reading the new - /// version by ignoring new kinds of subblocks), this number - /// should be increased. - const unsigned VERSION_MINOR = 0; - - /// An ID number that refers to an identifier in an AST file. - /// - /// The ID numbers of identifiers are consecutive (in order of discovery) - /// and start at 1. 0 is reserved for NULL. - using IdentifierID = uint32_t; - - /// An ID number that refers to a declaration in an AST file. - /// - /// The ID numbers of declarations are consecutive (in order of - /// discovery), with values below NUM_PREDEF_DECL_IDS being reserved. - /// At the start of a chain of precompiled headers, declaration ID 1 is - /// used for the translation unit declaration. - using DeclID = uint32_t; - - // FIXME: Turn these into classes so we can have some type safety when - // we go from local ID to global and vice-versa. - using LocalDeclID = DeclID; - using GlobalDeclID = DeclID; - - /// An ID number that refers to a type in an AST file. - /// - /// The ID of a type is partitioned into two parts: the lower - /// three bits are used to store the const/volatile/restrict - /// qualifiers (as with QualType) and the upper bits provide a - /// type index. The type index values are partitioned into two - /// sets. The values below NUM_PREDEF_TYPE_IDs are predefined type - /// IDs (based on the PREDEF_TYPE_*_ID constants), with 0 as a - /// placeholder for "no type". Values from NUM_PREDEF_TYPE_IDs are - /// other types that have serialized representations. - using TypeID = uint32_t; - - /// A type index; the type ID with the qualifier bits removed. - class TypeIdx { - uint32_t Idx = 0; - - public: - TypeIdx() = default; - explicit TypeIdx(uint32_t index) : Idx(index) {} - - uint32_t getIndex() const { return Idx; } - - TypeID asTypeID(unsigned FastQuals) const { - if (Idx == uint32_t(-1)) - return TypeID(-1); - - return (Idx << Qualifiers::FastWidth) | FastQuals; - } - - static TypeIdx fromTypeID(TypeID ID) { - if (ID == TypeID(-1)) - return TypeIdx(-1); - - return TypeIdx(ID >> Qualifiers::FastWidth); - } - }; +/// AST file major version number supported by this version of +/// Clang. +/// +/// Whenever the AST file format changes in a way that makes it +/// incompatible with previous versions (such that a reader +/// designed for the previous version could not support reading +/// the new version), this number should be increased. +/// +/// Version 4 of AST files also requires that the version control branch and +/// revision match exactly, since there is no backward compatibility of +/// AST files at this time. +const unsigned VERSION_MAJOR = 11; + +/// AST file minor version number supported by this version of +/// Clang. +/// +/// Whenever the AST format changes in a way that is still +/// compatible with previous versions (such that a reader designed +/// for the previous version could still support reading the new +/// version by ignoring new kinds of subblocks), this number +/// should be increased. +const unsigned VERSION_MINOR = 0; + +/// An ID number that refers to an identifier in an AST file. +/// +/// The ID numbers of identifiers are consecutive (in order of discovery) +/// and start at 1. 0 is reserved for NULL. +using IdentifierID = uint32_t; + +/// An ID number that refers to a declaration in an AST file. +/// +/// The ID numbers of declarations are consecutive (in order of +/// discovery), with values below NUM_PREDEF_DECL_IDS being reserved. +/// At the start of a chain of precompiled headers, declaration ID 1 is +/// used for the translation unit declaration. +using DeclID = uint32_t; + +// FIXME: Turn these into classes so we can have some type safety when +// we go from local ID to global and vice-versa. +using LocalDeclID = DeclID; +using GlobalDeclID = DeclID; + +/// An ID number that refers to a type in an AST file. +/// +/// The ID of a type is partitioned into two parts: the lower +/// three bits are used to store the const/volatile/restrict +/// qualifiers (as with QualType) and the upper bits provide a +/// type index. The type index values are partitioned into two +/// sets. The values below NUM_PREDEF_TYPE_IDs are predefined type +/// IDs (based on the PREDEF_TYPE_*_ID constants), with 0 as a +/// placeholder for "no type". Values from NUM_PREDEF_TYPE_IDs are +/// other types that have serialized representations. +using TypeID = uint32_t; + +/// A type index; the type ID with the qualifier bits removed. +class TypeIdx { + uint32_t Idx = 0; + +public: + TypeIdx() = default; + explicit TypeIdx(uint32_t index) : Idx(index) {} + + uint32_t getIndex() const { return Idx; } + + TypeID asTypeID(unsigned FastQuals) const { + if (Idx == uint32_t(-1)) + return TypeID(-1); + + return (Idx << Qualifiers::FastWidth) | FastQuals; + } + + static TypeIdx fromTypeID(TypeID ID) { + if (ID == TypeID(-1)) + return TypeIdx(-1); + + return TypeIdx(ID >> Qualifiers::FastWidth); + } +}; /// A structure for putting "fast"-unqualified QualTypes into a /// DenseMap. This uses the standard pointer hash function. @@ -181,7 +181,7 @@ namespace serialization { /// Raw source location of end of range. unsigned End; - /// Offset in the AST file. + /// Offset in the AST file relative to ModuleFile::MacroOffsetsBase. uint32_t BitOffset; PPEntityOffset(SourceRange R, uint32_t BitOffset) @@ -216,17 +216,43 @@ namespace serialization { } }; - /// Source range/offset of a preprocessed entity. + /// Offset in the AST file. Use splitted 64-bit integer into low/high + /// parts to keep structure alignment 32-bit (it is important because + /// blobs in bitstream are 32-bit aligned). This structure is serialized + /// "as is" to the AST file. + struct UnderalignedInt64 { + uint32_t BitOffsetLow = 0; + uint32_t BitOffsetHigh = 0; + + UnderalignedInt64() = default; + UnderalignedInt64(uint64_t BitOffset) { setBitOffset(BitOffset); } + + void setBitOffset(uint64_t Offset) { + BitOffsetLow = Offset; + BitOffsetHigh = Offset >> 32; + } + + uint64_t getBitOffset() const { + return BitOffsetLow | (uint64_t(BitOffsetHigh) << 32); + } + }; + + /// Source location and bit offset of a declaration. struct DeclOffset { /// Raw source location. unsigned Loc = 0; - /// Offset in the AST file. - uint32_t BitOffset = 0; + /// Offset relative to the start of the DECLTYPES_BLOCK block. Keep + /// structure alignment 32-bit and avoid padding gap because undefined + /// value in the padding affects AST hash. + UnderalignedInt64 BitOffset; DeclOffset() = default; - DeclOffset(SourceLocation Loc, uint32_t BitOffset) - : Loc(Loc.getRawEncoding()), BitOffset(BitOffset) {} + DeclOffset(SourceLocation Loc, uint64_t BitOffset, + uint64_t DeclTypesBlockStartOffset) { + setLocation(Loc); + setBitOffset(BitOffset, DeclTypesBlockStartOffset); + } void setLocation(SourceLocation L) { Loc = L.getRawEncoding(); @@ -235,6 +261,15 @@ namespace serialization { SourceLocation getLocation() const { return SourceLocation::getFromRawEncoding(Loc); } + + void setBitOffset(uint64_t Offset, + const uint64_t DeclTypesBlockStartOffset) { + BitOffset.setBitOffset(Offset - DeclTypesBlockStartOffset); + } + + uint64_t getBitOffset(const uint64_t DeclTypesBlockStartOffset) const { + return BitOffset.getBitOffset() + DeclTypesBlockStartOffset; + } }; /// The number of predefined preprocessed entity IDs. @@ -362,6 +397,9 @@ namespace serialization { /// Record code for the signature that identifiers this AST file. SIGNATURE = 1, + /// Record code for the content hash of the AST block. + AST_BLOCK_HASH, + /// Record code for the diagnostic options table. DIAGNOSTIC_OPTIONS, @@ -650,7 +688,13 @@ namespace serialization { PP_CONDITIONAL_STACK = 62, /// A table of skipped ranges within the preprocessing record. - PPD_SKIPPED_RANGES = 63 + PPD_SKIPPED_RANGES = 63, + + /// Record code for the Decls to be checked for deferred diags. + DECLS_TO_CHECK_FOR_DEFERRED_DIAGS = 64, + + /// Record code for \#pragma float_control options. + FLOAT_CONTROL_PRAGMA_OPTIONS = 65, }; /// Record types used within a source manager block. @@ -1013,6 +1057,18 @@ namespace serialization { /// \brief The '_Sat unsigned long _Fract' type PREDEF_TYPE_SAT_ULONG_FRACT_ID = 69, + /// The placeholder type for OpenMP array shaping operation. + PREDEF_TYPE_OMP_ARRAY_SHAPING = 70, + + /// The placeholder type for OpenMP iterator expression. + PREDEF_TYPE_OMP_ITERATOR = 71, + + /// A placeholder type for incomplete matrix index operations. + PREDEF_TYPE_INCOMPLETE_MATRIX_IDX = 72, + + /// \brief The '__bf16' type + PREDEF_TYPE_BFLOAT16_ID = 73, + /// OpenCL image types with auto numeration #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ PREDEF_TYPE_##Id##_ID, @@ -1125,27 +1181,30 @@ namespace serialization { /// The internal '__builtin_ms_va_list' typedef. PREDEF_DECL_BUILTIN_MS_VA_LIST_ID = 11, + /// The predeclared '_GUID' struct. + PREDEF_DECL_BUILTIN_MS_GUID_ID = 12, + /// The extern "C" context. - PREDEF_DECL_EXTERN_C_CONTEXT_ID = 12, + PREDEF_DECL_EXTERN_C_CONTEXT_ID = 13, /// The internal '__make_integer_seq' template. - PREDEF_DECL_MAKE_INTEGER_SEQ_ID = 13, + PREDEF_DECL_MAKE_INTEGER_SEQ_ID = 14, /// The internal '__NSConstantString' typedef. - PREDEF_DECL_CF_CONSTANT_STRING_ID = 14, + PREDEF_DECL_CF_CONSTANT_STRING_ID = 15, /// The internal '__NSConstantString' tag type. - PREDEF_DECL_CF_CONSTANT_STRING_TAG_ID = 15, + PREDEF_DECL_CF_CONSTANT_STRING_TAG_ID = 16, /// The internal '__type_pack_element' template. - PREDEF_DECL_TYPE_PACK_ELEMENT_ID = 16, + PREDEF_DECL_TYPE_PACK_ELEMENT_ID = 17, }; /// 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 = 17; + const unsigned int NUM_PREDEF_DECL_IDS = 18; /// Record of updates for a declaration that was modified after /// being deserialized. This can occur within DECLTYPES_BLOCK_ID. @@ -1219,6 +1278,9 @@ namespace serialization { /// A MSPropertyDecl record. DECL_MS_PROPERTY, + /// A MSGuidDecl record. + DECL_MS_GUID, + /// A VarDecl record. DECL_VAR, @@ -1403,6 +1465,9 @@ namespace serialization { /// An LifetimeExtendedTemporaryDecl record. DECL_LIFETIME_EXTENDED_TEMPORARY, + /// A RequiresExprBodyDecl record. + DECL_REQUIRES_EXPR_BODY, + /// An ObjCTypeParamDecl record. DECL_OBJC_TYPE_PARAM, @@ -1544,6 +1609,9 @@ namespace serialization { /// An ArraySubscriptExpr record. EXPR_ARRAY_SUBSCRIPT, + /// An MatrixSubscriptExpr record. + EXPR_MATRIX_SUBSCRIPT, + /// A CallExpr record. EXPR_CALL, @@ -1628,6 +1696,9 @@ namespace serialization { /// An AtomicExpr record. EXPR_ATOMIC, + /// A RecoveryExpr record. + EXPR_RECOVERY, + // Objective-C /// An ObjCStringLiteral record. @@ -1735,9 +1806,15 @@ namespace serialization { /// A CXXConstCastExpr record. EXPR_CXX_CONST_CAST, + /// A CXXAddrspaceCastExpr record. + EXPR_CXX_ADDRSPACE_CAST, + /// A CXXFunctionalCastExpr record. EXPR_CXX_FUNCTIONAL_CAST, + /// A BuiltinBitCastExpr record. + EXPR_BUILTIN_BIT_CAST, + /// A UserDefinedLiteral record. EXPR_USER_DEFINED_LITERAL, @@ -1785,6 +1862,7 @@ namespace serialization { EXPR_MATERIALIZE_TEMPORARY, // MaterializeTemporaryExpr EXPR_CXX_FOLD, // CXXFoldExpr EXPR_CONCEPT_SPECIALIZATION,// ConceptSpecializationExpr + EXPR_REQUIRES, // RequiresExpr // CUDA EXPR_CUDA_KERNEL_CALL, // CUDAKernelCallExpr @@ -1821,6 +1899,8 @@ namespace serialization { STMT_OMP_BARRIER_DIRECTIVE, STMT_OMP_TASKWAIT_DIRECTIVE, STMT_OMP_FLUSH_DIRECTIVE, + STMT_OMP_DEPOBJ_DIRECTIVE, + STMT_OMP_SCAN_DIRECTIVE, STMT_OMP_ORDERED_DIRECTIVE, STMT_OMP_ATOMIC_DIRECTIVE, STMT_OMP_TARGET_DIRECTIVE, @@ -1856,6 +1936,8 @@ namespace serialization { STMT_OMP_TARGET_TEAMS_DISTRIBUTE_PARALLEL_FOR_SIMD_DIRECTIVE, STMT_OMP_TARGET_TEAMS_DISTRIBUTE_SIMD_DIRECTIVE, EXPR_OMP_ARRAY_SECTION, + EXPR_OMP_ARRAY_SHAPING, + EXPR_OMP_ITERATOR, // ARC EXPR_OBJC_BRIDGED_CAST, // ObjCBridgedCastExpr @@ -1867,6 +1949,9 @@ namespace serialization { EXPR_COAWAIT, EXPR_COYIELD, EXPR_DEPENDENT_COAWAIT, + + // FixedPointLiteral + EXPR_FIXEDPOINT_LITERAL, }; /// The kinds of designators that can occur in a @@ -1895,6 +1980,9 @@ namespace serialization { CTOR_INITIALIZER_INDIRECT_MEMBER }; + /// Kinds of cleanup objects owned by ExprWithCleanups. + enum CleanupObjectKind { COK_Block, COK_CompoundLiteral }; + /// Describes the redeclarations of a declaration. struct LocalRedeclarationsInfo { // The ID of the first declaration diff --git a/clang/include/clang/Serialization/ASTReader.h b/clang/include/clang/Serialization/ASTReader.h index e74bf00e0872..a80366f0ee04 100644 --- a/clang/include/clang/Serialization/ASTReader.h +++ b/clang/include/clang/Serialization/ASTReader.h @@ -723,9 +723,10 @@ private: struct PendingMacroInfo { ModuleFile *M; - uint64_t MacroDirectivesOffset; + /// Offset relative to ModuleFile::MacroOffsetsBase. + uint32_t MacroDirectivesOffset; - PendingMacroInfo(ModuleFile *M, uint64_t MacroDirectivesOffset) + PendingMacroInfo(ModuleFile *M, uint32_t MacroDirectivesOffset) : M(M), MacroDirectivesOffset(MacroDirectivesOffset) {} }; @@ -856,6 +857,18 @@ private: int PragmaMSPointersToMembersState = -1; SourceLocation PointersToMembersPragmaLocation; + /// The pragma float_control state. + Optional<unsigned> FpPragmaCurrentValue; + SourceLocation FpPragmaCurrentLocation; + struct FpPragmaStackEntry { + unsigned Value; + SourceLocation Location; + SourceLocation PushLocation; + StringRef SlotLabel; + }; + llvm::SmallVector<FpPragmaStackEntry, 2> FpPragmaStack; + llvm::SmallVector<std::string, 2> FpPragmaStrings; + /// The pragma pack state. Optional<unsigned> PragmaPackCurrentValue; SourceLocation PragmaPackCurrentLocation; @@ -890,6 +903,12 @@ private: // A list of late parsed template function data. SmallVector<uint64_t, 1> LateParsedTemplates; + /// The IDs of all decls to be checked for deferred diags. + /// + /// Sema tracks these to emit deferred diags. + SmallVector<uint64_t, 4> DeclsToCheckForDeferredDiags; + + public: struct ImportedSubmodule { serialization::SubmoduleID ID; @@ -1348,7 +1367,7 @@ private: unsigned PreviousGeneration = 0); RecordLocation getLocalBitOffset(uint64_t GlobalOffset); - uint64_t getGlobalBitOffset(ModuleFile &M, uint32_t LocalOffset); + uint64_t getGlobalBitOffset(ModuleFile &M, uint64_t LocalOffset); /// Returns the first preprocessed entity ID that begins or ends after /// \arg Loc. @@ -1871,7 +1890,8 @@ 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. - static bool ReadBlockAbbrevs(llvm::BitstreamCursor &Cursor, unsigned BlockID); + static bool ReadBlockAbbrevs(llvm::BitstreamCursor &Cursor, unsigned BlockID, + uint64_t *StartOfBlockOffset = nullptr); /// Finds all the visible declarations with a given name. /// The current implementation of this method just loads the entire @@ -1983,6 +2003,9 @@ public: void ReadUnusedLocalTypedefNameCandidates( llvm::SmallSetVector<const TypedefNameDecl *, 4> &Decls) override; + void ReadDeclsToCheckForDeferredDiags( + llvm::SmallVector<Decl *, 4> &Decls) override; + void ReadReferencedSelectors( SmallVectorImpl<std::pair<Selector, SourceLocation>> &Sels) override; @@ -2196,7 +2219,7 @@ public: /// \param MacroDirectivesOffset Offset of the serialized macro directive /// history. void addPendingMacro(IdentifierInfo *II, ModuleFile *M, - uint64_t MacroDirectivesOffset); + uint32_t MacroDirectivesOffset); /// Read the set of macros defined by this external macro source. void ReadDefinedMacros() override; diff --git a/clang/include/clang/Serialization/ASTRecordReader.h b/clang/include/clang/Serialization/ASTRecordReader.h index f6dc8b2b7ae2..7248e6fa6c21 100644 --- a/clang/include/clang/Serialization/ASTRecordReader.h +++ b/clang/include/clang/Serialization/ASTRecordReader.h @@ -14,6 +14,7 @@ #ifndef LLVM_CLANG_SERIALIZATION_ASTRECORDREADER_H #define LLVM_CLANG_SERIALIZATION_ASTRECORDREADER_H +#include "clang/AST/ASTContext.h" #include "clang/AST/AbstractBasicReader.h" #include "clang/Lex/Token.h" #include "clang/Serialization/ASTReader.h" @@ -22,6 +23,7 @@ #include "llvm/ADT/APSInt.h" namespace clang { +class OMPTraitInfo; /// An object for streaming information from a record. class ASTRecordReader @@ -117,7 +119,7 @@ public: //readExceptionSpecInfo(SmallVectorImpl<QualType> &ExceptionStorage); /// Get the global offset corresponding to a local offset. - uint64_t getGlobalBitOffset(uint32_t LocalOffset) { + uint64_t getGlobalBitOffset(uint64_t LocalOffset) { return Reader->getGlobalBitOffset(*F, LocalOffset); } @@ -258,6 +260,9 @@ public: return Reader->ReadCXXTemporary(*F, Record, Idx); } + /// Read an OMPTraitInfo object, advancing Idx. + OMPTraitInfo *readOMPTraitInfo(); + /// Read an OpenMP clause, advancing Idx. OMPClause *readOMPClause(); diff --git a/clang/include/clang/Serialization/ASTRecordWriter.h b/clang/include/clang/Serialization/ASTRecordWriter.h index 43af68628ecc..491207c9de90 100644 --- a/clang/include/clang/Serialization/ASTRecordWriter.h +++ b/clang/include/clang/Serialization/ASTRecordWriter.h @@ -266,6 +266,9 @@ public: void AddCXXDefinitionData(const CXXRecordDecl *D); + /// Write an OMPTraitInfo object. + void writeOMPTraitInfo(const OMPTraitInfo *TI); + void writeOMPClause(OMPClause *C); /// Emit a string. diff --git a/clang/include/clang/Serialization/ASTWriter.h b/clang/include/clang/Serialization/ASTWriter.h index c0a943adf2c7..7a6664af65d8 100644 --- a/clang/include/clang/Serialization/ASTWriter.h +++ b/clang/include/clang/Serialization/ASTWriter.h @@ -27,6 +27,7 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/MapVector.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SetVector.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" @@ -61,6 +62,7 @@ class CXXRecordDecl; class CXXTemporary; class FileEntry; class FPOptions; +class FPOptionsOverride; class FunctionDecl; class HeaderSearch; class HeaderSearchOptions; @@ -137,6 +139,12 @@ private: /// The module we're currently writing, if any. Module *WritingModule = nullptr; + /// The offset of the first bit inside the AST_BLOCK. + uint64_t ASTBlockStartOffset = 0; + + /// The range representing all the AST_BLOCK. + std::pair<uint64_t, uint64_t> ASTBlockRange; + /// The base directory for any relative paths we emit. std::string BaseDirectory; @@ -206,6 +214,10 @@ private: /// the declaration's ID. std::vector<serialization::DeclOffset> DeclOffsets; + /// The offset of the DECLTYPES_BLOCK. The offsets in DeclOffsets + /// are relative to this value. + uint64_t DeclTypesBlockStartOffset = 0; + /// Sorted (by file offset) vector of pairs of file offset/DeclID. using LocDeclIDsTy = SmallVector<std::pair<unsigned, serialization::DeclID>, 64>; @@ -216,7 +228,8 @@ private: /// indicates the index that this particular vector has in the global one. unsigned FirstDeclIndex; }; - using FileDeclIDsTy = llvm::DenseMap<FileID, DeclIDInFileInfo *>; + using FileDeclIDsTy = + llvm::DenseMap<FileID, std::unique_ptr<DeclIDInFileInfo>>; /// Map from file SLocEntries to info about the file-level declarations /// that it contains. @@ -243,7 +256,7 @@ private: /// Offset of each type in the bitstream, indexed by /// the type's ID. - std::vector<uint32_t> TypeOffsets; + std::vector<serialization::UnderalignedInt64> TypeOffsets; /// The first ID number we can use for our own identifiers. serialization::IdentID FirstIdentID = serialization::NUM_PREDEF_IDENT_IDS; @@ -277,7 +290,8 @@ private: /// The macro infos to emit. std::vector<MacroInfoToEmitData> MacroInfosToEmit; - llvm::DenseMap<const IdentifierInfo *, uint64_t> IdentMacroDirectivesOffsetMap; + llvm::DenseMap<const IdentifierInfo *, uint32_t> + IdentMacroDirectivesOffsetMap; /// @name FlushStmt Caches /// @{ @@ -439,7 +453,7 @@ private: /// A list of the module file extension writers. std::vector<std::unique_ptr<ModuleFileExtensionWriter>> - ModuleFileExtensionWriters; + ModuleFileExtensionWriters; /// Retrieve or create a submodule ID for this module. unsigned getSubmoduleID(Module *Mod); @@ -456,7 +470,8 @@ private: ASTContext &Context); /// Calculate hash of the pcm content. - static ASTFileSignature createSignature(StringRef Bytes); + static std::pair<ASTFileSignature, ASTFileSignature> + createSignature(StringRef AllBytes, StringRef ASTBlockBytes); void WriteInputFiles(SourceManager &SourceMgr, HeaderSearchOptions &HSOpts, bool Modules); @@ -464,7 +479,8 @@ private: const Preprocessor &PP); void WritePreprocessor(const Preprocessor &PP, bool IsModule); void WriteHeaderSearch(const HeaderSearch &HS); - void WritePreprocessorDetail(PreprocessingRecord &PPRec); + void WritePreprocessorDetail(PreprocessingRecord &PPRec, + uint64_t MacroOffsetsBase); void WriteSubmodules(Module *WritingModule); void WritePragmaDiagnosticMappings(const DiagnosticsEngine &Diag, @@ -491,7 +507,7 @@ private: bool IsModule); void WriteDeclUpdatesBlocks(RecordDataImpl &OffsetsRecord); void WriteDeclContextVisibleUpdate(const DeclContext *DC); - void WriteFPPragmaOptions(const FPOptions &Opts); + void WriteFPPragmaOptions(const FPOptionsOverride &Opts); void WriteOpenCLExtensions(Sema &SemaRef); void WriteOpenCLExtensionTypes(Sema &SemaRef); void WriteOpenCLExtensionDecls(Sema &SemaRef); @@ -502,6 +518,7 @@ private: void WriteMSStructPragmaOptions(Sema &SemaRef); void WriteMSPointersToMembersPragmaOptions(Sema &SemaRef); void WritePackPragmaOptions(Sema &SemaRef); + void WriteFloatControlPragmaOptions(Sema &SemaRef); void WriteModuleFileExtension(Sema &SemaRef, ModuleFileExtensionWriter &Writer); @@ -588,7 +605,7 @@ public: /// Determine the ID of an already-emitted macro. serialization::MacroID getMacroID(MacroInfo *MI); - uint64_t getMacroDirectivesOffset(const IdentifierInfo *Name); + uint32_t getMacroDirectivesOffset(const IdentifierInfo *Name); /// Emit a reference to a type. void AddTypeRef(QualType T, RecordDataImpl &Record); diff --git a/clang/include/clang/Serialization/ModuleFile.h b/clang/include/clang/Serialization/ModuleFile.h index 8f3eb0220637..cec29da69372 100644 --- a/clang/include/clang/Serialization/ModuleFile.h +++ b/clang/include/clang/Serialization/ModuleFile.h @@ -14,6 +14,7 @@ #ifndef LLVM_CLANG_SERIALIZATION_MODULEFILE_H #define LLVM_CLANG_SERIALIZATION_MODULEFILE_H +#include "clang/Basic/FileManager.h" #include "clang/Basic/Module.h" #include "clang/Basic/SourceLocation.h" #include "clang/Serialization/ASTBitCodes.h" @@ -34,8 +35,6 @@ namespace clang { -class FileEntry; - namespace serialization { /// Specifies the kind of module that has been loaded. @@ -169,6 +168,10 @@ public: /// and modification time to identify this particular file. ASTFileSignature Signature; + /// The signature of the AST block of the module file, this can be used to + /// unique module files based on AST contents. + ASTFileSignature ASTBlockHash; + /// Whether this module has been directly imported by the /// user. bool DirectlyImported = false; @@ -186,6 +189,9 @@ public: /// The global bit offset (or base) of this module uint64_t GlobalBitOffset = 0; + /// The bit offset of the AST block of this module. + uint64_t ASTBlockStartOffset = 0; + /// The serialized bitstream data for this file. StringRef Data; @@ -243,6 +249,9 @@ public: /// Cursor used to read source location entries. llvm::BitstreamCursor SLocEntryCursor; + /// The bit offset to the start of the SOURCE_MANAGER_BLOCK. + uint64_t SourceManagerBlockStartOffset = 0; + /// The number of source location entries in this AST file. unsigned LocalNumSLocEntries = 0; @@ -252,6 +261,10 @@ public: /// The base offset in the source manager's view of this module. unsigned SLocEntryBaseOffset = 0; + /// Base file offset for the offsets in SLocEntryOffsets. Real file offset + /// for the entry is SLocEntryOffsetsBase + SLocEntryOffsets[i]. + uint64_t SLocEntryOffsetsBase = 0; + /// Offsets for all of the source location entries in the /// AST file. const uint32_t *SLocEntryOffsets = nullptr; @@ -303,6 +316,10 @@ public: /// The number of macros in this AST file. unsigned LocalNumMacros = 0; + /// Base file offset for the offsets in MacroOffsets. Real file offset for + /// the entry is MacroOffsetsBase + MacroOffsets[i]. + uint64_t MacroOffsetsBase = 0; + /// Offsets of macros in the preprocessor block. /// /// This array is indexed by the macro ID (-1), and provides @@ -402,11 +419,14 @@ public: // === Declarations === - /// DeclsCursor - This is a cursor to the start of the DECLS_BLOCK block. It - /// has read all the abbreviations at the start of the block and is ready to - /// jump around with these in context. + /// DeclsCursor - This is a cursor to the start of the DECLTYPES_BLOCK block. + /// It has read all the abbreviations at the start of the block and is ready + /// to jump around with these in context. llvm::BitstreamCursor DeclsCursor; + /// The offset to the start of the DECLTYPES_BLOCK block. + uint64_t DeclsBlockStartOffset = 0; + /// The number of declarations in this AST file. unsigned LocalNumDecls = 0; @@ -451,7 +471,7 @@ public: /// Offset of each type within the bitstream, indexed by the /// type ID, or the representation of a Type*. - const uint32_t *TypeOffsets = nullptr; + const UnderalignedInt64 *TypeOffsets = nullptr; /// Base type ID for types local to this module as represented in /// the global type ID space. diff --git a/clang/include/clang/Serialization/TypeBitCodes.def b/clang/include/clang/Serialization/TypeBitCodes.def index 38c73ccb7daf..e92e05810648 100644 --- a/clang/include/clang/Serialization/TypeBitCodes.def +++ b/clang/include/clang/Serialization/TypeBitCodes.def @@ -58,5 +58,9 @@ TYPE_BIT_CODE(DependentSizedExtVector, DEPENDENT_SIZED_EXT_VECTOR, 46) TYPE_BIT_CODE(DependentAddressSpace, DEPENDENT_ADDRESS_SPACE, 47) TYPE_BIT_CODE(DependentVector, DEPENDENT_SIZED_VECTOR, 48) TYPE_BIT_CODE(MacroQualified, MACRO_QUALIFIED, 49) +TYPE_BIT_CODE(ExtInt, EXT_INT, 50) +TYPE_BIT_CODE(DependentExtInt, DEPENDENT_EXT_INT, 51) +TYPE_BIT_CODE(ConstantMatrix, CONSTANT_MATRIX, 52) +TYPE_BIT_CODE(DependentSizedMatrix, DEPENDENT_SIZE_MATRIX, 53) #undef TYPE_BIT_CODE diff --git a/clang/include/clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h b/clang/include/clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h index c7732333d9ba..e2be957821b9 100644 --- a/clang/include/clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h +++ b/clang/include/clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h @@ -28,7 +28,7 @@ class CheckerRegistry; #define GET_CHECKERS #define CHECKER(FULLNAME, CLASS, HELPTEXT, DOC_URI, IS_HIDDEN) \ void register##CLASS(CheckerManager &mgr); \ - bool shouldRegister##CLASS(const LangOptions &LO); + bool shouldRegister##CLASS(const CheckerManager &mgr); #include "clang/StaticAnalyzer/Checkers/Checkers.inc" #undef CHECKER #undef GET_CHECKERS diff --git a/clang/include/clang/StaticAnalyzer/Checkers/CheckerBase.td b/clang/include/clang/StaticAnalyzer/Checkers/CheckerBase.td index 6625d79559f5..98d26aaa637d 100644 --- a/clang/include/clang/StaticAnalyzer/Checkers/CheckerBase.td +++ b/clang/include/clang/StaticAnalyzer/Checkers/CheckerBase.td @@ -112,6 +112,8 @@ class Checker<string name = ""> { list<CmdLineOption> CheckerOptions; // This field is optional. list<Checker> Dependencies; + // This field is optional. + list<Checker> WeakDependencies; bits<2> Documentation; Package ParentPackage; bit Hidden = 0; @@ -122,8 +124,13 @@ class CheckerOptions<list<CmdLineOption> opts> { list<CmdLineOption> CheckerOptions = opts; } -/// Describes dependencies in between checkers. For example, InnerPointerChecker -/// relies on information MallocBase gathers. +/// Describes (strong) dependencies in between checkers. This is important for +/// modeling checkers, for example, MallocBase depends on the proper modeling of +/// string operations, so it depends on CStringBase. A checker may only be +/// enabled if none of its dependencies (transitively) is disabled. Dependencies +/// are always registered before the dependent checker, and its checker +/// callbacks are also evaluated sooner. +/// One may only depend on a purely modeling checker (that emits no diagnostis). /// Example: /// def InnerPointerChecker : Checker<"InnerPointer">, /// HelpText<"Check for inner pointers of C++ containers used after " @@ -133,6 +140,24 @@ class Dependencies<list<Checker> Deps = []> { list<Checker> Dependencies = Deps; } +/// Describes preferred registration and evaluation order in between checkers. +/// Unlike strong dependencies, this expresses dependencies in between +/// diagnostics, and *not* modeling. In the case of an unsatisfied (disabled) +/// weak dependency, the dependent checker might still be registered. If the +/// weak dependency is satisfied, it'll be registered, and its checker +/// callbacks will be evaluated before the dependent checker. This can be used +/// to ensure that a more specific warning would be displayed in place of a +/// generic one, should multiple checkers detect the same bug. For example, +/// non-null parameter bugs are detected by NonNullParamChecker due to the +/// nonnull attribute, and StdLibraryFunctionsChecker as it models standard +/// functions, and the former is the more specific one. While freeing a +/// dangling pointer is a bug, if it is also a double free, we would like to +/// recognize it as such first and foremost. This works best for fatal error +/// node generation, otherwise both warnings may be present and in any order. +class WeakDependencies<list<Checker> Deps = []> { + list<Checker> WeakDependencies = Deps; +} + /// Marks a checker or a package hidden. Hidden entries are meant for developers /// only, and aren't exposed to end users. class Hidden { bit Hidden = 1; } diff --git a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td index d235273cda41..cbd925400328 100644 --- a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td +++ b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td @@ -71,6 +71,9 @@ def InsecureAPI : Package<"insecureAPI">, ParentPackage<Security>; def SecurityAlpha : Package<"security">, ParentPackage<Alpha>; def Taint : Package<"taint">, ParentPackage<SecurityAlpha>; +def CERT : Package<"cert">, ParentPackage<SecurityAlpha>; +def POS : Package<"pos">, ParentPackage<CERT>; + def Unix : Package<"unix">; def UnixAlpha : Package<"unix">, ParentPackage<Alpha>; def CString : Package<"cstring">, ParentPackage<Unix>; @@ -99,6 +102,8 @@ def LLVMAlpha : Package<"llvm">, ParentPackage<Alpha>; // any diagnostics. These checkers are always turned on; this package is // intended for API modeling that is not controlled by the target triple. def APIModeling : Package<"apiModeling">, Hidden; +def APIModelingAlpha : Package<"apiModeling">, ParentPackage<Alpha>, Hidden; + def GoogleAPIModeling : Package<"google">, ParentPackage<APIModeling>, Hidden; def LLVMAPIModeling : Package<"llvm">, ParentPackage<APIModeling>, Hidden; @@ -109,6 +114,10 @@ def CloneDetectionAlpha : Package<"clone">, ParentPackage<Alpha>; def NonDeterminismAlpha : Package<"nondeterminism">, ParentPackage<Alpha>; def Fuchsia : Package<"fuchsia">; +def FuchsiaAlpha : Package<"fuchsia">, ParentPackage<Alpha>; + +def WebKit : Package<"webkit">; +def WebKitAlpha : Package<"webkit">, ParentPackage<Alpha>; //===----------------------------------------------------------------------===// // Core Checkers. @@ -116,14 +125,71 @@ def Fuchsia : Package<"fuchsia">; let ParentPackage = Core in { -def DereferenceChecker : Checker<"NullDereference">, - HelpText<"Check for dereferences of null pointers">, - Documentation<HasDocumentation>; +def CallAndMessageModeling : Checker<"CallAndMessageModeling">, + HelpText<"Responsible for essential modeling and assumptions after a " + "function/method call. For instance, if we can't reason about the " + "nullability of the implicit this parameter after a method call, " + "this checker conservatively assumes it to be non-null">, + Documentation<HasDocumentation>, + Hidden; def CallAndMessageChecker : Checker<"CallAndMessage">, HelpText<"Check for logical errors for function calls and Objective-C " "message expressions (e.g., uninitialized arguments, null function " "pointers)">, + CheckerOptions<[ + CmdLineOption<Boolean, + "FunctionPointer", + "Check whether a called function pointer is null or " + "undefined", + "true", + Released>, + CmdLineOption<Boolean, + "ParameterCount", + "Check whether a function was called with the appropriate " + "number of arguments", + "true", + Released>, + CmdLineOption<Boolean, + "CXXThisMethodCall", + "Check whether the implicit this parameter is null or " + "undefined upon a method call", + "true", + Released>, + CmdLineOption<Boolean, + "CXXDeallocationArg", + "Check whether the argument of operator delete is undefined", + "true", + Released>, + CmdLineOption<Boolean, + "ArgInitializedness", + "Check whether any of the pass-by-value parameters is " + "undefined", + "true", + Released>, + CmdLineOption<Boolean, + "ArgPointeeInitializedness", + "Check whether the pointee of a pass-by-reference or " + "pass-by-pointer is undefined", + "false", + InAlpha>, + CmdLineOption<Boolean, + "NilReceiver", + "Check whether the reciever in the message expression is nil", + "true", + Released>, + CmdLineOption<Boolean, + "UndefReceiver", + "Check whether the reciever in the message expression is " + "undefined", + "true", + Released>, + ]>, + Documentation<HasDocumentation>, + Dependencies<[CallAndMessageModeling]>; + +def DereferenceChecker : Checker<"NullDereference">, + HelpText<"Check for dereferences of null pointers">, Documentation<HasDocumentation>; def NonNullParamChecker : Checker<"NonNullParamChecker">, @@ -155,7 +221,8 @@ def StackAddrEscapeChecker : Checker<"StackAddressEscape">, def DynamicTypePropagation : Checker<"DynamicTypePropagation">, HelpText<"Generate dynamic type information">, - Documentation<NotDocumented>; + Documentation<NotDocumented>, + Hidden; def NonnullGlobalConstantsChecker: Checker<"NonnilStringConstants">, HelpText<"Assume that const string-like globals are non-null">, @@ -205,13 +272,6 @@ def SizeofPointerChecker : Checker<"SizeofPtr">, HelpText<"Warn about unintended use of sizeof() on pointer expressions">, Documentation<HasAlphaDocumentation>; -def CallAndMessageUnInitRefArg : Checker<"CallAndMessageUnInitRefArg">, - HelpText<"Check for logical errors for function calls and Objective-C " - "message expressions (e.g., uninitialized arguments, null function " - "pointers, and pointer to undefined variables)">, - Dependencies<[CallAndMessageChecker]>, - Documentation<HasAlphaDocumentation>; - def TestAfterDivZeroChecker : Checker<"TestAfterDivZero">, HelpText<"Check for division by variable that is later compared against 0. " "Either the comparison is useless or there is division by zero.">, @@ -227,6 +287,16 @@ def StackAddrAsyncEscapeChecker : Checker<"StackAddressAsyncEscape">, Dependencies<[StackAddrEscapeBase]>, Documentation<HasAlphaDocumentation>; +def PthreadLockBase : Checker<"PthreadLockBase">, + HelpText<"Helper registering multiple checks.">, + Documentation<NotDocumented>, + Hidden; + +def C11LockChecker : Checker<"C11Lock">, + HelpText<"Simple lock -> unlock checker">, + Dependencies<[PthreadLockBase]>, + Documentation<HasAlphaDocumentation>; + } // end "alpha.core" //===----------------------------------------------------------------------===// @@ -279,7 +349,24 @@ let ParentPackage = APIModeling in { def StdCLibraryFunctionsChecker : Checker<"StdCLibraryFunctions">, HelpText<"Improve modeling of the C standard library functions">, - Documentation<NotDocumented>; + Dependencies<[CallAndMessageModeling]>, + CheckerOptions<[ + CmdLineOption<Boolean, + "DisplayLoadedSummaries", + "If set to true, the checker displays the found summaries " + "for the given translation unit.", + "false", + Released, + Hide>, + CmdLineOption<Boolean, + "ModelPOSIX", + "If set to true, the checker models functions from the " + "POSIX standard.", + "false", + InAlpha> + ]>, + Documentation<NotDocumented>, + Hidden; def TrustNonnullChecker : Checker<"TrustNonnull">, HelpText<"Trust that returns from framework methods annotated with _Nonnull " @@ -431,6 +518,7 @@ def ChrootChecker : Checker<"Chroot">, def PthreadLockChecker : Checker<"PthreadLock">, HelpText<"Simple lock -> unlock checker">, + Dependencies<[PthreadLockBase]>, Documentation<HasAlphaDocumentation>; def StreamChecker : Checker<"Stream">, @@ -445,6 +533,14 @@ def BlockInCriticalSectionChecker : Checker<"BlockInCriticalSection">, HelpText<"Check for calls to blocking functions inside a critical section">, Documentation<HasAlphaDocumentation>; +def StdCLibraryFunctionArgsChecker : Checker<"StdCLibraryFunctionArgs">, + HelpText<"Check constraints of arguments of C standard library functions, " + "such as whether the parameter of isalpha is in the range [0, 255] " + "or is EOF.">, + Dependencies<[StdCLibraryFunctionsChecker]>, + WeakDependencies<[NonNullParamChecker]>, + Documentation<NotDocumented>; + } // end "alpha.unix" //===----------------------------------------------------------------------===// @@ -467,7 +563,13 @@ def NewDeleteChecker : Checker<"NewDelete">, def NewDeleteLeaksChecker : Checker<"NewDeleteLeaks">, HelpText<"Check for memory leaks. Traces memory managed by new/delete.">, - Dependencies<[NewDeleteChecker]>, + Dependencies<[DynamicMemoryModeling]>, + Documentation<HasDocumentation>; + +def PlacementNewChecker : Checker<"PlacementNew">, + HelpText<"Check if default placement new is provided with pointers to " + "sufficient storage capacity">, + Dependencies<[DynamicMemoryModeling]>, Documentation<HasDocumentation>; def CXXSelfAssignmentChecker : Checker<"SelfAssignment">, @@ -475,9 +577,17 @@ def CXXSelfAssignmentChecker : Checker<"SelfAssignment">, Documentation<NotDocumented>, Hidden; -def SmartPtrModeling: Checker<"SmartPtr">, +def SmartPtrModeling: Checker<"SmartPtrModeling">, HelpText<"Model behavior of C++ smart pointers">, Documentation<NotDocumented>, + CheckerOptions<[ + CmdLineOption<Boolean, + "ModelSmartPtrDereference", + "Enable modeling for SmartPtr null dereferences", + "false", + InAlpha, + Hide>, + ]>, Hidden; def MoveChecker: Checker<"Move">, @@ -585,6 +695,11 @@ def VirtualCallChecker : Checker<"VirtualCall">, let ParentPackage = CplusplusAlpha in { +def ContainerModeling : Checker<"ContainerModeling">, + HelpText<"Models C++ containers">, + Documentation<NotDocumented>, + Hidden; + def DeleteWithNonVirtualDtorChecker : Checker<"DeleteWithNonVirtualDtor">, HelpText<"Reports destructions of polymorphic objects with a non-virtual " "destructor in their base class">, @@ -596,9 +711,23 @@ def EnumCastOutOfRangeChecker : Checker<"EnumCastOutOfRange">, def IteratorModeling : Checker<"IteratorModeling">, HelpText<"Models iterators of C++ containers">, + Dependencies<[ContainerModeling]>, Documentation<NotDocumented>, Hidden; +def STLAlgorithmModeling : Checker<"STLAlgorithmModeling">, + HelpText<"Models the algorithm library of the C++ STL.">, + CheckerOptions<[ + CmdLineOption<Boolean, + "AggressiveStdFindModeling", + "Enables exploration of the failure branch in std::find-like " + "functions.", + "false", + Released> + ]>, + Dependencies<[ContainerModeling]>, + Documentation<NotDocumented>; + def InvalidatedIteratorChecker : Checker<"InvalidatedIterator">, HelpText<"Check for use of invalidated iterators">, Dependencies<[IteratorModeling]>, @@ -615,11 +744,10 @@ def MismatchedIteratorChecker : Checker<"MismatchedIterator">, Dependencies<[IteratorModeling]>, Documentation<HasAlphaDocumentation>; -def PlacementNewChecker : Checker<"PlacementNew">, - HelpText<"Check if default placement new is provided with pointers to " - "sufficient storage capacity">, - Dependencies<[NewDeleteChecker]>, - Documentation<HasDocumentation>; +def SmartPtrChecker: Checker<"SmartPtr">, + HelpText<"Find the dereference of null SmrtPtr">, + Dependencies<[SmartPtrModeling]>, + Documentation<HasAlphaDocumentation>; } // end: "alpha.cplusplus" @@ -798,6 +926,15 @@ def FloatLoopCounter : Checker<"FloatLoopCounter">, } // end "security" +let ParentPackage = POS in { + + def PutenvWithAuto : Checker<"34c">, + HelpText<"Finds calls to the 'putenv' function which pass a pointer to " + "an automatic variable as the argument.">, + Documentation<HasDocumentation>; + +} // end "alpha.cert.pos" + let ParentPackage = SecurityAlpha in { def ArrayBoundChecker : Checker<"ArrayBound">, @@ -978,15 +1115,6 @@ def RetainCountChecker : Checker<"RetainCount">, HelpText<"Check for leaks and improper reference count management">, CheckerOptions<[ CmdLineOption<Boolean, - "CheckOSObject", - "Find violations of retain-release rules applied to XNU " - "OSObject instances. By default, the checker only checks " - "retain-release rules for Objective-C NSObject instances " - "and CoreFoundation objects.", - "true", - InAlpha, - Hide>, - CmdLineOption<Boolean, "TrackNSCFStartParam", "Check not only that the code follows retain-release rules " "with respect to objects it allocates or borrows from " @@ -1059,13 +1187,15 @@ def MissingInvalidationMethod : Checker<"MissingInvalidationMethod">, def DirectIvarAssignment : Checker<"DirectIvarAssignment">, HelpText<"Check for direct assignments to instance variables">, - Documentation<HasAlphaDocumentation>; - -def DirectIvarAssignmentForAnnotatedFunctions : - Checker<"DirectIvarAssignmentForAnnotatedFunctions">, - HelpText<"Check for direct assignments to instance variables in the methods " - "annotated with objc_no_direct_instance_variable_assignment">, - Dependencies<[DirectIvarAssignment]>, + CheckerOptions<[ + CmdLineOption<Boolean, + "AnnotatedFunctions", + "Check for direct assignments to instance variables in the " + "methods annotated with " + "objc_no_direct_instance_variable_assignment", + "false", + InAlpha> + ]>, Documentation<HasAlphaDocumentation>; } // end "alpha.osx.cocoa" @@ -1226,6 +1356,30 @@ def AnalysisOrderChecker : Checker<"AnalysisOrder">, Released, Hide>, CmdLineOption<Boolean, + "PreStmtCXXDeleteExpr", + "", + "false", + Released, + Hide>, + CmdLineOption<Boolean, + "PostStmtCXXDeleteExpr", + "", + "false", + Released, + Hide>, + CmdLineOption<Boolean, + "PreStmtCXXConstructExpr", + "", + "false", + Released, + Hide>, + CmdLineOption<Boolean, + "PostStmtCXXConstructExpr", + "", + "false", + Released, + Hide>, + CmdLineOption<Boolean, "PreStmtOffsetOfExpr", "", "false", @@ -1238,6 +1392,12 @@ def AnalysisOrderChecker : Checker<"AnalysisOrder">, Released, Hide>, CmdLineOption<Boolean, + "EvalCall", + "", + "false", + Released, + Hide>, + CmdLineOption<Boolean, "PreCall", "", "false", @@ -1256,6 +1416,12 @@ def AnalysisOrderChecker : Checker<"AnalysisOrder">, Released, Hide>, CmdLineOption<Boolean, + "EndAnalysis", + "", + "false", + Released, + Hide>, + CmdLineOption<Boolean, "NewAllocator", "", "false", @@ -1350,6 +1516,16 @@ def TaintTesterChecker : Checker<"TaintTest">, HelpText<"Mark tainted symbols as such.">, Documentation<NotDocumented>; +// This checker *technically* depends on SteamChecker, but we don't allow +// dependency checkers to emit diagnostics, and a debug checker isn't worth +// the chore needed to create a modeling portion on its own. Since this checker +// is for development purposes only anyways, make sure that StreamChecker is +// also enabled, at least for the time being. +def StreamTesterChecker : Checker<"StreamTester">, + HelpText<"Add test functions to StreamChecker for test and debugging " + "purposes.">, + Documentation<NotDocumented>; + def ExprInspectionChecker : Checker<"ExprInspection">, HelpText<"Check the analyzer's understanding of expressions">, Documentation<NotDocumented>; @@ -1362,9 +1538,20 @@ def ReportStmts : Checker<"ReportStmts">, HelpText<"Emits a warning for every statement.">, Documentation<NotDocumented>; +def DebugContainerModeling : Checker<"DebugContainerModeling">, + HelpText<"Check the analyzer's understanding of C++ containers">, + Dependencies<[ContainerModeling]>, + Documentation<NotDocumented>; + def DebugIteratorModeling : Checker<"DebugIteratorModeling">, HelpText<"Check the analyzer's understanding of C++ iterators">, - Dependencies<[IteratorModeling]>, + Dependencies<[DebugContainerModeling, IteratorModeling]>, + Documentation<NotDocumented>; + +def StdCLibraryFunctionsTesterChecker : Checker<"StdCLibraryFunctionsTester">, + HelpText<"Add test functions to the summary map, so testing of individual " + "summary constituents becomes possible.">, + Dependencies<[StdCLibraryFunctionsChecker]>, Documentation<NotDocumented>; } // end "debug" @@ -1442,5 +1629,37 @@ def FuchsiaHandleChecker : Checker<"HandleChecker">, HelpText<"A Checker that detect leaks related to Fuchsia handles">, Documentation<HasDocumentation>; +} + +let ParentPackage = FuchsiaAlpha in { + +def FuchsiaLockChecker : Checker<"Lock">, + HelpText<"Check for the correct usage of locking APIs.">, + Dependencies<[PthreadLockBase]>, + Documentation<HasDocumentation>; + } // end fuchsia +//===----------------------------------------------------------------------===// +// WebKit checkers. +//===----------------------------------------------------------------------===// + +let ParentPackage = WebKit in { + +def RefCntblBaseVirtualDtorChecker : Checker<"RefCntblBaseVirtualDtor">, + HelpText<"Check for any ref-countable base class having virtual destructor.">, + Documentation<HasDocumentation>; + +def NoUncountedMemberChecker : Checker<"NoUncountedMemberChecker">, + HelpText<"Check for no uncounted member variables.">, + Documentation<HasDocumentation>; + +} // end webkit + +let ParentPackage = WebKitAlpha in { + +def UncountedCallArgsChecker : Checker<"UncountedCallArgsChecker">, + HelpText<"Check uncounted call arguments.">, + Documentation<HasDocumentation>; + +} // end alpha.webkit diff --git a/clang/include/clang/StaticAnalyzer/Checkers/SValExplainer.h b/clang/include/clang/StaticAnalyzer/Checkers/SValExplainer.h index f7bd5b58aab5..0f33909daec0 100644 --- a/clang/include/clang/StaticAnalyzer/Checkers/SValExplainer.h +++ b/clang/include/clang/StaticAnalyzer/Checkers/SValExplainer.h @@ -18,6 +18,7 @@ #include "clang/AST/Attr.h" #include "clang/AST/DeclCXX.h" #include "clang/StaticAnalyzer/Core/PathSensitive/SValVisitor.h" +#include "llvm/ADT/StringExtras.h" namespace clang { @@ -179,7 +180,7 @@ public: return OS.str(); } - std::string VisitVarRegion(const VarRegion *R) { + std::string VisitNonParamVarRegion(const NonParamVarRegion *R) { const VarDecl *VD = R->getDecl(); std::string Name = VD->getQualifiedNameAsString(); if (isa<ParmVarDecl>(VD)) @@ -216,6 +217,39 @@ public: "' inside " + Visit(R->getSuperRegion()); } + std::string VisitParamVarRegion(const ParamVarRegion *R) { + std::string Str; + llvm::raw_string_ostream OS(Str); + + const ParmVarDecl *PVD = R->getDecl(); + std::string Name = PVD->getQualifiedNameAsString(); + if (!Name.empty()) { + OS << "parameter '" << Name << "'"; + return std::string(OS.str()); + } + + unsigned Index = R->getIndex() + 1; + OS << Index << llvm::getOrdinalSuffix(Index) << " parameter of "; + const Decl *Parent = R->getStackFrame()->getDecl(); + if (const auto *FD = dyn_cast<FunctionDecl>(Parent)) + OS << "function '" << FD->getQualifiedNameAsString() << "()'"; + else if (const auto *CD = dyn_cast<CXXConstructorDecl>(Parent)) + OS << "C++ constructor '" << CD->getQualifiedNameAsString() << "()'"; + else if (const auto *MD = dyn_cast<ObjCMethodDecl>(Parent)) { + if (MD->isClassMethod()) + OS << "Objective-C method '+" << MD->getQualifiedNameAsString() << "'"; + else + OS << "Objective-C method '-" << MD->getQualifiedNameAsString() << "'"; + } else if (isa<BlockDecl>(Parent)) { + if (cast<BlockDecl>(Parent)->isConversionFromLambda()) + OS << "lambda"; + else + OS << "block"; + } + + return std::string(OS.str()); + } + std::string VisitSVal(SVal V) { std::string Str; llvm::raw_string_ostream OS(Str); diff --git a/clang/include/clang/StaticAnalyzer/Core/Analyses.def b/clang/include/clang/StaticAnalyzer/Core/Analyses.def index 377451576148..c4e5f5be6fd7 100644 --- a/clang/include/clang/StaticAnalyzer/Core/Analyses.def +++ b/clang/include/clang/StaticAnalyzer/Core/Analyses.def @@ -14,41 +14,80 @@ #define ANALYSIS_STORE(NAME, CMDFLAG, DESC, CREATFN) #endif -ANALYSIS_STORE(RegionStore, "region", "Use region-based analyzer store", CreateRegionStoreManager) +ANALYSIS_STORE(RegionStore, "region", "Use region-based analyzer store", + CreateRegionStoreManager) #ifndef ANALYSIS_CONSTRAINTS #define ANALYSIS_CONSTRAINTS(NAME, CMDFLAG, DESC, CREATFN) #endif -ANALYSIS_CONSTRAINTS(RangeConstraints, "range", "Use constraint tracking of concrete value ranges", CreateRangeConstraintManager) -ANALYSIS_CONSTRAINTS(Z3Constraints, "z3", "Use Z3 contraint solver", CreateZ3ConstraintManager) +ANALYSIS_CONSTRAINTS(RangeConstraints, "range", + "Use constraint tracking of concrete value ranges", + CreateRangeConstraintManager) + +ANALYSIS_CONSTRAINTS(Z3Constraints, "z3", "Use Z3 contraint solver", + CreateZ3ConstraintManager) #ifndef ANALYSIS_DIAGNOSTICS #define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATEFN) #endif -ANALYSIS_DIAGNOSTICS(HTML, "html", "Output analysis results using HTML", createHTMLDiagnosticConsumer) -ANALYSIS_DIAGNOSTICS(HTML_SINGLE_FILE, "html-single-file", "Output analysis results using HTML (not allowing for multi-file bugs)", createHTMLSingleFileDiagnosticConsumer) -ANALYSIS_DIAGNOSTICS(PLIST, "plist", "Output analysis results using Plists", createPlistDiagnosticConsumer) -ANALYSIS_DIAGNOSTICS(PLIST_MULTI_FILE, "plist-multi-file", "Output analysis results using Plists (allowing for multi-file bugs)", createPlistMultiFileDiagnosticConsumer) -ANALYSIS_DIAGNOSTICS(PLIST_HTML, "plist-html", "Output analysis results using HTML wrapped with Plists", createPlistHTMLDiagnosticConsumer) -ANALYSIS_DIAGNOSTICS(SARIF, "sarif", "Output analysis results in a SARIF file", createSarifDiagnosticConsumer) -ANALYSIS_DIAGNOSTICS(TEXT, "text", "Text output of analysis results", createTextPathDiagnosticConsumer) +ANALYSIS_DIAGNOSTICS(HTML, "html", "Output analysis results using HTML", + createHTMLDiagnosticConsumer) + +ANALYSIS_DIAGNOSTICS( + HTML_SINGLE_FILE, "html-single-file", + "Output analysis results using HTML (not allowing for multi-file bugs)", + createHTMLSingleFileDiagnosticConsumer) + +ANALYSIS_DIAGNOSTICS(PLIST, "plist", "Output analysis results using Plists", + createPlistDiagnosticConsumer) + +ANALYSIS_DIAGNOSTICS( + PLIST_MULTI_FILE, "plist-multi-file", + "Output analysis results using Plists (allowing for multi-file bugs)", + createPlistMultiFileDiagnosticConsumer) + +ANALYSIS_DIAGNOSTICS(PLIST_HTML, "plist-html", + "Output analysis results using HTML wrapped with Plists", + createPlistHTMLDiagnosticConsumer) + +ANALYSIS_DIAGNOSTICS(SARIF, "sarif", "Output analysis results in a SARIF file", + createSarifDiagnosticConsumer) + +ANALYSIS_DIAGNOSTICS(TEXT, "text", "Text output of analysis results to stderr", + createTextPathDiagnosticConsumer) + +ANALYSIS_DIAGNOSTICS(TEXT_MINIMAL, "text-minimal", + "Emits minimal diagnostics to stderr, stating only the " + "warning message and the associated notes. Usually " + "used in addition to other analysis types", + createTextMinimalPathDiagnosticConsumer) #ifndef ANALYSIS_PURGE #define ANALYSIS_PURGE(NAME, CMDFLAG, DESC) #endif -ANALYSIS_PURGE(PurgeStmt, "statement", "Purge symbols, bindings, and constraints before every statement") -ANALYSIS_PURGE(PurgeBlock, "block", "Purge symbols, bindings, and constraints before every basic block") -ANALYSIS_PURGE(PurgeNone, "none", "Do not purge symbols, bindings, or constraints") +ANALYSIS_PURGE( + PurgeStmt, "statement", + "Purge symbols, bindings, and constraints before every statement") + +ANALYSIS_PURGE( + PurgeBlock, "block", + "Purge symbols, bindings, and constraints before every basic block") + +ANALYSIS_PURGE(PurgeNone, "none", + "Do not purge symbols, bindings, or constraints") #ifndef ANALYSIS_INLINING_MODE #define ANALYSIS_INLINING_MODE(NAME, CMDFLAG, DESC) #endif -ANALYSIS_INLINING_MODE(All, "all", "Analyze all functions as top level") -ANALYSIS_INLINING_MODE(NoRedundancy, "noredundancy", "Do not analyze a function which has been previously inlined") +ANALYSIS_INLINING_MODE(All, "all", "Analyze all functions as top level") + +ANALYSIS_INLINING_MODE( + NoRedundancy, "noredundancy", + "Do not analyze a function which has been previously inlined") #undef ANALYSIS_STORE #undef ANALYSIS_CONSTRAINTS @@ -56,4 +95,3 @@ ANALYSIS_INLINING_MODE(NoRedundancy, "noredundancy", "Do not analyze a function #undef ANALYSIS_PURGE #undef ANALYSIS_INLINING_MODE #undef ANALYSIS_IPA - diff --git a/clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def b/clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def index 00febf688195..f0359d2dbb3c 100644 --- a/clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def +++ b/clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def @@ -306,10 +306,14 @@ ANALYZER_OPTION(bool, ShouldTrackConditionsDebug, "track-conditions-debug", "Whether to place an event at each tracked condition.", false) -ANALYZER_OPTION(bool, ShouldEmitFixItHintsAsRemarks, "fixits-as-remarks", - "Emit fix-it hints as remarks for testing purposes", +ANALYZER_OPTION(bool, ShouldApplyFixIts, "apply-fixits", + "Apply the fix-it hints to the files", false) +ANALYZER_OPTION(bool, ShouldDisplayCheckerNameForText, "display-checker-name", + "Display the checker name for textual outputs", + true) + //===----------------------------------------------------------------------===// // Unsigned analyzer options. //===----------------------------------------------------------------------===// @@ -317,10 +321,17 @@ ANALYZER_OPTION(bool, ShouldEmitFixItHintsAsRemarks, "fixits-as-remarks", ANALYZER_OPTION(unsigned, CTUImportThreshold, "ctu-import-threshold", "The maximal amount of translation units that is considered " "for import when inlining functions during CTU analysis. " - "Lowering this threshold can alleviate the memory burder of " + "Lowering this threshold can alleviate the memory burden of " "analysis with many interdependent definitions located in " - "various translation units.", - 100u) + "various translation units. This is valid only for non C++ " + "source files.", + 24u) + +ANALYZER_OPTION(unsigned, CTUImportCppThreshold, "ctu-import-cpp-threshold", + "The maximal amount of translation units that is considered " + "for import when inlining functions during CTU analysis of C++ " + "source files.", + 8u) ANALYZER_OPTION( unsigned, AlwaysInlineSize, "ipa-always-inline-size", @@ -374,10 +385,25 @@ ANALYZER_OPTION(StringRef, CTUDir, "ctu-dir", "The directory containing the CTU related files.", "") ANALYZER_OPTION(StringRef, CTUIndexName, "ctu-index-name", - "the name of the file containing the CTU index of definitions.", + "The name of the file containing the CTU index of definitions. " + "The index file maps USR-names to identifiers. An identifier " + "can end with an '.ast' suffix, indicating the indentifier is " + "a path to a pch-dump. Otherwise the identifier is regarded as " + "path to a source file which is parsed on-demand. Relative " + "paths are prefixed with ctu-dir, absolute paths are used " + "unmodified during lookup.", "externalDefMap.txt") ANALYZER_OPTION( + StringRef, CTUInvocationList, "ctu-invocation-list", + "The path to the YAML format file containing a mapping from source file " + "paths to command-line invocations represented as a list of arguments. " + "This invocation is used produce the source-file's AST in case on-demand " + "loading is performed. Example file-content: " + "{/main.cpp: [clang++, /main.cpp], other.cpp: [clang++, /other.cpp]}", + "invocations.yaml") + +ANALYZER_OPTION( StringRef, ModelPath, "model-path", "The analyzer can inline an alternative implementation written in C at the " "call site if the called function's body is not available. This is a path " diff --git a/clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h b/clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h index ce16095e10c0..d2df24a6e21b 100644 --- a/clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h +++ b/clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h @@ -292,9 +292,7 @@ public: }; bool isUnknownAnalyzerConfig(StringRef Name) const { - - assert(std::is_sorted(AnalyzerConfigCmdFlags.begin(), - AnalyzerConfigCmdFlags.end())); + assert(llvm::is_sorted(AnalyzerConfigCmdFlags)); return !std::binary_search(AnalyzerConfigCmdFlags.begin(), AnalyzerConfigCmdFlags.end(), Name); diff --git a/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h b/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h index 69593e2b6c93..27bc0dda1f1c 100644 --- a/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h +++ b/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h @@ -17,12 +17,14 @@ #include "clang/Analysis/PathDiagnostic.h" #include "clang/Basic/LLVM.h" #include "clang/Basic/SourceLocation.h" +#include "clang/Lex/Preprocessor.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h" +#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/CheckerManager.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h" #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h" #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h" #include "clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h" -#include "clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/FoldingSet.h" @@ -134,7 +136,7 @@ protected: SmallVector<FixItHint, 4> Fixits; BugReport(Kind kind, const BugType &bt, StringRef desc) - : K(kind), BT(bt), Description(desc) {} + : BugReport(kind, bt, "", desc) {} BugReport(Kind K, const BugType &BT, StringRef ShortDescription, StringRef Description) @@ -368,16 +370,13 @@ protected: public: PathSensitiveBugReport(const BugType &bt, StringRef desc, const ExplodedNode *errorNode) - : BugReport(Kind::PathSensitive, bt, desc), ErrorNode(errorNode), - ErrorNodeRange(getStmt() ? getStmt()->getSourceRange() - : SourceRange()) {} + : PathSensitiveBugReport(bt, desc, desc, errorNode) {} PathSensitiveBugReport(const BugType &bt, StringRef shortDesc, StringRef desc, const ExplodedNode *errorNode) - : BugReport(Kind::PathSensitive, bt, shortDesc, desc), - ErrorNode(errorNode), - ErrorNodeRange(getStmt() ? getStmt()->getSourceRange() - : SourceRange()) {} + : PathSensitiveBugReport(bt, shortDesc, desc, errorNode, + /*LocationToUnique*/ {}, + /*DeclToUnique*/ nullptr) {} /// Create a PathSensitiveBugReport with a custom uniqueing location. /// @@ -390,11 +389,13 @@ public: const ExplodedNode *errorNode, PathDiagnosticLocation LocationToUnique, const Decl *DeclToUnique) - : BugReport(Kind::PathSensitive, bt, desc), ErrorNode(errorNode), - ErrorNodeRange(getStmt() ? getStmt()->getSourceRange() : SourceRange()), - UniqueingLocation(LocationToUnique), UniqueingDecl(DeclToUnique) { - assert(errorNode); - } + : PathSensitiveBugReport(bt, desc, desc, errorNode, LocationToUnique, + DeclToUnique) {} + + PathSensitiveBugReport(const BugType &bt, StringRef shortDesc, StringRef desc, + const ExplodedNode *errorNode, + PathDiagnosticLocation LocationToUnique, + const Decl *DeclToUnique); static bool classof(const BugReport *R) { return R->getKind() == Kind::PathSensitive; @@ -566,6 +567,7 @@ public: virtual ASTContext &getASTContext() = 0; virtual SourceManager &getSourceManager() = 0; virtual AnalyzerOptions &getAnalyzerOptions() = 0; + virtual Preprocessor &getPreprocessor() = 0; }; /// BugReporter is a utility class for generating PathDiagnostics for analysis. @@ -587,7 +589,7 @@ private: std::vector<BugReportEquivClass *> EQClassesVector; public: - BugReporter(BugReporterData &d) : D(d) {} + BugReporter(BugReporterData &d); virtual ~BugReporter(); /// Generate and flush diagnostics for all bug reports. @@ -608,6 +610,8 @@ public: const AnalyzerOptions &getAnalyzerOptions() { return D.getAnalyzerOptions(); } + Preprocessor &getPreprocessor() { return D.getPreprocessor(); } + /// Add the given report to the set of reports tracked by BugReporter. /// /// The reports are usually generated by the checkers. Further, they are @@ -628,7 +632,7 @@ public: ArrayRef<FixItHint> Fixits = None); private: - llvm::StringMap<BugType *> StrBugTypes; + llvm::StringMap<std::unique_ptr<BugType>> StrBugTypes; /// Returns a BugType that is associated with the given name and /// category. @@ -722,7 +726,8 @@ public: class NoteTag : public ProgramPointTag { public: using Callback = - std::function<std::string(BugReporterContext &, BugReport &)>; + std::function<std::string(BugReporterContext &, + PathSensitiveBugReport &)>; private: static int Kind; @@ -739,7 +744,7 @@ public: } Optional<std::string> generateMessage(BugReporterContext &BRC, - BugReport &R) const { + PathSensitiveBugReport &R) const { std::string Msg = Cb(BRC, R); if (Msg.empty()) return None; diff --git a/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h b/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h index de0ee5de81b5..365b1ff1bfe3 100644 --- a/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h +++ b/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h @@ -386,6 +386,8 @@ public: void finalizeVisitor(BugReporterContext &BRC, const ExplodedNode *EndPathNode, PathSensitiveBugReport &BR) override; + void addConstraints(const ExplodedNode *N, + bool OverwriteConstraintsOnExistingSyms); }; diff --git a/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h b/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h index 237053df7e44..49ab25eca2dd 100644 --- a/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h +++ b/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h @@ -78,13 +78,16 @@ public: const char *description) : BugType(checker, name, categories::LogicError), desc(description) {} + BuiltinBug(class CheckerNameRef checker, const char *name) + : BugType(checker, name, categories::LogicError), desc(name) {} + BuiltinBug(const CheckerBase *checker, const char *name) : BugType(checker, name, categories::LogicError), desc(name) {} StringRef getDescription() const { return desc; } }; -} // end ento namespace +} // namespace ento } // end clang namespace #endif diff --git a/clang/include/clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h b/clang/include/clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h index 22c1a7dd98cc..637b89fd9036 100644 --- a/clang/include/clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h +++ b/clang/include/clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h @@ -11,16 +11,16 @@ // Common strings used for the "category" of many static analyzer issues. namespace clang { - namespace ento { - namespace categories { - extern const char * const CoreFoundationObjectiveC; - extern const char * const LogicError; - extern const char * const MemoryRefCount; - extern const char * const MemoryError; - extern const char * const UnixAPI; - extern const char * const CXXObjectLifecycle; - } - } -} +namespace ento { +namespace categories { +extern const char *const CoreFoundationObjectiveC; +extern const char *const LogicError; +extern const char *const MemoryRefCount; +extern const char *const MemoryError; +extern const char *const UnixAPI; +extern const char *const CXXObjectLifecycle; +extern const char *const SecurityError; +} // namespace categories +} // namespace ento +} // namespace clang #endif - diff --git a/clang/include/clang/StaticAnalyzer/Core/Checker.h b/clang/include/clang/StaticAnalyzer/Core/Checker.h index 0c7acdbc3a97..fdba49664615 100644 --- a/clang/include/clang/StaticAnalyzer/Core/Checker.h +++ b/clang/include/clang/StaticAnalyzer/Core/Checker.h @@ -285,9 +285,9 @@ public: class NewAllocator { template <typename CHECKER> - static void _checkNewAllocator(void *checker, const CXXNewExpr *NE, - SVal Target, CheckerContext &C) { - ((const CHECKER *)checker)->checkNewAllocator(NE, Target, C); + static void _checkNewAllocator(void *checker, const CXXAllocatorCall &Call, + CheckerContext &C) { + ((const CHECKER *)checker)->checkNewAllocator(Call, C); } public: diff --git a/clang/include/clang/StaticAnalyzer/Core/CheckerManager.h b/clang/include/clang/StaticAnalyzer/Core/CheckerManager.h index 246ff8f90d35..d2f71baa56a4 100644 --- a/clang/include/clang/StaticAnalyzer/Core/CheckerManager.h +++ b/clang/include/clang/StaticAnalyzer/Core/CheckerManager.h @@ -14,6 +14,7 @@ #define LLVM_CLANG_STATICANALYZER_CORE_CHECKERMANAGER_H #include "clang/Analysis/ProgramPoint.h" +#include "clang/Basic/Diagnostic.h" #include "clang/Basic/LangOptions.h" #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h" #include "clang/StaticAnalyzer/Core/PathSensitive/Store.h" @@ -36,15 +37,18 @@ class TranslationUnitDecl; namespace ento { class AnalysisManager; +class CXXAllocatorCall; class BugReporter; class CallEvent; class CheckerBase; class CheckerContext; class CheckerRegistry; +struct CheckerRegistryData; class ExplodedGraph; class ExplodedNode; class ExplodedNodeSet; class ExprEngine; +struct EvalCallOptions; class MemRegion; struct NodeBuilderContext; class ObjCMethodCall; @@ -121,14 +125,38 @@ enum class ObjCMessageVisitKind { }; class CheckerManager { - ASTContext &Context; + ASTContext *Context = nullptr; const LangOptions LangOpts; - AnalyzerOptions &AOptions; + const AnalyzerOptions &AOptions; + const Preprocessor *PP = nullptr; CheckerNameRef CurrentCheckerName; + DiagnosticsEngine &Diags; + std::unique_ptr<CheckerRegistryData> RegistryData; public: - CheckerManager(ASTContext &Context, AnalyzerOptions &AOptions) - : Context(Context), LangOpts(Context.getLangOpts()), AOptions(AOptions) {} + // These constructors are defined in the Frontend library, because + // CheckerRegistry, a crucial component of the initialization is in there. + // CheckerRegistry cannot be moved to the Core library, because the checker + // registration functions are defined in the Checkers library, and the library + // dependencies look like this: Core -> Checkers -> Frontend. + + CheckerManager( + ASTContext &Context, AnalyzerOptions &AOptions, const Preprocessor &PP, + ArrayRef<std::string> plugins, + ArrayRef<std::function<void(CheckerRegistry &)>> checkerRegistrationFns); + + /// Constructs a CheckerManager that ignores all non TblGen-generated + /// checkers. Useful for unit testing, unless the checker infrastructure + /// itself is tested. + CheckerManager(ASTContext &Context, AnalyzerOptions &AOptions, + const Preprocessor &PP) + : CheckerManager(Context, AOptions, PP, {}, {}) {} + + /// Constructs a CheckerManager without requiring an AST. No checker + /// registration will take place. Only useful when one needs to print the + /// help flags through CheckerRegistryData, and the AST is unavalaible. + CheckerManager(AnalyzerOptions &AOptions, const LangOptions &LangOpts, + DiagnosticsEngine &Diags, ArrayRef<std::string> plugins); ~CheckerManager(); @@ -140,14 +168,25 @@ public: void finishedCheckerRegistration(); const LangOptions &getLangOpts() const { return LangOpts; } - AnalyzerOptions &getAnalyzerOptions() { return AOptions; } - ASTContext &getASTContext() { return Context; } + const AnalyzerOptions &getAnalyzerOptions() const { return AOptions; } + const Preprocessor &getPreprocessor() const { + assert(PP); + return *PP; + } + const CheckerRegistryData &getCheckerRegistryData() const { + return *RegistryData; + } + DiagnosticsEngine &getDiagnostics() const { return Diags; } + ASTContext &getASTContext() const { + assert(Context); + return *Context; + } /// Emits an error through a DiagnosticsEngine about an invalid user supplied /// checker option value. void reportInvalidCheckerOptionValue(const CheckerBase *C, StringRef OptionName, - StringRef ExpectedValueDesc); + StringRef ExpectedValueDesc) const; using CheckerRef = CheckerBase *; using CheckerTag = const void *; @@ -327,11 +366,9 @@ public: ExprEngine &Eng); /// Run checkers between C++ operator new and constructor calls. - void runCheckersForNewAllocator(const CXXNewExpr *NE, SVal Target, - ExplodedNodeSet &Dst, - ExplodedNode *Pred, - ExprEngine &Eng, - bool wasInlined = false); + void runCheckersForNewAllocator(const CXXAllocatorCall &Call, + ExplodedNodeSet &Dst, ExplodedNode *Pred, + ExprEngine &Eng, bool wasInlined = false); /// Run checkers for live symbols. /// @@ -400,9 +437,9 @@ public: /// Run checkers for evaluating a call. /// /// Warning: Currently, the CallEvent MUST come from a CallExpr! - void runCheckersForEvalCall(ExplodedNodeSet &Dst, - const ExplodedNodeSet &Src, - const CallEvent &CE, ExprEngine &Eng); + void runCheckersForEvalCall(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, + const CallEvent &CE, ExprEngine &Eng, + const EvalCallOptions &CallOpts); /// Run checkers for the entire Translation Unit. void runCheckersOnEndOfTranslationUnit(const TranslationUnitDecl *TU, @@ -472,7 +509,7 @@ public: CheckerFn<void (const Stmt *, CheckerContext &)>; using CheckNewAllocatorFunc = - CheckerFn<void (const CXXNewExpr *, SVal, CheckerContext &)>; + CheckerFn<void(const CXXAllocatorCall &Call, CheckerContext &)>; using CheckDeadSymbolsFunc = CheckerFn<void (SymbolReaper &, CheckerContext &)>; @@ -620,7 +657,7 @@ private: /// Returns the checkers that have registered for callbacks of the /// given \p Kind. const std::vector<CheckObjCMessageFunc> & - getObjCMessageCheckers(ObjCMessageVisitKind Kind); + getObjCMessageCheckers(ObjCMessageVisitKind Kind) const; std::vector<CheckObjCMessageFunc> PreObjCMessageCheckers; std::vector<CheckObjCMessageFunc> PostObjCMessageCheckers; diff --git a/clang/include/clang/StaticAnalyzer/Core/CheckerRegistryData.h b/clang/include/clang/StaticAnalyzer/Core/CheckerRegistryData.h new file mode 100644 index 000000000000..43248d8e6bb8 --- /dev/null +++ b/clang/include/clang/StaticAnalyzer/Core/CheckerRegistryData.h @@ -0,0 +1,226 @@ +//===- CheckerRegistryData.h ------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file contains the data structures to which the TableGen file Checkers.td +// maps to, as well as what was parsed from the the specific invocation (whether +// a checker/package is enabled, their options values, etc). +// +// The parsing of the invocation is done by CheckerRegistry, which is found in +// the Frontend library. This allows the Core and Checkers libraries to utilize +// this information, such as enforcing rules on checker dependency bug emission, +// ensuring all checker options were queried, etc. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_STATICANALYZER_CORE_CHECKERREGISTRYDATA_H +#define LLVM_CLANG_STATICANALYZER_CORE_CHECKERREGISTRYDATA_H + +#include "clang/Basic/LLVM.h" +#include "llvm/ADT/SetVector.h" +#include "llvm/ADT/StringMap.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/raw_ostream.h" + +namespace clang { + +class AnalyzerOptions; + +namespace ento { + +class CheckerManager; + +/// Initialization functions perform any necessary setup for a checker. +/// They should include a call to CheckerManager::registerChecker. +using RegisterCheckerFn = void (*)(CheckerManager &); +using ShouldRegisterFunction = bool (*)(const CheckerManager &); + +/// Specifies a command line option. It may either belong to a checker or a +/// package. +struct CmdLineOption { + StringRef OptionType; + StringRef OptionName; + StringRef DefaultValStr; + StringRef Description; + StringRef DevelopmentStatus; + bool IsHidden; + + CmdLineOption(StringRef OptionType, StringRef OptionName, + StringRef DefaultValStr, StringRef Description, + StringRef DevelopmentStatus, bool IsHidden) + : OptionType(OptionType), OptionName(OptionName), + DefaultValStr(DefaultValStr), Description(Description), + DevelopmentStatus(DevelopmentStatus), IsHidden(IsHidden) { + + assert((OptionType == "bool" || OptionType == "string" || + OptionType == "int") && + "Unknown command line option type!"); + + assert((OptionType != "bool" || + (DefaultValStr == "true" || DefaultValStr == "false")) && + "Invalid value for boolean command line option! Maybe incorrect " + "parameters to the addCheckerOption or addPackageOption method?"); + + int Tmp; + assert((OptionType != "int" || !DefaultValStr.getAsInteger(0, Tmp)) && + "Invalid value for integer command line option! Maybe incorrect " + "parameters to the addCheckerOption or addPackageOption method?"); + (void)Tmp; + + assert((DevelopmentStatus == "alpha" || DevelopmentStatus == "beta" || + DevelopmentStatus == "released") && + "Invalid development status!"); + } + + LLVM_DUMP_METHOD void dump() const; + LLVM_DUMP_METHOD void dumpToStream(llvm::raw_ostream &Out) const; +}; + +using CmdLineOptionList = llvm::SmallVector<CmdLineOption, 0>; + +struct CheckerInfo; + +using CheckerInfoList = std::vector<CheckerInfo>; +using CheckerInfoListRange = llvm::iterator_range<CheckerInfoList::iterator>; +using ConstCheckerInfoList = llvm::SmallVector<const CheckerInfo *, 0>; +using CheckerInfoSet = llvm::SetVector<const CheckerInfo *>; + +/// Specifies a checker. Note that this isn't what we call a checker object, +/// it merely contains everything required to create one. +struct CheckerInfo { + enum class StateFromCmdLine { + // This checker wasn't explicitly enabled or disabled. + State_Unspecified, + // This checker was explicitly disabled. + State_Disabled, + // This checker was explicitly enabled. + State_Enabled + }; + + RegisterCheckerFn Initialize = nullptr; + ShouldRegisterFunction ShouldRegister = nullptr; + StringRef FullName; + StringRef Desc; + StringRef DocumentationUri; + CmdLineOptionList CmdLineOptions; + bool IsHidden = false; + StateFromCmdLine State = StateFromCmdLine::State_Unspecified; + + ConstCheckerInfoList Dependencies; + ConstCheckerInfoList WeakDependencies; + + bool isEnabled(const CheckerManager &mgr) const { + return State == StateFromCmdLine::State_Enabled && ShouldRegister(mgr); + } + + bool isDisabled(const CheckerManager &mgr) const { + return State == StateFromCmdLine::State_Disabled || !ShouldRegister(mgr); + } + + // Since each checker must have a different full name, we can identify + // CheckerInfo objects by them. + bool operator==(const CheckerInfo &Rhs) const { + return FullName == Rhs.FullName; + } + + CheckerInfo(RegisterCheckerFn Fn, ShouldRegisterFunction sfn, StringRef Name, + StringRef Desc, StringRef DocsUri, bool IsHidden) + : Initialize(Fn), ShouldRegister(sfn), FullName(Name), Desc(Desc), + DocumentationUri(DocsUri), IsHidden(IsHidden) {} + + // Used for lower_bound. + explicit CheckerInfo(StringRef FullName) : FullName(FullName) {} + + LLVM_DUMP_METHOD void dump() const; + LLVM_DUMP_METHOD void dumpToStream(llvm::raw_ostream &Out) const; +}; + +using StateFromCmdLine = CheckerInfo::StateFromCmdLine; + +/// Specifies a package. Each package option is implicitly an option for all +/// checkers within the package. +struct PackageInfo { + StringRef FullName; + CmdLineOptionList CmdLineOptions; + + // Since each package must have a different full name, we can identify + // CheckerInfo objects by them. + bool operator==(const PackageInfo &Rhs) const { + return FullName == Rhs.FullName; + } + + explicit PackageInfo(StringRef FullName) : FullName(FullName) {} + + LLVM_DUMP_METHOD void dump() const; + LLVM_DUMP_METHOD void dumpToStream(llvm::raw_ostream &Out) const; +}; + +using PackageInfoList = llvm::SmallVector<PackageInfo, 0>; + +namespace checker_registry { + +template <class T> struct FullNameLT { + bool operator()(const T &Lhs, const T &Rhs) { + return Lhs.FullName < Rhs.FullName; + } +}; + +using PackageNameLT = FullNameLT<PackageInfo>; +using CheckerNameLT = FullNameLT<CheckerInfo>; + +template <class CheckerOrPackageInfoList> +std::conditional_t<std::is_const<CheckerOrPackageInfoList>::value, + typename CheckerOrPackageInfoList::const_iterator, + typename CheckerOrPackageInfoList::iterator> +binaryFind(CheckerOrPackageInfoList &Collection, StringRef FullName) { + + using CheckerOrPackage = typename CheckerOrPackageInfoList::value_type; + using CheckerOrPackageFullNameLT = FullNameLT<CheckerOrPackage>; + + assert(llvm::is_sorted(Collection, CheckerOrPackageFullNameLT{}) && + "In order to efficiently gather checkers/packages, this function " + "expects them to be already sorted!"); + + return llvm::lower_bound(Collection, CheckerOrPackage(FullName), + CheckerOrPackageFullNameLT{}); +} +} // namespace checker_registry + +struct CheckerRegistryData { +public: + CheckerInfoSet EnabledCheckers; + + CheckerInfoList Checkers; + PackageInfoList Packages; + /// Used for counting how many checkers belong to a certain package in the + /// \c Checkers field. For convenience purposes. + llvm::StringMap<size_t> PackageSizes; + + /// Contains all (FullName, CmdLineOption) pairs. Similarly to dependencies, + /// we only modify the actual CheckerInfo and PackageInfo objects once all + /// of them have been added. + llvm::SmallVector<std::pair<StringRef, CmdLineOption>, 0> PackageOptions; + llvm::SmallVector<std::pair<StringRef, CmdLineOption>, 0> CheckerOptions; + + llvm::SmallVector<std::pair<StringRef, StringRef>, 0> Dependencies; + llvm::SmallVector<std::pair<StringRef, StringRef>, 0> WeakDependencies; + + CheckerInfoListRange getMutableCheckersForCmdLineArg(StringRef CmdLineArg); + + /// Prints the name and description of all checkers in this registry. + /// This output is not intended to be machine-parseable. + void printCheckerWithDescList(const AnalyzerOptions &AnOpts, raw_ostream &Out, + size_t MaxNameChars = 30) const; + void printEnabledCheckerList(raw_ostream &Out) const; + void printCheckerOptionList(const AnalyzerOptions &AnOpts, + raw_ostream &Out) const; +}; + +} // namespace ento +} // namespace clang + +#endif // LLVM_CLANG_STATICANALYZER_CORE_CHECKERREGISTRYDATA_H diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h index d605a6a667f6..c76e9c0326af 100644 --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h @@ -16,6 +16,7 @@ #include "clang/Analysis/AnalysisDeclContext.h" #include "clang/Analysis/PathDiagnostic.h" +#include "clang/Lex/Preprocessor.h" #include "clang/StaticAnalyzer/Core/AnalyzerOptions.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h" #include "clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h" @@ -32,6 +33,7 @@ class AnalysisManager : public BugReporterData { AnalysisDeclContextManager AnaCtxMgr; ASTContext &Ctx; + Preprocessor &PP; const LangOptions &LangOpts; PathDiagnosticConsumers PathConsumers; @@ -44,7 +46,7 @@ class AnalysisManager : public BugReporterData { public: AnalyzerOptions &options; - AnalysisManager(ASTContext &ctx, + AnalysisManager(ASTContext &ctx, Preprocessor &PP, const PathDiagnosticConsumers &Consumers, StoreManagerCreator storemgr, ConstraintManagerCreator constraintmgr, @@ -61,6 +63,8 @@ public: return AnaCtxMgr; } + Preprocessor &getPreprocessor() override { return PP; } + StoreManagerCreator getStoreManagerCreator() { return CreateStoreMgr; } diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h index ac218bc070e9..a001c0dc7030 100644 --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h @@ -157,6 +157,10 @@ public: const llvm::APSInt &Convert(QualType T, const llvm::APSInt &From) { APSIntType TargetType = getAPSIntType(T); + return Convert(TargetType, From); + } + + const llvm::APSInt &Convert(APSIntType TargetType, const llvm::APSInt &From) { if (TargetType == APSIntType(From)) return From; @@ -177,11 +181,19 @@ public: } const llvm::APSInt &getMaxValue(QualType T) { - return getValue(getAPSIntType(T).getMaxValue()); + return getMaxValue(getAPSIntType(T)); } const llvm::APSInt &getMinValue(QualType T) { - return getValue(getAPSIntType(T).getMinValue()); + return getMinValue(getAPSIntType(T)); + } + + const llvm::APSInt &getMaxValue(APSIntType T) { + return getValue(T.getMaxValue()); + } + + const llvm::APSInt &getMinValue(APSIntType T) { + return getValue(T.getMinValue()); } const llvm::APSInt &Add1(const llvm::APSInt &V) { diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h index fc1cc9138826..a2a98c558a4b 100644 --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h @@ -39,6 +39,7 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" +#include "llvm/ADT/iterator_range.h" #include "llvm/Support/Allocator.h" #include "llvm/Support/Casting.h" #include "llvm/Support/ErrorHandling.h" @@ -63,9 +64,13 @@ enum CallEventKind { CE_BEG_CXX_INSTANCE_CALLS = CE_CXXMember, CE_END_CXX_INSTANCE_CALLS = CE_CXXDestructor, CE_CXXConstructor, + CE_CXXInheritedConstructor, + CE_BEG_CXX_CONSTRUCTOR_CALLS = CE_CXXConstructor, + CE_END_CXX_CONSTRUCTOR_CALLS = CE_CXXInheritedConstructor, CE_CXXAllocator, + CE_CXXDeallocator, CE_BEG_FUNCTION_CALLS = CE_Function, - CE_END_FUNCTION_CALLS = CE_CXXAllocator, + CE_END_FUNCTION_CALLS = CE_CXXDeallocator, CE_Block, CE_ObjCMessage }; @@ -196,6 +201,7 @@ public: /// Returns the kind of call this is. virtual Kind getKind() const = 0; + virtual StringRef getKindAsString() const = 0; /// Returns the declaration of the function or method that will be /// called. May be null. @@ -258,6 +264,13 @@ public: /// calls. bool isCalled(const CallDescription &CD) const; + /// Returns true whether the CallEvent is any of the CallDescriptions supplied + /// as a parameter. + template <typename FirstCallDesc, typename... CallDescs> + bool isCalled(const FirstCallDesc &First, const CallDescs &... Rest) const { + return isCalled(First) || isCalled(Rest...); + } + /// Returns a source range for the entire call, suitable for /// outputting in diagnostics. virtual SourceRange getSourceRange() const { @@ -389,9 +402,10 @@ public: const StackFrameContext *getCalleeStackFrame(unsigned BlockCount) const; /// Returns memory location for a parameter variable within the callee stack - /// frame. May fail; returns null on failure. - const VarRegion *getParameterLocation(unsigned Index, - unsigned BlockCount) const; + /// frame. The behavior is undefined if the block count is different from the + /// one that is there when call happens. May fail; returns null on failure. + const ParamVarRegion *getParameterLocation(unsigned Index, + unsigned BlockCount) const; /// Returns true if on the current path, the argument was constructed by /// calling a C++ constructor over it. This is an internal detail of the @@ -421,6 +435,15 @@ public: return CallArgumentIndex; } + /// Returns the construction context of the call, if it is a C++ constructor + /// call or a call of a function returning a C++ class instance. Otherwise + /// return nullptr. + const ConstructionContext *getConstructionContext() const; + + /// If the call returns a C++ record type then the region of its return value + /// can be retrieved from its construction context. + Optional<SVal> getReturnValueUnderConstruction() const; + // Iterator access to formal parameters and their types. private: struct GetTypeFn { @@ -520,6 +543,9 @@ public: } Kind getKind() const override { return CE_Function; } + virtual StringRef getKindAsString() const override { + return "SimpleFunctionCall"; + } static bool classof(const CallEvent *CA) { return CA->getKind() == CE_Function; @@ -528,7 +554,7 @@ public: /// Represents a call to a block. /// -/// Example: <tt>^{ /* ... */ }()</tt> +/// Example: <tt>^{ statement-body }()</tt> class BlockCall : public CallEvent { friend class CallEventManager; @@ -624,13 +650,12 @@ public: void getInitialStackFrameContents(const StackFrameContext *CalleeCtx, BindingsTy &Bindings) const override; - ArrayRef<ParmVarDecl*> parameters() const override; + ArrayRef<ParmVarDecl *> parameters() const override; Kind getKind() const override { return CE_Block; } + virtual StringRef getKindAsString() const override { return "BlockCall"; } - static bool classof(const CallEvent *CA) { - return CA->getKind() == CE_Block; - } + static bool classof(const CallEvent *CA) { return CA->getKind() == CE_Block; } }; /// Represents a non-static C++ member function call, no matter how @@ -702,6 +727,7 @@ public: RuntimeDefinition getRuntimeDefinition() const override; Kind getKind() const override { return CE_CXXMember; } + virtual StringRef getKindAsString() const override { return "CXXMemberCall"; } static bool classof(const CallEvent *CA) { return CA->getKind() == CE_CXXMember; @@ -741,6 +767,9 @@ public: const Expr *getCXXThisExpr() const override; Kind getKind() const override { return CE_CXXMemberOperator; } + virtual StringRef getKindAsString() const override { + return "CXXMemberOperatorCall"; + } static bool classof(const CallEvent *CA) { return CA->getKind() == CE_CXXMemberOperator; @@ -759,6 +788,10 @@ public: // to implicit this-parameter on the declaration. return CallArgumentIndex + 1; } + + OverloadedOperatorKind getOverloadedOperator() const { + return getOriginExpr()->getOperator(); + } }; /// Represents an implicit call to a C++ destructor. @@ -805,16 +838,47 @@ public: } Kind getKind() const override { return CE_CXXDestructor; } + virtual StringRef getKindAsString() const override { + return "CXXDestructorCall"; + } static bool classof(const CallEvent *CA) { return CA->getKind() == CE_CXXDestructor; } }; +/// Represents any constructor invocation. This includes regular constructors +/// and inherited constructors. +class AnyCXXConstructorCall : public AnyFunctionCall { +protected: + AnyCXXConstructorCall(const Expr *E, const MemRegion *Target, + ProgramStateRef St, const LocationContext *LCtx) + : AnyFunctionCall(E, St, LCtx) { + assert(E && (isa<CXXConstructExpr>(E) || isa<CXXInheritedCtorInitExpr>(E))); + // Target may be null when the region is unknown. + Data = Target; + } + + void getExtraInvalidatedValues(ValueList &Values, + RegionAndSymbolInvalidationTraits *ETraits) const override; + + void getInitialStackFrameContents(const StackFrameContext *CalleeCtx, + BindingsTy &Bindings) const override; + +public: + /// Returns the value of the implicit 'this' object. + SVal getCXXThisVal() const; + + static bool classof(const CallEvent *Call) { + return Call->getKind() >= CE_BEG_CXX_CONSTRUCTOR_CALLS && + Call->getKind() <= CE_END_CXX_CONSTRUCTOR_CALLS; + } +}; + /// Represents a call to a C++ constructor. /// /// Example: \c T(1) -class CXXConstructorCall : public AnyFunctionCall { +class CXXConstructorCall : public AnyCXXConstructorCall { friend class CallEventManager; protected: @@ -827,17 +891,12 @@ protected: /// \param LCtx The location context at this point in the program. CXXConstructorCall(const CXXConstructExpr *CE, const MemRegion *Target, ProgramStateRef St, const LocationContext *LCtx) - : AnyFunctionCall(CE, St, LCtx) { - Data = Target; - } + : AnyCXXConstructorCall(CE, Target, St, LCtx) {} CXXConstructorCall(const CXXConstructorCall &Other) = default; void cloneTo(void *Dest) const override { new (Dest) CXXConstructorCall(*this); } - void getExtraInvalidatedValues(ValueList &Values, - RegionAndSymbolInvalidationTraits *ETraits) const override; - public: virtual const CXXConstructExpr *getOriginExpr() const { return cast<CXXConstructExpr>(AnyFunctionCall::getOriginExpr()); @@ -853,19 +912,96 @@ public: return getOriginExpr()->getArg(Index); } - /// Returns the value of the implicit 'this' object. - SVal getCXXThisVal() const; - - void getInitialStackFrameContents(const StackFrameContext *CalleeCtx, - BindingsTy &Bindings) const override; - Kind getKind() const override { return CE_CXXConstructor; } + virtual StringRef getKindAsString() const override { + return "CXXConstructorCall"; + } static bool classof(const CallEvent *CA) { return CA->getKind() == CE_CXXConstructor; } }; +/// Represents a call to a C++ inherited constructor. +/// +/// Example: \c class T : public S { using S::S; }; T(1); +/// +// Note, it is difficult to model the parameters. This is one of the reasons +// why we skip analysis of inheriting constructors as top-level functions. +// CXXInheritedCtorInitExpr doesn't take arguments and doesn't model parameter +// initialization because there is none: the arguments in the outer +// CXXConstructExpr directly initialize the parameters of the base class +// constructor, and no copies are made. (Making a copy of the parameter is +// incorrect, at least if it's done in an observable way.) The derived class +// constructor doesn't even exist in the formal model. +/// E.g., in: +/// +/// struct X { X *p = this; ~X() {} }; +/// struct A { A(X x) : b(x.p == &x) {} bool b; }; +/// struct B : A { using A::A; }; +/// B b = X{}; +/// +/// ... b.b is initialized to true. +class CXXInheritedConstructorCall : public AnyCXXConstructorCall { + friend class CallEventManager; + +protected: + CXXInheritedConstructorCall(const CXXInheritedCtorInitExpr *CE, + const MemRegion *Target, ProgramStateRef St, + const LocationContext *LCtx) + : AnyCXXConstructorCall(CE, Target, St, LCtx) {} + + CXXInheritedConstructorCall(const CXXInheritedConstructorCall &Other) = + default; + + void cloneTo(void *Dest) const override { + new (Dest) CXXInheritedConstructorCall(*this); + } + +public: + virtual const CXXInheritedCtorInitExpr *getOriginExpr() const { + return cast<CXXInheritedCtorInitExpr>(AnyFunctionCall::getOriginExpr()); + } + + const CXXConstructorDecl *getDecl() const override { + return getOriginExpr()->getConstructor(); + } + + /// Obtain the stack frame of the inheriting constructor. Argument expressions + /// can be found on the call site of that stack frame. + const StackFrameContext *getInheritingStackFrame() const; + + /// Obtain the CXXConstructExpr for the sub-class that inherited the current + /// constructor (possibly indirectly). It's the statement that contains + /// argument expressions. + const CXXConstructExpr *getInheritingConstructor() const { + return cast<CXXConstructExpr>(getInheritingStackFrame()->getCallSite()); + } + + unsigned getNumArgs() const override { + return getInheritingConstructor()->getNumArgs(); + } + + const Expr *getArgExpr(unsigned Index) const override { + return getInheritingConstructor()->getArg(Index); + } + + virtual SVal getArgSVal(unsigned Index) const override { + return getState()->getSVal( + getArgExpr(Index), + getInheritingStackFrame()->getParent()->getStackFrame()); + } + + Kind getKind() const override { return CE_CXXInheritedConstructor; } + virtual StringRef getKindAsString() const override { + return "CXXInheritedConstructorCall"; + } + + static bool classof(const CallEvent *CA) { + return CA->getKind() == CE_CXXInheritedConstructor; + } +}; + /// Represents the memory allocation call in a C++ new-expression. /// /// This is a call to "operator new". @@ -889,6 +1025,12 @@ public: return getOriginExpr()->getOperatorNew(); } + SVal getObjectUnderConstruction() const { + return ExprEngine::getObjectUnderConstruction(getState(), getOriginExpr(), + getLocationContext()) + .getValue(); + } + /// Number of non-placement arguments to the call. It is equal to 2 for /// C++17 aligned operator new() calls that have alignment implicitly /// passed as the second argument, and to 1 for other operator new() calls. @@ -916,12 +1058,64 @@ public: } Kind getKind() const override { return CE_CXXAllocator; } + virtual StringRef getKindAsString() const override { + return "CXXAllocatorCall"; + } static bool classof(const CallEvent *CE) { return CE->getKind() == CE_CXXAllocator; } }; +/// Represents the memory deallocation call in a C++ delete-expression. +/// +/// This is a call to "operator delete". +// FIXME: CXXDeleteExpr isn't present for custom delete operators, or even for +// some those that are in the standard library, like the no-throw or align_val +// versions. +// Some pointers: +// http://lists.llvm.org/pipermail/cfe-dev/2020-April/065080.html +// clang/test/Analysis/cxx-dynamic-memory-analysis-order.cpp +// clang/unittests/StaticAnalyzer/CallEventTest.cpp +class CXXDeallocatorCall : public AnyFunctionCall { + friend class CallEventManager; + +protected: + CXXDeallocatorCall(const CXXDeleteExpr *E, ProgramStateRef St, + const LocationContext *LCtx) + : AnyFunctionCall(E, St, LCtx) {} + CXXDeallocatorCall(const CXXDeallocatorCall &Other) = default; + + void cloneTo(void *Dest) const override { + new (Dest) CXXDeallocatorCall(*this); + } + +public: + virtual const CXXDeleteExpr *getOriginExpr() const { + return cast<CXXDeleteExpr>(AnyFunctionCall::getOriginExpr()); + } + + const FunctionDecl *getDecl() const override { + return getOriginExpr()->getOperatorDelete(); + } + + unsigned getNumArgs() const override { return getDecl()->getNumParams(); } + + const Expr *getArgExpr(unsigned Index) const override { + // CXXDeleteExpr's only have a single argument. + return getOriginExpr()->getArgument(); + } + + Kind getKind() const override { return CE_CXXDeallocator; } + virtual StringRef getKindAsString() const override { + return "CXXDeallocatorCall"; + } + + static bool classof(const CallEvent *CE) { + return CE->getKind() == CE_CXXDeallocator; + } +}; + /// Represents the ways an Objective-C message send can occur. // // Note to maintainers: OCM_Message should always be last, since it does not @@ -992,9 +1186,6 @@ public: /// Returns the value of the receiver at the time of this call. SVal getReceiverSVal() const; - /// Return the value of 'self' if available. - SVal getSelfSVal() const; - /// Get the interface for the receiver. /// /// This works whether this is an instance message or a class message. @@ -1039,6 +1230,9 @@ public: ArrayRef<ParmVarDecl*> parameters() const override; Kind getKind() const override { return CE_ObjCMessage; } + virtual StringRef getKindAsString() const override { + return "ObjCMethodCall"; + } static bool classof(const CallEvent *CA) { return CA->getKind() == CE_ObjCMessage; @@ -1225,6 +1419,13 @@ public: return create<CXXConstructorCall>(E, Target, State, LCtx); } + CallEventRef<CXXInheritedConstructorCall> + getCXXInheritedConstructorCall(const CXXInheritedCtorInitExpr *E, + const MemRegion *Target, ProgramStateRef State, + const LocationContext *LCtx) { + return create<CXXInheritedConstructorCall>(E, Target, State, LCtx); + } + CallEventRef<CXXDestructorCall> getCXXDestructorCall(const CXXDestructorDecl *DD, const Stmt *Trigger, const MemRegion *Target, bool IsBase, @@ -1237,6 +1438,12 @@ public: const LocationContext *LCtx) { return create<CXXAllocatorCall>(E, State, LCtx); } + + CallEventRef<CXXDeallocatorCall> + getCXXDeallocatorCall(const CXXDeleteExpr *E, ProgramStateRef State, + const LocationContext *LCtx) { + return create<CXXDeallocatorCall>(E, State, LCtx); + } }; template <typename T> diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h index bd8760cf0ce0..8fd7f52585b8 100644 --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h @@ -107,6 +107,8 @@ public: return getBugReporter().getSourceManager(); } + Preprocessor &getPreprocessor() { return getBugReporter().getPreprocessor(); } + SValBuilder &getSValBuilder() { return Eng.getSValBuilder(); } @@ -173,8 +175,7 @@ public: /// @param Pred The transition will be generated from the specified Pred node /// to the newly generated node. /// @param Tag The tag to uniquely identify the creation site. - ExplodedNode *addTransition(ProgramStateRef State, - ExplodedNode *Pred, + ExplodedNode *addTransition(ProgramStateRef State, ExplodedNode *Pred, const ProgramPointTag *Tag = nullptr) { return addTransitionImpl(State, false, Pred, Tag); } @@ -187,6 +188,14 @@ public: return addTransitionImpl(State ? State : getState(), true, Pred, Tag); } + /// Add a sink node to the current path of execution, halting analysis. + void addSink(ProgramStateRef State = nullptr, + const ProgramPointTag *Tag = nullptr) { + if (!State) + State = getState(); + addTransition(State, generateSink(State, getPredecessor())); + } + /// 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. @@ -256,10 +265,12 @@ public: /// @param IsPrunable Whether the note is prunable. It allows BugReporter /// to omit the note from the report if it would make the displayed /// bug path significantly shorter. - const NoteTag *getNoteTag(std::function<std::string(BugReport &)> &&Cb, - bool IsPrunable = false) { + const NoteTag + *getNoteTag(std::function<std::string(PathSensitiveBugReport &)> &&Cb, + bool IsPrunable = false) { return getNoteTag( - [Cb](BugReporterContext &, BugReport &BR) { return Cb(BR); }, + [Cb](BugReporterContext &, + PathSensitiveBugReport &BR) { return Cb(BR); }, IsPrunable); } @@ -272,7 +283,8 @@ public: /// bug path significantly shorter. const NoteTag *getNoteTag(std::function<std::string()> &&Cb, bool IsPrunable = false) { - return getNoteTag([Cb](BugReporterContext &, BugReport &) { return Cb(); }, + return getNoteTag([Cb](BugReporterContext &, + PathSensitiveBugReport &) { return Cb(); }, IsPrunable); } @@ -284,7 +296,9 @@ public: /// bug path significantly shorter. const NoteTag *getNoteTag(StringRef Note, bool IsPrunable = false) { return getNoteTag( - [Note](BugReporterContext &, BugReport &) { return Note; }, IsPrunable); + [Note](BugReporterContext &, + PathSensitiveBugReport &) { return std::string(Note); }, + IsPrunable); } /// Returns the word that should be used to refer to the declaration diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerHelpers.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerHelpers.h index b53c042a1ca1..f253c14cc487 100644 --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerHelpers.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerHelpers.h @@ -14,6 +14,7 @@ #define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_CHECKERHELPERS_H #include "clang/AST/Stmt.h" +#include "llvm/ADT/Optional.h" #include <tuple> namespace clang { @@ -22,6 +23,7 @@ class Expr; class VarDecl; class QualType; class AttributedType; +class Preprocessor; namespace ento { @@ -62,8 +64,13 @@ enum class Nullability : char { /// Get nullability annotation for a given type. Nullability getNullabilityAnnotation(QualType Type); -} // end GR namespace +/// Try to parse the value of a defined preprocessor macro. We can only parse +/// simple expressions that consist of an optional minus sign token and then a +/// token for an integer. If we cannot parse the value then None is returned. +llvm::Optional<int> tryExpandAsInteger(StringRef Macro, const Preprocessor &PP); -} // end clang namespace +} // namespace ento + +} // namespace clang #endif diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h index f85c37379158..335536b6a310 100644 --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h @@ -32,7 +32,7 @@ namespace clang { namespace ento { class ProgramStateManager; -class SubEngine; +class ExprEngine; class SymbolReaper; class ConditionTruthVal { @@ -96,11 +96,7 @@ public: // If StTrue is infeasible, asserting the falseness of Cond is unnecessary // because the existing constraints already establish this. if (!StTrue) { -#ifndef __OPTIMIZE__ - // This check is expensive and should be disabled even in Release+Asserts - // builds. - // FIXME: __OPTIMIZE__ is a GNU extension that Clang implements but MSVC - // does not. Is there a good equivalent there? +#ifdef EXPENSIVE_CHECKS assert(assume(State, Cond, false) && "System is over constrained."); #endif return ProgramStatePair((ProgramStateRef)nullptr, State); @@ -197,10 +193,11 @@ protected: std::unique_ptr<ConstraintManager> CreateRangeConstraintManager(ProgramStateManager &statemgr, - SubEngine *subengine); + ExprEngine *exprengine); std::unique_ptr<ConstraintManager> -CreateZ3ConstraintManager(ProgramStateManager &statemgr, SubEngine *subengine); +CreateZ3ConstraintManager(ProgramStateManager &statemgr, + ExprEngine *exprengine); } // namespace ento } // namespace clang diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h index 278193ef99ed..2aca2c99ef4f 100644 --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h @@ -41,7 +41,7 @@ class LabelDecl; namespace ento { class FunctionSummariesTy; -class SubEngine; +class ExprEngine; //===----------------------------------------------------------------------===// /// CoreEngine - Implements the core logic of the graph-reachability @@ -69,7 +69,7 @@ public: std::vector<std::pair<const CFGBlock *, const ExplodedNode *>>; private: - SubEngine &SubEng; + ExprEngine &ExprEng; /// G - The simulation graph. Each node is a (location,state) pair. mutable ExplodedGraph G; @@ -129,7 +129,7 @@ private: public: /// Construct a CoreEngine object to analyze the provided CFG. - CoreEngine(SubEngine &subengine, + CoreEngine(ExprEngine &exprengine, FunctionSummariesTy *FS, AnalyzerOptions &Opts); diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicSize.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicSize.h new file mode 100644 index 000000000000..398f9b6ac33a --- /dev/null +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicSize.h @@ -0,0 +1,53 @@ +//===- DynamicSize.h - Dynamic size related APIs ----------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file defines APIs that track and query dynamic size information. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_DYNAMICSIZE_H +#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_DYNAMICSIZE_H + +#include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h" + +namespace clang { +namespace ento { + +/// Get the stored dynamic size for the region \p MR. +DefinedOrUnknownSVal getDynamicSize(ProgramStateRef State, const MemRegion *MR, + SValBuilder &SVB); + +/// Get the stored element count of the region \p MR. +DefinedOrUnknownSVal getDynamicElementCount(ProgramStateRef State, + const MemRegion *MR, + SValBuilder &SVB, + QualType ElementTy); + +/// Get the dynamic size for a symbolic value that represents a buffer. If +/// there is an offsetting to the underlying buffer we consider that too. +/// Returns with an SVal that represents the size, this is Unknown if the +/// engine cannot deduce the size. +/// E.g. +/// char buf[3]; +/// (buf); // size is 3 +/// (buf + 1); // size is 2 +/// (buf + 3); // size is 0 +/// (buf + 4); // size is -1 +/// +/// char *bufptr; +/// (bufptr) // size is unknown +SVal getDynamicSizeWithOffset(ProgramStateRef State, const SVal &BufV); + +} // namespace ento +} // namespace clang + +#endif // LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_DYNAMICSIZE_H diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicType.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicType.h index 356401d77561..2679339537e8 100644 --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicType.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicType.h @@ -36,6 +36,10 @@ DynamicTypeInfo getDynamicTypeInfo(ProgramStateRef State, const MemRegion *MR); const DynamicTypeInfo *getRawDynamicTypeInfo(ProgramStateRef State, const MemRegion *MR); +/// Get dynamic type information stored in a class object represented by \p Sym. +DynamicTypeInfo getClassObjectDynamicTypeInfo(ProgramStateRef State, + SymbolRef Sym); + /// Get dynamic cast information from \p CastFromTy to \p CastToTy of \p MR. const DynamicCastInfo *getDynamicCastInfo(ProgramStateRef State, const MemRegion *MR, @@ -50,6 +54,16 @@ ProgramStateRef setDynamicTypeInfo(ProgramStateRef State, const MemRegion *MR, ProgramStateRef setDynamicTypeInfo(ProgramStateRef State, const MemRegion *MR, QualType NewTy, bool CanBeSubClassed = true); +/// Set constraint on a type contained in a class object; return the new state. +ProgramStateRef setClassObjectDynamicTypeInfo(ProgramStateRef State, + SymbolRef Sym, + DynamicTypeInfo NewTy); + +/// Set constraint on a type contained in a class object; return the new state. +ProgramStateRef setClassObjectDynamicTypeInfo(ProgramStateRef State, + SymbolRef Sym, QualType NewTy, + bool CanBeSubClassed = true); + /// Set dynamic type and cast information of the region; return the new state. ProgramStateRef setDynamicTypeAndCastInfo(ProgramStateRef State, const MemRegion *MR, @@ -63,6 +77,10 @@ ProgramStateRef removeDeadTypes(ProgramStateRef State, SymbolReaper &SR); /// Removes the dead cast informations from \p State. ProgramStateRef removeDeadCasts(ProgramStateRef State, SymbolReaper &SR); +/// Removes the dead Class object type informations from \p State. +ProgramStateRef removeDeadClassObjectTypes(ProgramStateRef State, + SymbolReaper &SR); + void printDynamicTypeInfoJson(raw_ostream &Out, ProgramStateRef State, const char *NL = "\n", unsigned int Space = 0, bool IsDot = false); diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeInfo.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeInfo.h index 6262c4a1ce37..6d2b495dc0f5 100644 --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeInfo.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeInfo.h @@ -33,6 +33,8 @@ public: /// Returns the currently inferred upper bound on the runtime type. QualType getType() const { return DynTy; } + operator bool() const { return isValid(); } + bool operator==(const DynamicTypeInfo &RHS) const { return DynTy == RHS.DynTy && CanBeASubClass == RHS.CanBeASubClass; } diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h index 6e676c512b89..cdfe986355c5 100644 --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h @@ -21,6 +21,7 @@ #include "clang/Analysis/DomainSpecific/ObjCNoReturn.h" #include "clang/Analysis/ProgramPoint.h" #include "clang/Basic/LLVM.h" +#include "clang/StaticAnalyzer/Core/CheckerManager.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h" #include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h" @@ -29,9 +30,9 @@ #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h" #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h" #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/Store.h" #include "clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h" #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h" -#include "clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h" #include "clang/StaticAnalyzer/Core/PathSensitive/WorkList.h" #include "llvm/ADT/ArrayRef.h" #include <cassert> @@ -42,6 +43,8 @@ namespace clang { class AnalysisDeclContextManager; class AnalyzerOptions; class ASTContext; +class CFGBlock; +class CFGElement; class ConstructionContext; class CXXBindTemporaryExpr; class CXXCatchStmt; @@ -72,16 +75,58 @@ class CrossTranslationUnitContext; namespace ento { +class AnalysisManager; class BasicValueFactory; +class BlockCounter; +class BranchNodeBuilder; class CallEvent; class CheckerManager; class ConstraintManager; class CXXTempObjectRegion; +class EndOfFunctionNodeBuilder; +class ExplodedNodeSet; +class ExplodedNode; +class IndirectGotoNodeBuilder; class MemRegion; +struct NodeBuilderContext; +class NodeBuilderWithSinks; +class ProgramState; +class ProgramStateManager; class RegionAndSymbolInvalidationTraits; class SymbolManager; +class SwitchNodeBuilder; + +/// Hints for figuring out of a call should be inlined during evalCall(). +struct EvalCallOptions { + /// This call is a constructor or a destructor for which we do not currently + /// compute the this-region correctly. + bool IsCtorOrDtorWithImproperlyModeledTargetRegion = false; + + /// This call is a constructor or a destructor for a single element within + /// an array, a part of array construction or destruction. + bool IsArrayCtorOrDtor = false; + + /// This call is a constructor or a destructor of a temporary value. + bool IsTemporaryCtorOrDtor = false; + + /// This call is a constructor for a temporary that is lifetime-extended + /// by binding it to a reference-type field within an aggregate, + /// for example 'A { const C &c; }; A a = { C() };' + bool IsTemporaryLifetimeExtendedViaAggregate = false; + + /// This call is a pre-C++17 elidable constructor that we failed to elide + /// because we failed to compute the target region into which + /// this constructor would have been ultimately elided. Analysis that + /// we perform in this case is still correct but it behaves differently, + /// as if copy elision is disabled. + bool IsElidableCtorThatHasNotBeenElided = false; + + EvalCallOptions() {} +}; + +class ExprEngine { + void anchor(); -class ExprEngine : public SubEngine { public: /// The modes of inlining, which override the default analysis-wide settings. enum InliningModes { @@ -92,27 +137,6 @@ public: Inline_Minimal = 0x1 }; - /// Hints for figuring out of a call should be inlined during evalCall(). - struct EvalCallOptions { - /// This call is a constructor or a destructor for which we do not currently - /// compute the this-region correctly. - bool IsCtorOrDtorWithImproperlyModeledTargetRegion = false; - - /// This call is a constructor or a destructor for a single element within - /// an array, a part of array construction or destruction. - bool IsArrayCtorOrDtor = false; - - /// This call is a constructor or a destructor of a temporary value. - bool IsTemporaryCtorOrDtor = false; - - /// This call is a constructor for a temporary that is lifetime-extended - /// by binding it to a reference-type field within an aggregate, - /// for example 'A { const C &c; }; A a = { C() };' - bool IsTemporaryLifetimeExtendedViaAggregate = false; - - EvalCallOptions() {} - }; - private: cross_tu::CrossTranslationUnitContext &CTU; @@ -161,7 +185,7 @@ public: SetOfConstDecls *VisitedCalleesIn, FunctionSummariesTy *FS, InliningModes HowToInlineIn); - ~ExprEngine() override = default; + virtual ~ExprEngine() = default; /// Returns true if there is still simulation state on the worklist. bool ExecuteWorkList(const LocationContext *L, unsigned Steps = 150000) { @@ -181,7 +205,7 @@ public: /// getContext - Return the ASTContext associated with this analysis. ASTContext &getContext() const { return AMgr.getASTContext(); } - AnalysisManager &getAnalysisManager() override { return AMgr; } + AnalysisManager &getAnalysisManager() { return AMgr; } AnalysisDeclContextManager &getAnalysisDeclContextManager() { return AMgr.getAnalysisDeclContextManager(); @@ -196,7 +220,7 @@ public: BugReporter &getBugReporter() { return BR; } cross_tu::CrossTranslationUnitContext * - getCrossTranslationUnitContext() override { + getCrossTranslationUnitContext() { return &CTU; } @@ -232,7 +256,7 @@ public: /// getInitialState - Return the initial state used for the root vertex /// in the ExplodedGraph. - ProgramStateRef getInitialState(const LocationContext *InitLoc) override; + ProgramStateRef getInitialState(const LocationContext *InitLoc); ExplodedGraph &getGraph() { return G; } const ExplodedGraph &getGraph() const { return G; } @@ -270,7 +294,7 @@ public: /// processCFGElement - Called by CoreEngine. Used to generate new successor /// nodes by processing the 'effects' of a CFG element. void processCFGElement(const CFGElement E, ExplodedNode *Pred, - unsigned StmtIdx, NodeBuilderContext *Ctx) override; + unsigned StmtIdx, NodeBuilderContext *Ctx); void ProcessStmt(const Stmt *S, ExplodedNode *Pred); @@ -296,7 +320,7 @@ public: /// Called by CoreEngine when processing the entrance of a CFGBlock. void processCFGBlockEntrance(const BlockEdge &L, NodeBuilderWithSinks &nodeBuilder, - ExplodedNode *Pred) override; + ExplodedNode *Pred); /// ProcessBranch - Called by CoreEngine. Used to generate successor /// nodes by processing the 'effects' of a branch condition. @@ -305,7 +329,7 @@ public: ExplodedNode *Pred, ExplodedNodeSet &Dst, const CFGBlock *DstT, - const CFGBlock *DstF) override; + const CFGBlock *DstF); /// Called by CoreEngine. /// Used to generate successor nodes for temporary destructors depending @@ -314,7 +338,7 @@ public: NodeBuilderContext &BldCtx, ExplodedNode *Pred, ExplodedNodeSet &Dst, const CFGBlock *DstT, - const CFGBlock *DstF) override; + const CFGBlock *DstF); /// Called by CoreEngine. Used to processing branching behavior /// at static initializers. @@ -323,27 +347,27 @@ public: ExplodedNode *Pred, ExplodedNodeSet &Dst, const CFGBlock *DstT, - const CFGBlock *DstF) override; + const CFGBlock *DstF); /// processIndirectGoto - Called by CoreEngine. Used to generate successor /// nodes by processing the 'effects' of a computed goto jump. - void processIndirectGoto(IndirectGotoNodeBuilder& builder) override; + void processIndirectGoto(IndirectGotoNodeBuilder& builder); /// ProcessSwitch - Called by CoreEngine. Used to generate successor /// nodes by processing the 'effects' of a switch statement. - void processSwitch(SwitchNodeBuilder& builder) override; + void processSwitch(SwitchNodeBuilder& builder); /// Called by CoreEngine. Used to notify checkers that processing a /// function has begun. Called for both inlined and and top-level functions. void processBeginOfFunction(NodeBuilderContext &BC, ExplodedNode *Pred, ExplodedNodeSet &Dst, - const BlockEdge &L) override; + const BlockEdge &L); /// Called by CoreEngine. Used to notify checkers that processing a /// function has ended. Called for both inlined and and top-level functions. void processEndOfFunction(NodeBuilderContext& BC, ExplodedNode *Pred, - const ReturnStmt *RS = nullptr) override; + const ReturnStmt *RS = nullptr); /// Remove dead bindings/symbols before exiting a function. void removeDeadOnEndOfFunction(NodeBuilderContext& BC, @@ -352,19 +376,19 @@ public: /// Generate the entry node of the callee. void processCallEnter(NodeBuilderContext& BC, CallEnter CE, - ExplodedNode *Pred) override; + ExplodedNode *Pred); /// Generate the sequence of nodes that simulate the call exit and the post /// visit for CallExpr. - void processCallExit(ExplodedNode *Pred) override; + void processCallExit(ExplodedNode *Pred); /// Called by CoreEngine when the analysis worklist has terminated. - void processEndWorklist() override; + void processEndWorklist(); /// evalAssume - Callback function invoked by the ConstraintManager when /// making assumptions about state values. ProgramStateRef processAssume(ProgramStateRef state, SVal cond, - bool assumption) override; + bool assumption); /// processRegionChanges - Called by ProgramStateManager whenever a change is made /// to the store. Used to update checkers that track region values. @@ -374,14 +398,21 @@ public: ArrayRef<const MemRegion *> ExplicitRegions, ArrayRef<const MemRegion *> Regions, const LocationContext *LCtx, - const CallEvent *Call) override; + const CallEvent *Call); + + inline ProgramStateRef + processRegionChange(ProgramStateRef state, + const MemRegion* MR, + const LocationContext *LCtx) { + return processRegionChanges(state, nullptr, MR, MR, LCtx, nullptr); + } /// printJson - Called by ProgramStateManager to print checker-specific data. void printJson(raw_ostream &Out, ProgramStateRef State, const LocationContext *LCtx, const char *NL, - unsigned int Space, bool IsDot) const override; + unsigned int Space, bool IsDot) const; - ProgramStateManager &getStateManager() override { return StateMgr; } + ProgramStateManager &getStateManager() { return StateMgr; } StoreManager &getStoreManager() { return StateMgr.getStoreManager(); } @@ -527,6 +558,9 @@ public: void VisitCXXConstructExpr(const CXXConstructExpr *E, ExplodedNode *Pred, ExplodedNodeSet &Dst); + void VisitCXXInheritedCtorInitExpr(const CXXInheritedCtorInitExpr *E, + ExplodedNode *Pred, ExplodedNodeSet &Dst); + void VisitCXXDestructor(QualType ObjectType, const MemRegion *Dest, const Stmt *S, bool IsBaseDtor, ExplodedNode *Pred, ExplodedNodeSet &Dst, @@ -605,23 +639,11 @@ public: const ConstructionContextItem &Item, const LocationContext *LC); -protected: - /// evalBind - Handle the semantics of binding a value to a specific location. - /// This method is used by evalStore, VisitDeclStmt, and others. - void evalBind(ExplodedNodeSet &Dst, const Stmt *StoreE, ExplodedNode *Pred, - SVal location, SVal Val, bool atDeclInit = false, - const ProgramPoint *PP = nullptr); - /// Call PointerEscape callback when a value escapes as a result of bind. ProgramStateRef processPointerEscapedOnBind( ProgramStateRef State, ArrayRef<std::pair<SVal, SVal>> LocAndVals, const LocationContext *LCtx, PointerEscapeKind Kind, - const CallEvent *Call) override; - - ProgramStateRef - processPointerEscapedOnBind(ProgramStateRef State, - SVal Loc, SVal Val, - const LocationContext *LCtx); + const CallEvent *Call); /// Call PointerEscape callback when a value escapes as a result of /// region invalidation. @@ -631,7 +653,19 @@ protected: const InvalidatedSymbols *Invalidated, ArrayRef<const MemRegion *> ExplicitRegions, const CallEvent *Call, - RegionAndSymbolInvalidationTraits &ITraits) override; + RegionAndSymbolInvalidationTraits &ITraits); + +private: + /// evalBind - Handle the semantics of binding a value to a specific location. + /// This method is used by evalStore, VisitDeclStmt, and others. + void evalBind(ExplodedNodeSet &Dst, const Stmt *StoreE, ExplodedNode *Pred, + SVal location, SVal Val, bool atDeclInit = false, + const ProgramPoint *PP = nullptr); + + ProgramStateRef + processPointerEscapedOnBind(ProgramStateRef State, + SVal Loc, SVal Val, + const LocationContext *LCtx); /// A simple wrapper when you only need to notify checkers of pointer-escape /// of some values. @@ -683,6 +717,35 @@ public: const CallEvent &Call, const EvalCallOptions &CallOpts = {}); + /// Find location of the object that is being constructed by a given + /// constructor. This should ideally always succeed but due to not being + /// fully implemented it sometimes indicates that it failed via its + /// out-parameter CallOpts; in such cases a fake temporary region is + /// returned, which is better than nothing but does not represent + /// the actual behavior of the program. + SVal computeObjectUnderConstruction( + const Expr *E, ProgramStateRef State, const LocationContext *LCtx, + const ConstructionContext *CC, EvalCallOptions &CallOpts); + + /// Update the program state with all the path-sensitive information + /// that's necessary to perform construction of an object with a given + /// syntactic construction context. V and CallOpts have to be obtained from + /// computeObjectUnderConstruction() invoked with the same set of + /// the remaining arguments (E, State, LCtx, CC). + ProgramStateRef updateObjectsUnderConstruction( + SVal V, const Expr *E, ProgramStateRef State, const LocationContext *LCtx, + const ConstructionContext *CC, const EvalCallOptions &CallOpts); + + /// A convenient wrapper around computeObjectUnderConstruction + /// and updateObjectsUnderConstruction. + std::pair<ProgramStateRef, SVal> handleConstructionContext( + const Expr *E, ProgramStateRef State, const LocationContext *LCtx, + const ConstructionContext *CC, EvalCallOptions &CallOpts) { + SVal V = computeObjectUnderConstruction(E, State, LCtx, CC, CallOpts); + return std::make_pair( + updateObjectsUnderConstruction(V, E, State, LCtx, CC, CallOpts), V); + } + private: ProgramStateRef finishArgumentConstruction(ProgramStateRef State, const CallEvent &Call); @@ -801,15 +864,10 @@ private: /// constructing into an existing region. const CXXConstructExpr *findDirectConstructorForCurrentCFGElement(); - /// Update the program state with all the path-sensitive information - /// that's necessary to perform construction of an object with a given - /// syntactic construction context. If the construction context is unavailable - /// or unusable for any reason, a dummy temporary region is returned, and the - /// IsConstructorWithImproperlyModeledTargetRegion flag is set in \p CallOpts. - /// Returns the updated program state and the new object's this-region. - std::pair<ProgramStateRef, SVal> prepareForObjectConstruction( - const Expr *E, ProgramStateRef State, const LocationContext *LCtx, - const ConstructionContext *CC, EvalCallOptions &CallOpts); + /// Common code that handles either a CXXConstructExpr or a + /// CXXInheritedCtorInitExpr. + void handleConstructor(const Expr *E, ExplodedNode *Pred, + ExplodedNodeSet &Dst); /// Store the location of a C++ object corresponding to a statement /// until the statement is actually encountered. For example, if a DeclStmt diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h index 71cbbe28fc25..9f85347db5df 100644 --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h @@ -112,7 +112,7 @@ public: virtual void Profile(llvm::FoldingSetNodeID& ID) const = 0; - virtual MemRegionManager* getMemRegionManager() const = 0; + virtual MemRegionManager &getMemRegionManager() const = 0; const MemSpaceRegion *getMemorySpace() const; @@ -198,14 +198,13 @@ public: /// for example, the set of global variables, the stack frame, etc. class MemSpaceRegion : public MemRegion { protected: - MemRegionManager *Mgr; + MemRegionManager &Mgr; - MemSpaceRegion(MemRegionManager *mgr, Kind k) : MemRegion(k), Mgr(mgr) { + MemSpaceRegion(MemRegionManager &mgr, Kind k) : MemRegion(k), Mgr(mgr) { assert(classof(this)); - assert(mgr); } - MemRegionManager* getMemRegionManager() const override { return Mgr; } + MemRegionManager &getMemRegionManager() const override { return Mgr; } public: bool isBoundable() const override { return false; } @@ -223,7 +222,7 @@ public: class CodeSpaceRegion : public MemSpaceRegion { friend class MemRegionManager; - CodeSpaceRegion(MemRegionManager *mgr) + CodeSpaceRegion(MemRegionManager &mgr) : MemSpaceRegion(mgr, CodeSpaceRegionKind) {} public: @@ -238,7 +237,7 @@ class GlobalsSpaceRegion : public MemSpaceRegion { virtual void anchor(); protected: - GlobalsSpaceRegion(MemRegionManager *mgr, Kind k) : MemSpaceRegion(mgr, k) { + GlobalsSpaceRegion(MemRegionManager &mgr, Kind k) : MemSpaceRegion(mgr, k) { assert(classof(this)); } @@ -259,7 +258,7 @@ class StaticGlobalSpaceRegion : public GlobalsSpaceRegion { const CodeTextRegion *CR; - StaticGlobalSpaceRegion(MemRegionManager *mgr, const CodeTextRegion *cr) + StaticGlobalSpaceRegion(MemRegionManager &mgr, const CodeTextRegion *cr) : GlobalsSpaceRegion(mgr, StaticGlobalSpaceRegionKind), CR(cr) { assert(cr); } @@ -286,7 +285,7 @@ class NonStaticGlobalSpaceRegion : public GlobalsSpaceRegion { void anchor() override; protected: - NonStaticGlobalSpaceRegion(MemRegionManager *mgr, Kind k) + NonStaticGlobalSpaceRegion(MemRegionManager &mgr, Kind k) : GlobalsSpaceRegion(mgr, k) { assert(classof(this)); } @@ -304,7 +303,7 @@ public: class GlobalSystemSpaceRegion : public NonStaticGlobalSpaceRegion { friend class MemRegionManager; - GlobalSystemSpaceRegion(MemRegionManager *mgr) + GlobalSystemSpaceRegion(MemRegionManager &mgr) : NonStaticGlobalSpaceRegion(mgr, GlobalSystemSpaceRegionKind) {} public: @@ -323,7 +322,7 @@ public: class GlobalImmutableSpaceRegion : public NonStaticGlobalSpaceRegion { friend class MemRegionManager; - GlobalImmutableSpaceRegion(MemRegionManager *mgr) + GlobalImmutableSpaceRegion(MemRegionManager &mgr) : NonStaticGlobalSpaceRegion(mgr, GlobalImmutableSpaceRegionKind) {} public: @@ -340,7 +339,7 @@ public: class GlobalInternalSpaceRegion : public NonStaticGlobalSpaceRegion { friend class MemRegionManager; - GlobalInternalSpaceRegion(MemRegionManager *mgr) + GlobalInternalSpaceRegion(MemRegionManager &mgr) : NonStaticGlobalSpaceRegion(mgr, GlobalInternalSpaceRegionKind) {} public: @@ -354,7 +353,7 @@ public: class HeapSpaceRegion : public MemSpaceRegion { friend class MemRegionManager; - HeapSpaceRegion(MemRegionManager *mgr) + HeapSpaceRegion(MemRegionManager &mgr) : MemSpaceRegion(mgr, HeapSpaceRegionKind) {} public: @@ -368,7 +367,7 @@ public: class UnknownSpaceRegion : public MemSpaceRegion { friend class MemRegionManager; - UnknownSpaceRegion(MemRegionManager *mgr) + UnknownSpaceRegion(MemRegionManager &mgr) : MemSpaceRegion(mgr, UnknownSpaceRegionKind) {} public: @@ -385,7 +384,7 @@ class StackSpaceRegion : public MemSpaceRegion { const StackFrameContext *SFC; protected: - StackSpaceRegion(MemRegionManager *mgr, Kind k, const StackFrameContext *sfc) + StackSpaceRegion(MemRegionManager &mgr, Kind k, const StackFrameContext *sfc) : MemSpaceRegion(mgr, k), SFC(sfc) { assert(classof(this)); assert(sfc); @@ -405,7 +404,7 @@ public: class StackLocalsSpaceRegion : public StackSpaceRegion { friend class MemRegionManager; - StackLocalsSpaceRegion(MemRegionManager *mgr, const StackFrameContext *sfc) + StackLocalsSpaceRegion(MemRegionManager &mgr, const StackFrameContext *sfc) : StackSpaceRegion(mgr, StackLocalsSpaceRegionKind, sfc) {} public: @@ -420,7 +419,7 @@ class StackArgumentsSpaceRegion : public StackSpaceRegion { private: friend class MemRegionManager; - StackArgumentsSpaceRegion(MemRegionManager *mgr, const StackFrameContext *sfc) + StackArgumentsSpaceRegion(MemRegionManager &mgr, const StackFrameContext *sfc) : StackSpaceRegion(mgr, StackArgumentsSpaceRegionKind, sfc) {} public: @@ -449,12 +448,7 @@ public: return superRegion; } - /// getExtent - Returns the size of the region in bytes. - virtual DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const { - return UnknownVal(); - } - - MemRegionManager* getMemRegionManager() const override; + MemRegionManager &getMemRegionManager() const override; bool isSubRegionOf(const MemRegion* R) const override; @@ -491,8 +485,6 @@ public: bool isBoundable() const override { return true; } - DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const override; - void Profile(llvm::FoldingSetNodeID& ID) const override; void dumpToStream(raw_ostream &os) const override; @@ -552,8 +544,6 @@ public: return T.getTypePtrOrNull() ? T.getDesugaredType(Context) : T; } - DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const override; - static bool classof(const MemRegion* R) { unsigned k = R->getKind(); return k >= BEGIN_TYPED_VALUE_REGIONS && k <= END_TYPED_VALUE_REGIONS; @@ -782,8 +772,6 @@ public: bool isBoundable() const override { return true; } - DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const override; - void Profile(llvm::FoldingSetNodeID& ID) const override; static void ProfileRegion(llvm::FoldingSetNodeID& ID, @@ -817,8 +805,6 @@ public: QualType getValueType() const override { return Str->getType(); } - DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const override; - bool isBoundable() const override { return false; } void Profile(llvm::FoldingSetNodeID& ID) const override { @@ -904,20 +890,12 @@ public: class DeclRegion : public TypedValueRegion { protected: - const ValueDecl *D; - - DeclRegion(const ValueDecl *d, const MemRegion *sReg, Kind k) - : TypedValueRegion(sReg, k), D(d) { + DeclRegion(const MemRegion *sReg, Kind k) : TypedValueRegion(sReg, k) { assert(classof(this)); - assert(d && d->isCanonicalDecl()); } - static void ProfileRegion(llvm::FoldingSetNodeID& ID, const Decl *D, - const MemRegion* superRegion, Kind k); - public: - const ValueDecl *getDecl() const { return D; } - void Profile(llvm::FoldingSetNodeID& ID) const override; + virtual const ValueDecl *getDecl() const = 0; static bool classof(const MemRegion* R) { unsigned k = R->getKind(); @@ -928,9 +906,9 @@ public: class VarRegion : public DeclRegion { friend class MemRegionManager; - // Constructors and private methods. - VarRegion(const VarDecl *vd, const MemRegion *sReg) - : DeclRegion(vd, sReg, VarRegionKind) { +protected: + // Constructors and protected methods. + VarRegion(const MemRegion *sReg, Kind k) : DeclRegion(sReg, k) { // VarRegion appears in unknown space when it's a block variable as seen // from a block using it, when this block is analyzed at top-level. // Other block variables appear within block data regions, @@ -939,17 +917,45 @@ class VarRegion : public DeclRegion { isa<BlockDataRegion>(sReg) || isa<UnknownSpaceRegion>(sReg)); } - static void ProfileRegion(llvm::FoldingSetNodeID& ID, const VarDecl *VD, - const MemRegion *superRegion) { - DeclRegion::ProfileRegion(ID, VD, superRegion, VarRegionKind); +public: + const VarDecl *getDecl() const override = 0; + + const StackFrameContext *getStackFrame() const; + + QualType getValueType() const override { + // FIXME: We can cache this if needed. + return getDecl()->getType(); } -public: - void Profile(llvm::FoldingSetNodeID& ID) const override; + static bool classof(const MemRegion *R) { + unsigned k = R->getKind(); + return k >= BEGIN_VAR_REGIONS && k <= END_VAR_REGIONS; + } +}; - const VarDecl *getDecl() const { return cast<VarDecl>(D); } +class NonParamVarRegion : public VarRegion { + friend class MemRegionManager; - const StackFrameContext *getStackFrame() const; + const VarDecl *VD; + + // Constructors and private methods. + NonParamVarRegion(const VarDecl *vd, const MemRegion *sReg) + : VarRegion(sReg, NonParamVarRegionKind), VD(vd) { + // VarRegion appears in unknown space when it's a block variable as seen + // from a block using it, when this block is analyzed at top-level. + // Other block variables appear within block data regions, + // which, unlike everything else on this list, are not memory spaces. + assert(isa<GlobalsSpaceRegion>(sReg) || isa<StackSpaceRegion>(sReg) || + isa<BlockDataRegion>(sReg) || isa<UnknownSpaceRegion>(sReg)); + } + + static void ProfileRegion(llvm::FoldingSetNodeID &ID, const VarDecl *VD, + const MemRegion *superRegion); + +public: + void Profile(llvm::FoldingSetNodeID &ID) const override; + + const VarDecl *getDecl() const override { return VD; } QualType getValueType() const override { // FIXME: We can cache this if needed. @@ -963,7 +969,50 @@ public: void printPrettyAsExpr(raw_ostream &os) const override; static bool classof(const MemRegion* R) { - return R->getKind() == VarRegionKind; + return R->getKind() == NonParamVarRegionKind; + } +}; + +/// ParamVarRegion - Represents a region for paremters. Only parameters of the +/// function in the current stack frame are represented as `ParamVarRegion`s. +/// Parameters of top-level analyzed functions as well as captured paremeters +/// by lambdas and blocks are repesented as `VarRegion`s. + +// FIXME: `ParamVarRegion` only supports parameters of functions, C++ +// constructors, blocks and Objective-C methods with existing `Decl`. Upon +// implementing stack frame creations for functions without decl (functions +// passed by unknown function pointer) methods of `ParamVarRegion` must be +// updated. +class ParamVarRegion : public VarRegion { + friend class MemRegionManager; + + const Expr *OriginExpr; + unsigned Index; + + ParamVarRegion(const Expr *OE, unsigned Idx, const MemRegion *SReg) + : VarRegion(SReg, ParamVarRegionKind), OriginExpr(OE), Index(Idx) { + assert(!cast<StackSpaceRegion>(SReg)->getStackFrame()->inTopFrame()); + } + + static void ProfileRegion(llvm::FoldingSetNodeID &ID, const Expr *OE, + unsigned Idx, const MemRegion *SReg); + +public: + const Expr *getOriginExpr() const { return OriginExpr; } + unsigned getIndex() const { return Index; } + + void Profile(llvm::FoldingSetNodeID& ID) const override; + + void dumpToStream(raw_ostream &os) const override; + + QualType getValueType() const override; + const ParmVarDecl *getDecl() const override; + + bool canPrintPrettyAsExpr() const override; + void printPrettyAsExpr(raw_ostream &os) const override; + + static bool classof(const MemRegion *R) { + return R->getKind() == ParamVarRegionKind; } }; @@ -1005,24 +1054,28 @@ private: class FieldRegion : public DeclRegion { friend class MemRegionManager; - FieldRegion(const FieldDecl *fd, const SubRegion* sReg) - : DeclRegion(fd, sReg, FieldRegionKind) {} + const FieldDecl *FD; + + FieldRegion(const FieldDecl *fd, const SubRegion *sReg) + : DeclRegion(sReg, FieldRegionKind), FD(fd) {} - static void ProfileRegion(llvm::FoldingSetNodeID& ID, const FieldDecl *FD, + static void ProfileRegion(llvm::FoldingSetNodeID &ID, const FieldDecl *FD, const MemRegion* superRegion) { - DeclRegion::ProfileRegion(ID, FD, superRegion, FieldRegionKind); + ID.AddInteger(static_cast<unsigned>(FieldRegionKind)); + ID.AddPointer(FD); + ID.AddPointer(superRegion); } public: - const FieldDecl *getDecl() const { return cast<FieldDecl>(D); } + const FieldDecl *getDecl() const override { return FD; } + + void Profile(llvm::FoldingSetNodeID &ID) const override; QualType getValueType() const override { // FIXME: We can cache this if needed. return getDecl()->getType(); } - DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const override; - void dumpToStream(raw_ostream &os) const override; bool canPrintPretty() const override; @@ -1038,13 +1091,18 @@ public: class ObjCIvarRegion : public DeclRegion { friend class MemRegionManager; + const ObjCIvarDecl *IVD; + ObjCIvarRegion(const ObjCIvarDecl *ivd, const SubRegion *sReg); static void ProfileRegion(llvm::FoldingSetNodeID& ID, const ObjCIvarDecl *ivd, const MemRegion* superRegion); public: - const ObjCIvarDecl *getDecl() const; + const ObjCIvarDecl *getDecl() const override; + + void Profile(llvm::FoldingSetNodeID& ID) const override; + QualType getValueType() const override; bool canPrintPrettyAsExpr() const override; @@ -1242,8 +1300,9 @@ const RegionTy* MemRegion::castAs() const { //===----------------------------------------------------------------------===// class MemRegionManager { - ASTContext &C; + ASTContext &Ctx; llvm::BumpPtrAllocator& A; + llvm::FoldingSet<MemRegion> Regions; GlobalInternalSpaceRegion *InternalGlobals = nullptr; @@ -1262,13 +1321,18 @@ class MemRegionManager { CodeSpaceRegion *code = nullptr; public: - MemRegionManager(ASTContext &c, llvm::BumpPtrAllocator &a) : C(c), A(a) {} + MemRegionManager(ASTContext &c, llvm::BumpPtrAllocator &a) : Ctx(c), A(a) {} ~MemRegionManager(); - ASTContext &getContext() { return C; } + ASTContext &getContext() { return Ctx; } llvm::BumpPtrAllocator &getAllocator() { return A; } + /// \returns The static size in bytes of the region \p MR. + /// \note The region \p MR must be a 'SubRegion'. + DefinedOrUnknownSVal getStaticSize(const MemRegion *MR, + SValBuilder &SVB) const; + /// getStackLocalsRegion - Retrieve the memory region associated with the /// specified stack frame. const StackLocalsSpaceRegion * @@ -1322,11 +1386,18 @@ public: /// getVarRegion - Retrieve or create the memory region associated with /// a specified VarDecl and LocationContext. - const VarRegion* getVarRegion(const VarDecl *D, const LocationContext *LC); + const VarRegion *getVarRegion(const VarDecl *VD, const LocationContext *LC); /// getVarRegion - Retrieve or create the memory region associated with - /// a specified VarDecl and super region. - const VarRegion *getVarRegion(const VarDecl *D, const MemRegion *superR); + /// a specified VarDecl and LocationContext. + const NonParamVarRegion *getNonParamVarRegion(const VarDecl *VD, + const MemRegion *superR); + + /// getParamVarRegion - Retrieve or create the memory region + /// associated with a specified CallExpr, Index and LocationContext. + const ParamVarRegion *getParamVarRegion(const Expr *OriginExpr, + unsigned Index, + const LocationContext *LC); /// getElementRegion - Retrieve the memory region associated with the /// associated element type, index, and super region. @@ -1434,7 +1505,7 @@ private: //===----------------------------------------------------------------------===// inline ASTContext &MemRegion::getContext() const { - return getMemRegionManager()->getContext(); + return getMemRegionManager().getContext(); } //===----------------------------------------------------------------------===// diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h index bdd12a3ffe33..9a34639e2707 100644 --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h @@ -39,7 +39,7 @@ class CallEvent; class CallEventManager; typedef std::unique_ptr<ConstraintManager>(*ConstraintManagerCreator)( - ProgramStateManager &, SubEngine *); + ProgramStateManager &, ExprEngine *); typedef std::unique_ptr<StoreManager>(*StoreManagerCreator)( ProgramStateManager &); @@ -298,6 +298,9 @@ public: LLVM_NODISCARD ProgramStateRef enterStackFrame( const CallEvent &Call, const StackFrameContext *CalleeCtx) const; + /// Return the value of 'self' if available in the given context. + SVal getSelfSVal(const LocationContext *LC) const; + /// Get the lvalue for a base class object reference. Loc getLValue(const CXXBaseSpecifier &BaseSpec, const SubRegion *Super) const; @@ -305,6 +308,10 @@ public: Loc getLValue(const CXXRecordDecl *BaseClass, const SubRegion *Super, bool IsVirtual) const; + /// Get the lvalue for a parameter. + Loc getLValue(const Expr *Call, unsigned Index, + const LocationContext *LC) const; + /// Get the lvalue for a variable reference. Loc getLValue(const VarDecl *D, const LocationContext *LC) const; @@ -457,8 +464,8 @@ class ProgramStateManager { friend class ProgramState; friend void ProgramStateRelease(const ProgramState *state); private: - /// Eng - The SubEngine that owns this state manager. - SubEngine *Eng; /* Can be null. */ + /// Eng - The ExprEngine that owns this state manager. + ExprEngine *Eng; /* Can be null. */ EnvironmentManager EnvMgr; std::unique_ptr<StoreManager> StoreMgr; @@ -490,7 +497,7 @@ public: StoreManagerCreator CreateStoreManager, ConstraintManagerCreator CreateConstraintManager, llvm::BumpPtrAllocator& alloc, - SubEngine *subeng); + ExprEngine *expreng); ~ProgramStateManager(); @@ -531,7 +538,7 @@ public: StoreManager &getStoreManager() { return *StoreMgr; } ConstraintManager &getConstraintManager() { return *ConstraintMgr; } - SubEngine &getOwningEngine() { return *Eng; } + ExprEngine &getOwningEngine() { return *Eng; } ProgramStateRef removeDeadBindingsFromEnvironmentAndStore(ProgramStateRef St, diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/RangedConstraintManager.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/RangedConstraintManager.h index a9ca3451d8f3..a42eebd7d4e8 100644 --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/RangedConstraintManager.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/RangedConstraintManager.h @@ -30,6 +30,10 @@ public: : std::pair<const llvm::APSInt *, const llvm::APSInt *>(&from, &to) { assert(from <= to); } + + Range(const llvm::APSInt &point) + : std::pair<const llvm::APSInt *, const llvm::APSInt *>(&point, &point) {} + bool Includes(const llvm::APSInt &v) const { return *first <= v && v <= *second; } @@ -89,6 +93,9 @@ public: RangeSet(Factory &F, const llvm::APSInt &from, const llvm::APSInt &to) : ranges(F.add(F.getEmptySet(), Range(from, to))) {} + /// Construct a new RangeSet representing the given point as a range. + RangeSet(Factory &F, const llvm::APSInt &point) : RangeSet(F, point, point) {} + /// Profile - Generates a hash profile of this RangeSet for use /// by FoldingSet. void Profile(llvm::FoldingSetNodeID &ID) const { ranges.Profile(ID); } @@ -100,14 +107,17 @@ public: return ranges.isSingleton() ? ranges.begin()->getConcreteValue() : nullptr; } + /// Get a minimal value covered by the ranges in the set + const llvm::APSInt &getMinValue() const; + /// Get a maximal value covered by the ranges in the set + const llvm::APSInt &getMaxValue() const; + private: void IntersectInRange(BasicValueFactory &BV, Factory &F, const llvm::APSInt &Lower, const llvm::APSInt &Upper, PrimRangeSet &newRanges, PrimRangeSet::iterator &i, PrimRangeSet::iterator &e) const; - const llvm::APSInt &getMinValue() const; - bool pin(llvm::APSInt &Lower, llvm::APSInt &Upper) const; public: @@ -124,7 +134,6 @@ public: } }; - class ConstraintRange {}; using ConstraintRangeTy = llvm::ImmutableMap<SymbolRef, RangeSet>; @@ -137,8 +146,8 @@ struct ProgramStateTrait<ConstraintRange> class RangedConstraintManager : public SimpleConstraintManager { public: - RangedConstraintManager(SubEngine *SE, SValBuilder &SB) - : SimpleConstraintManager(SE, SB) {} + RangedConstraintManager(ExprEngine *EE, SValBuilder &SB) + : SimpleConstraintManager(EE, SB) {} ~RangedConstraintManager() override; diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/Regions.def b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/Regions.def index 3c52c2bc7142..44ab31fc9f2e 100644 --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/Regions.def +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/Regions.def @@ -73,9 +73,13 @@ ABSTRACT_REGION(SubRegion, MemRegion) ABSTRACT_REGION(DeclRegion, TypedValueRegion) REGION(FieldRegion, DeclRegion) REGION(ObjCIvarRegion, DeclRegion) - REGION(VarRegion, DeclRegion) - REGION_RANGE(DECL_REGIONS, FieldRegionKind, - VarRegionKind) + ABSTRACT_REGION(VarRegion, DeclRegion) + REGION(NonParamVarRegion, VarRegion) + REGION(ParamVarRegion, VarRegion) + REGION_RANGE(VAR_REGIONS, NonParamVarRegionKind, + ParamVarRegionKind) + REGION_RANGE(DECL_REGIONS, FieldRegionKind, + ParamVarRegionKind) REGION(ElementRegion, TypedValueRegion) REGION(ObjCStringRegion, TypedValueRegion) REGION(StringRegion, TypedValueRegion) diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SMTConstraintManager.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SMTConstraintManager.h index 1712501b13bd..6a0f5f10874e 100644 --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SMTConstraintManager.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SMTConstraintManager.h @@ -15,6 +15,7 @@ #define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SMTCONSTRAINTMANAGER_H #include "clang/Basic/JsonSupport.h" +#include "clang/Basic/TargetInfo.h" #include "clang/StaticAnalyzer/Core/PathSensitive/RangedConstraintManager.h" #include "clang/StaticAnalyzer/Core/PathSensitive/SMTConv.h" @@ -30,8 +31,9 @@ class SMTConstraintManager : public clang::ento::SimpleConstraintManager { mutable llvm::SMTSolverRef Solver = llvm::CreateZ3Solver(); public: - SMTConstraintManager(clang::ento::SubEngine *SE, clang::ento::SValBuilder &SB) - : SimpleConstraintManager(SE, SB) {} + SMTConstraintManager(clang::ento::ExprEngine *EE, + clang::ento::SValBuilder &SB) + : SimpleConstraintManager(EE, SB) {} virtual ~SMTConstraintManager() = default; //===------------------------------------------------------------------===// diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SimpleConstraintManager.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SimpleConstraintManager.h index 6bf5e94afdbb..87e927f5b480 100644 --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SimpleConstraintManager.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SimpleConstraintManager.h @@ -21,12 +21,12 @@ namespace clang { namespace ento { class SimpleConstraintManager : public ConstraintManager { - SubEngine *SU; + ExprEngine *EE; SValBuilder &SVB; public: - SimpleConstraintManager(SubEngine *subengine, SValBuilder &SB) - : SU(subengine), SVB(SB) {} + SimpleConstraintManager(ExprEngine *exprengine, SValBuilder &SB) + : EE(exprengine), SVB(SB) {} ~SimpleConstraintManager() override; diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h index cbff29953944..c3b590e4784e 100644 --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h @@ -148,14 +148,6 @@ public: virtual SVal getLValueElement(QualType elementType, NonLoc offset, SVal Base); - // FIXME: This should soon be eliminated altogether; clients should deal with - // region extents directly. - virtual DefinedOrUnknownSVal getSizeInElements(ProgramStateRef state, - const MemRegion *region, - QualType EleTy) { - return UnknownVal(); - } - /// ArrayToPointer - Used by ExprEngine::VistCast to handle implicit /// conversions between arrays and pointers. virtual SVal ArrayToPointer(Loc Array, QualType ElementTy) = 0; diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h deleted file mode 100644 index a7f3c28d4373..000000000000 --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h +++ /dev/null @@ -1,178 +0,0 @@ -//== SubEngine.h - Interface of the subengine of CoreEngine --------*- C++ -*-// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// This file defines the interface of a subengine of the CoreEngine. -// -//===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SUBENGINE_H -#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SUBENGINE_H - -#include "clang/Analysis/ProgramPoint.h" -#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h" -#include "clang/StaticAnalyzer/Core/PathSensitive/Store.h" -#include "clang/StaticAnalyzer/Core/CheckerManager.h" - -namespace clang { - -class CFGBlock; -class CFGElement; -class LocationContext; -class Stmt; - -namespace cross_tu { -class CrossTranslationUnitContext; -} - -namespace ento { - -struct NodeBuilderContext; -class AnalysisManager; -class ExplodedNodeSet; -class ExplodedNode; -class ProgramState; -class ProgramStateManager; -class BlockCounter; -class BranchNodeBuilder; -class IndirectGotoNodeBuilder; -class SwitchNodeBuilder; -class EndOfFunctionNodeBuilder; -class NodeBuilderWithSinks; -class MemRegion; - -class SubEngine { - virtual void anchor(); -public: - virtual ~SubEngine() {} - - virtual ProgramStateRef getInitialState(const LocationContext *InitLoc) = 0; - - virtual AnalysisManager &getAnalysisManager() = 0; - - virtual cross_tu::CrossTranslationUnitContext * - getCrossTranslationUnitContext() = 0; - - virtual ProgramStateManager &getStateManager() = 0; - - /// Called by CoreEngine. Used to generate new successor - /// nodes by processing the 'effects' of a block-level statement. - virtual void processCFGElement(const CFGElement E, ExplodedNode* Pred, - unsigned StmtIdx, NodeBuilderContext *Ctx)=0; - - /// Called by CoreEngine when it starts processing a CFGBlock. The - /// SubEngine is expected to populate dstNodes with new nodes representing - /// updated analysis state, or generate no nodes at all if it doesn't. - virtual void processCFGBlockEntrance(const BlockEdge &L, - NodeBuilderWithSinks &nodeBuilder, - ExplodedNode *Pred) = 0; - - /// Called by CoreEngine. Used to generate successor - /// nodes by processing the 'effects' of a branch condition. - virtual void processBranch(const Stmt *Condition, - NodeBuilderContext& BuilderCtx, - ExplodedNode *Pred, - ExplodedNodeSet &Dst, - const CFGBlock *DstT, - const CFGBlock *DstF) = 0; - - /// Called by CoreEngine. - /// Used to generate successor nodes for temporary destructors depending - /// on whether the corresponding constructor was visited. - virtual void processCleanupTemporaryBranch(const CXXBindTemporaryExpr *BTE, - NodeBuilderContext &BldCtx, - ExplodedNode *Pred, - ExplodedNodeSet &Dst, - const CFGBlock *DstT, - const CFGBlock *DstF) = 0; - - /// Called by CoreEngine. Used to processing branching behavior - /// at static initializers. - virtual void processStaticInitializer(const DeclStmt *DS, - NodeBuilderContext& BuilderCtx, - ExplodedNode *Pred, - ExplodedNodeSet &Dst, - const CFGBlock *DstT, - const CFGBlock *DstF) = 0; - - /// Called by CoreEngine. Used to generate successor - /// nodes by processing the 'effects' of a computed goto jump. - virtual void processIndirectGoto(IndirectGotoNodeBuilder& builder) = 0; - - /// Called by CoreEngine. Used to generate successor - /// nodes by processing the 'effects' of a switch statement. - virtual void processSwitch(SwitchNodeBuilder& builder) = 0; - - /// Called by CoreEngine. Used to notify checkers that processing a - /// function has begun. Called for both inlined and and top-level functions. - virtual void processBeginOfFunction(NodeBuilderContext &BC, - ExplodedNode *Pred, - ExplodedNodeSet &Dst, - const BlockEdge &L) = 0; - - /// Called by CoreEngine. Used to notify checkers that processing a - /// function has ended. Called for both inlined and and top-level functions. - virtual void processEndOfFunction(NodeBuilderContext& BC, - ExplodedNode *Pred, - const ReturnStmt *RS = nullptr) = 0; - - // Generate the entry node of the callee. - virtual void processCallEnter(NodeBuilderContext& BC, CallEnter CE, - ExplodedNode *Pred) = 0; - - // Generate the first post callsite node. - virtual void processCallExit(ExplodedNode *Pred) = 0; - - /// Called by ConstraintManager. Used to call checker-specific - /// logic for handling assumptions on symbolic values. - virtual ProgramStateRef processAssume(ProgramStateRef state, - SVal cond, bool assumption) = 0; - - /// processRegionChanges - Called by ProgramStateManager whenever a change is - /// made to the store. Used to update checkers that track region values. - virtual ProgramStateRef - processRegionChanges(ProgramStateRef state, - const InvalidatedSymbols *invalidated, - ArrayRef<const MemRegion *> ExplicitRegions, - ArrayRef<const MemRegion *> Regions, - const LocationContext *LCtx, - const CallEvent *Call) = 0; - - - inline ProgramStateRef - processRegionChange(ProgramStateRef state, - const MemRegion* MR, - const LocationContext *LCtx) { - return processRegionChanges(state, nullptr, MR, MR, LCtx, nullptr); - } - - virtual ProgramStateRef processPointerEscapedOnBind( - ProgramStateRef State, ArrayRef<std::pair<SVal, SVal>> LocAndVals, - const LocationContext *LCtx, PointerEscapeKind Kind, - const CallEvent *Call) = 0; - - virtual ProgramStateRef - notifyCheckersOfPointerEscape(ProgramStateRef State, - const InvalidatedSymbols *Invalidated, - ArrayRef<const MemRegion *> ExplicitRegions, - const CallEvent *Call, - RegionAndSymbolInvalidationTraits &HTraits) = 0; - - /// printJson - Called by ProgramStateManager to print checker-specific data. - virtual void printJson(raw_ostream &Out, ProgramStateRef State, - const LocationContext *LCtx, const char *NL, - unsigned int Space, bool IsDot) const = 0; - - /// Called by CoreEngine when the analysis worklist is either empty or the - // maximum number of analysis steps have been reached. - virtual void processEndWorklist() = 0; -}; - -} // end GR namespace - -} // end clang namespace - -#endif diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h index d212e23da6fc..390ced8c29f8 100644 --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h @@ -326,140 +326,88 @@ public: Kind k = SE->getKind(); return k >= BEGIN_BINARYSYMEXPRS && k <= END_BINARYSYMEXPRS; } -}; - -/// Represents a symbolic expression like 'x' + 3. -class SymIntExpr : public BinarySymExpr { - const SymExpr *LHS; - const llvm::APSInt& RHS; -public: - SymIntExpr(const SymExpr *lhs, BinaryOperator::Opcode op, - const llvm::APSInt &rhs, QualType t) - : BinarySymExpr(SymIntExprKind, op, t), LHS(lhs), RHS(rhs) { - assert(lhs); +protected: + static unsigned computeOperandComplexity(const SymExpr *Value) { + return Value->computeComplexity(); } - - void dumpToStream(raw_ostream &os) const override; - - const SymExpr *getLHS() const { return LHS; } - const llvm::APSInt &getRHS() const { return RHS; } - - unsigned computeComplexity() const override { - if (Complexity == 0) - Complexity = 1 + LHS->computeComplexity(); - return Complexity; + static unsigned computeOperandComplexity(const llvm::APSInt &Value) { + return 1; } - static void Profile(llvm::FoldingSetNodeID& ID, const SymExpr *lhs, - BinaryOperator::Opcode op, const llvm::APSInt& rhs, - QualType t) { - ID.AddInteger((unsigned) SymIntExprKind); - ID.AddPointer(lhs); - ID.AddInteger(op); - ID.AddPointer(&rhs); - ID.Add(t); + static const llvm::APSInt *getPointer(const llvm::APSInt &Value) { + return &Value; } + static const SymExpr *getPointer(const SymExpr *Value) { return Value; } - void Profile(llvm::FoldingSetNodeID& ID) override { - Profile(ID, LHS, getOpcode(), RHS, getType()); - } - - // Implement isa<T> support. - static bool classof(const SymExpr *SE) { - return SE->getKind() == SymIntExprKind; - } + static void dumpToStreamImpl(raw_ostream &os, const SymExpr *Value); + static void dumpToStreamImpl(raw_ostream &os, const llvm::APSInt &Value); + static void dumpToStreamImpl(raw_ostream &os, BinaryOperator::Opcode op); }; -/// Represents a symbolic expression like 3 - 'x'. -class IntSymExpr : public BinarySymExpr { - const llvm::APSInt& LHS; - const SymExpr *RHS; +/// Template implementation for all binary symbolic expressions +template <class LHSTYPE, class RHSTYPE, SymExpr::Kind ClassKind> +class BinarySymExprImpl : public BinarySymExpr { + LHSTYPE LHS; + RHSTYPE RHS; public: - IntSymExpr(const llvm::APSInt &lhs, BinaryOperator::Opcode op, - const SymExpr *rhs, QualType t) - : BinarySymExpr(IntSymExprKind, op, t), LHS(lhs), RHS(rhs) { - assert(rhs); + BinarySymExprImpl(LHSTYPE lhs, BinaryOperator::Opcode op, RHSTYPE rhs, + QualType t) + : BinarySymExpr(ClassKind, op, t), LHS(lhs), RHS(rhs) { + assert(getPointer(lhs)); + assert(getPointer(rhs)); } - void dumpToStream(raw_ostream &os) const override; + void dumpToStream(raw_ostream &os) const override { + dumpToStreamImpl(os, LHS); + dumpToStreamImpl(os, getOpcode()); + dumpToStreamImpl(os, RHS); + } - const SymExpr *getRHS() const { return RHS; } - const llvm::APSInt &getLHS() const { return LHS; } + LHSTYPE getLHS() const { return LHS; } + RHSTYPE getRHS() const { return RHS; } unsigned computeComplexity() const override { if (Complexity == 0) - Complexity = 1 + RHS->computeComplexity(); + Complexity = + computeOperandComplexity(RHS) + computeOperandComplexity(LHS); return Complexity; } - static void Profile(llvm::FoldingSetNodeID& ID, const llvm::APSInt& lhs, - BinaryOperator::Opcode op, const SymExpr *rhs, - QualType t) { - ID.AddInteger((unsigned) IntSymExprKind); - ID.AddPointer(&lhs); + static void Profile(llvm::FoldingSetNodeID &ID, LHSTYPE lhs, + BinaryOperator::Opcode op, RHSTYPE rhs, QualType t) { + ID.AddInteger((unsigned)ClassKind); + ID.AddPointer(getPointer(lhs)); ID.AddInteger(op); - ID.AddPointer(rhs); + ID.AddPointer(getPointer(rhs)); ID.Add(t); } - void Profile(llvm::FoldingSetNodeID& ID) override { + void Profile(llvm::FoldingSetNodeID &ID) override { Profile(ID, LHS, getOpcode(), RHS, getType()); } // Implement isa<T> support. - static bool classof(const SymExpr *SE) { - return SE->getKind() == IntSymExprKind; - } + static bool classof(const SymExpr *SE) { return SE->getKind() == ClassKind; } }; -/// Represents a symbolic expression like 'x' + 'y'. -class SymSymExpr : public BinarySymExpr { - const SymExpr *LHS; - const SymExpr *RHS; - -public: - SymSymExpr(const SymExpr *lhs, BinaryOperator::Opcode op, const SymExpr *rhs, - QualType t) - : BinarySymExpr(SymSymExprKind, op, t), LHS(lhs), RHS(rhs) { - assert(lhs); - assert(rhs); - } - - const SymExpr *getLHS() const { return LHS; } - const SymExpr *getRHS() const { return RHS; } - - void dumpToStream(raw_ostream &os) const override; - - unsigned computeComplexity() const override { - if (Complexity == 0) - Complexity = RHS->computeComplexity() + LHS->computeComplexity(); - return Complexity; - } - - static void Profile(llvm::FoldingSetNodeID& ID, const SymExpr *lhs, - BinaryOperator::Opcode op, const SymExpr *rhs, QualType t) { - ID.AddInteger((unsigned) SymSymExprKind); - ID.AddPointer(lhs); - ID.AddInteger(op); - ID.AddPointer(rhs); - ID.Add(t); - } +/// Represents a symbolic expression like 'x' + 3. +using SymIntExpr = BinarySymExprImpl<const SymExpr *, const llvm::APSInt &, + SymExpr::Kind::SymIntExprKind>; - void Profile(llvm::FoldingSetNodeID& ID) override { - Profile(ID, LHS, getOpcode(), RHS, getType()); - } +/// Represents a symbolic expression like 3 - 'x'. +using IntSymExpr = BinarySymExprImpl<const llvm::APSInt &, const SymExpr *, + SymExpr::Kind::IntSymExprKind>; - // Implement isa<T> support. - static bool classof(const SymExpr *SE) { - return SE->getKind() == SymSymExprKind; - } -}; +/// Represents a symbolic expression like 'x' + 'y'. +using SymSymExpr = BinarySymExprImpl<const SymExpr *, const SymExpr *, + SymExpr::Kind::SymSymExprKind>; class SymbolManager { using DataSetTy = llvm::FoldingSet<SymExpr>; - using SymbolDependTy = llvm::DenseMap<SymbolRef, SymbolRefSmallVectorTy *>; + using SymbolDependTy = + llvm::DenseMap<SymbolRef, std::unique_ptr<SymbolRefSmallVectorTy>>; DataSetTy DataSet; @@ -476,7 +424,6 @@ public: SymbolManager(ASTContext &ctx, BasicValueFactory &bv, llvm::BumpPtrAllocator& bpalloc) : SymbolDependencies(16), BPAlloc(bpalloc), BV(bv), Ctx(ctx) {} - ~SymbolManager(); static bool canSymbolicate(QualType T); diff --git a/clang/include/clang/StaticAnalyzer/Frontend/AnalysisConsumer.h b/clang/include/clang/StaticAnalyzer/Frontend/AnalysisConsumer.h index 2d24e6a9586b..bcc29a60ad70 100644 --- a/clang/include/clang/StaticAnalyzer/Frontend/AnalysisConsumer.h +++ b/clang/include/clang/StaticAnalyzer/Frontend/AnalysisConsumer.h @@ -55,7 +55,7 @@ public: std::unique_ptr<AnalysisASTConsumer> CreateAnalysisConsumer(CompilerInstance &CI); -} // end GR namespace +} // namespace ento } // end clang namespace diff --git a/clang/include/clang/StaticAnalyzer/Frontend/AnalyzerHelpFlags.h b/clang/include/clang/StaticAnalyzer/Frontend/AnalyzerHelpFlags.h new file mode 100644 index 000000000000..a30c241e1350 --- /dev/null +++ b/clang/include/clang/StaticAnalyzer/Frontend/AnalyzerHelpFlags.h @@ -0,0 +1,30 @@ +//===-- AnalyzerHelpFlags.h - Query functions for --help flags --*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_STATICANALYZER_FRONTEND_ANALYZERHELPFLAGS_H +#define LLVM_CLANG_STATICANALYZER_FRONTEND_ANALYZERHELPFLAGS_H + +namespace llvm { +class raw_ostream; +} // namespace llvm + +namespace clang { + +class CompilerInstance; + +namespace ento { + +void printCheckerHelp(llvm::raw_ostream &OS, CompilerInstance &CI); +void printEnabledCheckerList(llvm::raw_ostream &OS, CompilerInstance &CI); +void printAnalyzerConfigList(llvm::raw_ostream &OS); +void printCheckerConfigList(llvm::raw_ostream &OS, CompilerInstance &CI); + +} // namespace ento +} // namespace clang + +#endif diff --git a/clang/include/clang/StaticAnalyzer/Frontend/CheckerRegistration.h b/clang/include/clang/StaticAnalyzer/Frontend/CheckerRegistration.h deleted file mode 100644 index 52a534499002..000000000000 --- a/clang/include/clang/StaticAnalyzer/Frontend/CheckerRegistration.h +++ /dev/null @@ -1,38 +0,0 @@ -//===-- CheckerRegistration.h - Checker Registration Function ---*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_STATICANALYZER_FRONTEND_CHECKERREGISTRATION_H -#define LLVM_CLANG_STATICANALYZER_FRONTEND_CHECKERREGISTRATION_H - -#include "clang/AST/ASTContext.h" -#include "clang/Basic/LLVM.h" -#include <functional> -#include <memory> -#include <string> - -namespace clang { - class AnalyzerOptions; - class LangOptions; - class DiagnosticsEngine; - -namespace ento { - class CheckerManager; - class CheckerRegistry; - - std::unique_ptr<CheckerManager> createCheckerManager( - ASTContext &context, - AnalyzerOptions &opts, - ArrayRef<std::string> plugins, - ArrayRef<std::function<void(CheckerRegistry &)>> checkerRegistrationFns, - DiagnosticsEngine &diags); - -} // end ento namespace - -} // end namespace clang - -#endif diff --git a/clang/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h b/clang/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h index bc258160ada4..43dbfb158515 100644 --- a/clang/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h +++ b/clang/include/clang/StaticAnalyzer/Frontend/CheckerRegistry.h @@ -5,16 +5,22 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// +// +// Contains the logic for parsing the TableGen file Checkers.td, and parsing the +// specific invocation of the analyzer (which checker/package is enabled, values +// of their options, etc). This is in the frontend library because checker +// registry functions are called from here but are defined in the dependent +// library libStaticAnalyzerCheckers, but the actual data structure that holds +// the parsed information is in the Core library. +// +//===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_STATICANALYZER_CORE_CHECKERREGISTRY_H -#define LLVM_CLANG_STATICANALYZER_CORE_CHECKERREGISTRY_H +#ifndef LLVM_CLANG_STATICANALYZER_FRONTEND_CHECKERREGISTRY_H +#define LLVM_CLANG_STATICANALYZER_FRONTEND_CHECKERREGISTRY_H #include "clang/Basic/LLVM.h" -#include "clang/StaticAnalyzer/Core/CheckerManager.h" -#include "llvm/ADT/StringMap.h" +#include "clang/StaticAnalyzer/Core/CheckerRegistryData.h" #include "llvm/ADT/StringRef.h" -#include <cstddef> -#include <vector> // FIXME: move this information to an HTML file in docs/. // At the very least, a checker plugin is a dynamic library that exports @@ -69,10 +75,11 @@ namespace clang { class AnalyzerOptions; class DiagnosticsEngine; -class LangOptions; namespace ento { +class CheckerManager; + /// Manages a set of available checkers for running a static analysis. /// The checkers are organized into packages by full name, where including /// a package will recursively include all subpackages and checkers within it. @@ -81,161 +88,60 @@ namespace ento { /// "core.builtin", or the full name "core.builtin.NoReturnFunctionChecker". class CheckerRegistry { public: - CheckerRegistry(ArrayRef<std::string> plugins, DiagnosticsEngine &diags, - AnalyzerOptions &AnOpts, const LangOptions &LangOpts, + CheckerRegistry(CheckerRegistryData &Data, ArrayRef<std::string> Plugins, + DiagnosticsEngine &Diags, AnalyzerOptions &AnOpts, ArrayRef<std::function<void(CheckerRegistry &)>> - checkerRegistrationFns = {}); - - /// Initialization functions perform any necessary setup for a checker. - /// They should include a call to CheckerManager::registerChecker. - using InitializationFunction = void (*)(CheckerManager &); - using ShouldRegisterFunction = bool (*)(const LangOptions &); - - /// Specifies a command line option. It may either belong to a checker or a - /// package. - struct CmdLineOption { - StringRef OptionType; - StringRef OptionName; - StringRef DefaultValStr; - StringRef Description; - StringRef DevelopmentStatus; - bool IsHidden; - - CmdLineOption(StringRef OptionType, StringRef OptionName, - StringRef DefaultValStr, StringRef Description, - StringRef DevelopmentStatus, bool IsHidden) - : OptionType(OptionType), OptionName(OptionName), - DefaultValStr(DefaultValStr), Description(Description), - DevelopmentStatus(DevelopmentStatus), IsHidden(IsHidden) { - - assert((OptionType == "bool" || OptionType == "string" || - OptionType == "int") && - "Unknown command line option type!"); - - assert((OptionType != "bool" || - (DefaultValStr == "true" || DefaultValStr == "false")) && - "Invalid value for boolean command line option! Maybe incorrect " - "parameters to the addCheckerOption or addPackageOption method?"); - - int Tmp; - assert((OptionType != "int" || !DefaultValStr.getAsInteger(0, Tmp)) && - "Invalid value for integer command line option! Maybe incorrect " - "parameters to the addCheckerOption or addPackageOption method?"); - (void)Tmp; - - assert((DevelopmentStatus == "alpha" || DevelopmentStatus == "beta" || - DevelopmentStatus == "released") && - "Invalid development status!"); - } - }; - - using CmdLineOptionList = llvm::SmallVector<CmdLineOption, 0>; - - struct CheckerInfo; - - using CheckerInfoList = std::vector<CheckerInfo>; - using CheckerInfoListRange = llvm::iterator_range<CheckerInfoList::iterator>; - using ConstCheckerInfoList = llvm::SmallVector<const CheckerInfo *, 0>; - using CheckerInfoSet = llvm::SetVector<const CheckerInfo *>; - - /// Specifies a checker. Note that this isn't what we call a checker object, - /// it merely contains everything required to create one. - struct CheckerInfo { - enum class StateFromCmdLine { - // This checker wasn't explicitly enabled or disabled. - State_Unspecified, - // This checker was explicitly disabled. - State_Disabled, - // This checker was explicitly enabled. - State_Enabled - }; - - InitializationFunction Initialize = nullptr; - ShouldRegisterFunction ShouldRegister = nullptr; - StringRef FullName; - StringRef Desc; - StringRef DocumentationUri; - CmdLineOptionList CmdLineOptions; - bool IsHidden = false; - StateFromCmdLine State = StateFromCmdLine::State_Unspecified; - - ConstCheckerInfoList Dependencies; + CheckerRegistrationFns = {}); - bool isEnabled(const LangOptions &LO) const { - return State == StateFromCmdLine::State_Enabled && ShouldRegister(LO); - } + /// Collects all enabled checkers in the field EnabledCheckers. It preserves + /// the order of insertion, as dependencies have to be enabled before the + /// checkers that depend on them. + void initializeRegistry(const CheckerManager &Mgr); - bool isDisabled(const LangOptions &LO) const { - return State == StateFromCmdLine::State_Disabled && ShouldRegister(LO); - } - - // Since each checker must have a different full name, we can identify - // CheckerInfo objects by them. - bool operator==(const CheckerInfo &Rhs) const { - return FullName == Rhs.FullName; - } - - CheckerInfo(InitializationFunction Fn, ShouldRegisterFunction sfn, - StringRef Name, StringRef Desc, StringRef DocsUri, - bool IsHidden) - : Initialize(Fn), ShouldRegister(sfn), FullName(Name), Desc(Desc), - DocumentationUri(DocsUri), IsHidden(IsHidden) {} - - // Used for lower_bound. - explicit CheckerInfo(StringRef FullName) : FullName(FullName) {} - }; - - using StateFromCmdLine = CheckerInfo::StateFromCmdLine; - - /// Specifies a package. Each package option is implicitly an option for all - /// checkers within the package. - struct PackageInfo { - StringRef FullName; - CmdLineOptionList CmdLineOptions; - - // Since each package must have a different full name, we can identify - // CheckerInfo objects by them. - bool operator==(const PackageInfo &Rhs) const { - return FullName == Rhs.FullName; - } - - explicit PackageInfo(StringRef FullName) : FullName(FullName) {} - }; - - using PackageInfoList = llvm::SmallVector<PackageInfo, 0>; private: - template <typename T> static void initializeManager(CheckerManager &mgr) { - mgr.registerChecker<T>(); + /// Default initialization function for checkers -- since CheckerManager + /// includes this header, we need to make it a template parameter, and since + /// the checker must be a template parameter as well, we can't put this in the + /// cpp file. + template <typename MGR, typename T> static void initializeManager(MGR &mgr) { + mgr.template registerChecker<T>(); } - template <typename T> static bool returnTrue(const LangOptions &LO) { + template <typename T> static bool returnTrue(const CheckerManager &mgr) { return true; } public: /// Adds a checker to the registry. Use this non-templated overload when your /// checker requires custom initialization. - void addChecker(InitializationFunction Fn, ShouldRegisterFunction sfn, + void addChecker(RegisterCheckerFn Fn, ShouldRegisterFunction sfn, StringRef FullName, StringRef Desc, StringRef DocsUri, bool IsHidden); /// Adds a checker to the registry. Use this templated overload when your /// checker does not require any custom initialization. + /// This function isn't really needed and probably causes more headaches than + /// the tiny convenience that it provides, but external plugins might use it, + /// and there isn't a strong incentive to remove it. template <class T> void addChecker(StringRef FullName, StringRef Desc, StringRef DocsUri, bool IsHidden = false) { // Avoid MSVC's Compiler Error C2276: // http://msdn.microsoft.com/en-us/library/850cstw1(v=VS.80).aspx - addChecker(&CheckerRegistry::initializeManager<T>, + addChecker(&CheckerRegistry::initializeManager<CheckerManager, T>, &CheckerRegistry::returnTrue<T>, FullName, Desc, DocsUri, IsHidden); } - /// Makes the checker with the full name \p fullName depends on the checker + /// Makes the checker with the full name \p fullName depend on the checker /// called \p dependency. void addDependency(StringRef FullName, StringRef Dependency); + /// Makes the checker with the full name \p fullName weak depend on the + /// checker called \p dependency. + void addWeakDependency(StringRef FullName, StringRef Dependency); + /// Registers an option to a given checker. A checker option will always have /// the following format: /// CheckerFullName:OptionName=Value @@ -265,7 +171,7 @@ public: void addPackageOption(StringRef OptionType, StringRef PackageFullName, StringRef OptionName, StringRef DefaultValStr, StringRef Description, StringRef DevelopmentStatus, - bool IsHidden = false); + bool IsHidden = false); // FIXME: This *really* should be added to the frontend flag descriptions. /// Initializes a CheckerManager by calling the initialization functions for @@ -277,49 +183,17 @@ public: /// Check if every option corresponds to a specific checker or package. void validateCheckerOptions() const; - /// Prints the name and description of all checkers in this registry. - /// This output is not intended to be machine-parseable. - void printCheckerWithDescList(raw_ostream &Out, - size_t MaxNameChars = 30) const; - void printEnabledCheckerList(raw_ostream &Out) const; - void printCheckerOptionList(raw_ostream &Out) const; - private: - /// Collect all enabled checkers. The returned container preserves the order - /// of insertion, as dependencies have to be enabled before the checkers that - /// depend on them. - CheckerInfoSet getEnabledCheckers() const; - - /// Return an iterator range of mutable CheckerInfos \p CmdLineArg applies to. - /// For example, it'll return the checkers for the core package, if - /// \p CmdLineArg is "core". - CheckerInfoListRange getMutableCheckersForCmdLineArg(StringRef CmdLineArg); - - CheckerInfoList Checkers; - PackageInfoList Packages; - /// Used for couting how many checkers belong to a certain package in the - /// \c Checkers field. For convenience purposes. - llvm::StringMap<size_t> PackageSizes; - - /// Contains all (Dependendent checker, Dependency) pairs. We need this, as - /// we'll resolve dependencies after all checkers were added first. - llvm::SmallVector<std::pair<StringRef, StringRef>, 0> Dependencies; - void resolveDependencies(); - - /// Contains all (FullName, CmdLineOption) pairs. Similarly to dependencies, - /// we only modify the actual CheckerInfo and PackageInfo objects once all - /// of them have been added. - llvm::SmallVector<std::pair<StringRef, CmdLineOption>, 0> PackageOptions; - llvm::SmallVector<std::pair<StringRef, CmdLineOption>, 0> CheckerOptions; - + template <bool IsWeak> void resolveDependencies(); void resolveCheckerAndPackageOptions(); + CheckerRegistryData &Data; + DiagnosticsEngine &Diags; AnalyzerOptions &AnOpts; - const LangOptions &LangOpts; }; } // namespace ento } // namespace clang -#endif // LLVM_CLANG_STATICANALYZER_CORE_CHECKERREGISTRY_H +#endif // LLVM_CLANG_STATICANALYZER_FRONTEND_CHECKERREGISTRY_H diff --git a/clang/include/clang/StaticAnalyzer/Frontend/FrontendActions.h b/clang/include/clang/StaticAnalyzer/Frontend/FrontendActions.h index 878b65a1b143..2b12330e4f2d 100644 --- a/clang/include/clang/StaticAnalyzer/Frontend/FrontendActions.h +++ b/clang/include/clang/StaticAnalyzer/Frontend/FrontendActions.h @@ -20,6 +20,8 @@ class AnalyzerOptions; namespace ento { +class CheckerManager; + //===----------------------------------------------------------------------===// // AST Consumer Actions //===----------------------------------------------------------------------===// @@ -51,23 +53,7 @@ private: llvm::StringMap<Stmt *> &Bodies; }; -void printCheckerHelp(raw_ostream &OS, - ArrayRef<std::string> plugins, - AnalyzerOptions &opts, - DiagnosticsEngine &diags, - const LangOptions &LangOpts); -void printEnabledCheckerList(raw_ostream &OS, ArrayRef<std::string> plugins, - AnalyzerOptions &opts, - DiagnosticsEngine &diags, - const LangOptions &LangOpts); -void printAnalyzerConfigList(raw_ostream &OS); -void printCheckerConfigList(raw_ostream &OS, ArrayRef<std::string> plugins, - AnalyzerOptions &opts, - DiagnosticsEngine &diags, - const LangOptions &LangOpts); - -} // end GR namespace - +} // namespace ento } // end namespace clang #endif diff --git a/clang/include/clang/Testing/CommandLineArgs.h b/clang/include/clang/Testing/CommandLineArgs.h new file mode 100644 index 000000000000..95979a2bfb80 --- /dev/null +++ b/clang/include/clang/Testing/CommandLineArgs.h @@ -0,0 +1,41 @@ +//===--- CommandLineArgs.h ------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file defines language options for Clang unittests. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TESTING_COMMANDLINEARGS_H +#define LLVM_CLANG_TESTING_COMMANDLINEARGS_H + +#include "clang/Basic/LLVM.h" +#include "llvm/ADT/StringRef.h" +#include <string> +#include <vector> + +namespace clang { + +enum TestLanguage { + Lang_C89, + Lang_C99, + Lang_CXX03, + Lang_CXX11, + Lang_CXX14, + Lang_CXX17, + Lang_CXX20, + Lang_OpenCL, + Lang_OBJCXX +}; + +std::vector<std::string> getCommandLineArgsForTesting(TestLanguage Lang); + +StringRef getFilenameForTesting(TestLanguage Lang); + +} // end namespace clang + +#endif diff --git a/clang/include/clang/Testing/TestClangConfig.h b/clang/include/clang/Testing/TestClangConfig.h new file mode 100644 index 000000000000..eefa36dc2ebb --- /dev/null +++ b/clang/include/clang/Testing/TestClangConfig.h @@ -0,0 +1,85 @@ +//===--- TestClangConfig.h ------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TESTING_TESTCLANGCONFIG_H +#define LLVM_CLANG_TESTING_TESTCLANGCONFIG_H + +#include "clang/Testing/CommandLineArgs.h" +#include "llvm/Support/raw_ostream.h" +#include <string> +#include <vector> + +namespace clang { + +/// A Clang configuration for end-to-end tests that can be converted to +/// command line arguments for the driver. +/// +/// The configuration is represented as typed, named values, making it easier +/// and safer to work with compared to an array of string command line flags. +struct TestClangConfig { + TestLanguage Language; + + /// The argument of the `-target` command line flag. + std::string Target; + + bool isC() const { return Language == Lang_C89 || Language == Lang_C99; } + + bool isC99OrLater() const { return Language == Lang_C99; } + + bool isCXX() const { + return Language == Lang_CXX03 || Language == Lang_CXX11 || + Language == Lang_CXX14 || Language == Lang_CXX17 || + Language == Lang_CXX20; + } + + bool isCXX11OrLater() const { + return Language == Lang_CXX11 || Language == Lang_CXX14 || + Language == Lang_CXX17 || Language == Lang_CXX20; + } + + bool isCXX14OrLater() const { + return Language == Lang_CXX14 || Language == Lang_CXX17 || + Language == Lang_CXX20; + } + + bool isCXX17OrLater() const { + return Language == Lang_CXX17 || Language == Lang_CXX20; + } + + bool supportsCXXDynamicExceptionSpecification() const { + return Language == Lang_CXX03 || Language == Lang_CXX11 || + Language == Lang_CXX14; + } + + bool hasDelayedTemplateParsing() const { + return Target == "x86_64-pc-win32-msvc"; + } + + std::vector<std::string> getCommandLineArgs() const { + std::vector<std::string> Result = getCommandLineArgsForTesting(Language); + Result.push_back("-target"); + Result.push_back(Target); + return Result; + } + + std::string toString() const { + std::string Result; + llvm::raw_string_ostream OS(Result); + OS << "{ Language=" << Language << ", Target=" << Target << " }"; + return OS.str(); + } + + friend std::ostream &operator<<(std::ostream &OS, + const TestClangConfig &ClangConfig) { + return OS << ClangConfig.toString(); + } +}; + +} // end namespace clang + +#endif diff --git a/clang/include/clang/Tooling/ASTDiff/ASTDiff.h b/clang/include/clang/Tooling/ASTDiff/ASTDiff.h index c1cc124e1e9f..c772ad84c139 100644 --- a/clang/include/clang/Tooling/ASTDiff/ASTDiff.h +++ b/clang/include/clang/Tooling/ASTDiff/ASTDiff.h @@ -37,11 +37,11 @@ enum ChangeKind { struct Node { NodeId Parent, LeftMostDescendant, RightMostDescendant; int Depth, Height, Shift = 0; - ast_type_traits::DynTypedNode ASTNode; + DynTypedNode ASTNode; SmallVector<NodeId, 4> Children; ChangeKind Change = None; - ast_type_traits::ASTNodeKind getType() const; + ASTNodeKind getType() const; StringRef getTypeLabel() const; bool isLeaf() const { return Children.empty(); } llvm::Optional<StringRef> getIdentifier() const; diff --git a/clang/include/clang/Tooling/ASTDiff/ASTDiffInternal.h b/clang/include/clang/Tooling/ASTDiff/ASTDiffInternal.h index 0c15b30cc69c..1e784ef43ac1 100644 --- a/clang/include/clang/Tooling/ASTDiff/ASTDiffInternal.h +++ b/clang/include/clang/Tooling/ASTDiff/ASTDiffInternal.h @@ -15,7 +15,7 @@ namespace clang { namespace diff { -using DynTypedNode = ast_type_traits::DynTypedNode; +using DynTypedNode = DynTypedNode; class SyntaxTree; class SyntaxTreeImpl; diff --git a/clang/include/clang/Tooling/AllTUsExecution.h b/clang/include/clang/Tooling/AllTUsExecution.h index 1e618b5ba2f0..43f2792457e7 100644 --- a/clang/include/clang/Tooling/AllTUsExecution.h +++ b/clang/include/clang/Tooling/AllTUsExecution.h @@ -56,7 +56,7 @@ public: ToolResults *getToolResults() override { return Results.get(); } void mapVirtualFile(StringRef FilePath, StringRef Content) override { - OverlayFiles[FilePath] = Content; + OverlayFiles[FilePath] = std::string(Content); } private: diff --git a/clang/include/clang/Tooling/Core/Diagnostic.h b/clang/include/clang/Tooling/Core/Diagnostic.h index 4e0feba6d7dc..123874f9ccf7 100644 --- a/clang/include/clang/Tooling/Core/Diagnostic.h +++ b/clang/include/clang/Tooling/Core/Diagnostic.h @@ -47,6 +47,17 @@ struct DiagnosticMessage { llvm::StringMap<Replacements> Fix; }; +/// Represents a range within a specific source file. +struct FileByteRange { + FileByteRange() = default; + + FileByteRange(const SourceManager &Sources, CharSourceRange Range); + + std::string FilePath; + unsigned FileOffset; + unsigned Length; +}; + /// Represents the diagnostic with the level of severity and possible /// fixes to be applied. struct Diagnostic { @@ -62,7 +73,8 @@ struct Diagnostic { Diagnostic(llvm::StringRef DiagnosticName, const DiagnosticMessage &Message, const SmallVector<DiagnosticMessage, 1> &Notes, Level DiagLevel, - llvm::StringRef BuildDirectory); + llvm::StringRef BuildDirectory, + const SmallVector<FileByteRange, 1> &Ranges); /// Name identifying the Diagnostic. std::string DiagnosticName; @@ -84,6 +96,10 @@ struct Diagnostic { /// /// Note: it is empty in unittest. std::string BuildDirectory; + + /// Extra source ranges associated with the diagnostic (in addition to the + /// location of the Message above). + SmallVector<FileByteRange, 1> Ranges; }; /// Collection of Diagnostics generated from a single translation unit. diff --git a/clang/include/clang/Tooling/DependencyScanning/DependencyScanningTool.h b/clang/include/clang/Tooling/DependencyScanning/DependencyScanningTool.h index a0c1900f7ed9..1c106ed4b765 100644 --- a/clang/include/clang/Tooling/DependencyScanning/DependencyScanningTool.h +++ b/clang/include/clang/Tooling/DependencyScanning/DependencyScanningTool.h @@ -11,13 +11,69 @@ #include "clang/Tooling/DependencyScanning/DependencyScanningService.h" #include "clang/Tooling/DependencyScanning/DependencyScanningWorker.h" +#include "clang/Tooling/DependencyScanning/ModuleDepCollector.h" #include "clang/Tooling/JSONCompilationDatabase.h" +#include "llvm/ADT/StringSet.h" #include <string> namespace clang{ namespace tooling{ namespace dependencies{ +/// The full dependencies and module graph for a specific input. +struct FullDependencies { + /// The name of the C++20 module this translation unit exports. This may + /// include `:` for C++20 module partitons. + /// + /// If the translation unit is not a module then this will be empty. + std::string ExportedModuleName; + + /// The context hash represents the set of compiler options that may make one + /// version of a module incompatible with another. This includes things like + /// language mode, predefined macros, header search paths, etc... + /// + /// Modules with the same name but a different \c ContextHash should be + /// treated as separate modules for the purpose of a build. + std::string ContextHash; + + /// A collection of absolute paths to files that this translation unit + /// directly depends on, not including transitive dependencies. + std::vector<std::string> FileDeps; + + /// A list of modules this translation unit directly depends on, not including + /// transitive dependencies. + /// + /// This may include modules with a different context hash when it can be + /// determined that the differences are benign for this compilation. + std::vector<ClangModuleDep> ClangModuleDeps; + + /// A partial addtional set of command line arguments that can be used to + /// build this translation unit. + /// + /// Call \c getFullAdditionalCommandLine() to get a command line suitable for + /// appending to the original command line to pass to clang. + std::vector<std::string> AdditionalNonPathCommandLine; + + /// Gets the full addtional command line suitable for appending to the + /// original command line to pass to clang. + /// + /// \param LookupPCMPath this function is called to fill in `-fmodule-file=` + /// flags and for the `-o` flag. It needs to return a + /// path for where the PCM for the given module is to + /// be located. + /// \param LookupModuleDeps this fucntion is called to collect the full + /// transitive set of dependencies for this + /// compilation. + std::vector<std::string> getAdditionalCommandLine( + std::function<StringRef(ClangModuleDep)> LookupPCMPath, + std::function<const ModuleDeps &(ClangModuleDep)> LookupModuleDeps) const; +}; + +struct FullDependenciesResult { + FullDependencies FullDeps; + std::vector<ModuleDeps> DiscoveredModules; +}; + /// The high-level implementation of the dependency discovery tool that runs on /// an individual worker thread. class DependencyScanningTool { @@ -35,8 +91,23 @@ public: getDependencyFile(const tooling::CompilationDatabase &Compilations, StringRef CWD); + /// Collect the full module depenedency graph for the input, ignoring any + /// modules which have already been seen. + /// + /// \param AlreadySeen this is used to not report modules that have previously + /// been reported. Use the same `llvm::StringSet<>` for all + /// calls to `getFullDependencies` for a single + /// `DependencyScanningTool` for a single build. Use a + /// different one for different tools, and clear it between + /// builds. + /// + /// \returns a \c StringError with the diagnostic output if clang errors + /// occurred, \c FullDependencies otherwise. + llvm::Expected<FullDependenciesResult> + getFullDependencies(const tooling::CompilationDatabase &Compilations, + StringRef CWD, const llvm::StringSet<> &AlreadySeen); + private: - const ScanningOutputFormat Format; DependencyScanningWorker Worker; }; diff --git a/clang/include/clang/Tooling/DependencyScanning/ModuleDepCollector.h b/clang/include/clang/Tooling/DependencyScanning/ModuleDepCollector.h index 7a9fc276fcaa..c490bb38c167 100644 --- a/clang/include/clang/Tooling/DependencyScanning/ModuleDepCollector.h +++ b/clang/include/clang/Tooling/DependencyScanning/ModuleDepCollector.h @@ -19,8 +19,8 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/StringSet.h" #include "llvm/Support/raw_ostream.h" - #include <string> +#include <unordered_map> namespace clang { namespace tooling { @@ -28,16 +28,82 @@ namespace dependencies { class DependencyConsumer; +/// This is used to refer to a specific module. +/// +/// See \c ModuleDeps for details about what these members mean. +struct ClangModuleDep { + std::string ModuleName; + std::string ContextHash; +}; + struct ModuleDeps { + /// The name of the module. This may include `:` for C++20 module partitons, + /// or a header-name for C++20 header units. std::string ModuleName; - std::string ClangModuleMapFile; - std::string ModulePCMPath; + + /// The context hash of a module represents the set of compiler options that + /// may make one version of a module incompatible with another. This includes + /// things like language mode, predefined macros, header search paths, etc... + /// + /// Modules with the same name but a different \c ContextHash should be + /// treated as separate modules for the purpose of a build. std::string ContextHash; + + /// The path to the modulemap file which defines this module. + /// + /// This can be used to explicitly build this module. This file will + /// additionally appear in \c FileDeps as a dependency. + std::string ClangModuleMapFile; + + /// The path to where an implicit build would put the PCM for this module. + std::string ImplicitModulePCMPath; + + /// A collection of absolute paths to files that this module directly depends + /// on, not including transitive dependencies. llvm::StringSet<> FileDeps; - llvm::StringSet<> ClangModuleDeps; + + /// A list of modules this module directly depends on, not including + /// transitive dependencies. + /// + /// This may include modules with a different context hash when it can be + /// determined that the differences are benign for this compilation. + std::vector<ClangModuleDep> ClangModuleDeps; + + /// A partial command line that can be used to build this module. + /// + /// Call \c getFullCommandLine() to get a command line suitable for passing to + /// clang. + std::vector<std::string> NonPathCommandLine; + + // Used to track which modules that were discovered were directly imported by + // the primary TU. bool ImportedByMainFile = false; + + /// Gets the full command line suitable for passing to clang. + /// + /// \param LookupPCMPath this function is called to fill in `-fmodule-file=` + /// flags and for the `-o` flag. It needs to return a + /// path for where the PCM for the given module is to + /// be located. + /// \param LookupModuleDeps this fucntion is called to collect the full + /// transitive set of dependencies for this + /// compilation. + std::vector<std::string> getFullCommandLine( + std::function<StringRef(ClangModuleDep)> LookupPCMPath, + std::function<const ModuleDeps &(ClangModuleDep)> LookupModuleDeps) const; }; +namespace detail { +/// Append the `-fmodule-file=` and `-fmodule-map-file=` arguments for the +/// modules in \c Modules transitively, along with other needed arguments to +/// use explicitly built modules. +void appendCommonModuleArguments( + llvm::ArrayRef<ClangModuleDep> Modules, + std::function<StringRef(ClangModuleDep)> LookupPCMPath, + std::function<const ModuleDeps &(ClangModuleDep)> LookupModuleDeps, + std::vector<std::string> &Result); +} // namespace detail + class ModuleDepCollector; class ModuleDepCollectorPP final : public PPCallbacks { @@ -54,6 +120,8 @@ public: StringRef SearchPath, StringRef RelativePath, const Module *Imported, SrcMgr::CharacteristicKind FileType) override; + void moduleImport(SourceLocation ImportLoc, ModuleIdPath Path, + const Module *Imported) override; void EndOfMainFile() override; @@ -62,16 +130,18 @@ private: ModuleDepCollector &MDC; llvm::DenseSet<const Module *> DirectDeps; + void handleImport(const Module *Imported); void handleTopLevelModule(const Module *M); - void addAllSubmoduleDeps(const Module *M, ModuleDeps &MD); - void addModuleDep(const Module *M, ModuleDeps &MD); - - void addDirectDependencies(const Module *Mod); + void addAllSubmoduleDeps(const Module *M, ModuleDeps &MD, + llvm::DenseSet<const Module *> &AddedModules); + void addModuleDep(const Module *M, ModuleDeps &MD, + llvm::DenseSet<const Module *> &AddedModules); }; class ModuleDepCollector final : public DependencyCollector { public: - ModuleDepCollector(CompilerInstance &I, DependencyConsumer &C); + ModuleDepCollector(std::unique_ptr<DependencyOutputOptions> Opts, + CompilerInstance &I, DependencyConsumer &C); void attachToPreprocessor(Preprocessor &PP) override; void attachToASTReader(ASTReader &R) override; @@ -85,6 +155,7 @@ private: std::string ContextHash; std::vector<std::string> MainDeps; std::unordered_map<std::string, ModuleDeps> Deps; + std::unique_ptr<DependencyOutputOptions> Opts; }; } // end namespace dependencies diff --git a/clang/include/clang/Tooling/DiagnosticsYaml.h b/clang/include/clang/Tooling/DiagnosticsYaml.h index 366ee6f6703b..38fbcfc1da95 100644 --- a/clang/include/clang/Tooling/DiagnosticsYaml.h +++ b/clang/include/clang/Tooling/DiagnosticsYaml.h @@ -22,10 +22,19 @@ LLVM_YAML_IS_SEQUENCE_VECTOR(clang::tooling::Diagnostic) LLVM_YAML_IS_SEQUENCE_VECTOR(clang::tooling::DiagnosticMessage) +LLVM_YAML_IS_SEQUENCE_VECTOR(clang::tooling::FileByteRange) namespace llvm { namespace yaml { +template <> struct MappingTraits<clang::tooling::FileByteRange> { + static void mapping(IO &Io, clang::tooling::FileByteRange &R) { + Io.mapRequired("FilePath", R.FilePath); + Io.mapRequired("FileOffset", R.FileOffset); + Io.mapRequired("Length", R.Length); + } +}; + template <> struct MappingTraits<clang::tooling::DiagnosticMessage> { static void mapping(IO &Io, clang::tooling::DiagnosticMessage &M) { Io.mapRequired("Message", M.Message); @@ -58,19 +67,20 @@ template <> struct MappingTraits<clang::tooling::Diagnostic> { NormalizedDiagnostic(const IO &, const clang::tooling::Diagnostic &D) : DiagnosticName(D.DiagnosticName), Message(D.Message), Notes(D.Notes), - DiagLevel(D.DiagLevel), BuildDirectory(D.BuildDirectory) {} + DiagLevel(D.DiagLevel), BuildDirectory(D.BuildDirectory), + Ranges(D.Ranges) {} clang::tooling::Diagnostic denormalize(const IO &) { return clang::tooling::Diagnostic(DiagnosticName, Message, Notes, - DiagLevel, BuildDirectory); + DiagLevel, BuildDirectory, Ranges); } std::string DiagnosticName; clang::tooling::DiagnosticMessage Message; - llvm::StringMap<clang::tooling::Replacements> Fix; SmallVector<clang::tooling::DiagnosticMessage, 1> Notes; clang::tooling::Diagnostic::Level DiagLevel; std::string BuildDirectory; + SmallVector<clang::tooling::FileByteRange, 1> Ranges; }; static void mapping(IO &Io, clang::tooling::Diagnostic &D) { @@ -79,8 +89,9 @@ template <> struct MappingTraits<clang::tooling::Diagnostic> { Io.mapRequired("DiagnosticName", Keys->DiagnosticName); Io.mapRequired("DiagnosticMessage", Keys->Message); Io.mapOptional("Notes", Keys->Notes); - - // FIXME: Export properly all the different fields. + Io.mapOptional("Level", Keys->DiagLevel); + Io.mapOptional("BuildDirectory", Keys->BuildDirectory); + Io.mapOptional("Ranges", Keys->Ranges); } }; @@ -92,6 +103,14 @@ template <> struct MappingTraits<clang::tooling::TranslationUnitDiagnostics> { Io.mapRequired("Diagnostics", Doc.Diagnostics); } }; + +template <> struct ScalarEnumerationTraits<clang::tooling::Diagnostic::Level> { + static void enumeration(IO &IO, clang::tooling::Diagnostic::Level &Value) { + IO.enumCase(Value, "Warning", clang::tooling::Diagnostic::Warning); + IO.enumCase(Value, "Error", clang::tooling::Diagnostic::Error); + } +}; + } // end namespace yaml } // end namespace llvm diff --git a/clang/include/clang/Tooling/Refactoring/ASTSelection.h b/clang/include/clang/Tooling/Refactoring/ASTSelection.h index 9122b5c73c98..239be36012c3 100644 --- a/clang/include/clang/Tooling/Refactoring/ASTSelection.h +++ b/clang/include/clang/Tooling/Refactoring/ASTSelection.h @@ -13,6 +13,7 @@ #include "clang/AST/Stmt.h" #include "clang/Basic/LLVM.h" #include "clang/Basic/SourceLocation.h" +#include "llvm/Support/raw_ostream.h" #include <vector> namespace clang { @@ -48,12 +49,11 @@ enum class SourceSelectionKind { /// actually be selected, e.g. a statement in macro whose child is in a macro /// argument. struct SelectedASTNode { - ast_type_traits::DynTypedNode Node; + DynTypedNode Node; SourceSelectionKind SelectionKind; std::vector<SelectedASTNode> Children; - SelectedASTNode(const ast_type_traits::DynTypedNode &Node, - SourceSelectionKind SelectionKind) + SelectedASTNode(const DynTypedNode &Node, SourceSelectionKind SelectionKind) : Node(Node), SelectionKind(SelectionKind) {} SelectedASTNode(SelectedASTNode &&) = default; SelectedASTNode &operator=(SelectedASTNode &&) = default; diff --git a/clang/include/clang/Tooling/Refactoring/AtomicChange.h b/clang/include/clang/Tooling/Refactoring/AtomicChange.h index 32e4624fc8e7..f1034a3d0579 100644 --- a/clang/include/clang/Tooling/Refactoring/AtomicChange.h +++ b/clang/include/clang/Tooling/Refactoring/AtomicChange.h @@ -17,6 +17,7 @@ #include "clang/Basic/SourceManager.h" #include "clang/Format/Format.h" #include "clang/Tooling/Core/Replacement.h" +#include "llvm/ADT/Any.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/Error.h" @@ -41,6 +42,9 @@ public: /// is being changed, e.g. the call to a refactored method. AtomicChange(const SourceManager &SM, SourceLocation KeyPosition); + AtomicChange(const SourceManager &SM, SourceLocation KeyPosition, + llvm::Any Metadata); + /// Creates an atomic change for \p FilePath with a customized key. AtomicChange(llvm::StringRef FilePath, llvm::StringRef Key) : Key(Key), FilePath(FilePath) {} @@ -70,7 +74,7 @@ public: /// conflicts among replacements, use this to set an error description. /// Thereby, places that cannot be fixed automatically can be gathered when /// applying changes. - void setError(llvm::StringRef Error) { this->Error = Error; } + void setError(llvm::StringRef Error) { this->Error = std::string(Error); } /// Returns whether an error has been set on this list. bool hasError() const { return !Error.empty(); } @@ -120,6 +124,8 @@ public: return RemovedHeaders; } + const llvm::Any &getMetadata() const { return Metadata; } + private: AtomicChange() {} @@ -135,6 +141,12 @@ private: std::vector<std::string> InsertedHeaders; std::vector<std::string> RemovedHeaders; tooling::Replacements Replaces; + + // This field stores metadata which is ignored for the purposes of applying + // edits to source, but may be useful for other consumers of AtomicChanges. In + // particular, consumers can use this to direct how they want to consume each + // edit. + llvm::Any Metadata; }; using AtomicChanges = std::vector<AtomicChange>; diff --git a/clang/include/clang/Tooling/Refactoring/RefactoringOptions.h b/clang/include/clang/Tooling/Refactoring/RefactoringOptions.h index f25f526e146c..84122b111ee1 100644 --- a/clang/include/clang/Tooling/Refactoring/RefactoringOptions.h +++ b/clang/include/clang/Tooling/Refactoring/RefactoringOptions.h @@ -20,8 +20,8 @@ namespace clang { namespace tooling { /// A refactoring option that stores a value of type \c T. -template <typename T, typename = typename std::enable_if< - traits::IsValidOptionType<T>::value>::type> +template <typename T, + typename = std::enable_if_t<traits::IsValidOptionType<T>::value>> class OptionalRefactoringOption : public RefactoringOption { public: void passToVisitor(RefactoringOptionVisitor &Visitor) final override { @@ -39,8 +39,8 @@ protected: }; /// A required refactoring option that stores a value of type \c T. -template <typename T, typename = typename std::enable_if< - traits::IsValidOptionType<T>::value>::type> +template <typename T, + typename = std::enable_if_t<traits::IsValidOptionType<T>::value>> class RequiredRefactoringOption : public OptionalRefactoringOption<T> { public: using ValueType = T; diff --git a/clang/include/clang/Tooling/ReplacementsYaml.h b/clang/include/clang/Tooling/ReplacementsYaml.h index 2e3e401652e2..83e35d623255 100644 --- a/clang/include/clang/Tooling/ReplacementsYaml.h +++ b/clang/include/clang/Tooling/ReplacementsYaml.h @@ -35,13 +35,7 @@ template <> struct MappingTraits<clang::tooling::Replacement> { NormalizedReplacement(const IO &, const clang::tooling::Replacement &R) : FilePath(R.getFilePath()), Offset(R.getOffset()), - Length(R.getLength()), ReplacementText(R.getReplacementText()) { - size_t lineBreakPos = ReplacementText.find('\n'); - while (lineBreakPos != std::string::npos) { - ReplacementText.replace(lineBreakPos, 1, "\n\n"); - lineBreakPos = ReplacementText.find('\n', lineBreakPos + 2); - } - } + Length(R.getLength()), ReplacementText(R.getReplacementText()) {} clang::tooling::Replacement denormalize(const IO &) { return clang::tooling::Replacement(FilePath, Offset, Length, diff --git a/clang/include/clang/Tooling/Syntax/Nodes.h b/clang/include/clang/Tooling/Syntax/Nodes.h index 25acc1757428..d97b127638bb 100644 --- a/clang/include/clang/Tooling/Syntax/Nodes.h +++ b/clang/include/clang/Tooling/Syntax/Nodes.h @@ -38,10 +38,25 @@ enum class NodeKind : uint16_t { Leaf, TranslationUnit, - // Expressions + // Expressions. UnknownExpression, - - // Statements + PrefixUnaryOperatorExpression, + PostfixUnaryOperatorExpression, + BinaryOperatorExpression, + ParenExpression, + IntegerLiteralExpression, + CharacterLiteralExpression, + FloatingLiteralExpression, + StringLiteralExpression, + BoolLiteralExpression, + CxxNullPtrExpression, + IntegerUserDefinedLiteralExpression, + FloatUserDefinedLiteralExpression, + CharUserDefinedLiteralExpression, + StringUserDefinedLiteralExpression, + IdExpression, + + // Statements. UnknownStatement, DeclarationStatement, EmptyStatement, @@ -58,23 +73,54 @@ enum class NodeKind : uint16_t { ExpressionStatement, CompoundStatement, - // Declarations + // Declarations. UnknownDeclaration, EmptyDeclaration, StaticAssertDeclaration, LinkageSpecificationDeclaration, SimpleDeclaration, + TemplateDeclaration, + ExplicitTemplateInstantiation, NamespaceDefinition, NamespaceAliasDefinition, UsingNamespaceDirective, UsingDeclaration, - TypeAliasDeclaration + TypeAliasDeclaration, + + // Declarators. + SimpleDeclarator, + ParenDeclarator, + + ArraySubscript, + TrailingReturnType, + ParametersAndQualifiers, + MemberPointer, + NestedNameSpecifier, + NameSpecifier, + UnqualifiedId }; /// For debugging purposes. llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, NodeKind K); /// A relation between a parent and child node, e.g. 'left-hand-side of /// a binary expression'. Used for implementing accessors. +/// +/// Some roles describe parent/child relations that occur multiple times in +/// language grammar. We define only one role to describe all instances of such +/// recurring relations. For example, grammar for both "if" and "while" +/// statements requires an opening paren and a closing paren. The opening +/// paren token is assigned the OpenParen role regardless of whether it appears +/// as a child of IfStatement or WhileStatement node. More generally, when +/// grammar requires a certain fixed token (like a specific keyword, or an +/// opening paren), we define a role for this token and use it across all +/// grammar rules with the same requirement. Names of such reusable roles end +/// with a ~Token or a ~Keyword suffix. +/// +/// Some roles are assigned only to child nodes of one specific parent syntax +/// node type. Names of such roles start with the name of the parent syntax tree +/// node type. For example, a syntax node with a role +/// BinaryOperatorExpression_leftHandSide can only appear as a child of a +/// BinaryOperatorExpression node. enum class NodeRole : uint8_t { // Roles common to multiple node kinds. /// A node without a parent @@ -87,12 +133,21 @@ enum class NodeRole : uint8_t { CloseParen, /// A keywords that introduces some grammar construct, e.g. 'if', 'try', etc. IntroducerKeyword, + /// A token that represents a literal, e.g. 'nullptr', '1', 'true', etc. + LiteralToken, + /// Tokens or Keywords + ArrowToken, + ExternKeyword, /// An inner statement for those that have only a single child of kind /// statement, e.g. loop body for while, for, etc; inner statement for case, /// default, etc. BodyStatement, // Roles specific to particular node kinds. + OperatorExpression_operatorToken, + UnaryOperatorExpression_operand, + BinaryOperatorExpression_leftHandSide, + BinaryOperatorExpression_rightHandSide, CaseStatement_value, IfStatement_thenStatement, IfStatement_elseKeyword, @@ -101,11 +156,24 @@ enum class NodeRole : uint8_t { ExpressionStatement_expression, CompoundStatement_statement, StaticAssertDeclaration_condition, - StaticAssertDeclaration_message + StaticAssertDeclaration_message, + SimpleDeclaration_declarator, + TemplateDeclaration_declaration, + ExplicitTemplateInstantiation_declaration, + ArraySubscript_sizeExpression, + TrailingReturnType_declarator, + ParametersAndQualifiers_parameter, + ParametersAndQualifiers_trailingReturn, + IdExpression_id, + IdExpression_qualifier, + NestedNameSpecifier_specifier, + ParenExpression_subExpression }; /// For debugging purposes. llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, NodeRole R); +class SimpleDeclarator; + /// A root node for a translation unit. Parent is always null. class TranslationUnit final : public Tree { public: @@ -126,6 +194,56 @@ public: } }; +/// A sequence of these specifiers make a `nested-name-specifier`. +/// e.g. the `std::` or `vector<int>::` in `std::vector<int>::size`. +class NameSpecifier final : public Tree { +public: + NameSpecifier() : Tree(NodeKind::NameSpecifier) {} + static bool classof(const Node *N) { + return N->kind() == NodeKind::NameSpecifier; + } +}; + +/// Models a `nested-name-specifier`. C++ [expr.prim.id.qual] +/// e.g. the `std::vector<int>::` in `std::vector<int>::size`. +class NestedNameSpecifier final : public Tree { +public: + NestedNameSpecifier() : Tree(NodeKind::NestedNameSpecifier) {} + static bool classof(const Node *N) { + return N->kind() <= NodeKind::NestedNameSpecifier; + } + std::vector<syntax::NameSpecifier *> specifiers(); +}; + +/// Models an `unqualified-id`. C++ [expr.prim.id.unqual] +/// e.g. the `size` in `std::vector<int>::size`. +class UnqualifiedId final : public Tree { +public: + UnqualifiedId() : Tree(NodeKind::UnqualifiedId) {} + static bool classof(const Node *N) { + return N->kind() == NodeKind::UnqualifiedId; + } +}; + +/// Models an `id-expression`, e.g. `std::vector<int>::size`. +/// C++ [expr.prim.id] +/// id-expression: +/// unqualified-id +/// qualified-id +/// qualified-id: +/// nested-name-specifier template_opt unqualified-id +class IdExpression final : public Expression { +public: + IdExpression() : Expression(NodeKind::IdExpression) {} + static bool classof(const Node *N) { + return N->kind() == NodeKind::IdExpression; + } + syntax::NestedNameSpecifier *qualifier(); + // TODO after expose `id-expression` from `DependentScopeDeclRefExpr`: + // Add accessor for `template_opt`. + syntax::UnqualifiedId *unqualifiedId(); +}; + /// An expression of an unknown kind, i.e. one not currently handled by the /// syntax tree. class UnknownExpression final : public Expression { @@ -136,6 +254,209 @@ public: } }; +/// Models a parenthesized expression `(E)`. C++ [expr.prim.paren] +/// e.g. `(3 + 2)` in `a = 1 + (3 + 2);` +class ParenExpression final : public Expression { +public: + ParenExpression() : Expression(NodeKind::ParenExpression) {} + static bool classof(const Node *N) { + return N->kind() == NodeKind::ParenExpression; + } + syntax::Leaf *openParen(); + syntax::Expression *subExpression(); + syntax::Leaf *closeParen(); +}; + +/// Expression for integer literals. C++ [lex.icon] +class IntegerLiteralExpression final : public Expression { +public: + IntegerLiteralExpression() : Expression(NodeKind::IntegerLiteralExpression) {} + static bool classof(const Node *N) { + return N->kind() == NodeKind::IntegerLiteralExpression; + } + syntax::Leaf *literalToken(); +}; + +/// Expression for character literals. C++ [lex.ccon] +class CharacterLiteralExpression final : public Expression { +public: + CharacterLiteralExpression() + : Expression(NodeKind::CharacterLiteralExpression) {} + static bool classof(const Node *N) { + return N->kind() == NodeKind::CharacterLiteralExpression; + } + syntax::Leaf *literalToken(); +}; + +/// Expression for floating-point literals. C++ [lex.fcon] +class FloatingLiteralExpression final : public Expression { +public: + FloatingLiteralExpression() + : Expression(NodeKind::FloatingLiteralExpression) {} + static bool classof(const Node *N) { + return N->kind() == NodeKind::FloatingLiteralExpression; + } + syntax::Leaf *literalToken(); +}; + +/// Expression for string-literals. C++ [lex.string] +class StringLiteralExpression final : public Expression { +public: + StringLiteralExpression() : Expression(NodeKind::StringLiteralExpression) {} + static bool classof(const Node *N) { + return N->kind() == NodeKind::StringLiteralExpression; + } + syntax::Leaf *literalToken(); +}; + +/// Expression for boolean literals. C++ [lex.bool] +class BoolLiteralExpression final : public Expression { +public: + BoolLiteralExpression() : Expression(NodeKind::BoolLiteralExpression) {} + static bool classof(const Node *N) { + return N->kind() == NodeKind::BoolLiteralExpression; + } + syntax::Leaf *literalToken(); +}; + +/// Expression for the `nullptr` literal. C++ [lex.nullptr] +class CxxNullPtrExpression final : public Expression { +public: + CxxNullPtrExpression() : Expression(NodeKind::CxxNullPtrExpression) {} + static bool classof(const Node *N) { + return N->kind() == NodeKind::CxxNullPtrExpression; + } + syntax::Leaf *nullPtrKeyword(); +}; + +/// Expression for user-defined literal. C++ [lex.ext] +/// user-defined-literal: +/// user-defined-integer-literal +/// user-defined-floating-point-literal +/// user-defined-string-literal +/// user-defined-character-literal +class UserDefinedLiteralExpression : public Expression { +public: + UserDefinedLiteralExpression(NodeKind K) : Expression(K) {} + static bool classof(const Node *N) { + return N->kind() == NodeKind::IntegerUserDefinedLiteralExpression || + N->kind() == NodeKind::FloatUserDefinedLiteralExpression || + N->kind() == NodeKind::CharUserDefinedLiteralExpression || + N->kind() == NodeKind::StringUserDefinedLiteralExpression; + } + syntax::Leaf *literalToken(); +}; + +/// Expression for user-defined-integer-literal. C++ [lex.ext] +class IntegerUserDefinedLiteralExpression final + : public UserDefinedLiteralExpression { +public: + IntegerUserDefinedLiteralExpression() + : UserDefinedLiteralExpression( + NodeKind::IntegerUserDefinedLiteralExpression) {} + static bool classof(const Node *N) { + return N->kind() == NodeKind::IntegerUserDefinedLiteralExpression; + } +}; + +/// Expression for user-defined-floating-point-literal. C++ [lex.ext] +class FloatUserDefinedLiteralExpression final + : public UserDefinedLiteralExpression { +public: + FloatUserDefinedLiteralExpression() + : UserDefinedLiteralExpression( + NodeKind::FloatUserDefinedLiteralExpression) {} + static bool classof(const Node *N) { + return N->kind() == NodeKind::FloatUserDefinedLiteralExpression; + } +}; + +/// Expression for user-defined-character-literal. C++ [lex.ext] +class CharUserDefinedLiteralExpression final + : public UserDefinedLiteralExpression { +public: + CharUserDefinedLiteralExpression() + : UserDefinedLiteralExpression( + NodeKind::CharUserDefinedLiteralExpression) {} + static bool classof(const Node *N) { + return N->kind() == NodeKind::CharUserDefinedLiteralExpression; + } +}; + +/// Expression for user-defined-string-literal. C++ [lex.ext] +class StringUserDefinedLiteralExpression final + : public UserDefinedLiteralExpression { +public: + StringUserDefinedLiteralExpression() + : UserDefinedLiteralExpression( + NodeKind::StringUserDefinedLiteralExpression) {} + static bool classof(const Node *N) { + return N->kind() == NodeKind::StringUserDefinedLiteralExpression; + } +}; + +/// An abstract class for prefix and postfix unary operators. +class UnaryOperatorExpression : public Expression { +public: + UnaryOperatorExpression(NodeKind K) : Expression(K) {} + static bool classof(const Node *N) { + return N->kind() == NodeKind::PrefixUnaryOperatorExpression || + N->kind() == NodeKind::PostfixUnaryOperatorExpression; + } + syntax::Leaf *operatorToken(); + syntax::Expression *operand(); +}; + +/// <operator> <operand> +/// +/// For example: +/// +a -b +/// !c not c +/// ~d compl d +/// *e &f +/// ++h --h +/// __real i __imag i +class PrefixUnaryOperatorExpression final : public UnaryOperatorExpression { +public: + PrefixUnaryOperatorExpression() + : UnaryOperatorExpression(NodeKind::PrefixUnaryOperatorExpression) {} + static bool classof(const Node *N) { + return N->kind() == NodeKind::PrefixUnaryOperatorExpression; + } +}; + +/// <operand> <operator> +/// +/// For example: +/// a++ +/// b-- +class PostfixUnaryOperatorExpression final : public UnaryOperatorExpression { +public: + PostfixUnaryOperatorExpression() + : UnaryOperatorExpression(NodeKind::PostfixUnaryOperatorExpression) {} + static bool classof(const Node *N) { + return N->kind() == NodeKind::PostfixUnaryOperatorExpression; + } +}; + +/// <lhs> <operator> <rhs> +/// +/// For example: +/// a + b +/// a bitor 1 +/// a |= b +/// a and_eq b +class BinaryOperatorExpression final : public Expression { +public: + BinaryOperatorExpression() : Expression(NodeKind::BinaryOperatorExpression) {} + static bool classof(const Node *N) { + return N->kind() == NodeKind::BinaryOperatorExpression; + } + syntax::Expression *lhs(); + syntax::Leaf *operatorToken(); + syntax::Expression *rhs(); +}; + /// An abstract node for C++ statements, e.g. 'while', 'if', etc. /// FIXME: add accessors for semicolon of statements that have it. class Statement : public Tree { @@ -375,6 +696,36 @@ public: static bool classof(const Node *N) { return N->kind() == NodeKind::SimpleDeclaration; } + /// FIXME: use custom iterator instead of 'vector'. + std::vector<syntax::SimpleDeclarator *> declarators(); +}; + +/// template <template-parameters> <declaration> +class TemplateDeclaration final : public Declaration { +public: + TemplateDeclaration() : Declaration(NodeKind::TemplateDeclaration) {} + static bool classof(const Node *N) { + return N->kind() == NodeKind::TemplateDeclaration; + } + syntax::Leaf *templateKeyword(); + syntax::Declaration *declaration(); +}; + +/// template <declaration> +/// Examples: +/// template struct X<int> +/// template void foo<int>() +/// template int var<double> +class ExplicitTemplateInstantiation final : public Declaration { +public: + ExplicitTemplateInstantiation() + : Declaration(NodeKind::ExplicitTemplateInstantiation) {} + static bool classof(const Node *N) { + return N->kind() == NodeKind::ExplicitTemplateInstantiation; + } + syntax::Leaf *templateKeyword(); + syntax::Leaf *externKeyword(); + syntax::Declaration *declaration(); }; /// namespace <name> { <decls> } @@ -424,6 +775,113 @@ public: } }; +/// Covers a name, an initializer and a part of the type outside declaration +/// specifiers. Examples are: +/// `*a` in `int *a` +/// `a[10]` in `int a[10]` +/// `*a = nullptr` in `int *a = nullptr` +/// Declarators can be unnamed too: +/// `**` in `new int**` +/// `* = nullptr` in `void foo(int* = nullptr)` +/// Most declarators you encounter are instances of SimpleDeclarator. They may +/// contain an inner declarator inside parentheses, we represent it as +/// ParenDeclarator. E.g. +/// `(*a)` in `int (*a) = 10` +class Declarator : public Tree { +public: + Declarator(NodeKind K) : Tree(K) {} + static bool classof(const Node *N) { + return NodeKind::SimpleDeclarator <= N->kind() && + N->kind() <= NodeKind::ParenDeclarator; + } +}; + +/// A top-level declarator without parentheses. See comment of Declarator for +/// more details. +class SimpleDeclarator final : public Declarator { +public: + SimpleDeclarator() : Declarator(NodeKind::SimpleDeclarator) {} + static bool classof(const Node *N) { + return N->kind() == NodeKind::SimpleDeclarator; + } +}; + +/// Declarator inside parentheses. +/// E.g. `(***a)` from `int (***a) = nullptr;` +/// See comment of Declarator for more details. +class ParenDeclarator final : public Declarator { +public: + ParenDeclarator() : Declarator(NodeKind::ParenDeclarator) {} + static bool classof(const Node *N) { + return N->kind() == NodeKind::ParenDeclarator; + } + syntax::Leaf *lparen(); + syntax::Leaf *rparen(); +}; + +/// Array size specified inside a declarator. +/// E.g: +/// `[10]` in `int a[10];` +/// `[static 10]` in `void f(int xs[static 10]);` +class ArraySubscript final : public Tree { +public: + ArraySubscript() : Tree(NodeKind::ArraySubscript) {} + static bool classof(const Node *N) { + return N->kind() == NodeKind::ArraySubscript; + } + // TODO: add an accessor for the "static" keyword. + syntax::Leaf *lbracket(); + syntax::Expression *sizeExpression(); + syntax::Leaf *rbracket(); +}; + +/// Trailing return type after the parameter list, including the arrow token. +/// E.g. `-> int***`. +class TrailingReturnType final : public Tree { +public: + TrailingReturnType() : Tree(NodeKind::TrailingReturnType) {} + static bool classof(const Node *N) { + return N->kind() == NodeKind::TrailingReturnType; + } + // TODO: add accessors for specifiers. + syntax::Leaf *arrowToken(); + syntax::SimpleDeclarator *declarator(); +}; + +/// Parameter list for a function type and a trailing return type, if the +/// function has one. +/// E.g.: +/// `(int a) volatile ` in `int foo(int a) volatile;` +/// `(int a) &&` in `int foo(int a) &&;` +/// `() -> int` in `auto foo() -> int;` +/// `() const` in `int foo() const;` +/// `() noexcept` in `int foo() noexcept;` +/// `() throw()` in `int foo() throw();` +/// +/// (!) override doesn't belong here. +class ParametersAndQualifiers final : public Tree { +public: + ParametersAndQualifiers() : Tree(NodeKind::ParametersAndQualifiers) {} + static bool classof(const Node *N) { + return N->kind() == NodeKind::ParametersAndQualifiers; + } + syntax::Leaf *lparen(); + /// FIXME: use custom iterator instead of 'vector'. + std::vector<syntax::SimpleDeclaration *> parameters(); + syntax::Leaf *rparen(); + syntax::TrailingReturnType *trailingReturn(); +}; + +/// Member pointer inside a declarator +/// E.g. `X::*` in `int X::* a = 0;` +class MemberPointer final : public Tree { +public: + MemberPointer() : Tree(NodeKind::MemberPointer) {} + static bool classof(const Node *N) { + return N->kind() == NodeKind::MemberPointer; + } +}; + } // namespace syntax } // namespace clang #endif diff --git a/clang/include/clang/Tooling/Syntax/Tokens.h b/clang/include/clang/Tooling/Syntax/Tokens.h index a210815d49f9..a7f9369ddfff 100644 --- a/clang/include/clang/Tooling/Syntax/Tokens.h +++ b/clang/include/clang/Tooling/Syntax/Tokens.h @@ -171,11 +171,16 @@ llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const Token &T); /// To build a token buffer use the TokenCollector class. You can also compute /// the spelled tokens of a file using the tokenize() helper. /// -/// FIXME: allow to map from spelled to expanded tokens when use-case shows up. /// FIXME: allow mappings into macro arguments. class TokenBuffer { public: TokenBuffer(const SourceManager &SourceMgr) : SourceMgr(&SourceMgr) {} + + TokenBuffer(TokenBuffer &&) = default; + TokenBuffer(const TokenBuffer &) = delete; + TokenBuffer &operator=(TokenBuffer &&) = default; + TokenBuffer &operator=(const TokenBuffer &) = delete; + /// All tokens produced by the preprocessor after all macro replacements, /// directives, etc. Source locations found in the clang AST will always /// point to one of these tokens. @@ -191,18 +196,20 @@ public: /// token range R. llvm::ArrayRef<syntax::Token> expandedTokens(SourceRange R) const; - /// Find the subrange of spelled tokens that produced the corresponding \p - /// Expanded tokens. + /// Returns the subrange of spelled tokens corresponding to AST node spanning + /// \p Expanded. This is the text that should be replaced if a refactoring + /// were to rewrite the node. If \p Expanded is empty, the returned value is + /// llvm::None. /// - /// EXPECTS: \p Expanded is a subrange of expandedTokens(). - /// - /// Will fail if the expanded tokens do not correspond to a - /// sequence of spelled tokens. E.g. for the following example: + /// Will fail if the expanded tokens do not correspond to a sequence of + /// spelled tokens. E.g. for the following example: /// /// #define FIRST f1 f2 f3 /// #define SECOND s1 s2 s3 + /// #define ID2(X, Y) X Y /// /// a FIRST b SECOND c // expanded tokens are: a f1 f2 f3 b s1 s2 s3 c + /// d ID2(e f g, h) i // expanded tokens are: d e f g h i /// /// the results would be: /// expanded => spelled @@ -212,12 +219,44 @@ public: /// a f1 f2 f3 => a FIRST /// a f1 => can't map /// s1 s2 => can't map + /// e f => e f + /// g h => can't map /// - /// If \p Expanded is empty, the returned value is llvm::None. + /// EXPECTS: \p Expanded is a subrange of expandedTokens(). /// Complexity is logarithmic. llvm::Optional<llvm::ArrayRef<syntax::Token>> spelledForExpanded(llvm::ArrayRef<syntax::Token> Expanded) const; + /// Find the subranges of expanded tokens, corresponding to \p Spelled. + /// + /// Some spelled tokens may not be present in the expanded token stream, so + /// this function can return an empty vector, e.g. for tokens of macro + /// directives or disabled preprocessor branches. + /// + /// Some spelled tokens can be duplicated in the expanded token stream + /// multiple times and this function will return multiple results in those + /// cases. This happens when \p Spelled is inside a macro argument. + /// + /// FIXME: return correct results on macro arguments. For now, we return an + /// empty list. + /// + /// (!) will return empty vector on tokens from #define body: + /// E.g. for the following example: + /// + /// #define FIRST(A) f1 A = A f2 + /// #define SECOND s + /// + /// a FIRST(arg) b SECOND c // expanded tokens are: a f1 arg = arg f2 b s + /// The results would be + /// spelled => expanded + /// ------------------------ + /// #define FIRST => {} + /// a FIRST(arg) => {a f1 arg = arg f2} + /// arg => {arg, arg} // arg #1 is before `=` and arg #2 is + /// // after `=` in the expanded tokens. + llvm::SmallVector<llvm::ArrayRef<syntax::Token>, 1> + expandedForSpelled(llvm::ArrayRef<syntax::Token> Spelled) const; + /// An expansion produced by the preprocessor, includes macro expansions and /// preprocessor directives. Preprocessor always maps a non-empty range of /// spelled tokens to a (possibly empty) range of expanded tokens. Here is a @@ -245,6 +284,10 @@ public: /// "DECL", "(", "a", ")", ";"} llvm::ArrayRef<syntax::Token> spelledTokens(FileID FID) const; + /// Returns the spelled Token starting at Loc, if there are no such tokens + /// returns nullptr. + const syntax::Token *spelledTokenAt(SourceLocation Loc) const; + /// Get all tokens that expand a macro in \p FID. For the following input /// #define FOO B /// #define FOO2(X) int X @@ -303,6 +346,12 @@ private: std::pair<const syntax::Token *, const Mapping *> spelledForExpandedToken(const syntax::Token *Expanded) const; + /// Returns a mapping starting before \p Spelled token, or nullptr if no + /// such mapping exists. + static const Mapping * + mappingStartingBeforeSpelled(const MarkedFile &F, + const syntax::Token *Spelled); + /// Token stream produced after preprocessing, conceputally this captures the /// same stream as 'clang -E' (excluding the preprocessor directives like /// #file, etc.). @@ -317,11 +366,16 @@ private: /// This always returns 0-2 tokens. llvm::ArrayRef<syntax::Token> spelledTokensTouching(SourceLocation Loc, const syntax::TokenBuffer &Tokens); +llvm::ArrayRef<syntax::Token> +spelledTokensTouching(SourceLocation Loc, llvm::ArrayRef<syntax::Token> Tokens); /// The identifier token that overlaps or touches a spelling location Loc. /// If there is none, returns nullptr. const syntax::Token * spelledIdentifierTouching(SourceLocation Loc, + llvm::ArrayRef<syntax::Token> Tokens); +const syntax::Token * +spelledIdentifierTouching(SourceLocation Loc, const syntax::TokenBuffer &Tokens); /// Lex the text buffer, corresponding to \p FID, in raw mode and record the @@ -334,6 +388,12 @@ spelledIdentifierTouching(SourceLocation Loc, /// The result will *not* have a 'eof' token at the end. std::vector<syntax::Token> tokenize(FileID FID, const SourceManager &SM, const LangOptions &LO); +/// Similar to one above, instead of whole file tokenizes a part of it. Note +/// that, the first token might be incomplete if FR.startOffset is not at the +/// beginning of a token, and the last token returned will start before the +/// FR.endOffset but might end after it. +std::vector<syntax::Token> +tokenize(const FileRange &FR, const SourceManager &SM, const LangOptions &LO); /// Collects tokens for the main file while running the frontend action. An /// instance of this object should be created on diff --git a/clang/include/clang/Tooling/Syntax/Tree.h b/clang/include/clang/Tooling/Syntax/Tree.h index 8702fe60ce1b..bc581004c46e 100644 --- a/clang/include/clang/Tooling/Syntax/Tree.h +++ b/clang/include/clang/Tooling/Syntax/Tree.h @@ -126,6 +126,8 @@ private: // FactoryImpl sets CanModify flag. friend class FactoryImpl; + void setRole(NodeRole NR); + Tree *Parent; Node *NextSibling; unsigned Kind : 16; @@ -171,8 +173,11 @@ private: /// Prepend \p Child to the list of children and and sets the parent pointer. /// A very low-level operation that does not check any invariants, only used /// by TreeBuilder and FactoryImpl. - /// EXPECTS: Role != NodeRoleDetached. + /// EXPECTS: Role != Detached. void prependChildLowLevel(Node *Child, NodeRole Role); + /// Like the previous overload, but does not set role for \p Child. + /// EXPECTS: Child->Role != Detached + void prependChildLowLevel(Node *Child); friend class TreeBuilder; friend class FactoryImpl; diff --git a/clang/include/clang/Tooling/Tooling.h b/clang/include/clang/Tooling/Tooling.h index f759789170d9..4fb0c18be95e 100644 --- a/clang/include/clang/Tooling/Tooling.h +++ b/clang/include/clang/Tooling/Tooling.h @@ -225,7 +225,8 @@ std::unique_ptr<ASTUnit> buildASTFromCodeWithArgs( std::shared_ptr<PCHContainerOperations> PCHContainerOps = std::make_shared<PCHContainerOperations>(), ArgumentsAdjuster Adjuster = getClangStripDependencyFileAdjuster(), - const FileContentMappings &VirtualMappedFiles = FileContentMappings()); + const FileContentMappings &VirtualMappedFiles = FileContentMappings(), + DiagnosticConsumer *DiagConsumer = nullptr); /// Utility to run a FrontendAction in a single clang invocation. class ToolInvocation { @@ -504,7 +505,8 @@ void addTargetAndModeForProgramName(std::vector<std::string> &CommandLine, /// Creates a \c CompilerInvocation. CompilerInvocation *newInvocation(DiagnosticsEngine *Diagnostics, - const llvm::opt::ArgStringList &CC1Args); + const llvm::opt::ArgStringList &CC1Args, + const char *const BinaryName); } // namespace tooling diff --git a/clang/include/clang/Tooling/Transformer/Parsing.h b/clang/include/clang/Tooling/Transformer/Parsing.h new file mode 100644 index 000000000000..8e51f595cd5b --- /dev/null +++ b/clang/include/clang/Tooling/Transformer/Parsing.h @@ -0,0 +1,41 @@ +//===--- Parsing.h - Parsing library for Transformer ------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// Defines parsing functions for Transformer types. +/// FIXME: Currently, only supports `RangeSelectors` but parsers for other +/// Transformer types are under development. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLING_REFACTOR_PARSING_H_ +#define LLVM_CLANG_TOOLING_REFACTOR_PARSING_H_ + +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Basic/SourceLocation.h" +#include "clang/Tooling/Transformer/RangeSelector.h" +#include "llvm/Support/Error.h" +#include <functional> +#include <string> + +namespace clang { +namespace transformer { + +/// Parses a string representation of a \c RangeSelector. The grammar of these +/// strings is closely based on the (sub)grammar of \c RangeSelectors as they'd +/// appear in C++ code. However, this language constrains the set of permissible +/// strings (for node ids) -- it does not support escapes in the +/// string. Additionally, the \c charRange combinator is not supported, because +/// there is no representation of values of type \c CharSourceRange in this +/// (little) language. +llvm::Expected<RangeSelector> parseRangeSelector(llvm::StringRef Input); + +} // namespace transformer +} // namespace clang + +#endif // LLVM_CLANG_TOOLING_REFACTOR_PARSING_H_ diff --git a/clang/include/clang/Tooling/Transformer/RangeSelector.h b/clang/include/clang/Tooling/Transformer/RangeSelector.h index 9f556d206321..2807037bc208 100644 --- a/clang/include/clang/Tooling/Transformer/RangeSelector.h +++ b/clang/include/clang/Tooling/Transformer/RangeSelector.h @@ -32,10 +32,20 @@ inline RangeSelector charRange(CharSourceRange R) { } /// Selects from the start of \p Begin and to the end of \p End. -RangeSelector range(RangeSelector Begin, RangeSelector End); +RangeSelector enclose(RangeSelector Begin, RangeSelector End); /// Convenience version of \c range where end-points are bound nodes. -RangeSelector range(std::string BeginID, std::string EndID); +RangeSelector encloseNodes(std::string BeginID, std::string EndID); + +/// DEPRECATED. Use `enclose`. +inline RangeSelector range(RangeSelector Begin, RangeSelector End) { + return enclose(std::move(Begin), std::move(End)); +} + +/// DEPRECATED. Use `encloseNodes`. +inline RangeSelector range(std::string BeginID, std::string EndID) { + return encloseNodes(std::move(BeginID), std::move(EndID)); +} /// Selects the (empty) range [B,B) when \p Selector selects the range [B,E). RangeSelector before(RangeSelector Selector); @@ -43,7 +53,7 @@ RangeSelector before(RangeSelector Selector); /// Selects the the point immediately following \p Selector. That is, the /// (empty) range [E,E), when \p Selector selects either /// * the CharRange [B,E) or -/// * the TokenRange [B,E'] where the token at E' spans the range [E,E'). +/// * the TokenRange [B,E'] where the token at E' spans the range [E',E). RangeSelector after(RangeSelector Selector); /// Selects a node, including trailing semicolon (for non-expression diff --git a/clang/include/clang/Tooling/Transformer/RewriteRule.h b/clang/include/clang/Tooling/Transformer/RewriteRule.h index 7daf6ea154be..d9e68717d5c8 100644 --- a/clang/include/clang/Tooling/Transformer/RewriteRule.h +++ b/clang/include/clang/Tooling/Transformer/RewriteRule.h @@ -21,6 +21,7 @@ #include "clang/Tooling/Refactoring/AtomicChange.h" #include "clang/Tooling/Transformer/MatchConsumer.h" #include "clang/Tooling/Transformer/RangeSelector.h" +#include "llvm/ADT/Any.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Support/Error.h" @@ -30,6 +31,20 @@ namespace clang { namespace transformer { +/// A concrete description of a source edit, represented by a character range in +/// the source to be replaced and a corresponding replacement string. +struct Edit { + CharSourceRange Range; + std::string Replacement; + llvm::Any Metadata; +}; + +/// Maps a match result to a list of concrete edits (with possible +/// failure). This type is a building block of rewrite rules, but users will +/// generally work in terms of `ASTEdit`s (below) rather than directly in terms +/// of `EditGenerator`. +using EditGenerator = MatchConsumer<llvm::SmallVector<Edit, 1>>; + using TextGenerator = std::shared_ptr<MatchComputation<std::string>>; // Description of a source-code edit, expressed in terms of an AST node. @@ -72,8 +87,22 @@ struct ASTEdit { RangeSelector TargetRange; TextGenerator Replacement; TextGenerator Note; + llvm::Any Metadata; }; +/// Lifts a list of `ASTEdit`s into an `EditGenerator`. +/// +/// The `EditGenerator` will return an empty vector if any of the edits apply to +/// portions of the source that are ineligible for rewriting (certain +/// interactions with macros, for example) and it will fail if any invariants +/// are violated relating to bound nodes in the match. However, it does not +/// fail in the case of conflicting edits -- conflict handling is left to +/// clients. We recommend use of the \c AtomicChange or \c Replacements classes +/// for assistance in detecting such conflicts. +EditGenerator editList(llvm::SmallVector<ASTEdit, 1> Edits); +// Convenience form of `editList` for a single edit. +EditGenerator edit(ASTEdit); + /// Format of the path in an include directive -- angle brackets or quotes. enum class IncludeFormat { Quoted, @@ -106,7 +135,7 @@ enum class IncludeFormat { struct RewriteRule { struct Case { ast_matchers::internal::DynTypedMatcher Matcher; - SmallVector<ASTEdit, 1> Edits; + EditGenerator Edits; TextGenerator Explanation; // Include paths to add to the file affected by this case. These are // bundled with the `Case`, rather than the `RewriteRule`, because each case @@ -123,16 +152,22 @@ struct RewriteRule { /// Convenience function for constructing a simple \c RewriteRule. RewriteRule makeRule(ast_matchers::internal::DynTypedMatcher M, - SmallVector<ASTEdit, 1> Edits, - TextGenerator Explanation = nullptr); + EditGenerator Edits, TextGenerator Explanation = nullptr); + +/// Convenience function for constructing a \c RewriteRule from multiple +/// `ASTEdit`s. +inline RewriteRule makeRule(ast_matchers::internal::DynTypedMatcher M, + llvm::SmallVector<ASTEdit, 1> Edits, + TextGenerator Explanation = nullptr) { + return makeRule(std::move(M), editList(std::move(Edits)), + std::move(Explanation)); +} /// Convenience overload of \c makeRule for common case of only one edit. inline RewriteRule makeRule(ast_matchers::internal::DynTypedMatcher M, ASTEdit Edit, TextGenerator Explanation = nullptr) { - SmallVector<ASTEdit, 1> Edits; - Edits.emplace_back(std::move(Edit)); - return makeRule(std::move(M), std::move(Edits), std::move(Explanation)); + return makeRule(std::move(M), edit(std::move(Edit)), std::move(Explanation)); } /// For every case in Rule, adds an include directive for the given header. The @@ -203,7 +238,8 @@ inline ASTEdit change(RangeSelector Target, TextGenerator Replacement) { /// changeTo(cat("bar()"))) /// \endcode inline ASTEdit changeTo(TextGenerator Replacement) { - return changeTo(node(RewriteRule::RootID), std::move(Replacement)); + return changeTo(node(std::string(RewriteRule::RootID)), + std::move(Replacement)); } /// DEPRECATED: use \c changeTo. inline ASTEdit change(TextGenerator Replacement) { @@ -225,6 +261,11 @@ inline ASTEdit insertAfter(RangeSelector S, TextGenerator Replacement) { /// Removes the source selected by \p S. ASTEdit remove(RangeSelector S); +inline ASTEdit withMetadata(ASTEdit edit, llvm::Any Metadata) { + edit.Metadata = std::move(Metadata); + return edit; +} + /// The following three functions are a low-level part of the RewriteRule /// API. We expose them for use in implementing the fixtures that interpret /// RewriteRule, like Transformer and TransfomerTidy, or for more advanced @@ -240,11 +281,13 @@ namespace detail { /// supports mixing matchers of different kinds. ast_matchers::internal::DynTypedMatcher buildMatcher(const RewriteRule &Rule); -/// Builds a set of matchers that cover the rule (one for each distinct node -/// matcher base kind: Stmt, Decl, etc.). Node-matchers for `QualType` and -/// `Type` are not permitted, since such nodes carry no source location -/// information and are therefore not relevant for rewriting. If any such -/// matchers are included, will return an empty vector. +/// Builds a set of matchers that cover the rule. +/// +/// One matcher is built for each distinct node matcher base kind: Stmt, Decl, +/// etc. Node-matchers for `QualType` and `Type` are not permitted, since such +/// nodes carry no source location information and are therefore not relevant +/// for rewriting. If any such matchers are included, will return an empty +/// vector. std::vector<ast_matchers::internal::DynTypedMatcher> buildMatchers(const RewriteRule &Rule); @@ -259,28 +302,6 @@ getRuleMatchLoc(const ast_matchers::MatchFinder::MatchResult &Result); const RewriteRule::Case & findSelectedCase(const ast_matchers::MatchFinder::MatchResult &Result, const RewriteRule &Rule); - -/// A source "transformation," represented by a character range in the source to -/// be replaced and a corresponding replacement string. -struct Transformation { - CharSourceRange Range; - std::string Replacement; -}; - -/// Attempts to translate `Edits`, which are in terms of AST nodes bound in the -/// match `Result`, into Transformations, which are in terms of the source code -/// text. -/// -/// Returns an empty vector if any of the edits apply to portions of the source -/// that are ineligible for rewriting (certain interactions with macros, for -/// example). Fails if any invariants are violated relating to bound nodes in -/// the match. However, it does not fail in the case of conflicting edits -- -/// conflict handling is left to clients. We recommend use of the \c -/// AtomicChange or \c Replacements classes for assistance in detecting such -/// conflicts. -Expected<SmallVector<Transformation, 1>> -translateEdits(const ast_matchers::MatchFinder::MatchResult &Result, - llvm::ArrayRef<ASTEdit> Edits); } // namespace detail } // namespace transformer diff --git a/clang/include/clang/Tooling/Transformer/SourceCode.h b/clang/include/clang/Tooling/Transformer/SourceCode.h index bc9cc3d2a258..2c7eb65371cf 100644 --- a/clang/include/clang/Tooling/Transformer/SourceCode.h +++ b/clang/include/clang/Tooling/Transformer/SourceCode.h @@ -20,9 +20,10 @@ namespace clang { namespace tooling { -/// Extends \p Range to include the token \p Next, if it immediately follows the -/// end of the range. Otherwise, returns \p Range unchanged. -CharSourceRange maybeExtendRange(CharSourceRange Range, tok::TokenKind Next, +/// Extends \p Range to include the token \p Terminator, if it immediately +/// follows the end of the range. Otherwise, returns \p Range unchanged. +CharSourceRange maybeExtendRange(CharSourceRange Range, + tok::TokenKind Terminator, ASTContext &Context); /// Returns the source range spanning the node, extended to include \p Next, if @@ -35,6 +36,13 @@ CharSourceRange getExtendedRange(const T &Node, tok::TokenKind Next, Next, Context); } +/// Returns the logical source range of the node extended to include associated +/// comments and whitespace before and after the node, and associated +/// terminators. The returned range consists of file locations, if valid file +/// locations can be found for the associated content; otherwise, an invalid +/// range is returned. +CharSourceRange getAssociatedRange(const Decl &D, ASTContext &Context); + /// Returns the source-code text in the specified range. StringRef getText(CharSourceRange Range, const ASTContext &Context); @@ -73,13 +81,18 @@ StringRef getExtendedText(const T &Node, tok::TokenKind Next, return getText(getExtendedRange(Node, Next, Context), Context); } -// Attempts to resolve the given range to one that can be edited by a rewrite; -// generally, one that starts and ends within a particular file. It supports -// a limited set of cases involving source locations in macro expansions. +/// Determines whether \p Range is one that can be edited by a rewrite; +/// generally, one that starts and ends within a particular file. +llvm::Error validateEditRange(const CharSourceRange &Range, + const SourceManager &SM); + +/// Attempts to resolve the given range to one that can be edited by a rewrite; +/// generally, one that starts and ends within a particular file. It supports a +/// limited set of cases involving source locations in macro expansions. If a +/// value is returned, it satisfies \c validateEditRange. llvm::Optional<CharSourceRange> getRangeForEdit(const CharSourceRange &EditRange, const SourceManager &SM, const LangOptions &LangOpts); - inline llvm::Optional<CharSourceRange> getRangeForEdit(const CharSourceRange &EditRange, const ASTContext &Context) { return getRangeForEdit(EditRange, Context.getSourceManager(), diff --git a/clang/include/clang/Tooling/Transformer/Stencil.h b/clang/include/clang/Tooling/Transformer/Stencil.h index 0363b689dc5b..1b50a670f70b 100644 --- a/clang/include/clang/Tooling/Transformer/Stencil.h +++ b/clang/include/clang/Tooling/Transformer/Stencil.h @@ -69,14 +69,6 @@ template <typename... Ts> Stencil cat(Ts &&... Parts) { // Functions for conveniently building stencils. // -/// DEPRECATED: Use `cat` instead. -/// \returns exactly the text provided. -Stencil text(llvm::StringRef Text); - -/// DEPRECATED: Use `cat` instead. -/// \returns the source corresponding to the selected range. -Stencil selection(RangeSelector Selector); - /// Generates the source of the expression bound to \p Id, wrapping it in /// parentheses if it may parse differently depending on context. For example, a /// binary operation is always wrapped, while a variable reference is never @@ -112,7 +104,7 @@ Stencil maybeAddressOf(llvm::StringRef ExprId); /// Additionally, `e` is wrapped in parentheses, if needed. Stencil access(llvm::StringRef BaseId, Stencil Member); inline Stencil access(llvm::StringRef BaseId, llvm::StringRef Member) { - return access(BaseId, text(Member)); + return access(BaseId, detail::makeStencil(Member)); } /// Chooses between the two stencil parts, based on whether \p ID is bound in @@ -123,7 +115,8 @@ Stencil ifBound(llvm::StringRef Id, Stencil TrueStencil, Stencil FalseStencil); /// match. inline Stencil ifBound(llvm::StringRef Id, llvm::StringRef TrueText, llvm::StringRef FalseText) { - return ifBound(Id, text(TrueText), text(FalseText)); + return ifBound(Id, detail::makeStencil(TrueText), + detail::makeStencil(FalseText)); } /// Wraps a \c MatchConsumer in a \c Stencil, so that it can be used in a \c diff --git a/clang/include/clang/module.modulemap b/clang/include/clang/module.modulemap index b3e2108d3fa6..13d4dbf9dc2e 100644 --- a/clang/include/clang/module.modulemap +++ b/clang/include/clang/module.modulemap @@ -38,11 +38,14 @@ module Clang_Basic { textual header "Basic/BuiltinsBPF.def" textual header "Basic/Builtins.def" textual header "Basic/BuiltinsHexagon.def" + textual header "Basic/BuiltinsHexagonDep.def" + textual header "Basic/BuiltinsHexagonMapCustomDep.def" textual header "Basic/BuiltinsLe64.def" textual header "Basic/BuiltinsMips.def" textual header "Basic/BuiltinsNEON.def" textual header "Basic/BuiltinsNVPTX.def" textual header "Basic/BuiltinsPPC.def" + textual header "Basic/BuiltinsSVE.def" textual header "Basic/BuiltinsSystemZ.def" textual header "Basic/BuiltinsWebAssembly.def" textual header "Basic/BuiltinsX86.def" @@ -51,6 +54,7 @@ module Clang_Basic { textual header "Basic/CodeGenOptions.def" textual header "Basic/DiagnosticOptions.def" textual header "Basic/Features.def" + textual header "Basic/FPOptions.def" textual header "Basic/MSP430Target.def" textual header "Basic/LangOptions.def" textual header "Basic/OpenCLExtensions.def" @@ -149,6 +153,12 @@ module Clang_StaticAnalyzer_Frontend { module * { export * } } +module Clang_Testing { + requires cplusplus + umbrella "Testing" + module * { export * } +} + module Clang_Tooling { requires cplusplus umbrella "Tooling" module * { export * } // FIXME: Exclude these headers to avoid pulling all of the AST matchers |