From: Chris Lattner Date: Wed, 20 Feb 2008 20:55:12 +0000 (+0000) Subject: Alternate address spaces work: X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f46699ce225811d8d9dbab9d00189a0e54469457;p=clang Alternate address spaces work: rename QualType::getQualifiers to getCVRQualifiers. Add some fixme's and clean up some code relevant to qualifiers. Change ASQualType to contain a Type* instead of a QualType. Any CVR qualifiers should be on the outer qual type. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@47398 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/AST/ASTContext.cpp b/AST/ASTContext.cpp index bd7215dd4a..a636e8d8bb 100644 --- a/AST/ASTContext.cpp +++ b/AST/ASTContext.cpp @@ -257,7 +257,7 @@ ASTContext::getTypeInfo(QualType T, SourceLocation L) { break; } case Type::ASQual: - return getTypeInfo(cast(T)->getBaseType(), L); + return getTypeInfo(QualType(cast(T)->getBaseType(), 0), L); case Type::ObjCQualifiedId: Target.getPointerInfo(Size, Align, getFullLoc(L)); break; @@ -436,9 +436,18 @@ const ASTRecordLayout &ASTContext::getASTRecordLayout(const RecordDecl *D, //===----------------------------------------------------------------------===// QualType ASTContext::getASQualType(QualType T, unsigned AddressSpace) { - // Check if we've already instantiated an address space qual'd type of this type. + if (T.getCanonicalType().getAddressSpace() == AddressSpace) + return T; + + // Type's cannot have multiple ASQuals, therefore we know we only have to deal + // with CVR qualifiers from here on out. + assert(T.getCanonicalType().getAddressSpace() == 0 && + "Type is already address space qualified"); + + // Check if we've already instantiated an address space qual'd type of this + // type. llvm::FoldingSetNodeID ID; - ASQualType::Profile(ID, T, AddressSpace); + ASQualType::Profile(ID, T.getTypePtr(), AddressSpace); void *InsertPos = 0; if (ASQualType *ASQy = ASQualTypes.FindNodeOrInsertPos(ID, InsertPos)) return QualType(ASQy, 0); @@ -453,10 +462,10 @@ QualType ASTContext::getASQualType(QualType T, unsigned AddressSpace) { ASQualType *NewIP = ASQualTypes.FindNodeOrInsertPos(ID, InsertPos); assert(NewIP == 0 && "Shouldn't be in the map!"); } - ASQualType *New = new ASQualType(T, Canonical, AddressSpace); + ASQualType *New = new ASQualType(T.getTypePtr(), Canonical, AddressSpace); ASQualTypes.InsertNode(New, InsertPos); Types.push_back(New); - return QualType(New, 0); + return QualType(New, T.getCVRQualifiers()); } @@ -1621,7 +1630,8 @@ bool ASTContext::tagTypesAreCompatible(QualType lhs, QualType rhs) { bool ASTContext::pointerTypesAreCompatible(QualType lhs, QualType rhs) { // C99 6.7.5.1p2: For two pointer types to be compatible, both shall be // identically qualified and both shall be pointers to compatible types. - if (lhs.getQualifiers() != rhs.getQualifiers()) + if (lhs.getCVRQualifiers() != rhs.getCVRQualifiers() || + lhs.getAddressSpace() != rhs.getAddressSpace()) return false; QualType ltype = cast(lhs.getCanonicalType())->getPointeeType(); @@ -1713,7 +1723,8 @@ bool ASTContext::arrayTypesAreCompatible(QualType lhs, QualType rhs) { /// C99 6.2.7p1: Two types have compatible types if their types are the /// same. See 6.7.[2,3,5] for additional rules. bool ASTContext::typesAreCompatible(QualType lhs, QualType rhs) { - if (lhs.getQualifiers() != rhs.getQualifiers()) + if (lhs.getCVRQualifiers() != rhs.getCVRQualifiers() || + lhs.getAddressSpace() != rhs.getAddressSpace()) return false; QualType lcanon = lhs.getCanonicalType(); diff --git a/AST/Expr.cpp b/AST/Expr.cpp index 27dfa78273..7a9a78eb06 100644 --- a/AST/Expr.cpp +++ b/AST/Expr.cpp @@ -358,7 +358,7 @@ Expr::isLvalueResult Expr::isLvalue() const { return LV_NotObjectType; // Allow qualified void which is an incomplete type other than void (yuck). - if (TR->isVoidType() && !TR.getCanonicalType().getQualifiers()) + if (TR->isVoidType() && !TR.getCanonicalType().getCVRQualifiers()) return LV_IncompleteVoidType; if (TR->isReferenceType()) // C++ [expr] @@ -1000,7 +1000,8 @@ bool Expr::isNullPointerConstant(ASTContext &Ctx) const { // Check that it is a cast to void*. if (const PointerType *PT = CE->getType()->getAsPointerType()) { QualType Pointee = PT->getPointeeType(); - if (Pointee.getQualifiers() == 0 && Pointee->isVoidType() && // to void* + if (Pointee.getCVRQualifiers() == 0 && + Pointee->isVoidType() && // to void* CE->getSubExpr()->getType()->isIntegerType()) // from int. return CE->getSubExpr()->isNullPointerConstant(Ctx); } diff --git a/AST/Type.cpp b/AST/Type.cpp index 7e72d82bc2..f5f7f3d82c 100644 --- a/AST/Type.cpp +++ b/AST/Type.cpp @@ -709,7 +709,12 @@ QualType TypedefType::LookThroughTypedefs() const { const TypedefType *TDT = this; while (1) { QualType CurType = TDT->getDecl()->getUnderlyingType(); - TypeQuals |= CurType.getQualifiers(); + + + /// FIXME: + /// FIXME: This is incorrect for ASQuals! + /// FIXME: + TypeQuals |= CurType.getCVRQualifiers(); TDT = dyn_cast(CurType); if (TDT == 0) @@ -755,8 +760,7 @@ void QualType::getAsStringInternal(std::string &S) const { } // Print qualifiers as appropriate. - unsigned TQ = getQualifiers(); - if (TQ) { + if (unsigned TQ = getCVRQualifiers()) { std::string TQS; AppendTypeQualList(TQS, TQ); if (!S.empty()) diff --git a/AST/TypeSerialization.cpp b/AST/TypeSerialization.cpp index e2ccd3c55e..e1e8ef095e 100644 --- a/AST/TypeSerialization.cpp +++ b/AST/TypeSerialization.cpp @@ -25,7 +25,7 @@ using llvm::SerializedPtrID; void QualType::Emit(Serializer& S) const { S.EmitPtr(getTypePtr()); - S.EmitInt(getQualifiers()); + S.EmitInt(getCVRQualifiers()); } QualType QualType::ReadVal(Deserializer& D) { @@ -118,7 +118,7 @@ void Type::Create(ASTContext& Context, unsigned i, Deserializer& D) { //===----------------------------------------------------------------------===// void ASQualType::EmitImpl(Serializer& S) const { - S.Emit(getBaseType()); + S.EmitPtr(getBaseType()); S.EmitInt(getAddressSpace()); } diff --git a/CodeGen/CodeGenTypes.cpp b/CodeGen/CodeGenTypes.cpp index 96bccfc6ec..2037cfdca6 100644 --- a/CodeGen/CodeGenTypes.cpp +++ b/CodeGen/CodeGenTypes.cpp @@ -263,7 +263,7 @@ const llvm::Type *CodeGenTypes::ConvertNewType(QualType T) { } case Type::ASQual: - return ConvertType(cast(Ty).getBaseType()); + return ConvertType(QualType(cast(Ty).getBaseType(), 0)); case Type::ObjCInterface: assert(0 && "FIXME: add missing functionality here"); diff --git a/Sema/SemaDecl.cpp b/Sema/SemaDecl.cpp index 9a19928ce7..9ca5f2be22 100644 --- a/Sema/SemaDecl.cpp +++ b/Sema/SemaDecl.cpp @@ -1042,7 +1042,7 @@ Sema::DeclTy *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Declarator &D) { // Check for C99 6.7.5.3p10 - foo(void) is a non-varargs function that takes // no arguments, not a function that takes a single void argument. if (FTI.NumArgs == 1 && !FTI.isVariadic && FTI.ArgInfo[0].Ident == 0 && - !QualType::getFromOpaquePtr(FTI.ArgInfo[0].TypeInfo).getQualifiers() && + !QualType::getFromOpaquePtr(FTI.ArgInfo[0].TypeInfo).getCVRQualifiers() && QualType::getFromOpaquePtr(FTI.ArgInfo[0].TypeInfo)->isVoidType()) { // empty arg list, don't push any params. } else { @@ -1773,7 +1773,7 @@ void Sema::HandleDeclAttribute(Decl *New, AttributeList *rawAttr) { } else if (ValueDecl *vDecl = dyn_cast(New)) { QualType newType = HandleAddressSpaceTypeAttribute(vDecl->getType(), rawAttr); - if (!newType.isNull()) // install the new addr spaced type into the decl + if (!newType.isNull()) // install the new addr spaced type into the decl vDecl->setType(newType); } } else if (attrLen == 7 && !memcmp(attrName, "aligned", 7)) @@ -1798,7 +1798,7 @@ void Sema::HandleDeclAttributes(Decl *New, AttributeList *declspec_prefix, QualType Sema::HandleAddressSpaceTypeAttribute(QualType curType, AttributeList *rawAttr) { - // check the attribute arugments. + // check the attribute arguments. if (rawAttr->getNumArgs() != 1) { Diag(rawAttr->getAttributeLoc(), diag::err_attribute_wrong_number_arguments, std::string("1")); @@ -1820,7 +1820,6 @@ QualType Sema::HandleAddressSpaceTypeAttribute(QualType curType, // TODO: Should we convert contained types of address space // qualified types here or or where they directly participate in conversions // (i.e. elsewhere) - return Context.getASQualType(curType, addressSpace); } diff --git a/Sema/SemaExpr.cpp b/Sema/SemaExpr.cpp index 31cdc5947f..3d60866c01 100644 --- a/Sema/SemaExpr.cpp +++ b/Sema/SemaExpr.cpp @@ -541,7 +541,7 @@ ActOnMemberReferenceExpr(ExprTy *Base, SourceLocation OpLoc, // FIXME: Handle address space modifiers QualType MemberType = MemberDecl->getType(); unsigned combinedQualifiers = - MemberType.getQualifiers() | BaseType.getQualifiers(); + MemberType.getCVRQualifiers() | BaseType.getCVRQualifiers(); MemberType = MemberType.getQualifiedType(combinedQualifiers); return new MemberExpr(BaseExpr, OpKind==tok::arrow, MemberDecl, @@ -826,8 +826,8 @@ inline QualType Sema::CheckConditionalOperands( // C99 6.5.15 // ignore qualifiers on void (C99 6.5.15p3, clause 6) if (lhptee->isVoidType() && (rhptee->isObjectType() || rhptee->isIncompleteType())) { - // figure out necessary qualifiers (C99 6.5.15p6) - QualType destPointee = lhptee.getQualifiedType(rhptee.getQualifiers()); + // Figure out necessary qualifiers (C99 6.5.15p6) + QualType destPointee=lhptee.getQualifiedType(rhptee.getCVRQualifiers()); QualType destType = Context.getPointerType(destPointee); ImpCastExprToType(lex, destType); // add qualifiers if necessary ImpCastExprToType(rex, destType); // promote to void* @@ -835,7 +835,7 @@ inline QualType Sema::CheckConditionalOperands( // C99 6.5.15 } if (rhptee->isVoidType() && (lhptee->isObjectType() || lhptee->isIncompleteType())) { - QualType destPointee = rhptee.getQualifiedType(lhptee.getQualifiers()); + QualType destPointee=rhptee.getQualifiedType(lhptee.getCVRQualifiers()); QualType destType = Context.getPointerType(destPointee); ImpCastExprToType(lex, destType); // add qualifiers if necessary ImpCastExprToType(rex, destType); // promote to void* @@ -928,7 +928,8 @@ void Sema::DefaultFunctionArrayConversion(Expr *&e) { // b[4] = 1; // } QualType ELT = ary->getElementType(); - ELT = ELT.getQualifiedType(t.getQualifiers()|ELT.getQualifiers()); + // FIXME: Handle ASQualType + ELT = ELT.getQualifiedType(t.getCVRQualifiers()|ELT.getCVRQualifiers()); ImpCastExprToType(e, Context.getPointerType(ELT)); } } @@ -1114,8 +1115,9 @@ Sema::CheckPointerTypesForAssignment(QualType lhsType, QualType rhsType) { // C99 6.5.16.1p1: This following citation is common to constraints // 3 & 4 (below). ...and the type *pointed to* by the left has all the // qualifiers of the type *pointed to* by the right; - if ((lhptee.getQualifiers() & rhptee.getQualifiers()) != - rhptee.getQualifiers()) + // FIXME: Handle ASQualType + if ((lhptee.getCVRQualifiers() & rhptee.getCVRQualifiers()) != + rhptee.getCVRQualifiers()) ConvTy = CompatiblePointerDiscardsQualifiers; // C99 6.5.16.1p1 (constraint 4): If one operand is a pointer to an object or diff --git a/Sema/SemaType.cpp b/Sema/SemaType.cpp index 58d7019e6d..dd9ebd87c1 100644 --- a/Sema/SemaType.cpp +++ b/Sema/SemaType.cpp @@ -328,7 +328,7 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S) { FTI.ArgInfo[i].TypeInfo = ArgTy.getAsOpaquePtr(); } else { // Reject, but continue to parse 'float(const void)'. - if (ArgTy.getQualifiers()) + if (ArgTy.getCVRQualifiers()) Diag(DeclType.Loc, diag::err_void_param_qualified); // Do not add 'void' to the ArgTys list. diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h index 40e1f72bb6..1c98cb59a1 100644 --- a/include/clang/AST/ASTContext.h +++ b/include/clang/AST/ASTContext.h @@ -121,8 +121,10 @@ public: // Type Constructors //===--------------------------------------------------------------------===// - /// getAddrSpaceQualType - Return the uniqued reference to the type for an - /// address space qualified type with the specified type and address space. + /// getASQualType - Return the uniqued reference to the type for an address + /// space qualified type with the specified type and address space. The + /// resulting type has a union of the qualifiers from T and the address space. + // If T already has an address space specifier, it is silently replaced. QualType getASQualType(QualType T, unsigned AddressSpace); /// getComplexType - Return the uniqued reference to the type for a complex diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h index b77d23b813..fc115c8a39 100644 --- a/include/clang/AST/Type.h +++ b/include/clang/AST/Type.h @@ -51,7 +51,6 @@ namespace clang { class FunctionType; class OCUVectorType; class BuiltinType; - class ASQualType; class ObjCQualifiedInterfaceType; class StmtIteratorBase; @@ -90,7 +89,7 @@ public: return T; } - unsigned getQualifiers() const { + unsigned getCVRQualifiers() const { return ThePtr & CVRFlags; } Type *getTypePtr() const { @@ -237,7 +236,8 @@ protected: // silence VC++ warning C4355: 'this' : used in base member initializer list Type *this_() { return this; } Type(TypeClass tc, QualType Canonical) - : CanonicalType(Canonical.isNull() ? QualType(this_(),0) : Canonical), TC(tc){} + : CanonicalType(Canonical.isNull() ? QualType(this_(), 0) : Canonical), + TC(tc) {} virtual ~Type(); friend class ASTContext; @@ -311,8 +311,8 @@ public: bool isObjCQualifiedIdType() const; // id includes conforming protocol type // Type Checking Functions: Check to see if this type is structurally the - // specified type, ignoring typedefs and qualifiers, and return a pointer to the best type - // we can. + // specified type, ignoring typedefs and qualifiers, and return a pointer to + // the best type we can. const BuiltinType *getAsBuiltinType() const; const FunctionType *getAsFunctionType() const; const PointerType *getAsPointerType() const; @@ -379,15 +379,18 @@ protected: /// This supports address space qualified types. /// class ASQualType : public Type, public llvm::FoldingSetNode { - QualType BaseType; + /// BaseType - This is the underlying type that this qualifies. All CVR + /// qualifiers are stored on the QualType that references this type, so we + /// can't have any here. + Type *BaseType; /// Address Space ID - The address space ID this type is qualified with. unsigned AddressSpace; - ASQualType(QualType Base, QualType CanonicalPtr, unsigned AddrSpace) : + ASQualType(Type *Base, QualType CanonicalPtr, unsigned AddrSpace) : Type(ASQual, CanonicalPtr), BaseType(Base), AddressSpace(AddrSpace) { } friend class ASTContext; // ASTContext creates these. public: - QualType getBaseType() const { return BaseType; } + Type *getBaseType() const { return BaseType; } unsigned getAddressSpace() const { return AddressSpace; } virtual void getAsStringInternal(std::string &InnerString) const; @@ -395,9 +398,9 @@ public: void Profile(llvm::FoldingSetNodeID &ID) { Profile(ID, getBaseType(), AddressSpace); } - static void Profile(llvm::FoldingSetNodeID &ID, QualType Base, + static void Profile(llvm::FoldingSetNodeID &ID, Type *Base, unsigned AddrSpace) { - ID.AddPointer(Base.getAsOpaquePtr()); + ID.AddPointer(Base); ID.AddInteger(AddrSpace); } @@ -1093,21 +1096,22 @@ public: /// getCanonicalType - Return the canonical version of this type, with the /// appropriate type qualifiers on it. inline QualType QualType::getCanonicalType() const { - return QualType(getTypePtr()->getCanonicalTypeInternal().getTypePtr(), - getQualifiers() | - getTypePtr()->getCanonicalTypeInternal().getQualifiers()); + QualType CanType = getTypePtr()->getCanonicalTypeInternal(); + return QualType(CanType.getTypePtr(), + getCVRQualifiers() | CanType.getCVRQualifiers()); } /// getUnqualifiedType - Return the type without any qualifiers. inline QualType QualType::getUnqualifiedType() const { - if (const ASQualType *ASQT = dyn_cast(getTypePtr())) - return ASQT->getBaseType().getUnqualifiedType(); - return QualType(getTypePtr(), 0); + Type *TP = getTypePtr(); + if (const ASQualType *ASQT = dyn_cast(TP)) + TP = ASQT->getBaseType(); + return QualType(TP, 0); } /// getAddressSpace - Return the address space of this type. inline unsigned QualType::getAddressSpace() const { - if (const ASQualType *ASQT = dyn_cast(getTypePtr())) + if (const ASQualType *ASQT = dyn_cast(getCanonicalType())) return ASQT->getAddressSpace(); return 0; }