forked from OSchip/llvm-project
Changes through out the parser and actions/ast interface to return top-level
declarations through the asm streamer. For a testcase like: int G; int H, I, *J; int func() {} 'clang -parse-print-ast' prints: Read top-level decl: G Read top-level decl: H Read top-level decl: I Read top-level decl: J Read top-level decl: func llvm-svn: 38992
This commit is contained in:
parent
a11999d83a
commit
2dacc3ff2e
|
@ -19,15 +19,17 @@ using namespace clang;
|
|||
|
||||
/// Interface to the Builder.cpp file.
|
||||
///
|
||||
Action *CreateASTBuilderActions(Preprocessor &PP, bool FullLocInfo);
|
||||
Action *CreateASTBuilderActions(Preprocessor &PP, bool FullLocInfo,
|
||||
std::vector<Decl*> &LastInGroupList);
|
||||
|
||||
|
||||
namespace {
|
||||
class ASTStreamer {
|
||||
Parser P;
|
||||
std::vector<Decl*> LastInGroupList;
|
||||
public:
|
||||
ASTStreamer(Preprocessor &PP, unsigned MainFileID, bool FullLocInfo)
|
||||
: P(PP, *CreateASTBuilderActions(PP, FullLocInfo)) {
|
||||
: P(PP, *CreateASTBuilderActions(PP, FullLocInfo, LastInGroupList)) {
|
||||
PP.EnterSourceFile(MainFileID, 0, true);
|
||||
|
||||
// Initialize the parser.
|
||||
|
@ -37,9 +39,33 @@ namespace {
|
|||
/// ReadTopLevelDecl - Parse and return the next top-level declaration.
|
||||
Decl *ReadTopLevelDecl() {
|
||||
Parser::DeclTy *Result;
|
||||
if (P.ParseTopLevelDecl(Result))
|
||||
return 0;
|
||||
Result = (Decl*)1; // FIXME!
|
||||
|
||||
/// If the previous time through we read something like 'int X, Y', return
|
||||
/// the next declarator.
|
||||
if (!LastInGroupList.empty()) {
|
||||
Result = LastInGroupList.back();
|
||||
LastInGroupList.pop_back();
|
||||
return (Decl*)Result;
|
||||
}
|
||||
|
||||
do {
|
||||
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 (Result == 0);
|
||||
|
||||
// If we parsed a declspec with multiple declarators, reverse the list and
|
||||
// return the first one.
|
||||
if (!LastInGroupList.empty()) {
|
||||
LastInGroupList.push_back((Decl*)Result);
|
||||
std::reverse(LastInGroupList.begin(), LastInGroupList.end());
|
||||
Result = LastInGroupList.back();
|
||||
LastInGroupList.pop_back();
|
||||
}
|
||||
|
||||
return (Decl*)Result;
|
||||
}
|
||||
|
||||
|
|
|
@ -31,16 +31,25 @@ class VISIBILITY_HIDDEN ASTBuilder : public Action {
|
|||
/// FullLocInfo - If this is true, the ASTBuilder constructs AST Nodes that
|
||||
/// capture maximal location information for each source-language construct.
|
||||
bool FullLocInfo;
|
||||
|
||||
/// LastInGroupList - This vector is populated when there are multiple
|
||||
/// declarators in a single decl group (e.g. "int A, B, C"). In this case,
|
||||
/// all but the last decl will be entered into this. This is used by the
|
||||
/// ASTStreamer.
|
||||
std::vector<Decl*> &LastInGroupList;
|
||||
public:
|
||||
ASTBuilder(Preprocessor &pp, bool fullLocInfo)
|
||||
: PP(pp), FullLocInfo(fullLocInfo) {}
|
||||
ASTBuilder(Preprocessor &pp, bool fullLocInfo,
|
||||
std::vector<Decl*> &prevInGroup)
|
||||
: PP(pp), FullLocInfo(fullLocInfo), LastInGroupList(prevInGroup) {}
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Symbol table tracking callbacks.
|
||||
//
|
||||
virtual bool isTypedefName(const IdentifierInfo &II, Scope *S) const;
|
||||
virtual void ParseDeclarator(SourceLocation Loc, Scope *S, Declarator &D,
|
||||
ExprTy *Init);
|
||||
virtual DeclTy *ParseDeclarator(Scope *S, Declarator &D, ExprTy *Init,
|
||||
DeclTy *LastInGroup);
|
||||
virtual DeclTy *ParseFunctionDefinition(Scope *S, Declarator &D,
|
||||
StmtTy *Body);
|
||||
virtual void PopScope(SourceLocation Loc, Scope *S);
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
@ -103,16 +112,17 @@ bool ASTBuilder::isTypedefName(const IdentifierInfo &II, Scope *S) const {
|
|||
return D != 0 && D->getDeclSpec().StorageClassSpec == DeclSpec::SCS_typedef;
|
||||
}
|
||||
|
||||
void ASTBuilder::ParseDeclarator(SourceLocation Loc, Scope *S, Declarator &D,
|
||||
ExprTy *Init) {
|
||||
Action::DeclTy *
|
||||
ASTBuilder::ParseDeclarator(Scope *S, Declarator &D, ExprTy *Init,
|
||||
DeclTy *LastInGroup) {
|
||||
IdentifierInfo *II = D.getIdentifier();
|
||||
Decl *PrevDecl = II ? II->getFETokenInfo<Decl>() : 0;
|
||||
|
||||
Decl *New;
|
||||
if (D.isFunctionDeclarator())
|
||||
New = new FunctionDecl(II, D, Loc, PrevDecl);
|
||||
New = new FunctionDecl(II, D, PrevDecl);
|
||||
else
|
||||
New = new VarDecl(II, D, Loc, PrevDecl);
|
||||
New = new VarDecl(II, D, PrevDecl);
|
||||
|
||||
// If this has an identifier, add it to the scope stack.
|
||||
if (II) {
|
||||
|
@ -120,6 +130,17 @@ void ASTBuilder::ParseDeclarator(SourceLocation Loc, Scope *S, Declarator &D,
|
|||
II->setFETokenInfo(New);
|
||||
S->AddDecl(II);
|
||||
}
|
||||
|
||||
if (LastInGroup) LastInGroupList.push_back((Decl*)LastInGroup);
|
||||
|
||||
return New;
|
||||
}
|
||||
|
||||
Action::DeclTy *
|
||||
ASTBuilder::ParseFunctionDefinition(Scope *S, Declarator &D, StmtTy *Body) {
|
||||
FunctionDecl *FD = (FunctionDecl *)ParseDeclarator(S, D, 0, 0);
|
||||
// TODO: more stuff.
|
||||
return FD;
|
||||
}
|
||||
|
||||
void ASTBuilder::PopScope(SourceLocation Loc, Scope *S) {
|
||||
|
@ -359,9 +380,8 @@ Action::ExprResult ASTBuilder::ParseConditionalOp(SourceLocation QuestionLoc,
|
|||
|
||||
/// Interface to the Builder.cpp file.
|
||||
///
|
||||
Action *CreateASTBuilderActions(Preprocessor &PP, bool FullLocInfo) {
|
||||
return new ASTBuilder(PP, FullLocInfo);
|
||||
Action *CreateASTBuilderActions(Preprocessor &PP, bool FullLocInfo,
|
||||
std::vector<Decl*> &LastInGroupList) {
|
||||
return new ASTBuilder(PP, FullLocInfo, LastInGroupList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -24,11 +24,11 @@ using namespace clang;
|
|||
namespace {
|
||||
class ParserPrintActions : public EmptyAction {
|
||||
|
||||
/// ParseDeclarator - This callback is invoked when a declarator is parsed and
|
||||
/// 'Init' specifies the initializer if any. This is for things like:
|
||||
/// ParseDeclarator - This callback is invoked when a declarator is parsed
|
||||
/// and 'Init' specifies the initializer if any. This is for things like:
|
||||
/// "int X = 4" or "typedef int foo".
|
||||
virtual void ParseDeclarator(SourceLocation Loc, Scope *S, Declarator &D,
|
||||
ExprTy *Init) {
|
||||
virtual DeclTy *ParseDeclarator(Scope *S, Declarator &D, ExprTy *Init,
|
||||
DeclTy *LastInGroup) {
|
||||
std::cout << "ParseDeclarator ";
|
||||
if (IdentifierInfo *II = D.getIdentifier()) {
|
||||
std::cout << "'" << II->getName() << "'";
|
||||
|
@ -38,7 +38,7 @@ namespace {
|
|||
std::cout << "\n";
|
||||
|
||||
// Pass up to EmptyActions so that the symbol table is maintained right.
|
||||
EmptyAction::ParseDeclarator(Loc, S, D, Init);
|
||||
return EmptyAction::ParseDeclarator(S, D, Init, LastInGroup);
|
||||
}
|
||||
|
||||
/// PopScope - This callback is called immediately before the specified scope
|
||||
|
|
|
@ -577,12 +577,11 @@ static void PrintASTs(Preprocessor &PP, unsigned MainFileID) {
|
|||
ASTStreamerTy *Streamer = ASTStreamer_Init(PP, MainFileID, true);
|
||||
|
||||
while (Decl *D = ASTStreamer_ReadTopLevelDecl(Streamer)) {
|
||||
std::cerr << "Read top-level decl!\n";
|
||||
//if (const IdentifierInfo *II = D->getIdentifier())
|
||||
// std::cerr << II->getName() << "\n";
|
||||
//else
|
||||
// std::cerr << "\n";
|
||||
|
||||
std::cerr << "Read top-level decl: ";
|
||||
if (const IdentifierInfo *II = D->getIdentifier())
|
||||
std::cerr << II->getName() << "\n";
|
||||
else
|
||||
std::cerr << "\n";
|
||||
}
|
||||
|
||||
ASTStreamer_Terminate(Streamer);
|
||||
|
|
|
@ -34,10 +34,11 @@ bool EmptyAction::isTypedefName(const IdentifierInfo &II, Scope *S) const {
|
|||
/// ParseDeclarator - If this is a typedef declarator, we modify the
|
||||
/// IdentifierInfo::FETokenInfo field to keep track of this fact, until S is
|
||||
/// popped.
|
||||
void EmptyAction::ParseDeclarator(SourceLocation Loc, Scope *S, Declarator &D,
|
||||
ExprTy *Init) {
|
||||
Action::DeclTy *
|
||||
EmptyAction::ParseDeclarator(Scope *S, Declarator &D, ExprTy *Init,
|
||||
DeclTy *LastInGroup) {
|
||||
// If there is no identifier associated with this declarator, bail out.
|
||||
if (D.getIdentifier() == 0) return;
|
||||
if (D.getIdentifier() == 0) return 0;
|
||||
|
||||
// Remember whether or not this declarator is a typedef.
|
||||
TypedefInfo *TI = new TypedefInfo();
|
||||
|
@ -50,6 +51,7 @@ void EmptyAction::ParseDeclarator(SourceLocation Loc, Scope *S, Declarator &D,
|
|||
|
||||
// Remember that this needs to be removed when the scope is popped.
|
||||
S->AddDecl(&II);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// PopScope - When a scope is popped, if any typedefs are now out-of-scope,
|
||||
|
|
|
@ -112,7 +112,13 @@ void Parser::ParseDeclaration(unsigned Context) {
|
|||
/// [GNU] declarator simple-asm-expr[opt] attributes[opt]
|
||||
/// [GNU] declarator simple-asm-expr[opt] attributes[opt] '=' initializer
|
||||
///
|
||||
void Parser::ParseInitDeclaratorListAfterFirstDeclarator(Declarator &D) {
|
||||
Parser::DeclTy *Parser::
|
||||
ParseInitDeclaratorListAfterFirstDeclarator(Declarator &D) {
|
||||
|
||||
// Declarators may be grouped together ("int X, *Y, Z();"). Provide info so
|
||||
// that they can be chained properly if the actions want this.
|
||||
Parser::DeclTy *LastDeclInGroup = 0;
|
||||
|
||||
// At this point, we know that it is not a function definition. Parse the
|
||||
// rest of the init-declarator-list.
|
||||
while (1) {
|
||||
|
@ -129,15 +135,16 @@ void Parser::ParseInitDeclaratorListAfterFirstDeclarator(Declarator &D) {
|
|||
if (Tok.getKind() == tok::equal) {
|
||||
ConsumeToken();
|
||||
Init = ParseInitializer();
|
||||
if (!Init.isInvalid) {
|
||||
if (Init.isInvalid) {
|
||||
SkipUntil(tok::semi);
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Inform the current actions module that we just parsed a declarator.
|
||||
// TODO: pass asm & attributes.
|
||||
Actions.ParseDeclarator(Tok.getLocation(), CurScope, D, Init.Val);
|
||||
LastDeclInGroup = Actions.ParseDeclarator(CurScope, D, Init.Val,
|
||||
LastDeclInGroup);
|
||||
|
||||
// If we don't have a comma, it is either the end of the list (a ';') or an
|
||||
// error, bail out.
|
||||
|
@ -154,12 +161,14 @@ void Parser::ParseInitDeclaratorListAfterFirstDeclarator(Declarator &D) {
|
|||
|
||||
if (Tok.getKind() == tok::semi) {
|
||||
ConsumeToken();
|
||||
return LastDeclInGroup;
|
||||
} else {
|
||||
Diag(Tok, diag::err_parse_error);
|
||||
// Skip to end of block or statement
|
||||
SkipUntil(tok::r_brace, true);
|
||||
if (Tok.getKind() == tok::semi)
|
||||
ConsumeToken();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -219,7 +219,7 @@ void Parser::Initialize() {
|
|||
|
||||
Declarator D(DS, Declarator::FileContext);
|
||||
D.SetIdentifier(PP.getIdentifierInfo("__builtin_va_list"),SourceLocation());
|
||||
Actions.ParseDeclarator(SourceLocation(), CurScope, D, 0);
|
||||
Actions.ParseDeclarator(CurScope, D, 0, 0);
|
||||
}
|
||||
|
||||
if (Tok.getKind() == tok::eof) // Empty source file is an extension.
|
||||
|
@ -232,7 +232,7 @@ bool Parser::ParseTopLevelDecl(DeclTy*& Result) {
|
|||
Result = 0;
|
||||
if (Tok.getKind() == tok::eof) return true;
|
||||
|
||||
ParseExternalDeclaration();
|
||||
Result = ParseExternalDeclaration();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -274,21 +274,22 @@ void Parser::ParseTranslationUnit() {
|
|||
/// [GNU] asm-definition:
|
||||
/// simple-asm-expr ';'
|
||||
///
|
||||
void Parser::ParseExternalDeclaration() {
|
||||
Parser::DeclTy *Parser::ParseExternalDeclaration() {
|
||||
switch (Tok.getKind()) {
|
||||
case tok::semi:
|
||||
Diag(diag::ext_top_level_semi);
|
||||
ConsumeToken();
|
||||
break;
|
||||
// TODO: Invoke action for top-level semicolon.
|
||||
return 0;
|
||||
case tok::kw_asm:
|
||||
ParseSimpleAsm();
|
||||
ExpectAndConsume(tok::semi, diag::err_expected_semi_after,
|
||||
"top-level asm block");
|
||||
break;
|
||||
// TODO: Invoke action for top-level asm.
|
||||
return 0;
|
||||
default:
|
||||
// We can't tell whether this is a function-definition or declaration yet.
|
||||
ParseDeclarationOrFunctionDefinition();
|
||||
break;
|
||||
return ParseDeclarationOrFunctionDefinition();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -304,7 +305,7 @@ void Parser::ParseExternalDeclaration() {
|
|||
/// [!C99] init-declarator-list ';' [TODO]
|
||||
/// [OMP] threadprivate-directive [TODO]
|
||||
///
|
||||
void Parser::ParseDeclarationOrFunctionDefinition() {
|
||||
Parser::DeclTy *Parser::ParseDeclarationOrFunctionDefinition() {
|
||||
// Parse the common declaration-specifiers piece.
|
||||
DeclSpec DS;
|
||||
ParseDeclarationSpecifiers(DS);
|
||||
|
@ -316,7 +317,8 @@ void Parser::ParseDeclarationOrFunctionDefinition() {
|
|||
// if (!DS.isMissingDeclaratorOk()) Diag(...);
|
||||
|
||||
ConsumeToken();
|
||||
return;
|
||||
// TODO: Return type definition.
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Parse the first declarator.
|
||||
|
@ -328,32 +330,31 @@ void Parser::ParseDeclarationOrFunctionDefinition() {
|
|||
SkipUntil(tok::r_brace, true);
|
||||
if (Tok.getKind() == tok::semi)
|
||||
ConsumeToken();
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// If the declarator is the start of a function definition, handle it.
|
||||
if (Tok.getKind() == tok::equal || // int X()= -> not a function def
|
||||
Tok.getKind() == tok::comma || // int X(), -> not a function def
|
||||
Tok.getKind() == tok::semi || // int X(); -> not a function def
|
||||
Tok.getKind() == tok::semi || // int X(); -> not a function def
|
||||
Tok.getKind() == tok::kw_asm || // int X() __asm__ -> not a fn def
|
||||
Tok.getKind() == tok::kw___attribute) {// int X() __attr__ -> not a fn def
|
||||
// FALL THROUGH.
|
||||
} else if (DeclaratorInfo.isFunctionDeclarator() &&
|
||||
(Tok.getKind() == tok::l_brace || // int X() {}
|
||||
isDeclarationSpecifier())) { // int X(f) int f; {}
|
||||
ParseFunctionDefinition(DeclaratorInfo);
|
||||
return;
|
||||
return ParseFunctionDefinition(DeclaratorInfo);
|
||||
} else {
|
||||
if (DeclaratorInfo.isFunctionDeclarator())
|
||||
Diag(Tok, diag::err_expected_fn_body);
|
||||
else
|
||||
Diag(Tok, diag::err_expected_after_declarator);
|
||||
SkipUntil(tok::semi);
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Parse the init-declarator-list for a normal declaration.
|
||||
ParseInitDeclaratorListAfterFirstDeclarator(DeclaratorInfo);
|
||||
return ParseInitDeclaratorListAfterFirstDeclarator(DeclaratorInfo);
|
||||
}
|
||||
|
||||
/// ParseFunctionDefinition - We parsed and verified that the specified
|
||||
|
@ -363,7 +364,7 @@ void Parser::ParseDeclarationOrFunctionDefinition() {
|
|||
/// declaration-specifiers[opt] declarator declaration-list[opt]
|
||||
/// compound-statement [TODO]
|
||||
///
|
||||
void Parser::ParseFunctionDefinition(Declarator &D) {
|
||||
Parser::DeclTy *Parser::ParseFunctionDefinition(Declarator &D) {
|
||||
const DeclaratorTypeInfo &FnTypeInfo = D.getTypeObject(0);
|
||||
assert(FnTypeInfo.Kind == DeclaratorTypeInfo::Function &&
|
||||
"This isn't a function declarator!");
|
||||
|
@ -393,10 +394,15 @@ void Parser::ParseFunctionDefinition(Declarator &D) {
|
|||
|
||||
// If we didn't find the '{', bail out.
|
||||
if (Tok.getKind() != tok::l_brace)
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// TODO: Get stmt info.
|
||||
StmtTy *FnBody = 0;
|
||||
ParseCompoundStatement();
|
||||
|
||||
// TODO: Pass argument information.
|
||||
return Actions.ParseFunctionDefinition(CurScope, D, FnBody);
|
||||
}
|
||||
|
||||
/// ParseAsmStringLiteral - This is just a normal string-literal, but is not
|
||||
|
|
|
@ -19,15 +19,17 @@ using namespace clang;
|
|||
|
||||
/// Interface to the Builder.cpp file.
|
||||
///
|
||||
Action *CreateASTBuilderActions(Preprocessor &PP, bool FullLocInfo);
|
||||
Action *CreateASTBuilderActions(Preprocessor &PP, bool FullLocInfo,
|
||||
std::vector<Decl*> &LastInGroupList);
|
||||
|
||||
|
||||
namespace {
|
||||
class ASTStreamer {
|
||||
Parser P;
|
||||
std::vector<Decl*> LastInGroupList;
|
||||
public:
|
||||
ASTStreamer(Preprocessor &PP, unsigned MainFileID, bool FullLocInfo)
|
||||
: P(PP, *CreateASTBuilderActions(PP, FullLocInfo)) {
|
||||
: P(PP, *CreateASTBuilderActions(PP, FullLocInfo, LastInGroupList)) {
|
||||
PP.EnterSourceFile(MainFileID, 0, true);
|
||||
|
||||
// Initialize the parser.
|
||||
|
@ -37,9 +39,33 @@ namespace {
|
|||
/// ReadTopLevelDecl - Parse and return the next top-level declaration.
|
||||
Decl *ReadTopLevelDecl() {
|
||||
Parser::DeclTy *Result;
|
||||
if (P.ParseTopLevelDecl(Result))
|
||||
return 0;
|
||||
Result = (Decl*)1; // FIXME!
|
||||
|
||||
/// If the previous time through we read something like 'int X, Y', return
|
||||
/// the next declarator.
|
||||
if (!LastInGroupList.empty()) {
|
||||
Result = LastInGroupList.back();
|
||||
LastInGroupList.pop_back();
|
||||
return (Decl*)Result;
|
||||
}
|
||||
|
||||
do {
|
||||
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 (Result == 0);
|
||||
|
||||
// If we parsed a declspec with multiple declarators, reverse the list and
|
||||
// return the first one.
|
||||
if (!LastInGroupList.empty()) {
|
||||
LastInGroupList.push_back((Decl*)Result);
|
||||
std::reverse(LastInGroupList.begin(), LastInGroupList.end());
|
||||
Result = LastInGroupList.back();
|
||||
LastInGroupList.pop_back();
|
||||
}
|
||||
|
||||
return (Decl*)Result;
|
||||
}
|
||||
|
||||
|
|
|
@ -31,16 +31,25 @@ class VISIBILITY_HIDDEN ASTBuilder : public Action {
|
|||
/// FullLocInfo - If this is true, the ASTBuilder constructs AST Nodes that
|
||||
/// capture maximal location information for each source-language construct.
|
||||
bool FullLocInfo;
|
||||
|
||||
/// LastInGroupList - This vector is populated when there are multiple
|
||||
/// declarators in a single decl group (e.g. "int A, B, C"). In this case,
|
||||
/// all but the last decl will be entered into this. This is used by the
|
||||
/// ASTStreamer.
|
||||
std::vector<Decl*> &LastInGroupList;
|
||||
public:
|
||||
ASTBuilder(Preprocessor &pp, bool fullLocInfo)
|
||||
: PP(pp), FullLocInfo(fullLocInfo) {}
|
||||
ASTBuilder(Preprocessor &pp, bool fullLocInfo,
|
||||
std::vector<Decl*> &prevInGroup)
|
||||
: PP(pp), FullLocInfo(fullLocInfo), LastInGroupList(prevInGroup) {}
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Symbol table tracking callbacks.
|
||||
//
|
||||
virtual bool isTypedefName(const IdentifierInfo &II, Scope *S) const;
|
||||
virtual void ParseDeclarator(SourceLocation Loc, Scope *S, Declarator &D,
|
||||
ExprTy *Init);
|
||||
virtual DeclTy *ParseDeclarator(Scope *S, Declarator &D, ExprTy *Init,
|
||||
DeclTy *LastInGroup);
|
||||
virtual DeclTy *ParseFunctionDefinition(Scope *S, Declarator &D,
|
||||
StmtTy *Body);
|
||||
virtual void PopScope(SourceLocation Loc, Scope *S);
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
@ -103,16 +112,17 @@ bool ASTBuilder::isTypedefName(const IdentifierInfo &II, Scope *S) const {
|
|||
return D != 0 && D->getDeclSpec().StorageClassSpec == DeclSpec::SCS_typedef;
|
||||
}
|
||||
|
||||
void ASTBuilder::ParseDeclarator(SourceLocation Loc, Scope *S, Declarator &D,
|
||||
ExprTy *Init) {
|
||||
Action::DeclTy *
|
||||
ASTBuilder::ParseDeclarator(Scope *S, Declarator &D, ExprTy *Init,
|
||||
DeclTy *LastInGroup) {
|
||||
IdentifierInfo *II = D.getIdentifier();
|
||||
Decl *PrevDecl = II ? II->getFETokenInfo<Decl>() : 0;
|
||||
|
||||
Decl *New;
|
||||
if (D.isFunctionDeclarator())
|
||||
New = new FunctionDecl(II, D, Loc, PrevDecl);
|
||||
New = new FunctionDecl(II, D, PrevDecl);
|
||||
else
|
||||
New = new VarDecl(II, D, Loc, PrevDecl);
|
||||
New = new VarDecl(II, D, PrevDecl);
|
||||
|
||||
// If this has an identifier, add it to the scope stack.
|
||||
if (II) {
|
||||
|
@ -120,6 +130,17 @@ void ASTBuilder::ParseDeclarator(SourceLocation Loc, Scope *S, Declarator &D,
|
|||
II->setFETokenInfo(New);
|
||||
S->AddDecl(II);
|
||||
}
|
||||
|
||||
if (LastInGroup) LastInGroupList.push_back((Decl*)LastInGroup);
|
||||
|
||||
return New;
|
||||
}
|
||||
|
||||
Action::DeclTy *
|
||||
ASTBuilder::ParseFunctionDefinition(Scope *S, Declarator &D, StmtTy *Body) {
|
||||
FunctionDecl *FD = (FunctionDecl *)ParseDeclarator(S, D, 0, 0);
|
||||
// TODO: more stuff.
|
||||
return FD;
|
||||
}
|
||||
|
||||
void ASTBuilder::PopScope(SourceLocation Loc, Scope *S) {
|
||||
|
@ -359,9 +380,8 @@ Action::ExprResult ASTBuilder::ParseConditionalOp(SourceLocation QuestionLoc,
|
|||
|
||||
/// Interface to the Builder.cpp file.
|
||||
///
|
||||
Action *CreateASTBuilderActions(Preprocessor &PP, bool FullLocInfo) {
|
||||
return new ASTBuilder(PP, FullLocInfo);
|
||||
Action *CreateASTBuilderActions(Preprocessor &PP, bool FullLocInfo,
|
||||
std::vector<Decl*> &LastInGroupList) {
|
||||
return new ASTBuilder(PP, FullLocInfo, LastInGroupList);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -36,17 +36,12 @@ class Decl {
|
|||
/// Type.
|
||||
/// Kind.
|
||||
|
||||
/// Loc - The location of the declaration in the source code.
|
||||
///
|
||||
SourceLocation Loc;
|
||||
|
||||
/// Scope stack info when parsing, otherwise decl list when scope is popped.
|
||||
///
|
||||
Decl *Next;
|
||||
public:
|
||||
Decl(IdentifierInfo *Id, const Declarator &D, SourceLocation loc, Decl *next)
|
||||
: Identifier(Id), DeclarationSpecifier(D.getDeclSpec()), Loc(loc),
|
||||
Next(next) {}
|
||||
Decl(IdentifierInfo *Id, const Declarator &D, Decl *next)
|
||||
: Identifier(Id), DeclarationSpecifier(D.getDeclSpec()), Next(next) {}
|
||||
|
||||
const IdentifierInfo *getIdentifier() const { return Identifier; }
|
||||
|
||||
|
@ -60,8 +55,8 @@ public:
|
|||
class FunctionDecl : public Decl {
|
||||
// Args etc.
|
||||
public:
|
||||
FunctionDecl(IdentifierInfo *Id, const Declarator &D,
|
||||
SourceLocation Loc, Decl *Next) : Decl(Id, D, Loc, Next) {}
|
||||
FunctionDecl(IdentifierInfo *Id, const Declarator &D, Decl *Next)
|
||||
: Decl(Id, D, Next) {}
|
||||
|
||||
};
|
||||
|
||||
|
@ -70,8 +65,8 @@ public:
|
|||
class VarDecl : public Decl {
|
||||
// Initializer.
|
||||
public:
|
||||
VarDecl(IdentifierInfo *Id, const Declarator &D,
|
||||
SourceLocation Loc, Decl *Next) : Decl(Id, D, Loc, Next) {}
|
||||
VarDecl(IdentifierInfo *Id, const Declarator &D, Decl *Next)
|
||||
: Decl(Id, D, Next) {}
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -47,6 +47,7 @@ public:
|
|||
// Types - Though these don't actually enforce strong typing, they document
|
||||
// what types are required to be identical for the actions.
|
||||
typedef void ExprTy;
|
||||
typedef void StmtTy;
|
||||
typedef void DeclTy;
|
||||
typedef void TypeTy;
|
||||
|
||||
|
@ -79,13 +80,32 @@ public:
|
|||
/// ParseDeclarator - This callback is invoked when a declarator is parsed and
|
||||
/// 'Init' specifies the initializer if any. This is for things like:
|
||||
/// "int X = 4" or "typedef int foo".
|
||||
virtual void ParseDeclarator(SourceLocation Loc, Scope *S, Declarator &D,
|
||||
ExprTy *Init) {}
|
||||
|
||||
///
|
||||
/// LastInGroup is non-null for cases where one declspec has multiple
|
||||
/// declarators on it. For example in 'int A, B', ParseDeclarator will be
|
||||
/// called with LastInGroup=A when invoked for B.
|
||||
virtual DeclTy *ParseDeclarator(Scope *S, Declarator &D,
|
||||
ExprTy *Init, DeclTy *LastInGroup) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// ParseFunctionDefinition - This is called when a function definition is
|
||||
/// parsed. The declarator that is part of this is not passed to
|
||||
/// ParseDeclarator.
|
||||
virtual DeclTy *ParseFunctionDefinition(Scope *S, Declarator &D,
|
||||
// TODO: FORMAL ARG INFO.
|
||||
StmtTy *Body) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// PopScope - This callback is called immediately before the specified scope
|
||||
/// is popped and deleted.
|
||||
virtual void PopScope(SourceLocation Loc, Scope *S) {}
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// 'External Declaration' (Top Level) Parsing Callbacks.
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Expression Parsing Callbacks.
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
@ -178,8 +198,8 @@ public:
|
|||
/// ParseDeclarator - If this is a typedef declarator, we modify the
|
||||
/// IdentifierInfo::FETokenInfo field to keep track of this fact, until S is
|
||||
/// popped.
|
||||
virtual void ParseDeclarator(SourceLocation Loc, Scope *S, Declarator &D,
|
||||
ExprTy *Init);
|
||||
virtual DeclTy *ParseDeclarator(Scope *S, Declarator &D, ExprTy *Init,
|
||||
DeclTy *LastInGroup);
|
||||
|
||||
/// PopScope - When a scope is popped, if any typedefs are now out-of-scope,
|
||||
/// they are removed from the IdentifierInfo::FETokenInfo field.
|
||||
|
|
|
@ -48,6 +48,7 @@ public:
|
|||
// Type forwarding. All of these are statically 'void*', but they may all be
|
||||
// different actual classes based on the actions in place.
|
||||
typedef Action::ExprTy ExprTy;
|
||||
typedef Action::StmtTy StmtTy;
|
||||
typedef Action::DeclTy DeclTy;
|
||||
typedef Action::TypeTy TypeTy;
|
||||
|
||||
|
@ -214,9 +215,9 @@ private:
|
|||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// C99 6.9: External Definitions.
|
||||
void ParseExternalDeclaration();
|
||||
void ParseDeclarationOrFunctionDefinition();
|
||||
void ParseFunctionDefinition(Declarator &D);
|
||||
DeclTy *ParseExternalDeclaration();
|
||||
DeclTy *ParseDeclarationOrFunctionDefinition();
|
||||
DeclTy *ParseFunctionDefinition(Declarator &D);
|
||||
void ParseSimpleAsm();
|
||||
void ParseAsmStringLiteral();
|
||||
|
||||
|
@ -285,7 +286,7 @@ private:
|
|||
// C99 6.7: Declarations.
|
||||
|
||||
void ParseDeclaration(unsigned Context);
|
||||
void ParseInitDeclaratorListAfterFirstDeclarator(Declarator &D);
|
||||
DeclTy *ParseInitDeclaratorListAfterFirstDeclarator(Declarator &D);
|
||||
void ParseDeclarationSpecifiers(DeclSpec &DS);
|
||||
void ParseSpecifierQualifierList(DeclSpec &DS);
|
||||
|
||||
|
|
Loading…
Reference in New Issue