[cfe-commits] r90064 - in /cfe/trunk: include/clang/AST/DeclarationName.h include/clang/Basic/DiagnosticParseKinds.td include/clang/Basic/IdentifierTable.h lib/AST/DeclarationName.cpp lib/CodeGen/Mangle.cpp lib/Frontend/PCHReader.cpp lib/Frontend/PCHWriter.cpp lib/Parse/ParseExprCXX.cpp lib/Sema/SemaDecl.cpp lib/Sema/SemaExpr.cpp lib/Sema/SemaTemplate.cpp lib/Sema/TreeTransform.h test/Parser/cxx0x-literal-operators.cpp

Sean Hunt rideau3 at gmail.com
Sat Nov 28 23:34:05 PST 2009


Author: coppro
Date: Sun Nov 29 01:34:05 2009
New Revision: 90064

URL: http://llvm.org/viewvc/llvm-project?rev=90064&view=rev
Log:
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.

Modified:
    cfe/trunk/include/clang/AST/DeclarationName.h
    cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
    cfe/trunk/include/clang/Basic/IdentifierTable.h
    cfe/trunk/lib/AST/DeclarationName.cpp
    cfe/trunk/lib/CodeGen/Mangle.cpp
    cfe/trunk/lib/Frontend/PCHReader.cpp
    cfe/trunk/lib/Frontend/PCHWriter.cpp
    cfe/trunk/lib/Parse/ParseExprCXX.cpp
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/lib/Sema/SemaTemplate.cpp
    cfe/trunk/lib/Sema/TreeTransform.h
    cfe/trunk/test/Parser/cxx0x-literal-operators.cpp

Modified: cfe/trunk/include/clang/AST/DeclarationName.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclarationName.h?rev=90064&r1=90063&r2=90064&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/DeclarationName.h (original)
+++ cfe/trunk/include/clang/AST/DeclarationName.h Sun Nov 29 01:34:05 2009
@@ -25,6 +25,7 @@
 namespace clang {
   class CXXSpecialName;
   class CXXOperatorIdName;
+  class CXXLiteralOperatorIdName;
   class DeclarationNameExtra;
   class IdentifierInfo;
   class MultiKeywordSelector;
@@ -48,6 +49,7 @@
     CXXDestructorName,
     CXXConversionFunctionName,
     CXXOperatorName,
+    CXXLiteralOperatorName,
     CXXUsingDirective
   };
 
@@ -115,6 +117,12 @@
     return 0;
   }
 
+  CXXLiteralOperatorIdName *getAsCXXLiteralOperatorIdName() const {
+    if (getNameKind() == CXXLiteralOperatorName)
+      return reinterpret_cast<CXXLiteralOperatorIdName *>(Ptr & ~PtrMask);
+    return 0;
+  }
+
   // Construct a declaration name from the name of a C++ constructor,
   // destructor, or conversion function.
   DeclarationName(CXXSpecialName *Name)
@@ -131,6 +139,12 @@
     Ptr |= StoredDeclarationNameExtra;
   }
 
+  DeclarationName(CXXLiteralOperatorIdName *Name)
+    : Ptr(reinterpret_cast<uintptr_t>(Name)) {
+    assert((Ptr & PtrMask) == 0 && "Improperly aligned CXXLiteralOperatorId");
+    Ptr |= StoredDeclarationNameExtra;
+  }
+
   /// Construct a declaration name from a raw pointer.
   DeclarationName(uintptr_t Ptr) : Ptr(Ptr) { }
 
@@ -201,7 +215,7 @@
     N.Ptr = reinterpret_cast<uintptr_t> (P);
     return N;
   }
-  
+
   static DeclarationName getFromOpaqueInteger(uintptr_t P) {
     DeclarationName N;
     N.Ptr = P;
@@ -218,6 +232,10 @@
   /// kind of overloaded operator.
   OverloadedOperatorKind getCXXOverloadedOperator() const;
 
+  /// getCXXLiteralIdentifier - If this name is the name of a literal
+  /// operator, retrieve the identifier associated with it.
+  IdentifierInfo *getCXXLiteralIdentifier() const;
+
   /// getObjCSelector - Get the Objective-C selector stored in this
   /// declaration name.
   Selector getObjCSelector() const;
@@ -324,6 +342,10 @@
   /// getCXXOperatorName - Get the name of the overloadable C++
   /// operator corresponding to Op.
   DeclarationName getCXXOperatorName(OverloadedOperatorKind Op);
+
+  /// getCXXLiteralOperatorName - Get the name of the literal operator function
+  /// with II as the identifier.
+  DeclarationName getCXXLiteralOperatorName(IdentifierInfo *II);
 };
 
 /// Insertion operator for diagnostics.  This allows sending DeclarationName's

Modified: cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td?rev=90064&r1=90063&r2=90064&view=diff

==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td Sun Nov 29 01:34:05 2009
@@ -244,8 +244,6 @@
   "missing type specifier after 'operator'">;
 def err_operator_string_not_empty : Error<
   "string literal after 'operator' must be '\"\"'">;
-def err_unsupported_literal_operator : Error<
-  "C++0x literal operator support is currently under development">;
 
 // Classes.
 def err_anon_type_definition : Error<

Modified: cfe/trunk/include/clang/Basic/IdentifierTable.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/IdentifierTable.h?rev=90064&r1=90063&r2=90064&view=diff

==============================================================================
--- cfe/trunk/include/clang/Basic/IdentifierTable.h (original)
+++ cfe/trunk/include/clang/Basic/IdentifierTable.h Sun Nov 29 01:34:05 2009
@@ -496,6 +496,7 @@
 #define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
     CXXOperator##Name,
 #include "clang/Basic/OperatorKinds.def"
+    CXXLiteralOperator,
     CXXUsingDirective,
     NUM_EXTRA_KINDS
   };
@@ -503,10 +504,10 @@
   /// ExtraKindOrNumArgs - Either the kind of C++ special name or
   /// operator-id (if the value is one of the CXX* enumerators of
   /// ExtraKind), in which case the DeclarationNameExtra is also a
-  /// CXXSpecialName (for CXXConstructor, CXXDestructor, or
-  /// CXXConversionFunction) or CXXOperatorIdName, it may be also
-  /// name common to C++ using-directives (CXXUsingDirective), otherwise
-  /// it is NUM_EXTRA_KINDS+NumArgs, where NumArgs is the number of
+  /// CXXSpecialName, (for CXXConstructor, CXXDestructor, or
+  /// CXXConversionFunction) CXXOperatorIdName, or CXXLiteralOperatorName,
+  /// it may be also name common to C++ using-directives (CXXUsingDirective),
+  /// otherwise it is NUM_EXTRA_KINDS+NumArgs, where NumArgs is the number of
   /// arguments in the Objective-C selector, in which case the
   /// DeclarationNameExtra is also a MultiKeywordSelector.
   unsigned ExtraKindOrNumArgs;

Modified: cfe/trunk/lib/AST/DeclarationName.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclarationName.cpp?rev=90064&r1=90063&r2=90064&view=diff

==============================================================================
--- cfe/trunk/lib/AST/DeclarationName.cpp (original)
+++ cfe/trunk/lib/AST/DeclarationName.cpp Sun Nov 29 01:34:05 2009
@@ -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) {

Modified: cfe/trunk/lib/CodeGen/Mangle.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/Mangle.cpp?rev=90064&r1=90063&r2=90064&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/Mangle.cpp (original)
+++ cfe/trunk/lib/CodeGen/Mangle.cpp Sun Nov 29 01:34:05 2009
@@ -455,6 +455,12 @@
                        cast<FunctionDecl>(ND)->getNumParams());
     break;
 
+  case DeclarationName::CXXLiteralOperatorName:
+    // Guessing based on existing ABI.
+    Out << "ul";
+    mangleSourceName(Name.getCXXLiteralIdentifier());
+    break;
+
   case DeclarationName::CXXUsingDirective:
     assert(false && "Can't mangle a using directive name!");
     break;

Modified: cfe/trunk/lib/Frontend/PCHReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHReader.cpp?rev=90064&r1=90063&r2=90064&view=diff

==============================================================================
--- cfe/trunk/lib/Frontend/PCHReader.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHReader.cpp Sun Nov 29 01:34:05 2009
@@ -2589,6 +2589,10 @@
     return Context->DeclarationNames.getCXXOperatorName(
                                        (OverloadedOperatorKind)Record[Idx++]);
 
+  case DeclarationName::CXXLiteralOperatorName:
+    return Context->DeclarationNames.getCXXLiteralOperatorName(
+                                       GetIdentifierInfo(Record, Idx));
+
   case DeclarationName::CXXUsingDirective:
     return DeclarationName::getUsingDirectiveName();
   }

Modified: cfe/trunk/lib/Frontend/PCHWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHWriter.cpp?rev=90064&r1=90063&r2=90064&view=diff

==============================================================================
--- cfe/trunk/lib/Frontend/PCHWriter.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHWriter.cpp Sun Nov 29 01:34:05 2009
@@ -2284,6 +2284,10 @@
     Record.push_back(Name.getCXXOverloadedOperator());
     break;
 
+  case DeclarationName::CXXLiteralOperatorName:
+    AddIdentifierRef(Name.getCXXLiteralIdentifier(), Record);
+    break;
+
   case DeclarationName::CXXUsingDirective:
     // No extra data to emit
     break;

Modified: cfe/trunk/lib/Parse/ParseExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExprCXX.cpp?rev=90064&r1=90063&r2=90064&view=diff

==============================================================================
--- cfe/trunk/lib/Parse/ParseExprCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseExprCXX.cpp Sun Nov 29 01:34:05 2009
@@ -1052,8 +1052,7 @@
 
     IdentifierInfo *II = Tok.getIdentifierInfo();
     Result.setLiteralOperatorId(II, KeywordLoc, ConsumeToken());
-    Diag(KeywordLoc, diag::err_unsupported_literal_operator);
-    return true;
+    return false;
   }
   
   // Parse a conversion-function-id.

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=90064&r1=90063&r2=90064&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Sun Nov 29 01:34:05 2009
@@ -1767,7 +1767,8 @@
                                               Name.OperatorFunctionId.Operator);
 
     case UnqualifiedId::IK_LiteralOperatorId:
-      assert(false && "We don't support these; Parse shouldn't have allowed propagation");
+      return Context.DeclarationNames.getCXXLiteralOperatorName(
+                                                               Name.Identifier);
 
     case UnqualifiedId::IK_ConversionFunctionId: {
       QualType Ty = GetTypeFromParser(Name.ConversionFunctionId);

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=90064&r1=90063&r2=90064&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Sun Nov 29 01:34:05 2009
@@ -729,6 +729,7 @@
                            << Name << computeDeclContext(SS, false)
                            << SS.getRange());
       else if (Name.getNameKind() == DeclarationName::CXXOperatorName ||
+               Name.getNameKind() == DeclarationName::CXXLiteralOperatorName ||
                Name.getNameKind() == DeclarationName::CXXConversionFunctionName)
         return ExprError(Diag(NameLoc, diag::err_undeclared_use)
                            << Name);

Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=90064&r1=90063&r2=90064&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Sun Nov 29 01:34:05 2009
@@ -130,8 +130,8 @@
     break;
 
   case UnqualifiedId::IK_LiteralOperatorId:
-    assert(false && "We don't support these; Parse shouldn't have allowed propagation");
-
+    TName = Context.DeclarationNames.getCXXLiteralOperatorName(Name.Identifier);
+    break;
 
   default:
     return TNK_Non_template;

Modified: cfe/trunk/lib/Sema/TreeTransform.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=90064&r1=90063&r2=90064&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/TreeTransform.h (original)
+++ cfe/trunk/lib/Sema/TreeTransform.h Sun Nov 29 01:34:05 2009
@@ -1800,6 +1800,7 @@
   case DeclarationName::ObjCOneArgSelector:
   case DeclarationName::ObjCMultiArgSelector:
   case DeclarationName::CXXOperatorName:
+  case DeclarationName::CXXLiteralOperatorName:
   case DeclarationName::CXXUsingDirective:
     return Name;
 

Modified: cfe/trunk/test/Parser/cxx0x-literal-operators.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/cxx0x-literal-operators.cpp?rev=90064&r1=90063&r2=90064&view=diff

==============================================================================
--- cfe/trunk/test/Parser/cxx0x-literal-operators.cpp (original)
+++ cfe/trunk/test/Parser/cxx0x-literal-operators.cpp Sun Nov 29 01:34:05 2009
@@ -1,5 +1,5 @@
 // RUN: clang-cc -fsyntax-only -verify -std=c++0x %s
 
 void operator "" (); // expected-error {{expected identifier}}
-void operator "k" foo(); // expected-error {{string literal after 'operator' must be '""'}} \
-                         // expected-error {{C++0x literal operator support is currently under development}}
+void operator "k" foo(); // expected-error {{string literal after 'operator' must be '""'}}
+void operator "" tester (int);





More information about the cfe-commits mailing list