]> granicus.if.org Git - clang/commitdiff
Begin work on supporting "N3206: Override control: Eliminating Attributes", from
authorAnders Carlsson <andersca@mac.com>
Sun, 16 Jan 2011 23:56:42 +0000 (23:56 +0000)
committerAnders Carlsson <andersca@mac.com>
Sun, 16 Jan 2011 23:56:42 +0000 (23:56 +0000)
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
lib/Parse/ParseDeclCXX.cpp
lib/Parse/Parser.cpp
test/Parser/cxx0x-override-control-keywords.cpp [new file with mode: 0644]

index aebf82ee68ba9abc4f997ed3d48f02ff4eeb13ab..497c08b3b364f47fa5498b2ff7d387c91dc324db 100644 (file)
@@ -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<PragmaHandler> AlignHandler;
   llvm::OwningPtr<PragmaHandler> GCCVisibilityHandler;
   llvm::OwningPtr<PragmaHandler> 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.
index a5cdaa86748ac72df1a68e77ff92d6f053535576..960a9fab6885b0021cb4277a6344ef0b42f53e1f 100644 (file)
@@ -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'
     //
index aa0ad795cab7f8f8f9cd33555d9fa487056ca046..473c6ad7b000d31bbff93db45025201a9a886b89 100644 (file)
@@ -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 (file)
index 0000000..5643621
--- /dev/null
@@ -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;
+};