]> sourceware.org Git - systemtap.git/commitdiff
2005-03-04 Frank Ch. Eigler <fche@redhat.com>
authorfche <fche>
Fri, 4 Mar 2005 20:10:09 +0000 (20:10 +0000)
committerfche <fche>
Fri, 4 Mar 2005 20:10:09 +0000 (20:10 +0000)
* parse.cxx (scan): Support '$' characters in identifiers.
(parse_symbol): Support thread-> / process-> shorthand.
* staptree.cxx (symresolution_info::find): Split up into
find_scalar, find_array, find_function.
(resolve_symbols): Call the above for symbol/arrayindex/functioncall.
(find_scalar): Add stub support for synthetic builtin variables.
* staptree.h: Corresponding changes.
* testsuite/*: Some new tests.

ChangeLog
parse.cxx
parse.h
staptree.cxx
staptree.h
testsuite/parseko/four.stp [new file with mode: 0755]
testsuite/parseok/three.stp [new file with mode: 0755]
testsuite/semok/six.stp [new file with mode: 0755]

index a03c482bc3e288708c144692cf638d7a2a3b5957..d87b69ddd3e259530510f82d4b41c891c6065f50 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2005-03-04  Frank Ch. Eigler  <fche@redhat.com>
+
+       * parse.cxx (scan): Support '$' characters in identifiers.
+       (parse_symbol): Support thread-> / process-> shorthand.
+       * staptree.cxx (symresolution_info::find): Split up into
+       find_scalar, find_array, find_function.
+       (resolve_symbols): Call the above for symbol/arrayindex/functioncall.
+       (find_scalar): Add stub support for synthetic builtin variables.
+       * staptree.h: Corresponding changes.
+       * testsuite/*: Some new tests.
+
 2005-03-03  Frank Ch. Eigler  <fche@redhat.com>
 
        * parse.cxx (parse_assignment): Assert lvalueness of left
index 41ec6fef9a3a6573fa34baac8b7a6d2214c20789..640c37152330e391156df7ca280a25d6731bf78c 100644 (file)
--- a/parse.cxx
+++ b/parse.cxx
@@ -157,7 +157,7 @@ lexer::scan ()
   if (isspace (c))
     goto skip;
 
-  else if (isalpha (c))
+  else if (isalpha (c) || c == '$')
     {
       n->type = tok_identifier;
       n->content = (char) c;
@@ -166,7 +166,7 @@ lexer::scan ()
          int c2 = input.peek ();
          if (! input)
            break;
-         if ((isalnum(c2) || c2 == '_'))
+         if ((isalnum(c2) || c2 == '_' || c2 == '$'))
            {
              n->content.push_back(c2);
              input_get ();
@@ -247,6 +247,7 @@ lexer::scan ()
           (c == '+' && c2 == '=') ||
           (c == '-' && c2 == '=') ||
           (c == ':' && c2 == ':') ||
+          (c == '-' && c2 == '>') ||
          false) // XXX: etc.
         n->content.push_back((char) input_get ());
 
@@ -947,8 +948,9 @@ parser::parse_value ()
 }
 
 
+// var, var[index], func(parms), thread->var, process->var
 expression*
-parser::parse_symbol () // var, var[index], func(parms)
+parser::parse_symbol () 
 {
   const token* t = next ();
   if (t->type != tok_identifier)
@@ -957,7 +959,34 @@ parser::parse_symbol () // var, var[index], func(parms)
   string name = t->content;
   
   t = peek ();
-  if (t && t->type == tok_operator && t->content == "[") // array
+  if (t && t->type == tok_operator && t->content == "->")
+    {
+      // shorthand for process- or thread-specific array element
+      // map "thread->VAR" to "VAR[$tid]",
+      // and "process->VAR" to "VAR[$pid]"
+      symbol* sym = new symbol;
+      if (name == "thread")
+        sym->name = "$tid";
+      else if (name == "process") 
+        sym->name = "$pid";
+      else 
+        throw parse_error ("expected 'thread->' or 'process->'");
+      struct token* t2prime = new token (*t2);
+      t2prime->content = sym->name;
+      sym->tok = t2prime;
+
+      next (); // swallow "->"
+      t = next ();
+      if (! (t->type == tok_identifier))
+        throw parse_error ("expected identifier");
+
+      struct arrayindex* ai = new arrayindex;
+      ai->tok = t;
+      ai->base = t->content;
+      ai->indexes.push_back (sym);
+      return ai;
+    }
+  else if (t && t->type == tok_operator && t->content == "[") // array
     {
       next ();
       struct arrayindex* ai = new arrayindex;
diff --git a/parse.h b/parse.h
index ddfb19c1a6f1f0d9619290e6ea77b4ca0c58c5df..c8008bc7738e0a91f83b7265c48fadef99594fdc 100644 (file)
--- a/parse.h
+++ b/parse.h
@@ -22,6 +22,7 @@ enum token_type
     tok_junk, tok_identifier, tok_operator, tok_string, tok_number 
   };
 
+
 struct token
 {
   source_loc location;
@@ -29,6 +30,7 @@ struct token
   std::string content;
 };
 
+
 std::ostream& operator << (std::ostream& o, const token& t);
 
 
index 8a4fc14839593229a1b1e226b74bc7bab2f70afd..2bbdea9fc78664f6c6ee4864307cd49669fef05a 100644 (file)
@@ -387,7 +387,7 @@ symbol::resolve_symbols (symresolution_info& r)
   if (referent)
     return;
 
-  vardecl* d = r.find (name);
+  vardecl* d = r.find_scalar (name);
   if (d)
     referent = d;
   else
@@ -398,7 +398,6 @@ symbol::resolve_symbols (symresolution_info& r)
       v->tok = tok;
       r.locals.push_back (v);
       referent = v;
-      // XXX: check for conflicting function name
     }
 }
 
@@ -412,7 +411,7 @@ arrayindex::resolve_symbols (symresolution_info& r)
   if (referent)
     return;
 
-  vardecl* d = r.find (base);
+  vardecl* d = r.find_array (base, indexes);
   if (d)
     referent = d;
   else
@@ -423,7 +422,6 @@ arrayindex::resolve_symbols (symresolution_info& r)
       v->tok = tok;
       r.locals.push_back (v);
       referent = v;
-      // XXX: check for conflicting function name
     }
 }
 
@@ -437,19 +435,7 @@ functioncall::resolve_symbols (symresolution_info& r)
   if (referent)
     return;
 
-  // find global functiondecl
-  functiondecl* d = 0;
-  for (unsigned j = 0; j < r.current_file->functions.size(); j++)
-    {
-      functiondecl* fd = r.current_file->functions[j];
-      if (fd->name == function)
-        {
-          d = fd;
-          break;
-        }
-    }
-  // XXX: check for conflicting variable name
-
+  functiondecl* d = r.find_function (function, args);
   if (d)
     referent = d;
   else
@@ -492,13 +478,32 @@ expr_statement::resolve_symbols (symresolution_info& r)
 
 
 vardecl* 
-symresolution_info::find (const string& name)
+symresolution_info::find_scalar (const string& name)
 {
   // search locals
   for (unsigned i=0; i<locals.size(); i++)
     if (locals[i]->name == name)
       return locals[i];
 
+  // search builtins that become locals
+  // XXX: need to invent a proper formalism for this
+  if (name == "$pid" || name == "$tid")
+    {
+      vardecl_builtin* vb = new vardecl_builtin;
+      vb->name = name;
+      vb->type = pe_long;
+
+      // XXX: need a better way to synthesize tokens
+      token* t = new token;
+      t->type = tok_identifier;
+      t->content = name;
+      t->location.file = "<builtin>";
+      vb->tok = t;
+
+      locals.push_back (vb);
+      return vb;
+    }
+
   // search function formal parameters (if any)
   if (current_function)
     {
@@ -513,9 +518,54 @@ symresolution_info::find (const string& name)
       return globals[i];
 
   return 0;
+  // XXX: add checking for conflicting array or function
 }
 
 
+vardecl* 
+symresolution_info::find_array (const string& name, 
+                                const vector<expression*>& indexes)
+{
+  // search locals
+  for (unsigned i=0; i<locals.size(); i++)
+    if (locals[i]->name == name)
+      return locals[i];
+
+  // search function formal parameters (if any)
+  if (current_function)
+    {
+      for (unsigned i=0; i<current_function->formal_args.size(); i++)
+        if (current_function->formal_args [i]->name == name)
+          return current_function->formal_args [i];
+    }
+
+  // search globals
+  for (unsigned i=0; i<globals.size(); i++)
+    if (globals[i]->name == name)
+      return globals[i];
+
+  return 0;
+  // XXX: add checking for conflicting scalar or function
+}
+
+
+functiondecl* 
+symresolution_info::find_function (const string& name,
+                                   const vector<expression*>& args)
+{
+  for (unsigned j = 0; j < current_file->functions.size(); j++)
+    {
+      functiondecl* fd = current_file->functions[j];
+      if (fd->name == name)
+        return fd;
+    }
+
+  return 0;
+  // XXX: add checking for conflicting variables
+}
+
+
+
 void
 symresolution_info::unresolved (const token* tok)
 {
index a95d9f0579eac8db9de438ff3beaf00644aadaba..b38221bc13ae67c537a53b1ee8bb128c05ddafb6 100644 (file)
@@ -209,7 +209,9 @@ struct symresolution_info
                       vector<stapfile*>& f,
                       stapfile* cfil);
 
-  vardecl* find (const string& name);
+  vardecl* find_scalar (const string& name);
+  vardecl* find_array (const string& name, const vector<expression*>&);
+  functiondecl* find_function (const string& name, const vector<expression*>&);
 
   void unresolved (const token* tok);
   unsigned num_unresolved;
@@ -257,6 +259,11 @@ struct vardecl: public symboldecl
 };
 
 
+struct vardecl_builtin: public vardecl
+{
+};
+
+
 struct block;
 struct functiondecl: public symboldecl
 {
diff --git a/testsuite/parseko/four.stp b/testsuite/parseko/four.stp
new file mode 100755 (executable)
index 0000000..ad77239
--- /dev/null
@@ -0,0 +1,5 @@
+#! semtest
+
+probe foo {
+  somethingawful->foo = 1;
+}
diff --git a/testsuite/parseok/three.stp b/testsuite/parseok/three.stp
new file mode 100755 (executable)
index 0000000..b2628d4
--- /dev/null
@@ -0,0 +1,7 @@
+#! parsetest
+
+probe kernel:systemcall("foo") 
+{
+  $a = a$a = a$a$ = 0;
+}
+
diff --git a/testsuite/semok/six.stp b/testsuite/semok/six.stp
new file mode 100755 (executable)
index 0000000..53d6950
--- /dev/null
@@ -0,0 +1,7 @@
+#! parsetest
+
+probe foo
+{
+ thread->bar = 4;
+ process->baz = "5";
+}
This page took 0.04601 seconds and 5 git commands to generate.