pretty priting for method definitions.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@43986 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/Driver/ASTConsumers.cpp b/Driver/ASTConsumers.cpp
index 3c07c37..8b68f24 100644
--- a/Driver/ASTConsumers.cpp
+++ b/Driver/ASTConsumers.cpp
@@ -73,6 +73,58 @@
   fprintf(stderr, "typedef %s;\n", S.c_str());
 }
 
+static void PrintObjcMethodDecl(ObjcMethodDecl *OMD) {
+  if (OMD->isInstance())
+    fprintf(stderr, "\n- ");
+  else 
+    fprintf(stderr, "\n+ ");
+  if (!OMD->getResultType().isNull())
+    fprintf(stderr, "(%s) ", OMD->getResultType().getAsString().c_str());
+  // FIXME: just print original selector name!
+  fprintf(stderr, "%s ", OMD->getSelector().getName().c_str());
+  
+  for (int i = 0; i < OMD->getNumParams(); i++) {
+    ParmVarDecl *PDecl = OMD->getParamDecl(i);
+    // FIXME: selector is missing here!
+    fprintf(stderr, " :(%s) %s", PDecl->getType().getAsString().c_str(), 
+            PDecl->getName()); 
+  }
+}
+
+static void PrintObjcImplementationDecl(ObjcImplementationDecl *OID) {
+  std::string I = OID->getName();
+  ObjcInterfaceDecl *SID = OID->getSuperClass();
+  if (SID) {
+    std::string S = SID->getName();
+    fprintf(stderr, "@implementation %s : %s", I.c_str(), S.c_str());
+  }
+  else
+    fprintf(stderr, "@implementation %s", I.c_str());
+  
+  for (int i = 0; i < OID->getNumInstanceMethods(); i++) {
+    PrintObjcMethodDecl(OID->getInstanceMethods()[i]);
+    ObjcMethodDecl *OMD = OID->getInstanceMethods()[i];
+    if (OMD->getBody()) {
+      fprintf(stderr, " ");
+      OMD->getBody()->dumpPretty();
+      fprintf(stderr, "\n");
+    }
+  }
+  
+  for (int i = 0; i < OID->getNumClassMethods(); i++) {
+    PrintObjcMethodDecl(OID->getClassMethods()[i]);
+    ObjcMethodDecl *OMD = OID->getClassMethods()[i];
+    if (OMD->getBody()) {
+      fprintf(stderr, " ");
+      OMD->getBody()->dumpPretty();
+      fprintf(stderr, "\n");
+    }
+  }
+  
+  fprintf(stderr,"@end\n");
+}
+
+
 static void PrintObjcInterfaceDecl(ObjcInterfaceDecl *OID) {
   std::string I = OID->getName();
   ObjcInterfaceDecl *SID = OID->getSuperClass();
@@ -232,8 +284,7 @@
         fprintf(stderr, ";\n");
       } else if (ObjcImplementationDecl *OID = 
                    dyn_cast<ObjcImplementationDecl>(D)) {
-        fprintf(stderr, "@implementation %s  [printing todo]\n",
-                OID->getName());
+        PrintObjcImplementationDecl(OID);
       } else if (ObjcCategoryImplDecl *OID = 
                  dyn_cast<ObjcCategoryImplDecl>(D)) {
         PrintObjcCategoryImplDecl(OID);
diff --git a/Parse/ParseObjc.cpp b/Parse/ParseObjc.cpp
index b5f7429..4fbbc18 100644
--- a/Parse/ParseObjc.cpp
+++ b/Parse/ParseObjc.cpp
@@ -38,7 +38,7 @@
     case tok::objc_protocol:
       return ParseObjCAtProtocolDeclaration(AtLoc);
     case tok::objc_implementation:
-      return ObjcImpDecl = ParseObjCAtImplementationDeclaration(AtLoc);
+      return ParseObjCAtImplementationDeclaration(AtLoc);
     case tok::objc_end:
       return ParseObjCAtEndDeclaration(AtLoc);
     case tok::objc_compatibility_alias:
@@ -911,7 +911,8 @@
     DeclTy *ImplCatType = Actions.ActOnStartCategoryImplementation(
                                     atLoc, nameId, nameLoc, categoryId, 
                                     categoryLoc);
-    return ImplCatType;
+    ObjcImpDecl = ImplCatType;
+    return 0;
   }
   // We have a class implementation
   SourceLocation superClassLoc;
@@ -932,8 +933,9 @@
   
   if (Tok.is(tok::l_brace)) // we have ivars
     ParseObjCClassInstanceVariables(ImplClsType/*FIXME*/, atLoc);
+  ObjcImpDecl = ImplClsType;
   
-  return ImplClsType;
+  return 0;
 }
 
 Parser::DeclTy *Parser::ParseObjCAtEndDeclaration(SourceLocation atLoc) {
@@ -949,11 +951,10 @@
                                       &AllImplMethods[0], AllImplMethods.size(),
                                       (DeclTy **)0, 0,
                                       atLoc);
-    ObjcImpDecl = 0;
     AllImplMethods.clear();
   }
 
-  return 0;
+  return ObjcImpDecl;
 }
 
 ///   compatibility-alias-decl:
diff --git a/test/Sema/method-def-2.m b/test/Sema/method-def-2.m
new file mode 100644
index 0000000..d31a2b5
--- /dev/null
+++ b/test/Sema/method-def-2.m
@@ -0,0 +1,19 @@
+// RUN: clang -ast-print %s
+extern void abort(void);
+#define CHECK_IF(expr) if(!(expr)) abort()
+
+static double d = 4.5920234e2;
+
+@interface Foo 
+-(void) brokenType: (int)x floatingPoint: (double)y;
+@end
+
+
+@implementation Foo
+-(void) brokenType: (int)x floatingPoint: (double)y
+{
+        CHECK_IF(x == 459);
+        CHECK_IF(y == d);
+}
+@end
+