1198092Srdivacky//===--- TypeLoc.h - Type Source Info Wrapper -------------------*- C++ -*-===// 2198092Srdivacky// 3198092Srdivacky// The LLVM Compiler Infrastructure 4198092Srdivacky// 5198092Srdivacky// This file is distributed under the University of Illinois Open Source 6198092Srdivacky// License. See LICENSE.TXT for details. 7198092Srdivacky// 8198092Srdivacky//===----------------------------------------------------------------------===// 9198092Srdivacky// 10198092Srdivacky// This file defines the TypeLoc interface and subclasses. 11198092Srdivacky// 12198092Srdivacky//===----------------------------------------------------------------------===// 13198092Srdivacky 14198092Srdivacky#ifndef LLVM_CLANG_AST_TYPELOC_H 15198092Srdivacky#define LLVM_CLANG_AST_TYPELOC_H 16198092Srdivacky 17208600Srdivacky#include "clang/AST/Decl.h" 18198893Srdivacky#include "clang/AST/TemplateBase.h" 19249423Sdim#include "clang/AST/Type.h" 20202879Srdivacky#include "clang/Basic/Specifiers.h" 21234353Sdim#include "llvm/Support/Compiler.h" 22198092Srdivacky 23198092Srdivackynamespace clang { 24218893Sdim class ASTContext; 25198092Srdivacky class ParmVarDecl; 26200583Srdivacky class TypeSourceInfo; 27198112Srdivacky class UnqualTypeLoc; 28198092Srdivacky 29198398Srdivacky// Predeclare all the type nodes. 30198398Srdivacky#define ABSTRACT_TYPELOC(Class, Base) 31198398Srdivacky#define TYPELOC(Class, Base) \ 32198398Srdivacky class Class##TypeLoc; 33198398Srdivacky#include "clang/AST/TypeLocNodes.def" 34198398Srdivacky 35198092Srdivacky/// \brief Base wrapper for a particular "section" of type source info. 36198092Srdivacky/// 37198092Srdivacky/// A client should use the TypeLoc subclasses through cast/dyn_cast in order to 38198092Srdivacky/// get at the actual information. 39198092Srdivackyclass TypeLoc { 40198092Srdivackyprotected: 41198112Srdivacky // The correctness of this relies on the property that, for Type *Ty, 42198112Srdivacky // QualType(Ty, 0).getAsOpaquePtr() == (void*) Ty 43218893Sdim const void *Ty; 44198092Srdivacky void *Data; 45198092Srdivacky 46198092Srdivackypublic: 47249423Sdim /// \brief Convert to the specified TypeLoc type, asserting that this TypeLoc 48249423Sdim /// is of the desired type. 49249423Sdim template<typename T> 50249423Sdim T castAs() const { 51249423Sdim assert(T::isKind(*this)); 52249423Sdim T t; 53249423Sdim TypeLoc& tl = t; 54249423Sdim tl = *this; 55249423Sdim return t; 56249423Sdim } 57249423Sdim 58249423Sdim /// \brief Convert to the specified TypeLoc type, returning a null TypeLoc if 59249423Sdim /// this TypeLoc is not of the desired type. 60249423Sdim template<typename T> 61249423Sdim T getAs() const { 62249423Sdim if (!T::isKind(*this)) 63249423Sdim return T(); 64249423Sdim T t; 65249423Sdim TypeLoc& tl = t; 66249423Sdim tl = *this; 67249423Sdim return t; 68249423Sdim } 69249423Sdim 70198398Srdivacky /// The kinds of TypeLocs. Equivalent to the Type::TypeClass enum, 71198398Srdivacky /// except it also defines a Qualified enum that corresponds to the 72198398Srdivacky /// QualifiedLoc class. 73198398Srdivacky enum TypeLocClass { 74198398Srdivacky#define ABSTRACT_TYPE(Class, Base) 75198398Srdivacky#define TYPE(Class, Base) \ 76198398Srdivacky Class = Type::Class, 77198398Srdivacky#include "clang/AST/TypeNodes.def" 78198398Srdivacky Qualified 79198398Srdivacky }; 80198398Srdivacky 81198112Srdivacky TypeLoc() : Ty(0), Data(0) { } 82198112Srdivacky TypeLoc(QualType ty, void *opaqueData) 83198112Srdivacky : Ty(ty.getAsOpaquePtr()), Data(opaqueData) { } 84218893Sdim TypeLoc(const Type *ty, void *opaqueData) 85198112Srdivacky : Ty(ty), Data(opaqueData) { } 86198092Srdivacky 87198398Srdivacky TypeLocClass getTypeLocClass() const { 88199482Srdivacky if (getType().hasLocalQualifiers()) return Qualified; 89198398Srdivacky return (TypeLocClass) getType()->getTypeClass(); 90198398Srdivacky } 91198398Srdivacky 92198112Srdivacky bool isNull() const { return !Ty; } 93198112Srdivacky operator bool() const { return Ty; } 94198092Srdivacky 95198092Srdivacky /// \brief Returns the size of type source info data block for the given type. 96198092Srdivacky static unsigned getFullDataSizeForType(QualType Ty); 97198092Srdivacky 98198092Srdivacky /// \brief Get the type for which this source info wrapper provides 99198092Srdivacky /// information. 100198398Srdivacky QualType getType() const { 101198398Srdivacky return QualType::getFromOpaquePtr(Ty); 102198398Srdivacky } 103198092Srdivacky 104218893Sdim const Type *getTypePtr() const { 105198112Srdivacky return QualType::getFromOpaquePtr(Ty).getTypePtr(); 106198112Srdivacky } 107198112Srdivacky 108198092Srdivacky /// \brief Get the pointer where source information is stored. 109198398Srdivacky void *getOpaqueData() const { 110198398Srdivacky return Data; 111198398Srdivacky } 112198092Srdivacky 113208600Srdivacky /// \brief Get the begin source location. 114208600Srdivacky SourceLocation getBeginLoc() const; 115208600Srdivacky 116208600Srdivacky /// \brief Get the end source location. 117208600Srdivacky SourceLocation getEndLoc() const; 118208600Srdivacky 119198893Srdivacky /// \brief Get the full source range. 120234353Sdim SourceRange getSourceRange() const LLVM_READONLY { 121208600Srdivacky return SourceRange(getBeginLoc(), getEndLoc()); 122198893Srdivacky } 123234353Sdim SourceLocation getLocStart() const LLVM_READONLY { return getBeginLoc(); } 124234353Sdim SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); } 125198893Srdivacky 126198893Srdivacky /// \brief Get the local source range. 127208600Srdivacky SourceRange getLocalSourceRange() const { 128208600Srdivacky return getLocalSourceRangeImpl(*this); 129198398Srdivacky } 130198092Srdivacky 131198092Srdivacky /// \brief Returns the size of the type source info data block. 132198112Srdivacky unsigned getFullDataSize() const { 133198398Srdivacky return getFullDataSizeForType(getType()); 134198112Srdivacky } 135198092Srdivacky 136198092Srdivacky /// \brief Get the next TypeLoc pointed by this TypeLoc, e.g for "int*" the 137198092Srdivacky /// TypeLoc is a PointerLoc and next TypeLoc is for "int". 138198398Srdivacky TypeLoc getNextTypeLoc() const { 139198398Srdivacky return getNextTypeLocImpl(*this); 140198398Srdivacky } 141198092Srdivacky 142198112Srdivacky /// \brief Skips past any qualifiers, if this is qualified. 143198398Srdivacky UnqualTypeLoc getUnqualifiedLoc() const; // implemented in this header 144198112Srdivacky 145249423Sdim TypeLoc IgnoreParens() const; 146218893Sdim 147198398Srdivacky /// \brief Initializes this to state that every location in this 148198398Srdivacky /// type is the given location. 149198398Srdivacky /// 150198398Srdivacky /// This method exists to provide a simple transition for code that 151198398Srdivacky /// relies on location-less types. 152218893Sdim void initialize(ASTContext &Context, SourceLocation Loc) const { 153218893Sdim initializeImpl(Context, *this, Loc); 154198398Srdivacky } 155198398Srdivacky 156218893Sdim /// \brief Initializes this by copying its information from another 157218893Sdim /// TypeLoc of the same type. 158218893Sdim void initializeFullCopy(TypeLoc Other) const { 159218893Sdim assert(getType() == Other.getType()); 160218893Sdim size_t Size = getFullDataSize(); 161218893Sdim memcpy(getOpaqueData(), Other.getOpaqueData(), Size); 162218893Sdim } 163218893Sdim 164218893Sdim /// \brief Initializes this by copying its information from another 165218893Sdim /// TypeLoc of the same type. The given size must be the full data 166218893Sdim /// size. 167218893Sdim void initializeFullCopy(TypeLoc Other, unsigned Size) const { 168218893Sdim assert(getType() == Other.getType()); 169218893Sdim assert(getFullDataSize() == Size); 170218893Sdim memcpy(getOpaqueData(), Other.getOpaqueData(), Size); 171218893Sdim } 172218893Sdim 173198092Srdivacky friend bool operator==(const TypeLoc &LHS, const TypeLoc &RHS) { 174198092Srdivacky return LHS.Ty == RHS.Ty && LHS.Data == RHS.Data; 175198092Srdivacky } 176198092Srdivacky 177198092Srdivacky friend bool operator!=(const TypeLoc &LHS, const TypeLoc &RHS) { 178198092Srdivacky return !(LHS == RHS); 179198092Srdivacky } 180198092Srdivacky 181198398Srdivackyprivate: 182249423Sdim static bool isKind(const TypeLoc&) { 183249423Sdim return true; 184249423Sdim } 185249423Sdim 186234353Sdim static void initializeImpl(ASTContext &Context, TypeLoc TL, 187234353Sdim SourceLocation Loc); 188198398Srdivacky static TypeLoc getNextTypeLocImpl(TypeLoc TL); 189218893Sdim static TypeLoc IgnoreParensImpl(TypeLoc TL); 190208600Srdivacky static SourceRange getLocalSourceRangeImpl(TypeLoc TL); 191198092Srdivacky}; 192198092Srdivacky 193208600Srdivacky/// \brief Return the TypeLoc for a type source info. 194208600Srdivackyinline TypeLoc TypeSourceInfo::getTypeLoc() const { 195210299Sed return TypeLoc(Ty, const_cast<void*>(static_cast<const void*>(this + 1))); 196208600Srdivacky} 197208600Srdivacky 198198112Srdivacky/// \brief Wrapper of type source information for a type with 199218893Sdim/// no direct qualifiers. 200198112Srdivackyclass UnqualTypeLoc : public TypeLoc { 201198112Srdivackypublic: 202198112Srdivacky UnqualTypeLoc() {} 203218893Sdim UnqualTypeLoc(const Type *Ty, void *Data) : TypeLoc(Ty, Data) {} 204198112Srdivacky 205218893Sdim const Type *getTypePtr() const { 206218893Sdim return reinterpret_cast<const Type*>(Ty); 207198112Srdivacky } 208198112Srdivacky 209198398Srdivacky TypeLocClass getTypeLocClass() const { 210198398Srdivacky return (TypeLocClass) getTypePtr()->getTypeClass(); 211198398Srdivacky } 212198398Srdivacky 213249423Sdimprivate: 214249423Sdim friend class TypeLoc; 215249423Sdim static bool isKind(const TypeLoc &TL) { 216249423Sdim return !TL.getType().hasLocalQualifiers(); 217198112Srdivacky } 218198112Srdivacky}; 219198112Srdivacky 220198112Srdivacky/// \brief Wrapper of type source information for a type with 221198112Srdivacky/// non-trivial direct qualifiers. 222198112Srdivacky/// 223198112Srdivacky/// Currently, we intentionally do not provide source location for 224198112Srdivacky/// type qualifiers. 225198398Srdivackyclass QualifiedTypeLoc : public TypeLoc { 226198112Srdivackypublic: 227208600Srdivacky SourceRange getLocalSourceRange() const { 228198112Srdivacky return SourceRange(); 229198112Srdivacky } 230198112Srdivacky 231198112Srdivacky UnqualTypeLoc getUnqualifiedLoc() const { 232198398Srdivacky return UnqualTypeLoc(getTypePtr(), Data); 233198112Srdivacky } 234198112Srdivacky 235198398Srdivacky /// Initializes the local data of this type source info block to 236198398Srdivacky /// provide no information. 237218893Sdim void initializeLocal(ASTContext &Context, SourceLocation Loc) { 238198398Srdivacky // do nothing 239198398Srdivacky } 240198398Srdivacky 241198398Srdivacky TypeLoc getNextTypeLoc() const { 242198398Srdivacky return getUnqualifiedLoc(); 243198398Srdivacky } 244198398Srdivacky 245198112Srdivacky /// \brief Returns the size of the type source info data block that is 246198112Srdivacky /// specific to this type. 247198112Srdivacky unsigned getLocalDataSize() const { 248198112Srdivacky // In fact, we don't currently preserve any location information 249198112Srdivacky // for qualifiers. 250198112Srdivacky return 0; 251198112Srdivacky } 252198112Srdivacky 253198112Srdivacky /// \brief Returns the size of the type source info data block. 254198112Srdivacky unsigned getFullDataSize() const { 255234353Sdim return getLocalDataSize() + 256199482Srdivacky getFullDataSizeForType(getType().getLocalUnqualifiedType()); 257198112Srdivacky } 258198112Srdivacky 259249423Sdimprivate: 260249423Sdim friend class TypeLoc; 261249423Sdim static bool isKind(const TypeLoc &TL) { 262249423Sdim return TL.getType().hasLocalQualifiers(); 263198112Srdivacky } 264198112Srdivacky}; 265198112Srdivacky 266198112Srdivackyinline UnqualTypeLoc TypeLoc::getUnqualifiedLoc() const { 267249423Sdim if (QualifiedTypeLoc Loc = getAs<QualifiedTypeLoc>()) 268249423Sdim return Loc.getUnqualifiedLoc(); 269249423Sdim return castAs<UnqualTypeLoc>(); 270198112Srdivacky} 271198112Srdivacky 272198112Srdivacky/// A metaprogramming base class for TypeLoc classes which correspond 273198112Srdivacky/// to a particular Type subclass. It is accepted for a single 274198112Srdivacky/// TypeLoc class to correspond to multiple Type classes. 275198112Srdivacky/// 276243830Sdim/// \tparam Base a class from which to derive 277243830Sdim/// \tparam Derived the class deriving from this one 278243830Sdim/// \tparam TypeClass the concrete Type subclass associated with this 279198112Srdivacky/// location type 280243830Sdim/// \tparam LocalData the structure type of local location data for 281198112Srdivacky/// this type 282198112Srdivacky/// 283198112Srdivacky/// sizeof(LocalData) needs to be a multiple of sizeof(void*) or 284198112Srdivacky/// else the world will end. 285198112Srdivacky/// 286198112Srdivacky/// TypeLocs with non-constant amounts of local data should override 287198112Srdivacky/// getExtraLocalDataSize(); getExtraLocalData() will then point to 288198112Srdivacky/// this extra memory. 289198112Srdivacky/// 290198398Srdivacky/// TypeLocs with an inner type should define 291198398Srdivacky/// QualType getInnerType() const 292198398Srdivacky/// and getInnerTypeLoc() will then point to this inner type's 293198398Srdivacky/// location data. 294198398Srdivacky/// 295198398Srdivacky/// A word about hierarchies: this template is not designed to be 296198398Srdivacky/// derived from multiple times in a hierarchy. It is also not 297198398Srdivacky/// designed to be used for classes where subtypes might provide 298198398Srdivacky/// different amounts of source information. It should be subclassed 299198398Srdivacky/// only at the deepest portion of the hierarchy where all children 300198398Srdivacky/// have identical source information; if that's an abstract type, 301198398Srdivacky/// then further descendents should inherit from 302198398Srdivacky/// InheritingConcreteTypeLoc instead. 303198112Srdivackytemplate <class Base, class Derived, class TypeClass, class LocalData> 304198112Srdivackyclass ConcreteTypeLoc : public Base { 305198112Srdivacky 306198112Srdivacky const Derived *asDerived() const { 307198112Srdivacky return static_cast<const Derived*>(this); 308198112Srdivacky } 309198112Srdivacky 310249423Sdim friend class TypeLoc; 311249423Sdim static bool isKind(const TypeLoc &TL) { 312249423Sdim return Derived::classofType(TL.getTypePtr()); 313249423Sdim } 314249423Sdim 315249423Sdim static bool classofType(const Type *Ty) { 316249423Sdim return TypeClass::classof(Ty); 317249423Sdim } 318249423Sdim 319198112Srdivackypublic: 320198112Srdivacky unsigned getLocalDataSize() const { 321198112Srdivacky return sizeof(LocalData) + asDerived()->getExtraLocalDataSize(); 322198112Srdivacky } 323198112Srdivacky // Give a default implementation that's useful for leaf types. 324198112Srdivacky unsigned getFullDataSize() const { 325198112Srdivacky return asDerived()->getLocalDataSize() + getInnerTypeSize(); 326198112Srdivacky } 327198112Srdivacky 328198398Srdivacky TypeLoc getNextTypeLoc() const { 329198398Srdivacky return getNextTypeLoc(asDerived()->getInnerType()); 330198398Srdivacky } 331198398Srdivacky 332218893Sdim const TypeClass *getTypePtr() const { 333198398Srdivacky return cast<TypeClass>(Base::getTypePtr()); 334198112Srdivacky } 335198112Srdivacky 336198398Srdivackyprotected: 337198112Srdivacky unsigned getExtraLocalDataSize() const { 338198112Srdivacky return 0; 339198112Srdivacky } 340198112Srdivacky 341198112Srdivacky LocalData *getLocalData() const { 342198112Srdivacky return static_cast<LocalData*>(Base::Data); 343198112Srdivacky } 344198112Srdivacky 345198112Srdivacky /// Gets a pointer past the Info structure; useful for classes with 346198112Srdivacky /// local data that can't be captured in the Info (e.g. because it's 347198112Srdivacky /// of variable size). 348198112Srdivacky void *getExtraLocalData() const { 349198112Srdivacky return getLocalData() + 1; 350198112Srdivacky } 351234353Sdim 352198112Srdivacky void *getNonLocalData() const { 353198112Srdivacky return static_cast<char*>(Base::Data) + asDerived()->getLocalDataSize(); 354198112Srdivacky } 355198112Srdivacky 356198398Srdivacky struct HasNoInnerType {}; 357198398Srdivacky HasNoInnerType getInnerType() const { return HasNoInnerType(); } 358198112Srdivacky 359198112Srdivacky TypeLoc getInnerTypeLoc() const { 360198112Srdivacky return TypeLoc(asDerived()->getInnerType(), getNonLocalData()); 361198112Srdivacky } 362198112Srdivacky 363198112Srdivackyprivate: 364198112Srdivacky unsigned getInnerTypeSize() const { 365198398Srdivacky return getInnerTypeSize(asDerived()->getInnerType()); 366198398Srdivacky } 367198398Srdivacky 368198398Srdivacky unsigned getInnerTypeSize(HasNoInnerType _) const { 369198112Srdivacky return 0; 370198112Srdivacky } 371198112Srdivacky 372198398Srdivacky unsigned getInnerTypeSize(QualType _) const { 373198398Srdivacky return getInnerTypeLoc().getFullDataSize(); 374198112Srdivacky } 375198112Srdivacky 376198398Srdivacky TypeLoc getNextTypeLoc(HasNoInnerType _) const { 377198398Srdivacky return TypeLoc(); 378198398Srdivacky } 379198112Srdivacky 380198398Srdivacky TypeLoc getNextTypeLoc(QualType T) const { 381198398Srdivacky return TypeLoc(T, getNonLocalData()); 382198398Srdivacky } 383198112Srdivacky}; 384198112Srdivacky 385198398Srdivacky/// A metaprogramming class designed for concrete subtypes of abstract 386198398Srdivacky/// types where all subtypes share equivalently-structured source 387198398Srdivacky/// information. See the note on ConcreteTypeLoc. 388198398Srdivackytemplate <class Base, class Derived, class TypeClass> 389198398Srdivackyclass InheritingConcreteTypeLoc : public Base { 390249423Sdim friend class TypeLoc; 391212904Sdim static bool classofType(const Type *Ty) { 392212904Sdim return TypeClass::classof(Ty); 393212904Sdim } 394212904Sdim 395249423Sdim static bool isKind(const TypeLoc &TL) { 396249423Sdim return Derived::classofType(TL.getTypePtr()); 397198092Srdivacky } 398249423Sdim static bool isKind(const UnqualTypeLoc &TL) { 399249423Sdim return Derived::classofType(TL.getTypePtr()); 400198092Srdivacky } 401198092Srdivacky 402249423Sdimpublic: 403218893Sdim const TypeClass *getTypePtr() const { 404198398Srdivacky return cast<TypeClass>(Base::getTypePtr()); 405198398Srdivacky } 406198112Srdivacky}; 407198092Srdivacky 408200583Srdivacky 409198398Srdivackystruct TypeSpecLocInfo { 410198112Srdivacky SourceLocation NameLoc; 411198092Srdivacky}; 412198092Srdivacky 413198398Srdivacky/// \brief A reasonable base class for TypeLocs that correspond to 414198398Srdivacky/// types that are written as a type-specifier. 415234353Sdimclass TypeSpecTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, 416200583Srdivacky TypeSpecTypeLoc, 417200583Srdivacky Type, 418200583Srdivacky TypeSpecLocInfo> { 419198092Srdivackypublic: 420200583Srdivacky enum { LocalDataSize = sizeof(TypeSpecLocInfo) }; 421200583Srdivacky 422198092Srdivacky SourceLocation getNameLoc() const { 423198398Srdivacky return this->getLocalData()->NameLoc; 424198092Srdivacky } 425198092Srdivacky void setNameLoc(SourceLocation Loc) { 426198398Srdivacky this->getLocalData()->NameLoc = Loc; 427198092Srdivacky } 428208600Srdivacky SourceRange getLocalSourceRange() const { 429198092Srdivacky return SourceRange(getNameLoc(), getNameLoc()); 430198092Srdivacky } 431218893Sdim void initializeLocal(ASTContext &Context, SourceLocation Loc) { 432198398Srdivacky setNameLoc(Loc); 433198398Srdivacky } 434200583Srdivacky 435249423Sdimprivate: 436249423Sdim friend class TypeLoc; 437249423Sdim static bool isKind(const TypeLoc &TL); 438198398Srdivacky}; 439198092Srdivacky 440200583Srdivacky 441202879Srdivackystruct BuiltinLocInfo { 442202879Srdivacky SourceLocation BuiltinLoc; 443202879Srdivacky}; 444202879Srdivacky 445202879Srdivacky/// \brief Wrapper for source info for builtin types. 446202879Srdivackyclass BuiltinTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, 447202879Srdivacky BuiltinTypeLoc, 448202879Srdivacky BuiltinType, 449202879Srdivacky BuiltinLocInfo> { 450202879Srdivackypublic: 451202879Srdivacky enum { LocalDataSize = sizeof(BuiltinLocInfo) }; 452202879Srdivacky 453202879Srdivacky SourceLocation getBuiltinLoc() const { 454202879Srdivacky return getLocalData()->BuiltinLoc; 455202879Srdivacky } 456202879Srdivacky void setBuiltinLoc(SourceLocation Loc) { 457202879Srdivacky getLocalData()->BuiltinLoc = Loc; 458202879Srdivacky } 459202879Srdivacky 460202879Srdivacky SourceLocation getNameLoc() const { return getBuiltinLoc(); } 461202879Srdivacky 462202879Srdivacky WrittenBuiltinSpecs& getWrittenBuiltinSpecs() { 463202879Srdivacky return *(static_cast<WrittenBuiltinSpecs*>(getExtraLocalData())); 464202879Srdivacky } 465202879Srdivacky const WrittenBuiltinSpecs& getWrittenBuiltinSpecs() const { 466202879Srdivacky return *(static_cast<WrittenBuiltinSpecs*>(getExtraLocalData())); 467202879Srdivacky } 468202879Srdivacky 469202879Srdivacky bool needsExtraLocalData() const { 470202879Srdivacky BuiltinType::Kind bk = getTypePtr()->getKind(); 471202879Srdivacky return (bk >= BuiltinType::UShort && bk <= BuiltinType::UInt128) 472202879Srdivacky || (bk >= BuiltinType::Short && bk <= BuiltinType::LongDouble) 473202879Srdivacky || bk == BuiltinType::UChar 474202879Srdivacky || bk == BuiltinType::SChar; 475202879Srdivacky } 476202879Srdivacky 477202879Srdivacky unsigned getExtraLocalDataSize() const { 478202879Srdivacky return needsExtraLocalData() ? sizeof(WrittenBuiltinSpecs) : 0; 479202879Srdivacky } 480202879Srdivacky 481208600Srdivacky SourceRange getLocalSourceRange() const { 482202879Srdivacky return SourceRange(getBuiltinLoc(), getBuiltinLoc()); 483202879Srdivacky } 484202879Srdivacky 485202879Srdivacky TypeSpecifierSign getWrittenSignSpec() const { 486202879Srdivacky if (needsExtraLocalData()) 487202879Srdivacky return static_cast<TypeSpecifierSign>(getWrittenBuiltinSpecs().Sign); 488202879Srdivacky else 489202879Srdivacky return TSS_unspecified; 490202879Srdivacky } 491202879Srdivacky bool hasWrittenSignSpec() const { 492202879Srdivacky return getWrittenSignSpec() != TSS_unspecified; 493202879Srdivacky } 494202879Srdivacky void setWrittenSignSpec(TypeSpecifierSign written) { 495202879Srdivacky if (needsExtraLocalData()) 496202879Srdivacky getWrittenBuiltinSpecs().Sign = written; 497202879Srdivacky } 498202879Srdivacky 499202879Srdivacky TypeSpecifierWidth getWrittenWidthSpec() const { 500202879Srdivacky if (needsExtraLocalData()) 501202879Srdivacky return static_cast<TypeSpecifierWidth>(getWrittenBuiltinSpecs().Width); 502202879Srdivacky else 503202879Srdivacky return TSW_unspecified; 504202879Srdivacky } 505202879Srdivacky bool hasWrittenWidthSpec() const { 506202879Srdivacky return getWrittenWidthSpec() != TSW_unspecified; 507202879Srdivacky } 508202879Srdivacky void setWrittenWidthSpec(TypeSpecifierWidth written) { 509202879Srdivacky if (needsExtraLocalData()) 510202879Srdivacky getWrittenBuiltinSpecs().Width = written; 511202879Srdivacky } 512202879Srdivacky 513202879Srdivacky TypeSpecifierType getWrittenTypeSpec() const; 514202879Srdivacky bool hasWrittenTypeSpec() const { 515202879Srdivacky return getWrittenTypeSpec() != TST_unspecified; 516202879Srdivacky } 517202879Srdivacky void setWrittenTypeSpec(TypeSpecifierType written) { 518202879Srdivacky if (needsExtraLocalData()) 519202879Srdivacky getWrittenBuiltinSpecs().Type = written; 520202879Srdivacky } 521202879Srdivacky 522202879Srdivacky bool hasModeAttr() const { 523202879Srdivacky if (needsExtraLocalData()) 524202879Srdivacky return getWrittenBuiltinSpecs().ModeAttr; 525202879Srdivacky else 526202879Srdivacky return false; 527202879Srdivacky } 528202879Srdivacky void setModeAttr(bool written) { 529202879Srdivacky if (needsExtraLocalData()) 530202879Srdivacky getWrittenBuiltinSpecs().ModeAttr = written; 531202879Srdivacky } 532202879Srdivacky 533218893Sdim void initializeLocal(ASTContext &Context, SourceLocation Loc) { 534202879Srdivacky setBuiltinLoc(Loc); 535202879Srdivacky if (needsExtraLocalData()) { 536202879Srdivacky WrittenBuiltinSpecs &wbs = getWrittenBuiltinSpecs(); 537202879Srdivacky wbs.Sign = TSS_unspecified; 538202879Srdivacky wbs.Width = TSW_unspecified; 539202879Srdivacky wbs.Type = TST_unspecified; 540202879Srdivacky wbs.ModeAttr = false; 541202879Srdivacky } 542202879Srdivacky } 543202879Srdivacky}; 544202879Srdivacky 545202879Srdivacky 546198398Srdivacky/// \brief Wrapper for source info for typedefs. 547200583Srdivackyclass TypedefTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 548200583Srdivacky TypedefTypeLoc, 549200583Srdivacky TypedefType> { 550198398Srdivackypublic: 551221345Sdim TypedefNameDecl *getTypedefNameDecl() const { 552198112Srdivacky return getTypePtr()->getDecl(); 553198092Srdivacky } 554198112Srdivacky}; 555198092Srdivacky 556204962Srdivacky/// \brief Wrapper for source info for injected class names of class 557204962Srdivacky/// templates. 558204962Srdivackyclass InjectedClassNameTypeLoc : 559204962Srdivacky public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 560204962Srdivacky InjectedClassNameTypeLoc, 561204962Srdivacky InjectedClassNameType> { 562226633Sdimpublic: 563226633Sdim CXXRecordDecl *getDecl() const { 564226633Sdim return getTypePtr()->getDecl(); 565226633Sdim } 566204962Srdivacky}; 567204962Srdivacky 568200583Srdivacky/// \brief Wrapper for source info for unresolved typename using decls. 569200583Srdivackyclass UnresolvedUsingTypeLoc : 570200583Srdivacky public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 571200583Srdivacky UnresolvedUsingTypeLoc, 572200583Srdivacky UnresolvedUsingType> { 573200583Srdivackypublic: 574200583Srdivacky UnresolvedUsingTypenameDecl *getDecl() const { 575200583Srdivacky return getTypePtr()->getDecl(); 576200583Srdivacky } 577200583Srdivacky}; 578198092Srdivacky 579200583Srdivacky/// \brief Wrapper for source info for tag types. Note that this only 580200583Srdivacky/// records source info for the name itself; a type written 'struct foo' 581200583Srdivacky/// should be represented as an ElaboratedTypeLoc. We currently 582200583Srdivacky/// only do that when C++ is enabled because of the expense of 583200583Srdivacky/// creating an ElaboratedType node for so many type references in C. 584200583Srdivackyclass TagTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 585200583Srdivacky TagTypeLoc, 586200583Srdivacky TagType> { 587200583Srdivackypublic: 588200583Srdivacky TagDecl *getDecl() const { return getTypePtr()->getDecl(); } 589226633Sdim 590234353Sdim /// \brief True if the tag was defined in this type specifier. 591226633Sdim bool isDefinition() const { 592234353Sdim TagDecl *D = getDecl(); 593234353Sdim return D->isCompleteDefinition() && 594234353Sdim (D->getIdentifier() == 0 || D->getLocation() == getNameLoc()); 595226633Sdim } 596200583Srdivacky}; 597200583Srdivacky 598200583Srdivacky/// \brief Wrapper for source info for record types. 599200583Srdivackyclass RecordTypeLoc : public InheritingConcreteTypeLoc<TagTypeLoc, 600200583Srdivacky RecordTypeLoc, 601200583Srdivacky RecordType> { 602200583Srdivackypublic: 603200583Srdivacky RecordDecl *getDecl() const { return getTypePtr()->getDecl(); } 604200583Srdivacky}; 605200583Srdivacky 606200583Srdivacky/// \brief Wrapper for source info for enum types. 607200583Srdivackyclass EnumTypeLoc : public InheritingConcreteTypeLoc<TagTypeLoc, 608200583Srdivacky EnumTypeLoc, 609200583Srdivacky EnumType> { 610200583Srdivackypublic: 611200583Srdivacky EnumDecl *getDecl() const { return getTypePtr()->getDecl(); } 612200583Srdivacky}; 613200583Srdivacky 614198398Srdivacky/// \brief Wrapper for template type parameters. 615200583Srdivackyclass TemplateTypeParmTypeLoc : 616200583Srdivacky public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 617200583Srdivacky TemplateTypeParmTypeLoc, 618200583Srdivacky TemplateTypeParmType> { 619221345Sdimpublic: 620221345Sdim TemplateTypeParmDecl *getDecl() const { return getTypePtr()->getDecl(); } 621198398Srdivacky}; 622198092Srdivacky 623198398Srdivacky/// \brief Wrapper for substituted template type parameters. 624198398Srdivackyclass SubstTemplateTypeParmTypeLoc : 625200583Srdivacky public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 626200583Srdivacky SubstTemplateTypeParmTypeLoc, 627200583Srdivacky SubstTemplateTypeParmType> { 628198112Srdivacky}; 629198092Srdivacky 630218893Sdim /// \brief Wrapper for substituted template type parameters. 631218893Sdimclass SubstTemplateTypeParmPackTypeLoc : 632218893Sdim public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 633218893Sdim SubstTemplateTypeParmPackTypeLoc, 634218893Sdim SubstTemplateTypeParmPackType> { 635218893Sdim}; 636198092Srdivacky 637218893Sdimstruct AttributedLocInfo { 638218893Sdim union { 639218893Sdim Expr *ExprOperand; 640218893Sdim 641218893Sdim /// A raw SourceLocation. 642218893Sdim unsigned EnumOperandLoc; 643218893Sdim }; 644218893Sdim 645218893Sdim SourceRange OperandParens; 646218893Sdim 647218893Sdim SourceLocation AttrLoc; 648218893Sdim}; 649218893Sdim 650218893Sdim/// \brief Type source information for an attributed type. 651218893Sdimclass AttributedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, 652218893Sdim AttributedTypeLoc, 653218893Sdim AttributedType, 654218893Sdim AttributedLocInfo> { 655218893Sdimpublic: 656218893Sdim AttributedType::Kind getAttrKind() const { 657218893Sdim return getTypePtr()->getAttrKind(); 658218893Sdim } 659218893Sdim 660218893Sdim bool hasAttrExprOperand() const { 661218893Sdim return (getAttrKind() >= AttributedType::FirstExprOperandKind && 662218893Sdim getAttrKind() <= AttributedType::LastExprOperandKind); 663218893Sdim } 664218893Sdim 665218893Sdim bool hasAttrEnumOperand() const { 666218893Sdim return (getAttrKind() >= AttributedType::FirstEnumOperandKind && 667218893Sdim getAttrKind() <= AttributedType::LastEnumOperandKind); 668218893Sdim } 669218893Sdim 670218893Sdim bool hasAttrOperand() const { 671218893Sdim return hasAttrExprOperand() || hasAttrEnumOperand(); 672218893Sdim } 673218893Sdim 674218893Sdim /// The modified type, which is generally canonically different from 675218893Sdim /// the attribute type. 676218893Sdim /// int main(int, char**) __attribute__((noreturn)) 677218893Sdim /// ~~~ ~~~~~~~~~~~~~ 678218893Sdim TypeLoc getModifiedLoc() const { 679218893Sdim return getInnerTypeLoc(); 680218893Sdim } 681218893Sdim 682218893Sdim /// The location of the attribute name, i.e. 683218893Sdim /// __attribute__((regparm(1000))) 684218893Sdim /// ^~~~~~~ 685218893Sdim SourceLocation getAttrNameLoc() const { 686218893Sdim return getLocalData()->AttrLoc; 687218893Sdim } 688218893Sdim void setAttrNameLoc(SourceLocation loc) { 689218893Sdim getLocalData()->AttrLoc = loc; 690218893Sdim } 691218893Sdim 692218893Sdim /// The attribute's expression operand, if it has one. 693218893Sdim /// void *cur_thread __attribute__((address_space(21))) 694218893Sdim /// ^~ 695218893Sdim Expr *getAttrExprOperand() const { 696218893Sdim assert(hasAttrExprOperand()); 697218893Sdim return getLocalData()->ExprOperand; 698218893Sdim } 699218893Sdim void setAttrExprOperand(Expr *e) { 700218893Sdim assert(hasAttrExprOperand()); 701218893Sdim getLocalData()->ExprOperand = e; 702218893Sdim } 703218893Sdim 704218893Sdim /// The location of the attribute's enumerated operand, if it has one. 705218893Sdim /// void * __attribute__((objc_gc(weak))) 706218893Sdim /// ^~~~ 707218893Sdim SourceLocation getAttrEnumOperandLoc() const { 708218893Sdim assert(hasAttrEnumOperand()); 709218893Sdim return SourceLocation::getFromRawEncoding(getLocalData()->EnumOperandLoc); 710218893Sdim } 711218893Sdim void setAttrEnumOperandLoc(SourceLocation loc) { 712218893Sdim assert(hasAttrEnumOperand()); 713218893Sdim getLocalData()->EnumOperandLoc = loc.getRawEncoding(); 714218893Sdim } 715218893Sdim 716218893Sdim /// The location of the parentheses around the operand, if there is 717218893Sdim /// an operand. 718218893Sdim /// void * __attribute__((objc_gc(weak))) 719218893Sdim /// ^ ^ 720218893Sdim SourceRange getAttrOperandParensRange() const { 721218893Sdim assert(hasAttrOperand()); 722218893Sdim return getLocalData()->OperandParens; 723218893Sdim } 724218893Sdim void setAttrOperandParensRange(SourceRange range) { 725218893Sdim assert(hasAttrOperand()); 726218893Sdim getLocalData()->OperandParens = range; 727218893Sdim } 728218893Sdim 729218893Sdim SourceRange getLocalSourceRange() const { 730218893Sdim // Note that this does *not* include the range of the attribute 731218893Sdim // enclosure, e.g.: 732218893Sdim // __attribute__((foo(bar))) 733218893Sdim // ^~~~~~~~~~~~~~~ ~~ 734218893Sdim // or 735218893Sdim // [[foo(bar)]] 736218893Sdim // ^~ ~~ 737218893Sdim // That enclosure doesn't necessarily belong to a single attribute 738218893Sdim // anyway. 739218893Sdim SourceRange range(getAttrNameLoc()); 740218893Sdim if (hasAttrOperand()) 741218893Sdim range.setEnd(getAttrOperandParensRange().getEnd()); 742218893Sdim return range; 743218893Sdim } 744218893Sdim 745218893Sdim void initializeLocal(ASTContext &Context, SourceLocation loc) { 746218893Sdim setAttrNameLoc(loc); 747218893Sdim if (hasAttrExprOperand()) { 748218893Sdim setAttrOperandParensRange(SourceRange(loc)); 749218893Sdim setAttrExprOperand(0); 750218893Sdim } else if (hasAttrEnumOperand()) { 751218893Sdim setAttrOperandParensRange(SourceRange(loc)); 752218893Sdim setAttrEnumOperandLoc(loc); 753218893Sdim } 754218893Sdim } 755218893Sdim 756218893Sdim QualType getInnerType() const { 757218893Sdim return getTypePtr()->getModifiedType(); 758218893Sdim } 759218893Sdim}; 760218893Sdim 761218893Sdim 762198112Srdivackystruct ObjCProtocolListLocInfo { 763198398Srdivacky SourceLocation LAngleLoc; 764198398Srdivacky SourceLocation RAngleLoc; 765208600Srdivacky bool HasBaseTypeAsWritten; 766198092Srdivacky}; 767198092Srdivacky 768198398Srdivacky// A helper class for defining ObjC TypeLocs that can qualified with 769198398Srdivacky// protocols. 770198398Srdivacky// 771198398Srdivacky// TypeClass basically has to be either ObjCInterfaceType or 772198398Srdivacky// ObjCObjectPointerType. 773208600Srdivackyclass ObjCObjectTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, 774208600Srdivacky ObjCObjectTypeLoc, 775208600Srdivacky ObjCObjectType, 776208600Srdivacky ObjCProtocolListLocInfo> { 777198092Srdivacky // SourceLocations are stored after Info, one for each Protocol. 778198092Srdivacky SourceLocation *getProtocolLocArray() const { 779198398Srdivacky return (SourceLocation*) this->getExtraLocalData(); 780198092Srdivacky } 781198092Srdivacky 782198092Srdivackypublic: 783198092Srdivacky SourceLocation getLAngleLoc() const { 784198398Srdivacky return this->getLocalData()->LAngleLoc; 785198092Srdivacky } 786198092Srdivacky void setLAngleLoc(SourceLocation Loc) { 787198398Srdivacky this->getLocalData()->LAngleLoc = Loc; 788198092Srdivacky } 789198092Srdivacky 790198092Srdivacky SourceLocation getRAngleLoc() const { 791198398Srdivacky return this->getLocalData()->RAngleLoc; 792198092Srdivacky } 793198092Srdivacky void setRAngleLoc(SourceLocation Loc) { 794198398Srdivacky this->getLocalData()->RAngleLoc = Loc; 795198092Srdivacky } 796198092Srdivacky 797198092Srdivacky unsigned getNumProtocols() const { 798198398Srdivacky return this->getTypePtr()->getNumProtocols(); 799198092Srdivacky } 800198092Srdivacky 801198092Srdivacky SourceLocation getProtocolLoc(unsigned i) const { 802198092Srdivacky assert(i < getNumProtocols() && "Index is out of bounds!"); 803198092Srdivacky return getProtocolLocArray()[i]; 804198092Srdivacky } 805198092Srdivacky void setProtocolLoc(unsigned i, SourceLocation Loc) { 806198092Srdivacky assert(i < getNumProtocols() && "Index is out of bounds!"); 807198092Srdivacky getProtocolLocArray()[i] = Loc; 808198092Srdivacky } 809198092Srdivacky 810198092Srdivacky ObjCProtocolDecl *getProtocol(unsigned i) const { 811198092Srdivacky assert(i < getNumProtocols() && "Index is out of bounds!"); 812198398Srdivacky return *(this->getTypePtr()->qual_begin() + i); 813198092Srdivacky } 814234353Sdim 815208600Srdivacky bool hasBaseTypeAsWritten() const { 816208600Srdivacky return getLocalData()->HasBaseTypeAsWritten; 817208600Srdivacky } 818208600Srdivacky 819208600Srdivacky void setHasBaseTypeAsWritten(bool HasBaseType) { 820208600Srdivacky getLocalData()->HasBaseTypeAsWritten = HasBaseType; 821208600Srdivacky } 822208600Srdivacky 823208600Srdivacky TypeLoc getBaseLoc() const { 824208600Srdivacky return getInnerTypeLoc(); 825208600Srdivacky } 826208600Srdivacky 827208600Srdivacky SourceRange getLocalSourceRange() const { 828198092Srdivacky return SourceRange(getLAngleLoc(), getRAngleLoc()); 829198092Srdivacky } 830198092Srdivacky 831218893Sdim void initializeLocal(ASTContext &Context, SourceLocation Loc) { 832208600Srdivacky setHasBaseTypeAsWritten(true); 833208600Srdivacky setLAngleLoc(Loc); 834208600Srdivacky setRAngleLoc(Loc); 835208600Srdivacky for (unsigned i = 0, e = getNumProtocols(); i != e; ++i) 836208600Srdivacky setProtocolLoc(i, Loc); 837198398Srdivacky } 838198398Srdivacky 839198112Srdivacky unsigned getExtraLocalDataSize() const { 840198398Srdivacky return this->getNumProtocols() * sizeof(SourceLocation); 841198092Srdivacky } 842208600Srdivacky 843208600Srdivacky QualType getInnerType() const { 844208600Srdivacky return getTypePtr()->getBaseType(); 845208600Srdivacky } 846198398Srdivacky}; 847198092Srdivacky 848198398Srdivacky 849208600Srdivackystruct ObjCInterfaceLocInfo { 850198398Srdivacky SourceLocation NameLoc; 851239462Sdim SourceLocation NameEndLoc; 852198112Srdivacky}; 853198092Srdivacky 854198398Srdivacky/// \brief Wrapper for source info for ObjC interfaces. 855210299Sedclass ObjCInterfaceTypeLoc : public ConcreteTypeLoc<ObjCObjectTypeLoc, 856208600Srdivacky ObjCInterfaceTypeLoc, 857208600Srdivacky ObjCInterfaceType, 858208600Srdivacky ObjCInterfaceLocInfo> { 859198398Srdivackypublic: 860198398Srdivacky ObjCInterfaceDecl *getIFaceDecl() const { 861198398Srdivacky return getTypePtr()->getDecl(); 862198398Srdivacky } 863198112Srdivacky 864198398Srdivacky SourceLocation getNameLoc() const { 865198398Srdivacky return getLocalData()->NameLoc; 866198398Srdivacky } 867198398Srdivacky 868198398Srdivacky void setNameLoc(SourceLocation Loc) { 869198398Srdivacky getLocalData()->NameLoc = Loc; 870198398Srdivacky } 871239462Sdim 872208600Srdivacky SourceRange getLocalSourceRange() const { 873239462Sdim return SourceRange(getNameLoc(), getNameEndLoc()); 874198398Srdivacky } 875239462Sdim 876239462Sdim SourceLocation getNameEndLoc() const { 877239462Sdim return getLocalData()->NameEndLoc; 878239462Sdim } 879198398Srdivacky 880239462Sdim void setNameEndLoc(SourceLocation Loc) { 881239462Sdim getLocalData()->NameEndLoc = Loc; 882239462Sdim } 883239462Sdim 884218893Sdim void initializeLocal(ASTContext &Context, SourceLocation Loc) { 885198398Srdivacky setNameLoc(Loc); 886243830Sdim setNameEndLoc(Loc); 887198398Srdivacky } 888198398Srdivacky}; 889198398Srdivacky 890218893Sdimstruct ParenLocInfo { 891218893Sdim SourceLocation LParenLoc; 892218893Sdim SourceLocation RParenLoc; 893218893Sdim}; 894198398Srdivacky 895218893Sdimclass ParenTypeLoc 896218893Sdim : public ConcreteTypeLoc<UnqualTypeLoc, ParenTypeLoc, ParenType, 897218893Sdim ParenLocInfo> { 898218893Sdimpublic: 899218893Sdim SourceLocation getLParenLoc() const { 900218893Sdim return this->getLocalData()->LParenLoc; 901218893Sdim } 902218893Sdim SourceLocation getRParenLoc() const { 903218893Sdim return this->getLocalData()->RParenLoc; 904218893Sdim } 905218893Sdim void setLParenLoc(SourceLocation Loc) { 906218893Sdim this->getLocalData()->LParenLoc = Loc; 907218893Sdim } 908218893Sdim void setRParenLoc(SourceLocation Loc) { 909218893Sdim this->getLocalData()->RParenLoc = Loc; 910218893Sdim } 911218893Sdim 912218893Sdim SourceRange getLocalSourceRange() const { 913218893Sdim return SourceRange(getLParenLoc(), getRParenLoc()); 914218893Sdim } 915218893Sdim 916218893Sdim void initializeLocal(ASTContext &Context, SourceLocation Loc) { 917218893Sdim setLParenLoc(Loc); 918218893Sdim setRParenLoc(Loc); 919218893Sdim } 920218893Sdim 921218893Sdim TypeLoc getInnerLoc() const { 922218893Sdim return getInnerTypeLoc(); 923218893Sdim } 924218893Sdim 925218893Sdim QualType getInnerType() const { 926218893Sdim return this->getTypePtr()->getInnerType(); 927218893Sdim } 928218893Sdim}; 929218893Sdim 930249423Sdiminline TypeLoc TypeLoc::IgnoreParens() const { 931249423Sdim if (ParenTypeLoc::isKind(*this)) 932249423Sdim return IgnoreParensImpl(*this); 933249423Sdim return *this; 934249423Sdim} 935218893Sdim 936198398Srdivackystruct PointerLikeLocInfo { 937198398Srdivacky SourceLocation StarLoc; 938198092Srdivacky}; 939198092Srdivacky 940234353Sdim/// A base class for 941198398Srdivackytemplate <class Derived, class TypeClass, class LocalData = PointerLikeLocInfo> 942198398Srdivackyclass PointerLikeTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, Derived, 943198398Srdivacky TypeClass, LocalData> { 944234353Sdimpublic: 945198398Srdivacky SourceLocation getSigilLoc() const { 946198398Srdivacky return this->getLocalData()->StarLoc; 947198092Srdivacky } 948198398Srdivacky void setSigilLoc(SourceLocation Loc) { 949198398Srdivacky this->getLocalData()->StarLoc = Loc; 950198092Srdivacky } 951198092Srdivacky 952198092Srdivacky TypeLoc getPointeeLoc() const { 953198398Srdivacky return this->getInnerTypeLoc(); 954198092Srdivacky } 955198092Srdivacky 956208600Srdivacky SourceRange getLocalSourceRange() const { 957198398Srdivacky return SourceRange(getSigilLoc(), getSigilLoc()); 958198092Srdivacky } 959198092Srdivacky 960218893Sdim void initializeLocal(ASTContext &Context, SourceLocation Loc) { 961198398Srdivacky setSigilLoc(Loc); 962198092Srdivacky } 963198092Srdivacky 964198398Srdivacky QualType getInnerType() const { 965198398Srdivacky return this->getTypePtr()->getPointeeType(); 966198398Srdivacky } 967198112Srdivacky}; 968198092Srdivacky 969198092Srdivacky 970198398Srdivacky/// \brief Wrapper for source info for pointers. 971198398Srdivackyclass PointerTypeLoc : public PointerLikeTypeLoc<PointerTypeLoc, 972198398Srdivacky PointerType> { 973198092Srdivackypublic: 974198092Srdivacky SourceLocation getStarLoc() const { 975198398Srdivacky return getSigilLoc(); 976198092Srdivacky } 977198092Srdivacky void setStarLoc(SourceLocation Loc) { 978198398Srdivacky setSigilLoc(Loc); 979198092Srdivacky } 980198398Srdivacky}; 981198092Srdivacky 982198092Srdivacky 983198398Srdivacky/// \brief Wrapper for source info for block pointers. 984198398Srdivackyclass BlockPointerTypeLoc : public PointerLikeTypeLoc<BlockPointerTypeLoc, 985198398Srdivacky BlockPointerType> { 986198398Srdivackypublic: 987198398Srdivacky SourceLocation getCaretLoc() const { 988198398Srdivacky return getSigilLoc(); 989198092Srdivacky } 990198398Srdivacky void setCaretLoc(SourceLocation Loc) { 991198398Srdivacky setSigilLoc(Loc); 992198398Srdivacky } 993198398Srdivacky}; 994198092Srdivacky 995221345Sdimstruct MemberPointerLocInfo : public PointerLikeLocInfo { 996221345Sdim TypeSourceInfo *ClassTInfo; 997221345Sdim}; 998198398Srdivacky 999198398Srdivacky/// \brief Wrapper for source info for member pointers. 1000198398Srdivackyclass MemberPointerTypeLoc : public PointerLikeTypeLoc<MemberPointerTypeLoc, 1001221345Sdim MemberPointerType, 1002221345Sdim MemberPointerLocInfo> { 1003198398Srdivackypublic: 1004198398Srdivacky SourceLocation getStarLoc() const { 1005198398Srdivacky return getSigilLoc(); 1006198092Srdivacky } 1007198398Srdivacky void setStarLoc(SourceLocation Loc) { 1008198398Srdivacky setSigilLoc(Loc); 1009198398Srdivacky } 1010221345Sdim 1011221345Sdim const Type *getClass() const { 1012221345Sdim return getTypePtr()->getClass(); 1013221345Sdim } 1014221345Sdim TypeSourceInfo *getClassTInfo() const { 1015221345Sdim return getLocalData()->ClassTInfo; 1016221345Sdim } 1017221345Sdim void setClassTInfo(TypeSourceInfo* TI) { 1018221345Sdim getLocalData()->ClassTInfo = TI; 1019221345Sdim } 1020221345Sdim 1021221345Sdim void initializeLocal(ASTContext &Context, SourceLocation Loc) { 1022221345Sdim setSigilLoc(Loc); 1023221345Sdim setClassTInfo(0); 1024221345Sdim } 1025221345Sdim 1026221345Sdim SourceRange getLocalSourceRange() const { 1027221345Sdim if (TypeSourceInfo *TI = getClassTInfo()) 1028221345Sdim return SourceRange(TI->getTypeLoc().getBeginLoc(), getStarLoc()); 1029221345Sdim else 1030221345Sdim return SourceRange(getStarLoc()); 1031221345Sdim } 1032198112Srdivacky}; 1033198092Srdivacky 1034208600Srdivacky/// Wraps an ObjCPointerType with source location information. 1035208600Srdivackyclass ObjCObjectPointerTypeLoc : 1036208600Srdivacky public PointerLikeTypeLoc<ObjCObjectPointerTypeLoc, 1037208600Srdivacky ObjCObjectPointerType> { 1038208600Srdivackypublic: 1039208600Srdivacky SourceLocation getStarLoc() const { 1040208600Srdivacky return getSigilLoc(); 1041208600Srdivacky } 1042198092Srdivacky 1043208600Srdivacky void setStarLoc(SourceLocation Loc) { 1044208600Srdivacky setSigilLoc(Loc); 1045208600Srdivacky } 1046208600Srdivacky}; 1047208600Srdivacky 1048208600Srdivacky 1049198398Srdivackyclass ReferenceTypeLoc : public PointerLikeTypeLoc<ReferenceTypeLoc, 1050198398Srdivacky ReferenceType> { 1051198398Srdivackypublic: 1052198398Srdivacky QualType getInnerType() const { 1053198398Srdivacky return getTypePtr()->getPointeeTypeAsWritten(); 1054198398Srdivacky } 1055198092Srdivacky}; 1056198092Srdivacky 1057198398Srdivackyclass LValueReferenceTypeLoc : 1058198398Srdivacky public InheritingConcreteTypeLoc<ReferenceTypeLoc, 1059198398Srdivacky LValueReferenceTypeLoc, 1060198398Srdivacky LValueReferenceType> { 1061198092Srdivackypublic: 1062198092Srdivacky SourceLocation getAmpLoc() const { 1063198398Srdivacky return getSigilLoc(); 1064198092Srdivacky } 1065198092Srdivacky void setAmpLoc(SourceLocation Loc) { 1066198398Srdivacky setSigilLoc(Loc); 1067198092Srdivacky } 1068198398Srdivacky}; 1069198092Srdivacky 1070198398Srdivackyclass RValueReferenceTypeLoc : 1071198398Srdivacky public InheritingConcreteTypeLoc<ReferenceTypeLoc, 1072198398Srdivacky RValueReferenceTypeLoc, 1073198398Srdivacky RValueReferenceType> { 1074198398Srdivackypublic: 1075198398Srdivacky SourceLocation getAmpAmpLoc() const { 1076198398Srdivacky return getSigilLoc(); 1077198092Srdivacky } 1078198398Srdivacky void setAmpAmpLoc(SourceLocation Loc) { 1079198398Srdivacky setSigilLoc(Loc); 1080198092Srdivacky } 1081198112Srdivacky}; 1082198092Srdivacky 1083198092Srdivacky 1084198112Srdivackystruct FunctionLocInfo { 1085221345Sdim SourceLocation LocalRangeBegin; 1086243830Sdim SourceLocation LParenLoc; 1087243830Sdim SourceLocation RParenLoc; 1088221345Sdim SourceLocation LocalRangeEnd; 1089198092Srdivacky}; 1090198092Srdivacky 1091198092Srdivacky/// \brief Wrapper for source info for functions. 1092198398Srdivackyclass FunctionTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, 1093198398Srdivacky FunctionTypeLoc, 1094198398Srdivacky FunctionType, 1095198398Srdivacky FunctionLocInfo> { 1096198092Srdivackypublic: 1097221345Sdim SourceLocation getLocalRangeBegin() const { 1098221345Sdim return getLocalData()->LocalRangeBegin; 1099198092Srdivacky } 1100221345Sdim void setLocalRangeBegin(SourceLocation L) { 1101221345Sdim getLocalData()->LocalRangeBegin = L; 1102198092Srdivacky } 1103198092Srdivacky 1104221345Sdim SourceLocation getLocalRangeEnd() const { 1105221345Sdim return getLocalData()->LocalRangeEnd; 1106198092Srdivacky } 1107221345Sdim void setLocalRangeEnd(SourceLocation L) { 1108221345Sdim getLocalData()->LocalRangeEnd = L; 1109198092Srdivacky } 1110198092Srdivacky 1111243830Sdim SourceLocation getLParenLoc() const { 1112243830Sdim return this->getLocalData()->LParenLoc; 1113243830Sdim } 1114243830Sdim void setLParenLoc(SourceLocation Loc) { 1115243830Sdim this->getLocalData()->LParenLoc = Loc; 1116243830Sdim } 1117243830Sdim 1118243830Sdim SourceLocation getRParenLoc() const { 1119243830Sdim return this->getLocalData()->RParenLoc; 1120243830Sdim } 1121243830Sdim void setRParenLoc(SourceLocation Loc) { 1122243830Sdim this->getLocalData()->RParenLoc = Loc; 1123243830Sdim } 1124243830Sdim 1125243830Sdim SourceRange getParensRange() const { 1126243830Sdim return SourceRange(getLParenLoc(), getRParenLoc()); 1127243830Sdim } 1128243830Sdim 1129234353Sdim ArrayRef<ParmVarDecl *> getParams() const { 1130234353Sdim return ArrayRef<ParmVarDecl *>(getParmArray(), getNumArgs()); 1131234353Sdim } 1132234353Sdim 1133218893Sdim // ParmVarDecls* are stored after Info, one for each argument. 1134218893Sdim ParmVarDecl **getParmArray() const { 1135218893Sdim return (ParmVarDecl**) getExtraLocalData(); 1136218893Sdim } 1137218893Sdim 1138198092Srdivacky unsigned getNumArgs() const { 1139198112Srdivacky if (isa<FunctionNoProtoType>(getTypePtr())) 1140198092Srdivacky return 0; 1141198112Srdivacky return cast<FunctionProtoType>(getTypePtr())->getNumArgs(); 1142198092Srdivacky } 1143198092Srdivacky ParmVarDecl *getArg(unsigned i) const { return getParmArray()[i]; } 1144198092Srdivacky void setArg(unsigned i, ParmVarDecl *VD) { getParmArray()[i] = VD; } 1145198092Srdivacky 1146198092Srdivacky TypeLoc getResultLoc() const { 1147198112Srdivacky return getInnerTypeLoc(); 1148198092Srdivacky } 1149198092Srdivacky 1150208600Srdivacky SourceRange getLocalSourceRange() const { 1151221345Sdim return SourceRange(getLocalRangeBegin(), getLocalRangeEnd()); 1152198092Srdivacky } 1153198092Srdivacky 1154218893Sdim void initializeLocal(ASTContext &Context, SourceLocation Loc) { 1155221345Sdim setLocalRangeBegin(Loc); 1156243830Sdim setLParenLoc(Loc); 1157243830Sdim setRParenLoc(Loc); 1158221345Sdim setLocalRangeEnd(Loc); 1159198398Srdivacky for (unsigned i = 0, e = getNumArgs(); i != e; ++i) 1160198398Srdivacky setArg(i, NULL); 1161198398Srdivacky } 1162198398Srdivacky 1163198092Srdivacky /// \brief Returns the size of the type source info data block that is 1164198092Srdivacky /// specific to this type. 1165198112Srdivacky unsigned getExtraLocalDataSize() const { 1166198112Srdivacky return getNumArgs() * sizeof(ParmVarDecl*); 1167198092Srdivacky } 1168198092Srdivacky 1169198112Srdivacky QualType getInnerType() const { return getTypePtr()->getResultType(); } 1170198112Srdivacky}; 1171198092Srdivacky 1172198398Srdivackyclass FunctionProtoTypeLoc : 1173198398Srdivacky public InheritingConcreteTypeLoc<FunctionTypeLoc, 1174198398Srdivacky FunctionProtoTypeLoc, 1175198398Srdivacky FunctionProtoType> { 1176198398Srdivacky}; 1177198112Srdivacky 1178198398Srdivackyclass FunctionNoProtoTypeLoc : 1179198398Srdivacky public InheritingConcreteTypeLoc<FunctionTypeLoc, 1180198398Srdivacky FunctionNoProtoTypeLoc, 1181198398Srdivacky FunctionNoProtoType> { 1182198398Srdivacky}; 1183198398Srdivacky 1184198398Srdivacky 1185198112Srdivackystruct ArrayLocInfo { 1186198112Srdivacky SourceLocation LBracketLoc, RBracketLoc; 1187198112Srdivacky Expr *Size; 1188198092Srdivacky}; 1189198092Srdivacky 1190198092Srdivacky/// \brief Wrapper for source info for arrays. 1191198398Srdivackyclass ArrayTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, 1192198398Srdivacky ArrayTypeLoc, 1193198398Srdivacky ArrayType, 1194198398Srdivacky ArrayLocInfo> { 1195198092Srdivackypublic: 1196198092Srdivacky SourceLocation getLBracketLoc() const { 1197198112Srdivacky return getLocalData()->LBracketLoc; 1198198092Srdivacky } 1199198092Srdivacky void setLBracketLoc(SourceLocation Loc) { 1200198112Srdivacky getLocalData()->LBracketLoc = Loc; 1201198092Srdivacky } 1202198092Srdivacky 1203198092Srdivacky SourceLocation getRBracketLoc() const { 1204198112Srdivacky return getLocalData()->RBracketLoc; 1205198092Srdivacky } 1206198092Srdivacky void setRBracketLoc(SourceLocation Loc) { 1207198112Srdivacky getLocalData()->RBracketLoc = Loc; 1208198092Srdivacky } 1209198092Srdivacky 1210198893Srdivacky SourceRange getBracketsRange() const { 1211198893Srdivacky return SourceRange(getLBracketLoc(), getRBracketLoc()); 1212198893Srdivacky } 1213198893Srdivacky 1214198092Srdivacky Expr *getSizeExpr() const { 1215198112Srdivacky return getLocalData()->Size; 1216198092Srdivacky } 1217198092Srdivacky void setSizeExpr(Expr *Size) { 1218198112Srdivacky getLocalData()->Size = Size; 1219198092Srdivacky } 1220198092Srdivacky 1221198092Srdivacky TypeLoc getElementLoc() const { 1222198112Srdivacky return getInnerTypeLoc(); 1223198092Srdivacky } 1224198092Srdivacky 1225208600Srdivacky SourceRange getLocalSourceRange() const { 1226198092Srdivacky return SourceRange(getLBracketLoc(), getRBracketLoc()); 1227198092Srdivacky } 1228198092Srdivacky 1229218893Sdim void initializeLocal(ASTContext &Context, SourceLocation Loc) { 1230198398Srdivacky setLBracketLoc(Loc); 1231198398Srdivacky setRBracketLoc(Loc); 1232198398Srdivacky setSizeExpr(NULL); 1233198398Srdivacky } 1234198398Srdivacky 1235198112Srdivacky QualType getInnerType() const { return getTypePtr()->getElementType(); } 1236198092Srdivacky}; 1237198092Srdivacky 1238198398Srdivackyclass ConstantArrayTypeLoc : 1239198398Srdivacky public InheritingConcreteTypeLoc<ArrayTypeLoc, 1240198398Srdivacky ConstantArrayTypeLoc, 1241198398Srdivacky ConstantArrayType> { 1242198398Srdivacky}; 1243198398Srdivacky 1244198398Srdivackyclass IncompleteArrayTypeLoc : 1245198398Srdivacky public InheritingConcreteTypeLoc<ArrayTypeLoc, 1246198398Srdivacky IncompleteArrayTypeLoc, 1247198398Srdivacky IncompleteArrayType> { 1248198398Srdivacky}; 1249198398Srdivacky 1250198398Srdivackyclass DependentSizedArrayTypeLoc : 1251198398Srdivacky public InheritingConcreteTypeLoc<ArrayTypeLoc, 1252198398Srdivacky DependentSizedArrayTypeLoc, 1253198398Srdivacky DependentSizedArrayType> { 1254198398Srdivacky 1255198398Srdivacky}; 1256198398Srdivacky 1257198398Srdivackyclass VariableArrayTypeLoc : 1258198398Srdivacky public InheritingConcreteTypeLoc<ArrayTypeLoc, 1259198398Srdivacky VariableArrayTypeLoc, 1260198398Srdivacky VariableArrayType> { 1261198398Srdivacky}; 1262198398Srdivacky 1263198893Srdivacky 1264198893Srdivacky// Location information for a TemplateName. Rudimentary for now. 1265198893Srdivackystruct TemplateNameLocInfo { 1266198893Srdivacky SourceLocation NameLoc; 1267198893Srdivacky}; 1268198893Srdivacky 1269198893Srdivackystruct TemplateSpecializationLocInfo : TemplateNameLocInfo { 1270234353Sdim SourceLocation TemplateKWLoc; 1271198893Srdivacky SourceLocation LAngleLoc; 1272198893Srdivacky SourceLocation RAngleLoc; 1273198893Srdivacky}; 1274198893Srdivacky 1275198893Srdivackyclass TemplateSpecializationTypeLoc : 1276198893Srdivacky public ConcreteTypeLoc<UnqualTypeLoc, 1277198893Srdivacky TemplateSpecializationTypeLoc, 1278198893Srdivacky TemplateSpecializationType, 1279198893Srdivacky TemplateSpecializationLocInfo> { 1280198893Srdivackypublic: 1281234353Sdim SourceLocation getTemplateKeywordLoc() const { 1282234353Sdim return getLocalData()->TemplateKWLoc; 1283234353Sdim } 1284234353Sdim void setTemplateKeywordLoc(SourceLocation Loc) { 1285234353Sdim getLocalData()->TemplateKWLoc = Loc; 1286234353Sdim } 1287234353Sdim 1288198893Srdivacky SourceLocation getLAngleLoc() const { 1289198893Srdivacky return getLocalData()->LAngleLoc; 1290198893Srdivacky } 1291198893Srdivacky void setLAngleLoc(SourceLocation Loc) { 1292198893Srdivacky getLocalData()->LAngleLoc = Loc; 1293198893Srdivacky } 1294198893Srdivacky 1295198893Srdivacky SourceLocation getRAngleLoc() const { 1296198893Srdivacky return getLocalData()->RAngleLoc; 1297198893Srdivacky } 1298198893Srdivacky void setRAngleLoc(SourceLocation Loc) { 1299198893Srdivacky getLocalData()->RAngleLoc = Loc; 1300198893Srdivacky } 1301198893Srdivacky 1302198893Srdivacky unsigned getNumArgs() const { 1303198893Srdivacky return getTypePtr()->getNumArgs(); 1304198893Srdivacky } 1305198893Srdivacky void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) { 1306198893Srdivacky getArgInfos()[i] = AI; 1307198893Srdivacky } 1308198893Srdivacky TemplateArgumentLocInfo getArgLocInfo(unsigned i) const { 1309198893Srdivacky return getArgInfos()[i]; 1310198893Srdivacky } 1311198893Srdivacky 1312198893Srdivacky TemplateArgumentLoc getArgLoc(unsigned i) const { 1313198893Srdivacky return TemplateArgumentLoc(getTypePtr()->getArg(i), getArgLocInfo(i)); 1314198893Srdivacky } 1315198893Srdivacky 1316198893Srdivacky SourceLocation getTemplateNameLoc() const { 1317198893Srdivacky return getLocalData()->NameLoc; 1318198893Srdivacky } 1319198893Srdivacky void setTemplateNameLoc(SourceLocation Loc) { 1320198893Srdivacky getLocalData()->NameLoc = Loc; 1321198893Srdivacky } 1322198893Srdivacky 1323198893Srdivacky /// \brief - Copy the location information from the given info. 1324198893Srdivacky void copy(TemplateSpecializationTypeLoc Loc) { 1325198893Srdivacky unsigned size = getFullDataSize(); 1326198893Srdivacky assert(size == Loc.getFullDataSize()); 1327198893Srdivacky 1328198893Srdivacky // We're potentially copying Expr references here. We don't 1329200583Srdivacky // bother retaining them because TypeSourceInfos live forever, so 1330198893Srdivacky // as long as the Expr was retained when originally written into 1331198893Srdivacky // the TypeLoc, we're okay. 1332198893Srdivacky memcpy(Data, Loc.Data, size); 1333198893Srdivacky } 1334198893Srdivacky 1335208600Srdivacky SourceRange getLocalSourceRange() const { 1336234353Sdim if (getTemplateKeywordLoc().isValid()) 1337234353Sdim return SourceRange(getTemplateKeywordLoc(), getRAngleLoc()); 1338234353Sdim else 1339234353Sdim return SourceRange(getTemplateNameLoc(), getRAngleLoc()); 1340198893Srdivacky } 1341198893Srdivacky 1342218893Sdim void initializeLocal(ASTContext &Context, SourceLocation Loc) { 1343234353Sdim setTemplateKeywordLoc(Loc); 1344234353Sdim setTemplateNameLoc(Loc); 1345198893Srdivacky setLAngleLoc(Loc); 1346198893Srdivacky setRAngleLoc(Loc); 1347218893Sdim initializeArgLocs(Context, getNumArgs(), getTypePtr()->getArgs(), 1348210299Sed getArgInfos(), Loc); 1349210299Sed } 1350198893Srdivacky 1351218893Sdim static void initializeArgLocs(ASTContext &Context, unsigned NumArgs, 1352210299Sed const TemplateArgument *Args, 1353210299Sed TemplateArgumentLocInfo *ArgInfos, 1354218893Sdim SourceLocation Loc); 1355198893Srdivacky 1356198893Srdivacky unsigned getExtraLocalDataSize() const { 1357198893Srdivacky return getNumArgs() * sizeof(TemplateArgumentLocInfo); 1358198893Srdivacky } 1359198893Srdivacky 1360198893Srdivackyprivate: 1361198893Srdivacky TemplateArgumentLocInfo *getArgInfos() const { 1362198893Srdivacky return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData()); 1363198893Srdivacky } 1364198893Srdivacky}; 1365198893Srdivacky 1366200583Srdivacky//===----------------------------------------------------------------------===// 1367200583Srdivacky// 1368200583Srdivacky// All of these need proper implementations. 1369200583Srdivacky// 1370200583Srdivacky//===----------------------------------------------------------------------===// 1371198398Srdivacky 1372200583Srdivacky// FIXME: size expression and attribute locations (or keyword if we 1373200583Srdivacky// ever fully support altivec syntax). 1374200583Srdivackyclass VectorTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 1375200583Srdivacky VectorTypeLoc, 1376200583Srdivacky VectorType> { 1377198398Srdivacky}; 1378198398Srdivacky 1379200583Srdivacky// FIXME: size expression and attribute locations. 1380198398Srdivackyclass ExtVectorTypeLoc : public InheritingConcreteTypeLoc<VectorTypeLoc, 1381198398Srdivacky ExtVectorTypeLoc, 1382198398Srdivacky ExtVectorType> { 1383198398Srdivacky}; 1384198398Srdivacky 1385200583Srdivacky// FIXME: attribute locations. 1386198398Srdivacky// For some reason, this isn't a subtype of VectorType. 1387198398Srdivackyclass DependentSizedExtVectorTypeLoc : 1388200583Srdivacky public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 1389200583Srdivacky DependentSizedExtVectorTypeLoc, 1390200583Srdivacky DependentSizedExtVectorType> { 1391198398Srdivacky}; 1392198398Srdivacky 1393200583Srdivacky// FIXME: location of the '_Complex' keyword. 1394200583Srdivackyclass ComplexTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 1395200583Srdivacky ComplexTypeLoc, 1396200583Srdivacky ComplexType> { 1397198398Srdivacky}; 1398198398Srdivacky 1399202379Srdivackystruct TypeofLocInfo { 1400202379Srdivacky SourceLocation TypeofLoc; 1401202379Srdivacky SourceLocation LParenLoc; 1402202379Srdivacky SourceLocation RParenLoc; 1403198398Srdivacky}; 1404198398Srdivacky 1405202379Srdivackystruct TypeOfExprTypeLocInfo : public TypeofLocInfo { 1406198398Srdivacky}; 1407198398Srdivacky 1408202379Srdivackystruct TypeOfTypeLocInfo : public TypeofLocInfo { 1409202379Srdivacky TypeSourceInfo* UnderlyingTInfo; 1410202379Srdivacky}; 1411202379Srdivacky 1412202379Srdivackytemplate <class Derived, class TypeClass, class LocalData = TypeofLocInfo> 1413202379Srdivackyclass TypeofLikeTypeLoc 1414202379Srdivacky : public ConcreteTypeLoc<UnqualTypeLoc, Derived, TypeClass, LocalData> { 1415202379Srdivackypublic: 1416202379Srdivacky SourceLocation getTypeofLoc() const { 1417202379Srdivacky return this->getLocalData()->TypeofLoc; 1418202379Srdivacky } 1419202379Srdivacky void setTypeofLoc(SourceLocation Loc) { 1420202379Srdivacky this->getLocalData()->TypeofLoc = Loc; 1421202379Srdivacky } 1422202379Srdivacky 1423202379Srdivacky SourceLocation getLParenLoc() const { 1424202379Srdivacky return this->getLocalData()->LParenLoc; 1425202379Srdivacky } 1426202379Srdivacky void setLParenLoc(SourceLocation Loc) { 1427202379Srdivacky this->getLocalData()->LParenLoc = Loc; 1428202379Srdivacky } 1429202379Srdivacky 1430202379Srdivacky SourceLocation getRParenLoc() const { 1431202379Srdivacky return this->getLocalData()->RParenLoc; 1432202379Srdivacky } 1433202379Srdivacky void setRParenLoc(SourceLocation Loc) { 1434202379Srdivacky this->getLocalData()->RParenLoc = Loc; 1435202379Srdivacky } 1436202379Srdivacky 1437202379Srdivacky SourceRange getParensRange() const { 1438202379Srdivacky return SourceRange(getLParenLoc(), getRParenLoc()); 1439202379Srdivacky } 1440202379Srdivacky void setParensRange(SourceRange range) { 1441202379Srdivacky setLParenLoc(range.getBegin()); 1442202379Srdivacky setRParenLoc(range.getEnd()); 1443202379Srdivacky } 1444202379Srdivacky 1445208600Srdivacky SourceRange getLocalSourceRange() const { 1446202379Srdivacky return SourceRange(getTypeofLoc(), getRParenLoc()); 1447202379Srdivacky } 1448202379Srdivacky 1449218893Sdim void initializeLocal(ASTContext &Context, SourceLocation Loc) { 1450202379Srdivacky setTypeofLoc(Loc); 1451202379Srdivacky setLParenLoc(Loc); 1452202379Srdivacky setRParenLoc(Loc); 1453202379Srdivacky } 1454202379Srdivacky}; 1455202379Srdivacky 1456202379Srdivackyclass TypeOfExprTypeLoc : public TypeofLikeTypeLoc<TypeOfExprTypeLoc, 1457202379Srdivacky TypeOfExprType, 1458202379Srdivacky TypeOfExprTypeLocInfo> { 1459202379Srdivackypublic: 1460202379Srdivacky Expr* getUnderlyingExpr() const { 1461202379Srdivacky return getTypePtr()->getUnderlyingExpr(); 1462202379Srdivacky } 1463202379Srdivacky // Reimplemented to account for GNU/C++ extension 1464202379Srdivacky // typeof unary-expression 1465202379Srdivacky // where there are no parentheses. 1466208600Srdivacky SourceRange getLocalSourceRange() const; 1467202379Srdivacky}; 1468202379Srdivacky 1469202379Srdivackyclass TypeOfTypeLoc 1470202379Srdivacky : public TypeofLikeTypeLoc<TypeOfTypeLoc, TypeOfType, TypeOfTypeLocInfo> { 1471202379Srdivackypublic: 1472202379Srdivacky QualType getUnderlyingType() const { 1473202379Srdivacky return this->getTypePtr()->getUnderlyingType(); 1474202379Srdivacky } 1475202379Srdivacky TypeSourceInfo* getUnderlyingTInfo() const { 1476202379Srdivacky return this->getLocalData()->UnderlyingTInfo; 1477202379Srdivacky } 1478202379Srdivacky void setUnderlyingTInfo(TypeSourceInfo* TI) const { 1479202379Srdivacky this->getLocalData()->UnderlyingTInfo = TI; 1480202379Srdivacky } 1481202379Srdivacky}; 1482202379Srdivacky 1483200583Srdivacky// FIXME: location of the 'decltype' and parens. 1484200583Srdivackyclass DecltypeTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 1485200583Srdivacky DecltypeTypeLoc, 1486200583Srdivacky DecltypeType> { 1487226633Sdimpublic: 1488226633Sdim Expr *getUnderlyingExpr() const { return getTypePtr()->getUnderlyingExpr(); } 1489198398Srdivacky}; 1490198398Srdivacky 1491223017Sdimstruct UnaryTransformTypeLocInfo { 1492223017Sdim // FIXME: While there's only one unary transform right now, future ones may 1493223017Sdim // need different representations 1494223017Sdim SourceLocation KWLoc, LParenLoc, RParenLoc; 1495223017Sdim TypeSourceInfo *UnderlyingTInfo; 1496223017Sdim}; 1497223017Sdim 1498223017Sdimclass UnaryTransformTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, 1499223017Sdim UnaryTransformTypeLoc, 1500223017Sdim UnaryTransformType, 1501223017Sdim UnaryTransformTypeLocInfo> { 1502223017Sdimpublic: 1503223017Sdim SourceLocation getKWLoc() const { return getLocalData()->KWLoc; } 1504223017Sdim void setKWLoc(SourceLocation Loc) { getLocalData()->KWLoc = Loc; } 1505223017Sdim 1506223017Sdim SourceLocation getLParenLoc() const { return getLocalData()->LParenLoc; } 1507223017Sdim void setLParenLoc(SourceLocation Loc) { getLocalData()->LParenLoc = Loc; } 1508223017Sdim 1509223017Sdim SourceLocation getRParenLoc() const { return getLocalData()->RParenLoc; } 1510223017Sdim void setRParenLoc(SourceLocation Loc) { getLocalData()->RParenLoc = Loc; } 1511223017Sdim 1512223017Sdim TypeSourceInfo* getUnderlyingTInfo() const { 1513223017Sdim return getLocalData()->UnderlyingTInfo; 1514223017Sdim } 1515223017Sdim void setUnderlyingTInfo(TypeSourceInfo *TInfo) { 1516223017Sdim getLocalData()->UnderlyingTInfo = TInfo; 1517223017Sdim } 1518223017Sdim 1519223017Sdim SourceRange getLocalSourceRange() const { 1520223017Sdim return SourceRange(getKWLoc(), getRParenLoc()); 1521223017Sdim } 1522223017Sdim 1523223017Sdim SourceRange getParensRange() const { 1524223017Sdim return SourceRange(getLParenLoc(), getRParenLoc()); 1525223017Sdim } 1526223017Sdim void setParensRange(SourceRange Range) { 1527223017Sdim setLParenLoc(Range.getBegin()); 1528223017Sdim setRParenLoc(Range.getEnd()); 1529223017Sdim } 1530223017Sdim 1531223017Sdim void initializeLocal(ASTContext &Context, SourceLocation Loc) { 1532223017Sdim setKWLoc(Loc); 1533223017Sdim setRParenLoc(Loc); 1534223017Sdim setLParenLoc(Loc); 1535223017Sdim } 1536223017Sdim}; 1537223017Sdim 1538218893Sdimclass AutoTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, 1539218893Sdim AutoTypeLoc, 1540218893Sdim AutoType> { 1541218893Sdim}; 1542218893Sdim 1543208600Srdivackystruct ElaboratedLocInfo { 1544234353Sdim SourceLocation ElaboratedKWLoc; 1545234353Sdim /// \brief Data associated with the nested-name-specifier location. 1546221345Sdim void *QualifierData; 1547198398Srdivacky}; 1548198398Srdivacky 1549208600Srdivackyclass ElaboratedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, 1550208600Srdivacky ElaboratedTypeLoc, 1551208600Srdivacky ElaboratedType, 1552208600Srdivacky ElaboratedLocInfo> { 1553208600Srdivackypublic: 1554234353Sdim SourceLocation getElaboratedKeywordLoc() const { 1555234353Sdim return this->getLocalData()->ElaboratedKWLoc; 1556208600Srdivacky } 1557234353Sdim void setElaboratedKeywordLoc(SourceLocation Loc) { 1558234353Sdim this->getLocalData()->ElaboratedKWLoc = Loc; 1559208600Srdivacky } 1560208600Srdivacky 1561221345Sdim NestedNameSpecifierLoc getQualifierLoc() const { 1562234353Sdim return NestedNameSpecifierLoc(getTypePtr()->getQualifier(), 1563221345Sdim getLocalData()->QualifierData); 1564208600Srdivacky } 1565234353Sdim 1566221345Sdim void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) { 1567234353Sdim assert(QualifierLoc.getNestedNameSpecifier() 1568221345Sdim == getTypePtr()->getQualifier() && 1569221345Sdim "Inconsistent nested-name-specifier pointer"); 1570221345Sdim getLocalData()->QualifierData = QualifierLoc.getOpaqueData(); 1571208600Srdivacky } 1572208600Srdivacky 1573208600Srdivacky SourceRange getLocalSourceRange() const { 1574234353Sdim if (getElaboratedKeywordLoc().isValid()) 1575221345Sdim if (getQualifierLoc()) 1576234353Sdim return SourceRange(getElaboratedKeywordLoc(), 1577234353Sdim getQualifierLoc().getEndLoc()); 1578208600Srdivacky else 1579234353Sdim return SourceRange(getElaboratedKeywordLoc()); 1580208600Srdivacky else 1581221345Sdim return getQualifierLoc().getSourceRange(); 1582208600Srdivacky } 1583208600Srdivacky 1584221345Sdim void initializeLocal(ASTContext &Context, SourceLocation Loc); 1585208600Srdivacky 1586208600Srdivacky TypeLoc getNamedTypeLoc() const { 1587208600Srdivacky return getInnerTypeLoc(); 1588208600Srdivacky } 1589208600Srdivacky 1590208600Srdivacky QualType getInnerType() const { 1591208600Srdivacky return getTypePtr()->getNamedType(); 1592208600Srdivacky } 1593208600Srdivacky 1594208600Srdivacky void copy(ElaboratedTypeLoc Loc) { 1595208600Srdivacky unsigned size = getFullDataSize(); 1596208600Srdivacky assert(size == Loc.getFullDataSize()); 1597208600Srdivacky memcpy(Data, Loc.Data, size); 1598208600Srdivacky } 1599198398Srdivacky}; 1600198398Srdivacky 1601210299Sed// This is exactly the structure of an ElaboratedTypeLoc whose inner 1602210299Sed// type is some sort of TypeDeclTypeLoc. 1603210299Sedstruct DependentNameLocInfo : ElaboratedLocInfo { 1604208600Srdivacky SourceLocation NameLoc; 1605198398Srdivacky}; 1606198398Srdivacky 1607208600Srdivackyclass DependentNameTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, 1608208600Srdivacky DependentNameTypeLoc, 1609208600Srdivacky DependentNameType, 1610208600Srdivacky DependentNameLocInfo> { 1611208600Srdivackypublic: 1612234353Sdim SourceLocation getElaboratedKeywordLoc() const { 1613234353Sdim return this->getLocalData()->ElaboratedKWLoc; 1614208600Srdivacky } 1615234353Sdim void setElaboratedKeywordLoc(SourceLocation Loc) { 1616234353Sdim this->getLocalData()->ElaboratedKWLoc = Loc; 1617208600Srdivacky } 1618208600Srdivacky 1619221345Sdim NestedNameSpecifierLoc getQualifierLoc() const { 1620234353Sdim return NestedNameSpecifierLoc(getTypePtr()->getQualifier(), 1621221345Sdim getLocalData()->QualifierData); 1622208600Srdivacky } 1623234353Sdim 1624221345Sdim void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) { 1625234353Sdim assert(QualifierLoc.getNestedNameSpecifier() 1626221345Sdim == getTypePtr()->getQualifier() && 1627221345Sdim "Inconsistent nested-name-specifier pointer"); 1628221345Sdim getLocalData()->QualifierData = QualifierLoc.getOpaqueData(); 1629208600Srdivacky } 1630234353Sdim 1631208600Srdivacky SourceLocation getNameLoc() const { 1632208600Srdivacky return this->getLocalData()->NameLoc; 1633208600Srdivacky } 1634208600Srdivacky void setNameLoc(SourceLocation Loc) { 1635208600Srdivacky this->getLocalData()->NameLoc = Loc; 1636208600Srdivacky } 1637208600Srdivacky 1638208600Srdivacky SourceRange getLocalSourceRange() const { 1639234353Sdim if (getElaboratedKeywordLoc().isValid()) 1640234353Sdim return SourceRange(getElaboratedKeywordLoc(), getNameLoc()); 1641208600Srdivacky else 1642221345Sdim return SourceRange(getQualifierLoc().getBeginLoc(), getNameLoc()); 1643208600Srdivacky } 1644208600Srdivacky 1645208600Srdivacky void copy(DependentNameTypeLoc Loc) { 1646208600Srdivacky unsigned size = getFullDataSize(); 1647208600Srdivacky assert(size == Loc.getFullDataSize()); 1648208600Srdivacky memcpy(Data, Loc.Data, size); 1649208600Srdivacky } 1650208600Srdivacky 1651221345Sdim void initializeLocal(ASTContext &Context, SourceLocation Loc); 1652208600Srdivacky}; 1653208600Srdivacky 1654210299Sedstruct DependentTemplateSpecializationLocInfo : DependentNameLocInfo { 1655234353Sdim SourceLocation TemplateKWLoc; 1656210299Sed SourceLocation LAngleLoc; 1657210299Sed SourceLocation RAngleLoc; 1658210299Sed // followed by a TemplateArgumentLocInfo[] 1659210299Sed}; 1660210299Sed 1661210299Sedclass DependentTemplateSpecializationTypeLoc : 1662210299Sed public ConcreteTypeLoc<UnqualTypeLoc, 1663210299Sed DependentTemplateSpecializationTypeLoc, 1664210299Sed DependentTemplateSpecializationType, 1665210299Sed DependentTemplateSpecializationLocInfo> { 1666210299Sedpublic: 1667234353Sdim SourceLocation getElaboratedKeywordLoc() const { 1668234353Sdim return this->getLocalData()->ElaboratedKWLoc; 1669210299Sed } 1670234353Sdim void setElaboratedKeywordLoc(SourceLocation Loc) { 1671234353Sdim this->getLocalData()->ElaboratedKWLoc = Loc; 1672210299Sed } 1673210299Sed 1674221345Sdim NestedNameSpecifierLoc getQualifierLoc() const { 1675221345Sdim if (!getLocalData()->QualifierData) 1676221345Sdim return NestedNameSpecifierLoc(); 1677234353Sdim 1678234353Sdim return NestedNameSpecifierLoc(getTypePtr()->getQualifier(), 1679221345Sdim getLocalData()->QualifierData); 1680210299Sed } 1681234353Sdim 1682221345Sdim void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) { 1683221345Sdim if (!QualifierLoc) { 1684234353Sdim // Even if we have a nested-name-specifier in the dependent 1685221345Sdim // template specialization type, we won't record the nested-name-specifier 1686221345Sdim // location information when this type-source location information is 1687221345Sdim // part of a nested-name-specifier. 1688221345Sdim getLocalData()->QualifierData = 0; 1689221345Sdim return; 1690221345Sdim } 1691234353Sdim 1692234353Sdim assert(QualifierLoc.getNestedNameSpecifier() 1693221345Sdim == getTypePtr()->getQualifier() && 1694221345Sdim "Inconsistent nested-name-specifier pointer"); 1695221345Sdim getLocalData()->QualifierData = QualifierLoc.getOpaqueData(); 1696210299Sed } 1697210299Sed 1698234353Sdim SourceLocation getTemplateKeywordLoc() const { 1699234353Sdim return getLocalData()->TemplateKWLoc; 1700234353Sdim } 1701234353Sdim void setTemplateKeywordLoc(SourceLocation Loc) { 1702234353Sdim getLocalData()->TemplateKWLoc = Loc; 1703234353Sdim } 1704234353Sdim 1705234353Sdim SourceLocation getTemplateNameLoc() const { 1706210299Sed return this->getLocalData()->NameLoc; 1707210299Sed } 1708234353Sdim void setTemplateNameLoc(SourceLocation Loc) { 1709210299Sed this->getLocalData()->NameLoc = Loc; 1710210299Sed } 1711210299Sed 1712210299Sed SourceLocation getLAngleLoc() const { 1713210299Sed return this->getLocalData()->LAngleLoc; 1714210299Sed } 1715210299Sed void setLAngleLoc(SourceLocation Loc) { 1716210299Sed this->getLocalData()->LAngleLoc = Loc; 1717210299Sed } 1718210299Sed 1719210299Sed SourceLocation getRAngleLoc() const { 1720210299Sed return this->getLocalData()->RAngleLoc; 1721210299Sed } 1722210299Sed void setRAngleLoc(SourceLocation Loc) { 1723210299Sed this->getLocalData()->RAngleLoc = Loc; 1724210299Sed } 1725210299Sed 1726210299Sed unsigned getNumArgs() const { 1727210299Sed return getTypePtr()->getNumArgs(); 1728210299Sed } 1729210299Sed 1730210299Sed void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) { 1731210299Sed getArgInfos()[i] = AI; 1732210299Sed } 1733210299Sed TemplateArgumentLocInfo getArgLocInfo(unsigned i) const { 1734210299Sed return getArgInfos()[i]; 1735210299Sed } 1736210299Sed 1737210299Sed TemplateArgumentLoc getArgLoc(unsigned i) const { 1738210299Sed return TemplateArgumentLoc(getTypePtr()->getArg(i), getArgLocInfo(i)); 1739210299Sed } 1740210299Sed 1741210299Sed SourceRange getLocalSourceRange() const { 1742234353Sdim if (getElaboratedKeywordLoc().isValid()) 1743234353Sdim return SourceRange(getElaboratedKeywordLoc(), getRAngleLoc()); 1744221345Sdim else if (getQualifierLoc()) 1745221345Sdim return SourceRange(getQualifierLoc().getBeginLoc(), getRAngleLoc()); 1746234353Sdim else if (getTemplateKeywordLoc().isValid()) 1747234353Sdim return SourceRange(getTemplateKeywordLoc(), getRAngleLoc()); 1748210299Sed else 1749234353Sdim return SourceRange(getTemplateNameLoc(), getRAngleLoc()); 1750210299Sed } 1751210299Sed 1752210299Sed void copy(DependentTemplateSpecializationTypeLoc Loc) { 1753210299Sed unsigned size = getFullDataSize(); 1754210299Sed assert(size == Loc.getFullDataSize()); 1755210299Sed memcpy(Data, Loc.Data, size); 1756210299Sed } 1757210299Sed 1758221345Sdim void initializeLocal(ASTContext &Context, SourceLocation Loc); 1759210299Sed 1760210299Sed unsigned getExtraLocalDataSize() const { 1761210299Sed return getNumArgs() * sizeof(TemplateArgumentLocInfo); 1762210299Sed } 1763210299Sed 1764210299Sedprivate: 1765210299Sed TemplateArgumentLocInfo *getArgInfos() const { 1766210299Sed return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData()); 1767210299Sed } 1768210299Sed}; 1769210299Sed 1770218893Sdim 1771218893Sdimstruct PackExpansionTypeLocInfo { 1772218893Sdim SourceLocation EllipsisLoc; 1773218893Sdim}; 1774218893Sdim 1775218893Sdimclass PackExpansionTypeLoc 1776234353Sdim : public ConcreteTypeLoc<UnqualTypeLoc, PackExpansionTypeLoc, 1777218893Sdim PackExpansionType, PackExpansionTypeLocInfo> { 1778218893Sdimpublic: 1779218893Sdim SourceLocation getEllipsisLoc() const { 1780218893Sdim return this->getLocalData()->EllipsisLoc; 1781218893Sdim } 1782218893Sdim 1783218893Sdim void setEllipsisLoc(SourceLocation Loc) { 1784218893Sdim this->getLocalData()->EllipsisLoc = Loc; 1785218893Sdim } 1786218893Sdim 1787218893Sdim SourceRange getLocalSourceRange() const { 1788218893Sdim return SourceRange(getEllipsisLoc(), getEllipsisLoc()); 1789218893Sdim } 1790218893Sdim 1791218893Sdim void initializeLocal(ASTContext &Context, SourceLocation Loc) { 1792218893Sdim setEllipsisLoc(Loc); 1793218893Sdim } 1794218893Sdim 1795218893Sdim TypeLoc getPatternLoc() const { 1796218893Sdim return getInnerTypeLoc(); 1797218893Sdim } 1798218893Sdim 1799218893Sdim QualType getInnerType() const { 1800218893Sdim return this->getTypePtr()->getPattern(); 1801218893Sdim } 1802218893Sdim}; 1803218893Sdim 1804226633Sdimstruct AtomicTypeLocInfo { 1805226633Sdim SourceLocation KWLoc, LParenLoc, RParenLoc; 1806226633Sdim}; 1807226633Sdim 1808226633Sdimclass AtomicTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, AtomicTypeLoc, 1809226633Sdim AtomicType, AtomicTypeLocInfo> { 1810234353Sdimpublic: 1811226633Sdim TypeLoc getValueLoc() const { 1812226633Sdim return this->getInnerTypeLoc(); 1813226633Sdim } 1814226633Sdim 1815226633Sdim SourceRange getLocalSourceRange() const { 1816226633Sdim return SourceRange(getKWLoc(), getRParenLoc()); 1817226633Sdim } 1818226633Sdim 1819226633Sdim SourceLocation getKWLoc() const { 1820226633Sdim return this->getLocalData()->KWLoc; 1821226633Sdim } 1822226633Sdim void setKWLoc(SourceLocation Loc) { 1823226633Sdim this->getLocalData()->KWLoc = Loc; 1824226633Sdim } 1825226633Sdim 1826226633Sdim SourceLocation getLParenLoc() const { 1827226633Sdim return this->getLocalData()->LParenLoc; 1828226633Sdim } 1829226633Sdim void setLParenLoc(SourceLocation Loc) { 1830226633Sdim this->getLocalData()->LParenLoc = Loc; 1831226633Sdim } 1832226633Sdim 1833226633Sdim SourceLocation getRParenLoc() const { 1834226633Sdim return this->getLocalData()->RParenLoc; 1835226633Sdim } 1836226633Sdim void setRParenLoc(SourceLocation Loc) { 1837226633Sdim this->getLocalData()->RParenLoc = Loc; 1838226633Sdim } 1839226633Sdim 1840226633Sdim SourceRange getParensRange() const { 1841226633Sdim return SourceRange(getLParenLoc(), getRParenLoc()); 1842226633Sdim } 1843226633Sdim void setParensRange(SourceRange Range) { 1844226633Sdim setLParenLoc(Range.getBegin()); 1845226633Sdim setRParenLoc(Range.getEnd()); 1846226633Sdim } 1847226633Sdim 1848226633Sdim void initializeLocal(ASTContext &Context, SourceLocation Loc) { 1849226633Sdim setKWLoc(Loc); 1850226633Sdim setLParenLoc(Loc); 1851226633Sdim setRParenLoc(Loc); 1852226633Sdim } 1853226633Sdim 1854226633Sdim QualType getInnerType() const { 1855226633Sdim return this->getTypePtr()->getValueType(); 1856226633Sdim } 1857226633Sdim}; 1858226633Sdim 1859226633Sdim 1860198092Srdivacky} 1861198092Srdivacky 1862198092Srdivacky#endif 1863