Use the ASTMutationListener to track added template specializations in a chained...
[clang.git] / include / clang / AST / TypeLoc.h
blob35bba03d77357d6ff375e2094dd6977a7c821bf6
1 //===--- TypeLoc.h - Type Source Info Wrapper -------------------*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // 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"
22 namespace clang {
23 class ParmVarDecl;
24 class TypeSourceInfo;
25 class UnqualTypeLoc;
27 // Predeclare all the type nodes.
28 #define ABSTRACT_TYPELOC(Class, Base)
29 #define TYPELOC(Class, Base) \
30 class Class##TypeLoc;
31 #include "clang/AST/TypeLocNodes.def"
33 /// \brief Base wrapper for a particular "section" of type source info.
34 ///
35 /// A client should use the TypeLoc subclasses through cast/dyn_cast in order to
36 /// get at the actual information.
37 class TypeLoc {
38 protected:
39 // The correctness of this relies on the property that, for Type *Ty,
40 // QualType(Ty, 0).getAsOpaquePtr() == (void*) Ty
41 void *Ty;
42 void *Data;
44 public:
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.
48 enum TypeLocClass {
49 #define ABSTRACT_TYPE(Class, Base)
50 #define TYPE(Class, Base) \
51 Class = Type::Class,
52 #include "clang/AST/TypeNodes.def"
53 Qualified
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
74 /// information.
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 {
85 return Data;
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; }
137 private:
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 {
151 public:
152 UnqualTypeLoc() {}
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
173 /// type qualifiers.
174 class QualifiedTypeLoc : public TypeLoc {
175 public:
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) {
187 // do nothing
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
198 // for qualifiers.
199 return 0;
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
227 /// location type
228 /// \param LocalData the structure type of local location data for
229 /// this type
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
241 /// location data.
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);
258 public:
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) {
278 return true;
281 TypeLoc getNextTypeLoc() const {
282 return getNextTypeLoc(asDerived()->getInnerType());
285 TypeClass *getTypePtr() const {
286 return cast<TypeClass>(Base::getTypePtr());
289 protected:
290 unsigned getExtraLocalDataSize() const {
291 return 0;
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());
316 private:
317 unsigned getInnerTypeSize() const {
318 return getInnerTypeSize(asDerived()->getInnerType());
321 unsigned getInnerTypeSize(HasNoInnerType _) const {
322 return 0;
325 unsigned getInnerTypeSize(QualType _) const {
326 return getInnerTypeLoc().getFullDataSize();
329 TypeLoc getNextTypeLoc(HasNoInnerType _) const {
330 return TypeLoc();
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 {
343 public:
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) {
355 return true;
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,
371 TypeSpecTypeLoc,
372 Type,
373 TypeSpecLocInfo> {
374 public:
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) {
387 setNameLoc(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,
401 BuiltinTypeLoc,
402 BuiltinType,
403 BuiltinLocInfo> {
404 public:
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);
442 else
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);
456 else
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;
479 else
480 return false;
482 void setModeAttr(bool written) {
483 if (needsExtraLocalData())
484 getWrittenBuiltinSpecs().ModeAttr = written;
487 void initializeLocal(SourceLocation Loc) {
488 setBuiltinLoc(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,
502 TypedefTypeLoc,
503 TypedefType> {
504 public:
505 TypedefDecl *getTypedefDecl() const {
506 return getTypePtr()->getDecl();
510 /// \brief Wrapper for source info for injected class names of class
511 /// templates.
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> {
523 public:
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,
535 TagTypeLoc,
536 TagType> {
537 public:
538 TagDecl *getDecl() const { return getTypePtr()->getDecl(); }
541 /// \brief Wrapper for source info for record types.
542 class RecordTypeLoc : public InheritingConcreteTypeLoc<TagTypeLoc,
543 RecordTypeLoc,
544 RecordType> {
545 public:
546 RecordDecl *getDecl() const { return getTypePtr()->getDecl(); }
549 /// \brief Wrapper for source info for enum types.
550 class EnumTypeLoc : public InheritingConcreteTypeLoc<TagTypeLoc,
551 EnumTypeLoc,
552 EnumType> {
553 public:
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
579 // protocols.
581 // TypeClass basically has to be either ObjCInterfaceType or
582 // ObjCObjectPointerType.
583 class ObjCObjectTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
584 ObjCObjectTypeLoc,
585 ObjCObjectType,
586 ObjCProtocolListLocInfo> {
587 // SourceLocations are stored after Info, one for each Protocol.
588 SourceLocation *getProtocolLocArray() const {
589 return (SourceLocation*) this->getExtraLocalData();
592 public:
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);
643 setLAngleLoc(Loc);
644 setRAngleLoc(Loc);
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,
666 ObjCInterfaceType,
667 ObjCInterfaceLocInfo> {
668 public:
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) {
686 setNameLoc(Loc);
691 struct PointerLikeLocInfo {
692 SourceLocation StarLoc;
695 /// A base class for
696 template <class Derived, class TypeClass, class LocalData = PointerLikeLocInfo>
697 class PointerLikeTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, Derived,
698 TypeClass, LocalData> {
699 public:
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) {
716 setSigilLoc(Loc);
719 QualType getInnerType() const {
720 return this->getTypePtr()->getPointeeType();
725 /// \brief Wrapper for source info for pointers.
726 class PointerTypeLoc : public PointerLikeTypeLoc<PointerTypeLoc,
727 PointerType> {
728 public:
729 SourceLocation getStarLoc() const {
730 return getSigilLoc();
732 void setStarLoc(SourceLocation Loc) {
733 setSigilLoc(Loc);
738 /// \brief Wrapper for source info for block pointers.
739 class BlockPointerTypeLoc : public PointerLikeTypeLoc<BlockPointerTypeLoc,
740 BlockPointerType> {
741 public:
742 SourceLocation getCaretLoc() const {
743 return getSigilLoc();
745 void setCaretLoc(SourceLocation Loc) {
746 setSigilLoc(Loc);
751 /// \brief Wrapper for source info for member pointers.
752 class MemberPointerTypeLoc : public PointerLikeTypeLoc<MemberPointerTypeLoc,
753 MemberPointerType> {
754 public:
755 SourceLocation getStarLoc() const {
756 return getSigilLoc();
758 void setStarLoc(SourceLocation Loc) {
759 setSigilLoc(Loc);
763 /// Wraps an ObjCPointerType with source location information.
764 class ObjCObjectPointerTypeLoc :
765 public PointerLikeTypeLoc<ObjCObjectPointerTypeLoc,
766 ObjCObjectPointerType> {
767 public:
768 SourceLocation getStarLoc() const {
769 return getSigilLoc();
772 void setStarLoc(SourceLocation Loc) {
773 setSigilLoc(Loc);
778 class ReferenceTypeLoc : public PointerLikeTypeLoc<ReferenceTypeLoc,
779 ReferenceType> {
780 public:
781 QualType getInnerType() const {
782 return getTypePtr()->getPointeeTypeAsWritten();
786 class LValueReferenceTypeLoc :
787 public InheritingConcreteTypeLoc<ReferenceTypeLoc,
788 LValueReferenceTypeLoc,
789 LValueReferenceType> {
790 public:
791 SourceLocation getAmpLoc() const {
792 return getSigilLoc();
794 void setAmpLoc(SourceLocation Loc) {
795 setSigilLoc(Loc);
799 class RValueReferenceTypeLoc :
800 public InheritingConcreteTypeLoc<ReferenceTypeLoc,
801 RValueReferenceTypeLoc,
802 RValueReferenceType> {
803 public:
804 SourceLocation getAmpAmpLoc() const {
805 return getSigilLoc();
807 void setAmpAmpLoc(SourceLocation Loc) {
808 setSigilLoc(Loc);
813 struct FunctionLocInfo {
814 SourceLocation LParenLoc, RParenLoc;
815 bool TrailingReturn;
818 /// \brief Wrapper for source info for functions.
819 class FunctionTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
820 FunctionTypeLoc,
821 FunctionType,
822 FunctionLocInfo> {
823 // ParmVarDecls* are stored after Info, one for each argument.
824 ParmVarDecl **getParmArray() const {
825 return (ParmVarDecl**) getExtraLocalData();
828 public:
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()))
852 return 0;
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) {
867 setLParenLoc(Loc);
868 setRParenLoc(Loc);
869 setTrailingReturn(false);
870 for (unsigned i = 0, e = getNumArgs(); i != e; ++i)
871 setArg(i, NULL);
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,
886 FunctionProtoType> {
889 class FunctionNoProtoTypeLoc :
890 public InheritingConcreteTypeLoc<FunctionTypeLoc,
891 FunctionNoProtoTypeLoc,
892 FunctionNoProtoType> {
896 struct ArrayLocInfo {
897 SourceLocation LBracketLoc, RBracketLoc;
898 Expr *Size;
901 /// \brief Wrapper for source info for arrays.
902 class ArrayTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
903 ArrayTypeLoc,
904 ArrayType,
905 ArrayLocInfo> {
906 public:
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) {
941 setLBracketLoc(Loc);
942 setRBracketLoc(Loc);
943 setSizeExpr(NULL);
946 QualType getInnerType() const { return getTypePtr()->getElementType(); }
949 class ConstantArrayTypeLoc :
950 public InheritingConcreteTypeLoc<ArrayTypeLoc,
951 ConstantArrayTypeLoc,
952 ConstantArrayType> {
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,
971 VariableArrayType> {
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> {
990 public:
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) {
1009 #ifndef NDEBUG
1010 AI.validateForArgument(getTypePtr()->getArg(i));
1011 #endif
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) {
1046 setLAngleLoc(Loc);
1047 setRAngleLoc(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;
1059 #ifndef NDEBUG
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);
1066 break;
1068 case TemplateArgument::Type:
1069 Info = TemplateArgumentLocInfo((TypeSourceInfo*) 0);
1070 break;
1072 case TemplateArgument::Template:
1073 Info = TemplateArgumentLocInfo(SourceRange(Loc), Loc);
1074 break;
1076 case TemplateArgument::Integral:
1077 case TemplateArgument::Pack:
1078 case TemplateArgument::Null:
1079 // K_None is fine.
1080 break;
1082 #endif
1083 ArgInfos[i] = Info;
1087 unsigned getExtraLocalDataSize() const {
1088 return getNumArgs() * sizeof(TemplateArgumentLocInfo);
1091 private:
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,
1106 VectorTypeLoc,
1107 VectorType> {
1110 // FIXME: size expression and attribute locations.
1111 class ExtVectorTypeLoc : public InheritingConcreteTypeLoc<VectorTypeLoc,
1112 ExtVectorTypeLoc,
1113 ExtVectorType> {
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,
1126 ComplexTypeLoc,
1127 ComplexType> {
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> {
1146 public:
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) {
1181 setTypeofLoc(Loc);
1182 setLParenLoc(Loc);
1183 setRParenLoc(Loc);
1187 class TypeOfExprTypeLoc : public TypeofLikeTypeLoc<TypeOfExprTypeLoc,
1188 TypeOfExprType,
1189 TypeOfExprTypeLocInfo> {
1190 public:
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;
1200 class TypeOfTypeLoc
1201 : public TypeofLikeTypeLoc<TypeOfTypeLoc, TypeOfType, TypeOfTypeLocInfo> {
1202 public:
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,
1216 DecltypeTypeLoc,
1217 DecltypeType> {
1220 struct ElaboratedLocInfo {
1221 SourceLocation KeywordLoc;
1222 SourceRange QualifierRange;
1225 class ElaboratedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
1226 ElaboratedTypeLoc,
1227 ElaboratedType,
1228 ElaboratedLocInfo> {
1229 public:
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());
1248 else
1249 return SourceRange(getKeywordLoc());
1250 else
1251 return getQualifierRange();
1254 void initializeLocal(SourceLocation Loc) {
1255 setKeywordLoc(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,
1282 DependentNameType,
1283 DependentNameLocInfo> {
1284 public:
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());
1309 else
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) {
1320 setKeywordLoc(Loc);
1321 setQualifierRange(SourceRange(Loc));
1322 setNameLoc(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> {
1339 public:
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) {
1380 #ifndef NDEBUG
1381 AI.validateForArgument(getTypePtr()->getArg(i));
1382 #endif
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());
1396 else
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) {
1407 setKeywordLoc(Loc);
1408 setQualifierRange(SourceRange(Loc));
1409 setNameLoc(Loc);
1410 setLAngleLoc(Loc);
1411 setRAngleLoc(Loc);
1412 TemplateSpecializationTypeLoc::initializeArgLocs(getNumArgs(),
1413 getTypePtr()->getArgs(),
1414 getArgInfos(), Loc);
1417 unsigned getExtraLocalDataSize() const {
1418 return getNumArgs() * sizeof(TemplateArgumentLocInfo);
1421 private:
1422 TemplateArgumentLocInfo *getArgInfos() const {
1423 return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData());
1429 #endif