#include "clang/Frontend/Utils.h"
#include "clang/Basic/SourceManager.h"
+#include "clang/Frontend/FrontendDiagnostic.h"
#include "clang/Lex/Preprocessor.h"
-#include <cstdio>
+#include "llvm/Support/raw_ostream.h"
using namespace clang;
namespace {
class HeaderIncludesCallback : public PPCallbacks {
SourceManager &SM;
- FILE *OutputFile;
+ llvm::raw_ostream *OutputFile;
unsigned CurrentIncludeDepth;
bool HasProcessedPredefines;
bool OwnsOutputFile;
public:
HeaderIncludesCallback(const Preprocessor *PP, bool ShowAllHeaders_,
- FILE *OutputFile_, bool OwnsOutputFile_)
+ llvm::raw_ostream *OutputFile_, bool OwnsOutputFile_)
: SM(PP->getSourceManager()), OutputFile(OutputFile_),
CurrentIncludeDepth(0), HasProcessedPredefines(false),
OwnsOutputFile(OwnsOutputFile_), ShowAllHeaders(ShowAllHeaders_) {}
~HeaderIncludesCallback() {
if (OwnsOutputFile)
- fclose(OutputFile);
+ delete OutputFile;
}
virtual void FileChanged(SourceLocation Loc, FileChangeReason Reason,
void clang::AttachHeaderIncludeGen(Preprocessor &PP, bool ShowAllHeaders,
llvm::StringRef OutputPath) {
- FILE *OutputFile;
- bool OwnsOutputFile;
+ llvm::raw_ostream *OutputFile = &llvm::errs();
+ bool OwnsOutputFile = false;
// Open the output file, if used.
- if (OutputPath.empty()) {
- OutputFile = stderr;
- OwnsOutputFile = false;
- } else {
- OutputFile = fopen(OutputPath.str().c_str(), "a");
- OwnsOutputFile = true;
+ if (!OutputPath.empty()) {
+ std::string Error;
+ llvm::raw_fd_ostream *OS = new llvm::raw_fd_ostream(
+ OutputPath.str().c_str(), Error, llvm::raw_fd_ostream::F_Append);
+ if (!Error.empty()) {
+ PP.getDiagnostics().Report(
+ clang::diag::warn_fe_cc_print_header_failure) << Error;
+ delete OS;
+ } else {
+ OS->SetUnbuffered();
+ OS->SetUseAtomicWrites(true);
+ OutputFile = OS;
+ OwnsOutputFile = true;
+ }
}
PP.addPPCallbacks(new HeaderIncludesCallback(&PP, ShowAllHeaders,
Msg += Filename;
Msg += '\n';
- fwrite(Msg.data(), Msg.size(), 1, OutputFile);
+ OutputFile->write(Msg.data(), Msg.size());
}
}
-