clang API Documentation
00001 //===--- TypeLoc.h - Type Source Info Wrapper -------------------*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 /// 00010 /// \file 00011 /// \brief Defines the clang::TypeLoc interface and its subclasses. 00012 /// 00013 //===----------------------------------------------------------------------===// 00014 00015 #ifndef LLVM_CLANG_AST_TYPELOC_H 00016 #define LLVM_CLANG_AST_TYPELOC_H 00017 00018 #include "clang/AST/Decl.h" 00019 #include "clang/AST/TemplateBase.h" 00020 #include "clang/AST/Type.h" 00021 #include "clang/Basic/Specifiers.h" 00022 #include "llvm/Support/Compiler.h" 00023 00024 namespace clang { 00025 class ASTContext; 00026 class ParmVarDecl; 00027 class TypeSourceInfo; 00028 class UnqualTypeLoc; 00029 00030 // Predeclare all the type nodes. 00031 #define ABSTRACT_TYPELOC(Class, Base) 00032 #define TYPELOC(Class, Base) \ 00033 class Class##TypeLoc; 00034 #include "clang/AST/TypeLocNodes.def" 00035 00036 /// \brief Base wrapper for a particular "section" of type source info. 00037 /// 00038 /// A client should use the TypeLoc subclasses through castAs()/getAs() 00039 /// in order to get at the actual information. 00040 class TypeLoc { 00041 protected: 00042 // The correctness of this relies on the property that, for Type *Ty, 00043 // QualType(Ty, 0).getAsOpaquePtr() == (void*) Ty 00044 const void *Ty; 00045 void *Data; 00046 00047 public: 00048 /// \brief Convert to the specified TypeLoc type, asserting that this TypeLoc 00049 /// is of the desired type. 00050 /// 00051 /// \pre T::isKind(*this) 00052 template<typename T> 00053 T castAs() const { 00054 assert(T::isKind(*this)); 00055 T t; 00056 TypeLoc& tl = t; 00057 tl = *this; 00058 return t; 00059 } 00060 00061 /// \brief Convert to the specified TypeLoc type, returning a null TypeLoc if 00062 /// this TypeLoc is not of the desired type. 00063 template<typename T> 00064 T getAs() const { 00065 if (!T::isKind(*this)) 00066 return T(); 00067 T t; 00068 TypeLoc& tl = t; 00069 tl = *this; 00070 return t; 00071 } 00072 00073 /// The kinds of TypeLocs. Equivalent to the Type::TypeClass enum, 00074 /// except it also defines a Qualified enum that corresponds to the 00075 /// QualifiedLoc class. 00076 enum TypeLocClass { 00077 #define ABSTRACT_TYPE(Class, Base) 00078 #define TYPE(Class, Base) \ 00079 Class = Type::Class, 00080 #include "clang/AST/TypeNodes.def" 00081 Qualified 00082 }; 00083 00084 TypeLoc() : Ty(nullptr), Data(nullptr) { } 00085 TypeLoc(QualType ty, void *opaqueData) 00086 : Ty(ty.getAsOpaquePtr()), Data(opaqueData) { } 00087 TypeLoc(const Type *ty, void *opaqueData) 00088 : Ty(ty), Data(opaqueData) { } 00089 00090 TypeLocClass getTypeLocClass() const { 00091 if (getType().hasLocalQualifiers()) return Qualified; 00092 return (TypeLocClass) getType()->getTypeClass(); 00093 } 00094 00095 bool isNull() const { return !Ty; } 00096 LLVM_EXPLICIT operator bool() const { return Ty; } 00097 00098 /// \brief Returns the size of type source info data block for the given type. 00099 static unsigned getFullDataSizeForType(QualType Ty); 00100 00101 /// \brief Returns the alignment of type source info data block for 00102 /// the given type. 00103 static unsigned getLocalAlignmentForType(QualType Ty); 00104 00105 /// \brief Get the type for which this source info wrapper provides 00106 /// information. 00107 QualType getType() const { 00108 return QualType::getFromOpaquePtr(Ty); 00109 } 00110 00111 const Type *getTypePtr() const { 00112 return QualType::getFromOpaquePtr(Ty).getTypePtr(); 00113 } 00114 00115 /// \brief Get the pointer where source information is stored. 00116 void *getOpaqueData() const { 00117 return Data; 00118 } 00119 00120 /// \brief Get the begin source location. 00121 SourceLocation getBeginLoc() const; 00122 00123 /// \brief Get the end source location. 00124 SourceLocation getEndLoc() const; 00125 00126 /// \brief Get the full source range. 00127 SourceRange getSourceRange() const LLVM_READONLY { 00128 return SourceRange(getBeginLoc(), getEndLoc()); 00129 } 00130 SourceLocation getLocStart() const LLVM_READONLY { return getBeginLoc(); } 00131 SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); } 00132 00133 /// \brief Get the local source range. 00134 SourceRange getLocalSourceRange() const { 00135 return getLocalSourceRangeImpl(*this); 00136 } 00137 00138 /// \brief Returns the size of the type source info data block. 00139 unsigned getFullDataSize() const { 00140 return getFullDataSizeForType(getType()); 00141 } 00142 00143 /// \brief Get the next TypeLoc pointed by this TypeLoc, e.g for "int*" the 00144 /// TypeLoc is a PointerLoc and next TypeLoc is for "int". 00145 TypeLoc getNextTypeLoc() const { 00146 return getNextTypeLocImpl(*this); 00147 } 00148 00149 /// \brief Skips past any qualifiers, if this is qualified. 00150 UnqualTypeLoc getUnqualifiedLoc() const; // implemented in this header 00151 00152 TypeLoc IgnoreParens() const; 00153 00154 /// \brief Initializes this to state that every location in this 00155 /// type is the given location. 00156 /// 00157 /// This method exists to provide a simple transition for code that 00158 /// relies on location-less types. 00159 void initialize(ASTContext &Context, SourceLocation Loc) const { 00160 initializeImpl(Context, *this, Loc); 00161 } 00162 00163 /// \brief Initializes this by copying its information from another 00164 /// TypeLoc of the same type. 00165 void initializeFullCopy(TypeLoc Other) const { 00166 assert(getType() == Other.getType()); 00167 size_t Size = getFullDataSize(); 00168 memcpy(getOpaqueData(), Other.getOpaqueData(), Size); 00169 } 00170 00171 /// \brief Initializes this by copying its information from another 00172 /// TypeLoc of the same type. The given size must be the full data 00173 /// size. 00174 void initializeFullCopy(TypeLoc Other, unsigned Size) const { 00175 assert(getType() == Other.getType()); 00176 assert(getFullDataSize() == Size); 00177 memcpy(getOpaqueData(), Other.getOpaqueData(), Size); 00178 } 00179 00180 friend bool operator==(const TypeLoc &LHS, const TypeLoc &RHS) { 00181 return LHS.Ty == RHS.Ty && LHS.Data == RHS.Data; 00182 } 00183 00184 friend bool operator!=(const TypeLoc &LHS, const TypeLoc &RHS) { 00185 return !(LHS == RHS); 00186 } 00187 00188 private: 00189 static bool isKind(const TypeLoc&) { 00190 return true; 00191 } 00192 00193 static void initializeImpl(ASTContext &Context, TypeLoc TL, 00194 SourceLocation Loc); 00195 static TypeLoc getNextTypeLocImpl(TypeLoc TL); 00196 static TypeLoc IgnoreParensImpl(TypeLoc TL); 00197 static SourceRange getLocalSourceRangeImpl(TypeLoc TL); 00198 }; 00199 00200 /// \brief Return the TypeLoc for a type source info. 00201 inline TypeLoc TypeSourceInfo::getTypeLoc() const { 00202 return TypeLoc(Ty, const_cast<void*>(static_cast<const void*>(this + 1))); 00203 } 00204 00205 /// \brief Wrapper of type source information for a type with 00206 /// no direct qualifiers. 00207 class UnqualTypeLoc : public TypeLoc { 00208 public: 00209 UnqualTypeLoc() {} 00210 UnqualTypeLoc(const Type *Ty, void *Data) : TypeLoc(Ty, Data) {} 00211 00212 const Type *getTypePtr() const { 00213 return reinterpret_cast<const Type*>(Ty); 00214 } 00215 00216 TypeLocClass getTypeLocClass() const { 00217 return (TypeLocClass) getTypePtr()->getTypeClass(); 00218 } 00219 00220 private: 00221 friend class TypeLoc; 00222 static bool isKind(const TypeLoc &TL) { 00223 return !TL.getType().hasLocalQualifiers(); 00224 } 00225 }; 00226 00227 /// \brief Wrapper of type source information for a type with 00228 /// non-trivial direct qualifiers. 00229 /// 00230 /// Currently, we intentionally do not provide source location for 00231 /// type qualifiers. 00232 class QualifiedTypeLoc : public TypeLoc { 00233 public: 00234 SourceRange getLocalSourceRange() const { 00235 return SourceRange(); 00236 } 00237 00238 UnqualTypeLoc getUnqualifiedLoc() const { 00239 unsigned align = 00240 TypeLoc::getLocalAlignmentForType(QualType(getTypePtr(), 0)); 00241 uintptr_t dataInt = reinterpret_cast<uintptr_t>(Data); 00242 dataInt = llvm::RoundUpToAlignment(dataInt, align); 00243 return UnqualTypeLoc(getTypePtr(), reinterpret_cast<void*>(dataInt)); 00244 } 00245 00246 /// Initializes the local data of this type source info block to 00247 /// provide no information. 00248 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 00249 // do nothing 00250 } 00251 00252 TypeLoc getNextTypeLoc() const { 00253 return getUnqualifiedLoc(); 00254 } 00255 00256 /// \brief Returns the size of the type source info data block that is 00257 /// specific to this type. 00258 unsigned getLocalDataSize() const { 00259 // In fact, we don't currently preserve any location information 00260 // for qualifiers. 00261 return 0; 00262 } 00263 00264 /// \brief Returns the alignment of the type source info data block that is 00265 /// specific to this type. 00266 unsigned getLocalDataAlignment() const { 00267 // We don't preserve any location information. 00268 return 1; 00269 } 00270 00271 private: 00272 friend class TypeLoc; 00273 static bool isKind(const TypeLoc &TL) { 00274 return TL.getType().hasLocalQualifiers(); 00275 } 00276 }; 00277 00278 inline UnqualTypeLoc TypeLoc::getUnqualifiedLoc() const { 00279 if (QualifiedTypeLoc Loc = getAs<QualifiedTypeLoc>()) 00280 return Loc.getUnqualifiedLoc(); 00281 return castAs<UnqualTypeLoc>(); 00282 } 00283 00284 /// A metaprogramming base class for TypeLoc classes which correspond 00285 /// to a particular Type subclass. It is accepted for a single 00286 /// TypeLoc class to correspond to multiple Type classes. 00287 /// 00288 /// \tparam Base a class from which to derive 00289 /// \tparam Derived the class deriving from this one 00290 /// \tparam TypeClass the concrete Type subclass associated with this 00291 /// location type 00292 /// \tparam LocalData the structure type of local location data for 00293 /// this type 00294 /// 00295 /// TypeLocs with non-constant amounts of local data should override 00296 /// getExtraLocalDataSize(); getExtraLocalData() will then point to 00297 /// this extra memory. 00298 /// 00299 /// TypeLocs with an inner type should define 00300 /// QualType getInnerType() const 00301 /// and getInnerTypeLoc() will then point to this inner type's 00302 /// location data. 00303 /// 00304 /// A word about hierarchies: this template is not designed to be 00305 /// derived from multiple times in a hierarchy. It is also not 00306 /// designed to be used for classes where subtypes might provide 00307 /// different amounts of source information. It should be subclassed 00308 /// only at the deepest portion of the hierarchy where all children 00309 /// have identical source information; if that's an abstract type, 00310 /// then further descendents should inherit from 00311 /// InheritingConcreteTypeLoc instead. 00312 template <class Base, class Derived, class TypeClass, class LocalData> 00313 class ConcreteTypeLoc : public Base { 00314 00315 const Derived *asDerived() const { 00316 return static_cast<const Derived*>(this); 00317 } 00318 00319 friend class TypeLoc; 00320 static bool isKind(const TypeLoc &TL) { 00321 return !TL.getType().hasLocalQualifiers() && 00322 Derived::classofType(TL.getTypePtr()); 00323 } 00324 00325 static bool classofType(const Type *Ty) { 00326 return TypeClass::classof(Ty); 00327 } 00328 00329 public: 00330 unsigned getLocalDataAlignment() const { 00331 return std::max(llvm::alignOf<LocalData>(), 00332 asDerived()->getExtraLocalDataAlignment()); 00333 } 00334 unsigned getLocalDataSize() const { 00335 unsigned size = sizeof(LocalData); 00336 unsigned extraAlign = asDerived()->getExtraLocalDataAlignment(); 00337 size = llvm::RoundUpToAlignment(size, extraAlign); 00338 size += asDerived()->getExtraLocalDataSize(); 00339 return size; 00340 } 00341 00342 TypeLoc getNextTypeLoc() const { 00343 return getNextTypeLoc(asDerived()->getInnerType()); 00344 } 00345 00346 const TypeClass *getTypePtr() const { 00347 return cast<TypeClass>(Base::getTypePtr()); 00348 } 00349 00350 protected: 00351 unsigned getExtraLocalDataSize() const { 00352 return 0; 00353 } 00354 00355 unsigned getExtraLocalDataAlignment() const { 00356 return 1; 00357 } 00358 00359 LocalData *getLocalData() const { 00360 return static_cast<LocalData*>(Base::Data); 00361 } 00362 00363 /// Gets a pointer past the Info structure; useful for classes with 00364 /// local data that can't be captured in the Info (e.g. because it's 00365 /// of variable size). 00366 void *getExtraLocalData() const { 00367 unsigned size = sizeof(LocalData); 00368 unsigned extraAlign = asDerived()->getExtraLocalDataAlignment(); 00369 size = llvm::RoundUpToAlignment(size, extraAlign); 00370 return reinterpret_cast<char*>(Base::Data) + size; 00371 } 00372 00373 void *getNonLocalData() const { 00374 uintptr_t data = reinterpret_cast<uintptr_t>(Base::Data); 00375 data += asDerived()->getLocalDataSize(); 00376 data = llvm::RoundUpToAlignment(data, getNextTypeAlign()); 00377 return reinterpret_cast<void*>(data); 00378 } 00379 00380 struct HasNoInnerType {}; 00381 HasNoInnerType getInnerType() const { return HasNoInnerType(); } 00382 00383 TypeLoc getInnerTypeLoc() const { 00384 return TypeLoc(asDerived()->getInnerType(), getNonLocalData()); 00385 } 00386 00387 private: 00388 unsigned getInnerTypeSize() const { 00389 return getInnerTypeSize(asDerived()->getInnerType()); 00390 } 00391 00392 unsigned getInnerTypeSize(HasNoInnerType _) const { 00393 return 0; 00394 } 00395 00396 unsigned getInnerTypeSize(QualType _) const { 00397 return getInnerTypeLoc().getFullDataSize(); 00398 } 00399 00400 unsigned getNextTypeAlign() const { 00401 return getNextTypeAlign(asDerived()->getInnerType()); 00402 } 00403 00404 unsigned getNextTypeAlign(HasNoInnerType _) const { 00405 return 1; 00406 } 00407 00408 unsigned getNextTypeAlign(QualType T) const { 00409 return TypeLoc::getLocalAlignmentForType(T); 00410 } 00411 00412 TypeLoc getNextTypeLoc(HasNoInnerType _) const { 00413 return TypeLoc(); 00414 } 00415 00416 TypeLoc getNextTypeLoc(QualType T) const { 00417 return TypeLoc(T, getNonLocalData()); 00418 } 00419 }; 00420 00421 /// A metaprogramming class designed for concrete subtypes of abstract 00422 /// types where all subtypes share equivalently-structured source 00423 /// information. See the note on ConcreteTypeLoc. 00424 template <class Base, class Derived, class TypeClass> 00425 class InheritingConcreteTypeLoc : public Base { 00426 friend class TypeLoc; 00427 static bool classofType(const Type *Ty) { 00428 return TypeClass::classof(Ty); 00429 } 00430 00431 static bool isKind(const TypeLoc &TL) { 00432 return !TL.getType().hasLocalQualifiers() && 00433 Derived::classofType(TL.getTypePtr()); 00434 } 00435 static bool isKind(const UnqualTypeLoc &TL) { 00436 return Derived::classofType(TL.getTypePtr()); 00437 } 00438 00439 public: 00440 const TypeClass *getTypePtr() const { 00441 return cast<TypeClass>(Base::getTypePtr()); 00442 } 00443 }; 00444 00445 00446 struct TypeSpecLocInfo { 00447 SourceLocation NameLoc; 00448 }; 00449 00450 /// \brief A reasonable base class for TypeLocs that correspond to 00451 /// types that are written as a type-specifier. 00452 class TypeSpecTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, 00453 TypeSpecTypeLoc, 00454 Type, 00455 TypeSpecLocInfo> { 00456 public: 00457 enum { LocalDataSize = sizeof(TypeSpecLocInfo), 00458 LocalDataAlignment = llvm::AlignOf<TypeSpecLocInfo>::Alignment }; 00459 00460 SourceLocation getNameLoc() const { 00461 return this->getLocalData()->NameLoc; 00462 } 00463 void setNameLoc(SourceLocation Loc) { 00464 this->getLocalData()->NameLoc = Loc; 00465 } 00466 SourceRange getLocalSourceRange() const { 00467 return SourceRange(getNameLoc(), getNameLoc()); 00468 } 00469 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 00470 setNameLoc(Loc); 00471 } 00472 00473 private: 00474 friend class TypeLoc; 00475 static bool isKind(const TypeLoc &TL); 00476 }; 00477 00478 00479 struct BuiltinLocInfo { 00480 SourceLocation BuiltinLoc; 00481 }; 00482 00483 /// \brief Wrapper for source info for builtin types. 00484 class BuiltinTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, 00485 BuiltinTypeLoc, 00486 BuiltinType, 00487 BuiltinLocInfo> { 00488 public: 00489 SourceLocation getBuiltinLoc() const { 00490 return getLocalData()->BuiltinLoc; 00491 } 00492 void setBuiltinLoc(SourceLocation Loc) { 00493 getLocalData()->BuiltinLoc = Loc; 00494 } 00495 00496 SourceLocation getNameLoc() const { return getBuiltinLoc(); } 00497 00498 WrittenBuiltinSpecs& getWrittenBuiltinSpecs() { 00499 return *(static_cast<WrittenBuiltinSpecs*>(getExtraLocalData())); 00500 } 00501 const WrittenBuiltinSpecs& getWrittenBuiltinSpecs() const { 00502 return *(static_cast<WrittenBuiltinSpecs*>(getExtraLocalData())); 00503 } 00504 00505 bool needsExtraLocalData() const { 00506 BuiltinType::Kind bk = getTypePtr()->getKind(); 00507 return (bk >= BuiltinType::UShort && bk <= BuiltinType::UInt128) 00508 || (bk >= BuiltinType::Short && bk <= BuiltinType::LongDouble) 00509 || bk == BuiltinType::UChar 00510 || bk == BuiltinType::SChar; 00511 } 00512 00513 unsigned getExtraLocalDataSize() const { 00514 return needsExtraLocalData() ? sizeof(WrittenBuiltinSpecs) : 0; 00515 } 00516 00517 unsigned getExtraLocalDataAlignment() const { 00518 return needsExtraLocalData() ? llvm::alignOf<WrittenBuiltinSpecs>() : 1; 00519 } 00520 00521 SourceRange getLocalSourceRange() const { 00522 return SourceRange(getBuiltinLoc(), getBuiltinLoc()); 00523 } 00524 00525 TypeSpecifierSign getWrittenSignSpec() const { 00526 if (needsExtraLocalData()) 00527 return static_cast<TypeSpecifierSign>(getWrittenBuiltinSpecs().Sign); 00528 else 00529 return TSS_unspecified; 00530 } 00531 bool hasWrittenSignSpec() const { 00532 return getWrittenSignSpec() != TSS_unspecified; 00533 } 00534 void setWrittenSignSpec(TypeSpecifierSign written) { 00535 if (needsExtraLocalData()) 00536 getWrittenBuiltinSpecs().Sign = written; 00537 } 00538 00539 TypeSpecifierWidth getWrittenWidthSpec() const { 00540 if (needsExtraLocalData()) 00541 return static_cast<TypeSpecifierWidth>(getWrittenBuiltinSpecs().Width); 00542 else 00543 return TSW_unspecified; 00544 } 00545 bool hasWrittenWidthSpec() const { 00546 return getWrittenWidthSpec() != TSW_unspecified; 00547 } 00548 void setWrittenWidthSpec(TypeSpecifierWidth written) { 00549 if (needsExtraLocalData()) 00550 getWrittenBuiltinSpecs().Width = written; 00551 } 00552 00553 TypeSpecifierType getWrittenTypeSpec() const; 00554 bool hasWrittenTypeSpec() const { 00555 return getWrittenTypeSpec() != TST_unspecified; 00556 } 00557 void setWrittenTypeSpec(TypeSpecifierType written) { 00558 if (needsExtraLocalData()) 00559 getWrittenBuiltinSpecs().Type = written; 00560 } 00561 00562 bool hasModeAttr() const { 00563 if (needsExtraLocalData()) 00564 return getWrittenBuiltinSpecs().ModeAttr; 00565 else 00566 return false; 00567 } 00568 void setModeAttr(bool written) { 00569 if (needsExtraLocalData()) 00570 getWrittenBuiltinSpecs().ModeAttr = written; 00571 } 00572 00573 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 00574 setBuiltinLoc(Loc); 00575 if (needsExtraLocalData()) { 00576 WrittenBuiltinSpecs &wbs = getWrittenBuiltinSpecs(); 00577 wbs.Sign = TSS_unspecified; 00578 wbs.Width = TSW_unspecified; 00579 wbs.Type = TST_unspecified; 00580 wbs.ModeAttr = false; 00581 } 00582 } 00583 }; 00584 00585 00586 /// \brief Wrapper for source info for typedefs. 00587 class TypedefTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 00588 TypedefTypeLoc, 00589 TypedefType> { 00590 public: 00591 TypedefNameDecl *getTypedefNameDecl() const { 00592 return getTypePtr()->getDecl(); 00593 } 00594 }; 00595 00596 /// \brief Wrapper for source info for injected class names of class 00597 /// templates. 00598 class InjectedClassNameTypeLoc : 00599 public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 00600 InjectedClassNameTypeLoc, 00601 InjectedClassNameType> { 00602 public: 00603 CXXRecordDecl *getDecl() const { 00604 return getTypePtr()->getDecl(); 00605 } 00606 }; 00607 00608 /// \brief Wrapper for source info for unresolved typename using decls. 00609 class UnresolvedUsingTypeLoc : 00610 public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 00611 UnresolvedUsingTypeLoc, 00612 UnresolvedUsingType> { 00613 public: 00614 UnresolvedUsingTypenameDecl *getDecl() const { 00615 return getTypePtr()->getDecl(); 00616 } 00617 }; 00618 00619 /// \brief Wrapper for source info for tag types. Note that this only 00620 /// records source info for the name itself; a type written 'struct foo' 00621 /// should be represented as an ElaboratedTypeLoc. We currently 00622 /// only do that when C++ is enabled because of the expense of 00623 /// creating an ElaboratedType node for so many type references in C. 00624 class TagTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 00625 TagTypeLoc, 00626 TagType> { 00627 public: 00628 TagDecl *getDecl() const { return getTypePtr()->getDecl(); } 00629 00630 /// \brief True if the tag was defined in this type specifier. 00631 bool isDefinition() const { 00632 TagDecl *D = getDecl(); 00633 return D->isCompleteDefinition() && 00634 (D->getIdentifier() == nullptr || D->getLocation() == getNameLoc()); 00635 } 00636 }; 00637 00638 /// \brief Wrapper for source info for record types. 00639 class RecordTypeLoc : public InheritingConcreteTypeLoc<TagTypeLoc, 00640 RecordTypeLoc, 00641 RecordType> { 00642 public: 00643 RecordDecl *getDecl() const { return getTypePtr()->getDecl(); } 00644 }; 00645 00646 /// \brief Wrapper for source info for enum types. 00647 class EnumTypeLoc : public InheritingConcreteTypeLoc<TagTypeLoc, 00648 EnumTypeLoc, 00649 EnumType> { 00650 public: 00651 EnumDecl *getDecl() const { return getTypePtr()->getDecl(); } 00652 }; 00653 00654 /// \brief Wrapper for template type parameters. 00655 class TemplateTypeParmTypeLoc : 00656 public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 00657 TemplateTypeParmTypeLoc, 00658 TemplateTypeParmType> { 00659 public: 00660 TemplateTypeParmDecl *getDecl() const { return getTypePtr()->getDecl(); } 00661 }; 00662 00663 /// \brief Wrapper for substituted template type parameters. 00664 class SubstTemplateTypeParmTypeLoc : 00665 public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 00666 SubstTemplateTypeParmTypeLoc, 00667 SubstTemplateTypeParmType> { 00668 }; 00669 00670 /// \brief Wrapper for substituted template type parameters. 00671 class SubstTemplateTypeParmPackTypeLoc : 00672 public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 00673 SubstTemplateTypeParmPackTypeLoc, 00674 SubstTemplateTypeParmPackType> { 00675 }; 00676 00677 struct AttributedLocInfo { 00678 union { 00679 Expr *ExprOperand; 00680 00681 /// A raw SourceLocation. 00682 unsigned EnumOperandLoc; 00683 }; 00684 00685 SourceRange OperandParens; 00686 00687 SourceLocation AttrLoc; 00688 }; 00689 00690 /// \brief Type source information for an attributed type. 00691 class AttributedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, 00692 AttributedTypeLoc, 00693 AttributedType, 00694 AttributedLocInfo> { 00695 public: 00696 AttributedType::Kind getAttrKind() const { 00697 return getTypePtr()->getAttrKind(); 00698 } 00699 00700 bool hasAttrExprOperand() const { 00701 return (getAttrKind() >= AttributedType::FirstExprOperandKind && 00702 getAttrKind() <= AttributedType::LastExprOperandKind); 00703 } 00704 00705 bool hasAttrEnumOperand() const { 00706 return (getAttrKind() >= AttributedType::FirstEnumOperandKind && 00707 getAttrKind() <= AttributedType::LastEnumOperandKind); 00708 } 00709 00710 bool hasAttrOperand() const { 00711 return hasAttrExprOperand() || hasAttrEnumOperand(); 00712 } 00713 00714 /// The modified type, which is generally canonically different from 00715 /// the attribute type. 00716 /// int main(int, char**) __attribute__((noreturn)) 00717 /// ~~~ ~~~~~~~~~~~~~ 00718 TypeLoc getModifiedLoc() const { 00719 return getInnerTypeLoc(); 00720 } 00721 00722 /// The location of the attribute name, i.e. 00723 /// __attribute__((regparm(1000))) 00724 /// ^~~~~~~ 00725 SourceLocation getAttrNameLoc() const { 00726 return getLocalData()->AttrLoc; 00727 } 00728 void setAttrNameLoc(SourceLocation loc) { 00729 getLocalData()->AttrLoc = loc; 00730 } 00731 00732 /// The attribute's expression operand, if it has one. 00733 /// void *cur_thread __attribute__((address_space(21))) 00734 /// ^~ 00735 Expr *getAttrExprOperand() const { 00736 assert(hasAttrExprOperand()); 00737 return getLocalData()->ExprOperand; 00738 } 00739 void setAttrExprOperand(Expr *e) { 00740 assert(hasAttrExprOperand()); 00741 getLocalData()->ExprOperand = e; 00742 } 00743 00744 /// The location of the attribute's enumerated operand, if it has one. 00745 /// void * __attribute__((objc_gc(weak))) 00746 /// ^~~~ 00747 SourceLocation getAttrEnumOperandLoc() const { 00748 assert(hasAttrEnumOperand()); 00749 return SourceLocation::getFromRawEncoding(getLocalData()->EnumOperandLoc); 00750 } 00751 void setAttrEnumOperandLoc(SourceLocation loc) { 00752 assert(hasAttrEnumOperand()); 00753 getLocalData()->EnumOperandLoc = loc.getRawEncoding(); 00754 } 00755 00756 /// The location of the parentheses around the operand, if there is 00757 /// an operand. 00758 /// void * __attribute__((objc_gc(weak))) 00759 /// ^ ^ 00760 SourceRange getAttrOperandParensRange() const { 00761 assert(hasAttrOperand()); 00762 return getLocalData()->OperandParens; 00763 } 00764 void setAttrOperandParensRange(SourceRange range) { 00765 assert(hasAttrOperand()); 00766 getLocalData()->OperandParens = range; 00767 } 00768 00769 SourceRange getLocalSourceRange() const { 00770 // Note that this does *not* include the range of the attribute 00771 // enclosure, e.g.: 00772 // __attribute__((foo(bar))) 00773 // ^~~~~~~~~~~~~~~ ~~ 00774 // or 00775 // [[foo(bar)]] 00776 // ^~ ~~ 00777 // That enclosure doesn't necessarily belong to a single attribute 00778 // anyway. 00779 SourceRange range(getAttrNameLoc()); 00780 if (hasAttrOperand()) 00781 range.setEnd(getAttrOperandParensRange().getEnd()); 00782 return range; 00783 } 00784 00785 void initializeLocal(ASTContext &Context, SourceLocation loc) { 00786 setAttrNameLoc(loc); 00787 if (hasAttrExprOperand()) { 00788 setAttrOperandParensRange(SourceRange(loc)); 00789 setAttrExprOperand(nullptr); 00790 } else if (hasAttrEnumOperand()) { 00791 setAttrOperandParensRange(SourceRange(loc)); 00792 setAttrEnumOperandLoc(loc); 00793 } 00794 } 00795 00796 QualType getInnerType() const { 00797 return getTypePtr()->getModifiedType(); 00798 } 00799 }; 00800 00801 00802 struct ObjCProtocolListLocInfo { 00803 SourceLocation LAngleLoc; 00804 SourceLocation RAngleLoc; 00805 bool HasBaseTypeAsWritten; 00806 }; 00807 00808 // A helper class for defining ObjC TypeLocs that can qualified with 00809 // protocols. 00810 // 00811 // TypeClass basically has to be either ObjCInterfaceType or 00812 // ObjCObjectPointerType. 00813 class ObjCObjectTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, 00814 ObjCObjectTypeLoc, 00815 ObjCObjectType, 00816 ObjCProtocolListLocInfo> { 00817 // SourceLocations are stored after Info, one for each Protocol. 00818 SourceLocation *getProtocolLocArray() const { 00819 return (SourceLocation*) this->getExtraLocalData(); 00820 } 00821 00822 public: 00823 SourceLocation getLAngleLoc() const { 00824 return this->getLocalData()->LAngleLoc; 00825 } 00826 void setLAngleLoc(SourceLocation Loc) { 00827 this->getLocalData()->LAngleLoc = Loc; 00828 } 00829 00830 SourceLocation getRAngleLoc() const { 00831 return this->getLocalData()->RAngleLoc; 00832 } 00833 void setRAngleLoc(SourceLocation Loc) { 00834 this->getLocalData()->RAngleLoc = Loc; 00835 } 00836 00837 unsigned getNumProtocols() const { 00838 return this->getTypePtr()->getNumProtocols(); 00839 } 00840 00841 SourceLocation getProtocolLoc(unsigned i) const { 00842 assert(i < getNumProtocols() && "Index is out of bounds!"); 00843 return getProtocolLocArray()[i]; 00844 } 00845 void setProtocolLoc(unsigned i, SourceLocation Loc) { 00846 assert(i < getNumProtocols() && "Index is out of bounds!"); 00847 getProtocolLocArray()[i] = Loc; 00848 } 00849 00850 ObjCProtocolDecl *getProtocol(unsigned i) const { 00851 assert(i < getNumProtocols() && "Index is out of bounds!"); 00852 return *(this->getTypePtr()->qual_begin() + i); 00853 } 00854 00855 bool hasBaseTypeAsWritten() const { 00856 return getLocalData()->HasBaseTypeAsWritten; 00857 } 00858 00859 void setHasBaseTypeAsWritten(bool HasBaseType) { 00860 getLocalData()->HasBaseTypeAsWritten = HasBaseType; 00861 } 00862 00863 TypeLoc getBaseLoc() const { 00864 return getInnerTypeLoc(); 00865 } 00866 00867 SourceRange getLocalSourceRange() const { 00868 return SourceRange(getLAngleLoc(), getRAngleLoc()); 00869 } 00870 00871 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 00872 setHasBaseTypeAsWritten(true); 00873 setLAngleLoc(Loc); 00874 setRAngleLoc(Loc); 00875 for (unsigned i = 0, e = getNumProtocols(); i != e; ++i) 00876 setProtocolLoc(i, Loc); 00877 } 00878 00879 unsigned getExtraLocalDataSize() const { 00880 return this->getNumProtocols() * sizeof(SourceLocation); 00881 } 00882 00883 unsigned getExtraLocalDataAlignment() const { 00884 return llvm::alignOf<SourceLocation>(); 00885 } 00886 00887 QualType getInnerType() const { 00888 return getTypePtr()->getBaseType(); 00889 } 00890 }; 00891 00892 00893 struct ObjCInterfaceLocInfo { 00894 SourceLocation NameLoc; 00895 SourceLocation NameEndLoc; 00896 }; 00897 00898 /// \brief Wrapper for source info for ObjC interfaces. 00899 class ObjCInterfaceTypeLoc : public ConcreteTypeLoc<ObjCObjectTypeLoc, 00900 ObjCInterfaceTypeLoc, 00901 ObjCInterfaceType, 00902 ObjCInterfaceLocInfo> { 00903 public: 00904 ObjCInterfaceDecl *getIFaceDecl() const { 00905 return getTypePtr()->getDecl(); 00906 } 00907 00908 SourceLocation getNameLoc() const { 00909 return getLocalData()->NameLoc; 00910 } 00911 00912 void setNameLoc(SourceLocation Loc) { 00913 getLocalData()->NameLoc = Loc; 00914 } 00915 00916 SourceRange getLocalSourceRange() const { 00917 return SourceRange(getNameLoc(), getNameEndLoc()); 00918 } 00919 00920 SourceLocation getNameEndLoc() const { 00921 return getLocalData()->NameEndLoc; 00922 } 00923 00924 void setNameEndLoc(SourceLocation Loc) { 00925 getLocalData()->NameEndLoc = Loc; 00926 } 00927 00928 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 00929 setNameLoc(Loc); 00930 setNameEndLoc(Loc); 00931 } 00932 }; 00933 00934 struct ParenLocInfo { 00935 SourceLocation LParenLoc; 00936 SourceLocation RParenLoc; 00937 }; 00938 00939 class ParenTypeLoc 00940 : public ConcreteTypeLoc<UnqualTypeLoc, ParenTypeLoc, ParenType, 00941 ParenLocInfo> { 00942 public: 00943 SourceLocation getLParenLoc() const { 00944 return this->getLocalData()->LParenLoc; 00945 } 00946 SourceLocation getRParenLoc() const { 00947 return this->getLocalData()->RParenLoc; 00948 } 00949 void setLParenLoc(SourceLocation Loc) { 00950 this->getLocalData()->LParenLoc = Loc; 00951 } 00952 void setRParenLoc(SourceLocation Loc) { 00953 this->getLocalData()->RParenLoc = Loc; 00954 } 00955 00956 SourceRange getLocalSourceRange() const { 00957 return SourceRange(getLParenLoc(), getRParenLoc()); 00958 } 00959 00960 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 00961 setLParenLoc(Loc); 00962 setRParenLoc(Loc); 00963 } 00964 00965 TypeLoc getInnerLoc() const { 00966 return getInnerTypeLoc(); 00967 } 00968 00969 QualType getInnerType() const { 00970 return this->getTypePtr()->getInnerType(); 00971 } 00972 }; 00973 00974 inline TypeLoc TypeLoc::IgnoreParens() const { 00975 if (ParenTypeLoc::isKind(*this)) 00976 return IgnoreParensImpl(*this); 00977 return *this; 00978 } 00979 00980 00981 struct AdjustedLocInfo { }; // Nothing. 00982 00983 class AdjustedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, AdjustedTypeLoc, 00984 AdjustedType, AdjustedLocInfo> { 00985 public: 00986 TypeLoc getOriginalLoc() const { 00987 return getInnerTypeLoc(); 00988 } 00989 00990 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 00991 // do nothing 00992 } 00993 00994 QualType getInnerType() const { 00995 // The inner type is the undecayed type, since that's what we have source 00996 // location information for. 00997 return getTypePtr()->getOriginalType(); 00998 } 00999 01000 SourceRange getLocalSourceRange() const { 01001 return SourceRange(); 01002 } 01003 01004 unsigned getLocalDataSize() const { 01005 // sizeof(AdjustedLocInfo) is 1, but we don't need its address to be unique 01006 // anyway. TypeLocBuilder can't handle data sizes of 1. 01007 return 0; // No data. 01008 } 01009 }; 01010 01011 /// \brief Wrapper for source info for pointers decayed from arrays and 01012 /// functions. 01013 class DecayedTypeLoc : public InheritingConcreteTypeLoc< 01014 AdjustedTypeLoc, DecayedTypeLoc, DecayedType> { 01015 }; 01016 01017 struct PointerLikeLocInfo { 01018 SourceLocation StarLoc; 01019 }; 01020 01021 /// A base class for 01022 template <class Derived, class TypeClass, class LocalData = PointerLikeLocInfo> 01023 class PointerLikeTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, Derived, 01024 TypeClass, LocalData> { 01025 public: 01026 SourceLocation getSigilLoc() const { 01027 return this->getLocalData()->StarLoc; 01028 } 01029 void setSigilLoc(SourceLocation Loc) { 01030 this->getLocalData()->StarLoc = Loc; 01031 } 01032 01033 TypeLoc getPointeeLoc() const { 01034 return this->getInnerTypeLoc(); 01035 } 01036 01037 SourceRange getLocalSourceRange() const { 01038 return SourceRange(getSigilLoc(), getSigilLoc()); 01039 } 01040 01041 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 01042 setSigilLoc(Loc); 01043 } 01044 01045 QualType getInnerType() const { 01046 return this->getTypePtr()->getPointeeType(); 01047 } 01048 }; 01049 01050 01051 /// \brief Wrapper for source info for pointers. 01052 class PointerTypeLoc : public PointerLikeTypeLoc<PointerTypeLoc, 01053 PointerType> { 01054 public: 01055 SourceLocation getStarLoc() const { 01056 return getSigilLoc(); 01057 } 01058 void setStarLoc(SourceLocation Loc) { 01059 setSigilLoc(Loc); 01060 } 01061 }; 01062 01063 01064 /// \brief Wrapper for source info for block pointers. 01065 class BlockPointerTypeLoc : public PointerLikeTypeLoc<BlockPointerTypeLoc, 01066 BlockPointerType> { 01067 public: 01068 SourceLocation getCaretLoc() const { 01069 return getSigilLoc(); 01070 } 01071 void setCaretLoc(SourceLocation Loc) { 01072 setSigilLoc(Loc); 01073 } 01074 }; 01075 01076 struct MemberPointerLocInfo : public PointerLikeLocInfo { 01077 TypeSourceInfo *ClassTInfo; 01078 }; 01079 01080 /// \brief Wrapper for source info for member pointers. 01081 class MemberPointerTypeLoc : public PointerLikeTypeLoc<MemberPointerTypeLoc, 01082 MemberPointerType, 01083 MemberPointerLocInfo> { 01084 public: 01085 SourceLocation getStarLoc() const { 01086 return getSigilLoc(); 01087 } 01088 void setStarLoc(SourceLocation Loc) { 01089 setSigilLoc(Loc); 01090 } 01091 01092 const Type *getClass() const { 01093 return getTypePtr()->getClass(); 01094 } 01095 TypeSourceInfo *getClassTInfo() const { 01096 return getLocalData()->ClassTInfo; 01097 } 01098 void setClassTInfo(TypeSourceInfo* TI) { 01099 getLocalData()->ClassTInfo = TI; 01100 } 01101 01102 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 01103 setSigilLoc(Loc); 01104 setClassTInfo(nullptr); 01105 } 01106 01107 SourceRange getLocalSourceRange() const { 01108 if (TypeSourceInfo *TI = getClassTInfo()) 01109 return SourceRange(TI->getTypeLoc().getBeginLoc(), getStarLoc()); 01110 else 01111 return SourceRange(getStarLoc()); 01112 } 01113 }; 01114 01115 /// Wraps an ObjCPointerType with source location information. 01116 class ObjCObjectPointerTypeLoc : 01117 public PointerLikeTypeLoc<ObjCObjectPointerTypeLoc, 01118 ObjCObjectPointerType> { 01119 public: 01120 SourceLocation getStarLoc() const { 01121 return getSigilLoc(); 01122 } 01123 01124 void setStarLoc(SourceLocation Loc) { 01125 setSigilLoc(Loc); 01126 } 01127 }; 01128 01129 01130 class ReferenceTypeLoc : public PointerLikeTypeLoc<ReferenceTypeLoc, 01131 ReferenceType> { 01132 public: 01133 QualType getInnerType() const { 01134 return getTypePtr()->getPointeeTypeAsWritten(); 01135 } 01136 }; 01137 01138 class LValueReferenceTypeLoc : 01139 public InheritingConcreteTypeLoc<ReferenceTypeLoc, 01140 LValueReferenceTypeLoc, 01141 LValueReferenceType> { 01142 public: 01143 SourceLocation getAmpLoc() const { 01144 return getSigilLoc(); 01145 } 01146 void setAmpLoc(SourceLocation Loc) { 01147 setSigilLoc(Loc); 01148 } 01149 }; 01150 01151 class RValueReferenceTypeLoc : 01152 public InheritingConcreteTypeLoc<ReferenceTypeLoc, 01153 RValueReferenceTypeLoc, 01154 RValueReferenceType> { 01155 public: 01156 SourceLocation getAmpAmpLoc() const { 01157 return getSigilLoc(); 01158 } 01159 void setAmpAmpLoc(SourceLocation Loc) { 01160 setSigilLoc(Loc); 01161 } 01162 }; 01163 01164 01165 struct FunctionLocInfo { 01166 SourceLocation LocalRangeBegin; 01167 SourceLocation LParenLoc; 01168 SourceLocation RParenLoc; 01169 SourceLocation LocalRangeEnd; 01170 }; 01171 01172 /// \brief Wrapper for source info for functions. 01173 class FunctionTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, 01174 FunctionTypeLoc, 01175 FunctionType, 01176 FunctionLocInfo> { 01177 public: 01178 SourceLocation getLocalRangeBegin() const { 01179 return getLocalData()->LocalRangeBegin; 01180 } 01181 void setLocalRangeBegin(SourceLocation L) { 01182 getLocalData()->LocalRangeBegin = L; 01183 } 01184 01185 SourceLocation getLocalRangeEnd() const { 01186 return getLocalData()->LocalRangeEnd; 01187 } 01188 void setLocalRangeEnd(SourceLocation L) { 01189 getLocalData()->LocalRangeEnd = L; 01190 } 01191 01192 SourceLocation getLParenLoc() const { 01193 return this->getLocalData()->LParenLoc; 01194 } 01195 void setLParenLoc(SourceLocation Loc) { 01196 this->getLocalData()->LParenLoc = Loc; 01197 } 01198 01199 SourceLocation getRParenLoc() const { 01200 return this->getLocalData()->RParenLoc; 01201 } 01202 void setRParenLoc(SourceLocation Loc) { 01203 this->getLocalData()->RParenLoc = Loc; 01204 } 01205 01206 SourceRange getParensRange() const { 01207 return SourceRange(getLParenLoc(), getRParenLoc()); 01208 } 01209 01210 ArrayRef<ParmVarDecl *> getParams() const { 01211 return llvm::makeArrayRef(getParmArray(), getNumParams()); 01212 } 01213 01214 // ParmVarDecls* are stored after Info, one for each parameter. 01215 ParmVarDecl **getParmArray() const { 01216 return (ParmVarDecl**) getExtraLocalData(); 01217 } 01218 01219 unsigned getNumParams() const { 01220 if (isa<FunctionNoProtoType>(getTypePtr())) 01221 return 0; 01222 return cast<FunctionProtoType>(getTypePtr())->getNumParams(); 01223 } 01224 ParmVarDecl *getParam(unsigned i) const { return getParmArray()[i]; } 01225 void setParam(unsigned i, ParmVarDecl *VD) { getParmArray()[i] = VD; } 01226 01227 TypeLoc getReturnLoc() const { 01228 return getInnerTypeLoc(); 01229 } 01230 01231 SourceRange getLocalSourceRange() const { 01232 return SourceRange(getLocalRangeBegin(), getLocalRangeEnd()); 01233 } 01234 01235 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 01236 setLocalRangeBegin(Loc); 01237 setLParenLoc(Loc); 01238 setRParenLoc(Loc); 01239 setLocalRangeEnd(Loc); 01240 for (unsigned i = 0, e = getNumParams(); i != e; ++i) 01241 setParam(i, nullptr); 01242 } 01243 01244 /// \brief Returns the size of the type source info data block that is 01245 /// specific to this type. 01246 unsigned getExtraLocalDataSize() const { 01247 return getNumParams() * sizeof(ParmVarDecl *); 01248 } 01249 01250 unsigned getExtraLocalDataAlignment() const { 01251 return llvm::alignOf<ParmVarDecl*>(); 01252 } 01253 01254 QualType getInnerType() const { return getTypePtr()->getReturnType(); } 01255 }; 01256 01257 class FunctionProtoTypeLoc : 01258 public InheritingConcreteTypeLoc<FunctionTypeLoc, 01259 FunctionProtoTypeLoc, 01260 FunctionProtoType> { 01261 }; 01262 01263 class FunctionNoProtoTypeLoc : 01264 public InheritingConcreteTypeLoc<FunctionTypeLoc, 01265 FunctionNoProtoTypeLoc, 01266 FunctionNoProtoType> { 01267 }; 01268 01269 01270 struct ArrayLocInfo { 01271 SourceLocation LBracketLoc, RBracketLoc; 01272 Expr *Size; 01273 }; 01274 01275 /// \brief Wrapper for source info for arrays. 01276 class ArrayTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, 01277 ArrayTypeLoc, 01278 ArrayType, 01279 ArrayLocInfo> { 01280 public: 01281 SourceLocation getLBracketLoc() const { 01282 return getLocalData()->LBracketLoc; 01283 } 01284 void setLBracketLoc(SourceLocation Loc) { 01285 getLocalData()->LBracketLoc = Loc; 01286 } 01287 01288 SourceLocation getRBracketLoc() const { 01289 return getLocalData()->RBracketLoc; 01290 } 01291 void setRBracketLoc(SourceLocation Loc) { 01292 getLocalData()->RBracketLoc = Loc; 01293 } 01294 01295 SourceRange getBracketsRange() const { 01296 return SourceRange(getLBracketLoc(), getRBracketLoc()); 01297 } 01298 01299 Expr *getSizeExpr() const { 01300 return getLocalData()->Size; 01301 } 01302 void setSizeExpr(Expr *Size) { 01303 getLocalData()->Size = Size; 01304 } 01305 01306 TypeLoc getElementLoc() const { 01307 return getInnerTypeLoc(); 01308 } 01309 01310 SourceRange getLocalSourceRange() const { 01311 return SourceRange(getLBracketLoc(), getRBracketLoc()); 01312 } 01313 01314 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 01315 setLBracketLoc(Loc); 01316 setRBracketLoc(Loc); 01317 setSizeExpr(nullptr); 01318 } 01319 01320 QualType getInnerType() const { return getTypePtr()->getElementType(); } 01321 }; 01322 01323 class ConstantArrayTypeLoc : 01324 public InheritingConcreteTypeLoc<ArrayTypeLoc, 01325 ConstantArrayTypeLoc, 01326 ConstantArrayType> { 01327 }; 01328 01329 class IncompleteArrayTypeLoc : 01330 public InheritingConcreteTypeLoc<ArrayTypeLoc, 01331 IncompleteArrayTypeLoc, 01332 IncompleteArrayType> { 01333 }; 01334 01335 class DependentSizedArrayTypeLoc : 01336 public InheritingConcreteTypeLoc<ArrayTypeLoc, 01337 DependentSizedArrayTypeLoc, 01338 DependentSizedArrayType> { 01339 01340 }; 01341 01342 class VariableArrayTypeLoc : 01343 public InheritingConcreteTypeLoc<ArrayTypeLoc, 01344 VariableArrayTypeLoc, 01345 VariableArrayType> { 01346 }; 01347 01348 01349 // Location information for a TemplateName. Rudimentary for now. 01350 struct TemplateNameLocInfo { 01351 SourceLocation NameLoc; 01352 }; 01353 01354 struct TemplateSpecializationLocInfo : TemplateNameLocInfo { 01355 SourceLocation TemplateKWLoc; 01356 SourceLocation LAngleLoc; 01357 SourceLocation RAngleLoc; 01358 }; 01359 01360 class TemplateSpecializationTypeLoc : 01361 public ConcreteTypeLoc<UnqualTypeLoc, 01362 TemplateSpecializationTypeLoc, 01363 TemplateSpecializationType, 01364 TemplateSpecializationLocInfo> { 01365 public: 01366 SourceLocation getTemplateKeywordLoc() const { 01367 return getLocalData()->TemplateKWLoc; 01368 } 01369 void setTemplateKeywordLoc(SourceLocation Loc) { 01370 getLocalData()->TemplateKWLoc = Loc; 01371 } 01372 01373 SourceLocation getLAngleLoc() const { 01374 return getLocalData()->LAngleLoc; 01375 } 01376 void setLAngleLoc(SourceLocation Loc) { 01377 getLocalData()->LAngleLoc = Loc; 01378 } 01379 01380 SourceLocation getRAngleLoc() const { 01381 return getLocalData()->RAngleLoc; 01382 } 01383 void setRAngleLoc(SourceLocation Loc) { 01384 getLocalData()->RAngleLoc = Loc; 01385 } 01386 01387 unsigned getNumArgs() const { 01388 return getTypePtr()->getNumArgs(); 01389 } 01390 void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) { 01391 getArgInfos()[i] = AI; 01392 } 01393 TemplateArgumentLocInfo getArgLocInfo(unsigned i) const { 01394 return getArgInfos()[i]; 01395 } 01396 01397 TemplateArgumentLoc getArgLoc(unsigned i) const { 01398 return TemplateArgumentLoc(getTypePtr()->getArg(i), getArgLocInfo(i)); 01399 } 01400 01401 SourceLocation getTemplateNameLoc() const { 01402 return getLocalData()->NameLoc; 01403 } 01404 void setTemplateNameLoc(SourceLocation Loc) { 01405 getLocalData()->NameLoc = Loc; 01406 } 01407 01408 /// \brief - Copy the location information from the given info. 01409 void copy(TemplateSpecializationTypeLoc Loc) { 01410 unsigned size = getFullDataSize(); 01411 assert(size == Loc.getFullDataSize()); 01412 01413 // We're potentially copying Expr references here. We don't 01414 // bother retaining them because TypeSourceInfos live forever, so 01415 // as long as the Expr was retained when originally written into 01416 // the TypeLoc, we're okay. 01417 memcpy(Data, Loc.Data, size); 01418 } 01419 01420 SourceRange getLocalSourceRange() const { 01421 if (getTemplateKeywordLoc().isValid()) 01422 return SourceRange(getTemplateKeywordLoc(), getRAngleLoc()); 01423 else 01424 return SourceRange(getTemplateNameLoc(), getRAngleLoc()); 01425 } 01426 01427 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 01428 setTemplateKeywordLoc(Loc); 01429 setTemplateNameLoc(Loc); 01430 setLAngleLoc(Loc); 01431 setRAngleLoc(Loc); 01432 initializeArgLocs(Context, getNumArgs(), getTypePtr()->getArgs(), 01433 getArgInfos(), Loc); 01434 } 01435 01436 static void initializeArgLocs(ASTContext &Context, unsigned NumArgs, 01437 const TemplateArgument *Args, 01438 TemplateArgumentLocInfo *ArgInfos, 01439 SourceLocation Loc); 01440 01441 unsigned getExtraLocalDataSize() const { 01442 return getNumArgs() * sizeof(TemplateArgumentLocInfo); 01443 } 01444 01445 unsigned getExtraLocalDataAlignment() const { 01446 return llvm::alignOf<TemplateArgumentLocInfo>(); 01447 } 01448 01449 private: 01450 TemplateArgumentLocInfo *getArgInfos() const { 01451 return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData()); 01452 } 01453 }; 01454 01455 //===----------------------------------------------------------------------===// 01456 // 01457 // All of these need proper implementations. 01458 // 01459 //===----------------------------------------------------------------------===// 01460 01461 // FIXME: size expression and attribute locations (or keyword if we 01462 // ever fully support altivec syntax). 01463 class VectorTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 01464 VectorTypeLoc, 01465 VectorType> { 01466 }; 01467 01468 // FIXME: size expression and attribute locations. 01469 class ExtVectorTypeLoc : public InheritingConcreteTypeLoc<VectorTypeLoc, 01470 ExtVectorTypeLoc, 01471 ExtVectorType> { 01472 }; 01473 01474 // FIXME: attribute locations. 01475 // For some reason, this isn't a subtype of VectorType. 01476 class DependentSizedExtVectorTypeLoc : 01477 public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 01478 DependentSizedExtVectorTypeLoc, 01479 DependentSizedExtVectorType> { 01480 }; 01481 01482 // FIXME: location of the '_Complex' keyword. 01483 class ComplexTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 01484 ComplexTypeLoc, 01485 ComplexType> { 01486 }; 01487 01488 struct TypeofLocInfo { 01489 SourceLocation TypeofLoc; 01490 SourceLocation LParenLoc; 01491 SourceLocation RParenLoc; 01492 }; 01493 01494 struct TypeOfExprTypeLocInfo : public TypeofLocInfo { 01495 }; 01496 01497 struct TypeOfTypeLocInfo : public TypeofLocInfo { 01498 TypeSourceInfo* UnderlyingTInfo; 01499 }; 01500 01501 template <class Derived, class TypeClass, class LocalData = TypeofLocInfo> 01502 class TypeofLikeTypeLoc 01503 : public ConcreteTypeLoc<UnqualTypeLoc, Derived, TypeClass, LocalData> { 01504 public: 01505 SourceLocation getTypeofLoc() const { 01506 return this->getLocalData()->TypeofLoc; 01507 } 01508 void setTypeofLoc(SourceLocation Loc) { 01509 this->getLocalData()->TypeofLoc = Loc; 01510 } 01511 01512 SourceLocation getLParenLoc() const { 01513 return this->getLocalData()->LParenLoc; 01514 } 01515 void setLParenLoc(SourceLocation Loc) { 01516 this->getLocalData()->LParenLoc = Loc; 01517 } 01518 01519 SourceLocation getRParenLoc() const { 01520 return this->getLocalData()->RParenLoc; 01521 } 01522 void setRParenLoc(SourceLocation Loc) { 01523 this->getLocalData()->RParenLoc = Loc; 01524 } 01525 01526 SourceRange getParensRange() const { 01527 return SourceRange(getLParenLoc(), getRParenLoc()); 01528 } 01529 void setParensRange(SourceRange range) { 01530 setLParenLoc(range.getBegin()); 01531 setRParenLoc(range.getEnd()); 01532 } 01533 01534 SourceRange getLocalSourceRange() const { 01535 return SourceRange(getTypeofLoc(), getRParenLoc()); 01536 } 01537 01538 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 01539 setTypeofLoc(Loc); 01540 setLParenLoc(Loc); 01541 setRParenLoc(Loc); 01542 } 01543 }; 01544 01545 class TypeOfExprTypeLoc : public TypeofLikeTypeLoc<TypeOfExprTypeLoc, 01546 TypeOfExprType, 01547 TypeOfExprTypeLocInfo> { 01548 public: 01549 Expr* getUnderlyingExpr() const { 01550 return getTypePtr()->getUnderlyingExpr(); 01551 } 01552 // Reimplemented to account for GNU/C++ extension 01553 // typeof unary-expression 01554 // where there are no parentheses. 01555 SourceRange getLocalSourceRange() const; 01556 }; 01557 01558 class TypeOfTypeLoc 01559 : public TypeofLikeTypeLoc<TypeOfTypeLoc, TypeOfType, TypeOfTypeLocInfo> { 01560 public: 01561 QualType getUnderlyingType() const { 01562 return this->getTypePtr()->getUnderlyingType(); 01563 } 01564 TypeSourceInfo* getUnderlyingTInfo() const { 01565 return this->getLocalData()->UnderlyingTInfo; 01566 } 01567 void setUnderlyingTInfo(TypeSourceInfo* TI) const { 01568 this->getLocalData()->UnderlyingTInfo = TI; 01569 } 01570 01571 void initializeLocal(ASTContext &Context, SourceLocation Loc); 01572 }; 01573 01574 // FIXME: location of the 'decltype' and parens. 01575 class DecltypeTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 01576 DecltypeTypeLoc, 01577 DecltypeType> { 01578 public: 01579 Expr *getUnderlyingExpr() const { return getTypePtr()->getUnderlyingExpr(); } 01580 }; 01581 01582 struct UnaryTransformTypeLocInfo { 01583 // FIXME: While there's only one unary transform right now, future ones may 01584 // need different representations 01585 SourceLocation KWLoc, LParenLoc, RParenLoc; 01586 TypeSourceInfo *UnderlyingTInfo; 01587 }; 01588 01589 class UnaryTransformTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, 01590 UnaryTransformTypeLoc, 01591 UnaryTransformType, 01592 UnaryTransformTypeLocInfo> { 01593 public: 01594 SourceLocation getKWLoc() const { return getLocalData()->KWLoc; } 01595 void setKWLoc(SourceLocation Loc) { getLocalData()->KWLoc = Loc; } 01596 01597 SourceLocation getLParenLoc() const { return getLocalData()->LParenLoc; } 01598 void setLParenLoc(SourceLocation Loc) { getLocalData()->LParenLoc = Loc; } 01599 01600 SourceLocation getRParenLoc() const { return getLocalData()->RParenLoc; } 01601 void setRParenLoc(SourceLocation Loc) { getLocalData()->RParenLoc = Loc; } 01602 01603 TypeSourceInfo* getUnderlyingTInfo() const { 01604 return getLocalData()->UnderlyingTInfo; 01605 } 01606 void setUnderlyingTInfo(TypeSourceInfo *TInfo) { 01607 getLocalData()->UnderlyingTInfo = TInfo; 01608 } 01609 01610 SourceRange getLocalSourceRange() const { 01611 return SourceRange(getKWLoc(), getRParenLoc()); 01612 } 01613 01614 SourceRange getParensRange() const { 01615 return SourceRange(getLParenLoc(), getRParenLoc()); 01616 } 01617 void setParensRange(SourceRange Range) { 01618 setLParenLoc(Range.getBegin()); 01619 setRParenLoc(Range.getEnd()); 01620 } 01621 01622 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 01623 setKWLoc(Loc); 01624 setRParenLoc(Loc); 01625 setLParenLoc(Loc); 01626 } 01627 }; 01628 01629 class AutoTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 01630 AutoTypeLoc, 01631 AutoType> { 01632 }; 01633 01634 struct ElaboratedLocInfo { 01635 SourceLocation ElaboratedKWLoc; 01636 /// \brief Data associated with the nested-name-specifier location. 01637 void *QualifierData; 01638 }; 01639 01640 class ElaboratedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, 01641 ElaboratedTypeLoc, 01642 ElaboratedType, 01643 ElaboratedLocInfo> { 01644 public: 01645 SourceLocation getElaboratedKeywordLoc() const { 01646 return this->getLocalData()->ElaboratedKWLoc; 01647 } 01648 void setElaboratedKeywordLoc(SourceLocation Loc) { 01649 this->getLocalData()->ElaboratedKWLoc = Loc; 01650 } 01651 01652 NestedNameSpecifierLoc getQualifierLoc() const { 01653 return NestedNameSpecifierLoc(getTypePtr()->getQualifier(), 01654 getLocalData()->QualifierData); 01655 } 01656 01657 void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) { 01658 assert(QualifierLoc.getNestedNameSpecifier() 01659 == getTypePtr()->getQualifier() && 01660 "Inconsistent nested-name-specifier pointer"); 01661 getLocalData()->QualifierData = QualifierLoc.getOpaqueData(); 01662 } 01663 01664 SourceRange getLocalSourceRange() const { 01665 if (getElaboratedKeywordLoc().isValid()) 01666 if (getQualifierLoc()) 01667 return SourceRange(getElaboratedKeywordLoc(), 01668 getQualifierLoc().getEndLoc()); 01669 else 01670 return SourceRange(getElaboratedKeywordLoc()); 01671 else 01672 return getQualifierLoc().getSourceRange(); 01673 } 01674 01675 void initializeLocal(ASTContext &Context, SourceLocation Loc); 01676 01677 TypeLoc getNamedTypeLoc() const { 01678 return getInnerTypeLoc(); 01679 } 01680 01681 QualType getInnerType() const { 01682 return getTypePtr()->getNamedType(); 01683 } 01684 01685 void copy(ElaboratedTypeLoc Loc) { 01686 unsigned size = getFullDataSize(); 01687 assert(size == Loc.getFullDataSize()); 01688 memcpy(Data, Loc.Data, size); 01689 } 01690 }; 01691 01692 // This is exactly the structure of an ElaboratedTypeLoc whose inner 01693 // type is some sort of TypeDeclTypeLoc. 01694 struct DependentNameLocInfo : ElaboratedLocInfo { 01695 SourceLocation NameLoc; 01696 }; 01697 01698 class DependentNameTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, 01699 DependentNameTypeLoc, 01700 DependentNameType, 01701 DependentNameLocInfo> { 01702 public: 01703 SourceLocation getElaboratedKeywordLoc() const { 01704 return this->getLocalData()->ElaboratedKWLoc; 01705 } 01706 void setElaboratedKeywordLoc(SourceLocation Loc) { 01707 this->getLocalData()->ElaboratedKWLoc = Loc; 01708 } 01709 01710 NestedNameSpecifierLoc getQualifierLoc() const { 01711 return NestedNameSpecifierLoc(getTypePtr()->getQualifier(), 01712 getLocalData()->QualifierData); 01713 } 01714 01715 void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) { 01716 assert(QualifierLoc.getNestedNameSpecifier() 01717 == getTypePtr()->getQualifier() && 01718 "Inconsistent nested-name-specifier pointer"); 01719 getLocalData()->QualifierData = QualifierLoc.getOpaqueData(); 01720 } 01721 01722 SourceLocation getNameLoc() const { 01723 return this->getLocalData()->NameLoc; 01724 } 01725 void setNameLoc(SourceLocation Loc) { 01726 this->getLocalData()->NameLoc = Loc; 01727 } 01728 01729 SourceRange getLocalSourceRange() const { 01730 if (getElaboratedKeywordLoc().isValid()) 01731 return SourceRange(getElaboratedKeywordLoc(), getNameLoc()); 01732 else 01733 return SourceRange(getQualifierLoc().getBeginLoc(), getNameLoc()); 01734 } 01735 01736 void copy(DependentNameTypeLoc Loc) { 01737 unsigned size = getFullDataSize(); 01738 assert(size == Loc.getFullDataSize()); 01739 memcpy(Data, Loc.Data, size); 01740 } 01741 01742 void initializeLocal(ASTContext &Context, SourceLocation Loc); 01743 }; 01744 01745 struct DependentTemplateSpecializationLocInfo : DependentNameLocInfo { 01746 SourceLocation TemplateKWLoc; 01747 SourceLocation LAngleLoc; 01748 SourceLocation RAngleLoc; 01749 // followed by a TemplateArgumentLocInfo[] 01750 }; 01751 01752 class DependentTemplateSpecializationTypeLoc : 01753 public ConcreteTypeLoc<UnqualTypeLoc, 01754 DependentTemplateSpecializationTypeLoc, 01755 DependentTemplateSpecializationType, 01756 DependentTemplateSpecializationLocInfo> { 01757 public: 01758 SourceLocation getElaboratedKeywordLoc() const { 01759 return this->getLocalData()->ElaboratedKWLoc; 01760 } 01761 void setElaboratedKeywordLoc(SourceLocation Loc) { 01762 this->getLocalData()->ElaboratedKWLoc = Loc; 01763 } 01764 01765 NestedNameSpecifierLoc getQualifierLoc() const { 01766 if (!getLocalData()->QualifierData) 01767 return NestedNameSpecifierLoc(); 01768 01769 return NestedNameSpecifierLoc(getTypePtr()->getQualifier(), 01770 getLocalData()->QualifierData); 01771 } 01772 01773 void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) { 01774 if (!QualifierLoc) { 01775 // Even if we have a nested-name-specifier in the dependent 01776 // template specialization type, we won't record the nested-name-specifier 01777 // location information when this type-source location information is 01778 // part of a nested-name-specifier. 01779 getLocalData()->QualifierData = nullptr; 01780 return; 01781 } 01782 01783 assert(QualifierLoc.getNestedNameSpecifier() 01784 == getTypePtr()->getQualifier() && 01785 "Inconsistent nested-name-specifier pointer"); 01786 getLocalData()->QualifierData = QualifierLoc.getOpaqueData(); 01787 } 01788 01789 SourceLocation getTemplateKeywordLoc() const { 01790 return getLocalData()->TemplateKWLoc; 01791 } 01792 void setTemplateKeywordLoc(SourceLocation Loc) { 01793 getLocalData()->TemplateKWLoc = Loc; 01794 } 01795 01796 SourceLocation getTemplateNameLoc() const { 01797 return this->getLocalData()->NameLoc; 01798 } 01799 void setTemplateNameLoc(SourceLocation Loc) { 01800 this->getLocalData()->NameLoc = Loc; 01801 } 01802 01803 SourceLocation getLAngleLoc() const { 01804 return this->getLocalData()->LAngleLoc; 01805 } 01806 void setLAngleLoc(SourceLocation Loc) { 01807 this->getLocalData()->LAngleLoc = Loc; 01808 } 01809 01810 SourceLocation getRAngleLoc() const { 01811 return this->getLocalData()->RAngleLoc; 01812 } 01813 void setRAngleLoc(SourceLocation Loc) { 01814 this->getLocalData()->RAngleLoc = Loc; 01815 } 01816 01817 unsigned getNumArgs() const { 01818 return getTypePtr()->getNumArgs(); 01819 } 01820 01821 void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) { 01822 getArgInfos()[i] = AI; 01823 } 01824 TemplateArgumentLocInfo getArgLocInfo(unsigned i) const { 01825 return getArgInfos()[i]; 01826 } 01827 01828 TemplateArgumentLoc getArgLoc(unsigned i) const { 01829 return TemplateArgumentLoc(getTypePtr()->getArg(i), getArgLocInfo(i)); 01830 } 01831 01832 SourceRange getLocalSourceRange() const { 01833 if (getElaboratedKeywordLoc().isValid()) 01834 return SourceRange(getElaboratedKeywordLoc(), getRAngleLoc()); 01835 else if (getQualifierLoc()) 01836 return SourceRange(getQualifierLoc().getBeginLoc(), getRAngleLoc()); 01837 else if (getTemplateKeywordLoc().isValid()) 01838 return SourceRange(getTemplateKeywordLoc(), getRAngleLoc()); 01839 else 01840 return SourceRange(getTemplateNameLoc(), getRAngleLoc()); 01841 } 01842 01843 void copy(DependentTemplateSpecializationTypeLoc Loc) { 01844 unsigned size = getFullDataSize(); 01845 assert(size == Loc.getFullDataSize()); 01846 memcpy(Data, Loc.Data, size); 01847 } 01848 01849 void initializeLocal(ASTContext &Context, SourceLocation Loc); 01850 01851 unsigned getExtraLocalDataSize() const { 01852 return getNumArgs() * sizeof(TemplateArgumentLocInfo); 01853 } 01854 01855 unsigned getExtraLocalDataAlignment() const { 01856 return llvm::alignOf<TemplateArgumentLocInfo>(); 01857 } 01858 01859 private: 01860 TemplateArgumentLocInfo *getArgInfos() const { 01861 return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData()); 01862 } 01863 }; 01864 01865 01866 struct PackExpansionTypeLocInfo { 01867 SourceLocation EllipsisLoc; 01868 }; 01869 01870 class PackExpansionTypeLoc 01871 : public ConcreteTypeLoc<UnqualTypeLoc, PackExpansionTypeLoc, 01872 PackExpansionType, PackExpansionTypeLocInfo> { 01873 public: 01874 SourceLocation getEllipsisLoc() const { 01875 return this->getLocalData()->EllipsisLoc; 01876 } 01877 01878 void setEllipsisLoc(SourceLocation Loc) { 01879 this->getLocalData()->EllipsisLoc = Loc; 01880 } 01881 01882 SourceRange getLocalSourceRange() const { 01883 return SourceRange(getEllipsisLoc(), getEllipsisLoc()); 01884 } 01885 01886 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 01887 setEllipsisLoc(Loc); 01888 } 01889 01890 TypeLoc getPatternLoc() const { 01891 return getInnerTypeLoc(); 01892 } 01893 01894 QualType getInnerType() const { 01895 return this->getTypePtr()->getPattern(); 01896 } 01897 }; 01898 01899 struct AtomicTypeLocInfo { 01900 SourceLocation KWLoc, LParenLoc, RParenLoc; 01901 }; 01902 01903 class AtomicTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, AtomicTypeLoc, 01904 AtomicType, AtomicTypeLocInfo> { 01905 public: 01906 TypeLoc getValueLoc() const { 01907 return this->getInnerTypeLoc(); 01908 } 01909 01910 SourceRange getLocalSourceRange() const { 01911 return SourceRange(getKWLoc(), getRParenLoc()); 01912 } 01913 01914 SourceLocation getKWLoc() const { 01915 return this->getLocalData()->KWLoc; 01916 } 01917 void setKWLoc(SourceLocation Loc) { 01918 this->getLocalData()->KWLoc = Loc; 01919 } 01920 01921 SourceLocation getLParenLoc() const { 01922 return this->getLocalData()->LParenLoc; 01923 } 01924 void setLParenLoc(SourceLocation Loc) { 01925 this->getLocalData()->LParenLoc = Loc; 01926 } 01927 01928 SourceLocation getRParenLoc() const { 01929 return this->getLocalData()->RParenLoc; 01930 } 01931 void setRParenLoc(SourceLocation Loc) { 01932 this->getLocalData()->RParenLoc = Loc; 01933 } 01934 01935 SourceRange getParensRange() const { 01936 return SourceRange(getLParenLoc(), getRParenLoc()); 01937 } 01938 void setParensRange(SourceRange Range) { 01939 setLParenLoc(Range.getBegin()); 01940 setRParenLoc(Range.getEnd()); 01941 } 01942 01943 void initializeLocal(ASTContext &Context, SourceLocation Loc) { 01944 setKWLoc(Loc); 01945 setLParenLoc(Loc); 01946 setRParenLoc(Loc); 01947 } 01948 01949 QualType getInnerType() const { 01950 return this->getTypePtr()->getValueType(); 01951 } 01952 }; 01953 01954 01955 } 01956 01957 #endif