Skip to content

Commit c36ff64

Browse files
committed
Revert "[clang] Add support for the "abstract" contextual keyword of MSVC"
This reverts commit 818338a. Tests fail under sanitizer: https://lab.llvm.org/buildbot/#/builders/5/builds/8150
1 parent 0a52d90 commit c36ff64

File tree

10 files changed

+32
-171
lines changed

10 files changed

+32
-171
lines changed

clang/include/clang/AST/DeclCXX.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1786,7 +1786,6 @@ class CXXRecordDecl : public RecordDecl {
17861786
static bool classofKind(Kind K) {
17871787
return K >= firstCXXRecord && K <= lastCXXRecord;
17881788
}
1789-
void markAbstract() { data().Abstract = true; }
17901789
};
17911790

17921791
/// Store information needed for an explicit specifier.

clang/include/clang/Basic/DiagnosticGroups.td

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1086,7 +1086,6 @@ def MicrosoftInclude : DiagGroup<"microsoft-include">;
10861086
def MicrosoftCppMacro : DiagGroup<"microsoft-cpp-macro">;
10871087
def MicrosoftFixedEnum : DiagGroup<"microsoft-fixed-enum">;
10881088
def MicrosoftSealed : DiagGroup<"microsoft-sealed">;
1089-
def MicrosoftAbstract : DiagGroup<"microsoft-abstract">;
10901089
def MicrosoftUnqualifiedFriend : DiagGroup<"microsoft-unqualified-friend">;
10911090
def MicrosoftExceptionSpec : DiagGroup<"microsoft-exception-spec">;
10921091
def MicrosoftUsingDecl : DiagGroup<"microsoft-using-decl">;
@@ -1124,7 +1123,7 @@ def : DiagGroup<"msvc-include", [MicrosoftInclude]>;
11241123
// Warnings group for warnings about Microsoft extensions.
11251124
def Microsoft : DiagGroup<"microsoft",
11261125
[MicrosoftCharize, MicrosoftDrectveSection, MicrosoftInclude,
1127-
MicrosoftCppMacro, MicrosoftFixedEnum, MicrosoftSealed, MicrosoftAbstract,
1126+
MicrosoftCppMacro, MicrosoftFixedEnum, MicrosoftSealed,
11281127
MicrosoftUnqualifiedFriend, MicrosoftExceptionSpec, MicrosoftUsingDecl,
11291128
MicrosoftMutableReference, MicrosoftPureDefinition,
11301129
MicrosoftUnionMemberReference, MicrosoftExplicitConstructorCall,

clang/include/clang/Basic/DiagnosticParseKinds.td

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -922,16 +922,10 @@ def err_override_control_interface : Error<
922922
def ext_ms_sealed_keyword : ExtWarn<
923923
"'sealed' keyword is a Microsoft extension">,
924924
InGroup<MicrosoftSealed>;
925-
def ext_ms_abstract_keyword : ExtWarn<
926-
"'abstract' keyword is a Microsoft extension">,
927-
InGroup<MicrosoftAbstract>;
928925

929926
def err_access_specifier_interface : Error<
930927
"interface types cannot specify '%select{private|protected}0' access">;
931928

932-
def err_duplicate_class_virt_specifier : Error<
933-
"class already marked '%0'">;
934-
935929
def err_duplicate_virt_specifier : Error<
936930
"class member already marked '%0'">;
937931

clang/include/clang/Parse/Parser.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,6 @@ class Parser : public CodeCompletionHandler {
114114
/// Contextual keywords for Microsoft extensions.
115115
IdentifierInfo *Ident__except;
116116
mutable IdentifierInfo *Ident_sealed;
117-
mutable IdentifierInfo *Ident_abstract;
118117

119118
/// Ident_super - IdentifierInfo for "super", to support fast
120119
/// comparison.
@@ -2914,7 +2913,6 @@ class Parser : public CodeCompletionHandler {
29142913
SourceLocation FriendLoc);
29152914

29162915
bool isCXX11FinalKeyword() const;
2917-
bool isClassCompatibleKeyword() const;
29182916

29192917
/// DeclaratorScopeObj - RAII object used in Parser::ParseDirectDeclarator to
29202918
/// enter a new C++ declarator scope and exit it when the function is

clang/include/clang/Sema/DeclSpec.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2620,8 +2620,7 @@ class VirtSpecifiers {
26202620
VS_Final = 2,
26212621
VS_Sealed = 4,
26222622
// Represents the __final keyword, which is legal for gcc in pre-C++11 mode.
2623-
VS_GNU_Final = 8,
2624-
VS_Abstract = 16
2623+
VS_GNU_Final = 8
26252624
};
26262625

26272626
VirtSpecifiers() : Specifiers(0), LastSpecifier(VS_None) { }
@@ -2637,7 +2636,6 @@ class VirtSpecifiers {
26372636
bool isFinalSpecified() const { return Specifiers & (VS_Final | VS_Sealed | VS_GNU_Final); }
26382637
bool isFinalSpelledSealed() const { return Specifiers & VS_Sealed; }
26392638
SourceLocation getFinalLoc() const { return VS_finalLoc; }
2640-
SourceLocation getAbstractLoc() const { return VS_abstractLoc; }
26412639

26422640
void clear() { Specifiers = 0; }
26432641

@@ -2651,7 +2649,7 @@ class VirtSpecifiers {
26512649
unsigned Specifiers;
26522650
Specifier LastSpecifier;
26532651

2654-
SourceLocation VS_overrideLoc, VS_finalLoc, VS_abstractLoc;
2652+
SourceLocation VS_overrideLoc, VS_finalLoc;
26552653
SourceLocation FirstLocation;
26562654
SourceLocation LastLocation;
26572655
};

clang/include/clang/Sema/Sema.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3147,7 +3147,6 @@ class Sema final {
31473147
void ActOnStartCXXMemberDeclarations(Scope *S, Decl *TagDecl,
31483148
SourceLocation FinalLoc,
31493149
bool IsFinalSpelledSealed,
3150-
bool IsAbstract,
31513150
SourceLocation LBraceLoc);
31523151

31533152
/// ActOnTagFinishDefinition - Invoked once we have finished parsing

clang/lib/Parse/ParseDeclCXX.cpp

Lines changed: 27 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -1710,7 +1710,7 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
17101710
TUK = Sema::TUK_Reference;
17111711
else if (Tok.is(tok::l_brace) ||
17121712
(getLangOpts().CPlusPlus && Tok.is(tok::colon)) ||
1713-
(isClassCompatibleKeyword() &&
1713+
(isCXX11FinalKeyword() &&
17141714
(NextToken().is(tok::l_brace) || NextToken().is(tok::colon)))) {
17151715
if (DS.isFriendSpecified()) {
17161716
// C++ [class.friend]p2:
@@ -1726,18 +1726,14 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
17261726
// Okay, this is a class definition.
17271727
TUK = Sema::TUK_Definition;
17281728
}
1729-
} else if (isClassCompatibleKeyword() &&
1730-
(NextToken().is(tok::l_square) ||
1731-
NextToken().is(tok::kw_alignas) ||
1732-
isCXX11VirtSpecifier(NextToken()) != VirtSpecifiers::VS_None)) {
1729+
} else if (isCXX11FinalKeyword() && (NextToken().is(tok::l_square) ||
1730+
NextToken().is(tok::kw_alignas))) {
17331731
// We can't tell if this is a definition or reference
17341732
// until we skipped the 'final' and C++11 attribute specifiers.
17351733
TentativeParsingAction PA(*this);
17361734

1737-
// Skip the 'final', abstract'... keywords.
1738-
while (isClassCompatibleKeyword()) {
1739-
ConsumeToken();
1740-
}
1735+
// Skip the 'final' keyword.
1736+
ConsumeToken();
17411737

17421738
// Skip C++11 attribute specifiers.
17431739
while (true) {
@@ -1986,7 +1982,7 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
19861982
if (TUK == Sema::TUK_Definition) {
19871983
assert(Tok.is(tok::l_brace) ||
19881984
(getLangOpts().CPlusPlus && Tok.is(tok::colon)) ||
1989-
isClassCompatibleKeyword());
1985+
isCXX11FinalKeyword());
19901986
if (SkipBody.ShouldSkip)
19911987
SkipCXXMemberSpecification(StartLoc, AttrFixitLoc, TagType,
19921988
TagOrTempResult.get());
@@ -2253,10 +2249,8 @@ VirtSpecifiers::Specifier Parser::isCXX11VirtSpecifier(const Token &Tok) const {
22532249
Ident_final = &PP.getIdentifierTable().get("final");
22542250
if (getLangOpts().GNUKeywords)
22552251
Ident_GNU_final = &PP.getIdentifierTable().get("__final");
2256-
if (getLangOpts().MicrosoftExt) {
2252+
if (getLangOpts().MicrosoftExt)
22572253
Ident_sealed = &PP.getIdentifierTable().get("sealed");
2258-
Ident_abstract = &PP.getIdentifierTable().get("abstract");
2259-
}
22602254
Ident_override = &PP.getIdentifierTable().get("override");
22612255
}
22622256

@@ -2266,9 +2260,6 @@ VirtSpecifiers::Specifier Parser::isCXX11VirtSpecifier(const Token &Tok) const {
22662260
if (II == Ident_sealed)
22672261
return VirtSpecifiers::VS_Sealed;
22682262

2269-
if (II == Ident_abstract)
2270-
return VirtSpecifiers::VS_Abstract;
2271-
22722263
if (II == Ident_final)
22732264
return VirtSpecifiers::VS_Final;
22742265

@@ -2314,8 +2305,6 @@ void Parser::ParseOptionalCXX11VirtSpecifierSeq(VirtSpecifiers &VS,
23142305
<< VirtSpecifiers::getSpecifierName(Specifier);
23152306
} else if (Specifier == VirtSpecifiers::VS_Sealed) {
23162307
Diag(Tok.getLocation(), diag::ext_ms_sealed_keyword);
2317-
} else if (Specifier == VirtSpecifiers::VS_Abstract) {
2318-
Diag(Tok.getLocation(), diag::ext_ms_abstract_keyword);
23192308
} else if (Specifier == VirtSpecifiers::VS_GNU_Final) {
23202309
Diag(Tok.getLocation(), diag::ext_warn_gnu_final);
23212310
} else {
@@ -2338,16 +2327,6 @@ bool Parser::isCXX11FinalKeyword() const {
23382327
Specifier == VirtSpecifiers::VS_Sealed;
23392328
}
23402329

2341-
/// isClassCompatibleKeyword - Determine whether the next token is a C++11
2342-
/// 'final' or Microsoft 'sealed' or 'abstract' contextual keywords.
2343-
bool Parser::isClassCompatibleKeyword() const {
2344-
VirtSpecifiers::Specifier Specifier = isCXX11VirtSpecifier();
2345-
return Specifier == VirtSpecifiers::VS_Final ||
2346-
Specifier == VirtSpecifiers::VS_GNU_Final ||
2347-
Specifier == VirtSpecifiers::VS_Sealed ||
2348-
Specifier == VirtSpecifiers::VS_Abstract;
2349-
}
2350-
23512330
/// Parse a C++ member-declarator up to, but not including, the optional
23522331
/// brace-or-equal-initializer or pure-specifier.
23532332
bool Parser::ParseCXXMemberDeclaratorBeforeInitializer(
@@ -2914,13 +2893,8 @@ Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
29142893
HasStaticInitializer = true;
29152894
}
29162895

2917-
if (PureSpecLoc.isValid() && VS.getAbstractLoc().isValid()) {
2918-
Diag(PureSpecLoc, diag::err_duplicate_virt_specifier) << "abstract";
2919-
}
29202896
if (ThisDecl && PureSpecLoc.isValid())
29212897
Actions.ActOnPureSpecifier(ThisDecl, PureSpecLoc);
2922-
else if (ThisDecl && VS.getAbstractLoc().isValid())
2923-
Actions.ActOnPureSpecifier(ThisDecl, VS.getAbstractLoc());
29242898

29252899
// Handle the initializer.
29262900
if (HasInClassInit != ICIS_NoInit) {
@@ -3305,53 +3279,30 @@ void Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc,
33053279
Actions.ActOnTagStartDefinition(getCurScope(), TagDecl);
33063280

33073281
SourceLocation FinalLoc;
3308-
SourceLocation AbstractLoc;
33093282
bool IsFinalSpelledSealed = false;
3310-
bool IsAbstract = false;
33113283

33123284
// Parse the optional 'final' keyword.
33133285
if (getLangOpts().CPlusPlus && Tok.is(tok::identifier)) {
3314-
while (true) {
3315-
VirtSpecifiers::Specifier Specifier = isCXX11VirtSpecifier(Tok);
3316-
if (Specifier == VirtSpecifiers::VS_None)
3317-
break;
3318-
if (isCXX11FinalKeyword()) {
3319-
if (FinalLoc.isValid()) {
3320-
auto Skipped = ConsumeToken();
3321-
Diag(Skipped, diag::err_duplicate_class_virt_specifier)
3322-
<< VirtSpecifiers::getSpecifierName(Specifier);
3323-
} else {
3324-
FinalLoc = ConsumeToken();
3325-
if (Specifier == VirtSpecifiers::VS_Sealed)
3326-
IsFinalSpelledSealed = true;
3327-
}
3328-
} else {
3329-
if (AbstractLoc.isValid()) {
3330-
auto Skipped = ConsumeToken();
3331-
Diag(Skipped, diag::err_duplicate_class_virt_specifier)
3332-
<< VirtSpecifiers::getSpecifierName(Specifier);
3333-
} else {
3334-
AbstractLoc = ConsumeToken();
3335-
IsAbstract = true;
3336-
}
3337-
}
3338-
if (TagType == DeclSpec::TST_interface)
3339-
Diag(FinalLoc, diag::err_override_control_interface)
3340-
<< VirtSpecifiers::getSpecifierName(Specifier);
3341-
else if (Specifier == VirtSpecifiers::VS_Final)
3342-
Diag(FinalLoc, getLangOpts().CPlusPlus11
3343-
? diag::warn_cxx98_compat_override_control_keyword
3344-
: diag::ext_override_control_keyword)
3345-
<< VirtSpecifiers::getSpecifierName(Specifier);
3346-
else if (Specifier == VirtSpecifiers::VS_Sealed)
3347-
Diag(FinalLoc, diag::ext_ms_sealed_keyword);
3348-
else if (Specifier == VirtSpecifiers::VS_Abstract)
3349-
Diag(AbstractLoc, diag::ext_ms_abstract_keyword);
3350-
else if (Specifier == VirtSpecifiers::VS_GNU_Final)
3351-
Diag(FinalLoc, diag::ext_warn_gnu_final);
3352-
}
3353-
assert((FinalLoc.isValid() || AbstractLoc.isValid()) &&
3286+
VirtSpecifiers::Specifier Specifier = isCXX11VirtSpecifier(Tok);
3287+
assert((Specifier == VirtSpecifiers::VS_Final ||
3288+
Specifier == VirtSpecifiers::VS_GNU_Final ||
3289+
Specifier == VirtSpecifiers::VS_Sealed) &&
33543290
"not a class definition");
3291+
FinalLoc = ConsumeToken();
3292+
IsFinalSpelledSealed = Specifier == VirtSpecifiers::VS_Sealed;
3293+
3294+
if (TagType == DeclSpec::TST_interface)
3295+
Diag(FinalLoc, diag::err_override_control_interface)
3296+
<< VirtSpecifiers::getSpecifierName(Specifier);
3297+
else if (Specifier == VirtSpecifiers::VS_Final)
3298+
Diag(FinalLoc, getLangOpts().CPlusPlus11
3299+
? diag::warn_cxx98_compat_override_control_keyword
3300+
: diag::ext_override_control_keyword)
3301+
<< VirtSpecifiers::getSpecifierName(Specifier);
3302+
else if (Specifier == VirtSpecifiers::VS_Sealed)
3303+
Diag(FinalLoc, diag::ext_ms_sealed_keyword);
3304+
else if (Specifier == VirtSpecifiers::VS_GNU_Final)
3305+
Diag(FinalLoc, diag::ext_warn_gnu_final);
33553306

33563307
// Parse any C++11 attributes after 'final' keyword.
33573308
// These attributes are not allowed to appear here,
@@ -3424,7 +3375,7 @@ void Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc,
34243375

34253376
if (TagDecl)
34263377
Actions.ActOnStartCXXMemberDeclarations(getCurScope(), TagDecl, FinalLoc,
3427-
IsFinalSpelledSealed, IsAbstract,
3378+
IsFinalSpelledSealed,
34283379
T.getOpenLocation());
34293380

34303381
// C++ 11p3: Members of a class defined with the keyword class are private

clang/lib/Sema/DeclSpec.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1475,7 +1475,6 @@ bool VirtSpecifiers::SetSpecifier(Specifier VS, SourceLocation Loc,
14751475
case VS_GNU_Final:
14761476
case VS_Sealed:
14771477
case VS_Final: VS_finalLoc = Loc; break;
1478-
case VS_Abstract: VS_abstractLoc = Loc; break;
14791478
}
14801479

14811480
return false;
@@ -1488,6 +1487,5 @@ const char *VirtSpecifiers::getSpecifierName(Specifier VS) {
14881487
case VS_Final: return "final";
14891488
case VS_GNU_Final: return "__final";
14901489
case VS_Sealed: return "sealed";
1491-
case VS_Abstract: return "abstract";
14921490
}
14931491
}

clang/lib/Sema/SemaDecl.cpp

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16456,7 +16456,6 @@ Decl *Sema::ActOnObjCContainerStartDefinition(Decl *IDecl) {
1645616456
void Sema::ActOnStartCXXMemberDeclarations(Scope *S, Decl *TagD,
1645716457
SourceLocation FinalLoc,
1645816458
bool IsFinalSpelledSealed,
16459-
bool IsAbstract,
1646016459
SourceLocation LBraceLoc) {
1646116460
AdjustDeclIfTemplate(TagD);
1646216461
CXXRecordDecl *Record = cast<CXXRecordDecl>(TagD);
@@ -16466,14 +16465,11 @@ void Sema::ActOnStartCXXMemberDeclarations(Scope *S, Decl *TagD,
1646616465
if (!Record->getIdentifier())
1646716466
return;
1646816467

16469-
if (IsAbstract)
16470-
Record->markAbstract();
16471-
16472-
if (FinalLoc.isValid()) {
16468+
if (FinalLoc.isValid())
1647316469
Record->addAttr(FinalAttr::Create(
1647416470
Context, FinalLoc, AttributeCommonInfo::AS_Keyword,
1647516471
static_cast<FinalAttr::Spelling>(IsFinalSpelledSealed)));
16476-
}
16472+
1647716473
// C++ [class]p2:
1647816474
// [...] The class-name is also inserted into the scope of the
1647916475
// class itself; this is known as the injected-class-name. For

clang/test/SemaCXX/MicrosoftExtensions.cpp

Lines changed: 0 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -462,77 +462,6 @@ class SealedDestructor { // expected-note {{mark 'SealedDestructor' as 'sealed'
462462
virtual ~SealedDestructor() sealed; // expected-warning {{class with destructor marked 'sealed' cannot be inherited from}}
463463
};
464464

465-
// expected-warning@+1 {{'abstract' keyword is a Microsoft extension}}
466-
class AbstractClass abstract {
467-
int i;
468-
};
469-
470-
// expected-error@+1 {{variable type 'AbstractClass' is an abstract class}}
471-
AbstractClass abstractInstance;
472-
473-
// expected-warning@+4 {{abstract class is marked 'sealed'}}
474-
// expected-note@+3 {{'AbstractAndSealedClass' declared here}}
475-
// expected-warning@+2 {{'abstract' keyword is a Microsoft extension}}
476-
// expected-warning@+1 {{'sealed' keyword is a Microsoft extension}}
477-
class AbstractAndSealedClass abstract sealed {}; // Does no really make sense, but allowed
478-
479-
// expected-error@+1 {{variable type 'AbstractAndSealedClass' is an abstract class}}
480-
AbstractAndSealedClass abstractAndSealedInstance;
481-
// expected-error@+1 {{base 'AbstractAndSealedClass' is marked 'sealed'}}
482-
class InheritFromAbstractAndSealed : AbstractAndSealedClass {};
483-
484-
#if __cplusplus <= 199711L
485-
// expected-warning@+4 {{'final' keyword is a C++11 extension}}
486-
// expected-warning@+3 {{'final' keyword is a C++11 extension}}
487-
#endif
488-
// expected-error@+1 {{class already marked 'final'}}
489-
class TooManyVirtSpecifiers1 final final {};
490-
#if __cplusplus <= 199711L
491-
// expected-warning@+4 {{'final' keyword is a C++11 extension}}
492-
#endif
493-
// expected-warning@+2 {{'sealed' keyword is a Microsoft extension}}
494-
// expected-error@+1 {{class already marked 'sealed'}}
495-
class TooManyVirtSpecifiers2 final sealed {};
496-
#if __cplusplus <= 199711L
497-
// expected-warning@+6 {{'final' keyword is a C++11 extension}}
498-
// expected-warning@+5 {{'final' keyword is a C++11 extension}}
499-
#endif
500-
// expected-warning@+3 {{abstract class is marked 'final'}}
501-
// expected-warning@+2 {{'abstract' keyword is a Microsoft extension}}
502-
// expected-error@+1 {{class already marked 'final'}}
503-
class TooManyVirtSpecifiers3 final abstract final {};
504-
#if __cplusplus <= 199711L
505-
// expected-warning@+6 {{'final' keyword is a C++11 extension}}
506-
#endif
507-
// expected-warning@+4 {{abstract class is marked 'final'}}
508-
// expected-warning@+3 {{'abstract' keyword is a Microsoft extension}}
509-
// expected-warning@+2 {{'abstract' keyword is a Microsoft extension}}
510-
// expected-error@+1 {{class already marked 'abstract'}}
511-
class TooManyVirtSpecifiers4 abstract final abstract {};
512-
513-
class Base {
514-
virtual void i();
515-
};
516-
class AbstractFunctionInClass : public Base {
517-
// expected-note@+2 {{unimplemented pure virtual method 'f' in 'AbstractFunctionInClass'}}
518-
// expected-warning@+1 {{'abstract' keyword is a Microsoft extension}}
519-
virtual void f() abstract;
520-
// expected-warning@+1 {{'abstract' keyword is a Microsoft extension}}
521-
void g() abstract; // expected-error {{'g' is not virtual and cannot be declared pure}}
522-
// expected-note@+2 {{unimplemented pure virtual method 'h' in 'AbstractFunctionInClass'}}
523-
// expected-warning@+1 {{'abstract' keyword is a Microsoft extension}}
524-
virtual void h() abstract = 0; // expected-error {{class member already marked 'abstract'}}
525-
#if __cplusplus <= 199711L
526-
// expected-warning@+4 {{'override' keyword is a C++11 extension}}
527-
#endif
528-
// expected-note@+2 {{unimplemented pure virtual method 'i' in 'AbstractFunctionInClass'}}
529-
// expected-warning@+1 {{'abstract' keyword is a Microsoft extension}}
530-
virtual void i() abstract override;
531-
};
532-
533-
// expected-error@+1 {{variable type 'AbstractFunctionInClass' is an abstract class}}
534-
AbstractFunctionInClass abstractFunctionInClassInstance;
535-
536465
void AfterClassBody() {
537466
// expected-warning@+1 {{attribute 'deprecated' is ignored, place it after "struct" to apply attribute to type declaration}}
538467
struct D {} __declspec(deprecated);

0 commit comments

Comments
 (0)