1 //===--- TypeLoc.h - Type Source Info Wrapper -------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file defines the TypeLoc interface and subclasses.
12 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_CLANG_AST_TYPELOC_H
15 #define LLVM_CLANG_AST_TYPELOC_H
17 #include "clang/AST/Decl.h"
18 #include "clang/AST/TemplateBase.h"
19 #include "clang/AST/Type.h"
20 #include "clang/Basic/Specifiers.h"
21 #include "llvm/Support/Compiler.h"
29 // Predeclare all the type nodes.
30 #define ABSTRACT_TYPELOC(Class, Base)
31 #define TYPELOC(Class, Base) \
33 #include "clang/AST/TypeLocNodes.def"
35 /// \brief Base wrapper for a particular "section" of type source info.
37 /// A client should use the TypeLoc subclasses through cast/dyn_cast in order to
38 /// get at the actual information.
41 // The correctness of this relies on the property that, for Type *Ty,
42 // QualType(Ty, 0).getAsOpaquePtr() == (void*) Ty
47 /// \brief Convert to the specified TypeLoc type, asserting that this TypeLoc
48 /// is of the desired type.
51 assert(T::isKind(*this));
58 /// \brief Convert to the specified TypeLoc type, returning a null TypeLoc if
59 /// this TypeLoc is not of the desired type.
62 if (!T::isKind(*this))
70 /// The kinds of TypeLocs. Equivalent to the Type::TypeClass enum,
71 /// except it also defines a Qualified enum that corresponds to the
72 /// QualifiedLoc class.
74 #define ABSTRACT_TYPE(Class, Base)
75 #define TYPE(Class, Base) \
77 #include "clang/AST/TypeNodes.def"
81 TypeLoc() : Ty(0), Data(0) { }
82 TypeLoc(QualType ty, void *opaqueData)
83 : Ty(ty.getAsOpaquePtr()), Data(opaqueData) { }
84 TypeLoc(const Type *ty, void *opaqueData)
85 : Ty(ty), Data(opaqueData) { }
87 TypeLocClass getTypeLocClass() const {
88 if (getType().hasLocalQualifiers()) return Qualified;
89 return (TypeLocClass) getType()->getTypeClass();
92 bool isNull() const { return !Ty; }
93 operator bool() const { return Ty; }
95 /// \brief Returns the size of type source info data block for the given type.
96 static unsigned getFullDataSizeForType(QualType Ty);
98 /// \brief Get the type for which this source info wrapper provides
100 QualType getType() const {
101 return QualType::getFromOpaquePtr(Ty);
104 const Type *getTypePtr() const {
105 return QualType::getFromOpaquePtr(Ty).getTypePtr();
108 /// \brief Get the pointer where source information is stored.
109 void *getOpaqueData() const {
113 /// \brief Get the begin source location.
114 SourceLocation getBeginLoc() const;
116 /// \brief Get the end source location.
117 SourceLocation getEndLoc() const;
119 /// \brief Get the full source range.
120 SourceRange getSourceRange() const LLVM_READONLY {
121 return SourceRange(getBeginLoc(), getEndLoc());
123 SourceLocation getLocStart() const LLVM_READONLY { return getBeginLoc(); }
124 SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
126 /// \brief Get the local source range.
127 SourceRange getLocalSourceRange() const {
128 return getLocalSourceRangeImpl(*this);
131 /// \brief Returns the size of the type source info data block.
132 unsigned getFullDataSize() const {
133 return getFullDataSizeForType(getType());
136 /// \brief Get the next TypeLoc pointed by this TypeLoc, e.g for "int*" the
137 /// TypeLoc is a PointerLoc and next TypeLoc is for "int".
138 TypeLoc getNextTypeLoc() const {
139 return getNextTypeLocImpl(*this);
142 /// \brief Skips past any qualifiers, if this is qualified.
143 UnqualTypeLoc getUnqualifiedLoc() const; // implemented in this header
145 TypeLoc IgnoreParens() const;
147 /// \brief Initializes this to state that every location in this
148 /// type is the given location.
150 /// This method exists to provide a simple transition for code that
151 /// relies on location-less types.
152 void initialize(ASTContext &Context, SourceLocation Loc) const {
153 initializeImpl(Context, *this, Loc);
156 /// \brief Initializes this by copying its information from another
157 /// TypeLoc of the same type.
158 void initializeFullCopy(TypeLoc Other) const {
159 assert(getType() == Other.getType());
160 size_t Size = getFullDataSize();
161 memcpy(getOpaqueData(), Other.getOpaqueData(), Size);
164 /// \brief Initializes this by copying its information from another
165 /// TypeLoc of the same type. The given size must be the full data
167 void initializeFullCopy(TypeLoc Other, unsigned Size) const {
168 assert(getType() == Other.getType());
169 assert(getFullDataSize() == Size);
170 memcpy(getOpaqueData(), Other.getOpaqueData(), Size);
173 friend bool operator==(const TypeLoc &LHS, const TypeLoc &RHS) {
174 return LHS.Ty == RHS.Ty && LHS.Data == RHS.Data;
177 friend bool operator!=(const TypeLoc &LHS, const TypeLoc &RHS) {
178 return !(LHS == RHS);
182 static bool isKind(const TypeLoc&) {
186 static void initializeImpl(ASTContext &Context, TypeLoc TL,
188 static TypeLoc getNextTypeLocImpl(TypeLoc TL);
189 static TypeLoc IgnoreParensImpl(TypeLoc TL);
190 static SourceRange getLocalSourceRangeImpl(TypeLoc TL);
193 /// \brief Return the TypeLoc for a type source info.
194 inline TypeLoc TypeSourceInfo::getTypeLoc() const {
195 return TypeLoc(Ty, const_cast<void*>(static_cast<const void*>(this + 1)));
198 /// \brief Wrapper of type source information for a type with
199 /// no direct qualifiers.
200 class UnqualTypeLoc : public TypeLoc {
203 UnqualTypeLoc(const Type *Ty, void *Data) : TypeLoc(Ty, Data) {}
205 const Type *getTypePtr() const {
206 return reinterpret_cast<const Type*>(Ty);
209 TypeLocClass getTypeLocClass() const {
210 return (TypeLocClass) getTypePtr()->getTypeClass();
214 friend class TypeLoc;
215 static bool isKind(const TypeLoc &TL) {
216 return !TL.getType().hasLocalQualifiers();
220 /// \brief Wrapper of type source information for a type with
221 /// non-trivial direct qualifiers.
223 /// Currently, we intentionally do not provide source location for
225 class QualifiedTypeLoc : public TypeLoc {
227 SourceRange getLocalSourceRange() const {
228 return SourceRange();
231 UnqualTypeLoc getUnqualifiedLoc() const {
232 return UnqualTypeLoc(getTypePtr(), Data);
235 /// Initializes the local data of this type source info block to
236 /// provide no information.
237 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
241 TypeLoc getNextTypeLoc() const {
242 return getUnqualifiedLoc();
245 /// \brief Returns the size of the type source info data block that is
246 /// specific to this type.
247 unsigned getLocalDataSize() const {
248 // In fact, we don't currently preserve any location information
253 /// \brief Returns the size of the type source info data block.
254 unsigned getFullDataSize() const {
255 return getLocalDataSize() +
256 getFullDataSizeForType(getType().getLocalUnqualifiedType());
260 friend class TypeLoc;
261 static bool isKind(const TypeLoc &TL) {
262 return TL.getType().hasLocalQualifiers();
266 inline UnqualTypeLoc TypeLoc::getUnqualifiedLoc() const {
267 if (QualifiedTypeLoc Loc = getAs<QualifiedTypeLoc>())
268 return Loc.getUnqualifiedLoc();
269 return castAs<UnqualTypeLoc>();
272 /// A metaprogramming base class for TypeLoc classes which correspond
273 /// to a particular Type subclass. It is accepted for a single
274 /// TypeLoc class to correspond to multiple Type classes.
276 /// \tparam Base a class from which to derive
277 /// \tparam Derived the class deriving from this one
278 /// \tparam TypeClass the concrete Type subclass associated with this
280 /// \tparam LocalData the structure type of local location data for
283 /// sizeof(LocalData) needs to be a multiple of sizeof(void*) or
284 /// else the world will end.
286 /// TypeLocs with non-constant amounts of local data should override
287 /// getExtraLocalDataSize(); getExtraLocalData() will then point to
288 /// this extra memory.
290 /// TypeLocs with an inner type should define
291 /// QualType getInnerType() const
292 /// and getInnerTypeLoc() will then point to this inner type's
295 /// A word about hierarchies: this template is not designed to be
296 /// derived from multiple times in a hierarchy. It is also not
297 /// designed to be used for classes where subtypes might provide
298 /// different amounts of source information. It should be subclassed
299 /// only at the deepest portion of the hierarchy where all children
300 /// have identical source information; if that's an abstract type,
301 /// then further descendents should inherit from
302 /// InheritingConcreteTypeLoc instead.
303 template <class Base, class Derived, class TypeClass, class LocalData>
304 class ConcreteTypeLoc : public Base {
306 const Derived *asDerived() const {
307 return static_cast<const Derived*>(this);
310 friend class TypeLoc;
311 static bool isKind(const TypeLoc &TL) {
312 return Derived::classofType(TL.getTypePtr());
315 static bool classofType(const Type *Ty) {
316 return TypeClass::classof(Ty);
320 unsigned getLocalDataSize() const {
321 return sizeof(LocalData) + asDerived()->getExtraLocalDataSize();
323 // Give a default implementation that's useful for leaf types.
324 unsigned getFullDataSize() const {
325 return asDerived()->getLocalDataSize() + getInnerTypeSize();
328 TypeLoc getNextTypeLoc() const {
329 return getNextTypeLoc(asDerived()->getInnerType());
332 const TypeClass *getTypePtr() const {
333 return cast<TypeClass>(Base::getTypePtr());
337 unsigned getExtraLocalDataSize() const {
341 LocalData *getLocalData() const {
342 return static_cast<LocalData*>(Base::Data);
345 /// Gets a pointer past the Info structure; useful for classes with
346 /// local data that can't be captured in the Info (e.g. because it's
347 /// of variable size).
348 void *getExtraLocalData() const {
349 return getLocalData() + 1;
352 void *getNonLocalData() const {
353 return static_cast<char*>(Base::Data) + asDerived()->getLocalDataSize();
356 struct HasNoInnerType {};
357 HasNoInnerType getInnerType() const { return HasNoInnerType(); }
359 TypeLoc getInnerTypeLoc() const {
360 return TypeLoc(asDerived()->getInnerType(), getNonLocalData());
364 unsigned getInnerTypeSize() const {
365 return getInnerTypeSize(asDerived()->getInnerType());
368 unsigned getInnerTypeSize(HasNoInnerType _) const {
372 unsigned getInnerTypeSize(QualType _) const {
373 return getInnerTypeLoc().getFullDataSize();
376 TypeLoc getNextTypeLoc(HasNoInnerType _) const {
380 TypeLoc getNextTypeLoc(QualType T) const {
381 return TypeLoc(T, getNonLocalData());
385 /// A metaprogramming class designed for concrete subtypes of abstract
386 /// types where all subtypes share equivalently-structured source
387 /// information. See the note on ConcreteTypeLoc.
388 template <class Base, class Derived, class TypeClass>
389 class InheritingConcreteTypeLoc : public Base {
390 friend class TypeLoc;
391 static bool classofType(const Type *Ty) {
392 return TypeClass::classof(Ty);
395 static bool isKind(const TypeLoc &TL) {
396 return Derived::classofType(TL.getTypePtr());
398 static bool isKind(const UnqualTypeLoc &TL) {
399 return Derived::classofType(TL.getTypePtr());
403 const TypeClass *getTypePtr() const {
404 return cast<TypeClass>(Base::getTypePtr());
409 struct TypeSpecLocInfo {
410 SourceLocation NameLoc;
413 /// \brief A reasonable base class for TypeLocs that correspond to
414 /// types that are written as a type-specifier.
415 class TypeSpecTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
420 enum { LocalDataSize = sizeof(TypeSpecLocInfo) };
422 SourceLocation getNameLoc() const {
423 return this->getLocalData()->NameLoc;
425 void setNameLoc(SourceLocation Loc) {
426 this->getLocalData()->NameLoc = Loc;
428 SourceRange getLocalSourceRange() const {
429 return SourceRange(getNameLoc(), getNameLoc());
431 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
436 friend class TypeLoc;
437 static bool isKind(const TypeLoc &TL);
441 struct BuiltinLocInfo {
442 SourceLocation BuiltinLoc;
445 /// \brief Wrapper for source info for builtin types.
446 class BuiltinTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
451 enum { LocalDataSize = sizeof(BuiltinLocInfo) };
453 SourceLocation getBuiltinLoc() const {
454 return getLocalData()->BuiltinLoc;
456 void setBuiltinLoc(SourceLocation Loc) {
457 getLocalData()->BuiltinLoc = Loc;
460 SourceLocation getNameLoc() const { return getBuiltinLoc(); }
462 WrittenBuiltinSpecs& getWrittenBuiltinSpecs() {
463 return *(static_cast<WrittenBuiltinSpecs*>(getExtraLocalData()));
465 const WrittenBuiltinSpecs& getWrittenBuiltinSpecs() const {
466 return *(static_cast<WrittenBuiltinSpecs*>(getExtraLocalData()));
469 bool needsExtraLocalData() const {
470 BuiltinType::Kind bk = getTypePtr()->getKind();
471 return (bk >= BuiltinType::UShort && bk <= BuiltinType::UInt128)
472 || (bk >= BuiltinType::Short && bk <= BuiltinType::LongDouble)
473 || bk == BuiltinType::UChar
474 || bk == BuiltinType::SChar;
477 unsigned getExtraLocalDataSize() const {
478 return needsExtraLocalData() ? sizeof(WrittenBuiltinSpecs) : 0;
481 SourceRange getLocalSourceRange() const {
482 return SourceRange(getBuiltinLoc(), getBuiltinLoc());
485 TypeSpecifierSign getWrittenSignSpec() const {
486 if (needsExtraLocalData())
487 return static_cast<TypeSpecifierSign>(getWrittenBuiltinSpecs().Sign);
489 return TSS_unspecified;
491 bool hasWrittenSignSpec() const {
492 return getWrittenSignSpec() != TSS_unspecified;
494 void setWrittenSignSpec(TypeSpecifierSign written) {
495 if (needsExtraLocalData())
496 getWrittenBuiltinSpecs().Sign = written;
499 TypeSpecifierWidth getWrittenWidthSpec() const {
500 if (needsExtraLocalData())
501 return static_cast<TypeSpecifierWidth>(getWrittenBuiltinSpecs().Width);
503 return TSW_unspecified;
505 bool hasWrittenWidthSpec() const {
506 return getWrittenWidthSpec() != TSW_unspecified;
508 void setWrittenWidthSpec(TypeSpecifierWidth written) {
509 if (needsExtraLocalData())
510 getWrittenBuiltinSpecs().Width = written;
513 TypeSpecifierType getWrittenTypeSpec() const;
514 bool hasWrittenTypeSpec() const {
515 return getWrittenTypeSpec() != TST_unspecified;
517 void setWrittenTypeSpec(TypeSpecifierType written) {
518 if (needsExtraLocalData())
519 getWrittenBuiltinSpecs().Type = written;
522 bool hasModeAttr() const {
523 if (needsExtraLocalData())
524 return getWrittenBuiltinSpecs().ModeAttr;
528 void setModeAttr(bool written) {
529 if (needsExtraLocalData())
530 getWrittenBuiltinSpecs().ModeAttr = written;
533 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
535 if (needsExtraLocalData()) {
536 WrittenBuiltinSpecs &wbs = getWrittenBuiltinSpecs();
537 wbs.Sign = TSS_unspecified;
538 wbs.Width = TSW_unspecified;
539 wbs.Type = TST_unspecified;
540 wbs.ModeAttr = false;
546 /// \brief Wrapper for source info for typedefs.
547 class TypedefTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
551 TypedefNameDecl *getTypedefNameDecl() const {
552 return getTypePtr()->getDecl();
556 /// \brief Wrapper for source info for injected class names of class
558 class InjectedClassNameTypeLoc :
559 public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
560 InjectedClassNameTypeLoc,
561 InjectedClassNameType> {
563 CXXRecordDecl *getDecl() const {
564 return getTypePtr()->getDecl();
568 /// \brief Wrapper for source info for unresolved typename using decls.
569 class UnresolvedUsingTypeLoc :
570 public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
571 UnresolvedUsingTypeLoc,
572 UnresolvedUsingType> {
574 UnresolvedUsingTypenameDecl *getDecl() const {
575 return getTypePtr()->getDecl();
579 /// \brief Wrapper for source info for tag types. Note that this only
580 /// records source info for the name itself; a type written 'struct foo'
581 /// should be represented as an ElaboratedTypeLoc. We currently
582 /// only do that when C++ is enabled because of the expense of
583 /// creating an ElaboratedType node for so many type references in C.
584 class TagTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
588 TagDecl *getDecl() const { return getTypePtr()->getDecl(); }
590 /// \brief True if the tag was defined in this type specifier.
591 bool isDefinition() const {
592 TagDecl *D = getDecl();
593 return D->isCompleteDefinition() &&
594 (D->getIdentifier() == 0 || D->getLocation() == getNameLoc());
598 /// \brief Wrapper for source info for record types.
599 class RecordTypeLoc : public InheritingConcreteTypeLoc<TagTypeLoc,
603 RecordDecl *getDecl() const { return getTypePtr()->getDecl(); }
606 /// \brief Wrapper for source info for enum types.
607 class EnumTypeLoc : public InheritingConcreteTypeLoc<TagTypeLoc,
611 EnumDecl *getDecl() const { return getTypePtr()->getDecl(); }
614 /// \brief Wrapper for template type parameters.
615 class TemplateTypeParmTypeLoc :
616 public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
617 TemplateTypeParmTypeLoc,
618 TemplateTypeParmType> {
620 TemplateTypeParmDecl *getDecl() const { return getTypePtr()->getDecl(); }
623 /// \brief Wrapper for substituted template type parameters.
624 class SubstTemplateTypeParmTypeLoc :
625 public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
626 SubstTemplateTypeParmTypeLoc,
627 SubstTemplateTypeParmType> {
630 /// \brief Wrapper for substituted template type parameters.
631 class SubstTemplateTypeParmPackTypeLoc :
632 public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
633 SubstTemplateTypeParmPackTypeLoc,
634 SubstTemplateTypeParmPackType> {
637 struct AttributedLocInfo {
641 /// A raw SourceLocation.
642 unsigned EnumOperandLoc;
645 SourceRange OperandParens;
647 SourceLocation AttrLoc;
650 /// \brief Type source information for an attributed type.
651 class AttributedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
656 AttributedType::Kind getAttrKind() const {
657 return getTypePtr()->getAttrKind();
660 bool hasAttrExprOperand() const {
661 return (getAttrKind() >= AttributedType::FirstExprOperandKind &&
662 getAttrKind() <= AttributedType::LastExprOperandKind);
665 bool hasAttrEnumOperand() const {
666 return (getAttrKind() >= AttributedType::FirstEnumOperandKind &&
667 getAttrKind() <= AttributedType::LastEnumOperandKind);
670 bool hasAttrOperand() const {
671 return hasAttrExprOperand() || hasAttrEnumOperand();
674 /// The modified type, which is generally canonically different from
675 /// the attribute type.
676 /// int main(int, char**) __attribute__((noreturn))
677 /// ~~~ ~~~~~~~~~~~~~
678 TypeLoc getModifiedLoc() const {
679 return getInnerTypeLoc();
682 /// The location of the attribute name, i.e.
683 /// __attribute__((regparm(1000)))
685 SourceLocation getAttrNameLoc() const {
686 return getLocalData()->AttrLoc;
688 void setAttrNameLoc(SourceLocation loc) {
689 getLocalData()->AttrLoc = loc;
692 /// The attribute's expression operand, if it has one.
693 /// void *cur_thread __attribute__((address_space(21)))
695 Expr *getAttrExprOperand() const {
696 assert(hasAttrExprOperand());
697 return getLocalData()->ExprOperand;
699 void setAttrExprOperand(Expr *e) {
700 assert(hasAttrExprOperand());
701 getLocalData()->ExprOperand = e;
704 /// The location of the attribute's enumerated operand, if it has one.
705 /// void * __attribute__((objc_gc(weak)))
707 SourceLocation getAttrEnumOperandLoc() const {
708 assert(hasAttrEnumOperand());
709 return SourceLocation::getFromRawEncoding(getLocalData()->EnumOperandLoc);
711 void setAttrEnumOperandLoc(SourceLocation loc) {
712 assert(hasAttrEnumOperand());
713 getLocalData()->EnumOperandLoc = loc.getRawEncoding();
716 /// The location of the parentheses around the operand, if there is
718 /// void * __attribute__((objc_gc(weak)))
720 SourceRange getAttrOperandParensRange() const {
721 assert(hasAttrOperand());
722 return getLocalData()->OperandParens;
724 void setAttrOperandParensRange(SourceRange range) {
725 assert(hasAttrOperand());
726 getLocalData()->OperandParens = range;
729 SourceRange getLocalSourceRange() const {
730 // Note that this does *not* include the range of the attribute
732 // __attribute__((foo(bar)))
733 // ^~~~~~~~~~~~~~~ ~~
737 // That enclosure doesn't necessarily belong to a single attribute
739 SourceRange range(getAttrNameLoc());
740 if (hasAttrOperand())
741 range.setEnd(getAttrOperandParensRange().getEnd());
745 void initializeLocal(ASTContext &Context, SourceLocation loc) {
747 if (hasAttrExprOperand()) {
748 setAttrOperandParensRange(SourceRange(loc));
749 setAttrExprOperand(0);
750 } else if (hasAttrEnumOperand()) {
751 setAttrOperandParensRange(SourceRange(loc));
752 setAttrEnumOperandLoc(loc);
756 QualType getInnerType() const {
757 return getTypePtr()->getModifiedType();
762 struct ObjCProtocolListLocInfo {
763 SourceLocation LAngleLoc;
764 SourceLocation RAngleLoc;
765 bool HasBaseTypeAsWritten;
768 // A helper class for defining ObjC TypeLocs that can qualified with
771 // TypeClass basically has to be either ObjCInterfaceType or
772 // ObjCObjectPointerType.
773 class ObjCObjectTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
776 ObjCProtocolListLocInfo> {
777 // SourceLocations are stored after Info, one for each Protocol.
778 SourceLocation *getProtocolLocArray() const {
779 return (SourceLocation*) this->getExtraLocalData();
783 SourceLocation getLAngleLoc() const {
784 return this->getLocalData()->LAngleLoc;
786 void setLAngleLoc(SourceLocation Loc) {
787 this->getLocalData()->LAngleLoc = Loc;
790 SourceLocation getRAngleLoc() const {
791 return this->getLocalData()->RAngleLoc;
793 void setRAngleLoc(SourceLocation Loc) {
794 this->getLocalData()->RAngleLoc = Loc;
797 unsigned getNumProtocols() const {
798 return this->getTypePtr()->getNumProtocols();
801 SourceLocation getProtocolLoc(unsigned i) const {
802 assert(i < getNumProtocols() && "Index is out of bounds!");
803 return getProtocolLocArray()[i];
805 void setProtocolLoc(unsigned i, SourceLocation Loc) {
806 assert(i < getNumProtocols() && "Index is out of bounds!");
807 getProtocolLocArray()[i] = Loc;
810 ObjCProtocolDecl *getProtocol(unsigned i) const {
811 assert(i < getNumProtocols() && "Index is out of bounds!");
812 return *(this->getTypePtr()->qual_begin() + i);
815 bool hasBaseTypeAsWritten() const {
816 return getLocalData()->HasBaseTypeAsWritten;
819 void setHasBaseTypeAsWritten(bool HasBaseType) {
820 getLocalData()->HasBaseTypeAsWritten = HasBaseType;
823 TypeLoc getBaseLoc() const {
824 return getInnerTypeLoc();
827 SourceRange getLocalSourceRange() const {
828 return SourceRange(getLAngleLoc(), getRAngleLoc());
831 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
832 setHasBaseTypeAsWritten(true);
835 for (unsigned i = 0, e = getNumProtocols(); i != e; ++i)
836 setProtocolLoc(i, Loc);
839 unsigned getExtraLocalDataSize() const {
840 return this->getNumProtocols() * sizeof(SourceLocation);
843 QualType getInnerType() const {
844 return getTypePtr()->getBaseType();
849 struct ObjCInterfaceLocInfo {
850 SourceLocation NameLoc;
851 SourceLocation NameEndLoc;
854 /// \brief Wrapper for source info for ObjC interfaces.
855 class ObjCInterfaceTypeLoc : public ConcreteTypeLoc<ObjCObjectTypeLoc,
856 ObjCInterfaceTypeLoc,
858 ObjCInterfaceLocInfo> {
860 ObjCInterfaceDecl *getIFaceDecl() const {
861 return getTypePtr()->getDecl();
864 SourceLocation getNameLoc() const {
865 return getLocalData()->NameLoc;
868 void setNameLoc(SourceLocation Loc) {
869 getLocalData()->NameLoc = Loc;
872 SourceRange getLocalSourceRange() const {
873 return SourceRange(getNameLoc(), getNameEndLoc());
876 SourceLocation getNameEndLoc() const {
877 return getLocalData()->NameEndLoc;
880 void setNameEndLoc(SourceLocation Loc) {
881 getLocalData()->NameEndLoc = Loc;
884 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
890 struct ParenLocInfo {
891 SourceLocation LParenLoc;
892 SourceLocation RParenLoc;
896 : public ConcreteTypeLoc<UnqualTypeLoc, ParenTypeLoc, ParenType,
899 SourceLocation getLParenLoc() const {
900 return this->getLocalData()->LParenLoc;
902 SourceLocation getRParenLoc() const {
903 return this->getLocalData()->RParenLoc;
905 void setLParenLoc(SourceLocation Loc) {
906 this->getLocalData()->LParenLoc = Loc;
908 void setRParenLoc(SourceLocation Loc) {
909 this->getLocalData()->RParenLoc = Loc;
912 SourceRange getLocalSourceRange() const {
913 return SourceRange(getLParenLoc(), getRParenLoc());
916 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
921 TypeLoc getInnerLoc() const {
922 return getInnerTypeLoc();
925 QualType getInnerType() const {
926 return this->getTypePtr()->getInnerType();
930 inline TypeLoc TypeLoc::IgnoreParens() const {
931 if (ParenTypeLoc::isKind(*this))
932 return IgnoreParensImpl(*this);
936 struct PointerLikeLocInfo {
937 SourceLocation StarLoc;
941 template <class Derived, class TypeClass, class LocalData = PointerLikeLocInfo>
942 class PointerLikeTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, Derived,
943 TypeClass, LocalData> {
945 SourceLocation getSigilLoc() const {
946 return this->getLocalData()->StarLoc;
948 void setSigilLoc(SourceLocation Loc) {
949 this->getLocalData()->StarLoc = Loc;
952 TypeLoc getPointeeLoc() const {
953 return this->getInnerTypeLoc();
956 SourceRange getLocalSourceRange() const {
957 return SourceRange(getSigilLoc(), getSigilLoc());
960 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
964 QualType getInnerType() const {
965 return this->getTypePtr()->getPointeeType();
970 /// \brief Wrapper for source info for pointers.
971 class PointerTypeLoc : public PointerLikeTypeLoc<PointerTypeLoc,
974 SourceLocation getStarLoc() const {
975 return getSigilLoc();
977 void setStarLoc(SourceLocation Loc) {
983 /// \brief Wrapper for source info for block pointers.
984 class BlockPointerTypeLoc : public PointerLikeTypeLoc<BlockPointerTypeLoc,
987 SourceLocation getCaretLoc() const {
988 return getSigilLoc();
990 void setCaretLoc(SourceLocation Loc) {
995 struct MemberPointerLocInfo : public PointerLikeLocInfo {
996 TypeSourceInfo *ClassTInfo;
999 /// \brief Wrapper for source info for member pointers.
1000 class MemberPointerTypeLoc : public PointerLikeTypeLoc<MemberPointerTypeLoc,
1002 MemberPointerLocInfo> {
1004 SourceLocation getStarLoc() const {
1005 return getSigilLoc();
1007 void setStarLoc(SourceLocation Loc) {
1011 const Type *getClass() const {
1012 return getTypePtr()->getClass();
1014 TypeSourceInfo *getClassTInfo() const {
1015 return getLocalData()->ClassTInfo;
1017 void setClassTInfo(TypeSourceInfo* TI) {
1018 getLocalData()->ClassTInfo = TI;
1021 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1026 SourceRange getLocalSourceRange() const {
1027 if (TypeSourceInfo *TI = getClassTInfo())
1028 return SourceRange(TI->getTypeLoc().getBeginLoc(), getStarLoc());
1030 return SourceRange(getStarLoc());
1034 /// Wraps an ObjCPointerType with source location information.
1035 class ObjCObjectPointerTypeLoc :
1036 public PointerLikeTypeLoc<ObjCObjectPointerTypeLoc,
1037 ObjCObjectPointerType> {
1039 SourceLocation getStarLoc() const {
1040 return getSigilLoc();
1043 void setStarLoc(SourceLocation Loc) {
1049 class ReferenceTypeLoc : public PointerLikeTypeLoc<ReferenceTypeLoc,
1052 QualType getInnerType() const {
1053 return getTypePtr()->getPointeeTypeAsWritten();
1057 class LValueReferenceTypeLoc :
1058 public InheritingConcreteTypeLoc<ReferenceTypeLoc,
1059 LValueReferenceTypeLoc,
1060 LValueReferenceType> {
1062 SourceLocation getAmpLoc() const {
1063 return getSigilLoc();
1065 void setAmpLoc(SourceLocation Loc) {
1070 class RValueReferenceTypeLoc :
1071 public InheritingConcreteTypeLoc<ReferenceTypeLoc,
1072 RValueReferenceTypeLoc,
1073 RValueReferenceType> {
1075 SourceLocation getAmpAmpLoc() const {
1076 return getSigilLoc();
1078 void setAmpAmpLoc(SourceLocation Loc) {
1084 struct FunctionLocInfo {
1085 SourceLocation LocalRangeBegin;
1086 SourceLocation LParenLoc;
1087 SourceLocation RParenLoc;
1088 SourceLocation LocalRangeEnd;
1091 /// \brief Wrapper for source info for functions.
1092 class FunctionTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
1097 SourceLocation getLocalRangeBegin() const {
1098 return getLocalData()->LocalRangeBegin;
1100 void setLocalRangeBegin(SourceLocation L) {
1101 getLocalData()->LocalRangeBegin = L;
1104 SourceLocation getLocalRangeEnd() const {
1105 return getLocalData()->LocalRangeEnd;
1107 void setLocalRangeEnd(SourceLocation L) {
1108 getLocalData()->LocalRangeEnd = L;
1111 SourceLocation getLParenLoc() const {
1112 return this->getLocalData()->LParenLoc;
1114 void setLParenLoc(SourceLocation Loc) {
1115 this->getLocalData()->LParenLoc = Loc;
1118 SourceLocation getRParenLoc() const {
1119 return this->getLocalData()->RParenLoc;
1121 void setRParenLoc(SourceLocation Loc) {
1122 this->getLocalData()->RParenLoc = Loc;
1125 SourceRange getParensRange() const {
1126 return SourceRange(getLParenLoc(), getRParenLoc());
1129 ArrayRef<ParmVarDecl *> getParams() const {
1130 return ArrayRef<ParmVarDecl *>(getParmArray(), getNumArgs());
1133 // ParmVarDecls* are stored after Info, one for each argument.
1134 ParmVarDecl **getParmArray() const {
1135 return (ParmVarDecl**) getExtraLocalData();
1138 unsigned getNumArgs() const {
1139 if (isa<FunctionNoProtoType>(getTypePtr()))
1141 return cast<FunctionProtoType>(getTypePtr())->getNumArgs();
1143 ParmVarDecl *getArg(unsigned i) const { return getParmArray()[i]; }
1144 void setArg(unsigned i, ParmVarDecl *VD) { getParmArray()[i] = VD; }
1146 TypeLoc getResultLoc() const {
1147 return getInnerTypeLoc();
1150 SourceRange getLocalSourceRange() const {
1151 return SourceRange(getLocalRangeBegin(), getLocalRangeEnd());
1154 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1155 setLocalRangeBegin(Loc);
1158 setLocalRangeEnd(Loc);
1159 for (unsigned i = 0, e = getNumArgs(); i != e; ++i)
1163 /// \brief Returns the size of the type source info data block that is
1164 /// specific to this type.
1165 unsigned getExtraLocalDataSize() const {
1166 return getNumArgs() * sizeof(ParmVarDecl*);
1169 QualType getInnerType() const { return getTypePtr()->getResultType(); }
1172 class FunctionProtoTypeLoc :
1173 public InheritingConcreteTypeLoc<FunctionTypeLoc,
1174 FunctionProtoTypeLoc,
1175 FunctionProtoType> {
1178 class FunctionNoProtoTypeLoc :
1179 public InheritingConcreteTypeLoc<FunctionTypeLoc,
1180 FunctionNoProtoTypeLoc,
1181 FunctionNoProtoType> {
1185 struct ArrayLocInfo {
1186 SourceLocation LBracketLoc, RBracketLoc;
1190 /// \brief Wrapper for source info for arrays.
1191 class ArrayTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
1196 SourceLocation getLBracketLoc() const {
1197 return getLocalData()->LBracketLoc;
1199 void setLBracketLoc(SourceLocation Loc) {
1200 getLocalData()->LBracketLoc = Loc;
1203 SourceLocation getRBracketLoc() const {
1204 return getLocalData()->RBracketLoc;
1206 void setRBracketLoc(SourceLocation Loc) {
1207 getLocalData()->RBracketLoc = Loc;
1210 SourceRange getBracketsRange() const {
1211 return SourceRange(getLBracketLoc(), getRBracketLoc());
1214 Expr *getSizeExpr() const {
1215 return getLocalData()->Size;
1217 void setSizeExpr(Expr *Size) {
1218 getLocalData()->Size = Size;
1221 TypeLoc getElementLoc() const {
1222 return getInnerTypeLoc();
1225 SourceRange getLocalSourceRange() const {
1226 return SourceRange(getLBracketLoc(), getRBracketLoc());
1229 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1230 setLBracketLoc(Loc);
1231 setRBracketLoc(Loc);
1235 QualType getInnerType() const { return getTypePtr()->getElementType(); }
1238 class ConstantArrayTypeLoc :
1239 public InheritingConcreteTypeLoc<ArrayTypeLoc,
1240 ConstantArrayTypeLoc,
1241 ConstantArrayType> {
1244 class IncompleteArrayTypeLoc :
1245 public InheritingConcreteTypeLoc<ArrayTypeLoc,
1246 IncompleteArrayTypeLoc,
1247 IncompleteArrayType> {
1250 class DependentSizedArrayTypeLoc :
1251 public InheritingConcreteTypeLoc<ArrayTypeLoc,
1252 DependentSizedArrayTypeLoc,
1253 DependentSizedArrayType> {
1257 class VariableArrayTypeLoc :
1258 public InheritingConcreteTypeLoc<ArrayTypeLoc,
1259 VariableArrayTypeLoc,
1260 VariableArrayType> {
1264 // Location information for a TemplateName. Rudimentary for now.
1265 struct TemplateNameLocInfo {
1266 SourceLocation NameLoc;
1269 struct TemplateSpecializationLocInfo : TemplateNameLocInfo {
1270 SourceLocation TemplateKWLoc;
1271 SourceLocation LAngleLoc;
1272 SourceLocation RAngleLoc;
1275 class TemplateSpecializationTypeLoc :
1276 public ConcreteTypeLoc<UnqualTypeLoc,
1277 TemplateSpecializationTypeLoc,
1278 TemplateSpecializationType,
1279 TemplateSpecializationLocInfo> {
1281 SourceLocation getTemplateKeywordLoc() const {
1282 return getLocalData()->TemplateKWLoc;
1284 void setTemplateKeywordLoc(SourceLocation Loc) {
1285 getLocalData()->TemplateKWLoc = Loc;
1288 SourceLocation getLAngleLoc() const {
1289 return getLocalData()->LAngleLoc;
1291 void setLAngleLoc(SourceLocation Loc) {
1292 getLocalData()->LAngleLoc = Loc;
1295 SourceLocation getRAngleLoc() const {
1296 return getLocalData()->RAngleLoc;
1298 void setRAngleLoc(SourceLocation Loc) {
1299 getLocalData()->RAngleLoc = Loc;
1302 unsigned getNumArgs() const {
1303 return getTypePtr()->getNumArgs();
1305 void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) {
1306 getArgInfos()[i] = AI;
1308 TemplateArgumentLocInfo getArgLocInfo(unsigned i) const {
1309 return getArgInfos()[i];
1312 TemplateArgumentLoc getArgLoc(unsigned i) const {
1313 return TemplateArgumentLoc(getTypePtr()->getArg(i), getArgLocInfo(i));
1316 SourceLocation getTemplateNameLoc() const {
1317 return getLocalData()->NameLoc;
1319 void setTemplateNameLoc(SourceLocation Loc) {
1320 getLocalData()->NameLoc = Loc;
1323 /// \brief - Copy the location information from the given info.
1324 void copy(TemplateSpecializationTypeLoc Loc) {
1325 unsigned size = getFullDataSize();
1326 assert(size == Loc.getFullDataSize());
1328 // We're potentially copying Expr references here. We don't
1329 // bother retaining them because TypeSourceInfos live forever, so
1330 // as long as the Expr was retained when originally written into
1331 // the TypeLoc, we're okay.
1332 memcpy(Data, Loc.Data, size);
1335 SourceRange getLocalSourceRange() const {
1336 if (getTemplateKeywordLoc().isValid())
1337 return SourceRange(getTemplateKeywordLoc(), getRAngleLoc());
1339 return SourceRange(getTemplateNameLoc(), getRAngleLoc());
1342 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1343 setTemplateKeywordLoc(Loc);
1344 setTemplateNameLoc(Loc);
1347 initializeArgLocs(Context, getNumArgs(), getTypePtr()->getArgs(),
1348 getArgInfos(), Loc);
1351 static void initializeArgLocs(ASTContext &Context, unsigned NumArgs,
1352 const TemplateArgument *Args,
1353 TemplateArgumentLocInfo *ArgInfos,
1354 SourceLocation Loc);
1356 unsigned getExtraLocalDataSize() const {
1357 return getNumArgs() * sizeof(TemplateArgumentLocInfo);
1361 TemplateArgumentLocInfo *getArgInfos() const {
1362 return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData());
1366 //===----------------------------------------------------------------------===//
1368 // All of these need proper implementations.
1370 //===----------------------------------------------------------------------===//
1372 // FIXME: size expression and attribute locations (or keyword if we
1373 // ever fully support altivec syntax).
1374 class VectorTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
1379 // FIXME: size expression and attribute locations.
1380 class ExtVectorTypeLoc : public InheritingConcreteTypeLoc<VectorTypeLoc,
1385 // FIXME: attribute locations.
1386 // For some reason, this isn't a subtype of VectorType.
1387 class DependentSizedExtVectorTypeLoc :
1388 public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
1389 DependentSizedExtVectorTypeLoc,
1390 DependentSizedExtVectorType> {
1393 // FIXME: location of the '_Complex' keyword.
1394 class ComplexTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
1399 struct TypeofLocInfo {
1400 SourceLocation TypeofLoc;
1401 SourceLocation LParenLoc;
1402 SourceLocation RParenLoc;
1405 struct TypeOfExprTypeLocInfo : public TypeofLocInfo {
1408 struct TypeOfTypeLocInfo : public TypeofLocInfo {
1409 TypeSourceInfo* UnderlyingTInfo;
1412 template <class Derived, class TypeClass, class LocalData = TypeofLocInfo>
1413 class TypeofLikeTypeLoc
1414 : public ConcreteTypeLoc<UnqualTypeLoc, Derived, TypeClass, LocalData> {
1416 SourceLocation getTypeofLoc() const {
1417 return this->getLocalData()->TypeofLoc;
1419 void setTypeofLoc(SourceLocation Loc) {
1420 this->getLocalData()->TypeofLoc = Loc;
1423 SourceLocation getLParenLoc() const {
1424 return this->getLocalData()->LParenLoc;
1426 void setLParenLoc(SourceLocation Loc) {
1427 this->getLocalData()->LParenLoc = Loc;
1430 SourceLocation getRParenLoc() const {
1431 return this->getLocalData()->RParenLoc;
1433 void setRParenLoc(SourceLocation Loc) {
1434 this->getLocalData()->RParenLoc = Loc;
1437 SourceRange getParensRange() const {
1438 return SourceRange(getLParenLoc(), getRParenLoc());
1440 void setParensRange(SourceRange range) {
1441 setLParenLoc(range.getBegin());
1442 setRParenLoc(range.getEnd());
1445 SourceRange getLocalSourceRange() const {
1446 return SourceRange(getTypeofLoc(), getRParenLoc());
1449 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1456 class TypeOfExprTypeLoc : public TypeofLikeTypeLoc<TypeOfExprTypeLoc,
1458 TypeOfExprTypeLocInfo> {
1460 Expr* getUnderlyingExpr() const {
1461 return getTypePtr()->getUnderlyingExpr();
1463 // Reimplemented to account for GNU/C++ extension
1464 // typeof unary-expression
1465 // where there are no parentheses.
1466 SourceRange getLocalSourceRange() const;
1470 : public TypeofLikeTypeLoc<TypeOfTypeLoc, TypeOfType, TypeOfTypeLocInfo> {
1472 QualType getUnderlyingType() const {
1473 return this->getTypePtr()->getUnderlyingType();
1475 TypeSourceInfo* getUnderlyingTInfo() const {
1476 return this->getLocalData()->UnderlyingTInfo;
1478 void setUnderlyingTInfo(TypeSourceInfo* TI) const {
1479 this->getLocalData()->UnderlyingTInfo = TI;
1483 // FIXME: location of the 'decltype' and parens.
1484 class DecltypeTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
1488 Expr *getUnderlyingExpr() const { return getTypePtr()->getUnderlyingExpr(); }
1491 struct UnaryTransformTypeLocInfo {
1492 // FIXME: While there's only one unary transform right now, future ones may
1493 // need different representations
1494 SourceLocation KWLoc, LParenLoc, RParenLoc;
1495 TypeSourceInfo *UnderlyingTInfo;
1498 class UnaryTransformTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
1499 UnaryTransformTypeLoc,
1501 UnaryTransformTypeLocInfo> {
1503 SourceLocation getKWLoc() const { return getLocalData()->KWLoc; }
1504 void setKWLoc(SourceLocation Loc) { getLocalData()->KWLoc = Loc; }
1506 SourceLocation getLParenLoc() const { return getLocalData()->LParenLoc; }
1507 void setLParenLoc(SourceLocation Loc) { getLocalData()->LParenLoc = Loc; }
1509 SourceLocation getRParenLoc() const { return getLocalData()->RParenLoc; }
1510 void setRParenLoc(SourceLocation Loc) { getLocalData()->RParenLoc = Loc; }
1512 TypeSourceInfo* getUnderlyingTInfo() const {
1513 return getLocalData()->UnderlyingTInfo;
1515 void setUnderlyingTInfo(TypeSourceInfo *TInfo) {
1516 getLocalData()->UnderlyingTInfo = TInfo;
1519 SourceRange getLocalSourceRange() const {
1520 return SourceRange(getKWLoc(), getRParenLoc());
1523 SourceRange getParensRange() const {
1524 return SourceRange(getLParenLoc(), getRParenLoc());
1526 void setParensRange(SourceRange Range) {
1527 setLParenLoc(Range.getBegin());
1528 setRParenLoc(Range.getEnd());
1531 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1538 class AutoTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
1543 struct ElaboratedLocInfo {
1544 SourceLocation ElaboratedKWLoc;
1545 /// \brief Data associated with the nested-name-specifier location.
1546 void *QualifierData;
1549 class ElaboratedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
1552 ElaboratedLocInfo> {
1554 SourceLocation getElaboratedKeywordLoc() const {
1555 return this->getLocalData()->ElaboratedKWLoc;
1557 void setElaboratedKeywordLoc(SourceLocation Loc) {
1558 this->getLocalData()->ElaboratedKWLoc = Loc;
1561 NestedNameSpecifierLoc getQualifierLoc() const {
1562 return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
1563 getLocalData()->QualifierData);
1566 void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
1567 assert(QualifierLoc.getNestedNameSpecifier()
1568 == getTypePtr()->getQualifier() &&
1569 "Inconsistent nested-name-specifier pointer");
1570 getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
1573 SourceRange getLocalSourceRange() const {
1574 if (getElaboratedKeywordLoc().isValid())
1575 if (getQualifierLoc())
1576 return SourceRange(getElaboratedKeywordLoc(),
1577 getQualifierLoc().getEndLoc());
1579 return SourceRange(getElaboratedKeywordLoc());
1581 return getQualifierLoc().getSourceRange();
1584 void initializeLocal(ASTContext &Context, SourceLocation Loc);
1586 TypeLoc getNamedTypeLoc() const {
1587 return getInnerTypeLoc();
1590 QualType getInnerType() const {
1591 return getTypePtr()->getNamedType();
1594 void copy(ElaboratedTypeLoc Loc) {
1595 unsigned size = getFullDataSize();
1596 assert(size == Loc.getFullDataSize());
1597 memcpy(Data, Loc.Data, size);
1601 // This is exactly the structure of an ElaboratedTypeLoc whose inner
1602 // type is some sort of TypeDeclTypeLoc.
1603 struct DependentNameLocInfo : ElaboratedLocInfo {
1604 SourceLocation NameLoc;
1607 class DependentNameTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
1608 DependentNameTypeLoc,
1610 DependentNameLocInfo> {
1612 SourceLocation getElaboratedKeywordLoc() const {
1613 return this->getLocalData()->ElaboratedKWLoc;
1615 void setElaboratedKeywordLoc(SourceLocation Loc) {
1616 this->getLocalData()->ElaboratedKWLoc = Loc;
1619 NestedNameSpecifierLoc getQualifierLoc() const {
1620 return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
1621 getLocalData()->QualifierData);
1624 void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
1625 assert(QualifierLoc.getNestedNameSpecifier()
1626 == getTypePtr()->getQualifier() &&
1627 "Inconsistent nested-name-specifier pointer");
1628 getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
1631 SourceLocation getNameLoc() const {
1632 return this->getLocalData()->NameLoc;
1634 void setNameLoc(SourceLocation Loc) {
1635 this->getLocalData()->NameLoc = Loc;
1638 SourceRange getLocalSourceRange() const {
1639 if (getElaboratedKeywordLoc().isValid())
1640 return SourceRange(getElaboratedKeywordLoc(), getNameLoc());
1642 return SourceRange(getQualifierLoc().getBeginLoc(), getNameLoc());
1645 void copy(DependentNameTypeLoc Loc) {
1646 unsigned size = getFullDataSize();
1647 assert(size == Loc.getFullDataSize());
1648 memcpy(Data, Loc.Data, size);
1651 void initializeLocal(ASTContext &Context, SourceLocation Loc);
1654 struct DependentTemplateSpecializationLocInfo : DependentNameLocInfo {
1655 SourceLocation TemplateKWLoc;
1656 SourceLocation LAngleLoc;
1657 SourceLocation RAngleLoc;
1658 // followed by a TemplateArgumentLocInfo[]
1661 class DependentTemplateSpecializationTypeLoc :
1662 public ConcreteTypeLoc<UnqualTypeLoc,
1663 DependentTemplateSpecializationTypeLoc,
1664 DependentTemplateSpecializationType,
1665 DependentTemplateSpecializationLocInfo> {
1667 SourceLocation getElaboratedKeywordLoc() const {
1668 return this->getLocalData()->ElaboratedKWLoc;
1670 void setElaboratedKeywordLoc(SourceLocation Loc) {
1671 this->getLocalData()->ElaboratedKWLoc = Loc;
1674 NestedNameSpecifierLoc getQualifierLoc() const {
1675 if (!getLocalData()->QualifierData)
1676 return NestedNameSpecifierLoc();
1678 return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
1679 getLocalData()->QualifierData);
1682 void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
1683 if (!QualifierLoc) {
1684 // Even if we have a nested-name-specifier in the dependent
1685 // template specialization type, we won't record the nested-name-specifier
1686 // location information when this type-source location information is
1687 // part of a nested-name-specifier.
1688 getLocalData()->QualifierData = 0;
1692 assert(QualifierLoc.getNestedNameSpecifier()
1693 == getTypePtr()->getQualifier() &&
1694 "Inconsistent nested-name-specifier pointer");
1695 getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
1698 SourceLocation getTemplateKeywordLoc() const {
1699 return getLocalData()->TemplateKWLoc;
1701 void setTemplateKeywordLoc(SourceLocation Loc) {
1702 getLocalData()->TemplateKWLoc = Loc;
1705 SourceLocation getTemplateNameLoc() const {
1706 return this->getLocalData()->NameLoc;
1708 void setTemplateNameLoc(SourceLocation Loc) {
1709 this->getLocalData()->NameLoc = Loc;
1712 SourceLocation getLAngleLoc() const {
1713 return this->getLocalData()->LAngleLoc;
1715 void setLAngleLoc(SourceLocation Loc) {
1716 this->getLocalData()->LAngleLoc = Loc;
1719 SourceLocation getRAngleLoc() const {
1720 return this->getLocalData()->RAngleLoc;
1722 void setRAngleLoc(SourceLocation Loc) {
1723 this->getLocalData()->RAngleLoc = Loc;
1726 unsigned getNumArgs() const {
1727 return getTypePtr()->getNumArgs();
1730 void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) {
1731 getArgInfos()[i] = AI;
1733 TemplateArgumentLocInfo getArgLocInfo(unsigned i) const {
1734 return getArgInfos()[i];
1737 TemplateArgumentLoc getArgLoc(unsigned i) const {
1738 return TemplateArgumentLoc(getTypePtr()->getArg(i), getArgLocInfo(i));
1741 SourceRange getLocalSourceRange() const {
1742 if (getElaboratedKeywordLoc().isValid())
1743 return SourceRange(getElaboratedKeywordLoc(), getRAngleLoc());
1744 else if (getQualifierLoc())
1745 return SourceRange(getQualifierLoc().getBeginLoc(), getRAngleLoc());
1746 else if (getTemplateKeywordLoc().isValid())
1747 return SourceRange(getTemplateKeywordLoc(), getRAngleLoc());
1749 return SourceRange(getTemplateNameLoc(), getRAngleLoc());
1752 void copy(DependentTemplateSpecializationTypeLoc Loc) {
1753 unsigned size = getFullDataSize();
1754 assert(size == Loc.getFullDataSize());
1755 memcpy(Data, Loc.Data, size);
1758 void initializeLocal(ASTContext &Context, SourceLocation Loc);
1760 unsigned getExtraLocalDataSize() const {
1761 return getNumArgs() * sizeof(TemplateArgumentLocInfo);
1765 TemplateArgumentLocInfo *getArgInfos() const {
1766 return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData());
1771 struct PackExpansionTypeLocInfo {
1772 SourceLocation EllipsisLoc;
1775 class PackExpansionTypeLoc
1776 : public ConcreteTypeLoc<UnqualTypeLoc, PackExpansionTypeLoc,
1777 PackExpansionType, PackExpansionTypeLocInfo> {
1779 SourceLocation getEllipsisLoc() const {
1780 return this->getLocalData()->EllipsisLoc;
1783 void setEllipsisLoc(SourceLocation Loc) {
1784 this->getLocalData()->EllipsisLoc = Loc;
1787 SourceRange getLocalSourceRange() const {
1788 return SourceRange(getEllipsisLoc(), getEllipsisLoc());
1791 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1792 setEllipsisLoc(Loc);
1795 TypeLoc getPatternLoc() const {
1796 return getInnerTypeLoc();
1799 QualType getInnerType() const {
1800 return this->getTypePtr()->getPattern();
1804 struct AtomicTypeLocInfo {
1805 SourceLocation KWLoc, LParenLoc, RParenLoc;
1808 class AtomicTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, AtomicTypeLoc,
1809 AtomicType, AtomicTypeLocInfo> {
1811 TypeLoc getValueLoc() const {
1812 return this->getInnerTypeLoc();
1815 SourceRange getLocalSourceRange() const {
1816 return SourceRange(getKWLoc(), getRParenLoc());
1819 SourceLocation getKWLoc() const {
1820 return this->getLocalData()->KWLoc;
1822 void setKWLoc(SourceLocation Loc) {
1823 this->getLocalData()->KWLoc = Loc;
1826 SourceLocation getLParenLoc() const {
1827 return this->getLocalData()->LParenLoc;
1829 void setLParenLoc(SourceLocation Loc) {
1830 this->getLocalData()->LParenLoc = Loc;
1833 SourceLocation getRParenLoc() const {
1834 return this->getLocalData()->RParenLoc;
1836 void setRParenLoc(SourceLocation Loc) {
1837 this->getLocalData()->RParenLoc = Loc;
1840 SourceRange getParensRange() const {
1841 return SourceRange(getLParenLoc(), getRParenLoc());
1843 void setParensRange(SourceRange Range) {
1844 setLParenLoc(Range.getBegin());
1845 setRParenLoc(Range.getEnd());
1848 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1854 QualType getInnerType() const {
1855 return this->getTypePtr()->getValueType();