1 ;;; srecode/cpp.el --- C++ specific handlers for Semantic Recoder
3 ;; Copyright (C) 2007, 2009-2013 Free Software Foundation, Inc.
5 ;; Author: Eric M. Ludlam <eric@siege-engine.com>
6 ;; Jan Moringen <scymtym@users.sourceforge.net>
8 ;; This file is part of GNU Emacs.
10 ;; GNU Emacs is free software: you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation, either version 3 of the License, or
13 ;; (at your option) any later version.
15 ;; GNU Emacs is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
25 ;; Supply some C++ specific dictionary fillers and helpers
30 (require 'srecode
/dictionary
)
31 (require 'srecode
/semantic
)
32 (require 'semantic
/tag
)
37 (defgroup srecode-cpp nil
38 "C++-specific Semantic Recoder settings."
41 (defcustom srecode-cpp-namespaces
43 "List expansion candidates for the :using-namespaces argument.
44 A dictionary entry of the named PREFIX_NAMESPACE with the value
45 NAMESPACE:: is created for each namespace unless the current
46 buffer contains a using NAMESPACE; statement "
48 :type
'(repeat string
))
50 ;;; :c ARGUMENT HANDLING
52 ;; When a :c argument is required, fill the dictionary with
53 ;; information about the current C file.
55 ;; Error if not in a C mode.
58 (defun srecode-semantic-handle-:c
(dict)
59 "Add macros into the dictionary DICT based on the current c file.
61 FILENAME_SYMBOL - filename converted into a C compat symbol.
62 HEADER - Shown section if in a header file."
63 ;; A symbol representing
64 (let ((fsym (file-name-nondirectory (buffer-file-name)))
67 ;; Are we in a header file?
68 (if (string-match "\\.\\(h\\|hh\\|hpp\\|h\\+\\+\\)$" fsym
)
69 (srecode-dictionary-show-section dict
"HEADER")
70 (srecode-dictionary-show-section dict
"NOTHEADER"))
72 ;; Strip out bad characters
73 (setq fsym
(replace-regexp-in-string "[^a-zA-Z0-9_]" "_" fsym
))
74 (srecode-dictionary-set-value dict
"FILENAME_SYMBOL" fsym
)
78 ;;; :cpp ARGUMENT HANDLING
80 ;; When a :cpp argument is required, fill the dictionary with
81 ;; information about the current C++ file.
83 ;; Error if not in a C++ mode.
85 (defun srecode-semantic-handle-:cpp
(dict)
86 "Add macros into the dictionary DICT based on the current c file.
87 Calls `srecode-semantic-handle-:c.
88 Also adds the following:
90 (srecode-semantic-handle-:c dict
)
93 (defun srecode-semantic-handle-:using-namespaces
(dict)
94 "Add macros into the dictionary DICT based on used namespaces.
96 PREFIX_NAMESPACE - for each NAMESPACE in `srecode-cpp-namespaces'."
97 (let ((tags (semantic-find-tags-by-class
98 'using
(semantic-fetch-tags))))
99 (dolist (name srecode-cpp-namespaces
)
100 (let ((variable (format "PREFIX_%s" (upcase name
)))
101 (prefix (format "%s::" name
)))
102 (srecode-dictionary-set-value dict variable prefix
)
104 (when (and (eq (semantic-tag-get-attribute tag
:kind
)
106 (string= (semantic-tag-name tag
) name
))
107 (srecode-dictionary-set-value dict variable
""))))))
110 (define-mode-local-override srecode-semantic-apply-tag-to-dict
111 c-mode
(tag-wrapper dict
)
112 "Apply C and C++ specific features from TAG-WRAPPER into DICT.
113 Calls `srecode-semantic-apply-tag-to-dict-default' first. Adds
114 special behavior for tag of classes include, using and function.
116 This function cannot be split into C and C++ specific variants, as
117 the way the tags are created from the parser does not distinguish
118 either. The side effect is that you could get some C++ tag properties
119 specified in a C file."
121 ;; Use default implementation to fill in the basic properties.
122 (srecode-semantic-apply-tag-to-dict-default tag-wrapper dict
)
124 ;; Pull out the tag for the individual pieces.
125 (let* ((tag (oref tag-wrapper
:prime
))
126 (class (semantic-tag-class tag
)))
128 ;; Add additional information based on the class of the tag.
134 ;; For include tags, we have to discriminate between system-wide
135 ;; and local includes.
136 (if (semantic-tag-include-system-p tag
)
137 (srecode-dictionary-show-section dict
"SYSTEM")
138 (srecode-dictionary-show-section dict
"LOCAL")))
144 ;; Insert the subject (a tag) of the include statement as VALUE
145 ;; entry into the dictionary.
146 (let ((value-tag (semantic-tag-get-attribute tag
:value
))
147 (value-dict (srecode-dictionary-add-section-dictionary
149 (srecode-semantic-apply-tag-to-dict
150 (srecode-semantic-tag (semantic-tag-name value-tag
)
154 ;; Discriminate using statements referring to namespaces and
156 (when (eq (semantic-tag-get-attribute tag
:kind
) 'namespace
)
157 (srecode-dictionary-show-section dict
"NAMESPACE")))
162 ((eq class
'function
)
163 ;; @todo It would be nice to distinguish member functions from
164 ;; free functions and only apply the const and pure modifiers,
165 ;; when they make sense. My best bet would be
166 ;; (semantic-tag-function-parent tag), but it is not there, when
167 ;; the function is defined in the scope of a class.
169 (templates (semantic-tag-get-attribute tag
:template
))
170 (modifiers (semantic-tag-modifiers tag
)))
172 ;; Mark constructors and destructors as such.
173 (when (semantic-tag-function-constructor-p tag
)
174 (srecode-dictionary-show-section dict
"CONSTRUCTOR"))
175 (when (semantic-tag-function-destructor-p tag
)
176 (srecode-dictionary-show-section dict
"DESTRUCTOR"))
178 ;; Add modifiers into the dictionary.
179 (dolist (modifier modifiers
)
180 (let ((modifier-dict (srecode-dictionary-add-section-dictionary
182 (srecode-dictionary-set-value modifier-dict
"NAME" modifier
)))
184 ;; Add templates into child dictionaries.
185 (srecode-c-apply-templates dict templates
)
187 ;; When the function is a member function, it can have
188 ;; additional modifiers.
191 ;; For member functions, constness is called
192 ;; 'methodconst-flag'.
193 (when (semantic-tag-get-attribute tag
:methodconst-flag
)
194 (srecode-dictionary-show-section dict
"CONST"))
196 ;; If the member function is pure virtual, add a dictionary
198 (when (semantic-tag-get-attribute tag
:pure-virtual-flag
)
199 (srecode-dictionary-show-section dict
"PURE")))))
205 ;; For classes, add template parameters.
206 (when (or (semantic-tag-of-type-p tag
"class")
207 (semantic-tag-of-type-p tag
"struct"))
209 ;; Add templates into child dictionaries.
210 (let ((templates (semantic-tag-get-attribute tag
:template
)))
211 (srecode-c-apply-templates dict templates
))))
219 (defun srecode-c-apply-templates (dict templates
)
220 "Add section dictionaries for TEMPLATES to DICT."
222 (let ((templates-dict (srecode-dictionary-add-section-dictionary
224 (dolist (template templates
)
225 (let ((template-dict (srecode-dictionary-add-section-dictionary
226 templates-dict
"ARGS")))
227 (srecode-semantic-apply-tag-to-dict
228 (srecode-semantic-tag (semantic-tag-name template
)
233 (provide 'srecode
/cpp
)
236 ;; generated-autoload-file: "loaddefs.el"
237 ;; generated-autoload-load-name: "srecode/cpp"
240 ;;; srecode/cpp.el ends here