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 LLVM_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 Initializes this to state that every location in this
155 /// type is the given location.
157 /// This method exists to provide a simple transition for code that
158 /// relies on location-less types.
159 void initialize(ASTContext &Context, SourceLocation Loc) const {
160 initializeImpl(Context, *this, Loc);
163 /// \brief Initializes this by copying its information from another
164 /// TypeLoc of the same type.
165 void initializeFullCopy(TypeLoc Other) const {
166 assert(getType() == Other.getType());
167 size_t Size = getFullDataSize();
168 memcpy(getOpaqueData(), Other.getOpaqueData(), Size);
171 /// \brief Initializes this by copying its information from another
172 /// TypeLoc of the same type. The given size must be the full data
174 void initializeFullCopy(TypeLoc Other, unsigned Size) const {
175 assert(getType() == Other.getType());
176 assert(getFullDataSize() == Size);
177 memcpy(getOpaqueData(), Other.getOpaqueData(), Size);
180 friend bool operator==(const TypeLoc &LHS, const TypeLoc &RHS) {
181 return LHS.Ty == RHS.Ty && LHS.Data == RHS.Data;
184 friend bool operator!=(const TypeLoc &LHS, const TypeLoc &RHS) {
185 return !(LHS == RHS);
189 static bool isKind(const TypeLoc&) {
193 static void initializeImpl(ASTContext &Context, TypeLoc TL,
195 static TypeLoc getNextTypeLocImpl(TypeLoc TL);
196 static TypeLoc IgnoreParensImpl(TypeLoc TL);
197 static SourceRange getLocalSourceRangeImpl(TypeLoc TL);
200 /// \brief Return the TypeLoc for a type source info.
201 inline TypeLoc TypeSourceInfo::getTypeLoc() const {
202 return TypeLoc(Ty, const_cast<void*>(static_cast<const void*>(this + 1)));
205 /// \brief Wrapper of type source information for a type with
206 /// no direct qualifiers.
207 class UnqualTypeLoc : public TypeLoc {
210 UnqualTypeLoc(const Type *Ty, void *Data) : TypeLoc(Ty, Data) {}
212 const Type *getTypePtr() const {
213 return reinterpret_cast<const Type*>(Ty);
216 TypeLocClass getTypeLocClass() const {
217 return (TypeLocClass) getTypePtr()->getTypeClass();
221 friend class TypeLoc;
222 static bool isKind(const TypeLoc &TL) {
223 return !TL.getType().hasLocalQualifiers();
227 /// \brief Wrapper of type source information for a type with
228 /// non-trivial direct qualifiers.
230 /// Currently, we intentionally do not provide source location for
232 class QualifiedTypeLoc : public TypeLoc {
234 SourceRange getLocalSourceRange() const {
235 return SourceRange();
238 UnqualTypeLoc getUnqualifiedLoc() const {
240 TypeLoc::getLocalAlignmentForType(QualType(getTypePtr(), 0));
241 uintptr_t dataInt = reinterpret_cast<uintptr_t>(Data);
242 dataInt = llvm::RoundUpToAlignment(dataInt, align);
243 return UnqualTypeLoc(getTypePtr(), reinterpret_cast<void*>(dataInt));
246 /// Initializes the local data of this type source info block to
247 /// provide no information.
248 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
252 TypeLoc getNextTypeLoc() const {
253 return getUnqualifiedLoc();
256 /// \brief Returns the size of the type source info data block that is
257 /// specific to this type.
258 unsigned getLocalDataSize() const {
259 // In fact, we don't currently preserve any location information
264 /// \brief Returns the alignment of the type source info data block that is
265 /// specific to this type.
266 unsigned getLocalDataAlignment() const {
267 // We don't preserve any location information.
272 friend class TypeLoc;
273 static bool isKind(const TypeLoc &TL) {
274 return TL.getType().hasLocalQualifiers();
278 inline UnqualTypeLoc TypeLoc::getUnqualifiedLoc() const {
279 if (QualifiedTypeLoc Loc = getAs<QualifiedTypeLoc>())
280 return Loc.getUnqualifiedLoc();
281 return castAs<UnqualTypeLoc>();
284 /// A metaprogramming base class for TypeLoc classes which correspond
285 /// to a particular Type subclass. It is accepted for a single
286 /// TypeLoc class to correspond to multiple Type classes.
288 /// \tparam Base a class from which to derive
289 /// \tparam Derived the class deriving from this one
290 /// \tparam TypeClass the concrete Type subclass associated with this
292 /// \tparam LocalData the structure type of local location data for
295 /// TypeLocs with non-constant amounts of local data should override
296 /// getExtraLocalDataSize(); getExtraLocalData() will then point to
297 /// this extra memory.
299 /// TypeLocs with an inner type should define
300 /// QualType getInnerType() const
301 /// and getInnerTypeLoc() will then point to this inner type's
304 /// A word about hierarchies: this template is not designed to be
305 /// derived from multiple times in a hierarchy. It is also not
306 /// designed to be used for classes where subtypes might provide
307 /// different amounts of source information. It should be subclassed
308 /// only at the deepest portion of the hierarchy where all children
309 /// have identical source information; if that's an abstract type,
310 /// then further descendents should inherit from
311 /// InheritingConcreteTypeLoc instead.
312 template <class Base, class Derived, class TypeClass, class LocalData>
313 class ConcreteTypeLoc : public Base {
315 const Derived *asDerived() const {
316 return static_cast<const Derived*>(this);
319 friend class TypeLoc;
320 static bool isKind(const TypeLoc &TL) {
321 return !TL.getType().hasLocalQualifiers() &&
322 Derived::classofType(TL.getTypePtr());
325 static bool classofType(const Type *Ty) {
326 return TypeClass::classof(Ty);
330 unsigned getLocalDataAlignment() const {
331 return std::max(llvm::alignOf<LocalData>(),
332 asDerived()->getExtraLocalDataAlignment());
334 unsigned getLocalDataSize() const {
335 unsigned size = sizeof(LocalData);
336 unsigned extraAlign = asDerived()->getExtraLocalDataAlignment();
337 size = llvm::RoundUpToAlignment(size, extraAlign);
338 size += asDerived()->getExtraLocalDataSize();
342 TypeLoc getNextTypeLoc() const {
343 return getNextTypeLoc(asDerived()->getInnerType());
346 const TypeClass *getTypePtr() const {
347 return cast<TypeClass>(Base::getTypePtr());
351 unsigned getExtraLocalDataSize() const {
355 unsigned getExtraLocalDataAlignment() const {
359 LocalData *getLocalData() const {
360 return static_cast<LocalData*>(Base::Data);
363 /// Gets a pointer past the Info structure; useful for classes with
364 /// local data that can't be captured in the Info (e.g. because it's
365 /// of variable size).
366 void *getExtraLocalData() const {
367 unsigned size = sizeof(LocalData);
368 unsigned extraAlign = asDerived()->getExtraLocalDataAlignment();
369 size = llvm::RoundUpToAlignment(size, extraAlign);
370 return reinterpret_cast<char*>(Base::Data) + size;
373 void *getNonLocalData() const {
374 uintptr_t data = reinterpret_cast<uintptr_t>(Base::Data);
375 data += asDerived()->getLocalDataSize();
376 data = llvm::RoundUpToAlignment(data, getNextTypeAlign());
377 return reinterpret_cast<void*>(data);
380 struct HasNoInnerType {};
381 HasNoInnerType getInnerType() const { return HasNoInnerType(); }
383 TypeLoc getInnerTypeLoc() const {
384 return TypeLoc(asDerived()->getInnerType(), getNonLocalData());
388 unsigned getInnerTypeSize() const {
389 return getInnerTypeSize(asDerived()->getInnerType());
392 unsigned getInnerTypeSize(HasNoInnerType _) const {
396 unsigned getInnerTypeSize(QualType _) const {
397 return getInnerTypeLoc().getFullDataSize();
400 unsigned getNextTypeAlign() const {
401 return getNextTypeAlign(asDerived()->getInnerType());
404 unsigned getNextTypeAlign(HasNoInnerType _) const {
408 unsigned getNextTypeAlign(QualType T) const {
409 return TypeLoc::getLocalAlignmentForType(T);
412 TypeLoc getNextTypeLoc(HasNoInnerType _) const {
416 TypeLoc getNextTypeLoc(QualType T) const {
417 return TypeLoc(T, getNonLocalData());
421 /// A metaprogramming class designed for concrete subtypes of abstract
422 /// types where all subtypes share equivalently-structured source
423 /// information. See the note on ConcreteTypeLoc.
424 template <class Base, class Derived, class TypeClass>
425 class InheritingConcreteTypeLoc : public Base {
426 friend class TypeLoc;
427 static bool classofType(const Type *Ty) {
428 return TypeClass::classof(Ty);
431 static bool isKind(const TypeLoc &TL) {
432 return !TL.getType().hasLocalQualifiers() &&
433 Derived::classofType(TL.getTypePtr());
435 static bool isKind(const UnqualTypeLoc &TL) {
436 return Derived::classofType(TL.getTypePtr());
440 const TypeClass *getTypePtr() const {
441 return cast<TypeClass>(Base::getTypePtr());
446 struct TypeSpecLocInfo {
447 SourceLocation NameLoc;
450 /// \brief A reasonable base class for TypeLocs that correspond to
451 /// types that are written as a type-specifier.
452 class TypeSpecTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
457 enum { LocalDataSize = sizeof(TypeSpecLocInfo),
458 LocalDataAlignment = llvm::AlignOf<TypeSpecLocInfo>::Alignment };
460 SourceLocation getNameLoc() const {
461 return this->getLocalData()->NameLoc;
463 void setNameLoc(SourceLocation Loc) {
464 this->getLocalData()->NameLoc = Loc;
466 SourceRange getLocalSourceRange() const {
467 return SourceRange(getNameLoc(), getNameLoc());
469 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
474 friend class TypeLoc;
475 static bool isKind(const TypeLoc &TL);
479 struct BuiltinLocInfo {
480 SourceLocation BuiltinLoc;
483 /// \brief Wrapper for source info for builtin types.
484 class BuiltinTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
489 SourceLocation getBuiltinLoc() const {
490 return getLocalData()->BuiltinLoc;
492 void setBuiltinLoc(SourceLocation Loc) {
493 getLocalData()->BuiltinLoc = Loc;
496 SourceLocation getNameLoc() const { return getBuiltinLoc(); }
498 WrittenBuiltinSpecs& getWrittenBuiltinSpecs() {
499 return *(static_cast<WrittenBuiltinSpecs*>(getExtraLocalData()));
501 const WrittenBuiltinSpecs& getWrittenBuiltinSpecs() const {
502 return *(static_cast<WrittenBuiltinSpecs*>(getExtraLocalData()));
505 bool needsExtraLocalData() const {
506 BuiltinType::Kind bk = getTypePtr()->getKind();
507 return (bk >= BuiltinType::UShort && bk <= BuiltinType::UInt128)
508 || (bk >= BuiltinType::Short && bk <= BuiltinType::LongDouble)
509 || bk == BuiltinType::UChar
510 || bk == BuiltinType::SChar;
513 unsigned getExtraLocalDataSize() const {
514 return needsExtraLocalData() ? sizeof(WrittenBuiltinSpecs) : 0;
517 unsigned getExtraLocalDataAlignment() const {
518 return needsExtraLocalData() ? llvm::alignOf<WrittenBuiltinSpecs>() : 1;
521 SourceRange getLocalSourceRange() const {
522 return SourceRange(getBuiltinLoc(), getBuiltinLoc());
525 TypeSpecifierSign getWrittenSignSpec() const {
526 if (needsExtraLocalData())
527 return static_cast<TypeSpecifierSign>(getWrittenBuiltinSpecs().Sign);
529 return TSS_unspecified;
531 bool hasWrittenSignSpec() const {
532 return getWrittenSignSpec() != TSS_unspecified;
534 void setWrittenSignSpec(TypeSpecifierSign written) {
535 if (needsExtraLocalData())
536 getWrittenBuiltinSpecs().Sign = written;
539 TypeSpecifierWidth getWrittenWidthSpec() const {
540 if (needsExtraLocalData())
541 return static_cast<TypeSpecifierWidth>(getWrittenBuiltinSpecs().Width);
543 return TSW_unspecified;
545 bool hasWrittenWidthSpec() const {
546 return getWrittenWidthSpec() != TSW_unspecified;
548 void setWrittenWidthSpec(TypeSpecifierWidth written) {
549 if (needsExtraLocalData())
550 getWrittenBuiltinSpecs().Width = written;
553 TypeSpecifierType getWrittenTypeSpec() const;
554 bool hasWrittenTypeSpec() const {
555 return getWrittenTypeSpec() != TST_unspecified;
557 void setWrittenTypeSpec(TypeSpecifierType written) {
558 if (needsExtraLocalData())
559 getWrittenBuiltinSpecs().Type = written;
562 bool hasModeAttr() const {
563 if (needsExtraLocalData())
564 return getWrittenBuiltinSpecs().ModeAttr;
568 void setModeAttr(bool written) {
569 if (needsExtraLocalData())
570 getWrittenBuiltinSpecs().ModeAttr = written;
573 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
575 if (needsExtraLocalData()) {
576 WrittenBuiltinSpecs &wbs = getWrittenBuiltinSpecs();
577 wbs.Sign = TSS_unspecified;
578 wbs.Width = TSW_unspecified;
579 wbs.Type = TST_unspecified;
580 wbs.ModeAttr = false;
586 /// \brief Wrapper for source info for typedefs.
587 class TypedefTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
591 TypedefNameDecl *getTypedefNameDecl() const {
592 return getTypePtr()->getDecl();
596 /// \brief Wrapper for source info for injected class names of class
598 class InjectedClassNameTypeLoc :
599 public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
600 InjectedClassNameTypeLoc,
601 InjectedClassNameType> {
603 CXXRecordDecl *getDecl() const {
604 return getTypePtr()->getDecl();
608 /// \brief Wrapper for source info for unresolved typename using decls.
609 class UnresolvedUsingTypeLoc :
610 public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
611 UnresolvedUsingTypeLoc,
612 UnresolvedUsingType> {
614 UnresolvedUsingTypenameDecl *getDecl() const {
615 return getTypePtr()->getDecl();
619 /// \brief Wrapper for source info for tag types. Note that this only
620 /// records source info for the name itself; a type written 'struct foo'
621 /// should be represented as an ElaboratedTypeLoc. We currently
622 /// only do that when C++ is enabled because of the expense of
623 /// creating an ElaboratedType node for so many type references in C.
624 class TagTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
628 TagDecl *getDecl() const { return getTypePtr()->getDecl(); }
630 /// \brief True if the tag was defined in this type specifier.
631 bool isDefinition() const {
632 TagDecl *D = getDecl();
633 return D->isCompleteDefinition() &&
634 (D->getIdentifier() == nullptr || D->getLocation() == getNameLoc());
638 /// \brief Wrapper for source info for record types.
639 class RecordTypeLoc : public InheritingConcreteTypeLoc<TagTypeLoc,
643 RecordDecl *getDecl() const { return getTypePtr()->getDecl(); }
646 /// \brief Wrapper for source info for enum types.
647 class EnumTypeLoc : public InheritingConcreteTypeLoc<TagTypeLoc,
651 EnumDecl *getDecl() const { return getTypePtr()->getDecl(); }
654 /// \brief Wrapper for template type parameters.
655 class TemplateTypeParmTypeLoc :
656 public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
657 TemplateTypeParmTypeLoc,
658 TemplateTypeParmType> {
660 TemplateTypeParmDecl *getDecl() const { return getTypePtr()->getDecl(); }
663 /// \brief Wrapper for substituted template type parameters.
664 class SubstTemplateTypeParmTypeLoc :
665 public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
666 SubstTemplateTypeParmTypeLoc,
667 SubstTemplateTypeParmType> {
670 /// \brief Wrapper for substituted template type parameters.
671 class SubstTemplateTypeParmPackTypeLoc :
672 public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
673 SubstTemplateTypeParmPackTypeLoc,
674 SubstTemplateTypeParmPackType> {
677 struct AttributedLocInfo {
681 /// A raw SourceLocation.
682 unsigned EnumOperandLoc;
685 SourceRange OperandParens;
687 SourceLocation AttrLoc;
690 /// \brief Type source information for an attributed type.
691 class AttributedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
696 AttributedType::Kind getAttrKind() const {
697 return getTypePtr()->getAttrKind();
700 bool hasAttrExprOperand() const {
701 return (getAttrKind() >= AttributedType::FirstExprOperandKind &&
702 getAttrKind() <= AttributedType::LastExprOperandKind);
705 bool hasAttrEnumOperand() const {
706 return (getAttrKind() >= AttributedType::FirstEnumOperandKind &&
707 getAttrKind() <= AttributedType::LastEnumOperandKind);
710 bool hasAttrOperand() const {
711 return hasAttrExprOperand() || hasAttrEnumOperand();
714 /// The modified type, which is generally canonically different from
715 /// the attribute type.
716 /// int main(int, char**) __attribute__((noreturn))
717 /// ~~~ ~~~~~~~~~~~~~
718 TypeLoc getModifiedLoc() const {
719 return getInnerTypeLoc();
722 /// The location of the attribute name, i.e.
723 /// __attribute__((regparm(1000)))
725 SourceLocation getAttrNameLoc() const {
726 return getLocalData()->AttrLoc;
728 void setAttrNameLoc(SourceLocation loc) {
729 getLocalData()->AttrLoc = loc;
732 /// The attribute's expression operand, if it has one.
733 /// void *cur_thread __attribute__((address_space(21)))
735 Expr *getAttrExprOperand() const {
736 assert(hasAttrExprOperand());
737 return getLocalData()->ExprOperand;
739 void setAttrExprOperand(Expr *e) {
740 assert(hasAttrExprOperand());
741 getLocalData()->ExprOperand = e;
744 /// The location of the attribute's enumerated operand, if it has one.
745 /// void * __attribute__((objc_gc(weak)))
747 SourceLocation getAttrEnumOperandLoc() const {
748 assert(hasAttrEnumOperand());
749 return SourceLocation::getFromRawEncoding(getLocalData()->EnumOperandLoc);
751 void setAttrEnumOperandLoc(SourceLocation loc) {
752 assert(hasAttrEnumOperand());
753 getLocalData()->EnumOperandLoc = loc.getRawEncoding();
756 /// The location of the parentheses around the operand, if there is
758 /// void * __attribute__((objc_gc(weak)))
760 SourceRange getAttrOperandParensRange() const {
761 assert(hasAttrOperand());
762 return getLocalData()->OperandParens;
764 void setAttrOperandParensRange(SourceRange range) {
765 assert(hasAttrOperand());
766 getLocalData()->OperandParens = range;
769 SourceRange getLocalSourceRange() const {
770 // Note that this does *not* include the range of the attribute
772 // __attribute__((foo(bar)))
773 // ^~~~~~~~~~~~~~~ ~~
777 // That enclosure doesn't necessarily belong to a single attribute
779 SourceRange range(getAttrNameLoc());
780 if (hasAttrOperand())
781 range.setEnd(getAttrOperandParensRange().getEnd());
785 void initializeLocal(ASTContext &Context, SourceLocation loc) {
787 if (hasAttrExprOperand()) {
788 setAttrOperandParensRange(SourceRange(loc));
789 setAttrExprOperand(nullptr);
790 } else if (hasAttrEnumOperand()) {
791 setAttrOperandParensRange(SourceRange(loc));
792 setAttrEnumOperandLoc(loc);
796 QualType getInnerType() const {
797 return getTypePtr()->getModifiedType();
802 struct ObjCProtocolListLocInfo {
803 SourceLocation LAngleLoc;
804 SourceLocation RAngleLoc;
805 bool HasBaseTypeAsWritten;
808 // A helper class for defining ObjC TypeLocs that can qualified with
811 // TypeClass basically has to be either ObjCInterfaceType or
812 // ObjCObjectPointerType.
813 class ObjCObjectTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
816 ObjCProtocolListLocInfo> {
817 // SourceLocations are stored after Info, one for each Protocol.
818 SourceLocation *getProtocolLocArray() const {
819 return (SourceLocation*) this->getExtraLocalData();
823 SourceLocation getLAngleLoc() const {
824 return this->getLocalData()->LAngleLoc;
826 void setLAngleLoc(SourceLocation Loc) {
827 this->getLocalData()->LAngleLoc = Loc;
830 SourceLocation getRAngleLoc() const {
831 return this->getLocalData()->RAngleLoc;
833 void setRAngleLoc(SourceLocation Loc) {
834 this->getLocalData()->RAngleLoc = Loc;
837 unsigned getNumProtocols() const {
838 return this->getTypePtr()->getNumProtocols();
841 SourceLocation getProtocolLoc(unsigned i) const {
842 assert(i < getNumProtocols() && "Index is out of bounds!");
843 return getProtocolLocArray()[i];
845 void setProtocolLoc(unsigned i, SourceLocation Loc) {
846 assert(i < getNumProtocols() && "Index is out of bounds!");
847 getProtocolLocArray()[i] = Loc;
850 ObjCProtocolDecl *getProtocol(unsigned i) const {
851 assert(i < getNumProtocols() && "Index is out of bounds!");
852 return *(this->getTypePtr()->qual_begin() + i);
855 bool hasBaseTypeAsWritten() const {
856 return getLocalData()->HasBaseTypeAsWritten;
859 void setHasBaseTypeAsWritten(bool HasBaseType) {
860 getLocalData()->HasBaseTypeAsWritten = HasBaseType;
863 TypeLoc getBaseLoc() const {
864 return getInnerTypeLoc();
867 SourceRange getLocalSourceRange() const {
868 return SourceRange(getLAngleLoc(), getRAngleLoc());
871 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
872 setHasBaseTypeAsWritten(true);
875 for (unsigned i = 0, e = getNumProtocols(); i != e; ++i)
876 setProtocolLoc(i, Loc);
879 unsigned getExtraLocalDataSize() const {
880 return this->getNumProtocols() * sizeof(SourceLocation);
883 unsigned getExtraLocalDataAlignment() const {
884 return llvm::alignOf<SourceLocation>();
887 QualType getInnerType() const {
888 return getTypePtr()->getBaseType();
893 struct ObjCInterfaceLocInfo {
894 SourceLocation NameLoc;
895 SourceLocation NameEndLoc;
898 /// \brief Wrapper for source info for ObjC interfaces.
899 class ObjCInterfaceTypeLoc : public ConcreteTypeLoc<ObjCObjectTypeLoc,
900 ObjCInterfaceTypeLoc,
902 ObjCInterfaceLocInfo> {
904 ObjCInterfaceDecl *getIFaceDecl() const {
905 return getTypePtr()->getDecl();
908 SourceLocation getNameLoc() const {
909 return getLocalData()->NameLoc;
912 void setNameLoc(SourceLocation Loc) {
913 getLocalData()->NameLoc = Loc;
916 SourceRange getLocalSourceRange() const {
917 return SourceRange(getNameLoc(), getNameEndLoc());
920 SourceLocation getNameEndLoc() const {
921 return getLocalData()->NameEndLoc;
924 void setNameEndLoc(SourceLocation Loc) {
925 getLocalData()->NameEndLoc = Loc;
928 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
934 struct ParenLocInfo {
935 SourceLocation LParenLoc;
936 SourceLocation RParenLoc;
940 : public ConcreteTypeLoc<UnqualTypeLoc, ParenTypeLoc, ParenType,
943 SourceLocation getLParenLoc() const {
944 return this->getLocalData()->LParenLoc;
946 SourceLocation getRParenLoc() const {
947 return this->getLocalData()->RParenLoc;
949 void setLParenLoc(SourceLocation Loc) {
950 this->getLocalData()->LParenLoc = Loc;
952 void setRParenLoc(SourceLocation Loc) {
953 this->getLocalData()->RParenLoc = Loc;
956 SourceRange getLocalSourceRange() const {
957 return SourceRange(getLParenLoc(), getRParenLoc());
960 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
965 TypeLoc getInnerLoc() const {
966 return getInnerTypeLoc();
969 QualType getInnerType() const {
970 return this->getTypePtr()->getInnerType();
974 inline TypeLoc TypeLoc::IgnoreParens() const {
975 if (ParenTypeLoc::isKind(*this))
976 return IgnoreParensImpl(*this);
981 struct AdjustedLocInfo { }; // Nothing.
983 class AdjustedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, AdjustedTypeLoc,
984 AdjustedType, AdjustedLocInfo> {
986 TypeLoc getOriginalLoc() const {
987 return getInnerTypeLoc();
990 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
994 QualType getInnerType() const {
995 // The inner type is the undecayed type, since that's what we have source
996 // location information for.
997 return getTypePtr()->getOriginalType();
1000 SourceRange getLocalSourceRange() const {
1001 return SourceRange();
1004 unsigned getLocalDataSize() const {
1005 // sizeof(AdjustedLocInfo) is 1, but we don't need its address to be unique
1006 // anyway. TypeLocBuilder can't handle data sizes of 1.
1007 return 0; // No data.
1011 /// \brief Wrapper for source info for pointers decayed from arrays and
1013 class DecayedTypeLoc : public InheritingConcreteTypeLoc<
1014 AdjustedTypeLoc, DecayedTypeLoc, DecayedType> {
1017 struct PointerLikeLocInfo {
1018 SourceLocation StarLoc;
1021 /// A base class for
1022 template <class Derived, class TypeClass, class LocalData = PointerLikeLocInfo>
1023 class PointerLikeTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, Derived,
1024 TypeClass, LocalData> {
1026 SourceLocation getSigilLoc() const {
1027 return this->getLocalData()->StarLoc;
1029 void setSigilLoc(SourceLocation Loc) {
1030 this->getLocalData()->StarLoc = Loc;
1033 TypeLoc getPointeeLoc() const {
1034 return this->getInnerTypeLoc();
1037 SourceRange getLocalSourceRange() const {
1038 return SourceRange(getSigilLoc(), getSigilLoc());
1041 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1045 QualType getInnerType() const {
1046 return this->getTypePtr()->getPointeeType();
1051 /// \brief Wrapper for source info for pointers.
1052 class PointerTypeLoc : public PointerLikeTypeLoc<PointerTypeLoc,
1055 SourceLocation getStarLoc() const {
1056 return getSigilLoc();
1058 void setStarLoc(SourceLocation Loc) {
1064 /// \brief Wrapper for source info for block pointers.
1065 class BlockPointerTypeLoc : public PointerLikeTypeLoc<BlockPointerTypeLoc,
1068 SourceLocation getCaretLoc() const {
1069 return getSigilLoc();
1071 void setCaretLoc(SourceLocation Loc) {
1076 struct MemberPointerLocInfo : public PointerLikeLocInfo {
1077 TypeSourceInfo *ClassTInfo;
1080 /// \brief Wrapper for source info for member pointers.
1081 class MemberPointerTypeLoc : public PointerLikeTypeLoc<MemberPointerTypeLoc,
1083 MemberPointerLocInfo> {
1085 SourceLocation getStarLoc() const {
1086 return getSigilLoc();
1088 void setStarLoc(SourceLocation Loc) {
1092 const Type *getClass() const {
1093 return getTypePtr()->getClass();
1095 TypeSourceInfo *getClassTInfo() const {
1096 return getLocalData()->ClassTInfo;
1098 void setClassTInfo(TypeSourceInfo* TI) {
1099 getLocalData()->ClassTInfo = TI;
1102 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1104 setClassTInfo(nullptr);
1107 SourceRange getLocalSourceRange() const {
1108 if (TypeSourceInfo *TI = getClassTInfo())
1109 return SourceRange(TI->getTypeLoc().getBeginLoc(), getStarLoc());
1111 return SourceRange(getStarLoc());
1115 /// Wraps an ObjCPointerType with source location information.
1116 class ObjCObjectPointerTypeLoc :
1117 public PointerLikeTypeLoc<ObjCObjectPointerTypeLoc,
1118 ObjCObjectPointerType> {
1120 SourceLocation getStarLoc() const {
1121 return getSigilLoc();
1124 void setStarLoc(SourceLocation Loc) {
1130 class ReferenceTypeLoc : public PointerLikeTypeLoc<ReferenceTypeLoc,
1133 QualType getInnerType() const {
1134 return getTypePtr()->getPointeeTypeAsWritten();
1138 class LValueReferenceTypeLoc :
1139 public InheritingConcreteTypeLoc<ReferenceTypeLoc,
1140 LValueReferenceTypeLoc,
1141 LValueReferenceType> {
1143 SourceLocation getAmpLoc() const {
1144 return getSigilLoc();
1146 void setAmpLoc(SourceLocation Loc) {
1151 class RValueReferenceTypeLoc :
1152 public InheritingConcreteTypeLoc<ReferenceTypeLoc,
1153 RValueReferenceTypeLoc,
1154 RValueReferenceType> {
1156 SourceLocation getAmpAmpLoc() const {
1157 return getSigilLoc();
1159 void setAmpAmpLoc(SourceLocation Loc) {
1165 struct FunctionLocInfo {
1166 SourceLocation LocalRangeBegin;
1167 SourceLocation LParenLoc;
1168 SourceLocation RParenLoc;
1169 SourceLocation LocalRangeEnd;
1172 /// \brief Wrapper for source info for functions.
1173 class FunctionTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
1178 SourceLocation getLocalRangeBegin() const {
1179 return getLocalData()->LocalRangeBegin;
1181 void setLocalRangeBegin(SourceLocation L) {
1182 getLocalData()->LocalRangeBegin = L;
1185 SourceLocation getLocalRangeEnd() const {
1186 return getLocalData()->LocalRangeEnd;
1188 void setLocalRangeEnd(SourceLocation L) {
1189 getLocalData()->LocalRangeEnd = L;
1192 SourceLocation getLParenLoc() const {
1193 return this->getLocalData()->LParenLoc;
1195 void setLParenLoc(SourceLocation Loc) {
1196 this->getLocalData()->LParenLoc = Loc;
1199 SourceLocation getRParenLoc() const {
1200 return this->getLocalData()->RParenLoc;
1202 void setRParenLoc(SourceLocation Loc) {
1203 this->getLocalData()->RParenLoc = Loc;
1206 SourceRange getParensRange() const {
1207 return SourceRange(getLParenLoc(), getRParenLoc());
1210 ArrayRef<ParmVarDecl *> getParams() const {
1211 return llvm::makeArrayRef(getParmArray(), getNumParams());
1214 // ParmVarDecls* are stored after Info, one for each parameter.
1215 ParmVarDecl **getParmArray() const {
1216 return (ParmVarDecl**) getExtraLocalData();
1219 unsigned getNumParams() const {
1220 if (isa<FunctionNoProtoType>(getTypePtr()))
1222 return cast<FunctionProtoType>(getTypePtr())->getNumParams();
1224 ParmVarDecl *getParam(unsigned i) const { return getParmArray()[i]; }
1225 void setParam(unsigned i, ParmVarDecl *VD) { getParmArray()[i] = VD; }
1227 TypeLoc getReturnLoc() const {
1228 return getInnerTypeLoc();
1231 SourceRange getLocalSourceRange() const {
1232 return SourceRange(getLocalRangeBegin(), getLocalRangeEnd());
1235 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1236 setLocalRangeBegin(Loc);
1239 setLocalRangeEnd(Loc);
1240 for (unsigned i = 0, e = getNumParams(); i != e; ++i)
1241 setParam(i, nullptr);
1244 /// \brief Returns the size of the type source info data block that is
1245 /// specific to this type.
1246 unsigned getExtraLocalDataSize() const {
1247 return getNumParams() * sizeof(ParmVarDecl *);
1250 unsigned getExtraLocalDataAlignment() const {
1251 return llvm::alignOf<ParmVarDecl*>();
1254 QualType getInnerType() const { return getTypePtr()->getReturnType(); }
1257 class FunctionProtoTypeLoc :
1258 public InheritingConcreteTypeLoc<FunctionTypeLoc,
1259 FunctionProtoTypeLoc,
1260 FunctionProtoType> {
1263 class FunctionNoProtoTypeLoc :
1264 public InheritingConcreteTypeLoc<FunctionTypeLoc,
1265 FunctionNoProtoTypeLoc,
1266 FunctionNoProtoType> {
1270 struct ArrayLocInfo {
1271 SourceLocation LBracketLoc, RBracketLoc;
1275 /// \brief Wrapper for source info for arrays.
1276 class ArrayTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
1281 SourceLocation getLBracketLoc() const {
1282 return getLocalData()->LBracketLoc;
1284 void setLBracketLoc(SourceLocation Loc) {
1285 getLocalData()->LBracketLoc = Loc;
1288 SourceLocation getRBracketLoc() const {
1289 return getLocalData()->RBracketLoc;
1291 void setRBracketLoc(SourceLocation Loc) {
1292 getLocalData()->RBracketLoc = Loc;
1295 SourceRange getBracketsRange() const {
1296 return SourceRange(getLBracketLoc(), getRBracketLoc());
1299 Expr *getSizeExpr() const {
1300 return getLocalData()->Size;
1302 void setSizeExpr(Expr *Size) {
1303 getLocalData()->Size = Size;
1306 TypeLoc getElementLoc() const {
1307 return getInnerTypeLoc();
1310 SourceRange getLocalSourceRange() const {
1311 return SourceRange(getLBracketLoc(), getRBracketLoc());
1314 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1315 setLBracketLoc(Loc);
1316 setRBracketLoc(Loc);
1317 setSizeExpr(nullptr);
1320 QualType getInnerType() const { return getTypePtr()->getElementType(); }
1323 class ConstantArrayTypeLoc :
1324 public InheritingConcreteTypeLoc<ArrayTypeLoc,
1325 ConstantArrayTypeLoc,
1326 ConstantArrayType> {
1329 class IncompleteArrayTypeLoc :
1330 public InheritingConcreteTypeLoc<ArrayTypeLoc,
1331 IncompleteArrayTypeLoc,
1332 IncompleteArrayType> {
1335 class DependentSizedArrayTypeLoc :
1336 public InheritingConcreteTypeLoc<ArrayTypeLoc,
1337 DependentSizedArrayTypeLoc,
1338 DependentSizedArrayType> {
1342 class VariableArrayTypeLoc :
1343 public InheritingConcreteTypeLoc<ArrayTypeLoc,
1344 VariableArrayTypeLoc,
1345 VariableArrayType> {
1349 // Location information for a TemplateName. Rudimentary for now.
1350 struct TemplateNameLocInfo {
1351 SourceLocation NameLoc;
1354 struct TemplateSpecializationLocInfo : TemplateNameLocInfo {
1355 SourceLocation TemplateKWLoc;
1356 SourceLocation LAngleLoc;
1357 SourceLocation RAngleLoc;
1360 class TemplateSpecializationTypeLoc :
1361 public ConcreteTypeLoc<UnqualTypeLoc,
1362 TemplateSpecializationTypeLoc,
1363 TemplateSpecializationType,
1364 TemplateSpecializationLocInfo> {
1366 SourceLocation getTemplateKeywordLoc() const {
1367 return getLocalData()->TemplateKWLoc;
1369 void setTemplateKeywordLoc(SourceLocation Loc) {
1370 getLocalData()->TemplateKWLoc = Loc;
1373 SourceLocation getLAngleLoc() const {
1374 return getLocalData()->LAngleLoc;
1376 void setLAngleLoc(SourceLocation Loc) {
1377 getLocalData()->LAngleLoc = Loc;
1380 SourceLocation getRAngleLoc() const {
1381 return getLocalData()->RAngleLoc;
1383 void setRAngleLoc(SourceLocation Loc) {
1384 getLocalData()->RAngleLoc = Loc;
1387 unsigned getNumArgs() const {
1388 return getTypePtr()->getNumArgs();
1390 void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) {
1391 getArgInfos()[i] = AI;
1393 TemplateArgumentLocInfo getArgLocInfo(unsigned i) const {
1394 return getArgInfos()[i];
1397 TemplateArgumentLoc getArgLoc(unsigned i) const {
1398 return TemplateArgumentLoc(getTypePtr()->getArg(i), getArgLocInfo(i));
1401 SourceLocation getTemplateNameLoc() const {
1402 return getLocalData()->NameLoc;
1404 void setTemplateNameLoc(SourceLocation Loc) {
1405 getLocalData()->NameLoc = Loc;
1408 /// \brief - Copy the location information from the given info.
1409 void copy(TemplateSpecializationTypeLoc Loc) {
1410 unsigned size = getFullDataSize();
1411 assert(size == Loc.getFullDataSize());
1413 // We're potentially copying Expr references here. We don't
1414 // bother retaining them because TypeSourceInfos live forever, so
1415 // as long as the Expr was retained when originally written into
1416 // the TypeLoc, we're okay.
1417 memcpy(Data, Loc.Data, size);
1420 SourceRange getLocalSourceRange() const {
1421 if (getTemplateKeywordLoc().isValid())
1422 return SourceRange(getTemplateKeywordLoc(), getRAngleLoc());
1424 return SourceRange(getTemplateNameLoc(), getRAngleLoc());
1427 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1428 setTemplateKeywordLoc(Loc);
1429 setTemplateNameLoc(Loc);
1432 initializeArgLocs(Context, getNumArgs(), getTypePtr()->getArgs(),
1433 getArgInfos(), Loc);
1436 static void initializeArgLocs(ASTContext &Context, unsigned NumArgs,
1437 const TemplateArgument *Args,
1438 TemplateArgumentLocInfo *ArgInfos,
1439 SourceLocation Loc);
1441 unsigned getExtraLocalDataSize() const {
1442 return getNumArgs() * sizeof(TemplateArgumentLocInfo);
1445 unsigned getExtraLocalDataAlignment() const {
1446 return llvm::alignOf<TemplateArgumentLocInfo>();
1450 TemplateArgumentLocInfo *getArgInfos() const {
1451 return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData());
1455 //===----------------------------------------------------------------------===//
1457 // All of these need proper implementations.
1459 //===----------------------------------------------------------------------===//
1461 // FIXME: size expression and attribute locations (or keyword if we
1462 // ever fully support altivec syntax).
1463 class VectorTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
1468 // FIXME: size expression and attribute locations.
1469 class ExtVectorTypeLoc : public InheritingConcreteTypeLoc<VectorTypeLoc,
1474 // FIXME: attribute locations.
1475 // For some reason, this isn't a subtype of VectorType.
1476 class DependentSizedExtVectorTypeLoc :
1477 public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
1478 DependentSizedExtVectorTypeLoc,
1479 DependentSizedExtVectorType> {
1482 // FIXME: location of the '_Complex' keyword.
1483 class ComplexTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
1488 struct TypeofLocInfo {
1489 SourceLocation TypeofLoc;
1490 SourceLocation LParenLoc;
1491 SourceLocation RParenLoc;
1494 struct TypeOfExprTypeLocInfo : public TypeofLocInfo {
1497 struct TypeOfTypeLocInfo : public TypeofLocInfo {
1498 TypeSourceInfo* UnderlyingTInfo;
1501 template <class Derived, class TypeClass, class LocalData = TypeofLocInfo>
1502 class TypeofLikeTypeLoc
1503 : public ConcreteTypeLoc<UnqualTypeLoc, Derived, TypeClass, LocalData> {
1505 SourceLocation getTypeofLoc() const {
1506 return this->getLocalData()->TypeofLoc;
1508 void setTypeofLoc(SourceLocation Loc) {
1509 this->getLocalData()->TypeofLoc = Loc;
1512 SourceLocation getLParenLoc() const {
1513 return this->getLocalData()->LParenLoc;
1515 void setLParenLoc(SourceLocation Loc) {
1516 this->getLocalData()->LParenLoc = Loc;
1519 SourceLocation getRParenLoc() const {
1520 return this->getLocalData()->RParenLoc;
1522 void setRParenLoc(SourceLocation Loc) {
1523 this->getLocalData()->RParenLoc = Loc;
1526 SourceRange getParensRange() const {
1527 return SourceRange(getLParenLoc(), getRParenLoc());
1529 void setParensRange(SourceRange range) {
1530 setLParenLoc(range.getBegin());
1531 setRParenLoc(range.getEnd());
1534 SourceRange getLocalSourceRange() const {
1535 return SourceRange(getTypeofLoc(), getRParenLoc());
1538 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1545 class TypeOfExprTypeLoc : public TypeofLikeTypeLoc<TypeOfExprTypeLoc,
1547 TypeOfExprTypeLocInfo> {
1549 Expr* getUnderlyingExpr() const {
1550 return getTypePtr()->getUnderlyingExpr();
1552 // Reimplemented to account for GNU/C++ extension
1553 // typeof unary-expression
1554 // where there are no parentheses.
1555 SourceRange getLocalSourceRange() const;
1559 : public TypeofLikeTypeLoc<TypeOfTypeLoc, TypeOfType, TypeOfTypeLocInfo> {
1561 QualType getUnderlyingType() const {
1562 return this->getTypePtr()->getUnderlyingType();
1564 TypeSourceInfo* getUnderlyingTInfo() const {
1565 return this->getLocalData()->UnderlyingTInfo;
1567 void setUnderlyingTInfo(TypeSourceInfo* TI) const {
1568 this->getLocalData()->UnderlyingTInfo = TI;
1571 void initializeLocal(ASTContext &Context, SourceLocation Loc);
1574 // FIXME: location of the 'decltype' and parens.
1575 class DecltypeTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
1579 Expr *getUnderlyingExpr() const { return getTypePtr()->getUnderlyingExpr(); }
1582 struct UnaryTransformTypeLocInfo {
1583 // FIXME: While there's only one unary transform right now, future ones may
1584 // need different representations
1585 SourceLocation KWLoc, LParenLoc, RParenLoc;
1586 TypeSourceInfo *UnderlyingTInfo;
1589 class UnaryTransformTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
1590 UnaryTransformTypeLoc,
1592 UnaryTransformTypeLocInfo> {
1594 SourceLocation getKWLoc() const { return getLocalData()->KWLoc; }
1595 void setKWLoc(SourceLocation Loc) { getLocalData()->KWLoc = Loc; }
1597 SourceLocation getLParenLoc() const { return getLocalData()->LParenLoc; }
1598 void setLParenLoc(SourceLocation Loc) { getLocalData()->LParenLoc = Loc; }
1600 SourceLocation getRParenLoc() const { return getLocalData()->RParenLoc; }
1601 void setRParenLoc(SourceLocation Loc) { getLocalData()->RParenLoc = Loc; }
1603 TypeSourceInfo* getUnderlyingTInfo() const {
1604 return getLocalData()->UnderlyingTInfo;
1606 void setUnderlyingTInfo(TypeSourceInfo *TInfo) {
1607 getLocalData()->UnderlyingTInfo = TInfo;
1610 SourceRange getLocalSourceRange() const {
1611 return SourceRange(getKWLoc(), getRParenLoc());
1614 SourceRange getParensRange() const {
1615 return SourceRange(getLParenLoc(), getRParenLoc());
1617 void setParensRange(SourceRange Range) {
1618 setLParenLoc(Range.getBegin());
1619 setRParenLoc(Range.getEnd());
1622 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1629 class AutoTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
1634 struct ElaboratedLocInfo {
1635 SourceLocation ElaboratedKWLoc;
1636 /// \brief Data associated with the nested-name-specifier location.
1637 void *QualifierData;
1640 class ElaboratedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
1643 ElaboratedLocInfo> {
1645 SourceLocation getElaboratedKeywordLoc() const {
1646 return this->getLocalData()->ElaboratedKWLoc;
1648 void setElaboratedKeywordLoc(SourceLocation Loc) {
1649 this->getLocalData()->ElaboratedKWLoc = Loc;
1652 NestedNameSpecifierLoc getQualifierLoc() const {
1653 return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
1654 getLocalData()->QualifierData);
1657 void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
1658 assert(QualifierLoc.getNestedNameSpecifier()
1659 == getTypePtr()->getQualifier() &&
1660 "Inconsistent nested-name-specifier pointer");
1661 getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
1664 SourceRange getLocalSourceRange() const {
1665 if (getElaboratedKeywordLoc().isValid())
1666 if (getQualifierLoc())
1667 return SourceRange(getElaboratedKeywordLoc(),
1668 getQualifierLoc().getEndLoc());
1670 return SourceRange(getElaboratedKeywordLoc());
1672 return getQualifierLoc().getSourceRange();
1675 void initializeLocal(ASTContext &Context, SourceLocation Loc);
1677 TypeLoc getNamedTypeLoc() const {
1678 return getInnerTypeLoc();
1681 QualType getInnerType() const {
1682 return getTypePtr()->getNamedType();
1685 void copy(ElaboratedTypeLoc Loc) {
1686 unsigned size = getFullDataSize();
1687 assert(size == Loc.getFullDataSize());
1688 memcpy(Data, Loc.Data, size);
1692 // This is exactly the structure of an ElaboratedTypeLoc whose inner
1693 // type is some sort of TypeDeclTypeLoc.
1694 struct DependentNameLocInfo : ElaboratedLocInfo {
1695 SourceLocation NameLoc;
1698 class DependentNameTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
1699 DependentNameTypeLoc,
1701 DependentNameLocInfo> {
1703 SourceLocation getElaboratedKeywordLoc() const {
1704 return this->getLocalData()->ElaboratedKWLoc;
1706 void setElaboratedKeywordLoc(SourceLocation Loc) {
1707 this->getLocalData()->ElaboratedKWLoc = Loc;
1710 NestedNameSpecifierLoc getQualifierLoc() const {
1711 return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
1712 getLocalData()->QualifierData);
1715 void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
1716 assert(QualifierLoc.getNestedNameSpecifier()
1717 == getTypePtr()->getQualifier() &&
1718 "Inconsistent nested-name-specifier pointer");
1719 getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
1722 SourceLocation getNameLoc() const {
1723 return this->getLocalData()->NameLoc;
1725 void setNameLoc(SourceLocation Loc) {
1726 this->getLocalData()->NameLoc = Loc;
1729 SourceRange getLocalSourceRange() const {
1730 if (getElaboratedKeywordLoc().isValid())
1731 return SourceRange(getElaboratedKeywordLoc(), getNameLoc());
1733 return SourceRange(getQualifierLoc().getBeginLoc(), getNameLoc());
1736 void copy(DependentNameTypeLoc Loc) {
1737 unsigned size = getFullDataSize();
1738 assert(size == Loc.getFullDataSize());
1739 memcpy(Data, Loc.Data, size);
1742 void initializeLocal(ASTContext &Context, SourceLocation Loc);
1745 struct DependentTemplateSpecializationLocInfo : DependentNameLocInfo {
1746 SourceLocation TemplateKWLoc;
1747 SourceLocation LAngleLoc;
1748 SourceLocation RAngleLoc;
1749 // followed by a TemplateArgumentLocInfo[]
1752 class DependentTemplateSpecializationTypeLoc :
1753 public ConcreteTypeLoc<UnqualTypeLoc,
1754 DependentTemplateSpecializationTypeLoc,
1755 DependentTemplateSpecializationType,
1756 DependentTemplateSpecializationLocInfo> {
1758 SourceLocation getElaboratedKeywordLoc() const {
1759 return this->getLocalData()->ElaboratedKWLoc;
1761 void setElaboratedKeywordLoc(SourceLocation Loc) {
1762 this->getLocalData()->ElaboratedKWLoc = Loc;
1765 NestedNameSpecifierLoc getQualifierLoc() const {
1766 if (!getLocalData()->QualifierData)
1767 return NestedNameSpecifierLoc();
1769 return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
1770 getLocalData()->QualifierData);
1773 void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
1774 if (!QualifierLoc) {
1775 // Even if we have a nested-name-specifier in the dependent
1776 // template specialization type, we won't record the nested-name-specifier
1777 // location information when this type-source location information is
1778 // part of a nested-name-specifier.
1779 getLocalData()->QualifierData = nullptr;
1783 assert(QualifierLoc.getNestedNameSpecifier()
1784 == getTypePtr()->getQualifier() &&
1785 "Inconsistent nested-name-specifier pointer");
1786 getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
1789 SourceLocation getTemplateKeywordLoc() const {
1790 return getLocalData()->TemplateKWLoc;
1792 void setTemplateKeywordLoc(SourceLocation Loc) {
1793 getLocalData()->TemplateKWLoc = Loc;
1796 SourceLocation getTemplateNameLoc() const {
1797 return this->getLocalData()->NameLoc;
1799 void setTemplateNameLoc(SourceLocation Loc) {
1800 this->getLocalData()->NameLoc = Loc;
1803 SourceLocation getLAngleLoc() const {
1804 return this->getLocalData()->LAngleLoc;
1806 void setLAngleLoc(SourceLocation Loc) {
1807 this->getLocalData()->LAngleLoc = Loc;
1810 SourceLocation getRAngleLoc() const {
1811 return this->getLocalData()->RAngleLoc;
1813 void setRAngleLoc(SourceLocation Loc) {
1814 this->getLocalData()->RAngleLoc = Loc;
1817 unsigned getNumArgs() const {
1818 return getTypePtr()->getNumArgs();
1821 void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) {
1822 getArgInfos()[i] = AI;
1824 TemplateArgumentLocInfo getArgLocInfo(unsigned i) const {
1825 return getArgInfos()[i];
1828 TemplateArgumentLoc getArgLoc(unsigned i) const {
1829 return TemplateArgumentLoc(getTypePtr()->getArg(i), getArgLocInfo(i));
1832 SourceRange getLocalSourceRange() const {
1833 if (getElaboratedKeywordLoc().isValid())
1834 return SourceRange(getElaboratedKeywordLoc(), getRAngleLoc());
1835 else if (getQualifierLoc())
1836 return SourceRange(getQualifierLoc().getBeginLoc(), getRAngleLoc());
1837 else if (getTemplateKeywordLoc().isValid())
1838 return SourceRange(getTemplateKeywordLoc(), getRAngleLoc());
1840 return SourceRange(getTemplateNameLoc(), getRAngleLoc());
1843 void copy(DependentTemplateSpecializationTypeLoc Loc) {
1844 unsigned size = getFullDataSize();
1845 assert(size == Loc.getFullDataSize());
1846 memcpy(Data, Loc.Data, size);
1849 void initializeLocal(ASTContext &Context, SourceLocation Loc);
1851 unsigned getExtraLocalDataSize() const {
1852 return getNumArgs() * sizeof(TemplateArgumentLocInfo);
1855 unsigned getExtraLocalDataAlignment() const {
1856 return llvm::alignOf<TemplateArgumentLocInfo>();
1860 TemplateArgumentLocInfo *getArgInfos() const {
1861 return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData());
1866 struct PackExpansionTypeLocInfo {
1867 SourceLocation EllipsisLoc;
1870 class PackExpansionTypeLoc
1871 : public ConcreteTypeLoc<UnqualTypeLoc, PackExpansionTypeLoc,
1872 PackExpansionType, PackExpansionTypeLocInfo> {
1874 SourceLocation getEllipsisLoc() const {
1875 return this->getLocalData()->EllipsisLoc;
1878 void setEllipsisLoc(SourceLocation Loc) {
1879 this->getLocalData()->EllipsisLoc = Loc;
1882 SourceRange getLocalSourceRange() const {
1883 return SourceRange(getEllipsisLoc(), getEllipsisLoc());
1886 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1887 setEllipsisLoc(Loc);
1890 TypeLoc getPatternLoc() const {
1891 return getInnerTypeLoc();
1894 QualType getInnerType() const {
1895 return this->getTypePtr()->getPattern();
1899 struct AtomicTypeLocInfo {
1900 SourceLocation KWLoc, LParenLoc, RParenLoc;
1903 class AtomicTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, AtomicTypeLoc,
1904 AtomicType, AtomicTypeLocInfo> {
1906 TypeLoc getValueLoc() const {
1907 return this->getInnerTypeLoc();
1910 SourceRange getLocalSourceRange() const {
1911 return SourceRange(getKWLoc(), getRParenLoc());
1914 SourceLocation getKWLoc() const {
1915 return this->getLocalData()->KWLoc;
1917 void setKWLoc(SourceLocation Loc) {
1918 this->getLocalData()->KWLoc = Loc;
1921 SourceLocation getLParenLoc() const {
1922 return this->getLocalData()->LParenLoc;
1924 void setLParenLoc(SourceLocation Loc) {
1925 this->getLocalData()->LParenLoc = Loc;
1928 SourceLocation getRParenLoc() const {
1929 return this->getLocalData()->RParenLoc;
1931 void setRParenLoc(SourceLocation Loc) {
1932 this->getLocalData()->RParenLoc = Loc;
1935 SourceRange getParensRange() const {
1936 return SourceRange(getLParenLoc(), getRParenLoc());
1938 void setParensRange(SourceRange Range) {
1939 setLParenLoc(Range.getBegin());
1940 setRParenLoc(Range.getEnd());
1943 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1949 QualType getInnerType() const {
1950 return this->getTypePtr()->getValueType();