aboutsummaryrefslogtreecommitdiff
path: root/flang/lib
diff options
context:
space:
mode:
authorVictor Kingi <victor.kingi@arm.com>2023-08-30 12:45:23 +0000
committerVictor Kingi <victor.kingi@arm.com>2023-08-31 15:41:16 +0000
commit12da8ef0e318cf1e05c1380de7b98bc5cfa51f42 (patch)
treec93a3045e9976ffbb6fc231528f450a1eec17c34 /flang/lib
parent380c5da98efa62920e9fbf3aa9a4fa8add236fb9 (diff)
downloadllvm-12da8ef0e318cf1e05c1380de7b98bc5cfa51f42.zip
llvm-12da8ef0e318cf1e05c1380de7b98bc5cfa51f42.tar.gz
llvm-12da8ef0e318cf1e05c1380de7b98bc5cfa51f42.tar.bz2
[Flang][Driver] Add location and remark option printing to R_Group Diagnostics
For each R_Group diagnostic produced, this patch gives more information about it by printing the absolute file path, the line and column number the pass was applied to and finally the remark option that was used. Clang does the same with the exception of printing the relative path rather than absolute path. Depends on D159260. That patch adds support for backend passes while this patch adds remark options to the backend test cases. Reviewed By: awarzynski Differential Revision: https://reviews.llvm.org/D159258
Diffstat (limited to 'flang/lib')
-rw-r--r--flang/lib/Frontend/CompilerInvocation.cpp15
-rw-r--r--flang/lib/Frontend/FrontendActions.cpp13
-rw-r--r--flang/lib/Frontend/TextDiagnosticPrinter.cpp67
3 files changed, 93 insertions, 2 deletions
diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp
index 56218cb..81bf89b 100644
--- a/flang/lib/Frontend/CompilerInvocation.cpp
+++ b/flang/lib/Frontend/CompilerInvocation.cpp
@@ -267,6 +267,21 @@ static void parseCodeGenArgs(Fortran::frontend::CodeGenOptions &opts,
diags, args, clang::driver::options::OPT_Rpass_analysis_EQ,
/*remarkOptName=*/"pass-analysis");
+ if (opts.getDebugInfo() == llvm::codegenoptions::NoDebugInfo) {
+ // If the user requested a flag that requires source locations available in
+ // the backend, make sure that the backend tracks source location
+ // information.
+ bool needLocTracking = !opts.OptRecordFile.empty() ||
+ !opts.OptRecordPasses.empty() ||
+ !opts.OptRecordFormat.empty() ||
+ opts.OptimizationRemark.hasValidPattern() ||
+ opts.OptimizationRemarkMissed.hasValidPattern() ||
+ opts.OptimizationRemarkAnalysis.hasValidPattern();
+
+ if (needLocTracking)
+ opts.setDebugInfo(llvm::codegenoptions::LocTrackingOnly);
+ }
+
if (auto *a = args.getLastArg(clang::driver::options::OPT_save_temps_EQ))
opts.SaveTempsDir = a->getValue();
diff --git a/flang/lib/Frontend/FrontendActions.cpp b/flang/lib/Frontend/FrontendActions.cpp
index e61178b..3ca667e 100644
--- a/flang/lib/Frontend/FrontendActions.cpp
+++ b/flang/lib/Frontend/FrontendActions.cpp
@@ -957,6 +957,19 @@ public:
std::string msg;
llvm::raw_string_ostream msgStream(msg);
+
+ if (diagInfo.isLocationAvailable()) {
+ // Clang contains a SourceManager class which handles loading
+ // and caching of source files into memory and it can be used to
+ // query SourceLocation data. The SourceLocation data is what is
+ // needed here as it contains the full include stack which gives
+ // line and column number as well as file name and location.
+ // Since Flang doesn't have SourceManager, send file name and absolute
+ // path through msgStream, to use for printing.
+ msgStream << diagInfo.getLocationStr() << ";;"
+ << diagInfo.getAbsolutePath() << ";;";
+ }
+
msgStream << diagInfo.getMsg();
// Emit message.
diff --git a/flang/lib/Frontend/TextDiagnosticPrinter.cpp b/flang/lib/Frontend/TextDiagnosticPrinter.cpp
index 7ae1964..1e6414f 100644
--- a/flang/lib/Frontend/TextDiagnosticPrinter.cpp
+++ b/flang/lib/Frontend/TextDiagnosticPrinter.cpp
@@ -18,7 +18,10 @@
#include "flang/Frontend/TextDiagnostic.h"
#include "clang/Basic/DiagnosticOptions.h"
#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"
using namespace Fortran::frontend;
@@ -29,6 +32,62 @@ TextDiagnosticPrinter::TextDiagnosticPrinter(raw_ostream &diagOs,
TextDiagnosticPrinter::~TextDiagnosticPrinter() {}
+// For remarks only, print the remark option and pass name that was used to a
+// raw_ostream. This also supports warnings from invalid remark arguments
+// provided.
+static void printRemarkOption(llvm::raw_ostream &os,
+ clang::DiagnosticsEngine::Level level,
+ const clang::Diagnostic &info) {
+ llvm::StringRef opt =
+ clang::DiagnosticIDs::getWarningOptionForDiag(info.getID());
+ if (!opt.empty()) {
+ // We still need to check if the level is a Remark since, an unknown option
+ // warning could be printed i.e. [-Wunknown-warning-option]
+ os << " [" << (level == clang::DiagnosticsEngine::Remark ? "-R" : "-W")
+ << opt;
+ llvm::StringRef optValue = info.getDiags()->getFlagValue();
+ if (!optValue.empty())
+ os << "=" << optValue;
+ os << ']';
+ }
+}
+
+// For remarks only, if we are receiving a message of this format
+// [file location with line and column];;[path to file];;[the remark message]
+// then print the absolute file path, line and column number.
+void TextDiagnosticPrinter::printLocForRemarks(
+ llvm::raw_svector_ostream &diagMessageStream, llvm::StringRef &diagMsg) {
+ // split incoming string to get the absolute path and filename in the
+ // case we are receiving optimization remarks from BackendRemarkConsumer
+ diagMsg = diagMessageStream.str();
+ llvm::StringRef delimiter = ";;";
+
+ size_t pos = 0;
+ llvm::SmallVector<llvm::StringRef> tokens;
+ while ((pos = diagMsg.find(delimiter)) != std::string::npos) {
+ tokens.push_back(diagMsg.substr(0, pos));
+ diagMsg = diagMsg.drop_front(pos + delimiter.size());
+ }
+
+ // tokens will always be of size 2 in the case of optimization
+ // remark message received
+ if (tokens.size() == 2) {
+ // Extract absolute path
+ llvm::SmallString<128> absPath = llvm::sys::path::relative_path(tokens[1]);
+ llvm::sys::path::remove_filename(absPath);
+ // Add the last separator before the file name
+ llvm::sys::path::append(absPath, llvm::sys::path::get_separator());
+ llvm::sys::path::make_preferred(absPath);
+
+ // Used for changing only the bold attribute
+ if (diagOpts->ShowColors)
+ os.changeColor(llvm::raw_ostream::SAVEDCOLOR, true);
+
+ // Print path, file name, line and column
+ os << absPath << tokens[0] << ": ";
+ }
+}
+
void TextDiagnosticPrinter::HandleDiagnostic(
clang::DiagnosticsEngine::Level level, const clang::Diagnostic &info) {
// Default implementation (Warnings/errors count).
@@ -40,6 +99,7 @@ void TextDiagnosticPrinter::HandleDiagnostic(
info.FormatDiagnostic(outStr);
llvm::raw_svector_ostream diagMessageStream(outStr);
+ printRemarkOption(diagMessageStream, level, info);
if (!prefix.empty())
os << prefix << ": ";
@@ -48,12 +108,15 @@ void TextDiagnosticPrinter::HandleDiagnostic(
assert(!info.getLocation().isValid() &&
"Diagnostics with valid source location are not supported");
+ llvm::StringRef diagMsg;
+ printLocForRemarks(diagMessageStream, diagMsg);
+
Fortran::frontend::TextDiagnostic::printDiagnosticLevel(os, level,
diagOpts->ShowColors);
Fortran::frontend::TextDiagnostic::printDiagnosticMessage(
os,
- /*IsSupplemental=*/level == clang::DiagnosticsEngine::Note,
- diagMessageStream.str(), diagOpts->ShowColors);
+ /*IsSupplemental=*/level == clang::DiagnosticsEngine::Note, diagMsg,
+ diagOpts->ShowColors);
os.flush();
}