Re-land parsing and printing for Clang function types.

This reverts commit e805fe486e, which reverted
the change earlier. The problem was caused due to a simultaneous change to some
code by the PR with parsing and printing for Clang function types (#28737)
and the PR which introduced Located<T> (#28643).

This commit also includes a small change to make sure the intersecting region
is fixed: the change is limited to using the fields of Located<T> in the
`tryParseClangType` lambda.
This commit is contained in:
Varun Gandhi
2020-01-07 12:04:44 -08:00
parent 6e7521ac57
commit afc6ccdeb5
22 changed files with 274 additions and 22 deletions

View File

@@ -14,6 +14,7 @@
#define SWIFT_AST_ASTPRINTER_H
#include "swift/Basic/LLVM.h"
#include "swift/Basic/QuotedString.h"
#include "swift/Basic/UUID.h"
#include "swift/AST/Identifier.h"
#include "llvm/ADT/StringRef.h"
@@ -185,6 +186,8 @@ public:
return *this;
}
ASTPrinter &operator<<(QuotedString s);
ASTPrinter &operator<<(unsigned long long N);
ASTPrinter &operator<<(UUID UU);

View File

@@ -21,6 +21,7 @@ class CompilerInstance;
class Preprocessor;
class Sema;
class TargetInfo;
class Type;
} // namespace clang
namespace swift {
@@ -100,6 +101,16 @@ public:
lookupRelatedEntity(StringRef clangName, ClangTypeKind kind,
StringRef relatedEntityKind,
llvm::function_ref<void(TypeDecl *)> receiver) = 0;
/// Try to parse the string as a Clang function type.
///
/// Returns null if there was a parsing failure.
virtual const clang::Type *parseClangFunctionType(StringRef type,
SourceLoc loc) const = 0;
/// Print the Clang type.
virtual void printClangType(const clang::Type *type,
llvm::raw_ostream &os) const = 0;
};
} // namespace swift

View File

@@ -3924,6 +3924,13 @@ ERROR(unsupported_convention,none,
"convention '%0' not supported", (StringRef))
ERROR(unreferenced_generic_parameter,none,
"generic parameter '%0' is not used in function signature", (StringRef))
ERROR(unexpected_ctype_for_non_c_convention,none,
"convention '%0' does not support the 'cType' argument label, did you "
"mean @convention(c, cType: \"%1\") or @convention(block, cType: \"%1\") "
"instead?", (StringRef, StringRef))
ERROR(unable_to_parse_c_function_type,none,
"unable to parse '%0'; it should be a C function pointer type or a "
"block pointer type", (StringRef))
// Opaque types
ERROR(unsupported_opaque_type,none,

View File

@@ -306,8 +306,21 @@ struct PrintOptions {
/// List of decls that should be printed even if they are implicit and \c SkipImplicit is set to true.
std::vector<const Decl*> TreatAsExplicitDeclList;
enum class FunctionRepresentationMode : uint8_t {
/// Print the entire convention, including an arguments.
/// For example, this will print a cType argument label if applicable.
Full,
/// Print only the name of the convention, skipping extra argument labels.
NameOnly,
/// Skip printing the @convention(..) altogether.
None
};
/// Whether to print function @convention attribute on function types.
bool PrintFunctionRepresentationAttrs = true;
// FIXME: [clang-function-type-serialization] Once we start serializing Clang
// types, we should also start printing the full type in the swiftinterface.
FunctionRepresentationMode PrintFunctionRepresentationAttrs =
FunctionRepresentationMode::NameOnly;
/// Whether to print storage representation attributes on types, e.g.
/// '@sil_weak', '@sil_unmanaged'.
@@ -502,7 +515,8 @@ struct PrintOptions {
/// consistent and well-formed.
///
/// \see swift::emitSwiftInterface
static PrintOptions printSwiftInterfaceFile(bool preferTypeRepr);
static PrintOptions printSwiftInterfaceFile(bool preferTypeRepr,
bool printFullConvention);
/// Retrieve the set of options suitable for "Generated Interfaces", which
/// are a prettified representation of the public API of a module, to be
@@ -585,7 +599,8 @@ struct PrintOptions {
PO.SkipUnderscoredKeywords = true;
PO.EnumRawValues = EnumRawValueMode::Print;
PO.PrintImplicitAttrs = false;
PO.PrintFunctionRepresentationAttrs = false;
PO.PrintFunctionRepresentationAttrs =
PrintOptions::FunctionRepresentationMode::None;
PO.PrintDocumentationComments = false;
PO.ExcludeAttrList.push_back(DAK_Available);
PO.SkipPrivateStdlibDecls = true;

View File

@@ -59,6 +59,7 @@ class AssociatedTypeDecl;
class ASTContext;
enum BufferPointerTypeKind : unsigned;
class ClassDecl;
class ClangModuleLoader;
class DependentMemberType;
class GenericTypeParamDecl;
class GenericTypeParamType;
@@ -2950,6 +2951,11 @@ public:
bool empty() const { return !ClangFunctionType; }
Uncommon(const clang::Type *type) : ClangFunctionType(type) {}
public:
/// Use the ClangModuleLoader to print the Clang type as a string.
void printClangFunctionType(ClangModuleLoader *cml,
llvm::raw_ostream &os);
};
private:
@@ -3894,6 +3900,11 @@ public:
bool empty() const { return !ClangFunctionType; }
Uncommon(const clang::FunctionType *type) : ClangFunctionType(type) {}
public:
/// Analog of AnyFunctionType::ExtInfo::Uncommon::printClangFunctionType.
void printClangFunctionType(ClangModuleLoader *cml,
llvm::raw_ostream &os) const;
};
Uncommon Other;
@@ -3947,6 +3958,11 @@ public:
return getSILFunctionLanguage(getRepresentation());
}
/// Return the underlying Uncommon value if it is not the default value.
Optional<Uncommon> getUncommonInfo() const {
return Other.empty() ? Optional<Uncommon>() : Other;
}
bool hasSelfParam() const {
switch (getRepresentation()) {
case Representation::Thick:

View File

@@ -40,6 +40,7 @@ namespace clang {
class NamedDecl;
class Sema;
class TargetInfo;
class Type;
class VisibleDeclConsumer;
class DeclarationName;
}
@@ -416,6 +417,11 @@ public:
/// with -import-objc-header option.
getPCHFilename(const ClangImporterOptions &ImporterOptions,
StringRef SwiftPCHHash, bool &isExplicit);
const clang::Type *parseClangFunctionType(StringRef type,
SourceLoc loc) const override;
void printClangType(const clang::Type *type,
llvm::raw_ostream &os) const override;
};
ImportDecl *createImportDecl(ASTContext &Ctx, DeclContext *DC, ClangNode ClangN,

View File

@@ -31,6 +31,10 @@ struct ModuleInterfaceOptions {
/// interface, or should we fully-qualify them?
bool PreserveTypesAsWritten = false;
/// Should we emit the cType when printing @convention(c) or no?
/// FIXME: [clang-function-type-serialization] This check should go away.
bool PrintFullConvention = false;
/// Copy of all the command-line flags passed at .swiftinterface
/// generation time, re-applied to CompilerInvocation when reading
/// back .swiftinterface and reconstructing .swiftmodule.

View File

@@ -602,6 +602,11 @@ def module_interface_preserve_types_as_written :
HelpText<"When emitting a module interface, preserve types as they were "
"written in the source">;
def experimental_print_full_convention :
Flag<["-"], "experimental-print-full-convention">,
HelpText<"When emitting a module interface, emit additional @convention "
"arguments, regardless of whether they were written in the source">;
def prebuilt_module_cache_path :
Separate<["-"], "prebuilt-module-cache-path">,
HelpText<"Directory of prebuilt modules for loading module interfaces">;