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... llvm-svn: 42116
This commit is contained in:
parent
fb9ea52a13
commit
d54978ba8b
|
@ -15,6 +15,8 @@
|
||||||
#include "clang/AST/ASTContext.h"
|
#include "clang/AST/ASTContext.h"
|
||||||
#include "clang/AST/StmtVisitor.h"
|
#include "clang/AST/StmtVisitor.h"
|
||||||
#include "clang/Lex/IdentifierTable.h"
|
#include "clang/Lex/IdentifierTable.h"
|
||||||
|
// is this bad layering? I (snaroff) don't think so. Want Chris to weigh in.
|
||||||
|
#include "clang/Parse/DeclSpec.h"
|
||||||
using namespace clang;
|
using namespace clang;
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
@ -854,6 +856,52 @@ unsigned OCUVectorElementExpr::getEncodedElementAccess() const {
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// constructor for unary messages.
|
||||||
|
ObjCMessageExpr::ObjCMessageExpr(
|
||||||
|
IdentifierInfo *clsName, SelectorInfo &methName, QualType retType,
|
||||||
|
SourceLocation LBrac, SourceLocation RBrac)
|
||||||
|
: Expr(ObjCMessageExprClass, retType), Selector(methName) {
|
||||||
|
ClassName = clsName;
|
||||||
|
LBracloc = LBrac;
|
||||||
|
RBracloc = RBrac;
|
||||||
|
}
|
||||||
|
|
||||||
|
ObjCMessageExpr::ObjCMessageExpr(
|
||||||
|
Expr *fn, SelectorInfo &methName, QualType retType,
|
||||||
|
SourceLocation LBrac, SourceLocation RBrac)
|
||||||
|
: Expr(ObjCMessageExprClass, retType), Selector(methName), ClassName(0) {
|
||||||
|
SubExprs = new Expr*[1];
|
||||||
|
SubExprs[RECEIVER] = fn;
|
||||||
|
LBracloc = LBrac;
|
||||||
|
RBracloc = RBrac;
|
||||||
|
}
|
||||||
|
|
||||||
|
// constructor for keyword messages.
|
||||||
|
ObjCMessageExpr::ObjCMessageExpr(
|
||||||
|
Expr *fn, SelectorInfo &selInfo, ObjcKeywordMessage *keys, unsigned numargs,
|
||||||
|
QualType retType, SourceLocation LBrac, SourceLocation RBrac)
|
||||||
|
: Expr(ObjCMessageExprClass, retType), Selector(selInfo), ClassName(0) {
|
||||||
|
SubExprs = new Expr*[numargs+1];
|
||||||
|
SubExprs[RECEIVER] = fn;
|
||||||
|
for (unsigned i = 0; i != numargs; ++i)
|
||||||
|
SubExprs[i+ARGS_START] = static_cast<Expr *>(keys[i].KeywordExpr);
|
||||||
|
LBracloc = LBrac;
|
||||||
|
RBracloc = RBrac;
|
||||||
|
}
|
||||||
|
|
||||||
|
ObjCMessageExpr::ObjCMessageExpr(
|
||||||
|
IdentifierInfo *clsName, SelectorInfo &selInfo, ObjcKeywordMessage *keys,
|
||||||
|
unsigned numargs, QualType retType, SourceLocation LBrac, SourceLocation RBrac)
|
||||||
|
: Expr(ObjCMessageExprClass, retType), Selector(selInfo), ClassName(clsName) {
|
||||||
|
SubExprs = new Expr*[numargs+1];
|
||||||
|
SubExprs[RECEIVER] = 0;
|
||||||
|
for (unsigned i = 0; i != numargs; ++i)
|
||||||
|
SubExprs[i+ARGS_START] = static_cast<Expr *>(keys[i].KeywordExpr);
|
||||||
|
LBracloc = LBrac;
|
||||||
|
RBracloc = RBrac;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Child Iterators for iterating over subexpressions/substatements
|
// Child Iterators for iterating over subexpressions/substatements
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
@ -1023,3 +1071,11 @@ Stmt::child_iterator ObjCStringLiteral::child_end() { return NULL; }
|
||||||
Stmt::child_iterator ObjCEncodeExpr::child_begin() { return NULL; }
|
Stmt::child_iterator ObjCEncodeExpr::child_begin() { return NULL; }
|
||||||
Stmt::child_iterator ObjCEncodeExpr::child_end() { return NULL; }
|
Stmt::child_iterator ObjCEncodeExpr::child_end() { return NULL; }
|
||||||
|
|
||||||
|
// ObjCMessageExpr
|
||||||
|
Stmt::child_iterator ObjCMessageExpr::child_begin() {
|
||||||
|
return reinterpret_cast<Stmt**>(&SubExprs[0]);
|
||||||
|
}
|
||||||
|
Stmt::child_iterator ObjCMessageExpr::child_end() {
|
||||||
|
return reinterpret_cast<Stmt**>(&SubExprs[NumArgs+ARGS_START]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -612,6 +612,17 @@ void StmtPrinter::VisitObjCEncodeExpr(ObjCEncodeExpr *Node) {
|
||||||
OS << Node->getEncodedType().getAsString() << ")";
|
OS << Node->getEncodedType().getAsString() << ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void StmtPrinter::VisitObjCMessageExpr(ObjCMessageExpr *Mess) {
|
||||||
|
OS << "[";
|
||||||
|
PrintExpr(Mess->getReceiver());
|
||||||
|
for (unsigned i = 0, e = Mess->getNumArgs(); i != e; ++i) {
|
||||||
|
// FIXME: get/print keyword...
|
||||||
|
PrintExpr(Mess->getArg(i));
|
||||||
|
}
|
||||||
|
OS << "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Stmt method implementations
|
// Stmt method implementations
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
|
@ -1007,7 +1007,7 @@ Parser::ExprResult Parser::ParseObjCExpression() {
|
||||||
///
|
///
|
||||||
Parser::ExprResult Parser::ParseObjCMessageExpression() {
|
Parser::ExprResult Parser::ParseObjCMessageExpression() {
|
||||||
assert(Tok.getKind() == tok::l_square && "'[' expected");
|
assert(Tok.getKind() == tok::l_square && "'[' expected");
|
||||||
SourceLocation Loc = ConsumeBracket(); // consume '['
|
SourceLocation LBracloc = ConsumeBracket(); // consume '['
|
||||||
IdentifierInfo *ReceiverName = 0;
|
IdentifierInfo *ReceiverName = 0;
|
||||||
ExprTy *ReceiverExpr = 0;
|
ExprTy *ReceiverExpr = 0;
|
||||||
// Parse receiver
|
// Parse receiver
|
||||||
|
@ -1073,20 +1073,22 @@ Parser::ExprResult Parser::ParseObjCMessageExpression() {
|
||||||
SkipUntil(tok::semi);
|
SkipUntil(tok::semi);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
ConsumeBracket(); // consume ']'
|
SourceLocation RBracloc = ConsumeBracket(); // consume ']'
|
||||||
|
|
||||||
if (KeyInfo.size()) {
|
if (KeyInfo.size()) {
|
||||||
// We've just parsed a keyword message.
|
// We've just parsed a keyword message.
|
||||||
if (ReceiverName)
|
if (ReceiverName)
|
||||||
return Actions.ActOnKeywordMessage(ReceiverName,
|
return Actions.ActOnKeywordMessage(ReceiverName,
|
||||||
&KeyInfo[0], KeyInfo.size());
|
&KeyInfo[0], KeyInfo.size(),
|
||||||
|
LBracloc, RBracloc);
|
||||||
return Actions.ActOnKeywordMessage(ReceiverExpr,
|
return Actions.ActOnKeywordMessage(ReceiverExpr,
|
||||||
&KeyInfo[0], KeyInfo.size());
|
&KeyInfo[0], KeyInfo.size(),
|
||||||
|
LBracloc, RBracloc);
|
||||||
}
|
}
|
||||||
// We've just parsed a unary message (a message with no arguments).
|
// We've just parsed a unary message (a message with no arguments).
|
||||||
if (ReceiverName)
|
if (ReceiverName)
|
||||||
return Actions.ActOnUnaryMessage(ReceiverName, selIdent);
|
return Actions.ActOnUnaryMessage(ReceiverName, selIdent, LBracloc,RBracloc);
|
||||||
return Actions.ActOnUnaryMessage(ReceiverExpr, selIdent);
|
return Actions.ActOnUnaryMessage(ReceiverExpr, selIdent, LBracloc,RBracloc);
|
||||||
}
|
}
|
||||||
|
|
||||||
Parser::ExprResult Parser::ParseObjCStringLiteral() {
|
Parser::ExprResult Parser::ParseObjCStringLiteral() {
|
||||||
|
|
|
@ -384,17 +384,22 @@ public:
|
||||||
tok::ObjCKeywordKind MethodImplKind);
|
tok::ObjCKeywordKind MethodImplKind);
|
||||||
|
|
||||||
// This actions handles keyword message to classes.
|
// This actions handles keyword message to classes.
|
||||||
virtual ExprResult ActOnKeywordMessage(IdentifierInfo *receivingClassName,
|
virtual ExprResult ActOnKeywordMessage(
|
||||||
ObjcKeywordMessage *Keywords, unsigned NumKeywords);
|
IdentifierInfo *receivingClassName,
|
||||||
|
ObjcKeywordMessage *Keywords, unsigned NumKeywords,
|
||||||
|
SourceLocation lbrac, SourceLocation rbrac);
|
||||||
// This action handles keyword messages to instances.
|
// This action handles keyword messages to instances.
|
||||||
virtual ExprResult ActOnKeywordMessage(ExprTy *receiver,
|
virtual ExprResult ActOnKeywordMessage(ExprTy *receiver,
|
||||||
ObjcKeywordMessage *Keywords, unsigned NumKeywords);
|
ObjcKeywordMessage *Keywords, unsigned NumKeywords,
|
||||||
|
SourceLocation lbrac, SourceLocation rbrac);
|
||||||
// This actions handles keyword message to classes.
|
// This actions handles unary message to classes.
|
||||||
virtual ExprResult ActOnUnaryMessage(IdentifierInfo *receivingClassName,
|
virtual ExprResult ActOnUnaryMessage(
|
||||||
IdentifierInfo *selName);
|
IdentifierInfo *receivingClassName, IdentifierInfo *selName,
|
||||||
// This action handles keyword messages to instances.
|
SourceLocation lbrac, SourceLocation rbrac);
|
||||||
virtual ExprResult ActOnUnaryMessage(ExprTy *receiver, IdentifierInfo *sName);
|
// This action handles unary messages to instances.
|
||||||
|
virtual ExprResult ActOnUnaryMessage(
|
||||||
|
ExprTy *receiver, IdentifierInfo *sName,
|
||||||
|
SourceLocation lbrac, SourceLocation rbrac);
|
||||||
private:
|
private:
|
||||||
// UsualUnaryConversions - promotes integers (C99 6.3.1.1p2) and converts
|
// UsualUnaryConversions - promotes integers (C99 6.3.1.1p2) and converts
|
||||||
// functions and arrays to their respective pointers (C99 6.3.2.1).
|
// functions and arrays to their respective pointers (C99 6.3.2.1).
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include "clang/Basic/LangOptions.h"
|
#include "clang/Basic/LangOptions.h"
|
||||||
#include "clang/Basic/TargetInfo.h"
|
#include "clang/Basic/TargetInfo.h"
|
||||||
#include "llvm/Config/config.h"
|
#include "llvm/Config/config.h"
|
||||||
|
#include "llvm/ADT/SmallString.h"
|
||||||
#include "llvm/ADT/SmallSet.h"
|
#include "llvm/ADT/SmallSet.h"
|
||||||
#if !defined(LLVM_ON_WIN32)
|
#if !defined(LLVM_ON_WIN32)
|
||||||
#include <alloca.h>
|
#include <alloca.h>
|
||||||
|
@ -1298,21 +1299,21 @@ Sema::DeclTy *Sema::ObjcBuildMethodDeclaration(SourceLocation MethodLoc,
|
||||||
|
|
||||||
// Derive the selector name from the keyword declarations.
|
// Derive the selector name from the keyword declarations.
|
||||||
int len=0;
|
int len=0;
|
||||||
char *methodName;
|
|
||||||
for (unsigned int i = 0; i < NumKeywords; i++) {
|
for (unsigned int i = 0; i < NumKeywords; i++) {
|
||||||
if (Keywords[i].SelectorName)
|
if (Keywords[i].SelectorName)
|
||||||
len += strlen(Keywords[i].SelectorName->getName());
|
len += strlen(Keywords[i].SelectorName->getName());
|
||||||
len++;
|
len++;
|
||||||
}
|
}
|
||||||
methodName = (char *) alloca (len + 1);
|
llvm::SmallString<128> methodName;
|
||||||
methodName[0] = '\0';
|
methodName[0] = '\0';
|
||||||
for (unsigned int i = 0; i < NumKeywords; i++) {
|
for (unsigned int i = 0; i < NumKeywords; i++) {
|
||||||
if (Keywords[i].SelectorName)
|
if (Keywords[i].SelectorName)
|
||||||
strcat(methodName, Keywords[i].SelectorName->getName());
|
methodName += Keywords[i].SelectorName->getName();
|
||||||
strcat(methodName, ":");
|
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;
|
llvm::SmallVector<ParmVarDecl*, 16> Params;
|
||||||
|
|
||||||
for (unsigned i = 0; i < NumKeywords; i++) {
|
for (unsigned i = 0; i < NumKeywords; i++) {
|
||||||
|
@ -1332,9 +1333,9 @@ Sema::DeclTy *Sema::ObjcBuildMethodDeclaration(SourceLocation MethodLoc,
|
||||||
0, -1, AttrList, MethodType == tok::minus);
|
0, -1, AttrList, MethodType == tok::minus);
|
||||||
ObjcMethod->setMethodParams(&Params[0], NumKeywords);
|
ObjcMethod->setMethodParams(&Params[0], NumKeywords);
|
||||||
if (MethodDeclKind == tok::objc_optional)
|
if (MethodDeclKind == tok::objc_optional)
|
||||||
ObjcMethod->setDeclImplementation(ObjcMethodDecl::Optional);
|
ObjcMethod->setDeclImplementation(ObjcMethodDecl::Optional);
|
||||||
else
|
else
|
||||||
ObjcMethod->setDeclImplementation(ObjcMethodDecl::Required);
|
ObjcMethod->setDeclImplementation(ObjcMethodDecl::Required);
|
||||||
return ObjcMethod;
|
return ObjcMethod;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1350,9 +1351,9 @@ Sema::DeclTy *Sema::ObjcBuildMethodDeclaration(SourceLocation MethodLoc,
|
||||||
SelName, resultDeclType, 0, -1,
|
SelName, resultDeclType, 0, -1,
|
||||||
AttrList, MethodType == tok::minus);
|
AttrList, MethodType == tok::minus);
|
||||||
if (MethodDeclKind == tok::objc_optional)
|
if (MethodDeclKind == tok::objc_optional)
|
||||||
ObjcMethod->setDeclImplementation(ObjcMethodDecl::Optional);
|
ObjcMethod->setDeclImplementation(ObjcMethodDecl::Optional);
|
||||||
else
|
else
|
||||||
ObjcMethod->setDeclImplementation(ObjcMethodDecl::Required);
|
ObjcMethod->setDeclImplementation(ObjcMethodDecl::Required);
|
||||||
return ObjcMethod;
|
return ObjcMethod;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#include "clang/AST/ASTContext.h"
|
#include "clang/AST/ASTContext.h"
|
||||||
#include "clang/AST/Decl.h"
|
#include "clang/AST/Decl.h"
|
||||||
#include "clang/AST/Expr.h"
|
#include "clang/AST/Expr.h"
|
||||||
|
#include "clang/Parse/DeclSpec.h"
|
||||||
#include "clang/Lex/Preprocessor.h"
|
#include "clang/Lex/Preprocessor.h"
|
||||||
#include "clang/Lex/LiteralSupport.h"
|
#include "clang/Lex/LiteralSupport.h"
|
||||||
#include "clang/Basic/SourceManager.h"
|
#include "clang/Basic/SourceManager.h"
|
||||||
|
@ -1856,28 +1857,76 @@ Sema::ExprResult Sema::ParseObjCEncodeExpression(SourceLocation AtLoc,
|
||||||
return new ObjCEncodeExpr(t, EncodedType, AtLoc, RParenLoc);
|
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.
|
// This actions handles keyword message to classes.
|
||||||
Sema::ExprResult Sema::ActOnKeywordMessage(IdentifierInfo *receivingClassName,
|
Sema::ExprResult Sema::ActOnKeywordMessage(
|
||||||
ObjcKeywordMessage *Keywords, unsigned NumKeywords)
|
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.
|
// This action handles keyword messages to instances.
|
||||||
Sema::ExprResult Sema::ActOnKeywordMessage(ExprTy *receiver,
|
Sema::ExprResult Sema::ActOnKeywordMessage(
|
||||||
ObjcKeywordMessage *Keywords, unsigned NumKeywords) {
|
ExprTy *receiver, ObjcKeywordMessage *Keywords, unsigned NumKeywords,
|
||||||
return 0;
|
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.
|
// This actions handles unary message to classes.
|
||||||
Sema::ExprResult Sema::ActOnUnaryMessage(IdentifierInfo *receivingClassName,
|
Sema::ExprResult Sema::ActOnUnaryMessage(
|
||||||
IdentifierInfo *selName) {
|
IdentifierInfo *receivingClassName, IdentifierInfo *selName,
|
||||||
return 0;
|
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.
|
// This action handles unary messages to instances.
|
||||||
Sema::ExprResult Sema::ActOnUnaryMessage(ExprTy *receiver,
|
Sema::ExprResult Sema::ActOnUnaryMessage(
|
||||||
IdentifierInfo *selName) {
|
ExprTy *receiver, IdentifierInfo *selName,
|
||||||
return 0;
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -708,7 +708,6 @@
|
||||||
08FB7793FE84155DC02AAC07 /* Project object */ = {
|
08FB7793FE84155DC02AAC07 /* Project object */ = {
|
||||||
isa = PBXProject;
|
isa = PBXProject;
|
||||||
buildConfigurationList = 1DEB923508733DC60010E9CD /* Build configuration list for PBXProject "clang" */;
|
buildConfigurationList = 1DEB923508733DC60010E9CD /* Build configuration list for PBXProject "clang" */;
|
||||||
compatibilityVersion = "Xcode 2.4";
|
|
||||||
hasScannedForEncodings = 1;
|
hasScannedForEncodings = 1;
|
||||||
mainGroup = 08FB7794FE84155DC02AAC07 /* clang */;
|
mainGroup = 08FB7794FE84155DC02AAC07 /* clang */;
|
||||||
projectDirPath = "";
|
projectDirPath = "";
|
||||||
|
|
|
@ -23,6 +23,7 @@ namespace clang {
|
||||||
class IdentifierInfo;
|
class IdentifierInfo;
|
||||||
class Decl;
|
class Decl;
|
||||||
class ASTContext;
|
class ASTContext;
|
||||||
|
struct ObjcKeywordMessage;
|
||||||
|
|
||||||
/// Expr - This represents one expression. Note that Expr's are subclasses of
|
/// Expr - This represents one expression. Note that Expr's are subclasses of
|
||||||
/// Stmt. This allows an expression to be transparently used any place a Stmt
|
/// Stmt. This allows an expression to be transparently used any place a Stmt
|
||||||
|
@ -1058,6 +1059,70 @@ public:
|
||||||
virtual child_iterator child_end();
|
virtual child_iterator child_end();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class ObjCMessageExpr : public Expr {
|
||||||
|
enum { RECEIVER=0, ARGS_START=1 };
|
||||||
|
|
||||||
|
// The following 3 slots are only used for keyword messages.
|
||||||
|
// Adding a subclass could save us some space. For now, we keep it simple.
|
||||||
|
Expr **SubExprs;
|
||||||
|
unsigned NumArgs;
|
||||||
|
|
||||||
|
// A unigue name for this message.
|
||||||
|
SelectorInfo &Selector;
|
||||||
|
|
||||||
|
IdentifierInfo **KeyIdents;
|
||||||
|
|
||||||
|
IdentifierInfo *ClassName;
|
||||||
|
|
||||||
|
SourceLocation LBracloc, RBracloc;
|
||||||
|
public:
|
||||||
|
// constructor for unary messages.
|
||||||
|
// FIXME: clsName should be typed to ObjCInterfaceType
|
||||||
|
ObjCMessageExpr(IdentifierInfo *clsName, SelectorInfo &selInfo,
|
||||||
|
QualType retType, SourceLocation LBrac, SourceLocation RBrac);
|
||||||
|
ObjCMessageExpr(Expr *receiver, SelectorInfo &selInfo,
|
||||||
|
QualType retType, SourceLocation LBrac, SourceLocation RBrac);
|
||||||
|
|
||||||
|
// constructor for keyword messages.
|
||||||
|
// FIXME: clsName should be typed to ObjCInterfaceType
|
||||||
|
ObjCMessageExpr(IdentifierInfo *clsName, SelectorInfo &selInfo,
|
||||||
|
ObjcKeywordMessage *keys, unsigned numargs, QualType retType,
|
||||||
|
SourceLocation LBrac, SourceLocation RBrac);
|
||||||
|
ObjCMessageExpr(Expr *receiver, SelectorInfo &selInfo,
|
||||||
|
ObjcKeywordMessage *keys, unsigned numargs, QualType retType,
|
||||||
|
SourceLocation LBrac, SourceLocation RBrac);
|
||||||
|
~ObjCMessageExpr() {
|
||||||
|
delete [] SubExprs;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Expr *getReceiver() const { return SubExprs[RECEIVER]; }
|
||||||
|
Expr *getReceiver() { return SubExprs[RECEIVER]; }
|
||||||
|
|
||||||
|
/// getNumArgs - Return the number of actual arguments to this call.
|
||||||
|
///
|
||||||
|
unsigned getNumArgs() const { return NumArgs; }
|
||||||
|
|
||||||
|
/// getArg - Return the specified argument.
|
||||||
|
Expr *getArg(unsigned Arg) {
|
||||||
|
assert(Arg < NumArgs && "Arg access out of range!");
|
||||||
|
return SubExprs[Arg+ARGS_START];
|
||||||
|
}
|
||||||
|
const Expr *getArg(unsigned Arg) const {
|
||||||
|
assert(Arg < NumArgs && "Arg access out of range!");
|
||||||
|
return SubExprs[Arg+ARGS_START];
|
||||||
|
}
|
||||||
|
SourceRange getSourceRange() const { return SourceRange(LBracloc, RBracloc); }
|
||||||
|
|
||||||
|
static bool classof(const Stmt *T) {
|
||||||
|
return T->getStmtClass() == ObjCMessageExprClass;
|
||||||
|
}
|
||||||
|
static bool classof(const ObjCMessageExpr *) { return true; }
|
||||||
|
|
||||||
|
// Iterators
|
||||||
|
virtual child_iterator child_begin();
|
||||||
|
virtual child_iterator child_end();
|
||||||
|
};
|
||||||
|
|
||||||
} // end namespace clang
|
} // end namespace clang
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -80,8 +80,9 @@ STMT(61, CXXBoolLiteralExpr , Expr)
|
||||||
// Obj-C Expressions.
|
// Obj-C Expressions.
|
||||||
STMT(70, ObjCStringLiteral , Expr)
|
STMT(70, ObjCStringLiteral , Expr)
|
||||||
STMT(71, ObjCEncodeExpr , Expr)
|
STMT(71, ObjCEncodeExpr , Expr)
|
||||||
|
STMT(72, ObjCMessageExpr , Expr)
|
||||||
|
|
||||||
LAST_EXPR(71)
|
LAST_EXPR(72)
|
||||||
|
|
||||||
#undef STMT
|
#undef STMT
|
||||||
#undef FIRST_STMT
|
#undef FIRST_STMT
|
||||||
|
|
|
@ -473,22 +473,28 @@ public:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
// This actions handles keyword message to classes.
|
// This actions handles keyword message to classes.
|
||||||
virtual ExprResult ActOnKeywordMessage(IdentifierInfo *receivingClassName,
|
virtual ExprResult ActOnKeywordMessage(
|
||||||
ObjcKeywordMessage *Keywords, unsigned NumKeywords) {
|
IdentifierInfo *receivingClassName,
|
||||||
|
ObjcKeywordMessage *Keywords, unsigned NumKeywords,
|
||||||
|
SourceLocation lbrac, SourceLocation rbrac) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
// This action handles keyword messages to instances.
|
// This action handles keyword messages to instances.
|
||||||
virtual ExprResult ActOnKeywordMessage(ExprTy *receiver,
|
virtual ExprResult ActOnKeywordMessage(ExprTy *receiver,
|
||||||
ObjcKeywordMessage *Keywords, unsigned NumKeywords) {
|
ObjcKeywordMessage *Keywords, unsigned NumKeywords,
|
||||||
|
SourceLocation lbrac, SourceLocation rbrac) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
// This actions handles keyword message to classes.
|
// This actions handles unary message to classes.
|
||||||
virtual ExprResult ActOnUnaryMessage(IdentifierInfo *receivingClassName,
|
virtual ExprResult ActOnUnaryMessage(
|
||||||
IdentifierInfo *selName) {
|
IdentifierInfo *receivingClassName, IdentifierInfo *selName,
|
||||||
|
SourceLocation lbrac, SourceLocation rbrac) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
// This action handles keyword messages to instances.
|
// This action handles unary messages to instances.
|
||||||
virtual ExprResult ActOnUnaryMessage(ExprTy *receiver,IdentifierInfo *sName) {
|
virtual ExprResult ActOnUnaryMessage(
|
||||||
|
ExprTy *receiver, IdentifierInfo *sName,
|
||||||
|
SourceLocation lbrac, SourceLocation rbrac) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
virtual DeclTy *ObjcClassDeclaration(Scope *S, SourceLocation AtClassLoc,
|
virtual DeclTy *ObjcClassDeclaration(Scope *S, SourceLocation AtClassLoc,
|
||||||
|
|
Loading…
Reference in New Issue