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);
}