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