diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,18 @@
+{-
+Copyright 2014 Google Inc. All Rights Reserved.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-}
+
+import Distribution.Simple
+main = defaultMain
diff --git a/cbits/utils.h b/cbits/utils.h
new file mode 100644
--- /dev/null
+++ b/cbits/utils.h
@@ -0,0 +1,35 @@
+/*
+Copyright 2014 Google Inc. All Rights Reserved.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+typedef void (*haskell_visitor)(CXCursor*);
+
+// Macro that evaluates to a copy on the heap of the result of a given expression.
+#define ALLOC(__ALLOC_EXPR__) ({\
+  typeof (__ALLOC_EXPR__) __alloc_res__ = (__ALLOC_EXPR__);\
+  typeof (__ALLOC_EXPR__) *__alloc_ptr__ = malloc(sizeof(__alloc_res__));\
+  *__alloc_ptr__ = __alloc_res__;\
+  __alloc_ptr__;\
+  })
+
+// Traverse children using a haskell_visitor passed in as client_data.
+// The visitor gets a copy of the cursor on the heap and is responsible
+// for freeing it.
+static enum CXChildVisitResult visit_haskell(CXCursor cursor,
+                                             CXCursor parent,
+                                             CXClientData client_data) {
+  ((haskell_visitor) client_data)(ALLOC(cursor));
+  return CXChildVisit_Continue;
+};
diff --git a/clang-pure.cabal b/clang-pure.cabal
new file mode 100644
--- /dev/null
+++ b/clang-pure.cabal
@@ -0,0 +1,60 @@
+name:                  clang-pure
+version:               0.1.0.0
+synopsis:              Pure C++ code analysis with libclang
+description:
+  Pure C++ code analysis with libclang.
+  .
+  Refer to <http://clang.llvm.org/doxygen/group__CINDEX.html libclang's documentation> for usage.
+  In general, the naming scheme is @clang_getCursorType -> cursorType@, @CXCursor -> `Cursor`@.
+license:               Apache-2.0
+license-file:          LICENSE
+author:                Patrick Chilton
+maintainer:            chpatrick@gmail.com
+copyright:             Copyright 2014 Google Inc. All Rights Reserved.
+category:              Language
+build-type:            Simple
+-- extra-source-files:  
+cabal-version:         >=1.10
+extra-source-files:  cbits/utils.h
+
+source-repository head
+  type: git
+  location: https://github.com/chpatrick/clang-pure.git
+
+library
+  exposed-modules:     Language.C.Clang,
+                       Language.C.Clang.Cursor,
+                       Language.C.Clang.File,
+                       Language.C.Clang.Location,
+                       Language.C.Clang.Token,
+                       Language.C.Clang.TranslationUnit,
+                       Language.C.Clang.Type
+  other-modules:       Language.C.Clang.Internal.Context,
+                       Language.C.Clang.Internal.FFI,
+                       Language.C.Clang.Internal.Refs,
+                       Language.C.Clang.Internal.Types
+  default-extensions:  TypeFamilies,
+                       GeneralizedNewtypeDeriving,
+                       TemplateHaskell,
+                       QuasiQuotes,
+                       OverloadedStrings,
+                       LambdaCase,
+                       NamedFieldPuns,
+                       StandaloneDeriving,
+                       FlexibleContexts
+  build-depends:       base >=4.8 && <4.9,
+                       contravariant >= 1.3.3,
+                       inline-c >= 0.5.3.2,
+                       containers >= 0.5.6.2,
+                       template-haskell >= 2.10,
+                       vector >= 0.10.12,
+                       bytestring >= 0.10.6,
+                       stm >= 2.4.4
+  hs-source-dirs:      src/
+  build-tools:         hsc2hs
+  default-language:    Haskell2010
+  c-sources:           src/Language/C/Clang/Internal/FFI.c
+  include-dirs:        cbits/
+  cc-options:          -Wall
+  extra-libraries:     clang
+  ghc-options:         -Wall -O2
diff --git a/src/Language/C/Clang.hs b/src/Language/C/Clang.hs
new file mode 100644
--- /dev/null
+++ b/src/Language/C/Clang.hs
@@ -0,0 +1,48 @@
+{-
+Copyright 2014 Google Inc. All Rights Reserved.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-}
+
+module Language.C.Clang (
+  module C,
+  -- * Index
+  ClangIndex(),
+  createIndex,
+  -- * Utilities
+  Clang(),
+  ClangOrd(..)
+  ) where
+
+import Language.C.Clang.Cursor as C
+import Language.C.Clang.File as C
+import Language.C.Clang.Location as C
+import Language.C.Clang.Token as C
+import Language.C.Clang.TranslationUnit as C
+import Language.C.Clang.Type as C
+
+import Language.C.Clang.Internal.FFI
+import Language.C.Clang.Internal.Refs
+import Language.C.Clang.Internal.Types
+
+-- | The `Eq` instance for `Clang` types checks structural equality,
+-- i.e. whether they represent the same object in the translation unit.
+--
+-- Wrapping values in this type provides `Eq` and `Ord` instances based on reference equality.
+newtype ClangOrd a = ClangOrd { getOrdered :: a }
+
+instance Clang a => Eq (ClangOrd a) where
+  ClangOrd x == ClangOrd y = x `pointerEq` y
+
+instance Clang a => Ord (ClangOrd a) where
+  ClangOrd x `compare` ClangOrd y = x `pointerCompare` y
diff --git a/src/Language/C/Clang/Cursor.hs b/src/Language/C/Clang/Cursor.hs
new file mode 100644
--- /dev/null
+++ b/src/Language/C/Clang/Cursor.hs
@@ -0,0 +1,40 @@
+{-
+Copyright 2014 Google Inc. All Rights Reserved.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-}
+
+module Language.C.Clang.Cursor
+  ( Cursor()
+  , cursorTranslationUnit
+  , cursorChildrenF
+  , cursorChildren
+  , cursorSpelling
+  , cursorExtent
+  , cursorUSR
+  , cursorReferenced
+  , cursorType
+  , cursorKind
+  , CursorKind(..)
+  )
+where
+
+import Language.C.Clang.Internal.FFI
+import Language.C.Clang.Internal.Types
+
+import Control.Applicative
+import Data.Monoid
+
+cursorChildren :: Cursor -> [ Cursor ]
+cursorChildren
+  = (`appEndo` []) . getConst . cursorChildrenF (\c -> Const $ Endo (c:))
diff --git a/src/Language/C/Clang/File.hs b/src/Language/C/Clang/File.hs
new file mode 100644
--- /dev/null
+++ b/src/Language/C/Clang/File.hs
@@ -0,0 +1,25 @@
+{-
+Copyright 2014 Google Inc. All Rights Reserved.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-}
+
+module Language.C.Clang.File
+  ( File()
+  , getFile
+  , fileName
+  )
+where
+
+import Language.C.Clang.Internal.FFI
+import Language.C.Clang.Internal.Types
diff --git a/src/Language/C/Clang/Internal/Context.hs b/src/Language/C/Clang/Internal/Context.hs
new file mode 100644
--- /dev/null
+++ b/src/Language/C/Clang/Internal/Context.hs
@@ -0,0 +1,44 @@
+{-
+Copyright 2014 Google Inc. All Rights Reserved.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-}
+
+module Language.C.Clang.Internal.Context where
+
+import qualified Data.Map as M
+import Data.Monoid
+import qualified Language.C.Inline as C
+import qualified Language.C.Inline.Context as C
+import qualified Language.C.Types as C
+import qualified Language.Haskell.TH as TH
+
+import Language.C.Clang.Internal.Types
+
+clangTypesTable :: M.Map C.TypeSpecifier TH.TypeQ
+clangTypesTable = M.fromList
+  [ (C.TypeName "CXIndex", [t| CXIndex |])
+  , (C.TypeName "CXTranslationUnit", [t| CXTranslationUnit |])
+  , (C.TypeName "CXCursor", [t| CXCursor |])
+  , (C.TypeName "CXString", [t| CXString |])
+  , (C.TypeName "CXSourceRange", [t| CXSourceRange |])
+  , (C.TypeName "CXSourceLocation", [t| CXSourceLocation |])
+  , (C.TypeName "CXFile", [t| CXFile |])
+  , (C.TypeName "CXType", [t| CXType |])
+  , (C.TypeName "CXToken", [t| CXToken |])
+  ]
+
+clangCtx :: C.Context
+clangCtx = C.baseCtx <> C.funCtx <> C.vecCtx <> ctx
+  where
+    ctx = mempty { C.ctxTypesTable = clangTypesTable }
diff --git a/src/Language/C/Clang/Internal/FFI.c b/src/Language/C/Clang/Internal/FFI.c
new file mode 100644
--- /dev/null
+++ b/src/Language/C/Clang/Internal/FFI.c
@@ -0,0 +1,201 @@
+
+#include "stdlib.h"
+
+#include "clang-c/Index.h"
+
+#include "utils.h"
+
+CXIndex inline_c_Language_C_Clang_Internal_FFI_0_bbb74fcef49f2173e226e50e36672d4cf20c26cf() {
+return ( clang_createIndex(0, 1) );
+}
+
+
+int inline_c_Language_C_Clang_Internal_FFI_1_1b457d61428a48cbfcc276ae3010234ac1f6d4aa(CXIndex idxp_inline_c_0, char * cPath_inline_c_1, const char *const* cArgs_inline_c_2, long cArgs_inline_c_3, CXTranslationUnit * tupp_inline_c_4) {
+return (
+        clang_parseTranslationUnit2(
+          idxp_inline_c_0,
+          cPath_inline_c_1,
+          cArgs_inline_c_2, cArgs_inline_c_3,
+          NULL, 0,
+          0,
+          tupp_inline_c_4)
+        );
+}
+
+
+CXCursor * inline_c_Language_C_Clang_Internal_FFI_2_0a41a8f07961cb59fe1e6c0eff8cfa59bd837a75(CXTranslationUnit tup_inline_c_0) {
+return ( ALLOC(
+      clang_getTranslationUnitCursor(tup_inline_c_0)
+      ));
+}
+
+
+void inline_c_Language_C_Clang_Internal_FFI_3_26dd79d987cb18fd9b60848f6fef9651ea596325(CXCursor * cp_inline_c_0, void (* visitChild_inline_c_1)(CXCursor *)) {
+
+    clang_visitChildren(
+      *cp_inline_c_0,
+      visit_haskell,
+      visitChild_inline_c_1)
+    ;
+}
+
+
+const char * inline_c_Language_C_Clang_Internal_FFI_4_f0fd60d11137e5526d0d29649cf6a80152af4ee5(CXString * cxsp_inline_c_0) {
+return ( clang_getCString(*cxsp_inline_c_0) );
+}
+
+
+void inline_c_Language_C_Clang_Internal_FFI_5_aaa15c5f7cc155f34bd7888c71f492c421ec921f(CXString * cxsp_inline_c_0) {
+ clang_disposeString(*cxsp_inline_c_0) ;
+}
+
+
+void inline_c_Language_C_Clang_Internal_FFI_6_654625d7632bdac1227544395da0595f7f2bd246(CXString * cxsp_inline_c_0, CXCursor * cp_inline_c_1) {
+
+    *cxsp_inline_c_0 = clang_getCursorSpelling(*cp_inline_c_1);
+    
+}
+
+
+CXSourceRange * inline_c_Language_C_Clang_Internal_FFI_7_4a16e3c5ff5e0e56ede260ae320b6e3fcb519be8(CXCursor * cp_inline_c_0) {
+
+    CXSourceRange sr = clang_getCursorExtent(*cp_inline_c_0);
+    if (clang_Range_isNull(sr)) {
+      return NULL;
+    }
+
+    return ALLOC(sr);
+    
+}
+
+
+void inline_c_Language_C_Clang_Internal_FFI_8_654cc4d7a15ca22098e2b76991025bfea8e2a7c1(CXString * cxsp_inline_c_0, CXCursor * cp_inline_c_1) {
+
+    *cxsp_inline_c_0 = clang_getCursorUSR(*cp_inline_c_1);
+    
+}
+
+
+CXCursor * inline_c_Language_C_Clang_Internal_FFI_9_51239005fc283577baef0a3a25ccc32c163474ff(CXCursor * cp_inline_c_0) {
+
+    CXCursor ref = clang_getCursorReferenced(*cp_inline_c_0);
+    if (clang_Cursor_isNull(ref)) {
+      return NULL;
+    }
+
+    return ALLOC(ref);
+    
+}
+
+
+CXSourceLocation * inline_c_Language_C_Clang_Internal_FFI_10_01174c5fad196653eadc0d75887813449f7c6c44(CXSourceRange * srp_inline_c_0) {
+return ( ALLOC(
+    clang_getRangeStart(*srp_inline_c_0)
+    ));
+}
+
+
+CXSourceLocation * inline_c_Language_C_Clang_Internal_FFI_11_2506f272dc0f8ef468c4c127a2e3a5614300afbd(CXSourceRange * srp_inline_c_0) {
+return ( ALLOC(
+    clang_getRangeEnd(*srp_inline_c_0)
+    ));
+}
+
+
+void inline_c_Language_C_Clang_Internal_FFI_12_9be112e443ca74d8bc4c831343b6891c4295dcbc(CXSourceLocation * slp_inline_c_0, CXFile * fp_inline_c_1, unsigned * lp_inline_c_2, unsigned * cp_inline_c_3, unsigned * offp_inline_c_4) {
+
+      clang_getSpellingLocation(
+        *slp_inline_c_0,
+        fp_inline_c_1,
+        lp_inline_c_2,
+        cp_inline_c_3,
+        offp_inline_c_4)
+      ;
+}
+
+
+CXFile inline_c_Language_C_Clang_Internal_FFI_13_1dc5653d3b316566a228a71d6efa749cc40c291a(CXTranslationUnit tup_inline_c_0, const char * fn_inline_c_1) {
+return (
+    clang_getFile(tup_inline_c_0, fn_inline_c_1)
+    );
+}
+
+
+void inline_c_Language_C_Clang_Internal_FFI_14_b988619e4ed48ddcd0c83f2aa9e6177263942258(CXString * cxsp_inline_c_0, CXFile fp_inline_c_1) {
+
+    *cxsp_inline_c_0 = clang_getFileName(fp_inline_c_1);
+    
+}
+
+
+CXType * inline_c_Language_C_Clang_Internal_FFI_15_28d3d6c8bb9cdf93c0c25a3a8ea6431777e40068(CXCursor * cp_inline_c_0) {
+
+    CXType type = clang_getCursorType(*cp_inline_c_0);
+
+    if (type.kind == CXType_Invalid) {
+      return NULL;
+    }
+
+    return ALLOC(type);
+    
+}
+
+
+void inline_c_Language_C_Clang_Internal_FFI_16_ea90d6d14f81725ca6b378b32b5f0a8692cb183e(CXString * cxsp_inline_c_0, CXType * tp_inline_c_1) {
+ *cxsp_inline_c_0 = clang_getTypeSpelling(*tp_inline_c_1); ;
+}
+
+
+void inline_c_Language_C_Clang_Internal_FFI_17_ea0cc06208c508bf31fdb2025f7ab1764e2212ba(CXTranslationUnit tup_inline_c_0, CXSourceRange * srp_inline_c_1, CXToken ** tspp_inline_c_2, unsigned * tnp_inline_c_3) {
+
+          clang_tokenize(
+            tup_inline_c_0, 
+            *srp_inline_c_1,
+            tspp_inline_c_2,
+            tnp_inline_c_3);
+          ;
+}
+
+
+void inline_c_Language_C_Clang_Internal_FFI_18_565f5dad2370e065f27bdc06f712faa17fd7c3d4(CXString * cxsp_inline_c_0, CXTranslationUnit tup_inline_c_1, CXToken * tp_inline_c_2) {
+
+          *cxsp_inline_c_0 = clang_getTokenSpelling(
+            tup_inline_c_1,
+            *tp_inline_c_2);
+          
+}
+
+
+int inline_c_Language_C_Clang_Internal_FFI_19_75619e5975a8539d6a4f8a3f168e800a2f60e6be(CXSourceLocation * lp_inline_c_0) {
+return (
+    clang_Location_isInSystemHeader(*lp_inline_c_0)
+    );
+}
+
+
+int inline_c_Language_C_Clang_Internal_FFI_20_0dce75380f88691f9cf6d3de92251c770e071385(CXSourceLocation * lp_inline_c_0) {
+return (
+    clang_Location_isFromMainFile(*lp_inline_c_0)
+    );
+}
+
+
+int inline_c_Language_C_Clang_Internal_FFI_21_7c43b31e73b16206ea9c68efab47d1040d99de95(CXType * lp_inline_c_0, CXType * rp_inline_c_1) {
+return ( clang_equalTypes(*lp_inline_c_0, *rp_inline_c_1) );
+}
+
+
+int inline_c_Language_C_Clang_Internal_FFI_22_1dc05152878244ed78aba394ab8e0fefccda1dd7(CXSourceLocation * lp_inline_c_0, CXSourceLocation * rp_inline_c_1) {
+return ( clang_equalLocations(*lp_inline_c_0, *rp_inline_c_1) );
+}
+
+
+int inline_c_Language_C_Clang_Internal_FFI_23_51cac3d3c6607e337c0c1a424533416af56247d8(CXSourceRange * lp_inline_c_0, CXSourceRange * rp_inline_c_1) {
+return ( clang_equalRanges(*lp_inline_c_0, *rp_inline_c_1) );
+}
+
+
+int inline_c_Language_C_Clang_Internal_FFI_24_6edd96afecef70cb0090f782283f6f6a9cf124dc(CXCursor * lp_inline_c_0, CXCursor * rp_inline_c_1) {
+return ( clang_equalCursors(*lp_inline_c_0, *rp_inline_c_1) );
+}
+
diff --git a/src/Language/C/Clang/Internal/FFI.hsc b/src/Language/C/Clang/Internal/FFI.hsc
new file mode 100644
--- /dev/null
+++ b/src/Language/C/Clang/Internal/FFI.hsc
@@ -0,0 +1,608 @@
+{-
+Copyright 2014 Google Inc. All Rights Reserved.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-}
+
+{-# OPTIONS_GHC -fno-warn-orphans #-}
+
+module Language.C.Clang.Internal.FFI where
+
+import Data.ByteString (ByteString)
+import qualified Data.ByteString as BS
+import Control.Exception
+import Control.Monad
+import Data.Foldable
+import Data.Functor.Contravariant
+import Data.IORef
+import qualified Data.Vector.Storable as VS
+import Foreign
+import Foreign.C
+import qualified Language.C.Inline as C hiding (exp, block)
+import qualified Language.C.Inline as CSafe
+import qualified Language.C.Inline.Unsafe as C
+import System.IO.Unsafe
+
+import Language.C.Clang.Internal.Context
+import Language.C.Clang.Internal.Refs
+import Language.C.Clang.Internal.Types
+
+C.context clangCtx
+C.include "stdlib.h"
+#include  "clang-c/Index.h"
+C.include "clang-c/Index.h"
+C.include "utils.h"
+
+foreign import ccall "clang_disposeIndex"
+  clang_disposeIndex :: Ptr CXIndexImpl -> Finalizer
+
+createIndex :: IO ClangIndex
+createIndex = do
+  idxp <- [C.exp| CXIndex { clang_createIndex(0, 1) } |]
+  ClangIndex <$> newRoot idxp (clang_disposeIndex idxp)
+
+foreign import ccall "clang_disposeTranslationUnit"
+  clang_disposeTranslationUnit :: Ptr CXTranslationUnitImpl -> Finalizer
+
+data ClangError
+  = Success
+  | Failure
+  | Crashed
+  | InvalidArguments
+  | ASTReadError
+  deriving (Eq, Ord, Show)
+
+parseClangError :: CInt -> ClangError
+parseClangError = \case
+  #{const CXError_Success} -> Success
+  #{const CXError_Failure} -> Failure
+  #{const CXError_Crashed} -> Crashed
+  #{const CXError_InvalidArguments} -> InvalidArguments
+  #{const CXError_ASTReadError} -> ASTReadError
+  _ -> Failure -- unrecognized enum value
+
+instance Exception ClangError
+
+parseTranslationUnit :: ClangIndex -> FilePath -> [ String ] -> IO TranslationUnit
+parseTranslationUnit idx path args = do
+  tun <- newNode idx $ \idxp ->
+    withCString path $ \cPath -> do
+      cArgs <- VS.fromList <$> traverse newCString args
+      ( tup, cres ) <- C.withPtr $ \tupp -> [C.exp| int {
+        clang_parseTranslationUnit2(
+          $(CXIndex idxp),
+          $(char* cPath),
+          $vec-ptr:(const char * const * cArgs), $vec-len:cArgs,
+          NULL, 0,
+          0,
+          $(CXTranslationUnit *tupp))
+        } |]
+      traverse_ free $ VS.toList cArgs
+      let res = parseClangError cres
+      when (res /= Success) $ throwIO res
+      return ( tup, clang_disposeTranslationUnit tup )
+  return $ TranslationUnitRef tun
+
+translationUnitCursor :: TranslationUnit -> Cursor
+translationUnitCursor tu = unsafePerformIO $ do
+  cn <- newLeaf tu $ \tup -> do
+    cp <- [C.exp| CXCursor* { ALLOC(
+      clang_getTranslationUnitCursor($(CXTranslationUnit tup))
+      )} |]
+    return ( cp, free cp )
+  return $ Cursor cn
+
+cursorTranslationUnit :: Cursor -> TranslationUnit
+cursorTranslationUnit (Cursor c) = parent c
+
+cursorKind :: Cursor -> CursorKind
+cursorKind c = uderef c $ fmap parseCursorKind . #peek CXCursor, kind
+
+-- | Fold over the children of a cursor in the `lens` sense.
+cursorChildrenF :: (Applicative f, Contravariant f) => (Cursor -> f Cursor) -> (Cursor -> f Cursor)
+cursorChildrenF f c = uderef c $ \cp -> do
+  -- initialize the "Fold state" with no effect
+  fRef <- newIORef $ phantom $ pure ()
+  let 
+    visitChild chp = do
+      ch <- newLeaf (cursorTranslationUnit c) $ \_ ->
+        return ( chp, free chp )
+        -- fold over the new cursor and update the "Fold state"
+      modifyIORef' fRef (*> f (Cursor ch))
+  [CSafe.exp| void {
+    clang_visitChildren(
+      *$(CXCursor *cp),
+      visit_haskell,
+      $fun:(void (*visitChild)(CXCursor*)))
+    } |]
+  readIORef fRef
+
+withCXString :: (Ptr CXString -> IO ()) -> IO ByteString
+withCXString f = allocaBytes (#size CXString) $ \cxsp -> do
+  f cxsp
+  cs <- [C.exp| const char * { clang_getCString(*$(CXString *cxsp)) } |]
+  s <- BS.packCString cs
+  [C.exp| void { clang_disposeString(*$(CXString *cxsp)) } |]
+  return s
+
+cursorSpelling :: Cursor -> ByteString
+cursorSpelling c = uderef c $ \cp -> withCXString $ \cxsp ->
+  [C.block| void {
+    *$(CXString *cxsp) = clang_getCursorSpelling(*$(CXCursor *cp));
+    } |]
+
+cursorExtent :: Cursor -> Maybe SourceRange
+cursorExtent c = uderef c $ \cp -> do
+  srp <- [C.block| CXSourceRange* {
+    CXSourceRange sr = clang_getCursorExtent(*$(CXCursor *cp));
+    if (clang_Range_isNull(sr)) {
+      return NULL;
+    }
+
+    return ALLOC(sr);
+    } |]
+  if srp == nullPtr
+    then return Nothing
+    else do
+      srn <- newLeaf (cursorTranslationUnit c) $ \_ ->
+        return ( srp, free srp )
+      return $ Just $ SourceRange srn
+
+cursorUSR :: Cursor -> ByteString
+cursorUSR c = uderef c $ \cp -> withCXString $ \cxsp ->
+  [C.block| void {
+    *$(CXString *cxsp) = clang_getCursorUSR(*$(CXCursor *cp));
+    } |]
+
+cursorReferenced :: Cursor -> Maybe Cursor
+cursorReferenced c = uderef c $ \cp -> do
+  rcp <- [C.block| CXCursor* {
+    CXCursor ref = clang_getCursorReferenced(*$(CXCursor *cp));
+    if (clang_Cursor_isNull(ref)) {
+      return NULL;
+    }
+
+    return ALLOC(ref);
+    } |]
+  if rcp /= nullPtr
+    then (Just . Cursor) <$> newLeaf (parent c) (\_ -> return ( rcp, free rcp ))
+    else return Nothing
+
+rangeStart, rangeEnd :: SourceRange -> SourceLocation
+rangeStart sr = uderef sr $ \srp -> do
+  slp <- [C.exp| CXSourceLocation* { ALLOC(
+    clang_getRangeStart(*$(CXSourceRange *srp))
+    )} |]
+  sln <- newLeaf (parent sr) $ \_ ->
+    return ( slp, free slp )
+  return $ SourceLocation sln
+
+rangeEnd sr = uderef sr $ \srp -> do
+  slp <- [C.exp| CXSourceLocation* { ALLOC(
+    clang_getRangeEnd(*$(CXSourceRange *srp))
+    )} |]
+  sln <- newLeaf (parent sr) $ \_ ->
+    return ( slp, free slp )
+  return $ SourceLocation sln
+
+spellingLocation :: SourceLocation -> Location
+spellingLocation sl = uderef sl $ \slp -> do
+  ( f, l, c, o ) <- C.withPtrs_ $ \( fp, lp, cp, offp ) ->
+    [C.exp| void {
+      clang_getSpellingLocation(
+        *$(CXSourceLocation *slp),
+        $(CXFile *fp),
+        $(unsigned int *lp),
+        $(unsigned int *cp),
+        $(unsigned int *offp))
+      } |]
+  fn <- newLeaf (parent sl) $ \_ -> return ( f, return () )
+  return $ Location
+    { file = File fn
+    , line = fromIntegral l
+    , column = fromIntegral c
+    , offset = fromIntegral o
+    }
+
+getFile :: TranslationUnit -> FilePath -> Maybe File
+getFile tu p = uderef tu $ \tup -> withCString p $ \fn -> do
+  fp <- [C.exp| CXFile {
+    clang_getFile($(CXTranslationUnit tup), $(const char *fn))
+    } |]
+  if fp == nullPtr
+    then return Nothing
+    else (Just . File) <$> newLeaf tu (\_ -> return ( fp, return () ))
+
+fileName :: File -> ByteString
+fileName f = uderef f $ \fp -> withCXString $ \cxsp ->
+  [C.block| void {
+    *$(CXString *cxsp) = clang_getFileName($(CXFile fp));
+    } |]
+
+instance Eq Cursor where
+  (==) = defaultEq $ \lp rp ->
+    [C.exp| int { clang_equalCursors(*$(CXCursor *lp), *$(CXCursor *rp)) } |]
+
+instance Eq SourceRange where
+  (==) = defaultEq $ \lp rp ->
+    [C.exp| int { clang_equalRanges(*$(CXSourceRange *lp), *$(CXSourceRange *rp)) } |]
+
+instance Eq SourceLocation where
+  (==) = defaultEq $ \lp rp ->
+    [C.exp| int { clang_equalLocations(*$(CXSourceLocation *lp), *$(CXSourceLocation *rp)) } |]
+
+instance Eq Type where
+  (==) = defaultEq $ \lp rp ->
+    [C.exp| int { clang_equalTypes(*$(CXType *lp), *$(CXType *rp)) } |]
+
+-- Checks for pointer equality, alternatively checks for structural equality with the given function.
+defaultEq :: (Clang r, RefOf r ~ a) => (Ptr a -> Ptr a -> IO CInt) -> r -> r -> Bool
+defaultEq ne l r
+  = l `pointerEq` r || structEq
+    where
+      structEq =
+        unsafePerformIO $
+          deref l $ \p ->
+            deref r $ \p' ->
+              (/=0) <$> ne p p'
+
+parseCursorKind :: CInt -> CursorKind
+parseCursorKind = \case
+  #{const CXCursor_UnexposedDecl} -> UnexposedDecl
+  #{const CXCursor_StructDecl} -> StructDecl
+  #{const CXCursor_UnionDecl} -> UnionDecl
+  #{const CXCursor_ClassDecl} -> ClassDecl
+  #{const CXCursor_EnumDecl} -> EnumDecl
+  #{const CXCursor_FieldDecl} -> FieldDecl
+  #{const CXCursor_EnumConstantDecl} -> EnumConstantDecl
+  #{const CXCursor_FunctionDecl} -> FunctionDecl
+  #{const CXCursor_VarDecl} -> VarDecl
+  #{const CXCursor_ParmDecl} -> ParmDecl
+  #{const CXCursor_ObjCInterfaceDecl} -> ObjCInterfaceDecl
+  #{const CXCursor_ObjCCategoryDecl} -> ObjCCategoryDecl
+  #{const CXCursor_ObjCProtocolDecl} -> ObjCProtocolDecl
+  #{const CXCursor_ObjCPropertyDecl} -> ObjCPropertyDecl
+  #{const CXCursor_ObjCIvarDecl} -> ObjCIvarDecl
+  #{const CXCursor_ObjCInstanceMethodDecl} -> ObjCInstanceMethodDecl
+  #{const CXCursor_ObjCClassMethodDecl} -> ObjCClassMethodDecl
+  #{const CXCursor_ObjCImplementationDecl} -> ObjCImplementationDecl
+  #{const CXCursor_ObjCCategoryImplDecl} -> ObjCCategoryImplDecl
+  #{const CXCursor_TypedefDecl} -> TypedefDecl
+  #{const CXCursor_CXXMethod} -> CXXMethod
+  #{const CXCursor_Namespace} -> Namespace
+  #{const CXCursor_LinkageSpec} -> LinkageSpec
+  #{const CXCursor_Constructor} -> Constructor
+  #{const CXCursor_Destructor} -> Destructor
+  #{const CXCursor_ConversionFunction} -> ConversionFunction
+  #{const CXCursor_TemplateTypeParameter} -> TemplateTypeParameter
+  #{const CXCursor_NonTypeTemplateParameter} -> NonTypeTemplateParameter
+  #{const CXCursor_TemplateTemplateParameter} -> TemplateTemplateParameter
+  #{const CXCursor_FunctionTemplate} -> FunctionTemplate
+  #{const CXCursor_ClassTemplate} -> ClassTemplate
+  #{const CXCursor_ClassTemplatePartialSpecialization} -> ClassTemplatePartialSpecialization
+  #{const CXCursor_NamespaceAlias} -> NamespaceAlias
+  #{const CXCursor_UsingDirective} -> UsingDirective
+  #{const CXCursor_UsingDeclaration} -> UsingDeclaration
+  #{const CXCursor_TypeAliasDecl} -> TypeAliasDecl
+  #{const CXCursor_ObjCSynthesizeDecl} -> ObjCSynthesizeDecl
+  #{const CXCursor_ObjCDynamicDecl} -> ObjCDynamicDecl
+  #{const CXCursor_CXXAccessSpecifier} -> CXXAccessSpecifier
+  #{const CXCursor_FirstDecl} -> FirstDecl
+  #{const CXCursor_LastDecl} -> LastDecl
+  #{const CXCursor_FirstRef} -> FirstRef
+  #{const CXCursor_ObjCSuperClassRef} -> ObjCSuperClassRef
+  #{const CXCursor_ObjCProtocolRef} -> ObjCProtocolRef
+  #{const CXCursor_ObjCClassRef} -> ObjCClassRef
+  #{const CXCursor_TypeRef} -> TypeRef
+  #{const CXCursor_CXXBaseSpecifier} -> CXXBaseSpecifier
+  #{const CXCursor_TemplateRef} -> TemplateRef
+  #{const CXCursor_NamespaceRef} -> NamespaceRef
+  #{const CXCursor_MemberRef} -> MemberRef
+  #{const CXCursor_LabelRef} -> LabelRef
+  #{const CXCursor_OverloadedDeclRef} -> OverloadedDeclRef
+  #{const CXCursor_VariableRef} -> VariableRef
+  #{const CXCursor_LastRef} -> LastRef
+  #{const CXCursor_FirstInvalid} -> FirstInvalid
+  #{const CXCursor_InvalidFile} -> InvalidFile
+  #{const CXCursor_NoDeclFound} -> NoDeclFound
+  #{const CXCursor_NotImplemented} -> NotImplemented
+  #{const CXCursor_InvalidCode} -> InvalidCode
+  #{const CXCursor_LastInvalid} -> LastInvalid
+  #{const CXCursor_FirstExpr} -> FirstExpr
+  #{const CXCursor_UnexposedExpr} -> UnexposedExpr
+  #{const CXCursor_DeclRefExpr} -> DeclRefExpr
+  #{const CXCursor_MemberRefExpr} -> MemberRefExpr
+  #{const CXCursor_CallExpr} -> CallExpr
+  #{const CXCursor_ObjCMessageExpr} -> ObjCMessageExpr
+  #{const CXCursor_BlockExpr} -> BlockExpr
+  #{const CXCursor_IntegerLiteral} -> IntegerLiteral
+  #{const CXCursor_FloatingLiteral} -> FloatingLiteral
+  #{const CXCursor_ImaginaryLiteral} -> ImaginaryLiteral
+  #{const CXCursor_StringLiteral} -> StringLiteral
+  #{const CXCursor_CharacterLiteral} -> CharacterLiteral
+  #{const CXCursor_ParenExpr} -> ParenExpr
+  #{const CXCursor_UnaryOperator} -> UnaryOperator
+  #{const CXCursor_ArraySubscriptExpr} -> ArraySubscriptExpr
+  #{const CXCursor_BinaryOperator} -> BinaryOperator
+  #{const CXCursor_CompoundAssignOperator} -> CompoundAssignOperator
+  #{const CXCursor_ConditionalOperator} -> ConditionalOperator
+  #{const CXCursor_CStyleCastExpr} -> CStyleCastExpr
+  #{const CXCursor_CompoundLiteralExpr} -> CompoundLiteralExpr
+  #{const CXCursor_InitListExpr} -> InitListExpr
+  #{const CXCursor_AddrLabelExpr} -> AddrLabelExpr
+  #{const CXCursor_StmtExpr} -> StmtExpr
+  #{const CXCursor_GenericSelectionExpr} -> GenericSelectionExpr
+  #{const CXCursor_GNUNullExpr} -> GNUNullExpr
+  #{const CXCursor_CXXStaticCastExpr} -> CXXStaticCastExpr
+  #{const CXCursor_CXXDynamicCastExpr} -> CXXDynamicCastExpr
+  #{const CXCursor_CXXReinterpretCastExpr} -> CXXReinterpretCastExpr
+  #{const CXCursor_CXXConstCastExpr} -> CXXConstCastExpr
+  #{const CXCursor_CXXFunctionalCastExpr} -> CXXFunctionalCastExpr
+  #{const CXCursor_CXXTypeidExpr} -> CXXTypeidExpr
+  #{const CXCursor_CXXBoolLiteralExpr} -> CXXBoolLiteralExpr
+  #{const CXCursor_CXXNullPtrLiteralExpr} -> CXXNullPtrLiteralExpr
+  #{const CXCursor_CXXThisExpr} -> CXXThisExpr
+  #{const CXCursor_CXXThrowExpr} -> CXXThrowExpr
+  #{const CXCursor_CXXNewExpr} -> CXXNewExpr
+  #{const CXCursor_CXXDeleteExpr} -> CXXDeleteExpr
+  #{const CXCursor_UnaryExpr} -> UnaryExpr
+  #{const CXCursor_ObjCStringLiteral} -> ObjCStringLiteral
+  #{const CXCursor_ObjCEncodeExpr} -> ObjCEncodeExpr
+  #{const CXCursor_ObjCSelectorExpr} -> ObjCSelectorExpr
+  #{const CXCursor_ObjCProtocolExpr} -> ObjCProtocolExpr
+  #{const CXCursor_ObjCBridgedCastExpr} -> ObjCBridgedCastExpr
+  #{const CXCursor_PackExpansionExpr} -> PackExpansionExpr
+  #{const CXCursor_SizeOfPackExpr} -> SizeOfPackExpr
+  #{const CXCursor_LambdaExpr} -> LambdaExpr
+  #{const CXCursor_ObjCBoolLiteralExpr} -> ObjCBoolLiteralExpr
+  #{const CXCursor_ObjCSelfExpr} -> ObjCSelfExpr
+  #{const CXCursor_LastExpr} -> LastExpr
+  #{const CXCursor_FirstStmt} -> FirstStmt
+  #{const CXCursor_UnexposedStmt} -> UnexposedStmt
+  #{const CXCursor_LabelStmt} -> LabelStmt
+  #{const CXCursor_CompoundStmt} -> CompoundStmt
+  #{const CXCursor_CaseStmt} -> CaseStmt
+  #{const CXCursor_DefaultStmt} -> DefaultStmt
+  #{const CXCursor_IfStmt} -> IfStmt
+  #{const CXCursor_SwitchStmt} -> SwitchStmt
+  #{const CXCursor_WhileStmt} -> WhileStmt
+  #{const CXCursor_DoStmt} -> DoStmt
+  #{const CXCursor_ForStmt} -> ForStmt
+  #{const CXCursor_GotoStmt} -> GotoStmt
+  #{const CXCursor_IndirectGotoStmt} -> IndirectGotoStmt
+  #{const CXCursor_ContinueStmt} -> ContinueStmt
+  #{const CXCursor_BreakStmt} -> BreakStmt
+  #{const CXCursor_ReturnStmt} -> ReturnStmt
+  #{const CXCursor_GCCAsmStmt} -> GCCAsmStmt
+  #{const CXCursor_AsmStmt} -> AsmStmt
+  #{const CXCursor_ObjCAtTryStmt} -> ObjCAtTryStmt
+  #{const CXCursor_ObjCAtCatchStmt} -> ObjCAtCatchStmt
+  #{const CXCursor_ObjCAtFinallyStmt} -> ObjCAtFinallyStmt
+  #{const CXCursor_ObjCAtThrowStmt} -> ObjCAtThrowStmt
+  #{const CXCursor_ObjCAtSynchronizedStmt} -> ObjCAtSynchronizedStmt
+  #{const CXCursor_ObjCAutoreleasePoolStmt} -> ObjCAutoreleasePoolStmt
+  #{const CXCursor_ObjCForCollectionStmt} -> ObjCForCollectionStmt
+  #{const CXCursor_CXXCatchStmt} -> CXXCatchStmt
+  #{const CXCursor_CXXTryStmt} -> CXXTryStmt
+  #{const CXCursor_CXXForRangeStmt} -> CXXForRangeStmt
+  #{const CXCursor_SEHTryStmt} -> SEHTryStmt
+  #{const CXCursor_SEHExceptStmt} -> SEHExceptStmt
+  #{const CXCursor_SEHFinallyStmt} -> SEHFinallyStmt
+  #{const CXCursor_MSAsmStmt} -> MSAsmStmt
+  #{const CXCursor_NullStmt} -> NullStmt
+  #{const CXCursor_DeclStmt} -> DeclStmt
+  #{const CXCursor_OMPParallelDirective} -> OMPParallelDirective
+  #{const CXCursor_OMPSimdDirective} -> OMPSimdDirective
+  #{const CXCursor_OMPForDirective} -> OMPForDirective
+  #{const CXCursor_OMPSectionsDirective} -> OMPSectionsDirective
+  #{const CXCursor_OMPSectionDirective} -> OMPSectionDirective
+  #{const CXCursor_OMPSingleDirective} -> OMPSingleDirective
+  #{const CXCursor_OMPParallelForDirective} -> OMPParallelForDirective
+  #{const CXCursor_OMPParallelSectionsDirective} -> OMPParallelSectionsDirective
+  #{const CXCursor_OMPTaskDirective} -> OMPTaskDirective
+  #{const CXCursor_OMPMasterDirective} -> OMPMasterDirective
+  #{const CXCursor_OMPCriticalDirective} -> OMPCriticalDirective
+  #{const CXCursor_OMPTaskyieldDirective} -> OMPTaskyieldDirective
+  #{const CXCursor_OMPBarrierDirective} -> OMPBarrierDirective
+  #{const CXCursor_OMPTaskwaitDirective} -> OMPTaskwaitDirective
+  #{const CXCursor_OMPFlushDirective} -> OMPFlushDirective
+  #{const CXCursor_SEHLeaveStmt} -> SEHLeaveStmt
+  #{const CXCursor_LastStmt} -> LastStmt
+  #{const CXCursor_TranslationUnit} -> TranslationUnit
+  #{const CXCursor_FirstAttr} -> FirstAttr
+  #{const CXCursor_UnexposedAttr} -> UnexposedAttr
+  #{const CXCursor_IBActionAttr} -> IBActionAttr
+  #{const CXCursor_IBOutletAttr} -> IBOutletAttr
+  #{const CXCursor_IBOutletCollectionAttr} -> IBOutletCollectionAttr
+  #{const CXCursor_CXXFinalAttr} -> CXXFinalAttr
+  #{const CXCursor_CXXOverrideAttr} -> CXXOverrideAttr
+  #{const CXCursor_AnnotateAttr} -> AnnotateAttr
+  #{const CXCursor_AsmLabelAttr} -> AsmLabelAttr
+  #{const CXCursor_PackedAttr} -> PackedAttr
+  #{const CXCursor_PureAttr} -> PureAttr
+  #{const CXCursor_ConstAttr} -> ConstAttr
+  #{const CXCursor_NoDuplicateAttr} -> NoDuplicateAttr
+  #{const CXCursor_CUDAConstantAttr} -> CUDAConstantAttr
+  #{const CXCursor_CUDADeviceAttr} -> CUDADeviceAttr
+  #{const CXCursor_CUDAGlobalAttr} -> CUDAGlobalAttr
+  #{const CXCursor_CUDAHostAttr} -> CUDAHostAttr
+  #{const CXCursor_LastAttr} -> LastAttr
+  #{const CXCursor_PreprocessingDirective} -> PreprocessingDirective
+  #{const CXCursor_MacroDefinition} -> MacroDefinition
+  #{const CXCursor_MacroExpansion} -> MacroExpansion
+  #{const CXCursor_MacroInstantiation} -> MacroInstantiation
+  #{const CXCursor_InclusionDirective} -> InclusionDirective
+  #{const CXCursor_FirstPreprocessing} -> FirstPreprocessing
+  #{const CXCursor_LastPreprocessing} -> LastPreprocessing
+  #{const CXCursor_ModuleImportDecl} -> ModuleImportDecl
+  #{const CXCursor_FirstExtraDecl} -> FirstExtraDecl
+  #{const CXCursor_LastExtraDecl} -> LastExtraDecl
+  _ -> UnexposedDecl -- unrecognized enum value
+
+cursorType :: Cursor -> Maybe Type
+cursorType c = uderef c $ \cp -> do
+  tp <- [C.block| CXType* {
+    CXType type = clang_getCursorType(*$(CXCursor *cp));
+
+    if (type.kind == CXType_Invalid) {
+      return NULL;
+    }
+
+    return ALLOC(type);
+    } |]
+  if tp == nullPtr
+    then return Nothing
+    else (Just . Type) <$> newLeaf (parent c) (\_ -> return ( tp, free tp ))
+
+typeKind :: Type -> TypeKind
+typeKind t = uderef t $ fmap parseTypeKind . #peek CXType, kind
+
+parseTypeKind :: CInt -> TypeKind
+parseTypeKind = \case
+  #{const CXType_Invalid} -> Invalid
+  #{const CXType_Unexposed} -> Unexposed
+  #{const CXType_Void} -> Void
+  #{const CXType_Bool} -> Bool
+  #{const CXType_Char_U} -> Char_U
+  #{const CXType_UChar} -> UChar
+  #{const CXType_Char16} -> Char16
+  #{const CXType_Char32} -> Char32
+  #{const CXType_UShort} -> UShort
+  #{const CXType_UInt} -> UInt
+  #{const CXType_ULong} -> ULong
+  #{const CXType_ULongLong} -> ULongLong
+  #{const CXType_UInt128} -> UInt128
+  #{const CXType_Char_S} -> Char_S
+  #{const CXType_SChar} -> SChar
+  #{const CXType_WChar} -> WChar
+  #{const CXType_Short} -> Short
+  #{const CXType_Int} -> Int
+  #{const CXType_Long} -> Long
+  #{const CXType_LongLong} -> LongLong
+  #{const CXType_Int128} -> Int128
+  #{const CXType_Float} -> Float
+  #{const CXType_Double} -> Double
+  #{const CXType_LongDouble} -> LongDouble
+  #{const CXType_NullPtr} -> NullPtr
+  #{const CXType_Overload} -> Overload
+  #{const CXType_Dependent} -> Dependent
+  #{const CXType_ObjCId} -> ObjCId
+  #{const CXType_ObjCClass} -> ObjCClass
+  #{const CXType_ObjCSel} -> ObjCSel
+  #{const CXType_FirstBuiltin} -> FirstBuiltin
+  #{const CXType_LastBuiltin} -> LastBuiltin
+  #{const CXType_Complex} -> Complex
+  #{const CXType_Pointer} -> Pointer
+  #{const CXType_BlockPointer} -> BlockPointer
+  #{const CXType_LValueReference} -> LValueReference
+  #{const CXType_RValueReference} -> RValueReference
+  #{const CXType_Record} -> Record
+  #{const CXType_Enum} -> Enum
+  #{const CXType_Typedef} -> Typedef
+  #{const CXType_ObjCInterface} -> ObjCInterface
+  #{const CXType_ObjCObjectPointer} -> ObjCObjectPointer
+  #{const CXType_FunctionNoProto} -> FunctionNoProto
+  #{const CXType_FunctionProto} -> FunctionProto
+  #{const CXType_ConstantArray} -> ConstantArray
+  #{const CXType_Vector} -> Vector
+  #{const CXType_IncompleteArray} -> IncompleteArray
+  #{const CXType_VariableArray} -> VariableArray
+  #{const CXType_DependentSizedArray} -> DependentSizedArray
+  #{const CXType_MemberPointer} -> MemberPointer
+  _ -> Unexposed
+
+typeSpelling :: Type -> ByteString
+typeSpelling t = uderef t $ \tp ->
+  withCXString $ \cxsp ->
+    [C.exp| void { *$(CXString *cxsp) = clang_getTypeSpelling(*$(CXType *tp)); } |]
+
+instance Clang Token where
+  deref (Token ts i) f
+    = deref (tokenSetRef ts) $ f . (`plusPtr` (i * (#size CXToken)))
+  unsafeToPtr (Token ts i)
+     = unsafeToPtr (tokenSetRef ts) `plusPtr` (i * (#size CXToken))
+instance Child Token where
+  parent (Token ts _) = parent (tokenSetRef ts)
+
+foreign import ccall "clang_disposeTokens"
+  clang_disposeTokens :: CXTranslationUnit -> Ptr CXToken -> CUInt -> Finalizer
+
+tokenize :: SourceRange -> TokenSet
+tokenize sr = unsafePerformIO $
+  deref (parent sr) $ \tup ->
+    deref sr $ \srp -> do
+      ( tsp, tn ) <- C.withPtrs_ $ \( tspp, tnp ) ->
+        [C.exp| void {
+          clang_tokenize(
+            $(CXTranslationUnit tup), 
+            *$(CXSourceRange *srp),
+            $(CXToken **tspp),
+            $(unsigned int *tnp));
+          } |]
+      tsn <- newLeaf (parent sr) $ \_ ->
+        return ( tsp, clang_disposeTokens tup tsp tn )
+      return $ TokenSet tsn (fromIntegral tn)
+
+tokenSetTokens :: TokenSet -> [ Token ]
+tokenSetTokens ts
+  = map (Token ts) [0..tokenSetSize ts - 1]
+
+indexTokenSet :: TokenSet -> Int -> Token
+indexTokenSet ts i
+  | 0 <= i && i < tokenSetSize ts = Token ts i
+  | otherwise = error "Token index out of bounds."
+
+tokenSpelling :: Token -> ByteString
+tokenSpelling t = unsafePerformIO $
+  deref (parent t) $ \tup ->
+    deref t $ \tp ->
+      withCXString $ \cxsp -> do
+        [C.block| void {
+          *$(CXString *cxsp) = clang_getTokenSpelling(
+            $(CXTranslationUnit tup),
+            *$(CXToken *tp));
+          } |]
+
+isInSystemHeader :: SourceLocation -> Bool
+isInSystemHeader l = uderef l $ \lp ->
+  toBool <$> [C.exp| int {
+    clang_Location_isInSystemHeader(*$(CXSourceLocation *lp))
+    } |]
+
+isFromMainFile :: SourceLocation -> Bool
+isFromMainFile l = uderef l $ \lp ->
+  toBool <$> [C.exp| int {
+    clang_Location_isFromMainFile(*$(CXSourceLocation *lp))
+    } |]
+
+instance Show Cursor where
+  show c =
+    "Cursor { cursorKind = "
+    ++ show (cursorKind c)
+    ++ ", cursorSpelling = "
+    ++ show (cursorSpelling c)
+    ++ "}"
+
+instance Show Type where
+  show t =
+    "Type { typeKind = "
+    ++ show (typeKind t)
+    ++ ", typeSpelling = "
+    ++ show (typeSpelling t)
+    ++ "}"
+
+instance Show File where
+  show f =
+    "File { fileName = "
+    ++ show (fileName f)
+    ++ "}"
diff --git a/src/Language/C/Clang/Internal/Refs.hs b/src/Language/C/Clang/Internal/Refs.hs
new file mode 100644
--- /dev/null
+++ b/src/Language/C/Clang/Internal/Refs.hs
@@ -0,0 +1,119 @@
+{-
+Copyright 2014 Google Inc. All Rights Reserved.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-}
+
+module Language.C.Clang.Internal.Refs where
+
+import Control.Concurrent.MVar
+import GHC.ForeignPtr (unsafeForeignPtrToPtr)
+import Foreign hiding (newForeignPtr)
+import Foreign.Concurrent
+import System.IO.Unsafe
+
+type Finalizer = IO ()
+
+data NodeState = NodeState
+  { destructable :: !Bool
+  , refCount :: !Int
+  }
+
+type family RefOf n
+class Clang n where
+  deref :: n -> (Ptr (RefOf n) -> IO a) -> IO a
+  unsafeToPtr :: n -> Ptr (RefOf n)
+
+class Clang n => Parent n where
+  incCount :: n -> IO ()
+  decCount :: n -> IO ()
+
+type family ParentOf n
+class (Clang n, Parent (ParentOf n)) => Child n where
+  parent :: n -> ParentOf n
+
+data Root a = Root
+  { nodePtr :: ForeignPtr a
+  , nodeState :: MVar NodeState
+  , trueFinalize :: Finalizer
+  }
+
+newRoot :: Ptr a -> Finalizer -> IO (Root a)
+newRoot ptr fin = do
+  nsv <- newMVar $ NodeState { destructable = False, refCount = 0 }
+  nptr <- newForeignPtr ptr $ modifyMVar_ nsv $ \ns ->
+    if refCount ns == 0
+      then fin >> return ns
+      else return $ ns { destructable = True }
+  return $ Root nptr nsv fin
+
+instance Parent (Root a) where
+  incCount r = modifyMVar_ (nodeState r) $ \ns -> return ns { refCount = refCount ns + 1 }
+  decCount r = modifyMVar_ (nodeState r) $ \ns -> do
+    if refCount ns == 1 && destructable ns
+      then trueFinalize r >> return ns { refCount = 0, destructable = False }
+      else return ns { refCount = refCount ns - 1 }
+
+type instance RefOf (Root a) = a
+instance Clang (Root a) where
+  deref r = withForeignPtr (nodePtr r)
+  unsafeToPtr = unsafeForeignPtrToPtr . nodePtr
+
+data Node p a = Node p (Root a)
+
+newNode :: Parent p => p -> (Ptr (RefOf p) -> IO ( Ptr a, Finalizer )) -> IO (Node p a)
+newNode prn f = deref prn $ \pptr -> do
+  ( cptr, cfin ) <- f pptr
+  incCount prn
+  rt <- newRoot cptr (cfin >> decCount prn)
+  return $ Node prn rt
+
+instance Clang p => Parent (Node p a) where
+  incCount (Node _ n) = incCount n
+  decCount (Node _ n) = decCount n
+
+type instance ParentOf (Node p a) = p
+instance Parent p => Child (Node p a) where
+  parent (Node p _) = p
+
+type instance RefOf (Node p a) = a
+instance Clang p => Clang (Node p a) where
+  deref (Node p n) f = deref p $ \_ -> deref n f
+  unsafeToPtr (Node _ n) = unsafeToPtr n
+
+data Leaf p a = Leaf p (ForeignPtr a)
+
+newLeaf :: Parent p => p -> (Ptr (RefOf p) -> IO ( Ptr a, Finalizer )) -> IO (Leaf p a)
+newLeaf prn f = deref prn $ \pptr -> do
+    ( cptr, cfin ) <- f pptr
+    incCount prn
+    rt <- newForeignPtr cptr (cfin >> decCount prn)
+    return $ Leaf prn rt
+
+type instance ParentOf (Leaf p a) = p
+instance Parent p => Child (Leaf p a) where
+  parent (Leaf p _) = p
+
+type instance RefOf (Leaf p a) = a
+instance Clang p => Clang (Leaf p a) where
+  deref (Leaf p n) f = deref p $ \_ -> withForeignPtr n f
+  unsafeToPtr (Leaf _ n) = unsafeForeignPtrToPtr n
+
+pointerEq :: Clang n => n -> n -> Bool
+pointerEq r r' = unsafeToPtr r == unsafeToPtr r'
+
+pointerCompare :: Clang n => n -> n -> Ordering
+pointerCompare r r' = unsafeToPtr r `compare` unsafeToPtr r'
+
+uderef :: Clang r => r -> (Ptr (RefOf r) -> IO a) -> a
+uderef r f = unsafePerformIO $ deref r f
diff --git a/src/Language/C/Clang/Internal/Types.hs b/src/Language/C/Clang/Internal/Types.hs
new file mode 100644
--- /dev/null
+++ b/src/Language/C/Clang/Internal/Types.hs
@@ -0,0 +1,338 @@
+{-
+Copyright 2014 Google Inc. All Rights Reserved.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-}
+
+module Language.C.Clang.Internal.Types where
+
+import Foreign
+
+import Language.C.Clang.Internal.Refs
+
+data CXIndexImpl
+type CXIndex = Ptr CXIndexImpl
+type instance RefOf ClangIndex = CXIndexImpl
+newtype ClangIndex = ClangIndex (Root CXIndexImpl)
+  deriving (Parent, Clang)
+
+instance Eq ClangIndex where (==) = pointerEq
+
+data CXTranslationUnitImpl
+type CXTranslationUnit = Ptr CXTranslationUnitImpl
+type instance RefOf TranslationUnit = CXTranslationUnitImpl
+type instance ParentOf TranslationUnit = ClangIndex
+newtype TranslationUnit = TranslationUnitRef (Node ClangIndex CXTranslationUnitImpl)
+  deriving (Parent, Child, Clang)
+
+instance Eq TranslationUnit where (==) = pointerEq
+
+data CXCursor
+type instance RefOf Cursor = CXCursor
+type instance ParentOf Cursor = TranslationUnit
+newtype Cursor = Cursor (Leaf TranslationUnit CXCursor)
+  deriving (Child, Clang)
+
+data CXSourceRange
+type instance RefOf SourceRange = CXSourceRange
+type instance ParentOf SourceRange = TranslationUnit
+newtype SourceRange
+  = SourceRange (Leaf TranslationUnit CXSourceRange)
+  deriving (Child, Clang)
+
+data CXSourceLocation
+type instance RefOf SourceLocation = CXSourceLocation
+type instance ParentOf SourceLocation = TranslationUnit
+newtype SourceLocation
+  = SourceLocation (Leaf TranslationUnit CXSourceLocation)
+  deriving (Child, Clang)
+
+data CXFileImpl
+type CXFile = Ptr CXFileImpl
+type instance RefOf File = CXFileImpl
+type instance ParentOf File = TranslationUnit
+newtype File
+  = File (Leaf TranslationUnit CXFileImpl)
+  deriving (Child, Clang)
+
+instance Eq File where (==) = pointerEq
+
+data CXString
+
+data Location = Location
+  { file :: File
+  , line :: Word
+  , column :: Word
+  , offset :: Word
+  }
+
+data CursorKind
+  = UnexposedDecl
+  | StructDecl
+  | UnionDecl
+  | ClassDecl
+  | EnumDecl
+  | FieldDecl
+  | EnumConstantDecl
+  | FunctionDecl
+  | VarDecl
+  | ParmDecl
+  | ObjCInterfaceDecl
+  | ObjCCategoryDecl
+  | ObjCProtocolDecl
+  | ObjCPropertyDecl
+  | ObjCIvarDecl
+  | ObjCInstanceMethodDecl
+  | ObjCClassMethodDecl
+  | ObjCImplementationDecl
+  | ObjCCategoryImplDecl
+  | TypedefDecl
+  | CXXMethod
+  | Namespace
+  | LinkageSpec
+  | Constructor
+  | Destructor
+  | ConversionFunction
+  | TemplateTypeParameter
+  | NonTypeTemplateParameter
+  | TemplateTemplateParameter
+  | FunctionTemplate
+  | ClassTemplate
+  | ClassTemplatePartialSpecialization
+  | NamespaceAlias
+  | UsingDirective
+  | UsingDeclaration
+  | TypeAliasDecl
+  | ObjCSynthesizeDecl
+  | ObjCDynamicDecl
+  | CXXAccessSpecifier
+  | FirstDecl
+  | LastDecl
+  | FirstRef
+  | ObjCSuperClassRef
+  | ObjCProtocolRef
+  | ObjCClassRef
+  | TypeRef
+  | CXXBaseSpecifier
+  | TemplateRef
+  | NamespaceRef
+  | MemberRef
+  | LabelRef
+  | OverloadedDeclRef
+  | VariableRef
+  | LastRef
+  | FirstInvalid
+  | InvalidFile
+  | NoDeclFound
+  | NotImplemented
+  | InvalidCode
+  | LastInvalid
+  | FirstExpr
+  | UnexposedExpr
+  | DeclRefExpr
+  | MemberRefExpr
+  | CallExpr
+  | ObjCMessageExpr
+  | BlockExpr
+  | IntegerLiteral
+  | FloatingLiteral
+  | ImaginaryLiteral
+  | StringLiteral
+  | CharacterLiteral
+  | ParenExpr
+  | UnaryOperator
+  | ArraySubscriptExpr
+  | BinaryOperator
+  | CompoundAssignOperator
+  | ConditionalOperator
+  | CStyleCastExpr
+  | CompoundLiteralExpr
+  | InitListExpr
+  | AddrLabelExpr
+  | StmtExpr
+  | GenericSelectionExpr
+  | GNUNullExpr
+  | CXXStaticCastExpr
+  | CXXDynamicCastExpr
+  | CXXReinterpretCastExpr
+  | CXXConstCastExpr
+  | CXXFunctionalCastExpr
+  | CXXTypeidExpr
+  | CXXBoolLiteralExpr
+  | CXXNullPtrLiteralExpr
+  | CXXThisExpr
+  | CXXThrowExpr
+  | CXXNewExpr
+  | CXXDeleteExpr
+  | UnaryExpr
+  | ObjCStringLiteral
+  | ObjCEncodeExpr
+  | ObjCSelectorExpr
+  | ObjCProtocolExpr
+  | ObjCBridgedCastExpr
+  | PackExpansionExpr
+  | SizeOfPackExpr
+  | LambdaExpr
+  | ObjCBoolLiteralExpr
+  | ObjCSelfExpr
+  | LastExpr
+  | FirstStmt
+  | UnexposedStmt
+  | LabelStmt
+  | CompoundStmt
+  | CaseStmt
+  | DefaultStmt
+  | IfStmt
+  | SwitchStmt
+  | WhileStmt
+  | DoStmt
+  | ForStmt
+  | GotoStmt
+  | IndirectGotoStmt
+  | ContinueStmt
+  | BreakStmt
+  | ReturnStmt
+  | GCCAsmStmt
+  | AsmStmt
+  | ObjCAtTryStmt
+  | ObjCAtCatchStmt
+  | ObjCAtFinallyStmt
+  | ObjCAtThrowStmt
+  | ObjCAtSynchronizedStmt
+  | ObjCAutoreleasePoolStmt
+  | ObjCForCollectionStmt
+  | CXXCatchStmt
+  | CXXTryStmt
+  | CXXForRangeStmt
+  | SEHTryStmt
+  | SEHExceptStmt
+  | SEHFinallyStmt
+  | MSAsmStmt
+  | NullStmt
+  | DeclStmt
+  | OMPParallelDirective
+  | OMPSimdDirective
+  | OMPForDirective
+  | OMPSectionsDirective
+  | OMPSectionDirective
+  | OMPSingleDirective
+  | OMPParallelForDirective
+  | OMPParallelSectionsDirective
+  | OMPTaskDirective
+  | OMPMasterDirective
+  | OMPCriticalDirective
+  | OMPTaskyieldDirective
+  | OMPBarrierDirective
+  | OMPTaskwaitDirective
+  | OMPFlushDirective
+  | SEHLeaveStmt
+  | LastStmt
+  | TranslationUnit
+  | FirstAttr
+  | UnexposedAttr
+  | IBActionAttr
+  | IBOutletAttr
+  | IBOutletCollectionAttr
+  | CXXFinalAttr
+  | CXXOverrideAttr
+  | AnnotateAttr
+  | AsmLabelAttr
+  | PackedAttr
+  | PureAttr
+  | ConstAttr
+  | NoDuplicateAttr
+  | CUDAConstantAttr
+  | CUDADeviceAttr
+  | CUDAGlobalAttr
+  | CUDAHostAttr
+  | LastAttr
+  | PreprocessingDirective
+  | MacroDefinition
+  | MacroExpansion
+  | MacroInstantiation
+  | InclusionDirective
+  | FirstPreprocessing
+  | LastPreprocessing
+  | ModuleImportDecl
+  | FirstExtraDecl
+  | LastExtraDecl
+  deriving (Eq, Ord, Show)
+
+data TypeKind
+  = Invalid
+  | Unexposed
+  | Void
+  | Bool
+  | Char_U
+  | UChar
+  | Char16
+  | Char32
+  | UShort
+  | UInt
+  | ULong
+  | ULongLong
+  | UInt128
+  | Char_S
+  | SChar
+  | WChar
+  | Short
+  | Int
+  | Long
+  | LongLong
+  | Int128
+  | Float
+  | Double
+  | LongDouble
+  | NullPtr
+  | Overload
+  | Dependent
+  | ObjCId
+  | ObjCClass
+  | ObjCSel
+  | FirstBuiltin
+  | LastBuiltin
+  | Complex
+  | Pointer
+  | BlockPointer
+  | LValueReference
+  | RValueReference
+  | Record
+  | Enum
+  | Typedef
+  | ObjCInterface
+  | ObjCObjectPointer
+  | FunctionNoProto
+  | FunctionProto
+  | ConstantArray
+  | Vector
+  | IncompleteArray
+  | VariableArray
+  | DependentSizedArray
+  | MemberPointer
+    deriving (Eq, Ord, Show)
+
+data CXType
+type instance RefOf Type = CXType
+type instance ParentOf Type = TranslationUnit
+newtype Type = Type (Leaf TranslationUnit CXType)
+  deriving (Child, Clang)
+
+data CXToken
+data TokenSet = TokenSet
+  { tokenSetRef :: Leaf TranslationUnit CXToken
+  , tokenSetSize :: Int
+  }
+
+type instance RefOf Token = CXToken
+type instance ParentOf Token = TranslationUnit
+data Token = Token TokenSet Int
diff --git a/src/Language/C/Clang/Location.hs b/src/Language/C/Clang/Location.hs
new file mode 100644
--- /dev/null
+++ b/src/Language/C/Clang/Location.hs
@@ -0,0 +1,34 @@
+{-
+Copyright 2014 Google Inc. All Rights Reserved.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-}
+
+{-# OPTIONS_GHC -fno-warn-orphans #-}
+
+module Language.C.Clang.Location
+  ( SourceRange()
+  , rangeStart, rangeEnd
+  , SourceLocation()
+  , spellingLocation
+  , isInSystemHeader
+  , isFromMainFile
+  , Location(..)
+  )
+where
+
+import Language.C.Clang.Internal.FFI
+import Language.C.Clang.Internal.Types
+
+deriving instance Eq Location
+deriving instance Show Location
diff --git a/src/Language/C/Clang/Token.hs b/src/Language/C/Clang/Token.hs
new file mode 100644
--- /dev/null
+++ b/src/Language/C/Clang/Token.hs
@@ -0,0 +1,28 @@
+{-
+Copyright 2014 Google Inc. All Rights Reserved.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-}
+
+module Language.C.Clang.Token
+  ( TokenSet()
+  , Token()
+  , tokenize
+  , tokenSetTokens
+  , indexTokenSet
+  , tokenSpelling
+  )
+where
+
+import Language.C.Clang.Internal.FFI
+import Language.C.Clang.Internal.Types
diff --git a/src/Language/C/Clang/TranslationUnit.hs b/src/Language/C/Clang/TranslationUnit.hs
new file mode 100644
--- /dev/null
+++ b/src/Language/C/Clang/TranslationUnit.hs
@@ -0,0 +1,25 @@
+{-
+Copyright 2014 Google Inc. All Rights Reserved.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-}
+
+module Language.C.Clang.TranslationUnit
+  ( TranslationUnit()
+  , parseTranslationUnit
+  , translationUnitCursor
+  )
+where
+
+import Language.C.Clang.Internal.FFI
+import Language.C.Clang.Internal.Types
diff --git a/src/Language/C/Clang/Type.hs b/src/Language/C/Clang/Type.hs
new file mode 100644
--- /dev/null
+++ b/src/Language/C/Clang/Type.hs
@@ -0,0 +1,26 @@
+{-
+Copyright 2014 Google Inc. All Rights Reserved.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-}
+
+module Language.C.Clang.Type
+  ( Type()
+  , typeSpelling
+  , typeKind
+  , TypeKind(..)
+  )
+where
+
+import Language.C.Clang.Internal.FFI
+import Language.C.Clang.Internal.Types
