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...
llvm-svn: 44445
This commit is contained in:
Steve Naroff 2007-11-29 23:05:20 +00:00
parent bfcf8cdbd7
commit 205ec3d07a
6 changed files with 12 additions and 56 deletions

View File

@ -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();

View File

@ -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);
}

View File

@ -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.

View File

@ -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,

View File

@ -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__")) {

View File

@ -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.
///