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 bd7215d..a636e8d 100644
--- a/AST/ASTContext.cpp
+++ b/AST/ASTContext.cpp
@@ -257,7 +257,7 @@
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 @@
//===----------------------------------------------------------------------===//
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 @@
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::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 @@
/// 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 27dfa78..7a9a78e 100644
--- a/AST/Expr.cpp
+++ b/AST/Expr.cpp
@@ -358,7 +358,7 @@
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 @@
// 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 7e72d82..f5f7f3d 100644
--- a/AST/Type.cpp
+++ b/AST/Type.cpp
@@ -709,7 +709,12 @@
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 @@
}
// 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 e2ccd3c..e1e8ef0 100644
--- a/AST/TypeSerialization.cpp
+++ b/AST/TypeSerialization.cpp
@@ -25,7 +25,7 @@
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 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 96bccfc..2037cfd 100644
--- a/CodeGen/CodeGenTypes.cpp
+++ b/CodeGen/CodeGenTypes.cpp
@@ -263,7 +263,7 @@
}
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");
diff --git a/Sema/SemaDecl.cpp b/Sema/SemaDecl.cpp
index 9a19928..9ca5f2b 100644
--- a/Sema/SemaDecl.cpp
+++ b/Sema/SemaDecl.cpp
@@ -1042,7 +1042,7 @@
// 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 @@
} 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 @@
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 @@
// 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 31cdc59..3d60866 100644
--- a/Sema/SemaExpr.cpp
+++ b/Sema/SemaExpr.cpp
@@ -541,7 +541,7 @@
// 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 @@
// 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 @@
}
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 @@
// 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 @@
// 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 58d7019..dd9ebd8 100644
--- a/Sema/SemaType.cpp
+++ b/Sema/SemaType.cpp
@@ -328,7 +328,7 @@
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 40e1f72..1c98cb5 100644
--- a/include/clang/AST/ASTContext.h
+++ b/include/clang/AST/ASTContext.h
@@ -121,8 +121,10 @@
// 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 b77d23b..fc115c8 100644
--- a/include/clang/AST/Type.h
+++ b/include/clang/AST/Type.h
@@ -51,7 +51,6 @@
class FunctionType;
class OCUVectorType;
class BuiltinType;
- class ASQualType;
class ObjCQualifiedInterfaceType;
class StmtIteratorBase;
@@ -90,7 +89,7 @@
return T;
}
- unsigned getQualifiers() const {
+ unsigned getCVRQualifiers() const {
return ThePtr & CVRFlags;
}
Type *getTypePtr() const {
@@ -237,7 +236,8 @@
// 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 @@
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 @@
/// 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 @@
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 @@
/// 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;
}