зеркало из https://github.com/microsoft/clang-1.git
The -fshort-wchar option causes wchar_t to become unsigned, in addition to being
16-bits in size. Implement this by splitting WChar into two enums, like we have for char. This fixes a miscompmilation of XULRunner, PR8856. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@122558 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
af6530c938
Коммит
3f59c975aa
|
@ -1344,6 +1344,7 @@ public:
|
|||
Bool, // This is bool and/or _Bool.
|
||||
Char_U, // This is 'char' for targets where char is unsigned.
|
||||
UChar, // This is explicitly qualified unsigned char.
|
||||
WChar_U, // This is 'wchar_t' for C++, when unsigned.
|
||||
Char16, // This is 'char16_t' for C++.
|
||||
Char32, // This is 'char32_t' for C++.
|
||||
UShort,
|
||||
|
@ -1354,7 +1355,7 @@ public:
|
|||
|
||||
Char_S, // This is 'char' for targets where char is signed.
|
||||
SChar, // This is explicitly qualified signed char.
|
||||
WChar, // This is 'wchar_t' for C++.
|
||||
WChar_S, // This is 'wchar_t' for C++, when signed.
|
||||
Short,
|
||||
Int,
|
||||
Long,
|
||||
|
|
|
@ -151,7 +151,7 @@ public:
|
|||
|
||||
/// isTypeSigned - Return whether an integer types is signed. Returns true if
|
||||
/// the type is signed; false otherwise.
|
||||
bool isTypeSigned(IntType T) const;
|
||||
static bool isTypeSigned(IntType T);
|
||||
|
||||
/// getPointerWidth - Return the width of pointers on this target, for the
|
||||
/// specified address space.
|
||||
|
|
|
@ -98,7 +98,8 @@ NODE_XML(BuiltinType, "FundamentalType")
|
|||
ENUM_XML(BuiltinType::Float, "float");
|
||||
ENUM_XML(BuiltinType::Double, "double");
|
||||
ENUM_XML(BuiltinType::LongDouble, "long double");
|
||||
ENUM_XML(BuiltinType::WChar, "wchar_t");
|
||||
ENUM_XML(BuiltinType::WChar_U, "wchar_t");
|
||||
ENUM_XML(BuiltinType::WChar_S, "wchar_t");
|
||||
ENUM_XML(BuiltinType::Char16, "char16_t");
|
||||
ENUM_XML(BuiltinType::Char32, "char32_t");
|
||||
ENUM_XML(BuiltinType::NullPtr, "nullptr_t"); // This is the type of C++0x 'nullptr'.
|
||||
|
|
|
@ -316,9 +316,12 @@ void ASTContext::InitBuiltinTypes() {
|
|||
InitBuiltinType(Int128Ty, BuiltinType::Int128);
|
||||
InitBuiltinType(UnsignedInt128Ty, BuiltinType::UInt128);
|
||||
|
||||
if (LangOpts.CPlusPlus) // C++ 3.9.1p5
|
||||
InitBuiltinType(WCharTy, BuiltinType::WChar);
|
||||
else // C99
|
||||
if (LangOpts.CPlusPlus) { // C++ 3.9.1p5
|
||||
if (!LangOpts.ShortWChar)
|
||||
InitBuiltinType(WCharTy, BuiltinType::WChar_S);
|
||||
else // -fshort-wchar makes wchar_t be unsigned.
|
||||
InitBuiltinType(WCharTy, BuiltinType::WChar_U);
|
||||
} else // C99
|
||||
WCharTy = getFromTargetType(Target.getWCharType());
|
||||
|
||||
if (LangOpts.CPlusPlus) // C++0x 3.9.1p5, extension for C++
|
||||
|
@ -676,7 +679,8 @@ ASTContext::getTypeInfo(const Type *T) {
|
|||
Width = Target.getCharWidth();
|
||||
Align = Target.getCharAlign();
|
||||
break;
|
||||
case BuiltinType::WChar:
|
||||
case BuiltinType::WChar_S:
|
||||
case BuiltinType::WChar_U:
|
||||
Width = Target.getWCharWidth();
|
||||
Align = Target.getWCharAlign();
|
||||
break;
|
||||
|
@ -2946,7 +2950,8 @@ unsigned ASTContext::getIntegerRank(Type *T) {
|
|||
if (EnumType* ET = dyn_cast<EnumType>(T))
|
||||
T = ET->getDecl()->getPromotionType().getTypePtr();
|
||||
|
||||
if (T->isSpecificBuiltinType(BuiltinType::WChar))
|
||||
if (T->isSpecificBuiltinType(BuiltinType::WChar_S) ||
|
||||
T->isSpecificBuiltinType(BuiltinType::WChar_U))
|
||||
T = getFromTargetType(Target.getWCharType()).getTypePtr();
|
||||
|
||||
if (T->isSpecificBuiltinType(BuiltinType::Char16))
|
||||
|
@ -3731,7 +3736,8 @@ static char ObjCEncodingForPrimitiveKind(const ASTContext *C, QualType T) {
|
|||
case BuiltinType::Char_S:
|
||||
case BuiltinType::SChar: return 'c';
|
||||
case BuiltinType::Short: return 's';
|
||||
case BuiltinType::WChar:
|
||||
case BuiltinType::WChar_S:
|
||||
case BuiltinType::WChar_U:
|
||||
case BuiltinType::Int: return 'i';
|
||||
case BuiltinType::Long:
|
||||
return
|
||||
|
|
|
@ -1295,7 +1295,8 @@ QualType ASTNodeImporter::VisitBuiltinType(BuiltinType *T) {
|
|||
return Importer.getToContext().CharTy;
|
||||
|
||||
case BuiltinType::SChar: return Importer.getToContext().SignedCharTy;
|
||||
case BuiltinType::WChar:
|
||||
case BuiltinType::WChar_S:
|
||||
case BuiltinType::WChar_U:
|
||||
// FIXME: If not in C++, shall we translate to the C equivalent of
|
||||
// wchar_t?
|
||||
return Importer.getToContext().WCharTy;
|
||||
|
|
|
@ -524,20 +524,28 @@ bool Type::isCharType() const {
|
|||
|
||||
bool Type::isWideCharType() const {
|
||||
if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
|
||||
return BT->getKind() == BuiltinType::WChar;
|
||||
return BT->getKind() == BuiltinType::WChar_S ||
|
||||
BT->getKind() == BuiltinType::WChar_U;
|
||||
return false;
|
||||
}
|
||||
|
||||
/// \brief Determine whether this type is any of the built-in character
|
||||
/// types.
|
||||
bool Type::isAnyCharacterType() const {
|
||||
if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
|
||||
return (BT->getKind() >= BuiltinType::Char_U &&
|
||||
BT->getKind() <= BuiltinType::Char32) ||
|
||||
(BT->getKind() >= BuiltinType::Char_S &&
|
||||
BT->getKind() <= BuiltinType::WChar);
|
||||
|
||||
return false;
|
||||
const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType);
|
||||
if (BT == 0) return false;
|
||||
switch (BT->getKind()) {
|
||||
default: return false;
|
||||
case BuiltinType::Char_U:
|
||||
case BuiltinType::UChar:
|
||||
case BuiltinType::WChar_U:
|
||||
case BuiltinType::Char16:
|
||||
case BuiltinType::Char32:
|
||||
case BuiltinType::Char_S:
|
||||
case BuiltinType::SChar:
|
||||
case BuiltinType::WChar_S:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/// isSignedIntegerType - Return true if this is an integer type that is
|
||||
|
@ -1048,7 +1056,8 @@ const char *BuiltinType::getName(const LangOptions &LO) const {
|
|||
case Float: return "float";
|
||||
case Double: return "double";
|
||||
case LongDouble: return "long double";
|
||||
case WChar: return "wchar_t";
|
||||
case WChar_S:
|
||||
case WChar_U: return "wchar_t";
|
||||
case Char16: return "char16_t";
|
||||
case Char32: return "char32_t";
|
||||
case NullPtr: return "nullptr_t";
|
||||
|
|
|
@ -194,7 +194,8 @@ TypeSpecifierType BuiltinTypeLoc::getWrittenTypeSpec() const {
|
|||
return TST_char16;
|
||||
case BuiltinType::Char32:
|
||||
return TST_char32;
|
||||
case BuiltinType::WChar:
|
||||
case BuiltinType::WChar_S:
|
||||
case BuiltinType::WChar_U:
|
||||
return TST_wchar;
|
||||
case BuiltinType::UndeducedAuto:
|
||||
return TST_auto;
|
||||
|
|
|
@ -394,7 +394,8 @@ bool PrintfSpecifier::fixType(QualType QT) {
|
|||
LM.setKind(LengthModifier::AsShort);
|
||||
break;
|
||||
|
||||
case BuiltinType::WChar:
|
||||
case BuiltinType::WChar_S:
|
||||
case BuiltinType::WChar_U:
|
||||
case BuiltinType::Long:
|
||||
case BuiltinType::ULong:
|
||||
LM.setKind(LengthModifier::AsLong);
|
||||
|
|
|
@ -133,7 +133,7 @@ unsigned TargetInfo::getTypeAlign(IntType T) const {
|
|||
|
||||
/// isTypeSigned - Return whether an integer types is signed. Returns true if
|
||||
/// the type is signed; false otherwise.
|
||||
bool TargetInfo::isTypeSigned(IntType T) const {
|
||||
bool TargetInfo::isTypeSigned(IntType T) {
|
||||
switch (T) {
|
||||
default: assert(0 && "not an integer!");
|
||||
case SignedShort:
|
||||
|
|
|
@ -196,7 +196,8 @@ static bool TypeInfoIsInStandardLibrary(const BuiltinType *Ty) {
|
|||
case BuiltinType::Void:
|
||||
case BuiltinType::NullPtr:
|
||||
case BuiltinType::Bool:
|
||||
case BuiltinType::WChar:
|
||||
case BuiltinType::WChar_S:
|
||||
case BuiltinType::WChar_U:
|
||||
case BuiltinType::Char_U:
|
||||
case BuiltinType::Char_S:
|
||||
case BuiltinType::UChar:
|
||||
|
|
|
@ -228,7 +228,8 @@ const llvm::Type *CodeGenTypes::ConvertNewType(QualType T) {
|
|||
case BuiltinType::ULong:
|
||||
case BuiltinType::LongLong:
|
||||
case BuiltinType::ULongLong:
|
||||
case BuiltinType::WChar:
|
||||
case BuiltinType::WChar_S:
|
||||
case BuiltinType::WChar_U:
|
||||
case BuiltinType::Char16:
|
||||
case BuiltinType::Char32:
|
||||
return llvm::IntegerType::get(getLLVMContext(),
|
||||
|
|
|
@ -1233,7 +1233,8 @@ void CXXNameMangler::mangleType(const BuiltinType *T) {
|
|||
case BuiltinType::ULongLong: Out << 'y'; break;
|
||||
case BuiltinType::UInt128: Out << 'o'; break;
|
||||
case BuiltinType::SChar: Out << 'a'; break;
|
||||
case BuiltinType::WChar: Out << 'w'; break;
|
||||
case BuiltinType::WChar_S:
|
||||
case BuiltinType::WChar_U: Out << 'w'; break;
|
||||
case BuiltinType::Char16: Out << "Ds"; break;
|
||||
case BuiltinType::Char32: Out << "Di"; break;
|
||||
case BuiltinType::Short: Out << 's'; break;
|
||||
|
|
|
@ -756,7 +756,8 @@ void MicrosoftCXXNameMangler::mangleType(const BuiltinType *T) {
|
|||
case BuiltinType::Int128: Out << "_L"; break;
|
||||
case BuiltinType::UInt128: Out << "_M"; break;
|
||||
case BuiltinType::Bool: Out << "_N"; break;
|
||||
case BuiltinType::WChar: Out << "_W"; break;
|
||||
case BuiltinType::WChar_S:
|
||||
case BuiltinType::WChar_U: Out << "_W"; break;
|
||||
|
||||
case BuiltinType::Overload:
|
||||
case BuiltinType::Dependent:
|
||||
|
|
|
@ -36,7 +36,8 @@ serialization::TypeIdxFromBuiltin(const BuiltinType *BT) {
|
|||
case BuiltinType::UInt128: ID = PREDEF_TYPE_UINT128_ID; break;
|
||||
case BuiltinType::Char_S: ID = PREDEF_TYPE_CHAR_S_ID; break;
|
||||
case BuiltinType::SChar: ID = PREDEF_TYPE_SCHAR_ID; break;
|
||||
case BuiltinType::WChar: ID = PREDEF_TYPE_WCHAR_ID; break;
|
||||
case BuiltinType::WChar_S:
|
||||
case BuiltinType::WChar_U: ID = PREDEF_TYPE_WCHAR_ID; break;
|
||||
case BuiltinType::Short: ID = PREDEF_TYPE_SHORT_ID; break;
|
||||
case BuiltinType::Int: ID = PREDEF_TYPE_INT_ID; break;
|
||||
case BuiltinType::Long: ID = PREDEF_TYPE_LONG_ID; break;
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
// RUN: %clang_cc1 -emit-llvm -o - %s -fpascal-strings -fshort-wchar | FileCheck %s
|
||||
// rdar: // 8020384
|
||||
// rdar://8020384
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
extern void abort (void);
|
||||
|
||||
|
@ -29,3 +31,11 @@ int main(int argc, char* argv[])
|
|||
|
||||
// CHECK: c"\03\00b\00a\00r\00\00\00"
|
||||
// CHECK: c"\04\00g\00o\00r\00f\00\00\00"
|
||||
|
||||
|
||||
// PR8856 - -fshort-wchar makes wchar_t be unsigned.
|
||||
// CHECK: @test2
|
||||
// CHECK: volatile store i32 1, i32* %isUnsigned
|
||||
void test2() {
|
||||
volatile int isUnsigned = (wchar_t)-1 > (wchar_t)0;
|
||||
}
|
||||
|
|
|
@ -1291,7 +1291,8 @@ bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
|
|||
case BuiltinType::UInt128:
|
||||
case BuiltinType::Char_S:
|
||||
case BuiltinType::SChar:
|
||||
case BuiltinType::WChar:
|
||||
case BuiltinType::WChar_U:
|
||||
case BuiltinType::WChar_S:
|
||||
case BuiltinType::Short:
|
||||
case BuiltinType::Int:
|
||||
case BuiltinType::Long:
|
||||
|
|
|
@ -550,7 +550,8 @@ void USRGenerator::VisitType(QualType T) {
|
|||
case BuiltinType::Char_S:
|
||||
case BuiltinType::SChar:
|
||||
c = 'C'; break;
|
||||
case BuiltinType::WChar:
|
||||
case BuiltinType::WChar_S:
|
||||
case BuiltinType::WChar_U:
|
||||
c = 'W'; break;
|
||||
case BuiltinType::Short:
|
||||
c = 'S'; break;
|
||||
|
|
|
@ -41,7 +41,8 @@ static CXTypeKind GetBuiltinTypeKind(const BuiltinType *BT) {
|
|||
BTCASE(UInt128);
|
||||
BTCASE(Char_S);
|
||||
BTCASE(SChar);
|
||||
BTCASE(WChar);
|
||||
case BuiltinType::WChar_S: return CXType_WChar;
|
||||
case BuiltinType::WChar_U: return CXType_WChar;
|
||||
BTCASE(Short);
|
||||
BTCASE(Int);
|
||||
BTCASE(Long);
|
||||
|
@ -286,7 +287,7 @@ CXString clang_getTypeKindSpelling(enum CXTypeKind K) {
|
|||
TKIND(UInt128);
|
||||
TKIND(Char_S);
|
||||
TKIND(SChar);
|
||||
TKIND(WChar);
|
||||
case CXType_WChar: s = "WChar"; break;
|
||||
TKIND(Short);
|
||||
TKIND(Int);
|
||||
TKIND(Long);
|
||||
|
|
Загрузка…
Ссылка в новой задаче