This is based on Clang 2.9. I haven't tested with 3.0, but I briefly looked at the 3.0 source and I don't see anything that would have changed this...
When loading an AST file produced with something like:
clang -emit-ast file.c
with ASTUnit::LoadFromASTFile(), calling ASTUnit::isMainFileAST() will return true. However, the SourceManager instance will not have a main file ID as determined by SourceManager::getMainFileID() - this returns an invalid FileID instance.
ASTReader will call SourceManager::setPreambleFileID() if the AST file is a pre-compiled preamble, but there are no corresponding conditions under which SourceManager::createMainFileID() will be called. Note that SourceManager::setPreambleFileID() and SourceManager::createMainFileID() are mutually exclusive and both set SourceManager::MainFileID in Clang 2.9. In Clang 3.0, SourceManager has separate fields and these methods are not mutually exclusive.
Does this sound like the way things should be? I would expect ASTUnit::isMainFileAST() returning true to imply that SourceManager::getMainFileID() should return a valid FileID.
Basically, it seems like another case like the following from the Clang 3.0 ASTReader.cpp is needed:
// If this AST file is a precompiled preamble, then set the preamble file ID
// of the source manager to the file source file from which the preamble was
// built.
if (Type == MK_Preamble) {
if (!OriginalFileID.isInvalid()) {
OriginalFileID = FileID::get(ModuleMgr.getPrimaryModule().SLocEntryBaseID