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