Is there a __has_feature() detection for it? Howard
On May 19, 2011, at 1:37 AM, Sean Hunt wrote: > Author: coppro > Date: Thu May 19 00:37:45 2011 > New Revision: 131633 > > URL: http://llvm.org/viewvc/llvm-project?rev=131633&view=rev > Log: > Implement __underlying_type for libc++. > > Modified: > 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/lib/Parse/ParseDecl.cpp > cfe/trunk/lib/Parse/ParseDeclCXX.cpp > cfe/trunk/lib/Parse/ParseExprCXX.cpp > cfe/trunk/lib/Parse/ParseTentative.cpp > cfe/trunk/lib/Sema/DeclSpec.cpp > cfe/trunk/lib/Sema/SemaDecl.cpp > cfe/trunk/lib/Sema/SemaTemplateVariadic.cpp > cfe/trunk/lib/Sema/SemaType.cpp > > Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=131633&r1=131632&r2=131633&view=diff > ============================================================================== > --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original) > +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Thu May 19 00:37:45 > 2011 > @@ -1015,6 +1015,10 @@ > "enumeration previously declared with %select{non|}0fixed underlying type">; > def err_enum_redeclare_scoped_mismatch : Error< > "enumeration previously declared as %select{un|}0scoped">; > +def err_only_enums_have_underlying_types : Error< > + "only enumeration types have underlying types">; > +def err_incomplete_type_no_underlying_type : Error< > + "an incomplete enumeration type has no underlying type yet">; > > // C++0x delegating constructors > def err_delegation_0x_only : Error< > > Modified: cfe/trunk/include/clang/Basic/Specifiers.h > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Specifiers.h?rev=131633&r1=131632&r2=131633&view=diff > ============================================================================== > --- cfe/trunk/include/clang/Basic/Specifiers.h (original) > +++ cfe/trunk/include/clang/Basic/Specifiers.h Thu May 19 00:37:45 2011 > @@ -54,6 +54,7 @@ > TST_typeofType, > TST_typeofExpr, > TST_decltype, // C++0x decltype > + TST_underlying_type, // __underlying_type for C++0x > TST_auto, // C++0x auto > TST_unknown_anytype, // __unknown_anytype extension > 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=131633&r1=131632&r2=131633&view=diff > ============================================================================== > --- cfe/trunk/include/clang/Basic/TokenKinds.def (original) > +++ cfe/trunk/include/clang/Basic/TokenKinds.def Thu May 19 00:37:45 2011 > @@ -348,6 +348,7 @@ > > // Clang-only C++ Type Traits > KEYWORD(__is_trivially_copyable , KEYCXX) > +KEYWORD(__underlying_type , KEYCXX) > > // Embarcadero Expression Traits > KEYWORD(__is_lvalue_expr , KEYCXX) > > Modified: cfe/trunk/include/clang/Parse/Parser.h > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=131633&r1=131632&r2=131633&view=diff > ============================================================================== > --- cfe/trunk/include/clang/Parse/Parser.h (original) > +++ cfe/trunk/include/clang/Parse/Parser.h Thu May 19 00:37:45 2011 > @@ -1648,6 +1648,7 @@ > > void ParseTypeofSpecifier(DeclSpec &DS); > void ParseDecltypeSpecifier(DeclSpec &DS); > + void ParseUnderlyingTypeSpecifier(DeclSpec &DS); > > ExprResult ParseCXX0XAlignArgument(SourceLocation Start); > > > Modified: cfe/trunk/include/clang/Sema/DeclSpec.h > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/DeclSpec.h?rev=131633&r1=131632&r2=131633&view=diff > ============================================================================== > --- cfe/trunk/include/clang/Sema/DeclSpec.h (original) > +++ cfe/trunk/include/clang/Sema/DeclSpec.h Thu May 19 00:37:45 2011 > @@ -249,6 +249,7 @@ > static const TST TST_typeofType = clang::TST_typeofType; > static const TST TST_typeofExpr = clang::TST_typeofExpr; > static const TST TST_decltype = clang::TST_decltype; > + static const TST TST_underlying_type = clang::TST_underlying_type; > static const TST TST_auto = clang::TST_auto; > static const TST TST_unknown_anytype = clang::TST_unknown_anytype; > static const TST TST_error = clang::TST_error; > @@ -344,7 +345,8 @@ > void SaveStorageSpecifierAsWritten(); > > static bool isTypeRep(TST T) { > - return (T == TST_typename || T == TST_typeofType); > + return (T == TST_typename || T == TST_typeofType || > + T == TST_underlying_type); > } > static bool isExprRep(TST T) { > return (T == TST_typeofExpr || T == TST_decltype); > > Modified: cfe/trunk/lib/Parse/ParseDecl.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=131633&r1=131632&r2=131633&view=diff > ============================================================================== > --- cfe/trunk/lib/Parse/ParseDecl.cpp (original) > +++ cfe/trunk/lib/Parse/ParseDecl.cpp Thu May 19 00:37:45 2011 > @@ -1859,6 +1859,9 @@ > ParseDecltypeSpecifier(DS); > continue; > > + case tok::kw___underlying_type: > + ParseUnderlyingTypeSpecifier(DS); > + > // OpenCL qualifiers: > case tok::kw_private: > if (!getLang().OpenCL) > @@ -2129,6 +2132,11 @@ > ParseDecltypeSpecifier(DS); > return true; > > + // C++0x type traits support. > + case tok::kw___underlying_type: > + ParseUnderlyingTypeSpecifier(DS); > + return true; > + > // OpenCL qualifiers: > case tok::kw_private: > if (!getLang().OpenCL) > > Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=131633&r1=131632&r2=131633&view=diff > ============================================================================== > --- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original) > +++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Thu May 19 00:37:45 2011 > @@ -572,6 +572,42 @@ > Diag(StartLoc, DiagID) << PrevSpec; > } > > +void Parser::ParseUnderlyingTypeSpecifier(DeclSpec &DS) { > + assert(Tok.is(tok::kw___underlying_type) && > + "Not an underlying type specifier"); > + > + SourceLocation StartLoc = ConsumeToken(); > + SourceLocation LParenLoc = Tok.getLocation(); > + > + if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after, > + "__underlying_type")) { > + 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; > + > + const char *PrevSpec = 0; > + unsigned DiagID; > + if (DS.SetTypeSpecType(DeclSpec::TST_underlying_type, StartLoc, PrevSpec, > + DiagID, Result.release())) > + Diag(StartLoc, DiagID) << PrevSpec; > +} > + > /// ParseClassName - Parse a C++ class-name, which names a class. Note > /// that we only check that the result names a type; semantic analysis > /// will need to verify that the type names a class. The result is > > Modified: cfe/trunk/lib/Parse/ParseExprCXX.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExprCXX.cpp?rev=131633&r1=131632&r2=131633&view=diff > ============================================================================== > --- cfe/trunk/lib/Parse/ParseExprCXX.cpp (original) > +++ cfe/trunk/lib/Parse/ParseExprCXX.cpp Thu May 19 00:37:45 2011 > @@ -962,6 +962,7 @@ > case tok::kw_bool: > case tok::kw_decltype: > case tok::kw_typeof: > + case tok::kw___underlying_type: > return true; > > default: > > Modified: cfe/trunk/lib/Parse/ParseTentative.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseTentative.cpp?rev=131633&r1=131632&r2=131633&view=diff > ============================================================================== > --- cfe/trunk/lib/Parse/ParseTentative.cpp (original) > +++ cfe/trunk/lib/Parse/ParseTentative.cpp Thu May 19 00:37:45 2011 > @@ -694,6 +694,7 @@ > case tok::kw_char16_t: > case tok::kw_char32_t: > case tok::kw_decltype: > + case tok::kw___underlying_type: > case tok::kw_thread_local: > case tok::kw__Decimal32: > case tok::kw__Decimal64: > @@ -1012,6 +1013,10 @@ > case tok::kw_decltype: > return TPResult::True(); > > + // C++0x type traits support > + case tok::kw___underlying_type: > + 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=131633&r1=131632&r2=131633&view=diff > ============================================================================== > --- cfe/trunk/lib/Sema/DeclSpec.cpp (original) > +++ cfe/trunk/lib/Sema/DeclSpec.cpp Thu May 19 00:37:45 2011 > @@ -309,6 +309,7 @@ > case DeclSpec::TST_typeofExpr: return "typeof"; > case DeclSpec::TST_auto: return "auto"; > case DeclSpec::TST_decltype: return "(decltype)"; > + case DeclSpec::TST_underlying_type: return "__underlying_type"; > case DeclSpec::TST_unknown_anytype: return "__unknown_anytype"; > case DeclSpec::TST_error: return "(error)"; > } > > Modified: cfe/trunk/lib/Sema/SemaDecl.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=131633&r1=131632&r2=131633&view=diff > ============================================================================== > --- cfe/trunk/lib/Sema/SemaDecl.cpp (original) > +++ cfe/trunk/lib/Sema/SemaDecl.cpp Thu May 19 00:37:45 2011 > @@ -2864,7 +2864,8 @@ > switch (DS.getTypeSpecType()) { > case DeclSpec::TST_typename: > case DeclSpec::TST_typeofType: > - case DeclSpec::TST_decltype: { > + case DeclSpec::TST_decltype: > + case DeclSpec::TST_underlying_type: { > // Grab the type from the parser. > TypeSourceInfo *TSI = 0; > QualType T = S.GetTypeFromParser(DS.getRepAsType(), &TSI); > > Modified: cfe/trunk/lib/Sema/SemaTemplateVariadic.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateVariadic.cpp?rev=131633&r1=131632&r2=131633&view=diff > ============================================================================== > --- cfe/trunk/lib/Sema/SemaTemplateVariadic.cpp (original) > +++ cfe/trunk/lib/Sema/SemaTemplateVariadic.cpp Thu May 19 00:37:45 2011 > @@ -617,7 +617,8 @@ > const DeclSpec &DS = D.getDeclSpec(); > switch (DS.getTypeSpecType()) { > case TST_typename: > - case TST_typeofType: { > + case TST_typeofType: > + case TST_underlying_type: { > 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=131633&r1=131632&r2=131633&view=diff > ============================================================================== > --- cfe/trunk/lib/Sema/SemaType.cpp (original) > +++ cfe/trunk/lib/Sema/SemaType.cpp Thu May 19 00:37:45 2011 > @@ -836,6 +836,29 @@ > } > break; > } > + case DeclSpec::TST_underlying_type: > + // FIXME: Preserve type source info? > + Result = S.GetTypeFromParser(DS.getRepAsType()); > + assert(!Result.isNull() && "Didn't get a type for __underlying_type?"); > + if (!Result->isDependentType()) { > + if (Result->isEnumeralType()) { > + EnumDecl *ED = Result->getAs<EnumType>()->getDecl(); > + S.DiagnoseUseOfDecl(ED, DS.getTypeSpecTypeLoc()); > + QualType UnderlyingType = ED->getIntegerType(); > + if (UnderlyingType.isNull()) { > + declarator.setInvalidType(true); > + Result = Context.IntTy; > + } else { > + Result = UnderlyingType; > + } > + } else { > + S.Diag(DS.getTypeSpecTypeLoc(), > + diag::err_only_enums_have_underlying_types); > + Result = Context.IntTy; > + } > + } > + break; > + > case DeclSpec::TST_auto: { > // TypeQuals handled by caller. > Result = Context.getAutoType(QualType()); > > > _______________________________________________ > cfe-commits mailing list > [email protected] > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
