+// Build a set of fast lookup tables for a version script.
+
+void
+Version_script_info::build_lookup_tables()
+{
+ size_t size = this->version_trees_.size();
+ for (size_t j = 0; j < size; ++j)
+ {
+ const Version_tree* v = this->version_trees_[j];
+ this->build_expression_list_lookup(v->global, v, &this->globals_[0]);
+ this->build_expression_list_lookup(v->local, v, &this->locals_[0]);
+ }
+}
+
+// Build fast lookup information for EXPLIST and store it in LOOKUP.
+
+void
+Version_script_info::build_expression_list_lookup(
+ const Version_expression_list* explist,
+ const Version_tree* v,
+ Lookup** lookup)
+{
+ if (explist == NULL)
+ return;
+ size_t size = explist->expressions.size();
+ for (size_t j = 0; j < size; ++j)
+ {
+ const Version_expression& exp(explist->expressions[j]);
+ Lookup **pp = &lookup[exp.language];
+ if (*pp == NULL)
+ *pp = new Lookup();
+ Lookup* p = *pp;
+
+ if (!exp.exact_match && strpbrk(exp.pattern.c_str(), "?*[") != NULL)
+ p->globs.push_back(Glob(exp.pattern.c_str(), v));
+ else
+ {
+ std::pair<Exact::iterator, bool> ins =
+ p->exact.insert(std::make_pair(exp.pattern, v));
+ if (!ins.second)
+ {
+ const Version_tree* v1 = ins.first->second;
+ if (v1->tag != v->tag)
+ gold_error(_("'%s' appears in version script with both "
+ "versions '%s' and '%s'"),
+ exp.pattern.c_str(), v1->tag.c_str(),
+ v->tag.c_str());
+ }
+ }
+ }
+}
+