summaryrefslogtreecommitdiffstats
path: root/clang/Sema/SemaDecl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/Sema/SemaDecl.cpp')
-rw-r--r--clang/Sema/SemaDecl.cpp27
1 files changed, 25 insertions, 2 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.
OpenPOWER on IntegriCloud