[cfe-commits] r142195 - in /cfe/trunk: lib/Parse/ParseCXXInlineMethods.cpp lib/Parse/ParseDeclCXX.cpp test/SemaCXX/MicrosoftExtensions.cpp

Douglas Gregor dgregor at apple.com
Mon Oct 17 10:09:53 PDT 2011


Author: dgregor
Date: Mon Oct 17 12:09:53 2011
New Revision: 142195

URL: http://llvm.org/viewvc/llvm-project?rev=142195&view=rev
Log:
When we end up having to parse the initializer of a C++ member early
in -fms-extensions mode, make sure we actually use that initializer
after having handled the declaration. Fixes PR11150.


Modified:
    cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp
    cfe/trunk/lib/Parse/ParseDeclCXX.cpp
    cfe/trunk/test/SemaCXX/MicrosoftExtensions.cpp

Modified: cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp?rev=142195&r1=142194&r2=142195&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp (original)
+++ cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp Mon Oct 17 12:09:53 2011
@@ -43,13 +43,13 @@
   else {
     FnD = Actions.ActOnCXXMemberDeclarator(getCurScope(), AS, D,
                                            move(TemplateParams), 0, 
-                                           VS, /*HasInit=*/false);
+                                           VS, /*HasDeferredInit=*/false);
     if (FnD) {
       Actions.ProcessDeclAttributeList(getCurScope(), FnD, AccessAttrs,
                                        false, true);
       bool TypeSpecContainsAuto
         = D.getDeclSpec().getTypeSpecType() == DeclSpec::TST_auto;
-      if (Init.get())
+      if (Init.isUsable())
         Actions.AddInitializerToDecl(FnD, Init.get(), false, 
                                      TypeSpecContainsAuto);
       else

Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=142195&r1=142194&r2=142195&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Mon Oct 17 12:09:53 2011
@@ -1711,6 +1711,9 @@
   // Hold late-parsed attributes so we can attach a Decl to them later.
   LateParsedAttrList LateParsedAttrs;
 
+  SourceLocation EqualLoc;
+  bool HasInitializer = false;
+  ExprResult Init;
   if (Tok.isNot(tok::colon)) {
     // Don't parse FOO:BAR as if it were a typo for FOO::BAR.
     ColonProtectionRAIIObject X(*this);
@@ -1733,14 +1736,15 @@
 
     // MSVC permits pure specifier on inline functions declared at class scope.
     // Hence check for =0 before checking for function definition.
-    ExprResult Init;
     if (getLang().MicrosoftExt && Tok.is(tok::equal) &&
         DeclaratorInfo.isFunctionDeclarator() && 
         NextToken().is(tok::numeric_constant)) {
-      ConsumeToken();
+      EqualLoc = ConsumeToken();
       Init = ParseInitializer();
       if (Init.isInvalid())
         SkipUntil(tok::comma, true, true);
+      else
+        HasInitializer = true;
     }
 
     bool IsDefinition = false;
@@ -1842,9 +1846,8 @@
     // goes before or after the GNU attributes and __asm__.
     ParseOptionalCXX0XVirtSpecifierSeq(VS);
 
-    bool HasInitializer = false;
     bool HasDeferredInitializer = false;
-    if (Tok.is(tok::equal) || Tok.is(tok::l_brace)) {
+    if ((Tok.is(tok::equal) || Tok.is(tok::l_brace)) && !HasInitializer) {
       if (BitfieldSize.get()) {
         Diag(Tok, diag::err_bitfield_member_init);
         SkipUntil(tok::comma, true, true);
@@ -1905,15 +1908,15 @@
         ParseCXXNonStaticMemberInitializer(ThisDecl);
     } else if (HasInitializer) {
       // Normal initializer.
-      SourceLocation EqualLoc;
-      ExprResult Init
-        = ParseCXXMemberInitializer(DeclaratorInfo.isDeclarationOfFunction(), 
-                                    EqualLoc);
+      if (!Init.isUsable())
+        Init = ParseCXXMemberInitializer(
+                 DeclaratorInfo.isDeclarationOfFunction(), EqualLoc);
+      
       if (Init.isInvalid())
         SkipUntil(tok::comma, true, true);
       else if (ThisDecl)
         Actions.AddInitializerToDecl(ThisDecl, Init.get(), false,
-                                   DS.getTypeSpecType() == DeclSpec::TST_auto);
+                                   DS.getTypeSpecType() == DeclSpec::TST_auto);      
     } else if (ThisDecl && DS.getStorageClassSpec() == DeclSpec::SCS_static) {
       // No initializer.
       Actions.ActOnUninitializedDecl(ThisDecl, 
@@ -1945,6 +1948,8 @@
     DeclaratorInfo.clear();
     VS.clear();
     BitfieldSize = true;
+    Init = true;
+    HasInitializer = false;
 
     // Attributes are only allowed on the second declarator.
     MaybeParseGNUAttributes(DeclaratorInfo);

Modified: cfe/trunk/test/SemaCXX/MicrosoftExtensions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/MicrosoftExtensions.cpp?rev=142195&r1=142194&r2=142195&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/MicrosoftExtensions.cpp (original)
+++ cfe/trunk/test/SemaCXX/MicrosoftExtensions.cpp Mon Oct 17 12:09:53 2011
@@ -203,3 +203,10 @@
 
 }
 
+struct PR11150 {
+  class X {
+    virtual void f() = 0;
+  };
+
+  int array[__is_abstract(X)? 1 : -1];
+};





More information about the cfe-commits mailing list