r331244 - Implement P0482R2, support for char8_t type.

Richard Smith via cfe-commits cfe-commits at lists.llvm.org
Tue May 1 11:53:46 PDT 2018


On 1 May 2018 at 08:55, David Majnemer via cfe-commits <
cfe-commits at lists.llvm.org> wrote:

> On Mon, Apr 30, 2018 at 10:02 PM, Richard Smith via cfe-commits <
> cfe-commits at lists.llvm.org> wrote:
>
>> Author: rsmith
>> Date: Mon Apr 30 22:02:45 2018
>> New Revision: 331244
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=331244&view=rev
>> Log:
>> Implement P0482R2, support for char8_t type.
>>
>> This is not yet part of any C++ working draft, and so is controlled by
>> the flag
>> -fchar8_t rather than a -std= flag. (The GCC implementation is controlled
>> by a
>> flag with the same name.)
>>
>> This implementation is experimental, and will be removed or revised
>> substantially to match the proposal as it makes its way through the C++
>> committee.
>>
>> Added:
>>     cfe/trunk/test/CodeGenCXX/char8_t.cpp
>>     cfe/trunk/test/Lexer/char8_t.cpp
>>     cfe/trunk/test/SemaCXX/char8_t.cpp
>> Modified:
>>     cfe/trunk/include/clang/AST/ASTContext.h
>>     cfe/trunk/include/clang/AST/BuiltinTypes.def
>>     cfe/trunk/include/clang/AST/Type.h
>>     cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
>>     cfe/trunk/include/clang/Basic/LangOptions.def
>>     cfe/trunk/include/clang/Basic/Specifiers.h
>>     cfe/trunk/include/clang/Basic/TokenKinds.def
>>     cfe/trunk/include/clang/Driver/Options.td
>>     cfe/trunk/include/clang/Sema/DeclSpec.h
>>     cfe/trunk/include/clang/Sema/Initialization.h
>>     cfe/trunk/include/clang/Serialization/ASTBitCodes.h
>>     cfe/trunk/lib/AST/ASTContext.cpp
>>     cfe/trunk/lib/AST/ExprConstant.cpp
>>     cfe/trunk/lib/AST/ItaniumMangle.cpp
>>     cfe/trunk/lib/AST/MicrosoftMangle.cpp
>>     cfe/trunk/lib/AST/NSAPI.cpp
>>     cfe/trunk/lib/AST/Type.cpp
>>     cfe/trunk/lib/AST/TypeLoc.cpp
>>     cfe/trunk/lib/Analysis/PrintfFormatString.cpp
>>     cfe/trunk/lib/Basic/IdentifierTable.cpp
>>     cfe/trunk/lib/CodeGen/CGDebugInfo.cpp
>>     cfe/trunk/lib/CodeGen/CodeGenTypes.cpp
>>     cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp
>>     cfe/trunk/lib/Driver/ToolChains/Clang.cpp
>>     cfe/trunk/lib/Format/FormatToken.cpp
>>     cfe/trunk/lib/Frontend/CompilerInvocation.cpp
>>     cfe/trunk/lib/Frontend/InitPreprocessor.cpp
>>     cfe/trunk/lib/Index/USRGeneration.cpp
>>     cfe/trunk/lib/Lex/PPExpressions.cpp
>>     cfe/trunk/lib/Parse/ParseDecl.cpp
>>     cfe/trunk/lib/Parse/ParseExpr.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/SemaDeclCXX.cpp
>>     cfe/trunk/lib/Sema/SemaExpr.cpp
>>     cfe/trunk/lib/Sema/SemaInit.cpp
>>     cfe/trunk/lib/Sema/SemaOverload.cpp
>>     cfe/trunk/lib/Sema/SemaTemplate.cpp
>>     cfe/trunk/lib/Sema/SemaTemplateVariadic.cpp
>>     cfe/trunk/lib/Sema/SemaType.cpp
>>     cfe/trunk/lib/Serialization/ASTCommon.cpp
>>     cfe/trunk/lib/Serialization/ASTReader.cpp
>>     cfe/trunk/test/Lexer/cxx-features.cpp
>>
>> Modified: cfe/trunk/include/clang/AST/ASTContext.h
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/
>> AST/ASTContext.h?rev=331244&r1=331243&r2=331244&view=diff
>> ============================================================
>> ==================
>> --- cfe/trunk/include/clang/AST/ASTContext.h (original)
>> +++ cfe/trunk/include/clang/AST/ASTContext.h Mon Apr 30 22:02:45 2018
>> @@ -999,6 +999,7 @@ public:
>>    CanQualType WCharTy;  // [C++ 3.9.1p5].
>>    CanQualType WideCharTy; // Same as WCharTy in C++, integer type in C99.
>>    CanQualType WIntTy;   // [C99 7.24.1], integer type unchanged by
>> default promotions.
>> +  CanQualType Char8Ty;  // [C++20 proposal]
>>    CanQualType Char16Ty; // [C++0x 3.9.1p5], integer type in C99.
>>    CanQualType Char32Ty; // [C++0x 3.9.1p5], integer type in C99.
>>    CanQualType SignedCharTy, ShortTy, IntTy, LongTy, LongLongTy, Int128Ty;
>>
>> Modified: cfe/trunk/include/clang/AST/BuiltinTypes.def
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/
>> AST/BuiltinTypes.def?rev=331244&r1=331243&r2=331244&view=diff
>> ============================================================
>> ==================
>> --- cfe/trunk/include/clang/AST/BuiltinTypes.def (original)
>> +++ cfe/trunk/include/clang/AST/BuiltinTypes.def Mon Apr 30 22:02:45 2018
>> @@ -72,6 +72,9 @@ UNSIGNED_TYPE(UChar, UnsignedCharTy)
>>  // 'wchar_t' for targets where it's unsigned
>>  SHARED_SINGLETON_TYPE(UNSIGNED_TYPE(WChar_U, WCharTy))
>>
>> +// 'char8_t' in C++20 (proposed)
>> +UNSIGNED_TYPE(Char8, Char8Ty)
>> +
>>  // 'char16_t' in C++
>>  UNSIGNED_TYPE(Char16, Char16Ty)
>>
>>
>> Modified: cfe/trunk/include/clang/AST/Type.h
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/
>> AST/Type.h?rev=331244&r1=331243&r2=331244&view=diff
>> ============================================================
>> ==================
>> --- cfe/trunk/include/clang/AST/Type.h (original)
>> +++ cfe/trunk/include/clang/AST/Type.h Mon Apr 30 22:02:45 2018
>> @@ -1777,6 +1777,7 @@ public:
>>    bool isBooleanType() const;
>>    bool isCharType() const;
>>    bool isWideCharType() const;
>> +  bool isChar8Type() const;
>>    bool isChar16Type() const;
>>    bool isChar32Type() const;
>>    bool isAnyCharacterType() const;
>>
>> Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/
>> Basic/DiagnosticSemaKinds.td?rev=331244&r1=331243&r2=331244&view=diff
>> ============================================================
>> ==================
>> --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
>> +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Mon Apr 30
>> 22:02:45 2018
>> @@ -2421,6 +2421,9 @@ def err_template_different_associated_co
>>  def warn_cxx98_compat_unicode_type : Warning<
>>    "'%0' type specifier is incompatible with C++98">,
>>    InGroup<CXX98Compat>, DefaultIgnore;
>> +def warn_cxx17_compat_unicode_type : Warning<
>> +  "'char8_t' type specifier is incompatible with C++ standards before
>> C++20">,
>> +  InGroup<CXXPre2aCompat>, DefaultIgnore;
>>
>>  // __make_integer_seq
>>  def err_integer_sequence_negative_length : Error<
>> @@ -5822,6 +5825,13 @@ def err_array_init_wide_string_into_char
>>    "initializing char array with wide string literal">;
>>  def err_array_init_incompat_wide_string_into_wchar : Error<
>>    "initializing wide char array with incompatible wide string literal">;
>> +def err_array_init_plain_string_into_char8_t : Error<
>> +  "initializing 'char8_t' array with plain string literal">;
>> +def note_array_init_plain_string_into_char8_t : Note<
>> +  "add 'u8' prefix to form a 'char8_t' string literal">;
>> +def err_array_init_utf8_string_into_char : Error<
>> +  "initialization of char array with UTF-8 string literal is not
>> permitted "
>> +  "by '-fchar8_t'">;
>>  def err_array_init_different_type : Error<
>>    "cannot initialize array %diff{of type $ with array of type $|"
>>    "with different type of array}0,1">;
>>
>> Modified: cfe/trunk/include/clang/Basic/LangOptions.def
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/
>> Basic/LangOptions.def?rev=331244&r1=331243&r2=331244&view=diff
>> ============================================================
>> ==================
>> --- cfe/trunk/include/clang/Basic/LangOptions.def (original)
>> +++ cfe/trunk/include/clang/Basic/LangOptions.def Mon Apr 30 22:02:45
>> 2018
>> @@ -106,6 +106,7 @@ LANGOPT(LineComment       , 1, 0, "'//'
>>  LANGOPT(Bool              , 1, 0, "bool, true, and false keywords")
>>  LANGOPT(Half              , 1, 0, "half keyword")
>>  LANGOPT(WChar             , 1, CPlusPlus, "wchar_t keyword")
>> +LANGOPT(Char8             , 1, 0, "char8_t keyword")
>>  LANGOPT(DeclSpecKeyword   , 1, 0, "__declspec keyword")
>>  BENIGN_LANGOPT(DollarIdents   , 1, 1, "'$' in identifiers")
>>  BENIGN_LANGOPT(AsmPreprocessor, 1, 0, "preprocessor in asm mode")
>>
>> Modified: cfe/trunk/include/clang/Basic/Specifiers.h
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/
>> Basic/Specifiers.h?rev=331244&r1=331243&r2=331244&view=diff
>> ============================================================
>> ==================
>> --- cfe/trunk/include/clang/Basic/Specifiers.h (original)
>> +++ cfe/trunk/include/clang/Basic/Specifiers.h Mon Apr 30 22:02:45 2018
>> @@ -47,6 +47,7 @@ namespace clang {
>>      TST_void,
>>      TST_char,
>>      TST_wchar,        // C++ wchar_t
>> +    TST_char8,        // C++20 char8_t (proposed)
>>      TST_char16,       // C++11 char16_t
>>      TST_char32,       // C++11 char32_t
>>      TST_int,
>>
>> Modified: cfe/trunk/include/clang/Basic/TokenKinds.def
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/
>> Basic/TokenKinds.def?rev=331244&r1=331243&r2=331244&view=diff
>> ============================================================
>> ==================
>> --- cfe/trunk/include/clang/Basic/TokenKinds.def (original)
>> +++ cfe/trunk/include/clang/Basic/TokenKinds.def Mon Apr 30 22:02:45 2018
>> @@ -260,6 +260,7 @@ PUNCTUATOR(caretcaret,            "^^")
>>  //   BOOLSUPPORT - This is a keyword if 'bool' is a built-in type
>>  //   HALFSUPPORT - This is a keyword if 'half' is a built-in type
>>  //   WCHARSUPPORT - This is a keyword if 'wchar_t' is a built-in type
>> +//   CHAR8SUPPORT - This is a keyword if 'char8_t' is a built-in type
>>  //
>>  KEYWORD(auto                        , KEYALL)
>>  KEYWORD(break                       , KEYALL)
>> @@ -380,6 +381,9 @@ KEYWORD(co_yield                    , KE
>>  MODULES_KEYWORD(module)
>>  MODULES_KEYWORD(import)
>>
>> +// C++ char8_t proposal
>> +KEYWORD(char8_t                     , CHAR8SUPPORT)
>> +
>>  // C11 Extension
>>  KEYWORD(_Float16                    , KEYALL)
>>
>>
>> Modified: cfe/trunk/include/clang/Driver/Options.td
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/
>> Driver/Options.td?rev=331244&r1=331243&r2=331244&view=diff
>> ============================================================
>> ==================
>> --- cfe/trunk/include/clang/Driver/Options.td (original)
>> +++ cfe/trunk/include/clang/Driver/Options.td Mon Apr 30 22:02:45 2018
>> @@ -1525,6 +1525,10 @@ def frtti : Flag<["-"], "frtti">, Group<
>>  def : Flag<["-"], "fsched-interblock">, Group<clang_ignored_f_Group>;
>>  def fshort_enums : Flag<["-"], "fshort-enums">, Group<f_Group>,
>> Flags<[CC1Option]>,
>>    HelpText<"Allocate to an enum type only as many bytes as it needs for
>> the declared range of possible values">;
>> +def fchar8__t : Flag<["-"], "fchar8_t">, Group<f_Group>,
>> Flags<[CC1Option]>,
>> +  HelpText<"Enable C++ builtin type char8_t">;
>> +def fno_char8__t : Flag<["-"], "fno-char8_t">, Group<f_Group>,
>> +  HelpText<"Disable C++ builtin type char8_t">;
>>  def fshort_wchar : Flag<["-"], "fshort-wchar">, Group<f_Group>,
>>    HelpText<"Force wchar_t to be a short unsigned int">;
>>  def fno_short_wchar : Flag<["-"], "fno-short-wchar">, Group<f_Group>,
>>
>> Modified: cfe/trunk/include/clang/Sema/DeclSpec.h
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/
>> Sema/DeclSpec.h?rev=331244&r1=331243&r2=331244&view=diff
>> ============================================================
>> ==================
>> --- cfe/trunk/include/clang/Sema/DeclSpec.h (original)
>> +++ cfe/trunk/include/clang/Sema/DeclSpec.h Mon Apr 30 22:02:45 2018
>> @@ -273,6 +273,7 @@ public:
>>    static const TST TST_void = clang::TST_void;
>>    static const TST TST_char = clang::TST_char;
>>    static const TST TST_wchar = clang::TST_wchar;
>> +  static const TST TST_char8 = clang::TST_char8;
>>    static const TST TST_char16 = clang::TST_char16;
>>    static const TST TST_char32 = clang::TST_char32;
>>    static const TST TST_int = clang::TST_int;
>>
>> Modified: cfe/trunk/include/clang/Sema/Initialization.h
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/
>> Sema/Initialization.h?rev=331244&r1=331243&r2=331244&view=diff
>> ============================================================
>> ==================
>> --- cfe/trunk/include/clang/Sema/Initialization.h (original)
>> +++ cfe/trunk/include/clang/Sema/Initialization.h Mon Apr 30 22:02:45
>> 2018
>> @@ -952,6 +952,12 @@ public:
>>      /// literal.
>>      FK_IncompatWideStringIntoWideChar,
>>
>> +    /// \brief Initializing char8_t array with plain string literal.
>> +    FK_PlainStringIntoUTF8Char,
>> +
>> +    /// \brief Initializing char array with UTF-8 string literal.
>> +    FK_UTF8StringIntoPlainChar,
>> +
>>      /// \brief Array type mismatch.
>>      FK_ArrayTypeMismatch,
>>
>>
>> Modified: cfe/trunk/include/clang/Serialization/ASTBitCodes.h
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/
>> Serialization/ASTBitCodes.h?rev=331244&r1=331243&r2=331244&view=diff
>> ============================================================
>> ==================
>> --- cfe/trunk/include/clang/Serialization/ASTBitCodes.h (original)
>> +++ cfe/trunk/include/clang/Serialization/ASTBitCodes.h Mon Apr 30
>> 22:02:45 2018
>> @@ -936,6 +936,9 @@ namespace serialization {
>>        /// \brief The '_Float16' type
>>        PREDEF_TYPE_FLOAT16_ID = 44,
>>
>> +      /// \brief The C++ 'char8_t' type.
>> +      PREDEF_TYPE_CHAR8_ID = 45,
>> +
>>        /// \brief OpenCL image types with auto numeration
>>  #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
>>        PREDEF_TYPE_##Id##_ID,
>>
>> Modified: cfe/trunk/lib/AST/ASTContext.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTCon
>> text.cpp?rev=331244&r1=331243&r2=331244&view=diff
>> ============================================================
>> ==================
>> --- cfe/trunk/lib/AST/ASTContext.cpp (original)
>> +++ cfe/trunk/lib/AST/ASTContext.cpp Mon Apr 30 22:02:45 2018
>> @@ -1151,6 +1151,9 @@ void ASTContext::InitBuiltinTypes(const
>>
>>    WIntTy = getFromTargetType(Target.getWIntType());
>>
>> +  // C++20 (proposed)
>> +  InitBuiltinType(Char8Ty,              BuiltinType::Char8);
>> +
>>    if (LangOpts.CPlusPlus) // C++0x 3.9.1p5, extension for C++
>>      InitBuiltinType(Char16Ty,           BuiltinType::Char16);
>>    else // C99
>> @@ -1739,6 +1742,7 @@ TypeInfo ASTContext::getTypeInfoImpl(con
>>      case BuiltinType::Char_U:
>>      case BuiltinType::UChar:
>>      case BuiltinType::SChar:
>> +    case BuiltinType::Char8:
>>        Width = Target->getCharWidth();
>>        Align = Target->getCharAlign();
>>        break;
>> @@ -5456,6 +5460,7 @@ QualType ASTContext::getPromotedIntegerT
>>      // FIXME: Is there some better way to compute this?
>>      if (BT->getKind() == BuiltinType::WChar_S ||
>>          BT->getKind() == BuiltinType::WChar_U ||
>> +        BT->getKind() == BuiltinType::Char8 ||
>>          BT->getKind() == BuiltinType::Char16 ||
>>          BT->getKind() == BuiltinType::Char32) {
>>        bool FromIsSigned = BT->getKind() == BuiltinType::WChar_S;
>> @@ -6202,6 +6207,7 @@ static char getObjCEncodingForPrimitiveK
>>      switch (kind) {
>>      case BuiltinType::Void:       return 'v';
>>      case BuiltinType::Bool:       return 'B';
>> +    case BuiltinType::Char8:
>>      case BuiltinType::Char_U:
>>      case BuiltinType::UChar:      return 'C';
>>      case BuiltinType::Char16:
>>
>> Modified: cfe/trunk/lib/AST/ExprConstant.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprCo
>> nstant.cpp?rev=331244&r1=331243&r2=331244&view=diff
>> ============================================================
>> ==================
>> --- cfe/trunk/lib/AST/ExprConstant.cpp (original)
>> +++ cfe/trunk/lib/AST/ExprConstant.cpp Mon Apr 30 22:02:45 2018
>> @@ -7326,6 +7326,7 @@ static int EvaluateBuiltinClassifyType(c
>>        return pointer_type_class;
>>
>>      case BuiltinType::WChar_U:
>> +    case BuiltinType::Char8:
>>      case BuiltinType::Char16:
>>      case BuiltinType::Char32:
>>      case BuiltinType::ObjCId:
>>
>> Modified: cfe/trunk/lib/AST/ItaniumMangle.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Itaniu
>> mMangle.cpp?rev=331244&r1=331243&r2=331244&view=diff
>> ============================================================
>> ==================
>> --- cfe/trunk/lib/AST/ItaniumMangle.cpp (original)
>> +++ cfe/trunk/lib/AST/ItaniumMangle.cpp Mon Apr 30 22:02:45 2018
>> @@ -2525,6 +2525,9 @@ void CXXNameMangler::mangleType(const Bu
>>    case BuiltinType::WChar_U:
>>      Out << 'w';
>>      break;
>> +  case BuiltinType::Char8:
>> +    Out << "Du";
>> +    break;
>>    case BuiltinType::Char16:
>>      Out << "Ds";
>>      break;
>>
>> Modified: cfe/trunk/lib/AST/MicrosoftMangle.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Micros
>> oftMangle.cpp?rev=331244&r1=331243&r2=331244&view=diff
>> ============================================================
>> ==================
>> --- cfe/trunk/lib/AST/MicrosoftMangle.cpp (original)
>> +++ cfe/trunk/lib/AST/MicrosoftMangle.cpp Mon Apr 30 22:02:45 2018
>> @@ -1918,6 +1918,7 @@ void MicrosoftCXXNameMangler::mangleType
>>      Out << "$$T";
>>      break;
>>
>> +  case BuiltinType::Char8:
>>    case BuiltinType::Float16:
>>      mangleArtificalTagType(TTK_Struct, "_Float16", {"__clang"});
>>      break;
>>
>
> Won't this mangle char8_t as _Float16? This seems wrong.
>

Wow. This was a bad automatic svn merge with r330225; this case label was
attached to the following "cannot mangle this yet" block before I sync'd.
Thanks for the catch! Fixed in r331299.

Modified: cfe/trunk/lib/AST/NSAPI.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/NSAPI.
>> cpp?rev=331244&r1=331243&r2=331244&view=diff
>> ============================================================
>> ==================
>> --- cfe/trunk/lib/AST/NSAPI.cpp (original)
>> +++ cfe/trunk/lib/AST/NSAPI.cpp Mon Apr 30 22:02:45 2018
>> @@ -436,6 +436,7 @@ NSAPI::getNSNumberFactoryMethodKind(Qual
>>    case BuiltinType::Void:
>>    case BuiltinType::WChar_U:
>>    case BuiltinType::WChar_S:
>> +  case BuiltinType::Char8:
>>    case BuiltinType::Char16:
>>    case BuiltinType::Char32:
>>    case BuiltinType::Int128:
>>
>> Modified: cfe/trunk/lib/AST/Type.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Type.
>> cpp?rev=331244&r1=331243&r2=331244&view=diff
>> ============================================================
>> ==================
>> --- cfe/trunk/lib/AST/Type.cpp (original)
>> +++ cfe/trunk/lib/AST/Type.cpp Mon Apr 30 22:02:45 2018
>> @@ -1763,6 +1763,12 @@ bool Type::isWideCharType() const {
>>    return false;
>>  }
>>
>> +bool Type::isChar8Type() const {
>> +  if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
>> +    return BT->getKind() == BuiltinType::Char8;
>> +  return false;
>> +}
>> +
>>  bool Type::isChar16Type() const {
>>    if (const auto *BT = dyn_cast<BuiltinType>(CanonicalType))
>>      return BT->getKind() == BuiltinType::Char16;
>> @@ -1785,6 +1791,7 @@ bool Type::isAnyCharacterType() const {
>>    case BuiltinType::Char_U:
>>    case BuiltinType::UChar:
>>    case BuiltinType::WChar_U:
>> +  case BuiltinType::Char8:
>>    case BuiltinType::Char16:
>>    case BuiltinType::Char32:
>>    case BuiltinType::Char_S:
>> @@ -2419,6 +2426,7 @@ bool Type::isPromotableIntegerType() con
>>      case BuiltinType::UShort:
>>      case BuiltinType::WChar_S:
>>      case BuiltinType::WChar_U:
>> +    case BuiltinType::Char8:
>>      case BuiltinType::Char16:
>>      case BuiltinType::Char32:
>>        return true;
>> @@ -2655,6 +2663,8 @@ StringRef BuiltinType::getName(const Pri
>>    case WChar_S:
>>    case WChar_U:
>>      return Policy.MSWChar ? "__wchar_t" : "wchar_t";
>> +  case Char8:
>> +    return "char8_t";
>>    case Char16:
>>      return "char16_t";
>>    case Char32:
>>
>> Modified: cfe/trunk/lib/AST/TypeLoc.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/TypeLo
>> c.cpp?rev=331244&r1=331243&r2=331244&view=diff
>> ============================================================
>> ==================
>> --- cfe/trunk/lib/AST/TypeLoc.cpp (original)
>> +++ cfe/trunk/lib/AST/TypeLoc.cpp Mon Apr 30 22:02:45 2018
>> @@ -317,6 +317,8 @@ TypeSpecifierType BuiltinTypeLoc::getWri
>>    case BuiltinType::Char_U:
>>    case BuiltinType::Char_S:
>>      return TST_char;
>> +  case BuiltinType::Char8:
>> +    return TST_char8;
>>    case BuiltinType::Char16:
>>      return TST_char16;
>>    case BuiltinType::Char32:
>>
>> Modified: cfe/trunk/lib/Analysis/PrintfFormatString.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/
>> PrintfFormatString.cpp?rev=331244&r1=331243&r2=331244&view=diff
>> ============================================================
>> ==================
>> --- cfe/trunk/lib/Analysis/PrintfFormatString.cpp (original)
>> +++ cfe/trunk/lib/Analysis/PrintfFormatString.cpp Mon Apr 30 22:02:45
>> 2018
>> @@ -647,6 +647,7 @@ bool PrintfSpecifier::fixType(QualType Q
>>    case BuiltinType::Bool:
>>    case BuiltinType::WChar_U:
>>    case BuiltinType::WChar_S:
>> +  case BuiltinType::Char8: // FIXME: Treat like 'char'?
>>    case BuiltinType::Char16:
>>    case BuiltinType::Char32:
>>    case BuiltinType::UInt128:
>>
>> Modified: cfe/trunk/lib/Basic/IdentifierTable.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/Iden
>> tifierTable.cpp?rev=331244&r1=331243&r2=331244&view=diff
>> ============================================================
>> ==================
>> --- cfe/trunk/lib/Basic/IdentifierTable.cpp (original)
>> +++ cfe/trunk/lib/Basic/IdentifierTable.cpp Mon Apr 30 22:02:45 2018
>> @@ -115,14 +115,15 @@ namespace {
>>      KEYNOOPENCL = 0x02000,
>>      WCHARSUPPORT = 0x04000,
>>      HALFSUPPORT = 0x08000,
>> -    KEYCONCEPTS = 0x10000,
>> -    KEYOBJC2    = 0x20000,
>> -    KEYZVECTOR  = 0x40000,
>> -    KEYCOROUTINES = 0x80000,
>> -    KEYMODULES = 0x100000,
>> -    KEYCXX2A = 0x200000,
>> +    CHAR8SUPPORT = 0x10000,
>> +    KEYCONCEPTS = 0x20000,
>> +    KEYOBJC2    = 0x40000,
>> +    KEYZVECTOR  = 0x80000,
>> +    KEYCOROUTINES = 0x100000,
>> +    KEYMODULES = 0x200000,
>> +    KEYCXX2A = 0x400000,
>>      KEYALLCXX = KEYCXX | KEYCXX11 | KEYCXX2A,
>> -    KEYALL = (0x3fffff & ~KEYNOMS18 &
>> +    KEYALL = (0x7fffff & ~KEYNOMS18 &
>>                ~KEYNOOPENCL) // KEYNOMS18 and KEYNOOPENCL are used to
>> exclude.
>>    };
>>
>> @@ -151,6 +152,7 @@ static KeywordStatus getKeywordStatus(co
>>    if (LangOpts.Bool && (Flags & BOOLSUPPORT)) return KS_Enabled;
>>    if (LangOpts.Half && (Flags & HALFSUPPORT)) return KS_Enabled;
>>    if (LangOpts.WChar && (Flags & WCHARSUPPORT)) return KS_Enabled;
>> +  if (LangOpts.Char8 && (Flags & CHAR8SUPPORT)) return KS_Enabled;
>>    if (LangOpts.AltiVec && (Flags & KEYALTIVEC)) return KS_Enabled;
>>    if (LangOpts.OpenCL && (Flags & KEYOPENCL)) return KS_Enabled;
>>    if (!LangOpts.CPlusPlus && (Flags & KEYNOCXX)) return KS_Enabled;
>>
>> Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CG
>> DebugInfo.cpp?rev=331244&r1=331243&r2=331244&view=diff
>> ============================================================
>> ==================
>> --- cfe/trunk/lib/CodeGen/CGDebugInfo.cpp (original)
>> +++ cfe/trunk/lib/CodeGen/CGDebugInfo.cpp Mon Apr 30 22:02:45 2018
>> @@ -665,6 +665,7 @@ llvm::DIType *CGDebugInfo::CreateType(co
>>    case BuiltinType::SChar:
>>      Encoding = llvm::dwarf::DW_ATE_signed_char;
>>      break;
>> +  case BuiltinType::Char8:
>>    case BuiltinType::Char16:
>>    case BuiltinType::Char32:
>>      Encoding = llvm::dwarf::DW_ATE_UTF;
>>
>> Modified: cfe/trunk/lib/CodeGen/CodeGenTypes.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/Co
>> deGenTypes.cpp?rev=331244&r1=331243&r2=331244&view=diff
>> ============================================================
>> ==================
>> --- cfe/trunk/lib/CodeGen/CodeGenTypes.cpp (original)
>> +++ cfe/trunk/lib/CodeGen/CodeGenTypes.cpp Mon Apr 30 22:02:45 2018
>> @@ -437,6 +437,7 @@ llvm::Type *CodeGenTypes::ConvertType(Qu
>>      case BuiltinType::ULongLong:
>>      case BuiltinType::WChar_S:
>>      case BuiltinType::WChar_U:
>> +    case BuiltinType::Char8:
>>      case BuiltinType::Char16:
>>      case BuiltinType::Char32:
>>        ResultType = llvm::IntegerType::get(getLLVMContext(),
>>
>> Modified: cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/It
>> aniumCXXABI.cpp?rev=331244&r1=331243&r2=331244&view=diff
>> ============================================================
>> ==================
>> --- cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp (original)
>> +++ cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp Mon Apr 30 22:02:45 2018
>> @@ -2706,6 +2706,7 @@ static bool TypeInfoIsInStandardLibrary(
>>      case BuiltinType::LongDouble:
>>      case BuiltinType::Float16:
>>      case BuiltinType::Float128:
>> +    case BuiltinType::Char8:
>>      case BuiltinType::Char16:
>>      case BuiltinType::Char32:
>>      case BuiltinType::Int128:
>> @@ -3567,7 +3568,8 @@ void ItaniumCXXABI::EmitFundamentalRTTID
>>        getContext().UnsignedInt128Ty,   getContext().HalfTy,
>>        getContext().FloatTy,            getContext().DoubleTy,
>>        getContext().LongDoubleTy,       getContext().Float128Ty,
>> -      getContext().Char16Ty,           getContext().Char32Ty
>> +      getContext().Char8Ty,            getContext().Char16Ty,
>> +      getContext().Char32Ty
>>    };
>>    for (const QualType &FundamentalType : FundamentalTypes)
>>      EmitFundamentalRTTIDescriptor(FundamentalType, DLLExport);
>>
>> Modified: cfe/trunk/lib/Driver/ToolChains/Clang.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Too
>> lChains/Clang.cpp?rev=331244&r1=331243&r2=331244&view=diff
>> ============================================================
>> ==================
>> --- cfe/trunk/lib/Driver/ToolChains/Clang.cpp (original)
>> +++ cfe/trunk/lib/Driver/ToolChains/Clang.cpp Mon Apr 30 22:02:45 2018
>> @@ -2687,6 +2687,9 @@ static void RenderCharacterOptions(const
>>      CmdArgs.push_back("-fno-signed-char");
>>    }
>>
>> +  if (Args.hasFlag(options::OPT_fchar8__t, options::OPT_fno_char8__t,
>> false))
>> +    CmdArgs.push_back("-fchar8_t");
>> +
>>    if (const Arg *A = Args.getLastArg(options::OPT_fshort_wchar,
>>                                       options::OPT_fno_short_wchar)) {
>>      if (A->getOption().matches(options::OPT_fshort_wchar)) {
>>
>> Modified: cfe/trunk/lib/Format/FormatToken.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/For
>> matToken.cpp?rev=331244&r1=331243&r2=331244&view=diff
>> ============================================================
>> ==================
>> --- cfe/trunk/lib/Format/FormatToken.cpp (original)
>> +++ cfe/trunk/lib/Format/FormatToken.cpp Mon Apr 30 22:02:45 2018
>> @@ -57,6 +57,7 @@ bool FormatToken::isSimpleTypeSpecifier(
>>    case tok::kw_bool:
>>    case tok::kw___underlying_type:
>>    case tok::annot_typename:
>> +  case tok::kw_char8_t:
>>    case tok::kw_char16_t:
>>    case tok::kw_char32_t:
>>    case tok::kw_typeof:
>>
>> Modified: cfe/trunk/lib/Frontend/CompilerInvocation.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/
>> CompilerInvocation.cpp?rev=331244&r1=331243&r2=331244&view=diff
>> ============================================================
>> ==================
>> --- cfe/trunk/lib/Frontend/CompilerInvocation.cpp (original)
>> +++ cfe/trunk/lib/Frontend/CompilerInvocation.cpp Mon Apr 30 22:02:45
>> 2018
>> @@ -2362,6 +2362,7 @@ static void ParseLangArgs(LangOptions &O
>>    Opts.ImplicitModules = !Args.hasArg(OPT_fno_implicit_modules);
>>    Opts.CharIsSigned = Opts.OpenCL || !Args.hasArg(OPT_fno_signed_char);
>>    Opts.WChar = Opts.CPlusPlus && !Args.hasArg(OPT_fno_wchar);
>> +  Opts.Char8 = Args.hasArg(OPT_fchar8__t);
>>    if (const Arg *A = Args.getLastArg(OPT_fwchar_type_EQ)) {
>>      Opts.WCharSize = llvm::StringSwitch<unsigned>(A->getValue())
>>                           .Case("char", 1)
>>
>> Modified: cfe/trunk/lib/Frontend/InitPreprocessor.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/
>> InitPreprocessor.cpp?rev=331244&r1=331243&r2=331244&view=diff
>> ============================================================
>> ==================
>> --- cfe/trunk/lib/Frontend/InitPreprocessor.cpp (original)
>> +++ cfe/trunk/lib/Frontend/InitPreprocessor.cpp Mon Apr 30 22:02:45 2018
>> @@ -559,6 +559,10 @@ static void InitializeCPlusPlusFeatureTe
>>      Builder.defineMacro("__cpp_experimental_concepts", "1");
>>    if (LangOpts.CoroutinesTS)
>>      Builder.defineMacro("__cpp_coroutines", "201703L");
>> +
>> +  // Potential future breaking changes.
>> +  if (LangOpts.Char8)
>> +    Builder.defineMacro("__cpp_char8_t", "201803");
>>  }
>>
>>  static void InitializePredefinedMacros(const TargetInfo &TI,
>> @@ -939,6 +943,8 @@ static void InitializePredefinedMacros(c
>>                                         InlineWidthBits));
>>      DEFINE_LOCK_FREE_MACRO(BOOL, Bool);
>>      DEFINE_LOCK_FREE_MACRO(CHAR, Char);
>> +    if (LangOpts.Char8)
>> +      DEFINE_LOCK_FREE_MACRO(CHAR8_T, Char); // Treat char8_t like char.
>>      DEFINE_LOCK_FREE_MACRO(CHAR16_T, Char16);
>>      DEFINE_LOCK_FREE_MACRO(CHAR32_T, Char32);
>>      DEFINE_LOCK_FREE_MACRO(WCHAR_T, WChar);
>>
>> Modified: cfe/trunk/lib/Index/USRGeneration.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Index/USRG
>> eneration.cpp?rev=331244&r1=331243&r2=331244&view=diff
>> ============================================================
>> ==================
>> --- cfe/trunk/lib/Index/USRGeneration.cpp (original)
>> +++ cfe/trunk/lib/Index/USRGeneration.cpp Mon Apr 30 22:02:45 2018
>> @@ -650,6 +650,8 @@ void USRGenerator::VisitType(QualType T)
>>            c = 'b'; break;
>>          case BuiltinType::UChar:
>>            c = 'c'; break;
>> +        case BuiltinType::Char8:
>> +          c = 'u'; break; // FIXME: Check this doesn't collide
>>          case BuiltinType::Char16:
>>            c = 'q'; break;
>>          case BuiltinType::Char32:
>>
>> Modified: cfe/trunk/lib/Lex/PPExpressions.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPExpr
>> essions.cpp?rev=331244&r1=331243&r2=331244&view=diff
>> ============================================================
>> ==================
>> --- cfe/trunk/lib/Lex/PPExpressions.cpp (original)
>> +++ cfe/trunk/lib/Lex/PPExpressions.cpp Mon Apr 30 22:02:45 2018
>> @@ -363,7 +363,7 @@ static bool EvaluateValue(PPValue &Resul
>>        NumBits = TI.getChar16Width();
>>      else if (Literal.isUTF32())
>>        NumBits = TI.getChar32Width();
>> -    else
>> +    else // char or char8_t
>>        NumBits = TI.getCharWidth();
>>
>>      // Set the width.
>>
>> Modified: cfe/trunk/lib/Parse/ParseDecl.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/Pars
>> eDecl.cpp?rev=331244&r1=331243&r2=331244&view=diff
>> ============================================================
>> ==================
>> --- cfe/trunk/lib/Parse/ParseDecl.cpp (original)
>> +++ cfe/trunk/lib/Parse/ParseDecl.cpp Mon Apr 30 22:02:45 2018
>> @@ -3587,6 +3587,10 @@ void Parser::ParseDeclarationSpecifiers(
>>        isInvalid = DS.SetTypeSpecType(DeclSpec::TST_wchar, Loc, PrevSpec,
>>                                       DiagID, Policy);
>>        break;
>> +    case tok::kw_char8_t:
>> +      isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char8, Loc, PrevSpec,
>> +                                     DiagID, Policy);
>> +      break;
>>      case tok::kw_char16_t:
>>        isInvalid = DS.SetTypeSpecType(DeclSpec::TST_char16, Loc,
>> PrevSpec,
>>                                       DiagID, Policy);
>> @@ -4585,6 +4589,7 @@ bool Parser::isKnownToBeTypeSpecifier(co
>>    case tok::kw_void:
>>    case tok::kw_char:
>>    case tok::kw_wchar_t:
>> +  case tok::kw_char8_t:
>>    case tok::kw_char16_t:
>>    case tok::kw_char32_t:
>>    case tok::kw_int:
>> @@ -4661,6 +4666,7 @@ bool Parser::isTypeSpecifierQualifier()
>>    case tok::kw_void:
>>    case tok::kw_char:
>>    case tok::kw_wchar_t:
>> +  case tok::kw_char8_t:
>>    case tok::kw_char16_t:
>>    case tok::kw_char32_t:
>>    case tok::kw_int:
>> @@ -4817,6 +4823,7 @@ bool Parser::isDeclarationSpecifier(bool
>>    case tok::kw_void:
>>    case tok::kw_char:
>>    case tok::kw_wchar_t:
>> +  case tok::kw_char8_t:
>>    case tok::kw_char16_t:
>>    case tok::kw_char32_t:
>>
>>
>> Modified: cfe/trunk/lib/Parse/ParseExpr.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/Pars
>> eExpr.cpp?rev=331244&r1=331243&r2=331244&view=diff
>> ============================================================
>> ==================
>> --- cfe/trunk/lib/Parse/ParseExpr.cpp (original)
>> +++ cfe/trunk/lib/Parse/ParseExpr.cpp Mon Apr 30 22:02:45 2018
>> @@ -1224,6 +1224,7 @@ ExprResult Parser::ParseCastExpression(b
>>    case tok::annot_decltype:
>>    case tok::kw_char:
>>    case tok::kw_wchar_t:
>> +  case tok::kw_char8_t:
>>    case tok::kw_char16_t:
>>    case tok::kw_char32_t:
>>    case tok::kw_bool:
>>
>> Modified: cfe/trunk/lib/Parse/ParseExprCXX.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/Pars
>> eExprCXX.cpp?rev=331244&r1=331243&r2=331244&view=diff
>> ============================================================
>> ==================
>> --- cfe/trunk/lib/Parse/ParseExprCXX.cpp (original)
>> +++ cfe/trunk/lib/Parse/ParseExprCXX.cpp Mon Apr 30 22:02:45 2018
>> @@ -1962,6 +1962,9 @@ void Parser::ParseCXXSimpleTypeSpecifier
>>    case tok::kw_wchar_t:
>>      DS.SetTypeSpecType(DeclSpec::TST_wchar, Loc, PrevSpec, DiagID,
>> Policy);
>>      break;
>> +  case tok::kw_char8_t:
>> +    DS.SetTypeSpecType(DeclSpec::TST_char8, Loc, PrevSpec, DiagID,
>> Policy);
>> +    break;
>>    case tok::kw_char16_t:
>>      DS.SetTypeSpecType(DeclSpec::TST_char16, Loc, PrevSpec, DiagID,
>> Policy);
>>      break;
>>
>> Modified: cfe/trunk/lib/Parse/ParseTentative.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/Pars
>> eTentative.cpp?rev=331244&r1=331243&r2=331244&view=diff
>> ============================================================
>> ==================
>> --- cfe/trunk/lib/Parse/ParseTentative.cpp (original)
>> +++ cfe/trunk/lib/Parse/ParseTentative.cpp Mon Apr 30 22:02:45 2018
>> @@ -1052,6 +1052,7 @@ Parser::isExpressionOrTypeSpecifierSimpl
>>    case tok::kw_class:
>>    case tok::kw_typename:
>>    case tok::kw_wchar_t:
>> +  case tok::kw_char8_t:
>>    case tok::kw_char16_t:
>>    case tok::kw_char32_t:
>>    case tok::kw__Decimal32:
>> @@ -1523,6 +1524,7 @@ Parser::isCXXDeclarationSpecifier(Parser
>>
>>    case tok::kw_char:
>>    case tok::kw_wchar_t:
>> +  case tok::kw_char8_t:
>>    case tok::kw_char16_t:
>>    case tok::kw_char32_t:
>>    case tok::kw_bool:
>> @@ -1614,6 +1616,7 @@ bool Parser::isCXXDeclarationSpecifierAT
>>      // simple-type-specifier
>>    case tok::kw_char:
>>    case tok::kw_wchar_t:
>> +  case tok::kw_char8_t:
>>    case tok::kw_char16_t:
>>    case tok::kw_char32_t:
>>    case tok::kw_bool:
>>
>> Modified: cfe/trunk/lib/Sema/DeclSpec.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/DeclS
>> pec.cpp?rev=331244&r1=331243&r2=331244&view=diff
>> ============================================================
>> ==================
>> --- cfe/trunk/lib/Sema/DeclSpec.cpp (original)
>> +++ cfe/trunk/lib/Sema/DeclSpec.cpp Mon Apr 30 22:02:45 2018
>> @@ -329,6 +329,7 @@ bool Declarator::isDeclarationOfFunction
>>      case TST_auto_type:
>>      case TST_bool:
>>      case TST_char:
>> +    case TST_char8:
>>      case TST_char16:
>>      case TST_char32:
>>      case TST_class:
>> @@ -499,6 +500,7 @@ const char *DeclSpec::getSpecifierName(D
>>    case DeclSpec::TST_void:        return "void";
>>    case DeclSpec::TST_char:        return "char";
>>    case DeclSpec::TST_wchar:       return Policy.MSWChar ? "__wchar_t" :
>> "wchar_t";
>> +  case DeclSpec::TST_char8:       return "char8_t";
>>    case DeclSpec::TST_char16:      return "char16_t";
>>    case DeclSpec::TST_char32:      return "char32_t";
>>    case DeclSpec::TST_int:         return "int";
>> @@ -1202,7 +1204,9 @@ void DeclSpec::Finish(Sema &S, const Pri
>>        StorageClassSpec == SCS_auto)
>>      S.Diag(StorageClassSpecLoc, diag::warn_auto_storage_class)
>>        << FixItHint::CreateRemoval(StorageClassSpecLoc);
>> -  if (TypeSpecType == TST_char16 || TypeSpecType == TST_char32)
>> +  if (TypeSpecType == TST_char8)
>> +    S.Diag(TSTLoc, diag::warn_cxx17_compat_unicode_type);
>> +  else if (TypeSpecType == TST_char16 || TypeSpecType == TST_char32)
>>      S.Diag(TSTLoc, diag::warn_cxx98_compat_unicode_type)
>>        << (TypeSpecType == TST_char16 ? "char16_t" : "char32_t");
>>    if (Constexpr_specified)
>>
>> Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaD
>> ecl.cpp?rev=331244&r1=331243&r2=331244&view=diff
>> ============================================================
>> ==================
>> --- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
>> +++ cfe/trunk/lib/Sema/SemaDecl.cpp Mon Apr 30 22:02:45 2018
>> @@ -148,6 +148,9 @@ bool Sema::isSimpleTypeSpecifier(tok::To
>>    case tok::kw_decltype:
>>      return getLangOpts().CPlusPlus;
>>
>> +  case tok::kw_char8_t:
>> +    return getLangOpts().Char8;
>> +
>>    default:
>>      break;
>>    }
>>
>> Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaD
>> eclCXX.cpp?rev=331244&r1=331243&r2=331244&view=diff
>> ============================================================
>> ==================
>> --- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
>> +++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Mon Apr 30 22:02:45 2018
>> @@ -13187,6 +13187,7 @@ bool Sema::CheckLiteralOperatorDeclarati
>>          ParamType->isSpecificBuiltinType(BuiltinType::LongDouble) ||
>>          Context.hasSameType(ParamType, Context.CharTy) ||
>>          Context.hasSameType(ParamType, Context.WideCharTy) ||
>> +        Context.hasSameType(ParamType, Context.Char8Ty) ||
>>          Context.hasSameType(ParamType, Context.Char16Ty) ||
>>          Context.hasSameType(ParamType, Context.Char32Ty)) {
>>      } else if (const PointerType *Ptr = ParamType->getAs<PointerType>())
>> {
>> @@ -13247,10 +13248,12 @@ bool Sema::CheckLiteralOperatorDeclarati
>>      }
>>
>>      QualType InnerType = PointeeType.getUnqualifiedType();
>> -    // Only const char *, const wchar_t*, const char16_t*, and const
>> char32_t*
>> -    // are allowed as the first parameter to a two-parameter function
>> +    // Only const char *, const wchar_t*, const char8_t*, const
>> char16_t*, and
>> +    // const char32_t* are allowed as the first parameter to a
>> two-parameter
>> +    // function
>>      if (!(Context.hasSameType(InnerType, Context.CharTy) ||
>>            Context.hasSameType(InnerType, Context.WideCharTy) ||
>> +          Context.hasSameType(InnerType, Context.Char8Ty) ||
>>            Context.hasSameType(InnerType, Context.Char16Ty) ||
>>            Context.hasSameType(InnerType, Context.Char32Ty))) {
>>        Diag((*Param)->getSourceRange().getBegin(),
>>
>> Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaE
>> xpr.cpp?rev=331244&r1=331243&r2=331244&view=diff
>> ============================================================
>> ==================
>> --- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
>> +++ cfe/trunk/lib/Sema/SemaExpr.cpp Mon Apr 30 22:02:45 2018
>> @@ -1535,6 +1535,8 @@ Sema::ActOnStringLiteral(ArrayRef<Token>
>>      CharTy = Context.getWideCharType();
>>      Kind = StringLiteral::Wide;
>>    } else if (Literal.isUTF8()) {
>> +    if (getLangOpts().Char8)
>> +      CharTy = Context.Char8Ty;
>>      Kind = StringLiteral::UTF8;
>>    } else if (Literal.isUTF16()) {
>>      CharTy = Context.Char16Ty;
>> @@ -3094,6 +3096,8 @@ ExprResult Sema::ActOnCharacterConstant(
>>    QualType Ty;
>>    if (Literal.isWide())
>>      Ty = Context.WideCharTy; // L'x' -> wchar_t in C and C++.
>> +  else if (Literal.isUTF8() && getLangOpts().Char8)
>> +    Ty = Context.Char8Ty; // u8'x' -> char8_t when it exists.
>>    else if (Literal.isUTF16())
>>      Ty = Context.Char16Ty; // u'x' -> char16_t in C11 and C++11.
>>    else if (Literal.isUTF32())
>>
>> Modified: cfe/trunk/lib/Sema/SemaInit.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaI
>> nit.cpp?rev=331244&r1=331243&r2=331244&view=diff
>> ============================================================
>> ==================
>> --- cfe/trunk/lib/Sema/SemaInit.cpp (original)
>> +++ cfe/trunk/lib/Sema/SemaInit.cpp Mon Apr 30 22:02:45 2018
>> @@ -49,6 +49,8 @@ enum StringInitFailureKind {
>>    SIF_NarrowStringIntoWideChar,
>>    SIF_WideStringIntoChar,
>>    SIF_IncompatWideStringIntoWideChar,
>> +  SIF_UTF8StringIntoPlainChar,
>> +  SIF_PlainStringIntoUTF8Char,
>>    SIF_Other
>>  };
>>
>> @@ -77,12 +79,21 @@ static StringInitFailureKind IsStringIni
>>        Context.getCanonicalType(AT->getElementType()).getUnqualifi
>> edType();
>>
>>    switch (SL->getKind()) {
>> -  case StringLiteral::Ascii:
>>    case StringLiteral::UTF8:
>> +    // char8_t array can be initialized with a UTF-8 string.
>> +    if (ElemTy->isChar8Type())
>> +      return SIF_None;
>> +    LLVM_FALLTHROUGH;
>> +  case StringLiteral::Ascii:
>>      // char array can be initialized with a narrow string.
>>      // Only allow char x[] = "foo";  not char x[] = L"foo";
>>      if (ElemTy->isCharType())
>> -      return SIF_None;
>> +      return (SL->getKind() == StringLiteral::UTF8 &&
>> +              Context.getLangOpts().Char8)
>> +                 ? SIF_UTF8StringIntoPlainChar
>> +                 : SIF_None;
>> +    if (ElemTy->isChar8Type())
>> +      return SIF_PlainStringIntoUTF8Char;
>>      if (IsWideCharCompatible(ElemTy, Context))
>>        return SIF_NarrowStringIntoWideChar;
>>      return SIF_Other;
>> @@ -94,7 +105,7 @@ static StringInitFailureKind IsStringIni
>>    case StringLiteral::UTF16:
>>      if (Context.typesAreCompatible(Context.Char16Ty, ElemTy))
>>        return SIF_None;
>> -    if (ElemTy->isCharType())
>> +    if (ElemTy->isCharType() || ElemTy->isChar8Type())
>>        return SIF_WideStringIntoChar;
>>      if (IsWideCharCompatible(ElemTy, Context))
>>        return SIF_IncompatWideStringIntoWideChar;
>> @@ -102,7 +113,7 @@ static StringInitFailureKind IsStringIni
>>    case StringLiteral::UTF32:
>>      if (Context.typesAreCompatible(Context.Char32Ty, ElemTy))
>>        return SIF_None;
>> -    if (ElemTy->isCharType())
>> +    if (ElemTy->isCharType() || ElemTy->isChar8Type())
>>        return SIF_WideStringIntoChar;
>>      if (IsWideCharCompatible(ElemTy, Context))
>>        return SIF_IncompatWideStringIntoWideChar;
>> @@ -110,7 +121,7 @@ static StringInitFailureKind IsStringIni
>>    case StringLiteral::Wide:
>>      if (Context.typesAreCompatible(Context.getWideCharType(), ElemTy))
>>        return SIF_None;
>> -    if (ElemTy->isCharType())
>> +    if (ElemTy->isCharType() || ElemTy->isChar8Type())
>>        return SIF_WideStringIntoChar;
>>      if (IsWideCharCompatible(ElemTy, Context))
>>        return SIF_IncompatWideStringIntoWideChar;
>> @@ -3185,6 +3196,8 @@ bool InitializationSequence::isAmbiguous
>>    case FK_NarrowStringIntoWideCharArray:
>>    case FK_WideStringIntoCharArray:
>>    case FK_IncompatWideStringIntoWideChar:
>> +  case FK_PlainStringIntoUTF8Char:
>> +  case FK_UTF8StringIntoPlainChar:
>>    case FK_AddressOfOverloadFailed: // FIXME: Could do better
>>    case FK_NonConstLValueReferenceBindingToTemporary:
>>    case FK_NonConstLValueReferenceBindingToBitfield:
>> @@ -5362,6 +5375,12 @@ void InitializationSequence::InitializeF
>>        case SIF_IncompatWideStringIntoWideChar:
>>          SetFailed(FK_IncompatWideStringIntoWideChar);
>>          return;
>> +      case SIF_PlainStringIntoUTF8Char:
>> +        SetFailed(FK_PlainStringIntoUTF8Char);
>> +        return;
>> +      case SIF_UTF8StringIntoPlainChar:
>> +        SetFailed(FK_UTF8StringIntoPlainChar);
>> +        return;
>>        case SIF_Other:
>>          break;
>>        }
>> @@ -7591,6 +7610,17 @@ bool InitializationSequence::Diagnose(Se
>>      S.Diag(Kind.getLocation(),
>>             diag::err_array_init_incompat_wide_string_into_wchar);
>>      break;
>> +  case FK_PlainStringIntoUTF8Char:
>> +    S.Diag(Kind.getLocation(),
>> +           diag::err_array_init_plain_string_into_char8_t);
>> +    S.Diag(Args.front()->getLocStart(),
>> +           diag::note_array_init_plain_string_into_char8_t)
>> +      << FixItHint::CreateInsertion(Args.front()->getLocStart(), "u8");
>> +    break;
>> +  case FK_UTF8StringIntoPlainChar:
>> +    S.Diag(Kind.getLocation(),
>> +           diag::err_array_init_utf8_string_into_char);
>> +    break;
>>    case FK_ArrayTypeMismatch:
>>    case FK_NonConstantArrayInit:
>>      S.Diag(Kind.getLocation(),
>> @@ -8000,6 +8030,14 @@ void InitializationSequence::dump(raw_os
>>        OS << "incompatible wide string into wide char array";
>>        break;
>>
>> +    case FK_PlainStringIntoUTF8Char:
>> +      OS << "plain string literal into char8_t array";
>> +      break;
>> +
>> +    case FK_UTF8StringIntoPlainChar:
>> +      OS << "u8 string literal into char array";
>> +      break;
>> +
>>      case FK_ArrayTypeMismatch:
>>        OS << "array type mismatch";
>>        break;
>>
>> Modified: cfe/trunk/lib/Sema/SemaOverload.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaO
>> verload.cpp?rev=331244&r1=331243&r2=331244&view=diff
>> ============================================================
>> ==================
>> --- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
>> +++ cfe/trunk/lib/Sema/SemaOverload.cpp Mon Apr 30 22:02:45 2018
>> @@ -7707,6 +7707,8 @@ class BuiltinOperatorOverloadBuilder {
>>      ArithmeticTypes.push_back(S.Context.BoolTy);
>>      ArithmeticTypes.push_back(S.Context.CharTy);
>>      ArithmeticTypes.push_back(S.Context.WCharTy);
>> +    if (S.Context.getLangOpts().Char8)
>> +      ArithmeticTypes.push_back(S.Context.Char8Ty);
>>      ArithmeticTypes.push_back(S.Context.Char16Ty);
>>      ArithmeticTypes.push_back(S.Context.Char32Ty);
>>      ArithmeticTypes.push_back(S.Context.SignedCharTy);
>>
>> Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaT
>> emplate.cpp?rev=331244&r1=331243&r2=331244&view=diff
>> ============================================================
>> ==================
>> --- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
>> +++ cfe/trunk/lib/Sema/SemaTemplate.cpp Mon Apr 30 22:02:45 2018
>> @@ -6771,11 +6771,11 @@ Sema::BuildExpressionFromIntegralTemplat
>>
>>    Expr *E;
>>    if (T->isAnyCharacterType()) {
>> -    // This does not need to handle u8 character literals because those
>> are
>> -    // of type char, and so can also be covered by an ASCII character
>> literal.
>>      CharacterLiteral::CharacterKind Kind;
>>      if (T->isWideCharType())
>>        Kind = CharacterLiteral::Wide;
>> +    else if (T->isChar8Type() && getLangOpts().Char8)
>> +      Kind = CharacterLiteral::UTF8;
>>      else if (T->isChar16Type())
>>        Kind = CharacterLiteral::UTF16;
>>      else if (T->isChar32Type())
>>
>> Modified: cfe/trunk/lib/Sema/SemaTemplateVariadic.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaT
>> emplateVariadic.cpp?rev=331244&r1=331243&r2=331244&view=diff
>> ============================================================
>> ==================
>> --- cfe/trunk/lib/Sema/SemaTemplateVariadic.cpp (original)
>> +++ cfe/trunk/lib/Sema/SemaTemplateVariadic.cpp Mon Apr 30 22:02:45 2018
>> @@ -822,6 +822,7 @@ bool Sema::containsUnexpandedParameterPa
>>    case TST_void:
>>    case TST_char:
>>    case TST_wchar:
>> +  case TST_char8:
>>    case TST_char16:
>>    case TST_char32:
>>    case TST_int:
>>
>> Modified: cfe/trunk/lib/Sema/SemaType.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaT
>> ype.cpp?rev=331244&r1=331243&r2=331244&view=diff
>> ============================================================
>> ==================
>> --- cfe/trunk/lib/Sema/SemaType.cpp (original)
>> +++ cfe/trunk/lib/Sema/SemaType.cpp Mon Apr 30 22:02:45 2018
>> @@ -1277,6 +1277,11 @@ static QualType ConvertDeclSpecToType(Ty
>>        Result = Context.getUnsignedWCharType();
>>      }
>>      break;
>> +  case DeclSpec::TST_char8:
>> +      assert(DS.getTypeSpecSign() == DeclSpec::TSS_unspecified &&
>> +        "Unknown TSS value");
>> +      Result = Context.Char8Ty;
>> +    break;
>>    case DeclSpec::TST_char16:
>>        assert(DS.getTypeSpecSign() == DeclSpec::TSS_unspecified &&
>>          "Unknown TSS value");
>>
>> Modified: cfe/trunk/lib/Serialization/ASTCommon.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serializat
>> ion/ASTCommon.cpp?rev=331244&r1=331243&r2=331244&view=diff
>> ============================================================
>> ==================
>> --- cfe/trunk/lib/Serialization/ASTCommon.cpp (original)
>> +++ cfe/trunk/lib/Serialization/ASTCommon.cpp Mon Apr 30 22:02:45 2018
>> @@ -100,6 +100,9 @@ serialization::TypeIdxFromBuiltin(const
>>    case BuiltinType::NullPtr:
>>      ID = PREDEF_TYPE_NULLPTR_ID;
>>      break;
>> +  case BuiltinType::Char8:
>> +    ID = PREDEF_TYPE_CHAR8_ID;
>> +    break;
>>    case BuiltinType::Char16:
>>      ID = PREDEF_TYPE_CHAR16_ID;
>>      break;
>>
>> Modified: cfe/trunk/lib/Serialization/ASTReader.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serializat
>> ion/ASTReader.cpp?rev=331244&r1=331243&r2=331244&view=diff
>> ============================================================
>> ==================
>> --- cfe/trunk/lib/Serialization/ASTReader.cpp (original)
>> +++ cfe/trunk/lib/Serialization/ASTReader.cpp Mon Apr 30 22:02:45 2018
>> @@ -6841,6 +6841,9 @@ QualType ASTReader::GetType(TypeID ID) {
>>      case PREDEF_TYPE_NULLPTR_ID:
>>        T = Context.NullPtrTy;
>>        break;
>> +    case PREDEF_TYPE_CHAR8_ID:
>> +      T = Context.Char8Ty;
>> +      break;
>>      case PREDEF_TYPE_CHAR16_ID:
>>        T = Context.Char16Ty;
>>        break;
>>
>> Added: cfe/trunk/test/CodeGenCXX/char8_t.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCX
>> X/char8_t.cpp?rev=331244&view=auto
>> ============================================================
>> ==================
>> --- cfe/trunk/test/CodeGenCXX/char8_t.cpp (added)
>> +++ cfe/trunk/test/CodeGenCXX/char8_t.cpp Mon Apr 30 22:02:45 2018
>> @@ -0,0 +1,8 @@
>> +// RUN: %clang_cc1 -std=c++17 -emit-llvm -fchar8_t -triple x86_64-linux
>> %s -o - | FileCheck %s
>> +
>> +// CHECK: define void @_Z1fDu(
>> +void f(char8_t c) {}
>> +
>> +// CHECK: define void @_Z1gIiEvDTplplcvT__ELA4_KDuELDu114EE
>> +template<typename T> void g(decltype(T() + u8"foo" + u8'r')) {}
>> +template void g<int>(const char8_t*);
>>
>> Added: cfe/trunk/test/Lexer/char8_t.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Lexer/cha
>> r8_t.cpp?rev=331244&view=auto
>> ============================================================
>> ==================
>> --- cfe/trunk/test/Lexer/char8_t.cpp (added)
>> +++ cfe/trunk/test/Lexer/char8_t.cpp Mon Apr 30 22:02:45 2018
>> @@ -0,0 +1,17 @@
>> +// RUN: %clang_cc1 -std=c++2a -verify %s
>> +// RUN: %clang_cc1 -std=c++2a -verify %s -fchar8_t
>> +
>> +#if defined(__cpp_char8_t) && __is_identifier(char8_t)
>> +#error char8_t is an identifier under -fchar8_t
>> +#endif
>> +
>> +#if !defined(__cpp_char8_t) && !__is_identifier(char8_t)
>> +#error char8_t is a keyword under -fno-char8_t
>> +#endif
>> +
>> +char8_t c8t;
>> +#ifndef __cpp_char8_t
>> +// expected-error at -2 {{unknown type}}
>> +#else
>> +// expected-no-diagnostics
>> +#endif
>>
>> Modified: cfe/trunk/test/Lexer/cxx-features.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Lexer/cxx
>> -features.cpp?rev=331244&r1=331243&r2=331244&view=diff
>> ============================================================
>> ==================
>> --- cfe/trunk/test/Lexer/cxx-features.cpp (original)
>> +++ cfe/trunk/test/Lexer/cxx-features.cpp Mon Apr 30 22:02:45 2018
>> @@ -6,6 +6,7 @@
>>  // RUN: %clang_cc1 -std=c++1z -fcxx-exceptions -fsized-deallocation
>> -fconcepts-ts -DCONCEPTS_TS=1 -verify %s
>>  // RUN: %clang_cc1 -fno-rtti -fno-threadsafe-statics -verify %s
>> -DNO_EXCEPTIONS -DNO_RTTI -DNO_THREADSAFE_STATICS -fsized-deallocation
>>  // RUN: %clang_cc1 -fcoroutines-ts -DNO_EXCEPTIONS -DCOROUTINES -verify
>> -fsized-deallocation %s
>> +// RUN: %clang_cc1 -fchar8_t -DNO_EXCEPTIONS -DCHAR8_T -verify
>> -fsized-deallocation %s
>>
>>  // expected-no-diagnostics
>>
>> @@ -242,3 +243,9 @@
>>  #if defined(COROUTINES) ? check(coroutines, 201703L, 201703L, 201703L,
>> 201703L) : check(coroutines, 0, 0, 0, 0)
>>  #error "wrong value for __cpp_coroutines"
>>  #endif
>> +
>> +// --- not-yet-standard features --
>> +
>> +#if defined(CHAR8_T) ? check(char8_t, 201803, 201803, 201803, 201803) :
>> check(char8_t, 0, 0, 0, 0)
>> +#error "wrong value for __cpp_char8_t"
>> +#endif
>>
>> Added: cfe/trunk/test/SemaCXX/char8_t.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/
>> char8_t.cpp?rev=331244&view=auto
>> ============================================================
>> ==================
>> --- cfe/trunk/test/SemaCXX/char8_t.cpp (added)
>> +++ cfe/trunk/test/SemaCXX/char8_t.cpp Mon Apr 30 22:02:45 2018
>> @@ -0,0 +1,44 @@
>> +// RUN: %clang_cc1 -fchar8_t -std=c++2a -verify %s
>> +
>> +char8_t a = u8'a';
>> +char8_t b[] = u8"foo";
>> +char8_t c = 'a';
>> +char8_t d[] = "foo"; // expected-error {{initializing 'char8_t' array
>> with plain string literal}} expected-note {{add 'u8' prefix}}
>> +
>> +char e = u8'a';
>> +char f[] = u8"foo"; // expected-error {{initialization of char array
>> with UTF-8 string literal is not permitted by '-fchar8_t'}}
>> +char g = 'a';
>> +char h[] = "foo";
>> +
>> +void disambig() {
>> +  char8_t (a) = u8'x';
>> +}
>> +
>> +void operator""_a(char);
>> +void operator""_a(const char*, decltype(sizeof(0)));
>> +
>> +void test_udl1() {
>> +  int &x = u8'a'_a; // expected-error {{no matching literal operator}}
>> +  float &y = u8"a"_a; // expected-error {{no matching literal operator}}
>> +}
>> +
>> +int &operator""_a(char8_t);
>> +float &operator""_a(const char8_t*, decltype(sizeof(0)));
>> +
>> +void test_udl2() {
>> +  int &x = u8'a'_a;
>> +  float &y = u8"a"_a;
>> +}
>> +
>> +template<typename E, typename T> void check(T &&t) {
>> +  using Check = E;
>> +  using Check = T;
>> +}
>> +void check_deduction() {
>> +  check<char8_t>(u8'a');
>> +  check<const char8_t(&)[5]>(u8"a\u1000");
>> +}
>> +
>> +static_assert(sizeof(char8_t) == 1);
>> +static_assert(char8_t(-1) > 0);
>> +static_assert(u8"\u0080"[0] > 0);
>>
>>
>> _______________________________________________
>> cfe-commits mailing list
>> cfe-commits at lists.llvm.org
>> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>>
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20180501/254c2e03/attachment-0001.html>


More information about the cfe-commits mailing list