[AST] Merge BridgedDiagnosticEngine + BridgedDiagEngine

Introduce a macro that can stamp out wrapper
classes for underlying C++ pointers, and use
it to define BridgedDiagnosticEngine in
ASTBridging. Then, migrate users of
BridgedDiagEngine onto it.
This commit is contained in:
Hamish Knight
2023-10-30 23:49:55 +00:00
parent fe0ad60fe8
commit fce1cb54d5
18 changed files with 82 additions and 58 deletions

View File

@@ -52,16 +52,16 @@ public struct DiagnosticFixIt {
} }
public struct DiagnosticEngine { public struct DiagnosticEngine {
private let bridged: BridgedDiagEngine private let bridged: BridgedDiagnosticEngine
public init(bridged: BridgedDiagEngine) { public init(bridged: BridgedDiagnosticEngine) {
self.bridged = bridged self.bridged = bridged
} }
public init?(bridged: BridgedOptionalDiagnosticEngine) { public init?(bridged: BridgedNullableDiagnosticEngine) {
guard let object = bridged.object else { guard let raw = bridged.raw else {
return nil return nil
} }
self.bridged = BridgedDiagEngine(object: object) self.bridged = BridgedDiagnosticEngine(raw: raw)
} }
public func diagnose(_ position: SourceLoc?, public func diagnose(_ position: SourceLoc?,

View File

@@ -46,7 +46,7 @@ private func _RegexLiteralLexingFn(
_ curPtrPtr: UnsafeMutablePointer<UnsafePointer<CChar>>, _ curPtrPtr: UnsafeMutablePointer<UnsafePointer<CChar>>,
_ bufferEndPtr: UnsafePointer<CChar>, _ bufferEndPtr: UnsafePointer<CChar>,
_ mustBeRegex: CBool, _ mustBeRegex: CBool,
_ bridgedDiagnosticEngine: BridgedOptionalDiagnosticEngine _ bridgedDiagnosticEngine: BridgedNullableDiagnosticEngine
) -> /*CompletelyErroneous*/ CBool { ) -> /*CompletelyErroneous*/ CBool {
let inputPtr = curPtrPtr.pointee let inputPtr = curPtrPtr.pointee
@@ -92,7 +92,7 @@ public func _RegexLiteralParsingFn(
_ captureStructureOut: UnsafeMutableRawPointer, _ captureStructureOut: UnsafeMutableRawPointer,
_ captureStructureSize: CUnsignedInt, _ captureStructureSize: CUnsignedInt,
_ bridgedDiagnosticBaseLoc: BridgedSourceLoc, _ bridgedDiagnosticBaseLoc: BridgedSourceLoc,
_ bridgedDiagnosticEngine: BridgedDiagEngine _ bridgedDiagnosticEngine: BridgedDiagnosticEngine
) -> Bool { ) -> Bool {
let str = String(cString: inputPtr) let str = String(cString: inputPtr)
let captureBuffer = UnsafeMutableRawBufferPointer( let captureBuffer = UnsafeMutableRawBufferPointer(

View File

@@ -27,6 +27,7 @@ SWIFT_BEGIN_NULLABILITY_ANNOTATIONS
namespace swift { namespace swift {
class DiagnosticArgument; class DiagnosticArgument;
class DiagnosticEngine;
} }
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
@@ -40,14 +41,8 @@ typedef enum ENUM_EXTENSIBILITY_ATTR(open) BridgedDiagID : uint32_t {
#include "swift/AST/DiagnosticsAll.def" #include "swift/AST/DiagnosticsAll.def"
} BridgedDiagID; } BridgedDiagID;
// The name must not collide with BridgedDiagnosticEngine in CASTBridging.h. BRIDGING_WRAPPER_NONNULL(DiagnosticEngine)
struct BridgedDiagEngine { BRIDGING_WRAPPER_NULLABLE(DiagnosticEngine)
void * _Nonnull object;
};
struct BridgedOptionalDiagnosticEngine {
void *_Nullable object;
};
class BridgedDiagnosticArgument { class BridgedDiagnosticArgument {
int64_t storage[3]; int64_t storage[3];
@@ -83,12 +78,13 @@ public:
}; };
// FIXME: Can we bridge InFlightDiagnostic? // FIXME: Can we bridge InFlightDiagnostic?
void DiagnosticEngine_diagnose(BridgedDiagEngine, BridgedSourceLoc loc, void DiagnosticEngine_diagnose(BridgedDiagnosticEngine, BridgedSourceLoc loc,
BridgedDiagID diagID, BridgedArrayRef arguments, BridgedDiagID diagID, BridgedArrayRef arguments,
BridgedSourceLoc highlightStart, uint32_t hightlightLength, BridgedSourceLoc highlightStart,
uint32_t hightlightLength,
BridgedArrayRef fixIts); BridgedArrayRef fixIts);
bool DiagnosticEngine_hadAnyError(BridgedDiagEngine); bool DiagnosticEngine_hadAnyError(BridgedDiagnosticEngine);
SWIFT_END_NULLABILITY_ANNOTATIONS SWIFT_END_NULLABILITY_ANNOTATIONS

View File

@@ -18,14 +18,6 @@
namespace swift { namespace swift {
inline BridgedDiagEngine getBridgedDiagnosticEngine(DiagnosticEngine *D) {
return {(void *)D};
}
inline BridgedOptionalDiagnosticEngine
getBridgedOptionalDiagnosticEngine(DiagnosticEngine *D) {
return {(void *)D};
}
} // namespace swift } // namespace swift
#endif #endif

View File

@@ -13,7 +13,7 @@
#ifndef SWIFT_C_AST_ASTBRIDGING_H #ifndef SWIFT_C_AST_ASTBRIDGING_H
#define SWIFT_C_AST_ASTBRIDGING_H #define SWIFT_C_AST_ASTBRIDGING_H
#include "swift/Basic/BasicBridging.h" #include "swift/AST/ASTBridging.h"
#include "swift/Basic/CBasicBridging.h" #include "swift/Basic/CBasicBridging.h"
#include "swift/Basic/Compiler.h" #include "swift/Basic/Compiler.h"
#include "swift/Basic/Nullability.h" #include "swift/Basic/Nullability.h"
@@ -170,10 +170,6 @@ typedef struct BridgedDiagnostic {
void *raw; void *raw;
} BridgedDiagnostic; } BridgedDiagnostic;
typedef struct BridgedDiagnosticEngine {
void *raw;
} BridgedDiagnosticEngine;
typedef enum ENUM_EXTENSIBILITY_ATTR(open) BridgedMacroDefinitionKind : size_t { typedef enum ENUM_EXTENSIBILITY_ATTR(open) BridgedMacroDefinitionKind : size_t {
/// An expanded macro. /// An expanded macro.
BridgedExpandedMacro = 0, BridgedExpandedMacro = 0,

View File

@@ -43,6 +43,13 @@
#define SWIFT_NAME(NAME) #define SWIFT_NAME(NAME)
#endif #endif
#if __has_attribute(availability)
#define SWIFT_UNAVAILABLE(msg) \
__attribute__((availability(swift, unavailable, message=msg)))
#else
#define SWIFT_UNAVAILABLE(msg)
#endif
#ifdef PURE_BRIDGING_MODE #ifdef PURE_BRIDGING_MODE
// In PURE_BRIDGING_MODE, briding functions are not inlined // In PURE_BRIDGING_MODE, briding functions are not inlined
#define BRIDGED_INLINE #define BRIDGED_INLINE
@@ -55,6 +62,43 @@ SWIFT_BEGIN_NULLABILITY_ANNOTATIONS
typedef intptr_t SwiftInt; typedef intptr_t SwiftInt;
typedef uintptr_t SwiftUInt; typedef uintptr_t SwiftUInt;
// Define a bridging wrapper that wraps an underlying C++ pointer type. When
// importing into Swift, we expose an initializer and accessor that works with
// `void *`, which is imported as UnsafeMutableRawPointer. Note we can't rely on
// Swift importing the underlying C++ pointer as an OpaquePointer since that is
// liable to change with PURE_BRIDGING_MODE, since that changes what we include,
// and Swift could import the underlying pointee type instead. We need to be
// careful that the interface we expose remains consistent regardless of
// PURE_BRIDGING_MODE.
#define BRIDGING_WRAPPER_IMPL(Node, Name, Nullability) \
class Bridged##Name { \
swift::Node * Nullability Ptr; \
\
public: \
SWIFT_UNAVAILABLE("Use init(raw:) instead") \
Bridged##Name(swift::Node * Nullability ptr) : Ptr(ptr) {} \
\
SWIFT_UNAVAILABLE("Use '.raw' instead") \
swift::Node * Nullability get() const { return Ptr; } \
}; \
\
SWIFT_NAME("getter:Bridged" #Name ".raw(self:)") \
inline void * Nullability Bridged##Name##_getRaw(Bridged##Name bridged) { \
return bridged.get(); \
} \
\
SWIFT_NAME("Bridged" #Name ".init(raw:)") \
inline Bridged##Name Bridged##Name##_fromRaw(void * Nullability ptr) { \
return static_cast<swift::Node *>(ptr); \
}
// Bridging wrapper macros for convenience.
#define BRIDGING_WRAPPER_NONNULL(Name) \
BRIDGING_WRAPPER_IMPL(Name, Name, _Nonnull)
#define BRIDGING_WRAPPER_NULLABLE(Name) \
BRIDGING_WRAPPER_IMPL(Name, Nullable##Name, _Nullable)
struct BridgedOStream { struct BridgedOStream {
void * _Nonnull streamAddr; void * _Nonnull streamAddr;
}; };

View File

@@ -28,7 +28,7 @@
/// past. /// past.
/// - MustBeRegex: whether an error during lexing should be considered a regex /// - MustBeRegex: whether an error during lexing should be considered a regex
/// literal, or some thing else. /// literal, or some thing else.
/// - BridgedOptionalDiagnosticEngine: RegexLiteralLexingFn should diagnose the /// - BridgedNullableDiagnosticEngine: RegexLiteralLexingFn should diagnose the
/// token using this engine. /// token using this engine.
/// ///
/// Returns: A bool indicating whether lexing was completely erroneous, and /// Returns: A bool indicating whether lexing was completely erroneous, and
@@ -37,7 +37,7 @@
typedef bool (*RegexLiteralLexingFn)( typedef bool (*RegexLiteralLexingFn)(
/*CurPtrPtr*/ const char *_Nonnull *_Nonnull, /*CurPtrPtr*/ const char *_Nonnull *_Nonnull,
/*BufferEnd*/ const char *_Nonnull, /*BufferEnd*/ const char *_Nonnull,
/*MustBeRegex*/ bool, BridgedOptionalDiagnosticEngine); /*MustBeRegex*/ bool, BridgedNullableDiagnosticEngine);
void Parser_registerRegexLiteralLexingFn(RegexLiteralLexingFn _Nullable fn); void Parser_registerRegexLiteralLexingFn(RegexLiteralLexingFn _Nullable fn);
/// Parse a regex literal string. Takes the following arguments: /// Parse a regex literal string. Takes the following arguments:
@@ -58,7 +58,7 @@ typedef bool (*RegexLiteralParsingFn)(/*InputPtr*/ const char *_Nonnull,
/*CaptureStructureOut*/ void *_Nonnull, /*CaptureStructureOut*/ void *_Nonnull,
/*CaptureStructureSize*/ unsigned, /*CaptureStructureSize*/ unsigned,
/*DiagnosticBaseLoc*/ BridgedSourceLoc, /*DiagnosticBaseLoc*/ BridgedSourceLoc,
BridgedDiagEngine); BridgedDiagnosticEngine);
void Parser_registerRegexLiteralParsingFn(RegexLiteralParsingFn _Nullable fn); void Parser_registerRegexLiteralParsingFn(RegexLiteralParsingFn _Nullable fn);
#endif // REGEX_PARSER_BRIDGING #endif // REGEX_PARSER_BRIDGING

View File

@@ -181,7 +181,7 @@ struct BridgedPassContext {
// AST // AST
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE SWIFT_IMPORT_UNSAFE BRIDGED_INLINE
BridgedDiagEngine getDiagnosticEngine() const; BridgedDiagnosticEngine getDiagnosticEngine() const;
// SIL modifications // SIL modifications

View File

@@ -175,7 +175,7 @@ BridgedNominalTypeDecl BridgedPassContext::getSwiftArrayDecl() const {
// AST // AST
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE SWIFT_IMPORT_UNSAFE BRIDGED_INLINE
BridgedDiagEngine BridgedPassContext::getDiagnosticEngine() const { BridgedDiagnosticEngine BridgedPassContext::getDiagnosticEngine() const {
swift::SILModule *mod = invocation->getPassManager()->getModule(); swift::SILModule *mod = invocation->getPassManager()->getModule();
return {&mod->getASTContext().Diags}; return {&mod->getASTContext().Diags};
} }

View File

@@ -17,14 +17,6 @@
using namespace swift; using namespace swift;
namespace {
/// BridgedDiagEngine -> DiagnosticEngine *.
DiagnosticEngine *getDiagnosticEngine(const BridgedDiagEngine &bridged) {
return static_cast<DiagnosticEngine *>(bridged.object);
}
} // namespace
static_assert(sizeof(BridgedDiagnosticArgument) >= sizeof(DiagnosticArgument), static_assert(sizeof(BridgedDiagnosticArgument) >= sizeof(DiagnosticArgument),
"BridgedDiagnosticArgument has wrong size"); "BridgedDiagnosticArgument has wrong size");
@@ -45,12 +37,12 @@ BridgedDiagnosticFixIt::BridgedDiagnosticFixIt(BridgedSourceLoc start,
llvm::ArrayRef<DiagnosticArgument>())) {} llvm::ArrayRef<DiagnosticArgument>())) {}
void DiagnosticEngine_diagnose( void DiagnosticEngine_diagnose(
BridgedDiagEngine bridgedEngine, BridgedSourceLoc loc, BridgedDiagnosticEngine bridgedEngine, BridgedSourceLoc loc,
BridgedDiagID bridgedDiagID, BridgedDiagID bridgedDiagID,
BridgedArrayRef /*BridgedDiagnosticArgument*/ bridgedArguments, BridgedArrayRef /*BridgedDiagnosticArgument*/ bridgedArguments,
BridgedSourceLoc highlightStart, uint32_t hightlightLength, BridgedSourceLoc highlightStart, uint32_t hightlightLength,
BridgedArrayRef /*BridgedDiagnosticFixIt*/ bridgedFixIts) { BridgedArrayRef /*BridgedDiagnosticFixIt*/ bridgedFixIts) {
auto *D = getDiagnosticEngine(bridgedEngine); auto *D = bridgedEngine.get();
auto diagID = static_cast<DiagID>(bridgedDiagID); auto diagID = static_cast<DiagID>(bridgedDiagID);
SmallVector<DiagnosticArgument, 2> arguments; SmallVector<DiagnosticArgument, 2> arguments;
@@ -73,7 +65,6 @@ void DiagnosticEngine_diagnose(
} }
} }
bool DiagnosticEngine_hadAnyError(BridgedDiagEngine bridgedEngine) { bool DiagnosticEngine_hadAnyError(BridgedDiagnosticEngine bridgedEngine) {
auto *D = getDiagnosticEngine(bridgedEngine); return bridgedEngine.get()->hadAnyError();
return D->hadAnyError();
} }

View File

@@ -143,7 +143,7 @@ static inline BridgedDiagnosticImpl *unbridged(BridgedDiagnostic cDiag) {
} }
static inline DiagnosticEngine &unbridged(BridgedDiagnosticEngine cEngine) { static inline DiagnosticEngine &unbridged(BridgedDiagnosticEngine cEngine) {
return *static_cast<DiagnosticEngine *>(cEngine.raw); return *cEngine.get();
} }
static inline TypeAttributes *unbridged(BridgedTypeAttributes cAttributes) { static inline TypeAttributes *unbridged(BridgedTypeAttributes cAttributes) {

View File

@@ -1,3 +1,4 @@
import ASTBridging
import BasicBridging import BasicBridging
import CASTBridging import CASTBridging
import CBasicBridging import CBasicBridging

View File

@@ -1,3 +1,4 @@
import ASTBridging
import BasicBridging import BasicBridging
import CASTBridging import CASTBridging
import SwiftDiagnostics import SwiftDiagnostics

View File

@@ -10,6 +10,7 @@
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
import ASTBridging
import BasicBridging import BasicBridging
import CASTBridging import CASTBridging
import CBasicBridging import CBasicBridging

View File

@@ -1,3 +1,4 @@
import ASTBridging
import CASTBridging import CASTBridging
import CBasicBridging import CBasicBridging
import SwiftDiagnostics import SwiftDiagnostics

View File

@@ -1,3 +1,4 @@
import ASTBridging
import BasicBridging import BasicBridging
import CASTBridging import CASTBridging
import SwiftOperators import SwiftOperators

View File

@@ -2090,8 +2090,8 @@ const char *Lexer::tryScanRegexLiteral(const char *TokStart, bool MustBeRegex,
// - CompletelyErroneous will be set if there was an error that cannot be // - CompletelyErroneous will be set if there was an error that cannot be
// recovered from. // recovered from.
auto *Ptr = TokStart; auto *Ptr = TokStart;
CompletelyErroneous = regexLiteralLexingFn( CompletelyErroneous =
&Ptr, BufferEnd, MustBeRegex, getBridgedOptionalDiagnosticEngine(Diags)); regexLiteralLexingFn(&Ptr, BufferEnd, MustBeRegex, Diags);
// If we didn't make any lexing progress, this isn't a regex literal and we // If we didn't make any lexing progress, this isn't a regex literal and we
// should fallback to lexing as something else. // should fallback to lexing as something else.

View File

@@ -40,12 +40,12 @@ ParserResult<Expr> Parser::parseExprRegexLiteral() {
auto capturesBuf = Context.AllocateUninitialized<uint8_t>( auto capturesBuf = Context.AllocateUninitialized<uint8_t>(
RegexLiteralExpr::getCaptureStructureSerializationAllocationSize( RegexLiteralExpr::getCaptureStructureSerializationAllocationSize(
regexText.size())); regexText.size()));
bool hadError = bool hadError = regexLiteralParsingFn(
regexLiteralParsingFn(regexText.str().c_str(), &version, regexText.str().c_str(), &version,
/*captureStructureOut*/ capturesBuf.data(), /*captureStructureOut*/ capturesBuf.data(),
/*captureStructureSize*/ capturesBuf.size(), /*captureStructureSize*/ capturesBuf.size(),
/*diagBaseLoc*/ {(const uint8_t *)(Tok.getLoc().getOpaquePointerValue())}, /*diagBaseLoc*/ {(const uint8_t *)(Tok.getLoc().getOpaquePointerValue())},
getBridgedDiagnosticEngine(&Diags)); &Diags);
auto loc = consumeToken(); auto loc = consumeToken();
SourceMgr.recordRegexLiteralStartLoc(loc); SourceMgr.recordRegexLiteralStartLoc(loc);