Progress on message expressions...

- Add ObjcMessageExpr AST node and associated constructors.
- Add SourceLocation's to ActOnKeywordMessage/ActOnUnaryMessage API.
- Instantiate message expressions...
- Replace alloca usage with SmallString.

Next step, installing a correct type, among other tweaks...



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@42116 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/Sema/Sema.h b/Sema/Sema.h
index 79fc111..29a03d1 100644
--- a/Sema/Sema.h
+++ b/Sema/Sema.h
@@ -384,17 +384,22 @@
 		    tok::ObjCKeywordKind MethodImplKind);
                     
   // This actions handles keyword message to classes.
-  virtual ExprResult ActOnKeywordMessage(IdentifierInfo *receivingClassName, 
-    ObjcKeywordMessage *Keywords, unsigned NumKeywords);
+  virtual ExprResult ActOnKeywordMessage(
+    IdentifierInfo *receivingClassName, 
+    ObjcKeywordMessage *Keywords, unsigned NumKeywords,
+    SourceLocation lbrac, SourceLocation rbrac);
   // This action handles keyword messages to instances.
   virtual ExprResult ActOnKeywordMessage(ExprTy *receiver, 
-    ObjcKeywordMessage *Keywords, unsigned NumKeywords);
-    
-  // This actions handles keyword message to classes.
-  virtual ExprResult ActOnUnaryMessage(IdentifierInfo *receivingClassName, 
-                                    IdentifierInfo *selName);
-  // This action handles keyword messages to instances.
-  virtual ExprResult ActOnUnaryMessage(ExprTy *receiver, IdentifierInfo *sName);
+    ObjcKeywordMessage *Keywords, unsigned NumKeywords,
+    SourceLocation lbrac, SourceLocation rbrac);
+  // This actions handles unary message to classes.
+  virtual ExprResult ActOnUnaryMessage(
+    IdentifierInfo *receivingClassName, IdentifierInfo *selName,
+    SourceLocation lbrac, SourceLocation rbrac);
+  // This action handles unary messages to instances.
+  virtual ExprResult ActOnUnaryMessage(
+    ExprTy *receiver, IdentifierInfo *sName,
+    SourceLocation lbrac, SourceLocation rbrac);
 private:
   // UsualUnaryConversions - promotes integers (C99 6.3.1.1p2) and converts
   // functions and arrays to their respective pointers (C99 6.3.2.1). 
diff --git a/Sema/SemaDecl.cpp b/Sema/SemaDecl.cpp
index 3b7d8f3..d5ca796 100644
--- a/Sema/SemaDecl.cpp
+++ b/Sema/SemaDecl.cpp
@@ -23,6 +23,7 @@
 #include "clang/Basic/LangOptions.h"
 #include "clang/Basic/TargetInfo.h"
 #include "llvm/Config/config.h" 
+#include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/SmallSet.h"
 #if !defined(LLVM_ON_WIN32)
 #include <alloca.h>
@@ -1298,21 +1299,21 @@
 
   // Derive the selector name from the keyword declarations.
   int len=0;
-  char *methodName;
   for (unsigned int i = 0; i < NumKeywords; i++) {
     if (Keywords[i].SelectorName)
       len += strlen(Keywords[i].SelectorName->getName());
     len++;
   }
-  methodName = (char *) alloca (len + 1);
+  llvm::SmallString<128> methodName;
   methodName[0] = '\0';
   for (unsigned int i = 0; i < NumKeywords; i++) {
     if (Keywords[i].SelectorName)
-      strcat(methodName, Keywords[i].SelectorName->getName());
-    strcat(methodName, ":");
+      methodName += Keywords[i].SelectorName->getName();
+    methodName += ":";
   }
-  SelectorInfo &SelName = Context.getSelectorInfo(methodName, methodName+len);
-
+  methodName[len] = '\0';
+  SelectorInfo &SelName = Context.getSelectorInfo(&methodName[0], 
+                                                  &methodName[0]+len);
   llvm::SmallVector<ParmVarDecl*, 16> Params;
 
   for (unsigned i = 0; i < NumKeywords; i++) {
@@ -1332,9 +1333,9 @@
 		      		      0, -1, AttrList, MethodType == tok::minus);
   ObjcMethod->setMethodParams(&Params[0], NumKeywords);
   if (MethodDeclKind == tok::objc_optional)
-      ObjcMethod->setDeclImplementation(ObjcMethodDecl::Optional);
+    ObjcMethod->setDeclImplementation(ObjcMethodDecl::Optional);
   else
-       ObjcMethod->setDeclImplementation(ObjcMethodDecl::Required);
+    ObjcMethod->setDeclImplementation(ObjcMethodDecl::Required);
   return ObjcMethod;
 }
 
@@ -1350,9 +1351,9 @@
 			             SelName, resultDeclType, 0, -1,
                                      AttrList, MethodType == tok::minus);
   if (MethodDeclKind == tok::objc_optional)
-      ObjcMethod->setDeclImplementation(ObjcMethodDecl::Optional);
+    ObjcMethod->setDeclImplementation(ObjcMethodDecl::Optional);
   else
-       ObjcMethod->setDeclImplementation(ObjcMethodDecl::Required);
+    ObjcMethod->setDeclImplementation(ObjcMethodDecl::Required);
   return ObjcMethod;
 }
 
diff --git a/Sema/SemaExpr.cpp b/Sema/SemaExpr.cpp
index d7136a3..886b3dd 100644
--- a/Sema/SemaExpr.cpp
+++ b/Sema/SemaExpr.cpp
@@ -15,6 +15,7 @@
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/Expr.h"
+#include "clang/Parse/DeclSpec.h" 
 #include "clang/Lex/Preprocessor.h"
 #include "clang/Lex/LiteralSupport.h"
 #include "clang/Basic/SourceManager.h"
@@ -1856,28 +1857,76 @@
   return new ObjCEncodeExpr(t, EncodedType, AtLoc, RParenLoc);
 }
 
+static SelectorInfo &DeriveSelector(ObjcKeywordMessage *Keywords, 
+                                    unsigned NumKeywords,
+                                    ASTContext &Context) {
+  // Derive the selector name from the keyword declarations.
+  int len=0;
+  for (unsigned int i = 0; i < NumKeywords; i++) {
+    if (Keywords[i].SelectorName)
+      len += strlen(Keywords[i].SelectorName->getName());
+    len++;
+  }
+  llvm::SmallString<128> methodName;
+  methodName[0] = '\0';
+  for (unsigned int i = 0; i < NumKeywords; i++) {
+    if (Keywords[i].SelectorName)
+      methodName += Keywords[i].SelectorName->getName();
+    methodName += ":";
+  }
+  methodName[len] = '\0';
+  return Context.getSelectorInfo(&methodName[0], &methodName[0]+len);
+}
+
 // This actions handles keyword message to classes.
-Sema::ExprResult Sema::ActOnKeywordMessage(IdentifierInfo *receivingClassName, 
-    ObjcKeywordMessage *Keywords, unsigned NumKeywords)
+Sema::ExprResult Sema::ActOnKeywordMessage(
+  IdentifierInfo *receivingClassName, 
+  ObjcKeywordMessage *Keywords, unsigned NumKeywords,
+  SourceLocation lbrac, SourceLocation rbrac)
 {
-  return 0;
+  SelectorInfo &SelName = DeriveSelector(Keywords, NumKeywords, Context);
+  assert(receivingClassName && "missing receiver class name");
+
+  return new ObjCMessageExpr(receivingClassName, SelName, Keywords, NumKeywords, 
+                             Context.IntTy/*FIXME*/, lbrac, rbrac);
 }
 
 // This action handles keyword messages to instances.
-Sema::ExprResult Sema::ActOnKeywordMessage(ExprTy *receiver, 
-    ObjcKeywordMessage *Keywords, unsigned NumKeywords) {
-  return 0;
+Sema::ExprResult Sema::ActOnKeywordMessage(
+  ExprTy *receiver, ObjcKeywordMessage *Keywords, unsigned NumKeywords,
+  SourceLocation lbrac, SourceLocation rbrac) {
+  SelectorInfo &SelName = DeriveSelector(Keywords, NumKeywords, Context);
+  assert(receiver && "missing receiver expression");
+  
+  Expr *RExpr = static_cast<Expr *>(receiver);
+  return new ObjCMessageExpr(RExpr, SelName, Keywords, NumKeywords, 
+                             Context.IntTy/*FIXME*/, lbrac, rbrac);
 }
     
-// This actions handles keyword message to classes.
-Sema::ExprResult Sema::ActOnUnaryMessage(IdentifierInfo *receivingClassName, 
-                                         IdentifierInfo *selName) {
-  return 0;
+// This actions handles unary message to classes.
+Sema::ExprResult Sema::ActOnUnaryMessage(
+  IdentifierInfo *receivingClassName, IdentifierInfo *selName,
+  SourceLocation lbrac, SourceLocation rbrac) {
+  assert(receivingClassName && "missing receiver class name");
+  
+  // FIXME: this should be passed in...
+  SelectorInfo &SName = Context.getSelectorInfo(
+           selName->getName(), selName->getName()+strlen(selName->getName()));
+  return new ObjCMessageExpr(receivingClassName, SName,
+                             Context.IntTy/*FIXME*/, lbrac, rbrac);
 }
 
-// This action handles keyword messages to instances.
-Sema::ExprResult Sema::ActOnUnaryMessage(ExprTy *receiver, 
-                                         IdentifierInfo *selName) {
-  return 0;
+// This action handles unary messages to instances.
+Sema::ExprResult Sema::ActOnUnaryMessage(
+  ExprTy *receiver, IdentifierInfo *selName,
+  SourceLocation lbrac, SourceLocation rbrac) {
+  assert(receiver && "missing receiver expression");
+  
+  Expr *RExpr = static_cast<Expr *>(receiver);
+  // FIXME: this should be passed in...
+  SelectorInfo &SName = Context.getSelectorInfo(
+           selName->getName(), selName->getName()+strlen(selName->getName()));
+  return new ObjCMessageExpr(RExpr, SName,
+                             Context.IntTy/*FIXME*/, lbrac, rbrac);
 }