forked from OSchip/llvm-project
Next big step in function parsing: create decl objects for parameters,
inserting them into the function body scope and registering them with the corresponding FunctionDecl. llvm-svn: 39253
This commit is contained in:
parent
7f58c3dfe4
commit
c5cdf4d092
|
@ -23,3 +23,20 @@ Decl::~Decl() {
|
|||
const char *Decl::getName() const {
|
||||
return getIdentifier()->getName();
|
||||
}
|
||||
|
||||
|
||||
FunctionDecl::~FunctionDecl() {
|
||||
delete[] ParamInfo;
|
||||
}
|
||||
|
||||
unsigned FunctionDecl::getNumParams() const {
|
||||
return cast<FunctionTypeProto>(getType().getTypePtr())->getNumArgs();
|
||||
}
|
||||
|
||||
void FunctionDecl::setParams(VarDecl **NewParamInfo, unsigned NumParams) {
|
||||
assert(ParamInfo == 0 && "Already has param info!");
|
||||
assert(NumParams == getNumParams() && "Parameter count mismatch!");
|
||||
|
||||
ParamInfo = new VarDecl*[NumParams];
|
||||
memcpy(ParamInfo, NewParamInfo, sizeof(VarDecl*)*NumParams);
|
||||
}
|
||||
|
|
|
@ -24,9 +24,11 @@ namespace clang {
|
|||
class ASTContext;
|
||||
class Preprocessor;
|
||||
class Decl;
|
||||
class VarDecl;
|
||||
class TypeRef;
|
||||
class LangOptions;
|
||||
class FunctionDecl;
|
||||
class DeclaratorChunk;
|
||||
|
||||
/// Sema - This implements semantic analysis and AST building for C.
|
||||
class Sema : public Action {
|
||||
|
@ -66,8 +68,9 @@ public:
|
|||
virtual DeclTy *isTypeName(const IdentifierInfo &II, Scope *S) const;
|
||||
virtual DeclTy *ParseDeclarator(Scope *S, Declarator &D, ExprTy *Init,
|
||||
DeclTy *LastInGroup);
|
||||
virtual DeclTy *ParseStartOfFunctionDef(Scope *S, Declarator &D
|
||||
/* TODO: FORMAL ARG INFO.*/);
|
||||
VarDecl *ParseParamDeclarator(DeclaratorChunk &FI, unsigned ArgNo,
|
||||
Scope *FnBodyScope);
|
||||
virtual DeclTy *ParseStartOfFunctionDef(Scope *S, Declarator &D);
|
||||
virtual DeclTy *ParseFunctionDefBody(DeclTy *Decl, StmtTy *Body);
|
||||
virtual void PopScope(SourceLocation Loc, Scope *S);
|
||||
|
||||
|
|
|
@ -101,10 +101,34 @@ Sema::ParseDeclarator(Scope *S, Declarator &D, ExprTy *Init,
|
|||
return New;
|
||||
}
|
||||
|
||||
VarDecl *
|
||||
Sema::ParseParamDeclarator(DeclaratorChunk &FTI, unsigned ArgNo,
|
||||
Scope *FnScope) {
|
||||
const DeclaratorChunk::ParamInfo &PI = FTI.Fun.ArgInfo[ArgNo];
|
||||
|
||||
IdentifierInfo *II = PI.Ident;
|
||||
Decl *PrevDecl = 0;
|
||||
|
||||
if (II) {
|
||||
PrevDecl = II->getFETokenInfo<Decl>();
|
||||
|
||||
// TODO: CHECK FOR CONFLICTS, multiple decls with same name in one scope.
|
||||
}
|
||||
|
||||
VarDecl *New = new VarDecl(II, static_cast<Type*>(PI.TypeInfo), 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);
|
||||
FnScope->AddDecl(II);
|
||||
}
|
||||
|
||||
return New;
|
||||
}
|
||||
|
||||
|
||||
Sema::DeclTy *Sema::ParseStartOfFunctionDef(Scope *S, Declarator &D
|
||||
/* TODO: FORMAL ARG INFO.*/) {
|
||||
Sema::DeclTy *Sema::ParseStartOfFunctionDef(Scope *FnBodyScope, Declarator &D) {
|
||||
assert(CurFunctionDecl == 0 && "Function parsing confused");
|
||||
assert(D.getTypeObject(0).Kind == DeclaratorChunk::Function &&
|
||||
"Not a function declarator!");
|
||||
|
@ -131,14 +155,18 @@ Sema::DeclTy *Sema::ParseStartOfFunctionDef(Scope *S, Declarator &D
|
|||
|
||||
}
|
||||
|
||||
FunctionDecl *FD = static_cast<FunctionDecl*>(ParseDeclarator(S, D, 0, 0));
|
||||
Scope *GlobalScope = FnBodyScope->getParent();
|
||||
|
||||
FunctionDecl *FD =
|
||||
static_cast<FunctionDecl*>(ParseDeclarator(GlobalScope, D, 0, 0));
|
||||
CurFunctionDecl = FD;
|
||||
|
||||
// Since this is a function definition, remember the names of the arguments in
|
||||
// the FunctionDecl.
|
||||
|
||||
// FIXME: TODO. Add to FunctionDecl, install declarators into current scope.
|
||||
// Create Decl objects for each parameter, adding them to the FunctionDecl.
|
||||
SmallVector<VarDecl*, 16> Params;
|
||||
for (unsigned i = 0, e = FTI.NumArgs; i != e; ++i)
|
||||
Params.push_back(ParseParamDeclarator(D.getTypeObject(0), i, FnBodyScope));
|
||||
|
||||
FD->setParams(&Params[0], Params.size());
|
||||
|
||||
return FD;
|
||||
}
|
||||
|
|
|
@ -24,9 +24,11 @@ namespace clang {
|
|||
class ASTContext;
|
||||
class Preprocessor;
|
||||
class Decl;
|
||||
class VarDecl;
|
||||
class TypeRef;
|
||||
class LangOptions;
|
||||
class FunctionDecl;
|
||||
class DeclaratorChunk;
|
||||
|
||||
/// Sema - This implements semantic analysis and AST building for C.
|
||||
class Sema : public Action {
|
||||
|
@ -66,8 +68,9 @@ public:
|
|||
virtual DeclTy *isTypeName(const IdentifierInfo &II, Scope *S) const;
|
||||
virtual DeclTy *ParseDeclarator(Scope *S, Declarator &D, ExprTy *Init,
|
||||
DeclTy *LastInGroup);
|
||||
virtual DeclTy *ParseStartOfFunctionDef(Scope *S, Declarator &D
|
||||
/* TODO: FORMAL ARG INFO.*/);
|
||||
VarDecl *ParseParamDeclarator(DeclaratorChunk &FI, unsigned ArgNo,
|
||||
Scope *FnBodyScope);
|
||||
virtual DeclTy *ParseStartOfFunctionDef(Scope *S, Declarator &D);
|
||||
virtual DeclTy *ParseFunctionDefBody(DeclTy *Decl, StmtTy *Body);
|
||||
virtual void PopScope(SourceLocation Loc, Scope *S);
|
||||
|
||||
|
|
|
@ -101,10 +101,34 @@ Sema::ParseDeclarator(Scope *S, Declarator &D, ExprTy *Init,
|
|||
return New;
|
||||
}
|
||||
|
||||
VarDecl *
|
||||
Sema::ParseParamDeclarator(DeclaratorChunk &FTI, unsigned ArgNo,
|
||||
Scope *FnScope) {
|
||||
const DeclaratorChunk::ParamInfo &PI = FTI.Fun.ArgInfo[ArgNo];
|
||||
|
||||
IdentifierInfo *II = PI.Ident;
|
||||
Decl *PrevDecl = 0;
|
||||
|
||||
if (II) {
|
||||
PrevDecl = II->getFETokenInfo<Decl>();
|
||||
|
||||
// TODO: CHECK FOR CONFLICTS, multiple decls with same name in one scope.
|
||||
}
|
||||
|
||||
VarDecl *New = new VarDecl(II, static_cast<Type*>(PI.TypeInfo), 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);
|
||||
FnScope->AddDecl(II);
|
||||
}
|
||||
|
||||
return New;
|
||||
}
|
||||
|
||||
|
||||
Sema::DeclTy *Sema::ParseStartOfFunctionDef(Scope *S, Declarator &D
|
||||
/* TODO: FORMAL ARG INFO.*/) {
|
||||
Sema::DeclTy *Sema::ParseStartOfFunctionDef(Scope *FnBodyScope, Declarator &D) {
|
||||
assert(CurFunctionDecl == 0 && "Function parsing confused");
|
||||
assert(D.getTypeObject(0).Kind == DeclaratorChunk::Function &&
|
||||
"Not a function declarator!");
|
||||
|
@ -131,14 +155,18 @@ Sema::DeclTy *Sema::ParseStartOfFunctionDef(Scope *S, Declarator &D
|
|||
|
||||
}
|
||||
|
||||
FunctionDecl *FD = static_cast<FunctionDecl*>(ParseDeclarator(S, D, 0, 0));
|
||||
Scope *GlobalScope = FnBodyScope->getParent();
|
||||
|
||||
FunctionDecl *FD =
|
||||
static_cast<FunctionDecl*>(ParseDeclarator(GlobalScope, D, 0, 0));
|
||||
CurFunctionDecl = FD;
|
||||
|
||||
// Since this is a function definition, remember the names of the arguments in
|
||||
// the FunctionDecl.
|
||||
|
||||
// FIXME: TODO. Add to FunctionDecl, install declarators into current scope.
|
||||
// Create Decl objects for each parameter, adding them to the FunctionDecl.
|
||||
SmallVector<VarDecl*, 16> Params;
|
||||
for (unsigned i = 0, e = FTI.NumArgs; i != e; ++i)
|
||||
Params.push_back(ParseParamDeclarator(D.getTypeObject(0), i, FnBodyScope));
|
||||
|
||||
FD->setParams(&Params[0], Params.size());
|
||||
|
||||
return FD;
|
||||
}
|
||||
|
|
|
@ -118,7 +118,12 @@ public:
|
|||
/// FunctionDecl - An instance of this class is created to represent a function
|
||||
/// declaration or definition.
|
||||
class FunctionDecl : public ObjectDecl {
|
||||
// FIXME: Args etc.
|
||||
/// ParamInfo - new[]'d array of pointers to VarDecls for the formal
|
||||
/// parameters of this function. This is null if a prototype or if there are
|
||||
/// no formals. TODO: we could allocate this space immediately after the
|
||||
/// FunctionDecl object to save an allocation like FunctionType does.
|
||||
VarDecl **ParamInfo;
|
||||
|
||||
Stmt *Body; // Null if a prototype.
|
||||
|
||||
/// DeclChain - Linked list of declarations that are defined inside this
|
||||
|
@ -126,7 +131,8 @@ class FunctionDecl : public ObjectDecl {
|
|||
Decl *DeclChain;
|
||||
public:
|
||||
FunctionDecl(IdentifierInfo *Id, TypeRef T, Decl *Next)
|
||||
: ObjectDecl(Function, Id, T, Next), Body(0), DeclChain(0) {}
|
||||
: ObjectDecl(Function, Id, T, Next), ParamInfo(0), Body(0), DeclChain(0) {}
|
||||
virtual ~FunctionDecl();
|
||||
|
||||
Stmt *getBody() const { return Body; }
|
||||
void setBody(Stmt *B) { Body = B; }
|
||||
|
@ -134,6 +140,9 @@ public:
|
|||
Decl *getDeclChain() const { return DeclChain; }
|
||||
void setDeclChain(Decl *D) { DeclChain = D; }
|
||||
|
||||
unsigned getNumParams() const;
|
||||
void setParams(VarDecl **NewParamInfo, unsigned NumParams);
|
||||
|
||||
// Implement isa/cast/dyncast/etc.
|
||||
static bool classof(const Decl *D) { return D->getKind() == Function; }
|
||||
static bool classof(const FunctionDecl *D) { return true; }
|
||||
|
|
|
@ -98,11 +98,11 @@ public:
|
|||
}
|
||||
|
||||
/// ParseStartOfFunctionDef - This is called at the start of a function
|
||||
/// definition, instead of calling ParseDeclarator.
|
||||
virtual DeclTy *ParseStartOfFunctionDef(Scope *S, Declarator &D
|
||||
/* TODO: FORMAL ARG INFO.*/) {
|
||||
/// definition, instead of calling ParseDeclarator. The Declarator includes
|
||||
/// information about formal arguments that are part of this function.
|
||||
virtual DeclTy *ParseStartOfFunctionDef(Scope *FnBodyScope, Declarator &D) {
|
||||
// Default to ParseDeclarator.
|
||||
return ParseDeclarator(S, D, 0, 0);
|
||||
return ParseDeclarator(FnBodyScope, D, 0, 0);
|
||||
}
|
||||
|
||||
/// ParseFunctionDefBody - This is called when a function body has completed
|
||||
|
|
|
@ -259,7 +259,6 @@ struct DeclaratorChunk {
|
|||
/// Parameter type lists will have type info (if the actions module provides
|
||||
/// it), but may have null identifier info: e.g. for 'void foo(int X, int)'.
|
||||
struct ParamInfo {
|
||||
/// Ident - In a K&R
|
||||
IdentifierInfo *Ident;
|
||||
SourceLocation IdentLoc;
|
||||
Action::TypeTy *TypeInfo;
|
||||
|
|
Loading…
Reference in New Issue