From: Fariborz Jahanian Date: Fri, 9 Nov 2007 19:52:12 +0000 (+0000) Subject: Added class context to method declarations. Provide "interface *" type X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=1f7b6f88f18d7f6b10265acec5d41c4ed1897487;p=clang Added class context to method declarations. Provide "interface *" type to 'self' method of instance methods. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@43957 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/Parse/ParseObjc.cpp b/Parse/ParseObjc.cpp index 1f38c23ad5..a3fb0e80ab 100644 --- a/Parse/ParseObjc.cpp +++ b/Parse/ParseObjc.cpp @@ -416,7 +416,7 @@ Parser::DeclTy *Parser::ParseObjCMethodPrototype(DeclTy *IDecl, tok::TokenKind methodType = Tok.getKind(); SourceLocation mLoc = ConsumeToken(); - DeclTy *MDecl = ParseObjCMethodDecl(mLoc, methodType, MethodImplKind); + DeclTy *MDecl = ParseObjCMethodDecl(mLoc, methodType, IDecl, MethodImplKind); // Since this rule is used for both method declarations and definitions, // the caller is (optionally) responsible for consuming the ';'. return MDecl; @@ -550,7 +550,8 @@ Parser::TypeTy *Parser::ParseObjCTypeName(ObjcDeclSpec &DS) { /// __attribute__((unused)) /// Parser::DeclTy *Parser::ParseObjCMethodDecl(SourceLocation mLoc, - tok::TokenKind mType, + tok::TokenKind mType, + DeclTy *IDecl, tok::ObjCKeywordKind MethodImplKind) { // Parse the return type. @@ -574,7 +575,7 @@ Parser::DeclTy *Parser::ParseObjCMethodDecl(SourceLocation mLoc, Selector Sel = PP.getSelectorTable().getNullarySelector(SelIdent); return Actions.ActOnMethodDeclaration(mLoc, Tok.getLocation(), - mType, DSRet, ReturnType, Sel, + mType, IDecl, DSRet, ReturnType, Sel, 0, 0, 0, MethodAttrs, MethodImplKind); } @@ -645,7 +646,7 @@ Parser::DeclTy *Parser::ParseObjCMethodDecl(SourceLocation mLoc, Selector Sel = PP.getSelectorTable().getSelector(KeyIdents.size(), &KeyIdents[0]); return Actions.ActOnMethodDeclaration(mLoc, Tok.getLocation(), - mType, DSRet, ReturnType, Sel, + mType, IDecl, DSRet, ReturnType, Sel, &ArgTypeQuals[0], &KeyTypes[0], &ArgNames[0], MethodAttrs, MethodImplKind); diff --git a/Sema/Sema.h b/Sema/Sema.h index 28cf9c7b19..50a604619c 100644 --- a/Sema/Sema.h +++ b/Sema/Sema.h @@ -552,7 +552,8 @@ public: virtual DeclTy *ActOnMethodDeclaration( SourceLocation BeginLoc, // location of the + or -. SourceLocation EndLoc, // location of the ; or {. - tok::TokenKind MethodType, ObjcDeclSpec &ReturnQT, TypeTy *ReturnType, + tok::TokenKind MethodType, + DeclTy *ClassDecl, ObjcDeclSpec &ReturnQT, TypeTy *ReturnType, Selector Sel, // optional arguments. The number of types/arguments is obtained // from the Sel.getNumArgs(). diff --git a/Sema/SemaDecl.cpp b/Sema/SemaDecl.cpp index 0098f8b9cb..41f509ad95 100644 --- a/Sema/SemaDecl.cpp +++ b/Sema/SemaDecl.cpp @@ -1047,11 +1047,14 @@ Sema::DeclTy *Sema::ObjcActOnStartOfFunctionDef(Scope *FnBodyScope, DeclTy *D) { llvm::SmallVector Params; ParmVarDecl *PDecl; // Insert the invisible arguments! - if (MDecl->isInstance()) - // FIXME: type is wrong. + if (MDecl->isInstance()) { + QualType selfTy = Context.getObjcInterfaceType(MDecl->getClassInterface()); + selfTy = Context.getPointerType(selfTy); PDecl = new ParmVarDecl(SourceLocation(/*FIXME*/), &Context.Idents.get("self"), - Context.getObjcIdType(), VarDecl::None, 0); + selfTy, + VarDecl::None, 0); + } else PDecl = new ParmVarDecl(SourceLocation(/*FIXME*/), &Context.Idents.get("self"), @@ -2179,7 +2182,8 @@ CvtQTToAstBitMask(ObjcDeclSpec::ObjcDeclQualifier PQTVal) { Sema::DeclTy *Sema::ActOnMethodDeclaration( SourceLocation MethodLoc, SourceLocation EndLoc, - tok::TokenKind MethodType, ObjcDeclSpec &ReturnQT, TypeTy *ReturnType, + tok::TokenKind MethodType, DeclTy *ClassDecl, + ObjcDeclSpec &ReturnQT, TypeTy *ReturnType, Selector Sel, // optional arguments. The number of types/arguments is obtained // from the Sel.getNumArgs(). @@ -2207,9 +2211,22 @@ Sema::DeclTy *Sema::ActOnMethodDeclaration( resultDeclType = QualType::getFromOpaquePtr(ReturnType); else // get the type for "id". resultDeclType = Context.getObjcIdType(); - + + Decl *CDecl = static_cast(ClassDecl); + ObjcInterfaceDecl *IDecl = 0; + if (isa(CDecl)) + IDecl = cast(CDecl); + else if (isa(CDecl)) + IDecl = cast(CDecl)->getClassInterface(); + else if (isa(CDecl)) + IDecl = cast(CDecl)->getClassInterface(); + else if (isa(CDecl)) + IDecl = cast(CDecl)->getClassInterface(); + ObjcMethodDecl* ObjcMethod = new ObjcMethodDecl(MethodLoc, EndLoc, Sel, - resultDeclType, 0, -1, AttrList, + resultDeclType, + IDecl, + 0, -1, AttrList, MethodType == tok::minus, MethodDeclKind == tok::objc_optional ? ObjcMethodDecl::Optional : diff --git a/Sema/SemaType.cpp b/Sema/SemaType.cpp index 6398c6f71e..71ec3f395d 100644 --- a/Sema/SemaType.cpp +++ b/Sema/SemaType.cpp @@ -333,9 +333,11 @@ QualType Sema::ObjcGetTypeForDeclarator(DeclTy *D, Scope *S) { llvm::SmallVector ArgTys; // Add the first two invisible argument types for self and _cmd. - if (MDecl->isInstance()) - // FIXME: interface-name * - ArgTys.push_back(Context.getObjcIdType()); + if (MDecl->isInstance()) { + QualType selfTy = Context.getObjcInterfaceType(MDecl->getClassInterface()); + selfTy = Context.getPointerType(selfTy); + ArgTys.push_back(selfTy); + } else ArgTys.push_back(Context.getObjcIdType()); ArgTys.push_back(Context.getObjcSelType()); diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h index 4206d08aa0..fcc1dbf2f6 100644 --- a/include/clang/AST/DeclObjC.h +++ b/include/clang/AST/DeclObjC.h @@ -239,6 +239,9 @@ private: /// in, inout, etc. ObjcDeclQualifier objcDeclQualifier : 6; + // @interface decl this Method belongs to. + ObjcInterfaceDecl *ClassInterface; + // A unigue name for this method. Selector SelName; @@ -256,6 +259,7 @@ private: public: ObjcMethodDecl(SourceLocation beginLoc, SourceLocation endLoc, Selector SelInfo, QualType T, + ObjcInterfaceDecl *interfaceDecl, ParmVarDecl **paramInfo = 0, int numParams=-1, AttributeList *M = 0, bool isInstance = true, ImplementationControl impControl = None, @@ -263,6 +267,7 @@ public: : Decl(ObjcMethod, beginLoc), IsInstance(isInstance), DeclImplementation(impControl), objcDeclQualifier(OBJC_TQ_None), + ClassInterface(interfaceDecl), SelName(SelInfo), MethodDeclType(T), ParamInfo(paramInfo), NumMethodParams(numParams), MethodAttrs(M), EndLoc(endLoc) {} @@ -275,6 +280,8 @@ public: SourceLocation getLocStart() const { return getLocation(); } SourceLocation getLocEnd() const { return EndLoc; } + ObjcInterfaceDecl *const getClassInterface() const { return ClassInterface; } + 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 34a1a3320d..17bf9b9643 100644 --- a/include/clang/Parse/Action.h +++ b/include/clang/Parse/Action.h @@ -561,6 +561,7 @@ public: SourceLocation BeginLoc, // location of the + or -. SourceLocation EndLoc, // location of the ; or {. tok::TokenKind MethodType, // tok::minus for instance, tok::plus for class. + DeclTy *ClassDecl, // class this methods belongs to. ObjcDeclSpec &ReturnQT, // for return type's in inout etc. 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 202a7f0c62..e453aa769e 100644 --- a/include/clang/Parse/Parser.h +++ b/include/clang/Parse/Parser.h @@ -297,6 +297,7 @@ private: DeclTy *ParseObjCMethodPrototype(DeclTy *classOrCat, tok::ObjCKeywordKind MethodImplKind = tok::objc_not_keyword); DeclTy *ParseObjCMethodDecl(SourceLocation mLoc, tok::TokenKind mType, + DeclTy *classDecl, tok::ObjCKeywordKind MethodImplKind = tok::objc_not_keyword); void ParseObjCPropertyAttribute(ObjcDeclSpec &DS); DeclTy *ParseObjCPropertyDecl(DeclTy *interfaceDecl, SourceLocation AtLoc); diff --git a/test/Sema/method-def-1.m b/test/Sema/method-def-1.m new file mode 100644 index 0000000000..1658a7b50d --- /dev/null +++ b/test/Sema/method-def-1.m @@ -0,0 +1,8 @@ +@interface foo +- (int)meth; +@end + +@implementation foo +- (int) meth { return [self meth]; } +@end +