[cfe-commits] r43915 - in /cfe/trunk: Parse/ParseObjc.cpp Parse/Parser.cpp Sema/Sema.h Sema/SemaDecl.cpp Sema/SemaType.cpp include/clang/Parse/Action.h include/clang/Parse/Parser.h
Fariborz Jahanian
fjahanian at apple.com
Thu Nov 8 15:49:50 PST 2007
Author: fjahanian
Date: Thu Nov 8 17:49:49 2007
New Revision: 43915
URL: http://llvm.org/viewvc/llvm-project?rev=43915&view=rev
Log:
First patch toward rewriting of method definitions. This is work in progress.
Modified:
cfe/trunk/Parse/ParseObjc.cpp
cfe/trunk/Parse/Parser.cpp
cfe/trunk/Sema/Sema.h
cfe/trunk/Sema/SemaDecl.cpp
cfe/trunk/Sema/SemaType.cpp
cfe/trunk/include/clang/Parse/Action.h
cfe/trunk/include/clang/Parse/Parser.h
Modified: cfe/trunk/Parse/ParseObjc.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Parse/ParseObjc.cpp?rev=43915&r1=43914&r2=43915&view=diff
==============================================================================
--- cfe/trunk/Parse/ParseObjc.cpp (original)
+++ cfe/trunk/Parse/ParseObjc.cpp Thu Nov 8 17:49:49 2007
@@ -1146,38 +1146,37 @@
/// 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) {
Modified: cfe/trunk/Parse/Parser.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Parse/Parser.cpp?rev=43915&r1=43914&r2=43915&view=diff
==============================================================================
--- cfe/trunk/Parse/Parser.cpp (original)
+++ cfe/trunk/Parse/Parser.cpp Thu Nov 8 17:49:49 2007
@@ -331,7 +331,7 @@
return ParseObjCAtDirectives();
case tok::minus:
if (getLang().ObjC1) {
- ParseObjCInstanceMethodDefinition();
+ return ParseObjCInstanceMethodDefinition();
} else {
Diag(Tok, diag::err_expected_external_declaration);
ConsumeToken();
@@ -339,7 +339,7 @@
return 0;
case tok::plus:
if (getLang().ObjC1) {
- ParseObjCClassMethodDefinition();
+ return ParseObjCClassMethodDefinition();
} else {
Diag(Tok, diag::err_expected_external_declaration);
ConsumeToken();
@@ -465,6 +465,31 @@
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) {
Modified: cfe/trunk/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/Sema.h?rev=43915&r1=43914&r2=43915&view=diff
==============================================================================
--- cfe/trunk/Sema/Sema.h (original)
+++ cfe/trunk/Sema/Sema.h Thu Nov 8 17:49:49 2007
@@ -172,6 +172,9 @@
//
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 @@
//
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 @@
/// 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);
Modified: cfe/trunk/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/SemaDecl.cpp?rev=43915&r1=43914&r2=43915&view=diff
==============================================================================
--- cfe/trunk/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/Sema/SemaDecl.cpp Thu Nov 8 17:49:49 2007
@@ -545,6 +545,42 @@
}
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);
IdentifierInfo *II = D.getIdentifier();
@@ -853,7 +889,64 @@
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 @@
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).
Modified: cfe/trunk/Sema/SemaType.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/SemaType.cpp?rev=43915&r1=43914&r2=43915&view=diff
==============================================================================
--- cfe/trunk/Sema/SemaType.cpp (original)
+++ cfe/trunk/Sema/SemaType.cpp Thu Nov 8 17:49:49 2007
@@ -325,6 +325,42 @@
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.
Modified: cfe/trunk/include/clang/Parse/Action.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Action.h?rev=43915&r1=43914&r2=43915&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Action.h (original)
+++ cfe/trunk/include/clang/Parse/Action.h Thu Nov 8 17:49:49 2007
@@ -107,6 +107,9 @@
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 @@
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) {
Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=43915&r1=43914&r2=43915&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Thu Nov 8 17:49:49 2007
@@ -250,6 +250,7 @@
DeclTy *ParseExternalDeclaration();
DeclTy *ParseDeclarationOrFunctionDefinition();
DeclTy *ParseFunctionDefinition(Declarator &D);
+ DeclTy *ObjcParseFunctionDefinition(DeclTy *D);
void ParseKNRParamDeclarations(Declarator &D);
void ParseSimpleAsm();
void ParseAsmStringLiteral();
@@ -300,8 +301,8 @@
void ParseObjCPropertyAttribute(ObjcDeclSpec &DS);
DeclTy *ParseObjCPropertyDecl(DeclTy *interfaceDecl, SourceLocation AtLoc);
- void ParseObjCInstanceMethodDefinition();
- void ParseObjCClassMethodDefinition();
+ DeclTy *ParseObjCInstanceMethodDefinition();
+ DeclTy *ParseObjCClassMethodDefinition();
//===--------------------------------------------------------------------===//
// C99 6.5: Expressions.
More information about the cfe-commits
mailing list