namespace clang {
class ASTContext;
class Type;
+ class ObjCGCAttr;
class TypedefDecl;
class TemplateDecl;
class TemplateTypeParmDecl;
/// __strong attributes.
///
class ExtQualType : public Type, public llvm::FoldingSetNode {
+public:
+ enum EQT {
+ EXTNONE = 0x0,
+ ASQUAL = 0x01,
+ GCQUAL = 0x10
+ };
+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.
Type *BaseType;
+ unsigned ExtQualTypeKind : 2;
+
/// Address Space ID - The address space ID this type is qualified with.
unsigned AddressSpace;
- ExtQualType(Type *Base, QualType CanonicalPtr, unsigned AddrSpace) :
- Type(ExtQual, CanonicalPtr, Base->isDependentType()), BaseType(Base),
- AddressSpace(AddrSpace) {
+ /// GC __weak/__strong attributes
+ ObjCGCAttr *GCAttr;
+
+ ExtQualType(Type *Base, QualType CanonicalPtr, unsigned AddrSpace,
+ ObjCGCAttr *gcAttr,
+ unsigned ExtKind) :
+ Type(ExtQual, CanonicalPtr, Base->isDependentType()), BaseType(Base),
+ ExtQualTypeKind(ExtKind), AddressSpace(0), GCAttr(0) {
+ if (ExtKind & ASQUAL)
+ AddressSpace = AddrSpace;
+ if (ExtKind & GCQUAL)
+ GCAttr = gcAttr;
}
friend class ASTContext; // ASTContext creates these.
public:
Type *getBaseType() const { return BaseType; }
- unsigned getAddressSpace() const { return AddressSpace; }
+ ObjCGCAttr *getGCAttr() const {
+ assert((ExtQualTypeKind & GCQUAL) && "Bad ExtQualType Kind - not GCQUAL");
+ return GCAttr;
+ }
+ unsigned getAddressSpace() const {
+ assert((ExtQualTypeKind & ASQUAL) && "Bad ExtQualType Kind - not ASQUAL");
+ return AddressSpace;
+ }
virtual void getAsStringInternal(std::string &InnerString) const;
void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getBaseType(), AddressSpace);
+ Profile(ID, getBaseType(), AddressSpace, GCAttr);
}
static void Profile(llvm::FoldingSetNodeID &ID, Type *Base,
- unsigned AddrSpace) {
+ unsigned AddrSpace, ObjCGCAttr *gcAttr) {
ID.AddPointer(Base);
+ ID.AddPointer(gcAttr);
ID.AddInteger(AddrSpace);
}
// 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::Profile(ID, T.getTypePtr(), AddressSpace, 0);
void *InsertPos = 0;
if (ExtQualType *EXTQy = ExtQualTypes.FindNodeOrInsertPos(ID, InsertPos))
return QualType(EXTQy, 0);
assert(NewIP == 0 && "Shouldn't be in the map!"); NewIP = NewIP;
}
ExtQualType *New = new (*this, 8) ExtQualType(T.getTypePtr(), Canonical,
- AddressSpace);
+ AddressSpace, 0,
+ ExtQualType::ASQUAL);
ExtQualTypes.InsertNode(New, InsertPos);
Types.push_back(New);
return QualType(New, T.getCVRQualifiers());
}
void ExtQualType::getAsStringInternal(std::string &S) const {
- S = "__attribute__((address_space("+llvm::utostr_32(AddressSpace)+")))" + S;
+ bool space = false;
+ if (ExtQualTypeKind & ASQUAL) {
+ S = "__attribute__((address_space("+llvm::utostr_32(AddressSpace)+")))" + S;
+ space = true;
+ }
+ if (ExtQualTypeKind & GCQUAL) {
+ if (space)
+ S += ' ';
+ S += "__attribute__((objc_gc(";
+ ObjCGCAttr *gcattr = getGCAttr();
+ ObjCGCAttr::GCAttrTypes attr = gcattr->getType();
+ if (attr & ObjCGCAttr::Weak)
+ S += "weak";
+ else
+ S += "strong";
+ S += ")))";
+ }
BaseType->getAsStringInternal(S);
}