From: Fariborz Jahanian Date: Fri, 5 Oct 2007 21:01:53 +0000 (+0000) Subject: This is the first patch toward supporting protocol conforming X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=245f92a8867c02378ab485ac256ca2315a0ef94d;p=clang This is the first patch toward supporting protocol conforming objective-c types. It also removes use of Scope* parameter in getObjCProtocolDecl. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@42649 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/Parse/ParseDecl.cpp b/Parse/ParseDecl.cpp index db568df26e..8bdcd4e652 100644 --- a/Parse/ParseDecl.cpp +++ b/Parse/ParseDecl.cpp @@ -409,6 +409,10 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS) { if (Tok.getKind() == tok::less) { llvm::SmallVector ProtocolRefs; ParseObjCProtocolReferences(ProtocolRefs); + Actions.ActOnFindProtocolDeclaration(CurScope, + Loc, + &ProtocolRefs[0], + ProtocolRefs.size()); } continue; } diff --git a/Sema/Sema.h b/Sema/Sema.h index 7a6d62fac2..6d38e629e3 100644 --- a/Sema/Sema.h +++ b/Sema/Sema.h @@ -429,6 +429,11 @@ public: SourceLocation AtProtocolLoc, IdentifierInfo **IdentList, unsigned NumElts); + + virtual DeclTy **ActOnFindProtocolDeclaration(Scope *S, + SourceLocation TypeLoc, + IdentifierInfo **ProtocolId, + unsigned NumProtocols); virtual void ActOnAddMethodsToObjcDecl(Scope* S, DeclTy *ClassDecl, DeclTy **allMethods, unsigned allNum); diff --git a/Sema/SemaDecl.cpp b/Sema/SemaDecl.cpp index b827732b87..8f743789e8 100644 --- a/Sema/SemaDecl.cpp +++ b/Sema/SemaDecl.cpp @@ -104,8 +104,14 @@ ObjcProtocolDecl *Sema::getObjCProtocolDecl(Scope *S, IdentifierInfo *Id, SourceLocation IdLoc) { // Note that Protocols have their own namespace. - ScopedDecl *PrDecl = LookupScopedDecl(Id, Decl::IDNS_Protocol, - IdLoc, S); + ScopedDecl *PrDecl = NULL; + for (ScopedDecl *D = Id->getFETokenInfo(); D; D = D->getNext()) { + if (D->getIdentifierNamespace() == Decl::IDNS_Protocol) { + PrDecl = D; + break; + } + } + if (PrDecl && !isa(PrDecl)) PrDecl = 0; return cast_or_null(static_cast(PrDecl)); @@ -1007,6 +1013,24 @@ Sema::DeclTy *Sema::ActOnStartProtocolInterface(Scope* S, return PDecl; } +/// ActOnFindProtocolDeclaration - This routine looks for a previously +/// declared protocol and returns it. If not found, issues diagnostic. +/// Will build a list of previously protocol declarations found in the list. +Action::DeclTy ** +Sema::ActOnFindProtocolDeclaration(Scope *S, + SourceLocation TypeLoc, + IdentifierInfo **ProtocolId, + unsigned NumProtocols) { + for (unsigned i = 0; i != NumProtocols; ++i) { + ObjcProtocolDecl *PDecl = getObjCProtocolDecl(S, ProtocolId[i], + TypeLoc); + if (!PDecl) + Diag(TypeLoc, diag::err_undeclared_protocol, + ProtocolId[i]->getName()); + } + return 0; +} + /// ActOnForwardProtocolDeclaration - /// Scope will always be top level file scope. Action::DeclTy * diff --git a/clang.xcodeproj/project.pbxproj b/clang.xcodeproj/project.pbxproj index e36c144220..09ddf1c7e7 100644 --- a/clang.xcodeproj/project.pbxproj +++ b/clang.xcodeproj/project.pbxproj @@ -242,7 +242,7 @@ DE06B73D0A8307640050E87E /* LangOptions.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = LangOptions.h; sourceTree = ""; }; DE06BECA0A854E4B0050E87E /* Scope.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Scope.h; path = clang/Parse/Scope.h; sourceTree = ""; }; DE06D42F0A8BB52D0050E87E /* Parser.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Parser.cpp; path = Parse/Parser.cpp; sourceTree = ""; }; - DE06E8130A8FF9330050E87E /* Action.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Action.h; path = clang/Parse/Action.h; sourceTree = ""; }; + DE06E8130A8FF9330050E87E /* Action.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = Action.h; path = clang/Parse/Action.h; sourceTree = ""; tabWidth = 8; usesTabs = 0; }; DE0FCA620A95859D00248FD5 /* Expr.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Expr.h; path = clang/AST/Expr.h; sourceTree = ""; }; DE0FCB330A9C21F100248FD5 /* Expr.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Expr.cpp; path = AST/Expr.cpp; sourceTree = ""; }; DE1732FF0B068B700080B521 /* ASTContext.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ASTContext.cpp; path = AST/ASTContext.cpp; sourceTree = ""; }; @@ -737,6 +737,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/Basic/DiagnosticKinds.def b/include/clang/Basic/DiagnosticKinds.def index 389238bf05..9238e23e63 100644 --- a/include/clang/Basic/DiagnosticKinds.def +++ b/include/clang/Basic/DiagnosticKinds.def @@ -442,6 +442,8 @@ DIAG(error_duplicate_method_decl, ERROR, "duplicate declaration of method '%0'") DIAG(err_previous_declaration, ERROR, "previous declaration is here") +DIAG(err_undeclared_protocol, ERROR, + "cannot find protocol declaration for '%0'") //===----------------------------------------------------------------------===// diff --git a/include/clang/Parse/Action.h b/include/clang/Parse/Action.h index 515935c4f0..204bd6cfb5 100644 --- a/include/clang/Parse/Action.h +++ b/include/clang/Parse/Action.h @@ -555,6 +555,17 @@ public: return 0; } + /// ActOnFindProtocolDeclaration - This routine looks for a previously + /// declared protocol and returns it. If not found, issues diagnostic. + /// Will build a list of previously protocol declarations found in the list. + virtual DeclTy **ActOnFindProtocolDeclaration(Scope *S, + SourceLocation TypeLoc, + IdentifierInfo **ProtocolId, + unsigned NumProtocols) { + return 0; + } + + //===----------------------- Obj-C Expressions --------------------------===// virtual ExprResult ParseObjCStringLiteral(ExprTy *string) { return 0; diff --git a/test/Sema/undefined-protocol-type-1.m b/test/Sema/undefined-protocol-type-1.m new file mode 100644 index 0000000000..117f418ab1 --- /dev/null +++ b/test/Sema/undefined-protocol-type-1.m @@ -0,0 +1,9 @@ +// RUN: clang -fsyntax-only -verify %s + +@protocol p1, p4; +@protocol p2 @end + +@interface T +- (T*) meth; // expected-error {{cannot find protocol declaration for 'p3'}} +- (T*) meth; // expected-error {{cannot find protocol declaration for 'p3'}} +@end