diff options
author | Steve Naroff <snaroff@apple.com> | 2007-08-07 22:44:21 +0000 |
---|---|---|
committer | Steve Naroff <snaroff@apple.com> | 2007-08-07 22:44:21 +0000 |
commit | 773df5cf30059f0562f54e0bc8d22d7bf810803f (patch) | |
tree | 126b2aaaf7403bdc6bd9b986ef9cd600c6efc271 | |
parent | a47f7d7cfdfea46afbb3200e012feed10b7db1fe (diff) | |
download | bcm5719-llvm-773df5cf30059f0562f54e0bc8d22d7bf810803f.tar.gz bcm5719-llvm-773df5cf30059f0562f54e0bc8d22d7bf810803f.zip |
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
-rw-r--r-- | clang/Sema/SemaDecl.cpp | 27 | ||||
-rw-r--r-- | clang/Sema/SemaExpr.cpp | 26 |
2 files changed, 25 insertions, 28 deletions
diff --git a/clang/Sema/SemaDecl.cpp b/clang/Sema/SemaDecl.cpp index e052af82548..31b612cc7b6 100644 --- a/clang/Sema/SemaDecl.cpp +++ b/clang/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/clang/Sema/SemaExpr.cpp b/clang/Sema/SemaExpr.cpp index 05af3e0acec..22f8805b6b2 100644 --- a/clang/Sema/SemaExpr.cpp +++ b/clang/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<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)) |