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/TemplateBase.h"
25 // Predeclare all the type nodes.
26 #define ABSTRACT_TYPELOC(Class, Base)
27 #define TYPELOC(Class, Base) \
29 #include "clang/AST/TypeLocNodes.def"
31 /// \brief Base wrapper for a particular "section" of type source info.
33 /// A client should use the TypeLoc subclasses through cast/dyn_cast in order to
34 /// get at the actual information.
37 // The correctness of this relies on the property that, for Type *Ty,
38 // QualType(Ty, 0).getAsOpaquePtr() == (void*) Ty
43 /// The kinds of TypeLocs. Equivalent to the Type::TypeClass enum,
44 /// except it also defines a Qualified enum that corresponds to the
45 /// QualifiedLoc class.
47 #define ABSTRACT_TYPE(Class, Base)
48 #define TYPE(Class, Base) \
50 #include "clang/AST/TypeNodes.def"
54 TypeLoc() : Ty(0), Data(0) { }
55 TypeLoc(QualType ty, void *opaqueData)
56 : Ty(ty.getAsOpaquePtr()), Data(opaqueData) { }
57 TypeLoc(Type *ty, void *opaqueData)
58 : Ty(ty), Data(opaqueData) { }
60 TypeLocClass getTypeLocClass() const {
61 if (getType().hasQualifiers()) return Qualified;
62 return (TypeLocClass) getType()->getTypeClass();
65 bool isNull() const { return !Ty; }
66 operator bool() const { return Ty; }
68 /// \brief Returns the size of type source info data block for the given type.
69 static unsigned getFullDataSizeForType(QualType Ty);
71 /// \brief Get the type for which this source info wrapper provides
73 QualType getType() const {
74 return QualType::getFromOpaquePtr(Ty);
77 Type *getTypePtr() const {
78 return QualType::getFromOpaquePtr(Ty).getTypePtr();
81 /// \brief Get the pointer where source information is stored.
82 void *getOpaqueData() const {
86 /// \brief Get the full source range.
87 SourceRange getFullSourceRange() const {
88 SourceLocation End = getSourceRange().getEnd();
91 TypeLoc Next = Cur.getNextTypeLoc();
92 if (Next.isNull()) break;
95 return SourceRange(Cur.getSourceRange().getBegin(), End);
98 /// \brief Get the local source range.
99 SourceRange getSourceRange() const {
100 return getSourceRangeImpl(*this);
103 /// \brief Returns the size of the type source info data block.
104 unsigned getFullDataSize() const {
105 return getFullDataSizeForType(getType());
108 /// \brief Get the next TypeLoc pointed by this TypeLoc, e.g for "int*" the
109 /// TypeLoc is a PointerLoc and next TypeLoc is for "int".
110 TypeLoc getNextTypeLoc() const {
111 return getNextTypeLocImpl(*this);
114 /// \brief Skips past any qualifiers, if this is qualified.
115 UnqualTypeLoc getUnqualifiedLoc() const; // implemented in this header
117 /// \brief Initializes this to state that every location in this
118 /// type is the given location.
120 /// This method exists to provide a simple transition for code that
121 /// relies on location-less types.
122 void initialize(SourceLocation Loc) const {
123 initializeImpl(*this, Loc);
126 friend bool operator==(const TypeLoc &LHS, const TypeLoc &RHS) {
127 return LHS.Ty == RHS.Ty && LHS.Data == RHS.Data;
130 friend bool operator!=(const TypeLoc &LHS, const TypeLoc &RHS) {
131 return !(LHS == RHS);
134 static bool classof(const TypeLoc *TL) { return true; }
137 static void initializeImpl(TypeLoc TL, SourceLocation Loc);
138 static TypeLoc getNextTypeLocImpl(TypeLoc TL);
139 static SourceRange getSourceRangeImpl(TypeLoc TL);
142 /// \brief Wrapper of type source information for a type with
143 /// no direct quqlaifiers.
144 class UnqualTypeLoc : public TypeLoc {
147 UnqualTypeLoc(Type *Ty, void *Data) : TypeLoc(Ty, Data) {}
149 Type *getTypePtr() const {
150 return reinterpret_cast<Type*>(Ty);
153 TypeLocClass getTypeLocClass() const {
154 return (TypeLocClass) getTypePtr()->getTypeClass();
157 static bool classof(const TypeLoc *TL) {
158 return !TL->getType().hasQualifiers();
160 static bool classof(const UnqualTypeLoc *TL) { return true; }
163 /// \brief Wrapper of type source information for a type with
164 /// non-trivial direct qualifiers.
166 /// Currently, we intentionally do not provide source location for
168 class QualifiedTypeLoc : public TypeLoc {
170 SourceRange getSourceRange() const {
171 return SourceRange();
174 UnqualTypeLoc getUnqualifiedLoc() const {
175 return UnqualTypeLoc(getTypePtr(), Data);
178 /// Initializes the local data of this type source info block to
179 /// provide no information.
180 void initializeLocal(SourceLocation Loc) {
184 TypeLoc getNextTypeLoc() const {
185 return getUnqualifiedLoc();
188 /// \brief Returns the size of the type source info data block that is
189 /// specific to this type.
190 unsigned getLocalDataSize() const {
191 // In fact, we don't currently preserve any location information
196 /// \brief Returns the size of the type source info data block.
197 unsigned getFullDataSize() const {
198 return getLocalDataSize() +
199 getFullDataSizeForType(getType().getUnqualifiedType());
202 static bool classof(const TypeLoc *TL) {
203 return TL->getType().hasQualifiers();
205 static bool classof(const QualifiedTypeLoc *TL) { return true; }
208 inline UnqualTypeLoc TypeLoc::getUnqualifiedLoc() const {
209 if (isa<QualifiedTypeLoc>(this))
210 return cast<QualifiedTypeLoc>(this)->getUnqualifiedLoc();
211 return cast<UnqualTypeLoc>(*this);
214 /// A metaprogramming base class for TypeLoc classes which correspond
215 /// to a particular Type subclass. It is accepted for a single
216 /// TypeLoc class to correspond to multiple Type classes.
218 /// \param Base a class from which to derive
219 /// \param Derived the class deriving from this one
220 /// \param TypeClass the concrete Type subclass associated with this
222 /// \param LocalData the structure type of local location data for
225 /// sizeof(LocalData) needs to be a multiple of sizeof(void*) or
226 /// else the world will end.
228 /// TypeLocs with non-constant amounts of local data should override
229 /// getExtraLocalDataSize(); getExtraLocalData() will then point to
230 /// this extra memory.
232 /// TypeLocs with an inner type should define
233 /// QualType getInnerType() const
234 /// and getInnerTypeLoc() will then point to this inner type's
237 /// A word about hierarchies: this template is not designed to be
238 /// derived from multiple times in a hierarchy. It is also not
239 /// designed to be used for classes where subtypes might provide
240 /// different amounts of source information. It should be subclassed
241 /// only at the deepest portion of the hierarchy where all children
242 /// have identical source information; if that's an abstract type,
243 /// then further descendents should inherit from
244 /// InheritingConcreteTypeLoc instead.
245 template <class Base, class Derived, class TypeClass, class LocalData>
246 class ConcreteTypeLoc : public Base {
248 const Derived *asDerived() const {
249 return static_cast<const Derived*>(this);
253 unsigned getLocalDataSize() const {
254 return sizeof(LocalData) + asDerived()->getExtraLocalDataSize();
256 // Give a default implementation that's useful for leaf types.
257 unsigned getFullDataSize() const {
258 return asDerived()->getLocalDataSize() + getInnerTypeSize();
261 static bool classofType(const Type *Ty) {
262 return TypeClass::classof(Ty);
265 TypeLoc getNextTypeLoc() const {
266 return getNextTypeLoc(asDerived()->getInnerType());
269 TypeClass *getTypePtr() const {
270 return cast<TypeClass>(Base::getTypePtr());
274 unsigned getExtraLocalDataSize() const {
278 LocalData *getLocalData() const {
279 return static_cast<LocalData*>(Base::Data);
282 /// Gets a pointer past the Info structure; useful for classes with
283 /// local data that can't be captured in the Info (e.g. because it's
284 /// of variable size).
285 void *getExtraLocalData() const {
286 return getLocalData() + 1;
289 void *getNonLocalData() const {
290 return static_cast<char*>(Base::Data) + asDerived()->getLocalDataSize();
293 struct HasNoInnerType {};
294 HasNoInnerType getInnerType() const { return HasNoInnerType(); }
296 TypeLoc getInnerTypeLoc() const {
297 return TypeLoc(asDerived()->getInnerType(), getNonLocalData());
301 unsigned getInnerTypeSize() const {
302 return getInnerTypeSize(asDerived()->getInnerType());
305 unsigned getInnerTypeSize(HasNoInnerType _) const {
309 unsigned getInnerTypeSize(QualType _) const {
310 return getInnerTypeLoc().getFullDataSize();
313 TypeLoc getNextTypeLoc(HasNoInnerType _) const {
317 TypeLoc getNextTypeLoc(QualType T) const {
318 return TypeLoc(T, getNonLocalData());
322 /// A metaprogramming class designed for concrete subtypes of abstract
323 /// types where all subtypes share equivalently-structured source
324 /// information. See the note on ConcreteTypeLoc.
325 template <class Base, class Derived, class TypeClass>
326 class InheritingConcreteTypeLoc : public Base {
328 static bool classof(const TypeLoc *TL) {
329 return Derived::classofType(TL->getTypePtr());
331 static bool classof(const UnqualTypeLoc *TL) {
332 return Derived::classofType(TL->getTypePtr());
334 static bool classof(const Derived *TL) {
338 TypeClass *getTypePtr() const {
339 return cast<TypeClass>(Base::getTypePtr());
343 struct TypeSpecLocInfo {
344 SourceLocation NameLoc;
347 /// \brief A reasonable base class for TypeLocs that correspond to
348 /// types that are written as a type-specifier.
349 template <class Derived, class TypeClass, class LocalData = TypeSpecLocInfo>
350 class TypeSpecTypeLoc
351 : public ConcreteTypeLoc<UnqualTypeLoc, Derived, TypeClass, LocalData> {
353 SourceLocation getNameLoc() const {
354 return this->getLocalData()->NameLoc;
356 void setNameLoc(SourceLocation Loc) {
357 this->getLocalData()->NameLoc = Loc;
359 SourceRange getSourceRange() const {
360 return SourceRange(getNameLoc(), getNameLoc());
362 void initializeLocal(SourceLocation Loc) {
367 /// \brief Wrapper for source info for typedefs.
368 class TypedefTypeLoc : public TypeSpecTypeLoc<TypedefTypeLoc,TypedefType> {
370 TypedefDecl *getTypedefDecl() const {
371 return getTypePtr()->getDecl();
376 /// \brief Wrapper for source info for builtin types.
377 class BuiltinTypeLoc : public TypeSpecTypeLoc<BuiltinTypeLoc,
381 /// \brief Wrapper for template type parameters.
382 class TemplateTypeParmTypeLoc : public TypeSpecTypeLoc<TemplateTypeParmTypeLoc,
383 TemplateTypeParmType> {
386 /// \brief Wrapper for substituted template type parameters.
387 class SubstTemplateTypeParmTypeLoc :
388 public TypeSpecTypeLoc<SubstTemplateTypeParmTypeLoc,
389 SubstTemplateTypeParmType> {
393 struct ObjCProtocolListLocInfo {
394 SourceLocation LAngleLoc;
395 SourceLocation RAngleLoc;
398 // A helper class for defining ObjC TypeLocs that can qualified with
401 // TypeClass basically has to be either ObjCInterfaceType or
402 // ObjCObjectPointerType.
403 template <class Derived, class TypeClass, class LocalData>
404 class ObjCProtocolListTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
408 // SourceLocations are stored after Info, one for each Protocol.
409 SourceLocation *getProtocolLocArray() const {
410 return (SourceLocation*) this->getExtraLocalData();
414 void initializeLocalBase(SourceLocation Loc) {
417 for (unsigned i = 0, e = getNumProtocols(); i != e; ++i)
418 setProtocolLoc(i, Loc);
422 SourceLocation getLAngleLoc() const {
423 return this->getLocalData()->LAngleLoc;
425 void setLAngleLoc(SourceLocation Loc) {
426 this->getLocalData()->LAngleLoc = Loc;
429 SourceLocation getRAngleLoc() const {
430 return this->getLocalData()->RAngleLoc;
432 void setRAngleLoc(SourceLocation Loc) {
433 this->getLocalData()->RAngleLoc = Loc;
436 unsigned getNumProtocols() const {
437 return this->getTypePtr()->getNumProtocols();
440 SourceLocation getProtocolLoc(unsigned i) const {
441 assert(i < getNumProtocols() && "Index is out of bounds!");
442 return getProtocolLocArray()[i];
444 void setProtocolLoc(unsigned i, SourceLocation Loc) {
445 assert(i < getNumProtocols() && "Index is out of bounds!");
446 getProtocolLocArray()[i] = Loc;
449 ObjCProtocolDecl *getProtocol(unsigned i) const {
450 assert(i < getNumProtocols() && "Index is out of bounds!");
451 return *(this->getTypePtr()->qual_begin() + i);
454 SourceRange getSourceRange() const {
455 return SourceRange(getLAngleLoc(), getRAngleLoc());
458 void initializeLocal(SourceLocation Loc) {
459 initializeLocalBase(Loc);
462 unsigned getExtraLocalDataSize() const {
463 return this->getNumProtocols() * sizeof(SourceLocation);
468 struct ObjCInterfaceLocInfo : ObjCProtocolListLocInfo {
469 SourceLocation NameLoc;
472 /// \brief Wrapper for source info for ObjC interfaces.
473 class ObjCInterfaceTypeLoc :
474 public ObjCProtocolListTypeLoc<ObjCInterfaceTypeLoc,
476 ObjCInterfaceLocInfo> {
478 ObjCInterfaceDecl *getIFaceDecl() const {
479 return getTypePtr()->getDecl();
482 SourceLocation getNameLoc() const {
483 return getLocalData()->NameLoc;
486 void setNameLoc(SourceLocation Loc) {
487 getLocalData()->NameLoc = Loc;
490 SourceRange getSourceRange() const {
491 if (getNumProtocols())
492 return SourceRange(getNameLoc(), getRAngleLoc());
494 return SourceRange(getNameLoc(), getNameLoc());
497 void initializeLocal(SourceLocation Loc) {
498 initializeLocalBase(Loc);
504 struct ObjCObjectPointerLocInfo : ObjCProtocolListLocInfo {
505 SourceLocation StarLoc;
510 /// Wraps an ObjCPointerType with source location information. Note
511 /// that not all ObjCPointerTypes actually have a star location; nor
512 /// are protocol locations necessarily written in the source just
513 /// because they're present on the type.
514 class ObjCObjectPointerTypeLoc :
515 public ObjCProtocolListTypeLoc<ObjCObjectPointerTypeLoc,
516 ObjCObjectPointerType,
517 ObjCObjectPointerLocInfo> {
519 bool hasProtocolsAsWritten() const {
520 return getLocalData()->HasProtocols;
523 void setHasProtocolsAsWritten(bool HasProtocols) {
524 getLocalData()->HasProtocols = HasProtocols;
527 bool hasBaseTypeAsWritten() const {
528 return getLocalData()->HasBaseType;
531 void setHasBaseTypeAsWritten(bool HasBaseType) {
532 getLocalData()->HasBaseType = HasBaseType;
535 SourceLocation getStarLoc() const {
536 return getLocalData()->StarLoc;
539 void setStarLoc(SourceLocation Loc) {
540 getLocalData()->StarLoc = Loc;
543 SourceRange getSourceRange() const {
544 // Being written with protocols is incompatible with being written
546 if (hasProtocolsAsWritten())
547 return SourceRange(getLAngleLoc(), getRAngleLoc());
549 return SourceRange(getStarLoc(), getStarLoc());
552 void initializeLocal(SourceLocation Loc) {
553 initializeLocalBase(Loc);
554 setHasProtocolsAsWritten(false);
555 setHasBaseTypeAsWritten(false);
559 TypeLoc getBaseTypeLoc() const {
560 return getInnerTypeLoc();
563 QualType getInnerType() const {
564 return getTypePtr()->getPointeeType();
569 struct PointerLikeLocInfo {
570 SourceLocation StarLoc;
574 template <class Derived, class TypeClass, class LocalData = PointerLikeLocInfo>
575 class PointerLikeTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, Derived,
576 TypeClass, LocalData> {
578 SourceLocation getSigilLoc() const {
579 return this->getLocalData()->StarLoc;
581 void setSigilLoc(SourceLocation Loc) {
582 this->getLocalData()->StarLoc = Loc;
585 TypeLoc getPointeeLoc() const {
586 return this->getInnerTypeLoc();
589 SourceRange getSourceRange() const {
590 return SourceRange(getSigilLoc(), getSigilLoc());
593 void initializeLocal(SourceLocation Loc) {
597 QualType getInnerType() const {
598 return this->getTypePtr()->getPointeeType();
603 /// \brief Wrapper for source info for pointers.
604 class PointerTypeLoc : public PointerLikeTypeLoc<PointerTypeLoc,
607 SourceLocation getStarLoc() const {
608 return getSigilLoc();
610 void setStarLoc(SourceLocation Loc) {
616 /// \brief Wrapper for source info for block pointers.
617 class BlockPointerTypeLoc : public PointerLikeTypeLoc<BlockPointerTypeLoc,
620 SourceLocation getCaretLoc() const {
621 return getSigilLoc();
623 void setCaretLoc(SourceLocation Loc) {
629 /// \brief Wrapper for source info for member pointers.
630 class MemberPointerTypeLoc : public PointerLikeTypeLoc<MemberPointerTypeLoc,
633 SourceLocation getStarLoc() const {
634 return getSigilLoc();
636 void setStarLoc(SourceLocation Loc) {
642 class ReferenceTypeLoc : public PointerLikeTypeLoc<ReferenceTypeLoc,
645 QualType getInnerType() const {
646 return getTypePtr()->getPointeeTypeAsWritten();
650 class LValueReferenceTypeLoc :
651 public InheritingConcreteTypeLoc<ReferenceTypeLoc,
652 LValueReferenceTypeLoc,
653 LValueReferenceType> {
655 SourceLocation getAmpLoc() const {
656 return getSigilLoc();
658 void setAmpLoc(SourceLocation Loc) {
663 class RValueReferenceTypeLoc :
664 public InheritingConcreteTypeLoc<ReferenceTypeLoc,
665 RValueReferenceTypeLoc,
666 RValueReferenceType> {
668 SourceLocation getAmpAmpLoc() const {
669 return getSigilLoc();
671 void setAmpAmpLoc(SourceLocation Loc) {
677 struct FunctionLocInfo {
678 SourceLocation LParenLoc, RParenLoc;
681 /// \brief Wrapper for source info for functions.
682 class FunctionTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
686 // ParmVarDecls* are stored after Info, one for each argument.
687 ParmVarDecl **getParmArray() const {
688 return (ParmVarDecl**) getExtraLocalData();
692 SourceLocation getLParenLoc() const {
693 return getLocalData()->LParenLoc;
695 void setLParenLoc(SourceLocation Loc) {
696 getLocalData()->LParenLoc = Loc;
699 SourceLocation getRParenLoc() const {
700 return getLocalData()->RParenLoc;
702 void setRParenLoc(SourceLocation Loc) {
703 getLocalData()->RParenLoc = Loc;
706 unsigned getNumArgs() const {
707 if (isa<FunctionNoProtoType>(getTypePtr()))
709 return cast<FunctionProtoType>(getTypePtr())->getNumArgs();
711 ParmVarDecl *getArg(unsigned i) const { return getParmArray()[i]; }
712 void setArg(unsigned i, ParmVarDecl *VD) { getParmArray()[i] = VD; }
714 TypeLoc getArgLoc(unsigned i) const;
716 TypeLoc getResultLoc() const {
717 return getInnerTypeLoc();
720 SourceRange getSourceRange() const {
721 return SourceRange(getLParenLoc(), getRParenLoc());
724 void initializeLocal(SourceLocation Loc) {
727 for (unsigned i = 0, e = getNumArgs(); i != e; ++i)
731 /// \brief Returns the size of the type source info data block that is
732 /// specific to this type.
733 unsigned getExtraLocalDataSize() const {
734 return getNumArgs() * sizeof(ParmVarDecl*);
737 QualType getInnerType() const { return getTypePtr()->getResultType(); }
740 class FunctionProtoTypeLoc :
741 public InheritingConcreteTypeLoc<FunctionTypeLoc,
742 FunctionProtoTypeLoc,
746 class FunctionNoProtoTypeLoc :
747 public InheritingConcreteTypeLoc<FunctionTypeLoc,
748 FunctionNoProtoTypeLoc,
749 FunctionNoProtoType> {
753 struct ArrayLocInfo {
754 SourceLocation LBracketLoc, RBracketLoc;
758 /// \brief Wrapper for source info for arrays.
759 class ArrayTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
764 SourceLocation getLBracketLoc() const {
765 return getLocalData()->LBracketLoc;
767 void setLBracketLoc(SourceLocation Loc) {
768 getLocalData()->LBracketLoc = Loc;
771 SourceLocation getRBracketLoc() const {
772 return getLocalData()->RBracketLoc;
774 void setRBracketLoc(SourceLocation Loc) {
775 getLocalData()->RBracketLoc = Loc;
778 SourceRange getBracketsRange() const {
779 return SourceRange(getLBracketLoc(), getRBracketLoc());
782 Expr *getSizeExpr() const {
783 return getLocalData()->Size;
785 void setSizeExpr(Expr *Size) {
786 getLocalData()->Size = Size;
789 TypeLoc getElementLoc() const {
790 return getInnerTypeLoc();
793 SourceRange getSourceRange() const {
794 return SourceRange(getLBracketLoc(), getRBracketLoc());
797 void initializeLocal(SourceLocation Loc) {
803 QualType getInnerType() const { return getTypePtr()->getElementType(); }
806 class ConstantArrayTypeLoc :
807 public InheritingConcreteTypeLoc<ArrayTypeLoc,
808 ConstantArrayTypeLoc,
812 class IncompleteArrayTypeLoc :
813 public InheritingConcreteTypeLoc<ArrayTypeLoc,
814 IncompleteArrayTypeLoc,
815 IncompleteArrayType> {
818 class DependentSizedArrayTypeLoc :
819 public InheritingConcreteTypeLoc<ArrayTypeLoc,
820 DependentSizedArrayTypeLoc,
821 DependentSizedArrayType> {
825 class VariableArrayTypeLoc :
826 public InheritingConcreteTypeLoc<ArrayTypeLoc,
827 VariableArrayTypeLoc,
832 // Location information for a TemplateName. Rudimentary for now.
833 struct TemplateNameLocInfo {
834 SourceLocation NameLoc;
837 struct TemplateSpecializationLocInfo : TemplateNameLocInfo {
838 SourceLocation LAngleLoc;
839 SourceLocation RAngleLoc;
842 class TemplateSpecializationTypeLoc :
843 public ConcreteTypeLoc<UnqualTypeLoc,
844 TemplateSpecializationTypeLoc,
845 TemplateSpecializationType,
846 TemplateSpecializationLocInfo> {
848 SourceLocation getLAngleLoc() const {
849 return getLocalData()->LAngleLoc;
851 void setLAngleLoc(SourceLocation Loc) {
852 getLocalData()->LAngleLoc = Loc;
855 SourceLocation getRAngleLoc() const {
856 return getLocalData()->RAngleLoc;
858 void setRAngleLoc(SourceLocation Loc) {
859 getLocalData()->RAngleLoc = Loc;
862 unsigned getNumArgs() const {
863 return getTypePtr()->getNumArgs();
865 void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) {
867 AI.validateForArgument(getTypePtr()->getArg(i));
869 getArgInfos()[i] = AI;
871 TemplateArgumentLocInfo getArgLocInfo(unsigned i) const {
872 return getArgInfos()[i];
875 TemplateArgumentLoc getArgLoc(unsigned i) const {
876 return TemplateArgumentLoc(getTypePtr()->getArg(i), getArgLocInfo(i));
879 SourceLocation getTemplateNameLoc() const {
880 return getLocalData()->NameLoc;
882 void setTemplateNameLoc(SourceLocation Loc) {
883 getLocalData()->NameLoc = Loc;
886 /// \brief - Copy the location information from the given info.
887 void copy(TemplateSpecializationTypeLoc Loc) {
888 unsigned size = getFullDataSize();
889 assert(size == Loc.getFullDataSize());
891 // We're potentially copying Expr references here. We don't
892 // bother retaining them because DeclaratorInfos live forever, so
893 // as long as the Expr was retained when originally written into
894 // the TypeLoc, we're okay.
895 memcpy(Data, Loc.Data, size);
898 SourceRange getSourceRange() const {
899 return SourceRange(getTemplateNameLoc(), getRAngleLoc());
902 void initializeLocal(SourceLocation Loc) {
905 setTemplateNameLoc(Loc);
907 for (unsigned i = 0, e = getNumArgs(); i != e; ++i) {
908 TemplateArgumentLocInfo Info;
910 // If asserts are enabled, be sure to initialize the argument
911 // loc with the right kind of pointer.
912 switch (getTypePtr()->getArg(i).getKind()) {
913 case TemplateArgument::Expression:
914 case TemplateArgument::Declaration:
915 Info = TemplateArgumentLocInfo((Expr*) 0);
918 case TemplateArgument::Type:
919 Info = TemplateArgumentLocInfo((DeclaratorInfo*) 0);
922 case TemplateArgument::Integral:
923 case TemplateArgument::Pack:
924 case TemplateArgument::Null:
929 getArgInfos()[i] = Info;
933 unsigned getExtraLocalDataSize() const {
934 return getNumArgs() * sizeof(TemplateArgumentLocInfo);
938 TemplateArgumentLocInfo *getArgInfos() const {
939 return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData());
943 // None of these types have proper implementations yet.
945 class VectorTypeLoc : public TypeSpecTypeLoc<VectorTypeLoc, VectorType> {
948 class ExtVectorTypeLoc : public InheritingConcreteTypeLoc<VectorTypeLoc,
953 // For some reason, this isn't a subtype of VectorType.
954 class DependentSizedExtVectorTypeLoc :
955 public TypeSpecTypeLoc<DependentSizedExtVectorTypeLoc,
956 DependentSizedExtVectorType> {
959 class FixedWidthIntTypeLoc : public TypeSpecTypeLoc<FixedWidthIntTypeLoc,
963 class ComplexTypeLoc : public TypeSpecTypeLoc<ComplexTypeLoc,
967 class TypeOfExprTypeLoc : public TypeSpecTypeLoc<TypeOfExprTypeLoc,
971 class TypeOfTypeLoc : public TypeSpecTypeLoc<TypeOfTypeLoc, TypeOfType> {
974 class DecltypeTypeLoc : public TypeSpecTypeLoc<DecltypeTypeLoc, DecltypeType> {
977 class TagTypeLoc : public TypeSpecTypeLoc<TagTypeLoc, TagType> {
980 class RecordTypeLoc : public InheritingConcreteTypeLoc<TagTypeLoc,
985 class EnumTypeLoc : public InheritingConcreteTypeLoc<TagTypeLoc,
990 class ElaboratedTypeLoc : public TypeSpecTypeLoc<ElaboratedTypeLoc,
994 class QualifiedNameTypeLoc : public TypeSpecTypeLoc<QualifiedNameTypeLoc,
998 class TypenameTypeLoc : public TypeSpecTypeLoc<TypenameTypeLoc,