@@ -1009,6 +1009,117 @@ GetPatternBindingForVarDecl(swift::VarDecl *var_decl,
10091009 return pattern_binding;
10101010}
10111011
1012+ swift::FuncDecl *SwiftASTManipulator::GetFunctionToInjectVariableInto (
1013+ const SwiftASTManipulator::VariableInfo &variable, bool is_self) const {
1014+ // The only variable that we inject in the wrapper is self, so we can
1015+ // call the function declared in the type extension.
1016+ return is_self ? m_wrapper_decl : m_function_decl;
1017+ }
1018+
1019+ llvm::Optional<swift::Type> SwiftASTManipulator::GetSwiftTypeForVariable (
1020+ const SwiftASTManipulator::VariableInfo &variable, bool is_self) const {
1021+ auto *type_system_swift =
1022+ llvm::dyn_cast_or_null<TypeSystemSwift>(variable.m_type .GetTypeSystem ());
1023+
1024+ if (!type_system_swift)
1025+ return {};
1026+
1027+ // This might be a referenced type, which will confuse the type checker.
1028+ // The access pattern for these types is the same as for the referent
1029+ // type, so it is fine to just strip it off.
1030+ CompilerType referent_type =
1031+ type_system_swift->GetReferentType (variable.m_type .GetOpaqueQualType ());
1032+
1033+ swift::Type swift_type = GetSwiftType (referent_type);
1034+ if (!swift_type)
1035+ return {};
1036+
1037+ // One tricky bit here is that this var may be an argument to the
1038+ // function whose context we are emulating, and that argument might be
1039+ // of "inout" type. We need to strip the inout off the type or the
1040+ // initial parse will fail. Fortunately, the variable access goes the
1041+ // same regardless of whether it is inout or not, so we don't have to do
1042+ // anything more to get this to work.
1043+ swift_type = swift_type->getWithoutSpecifierType ();
1044+
1045+ if (is_self) {
1046+ // Another tricky bit is that the Metatype types we get have the
1047+ // "Representation" already attached (i.e.
1048+ // "@thick", "@thin".) But the representation is a SIL level thing,
1049+ // and if it is attached to types that we hand the parser, it throws a
1050+ // verifier error & aborts. So we strip it off here:
1051+ swift::MetatypeType *metatype_type =
1052+ llvm::dyn_cast<swift::MetatypeType>(swift_type.getPointer ());
1053+ if (metatype_type) {
1054+ swift_type = swift::Type (
1055+ swift::MetatypeType::get (metatype_type->getInstanceType ()));
1056+ }
1057+ }
1058+
1059+ if (swift_type->hasArchetype ())
1060+ swift_type = swift_type->mapTypeOutOfContext ();
1061+
1062+ return {swift_type};
1063+ }
1064+
1065+ swift::VarDecl *SwiftASTManipulator::GetVarDeclForVariableInFunction (
1066+ const SwiftASTManipulator::VariableInfo &variable, bool is_self,
1067+ swift::FuncDecl *containing_function) {
1068+ const auto maybe_swift_type = GetSwiftTypeForVariable (variable, is_self);
1069+
1070+ if (!maybe_swift_type)
1071+ return {};
1072+
1073+ const auto &swift_type = *maybe_swift_type;
1074+
1075+ const swift::SourceLoc loc = containing_function->getBody ()->getLBraceLoc ();
1076+ const swift::Identifier name = variable.GetName ();
1077+ // We may need to mutate the self variable later, so hardcode it to a var
1078+ // in that case.
1079+ const auto introducer =
1080+ is_self ? swift::VarDecl::Introducer::Var : variable.GetVarIntroducer ();
1081+
1082+ const swift::ASTContext &ast_context = m_source_file.getASTContext ();
1083+ swift::VarDecl *redirected_var_decl = new (ast_context) swift::VarDecl (
1084+ /* is_staic*/ false , introducer, loc, name, containing_function);
1085+
1086+ redirected_var_decl->setInterfaceType (swift_type);
1087+ redirected_var_decl->setDebuggerVar (true );
1088+ redirected_var_decl->setImplicit (true );
1089+
1090+ // This avoids having local variables filtered out by
1091+ // swift::namelookup::filterForDiscriminator().
1092+ redirected_var_decl->overwriteAccess (swift::AccessLevel::Public);
1093+
1094+ if (swift_type->getAs <swift::WeakStorageType>()) {
1095+ redirected_var_decl->getAttrs ().add (
1096+ new (ast_context) swift::ReferenceOwnershipAttr (
1097+ swift::SourceRange (), swift::ReferenceOwnership::Weak));
1098+ }
1099+
1100+ return redirected_var_decl;
1101+ }
1102+
1103+ // / Adds the new nodes to the beginning of the function.
1104+ static void AddNodesToBeginningFunction (
1105+ swift::FuncDecl *function,
1106+ const llvm::SmallVectorImpl<swift::ASTNode> &new_nodes,
1107+ swift::ASTContext &ast_context) {
1108+ swift::BraceStmt *body = function->getBody ();
1109+ llvm::ArrayRef<swift::ASTNode> current_elements = body->getElements ();
1110+
1111+ llvm::SmallVector<swift::ASTNode, 3 > new_elements (current_elements.begin (),
1112+ current_elements.end ());
1113+
1114+ // Make sure to add the new nodes at the beginning of the function.
1115+ new_elements.insert (new_elements.begin (), new_nodes.begin (), new_nodes.end ());
1116+ auto *new_function_body = swift::BraceStmt::create (
1117+ ast_context, body->getLBraceLoc (), ast_context.AllocateCopy (new_elements),
1118+ body->getRBraceLoc ());
1119+
1120+ function->setBody (new_function_body, function->getBodyKind ());
1121+ }
1122+
10121123bool SwiftASTManipulator::AddExternalVariables (
10131124 llvm::MutableArrayRef<VariableInfo> variables) {
10141125 if (!IsValid ())
@@ -1043,7 +1154,7 @@ bool SwiftASTManipulator::AddExternalVariables(
10431154
10441155 swift::VarDecl *redirected_var_decl = new (ast_context)
10451156 swift::VarDecl (is_static, introducer, loc, name,
1046- &m_source_file);
1157+ &m_source_file);
10471158 redirected_var_decl->setInterfaceType (var_type);
10481159 redirected_var_decl->setTopLevelGlobal (true );
10491160
@@ -1085,127 +1196,29 @@ bool SwiftASTManipulator::AddExternalVariables(
10851196
10861197 m_variables.push_back (variable);
10871198 } else {
1088- swift::BraceStmt *body = m_function_decl->getBody ();
1089- llvm::ArrayRef<swift::ASTNode> body_elements = body->getElements ();
1090-
1091- llvm::SmallVector<swift::ASTNode, 3 > elements (body_elements.begin (),
1092- body_elements.end ());
1093- llvm::SmallVectorImpl<swift::ASTNode>::iterator element_iterator =
1094- elements.begin ();
1095- const bool is_static = false ;
1199+ // The new nodes that should be added to each function.
1200+ std::unordered_map<swift::FuncDecl *, llvm::SmallVector<swift::ASTNode, 3 >>
1201+ injected_nodes;
10961202
10971203 for (SwiftASTManipulator::VariableInfo &variable : variables) {
1098- swift::SourceLoc loc = m_function_decl->getBody ()->getLBraceLoc ();
1099- swift::FuncDecl *containing_function = m_function_decl;
1100- swift::Identifier name = variable.m_name ;
1101- auto introducer = variable.GetVarIntroducer ();
1102-
11031204 bool is_self = !variable.m_name .str ().compare (" $__lldb_injected_self" );
1104-
1105- if (is_self) {
1106- if (!m_wrapper_decl)
1107- continue ;
1108-
1109- // We need to mutate the $__lldb_wrapped_expr_%d member of self later.
1110- introducer = swift::VarDecl::Introducer::Var;
1111- loc = m_wrapper_decl->getBody ()->getLBraceLoc ();
1112- containing_function = m_wrapper_decl;
1113- }
1114-
1115- // This might be a referenced type, which will confuse the type checker.
1116- // The access pattern for these types is the same as for the referent
1117- // type, so it is fine to
1118- // just strip it off.
1119- auto *swift_ast_ctx = llvm::dyn_cast_or_null<TypeSystemSwift>(
1120- variable.m_type .GetTypeSystem ());
1121-
1122- CompilerType referent_type;
1123- if (swift_ast_ctx)
1124- referent_type =
1125- swift_ast_ctx->GetReferentType (variable.m_type .GetOpaqueQualType ());
1126- if (!referent_type)
1127- continue ;
1128-
1129- swift::Type swift_referent_type = GetSwiftType (referent_type);
1130- if (!swift_referent_type)
1205+ swift::FuncDecl *containing_function =
1206+ GetFunctionToInjectVariableInto (variable, is_self);
1207+ assert (containing_function && " No function to inject variable into!" );
1208+ if (!containing_function)
11311209 continue ;
1132-
1133- // One tricky bit here is that this var may be an argument to the function
1134- // whose context we are
1135- // emulating, and that argument might be of "inout" type. We need to
1136- // strip the inout off the type
1137- // or the initial parse will fail. Fortunately, the variable access goes
1138- // the same regardless of whether
1139- // it is inout or not, so we don't have to do anything more to get this to
1140- // work.
1141- swift::Type var_type =
1142- swift_referent_type->getWithoutSpecifierType ();
1143- if (is_self) {
1144- // Another tricky bit is that the Metatype types we get have the
1145- // "Representation" already attached (i.e.
1146- // "@thick", "@thin".) But the representation is a SIL level thing, and
1147- // if it is attached to types that
1148- // we hand the parser, it throws a verifier error & aborts. So we strip
1149- // it off here:
1150- swift::MetatypeType *metatype_type =
1151- llvm::dyn_cast<swift::MetatypeType>(var_type.getPointer ());
1152- if (metatype_type) {
1153- var_type = swift::Type (
1154- swift::MetatypeType::get (metatype_type->getInstanceType ()));
1155- }
1156- }
1157-
1158- swift::VarDecl *redirected_var_decl = new (ast_context) swift::VarDecl (
1159- is_static, introducer, loc, name,
1160- containing_function);
1161- auto interface_type = var_type;
1162- if (interface_type->hasArchetype ())
1163- interface_type = interface_type->mapTypeOutOfContext ();
1164- redirected_var_decl->setInterfaceType (interface_type);
1165- redirected_var_decl->setDebuggerVar (true );
1166- redirected_var_decl->setImplicit (true );
1167- // This avoids having local variables filtered out by
1168- // swift::namelookup::filterForDiscriminator().
1169- redirected_var_decl->overwriteAccess (swift::AccessLevel::Public);
11701210
1211+ swift::VarDecl *redirected_var_decl = GetVarDeclForVariableInFunction (
1212+ variable, is_self, containing_function);
11711213 swift::PatternBindingDecl *pattern_binding =
11721214 GetPatternBindingForVarDecl (redirected_var_decl, containing_function);
11731215
1174- if (var_type->getAs <swift::WeakStorageType>()) {
1175- redirected_var_decl->getAttrs ().add (
1176- new (ast_context) swift::ReferenceOwnershipAttr (
1177- swift::SourceRange (), swift::ReferenceOwnership::Weak));
1178- }
1179-
1180- if (is_self) {
1181- // we need to inject into the wrapper
1182-
1183- swift::BraceStmt *wrapper_body = m_wrapper_decl->getBody ();
1184- llvm::ArrayRef<swift::ASTNode> wrapper_elements =
1185- wrapper_body->getElements ();
1186-
1187- llvm::SmallVector<swift::ASTNode, 3 > wrapper_elements_copy (
1188- wrapper_elements.begin (), wrapper_elements.end ());
1189- llvm::SmallVectorImpl<swift::ASTNode>::iterator
1190- wrapper_element_iterator = wrapper_elements_copy.begin ();
1191-
1192- wrapper_element_iterator = wrapper_elements_copy.insert (
1193- wrapper_element_iterator, swift::ASTNode (pattern_binding));
1194- wrapper_element_iterator = wrapper_elements_copy.insert (
1195- wrapper_element_iterator, swift::ASTNode (redirected_var_decl));
1196-
1197- auto *new_wrapper_body = swift::BraceStmt::create (
1198- ast_context, wrapper_body->getLBraceLoc (),
1199- ast_context.AllocateCopy (wrapper_elements_copy),
1200- wrapper_body->getRBraceLoc ());
1201- m_wrapper_decl->setBody (new_wrapper_body,
1202- m_wrapper_decl->getBodyKind ());
1203- } else {
1204- element_iterator =
1205- elements.insert (element_iterator, swift::ASTNode (pattern_binding));
1206- element_iterator = elements.insert (element_iterator,
1207- swift::ASTNode (redirected_var_decl));
1208- }
1216+ // Push the var decl and pattern binding so we add them to the function
1217+ // later.
1218+ injected_nodes[containing_function].push_back (
1219+ swift::ASTNode (pattern_binding));
1220+ injected_nodes[containing_function].push_back (
1221+ swift::ASTNode (redirected_var_decl));
12091222
12101223 variable.m_decl = redirected_var_decl;
12111224
@@ -1215,18 +1228,19 @@ bool SwiftASTManipulator::AddExternalVariables(
12151228 variable.m_decl ->dump (ss);
12161229 ss.flush ();
12171230
1218- log->Printf (
1219- " [SwiftASTManipulator::AddExternalVariables] Injected variable %s" ,
1220- s.c_str ());
1231+ log->Printf (" [SwiftASTManipulator::AddExternalVariables] Injected "
1232+ " variable %s" ,
1233+ s.c_str ());
12211234 }
12221235
12231236 m_variables.push_back (variable);
12241237 }
12251238
1226- auto *new_function_body = swift::BraceStmt::create (
1227- ast_context, body->getLBraceLoc (), ast_context.AllocateCopy (elements),
1228- body->getRBraceLoc ());
1229- m_function_decl->setBody (new_function_body, m_function_decl->getBodyKind ());
1239+ for (auto &pair : injected_nodes) {
1240+ auto *containing_function = pair.first ;
1241+ auto &new_nodes = pair.second ;
1242+ AddNodesToBeginningFunction (containing_function, new_nodes, ast_context);
1243+ }
12301244 }
12311245
12321246 return true ;
0 commit comments