diff --git a/src/shared/cplusplus/Bind.cpp b/src/shared/cplusplus/Bind.cpp
index 6522b69a82be0ecdc933bf5d1c714a00d50ca569..f9c20e7ac955c6b1dda23b51f54db1ff78cc151f 100644
--- a/src/shared/cplusplus/Bind.cpp
+++ b/src/shared/cplusplus/Bind.cpp
@@ -847,15 +847,14 @@ bool Bind::visit(ObjCTypeNameAST *ast)
     return false;
 }
 
-void Bind::objCTypeName(ObjCTypeNameAST *ast)
+FullySpecifiedType Bind::objCTypeName(ObjCTypeNameAST *ast)
 {
     if (! ast)
-        return;
+        return FullySpecifiedType();
 
-    // unsigned lparen_token = ast->lparen_token;
     // unsigned type_qualifier_token = ast->type_qualifier_token;
     ExpressionTy type_id = this->expression(ast->type_id);
-    // unsigned rparen_token = ast->rparen_token;
+    return type_id;
 }
 
 bool Bind::visit(ObjCInstanceVariablesDeclarationAST *ast)
@@ -903,18 +902,23 @@ bool Bind::visit(ObjCMessageArgumentDeclarationAST *ast)
     return false;
 }
 
-void Bind::objCMessageArgumentDeclaration(ObjCMessageArgumentDeclarationAST *ast)
+void Bind::objCMessageArgumentDeclaration(ObjCMessageArgumentDeclarationAST *ast, ObjCMethod *method)
 {
     if (! ast)
         return;
 
-    this->objCTypeName(ast->type_name);
-    FullySpecifiedType type;
+    FullySpecifiedType type = this->objCTypeName(ast->type_name);
+
     for (SpecifierListAST *it = ast->attribute_list; it; it = it->next) {
         type = this->specifier(it->value, type);
     }
-    /*const Name *param_name =*/ this->name(ast->param_name);
-    // Argument *argument = ast->argument;
+
+    const Name *param_name = this->name(ast->param_name);
+    const unsigned sourceLocation = ast->param_name ? ast->param_name->firstToken() : ast->firstToken();
+    Argument *arg = control()->newArgument(sourceLocation, param_name);
+    arg->setType(type);
+    ast->argument = arg;
+    method->addMember(arg);
 }
 
 bool Bind::visit(ObjCMethodPrototypeAST *ast)
@@ -924,23 +928,41 @@ bool Bind::visit(ObjCMethodPrototypeAST *ast)
     return false;
 }
 
-void Bind::objCMethodPrototype(ObjCMethodPrototypeAST *ast)
+ObjCMethod *Bind::objCMethodPrototype(ObjCMethodPrototypeAST *ast)
 {
     if (! ast)
-        return;
+        return 0;
 
     // unsigned method_type_token = ast->method_type_token;
-    this->objCTypeName(ast->type_name);
-    /*const Name *selector =*/ this->name(ast->selector);
+    FullySpecifiedType returnType = this->objCTypeName(ast->type_name);
+    const Name *selector = this->name(ast->selector);
+
+    const unsigned sourceLocation = ast->selector ? ast->selector->firstToken() : ast->firstToken();
+    ObjCMethod *method = control()->newObjCMethod(sourceLocation, selector);
+    // ### set the offsets
+    method->setReturnType(returnType);
+    if (isObjCClassMethod(tokenKind(ast->method_type_token)))
+        method->setStorage(Symbol::Static);
+    method->setVisibility(_objcVisibility);
+    _scope->addMember(method);
+    ast->symbol = method;
+
+    Scope *previousScope = switchScope(method);
     for (ObjCMessageArgumentDeclarationListAST *it = ast->argument_list; it; it = it->next) {
-        this->objCMessageArgumentDeclaration(it->value);
+        this->objCMessageArgumentDeclaration(it->value, method);
     }
-    // unsigned dot_dot_dot_token = ast->dot_dot_dot_token;
-    FullySpecifiedType type;
+    (void) switchScope(previousScope);
+
+    if (ast->dot_dot_dot_token)
+        method->setVariadic(true);
+
+    FullySpecifiedType specifiers;
     for (SpecifierListAST *it = ast->attribute_list; it; it = it->next) {
-        type = this->specifier(it->value, type);
+        specifiers = this->specifier(it->value, specifiers);
     }
-    // ObjCMethod *symbol = ast->symbol;
+    setDeclSpecifiers(method, specifiers);
+
+    return method;
 }
 
 bool Bind::visit(ObjCSynthesizedPropertyAST *ast)
@@ -1579,7 +1601,7 @@ bool Bind::visit(ObjCProtocolExpressionAST *ast)
 bool Bind::visit(ObjCEncodeExpressionAST *ast)
 {
     // unsigned encode_token = ast->encode_token;
-    this->objCTypeName(ast->type_name);
+    FullySpecifiedType type = this->objCTypeName(ast->type_name);
     return false;
 }
 
@@ -2227,9 +2249,14 @@ bool Bind::visit(ObjCPropertyDeclarationAST *ast)
 
 bool Bind::visit(ObjCMethodDeclarationAST *ast)
 {
-    this->objCMethodPrototype(ast->method_prototype);
-    this->statement(ast->function_body);
-    // unsigned semicolon_token = ast->semicolon_token;
+    ObjCMethod *method = this->objCMethodPrototype(ast->method_prototype);
+
+    if (! _skipFunctionBodies && ast->function_body) {
+        Scope *previousScope = switchScope(method);
+        this->statement(ast->function_body);
+        (void) switchScope(previousScope);
+    }
+
     return false;
 }
 
@@ -2831,3 +2858,14 @@ int Bind::visibilityForObjCAccessSpecifier(int tokenKind)
         return Symbol::Protected;
     }
 }
+
+bool Bind::isObjCClassMethod(int tokenKind)
+{
+    switch (tokenKind) {
+    case T_PLUS:
+        return true;
+    case T_MINUS:
+    default:
+        return false;
+    }
+}
diff --git a/src/shared/cplusplus/Bind.h b/src/shared/cplusplus/Bind.h
index a632da1f9fd8302c3f320cc34c3d7bbe01b10ec6..a92fd2121ff1c0759d3d8d4ad7503485668ac13b 100644
--- a/src/shared/cplusplus/Bind.h
+++ b/src/shared/cplusplus/Bind.h
@@ -72,6 +72,7 @@ protected:
     static int visibilityForAccessSpecifier(int tokenKind);
     static int visibilityForClassKey(int tokenKind);
     static int visibilityForObjCAccessSpecifier(int tokenKind);
+    static bool isObjCClassMethod(int tokenKind);
 
     void setDeclSpecifiers(Symbol *symbol, const FullySpecifiedType &declSpecifiers);
 
@@ -116,11 +117,11 @@ protected:
     void translationUnit(TranslationUnitAST *ast);
     void objCProtocolRefs(ObjCProtocolRefsAST *ast, Symbol *objcClassOrProtocol);
     void objCMessageArgument(ObjCMessageArgumentAST *ast);
-    void objCTypeName(ObjCTypeNameAST *ast);
+    FullySpecifiedType objCTypeName(ObjCTypeNameAST *ast);
     void objCInstanceVariablesDeclaration(ObjCInstanceVariablesDeclarationAST *ast, ObjCClass *klass);
     void objCPropertyAttribute(ObjCPropertyAttributeAST *ast);
-    void objCMessageArgumentDeclaration(ObjCMessageArgumentDeclarationAST *ast);
-    void objCMethodPrototype(ObjCMethodPrototypeAST *ast);
+    void objCMessageArgumentDeclaration(ObjCMessageArgumentDeclarationAST *ast, ObjCMethod *method);
+    ObjCMethod *objCMethodPrototype(ObjCMethodPrototypeAST *ast);
     void objCSynthesizedProperty(ObjCSynthesizedPropertyAST *ast);
     void lambdaIntroducer(LambdaIntroducerAST *ast);
     void lambdaCapture(LambdaCaptureAST *ast);