diff --git a/CodeGen/CodeGenTypes.cpp b/CodeGen/CodeGenTypes.cpp index 21a359fe70..d8174bec4e 100644 --- a/CodeGen/CodeGenTypes.cpp +++ b/CodeGen/CodeGenTypes.cpp @@ -140,6 +140,10 @@ const llvm::Type *CodeGenTypes::ConvertType(QualType T) { case Type::ObjcInterface: assert(0 && "FIXME: add missing functionality here"); break; + + case Type::ObjcQualifiedInterface: + assert(0 && "FIXME: add missing functionality here"); + break; case Type::Tagged: const TagType &TT = cast(Ty); diff --git a/Driver/ASTConsumers.cpp b/Driver/ASTConsumers.cpp index a52cd4511a..1ec2c72d52 100644 --- a/Driver/ASTConsumers.cpp +++ b/Driver/ASTConsumers.cpp @@ -74,8 +74,26 @@ static void PrintTypeDefDecl(TypedefDecl *TD) { } static void PrintObjcInterfaceDecl(ObjcInterfaceDecl *OID) { - std::string S = OID->getName(); - fprintf(stderr, "@interface %s;\n", S.c_str()); + std::string I = OID->getName(); + ObjcInterfaceDecl *SID = OID->getSuperClass(); + if (SID) { + std::string S = SID->getName(); + fprintf(stderr, "@interface %s : %s", I.c_str(), S.c_str()); + } + else + fprintf(stderr, "@interface %s", I.c_str()); + // Protocols? + int count = OID->getNumIntfRefProtocols(); + if (count > 0) { + ObjcProtocolDecl **refProtocols = OID->getReferencedProtocols(); + for (int i = 0; i < count; i++) + fprintf(stderr, "%c%s", (i == 0 ? '<' : ','), + refProtocols[i]->getName()); + } + if (count > 0) + fprintf(stderr, ">;\n"); + else + fprintf(stderr, ";\n"); // FIXME: implement the rest... } diff --git a/Parse/ParseObjc.cpp b/Parse/ParseObjc.cpp index b7ec93aaca..31caa58ef3 100644 --- a/Parse/ParseObjc.cpp +++ b/Parse/ParseObjc.cpp @@ -618,6 +618,12 @@ Parser::DeclTy *Parser::ParseObjCMethodDecl(tok::TokenKind mType, MethodAttrs, MethodImplKind); } +/// CmpProtocolVals - Comparison predicate for sorting protocols. +static bool CmpProtocolVals(const IdentifierInfo* const& lhs, + const IdentifierInfo* const& rhs) { + return strcmp(lhs->getName(), rhs->getName()) < 0; +} + /// objc-protocol-refs: /// '<' identifier-list '>' /// @@ -640,6 +646,15 @@ bool Parser::ParseObjCProtocolReferences( break; ConsumeToken(); } + + // Sort protocols, keyed by name. + // Later on, we remove duplicates. + std::stable_sort(ProtocolRefs.begin(), ProtocolRefs.end(), CmpProtocolVals); + + // Make protocol names unique. + ProtocolRefs.erase(std::unique(ProtocolRefs.begin(), ProtocolRefs.end()), + ProtocolRefs.end()); + // Consume the '>'. return ExpectAndConsume(tok::greater, diag::err_expected_greater); } diff --git a/clang.xcodeproj/project.pbxproj b/clang.xcodeproj/project.pbxproj index 951688f92a..12ddcaae8c 100644 --- a/clang.xcodeproj/project.pbxproj +++ b/clang.xcodeproj/project.pbxproj @@ -739,6 +739,7 @@ 08FB7793FE84155DC02AAC07 /* Project object */ = { isa = PBXProject; buildConfigurationList = 1DEB923508733DC60010E9CD /* Build configuration list for PBXProject "clang" */; + compatibilityVersion = "Xcode 2.4"; hasScannedForEncodings = 1; mainGroup = 08FB7794FE84155DC02AAC07 /* clang */; projectDirPath = ""; diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h index f2c4947312..b5e946b693 100644 --- a/include/clang/AST/Type.h +++ b/include/clang/AST/Type.h @@ -32,6 +32,7 @@ namespace clang { class RecordDecl; class EnumDecl; class ObjcInterfaceDecl; + class ObjcProtocolDecl; class Expr; class SourceLocation; class PointerType; @@ -204,7 +205,7 @@ public: Vector, OCUVector, FunctionNoProto, FunctionProto, TypeName, Tagged, - ObjcInterface, + ObjcInterface, ObjcQualifiedInterface, TypeOfExp, TypeOfTyp // GNU typeof extension. }; private: @@ -831,6 +832,28 @@ public: static bool classof(const ObjcInterfaceType *) { return true; } }; +/// - ObjcQualifiedInterfaceType - This class represense interface types +/// conforming to a list of protocols; such as, INTF. +class ObjcQualifiedInterfaceType : public Type { + // Interface type for this protocol conforming object type + ObjcInterfaceType *InterfaceType; + + // List of protocols for this protocol conforming object type + // List is sorted on protocol name. No protocol is enterred more than once. + llvm::SmallVector Protocols; + + ObjcQualifiedInterfaceType(ObjcInterfaceType *T) : + Type(ObjcQualifiedInterface, QualType()), InterfaceType(T) { } +public: + + ObjcInterfaceType *getInterfaceType() const { return InterfaceType; } + + static bool classof(const Type *T) { + return T->getTypeClass() == ObjcQualifiedInterface; + } + static bool classof(const ObjcQualifiedInterfaceType *) { return true; } +}; + /// RecordType - This is a helper class that allows the use of isa/cast/dyncast /// to detect TagType objects of structs/unions/classes. class RecordType : public TagType {