[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