Skip to content

Commit eb0d894

Browse files
committed
[ClangImporter] improve structure of swiftify debug logs
This adds automatic scope management and indentation to the logs to make them more structured. Also adds some additional logging. Here's an example of what it can look like now: ``` [swiftify:593] Checking 'CountedByProtocol' protocol for methods with bounds and lifetime info [swiftify:350] | Checking 'simple::' for bounds and lifetime info [swiftify:411] | | Checking parameter 'len' with type 'int' [swiftify:411] | | Checking parameter 'p' with type 'int * __counted_by(len)' [swiftify:435] | | | Found bounds info 'int * __counted_by(len)' [swiftify:350] | Checking 'shared:::' for bounds and lifetime info [swiftify:411] | | Checking parameter 'len' with type 'int' [swiftify:411] | | Checking parameter 'p1' with type 'int * __counted_by(len)' [swiftify:435] | | | Found bounds info 'int * __counted_by(len)' [swiftify:411] | | Checking parameter 'p2' with type 'int * __counted_by(len)' [swiftify:435] | | | Found bounds info 'int * __counted_by(len)' [swiftify:350] | Checking 'complexExpr:::' for bounds and lifetime info [swiftify:411] | | Checking parameter 'len' with type 'int' [swiftify:411] | | Checking parameter 'offset' with type 'int' [swiftify:411] | | Checking parameter 'p' with type 'int * __counted_by(len - offset)' [swiftify:435] | | | Found bounds info 'int * __counted_by(len - offset)' [swiftify:350] | Checking 'nullUnspecified::' for bounds and lifetime info [swiftify:411] | | Checking parameter 'len' with type 'int' [swiftify:411] | | Checking parameter 'p' with type 'int * __counted_by(len) _Null_unspecified' [swiftify:435] | | | Found bounds info 'int * __counted_by(len) _Null_unspecified' [swiftify:350] | Checking 'nonnull::' for bounds and lifetime info [swiftify:411] | | Checking parameter 'len' with type 'int' [swiftify:411] | | Checking parameter 'p' with type 'int * __counted_by(len) _Nonnull' [swiftify:435] | | | Found bounds info 'int * __counted_by(len) _Nonnull' [swiftify:350] | Checking 'nullable::' for bounds and lifetime info [swiftify:411] | | Checking parameter 'len' with type 'int' [swiftify:411] | | Checking parameter 'p' with type 'int * __counted_by(len) _Nullable' [swiftify:435] | | | Found bounds info 'int * __counted_by(len) _Nullable' [swiftify:350] | Checking 'returnPointer:' for bounds and lifetime info [swiftify:379] | | Found bounds info 'int * __counted_by(len)' on return value [swiftify:411] | | Checking parameter 'len' with type 'int' [swiftify:350] | Checking 'staticMethod::' for bounds and lifetime info [swiftify:411] | | Checking parameter 'len' with type 'int' [swiftify:411] | | Checking parameter 'p' with type 'int * __counted_by(len)' [swiftify:435] | | | Found bounds info 'int * __counted_by(len)' ```
1 parent 4c977c6 commit eb0d894

File tree

1 file changed

+80
-23
lines changed

1 file changed

+80
-23
lines changed

lib/ClangImporter/SwiftifyDecl.cpp

Lines changed: 80 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,38 @@ using namespace swift;
3131
using namespace importer;
3232

3333
#define DEBUG_TYPE "safe-interop-wrappers"
34-
#define DLOG(x) LLVM_DEBUG(llvm::dbgs() << x)
34+
35+
#define DLOG(x) LLVM_DEBUG(LogIndentTracker::indent(DBGS) << x)
36+
37+
#ifndef NDEBUG
38+
#define DBGS llvm::dbgs() << "[swiftify:" << __LINE__ << "] "
39+
#define DUMP(x) DLOG(""); x->dump()
40+
#define DLOG_SCOPE(x) DLOG(x); LogIndentTracker Scope
41+
#else
42+
#define DLOG_SCOPE(x) do {} while(false);
43+
#endif
44+
3545

3646
namespace {
47+
#ifndef NDEBUG
48+
struct LogIndentTracker {
49+
static thread_local uint8_t LogIndent;
50+
static llvm::raw_ostream &indent(llvm::raw_ostream &out) {
51+
for (uint8_t i = 0; i < LogIndent; i++)
52+
out << "| ";
53+
return out;
54+
}
55+
56+
LogIndentTracker() {
57+
LogIndent++;
58+
}
59+
~LogIndentTracker() {
60+
LogIndent--;
61+
}
62+
};
63+
thread_local uint8_t LogIndentTracker::LogIndent = 0;
64+
#endif
65+
3766
ValueDecl *getKnownSingleDecl(ASTContext &SwiftContext, StringRef DeclName) {
3867
SmallVector<ValueDecl *, 1> decls;
3968
SwiftContext.lookupInSwiftModule(DeclName, decls);
@@ -196,8 +225,7 @@ struct CountedByExpressionValidator
196225
case clang::BuiltinType::ULong:
197226
case clang::BuiltinType::LongLong:
198227
case clang::BuiltinType::ULongLong:
199-
// These integer literals are printed with a suffix that isn't valid Swift
200-
// syntax
228+
DLOG("Ignoring count parameter with non-portable integer literal");
201229
return false;
202230
default:
203231
return true;
@@ -236,7 +264,10 @@ struct CountedByExpressionValidator
236264
SUPPORTED_BINOP(Or)
237265
#undef SUPPORTED_BINOP
238266

239-
bool VisitStmt(const clang::Stmt *) { return false; }
267+
bool VisitStmt(const clang::Stmt *) {
268+
DLOG("Ignoring count parameter with unsupported expression\n");
269+
return false;
270+
}
240271
};
241272

242273

@@ -255,16 +286,24 @@ static bool SwiftifiableSizedByPointerType(const clang::ASTContext &ctx,
255286
if (nonnullType->isOpaquePointer())
256287
return true;
257288
PointerTypeKind PTK;
258-
if (!nonnullType->getAnyPointerElementType(PTK))
289+
if (!nonnullType->getAnyPointerElementType(PTK)) {
290+
DLOG("Ignoring sized_by on non-pointer type\n");
259291
return false;
292+
}
260293
if (PTK == PTK_UnsafeRawPointer || PTK == PTK_UnsafeMutableRawPointer)
261294
return true;
262-
if (PTK != PTK_UnsafePointer && PTK != PTK_UnsafeMutablePointer)
295+
if (PTK != PTK_UnsafePointer && PTK != PTK_UnsafeMutablePointer) {
296+
DLOG("Ignoring sized_by on Autoreleasing pointer\n");
297+
CONDITIONAL_ASSERT(PTK == PTK_AutoreleasingUnsafeMutablePointer);
263298
return false;
299+
}
264300
// We have a pointer to a type with a size. Verify that it is char-sized.
265301
auto PtrT = CAT->getAs<clang::PointerType>();
266302
auto PointeeT = PtrT->getPointeeType();
267-
return ctx.getTypeSizeInChars(PointeeT).isOne();
303+
bool isByteSized = ctx.getTypeSizeInChars(PointeeT).isOne();
304+
if (!isByteSized)
305+
DLOG("Ignoring sized_by on non-byte-sized pointer\n");
306+
return isByteSized;
268307
}
269308
static bool SwiftifiableCAT(const clang::ASTContext &ctx,
270309
const clang::CountAttributedType *CAT,
@@ -287,6 +326,7 @@ struct UnaliasedInstantiationVisitor
287326
bool
288327
VisitTemplateSpecializationType(const clang::TemplateSpecializationType *) {
289328
hasUnaliasedInstantiation = true;
329+
DLOG("Signature contains raw template, skipping");
290330
return false;
291331
}
292332
};
@@ -325,7 +365,7 @@ static bool swiftifyImpl(ClangImporter::Implementation &Self,
325365
SwiftifyInfoFunctionPrinter &printer,
326366
const AbstractFunctionDecl *MappedDecl,
327367
const T *ClangDecl) {
328-
DLOG("Checking " << *ClangDecl << " for bounds and lifetime info\n");
368+
DLOG_SCOPE("Checking '" << *ClangDecl << "' for bounds and lifetime info\n");
329369

330370
// FIXME: for private macro generated functions we do not serialize the
331371
// SILFunction's body anywhere triggering assertions.
@@ -354,20 +394,22 @@ static bool swiftifyImpl(ClangImporter::Implementation &Self,
354394
auto *CAT = clangReturnTy->getAs<clang::CountAttributedType>();
355395
if (SwiftifiableCAT(clangASTContext, CAT, swiftReturnTy)) {
356396
printer.printCountedBy(CAT, SwiftifyInfoPrinter::RETURN_VALUE_INDEX);
357-
DLOG(" Found bounds info '" << clang::QualType(CAT, 0) << "' on return value\n");
397+
DLOG("Found bounds info '" << clang::QualType(CAT, 0) << "' on return value\n");
358398
attachMacro = true;
359399
}
360400
auto dependsOnClass = [](const ParamDecl *fromParam) {
361401
return fromParam->getInterfaceType()->isAnyClassReferenceType();
362402
};
363403
bool returnHasLifetimeInfo = false;
364404
if (getImplicitObjectParamAnnotation<clang::LifetimeBoundAttr>(ClangDecl)) {
365-
DLOG(" Found lifetimebound attribute on implicit 'this'\n");
405+
DLOG("Found lifetimebound attribute on implicit 'this'\n");
366406
if (!dependsOnClass(
367407
MappedDecl->getImplicitSelfDecl(/*createIfNeeded*/ true))) {
368408
printer.printLifetimeboundReturn(SwiftifyInfoPrinter::SELF_PARAM_INDEX,
369409
true);
370410
returnHasLifetimeInfo = true;
411+
} else {
412+
DLOG("lifetimebound ignored because it depends on class with refcount\n");
371413
}
372414
}
373415

@@ -385,6 +427,8 @@ static bool swiftifyImpl(ClangImporter::Implementation &Self,
385427
: getNumParams(ClangDecl);
386428
for (auto [index, clangParam] : llvm::enumerate(ClangDecl->parameters())) {
387429
clang::QualType clangParamTy = clangParam->getType();
430+
DLOG_SCOPE("Checking parameter '" << *clangParam << "' with type '"
431+
<< clangParamTy << "'\n");
388432
int mappedIndex = index < selfParamIndex ? index :
389433
index > selfParamIndex ? index - 1 :
390434
SwiftifyInfoPrinter::SELF_PARAM_INDEX;
@@ -408,8 +452,7 @@ static bool swiftifyImpl(ClangImporter::Implementation &Self,
408452
diag::note_swift_name_instance_method);
409453
} else if (SwiftifiableCAT(clangASTContext, CAT, swiftParamTy)) {
410454
printer.printCountedBy(CAT, mappedIndex);
411-
DLOG(" Found bounds info '" << clangParamTy << "' on parameter '"
412-
<< *clangParam << "'\n");
455+
DLOG("Found bounds info '" << clangParamTy << "'\n");
413456
attachMacro = paramHasBoundsInfo = true;
414457
}
415458
bool paramIsStdSpan =
@@ -418,13 +461,12 @@ static bool swiftifyImpl(ClangImporter::Implementation &Self,
418461

419462
bool paramHasLifetimeInfo = false;
420463
if (clangParam->template hasAttr<clang::NoEscapeAttr>()) {
421-
DLOG(" Found noescape attribute on parameter '" << *clangParam << "'\n");
464+
DLOG("Found noescape attribute\n");
422465
printer.printNonEscaping(mappedIndex);
423466
paramHasLifetimeInfo = true;
424467
}
425468
if (clangParam->template hasAttr<clang::LifetimeBoundAttr>()) {
426-
DLOG(" Found lifetimebound attribute on parameter '" << *clangParam
427-
<< "'\n");
469+
DLOG("Found lifetimebound attribute\n");
428470
if (!dependsOnClass(swiftParam)) {
429471
// If this parameter has bounds info we will tranform it into a Span,
430472
// so then it will no longer be Escapable.
@@ -435,16 +477,17 @@ static bool swiftifyImpl(ClangImporter::Implementation &Self,
435477
printer.printLifetimeboundReturn(mappedIndex, willBeEscapable);
436478
paramHasLifetimeInfo = true;
437479
returnHasLifetimeInfo = true;
480+
} else {
481+
DLOG("lifetimebound ignored because it depends on class with refcount\n");
438482
}
439483
}
440484
if (paramIsStdSpan && paramHasLifetimeInfo) {
441-
DLOG(" Found both std::span and lifetime info for parameter '"
442-
<< *clangParam << "'\n");
485+
DLOG("Found both std::span and lifetime info\n");
443486
attachMacro = true;
444487
}
445488
}
446489
if (returnIsStdSpan && returnHasLifetimeInfo) {
447-
DLOG(" Found both std::span and lifetime info for return value\n");
490+
DLOG("Found both std::span and lifetime info for return value\n");
448491
attachMacro = true;
449492
}
450493
}
@@ -501,6 +544,11 @@ void ClangImporter::Implementation::swiftify(AbstractFunctionDecl *MappedDecl) {
501544
if (!ClangDecl)
502545
return;
503546

547+
DLOG_SCOPE(
548+
"Checking '" << *ClangDecl << "' (imported as '"
549+
<< MappedDecl->getName().getBaseName().userFacingName()
550+
<< "')\n");
551+
504552
{
505553
UnaliasedInstantiationVisitor visitor;
506554
visitor.TraverseType(ClangDecl->getType());
@@ -509,8 +557,10 @@ void ClangImporter::Implementation::swiftify(AbstractFunctionDecl *MappedDecl) {
509557
}
510558

511559
MacroDecl *SwiftifyImportDecl = dyn_cast_or_null<MacroDecl>(getKnownSingleDecl(SwiftContext, "_SwiftifyImport"));
512-
if (!SwiftifyImportDecl)
560+
if (!SwiftifyImportDecl) {
561+
DLOG("_SwiftifyImport macro not found");
513562
return;
563+
}
514564

515565
llvm::SmallString<128> MacroString;
516566
{
@@ -520,8 +570,10 @@ void ClangImporter::Implementation::swiftify(AbstractFunctionDecl *MappedDecl) {
520570
llvm::StringMap<std::string> typeMapping;
521571
SwiftifyInfoFunctionPrinter printer(getClangASTContext(), SwiftContext, out,
522572
*SwiftifyImportDecl, typeMapping);
523-
if (!swiftifyImpl(*this, printer, MappedDecl, ClangDecl))
573+
if (!swiftifyImpl(*this, printer, MappedDecl, ClangDecl)) {
574+
DLOG("No relevant bounds or lifetime info found\n");
524575
return;
576+
}
525577
printer.printAvailability();
526578
printer.printTypeMapping();
527579
out << ")";
@@ -557,10 +609,13 @@ void ClangImporter::Implementation::swiftifyProtocol(
557609

558610
MacroDecl *SwiftifyImportDecl = dyn_cast_or_null<MacroDecl>(
559611
getKnownSingleDecl(SwiftContext, "_SwiftifyImportProtocol"));
560-
if (!SwiftifyImportDecl)
612+
if (!SwiftifyImportDecl) {
613+
DLOG("_SwiftifyImportProtocol macro not found");
561614
return;
615+
}
562616

563-
DLOG("Checking " << MappedDecl->getName() << " protocol for methods with bounds and lifetime info\n");
617+
DLOG_SCOPE("Checking '" << MappedDecl->getName()
618+
<< "' protocol for methods with bounds and lifetime info\n");
564619
llvm::SmallString<128> MacroString;
565620
{
566621
llvm::raw_svector_ostream out(MacroString);
@@ -579,8 +634,10 @@ void ClangImporter::Implementation::swiftifyProtocol(
579634
hasBoundsAttributes |= printer.printMethod(SwiftDecl);
580635
}
581636

582-
if (!hasBoundsAttributes)
637+
if (!hasBoundsAttributes) {
638+
DLOG("No relevant bounds or lifetime info found\n");
583639
return;
640+
}
584641
printer.printAvailability();
585642
printer.printTypeMapping();
586643
out << ")";

0 commit comments

Comments
 (0)