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/Type.h"
18 #include "clang/AST/Decl.h"
19 #include "clang/AST/TemplateBase.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 /// The kinds of TypeLocs. Equivalent to the Type::TypeClass enum,
48 /// except it also defines a Qualified enum that corresponds to the
49 /// QualifiedLoc class.
51 #define ABSTRACT_TYPE(Class, Base)
52 #define TYPE(Class, Base) \
54 #include "clang/AST/TypeNodes.def"
58 TypeLoc() : Ty(0), Data(0) { }
59 TypeLoc(QualType ty, void *opaqueData)
60 : Ty(ty.getAsOpaquePtr()), Data(opaqueData) { }
61 TypeLoc(const Type *ty, void *opaqueData)
62 : Ty(ty), Data(opaqueData) { }
64 TypeLocClass getTypeLocClass() const {
65 if (getType().hasLocalQualifiers()) return Qualified;
66 return (TypeLocClass) getType()->getTypeClass();
69 bool isNull() const { return !Ty; }
70 operator bool() const { return Ty; }
72 /// \brief Returns the size of type source info data block for the given type.
73 static unsigned getFullDataSizeForType(QualType Ty);
75 /// \brief Get the type for which this source info wrapper provides
77 QualType getType() const {
78 return QualType::getFromOpaquePtr(Ty);
81 const Type *getTypePtr() const {
82 return QualType::getFromOpaquePtr(Ty).getTypePtr();
85 /// \brief Get the pointer where source information is stored.
86 void *getOpaqueData() const {
90 /// \brief Get the begin source location.
91 SourceLocation getBeginLoc() const;
93 /// \brief Get the end source location.
94 SourceLocation getEndLoc() const;
96 /// \brief Get the full source range.
97 SourceRange getSourceRange() const LLVM_READONLY {
98 return SourceRange(getBeginLoc(), getEndLoc());
100 SourceLocation getLocStart() const LLVM_READONLY { return getBeginLoc(); }
101 SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
103 /// \brief Get the local source range.
104 SourceRange getLocalSourceRange() const {
105 return getLocalSourceRangeImpl(*this);
108 /// \brief Returns the size of the type source info data block.
109 unsigned getFullDataSize() const {
110 return getFullDataSizeForType(getType());
113 /// \brief Get the next TypeLoc pointed by this TypeLoc, e.g for "int*" the
114 /// TypeLoc is a PointerLoc and next TypeLoc is for "int".
115 TypeLoc getNextTypeLoc() const {
116 return getNextTypeLocImpl(*this);
119 /// \brief Skips past any qualifiers, if this is qualified.
120 UnqualTypeLoc getUnqualifiedLoc() const; // implemented in this header
122 TypeLoc IgnoreParens() const {
123 if (isa<ParenTypeLoc>(this))
124 return IgnoreParensImpl(*this);
128 /// \brief Initializes this to state that every location in this
129 /// type is the given location.
131 /// This method exists to provide a simple transition for code that
132 /// relies on location-less types.
133 void initialize(ASTContext &Context, SourceLocation Loc) const {
134 initializeImpl(Context, *this, Loc);
137 /// \brief Initializes this by copying its information from another
138 /// TypeLoc of the same type.
139 void initializeFullCopy(TypeLoc Other) const {
140 assert(getType() == Other.getType());
141 size_t Size = getFullDataSize();
142 memcpy(getOpaqueData(), Other.getOpaqueData(), Size);
145 /// \brief Initializes this by copying its information from another
146 /// TypeLoc of the same type. The given size must be the full data
148 void initializeFullCopy(TypeLoc Other, unsigned Size) const {
149 assert(getType() == Other.getType());
150 assert(getFullDataSize() == Size);
151 memcpy(getOpaqueData(), Other.getOpaqueData(), Size);
154 friend bool operator==(const TypeLoc &LHS, const TypeLoc &RHS) {
155 return LHS.Ty == RHS.Ty && LHS.Data == RHS.Data;
158 friend bool operator!=(const TypeLoc &LHS, const TypeLoc &RHS) {
159 return !(LHS == RHS);
162 static bool classof(const TypeLoc *TL) { return true; }
165 static void initializeImpl(ASTContext &Context, TypeLoc TL,
167 static TypeLoc getNextTypeLocImpl(TypeLoc TL);
168 static TypeLoc IgnoreParensImpl(TypeLoc TL);
169 static SourceRange getLocalSourceRangeImpl(TypeLoc TL);
172 /// \brief Return the TypeLoc for a type source info.
173 inline TypeLoc TypeSourceInfo::getTypeLoc() const {
174 return TypeLoc(Ty, const_cast<void*>(static_cast<const void*>(this + 1)));
177 /// \brief Wrapper of type source information for a type with
178 /// no direct qualifiers.
179 class UnqualTypeLoc : public TypeLoc {
182 UnqualTypeLoc(const Type *Ty, void *Data) : TypeLoc(Ty, Data) {}
184 const Type *getTypePtr() const {
185 return reinterpret_cast<const Type*>(Ty);
188 TypeLocClass getTypeLocClass() const {
189 return (TypeLocClass) getTypePtr()->getTypeClass();
192 static bool classof(const TypeLoc *TL) {
193 return !TL->getType().hasLocalQualifiers();
195 static bool classof(const UnqualTypeLoc *TL) { return true; }
198 /// \brief Wrapper of type source information for a type with
199 /// non-trivial direct qualifiers.
201 /// Currently, we intentionally do not provide source location for
203 class QualifiedTypeLoc : public TypeLoc {
205 SourceRange getLocalSourceRange() const {
206 return SourceRange();
209 UnqualTypeLoc getUnqualifiedLoc() const {
210 return UnqualTypeLoc(getTypePtr(), Data);
213 /// Initializes the local data of this type source info block to
214 /// provide no information.
215 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
219 TypeLoc getNextTypeLoc() const {
220 return getUnqualifiedLoc();
223 /// \brief Returns the size of the type source info data block that is
224 /// specific to this type.
225 unsigned getLocalDataSize() const {
226 // In fact, we don't currently preserve any location information
231 /// \brief Returns the size of the type source info data block.
232 unsigned getFullDataSize() const {
233 return getLocalDataSize() +
234 getFullDataSizeForType(getType().getLocalUnqualifiedType());
237 static bool classof(const TypeLoc *TL) {
238 return TL->getType().hasLocalQualifiers();
240 static bool classof(const QualifiedTypeLoc *TL) { return true; }
243 inline UnqualTypeLoc TypeLoc::getUnqualifiedLoc() const {
244 if (isa<QualifiedTypeLoc>(this))
245 return cast<QualifiedTypeLoc>(this)->getUnqualifiedLoc();
246 return cast<UnqualTypeLoc>(*this);
249 /// A metaprogramming base class for TypeLoc classes which correspond
250 /// to a particular Type subclass. It is accepted for a single
251 /// TypeLoc class to correspond to multiple Type classes.
253 /// \param Base a class from which to derive
254 /// \param Derived the class deriving from this one
255 /// \param TypeClass the concrete Type subclass associated with this
257 /// \param LocalData the structure type of local location data for
260 /// sizeof(LocalData) needs to be a multiple of sizeof(void*) or
261 /// else the world will end.
263 /// TypeLocs with non-constant amounts of local data should override
264 /// getExtraLocalDataSize(); getExtraLocalData() will then point to
265 /// this extra memory.
267 /// TypeLocs with an inner type should define
268 /// QualType getInnerType() const
269 /// and getInnerTypeLoc() will then point to this inner type's
272 /// A word about hierarchies: this template is not designed to be
273 /// derived from multiple times in a hierarchy. It is also not
274 /// designed to be used for classes where subtypes might provide
275 /// different amounts of source information. It should be subclassed
276 /// only at the deepest portion of the hierarchy where all children
277 /// have identical source information; if that's an abstract type,
278 /// then further descendents should inherit from
279 /// InheritingConcreteTypeLoc instead.
280 template <class Base, class Derived, class TypeClass, class LocalData>
281 class ConcreteTypeLoc : public Base {
283 const Derived *asDerived() const {
284 return static_cast<const Derived*>(this);
288 unsigned getLocalDataSize() const {
289 return sizeof(LocalData) + asDerived()->getExtraLocalDataSize();
291 // Give a default implementation that's useful for leaf types.
292 unsigned getFullDataSize() const {
293 return asDerived()->getLocalDataSize() + getInnerTypeSize();
296 static bool classofType(const Type *Ty) {
297 return TypeClass::classof(Ty);
300 static bool classof(const TypeLoc *TL) {
301 return Derived::classofType(TL->getTypePtr());
303 static bool classof(const UnqualTypeLoc *TL) {
304 return Derived::classofType(TL->getTypePtr());
306 static bool classof(const Derived *TL) {
310 TypeLoc getNextTypeLoc() const {
311 return getNextTypeLoc(asDerived()->getInnerType());
314 const TypeClass *getTypePtr() const {
315 return cast<TypeClass>(Base::getTypePtr());
319 unsigned getExtraLocalDataSize() const {
323 LocalData *getLocalData() const {
324 return static_cast<LocalData*>(Base::Data);
327 /// Gets a pointer past the Info structure; useful for classes with
328 /// local data that can't be captured in the Info (e.g. because it's
329 /// of variable size).
330 void *getExtraLocalData() const {
331 return getLocalData() + 1;
334 void *getNonLocalData() const {
335 return static_cast<char*>(Base::Data) + asDerived()->getLocalDataSize();
338 struct HasNoInnerType {};
339 HasNoInnerType getInnerType() const { return HasNoInnerType(); }
341 TypeLoc getInnerTypeLoc() const {
342 return TypeLoc(asDerived()->getInnerType(), getNonLocalData());
346 unsigned getInnerTypeSize() const {
347 return getInnerTypeSize(asDerived()->getInnerType());
350 unsigned getInnerTypeSize(HasNoInnerType _) const {
354 unsigned getInnerTypeSize(QualType _) const {
355 return getInnerTypeLoc().getFullDataSize();
358 TypeLoc getNextTypeLoc(HasNoInnerType _) const {
362 TypeLoc getNextTypeLoc(QualType T) const {
363 return TypeLoc(T, getNonLocalData());
367 /// A metaprogramming class designed for concrete subtypes of abstract
368 /// types where all subtypes share equivalently-structured source
369 /// information. See the note on ConcreteTypeLoc.
370 template <class Base, class Derived, class TypeClass>
371 class InheritingConcreteTypeLoc : public Base {
373 static bool classofType(const Type *Ty) {
374 return TypeClass::classof(Ty);
377 static bool classof(const TypeLoc *TL) {
378 return Derived::classofType(TL->getTypePtr());
380 static bool classof(const UnqualTypeLoc *TL) {
381 return Derived::classofType(TL->getTypePtr());
383 static bool classof(const Derived *TL) {
387 const TypeClass *getTypePtr() const {
388 return cast<TypeClass>(Base::getTypePtr());
393 struct TypeSpecLocInfo {
394 SourceLocation NameLoc;
397 /// \brief A reasonable base class for TypeLocs that correspond to
398 /// types that are written as a type-specifier.
399 class TypeSpecTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
404 enum { LocalDataSize = sizeof(TypeSpecLocInfo) };
406 SourceLocation getNameLoc() const {
407 return this->getLocalData()->NameLoc;
409 void setNameLoc(SourceLocation Loc) {
410 this->getLocalData()->NameLoc = Loc;
412 SourceRange getLocalSourceRange() const {
413 return SourceRange(getNameLoc(), getNameLoc());
415 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
419 static bool classof(const TypeLoc *TL);
420 static bool classof(const TypeSpecTypeLoc *TL) { return true; }
424 struct BuiltinLocInfo {
425 SourceLocation BuiltinLoc;
428 /// \brief Wrapper for source info for builtin types.
429 class BuiltinTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
434 enum { LocalDataSize = sizeof(BuiltinLocInfo) };
436 SourceLocation getBuiltinLoc() const {
437 return getLocalData()->BuiltinLoc;
439 void setBuiltinLoc(SourceLocation Loc) {
440 getLocalData()->BuiltinLoc = Loc;
443 SourceLocation getNameLoc() const { return getBuiltinLoc(); }
445 WrittenBuiltinSpecs& getWrittenBuiltinSpecs() {
446 return *(static_cast<WrittenBuiltinSpecs*>(getExtraLocalData()));
448 const WrittenBuiltinSpecs& getWrittenBuiltinSpecs() const {
449 return *(static_cast<WrittenBuiltinSpecs*>(getExtraLocalData()));
452 bool needsExtraLocalData() const {
453 BuiltinType::Kind bk = getTypePtr()->getKind();
454 return (bk >= BuiltinType::UShort && bk <= BuiltinType::UInt128)
455 || (bk >= BuiltinType::Short && bk <= BuiltinType::LongDouble)
456 || bk == BuiltinType::UChar
457 || bk == BuiltinType::SChar;
460 unsigned getExtraLocalDataSize() const {
461 return needsExtraLocalData() ? sizeof(WrittenBuiltinSpecs) : 0;
464 SourceRange getLocalSourceRange() const {
465 return SourceRange(getBuiltinLoc(), getBuiltinLoc());
468 TypeSpecifierSign getWrittenSignSpec() const {
469 if (needsExtraLocalData())
470 return static_cast<TypeSpecifierSign>(getWrittenBuiltinSpecs().Sign);
472 return TSS_unspecified;
474 bool hasWrittenSignSpec() const {
475 return getWrittenSignSpec() != TSS_unspecified;
477 void setWrittenSignSpec(TypeSpecifierSign written) {
478 if (needsExtraLocalData())
479 getWrittenBuiltinSpecs().Sign = written;
482 TypeSpecifierWidth getWrittenWidthSpec() const {
483 if (needsExtraLocalData())
484 return static_cast<TypeSpecifierWidth>(getWrittenBuiltinSpecs().Width);
486 return TSW_unspecified;
488 bool hasWrittenWidthSpec() const {
489 return getWrittenWidthSpec() != TSW_unspecified;
491 void setWrittenWidthSpec(TypeSpecifierWidth written) {
492 if (needsExtraLocalData())
493 getWrittenBuiltinSpecs().Width = written;
496 TypeSpecifierType getWrittenTypeSpec() const;
497 bool hasWrittenTypeSpec() const {
498 return getWrittenTypeSpec() != TST_unspecified;
500 void setWrittenTypeSpec(TypeSpecifierType written) {
501 if (needsExtraLocalData())
502 getWrittenBuiltinSpecs().Type = written;
505 bool hasModeAttr() const {
506 if (needsExtraLocalData())
507 return getWrittenBuiltinSpecs().ModeAttr;
511 void setModeAttr(bool written) {
512 if (needsExtraLocalData())
513 getWrittenBuiltinSpecs().ModeAttr = written;
516 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
518 if (needsExtraLocalData()) {
519 WrittenBuiltinSpecs &wbs = getWrittenBuiltinSpecs();
520 wbs.Sign = TSS_unspecified;
521 wbs.Width = TSW_unspecified;
522 wbs.Type = TST_unspecified;
523 wbs.ModeAttr = false;
529 /// \brief Wrapper for source info for typedefs.
530 class TypedefTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
534 TypedefNameDecl *getTypedefNameDecl() const {
535 return getTypePtr()->getDecl();
539 /// \brief Wrapper for source info for injected class names of class
541 class InjectedClassNameTypeLoc :
542 public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
543 InjectedClassNameTypeLoc,
544 InjectedClassNameType> {
546 CXXRecordDecl *getDecl() const {
547 return getTypePtr()->getDecl();
551 /// \brief Wrapper for source info for unresolved typename using decls.
552 class UnresolvedUsingTypeLoc :
553 public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
554 UnresolvedUsingTypeLoc,
555 UnresolvedUsingType> {
557 UnresolvedUsingTypenameDecl *getDecl() const {
558 return getTypePtr()->getDecl();
562 /// \brief Wrapper for source info for tag types. Note that this only
563 /// records source info for the name itself; a type written 'struct foo'
564 /// should be represented as an ElaboratedTypeLoc. We currently
565 /// only do that when C++ is enabled because of the expense of
566 /// creating an ElaboratedType node for so many type references in C.
567 class TagTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
571 TagDecl *getDecl() const { return getTypePtr()->getDecl(); }
573 /// \brief True if the tag was defined in this type specifier.
574 bool isDefinition() const {
575 TagDecl *D = getDecl();
576 return D->isCompleteDefinition() &&
577 (D->getIdentifier() == 0 || D->getLocation() == getNameLoc());
581 /// \brief Wrapper for source info for record types.
582 class RecordTypeLoc : public InheritingConcreteTypeLoc<TagTypeLoc,
586 RecordDecl *getDecl() const { return getTypePtr()->getDecl(); }
589 /// \brief Wrapper for source info for enum types.
590 class EnumTypeLoc : public InheritingConcreteTypeLoc<TagTypeLoc,
594 EnumDecl *getDecl() const { return getTypePtr()->getDecl(); }
597 /// \brief Wrapper for template type parameters.
598 class TemplateTypeParmTypeLoc :
599 public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
600 TemplateTypeParmTypeLoc,
601 TemplateTypeParmType> {
603 TemplateTypeParmDecl *getDecl() const { return getTypePtr()->getDecl(); }
606 /// \brief Wrapper for substituted template type parameters.
607 class SubstTemplateTypeParmTypeLoc :
608 public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
609 SubstTemplateTypeParmTypeLoc,
610 SubstTemplateTypeParmType> {
613 /// \brief Wrapper for substituted template type parameters.
614 class SubstTemplateTypeParmPackTypeLoc :
615 public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
616 SubstTemplateTypeParmPackTypeLoc,
617 SubstTemplateTypeParmPackType> {
620 struct AttributedLocInfo {
624 /// A raw SourceLocation.
625 unsigned EnumOperandLoc;
628 SourceRange OperandParens;
630 SourceLocation AttrLoc;
633 /// \brief Type source information for an attributed type.
634 class AttributedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
639 AttributedType::Kind getAttrKind() const {
640 return getTypePtr()->getAttrKind();
643 bool hasAttrExprOperand() const {
644 return (getAttrKind() >= AttributedType::FirstExprOperandKind &&
645 getAttrKind() <= AttributedType::LastExprOperandKind);
648 bool hasAttrEnumOperand() const {
649 return (getAttrKind() >= AttributedType::FirstEnumOperandKind &&
650 getAttrKind() <= AttributedType::LastEnumOperandKind);
653 bool hasAttrOperand() const {
654 return hasAttrExprOperand() || hasAttrEnumOperand();
657 /// The modified type, which is generally canonically different from
658 /// the attribute type.
659 /// int main(int, char**) __attribute__((noreturn))
660 /// ~~~ ~~~~~~~~~~~~~
661 TypeLoc getModifiedLoc() const {
662 return getInnerTypeLoc();
665 /// The location of the attribute name, i.e.
666 /// __attribute__((regparm(1000)))
668 SourceLocation getAttrNameLoc() const {
669 return getLocalData()->AttrLoc;
671 void setAttrNameLoc(SourceLocation loc) {
672 getLocalData()->AttrLoc = loc;
675 /// The attribute's expression operand, if it has one.
676 /// void *cur_thread __attribute__((address_space(21)))
678 Expr *getAttrExprOperand() const {
679 assert(hasAttrExprOperand());
680 return getLocalData()->ExprOperand;
682 void setAttrExprOperand(Expr *e) {
683 assert(hasAttrExprOperand());
684 getLocalData()->ExprOperand = e;
687 /// The location of the attribute's enumerated operand, if it has one.
688 /// void * __attribute__((objc_gc(weak)))
690 SourceLocation getAttrEnumOperandLoc() const {
691 assert(hasAttrEnumOperand());
692 return SourceLocation::getFromRawEncoding(getLocalData()->EnumOperandLoc);
694 void setAttrEnumOperandLoc(SourceLocation loc) {
695 assert(hasAttrEnumOperand());
696 getLocalData()->EnumOperandLoc = loc.getRawEncoding();
699 /// The location of the parentheses around the operand, if there is
701 /// void * __attribute__((objc_gc(weak)))
703 SourceRange getAttrOperandParensRange() const {
704 assert(hasAttrOperand());
705 return getLocalData()->OperandParens;
707 void setAttrOperandParensRange(SourceRange range) {
708 assert(hasAttrOperand());
709 getLocalData()->OperandParens = range;
712 SourceRange getLocalSourceRange() const {
713 // Note that this does *not* include the range of the attribute
715 // __attribute__((foo(bar)))
716 // ^~~~~~~~~~~~~~~ ~~
720 // That enclosure doesn't necessarily belong to a single attribute
722 SourceRange range(getAttrNameLoc());
723 if (hasAttrOperand())
724 range.setEnd(getAttrOperandParensRange().getEnd());
728 void initializeLocal(ASTContext &Context, SourceLocation loc) {
730 if (hasAttrExprOperand()) {
731 setAttrOperandParensRange(SourceRange(loc));
732 setAttrExprOperand(0);
733 } else if (hasAttrEnumOperand()) {
734 setAttrOperandParensRange(SourceRange(loc));
735 setAttrEnumOperandLoc(loc);
739 QualType getInnerType() const {
740 return getTypePtr()->getModifiedType();
745 struct ObjCProtocolListLocInfo {
746 SourceLocation LAngleLoc;
747 SourceLocation RAngleLoc;
748 bool HasBaseTypeAsWritten;
751 // A helper class for defining ObjC TypeLocs that can qualified with
754 // TypeClass basically has to be either ObjCInterfaceType or
755 // ObjCObjectPointerType.
756 class ObjCObjectTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
759 ObjCProtocolListLocInfo> {
760 // SourceLocations are stored after Info, one for each Protocol.
761 SourceLocation *getProtocolLocArray() const {
762 return (SourceLocation*) this->getExtraLocalData();
766 SourceLocation getLAngleLoc() const {
767 return this->getLocalData()->LAngleLoc;
769 void setLAngleLoc(SourceLocation Loc) {
770 this->getLocalData()->LAngleLoc = Loc;
773 SourceLocation getRAngleLoc() const {
774 return this->getLocalData()->RAngleLoc;
776 void setRAngleLoc(SourceLocation Loc) {
777 this->getLocalData()->RAngleLoc = Loc;
780 unsigned getNumProtocols() const {
781 return this->getTypePtr()->getNumProtocols();
784 SourceLocation getProtocolLoc(unsigned i) const {
785 assert(i < getNumProtocols() && "Index is out of bounds!");
786 return getProtocolLocArray()[i];
788 void setProtocolLoc(unsigned i, SourceLocation Loc) {
789 assert(i < getNumProtocols() && "Index is out of bounds!");
790 getProtocolLocArray()[i] = Loc;
793 ObjCProtocolDecl *getProtocol(unsigned i) const {
794 assert(i < getNumProtocols() && "Index is out of bounds!");
795 return *(this->getTypePtr()->qual_begin() + i);
798 bool hasBaseTypeAsWritten() const {
799 return getLocalData()->HasBaseTypeAsWritten;
802 void setHasBaseTypeAsWritten(bool HasBaseType) {
803 getLocalData()->HasBaseTypeAsWritten = HasBaseType;
806 TypeLoc getBaseLoc() const {
807 return getInnerTypeLoc();
810 SourceRange getLocalSourceRange() const {
811 return SourceRange(getLAngleLoc(), getRAngleLoc());
814 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
815 setHasBaseTypeAsWritten(true);
818 for (unsigned i = 0, e = getNumProtocols(); i != e; ++i)
819 setProtocolLoc(i, Loc);
822 unsigned getExtraLocalDataSize() const {
823 return this->getNumProtocols() * sizeof(SourceLocation);
826 QualType getInnerType() const {
827 return getTypePtr()->getBaseType();
832 struct ObjCInterfaceLocInfo {
833 SourceLocation NameLoc;
836 /// \brief Wrapper for source info for ObjC interfaces.
837 class ObjCInterfaceTypeLoc : public ConcreteTypeLoc<ObjCObjectTypeLoc,
838 ObjCInterfaceTypeLoc,
840 ObjCInterfaceLocInfo> {
842 ObjCInterfaceDecl *getIFaceDecl() const {
843 return getTypePtr()->getDecl();
846 SourceLocation getNameLoc() const {
847 return getLocalData()->NameLoc;
850 void setNameLoc(SourceLocation Loc) {
851 getLocalData()->NameLoc = Loc;
854 SourceRange getLocalSourceRange() const {
855 return SourceRange(getNameLoc());
858 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
863 struct ParenLocInfo {
864 SourceLocation LParenLoc;
865 SourceLocation RParenLoc;
869 : public ConcreteTypeLoc<UnqualTypeLoc, ParenTypeLoc, ParenType,
872 SourceLocation getLParenLoc() const {
873 return this->getLocalData()->LParenLoc;
875 SourceLocation getRParenLoc() const {
876 return this->getLocalData()->RParenLoc;
878 void setLParenLoc(SourceLocation Loc) {
879 this->getLocalData()->LParenLoc = Loc;
881 void setRParenLoc(SourceLocation Loc) {
882 this->getLocalData()->RParenLoc = Loc;
885 SourceRange getLocalSourceRange() const {
886 return SourceRange(getLParenLoc(), getRParenLoc());
889 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
894 TypeLoc getInnerLoc() const {
895 return getInnerTypeLoc();
898 QualType getInnerType() const {
899 return this->getTypePtr()->getInnerType();
904 struct PointerLikeLocInfo {
905 SourceLocation StarLoc;
909 template <class Derived, class TypeClass, class LocalData = PointerLikeLocInfo>
910 class PointerLikeTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, Derived,
911 TypeClass, LocalData> {
913 SourceLocation getSigilLoc() const {
914 return this->getLocalData()->StarLoc;
916 void setSigilLoc(SourceLocation Loc) {
917 this->getLocalData()->StarLoc = Loc;
920 TypeLoc getPointeeLoc() const {
921 return this->getInnerTypeLoc();
924 SourceRange getLocalSourceRange() const {
925 return SourceRange(getSigilLoc(), getSigilLoc());
928 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
932 QualType getInnerType() const {
933 return this->getTypePtr()->getPointeeType();
938 /// \brief Wrapper for source info for pointers.
939 class PointerTypeLoc : public PointerLikeTypeLoc<PointerTypeLoc,
942 SourceLocation getStarLoc() const {
943 return getSigilLoc();
945 void setStarLoc(SourceLocation Loc) {
951 /// \brief Wrapper for source info for block pointers.
952 class BlockPointerTypeLoc : public PointerLikeTypeLoc<BlockPointerTypeLoc,
955 SourceLocation getCaretLoc() const {
956 return getSigilLoc();
958 void setCaretLoc(SourceLocation Loc) {
963 struct MemberPointerLocInfo : public PointerLikeLocInfo {
964 TypeSourceInfo *ClassTInfo;
967 /// \brief Wrapper for source info for member pointers.
968 class MemberPointerTypeLoc : public PointerLikeTypeLoc<MemberPointerTypeLoc,
970 MemberPointerLocInfo> {
972 SourceLocation getStarLoc() const {
973 return getSigilLoc();
975 void setStarLoc(SourceLocation Loc) {
979 const Type *getClass() const {
980 return getTypePtr()->getClass();
982 TypeSourceInfo *getClassTInfo() const {
983 return getLocalData()->ClassTInfo;
985 void setClassTInfo(TypeSourceInfo* TI) {
986 getLocalData()->ClassTInfo = TI;
989 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
994 SourceRange getLocalSourceRange() const {
995 if (TypeSourceInfo *TI = getClassTInfo())
996 return SourceRange(TI->getTypeLoc().getBeginLoc(), getStarLoc());
998 return SourceRange(getStarLoc());
1002 /// Wraps an ObjCPointerType with source location information.
1003 class ObjCObjectPointerTypeLoc :
1004 public PointerLikeTypeLoc<ObjCObjectPointerTypeLoc,
1005 ObjCObjectPointerType> {
1007 SourceLocation getStarLoc() const {
1008 return getSigilLoc();
1011 void setStarLoc(SourceLocation Loc) {
1017 class ReferenceTypeLoc : public PointerLikeTypeLoc<ReferenceTypeLoc,
1020 QualType getInnerType() const {
1021 return getTypePtr()->getPointeeTypeAsWritten();
1025 class LValueReferenceTypeLoc :
1026 public InheritingConcreteTypeLoc<ReferenceTypeLoc,
1027 LValueReferenceTypeLoc,
1028 LValueReferenceType> {
1030 SourceLocation getAmpLoc() const {
1031 return getSigilLoc();
1033 void setAmpLoc(SourceLocation Loc) {
1038 class RValueReferenceTypeLoc :
1039 public InheritingConcreteTypeLoc<ReferenceTypeLoc,
1040 RValueReferenceTypeLoc,
1041 RValueReferenceType> {
1043 SourceLocation getAmpAmpLoc() const {
1044 return getSigilLoc();
1046 void setAmpAmpLoc(SourceLocation Loc) {
1052 struct FunctionLocInfo {
1053 SourceLocation LocalRangeBegin;
1054 SourceLocation LocalRangeEnd;
1055 bool TrailingReturn;
1058 /// \brief Wrapper for source info for functions.
1059 class FunctionTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
1064 SourceLocation getLocalRangeBegin() const {
1065 return getLocalData()->LocalRangeBegin;
1067 void setLocalRangeBegin(SourceLocation L) {
1068 getLocalData()->LocalRangeBegin = L;
1071 SourceLocation getLocalRangeEnd() const {
1072 return getLocalData()->LocalRangeEnd;
1074 void setLocalRangeEnd(SourceLocation L) {
1075 getLocalData()->LocalRangeEnd = L;
1078 bool getTrailingReturn() const {
1079 return getLocalData()->TrailingReturn;
1081 void setTrailingReturn(bool Trailing) {
1082 getLocalData()->TrailingReturn = Trailing;
1085 ArrayRef<ParmVarDecl *> getParams() const {
1086 return ArrayRef<ParmVarDecl *>(getParmArray(), getNumArgs());
1089 // ParmVarDecls* are stored after Info, one for each argument.
1090 ParmVarDecl **getParmArray() const {
1091 return (ParmVarDecl**) getExtraLocalData();
1094 unsigned getNumArgs() const {
1095 if (isa<FunctionNoProtoType>(getTypePtr()))
1097 return cast<FunctionProtoType>(getTypePtr())->getNumArgs();
1099 ParmVarDecl *getArg(unsigned i) const { return getParmArray()[i]; }
1100 void setArg(unsigned i, ParmVarDecl *VD) { getParmArray()[i] = VD; }
1102 TypeLoc getResultLoc() const {
1103 return getInnerTypeLoc();
1106 SourceRange getLocalSourceRange() const {
1107 return SourceRange(getLocalRangeBegin(), getLocalRangeEnd());
1110 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1111 setLocalRangeBegin(Loc);
1112 setLocalRangeEnd(Loc);
1113 setTrailingReturn(false);
1114 for (unsigned i = 0, e = getNumArgs(); i != e; ++i)
1118 /// \brief Returns the size of the type source info data block that is
1119 /// specific to this type.
1120 unsigned getExtraLocalDataSize() const {
1121 return getNumArgs() * sizeof(ParmVarDecl*);
1124 QualType getInnerType() const { return getTypePtr()->getResultType(); }
1127 class FunctionProtoTypeLoc :
1128 public InheritingConcreteTypeLoc<FunctionTypeLoc,
1129 FunctionProtoTypeLoc,
1130 FunctionProtoType> {
1133 class FunctionNoProtoTypeLoc :
1134 public InheritingConcreteTypeLoc<FunctionTypeLoc,
1135 FunctionNoProtoTypeLoc,
1136 FunctionNoProtoType> {
1140 struct ArrayLocInfo {
1141 SourceLocation LBracketLoc, RBracketLoc;
1145 /// \brief Wrapper for source info for arrays.
1146 class ArrayTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
1151 SourceLocation getLBracketLoc() const {
1152 return getLocalData()->LBracketLoc;
1154 void setLBracketLoc(SourceLocation Loc) {
1155 getLocalData()->LBracketLoc = Loc;
1158 SourceLocation getRBracketLoc() const {
1159 return getLocalData()->RBracketLoc;
1161 void setRBracketLoc(SourceLocation Loc) {
1162 getLocalData()->RBracketLoc = Loc;
1165 SourceRange getBracketsRange() const {
1166 return SourceRange(getLBracketLoc(), getRBracketLoc());
1169 Expr *getSizeExpr() const {
1170 return getLocalData()->Size;
1172 void setSizeExpr(Expr *Size) {
1173 getLocalData()->Size = Size;
1176 TypeLoc getElementLoc() const {
1177 return getInnerTypeLoc();
1180 SourceRange getLocalSourceRange() const {
1181 return SourceRange(getLBracketLoc(), getRBracketLoc());
1184 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1185 setLBracketLoc(Loc);
1186 setRBracketLoc(Loc);
1190 QualType getInnerType() const { return getTypePtr()->getElementType(); }
1193 class ConstantArrayTypeLoc :
1194 public InheritingConcreteTypeLoc<ArrayTypeLoc,
1195 ConstantArrayTypeLoc,
1196 ConstantArrayType> {
1199 class IncompleteArrayTypeLoc :
1200 public InheritingConcreteTypeLoc<ArrayTypeLoc,
1201 IncompleteArrayTypeLoc,
1202 IncompleteArrayType> {
1205 class DependentSizedArrayTypeLoc :
1206 public InheritingConcreteTypeLoc<ArrayTypeLoc,
1207 DependentSizedArrayTypeLoc,
1208 DependentSizedArrayType> {
1212 class VariableArrayTypeLoc :
1213 public InheritingConcreteTypeLoc<ArrayTypeLoc,
1214 VariableArrayTypeLoc,
1215 VariableArrayType> {
1219 // Location information for a TemplateName. Rudimentary for now.
1220 struct TemplateNameLocInfo {
1221 SourceLocation NameLoc;
1224 struct TemplateSpecializationLocInfo : TemplateNameLocInfo {
1225 SourceLocation TemplateKWLoc;
1226 SourceLocation LAngleLoc;
1227 SourceLocation RAngleLoc;
1230 class TemplateSpecializationTypeLoc :
1231 public ConcreteTypeLoc<UnqualTypeLoc,
1232 TemplateSpecializationTypeLoc,
1233 TemplateSpecializationType,
1234 TemplateSpecializationLocInfo> {
1236 SourceLocation getTemplateKeywordLoc() const {
1237 return getLocalData()->TemplateKWLoc;
1239 void setTemplateKeywordLoc(SourceLocation Loc) {
1240 getLocalData()->TemplateKWLoc = Loc;
1243 SourceLocation getLAngleLoc() const {
1244 return getLocalData()->LAngleLoc;
1246 void setLAngleLoc(SourceLocation Loc) {
1247 getLocalData()->LAngleLoc = Loc;
1250 SourceLocation getRAngleLoc() const {
1251 return getLocalData()->RAngleLoc;
1253 void setRAngleLoc(SourceLocation Loc) {
1254 getLocalData()->RAngleLoc = Loc;
1257 unsigned getNumArgs() const {
1258 return getTypePtr()->getNumArgs();
1260 void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) {
1261 getArgInfos()[i] = AI;
1263 TemplateArgumentLocInfo getArgLocInfo(unsigned i) const {
1264 return getArgInfos()[i];
1267 TemplateArgumentLoc getArgLoc(unsigned i) const {
1268 return TemplateArgumentLoc(getTypePtr()->getArg(i), getArgLocInfo(i));
1271 SourceLocation getTemplateNameLoc() const {
1272 return getLocalData()->NameLoc;
1274 void setTemplateNameLoc(SourceLocation Loc) {
1275 getLocalData()->NameLoc = Loc;
1278 /// \brief - Copy the location information from the given info.
1279 void copy(TemplateSpecializationTypeLoc Loc) {
1280 unsigned size = getFullDataSize();
1281 assert(size == Loc.getFullDataSize());
1283 // We're potentially copying Expr references here. We don't
1284 // bother retaining them because TypeSourceInfos live forever, so
1285 // as long as the Expr was retained when originally written into
1286 // the TypeLoc, we're okay.
1287 memcpy(Data, Loc.Data, size);
1290 SourceRange getLocalSourceRange() const {
1291 if (getTemplateKeywordLoc().isValid())
1292 return SourceRange(getTemplateKeywordLoc(), getRAngleLoc());
1294 return SourceRange(getTemplateNameLoc(), getRAngleLoc());
1297 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1298 setTemplateKeywordLoc(Loc);
1299 setTemplateNameLoc(Loc);
1302 initializeArgLocs(Context, getNumArgs(), getTypePtr()->getArgs(),
1303 getArgInfos(), Loc);
1306 static void initializeArgLocs(ASTContext &Context, unsigned NumArgs,
1307 const TemplateArgument *Args,
1308 TemplateArgumentLocInfo *ArgInfos,
1309 SourceLocation Loc);
1311 unsigned getExtraLocalDataSize() const {
1312 return getNumArgs() * sizeof(TemplateArgumentLocInfo);
1316 TemplateArgumentLocInfo *getArgInfos() const {
1317 return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData());
1321 //===----------------------------------------------------------------------===//
1323 // All of these need proper implementations.
1325 //===----------------------------------------------------------------------===//
1327 // FIXME: size expression and attribute locations (or keyword if we
1328 // ever fully support altivec syntax).
1329 class VectorTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
1334 // FIXME: size expression and attribute locations.
1335 class ExtVectorTypeLoc : public InheritingConcreteTypeLoc<VectorTypeLoc,
1340 // FIXME: attribute locations.
1341 // For some reason, this isn't a subtype of VectorType.
1342 class DependentSizedExtVectorTypeLoc :
1343 public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
1344 DependentSizedExtVectorTypeLoc,
1345 DependentSizedExtVectorType> {
1348 // FIXME: location of the '_Complex' keyword.
1349 class ComplexTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
1354 struct TypeofLocInfo {
1355 SourceLocation TypeofLoc;
1356 SourceLocation LParenLoc;
1357 SourceLocation RParenLoc;
1360 struct TypeOfExprTypeLocInfo : public TypeofLocInfo {
1363 struct TypeOfTypeLocInfo : public TypeofLocInfo {
1364 TypeSourceInfo* UnderlyingTInfo;
1367 template <class Derived, class TypeClass, class LocalData = TypeofLocInfo>
1368 class TypeofLikeTypeLoc
1369 : public ConcreteTypeLoc<UnqualTypeLoc, Derived, TypeClass, LocalData> {
1371 SourceLocation getTypeofLoc() const {
1372 return this->getLocalData()->TypeofLoc;
1374 void setTypeofLoc(SourceLocation Loc) {
1375 this->getLocalData()->TypeofLoc = Loc;
1378 SourceLocation getLParenLoc() const {
1379 return this->getLocalData()->LParenLoc;
1381 void setLParenLoc(SourceLocation Loc) {
1382 this->getLocalData()->LParenLoc = Loc;
1385 SourceLocation getRParenLoc() const {
1386 return this->getLocalData()->RParenLoc;
1388 void setRParenLoc(SourceLocation Loc) {
1389 this->getLocalData()->RParenLoc = Loc;
1392 SourceRange getParensRange() const {
1393 return SourceRange(getLParenLoc(), getRParenLoc());
1395 void setParensRange(SourceRange range) {
1396 setLParenLoc(range.getBegin());
1397 setRParenLoc(range.getEnd());
1400 SourceRange getLocalSourceRange() const {
1401 return SourceRange(getTypeofLoc(), getRParenLoc());
1404 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1411 class TypeOfExprTypeLoc : public TypeofLikeTypeLoc<TypeOfExprTypeLoc,
1413 TypeOfExprTypeLocInfo> {
1415 Expr* getUnderlyingExpr() const {
1416 return getTypePtr()->getUnderlyingExpr();
1418 // Reimplemented to account for GNU/C++ extension
1419 // typeof unary-expression
1420 // where there are no parentheses.
1421 SourceRange getLocalSourceRange() const;
1425 : public TypeofLikeTypeLoc<TypeOfTypeLoc, TypeOfType, TypeOfTypeLocInfo> {
1427 QualType getUnderlyingType() const {
1428 return this->getTypePtr()->getUnderlyingType();
1430 TypeSourceInfo* getUnderlyingTInfo() const {
1431 return this->getLocalData()->UnderlyingTInfo;
1433 void setUnderlyingTInfo(TypeSourceInfo* TI) const {
1434 this->getLocalData()->UnderlyingTInfo = TI;
1438 // FIXME: location of the 'decltype' and parens.
1439 class DecltypeTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
1443 Expr *getUnderlyingExpr() const { return getTypePtr()->getUnderlyingExpr(); }
1446 struct UnaryTransformTypeLocInfo {
1447 // FIXME: While there's only one unary transform right now, future ones may
1448 // need different representations
1449 SourceLocation KWLoc, LParenLoc, RParenLoc;
1450 TypeSourceInfo *UnderlyingTInfo;
1453 class UnaryTransformTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
1454 UnaryTransformTypeLoc,
1456 UnaryTransformTypeLocInfo> {
1458 SourceLocation getKWLoc() const { return getLocalData()->KWLoc; }
1459 void setKWLoc(SourceLocation Loc) { getLocalData()->KWLoc = Loc; }
1461 SourceLocation getLParenLoc() const { return getLocalData()->LParenLoc; }
1462 void setLParenLoc(SourceLocation Loc) { getLocalData()->LParenLoc = Loc; }
1464 SourceLocation getRParenLoc() const { return getLocalData()->RParenLoc; }
1465 void setRParenLoc(SourceLocation Loc) { getLocalData()->RParenLoc = Loc; }
1467 TypeSourceInfo* getUnderlyingTInfo() const {
1468 return getLocalData()->UnderlyingTInfo;
1470 void setUnderlyingTInfo(TypeSourceInfo *TInfo) {
1471 getLocalData()->UnderlyingTInfo = TInfo;
1474 SourceRange getLocalSourceRange() const {
1475 return SourceRange(getKWLoc(), getRParenLoc());
1478 SourceRange getParensRange() const {
1479 return SourceRange(getLParenLoc(), getRParenLoc());
1481 void setParensRange(SourceRange Range) {
1482 setLParenLoc(Range.getBegin());
1483 setRParenLoc(Range.getEnd());
1486 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1493 class AutoTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
1498 struct ElaboratedLocInfo {
1499 SourceLocation ElaboratedKWLoc;
1500 /// \brief Data associated with the nested-name-specifier location.
1501 void *QualifierData;
1504 class ElaboratedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
1507 ElaboratedLocInfo> {
1509 SourceLocation getElaboratedKeywordLoc() const {
1510 return this->getLocalData()->ElaboratedKWLoc;
1512 void setElaboratedKeywordLoc(SourceLocation Loc) {
1513 this->getLocalData()->ElaboratedKWLoc = Loc;
1516 NestedNameSpecifierLoc getQualifierLoc() const {
1517 return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
1518 getLocalData()->QualifierData);
1521 void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
1522 assert(QualifierLoc.getNestedNameSpecifier()
1523 == getTypePtr()->getQualifier() &&
1524 "Inconsistent nested-name-specifier pointer");
1525 getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
1528 SourceRange getLocalSourceRange() const {
1529 if (getElaboratedKeywordLoc().isValid())
1530 if (getQualifierLoc())
1531 return SourceRange(getElaboratedKeywordLoc(),
1532 getQualifierLoc().getEndLoc());
1534 return SourceRange(getElaboratedKeywordLoc());
1536 return getQualifierLoc().getSourceRange();
1539 void initializeLocal(ASTContext &Context, SourceLocation Loc);
1541 TypeLoc getNamedTypeLoc() const {
1542 return getInnerTypeLoc();
1545 QualType getInnerType() const {
1546 return getTypePtr()->getNamedType();
1549 void copy(ElaboratedTypeLoc Loc) {
1550 unsigned size = getFullDataSize();
1551 assert(size == Loc.getFullDataSize());
1552 memcpy(Data, Loc.Data, size);
1556 // This is exactly the structure of an ElaboratedTypeLoc whose inner
1557 // type is some sort of TypeDeclTypeLoc.
1558 struct DependentNameLocInfo : ElaboratedLocInfo {
1559 SourceLocation NameLoc;
1562 class DependentNameTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
1563 DependentNameTypeLoc,
1565 DependentNameLocInfo> {
1567 SourceLocation getElaboratedKeywordLoc() const {
1568 return this->getLocalData()->ElaboratedKWLoc;
1570 void setElaboratedKeywordLoc(SourceLocation Loc) {
1571 this->getLocalData()->ElaboratedKWLoc = Loc;
1574 NestedNameSpecifierLoc getQualifierLoc() const {
1575 return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
1576 getLocalData()->QualifierData);
1579 void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
1580 assert(QualifierLoc.getNestedNameSpecifier()
1581 == getTypePtr()->getQualifier() &&
1582 "Inconsistent nested-name-specifier pointer");
1583 getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
1586 SourceLocation getNameLoc() const {
1587 return this->getLocalData()->NameLoc;
1589 void setNameLoc(SourceLocation Loc) {
1590 this->getLocalData()->NameLoc = Loc;
1593 SourceRange getLocalSourceRange() const {
1594 if (getElaboratedKeywordLoc().isValid())
1595 return SourceRange(getElaboratedKeywordLoc(), getNameLoc());
1597 return SourceRange(getQualifierLoc().getBeginLoc(), getNameLoc());
1600 void copy(DependentNameTypeLoc Loc) {
1601 unsigned size = getFullDataSize();
1602 assert(size == Loc.getFullDataSize());
1603 memcpy(Data, Loc.Data, size);
1606 void initializeLocal(ASTContext &Context, SourceLocation Loc);
1609 struct DependentTemplateSpecializationLocInfo : DependentNameLocInfo {
1610 SourceLocation TemplateKWLoc;
1611 SourceLocation LAngleLoc;
1612 SourceLocation RAngleLoc;
1613 // followed by a TemplateArgumentLocInfo[]
1616 class DependentTemplateSpecializationTypeLoc :
1617 public ConcreteTypeLoc<UnqualTypeLoc,
1618 DependentTemplateSpecializationTypeLoc,
1619 DependentTemplateSpecializationType,
1620 DependentTemplateSpecializationLocInfo> {
1622 SourceLocation getElaboratedKeywordLoc() const {
1623 return this->getLocalData()->ElaboratedKWLoc;
1625 void setElaboratedKeywordLoc(SourceLocation Loc) {
1626 this->getLocalData()->ElaboratedKWLoc = Loc;
1629 NestedNameSpecifierLoc getQualifierLoc() const {
1630 if (!getLocalData()->QualifierData)
1631 return NestedNameSpecifierLoc();
1633 return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
1634 getLocalData()->QualifierData);
1637 void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
1638 if (!QualifierLoc) {
1639 // Even if we have a nested-name-specifier in the dependent
1640 // template specialization type, we won't record the nested-name-specifier
1641 // location information when this type-source location information is
1642 // part of a nested-name-specifier.
1643 getLocalData()->QualifierData = 0;
1647 assert(QualifierLoc.getNestedNameSpecifier()
1648 == getTypePtr()->getQualifier() &&
1649 "Inconsistent nested-name-specifier pointer");
1650 getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
1653 SourceLocation getTemplateKeywordLoc() const {
1654 return getLocalData()->TemplateKWLoc;
1656 void setTemplateKeywordLoc(SourceLocation Loc) {
1657 getLocalData()->TemplateKWLoc = Loc;
1660 SourceLocation getTemplateNameLoc() const {
1661 return this->getLocalData()->NameLoc;
1663 void setTemplateNameLoc(SourceLocation Loc) {
1664 this->getLocalData()->NameLoc = Loc;
1667 SourceLocation getLAngleLoc() const {
1668 return this->getLocalData()->LAngleLoc;
1670 void setLAngleLoc(SourceLocation Loc) {
1671 this->getLocalData()->LAngleLoc = Loc;
1674 SourceLocation getRAngleLoc() const {
1675 return this->getLocalData()->RAngleLoc;
1677 void setRAngleLoc(SourceLocation Loc) {
1678 this->getLocalData()->RAngleLoc = Loc;
1681 unsigned getNumArgs() const {
1682 return getTypePtr()->getNumArgs();
1685 void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) {
1686 getArgInfos()[i] = AI;
1688 TemplateArgumentLocInfo getArgLocInfo(unsigned i) const {
1689 return getArgInfos()[i];
1692 TemplateArgumentLoc getArgLoc(unsigned i) const {
1693 return TemplateArgumentLoc(getTypePtr()->getArg(i), getArgLocInfo(i));
1696 SourceRange getLocalSourceRange() const {
1697 if (getElaboratedKeywordLoc().isValid())
1698 return SourceRange(getElaboratedKeywordLoc(), getRAngleLoc());
1699 else if (getQualifierLoc())
1700 return SourceRange(getQualifierLoc().getBeginLoc(), getRAngleLoc());
1701 else if (getTemplateKeywordLoc().isValid())
1702 return SourceRange(getTemplateKeywordLoc(), getRAngleLoc());
1704 return SourceRange(getTemplateNameLoc(), getRAngleLoc());
1707 void copy(DependentTemplateSpecializationTypeLoc Loc) {
1708 unsigned size = getFullDataSize();
1709 assert(size == Loc.getFullDataSize());
1710 memcpy(Data, Loc.Data, size);
1713 void initializeLocal(ASTContext &Context, SourceLocation Loc);
1715 unsigned getExtraLocalDataSize() const {
1716 return getNumArgs() * sizeof(TemplateArgumentLocInfo);
1720 TemplateArgumentLocInfo *getArgInfos() const {
1721 return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData());
1726 struct PackExpansionTypeLocInfo {
1727 SourceLocation EllipsisLoc;
1730 class PackExpansionTypeLoc
1731 : public ConcreteTypeLoc<UnqualTypeLoc, PackExpansionTypeLoc,
1732 PackExpansionType, PackExpansionTypeLocInfo> {
1734 SourceLocation getEllipsisLoc() const {
1735 return this->getLocalData()->EllipsisLoc;
1738 void setEllipsisLoc(SourceLocation Loc) {
1739 this->getLocalData()->EllipsisLoc = Loc;
1742 SourceRange getLocalSourceRange() const {
1743 return SourceRange(getEllipsisLoc(), getEllipsisLoc());
1746 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1747 setEllipsisLoc(Loc);
1750 TypeLoc getPatternLoc() const {
1751 return getInnerTypeLoc();
1754 QualType getInnerType() const {
1755 return this->getTypePtr()->getPattern();
1759 struct AtomicTypeLocInfo {
1760 SourceLocation KWLoc, LParenLoc, RParenLoc;
1763 class AtomicTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, AtomicTypeLoc,
1764 AtomicType, AtomicTypeLocInfo> {
1766 TypeLoc getValueLoc() const {
1767 return this->getInnerTypeLoc();
1770 SourceRange getLocalSourceRange() const {
1771 return SourceRange(getKWLoc(), getRParenLoc());
1774 SourceLocation getKWLoc() const {
1775 return this->getLocalData()->KWLoc;
1777 void setKWLoc(SourceLocation Loc) {
1778 this->getLocalData()->KWLoc = Loc;
1781 SourceLocation getLParenLoc() const {
1782 return this->getLocalData()->LParenLoc;
1784 void setLParenLoc(SourceLocation Loc) {
1785 this->getLocalData()->LParenLoc = Loc;
1788 SourceLocation getRParenLoc() const {
1789 return this->getLocalData()->RParenLoc;
1791 void setRParenLoc(SourceLocation Loc) {
1792 this->getLocalData()->RParenLoc = Loc;
1795 SourceRange getParensRange() const {
1796 return SourceRange(getLParenLoc(), getRParenLoc());
1798 void setParensRange(SourceRange Range) {
1799 setLParenLoc(Range.getBegin());
1800 setRParenLoc(Range.getEnd());
1803 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1809 QualType getInnerType() const {
1810 return this->getTypePtr()->getValueType();