1198092Srdivacky//===--- TypeLoc.h - Type Source Info Wrapper -------------------*- C++ -*-===//
2198092Srdivacky//
3198092Srdivacky//                     The LLVM Compiler Infrastructure
4198092Srdivacky//
5198092Srdivacky// This file is distributed under the University of Illinois Open Source
6198092Srdivacky// License. See LICENSE.TXT for details.
7198092Srdivacky//
8198092Srdivacky//===----------------------------------------------------------------------===//
9198092Srdivacky//
10198092Srdivacky//  This file defines the TypeLoc interface and subclasses.
11198092Srdivacky//
12198092Srdivacky//===----------------------------------------------------------------------===//
13198092Srdivacky
14198092Srdivacky#ifndef LLVM_CLANG_AST_TYPELOC_H
15198092Srdivacky#define LLVM_CLANG_AST_TYPELOC_H
16198092Srdivacky
17208600Srdivacky#include "clang/AST/Decl.h"
18198893Srdivacky#include "clang/AST/TemplateBase.h"
19249423Sdim#include "clang/AST/Type.h"
20202879Srdivacky#include "clang/Basic/Specifiers.h"
21234353Sdim#include "llvm/Support/Compiler.h"
22198092Srdivacky
23198092Srdivackynamespace clang {
24218893Sdim  class ASTContext;
25198092Srdivacky  class ParmVarDecl;
26200583Srdivacky  class TypeSourceInfo;
27198112Srdivacky  class UnqualTypeLoc;
28198092Srdivacky
29198398Srdivacky// Predeclare all the type nodes.
30198398Srdivacky#define ABSTRACT_TYPELOC(Class, Base)
31198398Srdivacky#define TYPELOC(Class, Base) \
32198398Srdivacky  class Class##TypeLoc;
33198398Srdivacky#include "clang/AST/TypeLocNodes.def"
34198398Srdivacky
35198092Srdivacky/// \brief Base wrapper for a particular "section" of type source info.
36198092Srdivacky///
37198092Srdivacky/// A client should use the TypeLoc subclasses through cast/dyn_cast in order to
38198092Srdivacky/// get at the actual information.
39198092Srdivackyclass TypeLoc {
40198092Srdivackyprotected:
41198112Srdivacky  // The correctness of this relies on the property that, for Type *Ty,
42198112Srdivacky  //   QualType(Ty, 0).getAsOpaquePtr() == (void*) Ty
43218893Sdim  const void *Ty;
44198092Srdivacky  void *Data;
45198092Srdivacky
46198092Srdivackypublic:
47249423Sdim  /// \brief Convert to the specified TypeLoc type, asserting that this TypeLoc
48249423Sdim  /// is of the desired type.
49249423Sdim  template<typename T>
50249423Sdim  T castAs() const {
51249423Sdim    assert(T::isKind(*this));
52249423Sdim    T t;
53249423Sdim    TypeLoc& tl = t;
54249423Sdim    tl = *this;
55249423Sdim    return t;
56249423Sdim  }
57249423Sdim
58249423Sdim  /// \brief Convert to the specified TypeLoc type, returning a null TypeLoc if
59249423Sdim  /// this TypeLoc is not of the desired type.
60249423Sdim  template<typename T>
61249423Sdim  T getAs() const {
62249423Sdim    if (!T::isKind(*this))
63249423Sdim      return T();
64249423Sdim    T t;
65249423Sdim    TypeLoc& tl = t;
66249423Sdim    tl = *this;
67249423Sdim    return t;
68249423Sdim  }
69249423Sdim
70198398Srdivacky  /// The kinds of TypeLocs.  Equivalent to the Type::TypeClass enum,
71198398Srdivacky  /// except it also defines a Qualified enum that corresponds to the
72198398Srdivacky  /// QualifiedLoc class.
73198398Srdivacky  enum TypeLocClass {
74198398Srdivacky#define ABSTRACT_TYPE(Class, Base)
75198398Srdivacky#define TYPE(Class, Base) \
76198398Srdivacky    Class = Type::Class,
77198398Srdivacky#include "clang/AST/TypeNodes.def"
78198398Srdivacky    Qualified
79198398Srdivacky  };
80198398Srdivacky
81198112Srdivacky  TypeLoc() : Ty(0), Data(0) { }
82198112Srdivacky  TypeLoc(QualType ty, void *opaqueData)
83198112Srdivacky    : Ty(ty.getAsOpaquePtr()), Data(opaqueData) { }
84218893Sdim  TypeLoc(const Type *ty, void *opaqueData)
85198112Srdivacky    : Ty(ty), Data(opaqueData) { }
86198092Srdivacky
87198398Srdivacky  TypeLocClass getTypeLocClass() const {
88199482Srdivacky    if (getType().hasLocalQualifiers()) return Qualified;
89198398Srdivacky    return (TypeLocClass) getType()->getTypeClass();
90198398Srdivacky  }
91198398Srdivacky
92198112Srdivacky  bool isNull() const { return !Ty; }
93198112Srdivacky  operator bool() const { return Ty; }
94198092Srdivacky
95198092Srdivacky  /// \brief Returns the size of type source info data block for the given type.
96198092Srdivacky  static unsigned getFullDataSizeForType(QualType Ty);
97198092Srdivacky
98198092Srdivacky  /// \brief Get the type for which this source info wrapper provides
99198092Srdivacky  /// information.
100198398Srdivacky  QualType getType() const {
101198398Srdivacky    return QualType::getFromOpaquePtr(Ty);
102198398Srdivacky  }
103198092Srdivacky
104218893Sdim  const Type *getTypePtr() const {
105198112Srdivacky    return QualType::getFromOpaquePtr(Ty).getTypePtr();
106198112Srdivacky  }
107198112Srdivacky
108198092Srdivacky  /// \brief Get the pointer where source information is stored.
109198398Srdivacky  void *getOpaqueData() const {
110198398Srdivacky    return Data;
111198398Srdivacky  }
112198092Srdivacky
113208600Srdivacky  /// \brief Get the begin source location.
114208600Srdivacky  SourceLocation getBeginLoc() const;
115208600Srdivacky
116208600Srdivacky  /// \brief Get the end source location.
117208600Srdivacky  SourceLocation getEndLoc() const;
118208600Srdivacky
119198893Srdivacky  /// \brief Get the full source range.
120234353Sdim  SourceRange getSourceRange() const LLVM_READONLY {
121208600Srdivacky    return SourceRange(getBeginLoc(), getEndLoc());
122198893Srdivacky  }
123234353Sdim  SourceLocation getLocStart() const LLVM_READONLY { return getBeginLoc(); }
124234353Sdim  SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
125198893Srdivacky
126198893Srdivacky  /// \brief Get the local source range.
127208600Srdivacky  SourceRange getLocalSourceRange() const {
128208600Srdivacky    return getLocalSourceRangeImpl(*this);
129198398Srdivacky  }
130198092Srdivacky
131198092Srdivacky  /// \brief Returns the size of the type source info data block.
132198112Srdivacky  unsigned getFullDataSize() const {
133198398Srdivacky    return getFullDataSizeForType(getType());
134198112Srdivacky  }
135198092Srdivacky
136198092Srdivacky  /// \brief Get the next TypeLoc pointed by this TypeLoc, e.g for "int*" the
137198092Srdivacky  /// TypeLoc is a PointerLoc and next TypeLoc is for "int".
138198398Srdivacky  TypeLoc getNextTypeLoc() const {
139198398Srdivacky    return getNextTypeLocImpl(*this);
140198398Srdivacky  }
141198092Srdivacky
142198112Srdivacky  /// \brief Skips past any qualifiers, if this is qualified.
143198398Srdivacky  UnqualTypeLoc getUnqualifiedLoc() const; // implemented in this header
144198112Srdivacky
145249423Sdim  TypeLoc IgnoreParens() const;
146218893Sdim
147198398Srdivacky  /// \brief Initializes this to state that every location in this
148198398Srdivacky  /// type is the given location.
149198398Srdivacky  ///
150198398Srdivacky  /// This method exists to provide a simple transition for code that
151198398Srdivacky  /// relies on location-less types.
152218893Sdim  void initialize(ASTContext &Context, SourceLocation Loc) const {
153218893Sdim    initializeImpl(Context, *this, Loc);
154198398Srdivacky  }
155198398Srdivacky
156218893Sdim  /// \brief Initializes this by copying its information from another
157218893Sdim  /// TypeLoc of the same type.
158218893Sdim  void initializeFullCopy(TypeLoc Other) const {
159218893Sdim    assert(getType() == Other.getType());
160218893Sdim    size_t Size = getFullDataSize();
161218893Sdim    memcpy(getOpaqueData(), Other.getOpaqueData(), Size);
162218893Sdim  }
163218893Sdim
164218893Sdim  /// \brief Initializes this by copying its information from another
165218893Sdim  /// TypeLoc of the same type.  The given size must be the full data
166218893Sdim  /// size.
167218893Sdim  void initializeFullCopy(TypeLoc Other, unsigned Size) const {
168218893Sdim    assert(getType() == Other.getType());
169218893Sdim    assert(getFullDataSize() == Size);
170218893Sdim    memcpy(getOpaqueData(), Other.getOpaqueData(), Size);
171218893Sdim  }
172218893Sdim
173198092Srdivacky  friend bool operator==(const TypeLoc &LHS, const TypeLoc &RHS) {
174198092Srdivacky    return LHS.Ty == RHS.Ty && LHS.Data == RHS.Data;
175198092Srdivacky  }
176198092Srdivacky
177198092Srdivacky  friend bool operator!=(const TypeLoc &LHS, const TypeLoc &RHS) {
178198092Srdivacky    return !(LHS == RHS);
179198092Srdivacky  }
180198092Srdivacky
181198398Srdivackyprivate:
182249423Sdim  static bool isKind(const TypeLoc&) {
183249423Sdim    return true;
184249423Sdim  }
185249423Sdim
186234353Sdim  static void initializeImpl(ASTContext &Context, TypeLoc TL,
187234353Sdim                             SourceLocation Loc);
188198398Srdivacky  static TypeLoc getNextTypeLocImpl(TypeLoc TL);
189218893Sdim  static TypeLoc IgnoreParensImpl(TypeLoc TL);
190208600Srdivacky  static SourceRange getLocalSourceRangeImpl(TypeLoc TL);
191198092Srdivacky};
192198092Srdivacky
193208600Srdivacky/// \brief Return the TypeLoc for a type source info.
194208600Srdivackyinline TypeLoc TypeSourceInfo::getTypeLoc() const {
195210299Sed  return TypeLoc(Ty, const_cast<void*>(static_cast<const void*>(this + 1)));
196208600Srdivacky}
197208600Srdivacky
198198112Srdivacky/// \brief Wrapper of type source information for a type with
199218893Sdim/// no direct qualifiers.
200198112Srdivackyclass UnqualTypeLoc : public TypeLoc {
201198112Srdivackypublic:
202198112Srdivacky  UnqualTypeLoc() {}
203218893Sdim  UnqualTypeLoc(const Type *Ty, void *Data) : TypeLoc(Ty, Data) {}
204198112Srdivacky
205218893Sdim  const Type *getTypePtr() const {
206218893Sdim    return reinterpret_cast<const Type*>(Ty);
207198112Srdivacky  }
208198112Srdivacky
209198398Srdivacky  TypeLocClass getTypeLocClass() const {
210198398Srdivacky    return (TypeLocClass) getTypePtr()->getTypeClass();
211198398Srdivacky  }
212198398Srdivacky
213249423Sdimprivate:
214249423Sdim  friend class TypeLoc;
215249423Sdim  static bool isKind(const TypeLoc &TL) {
216249423Sdim    return !TL.getType().hasLocalQualifiers();
217198112Srdivacky  }
218198112Srdivacky};
219198112Srdivacky
220198112Srdivacky/// \brief Wrapper of type source information for a type with
221198112Srdivacky/// non-trivial direct qualifiers.
222198112Srdivacky///
223198112Srdivacky/// Currently, we intentionally do not provide source location for
224198112Srdivacky/// type qualifiers.
225198398Srdivackyclass QualifiedTypeLoc : public TypeLoc {
226198112Srdivackypublic:
227208600Srdivacky  SourceRange getLocalSourceRange() const {
228198112Srdivacky    return SourceRange();
229198112Srdivacky  }
230198112Srdivacky
231198112Srdivacky  UnqualTypeLoc getUnqualifiedLoc() const {
232198398Srdivacky    return UnqualTypeLoc(getTypePtr(), Data);
233198112Srdivacky  }
234198112Srdivacky
235198398Srdivacky  /// Initializes the local data of this type source info block to
236198398Srdivacky  /// provide no information.
237218893Sdim  void initializeLocal(ASTContext &Context, SourceLocation Loc) {
238198398Srdivacky    // do nothing
239198398Srdivacky  }
240198398Srdivacky
241198398Srdivacky  TypeLoc getNextTypeLoc() const {
242198398Srdivacky    return getUnqualifiedLoc();
243198398Srdivacky  }
244198398Srdivacky
245198112Srdivacky  /// \brief Returns the size of the type source info data block that is
246198112Srdivacky  /// specific to this type.
247198112Srdivacky  unsigned getLocalDataSize() const {
248198112Srdivacky    // In fact, we don't currently preserve any location information
249198112Srdivacky    // for qualifiers.
250198112Srdivacky    return 0;
251198112Srdivacky  }
252198112Srdivacky
253198112Srdivacky  /// \brief Returns the size of the type source info data block.
254198112Srdivacky  unsigned getFullDataSize() const {
255234353Sdim    return getLocalDataSize() +
256199482Srdivacky      getFullDataSizeForType(getType().getLocalUnqualifiedType());
257198112Srdivacky  }
258198112Srdivacky
259249423Sdimprivate:
260249423Sdim  friend class TypeLoc;
261249423Sdim  static bool isKind(const TypeLoc &TL) {
262249423Sdim    return TL.getType().hasLocalQualifiers();
263198112Srdivacky  }
264198112Srdivacky};
265198112Srdivacky
266198112Srdivackyinline UnqualTypeLoc TypeLoc::getUnqualifiedLoc() const {
267249423Sdim  if (QualifiedTypeLoc Loc = getAs<QualifiedTypeLoc>())
268249423Sdim    return Loc.getUnqualifiedLoc();
269249423Sdim  return castAs<UnqualTypeLoc>();
270198112Srdivacky}
271198112Srdivacky
272198112Srdivacky/// A metaprogramming base class for TypeLoc classes which correspond
273198112Srdivacky/// to a particular Type subclass.  It is accepted for a single
274198112Srdivacky/// TypeLoc class to correspond to multiple Type classes.
275198112Srdivacky///
276243830Sdim/// \tparam Base a class from which to derive
277243830Sdim/// \tparam Derived the class deriving from this one
278243830Sdim/// \tparam TypeClass the concrete Type subclass associated with this
279198112Srdivacky///   location type
280243830Sdim/// \tparam LocalData the structure type of local location data for
281198112Srdivacky///   this type
282198112Srdivacky///
283198112Srdivacky/// sizeof(LocalData) needs to be a multiple of sizeof(void*) or
284198112Srdivacky/// else the world will end.
285198112Srdivacky///
286198112Srdivacky/// TypeLocs with non-constant amounts of local data should override
287198112Srdivacky/// getExtraLocalDataSize(); getExtraLocalData() will then point to
288198112Srdivacky/// this extra memory.
289198112Srdivacky///
290198398Srdivacky/// TypeLocs with an inner type should define
291198398Srdivacky///   QualType getInnerType() const
292198398Srdivacky/// and getInnerTypeLoc() will then point to this inner type's
293198398Srdivacky/// location data.
294198398Srdivacky///
295198398Srdivacky/// A word about hierarchies: this template is not designed to be
296198398Srdivacky/// derived from multiple times in a hierarchy.  It is also not
297198398Srdivacky/// designed to be used for classes where subtypes might provide
298198398Srdivacky/// different amounts of source information.  It should be subclassed
299198398Srdivacky/// only at the deepest portion of the hierarchy where all children
300198398Srdivacky/// have identical source information; if that's an abstract type,
301198398Srdivacky/// then further descendents should inherit from
302198398Srdivacky/// InheritingConcreteTypeLoc instead.
303198112Srdivackytemplate <class Base, class Derived, class TypeClass, class LocalData>
304198112Srdivackyclass ConcreteTypeLoc : public Base {
305198112Srdivacky
306198112Srdivacky  const Derived *asDerived() const {
307198112Srdivacky    return static_cast<const Derived*>(this);
308198112Srdivacky  }
309198112Srdivacky
310249423Sdim  friend class TypeLoc;
311249423Sdim  static bool isKind(const TypeLoc &TL) {
312249423Sdim    return Derived::classofType(TL.getTypePtr());
313249423Sdim  }
314249423Sdim
315249423Sdim  static bool classofType(const Type *Ty) {
316249423Sdim    return TypeClass::classof(Ty);
317249423Sdim  }
318249423Sdim
319198112Srdivackypublic:
320198112Srdivacky  unsigned getLocalDataSize() const {
321198112Srdivacky    return sizeof(LocalData) + asDerived()->getExtraLocalDataSize();
322198112Srdivacky  }
323198112Srdivacky  // Give a default implementation that's useful for leaf types.
324198112Srdivacky  unsigned getFullDataSize() const {
325198112Srdivacky    return asDerived()->getLocalDataSize() + getInnerTypeSize();
326198112Srdivacky  }
327198112Srdivacky
328198398Srdivacky  TypeLoc getNextTypeLoc() const {
329198398Srdivacky    return getNextTypeLoc(asDerived()->getInnerType());
330198398Srdivacky  }
331198398Srdivacky
332218893Sdim  const TypeClass *getTypePtr() const {
333198398Srdivacky    return cast<TypeClass>(Base::getTypePtr());
334198112Srdivacky  }
335198112Srdivacky
336198398Srdivackyprotected:
337198112Srdivacky  unsigned getExtraLocalDataSize() const {
338198112Srdivacky    return 0;
339198112Srdivacky  }
340198112Srdivacky
341198112Srdivacky  LocalData *getLocalData() const {
342198112Srdivacky    return static_cast<LocalData*>(Base::Data);
343198112Srdivacky  }
344198112Srdivacky
345198112Srdivacky  /// Gets a pointer past the Info structure; useful for classes with
346198112Srdivacky  /// local data that can't be captured in the Info (e.g. because it's
347198112Srdivacky  /// of variable size).
348198112Srdivacky  void *getExtraLocalData() const {
349198112Srdivacky    return getLocalData() + 1;
350198112Srdivacky  }
351234353Sdim
352198112Srdivacky  void *getNonLocalData() const {
353198112Srdivacky    return static_cast<char*>(Base::Data) + asDerived()->getLocalDataSize();
354198112Srdivacky  }
355198112Srdivacky
356198398Srdivacky  struct HasNoInnerType {};
357198398Srdivacky  HasNoInnerType getInnerType() const { return HasNoInnerType(); }
358198112Srdivacky
359198112Srdivacky  TypeLoc getInnerTypeLoc() const {
360198112Srdivacky    return TypeLoc(asDerived()->getInnerType(), getNonLocalData());
361198112Srdivacky  }
362198112Srdivacky
363198112Srdivackyprivate:
364198112Srdivacky  unsigned getInnerTypeSize() const {
365198398Srdivacky    return getInnerTypeSize(asDerived()->getInnerType());
366198398Srdivacky  }
367198398Srdivacky
368198398Srdivacky  unsigned getInnerTypeSize(HasNoInnerType _) const {
369198112Srdivacky    return 0;
370198112Srdivacky  }
371198112Srdivacky
372198398Srdivacky  unsigned getInnerTypeSize(QualType _) const {
373198398Srdivacky    return getInnerTypeLoc().getFullDataSize();
374198112Srdivacky  }
375198112Srdivacky
376198398Srdivacky  TypeLoc getNextTypeLoc(HasNoInnerType _) const {
377198398Srdivacky    return TypeLoc();
378198398Srdivacky  }
379198112Srdivacky
380198398Srdivacky  TypeLoc getNextTypeLoc(QualType T) const {
381198398Srdivacky    return TypeLoc(T, getNonLocalData());
382198398Srdivacky  }
383198112Srdivacky};
384198112Srdivacky
385198398Srdivacky/// A metaprogramming class designed for concrete subtypes of abstract
386198398Srdivacky/// types where all subtypes share equivalently-structured source
387198398Srdivacky/// information.  See the note on ConcreteTypeLoc.
388198398Srdivackytemplate <class Base, class Derived, class TypeClass>
389198398Srdivackyclass InheritingConcreteTypeLoc : public Base {
390249423Sdim  friend class TypeLoc;
391212904Sdim  static bool classofType(const Type *Ty) {
392212904Sdim    return TypeClass::classof(Ty);
393212904Sdim  }
394212904Sdim
395249423Sdim  static bool isKind(const TypeLoc &TL) {
396249423Sdim    return Derived::classofType(TL.getTypePtr());
397198092Srdivacky  }
398249423Sdim  static bool isKind(const UnqualTypeLoc &TL) {
399249423Sdim    return Derived::classofType(TL.getTypePtr());
400198092Srdivacky  }
401198092Srdivacky
402249423Sdimpublic:
403218893Sdim  const TypeClass *getTypePtr() const {
404198398Srdivacky    return cast<TypeClass>(Base::getTypePtr());
405198398Srdivacky  }
406198112Srdivacky};
407198092Srdivacky
408200583Srdivacky
409198398Srdivackystruct TypeSpecLocInfo {
410198112Srdivacky  SourceLocation NameLoc;
411198092Srdivacky};
412198092Srdivacky
413198398Srdivacky/// \brief A reasonable base class for TypeLocs that correspond to
414198398Srdivacky/// types that are written as a type-specifier.
415234353Sdimclass TypeSpecTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
416200583Srdivacky                                               TypeSpecTypeLoc,
417200583Srdivacky                                               Type,
418200583Srdivacky                                               TypeSpecLocInfo> {
419198092Srdivackypublic:
420200583Srdivacky  enum { LocalDataSize = sizeof(TypeSpecLocInfo) };
421200583Srdivacky
422198092Srdivacky  SourceLocation getNameLoc() const {
423198398Srdivacky    return this->getLocalData()->NameLoc;
424198092Srdivacky  }
425198092Srdivacky  void setNameLoc(SourceLocation Loc) {
426198398Srdivacky    this->getLocalData()->NameLoc = Loc;
427198092Srdivacky  }
428208600Srdivacky  SourceRange getLocalSourceRange() const {
429198092Srdivacky    return SourceRange(getNameLoc(), getNameLoc());
430198092Srdivacky  }
431218893Sdim  void initializeLocal(ASTContext &Context, SourceLocation Loc) {
432198398Srdivacky    setNameLoc(Loc);
433198398Srdivacky  }
434200583Srdivacky
435249423Sdimprivate:
436249423Sdim  friend class TypeLoc;
437249423Sdim  static bool isKind(const TypeLoc &TL);
438198398Srdivacky};
439198092Srdivacky
440200583Srdivacky
441202879Srdivackystruct BuiltinLocInfo {
442202879Srdivacky  SourceLocation BuiltinLoc;
443202879Srdivacky};
444202879Srdivacky
445202879Srdivacky/// \brief Wrapper for source info for builtin types.
446202879Srdivackyclass BuiltinTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
447202879Srdivacky                                              BuiltinTypeLoc,
448202879Srdivacky                                              BuiltinType,
449202879Srdivacky                                              BuiltinLocInfo> {
450202879Srdivackypublic:
451202879Srdivacky  enum { LocalDataSize = sizeof(BuiltinLocInfo) };
452202879Srdivacky
453202879Srdivacky  SourceLocation getBuiltinLoc() const {
454202879Srdivacky    return getLocalData()->BuiltinLoc;
455202879Srdivacky  }
456202879Srdivacky  void setBuiltinLoc(SourceLocation Loc) {
457202879Srdivacky    getLocalData()->BuiltinLoc = Loc;
458202879Srdivacky  }
459202879Srdivacky
460202879Srdivacky  SourceLocation getNameLoc() const { return getBuiltinLoc(); }
461202879Srdivacky
462202879Srdivacky  WrittenBuiltinSpecs& getWrittenBuiltinSpecs() {
463202879Srdivacky    return *(static_cast<WrittenBuiltinSpecs*>(getExtraLocalData()));
464202879Srdivacky  }
465202879Srdivacky  const WrittenBuiltinSpecs& getWrittenBuiltinSpecs() const {
466202879Srdivacky    return *(static_cast<WrittenBuiltinSpecs*>(getExtraLocalData()));
467202879Srdivacky  }
468202879Srdivacky
469202879Srdivacky  bool needsExtraLocalData() const {
470202879Srdivacky    BuiltinType::Kind bk = getTypePtr()->getKind();
471202879Srdivacky    return (bk >= BuiltinType::UShort && bk <= BuiltinType::UInt128)
472202879Srdivacky      || (bk >= BuiltinType::Short && bk <= BuiltinType::LongDouble)
473202879Srdivacky      || bk == BuiltinType::UChar
474202879Srdivacky      || bk == BuiltinType::SChar;
475202879Srdivacky  }
476202879Srdivacky
477202879Srdivacky  unsigned getExtraLocalDataSize() const {
478202879Srdivacky    return needsExtraLocalData() ? sizeof(WrittenBuiltinSpecs) : 0;
479202879Srdivacky  }
480202879Srdivacky
481208600Srdivacky  SourceRange getLocalSourceRange() const {
482202879Srdivacky    return SourceRange(getBuiltinLoc(), getBuiltinLoc());
483202879Srdivacky  }
484202879Srdivacky
485202879Srdivacky  TypeSpecifierSign getWrittenSignSpec() const {
486202879Srdivacky    if (needsExtraLocalData())
487202879Srdivacky      return static_cast<TypeSpecifierSign>(getWrittenBuiltinSpecs().Sign);
488202879Srdivacky    else
489202879Srdivacky      return TSS_unspecified;
490202879Srdivacky  }
491202879Srdivacky  bool hasWrittenSignSpec() const {
492202879Srdivacky    return getWrittenSignSpec() != TSS_unspecified;
493202879Srdivacky  }
494202879Srdivacky  void setWrittenSignSpec(TypeSpecifierSign written) {
495202879Srdivacky    if (needsExtraLocalData())
496202879Srdivacky      getWrittenBuiltinSpecs().Sign = written;
497202879Srdivacky  }
498202879Srdivacky
499202879Srdivacky  TypeSpecifierWidth getWrittenWidthSpec() const {
500202879Srdivacky    if (needsExtraLocalData())
501202879Srdivacky      return static_cast<TypeSpecifierWidth>(getWrittenBuiltinSpecs().Width);
502202879Srdivacky    else
503202879Srdivacky      return TSW_unspecified;
504202879Srdivacky  }
505202879Srdivacky  bool hasWrittenWidthSpec() const {
506202879Srdivacky    return getWrittenWidthSpec() != TSW_unspecified;
507202879Srdivacky  }
508202879Srdivacky  void setWrittenWidthSpec(TypeSpecifierWidth written) {
509202879Srdivacky    if (needsExtraLocalData())
510202879Srdivacky      getWrittenBuiltinSpecs().Width = written;
511202879Srdivacky  }
512202879Srdivacky
513202879Srdivacky  TypeSpecifierType getWrittenTypeSpec() const;
514202879Srdivacky  bool hasWrittenTypeSpec() const {
515202879Srdivacky    return getWrittenTypeSpec() != TST_unspecified;
516202879Srdivacky  }
517202879Srdivacky  void setWrittenTypeSpec(TypeSpecifierType written) {
518202879Srdivacky    if (needsExtraLocalData())
519202879Srdivacky      getWrittenBuiltinSpecs().Type = written;
520202879Srdivacky  }
521202879Srdivacky
522202879Srdivacky  bool hasModeAttr() const {
523202879Srdivacky    if (needsExtraLocalData())
524202879Srdivacky      return getWrittenBuiltinSpecs().ModeAttr;
525202879Srdivacky    else
526202879Srdivacky      return false;
527202879Srdivacky  }
528202879Srdivacky  void setModeAttr(bool written) {
529202879Srdivacky    if (needsExtraLocalData())
530202879Srdivacky      getWrittenBuiltinSpecs().ModeAttr = written;
531202879Srdivacky  }
532202879Srdivacky
533218893Sdim  void initializeLocal(ASTContext &Context, SourceLocation Loc) {
534202879Srdivacky    setBuiltinLoc(Loc);
535202879Srdivacky    if (needsExtraLocalData()) {
536202879Srdivacky      WrittenBuiltinSpecs &wbs = getWrittenBuiltinSpecs();
537202879Srdivacky      wbs.Sign = TSS_unspecified;
538202879Srdivacky      wbs.Width = TSW_unspecified;
539202879Srdivacky      wbs.Type = TST_unspecified;
540202879Srdivacky      wbs.ModeAttr = false;
541202879Srdivacky    }
542202879Srdivacky  }
543202879Srdivacky};
544202879Srdivacky
545202879Srdivacky
546198398Srdivacky/// \brief Wrapper for source info for typedefs.
547200583Srdivackyclass TypedefTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
548200583Srdivacky                                                        TypedefTypeLoc,
549200583Srdivacky                                                        TypedefType> {
550198398Srdivackypublic:
551221345Sdim  TypedefNameDecl *getTypedefNameDecl() const {
552198112Srdivacky    return getTypePtr()->getDecl();
553198092Srdivacky  }
554198112Srdivacky};
555198092Srdivacky
556204962Srdivacky/// \brief Wrapper for source info for injected class names of class
557204962Srdivacky/// templates.
558204962Srdivackyclass InjectedClassNameTypeLoc :
559204962Srdivacky    public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
560204962Srdivacky                                     InjectedClassNameTypeLoc,
561204962Srdivacky                                     InjectedClassNameType> {
562226633Sdimpublic:
563226633Sdim  CXXRecordDecl *getDecl() const {
564226633Sdim    return getTypePtr()->getDecl();
565226633Sdim  }
566204962Srdivacky};
567204962Srdivacky
568200583Srdivacky/// \brief Wrapper for source info for unresolved typename using decls.
569200583Srdivackyclass UnresolvedUsingTypeLoc :
570200583Srdivacky    public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
571200583Srdivacky                                     UnresolvedUsingTypeLoc,
572200583Srdivacky                                     UnresolvedUsingType> {
573200583Srdivackypublic:
574200583Srdivacky  UnresolvedUsingTypenameDecl *getDecl() const {
575200583Srdivacky    return getTypePtr()->getDecl();
576200583Srdivacky  }
577200583Srdivacky};
578198092Srdivacky
579200583Srdivacky/// \brief Wrapper for source info for tag types.  Note that this only
580200583Srdivacky/// records source info for the name itself; a type written 'struct foo'
581200583Srdivacky/// should be represented as an ElaboratedTypeLoc.  We currently
582200583Srdivacky/// only do that when C++ is enabled because of the expense of
583200583Srdivacky/// creating an ElaboratedType node for so many type references in C.
584200583Srdivackyclass TagTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
585200583Srdivacky                                                    TagTypeLoc,
586200583Srdivacky                                                    TagType> {
587200583Srdivackypublic:
588200583Srdivacky  TagDecl *getDecl() const { return getTypePtr()->getDecl(); }
589226633Sdim
590234353Sdim  /// \brief True if the tag was defined in this type specifier.
591226633Sdim  bool isDefinition() const {
592234353Sdim    TagDecl *D = getDecl();
593234353Sdim    return D->isCompleteDefinition() &&
594234353Sdim         (D->getIdentifier() == 0 || D->getLocation() == getNameLoc());
595226633Sdim  }
596200583Srdivacky};
597200583Srdivacky
598200583Srdivacky/// \brief Wrapper for source info for record types.
599200583Srdivackyclass RecordTypeLoc : public InheritingConcreteTypeLoc<TagTypeLoc,
600200583Srdivacky                                                       RecordTypeLoc,
601200583Srdivacky                                                       RecordType> {
602200583Srdivackypublic:
603200583Srdivacky  RecordDecl *getDecl() const { return getTypePtr()->getDecl(); }
604200583Srdivacky};
605200583Srdivacky
606200583Srdivacky/// \brief Wrapper for source info for enum types.
607200583Srdivackyclass EnumTypeLoc : public InheritingConcreteTypeLoc<TagTypeLoc,
608200583Srdivacky                                                     EnumTypeLoc,
609200583Srdivacky                                                     EnumType> {
610200583Srdivackypublic:
611200583Srdivacky  EnumDecl *getDecl() const { return getTypePtr()->getDecl(); }
612200583Srdivacky};
613200583Srdivacky
614198398Srdivacky/// \brief Wrapper for template type parameters.
615200583Srdivackyclass TemplateTypeParmTypeLoc :
616200583Srdivacky    public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
617200583Srdivacky                                     TemplateTypeParmTypeLoc,
618200583Srdivacky                                     TemplateTypeParmType> {
619221345Sdimpublic:
620221345Sdim  TemplateTypeParmDecl *getDecl() const { return getTypePtr()->getDecl(); }
621198398Srdivacky};
622198092Srdivacky
623198398Srdivacky/// \brief Wrapper for substituted template type parameters.
624198398Srdivackyclass SubstTemplateTypeParmTypeLoc :
625200583Srdivacky    public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
626200583Srdivacky                                     SubstTemplateTypeParmTypeLoc,
627200583Srdivacky                                     SubstTemplateTypeParmType> {
628198112Srdivacky};
629198092Srdivacky
630218893Sdim  /// \brief Wrapper for substituted template type parameters.
631218893Sdimclass SubstTemplateTypeParmPackTypeLoc :
632218893Sdim    public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
633218893Sdim                                     SubstTemplateTypeParmPackTypeLoc,
634218893Sdim                                     SubstTemplateTypeParmPackType> {
635218893Sdim};
636198092Srdivacky
637218893Sdimstruct AttributedLocInfo {
638218893Sdim  union {
639218893Sdim    Expr *ExprOperand;
640218893Sdim
641218893Sdim    /// A raw SourceLocation.
642218893Sdim    unsigned EnumOperandLoc;
643218893Sdim  };
644218893Sdim
645218893Sdim  SourceRange OperandParens;
646218893Sdim
647218893Sdim  SourceLocation AttrLoc;
648218893Sdim};
649218893Sdim
650218893Sdim/// \brief Type source information for an attributed type.
651218893Sdimclass AttributedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
652218893Sdim                                                 AttributedTypeLoc,
653218893Sdim                                                 AttributedType,
654218893Sdim                                                 AttributedLocInfo> {
655218893Sdimpublic:
656218893Sdim  AttributedType::Kind getAttrKind() const {
657218893Sdim    return getTypePtr()->getAttrKind();
658218893Sdim  }
659218893Sdim
660218893Sdim  bool hasAttrExprOperand() const {
661218893Sdim    return (getAttrKind() >= AttributedType::FirstExprOperandKind &&
662218893Sdim            getAttrKind() <= AttributedType::LastExprOperandKind);
663218893Sdim  }
664218893Sdim
665218893Sdim  bool hasAttrEnumOperand() const {
666218893Sdim    return (getAttrKind() >= AttributedType::FirstEnumOperandKind &&
667218893Sdim            getAttrKind() <= AttributedType::LastEnumOperandKind);
668218893Sdim  }
669218893Sdim
670218893Sdim  bool hasAttrOperand() const {
671218893Sdim    return hasAttrExprOperand() || hasAttrEnumOperand();
672218893Sdim  }
673218893Sdim
674218893Sdim  /// The modified type, which is generally canonically different from
675218893Sdim  /// the attribute type.
676218893Sdim  ///    int main(int, char**) __attribute__((noreturn))
677218893Sdim  ///    ~~~     ~~~~~~~~~~~~~
678218893Sdim  TypeLoc getModifiedLoc() const {
679218893Sdim    return getInnerTypeLoc();
680218893Sdim  }
681218893Sdim
682218893Sdim  /// The location of the attribute name, i.e.
683218893Sdim  ///    __attribute__((regparm(1000)))
684218893Sdim  ///                   ^~~~~~~
685218893Sdim  SourceLocation getAttrNameLoc() const {
686218893Sdim    return getLocalData()->AttrLoc;
687218893Sdim  }
688218893Sdim  void setAttrNameLoc(SourceLocation loc) {
689218893Sdim    getLocalData()->AttrLoc = loc;
690218893Sdim  }
691218893Sdim
692218893Sdim  /// The attribute's expression operand, if it has one.
693218893Sdim  ///    void *cur_thread __attribute__((address_space(21)))
694218893Sdim  ///                                                  ^~
695218893Sdim  Expr *getAttrExprOperand() const {
696218893Sdim    assert(hasAttrExprOperand());
697218893Sdim    return getLocalData()->ExprOperand;
698218893Sdim  }
699218893Sdim  void setAttrExprOperand(Expr *e) {
700218893Sdim    assert(hasAttrExprOperand());
701218893Sdim    getLocalData()->ExprOperand = e;
702218893Sdim  }
703218893Sdim
704218893Sdim  /// The location of the attribute's enumerated operand, if it has one.
705218893Sdim  ///    void * __attribute__((objc_gc(weak)))
706218893Sdim  ///                                  ^~~~
707218893Sdim  SourceLocation getAttrEnumOperandLoc() const {
708218893Sdim    assert(hasAttrEnumOperand());
709218893Sdim    return SourceLocation::getFromRawEncoding(getLocalData()->EnumOperandLoc);
710218893Sdim  }
711218893Sdim  void setAttrEnumOperandLoc(SourceLocation loc) {
712218893Sdim    assert(hasAttrEnumOperand());
713218893Sdim    getLocalData()->EnumOperandLoc = loc.getRawEncoding();
714218893Sdim  }
715218893Sdim
716218893Sdim  /// The location of the parentheses around the operand, if there is
717218893Sdim  /// an operand.
718218893Sdim  ///    void * __attribute__((objc_gc(weak)))
719218893Sdim  ///                                 ^    ^
720218893Sdim  SourceRange getAttrOperandParensRange() const {
721218893Sdim    assert(hasAttrOperand());
722218893Sdim    return getLocalData()->OperandParens;
723218893Sdim  }
724218893Sdim  void setAttrOperandParensRange(SourceRange range) {
725218893Sdim    assert(hasAttrOperand());
726218893Sdim    getLocalData()->OperandParens = range;
727218893Sdim  }
728218893Sdim
729218893Sdim  SourceRange getLocalSourceRange() const {
730218893Sdim    // Note that this does *not* include the range of the attribute
731218893Sdim    // enclosure, e.g.:
732218893Sdim    //    __attribute__((foo(bar)))
733218893Sdim    //    ^~~~~~~~~~~~~~~        ~~
734218893Sdim    // or
735218893Sdim    //    [[foo(bar)]]
736218893Sdim    //    ^~        ~~
737218893Sdim    // That enclosure doesn't necessarily belong to a single attribute
738218893Sdim    // anyway.
739218893Sdim    SourceRange range(getAttrNameLoc());
740218893Sdim    if (hasAttrOperand())
741218893Sdim      range.setEnd(getAttrOperandParensRange().getEnd());
742218893Sdim    return range;
743218893Sdim  }
744218893Sdim
745218893Sdim  void initializeLocal(ASTContext &Context, SourceLocation loc) {
746218893Sdim    setAttrNameLoc(loc);
747218893Sdim    if (hasAttrExprOperand()) {
748218893Sdim      setAttrOperandParensRange(SourceRange(loc));
749218893Sdim      setAttrExprOperand(0);
750218893Sdim    } else if (hasAttrEnumOperand()) {
751218893Sdim      setAttrOperandParensRange(SourceRange(loc));
752218893Sdim      setAttrEnumOperandLoc(loc);
753218893Sdim    }
754218893Sdim  }
755218893Sdim
756218893Sdim  QualType getInnerType() const {
757218893Sdim    return getTypePtr()->getModifiedType();
758218893Sdim  }
759218893Sdim};
760218893Sdim
761218893Sdim
762198112Srdivackystruct ObjCProtocolListLocInfo {
763198398Srdivacky  SourceLocation LAngleLoc;
764198398Srdivacky  SourceLocation RAngleLoc;
765208600Srdivacky  bool HasBaseTypeAsWritten;
766198092Srdivacky};
767198092Srdivacky
768198398Srdivacky// A helper class for defining ObjC TypeLocs that can qualified with
769198398Srdivacky// protocols.
770198398Srdivacky//
771198398Srdivacky// TypeClass basically has to be either ObjCInterfaceType or
772198398Srdivacky// ObjCObjectPointerType.
773208600Srdivackyclass ObjCObjectTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
774208600Srdivacky                                                 ObjCObjectTypeLoc,
775208600Srdivacky                                                 ObjCObjectType,
776208600Srdivacky                                                 ObjCProtocolListLocInfo> {
777198092Srdivacky  // SourceLocations are stored after Info, one for each Protocol.
778198092Srdivacky  SourceLocation *getProtocolLocArray() const {
779198398Srdivacky    return (SourceLocation*) this->getExtraLocalData();
780198092Srdivacky  }
781198092Srdivacky
782198092Srdivackypublic:
783198092Srdivacky  SourceLocation getLAngleLoc() const {
784198398Srdivacky    return this->getLocalData()->LAngleLoc;
785198092Srdivacky  }
786198092Srdivacky  void setLAngleLoc(SourceLocation Loc) {
787198398Srdivacky    this->getLocalData()->LAngleLoc = Loc;
788198092Srdivacky  }
789198092Srdivacky
790198092Srdivacky  SourceLocation getRAngleLoc() const {
791198398Srdivacky    return this->getLocalData()->RAngleLoc;
792198092Srdivacky  }
793198092Srdivacky  void setRAngleLoc(SourceLocation Loc) {
794198398Srdivacky    this->getLocalData()->RAngleLoc = Loc;
795198092Srdivacky  }
796198092Srdivacky
797198092Srdivacky  unsigned getNumProtocols() const {
798198398Srdivacky    return this->getTypePtr()->getNumProtocols();
799198092Srdivacky  }
800198092Srdivacky
801198092Srdivacky  SourceLocation getProtocolLoc(unsigned i) const {
802198092Srdivacky    assert(i < getNumProtocols() && "Index is out of bounds!");
803198092Srdivacky    return getProtocolLocArray()[i];
804198092Srdivacky  }
805198092Srdivacky  void setProtocolLoc(unsigned i, SourceLocation Loc) {
806198092Srdivacky    assert(i < getNumProtocols() && "Index is out of bounds!");
807198092Srdivacky    getProtocolLocArray()[i] = Loc;
808198092Srdivacky  }
809198092Srdivacky
810198092Srdivacky  ObjCProtocolDecl *getProtocol(unsigned i) const {
811198092Srdivacky    assert(i < getNumProtocols() && "Index is out of bounds!");
812198398Srdivacky    return *(this->getTypePtr()->qual_begin() + i);
813198092Srdivacky  }
814234353Sdim
815208600Srdivacky  bool hasBaseTypeAsWritten() const {
816208600Srdivacky    return getLocalData()->HasBaseTypeAsWritten;
817208600Srdivacky  }
818208600Srdivacky
819208600Srdivacky  void setHasBaseTypeAsWritten(bool HasBaseType) {
820208600Srdivacky    getLocalData()->HasBaseTypeAsWritten = HasBaseType;
821208600Srdivacky  }
822208600Srdivacky
823208600Srdivacky  TypeLoc getBaseLoc() const {
824208600Srdivacky    return getInnerTypeLoc();
825208600Srdivacky  }
826208600Srdivacky
827208600Srdivacky  SourceRange getLocalSourceRange() const {
828198092Srdivacky    return SourceRange(getLAngleLoc(), getRAngleLoc());
829198092Srdivacky  }
830198092Srdivacky
831218893Sdim  void initializeLocal(ASTContext &Context, SourceLocation Loc) {
832208600Srdivacky    setHasBaseTypeAsWritten(true);
833208600Srdivacky    setLAngleLoc(Loc);
834208600Srdivacky    setRAngleLoc(Loc);
835208600Srdivacky    for (unsigned i = 0, e = getNumProtocols(); i != e; ++i)
836208600Srdivacky      setProtocolLoc(i, Loc);
837198398Srdivacky  }
838198398Srdivacky
839198112Srdivacky  unsigned getExtraLocalDataSize() const {
840198398Srdivacky    return this->getNumProtocols() * sizeof(SourceLocation);
841198092Srdivacky  }
842208600Srdivacky
843208600Srdivacky  QualType getInnerType() const {
844208600Srdivacky    return getTypePtr()->getBaseType();
845208600Srdivacky  }
846198398Srdivacky};
847198092Srdivacky
848198398Srdivacky
849208600Srdivackystruct ObjCInterfaceLocInfo {
850198398Srdivacky  SourceLocation NameLoc;
851239462Sdim  SourceLocation NameEndLoc;
852198112Srdivacky};
853198092Srdivacky
854198398Srdivacky/// \brief Wrapper for source info for ObjC interfaces.
855210299Sedclass ObjCInterfaceTypeLoc : public ConcreteTypeLoc<ObjCObjectTypeLoc,
856208600Srdivacky                                                    ObjCInterfaceTypeLoc,
857208600Srdivacky                                                    ObjCInterfaceType,
858208600Srdivacky                                                    ObjCInterfaceLocInfo> {
859198398Srdivackypublic:
860198398Srdivacky  ObjCInterfaceDecl *getIFaceDecl() const {
861198398Srdivacky    return getTypePtr()->getDecl();
862198398Srdivacky  }
863198112Srdivacky
864198398Srdivacky  SourceLocation getNameLoc() const {
865198398Srdivacky    return getLocalData()->NameLoc;
866198398Srdivacky  }
867198398Srdivacky
868198398Srdivacky  void setNameLoc(SourceLocation Loc) {
869198398Srdivacky    getLocalData()->NameLoc = Loc;
870198398Srdivacky  }
871239462Sdim
872208600Srdivacky  SourceRange getLocalSourceRange() const {
873239462Sdim    return SourceRange(getNameLoc(), getNameEndLoc());
874198398Srdivacky  }
875239462Sdim
876239462Sdim  SourceLocation getNameEndLoc() const {
877239462Sdim    return getLocalData()->NameEndLoc;
878239462Sdim  }
879198398Srdivacky
880239462Sdim  void setNameEndLoc(SourceLocation Loc) {
881239462Sdim    getLocalData()->NameEndLoc = Loc;
882239462Sdim  }
883239462Sdim
884218893Sdim  void initializeLocal(ASTContext &Context, SourceLocation Loc) {
885198398Srdivacky    setNameLoc(Loc);
886243830Sdim    setNameEndLoc(Loc);
887198398Srdivacky  }
888198398Srdivacky};
889198398Srdivacky
890218893Sdimstruct ParenLocInfo {
891218893Sdim  SourceLocation LParenLoc;
892218893Sdim  SourceLocation RParenLoc;
893218893Sdim};
894198398Srdivacky
895218893Sdimclass ParenTypeLoc
896218893Sdim  : public ConcreteTypeLoc<UnqualTypeLoc, ParenTypeLoc, ParenType,
897218893Sdim                           ParenLocInfo> {
898218893Sdimpublic:
899218893Sdim  SourceLocation getLParenLoc() const {
900218893Sdim    return this->getLocalData()->LParenLoc;
901218893Sdim  }
902218893Sdim  SourceLocation getRParenLoc() const {
903218893Sdim    return this->getLocalData()->RParenLoc;
904218893Sdim  }
905218893Sdim  void setLParenLoc(SourceLocation Loc) {
906218893Sdim    this->getLocalData()->LParenLoc = Loc;
907218893Sdim  }
908218893Sdim  void setRParenLoc(SourceLocation Loc) {
909218893Sdim    this->getLocalData()->RParenLoc = Loc;
910218893Sdim  }
911218893Sdim
912218893Sdim  SourceRange getLocalSourceRange() const {
913218893Sdim    return SourceRange(getLParenLoc(), getRParenLoc());
914218893Sdim  }
915218893Sdim
916218893Sdim  void initializeLocal(ASTContext &Context, SourceLocation Loc) {
917218893Sdim    setLParenLoc(Loc);
918218893Sdim    setRParenLoc(Loc);
919218893Sdim  }
920218893Sdim
921218893Sdim  TypeLoc getInnerLoc() const {
922218893Sdim    return getInnerTypeLoc();
923218893Sdim  }
924218893Sdim
925218893Sdim  QualType getInnerType() const {
926218893Sdim    return this->getTypePtr()->getInnerType();
927218893Sdim  }
928218893Sdim};
929218893Sdim
930249423Sdiminline TypeLoc TypeLoc::IgnoreParens() const {
931249423Sdim  if (ParenTypeLoc::isKind(*this))
932249423Sdim    return IgnoreParensImpl(*this);
933249423Sdim  return *this;
934249423Sdim}
935218893Sdim
936198398Srdivackystruct PointerLikeLocInfo {
937198398Srdivacky  SourceLocation StarLoc;
938198092Srdivacky};
939198092Srdivacky
940234353Sdim/// A base class for
941198398Srdivackytemplate <class Derived, class TypeClass, class LocalData = PointerLikeLocInfo>
942198398Srdivackyclass PointerLikeTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, Derived,
943198398Srdivacky                                                  TypeClass, LocalData> {
944234353Sdimpublic:
945198398Srdivacky  SourceLocation getSigilLoc() const {
946198398Srdivacky    return this->getLocalData()->StarLoc;
947198092Srdivacky  }
948198398Srdivacky  void setSigilLoc(SourceLocation Loc) {
949198398Srdivacky    this->getLocalData()->StarLoc = Loc;
950198092Srdivacky  }
951198092Srdivacky
952198092Srdivacky  TypeLoc getPointeeLoc() const {
953198398Srdivacky    return this->getInnerTypeLoc();
954198092Srdivacky  }
955198092Srdivacky
956208600Srdivacky  SourceRange getLocalSourceRange() const {
957198398Srdivacky    return SourceRange(getSigilLoc(), getSigilLoc());
958198092Srdivacky  }
959198092Srdivacky
960218893Sdim  void initializeLocal(ASTContext &Context, SourceLocation Loc) {
961198398Srdivacky    setSigilLoc(Loc);
962198092Srdivacky  }
963198092Srdivacky
964198398Srdivacky  QualType getInnerType() const {
965198398Srdivacky    return this->getTypePtr()->getPointeeType();
966198398Srdivacky  }
967198112Srdivacky};
968198092Srdivacky
969198092Srdivacky
970198398Srdivacky/// \brief Wrapper for source info for pointers.
971198398Srdivackyclass PointerTypeLoc : public PointerLikeTypeLoc<PointerTypeLoc,
972198398Srdivacky                                                 PointerType> {
973198092Srdivackypublic:
974198092Srdivacky  SourceLocation getStarLoc() const {
975198398Srdivacky    return getSigilLoc();
976198092Srdivacky  }
977198092Srdivacky  void setStarLoc(SourceLocation Loc) {
978198398Srdivacky    setSigilLoc(Loc);
979198092Srdivacky  }
980198398Srdivacky};
981198092Srdivacky
982198092Srdivacky
983198398Srdivacky/// \brief Wrapper for source info for block pointers.
984198398Srdivackyclass BlockPointerTypeLoc : public PointerLikeTypeLoc<BlockPointerTypeLoc,
985198398Srdivacky                                                      BlockPointerType> {
986198398Srdivackypublic:
987198398Srdivacky  SourceLocation getCaretLoc() const {
988198398Srdivacky    return getSigilLoc();
989198092Srdivacky  }
990198398Srdivacky  void setCaretLoc(SourceLocation Loc) {
991198398Srdivacky    setSigilLoc(Loc);
992198398Srdivacky  }
993198398Srdivacky};
994198092Srdivacky
995221345Sdimstruct MemberPointerLocInfo : public PointerLikeLocInfo {
996221345Sdim  TypeSourceInfo *ClassTInfo;
997221345Sdim};
998198398Srdivacky
999198398Srdivacky/// \brief Wrapper for source info for member pointers.
1000198398Srdivackyclass MemberPointerTypeLoc : public PointerLikeTypeLoc<MemberPointerTypeLoc,
1001221345Sdim                                                       MemberPointerType,
1002221345Sdim                                                       MemberPointerLocInfo> {
1003198398Srdivackypublic:
1004198398Srdivacky  SourceLocation getStarLoc() const {
1005198398Srdivacky    return getSigilLoc();
1006198092Srdivacky  }
1007198398Srdivacky  void setStarLoc(SourceLocation Loc) {
1008198398Srdivacky    setSigilLoc(Loc);
1009198398Srdivacky  }
1010221345Sdim
1011221345Sdim  const Type *getClass() const {
1012221345Sdim    return getTypePtr()->getClass();
1013221345Sdim  }
1014221345Sdim  TypeSourceInfo *getClassTInfo() const {
1015221345Sdim    return getLocalData()->ClassTInfo;
1016221345Sdim  }
1017221345Sdim  void setClassTInfo(TypeSourceInfo* TI) {
1018221345Sdim    getLocalData()->ClassTInfo = TI;
1019221345Sdim  }
1020221345Sdim
1021221345Sdim  void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1022221345Sdim    setSigilLoc(Loc);
1023221345Sdim    setClassTInfo(0);
1024221345Sdim  }
1025221345Sdim
1026221345Sdim  SourceRange getLocalSourceRange() const {
1027221345Sdim    if (TypeSourceInfo *TI = getClassTInfo())
1028221345Sdim      return SourceRange(TI->getTypeLoc().getBeginLoc(), getStarLoc());
1029221345Sdim    else
1030221345Sdim      return SourceRange(getStarLoc());
1031221345Sdim  }
1032198112Srdivacky};
1033198092Srdivacky
1034208600Srdivacky/// Wraps an ObjCPointerType with source location information.
1035208600Srdivackyclass ObjCObjectPointerTypeLoc :
1036208600Srdivacky    public PointerLikeTypeLoc<ObjCObjectPointerTypeLoc,
1037208600Srdivacky                              ObjCObjectPointerType> {
1038208600Srdivackypublic:
1039208600Srdivacky  SourceLocation getStarLoc() const {
1040208600Srdivacky    return getSigilLoc();
1041208600Srdivacky  }
1042198092Srdivacky
1043208600Srdivacky  void setStarLoc(SourceLocation Loc) {
1044208600Srdivacky    setSigilLoc(Loc);
1045208600Srdivacky  }
1046208600Srdivacky};
1047208600Srdivacky
1048208600Srdivacky
1049198398Srdivackyclass ReferenceTypeLoc : public PointerLikeTypeLoc<ReferenceTypeLoc,
1050198398Srdivacky                                                   ReferenceType> {
1051198398Srdivackypublic:
1052198398Srdivacky  QualType getInnerType() const {
1053198398Srdivacky    return getTypePtr()->getPointeeTypeAsWritten();
1054198398Srdivacky  }
1055198092Srdivacky};
1056198092Srdivacky
1057198398Srdivackyclass LValueReferenceTypeLoc :
1058198398Srdivacky    public InheritingConcreteTypeLoc<ReferenceTypeLoc,
1059198398Srdivacky                                     LValueReferenceTypeLoc,
1060198398Srdivacky                                     LValueReferenceType> {
1061198092Srdivackypublic:
1062198092Srdivacky  SourceLocation getAmpLoc() const {
1063198398Srdivacky    return getSigilLoc();
1064198092Srdivacky  }
1065198092Srdivacky  void setAmpLoc(SourceLocation Loc) {
1066198398Srdivacky    setSigilLoc(Loc);
1067198092Srdivacky  }
1068198398Srdivacky};
1069198092Srdivacky
1070198398Srdivackyclass RValueReferenceTypeLoc :
1071198398Srdivacky    public InheritingConcreteTypeLoc<ReferenceTypeLoc,
1072198398Srdivacky                                     RValueReferenceTypeLoc,
1073198398Srdivacky                                     RValueReferenceType> {
1074198398Srdivackypublic:
1075198398Srdivacky  SourceLocation getAmpAmpLoc() const {
1076198398Srdivacky    return getSigilLoc();
1077198092Srdivacky  }
1078198398Srdivacky  void setAmpAmpLoc(SourceLocation Loc) {
1079198398Srdivacky    setSigilLoc(Loc);
1080198092Srdivacky  }
1081198112Srdivacky};
1082198092Srdivacky
1083198092Srdivacky
1084198112Srdivackystruct FunctionLocInfo {
1085221345Sdim  SourceLocation LocalRangeBegin;
1086243830Sdim  SourceLocation LParenLoc;
1087243830Sdim  SourceLocation RParenLoc;
1088221345Sdim  SourceLocation LocalRangeEnd;
1089198092Srdivacky};
1090198092Srdivacky
1091198092Srdivacky/// \brief Wrapper for source info for functions.
1092198398Srdivackyclass FunctionTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
1093198398Srdivacky                                               FunctionTypeLoc,
1094198398Srdivacky                                               FunctionType,
1095198398Srdivacky                                               FunctionLocInfo> {
1096198092Srdivackypublic:
1097221345Sdim  SourceLocation getLocalRangeBegin() const {
1098221345Sdim    return getLocalData()->LocalRangeBegin;
1099198092Srdivacky  }
1100221345Sdim  void setLocalRangeBegin(SourceLocation L) {
1101221345Sdim    getLocalData()->LocalRangeBegin = L;
1102198092Srdivacky  }
1103198092Srdivacky
1104221345Sdim  SourceLocation getLocalRangeEnd() const {
1105221345Sdim    return getLocalData()->LocalRangeEnd;
1106198092Srdivacky  }
1107221345Sdim  void setLocalRangeEnd(SourceLocation L) {
1108221345Sdim    getLocalData()->LocalRangeEnd = L;
1109198092Srdivacky  }
1110198092Srdivacky
1111243830Sdim  SourceLocation getLParenLoc() const {
1112243830Sdim    return this->getLocalData()->LParenLoc;
1113243830Sdim  }
1114243830Sdim  void setLParenLoc(SourceLocation Loc) {
1115243830Sdim    this->getLocalData()->LParenLoc = Loc;
1116243830Sdim  }
1117243830Sdim
1118243830Sdim  SourceLocation getRParenLoc() const {
1119243830Sdim    return this->getLocalData()->RParenLoc;
1120243830Sdim  }
1121243830Sdim  void setRParenLoc(SourceLocation Loc) {
1122243830Sdim    this->getLocalData()->RParenLoc = Loc;
1123243830Sdim  }
1124243830Sdim
1125243830Sdim  SourceRange getParensRange() const {
1126243830Sdim    return SourceRange(getLParenLoc(), getRParenLoc());
1127243830Sdim  }
1128243830Sdim
1129234353Sdim  ArrayRef<ParmVarDecl *> getParams() const {
1130234353Sdim    return ArrayRef<ParmVarDecl *>(getParmArray(), getNumArgs());
1131234353Sdim  }
1132234353Sdim
1133218893Sdim  // ParmVarDecls* are stored after Info, one for each argument.
1134218893Sdim  ParmVarDecl **getParmArray() const {
1135218893Sdim    return (ParmVarDecl**) getExtraLocalData();
1136218893Sdim  }
1137218893Sdim
1138198092Srdivacky  unsigned getNumArgs() const {
1139198112Srdivacky    if (isa<FunctionNoProtoType>(getTypePtr()))
1140198092Srdivacky      return 0;
1141198112Srdivacky    return cast<FunctionProtoType>(getTypePtr())->getNumArgs();
1142198092Srdivacky  }
1143198092Srdivacky  ParmVarDecl *getArg(unsigned i) const { return getParmArray()[i]; }
1144198092Srdivacky  void setArg(unsigned i, ParmVarDecl *VD) { getParmArray()[i] = VD; }
1145198092Srdivacky
1146198092Srdivacky  TypeLoc getResultLoc() const {
1147198112Srdivacky    return getInnerTypeLoc();
1148198092Srdivacky  }
1149198092Srdivacky
1150208600Srdivacky  SourceRange getLocalSourceRange() const {
1151221345Sdim    return SourceRange(getLocalRangeBegin(), getLocalRangeEnd());
1152198092Srdivacky  }
1153198092Srdivacky
1154218893Sdim  void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1155221345Sdim    setLocalRangeBegin(Loc);
1156243830Sdim    setLParenLoc(Loc);
1157243830Sdim    setRParenLoc(Loc);
1158221345Sdim    setLocalRangeEnd(Loc);
1159198398Srdivacky    for (unsigned i = 0, e = getNumArgs(); i != e; ++i)
1160198398Srdivacky      setArg(i, NULL);
1161198398Srdivacky  }
1162198398Srdivacky
1163198092Srdivacky  /// \brief Returns the size of the type source info data block that is
1164198092Srdivacky  /// specific to this type.
1165198112Srdivacky  unsigned getExtraLocalDataSize() const {
1166198112Srdivacky    return getNumArgs() * sizeof(ParmVarDecl*);
1167198092Srdivacky  }
1168198092Srdivacky
1169198112Srdivacky  QualType getInnerType() const { return getTypePtr()->getResultType(); }
1170198112Srdivacky};
1171198092Srdivacky
1172198398Srdivackyclass FunctionProtoTypeLoc :
1173198398Srdivacky    public InheritingConcreteTypeLoc<FunctionTypeLoc,
1174198398Srdivacky                                     FunctionProtoTypeLoc,
1175198398Srdivacky                                     FunctionProtoType> {
1176198398Srdivacky};
1177198112Srdivacky
1178198398Srdivackyclass FunctionNoProtoTypeLoc :
1179198398Srdivacky    public InheritingConcreteTypeLoc<FunctionTypeLoc,
1180198398Srdivacky                                     FunctionNoProtoTypeLoc,
1181198398Srdivacky                                     FunctionNoProtoType> {
1182198398Srdivacky};
1183198398Srdivacky
1184198398Srdivacky
1185198112Srdivackystruct ArrayLocInfo {
1186198112Srdivacky  SourceLocation LBracketLoc, RBracketLoc;
1187198112Srdivacky  Expr *Size;
1188198092Srdivacky};
1189198092Srdivacky
1190198092Srdivacky/// \brief Wrapper for source info for arrays.
1191198398Srdivackyclass ArrayTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
1192198398Srdivacky                                            ArrayTypeLoc,
1193198398Srdivacky                                            ArrayType,
1194198398Srdivacky                                            ArrayLocInfo> {
1195198092Srdivackypublic:
1196198092Srdivacky  SourceLocation getLBracketLoc() const {
1197198112Srdivacky    return getLocalData()->LBracketLoc;
1198198092Srdivacky  }
1199198092Srdivacky  void setLBracketLoc(SourceLocation Loc) {
1200198112Srdivacky    getLocalData()->LBracketLoc = Loc;
1201198092Srdivacky  }
1202198092Srdivacky
1203198092Srdivacky  SourceLocation getRBracketLoc() const {
1204198112Srdivacky    return getLocalData()->RBracketLoc;
1205198092Srdivacky  }
1206198092Srdivacky  void setRBracketLoc(SourceLocation Loc) {
1207198112Srdivacky    getLocalData()->RBracketLoc = Loc;
1208198092Srdivacky  }
1209198092Srdivacky
1210198893Srdivacky  SourceRange getBracketsRange() const {
1211198893Srdivacky    return SourceRange(getLBracketLoc(), getRBracketLoc());
1212198893Srdivacky  }
1213198893Srdivacky
1214198092Srdivacky  Expr *getSizeExpr() const {
1215198112Srdivacky    return getLocalData()->Size;
1216198092Srdivacky  }
1217198092Srdivacky  void setSizeExpr(Expr *Size) {
1218198112Srdivacky    getLocalData()->Size = Size;
1219198092Srdivacky  }
1220198092Srdivacky
1221198092Srdivacky  TypeLoc getElementLoc() const {
1222198112Srdivacky    return getInnerTypeLoc();
1223198092Srdivacky  }
1224198092Srdivacky
1225208600Srdivacky  SourceRange getLocalSourceRange() const {
1226198092Srdivacky    return SourceRange(getLBracketLoc(), getRBracketLoc());
1227198092Srdivacky  }
1228198092Srdivacky
1229218893Sdim  void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1230198398Srdivacky    setLBracketLoc(Loc);
1231198398Srdivacky    setRBracketLoc(Loc);
1232198398Srdivacky    setSizeExpr(NULL);
1233198398Srdivacky  }
1234198398Srdivacky
1235198112Srdivacky  QualType getInnerType() const { return getTypePtr()->getElementType(); }
1236198092Srdivacky};
1237198092Srdivacky
1238198398Srdivackyclass ConstantArrayTypeLoc :
1239198398Srdivacky    public InheritingConcreteTypeLoc<ArrayTypeLoc,
1240198398Srdivacky                                     ConstantArrayTypeLoc,
1241198398Srdivacky                                     ConstantArrayType> {
1242198398Srdivacky};
1243198398Srdivacky
1244198398Srdivackyclass IncompleteArrayTypeLoc :
1245198398Srdivacky    public InheritingConcreteTypeLoc<ArrayTypeLoc,
1246198398Srdivacky                                     IncompleteArrayTypeLoc,
1247198398Srdivacky                                     IncompleteArrayType> {
1248198398Srdivacky};
1249198398Srdivacky
1250198398Srdivackyclass DependentSizedArrayTypeLoc :
1251198398Srdivacky    public InheritingConcreteTypeLoc<ArrayTypeLoc,
1252198398Srdivacky                                     DependentSizedArrayTypeLoc,
1253198398Srdivacky                                     DependentSizedArrayType> {
1254198398Srdivacky
1255198398Srdivacky};
1256198398Srdivacky
1257198398Srdivackyclass VariableArrayTypeLoc :
1258198398Srdivacky    public InheritingConcreteTypeLoc<ArrayTypeLoc,
1259198398Srdivacky                                     VariableArrayTypeLoc,
1260198398Srdivacky                                     VariableArrayType> {
1261198398Srdivacky};
1262198398Srdivacky
1263198893Srdivacky
1264198893Srdivacky// Location information for a TemplateName.  Rudimentary for now.
1265198893Srdivackystruct TemplateNameLocInfo {
1266198893Srdivacky  SourceLocation NameLoc;
1267198893Srdivacky};
1268198893Srdivacky
1269198893Srdivackystruct TemplateSpecializationLocInfo : TemplateNameLocInfo {
1270234353Sdim  SourceLocation TemplateKWLoc;
1271198893Srdivacky  SourceLocation LAngleLoc;
1272198893Srdivacky  SourceLocation RAngleLoc;
1273198893Srdivacky};
1274198893Srdivacky
1275198893Srdivackyclass TemplateSpecializationTypeLoc :
1276198893Srdivacky    public ConcreteTypeLoc<UnqualTypeLoc,
1277198893Srdivacky                           TemplateSpecializationTypeLoc,
1278198893Srdivacky                           TemplateSpecializationType,
1279198893Srdivacky                           TemplateSpecializationLocInfo> {
1280198893Srdivackypublic:
1281234353Sdim  SourceLocation getTemplateKeywordLoc() const {
1282234353Sdim    return getLocalData()->TemplateKWLoc;
1283234353Sdim  }
1284234353Sdim  void setTemplateKeywordLoc(SourceLocation Loc) {
1285234353Sdim    getLocalData()->TemplateKWLoc = Loc;
1286234353Sdim  }
1287234353Sdim
1288198893Srdivacky  SourceLocation getLAngleLoc() const {
1289198893Srdivacky    return getLocalData()->LAngleLoc;
1290198893Srdivacky  }
1291198893Srdivacky  void setLAngleLoc(SourceLocation Loc) {
1292198893Srdivacky    getLocalData()->LAngleLoc = Loc;
1293198893Srdivacky  }
1294198893Srdivacky
1295198893Srdivacky  SourceLocation getRAngleLoc() const {
1296198893Srdivacky    return getLocalData()->RAngleLoc;
1297198893Srdivacky  }
1298198893Srdivacky  void setRAngleLoc(SourceLocation Loc) {
1299198893Srdivacky    getLocalData()->RAngleLoc = Loc;
1300198893Srdivacky  }
1301198893Srdivacky
1302198893Srdivacky  unsigned getNumArgs() const {
1303198893Srdivacky    return getTypePtr()->getNumArgs();
1304198893Srdivacky  }
1305198893Srdivacky  void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) {
1306198893Srdivacky    getArgInfos()[i] = AI;
1307198893Srdivacky  }
1308198893Srdivacky  TemplateArgumentLocInfo getArgLocInfo(unsigned i) const {
1309198893Srdivacky    return getArgInfos()[i];
1310198893Srdivacky  }
1311198893Srdivacky
1312198893Srdivacky  TemplateArgumentLoc getArgLoc(unsigned i) const {
1313198893Srdivacky    return TemplateArgumentLoc(getTypePtr()->getArg(i), getArgLocInfo(i));
1314198893Srdivacky  }
1315198893Srdivacky
1316198893Srdivacky  SourceLocation getTemplateNameLoc() const {
1317198893Srdivacky    return getLocalData()->NameLoc;
1318198893Srdivacky  }
1319198893Srdivacky  void setTemplateNameLoc(SourceLocation Loc) {
1320198893Srdivacky    getLocalData()->NameLoc = Loc;
1321198893Srdivacky  }
1322198893Srdivacky
1323198893Srdivacky  /// \brief - Copy the location information from the given info.
1324198893Srdivacky  void copy(TemplateSpecializationTypeLoc Loc) {
1325198893Srdivacky    unsigned size = getFullDataSize();
1326198893Srdivacky    assert(size == Loc.getFullDataSize());
1327198893Srdivacky
1328198893Srdivacky    // We're potentially copying Expr references here.  We don't
1329200583Srdivacky    // bother retaining them because TypeSourceInfos live forever, so
1330198893Srdivacky    // as long as the Expr was retained when originally written into
1331198893Srdivacky    // the TypeLoc, we're okay.
1332198893Srdivacky    memcpy(Data, Loc.Data, size);
1333198893Srdivacky  }
1334198893Srdivacky
1335208600Srdivacky  SourceRange getLocalSourceRange() const {
1336234353Sdim    if (getTemplateKeywordLoc().isValid())
1337234353Sdim      return SourceRange(getTemplateKeywordLoc(), getRAngleLoc());
1338234353Sdim    else
1339234353Sdim      return SourceRange(getTemplateNameLoc(), getRAngleLoc());
1340198893Srdivacky  }
1341198893Srdivacky
1342218893Sdim  void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1343234353Sdim    setTemplateKeywordLoc(Loc);
1344234353Sdim    setTemplateNameLoc(Loc);
1345198893Srdivacky    setLAngleLoc(Loc);
1346198893Srdivacky    setRAngleLoc(Loc);
1347218893Sdim    initializeArgLocs(Context, getNumArgs(), getTypePtr()->getArgs(),
1348210299Sed                      getArgInfos(), Loc);
1349210299Sed  }
1350198893Srdivacky
1351218893Sdim  static void initializeArgLocs(ASTContext &Context, unsigned NumArgs,
1352210299Sed                                const TemplateArgument *Args,
1353210299Sed                                TemplateArgumentLocInfo *ArgInfos,
1354218893Sdim                                SourceLocation Loc);
1355198893Srdivacky
1356198893Srdivacky  unsigned getExtraLocalDataSize() const {
1357198893Srdivacky    return getNumArgs() * sizeof(TemplateArgumentLocInfo);
1358198893Srdivacky  }
1359198893Srdivacky
1360198893Srdivackyprivate:
1361198893Srdivacky  TemplateArgumentLocInfo *getArgInfos() const {
1362198893Srdivacky    return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData());
1363198893Srdivacky  }
1364198893Srdivacky};
1365198893Srdivacky
1366200583Srdivacky//===----------------------------------------------------------------------===//
1367200583Srdivacky//
1368200583Srdivacky//  All of these need proper implementations.
1369200583Srdivacky//
1370200583Srdivacky//===----------------------------------------------------------------------===//
1371198398Srdivacky
1372200583Srdivacky// FIXME: size expression and attribute locations (or keyword if we
1373200583Srdivacky// ever fully support altivec syntax).
1374200583Srdivackyclass VectorTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
1375200583Srdivacky                                                       VectorTypeLoc,
1376200583Srdivacky                                                       VectorType> {
1377198398Srdivacky};
1378198398Srdivacky
1379200583Srdivacky// FIXME: size expression and attribute locations.
1380198398Srdivackyclass ExtVectorTypeLoc : public InheritingConcreteTypeLoc<VectorTypeLoc,
1381198398Srdivacky                                                          ExtVectorTypeLoc,
1382198398Srdivacky                                                          ExtVectorType> {
1383198398Srdivacky};
1384198398Srdivacky
1385200583Srdivacky// FIXME: attribute locations.
1386198398Srdivacky// For some reason, this isn't a subtype of VectorType.
1387198398Srdivackyclass DependentSizedExtVectorTypeLoc :
1388200583Srdivacky    public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
1389200583Srdivacky                                     DependentSizedExtVectorTypeLoc,
1390200583Srdivacky                                     DependentSizedExtVectorType> {
1391198398Srdivacky};
1392198398Srdivacky
1393200583Srdivacky// FIXME: location of the '_Complex' keyword.
1394200583Srdivackyclass ComplexTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
1395200583Srdivacky                                                        ComplexTypeLoc,
1396200583Srdivacky                                                        ComplexType> {
1397198398Srdivacky};
1398198398Srdivacky
1399202379Srdivackystruct TypeofLocInfo {
1400202379Srdivacky  SourceLocation TypeofLoc;
1401202379Srdivacky  SourceLocation LParenLoc;
1402202379Srdivacky  SourceLocation RParenLoc;
1403198398Srdivacky};
1404198398Srdivacky
1405202379Srdivackystruct TypeOfExprTypeLocInfo : public TypeofLocInfo {
1406198398Srdivacky};
1407198398Srdivacky
1408202379Srdivackystruct TypeOfTypeLocInfo : public TypeofLocInfo {
1409202379Srdivacky  TypeSourceInfo* UnderlyingTInfo;
1410202379Srdivacky};
1411202379Srdivacky
1412202379Srdivackytemplate <class Derived, class TypeClass, class LocalData = TypeofLocInfo>
1413202379Srdivackyclass TypeofLikeTypeLoc
1414202379Srdivacky  : public ConcreteTypeLoc<UnqualTypeLoc, Derived, TypeClass, LocalData> {
1415202379Srdivackypublic:
1416202379Srdivacky  SourceLocation getTypeofLoc() const {
1417202379Srdivacky    return this->getLocalData()->TypeofLoc;
1418202379Srdivacky  }
1419202379Srdivacky  void setTypeofLoc(SourceLocation Loc) {
1420202379Srdivacky    this->getLocalData()->TypeofLoc = Loc;
1421202379Srdivacky  }
1422202379Srdivacky
1423202379Srdivacky  SourceLocation getLParenLoc() const {
1424202379Srdivacky    return this->getLocalData()->LParenLoc;
1425202379Srdivacky  }
1426202379Srdivacky  void setLParenLoc(SourceLocation Loc) {
1427202379Srdivacky    this->getLocalData()->LParenLoc = Loc;
1428202379Srdivacky  }
1429202379Srdivacky
1430202379Srdivacky  SourceLocation getRParenLoc() const {
1431202379Srdivacky    return this->getLocalData()->RParenLoc;
1432202379Srdivacky  }
1433202379Srdivacky  void setRParenLoc(SourceLocation Loc) {
1434202379Srdivacky    this->getLocalData()->RParenLoc = Loc;
1435202379Srdivacky  }
1436202379Srdivacky
1437202379Srdivacky  SourceRange getParensRange() const {
1438202379Srdivacky    return SourceRange(getLParenLoc(), getRParenLoc());
1439202379Srdivacky  }
1440202379Srdivacky  void setParensRange(SourceRange range) {
1441202379Srdivacky      setLParenLoc(range.getBegin());
1442202379Srdivacky      setRParenLoc(range.getEnd());
1443202379Srdivacky  }
1444202379Srdivacky
1445208600Srdivacky  SourceRange getLocalSourceRange() const {
1446202379Srdivacky    return SourceRange(getTypeofLoc(), getRParenLoc());
1447202379Srdivacky  }
1448202379Srdivacky
1449218893Sdim  void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1450202379Srdivacky    setTypeofLoc(Loc);
1451202379Srdivacky    setLParenLoc(Loc);
1452202379Srdivacky    setRParenLoc(Loc);
1453202379Srdivacky  }
1454202379Srdivacky};
1455202379Srdivacky
1456202379Srdivackyclass TypeOfExprTypeLoc : public TypeofLikeTypeLoc<TypeOfExprTypeLoc,
1457202379Srdivacky                                                   TypeOfExprType,
1458202379Srdivacky                                                   TypeOfExprTypeLocInfo> {
1459202379Srdivackypublic:
1460202379Srdivacky  Expr* getUnderlyingExpr() const {
1461202379Srdivacky    return getTypePtr()->getUnderlyingExpr();
1462202379Srdivacky  }
1463202379Srdivacky  // Reimplemented to account for GNU/C++ extension
1464202379Srdivacky  //     typeof unary-expression
1465202379Srdivacky  // where there are no parentheses.
1466208600Srdivacky  SourceRange getLocalSourceRange() const;
1467202379Srdivacky};
1468202379Srdivacky
1469202379Srdivackyclass TypeOfTypeLoc
1470202379Srdivacky  : public TypeofLikeTypeLoc<TypeOfTypeLoc, TypeOfType, TypeOfTypeLocInfo> {
1471202379Srdivackypublic:
1472202379Srdivacky  QualType getUnderlyingType() const {
1473202379Srdivacky    return this->getTypePtr()->getUnderlyingType();
1474202379Srdivacky  }
1475202379Srdivacky  TypeSourceInfo* getUnderlyingTInfo() const {
1476202379Srdivacky    return this->getLocalData()->UnderlyingTInfo;
1477202379Srdivacky  }
1478202379Srdivacky  void setUnderlyingTInfo(TypeSourceInfo* TI) const {
1479202379Srdivacky    this->getLocalData()->UnderlyingTInfo = TI;
1480202379Srdivacky  }
1481202379Srdivacky};
1482202379Srdivacky
1483200583Srdivacky// FIXME: location of the 'decltype' and parens.
1484200583Srdivackyclass DecltypeTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
1485200583Srdivacky                                                         DecltypeTypeLoc,
1486200583Srdivacky                                                         DecltypeType> {
1487226633Sdimpublic:
1488226633Sdim  Expr *getUnderlyingExpr() const { return getTypePtr()->getUnderlyingExpr(); }
1489198398Srdivacky};
1490198398Srdivacky
1491223017Sdimstruct UnaryTransformTypeLocInfo {
1492223017Sdim  // FIXME: While there's only one unary transform right now, future ones may
1493223017Sdim  // need different representations
1494223017Sdim  SourceLocation KWLoc, LParenLoc, RParenLoc;
1495223017Sdim  TypeSourceInfo *UnderlyingTInfo;
1496223017Sdim};
1497223017Sdim
1498223017Sdimclass UnaryTransformTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
1499223017Sdim                                                    UnaryTransformTypeLoc,
1500223017Sdim                                                    UnaryTransformType,
1501223017Sdim                                                    UnaryTransformTypeLocInfo> {
1502223017Sdimpublic:
1503223017Sdim  SourceLocation getKWLoc() const { return getLocalData()->KWLoc; }
1504223017Sdim  void setKWLoc(SourceLocation Loc) { getLocalData()->KWLoc = Loc; }
1505223017Sdim
1506223017Sdim  SourceLocation getLParenLoc() const { return getLocalData()->LParenLoc; }
1507223017Sdim  void setLParenLoc(SourceLocation Loc) { getLocalData()->LParenLoc = Loc; }
1508223017Sdim
1509223017Sdim  SourceLocation getRParenLoc() const { return getLocalData()->RParenLoc; }
1510223017Sdim  void setRParenLoc(SourceLocation Loc) { getLocalData()->RParenLoc = Loc; }
1511223017Sdim
1512223017Sdim  TypeSourceInfo* getUnderlyingTInfo() const {
1513223017Sdim    return getLocalData()->UnderlyingTInfo;
1514223017Sdim  }
1515223017Sdim  void setUnderlyingTInfo(TypeSourceInfo *TInfo) {
1516223017Sdim    getLocalData()->UnderlyingTInfo = TInfo;
1517223017Sdim  }
1518223017Sdim
1519223017Sdim  SourceRange getLocalSourceRange() const {
1520223017Sdim    return SourceRange(getKWLoc(), getRParenLoc());
1521223017Sdim  }
1522223017Sdim
1523223017Sdim  SourceRange getParensRange() const {
1524223017Sdim    return SourceRange(getLParenLoc(), getRParenLoc());
1525223017Sdim  }
1526223017Sdim  void setParensRange(SourceRange Range) {
1527223017Sdim    setLParenLoc(Range.getBegin());
1528223017Sdim    setRParenLoc(Range.getEnd());
1529223017Sdim  }
1530223017Sdim
1531223017Sdim  void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1532223017Sdim    setKWLoc(Loc);
1533223017Sdim    setRParenLoc(Loc);
1534223017Sdim    setLParenLoc(Loc);
1535223017Sdim  }
1536223017Sdim};
1537223017Sdim
1538218893Sdimclass AutoTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
1539218893Sdim                                                        AutoTypeLoc,
1540218893Sdim                                                        AutoType> {
1541218893Sdim};
1542218893Sdim
1543208600Srdivackystruct ElaboratedLocInfo {
1544234353Sdim  SourceLocation ElaboratedKWLoc;
1545234353Sdim  /// \brief Data associated with the nested-name-specifier location.
1546221345Sdim  void *QualifierData;
1547198398Srdivacky};
1548198398Srdivacky
1549208600Srdivackyclass ElaboratedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
1550208600Srdivacky                                                 ElaboratedTypeLoc,
1551208600Srdivacky                                                 ElaboratedType,
1552208600Srdivacky                                                 ElaboratedLocInfo> {
1553208600Srdivackypublic:
1554234353Sdim  SourceLocation getElaboratedKeywordLoc() const {
1555234353Sdim    return this->getLocalData()->ElaboratedKWLoc;
1556208600Srdivacky  }
1557234353Sdim  void setElaboratedKeywordLoc(SourceLocation Loc) {
1558234353Sdim    this->getLocalData()->ElaboratedKWLoc = Loc;
1559208600Srdivacky  }
1560208600Srdivacky
1561221345Sdim  NestedNameSpecifierLoc getQualifierLoc() const {
1562234353Sdim    return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
1563221345Sdim                                  getLocalData()->QualifierData);
1564208600Srdivacky  }
1565234353Sdim
1566221345Sdim  void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
1567234353Sdim    assert(QualifierLoc.getNestedNameSpecifier()
1568221345Sdim                                            == getTypePtr()->getQualifier() &&
1569221345Sdim           "Inconsistent nested-name-specifier pointer");
1570221345Sdim    getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
1571208600Srdivacky  }
1572208600Srdivacky
1573208600Srdivacky  SourceRange getLocalSourceRange() const {
1574234353Sdim    if (getElaboratedKeywordLoc().isValid())
1575221345Sdim      if (getQualifierLoc())
1576234353Sdim        return SourceRange(getElaboratedKeywordLoc(),
1577234353Sdim                           getQualifierLoc().getEndLoc());
1578208600Srdivacky      else
1579234353Sdim        return SourceRange(getElaboratedKeywordLoc());
1580208600Srdivacky    else
1581221345Sdim      return getQualifierLoc().getSourceRange();
1582208600Srdivacky  }
1583208600Srdivacky
1584221345Sdim  void initializeLocal(ASTContext &Context, SourceLocation Loc);
1585208600Srdivacky
1586208600Srdivacky  TypeLoc getNamedTypeLoc() const {
1587208600Srdivacky    return getInnerTypeLoc();
1588208600Srdivacky  }
1589208600Srdivacky
1590208600Srdivacky  QualType getInnerType() const {
1591208600Srdivacky    return getTypePtr()->getNamedType();
1592208600Srdivacky  }
1593208600Srdivacky
1594208600Srdivacky  void copy(ElaboratedTypeLoc Loc) {
1595208600Srdivacky    unsigned size = getFullDataSize();
1596208600Srdivacky    assert(size == Loc.getFullDataSize());
1597208600Srdivacky    memcpy(Data, Loc.Data, size);
1598208600Srdivacky  }
1599198398Srdivacky};
1600198398Srdivacky
1601210299Sed// This is exactly the structure of an ElaboratedTypeLoc whose inner
1602210299Sed// type is some sort of TypeDeclTypeLoc.
1603210299Sedstruct DependentNameLocInfo : ElaboratedLocInfo {
1604208600Srdivacky  SourceLocation NameLoc;
1605198398Srdivacky};
1606198398Srdivacky
1607208600Srdivackyclass DependentNameTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
1608208600Srdivacky                                                    DependentNameTypeLoc,
1609208600Srdivacky                                                    DependentNameType,
1610208600Srdivacky                                                    DependentNameLocInfo> {
1611208600Srdivackypublic:
1612234353Sdim  SourceLocation getElaboratedKeywordLoc() const {
1613234353Sdim    return this->getLocalData()->ElaboratedKWLoc;
1614208600Srdivacky  }
1615234353Sdim  void setElaboratedKeywordLoc(SourceLocation Loc) {
1616234353Sdim    this->getLocalData()->ElaboratedKWLoc = Loc;
1617208600Srdivacky  }
1618208600Srdivacky
1619221345Sdim  NestedNameSpecifierLoc getQualifierLoc() const {
1620234353Sdim    return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
1621221345Sdim                                  getLocalData()->QualifierData);
1622208600Srdivacky  }
1623234353Sdim
1624221345Sdim  void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
1625234353Sdim    assert(QualifierLoc.getNestedNameSpecifier()
1626221345Sdim                                            == getTypePtr()->getQualifier() &&
1627221345Sdim           "Inconsistent nested-name-specifier pointer");
1628221345Sdim    getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
1629208600Srdivacky  }
1630234353Sdim
1631208600Srdivacky  SourceLocation getNameLoc() const {
1632208600Srdivacky    return this->getLocalData()->NameLoc;
1633208600Srdivacky  }
1634208600Srdivacky  void setNameLoc(SourceLocation Loc) {
1635208600Srdivacky    this->getLocalData()->NameLoc = Loc;
1636208600Srdivacky  }
1637208600Srdivacky
1638208600Srdivacky  SourceRange getLocalSourceRange() const {
1639234353Sdim    if (getElaboratedKeywordLoc().isValid())
1640234353Sdim      return SourceRange(getElaboratedKeywordLoc(), getNameLoc());
1641208600Srdivacky    else
1642221345Sdim      return SourceRange(getQualifierLoc().getBeginLoc(), getNameLoc());
1643208600Srdivacky  }
1644208600Srdivacky
1645208600Srdivacky  void copy(DependentNameTypeLoc Loc) {
1646208600Srdivacky    unsigned size = getFullDataSize();
1647208600Srdivacky    assert(size == Loc.getFullDataSize());
1648208600Srdivacky    memcpy(Data, Loc.Data, size);
1649208600Srdivacky  }
1650208600Srdivacky
1651221345Sdim  void initializeLocal(ASTContext &Context, SourceLocation Loc);
1652208600Srdivacky};
1653208600Srdivacky
1654210299Sedstruct DependentTemplateSpecializationLocInfo : DependentNameLocInfo {
1655234353Sdim  SourceLocation TemplateKWLoc;
1656210299Sed  SourceLocation LAngleLoc;
1657210299Sed  SourceLocation RAngleLoc;
1658210299Sed  // followed by a TemplateArgumentLocInfo[]
1659210299Sed};
1660210299Sed
1661210299Sedclass DependentTemplateSpecializationTypeLoc :
1662210299Sed    public ConcreteTypeLoc<UnqualTypeLoc,
1663210299Sed                           DependentTemplateSpecializationTypeLoc,
1664210299Sed                           DependentTemplateSpecializationType,
1665210299Sed                           DependentTemplateSpecializationLocInfo> {
1666210299Sedpublic:
1667234353Sdim  SourceLocation getElaboratedKeywordLoc() const {
1668234353Sdim    return this->getLocalData()->ElaboratedKWLoc;
1669210299Sed  }
1670234353Sdim  void setElaboratedKeywordLoc(SourceLocation Loc) {
1671234353Sdim    this->getLocalData()->ElaboratedKWLoc = Loc;
1672210299Sed  }
1673210299Sed
1674221345Sdim  NestedNameSpecifierLoc getQualifierLoc() const {
1675221345Sdim    if (!getLocalData()->QualifierData)
1676221345Sdim      return NestedNameSpecifierLoc();
1677234353Sdim
1678234353Sdim    return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
1679221345Sdim                                  getLocalData()->QualifierData);
1680210299Sed  }
1681234353Sdim
1682221345Sdim  void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
1683221345Sdim    if (!QualifierLoc) {
1684234353Sdim      // Even if we have a nested-name-specifier in the dependent
1685221345Sdim      // template specialization type, we won't record the nested-name-specifier
1686221345Sdim      // location information when this type-source location information is
1687221345Sdim      // part of a nested-name-specifier.
1688221345Sdim      getLocalData()->QualifierData = 0;
1689221345Sdim      return;
1690221345Sdim    }
1691234353Sdim
1692234353Sdim    assert(QualifierLoc.getNestedNameSpecifier()
1693221345Sdim                                        == getTypePtr()->getQualifier() &&
1694221345Sdim           "Inconsistent nested-name-specifier pointer");
1695221345Sdim    getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
1696210299Sed  }
1697210299Sed
1698234353Sdim  SourceLocation getTemplateKeywordLoc() const {
1699234353Sdim    return getLocalData()->TemplateKWLoc;
1700234353Sdim  }
1701234353Sdim  void setTemplateKeywordLoc(SourceLocation Loc) {
1702234353Sdim    getLocalData()->TemplateKWLoc = Loc;
1703234353Sdim  }
1704234353Sdim
1705234353Sdim  SourceLocation getTemplateNameLoc() const {
1706210299Sed    return this->getLocalData()->NameLoc;
1707210299Sed  }
1708234353Sdim  void setTemplateNameLoc(SourceLocation Loc) {
1709210299Sed    this->getLocalData()->NameLoc = Loc;
1710210299Sed  }
1711210299Sed
1712210299Sed  SourceLocation getLAngleLoc() const {
1713210299Sed    return this->getLocalData()->LAngleLoc;
1714210299Sed  }
1715210299Sed  void setLAngleLoc(SourceLocation Loc) {
1716210299Sed    this->getLocalData()->LAngleLoc = Loc;
1717210299Sed  }
1718210299Sed
1719210299Sed  SourceLocation getRAngleLoc() const {
1720210299Sed    return this->getLocalData()->RAngleLoc;
1721210299Sed  }
1722210299Sed  void setRAngleLoc(SourceLocation Loc) {
1723210299Sed    this->getLocalData()->RAngleLoc = Loc;
1724210299Sed  }
1725210299Sed
1726210299Sed  unsigned getNumArgs() const {
1727210299Sed    return getTypePtr()->getNumArgs();
1728210299Sed  }
1729210299Sed
1730210299Sed  void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) {
1731210299Sed    getArgInfos()[i] = AI;
1732210299Sed  }
1733210299Sed  TemplateArgumentLocInfo getArgLocInfo(unsigned i) const {
1734210299Sed    return getArgInfos()[i];
1735210299Sed  }
1736210299Sed
1737210299Sed  TemplateArgumentLoc getArgLoc(unsigned i) const {
1738210299Sed    return TemplateArgumentLoc(getTypePtr()->getArg(i), getArgLocInfo(i));
1739210299Sed  }
1740210299Sed
1741210299Sed  SourceRange getLocalSourceRange() const {
1742234353Sdim    if (getElaboratedKeywordLoc().isValid())
1743234353Sdim      return SourceRange(getElaboratedKeywordLoc(), getRAngleLoc());
1744221345Sdim    else if (getQualifierLoc())
1745221345Sdim      return SourceRange(getQualifierLoc().getBeginLoc(), getRAngleLoc());
1746234353Sdim    else if (getTemplateKeywordLoc().isValid())
1747234353Sdim      return SourceRange(getTemplateKeywordLoc(), getRAngleLoc());
1748210299Sed    else
1749234353Sdim      return SourceRange(getTemplateNameLoc(), getRAngleLoc());
1750210299Sed  }
1751210299Sed
1752210299Sed  void copy(DependentTemplateSpecializationTypeLoc Loc) {
1753210299Sed    unsigned size = getFullDataSize();
1754210299Sed    assert(size == Loc.getFullDataSize());
1755210299Sed    memcpy(Data, Loc.Data, size);
1756210299Sed  }
1757210299Sed
1758221345Sdim  void initializeLocal(ASTContext &Context, SourceLocation Loc);
1759210299Sed
1760210299Sed  unsigned getExtraLocalDataSize() const {
1761210299Sed    return getNumArgs() * sizeof(TemplateArgumentLocInfo);
1762210299Sed  }
1763210299Sed
1764210299Sedprivate:
1765210299Sed  TemplateArgumentLocInfo *getArgInfos() const {
1766210299Sed    return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData());
1767210299Sed  }
1768210299Sed};
1769210299Sed
1770218893Sdim
1771218893Sdimstruct PackExpansionTypeLocInfo {
1772218893Sdim  SourceLocation EllipsisLoc;
1773218893Sdim};
1774218893Sdim
1775218893Sdimclass PackExpansionTypeLoc
1776234353Sdim  : public ConcreteTypeLoc<UnqualTypeLoc, PackExpansionTypeLoc,
1777218893Sdim                           PackExpansionType, PackExpansionTypeLocInfo> {
1778218893Sdimpublic:
1779218893Sdim  SourceLocation getEllipsisLoc() const {
1780218893Sdim    return this->getLocalData()->EllipsisLoc;
1781218893Sdim  }
1782218893Sdim
1783218893Sdim  void setEllipsisLoc(SourceLocation Loc) {
1784218893Sdim    this->getLocalData()->EllipsisLoc = Loc;
1785218893Sdim  }
1786218893Sdim
1787218893Sdim  SourceRange getLocalSourceRange() const {
1788218893Sdim    return SourceRange(getEllipsisLoc(), getEllipsisLoc());
1789218893Sdim  }
1790218893Sdim
1791218893Sdim  void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1792218893Sdim    setEllipsisLoc(Loc);
1793218893Sdim  }
1794218893Sdim
1795218893Sdim  TypeLoc getPatternLoc() const {
1796218893Sdim    return getInnerTypeLoc();
1797218893Sdim  }
1798218893Sdim
1799218893Sdim  QualType getInnerType() const {
1800218893Sdim    return this->getTypePtr()->getPattern();
1801218893Sdim  }
1802218893Sdim};
1803218893Sdim
1804226633Sdimstruct AtomicTypeLocInfo {
1805226633Sdim  SourceLocation KWLoc, LParenLoc, RParenLoc;
1806226633Sdim};
1807226633Sdim
1808226633Sdimclass AtomicTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, AtomicTypeLoc,
1809226633Sdim                                             AtomicType, AtomicTypeLocInfo> {
1810234353Sdimpublic:
1811226633Sdim  TypeLoc getValueLoc() const {
1812226633Sdim    return this->getInnerTypeLoc();
1813226633Sdim  }
1814226633Sdim
1815226633Sdim  SourceRange getLocalSourceRange() const {
1816226633Sdim    return SourceRange(getKWLoc(), getRParenLoc());
1817226633Sdim  }
1818226633Sdim
1819226633Sdim  SourceLocation getKWLoc() const {
1820226633Sdim    return this->getLocalData()->KWLoc;
1821226633Sdim  }
1822226633Sdim  void setKWLoc(SourceLocation Loc) {
1823226633Sdim    this->getLocalData()->KWLoc = Loc;
1824226633Sdim  }
1825226633Sdim
1826226633Sdim  SourceLocation getLParenLoc() const {
1827226633Sdim    return this->getLocalData()->LParenLoc;
1828226633Sdim  }
1829226633Sdim  void setLParenLoc(SourceLocation Loc) {
1830226633Sdim    this->getLocalData()->LParenLoc = Loc;
1831226633Sdim  }
1832226633Sdim
1833226633Sdim  SourceLocation getRParenLoc() const {
1834226633Sdim    return this->getLocalData()->RParenLoc;
1835226633Sdim  }
1836226633Sdim  void setRParenLoc(SourceLocation Loc) {
1837226633Sdim    this->getLocalData()->RParenLoc = Loc;
1838226633Sdim  }
1839226633Sdim
1840226633Sdim  SourceRange getParensRange() const {
1841226633Sdim    return SourceRange(getLParenLoc(), getRParenLoc());
1842226633Sdim  }
1843226633Sdim  void setParensRange(SourceRange Range) {
1844226633Sdim    setLParenLoc(Range.getBegin());
1845226633Sdim    setRParenLoc(Range.getEnd());
1846226633Sdim  }
1847226633Sdim
1848226633Sdim  void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1849226633Sdim    setKWLoc(Loc);
1850226633Sdim    setLParenLoc(Loc);
1851226633Sdim    setRParenLoc(Loc);
1852226633Sdim  }
1853226633Sdim
1854226633Sdim  QualType getInnerType() const {
1855226633Sdim    return this->getTypePtr()->getValueType();
1856226633Sdim  }
1857226633Sdim};
1858226633Sdim
1859226633Sdim
1860198092Srdivacky}
1861198092Srdivacky
1862198092Srdivacky#endif
1863