]> granicus.if.org Git - clang/commitdiff
Move the function/array conversion for ParmVarDecl's from Sema::ParseIdentifierExpr()
authorSteve Naroff <snaroff@apple.com>
Tue, 7 Aug 2007 22:44:21 +0000 (22:44 +0000)
committerSteve Naroff <snaroff@apple.com>
Tue, 7 Aug 2007 22:44:21 +0000 (22:44 +0000)
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
Sema/SemaExpr.cpp

index e052af82548214cac1000e12550c7c0e1821a5d1..31b612cc7b64c9b4761776f3c53b719bf4a153c1 100644 (file)
@@ -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.
index 05af3e0acecb8282b41cfc43a052678e972c37dd..22f8805b6b2a798fc74c900a7ebe79e4d48b8462 100644 (file)
@@ -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))