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 /// The kinds of TypeLocs. Equivalent to the Type::TypeClass enum,
74 /// except it also defines a Qualified enum that corresponds to the
75 /// QualifiedLoc class.
77 #define ABSTRACT_TYPE(Class, Base)
78 #define TYPE(Class, Base) \
80 #include "clang/AST/TypeNodes.def"
84 TypeLoc() : Ty(nullptr), Data(nullptr) { }
85 TypeLoc(QualType ty, void *opaqueData)
86 : Ty(ty.getAsOpaquePtr()), Data(opaqueData) { }
87 TypeLoc(const Type *ty, void *opaqueData)
88 : Ty(ty), Data(opaqueData) { }
90 TypeLocClass getTypeLocClass() const {
91 if (getType().hasLocalQualifiers()) return Qualified;
92 return (TypeLocClass) getType()->getTypeClass();
95 bool isNull() const { return !Ty; }
96 explicit operator bool() const { return Ty; }
98 /// \brief Returns the size of type source info data block for the given type.
99 static unsigned getFullDataSizeForType(QualType Ty);
101 /// \brief Returns the alignment of type source info data block for
103 static unsigned getLocalAlignmentForType(QualType Ty);
105 /// \brief Get the type for which this source info wrapper provides
107 QualType getType() const {
108 return QualType::getFromOpaquePtr(Ty);
111 const Type *getTypePtr() const {
112 return QualType::getFromOpaquePtr(Ty).getTypePtr();
115 /// \brief Get the pointer where source information is stored.
116 void *getOpaqueData() const {
120 /// \brief Get the begin source location.
121 SourceLocation getBeginLoc() const;
123 /// \brief Get the end source location.
124 SourceLocation getEndLoc() const;
126 /// \brief Get the full source range.
127 SourceRange getSourceRange() const LLVM_READONLY {
128 return SourceRange(getBeginLoc(), getEndLoc());
130 SourceLocation getLocStart() const LLVM_READONLY { return getBeginLoc(); }
131 SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
133 /// \brief Get the local source range.
134 SourceRange getLocalSourceRange() const {
135 return getLocalSourceRangeImpl(*this);
138 /// \brief Returns the size of the type source info data block.
139 unsigned getFullDataSize() const {
140 return getFullDataSizeForType(getType());
143 /// \brief Get the next TypeLoc pointed by this TypeLoc, e.g for "int*" the
144 /// TypeLoc is a PointerLoc and next TypeLoc is for "int".
145 TypeLoc getNextTypeLoc() const {
146 return getNextTypeLocImpl(*this);
149 /// \brief Skips past any qualifiers, if this is qualified.
150 UnqualTypeLoc getUnqualifiedLoc() const; // implemented in this header
152 TypeLoc IgnoreParens() const;
154 /// \brief Find a type with the location of an explicit type qualifier.
156 /// The result, if non-null, will be one of:
159 /// AttributedTypeLoc, for those type attributes that behave as qualifiers
160 TypeLoc findExplicitQualifierLoc() const;
162 /// \brief Initializes this to state that every location in this
163 /// type is the given location.
165 /// This method exists to provide a simple transition for code that
166 /// relies on location-less types.
167 void initialize(ASTContext &Context, SourceLocation Loc) const {
168 initializeImpl(Context, *this, Loc);
171 /// \brief Initializes this by copying its information from another
172 /// TypeLoc of the same type.
173 void initializeFullCopy(TypeLoc Other) {
174 assert(getType() == Other.getType());
178 /// \brief Initializes this by copying its information from another
179 /// TypeLoc of the same type. The given size must be the full data
181 void initializeFullCopy(TypeLoc Other, unsigned Size) {
182 assert(getType() == Other.getType());
183 assert(getFullDataSize() == Size);
187 /// Copies the other type loc into this one.
188 void copy(TypeLoc other);
190 friend bool operator==(const TypeLoc &LHS, const TypeLoc &RHS) {
191 return LHS.Ty == RHS.Ty && LHS.Data == RHS.Data;
194 friend bool operator!=(const TypeLoc &LHS, const TypeLoc &RHS) {
195 return !(LHS == RHS);
198 /// Find the location of the nullability specifier (__nonnull,
199 /// __nullable, or __null_unspecifier), if there is one.
200 SourceLocation findNullabilityLoc() const;
203 static bool isKind(const TypeLoc&) {
207 static void initializeImpl(ASTContext &Context, TypeLoc TL,
209 static TypeLoc getNextTypeLocImpl(TypeLoc TL);
210 static TypeLoc IgnoreParensImpl(TypeLoc TL);
211 static SourceRange getLocalSourceRangeImpl(TypeLoc TL);
214 /// \brief Return the TypeLoc for a type source info.
215 inline TypeLoc TypeSourceInfo::getTypeLoc() const {
216 // TODO: is this alignment already sufficient?
217 return TypeLoc(Ty, const_cast<void*>(static_cast<const void*>(this + 1)));
220 /// \brief Wrapper of type source information for a type with
221 /// no direct qualifiers.
222 class UnqualTypeLoc : public TypeLoc {
225 UnqualTypeLoc(const Type *Ty, void *Data) : TypeLoc(Ty, Data) {}
227 const Type *getTypePtr() const {
228 return reinterpret_cast<const Type*>(Ty);
231 TypeLocClass getTypeLocClass() const {
232 return (TypeLocClass) getTypePtr()->getTypeClass();
236 friend class TypeLoc;
237 static bool isKind(const TypeLoc &TL) {
238 return !TL.getType().hasLocalQualifiers();
242 /// \brief Wrapper of type source information for a type with
243 /// non-trivial direct qualifiers.
245 /// Currently, we intentionally do not provide source location for
247 class QualifiedTypeLoc : public TypeLoc {
249 SourceRange getLocalSourceRange() const {
250 return SourceRange();
253 UnqualTypeLoc getUnqualifiedLoc() const {
255 TypeLoc::getLocalAlignmentForType(QualType(getTypePtr(), 0));
256 uintptr_t dataInt = reinterpret_cast<uintptr_t>(Data);
257 dataInt = llvm::alignTo(dataInt, align);
258 return UnqualTypeLoc(getTypePtr(), reinterpret_cast<void*>(dataInt));
261 /// Initializes the local data of this type source info block to
262 /// provide no information.
263 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
267 void copyLocal(TypeLoc other) {
271 TypeLoc getNextTypeLoc() const {
272 return getUnqualifiedLoc();
275 /// \brief Returns the size of the type source info data block that is
276 /// specific to this type.
277 unsigned getLocalDataSize() const {
278 // In fact, we don't currently preserve any location information
283 /// \brief Returns the alignment of the type source info data block that is
284 /// specific to this type.
285 unsigned getLocalDataAlignment() const {
286 // We don't preserve any location information.
291 friend class TypeLoc;
292 static bool isKind(const TypeLoc &TL) {
293 return TL.getType().hasLocalQualifiers();
297 inline UnqualTypeLoc TypeLoc::getUnqualifiedLoc() const {
298 if (QualifiedTypeLoc Loc = getAs<QualifiedTypeLoc>())
299 return Loc.getUnqualifiedLoc();
300 return castAs<UnqualTypeLoc>();
303 /// A metaprogramming base class for TypeLoc classes which correspond
304 /// to a particular Type subclass. It is accepted for a single
305 /// TypeLoc class to correspond to multiple Type classes.
307 /// \tparam Base a class from which to derive
308 /// \tparam Derived the class deriving from this one
309 /// \tparam TypeClass the concrete Type subclass associated with this
311 /// \tparam LocalData the structure type of local location data for
314 /// TypeLocs with non-constant amounts of local data should override
315 /// getExtraLocalDataSize(); getExtraLocalData() will then point to
316 /// this extra memory.
318 /// TypeLocs with an inner type should define
319 /// QualType getInnerType() const
320 /// and getInnerTypeLoc() will then point to this inner type's
323 /// A word about hierarchies: this template is not designed to be
324 /// derived from multiple times in a hierarchy. It is also not
325 /// designed to be used for classes where subtypes might provide
326 /// different amounts of source information. It should be subclassed
327 /// only at the deepest portion of the hierarchy where all children
328 /// have identical source information; if that's an abstract type,
329 /// then further descendents should inherit from
330 /// InheritingConcreteTypeLoc instead.
331 template <class Base, class Derived, class TypeClass, class LocalData>
332 class ConcreteTypeLoc : public Base {
334 const Derived *asDerived() const {
335 return static_cast<const Derived*>(this);
338 friend class TypeLoc;
339 static bool isKind(const TypeLoc &TL) {
340 return !TL.getType().hasLocalQualifiers() &&
341 Derived::classofType(TL.getTypePtr());
344 static bool classofType(const Type *Ty) {
345 return TypeClass::classof(Ty);
349 unsigned getLocalDataAlignment() const {
350 return std::max(llvm::alignOf<LocalData>(),
351 asDerived()->getExtraLocalDataAlignment());
353 unsigned getLocalDataSize() const {
354 unsigned size = sizeof(LocalData);
355 unsigned extraAlign = asDerived()->getExtraLocalDataAlignment();
356 size = llvm::alignTo(size, extraAlign);
357 size += asDerived()->getExtraLocalDataSize();
361 void copyLocal(Derived other) {
362 // Some subclasses have no data to copy.
363 if (asDerived()->getLocalDataSize() == 0) return;
365 // Copy the fixed-sized local data.
366 memcpy(getLocalData(), other.getLocalData(), sizeof(LocalData));
368 // Copy the variable-sized local data. We need to do this
369 // separately because the padding in the source and the padding in
370 // the destination might be different.
371 memcpy(getExtraLocalData(), other.getExtraLocalData(),
372 asDerived()->getExtraLocalDataSize());
375 TypeLoc getNextTypeLoc() const {
376 return getNextTypeLoc(asDerived()->getInnerType());
379 const TypeClass *getTypePtr() const {
380 return cast<TypeClass>(Base::getTypePtr());
384 unsigned getExtraLocalDataSize() const {
388 unsigned getExtraLocalDataAlignment() const {
392 LocalData *getLocalData() const {
393 return static_cast<LocalData*>(Base::Data);
396 /// Gets a pointer past the Info structure; useful for classes with
397 /// local data that can't be captured in the Info (e.g. because it's
398 /// of variable size).
399 void *getExtraLocalData() const {
400 unsigned size = sizeof(LocalData);
401 unsigned extraAlign = asDerived()->getExtraLocalDataAlignment();
402 size = llvm::alignTo(size, extraAlign);
403 return reinterpret_cast<char*>(Base::Data) + size;
406 void *getNonLocalData() const {
407 uintptr_t data = reinterpret_cast<uintptr_t>(Base::Data);
408 data += asDerived()->getLocalDataSize();
409 data = llvm::alignTo(data, getNextTypeAlign());
410 return reinterpret_cast<void*>(data);
413 struct HasNoInnerType {};
414 HasNoInnerType getInnerType() const { return HasNoInnerType(); }
416 TypeLoc getInnerTypeLoc() const {
417 return TypeLoc(asDerived()->getInnerType(), getNonLocalData());
421 unsigned getInnerTypeSize() const {
422 return getInnerTypeSize(asDerived()->getInnerType());
425 unsigned getInnerTypeSize(HasNoInnerType _) const {
429 unsigned getInnerTypeSize(QualType _) const {
430 return getInnerTypeLoc().getFullDataSize();
433 unsigned getNextTypeAlign() const {
434 return getNextTypeAlign(asDerived()->getInnerType());
437 unsigned getNextTypeAlign(HasNoInnerType _) const {
441 unsigned getNextTypeAlign(QualType T) const {
442 return TypeLoc::getLocalAlignmentForType(T);
445 TypeLoc getNextTypeLoc(HasNoInnerType _) const {
449 TypeLoc getNextTypeLoc(QualType T) const {
450 return TypeLoc(T, getNonLocalData());
454 /// A metaprogramming class designed for concrete subtypes of abstract
455 /// types where all subtypes share equivalently-structured source
456 /// information. See the note on ConcreteTypeLoc.
457 template <class Base, class Derived, class TypeClass>
458 class InheritingConcreteTypeLoc : public Base {
459 friend class TypeLoc;
460 static bool classofType(const Type *Ty) {
461 return TypeClass::classof(Ty);
464 static bool isKind(const TypeLoc &TL) {
465 return !TL.getType().hasLocalQualifiers() &&
466 Derived::classofType(TL.getTypePtr());
468 static bool isKind(const UnqualTypeLoc &TL) {
469 return Derived::classofType(TL.getTypePtr());
473 const TypeClass *getTypePtr() const {
474 return cast<TypeClass>(Base::getTypePtr());
479 struct TypeSpecLocInfo {
480 SourceLocation NameLoc;
483 /// \brief A reasonable base class for TypeLocs that correspond to
484 /// types that are written as a type-specifier.
485 class TypeSpecTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
490 enum { LocalDataSize = sizeof(TypeSpecLocInfo),
491 LocalDataAlignment = llvm::AlignOf<TypeSpecLocInfo>::Alignment };
493 SourceLocation getNameLoc() const {
494 return this->getLocalData()->NameLoc;
496 void setNameLoc(SourceLocation Loc) {
497 this->getLocalData()->NameLoc = Loc;
499 SourceRange getLocalSourceRange() const {
500 return SourceRange(getNameLoc(), getNameLoc());
502 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
507 friend class TypeLoc;
508 static bool isKind(const TypeLoc &TL);
512 struct BuiltinLocInfo {
513 SourceLocation BuiltinLoc;
516 /// \brief Wrapper for source info for builtin types.
517 class BuiltinTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
522 SourceLocation getBuiltinLoc() const {
523 return getLocalData()->BuiltinLoc;
525 void setBuiltinLoc(SourceLocation Loc) {
526 getLocalData()->BuiltinLoc = Loc;
529 SourceLocation getNameLoc() const { return getBuiltinLoc(); }
531 WrittenBuiltinSpecs& getWrittenBuiltinSpecs() {
532 return *(static_cast<WrittenBuiltinSpecs*>(getExtraLocalData()));
534 const WrittenBuiltinSpecs& getWrittenBuiltinSpecs() const {
535 return *(static_cast<WrittenBuiltinSpecs*>(getExtraLocalData()));
538 bool needsExtraLocalData() const {
539 BuiltinType::Kind bk = getTypePtr()->getKind();
540 return (bk >= BuiltinType::UShort && bk <= BuiltinType::UInt128)
541 || (bk >= BuiltinType::Short && bk <= BuiltinType::Float128)
542 || bk == BuiltinType::UChar
543 || bk == BuiltinType::SChar;
546 unsigned getExtraLocalDataSize() const {
547 return needsExtraLocalData() ? sizeof(WrittenBuiltinSpecs) : 0;
550 unsigned getExtraLocalDataAlignment() const {
551 return needsExtraLocalData() ? llvm::alignOf<WrittenBuiltinSpecs>() : 1;
554 SourceRange getLocalSourceRange() const {
555 return SourceRange(getBuiltinLoc(), getBuiltinLoc());
558 TypeSpecifierSign getWrittenSignSpec() const {
559 if (needsExtraLocalData())
560 return static_cast<TypeSpecifierSign>(getWrittenBuiltinSpecs().Sign);
562 return TSS_unspecified;
564 bool hasWrittenSignSpec() const {
565 return getWrittenSignSpec() != TSS_unspecified;
567 void setWrittenSignSpec(TypeSpecifierSign written) {
568 if (needsExtraLocalData())
569 getWrittenBuiltinSpecs().Sign = written;
572 TypeSpecifierWidth getWrittenWidthSpec() const {
573 if (needsExtraLocalData())
574 return static_cast<TypeSpecifierWidth>(getWrittenBuiltinSpecs().Width);
576 return TSW_unspecified;
578 bool hasWrittenWidthSpec() const {
579 return getWrittenWidthSpec() != TSW_unspecified;
581 void setWrittenWidthSpec(TypeSpecifierWidth written) {
582 if (needsExtraLocalData())
583 getWrittenBuiltinSpecs().Width = written;
586 TypeSpecifierType getWrittenTypeSpec() const;
587 bool hasWrittenTypeSpec() const {
588 return getWrittenTypeSpec() != TST_unspecified;
590 void setWrittenTypeSpec(TypeSpecifierType written) {
591 if (needsExtraLocalData())
592 getWrittenBuiltinSpecs().Type = written;
595 bool hasModeAttr() const {
596 if (needsExtraLocalData())
597 return getWrittenBuiltinSpecs().ModeAttr;
601 void setModeAttr(bool written) {
602 if (needsExtraLocalData())
603 getWrittenBuiltinSpecs().ModeAttr = written;
606 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
608 if (needsExtraLocalData()) {
609 WrittenBuiltinSpecs &wbs = getWrittenBuiltinSpecs();
610 wbs.Sign = TSS_unspecified;
611 wbs.Width = TSW_unspecified;
612 wbs.Type = TST_unspecified;
613 wbs.ModeAttr = false;
619 /// \brief Wrapper for source info for typedefs.
620 class TypedefTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
624 TypedefNameDecl *getTypedefNameDecl() const {
625 return getTypePtr()->getDecl();
629 /// \brief Wrapper for source info for injected class names of class
631 class InjectedClassNameTypeLoc :
632 public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
633 InjectedClassNameTypeLoc,
634 InjectedClassNameType> {
636 CXXRecordDecl *getDecl() const {
637 return getTypePtr()->getDecl();
641 /// \brief Wrapper for source info for unresolved typename using decls.
642 class UnresolvedUsingTypeLoc :
643 public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
644 UnresolvedUsingTypeLoc,
645 UnresolvedUsingType> {
647 UnresolvedUsingTypenameDecl *getDecl() const {
648 return getTypePtr()->getDecl();
652 /// \brief Wrapper for source info for tag types. Note that this only
653 /// records source info for the name itself; a type written 'struct foo'
654 /// should be represented as an ElaboratedTypeLoc. We currently
655 /// only do that when C++ is enabled because of the expense of
656 /// creating an ElaboratedType node for so many type references in C.
657 class TagTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
661 TagDecl *getDecl() const { return getTypePtr()->getDecl(); }
663 /// \brief True if the tag was defined in this type specifier.
664 bool isDefinition() const {
665 TagDecl *D = getDecl();
666 return D->isCompleteDefinition() &&
667 (D->getIdentifier() == nullptr || D->getLocation() == getNameLoc());
671 /// \brief Wrapper for source info for record types.
672 class RecordTypeLoc : public InheritingConcreteTypeLoc<TagTypeLoc,
676 RecordDecl *getDecl() const { return getTypePtr()->getDecl(); }
679 /// \brief Wrapper for source info for enum types.
680 class EnumTypeLoc : public InheritingConcreteTypeLoc<TagTypeLoc,
684 EnumDecl *getDecl() const { return getTypePtr()->getDecl(); }
687 /// \brief Wrapper for template type parameters.
688 class TemplateTypeParmTypeLoc :
689 public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
690 TemplateTypeParmTypeLoc,
691 TemplateTypeParmType> {
693 TemplateTypeParmDecl *getDecl() const { return getTypePtr()->getDecl(); }
696 /// \brief Wrapper for substituted template type parameters.
697 class SubstTemplateTypeParmTypeLoc :
698 public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
699 SubstTemplateTypeParmTypeLoc,
700 SubstTemplateTypeParmType> {
703 /// \brief Wrapper for substituted template type parameters.
704 class SubstTemplateTypeParmPackTypeLoc :
705 public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
706 SubstTemplateTypeParmPackTypeLoc,
707 SubstTemplateTypeParmPackType> {
710 struct AttributedLocInfo {
714 /// A raw SourceLocation.
715 unsigned EnumOperandLoc;
718 SourceRange OperandParens;
720 SourceLocation AttrLoc;
723 /// \brief Type source information for an attributed type.
724 class AttributedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
729 AttributedType::Kind getAttrKind() const {
730 return getTypePtr()->getAttrKind();
733 bool hasAttrExprOperand() const {
734 return (getAttrKind() >= AttributedType::FirstExprOperandKind &&
735 getAttrKind() <= AttributedType::LastExprOperandKind);
738 bool hasAttrEnumOperand() const {
739 return (getAttrKind() >= AttributedType::FirstEnumOperandKind &&
740 getAttrKind() <= AttributedType::LastEnumOperandKind);
743 bool hasAttrOperand() const {
744 return hasAttrExprOperand() || hasAttrEnumOperand();
747 bool isQualifier() const {
748 return getTypePtr()->isQualifier();
751 /// The modified type, which is generally canonically different from
752 /// the attribute type.
753 /// int main(int, char**) __attribute__((noreturn))
754 /// ~~~ ~~~~~~~~~~~~~
755 TypeLoc getModifiedLoc() const {
756 return getInnerTypeLoc();
759 /// The location of the attribute name, i.e.
760 /// __attribute__((regparm(1000)))
762 SourceLocation getAttrNameLoc() const {
763 return getLocalData()->AttrLoc;
765 void setAttrNameLoc(SourceLocation loc) {
766 getLocalData()->AttrLoc = loc;
769 /// The attribute's expression operand, if it has one.
770 /// void *cur_thread __attribute__((address_space(21)))
772 Expr *getAttrExprOperand() const {
773 assert(hasAttrExprOperand());
774 return getLocalData()->ExprOperand;
776 void setAttrExprOperand(Expr *e) {
777 assert(hasAttrExprOperand());
778 getLocalData()->ExprOperand = e;
781 /// The location of the attribute's enumerated operand, if it has one.
782 /// void * __attribute__((objc_gc(weak)))
784 SourceLocation getAttrEnumOperandLoc() const {
785 assert(hasAttrEnumOperand());
786 return SourceLocation::getFromRawEncoding(getLocalData()->EnumOperandLoc);
788 void setAttrEnumOperandLoc(SourceLocation loc) {
789 assert(hasAttrEnumOperand());
790 getLocalData()->EnumOperandLoc = loc.getRawEncoding();
793 /// The location of the parentheses around the operand, if there is
795 /// void * __attribute__((objc_gc(weak)))
797 SourceRange getAttrOperandParensRange() const {
798 assert(hasAttrOperand());
799 return getLocalData()->OperandParens;
801 void setAttrOperandParensRange(SourceRange range) {
802 assert(hasAttrOperand());
803 getLocalData()->OperandParens = range;
806 SourceRange getLocalSourceRange() const {
807 // Note that this does *not* include the range of the attribute
809 // __attribute__((foo(bar)))
810 // ^~~~~~~~~~~~~~~ ~~
814 // That enclosure doesn't necessarily belong to a single attribute
816 SourceRange range(getAttrNameLoc());
817 if (hasAttrOperand())
818 range.setEnd(getAttrOperandParensRange().getEnd());
822 void initializeLocal(ASTContext &Context, SourceLocation loc) {
824 if (hasAttrExprOperand()) {
825 setAttrOperandParensRange(SourceRange(loc));
826 setAttrExprOperand(nullptr);
827 } else if (hasAttrEnumOperand()) {
828 setAttrOperandParensRange(SourceRange(loc));
829 setAttrEnumOperandLoc(loc);
833 QualType getInnerType() const {
834 return getTypePtr()->getModifiedType();
839 struct ObjCObjectTypeLocInfo {
840 SourceLocation TypeArgsLAngleLoc;
841 SourceLocation TypeArgsRAngleLoc;
842 SourceLocation ProtocolLAngleLoc;
843 SourceLocation ProtocolRAngleLoc;
844 bool HasBaseTypeAsWritten;
847 // A helper class for defining ObjC TypeLocs that can qualified with
850 // TypeClass basically has to be either ObjCInterfaceType or
851 // ObjCObjectPointerType.
852 class ObjCObjectTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
855 ObjCObjectTypeLocInfo> {
856 // TypeSourceInfo*'s are stored after Info, one for each type argument.
857 TypeSourceInfo **getTypeArgLocArray() const {
858 return (TypeSourceInfo**)this->getExtraLocalData();
861 // SourceLocations are stored after the type argument information, one for
863 SourceLocation *getProtocolLocArray() const {
864 return (SourceLocation*)(getTypeArgLocArray() + getNumTypeArgs());
868 SourceLocation getTypeArgsLAngleLoc() const {
869 return this->getLocalData()->TypeArgsLAngleLoc;
871 void setTypeArgsLAngleLoc(SourceLocation Loc) {
872 this->getLocalData()->TypeArgsLAngleLoc = Loc;
875 SourceLocation getTypeArgsRAngleLoc() const {
876 return this->getLocalData()->TypeArgsRAngleLoc;
878 void setTypeArgsRAngleLoc(SourceLocation Loc) {
879 this->getLocalData()->TypeArgsRAngleLoc = Loc;
882 unsigned getNumTypeArgs() const {
883 return this->getTypePtr()->getTypeArgsAsWritten().size();
886 TypeSourceInfo *getTypeArgTInfo(unsigned i) const {
887 assert(i < getNumTypeArgs() && "Index is out of bounds!");
888 return getTypeArgLocArray()[i];
891 void setTypeArgTInfo(unsigned i, TypeSourceInfo *TInfo) {
892 assert(i < getNumTypeArgs() && "Index is out of bounds!");
893 getTypeArgLocArray()[i] = TInfo;
896 SourceLocation getProtocolLAngleLoc() const {
897 return this->getLocalData()->ProtocolLAngleLoc;
899 void setProtocolLAngleLoc(SourceLocation Loc) {
900 this->getLocalData()->ProtocolLAngleLoc = Loc;
903 SourceLocation getProtocolRAngleLoc() const {
904 return this->getLocalData()->ProtocolRAngleLoc;
906 void setProtocolRAngleLoc(SourceLocation Loc) {
907 this->getLocalData()->ProtocolRAngleLoc = Loc;
910 unsigned getNumProtocols() const {
911 return this->getTypePtr()->getNumProtocols();
914 SourceLocation getProtocolLoc(unsigned i) const {
915 assert(i < getNumProtocols() && "Index is out of bounds!");
916 return getProtocolLocArray()[i];
918 void setProtocolLoc(unsigned i, SourceLocation Loc) {
919 assert(i < getNumProtocols() && "Index is out of bounds!");
920 getProtocolLocArray()[i] = Loc;
923 ObjCProtocolDecl *getProtocol(unsigned i) const {
924 assert(i < getNumProtocols() && "Index is out of bounds!");
925 return *(this->getTypePtr()->qual_begin() + i);
929 ArrayRef<SourceLocation> getProtocolLocs() const {
930 return llvm::makeArrayRef(getProtocolLocArray(), getNumProtocols());
933 bool hasBaseTypeAsWritten() const {
934 return getLocalData()->HasBaseTypeAsWritten;
937 void setHasBaseTypeAsWritten(bool HasBaseType) {
938 getLocalData()->HasBaseTypeAsWritten = HasBaseType;
941 TypeLoc getBaseLoc() const {
942 return getInnerTypeLoc();
945 SourceRange getLocalSourceRange() const {
946 SourceLocation start = getTypeArgsLAngleLoc();
947 if (start.isInvalid())
948 start = getProtocolLAngleLoc();
949 SourceLocation end = getProtocolRAngleLoc();
951 end = getTypeArgsRAngleLoc();
952 return SourceRange(start, end);
955 void initializeLocal(ASTContext &Context, SourceLocation Loc);
957 unsigned getExtraLocalDataSize() const {
958 return this->getNumTypeArgs() * sizeof(TypeSourceInfo *)
959 + this->getNumProtocols() * sizeof(SourceLocation);
962 unsigned getExtraLocalDataAlignment() const {
963 assert(llvm::alignOf<ObjCObjectTypeLoc>()
964 >= llvm::alignOf<TypeSourceInfo *>() &&
965 "not enough alignment for tail-allocated data");
966 return llvm::alignOf<TypeSourceInfo *>();
969 QualType getInnerType() const {
970 return getTypePtr()->getBaseType();
975 struct ObjCInterfaceLocInfo {
976 SourceLocation NameLoc;
977 SourceLocation NameEndLoc;
980 /// \brief Wrapper for source info for ObjC interfaces.
981 class ObjCInterfaceTypeLoc : public ConcreteTypeLoc<ObjCObjectTypeLoc,
982 ObjCInterfaceTypeLoc,
984 ObjCInterfaceLocInfo> {
986 ObjCInterfaceDecl *getIFaceDecl() const {
987 return getTypePtr()->getDecl();
990 SourceLocation getNameLoc() const {
991 return getLocalData()->NameLoc;
994 void setNameLoc(SourceLocation Loc) {
995 getLocalData()->NameLoc = Loc;
998 SourceRange getLocalSourceRange() const {
999 return SourceRange(getNameLoc(), getNameEndLoc());
1002 SourceLocation getNameEndLoc() const {
1003 return getLocalData()->NameEndLoc;
1006 void setNameEndLoc(SourceLocation Loc) {
1007 getLocalData()->NameEndLoc = Loc;
1010 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1016 struct ParenLocInfo {
1017 SourceLocation LParenLoc;
1018 SourceLocation RParenLoc;
1022 : public ConcreteTypeLoc<UnqualTypeLoc, ParenTypeLoc, ParenType,
1025 SourceLocation getLParenLoc() const {
1026 return this->getLocalData()->LParenLoc;
1028 SourceLocation getRParenLoc() const {
1029 return this->getLocalData()->RParenLoc;
1031 void setLParenLoc(SourceLocation Loc) {
1032 this->getLocalData()->LParenLoc = Loc;
1034 void setRParenLoc(SourceLocation Loc) {
1035 this->getLocalData()->RParenLoc = Loc;
1038 SourceRange getLocalSourceRange() const {
1039 return SourceRange(getLParenLoc(), getRParenLoc());
1042 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1047 TypeLoc getInnerLoc() const {
1048 return getInnerTypeLoc();
1051 QualType getInnerType() const {
1052 return this->getTypePtr()->getInnerType();
1056 inline TypeLoc TypeLoc::IgnoreParens() const {
1057 if (ParenTypeLoc::isKind(*this))
1058 return IgnoreParensImpl(*this);
1063 struct AdjustedLocInfo { }; // Nothing.
1065 class AdjustedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, AdjustedTypeLoc,
1066 AdjustedType, AdjustedLocInfo> {
1068 TypeLoc getOriginalLoc() const {
1069 return getInnerTypeLoc();
1072 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1076 QualType getInnerType() const {
1077 // The inner type is the undecayed type, since that's what we have source
1078 // location information for.
1079 return getTypePtr()->getOriginalType();
1082 SourceRange getLocalSourceRange() const {
1083 return SourceRange();
1086 unsigned getLocalDataSize() const {
1087 // sizeof(AdjustedLocInfo) is 1, but we don't need its address to be unique
1088 // anyway. TypeLocBuilder can't handle data sizes of 1.
1089 return 0; // No data.
1093 /// \brief Wrapper for source info for pointers decayed from arrays and
1095 class DecayedTypeLoc : public InheritingConcreteTypeLoc<
1096 AdjustedTypeLoc, DecayedTypeLoc, DecayedType> {
1099 struct PointerLikeLocInfo {
1100 SourceLocation StarLoc;
1103 /// A base class for
1104 template <class Derived, class TypeClass, class LocalData = PointerLikeLocInfo>
1105 class PointerLikeTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, Derived,
1106 TypeClass, LocalData> {
1108 SourceLocation getSigilLoc() const {
1109 return this->getLocalData()->StarLoc;
1111 void setSigilLoc(SourceLocation Loc) {
1112 this->getLocalData()->StarLoc = Loc;
1115 TypeLoc getPointeeLoc() const {
1116 return this->getInnerTypeLoc();
1119 SourceRange getLocalSourceRange() const {
1120 return SourceRange(getSigilLoc(), getSigilLoc());
1123 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1127 QualType getInnerType() const {
1128 return this->getTypePtr()->getPointeeType();
1133 /// \brief Wrapper for source info for pointers.
1134 class PointerTypeLoc : public PointerLikeTypeLoc<PointerTypeLoc,
1137 SourceLocation getStarLoc() const {
1138 return getSigilLoc();
1140 void setStarLoc(SourceLocation Loc) {
1146 /// \brief Wrapper for source info for block pointers.
1147 class BlockPointerTypeLoc : public PointerLikeTypeLoc<BlockPointerTypeLoc,
1150 SourceLocation getCaretLoc() const {
1151 return getSigilLoc();
1153 void setCaretLoc(SourceLocation Loc) {
1158 struct MemberPointerLocInfo : public PointerLikeLocInfo {
1159 TypeSourceInfo *ClassTInfo;
1162 /// \brief Wrapper for source info for member pointers.
1163 class MemberPointerTypeLoc : public PointerLikeTypeLoc<MemberPointerTypeLoc,
1165 MemberPointerLocInfo> {
1167 SourceLocation getStarLoc() const {
1168 return getSigilLoc();
1170 void setStarLoc(SourceLocation Loc) {
1174 const Type *getClass() const {
1175 return getTypePtr()->getClass();
1177 TypeSourceInfo *getClassTInfo() const {
1178 return getLocalData()->ClassTInfo;
1180 void setClassTInfo(TypeSourceInfo* TI) {
1181 getLocalData()->ClassTInfo = TI;
1184 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1186 setClassTInfo(nullptr);
1189 SourceRange getLocalSourceRange() const {
1190 if (TypeSourceInfo *TI = getClassTInfo())
1191 return SourceRange(TI->getTypeLoc().getBeginLoc(), getStarLoc());
1193 return SourceRange(getStarLoc());
1197 /// Wraps an ObjCPointerType with source location information.
1198 class ObjCObjectPointerTypeLoc :
1199 public PointerLikeTypeLoc<ObjCObjectPointerTypeLoc,
1200 ObjCObjectPointerType> {
1202 SourceLocation getStarLoc() const {
1203 return getSigilLoc();
1206 void setStarLoc(SourceLocation Loc) {
1212 class ReferenceTypeLoc : public PointerLikeTypeLoc<ReferenceTypeLoc,
1215 QualType getInnerType() const {
1216 return getTypePtr()->getPointeeTypeAsWritten();
1220 class LValueReferenceTypeLoc :
1221 public InheritingConcreteTypeLoc<ReferenceTypeLoc,
1222 LValueReferenceTypeLoc,
1223 LValueReferenceType> {
1225 SourceLocation getAmpLoc() const {
1226 return getSigilLoc();
1228 void setAmpLoc(SourceLocation Loc) {
1233 class RValueReferenceTypeLoc :
1234 public InheritingConcreteTypeLoc<ReferenceTypeLoc,
1235 RValueReferenceTypeLoc,
1236 RValueReferenceType> {
1238 SourceLocation getAmpAmpLoc() const {
1239 return getSigilLoc();
1241 void setAmpAmpLoc(SourceLocation Loc) {
1247 struct FunctionLocInfo {
1248 SourceLocation LocalRangeBegin;
1249 SourceLocation LParenLoc;
1250 SourceLocation RParenLoc;
1251 SourceLocation LocalRangeEnd;
1254 /// \brief Wrapper for source info for functions.
1255 class FunctionTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
1260 SourceLocation getLocalRangeBegin() const {
1261 return getLocalData()->LocalRangeBegin;
1263 void setLocalRangeBegin(SourceLocation L) {
1264 getLocalData()->LocalRangeBegin = L;
1267 SourceLocation getLocalRangeEnd() const {
1268 return getLocalData()->LocalRangeEnd;
1270 void setLocalRangeEnd(SourceLocation L) {
1271 getLocalData()->LocalRangeEnd = L;
1274 SourceLocation getLParenLoc() const {
1275 return this->getLocalData()->LParenLoc;
1277 void setLParenLoc(SourceLocation Loc) {
1278 this->getLocalData()->LParenLoc = Loc;
1281 SourceLocation getRParenLoc() const {
1282 return this->getLocalData()->RParenLoc;
1284 void setRParenLoc(SourceLocation Loc) {
1285 this->getLocalData()->RParenLoc = Loc;
1288 SourceRange getParensRange() const {
1289 return SourceRange(getLParenLoc(), getRParenLoc());
1292 ArrayRef<ParmVarDecl *> getParams() const {
1293 return llvm::makeArrayRef(getParmArray(), getNumParams());
1296 // ParmVarDecls* are stored after Info, one for each parameter.
1297 ParmVarDecl **getParmArray() const {
1298 return (ParmVarDecl**) getExtraLocalData();
1301 unsigned getNumParams() const {
1302 if (isa<FunctionNoProtoType>(getTypePtr()))
1304 return cast<FunctionProtoType>(getTypePtr())->getNumParams();
1306 ParmVarDecl *getParam(unsigned i) const { return getParmArray()[i]; }
1307 void setParam(unsigned i, ParmVarDecl *VD) { getParmArray()[i] = VD; }
1309 TypeLoc getReturnLoc() const {
1310 return getInnerTypeLoc();
1313 SourceRange getLocalSourceRange() const {
1314 return SourceRange(getLocalRangeBegin(), getLocalRangeEnd());
1317 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1318 setLocalRangeBegin(Loc);
1321 setLocalRangeEnd(Loc);
1322 for (unsigned i = 0, e = getNumParams(); i != e; ++i)
1323 setParam(i, nullptr);
1326 /// \brief Returns the size of the type source info data block that is
1327 /// specific to this type.
1328 unsigned getExtraLocalDataSize() const {
1329 return getNumParams() * sizeof(ParmVarDecl *);
1332 unsigned getExtraLocalDataAlignment() const {
1333 return llvm::alignOf<ParmVarDecl*>();
1336 QualType getInnerType() const { return getTypePtr()->getReturnType(); }
1339 class FunctionProtoTypeLoc :
1340 public InheritingConcreteTypeLoc<FunctionTypeLoc,
1341 FunctionProtoTypeLoc,
1342 FunctionProtoType> {
1345 class FunctionNoProtoTypeLoc :
1346 public InheritingConcreteTypeLoc<FunctionTypeLoc,
1347 FunctionNoProtoTypeLoc,
1348 FunctionNoProtoType> {
1352 struct ArrayLocInfo {
1353 SourceLocation LBracketLoc, RBracketLoc;
1357 /// \brief Wrapper for source info for arrays.
1358 class ArrayTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
1363 SourceLocation getLBracketLoc() const {
1364 return getLocalData()->LBracketLoc;
1366 void setLBracketLoc(SourceLocation Loc) {
1367 getLocalData()->LBracketLoc = Loc;
1370 SourceLocation getRBracketLoc() const {
1371 return getLocalData()->RBracketLoc;
1373 void setRBracketLoc(SourceLocation Loc) {
1374 getLocalData()->RBracketLoc = Loc;
1377 SourceRange getBracketsRange() const {
1378 return SourceRange(getLBracketLoc(), getRBracketLoc());
1381 Expr *getSizeExpr() const {
1382 return getLocalData()->Size;
1384 void setSizeExpr(Expr *Size) {
1385 getLocalData()->Size = Size;
1388 TypeLoc getElementLoc() const {
1389 return getInnerTypeLoc();
1392 SourceRange getLocalSourceRange() const {
1393 return SourceRange(getLBracketLoc(), getRBracketLoc());
1396 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1397 setLBracketLoc(Loc);
1398 setRBracketLoc(Loc);
1399 setSizeExpr(nullptr);
1402 QualType getInnerType() const { return getTypePtr()->getElementType(); }
1405 class ConstantArrayTypeLoc :
1406 public InheritingConcreteTypeLoc<ArrayTypeLoc,
1407 ConstantArrayTypeLoc,
1408 ConstantArrayType> {
1411 class IncompleteArrayTypeLoc :
1412 public InheritingConcreteTypeLoc<ArrayTypeLoc,
1413 IncompleteArrayTypeLoc,
1414 IncompleteArrayType> {
1417 class DependentSizedArrayTypeLoc :
1418 public InheritingConcreteTypeLoc<ArrayTypeLoc,
1419 DependentSizedArrayTypeLoc,
1420 DependentSizedArrayType> {
1424 class VariableArrayTypeLoc :
1425 public InheritingConcreteTypeLoc<ArrayTypeLoc,
1426 VariableArrayTypeLoc,
1427 VariableArrayType> {
1431 // Location information for a TemplateName. Rudimentary for now.
1432 struct TemplateNameLocInfo {
1433 SourceLocation NameLoc;
1436 struct TemplateSpecializationLocInfo : TemplateNameLocInfo {
1437 SourceLocation TemplateKWLoc;
1438 SourceLocation LAngleLoc;
1439 SourceLocation RAngleLoc;
1442 class TemplateSpecializationTypeLoc :
1443 public ConcreteTypeLoc<UnqualTypeLoc,
1444 TemplateSpecializationTypeLoc,
1445 TemplateSpecializationType,
1446 TemplateSpecializationLocInfo> {
1448 SourceLocation getTemplateKeywordLoc() const {
1449 return getLocalData()->TemplateKWLoc;
1451 void setTemplateKeywordLoc(SourceLocation Loc) {
1452 getLocalData()->TemplateKWLoc = Loc;
1455 SourceLocation getLAngleLoc() const {
1456 return getLocalData()->LAngleLoc;
1458 void setLAngleLoc(SourceLocation Loc) {
1459 getLocalData()->LAngleLoc = Loc;
1462 SourceLocation getRAngleLoc() const {
1463 return getLocalData()->RAngleLoc;
1465 void setRAngleLoc(SourceLocation Loc) {
1466 getLocalData()->RAngleLoc = Loc;
1469 unsigned getNumArgs() const {
1470 return getTypePtr()->getNumArgs();
1472 void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) {
1473 getArgInfos()[i] = AI;
1475 TemplateArgumentLocInfo getArgLocInfo(unsigned i) const {
1476 return getArgInfos()[i];
1479 TemplateArgumentLoc getArgLoc(unsigned i) const {
1480 return TemplateArgumentLoc(getTypePtr()->getArg(i), getArgLocInfo(i));
1483 SourceLocation getTemplateNameLoc() const {
1484 return getLocalData()->NameLoc;
1486 void setTemplateNameLoc(SourceLocation Loc) {
1487 getLocalData()->NameLoc = Loc;
1490 /// \brief - Copy the location information from the given info.
1491 void copy(TemplateSpecializationTypeLoc Loc) {
1492 unsigned size = getFullDataSize();
1493 assert(size == Loc.getFullDataSize());
1495 // We're potentially copying Expr references here. We don't
1496 // bother retaining them because TypeSourceInfos live forever, so
1497 // as long as the Expr was retained when originally written into
1498 // the TypeLoc, we're okay.
1499 memcpy(Data, Loc.Data, size);
1502 SourceRange getLocalSourceRange() const {
1503 if (getTemplateKeywordLoc().isValid())
1504 return SourceRange(getTemplateKeywordLoc(), getRAngleLoc());
1506 return SourceRange(getTemplateNameLoc(), getRAngleLoc());
1509 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1510 setTemplateKeywordLoc(Loc);
1511 setTemplateNameLoc(Loc);
1514 initializeArgLocs(Context, getNumArgs(), getTypePtr()->getArgs(),
1515 getArgInfos(), Loc);
1518 static void initializeArgLocs(ASTContext &Context, unsigned NumArgs,
1519 const TemplateArgument *Args,
1520 TemplateArgumentLocInfo *ArgInfos,
1521 SourceLocation Loc);
1523 unsigned getExtraLocalDataSize() const {
1524 return getNumArgs() * sizeof(TemplateArgumentLocInfo);
1527 unsigned getExtraLocalDataAlignment() const {
1528 return llvm::alignOf<TemplateArgumentLocInfo>();
1532 TemplateArgumentLocInfo *getArgInfos() const {
1533 return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData());
1537 //===----------------------------------------------------------------------===//
1539 // All of these need proper implementations.
1541 //===----------------------------------------------------------------------===//
1543 // FIXME: size expression and attribute locations (or keyword if we
1544 // ever fully support altivec syntax).
1545 class VectorTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
1550 // FIXME: size expression and attribute locations.
1551 class ExtVectorTypeLoc : public InheritingConcreteTypeLoc<VectorTypeLoc,
1556 // FIXME: attribute locations.
1557 // For some reason, this isn't a subtype of VectorType.
1558 class DependentSizedExtVectorTypeLoc :
1559 public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
1560 DependentSizedExtVectorTypeLoc,
1561 DependentSizedExtVectorType> {
1564 // FIXME: location of the '_Complex' keyword.
1565 class ComplexTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
1570 struct TypeofLocInfo {
1571 SourceLocation TypeofLoc;
1572 SourceLocation LParenLoc;
1573 SourceLocation RParenLoc;
1576 struct TypeOfExprTypeLocInfo : public TypeofLocInfo {
1579 struct TypeOfTypeLocInfo : public TypeofLocInfo {
1580 TypeSourceInfo* UnderlyingTInfo;
1583 template <class Derived, class TypeClass, class LocalData = TypeofLocInfo>
1584 class TypeofLikeTypeLoc
1585 : public ConcreteTypeLoc<UnqualTypeLoc, Derived, TypeClass, LocalData> {
1587 SourceLocation getTypeofLoc() const {
1588 return this->getLocalData()->TypeofLoc;
1590 void setTypeofLoc(SourceLocation Loc) {
1591 this->getLocalData()->TypeofLoc = Loc;
1594 SourceLocation getLParenLoc() const {
1595 return this->getLocalData()->LParenLoc;
1597 void setLParenLoc(SourceLocation Loc) {
1598 this->getLocalData()->LParenLoc = Loc;
1601 SourceLocation getRParenLoc() const {
1602 return this->getLocalData()->RParenLoc;
1604 void setRParenLoc(SourceLocation Loc) {
1605 this->getLocalData()->RParenLoc = Loc;
1608 SourceRange getParensRange() const {
1609 return SourceRange(getLParenLoc(), getRParenLoc());
1611 void setParensRange(SourceRange range) {
1612 setLParenLoc(range.getBegin());
1613 setRParenLoc(range.getEnd());
1616 SourceRange getLocalSourceRange() const {
1617 return SourceRange(getTypeofLoc(), getRParenLoc());
1620 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1627 class TypeOfExprTypeLoc : public TypeofLikeTypeLoc<TypeOfExprTypeLoc,
1629 TypeOfExprTypeLocInfo> {
1631 Expr* getUnderlyingExpr() const {
1632 return getTypePtr()->getUnderlyingExpr();
1634 // Reimplemented to account for GNU/C++ extension
1635 // typeof unary-expression
1636 // where there are no parentheses.
1637 SourceRange getLocalSourceRange() const;
1641 : public TypeofLikeTypeLoc<TypeOfTypeLoc, TypeOfType, TypeOfTypeLocInfo> {
1643 QualType getUnderlyingType() const {
1644 return this->getTypePtr()->getUnderlyingType();
1646 TypeSourceInfo* getUnderlyingTInfo() const {
1647 return this->getLocalData()->UnderlyingTInfo;
1649 void setUnderlyingTInfo(TypeSourceInfo* TI) const {
1650 this->getLocalData()->UnderlyingTInfo = TI;
1653 void initializeLocal(ASTContext &Context, SourceLocation Loc);
1656 // FIXME: location of the 'decltype' and parens.
1657 class DecltypeTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
1661 Expr *getUnderlyingExpr() const { return getTypePtr()->getUnderlyingExpr(); }
1664 struct UnaryTransformTypeLocInfo {
1665 // FIXME: While there's only one unary transform right now, future ones may
1666 // need different representations
1667 SourceLocation KWLoc, LParenLoc, RParenLoc;
1668 TypeSourceInfo *UnderlyingTInfo;
1671 class UnaryTransformTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
1672 UnaryTransformTypeLoc,
1674 UnaryTransformTypeLocInfo> {
1676 SourceLocation getKWLoc() const { return getLocalData()->KWLoc; }
1677 void setKWLoc(SourceLocation Loc) { getLocalData()->KWLoc = Loc; }
1679 SourceLocation getLParenLoc() const { return getLocalData()->LParenLoc; }
1680 void setLParenLoc(SourceLocation Loc) { getLocalData()->LParenLoc = Loc; }
1682 SourceLocation getRParenLoc() const { return getLocalData()->RParenLoc; }
1683 void setRParenLoc(SourceLocation Loc) { getLocalData()->RParenLoc = Loc; }
1685 TypeSourceInfo* getUnderlyingTInfo() const {
1686 return getLocalData()->UnderlyingTInfo;
1688 void setUnderlyingTInfo(TypeSourceInfo *TInfo) {
1689 getLocalData()->UnderlyingTInfo = TInfo;
1692 SourceRange getLocalSourceRange() const {
1693 return SourceRange(getKWLoc(), getRParenLoc());
1696 SourceRange getParensRange() const {
1697 return SourceRange(getLParenLoc(), getRParenLoc());
1699 void setParensRange(SourceRange Range) {
1700 setLParenLoc(Range.getBegin());
1701 setRParenLoc(Range.getEnd());
1704 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1711 class AutoTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
1716 struct ElaboratedLocInfo {
1717 SourceLocation ElaboratedKWLoc;
1718 /// \brief Data associated with the nested-name-specifier location.
1719 void *QualifierData;
1722 class ElaboratedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
1725 ElaboratedLocInfo> {
1727 SourceLocation getElaboratedKeywordLoc() const {
1728 return this->getLocalData()->ElaboratedKWLoc;
1730 void setElaboratedKeywordLoc(SourceLocation Loc) {
1731 this->getLocalData()->ElaboratedKWLoc = Loc;
1734 NestedNameSpecifierLoc getQualifierLoc() const {
1735 return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
1736 getLocalData()->QualifierData);
1739 void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
1740 assert(QualifierLoc.getNestedNameSpecifier()
1741 == getTypePtr()->getQualifier() &&
1742 "Inconsistent nested-name-specifier pointer");
1743 getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
1746 SourceRange getLocalSourceRange() const {
1747 if (getElaboratedKeywordLoc().isValid())
1748 if (getQualifierLoc())
1749 return SourceRange(getElaboratedKeywordLoc(),
1750 getQualifierLoc().getEndLoc());
1752 return SourceRange(getElaboratedKeywordLoc());
1754 return getQualifierLoc().getSourceRange();
1757 void initializeLocal(ASTContext &Context, SourceLocation Loc);
1759 TypeLoc getNamedTypeLoc() const {
1760 return getInnerTypeLoc();
1763 QualType getInnerType() const {
1764 return getTypePtr()->getNamedType();
1767 void copy(ElaboratedTypeLoc Loc) {
1768 unsigned size = getFullDataSize();
1769 assert(size == Loc.getFullDataSize());
1770 memcpy(Data, Loc.Data, size);
1774 // This is exactly the structure of an ElaboratedTypeLoc whose inner
1775 // type is some sort of TypeDeclTypeLoc.
1776 struct DependentNameLocInfo : ElaboratedLocInfo {
1777 SourceLocation NameLoc;
1780 class DependentNameTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
1781 DependentNameTypeLoc,
1783 DependentNameLocInfo> {
1785 SourceLocation getElaboratedKeywordLoc() const {
1786 return this->getLocalData()->ElaboratedKWLoc;
1788 void setElaboratedKeywordLoc(SourceLocation Loc) {
1789 this->getLocalData()->ElaboratedKWLoc = Loc;
1792 NestedNameSpecifierLoc getQualifierLoc() const {
1793 return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
1794 getLocalData()->QualifierData);
1797 void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
1798 assert(QualifierLoc.getNestedNameSpecifier()
1799 == getTypePtr()->getQualifier() &&
1800 "Inconsistent nested-name-specifier pointer");
1801 getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
1804 SourceLocation getNameLoc() const {
1805 return this->getLocalData()->NameLoc;
1807 void setNameLoc(SourceLocation Loc) {
1808 this->getLocalData()->NameLoc = Loc;
1811 SourceRange getLocalSourceRange() const {
1812 if (getElaboratedKeywordLoc().isValid())
1813 return SourceRange(getElaboratedKeywordLoc(), getNameLoc());
1815 return SourceRange(getQualifierLoc().getBeginLoc(), getNameLoc());
1818 void copy(DependentNameTypeLoc Loc) {
1819 unsigned size = getFullDataSize();
1820 assert(size == Loc.getFullDataSize());
1821 memcpy(Data, Loc.Data, size);
1824 void initializeLocal(ASTContext &Context, SourceLocation Loc);
1827 struct DependentTemplateSpecializationLocInfo : DependentNameLocInfo {
1828 SourceLocation TemplateKWLoc;
1829 SourceLocation LAngleLoc;
1830 SourceLocation RAngleLoc;
1831 // followed by a TemplateArgumentLocInfo[]
1834 class DependentTemplateSpecializationTypeLoc :
1835 public ConcreteTypeLoc<UnqualTypeLoc,
1836 DependentTemplateSpecializationTypeLoc,
1837 DependentTemplateSpecializationType,
1838 DependentTemplateSpecializationLocInfo> {
1840 SourceLocation getElaboratedKeywordLoc() const {
1841 return this->getLocalData()->ElaboratedKWLoc;
1843 void setElaboratedKeywordLoc(SourceLocation Loc) {
1844 this->getLocalData()->ElaboratedKWLoc = Loc;
1847 NestedNameSpecifierLoc getQualifierLoc() const {
1848 if (!getLocalData()->QualifierData)
1849 return NestedNameSpecifierLoc();
1851 return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
1852 getLocalData()->QualifierData);
1855 void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
1856 if (!QualifierLoc) {
1857 // Even if we have a nested-name-specifier in the dependent
1858 // template specialization type, we won't record the nested-name-specifier
1859 // location information when this type-source location information is
1860 // part of a nested-name-specifier.
1861 getLocalData()->QualifierData = nullptr;
1865 assert(QualifierLoc.getNestedNameSpecifier()
1866 == getTypePtr()->getQualifier() &&
1867 "Inconsistent nested-name-specifier pointer");
1868 getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
1871 SourceLocation getTemplateKeywordLoc() const {
1872 return getLocalData()->TemplateKWLoc;
1874 void setTemplateKeywordLoc(SourceLocation Loc) {
1875 getLocalData()->TemplateKWLoc = Loc;
1878 SourceLocation getTemplateNameLoc() const {
1879 return this->getLocalData()->NameLoc;
1881 void setTemplateNameLoc(SourceLocation Loc) {
1882 this->getLocalData()->NameLoc = Loc;
1885 SourceLocation getLAngleLoc() const {
1886 return this->getLocalData()->LAngleLoc;
1888 void setLAngleLoc(SourceLocation Loc) {
1889 this->getLocalData()->LAngleLoc = Loc;
1892 SourceLocation getRAngleLoc() const {
1893 return this->getLocalData()->RAngleLoc;
1895 void setRAngleLoc(SourceLocation Loc) {
1896 this->getLocalData()->RAngleLoc = Loc;
1899 unsigned getNumArgs() const {
1900 return getTypePtr()->getNumArgs();
1903 void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) {
1904 getArgInfos()[i] = AI;
1906 TemplateArgumentLocInfo getArgLocInfo(unsigned i) const {
1907 return getArgInfos()[i];
1910 TemplateArgumentLoc getArgLoc(unsigned i) const {
1911 return TemplateArgumentLoc(getTypePtr()->getArg(i), getArgLocInfo(i));
1914 SourceRange getLocalSourceRange() const {
1915 if (getElaboratedKeywordLoc().isValid())
1916 return SourceRange(getElaboratedKeywordLoc(), getRAngleLoc());
1917 else if (getQualifierLoc())
1918 return SourceRange(getQualifierLoc().getBeginLoc(), getRAngleLoc());
1919 else if (getTemplateKeywordLoc().isValid())
1920 return SourceRange(getTemplateKeywordLoc(), getRAngleLoc());
1922 return SourceRange(getTemplateNameLoc(), getRAngleLoc());
1925 void copy(DependentTemplateSpecializationTypeLoc Loc) {
1926 unsigned size = getFullDataSize();
1927 assert(size == Loc.getFullDataSize());
1928 memcpy(Data, Loc.Data, size);
1931 void initializeLocal(ASTContext &Context, SourceLocation Loc);
1933 unsigned getExtraLocalDataSize() const {
1934 return getNumArgs() * sizeof(TemplateArgumentLocInfo);
1937 unsigned getExtraLocalDataAlignment() const {
1938 return llvm::alignOf<TemplateArgumentLocInfo>();
1942 TemplateArgumentLocInfo *getArgInfos() const {
1943 return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData());
1948 struct PackExpansionTypeLocInfo {
1949 SourceLocation EllipsisLoc;
1952 class PackExpansionTypeLoc
1953 : public ConcreteTypeLoc<UnqualTypeLoc, PackExpansionTypeLoc,
1954 PackExpansionType, PackExpansionTypeLocInfo> {
1956 SourceLocation getEllipsisLoc() const {
1957 return this->getLocalData()->EllipsisLoc;
1960 void setEllipsisLoc(SourceLocation Loc) {
1961 this->getLocalData()->EllipsisLoc = Loc;
1964 SourceRange getLocalSourceRange() const {
1965 return SourceRange(getEllipsisLoc(), getEllipsisLoc());
1968 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1969 setEllipsisLoc(Loc);
1972 TypeLoc getPatternLoc() const {
1973 return getInnerTypeLoc();
1976 QualType getInnerType() const {
1977 return this->getTypePtr()->getPattern();
1981 struct AtomicTypeLocInfo {
1982 SourceLocation KWLoc, LParenLoc, RParenLoc;
1985 class AtomicTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, AtomicTypeLoc,
1986 AtomicType, AtomicTypeLocInfo> {
1988 TypeLoc getValueLoc() const {
1989 return this->getInnerTypeLoc();
1992 SourceRange getLocalSourceRange() const {
1993 return SourceRange(getKWLoc(), getRParenLoc());
1996 SourceLocation getKWLoc() const {
1997 return this->getLocalData()->KWLoc;
1999 void setKWLoc(SourceLocation Loc) {
2000 this->getLocalData()->KWLoc = Loc;
2003 SourceLocation getLParenLoc() const {
2004 return this->getLocalData()->LParenLoc;
2006 void setLParenLoc(SourceLocation Loc) {
2007 this->getLocalData()->LParenLoc = Loc;
2010 SourceLocation getRParenLoc() const {
2011 return this->getLocalData()->RParenLoc;
2013 void setRParenLoc(SourceLocation Loc) {
2014 this->getLocalData()->RParenLoc = Loc;
2017 SourceRange getParensRange() const {
2018 return SourceRange(getLParenLoc(), getRParenLoc());
2020 void setParensRange(SourceRange Range) {
2021 setLParenLoc(Range.getBegin());
2022 setRParenLoc(Range.getEnd());
2025 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
2031 QualType getInnerType() const {
2032 return this->getTypePtr()->getValueType();
2036 struct PipeTypeLocInfo {
2037 SourceLocation KWLoc;
2040 class PipeTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, PipeTypeLoc, PipeType,
2043 TypeLoc getValueLoc() const { return this->getInnerTypeLoc(); }
2045 SourceRange getLocalSourceRange() const { return SourceRange(getKWLoc()); }
2047 SourceLocation getKWLoc() const { return this->getLocalData()->KWLoc; }
2048 void setKWLoc(SourceLocation Loc) { this->getLocalData()->KWLoc = Loc; }
2050 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
2054 QualType getInnerType() const { return this->getTypePtr()->getElementType(); }