OwningExprResult CreateBuiltinUnaryOp(SourceLocation OpLoc,
unsigned OpcIn,
ExprArg InputArg);
+ OwningExprResult BuildUnaryOp(Scope *S, SourceLocation OpLoc,
+ UnaryOperator::Opcode Opc, ExprArg input);
virtual OwningExprResult ActOnUnaryOp(Scope *S, SourceLocation OpLoc,
tok::TokenKind Op, ExprArg Input);
virtual OwningExprResult ActOnBinOp(Scope *S, SourceLocation TokLoc,
tok::TokenKind Kind,
ExprArg LHS, ExprArg RHS);
+ OwningExprResult BuildBinOp(Scope *S, SourceLocation OpLoc,
+ BinaryOperator::Opcode Opc,
+ Expr *lhs, Expr *rhs);
OwningExprResult CreateBuiltinBinOp(SourceLocation TokLoc,
unsigned Opc, Expr *lhs, Expr *rhs);
// Emit warnings for tricky precedence issues, e.g. "bitfield & 0x4 == 0"
DiagnoseBinOpPrecedence(*this, Opc, TokLoc, lhs, rhs);
+ return BuildBinOp(S, TokLoc, Opc, lhs, rhs);
+}
+
+Action::OwningExprResult Sema::BuildBinOp(Scope *S, SourceLocation OpLoc,
+ BinaryOperator::Opcode Opc,
+ Expr *lhs, Expr *rhs) {
if (getLangOptions().CPlusPlus &&
(lhs->getType()->isOverloadableType() ||
rhs->getType()->isOverloadableType())) {
FunctionSet Functions;
OverloadedOperatorKind OverOp = BinaryOperator::getOverloadedOperator(Opc);
if (OverOp != OO_None) {
- LookupOverloadedOperatorName(OverOp, S, lhs->getType(), rhs->getType(),
- Functions);
+ if (S)
+ LookupOverloadedOperatorName(OverOp, S, lhs->getType(), rhs->getType(),
+ Functions);
Expr *Args[2] = { lhs, rhs };
DeclarationName OpName
= Context.DeclarationNames.getCXXOperatorName(OverOp);
ArgumentDependentLookup(OpName, /*Operator*/true, Args, 2, Functions);
}
-
+
// Build the (potentially-overloaded, potentially-dependent)
// binary operation.
- return CreateOverloadedBinOp(TokLoc, Opc, Functions, lhs, rhs);
+ return CreateOverloadedBinOp(OpLoc, Opc, Functions, lhs, rhs);
}
-
+
// Build a built-in binary operation.
- return CreateBuiltinBinOp(TokLoc, Opc, lhs, rhs);
+ return CreateBuiltinBinOp(OpLoc, Opc, lhs, rhs);
}
Action::OwningExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc,
return Owned(new (Context) UnaryOperator(Input, Opc, resultType, OpLoc));
}
-// Unary Operators. 'Tok' is the token for the operator.
-Action::OwningExprResult Sema::ActOnUnaryOp(Scope *S, SourceLocation OpLoc,
- tok::TokenKind Op, ExprArg input) {
+Action::OwningExprResult Sema::BuildUnaryOp(Scope *S, SourceLocation OpLoc,
+ UnaryOperator::Opcode Opc,
+ ExprArg input) {
Expr *Input = (Expr*)input.get();
- UnaryOperator::Opcode Opc = ConvertTokenKindToUnaryOpcode(Op);
-
if (getLangOptions().CPlusPlus && Input->getType()->isOverloadableType()) {
// Find all of the overloaded operators visible from this
// point. We perform both an operator-name lookup from the local
FunctionSet Functions;
OverloadedOperatorKind OverOp = UnaryOperator::getOverloadedOperator(Opc);
if (OverOp != OO_None) {
- LookupOverloadedOperatorName(OverOp, S, Input->getType(), QualType(),
- Functions);
+ if (S)
+ LookupOverloadedOperatorName(OverOp, S, Input->getType(), QualType(),
+ Functions);
DeclarationName OpName
= Context.DeclarationNames.getCXXOperatorName(OverOp);
ArgumentDependentLookup(OpName, /*Operator*/true, &Input, 1, Functions);
}
-
+
return CreateOverloadedUnaryOp(OpLoc, Opc, Functions, move(input));
}
-
+
return CreateBuiltinUnaryOp(OpLoc, Opc, move(input));
}
+// Unary Operators. 'Tok' is the token for the operator.
+Action::OwningExprResult Sema::ActOnUnaryOp(Scope *S, SourceLocation OpLoc,
+ tok::TokenKind Op, ExprArg input) {
+ return BuildUnaryOp(S, OpLoc, ConvertTokenKindToUnaryOpcode(Op), move(input));
+}
+
/// ActOnAddrLabel - Parse the GNU address of label extension: "&&foo".
Sema::OwningExprResult Sema::ActOnAddrLabel(SourceLocation OpLoc,
SourceLocation LabLoc,
// If either side is type-dependent, create an appropriate dependent
// expression.
if (Args[0]->isTypeDependent() || Args[1]->isTypeDependent()) {
- // .* cannot be overloaded.
- if (Opc == BinaryOperator::PtrMemD)
- return Owned(new (Context) BinaryOperator(Args[0], Args[1], Opc,
- Context.DependentTy, OpLoc));
-
+ if (Functions.empty()) {
+ // If there are no functions to store, just build a dependent
+ // BinaryOperator or CompoundAssignment.
+ if (Opc <= BinaryOperator::Assign || Opc > BinaryOperator::OrAssign)
+ return Owned(new (Context) BinaryOperator(Args[0], Args[1], Opc,
+ Context.DependentTy, OpLoc));
+
+ return Owned(new (Context) CompoundAssignOperator(Args[0], Args[1], Opc,
+ Context.DependentTy,
+ Context.DependentTy,
+ Context.DependentTy,
+ OpLoc));
+ }
+
OverloadedFunctionDecl *Overloads
= OverloadedFunctionDecl::Create(Context, CurContext, OpName);
for (FunctionSet::iterator Func = Functions.begin(),
OwningExprResult RebuildUnaryOperator(SourceLocation OpLoc,
UnaryOperator::Opcode Opc,
ExprArg SubExpr) {
- return getSema().CreateBuiltinUnaryOp(OpLoc, Opc, move(SubExpr));
+ return getSema().BuildUnaryOp(/*Scope=*/0, OpLoc, Opc, move(SubExpr));
}
/// \brief Build a new sizeof or alignof expression with a type argument.
OwningExprResult RebuildBinaryOperator(SourceLocation OpLoc,
BinaryOperator::Opcode Opc,
ExprArg LHS, ExprArg RHS) {
- OwningExprResult Result
- = getSema().CreateBuiltinBinOp(OpLoc, Opc, (Expr *)LHS.get(),
- (Expr *)RHS.get());
- if (Result.isInvalid())
- return SemaRef.ExprError();
-
- LHS.release();
- RHS.release();
- return move(Result);
+ return getSema().BuildBinOp(/*Scope=*/0, OpLoc, Opc,
+ LHS.takeAs<Expr>(), RHS.takeAs<Expr>());
}
/// \brief Build a new conditional operator expression.