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