aboutsummaryrefslogtreecommitdiff
path: root/lib/AST/Expr.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2009-03-13 18:40:31 +0000
committerDouglas Gregor <dgregor@apple.com>2009-03-13 18:40:31 +0000
commit063daf6e196c51f162e0485478355d8e280eef5c (patch)
tree96bfffedbfbbf33d16167cde703b691cf2e2a7dd /lib/AST/Expr.cpp
parent13135a6171e5eb1dd0b10f49305bb757b8f8b20c (diff)
Refactor the way we handle operator overloading and template
instantiation for binary operators. This change moves most of the operator-overloading code from the parser action ActOnBinOp to a new, parser-independent semantic checking routine CreateOverloadedBinOp. Of particular importance is the fact that CreateOverloadedBinOp does *not* perform any name lookup based on the current parsing context (it doesn't take a Scope*), since it has to be usable during template instantiation, when there is no scope information. Rather, it takes a pre-computed set of functions that are visible from the context or via argument-dependent lookup, and adds to that set any member operators and built-in operator candidates. The set of functions is computed in the parser action ActOnBinOp based on the current context (both operator name lookup and argument-dependent lookup). Within a template, the set computed by ActOnBinOp is saved within the type-dependent AST node and is augmented with the results of argument-dependent name lookup at instantiation time (see TemplateExprInstantiator::VisitCXXOperatorCallExpr). Sadly, we can't fully test this yet. I'll follow up with template instantiation for sizeof so that the real fun can begin. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@66923 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST/Expr.cpp')
-rw-r--r--lib/AST/Expr.cpp62
1 files changed, 62 insertions, 0 deletions
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index 9612f7ff2a..4b99eefcd4 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -227,6 +227,68 @@ const char *BinaryOperator::getOpcodeStr(Opcode Op) {
return "";
}
+BinaryOperator::Opcode
+BinaryOperator::getOverloadedOpcode(OverloadedOperatorKind OO) {
+ switch (OO) {
+ case OO_Plus: return Add;
+ case OO_Minus: return Sub;
+ case OO_Star: return Mul;
+ case OO_Slash: return Div;
+ case OO_Percent: return Rem;
+ case OO_Caret: return Xor;
+ case OO_Amp: return And;
+ case OO_Pipe: return Or;
+ case OO_Equal: return Assign;
+ case OO_Less: return LT;
+ case OO_Greater: return GT;
+ case OO_PlusEqual: return AddAssign;
+ case OO_MinusEqual: return SubAssign;
+ case OO_StarEqual: return MulAssign;
+ case OO_SlashEqual: return DivAssign;
+ case OO_PercentEqual: return RemAssign;
+ case OO_CaretEqual: return XorAssign;
+ case OO_AmpEqual: return AndAssign;
+ case OO_PipeEqual: return OrAssign;
+ case OO_LessLess: return Shl;
+ case OO_GreaterGreater: return Shr;
+ case OO_LessLessEqual: return ShlAssign;
+ case OO_GreaterGreaterEqual: return ShrAssign;
+ case OO_EqualEqual: return EQ;
+ case OO_ExclaimEqual: return NE;
+ case OO_LessEqual: return LE;
+ case OO_GreaterEqual: return GE;
+ case OO_AmpAmp: return LAnd;
+ case OO_PipePipe: return LOr;
+ case OO_Comma: return Comma;
+ case OO_ArrowStar: return PtrMemI;
+ default: assert(false && "Not an overloadable binary operator");
+ }
+}
+
+OverloadedOperatorKind BinaryOperator::getOverloadedOperator(Opcode Opc) {
+ static const OverloadedOperatorKind OverOps[] = {
+ /* .* Cannot be overloaded */OO_None, OO_ArrowStar,
+ OO_Star, OO_Slash, OO_Percent,
+ OO_Plus, OO_Minus,
+ OO_LessLess, OO_GreaterGreater,
+ OO_Less, OO_Greater, OO_LessEqual, OO_GreaterEqual,
+ OO_EqualEqual, OO_ExclaimEqual,
+ OO_Amp,
+ OO_Caret,
+ OO_Pipe,
+ OO_AmpAmp,
+ OO_PipePipe,
+ OO_Equal, OO_StarEqual,
+ OO_SlashEqual, OO_PercentEqual,
+ OO_PlusEqual, OO_MinusEqual,
+ OO_LessLessEqual, OO_GreaterGreaterEqual,
+ OO_AmpEqual, OO_CaretEqual,
+ OO_PipeEqual,
+ OO_Comma
+ };
+ return OverOps[Opc];
+}
+
InitListExpr::InitListExpr(SourceLocation lbraceloc,
Expr **initExprs, unsigned numInits,
SourceLocation rbraceloc)