summaryrefslogtreecommitdiffstats
path: root/clang/lib/AST/Expr.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2016-12-06 23:52:28 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2016-12-06 23:52:28 +0000
commit122f88d481971b68d05ba12395c3b73ab4b31ab3 (patch)
treec59ee8196c104634ee39555cc8b9d97ee5d75b5c /clang/lib/AST/Expr.cpp
parent2187bb8a89cdbe529ee222bf56d1b7415337cb20 (diff)
downloadbcm5719-llvm-122f88d481971b68d05ba12395c3b73ab4b31ab3.tar.gz
bcm5719-llvm-122f88d481971b68d05ba12395c3b73ab4b31ab3.zip
[c++17] P0135R1: Guaranteed copy elision.
When an object of class type is initialized from a prvalue of the same type (ignoring cv qualifications), use the prvalue to initialize the object directly instead of inserting a redundant elidable call to a copy constructor. llvm-svn: 288866
Diffstat (limited to 'clang/lib/AST/Expr.cpp')
-rw-r--r--clang/lib/AST/Expr.cpp29
1 files changed, 25 insertions, 4 deletions
diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp
index e43a9c53d90..776a7f996d0 100644
--- a/clang/lib/AST/Expr.cpp
+++ b/clang/lib/AST/Expr.cpp
@@ -1864,6 +1864,24 @@ bool InitListExpr::isStringLiteralInit() const {
return isa<StringLiteral>(Init) || isa<ObjCEncodeExpr>(Init);
}
+bool InitListExpr::isTransparent() const {
+ assert(isSemanticForm() && "syntactic form never semantically transparent");
+
+ // A glvalue InitListExpr is always just sugar.
+ if (isGLValue()) {
+ assert(getNumInits() == 1 && "multiple inits in glvalue init list");
+ return true;
+ }
+
+ // Otherwise, we're sugar if and only if we have exactly one initializer that
+ // is of the same type.
+ if (getNumInits() != 1 || !getInit(0))
+ return false;
+
+ return getType().getCanonicalType() ==
+ getInit(0)->getType().getCanonicalType();
+}
+
SourceLocation InitListExpr::getLocStart() const {
if (InitListExpr *SyntacticForm = getSyntacticForm())
return SyntacticForm->getLocStart();
@@ -2246,12 +2264,15 @@ bool Expr::isUnusedResultAWarning(const Expr *&WarnE, SourceLocation &Loc,
// effects (e.g. a placement new with an uninitialized POD).
case CXXDeleteExprClass:
return false;
+ case MaterializeTemporaryExprClass:
+ return cast<MaterializeTemporaryExpr>(this)->GetTemporaryExpr()
+ ->isUnusedResultAWarning(WarnE, Loc, R1, R2, Ctx);
case CXXBindTemporaryExprClass:
- return (cast<CXXBindTemporaryExpr>(this)
- ->getSubExpr()->isUnusedResultAWarning(WarnE, Loc, R1, R2, Ctx));
+ return cast<CXXBindTemporaryExpr>(this)->getSubExpr()
+ ->isUnusedResultAWarning(WarnE, Loc, R1, R2, Ctx);
case ExprWithCleanupsClass:
- return (cast<ExprWithCleanups>(this)
- ->getSubExpr()->isUnusedResultAWarning(WarnE, Loc, R1, R2, Ctx));
+ return cast<ExprWithCleanups>(this)->getSubExpr()
+ ->isUnusedResultAWarning(WarnE, Loc, R1, R2, Ctx);
}
}
OpenPOWER on IntegriCloud