Index: cfe/trunk/include/clang/Lex/LiteralSupport.h =================================================================== --- cfe/trunk/include/clang/Lex/LiteralSupport.h +++ cfe/trunk/include/clang/Lex/LiteralSupport.h @@ -63,7 +63,7 @@ bool isLongLong; bool isFloat; // 1.0f bool isImaginary; // 1.0i - bool isMicrosoftInteger; // Microsoft suffix extension i8, i16, i32, or i64. + uint8_t MicrosoftInteger; // Microsoft suffix extension i8, i16, i32, or i64. bool isIntegerLiteral() const { return !saw_period && !saw_exponent; Index: cfe/trunk/lib/AST/StmtPrinter.cpp =================================================================== --- cfe/trunk/lib/AST/StmtPrinter.cpp +++ cfe/trunk/lib/AST/StmtPrinter.cpp @@ -947,8 +947,10 @@ // FIXME: The Short and UShort cases are to handle cases where a short // integeral literal is formed during template instantiation. They should // be removed when template instantiation no longer needs integer literals. - case BuiltinType::Short: - case BuiltinType::UShort: + case BuiltinType::SChar: OS << "i8"; break; + case BuiltinType::UChar: OS << "Ui8"; break; + case BuiltinType::Short: OS << "i16"; break; + case BuiltinType::UShort: OS << "Ui16"; break; case BuiltinType::Int: break; // no suffix. case BuiltinType::UInt: OS << 'U'; break; case BuiltinType::Long: OS << 'L'; break; Index: cfe/trunk/lib/Lex/LiteralSupport.cpp =================================================================== --- cfe/trunk/lib/Lex/LiteralSupport.cpp +++ cfe/trunk/lib/Lex/LiteralSupport.cpp @@ -522,7 +522,7 @@ isLongLong = false; isFloat = false; isImaginary = false; - isMicrosoftInteger = false; + MicrosoftInteger = 0; hadError = false; if (*s == '0') { // parse radix @@ -606,7 +606,8 @@ case 'i': case 'I': if (PP.getLangOpts().MicrosoftExt) { - if (isLong || isLongLong) break; + if (isLong || isLongLong || MicrosoftInteger) + break; // Allow i8, i16, i32, i64, and i128. if (s + 1 != ThisTokEnd) { @@ -614,20 +615,20 @@ case '8': if (isFPConstant) break; s += 2; // i8 suffix - isMicrosoftInteger = true; + MicrosoftInteger = 8; break; case '1': if (isFPConstant) break; if (s + 2 == ThisTokEnd) break; if (s[2] == '6') { s += 3; // i16 suffix - isMicrosoftInteger = true; + MicrosoftInteger = 16; } else if (s[2] == '2') { if (s + 3 == ThisTokEnd) break; if (s[3] == '8') { s += 4; // i128 suffix - isMicrosoftInteger = true; + MicrosoftInteger = 128; } } break; @@ -636,8 +637,7 @@ if (s + 2 == ThisTokEnd) break; if (s[2] == '2') { s += 3; // i32 suffix - isLong = true; - isMicrosoftInteger = true; + MicrosoftInteger = 32; } break; case '6': @@ -645,14 +645,13 @@ if (s + 2 == ThisTokEnd) break; if (s[2] == '4') { s += 3; // i64 suffix - isLongLong = true; - isMicrosoftInteger = true; + MicrosoftInteger = 64; } break; default: break; } - if (isMicrosoftInteger) + if (MicrosoftInteger) break; } } @@ -682,7 +681,7 @@ isLongLong = false; isFloat = false; isImaginary = false; - isMicrosoftInteger = false; + MicrosoftInteger = 0; saw_ud_suffix = true; return; Index: cfe/trunk/lib/Sema/SemaExpr.cpp =================================================================== --- cfe/trunk/lib/Sema/SemaExpr.cpp +++ cfe/trunk/lib/Sema/SemaExpr.cpp @@ -3190,7 +3190,7 @@ // may be wider than [u]intmax_t. // FIXME: Actually, they don't. We seem to have accidentally invented the // i128 suffix. - if (Literal.isMicrosoftInteger && MaxWidth < 128 && + if (Literal.MicrosoftInteger && MaxWidth < 128 && Context.getTargetInfo().hasInt128Type()) MaxWidth = 128; llvm::APInt ResultVal(MaxWidth, 0); @@ -3211,7 +3211,18 @@ // Check from smallest to largest, picking the smallest type we can. unsigned Width = 0; - if (!Literal.isLong && !Literal.isLongLong) { + + // Microsoft specific integer suffixes are explicitly sized. + if (Literal.MicrosoftInteger) { + Width = Literal.MicrosoftInteger; + if (Width < 128) + Ty = Context.getIntTypeForBitwidth(Width, + /*Signed=*/!Literal.isUnsigned); + else + Ty = Literal.isUnsigned ? Context.UnsignedInt128Ty : Context.Int128Ty; + } + + if (Ty.isNull() && !Literal.isLong && !Literal.isLongLong) { // Are int/unsigned possibilities? unsigned IntSize = Context.getTargetInfo().getIntWidth(); @@ -3258,17 +3269,6 @@ Width = LongLongSize; } } - - // If it doesn't fit in unsigned long long, and we're using Microsoft - // extensions, then its a 128-bit integer literal. - if (Ty.isNull() && Literal.isMicrosoftInteger && - Context.getTargetInfo().hasInt128Type()) { - if (Literal.isUnsigned) - Ty = Context.UnsignedInt128Ty; - else - Ty = Context.Int128Ty; - Width = 128; - } // If we still couldn't decide a type, we probably have something that // does not fit in a signed long long, but has no U suffix. Index: cfe/trunk/test/SemaCXX/ms_integer_suffix.cpp =================================================================== --- cfe/trunk/test/SemaCXX/ms_integer_suffix.cpp +++ cfe/trunk/test/SemaCXX/ms_integer_suffix.cpp @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -fms-compatibility -verify %s +// expected-no-diagnostics + +static_assert(sizeof(0i8 ) == sizeof(__INT8_TYPE__ ), ""); +static_assert(sizeof(0i16 ) == sizeof(__INT16_TYPE__), ""); +static_assert(sizeof(0i32 ) == sizeof(__INT32_TYPE__), ""); +static_assert(sizeof(0i64 ) == sizeof(__INT64_TYPE__), ""); +static_assert(sizeof(0i128) > sizeof(__INT64_TYPE__), ""); Index: cfe/trunk/unittests/AST/StmtPrinterTest.cpp =================================================================== --- cfe/trunk/unittests/AST/StmtPrinterTest.cpp +++ cfe/trunk/unittests/AST/StmtPrinterTest.cpp @@ -134,6 +134,8 @@ StringRef ContainingFunction, StringRef ExpectedPrinted) { std::vector Args; + Args.push_back("-target"); + Args.push_back("i686-pc-win32"); Args.push_back("-std=c++98"); Args.push_back("-fms-extensions"); Args.push_back("-Wno-unused-value"); @@ -169,9 +171,9 @@ " 1i64, -1i64, 1ui64;" "}", "A", + "1i8 , -1i8 , 1Ui8 , " + "1i16 , -1i16 , 1Ui16 , " "1 , -1 , 1U , " - "1 , -1 , 1U , " - "1L , -1L , 1UL , " "1LL , -1LL , 1ULL")); // Should be: with semicolon }