Add DeclarationName support for C++0x operator literals. They should now work as
function names outside of templates - they'll probably cause some damage there as
they're largely untested.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@90064 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/DeclarationName.cpp b/lib/AST/DeclarationName.cpp
index 1ff068c..3471657 100644
--- a/lib/AST/DeclarationName.cpp
+++ b/lib/AST/DeclarationName.cpp
@@ -50,6 +50,17 @@
   void *FETokenInfo;
 };
 
+/// CXXLiberalOperatorName - Contains the actual identifier that makes up the
+/// name.
+///
+/// This identifier is stored here rather than directly in DeclarationName so as
+/// to allow Objective-C selectors, which are about a million times more common,
+/// to consume minimal memory.
+class CXXLiteralOperatorIdName : public DeclarationNameExtra {
+public:
+  IdentifierInfo *ID;
+};
+
 bool operator<(DeclarationName LHS, DeclarationName RHS) {
   if (LHS.getNameKind() != RHS.getNameKind())
     return LHS.getNameKind() < RHS.getNameKind();
@@ -89,6 +100,10 @@
               
   case DeclarationName::CXXOperatorName:
     return LHS.getCXXOverloadedOperator() < RHS.getCXXOverloadedOperator();
+
+  case DeclarationName::CXXLiteralOperatorName:
+    return LHS.getCXXLiteralIdentifier()->getName() <
+                                       RHS.getCXXLiteralIdentifier()->getName();
               
   case DeclarationName::CXXUsingDirective:
     return false;
@@ -143,6 +158,9 @@
     case DeclarationNameExtra::CXXConversionFunction:
       return CXXConversionFunctionName;
 
+    case DeclarationNameExtra::CXXLiteralOperator:
+      return CXXLiteralOperatorName;
+
     case DeclarationNameExtra::CXXUsingDirective:
       return CXXUsingDirective;
 
@@ -208,6 +226,10 @@
     return Result;
   }
 
+  case CXXLiteralOperatorName: {
+    return "operator \"\" " + std::string(getCXXLiteralIdentifier()->getName());
+  }
+
   case CXXConversionFunctionName: {
     std::string Result = "operator ";
     QualType Type = getCXXNameType();
@@ -242,6 +264,13 @@
   }
 }
 
+IdentifierInfo *DeclarationName::getCXXLiteralIdentifier() const {
+  if (CXXLiteralOperatorIdName *CXXLit = getAsCXXLiteralOperatorIdName())
+    return CXXLit->ID;
+  else
+    return 0;
+}
+
 Selector DeclarationName::getObjCSelector() const {
   switch (getNameKind()) {
   case ObjCZeroArgSelector:
@@ -273,6 +302,9 @@
   case CXXOperatorName:
     return getAsCXXOperatorIdName()->FETokenInfo;
 
+  case CXXLiteralOperatorName:
+    return getCXXLiteralIdentifier()->getFETokenInfo<void>();
+
   default:
     assert(false && "Declaration name has no FETokenInfo");
   }
@@ -295,6 +327,10 @@
     getAsCXXOperatorIdName()->FETokenInfo = T;
     break;
 
+  case CXXLiteralOperatorName:
+    getCXXLiteralIdentifier()->setFETokenInfo(T);
+    break;
+
   default:
     assert(false && "Declaration name has no FETokenInfo");
   }
@@ -390,6 +426,14 @@
   return DeclarationName(&CXXOperatorNames[(unsigned)Op]);
 }
 
+DeclarationName
+DeclarationNameTable::getCXXLiteralOperatorName(IdentifierInfo *II) {
+  CXXLiteralOperatorIdName *LiteralName = new CXXLiteralOperatorIdName;
+  LiteralName->ExtraKindOrNumArgs = DeclarationNameExtra::CXXLiteralOperator;
+  LiteralName->ID = II;
+  return DeclarationName(LiteralName);
+}
+
 unsigned
 llvm::DenseMapInfo<clang::DeclarationName>::
 getHashValue(clang::DeclarationName N) {