On Mar 27, 2013, at 6:55 PM, Richard Smith <[email protected]> wrote: > Author: rsmith > Date: Wed Mar 27 20:55:44 2013 > New Revision: 178210 > > URL: http://llvm.org/viewvc/llvm-project?rev=178210&view=rev > Log: > Support C11 _Atomic type qualifier. This is more-or-less just syntactic sugar > for the _Atomic type specifier. > > Added: > cfe/trunk/test/Parser/atomic.c > Modified: > cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td > cfe/trunk/include/clang/Parse/Parser.h > cfe/trunk/include/clang/Sema/DeclSpec.h > cfe/trunk/include/clang/Sema/Sema.h > cfe/trunk/lib/Parse/ParseDecl.cpp > cfe/trunk/lib/Parse/ParseStmt.cpp > cfe/trunk/lib/Sema/DeclSpec.cpp > cfe/trunk/lib/Sema/SemaCodeComplete.cpp > cfe/trunk/lib/Sema/SemaDecl.cpp > cfe/trunk/lib/Sema/SemaType.cpp > cfe/trunk/test/Parser/asm.c > cfe/trunk/test/SemaCXX/atomic-type.cxx > > Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=178210&r1=178209&r2=178210&view=diff > ============================================================================== > --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original) > +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Wed Mar 27 20:55:44 > 2013 > @@ -1166,8 +1166,7 @@ def warn_cxx98_compat_static_data_member > def err_union_member_of_reference_type : Error< > "union member %0 has reference type %1">; > def ext_anonymous_struct_union_qualified : Extension< > - "anonymous %select{struct|union}0 cannot be '%select{const|volatile|" > - "restrict}1'">; > + "anonymous %select{struct|union}0 cannot be '%1'">; > def err_different_return_type_for_overriding_virtual_function : Error< > "virtual function %0 has a different return type " > "%diff{($) than the function it overrides (which has return type $)|" > > Modified: cfe/trunk/include/clang/Parse/Parser.h > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=178210&r1=178209&r2=178210&view=diff > ============================================================================== > --- cfe/trunk/include/clang/Parse/Parser.h (original) > +++ cfe/trunk/include/clang/Parse/Parser.h Wed Mar 27 20:55:44 2013 > @@ -1999,7 +1999,8 @@ private: > DirectDeclParseFunction DirectDeclParser); > > void ParseTypeQualifierListOpt(DeclSpec &DS, bool GNUAttributesAllowed = > true, > - bool CXX11AttributesAllowed = true); > + bool CXX11AttributesAllowed = true, > + bool AtomicAllowed = true); > void ParseDirectDeclarator(Declarator &D); > void ParseParenDeclarator(Declarator &D); > void ParseFunctionDeclarator(Declarator &D, > > Modified: cfe/trunk/include/clang/Sema/DeclSpec.h > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/DeclSpec.h?rev=178210&r1=178209&r2=178210&view=diff > ============================================================================== > --- cfe/trunk/include/clang/Sema/DeclSpec.h (original) > +++ cfe/trunk/include/clang/Sema/DeclSpec.h Wed Mar 27 20:55:44 2013 > @@ -291,7 +291,10 @@ public: > TQ_unspecified = 0, > TQ_const = 1, > TQ_restrict = 2, > - TQ_volatile = 4 > + TQ_volatile = 4, > + // This has no corresponding Qualifiers::TQ value, because it's not > treated > + // as a qualifier in our type system. > + TQ_atomic = 8 > }; > > /// ParsedSpecifiers - Flags to query which specifiers were applied. This > is > @@ -321,7 +324,7 @@ private: > unsigned TypeSpecOwned : 1; > > // type-qualifiers > - unsigned TypeQualifiers : 3; // Bitwise OR of TQ. > + unsigned TypeQualifiers : 4; // Bitwise OR of TQ. > > // function-specifier > unsigned FS_inline_specified : 1; > @@ -369,7 +372,7 @@ private: > /// TSTNameLoc provides source range info for tag types. > SourceLocation TSTNameLoc; > SourceRange TypeofParensRange; > - SourceLocation TQ_constLoc, TQ_restrictLoc, TQ_volatileLoc; > + SourceLocation TQ_constLoc, TQ_restrictLoc, TQ_volatileLoc, TQ_atomicLoc; > SourceLocation FS_inlineLoc, FS_virtualLoc, FS_explicitLoc, FS_noreturnLoc; > SourceLocation FriendLoc, ModulePrivateLoc, ConstexprLoc; > > @@ -503,6 +506,7 @@ public: > SourceLocation getConstSpecLoc() const { return TQ_constLoc; } > SourceLocation getRestrictSpecLoc() const { return TQ_restrictLoc; } > SourceLocation getVolatileSpecLoc() const { return TQ_volatileLoc; } > + SourceLocation getAtomicSpecLoc() const { return TQ_atomicLoc; } > > /// \brief Clear out all of the type qualifiers. > void ClearTypeQualifiers() { > @@ -510,6 +514,7 @@ public: > TQ_constLoc = SourceLocation(); > TQ_restrictLoc = SourceLocation(); > TQ_volatileLoc = SourceLocation(); > + TQ_atomicLoc = SourceLocation(); > } > > // function-specifier > @@ -1025,8 +1030,8 @@ struct DeclaratorChunk { > }; > > struct PointerTypeInfo : TypeInfoCommon { > - /// The type qualifiers: const/volatile/restrict. > - unsigned TypeQuals : 3; > + /// The type qualifiers: const/volatile/restrict/atomic. > + unsigned TypeQuals : 4; > > /// The location of the const-qualifier, if any. > unsigned ConstQualLoc; > @@ -1037,6 +1042,9 @@ struct DeclaratorChunk { > /// The location of the restrict-qualifier, if any. > unsigned RestrictQualLoc; > > + /// The location of the _Atomic-qualifier, if any. > + unsigned AtomicQualLoc; > + > void destroy() { > } > }; > @@ -1051,8 +1059,8 @@ struct DeclaratorChunk { > }; > > struct ArrayTypeInfo : TypeInfoCommon { > - /// The type qualifiers for the array: const/volatile/restrict. > - unsigned TypeQuals : 3; > + /// The type qualifiers for the array: const/volatile/restrict/_Atomic. > + unsigned TypeQuals : 4; > > /// True if this dimension included the 'static' keyword. > bool hasStatic : 1; > @@ -1274,16 +1282,16 @@ struct DeclaratorChunk { > > struct BlockPointerTypeInfo : TypeInfoCommon { > /// For now, sema will catch these as invalid. > - /// The type qualifiers: const/volatile/restrict. > - unsigned TypeQuals : 3; > + /// The type qualifiers: const/volatile/restrict/_Atomic. > + unsigned TypeQuals : 4; > > void destroy() { > } > }; > > struct MemberPointerTypeInfo : TypeInfoCommon { > - /// The type qualifiers: const/volatile/restrict. > - unsigned TypeQuals : 3; > + /// The type qualifiers: const/volatile/restrict/_Atomic. > + unsigned TypeQuals : 4; > // CXXScopeSpec has a constructor, so it can't be a direct member. > // So we need some pointer-aligned storage and a bit of trickery. > union { > > Modified: cfe/trunk/include/clang/Sema/Sema.h > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=178210&r1=178209&r2=178210&view=diff > ============================================================================== > --- cfe/trunk/include/clang/Sema/Sema.h (original) > +++ cfe/trunk/include/clang/Sema/Sema.h Wed Mar 27 20:55:44 2013 > @@ -936,10 +936,8 @@ public: > > QualType BuildQualifiedType(QualType T, SourceLocation Loc, Qualifiers Qs, > const DeclSpec *DS = 0); > - QualType BuildQualifiedType(QualType T, SourceLocation Loc, unsigned CVR, > - const DeclSpec *DS = 0) { > - return BuildQualifiedType(T, Loc, Qualifiers::fromCVRMask(CVR), DS); > - } > + QualType BuildQualifiedType(QualType T, SourceLocation Loc, unsigned CVRA, > + const DeclSpec *DS = 0); > QualType BuildPointerType(QualType T, > SourceLocation Loc, DeclarationName Entity); > QualType BuildReferenceType(QualType T, bool LValueRef, > > Modified: cfe/trunk/lib/Parse/ParseDecl.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=178210&r1=178209&r2=178210&view=diff > ============================================================================== > --- cfe/trunk/lib/Parse/ParseDecl.cpp (original) > +++ cfe/trunk/lib/Parse/ParseDecl.cpp Wed Mar 27 20:55:44 2013 > @@ -2905,8 +2905,17 @@ void Parser::ParseDeclarationSpecifiers( > continue; > > case tok::kw__Atomic: > - ParseAtomicSpecifier(DS); > - continue; > + // C11 6.7.2.4/4: > + // If the _Atomic keyword is immediately followed by a left > parenthesis, > + // it is interpreted as a type specifier (with a type name), not as a > + // type qualifier. > + if (NextToken().is(tok::l_paren)) { > + ParseAtomicSpecifier(DS); > + continue; > + } > + isInvalid = DS.SetTypeQual(DeclSpec::TQ_atomic, Loc, PrevSpec, DiagID, > + getLangOpts()); > + break; > > // OpenCL qualifiers: > case tok::kw_private: > @@ -3814,7 +3823,7 @@ bool Parser::isTypeSpecifierQualifier() > case tok::kw_private: > return getLangOpts().OpenCL; > > - // C11 _Atomic() > + // C11 _Atomic > case tok::kw__Atomic: > return true; > } > @@ -3959,7 +3968,7 @@ bool Parser::isDeclarationSpecifier(bool > case tok::annot_decltype: > case tok::kw_constexpr: > > - // C11 _Atomic() > + // C11 _Atomic > case tok::kw__Atomic: > return true; > > @@ -4099,7 +4108,8 @@ bool Parser::isConstructorDeclarator() { > /// > void Parser::ParseTypeQualifierListOpt(DeclSpec &DS, > bool VendorAttributesAllowed, > - bool CXX11AttributesAllowed) { > + bool CXX11AttributesAllowed, > + bool AtomicAllowed) { > if (getLangOpts().CPlusPlus11 && CXX11AttributesAllowed && > isCXX11AttributeSpecifier()) { > ParsedAttributesWithRange attrs(AttrFactory); > @@ -4132,6 +4142,12 @@ void Parser::ParseTypeQualifierListOpt(D > isInvalid = DS.SetTypeQual(DeclSpec::TQ_restrict, Loc, PrevSpec, DiagID, > getLangOpts()); > break; > + case tok::kw__Atomic: > + if (!AtomicAllowed) > + goto DoneWithTypeQuals; > + isInvalid = DS.SetTypeQual(DeclSpec::TQ_atomic, Loc, PrevSpec, DiagID, > + getLangOpts()); > + break; > > // OpenCL qualifiers: > case tok::kw_private: > @@ -4346,6 +4362,10 @@ void Parser::ParseDeclaratorInternal(Dec > if (DS.getTypeQualifiers() & DeclSpec::TQ_volatile) > Diag(DS.getVolatileSpecLoc(), > diag::err_invalid_reference_qualifier_application) << "volatile"; > + // 'restrict' is permitted as an extension. > + if (DS.getTypeQualifiers() & DeclSpec::TQ_atomic) > + Diag(DS.getAtomicSpecLoc(), > + diag::err_invalid_reference_qualifier_application) << "_Atomic"; > } > > // Recursively parse the declarator. > @@ -4368,7 +4388,7 @@ void Parser::ParseDeclaratorInternal(Dec > } > } > > - // Remember that we parsed a reference type. It doesn't have type-quals. > + // Remember that we parsed a reference type. > D.AddTypeInfo(DeclaratorChunk::getReference(DS.getTypeQualifiers(), Loc, > Kind == tok::amp), > DS.getAttributes(), > @@ -4809,7 +4829,9 @@ void Parser::ParseFunctionDeclarator(Dec > // with the virt-specifier-seq and pure-specifier in the same way. > > // Parse cv-qualifier-seq[opt]. > - ParseTypeQualifierListOpt(DS, false /*no attributes*/, false); > + ParseTypeQualifierListOpt(DS, /*VendorAttributesAllowed*/ false, > + /*CXX11AttributesAllowed*/ false, > + /*AtomicAllowed*/ false); > if (!DS.getSourceRange().getEnd().isInvalid()) { > EndLoc = DS.getSourceRange().getEnd(); > ConstQualifierLoc = DS.getConstSpecLoc(); > @@ -5350,14 +5372,13 @@ void Parser::ParseTypeofSpecifier(DeclSp > /// _Atomic ( type-name ) > /// > void Parser::ParseAtomicSpecifier(DeclSpec &DS) { > - assert(Tok.is(tok::kw__Atomic) && "Not an atomic specifier"); > + assert(Tok.is(tok::kw__Atomic) && NextToken().is(tok::l_paren) && > + "Not an atomic specifier"); > > SourceLocation StartLoc = ConsumeToken(); > BalancedDelimiterTracker T(*this, tok::l_paren); > - if (T.expectAndConsume(diag::err_expected_lparen_after, "_Atomic")) { > - SkipUntil(tok::r_paren); > + if (T.consumeOpen()) > return; > - } > > TypeResult Result = ParseTypeName(); > if (Result.isInvalid()) { > > Modified: cfe/trunk/lib/Parse/ParseStmt.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseStmt.cpp?rev=178210&r1=178209&r2=178210&view=diff > ============================================================================== > --- cfe/trunk/lib/Parse/ParseStmt.cpp (original) > +++ cfe/trunk/lib/Parse/ParseStmt.cpp Wed Mar 27 20:55:44 2013 > @@ -1810,6 +1810,9 @@ StmtResult Parser::ParseAsmStatement(boo > Diag(Loc, diag::w_asm_qualifier_ignored) << "const"; > if (DS.getTypeQualifiers() & DeclSpec::TQ_restrict) > Diag(Loc, diag::w_asm_qualifier_ignored) << "restrict"; > + // FIXME: Once GCC supports _Atomic, check whether it permits it here. > + if (DS.getTypeQualifiers() & DeclSpec::TQ_atomic) > + Diag(Loc, diag::w_asm_qualifier_ignored) << "_Atomic"; > > // Remember if this was a volatile asm. > bool isVolatile = DS.getTypeQualifiers() & DeclSpec::TQ_volatile; > > Modified: cfe/trunk/lib/Sema/DeclSpec.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/DeclSpec.cpp?rev=178210&r1=178209&r2=178210&view=diff > ============================================================================== > --- cfe/trunk/lib/Sema/DeclSpec.cpp (original) > +++ cfe/trunk/lib/Sema/DeclSpec.cpp Wed Mar 27 20:55:44 2013 > @@ -169,6 +169,9 @@ DeclaratorChunk DeclaratorChunk::getFunc > SourceLocation LocalRangeEnd, > Declarator &TheDeclarator, > TypeResult TrailingReturnType) { > + assert(!(TypeQuals & DeclSpec::TQ_atomic) && > + "function cannot have _Atomic qualifier"); > + > DeclaratorChunk I; > I.Kind = Function; > I.Loc = LocalRangeBegin; > @@ -442,6 +445,7 @@ const char *DeclSpec::getSpecifierName(T > case DeclSpec::TQ_const: return "const"; > case DeclSpec::TQ_restrict: return "restrict"; > case DeclSpec::TQ_volatile: return "volatile"; > + case DeclSpec::TQ_atomic: return "_Atomic"; > } > llvm_unreachable("Unknown typespec!"); > } > @@ -710,12 +714,14 @@ bool DeclSpec::SetTypeQual(TQ T, SourceL > TypeQualifiers |= T; > > switch (T) { > - default: llvm_unreachable("Unknown type qualifier!"); > - case TQ_const: TQ_constLoc = Loc; break; > - case TQ_restrict: TQ_restrictLoc = Loc; break; > - case TQ_volatile: TQ_volatileLoc = Loc; break; > + case TQ_unspecified: break; > + case TQ_const: TQ_constLoc = Loc; return false; > + case TQ_restrict: TQ_restrictLoc = Loc; return false; > + case TQ_volatile: TQ_volatileLoc = Loc; return false; > + case TQ_atomic: TQ_atomicLoc = Loc; return false; > } > - return false; > + > + llvm_unreachable("Unknown type qualifier!"); > } > > bool DeclSpec::setFunctionSpecInline(SourceLocation Loc) { > > Modified: cfe/trunk/lib/Sema/SemaCodeComplete.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCodeComplete.cpp?rev=178210&r1=178209&r2=178210&view=diff > ============================================================================== > --- cfe/trunk/lib/Sema/SemaCodeComplete.cpp (original) > +++ cfe/trunk/lib/Sema/SemaCodeComplete.cpp Wed Mar 27 20:55:44 2013 > @@ -3729,6 +3729,9 @@ void Sema::CodeCompleteTypeQualifiers(De > if (getLangOpts().C99 && > !(DS.getTypeQualifiers() & DeclSpec::TQ_restrict)) > Results.AddResult("restrict"); > + if (getLangOpts().C11 && > + !(DS.getTypeQualifiers() & DeclSpec::TQ_atomic)) > + Results.AddResult("_Atomic"); > Results.ExitScope(); > HandleCodeCompleteResults(this, CodeCompleter, > Results.getCompletionContext(), > > Modified: cfe/trunk/lib/Sema/SemaDecl.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=178210&r1=178209&r2=178210&view=diff > ============================================================================== > --- cfe/trunk/lib/Sema/SemaDecl.cpp (original) > +++ cfe/trunk/lib/Sema/SemaDecl.cpp Wed Mar 27 20:55:44 2013 > @@ -3175,6 +3175,8 @@ Decl *Sema::ParsedFreeStandingDeclSpec(S > if (DS.getTypeQualifiers() & DeclSpec::TQ_volatile) > Diag(DS.getConstSpecLoc(), DiagID) << "volatile"; > // Restrict is covered above. > + if (DS.getTypeQualifiers() & DeclSpec::TQ_atomic) > + Diag(DS.getAtomicSpecLoc(), DiagID) << "_Atomic"; > } > > // Warn about ignored type attributes, for example: > @@ -3411,18 +3413,23 @@ Decl *Sema::BuildAnonymousStructOrUnion( > if (DS.getTypeQualifiers()) { > if (DS.getTypeQualifiers() & DeclSpec::TQ_const) > Diag(DS.getConstSpecLoc(), diag::ext_anonymous_struct_union_qualified) > - << Record->isUnion() << 0 > + << Record->isUnion() << "const" > << FixItHint::CreateRemoval(DS.getConstSpecLoc()); > if (DS.getTypeQualifiers() & DeclSpec::TQ_volatile) > - Diag(DS.getVolatileSpecLoc(), > + Diag(DS.getVolatileSpecLoc(), > diag::ext_anonymous_struct_union_qualified) > - << Record->isUnion() << 1 > + << Record->isUnion() << "volatile" > << FixItHint::CreateRemoval(DS.getVolatileSpecLoc()); > if (DS.getTypeQualifiers() & DeclSpec::TQ_restrict) > - Diag(DS.getRestrictSpecLoc(), > + Diag(DS.getRestrictSpecLoc(), > diag::ext_anonymous_struct_union_qualified) > - << Record->isUnion() << 2 > + << Record->isUnion() << "restrict" > << FixItHint::CreateRemoval(DS.getRestrictSpecLoc()); > + if (DS.getTypeQualifiers() & DeclSpec::TQ_atomic) > + Diag(DS.getAtomicSpecLoc(), > + diag::ext_anonymous_struct_union_qualified) > + << Record->isUnion() << "_Atomic" > + << FixItHint::CreateRemoval(DS.getAtomicSpecLoc()); > > DS.ClearTypeQualifiers(); > } > > Modified: cfe/trunk/lib/Sema/SemaType.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=178210&r1=178209&r2=178210&view=diff > ============================================================================== > --- cfe/trunk/lib/Sema/SemaType.cpp (original) > +++ cfe/trunk/lib/Sema/SemaType.cpp Wed Mar 27 20:55:44 2013 > @@ -1089,21 +1089,18 @@ static QualType ConvertDeclSpecToType(Ty > // of a function type includes any type qualifiers, the behavior is > // undefined." > if (Result->isFunctionType() && TypeQuals) { > - // Get some location to point at, either the C or V location. > - SourceLocation Loc; > if (TypeQuals & DeclSpec::TQ_const) > - Loc = DS.getConstSpecLoc(); > + S.Diag(DS.getConstSpecLoc(), > diag::warn_typecheck_function_qualifiers) > + << Result << DS.getSourceRange(); > else if (TypeQuals & DeclSpec::TQ_volatile) > - Loc = DS.getVolatileSpecLoc(); > + S.Diag(DS.getVolatileSpecLoc(), > diag::warn_typecheck_function_qualifiers) > + << Result << DS.getSourceRange(); > else { > - assert((TypeQuals & DeclSpec::TQ_restrict) && > - "Has CVR quals but not C, V, or R?"); > - // No diagnostic; we'll diagnose 'restrict' applied to a function > type > - // later, in BuildQualifiedType. > + assert((TypeQuals & (DeclSpec::TQ_restrict | DeclSpec::TQ_atomic)) && > + "Has CVRA quals but not C, V, R, or A?"); > + // No diagnostic; we'll diagnose 'restrict' or '_Atomic' applied to a > + // function type later, in BuildQualifiedType. > } > - if (!Loc.isInvalid()) > - S.Diag(Loc, diag::warn_typecheck_function_qualifiers) > - << Result << DS.getSourceRange(); > } > > // C++ [dcl.ref]p1: > @@ -1116,6 +1113,7 @@ static QualType ConvertDeclSpecToType(Ty > TypeQuals && Result->isReferenceType()) { > TypeQuals &= ~DeclSpec::TQ_const; > TypeQuals &= ~DeclSpec::TQ_volatile; > + TypeQuals &= ~DeclSpec::TQ_atomic; > } > > // C90 6.5.3 constraints: "The same type qualifier shall not appear more > @@ -1133,11 +1131,17 @@ static QualType ConvertDeclSpecToType(Ty > << "volatile"; > } > > - // C90 doesn't have restrict, so it doesn't force us to produce a > warning > - // in this case. > + // C90 doesn't have restrict nor _Atomic, so it doesn't force us to > + // produce a warning in this case. > } > > - return S.BuildQualifiedType(Result, DeclLoc, TypeQuals, &DS); > + QualType Qualified = S.BuildQualifiedType(Result, DeclLoc, TypeQuals, > &DS); > + > + // If adding qualifiers fails, just use the unqualified type. > + if (Qualified.isNull()) > + declarator.setInvalidType(true); > + else > + Result = Qualified; > } > > return Result; > @@ -1188,6 +1192,39 @@ QualType Sema::BuildQualifiedType(QualTy > return Context.getQualifiedType(T, Qs); > } > > +QualType Sema::BuildQualifiedType(QualType T, SourceLocation Loc, > + unsigned CVRA, const DeclSpec *DS) { > + // Convert from DeclSpec::TQ to Qualifiers::TQ by just dropping TQ_atomic. > + unsigned CVR = CVRA & ~DeclSpec::TQ_atomic; > + > + // C11 6.7.3/5: > + // If the same qualifier appears more than once in the same > + // specifier-qualifier-list, either directly or via one or more typedefs, > + // the behavior is the same as if it appeared only once. > + // > + // It's not specified what happens when the _Atomic qualifier is applied to > + // a type specified with the _Atomic specifier, but we assume that this > + // should be treated as if the _Atomic qualifier appeared multiple times. > + if (CVRA & DeclSpec::TQ_atomic && !T->isAtomicType()) { > + // C11 6.7.3/5: > + // If other qualifiers appear along with the _Atomic qualifier in a > + // specifier-qualifier-list, the resulting type is the so-qualified > + // atomic type. > + // > + // Don't need to worry about array types here, since _Atomic can't be > + // applied to such types. > + SplitQualType Split = T.getSplitUnqualifiedType(); > + T = BuildAtomicType(QualType(Split.Ty, 0), > + DS ? DS->getAtomicSpecLoc() : Loc);
Won't this silently reinterpret the following so that 'x' has type 'const _Atomic(int)'? Are you sure that's intended behavior? typedef const int cint; _Atomic cint x; John. _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
