aboutsummaryrefslogtreecommitdiff
path: root/lib/AST
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2012-04-12 05:08:17 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2012-04-12 05:08:17 +0000
commitff34d401ff385ef7173ca612432b4ea717fff690 (patch)
treede759a7c65405730906e7d4ffd5f25cbbd5bcf69 /lib/AST
parentb92bd4b3271b7892abe9fd8c74fb54a27ad702ab (diff)
Implement support for 18 of the GNU-compatible __atomic builtins.
This is not quite sufficient for libstdc++'s <atomic>: we still need __atomic_test_and_set and __atomic_clear, and may need a more complete __atomic_is_lock_free implementation. We are also missing an implementation of __atomic_always_lock_free, __atomic_nand_fetch, and __atomic_fetch_nand, but those aren't needed for libstdc++. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@154579 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST')
-rw-r--r--lib/AST/Expr.cpp46
-rw-r--r--lib/AST/StmtPrinter.cpp54
2 files changed, 53 insertions, 47 deletions
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index 2bb79a0a4a..eb185b2c5a 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -3858,20 +3858,44 @@ AtomicExpr::AtomicExpr(SourceLocation BLoc, Expr **args, unsigned nexpr,
unsigned AtomicExpr::getNumSubExprs(AtomicOp Op) {
switch (Op) {
- case Init:
- case Load:
+ case AO__c11_atomic_init:
+ case AO__c11_atomic_load:
+ case AO__atomic_load_n:
return 2;
- case Store:
- case Xchg:
- case Add:
- case Sub:
- case And:
- case Or:
- case Xor:
+
+ case AO__c11_atomic_store:
+ case AO__c11_atomic_exchange:
+ case AO__atomic_load:
+ case AO__atomic_store:
+ case AO__atomic_store_n:
+ case AO__atomic_exchange_n:
+ case AO__c11_atomic_fetch_add:
+ case AO__c11_atomic_fetch_sub:
+ case AO__c11_atomic_fetch_and:
+ case AO__c11_atomic_fetch_or:
+ case AO__c11_atomic_fetch_xor:
+ case AO__atomic_fetch_add:
+ case AO__atomic_fetch_sub:
+ case AO__atomic_fetch_and:
+ case AO__atomic_fetch_or:
+ case AO__atomic_fetch_xor:
+ case AO__atomic_add_fetch:
+ case AO__atomic_sub_fetch:
+ case AO__atomic_and_fetch:
+ case AO__atomic_or_fetch:
+ case AO__atomic_xor_fetch:
return 3;
- case CmpXchgStrong:
- case CmpXchgWeak:
+
+ case AO__atomic_exchange:
+ return 4;
+
+ case AO__c11_atomic_compare_exchange_strong:
+ case AO__c11_atomic_compare_exchange_weak:
return 5;
+
+ case AO__atomic_compare_exchange:
+ case AO__atomic_compare_exchange_n:
+ return 6;
}
llvm_unreachable("unknown atomic op");
}
diff --git a/lib/AST/StmtPrinter.cpp b/lib/AST/StmtPrinter.cpp
index 651b88b5d3..3a44183e20 100644
--- a/lib/AST/StmtPrinter.cpp
+++ b/lib/AST/StmtPrinter.cpp
@@ -1108,52 +1108,34 @@ void StmtPrinter::VisitPseudoObjectExpr(PseudoObjectExpr *Node) {
void StmtPrinter::VisitAtomicExpr(AtomicExpr *Node) {
const char *Name = 0;
switch (Node->getOp()) {
- case AtomicExpr::Init:
- Name = "__c11_atomic_init(";
- break;
- case AtomicExpr::Load:
- Name = "__c11_atomic_load(";
- break;
- case AtomicExpr::Store:
- Name = "__c11_atomic_store(";
- break;
- case AtomicExpr::CmpXchgStrong:
- Name = "__c11_atomic_compare_exchange_strong(";
- break;
- case AtomicExpr::CmpXchgWeak:
- Name = "__c11_atomic_compare_exchange_weak(";
- break;
- case AtomicExpr::Xchg:
- Name = "__c11_atomic_exchange(";
- break;
- case AtomicExpr::Add:
- Name = "__c11_atomic_fetch_add(";
- break;
- case AtomicExpr::Sub:
- Name = "__c11_atomic_fetch_sub(";
- break;
- case AtomicExpr::And:
- Name = "__c11_atomic_fetch_and(";
- break;
- case AtomicExpr::Or:
- Name = "__c11_atomic_fetch_or(";
- break;
- case AtomicExpr::Xor:
- Name = "__c11_atomic_fetch_xor(";
- break;
+#define BUILTIN(ID, TYPE, ATTRS)
+#define ATOMIC_BUILTIN(ID, TYPE, ATTRS) \
+ case AtomicExpr::AO ## ID: \
+ Name = #ID "("; \
+ break;
+#include "clang/Basic/Builtins.def"
}
OS << Name;
+
+ // AtomicExpr stores its subexpressions in a permuted order.
PrintExpr(Node->getPtr());
OS << ", ";
- if (Node->getOp() != AtomicExpr::Load) {
+ if (Node->getOp() != AtomicExpr::AO__c11_atomic_load &&
+ Node->getOp() != AtomicExpr::AO__atomic_load_n) {
PrintExpr(Node->getVal1());
OS << ", ";
}
- if (Node->isCmpXChg()) {
+ if (Node->getOp() == AtomicExpr::AO__atomic_exchange ||
+ Node->isCmpXChg()) {
PrintExpr(Node->getVal2());
OS << ", ";
}
- if (Node->getOp() != AtomicExpr::Init)
+ if (Node->getOp() == AtomicExpr::AO__atomic_compare_exchange ||
+ Node->getOp() == AtomicExpr::AO__atomic_compare_exchange_n) {
+ PrintExpr(Node->getWeak());
+ OS << ", ";
+ }
+ if (Node->getOp() != AtomicExpr::AO__c11_atomic_init)
PrintExpr(Node->getOrder());
if (Node->isCmpXChg()) {
OS << ", ";