From: Fariborz Jahanian Date: Fri, 7 Dec 2007 00:18:54 +0000 (+0000) Subject: Patch to implement "Protocol" as a built-in type declared as X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=66c5dfc193c4090b67c5effb0e80e287b94de17e;p=clang Patch to implement "Protocol" as a built-in type declared as "@class Protocol;" git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@44670 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/AST/ASTContext.cpp b/AST/ASTContext.cpp index 3f5a7fbc58..e8ed9a209f 100644 --- a/AST/ASTContext.cpp +++ b/AST/ASTContext.cpp @@ -1121,15 +1121,10 @@ void ASTContext::setObjcSelType(TypedefDecl *TD) SelStructType = rec; } -void ASTContext::setObjcProtoType(TypedefDecl *TD) +void ASTContext::setObjcProtoType(QualType QT) { assert(ObjcProtoType.isNull() && "'Protocol' type already set!"); - - // typedef struct Protocol Protocol; - ObjcProtoType = TD->getUnderlyingType(); - // Protocol * type - ObjcProtoType = getPointerType(ObjcProtoType); - ProtoStructType = TD->getUnderlyingType()->getAsStructureType(); + ObjcProtoType = QT; } void ASTContext::setObjcClassType(TypedefDecl *TD) diff --git a/Parse/MinimalAction.cpp b/Parse/MinimalAction.cpp index 92d997f59c..54261527d9 100644 --- a/Parse/MinimalAction.cpp +++ b/Parse/MinimalAction.cpp @@ -43,6 +43,9 @@ void MinimalAction:: ActOnTranslationUnitScope(SourceLocation Loc, Scope *S) { II = &Idents.get("Class"); TI = new TypeNameInfo(1, II->getFETokenInfo()); II->setFETokenInfo(TI); + II = &Idents.get("Protocol"); + TI = new TypeNameInfo(1, II->getFETokenInfo()); + II->setFETokenInfo(TI); } /// isTypeName - This looks at the IdentifierInfo::FETokenInfo field to diff --git a/Sema/Sema.cpp b/Sema/Sema.cpp index 7bafd7db88..7a657cd5e1 100644 --- a/Sema/Sema.cpp +++ b/Sema/Sema.cpp @@ -23,7 +23,7 @@ using namespace clang; bool Sema::isBuiltinObjcType(TypedefDecl *TD) { const char *typeName = TD->getIdentifier()->getName(); return strcmp(typeName, "id") == 0 || strcmp(typeName, "Class") == 0 || - strcmp(typeName, "SEL") == 0; + strcmp(typeName, "SEL") == 0 || strcmp(typeName, "Protocol") == 0; } void Sema::ActOnTranslationUnitScope(SourceLocation Loc, Scope *S) { @@ -38,31 +38,16 @@ void Sema::ActOnTranslationUnitScope(SourceLocation Loc, Scope *S) { t = dyn_cast(Context.getObjcClassType().getTypePtr()); t->getDecl()->getIdentifier()->setFETokenInfo(t->getDecl()); TUScope->AddDecl(t->getDecl()); + ObjcInterfaceType *it = dyn_cast(Context.getObjcProtoType()); + ObjcInterfaceDecl *IDecl = it->getDecl(); + IDecl->getIdentifier()->setFETokenInfo(IDecl); + TUScope->AddDecl(IDecl); t = dyn_cast(Context.getObjcSelType().getTypePtr()); t->getDecl()->getIdentifier()->setFETokenInfo(t->getDecl()); TUScope->AddDecl(t->getDecl()); } } -/// FIXME: remove this. -/// GetObjcProtoType - See comments for Sema::GetObjcIdType above; replace "id" -/// with "Protocol". -QualType Sema::GetObjcProtoType(SourceLocation Loc) { - assert(TUScope && "GetObjcProtoType(): Top-level scope is null"); - if (Context.getObjcProtoType().isNull()) { - IdentifierInfo *ProtoIdent = &Context.Idents.get("Protocol"); - ScopedDecl *ProtoDecl = LookupScopedDecl(ProtoIdent, Decl::IDNS_Ordinary, - SourceLocation(), TUScope); - TypedefDecl *ObjcProtoTypedef = dyn_cast_or_null(ProtoDecl); - if (!ObjcProtoTypedef) { - Diag(Loc, diag::err_missing_proto_definition); - return QualType(); - } - Context.setObjcProtoType(ObjcProtoTypedef); - } - return Context.getObjcProtoType(); -} - Sema::Sema(Preprocessor &pp, ASTContext &ctxt) : PP(pp), Context(ctxt), CurFunctionDecl(0), CurMethodDecl(0) { @@ -91,6 +76,11 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt) ClassT, 0); Context.setObjcClassType(ClassTypedef); + // Synthesize "@class Protocol; + ObjcInterfaceDecl *ProtocolDecl = new ObjcInterfaceDecl(SourceLocation(), 0, + &Context.Idents.get("Protocol"), true); + Context.setObjcProtoType(Context.getObjcInterfaceType(ProtocolDecl)); + // Synthesize "typedef struct objc_object { Class isa; } *id;" RecordDecl *ObjectTag = new RecordDecl(Decl::Struct, SourceLocation(), &IT.get("objc_object"), 0); @@ -111,6 +101,7 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt) &Context.Idents.get("SEL"), SelT, 0); Context.setObjcSelType(SelTypedef); + } TUScope = 0; } diff --git a/Sema/Sema.h b/Sema/Sema.h index 00133f885a..234fc157d8 100644 --- a/Sema/Sema.h +++ b/Sema/Sema.h @@ -277,10 +277,8 @@ private: bool MatchTwoMethodDeclarations(const ObjcMethodDecl *Method, const ObjcMethodDecl *PrevMethod); - /// GetObjcSelType - Getter for the build-in "Protocol *" type. - QualType GetObjcProtoType(SourceLocation Loc = SourceLocation()); - - /// isBuiltinObjcType - Returns true of the type is "id", "SEL", "Class". + /// isBuiltinObjcType - Returns true of the type is "id", "SEL", "Class" + /// or "Protocol". bool isBuiltinObjcType(TypedefDecl *TD); /// AddInstanceMethodToGlobalPool - All instance methods in a translation diff --git a/Sema/SemaExpr.cpp b/Sema/SemaExpr.cpp index 379a033d41..9d3e9eb970 100644 --- a/Sema/SemaExpr.cpp +++ b/Sema/SemaExpr.cpp @@ -2061,9 +2061,10 @@ Sema::ExprResult Sema::ParseObjCProtocolExpression(IdentifierInfo *ProtocolId, return true; } - QualType t = GetObjcProtoType(AtLoc); + QualType t = Context.getObjcProtoType(); if (t.isNull()) return true; + t = Context.getPointerType(t); return new ObjCProtocolExpr(t, PDecl, AtLoc, RParenLoc); } diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h index c4a7c85c6b..c8a80b02f6 100644 --- a/include/clang/AST/ASTContext.h +++ b/include/clang/AST/ASTContext.h @@ -212,7 +212,7 @@ public: void setObjcSelType(TypedefDecl *Decl); QualType getObjcSelType() const { return ObjcSelType; } - void setObjcProtoType(TypedefDecl *Decl); + void setObjcProtoType(QualType QT); QualType getObjcProtoType() const { return ObjcProtoType; } void setObjcClassType(TypedefDecl *Decl); diff --git a/test/Sema/protocol-expr-1.m b/test/Sema/protocol-expr-1.m index 23cb5dd903..dff2866020 100644 --- a/test/Sema/protocol-expr-1.m +++ b/test/Sema/protocol-expr-1.m @@ -1,7 +1,5 @@ // RUN: clang -fsyntax-only -verify %s -typedef struct Protocol Protocol; - @protocol fproto; @protocol p1 diff --git a/test/Sema/protocol-expr-neg-1.m b/test/Sema/protocol-expr-neg-1.m index d59d83fd78..427e74417a 100644 --- a/test/Sema/protocol-expr-neg-1.m +++ b/test/Sema/protocol-expr-neg-1.m @@ -1,6 +1,6 @@ // RUN: clang -fsyntax-only -verify %s -typedef struct Protocol Protocol; +@class Protocol; @protocol fproto;