aboutsummaryrefslogtreecommitdiff
path: root/lib/Parse
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2013-10-18 00:33:31 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2013-10-18 00:33:31 +0000
commit7121bdb91b86f6053765bda18dd0a8a118929ace (patch)
tree5e7001cfb2daca9bed003da68fb3a646e99a3a56 /lib/Parse
parentd4f0e1991f42c69111213699fb2d09dedee1cd36 (diff)
downloadclang-7121bdb91b86f6053765bda18dd0a8a118929ace.tar.gz
[-fms-extensions] Permit 'override' in C++98 and 'sealed' as a synonym for 'final'
Summary: Some MS headers use these features. Reviewers: rnk, rsmith CC: cfe-commits Differential Revision: http://llvm-reviews.chandlerc.com/D1948 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@192936 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Parse')
-rw-r--r--lib/Parse/ParseDeclCXX.cpp51
-rw-r--r--lib/Parse/ParseExpr.cpp2
-rw-r--r--lib/Parse/ParseExprCXX.cpp1
-rw-r--r--lib/Parse/ParseTentative.cpp1
-rw-r--r--lib/Parse/Parser.cpp1
5 files changed, 41 insertions, 15 deletions
diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp
index 21b24bfd79..4625745c5e 100644
--- a/lib/Parse/ParseDeclCXX.cpp
+++ b/lib/Parse/ParseDeclCXX.cpp
@@ -1837,12 +1837,17 @@ VirtSpecifiers::Specifier Parser::isCXX11VirtSpecifier(const Token &Tok) const {
// Initialize the contextual keywords.
if (!Ident_final) {
Ident_final = &PP.getIdentifierTable().get("final");
+ if (getLangOpts().MicrosoftExt)
+ Ident_sealed = &PP.getIdentifierTable().get("sealed");
Ident_override = &PP.getIdentifierTable().get("override");
}
if (II == Ident_override)
return VirtSpecifiers::VS_Override;
+ if (II == Ident_sealed)
+ return VirtSpecifiers::VS_Sealed;
+
if (II == Ident_final)
return VirtSpecifiers::VS_Final;
}
@@ -1870,14 +1875,18 @@ void Parser::ParseOptionalCXX11VirtSpecifierSeq(VirtSpecifiers &VS,
<< PrevSpec
<< FixItHint::CreateRemoval(Tok.getLocation());
- if (IsInterface && Specifier == VirtSpecifiers::VS_Final) {
+ if (IsInterface && (Specifier == VirtSpecifiers::VS_Final ||
+ Specifier == VirtSpecifiers::VS_Sealed)) {
Diag(Tok.getLocation(), diag::err_override_control_interface)
<< VirtSpecifiers::getSpecifierName(Specifier);
+ } else if (Specifier == VirtSpecifiers::VS_Sealed) {
+ Diag(Tok.getLocation(), diag::ext_ms_sealed_keyword);
} else {
- Diag(Tok.getLocation(), getLangOpts().CPlusPlus11 ?
- diag::warn_cxx98_compat_override_control_keyword :
- diag::ext_override_control_keyword)
- << VirtSpecifiers::getSpecifierName(Specifier);
+ Diag(Tok.getLocation(),
+ getLangOpts().CPlusPlus11
+ ? diag::warn_cxx98_compat_override_control_keyword
+ : diag::ext_override_control_keyword)
+ << VirtSpecifiers::getSpecifierName(Specifier);
}
ConsumeToken();
}
@@ -1895,10 +1904,13 @@ bool Parser::isCXX11FinalKeyword() const {
// Initialize the contextual keywords.
if (!Ident_final) {
Ident_final = &PP.getIdentifierTable().get("final");
+ if (getLangOpts().MicrosoftExt)
+ Ident_sealed = &PP.getIdentifierTable().get("sealed");
Ident_override = &PP.getIdentifierTable().get("override");
}
-
- return Tok.getIdentifierInfo() == Ident_final;
+
+ return Tok.getIdentifierInfo() == Ident_final ||
+ Tok.getIdentifierInfo() == Ident_sealed;
}
/// ParseCXXClassMemberDeclaration - Parse a C++ class member declaration.
@@ -1929,6 +1941,7 @@ bool Parser::isCXX11FinalKeyword() const {
/// virt-specifier:
/// override
/// final
+/// [MS] sealed
///
/// pure-specifier:
/// '= 0'
@@ -2520,20 +2533,27 @@ void Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc,
Actions.ActOnTagStartDefinition(getCurScope(), TagDecl);
SourceLocation FinalLoc;
+ bool IsFinalSpelledSealed = false;
// Parse the optional 'final' keyword.
if (getLangOpts().CPlusPlus && Tok.is(tok::identifier)) {
- assert(isCXX11FinalKeyword() && "not a class definition");
+ VirtSpecifiers::Specifier Specifier = isCXX11VirtSpecifier(Tok);
+ assert((Specifier == VirtSpecifiers::VS_Final ||
+ Specifier == VirtSpecifiers::VS_Sealed) &&
+ "not a class definition");
FinalLoc = ConsumeToken();
+ IsFinalSpelledSealed = Specifier == VirtSpecifiers::VS_Sealed;
- if (TagType == DeclSpec::TST_interface) {
+ if (TagType == DeclSpec::TST_interface)
Diag(FinalLoc, diag::err_override_control_interface)
- << "final";
- } else {
- Diag(FinalLoc, getLangOpts().CPlusPlus11 ?
- diag::warn_cxx98_compat_override_control_keyword :
- diag::ext_override_control_keyword) << "final";
- }
+ << VirtSpecifiers::getSpecifierName(Specifier);
+ else if (Specifier == VirtSpecifiers::VS_Final)
+ Diag(FinalLoc, getLangOpts().CPlusPlus11
+ ? diag::warn_cxx98_compat_override_control_keyword
+ : diag::ext_override_control_keyword)
+ << VirtSpecifiers::getSpecifierName(Specifier);
+ else if (Specifier == VirtSpecifiers::VS_Sealed)
+ Diag(FinalLoc, diag::ext_ms_sealed_keyword);
// Parse any C++11 attributes after 'final' keyword.
// These attributes are not allowed to appear here,
@@ -2560,6 +2580,7 @@ void Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc,
if (TagDecl)
Actions.ActOnStartCXXMemberDeclarations(getCurScope(), TagDecl, FinalLoc,
+ IsFinalSpelledSealed,
T.getOpenLocation());
// C++ 11p3: Members of a class defined with the keyword class are private
diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp
index a82d5cea63..8867b08e4f 100644
--- a/lib/Parse/ParseExpr.cpp
+++ b/lib/Parse/ParseExpr.cpp
@@ -591,6 +591,7 @@ class CastExpressionIdValidator : public CorrectionCandidateCallback {
/// '__is_final'
/// '__is_pod'
/// '__is_polymorphic'
+/// '__is_sealed' [MS]
/// '__is_trivial'
/// '__is_union'
///
@@ -1200,6 +1201,7 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
case tok::kw___is_trivially_copyable:
case tok::kw___is_union:
case tok::kw___is_final:
+ case tok::kw___is_sealed:
case tok::kw___has_trivial_constructor:
case tok::kw___has_trivial_move_constructor:
case tok::kw___has_trivial_copy:
diff --git a/lib/Parse/ParseExprCXX.cpp b/lib/Parse/ParseExprCXX.cpp
index e9a5a88c76..4dd63e3763 100644
--- a/lib/Parse/ParseExprCXX.cpp
+++ b/lib/Parse/ParseExprCXX.cpp
@@ -2669,6 +2669,7 @@ static UnaryTypeTrait UnaryTypeTraitFromTokKind(tok::TokenKind kind) {
case tok::kw___is_reference: return UTT_IsReference;
case tok::kw___is_rvalue_reference: return UTT_IsRvalueReference;
case tok::kw___is_scalar: return UTT_IsScalar;
+ case tok::kw___is_sealed: return UTT_IsSealed;
case tok::kw___is_signed: return UTT_IsSigned;
case tok::kw___is_standard_layout: return UTT_IsStandardLayout;
case tok::kw___is_trivial: return UTT_IsTrivial;
diff --git a/lib/Parse/ParseTentative.cpp b/lib/Parse/ParseTentative.cpp
index 7d1475c3a6..2dc16d3b0b 100644
--- a/lib/Parse/ParseTentative.cpp
+++ b/lib/Parse/ParseTentative.cpp
@@ -962,6 +962,7 @@ Parser::isExpressionOrTypeSpecifierSimple(tok::TokenKind Kind) {
case tok::kw___is_literal_type:
case tok::kw___is_pod:
case tok::kw___is_polymorphic:
+ case tok::kw___is_sealed:
case tok::kw___is_trivial:
case tok::kw___is_trivially_assignable:
case tok::kw___is_trivially_constructible:
diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp
index f0a3d9190c..9b6c97ac19 100644
--- a/lib/Parse/Parser.cpp
+++ b/lib/Parse/Parser.cpp
@@ -486,6 +486,7 @@ void Parser::Initialize() {
Ident_instancetype = 0;
Ident_final = 0;
+ Ident_sealed = 0;
Ident_override = 0;
Ident_super = &PP.getIdentifierTable().get("super");