Extend DeclarationName to support C++ overloaded operators, e.g.,
operator+, directly, using the same mechanism as all other special
names.

Removed the "special" identifiers for the overloaded operators from
the identifier table and IdentifierInfo data structure. IdentifierInfo
is back to representing only real identifiers.

Added a new Action, ActOnOperatorFunctionIdExpr, that builds an
expression from an parsed operator-function-id (e.g., "operator
+"). ActOnIdentifierExpr used to do this job, but
operator-function-ids are no longer represented by IdentifierInfo's.

Extended Declarator to store overloaded operator names. 
Sema::GetNameForDeclarator now knows how to turn the operator
name into a DeclarationName for the overloaded operator. 

Except for (perhaps) consolidating the functionality of
ActOnIdentifier, ActOnOperatorFunctionIdExpr, and
ActOnConversionFunctionExpr into a common routine that builds an
appropriate DeclRefExpr by looking up a DeclarationName, all of the
work on normalizing declaration names should be complete with this
commit.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@59526 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index e49ef27..f2c6c3b 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -70,6 +70,52 @@
   return new DeclRefExpr(Conversion, Conversion->getType(), OperatorLoc);
 }
 
+/// ActOnOperatorFunctionIdExpr - 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::ExprResult Sema::ActOnOperatorFunctionIdExpr(Scope *S, 
+                                                   SourceLocation OperatorLoc,
+                                                   OverloadedOperatorKind Op,
+                                                   bool HasTrailingLParen,
+                                                   const CXXScopeSpec *SS) {
+  DeclarationName Name = Context.DeclarationNames.getCXXOperatorName(Op);
+  
+  Decl *D;
+  if (SS && !SS->isEmpty()) {
+    DeclContext *DC = static_cast<DeclContext*>(SS->getScopeRep());
+    if (DC == 0)
+      return true;
+    D = LookupDecl(Name, Decl::IDNS_Ordinary, S, DC);
+  } else
+    D = LookupDecl(Name, Decl::IDNS_Ordinary, S);
+  
+  if (D == 0) {
+    // If there is no conversion function that converts to this type,
+    // diagnose the problem.
+    if (SS && !SS->isEmpty())
+      return Diag(OperatorLoc, diag::err_typecheck_no_member,
+                  Name.getAsString(), SS->getRange());
+    else
+      return Diag(OperatorLoc, diag::err_undeclared_var_use,
+                  Name.getAsString());
+  }
+  
+  ValueDecl *VD = cast<ValueDecl>(D);
+
+  // check if referencing a declaration with __attribute__((deprecated)).
+  if (VD->getAttr<DeprecatedAttr>())
+    Diag(OperatorLoc, diag::warn_deprecated, Name.getAsString());
+
+  // Only create DeclRefExpr's for valid Decl's.
+  if (VD->isInvalidDecl())
+    return true;
+  
+  // Create a normal DeclRefExpr.
+  return new DeclRefExpr(VD, VD->getType(), OperatorLoc);
+}
+
 /// ActOnCXXTypeidOfType - Parse typeid( type-id ).
 Action::ExprResult
 Sema::ActOnCXXTypeid(SourceLocation OpLoc, SourceLocation LParenLoc,