summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2014-06-21 18:46:07 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2014-06-21 18:46:07 +0000
commit52ce795128022a5350050f7b8cd76cf56227c8ca (patch)
tree6b19d7d8cb644dc5c3970281280174aa84dd8fad
parente26b3797f8baf47892aafd9d06fac8cc6235dafc (diff)
downloadclang-52ce795128022a5350050f7b8cd76cf56227c8ca.tar.gz
clang-52ce795128022a5350050f7b8cd76cf56227c8ca.tar.bz2
clang-52ce795128022a5350050f7b8cd76cf56227c8ca.tar.xz
Lex: Use the correct types for MS integer suffixes
Something went wrong with r211426, it is an older version of this code and should not have been committed. It was reverted with r211434. Original commit message: We didn't properly implement support for the sized integer suffixes. Suffixes like i16 were essentially ignored instead of mapping them to the appropriately sized integer type. This fixes PR20008. Differential Revision: http://reviews.llvm.org/D4132 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@211441 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/Lex/LiteralSupport.h2
-rw-r--r--lib/AST/StmtPrinter.cpp9
-rw-r--r--lib/Lex/LiteralSupport.cpp21
-rw-r--r--lib/Sema/SemaExpr.cpp30
-rw-r--r--test/SemaCXX/ms_integer_suffix.cpp18
-rw-r--r--unittests/AST/StmtPrinterTest.cpp6
6 files changed, 54 insertions, 32 deletions
diff --git a/include/clang/Lex/LiteralSupport.h b/include/clang/Lex/LiteralSupport.h
index 2eb7751f3c..acfd174b63 100644
--- a/include/clang/Lex/LiteralSupport.h
+++ b/include/clang/Lex/LiteralSupport.h
@@ -63,7 +63,7 @@ public:
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;
diff --git a/lib/AST/StmtPrinter.cpp b/lib/AST/StmtPrinter.cpp
index 0f4fd55246..2d7c78a885 100644
--- a/lib/AST/StmtPrinter.cpp
+++ b/lib/AST/StmtPrinter.cpp
@@ -944,11 +944,10 @@ void StmtPrinter::VisitIntegerLiteral(IntegerLiteral *Node) {
// Emit suffixes. Integer literals are always a builtin integer type.
switch (Node->getType()->getAs<BuiltinType>()->getKind()) {
default: llvm_unreachable("Unexpected type for integer literal!");
- // 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;
diff --git a/lib/Lex/LiteralSupport.cpp b/lib/Lex/LiteralSupport.cpp
index 0103450cca..c55054be30 100644
--- a/lib/Lex/LiteralSupport.cpp
+++ b/lib/Lex/LiteralSupport.cpp
@@ -522,7 +522,7 @@ NumericLiteralParser::NumericLiteralParser(StringRef TokSpelling,
isLongLong = false;
isFloat = false;
isImaginary = false;
- isMicrosoftInteger = false;
+ MicrosoftInteger = 0;
hadError = false;
if (*s == '0') { // parse radix
@@ -606,7 +606,8 @@ NumericLiteralParser::NumericLiteralParser(StringRef TokSpelling,
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 @@ NumericLiteralParser::NumericLiteralParser(StringRef TokSpelling,
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 @@ NumericLiteralParser::NumericLiteralParser(StringRef TokSpelling,
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 @@ NumericLiteralParser::NumericLiteralParser(StringRef TokSpelling,
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 @@ NumericLiteralParser::NumericLiteralParser(StringRef TokSpelling,
isLongLong = false;
isFloat = false;
isImaginary = false;
- isMicrosoftInteger = false;
+ MicrosoftInteger = 0;
saw_ud_suffix = true;
return;
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 2654c390cc..bda80cd205 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -3190,7 +3190,7 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) {
// 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 == 128 && MaxWidth < 128 &&
Context.getTargetInfo().hasInt128Type())
MaxWidth = 128;
llvm::APInt ResultVal(MaxWidth, 0);
@@ -3211,7 +3211,22 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) {
// 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) {
+ if (Literal.MicrosoftInteger > MaxWidth) {
+ // If this target doesn't support __int128, error and force to ull.
+ Diag(Tok.getLocation(), diag::err_int128_unsupported);
+ Width = MaxWidth;
+ Ty = Context.getIntMaxType();
+ } else {
+ Width = Literal.MicrosoftInteger;
+ Ty = Context.getIntTypeForBitwidth(Width,
+ /*Signed=*/!Literal.isUnsigned);
+ }
+ }
+
+ if (Ty.isNull() && !Literal.isLong && !Literal.isLongLong) {
// Are int/unsigned possibilities?
unsigned IntSize = Context.getTargetInfo().getIntWidth();
@@ -3258,17 +3273,6 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) {
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.
diff --git a/test/SemaCXX/ms_integer_suffix.cpp b/test/SemaCXX/ms_integer_suffix.cpp
new file mode 100644
index 0000000000..6b4594dd5b
--- /dev/null
+++ b/test/SemaCXX/ms_integer_suffix.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -fms-extensions -verify %s
+// expected-no-diagnostics
+
+#ifdef __SIZEOF_INT8__
+static_assert(sizeof(0i8) == __SIZEOF_INT8__, "");
+#endif
+#ifdef __SIZEOF_INT16__
+static_assert(sizeof(0i16) == __SIZEOF_INT16__, "");
+#endif
+#ifdef __SIZEOF_INT32__
+static_assert(sizeof(0i32) == __SIZEOF_INT32__, "");
+#endif
+#ifdef __SIZEOF_INT64__
+static_assert(sizeof(0i64) == __SIZEOF_INT64__, "");
+#endif
+#ifdef __SIZEOF_INT128__
+static_assert(sizeof(0i128) == __SIZEOF_INT128__, "");
+#endif
diff --git a/unittests/AST/StmtPrinterTest.cpp b/unittests/AST/StmtPrinterTest.cpp
index c75cbdefbf..541fb3df1d 100644
--- a/unittests/AST/StmtPrinterTest.cpp
+++ b/unittests/AST/StmtPrinterTest.cpp
@@ -134,6 +134,8 @@ PrintedStmtCXX11Matches(StringRef Code, const StatementMatcher &NodeMatch,
StringRef ContainingFunction,
StringRef ExpectedPrinted) {
std::vector<std::string> 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 @@ TEST(StmtPrinter, TestMSIntegerLiteral) {
" 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
}