diff options
| author | Alan Mackenzie | 2019-07-21 21:08:03 +0000 |
|---|---|---|
| committer | Alan Mackenzie | 2019-07-21 21:08:03 +0000 |
| commit | 5ccaee4bbc184c53b262021361bd216af17e80f5 (patch) | |
| tree | d9fff44dc875fb76aef0081f8f6021e5efef5b2d /lisp | |
| parent | 5d4dd552c29279b8a9e6ed269a2dc3afc36f73b9 (diff) | |
| download | emacs-5ccaee4bbc184c53b262021361bd216af17e80f5.tar.gz emacs-5ccaee4bbc184c53b262021361bd216af17e80f5.zip | |
Implement C++ Mode attributes. This fixes bug #36650.
* lisp/progmodes/cc-engine.el (c-looking-at-c++-attribute)
(c-enclosing-c++-attribute, c-slow-enclosing-c++-attribute): New macro and
functions.
(c-crosses-statement-barrier-p): Add [ into skip-chars for C++ Mode, and use
it to detect and skip over an attribute whilst scanning forward.
(c-sws-lit-type): Use the new value 'attribute.
(c-invalidate-sws-region-before): Put a save-match-data around this function.
Detect and handle an enclosing attribute at either END or BEG.
(c-invalidate-sws-region-after): Handle C++ attributes.
(c-forward-sws, c-backward-sws): Handle C++ attributes.
* lisp/progmodes/cc-mode.el (c-fl-decl-end): Detect and handle point being
inside a C++ attribute.
Diffstat (limited to 'lisp')
| -rw-r--r-- | lisp/progmodes/cc-engine.el | 178 | ||||
| -rw-r--r-- | lisp/progmodes/cc-mode.el | 4 |
2 files changed, 148 insertions, 34 deletions
diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el index cb88fc3e58d..e7bae0e7b68 100644 --- a/lisp/progmodes/cc-engine.el +++ b/lisp/progmodes/cc-engine.el | |||
| @@ -690,6 +690,21 @@ comment at the start of cc-engine.el for more info." | |||
| 690 | (overlay-put (make-overlay end ol-end) 'face face)))) | 690 | (overlay-put (make-overlay end ol-end) 'face face)))) |
| 691 | 691 | ||
| 692 | 692 | ||
| 693 | (defmacro c-looking-at-c++-attribute () | ||
| 694 | ;; If we're in C++ Mode, and point is at the [[ introducing an attribute, | ||
| 695 | ;; return the position of the end of the attribute, otherwise return nil. | ||
| 696 | ;; The match data are NOT preserved over this macro. | ||
| 697 | `(and | ||
| 698 | (c-major-mode-is 'c++-mode) | ||
| 699 | (looking-at "\\[\\[") | ||
| 700 | (save-excursion | ||
| 701 | (and | ||
| 702 | (c-go-list-forward) | ||
| 703 | (eq (char-before) ?\]) | ||
| 704 | (eq (char-before (1- (point))) ?\]) | ||
| 705 | (point))))) | ||
| 706 | |||
| 707 | |||
| 693 | ;; `c-beginning-of-statement-1' and accompanying stuff. | 708 | ;; `c-beginning-of-statement-1' and accompanying stuff. |
| 694 | 709 | ||
| 695 | ;; KLUDGE ALERT: c-maybe-labelp is used to pass information between | 710 | ;; KLUDGE ALERT: c-maybe-labelp is used to pass information between |
| @@ -1414,9 +1429,15 @@ comment at the start of cc-engine.el for more info." | |||
| 1414 | c-opt-cpp-symbol ; usually "#" | 1429 | c-opt-cpp-symbol ; usually "#" |
| 1415 | (substring c-stmt-delim-chars 1)) ; e.g. ";{}?:" | 1430 | (substring c-stmt-delim-chars 1)) ; e.g. ";{}?:" |
| 1416 | c-stmt-delim-chars)) | 1431 | c-stmt-delim-chars)) |
| 1432 | (skip-chars | ||
| 1433 | (if (c-major-mode-is 'c++-mode) | ||
| 1434 | (concat (substring skip-chars 0 1) ; "^" | ||
| 1435 | "[" ; to catch C++ attributes | ||
| 1436 | (substring skip-chars 1)) ; e.g. "#;{}?:" | ||
| 1437 | skip-chars)) | ||
| 1417 | (non-skip-list | 1438 | (non-skip-list |
| 1418 | (append (substring skip-chars 1) nil)) ; e.g. (?# ?\; ?{ ?} ?? ?:) | 1439 | (append (substring skip-chars 1) nil)) ; e.g. (?# ?\; ?{ ?} ?? ?:) |
| 1419 | lit-range lit-start vsemi-pos) | 1440 | lit-range lit-start vsemi-pos attr-end) |
| 1420 | (save-restriction | 1441 | (save-restriction |
| 1421 | (widen) | 1442 | (widen) |
| 1422 | (save-excursion | 1443 | (save-excursion |
| @@ -1440,6 +1461,11 @@ comment at the start of cc-engine.el for more info." | |||
| 1440 | ;; In a string/comment? | 1461 | ;; In a string/comment? |
| 1441 | ((setq lit-range (c-literal-limits from)) | 1462 | ((setq lit-range (c-literal-limits from)) |
| 1442 | (goto-char (cdr lit-range))) | 1463 | (goto-char (cdr lit-range))) |
| 1464 | ;; Skip over a C++ attribute? | ||
| 1465 | ((eq (char-after) ?\[) | ||
| 1466 | (if (setq attr-end (c-looking-at-c++-attribute)) | ||
| 1467 | (goto-char attr-end) | ||
| 1468 | (forward-char))) | ||
| 1443 | ((eq (char-after) ?:) | 1469 | ((eq (char-after) ?:) |
| 1444 | (forward-char) | 1470 | (forward-char) |
| 1445 | (if (and (eq (char-after) ?:) | 1471 | (if (and (eq (char-after) ?:) |
| @@ -1827,12 +1853,63 @@ comment at the start of cc-engine.el for more info." | |||
| 1827 | (def-edebug-spec c-remove-is-and-in-sws t) | 1853 | (def-edebug-spec c-remove-is-and-in-sws t) |
| 1828 | 1854 | ||
| 1829 | ;; The type of literal position `end' is in a `before-change-functions' | 1855 | ;; The type of literal position `end' is in a `before-change-functions' |
| 1830 | ;; function - one of `c', `c++', `pound', or nil (but NOT `string'). | 1856 | ;; function - one of `c', `c++', `pound', `noise', `attribute' or nil (but NOT |
| 1857 | ;; `string'). | ||
| 1831 | (defvar c-sws-lit-type nil) | 1858 | (defvar c-sws-lit-type nil) |
| 1832 | ;; A cons (START . STOP) of the bounds of the comment or CPP construct | 1859 | ;; A cons (START . STOP) of the bounds of the comment or CPP construct, etc., |
| 1833 | ;; enclosing END, if any, else nil. | 1860 | ;; enclosing END, if any, else nil. |
| 1834 | (defvar c-sws-lit-limits nil) | 1861 | (defvar c-sws-lit-limits nil) |
| 1835 | 1862 | ||
| 1863 | (defun c-enclosing-c++-attribute () | ||
| 1864 | ;; If we're in C++ Mode, and point is within a correctly balanced [[ ... ]] | ||
| 1865 | ;; attribute structure, return a cons of its starting and ending positions. | ||
| 1866 | ;; Otherwise, return nil. We use the c-{in,is}-sws-face text properties for | ||
| 1867 | ;; this determination, this macro being intended only for use in the *-sws-* | ||
| 1868 | ;; functions and macros. The match data are NOT preserved over this macro. | ||
| 1869 | (let (attr-end pos-is-sws) | ||
| 1870 | (and | ||
| 1871 | (c-major-mode-is 'c++-mode) | ||
| 1872 | (> (point) (point-min)) | ||
| 1873 | (setq pos-is-sws | ||
| 1874 | (if (get-text-property (1- (point)) 'c-is-sws) | ||
| 1875 | (1- (point)) | ||
| 1876 | (1- (previous-single-property-change | ||
| 1877 | (point) 'c-is-sws nil (point-min))))) | ||
| 1878 | (save-excursion | ||
| 1879 | (goto-char pos-is-sws) | ||
| 1880 | (setq attr-end (c-looking-at-c++-attribute))) | ||
| 1881 | (> attr-end (point)) | ||
| 1882 | (cons pos-is-sws attr-end)))) | ||
| 1883 | |||
| 1884 | (defun c-slow-enclosing-c++-attribute () | ||
| 1885 | ;; Like `c-enclosing-c++-attribute', but does not depend on the c-i[ns]-sws | ||
| 1886 | ;; properties being set. | ||
| 1887 | (and | ||
| 1888 | (c-major-mode-is 'c++-mode) | ||
| 1889 | (save-excursion | ||
| 1890 | (let ((paren-state (c-parse-state)) | ||
| 1891 | cand) | ||
| 1892 | (while | ||
| 1893 | (progn | ||
| 1894 | (setq cand | ||
| 1895 | (catch 'found-cand | ||
| 1896 | (while (cdr paren-state) | ||
| 1897 | (when (and (numberp (car paren-state)) | ||
| 1898 | (numberp (cadr paren-state)) | ||
| 1899 | (eq (car paren-state) | ||
| 1900 | (1+ (cadr paren-state))) | ||
| 1901 | (eq (char-after (car paren-state)) ?\[) | ||
| 1902 | (eq (char-after (cadr paren-state)) ?\[)) | ||
| 1903 | (throw 'found-cand (cadr paren-state))) | ||
| 1904 | (setq paren-state (cdr paren-state))))) | ||
| 1905 | (and cand | ||
| 1906 | (not | ||
| 1907 | (and (c-go-list-forward cand) | ||
| 1908 | (eq (char-before) ?\]) | ||
| 1909 | (eq (char-before (1- (point))) ?\]))))) | ||
| 1910 | (setq paren-state (cdr paren-state))) | ||
| 1911 | (and cand (cons cand (point))))))) | ||
| 1912 | |||
| 1836 | (defun c-invalidate-sws-region-before (beg end) | 1913 | (defun c-invalidate-sws-region-before (beg end) |
| 1837 | ;; Called from c-before-change. BEG and END are the bounds of the change | 1914 | ;; Called from c-before-change. BEG and END are the bounds of the change |
| 1838 | ;; region, the standard parameters given to all before-change-functions. | 1915 | ;; region, the standard parameters given to all before-change-functions. |
| @@ -1841,31 +1918,41 @@ comment at the start of cc-engine.el for more info." | |||
| 1841 | ;; if so note its bounds in `c-sws-lit-limits' and type in `c-sws-lit-type'. | 1918 | ;; if so note its bounds in `c-sws-lit-limits' and type in `c-sws-lit-type'. |
| 1842 | (setq c-sws-lit-type nil | 1919 | (setq c-sws-lit-type nil |
| 1843 | c-sws-lit-limits nil) | 1920 | c-sws-lit-limits nil) |
| 1844 | (save-excursion | 1921 | (save-match-data |
| 1845 | (goto-char end) | 1922 | (save-excursion |
| 1846 | (let* ((limits (c-literal-limits)) | 1923 | (goto-char end) |
| 1847 | (lit-type (c-literal-type limits))) | 1924 | (let* ((limits (c-literal-limits)) |
| 1848 | (cond | 1925 | (lit-type (c-literal-type limits))) |
| 1849 | ((memq lit-type '(c c++)) | 1926 | (cond |
| 1850 | (setq c-sws-lit-type lit-type | 1927 | ((memq lit-type '(c c++)) |
| 1851 | c-sws-lit-limits limits)) | 1928 | (setq c-sws-lit-type lit-type |
| 1852 | ((c-beginning-of-macro) | 1929 | c-sws-lit-limits limits)) |
| 1853 | (setq c-sws-lit-type 'pound | 1930 | ((c-beginning-of-macro) |
| 1854 | c-sws-lit-limits (cons (point) | 1931 | (setq c-sws-lit-type 'pound |
| 1855 | (progn (c-end-of-macro) (point))))) | 1932 | c-sws-lit-limits (cons (point) |
| 1856 | ((progn (skip-syntax-backward "w_") | 1933 | (progn (c-end-of-macro) (point))))) |
| 1857 | (looking-at c-noise-macro-name-re)) | 1934 | ((eq lit-type 'string)) |
| 1858 | (setq c-sws-lit-type 'noise | 1935 | ((setq c-sws-lit-limits (c-enclosing-c++-attribute)) |
| 1859 | c-sws-lit-limits (cons (match-beginning 1) (match-end 1)))) | 1936 | (setq c-sws-lit-type 'attribute)) |
| 1860 | (t)))) | 1937 | ((progn (skip-syntax-backward "w_") |
| 1861 | (save-excursion | 1938 | (looking-at c-noise-macro-name-re)) |
| 1862 | (goto-char beg) | 1939 | (setq c-sws-lit-type 'noise |
| 1863 | (skip-syntax-backward "w_") | 1940 | c-sws-lit-limits (cons (match-beginning 1) (match-end 1)))) |
| 1864 | (when (looking-at c-noise-macro-name-re) | 1941 | (t)))) |
| 1865 | (setq c-sws-lit-type 'noise) | 1942 | (save-excursion |
| 1866 | (if (consp c-sws-lit-limits) | 1943 | (goto-char beg) |
| 1867 | (setcar c-sws-lit-limits (match-beginning 1)) | 1944 | (let ((attr-limits (c-enclosing-c++-attribute))) |
| 1868 | (setq c-sws-lit-limits (cons (match-beginning 1) (match-end 1))))))) | 1945 | (if attr-limits |
| 1946 | (if (consp c-sws-lit-limits) | ||
| 1947 | (setcar c-sws-lit-limits (car attr-limits)) | ||
| 1948 | (setq c-sws-lit-limits attr-limits)) | ||
| 1949 | (skip-syntax-backward "w_") | ||
| 1950 | (when (looking-at c-noise-macro-name-re) | ||
| 1951 | (setq c-sws-lit-type 'noise) | ||
| 1952 | (if (consp c-sws-lit-limits) | ||
| 1953 | (setcar c-sws-lit-limits (match-beginning 1)) | ||
| 1954 | (setq c-sws-lit-limits (cons (match-beginning 1) | ||
| 1955 | (match-end 1)))))))))) | ||
| 1869 | 1956 | ||
| 1870 | (defun c-invalidate-sws-region-after-del (beg end _old-len) | 1957 | (defun c-invalidate-sws-region-after-del (beg end _old-len) |
| 1871 | ;; Text has been deleted, OLD-LEN characters of it starting from position | 1958 | ;; Text has been deleted, OLD-LEN characters of it starting from position |
| @@ -1940,7 +2027,7 @@ comment at the start of cc-engine.el for more info." | |||
| 1940 | (when (and (eolp) (not (eobp))) | 2027 | (when (and (eolp) (not (eobp))) |
| 1941 | (setq end (1+ (point))))) | 2028 | (setq end (1+ (point))))) |
| 1942 | 2029 | ||
| 1943 | (when (eq c-sws-lit-type 'noise) | 2030 | (when (memq c-sws-lit-type '(noise attribute)) |
| 1944 | (setq beg (car c-sws-lit-limits) | 2031 | (setq beg (car c-sws-lit-limits) |
| 1945 | end (cdr c-sws-lit-limits))) ; This last setting may be redundant. | 2032 | end (cdr c-sws-lit-limits))) ; This last setting may be redundant. |
| 1946 | 2033 | ||
| @@ -1990,6 +2077,8 @@ comment at the start of cc-engine.el for more info." | |||
| 1990 | (when (or (looking-at c-syntactic-ws-start) | 2077 | (when (or (looking-at c-syntactic-ws-start) |
| 1991 | (and c-opt-cpp-prefix | 2078 | (and c-opt-cpp-prefix |
| 1992 | (looking-at c-noise-macro-name-re)) | 2079 | (looking-at c-noise-macro-name-re)) |
| 2080 | (and (c-major-mode-is 'c++-mode) | ||
| 2081 | (looking-at "\\[\\[")) | ||
| 1993 | (looking-at c-doc-line-join-re)) | 2082 | (looking-at c-doc-line-join-re)) |
| 1994 | 2083 | ||
| 1995 | (setq rung-end-pos (min (1+ (point)) (point-max))) | 2084 | (setq rung-end-pos (min (1+ (point)) (point-max))) |
| @@ -2126,6 +2215,10 @@ comment at the start of cc-engine.el for more info." | |||
| 2126 | (goto-char (match-end 1)) | 2215 | (goto-char (match-end 1)) |
| 2127 | (not (eobp))) | 2216 | (not (eobp))) |
| 2128 | 2217 | ||
| 2218 | ((setq next-rung-pos (c-looking-at-c++-attribute)) | ||
| 2219 | (goto-char next-rung-pos) | ||
| 2220 | (not (eobp))) | ||
| 2221 | |||
| 2129 | ((looking-at c-doc-line-join-re) | 2222 | ((looking-at c-doc-line-join-re) |
| 2130 | ;; Skip over a line join in (e.g.) Pike autodoc. | 2223 | ;; Skip over a line join in (e.g.) Pike autodoc. |
| 2131 | (goto-char (match-end 0)) | 2224 | (goto-char (match-end 0)) |
| @@ -2214,8 +2307,7 @@ comment at the start of cc-engine.el for more info." | |||
| 2214 | "c-forward-sws clearing thoroughly at %s for cache separation" | 2307 | "c-forward-sws clearing thoroughly at %s for cache separation" |
| 2215 | (1- last-put-in-sws-pos)) | 2308 | (1- last-put-in-sws-pos)) |
| 2216 | (c-remove-is-and-in-sws (1- last-put-in-sws-pos) | 2309 | (c-remove-is-and-in-sws (1- last-put-in-sws-pos) |
| 2217 | last-put-in-sws-pos)))) | 2310 | last-put-in-sws-pos)))))))) |
| 2218 | )))) | ||
| 2219 | 2311 | ||
| 2220 | (defun c-backward-sws () | 2312 | (defun c-backward-sws () |
| 2221 | ;; Used by `c-backward-syntactic-ws' to implement the unbounded search. | 2313 | ;; Used by `c-backward-syntactic-ws' to implement the unbounded search. |
| @@ -2226,7 +2318,8 @@ comment at the start of cc-engine.el for more info." | |||
| 2226 | ;; part of the simple ws region. | 2318 | ;; part of the simple ws region. |
| 2227 | (rung-pos (point)) next-rung-pos last-put-in-sws-pos | 2319 | (rung-pos (point)) next-rung-pos last-put-in-sws-pos |
| 2228 | rung-is-marked simple-ws-beg cmt-skip-pos | 2320 | rung-is-marked simple-ws-beg cmt-skip-pos |
| 2229 | (doc-line-join-here (concat c-doc-line-join-re "\\="))) | 2321 | (doc-line-join-here (concat c-doc-line-join-re "\\=")) |
| 2322 | attr-end) | ||
| 2230 | 2323 | ||
| 2231 | ;; Skip simple horizontal ws and do a quick check on the preceding | 2324 | ;; Skip simple horizontal ws and do a quick check on the preceding |
| 2232 | ;; character to see if it's anything that can't end syntactic ws, so we can | 2325 | ;; character to see if it's anything that can't end syntactic ws, so we can |
| @@ -2240,6 +2333,14 @@ comment at the start of cc-engine.el for more info." | |||
| 2240 | (memq (char-before) c-doc-line-join-end-ch) ; For speed. | 2333 | (memq (char-before) c-doc-line-join-end-ch) ; For speed. |
| 2241 | (re-search-backward doc-line-join-here | 2334 | (re-search-backward doc-line-join-here |
| 2242 | (c-point 'bopl) t)) | 2335 | (c-point 'bopl) t)) |
| 2336 | (and | ||
| 2337 | (c-major-mode-is 'c++-mode) | ||
| 2338 | (eq (char-before) ?\]) | ||
| 2339 | (eq (char-before (1- (point))) ?\]) | ||
| 2340 | (save-excursion | ||
| 2341 | (and (c-go-list-backward) | ||
| 2342 | (looking-at "\\[\\["))) | ||
| 2343 | (setq attr-end (point))) | ||
| 2243 | (progn | 2344 | (progn |
| 2244 | (backward-char) | 2345 | (backward-char) |
| 2245 | (or (looking-at c-syntactic-ws-end) | 2346 | (or (looking-at c-syntactic-ws-end) |
| @@ -2250,7 +2351,8 @@ comment at the start of cc-engine.el for more info." | |||
| 2250 | ;; Try to find a rung position in the simple ws preceding point, so that | 2351 | ;; Try to find a rung position in the simple ws preceding point, so that |
| 2251 | ;; we can get a cache hit even if the last bit of the simple ws has | 2352 | ;; we can get a cache hit even if the last bit of the simple ws has |
| 2252 | ;; changed recently. | 2353 | ;; changed recently. |
| 2253 | (setq simple-ws-beg (or (match-end 1) ; Noise macro | 2354 | (setq simple-ws-beg (or attr-end ; After attribute. |
| 2355 | (match-end 1) ; Noise macro, etc. | ||
| 2254 | (match-end 0))) ; c-syntactic-ws-end | 2356 | (match-end 0))) ; c-syntactic-ws-end |
| 2255 | (skip-chars-backward " \t\n\r\f\v") | 2357 | (skip-chars-backward " \t\n\r\f\v") |
| 2256 | (if (setq rung-is-marked (text-property-any | 2358 | (if (setq rung-is-marked (text-property-any |
| @@ -2388,6 +2490,16 @@ comment at the start of cc-engine.el for more info." | |||
| 2388 | (goto-char next-rung-pos) | 2490 | (goto-char next-rung-pos) |
| 2389 | t) | 2491 | t) |
| 2390 | 2492 | ||
| 2493 | ((and (c-major-mode-is 'c++-mode) | ||
| 2494 | (eq (char-before) ?\]) | ||
| 2495 | (eq (char-before (1- (point))) ?\]) | ||
| 2496 | (save-excursion | ||
| 2497 | (and (c-go-list-backward) | ||
| 2498 | (setq next-rung-pos (point)) | ||
| 2499 | (looking-at "\\[\\[")))) | ||
| 2500 | (goto-char next-rung-pos) | ||
| 2501 | t) | ||
| 2502 | |||
| 2391 | ((and | 2503 | ((and |
| 2392 | (memq (char-before) c-doc-line-join-end-ch) ; For speed. | 2504 | (memq (char-before) c-doc-line-join-end-ch) ; For speed. |
| 2393 | (re-search-backward doc-line-join-here (c-point 'bopl) t))))) | 2505 | (re-search-backward doc-line-join-here (c-point 'bopl) t))))) |
diff --git a/lisp/progmodes/cc-mode.el b/lisp/progmodes/cc-mode.el index 5ae7e0f09d8..a5e158933ba 100644 --- a/lisp/progmodes/cc-mode.el +++ b/lisp/progmodes/cc-mode.el | |||
| @@ -2158,9 +2158,11 @@ Note that this is a strict tail, so won't match, e.g. \"0x....\".") | |||
| 2158 | ;; count as being in a declarator (on pragmatic grounds). | 2158 | ;; count as being in a declarator (on pragmatic grounds). |
| 2159 | (goto-char pos) | 2159 | (goto-char pos) |
| 2160 | (let ((lit-start (c-literal-start)) | 2160 | (let ((lit-start (c-literal-start)) |
| 2161 | pos1) | 2161 | enclosing-attribute pos1) |
| 2162 | (unless lit-start | 2162 | (unless lit-start |
| 2163 | (c-backward-syntactic-ws) | 2163 | (c-backward-syntactic-ws) |
| 2164 | (when (setq enclosing-attribute (c-slow-enclosing-c++-attribute)) | ||
| 2165 | (goto-char (car enclosing-attribute))) ; Only happens in C++ Mode. | ||
| 2164 | (when (setq pos1 (c-on-identifier)) | 2166 | (when (setq pos1 (c-on-identifier)) |
| 2165 | (goto-char pos1) | 2167 | (goto-char pos1) |
| 2166 | (let ((lim (save-excursion | 2168 | (let ((lim (save-excursion |