aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaType.cpp
diff options
context:
space:
mode:
authorEli Friedman <eli.friedman@gmail.com>2011-10-06 23:00:33 +0000
committerEli Friedman <eli.friedman@gmail.com>2011-10-06 23:00:33 +0000
commitb001de7458d17c17e6d8b8034c7cfcefd3b70c00 (patch)
tree22aafdcc75a1bc4984c7112800b87ece9b2f54c6 /lib/Sema/SemaType.cpp
parent5f22614327065a4ae78588eda8cb62f8b50502aa (diff)
Support for C1x _Atomic specifier (see testcase). This is primarily being committed at the moment to help support C++0x <atomic>, but it should be a solid base for implementing the full specification of C1x _Atomic.
Thanks to Jeffrey Yasskin for the thorough review! git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@141330 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaType.cpp')
-rw-r--r--lib/Sema/SemaType.cpp47
1 files changed, 47 insertions, 0 deletions
diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp
index 4a865bf235..995d767e2b 100644
--- a/lib/Sema/SemaType.cpp
+++ b/lib/Sema/SemaType.cpp
@@ -856,6 +856,16 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) {
Result = Context.UnknownAnyTy;
break;
+ case DeclSpec::TST_atomic:
+ Result = S.GetTypeFromParser(DS.getRepAsType());
+ assert(!Result.isNull() && "Didn't get a type for _Atomic?");
+ Result = S.BuildAtomicType(Result, DS.getTypeSpecTypeLoc());
+ if (Result.isNull()) {
+ Result = Context.IntTy;
+ declarator.setInvalidType(true);
+ }
+ break;
+
case DeclSpec::TST_error:
Result = Context.IntTy;
declarator.setInvalidType(true);
@@ -2872,6 +2882,10 @@ namespace {
void VisitTagTypeLoc(TagTypeLoc TL) {
TL.setNameLoc(DS.getTypeSpecTypeNameLoc());
}
+ void VisitAtomicTypeLoc(AtomicTypeLoc TL) {
+ TL.setKWLoc(DS.getTypeSpecTypeLoc());
+ TL.setParensRange(DS.getTypeofParensRange());
+ }
void VisitTypeLoc(TypeLoc TL) {
// FIXME: add other typespec types and change this to an assert.
@@ -4183,3 +4197,36 @@ QualType Sema::BuildUnaryTransformType(QualType BaseType,
}
llvm_unreachable("unknown unary transform type");
}
+
+QualType Sema::BuildAtomicType(QualType T, SourceLocation Loc) {
+ if (!T->isDependentType()) {
+ int DisallowedKind = -1;
+ if (T->isIncompleteType())
+ // FIXME: It isn't entirely clear whether incomplete atomic types
+ // are allowed or not; for simplicity, ban them for the moment.
+ DisallowedKind = 0;
+ else if (T->isArrayType())
+ DisallowedKind = 1;
+ else if (T->isFunctionType())
+ DisallowedKind = 2;
+ else if (T->isReferenceType())
+ DisallowedKind = 3;
+ else if (T->isAtomicType())
+ DisallowedKind = 4;
+ else if (T.hasQualifiers())
+ DisallowedKind = 5;
+ else if (!T.isTriviallyCopyableType(Context))
+ // Some other non-trivially-copyable type (probably a C++ class)
+ DisallowedKind = 6;
+
+ if (DisallowedKind != -1) {
+ Diag(Loc, diag::err_atomic_specifier_bad_type) << DisallowedKind << T;
+ return QualType();
+ }
+
+ // FIXME: Do we need any handling for ARC here?
+ }
+
+ // Build the pointer type.
+ return Context.getAtomicType(T);
+}