pre-processor object macros and literals

If a pre-procesor object-like macro is used to define a literal value, such as in the example below (#define STEVE 345), is there any way to retrieve the name ("STEVE") from the AST? In the example, I have printed the AST, and the right-hand side of the assignment statement is represented as:

              <IntegerLiteral file="f2" line="2" col="15" type="_1F" value="345"/>

The line and column numbers do refer to the line with the #define, but the name "STEVE" does not seem to be stored anywhere.

-Steve

alban:tmp siegel$ cat exp.c

#define STEVE 345

void foo() {
  int x = STEVE;
}

alban:tmp siegel$ clang -cc1 -ast-print-xml exp.c

alban:tmp siegel$ cat exp.xml
<?xml version="1.0"?>
<CLANG_XML>
  <TranslationUnit>
    <Typedef id="_1" context="_2" name="__int128_t" type="_4"/>
    <Typedef id="_5" context="_2" name="__uint128_t" type="_7"/>
    <Record id="_8" file="f1" line="98" col="16" context="_2" name="__va_list_tag" type="_9">
      <Field id="_A" file="f1" line="98" col="42" context="_8" name="gp_offset" type="_C" access="public"/>
      <Field id="_D" file="f1" line="98" col="63" context="_8" name="fp_offset" type="_C" access="public"/>
      <Field id="_E" file="f1" line="98" col="81" context="_8" name="overflow_arg_area" type="_10" access="public"/>
      <Field id="_13" file="f1" line="98" col="107" context="_8" name="reg_save_area" type="_10" access="public"/>
    </Record>
    <Typedef id="_14" file="f1" line="98" col="123" context="_2" name="__va_list_tag" type="_9"/>
    <Typedef id="_16" file="f1" line="98" col="159" context="_2" name="__builtin_va_list" type="_18"/>
    <Function id="_1B" file="f2" line="4" col="6" context="_2" name="foo" type="_12" function_type="_1C" num_args="0">
      <Body>
        <CompoundStmt file="f2" line="4" col="12" endline="6" endcol="1" num_stmts="1">
          <DeclStmt file="f2" line="5" col="3" endcol="16">
            <Var id="_1D" file="f2" line="5" col="7" context="_1B" name="x" type="_1F">
              <IntegerLiteral file="f2" line="2" col="15" type="_1F" value="345"/>
            </Var>
          </DeclStmt>
        </CompoundStmt>
      </Body>
    </Function>
  </TranslationUnit>
  <ReferenceSection>
    <Types>
      <FunctionNoProtoType id="_1C"/>
      <FundamentalType kind="__uint128_t" id="_7"/>
      <FundamentalType kind="__int128_t" id="_4"/>
      <FundamentalType kind="unsigned int" id="_C"/>
      <PointerType type="_12" id="_10"/>
      <Typedef type="_9" name="__va_list_tag" context="_2" id="_1A"/>
      <ArrayType type="_1A" size="1" id="_18"/>
      <FundamentalType kind="int" id="_1F"/>
      <Record name="__va_list_tag" kind="struct" context="_2" id="_9"/>
      <FundamentalType kind="void" id="_12"/>
    </Types>
    <Contexts>
      <Record id="_8" name="__va_list_tag" type="_9" context="_2"/>
      <TranslationUnit id="_2"/>
      <Function id="_1B" name="foo" type="_1C" context="_2"/>
    </Contexts>
    <Files>
      <File id="f1" name="&amp;lt;built-in&amp;gt;"/>
      <File id="f2" name="exp.c"/>
    </Files>
  </ReferenceSection>
</CLANG_XML>
alban:tmp siegel$

This information can be extracted from Clang’s in-memory AST, but it is not part of the XML output. In the in-memory AST, the source location of the integer literal will point into a macro instantiation, which you can map back to the tokens in the source code.

  • Doug