In the following example, the variable a defined in line 1 is hidden in the scope from line 5 to 9. The problem is thus to write a semantic patch that transforms only one of the two variables.

1. extern int a;
2.
3. void foo()
4. {
5.    {
6.        int a;
7.        a = bar() + 3;
8.       ...
9.     }
10.
11    a = bar1() + bar2();
12. }

Since we only want to distinguish between local and global, there is a simple solution using the local attribute.

@@
local idexpression x;
expression E;
@@

(
x = E
|
-a = E
+a = 12 // whatever change you want to make
)

A local idexpression metavariable only matches an identifier that is declared as a local variable. The | gives precedence to the first pattern, so the only assignments to a that will get transformed are the global ones.

We could also have a rule to find extern variables:

@r@
type T;
identifier a;
@@

extern T a;

And then in the rule above, we could have a metavariable declaration:

identifier r.a;

On the other hand, if you want all global variables, not just extern ones, then it is more complicated, because global declarations and local declarations look the same. You also can't use the local idexpression trick, because that is for expressions, and a variable name in a declaration is an identifier. In this case, you could first match the identifiers that are declared locally:

@locally@
type T;
identifier a;
position p;
@@

{
<...
 T a@p;
...>
}

TOCHECK: I'm also not sure whether that would match a function body. You might need another rule for variables that are declared at the top level of a program.

Then the global variables are the ones that match the following rule:

@globally@
type T;
identifier a;
position p!=locally.p;
@@

 T a@p;
 
global_local_var.txt · Last modified: 2009/10/29 16:47 by npalix
 
Except where otherwise noted, content on this wiki is licensed under the following license:CC Attribution-Noncommercial-Share Alike 3.0 Unported
Recent changes RSS feed Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki