Use ParseUnqualifiedId when parsing id-expressions. This eliminates
yet another copy of the unqualified-id parsing code.

Also, use UnqualifiedId to simplify the Action interface for building
id-expressions. ActOnIdentifierExpr, ActOnCXXOperatorFunctionIdExpr,
ActOnCXXConversionFunctionExpr, and ActOnTemplateIdExpr have all been
removed in favor of the new ActOnIdExpression action.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@85904 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp
index 477e6fb..12025c6 100644
--- a/lib/Parse/ParseExpr.cpp
+++ b/lib/Parse/ParseExpr.cpp
@@ -651,7 +651,11 @@
     // Function designators are allowed to be undeclared (C99 6.5.1p2), so we
     // need to know whether or not this identifier is a function designator or
     // not.
-    Res = Actions.ActOnIdentifierExpr(CurScope, ILoc, II, Tok.is(tok::l_paren));
+    UnqualifiedId Name;
+    CXXScopeSpec ScopeSpec;
+    Name.setIdentifier(&II, ILoc);
+    Res = Actions.ActOnIdExpression(CurScope, ScopeSpec, Name, 
+                                    Tok.is(tok::l_paren), false);
     // These can be followed by postfix-expr pieces.
     return ParsePostfixExpressionSuffix(move(Res));
   }
diff --git a/lib/Parse/ParseExprCXX.cpp b/lib/Parse/ParseExprCXX.cpp
index dc79741..b125035 100644
--- a/lib/Parse/ParseExprCXX.cpp
+++ b/lib/Parse/ParseExprCXX.cpp
@@ -309,7 +309,19 @@
   //
   CXXScopeSpec SS;
   ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, false);
-
+  
+  UnqualifiedId Name;
+  if (ParseUnqualifiedId(SS, 
+                         /*EnteringContext=*/false, 
+                         /*AllowDestructorName=*/false, 
+                         /*AllowConstructorName=*/false, 
+                         Name))
+    return ExprError();
+  
+  return Actions.ActOnIdExpression(CurScope, SS, Name, Tok.is(tok::l_paren),
+                                   isAddressOfOperand);
+  
+#if 0
   // unqualified-id:
   //   identifier
   //   operator-function-id
@@ -372,6 +384,7 @@
   } // switch.
 
   assert(0 && "The switch was supposed to take care everything.");
+#endif
 }
 
 /// ParseCXXCasts - This handles the various ways to cast expressions to another
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
index 3281fc4..18dcd85 100644
--- a/lib/Sema/Sema.h
+++ b/lib/Sema/Sema.h
@@ -474,6 +474,7 @@
   /// \brief Create a LocInfoType to hold the given QualType and DeclaratorInfo.
   QualType CreateLocInfoType(QualType T, DeclaratorInfo *DInfo);
   DeclarationName GetNameForDeclarator(Declarator &D);
+  DeclarationName GetNameFromUnqualifiedId(UnqualifiedId &Name);
   static QualType GetTypeFromParser(TypeTy *Ty, DeclaratorInfo **DInfo = 0);
   bool CheckSpecifiedExceptionType(QualType T, const SourceRange &Range);
   bool CheckDistantExceptionSpec(QualType T);
@@ -1608,23 +1609,12 @@
   // Primary Expressions.
   virtual SourceRange getExprRange(ExprTy *E) const;
 
-  virtual OwningExprResult ActOnIdentifierExpr(Scope *S, SourceLocation Loc,
-                                               IdentifierInfo &II,
-                                               bool HasTrailingLParen,
-                                               const CXXScopeSpec *SS = 0,
-                                               bool isAddressOfOperand = false);
-  virtual OwningExprResult ActOnCXXOperatorFunctionIdExpr(Scope *S,
-                                                    SourceLocation OperatorLoc,
-                                                    OverloadedOperatorKind Op,
-                                                    bool HasTrailingLParen,
-                                                    const CXXScopeSpec &SS,
-                                                    bool isAddressOfOperand);
-  virtual OwningExprResult ActOnCXXConversionFunctionExpr(Scope *S,
-                                                    SourceLocation OperatorLoc,
-                                                    TypeTy *Ty,
-                                                    bool HasTrailingLParen,
-                                                    const CXXScopeSpec &SS,
-                                                    bool isAddressOfOperand);
+  virtual OwningExprResult ActOnIdExpression(Scope *S,
+                                             const CXXScopeSpec &SS,
+                                             UnqualifiedId &Name,
+                                             bool HasTrailingLParen,
+                                             bool IsAddressOfOperand);
+  
   OwningExprResult BuildDeclRefExpr(NamedDecl *D, QualType Ty,
                                     SourceLocation Loc, bool TypeDependent,
                                     bool ValueDependent,
@@ -2545,13 +2535,13 @@
                                        unsigned NumTemplateArgs,
                                        SourceLocation RAngleLoc);
 
-  virtual OwningExprResult ActOnTemplateIdExpr(const CXXScopeSpec &SS,
-                                               TemplateTy Template,
-                                               SourceLocation TemplateNameLoc,
-                                               SourceLocation LAngleLoc,
-                                               ASTTemplateArgsPtr TemplateArgs,
-                                               SourceLocation *TemplateArgLocs,
-                                               SourceLocation RAngleLoc);
+  OwningExprResult ActOnTemplateIdExpr(const CXXScopeSpec &SS,
+                                       TemplateTy Template,
+                                       SourceLocation TemplateNameLoc,
+                                       SourceLocation LAngleLoc,
+                                       ASTTemplateArgsPtr TemplateArgs,
+                                       SourceLocation *TemplateArgLocs,
+                                       SourceLocation RAngleLoc);
 
   virtual TemplateTy ActOnDependentTemplateName(SourceLocation TemplateKWLoc,
                                                 const IdentifierInfo &Name,
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 8d00c09..82d467f 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -1606,56 +1606,60 @@
 /// GetNameForDeclarator - Determine the full declaration name for the
 /// given Declarator.
 DeclarationName Sema::GetNameForDeclarator(Declarator &D) {
-  UnqualifiedId &Name = D.getName();
+  return GetNameFromUnqualifiedId(D.getName());
+}
+
+/// \brief Retrieves the canonicalized name from a parsed unqualified-id.
+DeclarationName Sema::GetNameFromUnqualifiedId(UnqualifiedId &Name) {
   switch (Name.getKind()) {
-  case UnqualifiedId::IK_Identifier:
-    return DeclarationName(Name.Identifier);
-
-  case UnqualifiedId::IK_OperatorFunctionId:
-    return Context.DeclarationNames.getCXXOperatorName(
-                                              Name.OperatorFunctionId.Operator);
-
-  case UnqualifiedId::IK_ConversionFunctionId: {
-    QualType Ty = GetTypeFromParser(Name.ConversionFunctionId);
-    if (Ty.isNull())
-      return DeclarationName();
-    
-    return Context.DeclarationNames.getCXXConversionFunctionName(
-                                                  Context.getCanonicalType(Ty));
-  }
+    case UnqualifiedId::IK_Identifier:
+      return DeclarationName(Name.Identifier);
       
-  case UnqualifiedId::IK_ConstructorName: {
-    QualType Ty = GetTypeFromParser(Name.ConstructorName);
-    if (Ty.isNull())
-      return DeclarationName();
-    
-    return Context.DeclarationNames.getCXXConstructorName(
-                                                Context.getCanonicalType(Ty));
-  }
+    case UnqualifiedId::IK_OperatorFunctionId:
+      return Context.DeclarationNames.getCXXOperatorName(
+                                                         Name.OperatorFunctionId.Operator);
       
-  case UnqualifiedId::IK_DestructorName: {
-    QualType Ty = GetTypeFromParser(Name.DestructorName);
-    if (Ty.isNull())
-      return DeclarationName();
-    
-    return Context.DeclarationNames.getCXXDestructorName(
-                                                Context.getCanonicalType(Ty));
-  }
+    case UnqualifiedId::IK_ConversionFunctionId: {
+      QualType Ty = GetTypeFromParser(Name.ConversionFunctionId);
+      if (Ty.isNull())
+        return DeclarationName();
       
-  case UnqualifiedId::IK_TemplateId: {
-    TemplateName TName
+      return Context.DeclarationNames.getCXXConversionFunctionName(
+                                                                   Context.getCanonicalType(Ty));
+    }
+      
+    case UnqualifiedId::IK_ConstructorName: {
+      QualType Ty = GetTypeFromParser(Name.ConstructorName);
+      if (Ty.isNull())
+        return DeclarationName();
+      
+      return Context.DeclarationNames.getCXXConstructorName(
+                                                            Context.getCanonicalType(Ty));
+    }
+      
+    case UnqualifiedId::IK_DestructorName: {
+      QualType Ty = GetTypeFromParser(Name.DestructorName);
+      if (Ty.isNull())
+        return DeclarationName();
+      
+      return Context.DeclarationNames.getCXXDestructorName(
+                                                           Context.getCanonicalType(Ty));
+    }
+      
+    case UnqualifiedId::IK_TemplateId: {
+      TemplateName TName
       = TemplateName::getFromVoidPointer(Name.TemplateId->Template);    
-    if (TemplateDecl *Template = TName.getAsTemplateDecl())
-      return Template->getDeclName();
-    if (OverloadedFunctionDecl *Ovl = TName.getAsOverloadedFunctionDecl())
-      return Ovl->getDeclName();
-    
-    return DeclarationName();
+      if (TemplateDecl *Template = TName.getAsTemplateDecl())
+        return Template->getDeclName();
+      if (OverloadedFunctionDecl *Ovl = TName.getAsOverloadedFunctionDecl())
+        return Ovl->getDeclName();
+      
+      return DeclarationName();
+    }
   }
-  }
-
+  
   assert(false && "Unknown name kind");
-  return DeclarationName();
+  return DeclarationName();  
 }
 
 /// isNearlyMatchingFunction - Determine whether the C++ functions
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index bdfe91e..63d39a0 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -436,20 +436,6 @@
 
 
 
-/// ActOnIdentifierExpr - The parser read an identifier in expression context,
-/// validate it per-C99 6.5.1.  HasTrailingLParen indicates whether this
-/// identifier is used in a function call context.
-/// SS is only used for a C++ qualified-id (foo::bar) to indicate the
-/// class or namespace that the identifier must be a member of.
-Sema::OwningExprResult Sema::ActOnIdentifierExpr(Scope *S, SourceLocation Loc,
-                                                 IdentifierInfo &II,
-                                                 bool HasTrailingLParen,
-                                                 const CXXScopeSpec *SS,
-                                                 bool isAddressOfOperand) {
-  return ActOnDeclarationNameExpr(S, Loc, &II, HasTrailingLParen, SS,
-                                  isAddressOfOperand);
-}
-
 /// BuildDeclRefExpr - Build a DeclRefExpr.
 Sema::OwningExprResult
 Sema::BuildDeclRefExpr(NamedDecl *D, QualType Ty, SourceLocation Loc,
@@ -654,15 +640,43 @@
   return Owned(Result);
 }
 
+Sema::OwningExprResult Sema::ActOnIdExpression(Scope *S,
+                                               const CXXScopeSpec &SS,
+                                               UnqualifiedId &Name,
+                                               bool HasTrailingLParen,
+                                               bool IsAddressOfOperand) {
+  if (Name.getKind() == UnqualifiedId::IK_TemplateId) {
+    ASTTemplateArgsPtr TemplateArgsPtr(*this,
+                                       Name.TemplateId->getTemplateArgs(),
+                                       Name.TemplateId->getTemplateArgIsType(),
+                                       Name.TemplateId->NumArgs);
+    return ActOnTemplateIdExpr(SS, 
+                               TemplateTy::make(Name.TemplateId->Template), 
+                               Name.TemplateId->TemplateNameLoc,
+                               Name.TemplateId->LAngleLoc,
+                               TemplateArgsPtr,
+                               Name.TemplateId->getTemplateArgLocations(),
+                               Name.TemplateId->RAngleLoc);
+  }
+  
+  // FIXME: We lose a bunch of source information by doing this. Later,
+  // we'll want to merge ActOnDeclarationNameExpr's logic into 
+  // ActOnIdExpression.
+  return ActOnDeclarationNameExpr(S, 
+                                  Name.StartLocation,
+                                  GetNameFromUnqualifiedId(Name),
+                                  HasTrailingLParen,
+                                  &SS,
+                                  IsAddressOfOperand);
+}
+
 /// ActOnDeclarationNameExpr - The parser has read some kind of name
 /// (e.g., a C++ id-expression (C++ [expr.prim]p1)). This routine
 /// performs lookup on that name and returns an expression that refers
 /// to that name. This routine isn't directly called from the parser,
 /// because the parser doesn't know about DeclarationName. Rather,
-/// this routine is called by ActOnIdentifierExpr,
-/// ActOnOperatorFunctionIdExpr, and ActOnConversionFunctionExpr,
-/// which form the DeclarationName from the corresponding syntactic
-/// forms.
+/// this routine is called by ActOnIdExpression, which contains a
+/// parsed UnqualifiedId.
 ///
 /// HasTrailingLParen indicates whether this identifier is used in a
 /// function call context.  LookupCtx is only used for a C++
@@ -743,8 +757,11 @@
           // FIXME: This should use a new expr for a direct reference, don't
           // turn this into Self->ivar, just return a BareIVarExpr or something.
           IdentifierInfo &II = Context.Idents.get("self");
-          OwningExprResult SelfExpr = ActOnIdentifierExpr(S, SourceLocation(),
-                                                          II, false);
+          UnqualifiedId SelfName;
+          SelfName.setIdentifier(&II, SourceLocation());          
+          CXXScopeSpec SelfScopeSpec;
+          OwningExprResult SelfExpr = ActOnIdExpression(S, SelfScopeSpec,
+                                                        SelfName, false, false);
           MarkDeclarationReferenced(Loc, IV);
           return Owned(new (Context)
                        ObjCIvarRefExpr(IV, IV->getType(), Loc,
@@ -3985,7 +4002,7 @@
 
   // This check seems unnatural, however it is necessary to ensure the proper
   // conversion of functions/arrays. If the conversion were done for all
-  // DeclExpr's (created by ActOnIdentifierExpr), it would mess up the unary
+  // DeclExpr's (created by ActOnIdExpression), it would mess up the unary
   // expressions that surpress this implicit conversion (&, sizeof).
   //
   // Suppress this for references: C++ 8.5.3p5.
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index fad1f3e..10fff0e 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -22,41 +22,6 @@
 #include "llvm/ADT/STLExtras.h"
 using namespace clang;
 
-/// ActOnCXXConversionFunctionExpr - Parse a C++ conversion function
-/// name (e.g., operator void const *) as an expression. This is
-/// very similar to ActOnIdentifierExpr, except that instead of
-/// providing an identifier the parser provides the type of the
-/// conversion function.
-Sema::OwningExprResult
-Sema::ActOnCXXConversionFunctionExpr(Scope *S, SourceLocation OperatorLoc,
-                                     TypeTy *Ty, bool HasTrailingLParen,
-                                     const CXXScopeSpec &SS,
-                                     bool isAddressOfOperand) {
-  //FIXME: Preserve type source info.
-  QualType ConvType = GetTypeFromParser(Ty);
-  CanQualType ConvTypeCanon = Context.getCanonicalType(ConvType);
-  DeclarationName ConvName
-    = Context.DeclarationNames.getCXXConversionFunctionName(ConvTypeCanon);
-  return ActOnDeclarationNameExpr(S, OperatorLoc, ConvName, HasTrailingLParen,
-                                  &SS, isAddressOfOperand);
-}
-
-/// ActOnCXXOperatorFunctionIdExpr - Parse a C++ overloaded operator
-/// name (e.g., @c operator+ ) as an expression. This is very
-/// similar to ActOnIdentifierExpr, except that instead of providing
-/// an identifier the parser provides the kind of overloaded
-/// operator that was parsed.
-Sema::OwningExprResult
-Sema::ActOnCXXOperatorFunctionIdExpr(Scope *S, SourceLocation OperatorLoc,
-                                     OverloadedOperatorKind Op,
-                                     bool HasTrailingLParen,
-                                     const CXXScopeSpec &SS,
-                                     bool isAddressOfOperand) {
-  DeclarationName Name = Context.DeclarationNames.getCXXOperatorName(Op);
-  return ActOnDeclarationNameExpr(S, OperatorLoc, Name, HasTrailingLParen, &SS,
-                                  isAddressOfOperand);
-}
-
 /// ActOnCXXTypeidOfType - Parse typeid( type-id ).
 Action::OwningExprResult
 Sema::ActOnCXXTypeid(SourceLocation OpLoc, SourceLocation LParenLoc,