Function: c-guess-basic-syntax

c-guess-basic-syntax is an autoloaded and byte-compiled function defined in cc-engine.el.gz.

Signature

(c-guess-basic-syntax)

Documentation

Return the syntactic context of the current line.

This function has :around advice: csharp-guess-basic-syntax.

Probably introduced at or before Emacs version 22.1.

Source Code

;; Defined in /usr/src/emacs/lisp/progmodes/cc-engine.el.gz
;; The next autoload was added by RMS on 2005/8/9 - don't know why (ACM,
;; 2005/11/29).
;;;###autoload
(defun c-guess-basic-syntax ()
  "Return the syntactic context of the current line."
  (save-excursion
    (beginning-of-line)
    (c-save-buffer-state
	((indent-point (point))
	 (case-fold-search nil)
	 ;; A whole ugly bunch of various temporary variables.  Have
	 ;; to declare them here since it's not possible to declare
	 ;; a variable with only the scope of a cond test and the
	 ;; following result clauses, and most of this function is a
	 ;; single gigantic cond. :P
	 literal char-before-ip before-ws-ip char-after-ip macro-start
	 in-macro-expr c-syntactic-context placeholder
	 step-type tmpsymbol keyword injava-inher special-brace-list tmp-pos
	 tmp-pos2 containing-< tmp constraint-detail enum-pos
	 ;; The following record some positions for the containing
	 ;; declaration block if we're directly within one:
	 ;; `containing-decl-open' is the position of the open
	 ;; brace.  `containing-decl-start' is the start of the
	 ;; declaration.  `containing-decl-kwd' is the keyword
	 ;; symbol of the keyword that tells what kind of block it
	 ;; is.
	 containing-decl-open
	 containing-decl-start
	 containing-decl-kwd
	 ;; The open paren of the closest surrounding sexp or nil if
	 ;; there is none.
	 containing-sexp
	 ;; The position after the closest preceding brace sexp
	 ;; (nested sexps are ignored), or the position after
	 ;; `containing-sexp' if there is none, or (point-min) if
	 ;; `containing-sexp' is nil.
	 lim
	 ;; The paren state outside `containing-sexp', or at
	 ;; `indent-point' if `containing-sexp' is nil.
	 (paren-state (c-parse-state))
	 (state-cache (copy-tree paren-state))
	 ;; There's always at most one syntactic element which got
	 ;; an anchor pos.  It's stored in syntactic-relpos.
	 syntactic-relpos
	 (c-commas-bound-stmts c-commas-bound-stmts))

      ;; Check if we're directly inside an enclosing declaration
      ;; level block.
      (when (and (setq containing-sexp
		       (c-most-enclosing-brace paren-state))
		 (progn
		   (goto-char containing-sexp)
		   (eq (char-after) ?{))
		 (setq placeholder
		       (c-looking-at-decl-block t)))
	(setq containing-decl-open containing-sexp
	      containing-decl-start (point)
	      containing-sexp nil)
	(goto-char placeholder)
	(setq containing-decl-kwd (and (looking-at c-keywords-regexp)
				       (c-keyword-sym (match-string 1)))))

      ;; Init some position variables.
      (if paren-state
	  (progn
	    (setq containing-sexp (car paren-state)
		  paren-state (cdr paren-state))
	    (if (consp containing-sexp)
	      (save-excursion
		(goto-char (cdr containing-sexp))
		(if (and (c-major-mode-is 'c++-mode)
			 (c-back-over-member-initializer-braces))
		      (c-syntactic-skip-backward "^}" nil t))
		(setq lim (point))
		(if paren-state
		    ;; Ignore balanced paren.	 The next entry
		    ;; can't be another one.
		    (setq containing-sexp (car paren-state)
			  paren-state (cdr paren-state))
		  ;; If there is no surrounding open paren then
		  ;; put the last balanced pair back on paren-state.
		  (setq paren-state (cons containing-sexp paren-state)
			containing-sexp nil)))
	      (setq lim (1+ containing-sexp))))
	(setq lim (c-determine-limit 1000)))

      ;; If we're in a parenthesis list then ',' delimits the
      ;; "statements" rather than being an operator (with the
      ;; exception of the "for" clause).  This difference is
      ;; typically only noticeable when statements are used in macro
      ;; arglists.
      (when (and containing-sexp
		 (eq (char-after containing-sexp) ?\())
	(setq c-commas-bound-stmts t))
      ;; cache char before and after indent point, and move point to
      ;; the most likely position to perform the majority of tests
      (goto-char indent-point)
      (c-backward-syntactic-ws lim)
      (setq before-ws-ip (point)
	    char-before-ip (char-before))
      (goto-char indent-point)
      (skip-chars-forward " \t")
      (setq char-after-ip (char-after))

      ;; are we in a literal?
      (setq literal (c-in-literal lim))

      ;; now figure out syntactic qualities of the current line
      (cond

       ;; CASE 1: in a string.
       ((eq literal 'string)
	(c-add-syntax 'string (c-point 'bopl)))

       ;; CASE 2: in a C or C++ style comment.
       ((and (memq literal '(c c++))
	     ;; This is a kludge for XEmacs where we use
	     ;; `buffer-syntactic-context', which doesn't correctly
	     ;; recognize "\*/" to end a block comment.
	     ;; `parse-partial-sexp' which is used by
	     ;; `c-literal-limits' will however do that in most
	     ;; versions, which results in that we get nil from
	     ;; `c-literal-limits' even when `c-in-literal' claims
	     ;; we're inside a comment.
	     (setq placeholder (c-literal-start lim)))
	(c-add-syntax literal placeholder))

       ;; CASE 3: in a cpp preprocessor macro continuation.
       ((and (save-excursion
	       (when (c-beginning-of-macro)
		 (setq macro-start (point))))
	     (/= macro-start (c-point 'boi))
	     (progn
	       (setq tmpsymbol 'cpp-macro-cont)
	       (or (not c-syntactic-indentation-in-macros)
		   (save-excursion
		     (goto-char macro-start)
		     ;; If at the beginning of the body of a #define
		     ;; directive then analyze as cpp-define-intro
		     ;; only.  Go on with the syntactic analysis
		     ;; otherwise.  in-macro-expr is set if we're in a
		     ;; cpp expression, i.e. before the #define body
		     ;; or anywhere in a non-#define directive.
		     (if (c-forward-to-cpp-define-body)
			 (let ((indent-boi (c-point 'boi indent-point)))
			   (setq in-macro-expr (> (point) indent-boi)
				 tmpsymbol 'cpp-define-intro)
			   (= (point) indent-boi))
		       (setq in-macro-expr t)
		       nil)))))
	(c-add-syntax tmpsymbol macro-start)
	(setq macro-start nil))

       ;; CASE 11: an else clause?
       ((looking-at "else\\_>")
	(c-beginning-of-statement-1 containing-sexp)
	(c-add-stmt-syntax 'else-clause nil t
			   containing-sexp paren-state))

       ;; CASE 12: while closure of a do/while construct?
       ((and (looking-at "while\\_>")
	     (save-excursion
	       (prog1 (eq (c-beginning-of-statement-1 containing-sexp)
			  'beginning)
		 (setq placeholder (point)))))
	(goto-char placeholder)
	(c-add-stmt-syntax 'do-while-closure nil t
			   containing-sexp paren-state))

       ;; CASE 13: A catch or finally clause?  This case is simpler
       ;; than if-else and do-while, because a block is required
       ;; after every try, catch and finally.
       ((save-excursion
	  (and (cond ((c-major-mode-is 'c++-mode)
		      (looking-at "catch\\_>"))
		     ((c-major-mode-is 'java-mode)
		      (looking-at "\\(catch\\|finally\\)\\_>")))
	       (and (c-safe (c-backward-syntactic-ws)
			    (c-backward-sexp)
			    t)
		    (eq (char-after) ?{)
		    (c-safe (c-backward-syntactic-ws)
			    (c-backward-sexp)
			    t)
		    (if (eq (char-after) ?\()
			(c-safe (c-backward-sexp) t)
		      t))
	       (looking-at "\\(try\\|catch\\)\\_>")
	       (setq placeholder (point))))
	(goto-char placeholder)
	(c-add-stmt-syntax 'catch-clause nil t
			   containing-sexp paren-state))

       ;; CASE 18: A substatement we can recognize by keyword.
       ((save-excursion
	  (and c-opt-block-stmt-key
	       (not (eq char-before-ip ?\;))
	       (not (c-at-vsemi-p before-ws-ip))
	       (not (memq char-after-ip '(?\) ?\] ?,)))
	       (or (not (eq char-before-ip ?}))
		   (c-looking-at-inexpr-block-backward state-cache))
	       (> (point)
		  (progn
		    ;; Ought to cache the result from the
		    ;; c-beginning-of-statement-1 calls here.
		    (setq placeholder (point))
		    (while (eq (setq step-type
				     (c-beginning-of-statement-1 lim))
			       'label))
		    (if (eq step-type 'previous)
			(goto-char placeholder)
		      (setq placeholder (point))
		      (if (and (eq step-type 'same)
			       (not (looking-at c-opt-block-stmt-key)))
			  ;; Step up to the containing statement if we
			  ;; stayed in the same one.
			  (let (step)
			    (while (eq
				    (setq step
					  (c-beginning-of-statement-1 lim))
				    'label))
			    (if (eq step 'up)
				(setq placeholder (point))
			      ;; There was no containing statement after all.
			      (goto-char placeholder)))))
		    placeholder))
	       (if (looking-at c-block-stmt-2-key)
		   ;; Require a parenthesis after these keywords.
		   ;; Necessary to catch e.g. synchronized in Java,
		   ;; which can be used both as statement and
		   ;; modifier.
		   (and (zerop (c-forward-token-2 1 nil))
			(eq (char-after) ?\())
		 (looking-at c-opt-block-stmt-key))))

	(if (eq step-type 'up)
	    ;; CASE 18A: Simple substatement.
	    (progn
	      (goto-char placeholder)
	      (cond
	       ((eq char-after-ip ?{)
		(c-add-stmt-syntax 'substatement-open nil nil
				   containing-sexp paren-state))
	       ((save-excursion
		  (goto-char indent-point)
		  (back-to-indentation)
		  (c-forward-label))
		(c-add-stmt-syntax 'substatement-label nil nil
				   containing-sexp paren-state))
	       (t
		(c-add-stmt-syntax 'substatement nil nil
				   containing-sexp paren-state))))

	  ;; CASE 18B: Some other substatement.  This is shared
	  ;; with case 10.
	  (c-guess-continued-construct indent-point
				       char-after-ip
				       placeholder
				       lim
				       paren-state)))

       ;; CASE 14: A case or default label
       ((save-excursion
	  (and (looking-at c-label-kwds-regexp)
	       (or (c-major-mode-is 'idl-mode)
		   (and
		    containing-sexp
		    (goto-char containing-sexp)
		    (eq (char-after) ?{)
		    (progn (c-backward-syntactic-ws) t)
		    (eq (char-before) ?\))
		    (c-go-list-backward)
		    (progn (c-backward-syntactic-ws) t)
		    (c-simple-skip-symbol-backward)
		    (looking-at c-block-stmt-2-key)))))
	(if containing-sexp
	    (progn
	      (goto-char containing-sexp)
	      (setq lim (c-most-enclosing-brace state-cache
						containing-sexp))
	      (c-backward-to-block-anchor lim)
	      (c-add-stmt-syntax 'case-label nil t lim paren-state))
	  ;; Got a bogus label at the top level.  In lack of better
	  ;; alternatives, anchor it on (point-min).
	  (c-add-syntax 'case-label (point-min))))

       ;; CASE 15: any other label
       ((save-excursion
	  (back-to-indentation)
	  (and (not (looking-at c-syntactic-ws-start))
	       (not (looking-at c-label-kwds-regexp))
	       (c-forward-label)))
	(cond (containing-decl-open
	       (setq placeholder (c-add-class-syntax 'inclass
						     containing-decl-open
						     containing-decl-start
						     containing-decl-kwd))
	       ;; Append access-label with the same anchor point as
	       ;; inclass gets.
	       (c-append-syntax 'access-label placeholder))

	      (containing-sexp
	       (goto-char containing-sexp)
	       (setq lim (c-most-enclosing-brace state-cache
						 containing-sexp))
	       (save-excursion
		 (setq tmpsymbol
		       (if (and (eq (c-beginning-of-statement-1 lim) 'up)
				(looking-at "switch\\_>"))
			   ;; If the surrounding statement is a switch then
			   ;; let's analyze all labels as switch labels, so
			   ;; that they get lined up consistently.
			   'case-label
			 'label)))
	       (c-backward-to-block-anchor lim)
	       (c-add-stmt-syntax tmpsymbol nil t lim paren-state))

	      (t
	       ;; A label on the top level.  Treat it as a class
	       ;; context.  (point-min) is the closest we get to the
	       ;; class open brace.
	       (c-add-syntax 'access-label (point-min)))))

       ;; CASE 4: In-expression statement.  C.f. cases 7B, 16A and
       ;; 17E.
       ((setq placeholder (c-looking-at-inexpr-block
			   (or
			    (c-safe-position containing-sexp paren-state)
			    (c-determine-limit 1000 containing-sexp))
			   containing-sexp
			   ;; Have to turn on the heuristics after
			   ;; the point even though it doesn't work
			   ;; very well.  C.f. test case class-16.pike.
			   t))
	(setq tmpsymbol (assq (car placeholder)
			      '((inexpr-class . class-open)
				(inexpr-statement . block-open))))
	(if tmpsymbol
	    ;; It's a statement block or an anonymous class.
	    (setq tmpsymbol (cdr tmpsymbol))
	  ;; It's a Pike lambda.  Check whether we are between the
	  ;; lambda keyword and the argument list or at the defun
	  ;; opener.
	  (setq tmpsymbol (if (eq char-after-ip ?{)
			      'inline-open
			    'lambda-intro-cont)))
	(goto-char (cdr placeholder))
	(back-to-indentation)
	(c-add-stmt-syntax tmpsymbol
			   (and (eq tmpsymbol 'class-open)
				(list (point)))
			   t
			   (c-most-enclosing-brace state-cache (point))
			   paren-state)
	(unless (eq (point) (cdr placeholder))
	  (c-add-syntax (car placeholder))))

       ;; CASE 5: Line is inside a declaration level block or at top level.
       ((or containing-decl-open (null containing-sexp))
	(cond

	 ;; CASE 5A: we are looking at a defun, brace list, class,
	 ;; or inline-inclass method opening brace
	 ((setq special-brace-list
		(or (and c-special-brace-lists
			 (c-looking-at-special-brace-list))
		    (eq char-after-ip ?{)))
	  (cond

	   ;; CASE 5A.1: Non-class declaration block open.
	   ((save-excursion
	      (let (tmp)
		(and (eq char-after-ip ?{)
		     (setq tmp (c-looking-at-decl-block t))
		     (progn
		       (setq placeholder (point))
		       (goto-char tmp)
		       (looking-at c-symbol-key))
		     (c-keyword-member
		      (c-keyword-sym (setq keyword (match-string 0)))
		      'c-other-block-decl-kwds))))
	    (goto-char placeholder)
	    (c-add-stmt-syntax
	     (if (string-equal keyword "extern")
		 ;; Special case for extern-lang-open.
		 'extern-lang-open
	       (intern (concat keyword "-open")))
	     nil t containing-sexp paren-state))

	   ;; CASE 5A.2: we are looking at a class opening brace
	   ((save-excursion
	      (goto-char indent-point)
	      (skip-chars-forward " \t")
	      (and (eq (char-after) ?{)
		   (setq tmp-pos (c-looking-at-decl-block t))
		   (setq placeholder (point))))
	    (c-add-syntax 'class-open placeholder
			  (c-point 'boi tmp-pos)))

	   ;; CASE 5A.3: brace-list/enum open
	   ((save-excursion
	      (goto-char indent-point)
	      (skip-chars-forward " \t")
	      (cond
	       ((setq enum-pos (c-at-enum-brace))
		(setq placeholder (c-point 'boi enum-pos)))
	       ((consp (setq placeholder
			     (c-looking-at-or-maybe-in-bracelist
			      containing-sexp lim)))
		(setq tmpsymbol (and (cdr placeholder) 'topmost-intro-cont))
		(setq placeholder (c-point 'boi (car placeholder))))))
	    (if (and (not c-auto-newline-analysis)
		     ;(c-major-mode-is 'java-mode)  ; Not needed anymore (2016-08-30).
		     (eq tmpsymbol 'topmost-intro-cont))
		;; We're in Java and have found that the open brace
		;; belongs to a "new Foo[]" initialization list,
		;; which means the brace list is part of an
		;; expression and not a top level definition.  We
		;; therefore treat it as any topmost continuation
		;; even though the semantically correct symbol still
		;; is brace-list-open, on the same grounds as in
		;; case B.2.
		(progn
		  (c-beginning-of-statement-1 lim)
		  (c-add-syntax 'topmost-intro-cont (c-point 'boi)))
	      (c-add-syntax (if enum-pos 'enum-open 'brace-list-open)
			    placeholder)))

	   ;; CASE 5A.4: inline defun open
	   ((and containing-decl-open
		 (not (c-keyword-member containing-decl-kwd
					'c-other-block-decl-kwds)))
	    (c-add-syntax 'inline-open)
	    (c-add-class-syntax 'inclass
				containing-decl-open
				containing-decl-start
				containing-decl-kwd))

	   ;; CASE 5A.7: "defun" open in a requires expression.
	   ((save-excursion
	      (goto-char indent-point)
	      (c-backward-syntactic-ws lim)
	      (and (or (not (eq (char-before) ?\)))
		       (c-go-list-backward nil lim))
		   (progn (c-backward-syntactic-ws lim)
			  (zerop (c-backward-token-2 nil nil lim)))
		   (looking-at c-fun-name-substitute-key)
		   (setq placeholder (point))))
	    (goto-char placeholder)
	    (back-to-indentation)
	    (c-add-syntax 'defun-open (point)))

	   ;; CASE 5A.6: "defun" open in concept.
	   ;; ((save-excursion
	   ;;    (goto-char indent-point)
	   ;;    (skip-chars-forward " \t")
	   ;;    (and (eq (char-after) ?{)
	   ;;      (eq (c-beginning-of-statement-1 lim) 'same)
	   ;;      (setq placeholder
	   ;;            (cdr (c-looking-at-concept indent-point)))))
	   ;;  (goto-char placeholder)
	   ;;  (back-to-indentation)
	   ;;  (c-add-syntax 'defun-open (point)))

	   ;; CASE 5A.5: ordinary defun open
	   (t
	    (save-excursion
	      (c-beginning-of-decl-1 lim)
	      (while (cond
		      ((looking-at c-specifier-key)
		       (c-forward-keyword-clause 1))
		      ((and c-opt-cpp-prefix
			    (looking-at c-noise-macro-with-parens-name-re))
		       (c-forward-noise-clause))))
	      (c-add-syntax 'defun-open (c-point 'boi))
	      ;; Bogus to use bol here, but it's the legacy.  (Resolved,
	      ;; 2007-11-09)
	      ))))

	 ;; CASE 5R: Member init list.  (Used to be part of CASE  5B.1)
	 ;; Note there is no limit on the backward search here, since member
	 ;; init lists can, in practice, be very large.
	 ((save-excursion
	    (when (and (c-major-mode-is 'c++-mode)
		       (setq placeholder (c-back-over-member-initializers
					  lim)))
	      (setq tmp-pos (point))))
	  (if (= (c-point 'bosws) (1+ tmp-pos))
		(progn
		  ;; There is no preceding member init clause.
		  ;; Indent relative to the beginning of indentation
		  ;; for the topmost-intro line that contains the
		  ;; prototype's open paren.
		  (goto-char placeholder)
		  (c-add-syntax 'member-init-intro (c-point 'boi)))
	      ;; Indent relative to the first member init clause.
	      (goto-char (1+ tmp-pos))
	      (c-forward-syntactic-ws)
	      (c-add-syntax 'member-init-cont (point))))

	 ;; CASE 5B: After a function header but before the body (or
	 ;; the ending semicolon if there's no body).
	 ((save-excursion
	    (when (setq placeholder (c-just-after-func-arglist-p
				     (max lim (c-determine-limit 500))))
	      (setq tmp-pos (point))))
	  (cond

	   ;; CASE 5B.1: Member init list.
	   ((eq (char-after tmp-pos) ?:)
	    ;; There is no preceding member init clause.
	    ;; Indent relative to the beginning of indentation
	    ;; for the topmost-intro line that contains the
	    ;; prototype's open paren.
	    (goto-char placeholder)
	    (c-add-syntax 'member-init-intro (c-point 'boi)))

	   ;; CASE 5B.2: K&R arg decl intro
	   ((and c-recognize-knr-p
		 (c-in-knr-argdecl lim))
	    (c-beginning-of-statement-1 lim)
	    (c-add-syntax 'knr-argdecl-intro (c-point 'boi))
	    (if containing-decl-open
		(c-add-class-syntax 'inclass
				    containing-decl-open
				    containing-decl-start
				    containing-decl-kwd)))

	   ;; CASE 5B.4: Nether region after a C++ or Java func
	   ;; decl, which could include a `throws' declaration.
	   (t
	    (c-beginning-of-statement-1 lim)
	    (c-add-syntax 'func-decl-cont (c-point 'boi))
	    )))

	 ;; CASE 5C: inheritance line. could be first inheritance
	 ;; line, or continuation of a multiple inheritance
	 ((or (and (c-major-mode-is 'c++-mode)
		   (progn
		     (when (eq char-after-ip ?,)
		       (skip-chars-forward " \t")
		       (forward-char))
		     (looking-at c-opt-postfix-decl-spec-key)))
	      (and (or (eq char-before-ip ?:)
		       ;; watch out for scope operator
		       (save-excursion
			 (and (eq char-after-ip ?:)
			      (c-safe (forward-char 1) t)
			      (not (eq (char-after) ?:))
			      )))
		   (save-excursion
		     (c-beginning-of-statement-1 lim)
		     (when (looking-at c-opt-<>-sexp-key)
		       (goto-char (match-end 1))
		       (c-forward-syntactic-ws)
		       (c-forward-<>-arglist nil)
		       (c-forward-syntactic-ws))
		     (looking-at c-class-key)))
	      ;; for Java
	      (and (c-major-mode-is 'java-mode)
		   (let ((fence (save-excursion
				  (c-beginning-of-statement-1 lim)
				  (point)))
			 cont done)
		     (save-excursion
		       (while (not done)
			 (cond ((looking-at c-opt-postfix-decl-spec-key)
				(setq injava-inher (cons cont (point))
				      done t))
			       ((or (not (c-safe (c-forward-sexp -1) t))
				    (<= (point) fence))
				(setq done t))
			       )
			 (setq cont t)))
		     injava-inher)
		   (not (c-crosses-statement-barrier-p (cdr injava-inher)
						       (point)))
		   ))
	  (cond

	   ;; CASE 5C.1: non-hanging colon on an inher intro
	   ((eq char-after-ip ?:)
	    (c-beginning-of-statement-1 lim)
	    (c-add-syntax 'inher-intro (c-point 'boi))
	    ;; don't add inclass symbol since relative point already
	    ;; contains any class offset
	    )

	   ;; CASE 5C.2: hanging colon on an inher intro
	   ((eq char-before-ip ?:)
	    (c-beginning-of-statement-1 lim)
	    (c-add-syntax 'inher-intro (c-point 'boi))
	    (if containing-decl-open
		(c-add-class-syntax 'inclass
				    containing-decl-open
				    containing-decl-start
				    containing-decl-kwd)))

	   ;; CASE 5C.3: in a Java implements/extends
	   (injava-inher
	    (let ((where (cdr injava-inher))
		  (cont (car injava-inher)))
	      (goto-char where)
	      (cond ((looking-at "throws\\_>")
		     (c-add-syntax 'func-decl-cont
				   (progn (c-beginning-of-statement-1 lim)
					  (c-point 'boi))))
		    (cont (c-add-syntax 'inher-cont where))
		    (t (c-add-syntax 'inher-intro
				     (progn (goto-char (cdr injava-inher))
					    (c-beginning-of-statement-1 lim)
					    (point))))
		    )))

	   ;; CASE 5C.4: a continued inheritance line
	   (t
	    (c-beginning-of-inheritance-list lim)
	    (c-add-syntax 'inher-cont (point))
	    ;; don't add inclass symbol since relative point already
	    ;; contains any class offset
	    )))

	 ;; CASE 5P: AWK pattern or function or continuation
	 ;; thereof.
	 ((c-major-mode-is 'awk-mode)
	  (setq placeholder (point))
	  (c-add-stmt-syntax
	   (if (and (eq (c-beginning-of-statement-1) 'same)
		    (/= (point) placeholder))
	       'topmost-intro-cont
	     'topmost-intro)
	   nil nil
	   containing-sexp paren-state))

	 ;; CASE 5F: Close of a non-class declaration level block.
	 ((and (eq char-after-ip ?})
	       (c-keyword-member containing-decl-kwd
				 'c-other-block-decl-kwds))
	  ;; This is inconsistent: Should use `containing-decl-open'
	  ;; here if it's at boi, like in case 5J.
	  (goto-char containing-decl-start)
	  (c-add-stmt-syntax
	   (if (string-equal (symbol-name containing-decl-kwd) "extern")
	       ;; Special case for compatibility with the
	       ;; extern-lang syntactic symbols.
	       'extern-lang-close
	     (intern (concat (symbol-name containing-decl-kwd)
			     "-close")))
	   nil t
	   (c-most-enclosing-brace paren-state (point))
	   paren-state))

	   ;; CASE 5T: Continuation of a concept clause.
	 ((save-excursion
	    (and (eq (c-beginning-of-statement-1 nil t) 'same)
		 (setq tmp (c-looking-at-concept indent-point))))
	  (c-add-syntax 'constraint-cont (car tmp)))

	 ;; CASE 5D: this could be a top-level initialization, a
	 ;; member init list continuation, or a template argument
	 ;; list continuation.
	 ((save-excursion
	    (setq constraint-detail (c-in-requires-or-at-end-of-clause))
	    ;; Note: We use the fact that lim is always after any
	    ;; preceding brace sexp.
	    (if c-recognize-<>-arglists
		(while (and
			(progn
			  (c-syntactic-skip-backward "^;,=<>" lim t)
			  (> (point) lim))
			(or
			 (when c-overloadable-operators-regexp
			   (when (setq placeholder (c-after-special-operator-id lim))
			     (goto-char placeholder)
			     t))
			 (cond
			  ((eq (char-before) ?>)
			   (or (c-backward-<>-arglist nil lim)
			       (backward-char))
			   t)
			  ((eq (char-before) ?<)
			   (backward-char)
			   (if (save-excursion
				 (c-forward-<>-arglist nil))
			       (progn (forward-char)
				      nil)
			     t))
			  (t nil)))))
	      ;; NB: No c-after-special-operator-id stuff in this
	      ;; clause - we assume only C++ needs it.
	      (c-syntactic-skip-backward "^;,=" lim t))
	    (setq placeholder (point))
	    (or constraint-detail
		(and (memq (char-before) '(?, ?= ?<))
		     (not (c-crosses-statement-barrier-p (point) indent-point)))))
	  (cond

	   ;; CASE 5D.6: Something like C++11's "using foo = <type-exp>"
	   ((save-excursion
	      (and (eq (char-before placeholder) ?=)
		   (goto-char placeholder)
		   (eq (c-backward-token-2 1 nil lim) 0)
		   (eq (point) (1- placeholder))
		   (eq (c-beginning-of-statement-1 lim) 'same)
		   (looking-at c-equals-type-clause-key)
		   (let ((preserve-point (point)))
		     (when
			 (and
			  (eq (c-forward-token-2 1 nil nil) 0)
			  (c-on-identifier))
		       (setq placeholder preserve-point)))))
	    (c-add-syntax
	     'statement-cont placeholder))

	   ;; CASE 5D.3: perhaps a template list continuation?
	   ((and (c-major-mode-is 'c++-mode)
		 (save-excursion
		   (save-restriction
		     (goto-char indent-point)
		     (setq placeholder (c-up-list-backward))
		     (and placeholder
			  (eq (char-after placeholder) ?<)))))
	    (goto-char placeholder)
	    (c-beginning-of-statement-1 lim t)
	    (if (save-excursion
		  (c-backward-syntactic-ws lim)
		  (eq (char-before) ?<))
		;; In a nested template arglist.
		(progn
		  (goto-char placeholder)
		  (c-syntactic-skip-backward "^,;" lim t)
		  (c-forward-syntactic-ws))
	      (back-to-indentation))
	    ;; FIXME: Should use c-add-stmt-syntax, but it's not yet
	    ;; template aware.
	    (c-add-syntax 'template-args-cont (point) placeholder))

	   ;; CASE 5D.4: perhaps a multiple inheritance line?
	   ((and (c-major-mode-is 'c++-mode)
		 (save-excursion
		   (c-beginning-of-statement-1 lim)
		   (setq placeholder (point))
		   (if (looking-at "static\\_>")
		       (c-forward-token-2 1 nil indent-point))
		   (and (looking-at c-class-key)
			(zerop (c-forward-token-2 2 nil indent-point))
			(if (eq (char-after) ?<)
			    (zerop (c-forward-token-2 1 t indent-point))
			  t)
			(progn
			  (while
			      (and
			       (< (point) indent-point)
			       (looking-at c-class-id-suffix-ws-ids-key)
			       (zerop (c-forward-token-2 1 nil indent-point))))
			  t)
			(eq (char-after) ?:))))
	    (goto-char placeholder)
	    (c-add-syntax 'inher-cont (c-point 'boi)))

	   ;; CASE 5D.7: Continuation of a "concept foo =" line in C++20 (or
	   ;; similar).
	   ((and constraint-detail
		 (not (eq (cdr constraint-detail) 'expression)))
	    (goto-char (car constraint-detail))
	    (c-add-stmt-syntax 'constraint-cont nil nil containing-sexp
			       paren-state))

	   ;; CASE 5D.5: Continuation of the "expression part" of a
	   ;; top level construct.  Or, perhaps, an unrecognized construct.
	   (t
	    (while (and (setq placeholder (point))
			(eq (car (c-beginning-of-decl-1 containing-sexp)) ; Can't use `lim' here.
			    'same)
			(save-excursion
			  (c-backward-syntactic-ws)
			  (eq (char-before) ?}))
			(< (point) placeholder)))
	    (c-add-stmt-syntax
	     (cond
	      ((eq (point) placeholder)
	       (setq placeholder nil)
	       'statement)  ; unrecognized construct
	      ;; A preceding comma at the top level means that a
	      ;; new variable declaration starts here.  Use
	      ;; topmost-intro-cont for it, for consistency with
	      ;; the first variable declaration.  C.f. case 5N.
	      ((eq char-before-ip ?,)
	       (if (save-excursion
		     (and
		      containing-sexp
		      (progn (goto-char containing-sexp) t)
		      (eq (char-after) ?{)
		      (setq placeholder (point))
		      (eq (c-beginning-of-statement-1
			   (or (c-most-enclosing-brace paren-state)
			       (c-determine-limit 500)))
			  'same)
		      (looking-at c-class-key)))
		   'class-field-cont
		 (setq placeholder nil)
		 'topmost-intro-cont))
	      (t
	       (setq placeholder nil)
	       'statement-cont))
	     (and placeholder (list placeholder))
	     nil containing-sexp paren-state))))

	 ;; CASE 5G: we are looking at the brace which closes the
	 ;; enclosing nested class decl
	 ((and containing-sexp
	       (eq char-after-ip ?})
	       (eq containing-decl-open containing-sexp))
	  (save-excursion
	    (goto-char containing-decl-open)
	    (setq tmp-pos (c-looking-at-decl-block nil)))
	  (c-add-class-syntax 'class-close
			      containing-decl-open
			      containing-decl-start
			      containing-decl-kwd
			      (c-point 'boi tmp-pos)))

	 ;; CASE 5H: we could be looking at subsequent knr-argdecls
	 ((and c-recognize-knr-p
	       (not containing-sexp)	; can't be knr inside braces.
	       (not (eq char-before-ip ?}))
	       (save-excursion
		 (setq placeholder (cdr (c-beginning-of-decl-1 lim)))
		 (and placeholder
		      ;; Do an extra check to avoid tripping up on
		      ;; statements that occur in invalid contexts
		      ;; (e.g. in macro bodies where we don't really
		      ;; know the context of what we're looking at).
		      (not (and c-opt-block-stmt-key
				(looking-at c-opt-block-stmt-key)))))
	       (< placeholder indent-point))
	  (goto-char placeholder)
	  (c-add-syntax 'knr-argdecl (point)))

	 ;; CASE 5I: ObjC method definition.
	 ((and c-opt-method-key
	       (looking-at c-opt-method-key))
	  (c-beginning-of-statement-1 (c-determine-limit 1000) t)
	  (if (= (point) indent-point)
	      ;; Handle the case when it's the first (non-comment)
	      ;; thing in the buffer.  Can't look for a 'same return
	      ;; value from cbos1 since ObjC directives currently
	      ;; aren't recognized fully, so that we get 'same
	      ;; instead of 'previous if it moved over a preceding
	      ;; directive.
	      (goto-char (point-min)))
	  (c-add-syntax 'objc-method-intro (c-point 'boi)))

	 ;; CASE 5N: At a variable declaration that follows a class
	 ;; definition or some other block declaration that doesn't
	 ;; end at the closing '}'.  C.f. case 5D.5.
	 ((progn
	    (c-backward-syntactic-ws lim)
	    (and (eq (char-before) ?})
		 (save-excursion
		   (let ((start (point)))
		     (if (and state-cache
			      (consp (car state-cache))
			      (eq (cdar state-cache) (point)))
			 ;; Speed up the backward search a bit.
			 (goto-char (caar state-cache)))
		     (c-beginning-of-decl-1 containing-sexp) ; Can't use `lim' here.
		     (setq placeholder (point))
		     (if (= start (point))
			 ;; The '}' is unbalanced.
			 nil
		       (c-end-of-decl-1)
		       (>= (point) indent-point))))
		 ;; Check that we only have one brace block here, i.e. that we
		 ;; don't have something like a function with a struct
		 ;; declaration as its type.
		 (save-excursion
		   (or (not (and state-cache (consp (car state-cache))))
		       ;; The above probably can't happen.
		       (progn
			 (goto-char placeholder)
			 (and (c-syntactic-re-search-forward
			       "{" indent-point t)
			      (eq (1- (point)) (caar state-cache))))))))
	  (goto-char placeholder)
	  (c-add-stmt-syntax 'topmost-intro-cont nil nil
			     containing-sexp paren-state))

	 ;; NOTE: The point is at the end of the previous token here.

	 ;; CASE 5U: We are just after a requires clause.
	 ((and (setq placeholder (c-in-requires-or-at-end-of-clause))
	       (eq (cdr-safe placeholder) t))
	  (goto-char (car placeholder))
	  (c-beginning-of-statement-1
	   (or (c-safe-position (point) paren-state)
	       (c-determine-limit 1000)))
	  (c-add-syntax 'topmost-intro-cont (point)))

	 ;; CASE 5J: we are at the topmost level, make
	 ;; sure we skip back past any access specifiers
	 ((and
	   ;; A macro continuation line is never at top level.
	   (not (and macro-start
		     (> indent-point macro-start)))
	   (save-excursion
	     (setq placeholder (point))
	     (or (memq char-before-ip '(?\; ?{ ?} nil))
		 (c-at-vsemi-p before-ws-ip)
		 (when (and (eq char-before-ip ?:)
			    (eq (c-beginning-of-statement-1 lim)
				'label))
		   (c-backward-syntactic-ws lim)
		   (setq placeholder (point)))
		 (and (c-major-mode-is 'objc-mode)
		      (catch 'not-in-directive
			(c-beginning-of-statement-1 lim)
			(setq placeholder (point))
			(while (and (c-forward-objc-directive)
				    (< (point) indent-point))
			  (c-forward-syntactic-ws)
			  (if (>= (point) indent-point)
			      (throw 'not-in-directive t))
			  (setq placeholder (point)))
			nil))
                 (and macro-start
		      (not (c-beginning-of-statement-1 lim nil nil nil t))
		      (setq placeholder
			    (let ((ps-top (car paren-state)))
			      (if (consp ps-top)
				  (progn
				    (goto-char (cdr ps-top))
				    (c-forward-syntactic-ws indent-point))
				(point-min))))))))
	  ;; For historic reasons we anchor at bol of the last
	  ;; line of the previous declaration.  That's clearly
	  ;; highly bogus and useless, and it makes our lives hard
	  ;; to remain compatible.  :P
	  (goto-char placeholder)
	  (c-add-syntax 'topmost-intro (c-point 'bol))
	  (if containing-decl-open
	      (if (c-keyword-member containing-decl-kwd
				    'c-other-block-decl-kwds)
		  (progn
		    (goto-char (c-brace-anchor-point containing-decl-open))
		    (c-add-stmt-syntax
		     (if (string-equal (symbol-name containing-decl-kwd)
				       "extern")
			 ;; Special case for compatibility with the
			 ;; extern-lang syntactic symbols.
			 'inextern-lang
		       (intern (concat "in"
				       (symbol-name containing-decl-kwd))))
		     nil t
		     (c-most-enclosing-brace paren-state (point))
		     paren-state))
		(c-add-class-syntax 'inclass
				    containing-decl-open
				    containing-decl-start
				    containing-decl-kwd)))
	  (when (and c-syntactic-indentation-in-macros
		     macro-start
		     (/= macro-start (c-point 'boi indent-point)))
	    (c-add-syntax 'cpp-define-intro)
	    (setq macro-start nil)))

	 ;; CASE 5K: we are at an ObjC method definition
	 ;; continuation line.
	 ((and c-opt-method-key
	       (save-excursion
		 (c-beginning-of-statement-1 lim)
		 (beginning-of-line)
		 (when (looking-at c-opt-method-key)
		   (setq placeholder (point)))))
	  (c-add-syntax 'objc-method-args-cont placeholder))

	 ;; CASE 5L: we are at the first argument of a template
	 ;; arglist that begins on the previous line.
	 ((and c-recognize-<>-arglists
	       (eq (char-before) ?<)
	       (not (and c-overloadable-operators-regexp
			 (c-after-special-operator-id lim))))
	  (c-beginning-of-statement-1
	   (or
	    (c-safe-position (point) paren-state)
	    (c-determine-limit 1000)))
	  (c-add-syntax 'template-args-cont (c-point 'boi)))

	 ;; CASE 5Q: we are at a statement within a macro.
	 ((and
	   macro-start
	   (save-excursion
	     (prog1
		 (not (eq (c-beginning-of-statement-1
			   (or containing-sexp (c-determine-limit 1000))
			   nil nil nil t)
			  nil)))
	       (setq placeholder (point))))
	  (goto-char placeholder)
	  (c-add-stmt-syntax 'statement nil t containing-sexp paren-state))

	 ;;CASE 5S: We are at a topmost continuation line and the only
	 ;;preceding items are annotations.
	 ((and (c-major-mode-is 'java-mode)
	       (setq placeholder (point))
	       (c-beginning-of-statement-1 lim)
	       (progn
		 (while (and (setq tmp-pos (point))
			     (< (point) placeholder)
			     (c-forward-annotation))
		   (c-forward-syntactic-ws)
		   (setq tmp-pos2 tmp-pos))
		 t)
	       (prog1
		   (>= (point) placeholder)
		 (goto-char placeholder)))
	  (c-add-syntax 'annotation-top-cont (c-point 'boi tmp-pos2)))

	 ;; CASE 5V: Identifier following type inside class braces.
	 ((save-excursion
	    (and
	     containing-sexp
	     (eq (c-beginning-of-statement-1 containing-sexp nil nil t) 'same)
	     (setq placeholder (point))
	     (progn (goto-char containing-sexp) t)
	     (eq (c-beginning-of-statement-1
		  (or (c-most-enclosing-brace paren-state)
		      (c-determine-limit 500)))
		 'same)
	     (looking-at c-class-key)
	     (progn (goto-char placeholder) t)
	     (eq (car (c-forward-decl-or-cast-1 (1+ containing-sexp) 'top nil))
		 (c-point 'boi indent-point))))
	  (c-add-syntax 'class-field-cont placeholder containing-sexp))

	 ;; CASE 5M: we are at a topmost continuation line
	 (t
	  (c-beginning-of-statement-1
	   (or (c-safe-position (point) paren-state)
	       (c-determine-limit 1000)))
	  (when (c-major-mode-is 'objc-mode)
	    (setq placeholder (point))
	    (while (and (c-forward-objc-directive)
			(< (point) indent-point))
	      (c-forward-syntactic-ws)
	      (setq placeholder (point)))
	    (goto-char placeholder))
	  (c-add-syntax 'topmost-intro-cont (c-point 'boi)))
	 ))

       ;; CASE 20: A C++ requires sub-clause.
       ((and (setq tmp (c-in-requires-or-at-end-of-clause indent-point))
	     (not (eq (cdr tmp) 'expression))
	     (setq placeholder (car tmp)))
	(c-add-syntax
	 (cond
	  ((and (eq (char-after containing-sexp) ?\()
		(> containing-sexp placeholder))
	   'constraint-cont)
	  ((eq char-after-ip ?{)
	   'substatement-open)
	  (t 'substatement))
	 (c-point 'boi placeholder)))

       ;; ((Old) CASE 6 has been removed.)
       ;; CASE 6: line is within a C11 _Generic expression.
       ((and c-generic-key
	     (eq (char-after containing-sexp) ?\()
	     (progn (setq tmp-pos (c-safe-scan-lists
				   containing-sexp 1 0
				   (min (+ (point) 2000) (point-max))))
		    t)
	     (save-excursion
	       (and
		(progn (goto-char containing-sexp)
		       (zerop (c-backward-token-2)))
		(looking-at c-generic-key)
		(progn (goto-char (1+ containing-sexp))
		       (c-syntactic-re-search-forward
			"," indent-point 'bound t t))
		(setq placeholder (point)))))
	(let ((res (c-syntactic-re-search-forward
		    "[,:)]"
		    (or tmp-pos (min (+ (point) 2000) (point-max)))
		    'bound t t)))
	  (cond
	   ((and res
		 (eq (char-before) ?\))
		 (save-excursion
		   (backward-char)
		   (c-backward-syntactic-ws indent-point)
		   (eq (point) indent-point)))
	    (c-add-stmt-syntax
	     'arglist-close (list containing-sexp) t
	     (c-most-enclosing-brace paren-state indent-point) paren-state))
	   ((or (not res)
		(eq (char-before) ?\)))
	    (backward-char)
	    (c-syntactic-skip-backward "^,:"  containing-sexp t)
	    (c-add-syntax (if (eq (char-before) ?:)
			      'statement-case-intro
			    'case-label)
			  (1+ containing-sexp)))
	   (t (c-add-syntax (if (eq (char-before) ?:)
				'case-label
			      'statement-case-intro)
			    (1+ containing-sexp))))))

       ;; CASE 7: line is an expression, not a statement.  Most
       ;; likely we are either in a function prototype or a function
       ;; call argument list
       ((not (or (and c-special-brace-lists
		      (save-excursion
			(goto-char containing-sexp)
			(c-looking-at-special-brace-list)))
		 (eq (char-after containing-sexp) ?{)))
	(cond

	 ;; CASE 7A: we are looking at the arglist closing paren.
	 ;; C.f. case 7F.
	 ((memq char-after-ip '(?\) ?\]))
	  (goto-char containing-sexp)
	  (setq placeholder (c-point 'boi))
	  (if (and (c-safe (backward-up-list 1) t)
		   (>= (point) placeholder))
	      (progn
		(forward-char)
		(skip-chars-forward " \t"))
	    (goto-char placeholder))
	  (c-add-stmt-syntax 'arglist-close (list containing-sexp) t
			     (c-most-enclosing-brace paren-state (point))
			     paren-state))

	 ;; CASE 7B: Looking at the opening brace of an
	 ;; in-expression block or brace list.  C.f. cases 4, 16A
	 ;; and 17E.
	 ((and (eq char-after-ip ?{)
	       (or (not (eq (char-after containing-sexp) ?\())
		   (save-excursion
		     (and c-opt-inexpr-brace-list-key
			  (eq (c-beginning-of-statement-1 lim t nil t) 'same)
			  (looking-at c-opt-inexpr-brace-list-key))))
	       (progn
		 (setq placeholder
		       (or (setq enum-pos (c-at-enum-brace))
			   (c-at-bracelist-p (point)
					     paren-state)))
		 (if placeholder
		     (setq tmpsymbol
			   `(,(if enum-pos 'enum-open 'brace-list-open)
			     . inexpr-class)
			   )
		   (setq tmpsymbol '(block-open . inexpr-statement)
			 placeholder
			 (cdr-safe (c-looking-at-inexpr-block
				    (or
				     (c-safe-position containing-sexp paren-state)
				     (c-determine-limit 1000 containing-sexp))
				    containing-sexp)))
		   ;; placeholder is nil if it's a block directly in
		   ;; a function arglist.  That makes us skip out of
		   ;; this case.
		   )))
	  (goto-char placeholder)
	  (back-to-indentation)
	  (c-add-stmt-syntax (car tmpsymbol) nil t
			     (c-most-enclosing-brace paren-state (point))
			     paren-state)
	  (if (/= (point) placeholder)
	      (c-add-syntax (cdr tmpsymbol))))

	 ;; CASE 7C: we are looking at the first argument in an empty
	 ;; argument list. Use arglist-close if we're actually
	 ;; looking at a close paren or bracket.
	 ((memq char-before-ip '(?\( ?\[))
	  (goto-char containing-sexp)
	  (setq placeholder (c-point 'boi))
	  (if (and (c-safe (backward-up-list 1) t)
		   (>= (point) placeholder))
	      (progn
		(forward-char)
		(skip-chars-forward " \t"))
	    (goto-char placeholder))
	  (c-add-stmt-syntax 'arglist-intro (list containing-sexp) t
			     (c-most-enclosing-brace paren-state (point))
			     paren-state))

	 ;; CASE 7D: we are inside a conditional test clause. treat
	 ;; these things as statements
	 ((progn
	    (goto-char containing-sexp)
	    (and (c-safe (c-forward-sexp -1) t)
		 (looking-at "\\_<for\\_>")))
	  (goto-char (1+ containing-sexp))
	  (c-forward-syntactic-ws indent-point)
	  (if (eq char-before-ip ?\;)
	      (c-add-syntax 'statement (point))
	    (c-add-syntax 'statement-cont (point))
	    ))

	 ;; CASE 7E: maybe a continued ObjC method call. This is the
	 ;; case when we are inside a [] bracketed exp, and what
	 ;; precede the opening bracket is not an identifier.
	 ((and c-opt-method-key
	       (eq (char-after containing-sexp) ?\[)
	       (progn
		 (goto-char (1- containing-sexp))
		 (c-backward-syntactic-ws (c-point 'bod))
		 (if (not (looking-at c-symbol-key))
		     (c-add-syntax 'objc-method-call-cont containing-sexp))
		 )))

	 ;; CASE 7F: we are looking at an arglist continuation line,
	 ;; but the preceding argument is on the same line as the
	 ;; opening paren.  This case includes multi-line
	 ;; mathematical paren groupings, but we could be on a
	 ;; for-list continuation line.  C.f. case 7A.
	 ((progn
	    (goto-char (1+ containing-sexp))
	    (< (save-excursion
		 (c-forward-syntactic-ws)
		 (point))
	       (c-point 'bonl)))
	  (goto-char containing-sexp)	; paren opening the arglist
	  (setq placeholder (c-point 'boi))
	  (if (and (c-safe (backward-up-list 1) t)
		   (>= (point) placeholder))
	      (progn
		(forward-char)
		(skip-chars-forward " \t"))
	    (goto-char placeholder))
	  (c-add-stmt-syntax 'arglist-cont-nonempty (list containing-sexp) t
			     (c-most-enclosing-brace state-cache (point))
			     paren-state))

	 ;; CASE 7G: we are looking at just a normal arglist
	 ;; continuation line
	 (t (c-forward-syntactic-ws indent-point)
	    (c-add-syntax 'arglist-cont (c-point 'boi)))
	 ))

       ;; CASE 8: func-local multi-inheritance line
       ((and (c-major-mode-is 'c++-mode)
	     (save-excursion
	       (goto-char indent-point)
	       (skip-chars-forward " \t")
	       (looking-at c-opt-postfix-decl-spec-key)))
	(goto-char indent-point)
	(skip-chars-forward " \t")
	(cond

	 ;; CASE 8A: non-hanging colon on an inher intro
	 ((eq char-after-ip ?:)
	  (c-backward-syntactic-ws lim)
	  (c-add-syntax 'inher-intro (c-point 'boi)))

	 ;; CASE 8B: hanging colon on an inher intro
	 ((eq char-before-ip ?:)
	  (c-add-syntax 'inher-intro (c-point 'boi)))

	 ;; CASE 8C: a continued inheritance line
	 (t
	  (c-beginning-of-inheritance-list lim)
	  (c-add-syntax 'inher-cont (point))
	  )))

       ;; CASE 9: we are inside a brace-list or enum.
       ((and (not (c-major-mode-is 'awk-mode))  ; Maybe this isn't needed (ACM, 2002/3/29)
	     (setq special-brace-list
		   (or (and c-special-brace-lists ;;;; ALWAYS NIL FOR AWK!!
			    (save-excursion
			      (goto-char containing-sexp)
			      (c-looking-at-special-brace-list)))
		       (setq enum-pos (c-at-enum-brace containing-sexp))
		       (c-at-bracelist-p containing-sexp paren-state)
		       (save-excursion
			 (goto-char containing-sexp)
			 (not (c-looking-at-statement-block))))))
	(cond
	 ;; CASE 9A: In the middle of a special brace list opener.
	 ((and (consp special-brace-list)
	       (save-excursion
		 (goto-char containing-sexp)
		 (eq (char-after) ?\())
	       (eq char-after-ip (car (cdr special-brace-list))))
	  (goto-char (car (car special-brace-list)))
	  (skip-chars-backward " \t")
	  (if (and (bolp)
		   (assoc 'statement-cont
			  (setq placeholder (c-guess-basic-syntax))))
	      (setq c-syntactic-context placeholder)
	    (c-beginning-of-statement-1
	     (or
	      (c-safe-position (1- containing-sexp) paren-state)
	      (c-determine-limit 1000 (1- containing-sexp))))
	    (c-forward-token-2 0)
	    (while (cond
		    ((looking-at c-specifier-key)
		     (c-forward-keyword-clause 1))
		    ((and c-opt-cpp-prefix
			  (looking-at c-noise-macro-with-parens-name-re))
		     (c-forward-noise-clause))))
	    (c-add-syntax 'brace-list-open (c-point 'boi))))

	 ;; CASE 9B: brace-list-close/enum-close brace
	 ((if (consp special-brace-list)
	      ;; Check special brace list closer.
	      (progn
		(goto-char (car (car special-brace-list)))
		(save-excursion
		  (goto-char indent-point)
		  (back-to-indentation)
		  (or
		   ;; We were between the special close char and the `)'.
		   (and (eq (char-after) ?\))
			(eq (1+ (point)) (cdr (car special-brace-list))))
		   ;; We were before the special close char.
		   (and (eq (char-after) (cdr (cdr special-brace-list)))
			(zerop (c-forward-token-2))
			(eq (1+ (point)) (cdr (car special-brace-list)))))))
	    ;; Normal brace list check.
	    (and (eq char-after-ip ?})
		 (c-safe (goto-char (c-up-list-backward (point))) t)
		 (= (point) containing-sexp)))
	  (if (eq (point) (c-point 'boi))
	      (c-add-syntax (if enum-pos 'enum-close 'brace-list-close)
			    (point))
	    (setq lim (or (save-excursion
			    (and
			     (c-back-over-member-initializers
			      (c-determine-limit 1000))
			     (point)))
			  (c-most-enclosing-brace state-cache (point))))
	    (save-excursion
	      (setq placeholder
		    (and (zerop (c-backward-token-2))
			 (looking-at "=\\([^=]\\|$\\)")
			 (zerop (c-backward-token-2))
			 (looking-at c-symbol-key)
			 (not (looking-at c-keywords-regexp))
			 (point))))
	    (if placeholder
		(goto-char placeholder)
	      (c-beginning-of-statement-1 lim nil nil t))
	    (c-add-stmt-syntax (if enum-pos 'enum-close 'brace-list-close)
			       nil t lim paren-state)))

	 (t
	  ;; Prepare for the rest of the cases below by going back to the
	  ;; previous entry, or BOI before that, providing that this is
	  ;; inside the enclosing brace.
	  (goto-char indent-point)
	  (c-beginning-of-statement-1 containing-sexp nil nil t)
	  (when (/= (point) indent-point)
	    (if (> (c-point 'boi) containing-sexp)
                (goto-char (c-point 'boi))
              (if (consp special-brace-list)
                  (progn
                    (goto-char (caar special-brace-list))
                    (c-forward-token-2 1 nil indent-point))
                (goto-char containing-sexp))
	      (forward-char)
	      (c-skip-ws-forward indent-point)))
	  (cond

	   ;; CASE 9C: we're looking at the first line in a brace-list/enum
	   ((= (point) indent-point)
	    (if (consp special-brace-list)
		(goto-char (car (car special-brace-list)))
	      (goto-char containing-sexp))
	    (if (eq (point) (c-point 'boi))
		(c-add-syntax (if enum-pos 'enum-intro 'brace-list-intro)
			      (point) containing-sexp)
	      (setq lim (or (save-excursion
			      (and
			       (c-back-over-member-initializers
				(c-determine-limit 1000))
			       (point)))
			    (c-most-enclosing-brace state-cache (point))))
	      (c-beginning-of-statement-1 lim nil nil t)
	      (c-add-stmt-syntax (if enum-pos 'enum-intro 'brace-list-intro)
				 (list containing-sexp)
				 t lim paren-state)))

	   ;; CASE 9D: this is just a later brace-list-entry/enum-entry or
	   ;; brace-entry-open
	   (t (cond
	       ((or (eq char-after-ip ?{)
		    (and c-special-brace-lists
			 (save-excursion
			   (goto-char indent-point)
			   (c-forward-syntactic-ws (c-point 'eol))
			   (c-looking-at-special-brace-list))))
		(c-add-syntax 'brace-entry-open (point)))
	       ((eq (c-point 'eol) (1- indent-point))
		(c-add-stmt-syntax (if enum-pos 'enum-entry 'brace-list-entry)
				   nil t containing-sexp
				   paren-state (point)))
	       (t (c-add-syntax (if enum-pos 'enum-entry 'brace-list-entry)
				(point)))))))))

       ;; CASE 10: A continued statement or top level construct.
       ((and (not (memq char-before-ip '(?\; ?:)))
	     (not (c-at-vsemi-p before-ws-ip))
	     (or (not (eq char-before-ip ?}))
		 (c-looking-at-inexpr-block-backward state-cache))
	     (> (point)
		(save-excursion
		  (c-beginning-of-statement-1 containing-sexp)
		  (setq placeholder (point))))
	     (/= placeholder containing-sexp))
	;; This is shared with case 18.
	(c-guess-continued-construct indent-point
				     char-after-ip
				     placeholder
				     containing-sexp
				     paren-state))

       ;; CASE 16: block close brace, possibly closing the defun or
       ;; the class
       ((eq char-after-ip ?})
	;; From here on we have the next containing sexp in lim.
	(setq lim (c-most-enclosing-brace paren-state))
	(goto-char containing-sexp)
	(cond

	 ;; CASE 16E: Closing a statement block?  This catches
	 ;; cases where it's preceded by a statement keyword,
	 ;; which works even when used in an "invalid" context,
	 ;; e.g. a macro argument.
	 ((c-after-conditional)
	  (c-backward-to-block-anchor lim)
	  (c-add-stmt-syntax 'block-close nil t lim paren-state))

	 ;; CASE 16A: closing a lambda defun or an in-expression
	 ;; block?  C.f. cases 4, 7B and 17E.
	 ((setq placeholder (c-looking-at-inexpr-block
			     (or
			      (c-safe-position containing-sexp paren-state)
			      (c-determine-limit 1000 containing-sexp))
			     nil))
	  (setq tmpsymbol (if (eq (car placeholder) 'inlambda)
			      'inline-close
			    'block-close))
	  (goto-char containing-sexp)
	  (back-to-indentation)
	  (if (= containing-sexp (point))
	      (c-add-syntax tmpsymbol (point))
	    (goto-char (cdr placeholder))
	    (back-to-indentation)
	    (c-add-stmt-syntax tmpsymbol nil t
			       (c-most-enclosing-brace paren-state (point))
			       paren-state)
	    (if (/= (point) (cdr placeholder))
		(c-add-syntax (car placeholder)))))

	 ;; CASE 16B: does this close an inline or a function in
	 ;; a non-class declaration level block?
	 ((save-excursion
	    (and lim
		 (progn
		   (goto-char lim)
		   (c-looking-at-decl-block nil))
		 (setq placeholder (point))))
	  (c-backward-to-decl-anchor lim)
	  (back-to-indentation)
	  (if (save-excursion
		(goto-char placeholder)
		(looking-at c-other-decl-block-key))
	      (c-add-syntax 'defun-close (point))
	    (c-add-syntax 'inline-close (point))))

	 ;; CASE 16G: Do we have the closing brace of a "requires" clause
	 ;; of a C++20 "concept"?
	 ((save-excursion
	    (c-backward-syntactic-ws lim)
	    (and (or (not (eq (char-before) ?\)))
		     (c-go-list-backward nil lim))
		 (progn (c-backward-syntactic-ws lim)
			(zerop (c-backward-token-2 nil nil lim)))
		 (looking-at c-fun-name-substitute-key)))
	  (goto-char containing-sexp)
	  (back-to-indentation)
	  (c-add-stmt-syntax 'defun-close nil t lim paren-state))

	 ;; CASE 16F: Can be a defun-close of a function declared
	 ;; in a statement block, e.g. in Pike or when using gcc
	 ;; extensions, but watch out for macros followed by
	 ;; blocks.  Let it through to be handled below.
	 ;; C.f. cases B.3 and 17G.
	 ((save-excursion
	    (and (not (c-at-statement-start-p))
		 (eq (c-beginning-of-statement-1 lim nil nil t) 'same)
		 (setq placeholder (point))
		 (let ((c-recognize-typeless-decls nil))
		   ;; Turn off recognition of constructs that
		   ;; lacks a type in this case, since that's more
		   ;; likely to be a macro followed by a block.
		   (c-forward-decl-or-cast-1 (c-point 'bosws) nil nil))))
	  (back-to-indentation)
	  (if (/= (point) containing-sexp)
	      (goto-char placeholder))
	  (c-add-stmt-syntax 'defun-close nil t lim paren-state))

	 ;; CASE 16C: If there is an enclosing brace then this is
	 ;; a block close since defun closes inside declaration
	 ;; level blocks have been handled above.
	 (lim
	  ;; If the block is preceded by a case/switch label on
	  ;; the same line, we anchor at the first preceding label
	  ;; at boi.  The default handling in c-add-stmt-syntax
	  ;; really fixes it better, but we do like this to keep
	  ;; the indentation compatible with version 5.28 and
	  ;; earlier.  C.f. case 17H.
	  (while (and (/= (setq placeholder (point)) (c-point 'boi))
		      (eq (c-beginning-of-statement-1 lim) 'label)))
	  (goto-char placeholder)
	  (if (looking-at c-label-kwds-regexp)
	      (c-add-syntax 'block-close (point))
	    (goto-char containing-sexp)
	    ;; c-backward-to-block-anchor not necessary here; those
	    ;; situations are handled in case 16E above.
	    (c-add-stmt-syntax 'block-close nil t lim paren-state)))

	 ;; CASE 16D: Only top level defun close left.
	 (t
	  (goto-char containing-sexp)
	  (c-backward-to-decl-anchor lim)
	  (c-add-stmt-syntax 'defun-close nil nil
			     (c-most-enclosing-brace paren-state)
			     paren-state))
	 ))

       ;; CASE 19: line is an expression, not a statement, and is directly
       ;; contained by a template delimiter.  Most likely, we are in a
       ;; template arglist within a statement.  This case is based on CASE
       ;; 7.  At some point in the future, we may wish to create more
       ;; syntactic symbols such as `template-intro',
       ;; `template-cont-nonempty', etc., and distinguish between them as we
       ;; do for `arglist-intro' etc. (2009-12-07).
       ((and c-recognize-<>-arglists
             (setq containing-< (c-up-list-backward indent-point containing-sexp))
             (eq (char-after containing-<) ?\<))
        (setq placeholder (c-point 'boi containing-<))
        (goto-char containing-sexp)	; Most nested Lbrace/Lparen (but not
                                        ; '<') before indent-point.
        (if (>= (point) placeholder)
            (progn
              (forward-char)
              (skip-chars-forward " \t"))
          (goto-char placeholder))
        (c-add-stmt-syntax 'template-args-cont (list containing-<) t
			   (c-most-enclosing-brace state-cache (point))
                           paren-state))

       ;; CASE 17: Statement or defun catchall.
       (t
	(goto-char indent-point)
	;; Back up statements until we find one that starts at boi.
	(while (let* ((prev-point (point))
		      (last-step-type (c-beginning-of-statement-1
				       containing-sexp)))
		 (if (= (point) prev-point)
		     (progn
		       (setq step-type (or step-type last-step-type))
		       nil)
		   (setq step-type last-step-type)
		   (/= (point) (c-point 'boi)))))
	(cond

	 ;; CASE 17B: continued statement
	 ((and (eq step-type 'same)
	       (/= (point) indent-point))
	  (c-add-stmt-syntax 'statement-cont nil nil
			     containing-sexp paren-state))

	 ;; CASE 17A: After a case/default label?
	 ((progn
	    (while (and (eq step-type 'label)
			(not (looking-at c-label-kwds-regexp)))
	      (setq step-type
		    (c-beginning-of-statement-1 containing-sexp)))
	    (eq step-type 'label))
	  (c-add-stmt-syntax (if (eq char-after-ip ?{)
				 'statement-case-open
			       'statement-case-intro)
			     nil t containing-sexp paren-state))

	 ;; CASE 17D: any old statement
	 ((progn
	    (while (eq step-type 'label)
	      (setq step-type
		    (c-beginning-of-statement-1 containing-sexp)))
	    (eq step-type 'previous))
	  (c-add-stmt-syntax 'statement nil t
			     containing-sexp paren-state)
	  (if (eq char-after-ip ?{)
	      (c-add-syntax 'block-open)))

	 ;; CASE 17I: Inside a substatement block.
	 ((progn
	    ;; The following tests are all based on containing-sexp.
	    (goto-char containing-sexp)
	    ;; From here on we have the next containing sexp in lim.
	    (setq lim (c-most-enclosing-brace paren-state containing-sexp))
	    (c-after-conditional))
	  (c-backward-to-block-anchor lim)
	  (c-add-stmt-syntax 'statement-block-intro nil t
			     lim paren-state)
	  (if (eq char-after-ip ?{)
	      (c-add-syntax 'block-open)))

	 ;; CASE 17E: first statement in an in-expression block.
	 ;; C.f. cases 4, 7B and 16A.
	 ((setq placeholder (c-looking-at-inexpr-block
			     (or
			      (c-safe-position containing-sexp paren-state)
			      (c-determine-limit 1000 containing-sexp))
			     nil))
	  (setq tmpsymbol (if (eq (car placeholder) 'inlambda)
			      'defun-block-intro
			    'statement-block-intro))
	  (back-to-indentation)
	  (if (= containing-sexp (point))
	      (c-add-syntax tmpsymbol (point))
	    (goto-char (cdr placeholder))
	    (back-to-indentation)
	    (c-add-stmt-syntax tmpsymbol nil t
			       (c-most-enclosing-brace state-cache (point))
			       paren-state)
	    (if (/= (point) (cdr placeholder))
		(c-add-syntax (car placeholder))))
	  (if (eq char-after-ip ?{)
	      (c-add-syntax 'block-open)))

	 ;; CASE 17J: first "statement" inside a C++20 requires
	 ;; "function".
	 ((save-excursion
	    (goto-char containing-sexp)
	    (c-backward-syntactic-ws lim)
	    (and (or (not (eq (char-before) ?\)))
		     (c-go-list-backward nil lim))
		 (progn (c-backward-syntactic-ws lim)
			(zerop (c-backward-token-2 nil nil lim)))
		 (looking-at c-fun-name-substitute-key)))
	  (goto-char containing-sexp)
	  (back-to-indentation)
	  (c-add-syntax 'defun-block-intro (point)))

	 ;; CASE 17F: first statement in an inline, or first
	 ;; statement in a top-level defun. we can tell this is it
	 ;; if there are no enclosing braces that haven't been
	 ;; narrowed out by a class (i.e. don't use bod here).
	 ((save-excursion
	    (or (not (setq placeholder (c-most-enclosing-brace
					paren-state)))
		(and (progn
		       (goto-char placeholder)
		       (eq (char-after) ?{))
		     (c-looking-at-decl-block nil))))
	  (c-backward-to-decl-anchor lim)
	  (back-to-indentation)
	  (c-add-syntax 'defun-block-intro (point)))

	 ;; CASE 17G: First statement in a function declared inside
	 ;; a normal block.  This can occur in Pike and with
	 ;; e.g. the gcc extensions, but watch out for macros
	 ;; followed by blocks.  C.f. cases B.3 and 16F.
	 ((save-excursion
	    (and (not (c-at-statement-start-p))
		 (eq (c-beginning-of-statement-1 lim nil nil t) 'same)
		 (setq placeholder (point))
		 (let ((c-recognize-typeless-decls nil))
		   ;; Turn off recognition of constructs that lacks
		   ;; a type in this case, since that's more likely
		   ;; to be a macro followed by a block.
		   (c-forward-decl-or-cast-1 (c-point 'bosws) nil nil))))
	  (back-to-indentation)
	  (if (/= (point) containing-sexp)
	      (goto-char placeholder))
	  (c-add-stmt-syntax 'defun-block-intro nil t
			     lim paren-state))

	 ;; CASE 17H: First statement in a block.
	 (t
	  ;; If the block is preceded by a case/switch label on the
	  ;; same line, we anchor at the first preceding label at
	  ;; boi.  The default handling in c-add-stmt-syntax is
	  ;; really fixes it better, but we do like this to keep the
	  ;; indentation compatible with version 5.28 and earlier.
	  ;; C.f. case 16C.
	  (while (and (/= (setq placeholder (point)) (c-point 'boi))
		      (eq (c-beginning-of-statement-1 lim) 'label)))
	  (goto-char placeholder)
	  (if (looking-at c-label-kwds-regexp)
	      (c-add-syntax 'statement-block-intro (point))
	    (goto-char containing-sexp)
	    ;; c-backward-to-block-anchor not necessary here; those
	    ;; situations are handled in case 17I above.
	    (c-add-stmt-syntax 'statement-block-intro nil t
			       lim paren-state))
	  (if (eq char-after-ip ?{)
	      (c-add-syntax 'block-open)))
	 ))
       )

      ;; now we need to look at any modifiers
      (goto-char indent-point)
      (skip-chars-forward " \t")

      ;; are we looking at a comment only line?
      (when (and (looking-at c-comment-start-regexp)
		 (/= (c-forward-token-2 0 nil (c-point 'eol)) 0))
	(c-append-syntax 'comment-intro))

      ;; we might want to give additional offset to friends (in C++).
      (when (and c-opt-friend-key
		 (looking-at c-opt-friend-key))
	(c-append-syntax 'friend))

      ;; Set syntactic-relpos.
      (let ((p c-syntactic-context))
	(while (and p
		    (if (integerp (c-langelem-pos (car p)))
			(progn
			  (setq syntactic-relpos (c-langelem-pos (car p)))
			  nil)
		      t))
	  (setq p (cdr p))))

      ;; Start of or a continuation of a preprocessor directive?
      (if (and macro-start
	       (eq macro-start (c-point 'boi))
	       (not (and (c-major-mode-is 'pike-mode)
			 (eq (char-after (1+ macro-start)) ?\"))))
	  (c-append-syntax 'cpp-macro)
	(when (and c-syntactic-indentation-in-macros macro-start)
	  (if in-macro-expr
	      (when (or
		     (< syntactic-relpos macro-start)
		     (not (or
			   (assq 'arglist-intro c-syntactic-context)
			   (assq 'arglist-cont c-syntactic-context)
			   (assq 'arglist-cont-nonempty c-syntactic-context)
			   (assq 'arglist-close c-syntactic-context))))
		;; If inside a cpp expression, i.e. anywhere in a
		;; cpp directive except a #define body, we only let
		;; through the syntactic analysis that is internal
		;; in the expression.  That means the arglist
		;; elements, if they are anchored inside the cpp
		;; expression.
		(setq c-syntactic-context nil)
		(c-add-syntax 'cpp-macro-cont macro-start))
	    (when (and (eq macro-start syntactic-relpos)
		       (not (assq 'cpp-define-intro c-syntactic-context))
		       (save-excursion
			 (goto-char macro-start)
			 (or (not (c-forward-to-cpp-define-body))
			     (<= (point) (c-point 'boi indent-point)))))
	      ;; Inside a #define body and the syntactic analysis is
	      ;; anchored on the start of the #define.  In this case
	      ;; we add cpp-define-intro to get the extra
	      ;; indentation of the #define body.
	      (c-add-syntax 'cpp-define-intro)))))

      ;; return the syntax
      c-syntactic-context)))