summaryrefslogtreecommitdiff
path: root/lisp
diff options
context:
space:
mode:
authorDavid Engster <dengste@eml.cc>2013-12-12 22:33:06 +0100
committerDavid Engster <dengste@eml.cc>2013-12-12 22:33:06 +0100
commitb0fe992f3657cf3c852c00d662783354fdab343d (patch)
treeab41cfa8f414e0912e61b2d6f01f728324bf8b5d /lisp
parentf4fe8fdd37f5ddb7aff322e2ff716b16ecb10c32 (diff)
downloademacs-b0fe992f3657cf3c852c00d662783354fdab343d.tar.gz
Merge with CEDET upstream.
* admin/grammars/c.by (expr-binop): Add MOD. (variablearg): Add 'opt-assign'. (variablearg, varnamelist): Add default values so that it can be later expanded into the tag. (opt-stuff-after-symbol): Rename to 'brackets-after-symbol' and remove empty match. (multi-stage-dereference): Adapt to above rename. (unaryexpression): Use 'symbol' instead of 'namespace-symbol', since the latter also leads to an empty match at the end which would make this too greedy. (variablearg-opt-name): Support parsing of function pointers inside an argument list. * semantic/analyze.el (semantic-analyze-find-tag-sequence-default): Always add scope to the local miniscope for each type. Otherwise, structure tags are not analyzed correctly. Also, always search the extended miniscope even when not dealing with types. * semantic/ctxt.el (semantic-get-local-variables-default): Also try to parse local variables for buffers which are currently marked as unparseable. Otherwise, it is often impossible to complete local variables. * semantic/scope.el (semantic-analyze-scoped-types-default): If we cannot find a type in the typecache, also look into the the types we already found. This is necessary since in C++, a 'using namespace' can be dependend on a previous one. (semantic-completable-tags-from-type): When creating the list of completable types, pull in types which are referenced through 'using' statements, and also preserve their filenames. * semanitc/bovine/c.el (semantic/analyze/refs): Require. (semantic-analyze-tag-references): New override. Mainly copied from the default implementation, but if nothing could be found (or just the tag itself), drop all namespaces from the scope and search again. This is necessary for implementations which are defined outside of the namespace and only pull those in through 'using' statements. (semantic-ctxt-scoped-types): Go through all tags around point and search them for using statements. In the case for using statements outside of function scope, append them in the correct order instead of using 'cons'. This is important since using statements may depend on previous ones. (semantic-expand-c-tag-namelist): Do not try to parse struct definitions as default values. The grammar parser seems to return the point positions slightly differently (as a cons instead of a list). Also, set parent for typedefs to 'nil'. It does not really make sense to set a parent class for typedefs, and it can also lead to endless loops when calculating scope. (semantic-c-reconstitute-token): Change handling of function pointers; instead of seeing them as variables, handle them as functions with a 'function-pointer' attribute. Also, correctly deal with function pointers as function arguments. (semantic-c-reconstitute-function-arglist): New function to parse function pointers inside an argument list. (semantic-format-tag-name): Use 'function-pointer' attribute instead of the old 'functionpointer-flag'. (semantic-cpp-lexer): Use new `semantic-lex-spp-paren-or-list'. * semantic/bovine/gcc.el (semantic-gcc-setup): Add 'features.h' to the list of files whose preprocessor symbols are included. This pulls in things like __USE_POSIX and similar. * semantic/format.el (semantic-format-tag-prototype-default): Display default values if available. * semantic/analyze/refs.el (semantic-analyze-refs-impl) (semantic-analyze-refs-proto): Add 'default-value' as ignorable in call to `semantic-tag-similar-p'. * semantic/db-mode.el (semanticdb-semantic-init-hook-fcn): Always set buffer for `semanticdb-current-table'. * semantic/db.el (semanticdb-table::semanticdb-refresh-table): The previous change turned up a bug in this method. Since the current table now correctly has a buffer set, the first clause in the `cond' would be taken, but there was a `save-excursion' missing. * semantic/lex-spp.el (semantic-c-end-of-macro): Declare. (semantic-lex-spp-token-macro-to-macro-stream): Deal with macros which open/close a scope. For this, leave an overlay if we encounter a single open paren and return a semantic-list in the lexer. When this list gets expanded, retrieve the old position from the overlay. See the comments in the function for further details. (semantic-lex-spp-find-closing-macro): New function to find the next macro which closes scope (i.e., has a closing paren). (semantic-lex-spp-replace-or-symbol-or-keyword): Go to end of closing macro if necessary. (semantic-lex-spp-paren-or-list): New lexer to specially deal with parens in macro definitions. * semantic/decorate/mode.el (semantic-decoration-mode): Do not decorate available tags immediately but in an idle timer, since EDE will usually not be activated yet, which will make it impossible to find project includes. * semantic/decorate/include.el (semantic-decoration-on-includes-highlight-default): Remove 'unloaded' from throttle when decorating includes, otherwise all would be loaded. Rename 'table' to 'currenttable' to make things clearer. * ede/linux.el (cl): Require during compile. * ede/linux.el (project-linux-build-directory-default) (project-linux-architecture-default): Add customizable variables. (ede-linux-project): Add additional slots to track Linux-specific information (out-of-tree build directory and selected architecture). (ede-linux--get-build-directory, ede-linux--get-archs) (ede-linux--detect-architecture, ede-linux--get-architecture) (ede-linux--include-path): Added function to detect Linux-specific information. (ede-linux-load): Set new Linux-specific information when creating a project. (ede-expand-filename-impl): Use new and more accurate include information. * semantic/scope.el (semantic-calculate-scope): Return a clone of the scopecache, so that everyone is working with its own (shallow) copy. Otherwise, if one caller is resetting the scope, it would be reset for all others working with the scope cache as well.
Diffstat (limited to 'lisp')
-rw-r--r--lisp/cedet/ChangeLog125
-rw-r--r--lisp/cedet/ede/generic.el1
-rw-r--r--lisp/cedet/ede/linux.el159
-rw-r--r--lisp/cedet/semantic/analyze.el15
-rw-r--r--lisp/cedet/semantic/analyze/refs.el6
-rw-r--r--lisp/cedet/semantic/bovine/c.el230
-rw-r--r--lisp/cedet/semantic/bovine/gcc.el3
-rw-r--r--lisp/cedet/semantic/ctxt.el3
-rw-r--r--lisp/cedet/semantic/db-mode.el4
-rw-r--r--lisp/cedet/semantic/db.el5
-rw-r--r--lisp/cedet/semantic/decorate/include.el7
-rw-r--r--lisp/cedet/semantic/decorate/mode.el8
-rw-r--r--lisp/cedet/semantic/format.el10
-rw-r--r--lisp/cedet/semantic/lex-spp.el154
-rw-r--r--lisp/cedet/semantic/scope.el50
15 files changed, 623 insertions, 157 deletions
diff --git a/lisp/cedet/ChangeLog b/lisp/cedet/ChangeLog
index 1a4a6580007..5b80e79a03e 100644
--- a/lisp/cedet/ChangeLog
+++ b/lisp/cedet/ChangeLog
@@ -1,3 +1,128 @@
+2013-12-12 David Engster <deng@randomsample.de>
+
+ * semantic/analyze.el
+ (semantic-analyze-find-tag-sequence-default): Always add scope to
+ the local miniscope for each type. Otherwise, structure tags are
+ not analyzed correctly. Also, always search the extended
+ miniscope even when not dealing with types.
+
+ * semantic/ctxt.el (semantic-get-local-variables-default): Also
+ try to parse local variables for buffers which are currently
+ marked as unparseable. Otherwise, it is often impossible to
+ complete local variables.
+
+ * semantic/scope.el (semantic-analyze-scoped-types-default): If we
+ cannot find a type in the typecache, also look into the the types
+ we already found. This is necessary since in C++, a 'using
+ namespace' can be dependend on a previous one.
+ (semantic-completable-tags-from-type): When creating the list of
+ completable types, pull in types which are referenced through
+ 'using' statements, and also preserve their filenames.
+
+ * semanitc/bovine/c.el (semantic/analyze/refs): Require.
+ (semantic-analyze-tag-references): New override. Mainly copied
+ from the default implementation, but if nothing could be found (or
+ just the tag itself), drop all namespaces from the scope and
+ search again. This is necessary for implementations which are
+ defined outside of the namespace and only pull those in through
+ 'using' statements.
+ (semantic-ctxt-scoped-types): Go through all tags around point and
+ search them for using statements. In the case for using
+ statements outside of function scope, append them in the correct
+ order instead of using 'cons'. This is important since using
+ statements may depend on previous ones.
+ (semantic-expand-c-tag-namelist): Do not try to parse struct
+ definitions as default values. The grammar parser seems to return
+ the point positions slightly differently (as a cons instead of a
+ list). Also, set parent for typedefs to 'nil'. It does not
+ really make sense to set a parent class for typedefs, and it can
+ also lead to endless loops when calculating scope.
+ (semantic-c-reconstitute-token): Change handling of function
+ pointers; instead of seeing them as variables, handle them as
+ functions with a 'function-pointer' attribute. Also, correctly
+ deal with function pointers as function arguments.
+ (semantic-c-reconstitute-function-arglist): New function to parse
+ function pointers inside an argument list.
+ (semantic-format-tag-name): Use 'function-pointer' attribute
+ instead of the old 'functionpointer-flag'.
+ (semantic-cpp-lexer): Use new `semantic-lex-spp-paren-or-list'.
+
+ * semantic/bovine/gcc.el (semantic-gcc-setup): Add 'features.h' to
+ the list of files whose preprocessor symbols are included. This
+ pulls in things like __USE_POSIX and similar.
+
+ * semantic/format.el (semantic-format-tag-prototype-default):
+ Display default values if available.
+
+ * semantic/analyze/refs.el (semantic-analyze-refs-impl)
+ (semantic-analyze-refs-proto): Add 'default-value' as ignorable in
+ call to `semantic-tag-similar-p'.
+
+ * semantic/db-mode.el (semanticdb-semantic-init-hook-fcn): Always
+ set buffer for `semanticdb-current-table'.
+
+ * semantic/db.el (semanticdb-table::semanticdb-refresh-table): The
+ previous change turned up a bug in this method. Since the current
+ table now correctly has a buffer set, the first clause in the
+ `cond' would be taken, but there was a `save-excursion' missing.
+
+ * semantic/lex-spp.el (semantic-c-end-of-macro): Declare.
+ (semantic-lex-spp-token-macro-to-macro-stream): Deal with macros
+ which open/close a scope. For this, leave an overlay if we
+ encounter a single open paren and return a semantic-list in the
+ lexer. When this list gets expanded, retrieve the old position
+ from the overlay. See the comments in the function for further
+ details.
+ (semantic-lex-spp-find-closing-macro): New function to find the
+ next macro which closes scope (i.e., has a closing paren).
+ (semantic-lex-spp-replace-or-symbol-or-keyword): Go to end of
+ closing macro if necessary.
+ (semantic-lex-spp-paren-or-list): New lexer to specially deal with
+ parens in macro definitions.
+
+ * semantic/decorate/mode.el (semantic-decoration-mode): Do not
+ decorate available tags immediately but in an idle timer, since
+ EDE will usually not be activated yet, which will make it
+ impossible to find project includes.
+
+ * semantic/decorate/include.el
+ (semantic-decoration-on-includes-highlight-default): Remove
+ 'unloaded' from throttle when decorating includes, otherwise all
+ would be loaded. Rename 'table' to 'currenttable' to make things
+ clearer.
+
+ * ede/linux.el (cl): Require during compile.
+
+2013-12-12 LluĂ­s Vilanova <xscript@gmx.net>
+
+ * ede/linux.el (project-linux-build-directory-default)
+ (project-linux-architecture-default): Add customizable variables.
+ (ede-linux-project): Add additional slots to track Linux-specific
+ information (out-of-tree build directory and selected
+ architecture).
+ (ede-linux--get-build-directory, ede-linux--get-archs)
+ (ede-linux--detect-architecture, ede-linux--get-architecture)
+ (ede-linux--include-path): Added function to detect Linux-specific
+ information.
+ (ede-linux-load): Set new Linux-specific information when creating
+ a project.
+ (ede-expand-filename-impl): Use new and more accurate include
+ information.
+
+2013-12-12 Eric Ludlam <zappo@gnu.org>
+
+ * semantic/scope.el (semantic-calculate-scope): Return a clone of
+ the scopecache, so that everyone is working with its own (shallow)
+ copy. Otherwise, if one caller is resetting the scope, it would
+ be reset for all others working with the scope cache as well.
+
+2013-12-12 Alex Ott <alexott@gmail.com>
+
+ * ede/generic.el (project-run-target): Remove incorrect require.
+
+ * semantic/format.el (semantic-format-tag-prototype-default): Use
+ concat only for strings.
+
2013-11-30 Glenn Morris <rgm@gnu.org>
Stop keeping (most) generated cedet grammar files in the repository.
diff --git a/lisp/cedet/ede/generic.el b/lisp/cedet/ede/generic.el
index fedf0ffc7c6..1804107bb79 100644
--- a/lisp/cedet/ede/generic.el
+++ b/lisp/cedet/ede/generic.el
@@ -360,7 +360,6 @@ Argument COMMAND is the command to use for compiling the target."
(defmethod project-run-target ((target ede-generic-target))
"Run the current project derived from TARGET."
- (require 'ede-shell)
(let* ((proj (ede-target-parent target))
(config (ede-generic-get-configuration proj))
(run (concat "./" (oref config :run-command)))
diff --git a/lisp/cedet/ede/linux.el b/lisp/cedet/ede/linux.el
index 728d27e4460..8a2b7c6686d 100644
--- a/lisp/cedet/ede/linux.el
+++ b/lisp/cedet/ede/linux.el
@@ -32,6 +32,8 @@
;; * Add texinfo lookup options.
;; * Add website
+(eval-when-compile (require 'cl))
+
(require 'ede)
(require 'ede/make)
@@ -46,6 +48,19 @@
:group 'ede
:version "24.3")
+(defcustom project-linux-build-directory-default 'ask
+ "Build directory."
+ :group 'project-linux
+ :type '(choice (const :tag "Same as source directory" 'same)
+ (const :tag "Ask the user" 'ask)))
+
+(defcustom project-linux-architecture-default 'ask
+ "Target architecture to assume when not auto-detected."
+ :group 'project-linux
+ :type '(choice (string :tag "Architecture name")
+ (const :tag "Ask the user" 'ask)))
+
+
(defcustom project-linux-compile-target-command (concat ede-make-command " -k -C %s SUBDIRS=%s")
"*Default command used to compile a target."
:group 'project-linux
@@ -109,10 +124,100 @@ DIR is the directory to search from."
(defclass ede-linux-project (ede-project eieio-instance-tracker)
((tracking-symbol :initform 'ede-linux-project-list)
- )
+ (build-directory :initarg :build-directory
+ :type string
+ :documentation "Build directory.")
+ (architecture :initarg :architecture
+ :type string
+ :documentation "Target architecture.")
+ (include-path :initarg :include-path
+ :type list
+ :documentation "Include directories.
+Contains both common and target architecture-specific directories."))
"Project Type for the Linux source code."
:method-invocation-order :depth-first)
+
+(defun ede-linux--get-build-directory (dir)
+ "Detect build directory for sources in DIR.
+If DIR has not been used as a build directory, fall back to
+`project-linux-build-directory-default'."
+ (or
+ ;; detected build on source directory
+ (and (file-exists-p (expand-file-name ".config" dir)) dir)
+ ;; use configuration
+ (case project-linux-build-directory-default
+ (same dir)
+ (ask (read-directory-name "Select Linux' build directory: " dir)))))
+
+
+(defun ede-linux--get-archs (dir)
+ "Returns a list of architecture names found in DIR."
+ (let ((archs-dir (expand-file-name "arch" dir))
+ archs)
+ (when (file-directory-p archs-dir)
+ (mapc (lambda (elem)
+ (when (and
+ (not (string= elem "."))
+ (not (string= elem ".."))
+ (not (string= elem "x86_64")) ; has no separate sources
+ (file-directory-p
+ (expand-file-name elem archs-dir)))
+ (add-to-list 'archs elem t)))
+ (directory-files archs-dir)))
+ archs))
+
+
+(defun ede-linux--detect-architecture (dir)
+ "Try to auto-detect the architecture as configured in DIR.
+DIR is Linux' build directory. If it cannot be auto-detected,
+returns `project-linux-architecture-default'."
+ (let ((archs-dir (expand-file-name "arch" dir))
+ (archs (ede-linux--get-archs dir))
+ arch found)
+ (or (and
+ archs
+ ;; Look for /arch/<arch>/include/generated
+ (progn
+ (while (and archs (not found))
+ (setq arch (car archs))
+ (when (file-directory-p
+ (expand-file-name (concat arch "/include/generated")
+ archs-dir))
+ (setq found arch))
+ (setq archs (cdr archs)))
+ found))
+ project-linux-architecture-default)))
+
+(defun ede-linux--get-architecture (dir bdir)
+ "Try to auto-detect the architecture as configured in BDIR.
+Uses `ede-linux--detect-architecture' for the auto-detection. If
+the result is `ask', let the user choose from architectures found
+in DIR."
+ (let ((arch (ede-linux--detect-architecture bdir)))
+ (case arch
+ (ask
+ (completing-read "Select target architecture: "
+ (ede-linux--get-archs dir)))
+ (t arch))))
+
+
+(defun ede-linux--include-path (dir bdir arch)
+ "Returns a list with include directories.
+Returned directories might not exist, since they are not created
+until Linux is built for the first time."
+ (map 'list
+ (lambda (elem) (format (concat (car elem) "/" (cdr elem)) arch))
+ ;; XXX: taken from the output of "make V=1"
+ (list (cons dir "arch/%s/include")
+ (cons bdir "arch/%s/include/generated")
+ (cons dir "include")
+ (cons bdir "include")
+ (cons dir "arch/%s/include/uapi")
+ (cons bdir "arch/%s/include/generated/uapi")
+ (cons dir "include/uapi")
+ (cons bdir "include/generated/uapi"))))
+
;;;###autoload
(defun ede-linux-load (dir &optional rootproj)
"Return an Linux Project object if there is a match.
@@ -121,15 +226,20 @@ Argument DIR is the directory it is created for.
ROOTPROJ is nil, since there is only one project."
(or (ede-linux-file-existing dir)
;; Doesn't already exist, so let's make one.
- (let ((proj (ede-linux-project
- "Linux"
- :name "Linux"
- :version (ede-linux-version dir)
- :directory (file-name-as-directory dir)
- :file (expand-file-name "scripts/ver_linux"
- dir))))
- (ede-add-project-to-global-list proj))
- ))
+ (let* ((bdir (ede-linux--get-build-directory dir))
+ (arch (ede-linux--get-architecture dir bdir))
+ (include-path (ede-linux--include-path dir bdir arch))
+ (proj (ede-linux-project
+ "Linux"
+ :name "Linux"
+ :version (ede-linux-version dir)
+ :directory (file-name-as-directory dir)
+ :file (expand-file-name "scripts/ver_linux"
+ dir)
+ :build-directory bdir
+ :architecture arch
+ :include-path include-path)))
+ (ede-add-project-to-global-list proj))))
;;;###autoload
(ede-add-project-autoload
@@ -245,18 +355,23 @@ All files need the macros from lisp.h!"
"Within this project PROJ, find the file NAME.
Knows about how the Linux source tree is organized."
(let* ((ext (file-name-extension name))
- (root (ede-project-root proj))
- (dir (ede-project-root-directory root))
- (F (cond
- ((not ext) nil)
- ((string-match "h" ext)
- (or (ede-linux-file-exists-name name dir "")
- (ede-linux-file-exists-name name dir "include"))
- )
- ((string-match "txt" ext)
- (ede-linux-file-exists-name name dir "Documentation"))
- (t nil)))
- )
+ (root (ede-project-root proj))
+ (dir (ede-project-root-directory root))
+ (bdir (oref proj build-directory))
+ (F (cond
+ ((not ext) nil)
+ ((string-match "h" ext)
+ (let ((dirs (oref proj include-path))
+ found)
+ (while (and dirs (not found))
+ (setq found
+ (or (ede-linux-file-exists-name name bdir (car dirs))
+ (ede-linux-file-exists-name name dir (car dirs))))
+ (setq dirs (cdr dirs)))
+ found))
+ ((string-match "txt" ext)
+ (ede-linux-file-exists-name name dir "Documentation"))
+ (t nil))))
(or F (call-next-method))))
(defmethod project-compile-project ((proj ede-linux-project)
diff --git a/lisp/cedet/semantic/analyze.el b/lisp/cedet/semantic/analyze.el
index 000193d4a55..07bf1c7f621 100644
--- a/lisp/cedet/semantic/analyze.el
+++ b/lisp/cedet/semantic/analyze.el
@@ -295,18 +295,10 @@ Optional argument THROWSYM specifies a symbol the throw on non-recoverable error
;; In some cases the found TMP is a type,
;; and we can use it directly.
(cond ((semantic-tag-of-class-p tmp 'type)
- ;; update the miniscope when we need to analyze types directly.
- (when miniscope
- (let ((rawscope
- (apply 'append
- (mapcar 'semantic-tag-type-members
- tagtype))))
- (oset miniscope fullscope rawscope)))
- ;; Now analyze the type to remove metatypes.
(or (semantic-analyze-type tmp miniscope)
tmp))
(t
- (semantic-analyze-tag-type tmp scope))))
+ (semantic-analyze-tag-type tmp miniscope))))
(typefile
(when tmptype
(semantic-tag-file-name tmptype)))
@@ -336,6 +328,11 @@ Optional argument THROWSYM specifies a symbol the throw on non-recoverable error
(semantic--tag-put-property tmp :filename fname))
(setq tag (cons tmp tag))
(setq tagtype (cons tmptype tagtype))
+ (when miniscope
+ (let ((rawscope
+ (apply 'append
+ (mapcar 'semantic-tag-type-members tagtype))))
+ (oset miniscope fullscope rawscope)))
)
(setq s (cdr s)))
diff --git a/lisp/cedet/semantic/analyze/refs.el b/lisp/cedet/semantic/analyze/refs.el
index 93dd710a67d..b06a8a2c5aa 100644
--- a/lisp/cedet/semantic/analyze/refs.el
+++ b/lisp/cedet/semantic/analyze/refs.el
@@ -118,7 +118,8 @@ Optional argument IN-BUFFER indicates that the returned tag should be in an acti
(semantic-tag-similar-p tag aT
:prototype-flag
:parent
- :typemodifiers))
+ :typemodifiers
+ :default-value))
(when in-buffer (save-excursion (semantic-go-to-tag aT aDB)))
(push aT impl))))
allhits)
@@ -141,7 +142,8 @@ Optional argument IN-BUFFER indicates that the returned tag should be in an acti
(semantic-tag-similar-p tag aT
:prototype-flag
:parent
- :typemodifiers))
+ :typemodifiers
+ :default-value))
(when in-buffer (save-excursion (semantic-go-to-tag aT aDB)))
(push aT proto))))
allhits)
diff --git a/lisp/cedet/semantic/bovine/c.el b/lisp/cedet/semantic/bovine/c.el
index 3c991ea8555..f7c6a43b37e 100644
--- a/lisp/cedet/semantic/bovine/c.el
+++ b/lisp/cedet/semantic/bovine/c.el
@@ -27,6 +27,7 @@
(require 'semantic)
(require 'semantic/analyze)
+(require 'semantic/analyze/refs)
(require 'semantic/bovine)
(require 'semantic/bovine/gcc)
(require 'semantic/idle)
@@ -812,7 +813,7 @@ Use semantic-cpp-lexer for parsing text inside a CPP macro."
;; semantic-lex-spp-replace-or-symbol-or-keyword
semantic-lex-symbol-or-keyword
semantic-lex-charquote
- semantic-lex-paren-or-list
+ semantic-lex-spp-paren-or-list
semantic-lex-close-paren
semantic-lex-ignore-comments
semantic-lex-punctuation
@@ -1118,7 +1119,8 @@ is its own toplevel tag. This function will return (cons A B)."
(semantic-tag-new-variable
(car cur) ;name
ty ;type
- (if default
+ (if (and default
+ (listp (cdr default)))
(buffer-substring-no-properties
(car default) (car (cdr default))))
:constant-flag (semantic-tag-variable-constant-p tag)
@@ -1173,11 +1175,7 @@ is its own toplevel tag. This function will return (cons A B)."
(nth 1 (car names)) ; name
"typedef"
(semantic-tag-type-members tag)
- ;; parent is just the name of what
- ;; is passed down as a tag.
- (list
- (semantic-tag-name
- (semantic-tag-type-superclasses tag)))
+ nil
:pointer
(let ((stars (car (car (car names)))))
(if (= stars 0) nil stars))
@@ -1227,6 +1225,45 @@ or \"struct\".")
name
(delete "" ans))))
+(define-mode-local-override semantic-analyze-tag-references c-mode (tag &optional db)
+ "Analyze the references for TAG.
+Returns a class with information about TAG.
+
+Optional argument DB is a database. It will be used to help
+locate TAG.
+
+Use `semantic-analyze-current-tag' to debug this fcn."
+ (when (not (semantic-tag-p tag)) (signal 'wrong-type-argument (list 'semantic-tag-p tag)))
+ (let ((allhits nil)
+ (scope nil)
+ (refs nil))
+ (save-excursion
+ (semantic-go-to-tag tag db)
+ (setq scope (semantic-calculate-scope))
+
+ (setq allhits (semantic--analyze-refs-full-lookup tag scope t))
+
+ (when (or (zerop (semanticdb-find-result-length allhits))
+ (and (= (semanticdb-find-result-length allhits) 1)
+ (eq (car (semanticdb-find-result-nth allhits 0)) tag)))
+ ;; It found nothing or only itself - not good enough. As a
+ ;; last resort, let's remove all namespaces from the scope and
+ ;; search again.
+ (oset scope parents
+ (let ((parents (oref scope parents))
+ newparents)
+ (dolist (cur parents)
+ (unless (string= (semantic-tag-type cur) "namespace")
+ (push cur newparents)))
+ (reverse newparents)))
+ (setq allhits (semantic--analyze-refs-full-lookup tag scope t)))
+
+ (setq refs (semantic-analyze-references (semantic-tag-name tag)
+ :tag tag
+ :tagdb db
+ :scope scope
+ :rawsearchdata allhits)))))
+
(defun semantic-c-reconstitute-token (tokenpart declmods typedecl)
"Reconstitute a token TOKENPART with DECLMODS and TYPEDECL.
This is so we don't have to match the same starting text several times.
@@ -1258,7 +1295,8 @@ Optional argument STAR and REF indicate the number of * and & in the typedef."
(nth 10 tokenpart) ; initializers
)
(not (car (nth 3 tokenpart)))))
- (fcnpointer (string-match "^\\*" (car tokenpart)))
+ (fcnpointer (and (> (length (car tokenpart)) 0)
+ (= (aref (car tokenpart) 0) ?*)))
(fnname (if fcnpointer
(substring (car tokenpart) 1)
(car tokenpart)))
@@ -1266,70 +1304,80 @@ Optional argument STAR and REF indicate the number of * and & in the typedef."
nil
t))
)
- (if fcnpointer
- ;; Function pointers are really variables.
- (semantic-tag-new-variable
- fnname
- typedecl
- nil
- ;; It is a function pointer
- :functionpointer-flag t
- )
- ;; The function
- (semantic-tag-new-function
- fnname
- (or typedecl ;type
- (cond ((car (nth 3 tokenpart) )
- "void") ; Destructors have no return?
- (constructor
- ;; Constructors return an object.
- (semantic-tag-new-type
- ;; name
- (or (car semantic-c-classname)
- (let ((split (semantic-analyze-split-name-c-mode
- (car (nth 2 tokenpart)))))
- (if (stringp split) split
- (car (last split)))))
- ;; type
- (or (cdr semantic-c-classname)
- "class")
- ;; members
- nil
- ;; parents
- nil
- ))
- (t "int")))
- (nth 4 tokenpart) ;arglist
- :constant-flag (if (member "const" declmods) t nil)
- :typemodifiers (delete "const" declmods)
- :parent (car (nth 2 tokenpart))
- :destructor-flag (if (car (nth 3 tokenpart) ) t)
- :constructor-flag (if constructor t)
- :pointer (nth 7 tokenpart)
- :operator-flag operator
- ;; Even though it is "throw" in C++, we use
- ;; `throws' as a common name for things that toss
- ;; exceptions about.
- :throws (nth 5 tokenpart)
- ;; Reentrant is a C++ thingy. Add it here
- :reentrant-flag (if (member "reentrant" (nth 6 tokenpart)) t)
- ;; A function post-const is funky. Try stuff
- :methodconst-flag (if (member "const" (nth 6 tokenpart)) t)
- ;; prototypes are functions w/ no body
- :prototype-flag (if (nth 8 tokenpart) t)
- ;; Pure virtual
- :pure-virtual-flag (if (eq (nth 8 tokenpart) :pure-virtual-flag) t)
- ;; Template specifier.
- :template-specifier (nth 9 tokenpart)
- )))
- )
- ))
+ ;; The function
+ (semantic-tag-new-function
+ fnname
+ (or typedecl ;type
+ (cond ((car (nth 3 tokenpart) )
+ "void") ; Destructors have no return?
+ (constructor
+ ;; Constructors return an object.
+ (semantic-tag-new-type
+ ;; name
+ (or (car semantic-c-classname)
+ (let ((split (semantic-analyze-split-name-c-mode
+ (car (nth 2 tokenpart)))))
+ (if (stringp split) split
+ (car (last split)))))
+ ;; type
+ (or (cdr semantic-c-classname)
+ "class")
+ ;; members
+ nil
+ ;; parents
+ nil
+ ))
+ (t "int")))
+ ;; Argument list can contain things like function pointers
+ (semantic-c-reconstitute-function-arglist (nth 4 tokenpart))
+ :constant-flag (if (member "const" declmods) t nil)
+ :typemodifiers (delete "const" declmods)
+ :parent (car (nth 2 tokenpart))
+ :destructor-flag (if (car (nth 3 tokenpart) ) t)
+ :constructor-flag (if constructor t)
+ :function-pointer fcnpointer
+ :pointer (nth 7 tokenpart)
+ :operator-flag operator
+ ;; Even though it is "throw" in C++, we use
+ ;; `throws' as a common name for things that toss
+ ;; exceptions about.
+ :throws (nth 5 tokenpart)
+ ;; Reentrant is a C++ thingy. Add it here
+ :reentrant-flag (if (member "reentrant" (nth 6 tokenpart)) t)
+ ;; A function post-const is funky. Try stuff
+ :methodconst-flag (if (member "const" (nth 6 tokenpart)) t)
+ ;; prototypes are functions w/ no body
+ :prototype-flag (if (nth 8 tokenpart) t)
+ ;; Pure virtual
+ :pure-virtual-flag (if (eq (nth 8 tokenpart) :pure-virtual-flag) t)
+ ;; Template specifier.
+ :template-specifier (nth 9 tokenpart))))))
(defun semantic-c-reconstitute-template (tag specifier)
"Reconstitute the token TAG with the template SPECIFIER."
(semantic-tag-put-attribute tag :template (or specifier ""))
tag)
+(defun semantic-c-reconstitute-function-arglist (arglist)
+ "Reconstitute the argument list of a function.
+This currently only checks if the function expects a function
+pointer as argument."
+ (let (result)
+ (dolist (arg arglist)
+ ;; Names starting with a '*' denote a function pointer
+ (if (and (> (length (semantic-tag-name arg)) 0)
+ (= (aref (semantic-tag-name arg) 0) ?*))
+ (setq result
+ (append result
+ (list
+ (semantic-tag-new-function
+ (substring (semantic-tag-name arg) 1)
+ (semantic-tag-type arg)
+ (cadr (semantic-tag-attributes arg))
+ :function-pointer t))))
+ (setq result (append result (list arg)))))
+ result))
+
;;; Override methods & Variables
;;
@@ -1338,7 +1386,7 @@ Optional argument STAR and REF indicate the number of * and & in the typedef."
"Convert TAG to a string that is the print name for TAG.
Optional PARENT and COLOR are ignored."
(let ((name (semantic-format-tag-name-default tag parent color))
- (fnptr (semantic-tag-get-attribute tag :functionpointer-flag))
+ (fnptr (semantic-tag-get-attribute tag :function-pointer))
)
(if (not fnptr)
name
@@ -1823,31 +1871,31 @@ DO NOT return the list of tags encompassing point."
(let ((idx 0)
(len (semanticdb-find-result-length tmp)))
(while (< idx len)
- (setq tagreturn (cons (semantic-tag-type (car (semanticdb-find-result-nth tmp idx))) tagreturn))
- (setq idx (1+ idx)))
- )
- ;; Use the encompassed types around point to also look for using statements.
- ;;(setq tagreturn (cons "bread_name" tagreturn))
- (while (cdr tagsaroundpoint) ; don't search the last one
- (setq tmp (semantic-find-tags-by-class 'using (semantic-tag-components (car tagsaroundpoint))))
- (dolist (T tmp)
- (setq tagreturn (cons (semantic-tag-type T) tagreturn))
- )
- (setq tagsaroundpoint (cdr tagsaroundpoint))
- )
- ;; If in a function...
- (when (and (semantic-tag-of-class-p (car tagsaroundpoint) 'function)
- ;; ...search for using statements in the local scope...
- (setq tmp (semantic-find-tags-by-class
- 'using
- (semantic-get-local-variables))))
- ;; ... and add them.
- (setq tagreturn
- (append tagreturn
- (mapcar 'semantic-tag-type tmp))))
+ (setq tagreturn
+ (append tagreturn (list (semantic-tag-type
+ (car (semanticdb-find-result-nth tmp idx))))))
+ (setq idx (1+ idx))))
+ ;; Use the encompassed types around point to also look for using
+ ;; statements. If we deal with types, search inside members; for
+ ;; functions, we have to call `semantic-get-local-variables' to
+ ;; parse inside the function's body.
+ (dolist (cur tagsaroundpoint)
+ (cond
+ ((and (eq (semantic-tag-class cur) 'type)
+ (setq tmp (semantic-find-tags-by-class
+ 'using
+ (semantic-tag-components (car tagsaroundpoint)))))
+ (dolist (T tmp)
+ (setq tagreturn (cons (semantic-tag-type T) tagreturn))))
+ ((and (semantic-tag-of-class-p (car (last tagsaroundpoint)) 'function)
+ (setq tmp (semantic-find-tags-by-class
+ 'using
+ (semantic-get-local-variables))))
+ (setq tagreturn
+ (append tagreturn
+ (mapcar 'semantic-tag-type tmp))))))
;; Return the stuff
- tagreturn
- ))
+ tagreturn))
(define-mode-local-override semantic-ctxt-imported-packages c++-mode (&optional point)
"Return the list of using tag types in scope of POINT."
diff --git a/lisp/cedet/semantic/bovine/gcc.el b/lisp/cedet/semantic/bovine/gcc.el
index 7beb8ff3203..e3c07ca96f4 100644
--- a/lisp/cedet/semantic/bovine/gcc.el
+++ b/lisp/cedet/semantic/bovine/gcc.el
@@ -210,7 +210,8 @@ It should also include other symbols GCC was compiled with.")
(semantic-add-system-include D 'c-mode))
(dolist (D (semantic-gcc-get-include-paths "c++"))
(semantic-add-system-include D 'c++-mode)
- (let ((cppconfig (list (concat D "/bits/c++config.h") (concat D "/sys/cdefs.h"))))
+ (let ((cppconfig (list (concat D "/bits/c++config.h") (concat D "/sys/cdefs.h")
+ (concat D "/features.h"))))
(dolist (cur cppconfig)
;; Presumably there will be only one of these files in the try-paths list...
(when (file-readable-p cur)
diff --git a/lisp/cedet/semantic/ctxt.el b/lisp/cedet/semantic/ctxt.el
index b010a30da7f..f421e725ad9 100644
--- a/lisp/cedet/semantic/ctxt.el
+++ b/lisp/cedet/semantic/ctxt.el
@@ -168,8 +168,7 @@ Uses the bovinator with the special top-symbol `bovine-inner-scope'
to collect tags, such as local variables or prototypes."
;; This assumes a bovine parser. Make sure we don't do
;; anything in that case.
- (when (and semantic--parse-table (not (eq semantic--parse-table t))
- (not (semantic-parse-tree-unparseable-p)))
+ (when (and semantic--parse-table (not (eq semantic--parse-table t)))
(let ((vars (semantic-get-cache-data 'get-local-variables)))
(if vars
(progn
diff --git a/lisp/cedet/semantic/db-mode.el b/lisp/cedet/semantic/db-mode.el
index e0cb3708454..27daa9c2279 100644
--- a/lisp/cedet/semantic/db-mode.el
+++ b/lisp/cedet/semantic/db-mode.el
@@ -105,7 +105,8 @@ Sets up the semanticdb environment."
(oset ctbl major-mode major-mode)
;; Local state
(setq semanticdb-current-table ctbl)
- ;; Try to swap in saved tags
+ (oset ctbl buffer (current-buffer))
+ ;; Try to swap in saved tags
(if (or (not (slot-boundp ctbl 'tags)) (not (oref ctbl tags))
(/= (or (oref ctbl pointmax) 0) (point-max))
)
@@ -133,7 +134,6 @@ Sets up the semanticdb environment."
(semantic--set-buffer-cache (oref ctbl tags))
;; Don't need it to be dirty. Set dirty due to hooks from above.
(oset ctbl dirty nil) ;; Special case here.
- (oset ctbl buffer (current-buffer))
;; Bind into the buffer.
(semantic--tag-link-cache-to-buffer)
)
diff --git a/lisp/cedet/semantic/db.el b/lisp/cedet/semantic/db.el
index 614ce706b0c..bb7836e5c98 100644
--- a/lisp/cedet/semantic/db.el
+++ b/lisp/cedet/semantic/db.el
@@ -560,8 +560,9 @@ This will call `semantic-fetch-tags' if that file is in memory."
;;
;; Already in a buffer, just do it.
((semanticdb-in-buffer-p obj)
- (semanticdb-set-buffer obj)
- (semantic-fetch-tags))
+ (save-excursion
+ (semanticdb-set-buffer obj)
+ (semantic-fetch-tags)))
;;
;; Not in a buffer. Forcing a load.
(force
diff --git a/lisp/cedet/semantic/decorate/include.el b/lisp/cedet/semantic/decorate/include.el
index 0451ad44fe8..aa488373f0d 100644
--- a/lisp/cedet/semantic/decorate/include.el
+++ b/lisp/cedet/semantic/decorate/include.el
@@ -335,6 +335,9 @@ This mode provides a nice context menu on the include statements."
(defun semantic-decoration-on-includes-highlight-default (tag)
"Highlight the include TAG to show that semantic can't find it."
(let* ((file (semantic-dependency-tag-file tag))
+ ;; Don't actually load includes
+ (semanticdb-find-default-throttle
+ (remq 'unloaded semanticdb-find-default-throttle))
(table (semanticdb-find-table-for-include tag (current-buffer)))
(face nil)
(map nil)
@@ -365,8 +368,8 @@ This mode provides a nice context menu on the include statements."
(semanticdb-cache-get
table 'semantic-decoration-unparsed-include-cache)
;; Add a dependency.
- (let ((table semanticdb-current-table))
- (semanticdb-add-reference table tag))
+ (let ((currenttable semanticdb-current-table))
+ (semanticdb-add-reference currenttable tag))
)
))
diff --git a/lisp/cedet/semantic/decorate/mode.el b/lisp/cedet/semantic/decorate/mode.el
index cc5e9d9bec2..d959d3ab9c7 100644
--- a/lisp/cedet/semantic/decorate/mode.el
+++ b/lisp/cedet/semantic/decorate/mode.el
@@ -275,7 +275,13 @@ minor mode is enabled."
'semantic-decorate-tags-after-full-reparse nil t)
;; Add decorations to available tags. The above hooks ensure
;; that new tags will be decorated when they become available.
- (semantic-decorate-add-decorations (semantic-fetch-available-tags)))
+ ;; However, don't do this immediately, because EDE will be
+ ;; activated later by find-file-hook, and includes might not
+ ;; be found yet.
+ (run-with-idle-timer
+ 0.1 nil
+ (lambda ()
+ (semantic-decorate-add-decorations (semantic-fetch-available-tags)))))
;; Remove decorations from available tags.
(semantic-decorate-clear-decorations (semantic-fetch-available-tags))
;; Cleanup any leftover crap too.
diff --git a/lisp/cedet/semantic/format.el b/lisp/cedet/semantic/format.el
index c6fbbed2424..16ff6eb768e 100644
--- a/lisp/cedet/semantic/format.el
+++ b/lisp/cedet/semantic/format.el
@@ -499,7 +499,12 @@ Optional argument COLOR means highlight the prototype with font-lock colors."
(setq r (concat r "[]")
deref (1- deref)))
r)))
- )
+ (default (when (eq class 'variable)
+ (let ((defval
+ (semantic-tag-get-attribute tag :default-value)))
+ (when (and defval (stringp defval))
+ (concat "[=" defval "]")))))
+ )
(if args
(setq args
(concat " "
@@ -512,7 +517,8 @@ Optional argument COLOR means highlight the prototype with font-lock colors."
(if type (concat type " "))
name
(or args "")
- (or array ""))))
+ (or array "")
+ (or default ""))))
;;;###autoload
(define-overloadable-function semantic-format-tag-concise-prototype (tag &optional parent color)
diff --git a/lisp/cedet/semantic/lex-spp.el b/lisp/cedet/semantic/lex-spp.el
index 462e520654a..a77ebf98684 100644
--- a/lisp/cedet/semantic/lex-spp.el
+++ b/lisp/cedet/semantic/lex-spp.el
@@ -70,6 +70,8 @@
(require 'semantic)
(require 'semantic/lex)
+(declare-function semantic-c-end-of-macro "semantic/bovine/c")
+
;;; Code:
(defvar semantic-lex-spp-macro-symbol-obarray nil
"Table of macro keywords used by the Semantic Preprocessor.
@@ -527,16 +529,54 @@ and what valid VAL values are."
;;
;; Nested token FOO shows up in the table of macros, and gets replace
;; inline. This is the same as case 2.
+ ;;
+ ;; CASE 5: Macros which open a scope without closing it
+ ;;
+ ;; #define __NAMESPACE_STD namespace std {
+ ;; #define __NAMESPACE_END }
+ ;; ==>
+ ;; ((NAMESPACE "namespace" 140 . 149)
+ ;; (symbol "std" 150 . 153)
+ ;; (open-paren "{" 154 . 155))
+ ;;
+ ;; Note that we get a single 'open-paren' instead of a
+ ;; 'semantic-list', which is because we use
+ ;; 'semantic-lex-spp-paren-or-list' instead of
+ ;; 'semantic-lex-paren-or-list' in our spp-lexer. To keep things
+ ;; reasonably simple, we assume that such an open scope will always
+ ;; be closed by another macro (see
+ ;; `semantic-lex-spp-find-closing-macro'). We generate a
+ ;; 'semantic-list' to this closing macro, and we leave an overlay
+ ;; which contains information how far we got into the macro's
+ ;; stream (since it might open several scopes).
+
+ (let* ((arglist (semantic-lex-spp-macro-with-args val))
+ (argalist nil)
+ (val-tmp nil)
+ (v nil)
+ (sppov (semantic-lex-spp-get-overlay beg))
+ (sppinfo (when sppov (overlay-get sppov 'semantic-spp))))
+
+ ;; First, check if we were already here and left information
+ (when sppinfo
+ ;; Advance in the tokens as far as we got last time
+ (when (numberp (car sppinfo))
+ (while (and val
+ (>= (car sppinfo) (car (last (car val)))))
+ (setq val (cdr val))))
+ ;; And push an open paren
+ (semantic-lex-push-token
+ (semantic-lex-token 'open-paren beg (1+ beg) "{"))
+ (setq semantic-lex-current-depth (1+ semantic-lex-current-depth))
+ (unless val
+ ;; We reached the end of this macro, so delete overlay
+ (delete-overlay sppov)))
- (let ((arglist (semantic-lex-spp-macro-with-args val))
- (argalist nil)
- (val-tmp nil)
- (v nil)
- )
;; CASE 2: Dealing with the arg list.
- (when arglist
+ (when (and val arglist)
;; Skip the arg list.
- (setq val (cdr val))
+ (when (eq (caar val) 'spp-arg-list)
+ (setq val (cdr val)))
;; Push args into the replacement list.
(let ((AV argvalues))
@@ -616,7 +656,32 @@ and what valid VAL values are."
(semantic-lex-push-token
(semantic-lex-token (semantic-lex-token-class v) beg end txt))
)
-
+ ;; CASE 5: Macro which opens a scope
+ ((eq (semantic-lex-token-class v) 'open-paren)
+ ;; We assume that the scope will be closed by another macro.
+ ;; (Everything else would be a terrible idea anyway.)
+ (let* ((endpoint (semantic-lex-spp-find-closing-macro))
+ (ov (when endpoint
+ (or sppov
+ (make-overlay beg end)))))
+ (when ov
+ ;; Generate a semantic-list which spans to the end of
+ ;; the closing macro
+ (semantic-lex-push-token
+ (semantic-lex-token 'semantic-list beg endpoint))
+ ;; The rest of the current macro's stream will be parsed
+ ;; next time.
+ (setq val-tmp nil)
+ ;; Store our current state were we are in the macro and
+ ;; the endpoint.
+ (overlay-put ov 'semantic-spp
+ (cons (car (last v)) endpoint)))))
+ ((eq (semantic-lex-token-class v) 'close-paren)
+ ;; Macro which closes a scope
+ ;; Just push the close paren, but also decrease depth
+ (semantic-lex-push-token
+ (semantic-lex-token 'close-paren beg end txt))
+ (setq semantic-lex-current-depth (1- semantic-lex-current-depth)))
;; CASE 1: Just another token in the stream.
(t
;; Nothing new.
@@ -652,6 +717,37 @@ will return empty string instead.")
txt
""))
+(defun semantic-lex-spp-find-closing-macro ()
+ "Find next macro which closes a scope through a close-paren.
+Returns position with the end of that macro."
+ (let ((macros (semantic-lex-spp-macros))
+ (cmacro-regexp "\\(")
+ (case-fold-search nil))
+ ;; Build a regexp which search for all macros with a closing
+ ;; paren, and search for it.
+ (dolist (cur macros)
+ (let ((stream (symbol-value cur)))
+ (when (and (listp stream) (listp (car stream)))
+ (while stream
+ (if (and (eq (caar stream) 'close-paren)
+ (string= (nth 1 (car stream)) "}"))
+ (setq cmacro-regexp (concat cmacro-regexp (symbol-name cur) "\\|")
+ stream nil)
+ (setq stream (cdr-safe stream)))))))
+ (when cmacro-regexp
+ (save-excursion
+ (when (re-search-forward
+ (concat (substring cmacro-regexp 0 -2) "\\)[^0-9a-zA-Z_]") nil t)
+ (point))))))
+
+(defun semantic-lex-spp-get-overlay (&optional point)
+ "Return first overlay which has a 'semantic-spp property."
+ (let ((overlays (overlays-at (or point (point)))))
+ (while (and overlays
+ (null (overlay-get (car overlays) 'semantic-spp)))
+ (setq overlays (cdr overlays)))
+ (car-safe overlays)))
+
;;; Macro Merging
;;
;; Used when token streams from different macros include each other.
@@ -824,8 +920,46 @@ STR occurs in the current buffer between BEG and END."
"\\(\\sw\\|\\s_\\)+"
(let ((str (match-string 0))
(beg (match-beginning 0))
- (end (match-end 0)))
- (semantic-lex-spp-analyzer-push-tokens-for-symbol str beg end)))
+ (end (match-end 0))
+ sppov)
+ (semantic-lex-spp-analyzer-push-tokens-for-symbol str beg end)
+ (when (setq sppov (semantic-lex-spp-get-overlay beg))
+ (setq semantic-lex-end-point (cdr (overlay-get sppov 'semantic-spp))))))
+
+(define-lex-regex-analyzer semantic-lex-spp-paren-or-list
+ "Detect open parenthesis.
+Contrary to `semantic-lex-paren-or-list', this will push a single
+open-paren onto the stream if no closing paren can be found.
+This is important for macros which open a scope which is closed
+by another macro."
+ "\\s("
+ (if (or (not semantic-lex-maximum-depth)
+ (< semantic-lex-current-depth semantic-lex-maximum-depth))
+ (progn
+ (setq semantic-lex-current-depth (1+ semantic-lex-current-depth))
+ (semantic-lex-push-token
+ (semantic-lex-token
+ 'open-paren (match-beginning 0) (match-end 0))))
+ (save-excursion
+ (let ((start (match-beginning 0))
+ (end (match-end 0))
+ (peom (save-excursion (semantic-c-end-of-macro) (point))))
+ (condition-case nil
+ (progn
+ ;; This will throw an error if no closing paren can be found.
+ (forward-list 1)
+ (when (> (point) peom)
+ ;; If we have left the macro, this is the wrong closing
+ ;; paren, so error out as well.
+ (error ""))
+ (semantic-lex-push-token
+ (semantic-lex-token
+ 'semantic-list start (point))))
+ (error
+ ;; Only push a single open-paren.
+ (semantic-lex-push-token
+ (semantic-lex-token
+ 'open-paren start end))))))))
;;; ANALYZERS FOR NEW MACROS
;;
diff --git a/lisp/cedet/semantic/scope.el b/lisp/cedet/semantic/scope.el
index 13e858ca000..653f02d8e41 100644
--- a/lisp/cedet/semantic/scope.el
+++ b/lisp/cedet/semantic/scope.el
@@ -195,12 +195,18 @@ Use `semantic-ctxt-scoped-types' to find types."
;; Get this thing as a tag
(let ((tmp (cond
((stringp (car sp))
- (semanticdb-typecache-find (car sp)))
- ;(semantic-analyze-find-tag (car sp) 'type))
+ (or (semanticdb-typecache-find (car sp))
+ ;; If we did not find it in the typecache,
+ ;; look in the tags we found so far
+ (car (semantic-deep-find-tags-by-name
+ (car sp)
+ code-scoped-types))))
((semantic-tag-p (car sp))
(if (semantic-tag-prototype-p (car sp))
- (semanticdb-typecache-find (semantic-tag-name (car sp)))
- ;;(semantic-analyze-find-tag (semantic-tag-name (car sp)) 'type)
+ (or (semanticdb-typecache-find (semantic-tag-name (car sp)))
+ (car (semantic-deep-find-tags-by-name
+ (semantic-tag-name (car sp))
+ code-scoped-types)))
(car sp)))
(t nil))))
(when tmp
@@ -506,10 +512,33 @@ tag is not something you can complete from within TYPE."
(leftover nil)
)
(dolist (S allslots)
- (when (or (not (semantic-tag-of-class-p S 'function))
- (not (semantic-tag-function-parent S)))
- (setq leftover (cons S leftover)))
- )
+ ;; We have to specially deal with 'using' tags here, since those
+ ;; pull in namespaces or classes into the current scope.
+ ;; (Should this go into c.el? If so, into which override?)
+ (if (semantic-tag-of-class-p S 'using)
+ (let* ((fullname (semantic-analyze-unsplit-name
+ (list (semantic-tag-name type)
+ (semantic-tag-name S))))
+ ;; Search the typecache, first for the unqualified name
+ (usingtype (or
+ (semanticdb-typecache-find (semantic-tag-name S))
+ ;; If that didn't return anything, use
+ ;; fully qualified name
+ (semanticdb-typecache-find fullname)))
+ (filename (when usingtype (semantic-tag-file-name usingtype))))
+ (when usingtype
+ ;; Use recursion to examine that namespace or class
+ (let ((tags (semantic-completable-tags-from-type usingtype)))
+ (if filename
+ ;; If we have a filename, copy the tags with it
+ (dolist (cur tags)
+ (setq leftover (cons (semantic-tag-copy cur nil filename)
+ leftover)))
+ ;; Otherwise just run with it
+ (setq leftover (append tags leftover))))))
+ (when (or (not (semantic-tag-of-class-p S 'function))
+ (not (semantic-tag-function-parent S)))
+ (setq leftover (cons S leftover)))))
(nreverse leftover)))
(defun semantic-analyze-scoped-type-parts (type &optional scope noinherit protection)
@@ -734,8 +763,9 @@ The class returned from the scope calculation is variable
(when (called-interactively-p 'any)
(require 'eieio-datadebug)
(data-debug-show scopecache))
- ;; Return ourselves
- scopecache))))
+ ;; Return ourselves, but make a clone first so that the caller
+ ;; can reset the scope cache without affecting others.
+ (clone scopecache)))))
(defun semantic-scope-find (name &optional class scope-in)
"Find the tag with NAME, and optional CLASS in the current SCOPE-IN.