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

Chris Lattner sabre at nondot.org
Wed Apr 9 23:46:29 PDT 2008


Author: lattner
Date: Thu Apr 10 01:46:29 2008
New Revision: 49468

URL: http://llvm.org/viewvc/llvm-project?rev=49468&view=rev
Log:
refactor Parser::ParseStructDeclaration to return a vector of uninterpreted 
declarators.  This allows the clients (C structs, objc classes, objc 
properties, [future] C++ classes) etc, to do custom processing before invoking
an action.

This has two benefits in the short term:
1) objc ivar processing should be split out of ActOnField into its own ActOn method.
2) the new objc ivar action can take visibility info directly, eliminating 
   AllVisibilities in ParseObjCClassInstanceVariables.
3) objc properties can pass their own special sauce down to sema as well.



Modified:
    cfe/trunk/include/clang/Parse/DeclSpec.h
    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/DeclSpec.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/DeclSpec.h?rev=49468&r1=49467&r2=49468&view=diff

==============================================================================
--- cfe/trunk/include/clang/Parse/DeclSpec.h (original)
+++ cfe/trunk/include/clang/Parse/DeclSpec.h Thu Apr 10 01:46:29 2008
@@ -665,6 +665,17 @@
   bool getInvalidType() const { return InvalidType; }
 };
 
+/// FieldDeclarator - This little struct is used to capture information about
+/// structure field declarators, which is basically just a bitfield size.
+struct FieldDeclarator {
+  Declarator D;
+  Action::ExprTy *BitfieldSize;
+  FieldDeclarator(DeclSpec &DS) : D(DS, Declarator::MemberContext) {
+    BitfieldSize = 0;
+  }
+};
+
+
 } // end namespace clang
 
 #endif

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

==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Thu Apr 10 01:46:29 2008
@@ -21,6 +21,7 @@
   class DeclSpec;
   class ObjCDeclSpec;
   class Declarator;
+  class FieldDeclarator;
   class AttributeList;
   class Scope;
 
@@ -453,8 +454,8 @@
   void ParseStructUnionSpecifier(DeclSpec &DS);
   void ParseStructUnionBody(SourceLocation StartLoc, unsigned TagType,
                             DeclTy *TagDecl);
-  void ParseStructDeclaration(DeclTy *TagDecl,
-                              llvm::SmallVectorImpl<DeclTy*> &FieldDecls);
+  void ParseStructDeclaration(DeclSpec &DS,
+                              llvm::SmallVectorImpl<FieldDeclarator> &Fields);
                               
   bool isDeclarationSpecifier() const;
   bool isTypeSpecifierQualifier() const;

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

==============================================================================
--- cfe/trunk/lib/Parse/ParseDecl.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDecl.cpp Thu Apr 10 01:46:29 2008
@@ -657,14 +657,14 @@
 ///         declarator[opt] ':' constant-expression
 /// [GNU]   declarator[opt] ':' constant-expression attributes[opt]
 ///
-void Parser::ParseStructDeclaration(DeclTy *TagDecl,
-  llvm::SmallVectorImpl<DeclTy*> &FieldDecls) {
+void Parser::
+ParseStructDeclaration(DeclSpec &DS,
+                       llvm::SmallVectorImpl<FieldDeclarator> &Fields) {
   // FIXME: When __extension__ is specified, disable extension diagnostics.
-  if (Tok.is(tok::kw___extension__))
+  while (Tok.is(tok::kw___extension__))
     ConsumeToken();
   
   // Parse the common specifier-qualifiers-list piece.
-  DeclSpec DS;
   SourceLocation DSStart = Tok.getLocation();
   ParseSpecifierQualifierList(DS);
   // TODO: Does specifier-qualifier list correctly check that *something* is
@@ -677,33 +677,27 @@
   }
 
   // Read struct-declarators until we find the semicolon.
-  Declarator DeclaratorInfo(DS, Declarator::MemberContext);
-
+  Fields.push_back(DS);
   while (1) {
+    FieldDeclarator &DeclaratorInfo = Fields.back();
+    
     /// struct-declarator: declarator
     /// struct-declarator: declarator[opt] ':' constant-expression
     if (Tok.isNot(tok::colon))
-      ParseDeclarator(DeclaratorInfo);
+      ParseDeclarator(DeclaratorInfo.D);
     
-    ExprTy *BitfieldSize = 0;
     if (Tok.is(tok::colon)) {
       ConsumeToken();
       ExprResult Res = ParseConstantExpression();
       if (Res.isInvalid)
         SkipUntil(tok::semi, true, true);
       else
-        BitfieldSize = Res.Val;
+        DeclaratorInfo.BitfieldSize = Res.Val;
     }
     
     // If attributes exist after the declarator, parse them.
     if (Tok.is(tok::kw___attribute))
-      DeclaratorInfo.AddAttributes(ParseAttributes());
-    
-    // Install the declarator into the current TagDecl.
-    DeclTy *Field = Actions.ActOnField(CurScope, TagDecl,
-                                       DS.getSourceRange().getBegin(),
-                                       DeclaratorInfo, BitfieldSize);
-    FieldDecls.push_back(Field);
+      DeclaratorInfo.D.AddAttributes(ParseAttributes());
     
     // If we don't have a comma, it is either the end of the list (a ';')
     // or an error, bail out.
@@ -714,11 +708,11 @@
     ConsumeToken();
     
     // Parse the next declarator.
-    DeclaratorInfo.clear();
+    Fields.push_back(DS);
     
     // Attributes are only allowed on the second declarator.
     if (Tok.is(tok::kw___attribute))
-      DeclaratorInfo.AddAttributes(ParseAttributes());
+      Fields.back().D.AddAttributes(ParseAttributes());
   }
 }
 
@@ -743,7 +737,8 @@
          DeclSpec::getSpecifierName((DeclSpec::TST)TagType));
 
   llvm::SmallVector<DeclTy*, 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)) {
     // Each iteration of this loop reads one struct-declaration.
@@ -754,7 +749,22 @@
       ConsumeToken();
       continue;
     }
-    ParseStructDeclaration(TagDecl, FieldDecls);
+
+    // 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 the current TagDecl.
+      DeclTy *Field = Actions.ActOnField(CurScope, TagDecl,
+                                         DS.getSourceRange().getBegin(),
+                                         FD.D, FD.BitfieldSize);
+      FieldDecls.push_back(Field);
+    }
+    
 
     if (Tok.is(tok::semi)) {
       ConsumeToken();

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

==============================================================================
--- cfe/trunk/lib/Parse/ParseObjc.cpp (original)
+++ cfe/trunk/lib/Parse/ParseObjc.cpp Thu Apr 10 01:46:29 2008
@@ -378,16 +378,31 @@
                                               SourceLocation AtLoc) {
   assert(Tok.isObjCAtKeyword(tok::objc_property) &&
          "ParseObjCPropertyDecl(): Expected @property");
-  ObjCDeclSpec DS;
+  ObjCDeclSpec OCDS;
   ConsumeToken(); // the "property" identifier
   // Parse property attribute list, if any. 
   if (Tok.is(tok::l_paren)) {
     // property has attribute list.
-    ParseObjCPropertyAttribute(DS);
+    ParseObjCPropertyAttribute(OCDS);
   }
   // Parse declaration portion of @property.
   llvm::SmallVector<DeclTy*, 8> PropertyDecls;
-  ParseStructDeclaration(interfaceDecl, PropertyDecls);
+  
+  // Parse all the comma separated declarators.
+  DeclSpec DS;
+  llvm::SmallVector<FieldDeclarator, 8> FieldDeclarators;
+  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.
+    DeclTy *Field = Actions.ActOnField(CurScope, interfaceDecl,
+                                       DS.getSourceRange().getBegin(),
+                                       FD.D, FD.BitfieldSize);
+    PropertyDecls.push_back(Field);
+  }
+  
   if (Tok.is(tok::semi)) 
     ConsumeToken();
   else {
@@ -395,7 +410,7 @@
     SkipUntil(tok::r_brace, true, true);
   }
   return Actions.ActOnAddObjCProperties(AtLoc,  &PropertyDecls[0],
-                                        PropertyDecls.size(), DS);
+                                        PropertyDecls.size(), OCDS);
 }
 
 ///   objc-method-proto:
@@ -756,10 +771,10 @@
 void Parser::ParseObjCClassInstanceVariables(DeclTy *interfaceDecl,
                                              SourceLocation atLoc) {
   assert(Tok.is(tok::l_brace) && "expected {");
-  llvm::SmallVector<DeclTy*, 16> IvarDecls;
   llvm::SmallVector<DeclTy*, 32> AllIvarDecls;
   llvm::SmallVector<tok::ObjCKeywordKind, 32> AllVisibilities;
-  
+  llvm::SmallVector<FieldDeclarator, 8> FieldDeclarators;
+
   SourceLocation LBraceLoc = ConsumeBrace(); // the "{"
   
   tok::ObjCKeywordKind visibility = tok::objc_private;
@@ -773,6 +788,7 @@
       ConsumeToken();
       continue;
     }
+    
     // Set the default visibility to private.
     if (Tok.is(tok::at)) { // parse objc-visibility-spec
       ConsumeToken(); // eat the @ sign
@@ -786,16 +802,25 @@
         continue; 
       default:
         Diag(Tok, diag::err_objc_illegal_visibility_spec);
-        ConsumeToken();
         continue;
       }
     }
-    ParseStructDeclaration(interfaceDecl, IvarDecls);
-    for (unsigned i = 0; i < IvarDecls.size(); i++) {
-      AllIvarDecls.push_back(IvarDecls[i]);
+    
+    // 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.
+      DeclTy *Field = Actions.ActOnField(CurScope, interfaceDecl,
+                                         DS.getSourceRange().getBegin(),
+                                         FD.D, FD.BitfieldSize);
+      AllIvarDecls.push_back(Field);
       AllVisibilities.push_back(visibility);
     }
-    IvarDecls.clear();
     
     if (Tok.is(tok::semi)) {
       ConsumeToken();





More information about the cfe-commits mailing list