mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
swift-module-digester: refactor the ABI/API diagnostics to use DiagnosticEngine. NFC (#18957)
Before this patch, we used to define tooling-specific diagnostics. With adding more checking logics, we found this mechanism hard to extend. This patch eliminates the home-made diagnostics model to use the one from compiler, which provides several benefits: less boiler-templates, better integration with DiagnosticConsumer, and easy ordering of detected issues.
This commit is contained in:
@@ -672,6 +672,19 @@ namespace swift {
|
||||
return diagnose(Loc, Diagnostic(ID, std::move(Args)...));
|
||||
}
|
||||
|
||||
/// \brief Emit a diagnostic with the given set of diagnostic arguments.
|
||||
///
|
||||
/// \param ID The diagnostic to be emitted.
|
||||
///
|
||||
/// \param Args The diagnostic arguments, which will be converted to
|
||||
/// the types expected by the diagnostic \p ID.
|
||||
template<typename ...ArgTypes>
|
||||
InFlightDiagnostic
|
||||
diagnose(Diag<ArgTypes...> ID,
|
||||
typename detail::PassArgument<ArgTypes>::type... Args) {
|
||||
return diagnose(SourceLoc(), ID, std::move(Args)...);
|
||||
}
|
||||
|
||||
/// \brief Emit a diagnostic with the given set of diagnostic arguments.
|
||||
///
|
||||
/// \param Loc The declaration name location to which the
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
#include "DiagnosticsFrontend.def"
|
||||
#include "DiagnosticsDriver.def"
|
||||
#include "DiagnosticsRefactoring.def"
|
||||
#include "DiagnosticsModuleDiffer.def"
|
||||
|
||||
#undef DIAG_NO_UNDEF
|
||||
|
||||
|
||||
62
include/swift/AST/DiagnosticsModuleDiffer.def
Normal file
62
include/swift/AST/DiagnosticsModuleDiffer.def
Normal file
@@ -0,0 +1,62 @@
|
||||
//===--- DiagnosticsModuleDiffer.def - Diagnostics Text ---------*- C++ -*-===//
|
||||
//
|
||||
// This source file is part of the Swift.org open source project
|
||||
//
|
||||
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
|
||||
// Licensed under Apache License v2.0 with Runtime Library Exception
|
||||
//
|
||||
// See https://swift.org/LICENSE.txt for license information
|
||||
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines diagnostics emitted during diffing two Swift modules.
|
||||
// Each diagnostic is described using one of three kinds (error, warning, or
|
||||
// note) along with a unique identifier, category, options, and text, and is
|
||||
// followed by a signature describing the diagnostic argument kinds.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#if !(defined(DIAG) || (defined(ERROR) && defined(WARNING) && defined(NOTE)))
|
||||
# error Must define either DIAG or the set {ERROR,WARNING,NOTE}
|
||||
#endif
|
||||
|
||||
#ifndef ERROR
|
||||
# define ERROR(ID,Options,Text,Signature) \
|
||||
DIAG(ERROR,ID,Options,Text,Signature)
|
||||
#endif
|
||||
|
||||
#ifndef WARNING
|
||||
# define WARNING(ID,Options,Text,Signature) \
|
||||
DIAG(WARNING,ID,Options,Text,Signature)
|
||||
#endif
|
||||
|
||||
#ifndef NOTE
|
||||
# define NOTE(ID,Options,Text,Signature) \
|
||||
DIAG(NOTE,ID,Options,Text,Signature)
|
||||
#endif
|
||||
|
||||
ERROR(generic_sig_change,none,"%0 has generic signature change from %1 to %2", (StringRef, StringRef, StringRef))
|
||||
|
||||
ERROR(raw_type_change,none,"%0(%1) is now %2 representable", (StringRef, StringRef, StringRef))
|
||||
|
||||
ERROR(removed_decl,none,"%0 has been removed%select{| (deprecated)}1", (StringRef, bool))
|
||||
|
||||
ERROR(moved_decl,none,"%0 has been moved to %1", (StringRef, StringRef))
|
||||
|
||||
ERROR(renamed_decl,none,"%0 has been renamed to %1", (StringRef, StringRef))
|
||||
|
||||
ERROR(decl_type_change,none,"%0 has %1 type change from %2 to %3", (StringRef, StringRef, StringRef, StringRef))
|
||||
|
||||
ERROR(decl_attr_change,none,"%0 changes from %1 to %2", (StringRef, StringRef, StringRef))
|
||||
|
||||
ERROR(decl_new_attr,none,"%0 is now %1", (StringRef, StringRef))
|
||||
|
||||
#ifndef DIAG_NO_UNDEF
|
||||
# if defined(DIAG)
|
||||
# undef DIAG
|
||||
# endif
|
||||
# undef NOTE
|
||||
# undef WARNING
|
||||
# undef ERROR
|
||||
#endif
|
||||
32
include/swift/AST/DiagnosticsModuleDiffer.h
Normal file
32
include/swift/AST/DiagnosticsModuleDiffer.h
Normal file
@@ -0,0 +1,32 @@
|
||||
//===--- DiagnosticsModuleDiffer.h - Diagnostic Definitions ----*- C++ -*-===//
|
||||
//
|
||||
// This source file is part of the Swift.org open source project
|
||||
//
|
||||
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
|
||||
// Licensed under Apache License v2.0 with Runtime Library Exception
|
||||
//
|
||||
// See https://swift.org/LICENSE.txt for license information
|
||||
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
/// \file
|
||||
/// \brief This file defines diagnostics for the Swift module differ.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef SWIFT_DIAGNOSTICS_MODULE_DIFFER_H
|
||||
#define SWIFT_DIAGNOSTICS_MODULE_DIFFER_H
|
||||
|
||||
#include "swift/AST/DiagnosticsCommon.h"
|
||||
|
||||
namespace swift {
|
||||
namespace diag {
|
||||
// Declare common diagnostics objects with their appropriate types.
|
||||
#define DIAG(KIND,ID,Options,Text,Signature) \
|
||||
extern detail::DiagWithArguments<void Signature>::type ID;
|
||||
#include "DiagnosticsModuleDiffer.def"
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -60,6 +60,11 @@ raw_ostream &operator<<(raw_ostream &Out, const NodeAnnotation Value);
|
||||
// Redefine << so that we can output the name of the node kind.
|
||||
raw_ostream &operator<<(raw_ostream &Out, const SDKNodeKind Value);
|
||||
|
||||
StringRef getDeclKindStr(const DeclKind Value);
|
||||
|
||||
// Redefine << so that we can output the name of decl kind.
|
||||
raw_ostream &operator<<(raw_ostream &Out, const DeclKind Value);
|
||||
|
||||
struct APIDiffItem {
|
||||
virtual void streamDef(llvm::raw_ostream &S) const = 0;
|
||||
virtual APIDiffItemKind getKind() const = 0;
|
||||
|
||||
@@ -23,7 +23,7 @@ using namespace swift;
|
||||
using namespace ide;
|
||||
using namespace api;
|
||||
|
||||
inline raw_ostream &swift::ide::api::
|
||||
raw_ostream &swift::ide::api::
|
||||
operator<<(raw_ostream &Out, const SDKNodeKind Value) {
|
||||
switch (Value) {
|
||||
#define NODE_KIND(Name, Value) case SDKNodeKind::Name: return Out << #Value;
|
||||
@@ -32,13 +32,26 @@ operator<<(raw_ostream &Out, const SDKNodeKind Value) {
|
||||
llvm_unreachable("Undefined SDK node kind.");
|
||||
}
|
||||
|
||||
inline raw_ostream &swift::ide::api::
|
||||
raw_ostream &swift::ide::api::
|
||||
operator<<(raw_ostream &Out, const NodeAnnotation Value) {
|
||||
#define NODE_ANNOTATION(X) if (Value == NodeAnnotation::X) { return Out << #X; }
|
||||
#include "swift/IDE/DigesterEnums.def"
|
||||
llvm_unreachable("Undefined SDK node kind.");
|
||||
}
|
||||
|
||||
StringRef swift::ide::api::getDeclKindStr(const DeclKind Value) {
|
||||
switch (Value) {
|
||||
#define DECL(X, PARENT) case DeclKind::X: return #X;
|
||||
#include "swift/AST/DeclNodes.def"
|
||||
}
|
||||
llvm_unreachable("Unhandled DeclKind in switch.");
|
||||
}
|
||||
|
||||
raw_ostream &swift::ide::api::operator<<(raw_ostream &Out,
|
||||
const DeclKind Value) {
|
||||
return Out << getDeclKindStr(Value);
|
||||
}
|
||||
|
||||
Optional<SDKNodeKind> swift::ide::api::parseSDKNodeKind(StringRef Content) {
|
||||
return llvm::StringSwitch<Optional<SDKNodeKind>>(Content)
|
||||
#define NODE_KIND(NAME, VALUE) .Case(#VALUE, SDKNodeKind::NAME)
|
||||
|
||||
@@ -11,8 +11,8 @@ cake1: Func C4.foo() has been removed
|
||||
/* Moved Decls */
|
||||
|
||||
/* Renamed Decls */
|
||||
cake1: Struct Somestruct2 has been renamed to Struct NSSomestruct2
|
||||
cake1: Func S1.foo5(x:y:) has been renamed to Func S1.foo5(x:y:z:)
|
||||
cake1: Struct Somestruct2 has been renamed to Struct NSSomestruct2
|
||||
|
||||
/* Type Changes */
|
||||
cake1: Constructor S1.init(_:) has parameter 0 type change from Int to Double
|
||||
@@ -20,12 +20,12 @@ cake1: Func C1.foo2(_:) has parameter 0 type change from Int to () -> ()
|
||||
cake1: Func Somestruct2.foo1(_:) has parameter 0 type change from C3 to C1
|
||||
|
||||
/* Decl Attribute changes */
|
||||
cake1: Enum IceKind is now without @_frozen
|
||||
cake1: Struct C6 is now with @_fixed_layout
|
||||
cake1: Class C5 is now without @objc
|
||||
cake1: Var C1.CIIns1 changes from weak to strong
|
||||
cake1: Var C1.CIIns2 changes from strong to weak
|
||||
cake1: Enum IceKind is now without @_frozen
|
||||
cake1: Func C1.foo1() is now not static
|
||||
cake1: Func C5.dy_foo() is now with dynamic
|
||||
cake1: Func S1.foo1() is now mutating
|
||||
cake1: Func S1.foo3() is now static
|
||||
cake1: Struct C6 is now with @_fixed_layout
|
||||
cake1: Var C1.CIIns1 changes from weak to strong
|
||||
cake1: Var C1.CIIns2 changes from strong to weak
|
||||
|
||||
@@ -11,16 +11,16 @@ cake1: Func C4.foo() has been removed
|
||||
/* Moved Decls */
|
||||
|
||||
/* Renamed Decls */
|
||||
cake1: Struct Somestruct2 has been renamed to Struct NSSomestruct2
|
||||
cake1: Func S1.foo5(x:y:) has been renamed to Func S1.foo5(x:y:z:)
|
||||
cake1: Struct Somestruct2 has been renamed to Struct NSSomestruct2
|
||||
|
||||
/* Type Changes */
|
||||
cake1: Constructor S1.init(_:) has parameter 0 type change from Int to Double
|
||||
cake1: Func C1.foo2(_:) has parameter 0 type change from Int to () -> ()
|
||||
|
||||
/* Decl Attribute changes */
|
||||
cake1: Var C1.CIIns1 changes from weak to strong
|
||||
cake1: Var C1.CIIns2 changes from strong to weak
|
||||
cake1: Func C1.foo1() is now not static
|
||||
cake1: Func S1.foo1() is now mutating
|
||||
cake1: Func S1.foo3() is now static
|
||||
cake1: Var C1.CIIns1 changes from weak to strong
|
||||
cake1: Var C1.CIIns2 changes from strong to weak
|
||||
|
||||
@@ -4,17 +4,6 @@
|
||||
/* RawRepresentable Changes */
|
||||
|
||||
/* Removed Decls */
|
||||
TypeAlias AbsoluteValuable has been removed
|
||||
TypeAlias BitwiseOperations has been removed (deprecated)
|
||||
TypeAlias IntMax has been removed
|
||||
TypeAlias Integer has been removed
|
||||
TypeAlias IntegerArithmetic has been removed
|
||||
TypeAlias SignedNumber has been removed
|
||||
TypeAlias StringProtocol.UTF16Index has been removed (deprecated)
|
||||
TypeAlias StringProtocol.UTF8Index has been removed (deprecated)
|
||||
TypeAlias StringProtocol.UnicodeScalarIndex has been removed (deprecated)
|
||||
TypeAlias UIntMax has been removed
|
||||
Var FixedWidthInteger.allZeros has been removed (deprecated)
|
||||
Constructor Int.init(truncatingBitPattern:) has been removed
|
||||
Constructor Int16.init(truncatingBitPattern:) has been removed
|
||||
Constructor Int32.init(truncatingBitPattern:) has been removed
|
||||
@@ -64,6 +53,17 @@ Func UInt32.toIntMax() has been removed
|
||||
Func UInt64.toIntMax() has been removed
|
||||
Func UInt8.toIntMax() has been removed
|
||||
Func UnsignedInteger.toUIntMax() has been removed
|
||||
TypeAlias AbsoluteValuable has been removed
|
||||
TypeAlias BitwiseOperations has been removed (deprecated)
|
||||
TypeAlias IntMax has been removed
|
||||
TypeAlias Integer has been removed
|
||||
TypeAlias IntegerArithmetic has been removed
|
||||
TypeAlias SignedNumber has been removed
|
||||
TypeAlias StringProtocol.UTF16Index has been removed (deprecated)
|
||||
TypeAlias StringProtocol.UTF8Index has been removed (deprecated)
|
||||
TypeAlias StringProtocol.UnicodeScalarIndex has been removed (deprecated)
|
||||
TypeAlias UIntMax has been removed
|
||||
Var FixedWidthInteger.allZeros has been removed (deprecated)
|
||||
|
||||
/* Moved Decls */
|
||||
|
||||
@@ -72,12 +72,13 @@ Func Dictionary.filter(_:obsoletedInSwift4:) has been renamed to Func Dictionary
|
||||
Func Set.filter(_:obsoletedInSwift4:) has been renamed to Func Set.filter(_:)
|
||||
|
||||
/* Type Changes */
|
||||
Var Dictionary.keys has declared type change from LazyMapCollection<[Key : Value], Key> to Dictionary<Key, Value>.Keys
|
||||
Var Dictionary.values has declared type change from LazyMapCollection<[Key : Value], Value> to Dictionary<Key, Value>.Values
|
||||
Constructor String.init(_:) has return type change from String? to String
|
||||
Func Dictionary.filter(_:obsoletedInSwift4:) has return type change from [Dictionary<Key, Value>.Element] to [Dictionary<Key, Value>.Key : Dictionary<Key, Value>.Value]
|
||||
Func Dictionary.makeIterator() has return type change from DictionaryIterator<Dictionary<Key, Value>.Key, Dictionary<Key, Value>.Value> to Dictionary<Key, Value>.Iterator
|
||||
Func Set.filter(_:obsoletedInSwift4:) has return type change from [Set<Element>.Element] to Set<Element>
|
||||
Func Set.makeIterator() has return type change from SetIterator<Element> to Set<Element>.Iterator
|
||||
Var Dictionary.keys has declared type change from LazyMapCollection<[Key : Value], Key> to Dictionary<Key, Value>.Keys
|
||||
Var Dictionary.values has declared type change from LazyMapCollection<[Key : Value], Value> to Dictionary<Key, Value>.Values
|
||||
|
||||
|
||||
/* Decl Attribute changes */
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
add_swift_host_tool(swift-api-digester
|
||||
swift-api-digester.cpp
|
||||
ModuleAnalyzerNodes.cpp
|
||||
ModuleDiagsConsumer.cpp
|
||||
LINK_LIBRARIES swiftFrontend swiftIDE
|
||||
SWIFT_COMPONENT tools
|
||||
)
|
||||
|
||||
@@ -293,6 +293,22 @@ SDKNode *SDKNodeRoot::getInstance(SDKContext &Ctx) {
|
||||
return Info.createSDKNode(SDKNodeKind::Root);
|
||||
}
|
||||
|
||||
StringRef SDKNodeDecl::getScreenInfo() const {
|
||||
auto ModuleName = getModuleName();
|
||||
auto HeaderName = getHeaderName();
|
||||
auto &Ctx = getSDKContext();
|
||||
llvm::SmallString<64> SS;
|
||||
llvm::raw_svector_ostream OS(SS);
|
||||
if (Ctx.getOpts().PrintModule)
|
||||
OS << ModuleName;
|
||||
if (!HeaderName.empty())
|
||||
OS << "(" << HeaderName << ")";
|
||||
if (!OS.str().empty())
|
||||
OS << ": ";
|
||||
OS << getDeclKind() << " " << getFullyQualifiedName();
|
||||
return Ctx.buffer(OS.str());
|
||||
}
|
||||
|
||||
bool SDKNodeDecl::isSDKPrivate() const {
|
||||
if (getName().startswith("__"))
|
||||
return true;
|
||||
|
||||
@@ -139,6 +139,7 @@ struct CheckerOptions {
|
||||
bool ABI;
|
||||
bool Verbose;
|
||||
bool AbortOnModuleLoadFailure;
|
||||
bool PrintModule;
|
||||
StringRef LocationFilter;
|
||||
};
|
||||
|
||||
@@ -303,6 +304,7 @@ public:
|
||||
bool hasDeclAttribute(DeclAttrKind DAKind) const;
|
||||
bool isStatic() const { return IsStatic; };
|
||||
StringRef getGenericSignature() const { return GenericSig; }
|
||||
StringRef getScreenInfo() const;
|
||||
};
|
||||
|
||||
class SDKNodeRoot: public SDKNode {
|
||||
|
||||
94
tools/swift-api-digester/ModuleDiagsConsumer.cpp
Normal file
94
tools/swift-api-digester/ModuleDiagsConsumer.cpp
Normal file
@@ -0,0 +1,94 @@
|
||||
//===--- ModuleDiagsConsumer.cpp - Print module differ diagnostics --*- C++ -*-===//
|
||||
//
|
||||
// This source file is part of the Swift.org open source project
|
||||
//
|
||||
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
|
||||
// Licensed under Apache License v2.0 with Runtime Library Exception
|
||||
//
|
||||
// See https://swift.org/LICENSE.txt for license information
|
||||
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file implements the ModuleDifferDiagsConsumer class, which displays
|
||||
// diagnostics from the module differ as text to an output.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "swift/AST/DiagnosticEngine.h"
|
||||
#include "swift/AST/DiagnosticsModuleDiffer.h"
|
||||
#include "ModuleDiagsConsumer.h"
|
||||
|
||||
using namespace swift;
|
||||
|
||||
namespace {
|
||||
// Reproduce the DiagIDs, as we want both the size and access to the raw ids
|
||||
// themselves.
|
||||
enum LocalDiagID : uint32_t {
|
||||
#define DIAG(KIND, ID, Options, Text, Signature) ID,
|
||||
#include "swift/AST/DiagnosticsAll.def"
|
||||
NumDiags
|
||||
};
|
||||
|
||||
static StringRef getCategoryName(uint32_t ID) {
|
||||
switch(ID) {
|
||||
case LocalDiagID::removed_decl:
|
||||
return "/* Removed Decls */";
|
||||
case LocalDiagID::moved_decl:
|
||||
return "/* Moved Decls */";
|
||||
case LocalDiagID::renamed_decl:
|
||||
return "/* Renamed Decls */";
|
||||
case LocalDiagID::decl_attr_change:
|
||||
case LocalDiagID::decl_new_attr:
|
||||
return "/* Decl Attribute changes */";
|
||||
case LocalDiagID::decl_type_change:
|
||||
return "/* Type Changes */";
|
||||
case LocalDiagID::raw_type_change:
|
||||
return "/* RawRepresentable Changes */";
|
||||
case LocalDiagID::generic_sig_change:
|
||||
return "/* Generic Signature Changes */";
|
||||
default:
|
||||
return StringRef();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
swift::ide::api::
|
||||
ModuleDifferDiagsConsumer::ModuleDifferDiagsConsumer():
|
||||
PrintingDiagnosticConsumer(llvm::errs()) {
|
||||
#define DIAG(KIND, ID, Options, Text, Signature) \
|
||||
auto ID = getCategoryName(LocalDiagID::ID); \
|
||||
assert(!ID.empty()); \
|
||||
AllDiags[ID] = std::set<std::string>();
|
||||
#include "swift/AST/DiagnosticsModuleDiffer.def"
|
||||
}
|
||||
|
||||
void swift::ide::api::
|
||||
ModuleDifferDiagsConsumer::handleDiagnostic(SourceManager &SM, SourceLoc Loc,
|
||||
DiagnosticKind Kind,
|
||||
StringRef FormatString,
|
||||
ArrayRef<DiagnosticArgument> FormatArgs,
|
||||
const DiagnosticInfo &Info) {
|
||||
auto Category = getCategoryName((uint32_t)Info.ID);
|
||||
if (Category.empty()) {
|
||||
PrintingDiagnosticConsumer::handleDiagnostic(SM, Loc, Kind, FormatString,
|
||||
FormatArgs, Info);
|
||||
return;
|
||||
}
|
||||
llvm::SmallString<256> Text;
|
||||
{
|
||||
llvm::raw_svector_ostream Out(Text);
|
||||
DiagnosticEngine::formatDiagnosticText(Out, FormatString, FormatArgs);
|
||||
}
|
||||
AllDiags[Category].insert(Text.str().str());
|
||||
}
|
||||
|
||||
swift::ide::api::ModuleDifferDiagsConsumer::~ModuleDifferDiagsConsumer() {
|
||||
for (auto &Pair: AllDiags) {
|
||||
llvm::outs() << "\n";
|
||||
llvm::outs() << Pair.first << "\n";
|
||||
for (auto &Item: Pair.second) {
|
||||
llvm::outs() << Item << "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
49
tools/swift-api-digester/ModuleDiagsConsumer.h
Normal file
49
tools/swift-api-digester/ModuleDiagsConsumer.h
Normal file
@@ -0,0 +1,49 @@
|
||||
//===--- ModuleDiagsConsumer.h - Print module differ diagnostics --*- C++ -*-===//
|
||||
//
|
||||
// This source file is part of the Swift.org open source project
|
||||
//
|
||||
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
|
||||
// Licensed under Apache License v2.0 with Runtime Library Exception
|
||||
//
|
||||
// See https://swift.org/LICENSE.txt for license information
|
||||
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines the ModuleDifferDiagsConsumer class, which displays
|
||||
// diagnostics from the module differ as text to an output.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef __SWIFT_MODULE_DIFFER_DIAGS_CONSUMER_H__
|
||||
#define __SWIFT_MODULE_DIFFER_DIAGS_CONSUMER_H__
|
||||
|
||||
#include "llvm/ADT/MapVector.h"
|
||||
#include "swift/Basic/LLVM.h"
|
||||
#include "swift/AST/DiagnosticConsumer.h"
|
||||
#include "swift/Frontend/PrintingDiagnosticConsumer.h"
|
||||
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include <set>
|
||||
|
||||
namespace swift {
|
||||
namespace ide {
|
||||
namespace api {
|
||||
|
||||
/// \brief Diagnostic consumer that displays diagnostics to standard output.
|
||||
class ModuleDifferDiagsConsumer: public PrintingDiagnosticConsumer {
|
||||
llvm::MapVector<StringRef, std::set<std::string>> AllDiags;
|
||||
public:
|
||||
ModuleDifferDiagsConsumer();
|
||||
~ModuleDifferDiagsConsumer();
|
||||
void handleDiagnostic(SourceManager &SM, SourceLoc Loc,
|
||||
DiagnosticKind Kind,
|
||||
StringRef FormatString,
|
||||
ArrayRef<DiagnosticArgument> FormatArgs,
|
||||
const DiagnosticInfo &Info) override;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -26,8 +26,11 @@
|
||||
// can be reflected as source-breaking changes for API users. If they are,
|
||||
// the output of api-digester will include such changes.
|
||||
|
||||
#include "swift/AST/DiagnosticsModuleDiffer.h"
|
||||
#include "swift/IDE/APIDigesterData.h"
|
||||
#include <functional>
|
||||
#include <ModuleAnalyzerNodes.h>
|
||||
#include "ModuleAnalyzerNodes.h"
|
||||
#include "ModuleDiagsConsumer.h"
|
||||
|
||||
using namespace swift;
|
||||
using namespace ide;
|
||||
@@ -1478,16 +1481,6 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
// Redefine << so that we can output the name of decl kind.
|
||||
raw_ostream &operator<<(raw_ostream &Out, const DeclKind Value) {
|
||||
switch (Value) {
|
||||
#define DECL(X, PARENT) case DeclKind::X: return Out << #X;
|
||||
#include "swift/AST/DeclNodes.def"
|
||||
}
|
||||
|
||||
llvm_unreachable("Unhandled DeclKind in switch.");
|
||||
}
|
||||
|
||||
class DiagnosisEmitter : public SDKNodeVisitor {
|
||||
void handle(const SDKNodeDecl *D, NodeAnnotation Anno);
|
||||
void visitType(SDKNodeType *T);
|
||||
@@ -1495,182 +1488,18 @@ class DiagnosisEmitter : public SDKNodeVisitor {
|
||||
void visit(NodePtr Node) override;
|
||||
SDKNodeDecl *findAddedDecl(const SDKNodeDecl *Node);
|
||||
bool findTypeAliasDecl(const SDKNodeDecl *Node);
|
||||
static StringRef printName(StringRef Name);
|
||||
static StringRef printDiagKeyword(StringRef Name);
|
||||
static void collectAddedDecls(NodePtr Root, std::set<SDKNodeDecl*> &Results);
|
||||
|
||||
template<typename T>
|
||||
struct DiagBag {
|
||||
std::vector<T> Diags;
|
||||
~DiagBag() {
|
||||
llvm::outs() << "\n/* ";
|
||||
T::theme(llvm::outs());
|
||||
llvm::outs() << " */\n";
|
||||
removeRedundantAndSort(Diags);
|
||||
std::for_each(Diags.begin(), Diags.end(), [](T &Diag) {
|
||||
if (Diag.isABISpecific() && !options::Abi)
|
||||
return;
|
||||
Diag.outputModule();
|
||||
Diag.output();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
struct MetaInfo {
|
||||
StringRef ModuleName;
|
||||
StringRef HeaderName;
|
||||
DeclKind Kind;
|
||||
StringRef Name;
|
||||
bool IsABISpecific;
|
||||
MetaInfo(const SDKNodeDecl *Node, bool IsABISpecific):
|
||||
ModuleName(Node->getModuleName()), HeaderName(Node->getHeaderName()),
|
||||
Kind(Node->getDeclKind()), Name(Node->getFullyQualifiedName()),
|
||||
IsABISpecific(IsABISpecific) {}
|
||||
int compare(MetaInfo &Other) const {
|
||||
if (ModuleName != Other.ModuleName)
|
||||
return ModuleName.compare(Other.ModuleName);
|
||||
if (HeaderName != Other.HeaderName)
|
||||
return HeaderName.compare(Other.HeaderName);
|
||||
if (Kind != Other.Kind)
|
||||
return (uint8_t)Kind - (uint8_t)Other.Kind;
|
||||
return Name.compare(Other.Name);
|
||||
}
|
||||
};
|
||||
|
||||
class DiagBase {
|
||||
protected:
|
||||
MetaInfo Info;
|
||||
DiagBase(MetaInfo Info): Info(Info) {}
|
||||
virtual ~DiagBase() = default;
|
||||
raw_ostream &outputName() const {
|
||||
return llvm::outs() << Info.Kind << " " << printName(Info.Name);
|
||||
}
|
||||
public:
|
||||
void outputModule() const {
|
||||
if (options::PrintModule) {
|
||||
llvm::outs() << Info.ModuleName;
|
||||
if (!Info.HeaderName.empty())
|
||||
llvm::outs() << "(" << Info.HeaderName << ")";
|
||||
llvm::outs() << ": ";
|
||||
}
|
||||
}
|
||||
virtual void output() const = 0;
|
||||
bool isABISpecific() const { return Info.IsABISpecific; }
|
||||
};
|
||||
|
||||
struct RemovedDeclDiag: public DiagBase {
|
||||
DeclKind Kind;
|
||||
StringRef Name;
|
||||
bool IsDeprecated;
|
||||
RemovedDeclDiag(MetaInfo Info, bool IsDeprecated): DiagBase(Info),
|
||||
IsDeprecated(IsDeprecated) {}
|
||||
bool operator<(RemovedDeclDiag Other) const {
|
||||
return Info.compare(Other.Info) < 0;
|
||||
}
|
||||
void output() const override;
|
||||
static void theme(raw_ostream &OS) { OS << "Removed Decls"; };
|
||||
};
|
||||
|
||||
struct MovedDeclDiag: public DiagBase {
|
||||
DeclKind AddedKind;
|
||||
StringRef AddedName;
|
||||
MovedDeclDiag(MetaInfo Info, DeclKind AddedKind, StringRef AddedName):
|
||||
DiagBase(Info), AddedKind(AddedKind), AddedName(AddedName) {}
|
||||
bool operator<(MovedDeclDiag Other) const {
|
||||
return Info.compare(Other.Info) < 0;
|
||||
}
|
||||
void output() const override;
|
||||
static void theme(raw_ostream &OS) { OS << "Moved Decls"; };
|
||||
};
|
||||
|
||||
struct RenamedDeclDiag: public DiagBase {
|
||||
DeclKind KindAfter;
|
||||
StringRef NameAfter;
|
||||
RenamedDeclDiag(MetaInfo Info, DeclKind KindAfter, StringRef NameAfter):
|
||||
DiagBase(Info), KindAfter(KindAfter), NameAfter(NameAfter) {}
|
||||
bool operator<(RenamedDeclDiag Other) const {
|
||||
return Info.compare(Other.Info) < 0;
|
||||
};
|
||||
void output() const override;
|
||||
static void theme(raw_ostream &OS) { OS << "Renamed Decls"; };
|
||||
};
|
||||
|
||||
struct DeclAttrDiag: public DiagBase {
|
||||
StringRef AttrBefore;
|
||||
StringRef AttrAfter;
|
||||
DeclAttrDiag(MetaInfo Info, StringRef AttrBefore, StringRef AttrAfter):
|
||||
DiagBase(Info), AttrBefore(AttrBefore), AttrAfter(AttrAfter) {}
|
||||
DeclAttrDiag(MetaInfo Info, StringRef AttrAfter): DeclAttrDiag(Info,
|
||||
StringRef(), AttrAfter) {}
|
||||
bool operator<(DeclAttrDiag Other) const;
|
||||
void output() const override;
|
||||
static void theme(raw_ostream &OS) { OS << "Decl Attribute changes"; };
|
||||
};
|
||||
|
||||
struct DeclTypeChangeDiag: public DiagBase {
|
||||
StringRef TypeNameBefore;
|
||||
StringRef TypeNameAfter;
|
||||
StringRef Description;
|
||||
DeclTypeChangeDiag(MetaInfo Info, StringRef TypeNameBefore,
|
||||
StringRef TypeNameAfter,
|
||||
StringRef Description): DiagBase(Info),
|
||||
TypeNameBefore(TypeNameBefore), TypeNameAfter(TypeNameAfter),
|
||||
Description(Description) {}
|
||||
bool operator<(DeclTypeChangeDiag Other) const {
|
||||
return Info.compare(Other.Info) < 0;
|
||||
};
|
||||
void output() const override;
|
||||
static void theme(raw_ostream &OS) { OS << "Type Changes"; };
|
||||
};
|
||||
|
||||
struct RawRepresentableChangeDiag: public DiagBase {
|
||||
StringRef UnderlyingType;
|
||||
StringRef RawTypeName;
|
||||
RawRepresentableChangeDiag(MetaInfo Info, StringRef UnderlyingType,
|
||||
StringRef RawTypeName): DiagBase(Info), UnderlyingType(UnderlyingType),
|
||||
RawTypeName(RawTypeName) {}
|
||||
bool operator<(RawRepresentableChangeDiag Other) const {
|
||||
return Info.compare(Other.Info) < 0;
|
||||
}
|
||||
void output() const override {
|
||||
outputName() << "(" << UnderlyingType << ")"
|
||||
<< " is now " << RawTypeName << " representable\n";
|
||||
}
|
||||
static void theme(raw_ostream &OS) { OS << "RawRepresentable Changes"; };
|
||||
};
|
||||
|
||||
struct GenericSignatureChangeDiag: public DiagBase {
|
||||
StringRef GSBefore;
|
||||
StringRef GSAfter;
|
||||
GenericSignatureChangeDiag(MetaInfo Info, StringRef GSBefore,
|
||||
StringRef GSAfter): DiagBase(Info),
|
||||
GSBefore(GSBefore), GSAfter(GSAfter) {}
|
||||
bool operator<(GenericSignatureChangeDiag Other) const {
|
||||
return Info.compare(Other.Info) < 0;
|
||||
}
|
||||
void output() const override {
|
||||
outputName() << " has generic signature change from " << GSBefore << " to "
|
||||
<< GSAfter << "\n";
|
||||
}
|
||||
static void theme(raw_ostream &OS) { OS << "Generic Signature Changes"; };
|
||||
};
|
||||
|
||||
std::set<SDKNodeDecl*> AddedDecls;
|
||||
DiagBag<DeclAttrDiag> AttrChangedDecls;
|
||||
DiagBag<DeclTypeChangeDiag> TypeChangedDecls;
|
||||
DiagBag<RenamedDeclDiag> RenamedDecls;
|
||||
DiagBag<MovedDeclDiag> MovedDecls;
|
||||
DiagBag<RemovedDeclDiag> RemovedDecls;
|
||||
DiagBag<RawRepresentableChangeDiag> RawRepresentableDecls;
|
||||
DiagBag<GenericSignatureChangeDiag> GSChangeDecls;
|
||||
|
||||
UpdatedNodesMap &UpdateMap;
|
||||
NodeMap &TypeAliasUpdateMap;
|
||||
TypeMemberDiffVector &MemberChanges;
|
||||
DiagnosticEngine &Diags;
|
||||
DiagnosisEmitter(SDKContext &Ctx):
|
||||
UpdateMap(Ctx.getNodeUpdateMap()),
|
||||
TypeAliasUpdateMap(Ctx.getTypeAliasUpdateMap()),
|
||||
MemberChanges(Ctx.getTypeMemberDiffs()){}
|
||||
MemberChanges(Ctx.getTypeMemberDiffs()), Diags(Ctx.getDiags()) {}
|
||||
|
||||
public:
|
||||
static void diagnosis(NodePtr LeftRoot, NodePtr RightRoot,
|
||||
@@ -1707,58 +1536,6 @@ bool DiagnosisEmitter::findTypeAliasDecl(const SDKNodeDecl *Node) {
|
||||
});
|
||||
}
|
||||
|
||||
StringRef DiagnosisEmitter::printName(StringRef Name) {
|
||||
OSColor Color(llvm::outs(), llvm::raw_ostream::CYAN);
|
||||
Color << Name;
|
||||
return StringRef();
|
||||
}
|
||||
|
||||
StringRef DiagnosisEmitter::printDiagKeyword(StringRef Name) {
|
||||
OSColor Color(llvm::outs(), llvm::raw_ostream::YELLOW);
|
||||
Color << Name;
|
||||
return StringRef();
|
||||
}
|
||||
|
||||
void DiagnosisEmitter::RemovedDeclDiag::output() const {
|
||||
outputName() << " has been " << printDiagKeyword("removed");
|
||||
if (IsDeprecated)
|
||||
llvm::outs() << " (deprecated)";
|
||||
llvm::outs() << "\n";
|
||||
}
|
||||
|
||||
void DiagnosisEmitter::MovedDeclDiag::output() const {
|
||||
outputName() << " has been " << printDiagKeyword("moved") << " to "
|
||||
<< AddedKind << " " << printName(AddedName) << "\n";
|
||||
}
|
||||
|
||||
void DiagnosisEmitter::RenamedDeclDiag::output() const {
|
||||
outputName() << " has been " << printDiagKeyword("renamed") << " to "
|
||||
<< KindAfter << " " << printName(NameAfter) << "\n";
|
||||
}
|
||||
|
||||
void DiagnosisEmitter::DeclTypeChangeDiag::output() const {
|
||||
outputName() << " has "
|
||||
<< Description << " type change from "
|
||||
<< printName(TypeNameBefore) << " to "
|
||||
<< printName(TypeNameAfter) << "\n";
|
||||
}
|
||||
|
||||
|
||||
bool DiagnosisEmitter::DeclAttrDiag::operator<(DeclAttrDiag Other) const {
|
||||
auto result = Info.compare(Other.Info);
|
||||
if (result)
|
||||
return result < 0;
|
||||
return AttrAfter.compare(Other.AttrAfter) < 0;
|
||||
}
|
||||
|
||||
void DiagnosisEmitter::DeclAttrDiag::output() const {
|
||||
if (AttrBefore.empty())
|
||||
outputName() << " is now " << printDiagKeyword(AttrAfter)<< "\n";
|
||||
else
|
||||
outputName() << " changes from " << printDiagKeyword(AttrBefore)
|
||||
<< " to "<< printDiagKeyword(AttrAfter)<< "\n";
|
||||
}
|
||||
|
||||
void DiagnosisEmitter::diagnosis(NodePtr LeftRoot, NodePtr RightRoot,
|
||||
SDKContext &Ctx) {
|
||||
DiagnosisEmitter Emitter(Ctx);
|
||||
@@ -1771,16 +1548,15 @@ void DiagnosisEmitter::handle(const SDKNodeDecl *Node, NodeAnnotation Anno) {
|
||||
auto &Ctx = Node->getSDKContext();
|
||||
switch(Anno) {
|
||||
case NodeAnnotation::Removed: {
|
||||
MetaInfo ScreenInfo(Node, false);
|
||||
// If we can find a type alias decl with the same name of this type, we
|
||||
// consider the type is not removed.
|
||||
if (findTypeAliasDecl(Node))
|
||||
return;
|
||||
if (auto *Added = findAddedDecl(Node)) {
|
||||
if (Node->getDeclKind() != DeclKind::Constructor) {
|
||||
MovedDecls.Diags.emplace_back(ScreenInfo,
|
||||
Added->getDeclKind(),
|
||||
Added->getFullyQualifiedName());
|
||||
Diags.diagnose(diag::moved_decl, Node->getScreenInfo(),
|
||||
Ctx.buffer((Twine(getDeclKindStr(Added->getDeclKind())) + " " +
|
||||
Added->getFullyQualifiedName()).str()));
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1790,8 +1566,9 @@ void DiagnosisEmitter::handle(const SDKNodeDecl *Node, NodeAnnotation Anno) {
|
||||
auto It = std::find_if(MemberChanges.begin(), MemberChanges.end(),
|
||||
[&](TypeMemberDiffItem &Item) { return Item.usr == Node->getUsr(); });
|
||||
if (It != MemberChanges.end()) {
|
||||
RenamedDecls.Diags.emplace_back(ScreenInfo, Node->getDeclKind(),
|
||||
Ctx.buffer((Twine(It->newTypeName) + "." + It->newPrintedName).str()));
|
||||
Diags.diagnose(diag::renamed_decl, Node->getScreenInfo(),
|
||||
Ctx.buffer((Twine(getDeclKindStr(Node->getDeclKind())) + " " +
|
||||
It->newTypeName + "." + It->newPrintedName).str()));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1800,7 +1577,7 @@ void DiagnosisEmitter::handle(const SDKNodeDecl *Node, NodeAnnotation Anno) {
|
||||
// refine diagnostics message instead of showing the type alias has been
|
||||
// removed.
|
||||
if (TypeAliasUpdateMap.find((SDKNode*)Node) != TypeAliasUpdateMap.end()) {
|
||||
RawRepresentableDecls.Diags.emplace_back(ScreenInfo,
|
||||
Diags.diagnose(diag::raw_type_change, Node->getScreenInfo(),
|
||||
Node->getAs<SDKNodeDeclTypeAlias>()->getUnderlyingType()->getPrintedName(),
|
||||
TypeAliasUpdateMap[(SDKNode*)Node]->getAs<SDKNodeDeclType>()->
|
||||
getRawValueType()->getPrintedName());
|
||||
@@ -1822,53 +1599,47 @@ void DiagnosisEmitter::handle(const SDKNodeDecl *Node, NodeAnnotation Anno) {
|
||||
}
|
||||
if (FoundInSuperclass)
|
||||
return;
|
||||
RemovedDecls.Diags.emplace_back(ScreenInfo,
|
||||
Node->isDeprecated());
|
||||
Diags.diagnose(diag::removed_decl, Node->getScreenInfo(), Node->isDeprecated());
|
||||
return;
|
||||
}
|
||||
case NodeAnnotation::Rename: {
|
||||
MetaInfo ScreenInfo(Node, false);
|
||||
auto *Count = UpdateMap.findUpdateCounterpart(Node)->getAs<SDKNodeDecl>();
|
||||
RenamedDecls.Diags.emplace_back(ScreenInfo,
|
||||
Count->getDeclKind(),
|
||||
Count->getFullyQualifiedName());
|
||||
Diags.diagnose(diag::renamed_decl, Node->getScreenInfo(),
|
||||
Ctx.buffer((Twine(getDeclKindStr(Count->getDeclKind())) + " " +
|
||||
Count->getFullyQualifiedName()).str()));
|
||||
return;
|
||||
}
|
||||
case NodeAnnotation::NowMutating: {
|
||||
MetaInfo ScreenInfo(Node, false);
|
||||
AttrChangedDecls.Diags.emplace_back(ScreenInfo, Ctx.buffer("mutating"));
|
||||
Diags.diagnose(diag::decl_new_attr, Node->getScreenInfo(),
|
||||
Ctx.buffer("mutating"));
|
||||
return;
|
||||
}
|
||||
case NodeAnnotation::NowThrowing: {
|
||||
MetaInfo ScreenInfo(Node, false);
|
||||
AttrChangedDecls.Diags.emplace_back(ScreenInfo, Ctx.buffer("throwing"));
|
||||
Diags.diagnose(diag::decl_new_attr, Node->getScreenInfo(),
|
||||
Ctx.buffer("throwing"));
|
||||
return;
|
||||
}
|
||||
case NodeAnnotation::StaticChange: {
|
||||
MetaInfo ScreenInfo(Node, false);
|
||||
AttrChangedDecls.Diags.emplace_back(ScreenInfo,
|
||||
Ctx.buffer(Node->isStatic() ? "not static" : "static"));
|
||||
Diags.diagnose(diag::decl_new_attr, Node->getScreenInfo(),
|
||||
Ctx.buffer(Node->isStatic() ? "not static" : "static"));
|
||||
return;
|
||||
}
|
||||
case NodeAnnotation::OwnershipChange: {
|
||||
MetaInfo ScreenInfo(Node, false);
|
||||
auto getOwnershipDescription = [&](swift::ReferenceOwnership O) {
|
||||
if (O == ReferenceOwnership::Strong)
|
||||
return Ctx.buffer("strong");
|
||||
return keywordOf(O);
|
||||
};
|
||||
auto *Count = UpdateMap.findUpdateCounterpart(Node)->getAs<SDKNodeDecl>();
|
||||
AttrChangedDecls.Diags.emplace_back(
|
||||
ScreenInfo,
|
||||
getOwnershipDescription(Node->getReferenceOwnership()),
|
||||
getOwnershipDescription(Count->getReferenceOwnership()));
|
||||
Diags.diagnose(diag::decl_attr_change, Node->getScreenInfo(),
|
||||
getOwnershipDescription(Node->getReferenceOwnership()),
|
||||
getOwnershipDescription(Count->getReferenceOwnership()));
|
||||
return;
|
||||
}
|
||||
case NodeAnnotation::ChangeGenericSignature: {
|
||||
MetaInfo ScreenInfo(Node, false);
|
||||
GSChangeDecls.Diags.emplace_back(ScreenInfo, Node->getGenericSignature(),
|
||||
UpdateMap.findUpdateCounterpart(Node)->getAs<SDKNodeDecl>()->
|
||||
getGenericSignature());
|
||||
Diags.diagnose(diag::generic_sig_change, Node->getScreenInfo(),
|
||||
Node->getGenericSignature(), UpdateMap.findUpdateCounterpart(Node)->
|
||||
getAs<SDKNodeDecl>()->getGenericSignature());
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1879,11 +1650,11 @@ void DiagnosisEmitter::handle(const SDKNodeDecl *Node, NodeAnnotation Anno) {
|
||||
[&](const ABIAttributeInfo &I) { return I.Annotation == Anno; });
|
||||
if (It == Infos.end())
|
||||
return;
|
||||
MetaInfo ScreenInfo(Node, true);
|
||||
auto Desc = Node->hasDeclAttribute(It->Kind) ?
|
||||
Ctx.buffer((llvm::Twine("without ") + It->Content).str()):
|
||||
Ctx.buffer((llvm::Twine("with ") + It->Content).str());
|
||||
AttrChangedDecls.Diags.emplace_back(ScreenInfo, Desc);
|
||||
if (options::Abi)
|
||||
Diags.diagnose(diag::decl_new_attr, Node->getScreenInfo(), Desc);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1901,7 +1672,6 @@ void DiagnosisEmitter::visitType(SDKNodeType *Node) {
|
||||
auto *Parent = dyn_cast<SDKNodeDecl>(Node->getParent());
|
||||
if (!Parent || Parent->isSDKPrivate())
|
||||
return;
|
||||
MetaInfo ScreenInfo(Parent, false);
|
||||
SDKContext &Ctx = Node->getSDKContext();
|
||||
if (Node->isAnnotatedAs(NodeAnnotation::Updated)) {
|
||||
auto *Count = UpdateMap.findUpdateCounterpart(Node)->getAs<SDKNodeType>();
|
||||
@@ -1914,10 +1684,8 @@ void DiagnosisEmitter::visitType(SDKNodeType *Node) {
|
||||
SDKNodeDeclAbstractFunc::getTypeRoleDescription(Ctx, Parent->getChildIndex(Node)) :
|
||||
Ctx.buffer("declared");
|
||||
if (Node->getPrintedName() != Count->getPrintedName())
|
||||
TypeChangedDecls.Diags.emplace_back(ScreenInfo,
|
||||
Node->getPrintedName(),
|
||||
Count->getPrintedName(),
|
||||
Descriptor);
|
||||
Diags.diagnose(diag::decl_type_change, Parent->getScreenInfo(),
|
||||
Descriptor, Node->getPrintedName(), Count->getPrintedName());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -2043,7 +1811,7 @@ static int diagnoseModuleChange(StringRef LeftPath, StringRef RightPath,
|
||||
llvm::errs() << RightPath << " does not exist\n";
|
||||
return 1;
|
||||
}
|
||||
PrintingDiagnosticConsumer PDC;
|
||||
ModuleDifferDiagsConsumer PDC;
|
||||
SDKContext Ctx(Opts);
|
||||
Ctx.getDiags().addConsumer(PDC);
|
||||
|
||||
@@ -2061,6 +1829,7 @@ static int diagnoseModuleChange(StringRef LeftPath, StringRef RightPath,
|
||||
RefinementPass.pass(LeftModule, RightModule);
|
||||
// Find member hoist changes to help refine diagnostics.
|
||||
findTypeMemberDiffs(LeftModule, RightModule, Ctx.getTypeMemberDiffs());
|
||||
|
||||
DiagnosisEmitter::diagnosis(LeftModule, RightModule, Ctx);
|
||||
return 0;
|
||||
}
|
||||
@@ -2099,7 +1868,7 @@ static int compareSDKs(StringRef LeftPath, StringRef RightPath,
|
||||
}
|
||||
llvm::errs() << "Diffing: " << LeftPath << " and " << RightPath << "\n";
|
||||
|
||||
PrintingDiagnosticConsumer PDC;
|
||||
ModuleDifferDiagsConsumer PDC;
|
||||
SDKContext Ctx(Opts);
|
||||
Ctx.getDiags().addConsumer(PDC);
|
||||
|
||||
@@ -2319,6 +2088,7 @@ static CheckerOptions getCheckOpts() {
|
||||
Opts.Verbose = options::Verbose;
|
||||
Opts.AbortOnModuleLoadFailure = options::AbortOnModuleLoadFailure;
|
||||
Opts.LocationFilter = options::LocationFilter;
|
||||
Opts.PrintModule = options::PrintModule;
|
||||
return Opts;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user