summaryrefslogtreecommitdiffstats
path: root/clang/lib/AST/Expr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/AST/Expr.cpp')
-rw-r--r--clang/lib/AST/Expr.cpp39
1 files changed, 39 insertions, 0 deletions
diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp
index 7c62ccf052c..f04a78f609a 100644
--- a/clang/lib/AST/Expr.cpp
+++ b/clang/lib/AST/Expr.cpp
@@ -1829,6 +1829,45 @@ OverloadedOperatorKind BinaryOperator::getOverloadedOperator(Opcode Opc) {
return OverOps[Opc];
}
+bool BinaryOperator::isNullPointerArithmeticExtension(ASTContext &Ctx,
+ Opcode Opc,
+ Expr *LHS, Expr *RHS) {
+ if (Opc != BO_Add)
+ return false;
+
+ // Check that we have one pointer and one integer operand.
+ Expr *PExp;
+ Expr *IExp;
+ if (LHS->getType()->isPointerType()) {
+ if (!RHS->getType()->isIntegerType())
+ return false;
+ PExp = LHS;
+ IExp = RHS;
+ } else if (RHS->getType()->isPointerType()) {
+ if (!LHS->getType()->isIntegerType())
+ return false;
+ PExp = RHS;
+ IExp = LHS;
+ } else {
+ return false;
+ }
+
+ // Check that the pointer is a nullptr.
+ if (!PExp->IgnoreParenCasts()
+ ->isNullPointerConstant(Ctx, Expr::NPC_ValueDependentIsNotNull))
+ return false;
+
+ // Check that the pointee type is char-sized.
+ const PointerType *PTy = PExp->getType()->getAs<PointerType>();
+ if (!PTy || !PTy->getPointeeType()->isCharType())
+ return false;
+
+ // Check that the integer type is pointer-sized.
+ if (Ctx.getTypeSize(IExp->getType()) != Ctx.getTypeSize(PExp->getType()))
+ return false;
+
+ return true;
+}
InitListExpr::InitListExpr(const ASTContext &C, SourceLocation lbraceloc,
ArrayRef<Expr*> initExprs, SourceLocation rbraceloc)
: Expr(InitListExprClass, QualType(), VK_RValue, OK_Ordinary, false, false,
OpenPOWER on IntegriCloud