diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -4381,6 +4381,9 @@
 //===----------------------------------------------------------------------===//
 let Flags = [FC1Option, FlangOnlyOption] in {
 
+def fget_definition : MultiArg<["-"], "fget-definition", 3>,
+  HelpText<"Get the symbol definition from <line> <start-column> <end-column>">,
+  Group<Action_Group>;
 def test_io : Flag<["-"], "test-io">, Group<Action_Group>,
   HelpText<"Run the InputOuputTest action. Use for development and testing only.">;
 def fdebug_unparse_no_sema : Flag<["-"], "fdebug-unparse-no-sema">, Group<Action_Group>,
diff --git a/flang/include/flang/Frontend/FrontendActions.h b/flang/include/flang/Frontend/FrontendActions.h
--- a/flang/include/flang/Frontend/FrontendActions.h
+++ b/flang/include/flang/Frontend/FrontendActions.h
@@ -116,6 +116,10 @@
   void ExecuteAction() override;
 };
 
+class GetDefinitionAction : public PrescanAndSemaAction {
+  void ExecuteAction() override;
+};
+
 class GetSymbolsSourcesAction : public PrescanAndSemaAction {
   void ExecuteAction() override;
 };
diff --git a/flang/include/flang/Frontend/FrontendOptions.h b/flang/include/flang/Frontend/FrontendOptions.h
--- a/flang/include/flang/Frontend/FrontendOptions.h
+++ b/flang/include/flang/Frontend/FrontendOptions.h
@@ -67,6 +67,9 @@
   /// Parse, run semantics and then output the pre-FIR tree
   DebugPreFIRTree,
 
+  /// `-fget-definition`
+  GetDefinition,
+
   /// Parse, run semantics and then dump symbol sources map
   GetSymbolsSources
 
@@ -206,6 +209,14 @@
   /// compilation.
   unsigned needProvenanceRangeToCharBlockMappings_ : 1;
 
+  /// Input values from `-fget-definition`
+  struct GetDefinitionVals {
+    unsigned line;
+    unsigned startColumn;
+    unsigned endColumn;
+  };
+  GetDefinitionVals getDefVals_;
+
   /// The input files and their types.
   std::vector<FrontendInputFile> inputs_;
 
diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp
--- a/flang/lib/Frontend/CompilerInvocation.cpp
+++ b/flang/lib/Frontend/CompilerInvocation.cpp
@@ -95,12 +95,14 @@
   if (opts.programAction_ == DebugDumpParsingLog)
     opts.instrumentedParse_ = true;
 
-  if (opts.programAction_ == DebugDumpProvenance)
+  if (opts.programAction_ == DebugDumpProvenance ||
+      opts.programAction_ == Fortran::frontend::GetDefinition)
     opts.needProvenanceRangeToCharBlockMappings_ = true;
 }
 
-static void ParseFrontendArgs(FrontendOptions &opts, llvm::opt::ArgList &args,
+static bool ParseFrontendArgs(FrontendOptions &opts, llvm::opt::ArgList &args,
     clang::DiagnosticsEngine &diags) {
+  unsigned numErrorsBefore = diags.getNumErrors();
 
   // By default the frontend driver creates a ParseSyntaxOnly action.
   opts.programAction_ = ParseSyntaxOnly;
@@ -157,6 +159,9 @@
     case clang::driver::options::OPT_fget_symbols_sources:
       opts.programAction_ = GetSymbolsSources;
       break;
+    case clang::driver::options::OPT_fget_definition:
+      opts.programAction_ = GetDefinition;
+      break;
 
       // TODO:
       // case calng::driver::options::OPT_emit_llvm:
@@ -165,6 +170,27 @@
       // case clang::driver::options::OPT_emit_module:
       // (...)
     }
+
+    // Parse the values provided with `-fget-definition` (there should be 3
+    // integers)
+    if (llvm::opt::OptSpecifier(a->getOption().getID()) ==
+        clang::driver::options::OPT_fget_definition) {
+      unsigned optVals[3] = {0, 0, 0};
+
+      for (unsigned i = 0; i < 3; i++) {
+        llvm::StringRef val = a->getValue(i);
+
+        if (val.getAsInteger(10, optVals[i])) {
+          // A non-integer was encountered - that's an error.
+          diags.Report(clang::diag::err_drv_invalid_value)
+              << a->getOption().getName() << val;
+          break;
+        }
+      }
+      opts.getDefVals_.line = optVals[0];
+      opts.getDefVals_.startColumn = optVals[1];
+      opts.getDefVals_.endColumn = optVals[2];
+    }
   }
 
   opts.outputFile_ = args.getLastArgValue(clang::driver::options::OPT_o);
@@ -293,6 +319,8 @@
 
   setUpFrontendBasedOnAction(opts);
   opts.dashX_ = dashX;
+
+  return diags.getNumErrors() == numErrorsBefore;
 }
 
 // Generate the path to look for intrinsic modules
@@ -481,8 +509,7 @@
     success = false;
   }
 
-  // Parse the frontend args
-  ParseFrontendArgs(res.frontendOpts(), args, diags);
+  success &= ParseFrontendArgs(res.frontendOpts(), args, diags);
   parsePreprocessorArgs(res.preprocessorOpts(), args);
   success &= parseSemaArgs(res, args, diags);
   success &= parseDialectArgs(res, args, diags);
diff --git a/flang/lib/Frontend/FrontendActions.cpp b/flang/lib/Frontend/FrontendActions.cpp
--- a/flang/lib/Frontend/FrontendActions.cpp
+++ b/flang/lib/Frontend/FrontendActions.cpp
@@ -21,6 +21,7 @@
 #include "flang/Semantics/semantics.h"
 #include "flang/Semantics/unparse-with-symbols.h"
 #include "llvm/ADT/StringRef.h"
+#include "llvm/Support/ErrorHandling.h"
 #include <clang/Basic/Diagnostic.h>
 #include <memory>
 
@@ -371,6 +372,53 @@
   ci.parsing().DumpParsingLog(llvm::outs());
 }
 
+void GetDefinitionAction::ExecuteAction() {
+  // Report and exit if fatal semantic errors are present
+  if (reportFatalSemanticErrors(semantics(), this->instance().diagnostics(),
+          GetCurrentFileOrBufferName()))
+    return;
+
+  CompilerInstance &ci = this->instance();
+  parser::AllCookedSources &cs = ci.allCookedSources();
+  unsigned diagID = ci.diagnostics().getCustomDiagID(
+      clang::DiagnosticsEngine::Error, "Symbol not found");
+
+  auto gdv = ci.invocation().frontendOpts().getDefVals_;
+  auto charBlock{cs.GetCharBlockFromLineAndColumns(
+      gdv.line, gdv.startColumn, gdv.endColumn)};
+  if (!charBlock) {
+    ci.diagnostics().Report(diagID);
+    return;
+  }
+
+  llvm::outs() << "String range: >" << charBlock->ToString() << "<\n";
+
+  auto *symbol{ci.invocation()
+                   .semanticsContext()
+                   .FindScope(*charBlock)
+                   .FindSymbol(*charBlock)};
+  if (!symbol) {
+    ci.diagnostics().Report(diagID);
+    return;
+  }
+
+  llvm::outs() << "Found symbol name: " << symbol->name().ToString() << "\n";
+
+  auto sourceInfo{cs.GetSourcePositionRange(symbol->name())};
+  if (!sourceInfo) {
+    llvm_unreachable(
+        "Failed to obtain SourcePosition."
+        "TODO: Please, write a test and replace this with a diagnostic!");
+    return;
+  }
+
+  llvm::outs() << "Found symbol name: " << symbol->name().ToString() << "\n";
+  llvm::outs() << symbol->name().ToString() << ": "
+               << sourceInfo->first.file.path() << ", "
+               << sourceInfo->first.line << ", " << sourceInfo->first.column
+               << "-" << sourceInfo->second.column << "\n";
+}
+
 void GetSymbolsSourcesAction::ExecuteAction() {
   // Report and exit if fatal semantic errors are present
   if (reportFatalSemanticErrors(semantics(), this->instance().diagnostics(),
diff --git a/flang/lib/FrontendTool/ExecuteCompilerInvocation.cpp b/flang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
--- a/flang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
+++ b/flang/lib/FrontendTool/ExecuteCompilerInvocation.cpp
@@ -67,6 +67,9 @@
   case DebugPreFIRTree:
     return std::make_unique<DebugPreFIRTreeAction>();
     break;
+  case GetDefinition:
+    return std::make_unique<GetDefinitionAction>();
+    break;
   case GetSymbolsSources:
     return std::make_unique<GetSymbolsSourcesAction>();
     break;
diff --git a/flang/test/Driver/driver-help.f90 b/flang/test/Driver/driver-help.f90
--- a/flang/test/Driver/driver-help.f90
+++ b/flang/test/Driver/driver-help.f90
@@ -91,6 +91,8 @@
 ! HELP-FC1-NEXT: -ffixed-line-length=<value>
 ! HELP-FC1-NEXT: Use <value> as character line width in fixed mode
 ! HELP-FC1-NEXT: -ffree-form            Process source files in free form
+! HELP-FC1-NEXT: -fget-definition <value> <value> <value>
+! HELP-FC1-NEXT:                        Get the symbol definition from <line> <start-column> <end-column>
 ! HELP-FC1-NEXT: -fget-symbols-sources   Dump symbols and their source code locations
 ! HELP-FC1-NEXT: -fimplicit-none        No implicit typing allowed unless overridden by IMPLICIT statements
 ! HELP-FC1-NEXT: -finput-charset=<value> Specify the default character set for source files
diff --git a/flang/test/Driver/get-definition.f90 b/flang/test/Driver/get-definition.f90
new file mode 100644
--- /dev/null
+++ b/flang/test/Driver/get-definition.f90
@@ -0,0 +1,46 @@
+! Verify that the driver correctly rejects invalid values for -fget-definition
+
+!-----------
+! RUN LINES
+!-----------
+! RUN: not %flang_fc1 -fsyntax-only -fget-definition 45 1 2 %s 2>&1 | FileCheck --check-prefix=OK %s
+! RUN: not %flang_fc1 -fsyntax-only -fget-definition a 1 1 %s 2>&1 | FileCheck --check-prefix=ERROR-a %s
+! RUN: not %flang_fc1 -fsyntax-only -fget-definition 1 b 1 %s 2>&1 | FileCheck --check-prefix=ERROR-b %s
+! RUN: not %flang_fc1 -fsyntax-only -fget-definition 1 1 c %s 2>&1 | FileCheck --check-prefix=ERROR-c %s
+! RUN: not %flang_fc1 -fsyntax-only -fget-definition a b 1 %s 2>&1 | FileCheck --check-prefix=ERROR-ab %s
+! RUN: not %flang_fc1 -fsyntax-only -fget-definition a b c %s 2>&1 | FileCheck --check-prefix=ERROR-abc %s
+! RUN: not %flang_fc1 -fsyntax-only -fget-definition 1 b c %s 2>&1 | FileCheck --check-prefix=ERROR-bc %s
+! RUN: not %flang_fc1 -fsyntax-only -fget-definition a 1 c %s 2>&1 | FileCheck --check-prefix=ERROR-ac %s
+
+!-----------------
+! EXPECTED OUTPUT
+!-----------------
+! OK: String range: >m<
+! OK-NOT: error
+
+! ERROR-a: error: invalid value 'a' in 'fget-definition'
+! ERROR-a-NOT: String range: >m<
+
+! ERROR-b: error: invalid value 'b' in 'fget-definition'
+! ERROR-b-NOT: String range: >m<
+
+! ERROR-c: error: invalid value 'c' in 'fget-definition'
+! ERROR-c-NOT: String range: >m<
+
+! ERROR-ab: error: invalid value 'a' in 'fget-definition'
+! ERROR-ab-NOT: String range: >m<
+
+! ERROR-ac: error: invalid value 'a' in 'fget-definition'
+! ERROR-ac-NOT: String range: >m<
+
+! ERROR-bc: error: invalid value 'b' in 'fget-definition'
+! ERROR-bc-NOT: String range: >m<
+
+! ERROR-abc: error: invalid value 'a' in 'fget-definition'
+! ERROR-abc-NOT: String range: >m<
+
+!-------
+! INPUT
+!-------
+module m
+end module
diff --git a/flang/test/Semantics/getdefinition01.f90 b/flang/test/Semantics/getdefinition01.f90
--- a/flang/test/Semantics/getdefinition01.f90
+++ b/flang/test/Semantics/getdefinition01.f90
@@ -16,12 +16,9 @@
 end module
 
 ! RUN and CHECK lines at the bottom as this test is sensitive to line numbers
-! RUN: %f18 -fget-definition 6 17 18 -fsyntax-only %s | FileCheck --check-prefix=CHECK1 %s
-! RUN: %f18 -fget-definition 7 20 23 -fsyntax-only %s | FileCheck --check-prefix=CHECK2 %s
-! RUN: %f18 -fget-definition 14 3 4 -fsyntax-only %s | FileCheck --check-prefix=CHECK3 %s
+! RUN: %flang_fc1 -fsyntax-only -fget-definition 6 17 18 %s | FileCheck --check-prefix=CHECK1 %s
+! RUN: %flang_fc1 -fsyntax-only -fget-definition 7 20 23 %s | FileCheck --check-prefix=CHECK2 %s
+! RUN: %flang_fc1 -fsyntax-only -fget-definition 14 3 4 %s | FileCheck --check-prefix=CHECK3 %s
 ! CHECK1: x:{{.*}}getdefinition01.f90, 5, 21-22
 ! CHECK2: yyy:{{.*}}getdefinition01.f90, 5, 24-27
 ! CHECK3: x:{{.*}}getdefinition01.f90, 13, 24-25
-
-! RUN: not %f18 -fget-definition -fsyntax-only %s 2>&1 | FileCheck --check-prefix=CHECK-ERROR %s
-! CHECK-ERROR: Invalid argument to -fget-definitions
diff --git a/flang/test/Semantics/getdefinition02.f b/flang/test/Semantics/getdefinition02.f
--- a/flang/test/Semantics/getdefinition02.f
+++ b/flang/test/Semantics/getdefinition02.f
@@ -17,9 +17,9 @@
       end module
 
 ! RUN and CHECK lines here as test is sensitive to line numbers
-! RUN: %f18 -fget-definition 7 9 10 -fsyntax-only %s 2>&1 | FileCheck --check-prefix=CHECK1 %s
-! RUN: %f18 -fget-definition 8 26 29 -fsyntax-only %s 2>&1 | FileCheck --check-prefix=CHECK2 %s
-! RUN: %f18 -fget-definition 15 9 10 -fsyntax-only %s 2>&1 | FileCheck --check-prefix=CHECK3 %s
+! RUN: %flang_fc1 -fsyntax-only -fget-definition 7 9 10 %s 2>&1 | FileCheck --check-prefix=CHECK1 %s
+! RUN: %flang_fc1 -fsyntax-only -fget-definition 8 26 29 %s 2>&1 | FileCheck --check-prefix=CHECK2 %s
+! RUN: %flang_fc1 -fsyntax-only -fget-definition 15 9 10 %s 2>&1 | FileCheck --check-prefix=CHECK3 %s
 ! CHECK1: x:{{.*}}getdefinition02.f, 5, 27-28
 ! CHECK2: yyy:{{.*}}getdefinition02.f, 5, 30-33
 ! CHECK3: x:{{.*}}getdefinition02.f, 14, 30-31
diff --git a/flang/test/Semantics/getdefinition03-a.f90 b/flang/test/Semantics/getdefinition03-a.f90
--- a/flang/test/Semantics/getdefinition03-a.f90
+++ b/flang/test/Semantics/getdefinition03-a.f90
@@ -7,7 +7,7 @@
  x = f
 end program
 
-! RUN: %f18 -fget-definition 7 6 7 -fsyntax-only %s | FileCheck --check-prefix=CHECK1 %s
-! RUN: %f18 -fget-definition 7 2 3 -fsyntax-only %s | FileCheck --check-prefix=CHECK2 %s
+! RUN: %flang_fc1 -fsyntax-only -fget-definition 7 6 7 %s | FileCheck --check-prefix=CHECK1 %s
+! RUN: %flang_fc1 -fsyntax-only -fget-definition 7 2 3 %s | FileCheck --check-prefix=CHECK2 %s
 ! CHECK1: f:{{.*}}getdefinition03-b.f90, 2, 12-13
 ! CHECK2: x:{{.*}}getdefinition03-a.f90, 6, 13-14
diff --git a/flang/test/Semantics/getdefinition04.f90 b/flang/test/Semantics/getdefinition04.f90
--- a/flang/test/Semantics/getdefinition04.f90
+++ b/flang/test/Semantics/getdefinition04.f90
@@ -6,5 +6,5 @@
   x = y
 end program
 
-! RUN: %f18 -fget-definition 6 3 4 -fsyntax-only %s | FileCheck %s
+! RUN: %flang_fc1 -fsyntax-only -fget-definition 6 3 4 %s | FileCheck %s
 ! CHECK: x:{{.*}}getdefinition04.f90, 3, 14-15
diff --git a/flang/test/Semantics/getdefinition05.f90 b/flang/test/Semantics/getdefinition05.f90
--- a/flang/test/Semantics/getdefinition05.f90
+++ b/flang/test/Semantics/getdefinition05.f90
@@ -12,8 +12,8 @@
 end program
 
 !! Inner x
-! RUN: %f18 -fget-definition 9 5 6 -fsyntax-only %s | FileCheck --check-prefix=CHECK1 %s
+! RUN: %flang_fc1 -fsyntax-only -fget-definition 9 5 6 %s | FileCheck --check-prefix=CHECK1 %s
 ! CHECK1: x:{{.*}}getdefinition05.f90, 7, 16-17
 !! Outer y
-! RUN: %f18 -fget-definition 11 7 8 -fsyntax-only %s | FileCheck --check-prefix=CHECK2 %s
+! RUN: %flang_fc1 -fsyntax-only -fget-definition 11 7 8 %s | FileCheck --check-prefix=CHECK2 %s
 ! CHECK2: y:{{.*}}getdefinition05.f90, 5, 14-15
diff --git a/flang/tools/f18/f18.cpp b/flang/tools/f18/f18.cpp
--- a/flang/tools/f18/f18.cpp
+++ b/flang/tools/f18/f18.cpp
@@ -658,8 +658,8 @@
         }
         arguments[i] = std::strtol(args.front().c_str(), &endptr, 10);
         if (*endptr != '\0') {
-          llvm::errs() << "Invalid argument to -fget-definitions: "
-                       << args.front() << '\n';
+          llvm::errs() << "error: invalid value '" << args.front()
+                       << "' in 'fget-definition'" << '\n';
           return EXIT_FAILURE;
         }
         args.pop_front();