Add support for __wchar_t in -fms-extensions mode.
MSVC provides __wchar_t. This is the same as the built-in wchar_t type
from C++, but it is also available with -fno-wchar and in C.
The commit changes ASTContext to have two different types for this:
- WCharTy is the built-in type used for wchar_t in C++ and __wchar_t.
- WideCharTy is the type of a wide character literal. In C++ this is
the same as WCharTy, and in C it is an integer type compatible with
the type in <stddef.h>.
This fixes PR15815.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@181587 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index ffcf6b5..960f261 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -897,13 +897,17 @@
InitBuiltinType(Int128Ty, BuiltinType::Int128);
InitBuiltinType(UnsignedInt128Ty, BuiltinType::UInt128);
- if (LangOpts.CPlusPlus && LangOpts.WChar) { // C++ 3.9.1p5
- if (TargetInfo::isTypeSigned(Target.getWCharType()))
- InitBuiltinType(WCharTy, BuiltinType::WChar_S);
- else // -fshort-wchar makes wchar_t be unsigned.
- InitBuiltinType(WCharTy, BuiltinType::WChar_U);
- } else // C99 (or C++ using -fno-wchar)
- WCharTy = getFromTargetType(Target.getWCharType());
+ // C++ 3.9.1p5
+ if (TargetInfo::isTypeSigned(Target.getWCharType()))
+ InitBuiltinType(WCharTy, BuiltinType::WChar_S);
+ else // -fshort-wchar makes wchar_t be unsigned.
+ InitBuiltinType(WCharTy, BuiltinType::WChar_U);
+ if (LangOpts.CPlusPlus && LangOpts.WChar)
+ WideCharTy = WCharTy;
+ else {
+ // C99 (or C++ using -fno-wchar).
+ WideCharTy = getFromTargetType(Target.getWCharType());
+ }
WIntTy = getFromTargetType(Target.getWIntType());
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp
index fa16fac..a1f0b08 100644
--- a/lib/AST/Type.cpp
+++ b/lib/AST/Type.cpp
@@ -1521,7 +1521,7 @@
case Double: return "double";
case LongDouble: return "long double";
case WChar_S:
- case WChar_U: return "wchar_t";
+ case WChar_U: return Policy.MSWChar ? "__wchar_t" : "wchar_t";
case Char16: return "char16_t";
case Char32: return "char32_t";
case NullPtr: return "nullptr_t";
diff --git a/lib/Analysis/FormatString.cpp b/lib/Analysis/FormatString.cpp
index ad0dce4..382be24 100644
--- a/lib/Analysis/FormatString.cpp
+++ b/lib/Analysis/FormatString.cpp
@@ -334,7 +334,7 @@
return false;
QualType pointeeTy =
C.getCanonicalType(PT->getPointeeType()).getUnqualifiedType();
- return pointeeTy == C.getWCharType();
+ return pointeeTy == C.getWideCharType();
}
case WIntTy: {
@@ -398,7 +398,7 @@
Res = C.getPointerType(C.CharTy);
break;
case WCStrTy:
- Res = C.getPointerType(C.getWCharType());
+ Res = C.getPointerType(C.getWideCharType());
break;
case ObjCPointerTy:
Res = C.ObjCBuiltinIdTy;
diff --git a/lib/Analysis/PrintfFormatString.cpp b/lib/Analysis/PrintfFormatString.cpp
index 8f151b9..60f9517 100644
--- a/lib/Analysis/PrintfFormatString.cpp
+++ b/lib/Analysis/PrintfFormatString.cpp
@@ -372,7 +372,7 @@
case ConversionSpecifier::CArg:
if (IsObjCLiteral)
return ArgType(Ctx.UnsignedShortTy, "unichar");
- return ArgType(Ctx.WCharTy, "wchar_t");
+ return ArgType(Ctx.WideCharTy, "wchar_t");
case ConversionSpecifier::pArg:
return ArgType::CPointerTy;
case ConversionSpecifier::ObjCObjArg:
diff --git a/lib/Analysis/ScanfFormatString.cpp b/lib/Analysis/ScanfFormatString.cpp
index 2dbc9e4..676b68f 100644
--- a/lib/Analysis/ScanfFormatString.cpp
+++ b/lib/Analysis/ScanfFormatString.cpp
@@ -311,7 +311,7 @@
case LengthModifier::None:
return ArgType::PtrTo(ArgType::AnyCharTy);
case LengthModifier::AsLong:
- return ArgType::PtrTo(ArgType(Ctx.getWCharType(), "wchar_t"));
+ return ArgType::PtrTo(ArgType(Ctx.getWideCharType(), "wchar_t"));
case LengthModifier::AsAllocate:
case LengthModifier::AsMAllocate:
return ArgType::PtrTo(ArgType::CStrTy);
@@ -323,7 +323,7 @@
// FIXME: Mac OS X specific?
switch (LM.getKind()) {
case LengthModifier::None:
- return ArgType::PtrTo(ArgType(Ctx.getWCharType(), "wchar_t"));
+ return ArgType::PtrTo(ArgType(Ctx.getWideCharType(), "wchar_t"));
case LengthModifier::AsAllocate:
case LengthModifier::AsMAllocate:
return ArgType::PtrTo(ArgType(ArgType::WCStrTy, "wchar_t *"));
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index b86a2b9..e5d0316 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -10408,7 +10408,7 @@
if (Context.hasSameType(T, Context.UnsignedLongLongTy) ||
Context.hasSameType(T, Context.LongDoubleTy) ||
Context.hasSameType(T, Context.CharTy) ||
- Context.hasSameType(T, Context.WCharTy) ||
+ Context.hasSameType(T, Context.WideCharTy) ||
Context.hasSameType(T, Context.Char16Ty) ||
Context.hasSameType(T, Context.Char32Ty)) {
if (++Param == FnDecl->param_end())
@@ -10438,7 +10438,7 @@
// const char *, const wchar_t*, const char16_t*, and const char32_t*
// are allowed as the first parameter to a two-parameter function
if (!(Context.hasSameType(T, Context.CharTy) ||
- Context.hasSameType(T, Context.WCharTy) ||
+ Context.hasSameType(T, Context.WideCharTy) ||
Context.hasSameType(T, Context.Char16Ty) ||
Context.hasSameType(T, Context.Char32Ty)))
goto FinishedParams;
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 031a631..ef7e0f2 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -1448,7 +1448,7 @@
QualType StrTy = Context.CharTy;
if (Literal.isWide())
- StrTy = Context.getWCharType();
+ StrTy = Context.getWideCharType();
else if (Literal.isUTF16())
StrTy = Context.Char16Ty;
else if (Literal.isUTF32())
@@ -2720,7 +2720,7 @@
llvm::APInt LengthI(32, Length + 1);
if (IT == PredefinedExpr::LFunction)
- ResTy = Context.WCharTy.withConst();
+ ResTy = Context.WideCharTy.withConst();
else
ResTy = Context.CharTy.withConst();
ResTy = Context.getConstantArrayType(ResTy, LengthI, ArrayType::Normal, 0);
@@ -2742,7 +2742,7 @@
QualType Ty;
if (Literal.isWide())
- Ty = Context.WCharTy; // L'x' -> wchar_t in C and C++.
+ Ty = Context.WideCharTy; // L'x' -> wchar_t in C and C++.
else if (Literal.isUTF16())
Ty = Context.Char16Ty; // u'x' -> char16_t in C11 and C++11.
else if (Literal.isUTF32())
diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp
index 0e3dc00..d37f61a 100644
--- a/lib/Sema/SemaExprObjC.cpp
+++ b/lib/Sema/SemaExprObjC.cpp
@@ -266,7 +266,7 @@
break;
case CharacterLiteral::Wide:
- NumberType = Context.getWCharType();
+ NumberType = Context.getWideCharType();
break;
case CharacterLiteral::UTF16:
@@ -521,7 +521,7 @@
break;
case CharacterLiteral::Wide:
- ValueType = Context.getWCharType();
+ ValueType = Context.getWideCharType();
break;
case CharacterLiteral::UTF16:
diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp
index 9e8936e..7016e56 100644
--- a/lib/Sema/SemaInit.cpp
+++ b/lib/Sema/SemaInit.cpp
@@ -65,7 +65,7 @@
// correction from DR343): "An array with element type compatible with a
// qualified or unqualified version of wchar_t may be initialized by a wide
// string literal, optionally enclosed in braces."
- if (Context.typesAreCompatible(Context.getWCharType(),
+ if (Context.typesAreCompatible(Context.getWideCharType(),
ElemTy.getUnqualifiedType()))
return Init;
diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp
index 7ef04e9..862334a 100644
--- a/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/lib/Sema/SemaTemplateInstantiate.cpp
@@ -1105,7 +1105,7 @@
llvm::APInt LengthI(32, Length + 1);
QualType ResTy;
if (IT == PredefinedExpr::LFunction)
- ResTy = getSema().Context.WCharTy.withConst();
+ ResTy = getSema().Context.WideCharTy.withConst();
else
ResTy = getSema().Context.CharTy.withConst();
ResTy = getSema().Context.getConstantArrayType(ResTy, LengthI,