1 //===--- TypeLoc.h - Type Source Info Wrapper -------------------*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file defines the TypeLoc interface and subclasses.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #ifndef LLVM_CLANG_AST_TYPELOC_H
15 #define LLVM_CLANG_AST_TYPELOC_H
16
17 #include "clang/AST/Decl.h"
18 #include "clang/AST/TemplateBase.h"
19 #include "clang/AST/Type.h"
20 #include "clang/Basic/Specifiers.h"
21 #include "llvm/Support/Compiler.h"
22
23 namespace clang {
24 class ASTContext;
25 class ParmVarDecl;
26 class TypeSourceInfo;
27 class UnqualTypeLoc;
28
29 // Predeclare all the type nodes.
30 #define ABSTRACT_TYPELOC(Class, Base)
31 #define TYPELOC(Class, Base) \
32 class Class##TypeLoc;
33 #include "clang/AST/TypeLocNodes.def"
34
35 /// \brief Base wrapper for a particular "section" of type source info.
36 ///
37 /// A client should use the TypeLoc subclasses through cast/dyn_cast in order to
38 /// get at the actual information.
39 class TypeLoc {
40 protected:
41 // The correctness of this relies on the property that, for Type *Ty,
42 // QualType(Ty, 0).getAsOpaquePtr() == (void*) Ty
43 const void *Ty;
44 void *Data;
45
46 public:
47 /// \brief Convert to the specified TypeLoc type, asserting that this TypeLoc
48 /// is of the desired type.
49 template<typename T>
castAs()50 T castAs() const {
51 assert(T::isKind(*this));
52 T t;
53 TypeLoc& tl = t;
54 tl = *this;
55 return t;
56 }
57
58 /// \brief Convert to the specified TypeLoc type, returning a null TypeLoc if
59 /// this TypeLoc is not of the desired type.
60 template<typename T>
getAs()61 T getAs() const {
62 if (!T::isKind(*this))
63 return T();
64 T t;
65 TypeLoc& tl = t;
66 tl = *this;
67 return t;
68 }
69
70 /// The kinds of TypeLocs. Equivalent to the Type::TypeClass enum,
71 /// except it also defines a Qualified enum that corresponds to the
72 /// QualifiedLoc class.
73 enum TypeLocClass {
74 #define ABSTRACT_TYPE(Class, Base)
75 #define TYPE(Class, Base) \
76 Class = Type::Class,
77 #include "clang/AST/TypeNodes.def"
78 Qualified
79 };
80
TypeLoc()81 TypeLoc() : Ty(0), Data(0) { }
TypeLoc(QualType ty,void * opaqueData)82 TypeLoc(QualType ty, void *opaqueData)
83 : Ty(ty.getAsOpaquePtr()), Data(opaqueData) { }
TypeLoc(const Type * ty,void * opaqueData)84 TypeLoc(const Type *ty, void *opaqueData)
85 : Ty(ty), Data(opaqueData) { }
86
getTypeLocClass()87 TypeLocClass getTypeLocClass() const {
88 if (getType().hasLocalQualifiers()) return Qualified;
89 return (TypeLocClass) getType()->getTypeClass();
90 }
91
isNull()92 bool isNull() const { return !Ty; }
93 LLVM_EXPLICIT operator bool() const { return Ty; }
94
95 /// \brief Returns the size of type source info data block for the given type.
96 static unsigned getFullDataSizeForType(QualType Ty);
97
98 /// \brief Returns the alignment of type source info data block for
99 /// the given type.
100 static unsigned getLocalAlignmentForType(QualType Ty);
101
102 /// \brief Get the type for which this source info wrapper provides
103 /// information.
getType()104 QualType getType() const {
105 return QualType::getFromOpaquePtr(Ty);
106 }
107
getTypePtr()108 const Type *getTypePtr() const {
109 return QualType::getFromOpaquePtr(Ty).getTypePtr();
110 }
111
112 /// \brief Get the pointer where source information is stored.
getOpaqueData()113 void *getOpaqueData() const {
114 return Data;
115 }
116
117 /// \brief Get the begin source location.
118 SourceLocation getBeginLoc() const;
119
120 /// \brief Get the end source location.
121 SourceLocation getEndLoc() const;
122
123 /// \brief Get the full source range.
getSourceRange()124 SourceRange getSourceRange() const LLVM_READONLY {
125 return SourceRange(getBeginLoc(), getEndLoc());
126 }
getLocStart()127 SourceLocation getLocStart() const LLVM_READONLY { return getBeginLoc(); }
getLocEnd()128 SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
129
130 /// \brief Get the local source range.
getLocalSourceRange()131 SourceRange getLocalSourceRange() const {
132 return getLocalSourceRangeImpl(*this);
133 }
134
135 /// \brief Returns the size of the type source info data block.
getFullDataSize()136 unsigned getFullDataSize() const {
137 return getFullDataSizeForType(getType());
138 }
139
140 /// \brief Get the next TypeLoc pointed by this TypeLoc, e.g for "int*" the
141 /// TypeLoc is a PointerLoc and next TypeLoc is for "int".
getNextTypeLoc()142 TypeLoc getNextTypeLoc() const {
143 return getNextTypeLocImpl(*this);
144 }
145
146 /// \brief Skips past any qualifiers, if this is qualified.
147 UnqualTypeLoc getUnqualifiedLoc() const; // implemented in this header
148
149 TypeLoc IgnoreParens() const;
150
151 /// \brief Initializes this to state that every location in this
152 /// type is the given location.
153 ///
154 /// This method exists to provide a simple transition for code that
155 /// relies on location-less types.
initialize(ASTContext & Context,SourceLocation Loc)156 void initialize(ASTContext &Context, SourceLocation Loc) const {
157 initializeImpl(Context, *this, Loc);
158 }
159
160 /// \brief Initializes this by copying its information from another
161 /// TypeLoc of the same type.
initializeFullCopy(TypeLoc Other)162 void initializeFullCopy(TypeLoc Other) const {
163 assert(getType() == Other.getType());
164 size_t Size = getFullDataSize();
165 memcpy(getOpaqueData(), Other.getOpaqueData(), Size);
166 }
167
168 /// \brief Initializes this by copying its information from another
169 /// TypeLoc of the same type. The given size must be the full data
170 /// size.
initializeFullCopy(TypeLoc Other,unsigned Size)171 void initializeFullCopy(TypeLoc Other, unsigned Size) const {
172 assert(getType() == Other.getType());
173 assert(getFullDataSize() == Size);
174 memcpy(getOpaqueData(), Other.getOpaqueData(), Size);
175 }
176
177 friend bool operator==(const TypeLoc &LHS, const TypeLoc &RHS) {
178 return LHS.Ty == RHS.Ty && LHS.Data == RHS.Data;
179 }
180
181 friend bool operator!=(const TypeLoc &LHS, const TypeLoc &RHS) {
182 return !(LHS == RHS);
183 }
184
185 private:
isKind(const TypeLoc &)186 static bool isKind(const TypeLoc&) {
187 return true;
188 }
189
190 static void initializeImpl(ASTContext &Context, TypeLoc TL,
191 SourceLocation Loc);
192 static TypeLoc getNextTypeLocImpl(TypeLoc TL);
193 static TypeLoc IgnoreParensImpl(TypeLoc TL);
194 static SourceRange getLocalSourceRangeImpl(TypeLoc TL);
195 };
196
197 /// \brief Return the TypeLoc for a type source info.
getTypeLoc()198 inline TypeLoc TypeSourceInfo::getTypeLoc() const {
199 return TypeLoc(Ty, const_cast<void*>(static_cast<const void*>(this + 1)));
200 }
201
202 /// \brief Wrapper of type source information for a type with
203 /// no direct qualifiers.
204 class UnqualTypeLoc : public TypeLoc {
205 public:
UnqualTypeLoc()206 UnqualTypeLoc() {}
UnqualTypeLoc(const Type * Ty,void * Data)207 UnqualTypeLoc(const Type *Ty, void *Data) : TypeLoc(Ty, Data) {}
208
getTypePtr()209 const Type *getTypePtr() const {
210 return reinterpret_cast<const Type*>(Ty);
211 }
212
getTypeLocClass()213 TypeLocClass getTypeLocClass() const {
214 return (TypeLocClass) getTypePtr()->getTypeClass();
215 }
216
217 private:
218 friend class TypeLoc;
isKind(const TypeLoc & TL)219 static bool isKind(const TypeLoc &TL) {
220 return !TL.getType().hasLocalQualifiers();
221 }
222 };
223
224 /// \brief Wrapper of type source information for a type with
225 /// non-trivial direct qualifiers.
226 ///
227 /// Currently, we intentionally do not provide source location for
228 /// type qualifiers.
229 class QualifiedTypeLoc : public TypeLoc {
230 public:
getLocalSourceRange()231 SourceRange getLocalSourceRange() const {
232 return SourceRange();
233 }
234
getUnqualifiedLoc()235 UnqualTypeLoc getUnqualifiedLoc() const {
236 unsigned align =
237 TypeLoc::getLocalAlignmentForType(QualType(getTypePtr(), 0));
238 uintptr_t dataInt = reinterpret_cast<uintptr_t>(Data);
239 dataInt = llvm::RoundUpToAlignment(dataInt, align);
240 return UnqualTypeLoc(getTypePtr(), reinterpret_cast<void*>(dataInt));
241 }
242
243 /// Initializes the local data of this type source info block to
244 /// provide no information.
initializeLocal(ASTContext & Context,SourceLocation Loc)245 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
246 // do nothing
247 }
248
getNextTypeLoc()249 TypeLoc getNextTypeLoc() const {
250 return getUnqualifiedLoc();
251 }
252
253 /// \brief Returns the size of the type source info data block that is
254 /// specific to this type.
getLocalDataSize()255 unsigned getLocalDataSize() const {
256 // In fact, we don't currently preserve any location information
257 // for qualifiers.
258 return 0;
259 }
260
261 /// \brief Returns the alignment of the type source info data block that is
262 /// specific to this type.
getLocalDataAlignment()263 unsigned getLocalDataAlignment() const {
264 // We don't preserve any location information.
265 return 1;
266 }
267
268 private:
269 friend class TypeLoc;
isKind(const TypeLoc & TL)270 static bool isKind(const TypeLoc &TL) {
271 return TL.getType().hasLocalQualifiers();
272 }
273 };
274
getUnqualifiedLoc()275 inline UnqualTypeLoc TypeLoc::getUnqualifiedLoc() const {
276 if (QualifiedTypeLoc Loc = getAs<QualifiedTypeLoc>())
277 return Loc.getUnqualifiedLoc();
278 return castAs<UnqualTypeLoc>();
279 }
280
281 /// A metaprogramming base class for TypeLoc classes which correspond
282 /// to a particular Type subclass. It is accepted for a single
283 /// TypeLoc class to correspond to multiple Type classes.
284 ///
285 /// \tparam Base a class from which to derive
286 /// \tparam Derived the class deriving from this one
287 /// \tparam TypeClass the concrete Type subclass associated with this
288 /// location type
289 /// \tparam LocalData the structure type of local location data for
290 /// this type
291 ///
292 /// TypeLocs with non-constant amounts of local data should override
293 /// getExtraLocalDataSize(); getExtraLocalData() will then point to
294 /// this extra memory.
295 ///
296 /// TypeLocs with an inner type should define
297 /// QualType getInnerType() const
298 /// and getInnerTypeLoc() will then point to this inner type's
299 /// location data.
300 ///
301 /// A word about hierarchies: this template is not designed to be
302 /// derived from multiple times in a hierarchy. It is also not
303 /// designed to be used for classes where subtypes might provide
304 /// different amounts of source information. It should be subclassed
305 /// only at the deepest portion of the hierarchy where all children
306 /// have identical source information; if that's an abstract type,
307 /// then further descendents should inherit from
308 /// InheritingConcreteTypeLoc instead.
309 template <class Base, class Derived, class TypeClass, class LocalData>
310 class ConcreteTypeLoc : public Base {
311
asDerived()312 const Derived *asDerived() const {
313 return static_cast<const Derived*>(this);
314 }
315
316 friend class TypeLoc;
isKind(const TypeLoc & TL)317 static bool isKind(const TypeLoc &TL) {
318 return !TL.getType().hasLocalQualifiers() &&
319 Derived::classofType(TL.getTypePtr());
320 }
321
classofType(const Type * Ty)322 static bool classofType(const Type *Ty) {
323 return TypeClass::classof(Ty);
324 }
325
326 public:
getLocalDataAlignment()327 unsigned getLocalDataAlignment() const {
328 return std::max(llvm::alignOf<LocalData>(),
329 asDerived()->getExtraLocalDataAlignment());
330 }
getLocalDataSize()331 unsigned getLocalDataSize() const {
332 unsigned size = sizeof(LocalData);
333 unsigned extraAlign = asDerived()->getExtraLocalDataAlignment();
334 size = llvm::RoundUpToAlignment(size, extraAlign);
335 size += asDerived()->getExtraLocalDataSize();
336 return size;
337 }
338
getNextTypeLoc()339 TypeLoc getNextTypeLoc() const {
340 return getNextTypeLoc(asDerived()->getInnerType());
341 }
342
getTypePtr()343 const TypeClass *getTypePtr() const {
344 return cast<TypeClass>(Base::getTypePtr());
345 }
346
347 protected:
getExtraLocalDataSize()348 unsigned getExtraLocalDataSize() const {
349 return 0;
350 }
351
getExtraLocalDataAlignment()352 unsigned getExtraLocalDataAlignment() const {
353 return 1;
354 }
355
getLocalData()356 LocalData *getLocalData() const {
357 return static_cast<LocalData*>(Base::Data);
358 }
359
360 /// Gets a pointer past the Info structure; useful for classes with
361 /// local data that can't be captured in the Info (e.g. because it's
362 /// of variable size).
getExtraLocalData()363 void *getExtraLocalData() const {
364 unsigned size = sizeof(LocalData);
365 unsigned extraAlign = asDerived()->getExtraLocalDataAlignment();
366 size = llvm::RoundUpToAlignment(size, extraAlign);
367 return reinterpret_cast<char*>(Base::Data) + size;
368 }
369
getNonLocalData()370 void *getNonLocalData() const {
371 uintptr_t data = reinterpret_cast<uintptr_t>(Base::Data);
372 data += asDerived()->getLocalDataSize();
373 data = llvm::RoundUpToAlignment(data, getNextTypeAlign());
374 return reinterpret_cast<void*>(data);
375 }
376
377 struct HasNoInnerType {};
getInnerType()378 HasNoInnerType getInnerType() const { return HasNoInnerType(); }
379
getInnerTypeLoc()380 TypeLoc getInnerTypeLoc() const {
381 return TypeLoc(asDerived()->getInnerType(), getNonLocalData());
382 }
383
384 private:
getInnerTypeSize()385 unsigned getInnerTypeSize() const {
386 return getInnerTypeSize(asDerived()->getInnerType());
387 }
388
getInnerTypeSize(HasNoInnerType _)389 unsigned getInnerTypeSize(HasNoInnerType _) const {
390 return 0;
391 }
392
getInnerTypeSize(QualType _)393 unsigned getInnerTypeSize(QualType _) const {
394 return getInnerTypeLoc().getFullDataSize();
395 }
396
getNextTypeAlign()397 unsigned getNextTypeAlign() const {
398 return getNextTypeAlign(asDerived()->getInnerType());
399 }
400
getNextTypeAlign(HasNoInnerType _)401 unsigned getNextTypeAlign(HasNoInnerType _) const {
402 return 1;
403 }
404
getNextTypeAlign(QualType T)405 unsigned getNextTypeAlign(QualType T) const {
406 return TypeLoc::getLocalAlignmentForType(T);
407 }
408
getNextTypeLoc(HasNoInnerType _)409 TypeLoc getNextTypeLoc(HasNoInnerType _) const {
410 return TypeLoc();
411 }
412
getNextTypeLoc(QualType T)413 TypeLoc getNextTypeLoc(QualType T) const {
414 return TypeLoc(T, getNonLocalData());
415 }
416 };
417
418 /// A metaprogramming class designed for concrete subtypes of abstract
419 /// types where all subtypes share equivalently-structured source
420 /// information. See the note on ConcreteTypeLoc.
421 template <class Base, class Derived, class TypeClass>
422 class InheritingConcreteTypeLoc : public Base {
423 friend class TypeLoc;
classofType(const Type * Ty)424 static bool classofType(const Type *Ty) {
425 return TypeClass::classof(Ty);
426 }
427
isKind(const TypeLoc & TL)428 static bool isKind(const TypeLoc &TL) {
429 return !TL.getType().hasLocalQualifiers() &&
430 Derived::classofType(TL.getTypePtr());
431 }
isKind(const UnqualTypeLoc & TL)432 static bool isKind(const UnqualTypeLoc &TL) {
433 return Derived::classofType(TL.getTypePtr());
434 }
435
436 public:
getTypePtr()437 const TypeClass *getTypePtr() const {
438 return cast<TypeClass>(Base::getTypePtr());
439 }
440 };
441
442
443 struct TypeSpecLocInfo {
444 SourceLocation NameLoc;
445 };
446
447 /// \brief A reasonable base class for TypeLocs that correspond to
448 /// types that are written as a type-specifier.
449 class TypeSpecTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
450 TypeSpecTypeLoc,
451 Type,
452 TypeSpecLocInfo> {
453 public:
454 enum { LocalDataSize = sizeof(TypeSpecLocInfo),
455 LocalDataAlignment = llvm::AlignOf<TypeSpecLocInfo>::Alignment };
456
getNameLoc()457 SourceLocation getNameLoc() const {
458 return this->getLocalData()->NameLoc;
459 }
setNameLoc(SourceLocation Loc)460 void setNameLoc(SourceLocation Loc) {
461 this->getLocalData()->NameLoc = Loc;
462 }
getLocalSourceRange()463 SourceRange getLocalSourceRange() const {
464 return SourceRange(getNameLoc(), getNameLoc());
465 }
initializeLocal(ASTContext & Context,SourceLocation Loc)466 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
467 setNameLoc(Loc);
468 }
469
470 private:
471 friend class TypeLoc;
472 static bool isKind(const TypeLoc &TL);
473 };
474
475
476 struct BuiltinLocInfo {
477 SourceLocation BuiltinLoc;
478 };
479
480 /// \brief Wrapper for source info for builtin types.
481 class BuiltinTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
482 BuiltinTypeLoc,
483 BuiltinType,
484 BuiltinLocInfo> {
485 public:
getBuiltinLoc()486 SourceLocation getBuiltinLoc() const {
487 return getLocalData()->BuiltinLoc;
488 }
setBuiltinLoc(SourceLocation Loc)489 void setBuiltinLoc(SourceLocation Loc) {
490 getLocalData()->BuiltinLoc = Loc;
491 }
492
getNameLoc()493 SourceLocation getNameLoc() const { return getBuiltinLoc(); }
494
getWrittenBuiltinSpecs()495 WrittenBuiltinSpecs& getWrittenBuiltinSpecs() {
496 return *(static_cast<WrittenBuiltinSpecs*>(getExtraLocalData()));
497 }
getWrittenBuiltinSpecs()498 const WrittenBuiltinSpecs& getWrittenBuiltinSpecs() const {
499 return *(static_cast<WrittenBuiltinSpecs*>(getExtraLocalData()));
500 }
501
needsExtraLocalData()502 bool needsExtraLocalData() const {
503 BuiltinType::Kind bk = getTypePtr()->getKind();
504 return (bk >= BuiltinType::UShort && bk <= BuiltinType::UInt128)
505 || (bk >= BuiltinType::Short && bk <= BuiltinType::LongDouble)
506 || bk == BuiltinType::UChar
507 || bk == BuiltinType::SChar;
508 }
509
getExtraLocalDataSize()510 unsigned getExtraLocalDataSize() const {
511 return needsExtraLocalData() ? sizeof(WrittenBuiltinSpecs) : 0;
512 }
513
getExtraLocalDataAlignment()514 unsigned getExtraLocalDataAlignment() const {
515 return needsExtraLocalData() ? llvm::alignOf<WrittenBuiltinSpecs>() : 1;
516 }
517
getLocalSourceRange()518 SourceRange getLocalSourceRange() const {
519 return SourceRange(getBuiltinLoc(), getBuiltinLoc());
520 }
521
getWrittenSignSpec()522 TypeSpecifierSign getWrittenSignSpec() const {
523 if (needsExtraLocalData())
524 return static_cast<TypeSpecifierSign>(getWrittenBuiltinSpecs().Sign);
525 else
526 return TSS_unspecified;
527 }
hasWrittenSignSpec()528 bool hasWrittenSignSpec() const {
529 return getWrittenSignSpec() != TSS_unspecified;
530 }
setWrittenSignSpec(TypeSpecifierSign written)531 void setWrittenSignSpec(TypeSpecifierSign written) {
532 if (needsExtraLocalData())
533 getWrittenBuiltinSpecs().Sign = written;
534 }
535
getWrittenWidthSpec()536 TypeSpecifierWidth getWrittenWidthSpec() const {
537 if (needsExtraLocalData())
538 return static_cast<TypeSpecifierWidth>(getWrittenBuiltinSpecs().Width);
539 else
540 return TSW_unspecified;
541 }
hasWrittenWidthSpec()542 bool hasWrittenWidthSpec() const {
543 return getWrittenWidthSpec() != TSW_unspecified;
544 }
setWrittenWidthSpec(TypeSpecifierWidth written)545 void setWrittenWidthSpec(TypeSpecifierWidth written) {
546 if (needsExtraLocalData())
547 getWrittenBuiltinSpecs().Width = written;
548 }
549
550 TypeSpecifierType getWrittenTypeSpec() const;
hasWrittenTypeSpec()551 bool hasWrittenTypeSpec() const {
552 return getWrittenTypeSpec() != TST_unspecified;
553 }
setWrittenTypeSpec(TypeSpecifierType written)554 void setWrittenTypeSpec(TypeSpecifierType written) {
555 if (needsExtraLocalData())
556 getWrittenBuiltinSpecs().Type = written;
557 }
558
hasModeAttr()559 bool hasModeAttr() const {
560 if (needsExtraLocalData())
561 return getWrittenBuiltinSpecs().ModeAttr;
562 else
563 return false;
564 }
setModeAttr(bool written)565 void setModeAttr(bool written) {
566 if (needsExtraLocalData())
567 getWrittenBuiltinSpecs().ModeAttr = written;
568 }
569
initializeLocal(ASTContext & Context,SourceLocation Loc)570 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
571 setBuiltinLoc(Loc);
572 if (needsExtraLocalData()) {
573 WrittenBuiltinSpecs &wbs = getWrittenBuiltinSpecs();
574 wbs.Sign = TSS_unspecified;
575 wbs.Width = TSW_unspecified;
576 wbs.Type = TST_unspecified;
577 wbs.ModeAttr = false;
578 }
579 }
580 };
581
582
583 /// \brief Wrapper for source info for typedefs.
584 class TypedefTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
585 TypedefTypeLoc,
586 TypedefType> {
587 public:
getTypedefNameDecl()588 TypedefNameDecl *getTypedefNameDecl() const {
589 return getTypePtr()->getDecl();
590 }
591 };
592
593 /// \brief Wrapper for source info for injected class names of class
594 /// templates.
595 class InjectedClassNameTypeLoc :
596 public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
597 InjectedClassNameTypeLoc,
598 InjectedClassNameType> {
599 public:
getDecl()600 CXXRecordDecl *getDecl() const {
601 return getTypePtr()->getDecl();
602 }
603 };
604
605 /// \brief Wrapper for source info for unresolved typename using decls.
606 class UnresolvedUsingTypeLoc :
607 public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
608 UnresolvedUsingTypeLoc,
609 UnresolvedUsingType> {
610 public:
getDecl()611 UnresolvedUsingTypenameDecl *getDecl() const {
612 return getTypePtr()->getDecl();
613 }
614 };
615
616 /// \brief Wrapper for source info for tag types. Note that this only
617 /// records source info for the name itself; a type written 'struct foo'
618 /// should be represented as an ElaboratedTypeLoc. We currently
619 /// only do that when C++ is enabled because of the expense of
620 /// creating an ElaboratedType node for so many type references in C.
621 class TagTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
622 TagTypeLoc,
623 TagType> {
624 public:
getDecl()625 TagDecl *getDecl() const { return getTypePtr()->getDecl(); }
626
627 /// \brief True if the tag was defined in this type specifier.
isDefinition()628 bool isDefinition() const {
629 TagDecl *D = getDecl();
630 return D->isCompleteDefinition() &&
631 (D->getIdentifier() == 0 || D->getLocation() == getNameLoc());
632 }
633 };
634
635 /// \brief Wrapper for source info for record types.
636 class RecordTypeLoc : public InheritingConcreteTypeLoc<TagTypeLoc,
637 RecordTypeLoc,
638 RecordType> {
639 public:
getDecl()640 RecordDecl *getDecl() const { return getTypePtr()->getDecl(); }
641 };
642
643 /// \brief Wrapper for source info for enum types.
644 class EnumTypeLoc : public InheritingConcreteTypeLoc<TagTypeLoc,
645 EnumTypeLoc,
646 EnumType> {
647 public:
getDecl()648 EnumDecl *getDecl() const { return getTypePtr()->getDecl(); }
649 };
650
651 /// \brief Wrapper for template type parameters.
652 class TemplateTypeParmTypeLoc :
653 public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
654 TemplateTypeParmTypeLoc,
655 TemplateTypeParmType> {
656 public:
getDecl()657 TemplateTypeParmDecl *getDecl() const { return getTypePtr()->getDecl(); }
658 };
659
660 /// \brief Wrapper for substituted template type parameters.
661 class SubstTemplateTypeParmTypeLoc :
662 public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
663 SubstTemplateTypeParmTypeLoc,
664 SubstTemplateTypeParmType> {
665 };
666
667 /// \brief Wrapper for substituted template type parameters.
668 class SubstTemplateTypeParmPackTypeLoc :
669 public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
670 SubstTemplateTypeParmPackTypeLoc,
671 SubstTemplateTypeParmPackType> {
672 };
673
674 struct AttributedLocInfo {
675 union {
676 Expr *ExprOperand;
677
678 /// A raw SourceLocation.
679 unsigned EnumOperandLoc;
680 };
681
682 SourceRange OperandParens;
683
684 SourceLocation AttrLoc;
685 };
686
687 /// \brief Type source information for an attributed type.
688 class AttributedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
689 AttributedTypeLoc,
690 AttributedType,
691 AttributedLocInfo> {
692 public:
getAttrKind()693 AttributedType::Kind getAttrKind() const {
694 return getTypePtr()->getAttrKind();
695 }
696
hasAttrExprOperand()697 bool hasAttrExprOperand() const {
698 return (getAttrKind() >= AttributedType::FirstExprOperandKind &&
699 getAttrKind() <= AttributedType::LastExprOperandKind);
700 }
701
hasAttrEnumOperand()702 bool hasAttrEnumOperand() const {
703 return (getAttrKind() >= AttributedType::FirstEnumOperandKind &&
704 getAttrKind() <= AttributedType::LastEnumOperandKind);
705 }
706
hasAttrOperand()707 bool hasAttrOperand() const {
708 return hasAttrExprOperand() || hasAttrEnumOperand();
709 }
710
711 /// The modified type, which is generally canonically different from
712 /// the attribute type.
713 /// int main(int, char**) __attribute__((noreturn))
714 /// ~~~ ~~~~~~~~~~~~~
getModifiedLoc()715 TypeLoc getModifiedLoc() const {
716 return getInnerTypeLoc();
717 }
718
719 /// The location of the attribute name, i.e.
720 /// __attribute__((regparm(1000)))
721 /// ^~~~~~~
getAttrNameLoc()722 SourceLocation getAttrNameLoc() const {
723 return getLocalData()->AttrLoc;
724 }
setAttrNameLoc(SourceLocation loc)725 void setAttrNameLoc(SourceLocation loc) {
726 getLocalData()->AttrLoc = loc;
727 }
728
729 /// The attribute's expression operand, if it has one.
730 /// void *cur_thread __attribute__((address_space(21)))
731 /// ^~
getAttrExprOperand()732 Expr *getAttrExprOperand() const {
733 assert(hasAttrExprOperand());
734 return getLocalData()->ExprOperand;
735 }
setAttrExprOperand(Expr * e)736 void setAttrExprOperand(Expr *e) {
737 assert(hasAttrExprOperand());
738 getLocalData()->ExprOperand = e;
739 }
740
741 /// The location of the attribute's enumerated operand, if it has one.
742 /// void * __attribute__((objc_gc(weak)))
743 /// ^~~~
getAttrEnumOperandLoc()744 SourceLocation getAttrEnumOperandLoc() const {
745 assert(hasAttrEnumOperand());
746 return SourceLocation::getFromRawEncoding(getLocalData()->EnumOperandLoc);
747 }
setAttrEnumOperandLoc(SourceLocation loc)748 void setAttrEnumOperandLoc(SourceLocation loc) {
749 assert(hasAttrEnumOperand());
750 getLocalData()->EnumOperandLoc = loc.getRawEncoding();
751 }
752
753 /// The location of the parentheses around the operand, if there is
754 /// an operand.
755 /// void * __attribute__((objc_gc(weak)))
756 /// ^ ^
getAttrOperandParensRange()757 SourceRange getAttrOperandParensRange() const {
758 assert(hasAttrOperand());
759 return getLocalData()->OperandParens;
760 }
setAttrOperandParensRange(SourceRange range)761 void setAttrOperandParensRange(SourceRange range) {
762 assert(hasAttrOperand());
763 getLocalData()->OperandParens = range;
764 }
765
getLocalSourceRange()766 SourceRange getLocalSourceRange() const {
767 // Note that this does *not* include the range of the attribute
768 // enclosure, e.g.:
769 // __attribute__((foo(bar)))
770 // ^~~~~~~~~~~~~~~ ~~
771 // or
772 // [[foo(bar)]]
773 // ^~ ~~
774 // That enclosure doesn't necessarily belong to a single attribute
775 // anyway.
776 SourceRange range(getAttrNameLoc());
777 if (hasAttrOperand())
778 range.setEnd(getAttrOperandParensRange().getEnd());
779 return range;
780 }
781
initializeLocal(ASTContext & Context,SourceLocation loc)782 void initializeLocal(ASTContext &Context, SourceLocation loc) {
783 setAttrNameLoc(loc);
784 if (hasAttrExprOperand()) {
785 setAttrOperandParensRange(SourceRange(loc));
786 setAttrExprOperand(0);
787 } else if (hasAttrEnumOperand()) {
788 setAttrOperandParensRange(SourceRange(loc));
789 setAttrEnumOperandLoc(loc);
790 }
791 }
792
getInnerType()793 QualType getInnerType() const {
794 return getTypePtr()->getModifiedType();
795 }
796 };
797
798
799 struct ObjCProtocolListLocInfo {
800 SourceLocation LAngleLoc;
801 SourceLocation RAngleLoc;
802 bool HasBaseTypeAsWritten;
803 };
804
805 // A helper class for defining ObjC TypeLocs that can qualified with
806 // protocols.
807 //
808 // TypeClass basically has to be either ObjCInterfaceType or
809 // ObjCObjectPointerType.
810 class ObjCObjectTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
811 ObjCObjectTypeLoc,
812 ObjCObjectType,
813 ObjCProtocolListLocInfo> {
814 // SourceLocations are stored after Info, one for each Protocol.
getProtocolLocArray()815 SourceLocation *getProtocolLocArray() const {
816 return (SourceLocation*) this->getExtraLocalData();
817 }
818
819 public:
getLAngleLoc()820 SourceLocation getLAngleLoc() const {
821 return this->getLocalData()->LAngleLoc;
822 }
setLAngleLoc(SourceLocation Loc)823 void setLAngleLoc(SourceLocation Loc) {
824 this->getLocalData()->LAngleLoc = Loc;
825 }
826
getRAngleLoc()827 SourceLocation getRAngleLoc() const {
828 return this->getLocalData()->RAngleLoc;
829 }
setRAngleLoc(SourceLocation Loc)830 void setRAngleLoc(SourceLocation Loc) {
831 this->getLocalData()->RAngleLoc = Loc;
832 }
833
getNumProtocols()834 unsigned getNumProtocols() const {
835 return this->getTypePtr()->getNumProtocols();
836 }
837
getProtocolLoc(unsigned i)838 SourceLocation getProtocolLoc(unsigned i) const {
839 assert(i < getNumProtocols() && "Index is out of bounds!");
840 return getProtocolLocArray()[i];
841 }
setProtocolLoc(unsigned i,SourceLocation Loc)842 void setProtocolLoc(unsigned i, SourceLocation Loc) {
843 assert(i < getNumProtocols() && "Index is out of bounds!");
844 getProtocolLocArray()[i] = Loc;
845 }
846
getProtocol(unsigned i)847 ObjCProtocolDecl *getProtocol(unsigned i) const {
848 assert(i < getNumProtocols() && "Index is out of bounds!");
849 return *(this->getTypePtr()->qual_begin() + i);
850 }
851
hasBaseTypeAsWritten()852 bool hasBaseTypeAsWritten() const {
853 return getLocalData()->HasBaseTypeAsWritten;
854 }
855
setHasBaseTypeAsWritten(bool HasBaseType)856 void setHasBaseTypeAsWritten(bool HasBaseType) {
857 getLocalData()->HasBaseTypeAsWritten = HasBaseType;
858 }
859
getBaseLoc()860 TypeLoc getBaseLoc() const {
861 return getInnerTypeLoc();
862 }
863
getLocalSourceRange()864 SourceRange getLocalSourceRange() const {
865 return SourceRange(getLAngleLoc(), getRAngleLoc());
866 }
867
initializeLocal(ASTContext & Context,SourceLocation Loc)868 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
869 setHasBaseTypeAsWritten(true);
870 setLAngleLoc(Loc);
871 setRAngleLoc(Loc);
872 for (unsigned i = 0, e = getNumProtocols(); i != e; ++i)
873 setProtocolLoc(i, Loc);
874 }
875
getExtraLocalDataSize()876 unsigned getExtraLocalDataSize() const {
877 return this->getNumProtocols() * sizeof(SourceLocation);
878 }
879
getExtraLocalDataAlignment()880 unsigned getExtraLocalDataAlignment() const {
881 return llvm::alignOf<SourceLocation>();
882 }
883
getInnerType()884 QualType getInnerType() const {
885 return getTypePtr()->getBaseType();
886 }
887 };
888
889
890 struct ObjCInterfaceLocInfo {
891 SourceLocation NameLoc;
892 SourceLocation NameEndLoc;
893 };
894
895 /// \brief Wrapper for source info for ObjC interfaces.
896 class ObjCInterfaceTypeLoc : public ConcreteTypeLoc<ObjCObjectTypeLoc,
897 ObjCInterfaceTypeLoc,
898 ObjCInterfaceType,
899 ObjCInterfaceLocInfo> {
900 public:
getIFaceDecl()901 ObjCInterfaceDecl *getIFaceDecl() const {
902 return getTypePtr()->getDecl();
903 }
904
getNameLoc()905 SourceLocation getNameLoc() const {
906 return getLocalData()->NameLoc;
907 }
908
setNameLoc(SourceLocation Loc)909 void setNameLoc(SourceLocation Loc) {
910 getLocalData()->NameLoc = Loc;
911 }
912
getLocalSourceRange()913 SourceRange getLocalSourceRange() const {
914 return SourceRange(getNameLoc(), getNameEndLoc());
915 }
916
getNameEndLoc()917 SourceLocation getNameEndLoc() const {
918 return getLocalData()->NameEndLoc;
919 }
920
setNameEndLoc(SourceLocation Loc)921 void setNameEndLoc(SourceLocation Loc) {
922 getLocalData()->NameEndLoc = Loc;
923 }
924
initializeLocal(ASTContext & Context,SourceLocation Loc)925 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
926 setNameLoc(Loc);
927 setNameEndLoc(Loc);
928 }
929 };
930
931 struct ParenLocInfo {
932 SourceLocation LParenLoc;
933 SourceLocation RParenLoc;
934 };
935
936 class ParenTypeLoc
937 : public ConcreteTypeLoc<UnqualTypeLoc, ParenTypeLoc, ParenType,
938 ParenLocInfo> {
939 public:
getLParenLoc()940 SourceLocation getLParenLoc() const {
941 return this->getLocalData()->LParenLoc;
942 }
getRParenLoc()943 SourceLocation getRParenLoc() const {
944 return this->getLocalData()->RParenLoc;
945 }
setLParenLoc(SourceLocation Loc)946 void setLParenLoc(SourceLocation Loc) {
947 this->getLocalData()->LParenLoc = Loc;
948 }
setRParenLoc(SourceLocation Loc)949 void setRParenLoc(SourceLocation Loc) {
950 this->getLocalData()->RParenLoc = Loc;
951 }
952
getLocalSourceRange()953 SourceRange getLocalSourceRange() const {
954 return SourceRange(getLParenLoc(), getRParenLoc());
955 }
956
initializeLocal(ASTContext & Context,SourceLocation Loc)957 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
958 setLParenLoc(Loc);
959 setRParenLoc(Loc);
960 }
961
getInnerLoc()962 TypeLoc getInnerLoc() const {
963 return getInnerTypeLoc();
964 }
965
getInnerType()966 QualType getInnerType() const {
967 return this->getTypePtr()->getInnerType();
968 }
969 };
970
IgnoreParens()971 inline TypeLoc TypeLoc::IgnoreParens() const {
972 if (ParenTypeLoc::isKind(*this))
973 return IgnoreParensImpl(*this);
974 return *this;
975 }
976
977
978 struct DecayedLocInfo { }; // Nothing.
979
980 /// \brief Wrapper for source info for pointers decayed from arrays and
981 /// functions.
982 class DecayedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, DecayedTypeLoc,
983 DecayedType, DecayedLocInfo> {
984 public:
getOriginalLoc()985 TypeLoc getOriginalLoc() const {
986 return getInnerTypeLoc();
987 }
988
initializeLocal(ASTContext & Context,SourceLocation Loc)989 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
990 // do nothing
991 }
992
getInnerType()993 QualType getInnerType() const {
994 // The inner type is the undecayed type, since that's what we have source
995 // location information for.
996 return getTypePtr()->getOriginalType();
997 }
998
getLocalSourceRange()999 SourceRange getLocalSourceRange() const {
1000 return SourceRange();
1001 }
1002
getLocalDataSize()1003 unsigned getLocalDataSize() const {
1004 // sizeof(DecayedLocInfo) is 1, but we don't need its address to be unique
1005 // anyway. TypeLocBuilder can't handle data sizes of 1.
1006 return 0; // No data.
1007 }
1008 };
1009
1010
1011 struct PointerLikeLocInfo {
1012 SourceLocation StarLoc;
1013 };
1014
1015 /// A base class for
1016 template <class Derived, class TypeClass, class LocalData = PointerLikeLocInfo>
1017 class PointerLikeTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, Derived,
1018 TypeClass, LocalData> {
1019 public:
getSigilLoc()1020 SourceLocation getSigilLoc() const {
1021 return this->getLocalData()->StarLoc;
1022 }
setSigilLoc(SourceLocation Loc)1023 void setSigilLoc(SourceLocation Loc) {
1024 this->getLocalData()->StarLoc = Loc;
1025 }
1026
getPointeeLoc()1027 TypeLoc getPointeeLoc() const {
1028 return this->getInnerTypeLoc();
1029 }
1030
getLocalSourceRange()1031 SourceRange getLocalSourceRange() const {
1032 return SourceRange(getSigilLoc(), getSigilLoc());
1033 }
1034
initializeLocal(ASTContext & Context,SourceLocation Loc)1035 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1036 setSigilLoc(Loc);
1037 }
1038
getInnerType()1039 QualType getInnerType() const {
1040 return this->getTypePtr()->getPointeeType();
1041 }
1042 };
1043
1044
1045 /// \brief Wrapper for source info for pointers.
1046 class PointerTypeLoc : public PointerLikeTypeLoc<PointerTypeLoc,
1047 PointerType> {
1048 public:
getStarLoc()1049 SourceLocation getStarLoc() const {
1050 return getSigilLoc();
1051 }
setStarLoc(SourceLocation Loc)1052 void setStarLoc(SourceLocation Loc) {
1053 setSigilLoc(Loc);
1054 }
1055 };
1056
1057
1058 /// \brief Wrapper for source info for block pointers.
1059 class BlockPointerTypeLoc : public PointerLikeTypeLoc<BlockPointerTypeLoc,
1060 BlockPointerType> {
1061 public:
getCaretLoc()1062 SourceLocation getCaretLoc() const {
1063 return getSigilLoc();
1064 }
setCaretLoc(SourceLocation Loc)1065 void setCaretLoc(SourceLocation Loc) {
1066 setSigilLoc(Loc);
1067 }
1068 };
1069
1070 struct MemberPointerLocInfo : public PointerLikeLocInfo {
1071 TypeSourceInfo *ClassTInfo;
1072 };
1073
1074 /// \brief Wrapper for source info for member pointers.
1075 class MemberPointerTypeLoc : public PointerLikeTypeLoc<MemberPointerTypeLoc,
1076 MemberPointerType,
1077 MemberPointerLocInfo> {
1078 public:
getStarLoc()1079 SourceLocation getStarLoc() const {
1080 return getSigilLoc();
1081 }
setStarLoc(SourceLocation Loc)1082 void setStarLoc(SourceLocation Loc) {
1083 setSigilLoc(Loc);
1084 }
1085
getClass()1086 const Type *getClass() const {
1087 return getTypePtr()->getClass();
1088 }
getClassTInfo()1089 TypeSourceInfo *getClassTInfo() const {
1090 return getLocalData()->ClassTInfo;
1091 }
setClassTInfo(TypeSourceInfo * TI)1092 void setClassTInfo(TypeSourceInfo* TI) {
1093 getLocalData()->ClassTInfo = TI;
1094 }
1095
initializeLocal(ASTContext & Context,SourceLocation Loc)1096 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1097 setSigilLoc(Loc);
1098 setClassTInfo(0);
1099 }
1100
getLocalSourceRange()1101 SourceRange getLocalSourceRange() const {
1102 if (TypeSourceInfo *TI = getClassTInfo())
1103 return SourceRange(TI->getTypeLoc().getBeginLoc(), getStarLoc());
1104 else
1105 return SourceRange(getStarLoc());
1106 }
1107 };
1108
1109 /// Wraps an ObjCPointerType with source location information.
1110 class ObjCObjectPointerTypeLoc :
1111 public PointerLikeTypeLoc<ObjCObjectPointerTypeLoc,
1112 ObjCObjectPointerType> {
1113 public:
getStarLoc()1114 SourceLocation getStarLoc() const {
1115 return getSigilLoc();
1116 }
1117
setStarLoc(SourceLocation Loc)1118 void setStarLoc(SourceLocation Loc) {
1119 setSigilLoc(Loc);
1120 }
1121 };
1122
1123
1124 class ReferenceTypeLoc : public PointerLikeTypeLoc<ReferenceTypeLoc,
1125 ReferenceType> {
1126 public:
getInnerType()1127 QualType getInnerType() const {
1128 return getTypePtr()->getPointeeTypeAsWritten();
1129 }
1130 };
1131
1132 class LValueReferenceTypeLoc :
1133 public InheritingConcreteTypeLoc<ReferenceTypeLoc,
1134 LValueReferenceTypeLoc,
1135 LValueReferenceType> {
1136 public:
getAmpLoc()1137 SourceLocation getAmpLoc() const {
1138 return getSigilLoc();
1139 }
setAmpLoc(SourceLocation Loc)1140 void setAmpLoc(SourceLocation Loc) {
1141 setSigilLoc(Loc);
1142 }
1143 };
1144
1145 class RValueReferenceTypeLoc :
1146 public InheritingConcreteTypeLoc<ReferenceTypeLoc,
1147 RValueReferenceTypeLoc,
1148 RValueReferenceType> {
1149 public:
getAmpAmpLoc()1150 SourceLocation getAmpAmpLoc() const {
1151 return getSigilLoc();
1152 }
setAmpAmpLoc(SourceLocation Loc)1153 void setAmpAmpLoc(SourceLocation Loc) {
1154 setSigilLoc(Loc);
1155 }
1156 };
1157
1158
1159 struct FunctionLocInfo {
1160 SourceLocation LocalRangeBegin;
1161 SourceLocation LParenLoc;
1162 SourceLocation RParenLoc;
1163 SourceLocation LocalRangeEnd;
1164 };
1165
1166 /// \brief Wrapper for source info for functions.
1167 class FunctionTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
1168 FunctionTypeLoc,
1169 FunctionType,
1170 FunctionLocInfo> {
1171 public:
getLocalRangeBegin()1172 SourceLocation getLocalRangeBegin() const {
1173 return getLocalData()->LocalRangeBegin;
1174 }
setLocalRangeBegin(SourceLocation L)1175 void setLocalRangeBegin(SourceLocation L) {
1176 getLocalData()->LocalRangeBegin = L;
1177 }
1178
getLocalRangeEnd()1179 SourceLocation getLocalRangeEnd() const {
1180 return getLocalData()->LocalRangeEnd;
1181 }
setLocalRangeEnd(SourceLocation L)1182 void setLocalRangeEnd(SourceLocation L) {
1183 getLocalData()->LocalRangeEnd = L;
1184 }
1185
getLParenLoc()1186 SourceLocation getLParenLoc() const {
1187 return this->getLocalData()->LParenLoc;
1188 }
setLParenLoc(SourceLocation Loc)1189 void setLParenLoc(SourceLocation Loc) {
1190 this->getLocalData()->LParenLoc = Loc;
1191 }
1192
getRParenLoc()1193 SourceLocation getRParenLoc() const {
1194 return this->getLocalData()->RParenLoc;
1195 }
setRParenLoc(SourceLocation Loc)1196 void setRParenLoc(SourceLocation Loc) {
1197 this->getLocalData()->RParenLoc = Loc;
1198 }
1199
getParensRange()1200 SourceRange getParensRange() const {
1201 return SourceRange(getLParenLoc(), getRParenLoc());
1202 }
1203
getParams()1204 ArrayRef<ParmVarDecl *> getParams() const {
1205 return ArrayRef<ParmVarDecl *>(getParmArray(), getNumArgs());
1206 }
1207
1208 // ParmVarDecls* are stored after Info, one for each argument.
getParmArray()1209 ParmVarDecl **getParmArray() const {
1210 return (ParmVarDecl**) getExtraLocalData();
1211 }
1212
getNumArgs()1213 unsigned getNumArgs() const {
1214 if (isa<FunctionNoProtoType>(getTypePtr()))
1215 return 0;
1216 return cast<FunctionProtoType>(getTypePtr())->getNumArgs();
1217 }
getArg(unsigned i)1218 ParmVarDecl *getArg(unsigned i) const { return getParmArray()[i]; }
setArg(unsigned i,ParmVarDecl * VD)1219 void setArg(unsigned i, ParmVarDecl *VD) { getParmArray()[i] = VD; }
1220
getResultLoc()1221 TypeLoc getResultLoc() const {
1222 return getInnerTypeLoc();
1223 }
1224
getLocalSourceRange()1225 SourceRange getLocalSourceRange() const {
1226 return SourceRange(getLocalRangeBegin(), getLocalRangeEnd());
1227 }
1228
initializeLocal(ASTContext & Context,SourceLocation Loc)1229 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1230 setLocalRangeBegin(Loc);
1231 setLParenLoc(Loc);
1232 setRParenLoc(Loc);
1233 setLocalRangeEnd(Loc);
1234 for (unsigned i = 0, e = getNumArgs(); i != e; ++i)
1235 setArg(i, NULL);
1236 }
1237
1238 /// \brief Returns the size of the type source info data block that is
1239 /// specific to this type.
getExtraLocalDataSize()1240 unsigned getExtraLocalDataSize() const {
1241 return getNumArgs() * sizeof(ParmVarDecl*);
1242 }
1243
getExtraLocalDataAlignment()1244 unsigned getExtraLocalDataAlignment() const {
1245 return llvm::alignOf<ParmVarDecl*>();
1246 }
1247
getInnerType()1248 QualType getInnerType() const { return getTypePtr()->getResultType(); }
1249 };
1250
1251 class FunctionProtoTypeLoc :
1252 public InheritingConcreteTypeLoc<FunctionTypeLoc,
1253 FunctionProtoTypeLoc,
1254 FunctionProtoType> {
1255 };
1256
1257 class FunctionNoProtoTypeLoc :
1258 public InheritingConcreteTypeLoc<FunctionTypeLoc,
1259 FunctionNoProtoTypeLoc,
1260 FunctionNoProtoType> {
1261 };
1262
1263
1264 struct ArrayLocInfo {
1265 SourceLocation LBracketLoc, RBracketLoc;
1266 Expr *Size;
1267 };
1268
1269 /// \brief Wrapper for source info for arrays.
1270 class ArrayTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
1271 ArrayTypeLoc,
1272 ArrayType,
1273 ArrayLocInfo> {
1274 public:
getLBracketLoc()1275 SourceLocation getLBracketLoc() const {
1276 return getLocalData()->LBracketLoc;
1277 }
setLBracketLoc(SourceLocation Loc)1278 void setLBracketLoc(SourceLocation Loc) {
1279 getLocalData()->LBracketLoc = Loc;
1280 }
1281
getRBracketLoc()1282 SourceLocation getRBracketLoc() const {
1283 return getLocalData()->RBracketLoc;
1284 }
setRBracketLoc(SourceLocation Loc)1285 void setRBracketLoc(SourceLocation Loc) {
1286 getLocalData()->RBracketLoc = Loc;
1287 }
1288
getBracketsRange()1289 SourceRange getBracketsRange() const {
1290 return SourceRange(getLBracketLoc(), getRBracketLoc());
1291 }
1292
getSizeExpr()1293 Expr *getSizeExpr() const {
1294 return getLocalData()->Size;
1295 }
setSizeExpr(Expr * Size)1296 void setSizeExpr(Expr *Size) {
1297 getLocalData()->Size = Size;
1298 }
1299
getElementLoc()1300 TypeLoc getElementLoc() const {
1301 return getInnerTypeLoc();
1302 }
1303
getLocalSourceRange()1304 SourceRange getLocalSourceRange() const {
1305 return SourceRange(getLBracketLoc(), getRBracketLoc());
1306 }
1307
initializeLocal(ASTContext & Context,SourceLocation Loc)1308 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1309 setLBracketLoc(Loc);
1310 setRBracketLoc(Loc);
1311 setSizeExpr(NULL);
1312 }
1313
getInnerType()1314 QualType getInnerType() const { return getTypePtr()->getElementType(); }
1315 };
1316
1317 class ConstantArrayTypeLoc :
1318 public InheritingConcreteTypeLoc<ArrayTypeLoc,
1319 ConstantArrayTypeLoc,
1320 ConstantArrayType> {
1321 };
1322
1323 class IncompleteArrayTypeLoc :
1324 public InheritingConcreteTypeLoc<ArrayTypeLoc,
1325 IncompleteArrayTypeLoc,
1326 IncompleteArrayType> {
1327 };
1328
1329 class DependentSizedArrayTypeLoc :
1330 public InheritingConcreteTypeLoc<ArrayTypeLoc,
1331 DependentSizedArrayTypeLoc,
1332 DependentSizedArrayType> {
1333
1334 };
1335
1336 class VariableArrayTypeLoc :
1337 public InheritingConcreteTypeLoc<ArrayTypeLoc,
1338 VariableArrayTypeLoc,
1339 VariableArrayType> {
1340 };
1341
1342
1343 // Location information for a TemplateName. Rudimentary for now.
1344 struct TemplateNameLocInfo {
1345 SourceLocation NameLoc;
1346 };
1347
1348 struct TemplateSpecializationLocInfo : TemplateNameLocInfo {
1349 SourceLocation TemplateKWLoc;
1350 SourceLocation LAngleLoc;
1351 SourceLocation RAngleLoc;
1352 };
1353
1354 class TemplateSpecializationTypeLoc :
1355 public ConcreteTypeLoc<UnqualTypeLoc,
1356 TemplateSpecializationTypeLoc,
1357 TemplateSpecializationType,
1358 TemplateSpecializationLocInfo> {
1359 public:
getTemplateKeywordLoc()1360 SourceLocation getTemplateKeywordLoc() const {
1361 return getLocalData()->TemplateKWLoc;
1362 }
setTemplateKeywordLoc(SourceLocation Loc)1363 void setTemplateKeywordLoc(SourceLocation Loc) {
1364 getLocalData()->TemplateKWLoc = Loc;
1365 }
1366
getLAngleLoc()1367 SourceLocation getLAngleLoc() const {
1368 return getLocalData()->LAngleLoc;
1369 }
setLAngleLoc(SourceLocation Loc)1370 void setLAngleLoc(SourceLocation Loc) {
1371 getLocalData()->LAngleLoc = Loc;
1372 }
1373
getRAngleLoc()1374 SourceLocation getRAngleLoc() const {
1375 return getLocalData()->RAngleLoc;
1376 }
setRAngleLoc(SourceLocation Loc)1377 void setRAngleLoc(SourceLocation Loc) {
1378 getLocalData()->RAngleLoc = Loc;
1379 }
1380
getNumArgs()1381 unsigned getNumArgs() const {
1382 return getTypePtr()->getNumArgs();
1383 }
setArgLocInfo(unsigned i,TemplateArgumentLocInfo AI)1384 void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) {
1385 getArgInfos()[i] = AI;
1386 }
getArgLocInfo(unsigned i)1387 TemplateArgumentLocInfo getArgLocInfo(unsigned i) const {
1388 return getArgInfos()[i];
1389 }
1390
getArgLoc(unsigned i)1391 TemplateArgumentLoc getArgLoc(unsigned i) const {
1392 return TemplateArgumentLoc(getTypePtr()->getArg(i), getArgLocInfo(i));
1393 }
1394
getTemplateNameLoc()1395 SourceLocation getTemplateNameLoc() const {
1396 return getLocalData()->NameLoc;
1397 }
setTemplateNameLoc(SourceLocation Loc)1398 void setTemplateNameLoc(SourceLocation Loc) {
1399 getLocalData()->NameLoc = Loc;
1400 }
1401
1402 /// \brief - Copy the location information from the given info.
copy(TemplateSpecializationTypeLoc Loc)1403 void copy(TemplateSpecializationTypeLoc Loc) {
1404 unsigned size = getFullDataSize();
1405 assert(size == Loc.getFullDataSize());
1406
1407 // We're potentially copying Expr references here. We don't
1408 // bother retaining them because TypeSourceInfos live forever, so
1409 // as long as the Expr was retained when originally written into
1410 // the TypeLoc, we're okay.
1411 memcpy(Data, Loc.Data, size);
1412 }
1413
getLocalSourceRange()1414 SourceRange getLocalSourceRange() const {
1415 if (getTemplateKeywordLoc().isValid())
1416 return SourceRange(getTemplateKeywordLoc(), getRAngleLoc());
1417 else
1418 return SourceRange(getTemplateNameLoc(), getRAngleLoc());
1419 }
1420
initializeLocal(ASTContext & Context,SourceLocation Loc)1421 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1422 setTemplateKeywordLoc(Loc);
1423 setTemplateNameLoc(Loc);
1424 setLAngleLoc(Loc);
1425 setRAngleLoc(Loc);
1426 initializeArgLocs(Context, getNumArgs(), getTypePtr()->getArgs(),
1427 getArgInfos(), Loc);
1428 }
1429
1430 static void initializeArgLocs(ASTContext &Context, unsigned NumArgs,
1431 const TemplateArgument *Args,
1432 TemplateArgumentLocInfo *ArgInfos,
1433 SourceLocation Loc);
1434
getExtraLocalDataSize()1435 unsigned getExtraLocalDataSize() const {
1436 return getNumArgs() * sizeof(TemplateArgumentLocInfo);
1437 }
1438
getExtraLocalDataAlignment()1439 unsigned getExtraLocalDataAlignment() const {
1440 return llvm::alignOf<TemplateArgumentLocInfo>();
1441 }
1442
1443 private:
getArgInfos()1444 TemplateArgumentLocInfo *getArgInfos() const {
1445 return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData());
1446 }
1447 };
1448
1449 //===----------------------------------------------------------------------===//
1450 //
1451 // All of these need proper implementations.
1452 //
1453 //===----------------------------------------------------------------------===//
1454
1455 // FIXME: size expression and attribute locations (or keyword if we
1456 // ever fully support altivec syntax).
1457 class VectorTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
1458 VectorTypeLoc,
1459 VectorType> {
1460 };
1461
1462 // FIXME: size expression and attribute locations.
1463 class ExtVectorTypeLoc : public InheritingConcreteTypeLoc<VectorTypeLoc,
1464 ExtVectorTypeLoc,
1465 ExtVectorType> {
1466 };
1467
1468 // FIXME: attribute locations.
1469 // For some reason, this isn't a subtype of VectorType.
1470 class DependentSizedExtVectorTypeLoc :
1471 public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
1472 DependentSizedExtVectorTypeLoc,
1473 DependentSizedExtVectorType> {
1474 };
1475
1476 // FIXME: location of the '_Complex' keyword.
1477 class ComplexTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
1478 ComplexTypeLoc,
1479 ComplexType> {
1480 };
1481
1482 struct TypeofLocInfo {
1483 SourceLocation TypeofLoc;
1484 SourceLocation LParenLoc;
1485 SourceLocation RParenLoc;
1486 };
1487
1488 struct TypeOfExprTypeLocInfo : public TypeofLocInfo {
1489 };
1490
1491 struct TypeOfTypeLocInfo : public TypeofLocInfo {
1492 TypeSourceInfo* UnderlyingTInfo;
1493 };
1494
1495 template <class Derived, class TypeClass, class LocalData = TypeofLocInfo>
1496 class TypeofLikeTypeLoc
1497 : public ConcreteTypeLoc<UnqualTypeLoc, Derived, TypeClass, LocalData> {
1498 public:
getTypeofLoc()1499 SourceLocation getTypeofLoc() const {
1500 return this->getLocalData()->TypeofLoc;
1501 }
setTypeofLoc(SourceLocation Loc)1502 void setTypeofLoc(SourceLocation Loc) {
1503 this->getLocalData()->TypeofLoc = Loc;
1504 }
1505
getLParenLoc()1506 SourceLocation getLParenLoc() const {
1507 return this->getLocalData()->LParenLoc;
1508 }
setLParenLoc(SourceLocation Loc)1509 void setLParenLoc(SourceLocation Loc) {
1510 this->getLocalData()->LParenLoc = Loc;
1511 }
1512
getRParenLoc()1513 SourceLocation getRParenLoc() const {
1514 return this->getLocalData()->RParenLoc;
1515 }
setRParenLoc(SourceLocation Loc)1516 void setRParenLoc(SourceLocation Loc) {
1517 this->getLocalData()->RParenLoc = Loc;
1518 }
1519
getParensRange()1520 SourceRange getParensRange() const {
1521 return SourceRange(getLParenLoc(), getRParenLoc());
1522 }
setParensRange(SourceRange range)1523 void setParensRange(SourceRange range) {
1524 setLParenLoc(range.getBegin());
1525 setRParenLoc(range.getEnd());
1526 }
1527
getLocalSourceRange()1528 SourceRange getLocalSourceRange() const {
1529 return SourceRange(getTypeofLoc(), getRParenLoc());
1530 }
1531
initializeLocal(ASTContext & Context,SourceLocation Loc)1532 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1533 setTypeofLoc(Loc);
1534 setLParenLoc(Loc);
1535 setRParenLoc(Loc);
1536 }
1537 };
1538
1539 class TypeOfExprTypeLoc : public TypeofLikeTypeLoc<TypeOfExprTypeLoc,
1540 TypeOfExprType,
1541 TypeOfExprTypeLocInfo> {
1542 public:
getUnderlyingExpr()1543 Expr* getUnderlyingExpr() const {
1544 return getTypePtr()->getUnderlyingExpr();
1545 }
1546 // Reimplemented to account for GNU/C++ extension
1547 // typeof unary-expression
1548 // where there are no parentheses.
1549 SourceRange getLocalSourceRange() const;
1550 };
1551
1552 class TypeOfTypeLoc
1553 : public TypeofLikeTypeLoc<TypeOfTypeLoc, TypeOfType, TypeOfTypeLocInfo> {
1554 public:
getUnderlyingType()1555 QualType getUnderlyingType() const {
1556 return this->getTypePtr()->getUnderlyingType();
1557 }
getUnderlyingTInfo()1558 TypeSourceInfo* getUnderlyingTInfo() const {
1559 return this->getLocalData()->UnderlyingTInfo;
1560 }
setUnderlyingTInfo(TypeSourceInfo * TI)1561 void setUnderlyingTInfo(TypeSourceInfo* TI) const {
1562 this->getLocalData()->UnderlyingTInfo = TI;
1563 }
1564 };
1565
1566 // FIXME: location of the 'decltype' and parens.
1567 class DecltypeTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
1568 DecltypeTypeLoc,
1569 DecltypeType> {
1570 public:
getUnderlyingExpr()1571 Expr *getUnderlyingExpr() const { return getTypePtr()->getUnderlyingExpr(); }
1572 };
1573
1574 struct UnaryTransformTypeLocInfo {
1575 // FIXME: While there's only one unary transform right now, future ones may
1576 // need different representations
1577 SourceLocation KWLoc, LParenLoc, RParenLoc;
1578 TypeSourceInfo *UnderlyingTInfo;
1579 };
1580
1581 class UnaryTransformTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
1582 UnaryTransformTypeLoc,
1583 UnaryTransformType,
1584 UnaryTransformTypeLocInfo> {
1585 public:
getKWLoc()1586 SourceLocation getKWLoc() const { return getLocalData()->KWLoc; }
setKWLoc(SourceLocation Loc)1587 void setKWLoc(SourceLocation Loc) { getLocalData()->KWLoc = Loc; }
1588
getLParenLoc()1589 SourceLocation getLParenLoc() const { return getLocalData()->LParenLoc; }
setLParenLoc(SourceLocation Loc)1590 void setLParenLoc(SourceLocation Loc) { getLocalData()->LParenLoc = Loc; }
1591
getRParenLoc()1592 SourceLocation getRParenLoc() const { return getLocalData()->RParenLoc; }
setRParenLoc(SourceLocation Loc)1593 void setRParenLoc(SourceLocation Loc) { getLocalData()->RParenLoc = Loc; }
1594
getUnderlyingTInfo()1595 TypeSourceInfo* getUnderlyingTInfo() const {
1596 return getLocalData()->UnderlyingTInfo;
1597 }
setUnderlyingTInfo(TypeSourceInfo * TInfo)1598 void setUnderlyingTInfo(TypeSourceInfo *TInfo) {
1599 getLocalData()->UnderlyingTInfo = TInfo;
1600 }
1601
getLocalSourceRange()1602 SourceRange getLocalSourceRange() const {
1603 return SourceRange(getKWLoc(), getRParenLoc());
1604 }
1605
getParensRange()1606 SourceRange getParensRange() const {
1607 return SourceRange(getLParenLoc(), getRParenLoc());
1608 }
setParensRange(SourceRange Range)1609 void setParensRange(SourceRange Range) {
1610 setLParenLoc(Range.getBegin());
1611 setRParenLoc(Range.getEnd());
1612 }
1613
initializeLocal(ASTContext & Context,SourceLocation Loc)1614 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1615 setKWLoc(Loc);
1616 setRParenLoc(Loc);
1617 setLParenLoc(Loc);
1618 }
1619 };
1620
1621 class AutoTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
1622 AutoTypeLoc,
1623 AutoType> {
1624 };
1625
1626 struct ElaboratedLocInfo {
1627 SourceLocation ElaboratedKWLoc;
1628 /// \brief Data associated with the nested-name-specifier location.
1629 void *QualifierData;
1630 };
1631
1632 class ElaboratedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
1633 ElaboratedTypeLoc,
1634 ElaboratedType,
1635 ElaboratedLocInfo> {
1636 public:
getElaboratedKeywordLoc()1637 SourceLocation getElaboratedKeywordLoc() const {
1638 return this->getLocalData()->ElaboratedKWLoc;
1639 }
setElaboratedKeywordLoc(SourceLocation Loc)1640 void setElaboratedKeywordLoc(SourceLocation Loc) {
1641 this->getLocalData()->ElaboratedKWLoc = Loc;
1642 }
1643
getQualifierLoc()1644 NestedNameSpecifierLoc getQualifierLoc() const {
1645 return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
1646 getLocalData()->QualifierData);
1647 }
1648
setQualifierLoc(NestedNameSpecifierLoc QualifierLoc)1649 void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
1650 assert(QualifierLoc.getNestedNameSpecifier()
1651 == getTypePtr()->getQualifier() &&
1652 "Inconsistent nested-name-specifier pointer");
1653 getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
1654 }
1655
getLocalSourceRange()1656 SourceRange getLocalSourceRange() const {
1657 if (getElaboratedKeywordLoc().isValid())
1658 if (getQualifierLoc())
1659 return SourceRange(getElaboratedKeywordLoc(),
1660 getQualifierLoc().getEndLoc());
1661 else
1662 return SourceRange(getElaboratedKeywordLoc());
1663 else
1664 return getQualifierLoc().getSourceRange();
1665 }
1666
1667 void initializeLocal(ASTContext &Context, SourceLocation Loc);
1668
getNamedTypeLoc()1669 TypeLoc getNamedTypeLoc() const {
1670 return getInnerTypeLoc();
1671 }
1672
getInnerType()1673 QualType getInnerType() const {
1674 return getTypePtr()->getNamedType();
1675 }
1676
copy(ElaboratedTypeLoc Loc)1677 void copy(ElaboratedTypeLoc Loc) {
1678 unsigned size = getFullDataSize();
1679 assert(size == Loc.getFullDataSize());
1680 memcpy(Data, Loc.Data, size);
1681 }
1682 };
1683
1684 // This is exactly the structure of an ElaboratedTypeLoc whose inner
1685 // type is some sort of TypeDeclTypeLoc.
1686 struct DependentNameLocInfo : ElaboratedLocInfo {
1687 SourceLocation NameLoc;
1688 };
1689
1690 class DependentNameTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
1691 DependentNameTypeLoc,
1692 DependentNameType,
1693 DependentNameLocInfo> {
1694 public:
getElaboratedKeywordLoc()1695 SourceLocation getElaboratedKeywordLoc() const {
1696 return this->getLocalData()->ElaboratedKWLoc;
1697 }
setElaboratedKeywordLoc(SourceLocation Loc)1698 void setElaboratedKeywordLoc(SourceLocation Loc) {
1699 this->getLocalData()->ElaboratedKWLoc = Loc;
1700 }
1701
getQualifierLoc()1702 NestedNameSpecifierLoc getQualifierLoc() const {
1703 return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
1704 getLocalData()->QualifierData);
1705 }
1706
setQualifierLoc(NestedNameSpecifierLoc QualifierLoc)1707 void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
1708 assert(QualifierLoc.getNestedNameSpecifier()
1709 == getTypePtr()->getQualifier() &&
1710 "Inconsistent nested-name-specifier pointer");
1711 getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
1712 }
1713
getNameLoc()1714 SourceLocation getNameLoc() const {
1715 return this->getLocalData()->NameLoc;
1716 }
setNameLoc(SourceLocation Loc)1717 void setNameLoc(SourceLocation Loc) {
1718 this->getLocalData()->NameLoc = Loc;
1719 }
1720
getLocalSourceRange()1721 SourceRange getLocalSourceRange() const {
1722 if (getElaboratedKeywordLoc().isValid())
1723 return SourceRange(getElaboratedKeywordLoc(), getNameLoc());
1724 else
1725 return SourceRange(getQualifierLoc().getBeginLoc(), getNameLoc());
1726 }
1727
copy(DependentNameTypeLoc Loc)1728 void copy(DependentNameTypeLoc Loc) {
1729 unsigned size = getFullDataSize();
1730 assert(size == Loc.getFullDataSize());
1731 memcpy(Data, Loc.Data, size);
1732 }
1733
1734 void initializeLocal(ASTContext &Context, SourceLocation Loc);
1735 };
1736
1737 struct DependentTemplateSpecializationLocInfo : DependentNameLocInfo {
1738 SourceLocation TemplateKWLoc;
1739 SourceLocation LAngleLoc;
1740 SourceLocation RAngleLoc;
1741 // followed by a TemplateArgumentLocInfo[]
1742 };
1743
1744 class DependentTemplateSpecializationTypeLoc :
1745 public ConcreteTypeLoc<UnqualTypeLoc,
1746 DependentTemplateSpecializationTypeLoc,
1747 DependentTemplateSpecializationType,
1748 DependentTemplateSpecializationLocInfo> {
1749 public:
getElaboratedKeywordLoc()1750 SourceLocation getElaboratedKeywordLoc() const {
1751 return this->getLocalData()->ElaboratedKWLoc;
1752 }
setElaboratedKeywordLoc(SourceLocation Loc)1753 void setElaboratedKeywordLoc(SourceLocation Loc) {
1754 this->getLocalData()->ElaboratedKWLoc = Loc;
1755 }
1756
getQualifierLoc()1757 NestedNameSpecifierLoc getQualifierLoc() const {
1758 if (!getLocalData()->QualifierData)
1759 return NestedNameSpecifierLoc();
1760
1761 return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
1762 getLocalData()->QualifierData);
1763 }
1764
setQualifierLoc(NestedNameSpecifierLoc QualifierLoc)1765 void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
1766 if (!QualifierLoc) {
1767 // Even if we have a nested-name-specifier in the dependent
1768 // template specialization type, we won't record the nested-name-specifier
1769 // location information when this type-source location information is
1770 // part of a nested-name-specifier.
1771 getLocalData()->QualifierData = 0;
1772 return;
1773 }
1774
1775 assert(QualifierLoc.getNestedNameSpecifier()
1776 == getTypePtr()->getQualifier() &&
1777 "Inconsistent nested-name-specifier pointer");
1778 getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
1779 }
1780
getTemplateKeywordLoc()1781 SourceLocation getTemplateKeywordLoc() const {
1782 return getLocalData()->TemplateKWLoc;
1783 }
setTemplateKeywordLoc(SourceLocation Loc)1784 void setTemplateKeywordLoc(SourceLocation Loc) {
1785 getLocalData()->TemplateKWLoc = Loc;
1786 }
1787
getTemplateNameLoc()1788 SourceLocation getTemplateNameLoc() const {
1789 return this->getLocalData()->NameLoc;
1790 }
setTemplateNameLoc(SourceLocation Loc)1791 void setTemplateNameLoc(SourceLocation Loc) {
1792 this->getLocalData()->NameLoc = Loc;
1793 }
1794
getLAngleLoc()1795 SourceLocation getLAngleLoc() const {
1796 return this->getLocalData()->LAngleLoc;
1797 }
setLAngleLoc(SourceLocation Loc)1798 void setLAngleLoc(SourceLocation Loc) {
1799 this->getLocalData()->LAngleLoc = Loc;
1800 }
1801
getRAngleLoc()1802 SourceLocation getRAngleLoc() const {
1803 return this->getLocalData()->RAngleLoc;
1804 }
setRAngleLoc(SourceLocation Loc)1805 void setRAngleLoc(SourceLocation Loc) {
1806 this->getLocalData()->RAngleLoc = Loc;
1807 }
1808
getNumArgs()1809 unsigned getNumArgs() const {
1810 return getTypePtr()->getNumArgs();
1811 }
1812
setArgLocInfo(unsigned i,TemplateArgumentLocInfo AI)1813 void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) {
1814 getArgInfos()[i] = AI;
1815 }
getArgLocInfo(unsigned i)1816 TemplateArgumentLocInfo getArgLocInfo(unsigned i) const {
1817 return getArgInfos()[i];
1818 }
1819
getArgLoc(unsigned i)1820 TemplateArgumentLoc getArgLoc(unsigned i) const {
1821 return TemplateArgumentLoc(getTypePtr()->getArg(i), getArgLocInfo(i));
1822 }
1823
getLocalSourceRange()1824 SourceRange getLocalSourceRange() const {
1825 if (getElaboratedKeywordLoc().isValid())
1826 return SourceRange(getElaboratedKeywordLoc(), getRAngleLoc());
1827 else if (getQualifierLoc())
1828 return SourceRange(getQualifierLoc().getBeginLoc(), getRAngleLoc());
1829 else if (getTemplateKeywordLoc().isValid())
1830 return SourceRange(getTemplateKeywordLoc(), getRAngleLoc());
1831 else
1832 return SourceRange(getTemplateNameLoc(), getRAngleLoc());
1833 }
1834
copy(DependentTemplateSpecializationTypeLoc Loc)1835 void copy(DependentTemplateSpecializationTypeLoc Loc) {
1836 unsigned size = getFullDataSize();
1837 assert(size == Loc.getFullDataSize());
1838 memcpy(Data, Loc.Data, size);
1839 }
1840
1841 void initializeLocal(ASTContext &Context, SourceLocation Loc);
1842
getExtraLocalDataSize()1843 unsigned getExtraLocalDataSize() const {
1844 return getNumArgs() * sizeof(TemplateArgumentLocInfo);
1845 }
1846
getExtraLocalDataAlignment()1847 unsigned getExtraLocalDataAlignment() const {
1848 return llvm::alignOf<TemplateArgumentLocInfo>();
1849 }
1850
1851 private:
getArgInfos()1852 TemplateArgumentLocInfo *getArgInfos() const {
1853 return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData());
1854 }
1855 };
1856
1857
1858 struct PackExpansionTypeLocInfo {
1859 SourceLocation EllipsisLoc;
1860 };
1861
1862 class PackExpansionTypeLoc
1863 : public ConcreteTypeLoc<UnqualTypeLoc, PackExpansionTypeLoc,
1864 PackExpansionType, PackExpansionTypeLocInfo> {
1865 public:
getEllipsisLoc()1866 SourceLocation getEllipsisLoc() const {
1867 return this->getLocalData()->EllipsisLoc;
1868 }
1869
setEllipsisLoc(SourceLocation Loc)1870 void setEllipsisLoc(SourceLocation Loc) {
1871 this->getLocalData()->EllipsisLoc = Loc;
1872 }
1873
getLocalSourceRange()1874 SourceRange getLocalSourceRange() const {
1875 return SourceRange(getEllipsisLoc(), getEllipsisLoc());
1876 }
1877
initializeLocal(ASTContext & Context,SourceLocation Loc)1878 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1879 setEllipsisLoc(Loc);
1880 }
1881
getPatternLoc()1882 TypeLoc getPatternLoc() const {
1883 return getInnerTypeLoc();
1884 }
1885
getInnerType()1886 QualType getInnerType() const {
1887 return this->getTypePtr()->getPattern();
1888 }
1889 };
1890
1891 struct AtomicTypeLocInfo {
1892 SourceLocation KWLoc, LParenLoc, RParenLoc;
1893 };
1894
1895 class AtomicTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, AtomicTypeLoc,
1896 AtomicType, AtomicTypeLocInfo> {
1897 public:
getValueLoc()1898 TypeLoc getValueLoc() const {
1899 return this->getInnerTypeLoc();
1900 }
1901
getLocalSourceRange()1902 SourceRange getLocalSourceRange() const {
1903 return SourceRange(getKWLoc(), getRParenLoc());
1904 }
1905
getKWLoc()1906 SourceLocation getKWLoc() const {
1907 return this->getLocalData()->KWLoc;
1908 }
setKWLoc(SourceLocation Loc)1909 void setKWLoc(SourceLocation Loc) {
1910 this->getLocalData()->KWLoc = Loc;
1911 }
1912
getLParenLoc()1913 SourceLocation getLParenLoc() const {
1914 return this->getLocalData()->LParenLoc;
1915 }
setLParenLoc(SourceLocation Loc)1916 void setLParenLoc(SourceLocation Loc) {
1917 this->getLocalData()->LParenLoc = Loc;
1918 }
1919
getRParenLoc()1920 SourceLocation getRParenLoc() const {
1921 return this->getLocalData()->RParenLoc;
1922 }
setRParenLoc(SourceLocation Loc)1923 void setRParenLoc(SourceLocation Loc) {
1924 this->getLocalData()->RParenLoc = Loc;
1925 }
1926
getParensRange()1927 SourceRange getParensRange() const {
1928 return SourceRange(getLParenLoc(), getRParenLoc());
1929 }
setParensRange(SourceRange Range)1930 void setParensRange(SourceRange Range) {
1931 setLParenLoc(Range.getBegin());
1932 setRParenLoc(Range.getEnd());
1933 }
1934
initializeLocal(ASTContext & Context,SourceLocation Loc)1935 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1936 setKWLoc(Loc);
1937 setLParenLoc(Loc);
1938 setRParenLoc(Loc);
1939 }
1940
getInnerType()1941 QualType getInnerType() const {
1942 return this->getTypePtr()->getValueType();
1943 }
1944 };
1945
1946
1947 }
1948
1949 #endif
1950