Refine the SlangRS::compile() API.
This makes compile() methods in SlangRS more reasonable. And this is
part of commits for ODR. The SlangRS::compile() now compiles "a group of
RS files" instead of one by one individually.
diff --git a/Android.mk b/Android.mk
index 4986a45..05066e5 100644
--- a/Android.mk
+++ b/Android.mk
@@ -191,6 +191,7 @@
DeclNodes.inc \
DiagnosticCommonKinds.inc \
DiagnosticDriverKinds.inc \
+ DiagnosticFrontendKinds.inc \
DiagnosticSemaKinds.inc \
StmtNodes.inc \
RSCCOptions.inc
diff --git a/llvm-rs-cc.cpp b/llvm-rs-cc.cpp
index f10e548..afd99b4 100644
--- a/llvm-rs-cc.cpp
+++ b/llvm-rs-cc.cpp
@@ -314,75 +314,6 @@
return SaveStringInSet(SavedStrings, OutputFile);
}
-static bool GenerateBitcodeAccessor(const char *InputFile,
- const char *OutputFile,
- const char *PackageName,
- const RSCCOptions &Opts) {
- if ((Opts.mOutputType != Slang::OT_Bitcode) ||
- (Opts.mBitcodeStorage != BCST_JAVA_CODE))
- return true;
-
- RSSlangReflectUtils::BitCodeAccessorContext BCAccessorContext;
- BCAccessorContext.rsFileName = InputFile;
- BCAccessorContext.bcFileName = OutputFile;
- BCAccessorContext.reflectPath = Opts.mJavaReflectionPathBase.c_str();
- BCAccessorContext.packageName = PackageName;
- BCAccessorContext.bcStorage = Opts.mBitcodeStorage;
-
- return RSSlangReflectUtils::GenerateBitCodeAccessor(BCAccessorContext);
-}
-
-// ExecuteCompilation -
-static bool ExecuteCompilation(SlangRS &Compiler,
- const char *InputFile,
- const char *OutputFile,
- const char *BCOutputFile,
- const char *DepOutputFile,
- const RSCCOptions &Opts) {
- std::string RealPackageName;
-
- Compiler.reset();
-
- Compiler.setIncludePaths(Opts.mIncludePaths);
- Compiler.setOutputType(Opts.mOutputType);
- Compiler.allowRSPrefix(Opts.mAllowRSPrefix);
-
- if (!Compiler.setInputSource(InputFile))
- return false;
-
- if (!Compiler.setOutput(OutputFile))
- return false;
-
- if (Opts.mOutputDep) {
- if (!Compiler.setDepOutput(DepOutputFile))
- return false;
-
- Compiler.setDepTargetBC(BCOutputFile);
- Compiler.setAdditionalDepTargets(Opts.mAdditionalDepTargets);
-
- if (Compiler.generateDepFile() > 0)
- return false;
- }
-
- if (Compiler.compile() > 0)
- return false;
-
- if (Opts.mOutputType != Slang::OT_Dependency) {
- if (!Compiler.reflectToJava(Opts.mJavaReflectionPathBase,
- Opts.mJavaReflectionPackageName,
- &RealPackageName))
- return false;
-
- if (!GenerateBitcodeAccessor(InputFile,
- OutputFile,
- RealPackageName.c_str(),
- Opts))
- return false;
- }
-
- return true;
-}
-
int main(int argc, const char **argv) {
std::set<std::string> SavedStrings;
llvm::SmallVector<const char*, 256> ArgVector;
@@ -430,37 +361,53 @@
return 1;
}
- const char *InputFile, *OutputFile, *BCOutputFile = NULL,
- *DepOutputFile = NULL;
+ // Prepare input data for RS compiler.
+ std::list<std::pair<const char*, const char*> > IOFiles;
+ std::list<std::pair<const char*, const char*> > DepFiles;
+
llvm::OwningPtr<SlangRS> Compiler(new SlangRS(Opts.mTriple, Opts.mCPU,
Opts.mFeatures));
for (int i = 0, e = Inputs.size(); i != e; i++) {
- InputFile = Inputs[i];
- OutputFile = DetermineOutputFile(Opts.mOutputDir, InputFile,
- Opts.mOutputType, SavedStrings);
+ const char *InputFile = Inputs[i];
+ const char *OutputFile =
+ DetermineOutputFile(Opts.mOutputDir, InputFile,
+ Opts.mOutputType, SavedStrings);
+
if (Opts.mOutputDep) {
- if (Opts.mOutputType == Slang::OT_Dependency)
- DepOutputFile = OutputFile;
- else
- DepOutputFile = DetermineOutputFile(Opts.mOutputDepDir, InputFile,
- Slang::OT_Dependency, SavedStrings);
+ const char *BCOutputFile, *DepOutputFile;
if (Opts.mOutputType == Slang::OT_Bitcode)
BCOutputFile = OutputFile;
else
BCOutputFile = DetermineOutputFile(Opts.mOutputDepDir, InputFile,
Slang::OT_Bitcode, SavedStrings);
+
+ if (Opts.mOutputType == Slang::OT_Dependency)
+ DepOutputFile = OutputFile;
+ else
+ DepOutputFile = DetermineOutputFile(Opts.mOutputDepDir, InputFile,
+ Slang::OT_Dependency, SavedStrings);
+
+ DepFiles.push_back(std::make_pair(BCOutputFile, DepOutputFile));
}
- if (!ExecuteCompilation(*Compiler,
- InputFile,
- OutputFile,
- BCOutputFile,
- DepOutputFile,
- Opts)) {
- llvm::errs() << Compiler->getErrorMessage();
- return 1;
- }
+
+ IOFiles.push_back(std::make_pair(InputFile, OutputFile));
+ }
+
+ // Let's rock!
+ if (!Compiler->compile(IOFiles,
+ DepFiles,
+ Opts.mIncludePaths,
+ Opts.mAdditionalDepTargets,
+ Opts.mOutputType,
+ Opts.mBitcodeStorage,
+ Opts.mAllowRSPrefix,
+ Opts.mOutputDep,
+ Opts.mJavaReflectionPathBase,
+ Opts.mJavaReflectionPackageName)) {
+ llvm::errs() << Compiler->getErrorMessage();
+ return 1;
}
return 0;
diff --git a/slang_rs.cpp b/slang_rs.cpp
index 98ce3b8..b71e904 100644
--- a/slang_rs.cpp
+++ b/slang_rs.cpp
@@ -18,6 +18,8 @@
#include <cstring>
+#include "clang/Frontend/FrontendDiagnostic.h"
+
#include "clang/Sema/SemaDiagnostic.h"
#include "slang_rs_backend.h"
@@ -39,12 +41,37 @@
ENUM_RS_HEADER()
#undef RS_HEADER_ENTRY
+bool SlangRS::reflectToJava(const std::string &OutputPathBase,
+ const std::string &OutputPackageName,
+ std::string *RealPackageName) {
+ return mRSContext->reflectToJava(OutputPathBase,
+ OutputPackageName,
+ getInputFileName(),
+ getOutputFileName(),
+ RealPackageName);
+}
+
+bool SlangRS::generateBitcodeAccessor(const std::string &OutputPathBase,
+ const std::string &PackageName) {
+ RSSlangReflectUtils::BitCodeAccessorContext BCAccessorContext;
+
+ BCAccessorContext.rsFileName = getInputFileName().c_str();
+ BCAccessorContext.bcFileName = getOutputFileName().c_str();
+ BCAccessorContext.reflectPath = OutputPathBase.c_str();
+ BCAccessorContext.packageName = PackageName.c_str();
+ BCAccessorContext.bcStorage = BCST_JAVA_CODE; // Must be BCST_JAVA_CODE
+
+ return RSSlangReflectUtils::GenerateBitCodeAccessor(BCAccessorContext);
+}
+
+
void SlangRS::initDiagnostic() {
clang::Diagnostic &Diag = getDiagnostics();
- if (!Diag.setDiagnosticGroupMapping(
- "implicit-function-declaration", clang::diag::MAP_ERROR))
- assert(false && "Unable to find option group "
- "implicit-function-declaration");
+ if (Diag.setDiagnosticGroupMapping("implicit-function-declaration",
+ clang::diag::MAP_ERROR))
+ Diag.Report(clang::diag::warn_unknown_warning_option)
+ << "implicit-function-declaration";
+
Diag.setDiagnosticMapping(
clang::diag::ext_typecheck_convert_discards_qualifiers,
clang::diag::MAP_ERROR);
@@ -107,24 +134,84 @@
return;
}
-bool SlangRS::reflectToJava(const std::string &OutputPathBase,
- const std::string &OutputPackageName,
- std::string *RealPackageName) {
- if (mRSContext)
- return mRSContext->reflectToJava(OutputPathBase,
- OutputPackageName,
- getInputFileName(),
- getOutputFileName(),
- RealPackageName);
- else
- return false;
-}
+bool SlangRS::compile(
+ const std::list<std::pair<const char*, const char*> > &IOFiles,
+ const std::list<std::pair<const char*, const char*> > &DepFiles,
+ const std::vector<std::string> &IncludePaths,
+ const std::vector<std::string> &AdditionalDepTargets,
+ Slang::OutputType OutputType, BitCodeStorageType BitcodeStorage,
+ bool AllowRSPrefix, bool OutputDep,
+ const std::string &JavaReflectionPathBase,
+ const std::string &JavaReflectionPackageName) {
+ if (IOFiles.empty())
+ return true;
-void SlangRS::reset() {
- Slang::reset();
- delete mRSContext;
- mRSContext = NULL;
- return;
+ if (OutputDep && (DepFiles.size() != IOFiles.size())) {
+ fprintf(stderr, "SlangRS::compile() : Invalid parameter for output "
+ "dependencies files.\n");
+ return false;
+ }
+
+ std::string RealPackageName;
+
+ const char *InputFile, *OutputFile, *BCOutputFile, *DepOutputFile;
+ std::list<std::pair<const char*, const char*> >::const_iterator
+ IOFileIter = IOFiles.begin(), DepFileIter = DepFiles.begin();
+
+ setIncludePaths(IncludePaths);
+ setOutputType(OutputType);
+ if (OutputDep)
+ setAdditionalDepTargets(AdditionalDepTargets);
+
+ mAllowRSPrefix = AllowRSPrefix;
+
+ for (unsigned i = 0, e = IOFiles.size(); i != e; i++) {
+ InputFile = IOFileIter->first;
+ OutputFile = IOFileIter->second;
+
+ reset();
+
+ if (!setInputSource(InputFile))
+ return false;
+
+ if (!setOutput(OutputFile))
+ return false;
+
+ if (OutputDep) {
+ BCOutputFile = DepFileIter->first;
+ DepOutputFile = DepFileIter->second;
+
+ setDepTargetBC(BCOutputFile);
+
+ if (!setDepOutput(DepOutputFile))
+ return false;
+
+ if (generateDepFile() > 0)
+ return false;
+
+ DepFileIter++;
+ }
+
+ if (Slang::compile() > 0)
+ return false;
+
+ if (OutputType != Slang::OT_Dependency) {
+ if (!reflectToJava(JavaReflectionPathBase,
+ JavaReflectionPackageName,
+ &RealPackageName))
+ return false;
+
+ if ((OutputType == Slang::OT_Bitcode) &&
+ (BitcodeStorage == BCST_JAVA_CODE) &&
+ !generateBitcodeAccessor(JavaReflectionPathBase,
+ RealPackageName.c_str()))
+ return false;
+ }
+
+ IOFileIter++;
+ }
+
+ return true;
}
SlangRS::~SlangRS() {
diff --git a/slang_rs.h b/slang_rs.h
index a8da424..6769744 100644
--- a/slang_rs.h
+++ b/slang_rs.h
@@ -19,6 +19,12 @@
#include "slang.h"
+#include <list>
+#include <vector>
+#include <string>
+
+#include "slang_rs_reflect_utils.h"
+
namespace slang {
class RSContext;
@@ -29,6 +35,14 @@
bool mAllowRSPrefix;
+ // The package name that's really applied will be filled in RealPackageName.
+ bool reflectToJava(const std::string &OutputPathBase,
+ const std::string &OutputPackageName,
+ std::string *RealPackageName);
+
+ bool generateBitcodeAccessor(const std::string &OutputPathBase,
+ const std::string &PackageName);
+
protected:
virtual void initDiagnostic();
virtual void initPreprocessor();
@@ -46,14 +60,41 @@
SlangRS(const std::string &Triple, const std::string &CPU,
const std::vector<std::string> &Features);
- // The package name that's really applied will be filled in RealPackageName.
- bool reflectToJava(const std::string &OutputPathBase,
- const std::string &OutputPackageName,
- std::string *RealPackageName);
-
- virtual void reset();
-
- inline void allowRSPrefix(bool V = true) { mAllowRSPrefix = V; }
+ // Compile bunch of RS files given in the llvm-rs-cc arguments. Return true if
+ // all given input files are successfully compiled without errors.
+ //
+ // @IOFiles - List of pairs of <input file path, output file path>.
+ //
+ // @DepFiles - List of pairs of <output dep. file path, dependent bitcode
+ // target>. If @OutputDep is true, this parameter must be given
+ // with the same number of pairs given in @IOFiles.
+ //
+ // @IncludePaths - User-defined include path.
+ //
+ // @AdditionalDepTargets - User-defined files added to the dependencies.
+ //
+ // @OutputType - See Slang::OutputType.
+ //
+ // @BitcodeStorage - See BitCodeStorageType in slang_rs_reflect_util.cpp.
+ //
+ // @AllowRSPrefix - true to allow user-defined function prefixed with 'rs'.
+ //
+ // @OutputDep - true if output dependecies file.
+ //
+ // @JavaReflectionPathBase - The path base for storing reflection files.
+ //
+ // @JavaReflectionPackageName - The package name given by user in command
+ // line. This may override the package name
+ // specified in the .rs using #pragma.
+ //
+ bool compile(const std::list<std::pair<const char*, const char*> > &IOFiles,
+ const std::list<std::pair<const char*, const char*> > &DepFiles,
+ const std::vector<std::string> &IncludePaths,
+ const std::vector<std::string> &AdditionalDepTargets,
+ Slang::OutputType OutputType, BitCodeStorageType BitcodeStorage,
+ bool AllowRSPrefix, bool OutputDep,
+ const std::string &JavaReflectionPathBase,
+ const std::string &JavaReflectionPackageName);
virtual ~SlangRS();
};