]> granicus.if.org Git - clang/commitdiff
Added class context to method declarations. Provide "interface *" type
authorFariborz Jahanian <fjahanian@apple.com>
Fri, 9 Nov 2007 19:52:12 +0000 (19:52 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Fri, 9 Nov 2007 19:52:12 +0000 (19:52 +0000)
to 'self' method of instance methods.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@43957 91177308-0d34-0410-b5e6-96231b3b80d8

Parse/ParseObjc.cpp
Sema/Sema.h
Sema/SemaDecl.cpp
Sema/SemaType.cpp
include/clang/AST/DeclObjC.h
include/clang/Parse/Action.h
include/clang/Parse/Parser.h
test/Sema/method-def-1.m [new file with mode: 0644]

index 1f38c23ad503fcae7ee6367b72df26a86e7784b4..a3fb0e80abdd4efd84dab48c259c543f4b98e6fb 100644 (file)
@@ -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);
index 28cf9c7b190556de674bbf244d001a38dcc95b98..50a604619cad364daf0467c7bcec271c3f235aea 100644 (file)
@@ -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().
index 0098f8b9cb37ae8c0fbc94dfcf5e02002589f730..41f509ad959f357ad1d4826c589c47fdf9e22d91 100644 (file)
@@ -1047,11 +1047,14 @@ Sema::DeclTy *Sema::ObjcActOnStartOfFunctionDef(Scope *FnBodyScope, DeclTy *D) {
   llvm::SmallVector<ParmVarDecl*, 16> 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<Decl*>(ClassDecl);
+  ObjcInterfaceDecl *IDecl = 0;
+  if (isa<ObjcInterfaceDecl>(CDecl))
+    IDecl = cast<ObjcInterfaceDecl>(CDecl);
+  else if (isa<ObjcCategoryDecl>(CDecl))
+    IDecl = cast<ObjcCategoryDecl>(CDecl)->getClassInterface();
+  else if (isa<ObjcImplementationDecl>(CDecl))
+    IDecl = cast<ObjcImplementationDecl>(CDecl)->getClassInterface();
+  else if (isa<ObjcCategoryImplDecl>(CDecl))
+    IDecl = cast<ObjcCategoryImplDecl>(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 : 
index 6398c6f71ea4ca621851fe59f23142ed6bdbbce3..71ec3f395d618402dadcf022fd36d21dd7bb0c61 100644 (file)
@@ -333,9 +333,11 @@ QualType Sema::ObjcGetTypeForDeclarator(DeclTy *D, Scope *S) {
   llvm::SmallVector<QualType, 16> 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());
index 4206d08aa0bf8d55cb3e325e871d242252d08d34..fcc1dbf2f6d7e01e6af4aeca264c4117e4f8312a 100644 (file)
@@ -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; }
 
index 34a1a3320d1048b61073e38016b0583c3325b4eb..17bf9b96438e636c28d870d7b88921ad562a35a7 100644 (file)
@@ -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.
index 202a7f0c624e4b27c37c6e37ff4f493f0a11177c..e453aa769e696bd6cb13c20daa0d9fe6e028c424 100644 (file)
@@ -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 (file)
index 0000000..1658a7b
--- /dev/null
@@ -0,0 +1,8 @@
+@interface foo
+- (int)meth;
+@end
+
+@implementation foo
+- (int) meth { return [self meth]; }
+@end
+