diff options
| author | Steve Naroff <snaroff@apple.com> | 2007-09-17 20:25:27 +0000 |
|---|---|---|
| committer | Steve Naroff <snaroff@apple.com> | 2007-09-17 20:25:27 +0000 |
| commit | 486760aee3cd6b74617924feb7a360278cd2b1a3 (patch) | |
| tree | a007d0bcd7226fdd80903190527e5fb5f46b27f1 /clang | |
| parent | ff7e4437925549640672f4ea60a7fbd87b77269c (diff) | |
| download | bcm5719-llvm-486760aee3cd6b74617924feb7a360278cd2b1a3.tar.gz bcm5719-llvm-486760aee3cd6b74617924feb7a360278cd2b1a3.zip | |
- Refactored ObjcKeywordInfo into ObjcKeywordInfo, ObjcKeywordDecl, and ObjcKeywordMessage.
- Removed helper ObjcGetSelectorInfo(), moving the code directly into ObjcBuildMethodDeclaration().
- Many refinements to ParseObjCMessageExpression().
- Add ActOnMessageExpression().
Next step, finish the message actions and (finally) create/instantiate an ObjcMessageExpr AST.
llvm-svn: 42050
Diffstat (limited to 'clang')
| -rw-r--r-- | clang/Parse/ParseObjc.cpp | 59 | ||||
| -rw-r--r-- | clang/Sema/Sema.h | 2 | ||||
| -rw-r--r-- | clang/Sema/SemaDecl.cpp | 44 | ||||
| -rw-r--r-- | clang/clang.xcodeproj/project.pbxproj | 1 | ||||
| -rw-r--r-- | clang/include/clang/Parse/Action.h | 26 | ||||
| -rw-r--r-- | clang/include/clang/Parse/DeclSpec.h | 29 |
6 files changed, 104 insertions, 57 deletions
diff --git a/clang/Parse/ParseObjc.cpp b/clang/Parse/ParseObjc.cpp index e396f375e7c..d61d621093d 100644 --- a/clang/Parse/ParseObjc.cpp +++ b/clang/Parse/ParseObjc.cpp @@ -486,12 +486,12 @@ Parser::DeclTy *Parser::ParseObjCMethodDecl(tok::TokenKind mType, ReturnType = ParseObjCTypeName(); IdentifierInfo *selIdent = ParseObjCSelector(); - llvm::SmallVector<ObjcKeywordInfo, 12> KeyInfo; + llvm::SmallVector<ObjcKeywordDecl, 12> KeyInfo; if (Tok.getKind() == tok::colon) { while (1) { - ObjcKeywordInfo KeyInfoDecl; + ObjcKeywordDecl KeyInfoDecl; KeyInfoDecl.SelectorName = selIdent; // Each iteration parses a single keyword argument. @@ -514,11 +514,11 @@ Parser::DeclTy *Parser::ParseObjCMethodDecl(tok::TokenKind mType, KeyInfoDecl.ArgumentName = Tok.getIdentifierInfo(); ConsumeToken(); // Eat the identifier. - // Rather than call out to the actions, try packaging up the info - // locally, like we do for Declarator. - // FIXME: add Actions.BuildObjCKeyword() - + // Rather than call out to the actions, package up the info locally, + // like we do for Declarator. KeyInfo.push_back(KeyInfoDecl); + + // Check for another keyword selector. selIdent = ParseObjCSelector(); if (!selIdent && Tok.getKind() != tok::colon) break; @@ -984,28 +984,52 @@ Parser::ExprResult Parser::ParseObjCExpression() { Parser::ExprResult Parser::ParseObjCMessageExpression() { assert(Tok.getKind() == tok::l_square && "'[' expected"); SourceLocation Loc = ConsumeBracket(); // consume '[' + IdentifierInfo *ReceiverName = 0; + ExprTy *ReceiverExpr = 0; // Parse receiver if (Tok.getKind() == tok::identifier && - Actions.isTypeName(*Tok.getIdentifierInfo(), CurScope)) + Actions.isTypeName(*Tok.getIdentifierInfo(), CurScope)) { + ReceiverName = Tok.getIdentifierInfo(); ConsumeToken(); - else - ParseAssignmentExpression(); + } else { + ExprResult Res = ParseAssignmentExpression(); + if (Res.isInvalid) { + SkipUntil(tok::identifier); + return Res; + } + ReceiverExpr = Res.Val; + } // Parse objc-selector IdentifierInfo *selIdent = ParseObjCSelector(); + llvm::SmallVector<ObjcKeywordMessage, 12> KeyInfo; if (Tok.getKind() == tok::colon) { while (1) { // Each iteration parses a single keyword argument. + ObjcKeywordMessage KeyInfoMess; + KeyInfoMess.SelectorName = selIdent; + if (Tok.getKind() != tok::colon) { Diag(Tok, diag::err_expected_colon); SkipUntil(tok::semi); - return 0; + return true; } - ConsumeToken(); // Eat the ':'. + KeyInfoMess.ColonLoc = ConsumeToken(); // Eat the ':'. /// Parse the expression after ':' - ParseAssignmentExpression(); - IdentifierInfo *keywordSelector = ParseObjCSelector(); + ExprResult Res = ParseAssignmentExpression(); + if (Res.isInvalid) { + SkipUntil(tok::identifier); + return Res; + } + // We have a valid expression. + KeyInfoMess.KeywordExpr = Res.Val; + + // Rather than call out to the actions, package up the info locally, + // like we do for Declarator. + KeyInfo.push_back(KeyInfoMess); - if (!keywordSelector && Tok.getKind() != tok::colon) + // Check for another keyword selector. + selIdent = ParseObjCSelector(); + if (!selIdent && Tok.getKind() != tok::colon) break; // We have a selector or a colon, continue parsing. } @@ -1026,7 +1050,12 @@ Parser::ExprResult Parser::ParseObjCMessageExpression() { return 0; } ConsumeBracket(); // consume ']' - return 0; // FIXME: return a message expr AST! + + if (ReceiverName) + return Actions.ActOnMessageExpression(ReceiverName, + &KeyInfo[0], KeyInfo.size()); + return Actions.ActOnMessageExpression(ReceiverExpr, + &KeyInfo[0], KeyInfo.size()); } Parser::ExprResult Parser::ParseObjCStringLiteral() { diff --git a/clang/Sema/Sema.h b/clang/Sema/Sema.h index 95086534b58..c1d3a3a05a8 100644 --- a/clang/Sema/Sema.h +++ b/clang/Sema/Sema.h @@ -366,7 +366,7 @@ public: DeclTy **allMethods, unsigned allNum); virtual DeclTy *ObjcBuildMethodDeclaration(SourceLocation MethodLoc, tok::TokenKind MethodType, TypeTy *ReturnType, - ObjcKeywordInfo *Keywords, unsigned NumKeywords, + ObjcKeywordDecl *Keywords, unsigned NumKeywords, AttributeList *AttrList); virtual DeclTy *ObjcBuildMethodDeclaration(SourceLocation MethodLoc, tok::TokenKind MethodType, TypeTy *ReturnType, diff --git a/clang/Sema/SemaDecl.cpp b/clang/Sema/SemaDecl.cpp index 22a7c0418db..051ba7665bd 100644 --- a/clang/Sema/SemaDecl.cpp +++ b/clang/Sema/SemaDecl.cpp @@ -1239,41 +1239,33 @@ void Sema::ObjcAddMethodsToClass(DeclTy *ClassDecl, return; } -/// Build objective-c style method name. -static SelectorInfo & - ObjcGetSelectorInfo(ObjcKeywordInfo* KeyInfo, unsigned numKeyInfo, - ASTContext &Context) -{ +Sema::DeclTy *Sema::ObjcBuildMethodDeclaration(SourceLocation MethodLoc, + tok::TokenKind MethodType, TypeTy *ReturnType, + ObjcKeywordDecl *Keywords, unsigned NumKeywords, + AttributeList *AttrList) { + assert(NumKeywords && "Selector must be specified"); + + // Derive the selector name from the keyword declarations. int len=0; char *methodName; - for (unsigned int i = 0; i < numKeyInfo; i++) { - IdentifierInfo *selectorName = KeyInfo[i].SelectorName; - if (selectorName) - len += strlen(selectorName->getName()); + for (unsigned int i = 0; i < NumKeywords; i++) { + if (Keywords[i].SelectorName) + len += strlen(Keywords[i].SelectorName->getName()); len++; } methodName = (char *) alloca (len + 1); methodName[0] = '\0'; - for (unsigned int i = 0; i < numKeyInfo; i++) { - IdentifierInfo *selectorName = KeyInfo[i].SelectorName; - if (selectorName) - strcat(methodName, selectorName->getName()); + for (unsigned int i = 0; i < NumKeywords; i++) { + if (Keywords[i].SelectorName) + strcat(methodName, Keywords[i].SelectorName->getName()); strcat(methodName, ":"); } - return Context.getSelectorInfo(methodName, methodName+len); -} + SelectorInfo &SelName = Context.getSelectorInfo(methodName, methodName+len); - -Sema::DeclTy *Sema::ObjcBuildMethodDeclaration(SourceLocation MethodLoc, - tok::TokenKind MethodType, TypeTy *ReturnType, - ObjcKeywordInfo *Keywords, unsigned NumKeywords, - AttributeList *AttrList) { - assert(NumKeywords && "Selector must be specified"); - SelectorInfo &SelName = ObjcGetSelectorInfo(Keywords, NumKeywords, Context); llvm::SmallVector<ParmVarDecl*, 16> Params; for (unsigned i = 0; i < NumKeywords; i++) { - ObjcKeywordInfo *arg = &Keywords[i]; + ObjcKeywordDecl *arg = &Keywords[i]; // FIXME: arg->AttrList must be stored too! ParmVarDecl* Param = new ParmVarDecl(arg->ColonLoc, arg->ArgumentName, QualType::getFromOpaquePtr(arg->TypeInfo), @@ -1284,9 +1276,9 @@ Sema::DeclTy *Sema::ObjcBuildMethodDeclaration(SourceLocation MethodLoc, Params.push_back(Param); } QualType resultDeclType = QualType::getFromOpaquePtr(ReturnType); - ObjcMethodDecl* ObjcMethod = new ObjcMethodDecl(MethodLoc, - SelName, resultDeclType, - 0, -1, AttrList, MethodType == tok::minus); + ObjcMethodDecl* ObjcMethod; + ObjcMethod = new ObjcMethodDecl(MethodLoc, SelName, resultDeclType, + 0, -1, AttrList, MethodType == tok::minus); ObjcMethod->setMethodParams(&Params[0], NumKeywords); return ObjcMethod; } diff --git a/clang/clang.xcodeproj/project.pbxproj b/clang/clang.xcodeproj/project.pbxproj index b10e99d777b..6ccef0836f7 100644 --- a/clang/clang.xcodeproj/project.pbxproj +++ b/clang/clang.xcodeproj/project.pbxproj @@ -708,7 +708,6 @@ 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/clang/include/clang/Parse/Action.h b/clang/include/clang/Parse/Action.h index e16d3f0fe97..2d7e8f452c6 100644 --- a/clang/include/clang/Parse/Action.h +++ b/clang/include/clang/Parse/Action.h @@ -21,7 +21,8 @@ namespace clang { // Semantic. class DeclSpec; class Declarator; - struct ObjcKeywordInfo; + struct ObjcKeywordDecl; + struct ObjcKeywordMessage; class AttributeList; // Parse. class Scope; @@ -145,12 +146,6 @@ public: return 0; } - virtual DeclTy *ObjcClassDeclaration(Scope *S, SourceLocation AtClassLoc, - IdentifierInfo **IdentList, - unsigned NumElts) { - return 0; - } - //===--------------------------------------------------------------------===// // Type Parsing Callbacks. //===--------------------------------------------------------------------===// @@ -455,7 +450,7 @@ public: } virtual DeclTy *ObjcBuildMethodDeclaration( SourceLocation MethodLoc, tok::TokenKind MethodType, TypeTy *ReturnType, - ObjcKeywordInfo *Keywords, unsigned NumKeywords, + ObjcKeywordDecl *Keywords, unsigned NumKeywords, AttributeList *AttrList) { return 0; } @@ -464,6 +459,21 @@ public: IdentifierInfo *SelectorName, AttributeList *AttrList) { return 0; } + // This actions handles keyword message to classes. + virtual DeclTy *ActOnMessageExpression(IdentifierInfo *receivingClassName, + ObjcKeywordMessage *Keywords, unsigned NumKeywords) { + return 0; + } + // This action handles keyword messages to instances. + virtual DeclTy *ActOnMessageExpression(ExprTy *receiver, + ObjcKeywordMessage *Keywords, unsigned NumKeywords) { + return 0; + } + virtual DeclTy *ObjcClassDeclaration(Scope *S, SourceLocation AtClassLoc, + IdentifierInfo **IdentList, + unsigned NumElts) { + return 0; + } virtual void ObjCStartCategoryInterface() { // FIXME return; } diff --git a/clang/include/clang/Parse/DeclSpec.h b/clang/include/clang/Parse/DeclSpec.h index de22360120e..bf197186ba8 100644 --- a/clang/include/clang/Parse/DeclSpec.h +++ b/clang/include/clang/Parse/DeclSpec.h @@ -566,20 +566,37 @@ struct ObjcKeywordInfo { IdentifierInfo *SelectorName; // optional SourceLocation SelectorLoc; SourceLocation ColonLoc; + + ObjcKeywordInfo() {} + ObjcKeywordInfo(IdentifierInfo *selName, SourceLocation sLoc, + SourceLocation cLoc) + : SelectorName(selName), SelectorLoc(sLoc), ColonLoc(cLoc) {} +}; + +struct ObjcKeywordDecl : ObjcKeywordInfo { Action::TypeTy *TypeInfo; // optional - bool InvalidType; IdentifierInfo *ArgumentName; AttributeList *AttrList; + bool InvalidType; // FIXME: is this used? - ObjcKeywordInfo() {} - ObjcKeywordInfo(IdentifierInfo *selName, SourceLocation sLoc, + ObjcKeywordDecl() {} + ObjcKeywordDecl(IdentifierInfo *selName, SourceLocation sLoc, SourceLocation cLoc, Action::TypeTy *tInfo, IdentifierInfo *argName, AttributeList *aList) - : SelectorName(selName), SelectorLoc(sLoc), ColonLoc(cLoc), TypeInfo(tInfo), - ArgumentName(argName), AttrList(aList) { + : ObjcKeywordInfo(selName, sLoc, cLoc), + TypeInfo(tInfo), ArgumentName(argName), AttrList(aList) { } }; + +struct ObjcKeywordMessage : ObjcKeywordInfo { + Action::ExprTy *KeywordExpr; + + ObjcKeywordMessage() {} + ObjcKeywordMessage(IdentifierInfo *selName, SourceLocation sLoc, + SourceLocation cLoc, Action::ExprTy *expr) + : ObjcKeywordInfo(selName, sLoc, cLoc), KeywordExpr(expr) {} +}; -} // end namespace clang +} // end namespace clang #endif |

