On Mon, Apr 30, 2018 at 10:02 PM, Richard Smith via cfe-commits < cfe-commits@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/ > ASTContext.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/ > ExprConstant.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/ > ItaniumMangle.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/ > MicrosoftMangle.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. > > 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/ > TypeLoc.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/ > IdentifierTable.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/ > CGDebugInfo.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/ > CodeGenTypes.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/ > ItaniumCXXABI.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/ > ToolChains/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/ > FormatToken.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/ > USRGeneration.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/ > PPExpressions.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/ > ParseDecl.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/ > ParseExpr.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/ > ParseExprCXX.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/ > ParseTentative.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/ > DeclSpec.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/ > SemaDecl.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/ > SemaDeclCXX.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/ > SemaExpr.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/ > SemaInit.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()). > getUnqualifiedType(); > > 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/ > SemaOverload.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/ > SemaTemplate.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/ > SemaTemplateVariadic.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/ > SemaType.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/ > Serialization/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/ > Serialization/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/ > CodeGenCXX/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/ > char8_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@-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@lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits >
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits