Odd diagnostics

I’m seeing some strange results using a RecursiveASTVisitor on some C code. The following code compiles fine with clang:

static __inline unsigned int
__bswap_32 (unsigned int __bsx)
{
return __builtin_bswap32 (__bsx);
}

But I get the following diagnostic when calling ParseAST:

C:/BUG/builtin.c:4:10: error: use of unknown builtin ‘__builtin_bswap32’

return __builtin_bswap32 (__bsx);

^

It seems odd that I should get this error, as __builtin_bswap32() is supported. Any idea why?

Another interesting thing - I get the following results for each of the getDiagnostics() calls:
hasUncompilableErrorOccurred() = True

hasUnrecoverableErrorOccurred() = False

hasFatalErrorOccurred() = False

hasErrorOccurred() = True

As a point of comparison, for the following code:

int foo()
{
retrun 42; // Typo on return
}

I get:

C:/Src/cp.PP/BUG/bug.c:3:3: error: use of undeclared identifier ‘retrun’

retrun 42;

^

hasUncompilableErrorOccurred() = True

hasUnrecoverableErrorOccurred() = True

hasFatalErrorOccurred() = False

hasErrorOccurred() = True

For code that generates only a warning, the above 4 calls all return False.

I guess I’m not sure what the difference is between hasUncompilableErrorOccurred() and
hasErrorOccurred(), or what exactly the other 2 functions do. Any enlightenment there?

This is with:

clang version 3.7.0 (trunk 230884)
Target: i686-pc-windows-gnu
Thread model: posix

Thanks,

Robert

I'm seeing some strange results using a RecursiveASTVisitor on some C
code. The following code compiles fine with clang:

static __inline unsigned int
__bswap_32 (unsigned int __bsx)
{
  return __builtin_bswap32 (__bsx);
}

But I get the following diagnostic when calling ParseAST:

C:/BUG/builtin.c:4:10: error: use of unknown builtin '__builtin_bswap32'

return __builtin_bswap32 (__bsx);

         ^

It seems odd that I should get this error, as __builtin_bswap32() is
supported. Any idea why?

If you're calling ParseAST yourself, you're likely missing quite a few of
the necessary set up steps; in this case, the missing step is a call to
InitializeBuiltins on the preprocessor's Builtins::Context object. It's
generally better to use the clang Frontend library to set up and initialize
the various components of the compiler for you; see ToolInvocation and
ClangTool in the Tooling library for some prebuilt wrappers to make this
easier.

Another interesting thing - I get the following results for each of the
getDiagnostics() calls:
hasUncompilableErrorOccurred() = True

hasUnrecoverableErrorOccurred() = False

hasFatalErrorOccurred() = False

hasErrorOccurred() = True

As a point of comparison, for the following code:

int foo()
{
  retrun 42; // Typo on return
}

I get:

C:/Src/cp.PP/BUG/bug.c:3:3: error: use of undeclared identifier 'retrun'

   retrun 42;

   ^

hasUncompilableErrorOccurred() = True

hasUnrecoverableErrorOccurred() = True

hasFatalErrorOccurred() = False

hasErrorOccurred() = True

For code that generates only a warning, the above 4 calls all return False.

I guess I'm not sure what the difference is between hasUncompilableErrorOccurred()
and
hasErrorOccurred(), or what exactly the other 2 functions do. Any
enlightenment there?

In order from most specific to most general:

hasFatalErrorOccurred() indicates whether we've emitted any "fatal error:"
diagnostics. These are diagnostics that indicate a problem sufficiently
severe that we don't think we could continue to emit correct diagnostics
after emitting one. (For instance: missing a file named by #include, or
reached the template instantiation depth limit.)

hasUnrecoverableErrorOccurred indicates whether we think the AST is not
essentially correct -- whether tools performing automated analysis and
refactorings might get the wrong answer. If an unrecoverable error occurs,
we turn off CFG-based analyses and the like. This excludes errors upgraded
from warnings, and also "warning-like" errors for ARC issues, functions
marked "unavailable", and so on.

hasUncompilableErrorOccurred indicates whether we think we could generate
correct code from the AST we built. This excludes errors upgraded from
warnings, but includes ARC issues and uses of unavailable functions (for
which we could analyse the program, but where we couldn't generate working
code).

hasErrorOccurred() indicates if we've emitted any "error:" diagnostics, and
thus whether the compilation should fail.

Thanks for the great answer! I’ll look into the Tooling library.

As to the diagnostics, those are great and clear descriptions. It’s a shame they aren’t in the documentation itself.