From 6a9f3e3dbc0ed9e883c475af342c0d1347469f55 Mon Sep 17 00:00:00 2001 From: Steve Naroff Date: Tue, 7 Aug 2007 22:44:21 +0000 Subject: [PATCH] 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). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@40907 91177308-0d34-0410-b5e6-96231b3b80d8 --- Sema/SemaDecl.cpp | 27 +++++++++++++++++++++++++-- Sema/SemaExpr.cpp | 26 -------------------------- 2 files changed, 25 insertions(+), 28 deletions(-) diff --git a/Sema/SemaDecl.cpp b/Sema/SemaDecl.cpp index e052af8254..31b612cc7b 100644 --- a/Sema/SemaDecl.cpp +++ b/Sema/SemaDecl.cpp @@ -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. diff --git a/Sema/SemaExpr.cpp b/Sema/SemaExpr.cpp index 05af3e0ace..22f8805b6b 100644 --- a/Sema/SemaExpr.cpp +++ b/Sema/SemaExpr.cpp @@ -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(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(D)) return new DeclRefExpr(VD, VD->getType(), Loc); if (isa(D)) -- 2.50.1