aboutsummaryrefslogtreecommitdiffstats
path: root/lisp
diff options
context:
space:
mode:
authorAlan Mackenzie2019-07-21 21:08:03 +0000
committerAlan Mackenzie2019-07-21 21:08:03 +0000
commit5ccaee4bbc184c53b262021361bd216af17e80f5 (patch)
treed9fff44dc875fb76aef0081f8f6021e5efef5b2d /lisp
parent5d4dd552c29279b8a9e6ed269a2dc3afc36f73b9 (diff)
downloademacs-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.el178
-rw-r--r--lisp/progmodes/cc-mode.el4
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