@@ -1677,6 +1677,9 @@ void request_initialize(const llvm::json::Object &request) {
16771677 body.try_emplace (" supportsCompletionsRequest" , true );
16781678 // The debug adapter supports the disassembly request.
16791679 body.try_emplace (" supportsDisassembleRequest" , true );
1680+ // The debug adapter supports stepping granularities (argument `granularity`)
1681+ // for the stepping requests.
1682+ body.try_emplace (" supportsSteppingGranularity" , true );
16801683
16811684 llvm::json::Array completion_characters;
16821685 completion_characters.emplace_back (" ." );
@@ -1985,6 +1988,14 @@ void request_launch(const llvm::json::Object &request) {
19851988 g_dap.SendJSON (CreateEventObject (" initialized" ));
19861989}
19871990
1991+ // Check if the step-granularity is `instruction`
1992+ static bool hasInstructionGranularity (const llvm::json::Object &requestArgs) {
1993+ if (std::optional<llvm::StringRef> value =
1994+ requestArgs.getString (" granularity" ))
1995+ return value == " instruction" ;
1996+ return false ;
1997+ }
1998+
19881999// "NextRequest": {
19892000// "allOf": [ { "$ref": "#/definitions/Request" }, {
19902001// "type": "object",
@@ -2012,6 +2023,11 @@ void request_launch(const llvm::json::Object &request) {
20122023// "threadId": {
20132024// "type": "integer",
20142025// "description": "Execute 'next' for this thread."
2026+ // },
2027+ // "granularity": {
2028+ // "$ref": "#/definitions/SteppingGranularity",
2029+ // "description": "Stepping granularity. If no granularity is specified, a
2030+ // granularity of `statement` is assumed."
20152031// }
20162032// },
20172033// "required": [ "threadId" ]
@@ -2032,7 +2048,11 @@ void request_next(const llvm::json::Object &request) {
20322048 // Remember the thread ID that caused the resume so we can set the
20332049 // "threadCausedFocus" boolean value in the "stopped" events.
20342050 g_dap.focus_tid = thread.GetThreadID ();
2035- thread.StepOver ();
2051+ if (hasInstructionGranularity (*arguments)) {
2052+ thread.StepInstruction (/* step_over=*/ true );
2053+ } else {
2054+ thread.StepOver ();
2055+ }
20362056 } else {
20372057 response[" success" ] = llvm::json::Value (false );
20382058 }
@@ -3193,6 +3213,11 @@ void request_stackTrace(const llvm::json::Object &request) {
31933213// "targetId": {
31943214// "type": "integer",
31953215// "description": "Optional id of the target to step into."
3216+ // },
3217+ // "granularity": {
3218+ // "$ref": "#/definitions/SteppingGranularity",
3219+ // "description": "Stepping granularity. If no granularity is specified, a
3220+ // granularity of `statement` is assumed."
31963221// }
31973222// },
31983223// "required": [ "threadId" ]
@@ -3223,7 +3248,11 @@ void request_stepIn(const llvm::json::Object &request) {
32233248 // Remember the thread ID that caused the resume so we can set the
32243249 // "threadCausedFocus" boolean value in the "stopped" events.
32253250 g_dap.focus_tid = thread.GetThreadID ();
3226- thread.StepInto (step_in_target.c_str (), run_mode);
3251+ if (hasInstructionGranularity (*arguments)) {
3252+ thread.StepInstruction (/* step_over=*/ false );
3253+ } else {
3254+ thread.StepInto (step_in_target.c_str (), run_mode);
3255+ }
32273256 } else {
32283257 response[" success" ] = llvm::json::Value (false );
32293258 }
0 commit comments