Merge from CEDET upstream.
This commit is contained in:
commit
2cc82b9fbc
17 changed files with 650 additions and 168 deletions
|
@ -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-12 Glenn Morris <rgm@gnu.org>
|
||||
|
||||
* update_autogen (info_dir):
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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)))
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)))
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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."
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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))
|
||||
)
|
||||
))
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
;;
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Add table
Reference in a new issue