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:
parent
a47f7d7cfd
commit
773df5cf30
|
|
@ -465,8 +465,31 @@ Sema::ParseParamDeclarator(DeclaratorChunk &FTI, unsigned ArgNo,
|
|||
|
||||
// FIXME: Handle storage class (auto, register). No declarator?
|
||||
// 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);
|
||||
|
||||
// If this has an identifier, add it to the scope stack.
|
||||
|
|
|
|||
|
|
@ -73,32 +73,6 @@ Sema::ExprResult Sema::ParseIdentifierExpr(Scope *S, SourceLocation Loc,
|
|||
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))
|
||||
return new DeclRefExpr(VD, VD->getType(), Loc);
|
||||
if (isa<TypedefDecl>(D))
|
||||
|
|
|
|||
Loading…
Reference in New Issue