[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

Sean Hunt scshunt at csclub.uwaterloo.ca
Wed May 18 22:37:45 PDT 2011


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());





More information about the cfe-commits mailing list