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 | 64c438a4be2a871fa43c78264663ba1e9788b94d (patch) | |
tree | d88760d32970f7715de5fc0d8aa444fa8857628f | |
parent | 907747b3a67a41420ead8ef1fc5e6bd9dc9e0ad9 (diff) |
Implement support for the 'wchar_t' C++ type.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@54585 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang/AST/ASTContext.h | 9 | ||||
-rw-r--r-- | include/clang/AST/Type.h | 4 | ||||
-rw-r--r-- | include/clang/Basic/DiagnosticKinds.def | 2 | ||||
-rw-r--r-- | include/clang/Parse/DeclSpec.h | 1 | ||||
-rw-r--r-- | lib/AST/ASTContext.cpp | 26 | ||||
-rw-r--r-- | lib/Parse/DeclSpec.cpp | 6 | ||||
-rw-r--r-- | lib/Parse/ParseDecl.cpp | 6 | ||||
-rw-r--r-- | lib/Sema/SemaType.cpp | 15 | ||||
-rw-r--r-- | test/Sema/cxx-wchar_t.cpp | 8 |
9 files changed, 73 insertions, 4 deletions
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h index 2c1e1e4ec6..1d4c2a351a 100644 --- a/include/clang/AST/ASTContext.h +++ b/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/include/clang/AST/Type.h b/include/clang/AST/Type.h index 21541792d5..502b387ac2 100644 --- a/include/clang/AST/Type.h +++ b/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/include/clang/Basic/DiagnosticKinds.def b/include/clang/Basic/DiagnosticKinds.def index 7afe5723a4..076ccce0d0 100644 --- a/include/clang/Basic/DiagnosticKinds.def +++ b/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/include/clang/Parse/DeclSpec.h b/include/clang/Parse/DeclSpec.h index acae7a3ad3..df5109d196 100644 --- a/include/clang/Parse/DeclSpec.h +++ b/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/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index f47855a5c6..fef85b540c 100644 --- a/lib/AST/ASTContext.cpp +++ b/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/lib/Parse/DeclSpec.cpp b/lib/Parse/DeclSpec.cpp index 8e6dacb761..d97dcfac80 100644 --- a/lib/Parse/DeclSpec.cpp +++ b/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/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index 1cf331702d..5b4473ea4d 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/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/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp index 7acb4587a0..bda8932ef4 100644 --- a/lib/Sema/SemaType.cpp +++ b/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/test/Sema/cxx-wchar_t.cpp b/test/Sema/cxx-wchar_t.cpp new file mode 100644 index 0000000000..43dd6ee994 --- /dev/null +++ b/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}} +} |