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