]> granicus.if.org Git - clang/commitdiff
Add template instantiation support for AtomicExpr.
authorEli Friedman <eli.friedman@gmail.com>
Fri, 14 Oct 2011 22:48:56 +0000 (22:48 +0000)
committerEli Friedman <eli.friedman@gmail.com>
Fri, 14 Oct 2011 22:48:56 +0000 (22:48 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@142012 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/Expr.h
include/clang/AST/Stmt.h
lib/AST/Expr.cpp
lib/Sema/SemaChecking.cpp
lib/Sema/TreeTransform.h

index d7b6247b63cc65d51a1dcc11f522edab77dce35d..1242f4e6c702c38532c47bde2da2b6093472b979 100644 (file)
@@ -4179,61 +4179,8 @@ private:
   AtomicOp Op;
 
 public:
-  // Constructor for Load
-  AtomicExpr(SourceLocation BLoc, Expr *ptr, Expr *order, QualType t,
-             AtomicOp op, SourceLocation RP,
-             bool TypeDependent, bool ValueDependent)
-    : Expr(AtomicExprClass, t, VK_RValue, OK_Ordinary,
-           TypeDependent, ValueDependent,
-           ptr->isInstantiationDependent(),
-           ptr->containsUnexpandedParameterPack()),
-      BuiltinLoc(BLoc), RParenLoc(RP), Op(op) {
-      assert(op == Load && "single-argument atomic must be load");
-      SubExprs[PTR] = ptr;
-      SubExprs[ORDER] = order;
-      NumSubExprs = 2;
-    }
-
-  // Constructor for Store, Xchg, Add, Sub, And, Or, Xor
-  AtomicExpr(SourceLocation BLoc, Expr *ptr, Expr *val, Expr *order,
-             QualType t, AtomicOp op, SourceLocation RP,
-             bool TypeDependent, bool ValueDependent)
-      : Expr(AtomicExprClass, t, VK_RValue, OK_Ordinary,
-             TypeDependent, ValueDependent,
-             (ptr->isInstantiationDependent() ||
-              val->isInstantiationDependent()),
-             (ptr->containsUnexpandedParameterPack() ||
-              val->containsUnexpandedParameterPack())),
-        BuiltinLoc(BLoc), RParenLoc(RP), Op(op) {
-        assert(!isCmpXChg() && op != Load &&
-               "two-argument atomic store or binop");
-        SubExprs[PTR] = ptr;
-        SubExprs[ORDER] = order;
-        SubExprs[VAL1] = val;
-        NumSubExprs = 3;
-      }
-
-  // Constructor for CmpXchgStrong, CmpXchgWeak
-  AtomicExpr(SourceLocation BLoc, Expr *ptr, Expr *val1, Expr *val2,
-             Expr *order, Expr *order_fail, QualType t, AtomicOp op,
-             SourceLocation RP, bool TypeDependent, bool ValueDependent)
-    : Expr(AtomicExprClass, t, VK_RValue, OK_Ordinary,
-           TypeDependent, ValueDependent,
-           (ptr->isInstantiationDependent() ||
-            val1->isInstantiationDependent() ||
-            val2->isInstantiationDependent()),
-           (ptr->containsUnexpandedParameterPack() ||
-            val1->containsUnexpandedParameterPack() ||
-            val2->containsUnexpandedParameterPack())),
-      BuiltinLoc(BLoc), RParenLoc(RP), Op(op) {
-      assert(isCmpXChg() && "three-argument atomic must be cmpxchg");
-      SubExprs[PTR] = ptr;
-      SubExprs[ORDER] = order;
-      SubExprs[VAL1] = val1;
-      SubExprs[VAL2] = val2;
-      SubExprs[ORDER_FAIL] = order_fail;
-      NumSubExprs = 5;
-    }
+  AtomicExpr(SourceLocation BLoc, Expr **args, unsigned nexpr, QualType t,
+             AtomicOp op, SourceLocation RP);
 
   /// \brief Build an empty AtomicExpr.
   explicit AtomicExpr(EmptyShell Empty) : Expr(AtomicExprClass, Empty) { }
@@ -4280,6 +4227,8 @@ public:
   unsigned getNumSubExprs() { return NumSubExprs; }
   void setNumSubExprs(unsigned num) { NumSubExprs = num; }
 
+  Expr **getSubExprs() { return reinterpret_cast<Expr **>(SubExprs); }
+
   bool isVolatile() const {
     return getPtr()->getType()->getPointeeType().isVolatileQualified();
   }
index 8a3a74c2bdc22e22f0774b83f80de970a2162be8..2a6fd6bc964cccf008aebb9f6cb3d96dba6f80f9 100644 (file)
@@ -146,6 +146,7 @@ protected:
     friend class CXXUnresolvedConstructExpr; // ctor
     friend class CXXDependentScopeMemberExpr; // ctor
     friend class OverloadExpr; // ctor
+    friend class AtomicExpr; // ctor
     unsigned : NumStmtBits;
 
     unsigned ValueKind : 2;
index 49a255a369108df124765f265efb87f7eb5e32b0..b0bcfe09f6dc387cfb18458fe44239cb2cc823c6 100644 (file)
@@ -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];
+  }
+}
index 74c69a3ce34f6db167bcfb8440dcef311cd6cd9b..310138354bb95ea96bbbbbfa92f10a87596b1a89 100644 (file)
@@ -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()));
 }
 
 
index 4a2ad18e7126a57296ae6c1cf3fe56f3aab4a500..bb49eee2f332c1c5fd1e4f6738f24bfd04d65ba0 100644 (file)
@@ -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());
 }
   
 //===----------------------------------------------------------------------===//