<div dir="ltr">AFAIK OpenMP is still work in progress... Hope Alexey knows more about this.</div><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Dec 2, 2014 at 5:26 AM, Xiaohui Chen <span dir="ltr"><<a href="mailto:xchen422@uwo.ca" target="_blank">xchen422@uwo.ca</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">hi<b> </b><span></span> Nikola:<br>i can not dump the openmp node, am i missing some options?<br>for example:<br><br>int main()<br>{<br>int k=90, l=0;<br>#pragma omp parallel private(k, l)<br>{<br>        #pragma omp for<br>        for(int kk=0; kk<90;kk++)<br>        {<br>                l;<br>        }<br>}<br>}<br><br>I use the following command to compile:<br><br><b>clang++  -Xclang -ast-dump -Xclang -fopenmp=libiomp5 t.cpp</b><br><br>output is :<br><br>`-OMPParallelDirective 0x6febf50 <line:32:9, col:35><br>      `-CapturedStmt 0x6febf10 <line:33:1, line:39:1><br>        `-DeclRefExpr 0x6feb7f8 <line:37:3> 'int' lvalue Var 0x6fe8590 'l' 'int'<br><br>it did not say anything about the for loop and the private clause.<br><br>Sincerely<br>xiaohui<br><br><span>On 11/23/14, <b>Nikola Smiljanic </b> <<a href="mailto:popizdeh@gmail.com" target="_blank">popizdeh@gmail.com</a>> wrote:</span><blockquote style="border-left:1px solid #00f;padding-left:13px;margin-left:0" type="cite"><div><div dir="ltr">Yes, and it'll call cc1_main.</div><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Nov 24, 2014 at 4:17 PM, Xiaohui Chen <span dir="ltr"><<a href="mailto:xchen422@uwo.ca" target="_blank">xchen422@uwo.ca</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">yes, you are right. Usually i just use the frontend through -cc1, and now i want to know a little about the workflow of the driver <img alt=":-)" src="https://iwc.uwo.ca/iwc_static/layout/images/emoticons/emo_smiley.png?2-4.01_114059" style="padding-left:2px;padding-right:3px" title="Smiley :-)"><font size="3">.<br><br></font>so does this mean that the frontend and driver shares the same main() function as i said below?<br>because i notice that in line 412 of main() function it will check the -cc1 flag.<div><div><br><br><br><span>On 11/23/14, <b>Nikola Smiljanic </b> <<a href="mailto:popizdeh@gmail.com" target="_blank">popizdeh@gmail.com</a>> wrote:</span><blockquote style="border-left:1px solid #00f;padding-left:13px;margin-left:0" type="cite"><div><div dir="ltr"><div>When you invoke something like "clang test.cpp -o test" you're invoking the driver. It will process the options you passed to it and build a list of arguments to pass to the frontend and other tools (assembler, linker, etc.). It will spawn a new process for the frontend. </div><div><br></div><div>To see the arguments passed to the frontend use -###.</div><div>To invoke the frontend directly use -cc1. If you're interested in clang's lexing/parsing/sema logic using someting like "clang -cc1 -fsyntax-only test.cpp" should be enough.</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Nov 24, 2014 at 3:38 PM, Xiaohui Chen <span dir="ltr"><<a href="mailto:xchen422@uwo.ca" target="_blank">xchen422@uwo.ca</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">hi all:<br><br>i am looking into the "main function" of llvm/tools/clang/tools/driver/driver.cpp,<br>i only add several llvm::outs() in the source code, and re-compile the source code again,<br>then i use the clang to compile  my input file(t.c) like this:<br><br>xchen422@dimsum:~$ clang  t.c<br><br> the output is :<br><br>xchen422@dimsum:~$ clang  t.c <br>clang main function start point 1<br>clang main function start point 3<br>clang main function start point 4<br>clang main function start point 1<br>clang main function start point 2<br>clang main function start point 5<br>clang main function start point 6<br>xchen422@dimsum:~$ <br><br>It seems that the main() function is called twice, also it seems that there are <br>some magic in this function(line 468):<br> Res = TheDriver.ExecuteCompilation(*C, FailingCommands);<br><br>i could not understand, could someone give me a brief explanation. <br><br><br>PS:<br>1). I add llvm::outs() in line 379, line 418, line 422, line 466, line 470 and line 512.<br>2). t.c file only contains an empty main() function.<br>3). i paste the main() function below.<br><br><br><br><br>          int main(int argc_, const char **argv_) {<br>379     llvm::outs() << "clang main function start point 1"  << '\n';<br>380 <br>381 <br>382   llvm::sys::PrintStackTraceOnErrorSignal();<br>383   llvm::PrettyStackTraceProgram X(argc_, argv_);<br>384 <br>385   if (llvm::sys::Process::FixupStandardFileDescriptors())<br>386     return 1;<br>387 <br>388   SmallVector<const char *, 256> argv;<br>389   llvm::SpecificBumpPtrAllocator<char> ArgAllocator;<br>390   std::error_code EC = llvm::sys::Process::GetArgumentVector(<br>391       argv, llvm::makeArrayRef(argv_, argc_), ArgAllocator);<br>392   if (EC) {<br>393     llvm::errs() << "error: couldn't get arguments: " << EC.message() << '\n';<br>394     return 1;<br>395   }<br>396 <br>397   std::set<std::string> SavedStrings;<br>398   StringSetSaver Saver(SavedStrings);<br>399 <br>400   // Determines whether we want nullptr markers in argv to indicate response<br>401   // files end-of-lines. We only use this for the /LINK driver argument.<br>402   bool MarkEOLs = true;<br>403   if (argv.size() > 1 && StringRef(argv[1]).startswith("-cc1"))<br>404     MarkEOLs = false;<br>405   llvm::cl::ExpandResponseFiles(Saver, llvm::cl::TokenizeGNUCommandLine, argv,<br>406                                 MarkEOLs);<br>407 <br>408   // Handle -cc1 integrated tools, even if -cc1 was expanded from a response<br>409   // file.<br>410   auto FirstArg = std::find_if(argv.begin() + 1, argv.end(),<br>411                                [](const char *A) { return A != nullptr; });<br>412   if (FirstArg != argv.end() && StringRef(*FirstArg).startswith("-cc1")) {<br>413     // If -cc1 came from a response file, remove the EOL sentinels.<br>414     if (MarkEOLs) {<br>415       auto newEnd = std::remove(argv.begin(), argv.end(), nullptr);<br>416       argv.resize(newEnd - argv.begin());<br>417     }<br>418     llvm::outs() << "clang main function start point 2"  << '\n';<br>419     return ExecuteCC1Tool(argv, argv[1] + 4);<br>420   }<br>421 <br>422     llvm::outs() << "clang main function start point 3"  << '\n';<br>423   bool CanonicalPrefixes = true;<br>424   for (int i = 1, size = argv.size(); i < size; ++i) {<br>425     // Skip end-of-line response file markers<br>426     if (argv[i] == nullptr)<br>427       continue;<br>428     if (StringRef(argv[i]) == "-no-canonical-prefixes") {<br>429       CanonicalPrefixes = false;<br>430       break;<br>431     }<br>432   }<br>433 <br>434   // Handle CCC_OVERRIDE_OPTIONS, used for editing a command line behind the<br>435   // scenes.<br>436   if (const char *OverrideStr = ::getenv("CCC_OVERRIDE_OPTIONS")) {<br>437     // FIXME: Driver shouldn't take extra initial argument.<br>438     ApplyQAOverride(argv, OverrideStr, SavedStrings);<br>439   }<br>440 <br>441   std::string Path = GetExecutablePath(argv[0], CanonicalPrefixes);<br>442 <br>443   IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts =<br>444       CreateAndPopulateDiagOpts(argv);<br>445 <br>446   TextDiagnosticPrinter *DiagClient<br>447     = new TextDiagnosticPrinter(llvm::errs(), &*DiagOpts);<br>448   FixupDiagPrefixExeName(DiagClient, Path);<br>449 <br>450   IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());<br>451 <br>452   DiagnosticsEngine Diags(DiagID, &*DiagOpts, DiagClient);<br>453   ProcessWarningOptions(Diags, *DiagOpts, /*ReportDiags=*/false);<br>454 <br>455   Driver TheDriver(Path, llvm::sys::getDefaultTargetTriple(), Diags);<br>456   SetInstallDir(argv, TheDriver);<br>457 <br>458   llvm::InitializeAllTargets();<br>459   ParseProgName(argv, SavedStrings);<br>460 <br>461   SetBackdoorDriverOutputsFromEnvVars(TheDriver);<br>462 <br>463   std::unique_ptr<Compilation> C(TheDriver.BuildCompilation(argv));<br>464   int Res = 0;<br>465   SmallVector<std::pair<int, const Command *>, 4> FailingCommands;<br>466     llvm::outs() << "clang main function start point 4"  << '\n';<br>467   if (C.get())<br>468     Res = TheDriver.ExecuteCompilation(*C, FailingCommands);<br>469 <br>470     llvm::outs() << "clang main function start point 5"  << '\n';<br>471   // Force a crash to test the diagnostics.<br>472   if (::getenv("FORCE_CLANG_DIAGNOSTICS_CRASH")) {<br>473     Diags.Report(diag::err_drv_force_crash) << "FORCE_CLANG_DIAGNOSTICS_CRASH";<br>474     const Command *FailingCommand = nullptr;<br>475     FailingCommands.push_back(std::make_pair(-1, FailingCommand));<br>476   }<br>477 <br>478   for (const auto &P : FailingCommands) {<br>479     int CommandRes = P.first;<br>480     const Command *FailingCommand = P.second;<br>481     if (!Res)<br>482       Res = CommandRes;<br>483 <br>484     // If result status is < 0, then the driver command signalled an error.<br>485     // If result status is 70, then the driver command reported a fatal error.<br>486     // On Windows, abort will return an exit code of 3.  In these cases,<br>487     // generate additional diagnostic information if possible.<br>488     bool DiagnoseCrash = CommandRes < 0 || CommandRes == 70;<br>489 #ifdef LLVM_ON_WIN32<br>490     DiagnoseCrash |= CommandRes == 3;<br>491 #endif<br>492     if (DiagnoseCrash) {<br>493       TheDriver.generateCompilationDiagnostics(*C, FailingCommand);<br>494       break;<br>495     }<br>496   }<br>497 <br>498   // If any timers were active but haven't been destroyed yet, print their<br>499   // results now.  This happens in -disable-free mode.<br>500   llvm::TimerGroup::printAll(llvm::errs());<br>501 <br>502   llvm::llvm_shutdown();<br>503 <br>504 #ifdef LLVM_ON_WIN32<br>505   // Exit status should not be negative on Win32, unless abnormal termination.<br>506   // Once abnormal termiation was caught, negative status should not be<br>507   // propagated.<br>508   if (Res < 0)<br>509     Res = 1;<br>510 #endif<br>511 <br>512     llvm::outs() << "clang main function start point 6"  << '\n';<br>513   // If we have multiple failing commands, we return the result of the first<br>514   // failing command.<br>515   return Res;<br>516 }<br>             <br><br><br><br><br><br><span>On 11/06/14, <b>Nikola Smiljanic </b> <<a href="mailto:popizdeh@gmail.com" target="_blank">popizdeh@gmail.com</a>> wrote:</span><blockquote style="border-left:1px solid #00f;padding-left:13px;margin-left:0" type="cite"><div><div dir="ltr">I'm not sure how long make takes to run if there's nothing to compile. But you should definitely check out cmake + ninja.</div><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Nov 7, 2014 at 10:52 AM, Xiaohui Chen <span dir="ltr"><<a href="mailto:xchen422@uwo.ca" target="_blank">xchen422@uwo.ca</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">yes, i know, the makefile will skip compiling the code if i do not change them, but it will still <br>go through some directories and say "nothing to do" i guess.<br><br>it is ok, i can use the current solution. Thank you!<div><div><br><br><span>On 11/06/14, <b>Nikola Smiljanic </b> <<a href="mailto:popizdeh@gmail.com" target="_blank">popizdeh@gmail.com</a>> wrote:</span><blockquote style="border-left:1px solid #00f;padding-left:13px;margin-left:0" type="cite"><div><div dir="ltr">How will it waste time if you don't change it?</div><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Nov 7, 2014 at 9:53 AM, Xiaohui Chen <span dir="ltr"><<a href="mailto:xchen422@uwo.ca" target="_blank">xchen422@uwo.ca</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">I am writing a source to source tool which need to add some new keywords in the clang source file, so this tool can parse <br>the input file with my new keywords, now this tool is still under developing and  debugging, each time when i want to <br>recompile this tool  i do not want to involve llvm stuff, because it will waste some time......<div><div><br><br><span>On 11/06/14, <b>Nikola Smiljanic </b> <<a href="mailto:popizdeh@gmail.com" target="_blank">popizdeh@gmail.com</a>> wrote:</span><blockquote style="border-left:1px solid #00f;padding-left:13px;margin-left:0" type="cite"><div><div dir="ltr">Why exactly do you want an out of source build if your using makefiles? It's beneficial with Visual Studio but I don't see the reason for it if you're building from the command line?</div><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Nov 7, 2014 at 9:14 AM, Xiaohui Chen <span dir="ltr"><<a href="mailto:xchen422@uwo.ca" target="_blank">xchen422@uwo.ca</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">.... i have no idea of cmake ....<br><br>i use makefile under linux, so who could help?<div><div><br><br><span>On 11/06/14, <b>Nikola Smiljanic </b> <<a href="mailto:popizdeh@gmail.com" target="_blank">popizdeh@gmail.com</a>> wrote:</span><blockquote style="border-left:1px solid #00f;padding-left:13px;margin-left:0" type="cite"><div><div dir="ltr">I only know how to do this with cmake.</div><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Nov 7, 2014 at 8:32 AM, Xiaohui Chen <span dir="ltr"><<a href="mailto:xchen422@uwo.ca" target="_blank">xchen422@uwo.ca</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">i think i get your point and that is what i expect.<br><br>you mean that:<br><br>1. make a standalone directory for Clang not in llvm/tools<br><br>2. compile both llvm and clang as usual<br><br>3. if i modify Clang source file, i just execute the Makefile inside clang/ directory, so it<br>will just re-compile the Clang file  without checking llvm files<br><br>is there any instructions to do this? <br><br>Especially in step 2, if i compile in this way i guess i will break the dependence relationship in "configure" file?<br><br>Best <br><span><font color="#888888">xiaohui</font></span><div><div><br><br><span>On 11/06/14, <b>Nikola Smiljanic </b> <<a href="mailto:popizdeh@gmail.com" target="_blank">popizdeh@gmail.com</a>> wrote:</span><blockquote style="border-left:1px solid #00f;padding-left:13px;margin-left:0" type="cite"><div><div dir="ltr">The best you can do is compile clang "out of source". Meaning the clang directory stands on its own and not in llvm/projects. This makes a difference if you're generating Visual Studio solution file as you won't have to load llvm projects. But llvm must be built.</div><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Nov 7, 2014 at 4:24 AM, Jingyue Wu <span dir="ltr"><<a href="mailto:jingyue@google.com" target="_blank">jingyue@google.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">I don't think so. clang uses a lot of LLVM's core libraries. <span><font color="#888888"><br><br><div>Jingyue</div></font></span><div><div><br><div class="gmail_quote">On Thu Nov 06 2014 at 9:14:49 AM Xiaohui Chen <<a href="mailto:xchen422@uwo.ca" target="_blank">xchen422@uwo.ca</a>> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi all:<br><br>I am writing a source to source tool and adding new keywords in the clang source file(i just care about the AST), <br>is there a way to just compile the clang frontend source file but not including llvm source file?<br><br>Sincerely<br>xiaohui  <br><br><span>On 11/03/14, <b>Nikola Smiljanic </b> <<a href="mailto:popizdeh@gmail.com" target="_blank">popizdeh@gmail.com</a>> wrote:</span><blockquote style="border-left:1px solid #00f;padding-left:13px;margin-left:0" type="cite"><div><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Tue, Nov 4, 2014 at 7:14 AM, Xiaohui Chen <span dir="ltr"><<a href="mailto:xchen422@uwo.ca" target="_blank">xchen422@uwo.ca</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Thanks for your reply.<br><br>I am confusing here:<span><br><br>1. Traverse method visits AST nodes that form a tree. CXXRecordDecl is the parent of each of its CXXMethodDecls and FieldDecls.<br><br></span> CXXMethodDecls ( FieldDecls )  is not  a member of CXXRecordDecl and also does not inherit from CXXRecordDecl, so how could<br>you define them as parent-child relationship?</blockquote><div><br></div><div>CXXRecordDecl contains CXXMethodDecls and RecordDecl contains FieldDecls. They're just stored in the DeclContext class but are exposed with method_begin/method_end and field_begin/field_end.</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span>2. WalkUpFrom method visits the class hierarchy of a single AST node. CXXRecordDecl inherits RecordDecl which inherits TagDecl etc.<br><br></span>here TagDecl has three direct parents, so will WalkUpFrom be applied to these three classes?<br><br></blockquote><div><br></div><div>TagDecl does have three super classes but only one of them is also an AST node. AST is built from declarations, statements and types. DeclContext represents a declaration context and structs/classes introduce one. They are also redeclarable (forward declaration) which is what Redeclarable class keeps track of.</div><div><br></div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">sincerely<span><font color="#888888"><br>xiaohui</font></span><div><div><br><br><span>On 11/03/14, <b>Nikola Smiljanic </b> <<a href="mailto:popizdeh@gmail.com" target="_blank">popizdeh@gmail.com</a>> wrote:</span><blockquote style="border-left:1px solid #00f;padding-left:13px;margin-left:0" type="cite"><div><div dir="ltr">There are two parent-child relationships at play.<div><br></div><div>1. Traverse method visits AST nodes that form a tree. CXXRecordDecl is the parent of each of its CXXMethodDecls and FieldDecls. This is what you'll see with clang -cc1 -ast-dump</div><div>2. WalkUpFrom method visits the class hierarchy of a single AST node. CXXRecordDecl inherits RecordDecl which inherits TagDecl etc. Think of serialization, to serialize CXXRecordDecl you'd first want to serialize everything from the base class and so on recursively.</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Nov 3, 2014 at 12:32 PM, Xiaohui Chen <span dir="ltr"><<a href="mailto:xchen422@uwo.ca" target="_blank">xchen422@uwo.ca</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"> Dear all:<br><span><div><br>I am using Clang as the frontend of my project, but i am confusing of the following statements.<br>PS: i am a newbie. <br><br><pre><span>These tasks are done by three groups of methods, respectively:</span>
<a name="14a071ab787fc08a_149e03bdbddaaa27_149e01796338663c_1498785a0356c1d7_14987505ac1199fd_149872c0d1b48f44_1498706daaa17355_149862cb4af790d9_msg-f:1484043415893042809_149774a86dc8444d_1497396fe06534f4_l00089"></a>00089 <span>///   1. TraverseDecl(Decl *x) does task #1.  It is the entry point</span>
<a name="14a071ab787fc08a_149e03bdbddaaa27_149e01796338663c_1498785a0356c1d7_14987505ac1199fd_149872c0d1b48f44_1498706daaa17355_149862cb4af790d9_msg-f:1484043415893042809_149774a86dc8444d_1497396fe06534f4_l00090"></a>00090 <span>///      for traversing an AST rooted at x.  This method simply</span>
<a name="14a071ab787fc08a_149e03bdbddaaa27_149e01796338663c_1498785a0356c1d7_14987505ac1199fd_149872c0d1b48f44_1498706daaa17355_149862cb4af790d9_msg-f:1484043415893042809_149774a86dc8444d_1497396fe06534f4_l00091"></a>00091 <span>///      dispatches (i.e. forwards) to TraverseFoo(Foo *x) where Foo</span>
<a name="14a071ab787fc08a_149e03bdbddaaa27_149e01796338663c_1498785a0356c1d7_14987505ac1199fd_149872c0d1b48f44_1498706daaa17355_149862cb4af790d9_msg-f:1484043415893042809_149774a86dc8444d_1497396fe06534f4_l00092"></a>00092 <span>///      is the dynamic type of *x, which calls WalkUpFromFoo(x) and</span>
<a name="14a071ab787fc08a_149e03bdbddaaa27_149e01796338663c_1498785a0356c1d7_14987505ac1199fd_149872c0d1b48f44_1498706daaa17355_149862cb4af790d9_msg-f:1484043415893042809_149774a86dc8444d_1497396fe06534f4_l00093"></a>00093 <span>///      then recursively visits the child nodes of x.</span>
<a name="14a071ab787fc08a_149e03bdbddaaa27_149e01796338663c_1498785a0356c1d7_14987505ac1199fd_149872c0d1b48f44_1498706daaa17355_149862cb4af790d9_msg-f:1484043415893042809_149774a86dc8444d_1497396fe06534f4_l00094"></a>00094 <span>///      TraverseStmt(Stmt *x) and TraverseType(QualType x) work</span>
<a name="14a071ab787fc08a_149e03bdbddaaa27_149e01796338663c_1498785a0356c1d7_14987505ac1199fd_149872c0d1b48f44_1498706daaa17355_149862cb4af790d9_msg-f:1484043415893042809_149774a86dc8444d_1497396fe06534f4_l00095"></a>00095 <span>///      similarly.</span>
<a name="14a071ab787fc08a_149e03bdbddaaa27_149e01796338663c_1498785a0356c1d7_14987505ac1199fd_149872c0d1b48f44_1498706daaa17355_149862cb4af790d9_msg-f:1484043415893042809_149774a86dc8444d_1497396fe06534f4_l00096"></a>00096 <span>///   2. WalkUpFromFoo(Foo *x) does task #2.  It does not try to visit</span>
<a name="14a071ab787fc08a_149e03bdbddaaa27_149e01796338663c_1498785a0356c1d7_14987505ac1199fd_149872c0d1b48f44_1498706daaa17355_149862cb4af790d9_msg-f:1484043415893042809_149774a86dc8444d_1497396fe06534f4_l00097"></a>00097 <span>///      any child node of x.  Instead, it first calls WalkUpFromBar(x)</span>
<a name="14a071ab787fc08a_149e03bdbddaaa27_149e01796338663c_1498785a0356c1d7_14987505ac1199fd_149872c0d1b48f44_1498706daaa17355_149862cb4af790d9_msg-f:1484043415893042809_149774a86dc8444d_1497396fe06534f4_l00098"></a>00098 <span>///      where Bar is the direct parent class of Foo (unless Foo has</span>
<a name="14a071ab787fc08a_149e03bdbddaaa27_149e01796338663c_1498785a0356c1d7_14987505ac1199fd_149872c0d1b48f44_1498706daaa17355_149862cb4af790d9_msg-f:1484043415893042809_149774a86dc8444d_1497396fe06534f4_l00099"></a>00099 <span>///      no parent), and then calls VisitFoo(x) (see the next list item).</span>
<a name="14a071ab787fc08a_149e03bdbddaaa27_149e01796338663c_1498785a0356c1d7_14987505ac1199fd_149872c0d1b48f44_1498706daaa17355_149862cb4af790d9_msg-f:1484043415893042809_149774a86dc8444d_1497396fe06534f4_l00100"></a>00100 <span>///   3. VisitFoo(Foo *x) does task #3.</span>
<a name="14a071ab787fc08a_149e03bdbddaaa27_149e01796338663c_1498785a0356c1d7_14987505ac1199fd_149872c0d1b48f44_1498706daaa17355_149862cb4af790d9_msg-f:1484043415893042809_149774a86dc8444d_1497396fe06534f4_l00101"></a>00101 <span>///</span>
<a name="14a071ab787fc08a_149e03bdbddaaa27_149e01796338663c_1498785a0356c1d7_14987505ac1199fd_149872c0d1b48f44_1498706daaa17355_149862cb4af790d9_msg-f:1484043415893042809_149774a86dc8444d_1497396fe06534f4_l00102"></a>00102 <span>/// These three method groups are tiered (Traverse* > WalkUpFrom* ></span>
<a name="14a071ab787fc08a_149e03bdbddaaa27_149e01796338663c_1498785a0356c1d7_14987505ac1199fd_149872c0d1b48f44_1498706daaa17355_149862cb4af790d9_msg-f:1484043415893042809_149774a86dc8444d_1497396fe06534f4_l00103"></a>00103 <span>/// Visit*).  A method (e.g. Traverse*) may call methods from the same</span>
<a name="14a071ab787fc08a_149e03bdbddaaa27_149e01796338663c_1498785a0356c1d7_14987505ac1199fd_149872c0d1b48f44_1498706daaa17355_149862cb4af790d9_msg-f:1484043415893042809_149774a86dc8444d_1497396fe06534f4_l00104"></a>00104 <span>/// tier (e.g. other Traverse*) or one tier lower (e.g. WalkUpFrom*).</span>
<a name="14a071ab787fc08a_149e03bdbddaaa27_149e01796338663c_1498785a0356c1d7_14987505ac1199fd_149872c0d1b48f44_1498706daaa17355_149862cb4af790d9_msg-f:1484043415893042809_149774a86dc8444d_1497396fe06534f4_l00105"></a>00105 <span>/// It may not call methods from a higher tier.</span></pre>According to the above statement, the calling relationship between these<br>functions are organized in this way in general:<br><br>Traversal*()<br>{<br>        .......<br>        WalkUpFrom*();<br>        .......<br>}<br><br>WalkUpFrom*()<br>{<br>         .......<br>         Visit*();<br>         .......<br><br>}<br><br>am i right?<br><br>For this statement:<br><pre>00096 <span>///   2. WalkUpFromFoo(Foo *x) does task #2.  It does not try to visit</span>
<a name="14a071ab787fc08a_149e03bdbddaaa27_149e01796338663c_1498785a0356c1d7_14987505ac1199fd_149872c0d1b48f44_1498706daaa17355_149862cb4af790d9_msg-f:1484043415893042809_149774a86dc8444d_1497396fe06534f4_l00097"></a>00097 <span>///      any child node of x.  Instead, it first calls WalkUpFromBar(x)</span>
<a name="14a071ab787fc08a_149e03bdbddaaa27_149e01796338663c_1498785a0356c1d7_14987505ac1199fd_149872c0d1b48f44_1498706daaa17355_149862cb4af790d9_msg-f:1484043415893042809_149774a86dc8444d_1497396fe06534f4_l00098"></a>00098 <span>///      where Bar is the direct parent class of Foo (unless Foo has</span>
<a name="14a071ab787fc08a_149e03bdbddaaa27_149e01796338663c_1498785a0356c1d7_14987505ac1199fd_149872c0d1b48f44_1498706daaa17355_149862cb4af790d9_msg-f:1484043415893042809_149774a86dc8444d_1497396fe06534f4_l00099"></a>00099 <span>///      no parent), and then calls VisitFoo(x) (see the next list item).</span></pre>what do you mean by saying "the direct parent class of Foo"?<br>why i need to visit the parent class before i visit the current class? <br>what is the purpose? Could you please give me a short example?<br><br>Thank you in advance!<br><br>Sincerely<span><font color="#888888"><br>xiaohui<br><br><br><br><br><br><br><br><br><br><br><br><br><br>
</font></span></div><br><br></span>
<br>_______________________________________________<br>
cfe-dev mailing list<br>
<a href="mailto:cfe-dev@cs.uiuc.edu" target="_blank">cfe-dev@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev</a><br>
<br></blockquote></div><br></div>
</div></blockquote>
</div></div></blockquote></div><br></div></div>
</div></blockquote>
______________________________<u></u>_________________<br>
cfe-dev mailing list<br>
<a href="mailto:cfe-dev@cs.uiuc.edu" target="_blank">cfe-dev@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev" target="_blank">http://lists.cs.uiuc.edu/<u></u>mailman/listinfo/cfe-dev</a><br>
</blockquote></div>
</div></div><br>_______________________________________________<br>
cfe-dev mailing list<br>
<a href="mailto:cfe-dev@cs.uiuc.edu" target="_blank">cfe-dev@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev</a><br>
<br></blockquote></div><br></div>
</div></blockquote>
</div></div></blockquote></div><br></div>
</div></blockquote>
</div></div></blockquote></div><br></div>
</div></blockquote>
</div></div></blockquote></div><br></div>
</div></blockquote>
</div></div></blockquote></div><br></div>
</div></blockquote>
</blockquote></div><br></div>
</div></blockquote>
</div></div></blockquote></div><br></div>
</div></blockquote>
</blockquote></div><br></div>