First patch toward rewriting of method definitions. This is work in progress.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@43915 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/Sema/SemaDecl.cpp b/Sema/SemaDecl.cpp
index 4892847..4f7ffc3 100644
--- a/Sema/SemaDecl.cpp
+++ b/Sema/SemaDecl.cpp
@@ -545,6 +545,42 @@
 }
 
 Sema::DeclTy *
+Sema::ObjcActOnDeclarator(Scope *S, DeclTy *D, DeclTy *lastDecl) {
+  ObjcMethodDecl *MDecl = dyn_cast<ObjcMethodDecl>(static_cast<Decl *>(D));
+  
+  ScopedDecl *LastDeclarator = dyn_cast_or_null<ScopedDecl>((Decl *)lastDecl);
+  const char *name = MDecl->getSelector().getName().c_str();
+  IdentifierInfo *II = &Context.Idents.get(name);
+  assert (II && "ObjcActOnDeclarator - selector name is missing");
+  
+  // The scope passed in may not be a decl scope.  Zip up the scope tree until
+  // we find one that is.
+  while ((S->getFlags() & Scope::DeclScope) == 0)
+    S = S->getParent();
+  
+  ScopedDecl *New;
+  QualType R = ObjcGetTypeForDeclarator(MDecl, S);
+  assert(!R.isNull() && "ObjcGetTypeForDeclarator() returned null type");
+    
+  FunctionDecl *NewFD = new FunctionDecl(MDecl->getLocation(), II, R, 
+                                         FunctionDecl::Static,
+                                         false, LastDeclarator);
+  New = NewFD;
+  
+  // If this has an identifier, add it to the scope stack.
+  if (II) {
+    New->setNext(II->getFETokenInfo<ScopedDecl>());
+    II->setFETokenInfo(New);
+    S->AddDecl(New);
+  }
+  
+  if (S->getParent() == 0)
+    AddTopLevelDecl(New, LastDeclarator);
+  
+  return New;
+}
+
+Sema::DeclTy *
 Sema::ActOnDeclarator(Scope *S, Declarator &D, DeclTy *lastDecl) {
   ScopedDecl *LastDeclarator = dyn_cast_or_null<ScopedDecl>((Decl *)lastDecl);
   IdentifierInfo *II = D.getIdentifier();
@@ -853,7 +889,64 @@
 
   return New;
 }
+
+// Called from Sema::ObjcParseStartOfFunctionDef().
+ParmVarDecl *
+Sema::ObjcParseParamDeclarator(ParmVarDecl *PI, Scope *FnScope) {
   
+  IdentifierInfo *II = PI->getIdentifier();
+  // TODO: CHECK FOR CONFLICTS, multiple decls with same name in one scope.
+  // Can this happen for params?  We already checked that they don't conflict
+  // among each other.  Here they can only shadow globals, which is ok.
+  if (/*Decl *PrevDecl = */LookupScopedDecl(II, Decl::IDNS_Ordinary,
+                                            PI->getLocation(), FnScope)) {
+    
+  }
+  
+  // FIXME: Handle storage class (auto, register). No declarator?
+  // TODO: Chain to previous parameter with the prevdeclarator chain?
+  
+  // Perform the default function/array conversion (C99 6.7.5.3p[7,8]).
+  // Doing the promotion here has a win and a loss. The win is the type for
+  // both Decl's and DeclRefExpr's will match (a convenient invariant for the
+  // code generator). The loss is the orginal type isn't preserved. For example:
+  //
+  // void func(int parmvardecl[5]) { // convert "int [5]" to "int *"
+  //    int blockvardecl[5];
+  //    sizeof(parmvardecl);  // size == 4
+  //    sizeof(blockvardecl); // size == 20
+  // }
+  //
+  // For expressions, all implicit conversions are captured using the
+  // ImplicitCastExpr AST node (we have no such mechanism for Decl's).
+  //
+  // FIXME: If a source translation tool needs to see the original type, then
+  // we need to consider storing both types (in ParmVarDecl)...
+  // 
+  QualType parmDeclType = PI->getType();
+  if (const ArrayType *AT = parmDeclType->getAsArrayType())
+    parmDeclType = Context.getPointerType(AT->getElementType());
+  else if (parmDeclType->isFunctionType())
+    parmDeclType = Context.getPointerType(parmDeclType);
+  
+  ParmVarDecl *New = new ParmVarDecl(PI->getLocation(), II, parmDeclType, 
+                                     VarDecl::None, 0);
+  // FIXME: need to check for invalid type.
+  /**
+  if (PI.InvalidType)
+    New->setInvalidDecl();
+   */
+  
+  // If this has an identifier, add it to the scope stack.
+  if (II) {
+    New->setNext(II->getFETokenInfo<ScopedDecl>());
+    II->setFETokenInfo(New);
+    FnScope->AddDecl(New);
+  }
+  
+  return New;
+}
+
 
 Sema::DeclTy *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Declarator &D) {
   assert(CurFunctionDecl == 0 && "Function parsing confused");
@@ -938,6 +1031,30 @@
   return FD;
 }
 
+Sema::DeclTy *Sema::ObjcActOnStartOfFunctionDef(Scope *FnBodyScope, DeclTy *D) {
+  assert(CurFunctionDecl == 0 && "Function parsing confused");
+  ObjcMethodDecl *MDecl = dyn_cast<ObjcMethodDecl>(static_cast<Decl *>(D));
+  
+  assert(MDecl != 0 && "Not a method declarator!");
+  
+  Scope *GlobalScope = FnBodyScope->getParent();
+  
+  FunctionDecl *FD =
+  static_cast<FunctionDecl*>(ObjcActOnDeclarator(GlobalScope, D, 0));
+  CurFunctionDecl = FD;
+  
+  // Create Decl objects for each parameter, adding them to the FunctionDecl.
+  llvm::SmallVector<ParmVarDecl*, 16> Params;
+  
+  for (int i = 0; i <  MDecl->getNumParams(); i++) {
+    ParmVarDecl *PDecl = MDecl->getParamDecl(i);
+    Params.push_back(ObjcParseParamDeclarator(PDecl, FnBodyScope));
+  }
+
+  FD->setParams(&Params[0], Params.size());
+  
+  return FD;
+}
 
 /// ImplicitlyDefineFunction - An undeclared identifier was used in a function
 /// call, forming a call to an implicitly defined function (per C99 6.5.1p2).