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