SemanticLibraryParsing

Last edit

Summary: Changed Qt setup.

Added:

> ;; Qt base directory, meaning the directory where the 'Qt' directory can be found.
> ;; Adapt accordingly.


If Semantic does not give you correct completions for a certain library, this is often due to some special preprocessor macros or some other trickery which Semantic cannot parse. This can often be overcome by giving Semantic some additional information. This page is intended to gather those special configuration options for parsing certain libraries. Also, please add libraries that work / don’t work. This page is currently focused on C/C++, but do not hesitate to add remarks for other languages as well.

Some general hints on parsing problems with C++ libraries

First of all, make sure that CEDET is correctly set up, and that you get completions for your own stuff. Create some silly test classes und try some completions - if this doesn’t work, there’s probably something wrong with your setup, and you’ll have to fix this first.

While the C/C++ support in CEDET is pretty good, there are still some areas where Semantic has problems. Most of those areas are related to preprocessor macros, so this is usually the first thing you should look for.

For example, some libraries use preprocessor symbols in class definitions, like

class SOMESYMBOL someClass {
 ....
};

where SOMESYMBOL is often expanded to some gcc attribute or similar. If SOMESYMBOL is defined in some other header file, Semantic will not be able to parse this. The reason for this is that Semantic does not parse every #define’d symbol out there - this would simply make parsing too slow. The easiest way to deal with this problem is to simply give Semantic a definition for SOMESYMBOL:

(add-to-list 'semantic-lex-c-preprocessor-symbol-map '("SOMESYMBOL" . ""))

This command will just set SOMESYMBOL to the empty string, and Semantic will therefore just ignore it. Another possibility is to find out in which header file SOMESYMBOL is defined, and add this one to the list of files which are explicitly parsed for symbol definitions:

(add-to-list 'semantic-lex-c-preprocessor-symbol-file '"/PATH/someheader.h")

Another problem are namespace macros, e.g.,

#define BEGIN_STD namespace std {
#define END_STD }

BEGIN_STD
  class someClass { ... };
END_STD

Currently, Semantic cannot deal with this. However, there’s some explicit support implemented for this, at least for the STL implementations from the GlibC? and from Visual C++.

wxWidget

The wxWidget library uses some preprocessor macros in its class definitions, which currently cannot be correctly dereferenced by Semantic. You have to set these macros manually through

(add-to-list 'semantic-lex-c-preprocessor-symbol-map '("WXDLLIMPEXP_CORE" . ""))
(add-to-list 'semantic-lex-c-preprocessor-symbol-map '("WXDLLIMPEXP_FWD_CORE" . ""))
(add-to-list 'semantic-lex-c-preprocessor-symbol-map '("WXDLLIMPEXP_BASE" . ""))
(add-to-list 'semantic-lex-c-preprocessor-symbol-map '("WXDLLIMPEXP_FWD_BASE" . ""))
(add-to-list 'semantic-lex-c-preprocessor-symbol-map '("WXDLLIMPEXP_FWD_XML" . ""))
(add-to-list 'semantic-lex-c-preprocessor-symbol-map '("WXDLLIMPEXP_ADV" . ""))

This applies to the current development version 2.90 of wxWidget. Older versions only need

(add-to-list 'semantic-lex-c-preprocessor-symbol-map '("WXDLLEXPORT" . ""))

Another problem with wxWidget is that it can use different toolkits, and most of the classes are defined in the toolkit header files, which are not included manually in the C++ files. However, you can include those header files through a Semantic feature called “implied includes”. You can use the following helper function:

 (defun DE-imply-includes-in-directory (dir)
  "Add all header files in DIR to `semanticdb-implied-include-tags'."
  (let ((files (directory-files dir t "^.+\\.h[hp]*$" t)))
    (defvar-mode-local c++-mode semanticdb-implied-include-tags
      (mapcar (lambda (header)
		(semantic-tag-new-include
		 header
		 nil
		 :filename header))
	      files))))

Now you can simply do

(DE-imply-includes-in-directory "/YOUR-INCLUDE-PATH/wx/gtk")

to implicitly include all header files from the GTK toolkit files. This should give Semantic all the information it needs to correctly parse the classes.

For a detailed explanation see http://navaneethkn.wordpress.com/2009/10/11/getting-smart-completion-wxwidgets-cedet-emacs

Qt

AlexOtt: This setup should work for Qt. Make sure you’re using the CEDET version from bzr, though.

;; Qt base directory, meaning the directory where the 'Qt' directory can be found.
;; Adapt accordingly.
(setq qt4-base-dir "/usr/include/qt4")
(setq qt4-gui-dir (concat qt4-base-dir "/QtGui"))
(semantic-add-system-include qt4-base-dir 'c++-mode)
(semantic-add-system-include qt4-gui-dir 'c++-mode)
(add-to-list 'auto-mode-alist (cons qt4-base-dir 'c++-mode))
(add-to-list 'semantic-lex-c-preprocessor-symbol-file (concat qt4-base-dir "/Qt/qconfig.h"))
(add-to-list 'semantic-lex-c-preprocessor-symbol-file (concat qt4-base-dir "/Qt/qconfig-large.h"))
(add-to-list 'semantic-lex-c-preprocessor-symbol-file (concat qt4-base-dir "/Qt/qglobal.h"))

GlibC (STL)

Uses namespace macros, but special support for that is implemented in Semantic. Most stuff should work out of the box. However, Semantic has problems parsing template specializations; those are used in allocator.h, for instance. This sometimes leads to wrong dereferencing of templated objects; for example, consider ‘v’ to be a vector like ‘vector<someClass>’, then ‘v[0].’ won’t complete from ‘someClass’ but from ‘vector’.

Visual C++ STL

Also uses namespace macros, but support for those in VC++ are implemented in latest CEDET from CVS.

Vmime

The vmime library uses lots of namespace aliasing, which is supported in the latest CEDET from CVS. However, there are still some problems with completing namespace aliases in the scope operator; this is a problem currently being worked on. Also, vmime uses its own kind of “smart” pointers, which might lead to problems. But basically, completions should still work.