diff options
| author | Douglas Gregor <dgregor@apple.com> | 2008-11-06 22:13:31 +0000 |
|---|---|---|
| committer | Douglas Gregor <dgregor@apple.com> | 2008-11-06 22:13:31 +0000 |
| commit | 11d0c4c0985fc37a844c0c3033db9f49291e2e1f (patch) | |
| tree | 4437dd5182125f02765bdb5e19309bd3cacf0e1f /clang/lib/Parse/ParseExprCXX.cpp | |
| parent | 193e4c025efda046c3db4be1efb098a491767ff9 (diff) | |
| download | bcm5719-llvm-11d0c4c0985fc37a844c0c3033db9f49291e2e1f.tar.gz bcm5719-llvm-11d0c4c0985fc37a844c0c3033db9f49291e2e1f.zip | |
Parsing, ASTs, and semantic analysis for the declaration of overloaded
operators in C++. Overloaded operators can be called directly via
their operator-function-ids, e.g., "operator+(foo, bar)", but we don't
yet implement the semantics of operator overloading to handle, e.g.,
"foo + bar".
llvm-svn: 58817
Diffstat (limited to 'clang/lib/Parse/ParseExprCXX.cpp')
| -rw-r--r-- | clang/lib/Parse/ParseExprCXX.cpp | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp index 2b9ab550320..fcb229b3621 100644 --- a/clang/lib/Parse/ParseExprCXX.cpp +++ b/clang/lib/Parse/ParseExprCXX.cpp @@ -291,3 +291,78 @@ void Parser::ParseCXXSimpleTypeSpecifier(DeclSpec &DS) { ConsumeToken(); DS.Finish(Diags, PP.getSourceManager(), getLang()); } + +/// MaybeParseOperatorFunctionId - Attempts to parse a C++ overloaded +/// operator name (C++ [over.oper]). If successful, returns the +/// predefined identifier that corresponds to that overloaded +/// operator. Otherwise, returns NULL and does not consume any tokens. +/// +/// operator-function-id: [C++ 13.5] +/// 'operator' operator +/// +/// operator: one of +/// new delete new[] delete[] +/// + - * / % ^ & | ~ +/// ! = < > += -= *= /= %= +/// ^= &= |= << >> >>= <<= == != +/// <= >= && || ++ -- , ->* -> +/// () [] +IdentifierInfo *Parser::MaybeParseOperatorFunctionId() { + if (Tok.isNot(tok::kw_operator)) + return 0; + + OverloadedOperatorKind Op = OO_None; + switch (NextToken().getKind()) { + case tok::kw_new: + ConsumeToken(); // 'operator' + ConsumeToken(); // 'new' + if (Tok.is(tok::l_square)) { + ConsumeBracket(); // '[' + ExpectAndConsume(tok::r_square, diag::err_expected_rsquare); // ']' + Op = OO_Array_New; + } else { + Op = OO_New; + } + return &PP.getIdentifierTable().getOverloadedOperator(Op); + + case tok::kw_delete: + ConsumeToken(); // 'operator' + ConsumeToken(); // 'delete' + if (Tok.is(tok::l_square)) { + ConsumeBracket(); // '[' + ExpectAndConsume(tok::r_square, diag::err_expected_rsquare); // ']' + Op = OO_Array_Delete; + } else { + Op = OO_Delete; + } + return &PP.getIdentifierTable().getOverloadedOperator(Op); + +#define OVERLOADED_OPERATOR(Name,Spelling,Token) \ + case tok::Token: Op = OO_##Name; break; +#define OVERLOADED_OPERATOR_MULTI(Name,Spelling) +#include "clang/Basic/OperatorKinds.def" + + case tok::l_paren: + ConsumeToken(); // 'operator' + ConsumeParen(); // '(' + ExpectAndConsume(tok::r_paren, diag::err_expected_rparen); // ')' + return &PP.getIdentifierTable().getOverloadedOperator(OO_Call); + + case tok::l_square: + ConsumeToken(); // 'operator' + ConsumeBracket(); // '[' + ExpectAndConsume(tok::r_square, diag::err_expected_rsquare); // ']' + return &PP.getIdentifierTable().getOverloadedOperator(OO_Subscript); + + default: + break; + } + + if (Op == OO_None) + return 0; + else { + ExpectAndConsume(tok::kw_operator, diag::err_expected_operator); + ConsumeAnyToken(); // the operator itself + return &PP.getIdentifierTable().getOverloadedOperator(Op); + } +} |

