forked from OSchip/llvm-project
Introduce a parsing action to distinguish between class, instance, and
super message sends in Objective-C. No actual functionality change here, but it provides a hook so that Sema can typo-correct the receiver in some cases. llvm-svn: 101207
This commit is contained in:
parent
9162fb07be
commit
a148a1d40e
|
@ -2344,6 +2344,52 @@ public:
|
|||
return ExprEmpty();
|
||||
}
|
||||
|
||||
/// \brief Describes the kind of message expression indicated by a message
|
||||
/// send that starts with an identifier.
|
||||
enum ObjCMessageKind {
|
||||
/// \brief The message is sent to 'super'.
|
||||
ObjCSuperMessage,
|
||||
/// \brief The message is an instance message.
|
||||
ObjCInstanceMessage,
|
||||
/// \brief The message is a class message, and the identifier is a type
|
||||
/// name.
|
||||
ObjCClassMessage
|
||||
};
|
||||
|
||||
/// \brief Determine the kind of Objective-C message send that we will be
|
||||
/// performing based on the identifier given.
|
||||
///
|
||||
/// This action determines how a message send that starts with [
|
||||
/// identifier (followed by another identifier) will be parsed,
|
||||
/// e.g., as a class message, instance message, super message. The
|
||||
/// result depends on the meaning of the given identifier. If the
|
||||
/// identifier is unknown, the action should indicate that the
|
||||
/// message is an instance message.
|
||||
///
|
||||
/// By default, this routine applies syntactic disambiguation and uses
|
||||
/// \c getTypeName() to determine whether the identifier refers to a type.
|
||||
/// However, \c Action subclasses may override this routine to improve
|
||||
/// error recovery.
|
||||
///
|
||||
/// \param S The scope in which the message send occurs.
|
||||
///
|
||||
/// \param Name The identifier following the '['. This identifier
|
||||
/// may be modified by the action, if, for example, typo-correction
|
||||
/// finds a different class name.
|
||||
///
|
||||
/// \param NameLoc The location of the identifier.
|
||||
///
|
||||
/// \param IsSuper Whether the name is the pseudo-keyword "super".
|
||||
///
|
||||
/// \param HasTrailingDot Whether the name is followed by a period.
|
||||
///
|
||||
/// \returns The kind of message send.
|
||||
virtual ObjCMessageKind getObjCMessageKind(Scope *S,
|
||||
IdentifierInfo *&Name,
|
||||
SourceLocation NameLoc,
|
||||
bool IsSuper,
|
||||
bool HasTrailingDot);
|
||||
|
||||
// ActOnClassMessage - used for both unary and keyword messages.
|
||||
// ArgExprs is optional - if it is present, the number of expressions
|
||||
// is obtained from NumArgs.
|
||||
|
|
|
@ -26,6 +26,20 @@ ActionBase::~ActionBase() {}
|
|||
/// Out-of-line virtual destructor to provide home for Action class.
|
||||
Action::~Action() {}
|
||||
|
||||
Action::ObjCMessageKind Action::getObjCMessageKind(Scope *S,
|
||||
IdentifierInfo *&Name,
|
||||
SourceLocation NameLoc,
|
||||
bool IsSuper,
|
||||
bool HasTrailingDot) {
|
||||
if (IsSuper && !HasTrailingDot && S->isInObjcMethodScope())
|
||||
return ObjCSuperMessage;
|
||||
|
||||
if (getTypeName(*Name, NameLoc, S))
|
||||
return ObjCClassMessage;
|
||||
|
||||
return ObjCInstanceMessage;
|
||||
}
|
||||
|
||||
// Defined out-of-line here because of dependecy on AttributeList
|
||||
Action::DeclPtrTy Action::ActOnUsingDirective(Scope *CurScope,
|
||||
SourceLocation UsingLoc,
|
||||
|
|
|
@ -1719,17 +1719,18 @@ Parser::OwningExprResult Parser::ParseObjCMessageExpression() {
|
|||
SourceLocation LBracLoc = ConsumeBracket(); // consume '['
|
||||
|
||||
if (Tok.is(tok::identifier)) {
|
||||
IdentifierInfo *II = Tok.getIdentifierInfo();
|
||||
|
||||
// If this is '[' 'super', then this is a magic superclass message.
|
||||
// We parse '[' 'super' '.' 'foo' as an expression?
|
||||
if ((II == Ident_super && GetLookAheadToken(1).isNot(tok::period) &&
|
||||
CurScope->isInObjcMethodScope()) ||
|
||||
// Check to see if this is a typename. If so, it is a class message.
|
||||
Actions.getTypeName(*II, Tok.getLocation(), CurScope)) {
|
||||
SourceLocation NameLoc = ConsumeToken();
|
||||
return ParseObjCMessageExpressionBody(LBracLoc, NameLoc, II,
|
||||
IdentifierInfo *Name = Tok.getIdentifierInfo();
|
||||
SourceLocation NameLoc = Tok.getLocation();
|
||||
switch (Actions.getObjCMessageKind(CurScope, Name, NameLoc,
|
||||
Name == Ident_super,
|
||||
NextToken().is(tok::period))) {
|
||||
case Action::ObjCSuperMessage:
|
||||
case Action::ObjCClassMessage:
|
||||
return ParseObjCMessageExpressionBody(LBracLoc, ConsumeToken(), Name,
|
||||
ExprArg(Actions));
|
||||
|
||||
case Action::ObjCInstanceMessage:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue