diff options
| author | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2008-08-09 16:51:54 +0000 | 
|---|---|---|
| committer | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2008-08-09 16:51:54 +0000 | 
| commit | 40e9e4828fe064f9375851e9dba04ec2d2a43a80 (patch) | |
| tree | b5c3ef636c241f2feb8f63df7aa8c4776583dc96 | |
| parent | 239255d2a6f0c568450aff21c09a4eb91ad10bef (diff) | |
| download | bcm5719-llvm-40e9e4828fe064f9375851e9dba04ec2d2a43a80.tar.gz bcm5719-llvm-40e9e4828fe064f9375851e9dba04ec2d2a43a80.zip | |
Implement support for the 'wchar_t' C++ type.
llvm-svn: 54585
| -rw-r--r-- | clang/include/clang/AST/ASTContext.h | 9 | ||||
| -rw-r--r-- | clang/include/clang/AST/Type.h | 4 | ||||
| -rw-r--r-- | clang/include/clang/Basic/DiagnosticKinds.def | 2 | ||||
| -rw-r--r-- | clang/include/clang/Parse/DeclSpec.h | 1 | ||||
| -rw-r--r-- | clang/lib/AST/ASTContext.cpp | 26 | ||||
| -rw-r--r-- | clang/lib/Parse/DeclSpec.cpp | 6 | ||||
| -rw-r--r-- | clang/lib/Parse/ParseDecl.cpp | 6 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaType.cpp | 15 | ||||
| -rw-r--r-- | clang/test/Sema/cxx-wchar_t.cpp | 8 | 
9 files changed, 73 insertions, 4 deletions
| diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index 2c1e1e4ec67..1d4c2a351af 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -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). diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h index 21541792d58..502b387ac2c 100644 --- a/clang/include/clang/AST/Type.h +++ b/clang/include/clang/AST/Type.h @@ -476,7 +476,9 @@ public:      Long,      LongLong, -    Float, Double, LongDouble +    Float, Double, LongDouble, + +    WChar     // This is 'wchar_t' for C++.    };  private:    Kind TypeKind; diff --git a/clang/include/clang/Basic/DiagnosticKinds.def b/clang/include/clang/Basic/DiagnosticKinds.def index 7afe5723a4e..076ccce0d02 100644 --- a/clang/include/clang/Basic/DiagnosticKinds.def +++ b/clang/include/clang/Basic/DiagnosticKinds.def @@ -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, diff --git a/clang/include/clang/Parse/DeclSpec.h b/clang/include/clang/Parse/DeclSpec.h index acae7a3ad35..df5109d196f 100644 --- a/clang/include/clang/Parse/DeclSpec.h +++ b/clang/include/clang/Parse/DeclSpec.h @@ -63,6 +63,7 @@ public:      TST_unspecified,      TST_void,      TST_char, +    TST_wchar,        // C++ wchar_t      TST_int,      TST_float,      TST_double, diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index f47855a5c6e..fef85b540c2 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -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 { diff --git a/clang/lib/Parse/DeclSpec.cpp b/clang/lib/Parse/DeclSpec.cpp index 8e6dacb761d..d97dcfac807 100644 --- a/clang/lib/Parse/DeclSpec.cpp +++ b/clang/lib/Parse/DeclSpec.cpp @@ -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. diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index 1cf331702d9..5b4473ea4de 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -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: diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index 7acb4587a0b..bda8932ef47 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -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/clang/test/Sema/cxx-wchar_t.cpp b/clang/test/Sema/cxx-wchar_t.cpp new file mode 100644 index 00000000000..43dd6ee9942 --- /dev/null +++ b/clang/test/Sema/cxx-wchar_t.cpp @@ -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}} +} | 

