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)))