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