SearchFilter.cpp revision 263363
1//===-- SearchFilter.cpp ----------------------------------------*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10// C Includes
11// C++ Includes
12// Other libraries and framework includes
13// Project includes
14
15#include "lldb/lldb-private.h"
16#include "lldb/Core/SearchFilter.h"
17#include "lldb/Core/Module.h"
18#include "lldb/Symbol/CompileUnit.h"
19#include "lldb/Target/Target.h"
20
21using namespace lldb;
22using namespace lldb_private;
23
24//----------------------------------------------------------------------
25// SearchFilter constructor
26//----------------------------------------------------------------------
27Searcher::Searcher ()
28{
29
30}
31
32Searcher::~Searcher ()
33{
34
35}
36
37void
38Searcher::GetDescription (Stream *s)
39{
40}
41
42//----------------------------------------------------------------------
43// SearchFilter constructor
44//----------------------------------------------------------------------
45SearchFilter::SearchFilter(const TargetSP &target_sp) :
46    m_target_sp (target_sp)
47{
48}
49
50//----------------------------------------------------------------------
51// SearchFilter copy constructor
52//----------------------------------------------------------------------
53SearchFilter::SearchFilter(const SearchFilter& rhs) :
54    m_target_sp (rhs.m_target_sp)
55{
56}
57
58//----------------------------------------------------------------------
59// SearchFilter assignment operator
60//----------------------------------------------------------------------
61const SearchFilter&
62SearchFilter::operator=(const SearchFilter& rhs)
63{
64    m_target_sp = rhs.m_target_sp;
65    return *this;
66}
67
68//----------------------------------------------------------------------
69// Destructor
70//----------------------------------------------------------------------
71SearchFilter::~SearchFilter()
72{
73}
74
75bool
76SearchFilter::ModulePasses (const FileSpec &spec)
77{
78    return true;
79}
80
81bool
82SearchFilter::ModulePasses (const ModuleSP &module_sp)
83{
84    return true;
85}
86
87bool
88SearchFilter::AddressPasses (Address &address)
89{
90    return true;
91}
92
93bool
94SearchFilter::CompUnitPasses (FileSpec &fileSpec)
95{
96    return true;
97}
98
99bool
100SearchFilter::CompUnitPasses (CompileUnit &compUnit)
101{
102    return true;
103}
104
105uint32_t
106SearchFilter::GetFilterRequiredItems()
107{
108    return (lldb::SymbolContextItem) 0;
109}
110
111void
112SearchFilter::GetDescription (Stream *s)
113{
114}
115
116void
117SearchFilter::Dump (Stream *s) const
118{
119
120}
121
122//----------------------------------------------------------------------
123// UTILITY Functions to help iterate down through the elements of the
124// SymbolContext.
125//----------------------------------------------------------------------
126
127void
128SearchFilter::Search (Searcher &searcher)
129{
130    SymbolContext empty_sc;
131
132    if (!m_target_sp)
133        return;
134    empty_sc.target_sp = m_target_sp;
135
136    if (searcher.GetDepth() == Searcher::eDepthTarget)
137        searcher.SearchCallback (*this, empty_sc, NULL, false);
138    else
139        DoModuleIteration(empty_sc, searcher);
140}
141
142void
143SearchFilter::SearchInModuleList (Searcher &searcher, ModuleList &modules)
144{
145    SymbolContext empty_sc;
146
147    if (!m_target_sp)
148        return;
149    empty_sc.target_sp = m_target_sp;
150
151    if (searcher.GetDepth() == Searcher::eDepthTarget)
152        searcher.SearchCallback (*this, empty_sc, NULL, false);
153    else
154    {
155        Mutex::Locker modules_locker(modules.GetMutex());
156        const size_t numModules = modules.GetSize();
157
158        for (size_t i = 0; i < numModules; i++)
159        {
160            ModuleSP module_sp(modules.GetModuleAtIndexUnlocked(i));
161            if (ModulePasses(module_sp))
162            {
163                if (DoModuleIteration(module_sp, searcher) == Searcher::eCallbackReturnStop)
164                    return;
165            }
166        }
167    }
168}
169
170
171Searcher::CallbackReturn
172SearchFilter::DoModuleIteration (const lldb::ModuleSP& module_sp, Searcher &searcher)
173{
174    SymbolContext matchingContext (m_target_sp, module_sp);
175    return DoModuleIteration(matchingContext, searcher);
176}
177
178Searcher::CallbackReturn
179SearchFilter::DoModuleIteration (const SymbolContext &context, Searcher &searcher)
180{
181    if (searcher.GetDepth () >= Searcher::eDepthModule)
182    {
183        if (context.module_sp)
184        {
185            if (searcher.GetDepth () == Searcher::eDepthModule)
186            {
187                SymbolContext matchingContext(context.module_sp.get());
188                searcher.SearchCallback (*this, matchingContext, NULL, false);
189            }
190            else
191            {
192                return DoCUIteration(context.module_sp, context, searcher);
193            }
194        }
195        else
196        {
197            const ModuleList &target_images = m_target_sp->GetImages();
198            Mutex::Locker modules_locker(target_images.GetMutex());
199
200            size_t n_modules = target_images.GetSize();
201            for (size_t i = 0; i < n_modules; i++)
202            {
203                // If this is the last level supplied, then call the callback directly,
204                // otherwise descend.
205                ModuleSP module_sp(target_images.GetModuleAtIndexUnlocked (i));
206                if (!ModulePasses (module_sp))
207                    continue;
208
209                if (searcher.GetDepth () == Searcher::eDepthModule)
210                {
211                    SymbolContext matchingContext(m_target_sp, module_sp);
212
213                    Searcher::CallbackReturn shouldContinue = searcher.SearchCallback (*this, matchingContext, NULL, false);
214                    if (shouldContinue == Searcher::eCallbackReturnStop
215                        || shouldContinue == Searcher::eCallbackReturnPop)
216                        return shouldContinue;
217                }
218                else
219                {
220                    Searcher::CallbackReturn shouldContinue = DoCUIteration(module_sp, context, searcher);
221                    if (shouldContinue == Searcher::eCallbackReturnStop)
222                        return shouldContinue;
223                    else if (shouldContinue == Searcher::eCallbackReturnPop)
224                        continue;
225                }
226            }
227        }
228    }
229    return Searcher::eCallbackReturnContinue;
230}
231
232Searcher::CallbackReturn
233SearchFilter::DoCUIteration (const ModuleSP &module_sp, const SymbolContext &context, Searcher &searcher)
234{
235    Searcher::CallbackReturn shouldContinue;
236    if (context.comp_unit == NULL)
237    {
238        const size_t num_comp_units = module_sp->GetNumCompileUnits();
239        for (size_t i = 0; i < num_comp_units; i++)
240        {
241            CompUnitSP cu_sp (module_sp->GetCompileUnitAtIndex (i));
242            if (cu_sp)
243            {
244                if (!CompUnitPasses (*(cu_sp.get())))
245                    continue;
246
247                if (searcher.GetDepth () == Searcher::eDepthCompUnit)
248                {
249                    SymbolContext matchingContext(m_target_sp, module_sp, cu_sp.get());
250
251                    shouldContinue = searcher.SearchCallback (*this, matchingContext, NULL, false);
252
253                    if (shouldContinue == Searcher::eCallbackReturnPop)
254                        return Searcher::eCallbackReturnContinue;
255                    else if (shouldContinue == Searcher::eCallbackReturnStop)
256                        return shouldContinue;
257                }
258                else
259                {
260                    // FIXME Descend to block.
261                }
262            }
263        }
264    }
265    else
266    {
267        if (CompUnitPasses(*context.comp_unit))
268        {
269            SymbolContext matchingContext (m_target_sp, module_sp, context.comp_unit);
270            return searcher.SearchCallback (*this, matchingContext, NULL, false);
271        }
272    }
273    return Searcher::eCallbackReturnContinue;
274}
275
276Searcher::CallbackReturn
277SearchFilter::DoFunctionIteration (Function *function, const SymbolContext &context, Searcher &searcher)
278{
279    // FIXME: Implement...
280    return Searcher::eCallbackReturnContinue;
281}
282
283//----------------------------------------------------------------------
284//  SearchFilterForNonModuleSpecificSearches:
285//  Selects a shared library matching a given file spec, consulting the targets "black list".
286//----------------------------------------------------------------------
287
288    bool
289    SearchFilterForNonModuleSpecificSearches::ModulePasses (const FileSpec &module_spec)
290    {
291        if (m_target_sp->ModuleIsExcludedForNonModuleSpecificSearches (module_spec))
292            return false;
293        else
294            return true;
295    }
296
297    bool
298    SearchFilterForNonModuleSpecificSearches::ModulePasses (const lldb::ModuleSP &module_sp)
299    {
300        if (!module_sp)
301            return true;
302        else if (m_target_sp->ModuleIsExcludedForNonModuleSpecificSearches (module_sp))
303            return false;
304        else
305            return true;
306    }
307
308//----------------------------------------------------------------------
309//  SearchFilterByModule:
310//  Selects a shared library matching a given file spec
311//----------------------------------------------------------------------
312
313//----------------------------------------------------------------------
314// SearchFilterByModule constructors
315//----------------------------------------------------------------------
316
317SearchFilterByModule::SearchFilterByModule (const lldb::TargetSP &target_sp, const FileSpec &module) :
318    SearchFilter (target_sp),
319    m_module_spec (module)
320{
321}
322
323
324//----------------------------------------------------------------------
325// SearchFilterByModule copy constructor
326//----------------------------------------------------------------------
327SearchFilterByModule::SearchFilterByModule(const SearchFilterByModule& rhs) :
328    SearchFilter (rhs),
329    m_module_spec (rhs.m_module_spec)
330{
331}
332
333//----------------------------------------------------------------------
334// SearchFilterByModule assignment operator
335//----------------------------------------------------------------------
336const SearchFilterByModule&
337SearchFilterByModule::operator=(const SearchFilterByModule& rhs)
338{
339    m_target_sp = rhs.m_target_sp;
340    m_module_spec = rhs.m_module_spec;
341    return *this;
342}
343
344//----------------------------------------------------------------------
345// Destructor
346//----------------------------------------------------------------------
347SearchFilterByModule::~SearchFilterByModule()
348{
349}
350
351bool
352SearchFilterByModule::ModulePasses (const ModuleSP &module_sp)
353{
354    if (module_sp && FileSpec::Equal(module_sp->GetFileSpec(), m_module_spec, false))
355        return true;
356    else
357        return false;
358}
359
360bool
361SearchFilterByModule::ModulePasses (const FileSpec &spec)
362{
363    // Do a full match only if "spec" has a directory
364    const bool full_match = (bool)spec.GetDirectory();
365    return FileSpec::Equal(spec, m_module_spec, full_match);
366}
367
368bool
369SearchFilterByModule::AddressPasses (Address &address)
370{
371    // FIXME: Not yet implemented
372    return true;
373}
374
375
376bool
377SearchFilterByModule::CompUnitPasses (FileSpec &fileSpec)
378{
379    return true;
380}
381
382bool
383SearchFilterByModule::CompUnitPasses (CompileUnit &compUnit)
384{
385    return true;
386}
387
388void
389SearchFilterByModule::Search (Searcher &searcher)
390{
391    if (!m_target_sp)
392        return;
393
394    if (searcher.GetDepth() == Searcher::eDepthTarget)
395    {
396        SymbolContext empty_sc;
397        empty_sc.target_sp = m_target_sp;
398        searcher.SearchCallback (*this, empty_sc, NULL, false);
399    }
400
401    // If the module file spec is a full path, then we can just find the one
402    // filespec that passes.  Otherwise, we need to go through all modules and
403    // find the ones that match the file name.
404
405    const ModuleList &target_modules = m_target_sp->GetImages();
406    Mutex::Locker modules_locker (target_modules.GetMutex());
407
408    const size_t num_modules = target_modules.GetSize ();
409    for (size_t i = 0; i < num_modules; i++)
410    {
411        Module* module = target_modules.GetModulePointerAtIndexUnlocked(i);
412        const bool full_match = (bool)m_module_spec.GetDirectory();
413        if (FileSpec::Equal (m_module_spec, module->GetFileSpec(), full_match))
414        {
415            SymbolContext matchingContext(m_target_sp, module->shared_from_this());
416            Searcher::CallbackReturn shouldContinue;
417
418            shouldContinue = DoModuleIteration(matchingContext, searcher);
419            if (shouldContinue == Searcher::eCallbackReturnStop)
420                return;
421        }
422    }
423}
424
425void
426SearchFilterByModule::GetDescription (Stream *s)
427{
428    s->PutCString(", module = ");
429    if (s->GetVerbose())
430    {
431        char buffer[2048];
432        m_module_spec.GetPath(buffer, 2047);
433        s->PutCString(buffer);
434    }
435    else
436    {
437        s->PutCString(m_module_spec.GetFilename().AsCString("<unknown>"));
438    }
439}
440
441uint32_t
442SearchFilterByModule::GetFilterRequiredItems()
443{
444    return eSymbolContextModule;
445}
446
447void
448SearchFilterByModule::Dump (Stream *s) const
449{
450
451}
452//----------------------------------------------------------------------
453//  SearchFilterByModuleList:
454//  Selects a shared library matching a given file spec
455//----------------------------------------------------------------------
456
457//----------------------------------------------------------------------
458// SearchFilterByModuleList constructors
459//----------------------------------------------------------------------
460
461SearchFilterByModuleList::SearchFilterByModuleList (const lldb::TargetSP &target_sp, const FileSpecList &module_list) :
462    SearchFilter (target_sp),
463    m_module_spec_list (module_list)
464{
465}
466
467
468//----------------------------------------------------------------------
469// SearchFilterByModuleList copy constructor
470//----------------------------------------------------------------------
471SearchFilterByModuleList::SearchFilterByModuleList(const SearchFilterByModuleList& rhs) :
472    SearchFilter (rhs),
473    m_module_spec_list (rhs.m_module_spec_list)
474{
475}
476
477//----------------------------------------------------------------------
478// SearchFilterByModuleList assignment operator
479//----------------------------------------------------------------------
480const SearchFilterByModuleList&
481SearchFilterByModuleList::operator=(const SearchFilterByModuleList& rhs)
482{
483    m_target_sp = rhs.m_target_sp;
484    m_module_spec_list = rhs.m_module_spec_list;
485    return *this;
486}
487
488//----------------------------------------------------------------------
489// Destructor
490//----------------------------------------------------------------------
491SearchFilterByModuleList::~SearchFilterByModuleList()
492{
493}
494
495bool
496SearchFilterByModuleList::ModulePasses (const ModuleSP &module_sp)
497{
498    if (m_module_spec_list.GetSize() == 0)
499        return true;
500
501    if (module_sp && m_module_spec_list.FindFileIndex(0, module_sp->GetFileSpec(), false) != UINT32_MAX)
502        return true;
503    else
504        return false;
505}
506
507bool
508SearchFilterByModuleList::ModulePasses (const FileSpec &spec)
509{
510    if (m_module_spec_list.GetSize() == 0)
511        return true;
512
513    if (m_module_spec_list.FindFileIndex(0, spec, true) != UINT32_MAX)
514        return true;
515    else
516        return false;
517}
518
519bool
520SearchFilterByModuleList::AddressPasses (Address &address)
521{
522    // FIXME: Not yet implemented
523    return true;
524}
525
526
527bool
528SearchFilterByModuleList::CompUnitPasses (FileSpec &fileSpec)
529{
530    return true;
531}
532
533bool
534SearchFilterByModuleList::CompUnitPasses (CompileUnit &compUnit)
535{
536    return true;
537}
538
539void
540SearchFilterByModuleList::Search (Searcher &searcher)
541{
542    if (!m_target_sp)
543        return;
544
545    if (searcher.GetDepth() == Searcher::eDepthTarget)
546    {
547        SymbolContext empty_sc;
548        empty_sc.target_sp = m_target_sp;
549        searcher.SearchCallback (*this, empty_sc, NULL, false);
550    }
551
552    // If the module file spec is a full path, then we can just find the one
553    // filespec that passes.  Otherwise, we need to go through all modules and
554    // find the ones that match the file name.
555
556    const ModuleList &target_modules = m_target_sp->GetImages();
557    Mutex::Locker modules_locker (target_modules.GetMutex());
558
559    const size_t num_modules = target_modules.GetSize ();
560    for (size_t i = 0; i < num_modules; i++)
561    {
562        Module* module = target_modules.GetModulePointerAtIndexUnlocked(i);
563        if (m_module_spec_list.FindFileIndex(0, module->GetFileSpec(), false) != UINT32_MAX)
564        {
565            SymbolContext matchingContext(m_target_sp, module->shared_from_this());
566            Searcher::CallbackReturn shouldContinue;
567
568            shouldContinue = DoModuleIteration(matchingContext, searcher);
569            if (shouldContinue == Searcher::eCallbackReturnStop)
570                return;
571        }
572    }
573}
574
575void
576SearchFilterByModuleList::GetDescription (Stream *s)
577{
578    size_t num_modules = m_module_spec_list.GetSize();
579    if (num_modules == 1)
580    {
581        s->Printf (", module = ");
582        if (s->GetVerbose())
583        {
584            char buffer[2048];
585            m_module_spec_list.GetFileSpecAtIndex(0).GetPath(buffer, 2047);
586            s->PutCString(buffer);
587        }
588        else
589        {
590            s->PutCString(m_module_spec_list.GetFileSpecAtIndex(0).GetFilename().AsCString("<unknown>"));
591        }
592    }
593    else
594    {
595        s->Printf (", modules(%zu) = ", num_modules);
596        for (size_t i = 0; i < num_modules; i++)
597        {
598            if (s->GetVerbose())
599            {
600                char buffer[2048];
601                m_module_spec_list.GetFileSpecAtIndex(i).GetPath(buffer, 2047);
602                s->PutCString(buffer);
603            }
604            else
605            {
606                s->PutCString(m_module_spec_list.GetFileSpecAtIndex(i).GetFilename().AsCString("<unknown>"));
607            }
608            if (i != num_modules - 1)
609                s->PutCString (", ");
610        }
611    }
612}
613
614uint32_t
615SearchFilterByModuleList::GetFilterRequiredItems()
616{
617    return eSymbolContextModule;
618}
619
620void
621SearchFilterByModuleList::Dump (Stream *s) const
622{
623
624}
625
626//----------------------------------------------------------------------
627//  SearchFilterByModuleListAndCU:
628//  Selects a shared library matching a given file spec
629//----------------------------------------------------------------------
630
631//----------------------------------------------------------------------
632// SearchFilterByModuleListAndCU constructors
633//----------------------------------------------------------------------
634
635SearchFilterByModuleListAndCU::SearchFilterByModuleListAndCU (const lldb::TargetSP &target_sp,
636                                                              const FileSpecList &module_list,
637                                                              const FileSpecList &cu_list) :
638    SearchFilterByModuleList (target_sp, module_list),
639    m_cu_spec_list (cu_list)
640{
641}
642
643
644//----------------------------------------------------------------------
645// SearchFilterByModuleListAndCU copy constructor
646//----------------------------------------------------------------------
647SearchFilterByModuleListAndCU::SearchFilterByModuleListAndCU(const SearchFilterByModuleListAndCU& rhs) :
648    SearchFilterByModuleList (rhs),
649    m_cu_spec_list (rhs.m_cu_spec_list)
650{
651}
652
653//----------------------------------------------------------------------
654// SearchFilterByModuleListAndCU assignment operator
655//----------------------------------------------------------------------
656const SearchFilterByModuleListAndCU&
657SearchFilterByModuleListAndCU::operator=(const SearchFilterByModuleListAndCU& rhs)
658{
659    if (&rhs != this)
660    {
661        m_target_sp = rhs.m_target_sp;
662        m_module_spec_list = rhs.m_module_spec_list;
663        m_cu_spec_list = rhs.m_cu_spec_list;
664    }
665    return *this;
666}
667
668//----------------------------------------------------------------------
669// Destructor
670//----------------------------------------------------------------------
671SearchFilterByModuleListAndCU::~SearchFilterByModuleListAndCU()
672{
673}
674
675bool
676SearchFilterByModuleListAndCU::AddressPasses (Address &address)
677{
678    return true;
679}
680
681
682bool
683SearchFilterByModuleListAndCU::CompUnitPasses (FileSpec &fileSpec)
684{
685    return m_cu_spec_list.FindFileIndex(0, fileSpec, false) != UINT32_MAX;
686}
687
688bool
689SearchFilterByModuleListAndCU::CompUnitPasses (CompileUnit &compUnit)
690{
691    bool in_cu_list = m_cu_spec_list.FindFileIndex(0, compUnit, false) != UINT32_MAX;
692    if (in_cu_list)
693    {
694        ModuleSP module_sp(compUnit.GetModule());
695        if (module_sp)
696        {
697            bool module_passes = SearchFilterByModuleList::ModulePasses(module_sp);
698            return module_passes;
699        }
700        else
701            return true;
702    }
703    else
704        return false;
705}
706
707void
708SearchFilterByModuleListAndCU::Search (Searcher &searcher)
709{
710    if (!m_target_sp)
711        return;
712
713    if (searcher.GetDepth() == Searcher::eDepthTarget)
714    {
715        SymbolContext empty_sc;
716        empty_sc.target_sp = m_target_sp;
717        searcher.SearchCallback (*this, empty_sc, NULL, false);
718    }
719
720    // If the module file spec is a full path, then we can just find the one
721    // filespec that passes.  Otherwise, we need to go through all modules and
722    // find the ones that match the file name.
723
724    ModuleList matching_modules;
725    const ModuleList &target_images = m_target_sp->GetImages();
726    Mutex::Locker modules_locker(target_images.GetMutex());
727
728    const size_t num_modules = target_images.GetSize ();
729    bool no_modules_in_filter = m_module_spec_list.GetSize() == 0;
730    for (size_t i = 0; i < num_modules; i++)
731    {
732        lldb::ModuleSP module_sp = target_images.GetModuleAtIndexUnlocked(i);
733        if (no_modules_in_filter || m_module_spec_list.FindFileIndex(0, module_sp->GetFileSpec(), false) != UINT32_MAX)
734        {
735            SymbolContext matchingContext(m_target_sp, module_sp);
736            Searcher::CallbackReturn shouldContinue;
737
738            if (searcher.GetDepth() == Searcher::eDepthModule)
739            {
740                shouldContinue = DoModuleIteration(matchingContext, searcher);
741                if (shouldContinue == Searcher::eCallbackReturnStop)
742                    return;
743            }
744            else
745            {
746                const size_t num_cu = module_sp->GetNumCompileUnits();
747                for (size_t cu_idx = 0; cu_idx < num_cu; cu_idx++)
748                {
749                    CompUnitSP cu_sp = module_sp->GetCompileUnitAtIndex(cu_idx);
750                    matchingContext.comp_unit = cu_sp.get();
751                    if (matchingContext.comp_unit)
752                    {
753                        if (m_cu_spec_list.FindFileIndex(0, *matchingContext.comp_unit, false) != UINT32_MAX)
754                        {
755                            shouldContinue = DoCUIteration(module_sp, matchingContext, searcher);
756                            if (shouldContinue == Searcher::eCallbackReturnStop)
757                                return;
758                        }
759                    }
760                }
761            }
762        }
763    }
764}
765
766void
767SearchFilterByModuleListAndCU::GetDescription (Stream *s)
768{
769    size_t num_modules = m_module_spec_list.GetSize();
770    if (num_modules == 1)
771    {
772        s->Printf (", module = ");
773        if (s->GetVerbose())
774        {
775            char buffer[2048];
776            m_module_spec_list.GetFileSpecAtIndex(0).GetPath(buffer, 2047);
777            s->PutCString(buffer);
778        }
779        else
780        {
781            s->PutCString(m_module_spec_list.GetFileSpecAtIndex(0).GetFilename().AsCString("<unknown>"));
782        }
783    }
784    else if (num_modules > 0)
785    {
786        s->Printf (", modules(%zd) = ", num_modules);
787        for (size_t i = 0; i < num_modules; i++)
788        {
789            if (s->GetVerbose())
790            {
791                char buffer[2048];
792                m_module_spec_list.GetFileSpecAtIndex(i).GetPath(buffer, 2047);
793                s->PutCString(buffer);
794            }
795            else
796            {
797                s->PutCString(m_module_spec_list.GetFileSpecAtIndex(i).GetFilename().AsCString("<unknown>"));
798            }
799            if (i != num_modules - 1)
800                s->PutCString (", ");
801        }
802    }
803}
804
805uint32_t
806SearchFilterByModuleListAndCU::GetFilterRequiredItems()
807{
808    return eSymbolContextModule | eSymbolContextCompUnit;
809}
810
811void
812SearchFilterByModuleListAndCU::Dump (Stream *s) const
813{
814
815}
816
817