TypeLoc.h revision 38a42916cb07fd368d9e2ae1e7915fa896f9ec06
1//===--- TypeLoc.h - Type Source Info Wrapper -------------------*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10//  This file defines the TypeLoc interface and subclasses.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_CLANG_AST_TYPELOC_H
15#define LLVM_CLANG_AST_TYPELOC_H
16
17#include "clang/AST/Type.h"
18#include "clang/AST/Decl.h"
19#include "clang/AST/TemplateBase.h"
20#include "clang/Basic/Specifiers.h"
21
22namespace clang {
23  class ASTContext;
24  class ParmVarDecl;
25  class TypeSourceInfo;
26  class UnqualTypeLoc;
27
28// Predeclare all the type nodes.
29#define ABSTRACT_TYPELOC(Class, Base)
30#define TYPELOC(Class, Base) \
31  class Class##TypeLoc;
32#include "clang/AST/TypeLocNodes.def"
33
34/// \brief Base wrapper for a particular "section" of type source info.
35///
36/// A client should use the TypeLoc subclasses through cast/dyn_cast in order to
37/// get at the actual information.
38class TypeLoc {
39protected:
40  // The correctness of this relies on the property that, for Type *Ty,
41  //   QualType(Ty, 0).getAsOpaquePtr() == (void*) Ty
42  const void *Ty;
43  void *Data;
44
45public:
46  /// The kinds of TypeLocs.  Equivalent to the Type::TypeClass enum,
47  /// except it also defines a Qualified enum that corresponds to the
48  /// QualifiedLoc class.
49  enum TypeLocClass {
50#define ABSTRACT_TYPE(Class, Base)
51#define TYPE(Class, Base) \
52    Class = Type::Class,
53#include "clang/AST/TypeNodes.def"
54    Qualified
55  };
56
57  TypeLoc() : Ty(0), Data(0) { }
58  TypeLoc(QualType ty, void *opaqueData)
59    : Ty(ty.getAsOpaquePtr()), Data(opaqueData) { }
60  TypeLoc(const Type *ty, void *opaqueData)
61    : Ty(ty), Data(opaqueData) { }
62
63  TypeLocClass getTypeLocClass() const {
64    if (getType().hasLocalQualifiers()) return Qualified;
65    return (TypeLocClass) getType()->getTypeClass();
66  }
67
68  bool isNull() const { return !Ty; }
69  operator bool() const { return Ty; }
70
71  /// \brief Returns the size of type source info data block for the given type.
72  static unsigned getFullDataSizeForType(QualType Ty);
73
74  /// \brief Get the type for which this source info wrapper provides
75  /// information.
76  QualType getType() const {
77    return QualType::getFromOpaquePtr(Ty);
78  }
79
80  const Type *getTypePtr() const {
81    return QualType::getFromOpaquePtr(Ty).getTypePtr();
82  }
83
84  /// \brief Get the pointer where source information is stored.
85  void *getOpaqueData() const {
86    return Data;
87  }
88
89  /// \brief Get the begin source location.
90  SourceLocation getBeginLoc() const;
91
92  /// \brief Get the end source location.
93  SourceLocation getEndLoc() const;
94
95  /// \brief Get the full source range.
96  SourceRange getSourceRange() const {
97    return SourceRange(getBeginLoc(), getEndLoc());
98  }
99
100  /// \brief Get the local source range.
101  SourceRange getLocalSourceRange() const {
102    return getLocalSourceRangeImpl(*this);
103  }
104
105  /// \brief Returns the size of the type source info data block.
106  unsigned getFullDataSize() const {
107    return getFullDataSizeForType(getType());
108  }
109
110  /// \brief Get the next TypeLoc pointed by this TypeLoc, e.g for "int*" the
111  /// TypeLoc is a PointerLoc and next TypeLoc is for "int".
112  TypeLoc getNextTypeLoc() const {
113    return getNextTypeLocImpl(*this);
114  }
115
116  /// \brief Skips past any qualifiers, if this is qualified.
117  UnqualTypeLoc getUnqualifiedLoc() const; // implemented in this header
118
119  TypeLoc IgnoreParens() const {
120    if (isa<ParenTypeLoc>(this))
121      return IgnoreParensImpl(*this);
122    return *this;
123  }
124
125  /// \brief Initializes this to state that every location in this
126  /// type is the given location.
127  ///
128  /// This method exists to provide a simple transition for code that
129  /// relies on location-less types.
130  void initialize(ASTContext &Context, SourceLocation Loc) const {
131    initializeImpl(Context, *this, Loc);
132  }
133
134  /// \brief Initializes this by copying its information from another
135  /// TypeLoc of the same type.
136  void initializeFullCopy(TypeLoc Other) const {
137    assert(getType() == Other.getType());
138    size_t Size = getFullDataSize();
139    memcpy(getOpaqueData(), Other.getOpaqueData(), Size);
140  }
141
142  /// \brief Initializes this by copying its information from another
143  /// TypeLoc of the same type.  The given size must be the full data
144  /// size.
145  void initializeFullCopy(TypeLoc Other, unsigned Size) const {
146    assert(getType() == Other.getType());
147    assert(getFullDataSize() == Size);
148    memcpy(getOpaqueData(), Other.getOpaqueData(), Size);
149  }
150
151  friend bool operator==(const TypeLoc &LHS, const TypeLoc &RHS) {
152    return LHS.Ty == RHS.Ty && LHS.Data == RHS.Data;
153  }
154
155  friend bool operator!=(const TypeLoc &LHS, const TypeLoc &RHS) {
156    return !(LHS == RHS);
157  }
158
159  static bool classof(const TypeLoc *TL) { return true; }
160
161private:
162  static void initializeImpl(ASTContext &Context, TypeLoc TL,
163                             SourceLocation Loc);
164  static TypeLoc getNextTypeLocImpl(TypeLoc TL);
165  static TypeLoc IgnoreParensImpl(TypeLoc TL);
166  static SourceRange getLocalSourceRangeImpl(TypeLoc TL);
167};
168
169/// \brief Return the TypeLoc for a type source info.
170inline TypeLoc TypeSourceInfo::getTypeLoc() const {
171  return TypeLoc(Ty, const_cast<void*>(static_cast<const void*>(this + 1)));
172}
173
174/// \brief Wrapper of type source information for a type with
175/// no direct qualifiers.
176class UnqualTypeLoc : public TypeLoc {
177public:
178  UnqualTypeLoc() {}
179  UnqualTypeLoc(const Type *Ty, void *Data) : TypeLoc(Ty, Data) {}
180
181  const Type *getTypePtr() const {
182    return reinterpret_cast<const Type*>(Ty);
183  }
184
185  TypeLocClass getTypeLocClass() const {
186    return (TypeLocClass) getTypePtr()->getTypeClass();
187  }
188
189  static bool classof(const TypeLoc *TL) {
190    return !TL->getType().hasLocalQualifiers();
191  }
192  static bool classof(const UnqualTypeLoc *TL) { return true; }
193};
194
195/// \brief Wrapper of type source information for a type with
196/// non-trivial direct qualifiers.
197///
198/// Currently, we intentionally do not provide source location for
199/// type qualifiers.
200class QualifiedTypeLoc : public TypeLoc {
201public:
202  SourceRange getLocalSourceRange() const {
203    return SourceRange();
204  }
205
206  UnqualTypeLoc getUnqualifiedLoc() const {
207    return UnqualTypeLoc(getTypePtr(), Data);
208  }
209
210  /// Initializes the local data of this type source info block to
211  /// provide no information.
212  void initializeLocal(ASTContext &Context, SourceLocation Loc) {
213    // do nothing
214  }
215
216  TypeLoc getNextTypeLoc() const {
217    return getUnqualifiedLoc();
218  }
219
220  /// \brief Returns the size of the type source info data block that is
221  /// specific to this type.
222  unsigned getLocalDataSize() const {
223    // In fact, we don't currently preserve any location information
224    // for qualifiers.
225    return 0;
226  }
227
228  /// \brief Returns the size of the type source info data block.
229  unsigned getFullDataSize() const {
230    return getLocalDataSize() +
231      getFullDataSizeForType(getType().getLocalUnqualifiedType());
232  }
233
234  static bool classof(const TypeLoc *TL) {
235    return TL->getType().hasLocalQualifiers();
236  }
237  static bool classof(const QualifiedTypeLoc *TL) { return true; }
238};
239
240inline UnqualTypeLoc TypeLoc::getUnqualifiedLoc() const {
241  if (isa<QualifiedTypeLoc>(this))
242    return cast<QualifiedTypeLoc>(this)->getUnqualifiedLoc();
243  return cast<UnqualTypeLoc>(*this);
244}
245
246/// A metaprogramming base class for TypeLoc classes which correspond
247/// to a particular Type subclass.  It is accepted for a single
248/// TypeLoc class to correspond to multiple Type classes.
249///
250/// \param Base a class from which to derive
251/// \param Derived the class deriving from this one
252/// \param TypeClass the concrete Type subclass associated with this
253///   location type
254/// \param LocalData the structure type of local location data for
255///   this type
256///
257/// sizeof(LocalData) needs to be a multiple of sizeof(void*) or
258/// else the world will end.
259///
260/// TypeLocs with non-constant amounts of local data should override
261/// getExtraLocalDataSize(); getExtraLocalData() will then point to
262/// this extra memory.
263///
264/// TypeLocs with an inner type should define
265///   QualType getInnerType() const
266/// and getInnerTypeLoc() will then point to this inner type's
267/// location data.
268///
269/// A word about hierarchies: this template is not designed to be
270/// derived from multiple times in a hierarchy.  It is also not
271/// designed to be used for classes where subtypes might provide
272/// different amounts of source information.  It should be subclassed
273/// only at the deepest portion of the hierarchy where all children
274/// have identical source information; if that's an abstract type,
275/// then further descendents should inherit from
276/// InheritingConcreteTypeLoc instead.
277template <class Base, class Derived, class TypeClass, class LocalData>
278class ConcreteTypeLoc : public Base {
279
280  const Derived *asDerived() const {
281    return static_cast<const Derived*>(this);
282  }
283
284public:
285  unsigned getLocalDataSize() const {
286    return sizeof(LocalData) + asDerived()->getExtraLocalDataSize();
287  }
288  // Give a default implementation that's useful for leaf types.
289  unsigned getFullDataSize() const {
290    return asDerived()->getLocalDataSize() + getInnerTypeSize();
291  }
292
293  static bool classofType(const Type *Ty) {
294    return TypeClass::classof(Ty);
295  }
296
297  static bool classof(const TypeLoc *TL) {
298    return Derived::classofType(TL->getTypePtr());
299  }
300  static bool classof(const UnqualTypeLoc *TL) {
301    return Derived::classofType(TL->getTypePtr());
302  }
303  static bool classof(const Derived *TL) {
304    return true;
305  }
306
307  TypeLoc getNextTypeLoc() const {
308    return getNextTypeLoc(asDerived()->getInnerType());
309  }
310
311  const TypeClass *getTypePtr() const {
312    return cast<TypeClass>(Base::getTypePtr());
313  }
314
315protected:
316  unsigned getExtraLocalDataSize() const {
317    return 0;
318  }
319
320  LocalData *getLocalData() const {
321    return static_cast<LocalData*>(Base::Data);
322  }
323
324  /// Gets a pointer past the Info structure; useful for classes with
325  /// local data that can't be captured in the Info (e.g. because it's
326  /// of variable size).
327  void *getExtraLocalData() const {
328    return getLocalData() + 1;
329  }
330
331  void *getNonLocalData() const {
332    return static_cast<char*>(Base::Data) + asDerived()->getLocalDataSize();
333  }
334
335  struct HasNoInnerType {};
336  HasNoInnerType getInnerType() const { return HasNoInnerType(); }
337
338  TypeLoc getInnerTypeLoc() const {
339    return TypeLoc(asDerived()->getInnerType(), getNonLocalData());
340  }
341
342private:
343  unsigned getInnerTypeSize() const {
344    return getInnerTypeSize(asDerived()->getInnerType());
345  }
346
347  unsigned getInnerTypeSize(HasNoInnerType _) const {
348    return 0;
349  }
350
351  unsigned getInnerTypeSize(QualType _) const {
352    return getInnerTypeLoc().getFullDataSize();
353  }
354
355  TypeLoc getNextTypeLoc(HasNoInnerType _) const {
356    return TypeLoc();
357  }
358
359  TypeLoc getNextTypeLoc(QualType T) const {
360    return TypeLoc(T, getNonLocalData());
361  }
362};
363
364/// A metaprogramming class designed for concrete subtypes of abstract
365/// types where all subtypes share equivalently-structured source
366/// information.  See the note on ConcreteTypeLoc.
367template <class Base, class Derived, class TypeClass>
368class InheritingConcreteTypeLoc : public Base {
369public:
370  static bool classofType(const Type *Ty) {
371    return TypeClass::classof(Ty);
372  }
373
374  static bool classof(const TypeLoc *TL) {
375    return Derived::classofType(TL->getTypePtr());
376  }
377  static bool classof(const UnqualTypeLoc *TL) {
378    return Derived::classofType(TL->getTypePtr());
379  }
380  static bool classof(const Derived *TL) {
381    return true;
382  }
383
384  const TypeClass *getTypePtr() const {
385    return cast<TypeClass>(Base::getTypePtr());
386  }
387};
388
389
390struct TypeSpecLocInfo {
391  SourceLocation NameLoc;
392};
393
394/// \brief A reasonable base class for TypeLocs that correspond to
395/// types that are written as a type-specifier.
396class TypeSpecTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
397                                               TypeSpecTypeLoc,
398                                               Type,
399                                               TypeSpecLocInfo> {
400public:
401  enum { LocalDataSize = sizeof(TypeSpecLocInfo) };
402
403  SourceLocation getNameLoc() const {
404    return this->getLocalData()->NameLoc;
405  }
406  void setNameLoc(SourceLocation Loc) {
407    this->getLocalData()->NameLoc = Loc;
408  }
409  SourceRange getLocalSourceRange() const {
410    return SourceRange(getNameLoc(), getNameLoc());
411  }
412  void initializeLocal(ASTContext &Context, SourceLocation Loc) {
413    setNameLoc(Loc);
414  }
415
416  static bool classof(const TypeLoc *TL);
417  static bool classof(const TypeSpecTypeLoc *TL) { return true; }
418};
419
420
421struct BuiltinLocInfo {
422  SourceLocation BuiltinLoc;
423};
424
425/// \brief Wrapper for source info for builtin types.
426class BuiltinTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
427                                              BuiltinTypeLoc,
428                                              BuiltinType,
429                                              BuiltinLocInfo> {
430public:
431  enum { LocalDataSize = sizeof(BuiltinLocInfo) };
432
433  SourceLocation getBuiltinLoc() const {
434    return getLocalData()->BuiltinLoc;
435  }
436  void setBuiltinLoc(SourceLocation Loc) {
437    getLocalData()->BuiltinLoc = Loc;
438  }
439
440  SourceLocation getNameLoc() const { return getBuiltinLoc(); }
441
442  WrittenBuiltinSpecs& getWrittenBuiltinSpecs() {
443    return *(static_cast<WrittenBuiltinSpecs*>(getExtraLocalData()));
444  }
445  const WrittenBuiltinSpecs& getWrittenBuiltinSpecs() const {
446    return *(static_cast<WrittenBuiltinSpecs*>(getExtraLocalData()));
447  }
448
449  bool needsExtraLocalData() const {
450    BuiltinType::Kind bk = getTypePtr()->getKind();
451    return (bk >= BuiltinType::UShort && bk <= BuiltinType::UInt128)
452      || (bk >= BuiltinType::Short && bk <= BuiltinType::LongDouble)
453      || bk == BuiltinType::UChar
454      || bk == BuiltinType::SChar;
455  }
456
457  unsigned getExtraLocalDataSize() const {
458    return needsExtraLocalData() ? sizeof(WrittenBuiltinSpecs) : 0;
459  }
460
461  SourceRange getLocalSourceRange() const {
462    return SourceRange(getBuiltinLoc(), getBuiltinLoc());
463  }
464
465  TypeSpecifierSign getWrittenSignSpec() const {
466    if (needsExtraLocalData())
467      return static_cast<TypeSpecifierSign>(getWrittenBuiltinSpecs().Sign);
468    else
469      return TSS_unspecified;
470  }
471  bool hasWrittenSignSpec() const {
472    return getWrittenSignSpec() != TSS_unspecified;
473  }
474  void setWrittenSignSpec(TypeSpecifierSign written) {
475    if (needsExtraLocalData())
476      getWrittenBuiltinSpecs().Sign = written;
477  }
478
479  TypeSpecifierWidth getWrittenWidthSpec() const {
480    if (needsExtraLocalData())
481      return static_cast<TypeSpecifierWidth>(getWrittenBuiltinSpecs().Width);
482    else
483      return TSW_unspecified;
484  }
485  bool hasWrittenWidthSpec() const {
486    return getWrittenWidthSpec() != TSW_unspecified;
487  }
488  void setWrittenWidthSpec(TypeSpecifierWidth written) {
489    if (needsExtraLocalData())
490      getWrittenBuiltinSpecs().Width = written;
491  }
492
493  TypeSpecifierType getWrittenTypeSpec() const;
494  bool hasWrittenTypeSpec() const {
495    return getWrittenTypeSpec() != TST_unspecified;
496  }
497  void setWrittenTypeSpec(TypeSpecifierType written) {
498    if (needsExtraLocalData())
499      getWrittenBuiltinSpecs().Type = written;
500  }
501
502  bool hasModeAttr() const {
503    if (needsExtraLocalData())
504      return getWrittenBuiltinSpecs().ModeAttr;
505    else
506      return false;
507  }
508  void setModeAttr(bool written) {
509    if (needsExtraLocalData())
510      getWrittenBuiltinSpecs().ModeAttr = written;
511  }
512
513  void initializeLocal(ASTContext &Context, SourceLocation Loc) {
514    setBuiltinLoc(Loc);
515    if (needsExtraLocalData()) {
516      WrittenBuiltinSpecs &wbs = getWrittenBuiltinSpecs();
517      wbs.Sign = TSS_unspecified;
518      wbs.Width = TSW_unspecified;
519      wbs.Type = TST_unspecified;
520      wbs.ModeAttr = false;
521    }
522  }
523};
524
525
526/// \brief Wrapper for source info for typedefs.
527class TypedefTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
528                                                        TypedefTypeLoc,
529                                                        TypedefType> {
530public:
531  TypedefNameDecl *getTypedefNameDecl() const {
532    return getTypePtr()->getDecl();
533  }
534};
535
536/// \brief Wrapper for source info for injected class names of class
537/// templates.
538class InjectedClassNameTypeLoc :
539    public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
540                                     InjectedClassNameTypeLoc,
541                                     InjectedClassNameType> {
542public:
543  CXXRecordDecl *getDecl() const {
544    return getTypePtr()->getDecl();
545  }
546};
547
548/// \brief Wrapper for source info for unresolved typename using decls.
549class UnresolvedUsingTypeLoc :
550    public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
551                                     UnresolvedUsingTypeLoc,
552                                     UnresolvedUsingType> {
553public:
554  UnresolvedUsingTypenameDecl *getDecl() const {
555    return getTypePtr()->getDecl();
556  }
557};
558
559/// \brief Wrapper for source info for tag types.  Note that this only
560/// records source info for the name itself; a type written 'struct foo'
561/// should be represented as an ElaboratedTypeLoc.  We currently
562/// only do that when C++ is enabled because of the expense of
563/// creating an ElaboratedType node for so many type references in C.
564class TagTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
565                                                    TagTypeLoc,
566                                                    TagType> {
567public:
568  TagDecl *getDecl() const { return getTypePtr()->getDecl(); }
569
570  /// \brief True if the tag was defined in this type specifier.
571  bool isDefinition() const {
572    return getDecl()->isCompleteDefinition() &&
573         (getNameLoc().isInvalid() || getNameLoc() == getDecl()->getLocation());
574  }
575};
576
577/// \brief Wrapper for source info for record types.
578class RecordTypeLoc : public InheritingConcreteTypeLoc<TagTypeLoc,
579                                                       RecordTypeLoc,
580                                                       RecordType> {
581public:
582  RecordDecl *getDecl() const { return getTypePtr()->getDecl(); }
583};
584
585/// \brief Wrapper for source info for enum types.
586class EnumTypeLoc : public InheritingConcreteTypeLoc<TagTypeLoc,
587                                                     EnumTypeLoc,
588                                                     EnumType> {
589public:
590  EnumDecl *getDecl() const { return getTypePtr()->getDecl(); }
591};
592
593/// \brief Wrapper for template type parameters.
594class TemplateTypeParmTypeLoc :
595    public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
596                                     TemplateTypeParmTypeLoc,
597                                     TemplateTypeParmType> {
598public:
599  TemplateTypeParmDecl *getDecl() const { return getTypePtr()->getDecl(); }
600};
601
602/// \brief Wrapper for substituted template type parameters.
603class SubstTemplateTypeParmTypeLoc :
604    public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
605                                     SubstTemplateTypeParmTypeLoc,
606                                     SubstTemplateTypeParmType> {
607};
608
609  /// \brief Wrapper for substituted template type parameters.
610class SubstTemplateTypeParmPackTypeLoc :
611    public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
612                                     SubstTemplateTypeParmPackTypeLoc,
613                                     SubstTemplateTypeParmPackType> {
614};
615
616struct AttributedLocInfo {
617  union {
618    Expr *ExprOperand;
619
620    /// A raw SourceLocation.
621    unsigned EnumOperandLoc;
622  };
623
624  SourceRange OperandParens;
625
626  SourceLocation AttrLoc;
627};
628
629/// \brief Type source information for an attributed type.
630class AttributedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
631                                                 AttributedTypeLoc,
632                                                 AttributedType,
633                                                 AttributedLocInfo> {
634public:
635  AttributedType::Kind getAttrKind() const {
636    return getTypePtr()->getAttrKind();
637  }
638
639  bool hasAttrExprOperand() const {
640    return (getAttrKind() >= AttributedType::FirstExprOperandKind &&
641            getAttrKind() <= AttributedType::LastExprOperandKind);
642  }
643
644  bool hasAttrEnumOperand() const {
645    return (getAttrKind() >= AttributedType::FirstEnumOperandKind &&
646            getAttrKind() <= AttributedType::LastEnumOperandKind);
647  }
648
649  bool hasAttrOperand() const {
650    return hasAttrExprOperand() || hasAttrEnumOperand();
651  }
652
653  /// The modified type, which is generally canonically different from
654  /// the attribute type.
655  ///    int main(int, char**) __attribute__((noreturn))
656  ///    ~~~     ~~~~~~~~~~~~~
657  TypeLoc getModifiedLoc() const {
658    return getInnerTypeLoc();
659  }
660
661  /// The location of the attribute name, i.e.
662  ///    __attribute__((regparm(1000)))
663  ///                   ^~~~~~~
664  SourceLocation getAttrNameLoc() const {
665    return getLocalData()->AttrLoc;
666  }
667  void setAttrNameLoc(SourceLocation loc) {
668    getLocalData()->AttrLoc = loc;
669  }
670
671  /// The attribute's expression operand, if it has one.
672  ///    void *cur_thread __attribute__((address_space(21)))
673  ///                                                  ^~
674  Expr *getAttrExprOperand() const {
675    assert(hasAttrExprOperand());
676    return getLocalData()->ExprOperand;
677  }
678  void setAttrExprOperand(Expr *e) {
679    assert(hasAttrExprOperand());
680    getLocalData()->ExprOperand = e;
681  }
682
683  /// The location of the attribute's enumerated operand, if it has one.
684  ///    void * __attribute__((objc_gc(weak)))
685  ///                                  ^~~~
686  SourceLocation getAttrEnumOperandLoc() const {
687    assert(hasAttrEnumOperand());
688    return SourceLocation::getFromRawEncoding(getLocalData()->EnumOperandLoc);
689  }
690  void setAttrEnumOperandLoc(SourceLocation loc) {
691    assert(hasAttrEnumOperand());
692    getLocalData()->EnumOperandLoc = loc.getRawEncoding();
693  }
694
695  /// The location of the parentheses around the operand, if there is
696  /// an operand.
697  ///    void * __attribute__((objc_gc(weak)))
698  ///                                 ^    ^
699  SourceRange getAttrOperandParensRange() const {
700    assert(hasAttrOperand());
701    return getLocalData()->OperandParens;
702  }
703  void setAttrOperandParensRange(SourceRange range) {
704    assert(hasAttrOperand());
705    getLocalData()->OperandParens = range;
706  }
707
708  SourceRange getLocalSourceRange() const {
709    // Note that this does *not* include the range of the attribute
710    // enclosure, e.g.:
711    //    __attribute__((foo(bar)))
712    //    ^~~~~~~~~~~~~~~        ~~
713    // or
714    //    [[foo(bar)]]
715    //    ^~        ~~
716    // That enclosure doesn't necessarily belong to a single attribute
717    // anyway.
718    SourceRange range(getAttrNameLoc());
719    if (hasAttrOperand())
720      range.setEnd(getAttrOperandParensRange().getEnd());
721    return range;
722  }
723
724  void initializeLocal(ASTContext &Context, SourceLocation loc) {
725    setAttrNameLoc(loc);
726    if (hasAttrExprOperand()) {
727      setAttrOperandParensRange(SourceRange(loc));
728      setAttrExprOperand(0);
729    } else if (hasAttrEnumOperand()) {
730      setAttrOperandParensRange(SourceRange(loc));
731      setAttrEnumOperandLoc(loc);
732    }
733  }
734
735  QualType getInnerType() const {
736    return getTypePtr()->getModifiedType();
737  }
738};
739
740
741struct ObjCProtocolListLocInfo {
742  SourceLocation LAngleLoc;
743  SourceLocation RAngleLoc;
744  bool HasBaseTypeAsWritten;
745};
746
747// A helper class for defining ObjC TypeLocs that can qualified with
748// protocols.
749//
750// TypeClass basically has to be either ObjCInterfaceType or
751// ObjCObjectPointerType.
752class ObjCObjectTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
753                                                 ObjCObjectTypeLoc,
754                                                 ObjCObjectType,
755                                                 ObjCProtocolListLocInfo> {
756  // SourceLocations are stored after Info, one for each Protocol.
757  SourceLocation *getProtocolLocArray() const {
758    return (SourceLocation*) this->getExtraLocalData();
759  }
760
761public:
762  SourceLocation getLAngleLoc() const {
763    return this->getLocalData()->LAngleLoc;
764  }
765  void setLAngleLoc(SourceLocation Loc) {
766    this->getLocalData()->LAngleLoc = Loc;
767  }
768
769  SourceLocation getRAngleLoc() const {
770    return this->getLocalData()->RAngleLoc;
771  }
772  void setRAngleLoc(SourceLocation Loc) {
773    this->getLocalData()->RAngleLoc = Loc;
774  }
775
776  unsigned getNumProtocols() const {
777    return this->getTypePtr()->getNumProtocols();
778  }
779
780  SourceLocation getProtocolLoc(unsigned i) const {
781    assert(i < getNumProtocols() && "Index is out of bounds!");
782    return getProtocolLocArray()[i];
783  }
784  void setProtocolLoc(unsigned i, SourceLocation Loc) {
785    assert(i < getNumProtocols() && "Index is out of bounds!");
786    getProtocolLocArray()[i] = Loc;
787  }
788
789  ObjCProtocolDecl *getProtocol(unsigned i) const {
790    assert(i < getNumProtocols() && "Index is out of bounds!");
791    return *(this->getTypePtr()->qual_begin() + i);
792  }
793
794  bool hasBaseTypeAsWritten() const {
795    return getLocalData()->HasBaseTypeAsWritten;
796  }
797
798  void setHasBaseTypeAsWritten(bool HasBaseType) {
799    getLocalData()->HasBaseTypeAsWritten = HasBaseType;
800  }
801
802  TypeLoc getBaseLoc() const {
803    return getInnerTypeLoc();
804  }
805
806  SourceRange getLocalSourceRange() const {
807    return SourceRange(getLAngleLoc(), getRAngleLoc());
808  }
809
810  void initializeLocal(ASTContext &Context, SourceLocation Loc) {
811    setHasBaseTypeAsWritten(true);
812    setLAngleLoc(Loc);
813    setRAngleLoc(Loc);
814    for (unsigned i = 0, e = getNumProtocols(); i != e; ++i)
815      setProtocolLoc(i, Loc);
816  }
817
818  unsigned getExtraLocalDataSize() const {
819    return this->getNumProtocols() * sizeof(SourceLocation);
820  }
821
822  QualType getInnerType() const {
823    return getTypePtr()->getBaseType();
824  }
825};
826
827
828struct ObjCInterfaceLocInfo {
829  SourceLocation NameLoc;
830};
831
832/// \brief Wrapper for source info for ObjC interfaces.
833class ObjCInterfaceTypeLoc : public ConcreteTypeLoc<ObjCObjectTypeLoc,
834                                                    ObjCInterfaceTypeLoc,
835                                                    ObjCInterfaceType,
836                                                    ObjCInterfaceLocInfo> {
837public:
838  ObjCInterfaceDecl *getIFaceDecl() const {
839    return getTypePtr()->getDecl();
840  }
841
842  SourceLocation getNameLoc() const {
843    return getLocalData()->NameLoc;
844  }
845
846  void setNameLoc(SourceLocation Loc) {
847    getLocalData()->NameLoc = Loc;
848  }
849
850  SourceRange getLocalSourceRange() const {
851    return SourceRange(getNameLoc());
852  }
853
854  void initializeLocal(ASTContext &Context, SourceLocation Loc) {
855    setNameLoc(Loc);
856  }
857};
858
859struct ParenLocInfo {
860  SourceLocation LParenLoc;
861  SourceLocation RParenLoc;
862};
863
864class ParenTypeLoc
865  : public ConcreteTypeLoc<UnqualTypeLoc, ParenTypeLoc, ParenType,
866                           ParenLocInfo> {
867public:
868  SourceLocation getLParenLoc() const {
869    return this->getLocalData()->LParenLoc;
870  }
871  SourceLocation getRParenLoc() const {
872    return this->getLocalData()->RParenLoc;
873  }
874  void setLParenLoc(SourceLocation Loc) {
875    this->getLocalData()->LParenLoc = Loc;
876  }
877  void setRParenLoc(SourceLocation Loc) {
878    this->getLocalData()->RParenLoc = Loc;
879  }
880
881  SourceRange getLocalSourceRange() const {
882    return SourceRange(getLParenLoc(), getRParenLoc());
883  }
884
885  void initializeLocal(ASTContext &Context, SourceLocation Loc) {
886    setLParenLoc(Loc);
887    setRParenLoc(Loc);
888  }
889
890  TypeLoc getInnerLoc() const {
891    return getInnerTypeLoc();
892  }
893
894  QualType getInnerType() const {
895    return this->getTypePtr()->getInnerType();
896  }
897};
898
899
900struct PointerLikeLocInfo {
901  SourceLocation StarLoc;
902};
903
904/// A base class for
905template <class Derived, class TypeClass, class LocalData = PointerLikeLocInfo>
906class PointerLikeTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, Derived,
907                                                  TypeClass, LocalData> {
908public:
909  SourceLocation getSigilLoc() const {
910    return this->getLocalData()->StarLoc;
911  }
912  void setSigilLoc(SourceLocation Loc) {
913    this->getLocalData()->StarLoc = Loc;
914  }
915
916  TypeLoc getPointeeLoc() const {
917    return this->getInnerTypeLoc();
918  }
919
920  SourceRange getLocalSourceRange() const {
921    return SourceRange(getSigilLoc(), getSigilLoc());
922  }
923
924  void initializeLocal(ASTContext &Context, SourceLocation Loc) {
925    setSigilLoc(Loc);
926  }
927
928  QualType getInnerType() const {
929    return this->getTypePtr()->getPointeeType();
930  }
931};
932
933
934/// \brief Wrapper for source info for pointers.
935class PointerTypeLoc : public PointerLikeTypeLoc<PointerTypeLoc,
936                                                 PointerType> {
937public:
938  SourceLocation getStarLoc() const {
939    return getSigilLoc();
940  }
941  void setStarLoc(SourceLocation Loc) {
942    setSigilLoc(Loc);
943  }
944};
945
946
947/// \brief Wrapper for source info for block pointers.
948class BlockPointerTypeLoc : public PointerLikeTypeLoc<BlockPointerTypeLoc,
949                                                      BlockPointerType> {
950public:
951  SourceLocation getCaretLoc() const {
952    return getSigilLoc();
953  }
954  void setCaretLoc(SourceLocation Loc) {
955    setSigilLoc(Loc);
956  }
957};
958
959struct MemberPointerLocInfo : public PointerLikeLocInfo {
960  TypeSourceInfo *ClassTInfo;
961};
962
963/// \brief Wrapper for source info for member pointers.
964class MemberPointerTypeLoc : public PointerLikeTypeLoc<MemberPointerTypeLoc,
965                                                       MemberPointerType,
966                                                       MemberPointerLocInfo> {
967public:
968  SourceLocation getStarLoc() const {
969    return getSigilLoc();
970  }
971  void setStarLoc(SourceLocation Loc) {
972    setSigilLoc(Loc);
973  }
974
975  const Type *getClass() const {
976    return getTypePtr()->getClass();
977  }
978  TypeSourceInfo *getClassTInfo() const {
979    return getLocalData()->ClassTInfo;
980  }
981  void setClassTInfo(TypeSourceInfo* TI) {
982    getLocalData()->ClassTInfo = TI;
983  }
984
985  void initializeLocal(ASTContext &Context, SourceLocation Loc) {
986    setSigilLoc(Loc);
987    setClassTInfo(0);
988  }
989
990  SourceRange getLocalSourceRange() const {
991    if (TypeSourceInfo *TI = getClassTInfo())
992      return SourceRange(TI->getTypeLoc().getBeginLoc(), getStarLoc());
993    else
994      return SourceRange(getStarLoc());
995  }
996};
997
998/// Wraps an ObjCPointerType with source location information.
999class ObjCObjectPointerTypeLoc :
1000    public PointerLikeTypeLoc<ObjCObjectPointerTypeLoc,
1001                              ObjCObjectPointerType> {
1002public:
1003  SourceLocation getStarLoc() const {
1004    return getSigilLoc();
1005  }
1006
1007  void setStarLoc(SourceLocation Loc) {
1008    setSigilLoc(Loc);
1009  }
1010};
1011
1012
1013class ReferenceTypeLoc : public PointerLikeTypeLoc<ReferenceTypeLoc,
1014                                                   ReferenceType> {
1015public:
1016  QualType getInnerType() const {
1017    return getTypePtr()->getPointeeTypeAsWritten();
1018  }
1019};
1020
1021class LValueReferenceTypeLoc :
1022    public InheritingConcreteTypeLoc<ReferenceTypeLoc,
1023                                     LValueReferenceTypeLoc,
1024                                     LValueReferenceType> {
1025public:
1026  SourceLocation getAmpLoc() const {
1027    return getSigilLoc();
1028  }
1029  void setAmpLoc(SourceLocation Loc) {
1030    setSigilLoc(Loc);
1031  }
1032};
1033
1034class RValueReferenceTypeLoc :
1035    public InheritingConcreteTypeLoc<ReferenceTypeLoc,
1036                                     RValueReferenceTypeLoc,
1037                                     RValueReferenceType> {
1038public:
1039  SourceLocation getAmpAmpLoc() const {
1040    return getSigilLoc();
1041  }
1042  void setAmpAmpLoc(SourceLocation Loc) {
1043    setSigilLoc(Loc);
1044  }
1045};
1046
1047
1048struct FunctionLocInfo {
1049  SourceLocation LocalRangeBegin;
1050  SourceLocation LocalRangeEnd;
1051  bool TrailingReturn;
1052};
1053
1054/// \brief Wrapper for source info for functions.
1055class FunctionTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
1056                                               FunctionTypeLoc,
1057                                               FunctionType,
1058                                               FunctionLocInfo> {
1059public:
1060  SourceLocation getLocalRangeBegin() const {
1061    return getLocalData()->LocalRangeBegin;
1062  }
1063  void setLocalRangeBegin(SourceLocation L) {
1064    getLocalData()->LocalRangeBegin = L;
1065  }
1066
1067  SourceLocation getLocalRangeEnd() const {
1068    return getLocalData()->LocalRangeEnd;
1069  }
1070  void setLocalRangeEnd(SourceLocation L) {
1071    getLocalData()->LocalRangeEnd = L;
1072  }
1073
1074  bool getTrailingReturn() const {
1075    return getLocalData()->TrailingReturn;
1076  }
1077  void setTrailingReturn(bool Trailing) {
1078    getLocalData()->TrailingReturn = Trailing;
1079  }
1080
1081  ArrayRef<ParmVarDecl *> getParams() const {
1082    return ArrayRef<ParmVarDecl *>(getParmArray(), getNumArgs());
1083  }
1084
1085  // ParmVarDecls* are stored after Info, one for each argument.
1086  ParmVarDecl **getParmArray() const {
1087    return (ParmVarDecl**) getExtraLocalData();
1088  }
1089
1090  unsigned getNumArgs() const {
1091    if (isa<FunctionNoProtoType>(getTypePtr()))
1092      return 0;
1093    return cast<FunctionProtoType>(getTypePtr())->getNumArgs();
1094  }
1095  ParmVarDecl *getArg(unsigned i) const { return getParmArray()[i]; }
1096  void setArg(unsigned i, ParmVarDecl *VD) { getParmArray()[i] = VD; }
1097
1098  TypeLoc getResultLoc() const {
1099    return getInnerTypeLoc();
1100  }
1101
1102  SourceRange getLocalSourceRange() const {
1103    return SourceRange(getLocalRangeBegin(), getLocalRangeEnd());
1104  }
1105
1106  void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1107    setLocalRangeBegin(Loc);
1108    setLocalRangeEnd(Loc);
1109    setTrailingReturn(false);
1110    for (unsigned i = 0, e = getNumArgs(); i != e; ++i)
1111      setArg(i, NULL);
1112  }
1113
1114  /// \brief Returns the size of the type source info data block that is
1115  /// specific to this type.
1116  unsigned getExtraLocalDataSize() const {
1117    return getNumArgs() * sizeof(ParmVarDecl*);
1118  }
1119
1120  QualType getInnerType() const { return getTypePtr()->getResultType(); }
1121};
1122
1123class FunctionProtoTypeLoc :
1124    public InheritingConcreteTypeLoc<FunctionTypeLoc,
1125                                     FunctionProtoTypeLoc,
1126                                     FunctionProtoType> {
1127};
1128
1129class FunctionNoProtoTypeLoc :
1130    public InheritingConcreteTypeLoc<FunctionTypeLoc,
1131                                     FunctionNoProtoTypeLoc,
1132                                     FunctionNoProtoType> {
1133};
1134
1135
1136struct ArrayLocInfo {
1137  SourceLocation LBracketLoc, RBracketLoc;
1138  Expr *Size;
1139};
1140
1141/// \brief Wrapper for source info for arrays.
1142class ArrayTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
1143                                            ArrayTypeLoc,
1144                                            ArrayType,
1145                                            ArrayLocInfo> {
1146public:
1147  SourceLocation getLBracketLoc() const {
1148    return getLocalData()->LBracketLoc;
1149  }
1150  void setLBracketLoc(SourceLocation Loc) {
1151    getLocalData()->LBracketLoc = Loc;
1152  }
1153
1154  SourceLocation getRBracketLoc() const {
1155    return getLocalData()->RBracketLoc;
1156  }
1157  void setRBracketLoc(SourceLocation Loc) {
1158    getLocalData()->RBracketLoc = Loc;
1159  }
1160
1161  SourceRange getBracketsRange() const {
1162    return SourceRange(getLBracketLoc(), getRBracketLoc());
1163  }
1164
1165  Expr *getSizeExpr() const {
1166    return getLocalData()->Size;
1167  }
1168  void setSizeExpr(Expr *Size) {
1169    getLocalData()->Size = Size;
1170  }
1171
1172  TypeLoc getElementLoc() const {
1173    return getInnerTypeLoc();
1174  }
1175
1176  SourceRange getLocalSourceRange() const {
1177    return SourceRange(getLBracketLoc(), getRBracketLoc());
1178  }
1179
1180  void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1181    setLBracketLoc(Loc);
1182    setRBracketLoc(Loc);
1183    setSizeExpr(NULL);
1184  }
1185
1186  QualType getInnerType() const { return getTypePtr()->getElementType(); }
1187};
1188
1189class ConstantArrayTypeLoc :
1190    public InheritingConcreteTypeLoc<ArrayTypeLoc,
1191                                     ConstantArrayTypeLoc,
1192                                     ConstantArrayType> {
1193};
1194
1195class IncompleteArrayTypeLoc :
1196    public InheritingConcreteTypeLoc<ArrayTypeLoc,
1197                                     IncompleteArrayTypeLoc,
1198                                     IncompleteArrayType> {
1199};
1200
1201class DependentSizedArrayTypeLoc :
1202    public InheritingConcreteTypeLoc<ArrayTypeLoc,
1203                                     DependentSizedArrayTypeLoc,
1204                                     DependentSizedArrayType> {
1205
1206};
1207
1208class VariableArrayTypeLoc :
1209    public InheritingConcreteTypeLoc<ArrayTypeLoc,
1210                                     VariableArrayTypeLoc,
1211                                     VariableArrayType> {
1212};
1213
1214
1215// Location information for a TemplateName.  Rudimentary for now.
1216struct TemplateNameLocInfo {
1217  SourceLocation NameLoc;
1218};
1219
1220struct TemplateSpecializationLocInfo : TemplateNameLocInfo {
1221  SourceLocation TemplateKWLoc;
1222  SourceLocation LAngleLoc;
1223  SourceLocation RAngleLoc;
1224};
1225
1226class TemplateSpecializationTypeLoc :
1227    public ConcreteTypeLoc<UnqualTypeLoc,
1228                           TemplateSpecializationTypeLoc,
1229                           TemplateSpecializationType,
1230                           TemplateSpecializationLocInfo> {
1231public:
1232  SourceLocation getTemplateKeywordLoc() const {
1233    return getLocalData()->TemplateKWLoc;
1234  }
1235  void setTemplateKeywordLoc(SourceLocation Loc) {
1236    getLocalData()->TemplateKWLoc = Loc;
1237  }
1238
1239  SourceLocation getLAngleLoc() const {
1240    return getLocalData()->LAngleLoc;
1241  }
1242  void setLAngleLoc(SourceLocation Loc) {
1243    getLocalData()->LAngleLoc = Loc;
1244  }
1245
1246  SourceLocation getRAngleLoc() const {
1247    return getLocalData()->RAngleLoc;
1248  }
1249  void setRAngleLoc(SourceLocation Loc) {
1250    getLocalData()->RAngleLoc = Loc;
1251  }
1252
1253  unsigned getNumArgs() const {
1254    return getTypePtr()->getNumArgs();
1255  }
1256  void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) {
1257    getArgInfos()[i] = AI;
1258  }
1259  TemplateArgumentLocInfo getArgLocInfo(unsigned i) const {
1260    return getArgInfos()[i];
1261  }
1262
1263  TemplateArgumentLoc getArgLoc(unsigned i) const {
1264    return TemplateArgumentLoc(getTypePtr()->getArg(i), getArgLocInfo(i));
1265  }
1266
1267  SourceLocation getTemplateNameLoc() const {
1268    return getLocalData()->NameLoc;
1269  }
1270  void setTemplateNameLoc(SourceLocation Loc) {
1271    getLocalData()->NameLoc = Loc;
1272  }
1273
1274  /// \brief - Copy the location information from the given info.
1275  void copy(TemplateSpecializationTypeLoc Loc) {
1276    unsigned size = getFullDataSize();
1277    assert(size == Loc.getFullDataSize());
1278
1279    // We're potentially copying Expr references here.  We don't
1280    // bother retaining them because TypeSourceInfos live forever, so
1281    // as long as the Expr was retained when originally written into
1282    // the TypeLoc, we're okay.
1283    memcpy(Data, Loc.Data, size);
1284  }
1285
1286  SourceRange getLocalSourceRange() const {
1287    if (getTemplateKeywordLoc().isValid())
1288      return SourceRange(getTemplateKeywordLoc(), getRAngleLoc());
1289    else
1290      return SourceRange(getTemplateNameLoc(), getRAngleLoc());
1291  }
1292
1293  void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1294    setTemplateKeywordLoc(Loc);
1295    setTemplateNameLoc(Loc);
1296    setLAngleLoc(Loc);
1297    setRAngleLoc(Loc);
1298    initializeArgLocs(Context, getNumArgs(), getTypePtr()->getArgs(),
1299                      getArgInfos(), Loc);
1300  }
1301
1302  static void initializeArgLocs(ASTContext &Context, unsigned NumArgs,
1303                                const TemplateArgument *Args,
1304                                TemplateArgumentLocInfo *ArgInfos,
1305                                SourceLocation Loc);
1306
1307  unsigned getExtraLocalDataSize() const {
1308    return getNumArgs() * sizeof(TemplateArgumentLocInfo);
1309  }
1310
1311private:
1312  TemplateArgumentLocInfo *getArgInfos() const {
1313    return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData());
1314  }
1315};
1316
1317//===----------------------------------------------------------------------===//
1318//
1319//  All of these need proper implementations.
1320//
1321//===----------------------------------------------------------------------===//
1322
1323// FIXME: size expression and attribute locations (or keyword if we
1324// ever fully support altivec syntax).
1325class VectorTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
1326                                                       VectorTypeLoc,
1327                                                       VectorType> {
1328};
1329
1330// FIXME: size expression and attribute locations.
1331class ExtVectorTypeLoc : public InheritingConcreteTypeLoc<VectorTypeLoc,
1332                                                          ExtVectorTypeLoc,
1333                                                          ExtVectorType> {
1334};
1335
1336// FIXME: attribute locations.
1337// For some reason, this isn't a subtype of VectorType.
1338class DependentSizedExtVectorTypeLoc :
1339    public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
1340                                     DependentSizedExtVectorTypeLoc,
1341                                     DependentSizedExtVectorType> {
1342};
1343
1344// FIXME: location of the '_Complex' keyword.
1345class ComplexTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
1346                                                        ComplexTypeLoc,
1347                                                        ComplexType> {
1348};
1349
1350struct TypeofLocInfo {
1351  SourceLocation TypeofLoc;
1352  SourceLocation LParenLoc;
1353  SourceLocation RParenLoc;
1354};
1355
1356struct TypeOfExprTypeLocInfo : public TypeofLocInfo {
1357};
1358
1359struct TypeOfTypeLocInfo : public TypeofLocInfo {
1360  TypeSourceInfo* UnderlyingTInfo;
1361};
1362
1363template <class Derived, class TypeClass, class LocalData = TypeofLocInfo>
1364class TypeofLikeTypeLoc
1365  : public ConcreteTypeLoc<UnqualTypeLoc, Derived, TypeClass, LocalData> {
1366public:
1367  SourceLocation getTypeofLoc() const {
1368    return this->getLocalData()->TypeofLoc;
1369  }
1370  void setTypeofLoc(SourceLocation Loc) {
1371    this->getLocalData()->TypeofLoc = Loc;
1372  }
1373
1374  SourceLocation getLParenLoc() const {
1375    return this->getLocalData()->LParenLoc;
1376  }
1377  void setLParenLoc(SourceLocation Loc) {
1378    this->getLocalData()->LParenLoc = Loc;
1379  }
1380
1381  SourceLocation getRParenLoc() const {
1382    return this->getLocalData()->RParenLoc;
1383  }
1384  void setRParenLoc(SourceLocation Loc) {
1385    this->getLocalData()->RParenLoc = Loc;
1386  }
1387
1388  SourceRange getParensRange() const {
1389    return SourceRange(getLParenLoc(), getRParenLoc());
1390  }
1391  void setParensRange(SourceRange range) {
1392      setLParenLoc(range.getBegin());
1393      setRParenLoc(range.getEnd());
1394  }
1395
1396  SourceRange getLocalSourceRange() const {
1397    return SourceRange(getTypeofLoc(), getRParenLoc());
1398  }
1399
1400  void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1401    setTypeofLoc(Loc);
1402    setLParenLoc(Loc);
1403    setRParenLoc(Loc);
1404  }
1405};
1406
1407class TypeOfExprTypeLoc : public TypeofLikeTypeLoc<TypeOfExprTypeLoc,
1408                                                   TypeOfExprType,
1409                                                   TypeOfExprTypeLocInfo> {
1410public:
1411  Expr* getUnderlyingExpr() const {
1412    return getTypePtr()->getUnderlyingExpr();
1413  }
1414  // Reimplemented to account for GNU/C++ extension
1415  //     typeof unary-expression
1416  // where there are no parentheses.
1417  SourceRange getLocalSourceRange() const;
1418};
1419
1420class TypeOfTypeLoc
1421  : public TypeofLikeTypeLoc<TypeOfTypeLoc, TypeOfType, TypeOfTypeLocInfo> {
1422public:
1423  QualType getUnderlyingType() const {
1424    return this->getTypePtr()->getUnderlyingType();
1425  }
1426  TypeSourceInfo* getUnderlyingTInfo() const {
1427    return this->getLocalData()->UnderlyingTInfo;
1428  }
1429  void setUnderlyingTInfo(TypeSourceInfo* TI) const {
1430    this->getLocalData()->UnderlyingTInfo = TI;
1431  }
1432};
1433
1434// FIXME: location of the 'decltype' and parens.
1435class DecltypeTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
1436                                                         DecltypeTypeLoc,
1437                                                         DecltypeType> {
1438public:
1439  Expr *getUnderlyingExpr() const { return getTypePtr()->getUnderlyingExpr(); }
1440};
1441
1442struct UnaryTransformTypeLocInfo {
1443  // FIXME: While there's only one unary transform right now, future ones may
1444  // need different representations
1445  SourceLocation KWLoc, LParenLoc, RParenLoc;
1446  TypeSourceInfo *UnderlyingTInfo;
1447};
1448
1449class UnaryTransformTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
1450                                                    UnaryTransformTypeLoc,
1451                                                    UnaryTransformType,
1452                                                    UnaryTransformTypeLocInfo> {
1453public:
1454  SourceLocation getKWLoc() const { return getLocalData()->KWLoc; }
1455  void setKWLoc(SourceLocation Loc) { getLocalData()->KWLoc = Loc; }
1456
1457  SourceLocation getLParenLoc() const { return getLocalData()->LParenLoc; }
1458  void setLParenLoc(SourceLocation Loc) { getLocalData()->LParenLoc = Loc; }
1459
1460  SourceLocation getRParenLoc() const { return getLocalData()->RParenLoc; }
1461  void setRParenLoc(SourceLocation Loc) { getLocalData()->RParenLoc = Loc; }
1462
1463  TypeSourceInfo* getUnderlyingTInfo() const {
1464    return getLocalData()->UnderlyingTInfo;
1465  }
1466  void setUnderlyingTInfo(TypeSourceInfo *TInfo) {
1467    getLocalData()->UnderlyingTInfo = TInfo;
1468  }
1469
1470  SourceRange getLocalSourceRange() const {
1471    return SourceRange(getKWLoc(), getRParenLoc());
1472  }
1473
1474  SourceRange getParensRange() const {
1475    return SourceRange(getLParenLoc(), getRParenLoc());
1476  }
1477  void setParensRange(SourceRange Range) {
1478    setLParenLoc(Range.getBegin());
1479    setRParenLoc(Range.getEnd());
1480  }
1481
1482  void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1483    setKWLoc(Loc);
1484    setRParenLoc(Loc);
1485    setLParenLoc(Loc);
1486  }
1487};
1488
1489class AutoTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
1490                                                        AutoTypeLoc,
1491                                                        AutoType> {
1492};
1493
1494struct ElaboratedLocInfo {
1495  SourceLocation ElaboratedKWLoc;
1496  /// \brief Data associated with the nested-name-specifier location.
1497  void *QualifierData;
1498};
1499
1500class ElaboratedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
1501                                                 ElaboratedTypeLoc,
1502                                                 ElaboratedType,
1503                                                 ElaboratedLocInfo> {
1504public:
1505  SourceLocation getElaboratedKeywordLoc() const {
1506    return this->getLocalData()->ElaboratedKWLoc;
1507  }
1508  void setElaboratedKeywordLoc(SourceLocation Loc) {
1509    this->getLocalData()->ElaboratedKWLoc = Loc;
1510  }
1511
1512  NestedNameSpecifierLoc getQualifierLoc() const {
1513    return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
1514                                  getLocalData()->QualifierData);
1515  }
1516
1517  void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
1518    assert(QualifierLoc.getNestedNameSpecifier()
1519                                            == getTypePtr()->getQualifier() &&
1520           "Inconsistent nested-name-specifier pointer");
1521    getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
1522  }
1523
1524  SourceRange getLocalSourceRange() const {
1525    if (getElaboratedKeywordLoc().isValid())
1526      if (getQualifierLoc())
1527        return SourceRange(getElaboratedKeywordLoc(),
1528                           getQualifierLoc().getEndLoc());
1529      else
1530        return SourceRange(getElaboratedKeywordLoc());
1531    else
1532      return getQualifierLoc().getSourceRange();
1533  }
1534
1535  void initializeLocal(ASTContext &Context, SourceLocation Loc);
1536
1537  TypeLoc getNamedTypeLoc() const {
1538    return getInnerTypeLoc();
1539  }
1540
1541  QualType getInnerType() const {
1542    return getTypePtr()->getNamedType();
1543  }
1544
1545  void copy(ElaboratedTypeLoc Loc) {
1546    unsigned size = getFullDataSize();
1547    assert(size == Loc.getFullDataSize());
1548    memcpy(Data, Loc.Data, size);
1549  }
1550};
1551
1552// This is exactly the structure of an ElaboratedTypeLoc whose inner
1553// type is some sort of TypeDeclTypeLoc.
1554struct DependentNameLocInfo : ElaboratedLocInfo {
1555  SourceLocation NameLoc;
1556};
1557
1558class DependentNameTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
1559                                                    DependentNameTypeLoc,
1560                                                    DependentNameType,
1561                                                    DependentNameLocInfo> {
1562public:
1563  SourceLocation getElaboratedKeywordLoc() const {
1564    return this->getLocalData()->ElaboratedKWLoc;
1565  }
1566  void setElaboratedKeywordLoc(SourceLocation Loc) {
1567    this->getLocalData()->ElaboratedKWLoc = Loc;
1568  }
1569
1570  NestedNameSpecifierLoc getQualifierLoc() const {
1571    return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
1572                                  getLocalData()->QualifierData);
1573  }
1574
1575  void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
1576    assert(QualifierLoc.getNestedNameSpecifier()
1577                                            == getTypePtr()->getQualifier() &&
1578           "Inconsistent nested-name-specifier pointer");
1579    getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
1580  }
1581
1582  SourceLocation getNameLoc() const {
1583    return this->getLocalData()->NameLoc;
1584  }
1585  void setNameLoc(SourceLocation Loc) {
1586    this->getLocalData()->NameLoc = Loc;
1587  }
1588
1589  SourceRange getLocalSourceRange() const {
1590    if (getElaboratedKeywordLoc().isValid())
1591      return SourceRange(getElaboratedKeywordLoc(), getNameLoc());
1592    else
1593      return SourceRange(getQualifierLoc().getBeginLoc(), getNameLoc());
1594  }
1595
1596  void copy(DependentNameTypeLoc Loc) {
1597    unsigned size = getFullDataSize();
1598    assert(size == Loc.getFullDataSize());
1599    memcpy(Data, Loc.Data, size);
1600  }
1601
1602  void initializeLocal(ASTContext &Context, SourceLocation Loc);
1603};
1604
1605struct DependentTemplateSpecializationLocInfo : DependentNameLocInfo {
1606  SourceLocation LAngleLoc;
1607  SourceLocation RAngleLoc;
1608  // followed by a TemplateArgumentLocInfo[]
1609};
1610
1611class DependentTemplateSpecializationTypeLoc :
1612    public ConcreteTypeLoc<UnqualTypeLoc,
1613                           DependentTemplateSpecializationTypeLoc,
1614                           DependentTemplateSpecializationType,
1615                           DependentTemplateSpecializationLocInfo> {
1616public:
1617  SourceLocation getElaboratedKeywordLoc() const {
1618    return this->getLocalData()->ElaboratedKWLoc;
1619  }
1620  void setElaboratedKeywordLoc(SourceLocation Loc) {
1621    this->getLocalData()->ElaboratedKWLoc = Loc;
1622  }
1623
1624  NestedNameSpecifierLoc getQualifierLoc() const {
1625    if (!getLocalData()->QualifierData)
1626      return NestedNameSpecifierLoc();
1627
1628    return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
1629                                  getLocalData()->QualifierData);
1630  }
1631
1632  void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
1633    if (!QualifierLoc) {
1634      // Even if we have a nested-name-specifier in the dependent
1635      // template specialization type, we won't record the nested-name-specifier
1636      // location information when this type-source location information is
1637      // part of a nested-name-specifier.
1638      getLocalData()->QualifierData = 0;
1639      return;
1640    }
1641
1642    assert(QualifierLoc.getNestedNameSpecifier()
1643                                        == getTypePtr()->getQualifier() &&
1644           "Inconsistent nested-name-specifier pointer");
1645    getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
1646  }
1647
1648  SourceLocation getTemplateNameLoc() const {
1649    return this->getLocalData()->NameLoc;
1650  }
1651  void setTemplateNameLoc(SourceLocation Loc) {
1652    this->getLocalData()->NameLoc = Loc;
1653  }
1654
1655  SourceLocation getLAngleLoc() const {
1656    return this->getLocalData()->LAngleLoc;
1657  }
1658  void setLAngleLoc(SourceLocation Loc) {
1659    this->getLocalData()->LAngleLoc = Loc;
1660  }
1661
1662  SourceLocation getRAngleLoc() const {
1663    return this->getLocalData()->RAngleLoc;
1664  }
1665  void setRAngleLoc(SourceLocation Loc) {
1666    this->getLocalData()->RAngleLoc = Loc;
1667  }
1668
1669  unsigned getNumArgs() const {
1670    return getTypePtr()->getNumArgs();
1671  }
1672
1673  void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) {
1674    getArgInfos()[i] = AI;
1675  }
1676  TemplateArgumentLocInfo getArgLocInfo(unsigned i) const {
1677    return getArgInfos()[i];
1678  }
1679
1680  TemplateArgumentLoc getArgLoc(unsigned i) const {
1681    return TemplateArgumentLoc(getTypePtr()->getArg(i), getArgLocInfo(i));
1682  }
1683
1684  SourceRange getLocalSourceRange() const {
1685    if (getElaboratedKeywordLoc().isValid())
1686      return SourceRange(getElaboratedKeywordLoc(), getRAngleLoc());
1687    else if (getQualifierLoc())
1688      return SourceRange(getQualifierLoc().getBeginLoc(), getRAngleLoc());
1689    else
1690      return SourceRange(getTemplateNameLoc(), getRAngleLoc());
1691  }
1692
1693  void copy(DependentTemplateSpecializationTypeLoc Loc) {
1694    unsigned size = getFullDataSize();
1695    assert(size == Loc.getFullDataSize());
1696    memcpy(Data, Loc.Data, size);
1697  }
1698
1699  void initializeLocal(ASTContext &Context, SourceLocation Loc);
1700
1701  unsigned getExtraLocalDataSize() const {
1702    return getNumArgs() * sizeof(TemplateArgumentLocInfo);
1703  }
1704
1705private:
1706  TemplateArgumentLocInfo *getArgInfos() const {
1707    return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData());
1708  }
1709};
1710
1711
1712struct PackExpansionTypeLocInfo {
1713  SourceLocation EllipsisLoc;
1714};
1715
1716class PackExpansionTypeLoc
1717  : public ConcreteTypeLoc<UnqualTypeLoc, PackExpansionTypeLoc,
1718                           PackExpansionType, PackExpansionTypeLocInfo> {
1719public:
1720  SourceLocation getEllipsisLoc() const {
1721    return this->getLocalData()->EllipsisLoc;
1722  }
1723
1724  void setEllipsisLoc(SourceLocation Loc) {
1725    this->getLocalData()->EllipsisLoc = Loc;
1726  }
1727
1728  SourceRange getLocalSourceRange() const {
1729    return SourceRange(getEllipsisLoc(), getEllipsisLoc());
1730  }
1731
1732  void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1733    setEllipsisLoc(Loc);
1734  }
1735
1736  TypeLoc getPatternLoc() const {
1737    return getInnerTypeLoc();
1738  }
1739
1740  QualType getInnerType() const {
1741    return this->getTypePtr()->getPattern();
1742  }
1743};
1744
1745struct AtomicTypeLocInfo {
1746  SourceLocation KWLoc, LParenLoc, RParenLoc;
1747};
1748
1749class AtomicTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, AtomicTypeLoc,
1750                                             AtomicType, AtomicTypeLocInfo> {
1751public:
1752  TypeLoc getValueLoc() const {
1753    return this->getInnerTypeLoc();
1754  }
1755
1756  SourceRange getLocalSourceRange() const {
1757    return SourceRange(getKWLoc(), getRParenLoc());
1758  }
1759
1760  SourceLocation getKWLoc() const {
1761    return this->getLocalData()->KWLoc;
1762  }
1763  void setKWLoc(SourceLocation Loc) {
1764    this->getLocalData()->KWLoc = Loc;
1765  }
1766
1767  SourceLocation getLParenLoc() const {
1768    return this->getLocalData()->LParenLoc;
1769  }
1770  void setLParenLoc(SourceLocation Loc) {
1771    this->getLocalData()->LParenLoc = Loc;
1772  }
1773
1774  SourceLocation getRParenLoc() const {
1775    return this->getLocalData()->RParenLoc;
1776  }
1777  void setRParenLoc(SourceLocation Loc) {
1778    this->getLocalData()->RParenLoc = Loc;
1779  }
1780
1781  SourceRange getParensRange() const {
1782    return SourceRange(getLParenLoc(), getRParenLoc());
1783  }
1784  void setParensRange(SourceRange Range) {
1785    setLParenLoc(Range.getBegin());
1786    setRParenLoc(Range.getEnd());
1787  }
1788
1789  void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1790    setKWLoc(Loc);
1791    setLParenLoc(Loc);
1792    setRParenLoc(Loc);
1793  }
1794
1795  QualType getInnerType() const {
1796    return this->getTypePtr()->getValueType();
1797  }
1798};
1799
1800
1801}
1802
1803#endif
1804