diff --git a/gdb/completer.c b/gdb/completer.c
index b23baed..eb80a37 100644
--- a/gdb/completer.c
+++ b/gdb/completer.c
@@ -555,8 +555,7 @@ complete_files_symbols (completion_tracker &tracker,
     }
 }
 
-/* Return a list of all source files whose names begin with matching
-   TEXT.  */
+/* See completer.h.  */
 
 completion_list
 complete_source_filenames (const char *text)
@@ -1000,9 +999,7 @@ add_struct_fields (struct type *type, completion_list &output,
     }
 }
 
-/* Complete on expressions.  Often this means completing on symbol
-   names, but some language parsers also have support for completing
-   field names.  */
+/* See completer.h.  */
 
 void
 complete_expression (completion_tracker &tracker,
diff --git a/gdb/completer.h b/gdb/completer.h
index ba66137..f68c6dc 100644
--- a/gdb/completer.h
+++ b/gdb/completer.h
@@ -267,8 +267,8 @@ private:
 
   /* If true, tell readline to skip appending a whitespace after the
      completion.  Automatically set if we have a unique completion
-     that already has a space at the end.  Completer may also
-     explicitly set this.  E.g., the linespec completer sets when when
+     that already has a space at the end.  A completer may also
+     explicitly set this.  E.g., the linespec completer sets this when
      the completion ends with the ":" separator between filename and
      function name.  */
   bool m_suppress_append_ws = false;
@@ -371,8 +371,13 @@ extern completer_handle_brkchars_ftype *
 
 /* Exported to linespec.c */
 
+/* Return a list of all source files whose names begin with matching
+   TEXT.  */
 extern completion_list complete_source_filenames (const char *text);
 
+/* Complete on expressions.  Often this means completing on symbol
+   names, but some language parsers also have support for completing
+   field names.  */
 extern void complete_expression (completion_tracker &tracker,
 				 const char *text, const char *word);
 
diff --git a/gdb/linespec.c b/gdb/linespec.c
index f2da551..136cb65 100644
--- a/gdb/linespec.c
+++ b/gdb/linespec.c
@@ -54,7 +54,14 @@ enum class linespec_complete_what
   /* Nothing, no possible completion.  */
   NOTHING,
 
-  /* A function/method name.  */
+  /* A function/method name.  Due to ambiguity between
+
+       (gdb) b source[TAB]
+       source_file.c
+       source_function
+
+     this can also indicate a source filename, iff we haven't seen a
+     separate source filename component, as in "b source.c:function".  */
   FUNCTION,
 
   /* A label symbol.  E.g., break file.c:function:LABEL.  */
@@ -298,7 +305,7 @@ struct ls_parser
      to.  */
   linespec_complete_what complete_what;
 
-  /* The completion word point.  The parser advances this as is skips
+  /* The completion word point.  The parser advances this as it skips
      tokens.  At some point the input string will end or parsing will
      fail, and then we attempt completion at the captured completion
      word point, interpreting the string at completion_word as
@@ -306,7 +313,7 @@ struct ls_parser
   const char *completion_word;
 
   /* If the current token was a quoted string, then this is the
-     quoting character (either " or '.).  */
+     quoting character (either " or ').  */
   int completion_quote_char;
 
   /* If the current token was a quoted string, then this points at the
@@ -592,7 +599,7 @@ find_parameter_list_end (const char *input)
    keyword, return the keyword start offset in STRING.  Return -1
    otherwise.  */
 
-size_t
+static size_t
 string_find_incomplete_keyword_at_end (const char * const *keywords,
 				       const char *string, size_t string_len)
 {
@@ -2893,7 +2900,12 @@ complete_linespec_component (linespec_parser *parser,
 
       linespec_complete_function (tracker, text, source_filename);
       if (source_filename == NULL)
-	fn_list = complete_source_filenames (text);
+	{
+	  /* Haven't seen a source component, like in "b
+	     file.c:function[TAB]".  Maybe this wasn't a function, but
+	     a filename instead, like "b file.[TAB]".  */
+	  fn_list = complete_source_filenames (text);
+	}
 
       /* If we only have a single filename completion, append a ':' for
 	 the user, since that's the only thing that can usefully follow
@@ -3066,7 +3078,10 @@ linespec_complete (completion_tracker &tracker, const char *text)
   else if (parser.complete_what == linespec_complete_what::FUNCTION)
     {
       /* While parsing/lexing, we didn't know whether the completion
-	 word completes to a unique function name already or not.  E.g.:
+	 word completes to a unique function/source name already or
+	 not.
+
+	 E.g.:
 	   "b function() <tab>"
 	 may need to complete either to:
 	   "b function() const"
@@ -3080,10 +3095,26 @@ linespec_complete (completion_tracker &tracker, const char *text)
 	 with "foo" being the template function's return type, or to:
 	   "b foo thread/task"
 
-	 Address that by completing assuming function, and seeing if
-	 we find a function completion that matches exactly
-	 "function()". If so, then we advance the completion word past
-	 the function and switch to KEYWORD completion mode.  */
+	 Or, this:
+	   "b file<TAB>"
+	 may need to complete either to a source file name:
+	   "b file.c"
+	 or this, also a filename, but a unique completion:
+	   "b file.c:"
+	 or to a function name:
+	   "b file_function"
+
+	 Address that by completing assuming source or function, and
+	 seeing if we find a completion that matches exactly the
+	 completion word.  If so, then it must be a function (see note
+	 below) and we advance the completion word to the end of input
+	 and switch to KEYWORD completion mode.
+
+	 Note: if we find a unique completion for a source filename,
+	 then it won't match the completion word, because the LCD will
+	 contain a trailing ':'.  And if we're completing at or after
+	 the ':', then complete_linespec_component won't try to
+	 complete on source filenames.  */
 
       const char *text = parser.completion_word;
       const char *word = parser.completion_word;
@@ -3098,7 +3129,9 @@ linespec_complete (completion_tracker &tracker, const char *text)
       if (tracker.quote_char ())
 	{
 	  /* The function/file name was not close-quoted, so this
-	     can't be a keyword.  */
+	     can't be a keyword.  Note: complete_linespec_component
+	     may have swapped the original quote char for ':' when we
+	     get here, but that still indicates the same.  */
 	}
       else if (!tracker.have_completions ())
 	{
