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"
27 // Predeclare all the type nodes.
28 #define ABSTRACT_TYPELOC(Class, Base)
29 #define TYPELOC(Class, Base) \
31 #include "clang/AST/TypeLocNodes.def"
33 /// \brief Base wrapper for a particular "section" of type source info.
35 /// A client should use the TypeLoc subclasses through cast/dyn_cast in order to
36 /// get at the actual information.
39 // The correctness of this relies on the property that, for Type *Ty,
40 // QualType(Ty, 0).getAsOpaquePtr() == (void*) Ty
45 /// The kinds of TypeLocs. Equivalent to the Type::TypeClass enum,
46 /// except it also defines a Qualified enum that corresponds to the
47 /// QualifiedLoc class.
49 #define ABSTRACT_TYPE(Class, Base)
50 #define TYPE(Class, Base) \
52 #include "clang/AST/TypeNodes.def"
56 TypeLoc() : Ty(0), Data(0) { }
57 TypeLoc(QualType ty
, void *opaqueData
)
58 : Ty(ty
.getAsOpaquePtr()), Data(opaqueData
) { }
59 TypeLoc(Type
*ty
, void *opaqueData
)
60 : Ty(ty
), Data(opaqueData
) { }
62 TypeLocClass
getTypeLocClass() const {
63 if (getType().hasLocalQualifiers()) return Qualified
;
64 return (TypeLocClass
) getType()->getTypeClass();
67 bool isNull() const { return !Ty
; }
68 operator bool() const { return Ty
; }
70 /// \brief Returns the size of type source info data block for the given type.
71 static unsigned getFullDataSizeForType(QualType Ty
);
73 /// \brief Get the type for which this source info wrapper provides
75 QualType
getType() const {
76 return QualType::getFromOpaquePtr(Ty
);
79 Type
*getTypePtr() const {
80 return QualType::getFromOpaquePtr(Ty
).getTypePtr();
83 /// \brief Get the pointer where source information is stored.
84 void *getOpaqueData() const {
88 /// \brief Get the begin source location.
89 SourceLocation
getBeginLoc() const;
91 /// \brief Get the end source location.
92 SourceLocation
getEndLoc() const;
94 /// \brief Get the full source range.
95 SourceRange
getSourceRange() const {
96 return SourceRange(getBeginLoc(), getEndLoc());
99 /// \brief Get the local source range.
100 SourceRange
getLocalSourceRange() const {
101 return getLocalSourceRangeImpl(*this);
104 /// \brief Returns the size of the type source info data block.
105 unsigned getFullDataSize() const {
106 return getFullDataSizeForType(getType());
109 /// \brief Get the next TypeLoc pointed by this TypeLoc, e.g for "int*" the
110 /// TypeLoc is a PointerLoc and next TypeLoc is for "int".
111 TypeLoc
getNextTypeLoc() const {
112 return getNextTypeLocImpl(*this);
115 /// \brief Skips past any qualifiers, if this is qualified.
116 UnqualTypeLoc
getUnqualifiedLoc() const; // implemented in this header
118 /// \brief Initializes this to state that every location in this
119 /// type is the given location.
121 /// This method exists to provide a simple transition for code that
122 /// relies on location-less types.
123 void initialize(SourceLocation Loc
) const {
124 initializeImpl(*this, Loc
);
127 friend bool operator==(const TypeLoc
&LHS
, const TypeLoc
&RHS
) {
128 return LHS
.Ty
== RHS
.Ty
&& LHS
.Data
== RHS
.Data
;
131 friend bool operator!=(const TypeLoc
&LHS
, const TypeLoc
&RHS
) {
132 return !(LHS
== RHS
);
135 static bool classof(const TypeLoc
*TL
) { return true; }
138 static void initializeImpl(TypeLoc TL
, SourceLocation Loc
);
139 static TypeLoc
getNextTypeLocImpl(TypeLoc TL
);
140 static SourceRange
getLocalSourceRangeImpl(TypeLoc TL
);
143 /// \brief Return the TypeLoc for a type source info.
144 inline TypeLoc
TypeSourceInfo::getTypeLoc() const {
145 return TypeLoc(Ty
, const_cast<void*>(static_cast<const void*>(this + 1)));
148 /// \brief Wrapper of type source information for a type with
149 /// no direct qualifiers.
150 class UnqualTypeLoc
: public TypeLoc
{
153 UnqualTypeLoc(Type
*Ty
, void *Data
) : TypeLoc(Ty
, Data
) {}
155 Type
*getTypePtr() const {
156 return reinterpret_cast<Type
*>(Ty
);
159 TypeLocClass
getTypeLocClass() const {
160 return (TypeLocClass
) getTypePtr()->getTypeClass();
163 static bool classof(const TypeLoc
*TL
) {
164 return !TL
->getType().hasLocalQualifiers();
166 static bool classof(const UnqualTypeLoc
*TL
) { return true; }
169 /// \brief Wrapper of type source information for a type with
170 /// non-trivial direct qualifiers.
172 /// Currently, we intentionally do not provide source location for
174 class QualifiedTypeLoc
: public TypeLoc
{
176 SourceRange
getLocalSourceRange() const {
177 return SourceRange();
180 UnqualTypeLoc
getUnqualifiedLoc() const {
181 return UnqualTypeLoc(getTypePtr(), Data
);
184 /// Initializes the local data of this type source info block to
185 /// provide no information.
186 void initializeLocal(SourceLocation Loc
) {
190 TypeLoc
getNextTypeLoc() const {
191 return getUnqualifiedLoc();
194 /// \brief Returns the size of the type source info data block that is
195 /// specific to this type.
196 unsigned getLocalDataSize() const {
197 // In fact, we don't currently preserve any location information
202 /// \brief Returns the size of the type source info data block.
203 unsigned getFullDataSize() const {
204 return getLocalDataSize() +
205 getFullDataSizeForType(getType().getLocalUnqualifiedType());
208 static bool classof(const TypeLoc
*TL
) {
209 return TL
->getType().hasLocalQualifiers();
211 static bool classof(const QualifiedTypeLoc
*TL
) { return true; }
214 inline UnqualTypeLoc
TypeLoc::getUnqualifiedLoc() const {
215 if (isa
<QualifiedTypeLoc
>(this))
216 return cast
<QualifiedTypeLoc
>(this)->getUnqualifiedLoc();
217 return cast
<UnqualTypeLoc
>(*this);
220 /// A metaprogramming base class for TypeLoc classes which correspond
221 /// to a particular Type subclass. It is accepted for a single
222 /// TypeLoc class to correspond to multiple Type classes.
224 /// \param Base a class from which to derive
225 /// \param Derived the class deriving from this one
226 /// \param TypeClass the concrete Type subclass associated with this
228 /// \param LocalData the structure type of local location data for
231 /// sizeof(LocalData) needs to be a multiple of sizeof(void*) or
232 /// else the world will end.
234 /// TypeLocs with non-constant amounts of local data should override
235 /// getExtraLocalDataSize(); getExtraLocalData() will then point to
236 /// this extra memory.
238 /// TypeLocs with an inner type should define
239 /// QualType getInnerType() const
240 /// and getInnerTypeLoc() will then point to this inner type's
243 /// A word about hierarchies: this template is not designed to be
244 /// derived from multiple times in a hierarchy. It is also not
245 /// designed to be used for classes where subtypes might provide
246 /// different amounts of source information. It should be subclassed
247 /// only at the deepest portion of the hierarchy where all children
248 /// have identical source information; if that's an abstract type,
249 /// then further descendents should inherit from
250 /// InheritingConcreteTypeLoc instead.
251 template <class Base
, class Derived
, class TypeClass
, class LocalData
>
252 class ConcreteTypeLoc
: public Base
{
254 const Derived
*asDerived() const {
255 return static_cast<const Derived
*>(this);
259 unsigned getLocalDataSize() const {
260 return sizeof(LocalData
) + asDerived()->getExtraLocalDataSize();
262 // Give a default implementation that's useful for leaf types.
263 unsigned getFullDataSize() const {
264 return asDerived()->getLocalDataSize() + getInnerTypeSize();
267 static bool classofType(const Type
*Ty
) {
268 return TypeClass::classof(Ty
);
271 static bool classof(const TypeLoc
*TL
) {
272 return Derived::classofType(TL
->getTypePtr());
274 static bool classof(const UnqualTypeLoc
*TL
) {
275 return Derived::classofType(TL
->getTypePtr());
277 static bool classof(const Derived
*TL
) {
281 TypeLoc
getNextTypeLoc() const {
282 return getNextTypeLoc(asDerived()->getInnerType());
285 TypeClass
*getTypePtr() const {
286 return cast
<TypeClass
>(Base::getTypePtr());
290 unsigned getExtraLocalDataSize() const {
294 LocalData
*getLocalData() const {
295 return static_cast<LocalData
*>(Base::Data
);
298 /// Gets a pointer past the Info structure; useful for classes with
299 /// local data that can't be captured in the Info (e.g. because it's
300 /// of variable size).
301 void *getExtraLocalData() const {
302 return getLocalData() + 1;
305 void *getNonLocalData() const {
306 return static_cast<char*>(Base::Data
) + asDerived()->getLocalDataSize();
309 struct HasNoInnerType
{};
310 HasNoInnerType
getInnerType() const { return HasNoInnerType(); }
312 TypeLoc
getInnerTypeLoc() const {
313 return TypeLoc(asDerived()->getInnerType(), getNonLocalData());
317 unsigned getInnerTypeSize() const {
318 return getInnerTypeSize(asDerived()->getInnerType());
321 unsigned getInnerTypeSize(HasNoInnerType _
) const {
325 unsigned getInnerTypeSize(QualType _
) const {
326 return getInnerTypeLoc().getFullDataSize();
329 TypeLoc
getNextTypeLoc(HasNoInnerType _
) const {
333 TypeLoc
getNextTypeLoc(QualType T
) const {
334 return TypeLoc(T
, getNonLocalData());
338 /// A metaprogramming class designed for concrete subtypes of abstract
339 /// types where all subtypes share equivalently-structured source
340 /// information. See the note on ConcreteTypeLoc.
341 template <class Base
, class Derived
, class TypeClass
>
342 class InheritingConcreteTypeLoc
: public Base
{
344 static bool classofType(const Type
*Ty
) {
345 return TypeClass::classof(Ty
);
348 static bool classof(const TypeLoc
*TL
) {
349 return Derived::classofType(TL
->getTypePtr());
351 static bool classof(const UnqualTypeLoc
*TL
) {
352 return Derived::classofType(TL
->getTypePtr());
354 static bool classof(const Derived
*TL
) {
358 TypeClass
*getTypePtr() const {
359 return cast
<TypeClass
>(Base::getTypePtr());
364 struct TypeSpecLocInfo
{
365 SourceLocation NameLoc
;
368 /// \brief A reasonable base class for TypeLocs that correspond to
369 /// types that are written as a type-specifier.
370 class TypeSpecTypeLoc
: public ConcreteTypeLoc
<UnqualTypeLoc
,
375 enum { LocalDataSize
= sizeof(TypeSpecLocInfo
) };
377 SourceLocation
getNameLoc() const {
378 return this->getLocalData()->NameLoc
;
380 void setNameLoc(SourceLocation Loc
) {
381 this->getLocalData()->NameLoc
= Loc
;
383 SourceRange
getLocalSourceRange() const {
384 return SourceRange(getNameLoc(), getNameLoc());
386 void initializeLocal(SourceLocation Loc
) {
390 static bool classof(const TypeLoc
*TL
);
391 static bool classof(const TypeSpecTypeLoc
*TL
) { return true; }
395 struct BuiltinLocInfo
{
396 SourceLocation BuiltinLoc
;
399 /// \brief Wrapper for source info for builtin types.
400 class BuiltinTypeLoc
: public ConcreteTypeLoc
<UnqualTypeLoc
,
405 enum { LocalDataSize
= sizeof(BuiltinLocInfo
) };
407 SourceLocation
getBuiltinLoc() const {
408 return getLocalData()->BuiltinLoc
;
410 void setBuiltinLoc(SourceLocation Loc
) {
411 getLocalData()->BuiltinLoc
= Loc
;
414 SourceLocation
getNameLoc() const { return getBuiltinLoc(); }
416 WrittenBuiltinSpecs
& getWrittenBuiltinSpecs() {
417 return *(static_cast<WrittenBuiltinSpecs
*>(getExtraLocalData()));
419 const WrittenBuiltinSpecs
& getWrittenBuiltinSpecs() const {
420 return *(static_cast<WrittenBuiltinSpecs
*>(getExtraLocalData()));
423 bool needsExtraLocalData() const {
424 BuiltinType::Kind bk
= getTypePtr()->getKind();
425 return (bk
>= BuiltinType::UShort
&& bk
<= BuiltinType::UInt128
)
426 || (bk
>= BuiltinType::Short
&& bk
<= BuiltinType::LongDouble
)
427 || bk
== BuiltinType::UChar
428 || bk
== BuiltinType::SChar
;
431 unsigned getExtraLocalDataSize() const {
432 return needsExtraLocalData() ? sizeof(WrittenBuiltinSpecs
) : 0;
435 SourceRange
getLocalSourceRange() const {
436 return SourceRange(getBuiltinLoc(), getBuiltinLoc());
439 TypeSpecifierSign
getWrittenSignSpec() const {
440 if (needsExtraLocalData())
441 return static_cast<TypeSpecifierSign
>(getWrittenBuiltinSpecs().Sign
);
443 return TSS_unspecified
;
445 bool hasWrittenSignSpec() const {
446 return getWrittenSignSpec() != TSS_unspecified
;
448 void setWrittenSignSpec(TypeSpecifierSign written
) {
449 if (needsExtraLocalData())
450 getWrittenBuiltinSpecs().Sign
= written
;
453 TypeSpecifierWidth
getWrittenWidthSpec() const {
454 if (needsExtraLocalData())
455 return static_cast<TypeSpecifierWidth
>(getWrittenBuiltinSpecs().Width
);
457 return TSW_unspecified
;
459 bool hasWrittenWidthSpec() const {
460 return getWrittenWidthSpec() != TSW_unspecified
;
462 void setWrittenWidthSpec(TypeSpecifierWidth written
) {
463 if (needsExtraLocalData())
464 getWrittenBuiltinSpecs().Width
= written
;
467 TypeSpecifierType
getWrittenTypeSpec() const;
468 bool hasWrittenTypeSpec() const {
469 return getWrittenTypeSpec() != TST_unspecified
;
471 void setWrittenTypeSpec(TypeSpecifierType written
) {
472 if (needsExtraLocalData())
473 getWrittenBuiltinSpecs().Type
= written
;
476 bool hasModeAttr() const {
477 if (needsExtraLocalData())
478 return getWrittenBuiltinSpecs().ModeAttr
;
482 void setModeAttr(bool written
) {
483 if (needsExtraLocalData())
484 getWrittenBuiltinSpecs().ModeAttr
= written
;
487 void initializeLocal(SourceLocation Loc
) {
489 if (needsExtraLocalData()) {
490 WrittenBuiltinSpecs
&wbs
= getWrittenBuiltinSpecs();
491 wbs
.Sign
= TSS_unspecified
;
492 wbs
.Width
= TSW_unspecified
;
493 wbs
.Type
= TST_unspecified
;
494 wbs
.ModeAttr
= false;
500 /// \brief Wrapper for source info for typedefs.
501 class TypedefTypeLoc
: public InheritingConcreteTypeLoc
<TypeSpecTypeLoc
,
505 TypedefDecl
*getTypedefDecl() const {
506 return getTypePtr()->getDecl();
510 /// \brief Wrapper for source info for injected class names of class
512 class InjectedClassNameTypeLoc
:
513 public InheritingConcreteTypeLoc
<TypeSpecTypeLoc
,
514 InjectedClassNameTypeLoc
,
515 InjectedClassNameType
> {
518 /// \brief Wrapper for source info for unresolved typename using decls.
519 class UnresolvedUsingTypeLoc
:
520 public InheritingConcreteTypeLoc
<TypeSpecTypeLoc
,
521 UnresolvedUsingTypeLoc
,
522 UnresolvedUsingType
> {
524 UnresolvedUsingTypenameDecl
*getDecl() const {
525 return getTypePtr()->getDecl();
529 /// \brief Wrapper for source info for tag types. Note that this only
530 /// records source info for the name itself; a type written 'struct foo'
531 /// should be represented as an ElaboratedTypeLoc. We currently
532 /// only do that when C++ is enabled because of the expense of
533 /// creating an ElaboratedType node for so many type references in C.
534 class TagTypeLoc
: public InheritingConcreteTypeLoc
<TypeSpecTypeLoc
,
538 TagDecl
*getDecl() const { return getTypePtr()->getDecl(); }
541 /// \brief Wrapper for source info for record types.
542 class RecordTypeLoc
: public InheritingConcreteTypeLoc
<TagTypeLoc
,
546 RecordDecl
*getDecl() const { return getTypePtr()->getDecl(); }
549 /// \brief Wrapper for source info for enum types.
550 class EnumTypeLoc
: public InheritingConcreteTypeLoc
<TagTypeLoc
,
554 EnumDecl
*getDecl() const { return getTypePtr()->getDecl(); }
557 /// \brief Wrapper for template type parameters.
558 class TemplateTypeParmTypeLoc
:
559 public InheritingConcreteTypeLoc
<TypeSpecTypeLoc
,
560 TemplateTypeParmTypeLoc
,
561 TemplateTypeParmType
> {
564 /// \brief Wrapper for substituted template type parameters.
565 class SubstTemplateTypeParmTypeLoc
:
566 public InheritingConcreteTypeLoc
<TypeSpecTypeLoc
,
567 SubstTemplateTypeParmTypeLoc
,
568 SubstTemplateTypeParmType
> {
572 struct ObjCProtocolListLocInfo
{
573 SourceLocation LAngleLoc
;
574 SourceLocation RAngleLoc
;
575 bool HasBaseTypeAsWritten
;
578 // A helper class for defining ObjC TypeLocs that can qualified with
581 // TypeClass basically has to be either ObjCInterfaceType or
582 // ObjCObjectPointerType.
583 class ObjCObjectTypeLoc
: public ConcreteTypeLoc
<UnqualTypeLoc
,
586 ObjCProtocolListLocInfo
> {
587 // SourceLocations are stored after Info, one for each Protocol.
588 SourceLocation
*getProtocolLocArray() const {
589 return (SourceLocation
*) this->getExtraLocalData();
593 SourceLocation
getLAngleLoc() const {
594 return this->getLocalData()->LAngleLoc
;
596 void setLAngleLoc(SourceLocation Loc
) {
597 this->getLocalData()->LAngleLoc
= Loc
;
600 SourceLocation
getRAngleLoc() const {
601 return this->getLocalData()->RAngleLoc
;
603 void setRAngleLoc(SourceLocation Loc
) {
604 this->getLocalData()->RAngleLoc
= Loc
;
607 unsigned getNumProtocols() const {
608 return this->getTypePtr()->getNumProtocols();
611 SourceLocation
getProtocolLoc(unsigned i
) const {
612 assert(i
< getNumProtocols() && "Index is out of bounds!");
613 return getProtocolLocArray()[i
];
615 void setProtocolLoc(unsigned i
, SourceLocation Loc
) {
616 assert(i
< getNumProtocols() && "Index is out of bounds!");
617 getProtocolLocArray()[i
] = Loc
;
620 ObjCProtocolDecl
*getProtocol(unsigned i
) const {
621 assert(i
< getNumProtocols() && "Index is out of bounds!");
622 return *(this->getTypePtr()->qual_begin() + i
);
625 bool hasBaseTypeAsWritten() const {
626 return getLocalData()->HasBaseTypeAsWritten
;
629 void setHasBaseTypeAsWritten(bool HasBaseType
) {
630 getLocalData()->HasBaseTypeAsWritten
= HasBaseType
;
633 TypeLoc
getBaseLoc() const {
634 return getInnerTypeLoc();
637 SourceRange
getLocalSourceRange() const {
638 return SourceRange(getLAngleLoc(), getRAngleLoc());
641 void initializeLocal(SourceLocation Loc
) {
642 setHasBaseTypeAsWritten(true);
645 for (unsigned i
= 0, e
= getNumProtocols(); i
!= e
; ++i
)
646 setProtocolLoc(i
, Loc
);
649 unsigned getExtraLocalDataSize() const {
650 return this->getNumProtocols() * sizeof(SourceLocation
);
653 QualType
getInnerType() const {
654 return getTypePtr()->getBaseType();
659 struct ObjCInterfaceLocInfo
{
660 SourceLocation NameLoc
;
663 /// \brief Wrapper for source info for ObjC interfaces.
664 class ObjCInterfaceTypeLoc
: public ConcreteTypeLoc
<ObjCObjectTypeLoc
,
665 ObjCInterfaceTypeLoc
,
667 ObjCInterfaceLocInfo
> {
669 ObjCInterfaceDecl
*getIFaceDecl() const {
670 return getTypePtr()->getDecl();
673 SourceLocation
getNameLoc() const {
674 return getLocalData()->NameLoc
;
677 void setNameLoc(SourceLocation Loc
) {
678 getLocalData()->NameLoc
= Loc
;
681 SourceRange
getLocalSourceRange() const {
682 return SourceRange(getNameLoc());
685 void initializeLocal(SourceLocation Loc
) {
691 struct PointerLikeLocInfo
{
692 SourceLocation StarLoc
;
696 template <class Derived
, class TypeClass
, class LocalData
= PointerLikeLocInfo
>
697 class PointerLikeTypeLoc
: public ConcreteTypeLoc
<UnqualTypeLoc
, Derived
,
698 TypeClass
, LocalData
> {
700 SourceLocation
getSigilLoc() const {
701 return this->getLocalData()->StarLoc
;
703 void setSigilLoc(SourceLocation Loc
) {
704 this->getLocalData()->StarLoc
= Loc
;
707 TypeLoc
getPointeeLoc() const {
708 return this->getInnerTypeLoc();
711 SourceRange
getLocalSourceRange() const {
712 return SourceRange(getSigilLoc(), getSigilLoc());
715 void initializeLocal(SourceLocation Loc
) {
719 QualType
getInnerType() const {
720 return this->getTypePtr()->getPointeeType();
725 /// \brief Wrapper for source info for pointers.
726 class PointerTypeLoc
: public PointerLikeTypeLoc
<PointerTypeLoc
,
729 SourceLocation
getStarLoc() const {
730 return getSigilLoc();
732 void setStarLoc(SourceLocation Loc
) {
738 /// \brief Wrapper for source info for block pointers.
739 class BlockPointerTypeLoc
: public PointerLikeTypeLoc
<BlockPointerTypeLoc
,
742 SourceLocation
getCaretLoc() const {
743 return getSigilLoc();
745 void setCaretLoc(SourceLocation Loc
) {
751 /// \brief Wrapper for source info for member pointers.
752 class MemberPointerTypeLoc
: public PointerLikeTypeLoc
<MemberPointerTypeLoc
,
755 SourceLocation
getStarLoc() const {
756 return getSigilLoc();
758 void setStarLoc(SourceLocation Loc
) {
763 /// Wraps an ObjCPointerType with source location information.
764 class ObjCObjectPointerTypeLoc
:
765 public PointerLikeTypeLoc
<ObjCObjectPointerTypeLoc
,
766 ObjCObjectPointerType
> {
768 SourceLocation
getStarLoc() const {
769 return getSigilLoc();
772 void setStarLoc(SourceLocation Loc
) {
778 class ReferenceTypeLoc
: public PointerLikeTypeLoc
<ReferenceTypeLoc
,
781 QualType
getInnerType() const {
782 return getTypePtr()->getPointeeTypeAsWritten();
786 class LValueReferenceTypeLoc
:
787 public InheritingConcreteTypeLoc
<ReferenceTypeLoc
,
788 LValueReferenceTypeLoc
,
789 LValueReferenceType
> {
791 SourceLocation
getAmpLoc() const {
792 return getSigilLoc();
794 void setAmpLoc(SourceLocation Loc
) {
799 class RValueReferenceTypeLoc
:
800 public InheritingConcreteTypeLoc
<ReferenceTypeLoc
,
801 RValueReferenceTypeLoc
,
802 RValueReferenceType
> {
804 SourceLocation
getAmpAmpLoc() const {
805 return getSigilLoc();
807 void setAmpAmpLoc(SourceLocation Loc
) {
813 struct FunctionLocInfo
{
814 SourceLocation LParenLoc
, RParenLoc
;
818 /// \brief Wrapper for source info for functions.
819 class FunctionTypeLoc
: public ConcreteTypeLoc
<UnqualTypeLoc
,
823 // ParmVarDecls* are stored after Info, one for each argument.
824 ParmVarDecl
**getParmArray() const {
825 return (ParmVarDecl
**) getExtraLocalData();
829 SourceLocation
getLParenLoc() const {
830 return getLocalData()->LParenLoc
;
832 void setLParenLoc(SourceLocation Loc
) {
833 getLocalData()->LParenLoc
= Loc
;
836 SourceLocation
getRParenLoc() const {
837 return getLocalData()->RParenLoc
;
839 void setRParenLoc(SourceLocation Loc
) {
840 getLocalData()->RParenLoc
= Loc
;
843 bool getTrailingReturn() const {
844 return getLocalData()->TrailingReturn
;
846 void setTrailingReturn(bool Trailing
) {
847 getLocalData()->TrailingReturn
= Trailing
;
850 unsigned getNumArgs() const {
851 if (isa
<FunctionNoProtoType
>(getTypePtr()))
853 return cast
<FunctionProtoType
>(getTypePtr())->getNumArgs();
855 ParmVarDecl
*getArg(unsigned i
) const { return getParmArray()[i
]; }
856 void setArg(unsigned i
, ParmVarDecl
*VD
) { getParmArray()[i
] = VD
; }
858 TypeLoc
getResultLoc() const {
859 return getInnerTypeLoc();
862 SourceRange
getLocalSourceRange() const {
863 return SourceRange(getLParenLoc(), getRParenLoc());
866 void initializeLocal(SourceLocation Loc
) {
869 setTrailingReturn(false);
870 for (unsigned i
= 0, e
= getNumArgs(); i
!= e
; ++i
)
874 /// \brief Returns the size of the type source info data block that is
875 /// specific to this type.
876 unsigned getExtraLocalDataSize() const {
877 return getNumArgs() * sizeof(ParmVarDecl
*);
880 QualType
getInnerType() const { return getTypePtr()->getResultType(); }
883 class FunctionProtoTypeLoc
:
884 public InheritingConcreteTypeLoc
<FunctionTypeLoc
,
885 FunctionProtoTypeLoc
,
889 class FunctionNoProtoTypeLoc
:
890 public InheritingConcreteTypeLoc
<FunctionTypeLoc
,
891 FunctionNoProtoTypeLoc
,
892 FunctionNoProtoType
> {
896 struct ArrayLocInfo
{
897 SourceLocation LBracketLoc
, RBracketLoc
;
901 /// \brief Wrapper for source info for arrays.
902 class ArrayTypeLoc
: public ConcreteTypeLoc
<UnqualTypeLoc
,
907 SourceLocation
getLBracketLoc() const {
908 return getLocalData()->LBracketLoc
;
910 void setLBracketLoc(SourceLocation Loc
) {
911 getLocalData()->LBracketLoc
= Loc
;
914 SourceLocation
getRBracketLoc() const {
915 return getLocalData()->RBracketLoc
;
917 void setRBracketLoc(SourceLocation Loc
) {
918 getLocalData()->RBracketLoc
= Loc
;
921 SourceRange
getBracketsRange() const {
922 return SourceRange(getLBracketLoc(), getRBracketLoc());
925 Expr
*getSizeExpr() const {
926 return getLocalData()->Size
;
928 void setSizeExpr(Expr
*Size
) {
929 getLocalData()->Size
= Size
;
932 TypeLoc
getElementLoc() const {
933 return getInnerTypeLoc();
936 SourceRange
getLocalSourceRange() const {
937 return SourceRange(getLBracketLoc(), getRBracketLoc());
940 void initializeLocal(SourceLocation Loc
) {
946 QualType
getInnerType() const { return getTypePtr()->getElementType(); }
949 class ConstantArrayTypeLoc
:
950 public InheritingConcreteTypeLoc
<ArrayTypeLoc
,
951 ConstantArrayTypeLoc
,
955 class IncompleteArrayTypeLoc
:
956 public InheritingConcreteTypeLoc
<ArrayTypeLoc
,
957 IncompleteArrayTypeLoc
,
958 IncompleteArrayType
> {
961 class DependentSizedArrayTypeLoc
:
962 public InheritingConcreteTypeLoc
<ArrayTypeLoc
,
963 DependentSizedArrayTypeLoc
,
964 DependentSizedArrayType
> {
968 class VariableArrayTypeLoc
:
969 public InheritingConcreteTypeLoc
<ArrayTypeLoc
,
970 VariableArrayTypeLoc
,
975 // Location information for a TemplateName. Rudimentary for now.
976 struct TemplateNameLocInfo
{
977 SourceLocation NameLoc
;
980 struct TemplateSpecializationLocInfo
: TemplateNameLocInfo
{
981 SourceLocation LAngleLoc
;
982 SourceLocation RAngleLoc
;
985 class TemplateSpecializationTypeLoc
:
986 public ConcreteTypeLoc
<UnqualTypeLoc
,
987 TemplateSpecializationTypeLoc
,
988 TemplateSpecializationType
,
989 TemplateSpecializationLocInfo
> {
991 SourceLocation
getLAngleLoc() const {
992 return getLocalData()->LAngleLoc
;
994 void setLAngleLoc(SourceLocation Loc
) {
995 getLocalData()->LAngleLoc
= Loc
;
998 SourceLocation
getRAngleLoc() const {
999 return getLocalData()->RAngleLoc
;
1001 void setRAngleLoc(SourceLocation Loc
) {
1002 getLocalData()->RAngleLoc
= Loc
;
1005 unsigned getNumArgs() const {
1006 return getTypePtr()->getNumArgs();
1008 void setArgLocInfo(unsigned i
, TemplateArgumentLocInfo AI
) {
1010 AI
.validateForArgument(getTypePtr()->getArg(i
));
1012 getArgInfos()[i
] = AI
;
1014 TemplateArgumentLocInfo
getArgLocInfo(unsigned i
) const {
1015 return getArgInfos()[i
];
1018 TemplateArgumentLoc
getArgLoc(unsigned i
) const {
1019 return TemplateArgumentLoc(getTypePtr()->getArg(i
), getArgLocInfo(i
));
1022 SourceLocation
getTemplateNameLoc() const {
1023 return getLocalData()->NameLoc
;
1025 void setTemplateNameLoc(SourceLocation Loc
) {
1026 getLocalData()->NameLoc
= Loc
;
1029 /// \brief - Copy the location information from the given info.
1030 void copy(TemplateSpecializationTypeLoc Loc
) {
1031 unsigned size
= getFullDataSize();
1032 assert(size
== Loc
.getFullDataSize());
1034 // We're potentially copying Expr references here. We don't
1035 // bother retaining them because TypeSourceInfos live forever, so
1036 // as long as the Expr was retained when originally written into
1037 // the TypeLoc, we're okay.
1038 memcpy(Data
, Loc
.Data
, size
);
1041 SourceRange
getLocalSourceRange() const {
1042 return SourceRange(getTemplateNameLoc(), getRAngleLoc());
1045 void initializeLocal(SourceLocation Loc
) {
1048 setTemplateNameLoc(Loc
);
1049 initializeArgLocs(getNumArgs(), getTypePtr()->getArgs(),
1050 getArgInfos(), Loc
);
1053 static void initializeArgLocs(unsigned NumArgs
,
1054 const TemplateArgument
*Args
,
1055 TemplateArgumentLocInfo
*ArgInfos
,
1056 SourceLocation Loc
) {
1057 for (unsigned i
= 0, e
= NumArgs
; i
!= e
; ++i
) {
1058 TemplateArgumentLocInfo Info
;
1060 // If asserts are enabled, be sure to initialize the argument
1061 // loc with the right kind of pointer.
1062 switch (Args
[i
].getKind()) {
1063 case TemplateArgument::Expression
:
1064 case TemplateArgument::Declaration
:
1065 Info
= TemplateArgumentLocInfo((Expr
*) 0);
1068 case TemplateArgument::Type
:
1069 Info
= TemplateArgumentLocInfo((TypeSourceInfo
*) 0);
1072 case TemplateArgument::Template
:
1073 Info
= TemplateArgumentLocInfo(SourceRange(Loc
), Loc
);
1076 case TemplateArgument::Integral
:
1077 case TemplateArgument::Pack
:
1078 case TemplateArgument::Null
:
1087 unsigned getExtraLocalDataSize() const {
1088 return getNumArgs() * sizeof(TemplateArgumentLocInfo
);
1092 TemplateArgumentLocInfo
*getArgInfos() const {
1093 return static_cast<TemplateArgumentLocInfo
*>(getExtraLocalData());
1097 //===----------------------------------------------------------------------===//
1099 // All of these need proper implementations.
1101 //===----------------------------------------------------------------------===//
1103 // FIXME: size expression and attribute locations (or keyword if we
1104 // ever fully support altivec syntax).
1105 class VectorTypeLoc
: public InheritingConcreteTypeLoc
<TypeSpecTypeLoc
,
1110 // FIXME: size expression and attribute locations.
1111 class ExtVectorTypeLoc
: public InheritingConcreteTypeLoc
<VectorTypeLoc
,
1116 // FIXME: attribute locations.
1117 // For some reason, this isn't a subtype of VectorType.
1118 class DependentSizedExtVectorTypeLoc
:
1119 public InheritingConcreteTypeLoc
<TypeSpecTypeLoc
,
1120 DependentSizedExtVectorTypeLoc
,
1121 DependentSizedExtVectorType
> {
1124 // FIXME: location of the '_Complex' keyword.
1125 class ComplexTypeLoc
: public InheritingConcreteTypeLoc
<TypeSpecTypeLoc
,
1130 struct TypeofLocInfo
{
1131 SourceLocation TypeofLoc
;
1132 SourceLocation LParenLoc
;
1133 SourceLocation RParenLoc
;
1136 struct TypeOfExprTypeLocInfo
: public TypeofLocInfo
{
1139 struct TypeOfTypeLocInfo
: public TypeofLocInfo
{
1140 TypeSourceInfo
* UnderlyingTInfo
;
1143 template <class Derived
, class TypeClass
, class LocalData
= TypeofLocInfo
>
1144 class TypeofLikeTypeLoc
1145 : public ConcreteTypeLoc
<UnqualTypeLoc
, Derived
, TypeClass
, LocalData
> {
1147 SourceLocation
getTypeofLoc() const {
1148 return this->getLocalData()->TypeofLoc
;
1150 void setTypeofLoc(SourceLocation Loc
) {
1151 this->getLocalData()->TypeofLoc
= Loc
;
1154 SourceLocation
getLParenLoc() const {
1155 return this->getLocalData()->LParenLoc
;
1157 void setLParenLoc(SourceLocation Loc
) {
1158 this->getLocalData()->LParenLoc
= Loc
;
1161 SourceLocation
getRParenLoc() const {
1162 return this->getLocalData()->RParenLoc
;
1164 void setRParenLoc(SourceLocation Loc
) {
1165 this->getLocalData()->RParenLoc
= Loc
;
1168 SourceRange
getParensRange() const {
1169 return SourceRange(getLParenLoc(), getRParenLoc());
1171 void setParensRange(SourceRange range
) {
1172 setLParenLoc(range
.getBegin());
1173 setRParenLoc(range
.getEnd());
1176 SourceRange
getLocalSourceRange() const {
1177 return SourceRange(getTypeofLoc(), getRParenLoc());
1180 void initializeLocal(SourceLocation Loc
) {
1187 class TypeOfExprTypeLoc
: public TypeofLikeTypeLoc
<TypeOfExprTypeLoc
,
1189 TypeOfExprTypeLocInfo
> {
1191 Expr
* getUnderlyingExpr() const {
1192 return getTypePtr()->getUnderlyingExpr();
1194 // Reimplemented to account for GNU/C++ extension
1195 // typeof unary-expression
1196 // where there are no parentheses.
1197 SourceRange
getLocalSourceRange() const;
1201 : public TypeofLikeTypeLoc
<TypeOfTypeLoc
, TypeOfType
, TypeOfTypeLocInfo
> {
1203 QualType
getUnderlyingType() const {
1204 return this->getTypePtr()->getUnderlyingType();
1206 TypeSourceInfo
* getUnderlyingTInfo() const {
1207 return this->getLocalData()->UnderlyingTInfo
;
1209 void setUnderlyingTInfo(TypeSourceInfo
* TI
) const {
1210 this->getLocalData()->UnderlyingTInfo
= TI
;
1214 // FIXME: location of the 'decltype' and parens.
1215 class DecltypeTypeLoc
: public InheritingConcreteTypeLoc
<TypeSpecTypeLoc
,
1220 struct ElaboratedLocInfo
{
1221 SourceLocation KeywordLoc
;
1222 SourceRange QualifierRange
;
1225 class ElaboratedTypeLoc
: public ConcreteTypeLoc
<UnqualTypeLoc
,
1228 ElaboratedLocInfo
> {
1230 SourceLocation
getKeywordLoc() const {
1231 return this->getLocalData()->KeywordLoc
;
1233 void setKeywordLoc(SourceLocation Loc
) {
1234 this->getLocalData()->KeywordLoc
= Loc
;
1237 SourceRange
getQualifierRange() const {
1238 return this->getLocalData()->QualifierRange
;
1240 void setQualifierRange(SourceRange Range
) {
1241 this->getLocalData()->QualifierRange
= Range
;
1244 SourceRange
getLocalSourceRange() const {
1245 if (getKeywordLoc().isValid())
1246 if (getQualifierRange().getEnd().isValid())
1247 return SourceRange(getKeywordLoc(), getQualifierRange().getEnd());
1249 return SourceRange(getKeywordLoc());
1251 return getQualifierRange();
1254 void initializeLocal(SourceLocation Loc
) {
1256 setQualifierRange(SourceRange(Loc
));
1259 TypeLoc
getNamedTypeLoc() const {
1260 return getInnerTypeLoc();
1263 QualType
getInnerType() const {
1264 return getTypePtr()->getNamedType();
1267 void copy(ElaboratedTypeLoc Loc
) {
1268 unsigned size
= getFullDataSize();
1269 assert(size
== Loc
.getFullDataSize());
1270 memcpy(Data
, Loc
.Data
, size
);
1274 // This is exactly the structure of an ElaboratedTypeLoc whose inner
1275 // type is some sort of TypeDeclTypeLoc.
1276 struct DependentNameLocInfo
: ElaboratedLocInfo
{
1277 SourceLocation NameLoc
;
1280 class DependentNameTypeLoc
: public ConcreteTypeLoc
<UnqualTypeLoc
,
1281 DependentNameTypeLoc
,
1283 DependentNameLocInfo
> {
1285 SourceLocation
getKeywordLoc() const {
1286 return this->getLocalData()->KeywordLoc
;
1288 void setKeywordLoc(SourceLocation Loc
) {
1289 this->getLocalData()->KeywordLoc
= Loc
;
1292 SourceRange
getQualifierRange() const {
1293 return this->getLocalData()->QualifierRange
;
1295 void setQualifierRange(SourceRange Range
) {
1296 this->getLocalData()->QualifierRange
= Range
;
1299 SourceLocation
getNameLoc() const {
1300 return this->getLocalData()->NameLoc
;
1302 void setNameLoc(SourceLocation Loc
) {
1303 this->getLocalData()->NameLoc
= Loc
;
1306 SourceRange
getLocalSourceRange() const {
1307 if (getKeywordLoc().isValid())
1308 return SourceRange(getKeywordLoc(), getNameLoc());
1310 return SourceRange(getQualifierRange().getBegin(), getNameLoc());
1313 void copy(DependentNameTypeLoc Loc
) {
1314 unsigned size
= getFullDataSize();
1315 assert(size
== Loc
.getFullDataSize());
1316 memcpy(Data
, Loc
.Data
, size
);
1319 void initializeLocal(SourceLocation Loc
) {
1321 setQualifierRange(SourceRange(Loc
));
1326 // This is exactly the structure of an ElaboratedTypeLoc whose inner
1327 // type is some sort of TemplateSpecializationTypeLoc.
1328 struct DependentTemplateSpecializationLocInfo
: DependentNameLocInfo
{
1329 SourceLocation LAngleLoc
;
1330 SourceLocation RAngleLoc
;
1331 // followed by a TemplateArgumentLocInfo[]
1334 class DependentTemplateSpecializationTypeLoc
:
1335 public ConcreteTypeLoc
<UnqualTypeLoc
,
1336 DependentTemplateSpecializationTypeLoc
,
1337 DependentTemplateSpecializationType
,
1338 DependentTemplateSpecializationLocInfo
> {
1340 SourceLocation
getKeywordLoc() const {
1341 return this->getLocalData()->KeywordLoc
;
1343 void setKeywordLoc(SourceLocation Loc
) {
1344 this->getLocalData()->KeywordLoc
= Loc
;
1347 SourceRange
getQualifierRange() const {
1348 return this->getLocalData()->QualifierRange
;
1350 void setQualifierRange(SourceRange Range
) {
1351 this->getLocalData()->QualifierRange
= Range
;
1354 SourceLocation
getNameLoc() const {
1355 return this->getLocalData()->NameLoc
;
1357 void setNameLoc(SourceLocation Loc
) {
1358 this->getLocalData()->NameLoc
= Loc
;
1361 SourceLocation
getLAngleLoc() const {
1362 return this->getLocalData()->LAngleLoc
;
1364 void setLAngleLoc(SourceLocation Loc
) {
1365 this->getLocalData()->LAngleLoc
= Loc
;
1368 SourceLocation
getRAngleLoc() const {
1369 return this->getLocalData()->RAngleLoc
;
1371 void setRAngleLoc(SourceLocation Loc
) {
1372 this->getLocalData()->RAngleLoc
= Loc
;
1375 unsigned getNumArgs() const {
1376 return getTypePtr()->getNumArgs();
1379 void setArgLocInfo(unsigned i
, TemplateArgumentLocInfo AI
) {
1381 AI
.validateForArgument(getTypePtr()->getArg(i
));
1383 getArgInfos()[i
] = AI
;
1385 TemplateArgumentLocInfo
getArgLocInfo(unsigned i
) const {
1386 return getArgInfos()[i
];
1389 TemplateArgumentLoc
getArgLoc(unsigned i
) const {
1390 return TemplateArgumentLoc(getTypePtr()->getArg(i
), getArgLocInfo(i
));
1393 SourceRange
getLocalSourceRange() const {
1394 if (getKeywordLoc().isValid())
1395 return SourceRange(getKeywordLoc(), getRAngleLoc());
1397 return SourceRange(getQualifierRange().getBegin(), getRAngleLoc());
1400 void copy(DependentTemplateSpecializationTypeLoc Loc
) {
1401 unsigned size
= getFullDataSize();
1402 assert(size
== Loc
.getFullDataSize());
1403 memcpy(Data
, Loc
.Data
, size
);
1406 void initializeLocal(SourceLocation Loc
) {
1408 setQualifierRange(SourceRange(Loc
));
1412 TemplateSpecializationTypeLoc::initializeArgLocs(getNumArgs(),
1413 getTypePtr()->getArgs(),
1414 getArgInfos(), Loc
);
1417 unsigned getExtraLocalDataSize() const {
1418 return getNumArgs() * sizeof(TemplateArgumentLocInfo
);
1422 TemplateArgumentLocInfo
*getArgInfos() const {
1423 return static_cast<TemplateArgumentLocInfo
*>(getExtraLocalData());