diff options
Diffstat (limited to 'lisp/progmodes/cc-engine.el')
| -rw-r--r-- | lisp/progmodes/cc-engine.el | 182 |
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 | ||
| 1150 | Note that this function might do hidden buffer changes. See the | 1155 | Note that this function might do hidden buffer changes. See the |
| 1151 | comment at the start of cc-engine.el for more info." | 1156 | comment 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 |