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.

llvm-svn: 47398
This commit is contained in:
Chris Lattner 2008-02-20 20:55:12 +00:00
parent 1872ad9888
commit 445fcabff7
10 changed files with 69 additions and 46 deletions

View File

@ -257,7 +257,7 @@ ASTContext::getTypeInfo(QualType T, SourceLocation L) {
break;
}
case Type::ASQual:
return getTypeInfo(cast<ASQualType>(T)->getBaseType(), L);
return getTypeInfo(QualType(cast<ASQualType>(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<PointerType>(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();

View File

@ -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);
}

View File

@ -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<TypedefType>(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())

View File

@ -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());
}

View File

@ -263,7 +263,7 @@ const llvm::Type *CodeGenTypes::ConvertNewType(QualType T) {
}
case Type::ASQual:
return ConvertType(cast<ASQualType>(Ty).getBaseType());
return ConvertType(QualType(cast<ASQualType>(Ty).getBaseType(), 0));
case Type::ObjCInterface:
assert(0 && "FIXME: add missing functionality here");

View File

@ -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<ValueDecl>(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);
}

View File

@ -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

View File

@ -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.

View File

@ -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

View File

@ -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<ASQualType>(getTypePtr()))
return ASQT->getBaseType().getUnqualifiedType();
return QualType(getTypePtr(), 0);
Type *TP = getTypePtr();
if (const ASQualType *ASQT = dyn_cast<ASQualType>(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<ASQualType>(getTypePtr()))
if (const ASQualType *ASQT = dyn_cast<ASQualType>(getCanonicalType()))
return ASQT->getAddressSpace();
return 0;
}