cpp.el 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. ;;; srecode/cpp.el --- C++ specific handlers for Semantic Recoder
  2. ;; Copyright (C) 2007, 2009-2012 Free Software Foundation, Inc.
  3. ;; Author: Eric M. Ludlam <eric@siege-engine.com>
  4. ;; Jan Moringen <scymtym@users.sourceforge.net>
  5. ;; This file is part of GNU Emacs.
  6. ;; GNU Emacs is free software: you can redistribute it and/or modify
  7. ;; it under the terms of the GNU General Public License as published by
  8. ;; the Free Software Foundation, either version 3 of the License, or
  9. ;; (at your option) any later version.
  10. ;; GNU Emacs is distributed in the hope that it will be useful,
  11. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ;; GNU General Public License for more details.
  14. ;; You should have received a copy of the GNU General Public License
  15. ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
  16. ;;; Commentary:
  17. ;;
  18. ;; Supply some C++ specific dictionary fillers and helpers
  19. ;;; Code:
  20. (require 'srecode)
  21. (require 'srecode/dictionary)
  22. (require 'srecode/semantic)
  23. (require 'semantic/tag)
  24. ;;; Customization
  25. ;;
  26. (defgroup srecode-cpp nil
  27. "C++-specific Semantic Recoder settings."
  28. :group 'srecode)
  29. (defcustom srecode-cpp-namespaces
  30. '("std" "boost")
  31. "List expansion candidates for the :using-namespaces argument.
  32. A dictionary entry of the named PREFIX_NAMESPACE with the value
  33. NAMESPACE:: is created for each namespace unless the current
  34. buffer contains a using NAMESPACE; statement "
  35. :group 'srecode-cpp
  36. :type '(repeat string))
  37. ;;; :cpp ARGUMENT HANDLING
  38. ;;
  39. ;; When a :cpp argument is required, fill the dictionary with
  40. ;; information about the current C++ file.
  41. ;;
  42. ;; Error if not in a C++ mode.
  43. ;;;###autoload
  44. (defun srecode-semantic-handle-:cpp (dict)
  45. "Add macros into the dictionary DICT based on the current c++ file.
  46. Adds the following:
  47. FILENAME_SYMBOL - filename converted into a C compat symbol.
  48. HEADER - Shown section if in a header file."
  49. ;; A symbol representing
  50. (let ((fsym (file-name-nondirectory (buffer-file-name)))
  51. (case-fold-search t))
  52. ;; Are we in a header file?
  53. (if (string-match "\\.\\(h\\|hh\\|hpp\\|h\\+\\+\\)$" fsym)
  54. (srecode-dictionary-show-section dict "HEADER")
  55. (srecode-dictionary-show-section dict "NOTHEADER"))
  56. ;; Strip out bad characters
  57. (while (string-match "\\.\\| " fsym)
  58. (setq fsym (replace-match "_" t t fsym)))
  59. (srecode-dictionary-set-value dict "FILENAME_SYMBOL" fsym)
  60. )
  61. )
  62. (defun srecode-semantic-handle-:using-namespaces (dict)
  63. "Add macros into the dictionary DICT based on used namespaces.
  64. Adds the following:
  65. PREFIX_NAMESPACE - for each NAMESPACE in `srecode-cpp-namespaces'."
  66. (let ((tags (semantic-find-tags-by-class
  67. 'using (semantic-fetch-tags))))
  68. (dolist (name srecode-cpp-namespaces)
  69. (let ((variable (format "PREFIX_%s" (upcase name)))
  70. (prefix (format "%s::" name)))
  71. (srecode-dictionary-set-value dict variable prefix)
  72. (dolist (tag tags)
  73. (when (and (eq (semantic-tag-get-attribute tag :kind)
  74. 'namespace)
  75. (string= (semantic-tag-name tag) name))
  76. (srecode-dictionary-set-value dict variable ""))))))
  77. )
  78. (define-mode-local-override srecode-semantic-apply-tag-to-dict
  79. c++-mode (tag-wrapper dict)
  80. "Apply C++ specific features from TAG-WRAPPER into DICT.
  81. Calls `srecode-semantic-apply-tag-to-dict-default' first. Adds
  82. special behavior for tag of classes include, using and function."
  83. ;; Use default implementation to fill in the basic properties.
  84. (srecode-semantic-apply-tag-to-dict-default tag-wrapper dict)
  85. ;; Pull out the tag for the individual pieces.
  86. (let* ((tag (oref tag-wrapper :prime))
  87. (class (semantic-tag-class tag)))
  88. ;; Add additional information based on the class of the tag.
  89. (cond
  90. ;;
  91. ;; INCLUDE
  92. ;;
  93. ((eq class 'include)
  94. ;; For include tags, we have to discriminate between system-wide
  95. ;; and local includes.
  96. (if (semantic-tag-include-system-p tag)
  97. (srecode-dictionary-show-section dict "SYSTEM")
  98. (srecode-dictionary-show-section dict "LOCAL")))
  99. ;;
  100. ;; USING
  101. ;;
  102. ((eq class 'using)
  103. ;; Insert the subject (a tag) of the include statement as VALUE
  104. ;; entry into the dictionary.
  105. (let ((value-tag (semantic-tag-get-attribute tag :value))
  106. (value-dict (srecode-dictionary-add-section-dictionary
  107. dict "VALUE")))
  108. (srecode-semantic-apply-tag-to-dict
  109. (srecode-semantic-tag (semantic-tag-name value-tag)
  110. :prime value-tag)
  111. value-dict))
  112. ;; Discriminate using statements referring to namespaces and
  113. ;; types.
  114. (when (eq (semantic-tag-get-attribute tag :kind) 'namespace)
  115. (srecode-dictionary-show-section dict "NAMESPACE")))
  116. ;;
  117. ;; FUNCTION
  118. ;;
  119. ((eq class 'function)
  120. ;; @todo It would be nice to distinguish member functions from
  121. ;; free functions and only apply the const and pure modifiers,
  122. ;; when they make sense. My best bet would be
  123. ;; (semantic-tag-function-parent tag), but it is not there, when
  124. ;; the function is defined in the scope of a class.
  125. (let ((member t)
  126. (templates (semantic-tag-get-attribute tag :template))
  127. (modifiers (semantic-tag-modifiers tag)))
  128. ;; Add modifiers into the dictionary
  129. (dolist (modifier modifiers)
  130. (let ((modifier-dict (srecode-dictionary-add-section-dictionary
  131. dict "MODIFIERS")))
  132. (srecode-dictionary-set-value modifier-dict "NAME" modifier)))
  133. ;; Add templates into child dictionaries.
  134. (srecode-cpp-apply-templates dict templates)
  135. ;; When the function is a member function, it can have
  136. ;; additional modifiers.
  137. (when member
  138. ;; For member functions, constness is called
  139. ;; 'methodconst-flag'.
  140. (when (semantic-tag-get-attribute tag :methodconst-flag)
  141. (srecode-dictionary-show-section dict "CONST"))
  142. ;; If the member function is pure virtual, add a dictionary
  143. ;; entry.
  144. (when (semantic-tag-get-attribute tag :pure-virtual-flag)
  145. (srecode-dictionary-show-section dict "PURE"))
  146. )))
  147. ;;
  148. ;; CLASS
  149. ;;
  150. ((eq class 'type)
  151. ;; For classes, add template parameters.
  152. (when (or (semantic-tag-of-type-p tag "class")
  153. (semantic-tag-of-type-p tag "struct"))
  154. ;; Add templates into child dictionaries.
  155. (let ((templates (semantic-tag-get-attribute tag :template)))
  156. (srecode-cpp-apply-templates dict templates))))
  157. ))
  158. )
  159. ;;; Helper functions
  160. ;;
  161. (defun srecode-cpp-apply-templates (dict templates)
  162. "Add section dictionaries for TEMPLATES to DICT."
  163. (when templates
  164. (let ((templates-dict (srecode-dictionary-add-section-dictionary
  165. dict "TEMPLATES")))
  166. (dolist (template templates)
  167. (let ((template-dict (srecode-dictionary-add-section-dictionary
  168. templates-dict "ARGS")))
  169. (srecode-semantic-apply-tag-to-dict
  170. (srecode-semantic-tag (semantic-tag-name template)
  171. :prime template)
  172. template-dict)))))
  173. )
  174. (provide 'srecode/cpp)
  175. ;; Local variables:
  176. ;; generated-autoload-file: "loaddefs.el"
  177. ;; generated-autoload-load-name: "srecode/cpp"
  178. ;; End:
  179. ;;; srecode/cpp.el ends here