diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/AST/ASTContext.cpp | 39 | ||||
-rw-r--r-- | lib/AST/Type.cpp | 4 | ||||
-rw-r--r-- | lib/Sema/SemaType.cpp | 32 |
3 files changed, 71 insertions, 4 deletions
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 4a3f00f356..6b49b85c24 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -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. diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp index bc597072ed..6c72a76a60 100644 --- a/lib/AST/Type.cpp +++ b/lib/AST/Type.cpp @@ -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"; diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp index db885e97fd..e6aafdab08 100644 --- a/lib/Sema/SemaType.cpp +++ b/lib/Sema/SemaType.cpp @@ -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; } } } |