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.
|
/// replaced.
|
||||||
QualType getAddrSpaceQualType(QualType T, unsigned AddressSpace);
|
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
|
/// getComplexType - Return the uniqued reference to the type for a complex
|
||||||
/// number with the specified element type.
|
/// number with the specified element type.
|
||||||
QualType getComplexType(QualType T);
|
QualType getComplexType(QualType T);
|
||||||
|
|
|
@ -93,6 +93,12 @@ public:
|
||||||
CVRFlags = Const|Restrict|Volatile
|
CVRFlags = Const|Restrict|Volatile
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum GCAttrTypes {
|
||||||
|
GCNone = 0,
|
||||||
|
Weak,
|
||||||
|
Strong
|
||||||
|
};
|
||||||
|
|
||||||
QualType() {}
|
QualType() {}
|
||||||
|
|
||||||
QualType(const Type *Ptr, unsigned Quals)
|
QualType(const Type *Ptr, unsigned Quals)
|
||||||
|
@ -188,6 +194,9 @@ public:
|
||||||
/// getAddressSpace - Return the address space of this type.
|
/// getAddressSpace - Return the address space of this type.
|
||||||
inline unsigned getAddressSpace() const;
|
inline unsigned getAddressSpace() const;
|
||||||
|
|
||||||
|
/// GCAttrTypesAttr - Returns gc attribute of this type.
|
||||||
|
inline QualType::GCAttrTypes getObjCGCAttr() const;
|
||||||
|
|
||||||
/// Emit - Serialize a QualType to Bitcode.
|
/// Emit - Serialize a QualType to Bitcode.
|
||||||
void Emit(llvm::Serializer& S) const;
|
void Emit(llvm::Serializer& S) const;
|
||||||
|
|
||||||
|
@ -255,6 +264,7 @@ public:
|
||||||
BlockPointer, // C extension
|
BlockPointer, // C extension
|
||||||
FixedWidthInt
|
FixedWidthInt
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QualType CanonicalType;
|
QualType CanonicalType;
|
||||||
|
|
||||||
|
@ -461,14 +471,6 @@ protected:
|
||||||
/// __strong attributes.
|
/// __strong attributes.
|
||||||
///
|
///
|
||||||
class ExtQualType : public Type, public llvm::FoldingSetNode {
|
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
|
/// BaseType - This is the underlying type that this qualifies. All CVR
|
||||||
/// qualifiers are stored on the QualType that references this type, so we
|
/// qualifiers are stored on the QualType that references this type, so we
|
||||||
/// can't have any here.
|
/// can't have any here.
|
||||||
|
@ -477,16 +479,16 @@ private:
|
||||||
/// Address Space ID - The address space ID this type is qualified with.
|
/// Address Space ID - The address space ID this type is qualified with.
|
||||||
unsigned AddressSpace;
|
unsigned AddressSpace;
|
||||||
/// GC __weak/__strong attributes
|
/// GC __weak/__strong attributes
|
||||||
GCAttrTypes GCAttrType;
|
QualType::GCAttrTypes GCAttrType;
|
||||||
|
|
||||||
ExtQualType(Type *Base, QualType CanonicalPtr, unsigned AddrSpace,
|
ExtQualType(Type *Base, QualType CanonicalPtr, unsigned AddrSpace,
|
||||||
GCAttrTypes gcAttr) :
|
QualType::GCAttrTypes gcAttr) :
|
||||||
Type(ExtQual, CanonicalPtr, Base->isDependentType()), BaseType(Base),
|
Type(ExtQual, CanonicalPtr, Base->isDependentType()), BaseType(Base),
|
||||||
AddressSpace(AddrSpace), GCAttrType(gcAttr) { }
|
AddressSpace(AddrSpace), GCAttrType(gcAttr) { }
|
||||||
friend class ASTContext; // ASTContext creates these.
|
friend class ASTContext; // ASTContext creates these.
|
||||||
public:
|
public:
|
||||||
Type *getBaseType() const { return BaseType; }
|
Type *getBaseType() const { return BaseType; }
|
||||||
GCAttrTypes getType() const { return GCAttrType; }
|
QualType::GCAttrTypes getObjCGCAttr() const { return GCAttrType; }
|
||||||
unsigned getAddressSpace() const { return AddressSpace; }
|
unsigned getAddressSpace() const { return AddressSpace; }
|
||||||
|
|
||||||
virtual void getAsStringInternal(std::string &InnerString) const;
|
virtual void getAsStringInternal(std::string &InnerString) const;
|
||||||
|
@ -495,7 +497,7 @@ public:
|
||||||
Profile(ID, getBaseType(), AddressSpace, GCAttrType);
|
Profile(ID, getBaseType(), AddressSpace, GCAttrType);
|
||||||
}
|
}
|
||||||
static void Profile(llvm::FoldingSetNodeID &ID, Type *Base,
|
static void Profile(llvm::FoldingSetNodeID &ID, Type *Base,
|
||||||
unsigned AddrSpace, GCAttrTypes gcAttr) {
|
unsigned AddrSpace, QualType::GCAttrTypes gcAttr) {
|
||||||
ID.AddPointer(Base);
|
ID.AddPointer(Base);
|
||||||
ID.AddInteger(AddrSpace);
|
ID.AddInteger(AddrSpace);
|
||||||
ID.AddInteger(gcAttr);
|
ID.AddInteger(gcAttr);
|
||||||
|
@ -1741,6 +1743,16 @@ inline unsigned QualType::getAddressSpace() const {
|
||||||
return 0;
|
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
|
/// isMoreQualifiedThan - Determine whether this type is more
|
||||||
/// qualified than the Other type. For example, "const volatile int"
|
/// qualified than the Other type. For example, "const volatile int"
|
||||||
/// is more qualified than "const int", "volatile int", and
|
/// 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
|
// Check if we've already instantiated an address space qual'd type of this
|
||||||
// type.
|
// type.
|
||||||
llvm::FoldingSetNodeID ID;
|
llvm::FoldingSetNodeID ID;
|
||||||
ExtQualType::Profile(ID, T.getTypePtr(), AddressSpace, ExtQualType::GCNone);
|
ExtQualType::Profile(ID, T.getTypePtr(), AddressSpace, T.getObjCGCAttr());
|
||||||
void *InsertPos = 0;
|
void *InsertPos = 0;
|
||||||
if (ExtQualType *EXTQy = ExtQualTypes.FindNodeOrInsertPos(ID, InsertPos))
|
if (ExtQualType *EXTQy = ExtQualTypes.FindNodeOrInsertPos(ID, InsertPos))
|
||||||
return QualType(EXTQy, 0);
|
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;
|
assert(NewIP == 0 && "Shouldn't be in the map!"); NewIP = NewIP;
|
||||||
}
|
}
|
||||||
ExtQualType *New = new (*this, 8) ExtQualType(T.getTypePtr(), Canonical,
|
ExtQualType *New = new (*this, 8) ExtQualType(T.getTypePtr(), Canonical,
|
||||||
AddressSpace, ExtQualType::GCNone);
|
AddressSpace,
|
||||||
|
QualType::GCNone);
|
||||||
ExtQualTypes.InsertNode(New, InsertPos);
|
ExtQualTypes.InsertNode(New, InsertPos);
|
||||||
Types.push_back(New);
|
Types.push_back(New);
|
||||||
return QualType(New, T.getCVRQualifiers());
|
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
|
/// getComplexType - Return the uniqued reference to the type for a complex
|
||||||
/// number with the specified element type.
|
/// 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;
|
S = "__attribute__((address_space("+llvm::utostr_32(AddressSpace)+")))" + S;
|
||||||
space = true;
|
space = true;
|
||||||
}
|
}
|
||||||
if (GCAttrType != GCNone) {
|
if (GCAttrType != QualType::GCNone) {
|
||||||
if (space)
|
if (space)
|
||||||
S += ' ';
|
S += ' ';
|
||||||
S += "__attribute__((objc_gc(";
|
S += "__attribute__((objc_gc(";
|
||||||
if (GCAttrType == Weak)
|
if (GCAttrType == QualType::Weak)
|
||||||
S += "weak";
|
S += "weak";
|
||||||
else
|
else
|
||||||
S += "strong";
|
S += "strong";
|
||||||
|
|
|
@ -758,6 +758,35 @@ static void HandleAddressSpaceTypeAttribute(QualType &Type,
|
||||||
Type = S.Context.getAddrSpaceQualType(Type, ASIdx);
|
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) {
|
void Sema::ProcessTypeAttributeList(QualType &Result, const AttributeList *AL) {
|
||||||
// Scan through and apply attributes to this type where it makes sense. Some
|
// Scan through and apply attributes to this type where it makes sense. Some
|
||||||
// attributes (such as __address_space__, __vector_size__, etc) apply to the
|
// 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:
|
case AttributeList::AT_address_space:
|
||||||
HandleAddressSpaceTypeAttribute(Result, *AL, *this);
|
HandleAddressSpaceTypeAttribute(Result, *AL, *this);
|
||||||
break;
|
break;
|
||||||
|
case AttributeList::AT_objc_gc:
|
||||||
|
HandleObjCGCTypeAttribute(Result, *AL, *this);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue