diff options
Diffstat (limited to 'lib/AST/Type.cpp')
-rw-r--r-- | lib/AST/Type.cpp | 157 |
1 files changed, 80 insertions, 77 deletions
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp index d7929304..ca10532 100644 --- a/lib/AST/Type.cpp +++ b/lib/AST/Type.cpp @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// #include "clang/AST/ASTContext.h" +#include "clang/AST/CharUnits.h" #include "clang/AST/Type.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclObjC.h" @@ -21,6 +22,7 @@ #include "clang/Basic/Specifiers.h" #include "llvm/ADT/StringExtras.h" #include "llvm/Support/raw_ostream.h" +#include <algorithm> using namespace clang; bool QualType::isConstant(QualType T, ASTContext &Ctx) { @@ -33,24 +35,32 @@ bool QualType::isConstant(QualType T, ASTContext &Ctx) { return false; } -void Type::Destroy(ASTContext& C) { - this->~Type(); - C.Deallocate(this); -} +Type::~Type() { } + +unsigned ConstantArrayType::getNumAddressingBits(ASTContext &Context, + QualType ElementType, + const llvm::APInt &NumElements) { + llvm::APSInt SizeExtended(NumElements, true); + unsigned SizeTypeBits = Context.getTypeSize(Context.getSizeType()); + SizeExtended.extend(std::max(SizeTypeBits, SizeExtended.getBitWidth()) * 2); -void VariableArrayType::Destroy(ASTContext& C) { - if (SizeExpr) - SizeExpr->Destroy(C); - this->~VariableArrayType(); - C.Deallocate(this); + uint64_t ElementSize + = Context.getTypeSizeInChars(ElementType).getQuantity(); + llvm::APSInt TotalSize(llvm::APInt(SizeExtended.getBitWidth(), ElementSize)); + TotalSize *= SizeExtended; + + return TotalSize.getActiveBits(); } -void DependentSizedArrayType::Destroy(ASTContext& C) { - // FIXME: Resource contention like in ConstantArrayWithExprType ? - // May crash, depending on platform or a particular build. - // SizeExpr->Destroy(C); - this->~DependentSizedArrayType(); - C.Deallocate(this); +unsigned ConstantArrayType::getMaxSizeBits(ASTContext &Context) { + unsigned Bits = Context.getTypeSize(Context.getSizeType()); + + // GCC appears to only allow 63 bits worth of address space when compiling + // for 64-bit, so we do the same. + if (Bits == 64) + --Bits; + + return Bits; } void DependentSizedArrayType::Profile(llvm::FoldingSetNodeID &ID, @@ -73,14 +83,6 @@ DependentSizedExtVectorType::Profile(llvm::FoldingSetNodeID &ID, SizeExpr->Profile(ID, Context, true); } -void DependentSizedExtVectorType::Destroy(ASTContext& C) { - // FIXME: Deallocate size expression, once we're cloning properly. -// if (SizeExpr) -// SizeExpr->Destroy(C); - this->~DependentSizedExtVectorType(); - C.Deallocate(this); -} - /// getArrayElementTypeNoTypeQual - If this is an array type, return the /// element type of the array, potentially with type qualifiers missing. /// This method should never be used when type qualifiers are meaningful. @@ -192,13 +194,6 @@ bool Type::isVoidType() const { return false; } -bool Type::isObjectType() const { - if (isa<FunctionType>(CanonicalType) || isa<ReferenceType>(CanonicalType) || - isa<IncompleteArrayType>(CanonicalType) || isVoidType()) - return false; - return true; -} - bool Type::isDerivedType() const { switch (CanonicalType->getTypeClass()) { case Pointer: @@ -348,11 +343,6 @@ const RecordType *Type::getAsUnionType() const { return 0; } -void ObjCInterfaceType::Destroy(ASTContext& C) { - this->~ObjCInterfaceType(); - C.Deallocate(this); -} - ObjCObjectType::ObjCObjectType(QualType Canonical, QualType Base, ObjCProtocolDecl * const *Protocols, unsigned NumProtocols) @@ -366,11 +356,6 @@ ObjCObjectType::ObjCObjectType(QualType Canonical, QualType Base, NumProtocols * sizeof(ObjCProtocolDecl*)); } -void ObjCObjectTypeImpl::Destroy(ASTContext& C) { - this->~ObjCObjectTypeImpl(); - C.Deallocate(this); -} - const ObjCObjectType *Type::getAsObjCQualifiedInterfaceType() const { // There is no sugar for ObjCObjectType's, just return the canonical // type pointer if it is the right class. There is no typedef information to @@ -385,11 +370,6 @@ bool Type::isObjCQualifiedInterfaceType() const { return getAsObjCQualifiedInterfaceType() != 0; } -void ObjCObjectPointerType::Destroy(ASTContext& C) { - this->~ObjCObjectPointerType(); - C.Deallocate(this); -} - const ObjCObjectPointerType *Type::getAsObjCQualifiedIdType() const { // There is no sugar for ObjCQualifiedIdType's, just return the canonical // type pointer if it is the right class. @@ -434,9 +414,14 @@ bool Type::isIntegerType() const { // FIXME: In C++, enum types are never integer types. if (TT->getDecl()->isEnum() && TT->getDecl()->isDefinition()) return true; + return false; +} + +bool Type::hasIntegerRepresentation() const { if (const VectorType *VT = dyn_cast<VectorType>(CanonicalType)) return VT->getElementType()->isIntegerType(); - return false; + else + return isIntegerType(); } /// \brief Determine whether this type is an integral type. @@ -475,10 +460,13 @@ bool Type::isIntegralOrEnumerationType() const { if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType)) return BT->getKind() >= BuiltinType::Bool && BT->getKind() <= BuiltinType::Int128; - - if (isa<EnumType>(CanonicalType)) - return true; - + + // Check for a complete enum type; incomplete enum types are not properly an + // enumeration type in the sense required here. + if (const TagType *TT = dyn_cast<TagType>(CanonicalType)) + if (TT->getDecl()->isEnum() && TT->getDecl()->isDefinition()) + return true; + return false; } @@ -523,8 +511,7 @@ bool Type::isAnyCharacterType() const { /// isSignedIntegerType - Return true if this is an integer type that is /// signed, according to C99 6.2.5p4 [char, signed char, short, int, long..], -/// an enum decl which has a signed representation, or a vector of signed -/// integer element type. +/// an enum decl which has a signed representation bool Type::isSignedIntegerType() const { if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType)) { return BT->getKind() >= BuiltinType::Char_S && @@ -534,15 +521,19 @@ bool Type::isSignedIntegerType() const { if (const EnumType *ET = dyn_cast<EnumType>(CanonicalType)) return ET->getDecl()->getIntegerType()->isSignedIntegerType(); + return false; +} + +bool Type::hasSignedIntegerRepresentation() const { if (const VectorType *VT = dyn_cast<VectorType>(CanonicalType)) return VT->getElementType()->isSignedIntegerType(); - return false; + else + return isSignedIntegerType(); } /// isUnsignedIntegerType - Return true if this is an integer type that is /// unsigned, according to C99 6.2.5p6 [which returns true for _Bool], an enum -/// decl which has an unsigned representation, or a vector of unsigned integer -/// element type. +/// decl which has an unsigned representation bool Type::isUnsignedIntegerType() const { if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType)) { return BT->getKind() >= BuiltinType::Bool && @@ -552,9 +543,14 @@ bool Type::isUnsignedIntegerType() const { if (const EnumType *ET = dyn_cast<EnumType>(CanonicalType)) return ET->getDecl()->getIntegerType()->isUnsignedIntegerType(); + return false; +} + +bool Type::hasUnsignedIntegerRepresentation() const { if (const VectorType *VT = dyn_cast<VectorType>(CanonicalType)) return VT->getElementType()->isUnsignedIntegerType(); - return false; + else + return isUnsignedIntegerType(); } bool Type::isFloatingType() const { @@ -671,10 +667,11 @@ bool Type::isIncompleteType() const { // An array of unknown size is an incomplete type (C99 6.2.5p22). return true; case ObjCObject: - return cast<ObjCObjectType>(this)->getBaseType()->isIncompleteType(); + return cast<ObjCObjectType>(CanonicalType)->getBaseType() + ->isIncompleteType(); case ObjCInterface: // ObjC interfaces are incomplete if they are @class, not @interface. - return cast<ObjCInterfaceType>(this)->getDecl()->isForwardDecl(); + return cast<ObjCInterfaceType>(CanonicalType)->getDecl()->isForwardDecl(); } } @@ -894,15 +891,6 @@ ElaboratedType::~ElaboratedType() {} DependentNameType::~DependentNameType() {} DependentTemplateSpecializationType::~DependentTemplateSpecializationType() {} -void DependentTemplateSpecializationType::Destroy(ASTContext &C) { - for (unsigned Arg = 0; Arg < NumArgs; ++Arg) { - // FIXME: Not all expressions get cloned, so we can't yet perform - // this destruction. - // if (Expr *E = getArg(Arg).getAsExpr()) - // E->Destroy(C); - } -} - DependentTemplateSpecializationType::DependentTemplateSpecializationType( ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS, const IdentifierInfo *Name, @@ -1017,6 +1005,7 @@ llvm::StringRef FunctionType::getNameForCallConv(CallingConv CC) { case CC_X86StdCall: return "stdcall"; case CC_X86FastCall: return "fastcall"; case CC_X86ThisCall: return "thiscall"; + case CC_X86Pascal: return "pascal"; } } @@ -1108,7 +1097,30 @@ void DependentDecltypeType::Profile(llvm::FoldingSetNodeID &ID, TagType::TagType(TypeClass TC, const TagDecl *D, QualType can) : Type(TC, can, D->isDependentType()), - decl(const_cast<TagDecl*>(D), 0) {} + decl(const_cast<TagDecl*>(D)) {} + +static TagDecl *getInterestingTagDecl(TagDecl *decl) { + for (TagDecl::redecl_iterator I = decl->redecls_begin(), + E = decl->redecls_end(); + I != E; ++I) { + if (I->isDefinition() || I->isBeingDefined()) + return *I; + } + // If there's no definition (not even in progress), return what we have. + return decl; +} + +TagDecl *TagType::getDecl() const { + return getInterestingTagDecl(decl); +} + +bool TagType::isBeingDefined() const { + return getDecl()->isBeingDefined(); +} + +CXXRecordDecl *InjectedClassNameType::getDecl() const { + return cast<CXXRecordDecl>(getInterestingTagDecl(Decl)); +} bool RecordType::classof(const TagType *TT) { return isa<RecordDecl>(TT->getDecl()); @@ -1196,15 +1208,6 @@ TemplateSpecializationType(TemplateName T, new (&TemplateArgs[Arg]) TemplateArgument(Args[Arg]); } -void TemplateSpecializationType::Destroy(ASTContext& C) { - for (unsigned Arg = 0; Arg < NumArgs; ++Arg) { - // FIXME: Not all expressions get cloned, so we can't yet perform - // this destruction. - // if (Expr *E = getArg(Arg).getAsExpr()) - // E->Destroy(C); - } -} - void TemplateSpecializationType::Profile(llvm::FoldingSetNodeID &ID, TemplateName T, |