Merge "Deprecate rs_fp_imprecise."
diff --git a/slang_rs_context.cpp b/slang_rs_context.cpp
index e9bb008..24fc204 100644
--- a/slang_rs_context.cpp
+++ b/slang_rs_context.cpp
@@ -61,20 +61,7 @@
mMangleCtx(Ctx.createMangleContext()),
mIs64Bit(Target.getPointerWidth(0) == 64) {
- // For #pragma rs export_type
- PP.AddPragmaHandler(
- "rs", RSPragmaHandler::CreatePragmaExportTypeHandler(this));
-
- // For #pragma rs java_package_name
- PP.AddPragmaHandler(
- "rs", RSPragmaHandler::CreatePragmaJavaPackageNameHandler(this));
-
- // For #pragma rs set_reflect_license
- PP.AddPragmaHandler(
- "rs", RSPragmaHandler::CreatePragmaReflectLicenseHandler(this));
-
- // For #pragma version
- PP.AddPragmaHandler(RSPragmaHandler::CreatePragmaVersionHandler(this));
+ AddPragmaHandlers(PP, this);
// Prepare target data
mDataLayout = new llvm::DataLayout(Target.getTargetDescription());
diff --git a/slang_rs_context.h b/slang_rs_context.h
index 41f5979..82cee40 100644
--- a/slang_rs_context.h
+++ b/slang_rs_context.h
@@ -67,6 +67,9 @@
clang::Preprocessor &mPP;
clang::ASTContext &mCtx;
PragmaList *mPragmas;
+ // Precision specified via pragma, either rs_fp_full or rs_fp_relaxed. If
+ // empty, rs_fp_full is assumed.
+ std::string mPrecision;
unsigned int mTargetAPI;
bool mVerbose;
@@ -234,6 +237,8 @@
void addPragma(const std::string &T, const std::string &V) {
mPragmas->push_back(make_pair(T, V));
}
+ void setPrecision(const std::string &P) { mPrecision = P; }
+ std::string getPrecision() { return mPrecision; }
// Report an error or a warning to the user.
template <unsigned N>
diff --git a/slang_rs_pragma_handler.cpp b/slang_rs_pragma_handler.cpp
index c562ec3..03e2161 100644
--- a/slang_rs_pragma_handler.cpp
+++ b/slang_rs_pragma_handler.cpp
@@ -167,28 +167,48 @@
}
};
+// Handles the pragmas rs_fp_full, rs_fp_relaxed, and rs_fp_imprecise.
+// There's one instance of this handler for each of the above values.
+// Only getName() differs between the instances.
+class RSPrecisionPragmaHandler : public RSPragmaHandler {
+public:
+ RSPrecisionPragmaHandler(llvm::StringRef Name, RSContext *Context)
+ : RSPragmaHandler(Name, Context) {}
+
+ void HandlePragma(clang::Preprocessor &PP,
+ clang::PragmaIntroducerKind Introducer,
+ clang::Token &Token) {
+ std::string Precision = getName();
+ // We are deprecating rs_fp_imprecise.
+ if (Precision == "rs_fp_imprecise") {
+ PP.Diag(Token, PP.getDiagnostics().getCustomDiagID(
+ clang::DiagnosticsEngine::Warning,
+ "rs_fp_imprecise is deprecated. Assuming "
+ "rs_fp_relaxed instead."));
+ Precision = "rs_fp_relaxed";
+ }
+ // Check if we have already encountered a precision pragma already.
+ std::string PreviousPrecision = mContext->getPrecision();
+ if (!PreviousPrecision.empty()) {
+ // If the previous specified a different value, it's an error.
+ if (PreviousPrecision != Precision) {
+ PP.Diag(Token, PP.getDiagnostics().getCustomDiagID(
+ clang::DiagnosticsEngine::Error,
+ "Multiple float precisions specified. Encountered "
+ "%0 previously."))
+ << PreviousPrecision;
+ }
+ // Otherwise we ignore redundant entries.
+ return;
+ }
+
+ mContext->addPragma(Precision, "");
+ mContext->setPrecision(Precision);
+ }
+};
+
} // namespace
-RSPragmaHandler *
-RSPragmaHandler::CreatePragmaExportTypeHandler(RSContext *Context) {
- return new RSExportTypePragmaHandler("export_type", Context);
-}
-
-RSPragmaHandler *
-RSPragmaHandler::CreatePragmaJavaPackageNameHandler(RSContext *Context) {
- return new RSJavaPackageNamePragmaHandler("java_package_name", Context);
-}
-
-RSPragmaHandler *
-RSPragmaHandler::CreatePragmaReflectLicenseHandler(RSContext *Context) {
- return new RSReflectLicensePragmaHandler("set_reflect_license", Context);
-}
-
-RSPragmaHandler *
-RSPragmaHandler::CreatePragmaVersionHandler(RSContext *Context) {
- return new RSVersionPragmaHandler("version", Context);
-}
-
void RSPragmaHandler::handleItemListPragma(clang::Preprocessor &PP,
clang::Token &FirstToken) {
clang::Token &PragmaToken = FirstToken;
@@ -321,4 +341,27 @@
} while (PragmaToken.isNot(clang::tok::eod));
}
+void AddPragmaHandlers(clang::Preprocessor &PP, RSContext *RsContext) {
+ // For #pragma rs export_type
+ PP.AddPragmaHandler("rs",
+ new RSExportTypePragmaHandler("export_type", RsContext));
+
+ // For #pragma rs java_package_name
+ PP.AddPragmaHandler(
+ "rs", new RSJavaPackageNamePragmaHandler("java_package_name", RsContext));
+
+ // For #pragma rs set_reflect_license
+ PP.AddPragmaHandler(
+ "rs", new RSReflectLicensePragmaHandler("set_reflect_license", RsContext));
+
+ // For #pragma version
+ PP.AddPragmaHandler(new RSVersionPragmaHandler("version", RsContext));
+
+ // For #pragma rs_fp*
+ PP.AddPragmaHandler(new RSPrecisionPragmaHandler("rs_fp_full", RsContext));
+ PP.AddPragmaHandler(new RSPrecisionPragmaHandler("rs_fp_relaxed", RsContext));
+ PP.AddPragmaHandler(new RSPrecisionPragmaHandler("rs_fp_imprecise", RsContext));
+}
+
+
} // namespace slang
diff --git a/slang_rs_pragma_handler.h b/slang_rs_pragma_handler.h
index c960842..1b6fbe6 100644
--- a/slang_rs_pragma_handler.h
+++ b/slang_rs_pragma_handler.h
@@ -64,17 +64,15 @@
clang::Token &FirstToken);
public:
- static RSPragmaHandler *CreatePragmaExportTypeHandler(RSContext *Context);
- static RSPragmaHandler *CreatePragmaJavaPackageNameHandler(
- RSContext *Context);
- static RSPragmaHandler *CreatePragmaReflectLicenseHandler(RSContext *Context);
- static RSPragmaHandler *CreatePragmaVersionHandler(RSContext *Context);
-
virtual void HandlePragma(clang::Preprocessor &PP,
clang::PragmaIntroducerKind Introducer,
clang::Token &FirstToken) = 0;
};
+// Add handlers for the RS pragmas to the preprocessor. These handlers
+// validate the pragmas and, if valid, set fields of the RSContext.
+void AddPragmaHandlers(clang::Preprocessor &PP, RSContext *RsContext);
+
} // namespace slang
#endif // _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_PRAGMA_HANDLER_H_ NOLINT
diff --git a/tests/F_rs_fp_two_pragmas/rs_fp_two_pragmas.rs b/tests/F_rs_fp_two_pragmas/rs_fp_two_pragmas.rs
new file mode 100644
index 0000000..b07091c
--- /dev/null
+++ b/tests/F_rs_fp_two_pragmas/rs_fp_two_pragmas.rs
@@ -0,0 +1,8 @@
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+#pragma rs_fp_relaxed
+#pragma rs_fp_full
+
+
+
diff --git a/tests/F_rs_fp_two_pragmas/stderr.txt.expect b/tests/F_rs_fp_two_pragmas/stderr.txt.expect
new file mode 100644
index 0000000..6ad9b66
--- /dev/null
+++ b/tests/F_rs_fp_two_pragmas/stderr.txt.expect
@@ -0,0 +1 @@
+rs_fp_two_pragmas.rs:5:9: error: Multiple float precisions specified. Encountered rs_fp_relaxed previously.
diff --git a/tests/F_rs_fp_two_pragmas/stdout.txt.expect b/tests/F_rs_fp_two_pragmas/stdout.txt.expect
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/F_rs_fp_two_pragmas/stdout.txt.expect
diff --git a/tests/P_rs_fp_full/rs_fp_full.rs b/tests/P_rs_fp_full/rs_fp_full.rs
new file mode 100644
index 0000000..35050fc
--- /dev/null
+++ b/tests/P_rs_fp_full/rs_fp_full.rs
@@ -0,0 +1,5 @@
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+#pragma rs_fp_full
+
diff --git a/tests/P_rs_fp_full/stderr.txt.expect b/tests/P_rs_fp_full/stderr.txt.expect
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/P_rs_fp_full/stderr.txt.expect
diff --git a/tests/P_rs_fp_full/stdout.txt.expect b/tests/P_rs_fp_full/stdout.txt.expect
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/P_rs_fp_full/stdout.txt.expect
diff --git a/tests/P_rs_fp_imprecise/stderr.txt.expect b/tests/P_rs_fp_imprecise/stderr.txt.expect
index e69de29..0d86335 100644
--- a/tests/P_rs_fp_imprecise/stderr.txt.expect
+++ b/tests/P_rs_fp_imprecise/stderr.txt.expect
@@ -0,0 +1 @@
+rs_fp_imprecise.rs:4:9: warning: rs_fp_imprecise is deprecated. Assuming rs_fp_relaxed instead.