diff options
author | Jean-Luc Brouillet <jeanluc@google.com> | 2015-06-14 09:37:33 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2015-06-14 09:37:34 +0000 |
commit | b2f95965a51a8c891e17f9d55aabb1ee990b5065 (patch) | |
tree | 36cf923937e843026ea9dac638878fe6ed2dcff8 | |
parent | 7332039f270d68c6e82012875833d9fe5e76ee66 (diff) | |
parent | 666b0a7711c10ea31008302495c6b25d1bd0729b (diff) | |
download | android_frameworks_compile_slang-b2f95965a51a8c891e17f9d55aabb1ee990b5065.tar.gz android_frameworks_compile_slang-b2f95965a51a8c891e17f9d55aabb1ee990b5065.tar.bz2 android_frameworks_compile_slang-b2f95965a51a8c891e17f9d55aabb1ee990b5065.zip |
Merge "Enable warnings in llvm_rs_cc" into mnc-dev
-rw-r--r-- | RSCCOptions.td | 2 | ||||
-rw-r--r-- | llvm-rs-cc.cpp | 112 | ||||
-rw-r--r-- | rs_cc_options.cpp | 320 | ||||
-rw-r--r-- | rs_cc_options.h | 11 | ||||
-rw-r--r-- | slang.cpp | 188 | ||||
-rw-r--r-- | slang.h | 54 | ||||
-rw-r--r-- | slang_diagnostic_buffer.cpp | 36 | ||||
-rw-r--r-- | slang_diagnostic_buffer.h | 21 | ||||
-rw-r--r-- | tests/F_unknown_function/stderr.txt.expect | 1 | ||||
-rw-r--r-- | tests/F_unknown_function/stdout.txt.expect (renamed from tests/P_unknown_function/stdout.txt.expect) | 0 | ||||
-rw-r--r-- | tests/F_unknown_function/unknown_function.rs (renamed from tests/P_unknown_function/unknown_function.rs) | 0 | ||||
-rw-r--r-- | tests/F_unknown_function/zzz.rs (renamed from tests/P_unknown_function/zzz.rs) | 0 | ||||
-rw-r--r-- | tests/P_unknown_function/stderr.txt.expect | 1 | ||||
-rw-r--r-- | tests/P_warnings/stderr.txt.expect | 8 | ||||
-rw-r--r-- | tests/P_warnings/warnings.rs | 6 | ||||
-rw-r--r-- | tests/P_warnings_deprecated/deprecated.rs | 11 | ||||
-rw-r--r-- | tests/P_warnings_deprecated/stderr.txt.expect | 4 | ||||
-rw-r--r-- | tests/P_warnings_deprecated/stdout.txt.expect | 0 |
18 files changed, 358 insertions, 417 deletions
diff --git a/RSCCOptions.td b/RSCCOptions.td index 1277c3a..96cdaa8 100644 --- a/RSCCOptions.td +++ b/RSCCOptions.td @@ -91,7 +91,7 @@ def rs_package_name : Separate<["-"], "rs-package-name">, HelpText<"package name for referencing RS classes">; def rs_package_name_EQ : Joined<["-"], "rs-package-name=">, Alias<rs_package_name>; -def W : Joined<["-"], "W">; +def W : Joined<["-"], "W">, HelpText<"Enable the specified warning">; def w : Flag<["-"], "w">, HelpText<"Suppress all warnings">; //===----------------------------------------------------------------------===// diff --git a/llvm-rs-cc.cpp b/llvm-rs-cc.cpp index fea818b..c860c9e 100644 --- a/llvm-rs-cc.cpp +++ b/llvm-rs-cc.cpp @@ -17,6 +17,8 @@ #include "clang/Basic/DiagnosticOptions.h" #include "clang/Driver/DriverDiagnostic.h" #include "clang/Driver/Options.h" +#include "clang/Frontend/CompilerInvocation.h" +#include "clang/Frontend/FrontendDiagnostic.h" #include "clang/Frontend/TextDiagnosticPrinter.h" #include "clang/Frontend/Utils.h" @@ -24,11 +26,11 @@ #include "llvm/ADT/IntrusiveRefCntPtr.h" #include "llvm/Option/OptTable.h" -#include "llvm/Support/CommandLine.h" #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Path.h" #include "llvm/Support/raw_ostream.h" +#include "llvm/Support/Signals.h" #include "llvm/Target/TargetMachine.h" #include "rs_cc_options.h" @@ -133,20 +135,15 @@ typedef std::list<std::pair<const char*, const char*> > NamePairList; * 32-bit and 64-bit bitcode outputs to be included in the final reflected * source code that is emitted. */ -static int compileFiles(NamePairList *IOFiles, NamePairList *IOFiles32, +static void makeFileList(NamePairList *IOFiles, NamePairList *DepFiles, const llvm::SmallVector<const char*, 16> &Inputs, slang::RSCCOptions &Opts, - clang::DiagnosticsEngine *DiagEngine, slang::DiagnosticBuffer *DiagClient, StringSet *SavedStrings) { - NamePairList DepFiles; std::string PathSuffix = ""; - bool CompileSecondTimeFor64Bit = false; - // In our mixed 32/64-bit path, we need to suffix our files differently for // both 32-bit and 64-bit versions. if (Opts.mEmit3264) { if (Opts.mBitWidth == 64) { PathSuffix = "bc64"; - CompileSecondTimeFor64Bit = true; } else { PathSuffix = "bc32"; } @@ -172,18 +169,11 @@ static int compileFiles(NamePairList *IOFiles, NamePairList *IOFiles32, OutputFile = DepOutputFile; } - DepFiles.push_back(std::make_pair(BCOutputFile, DepOutputFile)); + DepFiles->push_back(std::make_pair(BCOutputFile, DepOutputFile)); } IOFiles->push_back(std::make_pair(InputFile, OutputFile)); } - - std::unique_ptr<slang::Slang> Compiler(new slang::Slang()); - Compiler->init(Opts.mBitWidth, DiagEngine, DiagClient); - int CompileFailed = !Compiler->compile(*IOFiles, *IOFiles32, DepFiles, Opts); - // We suppress warnings (via reset) if we are doing a second compilation. - Compiler->reset(CompileSecondTimeFor64Bit); - return CompileFailed; } #define str(s) #s @@ -205,74 +195,94 @@ static void llvm_rs_cc_VersionPrinter() { #undef wrap_str #undef str -int main(int argc, const char **argv) { - llvm::llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. +static void LLVMErrorHandler(void *UserData, const std::string &Message, + bool GenCrashDialog) { + clang::DiagnosticsEngine *DiagEngine = + static_cast<clang::DiagnosticsEngine *>(UserData); - // Populate a vector with the command line arguments, expanding command files - // that have been included by via the '@' argument. - llvm::SmallVector<const char*, 256> ArgVector; - StringSet SavedStrings; // Keeps track of strings to be destroyed at the end. - const auto& ArgsIn(llvm::makeArrayRef(argv, argc)); - ArgVector.append(ArgsIn.begin(), ArgsIn.end()); - llvm::cl::ExpandResponseFiles(SavedStrings, llvm::cl::TokenizeGNUCommandLine, - ArgVector, false); + DiagEngine->Report(clang::diag::err_fe_error_backend) << Message; - const std::string Argv0 = llvm::sys::path::stem(ArgVector[0]); + // Run the interrupt handlers to make sure any special cleanups get done, in + // particular that we remove files registered with RemoveFileOnSignal. + llvm::sys::RunInterruptHandlers(); - // Setup diagnostic engine - slang::DiagnosticBuffer *DiagClient = new slang::DiagnosticBuffer(); - - llvm::IntrusiveRefCntPtr<clang::DiagnosticIDs> DiagIDs( - new clang::DiagnosticIDs()); + exit(1); +} - llvm::IntrusiveRefCntPtr<clang::DiagnosticOptions> DiagOpts( - new clang::DiagnosticOptions()); - clang::DiagnosticsEngine DiagEngine(DiagIDs, &*DiagOpts, DiagClient, true); +int main(int argc, const char **argv) { + llvm::llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. + LLVMInitializeARMTargetInfo(); + LLVMInitializeARMTarget(); + LLVMInitializeARMAsmPrinter(); - slang::Slang::GlobalInitialization(); + StringSet SavedStrings; // Keeps track of strings to be destroyed at the end. + // Parse the command line arguments and respond to show help & version + // commands. + llvm::SmallVector<const char *, 16> Inputs; slang::RSCCOptions Opts; - llvm::SmallVector<const char*, 16> Inputs; - slang::ParseArguments(ArgVector, Inputs, Opts, DiagEngine); - - // Exits when there's any error occurred during parsing the arguments - if (DiagEngine.hasErrorOccurred()) { - llvm::errs() << DiagClient->str(); + llvm::IntrusiveRefCntPtr<clang::DiagnosticOptions> DiagOpts = + new clang::DiagnosticOptions(); + if (!slang::ParseArguments(llvm::makeArrayRef(argv, argc), Inputs, Opts, + *DiagOpts, SavedStrings)) { + // Exits when there's any error occurred during parsing the arguments return 1; } - if (Opts.mShowHelp) { std::unique_ptr<llvm::opt::OptTable> OptTbl(slang::createRSCCOptTable()); + const std::string Argv0 = llvm::sys::path::stem(argv[0]); OptTbl->PrintHelp(llvm::outs(), Argv0.c_str(), "Renderscript source compiler"); return 0; } - if (Opts.mShowVersion) { llvm_rs_cc_VersionPrinter(); return 0; } - // No input file + // Initialize the diagnostic objects + llvm::IntrusiveRefCntPtr<clang::DiagnosticIDs> DiagIDs( + new clang::DiagnosticIDs()); + slang::DiagnosticBuffer DiagsBuffer; + clang::DiagnosticsEngine DiagEngine(DiagIDs, &*DiagOpts, &DiagsBuffer, false); + clang::ProcessWarningOptions(DiagEngine, *DiagOpts); + (void)DiagEngine.setSeverityForGroup(clang::diag::Flavor::WarningOrError, + "implicit-function-declaration", + clang::diag::Severity::Error); + + // Report error if no input file if (Inputs.empty()) { DiagEngine.Report(clang::diag::err_drv_no_input_files); - llvm::errs() << DiagClient->str(); + llvm::errs() << DiagsBuffer.str(); return 1; } - // Prepare input data for RS compiler. - NamePairList IOFiles64; + llvm::install_fatal_error_handler(LLVMErrorHandler, &DiagEngine); + + // Compile the 32 bit version NamePairList IOFiles32; + NamePairList DepFiles32; + makeFileList(&IOFiles32, &DepFiles32, Inputs, Opts, &SavedStrings); - int CompileFailed = compileFiles(&IOFiles32, &IOFiles32, Inputs, Opts, - &DiagEngine, DiagClient, &SavedStrings); + std::unique_ptr<slang::Slang> Compiler( + new slang::Slang(32, &DiagEngine, &DiagsBuffer)); + int CompileFailed = + !Compiler->compile(IOFiles32, IOFiles32, DepFiles32, Opts, *DiagOpts); // Handle the 64-bit case too! if (Opts.mEmit3264 && !CompileFailed) { Opts.mBitWidth = 64; - CompileFailed = compileFiles(&IOFiles64, &IOFiles32, Inputs, Opts, - &DiagEngine, DiagClient, &SavedStrings); + NamePairList IOFiles64; + NamePairList DepFiles64; + makeFileList(&IOFiles64, &DepFiles64, Inputs, Opts, &SavedStrings); + + std::unique_ptr<slang::Slang> Compiler( + new slang::Slang(64, &DiagEngine, &DiagsBuffer)); + CompileFailed = + !Compiler->compile(IOFiles64, IOFiles32, DepFiles64, Opts, *DiagOpts); } + llvm::errs() << DiagsBuffer.str(); + llvm::remove_fatal_error_handler(); return CompileFailed; } diff --git a/rs_cc_options.cpp b/rs_cc_options.cpp index ff37dd0..94d1453 100644 --- a/rs_cc_options.cpp +++ b/rs_cc_options.cpp @@ -23,6 +23,7 @@ #include "llvm/Option/ArgList.h" #include "llvm/Option/Option.h" #include "llvm/Option/OptTable.h" +#include "llvm/Support/CommandLine.h" #include "rs_cc_options.h" #include "slang.h" @@ -76,168 +77,193 @@ class RSCCOptTable : public llvm::opt::OptTable { }; } -llvm::opt::OptTable *slang::createRSCCOptTable() { return new RSCCOptTable(); } - -void slang::ParseArguments(llvm::SmallVectorImpl<const char *> &ArgVector, - llvm::SmallVectorImpl<const char *> &Inputs, - slang::RSCCOptions &Opts, - clang::DiagnosticsEngine &DiagEngine) { - if (ArgVector.size() > 1) { - const char **ArgBegin = ArgVector.data() + 1; - const char **ArgEnd = ArgVector.data() + ArgVector.size(); - unsigned MissingArgIndex, MissingArgCount; - std::unique_ptr<llvm::opt::OptTable> OptParser(slang::createRSCCOptTable()); - std::unique_ptr<llvm::opt::InputArgList> Args(OptParser->ParseArgs( - ArgBegin, ArgEnd, MissingArgIndex, MissingArgCount)); - - // Check for missing argument error. - if (MissingArgCount) - DiagEngine.Report(clang::diag::err_drv_missing_argument) - << Args->getArgString(MissingArgIndex) << MissingArgCount; - - clang::DiagnosticOptions DiagOpts; - DiagOpts.IgnoreWarnings = Args->hasArg(OPT_w); - DiagOpts.Warnings = Args->getAllArgValues(OPT_W); - clang::ProcessWarningOptions(DiagEngine, DiagOpts); - - // Issue errors on unknown arguments. - for (llvm::opt::arg_iterator it = Args->filtered_begin(OPT_UNKNOWN), - ie = Args->filtered_end(); - it != ie; ++it) - DiagEngine.Report(clang::diag::err_drv_unknown_argument) - << (*it)->getAsString(*Args); - - for (llvm::opt::ArgList::const_iterator it = Args->begin(), - ie = Args->end(); - it != ie; ++it) { - const llvm::opt::Arg *A = *it; - if (A->getOption().getKind() == llvm::opt::Option::InputClass) - Inputs.push_back(A->getValue()); - } +namespace slang { + +llvm::opt::OptTable *createRSCCOptTable() { return new RSCCOptTable(); } + +// This function is similar to +// clang/lib/Frontend/CompilerInvocation::CreateFromArgs. +bool ParseArguments(const llvm::ArrayRef<const char *> &ArgsIn, + llvm::SmallVectorImpl<const char *> &Inputs, + RSCCOptions &Opts, clang::DiagnosticOptions &DiagOpts, + llvm::cl::StringSaver &StringSaver) { + // We use a different diagnostic engine for argument parsing from the rest of + // the work. This mimics what's done in clang. I believe it is so the + // argument parsing errors are well formatted while the full errors can be + // influenced by command line arguments. + llvm::IntrusiveRefCntPtr<clang::DiagnosticOptions> ArgumentParseDiagOpts( + new clang::DiagnosticOptions()); + llvm::IntrusiveRefCntPtr<clang::DiagnosticIDs> DiagIDs( + new clang::DiagnosticIDs()); + DiagnosticBuffer DiagsBuffer; + clang::DiagnosticsEngine DiagEngine(DiagIDs, &*ArgumentParseDiagOpts, + &DiagsBuffer, false); + + // Populate a vector with the command line arguments, expanding command files + // that have been included via the '@' argument. + llvm::SmallVector<const char *, 256> ArgVector; + ArgVector.append(ArgsIn.begin(), ArgsIn.end()); + llvm::cl::ExpandResponseFiles(StringSaver, llvm::cl::TokenizeGNUCommandLine, + ArgVector, false); + + std::unique_ptr<llvm::opt::OptTable> OptParser(createRSCCOptTable()); + unsigned MissingArgIndex = 0; + unsigned MissingArgCount = 0; + std::unique_ptr<llvm::opt::InputArgList> Args( + OptParser->ParseArgs(ArgVector.begin() + 1, ArgVector.end(), + MissingArgIndex, MissingArgCount)); + + // Check for missing argument error. + if (MissingArgCount) { + DiagEngine.Report(clang::diag::err_drv_missing_argument) + << Args->getArgString(MissingArgIndex) << MissingArgCount; + } - Opts.mIncludePaths = Args->getAllArgValues(OPT_I); - - Opts.mBitcodeOutputDir = Args->getLastArgValue(OPT_o); - - if (const llvm::opt::Arg *A = Args->getLastArg(OPT_M_Group)) { - switch (A->getOption().getID()) { - case OPT_M: { - Opts.mEmitDependency = true; - Opts.mOutputType = slang::Slang::OT_Dependency; - break; - } - case OPT_MD: { - Opts.mEmitDependency = true; - Opts.mOutputType = slang::Slang::OT_Bitcode; - break; - } - default: { slangAssert(false && "Invalid option in M group!"); } - } + // Issue errors on unknown arguments. + for (llvm::opt::arg_iterator it = Args->filtered_begin(OPT_UNKNOWN), + ie = Args->filtered_end(); + it != ie; ++it) { + DiagEngine.Report(clang::diag::err_drv_unknown_argument) + << (*it)->getAsString(*Args); + } + + DiagOpts.IgnoreWarnings = Args->hasArg(OPT_w); + DiagOpts.Warnings = Args->getAllArgValues(OPT_W); + + for (llvm::opt::ArgList::const_iterator it = Args->begin(), ie = Args->end(); + it != ie; ++it) { + const llvm::opt::Arg *A = *it; + if (A->getOption().getKind() == llvm::opt::Option::InputClass) + Inputs.push_back(A->getValue()); + } + + Opts.mIncludePaths = Args->getAllArgValues(OPT_I); + + Opts.mBitcodeOutputDir = Args->getLastArgValue(OPT_o); + + if (const llvm::opt::Arg *A = Args->getLastArg(OPT_M_Group)) { + switch (A->getOption().getID()) { + case OPT_M: { + Opts.mEmitDependency = true; + Opts.mOutputType = Slang::OT_Dependency; + break; + } + case OPT_MD: { + Opts.mEmitDependency = true; + Opts.mOutputType = Slang::OT_Bitcode; + break; + } + default: { slangAssert(false && "Invalid option in M group!"); } } + } - if (const llvm::opt::Arg *A = Args->getLastArg(OPT_Output_Type_Group)) { - switch (A->getOption().getID()) { - case OPT_emit_asm: { - Opts.mOutputType = slang::Slang::OT_Assembly; - break; - } - case OPT_emit_llvm: { - Opts.mOutputType = slang::Slang::OT_LLVMAssembly; - break; - } - case OPT_emit_bc: { - Opts.mOutputType = slang::Slang::OT_Bitcode; - break; - } - case OPT_emit_nothing: { - Opts.mOutputType = slang::Slang::OT_Nothing; - break; - } - default: { - slangAssert(false && "Invalid option in output type group!"); - } - } + if (const llvm::opt::Arg *A = Args->getLastArg(OPT_Output_Type_Group)) { + switch (A->getOption().getID()) { + case OPT_emit_asm: { + Opts.mOutputType = Slang::OT_Assembly; + break; + } + case OPT_emit_llvm: { + Opts.mOutputType = Slang::OT_LLVMAssembly; + break; } + case OPT_emit_bc: { + Opts.mOutputType = Slang::OT_Bitcode; + break; + } + case OPT_emit_nothing: { + Opts.mOutputType = Slang::OT_Nothing; + break; + } + default: { slangAssert(false && "Invalid option in output type group!"); } + } + } - if (Opts.mEmitDependency && - ((Opts.mOutputType != slang::Slang::OT_Bitcode) && - (Opts.mOutputType != slang::Slang::OT_Dependency))) - DiagEngine.Report(clang::diag::err_drv_argument_not_allowed_with) - << Args->getLastArg(OPT_M_Group)->getAsString(*Args) - << Args->getLastArg(OPT_Output_Type_Group)->getAsString(*Args); - - Opts.mAllowRSPrefix = Args->hasArg(OPT_allow_rs_prefix); - - Opts.mJavaReflectionPathBase = - Args->getLastArgValue(OPT_java_reflection_path_base); - Opts.mJavaReflectionPackageName = - Args->getLastArgValue(OPT_java_reflection_package_name); - - Opts.mRSPackageName = Args->getLastArgValue(OPT_rs_package_name); - - llvm::StringRef BitcodeStorageValue = - Args->getLastArgValue(OPT_bitcode_storage); - if (BitcodeStorageValue == "ar") - Opts.mBitcodeStorage = slang::BCST_APK_RESOURCE; - else if (BitcodeStorageValue == "jc") - Opts.mBitcodeStorage = slang::BCST_JAVA_CODE; - else if (!BitcodeStorageValue.empty()) - DiagEngine.Report(clang::diag::err_drv_invalid_value) - << OptParser->getOptionName(OPT_bitcode_storage) - << BitcodeStorageValue; - - llvm::opt::Arg *lastBitwidthArg = Args->getLastArg(OPT_m32, OPT_m64); - if (Args->hasArg(OPT_reflect_cpp)) { - Opts.mBitcodeStorage = slang::BCST_CPP_CODE; - // mJavaReflectionPathBase can be set for C++ reflected builds. - // Set it to the standard mBitcodeOutputDir (via -o) by default. - if (Opts.mJavaReflectionPathBase.empty()) { - Opts.mJavaReflectionPathBase = Opts.mBitcodeOutputDir; - } + if (Opts.mEmitDependency && ((Opts.mOutputType != Slang::OT_Bitcode) && + (Opts.mOutputType != Slang::OT_Dependency))) + DiagEngine.Report(clang::diag::err_drv_argument_not_allowed_with) + << Args->getLastArg(OPT_M_Group)->getAsString(*Args) + << Args->getLastArg(OPT_Output_Type_Group)->getAsString(*Args); + + Opts.mAllowRSPrefix = Args->hasArg(OPT_allow_rs_prefix); + + Opts.mJavaReflectionPathBase = + Args->getLastArgValue(OPT_java_reflection_path_base); + Opts.mJavaReflectionPackageName = + Args->getLastArgValue(OPT_java_reflection_package_name); + + Opts.mRSPackageName = Args->getLastArgValue(OPT_rs_package_name); + + llvm::StringRef BitcodeStorageValue = + Args->getLastArgValue(OPT_bitcode_storage); + if (BitcodeStorageValue == "ar") + Opts.mBitcodeStorage = BCST_APK_RESOURCE; + else if (BitcodeStorageValue == "jc") + Opts.mBitcodeStorage = BCST_JAVA_CODE; + else if (!BitcodeStorageValue.empty()) + DiagEngine.Report(clang::diag::err_drv_invalid_value) + << OptParser->getOptionName(OPT_bitcode_storage) << BitcodeStorageValue; + + llvm::opt::Arg *lastBitwidthArg = Args->getLastArg(OPT_m32, OPT_m64); + if (Args->hasArg(OPT_reflect_cpp)) { + Opts.mBitcodeStorage = BCST_CPP_CODE; + // mJavaReflectionPathBase can be set for C++ reflected builds. + // Set it to the standard mBitcodeOutputDir (via -o) by default. + if (Opts.mJavaReflectionPathBase.empty()) { + Opts.mJavaReflectionPathBase = Opts.mBitcodeOutputDir; + } - // Check for bitwidth arguments. - if (lastBitwidthArg) { - if (lastBitwidthArg->getOption().matches(OPT_m32)) { - Opts.mBitWidth = 32; - } else { - Opts.mBitWidth = 64; - } + // Check for bitwidth arguments. + if (lastBitwidthArg) { + if (lastBitwidthArg->getOption().matches(OPT_m32)) { + Opts.mBitWidth = 32; + } else { + Opts.mBitWidth = 64; } - } else if (lastBitwidthArg) { - // -m32/-m64 are forbidden for non-C++ reflection paths. - DiagEngine.Report(DiagEngine.getCustomDiagID( - clang::DiagnosticsEngine::Error, - "cannot use -m32/-m64 without specifying C++ reflection (-reflect-c++)")); } + } else if (lastBitwidthArg) { + // -m32/-m64 are forbidden for non-C++ reflection paths. + DiagEngine.Report( + DiagEngine.getCustomDiagID(clang::DiagnosticsEngine::Error, + "cannot use -m32/-m64 without specifying " + "C++ reflection (-reflect-c++)")); + } - Opts.mDependencyOutputDir = - Args->getLastArgValue(OPT_output_dep_dir, Opts.mBitcodeOutputDir); - Opts.mAdditionalDepTargets = - Args->getAllArgValues(OPT_additional_dep_target); + Opts.mDependencyOutputDir = + Args->getLastArgValue(OPT_output_dep_dir, Opts.mBitcodeOutputDir); + Opts.mAdditionalDepTargets = Args->getAllArgValues(OPT_additional_dep_target); - Opts.mShowHelp = Args->hasArg(OPT_help); - Opts.mShowVersion = Args->hasArg(OPT_version); - Opts.mDebugEmission = Args->hasArg(OPT_emit_g); - Opts.mVerbose = Args->hasArg(OPT_verbose); + Opts.mShowHelp = Args->hasArg(OPT_help); + Opts.mShowVersion = Args->hasArg(OPT_version); + Opts.mDebugEmission = Args->hasArg(OPT_emit_g); + Opts.mVerbose = Args->hasArg(OPT_verbose); - // If we are emitting both 32-bit and 64-bit bitcode, we must embed it. + // If we are emitting both 32-bit and 64-bit bitcode, we must embed it. - size_t OptLevel = - clang::getLastArgIntValue(*Args, OPT_optimization_level, 3, DiagEngine); + size_t OptLevel = + clang::getLastArgIntValue(*Args, OPT_optimization_level, 3, DiagEngine); - Opts.mOptimizationLevel = - OptLevel == 0 ? llvm::CodeGenOpt::None : llvm::CodeGenOpt::Aggressive; + Opts.mOptimizationLevel = + OptLevel == 0 ? llvm::CodeGenOpt::None : llvm::CodeGenOpt::Aggressive; - Opts.mTargetAPI = clang::getLastArgIntValue(*Args, OPT_target_api, - RS_VERSION, DiagEngine); + Opts.mTargetAPI = + clang::getLastArgIntValue(*Args, OPT_target_api, RS_VERSION, DiagEngine); - if (Opts.mTargetAPI == 0) { - Opts.mTargetAPI = UINT_MAX; - } + if (Opts.mTargetAPI == 0) { + Opts.mTargetAPI = UINT_MAX; + } - Opts.mEmit3264 = (Opts.mTargetAPI >= 21) && (Opts.mBitcodeStorage != slang::BCST_CPP_CODE); - if (Opts.mEmit3264) { - Opts.mBitcodeStorage = slang::BCST_JAVA_CODE; - } + Opts.mEmit3264 = + (Opts.mTargetAPI >= 21) && (Opts.mBitcodeStorage != BCST_CPP_CODE); + if (Opts.mEmit3264) { + Opts.mBitcodeStorage = BCST_JAVA_CODE; } + + if (DiagEngine.hasErrorOccurred()) { + llvm::errs() << DiagsBuffer.str(); + return false; + } + + return true; +} } diff --git a/rs_cc_options.h b/rs_cc_options.h index 8bdd7bc..e45dae0 100644 --- a/rs_cc_options.h +++ b/rs_cc_options.h @@ -28,6 +28,9 @@ #include <vector> namespace llvm { +namespace cl { +class StringSaver; +} namespace opt { class OptTable; } @@ -125,10 +128,12 @@ llvm::opt::OptTable *createRSCCOptTable(); * \param Opts - returned options after command line has been processed * \param DiagEngine - input for issuing warnings/errors on arguments */ -void ParseArguments(llvm::SmallVectorImpl<const char *> &ArgVector, + +bool ParseArguments(const llvm::ArrayRef<const char *> &ArgsIn, llvm::SmallVectorImpl<const char *> &Inputs, - RSCCOptions &Opts, clang::DiagnosticsEngine &DiagEngine); + RSCCOptions &Opts, clang::DiagnosticOptions &DiagOpts, + llvm::cl::StringSaver &StringSaver); -} // namespace slang +} // namespace slang #endif // _FRAMEWORKS_COMPILE_SLANG_RS_CC_OPTIONS_H_ @@ -32,13 +32,11 @@ #include "clang/Basic/DiagnosticOptions.h" #include "clang/Basic/FileManager.h" #include "clang/Basic/FileSystemOptions.h" -#include "clang/Basic/LangOptions.h" #include "clang/Basic/SourceLocation.h" #include "clang/Basic/SourceManager.h" #include "clang/Basic/TargetInfo.h" #include "clang/Basic/TargetOptions.h" -#include "clang/Frontend/CodeGenOptions.h" #include "clang/Frontend/DependencyOutputOptions.h" #include "clang/Frontend/FrontendDiagnostic.h" #include "clang/Frontend/FrontendOptions.h" @@ -78,7 +76,6 @@ #include "slang_assert.h" #include "slang_backend.h" -#include "slang_backend.h" #include "slang_rs_context.h" #include "slang_rs_export_type.h" @@ -121,14 +118,6 @@ namespace slang { RS_HEADER_ENTRY(rs_vector_math) \ -bool Slang::GlobalInitialized = false; - -// Language option (define the language feature for compiler such as C99) -clang::LangOptions Slang::LangOpts; - -// Code generation option for the compiler -clang::CodeGenOptions Slang::CodeGenOpts; - // The named of metadata node that pragma resides (should be synced with // bcc.cpp) const llvm::StringRef Slang::PragmaMetadataName = "#pragma"; @@ -157,36 +146,6 @@ OpenOutputFile(const char *OutputFile, return nullptr; } -void Slang::GlobalInitialization() { - if (!GlobalInitialized) { - - LLVMInitializeARMTargetInfo(); - LLVMInitializeARMTarget(); - LLVMInitializeARMAsmPrinter(); - - // Please refer to include/clang/Basic/LangOptions.h to setup - // the options. - LangOpts.RTTI = 0; // Turn off the RTTI information support - LangOpts.C99 = 1; - LangOpts.Renderscript = 1; - LangOpts.LaxVectorConversions = 0; // Do not bitcast vectors! - LangOpts.CharIsSigned = 1; // Signed char is our default. - - CodeGenOpts.OptimizationLevel = 3; - - GlobalInitialized = true; - } -} - -void Slang::LLVMErrorHandler(void *UserData, const std::string &Message, - bool GenCrashDialog) { - clang::DiagnosticsEngine* DiagEngine = - static_cast<clang::DiagnosticsEngine *>(UserData); - - DiagEngine->Report(clang::diag::err_fe_error_backend) << Message; - exit(1); -} - void Slang::createTarget(uint32_t BitWidth) { std::vector<std::string> features; @@ -268,18 +227,32 @@ void Slang::createASTContext() { clang::ASTConsumer * Slang::createBackend(const clang::CodeGenOptions &CodeGenOpts, - llvm::raw_ostream *OS, Slang::OutputType OT) { + llvm::raw_ostream *OS, OutputType OT) { return new Backend(mRSContext, &getDiagnostics(), CodeGenOpts, getTargetOptions(), &mPragmas, OS, OT, getSourceManager(), mAllowRSPrefix, mIsFilterscript); } -Slang::Slang() - : mInitialized(false), mDiagClient(nullptr), +Slang::Slang(uint32_t BitWidth, clang::DiagnosticsEngine *DiagEngine, + DiagnosticBuffer *DiagClient) + : mDiagEngine(DiagEngine), mDiagClient(DiagClient), mTargetOpts(new clang::TargetOptions()), mOT(OT_Default), mRSContext(nullptr), mAllowRSPrefix(false), mTargetAPI(0), mVerbose(false), mIsFilterscript(false) { - GlobalInitialization(); + // Please refer to include/clang/Basic/LangOptions.h to setup + // the options. + LangOpts.RTTI = 0; // Turn off the RTTI information support + LangOpts.LineComment = 1; + LangOpts.C99 = 1; + LangOpts.Renderscript = 1; + LangOpts.LaxVectorConversions = 0; // Do not bitcast vectors! + LangOpts.CharIsSigned = 1; // Signed char is our default. + + CodeGenOpts.OptimizationLevel = 3; + + createTarget(BitWidth); + createFileManager(); + createSourceManager(); } Slang::~Slang() { @@ -291,24 +264,6 @@ Slang::~Slang() { } } -void Slang::init(uint32_t BitWidth, clang::DiagnosticsEngine *DiagEngine, - DiagnosticBuffer *DiagClient) { - if (mInitialized) - return; - - mDiagEngine = DiagEngine; - mDiagClient = DiagClient; - mDiag.reset(new clang::Diagnostic(mDiagEngine)); - initDiagnostic(); - llvm::install_fatal_error_handler(LLVMErrorHandler, mDiagEngine); - - createTarget(BitWidth); - createFileManager(); - createSourceManager(); - - mInitialized = true; -} - clang::ModuleLoadResult Slang::loadModule( clang::SourceLocation ImportLoc, clang::ModuleIdPath Path, @@ -474,30 +429,6 @@ void Slang::setOptimizationLevel(llvm::CodeGenOpt::Level OptimizationLevel) { CodeGenOpts.OptimizationLevel = OptimizationLevel; } -void Slang::reset(bool SuppressWarnings) { - delete mRSContext; - mRSContext = nullptr; - mGeneratedFileNames.clear(); - - // Always print diagnostics if we had an error occur, but don't print - // warnings if we suppressed them (i.e. we are doing the 64-bit compile after - // an existing 32-bit compile). - // - // TODO: This should really be removing duplicate identical warnings between - // the 32-bit and 64-bit compiles, but that is a more substantial feature. - // Bug: 17052573 - if (!SuppressWarnings || mDiagEngine->hasErrorOccurred()) { - llvm::errs() << mDiagClient->str(); - } - mDiagEngine->Reset(); - mDiagClient->reset(); - - // remove fatal error handler. slang::init needs to be called before another - // compilation, which will re-install the error handler. - llvm::remove_fatal_error_handler(); -} - -// Returns true if \p Filename ends in ".fs". bool Slang::isFilterscript(const char *Filename) { const char *c = strrchr(Filename, '.'); if (c && !strncmp(FS_SUFFIX, c + 1, strlen(FS_SUFFIX) + 1)) { @@ -513,8 +444,8 @@ bool Slang::generateJavaBitcodeAccessor(const std::string &OutputPathBase, RSSlangReflectUtils::BitCodeAccessorContext BCAccessorContext; BCAccessorContext.rsFileName = getInputFileName().c_str(); - BCAccessorContext.bc32FileName = getOutput32FileName().c_str(); - BCAccessorContext.bc64FileName = getOutputFileName().c_str(); + BCAccessorContext.bc32FileName = mOutput32FileName.c_str(); + BCAccessorContext.bc64FileName = mOutputFileName.c_str(); BCAccessorContext.reflectPath = OutputPathBase.c_str(); BCAccessorContext.packageName = PackageName.c_str(); BCAccessorContext.licenseNote = LicenseNote; @@ -589,9 +520,13 @@ bool Slang::checkODR(const char *CurInputFile) { } if (!PassODR) { - getDiagnostics().Report(mDiagErrorODR) << Reflected->getName() - << getInputFileName() - << RD->getValue().second; + unsigned DiagID = mDiagEngine->getCustomDiagID( + clang::DiagnosticsEngine::Error, + "type '%0' in different translation unit (%1 v.s. %2) " + "has incompatible type definition"); + getDiagnostics().Report(DiagID) << Reflected->getName() + << getInputFileName() + << RD->getValue().second; return false; } } else { @@ -609,39 +544,6 @@ bool Slang::checkODR(const char *CurInputFile) { return true; } -void Slang::initDiagnostic() { - clang::DiagnosticsEngine &DiagEngine = getDiagnostics(); - const auto Flavor = clang::diag::Flavor::WarningOrError; - - if (DiagEngine.setSeverityForGroup(Flavor, "implicit-function-declaration", - clang::diag::Severity::Error)) { - DiagEngine.Report(clang::diag::warn_unknown_diag_option) - << /* clang::diag::Flavor::WarningOrError */ 0 - << "implicit-function-declaration"; - } - - DiagEngine.setSeverity( - clang::diag::ext_typecheck_convert_discards_qualifiers, - clang::diag::Severity::Error, - clang::SourceLocation()); - - mDiagErrorInvalidOutputDepParameter = - DiagEngine.getCustomDiagID( - clang::DiagnosticsEngine::Error, - "invalid parameter for output dependencies files."); - - mDiagErrorODR = - DiagEngine.getCustomDiagID( - clang::DiagnosticsEngine::Error, - "type '%0' in different translation unit (%1 v.s. %2) " - "has incompatible type definition"); - - mDiagErrorTargetAPIRange = - DiagEngine.getCustomDiagID( - clang::DiagnosticsEngine::Error, - "target API level '%0' is out of range ('%1' - '%2')"); -} - void Slang::initPreprocessor() { clang::Preprocessor &PP = getPreprocessor(); @@ -687,12 +589,16 @@ bool Slang::compile( const std::list<std::pair<const char*, const char*> > &IOFiles64, const std::list<std::pair<const char*, const char*> > &IOFiles32, const std::list<std::pair<const char*, const char*> > &DepFiles, - const RSCCOptions &Opts) { + const RSCCOptions &Opts, + clang::DiagnosticOptions &DiagOpts) { if (IOFiles32.empty()) return true; if (Opts.mEmitDependency && (DepFiles.size() != IOFiles32.size())) { - getDiagnostics().Report(mDiagErrorInvalidOutputDepParameter); + unsigned DiagID = mDiagEngine->getCustomDiagID( + clang::DiagnosticsEngine::Error, + "invalid parameter for output dependencies files."); + getDiagnostics().Report(DiagID); return false; } @@ -705,10 +611,6 @@ bool Slang::compile( const char *InputFile, *Output64File, *Output32File, *BCOutputFile, *DepOutputFile; - std::list<std::pair<const char*, const char*> >::const_iterator - IOFile64Iter = IOFiles64.begin(), - IOFile32Iter = IOFiles32.begin(), - DepFileIter = DepFiles.begin(); setIncludePaths(Opts.mIncludePaths); setOutputType(Opts.mOutputType); @@ -726,8 +628,11 @@ bool Slang::compile( if (mTargetAPI != SLANG_DEVELOPMENT_TARGET_API && (mTargetAPI < SLANG_MINIMUM_TARGET_API || mTargetAPI > SLANG_MAXIMUM_TARGET_API)) { - getDiagnostics().Report(mDiagErrorTargetAPIRange) << mTargetAPI - << SLANG_MINIMUM_TARGET_API << SLANG_MAXIMUM_TARGET_API; + unsigned DiagID = mDiagEngine->getCustomDiagID( + clang::DiagnosticsEngine::Error, + "target API level '%0' is out of range ('%1' - '%2')"); + getDiagnostics().Report(DiagID) << mTargetAPI << SLANG_MINIMUM_TARGET_API + << SLANG_MAXIMUM_TARGET_API; return false; } @@ -742,23 +647,25 @@ bool Slang::compile( // a single pass over the input file. bool SuppressAllWarnings = (Opts.mOutputType != Slang::OT_Dependency); - bool CompileSecondTimeFor64Bit = Opts.mEmit3264 && Opts.mBitWidth == 64; + std::list<std::pair<const char*, const char*> >::const_iterator + IOFile64Iter = IOFiles64.begin(), + IOFile32Iter = IOFiles32.begin(), + DepFileIter = DepFiles.begin(); for (unsigned i = 0, e = IOFiles32.size(); i != e; i++) { InputFile = IOFile64Iter->first; Output64File = IOFile64Iter->second; Output32File = IOFile32Iter->second; - // We suppress warnings (via reset) if we are doing a second compilation. - reset(CompileSecondTimeFor64Bit); - if (!setInputSource(InputFile)) return false; if (!setOutput(Output64File)) return false; - setOutput32(Output32File); + // For use with 64-bit compilation/reflection. This only sets the filename of + // the 32-bit bitcode file, and doesn't actually verify it already exists. + mOutput32FileName = Output32File; mIsFilterscript = isFilterscript(InputFile); @@ -781,7 +688,7 @@ bool Slang::compile( if (Opts.mBitcodeStorage == BCST_CPP_CODE) { const std::string &outputFileName = (Opts.mBitWidth == 64) ? - getOutputFileName() : getOutput32FileName(); + mOutputFileName : mOutput32FileName; RSReflectionCpp R(mRSContext, Opts.mJavaReflectionPathBase, getInputFileName(), outputFileName); if (!R.reflect()) { @@ -795,7 +702,7 @@ bool Slang::compile( std::vector<std::string> generatedFileNames; RSReflectionJava R(mRSContext, &generatedFileNames, Opts.mJavaReflectionPathBase, getInputFileName(), - getOutputFileName(), + mOutputFileName, Opts.mBitcodeStorage == BCST_JAVA_CODE); if (!R.reflect()) { // TODO Is this needed or will the error message have been printed @@ -853,7 +760,6 @@ bool Slang::compile( IOFile64Iter++; IOFile32Iter++; } - return true; } @@ -32,7 +32,9 @@ #include "llvm/ADT/IntrusiveRefCntPtr.h" using llvm::RefCountedBase; +#include "clang/Basic/LangOptions.h" #include "clang/Basic/TargetOptions.h" +#include "clang/Frontend/CodeGenOptions.h" #include "clang/Lex/ModuleLoader.h" #include "llvm/ADT/StringRef.h" @@ -81,22 +83,14 @@ class Slang : public clang::ModuleLoader { }; private: - static clang::LangOptions LangOpts; - static clang::CodeGenOptions CodeGenOpts; - - static bool GlobalInitialized; - - static void LLVMErrorHandler(void *UserData, const std::string &Message, - bool GenCrashDialog); + // Language options (define the language feature for compiler such as C99) + clang::LangOptions LangOpts; + // Code generation options for the compiler + clang::CodeGenOptions CodeGenOpts; // Returns true if this is a Filterscript file. static bool isFilterscript(const char *Filename); - bool mInitialized; - - // Diagnostics Mediator (An interface for both Producer and Consumer) - std::unique_ptr<clang::Diagnostic> mDiag; - // Diagnostics Engine (Producer and Diagnostics Reporter) clang::DiagnosticsEngine *mDiagEngine; @@ -159,11 +153,6 @@ class Slang : public clang::ModuleLoader { bool mIsFilterscript; - // Custom diagnostic identifiers - unsigned mDiagErrorInvalidOutputDepParameter; - unsigned mDiagErrorODR; - unsigned mDiagErrorTargetAPIRange; - // Collect generated filenames (without the .java) for dependency generation std::vector<std::string> mGeneratedFileNames; @@ -197,13 +186,12 @@ class Slang : public clang::ModuleLoader { inline clang::TargetOptions const &getTargetOptions() const { return *mTargetOpts.get(); } - void initDiagnostic(); void initPreprocessor(); void initASTContext(); clang::ASTConsumer *createBackend(const clang::CodeGenOptions &CodeGenOpts, llvm::raw_ostream *OS, - Slang::OutputType OT); + OutputType OT); public: static const llvm::StringRef PragmaMetadataName; @@ -217,11 +205,10 @@ class Slang : public clang::ModuleLoader { static bool IsLocInRSHeaderFile(const clang::SourceLocation &Loc, const clang::SourceManager &SourceMgr); - Slang(); - virtual ~Slang(); + Slang(uint32_t BitWidth, clang::DiagnosticsEngine *DiagEngine, + DiagnosticBuffer *DiagClient); - void init(uint32_t BitWidth, clang::DiagnosticsEngine *DiagEngine, - DiagnosticBuffer *DiagClient); + virtual ~Slang(); bool setInputSource(llvm::StringRef InputFile); @@ -235,20 +222,6 @@ class Slang : public clang::ModuleLoader { bool setOutput(const char *OutputFile); - // For use with 64-bit compilation/reflection. This only sets the filename of - // the 32-bit bitcode file, and doesn't actually verify it already exists. - void setOutput32(const char *OutputFile) { - mOutput32FileName = OutputFile; - } - - std::string const &getOutputFileName() const { - return mOutputFileName; - } - - std::string const &getOutput32FileName() const { - return mOutput32FileName; - } - bool setDepOutput(const char *OutputFile); void setDepTargetBC(const char *TargetBCFile) { @@ -274,10 +247,6 @@ class Slang : public clang::ModuleLoader { void setOptimizationLevel(llvm::CodeGenOpt::Level OptimizationLevel); - // Reset the slang compiler state such that it can be reused to compile - // another file - void reset(bool SuppressWarnings = false); - // Compile bunch of RS files given in the llvm-rs-cc arguments. Return true if // all given input files are successfully compiled without errors. // @@ -292,7 +261,8 @@ class Slang : public clang::ModuleLoader { compile(const std::list<std::pair<const char *, const char *>> &IOFiles64, const std::list<std::pair<const char *, const char *>> &IOFiles32, const std::list<std::pair<const char *, const char *>> &DepFiles, - const RSCCOptions &Opts); + const RSCCOptions &Opts, + clang::DiagnosticOptions &DiagOpts); clang::ModuleLoadResult loadModule(clang::SourceLocation ImportLoc, clang::ModuleIdPath Path, diff --git a/slang_diagnostic_buffer.cpp b/slang_diagnostic_buffer.cpp index 5b7adaf..d6afabf 100644 --- a/slang_diagnostic_buffer.cpp +++ b/slang_diagnostic_buffer.cpp @@ -29,12 +29,6 @@ DiagnosticBuffer::DiagnosticBuffer() : mSOS(new llvm::raw_string_ostream(mDiags)) { } -DiagnosticBuffer::DiagnosticBuffer(DiagnosticBuffer const &src) - : clang::DiagnosticConsumer(src), - mDiags(src.mDiags), - mSOS(new llvm::raw_string_ostream(mDiags)) { -} - DiagnosticBuffer::~DiagnosticBuffer() { } @@ -43,43 +37,45 @@ void DiagnosticBuffer::HandleDiagnostic( clang::Diagnostic const &Info) { clang::SourceLocation const &SrcLoc = Info.getLocation(); - // 100 is enough for storing general diagnosis message - llvm::SmallString<100> Buf; + std::string Message; + llvm::raw_string_ostream stream(Message); if (SrcLoc.isValid()) { - SrcLoc.print(*mSOS, Info.getSourceManager()); - (*mSOS) << ": "; + SrcLoc.print(stream, Info.getSourceManager()); + stream << ": "; } switch (DiagLevel) { case clang::DiagnosticsEngine::Note: { - (*mSOS) << "note: "; + stream << "note: "; break; } case clang::DiagnosticsEngine::Warning: { - (*mSOS) << "warning: "; + stream << "warning: "; break; } case clang::DiagnosticsEngine::Error: { - (*mSOS) << "error: "; + stream << "error: "; break; } case clang::DiagnosticsEngine::Fatal: { - (*mSOS) << "fatal: "; + stream << "fatal: "; break; } default: { slangAssert(0 && "Diagnostic not handled during diagnostic buffering!"); } } - + // 100 is enough for storing general diagnosis Message + llvm::SmallString<100> Buf; Info.FormatDiagnostic(Buf); - (*mSOS) << Buf.str() << '\n'; -} + stream << Buf.str() << '\n'; + stream.flush(); -clang::DiagnosticConsumer * -DiagnosticBuffer::clone(clang::DiagnosticsEngine &Diags) const { - return new DiagnosticBuffer(*this); + if (mIncludedMessages.find(Message) == mIncludedMessages.end()) { + mIncludedMessages.insert(Message); + (*mSOS) << Message; + } } } // namespace slang diff --git a/slang_diagnostic_buffer.h b/slang_diagnostic_buffer.h index 56fa0a0..500f345 100644 --- a/slang_diagnostic_buffer.h +++ b/slang_diagnostic_buffer.h @@ -17,6 +17,7 @@ #ifndef _FRAMEWORKS_COMPILE_SLANG_SLANG_DIAGNOSTIC_BUFFER_H_ // NOLINT #define _FRAMEWORKS_COMPILE_SLANG_SLANG_DIAGNOSTIC_BUFFER_H_ +#include <set> #include <string> #include "clang/Basic/Diagnostic.h" @@ -31,22 +32,20 @@ namespace slang { // The diagnostics consumer instance (for reading the processed diagnostics) class DiagnosticBuffer : public clang::DiagnosticConsumer { - private: +private: + // We keed track of the messages that have been already added to this + // diagnostic buffer, to avoid duplicates. This can happen because for a + // given script we'll usually compile for both 32 and 64 bit targets. + std::set<std::string> mIncludedMessages; std::string mDiags; std::unique_ptr<llvm::raw_string_ostream> mSOS; - public: +public: DiagnosticBuffer(); - - explicit DiagnosticBuffer(DiagnosticBuffer const &src); - virtual ~DiagnosticBuffer(); virtual void HandleDiagnostic(clang::DiagnosticsEngine::Level DiagLevel, - const clang::Diagnostic& Info); - - virtual clang::DiagnosticConsumer * - clone(clang::DiagnosticsEngine &Diags) const; + const clang::Diagnostic &Info) override; inline const std::string &str() const { mSOS->flush(); @@ -54,7 +53,9 @@ class DiagnosticBuffer : public clang::DiagnosticConsumer { } inline void reset() { - this->mSOS->str().clear(); + mIncludedMessages.clear(); + mSOS.reset(); + mDiags.clear(); } }; diff --git a/tests/F_unknown_function/stderr.txt.expect b/tests/F_unknown_function/stderr.txt.expect new file mode 100644 index 0000000..c8329e3 --- /dev/null +++ b/tests/F_unknown_function/stderr.txt.expect @@ -0,0 +1 @@ +unknown_function.rs:6:5: error: implicit declaration of function 'bar' is invalid in C99 diff --git a/tests/P_unknown_function/stdout.txt.expect b/tests/F_unknown_function/stdout.txt.expect index e69de29..e69de29 100644 --- a/tests/P_unknown_function/stdout.txt.expect +++ b/tests/F_unknown_function/stdout.txt.expect diff --git a/tests/P_unknown_function/unknown_function.rs b/tests/F_unknown_function/unknown_function.rs index 8127993..8127993 100644 --- a/tests/P_unknown_function/unknown_function.rs +++ b/tests/F_unknown_function/unknown_function.rs diff --git a/tests/P_unknown_function/zzz.rs b/tests/F_unknown_function/zzz.rs index 54929dc..54929dc 100644 --- a/tests/P_unknown_function/zzz.rs +++ b/tests/F_unknown_function/zzz.rs diff --git a/tests/P_unknown_function/stderr.txt.expect b/tests/P_unknown_function/stderr.txt.expect deleted file mode 100644 index 901cd3b..0000000 --- a/tests/P_unknown_function/stderr.txt.expect +++ /dev/null @@ -1 +0,0 @@ -unknown_function.rs:6:5: warning: implicit declaration of function 'bar' is invalid in C99 diff --git a/tests/P_warnings/stderr.txt.expect b/tests/P_warnings/stderr.txt.expect index 7e049dc..00d6d40 100644 --- a/tests/P_warnings/stderr.txt.expect +++ b/tests/P_warnings/stderr.txt.expect @@ -1 +1,7 @@ -warnings.rs:5:1: warning: control reaches end of non-void function +warnings.rs:6:1: warning: control reaches end of non-void function +warnings.rs:9:7: warning: unused variable 'k' +warnings.rs:11:7: warning: unused variable 'j' +warnings.rs:11:11: warning: variable 'l' is uninitialized when used here +warnings.rs:10:8: note: initialize the variable 'l' to silence this warning +warnings.rs:5:12: warning: unused function 'foo' +warnings.rs:8:13: warning: unused function 'bar' diff --git a/tests/P_warnings/warnings.rs b/tests/P_warnings/warnings.rs index 01b3cd0..f419d9c 100644 --- a/tests/P_warnings/warnings.rs +++ b/tests/P_warnings/warnings.rs @@ -1,6 +1,12 @@ +// -Wall #pragma version(1) #pragma rs java_package_name(foo) static int foo() { } +static void bar() { + int k; + int l; + int j = l + 1; +} diff --git a/tests/P_warnings_deprecated/deprecated.rs b/tests/P_warnings_deprecated/deprecated.rs new file mode 100644 index 0000000..4e5f5af --- /dev/null +++ b/tests/P_warnings_deprecated/deprecated.rs @@ -0,0 +1,11 @@ +// -target-api 22 +#pragma version(1) +#pragma rs java_package_name(foo) + +char out; +rs_allocation al; + +void foo(char in) { + out = rsClamp(in, (char) 1, (char) 4); + al = rsGetAllocation((void*) 33); +} diff --git a/tests/P_warnings_deprecated/stderr.txt.expect b/tests/P_warnings_deprecated/stderr.txt.expect new file mode 100644 index 0000000..32f00d6 --- /dev/null +++ b/tests/P_warnings_deprecated/stderr.txt.expect @@ -0,0 +1,4 @@ +deprecated.rs:9:9: warning: 'rsClamp' is deprecated: Use clamp() instead. +../../../../../frameworks/rs/scriptc/rs_math.rsh:4091:5: note: 'rsClamp' has been explicitly marked deprecated here +deprecated.rs:10:8: warning: 'rsGetAllocation' is deprecated: This function is deprecated and will be removed from the SDK in a future release. +../../../../../frameworks/rs/scriptc/rs_object_info.rsh:381:5: note: 'rsGetAllocation' has been explicitly marked deprecated here diff --git a/tests/P_warnings_deprecated/stdout.txt.expect b/tests/P_warnings_deprecated/stdout.txt.expect new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tests/P_warnings_deprecated/stdout.txt.expect |