10b57cec5SDimitry Andric //===--- Specifiers.h - Declaration and Type Specifiers ---------*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric ///
90b57cec5SDimitry Andric /// \file
100b57cec5SDimitry Andric /// Defines various enumerations that describe declaration and
110b57cec5SDimitry Andric /// type specifiers.
120b57cec5SDimitry Andric ///
130b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
140b57cec5SDimitry Andric 
150b57cec5SDimitry Andric #ifndef LLVM_CLANG_BASIC_SPECIFIERS_H
160b57cec5SDimitry Andric #define LLVM_CLANG_BASIC_SPECIFIERS_H
170b57cec5SDimitry Andric 
180b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h"
190b57cec5SDimitry Andric #include "llvm/Support/DataTypes.h"
200b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
210b57cec5SDimitry Andric 
2206c3fb27SDimitry Andric namespace llvm {
2306c3fb27SDimitry Andric class raw_ostream;
2406c3fb27SDimitry Andric } // namespace llvm
250b57cec5SDimitry Andric namespace clang {
260b57cec5SDimitry Andric 
270b57cec5SDimitry Andric   /// Define the meaning of possible values of the kind in ExplicitSpecifier.
280b57cec5SDimitry Andric   enum class ExplicitSpecKind : unsigned {
290b57cec5SDimitry Andric     ResolvedFalse,
300b57cec5SDimitry Andric     ResolvedTrue,
310b57cec5SDimitry Andric     Unresolved,
320b57cec5SDimitry Andric   };
330b57cec5SDimitry Andric 
340b57cec5SDimitry Andric   /// Define the kind of constexpr specifier.
35e8d8bef9SDimitry Andric   enum class ConstexprSpecKind { Unspecified, Constexpr, Consteval, Constinit };
360b57cec5SDimitry Andric 
37bdd1243dSDimitry Andric   /// In an if statement, this denotes whether the statement is
38349cc55cSDimitry Andric   /// a constexpr or consteval if statement.
39349cc55cSDimitry Andric   enum class IfStatementKind : unsigned {
40349cc55cSDimitry Andric     Ordinary,
41349cc55cSDimitry Andric     Constexpr,
42349cc55cSDimitry Andric     ConstevalNonNegated,
43349cc55cSDimitry Andric     ConstevalNegated
44349cc55cSDimitry Andric   };
45349cc55cSDimitry Andric 
460b57cec5SDimitry Andric   /// Specifies the width of a type, e.g., short, long, or long long.
47e8d8bef9SDimitry Andric   enum class TypeSpecifierWidth { Unspecified, Short, Long, LongLong };
480b57cec5SDimitry Andric 
490b57cec5SDimitry Andric   /// Specifies the signedness of a type, e.g., signed or unsigned.
50e8d8bef9SDimitry Andric   enum class TypeSpecifierSign { Unspecified, Signed, Unsigned };
510b57cec5SDimitry Andric 
52e8d8bef9SDimitry Andric   enum class TypeSpecifiersPipe { Unspecified, Pipe };
530b57cec5SDimitry Andric 
540b57cec5SDimitry Andric   /// Specifies the kind of type.
550b57cec5SDimitry Andric   enum TypeSpecifierType {
560b57cec5SDimitry Andric     TST_unspecified,
570b57cec5SDimitry Andric     TST_void,
580b57cec5SDimitry Andric     TST_char,
590b57cec5SDimitry Andric     TST_wchar,  // C++ wchar_t
600b57cec5SDimitry Andric     TST_char8,  // C++20 char8_t (proposed)
610b57cec5SDimitry Andric     TST_char16, // C++11 char16_t
620b57cec5SDimitry Andric     TST_char32, // C++11 char32_t
630b57cec5SDimitry Andric     TST_int,
640b57cec5SDimitry Andric     TST_int128,
650eae32dcSDimitry Andric     TST_bitint,  // Bit-precise integer types.
660b57cec5SDimitry Andric     TST_half,    // OpenCL half, ARM NEON __fp16
670b57cec5SDimitry Andric     TST_Float16, // C11 extension ISO/IEC TS 18661-3
680b57cec5SDimitry Andric     TST_Accum,   // ISO/IEC JTC1 SC22 WG14 N1169 Extension
690b57cec5SDimitry Andric     TST_Fract,
705ffd83dbSDimitry Andric     TST_BFloat16,
710b57cec5SDimitry Andric     TST_float,
720b57cec5SDimitry Andric     TST_double,
730b57cec5SDimitry Andric     TST_float128,
74349cc55cSDimitry Andric     TST_ibm128,
750b57cec5SDimitry Andric     TST_bool,       // _Bool
760b57cec5SDimitry Andric     TST_decimal32,  // _Decimal32
770b57cec5SDimitry Andric     TST_decimal64,  // _Decimal64
780b57cec5SDimitry Andric     TST_decimal128, // _Decimal128
790b57cec5SDimitry Andric     TST_enum,
800b57cec5SDimitry Andric     TST_union,
810b57cec5SDimitry Andric     TST_struct,
820b57cec5SDimitry Andric     TST_class,     // C++ class type
830b57cec5SDimitry Andric     TST_interface, // C++ (Microsoft-specific) __interface type
840b57cec5SDimitry Andric     TST_typename,  // Typedef, C++ class-name or enum name, etc.
855f757f3fSDimitry Andric     TST_typeofType,        // C23 (and GNU extension) typeof(type-name)
865f757f3fSDimitry Andric     TST_typeofExpr,        // C23 (and GNU extension) typeof(expression)
875f757f3fSDimitry Andric     TST_typeof_unqualType, // C23 typeof_unqual(type-name)
885f757f3fSDimitry Andric     TST_typeof_unqualExpr, // C23 typeof_unqual(expression)
890b57cec5SDimitry Andric     TST_decltype, // C++11 decltype
90bdd1243dSDimitry Andric #define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) TST_##Trait,
91bdd1243dSDimitry Andric #include "clang/Basic/TransformTypeTraits.def"
920b57cec5SDimitry Andric     TST_auto,            // C++11 auto
930b57cec5SDimitry Andric     TST_decltype_auto,   // C++1y decltype(auto)
940b57cec5SDimitry Andric     TST_auto_type,       // __auto_type extension
950b57cec5SDimitry Andric     TST_unknown_anytype, // __unknown_anytype extension
960b57cec5SDimitry Andric     TST_atomic,          // C11 _Atomic
970b57cec5SDimitry Andric #define GENERIC_IMAGE_TYPE(ImgType, Id) TST_##ImgType##_t, // OpenCL image types
980b57cec5SDimitry Andric #include "clang/Basic/OpenCLImageTypes.def"
990b57cec5SDimitry Andric     TST_error // erroneous type
1000b57cec5SDimitry Andric   };
1010b57cec5SDimitry Andric 
1020b57cec5SDimitry Andric   /// Structure that packs information about the type specifiers that
1030b57cec5SDimitry Andric   /// were written in a particular type specifier sequence.
1040b57cec5SDimitry Andric   struct WrittenBuiltinSpecs {
105bdd1243dSDimitry Andric     static_assert(TST_error < 1 << 7, "Type bitfield not wide enough for TST");
1065f757f3fSDimitry Andric     LLVM_PREFERRED_TYPE(TypeSpecifierType)
1075f757f3fSDimitry Andric     unsigned Type : 7;
1085f757f3fSDimitry Andric     LLVM_PREFERRED_TYPE(TypeSpecifierSign)
1095f757f3fSDimitry Andric     unsigned Sign : 2;
1105f757f3fSDimitry Andric     LLVM_PREFERRED_TYPE(TypeSpecifierWidth)
1115f757f3fSDimitry Andric     unsigned Width : 2;
1125f757f3fSDimitry Andric     LLVM_PREFERRED_TYPE(bool)
1130b57cec5SDimitry Andric     unsigned ModeAttr : 1;
1140b57cec5SDimitry Andric   };
1150b57cec5SDimitry Andric 
1160b57cec5SDimitry Andric   /// A C++ access specifier (public, private, protected), plus the
1170b57cec5SDimitry Andric   /// special value "none" which means different things in different contexts.
1180b57cec5SDimitry Andric   enum AccessSpecifier {
1190b57cec5SDimitry Andric     AS_public,
1200b57cec5SDimitry Andric     AS_protected,
1210b57cec5SDimitry Andric     AS_private,
1220b57cec5SDimitry Andric     AS_none
1230b57cec5SDimitry Andric   };
1240b57cec5SDimitry Andric 
1250b57cec5SDimitry Andric   /// The categorization of expression values, currently following the
1260b57cec5SDimitry Andric   /// C++11 scheme.
1270b57cec5SDimitry Andric   enum ExprValueKind {
128fe6060f1SDimitry Andric     /// A pr-value expression (in the C++11 taxonomy)
1290b57cec5SDimitry Andric     /// produces a temporary value.
130fe6060f1SDimitry Andric     VK_PRValue,
1310b57cec5SDimitry Andric 
1320b57cec5SDimitry Andric     /// An l-value expression is a reference to an object with
1330b57cec5SDimitry Andric     /// independent storage.
1340b57cec5SDimitry Andric     VK_LValue,
1350b57cec5SDimitry Andric 
1360b57cec5SDimitry Andric     /// An x-value expression is a reference to an object with
1370b57cec5SDimitry Andric     /// independent storage but which can be "moved", i.e.
1380b57cec5SDimitry Andric     /// efficiently cannibalized for its resources.
1390b57cec5SDimitry Andric     VK_XValue
1400b57cec5SDimitry Andric   };
1410b57cec5SDimitry Andric 
1420b57cec5SDimitry Andric   /// A further classification of the kind of object referenced by an
1430b57cec5SDimitry Andric   /// l-value or x-value.
1440b57cec5SDimitry Andric   enum ExprObjectKind {
1450b57cec5SDimitry Andric     /// An ordinary object is located at an address in memory.
1460b57cec5SDimitry Andric     OK_Ordinary,
1470b57cec5SDimitry Andric 
1480b57cec5SDimitry Andric     /// A bitfield object is a bitfield on a C or C++ record.
1490b57cec5SDimitry Andric     OK_BitField,
1500b57cec5SDimitry Andric 
1510b57cec5SDimitry Andric     /// A vector component is an element or range of elements on a vector.
1520b57cec5SDimitry Andric     OK_VectorComponent,
1530b57cec5SDimitry Andric 
1540b57cec5SDimitry Andric     /// An Objective-C property is a logical field of an Objective-C
1550b57cec5SDimitry Andric     /// object which is read and written via Objective-C method calls.
1560b57cec5SDimitry Andric     OK_ObjCProperty,
1570b57cec5SDimitry Andric 
1580b57cec5SDimitry Andric     /// An Objective-C array/dictionary subscripting which reads an
1590b57cec5SDimitry Andric     /// object or writes at the subscripted array/dictionary element via
1600b57cec5SDimitry Andric     /// Objective-C method calls.
1615ffd83dbSDimitry Andric     OK_ObjCSubscript,
1625ffd83dbSDimitry Andric 
1635ffd83dbSDimitry Andric     /// A matrix component is a single element of a matrix.
1645ffd83dbSDimitry Andric     OK_MatrixComponent
1650b57cec5SDimitry Andric   };
1660b57cec5SDimitry Andric 
1670b57cec5SDimitry Andric   /// The reason why a DeclRefExpr does not constitute an odr-use.
1680b57cec5SDimitry Andric   enum NonOdrUseReason {
1690b57cec5SDimitry Andric     /// This is an odr-use.
1700b57cec5SDimitry Andric     NOUR_None = 0,
1710b57cec5SDimitry Andric     /// This name appears in an unevaluated operand.
1720b57cec5SDimitry Andric     NOUR_Unevaluated,
1730b57cec5SDimitry Andric     /// This name appears as a potential result of an lvalue-to-rvalue
1740b57cec5SDimitry Andric     /// conversion that is a constant expression.
1750b57cec5SDimitry Andric     NOUR_Constant,
1760b57cec5SDimitry Andric     /// This name appears as a potential result of a discarded value
1770b57cec5SDimitry Andric     /// expression.
1780b57cec5SDimitry Andric     NOUR_Discarded,
1790b57cec5SDimitry Andric   };
1800b57cec5SDimitry Andric 
1810b57cec5SDimitry Andric   /// Describes the kind of template specialization that a
1820b57cec5SDimitry Andric   /// particular template specialization declaration represents.
1830b57cec5SDimitry Andric   enum TemplateSpecializationKind {
1840b57cec5SDimitry Andric     /// This template specialization was formed from a template-id but
1850b57cec5SDimitry Andric     /// has not yet been declared, defined, or instantiated.
1860b57cec5SDimitry Andric     TSK_Undeclared = 0,
1870b57cec5SDimitry Andric     /// This template specialization was implicitly instantiated from a
1880b57cec5SDimitry Andric     /// template. (C++ [temp.inst]).
1890b57cec5SDimitry Andric     TSK_ImplicitInstantiation,
1900b57cec5SDimitry Andric     /// This template specialization was declared or defined by an
1910b57cec5SDimitry Andric     /// explicit specialization (C++ [temp.expl.spec]) or partial
1920b57cec5SDimitry Andric     /// specialization (C++ [temp.class.spec]).
1930b57cec5SDimitry Andric     TSK_ExplicitSpecialization,
1940b57cec5SDimitry Andric     /// This template specialization was instantiated from a template
1950b57cec5SDimitry Andric     /// due to an explicit instantiation declaration request
1960b57cec5SDimitry Andric     /// (C++11 [temp.explicit]).
1970b57cec5SDimitry Andric     TSK_ExplicitInstantiationDeclaration,
1980b57cec5SDimitry Andric     /// This template specialization was instantiated from a template
1990b57cec5SDimitry Andric     /// due to an explicit instantiation definition request
2000b57cec5SDimitry Andric     /// (C++ [temp.explicit]).
2010b57cec5SDimitry Andric     TSK_ExplicitInstantiationDefinition
2020b57cec5SDimitry Andric   };
2030b57cec5SDimitry Andric 
2040b57cec5SDimitry Andric   /// Determine whether this template specialization kind refers
2050b57cec5SDimitry Andric   /// to an instantiation of an entity (as opposed to a non-template or
2060b57cec5SDimitry Andric   /// an explicit specialization).
isTemplateInstantiation(TemplateSpecializationKind Kind)2070b57cec5SDimitry Andric   inline bool isTemplateInstantiation(TemplateSpecializationKind Kind) {
2080b57cec5SDimitry Andric     return Kind != TSK_Undeclared && Kind != TSK_ExplicitSpecialization;
2090b57cec5SDimitry Andric   }
2100b57cec5SDimitry Andric 
2110b57cec5SDimitry Andric   /// True if this template specialization kind is an explicit
2120b57cec5SDimitry Andric   /// specialization, explicit instantiation declaration, or explicit
2130b57cec5SDimitry Andric   /// instantiation definition.
isTemplateExplicitInstantiationOrSpecialization(TemplateSpecializationKind Kind)2140b57cec5SDimitry Andric   inline bool isTemplateExplicitInstantiationOrSpecialization(
2150b57cec5SDimitry Andric       TemplateSpecializationKind Kind) {
2160b57cec5SDimitry Andric     switch (Kind) {
2170b57cec5SDimitry Andric     case TSK_ExplicitSpecialization:
2180b57cec5SDimitry Andric     case TSK_ExplicitInstantiationDeclaration:
2190b57cec5SDimitry Andric     case TSK_ExplicitInstantiationDefinition:
2200b57cec5SDimitry Andric       return true;
2210b57cec5SDimitry Andric 
2220b57cec5SDimitry Andric     case TSK_Undeclared:
2230b57cec5SDimitry Andric     case TSK_ImplicitInstantiation:
2240b57cec5SDimitry Andric       return false;
2250b57cec5SDimitry Andric     }
2260b57cec5SDimitry Andric     llvm_unreachable("bad template specialization kind");
2270b57cec5SDimitry Andric   }
2280b57cec5SDimitry Andric 
2290b57cec5SDimitry Andric   /// Thread storage-class-specifier.
2300b57cec5SDimitry Andric   enum ThreadStorageClassSpecifier {
2310b57cec5SDimitry Andric     TSCS_unspecified,
2320b57cec5SDimitry Andric     /// GNU __thread.
2330b57cec5SDimitry Andric     TSCS___thread,
2340b57cec5SDimitry Andric     /// C++11 thread_local. Implies 'static' at block scope, but not at
2350b57cec5SDimitry Andric     /// class scope.
2360b57cec5SDimitry Andric     TSCS_thread_local,
2370b57cec5SDimitry Andric     /// C11 _Thread_local. Must be combined with either 'static' or 'extern'
2380b57cec5SDimitry Andric     /// if used at block scope.
2390b57cec5SDimitry Andric     TSCS__Thread_local
2400b57cec5SDimitry Andric   };
2410b57cec5SDimitry Andric 
2420b57cec5SDimitry Andric   /// Storage classes.
2430b57cec5SDimitry Andric   enum StorageClass {
2440b57cec5SDimitry Andric     // These are legal on both functions and variables.
2450b57cec5SDimitry Andric     SC_None,
2460b57cec5SDimitry Andric     SC_Extern,
2470b57cec5SDimitry Andric     SC_Static,
2480b57cec5SDimitry Andric     SC_PrivateExtern,
2490b57cec5SDimitry Andric 
2500b57cec5SDimitry Andric     // These are only legal on variables.
2510b57cec5SDimitry Andric     SC_Auto,
2520b57cec5SDimitry Andric     SC_Register
2530b57cec5SDimitry Andric   };
2540b57cec5SDimitry Andric 
2550b57cec5SDimitry Andric   /// Checks whether the given storage class is legal for functions.
isLegalForFunction(StorageClass SC)2560b57cec5SDimitry Andric   inline bool isLegalForFunction(StorageClass SC) {
2570b57cec5SDimitry Andric     return SC <= SC_PrivateExtern;
2580b57cec5SDimitry Andric   }
2590b57cec5SDimitry Andric 
2600b57cec5SDimitry Andric   /// Checks whether the given storage class is legal for variables.
isLegalForVariable(StorageClass SC)2610b57cec5SDimitry Andric   inline bool isLegalForVariable(StorageClass SC) {
2620b57cec5SDimitry Andric     return true;
2630b57cec5SDimitry Andric   }
2640b57cec5SDimitry Andric 
2650b57cec5SDimitry Andric   /// In-class initialization styles for non-static data members.
2660b57cec5SDimitry Andric   enum InClassInitStyle {
2670b57cec5SDimitry Andric     ICIS_NoInit,   ///< No in-class initializer.
2680b57cec5SDimitry Andric     ICIS_CopyInit, ///< Copy initialization.
2690b57cec5SDimitry Andric     ICIS_ListInit  ///< Direct list-initialization.
2700b57cec5SDimitry Andric   };
2710b57cec5SDimitry Andric 
2720b57cec5SDimitry Andric   /// CallingConv - Specifies the calling convention that a function uses.
2730b57cec5SDimitry Andric   enum CallingConv {
2740b57cec5SDimitry Andric     CC_C,           // __attribute__((cdecl))
2750b57cec5SDimitry Andric     CC_X86StdCall,  // __attribute__((stdcall))
2760b57cec5SDimitry Andric     CC_X86FastCall, // __attribute__((fastcall))
2770b57cec5SDimitry Andric     CC_X86ThisCall, // __attribute__((thiscall))
2780b57cec5SDimitry Andric     CC_X86VectorCall, // __attribute__((vectorcall))
2790b57cec5SDimitry Andric     CC_X86Pascal,   // __attribute__((pascal))
2800b57cec5SDimitry Andric     CC_Win64,       // __attribute__((ms_abi))
2810b57cec5SDimitry Andric     CC_X86_64SysV,  // __attribute__((sysv_abi))
2820b57cec5SDimitry Andric     CC_X86RegCall, // __attribute__((regcall))
2830b57cec5SDimitry Andric     CC_AAPCS,       // __attribute__((pcs("aapcs")))
2840b57cec5SDimitry Andric     CC_AAPCS_VFP,   // __attribute__((pcs("aapcs-vfp")))
2850b57cec5SDimitry Andric     CC_IntelOclBicc, // __attribute__((intel_ocl_bicc))
2860b57cec5SDimitry Andric     CC_SpirFunction, // default for OpenCL functions on SPIR target
2870b57cec5SDimitry Andric     CC_OpenCLKernel, // inferred for OpenCL kernels
2880b57cec5SDimitry Andric     CC_Swift,        // __attribute__((swiftcall))
289fe6060f1SDimitry Andric     CC_SwiftAsync,        // __attribute__((swiftasynccall))
2900b57cec5SDimitry Andric     CC_PreserveMost, // __attribute__((preserve_most))
2910b57cec5SDimitry Andric     CC_PreserveAll,  // __attribute__((preserve_all))
2920b57cec5SDimitry Andric     CC_AArch64VectorCall, // __attribute__((aarch64_vector_pcs))
29381ad6265SDimitry Andric     CC_AArch64SVEPCS, // __attribute__((aarch64_sve_pcs))
29481ad6265SDimitry Andric     CC_AMDGPUKernelCall, // __attribute__((amdgpu_kernel))
2955f757f3fSDimitry Andric     CC_M68kRTD,       // __attribute__((m68k_rtd))
2960b57cec5SDimitry Andric   };
2970b57cec5SDimitry Andric 
2980b57cec5SDimitry Andric   /// Checks whether the given calling convention supports variadic
2990b57cec5SDimitry Andric   /// calls. Unprototyped calls also use the variadic call rules.
supportsVariadicCall(CallingConv CC)3000b57cec5SDimitry Andric   inline bool supportsVariadicCall(CallingConv CC) {
3010b57cec5SDimitry Andric     switch (CC) {
3020b57cec5SDimitry Andric     case CC_X86StdCall:
3030b57cec5SDimitry Andric     case CC_X86FastCall:
3040b57cec5SDimitry Andric     case CC_X86ThisCall:
3050b57cec5SDimitry Andric     case CC_X86RegCall:
3060b57cec5SDimitry Andric     case CC_X86Pascal:
3070b57cec5SDimitry Andric     case CC_X86VectorCall:
3080b57cec5SDimitry Andric     case CC_SpirFunction:
3090b57cec5SDimitry Andric     case CC_OpenCLKernel:
3100b57cec5SDimitry Andric     case CC_Swift:
311fe6060f1SDimitry Andric     case CC_SwiftAsync:
3125f757f3fSDimitry Andric     case CC_M68kRTD:
3130b57cec5SDimitry Andric       return false;
3140b57cec5SDimitry Andric     default:
3150b57cec5SDimitry Andric       return true;
3160b57cec5SDimitry Andric     }
3170b57cec5SDimitry Andric   }
3180b57cec5SDimitry Andric 
3190b57cec5SDimitry Andric   /// The storage duration for an object (per C++ [basic.stc]).
3200b57cec5SDimitry Andric   enum StorageDuration {
3210b57cec5SDimitry Andric     SD_FullExpression, ///< Full-expression storage duration (for temporaries).
3220b57cec5SDimitry Andric     SD_Automatic,      ///< Automatic storage duration (most local variables).
3230b57cec5SDimitry Andric     SD_Thread,         ///< Thread storage duration.
3240b57cec5SDimitry Andric     SD_Static,         ///< Static storage duration.
3250b57cec5SDimitry Andric     SD_Dynamic         ///< Dynamic storage duration.
3260b57cec5SDimitry Andric   };
3270b57cec5SDimitry Andric 
3280b57cec5SDimitry Andric   /// Describes the nullability of a particular type.
3290b57cec5SDimitry Andric   enum class NullabilityKind : uint8_t {
3300b57cec5SDimitry Andric     /// Values of this type can never be null.
3310b57cec5SDimitry Andric     NonNull = 0,
3320b57cec5SDimitry Andric     /// Values of this type can be null.
3330b57cec5SDimitry Andric     Nullable,
3340b57cec5SDimitry Andric     /// Whether values of this type can be null is (explicitly)
3350b57cec5SDimitry Andric     /// unspecified. This captures a (fairly rare) case where we
3360b57cec5SDimitry Andric     /// can't conclude anything about the nullability of the type even
3370b57cec5SDimitry Andric     /// though it has been considered.
338e8d8bef9SDimitry Andric     Unspecified,
339e8d8bef9SDimitry Andric     // Generally behaves like Nullable, except when used in a block parameter
340e8d8bef9SDimitry Andric     // that was imported into a swift async method. There, swift will assume
34181ad6265SDimitry Andric     // that the parameter can get null even if no error occurred. _Nullable
342e8d8bef9SDimitry Andric     // parameters are assumed to only get null on error.
343e8d8bef9SDimitry Andric     NullableResult,
3440b57cec5SDimitry Andric   };
34506c3fb27SDimitry Andric   /// Prints human-readable debug representation.
34606c3fb27SDimitry Andric   llvm::raw_ostream &operator<<(llvm::raw_ostream&, NullabilityKind);
3470b57cec5SDimitry Andric 
3480b57cec5SDimitry Andric   /// Return true if \p L has a weaker nullability annotation than \p R. The
3490b57cec5SDimitry Andric   /// ordering is: Unspecified < Nullable < NonNull.
hasWeakerNullability(NullabilityKind L,NullabilityKind R)3500b57cec5SDimitry Andric   inline bool hasWeakerNullability(NullabilityKind L, NullabilityKind R) {
3510b57cec5SDimitry Andric     return uint8_t(L) > uint8_t(R);
3520b57cec5SDimitry Andric   }
3530b57cec5SDimitry Andric 
3540b57cec5SDimitry Andric   /// Retrieve the spelling of the given nullability kind.
3550b57cec5SDimitry Andric   llvm::StringRef getNullabilitySpelling(NullabilityKind kind,
3560b57cec5SDimitry Andric                                          bool isContextSensitive = false);
3570b57cec5SDimitry Andric 
3580b57cec5SDimitry Andric   /// Kinds of parameter ABI.
3590b57cec5SDimitry Andric   enum class ParameterABI {
3600b57cec5SDimitry Andric     /// This parameter uses ordinary ABI rules for its type.
3610b57cec5SDimitry Andric     Ordinary,
3620b57cec5SDimitry Andric 
3630b57cec5SDimitry Andric     /// This parameter (which must have pointer type) is a Swift
3640b57cec5SDimitry Andric     /// indirect result parameter.
3650b57cec5SDimitry Andric     SwiftIndirectResult,
3660b57cec5SDimitry Andric 
3670b57cec5SDimitry Andric     /// This parameter (which must have pointer-to-pointer type) uses
3680b57cec5SDimitry Andric     /// the special Swift error-result ABI treatment.  There can be at
3690b57cec5SDimitry Andric     /// most one parameter on a given function that uses this treatment.
3700b57cec5SDimitry Andric     SwiftErrorResult,
3710b57cec5SDimitry Andric 
3720b57cec5SDimitry Andric     /// This parameter (which must have pointer type) uses the special
3730b57cec5SDimitry Andric     /// Swift context-pointer ABI treatment.  There can be at
3740b57cec5SDimitry Andric     /// most one parameter on a given function that uses this treatment.
375fe6060f1SDimitry Andric     SwiftContext,
376fe6060f1SDimitry Andric 
377fe6060f1SDimitry Andric     /// This parameter (which must have pointer type) uses the special
378fe6060f1SDimitry Andric     /// Swift asynchronous context-pointer ABI treatment.  There can be at
379fe6060f1SDimitry Andric     /// most one parameter on a given function that uses this treatment.
380fe6060f1SDimitry Andric     SwiftAsyncContext,
3810b57cec5SDimitry Andric   };
3820b57cec5SDimitry Andric 
383480093f4SDimitry Andric   /// Assigned inheritance model for a class in the MS C++ ABI. Must match order
384480093f4SDimitry Andric   /// of spellings in MSInheritanceAttr.
385480093f4SDimitry Andric   enum class MSInheritanceModel {
386480093f4SDimitry Andric     Single = 0,
387480093f4SDimitry Andric     Multiple = 1,
388480093f4SDimitry Andric     Virtual = 2,
389480093f4SDimitry Andric     Unspecified = 3,
390480093f4SDimitry Andric   };
391480093f4SDimitry Andric 
3920b57cec5SDimitry Andric   llvm::StringRef getParameterABISpelling(ParameterABI kind);
3935ffd83dbSDimitry Andric 
getAccessSpelling(AccessSpecifier AS)3945ffd83dbSDimitry Andric   inline llvm::StringRef getAccessSpelling(AccessSpecifier AS) {
3955ffd83dbSDimitry Andric     switch (AS) {
3965ffd83dbSDimitry Andric     case AccessSpecifier::AS_public:
3975ffd83dbSDimitry Andric       return "public";
3985ffd83dbSDimitry Andric     case AccessSpecifier::AS_protected:
3995ffd83dbSDimitry Andric       return "protected";
4005ffd83dbSDimitry Andric     case AccessSpecifier::AS_private:
4015ffd83dbSDimitry Andric       return "private";
4025ffd83dbSDimitry Andric     case AccessSpecifier::AS_none:
4035ffd83dbSDimitry Andric       return {};
4045ffd83dbSDimitry Andric     }
4055ffd83dbSDimitry Andric     llvm_unreachable("Unknown AccessSpecifier");
4065ffd83dbSDimitry Andric   }
4070b57cec5SDimitry Andric } // end namespace clang
4080b57cec5SDimitry Andric 
4090b57cec5SDimitry Andric #endif // LLVM_CLANG_BASIC_SPECIFIERS_H
410