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