Beispiel #1
0
void generate_switch( FILE *file, struct function *f, int do_static )
{
	struct entry *r;

	if( f->options->also ) {
		fprintf(file,"/* %s has additional code from 'also' statement */\n",f->name->text);
		fprintf(file,"%s\n",f->options->also->text);
	}

	if( f->options->instead ) {
		fprintf(file,"/* %s generated instead of %s */\n\n",f->options->instead->name->text,f->name->text);
		generate_switch( file, f->options->instead, do_static );
		return;
	}

	if( f->options->switch_code ) {
		fprintf(file,"/* manual switch code for %s */\n\n",f->name->text);
		fprintf(file,"%s\n\n",f->options->switch_code->text);
		return;
	}

	for( r=f->options->entrys; r; r=r->next ) {
		generate_entry(file,f,pattern_complete(r->name->text,f->name->text));
	}
}
void generate(const std::string& source_executable, std::ostream& o) {
  o << "#include <string>\n";
  o << "#include <unordered_map>\n\n";

  o << "extern \"C\" {\n\n"
    << "auto " << HPHP::detail::kMemberReflectionTableName << " =\n"
       "  std::unordered_map<\n"
       "    std::string,\n"
       "    const char*(*)(const void*, const void*)\n"
       "  >\n"
       "{\n";

  if (actually_run) {
    auto reflectables = std::unordered_set<std::string> {
#define X(name) "HPHP::"#name,
      HPHP_REFLECTABLES
#undef X
    };

    auto const parser = TypeParser::make(source_executable);
    auto first = true;

    for (auto const& type : parser->getAllObjects()) {
      if (type.incomplete) continue;
      if (type.name.linkage != ObjectTypeName::Linkage::external) continue;

      // Assume the first, complete, external definition is the canonical one.
      if (!reflectables.count(type.name.name)) continue;
      reflectables.erase(type.name.name);

      if (first) {
        first = false;
      } else {
        o << ",\n";
      }
      generate_entry(parser->getObject(type.key), o, parser);
    }
  }

  o << "\n};\n\n";
  o << "}";
}
Beispiel #3
0
address InterpreterGenerator::generate_normal_entry(bool synchronized) {
  assert(synchronized == false, "should be");

  return generate_entry((address) CppInterpreter::normal_entry);
}
Beispiel #4
0
address InterpreterGenerator::generate_accessor_entry() {
  if (!UseFastAccessorMethods)
    return NULL;

  return generate_entry((address) CppInterpreter::accessor_entry);
}
Beispiel #5
0
address InterpreterGenerator::generate_empty_entry() {
  if (!UseFastEmptyMethods)
    return NULL;

  return generate_entry((address) CppInterpreter::empty_entry);
}
Beispiel #6
0
//
// Generate indexes using our own internal method:
//
void generate_indexes()
{
   for(boost::tiny_xml::element_list::const_iterator i = indexes.begin(); i != indexes.end(); ++i)
   {
      boost::tiny_xml::element_ptr node = *i;
      const std::string* category = find_attr(node, "type");
      bool has_title = false;

      for(boost::tiny_xml::element_list::const_iterator k = (*i)->elements.begin(); k != (*i)->elements.end(); ++k)
      {
         if((**k).name == "title")
         {
            has_title = true;
            break;
         }
      }

      boost::tiny_xml::element_ptr navbar = make_element("para");
      node->elements.push_back(navbar);

      index_entry_set::const_iterator m = index_entries.begin();
      index_entry_set::const_iterator n = m;
      boost::tiny_xml::element_ptr vlist = make_element("variablelist");
      node->elements.push_back(vlist);
      while(n != index_entries.end())
      {
         char current_letter = std::toupper((*n)->key[0]);
         std::string id_name = get_next_index_id();
         boost::tiny_xml::element_ptr entry = add_attribute(make_element("varlistentry"), "id", id_name);
         boost::tiny_xml::element_ptr term = make_element("term");
         term->content = std::string(1, current_letter);
         entry->elements.push_back(term);
         boost::tiny_xml::element_ptr item = make_element("listitem");
         entry->elements.push_back(item);
         while((n != index_entries.end()) && (std::toupper((*n)->key[0]) == current_letter))
            ++n;
         std::pair<index_entry_set::const_iterator, index_entry_set::const_iterator> range(m, n);
         item->elements.push_back(generate_entry(range, category));
         if(item->elements.size() && (*item->elements.begin())->elements.size())
         {
            vlist->elements.push_back(entry);
            boost::tiny_xml::element_ptr p = make_element("");
            p->content = " ";
            if(navbar->elements.size())
            {
               navbar->elements.push_back(p);
            }
            p = add_attribute(make_element("link"), "linkend", id_name);
            p->content = current_letter;
            navbar->elements.push_back(p);
         }
         m = n;
      }

      node->name = internal_index_type;
      boost::tiny_xml::element_ptr p(node->parent);
      while(p->name.empty())
         p = boost::tiny_xml::element_ptr(p->parent);
      check_index_type_and_placement(p->name, node->name);
      node->attributes.clear();
      if(!has_title)
      {
         boost::tiny_xml::element_ptr t = make_element("title");
         t->content = "Index";
         node->elements.push_front(t);
      }
   }
}
Beispiel #7
0
boost::tiny_xml::element_ptr generate_entry(const Range& range, const std::string* pcategory, int level = 0, const boost::regex* primary_key = 0)
{
   boost::tiny_xml::element_ptr list = add_attribute(add_attribute(::add_attribute(make_element("itemizedlist"), "mark", "none"), "spacing", "compact"), "role", "index");

   for(typename boost::range_iterator<Range>::type i = boost::begin(range); i != boost::end(range);)
   {
      std::string key = (*i)->key;
      index_entry_set entries;
      bool preferred = false;
      std::string id;
      bool collapse = false;
      
      //
      // Create a regular expression for comparing key to other key's:
      //
      boost::regex key_regex;
      if(level == 0)
      {
         key_regex = make_primary_key_matcher(key);
         primary_key = &key_regex;
      }
      //
      // Begin by consolidating entries with identical keys but possibly different categories:
      //
      while((i != boost::end(range)) && ((*i)->key == key))
      {
         if((0 == pcategory) || (pcategory->size() == 0) || (pcategory && (**i).category == *pcategory))
         {
            entries.insert((*i)->sub_keys.begin(), (*i)->sub_keys.end());
            if((*i)->preferred)
               preferred = true;
            if((*i)->id.size())
            {
               if(id.size())
               {
                  std::cerr << "WARNING: two identical index terms have different link destinations!!" << std::endl;
               }
               id = (*i)->id;
            }
         }
         ++i;
      }
      //
      // Only actually generate content if we have anything in the entries set:
      //
      if(entries.size() || id.size())
      {
         //
         // See if we can collapse any sub-entries into this one:
         //
         if(entries.size() == 1)
         {
            if((regex_match((*entries.begin())->key, *primary_key) || ((*entries.begin())->key == key)) 
               && ((*entries.begin())->id.size()) 
               && ((*entries.begin())->id != id))
            {
               collapse = true;
               id = (*entries.begin())->id;
            }
         }
         //
         // See if this key is the same as the primary key, if it is then make it prefered:
         //
         if(level && regex_match(key, *primary_key))
         {
            preferred = true;
         }
         boost::tiny_xml::element_ptr item = make_element("listitem");
         boost::tiny_xml::element_ptr para = make_element("para");
         item->elements.push_back(para);
         list->elements.push_back(item);
         if(preferred)
         {
            para->elements.push_back(make_element("emphasis"));
            para = para->elements.back();
         }
         if(id.size())
         {
            boost::tiny_xml::element_ptr link = add_attribute(make_element("link"), "linkend", id);
            para->elements.push_back(link);
            para = link;
         }
         std::string classname = (boost::format("index-entry-level-%1%") % level).str();
         para->elements.push_back(add_attribute(make_element("phrase"), "role", classname));
         para = para->elements.back();
         para->content = key;
         if(!collapse && entries.size())
         {
            std::pair<index_entry_set::const_iterator, index_entry_set::const_iterator> subrange(entries.begin(), entries.end());
            item->elements.push_back(generate_entry(subrange, 0, level+1, primary_key));
         }
      }
   }
   return list;
}
address InterpreterGenerator::generate_normal_entry(bool synchronized) {
  return generate_entry((address) CppInterpreter::normal_entry);
}