[cfe-commits] r58866 - in /cfe/trunk: include/clang/AST/DeclBase.h include/clang/Basic/DiagnosticKinds.def lib/Parse/ParseDecl.cpp lib/Sema/SemaDecl.cpp test/SemaCXX/destructor.cpp

Argiris Kirtzidis akyrtzi at gmail.com
Fri Nov 7 14:02:31 PST 2008


Author: akirtzidis
Date: Fri Nov  7 16:02:30 2008
New Revision: 58866

URL: http://llvm.org/viewvc/llvm-project?rev=58866&view=rev
Log:
Changes in preparation for nested-name-specifiers.

-When parsing declarators, don't depend on "CurScope->isCXXClassScope() == true" for constructors/destructors
-For C++ member declarations, don't depend on "Declarator.getContext() == Declarator::MemberContext"

Modified:
    cfe/trunk/include/clang/AST/DeclBase.h
    cfe/trunk/include/clang/Basic/DiagnosticKinds.def
    cfe/trunk/lib/Parse/ParseDecl.cpp
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/test/SemaCXX/destructor.cpp

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

==============================================================================
--- cfe/trunk/include/clang/AST/DeclBase.h (original)
+++ cfe/trunk/include/clang/AST/DeclBase.h Fri Nov  7 16:02:30 2008
@@ -310,6 +310,10 @@
     }
   }
 
+  bool isCXXRecord() const {
+    return DeclKind == Decl::CXXRecord;
+  }
+
   const ScopedDecl *getDeclChain() const { return DeclChain; }
   ScopedDecl *getDeclChain() { return DeclChain; }
   void setDeclChain(ScopedDecl *D) { DeclChain = D; }

Modified: cfe/trunk/include/clang/Basic/DiagnosticKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticKinds.def?rev=58866&r1=58865&r2=58866&view=diff

==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticKinds.def Fri Nov  7 16:02:30 2008
@@ -691,6 +691,8 @@
      "copy constructor must pass its first argument by reference")
 
 // C++ destructors
+DIAG(err_destructor_not_member, ERROR,
+     "destructor must be a non-static member function")
 DIAG(err_destructor_cannot_be, ERROR,
      "destructor cannot be declared '%0'")
 DIAG(err_invalid_qualified_destructor, ERROR,

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

==============================================================================
--- cfe/trunk/lib/Parse/ParseDecl.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDecl.cpp Fri Nov  7 16:02:30 2008
@@ -1355,6 +1355,7 @@
 ///         conversion-function-id  [TODO]
 ///          '~' class-name         
 ///         template-id             [TODO]
+///
 void Parser::ParseDirectDeclarator(Declarator &D) {
   // Parse the first direct-declarator seen.
   if (Tok.is(tok::identifier) && D.mayHaveIdentifier()) {
@@ -1362,31 +1363,35 @@
     // Determine whether this identifier is a C++ constructor name or
     // a normal identifier.
     if (getLang().CPlusPlus && 
-        CurScope->isCXXClassScope() &&
         Actions.isCurrentClassName(*Tok.getIdentifierInfo(), CurScope))
       D.SetConstructor(Actions.isTypeName(*Tok.getIdentifierInfo(), CurScope),
                        Tok.getIdentifierInfo(), Tok.getLocation());
     else
       D.SetIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());
     ConsumeToken();
-  } else if (getLang().CPlusPlus && Tok.is(tok::tilde) && 
-             CurScope->isCXXClassScope() && D.mayHaveIdentifier()) {
+  } else if (getLang().CPlusPlus &&
+             Tok.is(tok::tilde) && D.mayHaveIdentifier()) {
     // This should be a C++ destructor.
     SourceLocation TildeLoc = ConsumeToken();
-
-    // Use the next identifier and "~" to form a name for the
-    // destructor. This is useful both for diagnostics and for
-    // correctness of the parser, since we use presence/absence of the
-    // identifier to determine what we parsed.
-    // FIXME: We could end up with a template-id here, once we parse
-    // templates, and will have to do something different to form the
-    // name of the destructor.
-    assert(Tok.is(tok::identifier) && "Expected identifier");
-    IdentifierInfo *II = Tok.getIdentifierInfo();
-    II = &PP.getIdentifierTable().get(std::string("~") + II->getName());
-
-    if (TypeTy *Type = ParseClassName())
-      D.SetDestructor(Type, II, TildeLoc);
+    if (Tok.is(tok::identifier)) {
+      // Use the next identifier and "~" to form a name for the
+      // destructor. This is useful both for diagnostics and for
+      // correctness of the parser, since we use presence/absence of the
+      // identifier to determine what we parsed.
+      // FIXME: We could end up with a template-id here, once we parse
+      // templates, and will have to do something different to form the
+      // name of the destructor.
+      IdentifierInfo *II = Tok.getIdentifierInfo();
+      II = &PP.getIdentifierTable().get(std::string("~") + II->getName());
+
+      if (TypeTy *Type = ParseClassName())
+        D.SetDestructor(Type, II, TildeLoc);
+      else
+        D.SetIdentifier(0, TildeLoc);
+    } else {
+      Diag(Tok, diag::err_expected_class_name);
+      D.SetIdentifier(0, TildeLoc);
+    }
   } else if (Tok.is(tok::kw_operator)) {
     SourceLocation OperatorLoc = Tok.getLocation();
 

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Fri Nov  7 16:02:30 2008
@@ -811,7 +811,7 @@
     FunctionDecl *NewFD;
     if (D.getKind() == Declarator::DK_Constructor) {
       // This is a C++ constructor declaration.
-      assert(D.getContext() == Declarator::MemberContext &&
+      assert(CurContext->isCXXRecord() &&
              "Constructors can only be declared in a member context");
 
       bool isInvalidDecl = CheckConstructorDeclarator(D, R, SC);
@@ -827,21 +827,29 @@
         NewFD->setInvalidDecl();
     } else if (D.getKind() == Declarator::DK_Destructor) {
       // This is a C++ destructor declaration.
-      assert(D.getContext() == Declarator::MemberContext &&
-             "Destructor can only be declared in a member context");
+      if (CurContext->isCXXRecord()) {
+        bool isInvalidDecl = CheckDestructorDeclarator(D, R, SC);
 
-      bool isInvalidDecl = CheckDestructorDeclarator(D, R, SC);
-
-      NewFD = CXXDestructorDecl::Create(Context,
-                                        cast<CXXRecordDecl>(CurContext),
-                                        D.getIdentifierLoc(), II, R, 
-                                        isInline,
-                                        /*isImplicitlyDeclared=*/false);
+        NewFD = CXXDestructorDecl::Create(Context,
+                                          cast<CXXRecordDecl>(CurContext),
+                                          D.getIdentifierLoc(), II, R, 
+                                          isInline,
+                                          /*isImplicitlyDeclared=*/false);
 
-      if (isInvalidDecl)
+        if (isInvalidDecl)
+          NewFD->setInvalidDecl();
+      } else {
+        Diag(D.getIdentifierLoc(), diag::err_destructor_not_member);
+        // Create a FunctionDecl to satisfy the function definition parsing
+        // code path.
+        NewFD = FunctionDecl::Create(Context, CurContext, D.getIdentifierLoc(),
+                                     II, R, SC, isInline, LastDeclarator,
+                                     // FIXME: Move to DeclGroup...
+                                   D.getDeclSpec().getSourceRange().getBegin());
         NewFD->setInvalidDecl();
+      }
     } else if (D.getKind() == Declarator::DK_Conversion) {
-      if (D.getContext() != Declarator::MemberContext) {
+      if (!CurContext->isCXXRecord()) {
         Diag(D.getIdentifierLoc(),
              diag::err_conv_function_not_member);
         return 0;
@@ -856,7 +864,7 @@
         if (isInvalidDecl)
           NewFD->setInvalidDecl();
       }
-    } else if (D.getContext() == Declarator::MemberContext) {
+    } else if (CurContext->isCXXRecord()) {
       // This is a C++ method declaration.
       NewFD = CXXMethodDecl::Create(Context, cast<CXXRecordDecl>(CurContext),
                                     D.getIdentifierLoc(), II, R,
@@ -1037,7 +1045,7 @@
     case DeclSpec::SCS_register:       SC = VarDecl::Register; break;
     case DeclSpec::SCS_private_extern: SC = VarDecl::PrivateExtern; break;
     }    
-    if (D.getContext() == Declarator::MemberContext) {
+    if (CurContext->isCXXRecord()) {
       assert(SC == VarDecl::Static && "Invalid storage class for member!");
       // This is a static data member for a C++ class.
       NewVD = CXXClassVarDecl::Create(Context, cast<CXXRecordDecl>(CurContext),

Modified: cfe/trunk/test/SemaCXX/destructor.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/destructor.cpp?rev=58866&r1=58865&r2=58866&view=diff

==============================================================================
--- cfe/trunk/test/SemaCXX/destructor.cpp (original)
+++ cfe/trunk/test/SemaCXX/destructor.cpp Fri Nov  7 16:02:30 2008
@@ -35,3 +35,6 @@
   ~F(); // expected-error{{destructor cannot be redeclared}}
 };
 
+~; // expected-error {{expected class name}}
+~undef(); // expected-error {{expected class name}}
+~F(){} // expected-error {{destructor must be a non-static member function}}





More information about the cfe-commits mailing list