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/AST/DeclarationName.cpp b/lib/AST/DeclarationName.cpp
index d58016a..3a9e7c8 100644
--- a/lib/AST/DeclarationName.cpp
+++ b/lib/AST/DeclarationName.cpp
@@ -40,6 +40,15 @@
   }
 };
 
+/// CXXOperatorIdName - Contains extra information for the name of an
+/// overloaded operator in C++, such as "operator+. 
+class CXXOperatorIdName : public DeclarationNameExtra {
+public:
+  /// FETokenInfo - Extra information associated with this operator
+  /// name that can be used by the front end.
+  void *FETokenInfo;
+};
+
 bool operator<(DeclarationName LHS, DeclarationName RHS) {
   if (IdentifierInfo *LhsId = LHS.getAsIdentifierInfo())
     if (IdentifierInfo *RhsId = RHS.getAsIdentifierInfo())
@@ -64,7 +73,7 @@
 
   default:
     Ptr = Sel.InfoPtr & ~Selector::ArgFlags;
-    Ptr |= StoredObjCMultiArgSelectorOrCXXName;
+    Ptr |= StoredDeclarationNameExtra;
     break;
   }
 }
@@ -75,7 +84,7 @@
   case StoredObjCZeroArgSelector: return ObjCZeroArgSelector;
   case StoredObjCOneArgSelector:  return ObjCOneArgSelector;
 
-  case StoredObjCMultiArgSelectorOrCXXName:
+  case StoredDeclarationNameExtra:
     switch (getExtra()->ExtraKindOrNumArgs) {
     case DeclarationNameExtra::CXXConstructor: 
       return CXXConstructorName;
@@ -87,6 +96,11 @@
       return CXXConversionFunctionName;
 
     default:
+      // Check if we have one of the CXXOperator* enumeration values.
+      if (getExtra()->ExtraKindOrNumArgs < 
+            DeclarationNameExtra::NUM_EXTRA_KINDS)
+        return CXXOperatorName;
+
       return ObjCMultiArgSelector;
     }
     break;
@@ -125,6 +139,23 @@
     return Result;
   }
 
+  case CXXOperatorName: {
+    static const char *OperatorNames[NUM_OVERLOADED_OPERATORS] = {
+      0,
+#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
+      Spelling,
+#include "clang/Basic/OperatorKinds.def"
+    };
+    const char *OpName = OperatorNames[getCXXOverloadedOperator()];
+    assert(OpName && "not an overloaded operator");
+      
+    std::string Result = "operator";
+    if (OpName[0] >= 'a' && OpName[0] <= 'z')
+      Result += ' ';
+    Result += OpName;
+    return Result;
+  }
+
   case CXXConversionFunctionName: {
     std::string Result = "operator ";
     QualType Type = getCXXNameType();
@@ -147,6 +178,16 @@
     return QualType();
 }
 
+OverloadedOperatorKind DeclarationName::getCXXOverloadedOperator() const {
+  if (CXXOperatorIdName *CXXOp = getAsCXXOperatorIdName()) {
+    unsigned value 
+      = CXXOp->ExtraKindOrNumArgs - DeclarationNameExtra::CXXConversionFunction;
+    return static_cast<OverloadedOperatorKind>(value);
+  } else {
+    return OO_None;
+  }
+}
+
 Selector DeclarationName::getObjCSelector() const {
   switch (getNameKind()) {
   case ObjCZeroArgSelector:
@@ -175,6 +216,9 @@
   case CXXConversionFunctionName:
     return getAsCXXSpecialName()->FETokenInfo;
 
+  case CXXOperatorName:
+    return getAsCXXOperatorIdName()->FETokenInfo;
+
   default:
     assert(false && "Declaration name has no FETokenInfo");
   }
@@ -193,6 +237,10 @@
     getAsCXXSpecialName()->FETokenInfo = T;
     break;
 
+  case CXXOperatorName:
+    getAsCXXOperatorIdName()->FETokenInfo = T;
+    break;
+
   default:
     assert(false && "Declaration name has no FETokenInfo");
   }
@@ -200,10 +248,19 @@
 
 DeclarationNameTable::DeclarationNameTable() {
   CXXSpecialNamesImpl = new llvm::FoldingSet<CXXSpecialName>;
+
+  // Initialize the overloaded operator names.
+  CXXOperatorNames = new CXXOperatorIdName[NUM_OVERLOADED_OPERATORS];
+  for (unsigned Op = 0; Op < NUM_OVERLOADED_OPERATORS; ++Op) {
+    CXXOperatorNames[Op].ExtraKindOrNumArgs 
+      = Op + DeclarationNameExtra::CXXConversionFunction;
+    CXXOperatorNames[Op].FETokenInfo = 0;
+  }
 }
 
 DeclarationNameTable::~DeclarationNameTable() {
   delete static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl);
+  delete [] CXXOperatorNames;
 }
 
 DeclarationName 
@@ -249,3 +306,8 @@
   return DeclarationName(SpecialName);
 }
 
+DeclarationName 
+DeclarationNameTable::getCXXOperatorName(OverloadedOperatorKind Op) {
+  return DeclarationName(&CXXOperatorNames[(unsigned)Op]);
+}
+