[cfe-dev] Implicitly declared K&R parameters.

Enea Zaffanella zaffanella at cs.unipr.it
Wed Sep 29 05:11:04 PDT 2010


Hello.

Consider the following K&R function definition:

void foo(implicit, explicit)
   int explicit;
{}

While traversing the corresponding AST chunk, we would like to be able 
to distinguish between parameter 'explicit' (which was explicitly 
declared) from parameter 'implicit' (which was implicitly declared).

Is there a reliable way of distinguishing between the two cases?

First (failed) attempt:
Usually, implicit declarations are provided with an invalid source 
location, but this is false for the case at hand: the location of the 
identifier is obtained.

Second (failed) attempt:
Since 'implicit' has no type written, we also checked for an invalid 
getTypeSpecStartLoc(), but again we obtained a valid location, which is 
the same as that of the identifier. Here are the relevant source lines 
in SemaDecl.cpp:

   // Implicitly declare the argument as type 'int' for lack of a better
   // type.
   DeclSpec DS;
   const char* PrevSpec; // unused
   unsigned DiagID; // unused
   DS.SetTypeSpecType(DeclSpec::TST_int, FTI.ArgInfo[i].IdentLoc,
                      PrevSpec, DiagID);

Third (maybe working) attempt:
We ended up checking whether or not the two source locations mentioned 
above happen to be the same source location:

   bool implicit = (param.getLocation() == param.getTypeSpecStartLoc());

This was working as expected on the few tests we tried.
However, we would like to avoid making wild guesses: is such a property 
a valid (i.e., supported) clang invariant or is it just working by chance?

For clarity, would you accept the addition of a method

   bool ParmVarDecl::isImplicitIntKNRParameter() const {
     return getLocation() == getTypeSpecTypeLoc();
   }

?

Regards,
Enea.



More information about the cfe-dev mailing list