Refactor a bit & -M bug fixed.
1. Use llvm::tool_output_file instead of llvm::raw_stream. The former
can automatically deleted itself from filesystem once the compilation failed.
2. Fix -M bug which causes segfault previously.
diff --git a/llvm-rs-cc.cpp b/llvm-rs-cc.cpp
index 03fdd45..ec6362e 100644
--- a/llvm-rs-cc.cpp
+++ b/llvm-rs-cc.cpp
@@ -205,7 +205,9 @@
}
}
- if (Opts.mOutputType != Slang::OT_Bitcode)
+ if (Opts.mOutputDep &&
+ ((Opts.mOutputType != Slang::OT_Bitcode) &&
+ (Opts.mOutputType != Slang::OT_Dependency)))
Diags.Report(clang::diag::err_drv_argument_not_allowed_with)
<< Args->getLastArg(OPT_M_Group)->getAsString(*Args)
<< Args->getLastArg(OPT_Output_Type_Group)->getAsString(*Args);
@@ -318,6 +320,7 @@
static bool ExecuteCompilation(SlangRS &Compiler,
const char *InputFile,
const char *OutputFile,
+ const char *BCOutputFile,
const char *DepOutputFile,
const RSCCOptions &Opts) {
std::string RealPackageName;
@@ -338,8 +341,7 @@
if (!Compiler.setDepOutput(DepOutputFile))
return false;
- if (Opts.mOutputType != Slang::OT_Dependency)
- Compiler.setDepTargetBC(OutputFile);
+ Compiler.setDepTargetBC(BCOutputFile);
Compiler.setAdditionalDepTargets(Opts.mAdditionalDepTargets);
if (Compiler.generateDepFile() > 0)
@@ -412,7 +414,8 @@
return 1;
}
- const char *InputFile, *OutputFile, *DepOutputFile = NULL;
+ const char *InputFile, *OutputFile, *BCOutputFile = NULL,
+ *DepOutputFile = NULL;
llvm::OwningPtr<SlangRS> Compiler(new SlangRS(Opts.mTriple, Opts.mCPU,
Opts.mFeatures));
@@ -426,10 +429,17 @@
else
DepOutputFile = DetermineOutputFile(Opts.mOutputDepDir, InputFile,
Slang::OT_Dependency, SavedStrings);
+
+ if (Opts.mOutputType == Slang::OT_Bitcode)
+ BCOutputFile = OutputFile;
+ else
+ BCOutputFile = DetermineOutputFile(Opts.mOutputDepDir, InputFile,
+ Slang::OT_Bitcode, SavedStrings);
}
if (!ExecuteCompilation(*Compiler,
InputFile,
OutputFile,
+ BCOutputFile,
DepOutputFile,
Opts)) {
llvm::errs() << Compiler->getErrorMessage();
diff --git a/slang.cpp b/slang.cpp
index ba4c861..78428f9 100644
--- a/slang.cpp
+++ b/slang.cpp
@@ -106,6 +106,29 @@
// bcc.cpp)
const llvm::StringRef Slang::PragmaMetadataName = "#pragma";
+static inline llvm::tool_output_file *OpenOutputFile(const char *OutputFile,
+ unsigned Flags,
+ std::string* Error,
+ clang::Diagnostic* Diag) {
+ assert((OutputFile != NULL) && (Error != NULL) && (Diag != NULL) &&
+ "Invalid parameter!");
+
+ llvm::sys::Path OutputFilePath(OutputFile);
+
+ if (SlangUtils::CreateDirectoryWithParents(OutputFilePath.getDirname(),
+ Error)) {
+ llvm::tool_output_file *F =
+ new llvm::tool_output_file(OutputFile, *Error, Flags);
+ if (F != NULL)
+ return F;
+ }
+
+ // Report error here.
+ Diag->Report(clang::diag::err_fe_error_opening) << OutputFile << *Error;
+
+ return NULL;
+}
+
void Slang::GlobalInitialization() {
if (!GlobalInitialized) {
// We only support x86, x64 and ARM target
@@ -289,31 +312,24 @@
bool Slang::setOutput(const char *OutputFile) {
llvm::sys::Path OutputFilePath(OutputFile);
std::string Error;
+ llvm::tool_output_file *OS = NULL;
switch (mOT) {
case OT_Dependency:
case OT_Assembly:
case OT_LLVMAssembly: {
- if (!SlangUtils::CreateDirectoryWithParents(OutputFilePath.getDirname(),
- &Error))
- mDiagnostics->Report(clang::diag::err_fe_error_opening) << OutputFile
- << Error;
- mOS.reset(new llvm::tool_output_file(OutputFile, Error, 0));
+ OS = OpenOutputFile(OutputFile, 0, &Error, mDiagnostics.getPtr());
break;
}
case OT_Nothing: {
- mOS.reset();
break;
}
case OT_Object:
case OT_Bitcode: {
- if (!SlangUtils::CreateDirectoryWithParents(OutputFilePath.getDirname(),
- &Error))
- mDiagnostics->Report(clang::diag::err_fe_error_opening) << OutputFile
- << Error;
- mOS.reset(new llvm::tool_output_file(OutputFile,
- Error,
- llvm::raw_fd_ostream::F_Binary));
+ OS = OpenOutputFile(OutputFile,
+ llvm::raw_fd_ostream::F_Binary,
+ &Error,
+ mDiagnostics.getPtr());
break;
}
default: {
@@ -321,12 +337,10 @@
}
}
- if (!Error.empty()) {
- mOS.reset();
- mDiagnostics->Report(clang::diag::err_fe_error_opening) << OutputFile
- << Error;
+ if (!Error.empty())
return false;
- }
+
+ mOS.reset(OS);
mOutputFileName = OutputFile;
@@ -337,18 +351,9 @@
llvm::sys::Path OutputFilePath(OutputFile);
std::string Error;
- if (!SlangUtils::CreateDirectoryWithParents(OutputFilePath.getDirname(),
- &Error))
- mDiagnostics->Report(clang::diag::err_fe_error_opening) << OutputFile
- << Error;
- mDOS.reset(new llvm::raw_fd_ostream(OutputFile, Error, 0));
-
- if (!Error.empty()) {
- mDOS.reset();
- mDiagnostics->Report(clang::diag::err_fe_error_opening) << OutputFile
- << Error;
+ mDOS.reset(OpenOutputFile(OutputFile, 0, &Error, mDiagnostics.getPtr()));
+ if (!Error.empty() || (mDOS.get() == NULL))
return false;
- }
mDepOutputFileName = OutputFile;
@@ -361,21 +366,21 @@
if (mDOS.get() == NULL)
return 1;
- /* Initialize options for generating dependency file */
+ // Initialize options for generating dependency file
clang::DependencyOutputOptions DepOpts;
DepOpts.IncludeSystemHeaders = 1;
DepOpts.OutputFile = mDepOutputFileName;
DepOpts.Targets = mAdditionalDepTargets;
DepOpts.Targets.push_back(mDepTargetBCFileName);
- /* Per-compilation needed initialization */
+ // Per-compilation needed initialization
createPreprocessor();
AttachDependencyFileGen(*mPP.get(), DepOpts);
- /* Inform the diagnostic client we are processing a source file */
+ // Inform the diagnostic client we are processing a source file
mDiagClient->BeginSourceFile(LangOpts, mPP.get());
- /* Go through the source file (no operations necessary) */
+ // Go through the source file (no operations necessary)
clang::Token Tok;
mPP->EnterMainSourceFile();
do {
@@ -384,8 +389,13 @@
mPP->EndSourceFile();
- /* Clean up after compilation */
+ // Declare success if no error
+ if (mDiagnostics->getNumErrors() == 0)
+ mDOS->keep();
+
+ // Clean up after compilation
mPP.reset();
+ mDOS.reset();
return mDiagnostics->getNumErrors();
}
@@ -400,7 +410,7 @@
createPreprocessor();
createASTContext();
- mBackend.reset(createBackend(CodeGenOpts, mOS.take(), mOT));
+ mBackend.reset(createBackend(CodeGenOpts, mOS.get(), mOT));
// Inform the diagnostic client we are processing a source file
mDiagClient->BeginSourceFile(LangOpts, mPP.get());
@@ -408,13 +418,18 @@
// The core of the slang compiler
ParseAST(*mPP, mBackend.get(), *mASTContext);
+ // Inform the diagnostic client we are done with previous source file
+ mDiagClient->EndSourceFile();
+
+ // Declare success if no error
+ if (mDiagnostics->getNumErrors() == 0)
+ mOS->keep();
+
// The compilation ended, clear
mBackend.reset();
mASTContext.reset();
mPP.reset();
-
- // Inform the diagnostic client we are done with previous source file
- mDiagClient->EndSourceFile();
+ mOS.reset();
return mDiagnostics->getNumErrors();
}
diff --git a/slang.h b/slang.h
index 67f8560..a614135 100644
--- a/slang.h
+++ b/slang.h
@@ -15,7 +15,7 @@
#include "slang_diagnostic_buffer.h"
namespace llvm {
- class raw_ostream;
+ class tool_output_file;
}
namespace clang {
@@ -100,9 +100,9 @@
OutputType mOT;
// Output stream
- llvm::OwningPtr<llvm::raw_ostream> mOS;
+ llvm::OwningPtr<llvm::tool_output_file> mOS;
// Dependency output stream
- llvm::OwningPtr<llvm::raw_ostream> mDOS;
+ llvm::OwningPtr<llvm::tool_output_file> mDOS;
std::vector<std::string> mIncludePaths;