Skip to content

Commit 9660447

Browse files
[AST] Add printing for Clang function types in the AST.
1 parent afc6332 commit 9660447

File tree

17 files changed

+160
-14
lines changed

17 files changed

+160
-14
lines changed

include/swift/AST/ASTPrinter.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#define SWIFT_AST_ASTPRINTER_H
1515

1616
#include "swift/Basic/LLVM.h"
17+
#include "swift/Basic/QuotedString.h"
1718
#include "swift/Basic/UUID.h"
1819
#include "swift/AST/Identifier.h"
1920
#include "llvm/ADT/StringRef.h"
@@ -185,6 +186,8 @@ class ASTPrinter {
185186
return *this;
186187
}
187188

189+
ASTPrinter &operator<<(QuotedString s);
190+
188191
ASTPrinter &operator<<(unsigned long long N);
189192
ASTPrinter &operator<<(UUID UU);
190193

include/swift/AST/ClangModuleLoader.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,10 @@ class ClangModuleLoader : public ModuleLoader {
107107
/// Returns null if there was a parsing failure.
108108
virtual const clang::Type *parseClangFunctionType(StringRef type,
109109
SourceLoc loc) const = 0;
110+
111+
/// Print the Clang type.
112+
virtual void printClangType(const clang::Type *type,
113+
llvm::raw_ostream &os) const = 0;
110114
};
111115

112116
} // namespace swift

include/swift/AST/PrintOptions.h

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -306,8 +306,21 @@ struct PrintOptions {
306306
/// List of decls that should be printed even if they are implicit and \c SkipImplicit is set to true.
307307
std::vector<const Decl*> TreatAsExplicitDeclList;
308308

309+
enum class FunctionRepresentationMode : uint8_t {
310+
/// Print the entire convention, including an arguments.
311+
/// For example, this will print a cType argument label if applicable.
312+
Full,
313+
/// Print only the name of the convention, skipping extra argument labels.
314+
NameOnly,
315+
/// Skip printing the @convention(..) altogether.
316+
None
317+
};
318+
309319
/// Whether to print function @convention attribute on function types.
310-
bool PrintFunctionRepresentationAttrs = true;
320+
// FIXME: [clang-function-type-serialization] Once we start serializing Clang
321+
// types, we should also start printing the full type in the swiftinterface.
322+
FunctionRepresentationMode PrintFunctionRepresentationAttrs =
323+
FunctionRepresentationMode::NameOnly;
311324

312325
/// Whether to print storage representation attributes on types, e.g.
313326
/// '@sil_weak', '@sil_unmanaged'.
@@ -502,7 +515,8 @@ struct PrintOptions {
502515
/// consistent and well-formed.
503516
///
504517
/// \see swift::emitSwiftInterface
505-
static PrintOptions printSwiftInterfaceFile(bool preferTypeRepr);
518+
static PrintOptions printSwiftInterfaceFile(bool preferTypeRepr,
519+
bool printFullConvention);
506520

507521
/// Retrieve the set of options suitable for "Generated Interfaces", which
508522
/// are a prettified representation of the public API of a module, to be
@@ -585,7 +599,8 @@ struct PrintOptions {
585599
PO.SkipUnderscoredKeywords = true;
586600
PO.EnumRawValues = EnumRawValueMode::Print;
587601
PO.PrintImplicitAttrs = false;
588-
PO.PrintFunctionRepresentationAttrs = false;
602+
PO.PrintFunctionRepresentationAttrs =
603+
PrintOptions::FunctionRepresentationMode::None;
589604
PO.PrintDocumentationComments = false;
590605
PO.ExcludeAttrList.push_back(DAK_Available);
591606
PO.SkipPrivateStdlibDecls = true;

include/swift/AST/Types.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ class AssociatedTypeDecl;
5959
class ASTContext;
6060
enum BufferPointerTypeKind : unsigned;
6161
class ClassDecl;
62+
class ClangModuleLoader;
6263
class DependentMemberType;
6364
class GenericTypeParamDecl;
6465
class GenericTypeParamType;
@@ -2950,6 +2951,11 @@ class AnyFunctionType : public TypeBase {
29502951

29512952
bool empty() const { return !ClangFunctionType; }
29522953
Uncommon(const clang::Type *type) : ClangFunctionType(type) {}
2954+
2955+
public:
2956+
/// Use the ClangModuleLoader to print the Clang type as a string.
2957+
void printClangFunctionType(ClangModuleLoader *cml,
2958+
llvm::raw_ostream &os);
29532959
};
29542960

29552961
private:

include/swift/ClangImporter/ClangImporter.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -420,6 +420,8 @@ class ClangImporter final : public ClangModuleLoader {
420420

421421
const clang::Type *parseClangFunctionType(StringRef type,
422422
SourceLoc loc) const override;
423+
void printClangType(const clang::Type *type,
424+
llvm::raw_ostream &os) const override;
423425
};
424426

425427
ImportDecl *createImportDecl(ASTContext &Ctx, DeclContext *DC, ClangNode ClangN,

include/swift/Frontend/ModuleInterfaceSupport.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@ struct ModuleInterfaceOptions {
3131
/// interface, or should we fully-qualify them?
3232
bool PreserveTypesAsWritten = false;
3333

34+
/// Should we emit the cType when printing @convention(c) or no?
35+
/// FIXME: [clang-function-type-serialization] This check should go away.
36+
bool PrintFullConvention = false;
37+
3438
/// Copy of all the command-line flags passed at .swiftinterface
3539
/// generation time, re-applied to CompilerInvocation when reading
3640
/// back .swiftinterface and reconstructing .swiftmodule.

include/swift/Option/FrontendOptions.td

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -602,6 +602,11 @@ def module_interface_preserve_types_as_written :
602602
HelpText<"When emitting a module interface, preserve types as they were "
603603
"written in the source">;
604604

605+
def experimental_print_full_convention :
606+
Flag<["-"], "experimental-print-full-convention">,
607+
HelpText<"When emitting a module interface, emit additional @convention "
608+
"arguments, regardless of whether they were written in the source">;
609+
605610
def prebuilt_module_cache_path :
606611
Separate<["-"], "prebuilt-module-cache-path">,
607612
HelpText<"Directory of prebuilt modules for loading module interfaces">;

lib/AST/ASTPrinter.cpp

Lines changed: 45 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "swift/AST/ASTMangler.h"
2020
#include "swift/AST/ASTVisitor.h"
2121
#include "swift/AST/Attr.h"
22+
#include "swift/AST/ClangModuleLoader.h"
2223
#include "swift/AST/Comment.h"
2324
#include "swift/AST/Decl.h"
2425
#include "swift/AST/Expr.h"
@@ -98,7 +99,8 @@ static bool contributesToParentTypeStorage(const AbstractStorageDecl *ASD) {
9899
return !ND->isResilient() && ASD->hasStorage() && !ASD->isStatic();
99100
}
100101

101-
PrintOptions PrintOptions::printSwiftInterfaceFile(bool preferTypeRepr) {
102+
PrintOptions PrintOptions::printSwiftInterfaceFile(bool preferTypeRepr,
103+
bool printFullConvention) {
102104
PrintOptions result;
103105
result.PrintLongAttrsOnSeparateLines = true;
104106
result.TypeDefinitions = true;
@@ -115,6 +117,9 @@ PrintOptions PrintOptions::printSwiftInterfaceFile(bool preferTypeRepr) {
115117
result.OpaqueReturnTypePrinting =
116118
OpaqueReturnTypePrintingMode::StableReference;
117119
result.PreferTypeRepr = preferTypeRepr;
120+
if (printFullConvention)
121+
result.PrintFunctionRepresentationAttrs =
122+
PrintOptions::FunctionRepresentationMode::Full;
118123

119124
// We should print __consuming, __owned, etc for the module interface file.
120125
result.SkipUnderscoredKeywords = false;
@@ -321,6 +326,14 @@ void ASTPrinter::callPrintDeclPre(const Decl *D,
321326
printDeclPre(D, Bracket);
322327
}
323328

329+
ASTPrinter &ASTPrinter::operator<<(QuotedString s) {
330+
llvm::SmallString<32> Str;
331+
llvm::raw_svector_ostream OS(Str);
332+
OS << s;
333+
printTextImpl(OS.str());
334+
return *this;
335+
}
336+
324337
ASTPrinter &ASTPrinter::operator<<(unsigned long long N) {
325338
llvm::SmallString<32> Str;
326339
llvm::raw_svector_ostream OS(Str);
@@ -3462,6 +3475,15 @@ void Pattern::print(llvm::raw_ostream &OS, const PrintOptions &Options) const {
34623475
// Type Printing
34633476
//===----------------------------------------------------------------------===//
34643477

3478+
template <typename ExtInfo>
3479+
void printCType(ASTContext &Ctx, ASTPrinter &Printer, ExtInfo &info) {
3480+
auto *cml = Ctx.getClangModuleLoader();
3481+
SmallString<64> buf;
3482+
llvm::raw_svector_ostream os(buf);
3483+
info.getUncommonInfo().getValue().printClangFunctionType(cml, os);
3484+
Printer << ", cType: " << QuotedString(os.str());
3485+
}
3486+
34653487
namespace {
34663488
class TypePrinter : public TypeVisitor<TypePrinter> {
34673489
using super = TypeVisitor;
@@ -3824,7 +3846,7 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
38243846
visit(staticSelfT);
38253847
}
38263848

3827-
void printFunctionExtInfo(AnyFunctionType::ExtInfo info) {
3849+
void printFunctionExtInfo(ASTContext &Ctx, AnyFunctionType::ExtInfo info) {
38283850
if (Options.SkipAttributes)
38293851
return;
38303852

@@ -3837,9 +3859,18 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
38373859
}
38383860
}
38393861

3840-
if (Options.PrintFunctionRepresentationAttrs &&
3841-
!Options.excludeAttrKind(TAK_convention) &&
3842-
info.getSILRepresentation() != SILFunctionType::Representation::Thick) {
3862+
SmallString<64> buf;
3863+
switch (Options.PrintFunctionRepresentationAttrs) {
3864+
case PrintOptions::FunctionRepresentationMode::None:
3865+
return;
3866+
case PrintOptions::FunctionRepresentationMode::Full:
3867+
case PrintOptions::FunctionRepresentationMode::NameOnly:
3868+
if (Options.excludeAttrKind(TAK_convention) ||
3869+
info.getSILRepresentation() == SILFunctionType::Representation::Thick)
3870+
return;
3871+
3872+
bool printNameOnly = Options.PrintFunctionRepresentationAttrs ==
3873+
PrintOptions::FunctionRepresentationMode::NameOnly;
38433874
Printer.callPrintStructurePre(PrintStructureKind::BuiltinAttribute);
38443875
Printer.printAttrName("@convention");
38453876
Printer << "(";
@@ -3855,6 +3886,11 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
38553886
break;
38563887
case SILFunctionType::Representation::CFunctionPointer:
38573888
Printer << "c";
3889+
// FIXME: [clang-function-type-serialization] Once we start serializing
3890+
// Clang function types, we should be able to remove the second check.
3891+
if (printNameOnly || !info.getUncommonInfo().hasValue())
3892+
break;
3893+
printCType(Ctx, Printer, info);
38583894
break;
38593895
case SILFunctionType::Representation::Method:
38603896
Printer << "method";
@@ -3889,7 +3925,8 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
38893925
}
38903926
}
38913927

3892-
if (Options.PrintFunctionRepresentationAttrs &&
3928+
if ((Options.PrintFunctionRepresentationAttrs !=
3929+
PrintOptions::FunctionRepresentationMode::None) &&
38933930
!Options.excludeAttrKind(TAK_convention) &&
38943931
info.getRepresentation() != SILFunctionType::Representation::Thick) {
38953932
Printer.callPrintStructurePre(PrintStructureKind::BuiltinAttribute);
@@ -3975,7 +4012,7 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
39754012
Printer.printStructurePost(PrintStructureKind::FunctionType);
39764013
};
39774014

3978-
printFunctionExtInfo(T->getExtInfo());
4015+
printFunctionExtInfo(T->getASTContext(), T->getExtInfo());
39794016

39804017
// If we're stripping argument labels from types, do it when printing.
39814018
visitAnyFunctionTypeParams(T->getParams(), /*printLabels*/false);
@@ -4012,7 +4049,7 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
40124049
Printer.printStructurePost(PrintStructureKind::FunctionType);
40134050
};
40144051

4015-
printFunctionExtInfo(T->getExtInfo());
4052+
printFunctionExtInfo(T->getASTContext(), T->getExtInfo());
40164053
printGenericSignature(T->getGenericSignature(),
40174054
PrintAST::PrintParams |
40184055
PrintAST::PrintRequirements);

lib/AST/Type.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "swift/AST/Types.h"
1818
#include "ForeignRepresentationInfo.h"
1919
#include "swift/AST/ASTContext.h"
20+
#include "swift/AST/ClangModuleLoader.h"
2021
#include "swift/AST/ExistentialLayout.h"
2122
#include "swift/AST/ReferenceCounting.h"
2223
#include "swift/AST/TypeCheckRequests.h"
@@ -3239,6 +3240,11 @@ Type ProtocolCompositionType::get(const ASTContext &C,
32393240
return build(C, CanTypes, HasExplicitAnyObject);
32403241
}
32413242

3243+
void AnyFunctionType::ExtInfo::Uncommon::printClangFunctionType(
3244+
ClangModuleLoader *cml, llvm::raw_ostream &os) {
3245+
cml->printClangType(ClangFunctionType, os);
3246+
}
3247+
32423248
void
32433249
AnyFunctionType::ExtInfo::assertIsFunctionType(const clang::Type *type) {
32443250
#ifndef NDEBUG

lib/ClangImporter/ClangImporter.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3292,6 +3292,12 @@ ClangImporter::parseClangFunctionType(StringRef typeStr,
32923292
return nullptr;
32933293
}
32943294

3295+
void ClangImporter::printClangType(const clang::Type *type,
3296+
llvm::raw_ostream &os) const {
3297+
auto policy = clang::PrintingPolicy(getClangASTContext().getLangOpts());
3298+
clang::QualType(type, 0).print(os, policy);
3299+
}
3300+
32953301
//===----------------------------------------------------------------------===//
32963302
// ClangModule Implementation
32973303
//===----------------------------------------------------------------------===//

0 commit comments

Comments
 (0)