From ffe65b3ffd762468caa3d0afd57ade3ea5c098fb Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Mon, 14 Aug 2006 01:28:29 +0000 Subject: [PATCH] Implement scope tracking for empty-action. llvm-svn: 38919 --- clang/Parse/MinimalAction.cpp | 40 +++++++++++++++++++++++++++++++---- 1 file changed, 36 insertions(+), 4 deletions(-) diff --git a/clang/Parse/MinimalAction.cpp b/clang/Parse/MinimalAction.cpp index 413db98eb10b..de7443c194f1 100644 --- a/clang/Parse/MinimalAction.cpp +++ b/clang/Parse/MinimalAction.cpp @@ -12,15 +12,23 @@ //===----------------------------------------------------------------------===// #include "clang/Parse/Parser.h" -//#include "clang/Parse/Declarations.h" -//#include "clang/Parse/Scope.h" +#include "clang/Parse/Declarations.h" +#include "clang/Parse/Scope.h" using namespace llvm; using namespace clang; +/// TypedefInfo - A link exists here for each scope that an identifier is +/// defined. +struct TypedefInfo { + TypedefInfo *Prev; + bool isTypedef; +}; + /// isTypedefName - This looks at the IdentifierInfo::FETokenInfo field to /// determine whether the name is a typedef or not in this scope. bool EmptyAction::isTypedefName(const IdentifierInfo &II, Scope *S) const { - return true; + TypedefInfo *TI = II.getFETokenInfo(); + return TI != 0 && TI->isTypedef; } /// ParseDeclarator - If this is a typedef declarator, we modify the @@ -28,10 +36,34 @@ bool EmptyAction::isTypedefName(const IdentifierInfo &II, Scope *S) const { /// popped. void EmptyAction::ParseDeclarator(SourceLocation Loc, Scope *S, Declarator &D, ExprTy *Init) { + // If there is no identifier associated with this declarator, bail out. + if (D.getIdentifier() == 0) return; + + // Remember whether or not this declarator is a typedef. + TypedefInfo *TI = new TypedefInfo(); + TI->isTypedef = D.getDeclSpec().StorageClassSpec == DeclSpec::SCS_typedef; + + // Add this to the linked-list hanging off the identifier. + IdentifierInfo &II = *D.getIdentifier(); + TI->Prev = II.getFETokenInfo(); + II.setFETokenInfo(TI); + + // Remember that this needs to be removed when the scope is popped. + S->AddDecl(&II); } /// PopScope - When a scope is popped, if any typedefs are now out-of-scope, /// they are removed from the IdentifierInfo::FETokenInfo field. void EmptyAction::PopScope(SourceLocation Loc, Scope *S) { - + for (Scope::decl_iterator I = S->decl_begin(), E = S->decl_end(); + I != E; ++I) { + IdentifierInfo &II = *static_cast(*I); + TypedefInfo *TI = II.getFETokenInfo(); + assert(TI && "This decl didn't get pushed??"); + + TypedefInfo *Next = TI->Prev; + delete TI; + + II.setFETokenInfo(Next); + } }