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
diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp
index 7bd6fc2..eda7325 100644
--- a/lib/CodeGen/CGDebugInfo.cpp
+++ b/lib/CodeGen/CGDebugInfo.cpp
@@ -1423,6 +1423,13 @@
0, 0, Elements);
}
+llvm::DIType CGDebugInfo::CreateType(const AtomicType *Ty,
+ llvm::DIFile U) {
+ // Ignore the atomic wrapping
+ // FIXME: What is the correct representation?
+ return getOrCreateType(Ty->getValueType(), U);
+}
+
/// CreateEnumType - get enumeration type.
llvm::DIType CGDebugInfo::CreateEnumType(const EnumDecl *ED) {
llvm::DIFile Unit = getOrCreateFile(ED->getLocation());
@@ -1581,6 +1588,9 @@
case Type::MemberPointer:
return CreateType(cast<MemberPointerType>(Ty), Unit);
+ case Type::Atomic:
+ return CreateType(cast<AtomicType>(Ty), Unit);
+
case Type::Attributed:
case Type::TemplateSpecialization:
case Type::Elaborated:
diff --git a/lib/CodeGen/CGDebugInfo.h b/lib/CodeGen/CGDebugInfo.h
index 19d1ff3..68b3985 100644
--- a/lib/CodeGen/CGDebugInfo.h
+++ b/lib/CodeGen/CGDebugInfo.h
@@ -96,6 +96,7 @@
llvm::DIType CreateType(const LValueReferenceType *Ty, llvm::DIFile F);
llvm::DIType CreateType(const RValueReferenceType *Ty, llvm::DIFile Unit);
llvm::DIType CreateType(const MemberPointerType *Ty, llvm::DIFile F);
+ llvm::DIType CreateType(const AtomicType *Ty, llvm::DIFile F);
llvm::DIType CreateEnumType(const EnumDecl *ED);
llvm::DIType getOrCreateMethodType(const CXXMethodDecl *Method,
llvm::DIFile F);
diff --git a/lib/CodeGen/CGRTTI.cpp b/lib/CodeGen/CGRTTI.cpp
index a1105d2..2ad1ed3 100644
--- a/lib/CodeGen/CGRTTI.cpp
+++ b/lib/CodeGen/CGRTTI.cpp
@@ -404,6 +404,7 @@
case Type::Vector:
case Type::ExtVector:
case Type::Complex:
+ case Type::Atomic:
// FIXME: GCC treats block pointers as fundamental types?!
case Type::BlockPointer:
// abi::__fundamental_type_info.
@@ -656,6 +657,10 @@
case Type::MemberPointer:
BuildPointerToMemberTypeInfo(cast<MemberPointerType>(Ty));
break;
+
+ case Type::Atomic:
+ // No fields, at least for the moment.
+ break;
}
llvm::Constant *Init = llvm::ConstantStruct::getAnon(Fields);
diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp
index 12def67..2c6e7b0 100644
--- a/lib/CodeGen/CodeGenFunction.cpp
+++ b/lib/CodeGen/CodeGenFunction.cpp
@@ -87,6 +87,10 @@
case Type::ObjCObject:
case Type::ObjCInterface:
return true;
+
+ // In IRGen, atomic types are just the underlying type
+ case Type::Atomic:
+ return hasAggregateLLVMType(type->getAs<AtomicType>()->getValueType());
}
llvm_unreachable("unknown type kind!");
}
@@ -983,6 +987,10 @@
case Type::FunctionNoProto:
type = cast<FunctionType>(ty)->getResultType();
break;
+
+ case Type::Atomic:
+ type = cast<AtomicType>(ty)->getValueType();
+ break;
}
} while (type->isVariablyModifiedType());
}
diff --git a/lib/CodeGen/CodeGenTypes.cpp b/lib/CodeGen/CodeGenTypes.cpp
index 3032f82..61c1581 100644
--- a/lib/CodeGen/CodeGenTypes.cpp
+++ b/lib/CodeGen/CodeGenTypes.cpp
@@ -548,6 +548,11 @@
getCXXABI().ConvertMemberPointerType(cast<MemberPointerType>(Ty));
break;
}
+
+ case Type::Atomic: {
+ ResultType = ConvertTypeForMem(cast<AtomicType>(Ty)->getValueType());
+ break;
+ }
}
assert(ResultType && "Didn't convert a type?");