Skip to content

[flang/clang] Adding use of Clang's diagnostics in Flang #130593

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion clang/include/clang/Basic/Diagnostic.td
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,14 @@ class DiagCategory<string Name> {
}

// Diagnostic Groups.
class DiagGroup<string Name, list<DiagGroup> subgroups = [], code docs = [{}]> {
class DiagGroup<string Name, list<DiagGroup> subgroups = [], code docs = [{}],
bit clangDiag = 1, bit flangDiag = 0> {
string GroupName = Name;
list<DiagGroup> SubGroups = subgroups;
string CategoryName = "";
code Documentation = docs;
bit IsClangDiag = clangDiag;
bit IsFlangDiag = flangDiag;
}
class InGroup<DiagGroup G> { DiagGroup Group = G; }
//class IsGroup<string Name> { DiagGroup Group = DiagGroup<Name>; }
Expand Down
3 changes: 2 additions & 1 deletion clang/include/clang/Basic/DiagnosticCategories.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ namespace clang {
};

enum class Group {
#define DIAG_ENTRY(GroupName, FlagNameOffset, Members, SubGroups, Docs) \
#define DIAG_ENTRY(GroupName, FlagNameOffset, Members, SubGroups, Docs, \
IsClang, IsFlang) \
GroupName,
#include "clang/Basic/DiagnosticGroups.inc"
#undef CATEGORY
Expand Down
5 changes: 5 additions & 0 deletions clang/include/clang/Basic/DiagnosticIDs.h
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,11 @@ class DiagnosticIDs : public RefCountedBase<DiagnosticIDs> {
/// Given a diagnostic group ID, return its documentation.
static StringRef getWarningOptionDocumentation(diag::Group GroupID);

/// Given a diagnostic group ID, return true if its a Flang warning.
static bool isFlangWarningOption(diag::Group Group);
/// Given a diagnostic group ID, return true if its a Clang warning.
static bool isClangWarningOption(diag::Group Group);

void setGroupSeverity(StringRef Group, diag::Severity);
void setGroupNoWarningsAsError(StringRef Group, bool);

Expand Down
14 changes: 12 additions & 2 deletions clang/lib/Basic/DiagnosticIDs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -585,15 +585,18 @@ namespace {
uint16_t Members;
uint16_t SubGroups;
StringRef Documentation;
bool IsClangDiag;
bool IsFlangDiag;

StringRef getName() const { return DiagGroupNames[NameOffset]; }
};
}

// Second the table of options, sorted by name for fast binary lookup.
static const WarningOption OptionTable[] = {
#define DIAG_ENTRY(GroupName, FlagNameOffset, Members, SubGroups, Docs) \
{FlagNameOffset, Members, SubGroups, Docs},
#define DIAG_ENTRY(GroupName, FlagNameOffset, Members, SubGroups, Docs, \
IsClang, IsFlang) \
{FlagNameOffset, Members, SubGroups, Docs, IsClang, IsFlang},
#include "clang/Basic/DiagnosticGroups.inc"
#undef DIAG_ENTRY
};
Expand All @@ -607,6 +610,13 @@ StringRef DiagnosticIDs::getWarningOptionForGroup(diag::Group Group) {
return OptionTable[static_cast<int>(Group)].getName();
}

bool DiagnosticIDs::isFlangWarningOption(diag::Group Group) {
return OptionTable[static_cast<int>(Group)].IsFlangDiag;
}

bool DiagnosticIDs::isClangWarningOption(diag::Group Group) {
return OptionTable[static_cast<int>(Group)].IsClangDiag;
}
std::optional<diag::Group>
DiagnosticIDs::getGroupForWarningOption(StringRef Name) {
const auto *Found = llvm::partition_point(
Expand Down
9 changes: 9 additions & 0 deletions clang/lib/Basic/Warnings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,15 @@ void clang::ProcessWarningOptions(DiagnosticsEngine &Diags,
diag::Severity Mapping =
isPositive ? diag::Severity::Warning : diag::Severity::Ignored;

// Check if the warning option is valid for Clang
std::optional<diag::Group> Group = DiagIDs->getGroupForWarningOption(Opt);
if (Group.has_value() && !DiagIDs->isClangWarningOption(Group.value())) {
const unsigned DiagID = Diags.getCustomDiagID(
DiagnosticsEngine::Error,
"Warning option \"%0\" is valid for Fortran but not for C++.");
Diags.Report(DiagID) << Opt;
}

// -Wsystem-headers is a special case, not driven by the option table. It
// cannot be controlled with -Werror.
if (Opt == "system-headers") {
Expand Down
4 changes: 3 additions & 1 deletion clang/test/TableGen/DiagnosticBase.inc
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,13 @@ class DiagCategory<string Name> {
}

// Diagnostic Groups.
class DiagGroup<string Name, list<DiagGroup> subgroups = []> {
class DiagGroup<string Name, list<DiagGroup> subgroups = [], bit clangDiag = 1, bit flangDiag = 0> {
string GroupName = Name;
list<DiagGroup> SubGroups = subgroups;
string CategoryName = "";
code Documentation = [{}];
bit IsClangDiag = clangDiag;
bit IsFlangDiag = flangDiag;
}
class InGroup<DiagGroup G> { DiagGroup Group = G; }
//class IsGroup<string Name> { DiagGroup Group = DiagGroup<Name>; }
Expand Down
3 changes: 2 additions & 1 deletion clang/tools/diagtool/DiagnosticNames.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@ const DiagnosticRecord &diagtool::getDiagnosticForID(short DiagID) {

// Second the table of options, sorted by name for fast binary lookup.
static const GroupRecord OptionTable[] = {
#define DIAG_ENTRY(GroupName, FlagNameOffset, Members, SubGroups, Docs) \
#define DIAG_ENTRY(GroupName, FlagNameOffset, Members, SubGroups, Docs, \
IsClang, IsFlang) \
{FlagNameOffset, Members, SubGroups},
#include "clang/Basic/DiagnosticGroups.inc"
#undef DIAG_ENTRY
Expand Down
4 changes: 4 additions & 0 deletions clang/utils/TableGen/ClangDiagnosticsEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1890,6 +1890,10 @@ static void emitDiagTable(DiagsInGroupTy &DiagsInGroup,

OS << "R\"(" << StringRef(Documentation).trim() << ")\"";

OS << ", /*IsClangDiag*/ "
<< bool(GroupInfo.Defs.back()->getValueAsBit("IsClangDiag"));
OS << ", /*IsFlangDiag*/ "
<< bool(GroupInfo.Defs.back()->getValueAsBit("IsFlangDiag"));
OS << ")\n";
}
OS << "#endif // DIAG_ENTRY\n\n";
Expand Down
10 changes: 8 additions & 2 deletions flang/include/flang/Frontend/CompilerInvocation.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,18 @@ class TargetMachine;

namespace Fortran::frontend {

/// processWarningOptions - Initialize the diagnostic client and process the
/// warning options specified on the command line.
void processWarningOptions(clang::DiagnosticsEngine &Diags,
const clang::DiagnosticOptions &Opts);

/// Fill out Opts based on the options given in Args.
///
/// When errors are encountered, return false and, if Diags is non-null,
/// report the error(s).
bool parseDiagnosticArgs(clang::DiagnosticOptions &opts,
llvm::opt::ArgList &args);
llvm::opt::ArgList &args,
bool defaultDiagColor = true);

class CompilerInvocationBase {
public:
Expand Down Expand Up @@ -174,7 +180,7 @@ class CompilerInvocation : public CompilerInvocationBase {
/// Creates and configures semantics context based on the compilation flags.
std::unique_ptr<Fortran::semantics::SemanticsContext>
getSemanticsCtx(Fortran::parser::AllCookedSources &allCookedSources,
const llvm::TargetMachine &);
const llvm::TargetMachine &, clang::DiagnosticsEngine &diag);

std::string &getModuleDir() { return moduleDir; }
const std::string &getModuleDir() const { return moduleDir; }
Expand Down
5 changes: 4 additions & 1 deletion flang/include/flang/Semantics/semantics.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "flang/Parser/message.h"
#include "flang/Support/Fortran-features.h"
#include "flang/Support/LangOptions.h"
#include "clang/Basic/Diagnostic.h"
#include <iosfwd>
#include <set>
#include <string>
Expand Down Expand Up @@ -68,7 +69,7 @@ class SemanticsContext {
public:
SemanticsContext(const common::IntrinsicTypeDefaultKinds &,
const common::LanguageFeatureControl &, const common::LangOptions &,
parser::AllCookedSources &);
parser::AllCookedSources &, clang::DiagnosticsEngine &);
~SemanticsContext();

const common::IntrinsicTypeDefaultKinds &defaultKinds() const {
Expand All @@ -82,6 +83,7 @@ class SemanticsContext {
int doublePrecisionKind() const {
return defaultKinds_.doublePrecisionKind();
}
clang::DiagnosticsEngine &getDiagnostics() const { return diags_; }
int quadPrecisionKind() const { return defaultKinds_.quadPrecisionKind(); }
bool IsEnabled(common::LanguageFeature feature) const {
return languageFeatures_.IsEnabled(feature);
Expand Down Expand Up @@ -305,6 +307,7 @@ class SemanticsContext {
const common::IntrinsicTypeDefaultKinds &defaultKinds_;
const common::LanguageFeatureControl &languageFeatures_;
const common::LangOptions &langOpts_;
clang::DiagnosticsEngine &diags_;
parser::AllCookedSources &allCookedSources_;
std::optional<parser::CharBlock> location_;
std::vector<std::string> searchDirectories_;
Expand Down
3 changes: 3 additions & 0 deletions flang/include/flang/Semantics/symbol.h
Original file line number Diff line number Diff line change
Expand Up @@ -293,10 +293,13 @@ class EntityDetails : public WithBindName {
void set_isDummy(bool value = true) { isDummy_ = value; }
bool isFuncResult() const { return isFuncResult_; }
void set_funcResult(bool x) { isFuncResult_ = x; }
bool isUsed() const { return isUsed_; }
void set_isUsed() { isUsed_ = true; }

private:
bool isDummy_{false};
bool isFuncResult_{false};
bool isUsed_{false};
const DeclTypeSpec *type_{nullptr};
friend llvm::raw_ostream &operator<<(
llvm::raw_ostream &, const EntityDetails &);
Expand Down
1 change: 1 addition & 0 deletions flang/lib/Frontend/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ add_flang_library(flangFrontend
TextDiagnosticPrinter.cpp
TextDiagnosticBuffer.cpp
TextDiagnostic.cpp
Warnings.cpp

DEPENDS
CUFDialect
Expand Down
3 changes: 2 additions & 1 deletion flang/lib/Frontend/CompilerInstance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,8 @@ bool CompilerInstance::executeAction(FrontendAction &act) {
if (!setUpTargetMachine())
return false;
// Create the semantics context
semaContext = invoc.getSemanticsCtx(*allCookedSources, getTargetMachine());
semaContext = invoc.getSemanticsCtx(*allCookedSources, getTargetMachine(),
getDiagnostics());
// Set options controlling lowering to FIR.
invoc.setLoweringOptions();

Expand Down
50 changes: 29 additions & 21 deletions flang/lib/Frontend/CompilerInvocation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#include "llvm/Option/Arg.h"
#include "llvm/Option/ArgList.h"
#include "llvm/Option/OptTable.h"
#include "llvm/Option/Option.h"
#include "llvm/Support/CodeGen.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/FileUtilities.h"
Expand Down Expand Up @@ -119,9 +120,26 @@ static unsigned getOptimizationLevel(llvm::opt::ArgList &args,
}

bool Fortran::frontend::parseDiagnosticArgs(clang::DiagnosticOptions &opts,
llvm::opt::ArgList &args) {
opts.ShowColors = parseShowColorsArgs(args);

llvm::opt::ArgList &args,
bool defaultDiagColor) {
opts.ShowColors = parseShowColorsArgs(args, defaultDiagColor);

for (llvm::opt::Arg *A : args.filtered(clang::driver::options::OPT_W_Group)) {
if (A->getOption().getKind() == llvm::opt::Option::FlagClass) {
// The argument is a pure flag (such as OPT_Wall).
opts.Warnings.push_back(
std::string(A->getOption().getName().drop_front(1)));
} else if (A->getOption().matches(
clang::driver::options::OPT_W_value_Group)) {
// This is -Wfoo= where foo is the name of the diagnostic group.
// Add only the group name to the diagnostics.
opts.Warnings.push_back(
std::string(A->getOption().getName().drop_front(1).rtrim("=-")));
} else {
// Otherwise, add its value for OPT_W_Joined.
opts.Warnings.push_back(A->getValue());
}
}
return true;
}

Expand Down Expand Up @@ -927,22 +945,11 @@ static bool parseDiagArgs(CompilerInvocation &res, llvm::opt::ArgList &args,
clang::DiagnosticsEngine &diags) {
unsigned numErrorsBefore = diags.getNumErrors();

// -Werror option
// TODO: Currently throws a Diagnostic for anything other than -W<error>,
// this has to change when other -W<opt>'s are supported.
if (args.hasArg(clang::driver::options::OPT_W_Joined)) {
const auto &wArgs =
args.getAllArgValues(clang::driver::options::OPT_W_Joined);
for (const auto &wArg : wArgs) {
if (wArg == "error") {
res.setWarnAsErr(true);
} else {
const unsigned diagID =
diags.getCustomDiagID(clang::DiagnosticsEngine::Error,
"Only `-Werror` is supported currently.");
diags.Report(diagID);
}
}
// Handle warning Diagnostic for the frontend.
clang::DiagnosticOptions &diagOpts = res.getDiagnosticOpts();
for (const auto &warning : diagOpts.Warnings) {
if (warning == "error")
res.setWarnAsErr(true);
}

// Default to off for `flang -fc1`.
Expand Down Expand Up @@ -1030,6 +1037,7 @@ static bool parseDialectArgs(CompilerInvocation &res, llvm::opt::ArgList &args,
if (args.hasArg(clang::driver::options::OPT_pedantic)) {
res.setEnableConformanceChecks();
res.setEnableUsageChecks();
res.getDiagnosticOpts().Pedantic = true;
}

// -w
Expand Down Expand Up @@ -1650,12 +1658,12 @@ void CompilerInvocation::setFortranOpts() {
std::unique_ptr<Fortran::semantics::SemanticsContext>
CompilerInvocation::getSemanticsCtx(
Fortran::parser::AllCookedSources &allCookedSources,
const llvm::TargetMachine &targetMachine) {
const llvm::TargetMachine &targetMachine, clang::DiagnosticsEngine &diags) {
auto &fortranOptions = getFortranOpts();

auto semanticsContext = std::make_unique<semantics::SemanticsContext>(
getDefaultKinds(), fortranOptions.features, getLangOpts(),
allCookedSources);
allCookedSources, diags);

semanticsContext->set_moduleDirectory(getModuleDir())
.set_searchDirectories(fortranOptions.searchDirectories)
Expand Down
Loading