summaryrefslogtreecommitdiffstats
path: root/clang/lib/AST
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/AST')
-rw-r--r--clang/lib/AST/ASTContext.cpp57
-rw-r--r--clang/lib/AST/ASTImporter.cpp10
-rw-r--r--clang/lib/AST/ItaniumMangle.cpp8
-rw-r--r--clang/lib/AST/MicrosoftMangle.cpp4
-rw-r--r--clang/lib/AST/Type.cpp2
-rw-r--r--clang/lib/AST/TypePrinter.cpp11
6 files changed, 91 insertions, 1 deletions
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 055ed7c08c6..3377799e3dd 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -1063,6 +1063,11 @@ ASTContext::getTypeInfo(const Type *T) const {
return getTypeInfo(getCanonicalType(T));
}
+ case Type::Atomic: {
+ // FIXME: The alignment needs to be "fixed".
+ return getTypeInfo(cast<AtomicType>(T)->getValueType());
+ }
+
}
assert(Align && (Align & (Align-1)) == 0 && "Alignment must be power of 2");
@@ -1707,6 +1712,12 @@ QualType ASTContext::getVariableArrayDecayedType(QualType type) const {
break;
}
+ case Type::Atomic: {
+ const AtomicType *at = cast<AtomicType>(ty);
+ result = getAtomicType(getVariableArrayDecayedType(at->getValueType()));
+ break;
+ }
+
case Type::ConstantArray: {
const ConstantArrayType *cat = cast<ConstantArrayType>(ty);
result = getConstantArrayType(
@@ -2904,6 +2915,34 @@ QualType ASTContext::getAutoType(QualType DeducedType) const {
return QualType(AT, 0);
}
+/// getAtomicType - Return the uniqued reference to the atomic type for
+/// the given value type.
+QualType ASTContext::getAtomicType(QualType T) const {
+ // Unique pointers, to guarantee there is only one pointer of a particular
+ // structure.
+ llvm::FoldingSetNodeID ID;
+ AtomicType::Profile(ID, T);
+
+ void *InsertPos = 0;
+ if (AtomicType *AT = AtomicTypes.FindNodeOrInsertPos(ID, InsertPos))
+ return QualType(AT, 0);
+
+ // If the atomic value type isn't canonical, this won't be a canonical type
+ // either, so fill in the canonical type field.
+ QualType Canonical;
+ if (!T.isCanonical()) {
+ Canonical = getAtomicType(getCanonicalType(T));
+
+ // Get the new insert position for the node we care about.
+ AtomicType *NewIP = AtomicTypes.FindNodeOrInsertPos(ID, InsertPos);
+ assert(NewIP == 0 && "Shouldn't be in the map!"); (void)NewIP;
+ }
+ AtomicType *New = new (*this, TypeAlignment) AtomicType(T, Canonical);
+ Types.push_back(New);
+ AtomicTypes.InsertNode(New, InsertPos);
+ return QualType(New, 0);
+}
+
/// getAutoDeductType - Get type pattern for deducing against 'auto'.
QualType ASTContext::getAutoDeductType() const {
if (AutoDeductTy.isNull())
@@ -5802,6 +5841,24 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS,
return RHS;
return getBlockPointerType(ResultType);
}
+ case Type::Atomic:
+ {
+ // Merge two pointer types, while trying to preserve typedef info
+ QualType LHSValue = LHS->getAs<AtomicType>()->getValueType();
+ QualType RHSValue = RHS->getAs<AtomicType>()->getValueType();
+ if (Unqualified) {
+ LHSValue = LHSValue.getUnqualifiedType();
+ RHSValue = RHSValue.getUnqualifiedType();
+ }
+ QualType ResultType = mergeTypes(LHSValue, RHSValue, false,
+ Unqualified);
+ if (ResultType.isNull()) return QualType();
+ if (getCanonicalType(LHSValue) == getCanonicalType(ResultType))
+ return LHS;
+ if (getCanonicalType(RHSValue) == getCanonicalType(ResultType))
+ return RHS;
+ return getAtomicType(ResultType);
+ }
case Type::ConstantArray:
{
const ConstantArrayType* LCAT = getAsConstantArrayType(LHS);
diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index e50dcbe4b00..e95d01a98fb 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -810,7 +810,15 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
return false;
break;
}
-
+
+ case Type::Atomic: {
+ if (!IsStructurallyEquivalent(Context,
+ cast<AtomicType>(T1)->getValueType(),
+ cast<AtomicType>(T2)->getValueType()))
+ return false;
+ break;
+ }
+
} // end switch
return true;
diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
index e94cb2d54bc..41cfa6ad01e 100644
--- a/clang/lib/AST/ItaniumMangle.cpp
+++ b/clang/lib/AST/ItaniumMangle.cpp
@@ -788,6 +788,7 @@ void CXXNameMangler::mangleUnresolvedPrefix(NestedNameSpecifier *qualifier,
case Type::ObjCObject:
case Type::ObjCInterface:
case Type::ObjCObjectPointer:
+ case Type::Atomic:
llvm_unreachable("type is illegal as a nested name specifier");
case Type::SubstTemplateTypeParmPack:
@@ -2111,6 +2112,13 @@ void CXXNameMangler::mangleType(const AutoType *T) {
mangleType(D);
}
+void CXXNameMangler::mangleType(const AtomicType *T) {
+ // <type> ::= U <source-name> <type> # vendor extended type qualifier
+ // (Until there's a standardized mangling...)
+ Out << "U7_Atomic";
+ mangleType(T->getValueType());
+}
+
void CXXNameMangler::mangleIntegerLiteral(QualType T,
const llvm::APSInt &Value) {
// <expr-primary> ::= L <type> <value number> E # integer literal
diff --git a/clang/lib/AST/MicrosoftMangle.cpp b/clang/lib/AST/MicrosoftMangle.cpp
index a5bfd7d318e..e327d8b180a 100644
--- a/clang/lib/AST/MicrosoftMangle.cpp
+++ b/clang/lib/AST/MicrosoftMangle.cpp
@@ -1113,6 +1113,10 @@ void MicrosoftCXXNameMangler::mangleType(const AutoType *T) {
llvm_unreachable("Don't know how to mangle AutoTypes yet!");
}
+void MicrosoftCXXNameMangler::mangleType(const AtomicType *T) {
+ llvm_unreachable("Don't know how to mangle AtomicTypes yet!");
+}
+
void MicrosoftMangleContext::mangleName(const NamedDecl *D,
raw_ostream &Out) {
assert((isa<FunctionDecl>(D) || isa<VarDecl>(D)) &&
diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index a2c6954d751..60cb3fa33e5 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -2113,6 +2113,8 @@ static CachedProperties computeCachedProperties(const Type *T) {
return Cache::get(cast<ObjCObjectType>(T)->getBaseType());
case Type::ObjCObjectPointer:
return Cache::get(cast<ObjCObjectPointerType>(T)->getPointeeType());
+ case Type::Atomic:
+ return Cache::get(cast<AtomicType>(T)->getValueType());
}
llvm_unreachable("unhandled type class");
diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp
index 855cc02d9e6..fb7b918ca2f 100644
--- a/clang/lib/AST/TypePrinter.cpp
+++ b/clang/lib/AST/TypePrinter.cpp
@@ -123,6 +123,7 @@ void TypePrinter::print(const Type *T, Qualifiers Quals, std::string &buffer) {
case Type::DependentTemplateSpecialization:
case Type::ObjCObject:
case Type::ObjCInterface:
+ case Type::Atomic:
CanPrefixQualifiers = true;
break;
@@ -581,6 +582,16 @@ void TypePrinter::printAuto(const AutoType *T, std::string &S) {
}
}
+void TypePrinter::printAtomic(const AtomicType *T, std::string &S) {
+ if (!S.empty())
+ S = ' ' + S;
+ std::string Str;
+ IncludeStrongLifetimeRAII Strong(Policy);
+ print(T->getValueType(), Str);
+
+ S = "_Atomic(" + Str + ")" + S;
+}
+
/// Appends the given scope to the end of a string.
void TypePrinter::AppendScope(DeclContext *DC, std::string &Buffer) {
if (DC->isTranslationUnit()) return;
OpenPOWER on IntegriCloud