From 1f3b6fdabbb10779a473d6315154d7325ce20aea Mon Sep 17 00:00:00 2001 From: Anders Carlsson Date: Sun, 16 Jan 2011 23:56:42 +0000 Subject: [PATCH] Begin work on supporting "N3206: Override control: Eliminating Attributes", from http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3206.htm This lands support for parsing virt-specifier-seq after member functions, including the contextual keywords 'final', and 'override'. The keywords are not yet used for anything. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@123606 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Parse/Parser.h | 7 +++ lib/Parse/ParseDeclCXX.cpp | 46 ++++++++++++++++++- lib/Parse/Parser.cpp | 6 +++ .../cxx0x-override-control-keywords.cpp | 6 +++ 4 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 test/Parser/cxx0x-override-control-keywords.cpp diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h index aebf82ee68..497c08b3b3 100644 --- a/include/clang/Parse/Parser.h +++ b/include/clang/Parse/Parser.h @@ -112,6 +112,10 @@ class Parser : public CodeCompletionHandler { IdentifierInfo *Ident_vector; IdentifierInfo *Ident_pixel; + /// C++0x contextual keywords. + IdentifierInfo *Ident_final; + IdentifierInfo *Ident_override; + llvm::OwningPtr AlignHandler; llvm::OwningPtr GCCVisibilityHandler; llvm::OwningPtr OptionsHandler; @@ -1521,6 +1525,9 @@ private: ExprResult ParseCXX0XAlignArgument(SourceLocation Start); + bool isCXX0XVirtSpecifier() const; + void ParseOptionalCXX0XVirtSpecifierSeq(); + /// DeclaratorScopeObj - RAII object used in Parser::ParseDirectDeclarator to /// enter a new C++ declarator scope and exit it when the function is /// finished. diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp index a5cdaa8674..960a9fab68 100644 --- a/lib/Parse/ParseDeclCXX.cpp +++ b/lib/Parse/ParseDeclCXX.cpp @@ -1261,6 +1261,39 @@ void Parser::HandleMemberFunctionDefaultArgs(Declarator& DeclaratorInfo, } } +/// isCXX0XVirtSpecifier - Determine whether the next token is a C++0x +/// virt-specifier. +/// +/// virt-specifier: +/// override +/// final +/// new +bool Parser::isCXX0XVirtSpecifier() const { + if (Tok.is(tok::kw_new)) + return true; + + if (Tok.isNot(tok::identifier)) + return false; + + const IdentifierInfo *II = Tok.getIdentifierInfo(); + return II == Ident_override || II == Ident_final; +} + +/// ParseOptionalCXX0XVirtSpecifierSeq - Parse a virt-specifier-seq. +/// +/// virt-specifier-seq: +/// virt-specifier +/// virt-specifier-seq virt-specifier +void Parser::ParseOptionalCXX0XVirtSpecifierSeq() { + if (!getLang().CPlusPlus0x) + return; + + while (isCXX0XVirtSpecifier()) { + // FIXME: Actually do something with the specifier. + ConsumeToken(); + } +} + /// ParseCXXClassMemberDeclaration - Parse a C++ class member declaration. /// /// member-declaration: @@ -1277,10 +1310,19 @@ void Parser::HandleMemberFunctionDefaultArgs(Declarator& DeclaratorInfo, /// member-declarator-list ',' member-declarator /// /// member-declarator: -/// declarator pure-specifier[opt] +/// declarator virt-specifier-seq[opt] pure-specifier[opt] /// declarator constant-initializer[opt] /// identifier[opt] ':' constant-expression /// +/// virt-specifier-seq: +/// virt-specifier +/// virt-specifier-seq virt-specifier +/// +/// virt-specifier: +/// override +/// final +/// new +/// /// pure-specifier: /// '= 0' /// @@ -1470,6 +1512,8 @@ void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS, SkipUntil(tok::comma, true, true); } + ParseOptionalCXX0XVirtSpecifierSeq(); + // pure-specifier: // '= 0' // diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp index aa0ad795ca..473c6ad7b0 100644 --- a/lib/Parse/Parser.cpp +++ b/lib/Parse/Parser.cpp @@ -387,6 +387,12 @@ void Parser::Initialize() { ObjCTypeQuals[objc_byref] = &PP.getIdentifierTable().get("byref"); } + // Initialize C++0x contextual keywords. + if (getLang().CPlusPlus0x) { + Ident_final = &PP.getIdentifierTable().get("final"); + Ident_override = &PP.getIdentifierTable().get("override"); + } + Ident_super = &PP.getIdentifierTable().get("super"); if (getLang().AltiVec) { diff --git a/test/Parser/cxx0x-override-control-keywords.cpp b/test/Parser/cxx0x-override-control-keywords.cpp new file mode 100644 index 0000000000..5643621764 --- /dev/null +++ b/test/Parser/cxx0x-override-control-keywords.cpp @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x %s +struct S { + virtual void final() final; + virtual void override() override; + virtual void n() new; +}; -- 2.40.0