[cfe-commits] r85855 - in /cfe/trunk: include/clang/Parse/Parser.h lib/Parse/ParseDecl.cpp lib/Parse/ParseObjc.cpp

John McCall rjmccall at apple.com
Mon Nov 2 18:38:08 PST 2009


Author: rjmccall
Date: Mon Nov  2 20:38:08 2009
New Revision: 85855

URL: http://llvm.org/viewvc/llvm-project?rev=85855&view=rev
Log:
Switch ParseStructDeclaration to a callback-based API.  This will make
it easier to track within Sema whether the parser is parsing a declaration.


Modified:
    cfe/trunk/include/clang/Parse/Parser.h
    cfe/trunk/lib/Parse/ParseDecl.cpp
    cfe/trunk/lib/Parse/ParseObjc.cpp

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

==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Mon Nov  2 20:38:08 2009
@@ -979,8 +979,12 @@
   void ParseEnumBody(SourceLocation StartLoc, DeclPtrTy TagDecl);
   void ParseStructUnionBody(SourceLocation StartLoc, unsigned TagType,
                             DeclPtrTy TagDecl);
-  void ParseStructDeclaration(DeclSpec &DS,
-                              llvm::SmallVectorImpl<FieldDeclarator> &Fields);
+
+  struct FieldCallback {
+    virtual DeclPtrTy invoke(FieldDeclarator &Field) = 0;
+  };
+
+  void ParseStructDeclaration(DeclSpec &DS, FieldCallback &Callback);
 
   bool isDeclarationSpecifier();
   bool isTypeSpecifierQualifier();

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

==============================================================================
--- cfe/trunk/lib/Parse/ParseDecl.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDecl.cpp Mon Nov  2 20:38:08 2009
@@ -1468,8 +1468,7 @@
 /// [GNU]   declarator[opt] ':' constant-expression attributes[opt]
 ///
 void Parser::
-ParseStructDeclaration(DeclSpec &DS,
-                       llvm::SmallVectorImpl<FieldDeclarator> &Fields) {
+ParseStructDeclaration(DeclSpec &DS, FieldCallback &Fields) {
   if (Tok.is(tok::kw___extension__)) {
     // __extension__ silences extension warnings in the subexpression.
     ExtensionRAIIObject O(Diags);  // Use RAII to do this.
@@ -1489,9 +1488,16 @@
   }
 
   // Read struct-declarators until we find the semicolon.
-  Fields.push_back(FieldDeclarator(DS));
+  bool FirstDeclarator = true;
   while (1) {
-    FieldDeclarator &DeclaratorInfo = Fields.back();
+    FieldDeclarator DeclaratorInfo(DS);
+
+    // Attributes are only allowed here on successive declarators.
+    if (!FirstDeclarator && Tok.is(tok::kw___attribute)) {
+      SourceLocation Loc;
+      AttributeList *AttrList = ParseAttributes(&Loc);
+      DeclaratorInfo.D.AddAttributes(AttrList, Loc);
+    }
 
     /// struct-declarator: declarator
     /// struct-declarator: declarator[opt] ':' constant-expression
@@ -1514,6 +1520,9 @@
       DeclaratorInfo.D.AddAttributes(AttrList, Loc);
     }
 
+    // We're done with this declarator;  invoke the callback.
+    (void) Fields.invoke(DeclaratorInfo);
+
     // If we don't have a comma, it is either the end of the list (a ';')
     // or an error, bail out.
     if (Tok.isNot(tok::comma))
@@ -1522,15 +1531,7 @@
     // Consume the comma.
     ConsumeToken();
 
-    // Parse the next declarator.
-    Fields.push_back(FieldDeclarator(DS));
-
-    // Attributes are only allowed on the second declarator.
-    if (Tok.is(tok::kw___attribute)) {
-      SourceLocation Loc;
-      AttributeList *AttrList = ParseAttributes(&Loc);
-      Fields.back().D.AddAttributes(AttrList, Loc);
-    }
+    FirstDeclarator = false;
   }
 }
 
@@ -1562,7 +1563,6 @@
       << DeclSpec::getSpecifierName((DeclSpec::TST)TagType);
 
   llvm::SmallVector<DeclPtrTy, 32> FieldDecls;
-  llvm::SmallVector<FieldDeclarator, 8> FieldDeclarators;
 
   // While we still have something to read, read the declarations in the struct.
   while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
@@ -1578,28 +1578,39 @@
 
     // Parse all the comma separated declarators.
     DeclSpec DS;
-    FieldDeclarators.clear();
-    if (!Tok.is(tok::at)) {
-      ParseStructDeclaration(DS, FieldDeclarators);
 
-      // Convert them all to fields.
-      for (unsigned i = 0, e = FieldDeclarators.size(); i != e; ++i) {
-        FieldDeclarator &FD = FieldDeclarators[i];
-        DeclPtrTy Field;
-        // Install the declarator into the current TagDecl.
-        if (FD.D.getExtension()) {
-          // Silences extension warnings
-          ExtensionRAIIObject O(Diags);
-          Field = Actions.ActOnField(CurScope, TagDecl,
-                                     DS.getSourceRange().getBegin(),
-                                     FD.D, FD.BitfieldSize);
-        } else {
-          Field = Actions.ActOnField(CurScope, TagDecl,
-                                     DS.getSourceRange().getBegin(),
-                                     FD.D, FD.BitfieldSize);
+    if (!Tok.is(tok::at)) {
+      struct CFieldCallback : FieldCallback {
+        Parser &P;
+        DeclPtrTy TagDecl;
+        llvm::SmallVectorImpl<DeclPtrTy> &FieldDecls;
+
+        CFieldCallback(Parser &P, DeclPtrTy TagDecl,
+                       llvm::SmallVectorImpl<DeclPtrTy> &FieldDecls) :
+          P(P), TagDecl(TagDecl), FieldDecls(FieldDecls) {}
+
+        virtual DeclPtrTy invoke(FieldDeclarator &FD) {
+          const DeclSpec &DS = FD.D.getDeclSpec();
+          DeclPtrTy Field;
+
+          // Install the declarator into the current TagDecl.
+          if (FD.D.getExtension()) {
+            // Silences extension warnings
+            ExtensionRAIIObject O(P.Diags);
+            Field = P.Actions.ActOnField(P.CurScope, TagDecl,
+                                         DS.getSourceRange().getBegin(),
+                                         FD.D, FD.BitfieldSize);
+          } else {
+            Field = P.Actions.ActOnField(P.CurScope, TagDecl,
+                                         DS.getSourceRange().getBegin(),
+                                         FD.D, FD.BitfieldSize);
+          }
+          FieldDecls.push_back(Field);
+          return Field;
         }
-        FieldDecls.push_back(Field);
-      }
+      } Callback(*this, TagDecl, FieldDecls);
+
+      ParseStructDeclaration(DS, Callback);
     } else { // Handle @defs
       ConsumeToken();
       if (!Tok.isObjCAtKeyword(tok::objc_defs)) {

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

==============================================================================
--- cfe/trunk/lib/Parse/ParseObjc.cpp (original)
+++ cfe/trunk/lib/Parse/ParseObjc.cpp Mon Nov  2 20:38:08 2009
@@ -305,51 +305,68 @@
       if (Tok.is(tok::l_paren))
         ParseObjCPropertyAttribute(OCDS);
 
+      struct ObjCPropertyCallback : FieldCallback {
+        Parser &P;
+        DeclPtrTy IDecl;
+        llvm::SmallVectorImpl<DeclPtrTy> &Props;
+        ObjCDeclSpec &OCDS;
+        SourceLocation AtLoc;
+        tok::ObjCKeywordKind MethodImplKind;
+        
+        ObjCPropertyCallback(Parser &P, DeclPtrTy IDecl,
+                             llvm::SmallVectorImpl<DeclPtrTy> &Props,
+                             ObjCDeclSpec &OCDS, SourceLocation AtLoc,
+                             tok::ObjCKeywordKind MethodImplKind) :
+          P(P), IDecl(IDecl), Props(Props), OCDS(OCDS), AtLoc(AtLoc),
+          MethodImplKind(MethodImplKind) {
+        }
+
+        DeclPtrTy invoke(FieldDeclarator &FD) {
+          if (FD.D.getIdentifier() == 0) {
+            P.Diag(AtLoc, diag::err_objc_property_requires_field_name)
+              << FD.D.getSourceRange();
+            return DeclPtrTy();
+          }
+          if (FD.BitfieldSize) {
+            P.Diag(AtLoc, diag::err_objc_property_bitfield)
+              << FD.D.getSourceRange();
+            return DeclPtrTy();
+          }
+
+          // Install the property declarator into interfaceDecl.
+          IdentifierInfo *SelName =
+            OCDS.getGetterName() ? OCDS.getGetterName() : FD.D.getIdentifier();
+
+          Selector GetterSel =
+            P.PP.getSelectorTable().getNullarySelector(SelName);
+          IdentifierInfo *SetterName = OCDS.getSetterName();
+          Selector SetterSel;
+          if (SetterName)
+            SetterSel = P.PP.getSelectorTable().getSelector(1, &SetterName);
+          else
+            SetterSel = SelectorTable::constructSetterName(P.PP.getIdentifierTable(),
+                                                           P.PP.getSelectorTable(),
+                                                           FD.D.getIdentifier());
+          bool isOverridingProperty = false;
+          DeclPtrTy Property =
+            P.Actions.ActOnProperty(P.CurScope, AtLoc, FD, OCDS,
+                                    GetterSel, SetterSel, IDecl,
+                                    &isOverridingProperty,
+                                    MethodImplKind);
+          if (!isOverridingProperty)
+            Props.push_back(Property);
+
+          return Property;
+        }
+      } Callback(*this, interfaceDecl, allProperties,
+                 OCDS, AtLoc, MethodImplKind);
+
       // Parse all the comma separated declarators.
       DeclSpec DS;
-      llvm::SmallVector<FieldDeclarator, 8> FieldDeclarators;
-      ParseStructDeclaration(DS, FieldDeclarators);
+      ParseStructDeclaration(DS, Callback);
 
       ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list, "",
                        tok::at);
-
-      // Convert them all to property declarations.
-      for (unsigned i = 0, e = FieldDeclarators.size(); i != e; ++i) {
-        FieldDeclarator &FD = FieldDeclarators[i];
-        if (FD.D.getIdentifier() == 0) {
-          Diag(AtLoc, diag::err_objc_property_requires_field_name)
-            << FD.D.getSourceRange();
-          continue;
-        }
-        if (FD.BitfieldSize) {
-          Diag(AtLoc, diag::err_objc_property_bitfield)
-            << FD.D.getSourceRange();
-          continue;
-        }
-
-        // Install the property declarator into interfaceDecl.
-        IdentifierInfo *SelName =
-          OCDS.getGetterName() ? OCDS.getGetterName() : FD.D.getIdentifier();
-
-        Selector GetterSel =
-          PP.getSelectorTable().getNullarySelector(SelName);
-        IdentifierInfo *SetterName = OCDS.getSetterName();
-        Selector SetterSel;
-        if (SetterName)
-          SetterSel = PP.getSelectorTable().getSelector(1, &SetterName);
-        else
-          SetterSel = SelectorTable::constructSetterName(PP.getIdentifierTable(),
-                                                         PP.getSelectorTable(),
-                                                         FD.D.getIdentifier());
-        bool isOverridingProperty = false;
-        DeclPtrTy Property = Actions.ActOnProperty(CurScope, AtLoc, FD, OCDS,
-                                                   GetterSel, SetterSel,
-                                                   interfaceDecl,
-                                                   &isOverridingProperty,
-                                                   MethodImplKind);
-        if (!isOverridingProperty)
-          allProperties.push_back(Property);
-      }
       break;
     }
   }
@@ -858,7 +875,6 @@
                                              SourceLocation atLoc) {
   assert(Tok.is(tok::l_brace) && "expected {");
   llvm::SmallVector<DeclPtrTy, 32> AllIvarDecls;
-  llvm::SmallVector<FieldDeclarator, 8> FieldDeclarators;
 
   ParseScope ClassScope(this, Scope::DeclScope|Scope::ClassScope);
 
@@ -893,21 +909,31 @@
       }
     }
 
+    struct ObjCIvarCallback : FieldCallback {
+      Parser &P;
+      DeclPtrTy IDecl;
+      tok::ObjCKeywordKind visibility;
+      llvm::SmallVectorImpl<DeclPtrTy> &AllIvarDecls;
+
+      ObjCIvarCallback(Parser &P, DeclPtrTy IDecl, tok::ObjCKeywordKind V,
+                       llvm::SmallVectorImpl<DeclPtrTy> &AllIvarDecls) :
+        P(P), IDecl(IDecl), visibility(V), AllIvarDecls(AllIvarDecls) {
+      }
+
+      DeclPtrTy invoke(FieldDeclarator &FD) {
+        // Install the declarator into the interface decl.
+        DeclPtrTy Field
+          = P.Actions.ActOnIvar(P.CurScope,
+                                FD.D.getDeclSpec().getSourceRange().getBegin(),
+                                IDecl, FD.D, FD.BitfieldSize, visibility);
+        AllIvarDecls.push_back(Field);
+        return Field;
+      }
+    } Callback(*this, interfaceDecl, visibility, AllIvarDecls);
+
     // Parse all the comma separated declarators.
     DeclSpec DS;
-    FieldDeclarators.clear();
-    ParseStructDeclaration(DS, FieldDeclarators);
-
-    // Convert them all to fields.
-    for (unsigned i = 0, e = FieldDeclarators.size(); i != e; ++i) {
-      FieldDeclarator &FD = FieldDeclarators[i];
-      // Install the declarator into interfaceDecl.
-      DeclPtrTy Field = Actions.ActOnIvar(CurScope,
-                                          DS.getSourceRange().getBegin(),
-                                          interfaceDecl,
-                                          FD.D, FD.BitfieldSize, visibility);
-      AllIvarDecls.push_back(Field);
-    }
+    ParseStructDeclaration(DS, Callback);
 
     if (Tok.is(tok::semi)) {
       ConsumeToken();





More information about the cfe-commits mailing list