Make it possible for using decls to point to operators. Fixes PR4441.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@74362 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Parse/MinimalAction.cpp b/lib/Parse/MinimalAction.cpp
index 9ded366..648e2da 100644
--- a/lib/Parse/MinimalAction.cpp
+++ b/lib/Parse/MinimalAction.cpp
@@ -48,6 +48,7 @@
                                               const CXXScopeSpec &SS,
                                               SourceLocation IdentLoc,
                                               IdentifierInfo *TargetName,
+                                              OverloadedOperatorKind Op,
                                               AttributeList *AttrList,
                                               bool IsTypeName) {
   
diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp
index fed03a8..225f926 100644
--- a/lib/Parse/ParseDeclCXX.cpp
+++ b/lib/Parse/ParseDeclCXX.cpp
@@ -11,6 +11,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "clang/Basic/OperatorKinds.h"
 #include "clang/Parse/Parser.h"
 #include "clang/Parse/ParseDiagnostic.h"
 #include "clang/Parse/DeclSpec.h"
@@ -274,8 +275,6 @@
   ParseOptionalCXXScopeSpecifier(SS);
 
   AttributeList *AttrList = 0;
-  IdentifierInfo *TargetName = 0;
-  SourceLocation IdentLoc = SourceLocation();
 
   // Check nested-name specifier.
   if (SS.isInvalid()) {
@@ -287,17 +286,33 @@
     SkipUntil(tok::semi);
     return DeclPtrTy();
   }
-  if (Tok.isNot(tok::identifier)) {
+  
+  IdentifierInfo *TargetName = 0;
+  OverloadedOperatorKind Op = OO_None;
+  SourceLocation IdentLoc;
+  
+  if (Tok.is(tok::kw_operator)) {
+    IdentLoc = Tok.getLocation();
+
+    Op = TryParseOperatorFunctionId();
+    if (!Op) {
+      // If there was an invalid operator, skip to end of decl, and eat ';'.
+      SkipUntil(tok::semi);
+      return DeclPtrTy();
+    }
+  } else if (Tok.is(tok::identifier)) {
+    // Parse identifier.
+    TargetName = Tok.getIdentifierInfo();
+    IdentLoc = ConsumeToken();
+  } else {
+    // FIXME: Use a better diagnostic here.
     Diag(Tok, diag::err_expected_ident_in_using);
+
     // If there was invalid identifier, skip to end of decl, and eat ';'.
     SkipUntil(tok::semi);
     return DeclPtrTy();
   }
   
-  // Parse identifier.
-  TargetName = Tok.getIdentifierInfo();
-  IdentLoc = ConsumeToken();
-  
   // Parse (optional) attributes (most likely GNU strong-using extension).
   if (Tok.is(tok::kw___attribute))
     AttrList = ParseAttributes();
@@ -308,7 +323,8 @@
                    AttrList ? "attributes list" : "namespace name", tok::semi);
 
   return Actions.ActOnUsingDeclaration(CurScope, UsingLoc, SS,
-                                      IdentLoc, TargetName, AttrList, IsTypeName);
+                                       IdentLoc, TargetName, Op,
+                                       AttrList, IsTypeName);
 }
 
 /// ParseStaticAssertDeclaration - Parse C++0x static_assert-declaratoion.
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
index cbe0ad7..2d27ccc 100644
--- a/lib/Sema/Sema.h
+++ b/lib/Sema/Sema.h
@@ -1574,6 +1574,7 @@
                                         const CXXScopeSpec &SS,
                                         SourceLocation IdentLoc,
                                         IdentifierInfo *TargetName,
+                                        OverloadedOperatorKind Op,
                                         AttributeList *AttrList,
                                         bool IsTypeName);
   
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index b238318..b7a4299 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -1785,18 +1785,24 @@
                                           const CXXScopeSpec &SS,
                                           SourceLocation IdentLoc,
                                           IdentifierInfo *TargetName,
+                                          OverloadedOperatorKind Op,
                                           AttributeList *AttrList,
                                           bool IsTypeName) {
   assert(!SS.isInvalid() && "Invalid CXXScopeSpec.");
-  assert(TargetName && "Invalid TargetName.");
+  assert(TargetName || Op && "Invalid TargetName.");
   assert(IdentLoc.isValid() && "Invalid TargetName location.");
   assert(S->getFlags() & Scope::DeclScope && "Invalid Scope.");
 
   UsingDecl *UsingAlias = 0;
 
+  DeclarationName Name;
+  if (TargetName)
+    Name = TargetName;
+  else
+    Name = Context.DeclarationNames.getCXXOperatorName(Op);
+  
   // Lookup target name.
-  LookupResult R = LookupParsedName(S, &SS, TargetName,
-                                    LookupOrdinaryName, false);
+  LookupResult R = LookupParsedName(S, &SS, Name, LookupOrdinaryName, false);
 
   if (NamedDecl *NS = R) {
     if (IsTypeName && !isa<TypeDecl>(NS)) {