diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/AST/Expr.cpp | 21 | ||||
-rw-r--r-- | lib/Sema/SemaChecking.cpp | 37 | ||||
-rw-r--r-- | lib/Sema/TreeTransform.h | 37 |
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()); } //===----------------------------------------------------------------------===// |