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 //===----------------------------------------------------------------------===//
11 /// \brief Defines the clang::TypeLoc interface and its subclasses.
13 //===----------------------------------------------------------------------===//
15 #ifndef LLVM_CLANG_AST_TYPELOC_H
16 #define LLVM_CLANG_AST_TYPELOC_H
18 #include "clang/AST/Decl.h"
19 #include "clang/AST/TemplateBase.h"
20 #include "clang/AST/Type.h"
21 #include "clang/Basic/Specifiers.h"
22 #include "llvm/Support/Compiler.h"
30 // Predeclare all the type nodes.
31 #define ABSTRACT_TYPELOC(Class, Base)
32 #define TYPELOC(Class, Base) \
34 #include "clang/AST/TypeLocNodes.def"
36 /// \brief Base wrapper for a particular "section" of type source info.
38 /// A client should use the TypeLoc subclasses through castAs()/getAs()
39 /// in order to get at the actual information.
42 // The correctness of this relies on the property that, for Type *Ty,
43 // QualType(Ty, 0).getAsOpaquePtr() == (void*) Ty
48 /// \brief Convert to the specified TypeLoc type, asserting that this TypeLoc
49 /// is of the desired type.
51 /// \pre T::isKind(*this)
54 assert(T::isKind(*this));
61 /// \brief Convert to the specified TypeLoc type, returning a null TypeLoc if
62 /// this TypeLoc is not of the desired type.
65 if (!T::isKind(*this))
73 /// \brief Convert to the specified TypeLoc type, returning a null TypeLoc if
74 /// this TypeLock is not of the desired type. It will consider type
75 /// adjustments from a type that wad written as a T to another type that is
76 /// still canonically a T (ignores parens, attributes, elaborated types, etc).
78 T getAsAdjusted() const;
80 /// The kinds of TypeLocs. Equivalent to the Type::TypeClass enum,
81 /// except it also defines a Qualified enum that corresponds to the
82 /// QualifiedLoc class.
84 #define ABSTRACT_TYPE(Class, Base)
85 #define TYPE(Class, Base) \
87 #include "clang/AST/TypeNodes.def"
91 TypeLoc() : Ty(nullptr), Data(nullptr) { }
92 TypeLoc(QualType ty, void *opaqueData)
93 : Ty(ty.getAsOpaquePtr()), Data(opaqueData) { }
94 TypeLoc(const Type *ty, void *opaqueData)
95 : Ty(ty), Data(opaqueData) { }
97 TypeLocClass getTypeLocClass() const {
98 if (getType().hasLocalQualifiers()) return Qualified;
99 return (TypeLocClass) getType()->getTypeClass();
102 bool isNull() const { return !Ty; }
103 explicit operator bool() const { return Ty; }
105 /// \brief Returns the size of type source info data block for the given type.
106 static unsigned getFullDataSizeForType(QualType Ty);
108 /// \brief Returns the alignment of type source info data block for
110 static unsigned getLocalAlignmentForType(QualType Ty);
112 /// \brief Get the type for which this source info wrapper provides
114 QualType getType() const {
115 return QualType::getFromOpaquePtr(Ty);
118 const Type *getTypePtr() const {
119 return QualType::getFromOpaquePtr(Ty).getTypePtr();
122 /// \brief Get the pointer where source information is stored.
123 void *getOpaqueData() const {
127 /// \brief Get the begin source location.
128 SourceLocation getBeginLoc() const;
130 /// \brief Get the end source location.
131 SourceLocation getEndLoc() const;
133 /// \brief Get the full source range.
134 SourceRange getSourceRange() const LLVM_READONLY {
135 return SourceRange(getBeginLoc(), getEndLoc());
137 SourceLocation getLocStart() const LLVM_READONLY { return getBeginLoc(); }
138 SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
140 /// \brief Get the local source range.
141 SourceRange getLocalSourceRange() const {
142 return getLocalSourceRangeImpl(*this);
145 /// \brief Returns the size of the type source info data block.
146 unsigned getFullDataSize() const {
147 return getFullDataSizeForType(getType());
150 /// \brief Get the next TypeLoc pointed by this TypeLoc, e.g for "int*" the
151 /// TypeLoc is a PointerLoc and next TypeLoc is for "int".
152 TypeLoc getNextTypeLoc() const {
153 return getNextTypeLocImpl(*this);
156 /// \brief Skips past any qualifiers, if this is qualified.
157 UnqualTypeLoc getUnqualifiedLoc() const; // implemented in this header
159 TypeLoc IgnoreParens() const;
161 /// \brief Find a type with the location of an explicit type qualifier.
163 /// The result, if non-null, will be one of:
166 /// AttributedTypeLoc, for those type attributes that behave as qualifiers
167 TypeLoc findExplicitQualifierLoc() const;
169 /// \brief Initializes this to state that every location in this
170 /// type is the given location.
172 /// This method exists to provide a simple transition for code that
173 /// relies on location-less types.
174 void initialize(ASTContext &Context, SourceLocation Loc) const {
175 initializeImpl(Context, *this, Loc);
178 /// \brief Initializes this by copying its information from another
179 /// TypeLoc of the same type.
180 void initializeFullCopy(TypeLoc Other) {
181 assert(getType() == Other.getType());
185 /// \brief Initializes this by copying its information from another
186 /// TypeLoc of the same type. The given size must be the full data
188 void initializeFullCopy(TypeLoc Other, unsigned Size) {
189 assert(getType() == Other.getType());
190 assert(getFullDataSize() == Size);
194 /// Copies the other type loc into this one.
195 void copy(TypeLoc other);
197 friend bool operator==(const TypeLoc &LHS, const TypeLoc &RHS) {
198 return LHS.Ty == RHS.Ty && LHS.Data == RHS.Data;
201 friend bool operator!=(const TypeLoc &LHS, const TypeLoc &RHS) {
202 return !(LHS == RHS);
205 /// Find the location of the nullability specifier (__nonnull,
206 /// __nullable, or __null_unspecifier), if there is one.
207 SourceLocation findNullabilityLoc() const;
210 static bool isKind(const TypeLoc&) {
214 static void initializeImpl(ASTContext &Context, TypeLoc TL,
216 static TypeLoc getNextTypeLocImpl(TypeLoc TL);
217 static TypeLoc IgnoreParensImpl(TypeLoc TL);
218 static SourceRange getLocalSourceRangeImpl(TypeLoc TL);
221 /// \brief Return the TypeLoc for a type source info.
222 inline TypeLoc TypeSourceInfo::getTypeLoc() const {
223 // TODO: is this alignment already sufficient?
224 return TypeLoc(Ty, const_cast<void*>(static_cast<const void*>(this + 1)));
227 /// \brief Wrapper of type source information for a type with
228 /// no direct qualifiers.
229 class UnqualTypeLoc : public TypeLoc {
232 UnqualTypeLoc(const Type *Ty, void *Data) : TypeLoc(Ty, Data) {}
234 const Type *getTypePtr() const {
235 return reinterpret_cast<const Type*>(Ty);
238 TypeLocClass getTypeLocClass() const {
239 return (TypeLocClass) getTypePtr()->getTypeClass();
243 friend class TypeLoc;
244 static bool isKind(const TypeLoc &TL) {
245 return !TL.getType().hasLocalQualifiers();
249 /// \brief Wrapper of type source information for a type with
250 /// non-trivial direct qualifiers.
252 /// Currently, we intentionally do not provide source location for
254 class QualifiedTypeLoc : public TypeLoc {
256 SourceRange getLocalSourceRange() const {
257 return SourceRange();
260 UnqualTypeLoc getUnqualifiedLoc() const {
262 TypeLoc::getLocalAlignmentForType(QualType(getTypePtr(), 0));
263 uintptr_t dataInt = reinterpret_cast<uintptr_t>(Data);
264 dataInt = llvm::alignTo(dataInt, align);
265 return UnqualTypeLoc(getTypePtr(), reinterpret_cast<void*>(dataInt));
268 /// Initializes the local data of this type source info block to
269 /// provide no information.
270 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
274 void copyLocal(TypeLoc other) {
278 TypeLoc getNextTypeLoc() const {
279 return getUnqualifiedLoc();
282 /// \brief Returns the size of the type source info data block that is
283 /// specific to this type.
284 unsigned getLocalDataSize() const {
285 // In fact, we don't currently preserve any location information
290 /// \brief Returns the alignment of the type source info data block that is
291 /// specific to this type.
292 unsigned getLocalDataAlignment() const {
293 // We don't preserve any location information.
298 friend class TypeLoc;
299 static bool isKind(const TypeLoc &TL) {
300 return TL.getType().hasLocalQualifiers();
304 inline UnqualTypeLoc TypeLoc::getUnqualifiedLoc() const {
305 if (QualifiedTypeLoc Loc = getAs<QualifiedTypeLoc>())
306 return Loc.getUnqualifiedLoc();
307 return castAs<UnqualTypeLoc>();
310 /// A metaprogramming base class for TypeLoc classes which correspond
311 /// to a particular Type subclass. It is accepted for a single
312 /// TypeLoc class to correspond to multiple Type classes.
314 /// \tparam Base a class from which to derive
315 /// \tparam Derived the class deriving from this one
316 /// \tparam TypeClass the concrete Type subclass associated with this
318 /// \tparam LocalData the structure type of local location data for
321 /// TypeLocs with non-constant amounts of local data should override
322 /// getExtraLocalDataSize(); getExtraLocalData() will then point to
323 /// this extra memory.
325 /// TypeLocs with an inner type should define
326 /// QualType getInnerType() const
327 /// and getInnerTypeLoc() will then point to this inner type's
330 /// A word about hierarchies: this template is not designed to be
331 /// derived from multiple times in a hierarchy. It is also not
332 /// designed to be used for classes where subtypes might provide
333 /// different amounts of source information. It should be subclassed
334 /// only at the deepest portion of the hierarchy where all children
335 /// have identical source information; if that's an abstract type,
336 /// then further descendents should inherit from
337 /// InheritingConcreteTypeLoc instead.
338 template <class Base, class Derived, class TypeClass, class LocalData>
339 class ConcreteTypeLoc : public Base {
341 const Derived *asDerived() const {
342 return static_cast<const Derived*>(this);
345 friend class TypeLoc;
346 static bool isKind(const TypeLoc &TL) {
347 return !TL.getType().hasLocalQualifiers() &&
348 Derived::classofType(TL.getTypePtr());
351 static bool classofType(const Type *Ty) {
352 return TypeClass::classof(Ty);
356 unsigned getLocalDataAlignment() const {
357 return std::max(unsigned(alignof(LocalData)),
358 asDerived()->getExtraLocalDataAlignment());
360 unsigned getLocalDataSize() const {
361 unsigned size = sizeof(LocalData);
362 unsigned extraAlign = asDerived()->getExtraLocalDataAlignment();
363 size = llvm::alignTo(size, extraAlign);
364 size += asDerived()->getExtraLocalDataSize();
368 void copyLocal(Derived other) {
369 // Some subclasses have no data to copy.
370 if (asDerived()->getLocalDataSize() == 0) return;
372 // Copy the fixed-sized local data.
373 memcpy(getLocalData(), other.getLocalData(), sizeof(LocalData));
375 // Copy the variable-sized local data. We need to do this
376 // separately because the padding in the source and the padding in
377 // the destination might be different.
378 memcpy(getExtraLocalData(), other.getExtraLocalData(),
379 asDerived()->getExtraLocalDataSize());
382 TypeLoc getNextTypeLoc() const {
383 return getNextTypeLoc(asDerived()->getInnerType());
386 const TypeClass *getTypePtr() const {
387 return cast<TypeClass>(Base::getTypePtr());
391 unsigned getExtraLocalDataSize() const {
395 unsigned getExtraLocalDataAlignment() const {
399 LocalData *getLocalData() const {
400 return static_cast<LocalData*>(Base::Data);
403 /// Gets a pointer past the Info structure; useful for classes with
404 /// local data that can't be captured in the Info (e.g. because it's
405 /// of variable size).
406 void *getExtraLocalData() const {
407 unsigned size = sizeof(LocalData);
408 unsigned extraAlign = asDerived()->getExtraLocalDataAlignment();
409 size = llvm::alignTo(size, extraAlign);
410 return reinterpret_cast<char*>(Base::Data) + size;
413 void *getNonLocalData() const {
414 uintptr_t data = reinterpret_cast<uintptr_t>(Base::Data);
415 data += asDerived()->getLocalDataSize();
416 data = llvm::alignTo(data, getNextTypeAlign());
417 return reinterpret_cast<void*>(data);
420 struct HasNoInnerType {};
421 HasNoInnerType getInnerType() const { return HasNoInnerType(); }
423 TypeLoc getInnerTypeLoc() const {
424 return TypeLoc(asDerived()->getInnerType(), getNonLocalData());
428 unsigned getInnerTypeSize() const {
429 return getInnerTypeSize(asDerived()->getInnerType());
432 unsigned getInnerTypeSize(HasNoInnerType _) const {
436 unsigned getInnerTypeSize(QualType _) const {
437 return getInnerTypeLoc().getFullDataSize();
440 unsigned getNextTypeAlign() const {
441 return getNextTypeAlign(asDerived()->getInnerType());
444 unsigned getNextTypeAlign(HasNoInnerType _) const {
448 unsigned getNextTypeAlign(QualType T) const {
449 return TypeLoc::getLocalAlignmentForType(T);
452 TypeLoc getNextTypeLoc(HasNoInnerType _) const {
456 TypeLoc getNextTypeLoc(QualType T) const {
457 return TypeLoc(T, getNonLocalData());
461 /// A metaprogramming class designed for concrete subtypes of abstract
462 /// types where all subtypes share equivalently-structured source
463 /// information. See the note on ConcreteTypeLoc.
464 template <class Base, class Derived, class TypeClass>
465 class InheritingConcreteTypeLoc : public Base {
466 friend class TypeLoc;
467 static bool classofType(const Type *Ty) {
468 return TypeClass::classof(Ty);
471 static bool isKind(const TypeLoc &TL) {
472 return !TL.getType().hasLocalQualifiers() &&
473 Derived::classofType(TL.getTypePtr());
475 static bool isKind(const UnqualTypeLoc &TL) {
476 return Derived::classofType(TL.getTypePtr());
480 const TypeClass *getTypePtr() const {
481 return cast<TypeClass>(Base::getTypePtr());
486 struct TypeSpecLocInfo {
487 SourceLocation NameLoc;
490 /// \brief A reasonable base class for TypeLocs that correspond to
491 /// types that are written as a type-specifier.
492 class TypeSpecTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
498 LocalDataSize = sizeof(TypeSpecLocInfo),
499 LocalDataAlignment = alignof(TypeSpecLocInfo)
502 SourceLocation getNameLoc() const {
503 return this->getLocalData()->NameLoc;
505 void setNameLoc(SourceLocation Loc) {
506 this->getLocalData()->NameLoc = Loc;
508 SourceRange getLocalSourceRange() const {
509 return SourceRange(getNameLoc(), getNameLoc());
511 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
516 friend class TypeLoc;
517 static bool isKind(const TypeLoc &TL);
521 struct BuiltinLocInfo {
522 SourceRange BuiltinRange;
525 /// \brief Wrapper for source info for builtin types.
526 class BuiltinTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
531 SourceLocation getBuiltinLoc() const {
532 return getLocalData()->BuiltinRange.getBegin();
534 void setBuiltinLoc(SourceLocation Loc) {
535 getLocalData()->BuiltinRange = Loc;
537 void expandBuiltinRange(SourceRange Range) {
538 SourceRange &BuiltinRange = getLocalData()->BuiltinRange;
539 if (!BuiltinRange.getBegin().isValid()) {
540 BuiltinRange = Range;
542 BuiltinRange.setBegin(std::min(Range.getBegin(), BuiltinRange.getBegin()));
543 BuiltinRange.setEnd(std::max(Range.getEnd(), BuiltinRange.getEnd()));
547 SourceLocation getNameLoc() const { return getBuiltinLoc(); }
549 WrittenBuiltinSpecs& getWrittenBuiltinSpecs() {
550 return *(static_cast<WrittenBuiltinSpecs*>(getExtraLocalData()));
552 const WrittenBuiltinSpecs& getWrittenBuiltinSpecs() const {
553 return *(static_cast<WrittenBuiltinSpecs*>(getExtraLocalData()));
556 bool needsExtraLocalData() const {
557 BuiltinType::Kind bk = getTypePtr()->getKind();
558 return (bk >= BuiltinType::UShort && bk <= BuiltinType::UInt128)
559 || (bk >= BuiltinType::Short && bk <= BuiltinType::Float128)
560 || bk == BuiltinType::UChar
561 || bk == BuiltinType::SChar;
564 unsigned getExtraLocalDataSize() const {
565 return needsExtraLocalData() ? sizeof(WrittenBuiltinSpecs) : 0;
568 unsigned getExtraLocalDataAlignment() const {
569 return needsExtraLocalData() ? alignof(WrittenBuiltinSpecs) : 1;
572 SourceRange getLocalSourceRange() const {
573 return getLocalData()->BuiltinRange;
576 TypeSpecifierSign getWrittenSignSpec() const {
577 if (needsExtraLocalData())
578 return static_cast<TypeSpecifierSign>(getWrittenBuiltinSpecs().Sign);
580 return TSS_unspecified;
582 bool hasWrittenSignSpec() const {
583 return getWrittenSignSpec() != TSS_unspecified;
585 void setWrittenSignSpec(TypeSpecifierSign written) {
586 if (needsExtraLocalData())
587 getWrittenBuiltinSpecs().Sign = written;
590 TypeSpecifierWidth getWrittenWidthSpec() const {
591 if (needsExtraLocalData())
592 return static_cast<TypeSpecifierWidth>(getWrittenBuiltinSpecs().Width);
594 return TSW_unspecified;
596 bool hasWrittenWidthSpec() const {
597 return getWrittenWidthSpec() != TSW_unspecified;
599 void setWrittenWidthSpec(TypeSpecifierWidth written) {
600 if (needsExtraLocalData())
601 getWrittenBuiltinSpecs().Width = written;
604 TypeSpecifierType getWrittenTypeSpec() const;
605 bool hasWrittenTypeSpec() const {
606 return getWrittenTypeSpec() != TST_unspecified;
608 void setWrittenTypeSpec(TypeSpecifierType written) {
609 if (needsExtraLocalData())
610 getWrittenBuiltinSpecs().Type = written;
613 bool hasModeAttr() const {
614 if (needsExtraLocalData())
615 return getWrittenBuiltinSpecs().ModeAttr;
619 void setModeAttr(bool written) {
620 if (needsExtraLocalData())
621 getWrittenBuiltinSpecs().ModeAttr = written;
624 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
626 if (needsExtraLocalData()) {
627 WrittenBuiltinSpecs &wbs = getWrittenBuiltinSpecs();
628 wbs.Sign = TSS_unspecified;
629 wbs.Width = TSW_unspecified;
630 wbs.Type = TST_unspecified;
631 wbs.ModeAttr = false;
637 /// \brief Wrapper for source info for typedefs.
638 class TypedefTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
642 TypedefNameDecl *getTypedefNameDecl() const {
643 return getTypePtr()->getDecl();
647 /// \brief Wrapper for source info for injected class names of class
649 class InjectedClassNameTypeLoc :
650 public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
651 InjectedClassNameTypeLoc,
652 InjectedClassNameType> {
654 CXXRecordDecl *getDecl() const {
655 return getTypePtr()->getDecl();
659 /// \brief Wrapper for source info for unresolved typename using decls.
660 class UnresolvedUsingTypeLoc :
661 public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
662 UnresolvedUsingTypeLoc,
663 UnresolvedUsingType> {
665 UnresolvedUsingTypenameDecl *getDecl() const {
666 return getTypePtr()->getDecl();
670 /// \brief Wrapper for source info for tag types. Note that this only
671 /// records source info for the name itself; a type written 'struct foo'
672 /// should be represented as an ElaboratedTypeLoc. We currently
673 /// only do that when C++ is enabled because of the expense of
674 /// creating an ElaboratedType node for so many type references in C.
675 class TagTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
679 TagDecl *getDecl() const { return getTypePtr()->getDecl(); }
681 /// \brief True if the tag was defined in this type specifier.
682 bool isDefinition() const {
683 TagDecl *D = getDecl();
684 return D->isCompleteDefinition() &&
685 (D->getIdentifier() == nullptr || D->getLocation() == getNameLoc());
689 /// \brief Wrapper for source info for record types.
690 class RecordTypeLoc : public InheritingConcreteTypeLoc<TagTypeLoc,
694 RecordDecl *getDecl() const { return getTypePtr()->getDecl(); }
697 /// \brief Wrapper for source info for enum types.
698 class EnumTypeLoc : public InheritingConcreteTypeLoc<TagTypeLoc,
702 EnumDecl *getDecl() const { return getTypePtr()->getDecl(); }
705 /// \brief Wrapper for template type parameters.
706 class TemplateTypeParmTypeLoc :
707 public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
708 TemplateTypeParmTypeLoc,
709 TemplateTypeParmType> {
711 TemplateTypeParmDecl *getDecl() const { return getTypePtr()->getDecl(); }
714 struct ObjCTypeParamTypeLocInfo {
715 SourceLocation NameLoc;
718 /// ProtocolLAngleLoc, ProtocolRAngleLoc, and the source locations for
719 /// protocol qualifiers are stored after Info.
720 class ObjCTypeParamTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
721 ObjCTypeParamTypeLoc,
723 ObjCTypeParamTypeLocInfo> {
724 // SourceLocations are stored after Info, one for each protocol qualifier.
725 SourceLocation *getProtocolLocArray() const {
726 return (SourceLocation*)this->getExtraLocalData() + 2;
730 ObjCTypeParamDecl *getDecl() const { return getTypePtr()->getDecl(); }
732 SourceLocation getNameLoc() const {
733 return this->getLocalData()->NameLoc;
736 void setNameLoc(SourceLocation Loc) {
737 this->getLocalData()->NameLoc = Loc;
740 SourceLocation getProtocolLAngleLoc() const {
741 return getNumProtocols() ?
742 *((SourceLocation*)this->getExtraLocalData()) :
745 void setProtocolLAngleLoc(SourceLocation Loc) {
746 *((SourceLocation*)this->getExtraLocalData()) = Loc;
749 SourceLocation getProtocolRAngleLoc() const {
750 return getNumProtocols() ?
751 *((SourceLocation*)this->getExtraLocalData() + 1) :
754 void setProtocolRAngleLoc(SourceLocation Loc) {
755 *((SourceLocation*)this->getExtraLocalData() + 1) = Loc;
758 unsigned getNumProtocols() const {
759 return this->getTypePtr()->getNumProtocols();
762 SourceLocation getProtocolLoc(unsigned i) const {
763 assert(i < getNumProtocols() && "Index is out of bounds!");
764 return getProtocolLocArray()[i];
766 void setProtocolLoc(unsigned i, SourceLocation Loc) {
767 assert(i < getNumProtocols() && "Index is out of bounds!");
768 getProtocolLocArray()[i] = Loc;
771 ObjCProtocolDecl *getProtocol(unsigned i) const {
772 assert(i < getNumProtocols() && "Index is out of bounds!");
773 return *(this->getTypePtr()->qual_begin() + i);
776 ArrayRef<SourceLocation> getProtocolLocs() const {
777 return llvm::makeArrayRef(getProtocolLocArray(), getNumProtocols());
780 void initializeLocal(ASTContext &Context, SourceLocation Loc);
782 unsigned getExtraLocalDataSize() const {
783 if (!this->getNumProtocols()) return 0;
784 // When there are protocol qualifers, we have LAngleLoc and RAngleLoc
786 return (this->getNumProtocols() + 2) * sizeof(SourceLocation) ;
788 unsigned getExtraLocalDataAlignment() const {
789 return alignof(SourceLocation);
791 SourceRange getLocalSourceRange() const {
792 SourceLocation start = getNameLoc();
793 SourceLocation end = getProtocolRAngleLoc();
794 if (end.isInvalid()) return SourceRange(start, start);
795 return SourceRange(start, end);
799 /// \brief Wrapper for substituted template type parameters.
800 class SubstTemplateTypeParmTypeLoc :
801 public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
802 SubstTemplateTypeParmTypeLoc,
803 SubstTemplateTypeParmType> {
806 /// \brief Wrapper for substituted template type parameters.
807 class SubstTemplateTypeParmPackTypeLoc :
808 public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
809 SubstTemplateTypeParmPackTypeLoc,
810 SubstTemplateTypeParmPackType> {
813 struct AttributedLocInfo {
817 /// A raw SourceLocation.
818 unsigned EnumOperandLoc;
821 SourceRange OperandParens;
823 SourceLocation AttrLoc;
826 /// \brief Type source information for an attributed type.
827 class AttributedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
832 AttributedType::Kind getAttrKind() const {
833 return getTypePtr()->getAttrKind();
836 bool hasAttrExprOperand() const {
837 return (getAttrKind() >= AttributedType::FirstExprOperandKind &&
838 getAttrKind() <= AttributedType::LastExprOperandKind);
841 bool hasAttrEnumOperand() const {
842 return (getAttrKind() >= AttributedType::FirstEnumOperandKind &&
843 getAttrKind() <= AttributedType::LastEnumOperandKind);
846 bool hasAttrOperand() const {
847 return hasAttrExprOperand() || hasAttrEnumOperand();
850 bool isQualifier() const {
851 return getTypePtr()->isQualifier();
854 /// The modified type, which is generally canonically different from
855 /// the attribute type.
856 /// int main(int, char**) __attribute__((noreturn))
857 /// ~~~ ~~~~~~~~~~~~~
858 TypeLoc getModifiedLoc() const {
859 return getInnerTypeLoc();
862 /// The location of the attribute name, i.e.
863 /// __attribute__((regparm(1000)))
865 SourceLocation getAttrNameLoc() const {
866 return getLocalData()->AttrLoc;
868 void setAttrNameLoc(SourceLocation loc) {
869 getLocalData()->AttrLoc = loc;
872 /// The attribute's expression operand, if it has one.
873 /// void *cur_thread __attribute__((address_space(21)))
875 Expr *getAttrExprOperand() const {
876 assert(hasAttrExprOperand());
877 return getLocalData()->ExprOperand;
879 void setAttrExprOperand(Expr *e) {
880 assert(hasAttrExprOperand());
881 getLocalData()->ExprOperand = e;
884 /// The location of the attribute's enumerated operand, if it has one.
885 /// void * __attribute__((objc_gc(weak)))
887 SourceLocation getAttrEnumOperandLoc() const {
888 assert(hasAttrEnumOperand());
889 return SourceLocation::getFromRawEncoding(getLocalData()->EnumOperandLoc);
891 void setAttrEnumOperandLoc(SourceLocation loc) {
892 assert(hasAttrEnumOperand());
893 getLocalData()->EnumOperandLoc = loc.getRawEncoding();
896 /// The location of the parentheses around the operand, if there is
898 /// void * __attribute__((objc_gc(weak)))
900 SourceRange getAttrOperandParensRange() const {
901 assert(hasAttrOperand());
902 return getLocalData()->OperandParens;
904 void setAttrOperandParensRange(SourceRange range) {
905 assert(hasAttrOperand());
906 getLocalData()->OperandParens = range;
909 SourceRange getLocalSourceRange() const {
910 // Note that this does *not* include the range of the attribute
912 // __attribute__((foo(bar)))
913 // ^~~~~~~~~~~~~~~ ~~
917 // That enclosure doesn't necessarily belong to a single attribute
919 SourceRange range(getAttrNameLoc());
920 if (hasAttrOperand())
921 range.setEnd(getAttrOperandParensRange().getEnd());
925 void initializeLocal(ASTContext &Context, SourceLocation loc) {
927 if (hasAttrExprOperand()) {
928 setAttrOperandParensRange(SourceRange(loc));
929 setAttrExprOperand(nullptr);
930 } else if (hasAttrEnumOperand()) {
931 setAttrOperandParensRange(SourceRange(loc));
932 setAttrEnumOperandLoc(loc);
936 QualType getInnerType() const {
937 return getTypePtr()->getModifiedType();
942 struct ObjCObjectTypeLocInfo {
943 SourceLocation TypeArgsLAngleLoc;
944 SourceLocation TypeArgsRAngleLoc;
945 SourceLocation ProtocolLAngleLoc;
946 SourceLocation ProtocolRAngleLoc;
947 bool HasBaseTypeAsWritten;
950 // A helper class for defining ObjC TypeLocs that can qualified with
953 // TypeClass basically has to be either ObjCInterfaceType or
954 // ObjCObjectPointerType.
955 class ObjCObjectTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
958 ObjCObjectTypeLocInfo> {
959 // TypeSourceInfo*'s are stored after Info, one for each type argument.
960 TypeSourceInfo **getTypeArgLocArray() const {
961 return (TypeSourceInfo**)this->getExtraLocalData();
964 // SourceLocations are stored after the type argument information, one for
966 SourceLocation *getProtocolLocArray() const {
967 return (SourceLocation*)(getTypeArgLocArray() + getNumTypeArgs());
971 SourceLocation getTypeArgsLAngleLoc() const {
972 return this->getLocalData()->TypeArgsLAngleLoc;
974 void setTypeArgsLAngleLoc(SourceLocation Loc) {
975 this->getLocalData()->TypeArgsLAngleLoc = Loc;
978 SourceLocation getTypeArgsRAngleLoc() const {
979 return this->getLocalData()->TypeArgsRAngleLoc;
981 void setTypeArgsRAngleLoc(SourceLocation Loc) {
982 this->getLocalData()->TypeArgsRAngleLoc = Loc;
985 unsigned getNumTypeArgs() const {
986 return this->getTypePtr()->getTypeArgsAsWritten().size();
989 TypeSourceInfo *getTypeArgTInfo(unsigned i) const {
990 assert(i < getNumTypeArgs() && "Index is out of bounds!");
991 return getTypeArgLocArray()[i];
994 void setTypeArgTInfo(unsigned i, TypeSourceInfo *TInfo) {
995 assert(i < getNumTypeArgs() && "Index is out of bounds!");
996 getTypeArgLocArray()[i] = TInfo;
999 SourceLocation getProtocolLAngleLoc() const {
1000 return this->getLocalData()->ProtocolLAngleLoc;
1002 void setProtocolLAngleLoc(SourceLocation Loc) {
1003 this->getLocalData()->ProtocolLAngleLoc = Loc;
1006 SourceLocation getProtocolRAngleLoc() const {
1007 return this->getLocalData()->ProtocolRAngleLoc;
1009 void setProtocolRAngleLoc(SourceLocation Loc) {
1010 this->getLocalData()->ProtocolRAngleLoc = Loc;
1013 unsigned getNumProtocols() const {
1014 return this->getTypePtr()->getNumProtocols();
1017 SourceLocation getProtocolLoc(unsigned i) const {
1018 assert(i < getNumProtocols() && "Index is out of bounds!");
1019 return getProtocolLocArray()[i];
1021 void setProtocolLoc(unsigned i, SourceLocation Loc) {
1022 assert(i < getNumProtocols() && "Index is out of bounds!");
1023 getProtocolLocArray()[i] = Loc;
1026 ObjCProtocolDecl *getProtocol(unsigned i) const {
1027 assert(i < getNumProtocols() && "Index is out of bounds!");
1028 return *(this->getTypePtr()->qual_begin() + i);
1032 ArrayRef<SourceLocation> getProtocolLocs() const {
1033 return llvm::makeArrayRef(getProtocolLocArray(), getNumProtocols());
1036 bool hasBaseTypeAsWritten() const {
1037 return getLocalData()->HasBaseTypeAsWritten;
1040 void setHasBaseTypeAsWritten(bool HasBaseType) {
1041 getLocalData()->HasBaseTypeAsWritten = HasBaseType;
1044 TypeLoc getBaseLoc() const {
1045 return getInnerTypeLoc();
1048 SourceRange getLocalSourceRange() const {
1049 SourceLocation start = getTypeArgsLAngleLoc();
1050 if (start.isInvalid())
1051 start = getProtocolLAngleLoc();
1052 SourceLocation end = getProtocolRAngleLoc();
1053 if (end.isInvalid())
1054 end = getTypeArgsRAngleLoc();
1055 return SourceRange(start, end);
1058 void initializeLocal(ASTContext &Context, SourceLocation Loc);
1060 unsigned getExtraLocalDataSize() const {
1061 return this->getNumTypeArgs() * sizeof(TypeSourceInfo *)
1062 + this->getNumProtocols() * sizeof(SourceLocation);
1065 unsigned getExtraLocalDataAlignment() const {
1066 static_assert(alignof(ObjCObjectTypeLoc) >= alignof(TypeSourceInfo *),
1067 "not enough alignment for tail-allocated data");
1068 return alignof(TypeSourceInfo *);
1071 QualType getInnerType() const {
1072 return getTypePtr()->getBaseType();
1077 struct ObjCInterfaceLocInfo {
1078 SourceLocation NameLoc;
1079 SourceLocation NameEndLoc;
1082 /// \brief Wrapper for source info for ObjC interfaces.
1083 class ObjCInterfaceTypeLoc : public ConcreteTypeLoc<ObjCObjectTypeLoc,
1084 ObjCInterfaceTypeLoc,
1086 ObjCInterfaceLocInfo> {
1088 ObjCInterfaceDecl *getIFaceDecl() const {
1089 return getTypePtr()->getDecl();
1092 SourceLocation getNameLoc() const {
1093 return getLocalData()->NameLoc;
1096 void setNameLoc(SourceLocation Loc) {
1097 getLocalData()->NameLoc = Loc;
1100 SourceRange getLocalSourceRange() const {
1101 return SourceRange(getNameLoc(), getNameEndLoc());
1104 SourceLocation getNameEndLoc() const {
1105 return getLocalData()->NameEndLoc;
1108 void setNameEndLoc(SourceLocation Loc) {
1109 getLocalData()->NameEndLoc = Loc;
1112 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1118 struct ParenLocInfo {
1119 SourceLocation LParenLoc;
1120 SourceLocation RParenLoc;
1124 : public ConcreteTypeLoc<UnqualTypeLoc, ParenTypeLoc, ParenType,
1127 SourceLocation getLParenLoc() const {
1128 return this->getLocalData()->LParenLoc;
1130 SourceLocation getRParenLoc() const {
1131 return this->getLocalData()->RParenLoc;
1133 void setLParenLoc(SourceLocation Loc) {
1134 this->getLocalData()->LParenLoc = Loc;
1136 void setRParenLoc(SourceLocation Loc) {
1137 this->getLocalData()->RParenLoc = Loc;
1140 SourceRange getLocalSourceRange() const {
1141 return SourceRange(getLParenLoc(), getRParenLoc());
1144 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1149 TypeLoc getInnerLoc() const {
1150 return getInnerTypeLoc();
1153 QualType getInnerType() const {
1154 return this->getTypePtr()->getInnerType();
1158 inline TypeLoc TypeLoc::IgnoreParens() const {
1159 if (ParenTypeLoc::isKind(*this))
1160 return IgnoreParensImpl(*this);
1165 struct AdjustedLocInfo { }; // Nothing.
1167 class AdjustedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, AdjustedTypeLoc,
1168 AdjustedType, AdjustedLocInfo> {
1170 TypeLoc getOriginalLoc() const {
1171 return getInnerTypeLoc();
1174 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1178 QualType getInnerType() const {
1179 // The inner type is the undecayed type, since that's what we have source
1180 // location information for.
1181 return getTypePtr()->getOriginalType();
1184 SourceRange getLocalSourceRange() const {
1185 return SourceRange();
1188 unsigned getLocalDataSize() const {
1189 // sizeof(AdjustedLocInfo) is 1, but we don't need its address to be unique
1190 // anyway. TypeLocBuilder can't handle data sizes of 1.
1191 return 0; // No data.
1195 /// \brief Wrapper for source info for pointers decayed from arrays and
1197 class DecayedTypeLoc : public InheritingConcreteTypeLoc<
1198 AdjustedTypeLoc, DecayedTypeLoc, DecayedType> {
1201 struct PointerLikeLocInfo {
1202 SourceLocation StarLoc;
1205 /// A base class for
1206 template <class Derived, class TypeClass, class LocalData = PointerLikeLocInfo>
1207 class PointerLikeTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, Derived,
1208 TypeClass, LocalData> {
1210 SourceLocation getSigilLoc() const {
1211 return this->getLocalData()->StarLoc;
1213 void setSigilLoc(SourceLocation Loc) {
1214 this->getLocalData()->StarLoc = Loc;
1217 TypeLoc getPointeeLoc() const {
1218 return this->getInnerTypeLoc();
1221 SourceRange getLocalSourceRange() const {
1222 return SourceRange(getSigilLoc(), getSigilLoc());
1225 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1229 QualType getInnerType() const {
1230 return this->getTypePtr()->getPointeeType();
1235 /// \brief Wrapper for source info for pointers.
1236 class PointerTypeLoc : public PointerLikeTypeLoc<PointerTypeLoc,
1239 SourceLocation getStarLoc() const {
1240 return getSigilLoc();
1242 void setStarLoc(SourceLocation Loc) {
1248 /// \brief Wrapper for source info for block pointers.
1249 class BlockPointerTypeLoc : public PointerLikeTypeLoc<BlockPointerTypeLoc,
1252 SourceLocation getCaretLoc() const {
1253 return getSigilLoc();
1255 void setCaretLoc(SourceLocation Loc) {
1260 struct MemberPointerLocInfo : public PointerLikeLocInfo {
1261 TypeSourceInfo *ClassTInfo;
1264 /// \brief Wrapper for source info for member pointers.
1265 class MemberPointerTypeLoc : public PointerLikeTypeLoc<MemberPointerTypeLoc,
1267 MemberPointerLocInfo> {
1269 SourceLocation getStarLoc() const {
1270 return getSigilLoc();
1272 void setStarLoc(SourceLocation Loc) {
1276 const Type *getClass() const {
1277 return getTypePtr()->getClass();
1279 TypeSourceInfo *getClassTInfo() const {
1280 return getLocalData()->ClassTInfo;
1282 void setClassTInfo(TypeSourceInfo* TI) {
1283 getLocalData()->ClassTInfo = TI;
1286 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1288 setClassTInfo(nullptr);
1291 SourceRange getLocalSourceRange() const {
1292 if (TypeSourceInfo *TI = getClassTInfo())
1293 return SourceRange(TI->getTypeLoc().getBeginLoc(), getStarLoc());
1295 return SourceRange(getStarLoc());
1299 /// Wraps an ObjCPointerType with source location information.
1300 class ObjCObjectPointerTypeLoc :
1301 public PointerLikeTypeLoc<ObjCObjectPointerTypeLoc,
1302 ObjCObjectPointerType> {
1304 SourceLocation getStarLoc() const {
1305 return getSigilLoc();
1308 void setStarLoc(SourceLocation Loc) {
1314 class ReferenceTypeLoc : public PointerLikeTypeLoc<ReferenceTypeLoc,
1317 QualType getInnerType() const {
1318 return getTypePtr()->getPointeeTypeAsWritten();
1322 class LValueReferenceTypeLoc :
1323 public InheritingConcreteTypeLoc<ReferenceTypeLoc,
1324 LValueReferenceTypeLoc,
1325 LValueReferenceType> {
1327 SourceLocation getAmpLoc() const {
1328 return getSigilLoc();
1330 void setAmpLoc(SourceLocation Loc) {
1335 class RValueReferenceTypeLoc :
1336 public InheritingConcreteTypeLoc<ReferenceTypeLoc,
1337 RValueReferenceTypeLoc,
1338 RValueReferenceType> {
1340 SourceLocation getAmpAmpLoc() const {
1341 return getSigilLoc();
1343 void setAmpAmpLoc(SourceLocation Loc) {
1349 struct FunctionLocInfo {
1350 SourceLocation LocalRangeBegin;
1351 SourceLocation LParenLoc;
1352 SourceLocation RParenLoc;
1353 SourceLocation LocalRangeEnd;
1356 /// \brief Wrapper for source info for functions.
1357 class FunctionTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
1361 bool hasExceptionSpec() const {
1362 if (auto *FPT = dyn_cast<FunctionProtoType>(getTypePtr())) {
1363 return FPT->hasExceptionSpec();
1368 SourceRange *getExceptionSpecRangePtr() const {
1369 assert(hasExceptionSpec() && "No exception spec range");
1370 // After the Info comes the ParmVarDecl array, and after that comes the
1371 // exception specification information.
1372 return (SourceRange *)(getParmArray() + getNumParams());
1375 SourceLocation getLocalRangeBegin() const {
1376 return getLocalData()->LocalRangeBegin;
1378 void setLocalRangeBegin(SourceLocation L) {
1379 getLocalData()->LocalRangeBegin = L;
1382 SourceLocation getLocalRangeEnd() const {
1383 return getLocalData()->LocalRangeEnd;
1385 void setLocalRangeEnd(SourceLocation L) {
1386 getLocalData()->LocalRangeEnd = L;
1389 SourceLocation getLParenLoc() const {
1390 return this->getLocalData()->LParenLoc;
1392 void setLParenLoc(SourceLocation Loc) {
1393 this->getLocalData()->LParenLoc = Loc;
1396 SourceLocation getRParenLoc() const {
1397 return this->getLocalData()->RParenLoc;
1399 void setRParenLoc(SourceLocation Loc) {
1400 this->getLocalData()->RParenLoc = Loc;
1403 SourceRange getParensRange() const {
1404 return SourceRange(getLParenLoc(), getRParenLoc());
1407 SourceRange getExceptionSpecRange() const {
1408 if (hasExceptionSpec())
1409 return *getExceptionSpecRangePtr();
1410 return SourceRange();
1412 void setExceptionSpecRange(SourceRange R) {
1413 if (hasExceptionSpec())
1414 *getExceptionSpecRangePtr() = R;
1417 ArrayRef<ParmVarDecl *> getParams() const {
1418 return llvm::makeArrayRef(getParmArray(), getNumParams());
1421 // ParmVarDecls* are stored after Info, one for each parameter.
1422 ParmVarDecl **getParmArray() const {
1423 return (ParmVarDecl**) getExtraLocalData();
1426 unsigned getNumParams() const {
1427 if (isa<FunctionNoProtoType>(getTypePtr()))
1429 return cast<FunctionProtoType>(getTypePtr())->getNumParams();
1431 ParmVarDecl *getParam(unsigned i) const { return getParmArray()[i]; }
1432 void setParam(unsigned i, ParmVarDecl *VD) { getParmArray()[i] = VD; }
1434 TypeLoc getReturnLoc() const {
1435 return getInnerTypeLoc();
1438 SourceRange getLocalSourceRange() const {
1439 return SourceRange(getLocalRangeBegin(), getLocalRangeEnd());
1442 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1443 setLocalRangeBegin(Loc);
1446 setLocalRangeEnd(Loc);
1447 for (unsigned i = 0, e = getNumParams(); i != e; ++i)
1448 setParam(i, nullptr);
1449 if (hasExceptionSpec())
1450 setExceptionSpecRange(Loc);
1453 /// \brief Returns the size of the type source info data block that is
1454 /// specific to this type.
1455 unsigned getExtraLocalDataSize() const {
1456 unsigned ExceptSpecSize = hasExceptionSpec() ? sizeof(SourceRange) : 0;
1457 return (getNumParams() * sizeof(ParmVarDecl *)) + ExceptSpecSize;
1460 unsigned getExtraLocalDataAlignment() const { return alignof(ParmVarDecl *); }
1462 QualType getInnerType() const { return getTypePtr()->getReturnType(); }
1465 class FunctionProtoTypeLoc :
1466 public InheritingConcreteTypeLoc<FunctionTypeLoc,
1467 FunctionProtoTypeLoc,
1468 FunctionProtoType> {
1471 class FunctionNoProtoTypeLoc :
1472 public InheritingConcreteTypeLoc<FunctionTypeLoc,
1473 FunctionNoProtoTypeLoc,
1474 FunctionNoProtoType> {
1478 struct ArrayLocInfo {
1479 SourceLocation LBracketLoc, RBracketLoc;
1483 /// \brief Wrapper for source info for arrays.
1484 class ArrayTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
1489 SourceLocation getLBracketLoc() const {
1490 return getLocalData()->LBracketLoc;
1492 void setLBracketLoc(SourceLocation Loc) {
1493 getLocalData()->LBracketLoc = Loc;
1496 SourceLocation getRBracketLoc() const {
1497 return getLocalData()->RBracketLoc;
1499 void setRBracketLoc(SourceLocation Loc) {
1500 getLocalData()->RBracketLoc = Loc;
1503 SourceRange getBracketsRange() const {
1504 return SourceRange(getLBracketLoc(), getRBracketLoc());
1507 Expr *getSizeExpr() const {
1508 return getLocalData()->Size;
1510 void setSizeExpr(Expr *Size) {
1511 getLocalData()->Size = Size;
1514 TypeLoc getElementLoc() const {
1515 return getInnerTypeLoc();
1518 SourceRange getLocalSourceRange() const {
1519 return SourceRange(getLBracketLoc(), getRBracketLoc());
1522 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1523 setLBracketLoc(Loc);
1524 setRBracketLoc(Loc);
1525 setSizeExpr(nullptr);
1528 QualType getInnerType() const { return getTypePtr()->getElementType(); }
1531 class ConstantArrayTypeLoc :
1532 public InheritingConcreteTypeLoc<ArrayTypeLoc,
1533 ConstantArrayTypeLoc,
1534 ConstantArrayType> {
1537 class IncompleteArrayTypeLoc :
1538 public InheritingConcreteTypeLoc<ArrayTypeLoc,
1539 IncompleteArrayTypeLoc,
1540 IncompleteArrayType> {
1543 class DependentSizedArrayTypeLoc :
1544 public InheritingConcreteTypeLoc<ArrayTypeLoc,
1545 DependentSizedArrayTypeLoc,
1546 DependentSizedArrayType> {
1548 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1549 ArrayTypeLoc::initializeLocal(Context, Loc);
1550 setSizeExpr(getTypePtr()->getSizeExpr());
1554 class VariableArrayTypeLoc :
1555 public InheritingConcreteTypeLoc<ArrayTypeLoc,
1556 VariableArrayTypeLoc,
1557 VariableArrayType> {
1561 // Location information for a TemplateName. Rudimentary for now.
1562 struct TemplateNameLocInfo {
1563 SourceLocation NameLoc;
1566 struct TemplateSpecializationLocInfo : TemplateNameLocInfo {
1567 SourceLocation TemplateKWLoc;
1568 SourceLocation LAngleLoc;
1569 SourceLocation RAngleLoc;
1572 class TemplateSpecializationTypeLoc :
1573 public ConcreteTypeLoc<UnqualTypeLoc,
1574 TemplateSpecializationTypeLoc,
1575 TemplateSpecializationType,
1576 TemplateSpecializationLocInfo> {
1578 SourceLocation getTemplateKeywordLoc() const {
1579 return getLocalData()->TemplateKWLoc;
1581 void setTemplateKeywordLoc(SourceLocation Loc) {
1582 getLocalData()->TemplateKWLoc = Loc;
1585 SourceLocation getLAngleLoc() const {
1586 return getLocalData()->LAngleLoc;
1588 void setLAngleLoc(SourceLocation Loc) {
1589 getLocalData()->LAngleLoc = Loc;
1592 SourceLocation getRAngleLoc() const {
1593 return getLocalData()->RAngleLoc;
1595 void setRAngleLoc(SourceLocation Loc) {
1596 getLocalData()->RAngleLoc = Loc;
1599 unsigned getNumArgs() const {
1600 return getTypePtr()->getNumArgs();
1602 void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) {
1603 getArgInfos()[i] = AI;
1605 TemplateArgumentLocInfo getArgLocInfo(unsigned i) const {
1606 return getArgInfos()[i];
1609 TemplateArgumentLoc getArgLoc(unsigned i) const {
1610 return TemplateArgumentLoc(getTypePtr()->getArg(i), getArgLocInfo(i));
1613 SourceLocation getTemplateNameLoc() const {
1614 return getLocalData()->NameLoc;
1616 void setTemplateNameLoc(SourceLocation Loc) {
1617 getLocalData()->NameLoc = Loc;
1620 /// \brief - Copy the location information from the given info.
1621 void copy(TemplateSpecializationTypeLoc Loc) {
1622 unsigned size = getFullDataSize();
1623 assert(size == Loc.getFullDataSize());
1625 // We're potentially copying Expr references here. We don't
1626 // bother retaining them because TypeSourceInfos live forever, so
1627 // as long as the Expr was retained when originally written into
1628 // the TypeLoc, we're okay.
1629 memcpy(Data, Loc.Data, size);
1632 SourceRange getLocalSourceRange() const {
1633 if (getTemplateKeywordLoc().isValid())
1634 return SourceRange(getTemplateKeywordLoc(), getRAngleLoc());
1636 return SourceRange(getTemplateNameLoc(), getRAngleLoc());
1639 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1640 setTemplateKeywordLoc(Loc);
1641 setTemplateNameLoc(Loc);
1644 initializeArgLocs(Context, getNumArgs(), getTypePtr()->getArgs(),
1645 getArgInfos(), Loc);
1648 static void initializeArgLocs(ASTContext &Context, unsigned NumArgs,
1649 const TemplateArgument *Args,
1650 TemplateArgumentLocInfo *ArgInfos,
1651 SourceLocation Loc);
1653 unsigned getExtraLocalDataSize() const {
1654 return getNumArgs() * sizeof(TemplateArgumentLocInfo);
1657 unsigned getExtraLocalDataAlignment() const {
1658 return alignof(TemplateArgumentLocInfo);
1662 TemplateArgumentLocInfo *getArgInfos() const {
1663 return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData());
1667 //===----------------------------------------------------------------------===//
1669 // All of these need proper implementations.
1671 //===----------------------------------------------------------------------===//
1673 // FIXME: size expression and attribute locations (or keyword if we
1674 // ever fully support altivec syntax).
1675 class VectorTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
1680 // FIXME: size expression and attribute locations.
1681 class ExtVectorTypeLoc : public InheritingConcreteTypeLoc<VectorTypeLoc,
1686 // FIXME: attribute locations.
1687 // For some reason, this isn't a subtype of VectorType.
1688 class DependentSizedExtVectorTypeLoc :
1689 public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
1690 DependentSizedExtVectorTypeLoc,
1691 DependentSizedExtVectorType> {
1694 // FIXME: location of the '_Complex' keyword.
1695 class ComplexTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
1700 struct TypeofLocInfo {
1701 SourceLocation TypeofLoc;
1702 SourceLocation LParenLoc;
1703 SourceLocation RParenLoc;
1706 struct TypeOfExprTypeLocInfo : public TypeofLocInfo {
1709 struct TypeOfTypeLocInfo : public TypeofLocInfo {
1710 TypeSourceInfo* UnderlyingTInfo;
1713 template <class Derived, class TypeClass, class LocalData = TypeofLocInfo>
1714 class TypeofLikeTypeLoc
1715 : public ConcreteTypeLoc<UnqualTypeLoc, Derived, TypeClass, LocalData> {
1717 SourceLocation getTypeofLoc() const {
1718 return this->getLocalData()->TypeofLoc;
1720 void setTypeofLoc(SourceLocation Loc) {
1721 this->getLocalData()->TypeofLoc = Loc;
1724 SourceLocation getLParenLoc() const {
1725 return this->getLocalData()->LParenLoc;
1727 void setLParenLoc(SourceLocation Loc) {
1728 this->getLocalData()->LParenLoc = Loc;
1731 SourceLocation getRParenLoc() const {
1732 return this->getLocalData()->RParenLoc;
1734 void setRParenLoc(SourceLocation Loc) {
1735 this->getLocalData()->RParenLoc = Loc;
1738 SourceRange getParensRange() const {
1739 return SourceRange(getLParenLoc(), getRParenLoc());
1741 void setParensRange(SourceRange range) {
1742 setLParenLoc(range.getBegin());
1743 setRParenLoc(range.getEnd());
1746 SourceRange getLocalSourceRange() const {
1747 return SourceRange(getTypeofLoc(), getRParenLoc());
1750 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1757 class TypeOfExprTypeLoc : public TypeofLikeTypeLoc<TypeOfExprTypeLoc,
1759 TypeOfExprTypeLocInfo> {
1761 Expr* getUnderlyingExpr() const {
1762 return getTypePtr()->getUnderlyingExpr();
1764 // Reimplemented to account for GNU/C++ extension
1765 // typeof unary-expression
1766 // where there are no parentheses.
1767 SourceRange getLocalSourceRange() const;
1771 : public TypeofLikeTypeLoc<TypeOfTypeLoc, TypeOfType, TypeOfTypeLocInfo> {
1773 QualType getUnderlyingType() const {
1774 return this->getTypePtr()->getUnderlyingType();
1776 TypeSourceInfo* getUnderlyingTInfo() const {
1777 return this->getLocalData()->UnderlyingTInfo;
1779 void setUnderlyingTInfo(TypeSourceInfo* TI) const {
1780 this->getLocalData()->UnderlyingTInfo = TI;
1783 void initializeLocal(ASTContext &Context, SourceLocation Loc);
1786 // FIXME: location of the 'decltype' and parens.
1787 class DecltypeTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
1791 Expr *getUnderlyingExpr() const { return getTypePtr()->getUnderlyingExpr(); }
1794 struct UnaryTransformTypeLocInfo {
1795 // FIXME: While there's only one unary transform right now, future ones may
1796 // need different representations
1797 SourceLocation KWLoc, LParenLoc, RParenLoc;
1798 TypeSourceInfo *UnderlyingTInfo;
1801 class UnaryTransformTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
1802 UnaryTransformTypeLoc,
1804 UnaryTransformTypeLocInfo> {
1806 SourceLocation getKWLoc() const { return getLocalData()->KWLoc; }
1807 void setKWLoc(SourceLocation Loc) { getLocalData()->KWLoc = Loc; }
1809 SourceLocation getLParenLoc() const { return getLocalData()->LParenLoc; }
1810 void setLParenLoc(SourceLocation Loc) { getLocalData()->LParenLoc = Loc; }
1812 SourceLocation getRParenLoc() const { return getLocalData()->RParenLoc; }
1813 void setRParenLoc(SourceLocation Loc) { getLocalData()->RParenLoc = Loc; }
1815 TypeSourceInfo* getUnderlyingTInfo() const {
1816 return getLocalData()->UnderlyingTInfo;
1818 void setUnderlyingTInfo(TypeSourceInfo *TInfo) {
1819 getLocalData()->UnderlyingTInfo = TInfo;
1822 SourceRange getLocalSourceRange() const {
1823 return SourceRange(getKWLoc(), getRParenLoc());
1826 SourceRange getParensRange() const {
1827 return SourceRange(getLParenLoc(), getRParenLoc());
1829 void setParensRange(SourceRange Range) {
1830 setLParenLoc(Range.getBegin());
1831 setRParenLoc(Range.getEnd());
1834 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1841 class DeducedTypeLoc
1842 : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, DeducedTypeLoc,
1846 : public InheritingConcreteTypeLoc<DeducedTypeLoc, AutoTypeLoc, AutoType> {
1849 class DeducedTemplateSpecializationTypeLoc
1850 : public InheritingConcreteTypeLoc<DeducedTypeLoc,
1851 DeducedTemplateSpecializationTypeLoc,
1852 DeducedTemplateSpecializationType> {
1854 SourceLocation getTemplateNameLoc() const {
1855 return getNameLoc();
1857 void setTemplateNameLoc(SourceLocation Loc) {
1862 struct ElaboratedLocInfo {
1863 SourceLocation ElaboratedKWLoc;
1864 /// \brief Data associated with the nested-name-specifier location.
1865 void *QualifierData;
1868 class ElaboratedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
1871 ElaboratedLocInfo> {
1873 SourceLocation getElaboratedKeywordLoc() const {
1874 return this->getLocalData()->ElaboratedKWLoc;
1876 void setElaboratedKeywordLoc(SourceLocation Loc) {
1877 this->getLocalData()->ElaboratedKWLoc = Loc;
1880 NestedNameSpecifierLoc getQualifierLoc() const {
1881 return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
1882 getLocalData()->QualifierData);
1885 void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
1886 assert(QualifierLoc.getNestedNameSpecifier()
1887 == getTypePtr()->getQualifier() &&
1888 "Inconsistent nested-name-specifier pointer");
1889 getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
1892 SourceRange getLocalSourceRange() const {
1893 if (getElaboratedKeywordLoc().isValid())
1894 if (getQualifierLoc())
1895 return SourceRange(getElaboratedKeywordLoc(),
1896 getQualifierLoc().getEndLoc());
1898 return SourceRange(getElaboratedKeywordLoc());
1900 return getQualifierLoc().getSourceRange();
1903 void initializeLocal(ASTContext &Context, SourceLocation Loc);
1905 TypeLoc getNamedTypeLoc() const {
1906 return getInnerTypeLoc();
1909 QualType getInnerType() const {
1910 return getTypePtr()->getNamedType();
1913 void copy(ElaboratedTypeLoc Loc) {
1914 unsigned size = getFullDataSize();
1915 assert(size == Loc.getFullDataSize());
1916 memcpy(Data, Loc.Data, size);
1920 // This is exactly the structure of an ElaboratedTypeLoc whose inner
1921 // type is some sort of TypeDeclTypeLoc.
1922 struct DependentNameLocInfo : ElaboratedLocInfo {
1923 SourceLocation NameLoc;
1926 class DependentNameTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
1927 DependentNameTypeLoc,
1929 DependentNameLocInfo> {
1931 SourceLocation getElaboratedKeywordLoc() const {
1932 return this->getLocalData()->ElaboratedKWLoc;
1934 void setElaboratedKeywordLoc(SourceLocation Loc) {
1935 this->getLocalData()->ElaboratedKWLoc = Loc;
1938 NestedNameSpecifierLoc getQualifierLoc() const {
1939 return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
1940 getLocalData()->QualifierData);
1943 void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
1944 assert(QualifierLoc.getNestedNameSpecifier()
1945 == getTypePtr()->getQualifier() &&
1946 "Inconsistent nested-name-specifier pointer");
1947 getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
1950 SourceLocation getNameLoc() const {
1951 return this->getLocalData()->NameLoc;
1953 void setNameLoc(SourceLocation Loc) {
1954 this->getLocalData()->NameLoc = Loc;
1957 SourceRange getLocalSourceRange() const {
1958 if (getElaboratedKeywordLoc().isValid())
1959 return SourceRange(getElaboratedKeywordLoc(), getNameLoc());
1961 return SourceRange(getQualifierLoc().getBeginLoc(), getNameLoc());
1964 void copy(DependentNameTypeLoc Loc) {
1965 unsigned size = getFullDataSize();
1966 assert(size == Loc.getFullDataSize());
1967 memcpy(Data, Loc.Data, size);
1970 void initializeLocal(ASTContext &Context, SourceLocation Loc);
1973 struct DependentTemplateSpecializationLocInfo : DependentNameLocInfo {
1974 SourceLocation TemplateKWLoc;
1975 SourceLocation LAngleLoc;
1976 SourceLocation RAngleLoc;
1977 // followed by a TemplateArgumentLocInfo[]
1980 class DependentTemplateSpecializationTypeLoc :
1981 public ConcreteTypeLoc<UnqualTypeLoc,
1982 DependentTemplateSpecializationTypeLoc,
1983 DependentTemplateSpecializationType,
1984 DependentTemplateSpecializationLocInfo> {
1986 SourceLocation getElaboratedKeywordLoc() const {
1987 return this->getLocalData()->ElaboratedKWLoc;
1989 void setElaboratedKeywordLoc(SourceLocation Loc) {
1990 this->getLocalData()->ElaboratedKWLoc = Loc;
1993 NestedNameSpecifierLoc getQualifierLoc() const {
1994 if (!getLocalData()->QualifierData)
1995 return NestedNameSpecifierLoc();
1997 return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
1998 getLocalData()->QualifierData);
2001 void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
2002 if (!QualifierLoc) {
2003 // Even if we have a nested-name-specifier in the dependent
2004 // template specialization type, we won't record the nested-name-specifier
2005 // location information when this type-source location information is
2006 // part of a nested-name-specifier.
2007 getLocalData()->QualifierData = nullptr;
2011 assert(QualifierLoc.getNestedNameSpecifier()
2012 == getTypePtr()->getQualifier() &&
2013 "Inconsistent nested-name-specifier pointer");
2014 getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
2017 SourceLocation getTemplateKeywordLoc() const {
2018 return getLocalData()->TemplateKWLoc;
2020 void setTemplateKeywordLoc(SourceLocation Loc) {
2021 getLocalData()->TemplateKWLoc = Loc;
2024 SourceLocation getTemplateNameLoc() const {
2025 return this->getLocalData()->NameLoc;
2027 void setTemplateNameLoc(SourceLocation Loc) {
2028 this->getLocalData()->NameLoc = Loc;
2031 SourceLocation getLAngleLoc() const {
2032 return this->getLocalData()->LAngleLoc;
2034 void setLAngleLoc(SourceLocation Loc) {
2035 this->getLocalData()->LAngleLoc = Loc;
2038 SourceLocation getRAngleLoc() const {
2039 return this->getLocalData()->RAngleLoc;
2041 void setRAngleLoc(SourceLocation Loc) {
2042 this->getLocalData()->RAngleLoc = Loc;
2045 unsigned getNumArgs() const {
2046 return getTypePtr()->getNumArgs();
2049 void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) {
2050 getArgInfos()[i] = AI;
2052 TemplateArgumentLocInfo getArgLocInfo(unsigned i) const {
2053 return getArgInfos()[i];
2056 TemplateArgumentLoc getArgLoc(unsigned i) const {
2057 return TemplateArgumentLoc(getTypePtr()->getArg(i), getArgLocInfo(i));
2060 SourceRange getLocalSourceRange() const {
2061 if (getElaboratedKeywordLoc().isValid())
2062 return SourceRange(getElaboratedKeywordLoc(), getRAngleLoc());
2063 else if (getQualifierLoc())
2064 return SourceRange(getQualifierLoc().getBeginLoc(), getRAngleLoc());
2065 else if (getTemplateKeywordLoc().isValid())
2066 return SourceRange(getTemplateKeywordLoc(), getRAngleLoc());
2068 return SourceRange(getTemplateNameLoc(), getRAngleLoc());
2071 void copy(DependentTemplateSpecializationTypeLoc Loc) {
2072 unsigned size = getFullDataSize();
2073 assert(size == Loc.getFullDataSize());
2074 memcpy(Data, Loc.Data, size);
2077 void initializeLocal(ASTContext &Context, SourceLocation Loc);
2079 unsigned getExtraLocalDataSize() const {
2080 return getNumArgs() * sizeof(TemplateArgumentLocInfo);
2083 unsigned getExtraLocalDataAlignment() const {
2084 return alignof(TemplateArgumentLocInfo);
2088 TemplateArgumentLocInfo *getArgInfos() const {
2089 return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData());
2094 struct PackExpansionTypeLocInfo {
2095 SourceLocation EllipsisLoc;
2098 class PackExpansionTypeLoc
2099 : public ConcreteTypeLoc<UnqualTypeLoc, PackExpansionTypeLoc,
2100 PackExpansionType, PackExpansionTypeLocInfo> {
2102 SourceLocation getEllipsisLoc() const {
2103 return this->getLocalData()->EllipsisLoc;
2106 void setEllipsisLoc(SourceLocation Loc) {
2107 this->getLocalData()->EllipsisLoc = Loc;
2110 SourceRange getLocalSourceRange() const {
2111 return SourceRange(getEllipsisLoc(), getEllipsisLoc());
2114 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
2115 setEllipsisLoc(Loc);
2118 TypeLoc getPatternLoc() const {
2119 return getInnerTypeLoc();
2122 QualType getInnerType() const {
2123 return this->getTypePtr()->getPattern();
2127 struct AtomicTypeLocInfo {
2128 SourceLocation KWLoc, LParenLoc, RParenLoc;
2131 class AtomicTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, AtomicTypeLoc,
2132 AtomicType, AtomicTypeLocInfo> {
2134 TypeLoc getValueLoc() const {
2135 return this->getInnerTypeLoc();
2138 SourceRange getLocalSourceRange() const {
2139 return SourceRange(getKWLoc(), getRParenLoc());
2142 SourceLocation getKWLoc() const {
2143 return this->getLocalData()->KWLoc;
2145 void setKWLoc(SourceLocation Loc) {
2146 this->getLocalData()->KWLoc = Loc;
2149 SourceLocation getLParenLoc() const {
2150 return this->getLocalData()->LParenLoc;
2152 void setLParenLoc(SourceLocation Loc) {
2153 this->getLocalData()->LParenLoc = Loc;
2156 SourceLocation getRParenLoc() const {
2157 return this->getLocalData()->RParenLoc;
2159 void setRParenLoc(SourceLocation Loc) {
2160 this->getLocalData()->RParenLoc = Loc;
2163 SourceRange getParensRange() const {
2164 return SourceRange(getLParenLoc(), getRParenLoc());
2166 void setParensRange(SourceRange Range) {
2167 setLParenLoc(Range.getBegin());
2168 setRParenLoc(Range.getEnd());
2171 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
2177 QualType getInnerType() const {
2178 return this->getTypePtr()->getValueType();
2182 struct PipeTypeLocInfo {
2183 SourceLocation KWLoc;
2186 class PipeTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, PipeTypeLoc, PipeType,
2189 TypeLoc getValueLoc() const { return this->getInnerTypeLoc(); }
2191 SourceRange getLocalSourceRange() const { return SourceRange(getKWLoc()); }
2193 SourceLocation getKWLoc() const { return this->getLocalData()->KWLoc; }
2194 void setKWLoc(SourceLocation Loc) { this->getLocalData()->KWLoc = Loc; }
2196 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
2200 QualType getInnerType() const { return this->getTypePtr()->getElementType(); }
2203 template <typename T>
2204 inline T TypeLoc::getAsAdjusted() const {
2205 TypeLoc Cur = *this;
2206 while (!T::isKind(Cur)) {
2207 if (auto PTL = Cur.getAs<ParenTypeLoc>())
2208 Cur = PTL.getInnerLoc();
2209 else if (auto ATL = Cur.getAs<AttributedTypeLoc>())
2210 Cur = ATL.getModifiedLoc();
2211 else if (auto ETL = Cur.getAs<ElaboratedTypeLoc>())
2212 Cur = ETL.getNamedTypeLoc();
2213 else if (auto ATL = Cur.getAs<AdjustedTypeLoc>())
2214 Cur = ATL.getOriginalLoc();
2218 return Cur.getAs<T>();