Convert consecutive FSF copyright years to ranges.
[bpt/emacs.git] / lisp / cedet / srecode / cpp.el
CommitLineData
4d902e6f
CY
1;;; srecode/cpp.el --- C++ specific handlers for Semantic Recoder
2
73b0cd50 3;; Copyright (C) 2007, 2009-2011 Free Software Foundation, Inc.
4d902e6f
CY
4
5;; Author: Eric M. Ludlam <eric@siege-engine.com>
6;; Jan Moringen <scymtym@users.sourceforge.net>
7
8;; This file is part of GNU Emacs.
9
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.
14
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.
19
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/>.
22
23;;; Commentary:
24;;
25;; Supply some C++ specific dictionary fillers and helpers
26
27;;; Code:
28
b9749554
EL
29(require 'srecode)
30(require 'srecode/dictionary)
31(require 'srecode/semantic)
32(require 'semantic/tag)
33
34;;; Customization
35;;
36
37(defgroup srecode-cpp nil
38 "C++-specific Semantic Recoder settings."
39 :group 'srecode)
40
41(defcustom srecode-cpp-namespaces
42 '("std" "boost")
43 "List expansion candidates for the :using-namespaces argument.
44A dictionary entry of the named PREFIX_NAMESPACE with the value
45NAMESPACE:: is created for each namespace unless the current
46buffer contains a using NAMESPACE; statement "
47 :group 'srecode-cpp
48 :type '(repeat string))
49
4d902e6f
CY
50;;; :cpp ARGUMENT HANDLING
51;;
52;; When a :cpp argument is required, fill the dictionary with
53;; information about the current C++ file.
54;;
55;; Error if not in a C++ mode.
56
4d902e6f
CY
57;;;###autoload
58(defun srecode-semantic-handle-:cpp (dict)
59 "Add macros into the dictionary DICT based on the current c++ file.
60Adds the following:
61FILENAME_SYMBOL - filename converted into a C compat symbol.
62HEADER - Shown section if in a header file."
63 ;; A symbol representing
64 (let ((fsym (file-name-nondirectory (buffer-file-name)))
65 (case-fold-search t))
66
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"))
71
72 ;; Strip out bad characters
73 (while (string-match "\\.\\| " fsym)
74 (setq fsym (replace-match "_" t t fsym)))
75 (srecode-dictionary-set-value dict "FILENAME_SYMBOL" fsym)
76 )
77 )
78
b9749554
EL
79(defun srecode-semantic-handle-:using-namespaces (dict)
80 "Add macros into the dictionary DICT based on used namespaces.
81Adds the following:
82PREFIX_NAMESPACE - for each NAMESPACE in `srecode-cpp-namespaces'."
83 (let ((tags (semantic-find-tags-by-class
84 'using (semantic-fetch-tags))))
85 (dolist (name srecode-cpp-namespaces)
86 (let ((variable (format "PREFIX_%s" (upcase name)))
87 (prefix (format "%s::" name)))
88 (srecode-dictionary-set-value dict variable prefix)
89 (dolist (tag tags)
90 (when (and (eq (semantic-tag-get-attribute tag :kind)
91 'namespace)
92 (string= (semantic-tag-name tag) name))
93 (srecode-dictionary-set-value dict variable ""))))))
94 )
95
4d902e6f
CY
96(define-mode-local-override srecode-semantic-apply-tag-to-dict
97 c++-mode (tag-wrapper dict)
98 "Apply C++ specific features from TAG-WRAPPER into DICT.
99Calls `srecode-semantic-apply-tag-to-dict-default' first. Adds
100special behavior for tag of classes include, using and function."
101
102 ;; Use default implementation to fill in the basic properties.
103 (srecode-semantic-apply-tag-to-dict-default tag-wrapper dict)
104
105 ;; Pull out the tag for the individual pieces.
106 (let* ((tag (oref tag-wrapper :prime))
107 (class (semantic-tag-class tag)))
108
109 ;; Add additional information based on the class of the tag.
110 (cond
111 ;;
112 ;; INCLUDE
113 ;;
114 ((eq class 'include)
115 ;; For include tags, we have to discriminate between system-wide
116 ;; and local includes.
117 (if (semantic-tag-include-system-p tag)
118 (srecode-dictionary-show-section dict "SYSTEM")
119 (srecode-dictionary-show-section dict "LOCAL")))
120
121 ;;
122 ;; USING
123 ;;
124 ((eq class 'using)
125 ;; Insert the subject (a tag) of the include statement as VALUE
126 ;; entry into the dictionary.
127 (let ((value-tag (semantic-tag-get-attribute tag :value))
128 (value-dict (srecode-dictionary-add-section-dictionary
129 dict "VALUE")))
130 (srecode-semantic-apply-tag-to-dict
131 (srecode-semantic-tag (semantic-tag-name value-tag)
132 :prime value-tag)
133 value-dict))
b9749554 134
4d902e6f
CY
135 ;; Discriminate using statements referring to namespaces and
136 ;; types.
137 (when (eq (semantic-tag-get-attribute tag :kind) 'namespace)
138 (srecode-dictionary-show-section dict "NAMESPACE")))
139
140 ;;
141 ;; FUNCTION
142 ;;
143 ((eq class 'function)
144 ;; @todo It would be nice to distinguish member functions from
145 ;; free functions and only apply the const and pure modifiers,
146 ;; when they make sense. My best bet would be
147 ;; (semantic-tag-function-parent tag), but it is not there, when
148 ;; the function is defined in the scope of a class.
b9749554
EL
149 (let ((member t)
150 (templates (semantic-tag-get-attribute tag :template))
4d902e6f
CY
151 (modifiers (semantic-tag-modifiers tag)))
152
153 ;; Add modifiers into the dictionary
154 (dolist (modifier modifiers)
155 (let ((modifier-dict (srecode-dictionary-add-section-dictionary
156 dict "MODIFIERS")))
157 (srecode-dictionary-set-value modifier-dict "NAME" modifier)))
158
b9749554
EL
159 ;; Add templates into child dictionaries.
160 (srecode-cpp-apply-templates dict templates)
161
4d902e6f
CY
162 ;; When the function is a member function, it can have
163 ;; additional modifiers.
164 (when member
165
166 ;; For member functions, constness is called
167 ;; 'methodconst-flag'.
168 (when (semantic-tag-get-attribute tag :methodconst-flag)
169 (srecode-dictionary-show-section dict "CONST"))
170
171 ;; If the member function is pure virtual, add a dictionary
172 ;; entry.
173 (when (semantic-tag-get-attribute tag :pure-virtual-flag)
174 (srecode-dictionary-show-section dict "PURE"))
b9749554
EL
175 )))
176
177 ;;
178 ;; CLASS
179 ;;
180 ((eq class 'type)
181 ;; For classes, add template parameters.
182 (when (or (semantic-tag-of-type-p tag "class")
183 (semantic-tag-of-type-p tag "struct"))
184
185 ;; Add templates into child dictionaries.
186 (let ((templates (semantic-tag-get-attribute tag :template)))
187 (srecode-cpp-apply-templates dict templates))))
4d902e6f
CY
188 ))
189 )
190
b9749554
EL
191\f
192;;; Helper functions
193;;
194
195(defun srecode-cpp-apply-templates (dict templates)
196 "Add section dictionaries for TEMPLATES to DICT."
197 (when templates
198 (let ((templates-dict (srecode-dictionary-add-section-dictionary
199 dict "TEMPLATES")))
200 (dolist (template templates)
201 (let ((template-dict (srecode-dictionary-add-section-dictionary
202 templates-dict "ARGS")))
203 (srecode-semantic-apply-tag-to-dict
204 (srecode-semantic-tag (semantic-tag-name template)
205 :prime template)
206 template-dict)))))
207 )
208
4d902e6f
CY
209(provide 'srecode/cpp)
210
211;; Local variables:
212;; generated-autoload-file: "loaddefs.el"
4d902e6f
CY
213;; generated-autoload-load-name: "srecode/cpp"
214;; End:
215
216;;; srecode/cpp.el ends here