aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/AST/Expr.cpp21
-rw-r--r--lib/Sema/SemaChecking.cpp37
-rw-r--r--lib/Sema/TreeTransform.h37
3 files changed, 70 insertions, 25 deletions
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index 49a255a369..b0bcfe09f6 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -3315,3 +3315,24 @@ BlockDeclRefExpr::BlockDeclRefExpr(VarDecl *d, QualType t, ExprValueKind VK,
ExprBits.ValueDependent = ValueDependent;
ExprBits.InstantiationDependent = InstantiationDependent;
}
+
+
+AtomicExpr::AtomicExpr(SourceLocation BLoc, Expr **args, unsigned nexpr,
+ QualType t, AtomicOp op, SourceLocation RP)
+ : Expr(AtomicExprClass, t, VK_RValue, OK_Ordinary,
+ false, false, false, false),
+ NumSubExprs(nexpr), BuiltinLoc(BLoc), RParenLoc(RP), Op(op)
+{
+ for (unsigned i = 0; i < nexpr; i++) {
+ if (args[i]->isTypeDependent())
+ ExprBits.TypeDependent = true;
+ if (args[i]->isValueDependent())
+ ExprBits.ValueDependent = true;
+ if (args[i]->isInstantiationDependent())
+ ExprBits.InstantiationDependent = true;
+ if (args[i]->containsUnexpandedParameterPack())
+ ExprBits.ContainsUnexpandedParameterPack = true;
+
+ SubExprs[i] = args[i];
+ }
+}
diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp
index 74c69a3ce3..310138354b 100644
--- a/lib/Sema/SemaChecking.cpp
+++ b/lib/Sema/SemaChecking.cpp
@@ -475,7 +475,6 @@ ExprResult
Sema::SemaAtomicOpsOverloaded(ExprResult TheCallResult, AtomicExpr::AtomicOp Op) {
CallExpr *TheCall = cast<CallExpr>(TheCallResult.get());
DeclRefExpr *DRE =cast<DeclRefExpr>(TheCall->getCallee()->IgnoreParenCasts());
- Expr *Ptr, *Order, *Val1, *Val2, *OrderFail;
// All these operations take one of the following four forms:
// T __atomic_load(_Atomic(T)*, int) (loads)
@@ -508,7 +507,7 @@ Sema::SemaAtomicOpsOverloaded(ExprResult TheCallResult, AtomicExpr::AtomicOp Op)
// Inspect the first argument of the atomic operation. This should always be
// a pointer to an _Atomic type.
- Ptr = TheCall->getArg(0);
+ Expr *Ptr = TheCall->getArg(0);
Ptr = DefaultFunctionArrayLvalueConversion(Ptr).get();
const PointerType *pointerType = Ptr->getType()->getAs<PointerType>();
if (!pointerType) {
@@ -591,30 +590,24 @@ Sema::SemaAtomicOpsOverloaded(ExprResult TheCallResult, AtomicExpr::AtomicOp Op)
TheCall->setArg(i, Arg.get());
}
+ SmallVector<Expr*, 5> SubExprs;
+ SubExprs.push_back(Ptr);
if (Op == AtomicExpr::Load) {
- Order = TheCall->getArg(1);
- return Owned(new (Context) AtomicExpr(TheCall->getCallee()->getLocStart(),
- Ptr, Order, ResultType, Op,
- TheCall->getRParenLoc(), false,
- false));
+ SubExprs.push_back(TheCall->getArg(1)); // Order
} else if (Op != AtomicExpr::CmpXchgWeak && Op != AtomicExpr::CmpXchgStrong) {
- Val1 = TheCall->getArg(1);
- Order = TheCall->getArg(2);
- return Owned(new (Context) AtomicExpr(TheCall->getCallee()->getLocStart(),
- Ptr, Val1, Order, ResultType, Op,
- TheCall->getRParenLoc(), false,
- false));
+ SubExprs.push_back(TheCall->getArg(2)); // Order
+ SubExprs.push_back(TheCall->getArg(1)); // Val1
} else {
- Val1 = TheCall->getArg(1);
- Val2 = TheCall->getArg(2);
- Order = TheCall->getArg(3);
- OrderFail = TheCall->getArg(4);
- return Owned(new (Context) AtomicExpr(TheCall->getCallee()->getLocStart(),
- Ptr, Val1, Val2, Order, OrderFail,
- ResultType, Op,
- TheCall->getRParenLoc(), false,
- false));
+ SubExprs.push_back(TheCall->getArg(3)); // Order
+ SubExprs.push_back(TheCall->getArg(1)); // Val1
+ SubExprs.push_back(TheCall->getArg(2)); // Val2
+ SubExprs.push_back(TheCall->getArg(4)); // OrderFail
}
+
+ return Owned(new (Context) AtomicExpr(TheCall->getCallee()->getLocStart(),
+ SubExprs.data(), SubExprs.size(),
+ ResultType, Op,
+ TheCall->getRParenLoc()));
}
diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h
index 4a2ad18e71..bb49eee2f3 100644
--- a/lib/Sema/TreeTransform.h
+++ b/lib/Sema/TreeTransform.h
@@ -2385,7 +2385,26 @@ public:
llvm::Optional<unsigned> NumExpansions) {
return getSema().CheckPackExpansion(Pattern, EllipsisLoc, NumExpansions);
}
-
+
+ /// \brief Build a new atomic operation expression.
+ ///
+ /// By default, performs semantic analysis to build the new expression.
+ /// Subclasses may override this routine to provide different behavior.
+ ExprResult RebuildAtomicExpr(SourceLocation BuiltinLoc,
+ MultiExprArg SubExprs,
+ QualType RetTy,
+ AtomicExpr::AtomicOp Op,
+ SourceLocation RParenLoc) {
+ // Just create the expression; there is not any interesting semantic
+ // analysis here because we can't actually build an AtomicExpr until
+ // we are sure it is semantically sound.
+ unsigned NumSubExprs = SubExprs.size();
+ Expr **Subs = (Expr **)SubExprs.release();
+ return new (SemaRef.Context) AtomicExpr(BuiltinLoc, Subs,
+ NumSubExprs, RetTy, Op,
+ RParenLoc);
+ }
+
private:
TypeLoc TransformTypeInObjectScope(TypeLoc TL,
QualType ObjectType,
@@ -8103,8 +8122,20 @@ TreeTransform<Derived>::TransformAsTypeExpr(AsTypeExpr *E) {
template<typename Derived>
ExprResult
TreeTransform<Derived>::TransformAtomicExpr(AtomicExpr *E) {
- assert(false && "Cannot transform atomic expressions yet");
- return SemaRef.Owned(E);
+ QualType RetTy = getDerived().TransformType(E->getType());
+ bool ArgumentChanged = false;
+ ASTOwningVector<Expr*> SubExprs(SemaRef);
+ SubExprs.reserve(E->getNumSubExprs());
+ if (getDerived().TransformExprs(E->getSubExprs(), E->getNumSubExprs(), false,
+ SubExprs, &ArgumentChanged))
+ return ExprError();
+
+ if (!getDerived().AlwaysRebuild() &&
+ !ArgumentChanged)
+ return SemaRef.Owned(E);
+
+ return getDerived().RebuildAtomicExpr(E->getBuiltinLoc(), move_arg(SubExprs),
+ RetTy, E->getOp(), E->getRParenLoc());
}
//===----------------------------------------------------------------------===//