Move the function/array conversion for ParmVarDecl's from Sema::ParseIdentifierExpr()

to Sema::ParseParamDeclarator(). After discussing this with Chris, we decided this
approach has more immediate benefit (though we loose some information in the AST). 
The comment below should describe more (if interested).

llvm-svn: 40907
This commit is contained in:
Steve Naroff 2007-08-07 22:44:21 +00:00
parent a47f7d7cfd
commit 773df5cf30
2 changed files with 25 additions and 28 deletions

View File

@ -465,8 +465,31 @@ Sema::ParseParamDeclarator(DeclaratorChunk &FTI, unsigned ArgNo,
// FIXME: Handle storage class (auto, register). No declarator? // FIXME: Handle storage class (auto, register). No declarator?
// TODO: Chain to previous parameter with the prevdeclarator chain? // TODO: Chain to previous parameter with the prevdeclarator chain?
ParmVarDecl *New = new ParmVarDecl(PI.IdentLoc, II,
QualType::getFromOpaquePtr(PI.TypeInfo), // 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 = QualType::getFromOpaquePtr(PI.TypeInfo);
if (const ArrayType *AT = parmDeclType->getAsArrayType())
parmDeclType = Context.getPointerType(AT->getElementType());
else if (parmDeclType->isFunctionType())
parmDeclType = Context.getPointerType(parmDeclType);
ParmVarDecl *New = new ParmVarDecl(PI.IdentLoc, II, parmDeclType,
VarDecl::None, 0); VarDecl::None, 0);
// If this has an identifier, add it to the scope stack. // If this has an identifier, add it to the scope stack.

View File

@ -73,32 +73,6 @@ Sema::ExprResult Sema::ParseIdentifierExpr(Scope *S, SourceLocation Loc,
return Diag(Loc, diag::err_undeclared_var_use, II.getName()); return Diag(Loc, diag::err_undeclared_var_use, II.getName());
} }
} }
if (ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D)) {
// For ParmVarDecl's, we perform the default function/array conversion
// (C99 6.7.5.3p[7,8]).
QualType DeclRefType;
if (const ArrayType *AT = PD->getType()->getAsArrayType())
DeclRefType = Context.getPointerType(AT->getElementType());
else if (PD->getType()->isFunctionType())
DeclRefType = Context.getPointerType(PD->getType());
else
DeclRefType = PD->getType();
return new DeclRefExpr(PD, DeclRefType, Loc);
}
// The function/arrray conversion cannot be done for ValueDecl's in general.
// Consider this example:
//
// void func(int parmvardecl[5]) {
// int blockvardecl[5];
// sizeof(parmvardecl); // type is "int *" (converted from "int [5]")
// sizeof(blockvardecl); // type is "int [5]" (cannot convert to "int *")
// }
//
// If we converted blockvardecl (at this level) it would be be incorrect
// for the sizeof and address of (&) operators (see C99 6.3.2.1p[2-4]).
// This doesn't matter for parmvardecl, since arrays are always passed by
// reference (i.e. the [5] on parmvardecl is superfluous).
//
if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
return new DeclRefExpr(VD, VD->getType(), Loc); return new DeclRefExpr(VD, VD->getType(), Loc);
if (isa<TypedefDecl>(D)) if (isa<TypedefDecl>(D))