2

Sample code:

int f_i32() {
  __asm {
    mov eax, 1
    mov edx, 1
  }
}

AST for this code:

enter image description here

I get only MSASMStmt in AST and nothing from inside it.

I want to extract locations of ASM statements inside __asm block. How can get those with clang frontend and lib-tooling library?

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
Hemant
  • 767
  • 6
  • 20
  • Note that clang `-fasm-block` *doesn't* support leaving a return value in EAX and then falling off the end of a non-void function. Only MSVC itself supports that. It just inlines redundantly into `return f_i32() + f_i32()`. https://godbolt.org/g/9dRCLM. (But it's not optimized away like a GNU C asm statement that isn't `volatile` (implicitly or explictly).) – Peter Cordes Jun 06 '18 at 06:47
  • This isn't limited to MSVC-style asm blocks (`clang -fasm-blocks`). With a GNU C inline-asm statement like `asm("mov $1, %0" : "=r"(ret));`, the AST only includes something about the output operand, not the asm template. `GCCAsmStmt`...; Godbolt has an option for clang AST output: https://godbolt.org/g/ZsWXQb. Note that it optimizes much better, because it's non-volatile so the compiler can run it once then add the output to itself. MSVC-style asm is pretty crap; I wouldn't recommend it if you need efficiency. – Peter Cordes Jun 06 '18 at 06:56
  • I am interested in only the static locations of statements like 'mov eax, 1' from source code. How can I get it with AST? – Hemant Jun 06 '18 at 07:00
  • No idea, sorry, otherwise I'd post an answer. Just wanted to point out that your example function is useless and also undefined behaviour with clang. – Peter Cordes Jun 06 '18 at 07:01
  • Ok. But is part of code analysis and needs executable LOC. – Hemant Jun 06 '18 at 07:04

1 Answers1

1

Found the answer.

Idea is to iterate the ASM tokens returned by MSAsmStmt and get the location for each token.

    size_t asmTokens = asmStmt->getNumAsmToks();
    clang::Token* tokens = asmStmt->getAsmToks();
    for (size_t i = 0; i < asmTokens; ++i) {
        clang::Token token = tokens[i];
        size_t tokloc = SourceManager.getExpansionLineNumber(token.getLocation());
    }
Hemant
  • 767
  • 6
  • 20