[cfe-commits] r38992 - in /cfe/cfe/trunk: AST/ASTStreamer.cpp AST/Sema.cpp Driver/PrintParserCallbacks.cpp Driver/clang.cpp Parse/MinimalAction.cpp Parse/ParseDecl.cpp Parse/Parser.cpp Sema/ASTStreamer.cpp Sema/Sema.cpp include/clang/AST/Decl.h include/clang/Parse/Action.h include/clang/Parse/Parser.h

sabre at cs.uiuc.edu sabre at cs.uiuc.edu
Wed Jul 11 09:26:36 PDT 2007


Author: sabre
Date: Wed Jul 11 11:26:35 2007
New Revision: 38992

URL: http://llvm.org/viewvc/llvm-project?rev=38992&view=rev
Log:
Changes through out the parser and actions/ast interface to return top-level
declarations through the asm streamer.  For a testcase like:

int G;
int H, I, *J;
int func() {}

'clang -parse-print-ast' prints:

Read top-level decl: G
Read top-level decl: H
Read top-level decl: I
Read top-level decl: J
Read top-level decl: func

Modified:
    cfe/cfe/trunk/AST/ASTStreamer.cpp
    cfe/cfe/trunk/AST/Sema.cpp
    cfe/cfe/trunk/Driver/PrintParserCallbacks.cpp
    cfe/cfe/trunk/Driver/clang.cpp
    cfe/cfe/trunk/Parse/MinimalAction.cpp
    cfe/cfe/trunk/Parse/ParseDecl.cpp
    cfe/cfe/trunk/Parse/Parser.cpp
    cfe/cfe/trunk/Sema/ASTStreamer.cpp
    cfe/cfe/trunk/Sema/Sema.cpp
    cfe/cfe/trunk/include/clang/AST/Decl.h
    cfe/cfe/trunk/include/clang/Parse/Action.h
    cfe/cfe/trunk/include/clang/Parse/Parser.h

Modified: cfe/cfe/trunk/AST/ASTStreamer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/AST/ASTStreamer.cpp?rev=38992&r1=38991&r2=38992&view=diff

==============================================================================
--- cfe/cfe/trunk/AST/ASTStreamer.cpp (original)
+++ cfe/cfe/trunk/AST/ASTStreamer.cpp Wed Jul 11 11:26:35 2007
@@ -19,15 +19,17 @@
 
 /// Interface to the Builder.cpp file.
 ///
-Action *CreateASTBuilderActions(Preprocessor &PP, bool FullLocInfo);
+Action *CreateASTBuilderActions(Preprocessor &PP, bool FullLocInfo,
+                                std::vector<Decl*> &LastInGroupList);
 
 
 namespace {
   class ASTStreamer {
     Parser P;
+    std::vector<Decl*> LastInGroupList;
   public:
     ASTStreamer(Preprocessor &PP, unsigned MainFileID, bool FullLocInfo)
-      : P(PP, *CreateASTBuilderActions(PP, FullLocInfo)) {
+      : P(PP, *CreateASTBuilderActions(PP, FullLocInfo, LastInGroupList)) {
       PP.EnterSourceFile(MainFileID, 0, true);
       
       // Initialize the parser.
@@ -37,9 +39,33 @@
     /// ReadTopLevelDecl - Parse and return the next top-level declaration.
     Decl *ReadTopLevelDecl() {
       Parser::DeclTy *Result;
-      if (P.ParseTopLevelDecl(Result))
-        return 0;
-      Result = (Decl*)1; // FIXME!
+      
+      /// If the previous time through we read something like 'int X, Y', return
+      /// the next declarator.
+      if (!LastInGroupList.empty()) {
+        Result = LastInGroupList.back();
+        LastInGroupList.pop_back();
+        return (Decl*)Result;
+      }
+
+      do {
+        if (P.ParseTopLevelDecl(Result))
+          return 0;  // End of file.
+
+        // If we got a null return and something *was* parsed, try again.  This
+        // is due to a top-level semicolon, an action override, or a parse error
+        // skipping something.
+      } while (Result == 0);
+
+      // If we parsed a declspec with multiple declarators, reverse the list and
+      // return the first one.
+      if (!LastInGroupList.empty()) {
+        LastInGroupList.push_back((Decl*)Result);
+        std::reverse(LastInGroupList.begin(), LastInGroupList.end());
+        Result = LastInGroupList.back();
+        LastInGroupList.pop_back();
+      }
+
       return (Decl*)Result;
     }
     

Modified: cfe/cfe/trunk/AST/Sema.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/AST/Sema.cpp?rev=38992&r1=38991&r2=38992&view=diff

==============================================================================
--- cfe/cfe/trunk/AST/Sema.cpp (original)
+++ cfe/cfe/trunk/AST/Sema.cpp Wed Jul 11 11:26:35 2007
@@ -31,16 +31,25 @@
   /// FullLocInfo - If this is true, the ASTBuilder constructs AST Nodes that
   /// capture maximal location information for each source-language construct.
   bool FullLocInfo;
+  
+  /// LastInGroupList - This vector is populated when there are multiple
+  /// declarators in a single decl group (e.g. "int A, B, C").  In this case,
+  /// all but the last decl will be entered into this.  This is used by the
+  /// ASTStreamer.
+  std::vector<Decl*> &LastInGroupList;
 public:
-  ASTBuilder(Preprocessor &pp, bool fullLocInfo)
-    : PP(pp), FullLocInfo(fullLocInfo) {}
+  ASTBuilder(Preprocessor &pp, bool fullLocInfo,
+             std::vector<Decl*> &prevInGroup)
+    : PP(pp), FullLocInfo(fullLocInfo), LastInGroupList(prevInGroup) {}
   
   //===--------------------------------------------------------------------===//
   // Symbol table tracking callbacks.
   //
   virtual bool isTypedefName(const IdentifierInfo &II, Scope *S) const;
-  virtual void ParseDeclarator(SourceLocation Loc, Scope *S, Declarator &D,
-                               ExprTy *Init);
+  virtual DeclTy *ParseDeclarator(Scope *S, Declarator &D, ExprTy *Init,
+                                  DeclTy *LastInGroup);
+  virtual DeclTy *ParseFunctionDefinition(Scope *S, Declarator &D,
+                                          StmtTy *Body);
   virtual void PopScope(SourceLocation Loc, Scope *S);
   
   //===--------------------------------------------------------------------===//
@@ -103,16 +112,17 @@
   return D != 0 && D->getDeclSpec().StorageClassSpec == DeclSpec::SCS_typedef;
 }
 
-void ASTBuilder::ParseDeclarator(SourceLocation Loc, Scope *S, Declarator &D,
-                                 ExprTy *Init) {
+Action::DeclTy *
+ASTBuilder::ParseDeclarator(Scope *S, Declarator &D, ExprTy *Init, 
+                            DeclTy *LastInGroup) {
   IdentifierInfo *II = D.getIdentifier();
   Decl *PrevDecl = II ? II->getFETokenInfo<Decl>() : 0;
 
   Decl *New;
   if (D.isFunctionDeclarator())
-    New = new FunctionDecl(II, D, Loc, PrevDecl);
+    New = new FunctionDecl(II, D, PrevDecl);
   else
-    New = new VarDecl(II, D, Loc, PrevDecl);
+    New = new VarDecl(II, D, PrevDecl);
   
   // If this has an identifier, add it to the scope stack.
   if (II) {
@@ -120,6 +130,17 @@
     II->setFETokenInfo(New);
     S->AddDecl(II);
   }
+  
+  if (LastInGroup) LastInGroupList.push_back((Decl*)LastInGroup);
+  
+  return New;
+}
+
+Action::DeclTy *
+ASTBuilder::ParseFunctionDefinition(Scope *S, Declarator &D, StmtTy *Body) {
+  FunctionDecl *FD = (FunctionDecl *)ParseDeclarator(S, D, 0, 0);
+  // TODO: more stuff.
+  return FD;
 }
 
 void ASTBuilder::PopScope(SourceLocation Loc, Scope *S) {
@@ -359,9 +380,8 @@
 
 /// Interface to the Builder.cpp file.
 ///
-Action *CreateASTBuilderActions(Preprocessor &PP, bool FullLocInfo) {
-  return new ASTBuilder(PP, FullLocInfo);
+Action *CreateASTBuilderActions(Preprocessor &PP, bool FullLocInfo,
+                                std::vector<Decl*> &LastInGroupList) {
+  return new ASTBuilder(PP, FullLocInfo, LastInGroupList);
 }
 
-
-

Modified: cfe/cfe/trunk/Driver/PrintParserCallbacks.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Driver/PrintParserCallbacks.cpp?rev=38992&r1=38991&r2=38992&view=diff

==============================================================================
--- cfe/cfe/trunk/Driver/PrintParserCallbacks.cpp (original)
+++ cfe/cfe/trunk/Driver/PrintParserCallbacks.cpp Wed Jul 11 11:26:35 2007
@@ -24,11 +24,11 @@
 namespace {
   class ParserPrintActions : public EmptyAction {
     
-    /// ParseDeclarator - This callback is invoked when a declarator is parsed and
-    /// 'Init' specifies the initializer if any.  This is for things like:
+    /// ParseDeclarator - This callback is invoked when a declarator is parsed
+    /// and 'Init' specifies the initializer if any.  This is for things like:
     /// "int X = 4" or "typedef int foo".
-    virtual void ParseDeclarator(SourceLocation Loc, Scope *S, Declarator &D,
-                                 ExprTy *Init) {
+    virtual DeclTy *ParseDeclarator(Scope *S, Declarator &D, ExprTy *Init,
+                                    DeclTy *LastInGroup) {
       std::cout << "ParseDeclarator ";
       if (IdentifierInfo *II = D.getIdentifier()) {
         std::cout << "'" << II->getName() << "'";
@@ -38,7 +38,7 @@
       std::cout << "\n";
       
       // Pass up to EmptyActions so that the symbol table is maintained right.
-      EmptyAction::ParseDeclarator(Loc, S, D, Init);
+      return EmptyAction::ParseDeclarator(S, D, Init, LastInGroup);
     }
     
     /// PopScope - This callback is called immediately before the specified scope

Modified: cfe/cfe/trunk/Driver/clang.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Driver/clang.cpp?rev=38992&r1=38991&r2=38992&view=diff

==============================================================================
--- cfe/cfe/trunk/Driver/clang.cpp (original)
+++ cfe/cfe/trunk/Driver/clang.cpp Wed Jul 11 11:26:35 2007
@@ -577,12 +577,11 @@
   ASTStreamerTy *Streamer = ASTStreamer_Init(PP, MainFileID, true);
   
   while (Decl *D = ASTStreamer_ReadTopLevelDecl(Streamer)) {
-    std::cerr << "Read top-level decl!\n";
-    //if (const IdentifierInfo *II = D->getIdentifier())
-    //  std::cerr << II->getName() << "\n";
-    //else
-    //  std::cerr << "\n";
-    
+    std::cerr << "Read top-level decl: ";
+    if (const IdentifierInfo *II = D->getIdentifier())
+      std::cerr << II->getName() << "\n";
+    else
+      std::cerr << "\n";
   }
   
   ASTStreamer_Terminate(Streamer);

Modified: cfe/cfe/trunk/Parse/MinimalAction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Parse/MinimalAction.cpp?rev=38992&r1=38991&r2=38992&view=diff

==============================================================================
--- cfe/cfe/trunk/Parse/MinimalAction.cpp (original)
+++ cfe/cfe/trunk/Parse/MinimalAction.cpp Wed Jul 11 11:26:35 2007
@@ -34,10 +34,11 @@
 /// ParseDeclarator - If this is a typedef declarator, we modify the
 /// IdentifierInfo::FETokenInfo field to keep track of this fact, until S is
 /// popped.
-void EmptyAction::ParseDeclarator(SourceLocation Loc, Scope *S, Declarator &D,
-                                  ExprTy *Init) {
+Action::DeclTy *
+EmptyAction::ParseDeclarator(Scope *S, Declarator &D, ExprTy *Init,
+                             DeclTy *LastInGroup) {
   // If there is no identifier associated with this declarator, bail out.
-  if (D.getIdentifier() == 0) return;
+  if (D.getIdentifier() == 0) return 0;
   
   // Remember whether or not this declarator is a typedef.
   TypedefInfo *TI = new TypedefInfo();
@@ -50,6 +51,7 @@
   
   // Remember that this needs to be removed when the scope is popped.
   S->AddDecl(&II);
+  return 0;
 }
 
 /// PopScope - When a scope is popped, if any typedefs are now out-of-scope,

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

==============================================================================
--- cfe/cfe/trunk/Parse/ParseDecl.cpp (original)
+++ cfe/cfe/trunk/Parse/ParseDecl.cpp Wed Jul 11 11:26:35 2007
@@ -112,7 +112,13 @@
 /// [GNU]   declarator simple-asm-expr[opt] attributes[opt]
 /// [GNU]   declarator simple-asm-expr[opt] attributes[opt] '=' initializer
 ///
-void Parser::ParseInitDeclaratorListAfterFirstDeclarator(Declarator &D) {
+Parser::DeclTy *Parser::
+ParseInitDeclaratorListAfterFirstDeclarator(Declarator &D) {
+  
+  // Declarators may be grouped together ("int X, *Y, Z();").  Provide info so
+  // that they can be chained properly if the actions want this.
+  Parser::DeclTy *LastDeclInGroup = 0;
+  
   // At this point, we know that it is not a function definition.  Parse the
   // rest of the init-declarator-list.
   while (1) {
@@ -129,15 +135,16 @@
     if (Tok.getKind() == tok::equal) {
       ConsumeToken();
       Init = ParseInitializer();
-      if (!Init.isInvalid) {
+      if (Init.isInvalid) {
         SkipUntil(tok::semi);
-        return;
+        return 0;
       }
     }
     
     // Inform the current actions module that we just parsed a declarator.
     // TODO: pass asm & attributes.
-    Actions.ParseDeclarator(Tok.getLocation(), CurScope, D, Init.Val);
+    LastDeclInGroup = Actions.ParseDeclarator(CurScope, D, Init.Val,
+                                              LastDeclInGroup);
     
     // If we don't have a comma, it is either the end of the list (a ';') or an
     // error, bail out.
@@ -154,12 +161,14 @@
   
   if (Tok.getKind() == tok::semi) {
     ConsumeToken();
+    return LastDeclInGroup;
   } else {
     Diag(Tok, diag::err_parse_error);
     // Skip to end of block or statement
     SkipUntil(tok::r_brace, true);
     if (Tok.getKind() == tok::semi)
       ConsumeToken();
+    return 0;
   }
 }
 

Modified: cfe/cfe/trunk/Parse/Parser.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Parse/Parser.cpp?rev=38992&r1=38991&r2=38992&view=diff

==============================================================================
--- cfe/cfe/trunk/Parse/Parser.cpp (original)
+++ cfe/cfe/trunk/Parse/Parser.cpp Wed Jul 11 11:26:35 2007
@@ -219,7 +219,7 @@
     
     Declarator D(DS, Declarator::FileContext);
     D.SetIdentifier(PP.getIdentifierInfo("__builtin_va_list"),SourceLocation());
-    Actions.ParseDeclarator(SourceLocation(), CurScope, D, 0);
+    Actions.ParseDeclarator(CurScope, D, 0, 0);
   }
   
   if (Tok.getKind() == tok::eof)  // Empty source file is an extension.
@@ -232,7 +232,7 @@
   Result = 0;
   if (Tok.getKind() == tok::eof) return true;
   
-  ParseExternalDeclaration();
+  Result = ParseExternalDeclaration();
   return false;
 }
 
@@ -274,21 +274,22 @@
 /// [GNU] asm-definition:
 ///         simple-asm-expr ';'
 ///
-void Parser::ParseExternalDeclaration() {
+Parser::DeclTy *Parser::ParseExternalDeclaration() {
   switch (Tok.getKind()) {
   case tok::semi:
     Diag(diag::ext_top_level_semi);
     ConsumeToken();
-    break;
+    // TODO: Invoke action for top-level semicolon.
+    return 0;
   case tok::kw_asm:
     ParseSimpleAsm();
     ExpectAndConsume(tok::semi, diag::err_expected_semi_after,
                      "top-level asm block");
-    break;
+    // TODO: Invoke action for top-level asm.
+    return 0;
   default:
     // We can't tell whether this is a function-definition or declaration yet.
-    ParseDeclarationOrFunctionDefinition();
-    break;
+    return ParseDeclarationOrFunctionDefinition();
   }
 }
 
@@ -304,7 +305,7 @@
 /// [!C99]  init-declarator-list ';'                             [TODO]
 /// [OMP]   threadprivate-directive                              [TODO]
 ///
-void Parser::ParseDeclarationOrFunctionDefinition() {
+Parser::DeclTy *Parser::ParseDeclarationOrFunctionDefinition() {
   // Parse the common declaration-specifiers piece.
   DeclSpec DS;
   ParseDeclarationSpecifiers(DS);
@@ -316,7 +317,8 @@
     // if (!DS.isMissingDeclaratorOk()) Diag(...);
     
     ConsumeToken();
-    return;
+    // TODO: Return type definition.
+    return 0;
   }
   
   // Parse the first declarator.
@@ -328,32 +330,31 @@
     SkipUntil(tok::r_brace, true);
     if (Tok.getKind() == tok::semi)
       ConsumeToken();
-    return;
+    return 0;
   }
 
   // If the declarator is the start of a function definition, handle it.
   if (Tok.getKind() == tok::equal ||  // int X()=  -> not a function def
       Tok.getKind() == tok::comma ||  // int X(),  -> not a function def
-      Tok.getKind() == tok::semi ||   // int X();  -> not a function def
+      Tok.getKind() == tok::semi  ||  // int X();  -> not a function def
       Tok.getKind() == tok::kw_asm || // int X() __asm__ -> not a fn def
       Tok.getKind() == tok::kw___attribute) {// int X() __attr__ -> not a fn def
     // FALL THROUGH.
   } else if (DeclaratorInfo.isFunctionDeclarator() &&
              (Tok.getKind() == tok::l_brace ||  // int X() {}
               isDeclarationSpecifier())) {      // int X(f) int f; {}
-    ParseFunctionDefinition(DeclaratorInfo);
-    return;
+    return ParseFunctionDefinition(DeclaratorInfo);
   } else {
     if (DeclaratorInfo.isFunctionDeclarator())
       Diag(Tok, diag::err_expected_fn_body);
     else
       Diag(Tok, diag::err_expected_after_declarator);
     SkipUntil(tok::semi);
-    return;
+    return 0;
   }
 
   // Parse the init-declarator-list for a normal declaration.
-  ParseInitDeclaratorListAfterFirstDeclarator(DeclaratorInfo);
+  return ParseInitDeclaratorListAfterFirstDeclarator(DeclaratorInfo);
 }
 
 /// ParseFunctionDefinition - We parsed and verified that the specified
@@ -363,7 +364,7 @@
 ///         declaration-specifiers[opt] declarator declaration-list[opt] 
 ///                 compound-statement                           [TODO]
 ///
-void Parser::ParseFunctionDefinition(Declarator &D) {
+Parser::DeclTy *Parser::ParseFunctionDefinition(Declarator &D) {
   const DeclaratorTypeInfo &FnTypeInfo = D.getTypeObject(0);
   assert(FnTypeInfo.Kind == DeclaratorTypeInfo::Function &&
          "This isn't a function declarator!");
@@ -393,10 +394,15 @@
     
     // If we didn't find the '{', bail out.
     if (Tok.getKind() != tok::l_brace)
-      return;
+      return 0;
   }
   
+  // TODO: Get stmt info.
+  StmtTy *FnBody = 0;
   ParseCompoundStatement();
+
+  // TODO: Pass argument information.
+  return Actions.ParseFunctionDefinition(CurScope, D, FnBody);
 }
 
 /// ParseAsmStringLiteral - This is just a normal string-literal, but is not

Modified: cfe/cfe/trunk/Sema/ASTStreamer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Sema/ASTStreamer.cpp?rev=38992&r1=38991&r2=38992&view=diff

==============================================================================
--- cfe/cfe/trunk/Sema/ASTStreamer.cpp (original)
+++ cfe/cfe/trunk/Sema/ASTStreamer.cpp Wed Jul 11 11:26:35 2007
@@ -19,15 +19,17 @@
 
 /// Interface to the Builder.cpp file.
 ///
-Action *CreateASTBuilderActions(Preprocessor &PP, bool FullLocInfo);
+Action *CreateASTBuilderActions(Preprocessor &PP, bool FullLocInfo,
+                                std::vector<Decl*> &LastInGroupList);
 
 
 namespace {
   class ASTStreamer {
     Parser P;
+    std::vector<Decl*> LastInGroupList;
   public:
     ASTStreamer(Preprocessor &PP, unsigned MainFileID, bool FullLocInfo)
-      : P(PP, *CreateASTBuilderActions(PP, FullLocInfo)) {
+      : P(PP, *CreateASTBuilderActions(PP, FullLocInfo, LastInGroupList)) {
       PP.EnterSourceFile(MainFileID, 0, true);
       
       // Initialize the parser.
@@ -37,9 +39,33 @@
     /// ReadTopLevelDecl - Parse and return the next top-level declaration.
     Decl *ReadTopLevelDecl() {
       Parser::DeclTy *Result;
-      if (P.ParseTopLevelDecl(Result))
-        return 0;
-      Result = (Decl*)1; // FIXME!
+      
+      /// If the previous time through we read something like 'int X, Y', return
+      /// the next declarator.
+      if (!LastInGroupList.empty()) {
+        Result = LastInGroupList.back();
+        LastInGroupList.pop_back();
+        return (Decl*)Result;
+      }
+
+      do {
+        if (P.ParseTopLevelDecl(Result))
+          return 0;  // End of file.
+
+        // If we got a null return and something *was* parsed, try again.  This
+        // is due to a top-level semicolon, an action override, or a parse error
+        // skipping something.
+      } while (Result == 0);
+
+      // If we parsed a declspec with multiple declarators, reverse the list and
+      // return the first one.
+      if (!LastInGroupList.empty()) {
+        LastInGroupList.push_back((Decl*)Result);
+        std::reverse(LastInGroupList.begin(), LastInGroupList.end());
+        Result = LastInGroupList.back();
+        LastInGroupList.pop_back();
+      }
+
       return (Decl*)Result;
     }
     

Modified: cfe/cfe/trunk/Sema/Sema.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Sema/Sema.cpp?rev=38992&r1=38991&r2=38992&view=diff

==============================================================================
--- cfe/cfe/trunk/Sema/Sema.cpp (original)
+++ cfe/cfe/trunk/Sema/Sema.cpp Wed Jul 11 11:26:35 2007
@@ -31,16 +31,25 @@
   /// FullLocInfo - If this is true, the ASTBuilder constructs AST Nodes that
   /// capture maximal location information for each source-language construct.
   bool FullLocInfo;
+  
+  /// LastInGroupList - This vector is populated when there are multiple
+  /// declarators in a single decl group (e.g. "int A, B, C").  In this case,
+  /// all but the last decl will be entered into this.  This is used by the
+  /// ASTStreamer.
+  std::vector<Decl*> &LastInGroupList;
 public:
-  ASTBuilder(Preprocessor &pp, bool fullLocInfo)
-    : PP(pp), FullLocInfo(fullLocInfo) {}
+  ASTBuilder(Preprocessor &pp, bool fullLocInfo,
+             std::vector<Decl*> &prevInGroup)
+    : PP(pp), FullLocInfo(fullLocInfo), LastInGroupList(prevInGroup) {}
   
   //===--------------------------------------------------------------------===//
   // Symbol table tracking callbacks.
   //
   virtual bool isTypedefName(const IdentifierInfo &II, Scope *S) const;
-  virtual void ParseDeclarator(SourceLocation Loc, Scope *S, Declarator &D,
-                               ExprTy *Init);
+  virtual DeclTy *ParseDeclarator(Scope *S, Declarator &D, ExprTy *Init,
+                                  DeclTy *LastInGroup);
+  virtual DeclTy *ParseFunctionDefinition(Scope *S, Declarator &D,
+                                          StmtTy *Body);
   virtual void PopScope(SourceLocation Loc, Scope *S);
   
   //===--------------------------------------------------------------------===//
@@ -103,16 +112,17 @@
   return D != 0 && D->getDeclSpec().StorageClassSpec == DeclSpec::SCS_typedef;
 }
 
-void ASTBuilder::ParseDeclarator(SourceLocation Loc, Scope *S, Declarator &D,
-                                 ExprTy *Init) {
+Action::DeclTy *
+ASTBuilder::ParseDeclarator(Scope *S, Declarator &D, ExprTy *Init, 
+                            DeclTy *LastInGroup) {
   IdentifierInfo *II = D.getIdentifier();
   Decl *PrevDecl = II ? II->getFETokenInfo<Decl>() : 0;
 
   Decl *New;
   if (D.isFunctionDeclarator())
-    New = new FunctionDecl(II, D, Loc, PrevDecl);
+    New = new FunctionDecl(II, D, PrevDecl);
   else
-    New = new VarDecl(II, D, Loc, PrevDecl);
+    New = new VarDecl(II, D, PrevDecl);
   
   // If this has an identifier, add it to the scope stack.
   if (II) {
@@ -120,6 +130,17 @@
     II->setFETokenInfo(New);
     S->AddDecl(II);
   }
+  
+  if (LastInGroup) LastInGroupList.push_back((Decl*)LastInGroup);
+  
+  return New;
+}
+
+Action::DeclTy *
+ASTBuilder::ParseFunctionDefinition(Scope *S, Declarator &D, StmtTy *Body) {
+  FunctionDecl *FD = (FunctionDecl *)ParseDeclarator(S, D, 0, 0);
+  // TODO: more stuff.
+  return FD;
 }
 
 void ASTBuilder::PopScope(SourceLocation Loc, Scope *S) {
@@ -359,9 +380,8 @@
 
 /// Interface to the Builder.cpp file.
 ///
-Action *CreateASTBuilderActions(Preprocessor &PP, bool FullLocInfo) {
-  return new ASTBuilder(PP, FullLocInfo);
+Action *CreateASTBuilderActions(Preprocessor &PP, bool FullLocInfo,
+                                std::vector<Decl*> &LastInGroupList) {
+  return new ASTBuilder(PP, FullLocInfo, LastInGroupList);
 }
 
-
-

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

==============================================================================
--- cfe/cfe/trunk/include/clang/AST/Decl.h (original)
+++ cfe/cfe/trunk/include/clang/AST/Decl.h Wed Jul 11 11:26:35 2007
@@ -36,17 +36,12 @@
   /// Type.
   /// Kind.
   
-  /// Loc - The location of the declaration in the source code.
-  ///
-  SourceLocation Loc;
-  
   /// Scope stack info when parsing, otherwise decl list when scope is popped.
   ///
   Decl *Next;
 public:
-  Decl(IdentifierInfo *Id, const Declarator &D, SourceLocation loc, Decl *next)
-    : Identifier(Id), DeclarationSpecifier(D.getDeclSpec()), Loc(loc),
-      Next(next) {}
+  Decl(IdentifierInfo *Id, const Declarator &D, Decl *next)
+    : Identifier(Id), DeclarationSpecifier(D.getDeclSpec()), Next(next) {}
   
   const IdentifierInfo *getIdentifier() const { return Identifier; }
   
@@ -60,8 +55,8 @@
 class FunctionDecl : public Decl {
   // Args etc.
 public:
-  FunctionDecl(IdentifierInfo *Id, const Declarator &D,
-               SourceLocation Loc, Decl *Next) : Decl(Id, D, Loc, Next) {}
+  FunctionDecl(IdentifierInfo *Id, const Declarator &D, Decl *Next)
+    : Decl(Id, D, Next) {}
 
 };
 
@@ -70,8 +65,8 @@
 class VarDecl : public Decl {
   // Initializer.
 public:
-  VarDecl(IdentifierInfo *Id, const Declarator &D,
-          SourceLocation Loc, Decl *Next) : Decl(Id, D, Loc, Next) {}
+  VarDecl(IdentifierInfo *Id, const Declarator &D, Decl *Next)
+    : Decl(Id, D, Next) {}
   
 };
   

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

==============================================================================
--- cfe/cfe/trunk/include/clang/Parse/Action.h (original)
+++ cfe/cfe/trunk/include/clang/Parse/Action.h Wed Jul 11 11:26:35 2007
@@ -47,6 +47,7 @@
   // Types - Though these don't actually enforce strong typing, they document
   // what types are required to be identical for the actions.
   typedef void ExprTy;
+  typedef void StmtTy;
   typedef void DeclTy;
   typedef void TypeTy;
   
@@ -79,14 +80,33 @@
   /// ParseDeclarator - This callback is invoked when a declarator is parsed and
   /// 'Init' specifies the initializer if any.  This is for things like:
   /// "int X = 4" or "typedef int foo".
-  virtual void ParseDeclarator(SourceLocation Loc, Scope *S, Declarator &D,
-                               ExprTy *Init) {}
-  
+  ///
+  /// LastInGroup is non-null for cases where one declspec has multiple
+  /// declarators on it.  For example in 'int A, B', ParseDeclarator will be
+  /// called with LastInGroup=A when invoked for B.
+  virtual DeclTy *ParseDeclarator(Scope *S, Declarator &D,
+                                  ExprTy *Init, DeclTy *LastInGroup) {
+    return 0;
+  }
+
+  /// ParseFunctionDefinition - This is called when a function definition is
+  /// parsed.  The declarator that is part of this is not passed to
+  /// ParseDeclarator.
+  virtual DeclTy *ParseFunctionDefinition(Scope *S, Declarator &D,
+                                          // TODO: FORMAL ARG INFO.
+                                          StmtTy *Body) {
+    return 0;
+  }
+
   /// PopScope - This callback is called immediately before the specified scope
   /// is popped and deleted.
   virtual void PopScope(SourceLocation Loc, Scope *S) {}
   
   //===--------------------------------------------------------------------===//
+  // 'External Declaration' (Top Level) Parsing Callbacks.
+  //===--------------------------------------------------------------------===//
+  
+  //===--------------------------------------------------------------------===//
   // Expression Parsing Callbacks.
   //===--------------------------------------------------------------------===//
   
@@ -178,8 +198,8 @@
   /// ParseDeclarator - If this is a typedef declarator, we modify the
   /// IdentifierInfo::FETokenInfo field to keep track of this fact, until S is
   /// popped.
-  virtual void ParseDeclarator(SourceLocation Loc, Scope *S, Declarator &D,
-                               ExprTy *Init);
+  virtual DeclTy *ParseDeclarator(Scope *S, Declarator &D, ExprTy *Init,
+                                  DeclTy *LastInGroup);
   
   /// PopScope - When a scope is popped, if any typedefs are now out-of-scope,
   /// they are removed from the IdentifierInfo::FETokenInfo field.

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

==============================================================================
--- cfe/cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/cfe/trunk/include/clang/Parse/Parser.h Wed Jul 11 11:26:35 2007
@@ -48,6 +48,7 @@
   // Type forwarding.  All of these are statically 'void*', but they may all be
   // different actual classes based on the actions in place.
   typedef Action::ExprTy ExprTy;
+  typedef Action::StmtTy StmtTy;
   typedef Action::DeclTy DeclTy;
   typedef Action::TypeTy TypeTy;
   
@@ -214,9 +215,9 @@
     
   //===--------------------------------------------------------------------===//
   // C99 6.9: External Definitions.
-  void ParseExternalDeclaration();
-  void ParseDeclarationOrFunctionDefinition();
-  void ParseFunctionDefinition(Declarator &D);
+  DeclTy *ParseExternalDeclaration();
+  DeclTy *ParseDeclarationOrFunctionDefinition();
+  DeclTy *ParseFunctionDefinition(Declarator &D);
   void ParseSimpleAsm();
   void ParseAsmStringLiteral();
   
@@ -285,7 +286,7 @@
   // C99 6.7: Declarations.
   
   void ParseDeclaration(unsigned Context);
-  void ParseInitDeclaratorListAfterFirstDeclarator(Declarator &D);
+  DeclTy *ParseInitDeclaratorListAfterFirstDeclarator(Declarator &D);
   void ParseDeclarationSpecifiers(DeclSpec &DS);
   void ParseSpecifierQualifierList(DeclSpec &DS);
 





More information about the cfe-commits mailing list