Implement first cut of ASTBuilder class.

llvm-svn: 38938
This commit is contained in:
Chris Lattner 2006-08-18 05:17:52 +00:00
parent 01b0f1be80
commit c11438cee1
9 changed files with 176 additions and 14 deletions

View File

@ -14,20 +14,20 @@
#include "clang/AST/ASTStreamer.h"
#include "clang/Parse/Action.h"
#include "clang/Parse/Parser.h"
using namespace llvm;
using namespace clang;
/// Interface to the Builder.cpp file.
///
Action *CreateASTBuilderActions();
namespace {
class ASTStreamer {
EmptyAction Builder;
Parser P;
public:
ASTStreamer(Preprocessor &PP, unsigned MainFileID)
: P(PP, Builder) {
: P(PP, *CreateASTBuilderActions()) {
PP.EnterSourceFile(MainFileID, 0, true);
// Initialize the parser.
@ -45,6 +45,7 @@ namespace {
~ASTStreamer() {
P.Finalize();
delete &P.getActions();
}
};
}

View File

@ -12,4 +12,75 @@
//
//===----------------------------------------------------------------------===//
int xx;
#include "clang/Parse/Action.h"
#include "clang/Parse/Scope.h"
#include "clang/AST/Decl.h"
#include "clang/Lex/IdentifierTable.h"
#include "llvm/Support/Visibility.h"
using namespace llvm;
using namespace clang;
/// ASTBuilder
namespace {
class VISIBILITY_HIDDEN ASTBuilder : public Action {
public:
//===--------------------------------------------------------------------===//
// 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 void PopScope(SourceLocation Loc, Scope *S);
};
} // end anonymous namespace
//===----------------------------------------------------------------------===//
// Symbol table tracking callbacks.
//===----------------------------------------------------------------------===//
bool ASTBuilder::isTypedefName(const IdentifierInfo &II, Scope *S) const {
Decl *D = II.getFETokenInfo<Decl>();
return D != 0 && D->getDeclSpecs().StorageClassSpec == DeclSpec::SCS_typedef;
}
void ASTBuilder::ParseDeclarator(SourceLocation Loc, Scope *S, Declarator &D,
ExprTy *Init) {
IdentifierInfo *II = D.getIdentifier();
Decl *PrevDecl = II ? II->getFETokenInfo<Decl>() : 0;
Decl *New = new Decl(II, D.getDeclSpec(), Loc, PrevDecl);
// If this has an identifier, add it to the scope stack.
if (II) {
// If PrevDecl includes conflicting name here, emit a diagnostic.
II->setFETokenInfo(New);
S->AddDecl(II);
}
}
void ASTBuilder::PopScope(SourceLocation Loc, Scope *S) {
for (Scope::decl_iterator I = S->decl_begin(), E = S->decl_end();
I != E; ++I) {
IdentifierInfo &II = *static_cast<IdentifierInfo*>(*I);
Decl *D = II.getFETokenInfo<Decl>();
assert(D && "This decl didn't get pushed??");
Decl *Next = D->getNext();
// FIXME: Push the decl on the parent function list if in a function.
delete D;
II.setFETokenInfo(Next);
}
}
/// Interface to the Builder.cpp file.
///
Action *CreateASTBuilderActions() {
return new ASTBuilder();
}

View File

@ -14,20 +14,20 @@
#include "clang/AST/ASTStreamer.h"
#include "clang/Parse/Action.h"
#include "clang/Parse/Parser.h"
using namespace llvm;
using namespace clang;
/// Interface to the Builder.cpp file.
///
Action *CreateASTBuilderActions();
namespace {
class ASTStreamer {
EmptyAction Builder;
Parser P;
public:
ASTStreamer(Preprocessor &PP, unsigned MainFileID)
: P(PP, Builder) {
: P(PP, *CreateASTBuilderActions()) {
PP.EnterSourceFile(MainFileID, 0, true);
// Initialize the parser.
@ -45,6 +45,7 @@ namespace {
~ASTStreamer() {
P.Finalize();
delete &P.getActions();
}
};
}

View File

@ -12,4 +12,75 @@
//
//===----------------------------------------------------------------------===//
int xx;
#include "clang/Parse/Action.h"
#include "clang/Parse/Scope.h"
#include "clang/AST/Decl.h"
#include "clang/Lex/IdentifierTable.h"
#include "llvm/Support/Visibility.h"
using namespace llvm;
using namespace clang;
/// ASTBuilder
namespace {
class VISIBILITY_HIDDEN ASTBuilder : public Action {
public:
//===--------------------------------------------------------------------===//
// 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 void PopScope(SourceLocation Loc, Scope *S);
};
} // end anonymous namespace
//===----------------------------------------------------------------------===//
// Symbol table tracking callbacks.
//===----------------------------------------------------------------------===//
bool ASTBuilder::isTypedefName(const IdentifierInfo &II, Scope *S) const {
Decl *D = II.getFETokenInfo<Decl>();
return D != 0 && D->getDeclSpecs().StorageClassSpec == DeclSpec::SCS_typedef;
}
void ASTBuilder::ParseDeclarator(SourceLocation Loc, Scope *S, Declarator &D,
ExprTy *Init) {
IdentifierInfo *II = D.getIdentifier();
Decl *PrevDecl = II ? II->getFETokenInfo<Decl>() : 0;
Decl *New = new Decl(II, D.getDeclSpec(), Loc, PrevDecl);
// If this has an identifier, add it to the scope stack.
if (II) {
// If PrevDecl includes conflicting name here, emit a diagnostic.
II->setFETokenInfo(New);
S->AddDecl(II);
}
}
void ASTBuilder::PopScope(SourceLocation Loc, Scope *S) {
for (Scope::decl_iterator I = S->decl_begin(), E = S->decl_end();
I != E; ++I) {
IdentifierInfo &II = *static_cast<IdentifierInfo*>(*I);
Decl *D = II.getFETokenInfo<Decl>();
assert(D && "This decl didn't get pushed??");
Decl *Next = D->getNext();
// FIXME: Push the decl on the parent function list if in a function.
delete D;
II.setFETokenInfo(Next);
}
}
/// Interface to the Builder.cpp file.
///
Action *CreateASTBuilderActions() {
return new ASTBuilder();
}

View File

@ -17,6 +17,7 @@
DE06D4410A8BB55C0050E87E /* Declaration.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE06D4400A8BB55C0050E87E /* Declaration.cpp */; };
DE06E4D70A8FBF7A0050E87E /* Initializer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE06E4D60A8FBF7A0050E87E /* Initializer.cpp */; };
DE06E8140A8FF9330050E87E /* Action.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE06E8130A8FF9330050E87E /* Action.h */; };
DE0FCA210A95710600248FD5 /* EmptyAction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DE0FCA200A95710600248FD5 /* EmptyAction.cpp */; };
DE1F22030A7D852A00FBF588 /* Parser.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE1F22020A7D852A00FBF588 /* Parser.h */; };
DE1F24820A7DCD3800FBF588 /* Declarations.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE1F24810A7DCD3800FBF588 /* Declarations.h */; };
DEAEE98B0A5A2B970045101B /* MultipleIncludeOpt.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DEAEE98A0A5A2B970045101B /* MultipleIncludeOpt.h */; };
@ -114,6 +115,7 @@
DE06D4400A8BB55C0050E87E /* Declaration.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Declaration.cpp; path = Parse/Declaration.cpp; sourceTree = "<group>"; };
DE06E4D60A8FBF7A0050E87E /* Initializer.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Initializer.cpp; path = Parse/Initializer.cpp; sourceTree = "<group>"; };
DE06E8130A8FF9330050E87E /* Action.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Action.h; path = clang/Parse/Action.h; sourceTree = "<group>"; };
DE0FCA200A95710600248FD5 /* EmptyAction.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = EmptyAction.cpp; path = Parse/EmptyAction.cpp; sourceTree = "<group>"; };
DE1F22020A7D852A00FBF588 /* Parser.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Parser.h; path = clang/Parse/Parser.h; sourceTree = "<group>"; };
DE1F24810A7DCD3800FBF588 /* Declarations.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Declarations.h; path = clang/Parse/Declarations.h; sourceTree = "<group>"; };
DEAEE98A0A5A2B970045101B /* MultipleIncludeOpt.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MultipleIncludeOpt.h; sourceTree = "<group>"; };
@ -225,6 +227,7 @@
isa = PBXGroup;
children = (
DE06D4400A8BB55C0050E87E /* Declaration.cpp */,
DE0FCA200A95710600248FD5 /* EmptyAction.cpp */,
DE06D42E0A8BB52D0050E87E /* DeclarationSemantics.cpp */,
DE06CEBF0A8AE7800050E87E /* Expression.cpp */,
DE06E4D60A8FBF7A0050E87E /* Initializer.cpp */,
@ -403,6 +406,7 @@
DEC8D9B60A9434FA00353FCA /* Builder.cpp in Sources */,
DEC8DA1E0A94388B00353FCA /* PrintParserCallbacks.cpp in Sources */,
DEC8DAAD0A94400300353FCA /* ASTStreamer.cpp in Sources */,
DE0FCA210A95710600248FD5 /* EmptyAction.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

View File

@ -1,4 +1,4 @@
//===--- AST.h - "Umbrella" header for AST library --------------*- C++ -*-===//
//===--- ASTStreamer.h - Stream ASTs for top-level decls --------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//

View File

@ -15,6 +15,7 @@
#define LLVM_CLANG_AST_DECL_H
#include "clang/Basic/SourceLocation.h"
#include "clang/Parse/Declarations.h"
namespace llvm {
namespace clang {
@ -28,6 +29,10 @@ class Decl {
/// variable, the tag for a struct).
IdentifierInfo *Identifier;
/// DeclarationSpecifier - Information about storage class, type specifiers,
/// etc.
DeclSpec DeclarationSpecifier;
/// Type.
/// Kind.
@ -35,14 +40,22 @@ class Decl {
///
SourceLocation Loc;
#if 0
/// Next - Decls are chained together in a singly-linked list by their owning
/// object. Currently we allow decls to be owned by a translation unit or a
/// function. This way we can deallocate a function body and all the
/// declarations within it.
#endif
// Scope stack info when parsing, otherwise decl list when scope is popped.
Decl *Next;
public:
Decl(IdentifierInfo *Id, SourceLocation loc, Decl *next)
: Identifier(Id), Loc(loc), Next(next) {}
Decl(IdentifierInfo *Id, const DeclSpec &DS, SourceLocation loc, Decl *next)
: Identifier(Id), DeclarationSpecifier(DS), Loc(loc), Next(next) {}
const DeclSpec &getDeclSpecs() const { return DeclarationSpecifier; }
Decl *getNext() const { return Next; }
};

View File

@ -42,6 +42,7 @@ public:
~Parser();
const LangOptions &getLang() const { return PP.getLangOptions(); }
Action &getActions() const { return Actions; }
// Type forwarding. All of these are statically 'void*', but they may all be
// different actual classes based on the actions in place.

View File

@ -1,4 +1,4 @@
//===--- AST.h - "Umbrella" header for AST library --------------*- C++ -*-===//
//===--- ASTStreamer.h - Stream ASTs for top-level decls --------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//