]> granicus.if.org Git - clang/commitdiff
The -fshort-wchar option causes wchar_t to become unsigned, in addition to being
authorChris Lattner <sabre@nondot.org>
Sat, 25 Dec 2010 23:25:43 +0000 (23:25 +0000)
committerChris Lattner <sabre@nondot.org>
Sat, 25 Dec 2010 23:25:43 +0000 (23:25 +0000)
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

18 files changed:
include/clang/AST/Type.h
include/clang/Basic/TargetInfo.h
include/clang/Frontend/TypeXML.def
lib/AST/ASTContext.cpp
lib/AST/ASTImporter.cpp
lib/AST/Type.cpp
lib/AST/TypeLoc.cpp
lib/Analysis/PrintfFormatString.cpp
lib/Basic/TargetInfo.cpp
lib/CodeGen/CGRTTI.cpp
lib/CodeGen/CodeGenTypes.cpp
lib/CodeGen/Mangle.cpp
lib/CodeGen/MicrosoftCXXABI.cpp
lib/Serialization/ASTCommon.cpp
test/CodeGen/pascal-wchar-string.c
tools/libclang/CIndex.cpp
tools/libclang/CIndexUSRs.cpp
tools/libclang/CXType.cpp

index 5e675cbe87c6afe1b9c116e8ae5af055664a3aba..208b23c7268aa293965ba7adfc7b113c03a6fbe4 100644 (file)
@@ -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,
index 3e81fdf0e94d1bf723aaa96b132347c6ff9c04bf..c22f094c468b3896e82fd12d8449ce4fdcebbbb5 100644 (file)
@@ -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.
index 68452ae267c865a626275d5f2ac83519e66a26ec..b78e70f5aa86ae4288f9b112690253c2787b10f4 100644 (file)
@@ -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'.
index b145683ce5e5cc82b52f3381f74d361b7492c621..eb6a8217839b6d16f6b9f8903f68787277766d2e 100644 (file)
@@ -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
index 7d6c90519b9ff10eda5af2d62a68e8b6367d9d82..08c1ea45f74b4626f8d796a6b2ad35063200bf9e 100644 (file)
@@ -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;
index 9dbbfaa733d3df02335a660aedc6dd6200fab948..257d114f25af61f5efca5bb650e03f42402edf80 100644 (file)
@@ -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";
index cde747d5075413e1c75c7f75ccff74a4d6de4747..1fe28560f91f28c01573e2c94b2d57e1864c37a7 100644 (file)
@@ -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;
index daaa072a70f35f7ff0282cc28f92d93caab381e5..ff688e07d3da8f120fd3624e9bbf30fc5a3ca0a3 100644 (file)
@@ -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);
index 6a19abfb4ff910030e093e7e215f941042d2090a..3828c5ae6b1ad71f8cc83674264da72595d32398 100644 (file)
@@ -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:
index a8893d1fc6e1c1c2a084b014b3e968adb3f79e7e..444062bbfff31f0e0b2eb0ada62287d35a4d2f67 100644 (file)
@@ -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:
index dde1322e3c2fbbfbc045e4136a476ab8562129b0..6658179d7f9f85638d72cef41024a0ad3c2047cf 100644 (file)
@@ -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(),
index 4659831a66dacc985296946477b6754f6ebc1b0b..a45403e467e226e9e6fd035e61848affd62f9c67 100644 (file)
@@ -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;
index aa9046f981b97e838d683326c95c12e3404302a9..875c66c2a474138ebb44ddc46fd487411213dfc4 100644 (file)
@@ -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:
index d5b7371086eca3d96dfc9933e3fa796390a4acae..858baba95ab83560064305bd505e20ad25c2bd4b 100644 (file)
@@ -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;
index 89e4de489f09f6b393445cb830f292b5695925eb..7a03463d2cf14b2709327c8b46cceeddf30f01e4 100644 (file)
@@ -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;
+}
index 61ff611a66bf15507041b3dcc44fb3a0a10de751..7e3c3432d5660e191117e4941e408ca110d30c63 100644 (file)
@@ -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:
index 5861ee6309dcf2d73fd80df71416fb54a3d9ead9..c96dad5cd0fe2e92325dfe25d7945d7c9eda8dd8 100644 (file)
@@ -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;
index 2fe360b3199931ad2306882a0c9249a302396523..e1297a43252140a09791930beccd22cf1a51c59e 100644 (file)
@@ -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);