[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