[cfe-commits] r142012 - in /cfe/trunk: include/clang/AST/Expr.h include/clang/AST/Stmt.h lib/AST/Expr.cpp lib/Sema/SemaChecking.cpp lib/Sema/TreeTransform.h

Eli Friedman eli.friedman at gmail.com
Fri Oct 14 15:48:56 PDT 2011


Author: efriedma
Date: Fri Oct 14 17:48:56 2011
New Revision: 142012

URL: http://llvm.org/viewvc/llvm-project?rev=142012&view=rev
Log:
Add template instantiation support for AtomicExpr.


Modified:
    cfe/trunk/include/clang/AST/Expr.h
    cfe/trunk/include/clang/AST/Stmt.h
    cfe/trunk/lib/AST/Expr.cpp
    cfe/trunk/lib/Sema/SemaChecking.cpp
    cfe/trunk/lib/Sema/TreeTransform.h

Modified: cfe/trunk/include/clang/AST/Expr.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Expr.h?rev=142012&r1=142011&r2=142012&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Expr.h (original)
+++ cfe/trunk/include/clang/AST/Expr.h Fri Oct 14 17:48:56 2011
@@ -4179,61 +4179,8 @@
   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 @@
   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();
   }

Modified: cfe/trunk/include/clang/AST/Stmt.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Stmt.h?rev=142012&r1=142011&r2=142012&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Stmt.h (original)
+++ cfe/trunk/include/clang/AST/Stmt.h Fri Oct 14 17:48:56 2011
@@ -146,6 +146,7 @@
     friend class CXXUnresolvedConstructExpr; // ctor
     friend class CXXDependentScopeMemberExpr; // ctor
     friend class OverloadExpr; // ctor
+    friend class AtomicExpr; // ctor
     unsigned : NumStmtBits;
 
     unsigned ValueKind : 2;

Modified: cfe/trunk/lib/AST/Expr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?rev=142012&r1=142011&r2=142012&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Expr.cpp (original)
+++ cfe/trunk/lib/AST/Expr.cpp Fri Oct 14 17:48:56 2011
@@ -3315,3 +3315,24 @@
   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];
+  }
+}

Modified: cfe/trunk/lib/Sema/SemaChecking.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaChecking.cpp?rev=142012&r1=142011&r2=142012&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaChecking.cpp (original)
+++ cfe/trunk/lib/Sema/SemaChecking.cpp Fri Oct 14 17:48:56 2011
@@ -475,7 +475,6 @@
 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 @@
 
   // 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 @@
     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()));
 }
 
 

Modified: cfe/trunk/lib/Sema/TreeTransform.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=142012&r1=142011&r2=142012&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/TreeTransform.h (original)
+++ cfe/trunk/lib/Sema/TreeTransform.h Fri Oct 14 17:48:56 2011
@@ -2385,7 +2385,26 @@
                                   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 @@
 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());
 }
   
 //===----------------------------------------------------------------------===//





More information about the cfe-commits mailing list