mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
ClangImporter: Import (some) vector types.
When -enable-simd-import is active, if we encounter a vector type, try to load the SIMD Swift module, and if successful, map float, double, and int vectors to SIMD.{Float,Double,Int}N types if they exist.
Swift SVN r27367
This commit is contained in:
@@ -54,6 +54,7 @@ IDENTIFIER(RawValue)
|
||||
IDENTIFIER(self)
|
||||
IDENTIFIER(Self)
|
||||
IDENTIFIER(setObject)
|
||||
IDENTIFIER(SIMD)
|
||||
IDENTIFIER(Some)
|
||||
IDENTIFIER(subscript)
|
||||
IDENTIFIER(toRaw)
|
||||
|
||||
@@ -83,6 +83,9 @@ namespace swift {
|
||||
/// \brief Enable support for native C function pointer types.
|
||||
bool EnableCFunctionPointers = false;
|
||||
|
||||
/// \brief Enable support for SIMD type imports.
|
||||
bool EnableSIMDImport = false;
|
||||
|
||||
/// \brief Enable features useful for running in the debugger.
|
||||
bool DebuggerSupport = false;
|
||||
|
||||
|
||||
@@ -197,6 +197,10 @@ def enable_c_function_pointers : Flag<["-"],
|
||||
"enable-c-function-pointers">,
|
||||
HelpText<"Enable native C function pointer types">;
|
||||
|
||||
def enable_simd_import : Flag<["-"],
|
||||
"enable-simd-import">,
|
||||
HelpText<"Enable importing C vector types as SIMD types">;
|
||||
|
||||
def enable_character_literals : Flag<["-"], "enable-character-literals">,
|
||||
HelpText<"Enable legacy character literals">;
|
||||
|
||||
|
||||
@@ -420,13 +420,45 @@ namespace {
|
||||
}
|
||||
|
||||
ImportResult VisitVectorType(const clang::VectorType *type) {
|
||||
// FIXME: We could map these.
|
||||
// We can map this into a type from the SIMD module, if it exists.
|
||||
if (!Impl.SwiftContext.LangOpts.EnableSIMDImport)
|
||||
return Type();
|
||||
|
||||
auto *SIMD = Impl.tryLoadSIMDModule();
|
||||
if (!SIMD)
|
||||
return Type();
|
||||
|
||||
// Map the element type and count to a Swift name, such as
|
||||
// float x 3 => Float3.
|
||||
SmallString<16> name;
|
||||
{
|
||||
llvm::raw_svector_ostream names(name);
|
||||
|
||||
if (auto builtinTy
|
||||
= dyn_cast<clang::BuiltinType>(type->getElementType())){
|
||||
switch (builtinTy->getKind()) {
|
||||
case clang::BuiltinType::Float:
|
||||
names << "Float";
|
||||
break;
|
||||
case clang::BuiltinType::Double:
|
||||
names << "Double";
|
||||
break;
|
||||
case clang::BuiltinType::Int:
|
||||
names << "Int";
|
||||
break;
|
||||
default:
|
||||
// TODO:
|
||||
return Type();
|
||||
}
|
||||
} else {
|
||||
return Type();
|
||||
}
|
||||
|
||||
ImportResult VisitExtVectorType(const clang::ExtVectorType *type) {
|
||||
// FIXME: We could map these.
|
||||
return Type();
|
||||
names << type->getNumElements();
|
||||
names.flush();
|
||||
}
|
||||
|
||||
return Impl.getNamedSwiftType(SIMD, name);
|
||||
}
|
||||
|
||||
ImportResult VisitFunctionProtoType(const clang::FunctionProtoType *type) {
|
||||
@@ -1651,19 +1683,30 @@ Module *ClangImporter::Implementation::getNamedModule(StringRef name) {
|
||||
return SwiftContext.getLoadedModule(SwiftContext.getIdentifier(name));
|
||||
}
|
||||
|
||||
Module *ClangImporter::Implementation::tryLoadFoundationModule() {
|
||||
if (!checkedFoundationModule.hasValue()) {
|
||||
Identifier name = SwiftContext.getIdentifier(FOUNDATION_MODULE_NAME);
|
||||
|
||||
static Module *tryLoadModule(ASTContext &C,
|
||||
Identifier name,
|
||||
bool importForwardDeclarations,
|
||||
Optional<Module *> &cache) {
|
||||
if (!cache.hasValue()) {
|
||||
// If we're synthesizing forward declarations, we don't want to pull in
|
||||
// Foundation too eagerly.
|
||||
if (ImportForwardDeclarations)
|
||||
checkedFoundationModule = SwiftContext.getLoadedModule(name);
|
||||
// the module too eagerly.
|
||||
if (importForwardDeclarations)
|
||||
cache = C.getLoadedModule(name);
|
||||
else
|
||||
checkedFoundationModule = SwiftContext.getModule({ {name, SourceLoc()} });
|
||||
cache = C.getModule({ {name, SourceLoc()} });
|
||||
}
|
||||
|
||||
return checkedFoundationModule.getValue();
|
||||
return cache.getValue();
|
||||
}
|
||||
|
||||
Module *ClangImporter::Implementation::tryLoadFoundationModule() {
|
||||
return tryLoadModule(SwiftContext, SwiftContext.Id_Foundation,
|
||||
ImportForwardDeclarations, checkedFoundationModule);
|
||||
}
|
||||
|
||||
Module *ClangImporter::Implementation::tryLoadSIMDModule() {
|
||||
return tryLoadModule(SwiftContext, SwiftContext.Id_SIMD,
|
||||
ImportForwardDeclarations, checkedSIMDModule);
|
||||
}
|
||||
|
||||
Type ClangImporter::Implementation::getNamedSwiftType(Module *module,
|
||||
|
||||
@@ -531,7 +531,7 @@ public:
|
||||
clang::Selector setObjectForKeyedSubscript;
|
||||
|
||||
private:
|
||||
Optional<Module *> checkedFoundationModule;
|
||||
Optional<Module *> checkedFoundationModule, checkedSIMDModule;
|
||||
|
||||
/// External Decls that we have imported but not passed to the ASTContext yet.
|
||||
SmallVector<Decl *, 4> RegisteredExternalDecls;
|
||||
@@ -840,6 +840,12 @@ public:
|
||||
/// into the ASTContext.
|
||||
Module *tryLoadFoundationModule();
|
||||
|
||||
/// \brief Returns the "SIMD" module, if it can be loaded.
|
||||
///
|
||||
/// After this has been called, the SIMD module will or won't be loaded
|
||||
/// into the ASTContext.
|
||||
Module *tryLoadSIMDModule();
|
||||
|
||||
/// \brief Retrieves the Swift wrapper for the given Clang module, creating
|
||||
/// it if necessary.
|
||||
ClangModuleUnit *getWrapperForModule(ClangImporter &importer,
|
||||
|
||||
@@ -618,6 +618,9 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args,
|
||||
Opts.EnableCFunctionPointers |=
|
||||
Args.hasArg(OPT_enable_c_function_pointers);
|
||||
|
||||
Opts.EnableSIMDImport |=
|
||||
Args.hasArg(OPT_enable_simd_import);
|
||||
|
||||
Opts.EnableCharacterLiterals |= Args.hasArg(OPT_enable_character_literals);
|
||||
|
||||
if (auto A = Args.getLastArg(OPT_enable_access_control,
|
||||
|
||||
17
test/ClangModules/simd.swift
Normal file
17
test/ClangModules/simd.swift
Normal file
@@ -0,0 +1,17 @@
|
||||
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -parse -verify -enable-simd-import %s
|
||||
|
||||
import c_simd
|
||||
import SIMD
|
||||
|
||||
let f4: Float4 = makes_float4()
|
||||
let i3: Int3 = makes_int3()
|
||||
let d2: Double2 = makes_double2()
|
||||
|
||||
takes_float4(f4)
|
||||
takes_int3(i3)
|
||||
takes_double2(d2)
|
||||
|
||||
// byte17 isn't available since there isn't a type in the SIMD module to map it to.
|
||||
|
||||
let mb17 = makes_byte17 // expected-error{{unresolved identifier 'makes_byte17'}}
|
||||
let t17 = takes_byte17 // expected-error{{unresolved identifier 'takes_byte17'}}
|
||||
13
test/ClangModules/simd_sans_simd.swift
Normal file
13
test/ClangModules/simd_sans_simd.swift
Normal file
@@ -0,0 +1,13 @@
|
||||
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -parse -verify -enable-simd-import %s
|
||||
|
||||
import c_simd
|
||||
|
||||
// Ensure that the SIMD types from the imported module get mapped into the
|
||||
// SIMD Swift module, even if we in the importing module don't import SIMD.
|
||||
|
||||
takes_float4(makes_float4())
|
||||
takes_int3(makes_int3())
|
||||
takes_double2(makes_double2())
|
||||
|
||||
// Float4 should not have been transitively imported.
|
||||
let x: Float4 = makes_float4() // expected-error{{undeclared type 'Float4'}}
|
||||
3
test/Inputs/clang-importer-sdk/swift-modules/SIMD.swift
Normal file
3
test/Inputs/clang-importer-sdk/swift-modules/SIMD.swift
Normal file
@@ -0,0 +1,3 @@
|
||||
@_alignment(16) public struct Float4 { var x, y, z, w: Float }
|
||||
@_alignment(16) public struct Double2 { var x, y: Double }
|
||||
@_alignment(16) public struct Int3 { var x, y, z: Int32 }
|
||||
@@ -97,3 +97,8 @@ module exceptions {
|
||||
header "exceptions.h"
|
||||
export *
|
||||
}
|
||||
|
||||
module c_simd {
|
||||
header "simd.h"
|
||||
export *
|
||||
}
|
||||
|
||||
14
test/Inputs/clang-importer-sdk/usr/include/simd.h
Normal file
14
test/Inputs/clang-importer-sdk/usr/include/simd.h
Normal file
@@ -0,0 +1,14 @@
|
||||
typedef int int3 __attribute__((__ext_vector_type__(3)));
|
||||
typedef float float4 __attribute__((__ext_vector_type__(4)));
|
||||
typedef double double2 __attribute__((__ext_vector_type__(2)));
|
||||
typedef unsigned char byte17 __attribute__((__ext_vector_type__(17)));
|
||||
|
||||
int3 makes_int3(void);
|
||||
float4 makes_float4(void);
|
||||
double2 makes_double2(void);
|
||||
byte17 makes_byte17(void);
|
||||
|
||||
void takes_int3(int3 x);
|
||||
void takes_float4(float4 x);
|
||||
void takes_double2(double2 x);
|
||||
void takes_byte17(byte17 x);
|
||||
Reference in New Issue
Block a user