]> git.eshelyaron.com Git - emacs.git/commitdiff
Don't misfontify "foo ()" inside C++ initialization parentheses as a type
authorAlan Mackenzie <acm@muc.de>
Wed, 13 Dec 2017 20:55:03 +0000 (20:55 +0000)
committerAlan Mackenzie <acm@muc.de>
Wed, 13 Dec 2017 20:55:03 +0000 (20:55 +0000)
Also recognize and handle function names introduced by "extern" inside a
function.

* lisp/progmodes/cc-engine.el (c-forward-decl-or-cast-1): Add a new element to
the result list which is t when our declaration is, or is to be treated as,
being at top level.

* lisp/progmodes/cc-fonts.el (c-get-fontification-context): Detect being
inside a C++ uniform initialization and return (not-decl nil) for this case.
(c-font-lock-declarations): Use the new element 4 of the result of
c-forward-decl-or-cast-1.

* lisp/progmodes/cc-langs.el (c-make-top-level-kwds, c-make-top-level-key):
New lang consts/vars.

lisp/progmodes/cc-engine.el
lisp/progmodes/cc-fonts.el
lisp/progmodes/cc-langs.el

index ab0204cb9610926b2dac24aebee56c3c38706c56..138a0e5da2195d42c4d5ea04f273c9c38f677e2a 100644 (file)
@@ -8167,9 +8167,9 @@ comment at the start of cc-engine.el for more info."
   ;; If a declaration is parsed:
   ;;
   ;;   The point is left at the first token after the first complete
-  ;;   declarator, if there is one.  The return value is a list of 4 elements,
+  ;;   declarator, if there is one.  The return value is a list of 5 elements,
   ;;   where the first is the position of the first token in the declarator.
-  ;;   (See below for the other three.)
+  ;;   (See below for the other four.)
   ;;   Some examples:
   ;;
   ;;    void foo (int a, char *b) stuff ...
@@ -8210,7 +8210,9 @@ comment at the start of cc-engine.el for more info."
   ;;
   ;;   The third element of the return value is non-nil when the declaration
   ;;   parsed might be an expression.  The fourth element is the position of
-  ;;   the start of the type identifier.
+  ;;   the start of the type identifier.  The fifth element is t if either
+  ;;   CONTEXT was 'top, or the declaration is detected to be treated as top
+  ;;   level (e.g. with the keyword "extern").
   ;;
   ;; If a cast is parsed:
   ;;
@@ -8308,6 +8310,9 @@ comment at the start of cc-engine.el for more info."
        ;; Set when the symbol before `preceding-token-end' is known to
        ;; terminate the previous construct, or when we're at point-min.
        at-decl-start
+       ;; Set when we have encountered a keyword (e.g. "extern") which
+       ;; causes the following declaration to be treated as though top-level.
+       make-top
        ;; Save `c-record-type-identifiers' and
        ;; `c-record-ref-identifiers' since ranges are recorded
        ;; speculatively and should be thrown away if it turns out
@@ -8339,7 +8344,9 @@ comment at the start of cc-engine.el for more info."
 
          (cond
          ;; Look for a specifier keyword clause.
-          ((or (looking-at c-prefix-spec-kwds-re)
+          ((or (and (looking-at c-make-top-level-key)
+                    (setq make-top t))
+               (looking-at c-prefix-spec-kwds-re)
                (and (c-major-mode-is 'java-mode)
                 (looking-at "@[A-Za-z0-9]+")))
            (save-match-data
@@ -8609,7 +8616,7 @@ comment at the start of cc-engine.el for more info."
                 ;; construct here in C, since we want to recognize this as a
                 ;; typeless function declaration.
                 (not (and (c-major-mode-is 'c-mode)
-                          (eq context 'top)
+                          (or (eq context 'top) make-top)
                           (eq (char-after) ?\)))))
            (if (eq (char-after) ?\))
                (when (> paren-depth 0)
@@ -8657,7 +8664,7 @@ comment at the start of cc-engine.el for more info."
                                           ;; Recognize a top-level typeless
                                           ;; function declaration in C.
                                           (and (c-major-mode-is 'c-mode)
-                                               (eq context 'top)
+                                               (or (eq context 'top) make-top)
                                                (eq (char-after) ?\))))))))
                          (setq pos (c-up-list-forward (point)))
                          (eq (char-before pos) ?\)))
@@ -8914,6 +8921,7 @@ comment at the start of cc-engine.el for more info."
         (when (and got-identifier
                    (looking-at c-after-suffixed-type-decl-key)
                    (or (eq context 'top)
+                       make-top
                        (and (eq context nil)
                             (match-beginning 1)))
                    (if (and got-parens
@@ -9080,7 +9088,7 @@ comment at the start of cc-engine.el for more info."
         ;; CASE 19
         (or (eq context 'decl)
             (and (c-major-mode-is 'c-mode)
-                 (eq context 'top))))))
+                 (or (eq context 'top) make-top))))))
 
     ;; The point is now after the type decl expression.
 
@@ -9185,7 +9193,8 @@ comment at the start of cc-engine.el for more info."
            (and (or at-type-decl at-typedef)
                 (cons at-type-decl at-typedef))
            maybe-expression
-           type-start))
+           type-start
+           (or (eq context 'top) make-top)))
 
      (t
       ;; False alarm.  Restore the recorded ranges.
index d352e5b08c91db411dfcf86cb34bf4a0522dce8f..7b99c2f54e530d718ee3d470856d4893ac7d68fa 100644 (file)
@@ -1251,6 +1251,17 @@ casts and declarations are fontified.  Used on level 2 and higher."
          ;; Got a cached hit in some other type of arglist.
          (type
           (cons 'arglist t))
+         ;; We're at a C++ uniform initialization.
+         ((and (c-major-mode-is 'c++-mode)
+               (eq (char-before match-pos) ?\()
+               (save-excursion
+                 (goto-char match-pos)
+                 (and
+                  (zerop (c-backward-token-2 2))
+                  (looking-at c-identifier-start)
+                  (c-got-face-at (point)
+                                 '(font-lock-variable-name-face)))))
+          (cons 'not-decl nil))
          ((and not-front-decl
           ;; The point is within the range of a previously
           ;; encountered type decl expression, so the arglist
@@ -1589,7 +1600,8 @@ casts and declarations are fontified.  Used on level 2 and higher."
                    (setq max-type-decl-end (point))))
                (goto-char start-pos)
                (c-font-lock-single-decl limit decl-or-cast match-pos
-                                        context toplev))
+                                        context
+                                        (or toplev (nth 4 decl-or-cast))))
 
               (t t))))
 
index 227b3e16485936c9bb2f914082d0785371781074..869048bee31bce2c075127d05764c84ce072972c 100644 (file)
@@ -2355,6 +2355,16 @@ construct it's part of continues."
   t    nil
   (c c++ objc) '("extern"))
 
+(c-lang-defconst c-make-top-level-kwds
+  "Keywords which make declarations they introduce be handled as top-level."
+  t    nil
+  (c c++ objc) '("extern"))
+
+(c-lang-defconst c-make-top-level-key
+  ;; A regexp which matches any `c-make-top-level-kwds' keyword.
+  t (c-make-keywords-re t (c-lang-const c-make-top-level-kwds)))
+(c-lang-defvar c-make-top-level-key (c-lang-const c-make-top-level-key))
+
 (c-lang-defconst c-type-list-kwds
   "Keywords that may be followed by a comma separated list of type
 identifiers, where each optionally can be prefixed by keywords.  (Can