[cfe-commits] r67653 - in /cfe/trunk: include/clang/AST/Decl.h include/clang/Basic/DiagnosticSemaKinds.td include/clang/Parse/Action.h lib/Parse/ParseDecl.cpp lib/Sema/Sema.h lib/Sema/SemaDeclCXX.cpp test/SemaCXX/deleted-function.cpp

Sebastian Redl sebastian.redl at getdesigned.at
Tue Mar 24 15:27:57 PDT 2009


Author: cornedbee
Date: Tue Mar 24 17:27:57 2009
New Revision: 67653

URL: http://llvm.org/viewvc/llvm-project?rev=67653&view=rev
Log:
Parse deleted function definitions and hook them up to Doug's machinery.

Added:
    cfe/trunk/test/SemaCXX/deleted-function.cpp
Modified:
    cfe/trunk/include/clang/AST/Decl.h
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/include/clang/Parse/Action.h
    cfe/trunk/lib/Parse/ParseDecl.cpp
    cfe/trunk/lib/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaDeclCXX.cpp

Modified: cfe/trunk/include/clang/AST/Decl.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=67653&r1=67652&r2=67653&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/Decl.h (original)
+++ cfe/trunk/include/clang/AST/Decl.h Tue Mar 24 17:27:57 2009
@@ -618,6 +618,8 @@
   /// declaration of the function is also a definition. This does not
   /// determine whether the function has been defined (e.g., in a
   /// previous definition); for that information, use getBody.
+  /// FIXME: Should return true if function is deleted or defaulted. However,
+  /// CodeGenModule.cpp uses it, and I don't know if this would break it.
   bool isThisDeclarationADefinition() const { return Body != 0; }
 
   void setBody(CompoundStmt *B) { Body = (Stmt*) B; }

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=67653&r1=67652&r2=67653&view=diff

==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Tue Mar 24 17:27:57 2009
@@ -228,7 +228,12 @@
   
 def note_pure_virtual_function : Note<
   "pure virtual function %0">;
-  
+
+def err_deleted_non_function : Error<
+  "only functions can have deleted definitions">;
+def err_deleted_decl_not_first : Error<
+  "deleted definition must be first declaration">;
+
 // C++ name lookup
 def err_incomplete_nested_name_spec : Error<
   "incomplete type %0 named in nested name specifier">;

Modified: cfe/trunk/include/clang/Parse/Action.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Action.h?rev=67653&r1=67652&r2=67653&view=diff

==============================================================================
--- cfe/trunk/include/clang/Parse/Action.h (original)
+++ cfe/trunk/include/clang/Parse/Action.h Tue Mar 24 17:27:57 2009
@@ -234,6 +234,14 @@
     return;
   }
 
+  /// SetDeclDeleted - This action is called immediately after ActOnDeclarator
+  /// if =delete is parsed. C++0x [dcl.fct.def]p10
+  /// Note that this can be called even for variable declarations. It's the
+  /// action's job to reject it.
+  virtual void SetDeclDeleted(DeclTy *Dcl, SourceLocation DelLoc) {
+    return;
+  }
+
   /// ActOnUninitializedDecl - This action is called immediately after
   /// ActOnDeclarator (when an initializer is *not* present).
   virtual void ActOnUninitializedDecl(DeclTy *Dcl) {

Modified: cfe/trunk/lib/Parse/ParseDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=67653&r1=67652&r2=67653&view=diff

==============================================================================
--- cfe/trunk/lib/Parse/ParseDecl.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDecl.cpp Tue Mar 24 17:27:57 2009
@@ -225,7 +225,7 @@
 /// [C++]   namespace-definition
 /// [C++]   using-directive
 /// [C++]   using-declaration [TODO]
-//  [C++0x] static_assert-declaration
+/// [C++0x] static_assert-declaration
 ///         others... [FIXME]
 ///
 Parser::DeclTy *Parser::ParseDeclaration(unsigned Context) {
@@ -285,6 +285,11 @@
 /// [C++] initializer:
 /// [C++]   '=' initializer-clause
 /// [C++]   '(' expression-list ')'
+/// [C++0x] '=' 'default'                                                [TODO]
+/// [C++0x] '=' 'delete'
+///
+/// According to the standard grammar, =default and =delete are function
+/// definitions, but that definitely doesn't fit with the parser here.
 ///
 Parser::DeclTy *Parser::
 ParseInitDeclaratorListAfterFirstDeclarator(Declarator &D) {
@@ -322,12 +327,17 @@
     // Parse declarator '=' initializer.
     if (Tok.is(tok::equal)) {
       ConsumeToken();
-      OwningExprResult Init(ParseInitializer());
-      if (Init.isInvalid()) {
-        SkipUntil(tok::semi);
-        return 0;
+      if (getLang().CPlusPlus0x && Tok.is(tok::kw_delete)) {
+        SourceLocation DelLoc = ConsumeToken();
+        Actions.SetDeclDeleted(LastDeclInGroup, DelLoc);
+      } else {
+        OwningExprResult Init(ParseInitializer());
+        if (Init.isInvalid()) {
+          SkipUntil(tok::semi);
+          return 0;
+        }
+        Actions.AddInitializerToDecl(LastDeclInGroup, move(Init));
       }
-      Actions.AddInitializerToDecl(LastDeclInGroup, move(Init));
     } else if (Tok.is(tok::l_paren)) {
       // Parse C++ direct initializer: '(' expression-list ')'
       SourceLocation LParenLoc = ConsumeParen();
@@ -2037,13 +2047,13 @@
 ///         declaration-specifiers declarator
 /// [C++]   declaration-specifiers declarator '=' assignment-expression
 /// [GNU]   declaration-specifiers declarator attributes
-///         declaration-specifiers abstract-declarator[opt] 
-/// [C++]   declaration-specifiers abstract-declarator[opt] 
+///         declaration-specifiers abstract-declarator[opt]
+/// [C++]   declaration-specifiers abstract-declarator[opt]
 ///           '=' assignment-expression
 /// [GNU]   declaration-specifiers abstract-declarator[opt] attributes
 ///
 /// For C++, after the parameter-list, it also parses "cv-qualifier-seq[opt]"
-/// and "exception-specification[opt]"(TODO).
+/// and "exception-specification[opt]".
 ///
 void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D,
                                      AttributeList *AttrList,

Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=67653&r1=67652&r2=67653&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Tue Mar 24 17:27:57 2009
@@ -363,6 +363,7 @@
   virtual void AddInitializerToDecl(DeclTy *dcl, ExprArg init);
   void AddInitializerToDecl(DeclTy *dcl, ExprArg init, bool DirectInit);
   void ActOnUninitializedDecl(DeclTy *dcl);
+  virtual void SetDeclDeleted(DeclTy *dcl, SourceLocation DelLoc);
   virtual DeclTy *FinalizeDeclaratorGroup(Scope *S, DeclTy *Group);
 
   virtual void ActOnFinishKNRParamDeclarations(Scope *S, Declarator &D);

Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=67653&r1=67652&r2=67653&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Tue Mar 24 17:27:57 2009
@@ -2501,3 +2501,19 @@
   CurContext->addDecl(Decl);
   return Decl;
 }
+
+void Sema::SetDeclDeleted(DeclTy *dcl, SourceLocation DelLoc) {
+  Decl *Dcl = static_cast<Decl*>(dcl);
+  FunctionDecl *Fn = dyn_cast<FunctionDecl>(Dcl);
+  if (!Fn) {
+    Diag(DelLoc, diag::err_deleted_non_function);
+    return;
+  }
+  if (const FunctionDecl *Prev = Fn->getPreviousDeclaration()) {
+    Diag(DelLoc, diag::err_deleted_decl_not_first);
+    Diag(Prev->getLocation(), diag::note_previous_declaration);
+    // If the declaration wasn't the first, we delete the function anyway for
+    // recovery.
+  }
+  Fn->setDeleted();
+}

Added: cfe/trunk/test/SemaCXX/deleted-function.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/deleted-function.cpp?rev=67653&view=auto

==============================================================================
--- cfe/trunk/test/SemaCXX/deleted-function.cpp (added)
+++ cfe/trunk/test/SemaCXX/deleted-function.cpp Tue Mar 24 17:27:57 2009
@@ -0,0 +1,22 @@
+// RUN: clang-cc -fsyntax-only -verify -std=c++0x %s
+
+int i = delete; // expected-error {{only functions can have deleted definitions}}
+
+void fn() = delete; // expected-note {{candidate function has been explicitly deleted}}
+
+void fn2(); // expected-note {{previous declaration is here}}
+void fn2() = delete; // expected-error {{deleted definition must be first declaration}}
+
+void fn3() = delete;
+void fn3() {
+  // FIXME: This definition should be invalid.
+}
+
+void ov(int) {} // expected-note {{candidate function}}
+void ov(double) = delete; // expected-note {{candidate function has been explicitly deleted}}
+
+void test() {
+  fn(); // expected-error {{call to deleted function 'fn'}}
+  ov(1);
+  ov(1.0); // expected-error {{call to deleted function 'ov'}}
+}





More information about the cfe-commits mailing list