summaryrefslogtreecommitdiffstats
path: root/clang/include
diff options
context:
space:
mode:
Diffstat (limited to 'clang/include')
-rw-r--r--clang/include/clang/AST/Expr.h146
-rw-r--r--clang/include/clang/AST/RecursiveASTVisitor.h1
-rw-r--r--clang/include/clang/Basic/Builtins.def13
-rw-r--r--clang/include/clang/Basic/DiagnosticSemaKinds.td9
-rw-r--r--clang/include/clang/Basic/StmtNodes.td3
-rw-r--r--clang/include/clang/Sema/Sema.h2
-rw-r--r--clang/include/clang/Serialization/ASTBitCodes.h4
7 files changed, 176 insertions, 2 deletions
diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h
index 882124bfdd6..d7b6247b63c 100644
--- a/clang/include/clang/AST/Expr.h
+++ b/clang/include/clang/AST/Expr.h
@@ -4162,6 +4162,152 @@ public:
// Iterators
child_range children() { return child_range(&SrcExpr, &SrcExpr+1); }
};
+
+/// AtomicExpr - Variadic atomic builtins: __atomic_exchange, __atomic_fetch_*,
+/// __atomic_load, __atomic_store, and __atomic_compare_exchange_*, for the
+/// similarly-named C++0x instructions. All of these instructions take one
+/// primary pointer and at least one memory order.
+class AtomicExpr : public Expr {
+public:
+ enum AtomicOp { Load, Store, CmpXchgStrong, CmpXchgWeak, Xchg,
+ Add, Sub, And, Or, Xor };
+private:
+ enum { PTR, ORDER, VAL1, ORDER_FAIL, VAL2, END_EXPR };
+ Stmt* SubExprs[END_EXPR];
+ unsigned NumSubExprs;
+ SourceLocation BuiltinLoc, RParenLoc;
+ 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;
+ }
+
+ /// \brief Build an empty AtomicExpr.
+ explicit AtomicExpr(EmptyShell Empty) : Expr(AtomicExprClass, Empty) { }
+
+ Expr *getPtr() const {
+ return cast<Expr>(SubExprs[PTR]);
+ }
+ void setPtr(Expr *E) {
+ SubExprs[PTR] = E;
+ }
+ Expr *getOrder() const {
+ return cast<Expr>(SubExprs[ORDER]);
+ }
+ void setOrder(Expr *E) {
+ SubExprs[ORDER] = E;
+ }
+ Expr *getVal1() const {
+ assert(NumSubExprs >= 3);
+ return cast<Expr>(SubExprs[VAL1]);
+ }
+ void setVal1(Expr *E) {
+ assert(NumSubExprs >= 3);
+ SubExprs[VAL1] = E;
+ }
+ Expr *getOrderFail() const {
+ assert(NumSubExprs == 5);
+ return cast<Expr>(SubExprs[ORDER_FAIL]);
+ }
+ void setOrderFail(Expr *E) {
+ assert(NumSubExprs == 5);
+ SubExprs[ORDER_FAIL] = E;
+ }
+ Expr *getVal2() const {
+ assert(NumSubExprs == 5);
+ return cast<Expr>(SubExprs[VAL2]);
+ }
+ void setVal2(Expr *E) {
+ assert(NumSubExprs == 5);
+ SubExprs[VAL2] = E;
+ }
+
+ AtomicOp getOp() const { return Op; }
+ void setOp(AtomicOp op) { Op = op; }
+ unsigned getNumSubExprs() { return NumSubExprs; }
+ void setNumSubExprs(unsigned num) { NumSubExprs = num; }
+
+ bool isVolatile() const {
+ return getPtr()->getType()->getPointeeType().isVolatileQualified();
+ }
+
+ bool isCmpXChg() const {
+ return getOp() == AtomicExpr::CmpXchgStrong ||
+ getOp() == AtomicExpr::CmpXchgWeak;
+ }
+
+ SourceLocation getBuiltinLoc() const { return BuiltinLoc; }
+ void setBuiltinLoc(SourceLocation L) { BuiltinLoc = L; }
+
+ SourceLocation getRParenLoc() const { return RParenLoc; }
+ void setRParenLoc(SourceLocation L) { RParenLoc = L; }
+
+ SourceRange getSourceRange() const {
+ return SourceRange(BuiltinLoc, RParenLoc);
+ }
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == AtomicExprClass;
+ }
+ static bool classof(const AtomicExpr *) { return true; }
+
+ // Iterators
+ child_range children() {
+ return child_range(SubExprs, SubExprs+NumSubExprs);
+ }
+};
} // end namespace clang
#endif
diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h
index a224bb0a40c..0ec09c9b09e 100644
--- a/clang/include/clang/AST/RecursiveASTVisitor.h
+++ b/clang/include/clang/AST/RecursiveASTVisitor.h
@@ -1992,6 +1992,7 @@ DEF_TRAVERSE_STMT(SizeOfPackExpr, { })
DEF_TRAVERSE_STMT(SubstNonTypeTemplateParmPackExpr, { })
DEF_TRAVERSE_STMT(SubstNonTypeTemplateParmExpr, { })
DEF_TRAVERSE_STMT(MaterializeTemporaryExpr, { })
+DEF_TRAVERSE_STMT(AtomicExpr, { })
// These literals (all of them) do not need any action.
DEF_TRAVERSE_STMT(IntegerLiteral, { })
diff --git a/clang/include/clang/Basic/Builtins.def b/clang/include/clang/Basic/Builtins.def
index 50b51c7a4f7..60bcde372ac 100644
--- a/clang/include/clang/Basic/Builtins.def
+++ b/clang/include/clang/Basic/Builtins.def
@@ -585,7 +585,18 @@ BUILTIN(__sync_swap_4, "iiD*i.", "n")
BUILTIN(__sync_swap_8, "LLiLLiD*LLi.", "n")
BUILTIN(__sync_swap_16, "LLLiLLLiD*LLLi.", "n")
-
+BUILTIN(__atomic_load, "v.", "t")
+BUILTIN(__atomic_store, "v.", "t")
+BUILTIN(__atomic_exchange, "v.", "t")
+BUILTIN(__atomic_compare_exchange_strong, "v.", "t")
+BUILTIN(__atomic_compare_exchange_weak, "v.", "t")
+BUILTIN(__atomic_fetch_add, "v.", "t")
+BUILTIN(__atomic_fetch_sub, "v.", "t")
+BUILTIN(__atomic_fetch_and, "v.", "t")
+BUILTIN(__atomic_fetch_or, "v.", "t")
+BUILTIN(__atomic_fetch_xor, "v.", "t")
+BUILTIN(__atomic_thread_fence, "vi", "t")
+BUILTIN(__atomic_signal_fence, "vi", "t")
// Non-overloaded atomic builtins.
BUILTIN(__sync_synchronize, "v.", "n")
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index a1be656fac3..240401b3939 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -4012,6 +4012,15 @@ def err_atomic_builtin_must_be_pointer_intptr : Error<
def err_atomic_builtin_pointer_size : Error<
"first argument to atomic builtin must be a pointer to 1,2,4,8 or 16 byte "
"type (%0 invalid)">;
+def err_atomic_op_needs_atomic : Error<
+ "first argument to atomic operation must be a pointer to _Atomic "
+ "type (%0 invalid)">;
+def err_atomic_op_needs_atomic_int_or_ptr : Error<
+ "first argument to atomic operation must be a pointer to atomic "
+ "integer or pointer (%0 invalid)">;
+def err_atomic_op_logical_needs_atomic_int : Error<
+ "first argument to logical atomic operation must be a pointer to atomic "
+ "integer (%0 invalid)">;
def err_deleted_function_use : Error<"attempt to use a deleted function">;
diff --git a/clang/include/clang/Basic/StmtNodes.td b/clang/include/clang/Basic/StmtNodes.td
index 73996e43d5d..7b3d7762c24 100644
--- a/clang/include/clang/Basic/StmtNodes.td
+++ b/clang/include/clang/Basic/StmtNodes.td
@@ -78,6 +78,9 @@ def ParenListExpr : DStmt<Expr>;
def VAArgExpr : DStmt<Expr>;
def GenericSelectionExpr : DStmt<Expr>;
+// Atomic expressions
+def AtomicExpr : DStmt<Expr>;
+
// GNU Extensions.
def AddrLabelExpr : DStmt<Expr>;
def StmtExpr : DStmt<Expr>;
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 39c98997611..fec14c58260 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -6084,6 +6084,8 @@ private:
bool SemaBuiltinObjectSize(CallExpr *TheCall);
bool SemaBuiltinLongjmp(CallExpr *TheCall);
ExprResult SemaBuiltinAtomicOverloaded(ExprResult TheCallResult);
+ ExprResult SemaAtomicOpsOverloaded(ExprResult TheCallResult,
+ AtomicExpr::AtomicOp Op);
bool SemaBuiltinConstantArg(CallExpr *TheCall, int ArgNum,
llvm::APSInt &Result);
diff --git a/clang/include/clang/Serialization/ASTBitCodes.h b/clang/include/clang/Serialization/ASTBitCodes.h
index 9a8eba24274..1efd7542177 100644
--- a/clang/include/clang/Serialization/ASTBitCodes.h
+++ b/clang/include/clang/Serialization/ASTBitCodes.h
@@ -973,7 +973,9 @@ namespace clang {
EXPR_BLOCK_DECL_REF,
/// \brief A GenericSelectionExpr record.
EXPR_GENERIC_SELECTION,
-
+ /// \brief An AtomicExpr record.
+ EXPR_ATOMIC,
+
// Objective-C
/// \brief An ObjCStringLiteral record.
OpenPOWER on IntegriCloud