SourceLocation LastLocation;
};
-/// ClassVirtSpecifiers - Represents a C++0x class-virt-specifier-seq.
-class ClassVirtSpecifiers {
-public:
- enum Specifier {
- CVS_None = 0,
- CVS_Final = 1,
- CVS_Explicit = 2
- };
-
- ClassVirtSpecifiers() : Specifiers(0) { }
-
- bool SetSpecifier(Specifier CVS, SourceLocation Loc,
- const char *&PrevSpec);
-
- bool isFinalSpecified() const { return Specifiers & CVS_Final; }
- SourceLocation getFinalLoc() const { return CVS_finalLoc; }
-
- bool isExplicitSpecified() const { return Specifiers & CVS_Explicit; }
- SourceLocation getExplicitLoc() const { return CVS_explicitLoc; }
-
- static const char *getSpecifierName(Specifier CVS);
-
-private:
- unsigned Specifiers;
-
- SourceLocation CVS_finalLoc, CVS_explicitLoc;
-};
-
} // end namespace clang
#endif
TUK = Sema::TUK_Reference;
else if (Tok.is(tok::l_brace) ||
(getLang().CPlusPlus && Tok.is(tok::colon)) ||
- isCXX0XClassVirtSpecifier() != ClassVirtSpecifiers::CVS_None) {
+ isCXX0XFinalKeyword()) {
if (DS.isFriendSpecified()) {
// C++ [class.friend]p2:
// A class shall not be defined in a friend declaration.
if (TUK == Sema::TUK_Definition) {
assert(Tok.is(tok::l_brace) ||
(getLang().CPlusPlus && Tok.is(tok::colon)) ||
- isCXX0XClassVirtSpecifier() != ClassVirtSpecifiers::CVS_None);
+ isCXX0XFinalKeyword());
if (getLang().CPlusPlus)
ParseCXXMemberSpecification(StartLoc, TagType, TagOrTempResult.get());
else
}
}
-/// isCXX0XClassVirtSpecifier - Determine whether the next token is a C++0x
-/// class-virt-specifier.
-///
-/// class-virt-specifier:
-/// final
-/// explicit
-ClassVirtSpecifiers::Specifier Parser::isCXX0XClassVirtSpecifier() const {
+/// isCXX0XFinalKeyword - Determine whether the next token is a C++0x
+/// contextual 'final' keyword.
+bool Parser::isCXX0XFinalKeyword() const {
if (!getLang().CPlusPlus)
- return ClassVirtSpecifiers::CVS_None;
+ return false;
- if (Tok.is(tok::kw_explicit))
- return ClassVirtSpecifiers::CVS_Explicit;
-
- if (Tok.is(tok::identifier)) {
- IdentifierInfo *II = Tok.getIdentifierInfo();
-
- // Initialize the contextual keywords.
- if (!Ident_final) {
- Ident_final = &PP.getIdentifierTable().get("final");
- Ident_override = &PP.getIdentifierTable().get("override");
- }
+ if (!Tok.is(tok::identifier))
+ return false;
- if (II == Ident_final)
- return ClassVirtSpecifiers::CVS_Final;
- }
-
- return ClassVirtSpecifiers::CVS_None;
-}
-
-/// ParseOptionalCXX0XClassVirtSpecifierSeq - Parse a class-virt-specifier-seq.
-///
-/// class-virt-specifier-seq:
-/// class-virt-specifier
-/// class-virt-specifier-seq class-virt-specifier
-void Parser::ParseOptionalCXX0XClassVirtSpecifierSeq(ClassVirtSpecifiers &CVS) {
- while (true) {
- ClassVirtSpecifiers::Specifier Specifier = isCXX0XClassVirtSpecifier();
- if (Specifier == ClassVirtSpecifiers::CVS_None)
- return;
-
- // C++ [class]p1:
- // A class-virt-specifier-seq shall contain at most one of each
- // class-virt-specifier.
- const char *PrevSpec = 0;
- if (CVS.SetSpecifier(Specifier, Tok.getLocation(), PrevSpec))
- Diag(Tok.getLocation(), diag::err_duplicate_class_virt_specifier)
- << PrevSpec
- << FixItHint::CreateRemoval(Tok.getLocation());
-
- if (!getLang().CPlusPlus0x)
- Diag(Tok.getLocation(), diag::ext_override_control_keyword)
- << ClassVirtSpecifiers::getSpecifierName(Specifier);
-
- ConsumeToken();
+ // Initialize the contextual keywords.
+ if (!Ident_final) {
+ Ident_final = &PP.getIdentifierTable().get("final");
+ Ident_override = &PP.getIdentifierTable().get("override");
}
+
+ return Tok.getIdentifierInfo() == Ident_final;
}
/// ParseCXXClassMemberDeclaration - Parse a C++ class member declaration.
case VS_Final: return "final";
}
}
-
-bool ClassVirtSpecifiers::SetSpecifier(Specifier CVS, SourceLocation Loc,
- const char *&PrevSpec) {
- if (Specifiers & CVS) {
- PrevSpec = getSpecifierName(CVS);
- return true;
- }
-
- Specifiers |= CVS;
-
- switch (CVS) {
- default: assert(0 && "Unknown specifier!");
- case CVS_Final: CVS_finalLoc = Loc; break;
- case CVS_Explicit: CVS_explicitLoc = Loc; break;
- }
-
- return false;
-}
-
-const char *ClassVirtSpecifiers::getSpecifierName(Specifier CVS) {
- switch (CVS) {
- default: assert(0 && "Unknown specifier");
- case CVS_Final: return "final";
- case CVS_Explicit: return "explicit";
- }
-}
-