aboutsummaryrefslogtreecommitdiffstats
path: root/lisp/progmodes/cc-engine.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/progmodes/cc-engine.el')
-rw-r--r--lisp/progmodes/cc-engine.el182
1 files changed, 143 insertions, 39 deletions
diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el
index b2c548847c3..ea0a8f2d3b3 100644
--- a/lisp/progmodes/cc-engine.el
+++ b/lisp/progmodes/cc-engine.el
@@ -705,7 +705,7 @@ comment at the start of cc-engine.el for more info."
705 ;; The last position where a label is possible provided the 705 ;; The last position where a label is possible provided the
706 ;; statement started there. It's nil as long as no invalid 706 ;; statement started there. It's nil as long as no invalid
707 ;; label content has been found (according to 707 ;; label content has been found (according to
708 ;; `c-nonlabel-token-key'. It's `start' if no valid label 708 ;; `c-nonlabel-token-key'). It's `start' if no valid label
709 ;; content was found in the label. Note that we might still 709 ;; content was found in the label. Note that we might still
710 ;; regard it a label if it starts with `c-label-kwds'. 710 ;; regard it a label if it starts with `c-label-kwds'.
711 label-good-pos 711 label-good-pos
@@ -1035,7 +1035,12 @@ comment at the start of cc-engine.el for more info."
1035 ;; (including a case label) or something like C++'s "public:"? 1035 ;; (including a case label) or something like C++'s "public:"?
1036 ;; A case label might use an expression rather than a token. 1036 ;; A case label might use an expression rather than a token.
1037 (setq after-case:-pos (or tok start)) 1037 (setq after-case:-pos (or tok start))
1038 (if (looking-at c-nonlabel-token-key) ; e.g. "while" or "'a'" 1038 (if (or (looking-at c-nonlabel-token-key) ; e.g. "while" or "'a'"
1039 ;; Catch C++'s inheritance construct "class foo : bar".
1040 (save-excursion
1041 (and
1042 (c-safe (c-backward-sexp) t)
1043 (looking-at c-nonlabel-token-2-key))))
1039 (setq c-maybe-labelp nil) 1044 (setq c-maybe-labelp nil)
1040 (if after-labels-pos ; Have we already encountered a label? 1045 (if after-labels-pos ; Have we already encountered a label?
1041 (if (not last-label-pos) 1046 (if (not last-label-pos)
@@ -1149,42 +1154,65 @@ the line. If this virtual semicolon is _at_ from, the function recognizes it.
1149 1154
1150Note that this function might do hidden buffer changes. See the 1155Note that this function might do hidden buffer changes. See the
1151comment at the start of cc-engine.el for more info." 1156comment at the start of cc-engine.el for more info."
1152 (let ((skip-chars c-stmt-delim-chars) 1157 (let* ((skip-chars
1153 lit-range) 1158 ;; If the current language has CPP macros, insert # into skip-chars.
1154 (save-excursion 1159 (if c-opt-cpp-symbol
1155 (catch 'done 1160 (concat (substring c-stmt-delim-chars 0 1) ; "^"
1156 (goto-char from) 1161 c-opt-cpp-symbol ; usually "#"
1157 (while (progn (skip-chars-forward skip-chars to) 1162 (substring c-stmt-delim-chars 1)) ; e.g. ";{}?:"
1158 (< (point) to)) 1163 c-stmt-delim-chars))
1159 (cond 1164 (non-skip-list
1160 ((setq lit-range (c-literal-limits from)) ; Have we landed in a string/comment? 1165 (append (substring skip-chars 1) nil)) ; e.g. (?# ?\; ?{ ?} ?? ?:)
1161 (goto-char (cdr lit-range))) 1166 lit-range vsemi-pos)
1162 ((eq (char-after) ?:) 1167 (save-restriction
1163 (forward-char) 1168 (widen)
1164 (if (and (eq (char-after) ?:) 1169 (save-excursion
1165 (< (point) to)) 1170 (catch 'done
1166 ;; Ignore scope operators. 1171 (goto-char from)
1167 (forward-char) 1172 (while (progn (skip-chars-forward
1168 (setq c-maybe-labelp (1- (point))))) 1173 skip-chars
1169 ((eq (char-after) ??) 1174 (min to (c-point 'bonl)))
1170 ;; A question mark. Can't be a label, so stop 1175 (< (point) to))
1171 ;; looking for more : and ?. 1176 (cond
1172 (setq c-maybe-labelp nil 1177 ;; Virtual semicolon?
1173 skip-chars (substring c-stmt-delim-chars 0 -2))) 1178 ((and (bolp)
1174 ((memq (char-after) '(?# ?\n ?\r)) ; A virtual semicolon? 1179 (save-excursion
1175 (if (and (eq (char-before) ?\\) (memq (char-after) '(?\n ?\r))) 1180 (progn
1176 (backward-char)) 1181 (if (setq lit-range (c-literal-limits from)) ; Have we landed in a string/comment?
1177 (skip-chars-backward " \t" from) 1182 (goto-char (car lit-range)))
1178 (if (c-at-vsemi-p) 1183 (c-backward-syntactic-ws) ; ? put a limit here, maybe?
1179 (throw 'done (point)) 1184 (setq vsemi-pos (point))
1180 (forward-line))) 1185 (c-at-vsemi-p))))
1181 (t (throw 'done (point))))) 1186 (throw 'done vsemi-pos))
1182 ;; In trailing space after an as yet undetected virtual semicolon? 1187 ;; In a string/comment?
1183 (c-backward-syntactic-ws from) 1188 ((setq lit-range (c-literal-limits))
1184 (if (and (< (point) to) 1189 (goto-char (cdr lit-range)))
1185 (c-at-vsemi-p)) 1190 ((eq (char-after) ?:)
1186 (point) 1191 (forward-char)
1187 nil))))) 1192 (if (and (eq (char-after) ?:)
1193 (< (point) to))
1194 ;; Ignore scope operators.
1195 (forward-char)
1196 (setq c-maybe-labelp (1- (point)))))
1197 ((eq (char-after) ??)
1198 ;; A question mark. Can't be a label, so stop
1199 ;; looking for more : and ?.
1200 (setq c-maybe-labelp nil
1201 skip-chars (substring c-stmt-delim-chars 0 -2)))
1202 ;; At a CPP construct?
1203 ((and c-opt-cpp-symbol (looking-at c-opt-cpp-symbol)
1204 (save-excursion
1205 (forward-line 0)
1206 (looking-at c-opt-cpp-prefix)))
1207 (c-end-of-macro))
1208 ((memq (char-after) non-skip-list)
1209 (throw 'done (point)))))
1210 ;; In trailing space after an as yet undetected virtual semicolon?
1211 (c-backward-syntactic-ws from)
1212 (if (and (< (point) to)
1213 (c-at-vsemi-p))
1214 (point)
1215 nil))))))
1188 1216
1189(defun c-at-statement-start-p () 1217(defun c-at-statement-start-p ()
1190 "Return non-nil if the point is at the first token in a statement 1218 "Return non-nil if the point is at the first token in a statement
@@ -7158,12 +7186,14 @@ comment at the start of cc-engine.el for more info."
7158 ;; Check that we're not after a token that can't precede a label. 7186 ;; Check that we're not after a token that can't precede a label.
7159 (or 7187 (or
7160 ;; Trivially succeeds when there's no preceding token. 7188 ;; Trivially succeeds when there's no preceding token.
7189 ;; Succeeds when we're at a virtual semicolon.
7161 (if preceding-token-end 7190 (if preceding-token-end
7162 (<= preceding-token-end (point-min)) 7191 (<= preceding-token-end (point-min))
7163 (save-excursion 7192 (save-excursion
7164 (c-backward-syntactic-ws) 7193 (c-backward-syntactic-ws)
7165 (setq preceding-token-end (point)) 7194 (setq preceding-token-end (point))
7166 (bobp))) 7195 (or (bobp)
7196 (c-at-vsemi-p))))
7167 7197
7168 ;; Check if we're after a label, if we're after a closing 7198 ;; Check if we're after a label, if we're after a closing
7169 ;; paren that belong to statement, and with 7199 ;; paren that belong to statement, and with
@@ -8037,6 +8067,29 @@ comment at the start of cc-engine.el for more info."
8037 (back-to-indentation) 8067 (back-to-indentation)
8038 (vector (point) open-paren-pos)))))) 8068 (vector (point) open-paren-pos))))))
8039 8069
8070(defmacro c-pull-open-brace (ps)
8071 ;; Pull the next open brace from PS (which has the form of paren-state),
8072 ;; skipping over any brace pairs. Returns NIL when PS is exhausted.
8073 `(progn
8074 (while (consp (car ,ps))
8075 (setq ,ps (cdr ,ps)))
8076 (prog1 (car ,ps)
8077 (setq ,ps (cdr ,ps)))))
8078
8079(defun c-most-enclosing-decl-block (paren-state)
8080 ;; Return the buffer position of the most enclosing decl-block brace (in the
8081 ;; sense of c-looking-at-decl-block) in the PAREN-STATE structure, or nil if
8082 ;; none was found.
8083 (let* ((open-brace (c-pull-open-brace paren-state))
8084 (next-open-brace (c-pull-open-brace paren-state)))
8085 (while (and open-brace
8086 (save-excursion
8087 (goto-char open-brace)
8088 (not (c-looking-at-decl-block next-open-brace nil))))
8089 (setq open-brace next-open-brace
8090 next-open-brace (c-pull-open-brace paren-state)))
8091 open-brace))
8092
8040(defun c-inside-bracelist-p (containing-sexp paren-state) 8093(defun c-inside-bracelist-p (containing-sexp paren-state)
8041 ;; return the buffer position of the beginning of the brace list 8094 ;; return the buffer position of the beginning of the brace list
8042 ;; statement if we're inside a brace list, otherwise return nil. 8095 ;; statement if we're inside a brace list, otherwise return nil.
@@ -8372,6 +8425,57 @@ comment at the start of cc-engine.el for more info."
8372 paren-state) 8425 paren-state)
8373 containing-sexp))))) 8426 containing-sexp)))))
8374 8427
8428(defun c-at-macro-vsemi-p (&optional pos)
8429 ;; Is there a "virtual semicolon" at POS or point?
8430 ;; (See cc-defs.el for full details of "virtual semicolons".)
8431 ;;
8432 ;; This is true when point is at the last non syntactic WS position on the
8433 ;; line, there is a macro call last on the line, and this particular macro's
8434 ;; name is defined by the regexp `c-vs-macro-regexp' as not needing a
8435 ;; semicolon.
8436 (save-excursion
8437 (save-restriction
8438 (widen)
8439 (if pos
8440 (goto-char pos)
8441 (setq pos (point)))
8442 (and
8443 c-macro-with-semi-re
8444 (not (c-in-literal))
8445 (eq (skip-chars-backward " \t") 0)
8446
8447 ;; Check we've got nothing after this except comments and empty lines
8448 ;; joined by escaped EOLs.
8449 (skip-chars-forward " \t") ; always returns non-nil.
8450 (progn
8451 (while ; go over 1 block comment per iteration.
8452 (and
8453 (looking-at "\\(\\\\[\n\r][ \t]*\\)*")
8454 (goto-char (match-end 0))
8455 (cond
8456 ((looking-at c-block-comment-start-regexp)
8457 (and (forward-comment 1)
8458 (skip-chars-forward " \t"))) ; always returns non-nil
8459 ((looking-at c-line-comment-start-regexp)
8460 (end-of-line)
8461 nil)
8462 (t nil))))
8463 (eolp))
8464
8465 (goto-char pos)
8466 (progn (c-backward-syntactic-ws)
8467 (eq (point) pos))
8468
8469 ;; Check for one of the listed macros being before point.
8470 (or (not (eq (char-before) ?\)))
8471 (when (c-go-list-backward)
8472 (c-backward-syntactic-ws)
8473 t))
8474 (c-simple-skip-symbol-backward)
8475 (looking-at c-macro-with-semi-re)))))
8476
8477(defun c-macro-vsemi-status-unknown-p () t) ; See cc-defs.el.
8478
8375 8479
8376;; `c-guess-basic-syntax' and the functions that precedes it below 8480;; `c-guess-basic-syntax' and the functions that precedes it below
8377;; implements the main decision tree for determining the syntactic 8481;; implements the main decision tree for determining the syntactic