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
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
@@ -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>; }
3 changes: 2 additions & 1 deletion clang/include/clang/Basic/DiagnosticCategories.h
Original file line number Diff line number Diff line change
@@ -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
5 changes: 5 additions & 0 deletions clang/include/clang/Basic/DiagnosticIDs.h
Original file line number Diff line number Diff line change
@@ -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);

14 changes: 12 additions & 2 deletions clang/lib/Basic/DiagnosticIDs.cpp
Original file line number Diff line number Diff line change
@@ -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
};
@@ -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(
9 changes: 9 additions & 0 deletions clang/lib/Basic/Warnings.cpp
Original file line number Diff line number Diff line change
@@ -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") {
4 changes: 3 additions & 1 deletion clang/test/TableGen/DiagnosticBase.inc
Original file line number Diff line number Diff line change
@@ -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>; }
3 changes: 2 additions & 1 deletion clang/tools/diagtool/DiagnosticNames.cpp
Original file line number Diff line number Diff line change
@@ -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
4 changes: 4 additions & 0 deletions clang/utils/TableGen/ClangDiagnosticsEmitter.cpp
Original file line number Diff line number Diff line change
@@ -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";
10 changes: 8 additions & 2 deletions flang/include/flang/Frontend/CompilerInvocation.h
Original file line number Diff line number Diff line change
@@ -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:
@@ -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; }
5 changes: 4 additions & 1 deletion flang/include/flang/Semantics/semantics.h
Original file line number Diff line number Diff line change
@@ -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>
@@ -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 {
@@ -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);
@@ -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_;
3 changes: 3 additions & 0 deletions flang/include/flang/Semantics/symbol.h
Original file line number Diff line number Diff line change
@@ -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 &);
1 change: 1 addition & 0 deletions flang/lib/Frontend/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -11,6 +11,7 @@ add_flang_library(flangFrontend
TextDiagnosticPrinter.cpp
TextDiagnosticBuffer.cpp
TextDiagnostic.cpp
Warnings.cpp

DEPENDS
CUFDialect
3 changes: 2 additions & 1 deletion flang/lib/Frontend/CompilerInstance.cpp
Original file line number Diff line number Diff line change
@@ -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();

50 changes: 29 additions & 21 deletions flang/lib/Frontend/CompilerInvocation.cpp
Original file line number Diff line number Diff line change
@@ -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"
@@ -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;
}

@@ -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`.
@@ -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
@@ -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)
102 changes: 102 additions & 0 deletions flang/lib/Frontend/Warnings.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
//===--- Warnings.cpp -----------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// Command line warning options handler.
//
//===----------------------------------------------------------------------===//
//
// This file is responsible for handling all warning options. This includes
// a number of -Wfoo options and their variants, which are driven by TableGen-
// generated data, and the special cases -pedantic, -pedantic-errors, -w,
// -Werror, ...
//
// Each warning option controls any number of actual warnings.
// Given a warning option 'foo', the following are valid:
// -Wfoo, -Wno-foo, -Werror=foo
//
#include "clang/Basic/AllDiagnostics.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/DiagnosticDriver.h"
#include "clang/Basic/DiagnosticIDs.h"
#include "clang/Basic/DiagnosticOptions.h"
#include "llvm/ADT/StringRef.h"
#include <cstring>

namespace Fortran::frontend {

// EmitUnknownDiagWarning - Emit a warning and typo hint for unknown warning
// opts

static void EmitUnknownDiagWarning(clang::DiagnosticsEngine &diags,
clang::diag::Flavor flavor,
llvm::StringRef prefix,
llvm::StringRef opt) {
llvm::StringRef suggestion =
clang::DiagnosticIDs::getNearestOption(flavor, opt);
diags.Report(clang::diag::warn_unknown_diag_option)
<< (flavor == clang::diag::Flavor::WarningOrError ? 0 : 1)
<< (prefix.str() += std::string(opt)) << !suggestion.empty()
<< (prefix.str() += std::string(suggestion));
}

void processWarningOptions(clang::DiagnosticsEngine &diags,
const clang::DiagnosticOptions &opts) {
diags.setIgnoreAllWarnings(opts.IgnoreWarnings);
diags.setShowColors(opts.ShowColors);

// If -pedantic or -pedantic-errors was specified, then we want to map all
// extension diagnostics onto WARNING or ERROR.
if (opts.PedanticErrors)
diags.setExtensionHandlingBehavior(clang::diag::Severity::Error);
else if (opts.Pedantic)
diags.setExtensionHandlingBehavior(clang::diag::Severity::Warning);
else
diags.setExtensionHandlingBehavior(clang::diag::Severity::Ignored);

llvm::SmallVector<clang::diag::kind, 10> _diags;
const llvm::IntrusiveRefCntPtr<clang::DiagnosticIDs> diagIDs =
diags.getDiagnosticIDs();
for (unsigned i = 0, e = opts.Warnings.size(); i != e; ++i) {
const auto flavor = clang::diag::Flavor::WarningOrError;
llvm::StringRef opt = opts.Warnings[i];

// Check to see if this warning starts with "no-", if so, this is a
// negative form of the option.
bool isPositive = !opt.consume_front("no-");

// Figure out how this option affects the warning. If -Wfoo, map the
// diagnostic to a warning, if -Wno-foo, map it to ignore.
clang::diag::Severity mapping = isPositive ? clang::diag::Severity::Warning
: clang::diag::Severity::Ignored;

// -Werror/-Wno-error is a special case, not controlled by the option table.
// TODO: Adding support of "specifier" form of -Werror=foo.
if (opt == "error") {
diags.setWarningsAsErrors(isPositive);
continue;
}

if (std::optional<clang::diag::Group> group =
diagIDs->getGroupForWarningOption(opt)) {
if (!diagIDs->isFlangWarningOption(group.value())) {
// Warning option not supported by Flang
// FIXME : Updating diagnostic error message when all warning options
// will be supported
const unsigned diagID =
diags.getCustomDiagID(clang::DiagnosticsEngine::Error,
"Warning option \"%0\" not supported.");
diags.Report(diagID) << opt;
}
} else {
// Unkown warning option.
EmitUnknownDiagWarning(diags, flavor, isPositive ? "-W" : "-Wno-", opt);
}
diags.setSeverityForGroup(flavor, opt, mapping);
}
}
} // namespace Fortran::frontend
3 changes: 3 additions & 0 deletions flang/lib/Semantics/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -63,4 +63,7 @@ add_flang_library(FortranSemantics
FrontendOpenMP
FrontendOpenACC
TargetParser

CLANG_LIBS
clangBasic
)
4 changes: 2 additions & 2 deletions flang/lib/Semantics/semantics.cpp
Original file line number Diff line number Diff line change
@@ -346,9 +346,9 @@ SemanticsContext::SemanticsContext(
const common::IntrinsicTypeDefaultKinds &defaultKinds,
const common::LanguageFeatureControl &languageFeatures,
const common::LangOptions &langOpts,
parser::AllCookedSources &allCookedSources)
parser::AllCookedSources &allCookedSources, clang::DiagnosticsEngine &diags)
: defaultKinds_{defaultKinds}, languageFeatures_{languageFeatures},
langOpts_{langOpts}, allCookedSources_{allCookedSources},
langOpts_{langOpts}, allCookedSources_{allCookedSources}, diags_{diags},
intrinsics_{evaluate::IntrinsicProcTable::Configure(defaultKinds_)},
globalScope_{*this}, intrinsicModulesScope_{globalScope_.MakeScope(
Scope::Kind::IntrinsicModules, nullptr)},
7 changes: 7 additions & 0 deletions flang/test/Driver/w-arg-unknown.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
! Ensure that unknown warning options generate a warning message.

! RUN: %flang_fc1 -fsyntax-only -WX %s 2>&1 | FileCheck %s --check-prefix=UNKNOWN1
! RUN: %flang_fc1 -fsyntax-only -Werror2 %s 2>&1 | FileCheck %s --check-prefix=UNKNOWN2

! UNKNOWN1: unknown warning option '-WX'
! UNKNOWN2: unknown warning option '-Werror2'
6 changes: 0 additions & 6 deletions flang/test/Driver/werror-wrong.f90

This file was deleted.

4 changes: 2 additions & 2 deletions flang/test/Driver/wextra-ok.f90
Original file line number Diff line number Diff line change
@@ -2,10 +2,10 @@
! The first check should be changed if -Wextra is implemented

! RUN: %flang -std=f2018 -Wextra %s -c 2>&1 | FileCheck %s --check-prefix=CHECK-OK
! RUN: not %flang -std=f2018 -Wblah -Wextra %s -c 2>&1 | FileCheck %s --check-prefix=WRONG
! RUN: %flang -std=f2018 -Wblah -Wextra %s -c 2>&1 | FileCheck %s --check-prefix=WRONG

! CHECK-OK: the warning option '-Wextra' is not supported
! WRONG: Only `-Werror` is supported currently.
! WRONG: unknown warning option '-Wblah'

program wextra_ok
end program wextra_ok
5 changes: 5 additions & 0 deletions flang/tools/bbc/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -31,6 +31,11 @@ target_link_libraries(bbc PRIVATE
FlangOpenMPTransforms
)

clang_target_link_libraries(bbc PRIVATE
PRIVATE
clangBasic
)

mlir_target_link_libraries(bbc PRIVATE
${dialect_libs}
${extension_libs}
14 changes: 13 additions & 1 deletion flang/tools/bbc/bbc.cpp
Original file line number Diff line number Diff line change
@@ -15,7 +15,10 @@
//===----------------------------------------------------------------------===//

#include "flang/Frontend/CodeGenOptions.h"
#include "flang/Frontend/CompilerInstance.h"
#include "flang/Frontend/CompilerInvocation.h"
#include "flang/Frontend/TargetOptions.h"
#include "flang/Frontend/TextDiagnosticBuffer.h"
#include "flang/Lower/Bridge.h"
#include "flang/Lower/PFTBuilder.h"
#include "flang/Lower/Support/Verifier.h"
@@ -492,6 +495,15 @@ static llvm::LogicalResult convertFortranSourceToMLIR(
}

int main(int argc, char **argv) {
// Creating a SemanticsContext require a DiagnosticsEngine
Fortran::frontend::TextDiagnosticBuffer *diagsBuffer =
new Fortran::frontend::TextDiagnosticBuffer;
llvm::IntrusiveRefCntPtr<clang::DiagnosticIDs> diagID(
new clang::DiagnosticIDs());
llvm::IntrusiveRefCntPtr<clang::DiagnosticOptions> diagOpts =
new clang::DiagnosticOptions();
clang::DiagnosticsEngine diags(diagID, &*diagOpts, diagsBuffer);

[[maybe_unused]] llvm::InitLLVM y(argc, argv);
llvm::InitializeAllTargets();
llvm::InitializeAllTargetMCs();
@@ -573,7 +585,7 @@ int main(int argc, char **argv) {
Fortran::parser::AllSources allSources;
Fortran::parser::AllCookedSources allCookedSources(allSources);
Fortran::semantics::SemanticsContext semanticsContext{
defaultKinds, options.features, langOpts, allCookedSources};
defaultKinds, options.features, langOpts, allCookedSources, diags};
semanticsContext.set_moduleDirectory(moduleDir)
.set_moduleFileSuffix(moduleSuffix)
.set_searchDirectories(includeDirs)
10 changes: 9 additions & 1 deletion flang/tools/flang-driver/driver.cpp
Original file line number Diff line number Diff line change
@@ -115,12 +115,20 @@ int main(int argc, const char **argv) {

// Create DiagnosticsEngine for the compiler driver
llvm::IntrusiveRefCntPtr<clang::DiagnosticOptions> diagOpts =
createAndPopulateDiagOpts(args);
new clang::DiagnosticOptions();
llvm::IntrusiveRefCntPtr<clang::DiagnosticIDs> diagID(
new clang::DiagnosticIDs());
Fortran::frontend::TextDiagnosticPrinter *diagClient =
new Fortran::frontend::TextDiagnosticPrinter(llvm::errs(), &*diagOpts);

// Use the DiagnosticsEngine instance of the frontend driver
// for parsing the arguments
unsigned missingArgIndex, missingArgCount;
llvm::opt::InputArgList args2 = clang::driver::getDriverOptTable().ParseArgs(
args, missingArgIndex, missingArgCount,
llvm::opt::Visibility(clang::driver::options::FlangOption));
Fortran::frontend::parseDiagnosticArgs(*diagOpts, args2);

diagClient->setPrefix(
std::string(llvm::sys::path::stem(getExecutablePath(args[0]))));

19 changes: 11 additions & 8 deletions flang/tools/flang-driver/fc1_main.cpp
Original file line number Diff line number Diff line change
@@ -20,6 +20,7 @@
#include "flang/Frontend/CompilerInvocation.h"
#include "flang/Frontend/TextDiagnosticBuffer.h"
#include "flang/FrontendTool/Utils.h"
#include "clang/Driver/Driver.h"
#include "clang/Driver/DriverDiagnostic.h"
#include "llvm/MC/TargetRegistry.h"
#include "llvm/Option/Arg.h"
@@ -63,15 +64,17 @@ int fc1_main(llvm::ArrayRef<const char *> argv, const char *argv0) {
// them using a well formed diagnostic object.
TextDiagnosticBuffer *diagsBuffer = new TextDiagnosticBuffer;

// Create CompilerInvocation - use a dedicated instance of DiagnosticsEngine
// Use the DiagnosticsEngine instance of the frontend driver
// for parsing the arguments
llvm::IntrusiveRefCntPtr<clang::DiagnosticIDs> diagID(
new clang::DiagnosticIDs());
llvm::IntrusiveRefCntPtr<clang::DiagnosticOptions> diagOpts =
new clang::DiagnosticOptions();
clang::DiagnosticsEngine diags(diagID, &*diagOpts, diagsBuffer);
bool success = CompilerInvocation::createFromArgs(flang->getInvocation(),
argv, diags, argv0);
unsigned missingArgIndex, missingArgCount;
llvm::opt::InputArgList args = clang::driver::getDriverOptTable().ParseArgs(
argv.slice(0), missingArgIndex, missingArgCount,
llvm::opt::Visibility(clang::driver::options::FC1Option));
parseDiagnosticArgs(flang->getDiagnosticOpts(), args, false);

bool success = CompilerInvocation::createFromArgs(
flang->getInvocation(), argv, flang->getDiagnostics(), argv0);
processWarningOptions(flang->getDiagnostics(), flang->getDiagnosticOpts());

// Initialize targets first, so that --version shows registered targets.
llvm::InitializeAllTargets();