diff options
author | Douglas Gregor <dgregor@apple.com> | 2008-11-14 16:09:21 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2008-11-14 16:09:21 +0000 |
commit | b4609806e9232593ece09ce08b630836e825865c (patch) | |
tree | 7b70b5d015a0fd6fbf2907a5a0a12596f2760823 /lib/AST/Expr.cpp | |
parent | 0aab796da21bfc45381d3ce76c795710cb97acfc (diff) |
Add a new expression node, CXXOperatorCallExpr, which expresses a
function call created in response to the use of operator syntax that
resolves to an overloaded operator in C++, e.g., "str1 +
str2" that resolves to std::operator+(str1, str2)". We now build a
CXXOperatorCallExpr in C++ when we pick an overloaded operator. (But
only for binary operators, where we actually implement overloading)
I decided *not* to refactor the current CallExpr to make it abstract
(with FunctionCallExpr and CXXOperatorCallExpr as derived
classes). Doing so would allow us to make CXXOperatorCallExpr a little
bit smaller, at the cost of making the argument and callee accessors
virtual. We won't know if this is going to be a win until we can parse
lots of C++ code to determine how much memory we'll save by making
this change vs. the performance penalty due to the extra virtual
calls.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@59306 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST/Expr.cpp')
-rw-r--r-- | lib/AST/Expr.cpp | 19 |
1 files changed, 16 insertions, 3 deletions
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp index 249bebc91f..871dc4bb77 100644 --- a/lib/AST/Expr.cpp +++ b/lib/AST/Expr.cpp @@ -101,6 +101,15 @@ const char *UnaryOperator::getOpcodeStr(Opcode Op) { // Postfix Operators. //===----------------------------------------------------------------------===// +CallExpr::CallExpr(StmtClass SC, Expr *fn, Expr **args, unsigned numargs, + QualType t, SourceLocation rparenloc) + : Expr(SC, t), NumArgs(numargs) { + SubExprs = new Stmt*[numargs+1]; + SubExprs[FN] = fn; + for (unsigned i = 0; i != numargs; ++i) + SubExprs[i+ARGS_START] = args[i]; + RParenLoc = rparenloc; +} CallExpr::CallExpr(Expr *fn, Expr **args, unsigned numargs, QualType t, SourceLocation rparenloc) @@ -285,6 +294,7 @@ bool Expr::hasLocalSideEffect() const { return getType().isVolatileQualified(); case CallExprClass: + case CXXOperatorCallExprClass: // TODO: check attributes for pure/const. "void foo() { strlen("bar"); }" // should warn. return true; @@ -410,7 +420,8 @@ Expr::isLvalueResult Expr::isLvalue(ASTContext &Ctx) const { // An assignment expression [...] is not an lvalue. return LV_InvalidExpression; } - case CallExprClass: { + case CallExprClass: + case CXXOperatorCallExprClass: { // C++ [expr.call]p10: // A function call is an lvalue if and only if the result type // is a reference. @@ -586,7 +597,8 @@ bool Expr::isConstantExpr(ASTContext &Ctx, SourceLocation *Loc) const { case CXXBoolLiteralExprClass: case AddrLabelExprClass: return true; - case CallExprClass: { + case CallExprClass: + case CXXOperatorCallExprClass: { const CallExpr *CE = cast<CallExpr>(this); // Allow any constant foldable calls to builtins. @@ -777,7 +789,8 @@ bool Expr::isIntegerConstantExpr(llvm::APSInt &Result, ASTContext &Ctx, T1.getUnqualifiedType()); break; } - case CallExprClass: { + case CallExprClass: + case CXXOperatorCallExprClass: { const CallExpr *CE = cast<CallExpr>(this); Result.zextOrTrunc(static_cast<uint32_t>(Ctx.getTypeSize(getType()))); |