<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>