├── .gitignore ├── CONTRIBUTING ├── LICENSE ├── README ├── Setup.hs ├── cbits └── utils.h ├── clang-lens.cabal ├── examples ├── test.c └── test.hs └── src ├── Clang.hs └── Clang ├── Cursor.hs ├── File.hs ├── Internal ├── Context.hs ├── FFI.hsc ├── Refs.hs └── Types.hs ├── Location.hs ├── Token.hs ├── TranslationUnit.hs └── Type.hs /.gitignore: -------------------------------------------------------------------------------- 1 | dist/ 2 | src/**/*.c 3 | -------------------------------------------------------------------------------- /CONTRIBUTING: -------------------------------------------------------------------------------- 1 | Want to contribute? Great! First, read this page (including the small print at the end). 2 | 3 | ### Before you contribute 4 | Before we can use your code, you must sign the 5 | [Google Individual Contributor License Agreement](https://cla.developers.google.com/about/google-individual) 6 | (CLA), which you can do online. The CLA is necessary mainly because you own the 7 | copyright to your changes, even after your contribution becomes part of our 8 | codebase, so we need your permission to use and distribute your code. We also 9 | need to be sure of various other things—for instance that you'll tell us if you 10 | know that your code infringes on other people's patents. You don't have to sign 11 | the CLA until after you've submitted your code for review and a member has 12 | approved it, but you must do it before we can put your code into our codebase. 13 | Before you start working on a larger contribution, you should get in touch with 14 | us first through the issue tracker with your idea so that we can help out and 15 | possibly guide you. Coordinating up front makes it much easier to avoid 16 | frustration later on. 17 | 18 | ### Code reviews 19 | All submissions, including submissions by project members, require review. We 20 | use Github pull requests for this purpose. 21 | 22 | ### The small print 23 | Contributions made by corporations are covered by a different agreement than 24 | the one above, the 25 | [Software Grant and Corporate Contributor License Agreement](https://cla.developers.google.com/about/google-corporate). -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | Pure bindings to libclang 2 | ========================= 3 | 4 | A Haskell library for pure C++ code analysis with some light `lens` support. 5 | 6 | ``` 7 | gotoCount = lengthOf (allNodes . filtered (\c -> cursorKind c == GotoStmt)) root 8 | ``` 9 | 10 | *This is not an official Google product (experimental or otherwise), it is just code that happens to be owned by Google.* -------------------------------------------------------------------------------- /Setup.hs: -------------------------------------------------------------------------------- 1 | {- 2 | Copyright 2014 Google Inc. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | -} 16 | 17 | import Distribution.Simple 18 | main = defaultMain -------------------------------------------------------------------------------- /cbits/utils.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 Google Inc. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | typedef void (*haskell_visitor)(CXCursor*); 18 | 19 | // Macro that evaluates to a copy on the heap of the result of a given expression. 20 | #define ALLOC(__ALLOC_EXPR__) ({\ 21 | typeof (__ALLOC_EXPR__) __alloc_res__ = (__ALLOC_EXPR__);\ 22 | typeof (__ALLOC_EXPR__) *__alloc_ptr__ = malloc(sizeof(__alloc_res__));\ 23 | *__alloc_ptr__ = __alloc_res__;\ 24 | __alloc_ptr__;\ 25 | }) 26 | 27 | // Traverse children using a haskell_visitor passed in as client_data. 28 | // The visitor gets a copy of the cursor on the heap and is responsible 29 | // for freeing it. 30 | static enum CXChildVisitResult visit_haskell(CXCursor cursor, 31 | CXCursor parent, 32 | CXClientData client_data) { 33 | ((haskell_visitor) client_data)(ALLOC(cursor)); 34 | return CXChildVisit_Continue; 35 | }; 36 | -------------------------------------------------------------------------------- /clang-lens.cabal: -------------------------------------------------------------------------------- 1 | name: clang-lens 2 | version: 0.1.0.0 3 | synopsis: Pure read-only bindings to libclang 4 | description: 5 | Refer to for usage. 6 | In general, the naming scheme is @clang_getCursorType -> cursorType@, @CXCursor -> `Cursor`@. 7 | license: Apache-2.0 8 | license-file: LICENSE 9 | author: Patrick Chilton 10 | maintainer: chpatrick@gmail.com 11 | copyright: Copyright 2014 Google Inc. All Rights Reserved. 12 | category: Language 13 | build-type: Simple 14 | -- extra-source-files: 15 | cabal-version: >=1.10 16 | 17 | library 18 | exposed-modules: Clang, 19 | Clang.Cursor, 20 | Clang.File, 21 | Clang.Location, 22 | Clang.Token, 23 | Clang.TranslationUnit, 24 | Clang.Type 25 | other-modules: Clang.Internal.Context, 26 | Clang.Internal.FFI, 27 | Clang.Internal.Refs, 28 | Clang.Internal.Types 29 | default-extensions: TypeFamilies, 30 | GeneralizedNewtypeDeriving, 31 | TemplateHaskell, 32 | QuasiQuotes, 33 | OverloadedStrings, 34 | LambdaCase, 35 | NamedFieldPuns, 36 | StandaloneDeriving, 37 | FlexibleContexts 38 | build-depends: base >=4.8 && <4.9, 39 | contravariant >= 1.3.3, 40 | inline-c >= 0.5.3.2, 41 | containers >= 0.5.6.2, 42 | template-haskell >= 2.10, 43 | vector >= 0.10.12, 44 | bytestring >= 0.10.6, 45 | stm >= 2.4.4 46 | hs-source-dirs: src/ 47 | build-tools: hsc2hs 48 | default-language: Haskell2010 49 | c-sources: src/Clang/Internal/FFI.c 50 | include-dirs: /usr/lib/llvm-3.5/include cbits/ 51 | cc-options: -Wall 52 | ld-options: -lclang-3.5 53 | extra-libraries: clang-3.5 54 | ghc-options: -Wall -O2 55 | 56 | executable test 57 | hs-source-dirs: examples 58 | main-is: test.hs 59 | default-language: Haskell2010 60 | build-depends: base >= 4.8, clang-lens, lens, containers, bytestring -------------------------------------------------------------------------------- /examples/test.c: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2014 Google Inc. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #include "stdio.h" 18 | 19 | void foo() { 20 | lol: 21 | printf("%d", (2 + 2) + (2 * 2)); 22 | goto lol; 23 | } -------------------------------------------------------------------------------- /examples/test.hs: -------------------------------------------------------------------------------- 1 | {- 2 | Copyright 2014 Google Inc. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | -} 16 | 17 | {-# LANGUAGE PatternSynonyms, ViewPatterns, RankNTypes, LambdaCase, TupleSections #-} 18 | 19 | import Clang 20 | import Data.Foldable 21 | import Data.Function 22 | import Control.Lens 23 | import qualified Data.ByteString.Char8 as BS 24 | import Data.Monoid 25 | import Data.Tree 26 | import Data.Tree 27 | 28 | main = do 29 | idx <- createIndex 30 | tu <- parseTranslationUnit idx "examples/test.c" [] 31 | let 32 | root = translationUnitCursor tu 33 | funDecs = 34 | root ^.. 35 | cosmosOf cursorChildren 36 | . filtered (\c -> cursorKind c == FunctionDecl) 37 | . folding (\c -> ( cursorSpelling c, ) <$> (typeSpelling <$> cursorType c)) 38 | for_ funDecs $ \(f, t) -> putStrLn $ BS.unpack f ++ " :: " ++ BS.unpack t 39 | -------------------------------------------------------------------------------- /src/Clang.hs: -------------------------------------------------------------------------------- 1 | {- 2 | Copyright 2014 Google Inc. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | -} 16 | 17 | module Clang( 18 | module C, 19 | -- * Index 20 | ClangIndex(), 21 | createIndex, 22 | -- * Utilities 23 | Clang(), 24 | ClangOrd(..) 25 | ) where 26 | 27 | import Clang.Cursor as C 28 | import Clang.File as C 29 | import Clang.Location as C 30 | import Clang.Token as C 31 | import Clang.TranslationUnit as C 32 | import Clang.Type as C 33 | 34 | import Clang.Internal.FFI 35 | import Clang.Internal.Refs 36 | import Clang.Internal.Types 37 | 38 | -- | The `Eq` instance for `Clang` types checks structural equality, 39 | -- i.e. whether they represent the same object in the translation unit. 40 | -- 41 | -- Wrapping values in this type provides `Eq` and `Ord` instances based on reference equality. 42 | newtype ClangOrd a = ClangOrd { getOrdered :: a } 43 | 44 | instance Clang a => Eq (ClangOrd a) where 45 | ClangOrd x == ClangOrd y = x `pointerEq` y 46 | 47 | instance Clang a => Ord (ClangOrd a) where 48 | ClangOrd x `compare` ClangOrd y = x `pointerCompare` y -------------------------------------------------------------------------------- /src/Clang/Cursor.hs: -------------------------------------------------------------------------------- 1 | {- 2 | Copyright 2014 Google Inc. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | -} 16 | 17 | module Clang.Cursor 18 | ( Cursor() 19 | , cursorTranslationUnit 20 | , cursorChildren 21 | , cursorSpelling 22 | , cursorExtent 23 | , cursorUSR 24 | , cursorReferenced 25 | , cursorType 26 | , cursorKind 27 | , CursorKind(..) 28 | ) 29 | where 30 | 31 | import Clang.Internal.FFI 32 | import Clang.Internal.Types -------------------------------------------------------------------------------- /src/Clang/File.hs: -------------------------------------------------------------------------------- 1 | {- 2 | Copyright 2014 Google Inc. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | -} 16 | 17 | module Clang.File 18 | ( File() 19 | , getFile 20 | , fileName 21 | ) 22 | where 23 | 24 | import Clang.Internal.FFI 25 | import Clang.Internal.Types 26 | -------------------------------------------------------------------------------- /src/Clang/Internal/Context.hs: -------------------------------------------------------------------------------- 1 | {- 2 | Copyright 2014 Google Inc. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | -} 16 | 17 | module Clang.Internal.Context where 18 | 19 | import qualified Data.Map as M 20 | import Data.Monoid 21 | import qualified Language.C.Inline as C 22 | import qualified Language.C.Inline.Context as C 23 | import qualified Language.C.Types as C 24 | import qualified Language.Haskell.TH as TH 25 | 26 | import Clang.Internal.Types 27 | 28 | clangTypesTable :: M.Map C.TypeSpecifier TH.TypeQ 29 | clangTypesTable = M.fromList 30 | [ (C.TypeName "CXIndex", [t| CXIndex |]) 31 | , (C.TypeName "CXTranslationUnit", [t| CXTranslationUnit |]) 32 | , (C.TypeName "CXCursor", [t| CXCursor |]) 33 | , (C.TypeName "CXString", [t| CXString |]) 34 | , (C.TypeName "CXSourceRange", [t| CXSourceRange |]) 35 | , (C.TypeName "CXSourceLocation", [t| CXSourceLocation |]) 36 | , (C.TypeName "CXFile", [t| CXFile |]) 37 | , (C.TypeName "CXType", [t| CXType |]) 38 | , (C.TypeName "CXToken", [t| CXToken |]) 39 | ] 40 | 41 | clangCtx :: C.Context 42 | clangCtx = C.baseCtx <> C.funCtx <> C.vecCtx <> ctx 43 | where 44 | ctx = mempty { C.ctxTypesTable = clangTypesTable } 45 | -------------------------------------------------------------------------------- /src/Clang/Internal/FFI.hsc: -------------------------------------------------------------------------------- 1 | {- 2 | Copyright 2014 Google Inc. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | -} 16 | 17 | module Clang.Internal.FFI where 18 | 19 | import Data.ByteString (ByteString) 20 | import qualified Data.ByteString as BS 21 | import Control.Exception 22 | import Control.Monad 23 | import Data.Foldable 24 | import Data.Functor.Contravariant 25 | import Data.IORef 26 | import qualified Data.Vector.Storable as VS 27 | import Foreign 28 | import Foreign.C 29 | import qualified Language.C.Inline as C hiding (exp, block) 30 | import qualified Language.C.Inline as CSafe 31 | import qualified Language.C.Inline.Unsafe as C 32 | import System.IO.Unsafe 33 | 34 | import Clang.Internal.Context 35 | import Clang.Internal.Refs 36 | import Clang.Internal.Types 37 | 38 | C.context clangCtx 39 | C.include "stdlib.h" 40 | #include "clang-c/Index.h" 41 | C.include "clang-c/Index.h" 42 | C.include "utils.h" 43 | 44 | foreign import ccall "clang_disposeIndex" 45 | clang_disposeIndex :: Ptr CXIndexImpl -> Finalizer 46 | 47 | createIndex :: IO ClangIndex 48 | createIndex = do 49 | idxp <- [C.exp| CXIndex { clang_createIndex(0, 1) } |] 50 | ClangIndex <$> newRoot idxp (clang_disposeIndex idxp) 51 | 52 | foreign import ccall "clang_disposeTranslationUnit" 53 | clang_disposeTranslationUnit :: Ptr CXTranslationUnitImpl -> Finalizer 54 | 55 | data ClangError 56 | = Success 57 | | Failure 58 | | Crashed 59 | | InvalidArguments 60 | | ASTReadError 61 | deriving (Eq, Ord, Show) 62 | 63 | parseClangError :: CInt -> ClangError 64 | parseClangError = \case 65 | #{const CXError_Success} -> Success 66 | #{const CXError_Failure} -> Failure 67 | #{const CXError_Crashed} -> Crashed 68 | #{const CXError_InvalidArguments} -> InvalidArguments 69 | #{const CXError_ASTReadError} -> ASTReadError 70 | _ -> Failure -- unrecognized enum value 71 | 72 | instance Exception ClangError 73 | 74 | parseTranslationUnit :: ClangIndex -> FilePath -> [ String ] -> IO TranslationUnit 75 | parseTranslationUnit idx path args = do 76 | tun <- newNode idx $ \idxp -> 77 | withCString path $ \cPath -> do 78 | cArgs <- VS.fromList <$> traverse newCString args 79 | ( tup, cres ) <- C.withPtr $ \tupp -> [C.exp| int { 80 | clang_parseTranslationUnit2( 81 | $(CXIndex idxp), 82 | $(char* cPath), 83 | $vec-ptr:(const char * const * cArgs), $vec-len:cArgs, 84 | NULL, 0, 85 | 0, 86 | $(CXTranslationUnit *tupp)) 87 | } |] 88 | traverse_ free $ VS.toList cArgs 89 | let res = parseClangError cres 90 | when (res /= Success) $ throwIO res 91 | return ( tup, clang_disposeTranslationUnit tup ) 92 | return $ TranslationUnitRef tun 93 | 94 | translationUnitCursor :: TranslationUnit -> Cursor 95 | translationUnitCursor tu = unsafePerformIO $ do 96 | cn <- newLeaf tu $ \tup -> do 97 | cp <- [C.exp| CXCursor* { ALLOC( 98 | clang_getTranslationUnitCursor($(CXTranslationUnit tup)) 99 | )} |] 100 | return ( cp, free cp ) 101 | return $ Cursor cn 102 | 103 | cursorTranslationUnit :: Cursor -> TranslationUnit 104 | cursorTranslationUnit (Cursor c) = parent c 105 | 106 | cursorKind :: Cursor -> CursorKind 107 | cursorKind c = uderef c $ fmap parseCursorKind . #peek CXCursor, kind 108 | 109 | -- | Note: this is a @lens@ @Fold@. Use @toListOf@ to convert this into a function @Cursor -> [ Cursor ]@. 110 | cursorChildren :: (Applicative f, Contravariant f) => (Cursor -> f Cursor) -> (Cursor -> f Cursor) 111 | cursorChildren f c = uderef c $ \cp -> do 112 | -- initialize the "Fold state" with no effect 113 | fRef <- newIORef $ phantom $ pure () 114 | let 115 | visitChild chp = do 116 | ch <- newLeaf (cursorTranslationUnit c) $ \_ -> 117 | return ( chp, free chp ) 118 | -- fold over the new cursor and update the "Fold state" 119 | modifyIORef' fRef (*> f (Cursor ch)) 120 | [CSafe.exp| void { 121 | clang_visitChildren( 122 | *$(CXCursor *cp), 123 | visit_haskell, 124 | $fun:(void (*visitChild)(CXCursor*))) 125 | } |] 126 | readIORef fRef 127 | 128 | withCXString :: (Ptr CXString -> IO ()) -> IO ByteString 129 | withCXString f = allocaBytes (#size CXString) $ \cxsp -> do 130 | f cxsp 131 | cs <- [C.exp| const char * { clang_getCString(*$(CXString *cxsp)) } |] 132 | s <- BS.packCString cs 133 | [C.exp| void { clang_disposeString(*$(CXString *cxsp)) } |] 134 | return s 135 | 136 | cursorSpelling :: Cursor -> ByteString 137 | cursorSpelling c = uderef c $ \cp -> withCXString $ \cxsp -> 138 | [C.block| void { 139 | *$(CXString *cxsp) = clang_getCursorSpelling(*$(CXCursor *cp)); 140 | } |] 141 | 142 | cursorExtent :: Cursor -> Maybe SourceRange 143 | cursorExtent c = uderef c $ \cp -> do 144 | srp <- [C.block| CXSourceRange* { 145 | CXSourceRange sr = clang_getCursorExtent(*$(CXCursor *cp)); 146 | if (clang_Range_isNull(sr)) { 147 | return NULL; 148 | } 149 | 150 | return ALLOC(sr); 151 | } |] 152 | if srp == nullPtr 153 | then return Nothing 154 | else do 155 | srn <- newLeaf (cursorTranslationUnit c) $ \_ -> 156 | return ( srp, free srp ) 157 | return $ Just $ SourceRange srn 158 | 159 | cursorUSR :: Cursor -> ByteString 160 | cursorUSR c = uderef c $ \cp -> withCXString $ \cxsp -> 161 | [C.block| void { 162 | *$(CXString *cxsp) = clang_getCursorUSR(*$(CXCursor *cp)); 163 | } |] 164 | 165 | cursorReferenced :: Cursor -> Maybe Cursor 166 | cursorReferenced c = uderef c $ \cp -> do 167 | rcp <- [C.block| CXCursor* { 168 | CXCursor ref = clang_getCursorReferenced(*$(CXCursor *cp)); 169 | if (clang_Cursor_isNull(ref)) { 170 | return NULL; 171 | } 172 | 173 | return ALLOC(ref); 174 | } |] 175 | if rcp /= nullPtr 176 | then (Just . Cursor) <$> newLeaf (parent c) (\_ -> return ( rcp, free rcp )) 177 | else return Nothing 178 | 179 | rangeStart, rangeEnd :: SourceRange -> SourceLocation 180 | rangeStart sr = uderef sr $ \srp -> do 181 | slp <- [C.exp| CXSourceLocation* { ALLOC( 182 | clang_getRangeStart(*$(CXSourceRange *srp)) 183 | )} |] 184 | sln <- newLeaf (parent sr) $ \_ -> 185 | return ( slp, free slp ) 186 | return $ SourceLocation sln 187 | 188 | rangeEnd sr = uderef sr $ \srp -> do 189 | slp <- [C.exp| CXSourceLocation* { ALLOC( 190 | clang_getRangeEnd(*$(CXSourceRange *srp)) 191 | )} |] 192 | sln <- newLeaf (parent sr) $ \_ -> 193 | return ( slp, free slp ) 194 | return $ SourceLocation sln 195 | 196 | spellingLocation :: SourceLocation -> Location 197 | spellingLocation sl = uderef sl $ \slp -> do 198 | ( f, l, c, o ) <- C.withPtrs_ $ \( fp, lp, cp, offp ) -> 199 | [C.exp| void { 200 | clang_getSpellingLocation( 201 | *$(CXSourceLocation *slp), 202 | $(CXFile *fp), 203 | $(unsigned int *lp), 204 | $(unsigned int *cp), 205 | $(unsigned int *offp)) 206 | } |] 207 | fn <- newLeaf (parent sl) $ \_ -> return ( f, return () ) 208 | return $ Location 209 | { file = File fn 210 | , line = fromIntegral l 211 | , column = fromIntegral c 212 | , offset = fromIntegral o 213 | } 214 | 215 | getFile :: TranslationUnit -> FilePath -> Maybe File 216 | getFile tu p = uderef tu $ \tup -> withCString p $ \fn -> do 217 | fp <- [C.exp| CXFile { 218 | clang_getFile($(CXTranslationUnit tup), $(const char *fn)) 219 | } |] 220 | if fp == nullPtr 221 | then return Nothing 222 | else (Just . File) <$> newLeaf tu (\_ -> return ( fp, return () )) 223 | 224 | fileName :: File -> ByteString 225 | fileName f = uderef f $ \fp -> withCXString $ \cxsp -> 226 | [C.block| void { 227 | *$(CXString *cxsp) = clang_getFileName($(CXFile fp)); 228 | } |] 229 | 230 | instance Eq Cursor where 231 | (==) = defaultEq $ \lp rp -> 232 | [C.exp| int { clang_equalCursors(*$(CXCursor *lp), *$(CXCursor *rp)) } |] 233 | 234 | instance Eq SourceRange where 235 | (==) = defaultEq $ \lp rp -> 236 | [C.exp| int { clang_equalRanges(*$(CXSourceRange *lp), *$(CXSourceRange *rp)) } |] 237 | 238 | instance Eq SourceLocation where 239 | (==) = defaultEq $ \lp rp -> 240 | [C.exp| int { clang_equalLocations(*$(CXSourceLocation *lp), *$(CXSourceLocation *rp)) } |] 241 | 242 | instance Eq Type where 243 | (==) = defaultEq $ \lp rp -> 244 | [C.exp| int { clang_equalTypes(*$(CXType *lp), *$(CXType *rp)) } |] 245 | 246 | -- Checks for pointer equality, alternatively checks for structural equality with the given function. 247 | defaultEq :: (Clang r, RefOf r ~ a) => (Ptr a -> Ptr a -> IO CInt) -> r -> r -> Bool 248 | defaultEq ne l r 249 | = l `pointerEq` r || structEq 250 | where 251 | structEq = 252 | unsafePerformIO $ 253 | deref l $ \p -> 254 | deref r $ \p' -> 255 | (/=0) <$> ne p p' 256 | 257 | parseCursorKind :: CInt -> CursorKind 258 | parseCursorKind = \case 259 | #{const CXCursor_UnexposedDecl} -> UnexposedDecl 260 | #{const CXCursor_StructDecl} -> StructDecl 261 | #{const CXCursor_UnionDecl} -> UnionDecl 262 | #{const CXCursor_ClassDecl} -> ClassDecl 263 | #{const CXCursor_EnumDecl} -> EnumDecl 264 | #{const CXCursor_FieldDecl} -> FieldDecl 265 | #{const CXCursor_EnumConstantDecl} -> EnumConstantDecl 266 | #{const CXCursor_FunctionDecl} -> FunctionDecl 267 | #{const CXCursor_VarDecl} -> VarDecl 268 | #{const CXCursor_ParmDecl} -> ParmDecl 269 | #{const CXCursor_ObjCInterfaceDecl} -> ObjCInterfaceDecl 270 | #{const CXCursor_ObjCCategoryDecl} -> ObjCCategoryDecl 271 | #{const CXCursor_ObjCProtocolDecl} -> ObjCProtocolDecl 272 | #{const CXCursor_ObjCPropertyDecl} -> ObjCPropertyDecl 273 | #{const CXCursor_ObjCIvarDecl} -> ObjCIvarDecl 274 | #{const CXCursor_ObjCInstanceMethodDecl} -> ObjCInstanceMethodDecl 275 | #{const CXCursor_ObjCClassMethodDecl} -> ObjCClassMethodDecl 276 | #{const CXCursor_ObjCImplementationDecl} -> ObjCImplementationDecl 277 | #{const CXCursor_ObjCCategoryImplDecl} -> ObjCCategoryImplDecl 278 | #{const CXCursor_TypedefDecl} -> TypedefDecl 279 | #{const CXCursor_CXXMethod} -> CXXMethod 280 | #{const CXCursor_Namespace} -> Namespace 281 | #{const CXCursor_LinkageSpec} -> LinkageSpec 282 | #{const CXCursor_Constructor} -> Constructor 283 | #{const CXCursor_Destructor} -> Destructor 284 | #{const CXCursor_ConversionFunction} -> ConversionFunction 285 | #{const CXCursor_TemplateTypeParameter} -> TemplateTypeParameter 286 | #{const CXCursor_NonTypeTemplateParameter} -> NonTypeTemplateParameter 287 | #{const CXCursor_TemplateTemplateParameter} -> TemplateTemplateParameter 288 | #{const CXCursor_FunctionTemplate} -> FunctionTemplate 289 | #{const CXCursor_ClassTemplate} -> ClassTemplate 290 | #{const CXCursor_ClassTemplatePartialSpecialization} -> ClassTemplatePartialSpecialization 291 | #{const CXCursor_NamespaceAlias} -> NamespaceAlias 292 | #{const CXCursor_UsingDirective} -> UsingDirective 293 | #{const CXCursor_UsingDeclaration} -> UsingDeclaration 294 | #{const CXCursor_TypeAliasDecl} -> TypeAliasDecl 295 | #{const CXCursor_ObjCSynthesizeDecl} -> ObjCSynthesizeDecl 296 | #{const CXCursor_ObjCDynamicDecl} -> ObjCDynamicDecl 297 | #{const CXCursor_CXXAccessSpecifier} -> CXXAccessSpecifier 298 | #{const CXCursor_FirstDecl} -> FirstDecl 299 | #{const CXCursor_LastDecl} -> LastDecl 300 | #{const CXCursor_FirstRef} -> FirstRef 301 | #{const CXCursor_ObjCSuperClassRef} -> ObjCSuperClassRef 302 | #{const CXCursor_ObjCProtocolRef} -> ObjCProtocolRef 303 | #{const CXCursor_ObjCClassRef} -> ObjCClassRef 304 | #{const CXCursor_TypeRef} -> TypeRef 305 | #{const CXCursor_CXXBaseSpecifier} -> CXXBaseSpecifier 306 | #{const CXCursor_TemplateRef} -> TemplateRef 307 | #{const CXCursor_NamespaceRef} -> NamespaceRef 308 | #{const CXCursor_MemberRef} -> MemberRef 309 | #{const CXCursor_LabelRef} -> LabelRef 310 | #{const CXCursor_OverloadedDeclRef} -> OverloadedDeclRef 311 | #{const CXCursor_VariableRef} -> VariableRef 312 | #{const CXCursor_LastRef} -> LastRef 313 | #{const CXCursor_FirstInvalid} -> FirstInvalid 314 | #{const CXCursor_InvalidFile} -> InvalidFile 315 | #{const CXCursor_NoDeclFound} -> NoDeclFound 316 | #{const CXCursor_NotImplemented} -> NotImplemented 317 | #{const CXCursor_InvalidCode} -> InvalidCode 318 | #{const CXCursor_LastInvalid} -> LastInvalid 319 | #{const CXCursor_FirstExpr} -> FirstExpr 320 | #{const CXCursor_UnexposedExpr} -> UnexposedExpr 321 | #{const CXCursor_DeclRefExpr} -> DeclRefExpr 322 | #{const CXCursor_MemberRefExpr} -> MemberRefExpr 323 | #{const CXCursor_CallExpr} -> CallExpr 324 | #{const CXCursor_ObjCMessageExpr} -> ObjCMessageExpr 325 | #{const CXCursor_BlockExpr} -> BlockExpr 326 | #{const CXCursor_IntegerLiteral} -> IntegerLiteral 327 | #{const CXCursor_FloatingLiteral} -> FloatingLiteral 328 | #{const CXCursor_ImaginaryLiteral} -> ImaginaryLiteral 329 | #{const CXCursor_StringLiteral} -> StringLiteral 330 | #{const CXCursor_CharacterLiteral} -> CharacterLiteral 331 | #{const CXCursor_ParenExpr} -> ParenExpr 332 | #{const CXCursor_UnaryOperator} -> UnaryOperator 333 | #{const CXCursor_ArraySubscriptExpr} -> ArraySubscriptExpr 334 | #{const CXCursor_BinaryOperator} -> BinaryOperator 335 | #{const CXCursor_CompoundAssignOperator} -> CompoundAssignOperator 336 | #{const CXCursor_ConditionalOperator} -> ConditionalOperator 337 | #{const CXCursor_CStyleCastExpr} -> CStyleCastExpr 338 | #{const CXCursor_CompoundLiteralExpr} -> CompoundLiteralExpr 339 | #{const CXCursor_InitListExpr} -> InitListExpr 340 | #{const CXCursor_AddrLabelExpr} -> AddrLabelExpr 341 | #{const CXCursor_StmtExpr} -> StmtExpr 342 | #{const CXCursor_GenericSelectionExpr} -> GenericSelectionExpr 343 | #{const CXCursor_GNUNullExpr} -> GNUNullExpr 344 | #{const CXCursor_CXXStaticCastExpr} -> CXXStaticCastExpr 345 | #{const CXCursor_CXXDynamicCastExpr} -> CXXDynamicCastExpr 346 | #{const CXCursor_CXXReinterpretCastExpr} -> CXXReinterpretCastExpr 347 | #{const CXCursor_CXXConstCastExpr} -> CXXConstCastExpr 348 | #{const CXCursor_CXXFunctionalCastExpr} -> CXXFunctionalCastExpr 349 | #{const CXCursor_CXXTypeidExpr} -> CXXTypeidExpr 350 | #{const CXCursor_CXXBoolLiteralExpr} -> CXXBoolLiteralExpr 351 | #{const CXCursor_CXXNullPtrLiteralExpr} -> CXXNullPtrLiteralExpr 352 | #{const CXCursor_CXXThisExpr} -> CXXThisExpr 353 | #{const CXCursor_CXXThrowExpr} -> CXXThrowExpr 354 | #{const CXCursor_CXXNewExpr} -> CXXNewExpr 355 | #{const CXCursor_CXXDeleteExpr} -> CXXDeleteExpr 356 | #{const CXCursor_UnaryExpr} -> UnaryExpr 357 | #{const CXCursor_ObjCStringLiteral} -> ObjCStringLiteral 358 | #{const CXCursor_ObjCEncodeExpr} -> ObjCEncodeExpr 359 | #{const CXCursor_ObjCSelectorExpr} -> ObjCSelectorExpr 360 | #{const CXCursor_ObjCProtocolExpr} -> ObjCProtocolExpr 361 | #{const CXCursor_ObjCBridgedCastExpr} -> ObjCBridgedCastExpr 362 | #{const CXCursor_PackExpansionExpr} -> PackExpansionExpr 363 | #{const CXCursor_SizeOfPackExpr} -> SizeOfPackExpr 364 | #{const CXCursor_LambdaExpr} -> LambdaExpr 365 | #{const CXCursor_ObjCBoolLiteralExpr} -> ObjCBoolLiteralExpr 366 | #{const CXCursor_ObjCSelfExpr} -> ObjCSelfExpr 367 | #{const CXCursor_LastExpr} -> LastExpr 368 | #{const CXCursor_FirstStmt} -> FirstStmt 369 | #{const CXCursor_UnexposedStmt} -> UnexposedStmt 370 | #{const CXCursor_LabelStmt} -> LabelStmt 371 | #{const CXCursor_CompoundStmt} -> CompoundStmt 372 | #{const CXCursor_CaseStmt} -> CaseStmt 373 | #{const CXCursor_DefaultStmt} -> DefaultStmt 374 | #{const CXCursor_IfStmt} -> IfStmt 375 | #{const CXCursor_SwitchStmt} -> SwitchStmt 376 | #{const CXCursor_WhileStmt} -> WhileStmt 377 | #{const CXCursor_DoStmt} -> DoStmt 378 | #{const CXCursor_ForStmt} -> ForStmt 379 | #{const CXCursor_GotoStmt} -> GotoStmt 380 | #{const CXCursor_IndirectGotoStmt} -> IndirectGotoStmt 381 | #{const CXCursor_ContinueStmt} -> ContinueStmt 382 | #{const CXCursor_BreakStmt} -> BreakStmt 383 | #{const CXCursor_ReturnStmt} -> ReturnStmt 384 | #{const CXCursor_GCCAsmStmt} -> GCCAsmStmt 385 | #{const CXCursor_AsmStmt} -> AsmStmt 386 | #{const CXCursor_ObjCAtTryStmt} -> ObjCAtTryStmt 387 | #{const CXCursor_ObjCAtCatchStmt} -> ObjCAtCatchStmt 388 | #{const CXCursor_ObjCAtFinallyStmt} -> ObjCAtFinallyStmt 389 | #{const CXCursor_ObjCAtThrowStmt} -> ObjCAtThrowStmt 390 | #{const CXCursor_ObjCAtSynchronizedStmt} -> ObjCAtSynchronizedStmt 391 | #{const CXCursor_ObjCAutoreleasePoolStmt} -> ObjCAutoreleasePoolStmt 392 | #{const CXCursor_ObjCForCollectionStmt} -> ObjCForCollectionStmt 393 | #{const CXCursor_CXXCatchStmt} -> CXXCatchStmt 394 | #{const CXCursor_CXXTryStmt} -> CXXTryStmt 395 | #{const CXCursor_CXXForRangeStmt} -> CXXForRangeStmt 396 | #{const CXCursor_SEHTryStmt} -> SEHTryStmt 397 | #{const CXCursor_SEHExceptStmt} -> SEHExceptStmt 398 | #{const CXCursor_SEHFinallyStmt} -> SEHFinallyStmt 399 | #{const CXCursor_MSAsmStmt} -> MSAsmStmt 400 | #{const CXCursor_NullStmt} -> NullStmt 401 | #{const CXCursor_DeclStmt} -> DeclStmt 402 | #{const CXCursor_OMPParallelDirective} -> OMPParallelDirective 403 | #{const CXCursor_OMPSimdDirective} -> OMPSimdDirective 404 | #{const CXCursor_OMPForDirective} -> OMPForDirective 405 | #{const CXCursor_OMPSectionsDirective} -> OMPSectionsDirective 406 | #{const CXCursor_OMPSectionDirective} -> OMPSectionDirective 407 | #{const CXCursor_OMPSingleDirective} -> OMPSingleDirective 408 | #{const CXCursor_OMPParallelForDirective} -> OMPParallelForDirective 409 | #{const CXCursor_OMPParallelSectionsDirective} -> OMPParallelSectionsDirective 410 | #{const CXCursor_OMPTaskDirective} -> OMPTaskDirective 411 | #{const CXCursor_OMPMasterDirective} -> OMPMasterDirective 412 | #{const CXCursor_OMPCriticalDirective} -> OMPCriticalDirective 413 | #{const CXCursor_OMPTaskyieldDirective} -> OMPTaskyieldDirective 414 | #{const CXCursor_OMPBarrierDirective} -> OMPBarrierDirective 415 | #{const CXCursor_OMPTaskwaitDirective} -> OMPTaskwaitDirective 416 | #{const CXCursor_OMPFlushDirective} -> OMPFlushDirective 417 | #{const CXCursor_SEHLeaveStmt} -> SEHLeaveStmt 418 | #{const CXCursor_LastStmt} -> LastStmt 419 | #{const CXCursor_TranslationUnit} -> TranslationUnit 420 | #{const CXCursor_FirstAttr} -> FirstAttr 421 | #{const CXCursor_UnexposedAttr} -> UnexposedAttr 422 | #{const CXCursor_IBActionAttr} -> IBActionAttr 423 | #{const CXCursor_IBOutletAttr} -> IBOutletAttr 424 | #{const CXCursor_IBOutletCollectionAttr} -> IBOutletCollectionAttr 425 | #{const CXCursor_CXXFinalAttr} -> CXXFinalAttr 426 | #{const CXCursor_CXXOverrideAttr} -> CXXOverrideAttr 427 | #{const CXCursor_AnnotateAttr} -> AnnotateAttr 428 | #{const CXCursor_AsmLabelAttr} -> AsmLabelAttr 429 | #{const CXCursor_PackedAttr} -> PackedAttr 430 | #{const CXCursor_PureAttr} -> PureAttr 431 | #{const CXCursor_ConstAttr} -> ConstAttr 432 | #{const CXCursor_NoDuplicateAttr} -> NoDuplicateAttr 433 | #{const CXCursor_CUDAConstantAttr} -> CUDAConstantAttr 434 | #{const CXCursor_CUDADeviceAttr} -> CUDADeviceAttr 435 | #{const CXCursor_CUDAGlobalAttr} -> CUDAGlobalAttr 436 | #{const CXCursor_CUDAHostAttr} -> CUDAHostAttr 437 | #{const CXCursor_LastAttr} -> LastAttr 438 | #{const CXCursor_PreprocessingDirective} -> PreprocessingDirective 439 | #{const CXCursor_MacroDefinition} -> MacroDefinition 440 | #{const CXCursor_MacroExpansion} -> MacroExpansion 441 | #{const CXCursor_MacroInstantiation} -> MacroInstantiation 442 | #{const CXCursor_InclusionDirective} -> InclusionDirective 443 | #{const CXCursor_FirstPreprocessing} -> FirstPreprocessing 444 | #{const CXCursor_LastPreprocessing} -> LastPreprocessing 445 | #{const CXCursor_ModuleImportDecl} -> ModuleImportDecl 446 | #{const CXCursor_FirstExtraDecl} -> FirstExtraDecl 447 | #{const CXCursor_LastExtraDecl} -> LastExtraDecl 448 | _ -> UnexposedDecl -- unrecognized enum value 449 | 450 | cursorType :: Cursor -> Maybe Type 451 | cursorType c = uderef c $ \cp -> do 452 | tp <- [C.block| CXType* { 453 | CXType type = clang_getCursorType(*$(CXCursor *cp)); 454 | 455 | if (type.kind == CXType_Invalid) { 456 | return NULL; 457 | } 458 | 459 | return ALLOC(type); 460 | } |] 461 | if tp == nullPtr 462 | then return Nothing 463 | else (Just . Type) <$> newLeaf (parent c) (\_ -> return ( tp, free tp )) 464 | 465 | typeKind :: Type -> TypeKind 466 | typeKind t = uderef t $ fmap parseTypeKind . #peek CXType, kind 467 | 468 | parseTypeKind :: CInt -> TypeKind 469 | parseTypeKind = \case 470 | #{const CXType_Invalid} -> Invalid 471 | #{const CXType_Unexposed} -> Unexposed 472 | #{const CXType_Void} -> Void 473 | #{const CXType_Bool} -> Bool 474 | #{const CXType_Char_U} -> Char_U 475 | #{const CXType_UChar} -> UChar 476 | #{const CXType_Char16} -> Char16 477 | #{const CXType_Char32} -> Char32 478 | #{const CXType_UShort} -> UShort 479 | #{const CXType_UInt} -> UInt 480 | #{const CXType_ULong} -> ULong 481 | #{const CXType_ULongLong} -> ULongLong 482 | #{const CXType_UInt128} -> UInt128 483 | #{const CXType_Char_S} -> Char_S 484 | #{const CXType_SChar} -> SChar 485 | #{const CXType_WChar} -> WChar 486 | #{const CXType_Short} -> Short 487 | #{const CXType_Int} -> Int 488 | #{const CXType_Long} -> Long 489 | #{const CXType_LongLong} -> LongLong 490 | #{const CXType_Int128} -> Int128 491 | #{const CXType_Float} -> Float 492 | #{const CXType_Double} -> Double 493 | #{const CXType_LongDouble} -> LongDouble 494 | #{const CXType_NullPtr} -> NullPtr 495 | #{const CXType_Overload} -> Overload 496 | #{const CXType_Dependent} -> Dependent 497 | #{const CXType_ObjCId} -> ObjCId 498 | #{const CXType_ObjCClass} -> ObjCClass 499 | #{const CXType_ObjCSel} -> ObjCSel 500 | #{const CXType_FirstBuiltin} -> FirstBuiltin 501 | #{const CXType_LastBuiltin} -> LastBuiltin 502 | #{const CXType_Complex} -> Complex 503 | #{const CXType_Pointer} -> Pointer 504 | #{const CXType_BlockPointer} -> BlockPointer 505 | #{const CXType_LValueReference} -> LValueReference 506 | #{const CXType_RValueReference} -> RValueReference 507 | #{const CXType_Record} -> Record 508 | #{const CXType_Enum} -> Enum 509 | #{const CXType_Typedef} -> Typedef 510 | #{const CXType_ObjCInterface} -> ObjCInterface 511 | #{const CXType_ObjCObjectPointer} -> ObjCObjectPointer 512 | #{const CXType_FunctionNoProto} -> FunctionNoProto 513 | #{const CXType_FunctionProto} -> FunctionProto 514 | #{const CXType_ConstantArray} -> ConstantArray 515 | #{const CXType_Vector} -> Vector 516 | #{const CXType_IncompleteArray} -> IncompleteArray 517 | #{const CXType_VariableArray} -> VariableArray 518 | #{const CXType_DependentSizedArray} -> DependentSizedArray 519 | #{const CXType_MemberPointer} -> MemberPointer 520 | _ -> Unexposed 521 | 522 | typeSpelling :: Type -> ByteString 523 | typeSpelling t = uderef t $ \tp -> 524 | withCXString $ \cxsp -> 525 | [C.exp| void { *$(CXString *cxsp) = clang_getTypeSpelling(*$(CXType *tp)); } |] 526 | 527 | instance Clang Token where 528 | deref (Token ts i) f 529 | = deref (tokenSetRef ts) $ f . (`plusPtr` (i * (#size CXToken))) 530 | unsafeToPtr (Token ts i) 531 | = unsafeToPtr (tokenSetRef ts) `plusPtr` (i * (#size CXToken)) 532 | 533 | instance Child Token where 534 | parent (Token ts _) = parent (tokenSetRef ts) 535 | 536 | foreign import ccall "clang_disposeTokens" 537 | clang_disposeTokens :: CXTranslationUnit -> Ptr CXToken -> CUInt -> Finalizer 538 | 539 | tokenize :: SourceRange -> TokenSet 540 | tokenize sr = unsafePerformIO $ 541 | deref (parent sr) $ \tup -> 542 | deref sr $ \srp -> do 543 | ( tsp, tn ) <- C.withPtrs_ $ \( tspp, tnp ) -> 544 | [C.exp| void { 545 | clang_tokenize( 546 | $(CXTranslationUnit tup), 547 | *$(CXSourceRange *srp), 548 | $(CXToken **tspp), 549 | $(unsigned int *tnp)); 550 | } |] 551 | tsn <- newLeaf (parent sr) $ \_ -> 552 | return ( tsp, clang_disposeTokens tup tsp tn ) 553 | return $ TokenSet tsn (fromIntegral tn) 554 | 555 | tokenSetTokens :: TokenSet -> [ Token ] 556 | tokenSetTokens ts 557 | = map (Token ts) [0..tokenSetSize ts - 1] 558 | 559 | indexTokenSet :: TokenSet -> Int -> Token 560 | indexTokenSet ts i 561 | | 0 <= i && i < tokenSetSize ts = Token ts i 562 | | otherwise = error "Token index out of bounds." 563 | 564 | tokenSpelling :: Token -> ByteString 565 | tokenSpelling t = unsafePerformIO $ 566 | deref (parent t) $ \tup -> 567 | deref t $ \tp -> 568 | withCXString $ \cxsp -> do 569 | [C.block| void { 570 | *$(CXString *cxsp) = clang_getTokenSpelling( 571 | $(CXTranslationUnit tup), 572 | *$(CXToken *tp)); 573 | } |] 574 | 575 | isInSystemHeader :: SourceLocation -> Bool 576 | isInSystemHeader l = uderef l $ \lp -> 577 | toBool <$> [C.exp| int { 578 | clang_Location_isInSystemHeader(*$(CXSourceLocation *lp)) 579 | } |] 580 | 581 | isFromMainFile :: SourceLocation -> Bool 582 | isFromMainFile l = uderef l $ \lp -> 583 | toBool <$> [C.exp| int { 584 | clang_Location_isFromMainFile(*$(CXSourceLocation *lp)) 585 | } |] 586 | 587 | instance Show Cursor where 588 | show c = 589 | "Cursor { cursorKind = " 590 | ++ show (cursorKind c) 591 | ++ ", cursorSpelling = " 592 | ++ show (cursorSpelling c) 593 | ++ "}" 594 | 595 | instance Show Type where 596 | show t = 597 | "Type { typeKind = " 598 | ++ show (typeKind t) 599 | ++ ", typeSpelling = " 600 | ++ show (typeSpelling t) 601 | ++ "}" 602 | 603 | instance Show File where 604 | show f = 605 | "File { fileName = " 606 | ++ show (fileName f) 607 | ++ "}" -------------------------------------------------------------------------------- /src/Clang/Internal/Refs.hs: -------------------------------------------------------------------------------- 1 | {- 2 | Copyright 2014 Google Inc. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | -} 16 | 17 | module Clang.Internal.Refs where 18 | 19 | import Control.Concurrent.MVar 20 | import GHC.ForeignPtr (unsafeForeignPtrToPtr) 21 | import Foreign hiding (newForeignPtr) 22 | import Foreign.Concurrent 23 | import System.IO.Unsafe 24 | 25 | type Finalizer = IO () 26 | 27 | data NodeState = NodeState 28 | { destructable :: !Bool 29 | , refCount :: !Int 30 | } 31 | 32 | type family RefOf n 33 | class Clang n where 34 | deref :: n -> (Ptr (RefOf n) -> IO a) -> IO a 35 | unsafeToPtr :: n -> Ptr (RefOf n) 36 | 37 | class Clang n => Parent n where 38 | incCount :: n -> IO () 39 | decCount :: n -> IO () 40 | 41 | type family ParentOf n 42 | class (Clang n, Parent (ParentOf n)) => Child n where 43 | parent :: n -> ParentOf n 44 | 45 | data Root a = Root 46 | { nodePtr :: ForeignPtr a 47 | , nodeState :: MVar NodeState 48 | , trueFinalize :: Finalizer 49 | } 50 | 51 | newRoot :: Ptr a -> Finalizer -> IO (Root a) 52 | newRoot ptr fin = do 53 | nsv <- newMVar $ NodeState { destructable = False, refCount = 0 } 54 | nptr <- newForeignPtr ptr $ modifyMVar_ nsv $ \ns -> 55 | if refCount ns == 0 56 | then fin >> return ns 57 | else return $ ns { destructable = True } 58 | return $ Root nptr nsv fin 59 | 60 | instance Parent (Root a) where 61 | incCount r = modifyMVar_ (nodeState r) $ \ns -> return ns { refCount = refCount ns + 1 } 62 | decCount r = modifyMVar_ (nodeState r) $ \ns -> do 63 | if refCount ns == 1 && destructable ns 64 | then trueFinalize r >> return ns { refCount = 0, destructable = False } 65 | else return ns { refCount = refCount ns - 1 } 66 | 67 | type instance RefOf (Root a) = a 68 | instance Clang (Root a) where 69 | deref r = withForeignPtr (nodePtr r) 70 | unsafeToPtr = unsafeForeignPtrToPtr . nodePtr 71 | 72 | data Node p a = Node p (Root a) 73 | 74 | newNode :: Parent p => p -> (Ptr (RefOf p) -> IO ( Ptr a, Finalizer )) -> IO (Node p a) 75 | newNode prn f = deref prn $ \pptr -> do 76 | ( cptr, cfin ) <- f pptr 77 | incCount prn 78 | rt <- newRoot cptr (cfin >> decCount prn) 79 | return $ Node prn rt 80 | 81 | instance Clang p => Parent (Node p a) where 82 | incCount (Node _ n) = incCount n 83 | decCount (Node _ n) = decCount n 84 | 85 | type instance ParentOf (Node p a) = p 86 | instance Parent p => Child (Node p a) where 87 | parent (Node p _) = p 88 | 89 | type instance RefOf (Node p a) = a 90 | instance Clang p => Clang (Node p a) where 91 | deref (Node p n) f = deref p $ \_ -> deref n f 92 | unsafeToPtr (Node _ n) = unsafeToPtr n 93 | 94 | data Leaf p a = Leaf p (ForeignPtr a) 95 | 96 | newLeaf :: Parent p => p -> (Ptr (RefOf p) -> IO ( Ptr a, Finalizer )) -> IO (Leaf p a) 97 | newLeaf prn f = deref prn $ \pptr -> do 98 | ( cptr, cfin ) <- f pptr 99 | incCount prn 100 | rt <- newForeignPtr cptr (cfin >> decCount prn) 101 | return $ Leaf prn rt 102 | 103 | type instance ParentOf (Leaf p a) = p 104 | instance Parent p => Child (Leaf p a) where 105 | parent (Leaf p _) = p 106 | 107 | type instance RefOf (Leaf p a) = a 108 | instance Clang p => Clang (Leaf p a) where 109 | deref (Leaf p n) f = deref p $ \_ -> withForeignPtr n f 110 | unsafeToPtr (Leaf _ n) = unsafeForeignPtrToPtr n 111 | 112 | pointerEq :: Clang n => n -> n -> Bool 113 | pointerEq r r' = unsafeToPtr r == unsafeToPtr r' 114 | 115 | pointerCompare :: Clang n => n -> n -> Ordering 116 | pointerCompare r r' = unsafeToPtr r `compare` unsafeToPtr r' 117 | 118 | uderef :: Clang r => r -> (Ptr (RefOf r) -> IO a) -> a 119 | uderef r f = unsafePerformIO $ deref r f -------------------------------------------------------------------------------- /src/Clang/Internal/Types.hs: -------------------------------------------------------------------------------- 1 | {- 2 | Copyright 2014 Google Inc. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | -} 16 | 17 | module Clang.Internal.Types where 18 | 19 | import Foreign 20 | 21 | import Clang.Internal.Refs 22 | 23 | data CXIndexImpl 24 | type CXIndex = Ptr CXIndexImpl 25 | type instance RefOf ClangIndex = CXIndexImpl 26 | newtype ClangIndex = ClangIndex (Root CXIndexImpl) 27 | deriving (Parent, Clang) 28 | 29 | instance Eq ClangIndex where (==) = pointerEq 30 | 31 | data CXTranslationUnitImpl 32 | type CXTranslationUnit = Ptr CXTranslationUnitImpl 33 | type instance RefOf TranslationUnit = CXTranslationUnitImpl 34 | type instance ParentOf TranslationUnit = ClangIndex 35 | newtype TranslationUnit = TranslationUnitRef (Node ClangIndex CXTranslationUnitImpl) 36 | deriving (Parent, Child, Clang) 37 | 38 | instance Eq TranslationUnit where (==) = pointerEq 39 | 40 | data CXCursor 41 | type instance RefOf Cursor = CXCursor 42 | type instance ParentOf Cursor = TranslationUnit 43 | newtype Cursor = Cursor (Leaf TranslationUnit CXCursor) 44 | deriving (Child, Clang) 45 | 46 | data CXSourceRange 47 | type instance RefOf SourceRange = CXSourceRange 48 | type instance ParentOf SourceRange = TranslationUnit 49 | newtype SourceRange 50 | = SourceRange (Leaf TranslationUnit CXSourceRange) 51 | deriving (Child, Clang) 52 | 53 | data CXSourceLocation 54 | type instance RefOf SourceLocation = CXSourceLocation 55 | type instance ParentOf SourceLocation = TranslationUnit 56 | newtype SourceLocation 57 | = SourceLocation (Leaf TranslationUnit CXSourceLocation) 58 | deriving (Child, Clang) 59 | 60 | data CXFileImpl 61 | type CXFile = Ptr CXFileImpl 62 | type instance RefOf File = CXFileImpl 63 | type instance ParentOf File = TranslationUnit 64 | newtype File 65 | = File (Leaf TranslationUnit CXFileImpl) 66 | deriving (Child, Clang) 67 | 68 | instance Eq File where (==) = pointerEq 69 | 70 | data CXString 71 | 72 | data Location = Location 73 | { file :: File 74 | , line :: Word 75 | , column :: Word 76 | , offset :: Word 77 | } 78 | 79 | data CursorKind 80 | = UnexposedDecl 81 | | StructDecl 82 | | UnionDecl 83 | | ClassDecl 84 | | EnumDecl 85 | | FieldDecl 86 | | EnumConstantDecl 87 | | FunctionDecl 88 | | VarDecl 89 | | ParmDecl 90 | | ObjCInterfaceDecl 91 | | ObjCCategoryDecl 92 | | ObjCProtocolDecl 93 | | ObjCPropertyDecl 94 | | ObjCIvarDecl 95 | | ObjCInstanceMethodDecl 96 | | ObjCClassMethodDecl 97 | | ObjCImplementationDecl 98 | | ObjCCategoryImplDecl 99 | | TypedefDecl 100 | | CXXMethod 101 | | Namespace 102 | | LinkageSpec 103 | | Constructor 104 | | Destructor 105 | | ConversionFunction 106 | | TemplateTypeParameter 107 | | NonTypeTemplateParameter 108 | | TemplateTemplateParameter 109 | | FunctionTemplate 110 | | ClassTemplate 111 | | ClassTemplatePartialSpecialization 112 | | NamespaceAlias 113 | | UsingDirective 114 | | UsingDeclaration 115 | | TypeAliasDecl 116 | | ObjCSynthesizeDecl 117 | | ObjCDynamicDecl 118 | | CXXAccessSpecifier 119 | | FirstDecl 120 | | LastDecl 121 | | FirstRef 122 | | ObjCSuperClassRef 123 | | ObjCProtocolRef 124 | | ObjCClassRef 125 | | TypeRef 126 | | CXXBaseSpecifier 127 | | TemplateRef 128 | | NamespaceRef 129 | | MemberRef 130 | | LabelRef 131 | | OverloadedDeclRef 132 | | VariableRef 133 | | LastRef 134 | | FirstInvalid 135 | | InvalidFile 136 | | NoDeclFound 137 | | NotImplemented 138 | | InvalidCode 139 | | LastInvalid 140 | | FirstExpr 141 | | UnexposedExpr 142 | | DeclRefExpr 143 | | MemberRefExpr 144 | | CallExpr 145 | | ObjCMessageExpr 146 | | BlockExpr 147 | | IntegerLiteral 148 | | FloatingLiteral 149 | | ImaginaryLiteral 150 | | StringLiteral 151 | | CharacterLiteral 152 | | ParenExpr 153 | | UnaryOperator 154 | | ArraySubscriptExpr 155 | | BinaryOperator 156 | | CompoundAssignOperator 157 | | ConditionalOperator 158 | | CStyleCastExpr 159 | | CompoundLiteralExpr 160 | | InitListExpr 161 | | AddrLabelExpr 162 | | StmtExpr 163 | | GenericSelectionExpr 164 | | GNUNullExpr 165 | | CXXStaticCastExpr 166 | | CXXDynamicCastExpr 167 | | CXXReinterpretCastExpr 168 | | CXXConstCastExpr 169 | | CXXFunctionalCastExpr 170 | | CXXTypeidExpr 171 | | CXXBoolLiteralExpr 172 | | CXXNullPtrLiteralExpr 173 | | CXXThisExpr 174 | | CXXThrowExpr 175 | | CXXNewExpr 176 | | CXXDeleteExpr 177 | | UnaryExpr 178 | | ObjCStringLiteral 179 | | ObjCEncodeExpr 180 | | ObjCSelectorExpr 181 | | ObjCProtocolExpr 182 | | ObjCBridgedCastExpr 183 | | PackExpansionExpr 184 | | SizeOfPackExpr 185 | | LambdaExpr 186 | | ObjCBoolLiteralExpr 187 | | ObjCSelfExpr 188 | | LastExpr 189 | | FirstStmt 190 | | UnexposedStmt 191 | | LabelStmt 192 | | CompoundStmt 193 | | CaseStmt 194 | | DefaultStmt 195 | | IfStmt 196 | | SwitchStmt 197 | | WhileStmt 198 | | DoStmt 199 | | ForStmt 200 | | GotoStmt 201 | | IndirectGotoStmt 202 | | ContinueStmt 203 | | BreakStmt 204 | | ReturnStmt 205 | | GCCAsmStmt 206 | | AsmStmt 207 | | ObjCAtTryStmt 208 | | ObjCAtCatchStmt 209 | | ObjCAtFinallyStmt 210 | | ObjCAtThrowStmt 211 | | ObjCAtSynchronizedStmt 212 | | ObjCAutoreleasePoolStmt 213 | | ObjCForCollectionStmt 214 | | CXXCatchStmt 215 | | CXXTryStmt 216 | | CXXForRangeStmt 217 | | SEHTryStmt 218 | | SEHExceptStmt 219 | | SEHFinallyStmt 220 | | MSAsmStmt 221 | | NullStmt 222 | | DeclStmt 223 | | OMPParallelDirective 224 | | OMPSimdDirective 225 | | OMPForDirective 226 | | OMPSectionsDirective 227 | | OMPSectionDirective 228 | | OMPSingleDirective 229 | | OMPParallelForDirective 230 | | OMPParallelSectionsDirective 231 | | OMPTaskDirective 232 | | OMPMasterDirective 233 | | OMPCriticalDirective 234 | | OMPTaskyieldDirective 235 | | OMPBarrierDirective 236 | | OMPTaskwaitDirective 237 | | OMPFlushDirective 238 | | SEHLeaveStmt 239 | | LastStmt 240 | | TranslationUnit 241 | | FirstAttr 242 | | UnexposedAttr 243 | | IBActionAttr 244 | | IBOutletAttr 245 | | IBOutletCollectionAttr 246 | | CXXFinalAttr 247 | | CXXOverrideAttr 248 | | AnnotateAttr 249 | | AsmLabelAttr 250 | | PackedAttr 251 | | PureAttr 252 | | ConstAttr 253 | | NoDuplicateAttr 254 | | CUDAConstantAttr 255 | | CUDADeviceAttr 256 | | CUDAGlobalAttr 257 | | CUDAHostAttr 258 | | LastAttr 259 | | PreprocessingDirective 260 | | MacroDefinition 261 | | MacroExpansion 262 | | MacroInstantiation 263 | | InclusionDirective 264 | | FirstPreprocessing 265 | | LastPreprocessing 266 | | ModuleImportDecl 267 | | FirstExtraDecl 268 | | LastExtraDecl 269 | deriving (Eq, Ord, Show) 270 | 271 | data TypeKind 272 | = Invalid 273 | | Unexposed 274 | | Void 275 | | Bool 276 | | Char_U 277 | | UChar 278 | | Char16 279 | | Char32 280 | | UShort 281 | | UInt 282 | | ULong 283 | | ULongLong 284 | | UInt128 285 | | Char_S 286 | | SChar 287 | | WChar 288 | | Short 289 | | Int 290 | | Long 291 | | LongLong 292 | | Int128 293 | | Float 294 | | Double 295 | | LongDouble 296 | | NullPtr 297 | | Overload 298 | | Dependent 299 | | ObjCId 300 | | ObjCClass 301 | | ObjCSel 302 | | FirstBuiltin 303 | | LastBuiltin 304 | | Complex 305 | | Pointer 306 | | BlockPointer 307 | | LValueReference 308 | | RValueReference 309 | | Record 310 | | Enum 311 | | Typedef 312 | | ObjCInterface 313 | | ObjCObjectPointer 314 | | FunctionNoProto 315 | | FunctionProto 316 | | ConstantArray 317 | | Vector 318 | | IncompleteArray 319 | | VariableArray 320 | | DependentSizedArray 321 | | MemberPointer 322 | deriving (Eq, Ord, Show) 323 | 324 | data CXType 325 | type instance RefOf Type = CXType 326 | type instance ParentOf Type = TranslationUnit 327 | newtype Type = Type (Leaf TranslationUnit CXType) 328 | deriving (Child, Clang) 329 | 330 | data CXToken 331 | data TokenSet = TokenSet 332 | { tokenSetRef :: Leaf TranslationUnit CXToken 333 | , tokenSetSize :: Int 334 | } 335 | 336 | type instance RefOf Token = CXToken 337 | type instance ParentOf Token = TranslationUnit 338 | data Token = Token TokenSet Int -------------------------------------------------------------------------------- /src/Clang/Location.hs: -------------------------------------------------------------------------------- 1 | {- 2 | Copyright 2014 Google Inc. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | -} 16 | 17 | module Clang.Location 18 | ( SourceRange() 19 | , rangeStart, rangeEnd 20 | , SourceLocation() 21 | , spellingLocation 22 | , isInSystemHeader 23 | , isFromMainFile 24 | , Location(..) 25 | ) 26 | where 27 | 28 | import Clang.Internal.FFI 29 | import Clang.Internal.Types 30 | 31 | deriving instance Eq Location 32 | deriving instance Show Location -------------------------------------------------------------------------------- /src/Clang/Token.hs: -------------------------------------------------------------------------------- 1 | {- 2 | Copyright 2014 Google Inc. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | -} 16 | 17 | module Clang.Token 18 | ( TokenSet() 19 | , Token() 20 | , tokenize 21 | , tokenSetTokens 22 | , indexTokenSet 23 | , tokenSpelling 24 | ) 25 | where 26 | 27 | import Clang.Internal.FFI 28 | import Clang.Internal.Types 29 | -------------------------------------------------------------------------------- /src/Clang/TranslationUnit.hs: -------------------------------------------------------------------------------- 1 | {- 2 | Copyright 2014 Google Inc. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | -} 16 | 17 | module Clang.TranslationUnit 18 | ( TranslationUnit() 19 | , parseTranslationUnit 20 | , translationUnitCursor 21 | ) 22 | where 23 | 24 | import Clang.Internal.FFI 25 | import Clang.Internal.Types -------------------------------------------------------------------------------- /src/Clang/Type.hs: -------------------------------------------------------------------------------- 1 | {- 2 | Copyright 2014 Google Inc. All Rights Reserved. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | -} 16 | 17 | module Clang.Type 18 | ( Type() 19 | , typeSpelling 20 | , typeKind 21 | , TypeKind(..) 22 | ) 23 | where 24 | 25 | import Clang.Internal.FFI 26 | import Clang.Internal.Types 27 | --------------------------------------------------------------------------------