i wonder that whether it is possible to restore the preprocessed tokens when <br />i output the AST.<br /><br />for example, this is the input file:<br /><br />#define  COND<br /><br />void test(int var)<br />{<br />#ifdef COND<br />  var = 1;<br />#else<br />  var = 2;<br />#endif<br />}<br /><br />when the parser builds the AST, we will lose some parts of the code,<br />so is it possible to output the AST which is the same with the input?  <br /><br /><br /><br /><span>On 12/01/14, <b class="name">Nikola Smiljanic </b> <popizdeh@gmail.com> wrote:</span><blockquote cite="mid:CAGq7tnNDSWE+JApfYcuB_XuwomR1s74oMu5mSJ0zVfsxAxLRaw@mail.gmail.com" class="iwcQuote" style="border-left: 1px solid #00F; padding-left: 13px; margin-left: 0;" type="cite"><div class="mimepart text html"><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">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">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">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">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">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">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">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">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">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">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">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">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">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">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">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">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">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">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">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">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" target="1"></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" target="1"></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" target="1"></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" target="1"></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" target="1"></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" target="1"></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" target="1"></a>00095 <span>///      similarly.</span>
<a name="14a071ab787fc08a_149e03bdbddaaa27_149e01796338663c_1498785a0356c1d7_14987505ac1199fd_149872c0d1b48f44_1498706daaa17355_149862cb4af790d9_msg-f:1484043415893042809_149774a86dc8444d_1497396fe06534f4_l00096" target="1"></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" target="1"></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" target="1"></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" target="1"></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" target="1"></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" target="1"></a>00101 <span>///</span>
<a name="14a071ab787fc08a_149e03bdbddaaa27_149e01796338663c_1498785a0356c1d7_14987505ac1199fd_149872c0d1b48f44_1498706daaa17355_149862cb4af790d9_msg-f:1484043415893042809_149774a86dc8444d_1497396fe06534f4_l00102" target="1"></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" target="1"></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" target="1"></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" target="1"></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" target="1"></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" target="1"></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" target="1"></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">cfe-dev@cs.uiuc.edu</a><br />
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev" target="1">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">cfe-dev@cs.uiuc.edu</a><br />
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev" target="1">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">cfe-dev@cs.uiuc.edu</a><br />
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev" target="1">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>
</div></blockquote>