aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Mackenzie2016-02-29 21:51:32 +0000
committerAlan Mackenzie2016-02-29 21:51:32 +0000
commit71dc8213b18d4baa5802cf6b7181d81f1f76cbdb (patch)
tree54831c443e29609d57d02ab4916b4d34a921350d
parent93bf7d52841c60ffc10e0c9c789a7987812ce55e (diff)
downloademacs-71dc8213b18d4baa5802cf6b7181d81f1f76cbdb.tar.gz
emacs-71dc8213b18d4baa5802cf6b7181d81f1f76cbdb.zip
Handle "noise" macros and compiler directives.
* lisp/progmodes/cc-langs.el (c-symbol-char-key): New language variable. * lisp/progmodes/cc-vars.el (c-noise-macro-names) (c-noise-macro-with-parens-names): New customizable variables. (c-noise-macro-name-re, c-noise-macro-with-parens-name-re): New variables. (c-make-noise-macro-regexps): New function. * lisp/progmodes/cc-engine.el (c-forward-sws, c-backward-sws): Adapt to treat members of c-noise-macro-names as whitespace. (c-forward-noise-clause): New function. (c-forward-keyword-prefixed-id, c-forward-type, c-forward-declarator) (c-forward-decl-or-cast-1, c-backward-over-enum-header) (c-guess-basic-syntax CASE 5A.3, CASE 5A.5, CASE 9A): Handle "noise clauses" in parallel with, e.g., "hangon key clauses". * lisp/progmodes/cc-fonts.el (c-complex-decl-matchers): Handle "noise clauses" in parallel with "prefix-spec keywords". * lisp/progmodes/cc-mode.el (c-mode, c++-mode, objc-mode): call c-make-noise-macro-regexps to initialize the internal variables. * doc/misc/cc-mode.texi ("Noise Macros"): New section documenting the new facilities.
-rw-r--r--doc/misc/cc-mode.texi68
-rw-r--r--lisp/progmodes/cc-engine.el190
-rw-r--r--lisp/progmodes/cc-fonts.el16
-rw-r--r--lisp/progmodes/cc-langs.el5
-rw-r--r--lisp/progmodes/cc-mode.el3
-rw-r--r--lisp/progmodes/cc-vars.el43
6 files changed, 260 insertions, 65 deletions
diff --git a/doc/misc/cc-mode.texi b/doc/misc/cc-mode.texi
index bc8d24fd992..cdc659ab358 100644
--- a/doc/misc/cc-mode.texi
+++ b/doc/misc/cc-mode.texi
@@ -338,14 +338,15 @@ Line-Up Functions
338* Comment Line-Up:: 338* Comment Line-Up::
339* Misc Line-Up:: 339* Misc Line-Up::
340 340
341
341Customizing Macros 342Customizing Macros
342 343
343* Macro Backslashes:: 344* Macro Backslashes::
344* Macros with ;:: 345* Macros with ;::
346* Noise Macros::
345 347
346@end detailmenu 348@end detailmenu
347@end menu 349@end menu
348
349@comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 350@comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
350@node Introduction, Overview, Top, Top 351@node Introduction, Overview, Top, Top
351@comment node-name, next, previous, up 352@comment node-name, next, previous, up
@@ -6639,15 +6640,18 @@ Because a macro can expand into anything at all, near where one is
6639invoked @ccmode{} can only indent and fontify code heuristically. 6640invoked @ccmode{} can only indent and fontify code heuristically.
6640Sometimes it gets it wrong. Usually you should try to design your 6641Sometimes it gets it wrong. Usually you should try to design your
6641macros so that they ''look like ordinary code'' when you invoke them. 6642macros so that they ''look like ordinary code'' when you invoke them.
6642However, one situation is so common that @ccmode{} handles it 6643However, two situations are so common that @ccmode{} handles them
6643specially: that is when certain macros needn't (or mustn't) be 6644specially: that is when certain macros needn't (or mustn't) be
6644followed by a @samp{;}. You need to configure @ccmode{} to handle 6645followed by a @samp{;}, and when certain macros (or compiler
6645these macros properly, see @ref{Macros with ;}. 6646directives) expand to nothing. You need to configure @ccmode{} to
6647handle these macros properly, see @ref{Macros with ;} and @ref{Noise
6648Macros}.
6646 6649
6647@comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 6650@comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
6648@menu 6651@menu
6649* Macro Backslashes:: 6652* Macro Backslashes::
6650* Macros with ;:: 6653* Macros with ;::
6654* Noise Macros::
6651@end menu 6655@end menu
6652 6656
6653@comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 6657@comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
@@ -6699,7 +6703,7 @@ get aligned only when you explicitly invoke the command
6699@end defopt 6703@end defopt
6700 6704
6701@comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 6705@comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
6702@node Macros with ;, , Macro Backslashes, Custom Macros 6706@node Macros with ;, Noise Macros, Macro Backslashes, Custom Macros
6703@comment node-name, next, previous, up 6707@comment node-name, next, previous, up
6704@section Macros with semicolons 6708@section Macros with semicolons
6705@cindex macros with semicolons 6709@cindex macros with semicolons
@@ -6755,6 +6759,60 @@ initialization code.
6755@end defun 6759@end defun
6756 6760
6757@comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 6761@comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
6762@node Noise Macros, , Macros with ;, Custom Macros
6763@comment node-name, next, previous, up
6764@section Noise Macros
6765@cindex noise macros
6766@comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
6767
6768In @ccmode{}, @dfn{noise macros} are macros which expand to nothing,
6769or compiler directives (such as GCC's @code{__attribute__}) which play
6770no part in the syntax of the C (etc.) language. Some noise macros are
6771followed by arguments in parentheses (possibly optionally), others
6772are not.
6773
6774Noise macros can easily confuse @ccmode{}'s analysis of function
6775headers, causing them to be mis-fontified, or even mis-indented. You
6776can prevent this confusion by specifying the identifiers which
6777constitute noise macros.
6778
6779@defopt c-noise-macro-names
6780@vindex noise-macro-names (c-)
6781This variable is a list of names of noise macros which never have
6782parenthesized arguments. Each element is a string, and must be a
6783valid identifier. An element in @code{c-noise-macro-names} must not
6784also be in @code{c-noise-macro-with-parens-names}. Such an element is
6785treated as whitespace by @ccmode{}.
6786@end defopt
6787
6788@defopt c-noise-macro-with-parens-names
6789@vindex noise-macro-with-parens-names (c-)
6790This variable is a list of names of noise macros which optionally have
6791arguments in parentheses. Each element of the list is a string, and
6792must be a valid identifier. An element in
6793@code{c-noise-macro-with-parens-names} must not also be in
6794@code{c-noise-macro-names}. For performance reasons, such an element,
6795together with the optional parenthesized arguments, is specially
6796handled, but it is only handled when used in declaration
6797contexts@footnote{If this restriction causes your project
6798difficulties, please get in touch with @email{bug-cc-mode@@gnu.org}.}.
6799
6800The two compiler directives @code{__attribute__} and @code{__declspec}
6801have traditionally been handled specially in @ccmode{}; for example
6802they are fontified with font-lock-keyword-face. You don't need to
6803include these directives in @code{c-noise-macro-with-parens-names},
6804but doing so is OK.
6805@end defopt
6806
6807@defun c-make-noise-macro-regexps
6808@findex make-noise-macro-regexps (c-)
6809Call this (non-interactive) function, which sets internal variables,
6810after changing the value of @code{c-noise-macro-names} or
6811@code{c-noise-macro-with-parens-names} (e.g. in a hook (@pxref{CC
6812Hooks})). This function is called by @ccmode{}'s initialization code.
6813@end defun
6814
6815@comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
6758@node Odds and Ends, Sample Init File, Custom Macros, Top 6816@node Odds and Ends, Sample Init File, Custom Macros, Top
6759@comment node-name, next, previous, up 6817@comment node-name, next, previous, up
6760@chapter Odds and Ends 6818@chapter Odds and Ends
diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el
index f5aa4df7c2b..66b5369bbba 100644
--- a/lisp/progmodes/cc-engine.el
+++ b/lisp/progmodes/cc-engine.el
@@ -1543,7 +1543,7 @@ comment at the start of cc-engine.el for more info."
1543;; two newlines with horizontal whitespace between them. 1543;; two newlines with horizontal whitespace between them.
1544;; 1544;;
1545;; The reason to include the first following char is to cope with 1545;; The reason to include the first following char is to cope with
1546;; "rung positions" that doesn't have any ordinary whitespace. If 1546;; "rung positions" that don't have any ordinary whitespace. If
1547;; `c-is-sws' is put on a token character it does not have 1547;; `c-is-sws' is put on a token character it does not have
1548;; `c-in-sws' set simultaneously. That's the only case when that 1548;; `c-in-sws' set simultaneously. That's the only case when that
1549;; can occur, and the reason for not extending the `c-in-sws' 1549;; can occur, and the reason for not extending the `c-in-sws'
@@ -1714,7 +1714,9 @@ comment at the start of cc-engine.el for more info."
1714 ;; if it's anything that can't start syntactic ws, so we can bail out 1714 ;; if it's anything that can't start syntactic ws, so we can bail out
1715 ;; early in the majority of cases when there just are a few ws chars. 1715 ;; early in the majority of cases when there just are a few ws chars.
1716 (skip-chars-forward " \t\n\r\f\v") 1716 (skip-chars-forward " \t\n\r\f\v")
1717 (when (looking-at c-syntactic-ws-start) 1717 (when (or (looking-at c-syntactic-ws-start)
1718 (and c-opt-cpp-prefix
1719 (looking-at c-noise-macro-name-re)))
1718 1720
1719 (setq rung-end-pos (min (1+ (point)) (point-max))) 1721 (setq rung-end-pos (min (1+ (point)) (point-max)))
1720 (if (setq rung-is-marked (text-property-any rung-pos rung-end-pos 1722 (if (setq rung-is-marked (text-property-any rung-pos rung-end-pos
@@ -1733,6 +1735,10 @@ comment at the start of cc-engine.el for more info."
1733 (with-silent-modifications 1735 (with-silent-modifications
1734 (while 1736 (while
1735 (progn 1737 (progn
1738 ;; In the following while form, we move over a "ladder" and
1739 ;; following simple WS each time round the loop, appending the WS
1740 ;; onto the ladder, joining adjacent ladders, and terminating when
1741 ;; there is no more WS or we reach EOB.
1736 (while 1742 (while
1737 (when (and rung-is-marked 1743 (when (and rung-is-marked
1738 (get-text-property (point) 'c-in-sws)) 1744 (get-text-property (point) 'c-in-sws))
@@ -1776,6 +1782,7 @@ comment at the start of cc-engine.el for more info."
1776 (setq rung-pos (point) 1782 (setq rung-pos (point)
1777 last-put-in-sws-pos rung-pos))) 1783 last-put-in-sws-pos rung-pos)))
1778 1784
1785 ;; Now move over any comments (x)or a CPP construct.
1779 (setq simple-ws-end (point)) 1786 (setq simple-ws-end (point))
1780 (c-forward-comments) 1787 (c-forward-comments)
1781 1788
@@ -1801,6 +1808,13 @@ comment at the start of cc-engine.el for more info."
1801 (forward-line 1) 1808 (forward-line 1)
1802 (setq safe-start t) 1809 (setq safe-start t)
1803 ;; Don't cache at eob in case the buffer is narrowed. 1810 ;; Don't cache at eob in case the buffer is narrowed.
1811 (not (eobp)))
1812
1813 ((and c-opt-cpp-prefix
1814 (looking-at c-noise-macro-name-re))
1815 ;; Skip over a noise macro.
1816 (goto-char (match-end 1))
1817 (setq safe-start t)
1804 (not (eobp))))) 1818 (not (eobp)))))
1805 1819
1806 ;; We've searched over a piece of non-white syntactic ws. See if this 1820 ;; We've searched over a piece of non-white syntactic ws. See if this
@@ -1907,8 +1921,11 @@ comment at the start of cc-engine.el for more info."
1907 (when (and (not (bobp)) 1921 (when (and (not (bobp))
1908 (save-excursion 1922 (save-excursion
1909 (backward-char) 1923 (backward-char)
1910 (looking-at c-syntactic-ws-end))) 1924 (or (looking-at c-syntactic-ws-end)
1911 1925 (and c-opt-cpp-prefix
1926 (looking-at c-symbol-char-key)
1927 (progn (c-beginning-of-current-token)
1928 (looking-at c-noise-macro-name-re))))))
1912 ;; Try to find a rung position in the simple ws preceding point, so that 1929 ;; Try to find a rung position in the simple ws preceding point, so that
1913 ;; we can get a cache hit even if the last bit of the simple ws has 1930 ;; we can get a cache hit even if the last bit of the simple ws has
1914 ;; changed recently. 1931 ;; changed recently.
@@ -1927,6 +1944,9 @@ comment at the start of cc-engine.el for more info."
1927 (with-silent-modifications 1944 (with-silent-modifications
1928 (while 1945 (while
1929 (progn 1946 (progn
1947 ;; Each time round the next while form, we move back over a ladder
1948 ;; and append any simple WS preceding it, if possible joining with
1949 ;; the previous ladder.
1930 (while 1950 (while
1931 (when (and rung-is-marked 1951 (when (and rung-is-marked
1932 (not (bobp)) 1952 (not (bobp))
@@ -2035,6 +2055,15 @@ comment at the start of cc-engine.el for more info."
2035 ;; narrowed out, and we can't risk marking the simple ws 2055 ;; narrowed out, and we can't risk marking the simple ws
2036 ;; at the end of it. 2056 ;; at the end of it.
2037 (goto-char next-rung-pos) 2057 (goto-char next-rung-pos)
2058 t)
2059
2060 ((and c-opt-cpp-prefix
2061 (save-excursion
2062 (and (< (skip-syntax-backward "w_") 0)
2063 (progn (setq next-rung-pos (point))
2064 (looking-at c-noise-macro-name-re)))))
2065 ;; Skipped over a noise macro
2066 (goto-char next-rung-pos)
2038 t))) 2067 t)))
2039 2068
2040 ;; We've searched over a piece of non-white syntactic ws. See if this 2069 ;; We've searched over a piece of non-white syntactic ws. See if this
@@ -5807,8 +5836,10 @@ comment at the start of cc-engine.el for more info."
5807 `(c-forward-type) 5836 `(c-forward-type)
5808 `(c-forward-name))) 5837 `(c-forward-name)))
5809 nil 5838 nil
5810 (and (looking-at c-keywords-regexp) 5839 (cond ((looking-at c-keywords-regexp)
5811 (c-forward-keyword-clause 1)))) 5840 (c-forward-keyword-clause 1))
5841 ((looking-at c-noise-macro-with-parens-name-re)
5842 (c-forward-noise-clause)))))
5812 (when (memq res '(t known found prefix)) 5843 (when (memq res '(t known found prefix))
5813 ,(when (eq type 'ref) 5844 ,(when (eq type 'ref)
5814 `(when c-record-type-identifiers 5845 `(when c-record-type-identifiers
@@ -5830,6 +5861,17 @@ comment at the start of cc-engine.el for more info."
5830 (c-forward-syntactic-ws) 5861 (c-forward-syntactic-ws)
5831 (c-forward-keyword-prefixed-id ,type))))) 5862 (c-forward-keyword-prefixed-id ,type)))))
5832 5863
5864(defun c-forward-noise-clause ()
5865 ;; Point is at a c-noise-macro-with-parens-names macro identifier. Go
5866 ;; forward over this name, any parenthesis expression which follows it, and
5867 ;; any syntactic WS, ending up at the next token. If there is an unbalanced
5868 ;; paren expression, leave point at it. Always Return t.
5869 (c-forward-token-2)
5870 (if (and (eq (char-after) ?\()
5871 (c-go-list-forward))
5872 (c-forward-syntactic-ws))
5873 t)
5874
5833(defun c-forward-keyword-clause (match) 5875(defun c-forward-keyword-clause (match)
5834 ;; Submatch MATCH in the current match data is assumed to surround a 5876 ;; Submatch MATCH in the current match data is assumed to surround a
5835 ;; token. If it's a keyword, move over it and any immediately 5877 ;; token. If it's a keyword, move over it and any immediately
@@ -6460,6 +6502,13 @@ comment at the start of cc-engine.el for more info."
6460 ; "typedef". 6502 ; "typedef".
6461 (goto-char (match-end 1)) 6503 (goto-char (match-end 1))
6462 (c-forward-syntactic-ws) 6504 (c-forward-syntactic-ws)
6505
6506 (while (cond
6507 ((looking-at c-decl-hangon-key)
6508 (c-forward-keyword-clause 1))
6509 ((looking-at c-noise-macro-with-parens-name-re)
6510 (c-forward-noise-clause))))
6511
6463 (setq pos (point)) 6512 (setq pos (point))
6464 6513
6465 (setq name-res (c-forward-name)) 6514 (setq name-res (c-forward-name))
@@ -6852,31 +6901,38 @@ comment at the start of cc-engine.el for more info."
6852 ;; of the while. These are, e.g. "*" in "int *foo" or "(" and 6901 ;; of the while. These are, e.g. "*" in "int *foo" or "(" and
6853 ;; "*" in "int (*foo) (void)" (Note similar code in 6902 ;; "*" in "int (*foo) (void)" (Note similar code in
6854 ;; `c-forward-decl-or-cast-1'.) 6903 ;; `c-forward-decl-or-cast-1'.)
6855 (while (and (looking-at c-type-decl-prefix-key) 6904 (while
6856 (if (and (c-major-mode-is 'c++-mode) 6905 (cond
6857 (match-beginning 3)) 6906 ((looking-at c-decl-hangon-key)
6858 ;; If the third submatch matches in C++ then 6907 (c-forward-keyword-clause 1))
6859 ;; we're looking at an identifier that's a 6908 ((looking-at c-noise-macro-with-parens-name-re)
6860 ;; prefix only if it specifies a member pointer. 6909 (c-forward-noise-clause))
6861 (progn 6910 ((and (looking-at c-type-decl-prefix-key)
6862 (setq id-start (point)) 6911 (if (and (c-major-mode-is 'c++-mode)
6863 (c-forward-name) 6912 (match-beginning 3))
6864 (if (looking-at "\\(::\\)") 6913 ;; If the third submatch matches in C++ then
6865 ;; We only check for a trailing "::" and 6914 ;; we're looking at an identifier that's a
6866 ;; let the "*" that should follow be 6915 ;; prefix only if it specifies a member pointer.
6867 ;; matched in the next round. 6916 (progn
6868 t 6917 (setq id-start (point))
6869 ;; It turned out to be the real identifier, 6918 (c-forward-name)
6870 ;; so flag that and stop. 6919 (if (looking-at "\\(::\\)")
6871 (setq got-identifier t) 6920 ;; We only check for a trailing "::" and
6872 nil)) 6921 ;; let the "*" that should follow be
6873 t)) 6922 ;; matched in the next round.
6874 (if (eq (char-after) ?\() 6923 t
6875 (progn 6924 ;; It turned out to be the real identifier,
6876 (setq paren-depth (1+ paren-depth)) 6925 ;; so flag that and stop.
6877 (forward-char)) 6926 (setq got-identifier t)
6878 (goto-char (match-end 1))) 6927 nil))
6879 (c-forward-syntactic-ws)) 6928 t))
6929 (if (eq (char-after) ?\()
6930 (progn
6931 (setq paren-depth (1+ paren-depth))
6932 (forward-char))
6933 (goto-char (match-end 1)))
6934 (c-forward-syntactic-ws)
6935 t)))
6880 6936
6881 ;; If we haven't passed the identifier already, do it now. 6937 ;; If we haven't passed the identifier already, do it now.
6882 (unless got-identifier 6938 (unless got-identifier
@@ -6901,9 +6957,12 @@ comment at the start of cc-engine.el for more info."
6901 6957
6902 ;; Skip over any trailing bit, such as "__attribute__". 6958 ;; Skip over any trailing bit, such as "__attribute__".
6903 (progn 6959 (progn
6904 (when (looking-at c-decl-hangon-key) 6960 (while (cond
6905 (c-forward-keyword-clause 1)) 6961 ((looking-at c-decl-hangon-key)
6906 (<= (point) limit)) 6962 (c-forward-keyword-clause 1))
6963 ((looking-at c-noise-macro-with-parens-name-re)
6964 (c-forward-noise-clause))))
6965 (<= (point) limit))
6907 6966
6908 ;; Search syntactically to the end of the declarator (";", 6967 ;; Search syntactically to the end of the declarator (";",
6909 ;; ",", a closing paren, eob etc) or to the beginning of an 6968 ;; ",", a closing paren, eob etc) or to the beginning of an
@@ -7082,18 +7141,24 @@ comment at the start of cc-engine.el for more info."
7082 ;; macros like __INLINE__, so we recognize both types and known 7141 ;; macros like __INLINE__, so we recognize both types and known
7083 ;; specifiers after them too. 7142 ;; specifiers after them too.
7084 (while 7143 (while
7085 (let* ((start (point)) kwd-sym kwd-clause-end found-type) 7144 (let* ((start (point)) kwd-sym kwd-clause-end found-type noise-start)
7086 7145
7146 (cond
7087 ;; Look for a specifier keyword clause. 7147 ;; Look for a specifier keyword clause.
7088 (when (or (looking-at c-prefix-spec-kwds-re) ;FIXME!!! includes auto 7148 ((or (looking-at c-prefix-spec-kwds-re)
7089 (and (c-major-mode-is 'java-mode) 7149 (and (c-major-mode-is 'java-mode)
7090 (looking-at "@[A-Za-z0-9]+"))) 7150 (looking-at "@[A-Za-z0-9]+")))
7091 (if (save-match-data (looking-at c-typedef-key)) 7151 (save-match-data
7092 (setq at-typedef t)) 7152 (if (looking-at c-typedef-key)
7153 (setq at-typedef t)))
7093 (setq kwd-sym (c-keyword-sym (match-string 1))) 7154 (setq kwd-sym (c-keyword-sym (match-string 1)))
7094 (save-excursion 7155 (save-excursion
7095 (c-forward-keyword-clause 1) 7156 (c-forward-keyword-clause 1)
7096 (setq kwd-clause-end (point)))) 7157 (setq kwd-clause-end (point))))
7158 ((looking-at c-noise-macro-with-parens-name-re)
7159 (setq noise-start (point))
7160 (c-forward-noise-clause)
7161 (setq kwd-clause-end (point))))
7097 7162
7098 (when (setq found-type (c-forward-type t)) ; brace-block-too 7163 (when (setq found-type (c-forward-type t)) ; brace-block-too
7099 ;; Found a known or possible type or a prefix of a known type. 7164 ;; Found a known or possible type or a prefix of a known type.
@@ -7131,16 +7196,17 @@ comment at the start of cc-engine.el for more info."
7131 backup-at-type-decl nil 7196 backup-at-type-decl nil
7132 backup-maybe-typeless nil)) 7197 backup-maybe-typeless nil))
7133 7198
7134 (if kwd-sym 7199 (if (or kwd-sym noise-start)
7135 (progn 7200 (progn
7136 ;; Handle known specifier keywords and 7201 ;; Handle known specifier keywords and
7137 ;; `c-decl-hangon-kwds' which can occur after known 7202 ;; `c-decl-hangon-kwds' which can occur after known
7138 ;; types. 7203 ;; types.
7139 7204
7140 (if (c-keyword-member kwd-sym 'c-decl-hangon-kwds) 7205 (if (or (c-keyword-member kwd-sym 'c-decl-hangon-kwds)
7141 ;; It's a hang-on keyword that can occur anywhere. 7206 noise-start)
7207 ;; It's a hang-on keyword or noise clause that can occur
7208 ;; anywhere.
7142 (progn 7209 (progn
7143 (setq at-decl-or-cast t)
7144 (if at-type 7210 (if at-type
7145 ;; Move the identifier start position if 7211 ;; Move the identifier start position if
7146 ;; we've passed a type. 7212 ;; we've passed a type.
@@ -7192,8 +7258,11 @@ comment at the start of cc-engine.el for more info."
7192 ;; If a known type was found, we still need to skip over any 7258 ;; If a known type was found, we still need to skip over any
7193 ;; hangon keyword clauses after it. Otherwise it has already 7259 ;; hangon keyword clauses after it. Otherwise it has already
7194 ;; been done in the loop above. 7260 ;; been done in the loop above.
7195 (while (looking-at c-decl-hangon-key) 7261 (while
7196 (c-forward-keyword-clause 1)) 7262 (cond ((looking-at c-decl-hangon-key)
7263 (c-forward-keyword-clause 1))
7264 ((looking-at c-noise-macro-with-parens-name-re)
7265 (c-forward-noise-clause))))
7197 (setq id-start (point))) 7266 (setq id-start (point)))
7198 7267
7199 ((eq at-type 'prefix) 7268 ((eq at-type 'prefix)
@@ -8960,6 +9029,11 @@ comment at the start of cc-engine.el for more info."
8960 t) 9029 t)
8961 ((looking-at c-after-brace-list-key) t) 9030 ((looking-at c-after-brace-list-key) t)
8962 ((looking-at c-brace-list-key) nil) 9031 ((looking-at c-brace-list-key) nil)
9032 ((eq (char-after) ?\()
9033 (and (eq (c-backward-token-2) 0)
9034 (or (looking-at c-decl-hangon-key)
9035 (looking-at c-noise-macro-with-parens-name-re))))
9036
8963 ((and c-recognize-<>-arglists 9037 ((and c-recognize-<>-arglists
8964 (eq (char-after) ?<) 9038 (eq (char-after) ?<)
8965 (looking-at "\\s(")) 9039 (looking-at "\\s("))
@@ -10220,9 +10294,11 @@ comment at the start of cc-engine.el for more info."
10220 ;; CASE 5A.3: brace list open 10294 ;; CASE 5A.3: brace list open
10221 ((save-excursion 10295 ((save-excursion
10222 (c-beginning-of-decl-1 lim) 10296 (c-beginning-of-decl-1 lim)
10223 (while (looking-at c-specifier-key) 10297 (while (cond
10224 (goto-char (match-end 1)) 10298 ((looking-at c-specifier-key)
10225 (c-forward-syntactic-ws indent-point)) 10299 (c-forward-keyword-clause 1))
10300 ((looking-at c-noise-macro-with-parens-name-re)
10301 (c-forward-noise-clause))))
10226 (setq placeholder (c-point 'boi)) 10302 (setq placeholder (c-point 'boi))
10227 (or (consp special-brace-list) 10303 (or (consp special-brace-list)
10228 (and (or (save-excursion 10304 (and (or (save-excursion
@@ -10274,9 +10350,11 @@ comment at the start of cc-engine.el for more info."
10274 (t 10350 (t
10275 (save-excursion 10351 (save-excursion
10276 (c-beginning-of-decl-1 lim) 10352 (c-beginning-of-decl-1 lim)
10277 (while (looking-at c-specifier-key) 10353 (while (cond
10278 (goto-char (match-end 1)) 10354 ((looking-at c-specifier-key)
10279 (c-forward-syntactic-ws indent-point)) 10355 (c-forward-keyword-clause 1))
10356 ((looking-at c-noise-macro-with-parens-name-re)
10357 (c-forward-noise-clause))))
10280 (c-add-syntax 'defun-open (c-point 'boi)) 10358 (c-add-syntax 'defun-open (c-point 'boi))
10281 ;; Bogus to use bol here, but it's the legacy. (Resolved, 10359 ;; Bogus to use bol here, but it's the legacy. (Resolved,
10282 ;; 2007-11-09) 10360 ;; 2007-11-09)
@@ -10907,9 +10985,11 @@ comment at the start of cc-engine.el for more info."
10907 (c-beginning-of-statement-1 10985 (c-beginning-of-statement-1
10908 (c-safe-position (1- containing-sexp) paren-state)) 10986 (c-safe-position (1- containing-sexp) paren-state))
10909 (c-forward-token-2 0) 10987 (c-forward-token-2 0)
10910 (while (looking-at c-specifier-key) 10988 (while (cond
10911 (goto-char (match-end 1)) 10989 ((looking-at c-specifier-key)
10912 (c-forward-syntactic-ws)) 10990 (c-forward-keyword-clause 1))
10991 ((looking-at c-noise-macro-with-parens-name-re)
10992 (c-forward-noise-clause))))
10913 (c-add-syntax 'brace-list-open (c-point 'boi)))) 10993 (c-add-syntax 'brace-list-open (c-point 'boi))))
10914 10994
10915 ;; CASE 9B: brace-list-close brace 10995 ;; CASE 9B: brace-list-close brace
diff --git a/lisp/progmodes/cc-fonts.el b/lisp/progmodes/cc-fonts.el
index 3cc537bba3d..a7097b98c9d 100644
--- a/lisp/progmodes/cc-fonts.el
+++ b/lisp/progmodes/cc-fonts.el
@@ -1698,10 +1698,16 @@ on level 2 only and so aren't combined with `c-complex-decl-matchers'."
1698 (unless (c-skip-comments-and-strings limit) 1698 (unless (c-skip-comments-and-strings limit)
1699 (c-forward-syntactic-ws) 1699 (c-forward-syntactic-ws)
1700 ;; Handle prefix declaration specifiers. 1700 ;; Handle prefix declaration specifiers.
1701 (when (or (looking-at c-prefix-spec-kwds-re) 1701 (while
1702 (and (c-major-mode-is 'java-mode) 1702 (or
1703 (looking-at "@[A-Za-z0-9]+"))) 1703 (when (or (looking-at c-prefix-spec-kwds-re)
1704 (c-forward-keyword-clause 1)) 1704 (and (c-major-mode-is 'java-mode)
1705 (looking-at "@[A-Za-z0-9]+")))
1706 (c-forward-keyword-clause 1)
1707 t)
1708 (when (looking-at c-noise-macro-with-parens-name-re)
1709 (c-forward-noise-clause)
1710 t)))
1705 ,(if (c-major-mode-is 'c++-mode) 1711 ,(if (c-major-mode-is 'c++-mode)
1706 `(when (and (c-forward-type) 1712 `(when (and (c-forward-type)
1707 (eq (char-after) ?=)) 1713 (eq (char-after) ?=))
@@ -1827,7 +1833,7 @@ higher."
1827 "\\)\\>" 1833 "\\)\\>"
1828 ;; Disallow various common punctuation chars that can't come 1834 ;; Disallow various common punctuation chars that can't come
1829 ;; before the '{' of the enum list, to avoid searching too far. 1835 ;; before the '{' of the enum list, to avoid searching too far.
1830 "[^][{}();/#=]*" 1836 "[^][{};/#=]*"
1831 "{") 1837 "{")
1832 '((c-font-lock-declarators limit t nil) 1838 '((c-font-lock-declarators limit t nil)
1833 (save-match-data 1839 (save-match-data
diff --git a/lisp/progmodes/cc-langs.el b/lisp/progmodes/cc-langs.el
index 86b6bec78a1..d212482790d 100644
--- a/lisp/progmodes/cc-langs.el
+++ b/lisp/progmodes/cc-langs.el
@@ -619,6 +619,11 @@ This is of the form that fits inside [ ] in a regexp."
619 objc (concat c-alnum "_$@")) 619 objc (concat c-alnum "_$@"))
620(c-lang-defvar c-symbol-chars (c-lang-const c-symbol-chars)) 620(c-lang-defvar c-symbol-chars (c-lang-const c-symbol-chars))
621 621
622(c-lang-defconst c-symbol-char-key
623 "Regexp matching a sequence of at least one identifier character."
624 t (concat "[" (c-lang-const c-symbol-chars) "]+"))
625(c-lang-defvar c-symbol-char-key (c-lang-const c-symbol-char-key))
626
622(c-lang-defconst c-symbol-key 627(c-lang-defconst c-symbol-key
623 "Regexp matching identifiers and keywords (with submatch 0). Assumed 628 "Regexp matching identifiers and keywords (with submatch 0). Assumed
624to match if `c-symbol-start' matches on the same position." 629to match if `c-symbol-start' matches on the same position."
diff --git a/lisp/progmodes/cc-mode.el b/lisp/progmodes/cc-mode.el
index 58aebf8b410..9ebe6f79eb3 100644
--- a/lisp/progmodes/cc-mode.el
+++ b/lisp/progmodes/cc-mode.el
@@ -1493,6 +1493,7 @@ Key bindings:
1493 abbrev-mode t) 1493 abbrev-mode t)
1494 (use-local-map c-mode-map) 1494 (use-local-map c-mode-map)
1495 (c-init-language-vars-for 'c-mode) 1495 (c-init-language-vars-for 'c-mode)
1496 (c-make-noise-macro-regexps)
1496 (c-make-macro-with-semi-re) ; matches macro names whose expansion ends with ; 1497 (c-make-macro-with-semi-re) ; matches macro names whose expansion ends with ;
1497 (c-common-init 'c-mode) 1498 (c-common-init 'c-mode)
1498 (easy-menu-add c-c-menu) 1499 (easy-menu-add c-c-menu)
@@ -1548,6 +1549,7 @@ Key bindings:
1548 abbrev-mode t) 1549 abbrev-mode t)
1549 (use-local-map c++-mode-map) 1550 (use-local-map c++-mode-map)
1550 (c-init-language-vars-for 'c++-mode) 1551 (c-init-language-vars-for 'c++-mode)
1552 (c-make-noise-macro-regexps)
1551 (c-make-macro-with-semi-re) ; matches macro names whose expansion ends with ; 1553 (c-make-macro-with-semi-re) ; matches macro names whose expansion ends with ;
1552 (c-common-init 'c++-mode) 1554 (c-common-init 'c++-mode)
1553 (easy-menu-add c-c++-menu) 1555 (easy-menu-add c-c++-menu)
@@ -1601,6 +1603,7 @@ Key bindings:
1601 abbrev-mode t) 1603 abbrev-mode t)
1602 (use-local-map objc-mode-map) 1604 (use-local-map objc-mode-map)
1603 (c-init-language-vars-for 'objc-mode) 1605 (c-init-language-vars-for 'objc-mode)
1606 (c-make-noise-macro-regexps)
1604 (c-make-macro-with-semi-re) ; matches macro names whose expansion ends with ; 1607 (c-make-macro-with-semi-re) ; matches macro names whose expansion ends with ;
1605 (c-common-init 'objc-mode) 1608 (c-common-init 'objc-mode)
1606 (easy-menu-add c-objc-menu) 1609 (easy-menu-add c-objc-menu)
diff --git a/lisp/progmodes/cc-vars.el b/lisp/progmodes/cc-vars.el
index 8cee733ec8e..a6957185a2b 100644
--- a/lisp/progmodes/cc-vars.el
+++ b/lisp/progmodes/cc-vars.el
@@ -1619,6 +1619,49 @@ names)."))
1619 :type 'c-extra-types-widget 1619 :type 'c-extra-types-widget
1620 :group 'c) 1620 :group 'c)
1621 1621
1622(defvar c-noise-macro-with-parens-name-re nil)
1623(defvar c-noise-macro-name-re nil)
1624
1625(defcustom c-noise-macro-names nil
1626 "A list of names of macros which expand to nothing, or compiler extensions
1627like \"????\" which are syntactic noise. Such a macro/extension is complete in
1628itself, never having parentheses. All these names must be syntactically valid
1629identifiers.
1630
1631If you change this variable's value, call the function
1632`c-make-noise-macro-regexps' to set the necessary internal variables (or do
1633this implicitly by reinitialising C/C++/Objc Mode on any buffer)."
1634 :type '(repeat :tag "List of names" string)
1635 :group 'c)
1636
1637(defcustom c-noise-macro-with-parens-names nil
1638 "A list of names of macros \(or compiler extensions like \"__attribute__\")
1639which optionally have arguments in parentheses, and which expand to nothing.
1640These are recognized by CC Mode only in declarations."
1641 :type '(regexp :tag "List of names (possibly empty)" string)
1642 :group 'c)
1643
1644(defun c-make-noise-macro-regexps ()
1645 ;; Convert `c-noise-macro-names' and `c-noise-macro-with-parens-names' into
1646 ;; `c-noise-macro-name-re' and `c-noise-macro-with-parens-name-re'.
1647 (setq c-noise-macro-with-parens-name-re
1648 (cond ((null c-noise-macro-with-parens-names) "\\<\\>")
1649 ((consp c-noise-macro-with-parens-names)
1650 (concat (regexp-opt c-noise-macro-with-parens-names t)
1651 "\\([^[:alnum:]_$]\\|$\\)"))
1652 ((stringp c-noise-macro-with-parens-names)
1653 (copy-sequence c-noise-macro-with-parens-names))
1654 (t (error "c-make-noise-macro-regexps: \
1655c-noise-macro-with-parens-names is invalid: %s" c-noise-macro-with-parens-names))))
1656 (setq c-noise-macro-name-re
1657 (cond ((null c-noise-macro-names) "\\<\\>")
1658 ((consp c-noise-macro-names)
1659 (concat (regexp-opt c-noise-macro-names t)
1660 "\\([^[:alnum:]_$]\\|$\\)"))
1661 ((stringp c-noise-macro-names)
1662 (copy-sequence c-noise-macro-names))
1663 (t (error "c-make-noise-macro-regexps: \
1664c-noise-macro-names is invalid: %s" c-noise-macro-names)))))
1622 1665
1623;; Non-customizable variables, still part of the interface to CC Mode 1666;; Non-customizable variables, still part of the interface to CC Mode
1624(defvar c-macro-with-semi-re nil 1667(defvar c-macro-with-semi-re nil