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