1 //===- TypeLoc.h - Type Source Info Wrapper ---------------------*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
10 /// Defines the clang::TypeLoc interface and its subclasses.
12 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_CLANG_AST_TYPELOC_H
15 #define LLVM_CLANG_AST_TYPELOC_H
17 #include "clang/AST/Attr.h"
18 #include "clang/AST/Decl.h"
19 #include "clang/AST/NestedNameSpecifier.h"
20 #include "clang/AST/TemplateBase.h"
21 #include "clang/AST/Type.h"
22 #include "clang/Basic/LLVM.h"
23 #include "clang/Basic/SourceLocation.h"
24 #include "clang/Basic/Specifiers.h"
25 #include "llvm/ADT/ArrayRef.h"
26 #include "llvm/Support/Casting.h"
27 #include "llvm/Support/Compiler.h"
28 #include "llvm/Support/MathExtras.h"
39 class ObjCInterfaceDecl;
40 class ObjCProtocolDecl;
41 class ObjCTypeParamDecl;
42 class TemplateTypeParmDecl;
44 class UnresolvedUsingTypenameDecl;
46 // Predeclare all the type nodes.
47 #define ABSTRACT_TYPELOC(Class, Base)
48 #define TYPELOC(Class, Base) \
50 #include "clang/AST/TypeLocNodes.def"
52 /// Base wrapper for a particular "section" of type source info.
54 /// A client should use the TypeLoc subclasses through castAs()/getAs()
55 /// in order to get at the actual information.
58 // The correctness of this relies on the property that, for Type *Ty,
59 // QualType(Ty, 0).getAsOpaquePtr() == (void*) Ty
60 const void *Ty = nullptr;
65 TypeLoc(QualType ty, void *opaqueData)
66 : Ty(ty.getAsOpaquePtr()), Data(opaqueData) {}
67 TypeLoc(const Type *ty, void *opaqueData)
68 : Ty(ty), Data(opaqueData) {}
70 /// Convert to the specified TypeLoc type, asserting that this TypeLoc
71 /// is of the desired type.
73 /// \pre T::isKind(*this)
76 assert(T::isKind(*this));
83 /// Convert to the specified TypeLoc type, returning a null TypeLoc if
84 /// this TypeLoc is not of the desired type.
87 if (!T::isKind(*this))
95 /// Convert to the specified TypeLoc type, returning a null TypeLoc if
96 /// this TypeLoc is not of the desired type. It will consider type
97 /// adjustments from a type that was written as a T to another type that is
98 /// still canonically a T (ignores parens, attributes, elaborated types, etc).
100 T getAsAdjusted() const;
102 /// The kinds of TypeLocs. Equivalent to the Type::TypeClass enum,
103 /// except it also defines a Qualified enum that corresponds to the
104 /// QualifiedLoc class.
106 #define ABSTRACT_TYPE(Class, Base)
107 #define TYPE(Class, Base) \
109 #include "clang/AST/TypeNodes.def"
113 TypeLocClass getTypeLocClass() const {
114 if (getType().hasLocalQualifiers()) return Qualified;
115 return (TypeLocClass) getType()->getTypeClass();
118 bool isNull() const { return !Ty; }
119 explicit operator bool() const { return Ty; }
121 /// Returns the size of type source info data block for the given type.
122 static unsigned getFullDataSizeForType(QualType Ty);
124 /// Returns the alignment of type source info data block for
126 static unsigned getLocalAlignmentForType(QualType Ty);
128 /// Get the type for which this source info wrapper provides
130 QualType getType() const {
131 return QualType::getFromOpaquePtr(Ty);
134 const Type *getTypePtr() const {
135 return QualType::getFromOpaquePtr(Ty).getTypePtr();
138 /// Get the pointer where source information is stored.
139 void *getOpaqueData() const {
143 /// Get the begin source location.
144 SourceLocation getBeginLoc() const;
146 /// Get the end source location.
147 SourceLocation getEndLoc() const;
149 /// Get the full source range.
150 SourceRange getSourceRange() const LLVM_READONLY {
151 return SourceRange(getBeginLoc(), getEndLoc());
155 /// Get the local source range.
156 SourceRange getLocalSourceRange() const {
157 return getLocalSourceRangeImpl(*this);
160 /// Returns the size of the type source info data block.
161 unsigned getFullDataSize() const {
162 return getFullDataSizeForType(getType());
165 /// Get the next TypeLoc pointed by this TypeLoc, e.g for "int*" the
166 /// TypeLoc is a PointerLoc and next TypeLoc is for "int".
167 TypeLoc getNextTypeLoc() const {
168 return getNextTypeLocImpl(*this);
171 /// Skips past any qualifiers, if this is qualified.
172 UnqualTypeLoc getUnqualifiedLoc() const; // implemented in this header
174 TypeLoc IgnoreParens() const;
176 /// Strips MacroDefinitionTypeLocs from a type location.
177 TypeLoc IgnoreMacroDefinitions() const;
179 /// Find a type with the location of an explicit type qualifier.
181 /// The result, if non-null, will be one of:
184 /// AttributedTypeLoc, for those type attributes that behave as qualifiers
185 TypeLoc findExplicitQualifierLoc() const;
187 /// Initializes this to state that every location in this
188 /// type is the given location.
190 /// This method exists to provide a simple transition for code that
191 /// relies on location-less types.
192 void initialize(ASTContext &Context, SourceLocation Loc) const {
193 initializeImpl(Context, *this, Loc);
196 /// Initializes this by copying its information from another
197 /// TypeLoc of the same type.
198 void initializeFullCopy(TypeLoc Other) {
199 assert(getType() == Other.getType());
203 /// Initializes this by copying its information from another
204 /// TypeLoc of the same type. The given size must be the full data
206 void initializeFullCopy(TypeLoc Other, unsigned Size) {
207 assert(getType() == Other.getType());
208 assert(getFullDataSize() == Size);
212 /// Copies the other type loc into this one.
213 void copy(TypeLoc other);
215 friend bool operator==(const TypeLoc &LHS, const TypeLoc &RHS) {
216 return LHS.Ty == RHS.Ty && LHS.Data == RHS.Data;
219 friend bool operator!=(const TypeLoc &LHS, const TypeLoc &RHS) {
220 return !(LHS == RHS);
223 /// Find the location of the nullability specifier (__nonnull,
224 /// __nullable, or __null_unspecifier), if there is one.
225 SourceLocation findNullabilityLoc() const;
228 static bool isKind(const TypeLoc&) {
232 static void initializeImpl(ASTContext &Context, TypeLoc TL,
234 static TypeLoc getNextTypeLocImpl(TypeLoc TL);
235 static TypeLoc IgnoreParensImpl(TypeLoc TL);
236 static SourceRange getLocalSourceRangeImpl(TypeLoc TL);
239 /// Return the TypeLoc for a type source info.
240 inline TypeLoc TypeSourceInfo::getTypeLoc() const {
241 // TODO: is this alignment already sufficient?
242 return TypeLoc(Ty, const_cast<void*>(static_cast<const void*>(this + 1)));
245 /// Wrapper of type source information for a type with
246 /// no direct qualifiers.
247 class UnqualTypeLoc : public TypeLoc {
249 UnqualTypeLoc() = default;
250 UnqualTypeLoc(const Type *Ty, void *Data) : TypeLoc(Ty, Data) {}
252 const Type *getTypePtr() const {
253 return reinterpret_cast<const Type*>(Ty);
256 TypeLocClass getTypeLocClass() const {
257 return (TypeLocClass) getTypePtr()->getTypeClass();
261 friend class TypeLoc;
263 static bool isKind(const TypeLoc &TL) {
264 return !TL.getType().hasLocalQualifiers();
268 /// Wrapper of type source information for a type with
269 /// non-trivial direct qualifiers.
271 /// Currently, we intentionally do not provide source location for
273 class QualifiedTypeLoc : public TypeLoc {
275 SourceRange getLocalSourceRange() const { return {}; }
277 UnqualTypeLoc getUnqualifiedLoc() const {
279 TypeLoc::getLocalAlignmentForType(QualType(getTypePtr(), 0));
280 auto dataInt = reinterpret_cast<uintptr_t>(Data);
281 dataInt = llvm::alignTo(dataInt, align);
282 return UnqualTypeLoc(getTypePtr(), reinterpret_cast<void*>(dataInt));
285 /// Initializes the local data of this type source info block to
286 /// provide no information.
287 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
291 void copyLocal(TypeLoc other) {
295 TypeLoc getNextTypeLoc() const {
296 return getUnqualifiedLoc();
299 /// Returns the size of the type source info data block that is
300 /// specific to this type.
301 unsigned getLocalDataSize() const {
302 // In fact, we don't currently preserve any location information
307 /// Returns the alignment of the type source info data block that is
308 /// specific to this type.
309 unsigned getLocalDataAlignment() const {
310 // We don't preserve any location information.
315 friend class TypeLoc;
317 static bool isKind(const TypeLoc &TL) {
318 return TL.getType().hasLocalQualifiers();
322 inline UnqualTypeLoc TypeLoc::getUnqualifiedLoc() const {
323 if (QualifiedTypeLoc Loc = getAs<QualifiedTypeLoc>())
324 return Loc.getUnqualifiedLoc();
325 return castAs<UnqualTypeLoc>();
328 /// A metaprogramming base class for TypeLoc classes which correspond
329 /// to a particular Type subclass. It is accepted for a single
330 /// TypeLoc class to correspond to multiple Type classes.
332 /// \tparam Base a class from which to derive
333 /// \tparam Derived the class deriving from this one
334 /// \tparam TypeClass the concrete Type subclass associated with this
336 /// \tparam LocalData the structure type of local location data for
339 /// TypeLocs with non-constant amounts of local data should override
340 /// getExtraLocalDataSize(); getExtraLocalData() will then point to
341 /// this extra memory.
343 /// TypeLocs with an inner type should define
344 /// QualType getInnerType() const
345 /// and getInnerTypeLoc() will then point to this inner type's
348 /// A word about hierarchies: this template is not designed to be
349 /// derived from multiple times in a hierarchy. It is also not
350 /// designed to be used for classes where subtypes might provide
351 /// different amounts of source information. It should be subclassed
352 /// only at the deepest portion of the hierarchy where all children
353 /// have identical source information; if that's an abstract type,
354 /// then further descendents should inherit from
355 /// InheritingConcreteTypeLoc instead.
356 template <class Base, class Derived, class TypeClass, class LocalData>
357 class ConcreteTypeLoc : public Base {
358 friend class TypeLoc;
360 const Derived *asDerived() const {
361 return static_cast<const Derived*>(this);
364 static bool isKind(const TypeLoc &TL) {
365 return !TL.getType().hasLocalQualifiers() &&
366 Derived::classofType(TL.getTypePtr());
369 static bool classofType(const Type *Ty) {
370 return TypeClass::classof(Ty);
374 unsigned getLocalDataAlignment() const {
375 return std::max(unsigned(alignof(LocalData)),
376 asDerived()->getExtraLocalDataAlignment());
379 unsigned getLocalDataSize() const {
380 unsigned size = sizeof(LocalData);
381 unsigned extraAlign = asDerived()->getExtraLocalDataAlignment();
382 size = llvm::alignTo(size, extraAlign);
383 size += asDerived()->getExtraLocalDataSize();
387 void copyLocal(Derived other) {
388 // Some subclasses have no data to copy.
389 if (asDerived()->getLocalDataSize() == 0) return;
391 // Copy the fixed-sized local data.
392 memcpy(getLocalData(), other.getLocalData(), sizeof(LocalData));
394 // Copy the variable-sized local data. We need to do this
395 // separately because the padding in the source and the padding in
396 // the destination might be different.
397 memcpy(getExtraLocalData(), other.getExtraLocalData(),
398 asDerived()->getExtraLocalDataSize());
401 TypeLoc getNextTypeLoc() const {
402 return getNextTypeLoc(asDerived()->getInnerType());
405 const TypeClass *getTypePtr() const {
406 return cast<TypeClass>(Base::getTypePtr());
410 unsigned getExtraLocalDataSize() const {
414 unsigned getExtraLocalDataAlignment() const {
418 LocalData *getLocalData() const {
419 return static_cast<LocalData*>(Base::Data);
422 /// Gets a pointer past the Info structure; useful for classes with
423 /// local data that can't be captured in the Info (e.g. because it's
424 /// of variable size).
425 void *getExtraLocalData() const {
426 unsigned size = sizeof(LocalData);
427 unsigned extraAlign = asDerived()->getExtraLocalDataAlignment();
428 size = llvm::alignTo(size, extraAlign);
429 return reinterpret_cast<char*>(Base::Data) + size;
432 void *getNonLocalData() const {
433 auto data = reinterpret_cast<uintptr_t>(Base::Data);
434 data += asDerived()->getLocalDataSize();
435 data = llvm::alignTo(data, getNextTypeAlign());
436 return reinterpret_cast<void*>(data);
439 struct HasNoInnerType {};
440 HasNoInnerType getInnerType() const { return HasNoInnerType(); }
442 TypeLoc getInnerTypeLoc() const {
443 return TypeLoc(asDerived()->getInnerType(), getNonLocalData());
447 unsigned getInnerTypeSize() const {
448 return getInnerTypeSize(asDerived()->getInnerType());
451 unsigned getInnerTypeSize(HasNoInnerType _) const {
455 unsigned getInnerTypeSize(QualType _) const {
456 return getInnerTypeLoc().getFullDataSize();
459 unsigned getNextTypeAlign() const {
460 return getNextTypeAlign(asDerived()->getInnerType());
463 unsigned getNextTypeAlign(HasNoInnerType _) const {
467 unsigned getNextTypeAlign(QualType T) const {
468 return TypeLoc::getLocalAlignmentForType(T);
471 TypeLoc getNextTypeLoc(HasNoInnerType _) const { return {}; }
473 TypeLoc getNextTypeLoc(QualType T) const {
474 return TypeLoc(T, getNonLocalData());
478 /// A metaprogramming class designed for concrete subtypes of abstract
479 /// types where all subtypes share equivalently-structured source
480 /// information. See the note on ConcreteTypeLoc.
481 template <class Base, class Derived, class TypeClass>
482 class InheritingConcreteTypeLoc : public Base {
483 friend class TypeLoc;
485 static bool classofType(const Type *Ty) {
486 return TypeClass::classof(Ty);
489 static bool isKind(const TypeLoc &TL) {
490 return !TL.getType().hasLocalQualifiers() &&
491 Derived::classofType(TL.getTypePtr());
493 static bool isKind(const UnqualTypeLoc &TL) {
494 return Derived::classofType(TL.getTypePtr());
498 const TypeClass *getTypePtr() const {
499 return cast<TypeClass>(Base::getTypePtr());
503 struct TypeSpecLocInfo {
504 SourceLocation NameLoc;
507 /// A reasonable base class for TypeLocs that correspond to
508 /// types that are written as a type-specifier.
509 class TypeSpecTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
515 LocalDataSize = sizeof(TypeSpecLocInfo),
516 LocalDataAlignment = alignof(TypeSpecLocInfo)
519 SourceLocation getNameLoc() const {
520 return this->getLocalData()->NameLoc;
523 void setNameLoc(SourceLocation Loc) {
524 this->getLocalData()->NameLoc = Loc;
527 SourceRange getLocalSourceRange() const {
528 return SourceRange(getNameLoc(), getNameLoc());
531 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
536 friend class TypeLoc;
538 static bool isKind(const TypeLoc &TL);
541 struct BuiltinLocInfo {
542 SourceRange BuiltinRange;
545 /// Wrapper for source info for builtin types.
546 class BuiltinTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
551 SourceLocation getBuiltinLoc() const {
552 return getLocalData()->BuiltinRange.getBegin();
555 void setBuiltinLoc(SourceLocation Loc) {
556 getLocalData()->BuiltinRange = Loc;
559 void expandBuiltinRange(SourceRange Range) {
560 SourceRange &BuiltinRange = getLocalData()->BuiltinRange;
561 if (!BuiltinRange.getBegin().isValid()) {
562 BuiltinRange = Range;
564 BuiltinRange.setBegin(std::min(Range.getBegin(), BuiltinRange.getBegin()));
565 BuiltinRange.setEnd(std::max(Range.getEnd(), BuiltinRange.getEnd()));
569 SourceLocation getNameLoc() const { return getBuiltinLoc(); }
571 WrittenBuiltinSpecs& getWrittenBuiltinSpecs() {
572 return *(static_cast<WrittenBuiltinSpecs*>(getExtraLocalData()));
574 const WrittenBuiltinSpecs& getWrittenBuiltinSpecs() const {
575 return *(static_cast<WrittenBuiltinSpecs*>(getExtraLocalData()));
578 bool needsExtraLocalData() const {
579 BuiltinType::Kind bk = getTypePtr()->getKind();
580 return (bk >= BuiltinType::UShort && bk <= BuiltinType::UInt128)
581 || (bk >= BuiltinType::Short && bk <= BuiltinType::Float128)
582 || bk == BuiltinType::UChar
583 || bk == BuiltinType::SChar;
586 unsigned getExtraLocalDataSize() const {
587 return needsExtraLocalData() ? sizeof(WrittenBuiltinSpecs) : 0;
590 unsigned getExtraLocalDataAlignment() const {
591 return needsExtraLocalData() ? alignof(WrittenBuiltinSpecs) : 1;
594 SourceRange getLocalSourceRange() const {
595 return getLocalData()->BuiltinRange;
598 TypeSpecifierSign getWrittenSignSpec() const {
599 if (needsExtraLocalData())
600 return static_cast<TypeSpecifierSign>(getWrittenBuiltinSpecs().Sign);
602 return TSS_unspecified;
605 bool hasWrittenSignSpec() const {
606 return getWrittenSignSpec() != TSS_unspecified;
609 void setWrittenSignSpec(TypeSpecifierSign written) {
610 if (needsExtraLocalData())
611 getWrittenBuiltinSpecs().Sign = written;
614 TypeSpecifierWidth getWrittenWidthSpec() const {
615 if (needsExtraLocalData())
616 return static_cast<TypeSpecifierWidth>(getWrittenBuiltinSpecs().Width);
618 return TSW_unspecified;
621 bool hasWrittenWidthSpec() const {
622 return getWrittenWidthSpec() != TSW_unspecified;
625 void setWrittenWidthSpec(TypeSpecifierWidth written) {
626 if (needsExtraLocalData())
627 getWrittenBuiltinSpecs().Width = written;
630 TypeSpecifierType getWrittenTypeSpec() const;
632 bool hasWrittenTypeSpec() const {
633 return getWrittenTypeSpec() != TST_unspecified;
636 void setWrittenTypeSpec(TypeSpecifierType written) {
637 if (needsExtraLocalData())
638 getWrittenBuiltinSpecs().Type = written;
641 bool hasModeAttr() const {
642 if (needsExtraLocalData())
643 return getWrittenBuiltinSpecs().ModeAttr;
648 void setModeAttr(bool written) {
649 if (needsExtraLocalData())
650 getWrittenBuiltinSpecs().ModeAttr = written;
653 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
655 if (needsExtraLocalData()) {
656 WrittenBuiltinSpecs &wbs = getWrittenBuiltinSpecs();
657 wbs.Sign = TSS_unspecified;
658 wbs.Width = TSW_unspecified;
659 wbs.Type = TST_unspecified;
660 wbs.ModeAttr = false;
665 /// Wrapper for source info for typedefs.
666 class TypedefTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
670 TypedefNameDecl *getTypedefNameDecl() const {
671 return getTypePtr()->getDecl();
675 /// Wrapper for source info for injected class names of class
677 class InjectedClassNameTypeLoc :
678 public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
679 InjectedClassNameTypeLoc,
680 InjectedClassNameType> {
682 CXXRecordDecl *getDecl() const {
683 return getTypePtr()->getDecl();
687 /// Wrapper for source info for unresolved typename using decls.
688 class UnresolvedUsingTypeLoc :
689 public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
690 UnresolvedUsingTypeLoc,
691 UnresolvedUsingType> {
693 UnresolvedUsingTypenameDecl *getDecl() const {
694 return getTypePtr()->getDecl();
698 /// Wrapper for source info for tag types. Note that this only
699 /// records source info for the name itself; a type written 'struct foo'
700 /// should be represented as an ElaboratedTypeLoc. We currently
701 /// only do that when C++ is enabled because of the expense of
702 /// creating an ElaboratedType node for so many type references in C.
703 class TagTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
707 TagDecl *getDecl() const { return getTypePtr()->getDecl(); }
709 /// True if the tag was defined in this type specifier.
710 bool isDefinition() const {
711 TagDecl *D = getDecl();
712 return D->isCompleteDefinition() &&
713 (D->getIdentifier() == nullptr || D->getLocation() == getNameLoc());
717 /// Wrapper for source info for record types.
718 class RecordTypeLoc : public InheritingConcreteTypeLoc<TagTypeLoc,
722 RecordDecl *getDecl() const { return getTypePtr()->getDecl(); }
725 /// Wrapper for source info for enum types.
726 class EnumTypeLoc : public InheritingConcreteTypeLoc<TagTypeLoc,
730 EnumDecl *getDecl() const { return getTypePtr()->getDecl(); }
733 /// Wrapper for template type parameters.
734 class TemplateTypeParmTypeLoc :
735 public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
736 TemplateTypeParmTypeLoc,
737 TemplateTypeParmType> {
739 TemplateTypeParmDecl *getDecl() const { return getTypePtr()->getDecl(); }
742 struct ObjCTypeParamTypeLocInfo {
743 SourceLocation NameLoc;
746 /// ProtocolLAngleLoc, ProtocolRAngleLoc, and the source locations for
747 /// protocol qualifiers are stored after Info.
748 class ObjCTypeParamTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
749 ObjCTypeParamTypeLoc,
751 ObjCTypeParamTypeLocInfo> {
752 // SourceLocations are stored after Info, one for each protocol qualifier.
753 SourceLocation *getProtocolLocArray() const {
754 return (SourceLocation*)this->getExtraLocalData() + 2;
758 ObjCTypeParamDecl *getDecl() const { return getTypePtr()->getDecl(); }
760 SourceLocation getNameLoc() const {
761 return this->getLocalData()->NameLoc;
764 void setNameLoc(SourceLocation Loc) {
765 this->getLocalData()->NameLoc = Loc;
768 SourceLocation getProtocolLAngleLoc() const {
769 return getNumProtocols() ?
770 *((SourceLocation*)this->getExtraLocalData()) :
774 void setProtocolLAngleLoc(SourceLocation Loc) {
775 *((SourceLocation*)this->getExtraLocalData()) = Loc;
778 SourceLocation getProtocolRAngleLoc() const {
779 return getNumProtocols() ?
780 *((SourceLocation*)this->getExtraLocalData() + 1) :
784 void setProtocolRAngleLoc(SourceLocation Loc) {
785 *((SourceLocation*)this->getExtraLocalData() + 1) = Loc;
788 unsigned getNumProtocols() const {
789 return this->getTypePtr()->getNumProtocols();
792 SourceLocation getProtocolLoc(unsigned i) const {
793 assert(i < getNumProtocols() && "Index is out of bounds!");
794 return getProtocolLocArray()[i];
797 void setProtocolLoc(unsigned i, SourceLocation Loc) {
798 assert(i < getNumProtocols() && "Index is out of bounds!");
799 getProtocolLocArray()[i] = Loc;
802 ObjCProtocolDecl *getProtocol(unsigned i) const {
803 assert(i < getNumProtocols() && "Index is out of bounds!");
804 return *(this->getTypePtr()->qual_begin() + i);
807 ArrayRef<SourceLocation> getProtocolLocs() const {
808 return llvm::makeArrayRef(getProtocolLocArray(), getNumProtocols());
811 void initializeLocal(ASTContext &Context, SourceLocation Loc);
813 unsigned getExtraLocalDataSize() const {
814 if (!this->getNumProtocols()) return 0;
815 // When there are protocol qualifers, we have LAngleLoc and RAngleLoc
817 return (this->getNumProtocols() + 2) * sizeof(SourceLocation) ;
820 unsigned getExtraLocalDataAlignment() const {
821 return alignof(SourceLocation);
824 SourceRange getLocalSourceRange() const {
825 SourceLocation start = getNameLoc();
826 SourceLocation end = getProtocolRAngleLoc();
827 if (end.isInvalid()) return SourceRange(start, start);
828 return SourceRange(start, end);
832 /// Wrapper for substituted template type parameters.
833 class SubstTemplateTypeParmTypeLoc :
834 public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
835 SubstTemplateTypeParmTypeLoc,
836 SubstTemplateTypeParmType> {
839 /// Wrapper for substituted template type parameters.
840 class SubstTemplateTypeParmPackTypeLoc :
841 public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
842 SubstTemplateTypeParmPackTypeLoc,
843 SubstTemplateTypeParmPackType> {
846 struct AttributedLocInfo {
847 const Attr *TypeAttr;
850 /// Type source information for an attributed type.
851 class AttributedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
856 attr::Kind getAttrKind() const {
857 return getTypePtr()->getAttrKind();
860 bool isQualifier() const {
861 return getTypePtr()->isQualifier();
864 /// The modified type, which is generally canonically different from
865 /// the attribute type.
866 /// int main(int, char**) __attribute__((noreturn))
867 /// ~~~ ~~~~~~~~~~~~~
868 TypeLoc getModifiedLoc() const {
869 return getInnerTypeLoc();
872 /// The type attribute.
873 const Attr *getAttr() const {
874 return getLocalData()->TypeAttr;
876 void setAttr(const Attr *A) {
877 getLocalData()->TypeAttr = A;
880 template<typename T> const T *getAttrAs() {
881 return dyn_cast_or_null<T>(getAttr());
884 SourceRange getLocalSourceRange() const {
885 // Note that this does *not* include the range of the attribute
887 // __attribute__((foo(bar)))
888 // ^~~~~~~~~~~~~~~ ~~
892 // That enclosure doesn't necessarily belong to a single attribute
894 return getAttr() ? getAttr()->getRange() : SourceRange();
897 void initializeLocal(ASTContext &Context, SourceLocation loc) {
901 QualType getInnerType() const {
902 return getTypePtr()->getModifiedType();
906 struct ObjCObjectTypeLocInfo {
907 SourceLocation TypeArgsLAngleLoc;
908 SourceLocation TypeArgsRAngleLoc;
909 SourceLocation ProtocolLAngleLoc;
910 SourceLocation ProtocolRAngleLoc;
911 bool HasBaseTypeAsWritten;
914 // A helper class for defining ObjC TypeLocs that can qualified with
917 // TypeClass basically has to be either ObjCInterfaceType or
918 // ObjCObjectPointerType.
919 class ObjCObjectTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
922 ObjCObjectTypeLocInfo> {
923 // TypeSourceInfo*'s are stored after Info, one for each type argument.
924 TypeSourceInfo **getTypeArgLocArray() const {
925 return (TypeSourceInfo**)this->getExtraLocalData();
928 // SourceLocations are stored after the type argument information, one for
930 SourceLocation *getProtocolLocArray() const {
931 return (SourceLocation*)(getTypeArgLocArray() + getNumTypeArgs());
935 SourceLocation getTypeArgsLAngleLoc() const {
936 return this->getLocalData()->TypeArgsLAngleLoc;
939 void setTypeArgsLAngleLoc(SourceLocation Loc) {
940 this->getLocalData()->TypeArgsLAngleLoc = Loc;
943 SourceLocation getTypeArgsRAngleLoc() const {
944 return this->getLocalData()->TypeArgsRAngleLoc;
947 void setTypeArgsRAngleLoc(SourceLocation Loc) {
948 this->getLocalData()->TypeArgsRAngleLoc = Loc;
951 unsigned getNumTypeArgs() const {
952 return this->getTypePtr()->getTypeArgsAsWritten().size();
955 TypeSourceInfo *getTypeArgTInfo(unsigned i) const {
956 assert(i < getNumTypeArgs() && "Index is out of bounds!");
957 return getTypeArgLocArray()[i];
960 void setTypeArgTInfo(unsigned i, TypeSourceInfo *TInfo) {
961 assert(i < getNumTypeArgs() && "Index is out of bounds!");
962 getTypeArgLocArray()[i] = TInfo;
965 SourceLocation getProtocolLAngleLoc() const {
966 return this->getLocalData()->ProtocolLAngleLoc;
969 void setProtocolLAngleLoc(SourceLocation Loc) {
970 this->getLocalData()->ProtocolLAngleLoc = Loc;
973 SourceLocation getProtocolRAngleLoc() const {
974 return this->getLocalData()->ProtocolRAngleLoc;
977 void setProtocolRAngleLoc(SourceLocation Loc) {
978 this->getLocalData()->ProtocolRAngleLoc = Loc;
981 unsigned getNumProtocols() const {
982 return this->getTypePtr()->getNumProtocols();
985 SourceLocation getProtocolLoc(unsigned i) const {
986 assert(i < getNumProtocols() && "Index is out of bounds!");
987 return getProtocolLocArray()[i];
990 void setProtocolLoc(unsigned i, SourceLocation Loc) {
991 assert(i < getNumProtocols() && "Index is out of bounds!");
992 getProtocolLocArray()[i] = Loc;
995 ObjCProtocolDecl *getProtocol(unsigned i) const {
996 assert(i < getNumProtocols() && "Index is out of bounds!");
997 return *(this->getTypePtr()->qual_begin() + i);
1001 ArrayRef<SourceLocation> getProtocolLocs() const {
1002 return llvm::makeArrayRef(getProtocolLocArray(), getNumProtocols());
1005 bool hasBaseTypeAsWritten() const {
1006 return getLocalData()->HasBaseTypeAsWritten;
1009 void setHasBaseTypeAsWritten(bool HasBaseType) {
1010 getLocalData()->HasBaseTypeAsWritten = HasBaseType;
1013 TypeLoc getBaseLoc() const {
1014 return getInnerTypeLoc();
1017 SourceRange getLocalSourceRange() const {
1018 SourceLocation start = getTypeArgsLAngleLoc();
1019 if (start.isInvalid())
1020 start = getProtocolLAngleLoc();
1021 SourceLocation end = getProtocolRAngleLoc();
1022 if (end.isInvalid())
1023 end = getTypeArgsRAngleLoc();
1024 return SourceRange(start, end);
1027 void initializeLocal(ASTContext &Context, SourceLocation Loc);
1029 unsigned getExtraLocalDataSize() const {
1030 return this->getNumTypeArgs() * sizeof(TypeSourceInfo *)
1031 + this->getNumProtocols() * sizeof(SourceLocation);
1034 unsigned getExtraLocalDataAlignment() const {
1035 static_assert(alignof(ObjCObjectTypeLoc) >= alignof(TypeSourceInfo *),
1036 "not enough alignment for tail-allocated data");
1037 return alignof(TypeSourceInfo *);
1040 QualType getInnerType() const {
1041 return getTypePtr()->getBaseType();
1045 struct ObjCInterfaceLocInfo {
1046 SourceLocation NameLoc;
1047 SourceLocation NameEndLoc;
1050 /// Wrapper for source info for ObjC interfaces.
1051 class ObjCInterfaceTypeLoc : public ConcreteTypeLoc<ObjCObjectTypeLoc,
1052 ObjCInterfaceTypeLoc,
1054 ObjCInterfaceLocInfo> {
1056 ObjCInterfaceDecl *getIFaceDecl() const {
1057 return getTypePtr()->getDecl();
1060 SourceLocation getNameLoc() const {
1061 return getLocalData()->NameLoc;
1064 void setNameLoc(SourceLocation Loc) {
1065 getLocalData()->NameLoc = Loc;
1068 SourceRange getLocalSourceRange() const {
1069 return SourceRange(getNameLoc(), getNameEndLoc());
1072 SourceLocation getNameEndLoc() const {
1073 return getLocalData()->NameEndLoc;
1076 void setNameEndLoc(SourceLocation Loc) {
1077 getLocalData()->NameEndLoc = Loc;
1080 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1086 struct MacroQualifiedLocInfo {
1087 SourceLocation ExpansionLoc;
1090 class MacroQualifiedTypeLoc
1091 : public ConcreteTypeLoc<UnqualTypeLoc, MacroQualifiedTypeLoc,
1092 MacroQualifiedType, MacroQualifiedLocInfo> {
1094 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1095 setExpansionLoc(Loc);
1098 TypeLoc getInnerLoc() const { return getInnerTypeLoc(); }
1100 const IdentifierInfo *getMacroIdentifier() const {
1101 return getTypePtr()->getMacroIdentifier();
1104 SourceLocation getExpansionLoc() const {
1105 return this->getLocalData()->ExpansionLoc;
1108 void setExpansionLoc(SourceLocation Loc) {
1109 this->getLocalData()->ExpansionLoc = Loc;
1112 QualType getInnerType() const { return getTypePtr()->getUnderlyingType(); }
1114 SourceRange getLocalSourceRange() const {
1115 return getInnerLoc().getLocalSourceRange();
1119 struct ParenLocInfo {
1120 SourceLocation LParenLoc;
1121 SourceLocation RParenLoc;
1125 : public ConcreteTypeLoc<UnqualTypeLoc, ParenTypeLoc, ParenType,
1128 SourceLocation getLParenLoc() const {
1129 return this->getLocalData()->LParenLoc;
1132 SourceLocation getRParenLoc() const {
1133 return this->getLocalData()->RParenLoc;
1136 void setLParenLoc(SourceLocation Loc) {
1137 this->getLocalData()->LParenLoc = Loc;
1140 void setRParenLoc(SourceLocation Loc) {
1141 this->getLocalData()->RParenLoc = Loc;
1144 SourceRange getLocalSourceRange() const {
1145 return SourceRange(getLParenLoc(), getRParenLoc());
1148 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1153 TypeLoc getInnerLoc() const {
1154 return getInnerTypeLoc();
1157 QualType getInnerType() const {
1158 return this->getTypePtr()->getInnerType();
1162 inline TypeLoc TypeLoc::IgnoreParens() const {
1163 if (ParenTypeLoc::isKind(*this))
1164 return IgnoreParensImpl(*this);
1168 struct AdjustedLocInfo {}; // Nothing.
1170 class AdjustedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, AdjustedTypeLoc,
1171 AdjustedType, AdjustedLocInfo> {
1173 TypeLoc getOriginalLoc() const {
1174 return getInnerTypeLoc();
1177 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1181 QualType getInnerType() const {
1182 // The inner type is the undecayed type, since that's what we have source
1183 // location information for.
1184 return getTypePtr()->getOriginalType();
1187 SourceRange getLocalSourceRange() const { return {}; }
1189 unsigned getLocalDataSize() const {
1190 // sizeof(AdjustedLocInfo) is 1, but we don't need its address to be unique
1191 // anyway. TypeLocBuilder can't handle data sizes of 1.
1192 return 0; // No data.
1196 /// Wrapper for source info for pointers decayed from arrays and
1198 class DecayedTypeLoc : public InheritingConcreteTypeLoc<
1199 AdjustedTypeLoc, DecayedTypeLoc, DecayedType> {
1202 struct PointerLikeLocInfo {
1203 SourceLocation StarLoc;
1206 /// A base class for
1207 template <class Derived, class TypeClass, class LocalData = PointerLikeLocInfo>
1208 class PointerLikeTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, Derived,
1209 TypeClass, LocalData> {
1211 SourceLocation getSigilLoc() const {
1212 return this->getLocalData()->StarLoc;
1215 void setSigilLoc(SourceLocation Loc) {
1216 this->getLocalData()->StarLoc = Loc;
1219 TypeLoc getPointeeLoc() const {
1220 return this->getInnerTypeLoc();
1223 SourceRange getLocalSourceRange() const {
1224 return SourceRange(getSigilLoc(), getSigilLoc());
1227 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1231 QualType getInnerType() const {
1232 return this->getTypePtr()->getPointeeType();
1236 /// Wrapper for source info for pointers.
1237 class PointerTypeLoc : public PointerLikeTypeLoc<PointerTypeLoc,
1240 SourceLocation getStarLoc() const {
1241 return getSigilLoc();
1244 void setStarLoc(SourceLocation Loc) {
1249 /// Wrapper for source info for block pointers.
1250 class BlockPointerTypeLoc : public PointerLikeTypeLoc<BlockPointerTypeLoc,
1253 SourceLocation getCaretLoc() const {
1254 return getSigilLoc();
1257 void setCaretLoc(SourceLocation Loc) {
1262 struct MemberPointerLocInfo : public PointerLikeLocInfo {
1263 TypeSourceInfo *ClassTInfo;
1266 /// Wrapper for source info for member pointers.
1267 class MemberPointerTypeLoc : public PointerLikeTypeLoc<MemberPointerTypeLoc,
1269 MemberPointerLocInfo> {
1271 SourceLocation getStarLoc() const {
1272 return getSigilLoc();
1275 void setStarLoc(SourceLocation Loc) {
1279 const Type *getClass() const {
1280 return getTypePtr()->getClass();
1283 TypeSourceInfo *getClassTInfo() const {
1284 return getLocalData()->ClassTInfo;
1287 void setClassTInfo(TypeSourceInfo* TI) {
1288 getLocalData()->ClassTInfo = TI;
1291 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1293 setClassTInfo(nullptr);
1296 SourceRange getLocalSourceRange() const {
1297 if (TypeSourceInfo *TI = getClassTInfo())
1298 return SourceRange(TI->getTypeLoc().getBeginLoc(), getStarLoc());
1300 return SourceRange(getStarLoc());
1304 /// Wraps an ObjCPointerType with source location information.
1305 class ObjCObjectPointerTypeLoc :
1306 public PointerLikeTypeLoc<ObjCObjectPointerTypeLoc,
1307 ObjCObjectPointerType> {
1309 SourceLocation getStarLoc() const {
1310 return getSigilLoc();
1313 void setStarLoc(SourceLocation Loc) {
1318 class ReferenceTypeLoc : public PointerLikeTypeLoc<ReferenceTypeLoc,
1321 QualType getInnerType() const {
1322 return getTypePtr()->getPointeeTypeAsWritten();
1326 class LValueReferenceTypeLoc :
1327 public InheritingConcreteTypeLoc<ReferenceTypeLoc,
1328 LValueReferenceTypeLoc,
1329 LValueReferenceType> {
1331 SourceLocation getAmpLoc() const {
1332 return getSigilLoc();
1335 void setAmpLoc(SourceLocation Loc) {
1340 class RValueReferenceTypeLoc :
1341 public InheritingConcreteTypeLoc<ReferenceTypeLoc,
1342 RValueReferenceTypeLoc,
1343 RValueReferenceType> {
1345 SourceLocation getAmpAmpLoc() const {
1346 return getSigilLoc();
1349 void setAmpAmpLoc(SourceLocation Loc) {
1354 struct FunctionLocInfo {
1355 SourceLocation LocalRangeBegin;
1356 SourceLocation LParenLoc;
1357 SourceLocation RParenLoc;
1358 SourceLocation LocalRangeEnd;
1361 /// Wrapper for source info for functions.
1362 class FunctionTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
1366 bool hasExceptionSpec() const {
1367 if (auto *FPT = dyn_cast<FunctionProtoType>(getTypePtr())) {
1368 return FPT->hasExceptionSpec();
1373 SourceRange *getExceptionSpecRangePtr() const {
1374 assert(hasExceptionSpec() && "No exception spec range");
1375 // After the Info comes the ParmVarDecl array, and after that comes the
1376 // exception specification information.
1377 return (SourceRange *)(getParmArray() + getNumParams());
1381 SourceLocation getLocalRangeBegin() const {
1382 return getLocalData()->LocalRangeBegin;
1385 void setLocalRangeBegin(SourceLocation L) {
1386 getLocalData()->LocalRangeBegin = L;
1389 SourceLocation getLocalRangeEnd() const {
1390 return getLocalData()->LocalRangeEnd;
1393 void setLocalRangeEnd(SourceLocation L) {
1394 getLocalData()->LocalRangeEnd = L;
1397 SourceLocation getLParenLoc() const {
1398 return this->getLocalData()->LParenLoc;
1401 void setLParenLoc(SourceLocation Loc) {
1402 this->getLocalData()->LParenLoc = Loc;
1405 SourceLocation getRParenLoc() const {
1406 return this->getLocalData()->RParenLoc;
1409 void setRParenLoc(SourceLocation Loc) {
1410 this->getLocalData()->RParenLoc = Loc;
1413 SourceRange getParensRange() const {
1414 return SourceRange(getLParenLoc(), getRParenLoc());
1417 SourceRange getExceptionSpecRange() const {
1418 if (hasExceptionSpec())
1419 return *getExceptionSpecRangePtr();
1423 void setExceptionSpecRange(SourceRange R) {
1424 if (hasExceptionSpec())
1425 *getExceptionSpecRangePtr() = R;
1428 ArrayRef<ParmVarDecl *> getParams() const {
1429 return llvm::makeArrayRef(getParmArray(), getNumParams());
1432 // ParmVarDecls* are stored after Info, one for each parameter.
1433 ParmVarDecl **getParmArray() const {
1434 return (ParmVarDecl**) getExtraLocalData();
1437 unsigned getNumParams() const {
1438 if (isa<FunctionNoProtoType>(getTypePtr()))
1440 return cast<FunctionProtoType>(getTypePtr())->getNumParams();
1443 ParmVarDecl *getParam(unsigned i) const { return getParmArray()[i]; }
1444 void setParam(unsigned i, ParmVarDecl *VD) { getParmArray()[i] = VD; }
1446 TypeLoc getReturnLoc() const {
1447 return getInnerTypeLoc();
1450 SourceRange getLocalSourceRange() const {
1451 return SourceRange(getLocalRangeBegin(), getLocalRangeEnd());
1454 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1455 setLocalRangeBegin(Loc);
1458 setLocalRangeEnd(Loc);
1459 for (unsigned i = 0, e = getNumParams(); i != e; ++i)
1460 setParam(i, nullptr);
1461 if (hasExceptionSpec())
1462 setExceptionSpecRange(Loc);
1465 /// Returns the size of the type source info data block that is
1466 /// specific to this type.
1467 unsigned getExtraLocalDataSize() const {
1468 unsigned ExceptSpecSize = hasExceptionSpec() ? sizeof(SourceRange) : 0;
1469 return (getNumParams() * sizeof(ParmVarDecl *)) + ExceptSpecSize;
1472 unsigned getExtraLocalDataAlignment() const { return alignof(ParmVarDecl *); }
1474 QualType getInnerType() const { return getTypePtr()->getReturnType(); }
1477 class FunctionProtoTypeLoc :
1478 public InheritingConcreteTypeLoc<FunctionTypeLoc,
1479 FunctionProtoTypeLoc,
1480 FunctionProtoType> {
1483 class FunctionNoProtoTypeLoc :
1484 public InheritingConcreteTypeLoc<FunctionTypeLoc,
1485 FunctionNoProtoTypeLoc,
1486 FunctionNoProtoType> {
1489 struct ArrayLocInfo {
1490 SourceLocation LBracketLoc, RBracketLoc;
1494 /// Wrapper for source info for arrays.
1495 class ArrayTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
1500 SourceLocation getLBracketLoc() const {
1501 return getLocalData()->LBracketLoc;
1504 void setLBracketLoc(SourceLocation Loc) {
1505 getLocalData()->LBracketLoc = Loc;
1508 SourceLocation getRBracketLoc() const {
1509 return getLocalData()->RBracketLoc;
1512 void setRBracketLoc(SourceLocation Loc) {
1513 getLocalData()->RBracketLoc = Loc;
1516 SourceRange getBracketsRange() const {
1517 return SourceRange(getLBracketLoc(), getRBracketLoc());
1520 Expr *getSizeExpr() const {
1521 return getLocalData()->Size;
1524 void setSizeExpr(Expr *Size) {
1525 getLocalData()->Size = Size;
1528 TypeLoc getElementLoc() const {
1529 return getInnerTypeLoc();
1532 SourceRange getLocalSourceRange() const {
1533 return SourceRange(getLBracketLoc(), getRBracketLoc());
1536 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1537 setLBracketLoc(Loc);
1538 setRBracketLoc(Loc);
1539 setSizeExpr(nullptr);
1542 QualType getInnerType() const { return getTypePtr()->getElementType(); }
1545 class ConstantArrayTypeLoc :
1546 public InheritingConcreteTypeLoc<ArrayTypeLoc,
1547 ConstantArrayTypeLoc,
1548 ConstantArrayType> {
1551 class IncompleteArrayTypeLoc :
1552 public InheritingConcreteTypeLoc<ArrayTypeLoc,
1553 IncompleteArrayTypeLoc,
1554 IncompleteArrayType> {
1557 class DependentSizedArrayTypeLoc :
1558 public InheritingConcreteTypeLoc<ArrayTypeLoc,
1559 DependentSizedArrayTypeLoc,
1560 DependentSizedArrayType> {
1562 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1563 ArrayTypeLoc::initializeLocal(Context, Loc);
1564 setSizeExpr(getTypePtr()->getSizeExpr());
1568 class VariableArrayTypeLoc :
1569 public InheritingConcreteTypeLoc<ArrayTypeLoc,
1570 VariableArrayTypeLoc,
1571 VariableArrayType> {
1574 // Location information for a TemplateName. Rudimentary for now.
1575 struct TemplateNameLocInfo {
1576 SourceLocation NameLoc;
1579 struct TemplateSpecializationLocInfo : TemplateNameLocInfo {
1580 SourceLocation TemplateKWLoc;
1581 SourceLocation LAngleLoc;
1582 SourceLocation RAngleLoc;
1585 class TemplateSpecializationTypeLoc :
1586 public ConcreteTypeLoc<UnqualTypeLoc,
1587 TemplateSpecializationTypeLoc,
1588 TemplateSpecializationType,
1589 TemplateSpecializationLocInfo> {
1591 SourceLocation getTemplateKeywordLoc() const {
1592 return getLocalData()->TemplateKWLoc;
1595 void setTemplateKeywordLoc(SourceLocation Loc) {
1596 getLocalData()->TemplateKWLoc = Loc;
1599 SourceLocation getLAngleLoc() const {
1600 return getLocalData()->LAngleLoc;
1603 void setLAngleLoc(SourceLocation Loc) {
1604 getLocalData()->LAngleLoc = Loc;
1607 SourceLocation getRAngleLoc() const {
1608 return getLocalData()->RAngleLoc;
1611 void setRAngleLoc(SourceLocation Loc) {
1612 getLocalData()->RAngleLoc = Loc;
1615 unsigned getNumArgs() const {
1616 return getTypePtr()->getNumArgs();
1619 void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) {
1620 getArgInfos()[i] = AI;
1623 TemplateArgumentLocInfo getArgLocInfo(unsigned i) const {
1624 return getArgInfos()[i];
1627 TemplateArgumentLoc getArgLoc(unsigned i) const {
1628 return TemplateArgumentLoc(getTypePtr()->getArg(i), getArgLocInfo(i));
1631 SourceLocation getTemplateNameLoc() const {
1632 return getLocalData()->NameLoc;
1635 void setTemplateNameLoc(SourceLocation Loc) {
1636 getLocalData()->NameLoc = Loc;
1639 /// - Copy the location information from the given info.
1640 void copy(TemplateSpecializationTypeLoc Loc) {
1641 unsigned size = getFullDataSize();
1642 assert(size == Loc.getFullDataSize());
1644 // We're potentially copying Expr references here. We don't
1645 // bother retaining them because TypeSourceInfos live forever, so
1646 // as long as the Expr was retained when originally written into
1647 // the TypeLoc, we're okay.
1648 memcpy(Data, Loc.Data, size);
1651 SourceRange getLocalSourceRange() const {
1652 if (getTemplateKeywordLoc().isValid())
1653 return SourceRange(getTemplateKeywordLoc(), getRAngleLoc());
1655 return SourceRange(getTemplateNameLoc(), getRAngleLoc());
1658 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1659 setTemplateKeywordLoc(Loc);
1660 setTemplateNameLoc(Loc);
1663 initializeArgLocs(Context, getNumArgs(), getTypePtr()->getArgs(),
1664 getArgInfos(), Loc);
1667 static void initializeArgLocs(ASTContext &Context, unsigned NumArgs,
1668 const TemplateArgument *Args,
1669 TemplateArgumentLocInfo *ArgInfos,
1670 SourceLocation Loc);
1672 unsigned getExtraLocalDataSize() const {
1673 return getNumArgs() * sizeof(TemplateArgumentLocInfo);
1676 unsigned getExtraLocalDataAlignment() const {
1677 return alignof(TemplateArgumentLocInfo);
1681 TemplateArgumentLocInfo *getArgInfos() const {
1682 return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData());
1686 struct DependentAddressSpaceLocInfo {
1688 SourceRange OperandParens;
1689 SourceLocation AttrLoc;
1692 class DependentAddressSpaceTypeLoc
1693 : public ConcreteTypeLoc<UnqualTypeLoc,
1694 DependentAddressSpaceTypeLoc,
1695 DependentAddressSpaceType,
1696 DependentAddressSpaceLocInfo> {
1698 /// The location of the attribute name, i.e.
1699 /// int * __attribute__((address_space(11)))
1701 SourceLocation getAttrNameLoc() const {
1702 return getLocalData()->AttrLoc;
1704 void setAttrNameLoc(SourceLocation loc) {
1705 getLocalData()->AttrLoc = loc;
1708 /// The attribute's expression operand, if it has one.
1709 /// int * __attribute__((address_space(11)))
1711 Expr *getAttrExprOperand() const {
1712 return getLocalData()->ExprOperand;
1714 void setAttrExprOperand(Expr *e) {
1715 getLocalData()->ExprOperand = e;
1718 /// The location of the parentheses around the operand, if there is
1720 /// int * __attribute__((address_space(11)))
1722 SourceRange getAttrOperandParensRange() const {
1723 return getLocalData()->OperandParens;
1725 void setAttrOperandParensRange(SourceRange range) {
1726 getLocalData()->OperandParens = range;
1729 SourceRange getLocalSourceRange() const {
1730 SourceRange range(getAttrNameLoc());
1731 range.setEnd(getAttrOperandParensRange().getEnd());
1735 /// Returns the type before the address space attribute application
1737 /// int * __attribute__((address_space(11))) *
1739 QualType getInnerType() const {
1740 return this->getTypePtr()->getPointeeType();
1743 TypeLoc getPointeeTypeLoc() const {
1744 return this->getInnerTypeLoc();
1747 void initializeLocal(ASTContext &Context, SourceLocation loc) {
1748 setAttrNameLoc(loc);
1749 setAttrOperandParensRange(SourceRange(loc));
1750 setAttrExprOperand(getTypePtr()->getAddrSpaceExpr());
1754 //===----------------------------------------------------------------------===//
1756 // All of these need proper implementations.
1758 //===----------------------------------------------------------------------===//
1760 // FIXME: size expression and attribute locations (or keyword if we
1761 // ever fully support altivec syntax).
1762 class VectorTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
1767 // FIXME: size expression and attribute locations (or keyword if we
1768 // ever fully support altivec syntax).
1769 class DependentVectorTypeLoc
1770 : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
1771 DependentVectorTypeLoc,
1772 DependentVectorType> {};
1774 // FIXME: size expression and attribute locations.
1775 class ExtVectorTypeLoc : public InheritingConcreteTypeLoc<VectorTypeLoc,
1780 // FIXME: attribute locations.
1781 // For some reason, this isn't a subtype of VectorType.
1782 class DependentSizedExtVectorTypeLoc :
1783 public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
1784 DependentSizedExtVectorTypeLoc,
1785 DependentSizedExtVectorType> {
1788 // FIXME: location of the '_Complex' keyword.
1789 class ComplexTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
1794 struct TypeofLocInfo {
1795 SourceLocation TypeofLoc;
1796 SourceLocation LParenLoc;
1797 SourceLocation RParenLoc;
1800 struct TypeOfExprTypeLocInfo : public TypeofLocInfo {
1803 struct TypeOfTypeLocInfo : public TypeofLocInfo {
1804 TypeSourceInfo* UnderlyingTInfo;
1807 template <class Derived, class TypeClass, class LocalData = TypeofLocInfo>
1808 class TypeofLikeTypeLoc
1809 : public ConcreteTypeLoc<UnqualTypeLoc, Derived, TypeClass, LocalData> {
1811 SourceLocation getTypeofLoc() const {
1812 return this->getLocalData()->TypeofLoc;
1815 void setTypeofLoc(SourceLocation Loc) {
1816 this->getLocalData()->TypeofLoc = Loc;
1819 SourceLocation getLParenLoc() const {
1820 return this->getLocalData()->LParenLoc;
1823 void setLParenLoc(SourceLocation Loc) {
1824 this->getLocalData()->LParenLoc = Loc;
1827 SourceLocation getRParenLoc() const {
1828 return this->getLocalData()->RParenLoc;
1831 void setRParenLoc(SourceLocation Loc) {
1832 this->getLocalData()->RParenLoc = Loc;
1835 SourceRange getParensRange() const {
1836 return SourceRange(getLParenLoc(), getRParenLoc());
1839 void setParensRange(SourceRange range) {
1840 setLParenLoc(range.getBegin());
1841 setRParenLoc(range.getEnd());
1844 SourceRange getLocalSourceRange() const {
1845 return SourceRange(getTypeofLoc(), getRParenLoc());
1848 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1855 class TypeOfExprTypeLoc : public TypeofLikeTypeLoc<TypeOfExprTypeLoc,
1857 TypeOfExprTypeLocInfo> {
1859 Expr* getUnderlyingExpr() const {
1860 return getTypePtr()->getUnderlyingExpr();
1863 // Reimplemented to account for GNU/C++ extension
1864 // typeof unary-expression
1865 // where there are no parentheses.
1866 SourceRange getLocalSourceRange() const;
1870 : public TypeofLikeTypeLoc<TypeOfTypeLoc, TypeOfType, TypeOfTypeLocInfo> {
1872 QualType getUnderlyingType() const {
1873 return this->getTypePtr()->getUnderlyingType();
1876 TypeSourceInfo* getUnderlyingTInfo() const {
1877 return this->getLocalData()->UnderlyingTInfo;
1880 void setUnderlyingTInfo(TypeSourceInfo* TI) const {
1881 this->getLocalData()->UnderlyingTInfo = TI;
1884 void initializeLocal(ASTContext &Context, SourceLocation Loc);
1887 // FIXME: location of the 'decltype' and parens.
1888 class DecltypeTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
1892 Expr *getUnderlyingExpr() const { return getTypePtr()->getUnderlyingExpr(); }
1895 struct UnaryTransformTypeLocInfo {
1896 // FIXME: While there's only one unary transform right now, future ones may
1897 // need different representations
1898 SourceLocation KWLoc, LParenLoc, RParenLoc;
1899 TypeSourceInfo *UnderlyingTInfo;
1902 class UnaryTransformTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
1903 UnaryTransformTypeLoc,
1905 UnaryTransformTypeLocInfo> {
1907 SourceLocation getKWLoc() const { return getLocalData()->KWLoc; }
1908 void setKWLoc(SourceLocation Loc) { getLocalData()->KWLoc = Loc; }
1910 SourceLocation getLParenLoc() const { return getLocalData()->LParenLoc; }
1911 void setLParenLoc(SourceLocation Loc) { getLocalData()->LParenLoc = Loc; }
1913 SourceLocation getRParenLoc() const { return getLocalData()->RParenLoc; }
1914 void setRParenLoc(SourceLocation Loc) { getLocalData()->RParenLoc = Loc; }
1916 TypeSourceInfo* getUnderlyingTInfo() const {
1917 return getLocalData()->UnderlyingTInfo;
1920 void setUnderlyingTInfo(TypeSourceInfo *TInfo) {
1921 getLocalData()->UnderlyingTInfo = TInfo;
1924 SourceRange getLocalSourceRange() const {
1925 return SourceRange(getKWLoc(), getRParenLoc());
1928 SourceRange getParensRange() const {
1929 return SourceRange(getLParenLoc(), getRParenLoc());
1932 void setParensRange(SourceRange Range) {
1933 setLParenLoc(Range.getBegin());
1934 setRParenLoc(Range.getEnd());
1937 void initializeLocal(ASTContext &Context, SourceLocation Loc);
1940 class DeducedTypeLoc
1941 : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, DeducedTypeLoc,
1945 : public InheritingConcreteTypeLoc<DeducedTypeLoc, AutoTypeLoc, AutoType> {
1948 class DeducedTemplateSpecializationTypeLoc
1949 : public InheritingConcreteTypeLoc<DeducedTypeLoc,
1950 DeducedTemplateSpecializationTypeLoc,
1951 DeducedTemplateSpecializationType> {
1953 SourceLocation getTemplateNameLoc() const {
1954 return getNameLoc();
1957 void setTemplateNameLoc(SourceLocation Loc) {
1962 struct ElaboratedLocInfo {
1963 SourceLocation ElaboratedKWLoc;
1965 /// Data associated with the nested-name-specifier location.
1966 void *QualifierData;
1969 class ElaboratedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
1972 ElaboratedLocInfo> {
1974 SourceLocation getElaboratedKeywordLoc() const {
1975 return this->getLocalData()->ElaboratedKWLoc;
1978 void setElaboratedKeywordLoc(SourceLocation Loc) {
1979 this->getLocalData()->ElaboratedKWLoc = Loc;
1982 NestedNameSpecifierLoc getQualifierLoc() const {
1983 return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
1984 getLocalData()->QualifierData);
1987 void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
1988 assert(QualifierLoc.getNestedNameSpecifier()
1989 == getTypePtr()->getQualifier() &&
1990 "Inconsistent nested-name-specifier pointer");
1991 getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
1994 SourceRange getLocalSourceRange() const {
1995 if (getElaboratedKeywordLoc().isValid())
1996 if (getQualifierLoc())
1997 return SourceRange(getElaboratedKeywordLoc(),
1998 getQualifierLoc().getEndLoc());
2000 return SourceRange(getElaboratedKeywordLoc());
2002 return getQualifierLoc().getSourceRange();
2005 void initializeLocal(ASTContext &Context, SourceLocation Loc);
2007 TypeLoc getNamedTypeLoc() const {
2008 return getInnerTypeLoc();
2011 QualType getInnerType() const {
2012 return getTypePtr()->getNamedType();
2015 void copy(ElaboratedTypeLoc Loc) {
2016 unsigned size = getFullDataSize();
2017 assert(size == Loc.getFullDataSize());
2018 memcpy(Data, Loc.Data, size);
2022 // This is exactly the structure of an ElaboratedTypeLoc whose inner
2023 // type is some sort of TypeDeclTypeLoc.
2024 struct DependentNameLocInfo : ElaboratedLocInfo {
2025 SourceLocation NameLoc;
2028 class DependentNameTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
2029 DependentNameTypeLoc,
2031 DependentNameLocInfo> {
2033 SourceLocation getElaboratedKeywordLoc() const {
2034 return this->getLocalData()->ElaboratedKWLoc;
2037 void setElaboratedKeywordLoc(SourceLocation Loc) {
2038 this->getLocalData()->ElaboratedKWLoc = Loc;
2041 NestedNameSpecifierLoc getQualifierLoc() const {
2042 return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
2043 getLocalData()->QualifierData);
2046 void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
2047 assert(QualifierLoc.getNestedNameSpecifier()
2048 == getTypePtr()->getQualifier() &&
2049 "Inconsistent nested-name-specifier pointer");
2050 getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
2053 SourceLocation getNameLoc() const {
2054 return this->getLocalData()->NameLoc;
2057 void setNameLoc(SourceLocation Loc) {
2058 this->getLocalData()->NameLoc = Loc;
2061 SourceRange getLocalSourceRange() const {
2062 if (getElaboratedKeywordLoc().isValid())
2063 return SourceRange(getElaboratedKeywordLoc(), getNameLoc());
2065 return SourceRange(getQualifierLoc().getBeginLoc(), getNameLoc());
2068 void copy(DependentNameTypeLoc Loc) {
2069 unsigned size = getFullDataSize();
2070 assert(size == Loc.getFullDataSize());
2071 memcpy(Data, Loc.Data, size);
2074 void initializeLocal(ASTContext &Context, SourceLocation Loc);
2077 struct DependentTemplateSpecializationLocInfo : DependentNameLocInfo {
2078 SourceLocation TemplateKWLoc;
2079 SourceLocation LAngleLoc;
2080 SourceLocation RAngleLoc;
2081 // followed by a TemplateArgumentLocInfo[]
2084 class DependentTemplateSpecializationTypeLoc :
2085 public ConcreteTypeLoc<UnqualTypeLoc,
2086 DependentTemplateSpecializationTypeLoc,
2087 DependentTemplateSpecializationType,
2088 DependentTemplateSpecializationLocInfo> {
2090 SourceLocation getElaboratedKeywordLoc() const {
2091 return this->getLocalData()->ElaboratedKWLoc;
2094 void setElaboratedKeywordLoc(SourceLocation Loc) {
2095 this->getLocalData()->ElaboratedKWLoc = Loc;
2098 NestedNameSpecifierLoc getQualifierLoc() const {
2099 if (!getLocalData()->QualifierData)
2100 return NestedNameSpecifierLoc();
2102 return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
2103 getLocalData()->QualifierData);
2106 void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
2107 if (!QualifierLoc) {
2108 // Even if we have a nested-name-specifier in the dependent
2109 // template specialization type, we won't record the nested-name-specifier
2110 // location information when this type-source location information is
2111 // part of a nested-name-specifier.
2112 getLocalData()->QualifierData = nullptr;
2116 assert(QualifierLoc.getNestedNameSpecifier()
2117 == getTypePtr()->getQualifier() &&
2118 "Inconsistent nested-name-specifier pointer");
2119 getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
2122 SourceLocation getTemplateKeywordLoc() const {
2123 return getLocalData()->TemplateKWLoc;
2126 void setTemplateKeywordLoc(SourceLocation Loc) {
2127 getLocalData()->TemplateKWLoc = Loc;
2130 SourceLocation getTemplateNameLoc() const {
2131 return this->getLocalData()->NameLoc;
2134 void setTemplateNameLoc(SourceLocation Loc) {
2135 this->getLocalData()->NameLoc = Loc;
2138 SourceLocation getLAngleLoc() const {
2139 return this->getLocalData()->LAngleLoc;
2142 void setLAngleLoc(SourceLocation Loc) {
2143 this->getLocalData()->LAngleLoc = Loc;
2146 SourceLocation getRAngleLoc() const {
2147 return this->getLocalData()->RAngleLoc;
2150 void setRAngleLoc(SourceLocation Loc) {
2151 this->getLocalData()->RAngleLoc = Loc;
2154 unsigned getNumArgs() const {
2155 return getTypePtr()->getNumArgs();
2158 void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) {
2159 getArgInfos()[i] = AI;
2162 TemplateArgumentLocInfo getArgLocInfo(unsigned i) const {
2163 return getArgInfos()[i];
2166 TemplateArgumentLoc getArgLoc(unsigned i) const {
2167 return TemplateArgumentLoc(getTypePtr()->getArg(i), getArgLocInfo(i));
2170 SourceRange getLocalSourceRange() const {
2171 if (getElaboratedKeywordLoc().isValid())
2172 return SourceRange(getElaboratedKeywordLoc(), getRAngleLoc());
2173 else if (getQualifierLoc())
2174 return SourceRange(getQualifierLoc().getBeginLoc(), getRAngleLoc());
2175 else if (getTemplateKeywordLoc().isValid())
2176 return SourceRange(getTemplateKeywordLoc(), getRAngleLoc());
2178 return SourceRange(getTemplateNameLoc(), getRAngleLoc());
2181 void copy(DependentTemplateSpecializationTypeLoc Loc) {
2182 unsigned size = getFullDataSize();
2183 assert(size == Loc.getFullDataSize());
2184 memcpy(Data, Loc.Data, size);
2187 void initializeLocal(ASTContext &Context, SourceLocation Loc);
2189 unsigned getExtraLocalDataSize() const {
2190 return getNumArgs() * sizeof(TemplateArgumentLocInfo);
2193 unsigned getExtraLocalDataAlignment() const {
2194 return alignof(TemplateArgumentLocInfo);
2198 TemplateArgumentLocInfo *getArgInfos() const {
2199 return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData());
2203 struct PackExpansionTypeLocInfo {
2204 SourceLocation EllipsisLoc;
2207 class PackExpansionTypeLoc
2208 : public ConcreteTypeLoc<UnqualTypeLoc, PackExpansionTypeLoc,
2209 PackExpansionType, PackExpansionTypeLocInfo> {
2211 SourceLocation getEllipsisLoc() const {
2212 return this->getLocalData()->EllipsisLoc;
2215 void setEllipsisLoc(SourceLocation Loc) {
2216 this->getLocalData()->EllipsisLoc = Loc;
2219 SourceRange getLocalSourceRange() const {
2220 return SourceRange(getEllipsisLoc(), getEllipsisLoc());
2223 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
2224 setEllipsisLoc(Loc);
2227 TypeLoc getPatternLoc() const {
2228 return getInnerTypeLoc();
2231 QualType getInnerType() const {
2232 return this->getTypePtr()->getPattern();
2236 struct AtomicTypeLocInfo {
2237 SourceLocation KWLoc, LParenLoc, RParenLoc;
2240 class AtomicTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, AtomicTypeLoc,
2241 AtomicType, AtomicTypeLocInfo> {
2243 TypeLoc getValueLoc() const {
2244 return this->getInnerTypeLoc();
2247 SourceRange getLocalSourceRange() const {
2248 return SourceRange(getKWLoc(), getRParenLoc());
2251 SourceLocation getKWLoc() const {
2252 return this->getLocalData()->KWLoc;
2255 void setKWLoc(SourceLocation Loc) {
2256 this->getLocalData()->KWLoc = Loc;
2259 SourceLocation getLParenLoc() const {
2260 return this->getLocalData()->LParenLoc;
2263 void setLParenLoc(SourceLocation Loc) {
2264 this->getLocalData()->LParenLoc = Loc;
2267 SourceLocation getRParenLoc() const {
2268 return this->getLocalData()->RParenLoc;
2271 void setRParenLoc(SourceLocation Loc) {
2272 this->getLocalData()->RParenLoc = Loc;
2275 SourceRange getParensRange() const {
2276 return SourceRange(getLParenLoc(), getRParenLoc());
2279 void setParensRange(SourceRange Range) {
2280 setLParenLoc(Range.getBegin());
2281 setRParenLoc(Range.getEnd());
2284 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
2290 QualType getInnerType() const {
2291 return this->getTypePtr()->getValueType();
2295 struct PipeTypeLocInfo {
2296 SourceLocation KWLoc;
2299 class PipeTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, PipeTypeLoc, PipeType,
2302 TypeLoc getValueLoc() const { return this->getInnerTypeLoc(); }
2304 SourceRange getLocalSourceRange() const { return SourceRange(getKWLoc()); }
2306 SourceLocation getKWLoc() const { return this->getLocalData()->KWLoc; }
2307 void setKWLoc(SourceLocation Loc) { this->getLocalData()->KWLoc = Loc; }
2309 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
2313 QualType getInnerType() const { return this->getTypePtr()->getElementType(); }
2316 template <typename T>
2317 inline T TypeLoc::getAsAdjusted() const {
2318 TypeLoc Cur = *this;
2319 while (!T::isKind(Cur)) {
2320 if (auto PTL = Cur.getAs<ParenTypeLoc>())
2321 Cur = PTL.getInnerLoc();
2322 else if (auto ATL = Cur.getAs<AttributedTypeLoc>())
2323 Cur = ATL.getModifiedLoc();
2324 else if (auto ETL = Cur.getAs<ElaboratedTypeLoc>())
2325 Cur = ETL.getNamedTypeLoc();
2326 else if (auto ATL = Cur.getAs<AdjustedTypeLoc>())
2327 Cur = ATL.getOriginalLoc();
2328 else if (auto MQL = Cur.getAs<MacroQualifiedTypeLoc>())
2329 Cur = MQL.getInnerLoc();
2333 return Cur.getAs<T>();
2336 } // namespace clang
2338 #endif // LLVM_CLANG_AST_TYPELOC_H