forked from OSchip/llvm-project
First patch toward rewriting of method definitions. This is work in progress.
llvm-svn: 43915
This commit is contained in:
parent
94785aa1c7
commit
56ff146ec4
|
@ -1146,38 +1146,37 @@ Parser::StmtResult Parser::ParseObjCTryStmt(SourceLocation atLoc) {
|
|||
|
||||
/// objc-method-def: objc-method-proto ';'[opt] '{' body '}'
|
||||
///
|
||||
void Parser::ParseObjCInstanceMethodDefinition() {
|
||||
Parser::DeclTy *Parser::ParseObjCInstanceMethodDefinition() {
|
||||
assert(Tok.is(tok::minus) && "Method definitions should start with '-'");
|
||||
|
||||
DeclTy *MDecl = ParseObjCMethodPrototype(ObjcImpDecl);
|
||||
// FIXME: @optional/@protocol??
|
||||
AllImplMethods.push_back(ParseObjCMethodPrototype(ObjcImpDecl));
|
||||
AllImplMethods.push_back(MDecl);
|
||||
// parse optional ';'
|
||||
if (Tok.is(tok::semi))
|
||||
ConsumeToken();
|
||||
|
||||
if (Tok.isNot(tok::l_brace)) {
|
||||
Diag (Tok, diag::err_expected_lbrace);
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
StmtResult FnBody = ParseCompoundStatementBody();
|
||||
return ObjcParseFunctionDefinition(MDecl);
|
||||
}
|
||||
|
||||
/// objc-method-def: objc-method-proto ';'[opt] '{' body '}'
|
||||
///
|
||||
void Parser::ParseObjCClassMethodDefinition() {
|
||||
Parser::DeclTy *Parser::ParseObjCClassMethodDefinition() {
|
||||
assert(Tok.is(tok::plus) && "Class method definitions should start with '+'");
|
||||
DeclTy *MDecl = ParseObjCMethodPrototype(ObjcImpDecl);
|
||||
// FIXME: @optional/@protocol??
|
||||
AllImplMethods.push_back(ParseObjCMethodPrototype(ObjcImpDecl));
|
||||
AllImplMethods.push_back(MDecl);
|
||||
// parse optional ';'
|
||||
if (Tok.is(tok::semi))
|
||||
ConsumeToken();
|
||||
if (Tok.isNot(tok::l_brace)) {
|
||||
Diag (Tok, diag::err_expected_lbrace);
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
StmtResult FnBody = ParseCompoundStatementBody();
|
||||
return ObjcParseFunctionDefinition(MDecl);
|
||||
}
|
||||
|
||||
Parser::ExprResult Parser::ParseObjCAtExpression(SourceLocation AtLoc) {
|
||||
|
|
|
@ -331,7 +331,7 @@ Parser::DeclTy *Parser::ParseExternalDeclaration() {
|
|||
return ParseObjCAtDirectives();
|
||||
case tok::minus:
|
||||
if (getLang().ObjC1) {
|
||||
ParseObjCInstanceMethodDefinition();
|
||||
return ParseObjCInstanceMethodDefinition();
|
||||
} else {
|
||||
Diag(Tok, diag::err_expected_external_declaration);
|
||||
ConsumeToken();
|
||||
|
@ -339,7 +339,7 @@ Parser::DeclTy *Parser::ParseExternalDeclaration() {
|
|||
return 0;
|
||||
case tok::plus:
|
||||
if (getLang().ObjC1) {
|
||||
ParseObjCClassMethodDefinition();
|
||||
return ParseObjCClassMethodDefinition();
|
||||
} else {
|
||||
Diag(Tok, diag::err_expected_external_declaration);
|
||||
ConsumeToken();
|
||||
|
@ -465,6 +465,31 @@ Parser::DeclTy *Parser::ParseFunctionDefinition(Declarator &D) {
|
|||
return ParseFunctionStatementBody(Res, BraceLoc, BraceLoc);
|
||||
}
|
||||
|
||||
Parser::DeclTy *Parser::ObjcParseFunctionDefinition(DeclTy *D) {
|
||||
// We should have an opening brace now.
|
||||
if (Tok.isNot(tok::l_brace)) {
|
||||
Diag(Tok, diag::err_expected_fn_body);
|
||||
|
||||
// Skip over garbage, until we get to '{'. Don't eat the '{'.
|
||||
SkipUntil(tok::l_brace, true, true);
|
||||
|
||||
// If we didn't find the '{', bail out.
|
||||
if (Tok.isNot(tok::l_brace))
|
||||
return 0;
|
||||
}
|
||||
|
||||
SourceLocation BraceLoc = Tok.getLocation();
|
||||
|
||||
// Enter a scope for the function body.
|
||||
EnterScope(Scope::FnScope|Scope::DeclScope);
|
||||
|
||||
// Tell the actions module that we have entered a function definition with the
|
||||
// specified Declarator for the function.
|
||||
DeclTy *Res = Actions.ObjcActOnStartOfFunctionDef(CurScope, D);
|
||||
|
||||
return ParseFunctionStatementBody(Res, BraceLoc, BraceLoc);
|
||||
}
|
||||
|
||||
/// ParseKNRParamDeclarations - Parse 'declaration-list[opt]' which provides
|
||||
/// types for a function with a K&R-style identifier list for arguments.
|
||||
void Parser::ParseKNRParamDeclarations(Declarator &D) {
|
||||
|
|
|
@ -172,6 +172,9 @@ public:
|
|||
//
|
||||
QualType GetTypeForDeclarator(Declarator &D, Scope *S);
|
||||
|
||||
QualType ObjcGetTypeForDeclarator(DeclTy *D, Scope *S);
|
||||
|
||||
|
||||
virtual TypeResult ActOnTypeName(Scope *S, Declarator &D);
|
||||
|
||||
virtual TypeResult ActOnParamDeclaratorType(Scope *S, Declarator &D);
|
||||
|
@ -181,10 +184,12 @@ private:
|
|||
//
|
||||
virtual DeclTy *isTypeName(const IdentifierInfo &II, Scope *S) const;
|
||||
virtual DeclTy *ActOnDeclarator(Scope *S, Declarator &D, DeclTy *LastInGroup);
|
||||
virtual DeclTy *ObjcActOnDeclarator(Scope *S, DeclTy *D, DeclTy *LastInGroup);
|
||||
void AddInitializerToDecl(DeclTy *dcl, ExprTy *init);
|
||||
virtual DeclTy *FinalizeDeclaratorGroup(Scope *S, DeclTy *Group);
|
||||
|
||||
virtual DeclTy *ActOnStartOfFunctionDef(Scope *S, Declarator &D);
|
||||
virtual DeclTy *ObjcActOnStartOfFunctionDef(Scope *S, DeclTy *D);
|
||||
virtual DeclTy *ActOnFunctionDefBody(DeclTy *Decl, StmtTy *Body);
|
||||
|
||||
/// Scope actions.
|
||||
|
@ -226,6 +231,8 @@ private:
|
|||
/// More parsing and symbol table subroutines...
|
||||
ParmVarDecl *ParseParamDeclarator(DeclaratorChunk &FI, unsigned ArgNo,
|
||||
Scope *FnBodyScope);
|
||||
ParmVarDecl *ObjcParseParamDeclarator(ParmVarDecl *param, Scope *FnBodyScope);
|
||||
|
||||
ScopedDecl *LookupScopedDecl(IdentifierInfo *II, unsigned NSI,
|
||||
SourceLocation IdLoc, Scope *S);
|
||||
ScopedDecl *LookupInterfaceDecl(IdentifierInfo *II);
|
||||
|
|
|
@ -544,6 +544,42 @@ bool Sema::CheckInitializer(Expr *&Init, QualType &DeclType, bool isStatic) {
|
|||
return hadError;
|
||||
}
|
||||
|
||||
Sema::DeclTy *
|
||||
Sema::ObjcActOnDeclarator(Scope *S, DeclTy *D, DeclTy *lastDecl) {
|
||||
ObjcMethodDecl *MDecl = dyn_cast<ObjcMethodDecl>(static_cast<Decl *>(D));
|
||||
|
||||
ScopedDecl *LastDeclarator = dyn_cast_or_null<ScopedDecl>((Decl *)lastDecl);
|
||||
const char *name = MDecl->getSelector().getName().c_str();
|
||||
IdentifierInfo *II = &Context.Idents.get(name);
|
||||
assert (II && "ObjcActOnDeclarator - selector name is missing");
|
||||
|
||||
// The scope passed in may not be a decl scope. Zip up the scope tree until
|
||||
// we find one that is.
|
||||
while ((S->getFlags() & Scope::DeclScope) == 0)
|
||||
S = S->getParent();
|
||||
|
||||
ScopedDecl *New;
|
||||
QualType R = ObjcGetTypeForDeclarator(MDecl, S);
|
||||
assert(!R.isNull() && "ObjcGetTypeForDeclarator() returned null type");
|
||||
|
||||
FunctionDecl *NewFD = new FunctionDecl(MDecl->getLocation(), II, R,
|
||||
FunctionDecl::Static,
|
||||
false, LastDeclarator);
|
||||
New = NewFD;
|
||||
|
||||
// If this has an identifier, add it to the scope stack.
|
||||
if (II) {
|
||||
New->setNext(II->getFETokenInfo<ScopedDecl>());
|
||||
II->setFETokenInfo(New);
|
||||
S->AddDecl(New);
|
||||
}
|
||||
|
||||
if (S->getParent() == 0)
|
||||
AddTopLevelDecl(New, LastDeclarator);
|
||||
|
||||
return New;
|
||||
}
|
||||
|
||||
Sema::DeclTy *
|
||||
Sema::ActOnDeclarator(Scope *S, Declarator &D, DeclTy *lastDecl) {
|
||||
ScopedDecl *LastDeclarator = dyn_cast_or_null<ScopedDecl>((Decl *)lastDecl);
|
||||
|
@ -854,6 +890,63 @@ Sema::ParseParamDeclarator(DeclaratorChunk &FTI, unsigned ArgNo,
|
|||
return New;
|
||||
}
|
||||
|
||||
// Called from Sema::ObjcParseStartOfFunctionDef().
|
||||
ParmVarDecl *
|
||||
Sema::ObjcParseParamDeclarator(ParmVarDecl *PI, Scope *FnScope) {
|
||||
|
||||
IdentifierInfo *II = PI->getIdentifier();
|
||||
// TODO: CHECK FOR CONFLICTS, multiple decls with same name in one scope.
|
||||
// Can this happen for params? We already checked that they don't conflict
|
||||
// among each other. Here they can only shadow globals, which is ok.
|
||||
if (/*Decl *PrevDecl = */LookupScopedDecl(II, Decl::IDNS_Ordinary,
|
||||
PI->getLocation(), FnScope)) {
|
||||
|
||||
}
|
||||
|
||||
// FIXME: Handle storage class (auto, register). No declarator?
|
||||
// TODO: Chain to previous parameter with the prevdeclarator chain?
|
||||
|
||||
// Perform the default function/array conversion (C99 6.7.5.3p[7,8]).
|
||||
// Doing the promotion here has a win and a loss. The win is the type for
|
||||
// both Decl's and DeclRefExpr's will match (a convenient invariant for the
|
||||
// code generator). The loss is the orginal type isn't preserved. For example:
|
||||
//
|
||||
// void func(int parmvardecl[5]) { // convert "int [5]" to "int *"
|
||||
// int blockvardecl[5];
|
||||
// sizeof(parmvardecl); // size == 4
|
||||
// sizeof(blockvardecl); // size == 20
|
||||
// }
|
||||
//
|
||||
// For expressions, all implicit conversions are captured using the
|
||||
// ImplicitCastExpr AST node (we have no such mechanism for Decl's).
|
||||
//
|
||||
// FIXME: If a source translation tool needs to see the original type, then
|
||||
// we need to consider storing both types (in ParmVarDecl)...
|
||||
//
|
||||
QualType parmDeclType = PI->getType();
|
||||
if (const ArrayType *AT = parmDeclType->getAsArrayType())
|
||||
parmDeclType = Context.getPointerType(AT->getElementType());
|
||||
else if (parmDeclType->isFunctionType())
|
||||
parmDeclType = Context.getPointerType(parmDeclType);
|
||||
|
||||
ParmVarDecl *New = new ParmVarDecl(PI->getLocation(), II, parmDeclType,
|
||||
VarDecl::None, 0);
|
||||
// FIXME: need to check for invalid type.
|
||||
/**
|
||||
if (PI.InvalidType)
|
||||
New->setInvalidDecl();
|
||||
*/
|
||||
|
||||
// If this has an identifier, add it to the scope stack.
|
||||
if (II) {
|
||||
New->setNext(II->getFETokenInfo<ScopedDecl>());
|
||||
II->setFETokenInfo(New);
|
||||
FnScope->AddDecl(New);
|
||||
}
|
||||
|
||||
return New;
|
||||
}
|
||||
|
||||
|
||||
Sema::DeclTy *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Declarator &D) {
|
||||
assert(CurFunctionDecl == 0 && "Function parsing confused");
|
||||
|
@ -938,6 +1031,30 @@ Sema::DeclTy *Sema::ActOnFunctionDefBody(DeclTy *D, StmtTy *Body) {
|
|||
return FD;
|
||||
}
|
||||
|
||||
Sema::DeclTy *Sema::ObjcActOnStartOfFunctionDef(Scope *FnBodyScope, DeclTy *D) {
|
||||
assert(CurFunctionDecl == 0 && "Function parsing confused");
|
||||
ObjcMethodDecl *MDecl = dyn_cast<ObjcMethodDecl>(static_cast<Decl *>(D));
|
||||
|
||||
assert(MDecl != 0 && "Not a method declarator!");
|
||||
|
||||
Scope *GlobalScope = FnBodyScope->getParent();
|
||||
|
||||
FunctionDecl *FD =
|
||||
static_cast<FunctionDecl*>(ObjcActOnDeclarator(GlobalScope, D, 0));
|
||||
CurFunctionDecl = FD;
|
||||
|
||||
// Create Decl objects for each parameter, adding them to the FunctionDecl.
|
||||
llvm::SmallVector<ParmVarDecl*, 16> Params;
|
||||
|
||||
for (int i = 0; i < MDecl->getNumParams(); i++) {
|
||||
ParmVarDecl *PDecl = MDecl->getParamDecl(i);
|
||||
Params.push_back(ObjcParseParamDeclarator(PDecl, FnBodyScope));
|
||||
}
|
||||
|
||||
FD->setParams(&Params[0], Params.size());
|
||||
|
||||
return FD;
|
||||
}
|
||||
|
||||
/// ImplicitlyDefineFunction - An undeclared identifier was used in a function
|
||||
/// call, forming a call to an implicitly defined function (per C99 6.5.1p2).
|
||||
|
|
|
@ -325,6 +325,42 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S) {
|
|||
return T;
|
||||
}
|
||||
|
||||
/// GetTypeForDeclarator - Convert the type for the specified declarator to Type
|
||||
/// instances.
|
||||
QualType Sema::ObjcGetTypeForDeclarator(DeclTy *D, Scope *S) {
|
||||
ObjcMethodDecl *MDecl = dyn_cast<ObjcMethodDecl>(static_cast<Decl *>(D));
|
||||
QualType T = MDecl->getResultType();
|
||||
llvm::SmallVector<QualType, 16> ArgTys;
|
||||
|
||||
for (int i = 0; i < MDecl->getNumParams(); i++) {
|
||||
ParmVarDecl *PDecl = MDecl->getParamDecl(i);
|
||||
QualType ArgTy = PDecl->getType();
|
||||
assert(!ArgTy.isNull() && "Couldn't parse type?");
|
||||
//
|
||||
// Perform the default function/array conversion (C99 6.7.5.3p[7,8]).
|
||||
// This matches the conversion that is done in
|
||||
// Sema::ParseParamDeclarator(). Without this conversion, the
|
||||
// argument type in the function prototype *will not* match the
|
||||
// type in ParmVarDecl (which makes the code generator unhappy).
|
||||
//
|
||||
// FIXME: We still apparently need the conversion in
|
||||
// Sema::ParseParamDeclarator(). This doesn't make any sense, since
|
||||
// it should be driving off the type being created here.
|
||||
//
|
||||
// FIXME: If a source translation tool needs to see the original type,
|
||||
// then we need to consider storing both types somewhere...
|
||||
//
|
||||
if (const ArrayType *AT = ArgTy->getAsArrayType())
|
||||
ArgTy = Context.getPointerType(AT->getElementType());
|
||||
else if (ArgTy->isFunctionType())
|
||||
ArgTy = Context.getPointerType(ArgTy);
|
||||
ArgTys.push_back(ArgTy);
|
||||
}
|
||||
T = Context.getFunctionType(T, &ArgTys[0], ArgTys.size(),
|
||||
false);
|
||||
return T;
|
||||
}
|
||||
|
||||
Sema::TypeResult Sema::ActOnTypeName(Scope *S, Declarator &D) {
|
||||
// C99 6.7.6: Type names have no identifier. This is already validated by
|
||||
// the parser.
|
||||
|
|
|
@ -107,6 +107,9 @@ public:
|
|||
return 0;
|
||||
}
|
||||
|
||||
virtual DeclTy *ObjcActOnDeclarator(Scope *S, DeclTy *D,DeclTy *LastInGroup) {
|
||||
return 0;
|
||||
}
|
||||
/// AddInitializerToDecl - This action is called immediately after
|
||||
/// ParseDeclarator (when an initializer is present). The code is factored
|
||||
/// this way to make sure we are able to handle the following:
|
||||
|
@ -131,6 +134,11 @@ public:
|
|||
return ActOnDeclarator(FnBodyScope, D, 0);
|
||||
}
|
||||
|
||||
virtual DeclTy *ObjcActOnStartOfFunctionDef(Scope *FnBodyScope, DeclTy *D) {
|
||||
// Default to ActOnDeclarator.
|
||||
return ObjcActOnDeclarator(FnBodyScope, D, 0);
|
||||
}
|
||||
|
||||
/// ActOnFunctionDefBody - This is called when a function body has completed
|
||||
/// parsing. Decl is the DeclTy returned by ParseStartOfFunctionDef.
|
||||
virtual DeclTy *ActOnFunctionDefBody(DeclTy *Decl, StmtTy *Body) {
|
||||
|
|
|
@ -250,6 +250,7 @@ private:
|
|||
DeclTy *ParseExternalDeclaration();
|
||||
DeclTy *ParseDeclarationOrFunctionDefinition();
|
||||
DeclTy *ParseFunctionDefinition(Declarator &D);
|
||||
DeclTy *ObjcParseFunctionDefinition(DeclTy *D);
|
||||
void ParseKNRParamDeclarations(Declarator &D);
|
||||
void ParseSimpleAsm();
|
||||
void ParseAsmStringLiteral();
|
||||
|
@ -300,8 +301,8 @@ private:
|
|||
void ParseObjCPropertyAttribute(ObjcDeclSpec &DS);
|
||||
DeclTy *ParseObjCPropertyDecl(DeclTy *interfaceDecl, SourceLocation AtLoc);
|
||||
|
||||
void ParseObjCInstanceMethodDefinition();
|
||||
void ParseObjCClassMethodDefinition();
|
||||
DeclTy *ParseObjCInstanceMethodDefinition();
|
||||
DeclTy *ParseObjCClassMethodDefinition();
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// C99 6.5: Expressions.
|
||||
|
|
Loading…
Reference in New Issue