Home | History | Annotate | Line # | Download | only in Basic
      1 //===--- Specifiers.h - Declaration and Type Specifiers ---------*- C++ -*-===//
      2 //
      3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
      4 // See https://llvm.org/LICENSE.txt for license information.
      5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
      6 //
      7 //===----------------------------------------------------------------------===//
      8 ///
      9 /// \file
     10 /// Defines various enumerations that describe declaration and
     11 /// type specifiers.
     12 ///
     13 //===----------------------------------------------------------------------===//
     14 
     15 #ifndef LLVM_CLANG_BASIC_SPECIFIERS_H
     16 #define LLVM_CLANG_BASIC_SPECIFIERS_H
     17 
     18 #include "llvm/ADT/StringRef.h"
     19 #include "llvm/Support/DataTypes.h"
     20 #include "llvm/Support/ErrorHandling.h"
     21 
     22 namespace clang {
     23 
     24   /// Define the meaning of possible values of the kind in ExplicitSpecifier.
     25   enum class ExplicitSpecKind : unsigned {
     26     ResolvedFalse,
     27     ResolvedTrue,
     28     Unresolved,
     29   };
     30 
     31   /// Define the kind of constexpr specifier.
     32   enum class ConstexprSpecKind { Unspecified, Constexpr, Consteval, Constinit };
     33 
     34   /// Specifies the width of a type, e.g., short, long, or long long.
     35   enum class TypeSpecifierWidth { Unspecified, Short, Long, LongLong };
     36 
     37   /// Specifies the signedness of a type, e.g., signed or unsigned.
     38   enum class TypeSpecifierSign { Unspecified, Signed, Unsigned };
     39 
     40   enum class TypeSpecifiersPipe { Unspecified, Pipe };
     41 
     42   /// Specifies the kind of type.
     43   enum TypeSpecifierType {
     44     TST_unspecified,
     45     TST_void,
     46     TST_char,
     47     TST_wchar,        // C++ wchar_t
     48     TST_char8,        // C++20 char8_t (proposed)
     49     TST_char16,       // C++11 char16_t
     50     TST_char32,       // C++11 char32_t
     51     TST_int,
     52     TST_int128,
     53     TST_extint,       // Extended Int types.
     54     TST_half,         // OpenCL half, ARM NEON __fp16
     55     TST_Float16,      // C11 extension ISO/IEC TS 18661-3
     56     TST_Accum,        // ISO/IEC JTC1 SC22 WG14 N1169 Extension
     57     TST_Fract,
     58     TST_BFloat16,
     59     TST_float,
     60     TST_double,
     61     TST_float128,
     62     TST_bool,         // _Bool
     63     TST_decimal32,    // _Decimal32
     64     TST_decimal64,    // _Decimal64
     65     TST_decimal128,   // _Decimal128
     66     TST_enum,
     67     TST_union,
     68     TST_struct,
     69     TST_class,        // C++ class type
     70     TST_interface,    // C++ (Microsoft-specific) __interface type
     71     TST_typename,     // Typedef, C++ class-name or enum name, etc.
     72     TST_typeofType,
     73     TST_typeofExpr,
     74     TST_decltype,         // C++11 decltype
     75     TST_underlyingType,   // __underlying_type for C++11
     76     TST_auto,             // C++11 auto
     77     TST_decltype_auto,    // C++1y decltype(auto)
     78     TST_auto_type,        // __auto_type extension
     79     TST_unknown_anytype,  // __unknown_anytype extension
     80     TST_atomic,           // C11 _Atomic
     81 #define GENERIC_IMAGE_TYPE(ImgType, Id) TST_##ImgType##_t, // OpenCL image types
     82 #include "clang/Basic/OpenCLImageTypes.def"
     83     TST_error // erroneous type
     84   };
     85 
     86   /// Structure that packs information about the type specifiers that
     87   /// were written in a particular type specifier sequence.
     88   struct WrittenBuiltinSpecs {
     89     static_assert(TST_error < 1 << 6, "Type bitfield not wide enough for TST");
     90     /*DeclSpec::TST*/ unsigned Type  : 6;
     91     /*DeclSpec::TSS*/ unsigned Sign  : 2;
     92     /*TypeSpecifierWidth*/ unsigned Width : 2;
     93     unsigned ModeAttr : 1;
     94   };
     95 
     96   /// A C++ access specifier (public, private, protected), plus the
     97   /// special value "none" which means different things in different contexts.
     98   enum AccessSpecifier {
     99     AS_public,
    100     AS_protected,
    101     AS_private,
    102     AS_none
    103   };
    104 
    105   /// The categorization of expression values, currently following the
    106   /// C++11 scheme.
    107   enum ExprValueKind {
    108     /// An r-value expression (a pr-value in the C++11 taxonomy)
    109     /// produces a temporary value.
    110     VK_RValue,
    111 
    112     /// An l-value expression is a reference to an object with
    113     /// independent storage.
    114     VK_LValue,
    115 
    116     /// An x-value expression is a reference to an object with
    117     /// independent storage but which can be "moved", i.e.
    118     /// efficiently cannibalized for its resources.
    119     VK_XValue
    120   };
    121 
    122   /// A further classification of the kind of object referenced by an
    123   /// l-value or x-value.
    124   enum ExprObjectKind {
    125     /// An ordinary object is located at an address in memory.
    126     OK_Ordinary,
    127 
    128     /// A bitfield object is a bitfield on a C or C++ record.
    129     OK_BitField,
    130 
    131     /// A vector component is an element or range of elements on a vector.
    132     OK_VectorComponent,
    133 
    134     /// An Objective-C property is a logical field of an Objective-C
    135     /// object which is read and written via Objective-C method calls.
    136     OK_ObjCProperty,
    137 
    138     /// An Objective-C array/dictionary subscripting which reads an
    139     /// object or writes at the subscripted array/dictionary element via
    140     /// Objective-C method calls.
    141     OK_ObjCSubscript,
    142 
    143     /// A matrix component is a single element of a matrix.
    144     OK_MatrixComponent
    145   };
    146 
    147   /// The reason why a DeclRefExpr does not constitute an odr-use.
    148   enum NonOdrUseReason {
    149     /// This is an odr-use.
    150     NOUR_None = 0,
    151     /// This name appears in an unevaluated operand.
    152     NOUR_Unevaluated,
    153     /// This name appears as a potential result of an lvalue-to-rvalue
    154     /// conversion that is a constant expression.
    155     NOUR_Constant,
    156     /// This name appears as a potential result of a discarded value
    157     /// expression.
    158     NOUR_Discarded,
    159   };
    160 
    161   /// Describes the kind of template specialization that a
    162   /// particular template specialization declaration represents.
    163   enum TemplateSpecializationKind {
    164     /// This template specialization was formed from a template-id but
    165     /// has not yet been declared, defined, or instantiated.
    166     TSK_Undeclared = 0,
    167     /// This template specialization was implicitly instantiated from a
    168     /// template. (C++ [temp.inst]).
    169     TSK_ImplicitInstantiation,
    170     /// This template specialization was declared or defined by an
    171     /// explicit specialization (C++ [temp.expl.spec]) or partial
    172     /// specialization (C++ [temp.class.spec]).
    173     TSK_ExplicitSpecialization,
    174     /// This template specialization was instantiated from a template
    175     /// due to an explicit instantiation declaration request
    176     /// (C++11 [temp.explicit]).
    177     TSK_ExplicitInstantiationDeclaration,
    178     /// This template specialization was instantiated from a template
    179     /// due to an explicit instantiation definition request
    180     /// (C++ [temp.explicit]).
    181     TSK_ExplicitInstantiationDefinition
    182   };
    183 
    184   /// Determine whether this template specialization kind refers
    185   /// to an instantiation of an entity (as opposed to a non-template or
    186   /// an explicit specialization).
    187   inline bool isTemplateInstantiation(TemplateSpecializationKind Kind) {
    188     return Kind != TSK_Undeclared && Kind != TSK_ExplicitSpecialization;
    189   }
    190 
    191   /// True if this template specialization kind is an explicit
    192   /// specialization, explicit instantiation declaration, or explicit
    193   /// instantiation definition.
    194   inline bool isTemplateExplicitInstantiationOrSpecialization(
    195       TemplateSpecializationKind Kind) {
    196     switch (Kind) {
    197     case TSK_ExplicitSpecialization:
    198     case TSK_ExplicitInstantiationDeclaration:
    199     case TSK_ExplicitInstantiationDefinition:
    200       return true;
    201 
    202     case TSK_Undeclared:
    203     case TSK_ImplicitInstantiation:
    204       return false;
    205     }
    206     llvm_unreachable("bad template specialization kind");
    207   }
    208 
    209   /// Thread storage-class-specifier.
    210   enum ThreadStorageClassSpecifier {
    211     TSCS_unspecified,
    212     /// GNU __thread.
    213     TSCS___thread,
    214     /// C++11 thread_local. Implies 'static' at block scope, but not at
    215     /// class scope.
    216     TSCS_thread_local,
    217     /// C11 _Thread_local. Must be combined with either 'static' or 'extern'
    218     /// if used at block scope.
    219     TSCS__Thread_local
    220   };
    221 
    222   /// Storage classes.
    223   enum StorageClass {
    224     // These are legal on both functions and variables.
    225     SC_None,
    226     SC_Extern,
    227     SC_Static,
    228     SC_PrivateExtern,
    229 
    230     // These are only legal on variables.
    231     SC_Auto,
    232     SC_Register
    233   };
    234 
    235   /// Checks whether the given storage class is legal for functions.
    236   inline bool isLegalForFunction(StorageClass SC) {
    237     return SC <= SC_PrivateExtern;
    238   }
    239 
    240   /// Checks whether the given storage class is legal for variables.
    241   inline bool isLegalForVariable(StorageClass SC) {
    242     return true;
    243   }
    244 
    245   /// In-class initialization styles for non-static data members.
    246   enum InClassInitStyle {
    247     ICIS_NoInit,   ///< No in-class initializer.
    248     ICIS_CopyInit, ///< Copy initialization.
    249     ICIS_ListInit  ///< Direct list-initialization.
    250   };
    251 
    252   /// CallingConv - Specifies the calling convention that a function uses.
    253   enum CallingConv {
    254     CC_C,           // __attribute__((cdecl))
    255     CC_X86StdCall,  // __attribute__((stdcall))
    256     CC_X86FastCall, // __attribute__((fastcall))
    257     CC_X86ThisCall, // __attribute__((thiscall))
    258     CC_X86VectorCall, // __attribute__((vectorcall))
    259     CC_X86Pascal,   // __attribute__((pascal))
    260     CC_Win64,       // __attribute__((ms_abi))
    261     CC_X86_64SysV,  // __attribute__((sysv_abi))
    262     CC_X86RegCall, // __attribute__((regcall))
    263     CC_AAPCS,       // __attribute__((pcs("aapcs")))
    264     CC_AAPCS_VFP,   // __attribute__((pcs("aapcs-vfp")))
    265     CC_IntelOclBicc, // __attribute__((intel_ocl_bicc))
    266     CC_SpirFunction, // default for OpenCL functions on SPIR target
    267     CC_OpenCLKernel, // inferred for OpenCL kernels
    268     CC_Swift,        // __attribute__((swiftcall))
    269     CC_PreserveMost, // __attribute__((preserve_most))
    270     CC_PreserveAll,  // __attribute__((preserve_all))
    271     CC_AArch64VectorCall, // __attribute__((aarch64_vector_pcs))
    272   };
    273 
    274   /// Checks whether the given calling convention supports variadic
    275   /// calls. Unprototyped calls also use the variadic call rules.
    276   inline bool supportsVariadicCall(CallingConv CC) {
    277     switch (CC) {
    278     case CC_X86StdCall:
    279     case CC_X86FastCall:
    280     case CC_X86ThisCall:
    281     case CC_X86RegCall:
    282     case CC_X86Pascal:
    283     case CC_X86VectorCall:
    284     case CC_SpirFunction:
    285     case CC_OpenCLKernel:
    286     case CC_Swift:
    287       return false;
    288     default:
    289       return true;
    290     }
    291   }
    292 
    293   /// The storage duration for an object (per C++ [basic.stc]).
    294   enum StorageDuration {
    295     SD_FullExpression, ///< Full-expression storage duration (for temporaries).
    296     SD_Automatic,      ///< Automatic storage duration (most local variables).
    297     SD_Thread,         ///< Thread storage duration.
    298     SD_Static,         ///< Static storage duration.
    299     SD_Dynamic         ///< Dynamic storage duration.
    300   };
    301 
    302   /// Describes the nullability of a particular type.
    303   enum class NullabilityKind : uint8_t {
    304     /// Values of this type can never be null.
    305     NonNull = 0,
    306     /// Values of this type can be null.
    307     Nullable,
    308     /// Whether values of this type can be null is (explicitly)
    309     /// unspecified. This captures a (fairly rare) case where we
    310     /// can't conclude anything about the nullability of the type even
    311     /// though it has been considered.
    312     Unspecified,
    313     // Generally behaves like Nullable, except when used in a block parameter
    314     // that was imported into a swift async method. There, swift will assume
    315     // that the parameter can get null even if no error occured. _Nullable
    316     // parameters are assumed to only get null on error.
    317     NullableResult,
    318   };
    319 
    320   /// Return true if \p L has a weaker nullability annotation than \p R. The
    321   /// ordering is: Unspecified < Nullable < NonNull.
    322   inline bool hasWeakerNullability(NullabilityKind L, NullabilityKind R) {
    323     return uint8_t(L) > uint8_t(R);
    324   }
    325 
    326   /// Retrieve the spelling of the given nullability kind.
    327   llvm::StringRef getNullabilitySpelling(NullabilityKind kind,
    328                                          bool isContextSensitive = false);
    329 
    330   /// Kinds of parameter ABI.
    331   enum class ParameterABI {
    332     /// This parameter uses ordinary ABI rules for its type.
    333     Ordinary,
    334 
    335     /// This parameter (which must have pointer type) is a Swift
    336     /// indirect result parameter.
    337     SwiftIndirectResult,
    338 
    339     /// This parameter (which must have pointer-to-pointer type) uses
    340     /// the special Swift error-result ABI treatment.  There can be at
    341     /// most one parameter on a given function that uses this treatment.
    342     SwiftErrorResult,
    343 
    344     /// This parameter (which must have pointer type) uses the special
    345     /// Swift context-pointer ABI treatment.  There can be at
    346     /// most one parameter on a given function that uses this treatment.
    347     SwiftContext
    348   };
    349 
    350   /// Assigned inheritance model for a class in the MS C++ ABI. Must match order
    351   /// of spellings in MSInheritanceAttr.
    352   enum class MSInheritanceModel {
    353     Single = 0,
    354     Multiple = 1,
    355     Virtual = 2,
    356     Unspecified = 3,
    357   };
    358 
    359   llvm::StringRef getParameterABISpelling(ParameterABI kind);
    360 
    361   inline llvm::StringRef getAccessSpelling(AccessSpecifier AS) {
    362     switch (AS) {
    363     case AccessSpecifier::AS_public:
    364       return "public";
    365     case AccessSpecifier::AS_protected:
    366       return "protected";
    367     case AccessSpecifier::AS_private:
    368       return "private";
    369     case AccessSpecifier::AS_none:
    370       return {};
    371     }
    372     llvm_unreachable("Unknown AccessSpecifier");
    373   }
    374 } // end namespace clang
    375 
    376 #endif // LLVM_CLANG_BASIC_SPECIFIERS_H
    377