From: Steve Naroff Date: Fri, 26 Oct 2007 20:53:56 +0000 (+0000) Subject: Start rewriting ObjC interfaces. As a start, we comment out all the methods. This... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=bef1185418705e16012b3dd50cd7c260c8d6b79c;p=clang Start rewriting ObjC interfaces. As a start, we comment out all the methods. This involved refining how the parser/AST passes/manages SourceLocations for ObjcMethodDecl's. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@43404 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/Driver/RewriteTest.cpp b/Driver/RewriteTest.cpp index 95b05ba0f4..6ccc23ae09 100644 --- a/Driver/RewriteTest.cpp +++ b/Driver/RewriteTest.cpp @@ -58,6 +58,7 @@ namespace { void RewriteInclude(SourceLocation Loc); void RewriteTabs(); void RewriteForwardClassDecl(ObjcClassDecl *Dcl); + void RewriteInterfaceDecl(ObjcInterfaceDecl *Dcl); // Expression Rewriting. Stmt *RewriteFunctionBody(Stmt *S); @@ -120,8 +121,9 @@ void RewriteTest::HandleTopLevelDecl(Decl *D) { GetClassFunctionDecl = FD; else if (strcmp(FD->getName(), "sel_getUid") == 0) SelGetUidFunctionDecl = FD; + } else if (ObjcInterfaceDecl *MD = dyn_cast(D)) { + RewriteInterfaceDecl(MD); } - // If we have a decl in the main file, see if we should rewrite it. if (SM->getDecomposedFileLoc(Loc).first == MainFileID) return HandleDeclInMainFile(D); @@ -263,6 +265,31 @@ void RewriteTest::RewriteForwardClassDecl(ObjcClassDecl *ClassDecl) { typedefString.c_str(), typedefString.size()); } +void RewriteTest::RewriteInterfaceDecl(ObjcInterfaceDecl *ClassDecl) { + int nInstanceMethods = ClassDecl->getNumInstanceMethods(); + ObjcMethodDecl **instanceMethods = ClassDecl->getInstanceMethods(); + + for (int i = 0; i < nInstanceMethods; i++) { + ObjcMethodDecl *instanceMethod = instanceMethods[i]; + SourceLocation Loc = instanceMethod->getLocStart(); + + Rewrite.ReplaceText(Loc, 0, "// ", 3); + + // FIXME: handle methods that are declared across multiple lines. + } + int nClassMethods = ClassDecl->getNumClassMethods(); + ObjcMethodDecl **classMethods = ClassDecl->getClassMethods(); + + for (int i = 0; i < nClassMethods; i++) { + ObjcMethodDecl *classMethod = classMethods[i]; + SourceLocation Loc = classMethod->getLocStart(); + + Rewrite.ReplaceText(Loc, 0, "// ", 3); + + // FIXME: handle methods that are declared across multiple lines. + } +} + //===----------------------------------------------------------------------===// // Function Body / Expression rewriting //===----------------------------------------------------------------------===// @@ -290,11 +317,11 @@ Stmt *RewriteTest::RewriteFunctionBody(Stmt *S) { messString += "// "; messString.append(startBuf, endBuf-startBuf+1); messString += "\n"; - + // FIXME: Missing definition of Rewrite.InsertText(clang::SourceLocation, char const*, unsigned int). // Rewrite.InsertText(startLoc, messString.c_str(), messString.size()); // Tried this, but it didn't work either... - // Rewrite.ReplaceText(startLoc, 0, messString.c_str(), messString.size()); + Rewrite.ReplaceText(startLoc, 0, messString.c_str(), messString.size()); return RewriteMessageExpr(MessExpr); } // Return this stmt unmodified. diff --git a/Parse/ParseObjc.cpp b/Parse/ParseObjc.cpp index 2fd4446ae6..4abf8fd43d 100644 --- a/Parse/ParseObjc.cpp +++ b/Parse/ParseObjc.cpp @@ -379,9 +379,9 @@ Parser::DeclTy *Parser::ParseObjCMethodPrototype(DeclTy *IDecl, assert((Tok.is(tok::minus) || Tok.is(tok::plus)) && "expected +/-"); tok::TokenKind methodType = Tok.getKind(); - ConsumeToken(); + SourceLocation mLoc = ConsumeToken(); - DeclTy *MDecl = ParseObjCMethodDecl(methodType, MethodImplKind); + DeclTy *MDecl = ParseObjCMethodDecl(mLoc, methodType, MethodImplKind); // Since this rule is used for both method declarations and definitions, // the caller is (optionally) responsible for consuming the ';'. return MDecl; @@ -526,15 +526,16 @@ Parser::TypeTy *Parser::ParseObjCTypeName() { /// objc-keyword-attributes: [OBJC2] /// __attribute__((unused)) /// -Parser::DeclTy *Parser::ParseObjCMethodDecl(tok::TokenKind mType, +Parser::DeclTy *Parser::ParseObjCMethodDecl(SourceLocation mLoc, + tok::TokenKind mType, tok::ObjCKeywordKind MethodImplKind) { // Parse the return type. TypeTy *ReturnType = 0; if (Tok.is(tok::l_paren)) ReturnType = ParseObjCTypeName(); - SourceLocation mLoc; - IdentifierInfo *SelIdent = ParseObjCSelector(mLoc); + SourceLocation selLoc; + IdentifierInfo *SelIdent = ParseObjCSelector(selLoc); if (Tok.isNot(tok::colon)) { if (!SelIdent) { Diag(Tok, diag::err_expected_ident); // missing selector name. @@ -548,7 +549,8 @@ Parser::DeclTy *Parser::ParseObjCMethodDecl(tok::TokenKind mType, MethodAttrs = ParseAttributes(); Selector Sel = PP.getSelectorTable().getNullarySelector(SelIdent); - return Actions.ActOnMethodDeclaration(mLoc, mType, ReturnType, Sel, + return Actions.ActOnMethodDeclaration(mLoc, Tok.getLocation(), + mType, ReturnType, Sel, 0, 0, MethodAttrs, MethodImplKind); } @@ -614,7 +616,8 @@ Parser::DeclTy *Parser::ParseObjCMethodDecl(tok::TokenKind mType, Selector Sel = PP.getSelectorTable().getSelector(KeyIdents.size(), &KeyIdents[0]); - return Actions.ActOnMethodDeclaration(mLoc, mType, ReturnType, Sel, + return Actions.ActOnMethodDeclaration(mLoc, Tok.getLocation(), + mType, ReturnType, Sel, &KeyTypes[0], &ArgNames[0], MethodAttrs, MethodImplKind); } diff --git a/Sema/Sema.h b/Sema/Sema.h index 596173dda2..70d2f55ff8 100644 --- a/Sema/Sema.h +++ b/Sema/Sema.h @@ -516,7 +516,9 @@ public: virtual void ActOnAddMethodsToObjcDecl(Scope* S, DeclTy *ClassDecl, DeclTy **allMethods, unsigned allNum); - virtual DeclTy *ActOnMethodDeclaration(SourceLocation MethodLoc, + virtual DeclTy *ActOnMethodDeclaration( + SourceLocation BeginLoc, // location of the + or -. + SourceLocation EndLoc, // location of the ; or {. tok::TokenKind MethodType, TypeTy *ReturnType, Selector Sel, // optional arguments. The number of types/arguments is obtained // from the Sel.getNumArgs(). @@ -528,7 +530,7 @@ public: // is obtained from Sel.getNumArgs(). virtual ExprResult ActOnClassMessage( IdentifierInfo *receivingClassName, Selector Sel, - SourceLocation lbrac, SourceLocation rbrac, ExprTy **ArgExprs); + SourceLocation lbrac, SourceLocation rbrac, ExprTy **ArgExprs); // ActOnInstanceMessage - used for both unary and keyword messages. // ArgExprs is optional - if it is present, the number of expressions diff --git a/Sema/SemaDecl.cpp b/Sema/SemaDecl.cpp index b2845978bf..12efd458b2 100644 --- a/Sema/SemaDecl.cpp +++ b/Sema/SemaDecl.cpp @@ -1941,7 +1941,8 @@ void Sema::ActOnAddMethodsToObjcDecl(Scope* S, DeclTy *classDecl, } } -Sema::DeclTy *Sema::ActOnMethodDeclaration(SourceLocation MethodLoc, +Sema::DeclTy *Sema::ActOnMethodDeclaration( + SourceLocation MethodLoc, SourceLocation EndLoc, tok::TokenKind MethodType, TypeTy *ReturnType, Selector Sel, // optional arguments. The number of types/arguments is obtained // from the Sel.getNumArgs(). @@ -1968,7 +1969,7 @@ Sema::DeclTy *Sema::ActOnMethodDeclaration(SourceLocation MethodLoc, else // get the type for "id". resultDeclType = GetObjcIdType(MethodLoc); - ObjcMethodDecl* ObjcMethod = new ObjcMethodDecl(MethodLoc, Sel, + ObjcMethodDecl* ObjcMethod = new ObjcMethodDecl(MethodLoc, EndLoc, Sel, resultDeclType, 0, -1, AttrList, MethodType == tok::minus, MethodDeclKind == tok::objc_optional ? diff --git a/clang.xcodeproj/project.pbxproj b/clang.xcodeproj/project.pbxproj index fe4cf8d85b..de41b4628d 100644 --- a/clang.xcodeproj/project.pbxproj +++ b/clang.xcodeproj/project.pbxproj @@ -756,7 +756,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/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h index 40a2d9643c..6157187405 100644 --- a/include/clang/AST/DeclObjC.h +++ b/include/clang/AST/DeclObjC.h @@ -219,19 +219,25 @@ private: /// List of attributes for this method declaration. AttributeList *MethodAttrs; + SourceLocation EndLoc; // the location of the ';' or '{'. public: - ObjcMethodDecl(SourceLocation L, Selector SelInfo, QualType T, + ObjcMethodDecl(SourceLocation beginLoc, SourceLocation endLoc, + Selector SelInfo, QualType T, ParmVarDecl **paramInfo = 0, int numParams=-1, AttributeList *M = 0, bool isInstance = true, ImplementationControl impControl = None, Decl *PrevDecl = 0) - : Decl(ObjcMethod, L), + : Decl(ObjcMethod, beginLoc), IsInstance(isInstance), DeclImplementation(impControl), SelName(SelInfo), MethodDeclType(T), ParamInfo(paramInfo), NumMethodParams(numParams), - MethodAttrs(M) {} + MethodAttrs(M), EndLoc(endLoc) {} virtual ~ObjcMethodDecl(); + // Location information, modeled after the Stmt API. + SourceLocation getLocStart() const { return getLocation(); } + SourceLocation getLocEnd() const { return EndLoc; } + Selector getSelector() const { return SelName; } QualType getResultType() const { return MethodDeclType; } diff --git a/include/clang/Parse/Action.h b/include/clang/Parse/Action.h index e8c943d624..24b47c660f 100644 --- a/include/clang/Parse/Action.h +++ b/include/clang/Parse/Action.h @@ -519,7 +519,8 @@ public: } // ActOnMethodDeclaration - called for all method declarations. virtual DeclTy *ActOnMethodDeclaration( - SourceLocation MethodLoc, + SourceLocation BeginLoc, // location of the + or -. + SourceLocation EndLoc, // location of the ; or {. tok::TokenKind MethodType, // tok::minus for instance, tok::plus for class. TypeTy *ReturnType, // the method return type. Selector Sel, // a unique name for the method. diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h index 8c0b8e47bf..a41d357215 100644 --- a/include/clang/Parse/Parser.h +++ b/include/clang/Parse/Parser.h @@ -295,7 +295,7 @@ private: void ParseObjCMethodRequirement(); DeclTy *ParseObjCMethodPrototype(DeclTy *classOrCat, tok::ObjCKeywordKind MethodImplKind = tok::objc_not_keyword); - DeclTy *ParseObjCMethodDecl(tok::TokenKind mType, + DeclTy *ParseObjCMethodDecl(SourceLocation mLoc, tok::TokenKind mType, tok::ObjCKeywordKind MethodImplKind = tok::objc_not_keyword); void ParseObjCPropertyAttribute(DeclTy *interfaceDecl); void ParseObjCPropertyDecl(DeclTy *interfaceDecl);