[cfe-commits] r141330 - in /cfe/trunk: include/clang/AST/ include/clang/Basic/ include/clang/Parse/ include/clang/Sema/ include/clang/Serialization/ lib/AST/ lib/CodeGen/ lib/Parse/ lib/Sema/ lib/Serialization/ test/Sema/ tools/libclang/
Douglas Gregor
dgregor at apple.com
Fri Oct 7 12:57:57 PDT 2011
On Oct 6, 2011, at 4:00 PM, Eli Friedman wrote:
> Author: efriedma
> Date: Thu Oct 6 18:00:33 2011
> New Revision: 141330
>
> URL: http://llvm.org/viewvc/llvm-project?rev=141330&view=rev
> Log:
> 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!
This looks great. My only request is that you add a PCH test to make sure we don't break _Atomic serialization/deserialization in the future.
- Doug
> Added:
> cfe/trunk/test/Sema/atomic-type.c
> Modified:
> cfe/trunk/include/clang/AST/ASTContext.h
> cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
> cfe/trunk/include/clang/AST/Type.h
> cfe/trunk/include/clang/AST/TypeLoc.h
> cfe/trunk/include/clang/AST/TypeNodes.def
> cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
> cfe/trunk/include/clang/Basic/Specifiers.h
> cfe/trunk/include/clang/Basic/TokenKinds.def
> cfe/trunk/include/clang/Parse/Parser.h
> cfe/trunk/include/clang/Sema/DeclSpec.h
> cfe/trunk/include/clang/Sema/Sema.h
> cfe/trunk/include/clang/Serialization/ASTBitCodes.h
> cfe/trunk/lib/AST/ASTContext.cpp
> cfe/trunk/lib/AST/ASTImporter.cpp
> cfe/trunk/lib/AST/ItaniumMangle.cpp
> cfe/trunk/lib/AST/MicrosoftMangle.cpp
> cfe/trunk/lib/AST/Type.cpp
> cfe/trunk/lib/AST/TypePrinter.cpp
> cfe/trunk/lib/CodeGen/CGDebugInfo.cpp
> cfe/trunk/lib/CodeGen/CGDebugInfo.h
> cfe/trunk/lib/CodeGen/CGRTTI.cpp
> cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
> cfe/trunk/lib/CodeGen/CodeGenTypes.cpp
> cfe/trunk/lib/Parse/ParseDecl.cpp
> cfe/trunk/lib/Parse/ParseTentative.cpp
> cfe/trunk/lib/Sema/DeclSpec.cpp
> cfe/trunk/lib/Sema/SemaDecl.cpp
> cfe/trunk/lib/Sema/SemaDeclCXX.cpp
> cfe/trunk/lib/Sema/SemaExpr.cpp
> cfe/trunk/lib/Sema/SemaLookup.cpp
> cfe/trunk/lib/Sema/SemaTemplate.cpp
> cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp
> cfe/trunk/lib/Sema/SemaTemplateVariadic.cpp
> cfe/trunk/lib/Sema/SemaType.cpp
> cfe/trunk/lib/Sema/TreeTransform.h
> cfe/trunk/lib/Serialization/ASTReader.cpp
> cfe/trunk/lib/Serialization/ASTWriter.cpp
> cfe/trunk/tools/libclang/CIndex.cpp
>
> Modified: cfe/trunk/include/clang/AST/ASTContext.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=141330&r1=141329&r2=141330&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/AST/ASTContext.h (original)
> +++ cfe/trunk/include/clang/AST/ASTContext.h Thu Oct 6 18:00:33 2011
> @@ -120,6 +120,7 @@
> mutable llvm::FoldingSet<ObjCObjectTypeImpl> ObjCObjectTypes;
> mutable llvm::FoldingSet<ObjCObjectPointerType> ObjCObjectPointerTypes;
> mutable llvm::FoldingSet<AutoType> AutoTypes;
> + mutable llvm::FoldingSet<AtomicType> AtomicTypes;
> llvm::FoldingSet<AttributedType> AttributedTypes;
>
> mutable llvm::FoldingSet<QualifiedTemplateName> QualifiedTemplateNames;
> @@ -601,6 +602,10 @@
> return CanQualType::CreateUnsafe(getPointerType((QualType) T));
> }
>
> + /// getAtomicType - Return the uniqued reference to the atomic type for
> + /// the specified type.
> + QualType getAtomicType(QualType T) const;
> +
> /// getBlockPointerType - Return the uniqued reference to the type for a block
> /// of the specified type.
> QualType getBlockPointerType(QualType T) const;
>
> Modified: cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/RecursiveASTVisitor.h?rev=141330&r1=141329&r2=141330&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/AST/RecursiveASTVisitor.h (original)
> +++ cfe/trunk/include/clang/AST/RecursiveASTVisitor.h Thu Oct 6 18:00:33 2011
> @@ -813,6 +813,10 @@
> TRY_TO(TraverseType(T->getPointeeType()));
> })
>
> +DEF_TRAVERSE_TYPE(AtomicType, {
> + TRY_TO(TraverseType(T->getValueType()));
> + })
> +
> #undef DEF_TRAVERSE_TYPE
>
> // ----------------- TypeLoc traversal -----------------
> @@ -1041,6 +1045,10 @@
> TRY_TO(TraverseTypeLoc(TL.getPointeeLoc()));
> })
>
> +DEF_TRAVERSE_TYPELOC(AtomicType, {
> + TRY_TO(TraverseTypeLoc(TL.getValueLoc()));
> + })
> +
> #undef DEF_TRAVERSE_TYPELOC
>
> // ----------------- Decl traversal -----------------
>
> Modified: cfe/trunk/include/clang/AST/Type.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=141330&r1=141329&r2=141330&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/AST/Type.h (original)
> +++ cfe/trunk/include/clang/AST/Type.h Thu Oct 6 18:00:33 2011
> @@ -1449,6 +1449,7 @@
> bool isCARCBridgableType() const;
> bool isTemplateTypeParmType() const; // C++ template type parameter
> bool isNullPtrType() const; // C++0x nullptr_t
> + bool isAtomicType() const; // C1X _Atomic()
>
> /// Determines if this type, which must satisfy
> /// isObjCLifetimeType(), is implicitly __unsafe_unretained rather
> @@ -4352,6 +4353,37 @@
> static bool classof(const ObjCObjectPointerType *) { return true; }
> };
>
> +class AtomicType : public Type, public llvm::FoldingSetNode {
> + QualType ValueType;
> +
> + AtomicType(QualType ValTy, QualType Canonical)
> + : Type(Atomic, Canonical, ValTy->isDependentType(),
> + ValTy->isInstantiationDependentType(),
> + ValTy->isVariablyModifiedType(),
> + ValTy->containsUnexpandedParameterPack()),
> + ValueType(ValTy) {}
> + friend class ASTContext; // ASTContext creates these.
> +
> + public:
> + /// getValueType - Gets the type contained by this atomic type, i.e.
> + /// the type returned by performing an atomic load of this atomic type.
> + QualType getValueType() const { return ValueType; }
> +
> + bool isSugared() const { return false; }
> + QualType desugar() const { return QualType(this, 0); }
> +
> + void Profile(llvm::FoldingSetNodeID &ID) {
> + Profile(ID, getValueType());
> + }
> + static void Profile(llvm::FoldingSetNodeID &ID, QualType T) {
> + ID.AddPointer(T.getAsOpaquePtr());
> + }
> + static bool classof(const Type *T) {
> + return T->getTypeClass() == Atomic;
> + }
> + static bool classof(const AtomicType *) { return true; }
> +};
> +
> /// A qualifier set is used to build a set of qualifiers.
> class QualifierCollector : public Qualifiers {
> public:
> @@ -4677,6 +4709,9 @@
> return isa<ObjCInterfaceType>(CanonicalType) ||
> isa<ObjCObjectType>(CanonicalType);
> }
> +inline bool Type::isAtomicType() const {
> + return isa<AtomicType>(CanonicalType);
> +}
>
> inline bool Type::isObjCQualifiedIdType() const {
> if (const ObjCObjectPointerType *OPT = getAs<ObjCObjectPointerType>())
>
> Modified: cfe/trunk/include/clang/AST/TypeLoc.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/TypeLoc.h?rev=141330&r1=141329&r2=141330&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/AST/TypeLoc.h (original)
> +++ cfe/trunk/include/clang/AST/TypeLoc.h Thu Oct 6 18:00:33 2011
> @@ -1730,6 +1730,62 @@
> }
> };
>
> +struct AtomicTypeLocInfo {
> + SourceLocation KWLoc, LParenLoc, RParenLoc;
> +};
> +
> +class AtomicTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, AtomicTypeLoc,
> + AtomicType, AtomicTypeLocInfo> {
> +public:
> + TypeLoc getValueLoc() const {
> + return this->getInnerTypeLoc();
> + }
> +
> + SourceRange getLocalSourceRange() const {
> + return SourceRange(getKWLoc(), getRParenLoc());
> + }
> +
> + SourceLocation getKWLoc() const {
> + return this->getLocalData()->KWLoc;
> + }
> + void setKWLoc(SourceLocation Loc) {
> + this->getLocalData()->KWLoc = Loc;
> + }
> +
> + SourceLocation getLParenLoc() const {
> + return this->getLocalData()->LParenLoc;
> + }
> + void setLParenLoc(SourceLocation Loc) {
> + this->getLocalData()->LParenLoc = Loc;
> + }
> +
> + SourceLocation getRParenLoc() const {
> + return this->getLocalData()->RParenLoc;
> + }
> + void setRParenLoc(SourceLocation Loc) {
> + this->getLocalData()->RParenLoc = Loc;
> + }
> +
> + SourceRange getParensRange() const {
> + return SourceRange(getLParenLoc(), getRParenLoc());
> + }
> + void setParensRange(SourceRange Range) {
> + setLParenLoc(Range.getBegin());
> + setRParenLoc(Range.getEnd());
> + }
> +
> + void initializeLocal(ASTContext &Context, SourceLocation Loc) {
> + setKWLoc(Loc);
> + setLParenLoc(Loc);
> + setRParenLoc(Loc);
> + }
> +
> + QualType getInnerType() const {
> + return this->getTypePtr()->getValueType();
> + }
> +};
> +
> +
> }
>
> #endif
>
> Modified: cfe/trunk/include/clang/AST/TypeNodes.def
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/TypeNodes.def?rev=141330&r1=141329&r2=141330&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/AST/TypeNodes.def (original)
> +++ cfe/trunk/include/clang/AST/TypeNodes.def Thu Oct 6 18:00:33 2011
> @@ -102,9 +102,10 @@
> TYPE(ObjCObject, Type)
> TYPE(ObjCInterface, ObjCObjectType)
> TYPE(ObjCObjectPointer, Type)
> +TYPE(Atomic, Type)
>
> #ifdef LAST_TYPE
> -LAST_TYPE(ObjCObjectPointer)
> +LAST_TYPE(Atomic)
> #undef LAST_TYPE
> #endif
>
>
> Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=141330&r1=141329&r2=141330&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
> +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Thu Oct 6 18:00:33 2011
> @@ -3073,6 +3073,10 @@
> "block with explicit return type requires argument list">;
> def err_func_def_incomplete_result : Error<
> "incomplete result type %0 in function definition">;
> +def err_atomic_specifier_bad_type : Error<
> + "_Atomic cannot be applied to "
> + "%select{incomplete |array |function |reference |atomic |qualified |}0type "
> + "%1 %select{||||||which is not trivially copyable}0">;
>
> // Expressions.
> def ext_sizeof_function_type : Extension<
>
> Modified: cfe/trunk/include/clang/Basic/Specifiers.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Specifiers.h?rev=141330&r1=141329&r2=141330&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/Basic/Specifiers.h (original)
> +++ cfe/trunk/include/clang/Basic/Specifiers.h Thu Oct 6 18:00:33 2011
> @@ -57,6 +57,7 @@
> TST_underlyingType, // __underlying_type for C++0x
> TST_auto, // C++0x auto
> TST_unknown_anytype, // __unknown_anytype extension
> + TST_atomic, // C1X _Atomic
> TST_error // erroneous type
> };
>
>
> Modified: cfe/trunk/include/clang/Basic/TokenKinds.def
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/TokenKinds.def?rev=141330&r1=141329&r2=141330&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/Basic/TokenKinds.def (original)
> +++ cfe/trunk/include/clang/Basic/TokenKinds.def Thu Oct 6 18:00:33 2011
> @@ -250,6 +250,7 @@
> KEYWORD(volatile , KEYALL)
> KEYWORD(while , KEYALL)
> KEYWORD(_Alignas , KEYALL)
> +KEYWORD(_Atomic , KEYALL)
> KEYWORD(_Bool , KEYNOCXX)
> KEYWORD(_Complex , KEYALL)
> KEYWORD(_Generic , KEYALL)
>
> Modified: cfe/trunk/include/clang/Parse/Parser.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=141330&r1=141329&r2=141330&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/Parse/Parser.h (original)
> +++ cfe/trunk/include/clang/Parse/Parser.h Thu Oct 6 18:00:33 2011
> @@ -1768,7 +1768,8 @@
> void ParseTypeofSpecifier(DeclSpec &DS);
> void ParseDecltypeSpecifier(DeclSpec &DS);
> void ParseUnderlyingTypeSpecifier(DeclSpec &DS);
> -
> + void ParseAtomicSpecifier(DeclSpec &DS);
> +
> ExprResult ParseAlignArgument(SourceLocation Start);
> void ParseAlignmentSpecifier(ParsedAttributes &Attrs,
> SourceLocation *endLoc = 0);
>
> Modified: cfe/trunk/include/clang/Sema/DeclSpec.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/DeclSpec.h?rev=141330&r1=141329&r2=141330&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/Sema/DeclSpec.h (original)
> +++ cfe/trunk/include/clang/Sema/DeclSpec.h Thu Oct 6 18:00:33 2011
> @@ -260,6 +260,7 @@
> static const TST TST_underlyingType = clang::TST_underlyingType;
> static const TST TST_auto = clang::TST_auto;
> static const TST TST_unknown_anytype = clang::TST_unknown_anytype;
> + static const TST TST_atomic = clang::TST_atomic;
> static const TST TST_error = clang::TST_error;
>
> // type-qualifiers
> @@ -356,7 +357,7 @@
>
> static bool isTypeRep(TST T) {
> return (T == TST_typename || T == TST_typeofType ||
> - T == TST_underlyingType);
> + T == TST_underlyingType || T == TST_atomic);
> }
> static bool isExprRep(TST T) {
> return (T == TST_typeofExpr || T == TST_decltype);
>
> Modified: cfe/trunk/include/clang/Sema/Sema.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=141330&r1=141329&r2=141330&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/Sema/Sema.h (original)
> +++ cfe/trunk/include/clang/Sema/Sema.h Thu Oct 6 18:00:33 2011
> @@ -793,6 +793,7 @@
> QualType BuildBlockPointerType(QualType T,
> SourceLocation Loc, DeclarationName Entity);
> QualType BuildParenType(QualType T);
> + QualType BuildAtomicType(QualType T, SourceLocation Loc);
>
> TypeSourceInfo *GetTypeForDeclarator(Declarator &D, Scope *S);
> TypeSourceInfo *GetTypeForDeclaratorCast(Declarator &D, QualType FromTy);
>
> Modified: cfe/trunk/include/clang/Serialization/ASTBitCodes.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTBitCodes.h?rev=141330&r1=141329&r2=141330&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/Serialization/ASTBitCodes.h (original)
> +++ cfe/trunk/include/clang/Serialization/ASTBitCodes.h Thu Oct 6 18:00:33 2011
> @@ -647,7 +647,9 @@
> /// \brief A AutoType record.
> TYPE_AUTO = 38,
> /// \brief A UnaryTransformType record.
> - TYPE_UNARY_TRANSFORM = 39
> + TYPE_UNARY_TRANSFORM = 39,
> + /// \brief An AtomicType record.
> + TYPE_ATOMIC = 40
> };
>
> /// \brief The type IDs for special types constructed by semantic
>
> Modified: cfe/trunk/lib/AST/ASTContext.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=141330&r1=141329&r2=141330&view=diff
> ==============================================================================
> --- cfe/trunk/lib/AST/ASTContext.cpp (original)
> +++ cfe/trunk/lib/AST/ASTContext.cpp Thu Oct 6 18:00:33 2011
> @@ -1063,6 +1063,11 @@
> 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 @@
> 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 @@
> 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 @@
> 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);
>
> Modified: cfe/trunk/lib/AST/ASTImporter.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=141330&r1=141329&r2=141330&view=diff
> ==============================================================================
> --- cfe/trunk/lib/AST/ASTImporter.cpp (original)
> +++ cfe/trunk/lib/AST/ASTImporter.cpp Thu Oct 6 18:00:33 2011
> @@ -810,7 +810,15 @@
> return false;
> break;
> }
> -
> +
> + case Type::Atomic: {
> + if (!IsStructurallyEquivalent(Context,
> + cast<AtomicType>(T1)->getValueType(),
> + cast<AtomicType>(T2)->getValueType()))
> + return false;
> + break;
> + }
> +
> } // end switch
>
> return true;
>
> Modified: cfe/trunk/lib/AST/ItaniumMangle.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ItaniumMangle.cpp?rev=141330&r1=141329&r2=141330&view=diff
> ==============================================================================
> --- cfe/trunk/lib/AST/ItaniumMangle.cpp (original)
> +++ cfe/trunk/lib/AST/ItaniumMangle.cpp Thu Oct 6 18:00:33 2011
> @@ -788,6 +788,7 @@
> 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 @@
> 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
>
> Modified: cfe/trunk/lib/AST/MicrosoftMangle.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/MicrosoftMangle.cpp?rev=141330&r1=141329&r2=141330&view=diff
> ==============================================================================
> --- cfe/trunk/lib/AST/MicrosoftMangle.cpp (original)
> +++ cfe/trunk/lib/AST/MicrosoftMangle.cpp Thu Oct 6 18:00:33 2011
> @@ -1113,6 +1113,10 @@
> 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)) &&
>
> Modified: cfe/trunk/lib/AST/Type.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Type.cpp?rev=141330&r1=141329&r2=141330&view=diff
> ==============================================================================
> --- cfe/trunk/lib/AST/Type.cpp (original)
> +++ cfe/trunk/lib/AST/Type.cpp Thu Oct 6 18:00:33 2011
> @@ -2113,6 +2113,8 @@
> 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");
>
> Modified: cfe/trunk/lib/AST/TypePrinter.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/TypePrinter.cpp?rev=141330&r1=141329&r2=141330&view=diff
> ==============================================================================
> --- cfe/trunk/lib/AST/TypePrinter.cpp (original)
> +++ cfe/trunk/lib/AST/TypePrinter.cpp Thu Oct 6 18:00:33 2011
> @@ -123,6 +123,7 @@
> case Type::DependentTemplateSpecialization:
> case Type::ObjCObject:
> case Type::ObjCInterface:
> + case Type::Atomic:
> CanPrefixQualifiers = true;
> break;
>
> @@ -581,6 +582,16 @@
> }
> }
>
> +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;
>
> Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.cpp?rev=141330&r1=141329&r2=141330&view=diff
> ==============================================================================
> --- cfe/trunk/lib/CodeGen/CGDebugInfo.cpp (original)
> +++ cfe/trunk/lib/CodeGen/CGDebugInfo.cpp Thu Oct 6 18:00:33 2011
> @@ -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:
>
> Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.h?rev=141330&r1=141329&r2=141330&view=diff
> ==============================================================================
> --- cfe/trunk/lib/CodeGen/CGDebugInfo.h (original)
> +++ cfe/trunk/lib/CodeGen/CGDebugInfo.h Thu Oct 6 18:00:33 2011
> @@ -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);
>
> Modified: cfe/trunk/lib/CodeGen/CGRTTI.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGRTTI.cpp?rev=141330&r1=141329&r2=141330&view=diff
> ==============================================================================
> --- cfe/trunk/lib/CodeGen/CGRTTI.cpp (original)
> +++ cfe/trunk/lib/CodeGen/CGRTTI.cpp Thu Oct 6 18:00:33 2011
> @@ -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);
>
> Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.cpp?rev=141330&r1=141329&r2=141330&view=diff
> ==============================================================================
> --- cfe/trunk/lib/CodeGen/CodeGenFunction.cpp (original)
> +++ cfe/trunk/lib/CodeGen/CodeGenFunction.cpp Thu Oct 6 18:00:33 2011
> @@ -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());
> }
>
> Modified: cfe/trunk/lib/CodeGen/CodeGenTypes.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenTypes.cpp?rev=141330&r1=141329&r2=141330&view=diff
> ==============================================================================
> --- cfe/trunk/lib/CodeGen/CodeGenTypes.cpp (original)
> +++ cfe/trunk/lib/CodeGen/CodeGenTypes.cpp Thu Oct 6 18:00:33 2011
> @@ -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?");
>
> Modified: cfe/trunk/lib/Parse/ParseDecl.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=141330&r1=141329&r2=141330&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Parse/ParseDecl.cpp (original)
> +++ cfe/trunk/lib/Parse/ParseDecl.cpp Thu Oct 6 18:00:33 2011
> @@ -2184,6 +2184,11 @@
>
> case tok::kw___underlying_type:
> ParseUnderlyingTypeSpecifier(DS);
> + continue;
> +
> + case tok::kw__Atomic:
> + ParseAtomicSpecifier(DS);
> + continue;
>
> // OpenCL qualifiers:
> case tok::kw_private:
> @@ -2460,6 +2465,10 @@
> ParseUnderlyingTypeSpecifier(DS);
> return true;
>
> + case tok::kw__Atomic:
> + ParseAtomicSpecifier(DS);
> + return true;
> +
> // OpenCL qualifiers:
> case tok::kw_private:
> if (!getLang().OpenCL)
> @@ -3219,6 +3228,10 @@
>
> case tok::kw_private:
> return getLang().OpenCL;
> +
> + // C1x _Atomic()
> + case tok::kw__Atomic:
> + return true;
> }
> }
>
> @@ -3338,6 +3351,10 @@
> case tok::kw_decltype:
> return true;
>
> + // C1x _Atomic()
> + case tok::kw__Atomic:
> + return true;
> +
> // GNU ObjC bizarre protocol extension: <proto1,proto2> with implicit 'id'.
> case tok::less:
> return getLang().ObjC1;
> @@ -4504,6 +4521,47 @@
> Diag(StartLoc, DiagID) << PrevSpec;
> }
>
> +/// [C1X] atomic-specifier:
> +/// _Atomic ( type-name )
> +///
> +void Parser::ParseAtomicSpecifier(DeclSpec &DS) {
> + assert(Tok.is(tok::kw__Atomic) && "Not an atomic specifier");
> +
> + SourceLocation StartLoc = ConsumeToken();
> + SourceLocation LParenLoc = Tok.getLocation();
> +
> + if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
> + "_Atomic")) {
> + SkipUntil(tok::r_paren);
> + return;
> + }
> +
> + TypeResult Result = ParseTypeName();
> + if (Result.isInvalid()) {
> + SkipUntil(tok::r_paren);
> + return;
> + }
> +
> + // Match the ')'
> + SourceLocation RParenLoc;
> + if (Tok.is(tok::r_paren))
> + RParenLoc = ConsumeParen();
> + else
> + MatchRHSPunctuation(tok::r_paren, LParenLoc);
> +
> + if (RParenLoc.isInvalid())
> + return;
> +
> + DS.setTypeofParensRange(SourceRange(LParenLoc, RParenLoc));
> + DS.SetRangeEnd(RParenLoc);
> +
> + const char *PrevSpec = 0;
> + unsigned DiagID;
> + if (DS.SetTypeSpecType(DeclSpec::TST_atomic, StartLoc, PrevSpec,
> + DiagID, Result.release()))
> + Diag(StartLoc, DiagID) << PrevSpec;
> +}
> +
>
> /// TryAltiVecVectorTokenOutOfLine - Out of line body that should only be called
> /// from TryAltiVecVectorToken.
>
> Modified: cfe/trunk/lib/Parse/ParseTentative.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseTentative.cpp?rev=141330&r1=141329&r2=141330&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Parse/ParseTentative.cpp (original)
> +++ cfe/trunk/lib/Parse/ParseTentative.cpp Thu Oct 6 18:00:33 2011
> @@ -719,6 +719,7 @@
> case tok::kw___unaligned:
> case tok::kw___vector:
> case tok::kw___pixel:
> + case tok::kw__Atomic:
> return TPResult::False();
>
> default:
> @@ -1033,6 +1034,10 @@
> case tok::kw___underlying_type:
> return TPResult::True();
>
> + // C1x _Atomic
> + case tok::kw__Atomic:
> + return TPResult::True();
> +
> default:
> return TPResult::False();
> }
>
> Modified: cfe/trunk/lib/Sema/DeclSpec.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/DeclSpec.cpp?rev=141330&r1=141329&r2=141330&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Sema/DeclSpec.cpp (original)
> +++ cfe/trunk/lib/Sema/DeclSpec.cpp Thu Oct 6 18:00:33 2011
> @@ -243,6 +243,7 @@
> }
>
> switch (DS.getTypeSpecType()) {
> + case TST_atomic:
> case TST_auto:
> case TST_bool:
> case TST_char:
> @@ -389,6 +390,7 @@
> case DeclSpec::TST_decltype: return "(decltype)";
> case DeclSpec::TST_underlyingType: return "__underlying_type";
> case DeclSpec::TST_unknown_anytype: return "__unknown_anytype";
> + case DeclSpec::TST_atomic: return "_Atomic";
> case DeclSpec::TST_error: return "(error)";
> }
> llvm_unreachable("Unknown typespec!");
>
> Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=141330&r1=141329&r2=141330&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaDecl.cpp Thu Oct 6 18:00:33 2011
> @@ -3011,7 +3011,8 @@
> case DeclSpec::TST_typename:
> case DeclSpec::TST_typeofType:
> case DeclSpec::TST_decltype:
> - case DeclSpec::TST_underlyingType: {
> + case DeclSpec::TST_underlyingType:
> + case DeclSpec::TST_atomic: {
> // Grab the type from the parser.
> TypeSourceInfo *TSI = 0;
> QualType T = S.GetTypeFromParser(DS.getRepAsType(), &TSI);
>
> Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=141330&r1=141329&r2=141330&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Thu Oct 6 18:00:33 2011
> @@ -3419,6 +3419,7 @@
> CheckPolymorphic(ReferenceTypeLoc)
> CheckPolymorphic(MemberPointerTypeLoc)
> CheckPolymorphic(BlockPointerTypeLoc)
> + CheckPolymorphic(AtomicTypeLoc)
>
> /// Handle all the types we haven't given a more specific
> /// implementation for above.
>
> Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=141330&r1=141329&r2=141330&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaExpr.cpp Thu Oct 6 18:00:33 2011
> @@ -342,6 +342,10 @@
> QualType T = E->getType();
> assert(!T.isNull() && "r-value conversion on typeless expression?");
>
> + // We can't do lvalue-to-rvalue on atomics yet.
> + if (T->getAs<AtomicType>())
> + return Owned(E);
> +
> // Create a load out of an ObjCProperty l-value, if necessary.
> if (E->getObjectKind() == OK_ObjCProperty) {
> ExprResult Res = ConvertPropertyForRValue(E);
> @@ -5393,6 +5397,10 @@
> LHSType = Context.getCanonicalType(LHSType).getUnqualifiedType();
> RHSType = Context.getCanonicalType(RHSType).getUnqualifiedType();
>
> + // We can't do assignment from/to atomics yet.
> + if (LHSType->isAtomicType())
> + return Incompatible;
> +
> // Common case: no conversion required.
> if (LHSType == RHSType) {
> Kind = CK_NoOp;
> @@ -5712,7 +5720,7 @@
> Sema::CheckSingleAssignmentConstraints(QualType LHSType, ExprResult &RHS,
> bool Diagnose) {
> if (getLangOptions().CPlusPlus) {
> - if (!LHSType->isRecordType()) {
> + if (!LHSType->isRecordType() && !LHSType->isAtomicType()) {
> // C++ 5.17p3: If the left operand is not of class type, the
> // expression is implicitly converted (C++ 4) to the
> // cv-unqualified type of the left operand.
> @@ -5732,6 +5740,8 @@
>
> // FIXME: Currently, we fall through and treat C++ classes like C
> // structures.
> + // FIXME: We also fall through for atomics; not sure what should
> + // happen there, though.
> }
>
> // C99 6.5.16.1p1: the left operand is a pointer and the right is
>
> Modified: cfe/trunk/lib/Sema/SemaLookup.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLookup.cpp?rev=141330&r1=141329&r2=141330&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaLookup.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaLookup.cpp Thu Oct 6 18:00:33 2011
> @@ -2000,6 +2000,12 @@
> case Type::ObjCObjectPointer:
> Result.Namespaces.insert(Result.S.Context.getTranslationUnitDecl());
> break;
> +
> + // Atomic types are just wrappers; use the associations of the
> + // contained type.
> + case Type::Atomic:
> + T = cast<AtomicType>(T)->getValueType().getTypePtr();
> + continue;
> }
>
> if (Queue.empty()) break;
>
> Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=141330&r1=141329&r2=141330&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaTemplate.cpp Thu Oct 6 18:00:33 2011
> @@ -3246,6 +3246,10 @@
> return false;
> }
>
> +bool UnnamedLocalNoLinkageFinder::VisitAtomicType(const AtomicType* T) {
> + return Visit(T->getValueType());
> +}
> +
> bool UnnamedLocalNoLinkageFinder::VisitTagDecl(const TagDecl *Tag) {
> if (Tag->getDeclContext()->isFunctionOrMethod()) {
> S.Diag(SR.getBegin(), diag::ext_template_arg_local_type)
>
> Modified: cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp?rev=141330&r1=141329&r2=141330&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp Thu Oct 6 18:00:33 2011
> @@ -1116,7 +1116,17 @@
> Info, Deduced, TDF);
>
> return Sema::TDK_NonDeducedMismatch;
> -
> +
> + // _Atomic T [extension]
> + case Type::Atomic:
> + if (const AtomicType *AtomicArg = Arg->getAs<AtomicType>())
> + return DeduceTemplateArguments(S, TemplateParams,
> + cast<AtomicType>(Param)->getValueType(),
> + AtomicArg->getValueType(),
> + Info, Deduced, TDF);
> +
> + return Sema::TDK_NonDeducedMismatch;
> +
> // T *
> case Type::Pointer: {
> QualType PointeeType;
> @@ -4126,6 +4136,13 @@
> OnlyDeduced, Depth, Used);
> break;
>
> + case Type::Atomic:
> + if (!OnlyDeduced)
> + MarkUsedTemplateParameters(SemaRef,
> + cast<AtomicType>(T)->getValueType(),
> + OnlyDeduced, Depth, Used);
> + break;
> +
> case Type::DependentName:
> if (!OnlyDeduced)
> MarkUsedTemplateParameters(SemaRef,
>
> Modified: cfe/trunk/lib/Sema/SemaTemplateVariadic.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateVariadic.cpp?rev=141330&r1=141329&r2=141330&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaTemplateVariadic.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaTemplateVariadic.cpp Thu Oct 6 18:00:33 2011
> @@ -619,7 +619,8 @@
> switch (DS.getTypeSpecType()) {
> case TST_typename:
> case TST_typeofType:
> - case TST_underlyingType: {
> + case TST_underlyingType:
> + case TST_atomic: {
> QualType T = DS.getRepAsType().get();
> if (!T.isNull() && T->containsUnexpandedParameterPack())
> return true;
>
> Modified: cfe/trunk/lib/Sema/SemaType.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=141330&r1=141329&r2=141330&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaType.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaType.cpp Thu Oct 6 18:00:33 2011
> @@ -856,6 +856,16 @@
> 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 @@
> 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 @@
> }
> 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);
> +}
>
> Modified: cfe/trunk/lib/Sema/TreeTransform.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=141330&r1=141329&r2=141330&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Sema/TreeTransform.h (original)
> +++ cfe/trunk/lib/Sema/TreeTransform.h Thu Oct 6 18:00:33 2011
> @@ -905,6 +905,12 @@
> NumExpansions);
> }
>
> + /// \brief Build a new atomic type given its value type.
> + ///
> + /// By default, performs semantic analysis when building the atomic type.
> + /// Subclasses may override this routine to provide different behavior.
> + QualType RebuildAtomicType(QualType ValueType, SourceLocation KWLoc);
> +
> /// \brief Build a new template name given a nested name specifier, a flag
> /// indicating whether the "template" keyword was provided, and the template
> /// that the template name refers to.
> @@ -4399,6 +4405,29 @@
> return getDerived().TransformTemplateSpecializationType(TLB, TL, Template);
> }
>
> +template<typename Derived>
> +QualType TreeTransform<Derived>::TransformAtomicType(TypeLocBuilder &TLB,
> + AtomicTypeLoc TL) {
> + QualType ValueType = getDerived().TransformType(TLB, TL.getValueLoc());
> + if (ValueType.isNull())
> + return QualType();
> +
> + QualType Result = TL.getType();
> + if (getDerived().AlwaysRebuild() ||
> + ValueType != TL.getValueLoc().getType()) {
> + Result = getDerived().RebuildAtomicType(ValueType, TL.getKWLoc());
> + if (Result.isNull())
> + return QualType();
> + }
> +
> + AtomicTypeLoc NewTL = TLB.push<AtomicTypeLoc>(Result);
> + NewTL.setKWLoc(TL.getKWLoc());
> + NewTL.setLParenLoc(TL.getLParenLoc());
> + NewTL.setRParenLoc(TL.getRParenLoc());
> +
> + return Result;
> +}
> +
> namespace {
> /// \brief Simple iterator that traverses the template arguments in a
> /// container that provides a \c getArgLoc() member function.
> @@ -8277,6 +8306,12 @@
> }
>
> template<typename Derived>
> +QualType TreeTransform<Derived>::RebuildAtomicType(QualType ValueType,
> + SourceLocation KWLoc) {
> + return SemaRef.BuildAtomicType(ValueType, KWLoc);
> +}
> +
> +template<typename Derived>
> TemplateName
> TreeTransform<Derived>::RebuildTemplateName(CXXScopeSpec &SS,
> bool TemplateKW,
>
> Modified: cfe/trunk/lib/Serialization/ASTReader.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=141330&r1=141329&r2=141330&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Serialization/ASTReader.cpp (original)
> +++ cfe/trunk/lib/Serialization/ASTReader.cpp Thu Oct 6 18:00:33 2011
> @@ -3526,6 +3526,15 @@
> const_cast<Type*>(T.getTypePtr())->setDependent(IsDependent);
> return T;
> }
> +
> + case TYPE_ATOMIC: {
> + if (Record.size() != 1) {
> + Error("Incorrect encoding of atomic type");
> + return QualType();
> + }
> + QualType ValueType = readType(*Loc.F, Record, Idx);
> + return Context.getAtomicType(ValueType);
> + }
> }
> // Suppress a GCC warning
> return QualType();
> @@ -3760,6 +3769,11 @@
> void TypeLocReader::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
> TL.setStarLoc(ReadSourceLocation(Record, Idx));
> }
> +void TypeLocReader::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
> + TL.setKWLoc(ReadSourceLocation(Record, Idx));
> + TL.setLParenLoc(ReadSourceLocation(Record, Idx));
> + TL.setRParenLoc(ReadSourceLocation(Record, Idx));
> +}
>
> TypeSourceInfo *ASTReader::GetTypeSourceInfo(Module &F,
> const RecordData &Record,
>
> Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=141330&r1=141329&r2=141330&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Serialization/ASTWriter.cpp (original)
> +++ cfe/trunk/lib/Serialization/ASTWriter.cpp Thu Oct 6 18:00:33 2011
> @@ -388,6 +388,12 @@
> Code = TYPE_OBJC_OBJECT_POINTER;
> }
>
> +void
> +ASTTypeWriter::VisitAtomicType(const AtomicType *T) {
> + Writer.AddTypeRef(T->getValueType(), Record);
> + Code = TYPE_ATOMIC;
> +}
> +
> namespace {
>
> class TypeLocWriter : public TypeLocVisitor<TypeLocWriter> {
> @@ -596,6 +602,11 @@
> void TypeLocWriter::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
> Writer.AddSourceLocation(TL.getStarLoc(), Record);
> }
> +void TypeLocWriter::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
> + Writer.AddSourceLocation(TL.getKWLoc(), Record);
> + Writer.AddSourceLocation(TL.getLParenLoc(), Record);
> + Writer.AddSourceLocation(TL.getRParenLoc(), Record);
> +}
>
> //===----------------------------------------------------------------------===//
> // ASTWriter Implementation
> @@ -840,6 +851,7 @@
> RECORD(TYPE_PACK_EXPANSION);
> RECORD(TYPE_ATTRIBUTED);
> RECORD(TYPE_SUBST_TEMPLATE_TYPE_PARM_PACK);
> + RECORD(TYPE_ATOMIC);
> RECORD(DECL_TYPEDEF);
> RECORD(DECL_ENUM);
> RECORD(DECL_RECORD);
>
> Added: cfe/trunk/test/Sema/atomic-type.c
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/atomic-type.c?rev=141330&view=auto
> ==============================================================================
> --- cfe/trunk/test/Sema/atomic-type.c (added)
> +++ cfe/trunk/test/Sema/atomic-type.c Thu Oct 6 18:00:33 2011
> @@ -0,0 +1,22 @@
> +// RUN: %clang_cc1 %s -verify -fsyntax-only
> +
> +// Basic parsing/Sema tests for _Atomic
> +// No operations are actually supported on objects of this type yet.
> +// The qualifier syntax is not supported yet.
> +_Atomic(int) t1;
> +_Atomic(int) *t2 = &t1;
> +void testf(void*);
> +void f(void) {
> + _Atomic(_Atomic(int)*) t3;
> + _Atomic(_Atomic(int)*) *t4[2] = { &t3, 0 };
> + testf(t4);
> +}
> +extern _Atomic(int (*)(int(*)[], int(*)[10])) mergetest;
> +extern _Atomic(int (*)(int(*)[10], int(*)[])) mergetest;
> +extern _Atomic(int (*)(int(*)[10], int(*)[10])) mergetest;
> +
> +_Atomic(int()) error1; // expected-error {{_Atomic cannot be applied to function type}}
> +_Atomic(struct ErrorS) error2; // expected-error {{_Atomic cannot be applied to incomplete type}}
> +_Atomic(int[10]) error3; // expected-error {{_Atomic cannot be applied to array type}}
> +_Atomic(const int) error4; // expected-error {{_Atomic cannot be applied to qualified type}}
> +_Atomic(_Atomic(int)) error5; // expected-error {{_Atomic cannot be applied to atomic type}}
>
> Modified: cfe/trunk/tools/libclang/CIndex.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndex.cpp?rev=141330&r1=141329&r2=141330&view=diff
> ==============================================================================
> --- cfe/trunk/tools/libclang/CIndex.cpp (original)
> +++ cfe/trunk/tools/libclang/CIndex.cpp Thu Oct 6 18:00:33 2011
> @@ -1561,6 +1561,10 @@
> return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
> }
>
> +bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
> + return Visit(TL.getValueLoc());
> +}
> +
> #define DEFAULT_TYPELOC_IMPL(CLASS, PARENT) \
> bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
> return Visit##PARENT##Loc(TL); \
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
More information about the cfe-commits
mailing list