diff --git a/clang/include/clang/Lex/LiteralSupport.h b/clang/include/clang/Lex/LiteralSupport.h --- a/clang/include/clang/Lex/LiteralSupport.h +++ b/clang/include/clang/Lex/LiteralSupport.h @@ -69,8 +69,8 @@ bool isImaginary : 1; // 1.0i bool isFloat16 : 1; // 1.0f16 bool isFloat128 : 1; // 1.0q - uint8_t MicrosoftInteger; // Microsoft suffix extension i8, i16, i32, or i64. - + uint8_t MicrosoftInteger; // Microsoft suffix extension i8, i16, i32, i64, or + // i128. bool isFract : 1; // 1.0hr/r/lr/uhr/ur/ulr bool isAccum : 1; // 1.0hk/k/lk/uhk/uk/ulk diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp --- a/clang/lib/AST/StmtPrinter.cpp +++ b/clang/lib/AST/StmtPrinter.cpp @@ -1168,9 +1168,13 @@ case BuiltinType::LongLong: OS << "LL"; break; case BuiltinType::ULongLong: OS << "ULL"; break; case BuiltinType::Int128: - break; // no suffix. + if (Context && Context->getLangOpts().MicrosoftExt) + OS << "i128"; + break; case BuiltinType::UInt128: - break; // no suffix. + if (Context && Context->getLangOpts().MicrosoftExt) + OS << "ui128"; + break; } } diff --git a/clang/lib/Lex/LiteralSupport.cpp b/clang/lib/Lex/LiteralSupport.cpp --- a/clang/lib/Lex/LiteralSupport.cpp +++ b/clang/lib/Lex/LiteralSupport.cpp @@ -849,7 +849,7 @@ case 'i': case 'I': if (LangOpts.MicrosoftExt && !isFPConstant) { - // Allow i8, i16, i32, and i64. First, look ahead and check if + // Allow i8, i16, i32, i64, and i128. First, look ahead and check if // suffixes are Microsoft integers and not the imaginary unit. uint8_t Bits = 0; size_t ToSkip = 0; @@ -859,7 +859,10 @@ ToSkip = 2; break; case '1': - if (s[2] == '6') { // i16 suffix + if (s[2] == '2' && s[3] == '8') { + Bits = 128; + ToSkip = 4; + } else if (s[2] == '6') { // i16 suffix Bits = 16; ToSkip = 3; } diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -3924,6 +3924,11 @@ // Get the value in the widest-possible width. unsigned MaxWidth = Context.getTargetInfo().getIntMaxTWidth(); + // Microsoft extensions allow a maximal integer greater than `intmax_t` via + // the `i128` suffix, creating a 128-bit integeral value with a 64-bit + // maximum integer type. + if (Literal.MicrosoftInteger) + MaxWidth = Literal.MicrosoftInteger; llvm::APInt ResultVal(MaxWidth, 0); if (Literal.GetIntegerValue(ResultVal)) { diff --git a/clang/test/Lexer/ms-extensions.c b/clang/test/Lexer/ms-extensions.c --- a/clang/test/Lexer/ms-extensions.c +++ b/clang/test/Lexer/ms-extensions.c @@ -23,6 +23,9 @@ #define USHORT 0xffffui16 #define UCHAR 0xffui8 +#define INT128_MAX 170141183460469231731687303715884105727i128 +#define UINT128_MAX 0xffffffffffffffffffffffffffffffffui128 + void a(void) { unsigned long long m = ULLONG_MAX; unsigned int n = UINT; diff --git a/clang/unittests/AST/StmtPrinterTest.cpp b/clang/unittests/AST/StmtPrinterTest.cpp --- a/clang/unittests/AST/StmtPrinterTest.cpp +++ b/clang/unittests/AST/StmtPrinterTest.cpp @@ -44,7 +44,7 @@ PrintingPolicy Policy = Context->getPrintingPolicy(); if (PolicyAdjuster) PolicyAdjuster(Policy); - S->printPretty(Out, /*Helper*/ nullptr, Policy); + S->printPretty(Out, /*Helper*/ nullptr, Policy, 0, "\n", Context); } template @@ -128,13 +128,15 @@ " 1i8, -1i8, 1ui8, " " 1i16, -1i16, 1ui16, " " 1i32, -1i32, 1ui32, " - " 1i64, -1i64, 1ui64;" + " 1i64, -1i64, 1ui64, " + " 1i128, -1i128, 1ui128;" "}", FunctionBodyMatcher("A"), "1i8 , -1i8 , 1Ui8 , " "1i16 , -1i16 , 1Ui16 , " "1 , -1 , 1U , " - "1LL , -1LL , 1ULL")); + "1LL , -1LL , 1ULL , " + "1i128 , -1i128 , 1ui128")); // Should be: with semicolon }