summaryrefslogtreecommitdiff
path: root/modules/CIAO/CIDLC/RepositoryIdGenerator.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'modules/CIAO/CIDLC/RepositoryIdGenerator.cpp')
-rw-r--r--modules/CIAO/CIDLC/RepositoryIdGenerator.cpp289
1 files changed, 289 insertions, 0 deletions
diff --git a/modules/CIAO/CIDLC/RepositoryIdGenerator.cpp b/modules/CIAO/CIDLC/RepositoryIdGenerator.cpp
new file mode 100644
index 00000000000..03a28ab8b7e
--- /dev/null
+++ b/modules/CIAO/CIDLC/RepositoryIdGenerator.cpp
@@ -0,0 +1,289 @@
+// file : CIDLC/RepositoryIdGenerator.cpp
+// author : Boris Kolpackov <boris@dre.vanderbilt.edu>
+// cvs-id : $Id$
+
+#include "RepositoryIdGenerator.hpp"
+#include "Literals.hpp"
+
+#include "CCF/CompilerElements/Diagnostic.hpp"
+#include "CCF/CIDL/Traversal.hpp"
+#include "CCF/CodeGenerationKit/Regex.hpp"
+
+using namespace CCF::CIDL;
+using namespace CCF::CIDL::SemanticGraph;
+using namespace StringLiterals;
+using namespace std;
+
+namespace
+{
+ Nameable* defined_in (Nameable& n)
+ {
+ for (Nameable::NamedIterator i (n.named_begin ()), e (n.named_end ());
+ i != e;
+ ++i)
+ {
+ if (Defines* d = dynamic_cast<Defines*> (*i))
+ {
+ return &d->scope ();
+ }
+ }
+
+ return 0;
+ }
+
+ void
+ compute_new_repo_id (Nameable& d)
+ {
+ string prefix ("");
+ TypePrefix *tp = 0;
+
+ if (d.context ().count (STRS[TYPE_PREFIX]))
+ {
+ tp = d.context ().get<TypePrefix*> (STRS[TYPE_PREFIX]);
+ prefix = tp->prefix ().literal ();
+ }
+ else
+ {
+ Nameable* parent = defined_in (d);
+
+ while (parent != 0)
+ {
+ if (parent->context ().count (STRS[TYPE_PREFIX]))
+ {
+ tp =
+ parent->context ().get<TypePrefix*> (STRS[TYPE_PREFIX]);
+
+ prefix = tp->prefix ().literal ();
+ break;
+ }
+
+ parent = defined_in (*parent);
+ }
+ }
+
+ if (prefix != "") prefix += "/";
+
+ ScopedName scoped (d.scoped_name ());
+ Name stripped (scoped.begin () + 1, scoped.end ());
+
+ string scope_name = regex::perl_s (stripped.unescaped_str (), "%::%/%");
+
+ string repo_id = "IDL:" + prefix + scope_name + ":1.0";
+
+ d.context ().set<string> (STRS[REPO_ID], repo_id);
+ }
+
+ void
+ compute_repo_id (Nameable& d)
+ {
+ if (d.context ().count (STRS[REPO_ID]))
+ {
+ return;
+ }
+ else
+ {
+ compute_new_repo_id (d);
+ }
+ }
+}
+
+namespace
+{
+ class TypeIdLabelGenerator : public Traversal::TypeId
+ {
+ public:
+ TypeIdLabelGenerator (Diagnostic::Stream& dout,
+ TranslationUnit& tu)
+ : dout_ (dout),
+ tu_ (tu)
+ {
+ }
+
+ virtual void
+ traverse (SemanticGraph::TypeId& ti)
+ {
+ ScopedName decl_name (ti.declaration ());
+ Nameables ref = tu_.lookup (decl_name);
+
+ for (Nameables::const_iterator iter (ref.begin ());
+ iter != ref.end ();
+ ++iter)
+ {
+ Nameable *decl = *iter;
+
+ if (decl->context ().count (STRS[TYPE_ID]))
+ {
+ //@@ Seems it should contain filename and line
+ // of its origin.
+ //
+ Diagnostic::Error err ("???", 0);
+
+ err << "repetition of typeid for " << decl_name
+ << " is illegal";
+
+ dout_ << err;
+
+ Diagnostic::Info inf ("???", 0);
+
+ err << "original typeid here";
+
+ dout_ << inf;
+ }
+ else
+ {
+ decl->context ().set (STRS[TYPE_ID], &ti);
+ decl->context ().set (STRS[REPO_ID], ti.id ().literal ());
+ }
+ }
+ }
+
+ private:
+ Diagnostic::Stream& dout_;
+ SemanticGraph::TranslationUnit& tu_;
+ };
+
+ class TypePrefixLabelGenerator : public Traversal::TypePrefix
+ {
+ public:
+ TypePrefixLabelGenerator (Diagnostic::Stream& dout,
+ TranslationUnit& tu)
+ : dout_ (dout),
+ tu_ (tu)
+ {
+ }
+
+ virtual void
+ traverse (SemanticGraph::TypePrefix& tp)
+ {
+ ScopedName decl_name (tp.declaration ());
+ Nameables ref = tu_.lookup (decl_name);
+
+ for (Nameables::const_iterator iter (ref.begin ());
+ iter != ref.end ();
+ ++iter)
+ {
+ Nameable *decl = *iter;
+ CCF::CompilerElements::Context& ctx = decl->context ();
+
+ if (ctx.count (STRS[TYPE_PREFIX]))
+ {
+ SemanticGraph::TypePrefix* prev =
+ ctx.get<SemanticGraph::TypePrefix*> (STRS[TYPE_PREFIX]);
+
+ if (prev->prefix () != tp.prefix ())
+ {
+ //@@ Seems tp should contain filename and line
+ // of it's origin.
+ //
+ Diagnostic::Error err ("???", 0);
+
+ err << "resetting type prefix for " << decl_name
+ << " is illegal";
+
+ dout_ << err;
+
+ Diagnostic::Info inf ("???", 0);
+
+ err << "original typeprefix here";
+
+ dout_ << inf;
+ }
+ }
+ else
+ {
+ decl->context ().set (STRS[TYPE_PREFIX], &tp);
+
+ // A typeprefix declaration could appear after the IDL
+ // type declaration, so we want to update the repo id
+ // every time.
+ compute_new_repo_id (*decl);
+ }
+ }
+ }
+
+ private:
+ Diagnostic::Stream& dout_;
+ SemanticGraph::TranslationUnit& tu_;
+ };
+
+ class RepoIdGenerator : public Traversal::Interface,
+ public Traversal::EventType,
+ public Traversal::Home,
+ public Traversal::Component
+ {
+ virtual void
+ traverse (SemanticGraph::Interface& i)
+ {
+ compute_repo_id (i);
+ }
+
+ virtual void
+ traverse (SemanticGraph::EventType& e)
+ {
+ compute_repo_id (e);
+ }
+
+ virtual void
+ traverse (SemanticGraph::Home& h)
+ {
+ compute_repo_id (h);
+ }
+
+ virtual void
+ traverse (SemanticGraph::Component& c)
+ {
+ compute_repo_id (c);
+ }
+ };
+}
+
+
+bool RepositoryIdGenerator::generate (TranslationUnit& u)
+{
+ Diagnostic::Stream dout;
+
+ TypeIdLabelGenerator type_id (dout, u);
+ TypePrefixLabelGenerator type_prefix (dout, u);
+ RepoIdGenerator repo_id;
+
+ Traversal::TranslationUnit unit;
+
+ Traversal::ContainsPrincipal contains_principal;
+ unit.edge_traverser (contains_principal);
+
+ Traversal::TranslationRegion region;
+ contains_principal.node_traverser (region);
+
+ Traversal::ContainsRoot contains_root;
+ Traversal::Includes includes;
+
+ region.edge_traverser (includes);
+ region.edge_traverser (contains_root);
+
+ Traversal::Root root;
+ includes.node_traverser (region);
+ contains_root.node_traverser (root);
+
+ Traversal::Defines defines;
+ root.edge_traverser (defines);
+
+ Traversal::Module module;
+
+ defines.node_traverser (module);
+ defines.node_traverser (type_id);
+ defines.node_traverser (type_prefix);
+ defines.node_traverser (repo_id);
+
+ module.edge_traverser (defines);
+
+ Traversal::Interface iface;
+ defines.node_traverser (iface);
+
+ unit.traverse (u);
+
+ if (dout.error_count () != 0) return false;
+
+ //@@ check errors
+
+ return true;
+}