@@ -2897,7 +2897,8 @@ namespace {
2897
2897
auto result = Impl.createConstant (name, dc, type,
2898
2898
clang::APValue (decl->getInitVal ()),
2899
2899
ConstantConvertKind::Coerce,
2900
- /* static*/ false , decl);
2900
+ /* isStatic*/ false ,
2901
+ /* isFunctionLike*/ false , decl);
2901
2902
Impl.ImportedDecls [{decl->getCanonicalDecl (), getVersion ()}] = result;
2902
2903
2903
2904
// If this is a Swift 2 stub, mark it as such.
@@ -2936,7 +2937,8 @@ namespace {
2936
2937
auto result = Impl.createConstant (name, dc, enumType,
2937
2938
clang::APValue (decl->getInitVal ()),
2938
2939
ConstantConvertKind::Construction,
2939
- /* static*/ false , decl);
2940
+ /* isStatic*/ false ,
2941
+ /* isFunctionLike*/ false , decl);
2940
2942
Impl.ImportedDecls [{decl->getCanonicalDecl (), getVersion ()}] = result;
2941
2943
2942
2944
// If this is a Swift 2 stub, mark it as such.
@@ -4864,7 +4866,8 @@ SwiftDeclConverter::importOptionConstant(const clang::EnumConstantDecl *decl,
4864
4866
convertKind = ConstantConvertKind::ConstructionWithUnwrap;
4865
4867
Decl *CD = Impl.createConstant (
4866
4868
name, theStruct, theStruct->getDeclaredTypeInContext (),
4867
- clang::APValue (decl->getInitVal ()), convertKind, /* isStatic*/ true , decl);
4869
+ clang::APValue (decl->getInitVal ()), convertKind, /* isStatic*/ true ,
4870
+ /* isFunctionLike*/ false , decl);
4868
4871
Impl.importAttributes (decl, CD);
4869
4872
4870
4873
// NS_OPTIONS members that have a value of 0 (typically named "None") do
@@ -7201,6 +7204,7 @@ ClangImporter::Implementation::createConstant(Identifier name, DeclContext *dc,
7201
7204
const clang::APValue &value,
7202
7205
ConstantConvertKind convertKind,
7203
7206
bool isStatic,
7207
+ bool isFunctionLike,
7204
7208
ClangNode ClangN) {
7205
7209
auto &context = SwiftContext;
7206
7210
@@ -7260,73 +7264,62 @@ ClangImporter::Implementation::createConstant(Identifier name, DeclContext *dc,
7260
7264
}
7261
7265
7262
7266
assert (expr);
7263
- return createConstant (name, dc, type, expr, convertKind, isStatic, ClangN);
7267
+ if (isFunctionLike)
7268
+ return createFunction (name, dc, type, expr, convertKind, isStatic, ClangN);
7269
+ else
7270
+ return createConstant (name, dc, type, expr, convertKind, isStatic, ClangN);
7264
7271
}
7265
7272
7266
-
7267
7273
ValueDecl *
7268
7274
ClangImporter::Implementation::createConstant (Identifier name, DeclContext *dc,
7269
7275
Type type, StringRef value,
7270
7276
ConstantConvertKind convertKind,
7271
7277
bool isStatic,
7278
+ bool isFunctionLike,
7272
7279
ClangNode ClangN) {
7273
7280
auto expr = new (SwiftContext) StringLiteralExpr (value, SourceRange ());
7274
- return createConstant (name, dc, type, expr, convertKind, isStatic, ClangN);
7281
+ if (isFunctionLike)
7282
+ return createFunction (name, dc, type, expr, convertKind, isStatic, ClangN);
7283
+ else
7284
+ return createConstant (name, dc, type, expr, convertKind, isStatic, ClangN);
7275
7285
}
7276
7286
7277
-
7278
- ValueDecl *
7279
- ClangImporter::Implementation::createConstant (Identifier name, DeclContext *dc,
7280
- Type type, Expr *valueExpr,
7281
- ConstantConvertKind convertKind,
7282
- bool isStatic,
7283
- ClangNode ClangN) {
7284
- auto &C = SwiftContext;
7285
-
7286
- VarDecl *var = nullptr ;
7287
- if (ClangN) {
7288
- var = createDeclWithClangNode<VarDecl>(ClangN, Accessibility::Public,
7289
- /* IsStatic*/ isStatic, /* IsLet*/ false ,
7290
- /* IsCaptureList*/ false , SourceLoc (),
7291
- name, type, dc);
7292
- } else {
7293
- var = new (SwiftContext)
7294
- VarDecl (/* IsStatic*/ isStatic, /* IsLet*/ false , /* IsCaptureList*/ false ,
7295
- SourceLoc (), name, type, dc);
7296
- }
7297
-
7298
- var->setInterfaceType (type);
7299
-
7300
- // Form the argument patterns.
7301
- SmallVector<ParameterList*, 3 > getterArgs;
7302
-
7303
- // 'self'
7287
+ // / A helper function that creates a FuncDecl which simply returns the given
7288
+ // / constant value expression, and performs any additional conversion requested
7289
+ // / via the \c convertKind parameter. An unnamed FuncDecl (suitable for a getter
7290
+ // / function) may be created using the \c isNamed parameter.
7291
+ static FuncDecl *
7292
+ createValueGetterFuncDecl (ClangImporter::Implementation &Impl, Identifier name,
7293
+ ASTContext &C, DeclContext *dc,
7294
+ ConstantConvertKind convertKind, Type type,
7295
+ Expr *valueExpr, bool isStatic, bool isNamed) {
7296
+ // Form the parameters.
7297
+ SmallVector<ParameterList*, 3 > parameters;
7298
+ // The first parameter is 'self'.
7304
7299
if (dc->isTypeContext ()) {
7305
7300
auto *selfDecl = ParamDecl::createSelf (SourceLoc (), dc, isStatic);
7306
- getterArgs .push_back (ParameterList::createWithoutLoc (selfDecl));
7301
+ parameters .push_back (ParameterList::createWithoutLoc (selfDecl));
7307
7302
}
7308
-
7309
- // empty tuple
7310
- getterArgs.push_back (ParameterList::createEmpty (C));
7303
+ // The second is an empty tuple.
7304
+ parameters.push_back (ParameterList::createEmpty (C));
7311
7305
7312
- // Form the type of the getter .
7313
- auto getterType = ParameterList::getFullInterfaceType (type, getterArgs , C);
7306
+ // Form the type of the function .
7307
+ auto funcType = ParameterList::getFullInterfaceType (type, parameters , C);
7314
7308
7315
- // Create the getter function declaration.
7316
- auto func =
7317
- FuncDecl::create (C, /* StaticLoc=*/ SourceLoc (), StaticSpellingKind::None,
7318
- /* FuncLoc=*/ SourceLoc (),
7319
- /* Name=*/ Identifier (), /* NameLoc=*/ SourceLoc (),
7320
- /* Throws=*/ false , /* ThrowsLoc=*/ SourceLoc (),
7321
- /* AccessorKeywordLoc=*/ SourceLoc (),
7322
- /* GenericParams=*/ nullptr , getterArgs,
7323
- TypeLoc::withoutLoc (type), dc);
7309
+ // Create the function declaration.
7310
+ auto func = FuncDecl::create (
7311
+ C, /* StaticLoc=*/ SourceLoc (), StaticSpellingKind::None,
7312
+ /* FuncLoc=*/ SourceLoc (),
7313
+ /* Name=*/ isNamed ? DeclName (C, name, parameters[0 ]) : Identifier (),
7314
+ /* NameLoc=*/ SourceLoc (), /* Throws=*/ false , /* ThrowsLoc=*/ SourceLoc (),
7315
+ /* AccessorKeywordLoc=*/ SourceLoc (), /* GenericParams=*/ nullptr , parameters,
7316
+ /* TypeLoc=*/ TypeLoc::withoutLoc (type), dc);
7324
7317
func->setStatic (isStatic);
7325
- func->setInterfaceType (getterType );
7318
+ func->setInterfaceType (funcType );
7326
7319
func->setAccessibility (getOverridableAccessibility (dc));
7327
7320
7328
7321
// If we're not done type checking, build the getter body.
7329
- if (!hasFinishedTypeChecking ()) {
7322
+ if (!Impl. hasFinishedTypeChecking ()) {
7330
7323
auto expr = valueExpr;
7331
7324
7332
7325
// If we need a conversion, add one now.
@@ -7337,7 +7330,7 @@ ClangImporter::Implementation::createConstant(Identifier name, DeclContext *dc,
7337
7330
case ConstantConvertKind::Construction:
7338
7331
case ConstantConvertKind::ConstructionWithUnwrap: {
7339
7332
auto typeRef = TypeExpr::createImplicit (type, C);
7340
-
7333
+
7341
7334
expr = CallExpr::createImplicit (C, typeRef, { expr }, { C.Id_rawValue });
7342
7335
if (convertKind == ConstantConvertKind::ConstructionWithUnwrap)
7343
7336
expr = new (C) ForceValueExpr (expr, SourceLoc ());
@@ -7359,20 +7352,53 @@ ClangImporter::Implementation::createConstant(Identifier name, DeclContext *dc,
7359
7352
auto ret = new (C) ReturnStmt (SourceLoc (), expr);
7360
7353
7361
7354
// Finally, set the body.
7362
- func->setBody (BraceStmt::create (C, SourceLoc (),
7363
- ASTNode (ret),
7364
- SourceLoc ()));
7355
+ func->setBody (BraceStmt::create (C, SourceLoc (), { ret }, SourceLoc ()));
7365
7356
}
7366
7357
7358
+ // Register this thunk as an external definition.
7359
+ Impl.registerExternalDecl (func);
7360
+
7361
+ return func;
7362
+ }
7363
+
7364
+ ValueDecl *
7365
+ ClangImporter::Implementation::createFunction (Identifier name, DeclContext *dc,
7366
+ Type type, Expr *valueExpr,
7367
+ ConstantConvertKind convertKind,
7368
+ bool isStatic,
7369
+ ClangNode ClangN) {
7370
+ return createValueGetterFuncDecl (*this , name, SwiftContext, dc, convertKind,
7371
+ type, valueExpr, isStatic, /* isNamed*/ true );
7372
+ }
7373
+
7374
+ ValueDecl *
7375
+ ClangImporter::Implementation::createConstant (Identifier name, DeclContext *dc,
7376
+ Type type, Expr *valueExpr,
7377
+ ConstantConvertKind convertKind,
7378
+ bool isStatic,
7379
+ ClangNode ClangN) {
7380
+ auto &C = SwiftContext;
7381
+
7382
+ VarDecl *var = nullptr ;
7383
+ if (ClangN) {
7384
+ var = createDeclWithClangNode<VarDecl>(ClangN, Accessibility::Public,
7385
+ /* IsStatic*/ isStatic, /* IsLet*/ false ,
7386
+ /* IsCaptureList*/ false , SourceLoc (),
7387
+ name, type, dc);
7388
+ } else {
7389
+ var = new (SwiftContext)
7390
+ VarDecl (/* IsStatic*/ isStatic, /* IsLet*/ false , /* IsCaptureList*/ false ,
7391
+ SourceLoc (), name, type, dc);
7392
+ }
7393
+ var->setInterfaceType (type);
7394
+
7395
+ auto func = createValueGetterFuncDecl (*this , name, C, dc, convertKind, type,
7396
+ valueExpr, isStatic, /* isNamed*/ false );
7367
7397
// Mark the function transparent so that we inline it away completely.
7368
7398
func->getAttrs ().add (new (C) TransparentAttr (/* implicit*/ true ));
7369
-
7370
7399
// Set the function up as the getter.
7371
7400
var->makeComputed (SourceLoc (), func, nullptr , nullptr , SourceLoc ());
7372
7401
7373
- // Register this thunk as an external definition.
7374
- registerExternalDecl (func);
7375
-
7376
7402
return var;
7377
7403
}
7378
7404
0 commit comments