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