A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
print-introspected-doxygen.cc
Go to the documentation of this file.
1 #include <iostream>
2 #include <algorithm>
3 #include <map>
4 
5 #include "ns3/object.h"
6 #include "ns3/pointer.h"
7 #include "ns3/object-vector.h"
8 #include "ns3/config.h"
9 #include "ns3/log.h"
10 #include "ns3/global-value.h"
11 #include "ns3/string.h"
12 #include "ns3/node-container.h"
13 #include "ns3/csma-channel.h"
14 
15 using namespace ns3;
16 
17 NS_LOG_COMPONENT_DEFINE ("PrintIntrospectedDoxygen");
18 
19 namespace
20 {
21  std::string anchor;
22  std::string boldStart;
23  std::string boldStop;
24  std::string breakBoth;
25  std::string breakHtmlOnly;
26  std::string breakTextOnly;
27  std::string brief;
28  std::string commentStart;
29  std::string commentStop;
36  std::string flagSpanStart;
37  std::string flagSpanStop;
38  std::string functionStart;
39  std::string functionStop;
40  std::string headingStart;
41  std::string headingStop;
42  std::string indentHtmlOnly;
43  std::string ingroupConstructs;
44  std::string listStart;
45  std::string listStop;
46  std::string listLineStart;
47  std::string listLineStop;
48  std::string reference;
49  std::string temporaryCharacter;
50 
51 } // anonymous namespace
52 
53 void
54 PrintAttributes (TypeId tid, std::ostream &os)
55 {
56  os << listStart << std::endl;
57  for (uint32_t j = 0; j < tid.GetAttributeN (); j++)
58  {
59  struct TypeId::AttributeInformation info = tid.GetAttribute(j);
60  os << listLineStart << boldStart << info.name << boldStop << ": "
61  << info.help << std::endl;
62  os << " " << listStart << std::endl
63  << " " << listLineStart << "Set with class: " << reference << info.checker->GetValueTypeName () << listLineStop << std::endl;
64  if (info.checker->HasUnderlyingTypeInformation ())
65  {
66  os << " " << listLineStart << "Underlying type: ";
67  if ( (info.checker->GetValueTypeName () != "ns3::EnumValue")
68  && (info.checker->GetUnderlyingTypeInformation () != "std::string")
69  )
70  {
71  os << reference;
72  }
73  os << info.checker->GetUnderlyingTypeInformation () << listLineStop << std::endl;
74  }
75  if (info.flags & TypeId::ATTR_CONSTRUCT && info.accessor->HasSetter ())
76  {
77  os << " " << listLineStart << "Initial value: " << info.initialValue->SerializeToString (info.checker) << listLineStop << std::endl;
78  }
79  os << " " << listLineStart << "Flags: ";
80  if (info.flags & TypeId::ATTR_CONSTRUCT && info.accessor->HasSetter ())
81  {
82  os << flagSpanStart << "construct " << flagSpanStop;
83  }
84  if (info.flags & TypeId::ATTR_SET && info.accessor->HasSetter ())
85  {
86  os << flagSpanStart << "write " << flagSpanStop;
87  }
88  if (info.flags & TypeId::ATTR_GET && info.accessor->HasGetter ())
89  {
90  os << flagSpanStart << "read " << flagSpanStop;
91  }
92  os << listLineStop << std::endl;
93  os << " " << listStop << " " << std::endl;
94 
95  }
96  os << listStop << std::endl;
97 }
98 
99 void
100 PrintTraceSources (TypeId tid, std::ostream &os)
101 {
102  os << listStart << std::endl;
103  for (uint32_t i = 0; i < tid.GetTraceSourceN (); ++i)
104  {
105  struct TypeId::TraceSourceInformation info = tid.GetTraceSource (i);
106  os << listLineStart << boldStart << info.name << boldStop << ": "
107  << info.help
108  << std::endl;
109  os << listLineStop << std::endl;
110  }
111  os << listStop << std::endl;
112 }
113 
114 
119 {
120 public:
127  void RecordAggregationInfo (std::string a, std::string b);
133  void Gather (TypeId tid);
137  void Print (void) const;
138 
144  std::vector<std::string> Get (TypeId tid);
145 
146 private:
150  std::string GetCurrentPath (void) const;
156  void DoGather (TypeId tid);
162  void RecordOutput (TypeId tid);
168  bool HasAlreadyBeenProcessed (TypeId tid) const;
176  void find_and_replace (std::string &source, const std::string find, std::string replace );
180  std::vector<std::pair<TypeId,std::string> > m_output;
184  std::vector<std::string> m_currentPath;
188  std::vector<TypeId> m_alreadyProcessed;
192  std::vector<std::pair<TypeId,TypeId> > m_aggregates;
193 };
194 
195 void
196 StaticInformation::RecordAggregationInfo (std::string a, std::string b)
197 {
198  m_aggregates.push_back (std::make_pair (TypeId::LookupByName (a), TypeId::LookupByName (b)));
199 }
200 
201 void
203 {
204  for (std::vector<std::pair<TypeId,std::string> >::const_iterator i = m_output.begin (); i != m_output.end (); ++i)
205  {
206  std::pair<TypeId,std::string> item = *i;
207  std::cout << item.first.GetName () << " -> " << item.second << std::endl;
208  }
209 }
210 
211 std::string
213 {
214  std::ostringstream oss;
215  for (std::vector<std::string>::const_iterator i = m_currentPath.begin (); i != m_currentPath.end (); ++i)
216  {
217  std::string item = *i;
218  oss << "/" << item;
219  }
220  return oss.str ();
221 }
222 
223 void
225 {
226  m_output.push_back (std::make_pair (tid, GetCurrentPath ()));
227 }
228 
229 bool
231 {
232  for (uint32_t i = 0; i < m_alreadyProcessed.size (); ++i)
233  {
234  if (m_alreadyProcessed[i] == tid)
235  {
236  return true;
237  }
238  }
239  return false;
240 }
241 
242 std::vector<std::string>
244 {
245  std::vector<std::string> paths;
246  for (uint32_t i = 0; i < m_output.size (); ++i)
247  {
248  std::pair<TypeId,std::string> tmp = m_output[i];
249  if (tmp.first == tid)
250  {
251  paths.push_back (tmp.second);
252  }
253  }
254  return paths;
255 }
256 
257 void
259 {
260  DoGather (tid);
261 
262  std::sort (m_output.begin (), m_output.end ());
263  m_output.erase (std::unique (m_output.begin (), m_output.end ()), m_output.end ());
264 }
265 
266 void
268 {
269  NS_LOG_FUNCTION (this);
270  if (HasAlreadyBeenProcessed (tid))
271  {
272  return;
273  }
274  RecordOutput (tid);
275  for (uint32_t i = 0; i < tid.GetAttributeN (); ++i)
276  {
277  struct TypeId::AttributeInformation info = tid.GetAttribute(i);
278  const PointerChecker *ptrChecker = dynamic_cast<const PointerChecker *> (PeekPointer (info.checker));
279  if (ptrChecker != 0)
280  {
281  TypeId pointee = ptrChecker->GetPointeeTypeId ();
282 
283  // See if this is a pointer to an Object.
284  Ptr<Object> object = CreateObject<Object> ();
285  TypeId objectTypeId = object->GetTypeId ();
286  if (objectTypeId == pointee)
287  {
288  // Stop the recursion at this attribute if it is a
289  // pointer to an Object, which create too many spurious
290  // paths in the list of attribute paths because any
291  // Object can be in that part of the path.
292  continue;
293  }
294 
295  m_currentPath.push_back (info.name);
296  m_alreadyProcessed.push_back (tid);
297  DoGather (pointee);
298  m_alreadyProcessed.pop_back ();
299  m_currentPath.pop_back ();
300  continue;
301  }
302  // attempt to cast to an object vector.
303  const ObjectPtrContainerChecker *vectorChecker = dynamic_cast<const ObjectPtrContainerChecker *> (PeekPointer (info.checker));
304  if (vectorChecker != 0)
305  {
306  TypeId item = vectorChecker->GetItemTypeId ();
307  m_currentPath.push_back (info.name + "/[i]");
308  m_alreadyProcessed.push_back (tid);
309  DoGather (item);
310  m_alreadyProcessed.pop_back ();
311  m_currentPath.pop_back ();
312  continue;
313  }
314  }
315  for (uint32_t j = 0; j < TypeId::GetRegisteredN (); j++)
316  {
317  TypeId child = TypeId::GetRegistered (j);
318  if (child.IsChildOf (tid))
319  {
320  //please take a look at the following note for an explanation
321  std::string childName = "$" + temporaryCharacter + child.GetName ();
322  std::string replaceWith = "::" + temporaryCharacter;
323  find_and_replace(childName,"::",replaceWith);
324  m_currentPath.push_back (childName);
325  m_alreadyProcessed.push_back (tid);
326  DoGather (child);
327  m_alreadyProcessed.pop_back ();
328  m_currentPath.pop_back ();
329  }
330  }
331  for (uint32_t k = 0; k < m_aggregates.size (); ++k)
332  {
333  std::pair<TypeId,TypeId> tmp = m_aggregates[k];
334  if (tmp.first == tid || tmp.second == tid)
335  {
336  TypeId other;
337  if (tmp.first == tid)
338  {
339  other = tmp.second;
340  }
341  if (tmp.second == tid)
342  {
343  other = tmp.first;
344  }
356  std::string name = "$" + temporaryCharacter + other.GetName ();
357  //finding and replacing :: by ::% (for Doxygen version only).
358  std::string replaceWith = "::" + temporaryCharacter;
359  find_and_replace(name,"::",replaceWith);
360  m_currentPath.push_back (name);
361  m_alreadyProcessed.push_back (tid);
362  DoGather (other);
363  m_alreadyProcessed.pop_back ();
364  m_currentPath.pop_back ();
365  }
366  }
367 }
368 
369 void
370 StaticInformation::find_and_replace( std::string &source, const std::string find, std::string replace )
371 {
372  size_t j;
373  j = source.find (find);
374  while (j != std::string::npos )
375  {
376  source.replace (j, find.length (),replace);
377  j = source.find (find,j+1);
378  }
379 }
380 
381 void
382 PrintHelp (const char *program_name)
383 {
384  std::cout << "Usage: " << program_name << " [options]" << std::endl
385  << std::endl
386  << "Options:" << std::endl
387  << " --help : print these options" << std::endl
388  << " --output-text : format output as plain text" << std::endl;
389 }
390 
391 int main (int argc, char *argv[])
392 {
393  bool outputText = false;
394  char *programName = argv[0];
395 
396  argv++;
397 
398  while (*argv != 0)
399  {
400  char *arg = *argv;
401 
402  if (strcmp (arg, "--help") == 0)
403  {
404  PrintHelp (programName);
405  return 0;
406  }
407  else if (strcmp(arg, "--output-text") == 0)
408  {
409  outputText = true;
410  }
411  else
412  {
413  // un-recognized command-line argument
414  PrintHelp (programName);
415  return 0;
416  }
417  argv++;
418  }
419 
420  if (outputText)
421  {
422  anchor = "";
423  boldStart = "";
424  boldStop = "";
425  breakBoth = "\n";
426  breakHtmlOnly = "";
427  breakTextOnly = "\n";
428  brief = "";
429  commentStart = "===============================================================\n";
430  commentStop = "";
437  flagSpanStart = "";
438  flagSpanStop = "";
439  functionStart = "";
440  functionStop = "\n\n";
441  headingStart = "";
442  headingStop = "";
443  indentHtmlOnly = "";
444  ingroupConstructs = "";
445  listStart = "";
446  listStop = "";
447  listLineStart = " * ";
448  listLineStop = "";
449  reference = "";
450  temporaryCharacter = "";
451  }
452  else
453  {
454  anchor = "\\anchor ";
455  boldStart = "<b>";
456  boldStop = "</b>";
457  breakBoth = "<br>";
458  breakHtmlOnly = "<br>";
459  breakTextOnly = "";
460  brief = "\\brief ";
461  commentStart = "/*!";
462  commentStop = "*/";
463  defgroupAttributeListStart = "\\defgroup AttributeList ";
465  defgroupGlobalValueListStart = "\\defgroup GlobalValueList ";
467  defgroupTraceSourceListStart = "\\defgroup TraceSourceList ";
469  flagSpanStart = "<span class=\"mlabel\">";
470  flagSpanStop = "</span>";
471  functionStart = "\\class ";
472  functionStop = "";
473  headingStart = "<h3>";
474  headingStop = "</h3>";
475  indentHtmlOnly = " ";
476  ingroupConstructs = "\\ingroup constructs\n";
477  listStart = "<ul>";
478  listStop = "</ul>";
479  listLineStart = "<li>";
480  listLineStop = "</li>";
481  reference = "\\ref ";
482  temporaryCharacter = "%";
483  }
484 
485  NodeContainer c; c.Create (1);
486 
487  // The below statements register typical aggregation relationships
488  // in ns-3 programs, that otherwise aren't picked up automatically
489  // by the creation of the above node. To manually list other common
490  // aggregation relationships that you would like to see show up in
491  // the list of configuration paths in the doxygen, add additional
492  // statements below.
493  StaticInformation info;
494  info.RecordAggregationInfo ("ns3::Node", "ns3::TcpSocketFactory");
495  info.RecordAggregationInfo ("ns3::Node", "ns3::UdpSocketFactory");
496  info.RecordAggregationInfo ("ns3::Node", "ns3::PacketSocketFactory");
497  info.RecordAggregationInfo ("ns3::Node", "ns3::olsr::RoutingProtocol");
498  info.RecordAggregationInfo ("ns3::Node", "ns3::MobilityModel");
499  info.RecordAggregationInfo ("ns3::Node", "ns3::Ipv4L3Protocol");
500  info.RecordAggregationInfo ("ns3::Node", "ns3::ArpL3Protocol");
501  info.RecordAggregationInfo ("ns3::Node", "ns3::Icmpv4L4Protocol");
502  info.RecordAggregationInfo ("ns3::Node", "ns3::UdpL4Protocol");
503  info.RecordAggregationInfo ("ns3::Node", "ns3::Ipv6L3Protocol");
504  info.RecordAggregationInfo ("ns3::Node", "ns3::Icmpv6L4Protocol");
505  info.RecordAggregationInfo ("ns3::Node", "ns3::TcpL4Protocol");
506 
507  // Create a channel object so that channels appear in the namespace
508  // paths that will be generated here.
509  Ptr<CsmaChannel> csma;
510  csma = CreateObject<CsmaChannel> ();
511 
512  for (uint32_t i = 0; i < Config::GetRootNamespaceObjectN (); ++i)
513  {
515  info.Gather (object->GetInstanceTypeId ());
516  }
517 
518  std::map< std::string, uint32_t> nameMap;
519  std::map< std::string, uint32_t>::const_iterator nameMapIterator;
520 
521  // Create a map from the class names to their index in the vector of
522  // TypeId's so that the names will end up in alphabetical order.
523  for (uint32_t i = 0; i < TypeId::GetRegisteredN (); i++)
524  {
525  TypeId tid = TypeId::GetRegistered (i);
526  if (tid.MustHideFromDocumentation ())
527  {
528  continue;
529  }
530 
531  // Capitalize all of letters in the name so that it sorts
532  // correctly in the map.
533  std::string name = tid.GetName ();
534  for (uint32_t j = 0; j < name.length (); j++)
535  {
536  name[j] = toupper (name[j]);
537  }
538 
539  // Save this name's index.
540  nameMap[name] = i;
541  }
542 
543  // Iterate over the map, which will print the class names in
544  // alphabetical order.
545  for (nameMapIterator = nameMap.begin ();
546  nameMapIterator != nameMap.end ();
547  nameMapIterator++)
548  {
549  // Get the class's index out of the map;
550  uint32_t i = nameMapIterator->second;
551 
552  std::cout << commentStart << std::endl;
553  TypeId tid = TypeId::GetRegistered (i);
554  if (tid.MustHideFromDocumentation ())
555  {
556  continue;
557  }
558  std::cout << functionStart << tid.GetName () << std::endl;
559  std::cout << std::endl;
560  std::vector<std::string> paths = info.Get (tid);
561 
562  // Config --------------
563  if (paths.empty ())
564  {
565  std::cout << "Doxygen introspection did not find any typical Config paths."
566  << breakBoth << std::endl;
567  }
568  else
569  {
570  std::cout << headingStart
571  << "Config Paths"
572  << headingStop << std::endl;
573  std::cout << std::endl;
574  std::cout << tid.GetName ()
575  << " is accessible through the following paths"
576  << " with Config::Set and Config::Connect:"
577  << std::endl;
578  std::cout << listStart << std::endl;
579  for (uint32_t k = 0; k < paths.size (); ++k)
580  {
581  std::string path = paths[k];
582  std::cout << listLineStart << path
583  << listLineStop << breakTextOnly << std::endl;
584  }
585  std::cout << listStop << std::endl;
586  } // Config
587 
588  // Attributes ----------
589  if (tid.GetAttributeN () == 0)
590  {
591  std::cout << "No Attributes are defined for this type."
592  << breakBoth << std::endl;
593  }
594  else
595  {
596  std::cout << headingStart << "Attributes"
597  << headingStop << std::endl;
598  PrintAttributes (tid, std::cout);
599 
600  TypeId tmp = tid.GetParent ();
601  while (tmp.GetParent () != tmp)
602  {
603  if (tmp.GetAttributeN () != 0)
604  {
605  std::cout << headingStart
606  << "Attributes defined in parent class "
607  << tmp.GetName ()
608  << headingStop << std::endl;
609  PrintAttributes (tmp, std::cout);
610  }
611  tmp = tmp.GetParent ();
612  }
613  } // Attributes
614 
615  // Tracing -------------
616  if (tid.GetTraceSourceN () == 0)
617  {
618  std::cout << "No TraceSources are defined for this type."
619  << breakBoth << std::endl;
620  }
621  else
622  {
623  std::cout << headingStart << "TraceSources"
624  << headingStop << std::endl;
625  PrintTraceSources (tid, std::cout);
626  }
627  {
628  TypeId tmp = tid.GetParent ();
629  while (tmp.GetParent () != tmp)
630  {
631  if (tmp.GetTraceSourceN () != 0)
632  {
633  std::cout << headingStart
634  << "TraceSources defined in parent class "
635  << tmp.GetName ()
636  << headingStop << std::endl;
637  PrintTraceSources (tmp, std::cout);
638  }
639  tmp = tmp.GetParent ();
640  }
641  }
642  std::cout << commentStop << std::endl;
643  } // class documentation
644 
645 
646  std::cout << commentStart << std::endl
648  << defgroupTraceSourceListStart << "The list of all trace sources."
649  << defgroupTraceSourceListStop << std::endl;
650  for (uint32_t i = 0; i < TypeId::GetRegisteredN (); ++i)
651  {
652  TypeId tid = TypeId::GetRegistered (i);
653  if (tid.GetTraceSourceN () == 0 ||
655  {
656  continue;
657  }
658  std::cout << boldStart << tid.GetName ()
659  << boldStop << breakHtmlOnly << std::endl
660  << listStart << std::endl;
661  for (uint32_t j = 0; j < tid.GetTraceSourceN (); ++j)
662  {
663  struct TypeId::TraceSourceInformation info = tid.GetTraceSource(j);
664  std::cout << listLineStart << info.name << ": " << info.help
665  << listLineStop << std::endl;
666  }
667  std::cout << listStop << std::endl;
668  }
669  std::cout << commentStop << std::endl;
670 
671  std::cout << commentStart << std::endl
673  << defgroupAttributeListStart << "The list of all attributes."
674  << defgroupAttributeListStop << std::endl;
675  for (uint32_t i = 0; i < TypeId::GetRegisteredN (); ++i)
676  {
677  TypeId tid = TypeId::GetRegistered (i);
678  if (tid.GetAttributeN () == 0 ||
680  {
681  continue;
682  }
683  std::cout << boldStart << tid.GetName ()
684  << boldStop << breakHtmlOnly << std::endl
685  << listStart << std::endl;
686  for (uint32_t j = 0; j < tid.GetAttributeN (); ++j)
687  {
688  struct TypeId::AttributeInformation info = tid.GetAttribute(j);
689  std::cout << listLineStart << info.name << ": " << info.help
690  << listLineStop << std::endl;
691  }
692  std::cout << listStop << std::endl;
693  }
694  std::cout << commentStop << std::endl;
695 
696 
697 
698  std::cout << commentStart << std::endl
700  << defgroupGlobalValueListStart << "The list of all global values."
701  << defgroupGlobalValueListStop << std::endl
702  << listStart << std::endl;
704  i != GlobalValue::End ();
705  ++i)
706  {
707  StringValue val;
708  (*i)->GetValue (val);
709  std::cout << indentHtmlOnly
710  << listLineStart
711  << boldStart
712  << anchor
713  << "GlobalValue" << (*i)->GetName () << " " << (*i)->GetName ()
714  << boldStop
715  << ": " << (*i)->GetHelp () << ". Default value: " << val.Get () << "."
716  << listLineStop << std::endl;
717  }
718  std::cout << listStop << std::endl
719  << commentStop << std::endl;
720 
721 
722  return 0;
723 }
uint32_t GetAttributeN(void) const
Definition: type-id.cc:739
#define NS_LOG_FUNCTION(parameters)
Definition: log.h:345
std::string Get(void) const
virtual TypeId GetInstanceTypeId(void) const
Definition: object.cc:77
void RecordOutput(TypeId tid)
Record the current config path for tid.
NS_LOG_COMPONENT_DEFINE("GrantedTimeWindowMpiInterface")
std::vector< std::pair< TypeId, std::string > > m_output
Configuration path for each TypeId.
void find_and_replace(std::string &source, const std::string find, std::string replace)
(Inplace) find and replace all instances of string
hold variables of type string
Definition: string.h:19
std::string defgroupAttributeListStop
end of AttributeList group
std::string defgroupTraceSourceListStart
start of TraceSourceList group
std::string defgroupGlobalValueListStop
end of GlobalValueList group
std::string headingStart
start of section heading (h3)
virtual TypeId GetPointeeTypeId(void) const =0
std::string flagSpanStart
start of Attribute flag value
TypeId GetParent(void) const
Definition: type-id.cc:625
Vector::const_iterator Iterator
Definition: global-value.h:51
std::vector< std::string > Get(TypeId tid)
The attribute can be written at construction-time.
Definition: type-id.h:58
virtual TypeId GetItemTypeId(void) const =0
Ptr< Object > GetRootNamespaceObject(uint32_t i)
Definition: config.cc:763
std::string breakTextOnly
linebreak for text output only
void DoGather(TypeId tid)
Gather attribute, configuration path information for tid.
The attribute can be read.
Definition: type-id.h:56
bool MustHideFromDocumentation(void) const
Definition: type-id.cc:731
Ptr< const AttributeAccessor > accessor
Definition: type-id.h:67
std::string defgroupGlobalValueListStart
start of GlobalValueList group
std::string defgroupTraceSourceListStop
end of TraceSourceList group
static uint32_t GetRegisteredN(void)
Definition: type-id.cc:576
bool HasAlreadyBeenProcessed(TypeId tid) const
static Iterator Begin(void)
Ptr< const AttributeValue > initialValue
Definition: type-id.h:66
T * PeekPointer(const Ptr< T > &p)
Definition: ptr.h:279
uint32_t GetTraceSourceN(void) const
Definition: type-id.cc:760
static TypeId GetRegistered(uint32_t i)
Definition: type-id.cc:582
std::string breakHtmlOnly
linebreak for html output only
Ptr< const AttributeChecker > checker
Definition: type-id.h:68
void Print(void) const
Print output in "a -> b" form on std::cout.
keep track of a set of node pointers.
The attribute can be written.
Definition: type-id.h:57
std::string GetName(void) const
Definition: type-id.cc:658
std::vector< TypeId > m_alreadyProcessed
List of TypeIds we've already processed.
static Iterator End(void)
Gather aggregation and configuration path information from registered types.
std::vector< std::string > m_currentPath
Current configuration path.
void Gather(TypeId tid)
Gather aggregation and configuration path information for tid.
uint32_t GetRootNamespaceObjectN(void)
Definition: config.cc:757
bool IsChildOf(TypeId other) const
Definition: type-id.cc:639
void Create(uint32_t n)
Create n nodes and append pointers to them to the end of this NodeContainer.
std::string defgroupAttributeListStart
start of AttributeList group
struct TypeId::TraceSourceInformation GetTraceSource(uint32_t i) const
Definition: type-id.cc:766
struct TypeId::AttributeInformation GetAttribute(uint32_t i) const
Definition: type-id.cc:746
std::vector< std::pair< TypeId, TypeId > > m_aggregates
List of aggregation relationships.
std::string flagSpanStop
end of Attribute flag value
a unique identifier for an interface.
Definition: type-id.h:49
static TypeId LookupByName(std::string name)
Definition: type-id.cc:536
std::string GetCurrentPath(void) const
void RecordAggregationInfo(std::string a, std::string b)
Record the a -> b aggregation relation.