#include <clang/Basic/Diagnostic.h>              // DiagnosticsEngine
#include <clang/Basic/SourceLocation.h>          // FileID
#include <clang/Basic/SourceManager.h>           // SourceManager
#include <clang/Frontend/ASTUnit.h>              // ASTUnit
#include <clang/Frontend/DiagnosticOptions.h>    // DiagnosticOptions
#include <clang/Frontend/TextDiagnosticPrinter.h>// TextDiagnosticPrinter

#include <cassert>
#include <cstdlib>
#include <ctime>
#include <memory>

using namespace clang;

int main(int argc, char** argv) {
    TextDiagnosticPrinter clang_diag_printer(llvm::errs(), DiagnosticOptions());
    llvm::IntrusiveRefCntPtr<DiagnosticIDs> clang_diag_ids(new DiagnosticIDs);
    llvm::IntrusiveRefCntPtr<DiagnosticsEngine> clang_diags(
        new DiagnosticsEngine(clang_diag_ids, &clang_diag_printer,
                              /*owns printer*/false));
    FileSystemOptions clang_fs_options;

    for (int i = 1; i < argc; ++i) {
        const char *clang_ast_filename = argv[i];

        std::auto_ptr<ASTUnit> clang_ast(ASTUnit::LoadFromASTFile(
            clang_ast_filename, clang_diags, clang_fs_options));
        if (!clang_ast.get()) {
            std::fprintf(stderr, "error: Failed to load %s\n",
                         clang_ast_filename);
            return 2;
        }
        ASTContext& clang_ast_ctx(clang_ast->getASTContext());
        const SourceManager &source_manager(clang_ast_ctx.getSourceManager());

        assert(clang_ast->isMainFileAST());
        clang::FileID main_file_id = source_manager.getMainFileID();
        assert(!main_file_id.isInvalid());
        const clang::FileEntry *main_file_entry =
            source_manager.getFileEntryForID(main_file_id);
        assert(main_file_entry);
        time_t main_file_mod_time = main_file_entry->getModificationTime();
        std::printf("main file: %s\n", main_file_entry->getName());
        std::printf("    Size: %lu\n", (unsigned long)main_file_entry->getSize());
        std::printf("    Time: %lu: %s", (unsigned long)main_file_mod_time,
                    std::ctime(&main_file_mod_time));
        std::printf("    Mode: 0%lo\n", main_file_entry->getFileMode());
    }

    return 0;
}
