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/DeclarationName.h"
18 #include "clang/AST/NestedNameSpecifier.h"
19 #include "clang/AST/TemplateBase.h"
20 #include "clang/AST/Type.h"
21 #include "clang/Basic/LLVM.h"
22 #include "clang/Basic/SourceLocation.h"
23 #include "clang/Basic/Specifiers.h"
24 #include "llvm/ADT/ArrayRef.h"
25 #include "llvm/Support/Casting.h"
26 #include "llvm/Support/Compiler.h"
27 #include "llvm/Support/MathExtras.h"
40 class ObjCInterfaceDecl;
41 class ObjCProtocolDecl;
42 class ObjCTypeParamDecl;
44 class TemplateTypeParmDecl;
46 class UnresolvedUsingTypenameDecl;
48 // Predeclare all the type nodes.
49 #define ABSTRACT_TYPELOC(Class, Base)
50 #define TYPELOC(Class, Base) \
52 #include "clang/AST/TypeLocNodes.def"
54 /// Base wrapper for a particular "section" of type source info.
56 /// A client should use the TypeLoc subclasses through castAs()/getAs()
57 /// in order to get at the actual information.
60 // The correctness of this relies on the property that, for Type *Ty,
61 // QualType(Ty, 0).getAsOpaquePtr() == (void*) Ty
62 const void *Ty = nullptr;
67 TypeLoc(QualType ty, void *opaqueData)
68 : Ty(ty.getAsOpaquePtr()), Data(opaqueData) {}
69 TypeLoc(const Type *ty, void *opaqueData)
70 : Ty(ty), Data(opaqueData) {}
72 /// Convert to the specified TypeLoc type, asserting that this TypeLoc
73 /// is of the desired type.
75 /// \pre T::isKind(*this)
78 assert(T::isKind(*this));
85 /// Convert to the specified TypeLoc type, returning a null TypeLoc if
86 /// this TypeLoc is not of the desired type.
89 if (!T::isKind(*this))
97 /// Convert to the specified TypeLoc type, returning a null TypeLoc if
98 /// this TypeLoc is not of the desired type. It will consider type
99 /// adjustments from a type that was written as a T to another type that is
100 /// still canonically a T (ignores parens, attributes, elaborated types, etc).
101 template <typename T>
102 T getAsAdjusted() const;
104 /// The kinds of TypeLocs. Equivalent to the Type::TypeClass enum,
105 /// except it also defines a Qualified enum that corresponds to the
106 /// QualifiedLoc class.
108 #define ABSTRACT_TYPE(Class, Base)
109 #define TYPE(Class, Base) \
111 #include "clang/AST/TypeNodes.inc"
115 TypeLocClass getTypeLocClass() const {
116 if (getType().hasLocalQualifiers()) return Qualified;
117 return (TypeLocClass) getType()->getTypeClass();
120 bool isNull() const { return !Ty; }
121 explicit operator bool() const { return Ty; }
123 /// Returns the size of type source info data block for the given type.
124 static unsigned getFullDataSizeForType(QualType Ty);
126 /// Returns the alignment of type source info data block for
128 static unsigned getLocalAlignmentForType(QualType Ty);
130 /// Get the type for which this source info wrapper provides
132 QualType getType() const {
133 return QualType::getFromOpaquePtr(Ty);
136 const Type *getTypePtr() const {
137 return QualType::getFromOpaquePtr(Ty).getTypePtr();
140 /// Get the pointer where source information is stored.
141 void *getOpaqueData() const {
145 /// Get the begin source location.
146 SourceLocation getBeginLoc() const;
148 /// Get the end source location.
149 SourceLocation getEndLoc() const;
151 /// Get the full source range.
152 SourceRange getSourceRange() const LLVM_READONLY {
153 return SourceRange(getBeginLoc(), getEndLoc());
157 /// Get the local source range.
158 SourceRange getLocalSourceRange() const {
159 return getLocalSourceRangeImpl(*this);
162 /// Returns the size of the type source info data block.
163 unsigned getFullDataSize() const {
164 return getFullDataSizeForType(getType());
167 /// Get the next TypeLoc pointed by this TypeLoc, e.g for "int*" the
168 /// TypeLoc is a PointerLoc and next TypeLoc is for "int".
169 TypeLoc getNextTypeLoc() const {
170 return getNextTypeLocImpl(*this);
173 /// Skips past any qualifiers, if this is qualified.
174 UnqualTypeLoc getUnqualifiedLoc() const; // implemented in this header
176 TypeLoc IgnoreParens() const;
178 /// Find a type with the location of an explicit type qualifier.
180 /// The result, if non-null, will be one of:
183 /// AttributedTypeLoc, for those type attributes that behave as qualifiers
184 TypeLoc findExplicitQualifierLoc() const;
186 /// Get the typeloc of an AutoType whose type will be deduced for a variable
187 /// with an initializer of this type. This looks through declarators like
188 /// pointer types, but not through decltype or typedefs.
189 AutoTypeLoc getContainedAutoTypeLoc() const;
191 /// Initializes this to state that every location in this
192 /// type is the given location.
194 /// This method exists to provide a simple transition for code that
195 /// relies on location-less types.
196 void initialize(ASTContext &Context, SourceLocation Loc) const {
197 initializeImpl(Context, *this, Loc);
200 /// Initializes this by copying its information from another
201 /// TypeLoc of the same type.
202 void initializeFullCopy(TypeLoc Other) {
203 assert(getType() == Other.getType());
207 /// Initializes this by copying its information from another
208 /// TypeLoc of the same type. The given size must be the full data
210 void initializeFullCopy(TypeLoc Other, unsigned Size) {
211 assert(getType() == Other.getType());
212 assert(getFullDataSize() == Size);
216 /// Copies the other type loc into this one.
217 void copy(TypeLoc other);
219 friend bool operator==(const TypeLoc &LHS, const TypeLoc &RHS) {
220 return LHS.Ty == RHS.Ty && LHS.Data == RHS.Data;
223 friend bool operator!=(const TypeLoc &LHS, const TypeLoc &RHS) {
224 return !(LHS == RHS);
227 /// Find the location of the nullability specifier (__nonnull,
228 /// __nullable, or __null_unspecifier), if there is one.
229 SourceLocation findNullabilityLoc() const;
232 static bool isKind(const TypeLoc&) {
236 static void initializeImpl(ASTContext &Context, TypeLoc TL,
238 static TypeLoc getNextTypeLocImpl(TypeLoc TL);
239 static TypeLoc IgnoreParensImpl(TypeLoc TL);
240 static SourceRange getLocalSourceRangeImpl(TypeLoc TL);
243 /// Return the TypeLoc for a type source info.
244 inline TypeLoc TypeSourceInfo::getTypeLoc() const {
245 // TODO: is this alignment already sufficient?
246 return TypeLoc(Ty, const_cast<void*>(static_cast<const void*>(this + 1)));
249 /// Wrapper of type source information for a type with
250 /// no direct qualifiers.
251 class UnqualTypeLoc : public TypeLoc {
253 UnqualTypeLoc() = default;
254 UnqualTypeLoc(const Type *Ty, void *Data) : TypeLoc(Ty, Data) {}
256 const Type *getTypePtr() const {
257 return reinterpret_cast<const Type*>(Ty);
260 TypeLocClass getTypeLocClass() const {
261 return (TypeLocClass) getTypePtr()->getTypeClass();
265 friend class TypeLoc;
267 static bool isKind(const TypeLoc &TL) {
268 return !TL.getType().hasLocalQualifiers();
272 /// Wrapper of type source information for a type with
273 /// non-trivial direct qualifiers.
275 /// Currently, we intentionally do not provide source location for
277 class QualifiedTypeLoc : public TypeLoc {
279 SourceRange getLocalSourceRange() const { return {}; }
281 UnqualTypeLoc getUnqualifiedLoc() const {
283 TypeLoc::getLocalAlignmentForType(QualType(getTypePtr(), 0));
284 auto dataInt = reinterpret_cast<uintptr_t>(Data);
285 dataInt = llvm::alignTo(dataInt, align);
286 return UnqualTypeLoc(getTypePtr(), reinterpret_cast<void*>(dataInt));
289 /// Initializes the local data of this type source info block to
290 /// provide no information.
291 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
295 void copyLocal(TypeLoc other) {
299 TypeLoc getNextTypeLoc() const {
300 return getUnqualifiedLoc();
303 /// Returns the size of the type source info data block that is
304 /// specific to this type.
305 unsigned getLocalDataSize() const {
306 // In fact, we don't currently preserve any location information
311 /// Returns the alignment of the type source info data block that is
312 /// specific to this type.
313 unsigned getLocalDataAlignment() const {
314 // We don't preserve any location information.
319 friend class TypeLoc;
321 static bool isKind(const TypeLoc &TL) {
322 return TL.getType().hasLocalQualifiers();
326 inline UnqualTypeLoc TypeLoc::getUnqualifiedLoc() const {
327 if (QualifiedTypeLoc Loc = getAs<QualifiedTypeLoc>())
328 return Loc.getUnqualifiedLoc();
329 return castAs<UnqualTypeLoc>();
332 /// A metaprogramming base class for TypeLoc classes which correspond
333 /// to a particular Type subclass. It is accepted for a single
334 /// TypeLoc class to correspond to multiple Type classes.
336 /// \tparam Base a class from which to derive
337 /// \tparam Derived the class deriving from this one
338 /// \tparam TypeClass the concrete Type subclass associated with this
340 /// \tparam LocalData the structure type of local location data for
343 /// TypeLocs with non-constant amounts of local data should override
344 /// getExtraLocalDataSize(); getExtraLocalData() will then point to
345 /// this extra memory.
347 /// TypeLocs with an inner type should define
348 /// QualType getInnerType() const
349 /// and getInnerTypeLoc() will then point to this inner type's
352 /// A word about hierarchies: this template is not designed to be
353 /// derived from multiple times in a hierarchy. It is also not
354 /// designed to be used for classes where subtypes might provide
355 /// different amounts of source information. It should be subclassed
356 /// only at the deepest portion of the hierarchy where all children
357 /// have identical source information; if that's an abstract type,
358 /// then further descendents should inherit from
359 /// InheritingConcreteTypeLoc instead.
360 template <class Base, class Derived, class TypeClass, class LocalData>
361 class ConcreteTypeLoc : public Base {
362 friend class TypeLoc;
364 const Derived *asDerived() const {
365 return static_cast<const Derived*>(this);
368 static bool isKind(const TypeLoc &TL) {
369 return !TL.getType().hasLocalQualifiers() &&
370 Derived::classofType(TL.getTypePtr());
373 static bool classofType(const Type *Ty) {
374 return TypeClass::classof(Ty);
378 unsigned getLocalDataAlignment() const {
379 return std::max(unsigned(alignof(LocalData)),
380 asDerived()->getExtraLocalDataAlignment());
383 unsigned getLocalDataSize() const {
384 unsigned size = sizeof(LocalData);
385 unsigned extraAlign = asDerived()->getExtraLocalDataAlignment();
386 size = llvm::alignTo(size, extraAlign);
387 size += asDerived()->getExtraLocalDataSize();
391 void copyLocal(Derived other) {
392 // Some subclasses have no data to copy.
393 if (asDerived()->getLocalDataSize() == 0) return;
395 // Copy the fixed-sized local data.
396 memcpy(getLocalData(), other.getLocalData(), sizeof(LocalData));
398 // Copy the variable-sized local data. We need to do this
399 // separately because the padding in the source and the padding in
400 // the destination might be different.
401 memcpy(getExtraLocalData(), other.getExtraLocalData(),
402 asDerived()->getExtraLocalDataSize());
405 TypeLoc getNextTypeLoc() const {
406 return getNextTypeLoc(asDerived()->getInnerType());
409 const TypeClass *getTypePtr() const {
410 return cast<TypeClass>(Base::getTypePtr());
414 unsigned getExtraLocalDataSize() const {
418 unsigned getExtraLocalDataAlignment() const {
422 LocalData *getLocalData() const {
423 return static_cast<LocalData*>(Base::Data);
426 /// Gets a pointer past the Info structure; useful for classes with
427 /// local data that can't be captured in the Info (e.g. because it's
428 /// of variable size).
429 void *getExtraLocalData() const {
430 unsigned size = sizeof(LocalData);
431 unsigned extraAlign = asDerived()->getExtraLocalDataAlignment();
432 size = llvm::alignTo(size, extraAlign);
433 return reinterpret_cast<char*>(Base::Data) + size;
436 void *getNonLocalData() const {
437 auto data = reinterpret_cast<uintptr_t>(Base::Data);
438 data += asDerived()->getLocalDataSize();
439 data = llvm::alignTo(data, getNextTypeAlign());
440 return reinterpret_cast<void*>(data);
443 struct HasNoInnerType {};
444 HasNoInnerType getInnerType() const { return HasNoInnerType(); }
446 TypeLoc getInnerTypeLoc() const {
447 return TypeLoc(asDerived()->getInnerType(), getNonLocalData());
451 unsigned getInnerTypeSize() const {
452 return getInnerTypeSize(asDerived()->getInnerType());
455 unsigned getInnerTypeSize(HasNoInnerType _) const {
459 unsigned getInnerTypeSize(QualType _) const {
460 return getInnerTypeLoc().getFullDataSize();
463 unsigned getNextTypeAlign() const {
464 return getNextTypeAlign(asDerived()->getInnerType());
467 unsigned getNextTypeAlign(HasNoInnerType _) const {
471 unsigned getNextTypeAlign(QualType T) const {
472 return TypeLoc::getLocalAlignmentForType(T);
475 TypeLoc getNextTypeLoc(HasNoInnerType _) const { return {}; }
477 TypeLoc getNextTypeLoc(QualType T) const {
478 return TypeLoc(T, getNonLocalData());
482 /// A metaprogramming class designed for concrete subtypes of abstract
483 /// types where all subtypes share equivalently-structured source
484 /// information. See the note on ConcreteTypeLoc.
485 template <class Base, class Derived, class TypeClass>
486 class InheritingConcreteTypeLoc : public Base {
487 friend class TypeLoc;
489 static bool classofType(const Type *Ty) {
490 return TypeClass::classof(Ty);
493 static bool isKind(const TypeLoc &TL) {
494 return !TL.getType().hasLocalQualifiers() &&
495 Derived::classofType(TL.getTypePtr());
497 static bool isKind(const UnqualTypeLoc &TL) {
498 return Derived::classofType(TL.getTypePtr());
502 const TypeClass *getTypePtr() const {
503 return cast<TypeClass>(Base::getTypePtr());
507 struct TypeSpecLocInfo {
508 SourceLocation NameLoc;
511 /// A reasonable base class for TypeLocs that correspond to
512 /// types that are written as a type-specifier.
513 class TypeSpecTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
519 LocalDataSize = sizeof(TypeSpecLocInfo),
520 LocalDataAlignment = alignof(TypeSpecLocInfo)
523 SourceLocation getNameLoc() const {
524 return this->getLocalData()->NameLoc;
527 void setNameLoc(SourceLocation Loc) {
528 this->getLocalData()->NameLoc = Loc;
531 SourceRange getLocalSourceRange() const {
532 return SourceRange(getNameLoc(), getNameLoc());
535 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
540 friend class TypeLoc;
542 static bool isKind(const TypeLoc &TL);
545 struct BuiltinLocInfo {
546 SourceRange BuiltinRange;
549 /// Wrapper for source info for builtin types.
550 class BuiltinTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
555 SourceLocation getBuiltinLoc() const {
556 return getLocalData()->BuiltinRange.getBegin();
559 void setBuiltinLoc(SourceLocation Loc) {
560 getLocalData()->BuiltinRange = Loc;
563 void expandBuiltinRange(SourceRange Range) {
564 SourceRange &BuiltinRange = getLocalData()->BuiltinRange;
565 if (!BuiltinRange.getBegin().isValid()) {
566 BuiltinRange = Range;
568 BuiltinRange.setBegin(std::min(Range.getBegin(), BuiltinRange.getBegin()));
569 BuiltinRange.setEnd(std::max(Range.getEnd(), BuiltinRange.getEnd()));
573 SourceLocation getNameLoc() const { return getBuiltinLoc(); }
575 WrittenBuiltinSpecs& getWrittenBuiltinSpecs() {
576 return *(static_cast<WrittenBuiltinSpecs*>(getExtraLocalData()));
578 const WrittenBuiltinSpecs& getWrittenBuiltinSpecs() const {
579 return *(static_cast<WrittenBuiltinSpecs*>(getExtraLocalData()));
582 bool needsExtraLocalData() const {
583 BuiltinType::Kind bk = getTypePtr()->getKind();
584 return (bk >= BuiltinType::UShort && bk <= BuiltinType::UInt128)
585 || (bk >= BuiltinType::Short && bk <= BuiltinType::Float128)
586 || bk == BuiltinType::UChar
587 || bk == BuiltinType::SChar;
590 unsigned getExtraLocalDataSize() const {
591 return needsExtraLocalData() ? sizeof(WrittenBuiltinSpecs) : 0;
594 unsigned getExtraLocalDataAlignment() const {
595 return needsExtraLocalData() ? alignof(WrittenBuiltinSpecs) : 1;
598 SourceRange getLocalSourceRange() const {
599 return getLocalData()->BuiltinRange;
602 TypeSpecifierSign getWrittenSignSpec() const {
603 if (needsExtraLocalData())
604 return static_cast<TypeSpecifierSign>(getWrittenBuiltinSpecs().Sign);
606 return TSS_unspecified;
609 bool hasWrittenSignSpec() const {
610 return getWrittenSignSpec() != TSS_unspecified;
613 void setWrittenSignSpec(TypeSpecifierSign written) {
614 if (needsExtraLocalData())
615 getWrittenBuiltinSpecs().Sign = written;
618 TypeSpecifierWidth getWrittenWidthSpec() const {
619 if (needsExtraLocalData())
620 return static_cast<TypeSpecifierWidth>(getWrittenBuiltinSpecs().Width);
622 return TSW_unspecified;
625 bool hasWrittenWidthSpec() const {
626 return getWrittenWidthSpec() != TSW_unspecified;
629 void setWrittenWidthSpec(TypeSpecifierWidth written) {
630 if (needsExtraLocalData())
631 getWrittenBuiltinSpecs().Width = written;
634 TypeSpecifierType getWrittenTypeSpec() const;
636 bool hasWrittenTypeSpec() const {
637 return getWrittenTypeSpec() != TST_unspecified;
640 void setWrittenTypeSpec(TypeSpecifierType written) {
641 if (needsExtraLocalData())
642 getWrittenBuiltinSpecs().Type = written;
645 bool hasModeAttr() const {
646 if (needsExtraLocalData())
647 return getWrittenBuiltinSpecs().ModeAttr;
652 void setModeAttr(bool written) {
653 if (needsExtraLocalData())
654 getWrittenBuiltinSpecs().ModeAttr = written;
657 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
659 if (needsExtraLocalData()) {
660 WrittenBuiltinSpecs &wbs = getWrittenBuiltinSpecs();
661 wbs.Sign = TSS_unspecified;
662 wbs.Width = TSW_unspecified;
663 wbs.Type = TST_unspecified;
664 wbs.ModeAttr = false;
669 /// Wrapper for source info for typedefs.
670 class TypedefTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
674 TypedefNameDecl *getTypedefNameDecl() const {
675 return getTypePtr()->getDecl();
679 /// Wrapper for source info for injected class names of class
681 class InjectedClassNameTypeLoc :
682 public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
683 InjectedClassNameTypeLoc,
684 InjectedClassNameType> {
686 CXXRecordDecl *getDecl() const {
687 return getTypePtr()->getDecl();
691 /// Wrapper for source info for unresolved typename using decls.
692 class UnresolvedUsingTypeLoc :
693 public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
694 UnresolvedUsingTypeLoc,
695 UnresolvedUsingType> {
697 UnresolvedUsingTypenameDecl *getDecl() const {
698 return getTypePtr()->getDecl();
702 /// Wrapper for source info for tag types. Note that this only
703 /// records source info for the name itself; a type written 'struct foo'
704 /// should be represented as an ElaboratedTypeLoc. We currently
705 /// only do that when C++ is enabled because of the expense of
706 /// creating an ElaboratedType node for so many type references in C.
707 class TagTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
711 TagDecl *getDecl() const { return getTypePtr()->getDecl(); }
713 /// True if the tag was defined in this type specifier.
714 bool isDefinition() const;
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;
886 void initializeLocal(ASTContext &Context, SourceLocation loc) {
890 QualType getInnerType() const {
891 return getTypePtr()->getModifiedType();
895 struct ObjCObjectTypeLocInfo {
896 SourceLocation TypeArgsLAngleLoc;
897 SourceLocation TypeArgsRAngleLoc;
898 SourceLocation ProtocolLAngleLoc;
899 SourceLocation ProtocolRAngleLoc;
900 bool HasBaseTypeAsWritten;
903 // A helper class for defining ObjC TypeLocs that can qualified with
906 // TypeClass basically has to be either ObjCInterfaceType or
907 // ObjCObjectPointerType.
908 class ObjCObjectTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
911 ObjCObjectTypeLocInfo> {
912 // TypeSourceInfo*'s are stored after Info, one for each type argument.
913 TypeSourceInfo **getTypeArgLocArray() const {
914 return (TypeSourceInfo**)this->getExtraLocalData();
917 // SourceLocations are stored after the type argument information, one for
919 SourceLocation *getProtocolLocArray() const {
920 return (SourceLocation*)(getTypeArgLocArray() + getNumTypeArgs());
924 SourceLocation getTypeArgsLAngleLoc() const {
925 return this->getLocalData()->TypeArgsLAngleLoc;
928 void setTypeArgsLAngleLoc(SourceLocation Loc) {
929 this->getLocalData()->TypeArgsLAngleLoc = Loc;
932 SourceLocation getTypeArgsRAngleLoc() const {
933 return this->getLocalData()->TypeArgsRAngleLoc;
936 void setTypeArgsRAngleLoc(SourceLocation Loc) {
937 this->getLocalData()->TypeArgsRAngleLoc = Loc;
940 unsigned getNumTypeArgs() const {
941 return this->getTypePtr()->getTypeArgsAsWritten().size();
944 TypeSourceInfo *getTypeArgTInfo(unsigned i) const {
945 assert(i < getNumTypeArgs() && "Index is out of bounds!");
946 return getTypeArgLocArray()[i];
949 void setTypeArgTInfo(unsigned i, TypeSourceInfo *TInfo) {
950 assert(i < getNumTypeArgs() && "Index is out of bounds!");
951 getTypeArgLocArray()[i] = TInfo;
954 SourceLocation getProtocolLAngleLoc() const {
955 return this->getLocalData()->ProtocolLAngleLoc;
958 void setProtocolLAngleLoc(SourceLocation Loc) {
959 this->getLocalData()->ProtocolLAngleLoc = Loc;
962 SourceLocation getProtocolRAngleLoc() const {
963 return this->getLocalData()->ProtocolRAngleLoc;
966 void setProtocolRAngleLoc(SourceLocation Loc) {
967 this->getLocalData()->ProtocolRAngleLoc = Loc;
970 unsigned getNumProtocols() const {
971 return this->getTypePtr()->getNumProtocols();
974 SourceLocation getProtocolLoc(unsigned i) const {
975 assert(i < getNumProtocols() && "Index is out of bounds!");
976 return getProtocolLocArray()[i];
979 void setProtocolLoc(unsigned i, SourceLocation Loc) {
980 assert(i < getNumProtocols() && "Index is out of bounds!");
981 getProtocolLocArray()[i] = Loc;
984 ObjCProtocolDecl *getProtocol(unsigned i) const {
985 assert(i < getNumProtocols() && "Index is out of bounds!");
986 return *(this->getTypePtr()->qual_begin() + i);
990 ArrayRef<SourceLocation> getProtocolLocs() const {
991 return llvm::makeArrayRef(getProtocolLocArray(), getNumProtocols());
994 bool hasBaseTypeAsWritten() const {
995 return getLocalData()->HasBaseTypeAsWritten;
998 void setHasBaseTypeAsWritten(bool HasBaseType) {
999 getLocalData()->HasBaseTypeAsWritten = HasBaseType;
1002 TypeLoc getBaseLoc() const {
1003 return getInnerTypeLoc();
1006 SourceRange getLocalSourceRange() const {
1007 SourceLocation start = getTypeArgsLAngleLoc();
1008 if (start.isInvalid())
1009 start = getProtocolLAngleLoc();
1010 SourceLocation end = getProtocolRAngleLoc();
1011 if (end.isInvalid())
1012 end = getTypeArgsRAngleLoc();
1013 return SourceRange(start, end);
1016 void initializeLocal(ASTContext &Context, SourceLocation Loc);
1018 unsigned getExtraLocalDataSize() const {
1019 return this->getNumTypeArgs() * sizeof(TypeSourceInfo *)
1020 + this->getNumProtocols() * sizeof(SourceLocation);
1023 unsigned getExtraLocalDataAlignment() const {
1024 static_assert(alignof(ObjCObjectTypeLoc) >= alignof(TypeSourceInfo *),
1025 "not enough alignment for tail-allocated data");
1026 return alignof(TypeSourceInfo *);
1029 QualType getInnerType() const {
1030 return getTypePtr()->getBaseType();
1034 struct ObjCInterfaceLocInfo {
1035 SourceLocation NameLoc;
1036 SourceLocation NameEndLoc;
1039 /// Wrapper for source info for ObjC interfaces.
1040 class ObjCInterfaceTypeLoc : public ConcreteTypeLoc<ObjCObjectTypeLoc,
1041 ObjCInterfaceTypeLoc,
1043 ObjCInterfaceLocInfo> {
1045 ObjCInterfaceDecl *getIFaceDecl() const {
1046 return getTypePtr()->getDecl();
1049 SourceLocation getNameLoc() const {
1050 return getLocalData()->NameLoc;
1053 void setNameLoc(SourceLocation Loc) {
1054 getLocalData()->NameLoc = Loc;
1057 SourceRange getLocalSourceRange() const {
1058 return SourceRange(getNameLoc(), getNameEndLoc());
1061 SourceLocation getNameEndLoc() const {
1062 return getLocalData()->NameEndLoc;
1065 void setNameEndLoc(SourceLocation Loc) {
1066 getLocalData()->NameEndLoc = Loc;
1069 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1075 struct MacroQualifiedLocInfo {
1076 SourceLocation ExpansionLoc;
1079 class MacroQualifiedTypeLoc
1080 : public ConcreteTypeLoc<UnqualTypeLoc, MacroQualifiedTypeLoc,
1081 MacroQualifiedType, MacroQualifiedLocInfo> {
1083 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1084 setExpansionLoc(Loc);
1087 TypeLoc getInnerLoc() const { return getInnerTypeLoc(); }
1089 const IdentifierInfo *getMacroIdentifier() const {
1090 return getTypePtr()->getMacroIdentifier();
1093 SourceLocation getExpansionLoc() const {
1094 return this->getLocalData()->ExpansionLoc;
1097 void setExpansionLoc(SourceLocation Loc) {
1098 this->getLocalData()->ExpansionLoc = Loc;
1101 QualType getInnerType() const { return getTypePtr()->getUnderlyingType(); }
1103 SourceRange getLocalSourceRange() const {
1104 return getInnerLoc().getLocalSourceRange();
1108 struct ParenLocInfo {
1109 SourceLocation LParenLoc;
1110 SourceLocation RParenLoc;
1114 : public ConcreteTypeLoc<UnqualTypeLoc, ParenTypeLoc, ParenType,
1117 SourceLocation getLParenLoc() const {
1118 return this->getLocalData()->LParenLoc;
1121 SourceLocation getRParenLoc() const {
1122 return this->getLocalData()->RParenLoc;
1125 void setLParenLoc(SourceLocation Loc) {
1126 this->getLocalData()->LParenLoc = Loc;
1129 void setRParenLoc(SourceLocation Loc) {
1130 this->getLocalData()->RParenLoc = Loc;
1133 SourceRange getLocalSourceRange() const {
1134 return SourceRange(getLParenLoc(), getRParenLoc());
1137 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1142 TypeLoc getInnerLoc() const {
1143 return getInnerTypeLoc();
1146 QualType getInnerType() const {
1147 return this->getTypePtr()->getInnerType();
1151 inline TypeLoc TypeLoc::IgnoreParens() const {
1152 if (ParenTypeLoc::isKind(*this))
1153 return IgnoreParensImpl(*this);
1157 struct AdjustedLocInfo {}; // Nothing.
1159 class AdjustedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, AdjustedTypeLoc,
1160 AdjustedType, AdjustedLocInfo> {
1162 TypeLoc getOriginalLoc() const {
1163 return getInnerTypeLoc();
1166 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1170 QualType getInnerType() const {
1171 // The inner type is the undecayed type, since that's what we have source
1172 // location information for.
1173 return getTypePtr()->getOriginalType();
1176 SourceRange getLocalSourceRange() const { return {}; }
1178 unsigned getLocalDataSize() const {
1179 // sizeof(AdjustedLocInfo) is 1, but we don't need its address to be unique
1180 // anyway. TypeLocBuilder can't handle data sizes of 1.
1181 return 0; // No data.
1185 /// Wrapper for source info for pointers decayed from arrays and
1187 class DecayedTypeLoc : public InheritingConcreteTypeLoc<
1188 AdjustedTypeLoc, DecayedTypeLoc, DecayedType> {
1191 struct PointerLikeLocInfo {
1192 SourceLocation StarLoc;
1195 /// A base class for
1196 template <class Derived, class TypeClass, class LocalData = PointerLikeLocInfo>
1197 class PointerLikeTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, Derived,
1198 TypeClass, LocalData> {
1200 SourceLocation getSigilLoc() const {
1201 return this->getLocalData()->StarLoc;
1204 void setSigilLoc(SourceLocation Loc) {
1205 this->getLocalData()->StarLoc = Loc;
1208 TypeLoc getPointeeLoc() const {
1209 return this->getInnerTypeLoc();
1212 SourceRange getLocalSourceRange() const {
1213 return SourceRange(getSigilLoc(), getSigilLoc());
1216 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1220 QualType getInnerType() const {
1221 return this->getTypePtr()->getPointeeType();
1225 /// Wrapper for source info for pointers.
1226 class PointerTypeLoc : public PointerLikeTypeLoc<PointerTypeLoc,
1229 SourceLocation getStarLoc() const {
1230 return getSigilLoc();
1233 void setStarLoc(SourceLocation Loc) {
1238 /// Wrapper for source info for block pointers.
1239 class BlockPointerTypeLoc : public PointerLikeTypeLoc<BlockPointerTypeLoc,
1242 SourceLocation getCaretLoc() const {
1243 return getSigilLoc();
1246 void setCaretLoc(SourceLocation Loc) {
1251 struct MemberPointerLocInfo : public PointerLikeLocInfo {
1252 TypeSourceInfo *ClassTInfo;
1255 /// Wrapper for source info for member pointers.
1256 class MemberPointerTypeLoc : public PointerLikeTypeLoc<MemberPointerTypeLoc,
1258 MemberPointerLocInfo> {
1260 SourceLocation getStarLoc() const {
1261 return getSigilLoc();
1264 void setStarLoc(SourceLocation Loc) {
1268 const Type *getClass() const {
1269 return getTypePtr()->getClass();
1272 TypeSourceInfo *getClassTInfo() const {
1273 return getLocalData()->ClassTInfo;
1276 void setClassTInfo(TypeSourceInfo* TI) {
1277 getLocalData()->ClassTInfo = TI;
1280 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1282 setClassTInfo(nullptr);
1285 SourceRange getLocalSourceRange() const {
1286 if (TypeSourceInfo *TI = getClassTInfo())
1287 return SourceRange(TI->getTypeLoc().getBeginLoc(), getStarLoc());
1289 return SourceRange(getStarLoc());
1293 /// Wraps an ObjCPointerType with source location information.
1294 class ObjCObjectPointerTypeLoc :
1295 public PointerLikeTypeLoc<ObjCObjectPointerTypeLoc,
1296 ObjCObjectPointerType> {
1298 SourceLocation getStarLoc() const {
1299 return getSigilLoc();
1302 void setStarLoc(SourceLocation Loc) {
1307 class ReferenceTypeLoc : public PointerLikeTypeLoc<ReferenceTypeLoc,
1310 QualType getInnerType() const {
1311 return getTypePtr()->getPointeeTypeAsWritten();
1315 class LValueReferenceTypeLoc :
1316 public InheritingConcreteTypeLoc<ReferenceTypeLoc,
1317 LValueReferenceTypeLoc,
1318 LValueReferenceType> {
1320 SourceLocation getAmpLoc() const {
1321 return getSigilLoc();
1324 void setAmpLoc(SourceLocation Loc) {
1329 class RValueReferenceTypeLoc :
1330 public InheritingConcreteTypeLoc<ReferenceTypeLoc,
1331 RValueReferenceTypeLoc,
1332 RValueReferenceType> {
1334 SourceLocation getAmpAmpLoc() const {
1335 return getSigilLoc();
1338 void setAmpAmpLoc(SourceLocation Loc) {
1343 struct FunctionLocInfo {
1344 SourceLocation LocalRangeBegin;
1345 SourceLocation LParenLoc;
1346 SourceLocation RParenLoc;
1347 SourceLocation LocalRangeEnd;
1350 /// Wrapper for source info for functions.
1351 class FunctionTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
1355 bool hasExceptionSpec() const {
1356 if (auto *FPT = dyn_cast<FunctionProtoType>(getTypePtr())) {
1357 return FPT->hasExceptionSpec();
1362 SourceRange *getExceptionSpecRangePtr() const {
1363 assert(hasExceptionSpec() && "No exception spec range");
1364 // After the Info comes the ParmVarDecl array, and after that comes the
1365 // exception specification information.
1366 return (SourceRange *)(getParmArray() + getNumParams());
1370 SourceLocation getLocalRangeBegin() const {
1371 return getLocalData()->LocalRangeBegin;
1374 void setLocalRangeBegin(SourceLocation L) {
1375 getLocalData()->LocalRangeBegin = L;
1378 SourceLocation getLocalRangeEnd() const {
1379 return getLocalData()->LocalRangeEnd;
1382 void setLocalRangeEnd(SourceLocation L) {
1383 getLocalData()->LocalRangeEnd = L;
1386 SourceLocation getLParenLoc() const {
1387 return this->getLocalData()->LParenLoc;
1390 void setLParenLoc(SourceLocation Loc) {
1391 this->getLocalData()->LParenLoc = Loc;
1394 SourceLocation getRParenLoc() const {
1395 return this->getLocalData()->RParenLoc;
1398 void setRParenLoc(SourceLocation Loc) {
1399 this->getLocalData()->RParenLoc = Loc;
1402 SourceRange getParensRange() const {
1403 return SourceRange(getLParenLoc(), getRParenLoc());
1406 SourceRange getExceptionSpecRange() const {
1407 if (hasExceptionSpec())
1408 return *getExceptionSpecRangePtr();
1412 void setExceptionSpecRange(SourceRange R) {
1413 if (hasExceptionSpec())
1414 *getExceptionSpecRangePtr() = R;
1417 ArrayRef<ParmVarDecl *> getParams() const {
1418 return llvm::makeArrayRef(getParmArray(), getNumParams());
1421 // ParmVarDecls* are stored after Info, one for each parameter.
1422 ParmVarDecl **getParmArray() const {
1423 return (ParmVarDecl**) getExtraLocalData();
1426 unsigned getNumParams() const {
1427 if (isa<FunctionNoProtoType>(getTypePtr()))
1429 return cast<FunctionProtoType>(getTypePtr())->getNumParams();
1432 ParmVarDecl *getParam(unsigned i) const { return getParmArray()[i]; }
1433 void setParam(unsigned i, ParmVarDecl *VD) { getParmArray()[i] = VD; }
1435 TypeLoc getReturnLoc() const {
1436 return getInnerTypeLoc();
1439 SourceRange getLocalSourceRange() const {
1440 return SourceRange(getLocalRangeBegin(), getLocalRangeEnd());
1443 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1444 setLocalRangeBegin(Loc);
1447 setLocalRangeEnd(Loc);
1448 for (unsigned i = 0, e = getNumParams(); i != e; ++i)
1449 setParam(i, nullptr);
1450 if (hasExceptionSpec())
1451 setExceptionSpecRange(Loc);
1454 /// Returns the size of the type source info data block that is
1455 /// specific to this type.
1456 unsigned getExtraLocalDataSize() const {
1457 unsigned ExceptSpecSize = hasExceptionSpec() ? sizeof(SourceRange) : 0;
1458 return (getNumParams() * sizeof(ParmVarDecl *)) + ExceptSpecSize;
1461 unsigned getExtraLocalDataAlignment() const { return alignof(ParmVarDecl *); }
1463 QualType getInnerType() const { return getTypePtr()->getReturnType(); }
1466 class FunctionProtoTypeLoc :
1467 public InheritingConcreteTypeLoc<FunctionTypeLoc,
1468 FunctionProtoTypeLoc,
1469 FunctionProtoType> {
1472 class FunctionNoProtoTypeLoc :
1473 public InheritingConcreteTypeLoc<FunctionTypeLoc,
1474 FunctionNoProtoTypeLoc,
1475 FunctionNoProtoType> {
1478 struct ArrayLocInfo {
1479 SourceLocation LBracketLoc, RBracketLoc;
1483 /// Wrapper for source info for arrays.
1484 class ArrayTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
1489 SourceLocation getLBracketLoc() const {
1490 return getLocalData()->LBracketLoc;
1493 void setLBracketLoc(SourceLocation Loc) {
1494 getLocalData()->LBracketLoc = Loc;
1497 SourceLocation getRBracketLoc() const {
1498 return getLocalData()->RBracketLoc;
1501 void setRBracketLoc(SourceLocation Loc) {
1502 getLocalData()->RBracketLoc = Loc;
1505 SourceRange getBracketsRange() const {
1506 return SourceRange(getLBracketLoc(), getRBracketLoc());
1509 Expr *getSizeExpr() const {
1510 return getLocalData()->Size;
1513 void setSizeExpr(Expr *Size) {
1514 getLocalData()->Size = Size;
1517 TypeLoc getElementLoc() const {
1518 return getInnerTypeLoc();
1521 SourceRange getLocalSourceRange() const {
1522 return SourceRange(getLBracketLoc(), getRBracketLoc());
1525 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1526 setLBracketLoc(Loc);
1527 setRBracketLoc(Loc);
1528 setSizeExpr(nullptr);
1531 QualType getInnerType() const { return getTypePtr()->getElementType(); }
1534 class ConstantArrayTypeLoc :
1535 public InheritingConcreteTypeLoc<ArrayTypeLoc,
1536 ConstantArrayTypeLoc,
1537 ConstantArrayType> {
1540 class IncompleteArrayTypeLoc :
1541 public InheritingConcreteTypeLoc<ArrayTypeLoc,
1542 IncompleteArrayTypeLoc,
1543 IncompleteArrayType> {
1546 class DependentSizedArrayTypeLoc :
1547 public InheritingConcreteTypeLoc<ArrayTypeLoc,
1548 DependentSizedArrayTypeLoc,
1549 DependentSizedArrayType> {
1551 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1552 ArrayTypeLoc::initializeLocal(Context, Loc);
1553 setSizeExpr(getTypePtr()->getSizeExpr());
1557 class VariableArrayTypeLoc :
1558 public InheritingConcreteTypeLoc<ArrayTypeLoc,
1559 VariableArrayTypeLoc,
1560 VariableArrayType> {
1563 // Location information for a TemplateName. Rudimentary for now.
1564 struct TemplateNameLocInfo {
1565 SourceLocation NameLoc;
1568 struct TemplateSpecializationLocInfo : TemplateNameLocInfo {
1569 SourceLocation TemplateKWLoc;
1570 SourceLocation LAngleLoc;
1571 SourceLocation RAngleLoc;
1574 class TemplateSpecializationTypeLoc :
1575 public ConcreteTypeLoc<UnqualTypeLoc,
1576 TemplateSpecializationTypeLoc,
1577 TemplateSpecializationType,
1578 TemplateSpecializationLocInfo> {
1580 SourceLocation getTemplateKeywordLoc() const {
1581 return getLocalData()->TemplateKWLoc;
1584 void setTemplateKeywordLoc(SourceLocation Loc) {
1585 getLocalData()->TemplateKWLoc = Loc;
1588 SourceLocation getLAngleLoc() const {
1589 return getLocalData()->LAngleLoc;
1592 void setLAngleLoc(SourceLocation Loc) {
1593 getLocalData()->LAngleLoc = Loc;
1596 SourceLocation getRAngleLoc() const {
1597 return getLocalData()->RAngleLoc;
1600 void setRAngleLoc(SourceLocation Loc) {
1601 getLocalData()->RAngleLoc = Loc;
1604 unsigned getNumArgs() const {
1605 return getTypePtr()->getNumArgs();
1608 void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) {
1609 getArgInfos()[i] = AI;
1612 TemplateArgumentLocInfo getArgLocInfo(unsigned i) const {
1613 return getArgInfos()[i];
1616 TemplateArgumentLoc getArgLoc(unsigned i) const {
1617 return TemplateArgumentLoc(getTypePtr()->getArg(i), getArgLocInfo(i));
1620 SourceLocation getTemplateNameLoc() const {
1621 return getLocalData()->NameLoc;
1624 void setTemplateNameLoc(SourceLocation Loc) {
1625 getLocalData()->NameLoc = Loc;
1628 /// - Copy the location information from the given info.
1629 void copy(TemplateSpecializationTypeLoc Loc) {
1630 unsigned size = getFullDataSize();
1631 assert(size == Loc.getFullDataSize());
1633 // We're potentially copying Expr references here. We don't
1634 // bother retaining them because TypeSourceInfos live forever, so
1635 // as long as the Expr was retained when originally written into
1636 // the TypeLoc, we're okay.
1637 memcpy(Data, Loc.Data, size);
1640 SourceRange getLocalSourceRange() const {
1641 if (getTemplateKeywordLoc().isValid())
1642 return SourceRange(getTemplateKeywordLoc(), getRAngleLoc());
1644 return SourceRange(getTemplateNameLoc(), getRAngleLoc());
1647 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1648 setTemplateKeywordLoc(Loc);
1649 setTemplateNameLoc(Loc);
1652 initializeArgLocs(Context, getNumArgs(), getTypePtr()->getArgs(),
1653 getArgInfos(), Loc);
1656 static void initializeArgLocs(ASTContext &Context, unsigned NumArgs,
1657 const TemplateArgument *Args,
1658 TemplateArgumentLocInfo *ArgInfos,
1659 SourceLocation Loc);
1661 unsigned getExtraLocalDataSize() const {
1662 return getNumArgs() * sizeof(TemplateArgumentLocInfo);
1665 unsigned getExtraLocalDataAlignment() const {
1666 return alignof(TemplateArgumentLocInfo);
1670 TemplateArgumentLocInfo *getArgInfos() const {
1671 return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData());
1675 struct DependentAddressSpaceLocInfo {
1677 SourceRange OperandParens;
1678 SourceLocation AttrLoc;
1681 class DependentAddressSpaceTypeLoc
1682 : public ConcreteTypeLoc<UnqualTypeLoc,
1683 DependentAddressSpaceTypeLoc,
1684 DependentAddressSpaceType,
1685 DependentAddressSpaceLocInfo> {
1687 /// The location of the attribute name, i.e.
1688 /// int * __attribute__((address_space(11)))
1690 SourceLocation getAttrNameLoc() const {
1691 return getLocalData()->AttrLoc;
1693 void setAttrNameLoc(SourceLocation loc) {
1694 getLocalData()->AttrLoc = loc;
1697 /// The attribute's expression operand, if it has one.
1698 /// int * __attribute__((address_space(11)))
1700 Expr *getAttrExprOperand() const {
1701 return getLocalData()->ExprOperand;
1703 void setAttrExprOperand(Expr *e) {
1704 getLocalData()->ExprOperand = e;
1707 /// The location of the parentheses around the operand, if there is
1709 /// int * __attribute__((address_space(11)))
1711 SourceRange getAttrOperandParensRange() const {
1712 return getLocalData()->OperandParens;
1714 void setAttrOperandParensRange(SourceRange range) {
1715 getLocalData()->OperandParens = range;
1718 SourceRange getLocalSourceRange() const {
1719 SourceRange range(getAttrNameLoc());
1720 range.setEnd(getAttrOperandParensRange().getEnd());
1724 /// Returns the type before the address space attribute application
1726 /// int * __attribute__((address_space(11))) *
1728 QualType getInnerType() const {
1729 return this->getTypePtr()->getPointeeType();
1732 TypeLoc getPointeeTypeLoc() const {
1733 return this->getInnerTypeLoc();
1736 void initializeLocal(ASTContext &Context, SourceLocation loc) {
1737 setAttrNameLoc(loc);
1738 setAttrOperandParensRange(loc);
1739 setAttrOperandParensRange(SourceRange(loc));
1740 setAttrExprOperand(getTypePtr()->getAddrSpaceExpr());
1744 //===----------------------------------------------------------------------===//
1746 // All of these need proper implementations.
1748 //===----------------------------------------------------------------------===//
1750 // FIXME: size expression and attribute locations (or keyword if we
1751 // ever fully support altivec syntax).
1752 class VectorTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
1757 // FIXME: size expression and attribute locations (or keyword if we
1758 // ever fully support altivec syntax).
1759 class DependentVectorTypeLoc
1760 : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
1761 DependentVectorTypeLoc,
1762 DependentVectorType> {};
1764 // FIXME: size expression and attribute locations.
1765 class ExtVectorTypeLoc : public InheritingConcreteTypeLoc<VectorTypeLoc,
1770 // FIXME: attribute locations.
1771 // For some reason, this isn't a subtype of VectorType.
1772 class DependentSizedExtVectorTypeLoc :
1773 public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
1774 DependentSizedExtVectorTypeLoc,
1775 DependentSizedExtVectorType> {
1778 struct MatrixTypeLocInfo {
1779 SourceLocation AttrLoc;
1780 SourceRange OperandParens;
1782 Expr *ColumnOperand;
1785 class MatrixTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, MatrixTypeLoc,
1786 MatrixType, MatrixTypeLocInfo> {
1788 /// The location of the attribute name, i.e.
1789 /// float __attribute__((matrix_type(4, 2)))
1790 /// ^~~~~~~~~~~~~~~~~
1791 SourceLocation getAttrNameLoc() const { return getLocalData()->AttrLoc; }
1792 void setAttrNameLoc(SourceLocation loc) { getLocalData()->AttrLoc = loc; }
1794 /// The attribute's row operand, if it has one.
1795 /// float __attribute__((matrix_type(4, 2)))
1797 Expr *getAttrRowOperand() const { return getLocalData()->RowOperand; }
1798 void setAttrRowOperand(Expr *e) { getLocalData()->RowOperand = e; }
1800 /// The attribute's column operand, if it has one.
1801 /// float __attribute__((matrix_type(4, 2)))
1803 Expr *getAttrColumnOperand() const { return getLocalData()->ColumnOperand; }
1804 void setAttrColumnOperand(Expr *e) { getLocalData()->ColumnOperand = e; }
1806 /// The location of the parentheses around the operand, if there is
1808 /// float __attribute__((matrix_type(4, 2)))
1810 SourceRange getAttrOperandParensRange() const {
1811 return getLocalData()->OperandParens;
1813 void setAttrOperandParensRange(SourceRange range) {
1814 getLocalData()->OperandParens = range;
1817 SourceRange getLocalSourceRange() const {
1818 SourceRange range(getAttrNameLoc());
1819 range.setEnd(getAttrOperandParensRange().getEnd());
1823 void initializeLocal(ASTContext &Context, SourceLocation loc) {
1824 setAttrNameLoc(loc);
1825 setAttrOperandParensRange(loc);
1826 setAttrRowOperand(nullptr);
1827 setAttrColumnOperand(nullptr);
1831 class ConstantMatrixTypeLoc
1832 : public InheritingConcreteTypeLoc<MatrixTypeLoc, ConstantMatrixTypeLoc,
1833 ConstantMatrixType> {};
1835 class DependentSizedMatrixTypeLoc
1836 : public InheritingConcreteTypeLoc<MatrixTypeLoc,
1837 DependentSizedMatrixTypeLoc,
1838 DependentSizedMatrixType> {};
1840 // FIXME: location of the '_Complex' keyword.
1841 class ComplexTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
1846 struct TypeofLocInfo {
1847 SourceLocation TypeofLoc;
1848 SourceLocation LParenLoc;
1849 SourceLocation RParenLoc;
1852 struct TypeOfExprTypeLocInfo : public TypeofLocInfo {
1855 struct TypeOfTypeLocInfo : public TypeofLocInfo {
1856 TypeSourceInfo* UnderlyingTInfo;
1859 template <class Derived, class TypeClass, class LocalData = TypeofLocInfo>
1860 class TypeofLikeTypeLoc
1861 : public ConcreteTypeLoc<UnqualTypeLoc, Derived, TypeClass, LocalData> {
1863 SourceLocation getTypeofLoc() const {
1864 return this->getLocalData()->TypeofLoc;
1867 void setTypeofLoc(SourceLocation Loc) {
1868 this->getLocalData()->TypeofLoc = Loc;
1871 SourceLocation getLParenLoc() const {
1872 return this->getLocalData()->LParenLoc;
1875 void setLParenLoc(SourceLocation Loc) {
1876 this->getLocalData()->LParenLoc = Loc;
1879 SourceLocation getRParenLoc() const {
1880 return this->getLocalData()->RParenLoc;
1883 void setRParenLoc(SourceLocation Loc) {
1884 this->getLocalData()->RParenLoc = Loc;
1887 SourceRange getParensRange() const {
1888 return SourceRange(getLParenLoc(), getRParenLoc());
1891 void setParensRange(SourceRange range) {
1892 setLParenLoc(range.getBegin());
1893 setRParenLoc(range.getEnd());
1896 SourceRange getLocalSourceRange() const {
1897 return SourceRange(getTypeofLoc(), getRParenLoc());
1900 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1907 class TypeOfExprTypeLoc : public TypeofLikeTypeLoc<TypeOfExprTypeLoc,
1909 TypeOfExprTypeLocInfo> {
1911 Expr* getUnderlyingExpr() const {
1912 return getTypePtr()->getUnderlyingExpr();
1915 // Reimplemented to account for GNU/C++ extension
1916 // typeof unary-expression
1917 // where there are no parentheses.
1918 SourceRange getLocalSourceRange() const;
1922 : public TypeofLikeTypeLoc<TypeOfTypeLoc, TypeOfType, TypeOfTypeLocInfo> {
1924 QualType getUnderlyingType() const {
1925 return this->getTypePtr()->getUnderlyingType();
1928 TypeSourceInfo* getUnderlyingTInfo() const {
1929 return this->getLocalData()->UnderlyingTInfo;
1932 void setUnderlyingTInfo(TypeSourceInfo* TI) const {
1933 this->getLocalData()->UnderlyingTInfo = TI;
1936 void initializeLocal(ASTContext &Context, SourceLocation Loc);
1939 // FIXME: location of the 'decltype' and parens.
1940 class DecltypeTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
1944 Expr *getUnderlyingExpr() const { return getTypePtr()->getUnderlyingExpr(); }
1947 struct UnaryTransformTypeLocInfo {
1948 // FIXME: While there's only one unary transform right now, future ones may
1949 // need different representations
1950 SourceLocation KWLoc, LParenLoc, RParenLoc;
1951 TypeSourceInfo *UnderlyingTInfo;
1954 class UnaryTransformTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
1955 UnaryTransformTypeLoc,
1957 UnaryTransformTypeLocInfo> {
1959 SourceLocation getKWLoc() const { return getLocalData()->KWLoc; }
1960 void setKWLoc(SourceLocation Loc) { getLocalData()->KWLoc = Loc; }
1962 SourceLocation getLParenLoc() const { return getLocalData()->LParenLoc; }
1963 void setLParenLoc(SourceLocation Loc) { getLocalData()->LParenLoc = Loc; }
1965 SourceLocation getRParenLoc() const { return getLocalData()->RParenLoc; }
1966 void setRParenLoc(SourceLocation Loc) { getLocalData()->RParenLoc = Loc; }
1968 TypeSourceInfo* getUnderlyingTInfo() const {
1969 return getLocalData()->UnderlyingTInfo;
1972 void setUnderlyingTInfo(TypeSourceInfo *TInfo) {
1973 getLocalData()->UnderlyingTInfo = TInfo;
1976 SourceRange getLocalSourceRange() const {
1977 return SourceRange(getKWLoc(), getRParenLoc());
1980 SourceRange getParensRange() const {
1981 return SourceRange(getLParenLoc(), getRParenLoc());
1984 void setParensRange(SourceRange Range) {
1985 setLParenLoc(Range.getBegin());
1986 setRParenLoc(Range.getEnd());
1989 void initializeLocal(ASTContext &Context, SourceLocation Loc);
1992 class DeducedTypeLoc
1993 : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, DeducedTypeLoc,
1996 struct AutoTypeLocInfo : TypeSpecLocInfo {
1997 NestedNameSpecifierLoc NestedNameSpec;
1998 SourceLocation TemplateKWLoc;
1999 SourceLocation ConceptNameLoc;
2000 NamedDecl *FoundDecl;
2001 SourceLocation LAngleLoc;
2002 SourceLocation RAngleLoc;
2006 : public ConcreteTypeLoc<DeducedTypeLoc,
2011 AutoTypeKeyword getAutoKeyword() const {
2012 return getTypePtr()->getKeyword();
2015 bool isConstrained() const {
2016 return getTypePtr()->isConstrained();
2019 const NestedNameSpecifierLoc &getNestedNameSpecifierLoc() const {
2020 return getLocalData()->NestedNameSpec;
2023 void setNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) {
2024 getLocalData()->NestedNameSpec = NNS;
2027 SourceLocation getTemplateKWLoc() const {
2028 return getLocalData()->TemplateKWLoc;
2031 void setTemplateKWLoc(SourceLocation Loc) {
2032 getLocalData()->TemplateKWLoc = Loc;
2035 SourceLocation getConceptNameLoc() const {
2036 return getLocalData()->ConceptNameLoc;
2039 void setConceptNameLoc(SourceLocation Loc) {
2040 getLocalData()->ConceptNameLoc = Loc;
2043 NamedDecl *getFoundDecl() const {
2044 return getLocalData()->FoundDecl;
2047 void setFoundDecl(NamedDecl *D) {
2048 getLocalData()->FoundDecl = D;
2051 ConceptDecl *getNamedConcept() const {
2052 return getTypePtr()->getTypeConstraintConcept();
2055 DeclarationNameInfo getConceptNameInfo() const;
2057 bool hasExplicitTemplateArgs() const {
2058 return getLocalData()->LAngleLoc.isValid();
2061 SourceLocation getLAngleLoc() const {
2062 return this->getLocalData()->LAngleLoc;
2065 void setLAngleLoc(SourceLocation Loc) {
2066 this->getLocalData()->LAngleLoc = Loc;
2069 SourceLocation getRAngleLoc() const {
2070 return this->getLocalData()->RAngleLoc;
2073 void setRAngleLoc(SourceLocation Loc) {
2074 this->getLocalData()->RAngleLoc = Loc;
2077 unsigned getNumArgs() const {
2078 return getTypePtr()->getNumArgs();
2081 void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) {
2082 getArgInfos()[i] = AI;
2085 TemplateArgumentLocInfo getArgLocInfo(unsigned i) const {
2086 return getArgInfos()[i];
2089 TemplateArgumentLoc getArgLoc(unsigned i) const {
2090 return TemplateArgumentLoc(getTypePtr()->getTypeConstraintArguments()[i],
2094 SourceRange getLocalSourceRange() const {
2097 ? (getNestedNameSpecifierLoc()
2098 ? getNestedNameSpecifierLoc().getBeginLoc()
2099 : (getTemplateKWLoc().isValid()
2100 ? getTemplateKWLoc()
2101 : getConceptNameLoc()))
2107 void copy(AutoTypeLoc Loc) {
2108 unsigned size = getFullDataSize();
2109 assert(size == Loc.getFullDataSize());
2110 memcpy(Data, Loc.Data, size);
2113 void initializeLocal(ASTContext &Context, SourceLocation Loc);
2115 unsigned getExtraLocalDataSize() const {
2116 return getNumArgs() * sizeof(TemplateArgumentLocInfo);
2119 unsigned getExtraLocalDataAlignment() const {
2120 return alignof(TemplateArgumentLocInfo);
2124 TemplateArgumentLocInfo *getArgInfos() const {
2125 return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData());
2129 class DeducedTemplateSpecializationTypeLoc
2130 : public InheritingConcreteTypeLoc<DeducedTypeLoc,
2131 DeducedTemplateSpecializationTypeLoc,
2132 DeducedTemplateSpecializationType> {
2134 SourceLocation getTemplateNameLoc() const {
2135 return getNameLoc();
2138 void setTemplateNameLoc(SourceLocation Loc) {
2143 struct ElaboratedLocInfo {
2144 SourceLocation ElaboratedKWLoc;
2146 /// Data associated with the nested-name-specifier location.
2147 void *QualifierData;
2150 class ElaboratedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
2153 ElaboratedLocInfo> {
2155 SourceLocation getElaboratedKeywordLoc() const {
2156 return this->getLocalData()->ElaboratedKWLoc;
2159 void setElaboratedKeywordLoc(SourceLocation Loc) {
2160 this->getLocalData()->ElaboratedKWLoc = Loc;
2163 NestedNameSpecifierLoc getQualifierLoc() const {
2164 return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
2165 getLocalData()->QualifierData);
2168 void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
2169 assert(QualifierLoc.getNestedNameSpecifier()
2170 == getTypePtr()->getQualifier() &&
2171 "Inconsistent nested-name-specifier pointer");
2172 getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
2175 SourceRange getLocalSourceRange() const {
2176 if (getElaboratedKeywordLoc().isValid())
2177 if (getQualifierLoc())
2178 return SourceRange(getElaboratedKeywordLoc(),
2179 getQualifierLoc().getEndLoc());
2181 return SourceRange(getElaboratedKeywordLoc());
2183 return getQualifierLoc().getSourceRange();
2186 void initializeLocal(ASTContext &Context, SourceLocation Loc);
2188 TypeLoc getNamedTypeLoc() const {
2189 return getInnerTypeLoc();
2192 QualType getInnerType() const {
2193 return getTypePtr()->getNamedType();
2196 void copy(ElaboratedTypeLoc Loc) {
2197 unsigned size = getFullDataSize();
2198 assert(size == Loc.getFullDataSize());
2199 memcpy(Data, Loc.Data, size);
2203 // This is exactly the structure of an ElaboratedTypeLoc whose inner
2204 // type is some sort of TypeDeclTypeLoc.
2205 struct DependentNameLocInfo : ElaboratedLocInfo {
2206 SourceLocation NameLoc;
2209 class DependentNameTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
2210 DependentNameTypeLoc,
2212 DependentNameLocInfo> {
2214 SourceLocation getElaboratedKeywordLoc() const {
2215 return this->getLocalData()->ElaboratedKWLoc;
2218 void setElaboratedKeywordLoc(SourceLocation Loc) {
2219 this->getLocalData()->ElaboratedKWLoc = Loc;
2222 NestedNameSpecifierLoc getQualifierLoc() const {
2223 return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
2224 getLocalData()->QualifierData);
2227 void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
2228 assert(QualifierLoc.getNestedNameSpecifier()
2229 == getTypePtr()->getQualifier() &&
2230 "Inconsistent nested-name-specifier pointer");
2231 getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
2234 SourceLocation getNameLoc() const {
2235 return this->getLocalData()->NameLoc;
2238 void setNameLoc(SourceLocation Loc) {
2239 this->getLocalData()->NameLoc = Loc;
2242 SourceRange getLocalSourceRange() const {
2243 if (getElaboratedKeywordLoc().isValid())
2244 return SourceRange(getElaboratedKeywordLoc(), getNameLoc());
2246 return SourceRange(getQualifierLoc().getBeginLoc(), getNameLoc());
2249 void copy(DependentNameTypeLoc Loc) {
2250 unsigned size = getFullDataSize();
2251 assert(size == Loc.getFullDataSize());
2252 memcpy(Data, Loc.Data, size);
2255 void initializeLocal(ASTContext &Context, SourceLocation Loc);
2258 struct DependentTemplateSpecializationLocInfo : DependentNameLocInfo {
2259 SourceLocation TemplateKWLoc;
2260 SourceLocation LAngleLoc;
2261 SourceLocation RAngleLoc;
2262 // followed by a TemplateArgumentLocInfo[]
2265 class DependentTemplateSpecializationTypeLoc :
2266 public ConcreteTypeLoc<UnqualTypeLoc,
2267 DependentTemplateSpecializationTypeLoc,
2268 DependentTemplateSpecializationType,
2269 DependentTemplateSpecializationLocInfo> {
2271 SourceLocation getElaboratedKeywordLoc() const {
2272 return this->getLocalData()->ElaboratedKWLoc;
2275 void setElaboratedKeywordLoc(SourceLocation Loc) {
2276 this->getLocalData()->ElaboratedKWLoc = Loc;
2279 NestedNameSpecifierLoc getQualifierLoc() const {
2280 if (!getLocalData()->QualifierData)
2281 return NestedNameSpecifierLoc();
2283 return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
2284 getLocalData()->QualifierData);
2287 void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
2288 if (!QualifierLoc) {
2289 // Even if we have a nested-name-specifier in the dependent
2290 // template specialization type, we won't record the nested-name-specifier
2291 // location information when this type-source location information is
2292 // part of a nested-name-specifier.
2293 getLocalData()->QualifierData = nullptr;
2297 assert(QualifierLoc.getNestedNameSpecifier()
2298 == getTypePtr()->getQualifier() &&
2299 "Inconsistent nested-name-specifier pointer");
2300 getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
2303 SourceLocation getTemplateKeywordLoc() const {
2304 return getLocalData()->TemplateKWLoc;
2307 void setTemplateKeywordLoc(SourceLocation Loc) {
2308 getLocalData()->TemplateKWLoc = Loc;
2311 SourceLocation getTemplateNameLoc() const {
2312 return this->getLocalData()->NameLoc;
2315 void setTemplateNameLoc(SourceLocation Loc) {
2316 this->getLocalData()->NameLoc = Loc;
2319 SourceLocation getLAngleLoc() const {
2320 return this->getLocalData()->LAngleLoc;
2323 void setLAngleLoc(SourceLocation Loc) {
2324 this->getLocalData()->LAngleLoc = Loc;
2327 SourceLocation getRAngleLoc() const {
2328 return this->getLocalData()->RAngleLoc;
2331 void setRAngleLoc(SourceLocation Loc) {
2332 this->getLocalData()->RAngleLoc = Loc;
2335 unsigned getNumArgs() const {
2336 return getTypePtr()->getNumArgs();
2339 void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) {
2340 getArgInfos()[i] = AI;
2343 TemplateArgumentLocInfo getArgLocInfo(unsigned i) const {
2344 return getArgInfos()[i];
2347 TemplateArgumentLoc getArgLoc(unsigned i) const {
2348 return TemplateArgumentLoc(getTypePtr()->getArg(i), getArgLocInfo(i));
2351 SourceRange getLocalSourceRange() const {
2352 if (getElaboratedKeywordLoc().isValid())
2353 return SourceRange(getElaboratedKeywordLoc(), getRAngleLoc());
2354 else if (getQualifierLoc())
2355 return SourceRange(getQualifierLoc().getBeginLoc(), getRAngleLoc());
2356 else if (getTemplateKeywordLoc().isValid())
2357 return SourceRange(getTemplateKeywordLoc(), getRAngleLoc());
2359 return SourceRange(getTemplateNameLoc(), getRAngleLoc());
2362 void copy(DependentTemplateSpecializationTypeLoc Loc) {
2363 unsigned size = getFullDataSize();
2364 assert(size == Loc.getFullDataSize());
2365 memcpy(Data, Loc.Data, size);
2368 void initializeLocal(ASTContext &Context, SourceLocation Loc);
2370 unsigned getExtraLocalDataSize() const {
2371 return getNumArgs() * sizeof(TemplateArgumentLocInfo);
2374 unsigned getExtraLocalDataAlignment() const {
2375 return alignof(TemplateArgumentLocInfo);
2379 TemplateArgumentLocInfo *getArgInfos() const {
2380 return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData());
2384 struct PackExpansionTypeLocInfo {
2385 SourceLocation EllipsisLoc;
2388 class PackExpansionTypeLoc
2389 : public ConcreteTypeLoc<UnqualTypeLoc, PackExpansionTypeLoc,
2390 PackExpansionType, PackExpansionTypeLocInfo> {
2392 SourceLocation getEllipsisLoc() const {
2393 return this->getLocalData()->EllipsisLoc;
2396 void setEllipsisLoc(SourceLocation Loc) {
2397 this->getLocalData()->EllipsisLoc = Loc;
2400 SourceRange getLocalSourceRange() const {
2401 return SourceRange(getEllipsisLoc(), getEllipsisLoc());
2404 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
2405 setEllipsisLoc(Loc);
2408 TypeLoc getPatternLoc() const {
2409 return getInnerTypeLoc();
2412 QualType getInnerType() const {
2413 return this->getTypePtr()->getPattern();
2417 struct AtomicTypeLocInfo {
2418 SourceLocation KWLoc, LParenLoc, RParenLoc;
2421 class AtomicTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, AtomicTypeLoc,
2422 AtomicType, AtomicTypeLocInfo> {
2424 TypeLoc getValueLoc() const {
2425 return this->getInnerTypeLoc();
2428 SourceRange getLocalSourceRange() const {
2429 return SourceRange(getKWLoc(), getRParenLoc());
2432 SourceLocation getKWLoc() const {
2433 return this->getLocalData()->KWLoc;
2436 void setKWLoc(SourceLocation Loc) {
2437 this->getLocalData()->KWLoc = Loc;
2440 SourceLocation getLParenLoc() const {
2441 return this->getLocalData()->LParenLoc;
2444 void setLParenLoc(SourceLocation Loc) {
2445 this->getLocalData()->LParenLoc = Loc;
2448 SourceLocation getRParenLoc() const {
2449 return this->getLocalData()->RParenLoc;
2452 void setRParenLoc(SourceLocation Loc) {
2453 this->getLocalData()->RParenLoc = Loc;
2456 SourceRange getParensRange() const {
2457 return SourceRange(getLParenLoc(), getRParenLoc());
2460 void setParensRange(SourceRange Range) {
2461 setLParenLoc(Range.getBegin());
2462 setRParenLoc(Range.getEnd());
2465 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
2471 QualType getInnerType() const {
2472 return this->getTypePtr()->getValueType();
2476 struct PipeTypeLocInfo {
2477 SourceLocation KWLoc;
2480 class PipeTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, PipeTypeLoc, PipeType,
2483 TypeLoc getValueLoc() const { return this->getInnerTypeLoc(); }
2485 SourceRange getLocalSourceRange() const { return SourceRange(getKWLoc()); }
2487 SourceLocation getKWLoc() const { return this->getLocalData()->KWLoc; }
2488 void setKWLoc(SourceLocation Loc) { this->getLocalData()->KWLoc = Loc; }
2490 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
2494 QualType getInnerType() const { return this->getTypePtr()->getElementType(); }
2497 template <typename T>
2498 inline T TypeLoc::getAsAdjusted() const {
2499 TypeLoc Cur = *this;
2500 while (!T::isKind(Cur)) {
2501 if (auto PTL = Cur.getAs<ParenTypeLoc>())
2502 Cur = PTL.getInnerLoc();
2503 else if (auto ATL = Cur.getAs<AttributedTypeLoc>())
2504 Cur = ATL.getModifiedLoc();
2505 else if (auto ETL = Cur.getAs<ElaboratedTypeLoc>())
2506 Cur = ETL.getNamedTypeLoc();
2507 else if (auto ATL = Cur.getAs<AdjustedTypeLoc>())
2508 Cur = ATL.getOriginalLoc();
2509 else if (auto MQL = Cur.getAs<MacroQualifiedTypeLoc>())
2510 Cur = MQL.getInnerLoc();
2514 return Cur.getAs<T>();
2516 class ExtIntTypeLoc final
2517 : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, ExtIntTypeLoc,
2519 class DependentExtIntTypeLoc final
2520 : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, DependentExtIntTypeLoc,
2521 DependentExtIntType> {};
2523 } // namespace clang
2525 #endif // LLVM_CLANG_AST_TYPELOC_H