Type.h revision 7064f5c95bbdb17680d0ea658d4090898c2592d3
1//===--- Type.h - C Language Family Type Representation ---------*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file was developed by Chris Lattner and is distributed under 6// the University of Illinois Open Source License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file defines the Type interface and subclasses. 11// 12//===----------------------------------------------------------------------===// 13 14#ifndef LLVM_CLANG_AST_TYPE_H 15#define LLVM_CLANG_AST_TYPE_H 16 17#include "llvm/Support/Casting.h" 18#include "llvm/ADT/FoldingSet.h" 19 20using llvm::isa; 21using llvm::cast; 22using llvm::cast_or_null; 23using llvm::dyn_cast; 24using llvm::dyn_cast_or_null; 25 26namespace clang { 27 class ASTContext; 28 class Type; 29 class TypedefDecl; 30 class TagDecl; 31 class RecordDecl; 32 class EnumDecl; 33 class Expr; 34 class SourceLocation; 35 class PointerType; 36 class ReferenceType; 37 class VectorType; 38 class ArrayType; 39 class RecordType; 40 class TagType; 41 class FunctionType; 42 class OCUVectorType; 43 44/// QualType - For efficiency, we don't store CVR-qualified types as nodes on 45/// their own: instead each reference to a type stores the qualifiers. This 46/// greatly reduces the number of nodes we need to allocate for types (for 47/// example we only need one for 'int', 'const int', 'volatile int', 48/// 'const volatile int', etc). 49/// 50/// As an added efficiency bonus, instead of making this a pair, we just store 51/// the three bits we care about in the low bits of the pointer. To handle the 52/// packing/unpacking, we make QualType be a simple wrapper class that acts like 53/// a smart pointer. 54class QualType { 55 uintptr_t ThePtr; 56public: 57 enum TQ { // NOTE: These flags must be kept in sync with DeclSpec::TQ. 58 Const = 0x1, 59 Restrict = 0x2, 60 Volatile = 0x4, 61 CVRFlags = Const|Restrict|Volatile 62 }; 63 64 QualType() : ThePtr(0) {} 65 66 QualType(Type *Ptr, unsigned Quals) { 67 assert((Quals & ~CVRFlags) == 0 && "Invalid type qualifiers!"); 68 ThePtr = reinterpret_cast<uintptr_t>(Ptr); 69 assert((ThePtr & CVRFlags) == 0 && "Type pointer not 8-byte aligned?"); 70 ThePtr |= Quals; 71 } 72 73 static QualType getFromOpaquePtr(void *Ptr) { 74 QualType T; 75 T.ThePtr = reinterpret_cast<uintptr_t>(Ptr); 76 return T; 77 } 78 79 unsigned getQualifiers() const { 80 return ThePtr & CVRFlags; 81 } 82 Type *getTypePtr() const { 83 return reinterpret_cast<Type*>(ThePtr & ~CVRFlags); 84 } 85 86 void *getAsOpaquePtr() const { 87 return reinterpret_cast<void*>(ThePtr); 88 } 89 90 Type &operator*() const { 91 return *getTypePtr(); 92 } 93 94 Type *operator->() const { 95 return getTypePtr(); 96 } 97 98 /// isNull - Return true if this QualType doesn't point to a type yet. 99 bool isNull() const { 100 return ThePtr == 0; 101 } 102 103 bool isConstQualified() const { 104 return ThePtr & Const; 105 } 106 bool isVolatileQualified() const { 107 return ThePtr & Volatile; 108 } 109 bool isRestrictQualified() const { 110 return ThePtr & Restrict; 111 } 112 113 QualType getQualifiedType(unsigned TQs) const { 114 return QualType(getTypePtr(), TQs); 115 } 116 117 QualType getUnqualifiedType() const { 118 return QualType(getTypePtr(), 0); 119 } 120 121 /// operator==/!= - Indicate whether the specified types and qualifiers are 122 /// identical. 123 bool operator==(const QualType &RHS) const { 124 return ThePtr == RHS.ThePtr; 125 } 126 bool operator!=(const QualType &RHS) const { 127 return ThePtr != RHS.ThePtr; 128 } 129 std::string getAsString() const { 130 std::string S; 131 getAsStringInternal(S); 132 return S; 133 } 134 void getAsStringInternal(std::string &Str) const; 135 136 void dump(const char *s = 0) const; 137 138 /// getCanonicalType - Return the canonical version of this type, with the 139 /// appropriate type qualifiers on it. 140 inline QualType getCanonicalType() const; 141 142private: 143}; 144 145} // end clang. 146 147namespace llvm { 148/// Implement simplify_type for QualType, so that we can dyn_cast from QualType 149/// to a specific Type class. 150template<> struct simplify_type<const ::clang::QualType> { 151 typedef ::clang::Type* SimpleType; 152 static SimpleType getSimplifiedValue(const ::clang::QualType &Val) { 153 return Val.getTypePtr(); 154 } 155}; 156template<> struct simplify_type< ::clang::QualType> 157 : public simplify_type<const ::clang::QualType> {}; 158} 159 160namespace clang { 161 162/// Type - This is the base class of the type hierarchy. A central concept 163/// with types is that each type always has a canonical type. A canonical type 164/// is the type with any typedef names stripped out of it or the types it 165/// references. For example, consider: 166/// 167/// typedef int foo; 168/// typedef foo* bar; 169/// 'int *' 'foo *' 'bar' 170/// 171/// There will be a Type object created for 'int'. Since int is canonical, its 172/// canonicaltype pointer points to itself. There is also a Type for 'foo' (a 173/// TypeNameType). Its CanonicalType pointer points to the 'int' Type. Next 174/// there is a PointerType that represents 'int*', which, like 'int', is 175/// canonical. Finally, there is a PointerType type for 'foo*' whose canonical 176/// type is 'int*', and there is a TypeNameType for 'bar', whose canonical type 177/// is also 'int*'. 178/// 179/// Non-canonical types are useful for emitting diagnostics, without losing 180/// information about typedefs being used. Canonical types are useful for type 181/// comparisons (they allow by-pointer equality tests) and useful for reasoning 182/// about whether something has a particular form (e.g. is a function type), 183/// because they implicitly, recursively, strip all typedefs out of a type. 184/// 185/// Types, once created, are immutable. 186/// 187class Type { 188public: 189 enum TypeClass { 190 Builtin, Complex, Pointer, Reference, Array, Vector, OCUVector, 191 FunctionNoProto, FunctionProto, 192 TypeName, Tagged 193 }; 194private: 195 QualType CanonicalType; 196 197 /// TypeClass bitfield - Enum that specifies what subclass this belongs to. 198 /// Note that this should stay at the end of the ivars for Type so that 199 /// subclasses can pack their bitfields into the same word. 200 TypeClass TC : 4; 201protected: 202 Type(TypeClass tc, QualType Canonical) 203 : CanonicalType(Canonical.isNull() ? QualType(this,0) : Canonical), TC(tc){} 204 virtual ~Type(); 205 friend class ASTContext; 206public: 207 TypeClass getTypeClass() const { return TC; } 208 209 bool isCanonical() const { return CanonicalType.getTypePtr() == this; } 210 211 /// Types are partitioned into 3 broad categories (C99 6.2.5p1): 212 /// object types, function types, and incomplete types. 213 214 /// isObjectType - types that fully describe objects. An object is a region 215 /// of memory that can be examined and stored into (H&S). 216 bool isObjectType() const; 217 218 /// isIncompleteType - Return true if this is an incomplete type. 219 /// A type that can describe objects, but which lacks information needed to 220 /// determine its size (e.g. void, or a fwd declared struct). Clients of this 221 /// routine will need to determine if the size is actually required. 222 bool isIncompleteType() const; 223 224 /// Helper methods to distinguish type categories. All type predicates 225 /// operate on the canonical type, ignoring typedefs. 226 bool isIntegerType() const; // C99 6.2.5p17 (int, char, bool, enum) 227 228 /// Floating point categories. 229 bool isRealFloatingType() const; // C99 6.2.5p10 (float, double, long double) 230 bool isComplexType() const; // C99 6.2.5p11 (complex) 231 bool isFloatingType() const; // C99 6.2.5p11 (real floating + complex) 232 bool isRealType() const; // C99 6.2.5p17 (real floating + integer) 233 bool isArithmeticType() const; // C99 6.2.5p18 (integer + floating) 234 235 /// Vector types 236 const VectorType *isVectorType() const; // GCC vector type. 237 const OCUVectorType *isOCUVectorType() const; // OCU vector type. 238 239 /// Derived types (C99 6.2.5p20). 240 bool isDerivedType() const; 241 const FunctionType *isFunctionType() const; 242 const PointerType *isPointerType() const; 243 const ReferenceType *isReferenceType() const; 244 const ArrayType *isArrayType() const; 245 const RecordType *isRecordType() const; 246 const TagType *isStructureType() const; 247 const TagType *isUnionType() const; 248 249 bool isVoidType() const; // C99 6.2.5p19 250 bool isScalarType() const; // C99 6.2.5p21 (arithmetic + pointers) 251 bool isAggregateType() const; // C99 6.2.5p21 (arrays, structures) 252 253 /// More type predicates useful for type checking/promotion 254 bool isPromotableIntegerType() const; // C99 6.3.1.1p2 255 256 /// isSignedIntegerType - Return true if this is an integer type that is 257 /// signed, according to C99 6.2.5p4. 258 bool isSignedIntegerType() const; 259 260 /// isUnsignedIntegerType - Return true if this is an integer type that is 261 /// unsigned, according to C99 6.2.5p6. Note that this returns true for _Bool. 262 bool isUnsignedIntegerType() const; 263 264 /// isConstantSizeType - Return true if this is not a variable sized type, 265 /// according to the rules of C99 6.7.5p3. If Loc is non-null, it is set to 266 /// the location of the subexpression that makes it a vla type. It is not 267 /// legal to call this on incomplete types. 268 bool isConstantSizeType(ASTContext &Ctx, SourceLocation *Loc = 0) const; 269 270 /// Compatibility predicates used to check assignment expressions. 271 static bool typesAreCompatible(QualType, QualType); // C99 6.2.7p1 272 static bool tagTypesAreCompatible(QualType, QualType); // C99 6.2.7p1 273 static bool pointerTypesAreCompatible(QualType, QualType); // C99 6.7.5.1p2 274 static bool referenceTypesAreCompatible(QualType, QualType); // C++ 5.17p6 275 static bool functionTypesAreCompatible(QualType, QualType); // C99 6.7.5.3p15 276 static bool arrayTypesAreCompatible(QualType, QualType); // C99 6.7.5.2p6 277private: 278 QualType getCanonicalTypeInternal() const { return CanonicalType; } 279 friend class QualType; 280public: 281 virtual void getAsStringInternal(std::string &InnerString) const = 0; 282 283 static bool classof(const Type *) { return true; } 284}; 285 286/// BuiltinType - This class is used for builtin types like 'int'. Builtin 287/// types are always canonical and have a literal name field. 288class BuiltinType : public Type { 289public: 290 enum Kind { 291 Void, 292 293 Bool, // This is bool and/or _Bool. 294 Char_U, // This is 'char' for targets where char is unsigned. 295 UChar, // This is explicitly qualified unsigned char. 296 UShort, 297 UInt, 298 ULong, 299 ULongLong, 300 301 Char_S, // This is 'char' for targets where char is signed. 302 SChar, // This is explicitly qualified signed char. 303 Short, 304 Int, 305 Long, 306 LongLong, 307 308 Float, Double, LongDouble 309 }; 310private: 311 Kind TypeKind; 312public: 313 BuiltinType(Kind K) : Type(Builtin, QualType()), TypeKind(K) {} 314 315 Kind getKind() const { return TypeKind; } 316 const char *getName() const; 317 318 virtual void getAsStringInternal(std::string &InnerString) const; 319 320 static bool classof(const Type *T) { return T->getTypeClass() == Builtin; } 321 static bool classof(const BuiltinType *) { return true; } 322}; 323 324/// ComplexType - C99 6.2.5p11 - Complex values. This supports the C99 complex 325/// types (_Complex float etc) as well as the GCC integer complex extensions. 326/// 327class ComplexType : public Type, public llvm::FoldingSetNode { 328 QualType ElementType; 329 ComplexType(QualType Element, QualType CanonicalPtr) : 330 Type(Complex, CanonicalPtr), ElementType(Element) { 331 } 332 friend class ASTContext; // ASTContext creates these. 333public: 334 QualType getElementType() const { return ElementType; } 335 336 virtual void getAsStringInternal(std::string &InnerString) const; 337 338 339 void Profile(llvm::FoldingSetNodeID &ID) { 340 Profile(ID, getElementType()); 341 } 342 static void Profile(llvm::FoldingSetNodeID &ID, QualType Element) { 343 ID.AddPointer(Element.getAsOpaquePtr()); 344 } 345 346 static bool classof(const Type *T) { return T->getTypeClass() == Complex; } 347 static bool classof(const ComplexType *) { return true; } 348}; 349 350 351/// PointerType - C99 6.7.5.1 - Pointer Declarators. 352/// 353class PointerType : public Type, public llvm::FoldingSetNode { 354 QualType PointeeType; 355 PointerType(QualType Pointee, QualType CanonicalPtr) : 356 Type(Pointer, CanonicalPtr), PointeeType(Pointee) { 357 } 358 friend class ASTContext; // ASTContext creates these. 359public: 360 361 QualType getPointeeType() const { return PointeeType; } 362 363 virtual void getAsStringInternal(std::string &InnerString) const; 364 365 366 void Profile(llvm::FoldingSetNodeID &ID) { 367 Profile(ID, getPointeeType()); 368 } 369 static void Profile(llvm::FoldingSetNodeID &ID, QualType Pointee) { 370 ID.AddPointer(Pointee.getAsOpaquePtr()); 371 } 372 373 static bool classof(const Type *T) { return T->getTypeClass() == Pointer; } 374 static bool classof(const PointerType *) { return true; } 375}; 376 377/// ReferenceType - C++ 8.3.2 - Reference Declarators. 378/// 379class ReferenceType : public Type, public llvm::FoldingSetNode { 380 QualType ReferenceeType; 381 ReferenceType(QualType Referencee, QualType CanonicalRef) : 382 Type(Reference, CanonicalRef), ReferenceeType(Referencee) { 383 } 384 friend class ASTContext; // ASTContext creates these. 385public: 386 virtual void getAsStringInternal(std::string &InnerString) const; 387 388 QualType getReferenceeType() const { return ReferenceeType; } 389 390 void Profile(llvm::FoldingSetNodeID &ID) { 391 Profile(ID, getReferenceeType()); 392 } 393 static void Profile(llvm::FoldingSetNodeID &ID, QualType Referencee) { 394 ID.AddPointer(Referencee.getAsOpaquePtr()); 395 } 396 397 static bool classof(const Type *T) { return T->getTypeClass() == Reference; } 398 static bool classof(const ReferenceType *) { return true; } 399}; 400 401/// ArrayType - C99 6.7.5.2 - Array Declarators. 402/// 403class ArrayType : public Type, public llvm::FoldingSetNode { 404public: 405 /// ArraySizeModifier - Capture whether this is a normal array (e.g. int X[4]) 406 /// an array with a static size (e.g. int X[static 4]), or with a star size 407 /// (e.g. int X[*]). 408 enum ArraySizeModifier { 409 Normal, Static, Star 410 }; 411private: 412 /// NOTE: These fields are packed into the bitfields space in the Type class. 413 ArraySizeModifier SizeModifier : 2; 414 415 /// IndexTypeQuals - Capture qualifiers in declarations like: 416 /// 'int X[static restrict 4]'. 417 unsigned IndexTypeQuals : 3; 418 419 /// ElementType - The element type of the array. 420 QualType ElementType; 421 422 /// SizeExpr - The size is either a constant or assignment expression (for 423 /// Variable Length Arrays). VLA's are only permitted within a function block. 424 Expr *SizeExpr; 425 426 ArrayType(QualType et, ArraySizeModifier sm, unsigned tq, QualType can, 427 Expr *e) 428 : Type(Array, can), SizeModifier(sm), IndexTypeQuals(tq), ElementType(et), 429 SizeExpr(e) {} 430 friend class ASTContext; // ASTContext creates these. 431public: 432 433 QualType getElementType() const { return ElementType; } 434 ArraySizeModifier getSizeModifier() const { return SizeModifier; } 435 unsigned getIndexTypeQualifier() const { return IndexTypeQuals; } 436 Expr *getSizeExpr() const { return SizeExpr; } 437 438 virtual void getAsStringInternal(std::string &InnerString) const; 439 440 void Profile(llvm::FoldingSetNodeID &ID) { 441 Profile(ID, getSizeModifier(), getIndexTypeQualifier(), getElementType(), 442 getSizeExpr()); 443 } 444 static void Profile(llvm::FoldingSetNodeID &ID, 445 ArraySizeModifier SizeModifier, 446 unsigned IndexTypeQuals, QualType ElementType, 447 Expr *SizeExpr) { 448 ID.AddInteger(SizeModifier); 449 ID.AddInteger(IndexTypeQuals); 450 ID.AddPointer(ElementType.getAsOpaquePtr()); 451 ID.AddPointer(SizeExpr); 452 } 453 454 static bool classof(const Type *T) { return T->getTypeClass() == Array; } 455 static bool classof(const ArrayType *) { return true; } 456}; 457 458/// VectorType - GCC generic vector type. This type is created using 459/// __attribute__((vector_size(n)), where "n" specifies the vector size in 460/// bytes. Since the constructor takes the number of vector elements, the 461/// client is responsible for converting the size into the number of elements. 462class VectorType : public Type, public llvm::FoldingSetNode { 463protected: 464 /// ElementType - The element type of the vector. 465 QualType ElementType; 466 467 /// NumElements - The number of elements in the vector. 468 unsigned NumElements; 469 470 VectorType(QualType vecType, unsigned nElements, QualType canonType) : 471 Type(Vector, canonType), ElementType(vecType), NumElements(nElements) {} 472 VectorType(TypeClass tc, QualType vecType, unsigned nElements, 473 QualType canonType) : Type(tc, canonType), ElementType(vecType), 474 NumElements(nElements) {} 475 friend class ASTContext; // ASTContext creates these. 476public: 477 478 QualType getElementType() const { return ElementType; } 479 unsigned getNumElements() const { return NumElements; } 480 481 virtual void getAsStringInternal(std::string &InnerString) const; 482 483 void Profile(llvm::FoldingSetNodeID &ID) { 484 Profile(ID, getElementType(), getNumElements(), getTypeClass()); 485 } 486 static void Profile(llvm::FoldingSetNodeID &ID, QualType ElementType, 487 unsigned NumElements, TypeClass TypeClass) { 488 ID.AddPointer(ElementType.getAsOpaquePtr()); 489 ID.AddInteger(NumElements); 490 ID.AddInteger(TypeClass); 491 } 492 static bool classof(const Type *T) { 493 return T->getTypeClass() == Vector || T->getTypeClass() == OCUVector; 494 } 495 static bool classof(const VectorType *) { return true; } 496}; 497 498/// OCUVectorType - Extended vector type. This type is created using 499/// __attribute__((ocu_vector_type(n)), where "n" is the number of elements. 500/// Unlike vector_size, ocu_vector_type is only allowed on typedef's. 501/// This class will enable syntactic extensions, like C++ style initializers. 502class OCUVectorType : public VectorType { 503 OCUVectorType(QualType vecType, unsigned nElements, QualType canonType) : 504 VectorType(OCUVector, vecType, nElements, canonType) {} 505 friend class ASTContext; // ASTContext creates these. 506public: 507 static bool classof(const Type *T) { 508 return T->getTypeClass() == Vector || T->getTypeClass() == OCUVector; 509 } 510 static bool classof(const VectorType *T) { 511 return T->getTypeClass() == OCUVector; 512 } 513 static bool classof(const OCUVectorType *) { return true; } 514}; 515 516/// FunctionType - C99 6.7.5.3 - Function Declarators. This is the common base 517/// class of FunctionTypeNoProto and FunctionTypeProto. 518/// 519class FunctionType : public Type { 520 /// SubClassData - This field is owned by the subclass, put here to pack 521 /// tightly with the ivars in Type. 522 bool SubClassData : 1; 523 524 // The type returned by the function. 525 QualType ResultType; 526protected: 527 FunctionType(TypeClass tc, QualType res, bool SubclassInfo,QualType Canonical) 528 : Type(tc, Canonical), SubClassData(SubclassInfo), ResultType(res) {} 529 bool getSubClassData() const { return SubClassData; } 530public: 531 532 QualType getResultType() const { return ResultType; } 533 534 535 static bool classof(const Type *T) { 536 return T->getTypeClass() == FunctionNoProto || 537 T->getTypeClass() == FunctionProto; 538 } 539 static bool classof(const FunctionType *) { return true; } 540}; 541 542/// FunctionTypeNoProto - Represents a K&R-style 'int foo()' function, which has 543/// no information available about its arguments. 544class FunctionTypeNoProto : public FunctionType, public llvm::FoldingSetNode { 545 FunctionTypeNoProto(QualType Result, QualType Canonical) 546 : FunctionType(FunctionNoProto, Result, false, Canonical) {} 547 friend class ASTContext; // ASTContext creates these. 548public: 549 // No additional state past what FunctionType provides. 550 551 virtual void getAsStringInternal(std::string &InnerString) const; 552 553 void Profile(llvm::FoldingSetNodeID &ID) { 554 Profile(ID, getResultType()); 555 } 556 static void Profile(llvm::FoldingSetNodeID &ID, QualType ResultType) { 557 ID.AddPointer(ResultType.getAsOpaquePtr()); 558 } 559 560 static bool classof(const Type *T) { 561 return T->getTypeClass() == FunctionNoProto; 562 } 563 static bool classof(const FunctionTypeNoProto *) { return true; } 564}; 565 566/// FunctionTypeProto - Represents a prototype with argument type info, e.g. 567/// 'int foo(int)' or 'int foo(void)'. 'void' is represented as having no 568/// arguments, not as having a single void argument. 569class FunctionTypeProto : public FunctionType, public llvm::FoldingSetNode { 570 FunctionTypeProto(QualType Result, QualType *ArgArray, unsigned numArgs, 571 bool isVariadic, QualType Canonical) 572 : FunctionType(FunctionProto, Result, isVariadic, Canonical), 573 NumArgs(numArgs) { 574 // Fill in the trailing argument array. 575 QualType *ArgInfo = reinterpret_cast<QualType *>(this+1);; 576 for (unsigned i = 0; i != numArgs; ++i) 577 ArgInfo[i] = ArgArray[i]; 578 } 579 580 /// NumArgs - The number of arguments this function has, not counting '...'. 581 unsigned NumArgs; 582 583 /// ArgInfo - There is an variable size array after the class in memory that 584 /// holds the argument types. 585 friend class ASTContext; // ASTContext creates these. 586public: 587 unsigned getNumArgs() const { return NumArgs; } 588 QualType getArgType(unsigned i) const { 589 assert(i < NumArgs && "Invalid argument number!"); 590 return arg_type_begin()[i]; 591 } 592 593 bool isVariadic() const { return getSubClassData(); } 594 595 typedef const QualType *arg_type_iterator; 596 arg_type_iterator arg_type_begin() const { 597 return reinterpret_cast<const QualType *>(this+1); 598 } 599 arg_type_iterator arg_type_end() const { return arg_type_begin()+NumArgs; } 600 601 virtual void getAsStringInternal(std::string &InnerString) const; 602 603 static bool classof(const Type *T) { 604 return T->getTypeClass() == FunctionProto; 605 } 606 static bool classof(const FunctionTypeProto *) { return true; } 607 608 void Profile(llvm::FoldingSetNodeID &ID); 609 static void Profile(llvm::FoldingSetNodeID &ID, QualType Result, 610 arg_type_iterator ArgTys, unsigned NumArgs, 611 bool isVariadic); 612}; 613 614 615class TypedefType : public Type { 616 TypedefDecl *Decl; 617 TypedefType(TypedefDecl *D, QualType can) : Type(TypeName, can), Decl(D) { 618 assert(!isa<TypedefType>(can) && "Invalid canonical type"); 619 } 620 friend class ASTContext; // ASTContext creates these. 621public: 622 623 TypedefDecl *getDecl() const { return Decl; } 624 625 /// LookThroughTypedefs - Return the ultimate type this typedef corresponds to 626 /// potentially looking through *all* consequtive typedefs. This returns the 627 /// sum of the type qualifiers, so if you have: 628 /// typedef const int A; 629 /// typedef volatile A B; 630 /// looking through the typedefs for B will give you "const volatile A". 631 QualType LookThroughTypedefs() const; 632 633 virtual void getAsStringInternal(std::string &InnerString) const; 634 635 static bool classof(const Type *T) { return T->getTypeClass() == TypeName; } 636 static bool classof(const TypedefType *) { return true; } 637}; 638 639 640class TagType : public Type { 641 TagDecl *Decl; 642 TagType(TagDecl *D, QualType can) : Type(Tagged, can), Decl(D) {} 643 friend class ASTContext; // ASTContext creates these. 644public: 645 646 TagDecl *getDecl() const { return Decl; } 647 648 virtual void getAsStringInternal(std::string &InnerString) const; 649 650 static bool classof(const Type *T) { return T->getTypeClass() == Tagged; } 651 static bool classof(const TagType *) { return true; } 652}; 653 654/// RecordType - This is a helper class that allows the use of isa/cast/dyncast 655/// to detect TagType objects of structs/unions/classes. 656class RecordType : public TagType { 657 RecordType(); // DO NOT IMPLEMENT 658public: 659 660 const RecordDecl *getDecl() { 661 return reinterpret_cast<RecordDecl*>(TagType::getDecl()); 662 } 663 RecordDecl *getDecl() const { 664 return reinterpret_cast<RecordDecl*>(TagType::getDecl()); 665 } 666 667 // FIXME: This predicate is a helper to QualType/Type. It needs to 668 // recursively check all fields for const-ness. If any field is declared 669 // const, it needs to return false. 670 bool hasConstFields() const { return false; } 671 672 static bool classof(const Type *T); 673 static bool classof(const RecordType *) { return true; } 674}; 675 676 677/// ... 678 679// TODO: When we support C++, we should have types for uses of template with 680// default parameters. We should be able to distinguish source use of 681// 'std::vector<int>' from 'std::vector<int, std::allocator<int> >'. Though they 682// specify the same type, we want to print the default argument only if 683// specified in the source code. 684 685/// getCanonicalType - Return the canonical version of this type, with the 686/// appropriate type qualifiers on it. 687inline QualType QualType::getCanonicalType() const { 688 return QualType(getTypePtr()->getCanonicalTypeInternal().getTypePtr(), 689 getQualifiers() | 690 getTypePtr()->getCanonicalTypeInternal().getQualifiers()); 691} 692 693} // end namespace clang 694 695#endif 696