[cfe-commits] r102026 - in /cfe/trunk: include/clang/Parse/Action.h lib/Parse/MinimalAction.cpp lib/Parse/ParseInit.cpp lib/Parse/ParseObjc.cpp lib/Sema/Sema.h lib/Sema/SemaExprObjC.cpp

Douglas Gregor dgregor at apple.com
Wed Apr 21 13:38:14 PDT 2010


Author: dgregor
Date: Wed Apr 21 15:38:13 2010
New Revision: 102026

URL: http://llvm.org/viewvc/llvm-project?rev=102026&view=rev
Log:
Migrate the responsibility for turning the receiver name in an
Objective-C class message expression into a type from the parser
(which was doing so in two places) to Action::getObjCMessageKind()
which, in the case of Sema, reduces the number of name lookups we need
to perform.

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

Modified: cfe/trunk/include/clang/Parse/Action.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Action.h?rev=102026&r1=102025&r2=102026&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Action.h (original)
+++ cfe/trunk/include/clang/Parse/Action.h Wed Apr 21 15:38:13 2010
@@ -2373,9 +2373,7 @@
   ///
   /// \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 Name The identifier following the '['. 
   ///
   /// \param NameLoc The location of the identifier.
   ///
@@ -2383,12 +2381,16 @@
   ///
   /// \param HasTrailingDot Whether the name is followed by a period.
   /// 
+  /// \param ReceiverType If this routine returns \c ObjCClassMessage,
+  /// this argument will be set to the receiver type.
+  ///
   /// \returns The kind of message send.
   virtual ObjCMessageKind getObjCMessageKind(Scope *S,
-                                             IdentifierInfo *&Name,
+                                             IdentifierInfo *Name,
                                              SourceLocation NameLoc,
                                              bool IsSuper,
-                                             bool HasTrailingDot);
+                                             bool HasTrailingDot,
+                                             TypeTy *&ReceiverType);
 
   /// \brief Parsed a message send to 'super'.
   ///

Modified: cfe/trunk/lib/Parse/MinimalAction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/MinimalAction.cpp?rev=102026&r1=102025&r2=102026&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/MinimalAction.cpp (original)
+++ cfe/trunk/lib/Parse/MinimalAction.cpp Wed Apr 21 15:38:13 2010
@@ -27,15 +27,30 @@
 Action::~Action() {}
 
 Action::ObjCMessageKind Action::getObjCMessageKind(Scope *S,
-                                                   IdentifierInfo *&Name,
+                                                   IdentifierInfo *Name,
                                                    SourceLocation NameLoc,
                                                    bool IsSuper,
-                                                   bool HasTrailingDot) {
+                                                   bool HasTrailingDot,
+                                                   TypeTy *&ReceiverType) {
+  ReceiverType = 0;
+
   if (IsSuper && !HasTrailingDot && S->isInObjcMethodScope())
     return ObjCSuperMessage;
       
-  if (getTypeName(*Name, NameLoc, S))
+  if (TypeTy *TyName = getTypeName(*Name, NameLoc, S)) {
+    DeclSpec DS;
+    const char *PrevSpec = 0;
+    unsigned DiagID = 0;
+    if (!DS.SetTypeSpecType(DeclSpec::TST_typename, NameLoc, PrevSpec,
+                            DiagID, TyName)) {
+      DS.SetRangeEnd(NameLoc);
+      Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
+      TypeResult Ty = ActOnTypeName(S, DeclaratorInfo);
+      if (!Ty.isInvalid())
+        ReceiverType = Ty.get();
+    }
     return ObjCClassMessage;
+  }
       
   return ObjCInstanceMessage;
 }

Modified: cfe/trunk/lib/Parse/ParseInit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseInit.cpp?rev=102026&r1=102025&r2=102026&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseInit.cpp (original)
+++ cfe/trunk/lib/Parse/ParseInit.cpp Wed Apr 21 15:38:13 2010
@@ -130,15 +130,17 @@
     if (getLang().ObjC1 && Tok.is(tok::identifier)) {
       IdentifierInfo *II = Tok.getIdentifierInfo();
       SourceLocation IILoc = Tok.getLocation();
+      TypeTy *ReceiverType;
       // Three cases. This is a message send to a type: [type foo]
       // This is a message send to super:  [super foo]
       // This is a message sent to an expr:  [super.bar foo]
       switch (Action::ObjCMessageKind Kind
                 = Actions.getObjCMessageKind(CurScope, II, IILoc, 
                                              II == Ident_super,
-                                             NextToken().is(tok::period))) {
+                                             NextToken().is(tok::period),
+                                             ReceiverType)) {
       case Action::ObjCSuperMessage:
-      case Action::ObjCClassMessage: {
+      case Action::ObjCClassMessage:
         // If we have exactly one array designator, this used the GNU
         // 'designation: array-designator' extension, otherwise there should be no
         // designators at all!
@@ -154,36 +156,16 @@
                                                              ConsumeToken(),
                                                              0,
                                                              ExprArg(Actions));
-
-        // FIXME: This code is redundant with ParseObjCMessageExpr.
-        // Create the type that corresponds to the identifier (which
-        // names an Objective-C class).
-        TypeTy *Type = 0;
-        if (TypeTy *TyName = Actions.getTypeName(*II, IILoc, CurScope)) {
-          DeclSpec DS;
-          const char *PrevSpec = 0;
-          unsigned DiagID = 0;
-          if (!DS.SetTypeSpecType(DeclSpec::TST_typename, IILoc, PrevSpec,
-                                  DiagID, TyName)) {
-            DS.SetRangeEnd(IILoc);
-            Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
-            TypeResult Ty = Actions.ActOnTypeName(CurScope, DeclaratorInfo);
-            if (!Ty.isInvalid())
-              Type = Ty.get();
-          }
-        }
-
-        ConsumeToken(); // The identifier.
-        if (!Type) {
+        ConsumeToken(); // the identifier
+        if (!ReceiverType) {
           SkipUntil(tok::r_square);
           return ExprError();
         }
 
         return ParseAssignmentExprWithObjCMessageExprStart(StartLoc, 
                                                            SourceLocation(), 
-                                                           Type, 
+                                                           ReceiverType, 
                                                            ExprArg(Actions));
-      }
 
       case Action::ObjCInstanceMessage:
         // Fall through; we'll just parse the expression and

Modified: cfe/trunk/lib/Parse/ParseObjc.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseObjc.cpp?rev=102026&r1=102025&r2=102026&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseObjc.cpp (original)
+++ cfe/trunk/lib/Parse/ParseObjc.cpp Wed Apr 21 15:38:13 2010
@@ -1726,40 +1726,26 @@
   if (Tok.is(tok::identifier)) {
     IdentifierInfo *Name = Tok.getIdentifierInfo();
     SourceLocation NameLoc = Tok.getLocation();
+    TypeTy *ReceiverType;
     switch (Actions.getObjCMessageKind(CurScope, Name, NameLoc,
                                        Name == Ident_super,
-                                       NextToken().is(tok::period))) {
+                                       NextToken().is(tok::period),
+                                       ReceiverType)) {
     case Action::ObjCSuperMessage:
       return ParseObjCMessageExpressionBody(LBracLoc, ConsumeToken(), 0,
                                             ExprArg(Actions));
 
-    case Action::ObjCClassMessage: {
-      // Create the type that corresponds to the identifier (which
-      // names an Objective-C class).
-      TypeTy *Type = 0;
-      if (TypeTy *TyName = Actions.getTypeName(*Name, NameLoc, CurScope)) {
-        DeclSpec DS;
-        const char *PrevSpec = 0;
-        unsigned DiagID = 0;
-        if (!DS.SetTypeSpecType(DeclSpec::TST_typename, NameLoc, PrevSpec,
-                                DiagID, TyName)) {
-          DS.SetRangeEnd(NameLoc);
-          Declarator DeclaratorInfo(DS, Declarator::TypeNameContext);
-          TypeResult Ty = Actions.ActOnTypeName(CurScope, DeclaratorInfo);
-          if (!Ty.isInvalid())
-            Type = Ty.get();
-        }
-      }
-
-      ConsumeToken(); // The identifier.
-      if (!Type) {
+    case Action::ObjCClassMessage:
+      if (!ReceiverType) {
         SkipUntil(tok::r_square);
         return ExprError();
       }
 
-      return ParseObjCMessageExpressionBody(LBracLoc, SourceLocation(), Type,
+      ConsumeToken(); // the type name
+
+      return ParseObjCMessageExpressionBody(LBracLoc, SourceLocation(), 
+                                            ReceiverType,
                                             ExprArg(Actions));
-    }
         
     case Action::ObjCInstanceMessage:
       // Fall through to parse an expression.

Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=102026&r1=102025&r2=102026&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Wed Apr 21 15:38:13 2010
@@ -3867,10 +3867,11 @@
                             SourceLocation propertyNameLoc);
 
   virtual ObjCMessageKind getObjCMessageKind(Scope *S,
-                                             IdentifierInfo *&Name,
+                                             IdentifierInfo *Name,
                                              SourceLocation NameLoc,
                                              bool IsSuper,
-                                             bool HasTrailingDot);
+                                             bool HasTrailingDot,
+                                             TypeTy *&ReceiverType);
 
   virtual OwningExprResult ActOnSuperMessage(Scope *S, SourceLocation SuperLoc,
                                              Selector Sel,

Modified: cfe/trunk/lib/Sema/SemaExprObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprObjC.cpp?rev=102026&r1=102025&r2=102026&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprObjC.cpp Wed Apr 21 15:38:13 2010
@@ -503,10 +503,13 @@
 }
 
 Sema::ObjCMessageKind Sema::getObjCMessageKind(Scope *S,
-                                               IdentifierInfo *&Name,
+                                               IdentifierInfo *Name,
                                                SourceLocation NameLoc,
                                                bool IsSuper,
-                                               bool HasTrailingDot) {
+                                               bool HasTrailingDot,
+                                               TypeTy *&ReceiverType) {
+  ReceiverType = 0;
+
   // If the identifier is "super" and there is no trailing dot, we're
   // messaging super.
   if (IsSuper && !HasTrailingDot && S->isInObjcMethodScope())
@@ -541,11 +544,19 @@
     // We found something. If it's a type, then we have a class
     // message. Otherwise, it's an instance message.
     NamedDecl *ND = Result.getFoundDecl();
-    if (isa<ObjCInterfaceDecl>(ND) || isa<TypeDecl>(ND) || 
-        isa<UnresolvedUsingTypenameDecl>(ND))
-      return ObjCClassMessage;
-
-    return ObjCInstanceMessage;
+    QualType T;
+    if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(ND))
+      T = Context.getObjCInterfaceType(Class);
+    else if (TypeDecl *Type = dyn_cast<TypeDecl>(ND))
+      T = Context.getTypeDeclType(Type);
+    else 
+      return ObjCInstanceMessage;
+
+    //  We have a class message, and T is the type we're
+    //  messaging. Build source-location information for it.
+    TypeSourceInfo *TSInfo = Context.getTrivialTypeSourceInfo(T, NameLoc);
+    ReceiverType = CreateLocInfoType(T, TSInfo).getAsOpaquePtr();
+    return ObjCClassMessage;
   }
   }
 
@@ -561,7 +572,7 @@
       // If we found a declaration, correct when it refers to an Objective-C
       // class.
       NamedDecl *ND = Result.getFoundDecl();
-      if (isa<ObjCInterfaceDecl>(ND)) {
+      if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(ND)) {
         Diag(NameLoc, diag::err_unknown_receiver_suggest)
           << Name << Result.getLookupName()
           << FixItHint::CreateReplacement(SourceRange(NameLoc),
@@ -569,7 +580,9 @@
         Diag(ND->getLocation(), diag::note_previous_decl)
           << Corrected;
 
-        Name = ND->getIdentifier();
+        QualType T = Context.getObjCInterfaceType(Class);
+        TypeSourceInfo *TSInfo = Context.getTrivialTypeSourceInfo(T, NameLoc);
+        ReceiverType = CreateLocInfoType(T, TSInfo).getAsOpaquePtr();
         return ObjCClassMessage;
       }
     } else if (Result.empty() && Corrected.getAsIdentifierInfo() &&





More information about the cfe-commits mailing list