[cfe-commits] r85930 - in /cfe/trunk: include/clang/Basic/DiagnosticParseKinds.td include/clang/Basic/DiagnosticSemaKinds.td include/clang/Parse/Action.h include/clang/Parse/Parser.h lib/Parse/ParseDecl.cpp lib/Parse/ParseExpr.cpp lib/Parse/ParseExprCXX.cpp lib/Sema/Sema.h lib/Sema/SemaExpr.cpp lib/Sema/SemaExprCXX.cpp lib/Sema/SemaTemplate.cpp lib/Sema/TreeTransform.h test/SemaCXX/invalid-member-expr.cpp

Douglas Gregor dgregor at apple.com
Tue Nov 3 11:44:04 PST 2009


Author: dgregor
Date: Tue Nov  3 13:44:04 2009
New Revision: 85930

URL: http://llvm.org/viewvc/llvm-project?rev=85930&view=rev
Log:
Replace the code that parses member access expressions after "." or
"->" with a use of ParseUnqualifiedId. Collapse
ActOnMemberReferenceExpr, ActOnDestructorReferenceExpr (both of them),
ActOnOverloadedOperatorReferenceExpr,
ActOnConversionOperatorReferenceExpr, and
ActOnMemberTemplateIdReferenceExpr into a single, new action
ActOnMemberAccessExpr that does the same thing more cleanly (and can
keep more source-location information).


Modified:
    cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/include/clang/Parse/Action.h
    cfe/trunk/include/clang/Parse/Parser.h
    cfe/trunk/lib/Parse/ParseDecl.cpp
    cfe/trunk/lib/Parse/ParseExpr.cpp
    cfe/trunk/lib/Parse/ParseExprCXX.cpp
    cfe/trunk/lib/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/lib/Sema/SemaExprCXX.cpp
    cfe/trunk/lib/Sema/SemaTemplate.cpp
    cfe/trunk/lib/Sema/TreeTransform.h
    cfe/trunk/test/SemaCXX/invalid-member-expr.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td?rev=85930&r1=85929&r2=85930&view=diff

==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td Tue Nov  3 13:44:04 2009
@@ -216,7 +216,8 @@
 def err_no_matching_param : Error<"parameter named %0 is missing">;
 
 /// C++ parser diagnostics
-def err_expected_unqualified_id : Error<"expected unqualified-id">;
+def err_expected_unqualified_id : Error<
+  "expected %select{identifier|unqualified-id}0">;
 def err_func_def_no_params : Error<
   "function definition does not declare parameters">;
 def err_expected_lparen_after_type : Error<
@@ -233,6 +234,8 @@
 def err_expected_lbrace_or_comma : Error<"expected '{' or ','">;
 def err_using_namespace_in_class : Error<
   "'using namespace' in class not allowed">;
+def err_ident_in_pseudo_dtor_not_a_type : Error<
+  "identifier %0 in pseudo-destructor expression does not name a type">;
 
 // C++ derived classes
 def err_dup_virtual : Error<"duplicate 'virtual' in base specifier">;

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=85930&r1=85929&r2=85930&view=diff

==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Tue Nov  3 13:44:04 2009
@@ -1725,8 +1725,6 @@
 def err_return_in_constructor_handler : Error<
   "return in the catch of a function try block of a constructor is illegal">;
 
-def err_ident_in_pseudo_dtor_not_a_type : Error<
-  "identifier %0 in pseudo-destructor expression does not name a type">;
 def err_operator_arrow_circular : Error<
   "circular pointer delegation detected">;
 def err_pseudo_dtor_base_not_scalar : Error<

Modified: cfe/trunk/include/clang/Parse/Action.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Action.h?rev=85930&r1=85929&r2=85930&view=diff

==============================================================================
--- cfe/trunk/include/clang/Parse/Action.h (original)
+++ cfe/trunk/include/clang/Parse/Action.h Tue Nov  3 13:44:04 2009
@@ -922,16 +922,42 @@
                                                    SourceLocation RLoc) {
     return ExprEmpty();
   }
-  virtual OwningExprResult ActOnMemberReferenceExpr(Scope *S, ExprArg Base,
-                                                    SourceLocation OpLoc,
-                                                    tok::TokenKind OpKind,
-                                                    SourceLocation MemberLoc,
-                                                    IdentifierInfo &Member,
-                                                    DeclPtrTy ObjCImpDecl,
-                                                const CXXScopeSpec *SS = 0) {
+  
+  /// \brief Parsed a member access expresion (C99 6.5.2.3, C++ [expr.ref])
+  /// of the form \c x.m or \c p->m.
+  ///
+  /// \param S the scope in which the member access expression occurs.
+  ///
+  /// \param Base the class or pointer to class into which this member
+  /// access expression refers, e.g., \c x in \c x.m.
+  ///
+  /// \param OpLoc the location of the "." or "->" operator.
+  ///
+  /// \param OpKind the kind of member access operator, which will be either
+  /// tok::arrow ("->") or tok::period (".").
+  ///
+  /// \param SS in C++, the nested-name-specifier that precedes the member
+  /// name, if any.
+  ///
+  /// \param Member the name of the member that we are referring to. In C,
+  /// this will always store an identifier; in C++, we may also have operator
+  /// names, conversion function names, destructors, and template names.
+  ///
+  /// \param ObjCImpDecl the Objective-C implementation declaration.
+  /// FIXME: Do we really need this?
+  ///
+  /// \param HasTrailingLParen whether this member name is immediately followed
+  /// by a left parentheses ('(').
+  virtual OwningExprResult ActOnMemberAccessExpr(Scope *S, ExprArg Base,
+                                                 SourceLocation OpLoc,
+                                                 tok::TokenKind OpKind,
+                                                 const CXXScopeSpec &SS,
+                                                 UnqualifiedId &Member,
+                                                 DeclPtrTy ObjCImpDecl,
+                                                 bool HasTrailingLParen) {
     return ExprEmpty();
   }
-
+                                                 
   /// ActOnCallExpr - Handle a call to Fn with the specified array of arguments.
   /// This provides the location of the left/right parens and a list of comma
   /// locations.  There are guaranteed to be one fewer commas than arguments,
@@ -1361,123 +1387,6 @@
     return ExprEmpty();
   }
 
-  /// ActOnDestructorReferenceExpr - Parsed a destructor reference, for example:
-  ///
-  /// t->~T();
-  virtual OwningExprResult
-  ActOnDestructorReferenceExpr(Scope *S, ExprArg Base,
-                               SourceLocation OpLoc,
-                               tok::TokenKind OpKind,
-                               SourceLocation ClassNameLoc,
-                               IdentifierInfo *ClassName,
-                               const CXXScopeSpec &SS,
-                               bool HasTrailingLParen) {
-    return ExprEmpty();
-  }
-
-  /// \brief Parsed a C++ destructor reference that refers to a type.
-  ///
-  /// This action is used when parsing a destructor reference that uses a 
-  /// template-id, e.g.,
-  ///
-  /// \code
-  /// t->~Tmpl<T1, T2>
-  /// \endcode
-  ///
-  /// \param S the scope in which the destructor reference occurs.
-  /// \param Base the base object of the destructor reference expression.
-  /// \param OpLoc the location of the operator ('.' or '->').
-  /// \param OpKind the kind of the destructor reference operator ('.' or '->').
-  /// \param TypeRange the source range that covers the destructor type.
-  /// \param Type the type that is being destroyed.
-  /// \param SS the scope specifier that precedes the destructor name.
-  /// \param HasTrailingLParen whether the destructor name is followed by a '('.
-  virtual OwningExprResult
-  ActOnDestructorReferenceExpr(Scope *S, ExprArg Base,
-                               SourceLocation OpLoc,
-                               tok::TokenKind OpKind,
-                               SourceRange TypeRange,
-                               TypeTy *Type,
-                               const CXXScopeSpec &SS,
-                               bool HasTrailingLParen) {
-    return ExprEmpty();
-  }
-  
-  /// ActOnOverloadedOperatorReferenceExpr - Parsed an overloaded operator
-  /// reference, for example:
-  ///
-  /// t.operator++();
-  virtual OwningExprResult
-  ActOnOverloadedOperatorReferenceExpr(Scope *S, ExprArg Base,
-                                       SourceLocation OpLoc,
-                                       tok::TokenKind OpKind,
-                                       SourceLocation ClassNameLoc,
-                                       OverloadedOperatorKind OverOpKind,
-                                       const CXXScopeSpec *SS = 0) {
-    return ExprEmpty();
-  }
-
-  /// ActOnConversionOperatorReferenceExpr - Parsed an overloaded conversion
-  /// function reference, for example:
-  ///
-  /// t.operator int();
-  virtual OwningExprResult
-  ActOnConversionOperatorReferenceExpr(Scope *S, ExprArg Base,
-                                       SourceLocation OpLoc,
-                                       tok::TokenKind OpKind,
-                                       SourceLocation ClassNameLoc,
-                                       TypeTy *Ty,
-                                       const CXXScopeSpec *SS = 0) {
-    return ExprEmpty();
-  }
-
-  /// \brief Parsed a reference to a member template-id.
-  ///
-  /// This callback will occur instead of ActOnMemberReferenceExpr() when the
-  /// member in question is a template for which the code provides an
-  /// explicitly-specified template argument list, e.g.,
-  ///
-  /// \code
-  /// x.f<int>()
-  /// \endcode
-  ///
-  /// \param S the scope in which the member reference expression occurs
-  ///
-  /// \param Base the expression to the left of the "." or "->".
-  ///
-  /// \param OpLoc the location of the "." or "->".
-  ///
-  /// \param OpKind the kind of operator, which will be "." or "->".
-  ///
-  /// \param SS the scope specifier that precedes the template-id in, e.g.,
-  /// \c x.Base::f<int>().
-  ///
-  /// \param Template the declaration of the template that is being referenced.
-  ///
-  /// \param TemplateNameLoc the location of the template name referred to by
-  /// \p Template.
-  ///
-  /// \param LAngleLoc the location of the left angle bracket ('<')
-  ///
-  /// \param TemplateArgs the (possibly-empty) template argument list provided
-  /// as part of the member reference.
-  ///
-  /// \param RAngleLoc the location of the right angle bracket ('>')
-  virtual OwningExprResult
-  ActOnMemberTemplateIdReferenceExpr(Scope *S, ExprArg Base,
-                                     SourceLocation OpLoc,
-                                     tok::TokenKind OpKind,
-                                     const CXXScopeSpec &SS,
-                                     // FIXME: "template" keyword?
-                                     TemplateTy Template,
-                                     SourceLocation TemplateNameLoc,
-                                     SourceLocation LAngleLoc,
-                                     ASTTemplateArgsPtr TemplateArgs,
-                                     SourceLocation *TemplateArgLocs,
-                                     SourceLocation RAngleLoc) {
-    return ExprEmpty();
-  }
-
   /// ActOnFinishFullExpr - Called whenever a full expression has been parsed.
   /// (C++ [intro.execution]p12).
   virtual OwningExprResult ActOnFinishFullExpr(ExprArg Expr) {

Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=85930&r1=85929&r2=85930&view=diff

==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Tue Nov  3 13:44:04 2009
@@ -1216,10 +1216,12 @@
                                     IdentifierInfo *Name,
                                     SourceLocation NameLoc,
                                     bool EnteringContext,
+                                    TypeTy *ObjectType,
                                     UnqualifiedId &Id);
   bool ParseUnqualifiedId(CXXScopeSpec &SS, bool EnteringContext,
                           bool AllowDestructorName,
                           bool AllowConstructorName,
+                          TypeTy *ObjectType,
                           UnqualifiedId &Result);
     
   //===--------------------------------------------------------------------===//

Modified: cfe/trunk/lib/Parse/ParseDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=85930&r1=85929&r2=85930&view=diff

==============================================================================
--- cfe/trunk/lib/Parse/ParseDecl.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDecl.cpp Tue Nov  3 13:44:04 2009
@@ -2314,6 +2314,7 @@
                              /*EnteringContext=*/true, 
                              /*AllowDestructorName=*/true, 
                    /*AllowConstructorName=*/!D.getDeclSpec().hasTypeSpecifier(), 
+                             /*ObjectType=*/0,
                              D.getName())) {
         D.SetIdentifier(0, Tok.getLocation());
         D.setInvalidType(true);
@@ -2348,7 +2349,7 @@
       Diag(Tok, diag::err_expected_member_name_or_semi)
         << D.getDeclSpec().getSourceRange();
     else if (getLang().CPlusPlus)
-      Diag(Tok, diag::err_expected_unqualified_id);
+      Diag(Tok, diag::err_expected_unqualified_id) << getLang().CPlusPlus;
     else
       Diag(Tok, diag::err_expected_ident_lparen);
     D.SetIdentifier(0, Tok.getLocation());

Modified: cfe/trunk/lib/Parse/ParseExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExpr.cpp?rev=85930&r1=85929&r2=85930&view=diff

==============================================================================
--- cfe/trunk/lib/Parse/ParseExpr.cpp (original)
+++ cfe/trunk/lib/Parse/ParseExpr.cpp Tue Nov  3 13:44:04 2009
@@ -968,6 +968,21 @@
         ConsumeToken();
       }
       
+      UnqualifiedId Name;
+      if (ParseUnqualifiedId(SS, 
+                             /*EnteringContext=*/false, 
+                             /*AllowDestructorName=*/true,
+                             /*AllowConstructorName=*/false, 
+                             ObjectType,
+                             Name))
+        return ExprError();
+      
+      if (!LHS.isInvalid())
+        LHS = Actions.ActOnMemberAccessExpr(CurScope, move(LHS), OpLoc, OpKind,
+                                            SS, Name, ObjCImpDecl,
+                                            Tok.is(tok::l_paren));
+      
+#if 0
       if (Tok.is(tok::identifier)) {
         if (!LHS.isInvalid())
           LHS = Actions.ActOnMemberReferenceExpr(CurScope, move(LHS), OpLoc,
@@ -1072,6 +1087,7 @@
         Diag(Tok, diag::err_expected_ident);
         return ExprError();
       }
+#endif
       break;
     }
     case tok::plusplus:    // postfix-expression: postfix-expression '++'

Modified: cfe/trunk/lib/Parse/ParseExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExprCXX.cpp?rev=85930&r1=85929&r2=85930&view=diff

==============================================================================
--- cfe/trunk/lib/Parse/ParseExprCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseExprCXX.cpp Tue Nov  3 13:44:04 2009
@@ -315,76 +315,13 @@
                          /*EnteringContext=*/false, 
                          /*AllowDestructorName=*/false, 
                          /*AllowConstructorName=*/false, 
+                         /*ObjectType=*/0,
                          Name))
     return ExprError();
   
   return Actions.ActOnIdExpression(CurScope, SS, Name, Tok.is(tok::l_paren),
                                    isAddressOfOperand);
   
-#if 0
-  // unqualified-id:
-  //   identifier
-  //   operator-function-id
-  //   conversion-function-id
-  //   '~' class-name                        [TODO]
-  //   template-id
-  //
-  switch (Tok.getKind()) {
-  default:
-    return ExprError(Diag(Tok, diag::err_expected_unqualified_id));
-
-  case tok::identifier: {
-    // Consume the identifier so that we can see if it is followed by a '('.
-    IdentifierInfo &II = *Tok.getIdentifierInfo();
-    SourceLocation L = ConsumeToken();
-    return Actions.ActOnIdentifierExpr(CurScope, L, II, Tok.is(tok::l_paren),
-                                       &SS, isAddressOfOperand);
-  }
-
-  case tok::kw_operator: {
-    SourceLocation OperatorLoc = Tok.getLocation();
-    if (OverloadedOperatorKind Op = TryParseOperatorFunctionId())
-      return Actions.ActOnCXXOperatorFunctionIdExpr(
-                       CurScope, OperatorLoc, Op, Tok.is(tok::l_paren), SS,
-                       isAddressOfOperand);
-    if (TypeTy *Type = ParseConversionFunctionId())
-      return Actions.ActOnCXXConversionFunctionExpr(CurScope, OperatorLoc, Type,
-                                                    Tok.is(tok::l_paren), SS,
-                                                    isAddressOfOperand);
-
-    // We already complained about a bad conversion-function-id,
-    // above.
-    return ExprError();
-  }
-
-  case tok::annot_template_id: {
-    TemplateIdAnnotation *TemplateId
-      = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue());
-    assert((TemplateId->Kind == TNK_Function_template ||
-            TemplateId->Kind == TNK_Dependent_template_name) &&
-           "A template type name is not an ID expression");
-
-    ASTTemplateArgsPtr TemplateArgsPtr(Actions,
-                                       TemplateId->getTemplateArgs(),
-                                       TemplateId->getTemplateArgIsType(),
-                                       TemplateId->NumArgs);
-
-    OwningExprResult Result
-      = Actions.ActOnTemplateIdExpr(SS, 
-                                    TemplateTy::make(TemplateId->Template),
-                                    TemplateId->TemplateNameLoc,
-                                    TemplateId->LAngleLoc,
-                                    TemplateArgsPtr,
-                                    TemplateId->getTemplateArgLocations(),
-                                    TemplateId->RAngleLoc);
-    ConsumeToken(); // Consume the template-id token
-    return move(Result);
-  }
-
-  } // switch.
-
-  assert(0 && "The switch was supposed to take care everything.");
-#endif
 }
 
 /// ParseCXXCasts - This handles the various ways to cast expressions to another
@@ -806,6 +743,7 @@
                                           IdentifierInfo *Name,
                                           SourceLocation NameLoc,
                                           bool EnteringContext,
+                                          TypeTy *ObjectType,
                                           UnqualifiedId &Id) {
   assert(Tok.is(tok::less) && "Expected '<' to finish parsing a template-id");
   
@@ -814,14 +752,13 @@
   switch (Id.getKind()) {
   case UnqualifiedId::IK_Identifier:
     TNK = Actions.isTemplateName(CurScope, *Id.Identifier, Id.StartLocation, 
-                                 &SS, /*ObjectType=*/0, EnteringContext,
-                                 Template);
+                                 &SS, ObjectType, EnteringContext, Template);
     break;
       
   case UnqualifiedId::IK_OperatorFunctionId: {
     // FIXME: Temporary hack: warn that we are completely ignoring the 
     // template arguments for now.
-    // Parse the enclosed template argument list.
+    // Parse the enclosed template argument list and throw it away.
     SourceLocation LAngleLoc, RAngleLoc;
     TemplateArgList TemplateArgs;
     TemplateArgIsTypeList TemplateArgIsType;
@@ -840,15 +777,32 @@
   }
       
   case UnqualifiedId::IK_ConstructorName:
-    TNK = Actions.isTemplateName(CurScope, *Name, NameLoc, 
-                                 &SS, /*ObjectType=*/0, EnteringContext,
-                                 Template);
+    TNK = Actions.isTemplateName(CurScope, *Name, NameLoc, &SS, ObjectType, 
+                                 EnteringContext, Template);
     break;
       
   case UnqualifiedId::IK_DestructorName:
-    TNK = Actions.isTemplateName(CurScope, *Name, NameLoc,
-                                 &SS, /*ObjectType=*/0, EnteringContext,
-                                 Template);
+    if (ObjectType) {
+      Template = Actions.ActOnDependentTemplateName(SourceLocation(), *Name, 
+                                                    NameLoc, SS, ObjectType);
+      TNK = TNK_Dependent_template_name;
+      if (!Template.get())
+        return true;
+    } else {
+      TNK = Actions.isTemplateName(CurScope, *Name, NameLoc, &SS, ObjectType, 
+                                   EnteringContext, Template);
+      
+      if (TNK == TNK_Non_template && Id.DestructorName == 0) {
+        // The identifier following the destructor did not refer to a template
+        // or to a type. Complain.
+        if (ObjectType)
+          Diag(NameLoc, diag::err_ident_in_pseudo_dtor_not_a_type)
+            << Name;        
+        else
+          Diag(NameLoc, diag::err_destructor_class_name);
+        return true;        
+      }
+    }
     break;
       
   default:
@@ -974,6 +928,7 @@
 bool Parser::ParseUnqualifiedId(CXXScopeSpec &SS, bool EnteringContext,
                                 bool AllowDestructorName,
                                 bool AllowConstructorName,
+                                TypeTy *ObjectType,
                                 UnqualifiedId &Result) {
   // unqualified-id:
   //   identifier
@@ -997,7 +952,7 @@
     // If the next token is a '<', we may have a template.
     if (Tok.is(tok::less))
       return ParseUnqualifiedIdTemplateId(SS, Id, IdLoc, EnteringContext, 
-                                          Result);
+                                          ObjectType, Result);
     
     return false;
   }
@@ -1110,7 +1065,8 @@
       // If the next token is a '<', we may have a template.
       if (Tok.is(tok::less))
         return ParseUnqualifiedIdTemplateId(SS, 0, SourceLocation(), 
-                                            EnteringContext, Result);
+                                            EnteringContext, ObjectType, 
+                                            Result);
 
       return false;
     }
@@ -1166,24 +1122,30 @@
     IdentifierInfo *ClassName = Tok.getIdentifierInfo();
     SourceLocation ClassNameLoc = ConsumeToken();
     
+    if (Tok.is(tok::less)) {
+      Result.setDestructorName(TildeLoc, 0, ClassNameLoc);
+      return ParseUnqualifiedIdTemplateId(SS, ClassName, ClassNameLoc,
+                                          EnteringContext, ObjectType, Result);
+    }
+    
     // Note that this is a destructor name.
     Action::TypeTy *Ty = Actions.getTypeName(*ClassName, ClassNameLoc,
                                              CurScope, &SS);
     if (!Ty) {
-      Diag(ClassNameLoc, diag::err_destructor_class_name);
+      if (ObjectType)
+        Diag(ClassNameLoc, diag::err_ident_in_pseudo_dtor_not_a_type)
+          << ClassName;        
+      else
+        Diag(ClassNameLoc, diag::err_destructor_class_name);
       return true;
     }
     
     Result.setDestructorName(TildeLoc, Ty, ClassNameLoc);
-    
-    if (Tok.is(tok::less))
-      return ParseUnqualifiedIdTemplateId(SS, ClassName, ClassNameLoc,
-                                          EnteringContext, Result);
-
     return false;
   }
   
-  Diag(Tok, diag::err_expected_unqualified_id);
+  Diag(Tok, diag::err_expected_unqualified_id)
+    << getLang().CPlusPlus;
   return true;
 }
 

Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=85930&r1=85929&r2=85930&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Tue Nov  3 13:44:04 2009
@@ -1714,13 +1714,14 @@
                                             const CXXScopeSpec *SS,
                                           NamedDecl *FirstQualifierInScope = 0);
 
-  virtual OwningExprResult ActOnMemberReferenceExpr(Scope *S, ExprArg Base,
-                                                    SourceLocation OpLoc,
-                                                    tok::TokenKind OpKind,
-                                                    SourceLocation MemberLoc,
-                                                    IdentifierInfo &Member,
-                                                    DeclPtrTy ImplDecl,
-                                                    const CXXScopeSpec *SS = 0);
+  virtual OwningExprResult ActOnMemberAccessExpr(Scope *S, ExprArg Base,
+                                                 SourceLocation OpLoc,
+                                                 tok::TokenKind OpKind,
+                                                 const CXXScopeSpec &SS,
+                                                 UnqualifiedId &Member,
+                                                 DeclPtrTy ObjCImpDecl,
+                                                 bool HasTrailingLParen);
+    
   virtual void ActOnDefaultCtorInitializers(DeclPtrTy CDtorDecl);
   bool ConvertArgumentsForCall(CallExpr *Call, Expr *Fn,
                                FunctionDecl *FDecl,
@@ -2096,52 +2097,6 @@
                                                         tok::TokenKind OpKind,
                                                         TypeTy *&ObjectType);
 
-  virtual OwningExprResult
-  ActOnDestructorReferenceExpr(Scope *S, ExprArg Base,
-                               SourceLocation OpLoc,
-                               tok::TokenKind OpKind,
-                               SourceLocation ClassNameLoc,
-                               IdentifierInfo *ClassName,
-                               const CXXScopeSpec &SS,
-                               bool HasTrailingLParen);
-
-  virtual OwningExprResult
-  ActOnDestructorReferenceExpr(Scope *S, ExprArg Base,
-                               SourceLocation OpLoc,
-                               tok::TokenKind OpKind,
-                               SourceRange TypeRange,
-                               TypeTy *Type,
-                               const CXXScopeSpec &SS,
-                               bool HasTrailingLParen);
-    
-  virtual OwningExprResult
-  ActOnOverloadedOperatorReferenceExpr(Scope *S, ExprArg Base,
-                                       SourceLocation OpLoc,
-                                       tok::TokenKind OpKind,
-                                       SourceLocation ClassNameLoc,
-                                       OverloadedOperatorKind OverOpKind,
-                                       const CXXScopeSpec *SS = 0);
-  virtual OwningExprResult
-  ActOnConversionOperatorReferenceExpr(Scope *S, ExprArg Base,
-                                       SourceLocation OpLoc,
-                                       tok::TokenKind OpKind,
-                                       SourceLocation ClassNameLoc,
-                                       TypeTy *Ty,
-                                       const CXXScopeSpec *SS = 0);
-
-  virtual OwningExprResult
-  ActOnMemberTemplateIdReferenceExpr(Scope *S, ExprArg Base,
-                                     SourceLocation OpLoc,
-                                     tok::TokenKind OpKind,
-                                     const CXXScopeSpec &SS,
-                                     // FIXME: "template" keyword?
-                                     TemplateTy Template,
-                                     SourceLocation TemplateNameLoc,
-                                     SourceLocation LAngleLoc,
-                                     ASTTemplateArgsPtr TemplateArgs,
-                                     SourceLocation *TemplateArgLocs,
-                                     SourceLocation RAngleLoc);
-
   /// MaybeCreateCXXExprWithTemporaries - If the list of temporaries is
   /// non-empty, will create a new CXXExprWithTemporaries expression.
   /// Otherwise, just returs the passed in expression.

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=85930&r1=85929&r2=85930&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Tue Nov  3 13:44:04 2009
@@ -2479,13 +2479,72 @@
   return ExprError();
 }
 
-Action::OwningExprResult
-Sema::ActOnMemberReferenceExpr(Scope *S, ExprArg Base, SourceLocation OpLoc,
-                               tok::TokenKind OpKind, SourceLocation MemberLoc,
-                               IdentifierInfo &Member,
-                               DeclPtrTy ObjCImpDecl, const CXXScopeSpec *SS) {
-  return BuildMemberReferenceExpr(S, move(Base), OpLoc, OpKind, MemberLoc,
-                                  DeclarationName(&Member), ObjCImpDecl, SS);
+Sema::OwningExprResult Sema::ActOnMemberAccessExpr(Scope *S, ExprArg Base,
+                                                   SourceLocation OpLoc,
+                                                   tok::TokenKind OpKind,
+                                                   const CXXScopeSpec &SS,
+                                                   UnqualifiedId &Member,
+                                                   DeclPtrTy ObjCImpDecl,
+                                                   bool HasTrailingLParen) {
+  if (Member.getKind() == UnqualifiedId::IK_TemplateId) {
+    TemplateName Template
+      = TemplateName::getFromVoidPointer(Member.TemplateId->Template);
+    
+    // FIXME: We're going to end up looking up the template based on its name,
+    // twice!
+    DeclarationName Name;
+    if (TemplateDecl *ActualTemplate = Template.getAsTemplateDecl())
+      Name = ActualTemplate->getDeclName();
+    else if (OverloadedFunctionDecl *Ovl = Template.getAsOverloadedFunctionDecl())
+      Name = Ovl->getDeclName();
+    else
+      Name = Template.getAsDependentTemplateName()->getName();
+    
+    // Translate the parser's template argument list in our AST format.
+    ASTTemplateArgsPtr TemplateArgsPtr(*this,
+                                       Member.TemplateId->getTemplateArgs(),
+                                       Member.TemplateId->getTemplateArgIsType(),
+                                       Member.TemplateId->NumArgs);
+    
+    llvm::SmallVector<TemplateArgumentLoc, 16> TemplateArgs;
+    translateTemplateArguments(TemplateArgsPtr, 
+                               Member.TemplateId->getTemplateArgLocations(),
+                               TemplateArgs);
+    TemplateArgsPtr.release();
+    
+    // Do we have the save the actual template name? We might need it...
+    return BuildMemberReferenceExpr(S, move(Base), OpLoc, OpKind, 
+                                    Member.TemplateId->TemplateNameLoc,
+                                    Name, true, Member.TemplateId->LAngleLoc,
+                                    TemplateArgs.data(), TemplateArgs.size(),
+                                    Member.TemplateId->RAngleLoc, DeclPtrTy(),
+                                    &SS);
+  }
+  
+  // FIXME: We lose a lot of source information by mapping directly to the
+  // DeclarationName.
+  OwningExprResult Result
+    = BuildMemberReferenceExpr(S, move(Base), OpLoc, OpKind,
+                               Member.getSourceRange().getBegin(),
+                               GetNameFromUnqualifiedId(Member),
+                               ObjCImpDecl, &SS);
+  
+  if (Result.isInvalid() || HasTrailingLParen || 
+      Member.getKind() != UnqualifiedId::IK_DestructorName)
+    return move(Result);
+  
+  // The only way a reference to a destructor can be used is to
+  // immediately call them. Since the next token is not a '(', produce a
+  // diagnostic and build the call now.
+  Expr *E = (Expr *)Result.get();
+  SourceLocation ExpectedLParenLoc
+    = PP.getLocForEndOfToken(Member.getSourceRange().getEnd());
+  Diag(E->getLocStart(), diag::err_dtor_expr_without_call)
+    << isa<CXXPseudoDestructorExpr>(E)
+    << CodeModificationHint::CreateInsertion(ExpectedLParenLoc, "()");
+  
+  return ActOnCallExpr(0, move(Result), ExpectedLParenLoc,
+                       MultiExprArg(*this, 0, 0), 0, ExpectedLParenLoc);
 }
 
 Sema::OwningExprResult Sema::BuildCXXDefaultArgExpr(SourceLocation CallLoc,

Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=85930&r1=85929&r2=85930&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Tue Nov  3 13:44:04 2009
@@ -2114,110 +2114,6 @@
   return move(Base);
 }
 
-Sema::OwningExprResult
-Sema::ActOnDestructorReferenceExpr(Scope *S, ExprArg Base,
-                                   SourceLocation OpLoc,
-                                   tok::TokenKind OpKind,
-                                   SourceLocation ClassNameLoc,
-                                   IdentifierInfo *ClassName,
-                                   const CXXScopeSpec &SS,
-                                   bool HasTrailingLParen) {
-  if (SS.isInvalid())
-    return ExprError();
-
-  QualType BaseType;
-  if (isUnknownSpecialization(SS))
-    BaseType = Context.getTypenameType((NestedNameSpecifier *)SS.getScopeRep(),
-                                       ClassName);
-  else {
-    TypeTy *BaseTy = getTypeName(*ClassName, ClassNameLoc, S, &SS);
-    
-    // FIXME: If Base is dependent, we might not be able to resolve it here.
-    if (!BaseTy) {
-      Diag(ClassNameLoc, diag::err_ident_in_pseudo_dtor_not_a_type)
-        << ClassName;
-      return ExprError();
-    }
-
-    BaseType = GetTypeFromParser(BaseTy);
-  }
-
-  return ActOnDestructorReferenceExpr(S, move(Base), OpLoc, OpKind,
-                                      SourceRange(ClassNameLoc),
-                                      BaseType.getAsOpaquePtr(),
-                                      SS, HasTrailingLParen);
-}
-
-Sema::OwningExprResult
-Sema::ActOnDestructorReferenceExpr(Scope *S, ExprArg Base,
-                             SourceLocation OpLoc,
-                             tok::TokenKind OpKind,
-                             SourceRange TypeRange,
-                             TypeTy *T,
-                             const CXXScopeSpec &SS,
-                             bool HasTrailingLParen) {
-  QualType Type = GetTypeFromParser(T);
-  CanQualType CanType = Context.getCanonicalType(Type);
-  DeclarationName DtorName =
-    Context.DeclarationNames.getCXXDestructorName(CanType);
-  
-  OwningExprResult Result
-    = BuildMemberReferenceExpr(S, move(Base), OpLoc, OpKind, 
-                               TypeRange.getBegin(), DtorName, DeclPtrTy(), 
-                               &SS);
-  if (Result.isInvalid() || HasTrailingLParen)
-    return move(Result);
-  
-  // The only way a reference to a destructor can be used is to
-  // immediately call them. Since the next token is not a '(', produce a
-  // diagnostic and build the call now.
-  Expr *E = (Expr *)Result.get();
-  SourceLocation ExpectedLParenLoc = PP.getLocForEndOfToken(TypeRange.getEnd());
-  Diag(E->getLocStart(), diag::err_dtor_expr_without_call)
-    << isa<CXXPseudoDestructorExpr>(E)
-    << CodeModificationHint::CreateInsertion(ExpectedLParenLoc, "()");
-  
-  return ActOnCallExpr(0, move(Result), ExpectedLParenLoc,
-                       MultiExprArg(*this, 0, 0), 0, ExpectedLParenLoc);
-}
-
-Sema::OwningExprResult
-Sema::ActOnOverloadedOperatorReferenceExpr(Scope *S, ExprArg Base,
-                                           SourceLocation OpLoc,
-                                           tok::TokenKind OpKind,
-                                           SourceLocation ClassNameLoc,
-                                           OverloadedOperatorKind OverOpKind,
-                                           const CXXScopeSpec *SS) {
-  if (SS && SS->isInvalid())
-    return ExprError();
-
-  DeclarationName Name =
-    Context.DeclarationNames.getCXXOperatorName(OverOpKind);
-
-  return BuildMemberReferenceExpr(S, move(Base), OpLoc, OpKind, ClassNameLoc,
-                                  Name, DeclPtrTy(), SS);
-}
-
-Sema::OwningExprResult
-Sema::ActOnConversionOperatorReferenceExpr(Scope *S, ExprArg Base,
-                                           SourceLocation OpLoc,
-                                           tok::TokenKind OpKind,
-                                           SourceLocation ClassNameLoc,
-                                           TypeTy *Ty,
-                                           const CXXScopeSpec *SS) {
-  if (SS && SS->isInvalid())
-    return ExprError();
-
-  //FIXME: Preserve type source info.
-  QualType ConvType = GetTypeFromParser(Ty);
-  CanQualType ConvTypeCanon = Context.getCanonicalType(ConvType);
-  DeclarationName ConvName =
-    Context.DeclarationNames.getCXXConversionFunctionName(ConvTypeCanon);
-
-  return BuildMemberReferenceExpr(S, move(Base), OpLoc, OpKind, ClassNameLoc,
-                                  ConvName, DeclPtrTy(), SS);
-}
-
 CXXMemberCallExpr *Sema::BuildCXXMemberCallExpr(Expr *Exp, 
                                                 CXXMethodDecl *Method) {
   MemberExpr *ME = 

Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=85930&r1=85929&r2=85930&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Tue Nov  3 13:44:04 2009
@@ -1336,41 +1336,6 @@
                              RAngleLoc);
 }
 
-Sema::OwningExprResult
-Sema::ActOnMemberTemplateIdReferenceExpr(Scope *S, ExprArg Base,
-                                         SourceLocation OpLoc,
-                                         tok::TokenKind OpKind,
-                                         const CXXScopeSpec &SS,
-                                         TemplateTy TemplateD,
-                                         SourceLocation TemplateNameLoc,
-                                         SourceLocation LAngleLoc,
-                                         ASTTemplateArgsPtr TemplateArgsIn,
-                                         SourceLocation *TemplateArgLocs,
-                                         SourceLocation RAngleLoc) {
-  TemplateName Template = TemplateD.getAsVal<TemplateName>();
-
-  // FIXME: We're going to end up looking up the template based on its name,
-  // twice!
-  DeclarationName Name;
-  if (TemplateDecl *ActualTemplate = Template.getAsTemplateDecl())
-    Name = ActualTemplate->getDeclName();
-  else if (OverloadedFunctionDecl *Ovl = Template.getAsOverloadedFunctionDecl())
-    Name = Ovl->getDeclName();
-  else
-    Name = Template.getAsDependentTemplateName()->getName();
-
-  // Translate the parser's template argument list in our AST format.
-  llvm::SmallVector<TemplateArgumentLoc, 16> TemplateArgs;
-  translateTemplateArguments(TemplateArgsIn, TemplateArgLocs, TemplateArgs);
-  TemplateArgsIn.release();
-
-  // Do we have the save the actual template name? We might need it...
-  return BuildMemberReferenceExpr(S, move(Base), OpLoc, OpKind, TemplateNameLoc,
-                                  Name, true, LAngleLoc,
-                                  TemplateArgs.data(), TemplateArgs.size(),
-                                  RAngleLoc, DeclPtrTy(), &SS);
-}
-
 /// \brief Form a dependent template name.
 ///
 /// This action forms a dependent template name given the template

Modified: cfe/trunk/lib/Sema/TreeTransform.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=85930&r1=85929&r2=85930&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/TreeTransform.h (original)
+++ cfe/trunk/lib/Sema/TreeTransform.h Tue Nov  3 13:44:04 2009
@@ -1034,9 +1034,9 @@
                                                SourceLocation OpLoc,
                                                SourceLocation AccessorLoc,
                                                IdentifierInfo &Accessor) {
-    return getSema().ActOnMemberReferenceExpr(/*Scope=*/0, move(Base), OpLoc,
+    return getSema().BuildMemberReferenceExpr(/*Scope=*/0, move(Base), OpLoc,
                                               tok::period, AccessorLoc,
-                                              Accessor,
+                                              DeclarationName(&Accessor),
                                      /*FIXME?*/Sema::DeclPtrTy::make((Decl*)0));
   }
 
@@ -1568,7 +1568,7 @@
     SS.setScopeRep(Qualifier);
 
     // FIXME: We're going to end up looking up the template based on its name,
-    // twice! Also, duplicates part of Sema::ActOnMemberTemplateIdReferenceExpr.
+    // twice! Also, duplicates part of Sema::BuildMemberAccessExpr.
     DeclarationName Name;
     if (TemplateDecl *ActualTemplate = Template.getAsTemplateDecl())
       Name = ActualTemplate->getDeclName();

Modified: cfe/trunk/test/SemaCXX/invalid-member-expr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/invalid-member-expr.cpp?rev=85930&r1=85929&r2=85930&view=diff

==============================================================================
--- cfe/trunk/test/SemaCXX/invalid-member-expr.cpp (original)
+++ cfe/trunk/test/SemaCXX/invalid-member-expr.cpp Tue Nov  3 13:44:04 2009
@@ -5,8 +5,8 @@
 void test() {
   X x;
 
-  x.int; // expected-error{{expected identifier}}
-  x.~int(); // expected-error{{expected identifier}}
+  x.int; // expected-error{{expected unqualified-id}}
+  x.~int(); // expected-error{{expected the class name}}
   x.operator; // expected-error{{missing type specifier after 'operator'}}
   x.operator typedef; // expected-error{{missing type specifier after 'operator'}}
 }
@@ -14,8 +14,8 @@
 void test2() {
   X *x;
 
-  x->int; // expected-error{{expected identifier}}
-  x->~int(); // expected-error{{expected identifier}}
+  x->int; // expected-error{{expected unqualified-id}}
+  x->~int(); // expected-error{{expected the class name}}
   x->operator; // expected-error{{missing type specifier after 'operator'}}
   x->operator typedef; // expected-error{{missing type specifier after 'operator'}}
 }





More information about the cfe-commits mailing list