forked from OSchip/llvm-project
Representation of objc gc's attribute using ExtQualType.
Note that one test attr-objc-gc.m fails. I will fix this after removing these attributes from the Decl nodes. llvm-svn: 64889
This commit is contained in:
parent
38a9631d5f
commit
e27e934d45
|
@ -190,6 +190,11 @@ public:
|
|||
/// replaced.
|
||||
QualType getAddrSpaceQualType(QualType T, unsigned AddressSpace);
|
||||
|
||||
/// getObjCGCQualType - Returns the uniqued reference to the type for an
|
||||
/// objc gc qualified type. The retulting type has a union of the qualifiers
|
||||
/// from T and the gc attribute.
|
||||
QualType getObjCGCQualType(QualType T, QualType::GCAttrTypes gcAttr);
|
||||
|
||||
/// getComplexType - Return the uniqued reference to the type for a complex
|
||||
/// number with the specified element type.
|
||||
QualType getComplexType(QualType T);
|
||||
|
|
|
@ -93,6 +93,12 @@ public:
|
|||
CVRFlags = Const|Restrict|Volatile
|
||||
};
|
||||
|
||||
enum GCAttrTypes {
|
||||
GCNone = 0,
|
||||
Weak,
|
||||
Strong
|
||||
};
|
||||
|
||||
QualType() {}
|
||||
|
||||
QualType(const Type *Ptr, unsigned Quals)
|
||||
|
@ -188,6 +194,9 @@ public:
|
|||
/// getAddressSpace - Return the address space of this type.
|
||||
inline unsigned getAddressSpace() const;
|
||||
|
||||
/// GCAttrTypesAttr - Returns gc attribute of this type.
|
||||
inline QualType::GCAttrTypes getObjCGCAttr() const;
|
||||
|
||||
/// Emit - Serialize a QualType to Bitcode.
|
||||
void Emit(llvm::Serializer& S) const;
|
||||
|
||||
|
@ -255,6 +264,7 @@ public:
|
|||
BlockPointer, // C extension
|
||||
FixedWidthInt
|
||||
};
|
||||
|
||||
private:
|
||||
QualType CanonicalType;
|
||||
|
||||
|
@ -461,14 +471,6 @@ protected:
|
|||
/// __strong attributes.
|
||||
///
|
||||
class ExtQualType : public Type, public llvm::FoldingSetNode {
|
||||
public:
|
||||
enum GCAttrTypes {
|
||||
GCNone = 0,
|
||||
Weak,
|
||||
Strong
|
||||
};
|
||||
|
||||
private:
|
||||
/// 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.
|
||||
|
@ -477,16 +479,16 @@ private:
|
|||
/// Address Space ID - The address space ID this type is qualified with.
|
||||
unsigned AddressSpace;
|
||||
/// GC __weak/__strong attributes
|
||||
GCAttrTypes GCAttrType;
|
||||
QualType::GCAttrTypes GCAttrType;
|
||||
|
||||
ExtQualType(Type *Base, QualType CanonicalPtr, unsigned AddrSpace,
|
||||
GCAttrTypes gcAttr) :
|
||||
QualType::GCAttrTypes gcAttr) :
|
||||
Type(ExtQual, CanonicalPtr, Base->isDependentType()), BaseType(Base),
|
||||
AddressSpace(AddrSpace), GCAttrType(gcAttr) { }
|
||||
friend class ASTContext; // ASTContext creates these.
|
||||
public:
|
||||
Type *getBaseType() const { return BaseType; }
|
||||
GCAttrTypes getType() const { return GCAttrType; }
|
||||
QualType::GCAttrTypes getObjCGCAttr() const { return GCAttrType; }
|
||||
unsigned getAddressSpace() const { return AddressSpace; }
|
||||
|
||||
virtual void getAsStringInternal(std::string &InnerString) const;
|
||||
|
@ -495,7 +497,7 @@ public:
|
|||
Profile(ID, getBaseType(), AddressSpace, GCAttrType);
|
||||
}
|
||||
static void Profile(llvm::FoldingSetNodeID &ID, Type *Base,
|
||||
unsigned AddrSpace, GCAttrTypes gcAttr) {
|
||||
unsigned AddrSpace, QualType::GCAttrTypes gcAttr) {
|
||||
ID.AddPointer(Base);
|
||||
ID.AddInteger(AddrSpace);
|
||||
ID.AddInteger(gcAttr);
|
||||
|
@ -1741,6 +1743,16 @@ inline unsigned QualType::getAddressSpace() const {
|
|||
return 0;
|
||||
}
|
||||
|
||||
/// getObjCGCAttr - Return the gc attribute of this type.
|
||||
inline QualType::GCAttrTypes QualType::getObjCGCAttr() const {
|
||||
QualType CT = getTypePtr()->getCanonicalTypeInternal();
|
||||
if (const ArrayType *AT = dyn_cast<ArrayType>(CT))
|
||||
return AT->getElementType().getObjCGCAttr();
|
||||
if (const ExtQualType *EXTQT = dyn_cast<ExtQualType>(CT))
|
||||
return EXTQT->getObjCGCAttr();
|
||||
return GCNone;
|
||||
}
|
||||
|
||||
/// isMoreQualifiedThan - Determine whether this type is more
|
||||
/// qualified than the Other type. For example, "const volatile int"
|
||||
/// is more qualified than "const int", "volatile int", and
|
||||
|
|
|
@ -725,7 +725,7 @@ QualType ASTContext::getAddrSpaceQualType(QualType T, unsigned AddressSpace) {
|
|||
// Check if we've already instantiated an address space qual'd type of this
|
||||
// type.
|
||||
llvm::FoldingSetNodeID ID;
|
||||
ExtQualType::Profile(ID, T.getTypePtr(), AddressSpace, ExtQualType::GCNone);
|
||||
ExtQualType::Profile(ID, T.getTypePtr(), AddressSpace, T.getObjCGCAttr());
|
||||
void *InsertPos = 0;
|
||||
if (ExtQualType *EXTQy = ExtQualTypes.FindNodeOrInsertPos(ID, InsertPos))
|
||||
return QualType(EXTQy, 0);
|
||||
|
@ -741,12 +741,47 @@ QualType ASTContext::getAddrSpaceQualType(QualType T, unsigned AddressSpace) {
|
|||
assert(NewIP == 0 && "Shouldn't be in the map!"); NewIP = NewIP;
|
||||
}
|
||||
ExtQualType *New = new (*this, 8) ExtQualType(T.getTypePtr(), Canonical,
|
||||
AddressSpace, ExtQualType::GCNone);
|
||||
AddressSpace,
|
||||
QualType::GCNone);
|
||||
ExtQualTypes.InsertNode(New, InsertPos);
|
||||
Types.push_back(New);
|
||||
return QualType(New, T.getCVRQualifiers());
|
||||
}
|
||||
|
||||
QualType ASTContext::getObjCGCQualType(QualType T,
|
||||
QualType::GCAttrTypes attr) {
|
||||
QualType CanT = getCanonicalType(T);
|
||||
if (CanT.getObjCGCAttr() == attr)
|
||||
return T;
|
||||
|
||||
// Type's cannot have multiple ExtQuals, therefore we know we only have to deal
|
||||
// with CVR qualifiers from here on out.
|
||||
assert(CanT.getObjCGCAttr() == QualType::GCNone &&
|
||||
"Type is already gc qualified");
|
||||
|
||||
// Check if we've already instantiated an gc qual'd type of this type.
|
||||
llvm::FoldingSetNodeID ID;
|
||||
ExtQualType::Profile(ID, T.getTypePtr(), T.getAddressSpace(), attr);
|
||||
void *InsertPos = 0;
|
||||
if (ExtQualType *EXTQy = ExtQualTypes.FindNodeOrInsertPos(ID, InsertPos))
|
||||
return QualType(EXTQy, 0);
|
||||
|
||||
// If the base type isn't canonical, this won't be a canonical type either,
|
||||
// so fill in the canonical type field.
|
||||
QualType Canonical;
|
||||
if (!T->isCanonical()) {
|
||||
Canonical = getObjCGCQualType(CanT, attr);
|
||||
|
||||
// Get the new insert position for the node we care about.
|
||||
ExtQualType *NewIP = ExtQualTypes.FindNodeOrInsertPos(ID, InsertPos);
|
||||
assert(NewIP == 0 && "Shouldn't be in the map!"); NewIP = NewIP;
|
||||
}
|
||||
ExtQualType *New = new (*this, 8) ExtQualType(T.getTypePtr(), Canonical,
|
||||
0, attr);
|
||||
ExtQualTypes.InsertNode(New, InsertPos);
|
||||
Types.push_back(New);
|
||||
return QualType(New, T.getCVRQualifiers());
|
||||
}
|
||||
|
||||
/// getComplexType - Return the uniqued reference to the type for a complex
|
||||
/// number with the specified element type.
|
||||
|
|
|
@ -1058,11 +1058,11 @@ void ExtQualType::getAsStringInternal(std::string &S) const {
|
|||
S = "__attribute__((address_space("+llvm::utostr_32(AddressSpace)+")))" + S;
|
||||
space = true;
|
||||
}
|
||||
if (GCAttrType != GCNone) {
|
||||
if (GCAttrType != QualType::GCNone) {
|
||||
if (space)
|
||||
S += ' ';
|
||||
S += "__attribute__((objc_gc(";
|
||||
if (GCAttrType == Weak)
|
||||
if (GCAttrType == QualType::Weak)
|
||||
S += "weak";
|
||||
else
|
||||
S += "strong";
|
||||
|
|
|
@ -758,6 +758,35 @@ static void HandleAddressSpaceTypeAttribute(QualType &Type,
|
|||
Type = S.Context.getAddrSpaceQualType(Type, ASIdx);
|
||||
}
|
||||
|
||||
/// HandleObjCGCTypeAttribute - Process an objc's gc attribute on the
|
||||
/// specified type. The attribute contains 1 argument, weak or strong.
|
||||
static void HandleObjCGCTypeAttribute(QualType &Type,
|
||||
const AttributeList &Attr, Sema &S){
|
||||
// FIXME. Needs more work for this to make sense.
|
||||
if (Type.getObjCGCAttr() != QualType::GCNone) {
|
||||
S.Diag(Attr.getLoc(), diag::err_attribute_address_multiple_qualifiers);
|
||||
return;
|
||||
}
|
||||
|
||||
// Check the attribute arguments.
|
||||
QualType::GCAttrTypes attr;
|
||||
if (!Attr.getParameterName() || Attr.getNumArgs() != 0) {
|
||||
S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
|
||||
return;
|
||||
}
|
||||
if (Attr.getParameterName()->isStr("weak"))
|
||||
attr = QualType::Weak;
|
||||
else if (Attr.getParameterName()->isStr("strong"))
|
||||
attr = QualType::Strong;
|
||||
else {
|
||||
S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
|
||||
<< "objc_gc" << Attr.getParameterName();
|
||||
return;
|
||||
}
|
||||
|
||||
Type = S.Context.getObjCGCQualType(Type, attr);
|
||||
}
|
||||
|
||||
void Sema::ProcessTypeAttributeList(QualType &Result, const AttributeList *AL) {
|
||||
// Scan through and apply attributes to this type where it makes sense. Some
|
||||
// attributes (such as __address_space__, __vector_size__, etc) apply to the
|
||||
|
@ -771,6 +800,9 @@ void Sema::ProcessTypeAttributeList(QualType &Result, const AttributeList *AL) {
|
|||
case AttributeList::AT_address_space:
|
||||
HandleAddressSpaceTypeAttribute(Result, *AL, *this);
|
||||
break;
|
||||
case AttributeList::AT_objc_gc:
|
||||
HandleObjCGCTypeAttribute(Result, *AL, *this);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue