diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2012-12-02 13:20:44 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2012-12-02 13:20:44 +0000 |
commit | 13cc256e404620c1de0cbcc4e43ce1e2dbbc4898 (patch) | |
tree | 2732d02d7d51218d6eed98ac7fcfc5b8794896b5 /lib/AST/Type.cpp | |
parent | 657bc3d9848e3be92029b2416031340988cd0111 (diff) | |
download | src-13cc256e404620c1de0cbcc4e43ce1e2dbbc4898.tar.gz src-13cc256e404620c1de0cbcc4e43ce1e2dbbc4898.zip |
Notes
Diffstat (limited to 'lib/AST/Type.cpp')
-rw-r--r-- | lib/AST/Type.cpp | 55 |
1 files changed, 41 insertions, 14 deletions
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp index abefae44b2ba..580ec50ca1f8 100644 --- a/lib/AST/Type.cpp +++ b/lib/AST/Type.cpp @@ -288,18 +288,17 @@ QualType QualType::IgnoreParens(QualType T) { return T; } -/// \brief This will check for a TypedefType by removing any existing sugar -/// until it reaches a TypedefType or a non-sugared type. -template <> const TypedefType *Type::getAs() const { - const Type *Cur = this; - +/// \brief This will check for a T (which should be a Type which can act as +/// sugar, such as a TypedefType) by removing any existing sugar until it +/// reaches a T or a non-sugared type. +template<typename T> static const T *getAsSugar(const Type *Cur) { while (true) { - if (const TypedefType *TDT = dyn_cast<TypedefType>(Cur)) - return TDT; + if (const T *Sugar = dyn_cast<T>(Cur)) + return Sugar; switch (Cur->getTypeClass()) { #define ABSTRACT_TYPE(Class, Parent) #define TYPE(Class, Parent) \ - case Class: { \ + case Type::Class: { \ const Class##Type *Ty = cast<Class##Type>(Cur); \ if (!Ty->isSugared()) return 0; \ Cur = Ty->desugar().getTypePtr(); \ @@ -310,6 +309,14 @@ template <> const TypedefType *Type::getAs() const { } } +template <> const TypedefType *Type::getAs() const { + return getAsSugar<TypedefType>(this); +} + +template <> const TemplateSpecializationType *Type::getAs() const { + return getAsSugar<TemplateSpecializationType>(this); +} + /// getUnqualifiedDesugaredType - Pull any qualifiers and syntactic /// sugar off the given type. This should produce an object of the /// same dynamic type as the canonical type. @@ -357,9 +364,15 @@ bool Type::isStructureType() const { return RT->getDecl()->isStruct(); return false; } +bool Type::isInterfaceType() const { + if (const RecordType *RT = getAs<RecordType>()) + return RT->getDecl()->isInterface(); + return false; +} bool Type::isStructureOrClassType() const { if (const RecordType *RT = getAs<RecordType>()) - return RT->getDecl()->isStruct() || RT->getDecl()->isClass(); + return RT->getDecl()->isStruct() || RT->getDecl()->isClass() || + RT->getDecl()->isInterface(); return false; } bool Type::isVoidPointerType() const { @@ -499,10 +512,18 @@ const ObjCObjectPointerType *Type::getAsObjCInterfacePointerType() const { return 0; } -const CXXRecordDecl *Type::getCXXRecordDeclForPointerType() const { +const CXXRecordDecl *Type::getPointeeCXXRecordDecl() const { + QualType PointeeType; if (const PointerType *PT = getAs<PointerType>()) - if (const RecordType *RT = PT->getPointeeType()->getAs<RecordType>()) - return dyn_cast<CXXRecordDecl>(RT->getDecl()); + PointeeType = PT->getPointeeType(); + else if (const ReferenceType *RT = getAs<ReferenceType>()) + PointeeType = RT->getPointeeType(); + else + return 0; + + if (const RecordType *RT = PointeeType->getAs<RecordType>()) + return dyn_cast<CXXRecordDecl>(RT->getDecl()); + return 0; } @@ -1205,8 +1226,6 @@ bool QualType::isCXX11PODType(ASTContext &Context) const { return false; case Qualifiers::OCL_None: - if (ty->isObjCLifetimeType()) - return false; break; } } @@ -1317,6 +1336,7 @@ TypeWithKeyword::getKeywordForTypeSpec(unsigned TypeSpec) { case TST_typename: return ETK_Typename; case TST_class: return ETK_Class; case TST_struct: return ETK_Struct; + case TST_interface: return ETK_Interface; case TST_union: return ETK_Union; case TST_enum: return ETK_Enum; } @@ -1327,6 +1347,7 @@ TypeWithKeyword::getTagTypeKindForTypeSpec(unsigned TypeSpec) { switch(TypeSpec) { case TST_class: return TTK_Class; case TST_struct: return TTK_Struct; + case TST_interface: return TTK_Interface; case TST_union: return TTK_Union; case TST_enum: return TTK_Enum; } @@ -1339,6 +1360,7 @@ TypeWithKeyword::getKeywordForTagTypeKind(TagTypeKind Kind) { switch (Kind) { case TTK_Class: return ETK_Class; case TTK_Struct: return ETK_Struct; + case TTK_Interface: return ETK_Interface; case TTK_Union: return ETK_Union; case TTK_Enum: return ETK_Enum; } @@ -1350,6 +1372,7 @@ TypeWithKeyword::getTagTypeKindForKeyword(ElaboratedTypeKeyword Keyword) { switch (Keyword) { case ETK_Class: return TTK_Class; case ETK_Struct: return TTK_Struct; + case ETK_Interface: return TTK_Interface; case ETK_Union: return TTK_Union; case ETK_Enum: return TTK_Enum; case ETK_None: // Fall through. @@ -1367,6 +1390,7 @@ TypeWithKeyword::KeywordIsTagTypeKind(ElaboratedTypeKeyword Keyword) { return false; case ETK_Class: case ETK_Struct: + case ETK_Interface: case ETK_Union: case ETK_Enum: return true; @@ -1381,6 +1405,7 @@ TypeWithKeyword::getKeywordName(ElaboratedTypeKeyword Keyword) { case ETK_Typename: return "typename"; case ETK_Class: return "class"; case ETK_Struct: return "struct"; + case ETK_Interface: return "__interface"; case ETK_Union: return "union"; case ETK_Enum: return "enum"; } @@ -1480,6 +1505,7 @@ StringRef BuiltinType::getName(const PrintingPolicy &Policy) const { case Dependent: return "<dependent type>"; case UnknownAny: return "<unknown type>"; case ARCUnbridgedCast: return "<ARC unbridged cast type>"; + case BuiltinFn: return "<builtin fn type>"; case ObjCId: return "id"; case ObjCClass: return "Class"; case ObjCSel: return "SEL"; @@ -1516,6 +1542,7 @@ StringRef FunctionType::getNameForCallConv(CallingConv CC) { case CC_X86Pascal: return "pascal"; case CC_AAPCS: return "aapcs"; case CC_AAPCS_VFP: return "aapcs-vfp"; + case CC_PnaclCall: return "pnaclcall"; } llvm_unreachable("Invalid calling convention."); |