diff options
author | Steve Naroff <snaroff@apple.com> | 2007-11-29 23:05:20 +0000 |
---|---|---|
committer | Steve Naroff <snaroff@apple.com> | 2007-11-29 23:05:20 +0000 |
commit | 89307ffaf8acf4d6fdffd72b607ca4fbcfdffc9d (patch) | |
tree | bbf0f3ba5d789a183976c58fc486375e4d480bba | |
parent | 2ff3e691ecc63a5d82d4023b46b5b47ce14ace53 (diff) |
Yesterday, I simplified how we stream top-level decls.
After a discussion with Ted, we both came to the conclusion that adding a "HandleTopLevelDeclaration" hook to ASConsumer is far more elegant. The default implementation of HandleTopLevelDeclaration will be responsible for iterating over the ScopedDecl (which has a chain of the decls:-).
TODO: Once Ted adds HandleTopLevelDeclaration, make sure TagDecls are chainged appropriately...
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@44445 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | Parse/Parser.cpp | 8 | ||||
-rw-r--r-- | Sema/ASTStreamer.cpp | 23 | ||||
-rw-r--r-- | Sema/Sema.cpp | 4 | ||||
-rw-r--r-- | Sema/Sema.h | 9 | ||||
-rw-r--r-- | Sema/SemaDecl.cpp | 22 | ||||
-rw-r--r-- | include/clang/Parse/Parser.h | 2 |
6 files changed, 12 insertions, 56 deletions
diff --git a/Parse/Parser.cpp b/Parse/Parser.cpp index 6e03328592..8a0d8c7ecd 100644 --- a/Parse/Parser.cpp +++ b/Parse/Parser.cpp @@ -259,10 +259,11 @@ void Parser::Initialize() { /// ParseTopLevelDecl - Parse one top-level declaration, return whatever the /// action tells us to. This returns true if the EOF was encountered. -bool Parser::ParseTopLevelDecl() { +bool Parser::ParseTopLevelDecl(DeclTy*& Result) { + Result = 0; if (Tok.is(tok::eof)) return true; - ParseExternalDeclaration(); + Result = ParseExternalDeclaration(); return false; } @@ -280,7 +281,8 @@ void Parser::Finalize() { void Parser::ParseTranslationUnit() { Initialize(); - while (!ParseTopLevelDecl()) + DeclTy *Res; + while (!ParseTopLevelDecl(Res)) /*parse them all*/; Finalize(); diff --git a/Sema/ASTStreamer.cpp b/Sema/ASTStreamer.cpp index 5a372da088..b51874ca35 100644 --- a/Sema/ASTStreamer.cpp +++ b/Sema/ASTStreamer.cpp @@ -24,10 +24,9 @@ ASTConsumer::~ASTConsumer() {} namespace { class ASTStreamer { Parser P; - std::vector<Decl*> TopLevelDeclList; public: ASTStreamer(Preprocessor &pp, ASTContext &ctxt, unsigned MainFileID) - : P(pp, *new Sema(pp, ctxt, TopLevelDeclList)) { + : P(pp, *new Sema(pp, ctxt)) { pp.EnterMainSourceFile(MainFileID); // Initialize the parser. @@ -51,30 +50,14 @@ namespace { Decl *ASTStreamer::ReadTopLevelDecl() { Parser::DeclTy *Result; - /// If the previous time through we read something like 'int X, Y', return - /// the next declarator. - if (!TopLevelDeclList.empty()) { - Result = TopLevelDeclList.back(); - TopLevelDeclList.pop_back(); - return static_cast<Decl*>(Result); - } - do { - if (P.ParseTopLevelDecl()) + 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 (TopLevelDeclList.size() == 0); - - // If we parsed a declspec with multiple declarators, reverse the list and - // return the first one. - if (TopLevelDeclList.size() > 1) - std::reverse(TopLevelDeclList.begin(), TopLevelDeclList.end()); - - Result = TopLevelDeclList.back(); - TopLevelDeclList.pop_back(); + } while (Result == 0); return static_cast<Decl*>(Result); } diff --git a/Sema/Sema.cpp b/Sema/Sema.cpp index d3930f60fa..6b799e0c74 100644 --- a/Sema/Sema.cpp +++ b/Sema/Sema.cpp @@ -63,8 +63,8 @@ QualType Sema::GetObjcProtoType(SourceLocation Loc) { return Context.getObjcProtoType(); } -Sema::Sema(Preprocessor &pp, ASTContext &ctxt, std::vector<Decl*> &prevInGroup) - : PP(pp), Context(ctxt), CurFunctionDecl(0), TopLevelDeclList(prevInGroup) { +Sema::Sema(Preprocessor &pp, ASTContext &ctxt) + : PP(pp), Context(ctxt), CurFunctionDecl(0) { // Get IdentifierInfo objects for known functions for which we // do extra checking. diff --git a/Sema/Sema.h b/Sema/Sema.h index cbb94bc372..590f46f155 100644 --- a/Sema/Sema.h +++ b/Sema/Sema.h @@ -69,10 +69,6 @@ class Sema : public Action { /// the method decl for the method being parsed. ObjcMethodDecl *CurMethodDecl; - /// TopLevelDeclList - This vector is populated with all declarators from - /// a top-level declaration. This is used by the ASTStreamer. - std::vector<Decl*> &TopLevelDeclList; - /// LabelMap - This is a mapping from label identifiers to the LabelStmt for /// it (which acts like the label decl in some ways). Forward referenced /// labels have a LabelStmt created for them with a null location & SubStmt. @@ -141,7 +137,7 @@ class Sema : public Action { llvm::DenseMap<Selector, ObjcMethodList> InstanceMethodPool; llvm::DenseMap<Selector, ObjcMethodList> FactoryMethodPool; public: - Sema(Preprocessor &pp, ASTContext &ctxt, std::vector<Decl*> &prevInGroup); + Sema(Preprocessor &pp, ASTContext &ctxt); const LangOptions &getLangOptions() const; @@ -227,9 +223,6 @@ private: TypedefDecl *MergeTypeDefDecl(TypedefDecl *New, ScopedDecl *Old); FunctionDecl *MergeFunctionDecl(FunctionDecl *New, ScopedDecl *Old); VarDecl *MergeVarDecl(VarDecl *New, ScopedDecl *Old); - /// AddTopLevelDecl - called after the decl has been fully processed. - /// Allows for bookkeeping and post-processing of each declaration. - void AddTopLevelDecl(Decl *current); /// More parsing and symbol table subroutines... ParmVarDecl *ActOnParamDeclarator(struct DeclaratorChunk::ParamInfo &PI, diff --git a/Sema/SemaDecl.cpp b/Sema/SemaDecl.cpp index 8d5c69915d..71f2f19226 100644 --- a/Sema/SemaDecl.cpp +++ b/Sema/SemaDecl.cpp @@ -191,9 +191,6 @@ ScopedDecl *Sema::LazilyCreateBuiltin(IdentifierInfo *II, unsigned bid, } else { II->setFETokenInfo(New); } - // Make sure clients iterating over decls see this. - AddTopLevelDecl(New); - return New; } @@ -676,10 +673,6 @@ Sema::ActOnDeclarator(Scope *S, Declarator &D, DeclTy *lastDecl) { II->setFETokenInfo(New); S->AddDecl(New); } - - if (S->getParent() == 0) - AddTopLevelDecl(New); - // If any semantic error occurred, mark the decl as invalid. if (D.getInvalidType() || InvalidDecl) New->setInvalidDecl(); @@ -975,7 +968,6 @@ void Sema::ObjcActOnStartOfMethodDef(Scope *FnBodyScope, DeclTy *D) { NewFD->setNext(II->getFETokenInfo<ScopedDecl>()); II->setFETokenInfo(NewFD); GlobalScope->AddDecl(NewFD); - AddTopLevelDecl(NewFD); // Allow all of Sema to see that we are entering a method definition. CurMethodDecl = MDecl; @@ -1685,12 +1677,6 @@ Sema::DeclTy *Sema::ActOnTag(Scope *S, unsigned TagType, TagKind TK, break; } - // For top-level tag definitions, make sure we chain the the tag decl to - // the vardecl. This enables the AST streamer to see both X and D in the - // following example: struct X { int A; } D; - if (S->getParent() == 0) - AddTopLevelDecl(New); - // 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 @@ -2464,14 +2450,6 @@ void Sema::ActOnEnumBody(SourceLocation EnumLoc, DeclTy *EnumDeclX, Enum->defineElements(EltList, BestType); } -void Sema::AddTopLevelDecl(Decl *current) { - if (!current) return; - - // If this is a top-level decl that is chained to some other (e.g. int A,B,C;) - // remember this in the TopLevelDeclList list. - TopLevelDeclList.push_back((Decl*)current); -} - void Sema::HandleDeclAttribute(Decl *New, AttributeList *rawAttr) { if (!strcmp(rawAttr->getAttributeName()->getName(), "vector_size") || !strcmp(rawAttr->getAttributeName()->getName(), "__vector_size__")) { diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h index 7b479e6620..65cdc274e6 100644 --- a/include/clang/Parse/Parser.h +++ b/include/clang/Parse/Parser.h @@ -76,7 +76,7 @@ public: /// ParseTopLevelDecl - Parse one top-level declaration. Returns true if /// the EOF was encountered. - bool ParseTopLevelDecl(); + bool ParseTopLevelDecl(DeclTy*& Result); /// Finalize - Shut down the parser. /// |