diff options
Diffstat (limited to 'clang/lib/Sema')
| -rw-r--r-- | clang/lib/Sema/SemaChecking.cpp | 37 | ||||
| -rw-r--r-- | clang/lib/Sema/TreeTransform.h | 37 | 
2 files changed, 49 insertions, 25 deletions
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 74c69a3ce34..310138354bb 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/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/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 4a2ad18e712..bb49eee2f33 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/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());  }  //===----------------------------------------------------------------------===//  | 

