1212795Sdim//===--- DeclSpec.h - Parsed declaration specifiers -------------*- C++ -*-===// 2212795Sdim// 3212795Sdim// The LLVM Compiler Infrastructure 4212795Sdim// 5212795Sdim// This file is distributed under the University of Illinois Open Source 6212795Sdim// License. See LICENSE.TXT for details. 7212795Sdim// 8212795Sdim//===----------------------------------------------------------------------===// 9245431Sdim/// 10245431Sdim/// \file 11245431Sdim/// \brief This file defines the classes used to store parsed information about 12245431Sdim/// declaration-specifiers and declarators. 13245431Sdim/// 14245431Sdim/// \verbatim 15245431Sdim/// static const int volatile x, *y, *(*(*z)[10])(const void *x); 16245431Sdim/// ------------------------- - -- --------------------------- 17245431Sdim/// declaration-specifiers \ | / 18245431Sdim/// declarators 19245431Sdim/// \endverbatim 20245431Sdim/// 21212795Sdim//===----------------------------------------------------------------------===// 22212795Sdim 23212795Sdim#ifndef LLVM_CLANG_SEMA_DECLSPEC_H 24212795Sdim#define LLVM_CLANG_SEMA_DECLSPEC_H 25212795Sdim 26221345Sdim#include "clang/AST/NestedNameSpecifier.h" 27221345Sdim#include "clang/Basic/ExceptionSpecificationType.h" 28235633Sdim#include "clang/Basic/Lambda.h" 29212795Sdim#include "clang/Basic/OperatorKinds.h" 30212795Sdim#include "clang/Basic/Specifiers.h" 31252723Sdim#include "clang/Lex/Token.h" 32252723Sdim#include "clang/Sema/AttributeList.h" 33252723Sdim#include "clang/Sema/Ownership.h" 34212795Sdim#include "llvm/ADT/SmallVector.h" 35235633Sdim#include "llvm/Support/Compiler.h" 36218893Sdim#include "llvm/Support/ErrorHandling.h" 37212795Sdim 38212795Sdimnamespace clang { 39219077Sdim class ASTContext; 40219077Sdim class TypeLoc; 41212795Sdim class LangOptions; 42226890Sdim class DiagnosticsEngine; 43212795Sdim class IdentifierInfo; 44219077Sdim class NamespaceAliasDecl; 45219077Sdim class NamespaceDecl; 46212795Sdim class NestedNameSpecifier; 47219077Sdim class NestedNameSpecifierLoc; 48224145Sdim class ObjCDeclSpec; 49212795Sdim class Preprocessor; 50226890Sdim class Sema; 51212795Sdim class Declarator; 52212795Sdim struct TemplateIdAnnotation; 53212795Sdim 54245431Sdim/// \brief Represents a C++ nested-name-specifier or a global scope specifier. 55245431Sdim/// 56245431Sdim/// These can be in 3 states: 57212795Sdim/// 1) Not present, identified by isEmpty() 58212795Sdim/// 2) Present, identified by isNotEmpty() 59212795Sdim/// 2.a) Valid, idenified by isValid() 60212795Sdim/// 2.b) Invalid, identified by isInvalid(). 61212795Sdim/// 62212795Sdim/// isSet() is deprecated because it mostly corresponded to "valid" but was 63212795Sdim/// often used as if it meant "present". 64212795Sdim/// 65212795Sdim/// The actual scope is described by getScopeRep(). 66212795Sdimclass CXXScopeSpec { 67221345Sdim SourceRange Range; 68221345Sdim NestedNameSpecifierLocBuilder Builder; 69212795Sdim 70212795Sdimpublic: 71212795Sdim const SourceRange &getRange() const { return Range; } 72212795Sdim void setRange(const SourceRange &R) { Range = R; } 73212795Sdim void setBeginLoc(SourceLocation Loc) { Range.setBegin(Loc); } 74212795Sdim void setEndLoc(SourceLocation Loc) { Range.setEnd(Loc); } 75212795Sdim SourceLocation getBeginLoc() const { return Range.getBegin(); } 76212795Sdim SourceLocation getEndLoc() const { return Range.getEnd(); } 77212795Sdim 78221345Sdim /// \brief Retrieve the representation of the nested-name-specifier. 79221345Sdim NestedNameSpecifier *getScopeRep() const { 80221345Sdim return Builder.getRepresentation(); 81221345Sdim } 82212795Sdim 83219077Sdim /// \brief Extend the current nested-name-specifier by another 84219077Sdim /// nested-name-specifier component of the form 'type::'. 85219077Sdim /// 86219077Sdim /// \param Context The AST context in which this nested-name-specifier 87219077Sdim /// resides. 88219077Sdim /// 89219077Sdim /// \param TemplateKWLoc The location of the 'template' keyword, if present. 90219077Sdim /// 91219077Sdim /// \param TL The TypeLoc that describes the type preceding the '::'. 92219077Sdim /// 93219077Sdim /// \param ColonColonLoc The location of the trailing '::'. 94219077Sdim void Extend(ASTContext &Context, SourceLocation TemplateKWLoc, TypeLoc TL, 95219077Sdim SourceLocation ColonColonLoc); 96219077Sdim 97219077Sdim /// \brief Extend the current nested-name-specifier by another 98219077Sdim /// nested-name-specifier component of the form 'identifier::'. 99219077Sdim /// 100219077Sdim /// \param Context The AST context in which this nested-name-specifier 101219077Sdim /// resides. 102219077Sdim /// 103219077Sdim /// \param Identifier The identifier. 104219077Sdim /// 105219077Sdim /// \param IdentifierLoc The location of the identifier. 106219077Sdim /// 107219077Sdim /// \param ColonColonLoc The location of the trailing '::'. 108219077Sdim void Extend(ASTContext &Context, IdentifierInfo *Identifier, 109219077Sdim SourceLocation IdentifierLoc, SourceLocation ColonColonLoc); 110219077Sdim 111219077Sdim /// \brief Extend the current nested-name-specifier by another 112219077Sdim /// nested-name-specifier component of the form 'namespace::'. 113219077Sdim /// 114219077Sdim /// \param Context The AST context in which this nested-name-specifier 115219077Sdim /// resides. 116219077Sdim /// 117219077Sdim /// \param Namespace The namespace. 118219077Sdim /// 119219077Sdim /// \param NamespaceLoc The location of the namespace name. 120219077Sdim /// 121219077Sdim /// \param ColonColonLoc The location of the trailing '::'. 122219077Sdim void Extend(ASTContext &Context, NamespaceDecl *Namespace, 123219077Sdim SourceLocation NamespaceLoc, SourceLocation ColonColonLoc); 124219077Sdim 125219077Sdim /// \brief Extend the current nested-name-specifier by another 126219077Sdim /// nested-name-specifier component of the form 'namespace-alias::'. 127219077Sdim /// 128219077Sdim /// \param Context The AST context in which this nested-name-specifier 129219077Sdim /// resides. 130219077Sdim /// 131219077Sdim /// \param Alias The namespace alias. 132219077Sdim /// 133219077Sdim /// \param AliasLoc The location of the namespace alias 134219077Sdim /// name. 135219077Sdim /// 136219077Sdim /// \param ColonColonLoc The location of the trailing '::'. 137219077Sdim void Extend(ASTContext &Context, NamespaceAliasDecl *Alias, 138219077Sdim SourceLocation AliasLoc, SourceLocation ColonColonLoc); 139219077Sdim 140219077Sdim /// \brief Turn this (empty) nested-name-specifier into the global 141219077Sdim /// nested-name-specifier '::'. 142219077Sdim void MakeGlobal(ASTContext &Context, SourceLocation ColonColonLoc); 143219077Sdim 144219077Sdim /// \brief Make a new nested-name-specifier from incomplete source-location 145219077Sdim /// information. 146219077Sdim /// 147219077Sdim /// FIXME: This routine should be used very, very rarely, in cases where we 148219077Sdim /// need to synthesize a nested-name-specifier. Most code should instead use 149219077Sdim /// \c Adopt() with a proper \c NestedNameSpecifierLoc. 150219077Sdim void MakeTrivial(ASTContext &Context, NestedNameSpecifier *Qualifier, 151219077Sdim SourceRange R); 152219077Sdim 153219077Sdim /// \brief Adopt an existing nested-name-specifier (with source-range 154219077Sdim /// information). 155219077Sdim void Adopt(NestedNameSpecifierLoc Other); 156219077Sdim 157219077Sdim /// \brief Retrieve a nested-name-specifier with location information, copied 158219077Sdim /// into the given AST context. 159219077Sdim /// 160219077Sdim /// \param Context The context into which this nested-name-specifier will be 161219077Sdim /// copied. 162219077Sdim NestedNameSpecifierLoc getWithLocInContext(ASTContext &Context) const; 163219077Sdim 164224145Sdim /// \brief Retrieve the location of the name in the last qualifier 165245431Sdim /// in this nested name specifier. 166245431Sdim /// 167245431Sdim /// For example, the location of \c bar 168245431Sdim /// in 169245431Sdim /// \verbatim 170245431Sdim /// \::foo::bar<0>:: 171245431Sdim /// ^~~ 172245431Sdim /// \endverbatim 173224145Sdim SourceLocation getLastQualifierNameLoc() const; 174224145Sdim 175212795Sdim /// No scope specifier. 176212795Sdim bool isEmpty() const { return !Range.isValid(); } 177212795Sdim /// A scope specifier is present, but may be valid or invalid. 178212795Sdim bool isNotEmpty() const { return !isEmpty(); } 179212795Sdim 180221345Sdim /// An error occurred during parsing of the scope specifier. 181221345Sdim bool isInvalid() const { return isNotEmpty() && getScopeRep() == 0; } 182212795Sdim /// A scope specifier is present, and it refers to a real scope. 183221345Sdim bool isValid() const { return isNotEmpty() && getScopeRep() != 0; } 184212795Sdim 185219077Sdim /// \brief Indicate that this nested-name-specifier is invalid. 186219077Sdim void SetInvalid(SourceRange R) { 187219077Sdim assert(R.isValid() && "Must have a valid source range"); 188219077Sdim if (Range.getBegin().isInvalid()) 189219077Sdim Range.setBegin(R.getBegin()); 190219077Sdim Range.setEnd(R.getEnd()); 191221345Sdim Builder.Clear(); 192219077Sdim } 193219077Sdim 194212795Sdim /// Deprecated. Some call sites intend isNotEmpty() while others intend 195212795Sdim /// isValid(). 196221345Sdim bool isSet() const { return getScopeRep() != 0; } 197212795Sdim 198212795Sdim void clear() { 199212795Sdim Range = SourceRange(); 200221345Sdim Builder.Clear(); 201212795Sdim } 202219077Sdim 203219077Sdim /// \brief Retrieve the data associated with the source-location information. 204221345Sdim char *location_data() const { return Builder.getBuffer().first; } 205219077Sdim 206219077Sdim /// \brief Retrieve the size of the data associated with source-location 207219077Sdim /// information. 208221345Sdim unsigned location_size() const { return Builder.getBuffer().second; } 209212795Sdim}; 210212795Sdim 211245431Sdim/// \brief Captures information about "declaration specifiers". 212245431Sdim/// 213245431Sdim/// "Declaration specifiers" encompasses storage-class-specifiers, 214245431Sdim/// type-specifiers, type-qualifiers, and function-specifiers. 215212795Sdimclass DeclSpec { 216212795Sdimpublic: 217245431Sdim /// \brief storage-class-specifier 218245431Sdim /// \note The order of these enumerators is important for diagnostics. 219212795Sdim enum SCS { 220212795Sdim SCS_unspecified = 0, 221212795Sdim SCS_typedef, 222212795Sdim SCS_extern, 223212795Sdim SCS_static, 224212795Sdim SCS_auto, 225212795Sdim SCS_register, 226212795Sdim SCS_private_extern, 227212795Sdim SCS_mutable 228212795Sdim }; 229212795Sdim 230252723Sdim // Import thread storage class specifier enumeration and constants. 231252723Sdim // These can be combined with SCS_extern and SCS_static. 232252723Sdim typedef ThreadStorageClassSpecifier TSCS; 233252723Sdim static const TSCS TSCS_unspecified = clang::TSCS_unspecified; 234252723Sdim static const TSCS TSCS___thread = clang::TSCS___thread; 235252723Sdim static const TSCS TSCS_thread_local = clang::TSCS_thread_local; 236252723Sdim static const TSCS TSCS__Thread_local = clang::TSCS__Thread_local; 237252723Sdim 238212795Sdim // Import type specifier width enumeration and constants. 239212795Sdim typedef TypeSpecifierWidth TSW; 240212795Sdim static const TSW TSW_unspecified = clang::TSW_unspecified; 241212795Sdim static const TSW TSW_short = clang::TSW_short; 242212795Sdim static const TSW TSW_long = clang::TSW_long; 243212795Sdim static const TSW TSW_longlong = clang::TSW_longlong; 244212795Sdim 245212795Sdim enum TSC { 246212795Sdim TSC_unspecified, 247212795Sdim TSC_imaginary, 248212795Sdim TSC_complex 249212795Sdim }; 250212795Sdim 251212795Sdim // Import type specifier sign enumeration and constants. 252212795Sdim typedef TypeSpecifierSign TSS; 253212795Sdim static const TSS TSS_unspecified = clang::TSS_unspecified; 254212795Sdim static const TSS TSS_signed = clang::TSS_signed; 255212795Sdim static const TSS TSS_unsigned = clang::TSS_unsigned; 256212795Sdim 257212795Sdim // Import type specifier type enumeration and constants. 258212795Sdim typedef TypeSpecifierType TST; 259212795Sdim static const TST TST_unspecified = clang::TST_unspecified; 260212795Sdim static const TST TST_void = clang::TST_void; 261212795Sdim static const TST TST_char = clang::TST_char; 262212795Sdim static const TST TST_wchar = clang::TST_wchar; 263212795Sdim static const TST TST_char16 = clang::TST_char16; 264212795Sdim static const TST TST_char32 = clang::TST_char32; 265212795Sdim static const TST TST_int = clang::TST_int; 266235633Sdim static const TST TST_int128 = clang::TST_int128; 267226890Sdim static const TST TST_half = clang::TST_half; 268212795Sdim static const TST TST_float = clang::TST_float; 269212795Sdim static const TST TST_double = clang::TST_double; 270212795Sdim static const TST TST_bool = clang::TST_bool; 271212795Sdim static const TST TST_decimal32 = clang::TST_decimal32; 272212795Sdim static const TST TST_decimal64 = clang::TST_decimal64; 273212795Sdim static const TST TST_decimal128 = clang::TST_decimal128; 274212795Sdim static const TST TST_enum = clang::TST_enum; 275212795Sdim static const TST TST_union = clang::TST_union; 276212795Sdim static const TST TST_struct = clang::TST_struct; 277245431Sdim static const TST TST_interface = clang::TST_interface; 278212795Sdim static const TST TST_class = clang::TST_class; 279212795Sdim static const TST TST_typename = clang::TST_typename; 280212795Sdim static const TST TST_typeofType = clang::TST_typeofType; 281212795Sdim static const TST TST_typeofExpr = clang::TST_typeofExpr; 282212795Sdim static const TST TST_decltype = clang::TST_decltype; 283252723Sdim static const TST TST_decltype_auto = clang::TST_decltype_auto; 284223017Sdim static const TST TST_underlyingType = clang::TST_underlyingType; 285212795Sdim static const TST TST_auto = clang::TST_auto; 286221345Sdim static const TST TST_unknown_anytype = clang::TST_unknown_anytype; 287226890Sdim static const TST TST_atomic = clang::TST_atomic; 288252723Sdim static const TST TST_image1d_t = clang::TST_image1d_t; 289252723Sdim static const TST TST_image1d_array_t = clang::TST_image1d_array_t; 290252723Sdim static const TST TST_image1d_buffer_t = clang::TST_image1d_buffer_t; 291252723Sdim static const TST TST_image2d_t = clang::TST_image2d_t; 292252723Sdim static const TST TST_image2d_array_t = clang::TST_image2d_array_t; 293252723Sdim static const TST TST_image3d_t = clang::TST_image3d_t; 294252723Sdim static const TST TST_sampler_t = clang::TST_sampler_t; 295252723Sdim static const TST TST_event_t = clang::TST_event_t; 296212795Sdim static const TST TST_error = clang::TST_error; 297212795Sdim 298212795Sdim // type-qualifiers 299212795Sdim enum TQ { // NOTE: These flags must be kept in sync with Qualifiers::TQ. 300212795Sdim TQ_unspecified = 0, 301212795Sdim TQ_const = 1, 302212795Sdim TQ_restrict = 2, 303252723Sdim TQ_volatile = 4, 304252723Sdim // This has no corresponding Qualifiers::TQ value, because it's not treated 305252723Sdim // as a qualifier in our type system. 306252723Sdim TQ_atomic = 8 307212795Sdim }; 308212795Sdim 309212795Sdim /// ParsedSpecifiers - Flags to query which specifiers were applied. This is 310212795Sdim /// returned by getParsedSpecifiers. 311212795Sdim enum ParsedSpecifiers { 312212795Sdim PQ_None = 0, 313212795Sdim PQ_StorageClassSpecifier = 1, 314212795Sdim PQ_TypeSpecifier = 2, 315212795Sdim PQ_TypeQualifier = 4, 316212795Sdim PQ_FunctionSpecifier = 8 317212795Sdim }; 318212795Sdim 319212795Sdimprivate: 320212795Sdim // storage-class-specifier 321212795Sdim /*SCS*/unsigned StorageClassSpec : 3; 322252723Sdim /*TSCS*/unsigned ThreadStorageClassSpec : 2; 323218893Sdim unsigned SCS_extern_in_linkage_spec : 1; 324212795Sdim 325212795Sdim // type-specifier 326212795Sdim /*TSW*/unsigned TypeSpecWidth : 2; 327212795Sdim /*TSC*/unsigned TypeSpecComplex : 2; 328212795Sdim /*TSS*/unsigned TypeSpecSign : 2; 329252723Sdim /*TST*/unsigned TypeSpecType : 6; 330218893Sdim unsigned TypeAltiVecVector : 1; 331218893Sdim unsigned TypeAltiVecPixel : 1; 332218893Sdim unsigned TypeAltiVecBool : 1; 333218893Sdim unsigned TypeSpecOwned : 1; 334212795Sdim 335212795Sdim // type-qualifiers 336252723Sdim unsigned TypeQualifiers : 4; // Bitwise OR of TQ. 337212795Sdim 338212795Sdim // function-specifier 339218893Sdim unsigned FS_inline_specified : 1; 340263509Sdim unsigned FS_forceinline_specified: 1; 341218893Sdim unsigned FS_virtual_specified : 1; 342218893Sdim unsigned FS_explicit_specified : 1; 343252723Sdim unsigned FS_noreturn_specified : 1; 344212795Sdim 345212795Sdim // friend-specifier 346218893Sdim unsigned Friend_specified : 1; 347212795Sdim 348212795Sdim // constexpr-specifier 349218893Sdim unsigned Constexpr_specified : 1; 350212795Sdim 351212795Sdim union { 352212795Sdim UnionParsedType TypeRep; 353212795Sdim Decl *DeclRep; 354212795Sdim Expr *ExprRep; 355212795Sdim }; 356212795Sdim 357212795Sdim // attributes. 358218893Sdim ParsedAttributes Attrs; 359212795Sdim 360212795Sdim // Scope specifier for the type spec, if applicable. 361212795Sdim CXXScopeSpec TypeScope; 362212795Sdim 363212795Sdim // List of protocol qualifiers for objective-c classes. Used for 364212795Sdim // protocol-qualified interfaces "NString<foo>" and protocol-qualified id 365212795Sdim // "id<foo>". 366212795Sdim Decl * const *ProtocolQualifiers; 367212795Sdim unsigned NumProtocolQualifiers; 368212795Sdim SourceLocation ProtocolLAngleLoc; 369212795Sdim SourceLocation *ProtocolLocs; 370212795Sdim 371212795Sdim // SourceLocation info. These are null if the item wasn't specified or if 372212795Sdim // the setting was synthesized. 373212795Sdim SourceRange Range; 374212795Sdim 375252723Sdim SourceLocation StorageClassSpecLoc, ThreadStorageClassSpecLoc; 376212795Sdim SourceLocation TSWLoc, TSCLoc, TSSLoc, TSTLoc, AltiVecLoc; 377221345Sdim /// TSTNameLoc - If TypeSpecType is any of class, enum, struct, union, 378221345Sdim /// typename, then this is the location of the named type (if present); 379221345Sdim /// otherwise, it is the same as TSTLoc. Hence, the pair TSTLoc and 380221345Sdim /// TSTNameLoc provides source range info for tag types. 381221345Sdim SourceLocation TSTNameLoc; 382212795Sdim SourceRange TypeofParensRange; 383252723Sdim SourceLocation TQ_constLoc, TQ_restrictLoc, TQ_volatileLoc, TQ_atomicLoc; 384252723Sdim SourceLocation FS_inlineLoc, FS_virtualLoc, FS_explicitLoc, FS_noreturnLoc; 385263509Sdim SourceLocation FS_forceinlineLoc; 386226890Sdim SourceLocation FriendLoc, ModulePrivateLoc, ConstexprLoc; 387212795Sdim 388212795Sdim WrittenBuiltinSpecs writtenBS; 389212795Sdim void SaveWrittenBuiltinSpecs(); 390212795Sdim 391224145Sdim ObjCDeclSpec *ObjCQualifiers; 392224145Sdim 393212795Sdim static bool isTypeRep(TST T) { 394223017Sdim return (T == TST_typename || T == TST_typeofType || 395226890Sdim T == TST_underlyingType || T == TST_atomic); 396212795Sdim } 397212795Sdim static bool isExprRep(TST T) { 398212795Sdim return (T == TST_typeofExpr || T == TST_decltype); 399212795Sdim } 400252723Sdim 401252723Sdim DeclSpec(const DeclSpec &) LLVM_DELETED_FUNCTION; 402252723Sdim void operator=(const DeclSpec &) LLVM_DELETED_FUNCTION; 403252723Sdimpublic: 404212795Sdim static bool isDeclRep(TST T) { 405212795Sdim return (T == TST_enum || T == TST_struct || 406245431Sdim T == TST_interface || T == TST_union || 407245431Sdim T == TST_class); 408212795Sdim } 409212795Sdim 410221345Sdim DeclSpec(AttributeFactory &attrFactory) 411212795Sdim : StorageClassSpec(SCS_unspecified), 412252723Sdim ThreadStorageClassSpec(TSCS_unspecified), 413212795Sdim SCS_extern_in_linkage_spec(false), 414212795Sdim TypeSpecWidth(TSW_unspecified), 415212795Sdim TypeSpecComplex(TSC_unspecified), 416212795Sdim TypeSpecSign(TSS_unspecified), 417212795Sdim TypeSpecType(TST_unspecified), 418212795Sdim TypeAltiVecVector(false), 419212795Sdim TypeAltiVecPixel(false), 420212795Sdim TypeAltiVecBool(false), 421212795Sdim TypeSpecOwned(false), 422226890Sdim TypeQualifiers(TQ_unspecified), 423212795Sdim FS_inline_specified(false), 424263509Sdim FS_forceinline_specified(false), 425212795Sdim FS_virtual_specified(false), 426212795Sdim FS_explicit_specified(false), 427252723Sdim FS_noreturn_specified(false), 428212795Sdim Friend_specified(false), 429212795Sdim Constexpr_specified(false), 430221345Sdim Attrs(attrFactory), 431212795Sdim ProtocolQualifiers(0), 432212795Sdim NumProtocolQualifiers(0), 433212795Sdim ProtocolLocs(0), 434224145Sdim writtenBS(), 435224145Sdim ObjCQualifiers(0) { 436212795Sdim } 437212795Sdim ~DeclSpec() { 438212795Sdim delete [] ProtocolQualifiers; 439212795Sdim delete [] ProtocolLocs; 440212795Sdim } 441212795Sdim // storage-class-specifier 442212795Sdim SCS getStorageClassSpec() const { return (SCS)StorageClassSpec; } 443252723Sdim TSCS getThreadStorageClassSpec() const { 444252723Sdim return (TSCS)ThreadStorageClassSpec; 445252723Sdim } 446212795Sdim bool isExternInLinkageSpec() const { return SCS_extern_in_linkage_spec; } 447212795Sdim void setExternInLinkageSpec(bool Value) { 448212795Sdim SCS_extern_in_linkage_spec = Value; 449212795Sdim } 450212795Sdim 451212795Sdim SourceLocation getStorageClassSpecLoc() const { return StorageClassSpecLoc; } 452252723Sdim SourceLocation getThreadStorageClassSpecLoc() const { 453252723Sdim return ThreadStorageClassSpecLoc; 454252723Sdim } 455212795Sdim 456212795Sdim void ClearStorageClassSpecs() { 457252723Sdim StorageClassSpec = DeclSpec::SCS_unspecified; 458252723Sdim ThreadStorageClassSpec = DeclSpec::TSCS_unspecified; 459212795Sdim SCS_extern_in_linkage_spec = false; 460252723Sdim StorageClassSpecLoc = SourceLocation(); 461252723Sdim ThreadStorageClassSpecLoc = SourceLocation(); 462212795Sdim } 463212795Sdim 464263509Sdim void ClearTypeSpecType() { 465263509Sdim TypeSpecType = DeclSpec::TST_unspecified; 466263509Sdim TypeSpecOwned = false; 467263509Sdim TSTLoc = SourceLocation(); 468263509Sdim } 469263509Sdim 470212795Sdim // type-specifier 471212795Sdim TSW getTypeSpecWidth() const { return (TSW)TypeSpecWidth; } 472212795Sdim TSC getTypeSpecComplex() const { return (TSC)TypeSpecComplex; } 473212795Sdim TSS getTypeSpecSign() const { return (TSS)TypeSpecSign; } 474212795Sdim TST getTypeSpecType() const { return (TST)TypeSpecType; } 475212795Sdim bool isTypeAltiVecVector() const { return TypeAltiVecVector; } 476212795Sdim bool isTypeAltiVecPixel() const { return TypeAltiVecPixel; } 477212795Sdim bool isTypeAltiVecBool() const { return TypeAltiVecBool; } 478212795Sdim bool isTypeSpecOwned() const { return TypeSpecOwned; } 479212795Sdim ParsedType getRepAsType() const { 480212795Sdim assert(isTypeRep((TST) TypeSpecType) && "DeclSpec does not store a type"); 481212795Sdim return TypeRep; 482212795Sdim } 483212795Sdim Decl *getRepAsDecl() const { 484212795Sdim assert(isDeclRep((TST) TypeSpecType) && "DeclSpec does not store a decl"); 485212795Sdim return DeclRep; 486212795Sdim } 487212795Sdim Expr *getRepAsExpr() const { 488212795Sdim assert(isExprRep((TST) TypeSpecType) && "DeclSpec does not store an expr"); 489212795Sdim return ExprRep; 490212795Sdim } 491212795Sdim CXXScopeSpec &getTypeSpecScope() { return TypeScope; } 492212795Sdim const CXXScopeSpec &getTypeSpecScope() const { return TypeScope; } 493212795Sdim 494235633Sdim const SourceRange &getSourceRange() const LLVM_READONLY { return Range; } 495235633Sdim SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); } 496235633Sdim SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); } 497235633Sdim 498212795Sdim SourceLocation getTypeSpecWidthLoc() const { return TSWLoc; } 499212795Sdim SourceLocation getTypeSpecComplexLoc() const { return TSCLoc; } 500212795Sdim SourceLocation getTypeSpecSignLoc() const { return TSSLoc; } 501212795Sdim SourceLocation getTypeSpecTypeLoc() const { return TSTLoc; } 502212795Sdim SourceLocation getAltiVecLoc() const { return AltiVecLoc; } 503212795Sdim 504221345Sdim SourceLocation getTypeSpecTypeNameLoc() const { 505221345Sdim assert(isDeclRep((TST) TypeSpecType) || TypeSpecType == TST_typename); 506221345Sdim return TSTNameLoc; 507221345Sdim } 508221345Sdim 509212795Sdim SourceRange getTypeofParensRange() const { return TypeofParensRange; } 510212795Sdim void setTypeofParensRange(SourceRange range) { TypeofParensRange = range; } 511212795Sdim 512252723Sdim bool containsPlaceholderType() const { 513252723Sdim return TypeSpecType == TST_auto || TypeSpecType == TST_decltype_auto; 514252723Sdim } 515252723Sdim 516263509Sdim bool hasTagDefinition() const; 517263509Sdim 518245431Sdim /// \brief Turn a type-specifier-type into a string like "_Bool" or "union". 519212795Sdim static const char *getSpecifierName(DeclSpec::TST T); 520212795Sdim static const char *getSpecifierName(DeclSpec::TQ Q); 521212795Sdim static const char *getSpecifierName(DeclSpec::TSS S); 522212795Sdim static const char *getSpecifierName(DeclSpec::TSC C); 523212795Sdim static const char *getSpecifierName(DeclSpec::TSW W); 524212795Sdim static const char *getSpecifierName(DeclSpec::SCS S); 525252723Sdim static const char *getSpecifierName(DeclSpec::TSCS S); 526212795Sdim 527212795Sdim // type-qualifiers 528212795Sdim 529212795Sdim /// getTypeQualifiers - Return a set of TQs. 530212795Sdim unsigned getTypeQualifiers() const { return TypeQualifiers; } 531212795Sdim SourceLocation getConstSpecLoc() const { return TQ_constLoc; } 532212795Sdim SourceLocation getRestrictSpecLoc() const { return TQ_restrictLoc; } 533212795Sdim SourceLocation getVolatileSpecLoc() const { return TQ_volatileLoc; } 534252723Sdim SourceLocation getAtomicSpecLoc() const { return TQ_atomicLoc; } 535212795Sdim 536223017Sdim /// \brief Clear out all of the type qualifiers. 537223017Sdim void ClearTypeQualifiers() { 538223017Sdim TypeQualifiers = 0; 539223017Sdim TQ_constLoc = SourceLocation(); 540223017Sdim TQ_restrictLoc = SourceLocation(); 541223017Sdim TQ_volatileLoc = SourceLocation(); 542252723Sdim TQ_atomicLoc = SourceLocation(); 543223017Sdim } 544223017Sdim 545212795Sdim // function-specifier 546263509Sdim bool isInlineSpecified() const { 547263509Sdim return FS_inline_specified | FS_forceinline_specified; 548263509Sdim } 549263509Sdim SourceLocation getInlineSpecLoc() const { 550263509Sdim return FS_inline_specified ? FS_inlineLoc : FS_forceinlineLoc; 551263509Sdim } 552212795Sdim 553212795Sdim bool isVirtualSpecified() const { return FS_virtual_specified; } 554212795Sdim SourceLocation getVirtualSpecLoc() const { return FS_virtualLoc; } 555212795Sdim 556212795Sdim bool isExplicitSpecified() const { return FS_explicit_specified; } 557212795Sdim SourceLocation getExplicitSpecLoc() const { return FS_explicitLoc; } 558212795Sdim 559252723Sdim bool isNoreturnSpecified() const { return FS_noreturn_specified; } 560252723Sdim SourceLocation getNoreturnSpecLoc() const { return FS_noreturnLoc; } 561252723Sdim 562212795Sdim void ClearFunctionSpecs() { 563212795Sdim FS_inline_specified = false; 564212795Sdim FS_inlineLoc = SourceLocation(); 565263509Sdim FS_forceinline_specified = false; 566263509Sdim FS_forceinlineLoc = SourceLocation(); 567212795Sdim FS_virtual_specified = false; 568212795Sdim FS_virtualLoc = SourceLocation(); 569212795Sdim FS_explicit_specified = false; 570212795Sdim FS_explicitLoc = SourceLocation(); 571252723Sdim FS_noreturn_specified = false; 572252723Sdim FS_noreturnLoc = SourceLocation(); 573212795Sdim } 574212795Sdim 575245431Sdim /// \brief Return true if any type-specifier has been found. 576212795Sdim bool hasTypeSpecifier() const { 577212795Sdim return getTypeSpecType() != DeclSpec::TST_unspecified || 578212795Sdim getTypeSpecWidth() != DeclSpec::TSW_unspecified || 579212795Sdim getTypeSpecComplex() != DeclSpec::TSC_unspecified || 580212795Sdim getTypeSpecSign() != DeclSpec::TSS_unspecified; 581212795Sdim } 582212795Sdim 583245431Sdim /// \brief Return a bitmask of which flavors of specifiers this 584212795Sdim /// DeclSpec includes. 585212795Sdim unsigned getParsedSpecifiers() const; 586212795Sdim 587212795Sdim /// isEmpty - Return true if this declaration specifier is completely empty: 588212795Sdim /// no tokens were parsed in the production of it. 589212795Sdim bool isEmpty() const { 590212795Sdim return getParsedSpecifiers() == DeclSpec::PQ_None; 591212795Sdim } 592212795Sdim 593212795Sdim void SetRangeStart(SourceLocation Loc) { Range.setBegin(Loc); } 594212795Sdim void SetRangeEnd(SourceLocation Loc) { Range.setEnd(Loc); } 595212795Sdim 596212795Sdim /// These methods set the specified attribute of the DeclSpec and 597212795Sdim /// return false if there was no error. If an error occurs (for 598212795Sdim /// example, if we tried to set "auto" on a spec with "extern" 599212795Sdim /// already set), they return true and set PrevSpec and DiagID 600212795Sdim /// such that 601212795Sdim /// Diag(Loc, DiagID) << PrevSpec; 602212795Sdim /// will yield a useful result. 603212795Sdim /// 604212795Sdim /// TODO: use a more general approach that still allows these 605212795Sdim /// diagnostics to be ignored when desired. 606226890Sdim bool SetStorageClassSpec(Sema &S, SCS SC, SourceLocation Loc, 607226890Sdim const char *&PrevSpec, unsigned &DiagID); 608252723Sdim bool SetStorageClassSpecThread(TSCS TSC, SourceLocation Loc, 609252723Sdim const char *&PrevSpec, unsigned &DiagID); 610212795Sdim bool SetTypeSpecWidth(TSW W, SourceLocation Loc, const char *&PrevSpec, 611212795Sdim unsigned &DiagID); 612212795Sdim bool SetTypeSpecComplex(TSC C, SourceLocation Loc, const char *&PrevSpec, 613212795Sdim unsigned &DiagID); 614212795Sdim bool SetTypeSpecSign(TSS S, SourceLocation Loc, const char *&PrevSpec, 615212795Sdim unsigned &DiagID); 616212795Sdim bool SetTypeSpecType(TST T, SourceLocation Loc, const char *&PrevSpec, 617212795Sdim unsigned &DiagID); 618212795Sdim bool SetTypeSpecType(TST T, SourceLocation Loc, const char *&PrevSpec, 619212795Sdim unsigned &DiagID, ParsedType Rep); 620212795Sdim bool SetTypeSpecType(TST T, SourceLocation Loc, const char *&PrevSpec, 621212795Sdim unsigned &DiagID, Decl *Rep, bool Owned); 622221345Sdim bool SetTypeSpecType(TST T, SourceLocation TagKwLoc, 623221345Sdim SourceLocation TagNameLoc, const char *&PrevSpec, 624221345Sdim unsigned &DiagID, ParsedType Rep); 625221345Sdim bool SetTypeSpecType(TST T, SourceLocation TagKwLoc, 626221345Sdim SourceLocation TagNameLoc, const char *&PrevSpec, 627221345Sdim unsigned &DiagID, Decl *Rep, bool Owned); 628221345Sdim 629212795Sdim bool SetTypeSpecType(TST T, SourceLocation Loc, const char *&PrevSpec, 630212795Sdim unsigned &DiagID, Expr *Rep); 631212795Sdim bool SetTypeAltiVecVector(bool isAltiVecVector, SourceLocation Loc, 632212795Sdim const char *&PrevSpec, unsigned &DiagID); 633212795Sdim bool SetTypeAltiVecPixel(bool isAltiVecPixel, SourceLocation Loc, 634212795Sdim const char *&PrevSpec, unsigned &DiagID); 635263509Sdim bool SetTypeAltiVecBool(bool isAltiVecBool, SourceLocation Loc, 636263509Sdim const char *&PrevSpec, unsigned &DiagID); 637212795Sdim bool SetTypeSpecError(); 638212795Sdim void UpdateDeclRep(Decl *Rep) { 639212795Sdim assert(isDeclRep((TST) TypeSpecType)); 640212795Sdim DeclRep = Rep; 641212795Sdim } 642212795Sdim void UpdateTypeRep(ParsedType Rep) { 643212795Sdim assert(isTypeRep((TST) TypeSpecType)); 644212795Sdim TypeRep = Rep; 645212795Sdim } 646212795Sdim void UpdateExprRep(Expr *Rep) { 647212795Sdim assert(isExprRep((TST) TypeSpecType)); 648212795Sdim ExprRep = Rep; 649212795Sdim } 650212795Sdim 651212795Sdim bool SetTypeQual(TQ T, SourceLocation Loc, const char *&PrevSpec, 652212795Sdim unsigned &DiagID, const LangOptions &Lang); 653212795Sdim 654263509Sdim bool setFunctionSpecInline(SourceLocation Loc, const char *&PrevSpec, 655263509Sdim unsigned &DiagID); 656263509Sdim bool setFunctionSpecForceInline(SourceLocation Loc, const char *&PrevSpec, 657263509Sdim unsigned &DiagID); 658263509Sdim bool setFunctionSpecVirtual(SourceLocation Loc, const char *&PrevSpec, 659263509Sdim unsigned &DiagID); 660263509Sdim bool setFunctionSpecExplicit(SourceLocation Loc, const char *&PrevSpec, 661263509Sdim unsigned &DiagID); 662263509Sdim bool setFunctionSpecNoreturn(SourceLocation Loc, const char *&PrevSpec, 663263509Sdim unsigned &DiagID); 664212795Sdim 665212795Sdim bool SetFriendSpec(SourceLocation Loc, const char *&PrevSpec, 666212795Sdim unsigned &DiagID); 667226890Sdim bool setModulePrivateSpec(SourceLocation Loc, const char *&PrevSpec, 668226890Sdim unsigned &DiagID); 669212795Sdim bool SetConstexprSpec(SourceLocation Loc, const char *&PrevSpec, 670212795Sdim unsigned &DiagID); 671212795Sdim 672212795Sdim bool isFriendSpecified() const { return Friend_specified; } 673212795Sdim SourceLocation getFriendSpecLoc() const { return FriendLoc; } 674212795Sdim 675226890Sdim bool isModulePrivateSpecified() const { return ModulePrivateLoc.isValid(); } 676226890Sdim SourceLocation getModulePrivateSpecLoc() const { return ModulePrivateLoc; } 677226890Sdim 678212795Sdim bool isConstexprSpecified() const { return Constexpr_specified; } 679212795Sdim SourceLocation getConstexprSpecLoc() const { return ConstexprLoc; } 680212795Sdim 681235633Sdim void ClearConstexprSpec() { 682235633Sdim Constexpr_specified = false; 683235633Sdim ConstexprLoc = SourceLocation(); 684235633Sdim } 685235633Sdim 686221345Sdim AttributePool &getAttributePool() const { 687221345Sdim return Attrs.getPool(); 688221345Sdim } 689221345Sdim 690245431Sdim /// \brief Concatenates two attribute lists. 691245431Sdim /// 692212795Sdim /// The GCC attribute syntax allows for the following: 693212795Sdim /// 694245431Sdim /// \code 695212795Sdim /// short __attribute__(( unused, deprecated )) 696212795Sdim /// int __attribute__(( may_alias, aligned(16) )) var; 697245431Sdim /// \endcode 698212795Sdim /// 699212795Sdim /// This declares 4 attributes using 2 lists. The following syntax is 700212795Sdim /// also allowed and equivalent to the previous declaration. 701212795Sdim /// 702245431Sdim /// \code 703212795Sdim /// short __attribute__((unused)) __attribute__((deprecated)) 704212795Sdim /// int __attribute__((may_alias)) __attribute__((aligned(16))) var; 705245431Sdim /// \endcode 706212795Sdim /// 707218893Sdim void addAttributes(AttributeList *AL) { 708221345Sdim Attrs.addAll(AL); 709212795Sdim } 710221345Sdim void setAttributes(AttributeList *AL) { 711218893Sdim Attrs.set(AL); 712218893Sdim } 713212795Sdim 714218893Sdim bool hasAttributes() const { return !Attrs.empty(); } 715218893Sdim 716218893Sdim ParsedAttributes &getAttributes() { return Attrs; } 717218893Sdim const ParsedAttributes &getAttributes() const { return Attrs; } 718218893Sdim 719245431Sdim /// \brief Return the current attribute list and remove them from 720212795Sdim /// the DeclSpec so that it doesn't own them. 721218893Sdim ParsedAttributes takeAttributes() { 722221345Sdim // The non-const "copy" constructor clears the operand automatically. 723221345Sdim return Attrs; 724212795Sdim } 725212795Sdim 726218893Sdim void takeAttributesFrom(ParsedAttributes &attrs) { 727221345Sdim Attrs.takeAllFrom(attrs); 728218893Sdim } 729218893Sdim 730212795Sdim typedef Decl * const *ProtocolQualifierListTy; 731212795Sdim ProtocolQualifierListTy getProtocolQualifiers() const { 732212795Sdim return ProtocolQualifiers; 733212795Sdim } 734212795Sdim SourceLocation *getProtocolLocs() const { return ProtocolLocs; } 735212795Sdim unsigned getNumProtocolQualifiers() const { 736212795Sdim return NumProtocolQualifiers; 737212795Sdim } 738212795Sdim SourceLocation getProtocolLAngleLoc() const { return ProtocolLAngleLoc; } 739212795Sdim void setProtocolQualifiers(Decl * const *Protos, unsigned NP, 740212795Sdim SourceLocation *ProtoLocs, 741212795Sdim SourceLocation LAngleLoc); 742212795Sdim 743212795Sdim /// Finish - This does final analysis of the declspec, issuing diagnostics for 744212795Sdim /// things like "_Imaginary" (lacking an FP type). After calling this method, 745212795Sdim /// DeclSpec is guaranteed self-consistent, even if an error occurred. 746226890Sdim void Finish(DiagnosticsEngine &D, Preprocessor &PP); 747212795Sdim 748212795Sdim const WrittenBuiltinSpecs& getWrittenBuiltinSpecs() const { 749212795Sdim return writtenBS; 750212795Sdim } 751212795Sdim 752224145Sdim ObjCDeclSpec *getObjCQualifiers() const { return ObjCQualifiers; } 753224145Sdim void setObjCQualifiers(ObjCDeclSpec *quals) { ObjCQualifiers = quals; } 754224145Sdim 755245431Sdim /// \brief Checks if this DeclSpec can stand alone, without a Declarator. 756245431Sdim /// 757245431Sdim /// Only tag declspecs can stand alone. 758212795Sdim bool isMissingDeclaratorOk(); 759212795Sdim}; 760212795Sdim 761245431Sdim/// \brief Captures information about "declaration specifiers" specific to 762245431Sdim/// Objective-C. 763212795Sdimclass ObjCDeclSpec { 764212795Sdimpublic: 765221345Sdim /// ObjCDeclQualifier - Qualifier used on types in method 766221345Sdim /// declarations. Not all combinations are sensible. Parameters 767221345Sdim /// can be one of { in, out, inout } with one of { bycopy, byref }. 768221345Sdim /// Returns can either be { oneway } or not. 769221345Sdim /// 770221345Sdim /// This should be kept in sync with Decl::ObjCDeclQualifier. 771212795Sdim enum ObjCDeclQualifier { 772212795Sdim DQ_None = 0x0, 773212795Sdim DQ_In = 0x1, 774212795Sdim DQ_Inout = 0x2, 775212795Sdim DQ_Out = 0x4, 776212795Sdim DQ_Bycopy = 0x8, 777212795Sdim DQ_Byref = 0x10, 778212795Sdim DQ_Oneway = 0x20 779212795Sdim }; 780212795Sdim 781212795Sdim /// PropertyAttributeKind - list of property attributes. 782221345Sdim enum ObjCPropertyAttributeKind { 783221345Sdim DQ_PR_noattr = 0x0, 784212795Sdim DQ_PR_readonly = 0x01, 785212795Sdim DQ_PR_getter = 0x02, 786212795Sdim DQ_PR_assign = 0x04, 787212795Sdim DQ_PR_readwrite = 0x08, 788212795Sdim DQ_PR_retain = 0x10, 789212795Sdim DQ_PR_copy = 0x20, 790212795Sdim DQ_PR_nonatomic = 0x40, 791218893Sdim DQ_PR_setter = 0x80, 792224145Sdim DQ_PR_atomic = 0x100, 793224145Sdim DQ_PR_weak = 0x200, 794224145Sdim DQ_PR_strong = 0x400, 795224145Sdim DQ_PR_unsafe_unretained = 0x800 796212795Sdim }; 797212795Sdim 798212795Sdim 799212795Sdim ObjCDeclSpec() 800212795Sdim : objcDeclQualifier(DQ_None), PropertyAttributes(DQ_PR_noattr), 801212795Sdim GetterName(0), SetterName(0) { } 802212795Sdim ObjCDeclQualifier getObjCDeclQualifier() const { return objcDeclQualifier; } 803212795Sdim void setObjCDeclQualifier(ObjCDeclQualifier DQVal) { 804212795Sdim objcDeclQualifier = (ObjCDeclQualifier) (objcDeclQualifier | DQVal); 805212795Sdim } 806212795Sdim 807212795Sdim ObjCPropertyAttributeKind getPropertyAttributes() const { 808212795Sdim return ObjCPropertyAttributeKind(PropertyAttributes); 809212795Sdim } 810212795Sdim void setPropertyAttributes(ObjCPropertyAttributeKind PRVal) { 811212795Sdim PropertyAttributes = 812212795Sdim (ObjCPropertyAttributeKind)(PropertyAttributes | PRVal); 813212795Sdim } 814212795Sdim 815212795Sdim const IdentifierInfo *getGetterName() const { return GetterName; } 816212795Sdim IdentifierInfo *getGetterName() { return GetterName; } 817212795Sdim void setGetterName(IdentifierInfo *name) { GetterName = name; } 818212795Sdim 819212795Sdim const IdentifierInfo *getSetterName() const { return SetterName; } 820212795Sdim IdentifierInfo *getSetterName() { return SetterName; } 821212795Sdim void setSetterName(IdentifierInfo *name) { SetterName = name; } 822226890Sdim 823212795Sdimprivate: 824212795Sdim // FIXME: These two are unrelated and mutially exclusive. So perhaps 825212795Sdim // we can put them in a union to reflect their mutual exclusiveness 826212795Sdim // (space saving is negligible). 827212795Sdim ObjCDeclQualifier objcDeclQualifier : 6; 828212795Sdim 829212795Sdim // NOTE: VC++ treats enums as signed, avoid using ObjCPropertyAttributeKind 830224145Sdim unsigned PropertyAttributes : 12; 831212795Sdim IdentifierInfo *GetterName; // getter name of NULL if no getter 832212795Sdim IdentifierInfo *SetterName; // setter name of NULL if no setter 833212795Sdim}; 834212795Sdim 835212795Sdim/// \brief Represents a C++ unqualified-id that has been parsed. 836212795Sdimclass UnqualifiedId { 837212795Sdimprivate: 838245431Sdim UnqualifiedId(const UnqualifiedId &Other) LLVM_DELETED_FUNCTION; 839245431Sdim const UnqualifiedId &operator=(const UnqualifiedId &) LLVM_DELETED_FUNCTION; 840245431Sdim 841212795Sdimpublic: 842212795Sdim /// \brief Describes the kind of unqualified-id parsed. 843212795Sdim enum IdKind { 844212795Sdim /// \brief An identifier. 845212795Sdim IK_Identifier, 846212795Sdim /// \brief An overloaded operator name, e.g., operator+. 847212795Sdim IK_OperatorFunctionId, 848212795Sdim /// \brief A conversion function name, e.g., operator int. 849212795Sdim IK_ConversionFunctionId, 850212795Sdim /// \brief A user-defined literal name, e.g., operator "" _i. 851212795Sdim IK_LiteralOperatorId, 852212795Sdim /// \brief A constructor name. 853212795Sdim IK_ConstructorName, 854212795Sdim /// \brief A constructor named via a template-id. 855212795Sdim IK_ConstructorTemplateId, 856212795Sdim /// \brief A destructor name. 857212795Sdim IK_DestructorName, 858212795Sdim /// \brief A template-id, e.g., f<int>. 859224145Sdim IK_TemplateId, 860224145Sdim /// \brief An implicit 'self' parameter 861224145Sdim IK_ImplicitSelfParam 862212795Sdim } Kind; 863212795Sdim 864252723Sdim struct OFI { 865252723Sdim /// \brief The kind of overloaded operator. 866252723Sdim OverloadedOperatorKind Operator; 867252723Sdim 868252723Sdim /// \brief The source locations of the individual tokens that name 869252723Sdim /// the operator, e.g., the "new", "[", and "]" tokens in 870252723Sdim /// operator new []. 871252723Sdim /// 872252723Sdim /// Different operators have different numbers of tokens in their name, 873252723Sdim /// up to three. Any remaining source locations in this array will be 874252723Sdim /// set to an invalid value for operators with fewer than three tokens. 875252723Sdim unsigned SymbolLocations[3]; 876252723Sdim }; 877252723Sdim 878212795Sdim /// \brief Anonymous union that holds extra data associated with the 879212795Sdim /// parsed unqualified-id. 880212795Sdim union { 881212795Sdim /// \brief When Kind == IK_Identifier, the parsed identifier, or when Kind 882212795Sdim /// == IK_UserLiteralId, the identifier suffix. 883212795Sdim IdentifierInfo *Identifier; 884212795Sdim 885212795Sdim /// \brief When Kind == IK_OperatorFunctionId, the overloaded operator 886212795Sdim /// that we parsed. 887252723Sdim struct OFI OperatorFunctionId; 888212795Sdim 889212795Sdim /// \brief When Kind == IK_ConversionFunctionId, the type that the 890212795Sdim /// conversion function names. 891212795Sdim UnionParsedType ConversionFunctionId; 892212795Sdim 893212795Sdim /// \brief When Kind == IK_ConstructorName, the class-name of the type 894212795Sdim /// whose constructor is being referenced. 895212795Sdim UnionParsedType ConstructorName; 896212795Sdim 897212795Sdim /// \brief When Kind == IK_DestructorName, the type referred to by the 898212795Sdim /// class-name. 899212795Sdim UnionParsedType DestructorName; 900212795Sdim 901212795Sdim /// \brief When Kind == IK_TemplateId or IK_ConstructorTemplateId, 902212795Sdim /// the template-id annotation that contains the template name and 903212795Sdim /// template arguments. 904212795Sdim TemplateIdAnnotation *TemplateId; 905212795Sdim }; 906212795Sdim 907212795Sdim /// \brief The location of the first token that describes this unqualified-id, 908212795Sdim /// which will be the location of the identifier, "operator" keyword, 909212795Sdim /// tilde (for a destructor), or the template name of a template-id. 910212795Sdim SourceLocation StartLocation; 911212795Sdim 912212795Sdim /// \brief The location of the last token that describes this unqualified-id. 913212795Sdim SourceLocation EndLocation; 914212795Sdim 915212795Sdim UnqualifiedId() : Kind(IK_Identifier), Identifier(0) { } 916224145Sdim 917212795Sdim /// \brief Clear out this unqualified-id, setting it to default (invalid) 918212795Sdim /// state. 919245431Sdim void clear() { 920245431Sdim Kind = IK_Identifier; 921245431Sdim Identifier = 0; 922245431Sdim StartLocation = SourceLocation(); 923245431Sdim EndLocation = SourceLocation(); 924245431Sdim } 925212795Sdim 926212795Sdim /// \brief Determine whether this unqualified-id refers to a valid name. 927212795Sdim bool isValid() const { return StartLocation.isValid(); } 928212795Sdim 929212795Sdim /// \brief Determine whether this unqualified-id refers to an invalid name. 930212795Sdim bool isInvalid() const { return !isValid(); } 931212795Sdim 932212795Sdim /// \brief Determine what kind of name we have. 933212795Sdim IdKind getKind() const { return Kind; } 934224145Sdim void setKind(IdKind kind) { Kind = kind; } 935212795Sdim 936212795Sdim /// \brief Specify that this unqualified-id was parsed as an identifier. 937212795Sdim /// 938212795Sdim /// \param Id the parsed identifier. 939212795Sdim /// \param IdLoc the location of the parsed identifier. 940212795Sdim void setIdentifier(const IdentifierInfo *Id, SourceLocation IdLoc) { 941212795Sdim Kind = IK_Identifier; 942212795Sdim Identifier = const_cast<IdentifierInfo *>(Id); 943212795Sdim StartLocation = EndLocation = IdLoc; 944212795Sdim } 945212795Sdim 946212795Sdim /// \brief Specify that this unqualified-id was parsed as an 947212795Sdim /// operator-function-id. 948212795Sdim /// 949212795Sdim /// \param OperatorLoc the location of the 'operator' keyword. 950212795Sdim /// 951212795Sdim /// \param Op the overloaded operator. 952212795Sdim /// 953212795Sdim /// \param SymbolLocations the locations of the individual operator symbols 954212795Sdim /// in the operator. 955212795Sdim void setOperatorFunctionId(SourceLocation OperatorLoc, 956212795Sdim OverloadedOperatorKind Op, 957212795Sdim SourceLocation SymbolLocations[3]); 958212795Sdim 959212795Sdim /// \brief Specify that this unqualified-id was parsed as a 960212795Sdim /// conversion-function-id. 961212795Sdim /// 962212795Sdim /// \param OperatorLoc the location of the 'operator' keyword. 963212795Sdim /// 964212795Sdim /// \param Ty the type to which this conversion function is converting. 965212795Sdim /// 966212795Sdim /// \param EndLoc the location of the last token that makes up the type name. 967212795Sdim void setConversionFunctionId(SourceLocation OperatorLoc, 968212795Sdim ParsedType Ty, 969212795Sdim SourceLocation EndLoc) { 970212795Sdim Kind = IK_ConversionFunctionId; 971212795Sdim StartLocation = OperatorLoc; 972212795Sdim EndLocation = EndLoc; 973212795Sdim ConversionFunctionId = Ty; 974212795Sdim } 975212795Sdim 976212795Sdim /// \brief Specific that this unqualified-id was parsed as a 977212795Sdim /// literal-operator-id. 978212795Sdim /// 979212795Sdim /// \param Id the parsed identifier. 980212795Sdim /// 981212795Sdim /// \param OpLoc the location of the 'operator' keyword. 982212795Sdim /// 983212795Sdim /// \param IdLoc the location of the identifier. 984212795Sdim void setLiteralOperatorId(const IdentifierInfo *Id, SourceLocation OpLoc, 985212795Sdim SourceLocation IdLoc) { 986212795Sdim Kind = IK_LiteralOperatorId; 987212795Sdim Identifier = const_cast<IdentifierInfo *>(Id); 988212795Sdim StartLocation = OpLoc; 989212795Sdim EndLocation = IdLoc; 990212795Sdim } 991212795Sdim 992212795Sdim /// \brief Specify that this unqualified-id was parsed as a constructor name. 993212795Sdim /// 994212795Sdim /// \param ClassType the class type referred to by the constructor name. 995212795Sdim /// 996212795Sdim /// \param ClassNameLoc the location of the class name. 997212795Sdim /// 998212795Sdim /// \param EndLoc the location of the last token that makes up the type name. 999212795Sdim void setConstructorName(ParsedType ClassType, 1000212795Sdim SourceLocation ClassNameLoc, 1001212795Sdim SourceLocation EndLoc) { 1002212795Sdim Kind = IK_ConstructorName; 1003212795Sdim StartLocation = ClassNameLoc; 1004212795Sdim EndLocation = EndLoc; 1005212795Sdim ConstructorName = ClassType; 1006212795Sdim } 1007212795Sdim 1008212795Sdim /// \brief Specify that this unqualified-id was parsed as a 1009212795Sdim /// template-id that names a constructor. 1010212795Sdim /// 1011212795Sdim /// \param TemplateId the template-id annotation that describes the parsed 1012212795Sdim /// template-id. This UnqualifiedId instance will take ownership of the 1013212795Sdim /// \p TemplateId and will free it on destruction. 1014212795Sdim void setConstructorTemplateId(TemplateIdAnnotation *TemplateId); 1015212795Sdim 1016212795Sdim /// \brief Specify that this unqualified-id was parsed as a destructor name. 1017212795Sdim /// 1018212795Sdim /// \param TildeLoc the location of the '~' that introduces the destructor 1019212795Sdim /// name. 1020212795Sdim /// 1021212795Sdim /// \param ClassType the name of the class referred to by the destructor name. 1022212795Sdim void setDestructorName(SourceLocation TildeLoc, 1023212795Sdim ParsedType ClassType, 1024212795Sdim SourceLocation EndLoc) { 1025212795Sdim Kind = IK_DestructorName; 1026212795Sdim StartLocation = TildeLoc; 1027212795Sdim EndLocation = EndLoc; 1028212795Sdim DestructorName = ClassType; 1029212795Sdim } 1030212795Sdim 1031212795Sdim /// \brief Specify that this unqualified-id was parsed as a template-id. 1032212795Sdim /// 1033212795Sdim /// \param TemplateId the template-id annotation that describes the parsed 1034212795Sdim /// template-id. This UnqualifiedId instance will take ownership of the 1035212795Sdim /// \p TemplateId and will free it on destruction. 1036212795Sdim void setTemplateId(TemplateIdAnnotation *TemplateId); 1037212795Sdim 1038212795Sdim /// \brief Return the source range that covers this unqualified-id. 1039235633Sdim SourceRange getSourceRange() const LLVM_READONLY { 1040212795Sdim return SourceRange(StartLocation, EndLocation); 1041212795Sdim } 1042235633Sdim SourceLocation getLocStart() const LLVM_READONLY { return StartLocation; } 1043235633Sdim SourceLocation getLocEnd() const LLVM_READONLY { return EndLocation; } 1044212795Sdim}; 1045245431Sdim 1046245431Sdim/// \brief A set of tokens that has been cached for later parsing. 1047226890Sdimtypedef SmallVector<Token, 4> CachedTokens; 1048212795Sdim 1049245431Sdim/// \brief One instance of this struct is used for each type in a 1050212795Sdim/// declarator that is parsed. 1051212795Sdim/// 1052212795Sdim/// This is intended to be a small value object. 1053212795Sdimstruct DeclaratorChunk { 1054212795Sdim enum { 1055218893Sdim Pointer, Reference, Array, Function, BlockPointer, MemberPointer, Paren 1056212795Sdim } Kind; 1057212795Sdim 1058212795Sdim /// Loc - The place where this type was defined. 1059212795Sdim SourceLocation Loc; 1060212795Sdim /// EndLoc - If valid, the place where this chunck ends. 1061212795Sdim SourceLocation EndLoc; 1062212795Sdim 1063218893Sdim struct TypeInfoCommon { 1064218893Sdim AttributeList *AttrList; 1065218893Sdim }; 1066218893Sdim 1067218893Sdim struct PointerTypeInfo : TypeInfoCommon { 1068252723Sdim /// The type qualifiers: const/volatile/restrict/atomic. 1069252723Sdim unsigned TypeQuals : 4; 1070219077Sdim 1071219077Sdim /// The location of the const-qualifier, if any. 1072219077Sdim unsigned ConstQualLoc; 1073219077Sdim 1074219077Sdim /// The location of the volatile-qualifier, if any. 1075219077Sdim unsigned VolatileQualLoc; 1076219077Sdim 1077219077Sdim /// The location of the restrict-qualifier, if any. 1078219077Sdim unsigned RestrictQualLoc; 1079219077Sdim 1080252723Sdim /// The location of the _Atomic-qualifier, if any. 1081252723Sdim unsigned AtomicQualLoc; 1082252723Sdim 1083212795Sdim void destroy() { 1084212795Sdim } 1085212795Sdim }; 1086212795Sdim 1087218893Sdim struct ReferenceTypeInfo : TypeInfoCommon { 1088212795Sdim /// The type qualifier: restrict. [GNU] C++ extension 1089212795Sdim bool HasRestrict : 1; 1090212795Sdim /// True if this is an lvalue reference, false if it's an rvalue reference. 1091212795Sdim bool LValueRef : 1; 1092212795Sdim void destroy() { 1093212795Sdim } 1094212795Sdim }; 1095212795Sdim 1096218893Sdim struct ArrayTypeInfo : TypeInfoCommon { 1097252723Sdim /// The type qualifiers for the array: const/volatile/restrict/_Atomic. 1098252723Sdim unsigned TypeQuals : 4; 1099212795Sdim 1100212795Sdim /// True if this dimension included the 'static' keyword. 1101212795Sdim bool hasStatic : 1; 1102212795Sdim 1103212795Sdim /// True if this dimension was [*]. In this case, NumElts is null. 1104212795Sdim bool isStar : 1; 1105212795Sdim 1106212795Sdim /// This is the size of the array, or null if [] or [*] was specified. 1107212795Sdim /// Since the parser is multi-purpose, and we don't want to impose a root 1108212795Sdim /// expression class on all clients, NumElts is untyped. 1109212795Sdim Expr *NumElts; 1110218893Sdim 1111212795Sdim void destroy() {} 1112212795Sdim }; 1113212795Sdim 1114212795Sdim /// ParamInfo - An array of paraminfo objects is allocated whenever a function 1115212795Sdim /// declarator is parsed. There are two interesting styles of arguments here: 1116212795Sdim /// K&R-style identifier lists and parameter type lists. K&R-style identifier 1117212795Sdim /// lists will have information about the identifier, but no type information. 1118212795Sdim /// Parameter type lists will have type info (if the actions module provides 1119212795Sdim /// it), but may have null identifier info: e.g. for 'void foo(int X, int)'. 1120212795Sdim struct ParamInfo { 1121212795Sdim IdentifierInfo *Ident; 1122212795Sdim SourceLocation IdentLoc; 1123212795Sdim Decl *Param; 1124212795Sdim 1125212795Sdim /// DefaultArgTokens - When the parameter's default argument 1126212795Sdim /// cannot be parsed immediately (because it occurs within the 1127212795Sdim /// declaration of a member function), it will be stored here as a 1128212795Sdim /// sequence of tokens to be parsed once the class definition is 1129212795Sdim /// complete. Non-NULL indicates that there is a default argument. 1130212795Sdim CachedTokens *DefaultArgTokens; 1131212795Sdim 1132212795Sdim ParamInfo() {} 1133212795Sdim ParamInfo(IdentifierInfo *ident, SourceLocation iloc, 1134212795Sdim Decl *param, 1135212795Sdim CachedTokens *DefArgTokens = 0) 1136212795Sdim : Ident(ident), IdentLoc(iloc), Param(param), 1137212795Sdim DefaultArgTokens(DefArgTokens) {} 1138212795Sdim }; 1139212795Sdim 1140212795Sdim struct TypeAndRange { 1141212795Sdim ParsedType Ty; 1142212795Sdim SourceRange Range; 1143212795Sdim }; 1144212795Sdim 1145218893Sdim struct FunctionTypeInfo : TypeInfoCommon { 1146212795Sdim /// hasPrototype - This is true if the function had at least one typed 1147212795Sdim /// argument. If the function is () or (a,b,c), then it has no prototype, 1148212795Sdim /// and is treated as a K&R-style function. 1149218893Sdim unsigned hasPrototype : 1; 1150212795Sdim 1151212795Sdim /// isVariadic - If this function has a prototype, and if that 1152212795Sdim /// proto ends with ',...)', this is true. When true, EllipsisLoc 1153212795Sdim /// contains the location of the ellipsis. 1154218893Sdim unsigned isVariadic : 1; 1155212795Sdim 1156245431Sdim /// Can this declaration be a constructor-style initializer? 1157245431Sdim unsigned isAmbiguous : 1; 1158245431Sdim 1159218893Sdim /// \brief Whether the ref-qualifier (if any) is an lvalue reference. 1160218893Sdim /// Otherwise, it's an rvalue reference. 1161218893Sdim unsigned RefQualifierIsLValueRef : 1; 1162245431Sdim 1163212795Sdim /// The type qualifiers: const/volatile/restrict. 1164212795Sdim /// The qualifier bitmask values are the same as in QualType. 1165212795Sdim unsigned TypeQuals : 3; 1166212795Sdim 1167221345Sdim /// ExceptionSpecType - An ExceptionSpecificationType value. 1168221345Sdim unsigned ExceptionSpecType : 3; 1169212795Sdim 1170212795Sdim /// DeleteArgInfo - If this is true, we need to delete[] ArgInfo. 1171218893Sdim unsigned DeleteArgInfo : 1; 1172212795Sdim 1173245431Sdim /// HasTrailingReturnType - If this is true, a trailing return type was 1174245431Sdim /// specified. 1175245431Sdim unsigned HasTrailingReturnType : 1; 1176245431Sdim 1177245431Sdim /// The location of the left parenthesis in the source. 1178245431Sdim unsigned LParenLoc; 1179245431Sdim 1180212795Sdim /// When isVariadic is true, the location of the ellipsis in the source. 1181212795Sdim unsigned EllipsisLoc; 1182212795Sdim 1183245431Sdim /// The location of the right parenthesis in the source. 1184245431Sdim unsigned RParenLoc; 1185245431Sdim 1186212795Sdim /// NumArgs - This is the number of formal arguments provided for the 1187212795Sdim /// declarator. 1188212795Sdim unsigned NumArgs; 1189212795Sdim 1190221345Sdim /// NumExceptions - This is the number of types in the dynamic-exception- 1191221345Sdim /// decl, if the function has one. 1192212795Sdim unsigned NumExceptions; 1193212795Sdim 1194218893Sdim /// \brief The location of the ref-qualifier, if any. 1195218893Sdim /// 1196218893Sdim /// If this is an invalid location, there is no ref-qualifier. 1197218893Sdim unsigned RefQualifierLoc; 1198221345Sdim 1199235633Sdim /// \brief The location of the const-qualifier, if any. 1200235633Sdim /// 1201235633Sdim /// If this is an invalid location, there is no const-qualifier. 1202235633Sdim unsigned ConstQualifierLoc; 1203235633Sdim 1204235633Sdim /// \brief The location of the volatile-qualifier, if any. 1205235633Sdim /// 1206235633Sdim /// If this is an invalid location, there is no volatile-qualifier. 1207235633Sdim unsigned VolatileQualifierLoc; 1208235633Sdim 1209224145Sdim /// \brief The location of the 'mutable' qualifer in a lambda-declarator, if 1210224145Sdim /// any. 1211224145Sdim unsigned MutableLoc; 1212224145Sdim 1213245431Sdim /// \brief The location of the keyword introducing the spec, if any. 1214221345Sdim unsigned ExceptionSpecLoc; 1215212795Sdim 1216212795Sdim /// ArgInfo - This is a pointer to a new[]'d array of ParamInfo objects that 1217212795Sdim /// describe the arguments for this function declarator. This is null if 1218212795Sdim /// there are no arguments specified. 1219212795Sdim ParamInfo *ArgInfo; 1220212795Sdim 1221221345Sdim union { 1222221345Sdim /// \brief Pointer to a new[]'d array of TypeAndRange objects that 1223221345Sdim /// contain the types in the function's dynamic exception specification 1224221345Sdim /// and their locations, if there is one. 1225221345Sdim TypeAndRange *Exceptions; 1226212795Sdim 1227221345Sdim /// \brief Pointer to the expression in the noexcept-specifier of this 1228221345Sdim /// function, if it has one. 1229221345Sdim Expr *NoexceptExpr; 1230221345Sdim }; 1231221345Sdim 1232245431Sdim /// \brief If HasTrailingReturnType is true, this is the trailing return 1233245431Sdim /// type specified. 1234245431Sdim UnionParsedType TrailingReturnType; 1235218893Sdim 1236245431Sdim /// \brief Reset the argument list to having zero arguments. 1237245431Sdim /// 1238245431Sdim /// This is used in various places for error recovery. 1239212795Sdim void freeArgs() { 1240212795Sdim if (DeleteArgInfo) { 1241212795Sdim delete[] ArgInfo; 1242212795Sdim DeleteArgInfo = false; 1243212795Sdim } 1244212795Sdim NumArgs = 0; 1245212795Sdim } 1246212795Sdim 1247212795Sdim void destroy() { 1248212795Sdim if (DeleteArgInfo) 1249212795Sdim delete[] ArgInfo; 1250221345Sdim if (getExceptionSpecType() == EST_Dynamic) 1251221345Sdim delete[] Exceptions; 1252212795Sdim } 1253212795Sdim 1254212795Sdim /// isKNRPrototype - Return true if this is a K&R style identifier list, 1255212795Sdim /// like "void foo(a,b,c)". In a function definition, this will be followed 1256212795Sdim /// by the argument type definitions. 1257212795Sdim bool isKNRPrototype() const { 1258212795Sdim return !hasPrototype && NumArgs != 0; 1259212795Sdim } 1260245431Sdim 1261245431Sdim SourceLocation getLParenLoc() const { 1262245431Sdim return SourceLocation::getFromRawEncoding(LParenLoc); 1263245431Sdim } 1264245431Sdim 1265212795Sdim SourceLocation getEllipsisLoc() const { 1266212795Sdim return SourceLocation::getFromRawEncoding(EllipsisLoc); 1267212795Sdim } 1268245431Sdim 1269245431Sdim SourceLocation getRParenLoc() const { 1270245431Sdim return SourceLocation::getFromRawEncoding(RParenLoc); 1271245431Sdim } 1272245431Sdim 1273221345Sdim SourceLocation getExceptionSpecLoc() const { 1274221345Sdim return SourceLocation::getFromRawEncoding(ExceptionSpecLoc); 1275212795Sdim } 1276221345Sdim 1277218893Sdim /// \brief Retrieve the location of the ref-qualifier, if any. 1278218893Sdim SourceLocation getRefQualifierLoc() const { 1279218893Sdim return SourceLocation::getFromRawEncoding(RefQualifierLoc); 1280218893Sdim } 1281221345Sdim 1282235633Sdim /// \brief Retrieve the location of the ref-qualifier, if any. 1283235633Sdim SourceLocation getConstQualifierLoc() const { 1284235633Sdim return SourceLocation::getFromRawEncoding(ConstQualifierLoc); 1285235633Sdim } 1286235633Sdim 1287235633Sdim /// \brief Retrieve the location of the ref-qualifier, if any. 1288235633Sdim SourceLocation getVolatileQualifierLoc() const { 1289235633Sdim return SourceLocation::getFromRawEncoding(VolatileQualifierLoc); 1290235633Sdim } 1291235633Sdim 1292224145Sdim /// \brief Retrieve the location of the 'mutable' qualifier, if any. 1293224145Sdim SourceLocation getMutableLoc() const { 1294224145Sdim return SourceLocation::getFromRawEncoding(MutableLoc); 1295224145Sdim } 1296224145Sdim 1297218893Sdim /// \brief Determine whether this function declaration contains a 1298218893Sdim /// ref-qualifier. 1299218893Sdim bool hasRefQualifier() const { return getRefQualifierLoc().isValid(); } 1300221345Sdim 1301224145Sdim /// \brief Determine whether this lambda-declarator contains a 'mutable' 1302224145Sdim /// qualifier. 1303224145Sdim bool hasMutableQualifier() const { return getMutableLoc().isValid(); } 1304224145Sdim 1305221345Sdim /// \brief Get the type of exception specification this function has. 1306221345Sdim ExceptionSpecificationType getExceptionSpecType() const { 1307221345Sdim return static_cast<ExceptionSpecificationType>(ExceptionSpecType); 1308221345Sdim } 1309245431Sdim 1310245431Sdim /// \brief Determine whether this function declarator had a 1311245431Sdim /// trailing-return-type. 1312245431Sdim bool hasTrailingReturnType() const { return HasTrailingReturnType; } 1313245431Sdim 1314245431Sdim /// \brief Get the trailing-return-type for this function declarator. 1315245431Sdim ParsedType getTrailingReturnType() const { return TrailingReturnType; } 1316212795Sdim }; 1317212795Sdim 1318218893Sdim struct BlockPointerTypeInfo : TypeInfoCommon { 1319212795Sdim /// For now, sema will catch these as invalid. 1320252723Sdim /// The type qualifiers: const/volatile/restrict/_Atomic. 1321252723Sdim unsigned TypeQuals : 4; 1322218893Sdim 1323212795Sdim void destroy() { 1324212795Sdim } 1325212795Sdim }; 1326212795Sdim 1327218893Sdim struct MemberPointerTypeInfo : TypeInfoCommon { 1328252723Sdim /// The type qualifiers: const/volatile/restrict/_Atomic. 1329252723Sdim unsigned TypeQuals : 4; 1330212795Sdim // CXXScopeSpec has a constructor, so it can't be a direct member. 1331212795Sdim // So we need some pointer-aligned storage and a bit of trickery. 1332212795Sdim union { 1333212795Sdim void *Aligner; 1334212795Sdim char Mem[sizeof(CXXScopeSpec)]; 1335212795Sdim } ScopeMem; 1336212795Sdim CXXScopeSpec &Scope() { 1337212795Sdim return *reinterpret_cast<CXXScopeSpec*>(ScopeMem.Mem); 1338212795Sdim } 1339212795Sdim const CXXScopeSpec &Scope() const { 1340212795Sdim return *reinterpret_cast<const CXXScopeSpec*>(ScopeMem.Mem); 1341212795Sdim } 1342212795Sdim void destroy() { 1343212795Sdim Scope().~CXXScopeSpec(); 1344212795Sdim } 1345212795Sdim }; 1346212795Sdim 1347212795Sdim union { 1348218893Sdim TypeInfoCommon Common; 1349212795Sdim PointerTypeInfo Ptr; 1350212795Sdim ReferenceTypeInfo Ref; 1351212795Sdim ArrayTypeInfo Arr; 1352212795Sdim FunctionTypeInfo Fun; 1353212795Sdim BlockPointerTypeInfo Cls; 1354212795Sdim MemberPointerTypeInfo Mem; 1355212795Sdim }; 1356212795Sdim 1357212795Sdim void destroy() { 1358212795Sdim switch (Kind) { 1359212795Sdim case DeclaratorChunk::Function: return Fun.destroy(); 1360212795Sdim case DeclaratorChunk::Pointer: return Ptr.destroy(); 1361212795Sdim case DeclaratorChunk::BlockPointer: return Cls.destroy(); 1362212795Sdim case DeclaratorChunk::Reference: return Ref.destroy(); 1363212795Sdim case DeclaratorChunk::Array: return Arr.destroy(); 1364212795Sdim case DeclaratorChunk::MemberPointer: return Mem.destroy(); 1365218893Sdim case DeclaratorChunk::Paren: return; 1366212795Sdim } 1367212795Sdim } 1368212795Sdim 1369245431Sdim /// \brief If there are attributes applied to this declaratorchunk, return 1370212795Sdim /// them. 1371212795Sdim const AttributeList *getAttrs() const { 1372218893Sdim return Common.AttrList; 1373212795Sdim } 1374212795Sdim 1375218893Sdim AttributeList *&getAttrListRef() { 1376218893Sdim return Common.AttrList; 1377218893Sdim } 1378212795Sdim 1379245431Sdim /// \brief Return a DeclaratorChunk for a pointer. 1380212795Sdim static DeclaratorChunk getPointer(unsigned TypeQuals, SourceLocation Loc, 1381219077Sdim SourceLocation ConstQualLoc, 1382219077Sdim SourceLocation VolatileQualLoc, 1383221345Sdim SourceLocation RestrictQualLoc) { 1384212795Sdim DeclaratorChunk I; 1385219077Sdim I.Kind = Pointer; 1386219077Sdim I.Loc = Loc; 1387219077Sdim I.Ptr.TypeQuals = TypeQuals; 1388219077Sdim I.Ptr.ConstQualLoc = ConstQualLoc.getRawEncoding(); 1389219077Sdim I.Ptr.VolatileQualLoc = VolatileQualLoc.getRawEncoding(); 1390219077Sdim I.Ptr.RestrictQualLoc = RestrictQualLoc.getRawEncoding(); 1391221345Sdim I.Ptr.AttrList = 0; 1392212795Sdim return I; 1393212795Sdim } 1394212795Sdim 1395245431Sdim /// \brief Return a DeclaratorChunk for a reference. 1396212795Sdim static DeclaratorChunk getReference(unsigned TypeQuals, SourceLocation Loc, 1397218893Sdim bool lvalue) { 1398212795Sdim DeclaratorChunk I; 1399212795Sdim I.Kind = Reference; 1400212795Sdim I.Loc = Loc; 1401212795Sdim I.Ref.HasRestrict = (TypeQuals & DeclSpec::TQ_restrict) != 0; 1402212795Sdim I.Ref.LValueRef = lvalue; 1403221345Sdim I.Ref.AttrList = 0; 1404212795Sdim return I; 1405212795Sdim } 1406212795Sdim 1407245431Sdim /// \brief Return a DeclaratorChunk for an array. 1408218893Sdim static DeclaratorChunk getArray(unsigned TypeQuals, 1409218893Sdim bool isStatic, bool isStar, Expr *NumElts, 1410212795Sdim SourceLocation LBLoc, SourceLocation RBLoc) { 1411212795Sdim DeclaratorChunk I; 1412212795Sdim I.Kind = Array; 1413212795Sdim I.Loc = LBLoc; 1414212795Sdim I.EndLoc = RBLoc; 1415221345Sdim I.Arr.AttrList = 0; 1416212795Sdim I.Arr.TypeQuals = TypeQuals; 1417212795Sdim I.Arr.hasStatic = isStatic; 1418212795Sdim I.Arr.isStar = isStar; 1419212795Sdim I.Arr.NumElts = NumElts; 1420212795Sdim return I; 1421212795Sdim } 1422212795Sdim 1423212795Sdim /// DeclaratorChunk::getFunction - Return a DeclaratorChunk for a function. 1424212795Sdim /// "TheDeclarator" is the declarator that this will be added to. 1425245431Sdim static DeclaratorChunk getFunction(bool hasProto, 1426245431Sdim bool isAmbiguous, 1427245431Sdim SourceLocation LParenLoc, 1428245431Sdim ParamInfo *ArgInfo, unsigned NumArgs, 1429212795Sdim SourceLocation EllipsisLoc, 1430245431Sdim SourceLocation RParenLoc, 1431245431Sdim unsigned TypeQuals, 1432218893Sdim bool RefQualifierIsLvalueRef, 1433218893Sdim SourceLocation RefQualifierLoc, 1434235633Sdim SourceLocation ConstQualifierLoc, 1435235633Sdim SourceLocation VolatileQualifierLoc, 1436224145Sdim SourceLocation MutableLoc, 1437221345Sdim ExceptionSpecificationType ESpecType, 1438221345Sdim SourceLocation ESpecLoc, 1439212795Sdim ParsedType *Exceptions, 1440212795Sdim SourceRange *ExceptionRanges, 1441212795Sdim unsigned NumExceptions, 1442221345Sdim Expr *NoexceptExpr, 1443221345Sdim SourceLocation LocalRangeBegin, 1444221345Sdim SourceLocation LocalRangeEnd, 1445218893Sdim Declarator &TheDeclarator, 1446245431Sdim TypeResult TrailingReturnType = 1447245431Sdim TypeResult()); 1448212795Sdim 1449245431Sdim /// \brief Return a DeclaratorChunk for a block. 1450221345Sdim static DeclaratorChunk getBlockPointer(unsigned TypeQuals, 1451221345Sdim SourceLocation Loc) { 1452212795Sdim DeclaratorChunk I; 1453212795Sdim I.Kind = BlockPointer; 1454212795Sdim I.Loc = Loc; 1455212795Sdim I.Cls.TypeQuals = TypeQuals; 1456221345Sdim I.Cls.AttrList = 0; 1457212795Sdim return I; 1458212795Sdim } 1459212795Sdim 1460212795Sdim static DeclaratorChunk getMemberPointer(const CXXScopeSpec &SS, 1461212795Sdim unsigned TypeQuals, 1462221345Sdim SourceLocation Loc) { 1463212795Sdim DeclaratorChunk I; 1464212795Sdim I.Kind = MemberPointer; 1465212795Sdim I.Loc = Loc; 1466212795Sdim I.Mem.TypeQuals = TypeQuals; 1467221345Sdim I.Mem.AttrList = 0; 1468212795Sdim new (I.Mem.ScopeMem.Mem) CXXScopeSpec(SS); 1469212795Sdim return I; 1470212795Sdim } 1471218893Sdim 1472245431Sdim /// \brief Return a DeclaratorChunk for a paren. 1473218893Sdim static DeclaratorChunk getParen(SourceLocation LParenLoc, 1474218893Sdim SourceLocation RParenLoc) { 1475218893Sdim DeclaratorChunk I; 1476218893Sdim I.Kind = Paren; 1477218893Sdim I.Loc = LParenLoc; 1478218893Sdim I.EndLoc = RParenLoc; 1479218893Sdim I.Common.AttrList = 0; 1480218893Sdim return I; 1481218893Sdim } 1482218893Sdim 1483252723Sdim bool isParen() const { 1484252723Sdim return Kind == Paren; 1485252723Sdim } 1486212795Sdim}; 1487212795Sdim 1488235633Sdim/// \brief Described the kind of function definition (if any) provided for 1489235633Sdim/// a function. 1490235633Sdimenum FunctionDefinitionKind { 1491235633Sdim FDK_Declaration, 1492235633Sdim FDK_Definition, 1493235633Sdim FDK_Defaulted, 1494235633Sdim FDK_Deleted 1495235633Sdim}; 1496245431Sdim 1497245431Sdim/// \brief Information about one declarator, including the parsed type 1498245431Sdim/// information and the identifier. 1499212795Sdim/// 1500245431Sdim/// When the declarator is fully formed, this is turned into the appropriate 1501245431Sdim/// Decl object. 1502245431Sdim/// 1503212795Sdim/// Declarators come in two types: normal declarators and abstract declarators. 1504212795Sdim/// Abstract declarators are used when parsing types, and don't have an 1505212795Sdim/// identifier. Normal declarators do have ID's. 1506212795Sdim/// 1507212795Sdim/// Instances of this class should be a transient object that lives on the 1508212795Sdim/// stack, not objects that are allocated in large quantities on the heap. 1509212795Sdimclass Declarator { 1510212795Sdimpublic: 1511212795Sdim enum TheContext { 1512212795Sdim FileContext, // File scope declaration. 1513212795Sdim PrototypeContext, // Within a function prototype. 1514226890Sdim ObjCResultContext, // An ObjC method result type. 1515226890Sdim ObjCParameterContext,// An ObjC method parameter type. 1516212795Sdim KNRTypeListContext, // K&R type definition list for formals. 1517212795Sdim TypeNameContext, // Abstract declarator for types. 1518212795Sdim MemberContext, // Struct/Union field. 1519212795Sdim BlockContext, // Declaration within a block in a function. 1520212795Sdim ForContext, // Declaration within first part of a for loop. 1521212795Sdim ConditionContext, // Condition declaration in a C++ if/switch/while/for. 1522212795Sdim TemplateParamContext,// Within a template parameter list. 1523224145Sdim CXXNewContext, // C++ new-expression. 1524212795Sdim CXXCatchContext, // C++ catch exception-declaration 1525224145Sdim ObjCCatchContext, // Objective-C catch exception-declaration 1526252723Sdim BlockLiteralContext, // Block literal declarator. 1527235633Sdim LambdaExprContext, // Lambda-expression declarator. 1528263509Sdim LambdaExprParameterContext, // Lambda-expression parameter declarator. 1529252723Sdim ConversionIdContext, // C++ conversion-type-id. 1530235633Sdim TrailingReturnContext, // C++11 trailing-type-specifier. 1531221345Sdim TemplateTypeArgContext, // Template type argument. 1532235633Sdim AliasDeclContext, // C++11 alias-declaration. 1533235633Sdim AliasTemplateContext // C++11 alias-declaration template. 1534212795Sdim }; 1535212795Sdim 1536212795Sdimprivate: 1537212795Sdim const DeclSpec &DS; 1538212795Sdim CXXScopeSpec SS; 1539212795Sdim UnqualifiedId Name; 1540212795Sdim SourceRange Range; 1541212795Sdim 1542245431Sdim /// \brief Where we are parsing this declarator. 1543212795Sdim TheContext Context; 1544212795Sdim 1545212795Sdim /// DeclTypeInfo - This holds each type that the declarator includes as it is 1546212795Sdim /// parsed. This is pushed from the identifier out, which means that element 1547212795Sdim /// #0 will be the most closely bound to the identifier, and 1548212795Sdim /// DeclTypeInfo.back() will be the least closely bound. 1549226890Sdim SmallVector<DeclaratorChunk, 8> DeclTypeInfo; 1550212795Sdim 1551212795Sdim /// InvalidType - Set by Sema::GetTypeForDeclarator(). 1552212795Sdim bool InvalidType : 1; 1553212795Sdim 1554212795Sdim /// GroupingParens - Set by Parser::ParseParenDeclarator(). 1555212795Sdim bool GroupingParens : 1; 1556212795Sdim 1557235633Sdim /// FunctionDefinition - Is this Declarator for a function or member 1558235633Sdim /// definition and, if so, what kind? 1559235633Sdim /// 1560235633Sdim /// Actually a FunctionDefinitionKind. 1561235633Sdim unsigned FunctionDefinition : 2; 1562226890Sdim 1563245431Sdim /// \brief Is this Declarator a redeclaration? 1564226890Sdim bool Redeclaration : 1; 1565226890Sdim 1566221345Sdim /// Attrs - Attributes. 1567221345Sdim ParsedAttributes Attrs; 1568212795Sdim 1569245431Sdim /// \brief The asm label, if specified. 1570212795Sdim Expr *AsmLabel; 1571212795Sdim 1572212795Sdim /// InlineParams - This is a local array used for the first function decl 1573212795Sdim /// chunk to avoid going to the heap for the common case when we have one 1574212795Sdim /// function chunk in the declarator. 1575212795Sdim DeclaratorChunk::ParamInfo InlineParams[16]; 1576212795Sdim bool InlineParamsUsed; 1577212795Sdim 1578245431Sdim /// \brief true if the declaration is preceded by \c __extension__. 1579212795Sdim bool Extension : 1; 1580212795Sdim 1581235633Sdim /// \brief If this is the second or subsequent declarator in this declaration, 1582235633Sdim /// the location of the comma before this declarator. 1583235633Sdim SourceLocation CommaLoc; 1584235633Sdim 1585218893Sdim /// \brief If provided, the source location of the ellipsis used to describe 1586218893Sdim /// this declarator as a parameter pack. 1587218893Sdim SourceLocation EllipsisLoc; 1588218893Sdim 1589212795Sdim friend struct DeclaratorChunk; 1590212795Sdim 1591212795Sdimpublic: 1592212795Sdim Declarator(const DeclSpec &ds, TheContext C) 1593212795Sdim : DS(ds), Range(ds.getSourceRange()), Context(C), 1594212795Sdim InvalidType(DS.getTypeSpecType() == DeclSpec::TST_error), 1595235633Sdim GroupingParens(false), FunctionDefinition(FDK_Declaration), 1596235633Sdim Redeclaration(false), 1597226890Sdim Attrs(ds.getAttributePool().getFactory()), AsmLabel(0), 1598226890Sdim InlineParamsUsed(false), Extension(false) { 1599212795Sdim } 1600212795Sdim 1601212795Sdim ~Declarator() { 1602212795Sdim clear(); 1603212795Sdim } 1604212795Sdim /// getDeclSpec - Return the declaration-specifier that this declarator was 1605212795Sdim /// declared with. 1606212795Sdim const DeclSpec &getDeclSpec() const { return DS; } 1607212795Sdim 1608212795Sdim /// getMutableDeclSpec - Return a non-const version of the DeclSpec. This 1609212795Sdim /// should be used with extreme care: declspecs can often be shared between 1610212795Sdim /// multiple declarators, so mutating the DeclSpec affects all of the 1611212795Sdim /// Declarators. This should only be done when the declspec is known to not 1612212795Sdim /// be shared or when in error recovery etc. 1613212795Sdim DeclSpec &getMutableDeclSpec() { return const_cast<DeclSpec &>(DS); } 1614212795Sdim 1615221345Sdim AttributePool &getAttributePool() const { 1616221345Sdim return Attrs.getPool(); 1617221345Sdim } 1618221345Sdim 1619212795Sdim /// getCXXScopeSpec - Return the C++ scope specifier (global scope or 1620212795Sdim /// nested-name-specifier) that is part of the declarator-id. 1621212795Sdim const CXXScopeSpec &getCXXScopeSpec() const { return SS; } 1622212795Sdim CXXScopeSpec &getCXXScopeSpec() { return SS; } 1623212795Sdim 1624212795Sdim /// \brief Retrieve the name specified by this declarator. 1625212795Sdim UnqualifiedId &getName() { return Name; } 1626212795Sdim 1627212795Sdim TheContext getContext() const { return Context; } 1628212795Sdim 1629221345Sdim bool isPrototypeContext() const { 1630226890Sdim return (Context == PrototypeContext || 1631226890Sdim Context == ObjCParameterContext || 1632263509Sdim Context == ObjCResultContext || 1633263509Sdim Context == LambdaExprParameterContext); 1634221345Sdim } 1635221345Sdim 1636245431Sdim /// \brief Get the source range that spans this declarator. 1637235633Sdim const SourceRange &getSourceRange() const LLVM_READONLY { return Range; } 1638235633Sdim SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); } 1639235633Sdim SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); } 1640212795Sdim 1641212795Sdim void SetSourceRange(SourceRange R) { Range = R; } 1642212795Sdim /// SetRangeBegin - Set the start of the source range to Loc, unless it's 1643212795Sdim /// invalid. 1644212795Sdim void SetRangeBegin(SourceLocation Loc) { 1645212795Sdim if (!Loc.isInvalid()) 1646212795Sdim Range.setBegin(Loc); 1647212795Sdim } 1648212795Sdim /// SetRangeEnd - Set the end of the source range to Loc, unless it's invalid. 1649212795Sdim void SetRangeEnd(SourceLocation Loc) { 1650212795Sdim if (!Loc.isInvalid()) 1651212795Sdim Range.setEnd(Loc); 1652212795Sdim } 1653212795Sdim /// ExtendWithDeclSpec - Extend the declarator source range to include the 1654212795Sdim /// given declspec, unless its location is invalid. Adopts the range start if 1655212795Sdim /// the current range start is invalid. 1656212795Sdim void ExtendWithDeclSpec(const DeclSpec &DS) { 1657212795Sdim const SourceRange &SR = DS.getSourceRange(); 1658212795Sdim if (Range.getBegin().isInvalid()) 1659212795Sdim Range.setBegin(SR.getBegin()); 1660212795Sdim if (!SR.getEnd().isInvalid()) 1661212795Sdim Range.setEnd(SR.getEnd()); 1662212795Sdim } 1663212795Sdim 1664245431Sdim /// \brief Reset the contents of this Declarator. 1665212795Sdim void clear() { 1666212795Sdim SS.clear(); 1667212795Sdim Name.clear(); 1668212795Sdim Range = DS.getSourceRange(); 1669212795Sdim 1670212795Sdim for (unsigned i = 0, e = DeclTypeInfo.size(); i != e; ++i) 1671212795Sdim DeclTypeInfo[i].destroy(); 1672212795Sdim DeclTypeInfo.clear(); 1673221345Sdim Attrs.clear(); 1674212795Sdim AsmLabel = 0; 1675212795Sdim InlineParamsUsed = false; 1676235633Sdim CommaLoc = SourceLocation(); 1677235633Sdim EllipsisLoc = SourceLocation(); 1678212795Sdim } 1679212795Sdim 1680212795Sdim /// mayOmitIdentifier - Return true if the identifier is either optional or 1681212795Sdim /// not allowed. This is true for typenames, prototypes, and template 1682212795Sdim /// parameter lists. 1683212795Sdim bool mayOmitIdentifier() const { 1684221345Sdim switch (Context) { 1685221345Sdim case FileContext: 1686221345Sdim case KNRTypeListContext: 1687221345Sdim case MemberContext: 1688221345Sdim case BlockContext: 1689221345Sdim case ForContext: 1690221345Sdim case ConditionContext: 1691221345Sdim return false; 1692221345Sdim 1693221345Sdim case TypeNameContext: 1694221345Sdim case AliasDeclContext: 1695223017Sdim case AliasTemplateContext: 1696221345Sdim case PrototypeContext: 1697263509Sdim case LambdaExprParameterContext: 1698226890Sdim case ObjCParameterContext: 1699226890Sdim case ObjCResultContext: 1700221345Sdim case TemplateParamContext: 1701224145Sdim case CXXNewContext: 1702221345Sdim case CXXCatchContext: 1703224145Sdim case ObjCCatchContext: 1704221345Sdim case BlockLiteralContext: 1705235633Sdim case LambdaExprContext: 1706252723Sdim case ConversionIdContext: 1707221345Sdim case TemplateTypeArgContext: 1708235633Sdim case TrailingReturnContext: 1709221345Sdim return true; 1710221345Sdim } 1711221345Sdim llvm_unreachable("unknown context kind!"); 1712212795Sdim } 1713212795Sdim 1714212795Sdim /// mayHaveIdentifier - Return true if the identifier is either optional or 1715212795Sdim /// required. This is true for normal declarators and prototypes, but not 1716212795Sdim /// typenames. 1717212795Sdim bool mayHaveIdentifier() const { 1718221345Sdim switch (Context) { 1719221345Sdim case FileContext: 1720221345Sdim case KNRTypeListContext: 1721221345Sdim case MemberContext: 1722221345Sdim case BlockContext: 1723221345Sdim case ForContext: 1724221345Sdim case ConditionContext: 1725221345Sdim case PrototypeContext: 1726263509Sdim case LambdaExprParameterContext: 1727221345Sdim case TemplateParamContext: 1728221345Sdim case CXXCatchContext: 1729224145Sdim case ObjCCatchContext: 1730221345Sdim return true; 1731221345Sdim 1732221345Sdim case TypeNameContext: 1733224145Sdim case CXXNewContext: 1734221345Sdim case AliasDeclContext: 1735223017Sdim case AliasTemplateContext: 1736226890Sdim case ObjCParameterContext: 1737226890Sdim case ObjCResultContext: 1738221345Sdim case BlockLiteralContext: 1739235633Sdim case LambdaExprContext: 1740252723Sdim case ConversionIdContext: 1741221345Sdim case TemplateTypeArgContext: 1742235633Sdim case TrailingReturnContext: 1743221345Sdim return false; 1744221345Sdim } 1745221345Sdim llvm_unreachable("unknown context kind!"); 1746212795Sdim } 1747212795Sdim 1748263509Sdim /// diagnoseIdentifier - Return true if the identifier is prohibited and 1749263509Sdim /// should be diagnosed (because it cannot be anything else). 1750263509Sdim bool diagnoseIdentifier() const { 1751263509Sdim switch (Context) { 1752263509Sdim case FileContext: 1753263509Sdim case KNRTypeListContext: 1754263509Sdim case MemberContext: 1755263509Sdim case BlockContext: 1756263509Sdim case ForContext: 1757263509Sdim case ConditionContext: 1758263509Sdim case PrototypeContext: 1759263509Sdim case LambdaExprParameterContext: 1760263509Sdim case TemplateParamContext: 1761263509Sdim case CXXCatchContext: 1762263509Sdim case ObjCCatchContext: 1763263509Sdim case TypeNameContext: 1764263509Sdim case ConversionIdContext: 1765263509Sdim case ObjCParameterContext: 1766263509Sdim case ObjCResultContext: 1767263509Sdim case BlockLiteralContext: 1768263509Sdim case CXXNewContext: 1769263509Sdim case LambdaExprContext: 1770263509Sdim return false; 1771263509Sdim 1772263509Sdim case AliasDeclContext: 1773263509Sdim case AliasTemplateContext: 1774263509Sdim case TemplateTypeArgContext: 1775263509Sdim case TrailingReturnContext: 1776263509Sdim return true; 1777263509Sdim } 1778263509Sdim llvm_unreachable("unknown context kind!"); 1779263509Sdim } 1780263509Sdim 1781212795Sdim /// mayBeFollowedByCXXDirectInit - Return true if the declarator can be 1782212795Sdim /// followed by a C++ direct initializer, e.g. "int x(1);". 1783212795Sdim bool mayBeFollowedByCXXDirectInit() const { 1784221345Sdim if (hasGroupingParens()) return false; 1785221345Sdim 1786235633Sdim if (getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_typedef) 1787235633Sdim return false; 1788235633Sdim 1789235633Sdim if (getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_extern && 1790235633Sdim Context != FileContext) 1791235633Sdim return false; 1792235633Sdim 1793235633Sdim // Special names can't have direct initializers. 1794235633Sdim if (Name.getKind() != UnqualifiedId::IK_Identifier) 1795235633Sdim return false; 1796235633Sdim 1797221345Sdim switch (Context) { 1798221345Sdim case FileContext: 1799221345Sdim case BlockContext: 1800221345Sdim case ForContext: 1801221345Sdim return true; 1802221345Sdim 1803235633Sdim case ConditionContext: 1804235633Sdim // This may not be followed by a direct initializer, but it can't be a 1805235633Sdim // function declaration either, and we'd prefer to perform a tentative 1806235633Sdim // parse in order to produce the right diagnostic. 1807235633Sdim return true; 1808235633Sdim 1809221345Sdim case KNRTypeListContext: 1810221345Sdim case MemberContext: 1811221345Sdim case PrototypeContext: 1812263509Sdim case LambdaExprParameterContext: 1813226890Sdim case ObjCParameterContext: 1814226890Sdim case ObjCResultContext: 1815221345Sdim case TemplateParamContext: 1816221345Sdim case CXXCatchContext: 1817224145Sdim case ObjCCatchContext: 1818221345Sdim case TypeNameContext: 1819224145Sdim case CXXNewContext: 1820221345Sdim case AliasDeclContext: 1821223017Sdim case AliasTemplateContext: 1822221345Sdim case BlockLiteralContext: 1823235633Sdim case LambdaExprContext: 1824252723Sdim case ConversionIdContext: 1825221345Sdim case TemplateTypeArgContext: 1826235633Sdim case TrailingReturnContext: 1827221345Sdim return false; 1828221345Sdim } 1829221345Sdim llvm_unreachable("unknown context kind!"); 1830212795Sdim } 1831212795Sdim 1832212795Sdim /// isPastIdentifier - Return true if we have parsed beyond the point where 1833212795Sdim /// the 1834212795Sdim bool isPastIdentifier() const { return Name.isValid(); } 1835212795Sdim 1836212795Sdim /// hasName - Whether this declarator has a name, which might be an 1837212795Sdim /// identifier (accessible via getIdentifier()) or some kind of 1838212795Sdim /// special C++ name (constructor, destructor, etc.). 1839212795Sdim bool hasName() const { 1840212795Sdim return Name.getKind() != UnqualifiedId::IK_Identifier || Name.Identifier; 1841212795Sdim } 1842212795Sdim 1843212795Sdim IdentifierInfo *getIdentifier() const { 1844212795Sdim if (Name.getKind() == UnqualifiedId::IK_Identifier) 1845212795Sdim return Name.Identifier; 1846212795Sdim 1847212795Sdim return 0; 1848212795Sdim } 1849212795Sdim SourceLocation getIdentifierLoc() const { return Name.StartLocation; } 1850212795Sdim 1851212795Sdim /// \brief Set the name of this declarator to be the given identifier. 1852212795Sdim void SetIdentifier(IdentifierInfo *Id, SourceLocation IdLoc) { 1853212795Sdim Name.setIdentifier(Id, IdLoc); 1854212795Sdim } 1855212795Sdim 1856212795Sdim /// AddTypeInfo - Add a chunk to this declarator. Also extend the range to 1857212795Sdim /// EndLoc, which should be the last token of the chunk. 1858221345Sdim void AddTypeInfo(const DeclaratorChunk &TI, 1859221345Sdim ParsedAttributes &attrs, 1860221345Sdim SourceLocation EndLoc) { 1861212795Sdim DeclTypeInfo.push_back(TI); 1862221345Sdim DeclTypeInfo.back().getAttrListRef() = attrs.getList(); 1863221345Sdim getAttributePool().takeAllFrom(attrs.getPool()); 1864221345Sdim 1865212795Sdim if (!EndLoc.isInvalid()) 1866212795Sdim SetRangeEnd(EndLoc); 1867212795Sdim } 1868212795Sdim 1869245431Sdim /// \brief Add a new innermost chunk to this declarator. 1870218893Sdim void AddInnermostTypeInfo(const DeclaratorChunk &TI) { 1871218893Sdim DeclTypeInfo.insert(DeclTypeInfo.begin(), TI); 1872218893Sdim } 1873218893Sdim 1874245431Sdim /// \brief Return the number of types applied to this declarator. 1875212795Sdim unsigned getNumTypeObjects() const { return DeclTypeInfo.size(); } 1876212795Sdim 1877212795Sdim /// Return the specified TypeInfo from this declarator. TypeInfo #0 is 1878212795Sdim /// closest to the identifier. 1879212795Sdim const DeclaratorChunk &getTypeObject(unsigned i) const { 1880212795Sdim assert(i < DeclTypeInfo.size() && "Invalid type chunk"); 1881212795Sdim return DeclTypeInfo[i]; 1882212795Sdim } 1883212795Sdim DeclaratorChunk &getTypeObject(unsigned i) { 1884212795Sdim assert(i < DeclTypeInfo.size() && "Invalid type chunk"); 1885212795Sdim return DeclTypeInfo[i]; 1886212795Sdim } 1887212795Sdim 1888252723Sdim void DropFirstTypeObject() { 1889212795Sdim assert(!DeclTypeInfo.empty() && "No type chunks to drop."); 1890212795Sdim DeclTypeInfo.front().destroy(); 1891212795Sdim DeclTypeInfo.erase(DeclTypeInfo.begin()); 1892212795Sdim } 1893212795Sdim 1894252723Sdim /// Return the innermost (closest to the declarator) chunk of this 1895252723Sdim /// declarator that is not a parens chunk, or null if there are no 1896252723Sdim /// non-parens chunks. 1897252723Sdim const DeclaratorChunk *getInnermostNonParenChunk() const { 1898252723Sdim for (unsigned i = 0, i_end = DeclTypeInfo.size(); i < i_end; ++i) { 1899252723Sdim if (!DeclTypeInfo[i].isParen()) 1900252723Sdim return &DeclTypeInfo[i]; 1901252723Sdim } 1902252723Sdim return 0; 1903252723Sdim } 1904252723Sdim 1905252723Sdim /// Return the outermost (furthest from the declarator) chunk of 1906252723Sdim /// this declarator that is not a parens chunk, or null if there are 1907252723Sdim /// no non-parens chunks. 1908252723Sdim const DeclaratorChunk *getOutermostNonParenChunk() const { 1909252723Sdim for (unsigned i = DeclTypeInfo.size(), i_end = 0; i != i_end; --i) { 1910252723Sdim if (!DeclTypeInfo[i-1].isParen()) 1911252723Sdim return &DeclTypeInfo[i-1]; 1912252723Sdim } 1913252723Sdim return 0; 1914252723Sdim } 1915252723Sdim 1916223017Sdim /// isArrayOfUnknownBound - This method returns true if the declarator 1917223017Sdim /// is a declarator for an array of unknown bound (looking through 1918223017Sdim /// parentheses). 1919223017Sdim bool isArrayOfUnknownBound() const { 1920252723Sdim const DeclaratorChunk *chunk = getInnermostNonParenChunk(); 1921252723Sdim return (chunk && chunk->Kind == DeclaratorChunk::Array && 1922252723Sdim !chunk->Arr.NumElts); 1923223017Sdim } 1924223017Sdim 1925218893Sdim /// isFunctionDeclarator - This method returns true if the declarator 1926218893Sdim /// is a function declarator (looking through parentheses). 1927218893Sdim /// If true is returned, then the reference type parameter idx is 1928218893Sdim /// assigned with the index of the declaration chunk. 1929218893Sdim bool isFunctionDeclarator(unsigned& idx) const { 1930218893Sdim for (unsigned i = 0, i_end = DeclTypeInfo.size(); i < i_end; ++i) { 1931218893Sdim switch (DeclTypeInfo[i].Kind) { 1932218893Sdim case DeclaratorChunk::Function: 1933218893Sdim idx = i; 1934218893Sdim return true; 1935218893Sdim case DeclaratorChunk::Paren: 1936218893Sdim continue; 1937218893Sdim case DeclaratorChunk::Pointer: 1938218893Sdim case DeclaratorChunk::Reference: 1939218893Sdim case DeclaratorChunk::Array: 1940218893Sdim case DeclaratorChunk::BlockPointer: 1941218893Sdim case DeclaratorChunk::MemberPointer: 1942218893Sdim return false; 1943218893Sdim } 1944218893Sdim llvm_unreachable("Invalid type chunk"); 1945218893Sdim } 1946218893Sdim return false; 1947218893Sdim } 1948218893Sdim 1949212795Sdim /// isFunctionDeclarator - Once this declarator is fully parsed and formed, 1950218893Sdim /// this method returns true if the identifier is a function declarator 1951218893Sdim /// (looking through parentheses). 1952212795Sdim bool isFunctionDeclarator() const { 1953218893Sdim unsigned index; 1954218893Sdim return isFunctionDeclarator(index); 1955212795Sdim } 1956212795Sdim 1957218893Sdim /// getFunctionTypeInfo - Retrieves the function type info object 1958218893Sdim /// (looking through parentheses). 1959218893Sdim DeclaratorChunk::FunctionTypeInfo &getFunctionTypeInfo() { 1960218893Sdim assert(isFunctionDeclarator() && "Not a function declarator!"); 1961218893Sdim unsigned index = 0; 1962218893Sdim isFunctionDeclarator(index); 1963218893Sdim return DeclTypeInfo[index].Fun; 1964218893Sdim } 1965218893Sdim 1966218893Sdim /// getFunctionTypeInfo - Retrieves the function type info object 1967218893Sdim /// (looking through parentheses). 1968218893Sdim const DeclaratorChunk::FunctionTypeInfo &getFunctionTypeInfo() const { 1969218893Sdim return const_cast<Declarator*>(this)->getFunctionTypeInfo(); 1970218893Sdim } 1971218893Sdim 1972224145Sdim /// \brief Determine whether the declaration that will be produced from 1973224145Sdim /// this declaration will be a function. 1974224145Sdim /// 1975224145Sdim /// A declaration can declare a function even if the declarator itself 1976224145Sdim /// isn't a function declarator, if the type specifier refers to a function 1977224145Sdim /// type. This routine checks for both cases. 1978224145Sdim bool isDeclarationOfFunction() const; 1979252723Sdim 1980252723Sdim /// \brief Return true if this declaration appears in a context where a 1981252723Sdim /// function declarator would be a function declaration. 1982252723Sdim bool isFunctionDeclarationContext() const { 1983252723Sdim if (getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_typedef) 1984252723Sdim return false; 1985252723Sdim 1986252723Sdim switch (Context) { 1987252723Sdim case FileContext: 1988252723Sdim case MemberContext: 1989252723Sdim case BlockContext: 1990252723Sdim return true; 1991252723Sdim 1992252723Sdim case ForContext: 1993252723Sdim case ConditionContext: 1994252723Sdim case KNRTypeListContext: 1995252723Sdim case TypeNameContext: 1996252723Sdim case AliasDeclContext: 1997252723Sdim case AliasTemplateContext: 1998252723Sdim case PrototypeContext: 1999263509Sdim case LambdaExprParameterContext: 2000252723Sdim case ObjCParameterContext: 2001252723Sdim case ObjCResultContext: 2002252723Sdim case TemplateParamContext: 2003252723Sdim case CXXNewContext: 2004252723Sdim case CXXCatchContext: 2005252723Sdim case ObjCCatchContext: 2006252723Sdim case BlockLiteralContext: 2007252723Sdim case LambdaExprContext: 2008252723Sdim case ConversionIdContext: 2009252723Sdim case TemplateTypeArgContext: 2010252723Sdim case TrailingReturnContext: 2011252723Sdim return false; 2012252723Sdim } 2013252723Sdim llvm_unreachable("unknown context kind!"); 2014252723Sdim } 2015224145Sdim 2016252723Sdim /// \brief Return true if a function declarator at this position would be a 2017252723Sdim /// function declaration. 2018252723Sdim bool isFunctionDeclaratorAFunctionDeclaration() const { 2019252723Sdim if (!isFunctionDeclarationContext()) 2020252723Sdim return false; 2021252723Sdim 2022252723Sdim for (unsigned I = 0, N = getNumTypeObjects(); I != N; ++I) 2023252723Sdim if (getTypeObject(I).Kind != DeclaratorChunk::Paren) 2024252723Sdim return false; 2025252723Sdim 2026252723Sdim return true; 2027252723Sdim } 2028252723Sdim 2029221345Sdim /// takeAttributes - Takes attributes from the given parsed-attributes 2030221345Sdim /// set and add them to this declarator. 2031221345Sdim /// 2032212795Sdim /// These examples both add 3 attributes to "var": 2033212795Sdim /// short int var __attribute__((aligned(16),common,deprecated)); 2034212795Sdim /// short int x, __attribute__((aligned(16)) var 2035212795Sdim /// __attribute__((common,deprecated)); 2036212795Sdim /// 2037212795Sdim /// Also extends the range of the declarator. 2038221345Sdim void takeAttributes(ParsedAttributes &attrs, SourceLocation lastLoc) { 2039221345Sdim Attrs.takeAllFrom(attrs); 2040212795Sdim 2041221345Sdim if (!lastLoc.isInvalid()) 2042221345Sdim SetRangeEnd(lastLoc); 2043212795Sdim } 2044212795Sdim 2045221345Sdim const AttributeList *getAttributes() const { return Attrs.getList(); } 2046221345Sdim AttributeList *getAttributes() { return Attrs.getList(); } 2047218893Sdim 2048221345Sdim AttributeList *&getAttrListRef() { return Attrs.getListRef(); } 2049212795Sdim 2050212795Sdim /// hasAttributes - do we contain any attributes? 2051212795Sdim bool hasAttributes() const { 2052218893Sdim if (getAttributes() || getDeclSpec().hasAttributes()) return true; 2053212795Sdim for (unsigned i = 0, e = getNumTypeObjects(); i != e; ++i) 2054212795Sdim if (getTypeObject(i).getAttrs()) 2055212795Sdim return true; 2056212795Sdim return false; 2057212795Sdim } 2058212795Sdim 2059252723Sdim /// \brief Return a source range list of C++11 attributes associated 2060252723Sdim /// with the declarator. 2061263509Sdim void getCXX11AttributeRanges(SmallVectorImpl<SourceRange> &Ranges) { 2062252723Sdim AttributeList *AttrList = Attrs.getList(); 2063252723Sdim while (AttrList) { 2064252723Sdim if (AttrList->isCXX11Attribute()) 2065252723Sdim Ranges.push_back(AttrList->getRange()); 2066252723Sdim AttrList = AttrList->getNext(); 2067252723Sdim } 2068252723Sdim } 2069252723Sdim 2070212795Sdim void setAsmLabel(Expr *E) { AsmLabel = E; } 2071212795Sdim Expr *getAsmLabel() const { return AsmLabel; } 2072212795Sdim 2073212795Sdim void setExtension(bool Val = true) { Extension = Val; } 2074212795Sdim bool getExtension() const { return Extension; } 2075212795Sdim 2076212795Sdim void setInvalidType(bool Val = true) { InvalidType = Val; } 2077212795Sdim bool isInvalidType() const { 2078212795Sdim return InvalidType || DS.getTypeSpecType() == DeclSpec::TST_error; 2079212795Sdim } 2080212795Sdim 2081212795Sdim void setGroupingParens(bool flag) { GroupingParens = flag; } 2082212795Sdim bool hasGroupingParens() const { return GroupingParens; } 2083235633Sdim 2084235633Sdim bool isFirstDeclarator() const { return !CommaLoc.isValid(); } 2085235633Sdim SourceLocation getCommaLoc() const { return CommaLoc; } 2086235633Sdim void setCommaLoc(SourceLocation CL) { CommaLoc = CL; } 2087235633Sdim 2088218893Sdim bool hasEllipsis() const { return EllipsisLoc.isValid(); } 2089218893Sdim SourceLocation getEllipsisLoc() const { return EllipsisLoc; } 2090218893Sdim void setEllipsisLoc(SourceLocation EL) { EllipsisLoc = EL; } 2091226890Sdim 2092235633Sdim void setFunctionDefinitionKind(FunctionDefinitionKind Val) { 2093235633Sdim FunctionDefinition = Val; 2094235633Sdim } 2095235633Sdim 2096235633Sdim bool isFunctionDefinition() const { 2097235633Sdim return getFunctionDefinitionKind() != FDK_Declaration; 2098235633Sdim } 2099235633Sdim 2100235633Sdim FunctionDefinitionKind getFunctionDefinitionKind() const { 2101235633Sdim return (FunctionDefinitionKind)FunctionDefinition; 2102235633Sdim } 2103226890Sdim 2104263509Sdim /// Returns true if this declares a real member and not a friend. 2105263509Sdim bool isFirstDeclarationOfMember() { 2106263509Sdim return getContext() == MemberContext && !getDeclSpec().isFriendSpecified(); 2107263509Sdim } 2108263509Sdim 2109263509Sdim /// Returns true if this declares a static member. This cannot be called on a 2110263509Sdim /// declarator outside of a MemberContext because we won't know until 2111263509Sdim /// redeclaration time if the decl is static. 2112263509Sdim bool isStaticMember(); 2113263509Sdim 2114226890Sdim void setRedeclaration(bool Val) { Redeclaration = Val; } 2115226890Sdim bool isRedeclaration() const { return Redeclaration; } 2116212795Sdim}; 2117212795Sdim 2118245431Sdim/// \brief This little struct is used to capture information about 2119212795Sdim/// structure field declarators, which is basically just a bitfield size. 2120212795Sdimstruct FieldDeclarator { 2121212795Sdim Declarator D; 2122212795Sdim Expr *BitfieldSize; 2123245431Sdim explicit FieldDeclarator(const DeclSpec &DS) 2124245431Sdim : D(DS, Declarator::MemberContext), BitfieldSize(0) { } 2125212795Sdim}; 2126218893Sdim 2127245431Sdim/// \brief Represents a C++11 virt-specifier-seq. 2128218893Sdimclass VirtSpecifiers { 2129218893Sdimpublic: 2130218893Sdim enum Specifier { 2131218893Sdim VS_None = 0, 2132218893Sdim VS_Override = 1, 2133263509Sdim VS_Final = 2, 2134263509Sdim VS_Sealed = 4 2135218893Sdim }; 2136218893Sdim 2137218893Sdim VirtSpecifiers() : Specifiers(0) { } 2138218893Sdim 2139218893Sdim bool SetSpecifier(Specifier VS, SourceLocation Loc, 2140218893Sdim const char *&PrevSpec); 2141218893Sdim 2142218893Sdim bool isOverrideSpecified() const { return Specifiers & VS_Override; } 2143218893Sdim SourceLocation getOverrideLoc() const { return VS_overrideLoc; } 2144218893Sdim 2145263509Sdim bool isFinalSpecified() const { return Specifiers & (VS_Final | VS_Sealed); } 2146263509Sdim bool isFinalSpelledSealed() const { return Specifiers & VS_Sealed; } 2147218893Sdim SourceLocation getFinalLoc() const { return VS_finalLoc; } 2148218893Sdim 2149218893Sdim void clear() { Specifiers = 0; } 2150218893Sdim 2151218893Sdim static const char *getSpecifierName(Specifier VS); 2152218893Sdim 2153221345Sdim SourceLocation getLastLocation() const { return LastLocation; } 2154221345Sdim 2155218893Sdimprivate: 2156218893Sdim unsigned Specifiers; 2157218893Sdim 2158221345Sdim SourceLocation VS_overrideLoc, VS_finalLoc; 2159221345Sdim SourceLocation LastLocation; 2160218893Sdim}; 2161218893Sdim 2162245431Sdim/// \brief An individual capture in a lambda introducer. 2163226890Sdimstruct LambdaCapture { 2164226890Sdim LambdaCaptureKind Kind; 2165226890Sdim SourceLocation Loc; 2166263509Sdim IdentifierInfo *Id; 2167235633Sdim SourceLocation EllipsisLoc; 2168263509Sdim ExprResult Init; 2169263509Sdim ParsedType InitCaptureType; 2170235633Sdim LambdaCapture(LambdaCaptureKind Kind, SourceLocation Loc, 2171263509Sdim IdentifierInfo* Id, 2172263509Sdim SourceLocation EllipsisLoc, 2173263509Sdim ExprResult Init, ParsedType InitCaptureType) 2174263509Sdim : Kind(Kind), Loc(Loc), Id(Id), EllipsisLoc(EllipsisLoc), Init(Init), 2175263509Sdim InitCaptureType(InitCaptureType) 2176226890Sdim {} 2177226890Sdim}; 2178226890Sdim 2179245431Sdim/// \brief Represents a complete lambda introducer. 2180226890Sdimstruct LambdaIntroducer { 2181226890Sdim SourceRange Range; 2182235633Sdim SourceLocation DefaultLoc; 2183226890Sdim LambdaCaptureDefault Default; 2184252723Sdim SmallVector<LambdaCapture, 4> Captures; 2185226890Sdim 2186226890Sdim LambdaIntroducer() 2187226890Sdim : Default(LCD_None) {} 2188226890Sdim 2189245431Sdim /// \brief Append a capture in a lambda introducer. 2190226890Sdim void addCapture(LambdaCaptureKind Kind, 2191226890Sdim SourceLocation Loc, 2192263509Sdim IdentifierInfo* Id, 2193263509Sdim SourceLocation EllipsisLoc, 2194263509Sdim ExprResult Init, 2195263509Sdim ParsedType InitCaptureType) { 2196263509Sdim Captures.push_back(LambdaCapture(Kind, Loc, Id, EllipsisLoc, Init, 2197263509Sdim InitCaptureType)); 2198226890Sdim } 2199226890Sdim}; 2200226890Sdim 2201212795Sdim} // end namespace clang 2202212795Sdim 2203212795Sdim#endif 2204