title: Implementing a symbol table for a compiler in C++
body: <p>I am currently developing a small compiler for a language for problem definitions. You can imagine a bastard child of Lisp and Prolog. Now, to the case:</p>
  
  <p><a href="https://en.wikipedia.org/wiki/Functor" rel="nofollow">Functor</a> is a base class from which 3 classes inherit: A,B,C.</p>
  
  <p>I made a lexer and parser with ANTLR3C, which gives me an AST tree. I traverse the tree and when I find a function of type A, I create an object of type A with the data from the tree, and a sym_register object to hold it:</p>
  
  <pre class="lang-c prettyprint-override"><code>#ifndef SYM_REGISTER_H
  #define SYM_REGISTER_H
  
  #include &lt;vector&gt;
  #include &lt;string&gt;
  
  enum class Symbol_type : int { T_A, T_B, T_C, T_D };
  
  class sym_register {
      public:
          std::string name;
          Symbol_type type;
          std::shared_ptr&lt;Functor&gt; declaration;
          std::vector &lt; InstancedFunctor &gt; result;
  
          sym_register(std::string n, Symbol_type t, std::shared_ptr&lt;Functor&gt; p){ 
              name = n; type = t; declaration = p;
          }   
  };
  
  #endif
  </code></pre>
  
  <p>The Symbol_type enum class gives me the info of what kind of object is std::shared_ptr declaration; pointing to, so I should be able to retrieve the full information of the object. </p>
  
  <p>This is how I store the symbols in my main Problem class:</p>
  
  <pre class="lang-c prettyprint-override"><code>class Problem {
      std::map&lt; std::string, std::shared_ptr&lt;sym_register&gt; &gt; sym_table;
  };
  </code></pre>
  
  <p>My problem is when I try to retrieve the symbols from the table, as I am not able to get the "declaration" attribute to its original class, I've tried using static_cast and reinterpret_cast with no results.</p>
  
  <p>So, here I have various questions:</p>
  
  <ol>
  <li>Is the "extra" information from the inherited classes lost when I store a pointer to an object of type A on a std::shared_ptr ?</li>
  <li>Should I go for a switch and an (unsafe) explicit conversion?</li>
  <li>Should I store pointers to NULL (a-la C) instead of std::shared_ptr ?</li>
  <li>What is the correct way to do it?</li>
  </ol>
  
  <p>EDIT: I basically want to be able to do:</p>
  
  <pre class="lang-c prettyprint-override"><code>std::shared_ptr&lt;A&gt; foo = Problem.getSymbol("objectWithTypeA"); 
  // and so on with the rest of the class hierarchy ...
  </code></pre>
  
  <p>EDIT2: The compilation errors are:</p>
  
  <pre><code>std::shared_ptr&lt;A&gt; foo = it.second-&gt;declaration; 
  // error: conversion from ‘std::shared_ptr&lt;Functor&gt;’ 
  // to non-scalar type ‘std::shared_ptr&lt;A&gt;’ requested
  
  std::shared_ptr&lt;A&gt; foo(reinterpret_cast&lt;std::shared_ptr&lt;A&gt; &gt;(it.second-&gt;declaration));
  // error: invalid cast from type ‘std::shared_ptr&lt;Functor&gt;’
  // to type ‘std::shared_ptr&lt;A&gt;’
  
  std::shared_ptr&lt;A&gt; foo(static_cast&lt;std::shared_ptr&lt;A&gt; &gt;(it.second-&gt;declaration));
  // error: no matching function for call to ‘std::shared_ptr&lt;A&gt;::shared_ptr(std::shared_ptr&lt;Functor&gt;&amp;)’
  // note: candidates are:
  // long list of template instantiations with a final
  // note:   no known conversion for argument 1 
  // from ‘std::shared_ptr&lt;Functor&gt;’ to ‘const std::shared_ptr&lt;A&gt;&amp;’
  
  std::shared_ptr&lt;A&gt; foo(static_cast&lt;A*&gt;(it.second-&gt;declaration));
  // error: invalid static_cast from type ‘std::shared_ptr&lt;Functor&gt;’ to type ‘A*’
  
  std::shared_ptr&lt;A&gt; foo(reinterpret_cast&lt;A*&gt;(it.second-&gt;declaration));
  // error: invalid cast from type ‘std::shared_ptr&lt;Functor&gt;’ to type ‘A*’
  </code></pre>