Commits

Grigoriy Kuznetsov committed 4bac4ec

updated clang-complete

  • Participants
  • Parent commits 8a86c98

Comments (0)

Files changed (42)

File bin/cc_args.py

-#!/usr/bin/env python
-#-*- coding: utf-8 -*-
-
-import os
-import sys
-
-CONFIG_NAME = ".clang_complete"
-
-def readConfiguration():
-  try:
-    f = open(CONFIG_NAME, "r")
-  except IOError:
-    return []
-
-  result = []
-  for line in f.readlines():
-    strippedLine = line.strip()
-    if len(strippedLine) > 0:
-      result += [strippedLine]
-  f.close()
-  return result
-
-def writeConfiguration(lines):
-  f = open(CONFIG_NAME, "w")
-  f.writelines(lines)
-  f.close()
-
-def parseArguments(arguments):
-  nextIsInclude = False
-  nextIsDefine = False
-  nextIsIncludeFile = False
-
-  includes = []
-  defines = []
-  include_file = []
-
-  for arg in arguments:
-    if nextIsInclude:
-      includes += [arg]
-      nextIsInclude = False
-    elif nextIsDefine:
-      defines += [arg]
-      nextIsDefine = False
-    elif nextIsIncludeFile:
-      include_file += [arg]
-      nextIsIncludeFile = False
-    elif arg == "-I":
-      nextIsInclude = True
-    elif arg == "-D":
-      nextIsDefine = True
-    elif arg[:2] == "-I":
-      includes += [arg[2:]]
-    elif arg[:2] == "-D":
-      defines += [arg[2:]]
-    elif arg == "-include":
-      nextIsIncludeFile = True
-
-  result = map(lambda x: "-I" + x, includes)
-  result += map(lambda x: "-D" + x, defines)
-  result += map(lambda x: "-include " + x, include_file)
-
-  return result
-
-def mergeLists(base, new):
-  result = list(base)
-  for newLine in new:
-    try:
-      result.index(newLine)
-    except ValueError:
-      result += [newLine]
-  return result
-
-configuration = readConfiguration()
-args = parseArguments(sys.argv)
-result = mergeLists(configuration, args)
-writeConfiguration(map(lambda x: x + "\n", result))
-
-
-status = os.system(" ".join(sys.argv[1:]))
-if not os.WIFEXITED(status):
-  sys.exit(1)
-sys.exit(os.WEXITSTATUS(status))
-
-# vim: set ts=2 sts=2 sw=2 expandtab :

File bundle/clang_complete/.git/HEAD

+ref: refs/heads/master

File bundle/clang_complete/.git/config

+[core]
+	repositoryformatversion = 0
+	filemode = true
+	bare = false
+	logallrefupdates = true
+	ignorecase = true
+[remote "origin"]
+	fetch = +refs/heads/*:refs/remotes/origin/*
+	url = https://github.com/Rip-Rip/clang_complete.git
+[branch "master"]
+	remote = origin
+	merge = refs/heads/master

File bundle/clang_complete/.git/description

+Unnamed repository; edit this file 'description' to name the repository.

File bundle/clang_complete/.git/hooks/applypatch-msg.sample

+#!/bin/sh
+#
+# An example hook script to check the commit log message taken by
+# applypatch from an e-mail message.
+#
+# The hook should exit with non-zero status after issuing an
+# appropriate message if it wants to stop the commit.  The hook is
+# allowed to edit the commit message file.
+#
+# To enable this hook, rename this file to "applypatch-msg".
+
+. git-sh-setup
+test -x "$GIT_DIR/hooks/commit-msg" &&
+	exec "$GIT_DIR/hooks/commit-msg" ${1+"$@"}
+:

File bundle/clang_complete/.git/hooks/commit-msg.sample

+#!/bin/sh
+#
+# An example hook script to check the commit log message.
+# Called by "git commit" with one argument, the name of the file
+# that has the commit message.  The hook should exit with non-zero
+# status after issuing an appropriate message if it wants to stop the
+# commit.  The hook is allowed to edit the commit message file.
+#
+# To enable this hook, rename this file to "commit-msg".
+
+# Uncomment the below to add a Signed-off-by line to the message.
+# Doing this in a hook is a bad idea in general, but the prepare-commit-msg
+# hook is more suited to it.
+#
+# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p')
+# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1"
+
+# This example catches duplicate Signed-off-by lines.
+
+test "" = "$(grep '^Signed-off-by: ' "$1" |
+	 sort | uniq -c | sed -e '/^[ 	]*1[ 	]/d')" || {
+	echo >&2 Duplicate Signed-off-by lines.
+	exit 1
+}

File bundle/clang_complete/.git/hooks/post-update.sample

+#!/bin/sh
+#
+# An example hook script to prepare a packed repository for use over
+# dumb transports.
+#
+# To enable this hook, rename this file to "post-update".
+
+exec git update-server-info

File bundle/clang_complete/.git/hooks/pre-applypatch.sample

+#!/bin/sh
+#
+# An example hook script to verify what is about to be committed
+# by applypatch from an e-mail message.
+#
+# The hook should exit with non-zero status after issuing an
+# appropriate message if it wants to stop the commit.
+#
+# To enable this hook, rename this file to "pre-applypatch".
+
+. git-sh-setup
+test -x "$GIT_DIR/hooks/pre-commit" &&
+	exec "$GIT_DIR/hooks/pre-commit" ${1+"$@"}
+:

File bundle/clang_complete/.git/hooks/pre-commit.sample

+#!/bin/sh
+#
+# An example hook script to verify what is about to be committed.
+# Called by "git commit" with no arguments.  The hook should
+# exit with non-zero status after issuing an appropriate message if
+# it wants to stop the commit.
+#
+# To enable this hook, rename this file to "pre-commit".
+
+if git rev-parse --verify HEAD >/dev/null 2>&1
+then
+	against=HEAD
+else
+	# Initial commit: diff against an empty tree object
+	against=4b825dc642cb6eb9a060e54bf8d69288fbee4904
+fi
+
+# If you want to allow non-ascii filenames set this variable to true.
+allownonascii=$(git config hooks.allownonascii)
+
+# Redirect output to stderr.
+exec 1>&2
+
+# Cross platform projects tend to avoid non-ascii filenames; prevent
+# them from being added to the repository. We exploit the fact that the
+# printable range starts at the space character and ends with tilde.
+if [ "$allownonascii" != "true" ] &&
+	# Note that the use of brackets around a tr range is ok here, (it's
+	# even required, for portability to Solaris 10's /usr/bin/tr), since
+	# the square bracket bytes happen to fall in the designated range.
+	test $(git diff --cached --name-only --diff-filter=A -z $against |
+	  LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0
+then
+	echo "Error: Attempt to add a non-ascii file name."
+	echo
+	echo "This can cause problems if you want to work"
+	echo "with people on other platforms."
+	echo
+	echo "To be portable it is advisable to rename the file ..."
+	echo
+	echo "If you know what you are doing you can disable this"
+	echo "check using:"
+	echo
+	echo "  git config hooks.allownonascii true"
+	echo
+	exit 1
+fi
+
+# If there are whitespace errors, print the offending file names and fail.
+exec git diff-index --check --cached $against --

File bundle/clang_complete/.git/hooks/pre-rebase.sample

+#!/bin/sh
+#
+# Copyright (c) 2006, 2008 Junio C Hamano
+#
+# The "pre-rebase" hook is run just before "git rebase" starts doing
+# its job, and can prevent the command from running by exiting with
+# non-zero status.
+#
+# The hook is called with the following parameters:
+#
+# $1 -- the upstream the series was forked from.
+# $2 -- the branch being rebased (or empty when rebasing the current branch).
+#
+# This sample shows how to prevent topic branches that are already
+# merged to 'next' branch from getting rebased, because allowing it
+# would result in rebasing already published history.
+
+publish=next
+basebranch="$1"
+if test "$#" = 2
+then
+	topic="refs/heads/$2"
+else
+	topic=`git symbolic-ref HEAD` ||
+	exit 0 ;# we do not interrupt rebasing detached HEAD
+fi
+
+case "$topic" in
+refs/heads/??/*)
+	;;
+*)
+	exit 0 ;# we do not interrupt others.
+	;;
+esac
+
+# Now we are dealing with a topic branch being rebased
+# on top of master.  Is it OK to rebase it?
+
+# Does the topic really exist?
+git show-ref -q "$topic" || {
+	echo >&2 "No such branch $topic"
+	exit 1
+}
+
+# Is topic fully merged to master?
+not_in_master=`git rev-list --pretty=oneline ^master "$topic"`
+if test -z "$not_in_master"
+then
+	echo >&2 "$topic is fully merged to master; better remove it."
+	exit 1 ;# we could allow it, but there is no point.
+fi
+
+# Is topic ever merged to next?  If so you should not be rebasing it.
+only_next_1=`git rev-list ^master "^$topic" ${publish} | sort`
+only_next_2=`git rev-list ^master           ${publish} | sort`
+if test "$only_next_1" = "$only_next_2"
+then
+	not_in_topic=`git rev-list "^$topic" master`
+	if test -z "$not_in_topic"
+	then
+		echo >&2 "$topic is already up-to-date with master"
+		exit 1 ;# we could allow it, but there is no point.
+	else
+		exit 0
+	fi
+else
+	not_in_next=`git rev-list --pretty=oneline ^${publish} "$topic"`
+	/opt/local/bin/perl5.12 -e '
+		my $topic = $ARGV[0];
+		my $msg = "* $topic has commits already merged to public branch:\n";
+		my (%not_in_next) = map {
+			/^([0-9a-f]+) /;
+			($1 => 1);
+		} split(/\n/, $ARGV[1]);
+		for my $elem (map {
+				/^([0-9a-f]+) (.*)$/;
+				[$1 => $2];
+			} split(/\n/, $ARGV[2])) {
+			if (!exists $not_in_next{$elem->[0]}) {
+				if ($msg) {
+					print STDERR $msg;
+					undef $msg;
+				}
+				print STDERR " $elem->[1]\n";
+			}
+		}
+	' "$topic" "$not_in_next" "$not_in_master"
+	exit 1
+fi
+
+exit 0
+
+################################################################
+
+This sample hook safeguards topic branches that have been
+published from being rewound.
+
+The workflow assumed here is:
+
+ * Once a topic branch forks from "master", "master" is never
+   merged into it again (either directly or indirectly).
+
+ * Once a topic branch is fully cooked and merged into "master",
+   it is deleted.  If you need to build on top of it to correct
+   earlier mistakes, a new topic branch is created by forking at
+   the tip of the "master".  This is not strictly necessary, but
+   it makes it easier to keep your history simple.
+
+ * Whenever you need to test or publish your changes to topic
+   branches, merge them into "next" branch.
+
+The script, being an example, hardcodes the publish branch name
+to be "next", but it is trivial to make it configurable via
+$GIT_DIR/config mechanism.
+
+With this workflow, you would want to know:
+
+(1) ... if a topic branch has ever been merged to "next".  Young
+    topic branches can have stupid mistakes you would rather
+    clean up before publishing, and things that have not been
+    merged into other branches can be easily rebased without
+    affecting other people.  But once it is published, you would
+    not want to rewind it.
+
+(2) ... if a topic branch has been fully merged to "master".
+    Then you can delete it.  More importantly, you should not
+    build on top of it -- other people may already want to
+    change things related to the topic as patches against your
+    "master", so if you need further changes, it is better to
+    fork the topic (perhaps with the same name) afresh from the
+    tip of "master".
+
+Let's look at this example:
+
+		   o---o---o---o---o---o---o---o---o---o "next"
+		  /       /           /           /
+		 /   a---a---b A     /           /
+		/   /               /           /
+	       /   /   c---c---c---c B         /
+	      /   /   /             \         /
+	     /   /   /   b---b C     \       /
+	    /   /   /   /             \     /
+    ---o---o---o---o---o---o---o---o---o---o---o "master"
+
+
+A, B and C are topic branches.
+
+ * A has one fix since it was merged up to "next".
+
+ * B has finished.  It has been fully merged up to "master" and "next",
+   and is ready to be deleted.
+
+ * C has not merged to "next" at all.
+
+We would want to allow C to be rebased, refuse A, and encourage
+B to be deleted.
+
+To compute (1):
+
+	git rev-list ^master ^topic next
+	git rev-list ^master        next
+
+	if these match, topic has not merged in next at all.
+
+To compute (2):
+
+	git rev-list master..topic
+
+	if this is empty, it is fully merged to "master".

File bundle/clang_complete/.git/hooks/prepare-commit-msg.sample

+#!/bin/sh
+#
+# An example hook script to prepare the commit log message.
+# Called by "git commit" with the name of the file that has the
+# commit message, followed by the description of the commit
+# message's source.  The hook's purpose is to edit the commit
+# message file.  If the hook fails with a non-zero status,
+# the commit is aborted.
+#
+# To enable this hook, rename this file to "prepare-commit-msg".
+
+# This hook includes three examples.  The first comments out the
+# "Conflicts:" part of a merge commit.
+#
+# The second includes the output of "git diff --name-status -r"
+# into the message, just before the "git status" output.  It is
+# commented because it doesn't cope with --amend or with squashed
+# commits.
+#
+# The third example adds a Signed-off-by line to the message, that can
+# still be edited.  This is rarely a good idea.
+
+case "$2,$3" in
+  merge,)
+    /opt/local/bin/perl5.12 -i.bak -ne 's/^/# /, s/^# #/#/ if /^Conflicts/ .. /#/; print' "$1" ;;
+
+# ,|template,)
+#   /opt/local/bin/perl5.12 -i.bak -pe '
+#      print "\n" . `git diff --cached --name-status -r`
+#	 if /^#/ && $first++ == 0' "$1" ;;
+
+  *) ;;
+esac
+
+# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p')
+# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1"

File bundle/clang_complete/.git/hooks/update.sample

+#!/bin/sh
+#
+# An example hook script to blocks unannotated tags from entering.
+# Called by "git receive-pack" with arguments: refname sha1-old sha1-new
+#
+# To enable this hook, rename this file to "update".
+#
+# Config
+# ------
+# hooks.allowunannotated
+#   This boolean sets whether unannotated tags will be allowed into the
+#   repository.  By default they won't be.
+# hooks.allowdeletetag
+#   This boolean sets whether deleting tags will be allowed in the
+#   repository.  By default they won't be.
+# hooks.allowmodifytag
+#   This boolean sets whether a tag may be modified after creation. By default
+#   it won't be.
+# hooks.allowdeletebranch
+#   This boolean sets whether deleting branches will be allowed in the
+#   repository.  By default they won't be.
+# hooks.denycreatebranch
+#   This boolean sets whether remotely creating branches will be denied
+#   in the repository.  By default this is allowed.
+#
+
+# --- Command line
+refname="$1"
+oldrev="$2"
+newrev="$3"
+
+# --- Safety check
+if [ -z "$GIT_DIR" ]; then
+	echo "Don't run this script from the command line." >&2
+	echo " (if you want, you could supply GIT_DIR then run" >&2
+	echo "  $0 <ref> <oldrev> <newrev>)" >&2
+	exit 1
+fi
+
+if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then
+	echo "Usage: $0 <ref> <oldrev> <newrev>" >&2
+	exit 1
+fi
+
+# --- Config
+allowunannotated=$(git config --bool hooks.allowunannotated)
+allowdeletebranch=$(git config --bool hooks.allowdeletebranch)
+denycreatebranch=$(git config --bool hooks.denycreatebranch)
+allowdeletetag=$(git config --bool hooks.allowdeletetag)
+allowmodifytag=$(git config --bool hooks.allowmodifytag)
+
+# check for no description
+projectdesc=$(sed -e '1q' "$GIT_DIR/description")
+case "$projectdesc" in
+"Unnamed repository"* | "")
+	echo "*** Project description file hasn't been set" >&2
+	exit 1
+	;;
+esac
+
+# --- Check types
+# if $newrev is 0000...0000, it's a commit to delete a ref.
+zero="0000000000000000000000000000000000000000"
+if [ "$newrev" = "$zero" ]; then
+	newrev_type=delete
+else
+	newrev_type=$(git cat-file -t $newrev)
+fi
+
+case "$refname","$newrev_type" in
+	refs/tags/*,commit)
+		# un-annotated tag
+		short_refname=${refname##refs/tags/}
+		if [ "$allowunannotated" != "true" ]; then
+			echo "*** The un-annotated tag, $short_refname, is not allowed in this repository" >&2
+			echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2
+			exit 1
+		fi
+		;;
+	refs/tags/*,delete)
+		# delete tag
+		if [ "$allowdeletetag" != "true" ]; then
+			echo "*** Deleting a tag is not allowed in this repository" >&2
+			exit 1
+		fi
+		;;
+	refs/tags/*,tag)
+		# annotated tag
+		if [ "$allowmodifytag" != "true" ] && git rev-parse $refname > /dev/null 2>&1
+		then
+			echo "*** Tag '$refname' already exists." >&2
+			echo "*** Modifying a tag is not allowed in this repository." >&2
+			exit 1
+		fi
+		;;
+	refs/heads/*,commit)
+		# branch
+		if [ "$oldrev" = "$zero" -a "$denycreatebranch" = "true" ]; then
+			echo "*** Creating a branch is not allowed in this repository" >&2
+			exit 1
+		fi
+		;;
+	refs/heads/*,delete)
+		# delete branch
+		if [ "$allowdeletebranch" != "true" ]; then
+			echo "*** Deleting a branch is not allowed in this repository" >&2
+			exit 1
+		fi
+		;;
+	refs/remotes/*,commit)
+		# tracking branch
+		;;
+	refs/remotes/*,delete)
+		# delete tracking branch
+		if [ "$allowdeletebranch" != "true" ]; then
+			echo "*** Deleting a tracking branch is not allowed in this repository" >&2
+			exit 1
+		fi
+		;;
+	*)
+		# Anything else (is there anything else?)
+		echo "*** Update hook: unknown type of update to ref $refname of type $newrev_type" >&2
+		exit 1
+		;;
+esac
+
+# --- Finished
+exit 0

File bundle/clang_complete/.git/index

Binary file added.

File bundle/clang_complete/.git/info/exclude

+# git ls-files --others --exclude-from=.git/info/exclude
+# Lines that start with '#' are comments.
+# For a project mostly in C, the following would be a good set of
+# exclude patterns (uncomment them if you want to use them):
+# *.[oa]
+# *~

File bundle/clang_complete/.git/logs/HEAD

+0000000000000000000000000000000000000000 22629de5e75ca0a997519cf44cc4226c5d297dbb Grigoriy Kuznetsov <gkuznets@yandex-team.ru> 1338291216 +0400	clone: from https://github.com/Rip-Rip/clang_complete.git

File bundle/clang_complete/.git/logs/refs/heads/master

+0000000000000000000000000000000000000000 22629de5e75ca0a997519cf44cc4226c5d297dbb Grigoriy Kuznetsov <gkuznets@yandex-team.ru> 1338291216 +0400	clone: from https://github.com/Rip-Rip/clang_complete.git

File bundle/clang_complete/.git/logs/refs/remotes/origin/HEAD

+0000000000000000000000000000000000000000 22629de5e75ca0a997519cf44cc4226c5d297dbb Grigoriy Kuznetsov <gkuznets@yandex-team.ru> 1338291216 +0400	clone: from https://github.com/Rip-Rip/clang_complete.git

File bundle/clang_complete/.git/objects/pack/pack-6d3c1490a3aaf956054720be34d5596c2d18bef0.idx

Binary file added.

File bundle/clang_complete/.git/objects/pack/pack-6d3c1490a3aaf956054720be34d5596c2d18bef0.pack

Binary file added.

File bundle/clang_complete/.git/packed-refs

+# pack-refs with: peeled 
+22629de5e75ca0a997519cf44cc4226c5d297dbb refs/remotes/origin/master
+8fa8cd5b8421fb8406ed9e5318f09c35f861a76f refs/remotes/origin/old-clang
+8fa8cd5b8421fb8406ed9e5318f09c35f861a76f refs/tags/v1.8

File bundle/clang_complete/.git/refs/heads/master

+22629de5e75ca0a997519cf44cc4226c5d297dbb

File bundle/clang_complete/.git/refs/remotes/origin/HEAD

+ref: refs/remotes/origin/master

File bundle/clang_complete/.gitignore

+*.pyc
+*.vmb
+*.cache
+tags

File bundle/clang_complete/Makefile

+SHELL	:= /bin/bash
+FILES	:= $(shell git ls-files autoload bin doc plugin)
+
+all: clang_complete.vmb
+
+clang_complete.vmb: $(FILES)
+	vim -c "r! git ls-files autoload bin doc plugin" \
+	     -c '$$,$$d _' \
+	     -c "%MkVimball! $@ ." -c 'q!'
+
+.PHONY: install uninstall
+install: clang_complete.vmb
+	vim $< -c 'so %' -c 'q'
+uninstall:
+	vim -c 'RmVimball clang_complete.vmb' -c 'q'
+
+.PHONY: clean
+clean:
+	rm -f clang_complete.vmb

File bundle/clang_complete/README

+This plugin uses clang for accurately completing C and C++ code.
+
+To build and install in one step, type:
+$ make install
+
+To build and install in two steps, type:
+$ make
+$ vim clang_complete.vmb -c 'so %' -c 'q'
+
+Alternatively, you can also put the files in ~/.vim/
+
+You need Vim 7.3 or higher, compiled with python support and ideally, with
+the conceal feature.
+
+See doc/clang_complete.txt for help and license.

File bundle/clang_complete/autoload/getopts/gcc.vim

+" clang_complete gcc's include paths finder
+" Author: xaizek
+
+let s:scr = expand('<sfile>')
+let s:cache_path = fnamemodify(s:scr, ':p:h')
+
+function! getopts#gcc#getopts()
+  call s:DetemineFileType()
+  if !s:CacheExists()
+    call s:CreateCache()
+  endif
+  call s:ReadCache()
+  call s:AppendOptions()
+endfunction
+
+function! s:DetemineFileType()
+  let b:cache = s:cache_path . '/' . &filetype . '.cache'
+  if &filetype == 'c'
+    let b:lang_name = 'c'
+  elseif &filetype == 'cpp'
+    let b:lang_name = 'c++'
+  elseif &filetype == 'objc'
+    let b:lang_name = 'objective-c'
+  elseif &filetype == 'objcpp'
+    let b:lang_name = 'objective-c++'
+  elseif
+    let b:lang_name = 'none'
+  endif
+endfunction
+
+function! s:CacheExists()
+  if !filereadable(b:cache)
+    return 0
+  endif
+
+  let l:lines = readfile(b:cache)
+
+  for l:line in l:lines
+    let l:line = substitute(l:line, '^\s\+', '', '')
+    if l:line =~ '^-I' && !isdirectory(l:line[2:])
+      return 0
+    endif
+  endfor
+
+  return len(l:lines) > 0
+endfunction
+
+function! s:CreateCache()
+  let b:gcc_opts = s:GetGCCOptions()
+  call writefile(b:gcc_opts, b:cache)
+endfunction
+
+function! s:GetGCCOptions()
+  let l:out = split(system('echo | cpp -v -x ' . b:lang_name), "\n")
+
+  while !empty(l:out) && l:out[0] !~ '^#include <...>'
+    let l:out = l:out[1:]
+  endwhile
+  if !empty(l:out)
+    let l:out = l:out[1:]
+  endif
+
+  let l:result = []
+  while !empty(l:out) && l:out[0] !~ '^End of search list.$'
+    let l:inc_path = substitute(l:out[0], '^\s*', '', '')
+    let l:inc_path = fnamemodify(l:inc_path, ':p')
+    let l:inc_path = substitute(l:inc_path, '\', '/', 'g')
+
+    if isdirectory(l:inc_path)
+      call add(l:result, '-I' . l:inc_path)
+    endif
+
+    let l:out = l:out[1:]
+  endwhile
+  return l:result
+endfunction
+
+function! s:ReadCache()
+  let b:gcc_opts = readfile(b:cache)
+endfunction
+
+function! s:AppendOptions()
+  let b:clang_user_options .= ' ' . join(b:gcc_opts, ' ')
+endfunction
+
+function! ClearGCCIncludeCaches()
+  let l:cache_files = split(globpath(s:cache_path, '*.cache', 1), "\n")
+  for l:cache_file in l:cache_files
+    call delete(l:cache_file)
+  endfor
+  unlet! b:gcc_opts
+endfunction
+
+" vim: set ts=2 sts=2 sw=2 expandtab :

File bundle/clang_complete/autoload/snippets/clang_complete.vim

+" clang_complete clang_complete's snippet generator
+" Author: Xavier Deguillard, Philippe Vaucher
+
+function! snippets#clang_complete#init()
+  noremap <expr> <silent> <buffer> <tab> UpdateSnips()
+  snoremap <expr> <silent> <buffer> <tab> UpdateSnips()
+  syntax match Conceal /<#/ conceal
+  syntax match Conceal /#>/ conceal
+endfunction
+
+" fullname = strcat(char *dest, const char *src)
+" args_pos = [ [8, 17], [20, 34] ]
+function! snippets#clang_complete#add_snippet(fullname, args_pos)
+  let l:res = ''
+  let l:prev_idx = 0
+  for elt in a:args_pos
+    let l:res .= a:fullname[l:prev_idx : elt[0] - 1] . '<#' . a:fullname[elt[0] : elt[1] - 1] . '#>'
+    let l:prev_idx = elt[1]
+  endfor
+
+  let l:res .= a:fullname[l:prev_idx : ]
+
+  return l:res
+endfunction
+
+function! snippets#clang_complete#trigger()
+  call s:BeginSnips()
+endfunction
+
+function! snippets#clang_complete#reset()
+endfunction
+
+
+" ---------------- Helpers ----------------
+
+function! UpdateSnips()
+  let l:line = getline('.')
+  let l:pattern = '<#[^#]*#>'
+  if match(l:line, l:pattern) == -1
+    return "\<c-i>"
+  endif
+
+  let l:commands = ""
+  if mode() != 'n'
+      let l:commands .= "\<esc>"
+  endif
+
+  let l:commands .= ":call MoveToCCSnippetBegin()\<CR>"
+  let l:commands .= "m'"
+  let l:commands .= ":call MoveToCCSnippetEnd()\<CR>"
+
+  if &selection == "exclusive"
+    let l:commands .= "ll"
+  else
+    let l:commands .= "l"
+  endif
+
+  let l:commands .= "v`'o\<C-G>"
+
+  return l:commands
+endfunction
+
+function! MoveToCCSnippetBegin()
+  let l:pattern = '<#'
+  let l:line = getline('.')
+  let l:startpos = col('.') + 1
+  let l:ind = match(l:line, l:pattern, l:startpos)
+  if l:ind == -1
+    let l:ind = match(l:line, l:pattern, 0)
+  endif
+  call cursor(line('.'), l:ind + 1)
+endfunction
+
+function! MoveToCCSnippetEnd()
+  let l:line = getline('.')
+  let l:pattern = '#>'
+  let l:startpos = col('.') + 2
+
+  call cursor(line('.'), match(l:line, l:pattern, l:startpos) + 1)
+endfunction
+
+function! s:BeginSnips()
+  if pumvisible() != 0
+    return
+  endif
+
+  " Do we need to launch UpdateSnippets()?
+  let l:line = getline('.')
+  let l:pattern = '<#[^#]*#>'
+  if match(l:line, l:pattern) == -1
+    return
+  endif
+  call feedkeys("\<esc>^\<tab>")
+endfunction
+
+" vim: set ts=2 sts=2 sw=2 expandtab :

File bundle/clang_complete/autoload/snippets/dummy.vim

+" Prepare the snippet engine
+function! snippets#dummy#init()
+  echo 'Initializing stuffs'
+endfunction
+
+" Add a snippet to be triggered
+" fullname: contain an unmangled name. ex: strcat(char *dest, const char *src)
+" args_pos: contain the position of the argument in fullname. ex [ [8, 17], [20, 34] ]
+" Returns: text to be inserted for when trigger() is called
+function! snippets#dummy#add_snippet(fullname, args_pos)
+  echo 'Creating snippet for "' . a:fullname
+  return a:fullname
+endfunction
+
+" Trigger the snippet
+" Note: usually as simple as triggering the tab key
+function! snippets#dummy#trigger()
+  echo 'Triggering snippet'
+endfunction
+
+" Remove all snippets
+function! snippets#dummy#reset()
+  echo 'Resetting all snippets'
+endfunction

File bundle/clang_complete/autoload/snippets/snipmate.vim

+" clang_complete snipmate's snippet generator
+" Author: Philippe Vaucher
+
+function! snippets#snipmate#init()
+  call snippets#snipmate#reset()
+endfunction
+
+" fullname = strcat(char *dest, const char *src)
+" args_pos = [ [8, 17], [20, 34] ]
+function! snippets#snipmate#add_snippet(fullname, args_pos)
+  " If we are already in a snipmate snippet, well not much we can do until snipmate supports nested snippets
+  if exists('g:snipPos')
+    return a:fullname
+  endif
+
+  let l:snip = ''
+  let l:prev_idx = 0
+  let l:snip_idx = 1
+  for elt in a:args_pos
+    let l:snip .= a:fullname[l:prev_idx : elt[0] - 1] . '${' . l:snip_idx . ':' . a:fullname[elt[0] : elt[1] - 1] . '}'
+    let l:snip_idx += 1
+    let l:prev_idx = elt[1]
+  endfor
+
+  let l:snip .= a:fullname[l:prev_idx : ] . '${' . l:snip_idx . '}'
+
+  let l:snippet_id = substitute(a:fullname, ' ', '_', 'g')
+
+  call MakeSnip(&filetype, l:snippet_id, l:snip)
+
+  return l:snippet_id
+endfunction
+
+function! snippets#snipmate#trigger()
+  " If we are already in a snipmate snippet, well not much we can do until snipmate supports nested snippets
+  if exists('g:snipPos')
+    return
+  endif
+
+  " Trigger snipmate
+  call feedkeys("\<Tab>", 't')
+endfunction
+
+function! snippets#snipmate#reset()
+  " Quick & Easy way to prevent snippets to be added twice
+  " Ideally we should modify snipmate to be smarter about this
+  call ReloadSnippets(&filetype)
+endfunction
+
+" vim: set ts=2 sts=2 sw=2 expandtab :

File bundle/clang_complete/autoload/snippets/ultisnips.vim

+" clang_complete ultisnips's snippet generator
+" Author: Philippe Vaucher
+
+function! snippets#ultisnips#init()
+  call snippets#ultisnips#reset()
+endfunction
+
+" fullname = strcat(char *dest, const char *src)
+" args_pos = [ [8, 17], [20, 34] ]
+function! snippets#ultisnips#add_snippet(fullname, args_pos)
+  let l:snip = ''
+  let l:prev_idx = 0
+  let l:snip_idx = 1
+  for elt in a:args_pos
+    let l:snip .= a:fullname[l:prev_idx : elt[0] - 1] . '${' . l:snip_idx . ':' . a:fullname[elt[0] : elt[1] - 1] . '}'
+    let l:snip_idx += 1
+    let l:prev_idx = elt[1]
+  endfor
+
+  let l:snip .= a:fullname[l:prev_idx : ] . '${' . l:snip_idx . '}'
+
+  let l:snippet_id = substitute(a:fullname, ' ', '_', 'g')
+
+  call UltiSnips_AddSnippet(l:snippet_id, l:snip, a:fullname, 'i', &filetype)
+
+  return l:snippet_id
+endfunction
+
+function! snippets#ultisnips#trigger()
+  call UltiSnips_ExpandSnippet()
+endfunction
+
+function! snippets#ultisnips#reset()
+  python UltiSnips_Manager.reset()
+endfunction
+
+" vim: set ts=2 sts=2 sw=2 expandtab :

File bundle/clang_complete/bin/cc_args.py

+#!/usr/bin/env python
+#-*- coding: utf-8 -*-
+
+import os
+import sys
+
+CONFIG_NAME = ".clang_complete"
+
+def readConfiguration():
+  try:
+    f = open(CONFIG_NAME, "r")
+  except IOError:
+    return []
+
+  result = []
+  for line in f.readlines():
+    strippedLine = line.strip()
+    if len(strippedLine) > 0:
+      result += [strippedLine]
+  f.close()
+  return result
+
+def writeConfiguration(lines):
+  f = open(CONFIG_NAME, "w")
+  f.writelines(lines)
+  f.close()
+
+def parseArguments(arguments):
+  nextIsInclude = False
+  nextIsDefine = False
+  nextIsIncludeFile = False
+
+  includes = []
+  defines = []
+  include_file = []
+
+  for arg in arguments:
+    if nextIsInclude:
+      includes += [arg]
+      nextIsInclude = False
+    elif nextIsDefine:
+      defines += [arg]
+      nextIsDefine = False
+    elif nextIsIncludeFile:
+      include_file += [arg]
+      nextIsIncludeFile = False
+    elif arg == "-I":
+      nextIsInclude = True
+    elif arg == "-D":
+      nextIsDefine = True
+    elif arg[:2] == "-I":
+      includes += [arg[2:]]
+    elif arg[:2] == "-D":
+      defines += [arg[2:]]
+    elif arg == "-include":
+      nextIsIncludeFile = True
+
+  result = list(map(lambda x: "-I" + x, includes))
+  result.extend(map(lambda x: "-D" + x, defines))
+  result.extend(map(lambda x: "-include " + x, include_file))
+
+  return result
+
+def mergeLists(base, new):
+  result = list(base)
+  for newLine in new:
+    try:
+      result.index(newLine)
+    except ValueError:
+      result += [newLine]
+  return result
+
+configuration = readConfiguration()
+args = parseArguments(sys.argv)
+result = mergeLists(configuration, args)
+writeConfiguration(map(lambda x: x + "\n", result))
+
+
+import subprocess
+proc = subprocess.Popen(sys.argv[1:])
+ret = proc.wait()
+
+if ret is None:
+  sys.exit(1)
+sys.exit(ret)
+
+# vim: set ts=2 sts=2 sw=2 expandtab :

File bundle/clang_complete/doc/clang_complete.txt

+*clang_complete.txt*	For Vim version 7.3.  Last change: 2011 Jun 04
+
+
+		  clang_complete plugin documentation
+
+
+clang_complete plugin		      		*clang_complete*
+
+1. Description		|clang_complete-description|
+2. Completion kinds    	|clang_complete-compl_kinds|
+3. Configuration	|clang_complete-configuration|
+4. Options		|clang_complete-options|
+5. Known issues		|clang_complete-issues|
+6. PCH      		|clang_complete-pch|
+7. cc_args.py script	|clang_complete-cc_args|
+8. To do		|clang_complete-todo|
+9. FAQ			|clang_complete-faq|
+10. License		|clang_complete-license|
+
+Author: Xavier Deguillard <deguilx@gmail.com>	*clang_complete-author*
+
+==============================================================================
+1. Description 					*clang_complete-description*
+
+This plugin use clang for accurately completing C and C++ code.
+
+Note: This plugin is incompatible with omnicppcomplete due to the
+unconditionnaly set mapping done by omnicppcomplete. So don't forget to
+suppress it before using this plugin.
+
+==============================================================================
+2. Completion kinds    				*clang_complete-compl_kinds*
+
+Because libclang provides a lot of information about completion, there are
+some additional kinds of completion along with standard ones (see >
+ :help complete-items
+for details):
+ '+' - constructor
+ '~' - destructor
+ 'e' - enumerator constant
+ 'a' - parameter ('a' from "argument") of a function, method or template
+ 'u' - unknown or buildin type (int, float, ...)
+ 'n' - namespace or its alias
+ 'p' - template ('p' from "pattern")
+
+==============================================================================
+3. Configuration				*clang_complete-configuration*
+
+Each project can have a .clang_complete at his root, containing the compiler
+options. This is useful if you're using some non-standard include paths or
+need to specify particular architecture type, frameworks to use, path to
+precompiled headers, precompiler definitions etc.
+
+Compiler options should go on individual lines (multiple options on one line
+can work sometimes too, but since there are some not obvious conditions for
+that, it's better to have one option per line).
+
+Linking isn't performed during completion, so one doesn't need to specify any
+of linker arguments in .clang_complete file. They will lead to completion
+failure when using clang executable and will be completely ignored by
+libclang.
+
+Example .clang_complete file: >
+ -DDEBUG
+ -include ../config.h
+ -I../common
+ -I/usr/include/c++/4.5.3/
+ -I/usr/include/c++/4.5.3/x86_64-slackware-linux/
+<
+==============================================================================
+4. Options					*clang_complete-options*
+
+       				       	*clang_complete-auto_select*
+				       	*g:clang_auto_select*
+If equal to 0, nothing is selected.
+If equal to 1, automatically select the first entry in the popup menu, but
+without inserting it into the code.
+If equal to 2, automatically select the first entry in the popup menu, and
+insert it into the code.
+Default: 0
+
+       				       	*clang_complete-complete_auto*
+       				       	*g:clang_complete_auto*
+If equal to 1, automatically complete after ->, ., ::
+Default: 1
+
+       				       	*clang_complete-copen*
+       				       	*g:clang_complete_copen*
+If equal to 1, open quickfix window on error.
+Default: 0
+
+       				       	*clang_complete-hl_errors*
+       				       	*g:clang_hl_errors*
+If equal to 1, it will highlight the warnings and errors the same way clang
+does it.
+Default: 1
+
+       				       	*clang_complete-periodic_quickfix*
+       				       	*g:clang_periodic_quickfix*
+If equal to 1, it will periodically update the quickfix window.
+Default: 0
+Note: You could use the g:ClangUpdateQuickFix() to do the same with a mapping.
+
+       				       	*clang_complete-snippets*
+       				       	*g:clang_snippets*
+If equal to 1, it will do some snippets magic after a ( or a , inside function
+call. Not currently fully working.
+Default: 0
+
+				       	*clang_complete-snippets_engine*
+				       	*g:clang_snippets_engine*
+The snippets engine (clang_complete, snipmate, ultisnips... see the snippets
+subdirectory).
+Default: "clang_complete"
+
+       				       	*clang_complete-conceal_snippets*
+       				       	*g:clang_conceal_snippets*
+If equal to 1, vim will use vim 7.3 conceal feature to hide <# and #> which
+delimit a snippets.
+Default: 1 (0 if conceal not available)
+Note: See concealcursor and conceallevel for conceal configuration.
+
+       				       	*clang_close-preview*
+       				       	*g:clang_close_preview*
+If equal to 1, the preview window will be close automatically after a
+completion.
+Default: 0
+
+       				       	*clang_complete-exec*
+       				       	*g:clang_exec*
+Name or path of clang executable.
+Note: Use this if clang has a non-standard name, or isn't in the path.
+Default: "clang"
+
+       				      	*clang_complete-user_options*
+       				       	*g:clang_user_options*
+Option added at the end of clang command. Useful if you want to filter the
+result, or do other stuffs. To ignore the error code returned by clang, set
+|g:clang_exec| to `"clang` and |g:clang_user_options| to `2>/dev/null || exit
+0"` if you're on *nix, or `2>NUL || exit 0"` if you are on windows.
+Default: ""
+
+       				       	*clang_complete-auto_user_options*
+       				       	*g:clang_auto_user_options*
+Set sources for user options passed to clang. Available sources are:
+- path - use &path content as list of include directories (relative paths are
+  ignored);
+- .clang_complete - use information from .clang_complete file Multiple options
+  are separated by comma;
+- {anything} else will be treaded as a custom option source in the following
+  manner: clang_complete will try to load autoload-function named
+  getopts#{anything}#getopts, which then will be able to modify
+  b:clang_user_options variable. See help on |autoload| if you don't know
+  what it is.
+  
+An example of custom option sources is bundled with clang_complete and called
+"gcc". This source runs gcc to get a list of include paths. The list of
+include paths for each of supported filetypes (c, cpp, objc and objcpp) is
+cached on a disk and can be removed by calling ClearGCCIncludeCaches()
+function (for changes to take affect one needs to reread buffers using the
+:edit command or something equivalent).
+Default: "path, .clang_complete, gcc"
+
+       				       	*clang_complete-use_library*
+       				       	*g:clang_use_library*
+Instead of calling the clang/clang++ tool use libclang directly. This gives
+access to many more clang features. Furthermore it automatically caches all
+includes in memory. Updates after changes in the same file will therefore be a
+lot faster.
+Default: 0
+
+       				       	*clang_complete-library_path*
+       				       	*g:clang_library_path*
+If libclang.[dll/so/dylib] is not in your library search path, set this to the
+absolute path where libclang is available.
+Default: ""
+
+					*clang_complete-sort_algo*
+					*g:clang_sort_algo*
+How results are sorted (alpha, priority, none). Currently only works with
+libclang.
+Default: "priority"
+
+					*clang_complete-complete_macros*
+					*g:clang_complete_macros*
+If clang should complete preprocessor macros and constants.
+Default: 0
+
+					*clang_complete-complete_patterns*
+					*g:clang_complete_patterns*
+If clang should complete code patterns, i.e loop constructs etc.
+Defaut: 0
+
+==============================================================================
+5. Known issues					*clang_complete-issues*
+
+If you find that completion is slow, please read the |clang_complete-pch|
+section below.
+
+If you get following error message while trying to complete anything: >
+ E121: Undefined variable: b:should_overload
+it means that your version of Vim is too old (this is an old bug and it has
+been fixed with one of patches for Vim 7.2) and you need to update it.
+
+If clang is not able to compile your file, it cannot complete anything. Since
+clang is not supporting every C++0x features, this is normal if it can do any
+completion on C++0x file.
+
+There is no difference in clang's output between private methods/members and
+public ones. Which means that I cannot filter private methods on the
+completion list.
+
+==============================================================================
+6. PCH      					*clang_complete-pch*
+
+In case you can not or you do not want to install libclang, a precompiled
+header file is another way to accelerate compilation, and so, to accelerate
+the completion. It is however more complicated to install and is still slower
+than the use of libclang.
+
+Here is how to create the <vector> pch, on linux (OSX users may use
+-fnext-runtime instead of -fgnu-runtime): >
+ clang -x c++-header /path/to/c++/vector -fno-exceptions -fgnu-runtime \
+    -o vector.pch
+You just have to insert it into your .clang_complete: >
+ echo '-include-pch /path/to/vector.pch -fgnu-runtime' >> .clang_complete
+<
+One of the major problem is that you cannot include more that one pch, the
+solution is to put the system headers or non changing headers into another
+header and then compile it to pch: >
+ echo '#include <iostream>\n#include <vector>' > pchheader.h
+ clang -x c++-header ./pchheader.h -fno-exceptions -fnu-runtime \
+    -o ./pchheader.pch
+And then add it to the .clang_complete file.
+
+==============================================================================
+7. cc_args.py script				*clang_complete-cc_args*
+
+This script, installed at ~/.vim/bin/cc_args.py, could be used to generate or
+update the .clang_complete file. It works similar to gccsence's gccrec and
+simply stores -I and -D arguments passed to the compiler in the
+.clang_complete file.  Just add the cc_args.py script as the first argument of
+the compile command. You should do that every time compile options have
+changed.
+
+Example (we need -B flag to force compiling even if project is up to date): >
+ make CC='~/.vim/bin/cc_args.py gcc' CXX='~/.vim/bin/cc_args.py g++' -B
+After running this command, .clang_complete will be created or updated with
+new options. If you don't want to update an existing configuration file,
+delete it before running make.
+
+==============================================================================
+8. To do						*clang_complete-todo*
+
+- Write some unit tests
+  - clang vs libclang accuracy for complex completions
+  - clang vs libclang timing
+- Explore "jump to declaration/definition" with libclang FGJ
+- Think about supertab (<C-X><C-U> with supertab and clang_auto_select)
+- Parse fix-its and do something useful with it
+
+==============================================================================
+9. FAQ						*clang_complete-faq*
+
+*) clang_complete doesn't work! I always get the message "pattern not found".
+
+This can have multiple reasons. You can try to open the quickfix window
+(:copen) that displays the error messages from clang to get a better idea what
+goes on. It might be that you need to update your .clang_complete file. If
+this does not help, keep in mind that clang_complete can cause clang to search
+for header files first in the system-wide paths and then in the ones specified
+locally in .clang_complete. Therefore you might have to add "-nostdinc" and
+the system include paths in the right order to .clang_complete.
+
+*) Only function names get completed but not the parentheses/parameters.
+
+Enable the snippets-support by adding the following lines to your .vimrc,
+for example:
+
+let g:clang_snippets = 1
+let g:clang_snippets_engine = 'clang_complete'
+
+If you have snipmate installed, you can use
+
+let g:clang_snippets = 1
+let g:clang_snippets_engine = 'snipmate'
+
+instead. After a completetion you can use <Tab> in normal mode to jump to the
+next parameter.
+
+*) Can I configure clang_complete to insert the text automatically when there
+   is only one possibility?
+
+You can configure vim to complete automatically the longest common match by 
+adding the following line to your vimrc:
+
+set completeopt=menu,longest
+
+==============================================================================
+10. License					*clang_complete-license*
+
+Copyright (c) 2010, 2011, Xavier Deguillard
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in the
+      documentation and/or other materials provided with the distribution.
+    * Neither the name of Xavier Deguillard nor the
+      names of its contributors may be used to endorse or promote products
+      derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL XAVIER DEGUILLARD BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Note: This license does not cover the files that come from the LLVM project,
+namely, cindex.py and __init__.py, which are covered by the LLVM license.
+
+ vim:tw=78:ts=8:ft=help:norl:

File bundle/clang_complete/examples/boost.cpp

+#include <cstdlib>
+#include <iostream>
+
+#include <boost/asio.hpp>
+#include <boost/bind.hpp>
+#include <boost/array.hpp>
+#include <boost/signal.hpp>
+#include <boost/function.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/noncopyable.hpp>
+#include <boost/aligned_storage.hpp>
+#include <boost/enable_shared_from_this.hpp>
+
+int main()
+{
+	boost::matc
+	//     ^ Code complete here by typing ":"
+}

File bundle/clang_complete/plugin/clang/__init__.py

+#===- __init__.py - Clang Python Bindings --------------------*- python -*--===#
+#
+#                     The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+#===------------------------------------------------------------------------===#
+
+r"""
+Clang Library Bindings
+======================
+
+This package provides access to the Clang compiler and libraries.
+
+The available modules are:
+
+  cindex
+
+    Bindings for the Clang indexing library.
+"""
+
+__all__ = ['cindex']
+

File bundle/clang_complete/plugin/clang/cindex.py

+#===- cindex.py - Python Indexing Library Bindings -----------*- python -*--===#
+#
+#                     The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+#===------------------------------------------------------------------------===#
+
+r"""
+Clang Indexing Library Bindings
+===============================
+
+This module provides an interface to the Clang indexing library. It is a
+low-level interface to the indexing library which attempts to match the Clang
+API directly while also being "pythonic". Notable differences from the C API
+are:
+
+ * string results are returned as Python strings, not CXString objects.
+
+ * null cursors are translated to None.
+
+ * access to child cursors is done via iteration, not visitation.
+
+The major indexing objects are:
+
+  Index
+
+    The top-level object which manages some global library state.
+
+  TranslationUnit
+
+    High-level object encapsulating the AST for a single translation unit. These
+    can be loaded from .ast files or parsed on the fly.
+
+  Cursor
+
+    Generic object for representing a node in the AST.
+
+  SourceRange, SourceLocation, and File
+
+    Objects representing information about the input source.
+
+Most object information is exposed using properties, when the underlying API
+call is efficient.
+"""
+
+# TODO
+# ====
+#
+# o API support for invalid translation units. Currently we can't even get the
+#   diagnostics on failure because they refer to locations in an object that
+#   will have been invalidated.
+#
+# o fix memory management issues (currently client must hold on to index and
+#   translation unit, or risk crashes).
+#
+# o expose code completion APIs.
+#
+# o cleanup ctypes wrapping, would be nice to separate the ctypes details more
+#   clearly, and hide from the external interface (i.e., help(cindex)).
+#
+# o implement additional SourceLocation, SourceRange, and File methods.
+
+import sys
+from ctypes import *
+
+def get_cindex_library():
+    # FIXME: It's probably not the case that the library is actually found in
+    # this location. We need a better system of identifying and loading the
+    # CIndex library. It could be on path or elsewhere, or versioned, etc.
+    import platform
+    name = platform.system()
+    path = sys.argv[0]
+    if path != '':
+        path += '/'
+    if name == 'Darwin':
+        path += 'libclang.dylib'
+    elif name == 'Windows':
+        path += 'libclang.dll'
+    else:
+        path += 'libclang.so'
+    return cdll.LoadLibrary(path)
+
+# ctypes doesn't implicitly convert c_void_p to the appropriate wrapper
+# object. This is a problem, because it means that from_parameter will see an
+# integer and pass the wrong value on platforms where int != void*. Work around
+# this by marshalling object arguments as void**.
+c_object_p = POINTER(c_void_p)
+
+lib = get_cindex_library()
+
+### Structures and Utility Classes ###
+
+class _CXString(Structure):
+    """Helper for transforming CXString results."""
+
+    _fields_ = [("spelling", c_char_p), ("free", c_int)]
+
+    def __del__(self):
+        _CXString_dispose(self)
+
+    @staticmethod
+    def from_result(res, fn, args):
+        assert isinstance(res, _CXString)
+        return _CXString_getCString(res)
+
+class SourceLocation(Structure):
+    """
+    A SourceLocation represents a particular location within a source file.
+    """
+    _fields_ = [("ptr_data", c_void_p * 2), ("int_data", c_uint)]
+    _data = None
+
+    def _get_instantiation(self):
+        if self._data is None:
+            f, l, c, o = c_object_p(), c_uint(), c_uint(), c_uint()
+            SourceLocation_loc(self, byref(f), byref(l), byref(c), byref(o))
+            if f:
+                f = File(f)
+            else:
+                f = None
+            self._data = (f, int(l.value), int(c.value), int(o.value))
+        return self._data
+
+    @staticmethod
+    def from_position(tu, file, line, column):
+        """
+        Retrieve the source location associated with a given file/line/column in
+        a particular translation unit.
+        """
+        return SourceLocation_getLocation(tu, file, line, column)
+
+    @property
+    def file(self):
+        """Get the file represented by this source location."""
+        return self._get_instantiation()[0]
+
+    @property
+    def line(self):
+        """Get the line represented by this source location."""
+        return self._get_instantiation()[1]
+
+    @property
+    def column(self):
+        """Get the column represented by this source location."""
+        return self._get_instantiation()[2]
+
+    @property
+    def offset(self):
+        """Get the file offset represented by this source location."""
+        return self._get_instantiation()[3]
+
+    def __repr__(self):
+        if self.file:
+            filename = self.file.name
+        else:
+            filename = None
+        return "<SourceLocation file %r, line %r, column %r>" % (
+            filename, self.line, self.column)
+
+class SourceRange(Structure):
+    """
+    A SourceRange describes a range of source locations within the source
+    code.
+    """
+    _fields_ = [
+        ("ptr_data", c_void_p * 2),
+        ("begin_int_data", c_uint),
+        ("end_int_data", c_uint)]
+
+    # FIXME: Eliminate this and make normal constructor? Requires hiding ctypes
+    # object.
+    @staticmethod
+    def from_locations(start, end):
+        return SourceRange_getRange(start, end)
+
+    @property
+    def start(self):
+        """
+        Return a SourceLocation representing the first character within a
+        source range.
+        """
+        return SourceRange_start(self)
+
+    @property
+    def end(self):
+        """
+        Return a SourceLocation representing the last character within a
+        source range.
+        """
+        return SourceRange_end(self)
+
+    def __repr__(self):
+        return "<SourceRange start %r, end %r>" % (self.start, self.end)
+
+class Diagnostic(object):
+    """
+    A Diagnostic is a single instance of a Clang diagnostic. It includes the
+    diagnostic severity, the message, the location the diagnostic occurred, as
+    well as additional source ranges and associated fix-it hints.
+    """
+
+    Ignored = 0
+    Note    = 1
+    Warning = 2
+    Error   = 3
+    Fatal   = 4
+
+    def __init__(self, ptr):
+        self.ptr = ptr
+
+    def __del__(self):
+        _clang_disposeDiagnostic(self)
+
+    @property
+    def severity(self):
+        return _clang_getDiagnosticSeverity(self)
+
+    @property
+    def location(self):
+        return _clang_getDiagnosticLocation(self)
+
+    @property
+    def spelling(self):
+        return _clang_getDiagnosticSpelling(self)
+
+    @property
+    def ranges(self):
+        class RangeIterator:
+            def __init__(self, diag):
+                self.diag = diag
+
+            def __len__(self):
+                return int(_clang_getDiagnosticNumRanges(self.diag))
+
+            def __getitem__(self, key):
+                if (key >= len(self)):
+                    raise IndexError
+                return _clang_getDiagnosticRange(self.diag, key)
+
+        return RangeIterator(self)
+
+    @property
+    def fixits(self):
+        class FixItIterator:
+            def __init__(self, diag):
+                self.diag = diag
+
+            def __len__(self):
+                return int(_clang_getDiagnosticNumFixIts(self.diag))
+
+            def __getitem__(self, key):
+                range = SourceRange()
+                value = _clang_getDiagnosticFixIt(self.diag, key, byref(range))
+                if len(value) == 0:
+                    raise IndexError
+
+                return FixIt(range, value)
+
+        return FixItIterator(self)
+
+    def __repr__(self):
+        return "<Diagnostic severity %r, location %r, spelling %r>" % (
+            self.severity, self.location, self.spelling)
+
+    def from_param(self):
+      return self.ptr
+
+class FixIt(object):
+    """
+    A FixIt represents a transformation to be applied to the source to
+    "fix-it". The fix-it shouldbe applied by replacing the given source range
+    with the given value.
+    """
+
+    def __init__(self, range, value):
+        self.range = range
+        self.value = value
+
+    def __repr__(self):
+        return "<FixIt range %r, value %r>" % (self.range, self.value)
+
+### Cursor Kinds ###
+
+class CursorKind(object):
+    """
+    A CursorKind describes the kind of entity that a cursor points to.
+    """
+
+    # The unique kind objects, indexed by id.
+    _kinds = []
+    _name_map = None
+
+    def __init__(self, value):
+        if value >= len(CursorKind._kinds):
+            CursorKind._kinds += [None] * (value - len(CursorKind._kinds) + 1)
+        if CursorKind._kinds[value] is not None:
+            raise ValueError,'CursorKind already loaded'
+        self.value = value
+        CursorKind._kinds[value] = self
+        CursorKind._name_map = None
+
+    def from_param(self):
+        return self.value
+
+    @property
+    def name(self):
+        """Get the enumeration name of this cursor kind."""
+        if self._name_map is None:
+            self._name_map = {}
+            for key,value in CursorKind.__dict__.items():
+                if isinstance(value,CursorKind):
+                    self._name_map[value] = key
+        return self._name_map[self]
+
+    @staticmethod
+    def from_id(id):
+        if id >= len(CursorKind._kinds) or CursorKind._kinds[id] is None:
+            raise ValueError,'Unknown cursor kind'
+        return CursorKind._kinds[id]
+
+    @staticmethod
+    def get_all_kinds():
+        """Return all CursorKind enumeration instances."""
+        return filter(None, CursorKind._kinds)
+
+    def is_declaration(self):
+        """Test if this is a declaration kind."""
+        return CursorKind_is_decl(self)
+
+    def is_reference(self):
+        """Test if this is a reference kind."""
+        return CursorKind_is_ref(self)
+
+    def is_expression(self):
+        """Test if this is an expression kind."""
+        return CursorKind_is_expr(self)
+
+    def is_statement(self):
+        """Test if this is a statement kind."""
+        return CursorKind_is_stmt(self)
+
+    def is_attribute(self):
+        """Test if this is an attribute kind."""
+        return CursorKind_is_attribute(self)
+
+    def is_invalid(self):
+        """Test if this is an invalid kind."""
+        return CursorKind_is_inv(self)
+
+    def __repr__(self):
+        return 'CursorKind.%s' % (self.name,)
+
+# FIXME: Is there a nicer way to expose this enumeration? We could potentially
+# represent the nested structure, or even build a class hierarchy. The main
+# things we want for sure are (a) simple external access to kinds, (b) a place
+# to hang a description and name, (c) easy to keep in sync with Index.h.
+
+###
+# Declaration Kinds
+
+# A declaration whose specific kind is not exposed via this interface.
+#
+# Unexposed declarations have the same operations as any other kind of
+# declaration; one can extract their location information, spelling, find their
+# definitions, etc. However, the specific kind of the declaration is not
+# reported.
+CursorKind.UNEXPOSED_DECL = CursorKind(1)
+
+# A C or C++ struct.
+CursorKind.STRUCT_DECL = CursorKind(2)
+
+# A C or C++ union.
+CursorKind.UNION_DECL = CursorKind(3)
+
+# A C++ class.
+CursorKind.CLASS_DECL = CursorKind(4)
+
+# An enumeration.
+CursorKind.ENUM_DECL = CursorKind(5)
+
+# A field (in C) or non-static data member (in C++) in a struct, union, or C++
+# class.
+CursorKind.FIELD_DECL = CursorKind(6)
+
+# An enumerator constant.
+CursorKind.ENUM_CONSTANT_DECL = CursorKind(7)
+
+# A function.
+CursorKind.FUNCTION_DECL = CursorKind(8)
+
+# A variable.
+CursorKind.VAR_DECL = CursorKind(9)
+
+# A function or method parameter.
+CursorKind.PARM_DECL = CursorKind(10)
+
+# An Objective-C @interface.
+CursorKind.OBJC_INTERFACE_DECL = CursorKind(11)
+
+# An Objective-C @interface for a category.
+CursorKind.OBJC_CATEGORY_DECL = CursorKind(12)
+
+# An Objective-C @protocol declaration.
+CursorKind.OBJC_PROTOCOL_DECL = CursorKind(13)
+
+# An Objective-C @property declaration.
+CursorKind.OBJC_PROPERTY_DECL = CursorKind(14)
+
+# An Objective-C instance variable.
+CursorKind.OBJC_IVAR_DECL = CursorKind(15)
+
+# An Objective-C instance method.
+CursorKind.OBJC_INSTANCE_METHOD_DECL = CursorKind(16)
+
+# An Objective-C class method.
+CursorKind.OBJC_CLASS_METHOD_DECL = CursorKind(17)
+
+# An Objective-C @implementation.
+CursorKind.OBJC_IMPLEMENTATION_DECL = CursorKind(18)
+
+# An Objective-C @implementation for a category.
+CursorKind.OBJC_CATEGORY_IMPL_DECL = CursorKind(19)