summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--admin/ChangeLog15
-rw-r--r--admin/grammars/c.by23
-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
17 files changed, 650 insertions, 168 deletions
diff --git a/admin/ChangeLog b/admin/ChangeLog
index 22824995dfc..54da0edf23f 100644
--- a/admin/ChangeLog
+++ b/admin/ChangeLog
@@ -1,3 +1,18 @@
+2013-12-12 David Engster <deng@randomsample.de>
+
+ * 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.
+
2013-12-11 Paul Eggert <eggert@cs.ucla.edu>
Remove the option of using libcrypto.
diff --git a/admin/grammars/c.by b/admin/grammars/c.by
index 55ec0fbaf01..7aafe7b90f3 100644
--- a/admin/grammars/c.by
+++ b/admin/grammars/c.by
@@ -901,8 +901,8 @@ varname
;; I should store more in this def, but leave it simple for now.
;; Klaus Berndl: const and volatile can be written after the type!
variablearg
- : declmods typeformbase cv-declmods opt-ref variablearg-opt-name
- ( VARIABLE-TAG (list $5) $2 nil
+ : declmods typeformbase cv-declmods opt-ref variablearg-opt-name opt-assign
+ ( VARIABLE-TAG (list (append $5 ,$6)) $2 nil
:constant-flag (if (member "const" (append $1 $3)) t nil)
:typemodifiers (delete "const" (append $1 $3))
:reference (car ,$4)
@@ -912,6 +912,8 @@ variablearg
variablearg-opt-name
: varname
( ,$1 )
+ | semantic-list arg-list
+ ( (car ( EXPAND $1 function-pointer )) $2)
;; Klaus Berndl: This allows variableargs without a arg-name being
;; parsed correct even if there several pointers (*)
| opt-stars
@@ -926,9 +928,9 @@ varname-opt-initializer
varnamelist
: opt-ref varname varname-opt-initializer COMA varnamelist
- ( ,(cons $2 $5) )
+ ( ,(cons (append $2 $3) $5) )
| opt-ref varname varname-opt-initializer
- ( $2 )
+ ( (append $2 $3) )
;
;; Klaus Berndl: Is necessary to parse stuff like
@@ -1152,16 +1154,15 @@ type-cast-list
: open-paren typeformbase close-paren
;
-opt-stuff-after-symbol
+brackets-after-symbol
: PAREN_BLCK
| BRACK_BLCK
- | ;; EMPTY
;
multi-stage-dereference
- : namespace-symbol opt-stuff-after-symbol PERIOD multi-stage-dereference ;; method call
- | namespace-symbol opt-stuff-after-symbol MINUS GREATER multi-stage-dereference ;;method call
- | namespace-symbol opt-stuff-after-symbol
+ : namespace-symbol brackets-after-symbol PERIOD multi-stage-dereference ;; method call
+ | namespace-symbol brackets-after-symbol MINUS GREATER multi-stage-dereference ;;method call
+ | namespace-symbol brackets-after-symbol
;
string-seq
@@ -1187,6 +1188,7 @@ expr-binop
| AMPERSAND
| OR OR
| OR
+ | MOD
;; There are more.
;
@@ -1204,8 +1206,7 @@ unaryexpression
| multi-stage-dereference
| NEW multi-stage-dereference
| NEW builtintype-types semantic-list
- ;; Klaus Berndl: symbol -> namespace-symbol!
- | namespace-symbol
+ | symbol
;; Klaus Berndl: C/C++ allows sequences of strings which are
;; concatenated by the precompiler to one string
| string-seq
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.