aboutsummaryrefslogtreecommitdiff
path: root/lib/AST/Expr.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2008-11-14 16:09:21 +0000
committerDouglas Gregor <dgregor@apple.com>2008-11-14 16:09:21 +0000
commitb4609806e9232593ece09ce08b630836e825865c (patch)
tree7b70b5d015a0fd6fbf2907a5a0a12596f2760823 /lib/AST/Expr.cpp
parent0aab796da21bfc45381d3ce76c795710cb97acfc (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.cpp19
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())));