]> granicus.if.org Git - clang/commitdiff
Basic support for C++0x unicode types. Support for literals will follow in an increm...
authorAlisdair Meredith <public@alisdairm.net>
Tue, 14 Jul 2009 06:30:34 +0000 (06:30 +0000)
committerAlisdair Meredith <public@alisdairm.net>
Tue, 14 Jul 2009 06:30:34 +0000 (06:30 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@75622 91177308-0d34-0410-b5e6-96231b3b80d8

21 files changed:
include/clang/AST/ASTContext.h
include/clang/AST/Type.h
include/clang/Basic/TargetInfo.h
include/clang/Frontend/PCHBitCodes.h
include/clang/Frontend/TypeXML.def
include/clang/Parse/DeclSpec.h
lib/AST/ASTContext.cpp
lib/AST/Type.cpp
lib/Basic/TargetInfo.cpp
lib/CodeGen/CodeGenTypes.cpp
lib/CodeGen/Mangle.cpp
lib/Frontend/PCHReader.cpp
lib/Frontend/PCHWriter.cpp
lib/Lex/PPExpressions.cpp
lib/Parse/DeclSpec.cpp
lib/Parse/ParseDecl.cpp
lib/Parse/ParseExpr.cpp
lib/Parse/ParseExprCXX.cpp
lib/Parse/ParseTentative.cpp
lib/Sema/SemaOverload.cpp
lib/Sema/SemaType.cpp

index b13028d8f71b9f9eb6ec7feba550b16af1ce3745..56b3e6983349a83f5a6095d4dc0b5a9457c2f3fa 100644 (file)
@@ -198,7 +198,9 @@ public:
   QualType VoidTy;
   QualType BoolTy;
   QualType CharTy;
-  QualType WCharTy; // [C++ 3.9.1p5], integer type in C99.
+  QualType WCharTy;  // [C++ 3.9.1p5], integer type in C99.
+  QualType Char16Ty; // [C++0x 3.9.1p5], integer type in C99.
+  QualType Char32Ty; // [C++0x 3.9.1p5], integer type in C99.
   QualType SignedCharTy, ShortTy, IntTy, LongTy, LongLongTy, Int128Ty;
   QualType UnsignedCharTy, UnsignedShortTy, UnsignedIntTy, UnsignedLongTy;
   QualType UnsignedLongLongTy, UnsignedInt128Ty;
index 8634bb0bdc3e3d4b1bc6339f0235f164e4a469d1..d3f7b5be015e0c305e7a7938b2f6fcd1dcaf8beb 100644 (file)
@@ -567,6 +567,8 @@ public:
     Bool,     // This is bool and/or _Bool.
     Char_U,   // This is 'char' for targets where char is unsigned.
     UChar,    // This is explicitly qualified unsigned char.
+    Char16,   // This is 'char16_t' for C++.
+    Char32,   // This is 'char32_t' for C++.
     UShort,
     UInt,
     ULong,
index 537d553bc2d1a4097e2d48406dfd62959914eeb5..b1f9821d3121f86e70d72a1ed90567cd9b761350 100644 (file)
@@ -41,6 +41,8 @@ protected:
   bool TLSSupported;
   unsigned char PointerWidth, PointerAlign;
   unsigned char WCharWidth, WCharAlign;
+  unsigned char Char16Width, Char16Align;
+  unsigned char Char32Width, Char32Align;
   unsigned char IntWidth, IntAlign;
   unsigned char FloatWidth, FloatAlign;
   unsigned char DoubleWidth, DoubleAlign;
@@ -77,7 +79,7 @@ public:
   };
 protected:
   IntType SizeType, IntMaxType, UIntMaxType, PtrDiffType, IntPtrType, WCharType,
-          Int64Type;
+          Char16Type, Char32Type, Int64Type;
 public:
   IntType getSizeType() const { return SizeType; }
   IntType getIntMaxType() const { return IntMaxType; }
@@ -87,6 +89,8 @@ public:
   }
   IntType getIntPtrType() const { return IntPtrType; }
   IntType getWCharType() const { return WCharType; }
+  IntType getChar16Type() const { return Char16Type; }
+  IntType getChar32Type() const { return Char32Type; }
   IntType getInt64Type() const { return Int64Type; }
 
   /// getPointerWidth - Return the width of pointers on this target, for the
@@ -102,13 +106,9 @@ public:
   /// target, in bits.
   unsigned getBoolWidth(bool isWide = false) const { return 8; }  // FIXME
   unsigned getBoolAlign(bool isWide = false) const { return 8; }  // FIXME
-  
-  unsigned getCharWidth(bool isWide = false) const {
-    return isWide ? getWCharWidth() : 8; // FIXME
-  }
-  unsigned getCharAlign(bool isWide = false) const {
-    return isWide ? getWCharAlign() : 8; // FIXME
-  }
+  unsigned getCharWidth() const { return 8; } // FIXME
+  unsigned getCharAlign() const { return 8; } // FIXME
   
   /// getShortWidth/Align - Return the size of 'signed short' and
   /// 'unsigned short' for this target, in bits.  
@@ -130,11 +130,21 @@ public:
   unsigned getLongLongWidth() const { return LongLongWidth; }
   unsigned getLongLongAlign() const { return LongLongAlign; }
   
-  /// getWcharWidth/Align - Return the size of 'wchar_t' for this target, in
+  /// getWCharWidth/Align - Return the size of 'wchar_t' for this target, in
   /// bits.
   unsigned getWCharWidth() const { return WCharWidth; }
   unsigned getWCharAlign() const { return WCharAlign; }
 
+  /// getChar16Width/Align - Return the size of 'char16_t' for this target, in
+  /// bits.
+  unsigned getChar16Width() const { return Char16Width; }
+  unsigned getChar16Align() const { return Char16Align; }
+
+  /// getChar32Width/Align - Return the size of 'char32_t' for this target, in
+  /// bits.
+  unsigned getChar32Width() const { return Char32Width; }
+  unsigned getChar32Align() const { return Char32Align; }
+
   /// getFloatWidth/Align/Format - Return the size/align/format of 'float'.
   unsigned getFloatWidth() const { return FloatWidth; }
   unsigned getFloatAlign() const { return FloatAlign; }
index b6155431c3b0b82d9fec8481e0d16051809d05a3..a1feec3a6a8c49009e4bc608d940d56ae9f3ac29 100644 (file)
@@ -329,7 +329,11 @@ namespace clang {
       /// \brief The '__int128_t' type.
       PREDEF_TYPE_INT128_ID     = 22,
       /// \brief The type of 'nullptr'.
-      PREDEF_TYPE_NULLPTR_ID    = 23
+      PREDEF_TYPE_NULLPTR_ID    = 23,
+      /// \brief The C++ 'char16_t' type.
+      PREDEF_TYPE_CHAR16_ID     = 24,
+      /// \brief The C++ 'char32_t' type.
+      PREDEF_TYPE_CHAR32_ID     = 25
     };
 
     /// \brief The number of predefined type IDs that are reserved for
index 2a78fd9f75b1285907bc01f65cc34e67293a05c8..dd127388ddbb6138caa71e4c0f5d3703e28f428e 100644 (file)
@@ -104,6 +104,8 @@ NODE_XML(BuiltinType, "FundamentalType")
          ENUM_XML(BuiltinType::Double, "double");
          ENUM_XML(BuiltinType::LongDouble, "long double");
          ENUM_XML(BuiltinType::WChar, "wchar_t");
+         ENUM_XML(BuiltinType::Char16, "char16_t");
+         ENUM_XML(BuiltinType::Char32, "char32_t");
          ENUM_XML(BuiltinType::NullPtr, "nullptr_t");        // This is the type of C++0x 'nullptr'.
          ENUM_XML(BuiltinType::Overload, "overloaded");
          ENUM_XML(BuiltinType::Dependent, "dependent");
index 0c579152989179f4bdcd0e3053c6e7590c8f1cd6..b6044ff4c84714c60d0a675399a07dc8365a792b 100644 (file)
@@ -68,6 +68,8 @@ public:
     TST_void,
     TST_char,
     TST_wchar,        // C++ wchar_t
+    TST_char16,       // C++0x char16_t
+    TST_char32,       // C++0x char32_t
     TST_int,
     TST_float,
     TST_double,
index 5de66596e1d7d0ee5fabeeebb64909f8da973ef0..9d1e1267e45d0ca9d0f6c85c4fb0a0f233cc0a83 100644 (file)
@@ -170,6 +170,16 @@ void ASTContext::InitBuiltinTypes() {
   else // C99
     WCharTy = getFromTargetType(Target.getWCharType());
 
+  if (LangOpts.CPlusPlus) // C++0x 3.9.1p5, extension for C++
+    InitBuiltinType(Char16Ty,           BuiltinType::Char16);
+  else // C99
+    Char16Ty = getFromTargetType(Target.getChar16Type());
+
+  if (LangOpts.CPlusPlus) // C++0x 3.9.1p5, extension for C++
+    InitBuiltinType(Char32Ty,           BuiltinType::Char32);
+  else // C99
+    Char32Ty = getFromTargetType(Target.getChar32Type());
+
   // Placeholder type for functions.
   InitBuiltinType(OverloadTy,          BuiltinType::Overload);
 
@@ -522,6 +532,14 @@ ASTContext::getTypeInfo(const Type *T) {
       Width = Target.getWCharWidth();
       Align = Target.getWCharAlign();
       break;
+    case BuiltinType::Char16:
+      Width = Target.getChar16Width();
+      Align = Target.getChar16Align();
+      break;
+    case BuiltinType::Char32:
+      Width = Target.getChar32Width();
+      Align = Target.getChar32Align();
+      break;
     case BuiltinType::UShort:
     case BuiltinType::Short:
       Width = Target.getShortWidth();
@@ -2326,6 +2344,12 @@ unsigned ASTContext::getIntegerRank(Type *T) {
   if (T->isSpecificBuiltinType(BuiltinType::WChar))
     T = getFromTargetType(Target.getWCharType()).getTypePtr();
 
+  if (T->isSpecificBuiltinType(BuiltinType::Char16))
+    T = getFromTargetType(Target.getChar16Type()).getTypePtr();
+
+  if (T->isSpecificBuiltinType(BuiltinType::Char32))
+    T = getFromTargetType(Target.getChar32Type()).getTypePtr();
+
   // There are two things which impact the integer rank: the width, and
   // the ordering of builtins.  The builtin ordering is encoded in the
   // bottom three bits; the width is encoded in the bits above that.
index 7a9faac60f3414dc029b5ac3a45485aa877ba326..9edb9c046dee2c05718a439c3837c806e8307f57 100644 (file)
@@ -1003,6 +1003,8 @@ const char *BuiltinType::getName(const LangOptions &LO) const {
   case Double:            return "double";
   case LongDouble:        return "long double";
   case WChar:             return "wchar_t";
+  case Char16:            return "char16_t";
+  case Char32:            return "char32_t";
   case NullPtr:           return "nullptr_t";
   case Overload:          return "<overloaded function type>";
   case Dependent:         return "<dependent type>";
index ba7f190408b29bc9328d8bb6fa2f653a1bf02a72..5b2ffb7d165c79dcf8cbcfdea86e8b780043a888 100644 (file)
@@ -25,6 +25,8 @@ TargetInfo::TargetInfo(const std::string &T) : Triple(T) {
   TLSSupported = true;
   PointerWidth = PointerAlign = 32;
   WCharWidth = WCharAlign = 32;
+  Char16Width = Char16Align = 16;
+  Char32Width = Char32Align = 32;
   IntWidth = IntAlign = 32;
   LongWidth = LongAlign = 32;
   LongLongWidth = LongLongAlign = 64;
@@ -41,6 +43,8 @@ TargetInfo::TargetInfo(const std::string &T) : Triple(T) {
   UIntMaxType = UnsignedLongLong;
   IntPtrType = SignedLong;
   WCharType = SignedInt;
+  Char16Type = UnsignedShort;
+  Char32Type = UnsignedInt;
   Int64Type = SignedLongLong;
   FloatFormat = &llvm::APFloat::IEEEsingle;
   DoubleFormat = &llvm::APFloat::IEEEdouble;
index 6add2c25c7c99bd55bf8e4262060bcd3e331b155..5ed2b7c2a0931fa6dccb42393d741c3a1744c241 100644 (file)
@@ -249,6 +249,8 @@ const llvm::Type *CodeGenTypes::ConvertNewType(QualType T) {
     case BuiltinType::LongLong:
     case BuiltinType::ULongLong:
     case BuiltinType::WChar:
+    case BuiltinType::Char16:
+    case BuiltinType::Char32:
       return llvm::IntegerType::get(
         static_cast<unsigned>(Context.getTypeSize(T)));
       
index 97c26f87b18d4b57fd38e59e09b5b6b2265a2b01..cd0e2eae7dc8dd2f1e120e61e567de3c4c727919 100644 (file)
@@ -540,8 +540,8 @@ void CXXNameMangler::mangleType(const BuiltinType *T) {
   // UNSUPPORTED:    ::= De # IEEE 754r decimal floating point (128 bits)
   // UNSUPPORTED:    ::= Df # IEEE 754r decimal floating point (32 bits)
   // UNSUPPORTED:    ::= Dh # IEEE 754r half-precision floating point (16 bits)
-  // UNSUPPORTED:    ::= Di # char32_t
-  // UNSUPPORTED:    ::= Ds # char16_t
+  //                 ::= Di # char32_t
+  //                 ::= Ds # char16_t
   //                 ::= u <source-name>    # vendor extended type
   // From our point of view, std::nullptr_t is a builtin, but as far as mangling
   // is concerned, it's a type called std::nullptr_t.
@@ -557,6 +557,8 @@ void CXXNameMangler::mangleType(const BuiltinType *T) {
   case BuiltinType::UInt128: Out << 'o'; break;
   case BuiltinType::SChar: Out << 'a'; break;
   case BuiltinType::WChar: Out << 'w'; break;
+  case BuiltinType::Char16: Out << "Ds"; break;
+  case BuiltinType::Char32: Out << "Di"; break;
   case BuiltinType::Short: Out << 's'; break;
   case BuiltinType::Int: Out << 'i'; break;
   case BuiltinType::Long: Out << 'l'; break;
index c922b0d6db4f0d7bafe3022a952a23871c916a47..012c6fecfe3d88720639892255c653d6c8d7494d 100644 (file)
@@ -1984,6 +1984,8 @@ QualType PCHReader::GetType(pch::TypeID ID) {
     case pch::PREDEF_TYPE_OVERLOAD_ID:   T = Context->OverloadTy;         break;
     case pch::PREDEF_TYPE_DEPENDENT_ID:  T = Context->DependentTy;        break;
     case pch::PREDEF_TYPE_NULLPTR_ID:    T = Context->NullPtrTy;          break;
+    case pch::PREDEF_TYPE_CHAR16_ID:     T = Context->Char16Ty;           break;
+    case pch::PREDEF_TYPE_CHAR32_ID:     T = Context->Char32Ty;           break;
     }
 
     assert(!T.isNull() && "Unknown predefined type");
index 57577b7dfa2099d7eb0fa806a613bd4354c91a69..333bcc98935385b477b5e353c70fba8488dff1a7 100644 (file)
@@ -2005,6 +2005,8 @@ void PCHWriter::AddTypeRef(QualType T, RecordData &Record) {
     case BuiltinType::Double:     ID = pch::PREDEF_TYPE_DOUBLE_ID;     break;
     case BuiltinType::LongDouble: ID = pch::PREDEF_TYPE_LONGDOUBLE_ID; break;
     case BuiltinType::NullPtr:    ID = pch::PREDEF_TYPE_NULLPTR_ID;    break;
+    case BuiltinType::Char16:     ID = pch::PREDEF_TYPE_CHAR16_ID;     break;
+    case BuiltinType::Char32:     ID = pch::PREDEF_TYPE_CHAR32_ID;     break;
     case BuiltinType::Overload:   ID = pch::PREDEF_TYPE_OVERLOAD_ID;   break;
     case BuiltinType::Dependent:  ID = pch::PREDEF_TYPE_DEPENDENT_ID;  break;
     case BuiltinType::UndeducedAuto:
index c98acc4deb351bc95dd3ab5e91563921f10177b8..a7307c6b56eb43345bc56267f69f7b780f485adb 100644 (file)
@@ -224,8 +224,10 @@ static bool EvaluateValue(PPValue &Result, Token &PeekTok, DefinedTracker &DT,
     unsigned NumBits;
     if (Literal.isMultiChar())
       NumBits = TI.getIntWidth();
+    else if (Literal.isWide())
+      NumBits = TI.getWCharWidth();
     else
-      NumBits = TI.getCharWidth(Literal.isWide());
+      NumBits = TI.getCharWidth();
 
     // Set the width.
     llvm::APSInt Val(NumBits);
index 8b3b2851c1e0c008bd9a6ef6715200ab2678e567..e58076ee5a5d96bc0a1b57cd62bc2e29333598d8 100644 (file)
@@ -159,6 +159,8 @@ const char *DeclSpec::getSpecifierName(DeclSpec::TST T) {
   case DeclSpec::TST_void:        return "void";
   case DeclSpec::TST_char:        return "char";
   case DeclSpec::TST_wchar:       return "wchar_t";
+  case DeclSpec::TST_char16:      return "char16_t";
+  case DeclSpec::TST_char32:      return "char32_t";
   case DeclSpec::TST_int:         return "int";
   case DeclSpec::TST_float:       return "float";
   case DeclSpec::TST_double:      return "double";
index 94855b24f5ffcfe3db645a3580b5e2c37784ce4b..cefd325248a5f76b44c868494ff7ca2acd17de8b 100644 (file)
@@ -159,6 +159,8 @@ AttributeList *Parser::ParseAttributes(SourceLocation *EndLoc) {
             break;
           case tok::kw_char:
           case tok::kw_wchar_t:
+          case tok::kw_char16_t:
+          case tok::kw_char32_t:
           case tok::kw_bool:
           case tok::kw_short:
           case tok::kw_int:
@@ -999,6 +1001,12 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
     case tok::kw_wchar_t:
       isInvalid = DS.SetTypeSpecType(DeclSpec::TST_wchar, Loc, PrevSpec);
       break;
+    case tok::kw_char16_t:
+      isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char16, Loc, PrevSpec);
+      break;
+    case tok::kw_char32_t:
+      isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char32, Loc, PrevSpec);
+      break;
     case tok::kw_bool:
     case tok::kw__Bool:
       isInvalid = DS.SetTypeSpecType(DeclSpec::TST_bool, Loc, PrevSpec);
@@ -1226,6 +1234,12 @@ bool Parser::ParseOptionalTypeSpecifier(DeclSpec &DS, int& isInvalid,
   case tok::kw_wchar_t:
     isInvalid = DS.SetTypeSpecType(DeclSpec::TST_wchar, Loc, PrevSpec);
     break;
+  case tok::kw_char16_t:
+    isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char16, Loc, PrevSpec);
+    break;
+  case tok::kw_char32_t:
+    isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char32, Loc, PrevSpec);
+    break;
   case tok::kw_bool:
   case tok::kw__Bool:
     isInvalid = DS.SetTypeSpecType(DeclSpec::TST_bool, Loc, PrevSpec);
@@ -1714,6 +1728,8 @@ bool Parser::isTypeSpecifierQualifier() {
   case tok::kw_void:
   case tok::kw_char:
   case tok::kw_wchar_t:
+  case tok::kw_char16_t:
+  case tok::kw_char32_t:
   case tok::kw_int:
   case tok::kw_float:
   case tok::kw_double:
@@ -1802,6 +1818,9 @@ bool Parser::isDeclarationSpecifier() {
   case tok::kw_void:
   case tok::kw_char:
   case tok::kw_wchar_t:
+  case tok::kw_char16_t:
+  case tok::kw_char32_t:
+
   case tok::kw_int:
   case tok::kw_float:
   case tok::kw_double:
index cd7618f665367b088a14c4e027ee456ba72d03e4..c2086b9e1a962637f0a4bc507b9020e41e1f1cac 100644 (file)
@@ -739,6 +739,8 @@ Parser::OwningExprResult Parser::ParseCastExpression(bool isUnaryExpression,
 
   case tok::kw_char:
   case tok::kw_wchar_t:
+  case tok::kw_char16_t:
+  case tok::kw_char32_t:
   case tok::kw_bool:
   case tok::kw_short:
   case tok::kw_int:
index 1c00a8eabe806146119b24ce907a5032b5a9342d..68101fcdf4ea7c9fcc41cc409a5257b2b71b00ff 100644 (file)
@@ -654,6 +654,12 @@ void Parser::ParseCXXSimpleTypeSpecifier(DeclSpec &DS) {
   case tok::kw_wchar_t:
     DS.SetTypeSpecType(DeclSpec::TST_wchar, Loc, PrevSpec);
     break;
+  case tok::kw_char16_t:
+    DS.SetTypeSpecType(DeclSpec::TST_char16, Loc, PrevSpec);
+    break;
+  case tok::kw_char32_t:
+    DS.SetTypeSpecType(DeclSpec::TST_char32, Loc, PrevSpec);
+    break;
   case tok::kw_bool:
     DS.SetTypeSpecType(DeclSpec::TST_bool, Loc, PrevSpec);
     break;
index 02687a216c7d9dca683de538df98442fada9612a..97f6f526d4061cc740d05af09473d54ba34420fd 100644 (file)
@@ -681,6 +681,8 @@ Parser::TPResult Parser::isCXXDeclarationSpecifier() {
 
   case tok::kw_char:
   case tok::kw_wchar_t:
+  case tok::kw_char16_t:
+  case tok::kw_char32_t:
   case tok::kw_bool:
   case tok::kw_short:
   case tok::kw_int:
index b7f698eb0b5ea061d433892e514c424441e78673..bee3936048f020bb16816a881a694b10330a045b 100644 (file)
@@ -2792,7 +2792,8 @@ Sema::AddBuiltinOperatorCandidates(OverloadedOperatorKind Op,
                  LastPromotedArithmeticType = 16;
   const unsigned NumArithmeticTypes = 16;
   QualType ArithmeticTypes[NumArithmeticTypes] = {
-    Context.BoolTy, Context.CharTy, Context.WCharTy,
+    Context.BoolTy, Context.CharTy, Context.WCharTy, 
+//    Context.Char16Ty, Context.Char32Ty, 
     Context.SignedCharTy, Context.ShortTy,
     Context.UnsignedCharTy, Context.UnsignedShortTy,
     Context.IntTy, Context.LongTy, Context.LongLongTy,
index 7551d93c66be5eabd4217063381b1ded3d584e5c..8195aba967a2519b9fd14d3d449611df4efb5633 100644 (file)
@@ -88,6 +88,16 @@ QualType Sema::ConvertDeclSpecToType(const DeclSpec &DS,
       Result = Context.getUnsignedWCharType();
     }
     break;
+  case DeclSpec::TST_char16:
+      assert(DS.getTypeSpecSign() == DeclSpec::TSS_unspecified &&
+        "Unknown TSS value");
+      Result = Context.Char16Ty;
+    break;
+  case DeclSpec::TST_char32:
+      assert(DS.getTypeSpecSign() == DeclSpec::TSS_unspecified &&
+        "Unknown TSS value");
+      Result = Context.Char32Ty;
+    break;
   case DeclSpec::TST_unspecified:
     // "<proto1,proto2>" is an objc qualified ID with a missing id.
     if (DeclSpec::ProtocolQualifierListTy PQ = DS.getProtocolQualifiers()) {