summaryrefslogtreecommitdiff
path: root/lisp/cedet/srecode/cpp.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/cedet/srecode/cpp.el')
-rw-r--r--lisp/cedet/srecode/cpp.el149
1 files changed, 149 insertions, 0 deletions
diff --git a/lisp/cedet/srecode/cpp.el b/lisp/cedet/srecode/cpp.el
new file mode 100644
index 00000000000..28613a004ed
--- /dev/null
+++ b/lisp/cedet/srecode/cpp.el
@@ -0,0 +1,149 @@
+;;; srecode/cpp.el --- C++ specific handlers for Semantic Recoder
+
+;; Copyright (C) 2007, 2009 Free Software Foundation, Inc.
+
+;; Author: Eric M. Ludlam <eric@siege-engine.com>
+;; Jan Moringen <scymtym@users.sourceforge.net>
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;
+;; Supply some C++ specific dictionary fillers and helpers
+
+;;; Code:
+
+;;; :cpp ARGUMENT HANDLING
+;;
+;; When a :cpp argument is required, fill the dictionary with
+;; information about the current C++ file.
+;;
+;; Error if not in a C++ mode.
+
+(require 'srecode)
+(require 'srecode/dictionary)
+(require 'srecode/semantic)
+
+;;;###autoload
+(defun srecode-semantic-handle-:cpp (dict)
+ "Add macros into the dictionary DICT based on the current c++ file.
+Adds the following:
+FILENAME_SYMBOL - filename converted into a C compat symbol.
+HEADER - Shown section if in a header file."
+ ;; A symbol representing
+ (let ((fsym (file-name-nondirectory (buffer-file-name)))
+ (case-fold-search t))
+
+ ;; Are we in a header file?
+ (if (string-match "\\.\\(h\\|hh\\|hpp\\|h\\+\\+\\)$" fsym)
+ (srecode-dictionary-show-section dict "HEADER")
+ (srecode-dictionary-show-section dict "NOTHEADER"))
+
+ ;; Strip out bad characters
+ (while (string-match "\\.\\| " fsym)
+ (setq fsym (replace-match "_" t t fsym)))
+ (srecode-dictionary-set-value dict "FILENAME_SYMBOL" fsym)
+ )
+ )
+
+(define-mode-local-override srecode-semantic-apply-tag-to-dict
+ c++-mode (tag-wrapper dict)
+ "Apply C++ specific features from TAG-WRAPPER into DICT.
+Calls `srecode-semantic-apply-tag-to-dict-default' first. Adds
+special behavior for tag of classes include, using and function."
+
+ ;; Use default implementation to fill in the basic properties.
+ (srecode-semantic-apply-tag-to-dict-default tag-wrapper dict)
+
+ ;; Pull out the tag for the individual pieces.
+ (let* ((tag (oref tag-wrapper :prime))
+ (class (semantic-tag-class tag)))
+
+ ;; Add additional information based on the class of the tag.
+ (cond
+ ;;
+ ;; INCLUDE
+ ;;
+ ((eq class 'include)
+ ;; For include tags, we have to discriminate between system-wide
+ ;; and local includes.
+ (if (semantic-tag-include-system-p tag)
+ (srecode-dictionary-show-section dict "SYSTEM")
+ (srecode-dictionary-show-section dict "LOCAL")))
+
+ ;;
+ ;; USING
+ ;;
+ ((eq class 'using)
+ ;; Insert the subject (a tag) of the include statement as VALUE
+ ;; entry into the dictionary.
+ (let ((value-tag (semantic-tag-get-attribute tag :value))
+ (value-dict (srecode-dictionary-add-section-dictionary
+ dict "VALUE")))
+ (srecode-semantic-apply-tag-to-dict
+ (srecode-semantic-tag (semantic-tag-name value-tag)
+ :prime value-tag)
+ value-dict))
+ ;; Discriminate using statements referring to namespaces and
+ ;; types.
+ (when (eq (semantic-tag-get-attribute tag :kind) 'namespace)
+ (srecode-dictionary-show-section dict "NAMESPACE")))
+
+ ;;
+ ;; FUNCTION
+ ;;
+ ((eq class 'function)
+ ;; @todo It would be nice to distinguish member functions from
+ ;; free functions and only apply the const and pure modifiers,
+ ;; when they make sense. My best bet would be
+ ;; (semantic-tag-function-parent tag), but it is not there, when
+ ;; the function is defined in the scope of a class.
+ (let ((member 't)
+ (modifiers (semantic-tag-modifiers tag)))
+
+ ;; Add modifiers into the dictionary
+ (dolist (modifier modifiers)
+ (let ((modifier-dict (srecode-dictionary-add-section-dictionary
+ dict "MODIFIERS")))
+ (srecode-dictionary-set-value modifier-dict "NAME" modifier)))
+
+ ;; When the function is a member function, it can have
+ ;; additional modifiers.
+ (when member
+
+ ;; For member functions, constness is called
+ ;; 'methodconst-flag'.
+ (when (semantic-tag-get-attribute tag :methodconst-flag)
+ (srecode-dictionary-show-section dict "CONST"))
+
+ ;; If the member function is pure virtual, add a dictionary
+ ;; entry.
+ (when (semantic-tag-get-attribute tag :pure-virtual-flag)
+ (srecode-dictionary-show-section dict "PURE"))
+ )
+ ))
+ ))
+ )
+
+(provide 'srecode/cpp)
+
+;; Local variables:
+;; generated-autoload-file: "loaddefs.el"
+;; generated-autoload-feature: srecode/loaddefs
+;; generated-autoload-load-name: "srecode/cpp"
+;; End:
+
+;;; srecode/cpp.el ends here