[cfe-commits] r101207 - in /cfe/trunk: include/clang/Parse/Action.h lib/Parse/MinimalAction.cpp lib/Parse/ParseObjc.cpp

Douglas Gregor dgregor at apple.com
Tue Apr 13 19:22:16 PDT 2010


Author: dgregor
Date: Tue Apr 13 21:22:16 2010
New Revision: 101207

URL: http://llvm.org/viewvc/llvm-project?rev=101207&view=rev
Log:
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.


Modified:
    cfe/trunk/include/clang/Parse/Action.h
    cfe/trunk/lib/Parse/MinimalAction.cpp
    cfe/trunk/lib/Parse/ParseObjc.cpp

Modified: cfe/trunk/include/clang/Parse/Action.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Action.h?rev=101207&r1=101206&r2=101207&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Action.h (original)
+++ cfe/trunk/include/clang/Parse/Action.h Tue Apr 13 21:22:16 2010
@@ -2344,6 +2344,52 @@
     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.

Modified: cfe/trunk/lib/Parse/MinimalAction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/MinimalAction.cpp?rev=101207&r1=101206&r2=101207&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/MinimalAction.cpp (original)
+++ cfe/trunk/lib/Parse/MinimalAction.cpp Tue Apr 13 21:22:16 2010
@@ -26,6 +26,20 @@
 ///  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,

Modified: cfe/trunk/lib/Parse/ParseObjc.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseObjc.cpp?rev=101207&r1=101206&r2=101207&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseObjc.cpp (original)
+++ cfe/trunk/lib/Parse/ParseObjc.cpp Tue Apr 13 21:22:16 2010
@@ -1719,17 +1719,18 @@
   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;
     }
   }
   





More information about the cfe-commits mailing list