aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/Basic/DiagnosticParseKinds.td4
-rw-r--r--include/clang/Parse/DeclSpec.h21
-rw-r--r--lib/Parse/ParseExprCXX.cpp21
-rw-r--r--lib/Sema/SemaDecl.cpp5
-rw-r--r--lib/Sema/SemaDeclCXX.cpp1
-rw-r--r--lib/Sema/SemaType.cpp1
-rw-r--r--test/Parser/cxx0x-literal-operators.cpp5
7 files changed, 56 insertions, 2 deletions
diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td
index 691c571f82..7de5b20d6e 100644
--- a/include/clang/Basic/DiagnosticParseKinds.td
+++ b/include/clang/Basic/DiagnosticParseKinds.td
@@ -242,6 +242,10 @@ def err_dup_virtual : Error<"duplicate 'virtual' in base specifier">;
// C++ operator overloading
def err_operator_missing_type_specifier : Error<
"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<
diff --git a/include/clang/Parse/DeclSpec.h b/include/clang/Parse/DeclSpec.h
index 7e7d0b3f28..fe899b3fdb 100644
--- a/include/clang/Parse/DeclSpec.h
+++ b/include/clang/Parse/DeclSpec.h
@@ -484,6 +484,8 @@ public:
IK_OperatorFunctionId,
/// \brief A conversion function name, e.g., operator int.
IK_ConversionFunctionId,
+ /// \brief A user-defined literal name, e.g., operator "" _i.
+ IK_LiteralOperatorId,
/// \brief A constructor name.
IK_ConstructorName,
/// \brief A destructor name.
@@ -495,7 +497,8 @@ public:
/// \brief Anonymous union that holds extra data associated with the
/// parsed unqualified-id.
union {
- /// \brief When Kind == IK_Identifier, the parsed identifier.
+ /// \brief When Kind == IK_Identifier, the parsed identifier, or when Kind
+ /// == IK_UserLiteralId, the identifier suffix.
IdentifierInfo *Identifier;
/// \brief When Kind == IK_OperatorFunctionId, the overloaded operator
@@ -607,6 +610,22 @@ public:
EndLocation = EndLoc;
ConversionFunctionId = Ty;
}
+
+ /// \brief Specific that this unqualified-id was parsed as a
+ /// literal-operator-id.
+ ///
+ /// \param Id the parsed identifier.
+ ///
+ /// \param OpLoc the location of the 'operator' keyword.
+ ///
+ /// \param IdLoc the location of the identifier.
+ void setLiteralOperatorId(const IdentifierInfo *Id, SourceLocation OpLoc,
+ SourceLocation IdLoc) {
+ Kind = IK_LiteralOperatorId;
+ Identifier = const_cast<IdentifierInfo *>(Id);
+ StartLocation = OpLoc;
+ EndLocation = IdLoc;
+ }
/// \brief Specify that this unqualified-id was parsed as a constructor name.
///
diff --git a/lib/Parse/ParseExprCXX.cpp b/lib/Parse/ParseExprCXX.cpp
index 157d8837a9..6aca1cbbcc 100644
--- a/lib/Parse/ParseExprCXX.cpp
+++ b/lib/Parse/ParseExprCXX.cpp
@@ -1031,6 +1031,27 @@ bool Parser::ParseUnqualifiedIdOperator(CXXScopeSpec &SS, bool EnteringContext,
Result.setOperatorFunctionId(KeywordLoc, Op, SymbolLocations);
return false;
}
+
+ // Parse a literal-operator-id.
+ //
+ // literal-operator-id: [C++0x 13.5.8]
+ // operator "" identifier
+
+ if (getLang().CPlusPlus0x && Tok.is(tok::string_literal)) {
+ if (Tok.getLength() != 2)
+ Diag(Tok.getLocation(), diag::err_operator_string_not_empty);
+ ConsumeStringToken();
+
+ if (Tok.isNot(tok::identifier)) {
+ Diag(Tok.getLocation(), diag::err_expected_ident);
+ return true;
+ }
+
+ IdentifierInfo *II = Tok.getIdentifierInfo();
+ Result.setLiteralOperatorId(II, KeywordLoc, ConsumeToken());
+ Diag(KeywordLoc, diag::err_unsupported_literal_operator);
+ return true;
+ }
// Parse a conversion-function-id.
//
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 153c15b889..fe73785a7f 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -1765,7 +1765,10 @@ DeclarationName Sema::GetNameFromUnqualifiedId(UnqualifiedId &Name) {
case UnqualifiedId::IK_OperatorFunctionId:
return Context.DeclarationNames.getCXXOperatorName(
Name.OperatorFunctionId.Operator);
-
+
+ case UnqualifiedId::IK_LiteralOperatorId:
+ assert(false && "We don't support these; Parse shouldn't have allowed propagation");
+
case UnqualifiedId::IK_ConversionFunctionId: {
QualType Ty = GetTypeFromParser(Name.ConversionFunctionId);
if (Ty.isNull())
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index aeb9a8860c..a6bb401a88 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -2823,6 +2823,7 @@ Sema::DeclPtrTy Sema::ActOnUsingDeclaration(Scope *S,
switch (Name.getKind()) {
case UnqualifiedId::IK_Identifier:
case UnqualifiedId::IK_OperatorFunctionId:
+ case UnqualifiedId::IK_LiteralOperatorId:
case UnqualifiedId::IK_ConversionFunctionId:
break;
diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp
index 00dc809f51..afce5e33ba 100644
--- a/lib/Sema/SemaType.cpp
+++ b/lib/Sema/SemaType.cpp
@@ -879,6 +879,7 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S,
switch (D.getName().getKind()) {
case UnqualifiedId::IK_Identifier:
case UnqualifiedId::IK_OperatorFunctionId:
+ case UnqualifiedId::IK_LiteralOperatorId:
case UnqualifiedId::IK_TemplateId:
T = ConvertDeclSpecToType(D, *this);
diff --git a/test/Parser/cxx0x-literal-operators.cpp b/test/Parser/cxx0x-literal-operators.cpp
new file mode 100644
index 0000000000..b01cf06edb
--- /dev/null
+++ b/test/Parser/cxx0x-literal-operators.cpp
@@ -0,0 +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}} \ No newline at end of file