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/NestedNameSpecifier.h"
20 #include "clang/AST/TemplateBase.h"
21 #include "clang/AST/Type.h"
22 #include "clang/Basic/LLVM.h"
23 #include "clang/Basic/SourceLocation.h"
24 #include "clang/Basic/Specifiers.h"
25 #include "llvm/ADT/ArrayRef.h"
26 #include "llvm/Support/Casting.h"
27 #include "llvm/Support/Compiler.h"
28 #include "llvm/Support/MathExtras.h"
39 class ObjCInterfaceDecl;
40 class ObjCProtocolDecl;
41 class ObjCTypeParamDecl;
42 class TemplateTypeParmDecl;
44 class UnresolvedUsingTypenameDecl;
46 // Predeclare all the type nodes.
47 #define ABSTRACT_TYPELOC(Class, Base)
48 #define TYPELOC(Class, Base) \
50 #include "clang/AST/TypeLocNodes.def"
52 /// \brief Base wrapper for a particular "section" of type source info.
54 /// A client should use the TypeLoc subclasses through castAs()/getAs()
55 /// in order to get at the actual information.
58 // The correctness of this relies on the property that, for Type *Ty,
59 // QualType(Ty, 0).getAsOpaquePtr() == (void*) Ty
60 const void *Ty = nullptr;
65 TypeLoc(QualType ty, void *opaqueData)
66 : Ty(ty.getAsOpaquePtr()), Data(opaqueData) {}
67 TypeLoc(const Type *ty, void *opaqueData)
68 : Ty(ty), Data(opaqueData) {}
70 /// \brief Convert to the specified TypeLoc type, asserting that this TypeLoc
71 /// is of the desired type.
73 /// \pre T::isKind(*this)
76 assert(T::isKind(*this));
83 /// \brief Convert to the specified TypeLoc type, returning a null TypeLoc if
84 /// this TypeLoc is not of the desired type.
87 if (!T::isKind(*this))
95 /// \brief Convert to the specified TypeLoc type, returning a null TypeLoc if
96 /// this TypeLock is not of the desired type. It will consider type
97 /// adjustments from a type that wad written as a T to another type that is
98 /// still canonically a T (ignores parens, attributes, elaborated types, etc).
100 T getAsAdjusted() const;
102 /// The kinds of TypeLocs. Equivalent to the Type::TypeClass enum,
103 /// except it also defines a Qualified enum that corresponds to the
104 /// QualifiedLoc class.
106 #define ABSTRACT_TYPE(Class, Base)
107 #define TYPE(Class, Base) \
109 #include "clang/AST/TypeNodes.def"
113 TypeLocClass getTypeLocClass() const {
114 if (getType().hasLocalQualifiers()) return Qualified;
115 return (TypeLocClass) getType()->getTypeClass();
118 bool isNull() const { return !Ty; }
119 explicit operator bool() const { return Ty; }
121 /// \brief Returns the size of type source info data block for the given type.
122 static unsigned getFullDataSizeForType(QualType Ty);
124 /// \brief Returns the alignment of type source info data block for
126 static unsigned getLocalAlignmentForType(QualType Ty);
128 /// \brief Get the type for which this source info wrapper provides
130 QualType getType() const {
131 return QualType::getFromOpaquePtr(Ty);
134 const Type *getTypePtr() const {
135 return QualType::getFromOpaquePtr(Ty).getTypePtr();
138 /// \brief Get the pointer where source information is stored.
139 void *getOpaqueData() const {
143 /// \brief Get the begin source location.
144 SourceLocation getBeginLoc() const;
146 /// \brief Get the end source location.
147 SourceLocation getEndLoc() const;
149 /// \brief Get the full source range.
150 SourceRange getSourceRange() const LLVM_READONLY {
151 return SourceRange(getBeginLoc(), getEndLoc());
154 SourceLocation getLocStart() const LLVM_READONLY { return getBeginLoc(); }
155 SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
157 /// \brief Get the local source range.
158 SourceRange getLocalSourceRange() const {
159 return getLocalSourceRangeImpl(*this);
162 /// \brief Returns the size of the type source info data block.
163 unsigned getFullDataSize() const {
164 return getFullDataSizeForType(getType());
167 /// \brief Get the next TypeLoc pointed by this TypeLoc, e.g for "int*" the
168 /// TypeLoc is a PointerLoc and next TypeLoc is for "int".
169 TypeLoc getNextTypeLoc() const {
170 return getNextTypeLocImpl(*this);
173 /// \brief Skips past any qualifiers, if this is qualified.
174 UnqualTypeLoc getUnqualifiedLoc() const; // implemented in this header
176 TypeLoc IgnoreParens() const;
178 /// \brief Find a type with the location of an explicit type qualifier.
180 /// The result, if non-null, will be one of:
183 /// AttributedTypeLoc, for those type attributes that behave as qualifiers
184 TypeLoc findExplicitQualifierLoc() const;
186 /// \brief Initializes this to state that every location in this
187 /// type is the given location.
189 /// This method exists to provide a simple transition for code that
190 /// relies on location-less types.
191 void initialize(ASTContext &Context, SourceLocation Loc) const {
192 initializeImpl(Context, *this, Loc);
195 /// \brief Initializes this by copying its information from another
196 /// TypeLoc of the same type.
197 void initializeFullCopy(TypeLoc Other) {
198 assert(getType() == Other.getType());
202 /// \brief Initializes this by copying its information from another
203 /// TypeLoc of the same type. The given size must be the full data
205 void initializeFullCopy(TypeLoc Other, unsigned Size) {
206 assert(getType() == Other.getType());
207 assert(getFullDataSize() == Size);
211 /// Copies the other type loc into this one.
212 void copy(TypeLoc other);
214 friend bool operator==(const TypeLoc &LHS, const TypeLoc &RHS) {
215 return LHS.Ty == RHS.Ty && LHS.Data == RHS.Data;
218 friend bool operator!=(const TypeLoc &LHS, const TypeLoc &RHS) {
219 return !(LHS == RHS);
222 /// Find the location of the nullability specifier (__nonnull,
223 /// __nullable, or __null_unspecifier), if there is one.
224 SourceLocation findNullabilityLoc() const;
227 static bool isKind(const TypeLoc&) {
231 static void initializeImpl(ASTContext &Context, TypeLoc TL,
233 static TypeLoc getNextTypeLocImpl(TypeLoc TL);
234 static TypeLoc IgnoreParensImpl(TypeLoc TL);
235 static SourceRange getLocalSourceRangeImpl(TypeLoc TL);
238 /// \brief Return the TypeLoc for a type source info.
239 inline TypeLoc TypeSourceInfo::getTypeLoc() const {
240 // TODO: is this alignment already sufficient?
241 return TypeLoc(Ty, const_cast<void*>(static_cast<const void*>(this + 1)));
244 /// \brief Wrapper of type source information for a type with
245 /// no direct qualifiers.
246 class UnqualTypeLoc : public TypeLoc {
248 UnqualTypeLoc() = default;
249 UnqualTypeLoc(const Type *Ty, void *Data) : TypeLoc(Ty, Data) {}
251 const Type *getTypePtr() const {
252 return reinterpret_cast<const Type*>(Ty);
255 TypeLocClass getTypeLocClass() const {
256 return (TypeLocClass) getTypePtr()->getTypeClass();
260 friend class TypeLoc;
262 static bool isKind(const TypeLoc &TL) {
263 return !TL.getType().hasLocalQualifiers();
267 /// \brief Wrapper of type source information for a type with
268 /// non-trivial direct qualifiers.
270 /// Currently, we intentionally do not provide source location for
272 class QualifiedTypeLoc : public TypeLoc {
274 SourceRange getLocalSourceRange() const { return {}; }
276 UnqualTypeLoc getUnqualifiedLoc() const {
278 TypeLoc::getLocalAlignmentForType(QualType(getTypePtr(), 0));
279 uintptr_t dataInt = reinterpret_cast<uintptr_t>(Data);
280 dataInt = llvm::alignTo(dataInt, align);
281 return UnqualTypeLoc(getTypePtr(), reinterpret_cast<void*>(dataInt));
284 /// Initializes the local data of this type source info block to
285 /// provide no information.
286 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
290 void copyLocal(TypeLoc other) {
294 TypeLoc getNextTypeLoc() const {
295 return getUnqualifiedLoc();
298 /// \brief Returns the size of the type source info data block that is
299 /// specific to this type.
300 unsigned getLocalDataSize() const {
301 // In fact, we don't currently preserve any location information
306 /// \brief Returns the alignment of the type source info data block that is
307 /// specific to this type.
308 unsigned getLocalDataAlignment() const {
309 // We don't preserve any location information.
314 friend class TypeLoc;
316 static bool isKind(const TypeLoc &TL) {
317 return TL.getType().hasLocalQualifiers();
321 inline UnqualTypeLoc TypeLoc::getUnqualifiedLoc() const {
322 if (QualifiedTypeLoc Loc = getAs<QualifiedTypeLoc>())
323 return Loc.getUnqualifiedLoc();
324 return castAs<UnqualTypeLoc>();
327 /// A metaprogramming base class for TypeLoc classes which correspond
328 /// to a particular Type subclass. It is accepted for a single
329 /// TypeLoc class to correspond to multiple Type classes.
331 /// \tparam Base a class from which to derive
332 /// \tparam Derived the class deriving from this one
333 /// \tparam TypeClass the concrete Type subclass associated with this
335 /// \tparam LocalData the structure type of local location data for
338 /// TypeLocs with non-constant amounts of local data should override
339 /// getExtraLocalDataSize(); getExtraLocalData() will then point to
340 /// this extra memory.
342 /// TypeLocs with an inner type should define
343 /// QualType getInnerType() const
344 /// and getInnerTypeLoc() will then point to this inner type's
347 /// A word about hierarchies: this template is not designed to be
348 /// derived from multiple times in a hierarchy. It is also not
349 /// designed to be used for classes where subtypes might provide
350 /// different amounts of source information. It should be subclassed
351 /// only at the deepest portion of the hierarchy where all children
352 /// have identical source information; if that's an abstract type,
353 /// then further descendents should inherit from
354 /// InheritingConcreteTypeLoc instead.
355 template <class Base, class Derived, class TypeClass, class LocalData>
356 class ConcreteTypeLoc : public Base {
357 friend class TypeLoc;
359 const Derived *asDerived() const {
360 return static_cast<const Derived*>(this);
363 static bool isKind(const TypeLoc &TL) {
364 return !TL.getType().hasLocalQualifiers() &&
365 Derived::classofType(TL.getTypePtr());
368 static bool classofType(const Type *Ty) {
369 return TypeClass::classof(Ty);
373 unsigned getLocalDataAlignment() const {
374 return std::max(unsigned(alignof(LocalData)),
375 asDerived()->getExtraLocalDataAlignment());
378 unsigned getLocalDataSize() const {
379 unsigned size = sizeof(LocalData);
380 unsigned extraAlign = asDerived()->getExtraLocalDataAlignment();
381 size = llvm::alignTo(size, extraAlign);
382 size += asDerived()->getExtraLocalDataSize();
386 void copyLocal(Derived other) {
387 // Some subclasses have no data to copy.
388 if (asDerived()->getLocalDataSize() == 0) return;
390 // Copy the fixed-sized local data.
391 memcpy(getLocalData(), other.getLocalData(), sizeof(LocalData));
393 // Copy the variable-sized local data. We need to do this
394 // separately because the padding in the source and the padding in
395 // the destination might be different.
396 memcpy(getExtraLocalData(), other.getExtraLocalData(),
397 asDerived()->getExtraLocalDataSize());
400 TypeLoc getNextTypeLoc() const {
401 return getNextTypeLoc(asDerived()->getInnerType());
404 const TypeClass *getTypePtr() const {
405 return cast<TypeClass>(Base::getTypePtr());
409 unsigned getExtraLocalDataSize() const {
413 unsigned getExtraLocalDataAlignment() const {
417 LocalData *getLocalData() const {
418 return static_cast<LocalData*>(Base::Data);
421 /// Gets a pointer past the Info structure; useful for classes with
422 /// local data that can't be captured in the Info (e.g. because it's
423 /// of variable size).
424 void *getExtraLocalData() const {
425 unsigned size = sizeof(LocalData);
426 unsigned extraAlign = asDerived()->getExtraLocalDataAlignment();
427 size = llvm::alignTo(size, extraAlign);
428 return reinterpret_cast<char*>(Base::Data) + size;
431 void *getNonLocalData() const {
432 uintptr_t data = reinterpret_cast<uintptr_t>(Base::Data);
433 data += asDerived()->getLocalDataSize();
434 data = llvm::alignTo(data, getNextTypeAlign());
435 return reinterpret_cast<void*>(data);
438 struct HasNoInnerType {};
439 HasNoInnerType getInnerType() const { return HasNoInnerType(); }
441 TypeLoc getInnerTypeLoc() const {
442 return TypeLoc(asDerived()->getInnerType(), getNonLocalData());
446 unsigned getInnerTypeSize() const {
447 return getInnerTypeSize(asDerived()->getInnerType());
450 unsigned getInnerTypeSize(HasNoInnerType _) const {
454 unsigned getInnerTypeSize(QualType _) const {
455 return getInnerTypeLoc().getFullDataSize();
458 unsigned getNextTypeAlign() const {
459 return getNextTypeAlign(asDerived()->getInnerType());
462 unsigned getNextTypeAlign(HasNoInnerType _) const {
466 unsigned getNextTypeAlign(QualType T) const {
467 return TypeLoc::getLocalAlignmentForType(T);
470 TypeLoc getNextTypeLoc(HasNoInnerType _) const { return {}; }
472 TypeLoc getNextTypeLoc(QualType T) const {
473 return TypeLoc(T, getNonLocalData());
477 /// A metaprogramming class designed for concrete subtypes of abstract
478 /// types where all subtypes share equivalently-structured source
479 /// information. See the note on ConcreteTypeLoc.
480 template <class Base, class Derived, class TypeClass>
481 class InheritingConcreteTypeLoc : public Base {
482 friend class TypeLoc;
484 static bool classofType(const Type *Ty) {
485 return TypeClass::classof(Ty);
488 static bool isKind(const TypeLoc &TL) {
489 return !TL.getType().hasLocalQualifiers() &&
490 Derived::classofType(TL.getTypePtr());
492 static bool isKind(const UnqualTypeLoc &TL) {
493 return Derived::classofType(TL.getTypePtr());
497 const TypeClass *getTypePtr() const {
498 return cast<TypeClass>(Base::getTypePtr());
502 struct TypeSpecLocInfo {
503 SourceLocation NameLoc;
506 /// \brief A reasonable base class for TypeLocs that correspond to
507 /// types that are written as a type-specifier.
508 class TypeSpecTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
514 LocalDataSize = sizeof(TypeSpecLocInfo),
515 LocalDataAlignment = alignof(TypeSpecLocInfo)
518 SourceLocation getNameLoc() const {
519 return this->getLocalData()->NameLoc;
522 void setNameLoc(SourceLocation Loc) {
523 this->getLocalData()->NameLoc = Loc;
526 SourceRange getLocalSourceRange() const {
527 return SourceRange(getNameLoc(), getNameLoc());
530 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
535 friend class TypeLoc;
537 static bool isKind(const TypeLoc &TL);
540 struct BuiltinLocInfo {
541 SourceRange BuiltinRange;
544 /// \brief Wrapper for source info for builtin types.
545 class BuiltinTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
550 SourceLocation getBuiltinLoc() const {
551 return getLocalData()->BuiltinRange.getBegin();
554 void setBuiltinLoc(SourceLocation Loc) {
555 getLocalData()->BuiltinRange = Loc;
558 void expandBuiltinRange(SourceRange Range) {
559 SourceRange &BuiltinRange = getLocalData()->BuiltinRange;
560 if (!BuiltinRange.getBegin().isValid()) {
561 BuiltinRange = Range;
563 BuiltinRange.setBegin(std::min(Range.getBegin(), BuiltinRange.getBegin()));
564 BuiltinRange.setEnd(std::max(Range.getEnd(), BuiltinRange.getEnd()));
568 SourceLocation getNameLoc() const { return getBuiltinLoc(); }
570 WrittenBuiltinSpecs& getWrittenBuiltinSpecs() {
571 return *(static_cast<WrittenBuiltinSpecs*>(getExtraLocalData()));
573 const WrittenBuiltinSpecs& getWrittenBuiltinSpecs() const {
574 return *(static_cast<WrittenBuiltinSpecs*>(getExtraLocalData()));
577 bool needsExtraLocalData() const {
578 BuiltinType::Kind bk = getTypePtr()->getKind();
579 return (bk >= BuiltinType::UShort && bk <= BuiltinType::UInt128)
580 || (bk >= BuiltinType::Short && bk <= BuiltinType::Float128)
581 || bk == BuiltinType::UChar
582 || bk == BuiltinType::SChar;
585 unsigned getExtraLocalDataSize() const {
586 return needsExtraLocalData() ? sizeof(WrittenBuiltinSpecs) : 0;
589 unsigned getExtraLocalDataAlignment() const {
590 return needsExtraLocalData() ? alignof(WrittenBuiltinSpecs) : 1;
593 SourceRange getLocalSourceRange() const {
594 return getLocalData()->BuiltinRange;
597 TypeSpecifierSign getWrittenSignSpec() const {
598 if (needsExtraLocalData())
599 return static_cast<TypeSpecifierSign>(getWrittenBuiltinSpecs().Sign);
601 return TSS_unspecified;
604 bool hasWrittenSignSpec() const {
605 return getWrittenSignSpec() != TSS_unspecified;
608 void setWrittenSignSpec(TypeSpecifierSign written) {
609 if (needsExtraLocalData())
610 getWrittenBuiltinSpecs().Sign = written;
613 TypeSpecifierWidth getWrittenWidthSpec() const {
614 if (needsExtraLocalData())
615 return static_cast<TypeSpecifierWidth>(getWrittenBuiltinSpecs().Width);
617 return TSW_unspecified;
620 bool hasWrittenWidthSpec() const {
621 return getWrittenWidthSpec() != TSW_unspecified;
624 void setWrittenWidthSpec(TypeSpecifierWidth written) {
625 if (needsExtraLocalData())
626 getWrittenBuiltinSpecs().Width = written;
629 TypeSpecifierType getWrittenTypeSpec() const;
631 bool hasWrittenTypeSpec() const {
632 return getWrittenTypeSpec() != TST_unspecified;
635 void setWrittenTypeSpec(TypeSpecifierType written) {
636 if (needsExtraLocalData())
637 getWrittenBuiltinSpecs().Type = written;
640 bool hasModeAttr() const {
641 if (needsExtraLocalData())
642 return getWrittenBuiltinSpecs().ModeAttr;
647 void setModeAttr(bool written) {
648 if (needsExtraLocalData())
649 getWrittenBuiltinSpecs().ModeAttr = written;
652 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
654 if (needsExtraLocalData()) {
655 WrittenBuiltinSpecs &wbs = getWrittenBuiltinSpecs();
656 wbs.Sign = TSS_unspecified;
657 wbs.Width = TSW_unspecified;
658 wbs.Type = TST_unspecified;
659 wbs.ModeAttr = false;
664 /// \brief Wrapper for source info for typedefs.
665 class TypedefTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
669 TypedefNameDecl *getTypedefNameDecl() const {
670 return getTypePtr()->getDecl();
674 /// \brief Wrapper for source info for injected class names of class
676 class InjectedClassNameTypeLoc :
677 public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
678 InjectedClassNameTypeLoc,
679 InjectedClassNameType> {
681 CXXRecordDecl *getDecl() const {
682 return getTypePtr()->getDecl();
686 /// \brief Wrapper for source info for unresolved typename using decls.
687 class UnresolvedUsingTypeLoc :
688 public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
689 UnresolvedUsingTypeLoc,
690 UnresolvedUsingType> {
692 UnresolvedUsingTypenameDecl *getDecl() const {
693 return getTypePtr()->getDecl();
697 /// \brief Wrapper for source info for tag types. Note that this only
698 /// records source info for the name itself; a type written 'struct foo'
699 /// should be represented as an ElaboratedTypeLoc. We currently
700 /// only do that when C++ is enabled because of the expense of
701 /// creating an ElaboratedType node for so many type references in C.
702 class TagTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
706 TagDecl *getDecl() const { return getTypePtr()->getDecl(); }
708 /// \brief True if the tag was defined in this type specifier.
709 bool isDefinition() const {
710 TagDecl *D = getDecl();
711 return D->isCompleteDefinition() &&
712 (D->getIdentifier() == nullptr || D->getLocation() == getNameLoc());
716 /// \brief Wrapper for source info for record types.
717 class RecordTypeLoc : public InheritingConcreteTypeLoc<TagTypeLoc,
721 RecordDecl *getDecl() const { return getTypePtr()->getDecl(); }
724 /// \brief Wrapper for source info for enum types.
725 class EnumTypeLoc : public InheritingConcreteTypeLoc<TagTypeLoc,
729 EnumDecl *getDecl() const { return getTypePtr()->getDecl(); }
732 /// \brief Wrapper for template type parameters.
733 class TemplateTypeParmTypeLoc :
734 public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
735 TemplateTypeParmTypeLoc,
736 TemplateTypeParmType> {
738 TemplateTypeParmDecl *getDecl() const { return getTypePtr()->getDecl(); }
741 struct ObjCTypeParamTypeLocInfo {
742 SourceLocation NameLoc;
745 /// ProtocolLAngleLoc, ProtocolRAngleLoc, and the source locations for
746 /// protocol qualifiers are stored after Info.
747 class ObjCTypeParamTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
748 ObjCTypeParamTypeLoc,
750 ObjCTypeParamTypeLocInfo> {
751 // SourceLocations are stored after Info, one for each protocol qualifier.
752 SourceLocation *getProtocolLocArray() const {
753 return (SourceLocation*)this->getExtraLocalData() + 2;
757 ObjCTypeParamDecl *getDecl() const { return getTypePtr()->getDecl(); }
759 SourceLocation getNameLoc() const {
760 return this->getLocalData()->NameLoc;
763 void setNameLoc(SourceLocation Loc) {
764 this->getLocalData()->NameLoc = Loc;
767 SourceLocation getProtocolLAngleLoc() const {
768 return getNumProtocols() ?
769 *((SourceLocation*)this->getExtraLocalData()) :
773 void setProtocolLAngleLoc(SourceLocation Loc) {
774 *((SourceLocation*)this->getExtraLocalData()) = Loc;
777 SourceLocation getProtocolRAngleLoc() const {
778 return getNumProtocols() ?
779 *((SourceLocation*)this->getExtraLocalData() + 1) :
783 void setProtocolRAngleLoc(SourceLocation Loc) {
784 *((SourceLocation*)this->getExtraLocalData() + 1) = Loc;
787 unsigned getNumProtocols() const {
788 return this->getTypePtr()->getNumProtocols();
791 SourceLocation getProtocolLoc(unsigned i) const {
792 assert(i < getNumProtocols() && "Index is out of bounds!");
793 return getProtocolLocArray()[i];
796 void setProtocolLoc(unsigned i, SourceLocation Loc) {
797 assert(i < getNumProtocols() && "Index is out of bounds!");
798 getProtocolLocArray()[i] = Loc;
801 ObjCProtocolDecl *getProtocol(unsigned i) const {
802 assert(i < getNumProtocols() && "Index is out of bounds!");
803 return *(this->getTypePtr()->qual_begin() + i);
806 ArrayRef<SourceLocation> getProtocolLocs() const {
807 return llvm::makeArrayRef(getProtocolLocArray(), getNumProtocols());
810 void initializeLocal(ASTContext &Context, SourceLocation Loc);
812 unsigned getExtraLocalDataSize() const {
813 if (!this->getNumProtocols()) return 0;
814 // When there are protocol qualifers, we have LAngleLoc and RAngleLoc
816 return (this->getNumProtocols() + 2) * sizeof(SourceLocation) ;
819 unsigned getExtraLocalDataAlignment() const {
820 return alignof(SourceLocation);
823 SourceRange getLocalSourceRange() const {
824 SourceLocation start = getNameLoc();
825 SourceLocation end = getProtocolRAngleLoc();
826 if (end.isInvalid()) return SourceRange(start, start);
827 return SourceRange(start, end);
831 /// \brief Wrapper for substituted template type parameters.
832 class SubstTemplateTypeParmTypeLoc :
833 public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
834 SubstTemplateTypeParmTypeLoc,
835 SubstTemplateTypeParmType> {
838 /// \brief Wrapper for substituted template type parameters.
839 class SubstTemplateTypeParmPackTypeLoc :
840 public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
841 SubstTemplateTypeParmPackTypeLoc,
842 SubstTemplateTypeParmPackType> {
845 struct AttributedLocInfo {
849 /// A raw SourceLocation.
850 unsigned EnumOperandLoc;
853 SourceRange OperandParens;
855 SourceLocation AttrLoc;
858 /// \brief Type source information for an attributed type.
859 class AttributedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
864 AttributedType::Kind getAttrKind() const {
865 return getTypePtr()->getAttrKind();
868 bool hasAttrExprOperand() const {
869 return (getAttrKind() >= AttributedType::FirstExprOperandKind &&
870 getAttrKind() <= AttributedType::LastExprOperandKind);
873 bool hasAttrEnumOperand() const {
874 return (getAttrKind() >= AttributedType::FirstEnumOperandKind &&
875 getAttrKind() <= AttributedType::LastEnumOperandKind);
878 bool hasAttrOperand() const {
879 return hasAttrExprOperand() || hasAttrEnumOperand();
882 bool isQualifier() const {
883 return getTypePtr()->isQualifier();
886 /// The modified type, which is generally canonically different from
887 /// the attribute type.
888 /// int main(int, char**) __attribute__((noreturn))
889 /// ~~~ ~~~~~~~~~~~~~
890 TypeLoc getModifiedLoc() const {
891 return getInnerTypeLoc();
894 /// The location of the attribute name, i.e.
895 /// __attribute__((regparm(1000)))
897 SourceLocation getAttrNameLoc() const {
898 return getLocalData()->AttrLoc;
900 void setAttrNameLoc(SourceLocation loc) {
901 getLocalData()->AttrLoc = loc;
904 /// The attribute's expression operand, if it has one.
905 /// void *cur_thread __attribute__((address_space(21)))
907 Expr *getAttrExprOperand() const {
908 assert(hasAttrExprOperand());
909 return getLocalData()->ExprOperand;
911 void setAttrExprOperand(Expr *e) {
912 assert(hasAttrExprOperand());
913 getLocalData()->ExprOperand = e;
916 /// The location of the attribute's enumerated operand, if it has one.
917 /// void * __attribute__((objc_gc(weak)))
919 SourceLocation getAttrEnumOperandLoc() const {
920 assert(hasAttrEnumOperand());
921 return SourceLocation::getFromRawEncoding(getLocalData()->EnumOperandLoc);
923 void setAttrEnumOperandLoc(SourceLocation loc) {
924 assert(hasAttrEnumOperand());
925 getLocalData()->EnumOperandLoc = loc.getRawEncoding();
928 /// The location of the parentheses around the operand, if there is
930 /// void * __attribute__((objc_gc(weak)))
932 SourceRange getAttrOperandParensRange() const {
933 assert(hasAttrOperand());
934 return getLocalData()->OperandParens;
936 void setAttrOperandParensRange(SourceRange range) {
937 assert(hasAttrOperand());
938 getLocalData()->OperandParens = range;
941 SourceRange getLocalSourceRange() const {
942 // Note that this does *not* include the range of the attribute
944 // __attribute__((foo(bar)))
945 // ^~~~~~~~~~~~~~~ ~~
949 // That enclosure doesn't necessarily belong to a single attribute
951 SourceRange range(getAttrNameLoc());
952 if (hasAttrOperand())
953 range.setEnd(getAttrOperandParensRange().getEnd());
957 void initializeLocal(ASTContext &Context, SourceLocation loc) {
959 if (hasAttrExprOperand()) {
960 setAttrOperandParensRange(SourceRange(loc));
961 setAttrExprOperand(nullptr);
962 } else if (hasAttrEnumOperand()) {
963 setAttrOperandParensRange(SourceRange(loc));
964 setAttrEnumOperandLoc(loc);
968 QualType getInnerType() const {
969 return getTypePtr()->getModifiedType();
973 struct ObjCObjectTypeLocInfo {
974 SourceLocation TypeArgsLAngleLoc;
975 SourceLocation TypeArgsRAngleLoc;
976 SourceLocation ProtocolLAngleLoc;
977 SourceLocation ProtocolRAngleLoc;
978 bool HasBaseTypeAsWritten;
981 // A helper class for defining ObjC TypeLocs that can qualified with
984 // TypeClass basically has to be either ObjCInterfaceType or
985 // ObjCObjectPointerType.
986 class ObjCObjectTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
989 ObjCObjectTypeLocInfo> {
990 // TypeSourceInfo*'s are stored after Info, one for each type argument.
991 TypeSourceInfo **getTypeArgLocArray() const {
992 return (TypeSourceInfo**)this->getExtraLocalData();
995 // SourceLocations are stored after the type argument information, one for
997 SourceLocation *getProtocolLocArray() const {
998 return (SourceLocation*)(getTypeArgLocArray() + getNumTypeArgs());
1002 SourceLocation getTypeArgsLAngleLoc() const {
1003 return this->getLocalData()->TypeArgsLAngleLoc;
1006 void setTypeArgsLAngleLoc(SourceLocation Loc) {
1007 this->getLocalData()->TypeArgsLAngleLoc = Loc;
1010 SourceLocation getTypeArgsRAngleLoc() const {
1011 return this->getLocalData()->TypeArgsRAngleLoc;
1014 void setTypeArgsRAngleLoc(SourceLocation Loc) {
1015 this->getLocalData()->TypeArgsRAngleLoc = Loc;
1018 unsigned getNumTypeArgs() const {
1019 return this->getTypePtr()->getTypeArgsAsWritten().size();
1022 TypeSourceInfo *getTypeArgTInfo(unsigned i) const {
1023 assert(i < getNumTypeArgs() && "Index is out of bounds!");
1024 return getTypeArgLocArray()[i];
1027 void setTypeArgTInfo(unsigned i, TypeSourceInfo *TInfo) {
1028 assert(i < getNumTypeArgs() && "Index is out of bounds!");
1029 getTypeArgLocArray()[i] = TInfo;
1032 SourceLocation getProtocolLAngleLoc() const {
1033 return this->getLocalData()->ProtocolLAngleLoc;
1036 void setProtocolLAngleLoc(SourceLocation Loc) {
1037 this->getLocalData()->ProtocolLAngleLoc = Loc;
1040 SourceLocation getProtocolRAngleLoc() const {
1041 return this->getLocalData()->ProtocolRAngleLoc;
1044 void setProtocolRAngleLoc(SourceLocation Loc) {
1045 this->getLocalData()->ProtocolRAngleLoc = Loc;
1048 unsigned getNumProtocols() const {
1049 return this->getTypePtr()->getNumProtocols();
1052 SourceLocation getProtocolLoc(unsigned i) const {
1053 assert(i < getNumProtocols() && "Index is out of bounds!");
1054 return getProtocolLocArray()[i];
1057 void setProtocolLoc(unsigned i, SourceLocation Loc) {
1058 assert(i < getNumProtocols() && "Index is out of bounds!");
1059 getProtocolLocArray()[i] = Loc;
1062 ObjCProtocolDecl *getProtocol(unsigned i) const {
1063 assert(i < getNumProtocols() && "Index is out of bounds!");
1064 return *(this->getTypePtr()->qual_begin() + i);
1068 ArrayRef<SourceLocation> getProtocolLocs() const {
1069 return llvm::makeArrayRef(getProtocolLocArray(), getNumProtocols());
1072 bool hasBaseTypeAsWritten() const {
1073 return getLocalData()->HasBaseTypeAsWritten;
1076 void setHasBaseTypeAsWritten(bool HasBaseType) {
1077 getLocalData()->HasBaseTypeAsWritten = HasBaseType;
1080 TypeLoc getBaseLoc() const {
1081 return getInnerTypeLoc();
1084 SourceRange getLocalSourceRange() const {
1085 SourceLocation start = getTypeArgsLAngleLoc();
1086 if (start.isInvalid())
1087 start = getProtocolLAngleLoc();
1088 SourceLocation end = getProtocolRAngleLoc();
1089 if (end.isInvalid())
1090 end = getTypeArgsRAngleLoc();
1091 return SourceRange(start, end);
1094 void initializeLocal(ASTContext &Context, SourceLocation Loc);
1096 unsigned getExtraLocalDataSize() const {
1097 return this->getNumTypeArgs() * sizeof(TypeSourceInfo *)
1098 + this->getNumProtocols() * sizeof(SourceLocation);
1101 unsigned getExtraLocalDataAlignment() const {
1102 static_assert(alignof(ObjCObjectTypeLoc) >= alignof(TypeSourceInfo *),
1103 "not enough alignment for tail-allocated data");
1104 return alignof(TypeSourceInfo *);
1107 QualType getInnerType() const {
1108 return getTypePtr()->getBaseType();
1112 struct ObjCInterfaceLocInfo {
1113 SourceLocation NameLoc;
1114 SourceLocation NameEndLoc;
1117 /// \brief Wrapper for source info for ObjC interfaces.
1118 class ObjCInterfaceTypeLoc : public ConcreteTypeLoc<ObjCObjectTypeLoc,
1119 ObjCInterfaceTypeLoc,
1121 ObjCInterfaceLocInfo> {
1123 ObjCInterfaceDecl *getIFaceDecl() const {
1124 return getTypePtr()->getDecl();
1127 SourceLocation getNameLoc() const {
1128 return getLocalData()->NameLoc;
1131 void setNameLoc(SourceLocation Loc) {
1132 getLocalData()->NameLoc = Loc;
1135 SourceRange getLocalSourceRange() const {
1136 return SourceRange(getNameLoc(), getNameEndLoc());
1139 SourceLocation getNameEndLoc() const {
1140 return getLocalData()->NameEndLoc;
1143 void setNameEndLoc(SourceLocation Loc) {
1144 getLocalData()->NameEndLoc = Loc;
1147 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1153 struct ParenLocInfo {
1154 SourceLocation LParenLoc;
1155 SourceLocation RParenLoc;
1159 : public ConcreteTypeLoc<UnqualTypeLoc, ParenTypeLoc, ParenType,
1162 SourceLocation getLParenLoc() const {
1163 return this->getLocalData()->LParenLoc;
1166 SourceLocation getRParenLoc() const {
1167 return this->getLocalData()->RParenLoc;
1170 void setLParenLoc(SourceLocation Loc) {
1171 this->getLocalData()->LParenLoc = Loc;
1174 void setRParenLoc(SourceLocation Loc) {
1175 this->getLocalData()->RParenLoc = Loc;
1178 SourceRange getLocalSourceRange() const {
1179 return SourceRange(getLParenLoc(), getRParenLoc());
1182 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1187 TypeLoc getInnerLoc() const {
1188 return getInnerTypeLoc();
1191 QualType getInnerType() const {
1192 return this->getTypePtr()->getInnerType();
1196 inline TypeLoc TypeLoc::IgnoreParens() const {
1197 if (ParenTypeLoc::isKind(*this))
1198 return IgnoreParensImpl(*this);
1202 struct AdjustedLocInfo {}; // Nothing.
1204 class AdjustedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, AdjustedTypeLoc,
1205 AdjustedType, AdjustedLocInfo> {
1207 TypeLoc getOriginalLoc() const {
1208 return getInnerTypeLoc();
1211 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1215 QualType getInnerType() const {
1216 // The inner type is the undecayed type, since that's what we have source
1217 // location information for.
1218 return getTypePtr()->getOriginalType();
1221 SourceRange getLocalSourceRange() const { return {}; }
1223 unsigned getLocalDataSize() const {
1224 // sizeof(AdjustedLocInfo) is 1, but we don't need its address to be unique
1225 // anyway. TypeLocBuilder can't handle data sizes of 1.
1226 return 0; // No data.
1230 /// \brief Wrapper for source info for pointers decayed from arrays and
1232 class DecayedTypeLoc : public InheritingConcreteTypeLoc<
1233 AdjustedTypeLoc, DecayedTypeLoc, DecayedType> {
1236 struct PointerLikeLocInfo {
1237 SourceLocation StarLoc;
1240 /// A base class for
1241 template <class Derived, class TypeClass, class LocalData = PointerLikeLocInfo>
1242 class PointerLikeTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, Derived,
1243 TypeClass, LocalData> {
1245 SourceLocation getSigilLoc() const {
1246 return this->getLocalData()->StarLoc;
1249 void setSigilLoc(SourceLocation Loc) {
1250 this->getLocalData()->StarLoc = Loc;
1253 TypeLoc getPointeeLoc() const {
1254 return this->getInnerTypeLoc();
1257 SourceRange getLocalSourceRange() const {
1258 return SourceRange(getSigilLoc(), getSigilLoc());
1261 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1265 QualType getInnerType() const {
1266 return this->getTypePtr()->getPointeeType();
1270 /// \brief Wrapper for source info for pointers.
1271 class PointerTypeLoc : public PointerLikeTypeLoc<PointerTypeLoc,
1274 SourceLocation getStarLoc() const {
1275 return getSigilLoc();
1278 void setStarLoc(SourceLocation Loc) {
1283 /// \brief Wrapper for source info for block pointers.
1284 class BlockPointerTypeLoc : public PointerLikeTypeLoc<BlockPointerTypeLoc,
1287 SourceLocation getCaretLoc() const {
1288 return getSigilLoc();
1291 void setCaretLoc(SourceLocation Loc) {
1296 struct MemberPointerLocInfo : public PointerLikeLocInfo {
1297 TypeSourceInfo *ClassTInfo;
1300 /// \brief Wrapper for source info for member pointers.
1301 class MemberPointerTypeLoc : public PointerLikeTypeLoc<MemberPointerTypeLoc,
1303 MemberPointerLocInfo> {
1305 SourceLocation getStarLoc() const {
1306 return getSigilLoc();
1309 void setStarLoc(SourceLocation Loc) {
1313 const Type *getClass() const {
1314 return getTypePtr()->getClass();
1317 TypeSourceInfo *getClassTInfo() const {
1318 return getLocalData()->ClassTInfo;
1321 void setClassTInfo(TypeSourceInfo* TI) {
1322 getLocalData()->ClassTInfo = TI;
1325 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1327 setClassTInfo(nullptr);
1330 SourceRange getLocalSourceRange() const {
1331 if (TypeSourceInfo *TI = getClassTInfo())
1332 return SourceRange(TI->getTypeLoc().getBeginLoc(), getStarLoc());
1334 return SourceRange(getStarLoc());
1338 /// Wraps an ObjCPointerType with source location information.
1339 class ObjCObjectPointerTypeLoc :
1340 public PointerLikeTypeLoc<ObjCObjectPointerTypeLoc,
1341 ObjCObjectPointerType> {
1343 SourceLocation getStarLoc() const {
1344 return getSigilLoc();
1347 void setStarLoc(SourceLocation Loc) {
1352 class ReferenceTypeLoc : public PointerLikeTypeLoc<ReferenceTypeLoc,
1355 QualType getInnerType() const {
1356 return getTypePtr()->getPointeeTypeAsWritten();
1360 class LValueReferenceTypeLoc :
1361 public InheritingConcreteTypeLoc<ReferenceTypeLoc,
1362 LValueReferenceTypeLoc,
1363 LValueReferenceType> {
1365 SourceLocation getAmpLoc() const {
1366 return getSigilLoc();
1369 void setAmpLoc(SourceLocation Loc) {
1374 class RValueReferenceTypeLoc :
1375 public InheritingConcreteTypeLoc<ReferenceTypeLoc,
1376 RValueReferenceTypeLoc,
1377 RValueReferenceType> {
1379 SourceLocation getAmpAmpLoc() const {
1380 return getSigilLoc();
1383 void setAmpAmpLoc(SourceLocation Loc) {
1388 struct FunctionLocInfo {
1389 SourceLocation LocalRangeBegin;
1390 SourceLocation LParenLoc;
1391 SourceLocation RParenLoc;
1392 SourceLocation LocalRangeEnd;
1395 /// \brief Wrapper for source info for functions.
1396 class FunctionTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
1400 bool hasExceptionSpec() const {
1401 if (auto *FPT = dyn_cast<FunctionProtoType>(getTypePtr())) {
1402 return FPT->hasExceptionSpec();
1407 SourceRange *getExceptionSpecRangePtr() const {
1408 assert(hasExceptionSpec() && "No exception spec range");
1409 // After the Info comes the ParmVarDecl array, and after that comes the
1410 // exception specification information.
1411 return (SourceRange *)(getParmArray() + getNumParams());
1415 SourceLocation getLocalRangeBegin() const {
1416 return getLocalData()->LocalRangeBegin;
1419 void setLocalRangeBegin(SourceLocation L) {
1420 getLocalData()->LocalRangeBegin = L;
1423 SourceLocation getLocalRangeEnd() const {
1424 return getLocalData()->LocalRangeEnd;
1427 void setLocalRangeEnd(SourceLocation L) {
1428 getLocalData()->LocalRangeEnd = L;
1431 SourceLocation getLParenLoc() const {
1432 return this->getLocalData()->LParenLoc;
1435 void setLParenLoc(SourceLocation Loc) {
1436 this->getLocalData()->LParenLoc = Loc;
1439 SourceLocation getRParenLoc() const {
1440 return this->getLocalData()->RParenLoc;
1443 void setRParenLoc(SourceLocation Loc) {
1444 this->getLocalData()->RParenLoc = Loc;
1447 SourceRange getParensRange() const {
1448 return SourceRange(getLParenLoc(), getRParenLoc());
1451 SourceRange getExceptionSpecRange() const {
1452 if (hasExceptionSpec())
1453 return *getExceptionSpecRangePtr();
1457 void setExceptionSpecRange(SourceRange R) {
1458 if (hasExceptionSpec())
1459 *getExceptionSpecRangePtr() = R;
1462 ArrayRef<ParmVarDecl *> getParams() const {
1463 return llvm::makeArrayRef(getParmArray(), getNumParams());
1466 // ParmVarDecls* are stored after Info, one for each parameter.
1467 ParmVarDecl **getParmArray() const {
1468 return (ParmVarDecl**) getExtraLocalData();
1471 unsigned getNumParams() const {
1472 if (isa<FunctionNoProtoType>(getTypePtr()))
1474 return cast<FunctionProtoType>(getTypePtr())->getNumParams();
1477 ParmVarDecl *getParam(unsigned i) const { return getParmArray()[i]; }
1478 void setParam(unsigned i, ParmVarDecl *VD) { getParmArray()[i] = VD; }
1480 TypeLoc getReturnLoc() const {
1481 return getInnerTypeLoc();
1484 SourceRange getLocalSourceRange() const {
1485 return SourceRange(getLocalRangeBegin(), getLocalRangeEnd());
1488 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1489 setLocalRangeBegin(Loc);
1492 setLocalRangeEnd(Loc);
1493 for (unsigned i = 0, e = getNumParams(); i != e; ++i)
1494 setParam(i, nullptr);
1495 if (hasExceptionSpec())
1496 setExceptionSpecRange(Loc);
1499 /// \brief Returns the size of the type source info data block that is
1500 /// specific to this type.
1501 unsigned getExtraLocalDataSize() const {
1502 unsigned ExceptSpecSize = hasExceptionSpec() ? sizeof(SourceRange) : 0;
1503 return (getNumParams() * sizeof(ParmVarDecl *)) + ExceptSpecSize;
1506 unsigned getExtraLocalDataAlignment() const { return alignof(ParmVarDecl *); }
1508 QualType getInnerType() const { return getTypePtr()->getReturnType(); }
1511 class FunctionProtoTypeLoc :
1512 public InheritingConcreteTypeLoc<FunctionTypeLoc,
1513 FunctionProtoTypeLoc,
1514 FunctionProtoType> {
1517 class FunctionNoProtoTypeLoc :
1518 public InheritingConcreteTypeLoc<FunctionTypeLoc,
1519 FunctionNoProtoTypeLoc,
1520 FunctionNoProtoType> {
1523 struct ArrayLocInfo {
1524 SourceLocation LBracketLoc, RBracketLoc;
1528 /// \brief Wrapper for source info for arrays.
1529 class ArrayTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
1534 SourceLocation getLBracketLoc() const {
1535 return getLocalData()->LBracketLoc;
1538 void setLBracketLoc(SourceLocation Loc) {
1539 getLocalData()->LBracketLoc = Loc;
1542 SourceLocation getRBracketLoc() const {
1543 return getLocalData()->RBracketLoc;
1546 void setRBracketLoc(SourceLocation Loc) {
1547 getLocalData()->RBracketLoc = Loc;
1550 SourceRange getBracketsRange() const {
1551 return SourceRange(getLBracketLoc(), getRBracketLoc());
1554 Expr *getSizeExpr() const {
1555 return getLocalData()->Size;
1558 void setSizeExpr(Expr *Size) {
1559 getLocalData()->Size = Size;
1562 TypeLoc getElementLoc() const {
1563 return getInnerTypeLoc();
1566 SourceRange getLocalSourceRange() const {
1567 return SourceRange(getLBracketLoc(), getRBracketLoc());
1570 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1571 setLBracketLoc(Loc);
1572 setRBracketLoc(Loc);
1573 setSizeExpr(nullptr);
1576 QualType getInnerType() const { return getTypePtr()->getElementType(); }
1579 class ConstantArrayTypeLoc :
1580 public InheritingConcreteTypeLoc<ArrayTypeLoc,
1581 ConstantArrayTypeLoc,
1582 ConstantArrayType> {
1585 class IncompleteArrayTypeLoc :
1586 public InheritingConcreteTypeLoc<ArrayTypeLoc,
1587 IncompleteArrayTypeLoc,
1588 IncompleteArrayType> {
1591 class DependentSizedArrayTypeLoc :
1592 public InheritingConcreteTypeLoc<ArrayTypeLoc,
1593 DependentSizedArrayTypeLoc,
1594 DependentSizedArrayType> {
1596 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1597 ArrayTypeLoc::initializeLocal(Context, Loc);
1598 setSizeExpr(getTypePtr()->getSizeExpr());
1602 class VariableArrayTypeLoc :
1603 public InheritingConcreteTypeLoc<ArrayTypeLoc,
1604 VariableArrayTypeLoc,
1605 VariableArrayType> {
1608 // Location information for a TemplateName. Rudimentary for now.
1609 struct TemplateNameLocInfo {
1610 SourceLocation NameLoc;
1613 struct TemplateSpecializationLocInfo : TemplateNameLocInfo {
1614 SourceLocation TemplateKWLoc;
1615 SourceLocation LAngleLoc;
1616 SourceLocation RAngleLoc;
1619 class TemplateSpecializationTypeLoc :
1620 public ConcreteTypeLoc<UnqualTypeLoc,
1621 TemplateSpecializationTypeLoc,
1622 TemplateSpecializationType,
1623 TemplateSpecializationLocInfo> {
1625 SourceLocation getTemplateKeywordLoc() const {
1626 return getLocalData()->TemplateKWLoc;
1629 void setTemplateKeywordLoc(SourceLocation Loc) {
1630 getLocalData()->TemplateKWLoc = Loc;
1633 SourceLocation getLAngleLoc() const {
1634 return getLocalData()->LAngleLoc;
1637 void setLAngleLoc(SourceLocation Loc) {
1638 getLocalData()->LAngleLoc = Loc;
1641 SourceLocation getRAngleLoc() const {
1642 return getLocalData()->RAngleLoc;
1645 void setRAngleLoc(SourceLocation Loc) {
1646 getLocalData()->RAngleLoc = Loc;
1649 unsigned getNumArgs() const {
1650 return getTypePtr()->getNumArgs();
1653 void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) {
1654 getArgInfos()[i] = AI;
1657 TemplateArgumentLocInfo getArgLocInfo(unsigned i) const {
1658 return getArgInfos()[i];
1661 TemplateArgumentLoc getArgLoc(unsigned i) const {
1662 return TemplateArgumentLoc(getTypePtr()->getArg(i), getArgLocInfo(i));
1665 SourceLocation getTemplateNameLoc() const {
1666 return getLocalData()->NameLoc;
1669 void setTemplateNameLoc(SourceLocation Loc) {
1670 getLocalData()->NameLoc = Loc;
1673 /// \brief - Copy the location information from the given info.
1674 void copy(TemplateSpecializationTypeLoc Loc) {
1675 unsigned size = getFullDataSize();
1676 assert(size == Loc.getFullDataSize());
1678 // We're potentially copying Expr references here. We don't
1679 // bother retaining them because TypeSourceInfos live forever, so
1680 // as long as the Expr was retained when originally written into
1681 // the TypeLoc, we're okay.
1682 memcpy(Data, Loc.Data, size);
1685 SourceRange getLocalSourceRange() const {
1686 if (getTemplateKeywordLoc().isValid())
1687 return SourceRange(getTemplateKeywordLoc(), getRAngleLoc());
1689 return SourceRange(getTemplateNameLoc(), getRAngleLoc());
1692 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1693 setTemplateKeywordLoc(Loc);
1694 setTemplateNameLoc(Loc);
1697 initializeArgLocs(Context, getNumArgs(), getTypePtr()->getArgs(),
1698 getArgInfos(), Loc);
1701 static void initializeArgLocs(ASTContext &Context, unsigned NumArgs,
1702 const TemplateArgument *Args,
1703 TemplateArgumentLocInfo *ArgInfos,
1704 SourceLocation Loc);
1706 unsigned getExtraLocalDataSize() const {
1707 return getNumArgs() * sizeof(TemplateArgumentLocInfo);
1710 unsigned getExtraLocalDataAlignment() const {
1711 return alignof(TemplateArgumentLocInfo);
1715 TemplateArgumentLocInfo *getArgInfos() const {
1716 return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData());
1720 struct DependentAddressSpaceLocInfo {
1722 SourceRange OperandParens;
1723 SourceLocation AttrLoc;
1726 class DependentAddressSpaceTypeLoc
1727 : public ConcreteTypeLoc<UnqualTypeLoc,
1728 DependentAddressSpaceTypeLoc,
1729 DependentAddressSpaceType,
1730 DependentAddressSpaceLocInfo> {
1732 /// The location of the attribute name, i.e.
1733 /// int * __attribute__((address_space(11)))
1735 SourceLocation getAttrNameLoc() const {
1736 return getLocalData()->AttrLoc;
1738 void setAttrNameLoc(SourceLocation loc) {
1739 getLocalData()->AttrLoc = loc;
1742 /// The attribute's expression operand, if it has one.
1743 /// int * __attribute__((address_space(11)))
1745 Expr *getAttrExprOperand() const {
1746 return getLocalData()->ExprOperand;
1748 void setAttrExprOperand(Expr *e) {
1749 getLocalData()->ExprOperand = e;
1752 /// The location of the parentheses around the operand, if there is
1754 /// int * __attribute__((address_space(11)))
1756 SourceRange getAttrOperandParensRange() const {
1757 return getLocalData()->OperandParens;
1759 void setAttrOperandParensRange(SourceRange range) {
1760 getLocalData()->OperandParens = range;
1763 SourceRange getLocalSourceRange() const {
1764 SourceRange range(getAttrNameLoc());
1765 range.setEnd(getAttrOperandParensRange().getEnd());
1769 /// Returns the type before the address space attribute application
1771 /// int * __attribute__((address_space(11))) *
1773 QualType getInnerType() const {
1774 return this->getTypePtr()->getPointeeType();
1777 TypeLoc getPointeeTypeLoc() const {
1778 return this->getInnerTypeLoc();
1781 void initializeLocal(ASTContext &Context, SourceLocation loc) {
1782 setAttrNameLoc(loc);
1783 setAttrOperandParensRange(SourceRange(loc));
1784 setAttrExprOperand(getTypePtr()->getAddrSpaceExpr());
1788 //===----------------------------------------------------------------------===//
1790 // All of these need proper implementations.
1792 //===----------------------------------------------------------------------===//
1794 // FIXME: size expression and attribute locations (or keyword if we
1795 // ever fully support altivec syntax).
1796 class VectorTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
1801 // FIXME: size expression and attribute locations.
1802 class ExtVectorTypeLoc : public InheritingConcreteTypeLoc<VectorTypeLoc,
1807 // FIXME: attribute locations.
1808 // For some reason, this isn't a subtype of VectorType.
1809 class DependentSizedExtVectorTypeLoc :
1810 public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
1811 DependentSizedExtVectorTypeLoc,
1812 DependentSizedExtVectorType> {
1815 // FIXME: location of the '_Complex' keyword.
1816 class ComplexTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
1821 struct TypeofLocInfo {
1822 SourceLocation TypeofLoc;
1823 SourceLocation LParenLoc;
1824 SourceLocation RParenLoc;
1827 struct TypeOfExprTypeLocInfo : public TypeofLocInfo {
1830 struct TypeOfTypeLocInfo : public TypeofLocInfo {
1831 TypeSourceInfo* UnderlyingTInfo;
1834 template <class Derived, class TypeClass, class LocalData = TypeofLocInfo>
1835 class TypeofLikeTypeLoc
1836 : public ConcreteTypeLoc<UnqualTypeLoc, Derived, TypeClass, LocalData> {
1838 SourceLocation getTypeofLoc() const {
1839 return this->getLocalData()->TypeofLoc;
1842 void setTypeofLoc(SourceLocation Loc) {
1843 this->getLocalData()->TypeofLoc = Loc;
1846 SourceLocation getLParenLoc() const {
1847 return this->getLocalData()->LParenLoc;
1850 void setLParenLoc(SourceLocation Loc) {
1851 this->getLocalData()->LParenLoc = Loc;
1854 SourceLocation getRParenLoc() const {
1855 return this->getLocalData()->RParenLoc;
1858 void setRParenLoc(SourceLocation Loc) {
1859 this->getLocalData()->RParenLoc = Loc;
1862 SourceRange getParensRange() const {
1863 return SourceRange(getLParenLoc(), getRParenLoc());
1866 void setParensRange(SourceRange range) {
1867 setLParenLoc(range.getBegin());
1868 setRParenLoc(range.getEnd());
1871 SourceRange getLocalSourceRange() const {
1872 return SourceRange(getTypeofLoc(), getRParenLoc());
1875 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1882 class TypeOfExprTypeLoc : public TypeofLikeTypeLoc<TypeOfExprTypeLoc,
1884 TypeOfExprTypeLocInfo> {
1886 Expr* getUnderlyingExpr() const {
1887 return getTypePtr()->getUnderlyingExpr();
1890 // Reimplemented to account for GNU/C++ extension
1891 // typeof unary-expression
1892 // where there are no parentheses.
1893 SourceRange getLocalSourceRange() const;
1897 : public TypeofLikeTypeLoc<TypeOfTypeLoc, TypeOfType, TypeOfTypeLocInfo> {
1899 QualType getUnderlyingType() const {
1900 return this->getTypePtr()->getUnderlyingType();
1903 TypeSourceInfo* getUnderlyingTInfo() const {
1904 return this->getLocalData()->UnderlyingTInfo;
1907 void setUnderlyingTInfo(TypeSourceInfo* TI) const {
1908 this->getLocalData()->UnderlyingTInfo = TI;
1911 void initializeLocal(ASTContext &Context, SourceLocation Loc);
1914 // FIXME: location of the 'decltype' and parens.
1915 class DecltypeTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
1919 Expr *getUnderlyingExpr() const { return getTypePtr()->getUnderlyingExpr(); }
1922 struct UnaryTransformTypeLocInfo {
1923 // FIXME: While there's only one unary transform right now, future ones may
1924 // need different representations
1925 SourceLocation KWLoc, LParenLoc, RParenLoc;
1926 TypeSourceInfo *UnderlyingTInfo;
1929 class UnaryTransformTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
1930 UnaryTransformTypeLoc,
1932 UnaryTransformTypeLocInfo> {
1934 SourceLocation getKWLoc() const { return getLocalData()->KWLoc; }
1935 void setKWLoc(SourceLocation Loc) { getLocalData()->KWLoc = Loc; }
1937 SourceLocation getLParenLoc() const { return getLocalData()->LParenLoc; }
1938 void setLParenLoc(SourceLocation Loc) { getLocalData()->LParenLoc = Loc; }
1940 SourceLocation getRParenLoc() const { return getLocalData()->RParenLoc; }
1941 void setRParenLoc(SourceLocation Loc) { getLocalData()->RParenLoc = Loc; }
1943 TypeSourceInfo* getUnderlyingTInfo() const {
1944 return getLocalData()->UnderlyingTInfo;
1947 void setUnderlyingTInfo(TypeSourceInfo *TInfo) {
1948 getLocalData()->UnderlyingTInfo = TInfo;
1951 SourceRange getLocalSourceRange() const {
1952 return SourceRange(getKWLoc(), getRParenLoc());
1955 SourceRange getParensRange() const {
1956 return SourceRange(getLParenLoc(), getRParenLoc());
1959 void setParensRange(SourceRange Range) {
1960 setLParenLoc(Range.getBegin());
1961 setRParenLoc(Range.getEnd());
1964 void initializeLocal(ASTContext &Context, SourceLocation Loc);
1967 class DeducedTypeLoc
1968 : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, DeducedTypeLoc,
1972 : public InheritingConcreteTypeLoc<DeducedTypeLoc, AutoTypeLoc, AutoType> {
1975 class DeducedTemplateSpecializationTypeLoc
1976 : public InheritingConcreteTypeLoc<DeducedTypeLoc,
1977 DeducedTemplateSpecializationTypeLoc,
1978 DeducedTemplateSpecializationType> {
1980 SourceLocation getTemplateNameLoc() const {
1981 return getNameLoc();
1984 void setTemplateNameLoc(SourceLocation Loc) {
1989 struct ElaboratedLocInfo {
1990 SourceLocation ElaboratedKWLoc;
1992 /// \brief Data associated with the nested-name-specifier location.
1993 void *QualifierData;
1996 class ElaboratedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
1999 ElaboratedLocInfo> {
2001 SourceLocation getElaboratedKeywordLoc() const {
2002 return this->getLocalData()->ElaboratedKWLoc;
2005 void setElaboratedKeywordLoc(SourceLocation Loc) {
2006 this->getLocalData()->ElaboratedKWLoc = Loc;
2009 NestedNameSpecifierLoc getQualifierLoc() const {
2010 return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
2011 getLocalData()->QualifierData);
2014 void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
2015 assert(QualifierLoc.getNestedNameSpecifier()
2016 == getTypePtr()->getQualifier() &&
2017 "Inconsistent nested-name-specifier pointer");
2018 getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
2021 SourceRange getLocalSourceRange() const {
2022 if (getElaboratedKeywordLoc().isValid())
2023 if (getQualifierLoc())
2024 return SourceRange(getElaboratedKeywordLoc(),
2025 getQualifierLoc().getEndLoc());
2027 return SourceRange(getElaboratedKeywordLoc());
2029 return getQualifierLoc().getSourceRange();
2032 void initializeLocal(ASTContext &Context, SourceLocation Loc);
2034 TypeLoc getNamedTypeLoc() const {
2035 return getInnerTypeLoc();
2038 QualType getInnerType() const {
2039 return getTypePtr()->getNamedType();
2042 void copy(ElaboratedTypeLoc Loc) {
2043 unsigned size = getFullDataSize();
2044 assert(size == Loc.getFullDataSize());
2045 memcpy(Data, Loc.Data, size);
2049 // This is exactly the structure of an ElaboratedTypeLoc whose inner
2050 // type is some sort of TypeDeclTypeLoc.
2051 struct DependentNameLocInfo : ElaboratedLocInfo {
2052 SourceLocation NameLoc;
2055 class DependentNameTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
2056 DependentNameTypeLoc,
2058 DependentNameLocInfo> {
2060 SourceLocation getElaboratedKeywordLoc() const {
2061 return this->getLocalData()->ElaboratedKWLoc;
2064 void setElaboratedKeywordLoc(SourceLocation Loc) {
2065 this->getLocalData()->ElaboratedKWLoc = Loc;
2068 NestedNameSpecifierLoc getQualifierLoc() const {
2069 return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
2070 getLocalData()->QualifierData);
2073 void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
2074 assert(QualifierLoc.getNestedNameSpecifier()
2075 == getTypePtr()->getQualifier() &&
2076 "Inconsistent nested-name-specifier pointer");
2077 getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
2080 SourceLocation getNameLoc() const {
2081 return this->getLocalData()->NameLoc;
2084 void setNameLoc(SourceLocation Loc) {
2085 this->getLocalData()->NameLoc = Loc;
2088 SourceRange getLocalSourceRange() const {
2089 if (getElaboratedKeywordLoc().isValid())
2090 return SourceRange(getElaboratedKeywordLoc(), getNameLoc());
2092 return SourceRange(getQualifierLoc().getBeginLoc(), getNameLoc());
2095 void copy(DependentNameTypeLoc Loc) {
2096 unsigned size = getFullDataSize();
2097 assert(size == Loc.getFullDataSize());
2098 memcpy(Data, Loc.Data, size);
2101 void initializeLocal(ASTContext &Context, SourceLocation Loc);
2104 struct DependentTemplateSpecializationLocInfo : DependentNameLocInfo {
2105 SourceLocation TemplateKWLoc;
2106 SourceLocation LAngleLoc;
2107 SourceLocation RAngleLoc;
2108 // followed by a TemplateArgumentLocInfo[]
2111 class DependentTemplateSpecializationTypeLoc :
2112 public ConcreteTypeLoc<UnqualTypeLoc,
2113 DependentTemplateSpecializationTypeLoc,
2114 DependentTemplateSpecializationType,
2115 DependentTemplateSpecializationLocInfo> {
2117 SourceLocation getElaboratedKeywordLoc() const {
2118 return this->getLocalData()->ElaboratedKWLoc;
2121 void setElaboratedKeywordLoc(SourceLocation Loc) {
2122 this->getLocalData()->ElaboratedKWLoc = Loc;
2125 NestedNameSpecifierLoc getQualifierLoc() const {
2126 if (!getLocalData()->QualifierData)
2127 return NestedNameSpecifierLoc();
2129 return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
2130 getLocalData()->QualifierData);
2133 void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
2134 if (!QualifierLoc) {
2135 // Even if we have a nested-name-specifier in the dependent
2136 // template specialization type, we won't record the nested-name-specifier
2137 // location information when this type-source location information is
2138 // part of a nested-name-specifier.
2139 getLocalData()->QualifierData = nullptr;
2143 assert(QualifierLoc.getNestedNameSpecifier()
2144 == getTypePtr()->getQualifier() &&
2145 "Inconsistent nested-name-specifier pointer");
2146 getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
2149 SourceLocation getTemplateKeywordLoc() const {
2150 return getLocalData()->TemplateKWLoc;
2153 void setTemplateKeywordLoc(SourceLocation Loc) {
2154 getLocalData()->TemplateKWLoc = Loc;
2157 SourceLocation getTemplateNameLoc() const {
2158 return this->getLocalData()->NameLoc;
2161 void setTemplateNameLoc(SourceLocation Loc) {
2162 this->getLocalData()->NameLoc = Loc;
2165 SourceLocation getLAngleLoc() const {
2166 return this->getLocalData()->LAngleLoc;
2169 void setLAngleLoc(SourceLocation Loc) {
2170 this->getLocalData()->LAngleLoc = Loc;
2173 SourceLocation getRAngleLoc() const {
2174 return this->getLocalData()->RAngleLoc;
2177 void setRAngleLoc(SourceLocation Loc) {
2178 this->getLocalData()->RAngleLoc = Loc;
2181 unsigned getNumArgs() const {
2182 return getTypePtr()->getNumArgs();
2185 void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) {
2186 getArgInfos()[i] = AI;
2189 TemplateArgumentLocInfo getArgLocInfo(unsigned i) const {
2190 return getArgInfos()[i];
2193 TemplateArgumentLoc getArgLoc(unsigned i) const {
2194 return TemplateArgumentLoc(getTypePtr()->getArg(i), getArgLocInfo(i));
2197 SourceRange getLocalSourceRange() const {
2198 if (getElaboratedKeywordLoc().isValid())
2199 return SourceRange(getElaboratedKeywordLoc(), getRAngleLoc());
2200 else if (getQualifierLoc())
2201 return SourceRange(getQualifierLoc().getBeginLoc(), getRAngleLoc());
2202 else if (getTemplateKeywordLoc().isValid())
2203 return SourceRange(getTemplateKeywordLoc(), getRAngleLoc());
2205 return SourceRange(getTemplateNameLoc(), getRAngleLoc());
2208 void copy(DependentTemplateSpecializationTypeLoc Loc) {
2209 unsigned size = getFullDataSize();
2210 assert(size == Loc.getFullDataSize());
2211 memcpy(Data, Loc.Data, size);
2214 void initializeLocal(ASTContext &Context, SourceLocation Loc);
2216 unsigned getExtraLocalDataSize() const {
2217 return getNumArgs() * sizeof(TemplateArgumentLocInfo);
2220 unsigned getExtraLocalDataAlignment() const {
2221 return alignof(TemplateArgumentLocInfo);
2225 TemplateArgumentLocInfo *getArgInfos() const {
2226 return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData());
2230 struct PackExpansionTypeLocInfo {
2231 SourceLocation EllipsisLoc;
2234 class PackExpansionTypeLoc
2235 : public ConcreteTypeLoc<UnqualTypeLoc, PackExpansionTypeLoc,
2236 PackExpansionType, PackExpansionTypeLocInfo> {
2238 SourceLocation getEllipsisLoc() const {
2239 return this->getLocalData()->EllipsisLoc;
2242 void setEllipsisLoc(SourceLocation Loc) {
2243 this->getLocalData()->EllipsisLoc = Loc;
2246 SourceRange getLocalSourceRange() const {
2247 return SourceRange(getEllipsisLoc(), getEllipsisLoc());
2250 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
2251 setEllipsisLoc(Loc);
2254 TypeLoc getPatternLoc() const {
2255 return getInnerTypeLoc();
2258 QualType getInnerType() const {
2259 return this->getTypePtr()->getPattern();
2263 struct AtomicTypeLocInfo {
2264 SourceLocation KWLoc, LParenLoc, RParenLoc;
2267 class AtomicTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, AtomicTypeLoc,
2268 AtomicType, AtomicTypeLocInfo> {
2270 TypeLoc getValueLoc() const {
2271 return this->getInnerTypeLoc();
2274 SourceRange getLocalSourceRange() const {
2275 return SourceRange(getKWLoc(), getRParenLoc());
2278 SourceLocation getKWLoc() const {
2279 return this->getLocalData()->KWLoc;
2282 void setKWLoc(SourceLocation Loc) {
2283 this->getLocalData()->KWLoc = Loc;
2286 SourceLocation getLParenLoc() const {
2287 return this->getLocalData()->LParenLoc;
2290 void setLParenLoc(SourceLocation Loc) {
2291 this->getLocalData()->LParenLoc = Loc;
2294 SourceLocation getRParenLoc() const {
2295 return this->getLocalData()->RParenLoc;
2298 void setRParenLoc(SourceLocation Loc) {
2299 this->getLocalData()->RParenLoc = Loc;
2302 SourceRange getParensRange() const {
2303 return SourceRange(getLParenLoc(), getRParenLoc());
2306 void setParensRange(SourceRange Range) {
2307 setLParenLoc(Range.getBegin());
2308 setRParenLoc(Range.getEnd());
2311 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
2317 QualType getInnerType() const {
2318 return this->getTypePtr()->getValueType();
2322 struct PipeTypeLocInfo {
2323 SourceLocation KWLoc;
2326 class PipeTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, PipeTypeLoc, PipeType,
2329 TypeLoc getValueLoc() const { return this->getInnerTypeLoc(); }
2331 SourceRange getLocalSourceRange() const { return SourceRange(getKWLoc()); }
2333 SourceLocation getKWLoc() const { return this->getLocalData()->KWLoc; }
2334 void setKWLoc(SourceLocation Loc) { this->getLocalData()->KWLoc = Loc; }
2336 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
2340 QualType getInnerType() const { return this->getTypePtr()->getElementType(); }
2343 template <typename T>
2344 inline T TypeLoc::getAsAdjusted() const {
2345 TypeLoc Cur = *this;
2346 while (!T::isKind(Cur)) {
2347 if (auto PTL = Cur.getAs<ParenTypeLoc>())
2348 Cur = PTL.getInnerLoc();
2349 else if (auto ATL = Cur.getAs<AttributedTypeLoc>())
2350 Cur = ATL.getModifiedLoc();
2351 else if (auto ETL = Cur.getAs<ElaboratedTypeLoc>())
2352 Cur = ETL.getNamedTypeLoc();
2353 else if (auto ATL = Cur.getAs<AdjustedTypeLoc>())
2354 Cur = ATL.getOriginalLoc();
2358 return Cur.getAs<T>();
2361 } // namespace clang
2363 #endif // LLVM_CLANG_AST_TYPELOC_H