diff options
Diffstat (limited to 'clang/lib/AST')
| -rw-r--r-- | clang/lib/AST/ASTContext.cpp | 57 | ||||
| -rw-r--r-- | clang/lib/AST/ASTImporter.cpp | 10 | ||||
| -rw-r--r-- | clang/lib/AST/ItaniumMangle.cpp | 8 | ||||
| -rw-r--r-- | clang/lib/AST/MicrosoftMangle.cpp | 4 | ||||
| -rw-r--r-- | clang/lib/AST/Type.cpp | 2 | ||||
| -rw-r--r-- | clang/lib/AST/TypePrinter.cpp | 11 |
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; |

