]> granicus.if.org Git - clang/commitdiff
Implement support for the 'wchar_t' C++ type.
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>
Sat, 9 Aug 2008 16:51:54 +0000 (16:51 +0000)
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>
Sat, 9 Aug 2008 16:51:54 +0000 (16:51 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@54585 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/ASTContext.h
include/clang/AST/Type.h
include/clang/Basic/DiagnosticKinds.def
include/clang/Parse/DeclSpec.h
lib/AST/ASTContext.cpp
lib/Parse/DeclSpec.cpp
lib/Parse/ParseDecl.cpp
lib/Sema/SemaType.cpp
test/Sema/cxx-wchar_t.cpp [new file with mode: 0644]

index 2c1e1e4ec67305e81627617d3b83a2ac12c02646..1d4c2a351af17ca14230d2e434d338852416860d 100644 (file)
@@ -118,6 +118,7 @@ public:
   QualType VoidTy;
   QualType BoolTy;
   QualType CharTy;
+  QualType WCharTy; // [C++ 3.9.1p5]
   QualType SignedCharTy, ShortTy, IntTy, LongTy, LongLongTy;
   QualType UnsignedCharTy, UnsignedShortTy, UnsignedIntTy, UnsignedLongTy;
   QualType UnsignedLongLongTy;
@@ -236,6 +237,14 @@ public:
   /// getWcharType - Return the unique type for "wchar_t" (C99 7.17), defined
   /// in <stddef.h>. Wide strings require this (C99 6.4.5p5).
   QualType getWcharType() const;
+
+  /// getSignedWCharType - Return the type of "signed wchar_t".
+  /// Used when in C++, as a GCC extension.
+  QualType getSignedWCharType() const;
+
+  /// getUnsignedWCharType - Return the type of "unsigned wchar_t".
+  /// Used when in C++, as a GCC extension.
+  QualType getUnsignedWCharType() const;
   
   /// getPointerDiffType - Return the unique type for "ptrdiff_t" (ref?)
   /// defined in <stddef.h>. Pointer - pointer requires this (C99 6.5.6p9).
index 21541792d58edae4606e9b73761be0e342181a06..502b387ac2c2cd0de11054fce7ff8b763968cb48 100644 (file)
@@ -476,7 +476,9 @@ public:
     Long,
     LongLong,
     
-    Float, Double, LongDouble
+    Float, Double, LongDouble,
+
+    WChar     // This is 'wchar_t' for C++.
   };
 private:
   Kind TypeKind;
index 7afe5723a4e24787382e993548cf54fb0198c979..076ccce0d024169f89a048d8ed8bcf067c8f4a20 100644 (file)
@@ -571,6 +571,8 @@ DIAG(err_invalid_decl_spec_combination, ERROR,
      "cannot combine with previous '%0' declaration specifier")
 DIAG(err_invalid_sign_spec, ERROR,
      "'%0' cannot be signed or unsigned")
+DIAG(ext_invalid_sign_spec, EXTENSION,
+     "'%0' cannot be signed or unsigned")
 DIAG(err_invalid_short_spec, ERROR,
      "'short %0' is invalid")
 DIAG(err_invalid_long_spec, ERROR,
index acae7a3ad3520b866a9254c3f305b6867de993be..df5109d196f7ff41d6b81b22eee857d5d77aec5c 100644 (file)
@@ -63,6 +63,7 @@ public:
     TST_unspecified,
     TST_void,
     TST_char,
+    TST_wchar,        // C++ wchar_t
     TST_int,
     TST_float,
     TST_double,
index f47855a5c6ed6560ad2aaf163a15112d0c053b46..fef85b540c25cfdaf1a7a2264d1729824d0dd018 100644 (file)
@@ -161,7 +161,10 @@ void ASTContext::InitBuiltinTypes() {
   InitBuiltinType(FloatTy,             BuiltinType::Float);
   InitBuiltinType(DoubleTy,            BuiltinType::Double);
   InitBuiltinType(LongDoubleTy,        BuiltinType::LongDouble);
-  
+
+  // C++ 3.9.1p5
+  InitBuiltinType(WCharTy,             BuiltinType::WChar);
+
   // C99 6.2.5p11.
   FloatComplexTy      = getComplexType(FloatTy);
   DoubleComplexTy     = getComplexType(DoubleTy);
@@ -246,6 +249,10 @@ ASTContext::getTypeInfo(QualType T) {
       Width = Target.getCharWidth();
       Align = Target.getCharAlign();
       break;
+    case BuiltinType::WChar:
+      Width = Target.getWCharWidth();
+      Align = Target.getWCharAlign();
+      break;
     case BuiltinType::UShort:
     case BuiltinType::Short:
       Width = Target.getShortWidth();
@@ -996,11 +1003,28 @@ QualType ASTContext::getSizeType() const {
 /// width of characters in wide strings, The value is target dependent and 
 /// needs to agree with the definition in <stddef.h>.
 QualType ASTContext::getWcharType() const {
+  if (LangOpts.CPlusPlus)
+    return WCharTy;
+
   // On Darwin, wchar_t is defined as a "int". 
   // FIXME: should derive from "Target".
   return IntTy; 
 }
 
+/// getSignedWCharType - Return the type of "signed wchar_t".
+/// Used when in C++, as a GCC extension.
+QualType ASTContext::getSignedWCharType() const {
+  // FIXME: derive from "Target" ?
+  return WCharTy;
+}
+
+/// getUnsignedWCharType - Return the type of "unsigned wchar_t".
+/// Used when in C++, as a GCC extension.
+QualType ASTContext::getUnsignedWCharType() const {
+  // FIXME: derive from "Target" ?
+  return UnsignedIntTy;
+}
+
 /// getPointerDiffType - Return the unique type for "ptrdiff_t" (ref?)
 /// defined in <stddef.h>. Pointer - pointer requires this (C99 6.5.6p9).
 QualType ASTContext::getPointerDiffType() const {
index 8e6dacb761d3914265f3e90e3cdd687660ca8386..d97dcfac807ef76f2e0dcc92c43333e32bf8ad57 100644 (file)
@@ -87,6 +87,7 @@ const char *DeclSpec::getSpecifierName(DeclSpec::TST T) {
   case DeclSpec::TST_unspecified: return "unspecified";
   case DeclSpec::TST_void:        return "void";
   case DeclSpec::TST_char:        return "char";
+  case DeclSpec::TST_wchar:       return "wchar_t";
   case DeclSpec::TST_int:         return "int";
   case DeclSpec::TST_float:       return "float";
   case DeclSpec::TST_double:      return "double";
@@ -214,11 +215,12 @@ void DeclSpec::Finish(Diagnostic &D, SourceManager& SrcMgr,
                       const LangOptions &Lang) {
   // Check the type specifier components first.
 
-  // signed/unsigned are only valid with int/char.
+  // signed/unsigned are only valid with int/char/wchar_t.
   if (TypeSpecSign != TSS_unspecified) {
     if (TypeSpecType == TST_unspecified)
       TypeSpecType = TST_int; // unsigned -> unsigned int, signed -> signed int.
-    else if (TypeSpecType != TST_int && TypeSpecType != TST_char) {
+    else if (TypeSpecType != TST_int  &&
+             TypeSpecType != TST_char && TypeSpecType != TST_wchar) {
       Diag(D, TSSLoc, SrcMgr, diag::err_invalid_sign_spec,
            getSpecifierName( (TST)TypeSpecType));
       // signed double -> double.
index 1cf331702d99424e75a9c278fd3613ceb6dfdbda..5b4473ea4de5dfa5d8ca8655d3251b4dd98a7467 100644 (file)
@@ -376,6 +376,7 @@ void Parser::ParseSpecifierQualifierList(DeclSpec &DS) {
 ///         struct-or-union-specifier
 ///         enum-specifier
 ///         typedef-name
+/// [C++]   'wchar_t'
 /// [C++]   'bool'
 /// [C99]   '_Bool'
 /// [C99]   '_Complex'
@@ -517,6 +518,9 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS) {
     case tok::kw_double:
       isInvalid = DS.SetTypeSpecType(DeclSpec::TST_double, Loc, PrevSpec);
       break;
+    case tok::kw_wchar_t:       // [C++ 2.11p1]
+      isInvalid = DS.SetTypeSpecType(DeclSpec::TST_wchar, Loc, PrevSpec);
+      break;
     case tok::kw_bool:          // [C++ 2.11p1]
     case tok::kw__Bool:
       isInvalid = DS.SetTypeSpecType(DeclSpec::TST_bool, Loc, PrevSpec);
@@ -941,6 +945,7 @@ bool Parser::isTypeSpecifierQualifier() const {
   case tok::kw__Imaginary:
   case tok::kw_void:
   case tok::kw_char:
+  case tok::kw_wchar_t:
   case tok::kw_int:
   case tok::kw_float:
   case tok::kw_double:
@@ -992,6 +997,7 @@ bool Parser::isDeclarationSpecifier() const {
   case tok::kw__Imaginary:
   case tok::kw_void:
   case tok::kw_char:
+  case tok::kw_wchar_t:
   case tok::kw_int:
   case tok::kw_float:
   case tok::kw_double:
index 7acb4587a0ba2a98bcadfd6571356b41be8d292c..bda8932ef471e3dda5c6e6e297ebaf3257c405d8 100644 (file)
@@ -42,6 +42,21 @@ QualType Sema::ConvertDeclSpecToType(const DeclSpec &DS) {
       Result = Context.UnsignedCharTy;
     }
     break;
+  case DeclSpec::TST_wchar:
+    if (DS.getTypeSpecSign() == DeclSpec::TSS_unspecified)
+      Result = Context.WCharTy;
+    else if (DS.getTypeSpecSign() == DeclSpec::TSS_signed) {
+      Diag(DS.getTypeSpecSignLoc(), diag::ext_invalid_sign_spec,
+           DS.getSpecifierName(DS.getTypeSpecType()));
+      Result = Context.getSignedWCharType();
+    } else {
+      assert(DS.getTypeSpecSign() == DeclSpec::TSS_unsigned &&
+        "Unknown TSS value");
+      Diag(DS.getTypeSpecSignLoc(), diag::ext_invalid_sign_spec,
+           DS.getSpecifierName(DS.getTypeSpecType()));
+      Result = Context.getUnsignedWCharType();
+    }
+    break;
   case DeclSpec::TST_unspecified:
     // "<proto1,proto2>" is an objc qualified ID with a missing id.
       if (DeclSpec::ProtocolQualifierListTy PQ = DS.getProtocolQualifiers()) {
diff --git a/test/Sema/cxx-wchar_t.cpp b/test/Sema/cxx-wchar_t.cpp
new file mode 100644 (file)
index 0000000..43dd6ee
--- /dev/null
@@ -0,0 +1,8 @@
+// RUN: clang -fsyntax-only -pedantic -verify %s 
+wchar_t x;
+
+void f(wchar_t p) {
+  wchar_t x;
+  unsigned wchar_t y; // expected-warning {{'wchar_t' cannot be signed or unsigned}}
+  signed wchar_t z; // expected-warning {{'wchar_t' cannot be signed or unsigned}}
+}