[cfe-commits] r131633 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td include/clang/Basic/Specifiers.h include/clang/Basic/TokenKinds.def include/clang/Parse/Parser.h include/clang/Sema/DeclSpec.h lib/Parse/ParseDecl.cpp lib/Parse/ParseDeclCXX.cpp lib/Parse/ParseExprCXX.cpp lib/Parse/ParseTentative.cpp lib/Sema/DeclSpec.cpp lib/Sema/SemaDecl.cpp lib/Sema/SemaTemplateVariadic.cpp lib/Sema/SemaType.cpp

Howard Hinnant hhinnant at apple.com
Thu May 19 13:30:46 PDT 2011


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
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits




More information about the cfe-commits mailing list