aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>2008-08-09 16:51:54 +0000
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>2008-08-09 16:51:54 +0000
commit64c438a4be2a871fa43c78264663ba1e9788b94d (patch)
treed88760d32970f7715de5fc0d8aa444fa8857628f
parent907747b3a67a41420ead8ef1fc5e6bd9dc9e0ad9 (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.h9
-rw-r--r--include/clang/AST/Type.h4
-rw-r--r--include/clang/Basic/DiagnosticKinds.def2
-rw-r--r--include/clang/Parse/DeclSpec.h1
-rw-r--r--lib/AST/ASTContext.cpp26
-rw-r--r--lib/Parse/DeclSpec.cpp6
-rw-r--r--lib/Parse/ParseDecl.cpp6
-rw-r--r--lib/Sema/SemaType.cpp15
-rw-r--r--test/Sema/cxx-wchar_t.cpp8
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}}
+}