diff options
| author | Douglas Gregor <dgregor@apple.com> | 2008-11-10 13:38:07 +0000 | 
|---|---|---|
| committer | Douglas Gregor <dgregor@apple.com> | 2008-11-10 13:38:07 +0000 | 
| commit | 6cf0806e75fba6857c1c5df97f9881bf45e1ab42 (patch) | |
| tree | 222aa1c92d650aeb6f24f90f0f551c5f9247e415 /clang/lib | |
| parent | bba5c7c629565ccc78a58368bf320cbdbb579d7a (diff) | |
| download | bcm5719-llvm-6cf0806e75fba6857c1c5df97f9881bf45e1ab42.tar.gz bcm5719-llvm-6cf0806e75fba6857c1c5df97f9881bf45e1ab42.zip  | |
Some cleanups to the declaration/checking of overloaded operators in C++. Thanks to Sebastian for the review
llvm-svn: 58986
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/Basic/IdentifierTable.cpp | 2 | ||||
| -rw-r--r-- | clang/lib/Parse/ParseExprCXX.cpp | 4 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 132 | 
3 files changed, 43 insertions, 95 deletions
diff --git a/clang/lib/Basic/IdentifierTable.cpp b/clang/lib/Basic/IdentifierTable.cpp index e17f48ad3bd..2b9d7e38456 100644 --- a/clang/lib/Basic/IdentifierTable.cpp +++ b/clang/lib/Basic/IdentifierTable.cpp @@ -165,7 +165,7 @@ void IdentifierTable::AddKeywords(const LangOptions &LangOpts) {  /// 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" diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp index 2fe3bcf2db6..a1fd565822d 100644 --- a/clang/lib/Parse/ParseExprCXX.cpp +++ b/clang/lib/Parse/ParseExprCXX.cpp @@ -515,9 +515,9 @@ IdentifierInfo *Parser::MaybeParseOperatorFunctionId() {      }      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: diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 8bdb389f1f2..c10fd8b3c26 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -1801,83 +1801,16 @@ bool Sema::CheckOverloadedOperatorDeclaration(FunctionDecl *FnDecl) {      }    } -  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; +  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" +  }; -  // 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; -  } +  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 @@ bool Sema::CheckOverloadedOperatorDeclaration(FunctionDecl *FnDecl) {         (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 @@ bool Sema::CheckOverloadedOperatorDeclaration(FunctionDecl *FnDecl) {        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;  | 

