[cfe-commits] r58986 - in /cfe/trunk: include/clang/Basic/DiagnosticKinds.def include/clang/Basic/OperatorKinds.def include/clang/Basic/OperatorKinds.h lib/Basic/IdentifierTable.cpp lib/Parse/ParseExprCXX.cpp lib/Sema/SemaDeclCXX.cpp
Douglas Gregor
doug.gregor at gmail.com
Mon Nov 10 05:38:23 PST 2008
Author: dgregor
Date: Mon Nov 10 07:38:07 2008
New Revision: 58986
URL: http://llvm.org/viewvc/llvm-project?rev=58986&view=rev
Log:
Some cleanups to the declaration/checking of overloaded operators in C++. Thanks to Sebastian for the review
Modified:
cfe/trunk/include/clang/Basic/DiagnosticKinds.def
cfe/trunk/include/clang/Basic/OperatorKinds.def
cfe/trunk/include/clang/Basic/OperatorKinds.h
cfe/trunk/lib/Basic/IdentifierTable.cpp
cfe/trunk/lib/Parse/ParseExprCXX.cpp
cfe/trunk/lib/Sema/SemaDeclCXX.cpp
Modified: cfe/trunk/include/clang/Basic/DiagnosticKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticKinds.def?rev=58986&r1=58985&r2=58986&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticKinds.def Mon Nov 10 07:38:07 2008
@@ -1316,15 +1316,27 @@
DIAG(err_operator_overload_default_arg, ERROR,
"a parameter of an overloaded operator cannot have a default argument")
DIAG(err_operator_overload_must_be_unary, ERROR,
- "overloaded operator '%0' must be a unary operator (has %1 parameter%2)")
+ "overloaded operator '%0' must be a unary operator (has %1 parameter)")
DIAG(err_operator_overload_must_be_binary, ERROR,
- "overloaded operator '%0' must be a binary operator (has %1 parameter%2)")
+ "overloaded operator '%0' must be a binary operator (has %1 parameter)")
DIAG(err_operator_overload_must_be_unary_or_binary, ERROR,
- "overloaded operator '%0' must be a unary or binary operator (has %1 parameter%2)")
+ "overloaded operator '%0' must be a unary or binary operator (has %1 parameter)")
+DIAG(err_operator_overload_must_be_unary_plural, ERROR,
+ "overloaded operator '%0' must be a unary operator (has %1 parameters)")
+DIAG(err_operator_overload_must_be_binary_plural, ERROR,
+ "overloaded operator '%0' must be a binary operator (has %1 parameters)")
+DIAG(err_operator_overload_must_be_unary_or_binary_plural, ERROR,
+ "overloaded operator '%0' must be a unary or binary operator (has %1 parameters)")
DIAG(err_operator_overload_must_be_member, ERROR,
"overloaded operator '%0' must be a non-static member function")
-DIAG(err_operator_overload_post_incdec_must_be_int, ERROR,
- "%0parameter of overloaded post-%1 operator must have type 'int' (not '%2')")
+DIAG(err_operator_overload_post_inc_must_be_int, ERROR,
+ "second parameter of overloaded post-increment operator must have type 'int' (not '%0')")
+DIAG(err_operator_overload_post_dec_must_be_int, ERROR,
+ "second parameter of overloaded post-decrement operator must have type 'int' (not '%0')")
+DIAG(err_operator_overload_post_inc_must_be_int_member, ERROR,
+ "parameter of overloaded post-increment operator must have type 'int' (not '%0')")
+DIAG(err_operator_overload_post_dec_must_be_int_member, ERROR,
+ "parameter of overloaded post-decrement operator must have type 'int' (not '%0')")
DIAG(err_operator_missing_type_specifier, ERROR,
"missing type specifier after 'operator'")
Modified: cfe/trunk/include/clang/Basic/OperatorKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/OperatorKinds.def?rev=58986&r1=58985&r2=58986&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/OperatorKinds.def (original)
+++ cfe/trunk/include/clang/Basic/OperatorKinds.def Mon Nov 10 07:38:07 2008
@@ -11,58 +11,93 @@
// all of the overloadable C++ operators.
//
//===----------------------------------------------------------------------===//
+//
+/// @file OperatorKinds.def
+///
+/// In this file, each of the overloadable C++ operators is enumerated
+/// with either the OVERLOADED_OPERATOR or OVERLOADED_OPERATOR_MULTI
+/// macro, each of which can be specified by the code including this
+/// file. OVERLOADED_OPERATOR is used for single-token operators
+/// (e.g., "+"), and has six arguments:
+///
+/// Name: The name of the token. OO_Name will be the name of the
+/// corresponding enumerator in OverloadedOperatorKind in
+/// OperatorKinds.h.
+///
+/// Spelling: A string that provides a canonical spelling for the
+/// operator, e.g., "operator+".
+///
+/// Token: The name of the token that specifies the operator, e.g.,
+/// "plus" for operator+ or "greatergreaterequal" for
+/// "operator>>=". With a "kw_" prefix, the token name can be used as
+/// an enumerator into the TokenKind enumeration.
+///
+/// Unary: True if the operator can be declared as a unary operator.
+///
+/// Binary: True if the operator can be declared as a binary
+/// operator. Note that some operators (e.g., "operator+" and
+/// "operator*") can be both unary and binary.
+///
+/// MemberOnly: True if this operator can only be declared as a
+/// non-static member function. False if the operator can be both a
+/// non-member function and a non-static member function.
+///
+/// OVERLOADED_OPERATOR_MULTI is used to enumerate the multi-token
+/// overloaded operator names, e.g., "operator delete []". The macro
+/// has all of the parameters of OVERLOADED_OPERATOR except Token,
+/// which is omitted.
#ifndef OVERLOADED_OPERATOR
-# define OVERLOADED_OPERATOR(Name,Spelling,Token)
+# define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly)
#endif
#ifndef OVERLOADED_OPERATOR_MULTI
-# define OVERLOADED_OPERATOR_MULTI(Name,Spelling) \
- OVERLOADED_OPERATOR(Name,Spelling,unknown)
+# define OVERLOADED_OPERATOR_MULTI(Name,Spelling,Unary,Binary,MemberOnly) \
+ OVERLOADED_OPERATOR(Name,Spelling,unknown,Unary,Binary,MemberOnly)
#endif
-OVERLOADED_OPERATOR_MULTI(New , "operator new")
-OVERLOADED_OPERATOR_MULTI(Delete , "operator delete")
-OVERLOADED_OPERATOR_MULTI(Array_New , "operator new[]")
-OVERLOADED_OPERATOR_MULTI(Array_Delete , "operator delete[]")
-OVERLOADED_OPERATOR(Plus , "operator+" , plus)
-OVERLOADED_OPERATOR(Minus , "operator-" , minus)
-OVERLOADED_OPERATOR(Star , "operator*" , star)
-OVERLOADED_OPERATOR(Slash , "operator/" , slash)
-OVERLOADED_OPERATOR(Percent , "operator%" , percent)
-OVERLOADED_OPERATOR(Caret , "operator^" , caret)
-OVERLOADED_OPERATOR(Amp , "operator&" , amp)
-OVERLOADED_OPERATOR(Pipe , "operator|" , pipe)
-OVERLOADED_OPERATOR(Tilde , "operator~" , tilde)
-OVERLOADED_OPERATOR(Exclaim , "operator!" , exclaim)
-OVERLOADED_OPERATOR(Equal , "operator=" , equal)
-OVERLOADED_OPERATOR(Less , "operator<" , less)
-OVERLOADED_OPERATOR(Greater , "operator>" , greater)
-OVERLOADED_OPERATOR(PlusEqual , "operator+=" , plusequal)
-OVERLOADED_OPERATOR(MinusEqual , "operator-=" , minusequal)
-OVERLOADED_OPERATOR(StarEqual , "operator*=" , starequal)
-OVERLOADED_OPERATOR(SlashEqual , "operator/=" , slashequal)
-OVERLOADED_OPERATOR(PercentEqual , "operator%=" , percentequal)
-OVERLOADED_OPERATOR(CaretEqual , "operator^=" , caretequal)
-OVERLOADED_OPERATOR(AmpEqual , "operator&=" , ampequal)
-OVERLOADED_OPERATOR(PipeEqual , "operator|=" , pipeequal)
-OVERLOADED_OPERATOR(LessLess , "operator<<" , lessless)
-OVERLOADED_OPERATOR(GreaterGreater , "operator>>" , greatergreater)
-OVERLOADED_OPERATOR(LessLessEqual , "operator<<=" , lesslessequal)
-OVERLOADED_OPERATOR(GreaterGreaterEqual , "operator>>=" , greatergreaterequal)
-OVERLOADED_OPERATOR(EqualEqual , "operator==" , equalequal)
-OVERLOADED_OPERATOR(ExclaimEqual , "operator!=" , exclaimequal)
-OVERLOADED_OPERATOR(LessEqual , "operator<=" , lessequal)
-OVERLOADED_OPERATOR(GreaterEqual , "operator>=" , greaterequal)
-OVERLOADED_OPERATOR(AmpAmp , "operator&&" , ampamp)
-OVERLOADED_OPERATOR(PipePipe , "operator||" , pipepipe)
-OVERLOADED_OPERATOR(PlusPlus , "operator++" , plusplus)
-OVERLOADED_OPERATOR(MinusMinus , "operator--" , minusminus)
-OVERLOADED_OPERATOR(Comma , "operator," , comma)
-OVERLOADED_OPERATOR(ArrowStar , "operator->*" , arrowstar)
-OVERLOADED_OPERATOR(Arrow , "operator->" , arrow)
-OVERLOADED_OPERATOR_MULTI(Call , "operator()")
-OVERLOADED_OPERATOR_MULTI(Subscript , "operator[]")
+OVERLOADED_OPERATOR_MULTI(New , "operator new" , true , true , false)
+OVERLOADED_OPERATOR_MULTI(Delete , "operator delete" , true , true , false)
+OVERLOADED_OPERATOR_MULTI(Array_New , "operator new[]" , true , true , false)
+OVERLOADED_OPERATOR_MULTI(Array_Delete , "operator delete[]" , true , true , false)
+OVERLOADED_OPERATOR(Plus , "operator+" , plus , true , true , false)
+OVERLOADED_OPERATOR(Minus , "operator-" , minus , true , true , false)
+OVERLOADED_OPERATOR(Star , "operator*" , star , true , true , false)
+OVERLOADED_OPERATOR(Slash , "operator/" , slash , false, true , false)
+OVERLOADED_OPERATOR(Percent , "operator%" , percent , false, true , false)
+OVERLOADED_OPERATOR(Caret , "operator^" , caret , false, true , false)
+OVERLOADED_OPERATOR(Amp , "operator&" , amp , true , true , false)
+OVERLOADED_OPERATOR(Pipe , "operator|" , pipe , false, true , false)
+OVERLOADED_OPERATOR(Tilde , "operator~" , tilde , true , false, false)
+OVERLOADED_OPERATOR(Exclaim , "operator!" , exclaim , true , false, false)
+OVERLOADED_OPERATOR(Equal , "operator=" , equal , false, true , true)
+OVERLOADED_OPERATOR(Less , "operator<" , less , false, true , false)
+OVERLOADED_OPERATOR(Greater , "operator>" , greater , false, true , false)
+OVERLOADED_OPERATOR(PlusEqual , "operator+=" , plusequal , false, true , false)
+OVERLOADED_OPERATOR(MinusEqual , "operator-=" , minusequal , false, true , false)
+OVERLOADED_OPERATOR(StarEqual , "operator*=" , starequal , false, true , false)
+OVERLOADED_OPERATOR(SlashEqual , "operator/=" , slashequal , false, true , false)
+OVERLOADED_OPERATOR(PercentEqual , "operator%=" , percentequal , false, true , false)
+OVERLOADED_OPERATOR(CaretEqual , "operator^=" , caretequal , false, true , false)
+OVERLOADED_OPERATOR(AmpEqual , "operator&=" , ampequal , false, true , false)
+OVERLOADED_OPERATOR(PipeEqual , "operator|=" , pipeequal , false, true , false)
+OVERLOADED_OPERATOR(LessLess , "operator<<" , lessless , false, true , false)
+OVERLOADED_OPERATOR(GreaterGreater , "operator>>" , greatergreater , false, true , false)
+OVERLOADED_OPERATOR(LessLessEqual , "operator<<=" , lesslessequal , false, true , false)
+OVERLOADED_OPERATOR(GreaterGreaterEqual , "operator>>=" , greatergreaterequal, false, true , false)
+OVERLOADED_OPERATOR(EqualEqual , "operator==" , equalequal , false, true , false)
+OVERLOADED_OPERATOR(ExclaimEqual , "operator!=" , exclaimequal , false, true , false)
+OVERLOADED_OPERATOR(LessEqual , "operator<=" , lessequal , false, true , false)
+OVERLOADED_OPERATOR(GreaterEqual , "operator>=" , greaterequal , false, true , false)
+OVERLOADED_OPERATOR(AmpAmp , "operator&&" , ampamp , false, true , false)
+OVERLOADED_OPERATOR(PipePipe , "operator||" , pipepipe , false, true , false)
+OVERLOADED_OPERATOR(PlusPlus , "operator++" , plusplus , true , true , false)
+OVERLOADED_OPERATOR(MinusMinus , "operator--" , minusminus , true , true , false)
+OVERLOADED_OPERATOR(Comma , "operator," , comma , false, true , false)
+OVERLOADED_OPERATOR(ArrowStar , "operator->*" , arrowstar , false, true , false)
+OVERLOADED_OPERATOR(Arrow , "operator->" , arrow , true , false, true)
+OVERLOADED_OPERATOR_MULTI(Call , "operator()" , true , true , true)
+OVERLOADED_OPERATOR_MULTI(Subscript , "operator[]" , false, true , true)
#undef OVERLOADED_OPERATOR_MULTI
#undef OVERLOADED_OPERATOR
Modified: cfe/trunk/include/clang/Basic/OperatorKinds.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/OperatorKinds.h?rev=58986&r1=58985&r2=58986&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/OperatorKinds.h (original)
+++ cfe/trunk/include/clang/Basic/OperatorKinds.h Mon Nov 10 07:38:07 2008
@@ -20,7 +20,8 @@
/// C++ overloaded operators.
enum OverloadedOperatorKind {
OO_None, //< Not an overloaded operator
-#define OVERLOADED_OPERATOR(Name,Spelling,Token) OO_##Name,
+#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
+ OO_##Name,
#include "clang/Basic/OperatorKinds.def"
NUM_OVERLOADED_OPERATORS
};
Modified: cfe/trunk/lib/Basic/IdentifierTable.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/IdentifierTable.cpp?rev=58986&r1=58985&r2=58986&view=diff
==============================================================================
--- cfe/trunk/lib/Basic/IdentifierTable.cpp (original)
+++ cfe/trunk/lib/Basic/IdentifierTable.cpp Mon Nov 10 07:38:07 2008
@@ -165,7 +165,7 @@
/// AddOverloadedOperators - Register the name of all C++ overloadable
/// operators ("operator+", "operator[]", etc.)
void IdentifierTable::AddOverloadedOperators() {
-#define OVERLOADED_OPERATOR(Name,Spelling,Token) \
+#define OVERLOADED_OPERATOR(Name,Spelling,Token, Unary, Binary, MemberOnly) \
OverloadedOperators[OO_##Name] = &get(Spelling); \
OverloadedOperators[OO_##Name]->setOverloadedOperatorID(OO_##Name);
#include "clang/Basic/OperatorKinds.def"
Modified: cfe/trunk/lib/Parse/ParseExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExprCXX.cpp?rev=58986&r1=58985&r2=58986&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseExprCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseExprCXX.cpp Mon Nov 10 07:38:07 2008
@@ -515,9 +515,9 @@
}
return &PP.getIdentifierTable().getOverloadedOperator(Op);
-#define OVERLOADED_OPERATOR(Name,Spelling,Token) \
+#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
case tok::Token: Op = OO_##Name; break;
-#define OVERLOADED_OPERATOR_MULTI(Name,Spelling)
+#define OVERLOADED_OPERATOR_MULTI(Name,Spelling,Unary,Binary,MemberOnly)
#include "clang/Basic/OperatorKinds.def"
case tok::l_paren:
Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=58986&r1=58985&r2=58986&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Mon Nov 10 07:38:07 2008
@@ -1801,83 +1801,16 @@
}
}
- bool CanBeUnaryOperator = false;
- bool CanBeBinaryOperator = false;
- bool MustBeMemberOperator = false;
-
- switch (Op) {
- case OO_New:
- case OO_Delete:
- case OO_Array_New:
- case OO_Array_Delete:
- assert(false && "Operators new, new[], delete, and delete[] handled above");
- return true;
-
- // Unary-only operators
- case OO_Arrow:
- MustBeMemberOperator = true;
- // Fall through
-
- case OO_Tilde:
- case OO_Exclaim:
- CanBeUnaryOperator = true;
- break;
-
- // Binary-only operators
- case OO_Equal:
- case OO_Subscript:
- MustBeMemberOperator = true;
- // Fall through
-
- case OO_Slash:
- case OO_Percent:
- case OO_Caret:
- case OO_Pipe:
- case OO_Less:
- case OO_Greater:
- case OO_PlusEqual:
- case OO_MinusEqual:
- case OO_StarEqual:
- case OO_SlashEqual:
- case OO_PercentEqual:
- case OO_CaretEqual:
- case OO_AmpEqual:
- case OO_PipeEqual:
- case OO_LessLess:
- case OO_GreaterGreater:
- case OO_LessLessEqual:
- case OO_GreaterGreaterEqual:
- case OO_EqualEqual:
- case OO_ExclaimEqual:
- case OO_LessEqual:
- case OO_GreaterEqual:
- case OO_AmpAmp:
- case OO_PipePipe:
- case OO_Comma:
- CanBeBinaryOperator = true;
- break;
-
- // Unary or binary operators
- case OO_Amp:
- case OO_Plus:
- case OO_Minus:
- case OO_Star:
- case OO_PlusPlus:
- case OO_MinusMinus:
- case OO_ArrowStar:
- CanBeUnaryOperator = true;
- CanBeBinaryOperator = true;
- break;
-
- case OO_Call:
- MustBeMemberOperator = true;
- break;
-
- case OO_None:
- case NUM_OVERLOADED_OPERATORS:
- assert(false && "Not an overloaded operator!");
- return true;
- }
+ static const bool OperatorUses[NUM_OVERLOADED_OPERATORS][3] = {
+ { false, false, false }
+#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
+ , { Unary, Binary, MemberOnly }
+#include "clang/Basic/OperatorKinds.def"
+ };
+
+ bool CanBeUnaryOperator = OperatorUses[Op][0];
+ bool CanBeBinaryOperator = OperatorUses[Op][1];
+ bool MustBeMemberOperator = OperatorUses[Op][2];
// C++ [over.oper]p8:
// [...] Operator functions cannot have more or fewer parameters
@@ -1890,23 +1823,30 @@
(NumParams < 1) || (NumParams > 2))) {
// We have the wrong number of parameters.
std::string NumParamsStr = (llvm::APSInt(32) = NumParams).toString(10);
- std::string NumParamsPlural;
- if (NumParams != 1)
- NumParamsPlural = "s";
diag::kind DK;
- if (CanBeUnaryOperator && CanBeBinaryOperator)
- DK = diag::err_operator_overload_must_be_unary_or_binary;
- else if (CanBeUnaryOperator)
- DK = diag::err_operator_overload_must_be_unary;
- else if (CanBeBinaryOperator)
- DK = diag::err_operator_overload_must_be_binary;
- else
+ if (CanBeUnaryOperator && CanBeBinaryOperator) {
+ if (NumParams == 1)
+ DK = diag::err_operator_overload_must_be_unary_or_binary;
+ else
+ DK = diag::err_operator_overload_must_be_unary_or_binary;
+ } else if (CanBeUnaryOperator) {
+ if (NumParams == 1)
+ DK = diag::err_operator_overload_must_be_unary;
+ else
+ DK = diag::err_operator_overload_must_be_unary_plural;
+ } else if (CanBeBinaryOperator) {
+ if (NumParams == 1)
+ DK = diag::err_operator_overload_must_be_binary;
+ else
+ DK = diag::err_operator_overload_must_be_binary_plural;
+ } else {
assert(false && "All non-call overloaded operators are unary or binary!");
+ }
Diag(FnDecl->getLocation(), DK,
- FnDecl->getName(), NumParamsStr, NumParamsPlural,
+ FnDecl->getName(), NumParamsStr,
SourceRange(FnDecl->getLocation()));
IsInvalid = true;
}
@@ -1945,11 +1885,19 @@
ParamIsInt = BT->getKind() == BuiltinType::Int;
if (!ParamIsInt) {
- Diag(LastParam->getLocation(),
- diag::err_operator_overload_post_incdec_must_be_int,
- MethodDecl? std::string() : std::string("second "),
- (Op == OO_PlusPlus)? std::string("increment")
- : std::string("decrement"),
+ diag::kind DK;
+ if (Op == OO_PlusPlus) {
+ if (MethodDecl)
+ DK = diag::err_operator_overload_post_inc_must_be_int_member;
+ else
+ DK = diag::err_operator_overload_post_inc_must_be_int;
+ } else {
+ if (MethodDecl)
+ DK = diag::err_operator_overload_post_dec_must_be_int_member;
+ else
+ DK = diag::err_operator_overload_post_dec_must_be_int;
+ }
+ Diag(LastParam->getLocation(), DK,
Context.getCanonicalType(LastParam->getType()).getAsString(),
SourceRange(FnDecl->getLocation()));
IsInvalid = true;
More information about the cfe-commits
mailing list