diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Sema/DeclSpec.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/Sema/DeclSpec.cpp | 33 |
1 files changed, 23 insertions, 10 deletions
diff --git a/contrib/llvm/tools/clang/lib/Sema/DeclSpec.cpp b/contrib/llvm/tools/clang/lib/Sema/DeclSpec.cpp index f0a763e..b531acc 100644 --- a/contrib/llvm/tools/clang/lib/Sema/DeclSpec.cpp +++ b/contrib/llvm/tools/clang/lib/Sema/DeclSpec.cpp @@ -15,6 +15,7 @@ #include "clang/Sema/DeclSpec.h" #include "clang/Sema/LocInfoType.h" #include "clang/Sema/ParsedTemplate.h" +#include "clang/Sema/SemaDiagnostic.h" #include "clang/Sema/Sema.h" #include "clang/AST/ASTContext.h" #include "clang/AST/Expr.h" @@ -150,6 +151,9 @@ DeclaratorChunk DeclaratorChunk::getFunction(bool hasProto, bool isVariadic, unsigned TypeQuals, bool RefQualifierIsLvalueRef, SourceLocation RefQualifierLoc, + SourceLocation ConstQualifierLoc, + SourceLocation + VolatileQualifierLoc, SourceLocation MutableLoc, ExceptionSpecificationType ESpecType, @@ -176,6 +180,8 @@ DeclaratorChunk DeclaratorChunk::getFunction(bool hasProto, bool isVariadic, I.Fun.ArgInfo = 0; I.Fun.RefQualifierIsLValueRef = RefQualifierIsLvalueRef; I.Fun.RefQualifierLoc = RefQualifierLoc.getRawEncoding(); + I.Fun.ConstQualifierLoc = ConstQualifierLoc.getRawEncoding(); + I.Fun.VolatileQualifierLoc = VolatileQualifierLoc.getRawEncoding(); I.Fun.MutableLoc = MutableLoc.getRawEncoding(); I.Fun.ExceptionSpecType = ESpecType; I.Fun.ExceptionSpecLoc = ESpecLoc.getRawEncoding(); @@ -239,7 +245,6 @@ bool Declarator::isDeclarationOfFunction() const { return false; } llvm_unreachable("Invalid type chunk"); - return false; } switch (DS.getTypeSpecType()) { @@ -259,6 +264,7 @@ bool Declarator::isDeclarationOfFunction() const { case TST_float: case TST_half: case TST_int: + case TST_int128: case TST_struct: case TST_union: case TST_unknown_anytype: @@ -289,8 +295,8 @@ bool Declarator::isDeclarationOfFunction() const { return QT->isFunctionType(); } } - - return false; + + llvm_unreachable("Invalid TypeSpecType!"); } /// getParsedSpecifiers - Return a bitmask of which flavors of specifiers this @@ -374,6 +380,7 @@ const char *DeclSpec::getSpecifierName(DeclSpec::TST T) { case DeclSpec::TST_char16: return "char16_t"; case DeclSpec::TST_char32: return "char32_t"; case DeclSpec::TST_int: return "int"; + case DeclSpec::TST_int128: return "__int128"; case DeclSpec::TST_half: return "half"; case DeclSpec::TST_float: return "float"; case DeclSpec::TST_double: return "double"; @@ -416,7 +423,7 @@ bool DeclSpec::SetStorageClassSpec(Sema &S, SCS SC, SourceLocation Loc, // It seems sensible to prohibit private_extern too // The cl_clang_storage_class_specifiers extension enables support for // these storage-class specifiers. - if (S.getLangOptions().OpenCL && + if (S.getLangOpts().OpenCL && !S.getOpenCLOptions().cl_clang_storage_class_specifiers) { switch (SC) { case SCS_extern: @@ -435,7 +442,7 @@ bool DeclSpec::SetStorageClassSpec(Sema &S, SCS SC, SourceLocation Loc, if (StorageClassSpec != SCS_unspecified) { // Maybe this is an attempt to use C++0x 'auto' outside of C++0x mode. bool isInvalid = true; - if (TypeSpecType == TST_unspecified && S.getLangOptions().CPlusPlus) { + if (TypeSpecType == TST_unspecified && S.getLangOpts().CPlusPlus) { if (SC == SCS_auto) return SetTypeSpecType(TST_auto, Loc, PrevSpec, DiagID); if (StorageClassSpec == SCS_auto) { @@ -813,7 +820,7 @@ void DeclSpec::Finish(DiagnosticsEngine &D, Preprocessor &PP) { if (TypeSpecSign != TSS_unspecified) { if (TypeSpecType == TST_unspecified) TypeSpecType = TST_int; // unsigned -> unsigned int, signed -> signed int. - else if (TypeSpecType != TST_int && + else if (TypeSpecType != TST_int && TypeSpecType != TST_int128 && TypeSpecType != TST_char && TypeSpecType != TST_wchar) { Diag(D, TSSLoc, diag::err_invalid_sign_spec) << getSpecifierName((TST)TypeSpecType); @@ -861,7 +868,8 @@ void DeclSpec::Finish(DiagnosticsEngine &D, Preprocessor &PP) { TypeSpecType = TST_double; // _Complex -> _Complex double. } else if (TypeSpecType == TST_int || TypeSpecType == TST_char) { // Note that this intentionally doesn't include _Complex _Bool. - Diag(D, TSTLoc, diag::ext_integer_complex); + if (!PP.getLangOpts().CPlusPlus) + Diag(D, TSTLoc, diag::ext_integer_complex); } else if (TypeSpecType != TST_float && TypeSpecType != TST_double) { Diag(D, TSCLoc, diag::err_invalid_complex_spec) << getSpecifierName((TST)TypeSpecType); @@ -874,7 +882,7 @@ void DeclSpec::Finish(DiagnosticsEngine &D, Preprocessor &PP) { // class specifier, then assume this is an attempt to use C++0x's 'auto' // type specifier. // FIXME: Does Microsoft really support implicit int in C++? - if (PP.getLangOptions().CPlusPlus && !PP.getLangOptions().MicrosoftExt && + if (PP.getLangOpts().CPlusPlus && !PP.getLangOpts().MicrosoftExt && TypeSpecType == TST_unspecified && StorageClassSpec == SCS_auto) { TypeSpecType = TST_auto; StorageClassSpec = StorageClassSpecAsWritten = SCS_unspecified; @@ -883,12 +891,17 @@ void DeclSpec::Finish(DiagnosticsEngine &D, Preprocessor &PP) { } // Diagnose if we've recovered from an ill-formed 'auto' storage class // specifier in a pre-C++0x dialect of C++. - if (!PP.getLangOptions().CPlusPlus0x && TypeSpecType == TST_auto) + if (!PP.getLangOpts().CPlusPlus0x && TypeSpecType == TST_auto) Diag(D, TSTLoc, diag::ext_auto_type_specifier); - if (PP.getLangOptions().CPlusPlus && !PP.getLangOptions().CPlusPlus0x && + if (PP.getLangOpts().CPlusPlus && !PP.getLangOpts().CPlusPlus0x && StorageClassSpec == SCS_auto) Diag(D, StorageClassSpecLoc, diag::warn_auto_storage_class) << FixItHint::CreateRemoval(StorageClassSpecLoc); + if (TypeSpecType == TST_char16 || TypeSpecType == TST_char32) + Diag(D, TSTLoc, diag::warn_cxx98_compat_unicode_type) + << (TypeSpecType == TST_char16 ? "char16_t" : "char32_t"); + if (Constexpr_specified) + Diag(D, ConstexprLoc, diag::warn_cxx98_compat_constexpr); // C++ [class.friend]p6: // No storage-class-specifier shall appear in the decl-specifier-seq |