[cfe-commits] r41431 - in /cfe/trunk: Parse/ParseDecl.cpp Parse/ParseStmt.cpp Parse/Parser.cpp Sema/SemaDecl.cpp include/clang/Parse/Scope.h

Chris Lattner sabre at nondot.org
Sat Aug 25 23:24:46 PDT 2007


Author: lattner
Date: Sun Aug 26 01:24:45 2007
New Revision: 41431

URL: http://llvm.org/viewvc/llvm-project?rev=41431&view=rev
Log:
Break the assumption that any sort of scope (e.g. a loop scope) can 
hold declarations.  Instead, introduce a new "DeclScope" scope type that
holds them explicitly.  For now, all scopes have this bit, but in the 
future we can use them to fix some issues Neil noticed.

Modified:
    cfe/trunk/Parse/ParseDecl.cpp
    cfe/trunk/Parse/ParseStmt.cpp
    cfe/trunk/Parse/Parser.cpp
    cfe/trunk/Sema/SemaDecl.cpp
    cfe/trunk/include/clang/Parse/Scope.h

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

==============================================================================
--- cfe/trunk/Parse/ParseDecl.cpp (original)
+++ cfe/trunk/Parse/ParseDecl.cpp Sun Aug 26 01:24:45 2007
@@ -13,6 +13,7 @@
 
 #include "clang/Parse/Parser.h"
 #include "clang/Parse/DeclSpec.h"
+#include "clang/Parse/Scope.h"
 #include "llvm/ADT/SmallSet.h"
 using namespace clang;
 
@@ -1268,7 +1269,7 @@
     // Enter function-declaration scope, limiting any declarators for struct
     // tags to the function prototype scope.
     // FIXME: is this needed?
-    EnterScope(0);
+    EnterScope(Scope::DeclScope);
     
     IsVariadic = false;
     while (1) {

Modified: cfe/trunk/Parse/ParseStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Parse/ParseStmt.cpp?rev=41431&r1=41430&r2=41431&view=diff

==============================================================================
--- cfe/trunk/Parse/ParseStmt.cpp (original)
+++ cfe/trunk/Parse/ParseStmt.cpp Sun Aug 26 01:24:45 2007
@@ -372,8 +372,9 @@
 Parser::StmtResult Parser::ParseCompoundStatement() {
   assert(Tok.getKind() == tok::l_brace && "Not a compount stmt!");
   
-  // Enter a scope to hold everything within the compound stmt.
-  EnterScope(0);
+  // Enter a scope to hold everything within the compound stmt.  Compound
+  // statements can always hold declarations.
+  EnterScope(Scope::DeclScope);
 
   // Parse the statements in the body.
   StmtResult Body = ParseCompoundStatementBody();
@@ -437,7 +438,7 @@
   // there is no compound stmt.  C90 does not have this clause.  We only do this
   // if the body isn't a compound statement to avoid push/pop in common cases.
   bool NeedsInnerScope = getLang().C99 && Tok.getKind() != tok::l_brace;
-  if (NeedsInnerScope) EnterScope(0);
+  if (NeedsInnerScope) EnterScope(Scope::DeclScope);
   
   // Read the if condition.
   StmtResult CondStmt = ParseStatement();
@@ -460,7 +461,7 @@
     // this if the body isn't a compound statement to avoid push/pop in common
     // cases.
     NeedsInnerScope = getLang().C99 && Tok.getKind() != tok::l_brace;
-    if (NeedsInnerScope) EnterScope(0);
+    if (NeedsInnerScope) EnterScope(Scope::DeclScope);
     
     ElseStmt = ParseStatement();
 
@@ -489,7 +490,7 @@
   }
   
   // Start the switch scope.
-  EnterScope(Scope::BreakScope);
+  EnterScope(Scope::BreakScope|Scope::DeclScope);
 
   // Parse the condition.
   ExprResult Cond = ParseSimpleParenExpression();
@@ -505,7 +506,7 @@
   // there is no compound stmt.  C90 does not have this clause.  We only do this
   // if the body isn't a compound statement to avoid push/pop in common cases.
   bool NeedsInnerScope = getLang().C99 && Tok.getKind() != tok::l_brace;
-  if (NeedsInnerScope) EnterScope(0);
+  if (NeedsInnerScope) EnterScope(Scope::DeclScope);
   
   // Read the body statement.
   StmtResult Body = ParseStatement();
@@ -538,7 +539,7 @@
   }
   
   // Start the loop scope.
-  EnterScope(Scope::BreakScope | Scope::ContinueScope);
+  EnterScope(Scope::BreakScope | Scope::ContinueScope | Scope::DeclScope);
 
   // Parse the condition.
   ExprResult Cond = ParseSimpleParenExpression();
@@ -547,7 +548,7 @@
   // there is no compound stmt.  C90 does not have this clause.  We only do this
   // if the body isn't a compound statement to avoid push/pop in common cases.
   bool NeedsInnerScope = getLang().C99 && Tok.getKind() != tok::l_brace;
-  if (NeedsInnerScope) EnterScope(0);
+  if (NeedsInnerScope) EnterScope(Scope::DeclScope);
   
   // Read the body statement.
   StmtResult Body = ParseStatement();
@@ -571,13 +572,13 @@
   SourceLocation DoLoc = ConsumeToken();  // eat the 'do'.
   
   // Start the loop scope.
-  EnterScope(Scope::BreakScope | Scope::ContinueScope);
+  EnterScope(Scope::BreakScope | Scope::ContinueScope | Scope::DeclScope);
 
   // C99 6.8.5p5 - In C99, the body of the if statement is a scope, even if
   // there is no compound stmt.  C90 does not have this clause. We only do this
   // if the body isn't a compound statement to avoid push/pop in common cases.
   bool NeedsInnerScope = getLang().C99 && Tok.getKind() != tok::l_brace;
-  if (NeedsInnerScope) EnterScope(0);
+  if (NeedsInnerScope) EnterScope(Scope::DeclScope);
   
   // Read the body statement.
   StmtResult Body = ParseStatement();
@@ -625,7 +626,7 @@
     return true;
   }
   
-  EnterScope(Scope::BreakScope | Scope::ContinueScope);
+  EnterScope(Scope::BreakScope | Scope::ContinueScope | Scope::DeclScope);
 
   SourceLocation LParenLoc = ConsumeParen();
   ExprResult Value;
@@ -701,7 +702,7 @@
   // there is no compound stmt.  C90 does not have this clause.  We only do this
   // if the body isn't a compound statement to avoid push/pop in common cases.
   bool NeedsInnerScope = getLang().C99 && Tok.getKind() != tok::l_brace;
-  if (NeedsInnerScope) EnterScope(0);
+  if (NeedsInnerScope) EnterScope(Scope::DeclScope);
   
   // Read the body statement.
   StmtResult Body = ParseStatement();

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

==============================================================================
--- cfe/trunk/Parse/Parser.cpp (original)
+++ cfe/trunk/Parse/Parser.cpp Sun Aug 26 01:24:45 2007
@@ -221,11 +221,10 @@
   // Prime the lexer look-ahead.
   ConsumeToken();
   
-  // Create the global scope, install it as the current scope.
+  // Create the translation unit scope.  Install it as the current scope.
   assert(CurScope == 0 && "A scope is already active?");
-  EnterScope(0);
-  
-  
+  EnterScope(Scope::DeclScope);
+    
   // Install builtin types.
   // TODO: Move this someplace more useful.
   {
@@ -435,7 +434,7 @@
     ParseKNRParamDeclarations(D);
 
   // Enter a scope for the function body.
-  EnterScope(Scope::FnScope);
+  EnterScope(Scope::FnScope|Scope::DeclScope);
   
   // Tell the actions module that we have entered a function definition with the
   // specified Declarator for the function.

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

==============================================================================
--- cfe/trunk/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/Sema/SemaDecl.cpp Sun Aug 26 01:24:45 2007
@@ -78,6 +78,9 @@
 }
 
 void Sema::PopScope(SourceLocation Loc, Scope *S) {
+  if (S->decl_empty()) return;
+  assert((S->getFlags() & Scope::DeclScope) &&"Scope shouldn't contain decls!");
+         
   for (Scope::decl_iterator I = S->decl_begin(), E = S->decl_end();
        I != E; ++I) {
     Decl *D = static_cast<Decl*>(*I);
@@ -159,6 +162,8 @@
                                        FunctionDecl::Extern, false, 0);
   
   // Find translation-unit scope to insert this function into.
+  if (Scope *FnS = S->getFnParent())
+    S = FnS->getParent();   // Skip all scopes in a function at once.
   while (S->getParent())
     S = S->getParent();
   S->AddDecl(New);
@@ -286,6 +291,11 @@
     return 0;
   }
   
+  // The scope passed in may not be a decl scope.  Zip up the scope tree until
+  // we find one that is.
+  while ((S->getFlags() & Scope::DeclScope) == 0)
+    S = S->getParent();
+  
   // See if this is a redefinition of a variable in the same scope.
   Decl *PrevDecl = LookupScopedDecl(II, Decl::IDNS_Ordinary,
                                     D.getIdentifierLoc(), S);
@@ -616,6 +626,8 @@
   D.SetIdentifier(&II, Loc);
   
   // Find translation-unit scope to insert this function into.
+  if (Scope *FnS = S->getFnParent())
+    S = FnS->getParent();   // Skip all scopes in a function at once.
   while (S->getParent())
     S = S->getParent();
   
@@ -724,6 +736,12 @@
   
   // If this has an identifier, add it to the scope stack.
   if (Name) {
+    // The scope passed in may not be a decl scope.  Zip up the scope tree until
+    // we find one that is.
+    while ((S->getFlags() & Scope::DeclScope) == 0)
+      S = S->getParent();
+    
+    // Add it to the decl chain.
     New->setNext(Name->getFETokenInfo<Decl>());
     Name->setFETokenInfo(New);
     S->AddDecl(New);
@@ -896,6 +914,11 @@
     cast_or_null<EnumConstantDecl>(static_cast<Decl*>(lastEnumConst));
   Expr *Val = static_cast<Expr*>(val);
 
+  // The scope passed in may not be a decl scope.  Zip up the scope tree until
+  // we find one that is.
+  while ((S->getFlags() & Scope::DeclScope) == 0)
+    S = S->getParent();
+  
   // Verify that there isn't already something declared with this name in this
   // scope.
   if (Decl *PrevDecl = LookupScopedDecl(Id, Decl::IDNS_Ordinary, IdLoc, S)) {

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

==============================================================================
--- cfe/trunk/include/clang/Parse/Scope.h (original)
+++ cfe/trunk/include/clang/Parse/Scope.h Sun Aug 26 01:24:45 2007
@@ -38,7 +38,11 @@
     
     /// ContinueScope - This is a while,do,for, which can have continue
     /// stmt embedded into it.
-    ContinueScope = 0x04
+    ContinueScope = 0x04,
+    
+    /// DeclScope - This is a scope that can contain a declaration.  Some scopes
+    /// just contain loop constructs but don't contain decls.
+    DeclScope = 0x08
   };
 private:
   /// The parent scope for this scope.  This is null for the translation-unit
@@ -75,27 +79,36 @@
   Scope(Scope *Parent, unsigned ScopeFlags) {
     Init(Parent, ScopeFlags);
   }
-  
+
+  /// getFlags - Return the flags for this scope.
+  ///
+  unsigned getFlags() const { return Flags; }
+
   /// getParent - Return the scope that this is nested in.
   ///
-  Scope *getParent() const { return AnyParent; }
+  const Scope *getParent() const { return AnyParent; }
+  Scope *getParent() { return AnyParent; }
+
+  /// getFnParent - Return the closest scope that is a function body.
+  ///
+  const Scope *getFnParent() const { return FnParent; }
+  Scope *getFnParent() { return FnParent; }
   
   /// getContinueParent - Return the closest scope that a continue statement
   /// would be affected by.
-  Scope *getContinueParent() const {
-    return ContinueParent;
-  }
+  const Scope *getContinueParent() const { return ContinueParent; }
+  Scope *getContinueParent() { return ContinueParent; }
   
   /// getBreakParent - Return the closest scope that a break statement
   /// would be affected by.
-  Scope *getBreakParent() const {
-    return BreakParent;
-  }
-  
+  const Scope *getBreakParent() const { return BreakParent; }
+  Scope *getBreakParent() { return BreakParent; }
   
+ 
   typedef DeclSetTy::iterator decl_iterator;
   decl_iterator decl_begin() const { return DeclsInScope.begin(); }
   decl_iterator decl_end()   const { return DeclsInScope.end(); }
+  bool decl_empty()          const { return DeclsInScope.empty(); }
 
   void AddDecl(Action::DeclTy *D) {
     DeclsInScope.insert(D);





More information about the cfe-commits mailing list