[cfe-commits] r61442 - in /cfe/trunk: lib/Parse/ParseDecl.cpp lib/Sema/SemaDecl.cpp lib/Sema/SemaDeclCXX.cpp test/SemaCXX/nested-name-spec.cpp

Douglas Gregor dgregor at apple.com
Fri Dec 26 07:00:53 PST 2008


Author: dgregor
Date: Fri Dec 26 09:00:45 2008
New Revision: 61442

URL: http://llvm.org/viewvc/llvm-project?rev=61442&view=rev
Log:
Add support for out-of-line definitions of conversion functions and member operators

Modified:
    cfe/trunk/lib/Parse/ParseDecl.cpp
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/lib/Sema/SemaDeclCXX.cpp
    cfe/trunk/test/SemaCXX/nested-name-spec.cpp

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

==============================================================================
--- cfe/trunk/lib/Parse/ParseDecl.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDecl.cpp Fri Dec 26 09:00:45 2008
@@ -1514,7 +1514,7 @@
 
         // If this identifier is followed by a '<', we may have a template-id.
         DeclTy *Template;
-        if (getLang().CPlusPlus && NextToken().is(tok::less) &&
+        if (NextToken().is(tok::less) &&
             (Template = Actions.isTemplateName(*Tok.getIdentifierInfo(), 
                                                CurScope))) {
           IdentifierInfo *II = Tok.getIdentifierInfo();
@@ -1525,8 +1525,7 @@
         }
         // If this identifier is the name of the current class, it's a
         // constructor name. 
-        else if (getLang().CPlusPlus &&
-                 Actions.isCurrentClassName(*Tok.getIdentifierInfo(), CurScope))
+        else if (Actions.isCurrentClassName(*Tok.getIdentifierInfo(), CurScope))
           D.setConstructor(Actions.isTypeName(*Tok.getIdentifierInfo(),
                                               CurScope),
                            Tok.getLocation());
@@ -1535,9 +1534,21 @@
           D.SetIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());
         ConsumeToken();
         goto PastIdentifier;
-      }
+      } else if (Tok.is(tok::kw_operator)) {
+        SourceLocation OperatorLoc = Tok.getLocation();
 
-      if (Tok.is(tok::tilde)) {
+        // First try the name of an overloaded operator
+        if (OverloadedOperatorKind Op = TryParseOperatorFunctionId()) {
+          D.setOverloadedOperator(Op, OperatorLoc);
+        } else {
+          // This must be a conversion function (C++ [class.conv.fct]).
+          if (TypeTy *ConvType = ParseConversionFunctionId())
+            D.setConversionFunction(ConvType, OperatorLoc);
+          else
+            D.SetIdentifier(0, Tok.getLocation());
+        }
+        goto PastIdentifier;
+      } else if (Tok.is(tok::tilde)) {
         // This should be a C++ destructor.
         SourceLocation TildeLoc = ConsumeToken();
         if (Tok.is(tok::identifier)) {
@@ -1561,22 +1572,6 @@
         goto PastIdentifier;
       }
     }
-
-    if (Tok.is(tok::kw_operator)) {
-      SourceLocation OperatorLoc = Tok.getLocation();
-
-      // First try the name of an overloaded operator
-      if (OverloadedOperatorKind Op = TryParseOperatorFunctionId()) {
-        D.setOverloadedOperator(Op, OperatorLoc);
-      } else {
-        // This must be a conversion function (C++ [class.conv.fct]).
-        if (TypeTy *ConvType = ParseConversionFunctionId())
-          D.setConversionFunction(ConvType, OperatorLoc);
-        else
-          D.SetIdentifier(0, Tok.getLocation());
-      }
-      goto PastIdentifier;
-    }
   }
 
   // If we reached this point, we are either in C/ObjC or the token didn't

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Fri Dec 26 09:00:45 2008
@@ -1186,8 +1186,7 @@
       } else {
         InvalidDecl = InvalidDecl || CheckConversionDeclarator(D, R, SC);
 
-        NewFD = CXXConversionDecl::Create(Context, 
-                                          cast<CXXRecordDecl>(DC),
+        NewFD = CXXConversionDecl::Create(Context, cast<CXXRecordDecl>(DC),
                                           D.getIdentifierLoc(), Name, R,
                                           isInline, isExplicit);
         

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Fri Dec 26 09:00:45 2008
@@ -1230,21 +1230,6 @@
 
   // Make sure we aren't redeclaring the conversion function.
   QualType ConvType = Context.getCanonicalType(Conversion->getConversionType());
-  OverloadedFunctionDecl *Conversions = ClassDecl->getConversionFunctions();
-  for (OverloadedFunctionDecl::function_iterator Func 
-         = Conversions->function_begin();
-       Func != Conversions->function_end(); ++Func) {
-    CXXConversionDecl *OtherConv = cast<CXXConversionDecl>(*Func);
-    if (ConvType == Context.getCanonicalType(OtherConv->getConversionType())) {
-      Diag(Conversion->getLocation(), diag::err_conv_function_redeclared);
-      Diag(OtherConv->getLocation(),
-           OtherConv->isThisDeclarationADefinition()?
-              diag::note_previous_definition
-            : diag::note_previous_declaration);
-      Conversion->setInvalidDecl();
-      return (DeclTy *)Conversion;      
-    }
-  }
 
   // C++ [class.conv.fct]p1:
   //   [...] A conversion function is never used to convert a
@@ -1272,7 +1257,20 @@
       << ClassType << ConvType;
   }
 
-  ClassDecl->addConversionFunction(Context, Conversion);
+  if (Conversion->getPreviousDeclaration()) {
+    OverloadedFunctionDecl *Conversions = ClassDecl->getConversionFunctions();
+    for (OverloadedFunctionDecl::function_iterator 
+           Conv = Conversions->function_begin(),
+           ConvEnd = Conversions->function_end();
+         Conv != ConvEnd; ++Conv) {
+      if (*Conv == Conversion->getPreviousDeclaration()) {
+        *Conv = Conversion;
+        return (DeclTy *)Conversion;
+      }
+    }
+    assert(Conversion->isInvalidDecl() && "Conversion should not get here.");
+  } else 
+    ClassDecl->addConversionFunction(Context, Conversion);
 
   return (DeclTy *)Conversion;
 }

Modified: cfe/trunk/test/SemaCXX/nested-name-spec.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/nested-name-spec.cpp?rev=61442&r1=61441&r2=61442&view=diff

==============================================================================
--- cfe/trunk/test/SemaCXX/nested-name-spec.cpp (original)
+++ cfe/trunk/test/SemaCXX/nested-name-spec.cpp Fri Dec 26 09:00:45 2008
@@ -103,3 +103,23 @@
     }
   }
 }
+
+
+class Operators {
+  Operators operator+(const Operators&) const; // expected-note{{member declaration nearly matches}}
+  operator bool();
+};
+
+Operators Operators::operator+(const Operators&) { // expected-error{{out-of-line definition does not match any declaration in 'Operators'}}
+  Operators ops;
+  return ops;
+}
+
+Operators Operators::operator+(const Operators&) const {
+  Operators ops;
+  return ops;
+}
+
+Operators::operator bool() {
+  return true;
+}





More information about the cfe-commits mailing list