[cfe-dev] [AST] Function redeclaration: parameter decl isn't redecl of same parameter of redecl'd function
Whisperity via cfe-dev
cfe-dev at lists.llvm.org
Mon Aug 17 09:01:34 PDT 2020
Hey!
Suppose we have a rather trivial situation with a function prototype, a
usage, and then later a definition:
int foo(int x);
void bar() {
foo(0);
}
int foo(int x) { return x * 2; }
void baz() {
foo(1);
}
The following AST results:
|-FunctionDecl 0x55ae46421ca8 <a.cpp:1:1, col:14> col:5 used foo 'int (int)'
| `-ParmVarDecl 0x55ae46421bd0 <col:9, col:13> col:13 x 'int'
|-FunctionDecl 0x55ae46421df0 <line:2:1, col:23> col:6 bar 'void ()'
| `-CompoundStmt 0x55ae46421f90 <col:12, col:23>
| `-CallExpr 0x55ae46421f68 <col:16, col:21> 'int'
| |-ImplicitCastExpr 0x55ae46421f50 <col:16> 'int (*)(int)'
<FunctionToPointerDecay>
| | `-DeclRefExpr 0x55ae46421ef8 <col:16> 'int (int)' lvalue
Function 0x55ae46421ca8 'foo' 'int (int)'
| `-IntegerLiteral 0x55ae46421ed8 <col:20> 'int' 0
|-FunctionDecl 0x55ae46422058 prev 0x55ae46421ca8 <line:3:1, col:32>
col:5 used foo 'int (int)'
| |-ParmVarDecl 0x55ae46421fc0 <col:9, col:13> col:13 used x 'int'
| `-CompoundStmt 0x55ae46422188 <col:16, col:32>
| `-ReturnStmt 0x55ae46422178 <col:18, col:29>
| `-BinaryOperator 0x55ae46422158 <col:25, col:29> 'int' '*'
| |-ImplicitCastExpr 0x55ae46422140 <col:25> 'int' <LValueToRValue>
| | `-DeclRefExpr 0x55ae46422100 <col:25> 'int' lvalue ParmVar
0x55ae46421fc0 'x' 'int'
| `-IntegerLiteral 0x55ae46422120 <col:29> 'int' 2
`-FunctionDecl 0x55ae464221c0 <line:4:1, col:21> col:6 baz 'void ()'
`-CompoundStmt 0x55ae46422328 <col:12, col:21>
`-CallExpr 0x55ae46422300 <col:14, col:19> 'int'
|-ImplicitCastExpr 0x55ae464222e8 <col:14> 'int (*)(int)'
<FunctionToPointerDecay>
| `-DeclRefExpr 0x55ae464222c8 <col:14> 'int (int)' lvalue
Function 0x55ae46422058 'foo' 'int (int)'
`-IntegerLiteral 0x55ae464222a8 <col:18> 'int' 1
The FunctionDecl knows that it is a redeclaration of a previous Decl
(namely, the prototype). However, the two ParmVarDecls for int x do not
have this relationship: PVD->getCanonicalDecl() == PVD holds for both
instances, with no connection between. PVD->redecls() == {PVD}, too.
What is more interesting, is that querying the parameter to which the
CallExpr gives the argument to, by iterating the number of arguments and
doing cast<FunctionDecl>(CE->getCalledDecl())->getParamDecl(0), we will get
two separate ParmVarDecl instances, due to how the call before the
*definition* of *foo()* binds the prototype (and gives us the prototype’s
ParmVarDecl) but the call site *after* the called function has been defined
bind the *definition*.
Is this an intended behaviour?
Why isn’t the two ParmVarDecls not linked into a redecl chain, considering
they should mean the “same entity”, as it is the same parameter of a
redecl’d function?
I obviously mean once we are past overloads, past template instantiations,
etc. No “magic” should be intervening.
Or is it me who’s not grasping something from the language correctly?
Regards,
W.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20200817/d96fd9dd/attachment-0001.html>
More information about the cfe-dev
mailing list