summaryrefslogtreecommitdiff
path: root/lisp/progmodes/cc-langs.el
diff options
context:
space:
mode:
authorAlan Mackenzie <acm@muc.de>2016-09-11 21:09:08 +0000
committerAlan Mackenzie <acm@muc.de>2016-09-11 21:09:08 +0000
commitc417f08b16cd9e16451a6d3231097eeb4a804f2d (patch)
tree9590af6fa9497372061c4a41106e05066180cd84 /lisp/progmodes/cc-langs.el
parentf95ca1268da211f5c60985d411df43bb5477430b (diff)
downloademacs-c417f08b16cd9e16451a6d3231097eeb4a804f2d.tar.gz
emacs-c417f08b16cd9e16451a6d3231097eeb4a804f2d.tar.bz2
emacs-c417f08b16cd9e16451a6d3231097eeb4a804f2d.zip
Correctly fontify C++ direct initializations with parens inside functions
Or, more clearly, when something looks like a function declaration and it's inside a function, fontify it as a direct initialization. For this purpose, introduce a "brace stack" for each buffer, where an entry on the brace stack states how deeply nested a particular position is inside braces inside a "top level", which includes classes and namespaces. Also introduce a new "context", "top", with which c-font-lock-declarations signals to c-forward-decl-or-cast-1 that point is at the top level. * lisp/progmodes/cc-langs.el (c-get-state-before-change-functions): add c-truncate-bs-cache. (c-flat-decl-block-kwds, c-brace-stack-thing-key, c-brace-stack-no-semi-key) (c-type-decl-operator-prefix-key): new language constants/variables. * lisp/progmodes/cc-engine.el (c-bs-interval, c-bs-cache, c-bs-cache-limit) (c-bs-prev-pos, c-bs-prev-stack): New mostly local variables for the brace stack cache. (c-init-bs-cache, c-truncate-bs-cache, c-truncate-bs-cache, c-brace-stack-at) (c-bs-at-toplevel-p): New functions which manipulate the brace stack (cache). (c-find-decl-prefix-search): Keep track of whether we're at top level. (c-find-decl-spots): New local variable cfd-top-level which records what it says. On calling cfd-fun, pass cfd-top-level as an additional argument. (c-forward-declarator): Add new element DECORATED to the result list. Set it to non-nil when a match for c-type-decl-operator-prefix-key is found. (c-forward-decl-or-cast-1): Handle the newly introduced context "top". Introduce "CASE 9.5", which recognizes direct initializations. * lisp/progmodes/cc-fonts.el (c-font-lock-complex-decl-prepare) (c-font-lock-enum-tail, c-font-lock-cut-off-declarators) (c-font-lock-enclosing-decls, c-simple-decl-matchers, c-basic-matchers-after): Add appropriate `not-top' argument to calls to c-font-lock-declarators. (c-font-lock-declarators): Additional parameter `not-top'. Use not-top to participate in the decision whether to fontify an identifier as a function or a variable. (c-font-lock-declarations): The internal lambda function takes an additional argument `toplev' from c-find-decl-spots, which it uses in determining the "context" of a declaration. Add appropriate `not-top' argument to calls to c-font-lock-declarators. (c-font-lock-objc-methods): Add extra parameter to internal lambda function, like for c-font-lock-declarators. * lisp/progmodes/cc-mode.el (c-basic-common-init): Initialize the brace stack cache.
Diffstat (limited to 'lisp/progmodes/cc-langs.el')
-rw-r--r--lisp/progmodes/cc-langs.el63
1 files changed, 61 insertions, 2 deletions
diff --git a/lisp/progmodes/cc-langs.el b/lisp/progmodes/cc-langs.el
index ae6e6a3071f..3c328489ec1 100644
--- a/lisp/progmodes/cc-langs.el
+++ b/lisp/progmodes/cc-langs.el
@@ -479,10 +479,12 @@ so that all identifiers are recognized as words.")
c-before-change-check-<>-operators
c-depropertize-CPP
c-before-after-change-digit-quote
- c-invalidate-macro-cache)
+ c-invalidate-macro-cache
+ c-truncate-bs-cache)
(c objc) '(c-extend-region-for-CPP
c-depropertize-CPP
- c-invalidate-macro-cache)
+ c-invalidate-macro-cache
+ c-truncate-bs-cache)
;; java 'c-before-change-check-<>-operators
awk 'c-awk-record-region-clear-NL)
(c-lang-defvar c-get-state-before-change-functions
@@ -2588,6 +2590,41 @@ Note that Java specific rules are currently applied to tell this from
(c-lang-defvar c-opt-inexpr-brace-list-key
(c-lang-const c-opt-inexpr-brace-list-key))
+(c-lang-defconst c-flat-decl-block-kwds
+ ;; Keywords that can introduce another declaration level, i.e. where a
+ ;; following "{" isn't a function block or brace list. Note that, for
+ ;; historical reasons, `c-decl-block-key' is NOT constructed from this lang
+ ;; const.
+ t (c--delete-duplicates
+ (append (c-lang-const c-class-decl-kwds)
+ (c-lang-const c-other-block-decl-kwds)
+ (c-lang-const c-inexpr-class-kwds))
+ :test 'string-equal))
+
+(c-lang-defconst c-brace-stack-thing-key
+ ;; Regexp matching any keyword or operator relevant to the brace stack (see
+ ;; `c-update-brace-stack' in cc-engine.el).
+ t (c-make-keywords-re 'appendable
+ (append
+ (c-lang-const c-flat-decl-block-kwds)
+ (if (c-lang-const c-recognize-<>-arglists)
+ '("{" "}" ";" "," ")" ":" "<")
+ '("{" "}" ";" "," ")" ":")))))
+(c-lang-defvar c-brace-stack-thing-key (c-lang-const c-brace-stack-thing-key))
+
+(c-lang-defconst c-brace-stack-no-semi-key
+ ;; Regexp matching any keyword or operator relevant to the brace stack when
+ ;; a semicolon is not relevant (see `c-update-brace-stack' in
+ ;; cc-engine.el).
+ t (c-make-keywords-re 'appendable
+ (append
+ (c-lang-const c-flat-decl-block-kwds)
+ (if (c-lang-const c-recognize-<>-arglists)
+ '("{" "}" "<")
+ '("{" "}")))))
+(c-lang-defvar c-brace-stack-no-semi-key
+ (c-lang-const c-brace-stack-no-semi-key))
+
(c-lang-defconst c-decl-block-key
;; Regexp matching keywords in any construct that contain another
;; declaration level, i.e. that isn't followed by a function block
@@ -3031,6 +3068,28 @@ Identifier syntax is in effect when this is matched \(see
(c-lang-defvar c-type-decl-prefix-key (c-lang-const c-type-decl-prefix-key)
'dont-doc)
+(c-lang-defconst c-type-decl-operator-prefix-key
+ "Regexp matching any declarator operator which isn't a keyword
+that might precede the identifier in a declaration, e.g. the
+\"*\" in \"char *argv\". The end of the first submatch is taken
+as the end of the operator. Identifier syntax is in effect when
+this is matched \(see `c-identifier-syntax-table')."
+ t ;; Default to a regexp that never matches.
+ "\\<\\>"
+ ;; Check that there's no "=" afterwards to avoid matching tokens
+ ;; like "*=".
+ (c objc) (concat "\\(\\*\\)"
+ "\\([^=]\\|$\\)")
+ c++ (concat "\\("
+ "\\.\\.\\."
+ "\\|"
+ "\\*"
+ "\\)"
+ "\\([^=]\\|$\\)")
+ pike "\\(\\*\\)\\([^=]\\|$\\)")
+(c-lang-defvar c-type-decl-operator-prefix-key
+ (c-lang-const c-type-decl-operator-prefix-key))
+
(c-lang-defconst c-type-decl-suffix-key
"Regexp matching the declarator operators that might follow after the
identifier in a declaration, e.g. the \"[\" in \"char argv[]\". This