LibClang (empty) → 3.8.0
raw patch · 42 files changed
+8569/−0 lines, 42 filesdep +basedep +bytestringdep +filepathbuild-type:Customsetup-changed
Dependencies added: base, bytestring, filepath, hashable, mtl, resourcet, text, time, transformers, transformers-base, vector
Files
- LICENSE +32/−0
- LibClang.cabal +75/−0
- Setup.hs +78/−0
- cbits/utils.c +24/−0
- cbits/utils.h +12/−0
- cbits/visitors.c +333/−0
- cbits/visitors.h +54/−0
- cbits/wrappers.c +129/−0
- cbits/wrappers.h +125/−0
- src/Clang.hs +167/−0
- src/Clang/Comment.hs +113/−0
- src/Clang/Completion.hs +225/−0
- src/Clang/Cursor.hs +329/−0
- src/Clang/Debug.hs +23/−0
- src/Clang/Diagnostic.hs +151/−0
- src/Clang/File.hs +60/−0
- src/Clang/Index.hs +45/−0
- src/Clang/Internal/BitFlags.hs +33/−0
- src/Clang/Internal/Comment.hs +189/−0
- src/Clang/Internal/FFI.chs +5068/−0
- src/Clang/Internal/FFIConstants.hsc +161/−0
- src/Clang/Internal/Monad.hs +81/−0
- src/Clang/Location.hs +106/−0
- src/Clang/Module.hs +50/−0
- src/Clang/Range.hs +49/−0
- src/Clang/Remapping.hs +37/−0
- src/Clang/String.hs +51/−0
- src/Clang/Token.hs +90/−0
- src/Clang/TranslationUnit.hs +195/−0
- src/Clang/Type.hs +142/−0
- src/Clang/USR.hs +79/−0
- src/Clang/UnsavedFile.hs +44/−0
- src/Clang/Version.hs +30/−0
- test/Makefile +25/−0
- test/Test_ChildVisitor.c +26/−0
- test/Test_ChildVisitor.hs +20/−0
- test/Test_Diagnostics.c +22/−0
- test/Test_Diagnostics.hs +16/−0
- test/Test_Diagnostics_FFI.hs +20/−0
- test/Test_InclusionVisitor.c +23/−0
- test/Test_InclusionVisitor.hs +17/−0
- test/runTest.sh +20/−0
+ LICENSE view
@@ -0,0 +1,32 @@+Copyright (c) Chetan Taralekar 2010, 2011, 2014+Copyright (c) Seth Fowler 2013, 2014+Each patch is attributed to its author, usually by email address.++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++ * Redistributions of source code must retain the above copyright+ notice, this list of conditions and the following disclaimer.++ * Redistributions in binary form must reproduce the above+ copyright notice, this list of conditions and the following+ disclaimer in the documentation and/or other materials provided+ with the distribution.++ * The names of the contributors may not be used to endorse or promote+ products derived from this software without specific prior written+ permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ LibClang.cabal view
@@ -0,0 +1,75 @@+Name: LibClang+Cabal-version: >= 1.18+Version: 3.8.0+Author: Chetan Taralekar <chetant@gmail.com>+Maintainer: Chetan Taralekar <chetant@gmail.com>, Seth Fowler <mark.seth.fowler@gmail.com>+Homepage: https://github.com/chetant/LibClang+License: BSD3+License-file: LICENSE+Synopsis: Haskell bindings for libclang (a C++ parsing library)+Description:+ LibClang package provides bindings to libclang.+ .+ This should be enough for parsing C/C++ code, walking the AST and querying nodes and completion queries.+ .+ * NOTE: This version is set to build against llvm 3.8.0+ .+ Please use <https://github.com/chetant/LibClang/issues> to report bugs++Category: Language+Tested-With: GHC == 7.8.4+ , GHC == 7.10.3+ , GHC == 8.0.2+Build-type: Custom+Extra-Source-Files: cbits/utils.h, cbits/visitors.h, cbits/wrappers.h,+ test/*.hs, test/*.c, test/runTest.sh, test/Makefile+Source-Repository head+ type: git+ location: git://github.com/chetant/LibClang.git++Library+ ghc-options: -Wall -funbox-strict-fields+ build-tools: c2hs >= 0.28.1+ build-depends: base >= 4.6 && < 5,+ bytestring >= 0.10 && < 0.11,+ filepath >= 1.3 && < 1.5,+ hashable >= 1.2 && < 1.3,+ mtl >= 2.1 && < 2.3,+ resourcet >= 1.1 && < 1.2,+ text >= 1.1 && < 1.3,+ time >= 1.4 && < 1.7,+ transformers >= 0.3 && < 0.6,+ transformers-base >= 0.4,+ vector >= 0.10 && < 0.12+ hs-source-dirs: src+ c-sources: cbits/utils.c,+ cbits/visitors.c,+ cbits/wrappers.c+ include-dirs: cbits+ exposed-modules: Clang,+ Clang.Comment,+ Clang.Completion,+ Clang.Cursor,+ Clang.Debug,+ Clang.Diagnostic,+ Clang.File,+ Clang.Location,+ Clang.Index,+ Clang.Module,+ Clang.Range,+ Clang.Remapping,+ Clang.String,+ Clang.Token,+ Clang.TranslationUnit,+ Clang.Type,+ Clang.UnsavedFile,+ Clang.USR,+ Clang.Version+ other-modules: Clang.Internal.BitFlags,+ Clang.Internal.Comment,+ Clang.Internal.Monad,+ Clang.Internal.FFI,+ Clang.Internal.FFIConstants+ default-language: Haskell2010+ pkgconfig-depends: ncurses+ extra-libraries: clang-3.8
+ Setup.hs view
@@ -0,0 +1,78 @@+{-# LANGUAGE CPP #-}+import Distribution.Simple+import Distribution.PackageDescription+import Data.Version+import Data.List+import Data.Char(isSpace)+import Data.Maybe+import System.Directory(getCurrentDirectory, removeFile)+import System.IO(IOMode(..), openFile, hPutStr, hFlush, hClose)+import System.IO.Error(catchIOError)+import System.Process(readProcess)+import System.Environment(lookupEnv, getEnv, setEnv)+import System.FilePath.Posix((</>))+import Control.Applicative((<$>))+import Control.Exception(bracket)++rtrim :: String -> String+rtrim = f . f+ where f = reverse . dropWhile isSpace++getLLVMDetails llvmConfigPath = do+ version <- rtrim <$> readProcess llvmConfigPath ["--version"] []+ libPath <- rtrim <$> readProcess llvmConfigPath ["--libdir"] []+ includePath <- rtrim <$> readProcess llvmConfigPath ["--includedir"] []+ return (version,libPath,includePath)++setupLLVMPkgConfig tmpPCPath outf = do+ let tryElse act failAct = catchIOError act (const failAct)+ (version,libPath,includePath) <- getLLVMDetails "llvm-config-3.8" `tryElse`+ getLLVMDetails "llvm-config" `tryElse`+ (getEnv "LLVM_CONFIG" >>= getLLVMDetails) `tryElse`+ (error "ERROR: cannot find llvm-config, please setup environment variable LLVM_CONFIG with location of llvm-config and try again")+ let pc = unlines $ ["Name: LLVM"+ ,"Description: Low-level Virtual Machine compiler framework"+ ,"Version: " ++ version+ ,"URL: http://www.llvm.org/"+ ,"Requires:"+ ,"Conflicts:"+ ,"Libs: -L" ++ libPath ++ " -lLLVM-" ++ version+ ,"Cflags: -I" ++ includePath]+ pkgConfigPath = "PKG_CONFIG_PATH"+ hPutStr outf pc+ hFlush outf+ mpc <- lookupEnv pkgConfigPath+ let pkgConfigPathVal = case mpc of+ Just pc -> pc ++ ":" ++ tmpPCPath+ Nothing -> tmpPCPath+ -- putStrLn $ pkgConfigPath ++ "=" ++ pkgConfigPathVal+ setEnv pkgConfigPath pkgConfigPathVal++withTmpPC runM = do+ cwd <- getCurrentDirectory+ let llvmPCFname = cwd </> "llvm.pc"+ bracket+ (openFile llvmPCFname WriteMode)+ (\outf -> hClose outf >> removeFile llvmPCFname)+ (runM cwd)++pcHook = simpleUserHooks { confHook = confHookM }+ where confHookM (gpd, hbi) cf = do+ let cdt = fromJust $ condLibrary gpd+ lib = condTreeData cdt+ lbi = libBuildInfo lib+ vRange = withinVersion $ makeVersion [3,8]+ lbi' = lbi { pkgconfigDepends = pkgconfigDepends lbi +++ [Dependency (PackageName "llvm") vRange] }+ lib' = lib { libBuildInfo = lbi' }+ gpd' = gpd { condLibrary = Just (cdt { condTreeData = lib' }) }+ (confHook simpleUserHooks) (gpd', hbi) cf++#if __GLASGOW_HASKELL__ < 710+makeVersion xs = Version xs []+#endif++main =+ withTmpPC $ \cwd outf -> do+ setupLLVMPkgConfig cwd outf+ defaultMainWithHooks pcHook
+ cbits/utils.c view
@@ -0,0 +1,24 @@+#include "utils.h"++unsigned codeCompleteGetNumResults(CXCodeCompleteResults* results)+{+ return results ? results->NumResults+ : 0;+}++// We don't perform any null or bounds checks here because this is an internal function+// with only one caller, but if we exposed this API publicly we'd have to do so.+enum CXCursorKind codeCompleteGetResult(CXCodeCompleteResults* results,+ unsigned index,+ CXCompletionString* stringOut)+{+ *stringOut = results->Results[index].CompletionString;+ return results->Results[index].CursorKind;+}++void freeClangString(void* data, unsigned flags) {+ CXString str;+ str.data = data;+ str.private_flags = flags;+ clang_disposeString(str);+}
+ cbits/utils.h view
@@ -0,0 +1,12 @@+#include <clang-c/Index.h>++// This file contains utility functions that make implementing the Haskell FFI+// code easier.++unsigned codeCompleteGetNumResults(CXCodeCompleteResults* results);++enum CXCursorKind codeCompleteGetResult(CXCodeCompleteResults* results,+ unsigned index,+ CXCompletionString* stringOut);++void freeClangString(void* data, unsigned flags);
+ cbits/visitors.c view
@@ -0,0 +1,333 @@+#include <stdlib.h>++#include "visitors.h"++#define INITIAL_LIST_CAPACITY 16+#define LIST_GROWTH_RATE 4++typedef struct+{+ CXCursor* items;+ unsigned count;+ size_t capacity;+} CursorList;++void freeCursorList(CXCursor* cursors)+{+ free(cursors);+}++#define LIST_INIT(_type) { \+ malloc(INITIAL_LIST_CAPACITY * sizeof(_type)), \+ 0, \+ INITIAL_LIST_CAPACITY \+ }++#define LIST_APPEND(_type, _list, _item) \+ do { \+ if (_list->count >= _list->capacity) { \+ size_t newCapacity = LIST_GROWTH_RATE * _list->capacity; \+ _list->items = \+ realloc(_list->items, newCapacity * sizeof(_type)); \+ _list->capacity = newCapacity; \+ } \+ \+ _list->items[_list->count++] = _item; \+ } while(0) \++enum CXChildVisitResult childListBuilder(CXCursor cursor, CXCursor parent,+ CXClientData clientData)+{+ CursorList* childList = (CursorList*) clientData;+ LIST_APPEND(CXCursor, childList, cursor);+ return CXChildVisit_Continue;+}++void getChildren(CXCursor parent, CXCursor** childrenOut, unsigned* countOut)+{+ CursorList childList = LIST_INIT(CXCursor);+ clang_visitChildren(parent, childListBuilder, &childList);+ *childrenOut = childList.items;+ *countOut = childList.count;+}++enum CXChildVisitResult descendantListBuilder(CXCursor cursor, CXCursor parent,+ CXClientData clientData)+{+ CursorList* childList = (CursorList*) clientData;+ LIST_APPEND(CXCursor, childList, cursor);+ return CXChildVisit_Recurse;+}++void getDescendants(CXCursor parent, CXCursor** childrenOut, unsigned* countOut)+{+ CursorList childList = LIST_INIT(CXCursor);+ clang_visitChildren(parent, descendantListBuilder, &childList);+ *childrenOut = childList.items;+ *countOut = childList.count;+}++enum CXChildVisitResult declarationListBuilder(CXCursor cursor, CXCursor parent,+ CXClientData clientData)+{+ if (clang_isDeclaration(clang_getCursorKind(cursor))) {+ CursorList* childList = (CursorList*) clientData;+ LIST_APPEND(CXCursor, childList, cursor);+ }+ return CXChildVisit_Recurse;+}++void getDeclarations(CXTranslationUnit tu, CXCursor** childrenOut, unsigned* countOut)+{+ CursorList childList = LIST_INIT(CXCursor);+ CXCursor parent = clang_getTranslationUnitCursor(tu);+ clang_visitChildren(parent, declarationListBuilder, &childList);+ *childrenOut = childList.items;+ *countOut = childList.count;+}++enum CXChildVisitResult referenceListBuilder(CXCursor cursor, CXCursor parent,+ CXClientData clientData)+{+ if (clang_isReference(clang_getCursorKind(cursor))) {+ CursorList* childList = (CursorList*) clientData;+ LIST_APPEND(CXCursor, childList, cursor);+ }+ return CXChildVisit_Recurse;+}++void getReferences(CXTranslationUnit tu, CXCursor** childrenOut, unsigned* countOut)+{+ CursorList childList = LIST_INIT(CXCursor);+ CXCursor parent = clang_getTranslationUnitCursor(tu);+ clang_visitChildren(parent, referenceListBuilder, &childList);+ *childrenOut = childList.items;+ *countOut = childList.count;+}++typedef struct+{+ CursorList decls;+ CursorList refs;+} CursorListPair;++enum CXChildVisitResult declAndRefListBuilder(CXCursor cursor, CXCursor parent,+ CXClientData clientData)+{+ CursorListPair* declsAndRefs = (CursorListPair*) clientData;++ if (clang_isDeclaration(clang_getCursorKind(cursor))) {+ CursorList* decls = &declsAndRefs->decls;+ LIST_APPEND(CXCursor, decls, cursor);+ }++ if (clang_isReference(clang_getCursorKind(cursor))) {+ CursorList* refs = &declsAndRefs->refs;+ LIST_APPEND(CXCursor, refs, cursor);+ }+ + return CXChildVisit_Recurse;+}++void getDeclarationsAndReferences(CXTranslationUnit tu,+ CXCursor** declsOut,+ unsigned* declCountOut,+ CXCursor** refsOut,+ unsigned* refCountOut)+{+ CursorListPair declsAndRefs = {+ LIST_INIT(CXCursor),+ LIST_INIT(CXCursor)+ };++ CXCursor parent = clang_getTranslationUnitCursor(tu);+ clang_visitChildren(parent, declAndRefListBuilder, &declsAndRefs);++ *declsOut = declsAndRefs.decls.items;+ *declCountOut = declsAndRefs.decls.count;+ *refsOut = declsAndRefs.refs.items;+ *refCountOut = declsAndRefs.refs.count;+}++typedef struct+{+ ParentedCursor* items;+ unsigned count;+ size_t capacity;+} ParentedCursorList;++void freeParentedCursorList(ParentedCursor* parentedCursors)+{+ free(parentedCursors);+}++enum CXChildVisitResult parentedDescendantListBuilder(CXCursor cursor, CXCursor parent,+ CXClientData clientData)+{+ ParentedCursorList* descendantList = (ParentedCursorList*) clientData;++ ParentedCursor newEntry = {+ parent,+ cursor+ };++ LIST_APPEND(ParentedCursor, descendantList, newEntry);++ return CXChildVisit_Recurse;+}++void getParentedDescendants(CXCursor parent, ParentedCursor** descendantsOut,+ unsigned* countOut)+{+ ParentedCursorList descendantList = LIST_INIT(ParentedCursor);+ clang_visitChildren(parent, parentedDescendantListBuilder, &descendantList);+ *descendantsOut = descendantList.items;+ *countOut = descendantList.count;+}++enum CXChildVisitResult parentedDeclarationListBuilder(CXCursor cursor, CXCursor parent,+ CXClientData clientData)+{+ ParentedCursorList* declarationList = (ParentedCursorList*) clientData;++ if (clang_isDeclaration(clang_getCursorKind(cursor))) {+ ParentedCursor newEntry = {+ parent,+ cursor+ };++ LIST_APPEND(ParentedCursor, declarationList, newEntry);+ }++ return CXChildVisit_Recurse;+}++void getParentedDeclarations(CXTranslationUnit tu, ParentedCursor** declarationsOut,+ unsigned* countOut)+{+ ParentedCursorList declarationList = LIST_INIT(ParentedCursor);+ CXCursor parent = clang_getTranslationUnitCursor(tu);+ clang_visitChildren(parent, parentedDeclarationListBuilder, &declarationList);+ *declarationsOut = declarationList.items;+ *countOut = declarationList.count;+}++enum CXChildVisitResult parentedReferenceListBuilder(CXCursor cursor, CXCursor parent,+ CXClientData clientData)+{+ ParentedCursorList* referenceList = (ParentedCursorList*) clientData;++ if (clang_isReference(clang_getCursorKind(cursor))) {+ ParentedCursor newEntry = {+ parent,+ cursor+ };++ LIST_APPEND(ParentedCursor, referenceList, newEntry);+ }++ return CXChildVisit_Recurse;+}++void getParentedReferences(CXTranslationUnit tu, ParentedCursor** referencesOut,+ unsigned* countOut)+{+ ParentedCursorList referenceList = LIST_INIT(ParentedCursor);+ CXCursor parent = clang_getTranslationUnitCursor(tu);+ clang_visitChildren(parent, parentedReferenceListBuilder, &referenceList);+ *referencesOut = referenceList.items;+ *countOut = referenceList.count;+}++typedef struct+{+ ParentedCursorList decls;+ ParentedCursorList refs;+} ParentedCursorListPair;++enum CXChildVisitResult parentedDeclAndRefListBuilder(CXCursor cursor,+ CXCursor parent,+ CXClientData clientData)+{+ ParentedCursorListPair* declsAndRefs = (ParentedCursorListPair*) clientData;++ if (clang_isDeclaration(clang_getCursorKind(cursor))) {+ ParentedCursor newEntry = {+ parent,+ cursor+ };++ ParentedCursorList* decls = &declsAndRefs->decls;+ LIST_APPEND(ParentedCursor, decls, newEntry);+ }++ if (clang_isReference(clang_getCursorKind(cursor))) {+ ParentedCursor newEntry = {+ parent,+ cursor+ };++ ParentedCursorList* refs = &declsAndRefs->refs;+ LIST_APPEND(ParentedCursor, refs, newEntry);+ }++ return CXChildVisit_Recurse;+}++void getParentedDeclarationsAndReferences(CXTranslationUnit tu,+ ParentedCursor** declsOut,+ unsigned* declCountOut,+ ParentedCursor** refsOut,+ unsigned* refCountOut)+{+ ParentedCursorListPair declsAndRefs = {+ LIST_INIT(ParentedCursor),+ LIST_INIT(ParentedCursor)+ };+ + CXCursor parent = clang_getTranslationUnitCursor(tu);+ clang_visitChildren(parent, parentedDeclAndRefListBuilder, &declsAndRefs);+ *declsOut = declsAndRefs.decls.items;+ *declCountOut = declsAndRefs.decls.count;+ *refsOut = declsAndRefs.refs.items;+ *refCountOut = declsAndRefs.refs.count;+}++typedef struct+{+ Inclusion* items;+ unsigned count;+ size_t capacity;+} InclusionList;++void freeInclusionList(Inclusion* inclusions)+{+ free(inclusions);+}++void inclusionListBuilder(CXFile includedFile, CXSourceLocation* inclusionStack,+ unsigned stackLen, CXClientData clientData)+{+ // Skip the initial file.+ if (stackLen == 0)+ return;+ + InclusionList* inclusionList = (InclusionList*) clientData;++ Inclusion newEntry = {+ includedFile,+ inclusionStack[0],+ stackLen == 1 // It's a direct inclusion if there's only one stack entry.+ };++ LIST_APPEND(Inclusion, inclusionList, newEntry);+}++void getInclusions(CXTranslationUnit tu, Inclusion** inclusionsOut,+ unsigned* countOut)+{+ InclusionList inclusionList = LIST_INIT(Inclusion);+ clang_getInclusions(tu, inclusionListBuilder, &inclusionList);+ *inclusionsOut = inclusionList.items;+ *countOut = inclusionList.count;+}
+ cbits/visitors.h view
@@ -0,0 +1,54 @@+#ifndef LIBCLANG_VISITORS_H+#define LIBCLANG_VISITORS_H++#include "clang-c/Index.h"++void freeCursorList(CXCursor* cursors);++typedef struct+{+ CXCursor parent;+ CXCursor cursor;+} ParentedCursor;++void freeParentedCursorList(ParentedCursor* parentedCursors);++// Wrappers for libclang traversals.+void getChildren(CXCursor parent, CXCursor** childrenOut, unsigned* countOut);+void getDescendants(CXCursor parent, CXCursor** childrenOut, unsigned* countOut);+void getDeclarations(CXTranslationUnit tu, CXCursor** declsOut, unsigned* declCountOut);+void getReferences(CXTranslationUnit tu, CXCursor** refsOut, unsigned* refCountOut);+void getDeclarationsAndReferences(CXTranslationUnit tu,+ CXCursor** declsOut, unsigned* declCountOut,+ CXCursor** refsOut, unsigned* refCountOut);++// Variants that include the parent of each cursor.+void getParentedDescendants(CXCursor parent,+ ParentedCursor** descendantsOut,+ unsigned* countOut);+void getParentedDeclarations(CXTranslationUnit tu,+ ParentedCursor** declsOut,+ unsigned* declCountOut);+void getParentedReferences(CXTranslationUnit tu,+ ParentedCursor** refsOut,+ unsigned* refCountOut);+void getParentedDeclarationsAndReferences(CXTranslationUnit tu,+ ParentedCursor** declsOut,+ unsigned* declCountOut,+ ParentedCursor** refsOut,+ unsigned* refCountOut);++// Wrappers for clang_getInclusions.+typedef struct+{+ CXFile inclusion;+ CXSourceLocation location;+ unsigned char isDirect;+} Inclusion;++void freeInclusionList(Inclusion* inclusions);++void getInclusions(CXTranslationUnit tu, Inclusion** inclusionsOut,+ unsigned* countOut);++#endif
+ cbits/wrappers.c view
@@ -0,0 +1,129 @@+#include "wrappers.h"+#include <stdlib.h>++WRAPPED_IMPL(CXSourceLocation, clang_getNullLocation, (), ());+WRAPPED_IMPL(CXSourceLocation, clang_getLocation, (CXTranslationUnit tu,+ CXFile file,+ unsigned line,+ unsigned column), (tu,+ file,+ line,+ column));+WRAPPED_IMPL(CXSourceLocation, clang_getLocationForOffset, (CXTranslationUnit tu,+ CXFile file,+ unsigned offset), (tu,+ file,+ offset));+WRAPPED_IMPL(CXSourceLocation, clang_getRangeStart, (CXSourceRange range), (range));+WRAPPED_IMPL(CXSourceLocation, clang_getRangeEnd, (CXSourceRange range), (range));+WRAPPED_IMPL(CXSourceLocation, clang_getDiagnosticLocation, (CXDiagnostic d), (d));+WRAPPED_IMPL(CXSourceLocation, clang_getCursorLocation, (CXCursor c), (c));+WRAPPED_IMPL(CXSourceLocation, clang_getTokenLocation, (CXTranslationUnit tu,+ CXToken token), (tu,+ token));++WRAPPED_IMPL(CXSourceRange,clang_getNullRange, (), ());+WRAPPED_IMPL(CXSourceRange,clang_getRange,(CXSourceLocation begin,+ CXSourceLocation end),(begin,+ end));+WRAPPED_IMPL(CXSourceRange,clang_getDiagnosticRange, (CXDiagnostic Diagnostic,+ unsigned Range),(Diagnostic,+ Range));+WRAPPED_IMPL(CXSourceRange,clang_getCursorExtent,(CXCursor c), (c));+WRAPPED_IMPL(CXSourceRange,clang_Cursor_getSpellingNameRange, (CXCursor c,+ unsigned pieceIndex,+ unsigned options),(c,+ pieceIndex,+ options));+WRAPPED_IMPL(CXSourceRange,clang_Cursor_getCommentRange, (CXCursor C), (C));+WRAPPED_IMPL(CXSourceRange,clang_getCursorReferenceNameRange, (CXCursor C,+ unsigned NameFlags,+ unsigned PieceIndex),(C,+ NameFlags,+ PieceIndex));+WRAPPED_IMPL(CXSourceRange,clang_getTokenExtent, (CXTranslationUnit tu, CXToken token), (tu, token));++WRAPPED_IMPL(CXCursor,clang_getNullCursor,(),());+WRAPPED_IMPL(CXCursor,clang_getTranslationUnitCursor,(CXTranslationUnit tu),(tu));+WRAPPED_IMPL(CXCursor,clang_getCursorSemanticParent,(CXCursor cursor),(cursor));+WRAPPED_IMPL(CXCursor,clang_getCursorLexicalParent,(CXCursor cursor),(cursor));+WRAPPED_IMPL(CXCursor,clang_getCursor,(CXTranslationUnit tu, CXSourceLocation sl),(tu, sl));+WRAPPED_IMPL(CXCursor,clang_Cursor_getArgument,(CXCursor C, unsigned i),(C, i));+WRAPPED_IMPL(CXCursor,clang_getTypeDeclaration,(CXType T),(T));+WRAPPED_IMPL(CXCursor,clang_getOverloadedDecl,(CXCursor cursor,+ unsigned index),(cursor, index));+WRAPPED_IMPL(CXCursor,clang_getCursorReferenced,(CXCursor c),(c));+WRAPPED_IMPL(CXCursor,clang_getCursorDefinition,(CXCursor c),(c));+WRAPPED_IMPL(CXCursor,clang_getCanonicalCursor,(CXCursor c),(c));+WRAPPED_IMPL(CXCursor,clang_getSpecializedCursorTemplate,(CXCursor C),(C));++WRAPPED_IMPL(CXComment,clang_Cursor_getParsedComment,(CXCursor C),(C));++WRAPPED_IMPL(CXType,clang_getCursorType,(CXCursor C),(C));+WRAPPED_IMPL(CXType,clang_getTypedefDeclUnderlyingType,(CXCursor C),(C));+WRAPPED_IMPL(CXType,clang_getEnumDeclIntegerType,(CXCursor C),(C));+WRAPPED_IMPL(CXType,clang_getCanonicalType,(CXType T),(T));+WRAPPED_IMPL(CXType,clang_getPointeeType,(CXType T),(T));+WRAPPED_IMPL(CXType,clang_getResultType,(CXType T),(T));+WRAPPED_IMPL(CXType,clang_getArgType,(CXType T, unsigned i),(T, i));+WRAPPED_IMPL(CXType,clang_getCursorResultType,(CXCursor C),(C));+WRAPPED_IMPL(CXType,clang_getElementType,(CXType T),(T));+WRAPPED_IMPL(CXType,clang_getArrayElementType,(CXType T),(T));+WRAPPED_IMPL(CXType,clang_Type_getClassType,(CXType T),(T));+WRAPPED_IMPL(CXType,clang_getIBOutletCollectionType,(CXCursor c),(c));+WRAPPED_IMPL(CXType,clang_Cursor_getReceiverType,(CXCursor C),(C));++WRAPPED_IMPL(CXString,clang_getFileName,(CXFile SFile),(SFile));+WRAPPED_IMPL(CXString,clang_formatDiagnostic,(CXDiagnostic Diagnostic,+ unsigned Options),(Diagnostic,+ Options));+WRAPPED_IMPL(CXString,clang_getDiagnosticSpelling,(CXDiagnostic d),(d));+WRAPPED_IMPL(CXString,clang_getDiagnosticOption,(CXDiagnostic Diag,+ CXString *Disable),(Diag,+ Disable));+WRAPPED_IMPL(CXString,clang_getDiagnosticCategoryText,(CXDiagnostic d),(d));+WRAPPED_IMPL(CXString,clang_getDiagnosticFixIt,(CXDiagnostic Diagnostic,+ unsigned FixIt,+ CXSourceRange *ReplacementRange),(Diagnostic,+ FixIt,+ ReplacementRange));+WRAPPED_IMPL(CXString,clang_getTranslationUnitSpelling,(CXTranslationUnit CTUnit),(CTUnit));;+WRAPPED_IMPL(CXString,clang_getTypeSpelling,(CXType CT),(CT));+WRAPPED_IMPL(CXString,clang_getDeclObjCTypeEncoding,(CXCursor C),(C));+WRAPPED_IMPL(CXString,clang_getTypeKindSpelling,(enum CXTypeKind K),(K));+WRAPPED_IMPL(CXString,clang_getCursorUSR,(CXCursor c),(c));+WRAPPED_IMPL(CXString,clang_constructUSR_ObjCClass,(const char *class_name),(class_name));+WRAPPED_IMPL(CXString,clang_constructUSR_ObjCCategory,(const char *class_name,+ const char *category_name),(class_name,+ category_name));;+WRAPPED_IMPL(CXString,clang_constructUSR_ObjCProtocol,(const char *protocol_name),(protocol_name));;+WRAPPED_IMPL(CXString,clang_constructUSR_ObjCIvar,(const char *name,+ CXString classUSR),(name,+ classUSR));+WRAPPED_IMPL(CXString,clang_constructUSR_ObjCMethod,(const char *name,+ unsigned isInstanceMethod,+ CXString classUSR),(name,+ isInstanceMethod,+ classUSR));+WRAPPED_IMPL(CXString,clang_constructUSR_ObjCProperty,(const char *property,+ CXString classUSR),(property,+ classUSR));+WRAPPED_IMPL(CXString,clang_getCursorSpelling,(CXCursor c),(c));+WRAPPED_IMPL(CXString,clang_getCursorDisplayName,(CXCursor c),(c));+WRAPPED_IMPL(CXString,clang_Cursor_getRawCommentText,(CXCursor C),(C));+WRAPPED_IMPL(CXString,clang_Cursor_getBriefCommentText,(CXCursor C),(C));+WRAPPED_IMPL(CXString,clang_Module_getName,(CXModule Module),(Module));+WRAPPED_IMPL(CXString,clang_Module_getFullName,(CXModule Module),(Module));+WRAPPED_IMPL(CXString,clang_TextComment_getText,(CXComment Comment),(Comment));+WRAPPED_IMPL(CXString,clang_HTMLTagComment_getTagName,(CXComment Comment),(Comment));+WRAPPED_IMPL(CXString,clang_VerbatimLineComment_getText,(CXComment Comment),(Comment));+WRAPPED_IMPL(CXString,clang_HTMLTagComment_getAsString,(CXComment Comment),(Comment));+WRAPPED_IMPL(CXString,clang_FullComment_getAsHTML,(CXComment Comment),(Comment));+WRAPPED_IMPL(CXString,clang_FullComment_getAsXML,(CXComment Comment),(Comment));+WRAPPED_IMPL(CXString,clang_getTokenSpelling,(CXTranslationUnit tu, CXToken token),(tu, token));+WRAPPED_IMPL(CXString,clang_getCursorKindSpelling,(enum CXCursorKind Kind),(Kind));+WRAPPED_IMPL(CXString,clang_getCompletionChunkText,(CXCompletionString completion_string, unsigned chunk_number),(completion_string, chunk_number));;+WRAPPED_IMPL(CXString,clang_getCompletionAnnotation,(CXCompletionString completion_string, unsigned annotation_number),(completion_string, annotation_number));;+WRAPPED_IMPL(CXString,clang_getCompletionParent,(CXCompletionString completion_string, enum CXCursorKind *kind),(completion_string, kind));;+WRAPPED_IMPL(CXString,clang_getCompletionBriefComment,(CXCompletionString completion_string),(completion_string));;+WRAPPED_IMPL(CXString,clang_getClangVersion,(),());
+ cbits/wrappers.h view
@@ -0,0 +1,125 @@+#include <clang-c/Index.h>+#include <clang-c/Documentation.h>++// This file contains wrappers around clang_* functions that return+// bare structs. Since bare structs are not supported by the Haskell+// FFI these functions+// 1. call the clang_* function+// 2. copy the returned struct to the heap+// 3. hand the caller a pointer to that location.++#define WRAPPED_HEADER(RETURN_TYPE, CLANG_FUNCTION, CLANG_FUNCTION_ARGS) \+ RETURN_TYPE* wrapped_##CLANG_FUNCTION CLANG_FUNCTION_ARGS+#define WRAPPED_IMPL(RETURN_TYPE, CLANG_FUNCTION, CLANG_FUNCTION_ARGS, CLANG_FUNCTION_CALL_ARGS) \+ RETURN_TYPE* wrapped_##CLANG_FUNCTION CLANG_FUNCTION_ARGS \+ { \+ RETURN_TYPE* ret = (void*) malloc(sizeof(RETURN_TYPE)); \+ *ret = CLANG_FUNCTION CLANG_FUNCTION_CALL_ARGS; \+ return ret; \+ }; \++WRAPPED_HEADER(CXSourceLocation, clang_getNullLocation, (void));+WRAPPED_HEADER(CXSourceLocation, clang_getLocation, (CXTranslationUnit tu,+ CXFile file,+ unsigned line,+ unsigned column));+WRAPPED_HEADER(CXSourceLocation, clang_getLocationForOffset, (CXTranslationUnit tu,+ CXFile file,+ unsigned offset));+WRAPPED_HEADER(CXSourceLocation, clang_getRangeStart, (CXSourceRange range));+WRAPPED_HEADER(CXSourceLocation, clang_getRangeEnd, (CXSourceRange range));+WRAPPED_HEADER(CXSourceLocation, clang_getDiagnosticLocation, (CXDiagnostic d));+WRAPPED_HEADER(CXSourceLocation, clang_getCursorLocation, (CXCursor c));+WRAPPED_HEADER(CXSourceLocation, clang_getTokenLocation, (CXTranslationUnit tu,+ CXToken token));++WRAPPED_HEADER(CXSourceRange,clang_getNullRange, (void));+WRAPPED_HEADER(CXSourceRange,clang_getRange,(CXSourceLocation begin,+ CXSourceLocation end));+WRAPPED_HEADER(CXSourceRange,clang_getDiagnosticRange,(CXDiagnostic Diagnostic,+ unsigned Range));+WRAPPED_HEADER(CXSourceRange,clang_getCursorExtent,(CXCursor));+WRAPPED_HEADER(CXSourceRange,clang_Cursor_getSpellingNameRange,(CXCursor,+ unsigned pieceIndex,+ unsigned options));+WRAPPED_HEADER(CXSourceRange,clang_Cursor_getCommentRange,(CXCursor C));+WRAPPED_HEADER(CXSourceRange,clang_getCursorReferenceNameRange,(CXCursor C,+ unsigned NameFlags,+ unsigned PieceIndex));+WRAPPED_HEADER(CXSourceRange,clang_getTokenExtent,(CXTranslationUnit, CXToken));++WRAPPED_HEADER(CXCursor,clang_getNullCursor,(void));+WRAPPED_HEADER(CXCursor,clang_getTranslationUnitCursor,(CXTranslationUnit));+WRAPPED_HEADER(CXCursor,clang_getCursorSemanticParent,(CXCursor cursor));+WRAPPED_HEADER(CXCursor,clang_getCursorLexicalParent,(CXCursor cursor));+WRAPPED_HEADER(CXCursor,clang_getCursor,(CXTranslationUnit, CXSourceLocation));+WRAPPED_HEADER(CXCursor,clang_Cursor_getArgument,(CXCursor C, unsigned i));+WRAPPED_HEADER(CXCursor,clang_getTypeDeclaration,(CXType T));+WRAPPED_HEADER(CXCursor,clang_getOverloadedDecl,(CXCursor cursor,+ unsigned index));+WRAPPED_HEADER(CXCursor,clang_getCursorReferenced,(CXCursor));+WRAPPED_HEADER(CXCursor,clang_getCursorDefinition,(CXCursor));+WRAPPED_HEADER(CXCursor,clang_getCanonicalCursor,(CXCursor));+WRAPPED_HEADER(CXCursor,clang_getSpecializedCursorTemplate,(CXCursor C));++WRAPPED_HEADER(CXComment,clang_Cursor_getParsedComment,(CXCursor C));++WRAPPED_HEADER(CXType,clang_getCursorType,(CXCursor C));+WRAPPED_HEADER(CXType,clang_getTypedefDeclUnderlyingType,(CXCursor C));+WRAPPED_HEADER(CXType,clang_getEnumDeclIntegerType,(CXCursor C));+WRAPPED_HEADER(CXType,clang_getCanonicalType,(CXType T));+WRAPPED_HEADER(CXType,clang_getPointeeType,(CXType T));+WRAPPED_HEADER(CXType,clang_getResultType,(CXType T));+WRAPPED_HEADER(CXType,clang_getArgType,(CXType T, unsigned i));+WRAPPED_HEADER(CXType,clang_getCursorResultType,(CXCursor C));+WRAPPED_HEADER(CXType,clang_getElementType,(CXType T));+WRAPPED_HEADER(CXType,clang_getArrayElementType,(CXType T));+WRAPPED_HEADER(CXType,clang_Type_getClassType,(CXType T));+WRAPPED_HEADER(CXType,clang_getIBOutletCollectionType,(CXCursor));+WRAPPED_HEADER(CXType,clang_Cursor_getReceiverType,(CXCursor C));++WRAPPED_HEADER(CXString,clang_getFileName,(CXFile SFile));+WRAPPED_HEADER(CXString,clang_formatDiagnostic,(CXDiagnostic Diagnostic,+ unsigned Options));+WRAPPED_HEADER(CXString,clang_getDiagnosticSpelling,(CXDiagnostic d));+WRAPPED_HEADER(CXString,clang_getDiagnosticOption,(CXDiagnostic Diag,+ CXString *Disable));+WRAPPED_HEADER(CXString,clang_getDiagnosticCategoryText,(CXDiagnostic d));+WRAPPED_HEADER(CXString,clang_getDiagnosticFixIt,(CXDiagnostic Diagnostic,+ unsigned FixIt,+ CXSourceRange *ReplacementRange));+WRAPPED_HEADER(CXString,clang_getTranslationUnitSpelling,(CXTranslationUnit CTUnit));;+WRAPPED_HEADER(CXString,clang_getTypeSpelling,(CXType CT));+WRAPPED_HEADER(CXString,clang_getDeclObjCTypeEncoding,(CXCursor C));+WRAPPED_HEADER(CXString,clang_getTypeKindSpelling,(enum CXTypeKind K));+WRAPPED_HEADER(CXString,clang_getCursorUSR,(CXCursor c));+WRAPPED_HEADER(CXString,clang_constructUSR_ObjCClass,(const char *class_name));+WRAPPED_HEADER(CXString,clang_constructUSR_ObjCCategory,(const char *class_name,+ const char *category_name));;+WRAPPED_HEADER(CXString,clang_constructUSR_ObjCProtocol,(const char *protocol_name));;+WRAPPED_HEADER(CXString,clang_constructUSR_ObjCIvar,(const char *name,+ CXString classUSR));+WRAPPED_HEADER(CXString,clang_constructUSR_ObjCMethod,(const char *name,+ unsigned isInstanceMethod,+ CXString classUSR));+WRAPPED_HEADER(CXString,clang_constructUSR_ObjCProperty,(const char *property,+ CXString classUSR));+WRAPPED_HEADER(CXString,clang_getCursorSpelling,(CXCursor c));+WRAPPED_HEADER(CXString,clang_getCursorDisplayName,(CXCursor c));+WRAPPED_HEADER(CXString,clang_Cursor_getRawCommentText,(CXCursor C));+WRAPPED_HEADER(CXString,clang_Cursor_getBriefCommentText,(CXCursor C));+WRAPPED_HEADER(CXString,clang_Module_getName,(CXModule Module));+WRAPPED_HEADER(CXString,clang_Module_getFullName,(CXModule Module));+WRAPPED_HEADER(CXString,clang_TextComment_getText,(CXComment Comment));+WRAPPED_HEADER(CXString,clang_HTMLTagComment_getTagName,(CXComment Comment));+WRAPPED_HEADER(CXString,clang_VerbatimLineComment_getText,(CXComment Comment));+WRAPPED_HEADER(CXString,clang_HTMLTagComment_getAsString,(CXComment Comment));+WRAPPED_HEADER(CXString,clang_FullComment_getAsHTML,(CXComment Comment));+WRAPPED_HEADER(CXString,clang_FullComment_getAsXML,(CXComment Comment));+WRAPPED_HEADER(CXString,clang_getTokenSpelling,(CXTranslationUnit tu, CXToken token));+WRAPPED_HEADER(CXString,clang_getCursorKindSpelling,(enum CXCursorKind Kind));+WRAPPED_HEADER(CXString,clang_getCompletionChunkText,(CXCompletionString completion_string, unsigned chunk_number));;+WRAPPED_HEADER(CXString,clang_getCompletionAnnotation,(CXCompletionString completion_string, unsigned annotation_number));;+WRAPPED_HEADER(CXString,clang_getCompletionParent,(CXCompletionString completion_string, enum CXCursorKind *kind));;+WRAPPED_HEADER(CXString,clang_getCompletionBriefComment,(CXCompletionString completion_string));;+WRAPPED_HEADER(CXString,clang_getClangVersion,());
+ src/Clang.hs view
@@ -0,0 +1,167 @@+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE ImpredicativeTypes #-}+{-# LANGUAGE RankNTypes #-}++-- | LibClang is a Haskell binding to the libclang library, a compiler+-- front-end for C-family languages. It allows you to produce and walk+-- an AST, get a list of diagnostic warnings and errors, perform code+-- completion, and more.+--+-- Your starting point for using LibClang should be this module, which+-- exports the 'ClangT' monad and the functions you'll need to start+-- analyzing source code. The other modules in this library, such as+-- "Clang.Cursor" and "Clang.Type", are meant to be imported+-- qualified, and provide the functions you'll need to get more+-- detailed information about the AST.+module Clang (+-- * Parsing+ parseSourceFile++-- * Traversing the AST+, FFI.CursorList+, getChildren+, getDescendants+, getDeclarations+, getReferences+, getDeclarationsAndReferences++, FFI.ParentedCursorList+, getParentedDescendants+, getParentedDeclarations+, getParentedReferences+, getParentedDeclarationsAndReferences++-- * Traversing inclusions+, FFI.Inclusion(..)+, FFI.InclusionList+, getInclusions++-- * The ClangT monad+, ClangT+, Clang+, ClangBase+, ClangValue(..)+, ClangValueList(..)+, clangScope++-- * Clang AST types+, FFI.AvailabilityKind(..)+, FFI.CursorKind(..)+, FFI.LinkageKind(..)+, FFI.LanguageKind(..)+, FFI.Cursor+, FFI.CursorSet+, FFI.ParentedCursor(..)+, FFI.ObjCPropertyAttrKind(..)+, FFI.ObjCDeclQualifierKind(..)+, FFI.NameRefFlags(..)+, FFI.Version(..)+, FFI.PlatformAvailability(..)+, FFI.PlatformAvailabilityInfo(..)+, FFI.Diagnostic+, FFI.DiagnosticSet+, FFI.File+, FFI.Remapping+, FFI.SourceLocation+, FFI.SourceRange+, FFI.ClangString+, FFI.Token+, FFI.TokenKind(..)+, FFI.Index+, FFI.TranslationUnit+, FFI.UnsavedFile+, FFI.Module (..)+, FFI.Type+, FFI.TypeKind(..)+, FFI.CallingConv(..)+, FFI.CXXAccessSpecifier(..)+, FFI.TypeLayoutError(..)+, FFI.RefQualifierKind(..)+) where++import qualified Data.Vector as DV++import qualified Clang.Internal.FFI as FFI+import qualified Clang.Index as Index+import Clang.Internal.Monad+import qualified Clang.TranslationUnit as TU++-- | Parses a source file using libclang and allows you to analyze the+-- resulting AST using a callback.+--+-- More flexible alternatives to 'parseSourceFile' are available in+-- "Clang.Index" and "Clang.TranslationUnit".+parseSourceFile :: ClangBase m+ => FilePath -- ^ Source filename+ -> [String] -- ^ Clang-compatible compilation arguments+ -> (forall s. FFI.TranslationUnit s -> ClangT s m a) -- ^ Callback+ -> m (Maybe a)+parseSourceFile path args f =+ Index.withNew False False $ \index ->+ TU.withParsed index (Just path) args DV.empty [] f++-- | Gets an 'FFI.CursorList' of the children of this 'FFI.Cursor'.+getChildren :: ClangBase m => FFI.Cursor s' -> ClangT s m (FFI.CursorList s)+getChildren = FFI.getChildren++-- | Gets an 'FFI.CursorList' of all descendants of this+-- 'FFI.Cursor'. If you are planning on visiting all the descendants+-- anyway, this is often more efficient than calling 'getChildren'+-- repeatedly. The descendants are listed according to a preorder+-- traversal of the AST.+getDescendants :: ClangBase m => FFI.Cursor s' -> ClangT s m (FFI.CursorList s)+getDescendants = FFI.getDescendants++-- | Like 'getDescendants', but each descendant is annotated with its+-- parent AST node. This provides enough information to replicate the+-- preorder traversal of the AST, but maintains the performance+-- benefits relative to 'getChildren'.+getParentedDescendants :: ClangBase m => FFI.Cursor s' -> ClangT s m (FFI.ParentedCursorList s)+getParentedDescendants = FFI.getParentedDescendants++-- | Gets an 'FFI.CursorList' of all declarations in this 'FFI.TranslationUnit'.+getDeclarations :: ClangBase m => FFI.TranslationUnit s' -> ClangT s m (FFI.CursorList s)+getDeclarations = FFI.getDeclarations++-- | Like 'getDeclarations', but each declaration is annotated with+-- its parent AST node.+getParentedDeclarations :: ClangBase m => FFI.TranslationUnit s'+ -> ClangT s m (FFI.ParentedCursorList s)+getParentedDeclarations = FFI.getParentedDeclarations++-- | Gets an 'FFI.CursorList' of all references in this 'FFI.TranslationUnit'.+getReferences :: ClangBase m => FFI.TranslationUnit s' -> ClangT s m (FFI.CursorList s)+getReferences = FFI.getReferences++-- | Like 'getReferences', but each reference is annotated with+-- its parent AST node.+getParentedReferences :: ClangBase m => FFI.TranslationUnit s'+ -> ClangT s m (FFI.ParentedCursorList s)+getParentedReferences = FFI.getParentedReferences++-- | Gets two 'FFI.CursorList's, one containing all declarations in+-- this 'FFI.TranslationUnit', and another containing all+-- references. If you need both lists, this is more efficient than+-- calling 'getDeclarations' and 'getReferences' individually, as it+-- only traverses the AST once.+getDeclarationsAndReferences :: ClangBase m => FFI.TranslationUnit s'+ -> ClangT s m (FFI.CursorList s, FFI.CursorList s)+getDeclarationsAndReferences = FFI.getDeclarationsAndReferences++-- | Like 'getDeclarationsAndReferences', but each reference is annotated with+-- its parent AST node.+getParentedDeclarationsAndReferences :: ClangBase m => FFI.TranslationUnit s'+ -> ClangT s m (FFI.ParentedCursorList s,+ FFI.ParentedCursorList s)+getParentedDeclarationsAndReferences = FFI.getParentedDeclarationsAndReferences++-- | Gets all inclusions in this 'FFI.TranslationUnit'.+getInclusions :: ClangBase m => FFI.TranslationUnit s' -> ClangT s m (FFI.InclusionList s)+getInclusions = FFI.getInclusions++-- | 'Clang' is a specialization of the 'ClangT' monad to 'IO',+-- provided as a convenience. If you have a more complicated monad+-- stack, you may find it useful to define your own 'Clang'-like+-- type synonym.+type Clang s a = ClangT s IO a
+ src/Clang/Comment.hs view
@@ -0,0 +1,113 @@+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE FlexibleContexts #-}++-- | Functions for traversing the comment AST and analyzing the nodes it contains.+--+-- To start traversing the comment AST, use 'Clang.Cursor.getParsedComment' to+-- retrieve the comment from an AST node that may be associated with one (for+-- example, any kind of declaration). You can access child nodes in the AST using+-- 'getChildren'. Most of the important information about comment AST nodes is+-- contained in the fields of the 'ParsedComment' type.+--+-- This module is intended to be imported qualified.+module Clang.Comment+(+-- * Navigating the comment AST+ getChildren++-- * Predicates and transformations+, isWhitespace+, hasTrailingNewline+, getTagCommentAsString+, getFullCommentAsHTML+, getFullCommentAsXML++-- * Comment AST nodes+, ParsedComment(..)+, ParamPassDirection(..)+, FFI.ParamPassDirectionKind (..)+, FFI.InlineCommandRenderStyle (..)+) where++import Control.Applicative+import Control.Monad+import Control.Monad.IO.Class+import Data.Maybe++import Clang.Internal.Comment+import qualified Clang.Internal.FFI as FFI+import Clang.Internal.Monad++-- | Returns the children nodes of the given comment in the comment AST.+getChildren :: ClangBase m => ParsedComment s' -> ClangT s m [ParsedComment s]+getChildren pc = do+ let c = getFFIComment pc+ numC <- liftIO $ FFI.comment_getNumChildren c+ mayCs <- forM [0..(numC - 1)] $ \i ->+ parseComment =<< liftIO (FFI.comment_getChild mkProxy c i)+ return $ catMaybes mayCs++-- | Returns 'True' if the provided comment is a 'TextComment' which is empty or contains+-- only whitespace, or if it is a 'ParagraphComment' which contains only whitespace+-- 'TextComment' nodes.+isWhitespace :: ClangBase m => ParsedComment s' -> ClangT s m Bool+isWhitespace c = liftIO $ FFI.comment_isWhitespace (getFFIComment c)++-- | Returns 'True' if the provided comment is inline content and has a newline immediately+-- following it in the comment text. Newlines between paragraphs do not count.+hasTrailingNewline :: ClangBase m => ParsedComment s' -> ClangT s m Bool+hasTrailingNewline c = liftIO $ FFI.inlineContentComment_hasTrailingNewline (getFFIComment c)++-- | Returns a string representation of an 'HTMLStartTagComment' or 'HTMLEndTagComment'.+-- For other kinds of comments, returns 'Nothing'.+getTagCommentAsString :: ClangBase m => ParsedComment s' -> ClangT s m (Maybe (FFI.ClangString s))+getTagCommentAsString (HTMLStartTagComment c _ _ _) = Just <$> FFI.hTMLTagComment_getAsString c+getTagCommentAsString (HTMLEndTagComment c _) = Just <$> FFI.hTMLTagComment_getAsString c+getTagCommentAsString _ = return Nothing++-- | Converts the given 'FullComment' to an HTML fragment.+--+-- Specific details of HTML layout are subject to change. Don't try to parse+-- this HTML back into an AST; use other APIs instead.+--+-- Currently the following CSS classes are used:+--+-- * \"para-brief\" for \'brief\' paragraph and equivalent commands;+--+-- * \"para-returns\" for \'returns\' paragraph and equivalent commands;+--+-- * \"word-returns\" for the \"Returns\" word in a \'returns\' paragraph.+--+-- Function argument documentation is rendered as a \<dl\> list with arguments+-- sorted in function prototype order. The following CSS classes are used:+--+-- * \"param-name-index-NUMBER\" for parameter name (\<dt\>);+--+-- * \"param-descr-index-NUMBER\" for parameter description (\<dd\>);+--+-- * \"param-name-index-invalid\" and \"param-descr-index-invalid\" are used if+-- parameter index is invalid.+--+-- Template parameter documentation is rendered as a \<dl\> list with+-- parameters sorted in template parameter list order. The following CSS classes are used:+--+-- * \"tparam-name-index-NUMBER\" for parameter name (\<dt\>);+--+-- * \"tparam-descr-index-NUMBER\" for parameter description (\<dd\>);+--+-- * \"tparam-name-index-other\" and \"tparam-descr-index-other\" are used for+-- names inside template template parameters;+--+-- * \"tparam-name-index-invalid\" and \"tparam-descr-index-invalid\" are used if+-- parameter position is invalid.+getFullCommentAsHTML :: ClangBase m => ParsedComment s' -> ClangT s m (Maybe (FFI.ClangString s))+getFullCommentAsHTML (FullComment c) = Just <$> FFI.fullComment_getAsHTML c+getFullCommentAsHTML _ = return Nothing++-- | Converts the given 'FullComment' to an XML document.+--+-- A Relax NG schema for the XML is distributed in the \"comment-xml-schema.rng\" file+-- inside the libclang source tree.+getFullCommentAsXML :: ClangBase m => ParsedComment s' -> ClangT s m (Maybe (FFI.ClangString s))+getFullCommentAsXML (FullComment c) = Just <$> FFI.fullComment_getAsXML c+getFullCommentAsXML _ = return Nothing
+ src/Clang/Completion.hs view
@@ -0,0 +1,225 @@+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE DeriveDataTypeable #-}+{-# LANGUAGE FlexibleContexts #-}++-- | Functions for performing code completion.+--+-- To get started with code completion, it's enough to parse a file with+-- 'Clang.parseSourceFile' and pass the 'FFI.TranslationUnit' to 'codeCompleteAt'.+-- This will return a 'FFI.CodeCompleteResults' value, from which you can+-- retrieve a list of completion strings using 'getResults'. Each completion+-- string in turn consists of a series of chunks, which you can retrieve using+-- 'getChunks'.+--+-- This module is intended to be imported qualified.+module Clang.Completion+(+-- * Code completion+ codeCompleteAt+, FFI.CodeCompleteFlags(..)+, FFI.CodeCompleteResults++-- * Completion results+, getResults+, FFI.CompletionString+, sortResults+, getDiagnostics+, getContexts+, FFI.CompletionContext(..)+, getContainerKind+, getContainerUSR+, getObjCSelector++-- * Completion strings+, getChunks+, Chunk(..)+, FFI.ChunkKind(..)+, getPriority+, getAvailability+, getAnnotations+, getParent+, getBriefComment+) where++import Control.Applicative+import Control.Monad+import Control.Monad.IO.Class+import Data.Typeable+import qualified Data.Vector as DV++import Clang.Internal.BitFlags+import qualified Clang.Internal.FFI as FFI+import Clang.Internal.Monad++-- | Perform code completion at a given location in a translation unit.+--+-- This function performs code completion at a particular file, line, and+-- column within source code, providing results that suggest potential+-- code snippets based on the context of the completion. The basic model+-- for code completion is that Clang will parse a complete source file,+-- performing syntax checking up to the location where code completion has+-- been requested. At that point, a special code completion token is passed+-- to the parser, which recognizes this token and determines, based on the+-- current location in the C \/ Objective-C \/ C++ grammar and the state of+-- semantic analysis, what completions to provide. These completions are+-- returned via a 'FFI.CodeCompleteResults' value.+--+-- Code completion itself is meant to be triggered by the client when the+-- user types punctuation characters or whitespace, at which point the+-- code completion location will coincide with the cursor. For example, if \'p\'+-- is a pointer, code completion might be triggered after the \'-\' and then+-- after the \'>\' in \'p->\'. When the code completion location is after the \'>\',+-- the completion results will provide, e.g., the members of the struct that+-- \'p\' points to. The client is responsible for placing the cursor at the+-- beginning of the token currently being typed, then filtering the results+-- based on the contents of the token. For example, when code-completing for+-- the expression \'p->get\', the client should provide the location just after+-- the \'>\' (e.g., pointing at the \'g\') to this code completion hook. Then, the+-- client can filter the results based on the current token text (\'get\'), only+-- showing those results that start with \'get\'. The intent of this interface+-- is to separate the relatively high-latency acquisition of code completion+-- results from the filtering of results on a per-character basis, which must+-- have a lower latency.+codeCompleteAt ::+ ClangBase m+ => FFI.TranslationUnit s' -- ^ The translation unit in which code completion should occur.+ -- The source files for this translation unit need not be+ -- completely up-to-date (and the contents of those source files+ -- may be overridden via the 'FFI.UnsavedFile' vector). Cursors+ -- referring into the translation unit may be invalidated by+ -- this invocation.+ -> FilePath -- ^ The name of the source file where code+ -- completion should be performed. This filename may be any file+ -- included in the translation unit.+ -> Int -- ^ The line at which code completion should occur.+ -> Int -- ^ The column at which code completion should occur.+ -- Note that the column should point just after the syntactic construct that+ -- initiated code completion, and not in the middle of a lexical token.+ -> DV.Vector FFI.UnsavedFile -- ^ Files that have not yet been saved to disk+ -- but may be required for parsing or code completion, including+ -- the contents of those files. The contents and name of these+ -- files (as specified by 'FFI.UnsavedFile') are copied when+ -- necessary, so the client only needs to guarantee their+ -- validity until the call to this function returns.+ -> Maybe [FFI.CodeCompleteFlags] -- ^ Extra options that control the behavior of code+ -- completion, or 'Nothing' to use the default set.+ -> ClangT s m (FFI.CodeCompleteResults s)+codeCompleteAt t fname l c ufs mayOpts = do+ opts <- case mayOpts of+ Just os -> return os+ Nothing -> unFlags <$> liftIO FFI.defaultCodeCompleteOptions+ FFI.codeCompleteAt t fname l c ufs (orFlags opts)++-- | Retrieves a list of code completion results.+--+-- The first element of each tuple is the completion string, which describes how to insert+-- this result into the editing buffer. Use 'getChunks' to analyze it further.+--+-- The second element of each tuple is the kind of entity that this completion refers to.+-- It will be a macro, keyword, or declaration describing the entity that the completion+-- is referring to.+getResults :: ClangBase m => FFI.CodeCompleteResults s'+ -> ClangT s m [(FFI.CompletionString s, FFI.CursorKind)]+getResults rs = do+ numS <- liftIO $ FFI.codeCompleteGetNumResults rs+ forM [0..(numS - 1)] $ \i ->+ FFI.codeCompleteGetResult rs i++-- | Sort the provided code completion results in case-insensitive alphabetical order.+sortResults :: ClangBase m => FFI.CodeCompleteResults s' -> ClangT s m ()+sortResults c = liftIO $ FFI.sortCodeCompletionResults c++-- | Retrieves the diagnostics associated with the given code completion.+getDiagnostics :: ClangBase m => FFI.CodeCompleteResults s' -> ClangT s m [FFI.Diagnostic s]+getDiagnostics c = do+ numD <- liftIO $ FFI.codeCompleteGetNumDiagnostics c+ mapM (FFI.codeCompleteGetDiagnostic c) [0..(numD - 1)]++-- | Determines which kinds of completions are appropriate for the context+-- of the given code completion.+getContexts :: ClangBase m => FFI.CodeCompleteResults s' -> ClangT s m [FFI.CompletionContext]+getContexts rs = unFlags <$> liftIO (FFI.codeCompleteGetContexts rs)++-- | Returns a cursor kind for the container associated with the given code+-- completion. Only contexts like member accesses and Objective-C message sends+-- have containers; for other kinds of contexts, a cursor kind of+-- 'FFI.InvalidCodeCursor' is returned.+--+-- The second element of the result tuple is a boolean indicating whether libclang+-- has incomplete information about the container. A 'True' value indicates that+-- information about the container is incomplete.+getContainerKind :: ClangBase m => FFI.CodeCompleteResults s'+ -> ClangT s m (FFI.CursorKind, Bool)+getContainerKind rs = liftIO $ FFI.codeCompleteGetContainerKind rs++-- | Given a code completion context, returns a "Clang.USR" for the appropriate+-- container. Only contexts like member accesses and Objective-C message sends+-- have containers; for other kinds of contexts, the empty string is returned.+getContainerUSR :: ClangBase m => FFI.CodeCompleteResults s' -> ClangT s m (FFI.ClangString s)+getContainerUSR = FFI.codeCompleteGetContainerUSR++-- | Returns the currently-entered selector for an Objective-C message+-- send, formatted like \"initWithFoo:bar:\". This function is only guaranteed+-- to return a non-empty string if the completion context is an Objective-C+-- instance message or class message send, which you can check with 'getContexts'.+getObjCSelector :: ClangBase m => FFI.CodeCompleteResults s' -> ClangT s m (FFI.ClangString s)+getObjCSelector = FFI.codeCompleteGetObjCSelector++-- | The completion string is a template that describes not only the completion itself,+-- but also information about how it should be presented to the user. It is divided into+-- a list of chunks, with each kind of chunk playing a different role in the template.+data Chunk s+ = TextChunk FFI.ChunkKind (FFI.ClangString s)+ | OptionalChunk (FFI.CompletionString s)+ deriving (Eq, Ord, Typeable)++-- | Retrieves the chunks within a completion string.+--+-- Each \"chunk\" contains either a piece of text with a specific \"kind\"+-- that describes how that text should be interpreted by the client, or+-- another completion string.+getChunks :: ClangBase m => FFI.CompletionString s' -> ClangT s m [Chunk s]+getChunks cs = do+ numC <- liftIO $ FFI.getNumCompletionChunks cs+ forM [0..(numC - 1)] $ \i -> do+ kind <- liftIO $ FFI.getCompletionChunkKind cs i+ case kind of+ FFI.OptionalChunkKind ->+ OptionalChunk <$> (liftIO $ FFI.getCompletionChunkCompletionString cs i)+ _ ->+ TextChunk kind <$> FFI.getCompletionChunkText cs i++-- | Determines the priority of this code completion string.+--+-- The priority of a code completion indicates how likely it is that this+-- particular completion is the completion that the user will select. The+-- priority is selected by various internal heuristics. Smaller values+-- indicate more likely completions.+getPriority :: ClangBase m => FFI.CompletionString s' -> ClangT s m Int+getPriority cs = liftIO $ FFI.getCompletionPriority cs++-- | Determines the availability of the entity that this code completion+-- string refers to.+getAvailability :: ClangBase m => FFI.CompletionString s' -> ClangT s m FFI.AvailabilityKind+getAvailability cs = liftIO $ FFI.getCompletionAvailability cs++-- | Retrieves the annotations associated with the given completion string.+getAnnotations :: ClangBase m => FFI.CompletionString s' -> ClangT s m [FFI.ClangString s]+getAnnotations cs = do+ numA <- liftIO $ FFI.getCompletionNumAnnotations cs+ mapM (FFI.getCompletionAnnotation cs) [0..(numA - 1)]++-- | Retrieves the parent context of the given completion string.+--+-- The parent context of a completion string is the semantic parent of+-- the declaration (if any) that the code completion represents. For example,+-- a code completion for an Objective-C method would have the method's class+-- or protocol as its context. A completion string representing a method on+-- the NSObject class might have a parent context of \"NSObject\".+getParent :: ClangBase m => FFI.CompletionString s' -> ClangT s m (FFI.ClangString s)+getParent = FFI.getCompletionParent++-- | Retrieves the brief documentation comment attached to the declaration+-- that corresponds to the given completion string.+getBriefComment :: ClangBase m => FFI.CompletionString s' -> ClangT s m (FFI.ClangString s)+getBriefComment = FFI.getCompletionBriefComment
+ src/Clang/Cursor.hs view
@@ -0,0 +1,329 @@+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE FlexibleContexts #-}++{-|+ The Cursor is an easy way to reference something in code and query its properties and relationships+ This is the primary way of traversing and querying code+-}+module Clang.Cursor+( isNullCursor+, nullCursor+, getHash+, getKind+, getLinkage+, getAvailability+, getLanguage+, getTranslationUnit+, getSemanticParent+, getLexicalParent+, getOverriddenCursors+, getIncludedFile+, getLocation+, getSpellingLocation+, getExtent+, getType+, getResultType+, getDeclObjCTypeEncoding+, getSpelling+, getSpellingNameRange+, getDisplayName+, getReferenced+, getDefinition+, getCanonicalCursor+, getObjCSelectorIndex+, getReceiverType+, getObjCPropertyAttributes+, getObjCDeclQualifiers+, isObjCOptional+, isVariadic+, getTemplateKind+, getTemplateForSpecialization+, getReferenceNameRange+, getTypeDeclaration+, getNumArguments+, getArgument+, getUSR++-- attribute function+, getIBOutletCollectionType++, isDefinition+, isDeclaration+, isReference+, isExpression+, isStatement+, isAttribute+, isInvalid+, isTranslationUnit+, isPreprocessing+, isUnexposed+, isBitField+, isVirtualBase+, isPureVirtualCppMethod+, isStaticCppMethod+, isVirtualCppMethod+, isDynamicCall+, getCommentRange+, getRawCommentText+, getBriefCommentText+, getParsedComment+, getModule+, getCXXAccessSpecifier+, getOverloadedDecls++-- CursorSet functions+, createSet+, setContains+, setInsert++-- CursorKind functions+, getCursorKindSpelling++-- Platform availability+, getCursorPlatformAvailability++, getCompletionString+) where++import Control.Applicative+import Control.Monad.IO.Class+import GHC.Word++import Clang.Internal.BitFlags+import Clang.Internal.Comment+import qualified Clang.Internal.FFI as FFI+import Clang.Internal.Monad++isNullCursor :: FFI.Cursor s -> Bool+isNullCursor = FFI.cursor_isNull+{-# INLINE isNullCursor #-}++nullCursor :: ClangBase m => ClangT s m (FFI.Cursor s)+nullCursor = FFI.getNullCursor+{-# INLINE nullCursor #-}++getHash :: ClangBase m => FFI.Cursor s' -> ClangT s m GHC.Word.Word32+getHash c = liftIO $ FFI.hashCursor c++getKind :: FFI.Cursor s -> FFI.CursorKind+getKind = FFI.getCursorKind+{-# INLINE getKind #-}++getLinkage :: ClangBase m => FFI.Cursor s' -> ClangT s m FFI.LinkageKind+getLinkage c = liftIO $ FFI.getCursorLinkage c++getAvailability :: ClangBase m => FFI.Cursor s' -> ClangT s m FFI.AvailabilityKind+getAvailability c = liftIO $ FFI.getCursorAvailability c++getLanguage :: ClangBase m => FFI.Cursor s' -> ClangT s m FFI.LanguageKind+getLanguage c = liftIO $ FFI.getCursorLanguage c++getTranslationUnit :: ClangBase m => FFI.Cursor s' -> ClangT s m (FFI.TranslationUnit s)+getTranslationUnit = FFI.cursor_getTranslationUnit++getSemanticParent :: ClangBase m => FFI.Cursor s' -> ClangT s m (FFI.Cursor s)+getSemanticParent c = liftIO $ FFI.getCursorSemanticParent mkProxy c++getLexicalParent :: ClangBase m => FFI.Cursor s' -> ClangT s m (FFI.Cursor s)+getLexicalParent c = liftIO $ FFI.getCursorLexicalParent mkProxy c++getOverriddenCursors :: ClangBase m => FFI.Cursor s' -> ClangT s m (FFI.CursorList s)+getOverriddenCursors = FFI.getOverriddenCursors++getIncludedFile :: ClangBase m => FFI.Cursor s' -> ClangT s m (Maybe (FFI.File s))+getIncludedFile c = liftIO $ FFI.getIncludedFile mkProxy c++getLocation :: ClangBase m => FFI.Cursor s' -> ClangT s m (FFI.SourceLocation s)+getLocation c = liftIO $ FFI.getCursorLocation mkProxy c++getSpellingLocation :: ClangBase m => FFI.Cursor s'+ -> ClangT s m (Maybe (FFI.File s), Int, Int, Int)+getSpellingLocation l = liftIO $ FFI.getCursorSpellingLocation mkProxy l++getExtent :: ClangBase m => FFI.Cursor s' -> ClangT s m (FFI.SourceRange s)+getExtent c = liftIO $ FFI.getCursorExtent mkProxy c++getType :: ClangBase m => FFI.Cursor s' -> ClangT s m (FFI.Type s)+getType c = liftIO $ FFI.getCursorType mkProxy c++getResultType :: ClangBase m => FFI.Cursor s' -> ClangT s m (FFI.Type s)+getResultType c = liftIO $ FFI.getCursorResultType mkProxy c++getDeclObjCTypeEncoding :: ClangBase m => FFI.Cursor s' -> ClangT s m (FFI.ClangString s)+getDeclObjCTypeEncoding = FFI.getDeclObjCTypeEncoding++getSpelling :: ClangBase m => FFI.Cursor s' -> ClangT s m (FFI.ClangString s)+getSpelling = FFI.getCursorSpelling++getSpellingNameRange :: ClangBase m => FFI.Cursor s' -> Int -> ClangT s m (FFI.SourceRange s)+getSpellingNameRange c idx = liftIO $ FFI.cursor_getSpellingNameRange mkProxy c idx++getDisplayName :: ClangBase m => FFI.Cursor s' -> ClangT s m (FFI.ClangString s)+getDisplayName = FFI.getCursorDisplayName++getReferenced :: ClangBase m => FFI.Cursor s' -> ClangT s m (FFI.Cursor s)+getReferenced c = liftIO $ FFI.getCursorReferenced mkProxy c++getDefinition :: ClangBase m => FFI.Cursor s' -> ClangT s m (FFI.Cursor s)+getDefinition c = liftIO $ FFI.getCursorDefinition mkProxy c++getCanonicalCursor :: ClangBase m => FFI.Cursor s' -> ClangT s m (FFI.Cursor s)+getCanonicalCursor c = liftIO $ FFI.getCanonicalCursor mkProxy c++getObjCSelectorIndex :: ClangBase m => FFI.Cursor s' -> ClangT s m Int+getObjCSelectorIndex c = liftIO $ FFI.cursor_getObjCSelectorIndex c++getReceiverType :: ClangBase m => FFI.Cursor s' -> ClangT s m (FFI.Type s)+getReceiverType c = liftIO $ FFI.cursor_getReceiverType mkProxy c++getObjCPropertyAttributes :: ClangBase m => FFI.Cursor s'+ -> ClangT s m [FFI.ObjCPropertyAttrKind]+getObjCPropertyAttributes c = unFlags <$> liftIO (FFI.cursor_getObjCPropertyAttributes c)++getObjCDeclQualifiers :: ClangBase m => FFI.Cursor s' -> ClangT s m [FFI.ObjCDeclQualifierKind]+getObjCDeclQualifiers c = unFlags <$> liftIO (FFI.cursor_getObjCDeclQualifiers c)++isObjCOptional :: ClangBase m => FFI.Cursor s' -> ClangT s m Bool+isObjCOptional c = liftIO $ FFI.cursor_isObjCOptional c++isVariadic :: ClangBase m => FFI.Cursor s' -> ClangT s m Bool+isVariadic c = liftIO $ FFI.cursor_isVariadic c++getTemplateKind :: ClangBase m => FFI.Cursor s' -> ClangT s m FFI.CursorKind+getTemplateKind c = liftIO $ FFI.getTemplateCursorKind c++getTemplateForSpecialization :: ClangBase m => FFI.Cursor s' -> ClangT s m (FFI.Cursor s)+getTemplateForSpecialization c = liftIO $ FFI.getSpecializedCursorTemplate mkProxy c++getReferenceNameRange :: ClangBase m => FFI.Cursor s' -> [FFI.NameRefFlags] -> Int+ -> ClangT s m (FFI.SourceRange s)+getReferenceNameRange c fs p = liftIO $ FFI.getCursorReferenceNameRange mkProxy c (orFlags fs) p++getTypeDeclaration :: ClangBase m => FFI.Type s' -> ClangT s m (FFI.Cursor s)+getTypeDeclaration t = liftIO $ FFI.getTypeDeclaration mkProxy t++getNumArguments :: ClangBase m => FFI.Cursor s' -> ClangT s m Int+getNumArguments c = liftIO $ FFI.cursor_getNumArguments c++getArgument :: ClangBase m => FFI.Cursor s' -> Int -> ClangT s m (FFI.Cursor s)+getArgument c i = liftIO $ FFI.cursor_getArgument mkProxy c i++getUSR :: ClangBase m => FFI.Cursor s' -> ClangT s m (FFI.ClangString s)+getUSR = FFI.getCursorUSR++-- attribute function++getIBOutletCollectionType :: ClangBase m => FFI.Cursor s' -> ClangT s m (FFI.Type s)+getIBOutletCollectionType c = liftIO $ FFI.getIBOutletCollectionType mkProxy c++isDefinition :: ClangBase m => FFI.Cursor s' -> ClangT s m Bool+isDefinition c = liftIO $ FFI.isCursorDefinition c++isDeclaration :: FFI.CursorKind -> Bool+isDeclaration = FFI.isDeclaration+{-# INLINE isDeclaration #-}++isReference :: FFI.CursorKind -> Bool+isReference = FFI.isReference+{-# INLINE isReference #-}++isExpression :: FFI.CursorKind -> Bool+isExpression = FFI.isExpression+{-# INLINE isExpression #-}++isStatement :: FFI.CursorKind -> Bool+isStatement = FFI.isStatement+{-# INLINE isStatement #-}++isAttribute :: FFI.CursorKind -> Bool+isAttribute = FFI.isAttribute+{-# INLINE isAttribute #-}++isInvalid :: FFI.CursorKind -> Bool+isInvalid = FFI.isInvalid+{-# INLINE isInvalid #-}++isTranslationUnit :: FFI.CursorKind -> Bool+isTranslationUnit = FFI.isTranslationUnit+{-# INLINE isTranslationUnit #-}++isPreprocessing :: FFI.CursorKind -> Bool+isPreprocessing = FFI.isPreprocessing+{-# INLINE isPreprocessing #-}++isUnexposed :: FFI.CursorKind -> Bool+isUnexposed = FFI.isUnexposed+{-# INLINE isUnexposed #-}++isBitField :: ClangBase m => FFI.Cursor s' -> ClangT s m Bool+isBitField c = liftIO $ FFI.isBitField c++isVirtualBase :: ClangBase m => FFI.Cursor s' -> ClangT s m Bool+isVirtualBase c = liftIO $ FFI.isVirtualBase c++isPureVirtualCppMethod :: ClangBase m => FFI.Cursor s' -> ClangT s m Bool+isPureVirtualCppMethod c = liftIO $ FFI.cXXMethod_isPureVirtual c++isStaticCppMethod :: ClangBase m => FFI.Cursor s' -> ClangT s m Bool+isStaticCppMethod c = liftIO $ FFI.cXXMethod_isStatic c++isVirtualCppMethod :: ClangBase m => FFI.Cursor s' -> ClangT s m Bool+isVirtualCppMethod c = liftIO $ FFI.cXXMethod_isVirtual c++isDynamicCall :: ClangBase m => FFI.Cursor s' -> ClangT s m Bool+isDynamicCall c = liftIO $ FFI.cursor_isDynamicCall c++getCommentRange :: ClangBase m => FFI.Cursor s' -> ClangT s m (FFI.SourceRange s)+getCommentRange c = liftIO $ FFI.cursor_getCommentRange mkProxy c++getRawCommentText :: ClangBase m => FFI.Cursor s' -> ClangT s m (FFI.ClangString s)+getRawCommentText = FFI.cursor_getRawCommentText++getBriefCommentText :: ClangBase m => FFI.Cursor s' -> ClangT s m (FFI.ClangString s)+getBriefCommentText = FFI.cursor_getBriefCommentText++getParsedComment :: ClangBase m => FFI.Cursor s' -> ClangT s m (Maybe (ParsedComment s))+getParsedComment c = do+ comment <- liftIO $ FFI.cursor_getParsedComment mkProxy c+ parseComment comment++getModule :: ClangBase m => FFI.Cursor s' -> ClangT s m (FFI.Module s)+getModule c = liftIO $ FFI.cursor_getModule mkProxy c++getCXXAccessSpecifier :: ClangBase m => FFI.Cursor s' -> ClangT s m FFI.CXXAccessSpecifier+getCXXAccessSpecifier c = liftIO $ FFI.getCXXAccessSpecifier c++getOverloadedDecls :: ClangBase m => FFI.Cursor s' -> ClangT s m [FFI.Cursor s]+getOverloadedDecls c = liftIO $ do+ numDecls <- FFI.getNumOverloadedDecls c+ mapM (FFI.getOverloadedDecl mkProxy c) [0..(numDecls - 1)]++-- CursorSet functions++createSet :: ClangBase m => ClangT s m (FFI.CursorSet s)+createSet = FFI.createCXCursorSet++setContains :: ClangBase m => FFI.CursorSet s' -> FFI.Cursor s'' -> ClangT s m Bool+setContains s c = liftIO $ FFI.cXCursorSet_contains s c++setInsert :: ClangBase m => FFI.CursorSet s' -> FFI.Cursor s'' -> ClangT s m Bool+setInsert s c = liftIO $ FFI.cXCursorSet_insert s c+++-- CursorKind functions++getCursorKindSpelling :: ClangBase m => FFI.CursorKind -> ClangT s m (FFI.ClangString s)+getCursorKindSpelling = FFI.getCursorKindSpelling++-- Platform availability++getCursorPlatformAvailability :: ClangBase m => FFI.Cursor s'+ -> ClangT s m (FFI.PlatformAvailabilityInfo s)+getCursorPlatformAvailability = FFI.getCursorPlatformAvailability++-- | Retrieve a completion string for an arbitrary declaration or macro+-- definition cursor.+--+-- Completion strings can be manipulated using the functions in "Clang.Completion".+getCompletionString :: ClangBase m => FFI.Cursor s' -> ClangT s m (FFI.CompletionString s)+getCompletionString = FFI.getCursorCompletionString
+ src/Clang/Debug.hs view
@@ -0,0 +1,23 @@+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE FlexibleContexts #-}++-- | This module contains debug-related functionality.+module Clang.Debug+( setCrashRecoveryEnabled+, enableStackTraces+) where++import Control.Monad.IO.Class++import qualified Clang.Internal.FFI as FFI+import Clang.Internal.Monad++-- | Enable or disable crash recovery.+setCrashRecoveryEnabled :: ClangBase m+ => Bool -- ^ Whether crash recovery should be enabled.+ -> ClangT s m ()+setCrashRecoveryEnabled enable = liftIO $ FFI.toggleCrashRecovery enable++-- | Enable stack traces when crashes occur.+enableStackTraces :: ClangBase m => ClangT s m ()+enableStackTraces = liftIO FFI.enableStackTraces
+ src/Clang/Diagnostic.hs view
@@ -0,0 +1,151 @@+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE FlexibleContexts #-}++-- | Functions for manipulating 'FFI.Diagnostic's, which represent+-- diagnostics - warnings, errors, and the like - produced by libclang.+--+-- 'FFI.Diagnostic's are grouped into 'FFI.DiagnosticSet's. You+-- usually obtain a 'FFI.DiagnosticSet' from a 'FFI.TranslationUnit'+-- using 'Clang.TranslationUnit.getDiagnosticSet', and then analyze it+-- using the functions in this module.+--+-- This module is intended to be imported qualified.+module Clang.Diagnostic+(+-- * Diagnostic sets+ getElements++-- * Diagnostics+, getChildren+, getSeverity+, FFI.Severity(..)+, getSpelling+, getOptions+, getCategoryName+, getCategoryId+, getRanges+, getFixIts++-- * Rendering diagnostics+, format+, FFI.DisplayOptions(..)++-- * Deserializing diagnostics+, load+, FFI.LoadError(..)+) where++import Control.Monad.IO.Class++import Clang.Internal.BitFlags+import qualified Clang.Internal.FFI as FFI+import Clang.Internal.Monad+++-- | Retrieve the diagnostics contained in the given 'FFI.DiagnosticSet'.+--+-- You can obtain a 'FFI.DiagnosticSet' from a 'FFI.TranslationUnit'+-- using 'Clang.TranslationUnit.getDiagnosticSet', or by deserializing+-- it from a file using 'load'.+getElements :: ClangBase m => FFI.DiagnosticSet s' -> ClangT s m [FFI.Diagnostic s]+getElements ds = do+ numDiags <- liftIO $ FFI.getNumDiagnosticsInSet ds+ mapM (FFI.getDiagnosticInSet ds) [0..(numDiags - 1)]++-- | Get the child diagnostics of the given diagnostic.+getChildren :: ClangBase m => FFI.Diagnostic s' -> ClangT s m (FFI.DiagnosticSet s)+getChildren = FFI.getChildDiagnostics++-- | Determine the severity of the given diagnostic.+getSeverity :: ClangBase m => FFI.Diagnostic s' -> ClangT s m FFI.Severity+getSeverity d = liftIO $ FFI.getDiagnosticSeverity d++-- | Retrieve the text of the given diagnostic.+getSpelling :: ClangBase m => FFI.Diagnostic s' -> ClangT s m (FFI.ClangString s)+getSpelling = FFI.getDiagnosticSpelling++-- | Retrieve the name of the command-line option that enabled this diagnostic.+getOptions :: ClangBase m+ => FFI.Diagnostic s' -- ^ The diagnostic in question.+ -> ClangT s m (FFI.ClangString s, FFI.ClangString s) -- ^ The options controlling+ -- this diagnostic. The+ -- first member of the pair+ -- is the option to enable+ -- this diagnostic. The+ -- second member is the+ -- option to disable it.+getOptions = FFI.getDiagnosticOption++-- | Get the name of the diagnostic category for the given diagnostic.+--+-- Diagnostics are categorized into groups along with other,+-- related diagnostics (e.g., diagnostics under the same warning+-- flag).+getCategoryName :: ClangBase m => FFI.Diagnostic s' -> ClangT s m (FFI.ClangString s)+getCategoryName = FFI.getDiagnosticCategoryText++-- | Retrieve the category id for this diagnostic.+--+-- For display to the user, use 'getCategoryName'.+getCategoryId :: ClangBase m => FFI.Diagnostic s' -> ClangT s m Int+getCategoryId d = liftIO $ FFI.getDiagnosticCategory d++-- | Retrieve the source ranges associated with this diagnostic.+--+-- A diagnostic's source ranges highlight important elements in the+-- source code. On the command line, Clang displays source ranges by+-- underlining them with '~' characters.+getRanges :: ClangBase m => FFI.Diagnostic s' -> ClangT s m [FFI.SourceRange s]+getRanges d = liftIO $ do+ numRanges <- FFI.getDiagnosticNumRanges d+ mapM (FFI.getDiagnosticRange d) [0..(numRanges - 1)]++-- | Retrieve the fix-it hints associated with the given diagnostic.+--+-- Fix-its are described in terms of a source range whose contents+-- should be replaced by a string. This approach generalizes over+-- three kinds of operations: removal of source code (the range covers+-- the code to be removed and the replacement string is empty),+-- replacement of source code (the range covers the code to be+-- replaced and the replacement string provides the new code), and+-- insertion (both the start and end of the range point at the+-- insertion location, and the replacement string provides the text to+-- insert).+getFixIts :: ClangBase m+ => FFI.Diagnostic s' -- ^ The diagnostic in question.+ -> ClangT s m [(FFI.SourceRange s, FFI.ClangString s)] -- ^ A list of replacement+ -- ranges and strings. Note+ -- that source ranges are+ -- half-open ranges '[a, b)'+ -- so the source code should+ -- be replaced from 'a' up+ -- to (but not including)+ -- 'b'.+getFixIts d = do+ numFixes <- liftIO $ FFI.getDiagnosticNumFixIts d+ mapM (FFI.getDiagnosticFixIt d) [0..(numFixes - 1)]++-- | Format the given diagnostic in a manner that is suitable for+-- display.+format :: ClangBase m+ => Maybe [FFI.DisplayOptions] -- ^ An optional list of options+ -- for rendering the diagnostic.+ -- If 'Nothing' is given, default+ -- options are used that mimic the+ -- behavior of the Clang compiler+ -- as closely as possible.+ -> FFI.Diagnostic s' -- ^ The diagnostic to format.+ -> ClangT s m (FFI.ClangString s) -- ^ A formatted rendering of the+ -- given diagnostic.+format Nothing diag = FFI.formatDiagnostic diag =<<+ liftIO FFI.defaultDiagnosticDisplayOptions+format (Just opts) diag = FFI.formatDiagnostic diag (orFlags opts)++-- | Deserialize a set of diagnostics from a Clang diagnostics bitcode file.+--+-- If an error is encountered, a 'FFI.LoadError' and a textual error+-- message suitable for display to the user are returned.+load :: ClangBase m+ => FilePath+ -> ClangT s m (Either (FFI.LoadError, FFI.ClangString s) (FFI.DiagnosticSet s))+load = FFI.loadDiagnostics
+ src/Clang/File.hs view
@@ -0,0 +1,60 @@+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE FlexibleContexts #-}++-- | Functions for manipulating 'FFI.File's, which represent+-- references to files in the libclang AST.+--+-- This module is intended to be imported qualified.+module Clang.File+(+-- * Creating files+ createFromPath++-- * File properties+, getName+, isMultipleIncludeGuarded+, getMTime+, getPosixMTime++-- * Unique IDs+, getUniqueId+, FFI.UniqueId+) where++import Control.Applicative+import Control.Monad.IO.Class+import Data.Time.Clock.POSIX (POSIXTime, posixSecondsToUTCTime)+import Data.Time.Clock (UTCTime)++import qualified Clang.Internal.FFI as FFI+import Clang.Internal.Monad++-- | Create a new 'FFI.File' value from the provided path.+createFromPath :: ClangBase m => FFI.TranslationUnit s' -> FilePath -> ClangT s m (FFI.File s)+createFromPath t f = liftIO $ FFI.getFile mkProxy t f++-- | Retrieve the filename of the given file.+getName :: ClangBase m => FFI.File s' -> ClangT s m (FFI.ClangString s)+getName = FFI.getFileName++-- | Determines whether the given file is guarded against multiple+-- inclusions, either with the conventional '#ifdef' / '#define' / '#endif'+-- macro guards or with '#pragma once'.+isMultipleIncludeGuarded :: ClangBase m => FFI.TranslationUnit s' -> FFI.File s''+ -> ClangT s m Bool+isMultipleIncludeGuarded t f = liftIO $ FFI.isFileMultipleIncludeGuarded t f++-- | Returns the last modification time of the given file, represented+-- as a 'UTCTime'.+getMTime :: ClangBase m => FFI.File s' -> ClangT s m UTCTime+getMTime f = liftIO $ posixSecondsToUTCTime . realToFrac <$> FFI.getFileTime f++-- | Returns the last modification time of the given file, represented+-- as a 'POSIXTime'.+getPosixMTime :: ClangBase m => FFI.File s' -> ClangT s m POSIXTime+getPosixMTime f = liftIO $ realToFrac <$> FFI.getFileTime f++-- | Retrieves a unique ID for the given file. If no unique ID can be+-- generated, returns 'Nothing'.+getUniqueId :: ClangBase m => FFI.File s' -> ClangT s m (Maybe FFI.UniqueId)+getUniqueId f = liftIO $ FFI.getFileUniqueID f
+ src/Clang/Index.hs view
@@ -0,0 +1,45 @@+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE RankNTypes #-}++-- | Functions for manipulating indexes.+--+-- An index is a container that holds a set of translation units. Generally+-- you'll create an index using 'withNew' and then use that index with functions+-- from "Clang.TranslationUnit" to create and work with translation units.+--+-- This module is intended to be imported qualified.+module Clang.Index+(+-- * Creating an index+ withNew++-- * Index options+, getGlobalOptions+, setGlobalOptions+, FFI.GlobalIndexOptions(..)+, FFI.threadBackgroundPriorityForAll+) where++import Control.Applicative+import Control.Monad.IO.Class++import Clang.Internal.BitFlags+import qualified Clang.Internal.FFI as FFI+import Clang.Internal.Monad++-- | Creates an index.+withNew :: ClangBase m+ => Bool -- ^ Whether to exclude declarations coming from pre-compiled headers.+ -> Bool -- ^ Whether to automatically display diagnostic messages.+ -> (forall s. FFI.Index s -> ClangT s m a) -- ^ The function which will use the index.+ -> m a+withNew i1 i2 f = runClangT (FFI.createIndex i1 i2 >>= f)++-- | Retrieves the global options for this index.+getGlobalOptions :: ClangBase m => FFI.Index s' -> ClangT s m [FFI.GlobalIndexOptions]+getGlobalOptions i = unFlags <$> liftIO (FFI.cXIndex_getGlobalOptions i)++-- | Sets the global options for this index.+setGlobalOptions :: ClangBase m => FFI.Index s' -> [FFI.GlobalIndexOptions] -> ClangT s m ()+setGlobalOptions i opts = liftIO $ FFI.cXIndex_setGlobalOptions i (orFlags opts)
+ src/Clang/Internal/BitFlags.hs view
@@ -0,0 +1,33 @@+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeFamilies #-}++module Clang.Internal.BitFlags+( BitFlags (..)+, orFlags+, andFlags+, unFlags+) where++import Data.Bits+import Data.List++class (Bits (FlagInt a), Num (FlagInt a)) => BitFlags a where+ type FlagInt a :: *+ type FlagInt a = Int++ toBit :: a -> FlagInt a++orFlags :: BitFlags a => [a] -> FlagInt a+orFlags [] = 0+orFlags fs = foldl1' (.|.) $ map toBit fs++andFlags :: BitFlags a => [a] -> FlagInt a+andFlags [] = 0+andFlags fs = foldl1' (.&.) $ map toBit fs++unFlags :: forall a. (BitFlags a, Bounded a, Enum a) => FlagInt a -> [a]+unFlags v = filter (checkFlag v) allFlags+ where+ checkFlag i f = (i .&. toBit f) /= 0+ allFlags = enumFrom (minBound :: a)
+ src/Clang/Internal/Comment.hs view
@@ -0,0 +1,189 @@+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE DeriveDataTypeable #-}+{-# LANGUAGE FlexibleContexts #-}++module Clang.Internal.Comment+( ParsedComment(..)+, ParamPassDirection(..)+, parseComment+, getFFIComment+) where++import Control.Applicative+import Control.Monad+import Control.Monad.IO.Class+import Data.Typeable++import qualified Clang.Internal.FFI as FFI+import Clang.Internal.Monad++-- | A node in the comment AST.+--+-- Every constructor contains an opaque 'FFI.Comment' value, which represents the AST node+-- itself. The other fields are the user-visible metadata for that node type.+data ParsedComment s+ -- | Plain text. Inline content.+ = TextComment (FFI.Comment s) (FFI.ClangString s)++ -- | A command with word-like arguments that is considered inline content.+ | InlineCommandComment (FFI.Comment s) (FFI.ClangString s) FFI.InlineCommandRenderStyle [FFI.ClangString s]++ -- | An HTML start tag with attributes (represented as name/value pairs). Considered inline content.+ -- The final argument of the constructor is 'True' if the tag is self-closing.+ | HTMLStartTagComment (FFI.Comment s) (FFI.ClangString s) [(FFI.ClangString s, FFI.ClangString s)] Bool++ -- | An HTML end tag. Considered inline content.+ | HTMLEndTagComment (FFI.Comment s) (FFI.ClangString s)++ -- | A paragraph, which contains inline content. The paragraph itself is block content.+ | ParagraphComment (FFI.Comment s)++ -- | A command which has zero or more word-like arguments and a paragraph argument. Block content.+ -- The paragraph argument (of type 'ParsedComment') is also a child of the 'BlockCommandComment'.+ --+ -- As an example, a \'\\brief\' comment creates a 'BlockCommandComment' AST node with no word-like+ -- arguments and a paragraph argument.+ | BlockCommandComment (FFI.Comment s) (FFI.ClangString s) [FFI.ClangString s] (Maybe (ParsedComment s))++ -- | A \'\\param\' or \'\\arg\' command that describes a function parameter. The parameter name,+ -- index in the parameter list (or 'Nothing' if the index is invalid), and parameter passing+ -- direction are provided as constructor fields. The description is provided as a child node.+ | ParamCommandComment (FFI.Comment s) (FFI.ClangString s) (Maybe Int) ParamPassDirection+++ -- | A \'\\tparam\' command that describes a template parameter. The parameter name and position+ -- are provided as constructor fields, while the description is provided as a child node.+ --+ -- Since template parameters can be nested, the position is a list with a left-to-right position+ -- at each nesting depth. For example, for the following declaration:+ --+ -- > template<typename C, template<typename T> class TT>+ -- > void test(TT<int> aaa);+ --+ -- The resulting position would be [0] for \'C\', [1] for \'TT\', and [1, 0] for \'T\'.+ | TypeParamCommandComment (FFI.Comment s) (FFI.ClangString s) (Maybe [Int])++ -- | A verbatim block command (e.g. preformatted code). A verbatim block has an opening+ -- and a closing command and contains multiple lines of text, represented as+ -- 'VerbatimBlockLineComment' nodes.+ | VerbatimBlockCommandComment (FFI.Comment s) (Maybe (ParsedComment s))++ -- | A line of text that is contained within a 'VerbatimBlockCommandComment' node.+ | VerbatimBlockLineComment (FFI.Comment s) (FFI.ClangString s)++ -- | A verbatim line command. A verbatim line has an opening command, a single line+ -- of text (up to the newline after the opening command), and has no closing command.+ | VerbatimLineComment (FFI.Comment s) (FFI.ClangString s)++ -- | A full comment attached to a declaration. Contains block content.+ | FullComment (FFI.Comment s)+ deriving (Eq, Ord, Typeable)++-- | A parameter passing direction, either explicitly provided in the comment text or+-- inferred.+data ParamPassDirection+ = ExplicitParamPassDirection FFI.ParamPassDirectionKind+ | InferredParamPassDirection FFI.ParamPassDirectionKind+ deriving (Eq, Ord, Read, Show, Typeable)++parseComment :: ClangBase m => FFI.Comment s -> ClangT s m (Maybe (ParsedComment s))+parseComment c = do+ kind <- liftIO $ FFI.comment_getKind c+ case kind of+ FFI.NullComment -> pure Nothing+ FFI.TextComment -> Just . TextComment c <$> FFI.textComment_getText c+ FFI.InlineCommandComment -> do v <- InlineCommandComment c <$> FFI.inlineCommandComment_getCommandName c+ <*> inlineCommandComment_getRenderKind c+ <*> inlineCommandComment_getArgs c+ return $ Just v+ FFI.HTMLStartTagComment -> do v <- HTMLStartTagComment c <$> FFI.hTMLTagComment_getTagName c+ <*> htmlStartTagComment_getAttrs c+ <*> htmlStartTagComment_isSelfClosing c+ return $ Just v+ FFI.HTMLEndTagComment -> Just . HTMLEndTagComment c <$> FFI.hTMLTagComment_getTagName c+ FFI.ParagraphComment -> pure $ Just (ParagraphComment c)+ FFI.BlockCommandComment -> do v <- BlockCommandComment c <$> FFI.blockCommandComment_getCommandName c+ <*> blockCommandComment_getArgs c+ <*> blockCommandComment_getParagraph c+ return $ Just v+ FFI.ParamCommandComment -> do v <- ParamCommandComment c <$> FFI.paramCommandComment_getParamName c+ <*> paramCommandComment_getParamIndex c+ <*> paramCommandComment_getDirection c+ return $ Just v+ FFI.TParamCommandComment -> do v <- TypeParamCommandComment c+ <$> FFI.tParamCommandComment_getParamName c+ <*> tParamCommandComment_getPosition c+ return $ Just v+ FFI.VerbatimBlockCommandComment -> Just . VerbatimBlockCommandComment c <$> blockCommandComment_getParagraph c+ FFI.VerbatimBlockLineComment -> Just . VerbatimBlockLineComment c <$> FFI.verbatimBlockLineComment_getText c+ FFI.VerbatimLineComment -> Just . VerbatimLineComment c <$> FFI.verbatimLineComment_getText c+ FFI.FullComment -> pure $ Just (FullComment c)++getFFIComment :: ParsedComment s -> FFI.Comment s+getFFIComment (TextComment c _) = c+getFFIComment (InlineCommandComment c _ _ _) = c+getFFIComment (HTMLStartTagComment c _ _ _) = c+getFFIComment (HTMLEndTagComment c _) = c+getFFIComment (ParagraphComment c) = c+getFFIComment (BlockCommandComment c _ _ _) = c+getFFIComment (ParamCommandComment c _ _ _) = c+getFFIComment (TypeParamCommandComment c _ _) = c+getFFIComment (VerbatimBlockCommandComment c _) = c+getFFIComment (VerbatimBlockLineComment c _) = c+getFFIComment (VerbatimLineComment c _) = c+getFFIComment (FullComment c) = c++inlineCommandComment_getRenderKind :: ClangBase m => FFI.Comment s'+ -> ClangT s m FFI.InlineCommandRenderStyle+inlineCommandComment_getRenderKind c = liftIO $ FFI.inlineCommandComment_getRenderKind c++inlineCommandComment_getArgs :: ClangBase m => FFI.Comment s' -> ClangT s m [FFI.ClangString s]+inlineCommandComment_getArgs c = do+ numArgs <- liftIO $ FFI.inlineCommandComment_getNumArgs c+ mapM (FFI.inlineCommandComment_getArgText c) [0..(numArgs - 1)]++htmlStartTagComment_getAttrs :: ClangBase m => FFI.Comment s'+ -> ClangT s m [(FFI.ClangString s, FFI.ClangString s)]+htmlStartTagComment_getAttrs c = do+ numAttrs <- liftIO $ FFI.hTMLStartTag_getNumAttrs c+ forM [0..numAttrs] $ \attr -> do+ attrName <- FFI.hTMLStartTag_getAttrName c attr+ attrValue <- FFI.hTMLStartTag_getAttrValue c attr+ return (attrName, attrValue)++htmlStartTagComment_isSelfClosing :: ClangBase m => FFI.Comment s' -> ClangT s m Bool+htmlStartTagComment_isSelfClosing c = liftIO $ FFI.hTMLStartTagComment_isSelfClosing c++blockCommandComment_getArgs :: ClangBase m => FFI.Comment s' -> ClangT s m [FFI.ClangString s]+blockCommandComment_getArgs c = do+ numArgs <- liftIO $ FFI.blockCommandComment_getNumArgs c+ mapM (FFI.blockCommandComment_getArgText c) [0..(numArgs - 1)]++blockCommandComment_getParagraph :: ClangBase m => FFI.Comment s' -> ClangT s m (Maybe (ParsedComment s))+blockCommandComment_getParagraph c =+ parseComment =<< liftIO (FFI.blockCommandComment_getParagraph mkProxy c)++paramCommandComment_getParamIndex :: ClangBase m => FFI.Comment s' -> ClangT s m (Maybe Int)+paramCommandComment_getParamIndex c = do+ valid <- liftIO $ FFI.paramCommandComment_isParamIndexValid c+ if valid+ then Just <$> (liftIO $ FFI.paramCommandComment_getParamIndex c)+ else return Nothing++paramCommandComment_getDirection :: ClangBase m => FFI.Comment s' -> ClangT s m ParamPassDirection+paramCommandComment_getDirection c = do+ dir <- liftIO $ FFI.paramCommandComment_getDirection c+ explicit <- liftIO $ FFI.paramCommandComment_isDirectionExplicit c+ return $ if explicit+ then ExplicitParamPassDirection dir+ else InferredParamPassDirection dir++tParamCommandComment_getPosition :: ClangBase m => FFI.Comment s' -> ClangT s m (Maybe [Int])+tParamCommandComment_getPosition c = do+ valid <- liftIO $ FFI.tParamCommandComment_isParamPositionValid c+ if valid+ then do depth <- liftIO $ FFI.tParamCommandComment_getDepth c+ indices <- forM [0..depth] $ \d ->+ liftIO $ FFI.tParamCommandComment_getIndex c d+ return $ Just indices+ else return Nothing
+ src/Clang/Internal/FFI.chs view
@@ -0,0 +1,5068 @@+{-# OPTIONS_GHC -fno-warn-unused-binds -fno-warn-unused-matches #-}+{-# LANGUAGE BangPatterns #-}+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE DeriveDataTypeable #-}+{-# LANGUAGE EmptyDataDecls #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE ForeignFunctionInterface #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TupleSections #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeSynonymInstances #-}+{-# LANGUAGE CPP #-}++module Clang.Internal.FFI+( versionMajor+, versionMinor+, encodedVersion+, Index+, createIndex+, GlobalIndexOptions(..)+, threadBackgroundPriorityForAll+, cXIndex_setGlobalOptions+, cXIndex_getGlobalOptions+, TranslationUnit+, UnsavedFile+, unsavedFilename+, unsavedContents+, newUnsavedFile+, updateUnsavedContents+, AvailabilityKind(..)+, Version(..)+, ClangString+, getString+, getByteString+, unsafeGetByteString+, File(..)+, getFileName+, getFileTime+, UniqueId(..)+, getFileUniqueID+, isFileMultipleIncludeGuarded+, getFile+, SourceLocation+, getNullLocation+, equalLocations+, getLocation+, getLocationForOffset+, location_isInSystemHeader+, location_isFromMainFile+, SourceRange+, getNullRange+, getRange+, equalRanges+, range_isNull+, getExpansionLocation+, getPresumedLocation+, getSpellingLocation+, getFileLocation+, getRangeStart+, getRangeEnd+, Severity(..)+, Diagnostic+, DiagnosticSet+, getNumDiagnosticsInSet+, getDiagnosticInSet+, LoadError(..)+, loadDiagnostics+, getChildDiagnostics+, getNumDiagnostics+, getDiagnostic+, getDiagnosticSetFromTU+, DisplayOptions(..)+, formatDiagnostic+, defaultDiagnosticDisplayOptions+, getDiagnosticSeverity+, getDiagnosticLocation+, getDiagnosticSpelling+, getDiagnosticOption+, getDiagnosticCategory+, getDiagnosticCategoryText+, getDiagnosticNumRanges+, getDiagnosticRange+, getDiagnosticNumFixIts+, getDiagnosticFixIt+, getTranslationUnitSpelling+, createTranslationUnitFromSourceFile+, createTranslationUnit+, TranslationUnitFlags(..)+, defaultEditingTranslationUnitOptions+, parseTranslationUnit+, SaveTranslationUnitFlags(..)+, defaultSaveOptions+, saveTranslationUnit+, ReparseFlags(..)+, defaultReparseOptions+, reparseTranslationUnit+, CursorKind(..)+, firstDeclCursor+, lastDeclCursor+, firstRefCursor+, lastRefCursor+, firstInvalidCursor+, lastInvalidCursor+, firstExprCursor+, lastExprCursor+, firstStmtCursor+, lastStmtCursor+, firstAttrCursor+, lastAttrCursor+, firstPreprocessingCursor+, lastPreprocessingCursor+, firstExtraDeclCursor+, lastExtraDeclCursor+, gccAsmStmtCursor+, macroInstantiationCursor+, Comment(..)+, Cursor+, getNullCursor+, getTranslationUnitCursor+, cursor_isNull+, hashCursor+, getCursorKind+, isDeclaration+, isReference+, isExpression+, isStatement+, isAttribute+, isInvalid+, isTranslationUnit+, isPreprocessing+, isUnexposed+, LinkageKind(..)+, getCursorLinkage+, getCursorAvailability+, PlatformAvailability(..)+, PlatformAvailabilityInfo(..)+, getCursorPlatformAvailability+, LanguageKind(..)+, getCursorLanguage+, cursor_getTranslationUnit+, CursorSet+, createCXCursorSet+, cXCursorSet_contains+, cXCursorSet_insert+, getCursorSemanticParent+, getCursorLexicalParent+, getOverriddenCursors+, getIncludedFile+, getCursor+, getCursorLocation+, getCursorSpellingLocation+, getCursorExtent+, TypeKind(..)+, type_FirstBuiltin+, type_LastBuiltin+, CallingConv(..)+, Type+, getTypeKind+, getCursorType+, getTypeSpelling+, getTypedefDeclUnderlyingType+, getEnumDeclIntegerType+, getEnumConstantDeclValue+, getEnumConstantDeclUnsignedValue+, getFieldDeclBitWidth+, cursor_getNumArguments+, cursor_getArgument+, equalTypes+, getCanonicalType+, isConstQualifiedType+, isVolatileQualifiedType+, isRestrictQualifiedType+, getPointeeType+, getTypeDeclaration+, getDeclObjCTypeEncoding+, getTypeKindSpelling+, getFunctionTypeCallingConv+, getResultType+, getNumArgTypes+, getArgType+, isFunctionTypeVariadic+, getCursorResultType+, isPODType+, getElementType+, getNumElements+, getArrayElementType+, getArraySize+, TypeLayoutError(..)+, type_getAlignOf+, type_getClassType+, type_getSizeOf+, type_getOffsetOf+, RefQualifierKind(..)+, type_getCXXRefQualifier+, isBitField+, isVirtualBase+, CXXAccessSpecifier(..)+, getCXXAccessSpecifier+, getNumOverloadedDecls+, getOverloadedDecl+, getIBOutletCollectionType+, CursorList+, getChildren+, getDescendants+, getDeclarations+, getReferences+, getDeclarationsAndReferences+, ParentedCursor(..)+, ParentedCursorList+, getParentedDescendants+, getParentedDeclarations+, getParentedReferences+, getParentedDeclarationsAndReferences+, getCursorUSR+, constructUSR_ObjCClass+, constructUSR_ObjCCategory+, constructUSR_ObjCProtocol+, constructUSR_ObjCIvar+, constructUSR_ObjCMethod+, constructUSR_ObjCProperty+, getCursorSpelling+, cursor_getSpellingNameRange+, getCursorDisplayName+, getCursorReferenced+, getCursorDefinition+, isCursorDefinition+, cursor_isDynamicCall+, getCanonicalCursor+, cursor_getObjCSelectorIndex+, cursor_getReceiverType+, ObjCPropertyAttrKind(..)+, cursor_getObjCPropertyAttributes+, ObjCDeclQualifierKind(..)+, cursor_getObjCDeclQualifiers+, cursor_isObjCOptional+, cursor_isVariadic+, cursor_getCommentRange+, cursor_getRawCommentText+, cursor_getBriefCommentText+, cursor_getParsedComment+, Module(..)+, cursor_getModule+, module_getASTFile+, module_getParent+, module_getName+, module_getFullName+, module_getNumTopLevelHeaders+, module_getTopLevelHeader+, cXXMethod_isPureVirtual+, cXXMethod_isStatic+, cXXMethod_isVirtual+, getTemplateCursorKind+, getSpecializedCursorTemplate+, getCursorReferenceNameRange+, NameRefFlags(..)+, CommentKind(..)+, InlineCommandRenderStyle(..)+, ParamPassDirectionKind(..)+, comment_getKind+, comment_getNumChildren+, comment_getChild+, comment_isWhitespace+, inlineContentComment_hasTrailingNewline+, textComment_getText+, inlineCommandComment_getCommandName+, inlineCommandComment_getRenderKind+, inlineCommandComment_getNumArgs+, inlineCommandComment_getArgText+, hTMLTagComment_getTagName+, hTMLStartTagComment_isSelfClosing+, hTMLStartTag_getNumAttrs+, hTMLStartTag_getAttrName+, hTMLStartTag_getAttrValue+, blockCommandComment_getCommandName+, blockCommandComment_getNumArgs+, blockCommandComment_getArgText+, blockCommandComment_getParagraph+, paramCommandComment_getParamName+, paramCommandComment_isParamIndexValid+, paramCommandComment_getParamIndex+, paramCommandComment_isDirectionExplicit+, paramCommandComment_getDirection+, tParamCommandComment_getParamName+, tParamCommandComment_isParamPositionValid+, tParamCommandComment_getDepth+, tParamCommandComment_getIndex+, verbatimBlockLineComment_getText+, verbatimLineComment_getText+, hTMLTagComment_getAsString+, fullComment_getAsHTML+, fullComment_getAsXML+, TokenKind(..)+, Token+, TokenList+, getTokenKind+, getTokenSpelling+, getTokenLocation+, getTokenExtent+, tokenize+, annotateTokens+, getCursorKindSpelling+, enableStackTraces+, CompletionString+, CompletionResult+, ChunkKind(..)+, getCompletionChunkKind+, getCompletionChunkText+, getCompletionChunkCompletionString+, getNumCompletionChunks+, getCompletionPriority+, getCompletionAvailability+, getCompletionNumAnnotations+, getCompletionAnnotation+, getCompletionParent+, getCompletionBriefComment+, getCursorCompletionString+, CodeCompleteFlags(..)+, defaultCodeCompleteOptions+, CodeCompleteResults+, codeCompleteAt+, codeCompleteGetNumResults+, codeCompleteGetResult+, sortCodeCompletionResults+, codeCompleteGetNumDiagnostics+, codeCompleteGetDiagnostic+, CompletionContext(..)+, codeCompleteGetContexts+, codeCompleteGetContainerKind+, codeCompleteGetContainerUSR+, codeCompleteGetObjCSelector+, getClangVersion+, toggleCrashRecovery+, Inclusion(..)+, InclusionList+, getInclusions+, Remapping+, getRemappings+, getRemappingsFromFileList+, remap_getNumFiles+, remap_getFilenames+) where++import Control.Applicative+import Control.Monad (forM_)+import Control.Monad.Trans+import qualified Data.ByteString as B+import qualified Data.ByteString.Unsafe as BU+import Data.Hashable+import Data.Typeable (Typeable)+import qualified Data.Vector as DV+import qualified Data.Vector.Storable as DVS+import qualified Data.Vector.Storable.Mutable as DVSM+import Data.Word+import Foreign.C+import Foreign+import Foreign.ForeignPtr.Unsafe (unsafeForeignPtrToPtr)+import Unsafe.Coerce (unsafeCoerce) -- With GHC 7.8 we can use the safer 'coerce'.+import System.IO.Unsafe(unsafePerformIO)++import Clang.Internal.BitFlags+import Clang.Internal.FFIConstants+import Clang.Internal.Monad++#include <inttypes.h>+#include <stdlib.h>+#include <stddef.h>+#include <clang-c/Index.h>+#include <stdio.h>+#include "utils.h"+#include "visitors.h"+#include "wrappers.h"++{-+LibClang uses two strategies to create safe, deterministic+bindings.++First, all types that either represent resources managed on the C side+(for example, TranslationUnit and ClangString) or contain pointers into+those resources (for example, Cursor) are tagged with an ST-like+universally quantified phantom type parameter. This prevents them from+being used outside of the scope in which they were allocated. This is+particularly important for libclang, which uses an arena allocator to+store much of its data; preventing resources from leaking outside+their proper scope is critical to making this safe.++Second, all operations that allocate a resource that later+needs to be freed are wrapped in a type-specific 'register'+function. An example is registerClangString. This function registers a+cleanup action with the underlying ClangT monad, which is essentially+just ResourceT in disguise. This not only provides safety, but it also+enforces prompt finalization of resources which can significantly+increase performance by keeping the working set of user programs down.++There are a few different patterns for the FFI code, depending on what+kind of value the libclang function we want to wrap returns.++If it returns a pure value (say an Int), then we don't need to do+anything special. The greencard-generated function will have a return+type of IO Int, and the user-facing wrapper function will use liftIO+to call it.++If it returns a value that doesn't represent a newly allocated+resource, but does need the phantom type parameter (because it+contains a pointer into some other resource, generally), then we+generally pass a Proxy value with a type parameter that we'll use to+tag the return type. This has no runtime cost. The user-facing wrapper+function still needs to call liftIO.++For values that DO represent a newly allocated resource, we need to+call the appropriate 'register' function. This function will return a+value in the ClangT monad, so user-facing wrapper functions don't need+to use liftIO or Proxy in this case. It's the convention to use '()' for the+phantom type parameter returned from the greencard-generated function,+and allow the 'register' function to coerce the value to the correct+type. This way we can distinguish values that need to be registered+from other values: if a value's phantom type parameter is '()', it+needs to be registered, and it won't typecheck as the return value of+a user-facing wrapper function.++It's important to keep in mind that it should be legal to use values+from enclosing scopes in an inner scope created by clangScope. In+practice, this means that the phantom type parameters used by each+argument to a function should be distinct, and they should all be+distinct from the phantom type parameter used in the return value.+Of course, this doesn't apply to the Proxy parameter, which must+always have the same phantom type parameter as the return value.+-}++-- Marshalling utility functions.+fromCInt :: Num b => CInt -> b+fromCInt = fromIntegral++toCInt :: Integral a => a -> CInt+toCInt = fromIntegral++-- Version information.+versionMajor :: Int+versionMajor = {# const CINDEX_VERSION_MAJOR #}+versionMinor :: Int+versionMinor = {# const CINDEX_VERSION_MINOR #}+encodedVersion :: Int+encodedVersion = {# const CINDEX_VERSION #}++-- typedef void *CXIndex;+newtype Index s = Index { unIndex :: Ptr () }+ deriving (Eq, Ord, Typeable)++instance ClangValue Index++mkIndex :: Ptr () -> Index ()+mkIndex = Index++-- CXIndex clang_createIndex(int excludeDeclarationsFromPCH, int displayDiagnostics);+{# fun clang_createIndex { `CInt', `CInt' } -> `Ptr ()' #}+unsafe_createIndex :: Bool -> Bool -> IO (Index ())+unsafe_createIndex a b = clang_createIndex (fromBool a) (fromBool b) >>= return . mkIndex++createIndex :: ClangBase m => Bool -> Bool -> ClangT s m (Index s)+createIndex = (registerIndex .) . unsafe_createIndex+++-- void clang_disposeIndex(CXIndex index);+{# fun clang_disposeIndex { `Ptr ()' } -> `()' #}+disposeIndex :: Index s -> IO ()+disposeIndex index = clang_disposeIndex (unIndex index)++registerIndex :: ClangBase m => IO (Index ()) -> ClangT s m (Index s)+registerIndex action = do+ (_, idx) <- clangAllocate (action >>= return . unsafeCoerce)+ (\i -> disposeIndex i)+ return idx+{-# INLINEABLE registerIndex #-}++-- typedef enum {+-- CXGlobalOpt_None = 0x0,+-- CXGlobalOpt_ThreadBackgroundPriorityForIndexing = 0x1,+-- CXGlobalOpt_ThreadBackgroundPriorityForEditing = 0x2,+-- CXGlobalOpt_ThreadBackgroundPriorityForAll =+-- CXGlobalOpt_ThreadBackgroundPriorityForIndexing |+-- CXGlobalOpt_ThreadBackgroundPriorityForEditing+--+-- } CXGlobalOptFlags;++-- | Options that apply globally to every translation unit within an index.+#c+enum GlobalIndexOptions+ { DefaultGlobalIndexOptions = CXGlobalOpt_None+ , ThreadBackgroundPriorityForIndexing = CXGlobalOpt_ThreadBackgroundPriorityForIndexing+ , ThreadBackgroundPriorityForEditing = CXGlobalOpt_ThreadBackgroundPriorityForEditing+ };+#endc+{# enum GlobalIndexOptions{} deriving (Bounded, Eq, Ord, Read, Show, Typeable) #}++instance BitFlags GlobalIndexOptions where+ toBit DefaultGlobalIndexOptions = 0x0+ toBit ThreadBackgroundPriorityForIndexing = 0x1+ toBit ThreadBackgroundPriorityForEditing = 0x2++-- | A set of global index options that requests background priority for all threads.+threadBackgroundPriorityForAll :: [GlobalIndexOptions]+threadBackgroundPriorityForAll = [ThreadBackgroundPriorityForEditing,+ ThreadBackgroundPriorityForIndexing]++-- void clang_CXIndex_setGlobalOptions(CXIndex, unsigned options);+{# fun clang_CXIndex_setGlobalOptions { `Ptr ()', `Int' } -> `()' #}+cXIndex_setGlobalOptions :: Index s -> Int -> IO ()+cXIndex_setGlobalOptions index options = clang_CXIndex_setGlobalOptions (unIndex index) options++-- unsigned clang_CXIndex_getGlobalOptions(CXIndex);+{# fun clang_CXIndex_getGlobalOptions { `Ptr ()' } -> `Int' #}+cXIndex_getGlobalOptions :: Index s -> IO Int+cXIndex_getGlobalOptions index = clang_CXIndex_getGlobalOptions (unIndex index)++-- typedef struct CXTranslationUnitImpl *CXTranslationUnit;+newtype TranslationUnit s = TranslationUnit { unTranslationUnit :: (Ptr ()) }+ deriving (Eq, Ord, Typeable)++instance ClangValue TranslationUnit++mkTranslationUnit :: Ptr () -> TranslationUnit ()+mkTranslationUnit = TranslationUnit++-- void clang_disposeTranslationUnit(CXTranslationUnit);+{# fun clang_disposeTranslationUnit { `Ptr ()' } -> `()' #}+disposeTranslationUnit :: TranslationUnit s -> IO ()+disposeTranslationUnit t = clang_disposeTranslationUnit (unTranslationUnit t)++registerTranslationUnit :: ClangBase m => IO (TranslationUnit ())+ -> ClangT s m (TranslationUnit s)+registerTranslationUnit action = do+ (_, tu) <- clangAllocate (action >>= return . unsafeCoerce)+ (\t -> disposeTranslationUnit t)+ return tu+{-# INLINEABLE registerTranslationUnit #-}++-- struct CXUnsavedFile {+-- const char* Filename;+-- const char* Contents;+-- unsigned long Length;+-- };++-- | A representation of an unsaved file and its contents.+data UnsavedFile = UnsavedFile+ { _unsavedFilename :: !B.ByteString+ , _unsavedContents :: !B.ByteString+ } deriving (Eq, Show, Typeable)++-- We maintain the invariant that _unsavedFilename is always+-- null-terminated. That's why we don't directly expose the record fields.+unsavedFilename :: UnsavedFile -> B.ByteString+unsavedFilename = _unsavedFilename++unsavedContents :: UnsavedFile -> B.ByteString+unsavedContents = _unsavedContents++newUnsavedFile :: B.ByteString -> B.ByteString -> UnsavedFile+newUnsavedFile f c = UnsavedFile (nullTerminate f) c++updateUnsavedContents :: UnsavedFile -> B.ByteString -> UnsavedFile+updateUnsavedContents uf c = UnsavedFile (unsavedFilename uf) c++-- TODO: Use BU.unsafeLast when we can use newer B.ByteString.+nullTerminate :: B.ByteString -> B.ByteString+nullTerminate bs+ | B.null bs = B.singleton 0+ | B.last bs == 0 = bs+ | otherwise = B.snoc bs 0++-- Functions which take a Vector UnsavedFile argument are implemented+-- internally in terms of this function, which temporarily allocates a+-- Vector CUnsavedFile holding the same data. (But does not copy the+-- string data itself.)+withUnsavedFiles :: DV.Vector UnsavedFile -> (Ptr CUnsavedFile -> Int -> IO a) -> IO a+withUnsavedFiles ufs f =+ withCUnsavedFiles ufs $ \cufs ->+ DVS.unsafeWith cufs $ \ptr ->+ f ptr (DVS.length cufs)++data CUnsavedFile = CUnsavedFile+ { cUnsavedFilename :: CString+ , cUnsavedContents :: CString+ , cUnsavedContentsLen :: CULong+ }++instance Storable CUnsavedFile where+ sizeOf _ = sizeOfCXUnsavedFile+ {-# INLINE sizeOf #-}++ alignment _ = alignOfCXUnsavedFile+ {-# INLINE alignment #-}++ peek p = do+ filename <- peekByteOff p offsetCXUnsavedFileFilename+ contents <- peekByteOff p offsetCXUnsavedFileContents+ contentsLen <- peekByteOff p offsetCXUnsavedFileContentsLen+ return $! CUnsavedFile filename contents contentsLen+ {-# INLINE peek #-}++ poke p (CUnsavedFile filename contents contentsLen) = do+ pokeByteOff p offsetCXUnsavedFileFilename filename+ pokeByteOff p offsetCXUnsavedFileContents contents+ pokeByteOff p offsetCXUnsavedFileContentsLen contentsLen+ {-# INLINE poke #-}+++withCUnsavedFiles :: DV.Vector UnsavedFile -> (DVS.Vector CUnsavedFile -> IO a) -> IO a+withCUnsavedFiles ufs f = do+ let len = DV.length ufs+ v <- DVSM.new len+ go v 0 len+ where+ go v i len+ | i == len = f =<< DVS.unsafeFreeze v+ | otherwise = do let uf = DV.unsafeIndex ufs i+ ufFilename = unsavedFilename uf+ ufContents = unsavedContents uf+ BU.unsafeUseAsCString ufFilename $ \cufFilename ->+ BU.unsafeUseAsCString ufContents $ \cufContents -> do+ let contentsLen = fromIntegral $ B.length ufContents+ cuf = CUnsavedFile cufFilename cufContents contentsLen+ DVSM.write v i cuf+ go v (i + 1) len++#c+enum AvailabilityKind {+ Availability_Available = CXAvailability_Available,+ Availability_Deprecated = CXAvailability_Deprecated,+ Availability_NotAvailable = CXAvailability_NotAvailable,+ Availability_NotAccessible = CXAvailability_NotAccessible+};+#endc+{# enum AvailabilityKind{} deriving (Bounded, Eq, Ord, Read, Show, Typeable) #}++data Version = Version+ { majorVersion :: !Int+ , minorVersion :: !Int+ , subminorVersion :: !Int+ } deriving (Eq, Ord, Show, Typeable)++instance Storable Version where+ sizeOf _ = sizeOfCXVersion+ {-# INLINE sizeOf #-}++ alignment _ = alignOfCXVersion+ {-# INLINE alignment #-}++ peek p = do+ major <- fromCInt <$> peekByteOff p offsetCXVersionMajor+ minor <- fromCInt <$> peekByteOff p offsetCXVersionMinor+ subminor <- fromCInt <$> peekByteOff p offsetCXVersionSubminor+ return $! Version major minor subminor+ {-# INLINE peek #-}++ poke p (Version major minor subminor) = do+ pokeByteOff p offsetCXVersionMajor major+ pokeByteOff p offsetCXVersionMinor minor+ pokeByteOff p offsetCXVersionSubminor subminor+ {-# INLINE poke #-}++-- typedef struct {+-- const void *data;+-- unsigned private_flags;+-- } CXString;+data ClangString s = ClangString !(Ptr ()) !Word32+ deriving (Eq, Ord, Typeable)++instance ClangValue ClangString++instance Storable (ClangString s) where+ sizeOf _ = {# sizeof CXString #} -- sizeOfCXString+ {-# INLINE sizeOf #-}++ alignment _ = {# alignof CXString #} -- alignOfCXString+ {-# INLINE alignment #-}++ peek p = do+ strData <- {#get CXString->data #} p+ strFlags <- {#get CXString->private_flags #} p+ return $! ClangString strData (fromIntegral strFlags)+ {-# INLINE peek #-}++ poke p (ClangString d f) = do+ {#set CXString->data #} p d+ {#set CXString->private_flags #} p (fromIntegral f)+ {-# INLINE poke #-}++instance Hashable (ClangString s) where+ hashWithSalt salt (ClangString p f) = (`hashWithSalt` f)+ . (`hashWithSalt` pInt)+ $ salt+ where+ pInt = (fromIntegral $ ptrToWordPtr p) :: Int++registerClangString :: ClangBase m => IO (ClangString ()) -> ClangT s m (ClangString s)+registerClangString action = do+ (_, str) <- clangAllocate (action >>= return . unsafeCoerce)+ (\(ClangString d f) -> freeClangString d f)+ return str+{-# INLINEABLE registerClangString #-}++{#fun freeClangString { id `Ptr ()', `Word32' } -> `()' #}++unmarshall_clangString :: Ptr () -> Word32 -> IO (ClangString ())+unmarshall_clangString d f = return $ ClangString d f++getString :: ClangBase m => ClangString s' -> ClangT s m String+getString (ClangString d f) = liftIO $ getCStringPtr d f >>= peekCString++getByteString :: ClangBase m => ClangString s' -> ClangT s m B.ByteString+getByteString (ClangString d f) = liftIO $ getCStringPtr d f >>= B.packCString++unsafeGetByteString :: ClangBase m => ClangString s' -> ClangT s m B.ByteString+unsafeGetByteString (ClangString d f) = liftIO $ getCStringPtr d f >>= BU.unsafePackCString++-- const char *clang_getCString(ClangString string);+{# fun clang_getCString {withVoided* %`ClangString a' } -> `CString' id #}+getCStringPtr :: Ptr () -> Word32 -> IO CString+getCStringPtr d f = clang_getCString (ClangString d f)++-- typedef void *CXFile;+newtype File s = File { unFile :: Ptr () }+ deriving (Eq, Ord, Typeable)++instance ClangValue File++instance Hashable (File s) where+ hashWithSalt salt (File p) = let !pInt = (fromIntegral $ ptrToWordPtr p) :: Int+ in hashWithSalt salt pInt++maybeFile :: File s' -> Maybe (File s)+maybeFile (File p) | p == nullPtr = Nothing+maybeFile f = Just (unsafeCoerce f)++unMaybeFile :: Maybe (File s') -> File s+unMaybeFile (Just f) = unsafeCoerce f+unMaybeFile Nothing = File nullPtr+++-- CXString clang_getFileName(CXFile SFile);+{# fun wrapped_clang_getFileName as clang_getFileName { `Ptr ()' } -> `Ptr (ClangString ())' castPtr #}+unsafe_getFileName :: File s -> IO (ClangString ())+unsafe_getFileName x = clang_getFileName (unFile x) >>= peek++getFileName :: ClangBase m => File s' -> ClangT s m (ClangString s)+getFileName = registerClangString . unsafe_getFileName++-- time_t clang_getFileTime(CXFile SFile);+foreign import ccall unsafe "clang-c/Index.h clang_getFileTime" clang_getFileTime :: Ptr () -> IO CTime++getFileTime :: File s -> IO CTime+getFileTime (File ptr) = clang_getFileTime ptr++-- | A unique identifier that can be used to distinguish 'File's.+data UniqueId = UniqueId !Word64 !Word64 !Word64+ deriving (Eq, Ord, Show, Typeable)++instance Hashable UniqueId where+ hashWithSalt salt (UniqueId a b c) = (`hashWithSalt` a)+ . (`hashWithSalt` b)+ . (`hashWithSalt` c)+ $ salt+ {-# INLINE hashWithSalt #-}++maybeFileUniqueID :: (Int, Word64, Word64, Word64) -> Maybe UniqueId+maybeFileUniqueID (v, d1, d2, d3) | v /= 0 = Nothing+ | otherwise = Just $ UniqueId d1 d2 d3++-- int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID);+{# fun clang_getFileUniqueID { `Ptr ()', `Ptr ()' } -> `CInt' id #}+getFileUniqueID :: File s -> IO (Maybe UniqueId)+getFileUniqueID f =+ allocaArray 3 (ptrToFileUniqueId f)+ where+ ptrToFileUniqueId :: File s -> Ptr Word64 -> IO (Maybe UniqueId)+ ptrToFileUniqueId f' ptr = do+ res' <- clang_getFileUniqueID (unFile f') (castPtr ptr)+ ds' <- peekArray 3 ptr+ return (maybeFileUniqueID (fromIntegral res', ds' !! 0, ds' !! 1, ds' !! 2))++-- -- unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit tu, CXFile file);+{# fun clang_isFileMultipleIncludeGuarded { `Ptr ()', `Ptr ()' } -> `CInt' #}+isFileMultipleIncludeGuarded :: TranslationUnit s -> File s' -> IO Bool+isFileMultipleIncludeGuarded t f = clang_isFileMultipleIncludeGuarded (unTranslationUnit t) (unFile f) >>= return . (toBool :: Int -> Bool) . fromIntegral++-- CXFile clang_getFile(CXTranslationUnit tu, const char *file_name);+{# fun clang_getFile { `Ptr ()', `CString' } -> `Ptr ()' #}+getFile:: Proxy s -> TranslationUnit s' -> String -> IO (File s)+getFile _ t s = withCString s (\cs -> clang_getFile (unTranslationUnit t) cs >>= return . File)++-- typedef struct {+-- void *ptr_data[2];+-- unsigned int_data;+-- } CXSourceLocation;++data SourceLocation s = SourceLocation !(Ptr ()) !(Ptr ()) !Int+ deriving (Ord, Typeable)++instance ClangValue SourceLocation++instance Eq (SourceLocation s) where+ a == b = unsafePerformIO $ equalLocations a b++instance Storable (SourceLocation s) where+ sizeOf _ = sizeOfCXSourceLocation+ {-# INLINE sizeOf #-}++ alignment _ = alignOfCXSourceLocation+ {-# INLINE alignment #-}++ peek p = do+ ptrArray <- {#get CXSourceLocation->ptr_data #} p >>= peekArray 2+ intData <- {#get CXSourceLocation->int_data #} p+ return $! SourceLocation (ptrArray !! 0) (ptrArray !! 1) (fromIntegral intData)+ {-# INLINE peek #-}++ poke p (SourceLocation p0 p1 i )= do+ ptrsArray <- mallocArray 2+ pokeArray ptrsArray [p0,p1]+ {#set CXSourceLocation->ptr_data #} p (castPtr ptrsArray)+ {#set CXSourceLocation->int_data #} p (fromIntegral i)+ {-# INLINE poke #-}++-- typedef struct {+-- void *ptr_data[2];+-- unsigned begin_int_data;+-- unsigned end_int_data;+-- } CXSourceRange;+data SourceRange s = SourceRange !(Ptr ()) !(Ptr ()) !Int !Int+ deriving (Ord, Typeable)++instance ClangValue SourceRange++instance Eq (SourceRange s) where+ a == b = unsafePerformIO $ equalRanges a b++instance Storable (SourceRange s) where+ sizeOf _ = sizeOfCXSourceRange+ {-# INLINE sizeOf #-}++ alignment _ = alignOfCXSourceRange+ {-# INLINE alignment #-}++ peek p = do+ ptrArray <- {#get CXSourceRange->ptr_data #} p >>= peekArray 2+ beginIntData <- {#get CXSourceRange->begin_int_data #} p+ endIntData <- {#get CXSourceRange->end_int_data #} p+ return $! SourceRange (ptrArray !! 0) (ptrArray !! 1) (fromIntegral beginIntData) (fromIntegral endIntData)+ {-# INLINE peek #-}++ poke p (SourceRange p0 p1 begin end)= do+ ptrsArray <- mallocArray 2+ pokeArray ptrsArray [p0,p1]+ {#set CXSourceRange->ptr_data #} p (castPtr ptrsArray)+ {#set CXSourceRange->begin_int_data #} p (fromIntegral begin)+ {#set CXSourceRange->end_int_data #} p (fromIntegral end)+ {-# INLINE poke #-}++-- CXSourceLocation wrapped_clang_getNullLocation();+{# fun wrapped_clang_getNullLocation as clang_getNullLocation { } -> `Ptr (SourceLocation s)' castPtr #}+getNullLocation :: Proxy s -> IO (SourceLocation s)+getNullLocation _ = clang_getNullLocation >>= peek++withVoided :: Storable a => a -> (Ptr () -> IO c) -> IO c+withVoided a f= with a (\aPtr -> f (castPtr aPtr))++-- unsigned clang_equalLocations(CXSourceLocation loc1, CXSourceLocation loc2);+{# fun clang_equalLocations {withVoided* %`SourceLocation a' , withVoided* %`SourceLocation b' } -> `Bool' toBool #}+equalLocations :: SourceLocation s -> SourceLocation s' -> IO Bool+equalLocations s1 s2 = clang_equalLocations s1 s2++-- CXSourceLocation clang_getLocation(CXTranslationUnit tu,+-- CXFile file,+-- unsigned line,+-- unsigned column);+{# fun wrapped_clang_getLocation as clang_getLocation { `Ptr ()' , `Ptr ()', `Int', `Int' } -> `Ptr (SourceLocation s)' castPtr #}+getLocation :: Proxy s -> TranslationUnit s' -> File s'' -> Int -> Int -> IO (SourceLocation s)+getLocation _ t f i j = clang_getLocation (unTranslationUnit t) (unFile f) i j >>= peek++-- CXSourceLocation clang_getLocationForOffset(CXTranslationUnit tu,+-- CXFile file,+-- unsigned offset);+{# fun wrapped_clang_getLocationForOffset as clang_getLocationForOffset { `Ptr ()', `Ptr ()', `Int' } -> `Ptr (SourceLocation s)' castPtr #}+getLocationForOffset :: Proxy s -> TranslationUnit s' -> File s'' -> Int -> IO (SourceLocation s)+getLocationForOffset _ t f i = clang_getLocationForOffset (unTranslationUnit t) (unFile f) i >>= peek++-- int clang_Location_isInSystemHeader(CXSourceLocation location);+{# fun clang_Location_isInSystemHeader { withVoided* %`SourceLocation a' } -> `Bool' toBool #}+location_isInSystemHeader :: SourceLocation s -> IO Bool+location_isInSystemHeader s = clang_Location_isInSystemHeader s++-- int clang_Location_isFromMainFile(CXSourceLocation location);+{# fun clang_Location_isFromMainFile { withVoided* %`SourceLocation a' } -> `Bool' toBool #}+location_isFromMainFile :: SourceLocation s -> IO Bool+location_isFromMainFile s = clang_Location_isFromMainFile s++-- CXSourceRange clang_getNullRange();+{# fun wrapped_clang_getNullRange as clang_getNullRange { } -> `Ptr (SourceRange s)' castPtr #}+getNullRange :: Proxy s -> IO (SourceRange s)+getNullRange _ = clang_getNullRange >>= peek++-- CXSourceRange clang_getRange(CXSourceLocation begin, CXSourceLocation end);+{# fun wrapped_clang_getRange as clang_getRange { withVoided* %`SourceLocation a', withVoided* %`SourceLocation b' } -> `Ptr (SourceRange s)' castPtr #}+getRange :: Proxy s -> SourceLocation s' -> SourceLocation s'' -> IO (SourceRange s)+getRange _ sl1 sl2 = clang_getRange sl1 sl2 >>= peek++-- unsigned clang_equalRanges(CXSourceRange range1, CXSourceRange range2);+{# fun clang_equalRanges {withVoided* %`SourceRange a', withVoided* %`SourceRange b' } -> `Bool' toBool #}+equalRanges :: SourceRange s' -> SourceRange s'' -> IO Bool+equalRanges sr1 sr2 = clang_equalRanges sr1 sr2++-- int clang_Range_isNull(CXSourceRange range);+{# fun clang_Range_isNull {withVoided* %`SourceRange a ' } -> `Bool' toBool #}+range_isNull :: SourceRange s -> IO Bool+range_isNull s = clang_Range_isNull s++#c+typedef CXFile** PtrPtrCXFile;+#endc++-- void clang_getExpansionLocation(CXSourceLocation location,+-- CXFile *file,+-- unsigned *line,+-- unsigned *column,+-- unsigned *offset);+{# fun clang_getExpansionLocation { withVoided* %`SourceLocation a', id `Ptr (Ptr ())', id `Ptr CUInt', id `Ptr CUInt', id `Ptr CUInt' } -> `()' #}+getExpansionLocation :: Proxy s -> SourceLocation s' -> IO (Maybe (File s), Int, Int, Int)+getExpansionLocation _ s =+ allocaBytes {#sizeof PtrPtrCXFile #} (\ptrToFilePtr ->+ alloca (\(linePtr :: (Ptr CUInt)) ->+ alloca (\(columnPtr :: (Ptr CUInt)) ->+ alloca (\(offsetPtr :: (Ptr CUInt)) -> do+ clang_getExpansionLocation s (castPtr ptrToFilePtr) (castPtr linePtr) (castPtr columnPtr) (castPtr offsetPtr)+ filePtr <- {#get *CXFile #} ptrToFilePtr+ let _maybeFile = maybeFile (File filePtr)+ line <- peek linePtr+ column <- peek columnPtr+ offset <- peek offsetPtr+ return (_maybeFile, fromIntegral line, fromIntegral column, fromIntegral offset)))))++-- void clang_getPresumedLocation(CXSourceLocation location,+-- CXString *filename,+-- unsigned *line,+-- unsigned *column);++{# fun clang_getPresumedLocation { withVoided* %`SourceLocation a', id `Ptr ()', alloca- `CUInt' peek*, alloca- `CUInt' peek* } -> `()' #}+unsafe_getPresumedLocation :: SourceLocation s' -> IO (ClangString (), Int, Int)+unsafe_getPresumedLocation s =+ alloca (\(stringPtr :: (Ptr (ClangString ()))) -> do+ (line, column) <- clang_getPresumedLocation s (castPtr stringPtr)+ clangString <- peek stringPtr+ return (clangString, fromIntegral line, fromIntegral column))++getPresumedLocation :: ClangBase m => SourceLocation s' -> ClangT s m (ClangString s, Int, Int)+getPresumedLocation l = do+ (f, ln, c) <- liftIO $ unsafe_getPresumedLocation l+ (,,) <$> registerClangString (return f) <*> return ln <*> return c++-- void clang_getSpellingLocation(CXSourceLocation location,+-- CXFile *file,+-- unsigned *line,+-- unsigned *column,+-- unsigned *offset);+{# fun clang_getSpellingLocation { withVoided* %`SourceLocation a', id `Ptr (Ptr ())', id `Ptr CUInt', id `Ptr CUInt', id `Ptr CUInt' } -> `()' #}+getSpellingLocation :: Proxy s -> SourceLocation s' -> IO (Maybe (File s), Int, Int, Int)+getSpellingLocation _ s =+ allocaBytes {# sizeof PtrPtrCXFile #} (\ptrToFilePtr ->+ alloca (\(linePtr :: (Ptr CUInt)) ->+ alloca (\(columnPtr :: (Ptr CUInt)) ->+ alloca (\(offsetPtr :: (Ptr CUInt)) -> do+ clang_getSpellingLocation s (castPtr ptrToFilePtr) linePtr columnPtr offsetPtr+ filePtr <- {#get *CXFile #} ptrToFilePtr+ let _maybeFile = maybeFile (File filePtr)+ line <- peek linePtr+ column <- peek columnPtr+ offset <- peek offsetPtr+ return (_maybeFile, fromIntegral line, fromIntegral column, fromIntegral offset)))))++-- void clang_getFileLocation(CXSourceLocation location,+-- CXFile *file,+-- unsigned *line,+-- unsigned *column,+-- unsigned *offset);+{# fun clang_getFileLocation { withVoided* %`SourceLocation a', id `Ptr (Ptr ())', id `Ptr CUInt', id `Ptr CUInt', id `Ptr CUInt' } -> `()' #}+getFileLocation :: Proxy s -> SourceLocation s' -> IO (Maybe (File s), Int, Int, Int)+getFileLocation _ s =+ allocaBytes {#sizeof PtrPtrCXFile #} (\ptrToFilePtr ->+ alloca (\(linePtr :: (Ptr CUInt)) ->+ alloca (\(columnPtr :: (Ptr CUInt)) ->+ alloca (\(offsetPtr :: (Ptr CUInt)) -> do+ clang_getFileLocation s ptrToFilePtr (castPtr linePtr) (castPtr columnPtr) (castPtr offsetPtr)+ filePtr <- {#get *CXFile #} ptrToFilePtr+ let _maybeFile = maybeFile (File filePtr)+ line <- peek linePtr+ column <- peek columnPtr+ offset <- peek offsetPtr+ return (_maybeFile, fromIntegral line, fromIntegral column, fromIntegral offset)))))++-- CXSourceLocation clang_getRangeStart(CXSourceRange range);+{# fun wrapped_clang_getRangeStart as clang_getRangeStart {withVoided* %`SourceRange a' } -> `Ptr (SourceLocation s)' castPtr #}+getRangeStart :: Proxy s -> SourceRange s' -> IO (SourceLocation s)+getRangeStart _ sr = clang_getRangeStart sr >>= peek++-- CXSourceLocation clang_getRangeEnd(CXSourceRange range);+{# fun wrapped_clang_getRangeEnd as clang_getRangeEnd {withVoided* %`SourceRange a' } -> `Ptr (SourceLocation s)' castPtr #}+getRangeEnd :: Proxy s -> SourceRange s' -> IO (SourceLocation s)+getRangeEnd _ sr = clang_getRangeEnd sr >>= peek++-- enum CXDiagnosticSeverity {+-- CXDiagnostic_Ignored = 0,+-- CXDiagnostic_Note = 1,+-- CXDiagnostic_Warning = 2,+-- CXDiagnostic_Error = 3,+-- CXDiagnostic_Fatal = 4+-- };++-- | The severity of a diagnostic.+#c+enum Severity+ { SeverityIgnored = CXDiagnostic_Ignored+ , SeverityNote = CXDiagnostic_Note+ , SeverityWarning = CXDiagnostic_Warning+ , SeverityError = CXDiagnostic_Error+ , SeverityFatal = CXDiagnostic_Fatal+ };+#endc+{# enum Severity {} deriving (Bounded, Eq, Ord, Read, Show, Typeable) #}++-- typedef void* CXDiagnostic;+newtype Diagnostic s = Diagnostic { unDiagnostic :: Ptr () }+ deriving (Eq, Ord, Typeable)++instance ClangValue Diagnostic++mkDiagnostic :: Ptr () -> Diagnostic ()+mkDiagnostic = Diagnostic++-- void clang_disposeDiagnostic(CXDiagnostic);+{# fun clang_disposeDiagnostic { id `Ptr ()' } -> `()' #}+disposeDiagnostic:: Diagnostic s -> IO ()+disposeDiagnostic d = clang_disposeDiagnostic (unDiagnostic d)++registerDiagnostic :: ClangBase m => IO (Diagnostic ()) -> ClangT s m (Diagnostic s)+registerDiagnostic action = do+ (_, idx) <- clangAllocate (action >>= return . unsafeCoerce)+ (\i -> disposeDiagnostic i)+ return idx+{-# INLINEABLE registerDiagnostic #-}++-- typedef void* CXDiagnosticSet;+newtype DiagnosticSet s = DiagnosticSet { unDiagnosticSet :: Ptr () }+ deriving (Eq, Ord, Typeable)++instance ClangValue DiagnosticSet++mkDiagnosticSet :: Ptr () -> DiagnosticSet ()+mkDiagnosticSet = DiagnosticSet++-- void clang_disposeDiagnosticSet(CXDiagnosticSet);+{# fun clang_disposeDiagnosticSet { id `Ptr ()' } -> `()' #}+disposeDiagnosticSet :: DiagnosticSet s -> IO ()+disposeDiagnosticSet s = clang_disposeDiagnosticSet (unDiagnosticSet s)++registerDiagnosticSet :: ClangBase m => IO (DiagnosticSet ()) -> ClangT s m (DiagnosticSet s)+registerDiagnosticSet action = do+ (_, idx) <- clangAllocate (action >>= return . unsafeCoerce)+ (\i -> disposeDiagnosticSet i)+ return idx+{-# INLINEABLE registerDiagnosticSet #-}++-- unsigned clang_getNumDiagnosticsInSet(CXDiagnosticSet Diags);+{# fun clang_getNumDiagnosticsInSet { id `Ptr ()' } -> `Int' #}+getNumDiagnosticsInSet :: DiagnosticSet s -> IO Int+getNumDiagnosticsInSet s = clang_getNumDiagnosticsInSet (unDiagnosticSet s)++-- CXDiagnostic clang_getDiagnosticInSet(CXDiagnosticSet Diags, unsigned Index);+{# fun clang_getDiagnosticInSet { id `Ptr ()', `Int' } -> `Ptr ()' id #}+unsafe_getDiagnosticInSet :: DiagnosticSet s -> Int -> IO (Diagnostic ())+unsafe_getDiagnosticInSet s i = clang_getDiagnosticInSet (unDiagnosticSet s) i >>= return . mkDiagnostic++getDiagnosticInSet :: ClangBase m => DiagnosticSet s' -> Int -> ClangT s m (Diagnostic s)+getDiagnosticInSet = (registerDiagnostic .) . unsafe_getDiagnosticInSet++-- enum CXLoadDiag_Error {+-- CXLoadDiag_None = 0,+-- CXLoadDiag_Unknown = 1,+-- CXLoadDiag_CannotLoad = 2,+-- CXLoadDiag_InvalidFile = 3+-- };++-- | An error encountered while loading a serialized diagnostics bitcode file.+#c+enum LoadError+ { LoadSuccessful = CXLoadDiag_None+ , LoadUnknownError = CXLoadDiag_Unknown+ , LoadCannotOpen = CXLoadDiag_CannotLoad+ , LoadInvalidFile = CXLoadDiag_InvalidFile+ };+#endc+{# enum LoadError {} deriving (Bounded, Eq, Ord, Read, Show, Typeable) #}++data LoadDiagsResult =+ LoadDiagsResult LoadError (ClangString ()) (DiagnosticSet ())++-- CXDiagnosticSet clang_loadDiagnostics(const char *file,+-- enum CXLoadDiag_Error *error,+-- CXString *errorString);+{# fun clang_loadDiagnostics {`CString', alloca- `CInt' peek*, `Ptr ()' } -> `Ptr ()' id #}+unsafe_loadDiagnostics :: FilePath -> IO LoadDiagsResult+unsafe_loadDiagnostics file = withCString file (\cString -> alloca (go cString))+ where+ go :: CString -> Ptr (ClangString ()) -> IO LoadDiagsResult+ go str ptr = do+ (diagnosticSetPtr, err) <- clang_loadDiagnostics str (castPtr ptr)+ errString <- peek (castPtr ptr)+ return (LoadDiagsResult (toEnum (fromIntegral err)) errString (DiagnosticSet diagnosticSetPtr))++loadDiagnostics :: ClangBase m => FilePath+ -> ClangT s m (Either (LoadError, ClangString s) (DiagnosticSet s))+loadDiagnostics path = do+ result <- liftIO $ unsafe_loadDiagnostics path+ case result of+ (LoadDiagsResult err errStr ds@(DiagnosticSet p))+ | p == nullPtr -> Left . (err,) <$> registerClangString (return errStr)+ | otherwise -> Right <$> registerDiagnosticSet (return ds)++-- CXDiagnosticSet clang_getChildDiagnostics(CXDiagnostic D);+{# fun clang_getChildDiagnostics { `Ptr ()' } -> `Ptr ()' id #}+unsafe_getChildDiagnostics :: Diagnostic s' -> IO (DiagnosticSet ())+unsafe_getChildDiagnostics d = clang_getChildDiagnostics (unDiagnostic d) >>= return . mkDiagnosticSet++-- Note that as a special case, the DiagnosticSet returned by this+-- function does not need to be freed, so we intentionally don't+-- register it.+getChildDiagnostics :: ClangBase m => Diagnostic s' -> ClangT s m (DiagnosticSet s)+getChildDiagnostics = unsafeCoerce <$> unsafe_getChildDiagnostics++-- unsigned clang_getNumDiagnostics(CXTranslationUnit Unit);+{# fun clang_getNumDiagnostics { `Ptr ()' } -> `CUInt' id#}+getNumDiagnostics :: TranslationUnit s -> IO Int+getNumDiagnostics t = clang_getNumDiagnostics (unTranslationUnit t) >>= return . fromIntegral++-- CXDiagnostic clang_getDiagnostic(CXTranslationUnit Unit, unsigned Index);+{# fun clang_getDiagnostic { `Ptr ()', `CUInt' } -> `Ptr ()' id #}+unsafe_getDiagnostic :: TranslationUnit s -> Int -> IO (Diagnostic ())+unsafe_getDiagnostic t i = clang_getDiagnostic (unTranslationUnit t) (fromIntegral i) >>= return . mkDiagnostic++getDiagnostic :: ClangBase m => TranslationUnit s' -> Int -> ClangT s m (Diagnostic s)+getDiagnostic = (registerDiagnostic .) . unsafe_getDiagnostic++-- CXDiagnosticSet clang_getDiagnosticSetFromTU(CXTranslationUnit Unit);+{# fun clang_getDiagnosticSetFromTU { `Ptr ()' } -> `Ptr ()' id #}+unsafe_getDiagnosticSetFromTU :: TranslationUnit s -> IO (DiagnosticSet ())+unsafe_getDiagnosticSetFromTU t = do+ set <- clang_getDiagnosticSetFromTU (unTranslationUnit t)+ return (mkDiagnosticSet set)++getDiagnosticSetFromTU :: ClangBase m => TranslationUnit s' -> ClangT s m (DiagnosticSet s)+getDiagnosticSetFromTU = registerDiagnosticSet . unsafe_getDiagnosticSetFromTU++-- enum CXDiagnosticDisplayOptions {+-- CXDiagnostic_DisplaySourceLocation = 0x01,+-- CXDiagnostic_DisplayColumn = 0x02,+-- CXDiagnostic_DisplaySourceRanges = 0x04,+-- CXDiagnostic_DisplayOption = 0x08,+-- CXDiagnostic_DisplayCategoryId = 0x10,+-- CXDiagnostic_DisplayCategoryName = 0x20+-- };++-- | Options for rendering of 'Diagnostic' values.+#c+enum DisplayOptions+ { DisplaySourceLocation = CXDiagnostic_DisplaySourceLocation+ , DisplayColumn = CXDiagnostic_DisplayColumn+ , DisplaySourceRanges = CXDiagnostic_DisplaySourceRanges+ , DisplayOption = CXDiagnostic_DisplayOption+ , DisplayCategoryId = CXDiagnostic_DisplayCategoryId+ , DisplayCategoryName = CXDiagnostic_DisplayCategoryName+ };+#endc+{#enum DisplayOptions {} deriving (Bounded, Eq, Ord, Read, Show, Typeable) #}++instance BitFlags DisplayOptions where+ toBit DisplaySourceLocation = 0x1+ toBit DisplayColumn = 0x2+ toBit DisplaySourceRanges = 0x4+ toBit DisplayOption = 0x8+ toBit DisplayCategoryId = 0x10+ toBit DisplayCategoryName = 0x20++-- CXString clang_formatDiagnostic(CXDiagnostic Diagnostic, unsigned Options);+{# fun wrapped_clang_formatDiagnostic as clang_formatDiagnostic { `Ptr ()' , `Int' } -> `Ptr (ClangString ())' castPtr #}+unsafe_formatDiagnostic :: Diagnostic s -> Int -> IO (ClangString ())+unsafe_formatDiagnostic d i = clang_formatDiagnostic (unDiagnostic d) (fromIntegral i) >>= peek++formatDiagnostic :: ClangBase m => Diagnostic s' -> Int -> ClangT s m (ClangString s)+formatDiagnostic = (registerClangString .) . unsafe_formatDiagnostic++-- unsigned clang_defaultDiagnosticDisplayOptions(void);+{# fun clang_defaultDiagnosticDisplayOptions { } -> `CUInt' #}+defaultDiagnosticDisplayOptions :: IO Int+defaultDiagnosticDisplayOptions = clang_defaultDiagnosticDisplayOptions >>= return . fromIntegral++-- clang_getDiagnosticSeverity(CXDiagnostic);+{# fun clang_getDiagnosticSeverity {id `Ptr ()' } -> `CInt' #}+getDiagnosticSeverity :: Diagnostic s -> IO Severity+getDiagnosticSeverity d = clang_getDiagnosticSeverity (unDiagnostic d) >>= return . toEnum . fromIntegral++-- CXSourceLocation clang_getDiagnosticLocation(CXDiagnostic);+{# fun wrapped_clang_getDiagnosticLocation as clang_getDiagnosticLocation {id `Ptr ()' } -> `Ptr (SourceLocation s)' castPtr #}+getDiagnosticLocation :: Proxy s -> Diagnostic s' -> IO (SourceLocation s)+getDiagnosticLocation _ d = clang_getDiagnosticLocation (unDiagnostic d) >>= peek++-- CXString clang_getDiagnosticSpelling(CXDiagnostic);+{# fun wrapped_clang_getDiagnosticSpelling as clang_getDiagnosticSpelling { id `Ptr ()' } -> `Ptr (ClangString ())' castPtr #}+unsafe_getDiagnosticSpelling :: Diagnostic s -> IO (ClangString ())+unsafe_getDiagnosticSpelling d = clang_getDiagnosticSpelling (unDiagnostic d) >>= peek++getDiagnosticSpelling :: ClangBase m => Diagnostic s' -> ClangT s m (ClangString s)+getDiagnosticSpelling = registerClangString . unsafe_getDiagnosticSpelling++-- CXString clang_getDiagnosticOption(CXDiagnostic Diag,+-- CXString *Disable);+{# fun wrapped_clang_getDiagnosticOption as clang_getDiagnosticOption { id `Ptr ()', id `Ptr ()' } -> `Ptr ()' id #}+unsafe_getDiagnosticOption :: Diagnostic s -> IO (ClangString (), ClangString ())+unsafe_getDiagnosticOption d =+ alloca (\(disableCXStringPtr :: (Ptr (ClangString ()))) -> do+ diagnosticOptionPtr <- clang_getDiagnosticOption (unDiagnostic d) (castPtr disableCXStringPtr)+ disableCXString <- peek disableCXStringPtr+ diagnosticOption <- peek (castPtr diagnosticOptionPtr)+ return (diagnosticOption, disableCXString))++getDiagnosticOption :: ClangBase m => Diagnostic s' -> ClangT s m (ClangString s, ClangString s)+getDiagnosticOption d = do+ (a, b) <- liftIO $ unsafe_getDiagnosticOption d+ (,) <$> registerClangString (return a) <*> registerClangString (return b)++-- unsigned clang_getDiagnosticCategory(CXDiagnostic);+{# fun clang_getDiagnosticCategory { id `Ptr ()' } -> `Int' #}+getDiagnosticCategory :: Diagnostic s -> IO Int+getDiagnosticCategory d = clang_getDiagnosticCategory (unDiagnostic d)++-- CXString clang_getDiagnosticCategoryText(CXDiagnostic);+{# fun wrapped_clang_getDiagnosticCategoryText as clang_getDiagnosticCategoryText { id `Ptr ()' } -> `Ptr (ClangString ())' castPtr #}+unsafe_getDiagnosticCategoryText :: Diagnostic s -> IO (ClangString ())+unsafe_getDiagnosticCategoryText d = clang_getDiagnosticCategoryText (unDiagnostic d) >>= peek++getDiagnosticCategoryText :: ClangBase m => Diagnostic s' -> ClangT s m (ClangString s)+getDiagnosticCategoryText = registerClangString . unsafe_getDiagnosticCategoryText++-- unsigned clang_getDiagnosticNumRanges(CXDiagnostic);+{# fun clang_getDiagnosticNumRanges { id `Ptr ()' } -> `Int' #}+getDiagnosticNumRanges :: Diagnostic s -> IO Int+getDiagnosticNumRanges d = clang_getDiagnosticNumRanges (unDiagnostic d)++-- CXSourceRange clang_getDiagnosticRange(CXDiagnostic Diagnostic,+-- unsigned Range);+{# fun wrapped_clang_getDiagnosticRange as clang_getDiagnosticRange { id `Ptr ()', `Int' } -> `Ptr (SourceRange s)' castPtr #}+getDiagnosticRange :: Diagnostic s' -> Int -> IO (SourceRange s)+getDiagnosticRange d i = clang_getDiagnosticRange (unDiagnostic d) i >>= peek++-- unsigned clang_getDiagnosticNumFixIts(CXDiagnostic Diagnostic);+{# fun clang_getDiagnosticNumFixIts { id `Ptr ()' } -> `Int' #}+getDiagnosticNumFixIts :: Diagnostic s -> IO Int+getDiagnosticNumFixIts d = clang_getDiagnosticNumFixIts (unDiagnostic d)++-- CXString clang_getDiagnosticFixIt(CXDiagnostic Diagnostic,+-- unsigned FixIt,+-- CXSourceRange *ReplacementRange);+{# fun wrapped_clang_getDiagnosticFixIt as clang_getDiagnosticFixIt { id `Ptr ()', `Int', id `Ptr ()' } -> `Ptr (ClangString())' castPtr #}+unsafe_getDiagnosticFixIt :: Diagnostic s' -> Int -> IO (SourceRange s, ClangString ())+unsafe_getDiagnosticFixIt d i =+ alloca (\(replacementRangePtr :: (Ptr (SourceRange s))) -> do+ clangStringPtr <- clang_getDiagnosticFixIt (unDiagnostic d) i (castPtr replacementRangePtr)+ clangString <- peek clangStringPtr+ replacementRange <- peek replacementRangePtr+ return (replacementRange, clangString))++getDiagnosticFixIt :: ClangBase m => Diagnostic s' -> Int+ -> ClangT s m (SourceRange s, ClangString s)+getDiagnosticFixIt d i = do+ (r, s) <- liftIO $ unsafe_getDiagnosticFixIt d i+ (r,) <$> registerClangString (return s)++-- CXString+-- clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit);+{# fun wrapped_clang_getTranslationUnitSpelling as clang_getTranslationUnitSpelling { id `Ptr ()' } -> `Ptr (ClangString ())' castPtr #}+unsafe_getTranslationUnitSpelling :: TranslationUnit s -> IO (ClangString ())+unsafe_getTranslationUnitSpelling t = clang_getTranslationUnitSpelling (unTranslationUnit t) >>= peek++getTranslationUnitSpelling :: ClangBase m => TranslationUnit s' -> ClangT s m (ClangString s)+getTranslationUnitSpelling = registerClangString . unsafe_getTranslationUnitSpelling++-- CXTranslationUnit clang_createTranslationUnitFromSourceFile(+-- CXIndex CIdx,+-- const char *source_filename,+-- int num_clang_command_line_args,+-- const char * const *clang_command_line_args,+-- unsigned num_unsaved_files,+-- struct CXUnsavedFile *unsaved_files);+{# fun clang_createTranslationUnitFromSourceFile { id `Ptr ()' , `CString' , `Int' , id `Ptr CString' , `Int' , id `Ptr ()' } -> `Ptr ()' id #}+unsafe_createTranslationUnitFromSourceFile :: Index s -> String -> Int -> Ptr CString -> Int -> Ptr CUnsavedFile -> IO (TranslationUnit ())+unsafe_createTranslationUnitFromSourceFile i s nas as nufs ufs =+ withCString s (\sPtr -> do+ rPtr <- clang_createTranslationUnitFromSourceFile (unIndex i) sPtr nas as nufs (castPtr ufs)+ return (mkTranslationUnit rPtr))++createTranslationUnitFromSourceFile :: ClangBase m => Index s' -> String -> [String]+ -> DV.Vector UnsavedFile -> ClangT s m (TranslationUnit s)+createTranslationUnitFromSourceFile idx sf as ufs =+ registerTranslationUnit $+ withStringList as $ \asPtr asLen ->+ withUnsavedFiles ufs $ \ufsPtr ufsLen ->+ unsafe_createTranslationUnitFromSourceFile idx sf asLen asPtr ufsLen ufsPtr++-- CXTranslationUnit clang_createTranslationUnit(CXIndex,+-- const char *ast_filename);+{# fun clang_createTranslationUnit { id `Ptr ()', `CString' } -> `Ptr ()' #}+unsafe_createTranslationUnit :: Index s -> String -> IO (TranslationUnit ())+unsafe_createTranslationUnit i s =+ withCString s (\strPtr -> do+ trPtr <- clang_createTranslationUnit (unIndex i) strPtr+ return (mkTranslationUnit trPtr))++createTranslationUnit :: ClangBase m => Index s' -> String -> ClangT s m (TranslationUnit s)+createTranslationUnit = (registerTranslationUnit .) . unsafe_createTranslationUnit++-- enum CXTranslationUnit_Flags {+-- CXTranslationUnit_None = 0x0,+-- CXTranslationUnit_DetailedPreprocessingRecord = 0x01,+-- CXTranslationUnit_Incomplete = 0x02,+-- CXTranslationUnit_PrecompiledPreamble = 0x04,+-- CXTranslationUnit_CacheCompletionResults = 0x08,+-- CXTranslationUnit_ForSerialization = 0x10,+-- CXTranslationUnit_CXXChainedPCH = 0x20,+-- CXTranslationUnit_SkipFunctionBodies = 0x40,+-- CXTranslationUnit_IncludeBriefCommentsInCodeCompletion = 0x80+-- };++-- | Flags that control how a translation unit is parsed.+--+-- * 'DetailedPreprocessingRecordFlag': Used to indicate that the parser should construct a+-- "detailed" preprocessing record, including all macro definitions and instantiations.+-- Constructing a detailed preprocessing record requires more memory and time to parse,+-- since the information contained in the record is usually not retained. However, it can be+-- useful for applications that require more detailed information about the behavior of the+-- preprocessor.+--+-- * 'IncompleteFlag': Used to indicate that the translation unit is incomplete.+-- When a translation unit is considered "incomplete", semantic analysis that is typically+-- performed at the end of the translation unit will be suppressed. For example, this+-- suppresses the completion of tentative declarations in C and of instantiation of+-- implicitly-instantiation function templates in C++. This option is typically used when+-- parsing a header with the intent of producing a precompiled header.+--+-- * 'PrecompiledPreambleFlag': Used to indicate that the translation unit should be built+-- with an implicit precompiled header for the preamble. An implicit precompiled header is+-- used as an optimization when a particular translation unit is likely to be reparsed many+-- times when the sources aren't changing that often. In this case, an implicit precompiled+-- header will be built containing all of the initial includes at the top of the main file+-- (what we refer to as the "preamble" of the file). In subsequent parses, if the preamble+-- or the files in it have not changed, 'Clang.TranslationUnit.reparse' will re-use the+-- implicit precompiled header to improve parsing performance.+--+-- * 'CacheCompletionResultsFlag': Used to indicate that the translation unit should cache+-- some code-completion results with each reparse of the source file.+-- Caching of code-completion results is a performance optimization that introduces some+-- overhead to reparsing but improves the performance of code-completion operations.+--+-- * 'ForSerializationFlag': Used to indicate that the translation unit will be serialized+-- 'Clang.TranslationUnit.save'. This option is typically used when parsing a header with+-- the intent of producing a precompiled header.+--+-- * 'CXXChainedPCHFlag': DEPRECATED: Enabled chained precompiled preambles in C++. Note:+-- this is a *temporary* option that is available only while we are testing C++ precompiled+-- preamble support. It is deprecated.+--+-- * 'SkipFunctionBodiesFlag': Used to indicate that function/method bodies should be skipped+-- while parsing. This option can be used to search for declarations/definitions while+-- ignoring the usages.+--+-- * 'IncludeBriefCommentsInCodeCompletionFlag': Used to indicate that brief documentation+-- comments should be included into the set of code completions returned from this+-- translation unit.+#c+enum TranslationUnitFlags+ { DefaultTranslationUnitFlags = CXTranslationUnit_None+ , DetailedPreprocessingRecordFlag = CXTranslationUnit_DetailedPreprocessingRecord+ , IncompleteFlag = CXTranslationUnit_Incomplete+ , PrecompiledPreambleFlag = CXTranslationUnit_PrecompiledPreamble+ , CacheCompletionResultsFlag = CXTranslationUnit_CacheCompletionResults+ , ForSerializationFlag = CXTranslationUnit_ForSerialization+ , ChainedPCHFlag = CXTranslationUnit_CXXChainedPCH+ , SkipFunctionBodiesFlag = CXTranslationUnit_SkipFunctionBodies+ , IncludeBriefCommentsInCodeCompletionFlag = CXTranslationUnit_IncludeBriefCommentsInCodeCompletion+ };+#endc+{# enum TranslationUnitFlags {} deriving (Bounded, Eq, Ord, Read, Show, Typeable) #}++instance BitFlags TranslationUnitFlags where+ toBit DefaultTranslationUnitFlags = 0x0+ toBit DetailedPreprocessingRecordFlag = 0x01+ toBit IncompleteFlag = 0x02+ toBit PrecompiledPreambleFlag = 0x04+ toBit CacheCompletionResultsFlag = 0x08+ toBit ForSerializationFlag = 0x10+ toBit ChainedPCHFlag = 0x20+ toBit SkipFunctionBodiesFlag = 0x40+ toBit IncludeBriefCommentsInCodeCompletionFlag = 0x80++-- unsigned clang_defaultEditingTranslationUnitOptions(void);+{# fun clang_defaultEditingTranslationUnitOptions as defaultEditingTranslationUnitOptions {} -> `Int' #}++maybeTranslationUnit :: TranslationUnit s' -> Maybe (TranslationUnit s)+maybeTranslationUnit (TranslationUnit p) | p == nullPtr = Nothing+maybeTranslationUnit f = Just (unsafeCoerce f)++-- CXTranslationUnit clang_parseTranslationUnit(CXIndex CIdx,+-- const char *source_filename,+-- const char * const *command_line_args,+-- int num_command_line_args,+-- struct CXUnsavedFile *unsaved_files,+-- unsigned num_unsaved_files,+-- unsigned options);+{# fun clang_parseTranslationUnit { id `Ptr ()', `CString' , id `Ptr CString', `Int', id `Ptr ()', `Int', `Int'} -> `Ptr ()' id #}+unsafe_parseTranslationUnit :: Index s -> CString -> Ptr CString -> Int -> Ptr CUnsavedFile -> Int -> Int -> IO (Maybe (TranslationUnit ()))+unsafe_parseTranslationUnit i s as nas ufs nufs o =+ clang_parseTranslationUnit (unIndex i) s as nas (castPtr ufs) nufs o >>= return . maybeTranslationUnit . mkTranslationUnit++parseTranslationUnit :: ClangBase m => Index s' -> Maybe String -> [String]+ -> DV.Vector UnsavedFile -> Int -> ClangT s m (Maybe (TranslationUnit s))+parseTranslationUnit idx maySF as ufs opts = do+ mayTU <- liftIO $+ withMaybeCString maySF $ \cSF ->+ withStringList as $ \asPtr asLen ->+ withUnsavedFiles ufs $ \ufsPtr ufsLen ->+ unsafe_parseTranslationUnit idx cSF asPtr asLen ufsPtr ufsLen opts+ case mayTU of+ Just tu -> Just <$> registerTranslationUnit (return tu)+ Nothing -> return Nothing++withMaybeCString :: Maybe String -> (CString -> IO a) -> IO a+withMaybeCString (Just s) f = withCString s f+withMaybeCString Nothing f = f nullPtr++withStringList :: [String] -> (Ptr CString -> Int -> IO a) -> IO a+withStringList [] f = f nullPtr 0+withStringList strs f = do+ let len = length strs+ allocaArray len $ \arr -> go arr len arr strs+ where+ go arr len _ [] = f arr len+ go arr len ptr (s : ss) = withCString s $ \cs -> do+ poke ptr cs+ go arr len (advancePtr ptr 1) ss++-- enum CXSaveTranslationUnit_Flags {+-- CXSaveTranslationUnit_None = 0x0+-- };++-- | Flags that control how a translation unit is saved.+#c+enum SaveTranslationUnitFlags+ {DefaultSaveTranslationUnitFlags = CXSaveTranslationUnit_None};+#endc+{# enum SaveTranslationUnitFlags {} deriving (Bounded, Eq, Ord, Read, Show, Typeable) #}+instance BitFlags SaveTranslationUnitFlags where+ toBit DefaultSaveTranslationUnitFlags = 0x0++-- unsigned clang_defaultSaveOptions(CXTranslationUnit TU);+{# fun clang_defaultSaveOptions { id `Ptr ()' } -> `Int' #}+defaultSaveOptions :: TranslationUnit s -> IO Int+defaultSaveOptions t = clang_defaultSaveOptions (unTranslationUnit t)+++-- int clang_saveTranslationUnit(CXTranslationUnit TU,+-- const char *FileName,+-- unsigned options);+{# fun clang_saveTranslationUnit { id `Ptr ()' , `CString', `Int' } -> `Int' #}+saveTranslationUnit :: TranslationUnit s -> String -> Int -> IO Bool+saveTranslationUnit t s i =+ withCString s (\sPtr -> do+ r <- clang_saveTranslationUnit (unTranslationUnit t) sPtr i+ return (toBool ((if (r /= 0) then 0 else 1) :: Int)))++-- enum CXReparse_Flags {+-- CXReparse_None = 0x0+-- };++-- | Flags that control how a translation unit is reparsed.+#c+enum ReparseFlags {+ DefaultReparseFlags = CXReparse_None+};+#endc+{# enum ReparseFlags {} deriving (Bounded, Eq, Ord, Read, Show, Typeable) #}++instance BitFlags ReparseFlags where+ toBit DefaultReparseFlags = 0x0++-- unsigned clang_defaultReparseOptions(CXTranslationUnit TU);+{# fun clang_defaultReparseOptions { id `Ptr ()' } -> `CUInt' #}+defaultReparseOptions :: TranslationUnit s -> IO Int+defaultReparseOptions t = clang_defaultReparseOptions (unTranslationUnit t) >>= return . fromIntegral++-- int clang_reparseTranslationUnit(CXTranslationUnit TU,+-- unsigned num_unsaved_files,+-- struct CXUnsavedFile *unsaved_files,+-- unsigned options);+{# fun clang_reparseTranslationUnit { id `Ptr ()', `Int' , id `Ptr ()' , `Int' } -> `Bool' toBool #}+unsafe_reparseTranslationUnit :: TranslationUnit s -> Ptr CUnsavedFile -> Int -> Int -> IO Bool+unsafe_reparseTranslationUnit t ufs nufs i =+ clang_reparseTranslationUnit (unTranslationUnit t) nufs (castPtr ufs) i++reparseTranslationUnit :: ClangBase m => TranslationUnit s' -> DV.Vector UnsavedFile -> Int+ -> ClangT s m Bool+reparseTranslationUnit tu ufs opts = liftIO $+ withUnsavedFiles ufs $ \ufsPtr ufsLen ->+ unsafe_reparseTranslationUnit tu ufsPtr ufsLen opts+++-- enum CXCursorKind {+-- /* Declarations */+-- /**+-- * \brief A declaration whose specific kind is not exposed via this+-- * interface.+-- *+-- * Unexposed declarations have the same operations as any other kind+-- * of declaration; one can extract their location information,+-- * spelling, find their definitions, etc. However, the specific kind+-- * of the declaration is not reported.+-- */+-- CXCursor_UnexposedDecl = 1,+-- /** \brief A C or C++ struct. */+-- CXCursor_StructDecl = 2,+-- /** \brief A C or C++ union. */+-- CXCursor_UnionDecl = 3,+-- /** \brief A C++ class. */+-- CXCursor_ClassDecl = 4,+-- /** \brief An enumeration. */+-- CXCursor_EnumDecl = 5,+-- /**+-- * \brief A field (in C) or non-static data member (in C++) in a+-- * struct, union, or C++ class.+-- */+-- CXCursor_FieldDecl = 6,+-- /** \brief An enumerator constant. */+-- CXCursor_EnumConstantDecl = 7,+-- /** \brief A function. */+-- CXCursor_FunctionDecl = 8,+-- /** \brief A variable. */+-- CXCursor_VarDecl = 9,+-- /** \brief A function or method parameter. */+-- CXCursor_ParmDecl = 10,+-- /** \brief An Objective-C @interface. */+-- CXCursor_ObjCInterfaceDecl = 11,+-- /** \brief An Objective-C @interface for a category. */+-- CXCursor_ObjCCategoryDecl = 12,+-- /** \brief An Objective-C @protocol declaration. */+-- CXCursor_ObjCProtocolDecl = 13,+-- /** \brief An Objective-C @property declaration. */+-- CXCursor_ObjCPropertyDecl = 14,+-- /** \brief An Objective-C instance variable. */+-- CXCursor_ObjCIvarDecl = 15,+-- /** \brief An Objective-C instance method. */+-- CXCursor_ObjCInstanceMethodDecl = 16,+-- /** \brief An Objective-C class method. */+-- CXCursor_ObjCClassMethodDecl = 17,+-- /** \brief An Objective-C @implementation. */+-- CXCursor_ObjCImplementationDecl = 18,+-- /** \brief An Objective-C @implementation for a category. */+-- CXCursor_ObjCCategoryImplDecl = 19,+-- /** \brief A typedef */+-- CXCursor_TypedefDecl = 20,+-- /** \brief A C++ class method. */+-- CXCursor_CXXMethod = 21,+-- /** \brief A C++ namespace. */+-- CXCursor_Namespace = 22,+-- /** \brief A linkage specification, e.g. 'extern "C"'. */+-- CXCursor_LinkageSpec = 23,+-- /** \brief A C++ constructor. */+-- CXCursor_Constructor = 24,+-- /** \brief A C++ destructor. */+-- CXCursor_Destructor = 25,+-- /** \brief A C++ conversion function. */+-- CXCursor_ConversionFunction = 26,+-- /** \brief A C++ template type parameter. */+-- CXCursor_TemplateTypeParameter = 27,+-- /** \brief A C++ non-type template parameter. */+-- CXCursor_NonTypeTemplateParameter = 28,+-- /** \brief A C++ template template parameter. */+-- CXCursor_TemplateTemplateParameter = 29,+-- /** \brief A C++ function template. */+-- CXCursor_FunctionTemplate = 30,+-- /** \brief A C++ class template. */+-- CXCursor_ClassTemplate = 31,+-- /** \brief A C++ class template partial specialization. */+-- CXCursor_ClassTemplatePartialSpecialization = 32,+-- /** \brief A C++ namespace alias declaration. */+-- CXCursor_NamespaceAlias = 33,+-- /** \brief A C++ using directive. */+-- CXCursor_UsingDirective = 34,+-- /** \brief A C++ using declaration. */+-- CXCursor_UsingDeclaration = 35,+-- /** \brief A C++ alias declaration */+-- CXCursor_TypeAliasDecl = 36,+-- /** \brief An Objective-C @synthesize definition. */+-- CXCursor_ObjCSynthesizeDecl = 37,+-- /** \brief An Objective-C @dynamic definition. */+-- CXCursor_ObjCDynamicDecl = 38,+-- /** \brief An access specifier. */+-- CXCursor_CXXAccessSpecifier = 39,++-- CXCursor_FirstDecl = CXCursor_UnexposedDecl,+-- CXCursor_LastDecl = CXCursor_CXXAccessSpecifier,++-- /* References */+-- CXCursor_FirstRef = 40, /* Decl references */+-- CXCursor_ObjCSuperClassRef = 40,+-- CXCursor_ObjCProtocolRef = 41,+-- CXCursor_ObjCClassRef = 42,+-- /**+-- * \brief A reference to a type declaration.+-- *+-- * A type reference occurs anywhere where a type is named but not+-- * declared. For example, given:+-- *+-- * \code+-- * typedef unsigned size_type;+-- * size_type size;+-- * \endcode+-- *+-- * The typedef is a declaration of size_type (CXCursor_TypedefDecl),+-- * while the type of the variable "size" is referenced. The cursor+-- * referenced by the type of size is the typedef for size_type.+-- */+-- CXCursor_TypeRef = 43,+-- CXCursor_CXXBaseSpecifier = 44,+-- /**+-- * \brief A reference to a class template, function template, template+-- * template parameter, or class template partial specialization.+-- */+-- CXCursor_TemplateRef = 45,+-- /**+-- * \brief A reference to a namespace or namespace alias.+-- */+-- CXCursor_NamespaceRef = 46,+-- /**+-- * \brief A reference to a member of a struct, union, or class that occurs in+-- * some non-expression context, e.g., a designated initializer.+-- */+-- CXCursor_MemberRef = 47,+-- /**+-- * \brief A reference to a labeled statement.+-- *+-- * This cursor kind is used to describe the jump to "start_over" in the+-- * goto statement in the following example:+-- *+-- * \code+-- * start_over:+-- * ++counter;+-- *+-- * goto start_over;+-- * \endcode+-- *+-- * A label reference cursor refers to a label statement.+-- */+-- CXCursor_LabelRef = 48,++-- /**+-- * \brief A reference to a set of overloaded functions or function templates+-- * that has not yet been resolved to a specific function or function template.+-- *+-- * An overloaded declaration reference cursor occurs in C++ templates where+-- * a dependent name refers to a function. For example:+-- *+-- * \code+-- * template<typename T> void swap(T&, T&);+-- *+-- * struct X { ... };+-- * void swap(X&, X&);+-- *+-- * template<typename T>+-- * void reverse(T* first, T* last) {+-- * while (first < last - 1) {+-- * swap(*first, *--last);+-- * ++first;+-- * }+-- * }+-- *+-- * struct Y { };+-- * void swap(Y&, Y&);+-- * \endcode+-- *+-- * Here, the identifier "swap" is associated with an overloaded declaration+-- * reference. In the template definition, "swap" refers to either of the two+-- * "swap" functions declared above, so both results will be available. At+-- * instantiation time, "swap" may also refer to other functions found via+-- * argument-dependent lookup (e.g., the "swap" function at the end of the+-- * example).+-- *+-- * The functions \c clang_getNumOverloadedDecls() and+-- * \c clang_getOverloadedDecl() can be used to retrieve the definitions+-- * referenced by this cursor.+-- */+-- CXCursor_OverloadedDeclRef = 49,++-- /*+-- * \brief A reference to a variable that occurs in some non-expression+-- * context, e.g., a C++ lambda capture list.+-- */+-- CXCursor_VariableRef = 50,++-- CXCursor_LastRef = CXCursor_VariableRef,++-- /* Error conditions */+-- CXCursor_FirstInvalid = 70,+-- CXCursor_InvalidFile = 70,+-- CXCursor_NoDeclFound = 71,+-- CXCursor_NotImplemented = 72,+-- CXCursor_InvalidCode = 73,+-- CXCursor_LastInvalid = CXCursor_InvalidCode,++-- /* Expressions */+-- CXCursor_FirstExpr = 100,++-- /**+-- * \brief An expression whose specific kind is not exposed via this+-- * interface.+-- *+-- * Unexposed expressions have the same operations as any other kind+-- * of expression; one can extract their location information,+-- * spelling, children, etc. However, the specific kind of the+-- * expression is not reported.+-- */+-- CXCursor_UnexposedExpr = 100,++-- /**+-- * \brief An expression that refers to some value declaration, such+-- * as a function, varible, or enumerator.+-- */+-- CXCursor_DeclRefExpr = 101,++-- /**+-- * \brief An expression that refers to a member of a struct, union,+-- * class, Objective-C class, etc.+-- */+-- CXCursor_MemberRefExpr = 102,++-- /** \brief An expression that calls a function. */+-- CXCursor_CallExpr = 103,++-- /** \brief An expression that sends a message to an Objective-C+-- object or class. */+-- CXCursor_ObjCMessageExpr = 104,++-- /** \brief An expression that represents a block literal. */+-- CXCursor_BlockExpr = 105,++-- /** \brief An integer literal.+-- */+-- CXCursor_IntegerLiteral = 106,++-- /** \brief A floating point number literal.+-- */+-- CXCursor_FloatingLiteral = 107,++-- /** \brief An imaginary number literal.+-- */+-- CXCursor_ImaginaryLiteral = 108,++-- /** \brief A string literal.+-- */+-- CXCursor_StringLiteral = 109,++-- /** \brief A character literal.+-- */+-- CXCursor_CharacterLiteral = 110,++-- /** \brief A parenthesized expression, e.g. "(1)".+-- *+-- * This AST node is only formed if full location information is requested.+-- */+-- CXCursor_ParenExpr = 111,++-- /** \brief This represents the unary-expression's (except sizeof and+-- * alignof).+-- */+-- CXCursor_UnaryOperator = 112,++-- /** \brief [C99 6.5.2.1] Array Subscripting.+-- */+-- CXCursor_ArraySubscriptExpr = 113,++-- /** \brief A builtin binary operation expression such as "x + y" or+-- * "x <= y".+-- */+-- CXCursor_BinaryOperator = 114,++-- /** \brief Compound assignment such as "+=".+-- */+-- CXCursor_CompoundAssignOperator = 115,++-- /** \brief The ?: ternary operator.+-- */+-- CXCursor_ConditionalOperator = 116,++-- /** \brief An explicit cast in C (C99 6.5.4) or a C-style cast in C+++-- * (C++ [expr.cast]), which uses the syntax (Type)expr.+-- *+-- * For example: (int)f.+-- */+-- CXCursor_CStyleCastExpr = 117,++-- /** \brief [C99 6.5.2.5]+-- */+-- CXCursor_CompoundLiteralExpr = 118,++-- /** \brief Describes an C or C++ initializer list.+-- */+-- CXCursor_InitListExpr = 119,++-- /** \brief The GNU address of label extension, representing &&label.+-- */+-- CXCursor_AddrLabelExpr = 120,++-- /** \brief This is the GNU Statement Expression extension: ({int X=4; X;})+-- */+-- CXCursor_StmtExpr = 121,++-- /** \brief Represents a C1X generic selection.+-- */+-- CXCursor_GenericSelectionExpr = 122,++-- /** \brief Implements the GNU __null extension, which is a name for a null+-- * pointer constant that has integral type (e.g., int or long) and is the same+-- * size and alignment as a pointer.+-- *+-- * The __null extension is typically only used by system headers, which define+-- * NULL as __null in C++ rather than using 0 (which is an integer that may not+-- * match the size of a pointer).+-- */+-- CXCursor_GNUNullExpr = 123,++-- /** \brief C++'s static_cast<> expression.+-- */+-- CXCursor_CXXStaticCastExpr = 124,++-- /** \brief C++'s dynamic_cast<> expression.+-- */+-- CXCursor_CXXDynamicCastExpr = 125,++-- /** \brief C++'s reinterpret_cast<> expression.+-- */+-- CXCursor_CXXReinterpretCastExpr = 126,++-- /** \brief C++'s const_cast<> expression.+-- */+-- CXCursor_CXXConstCastExpr = 127,++-- /** \brief Represents an explicit C++ type conversion that uses "functional"+-- * notion (C++ [expr.type.conv]).+-- *+-- * Example:+-- * \code+-- * x = int(0.5);+-- * \endcode+-- */+-- CXCursor_CXXFunctionalCastExpr = 128,++-- /** \brief A C++ typeid expression (C++ [expr.typeid]).+-- */+-- CXCursor_CXXTypeidExpr = 129,++-- /** \brief [C++ 2.13.5] C++ Boolean Literal.+-- */+-- CXCursor_CXXBoolLiteralExpr = 130,++-- /** \brief [C++0x 2.14.7] C++ Pointer Literal.+-- */+-- CXCursor_CXXNullPtrLiteralExpr = 131,++-- /** \brief Represents the "this" expression in C+++-- */+-- CXCursor_CXXThisExpr = 132,++-- /** \brief [C++ 15] C++ Throw Expression.+-- *+-- * This handles 'throw' and 'throw' assignment-expression. When+-- * assignment-expression isn't present, Op will be null.+-- */+-- CXCursor_CXXThrowExpr = 133,++-- /** \brief A new expression for memory allocation and constructor calls, e.g:+-- * "new CXXNewExpr(foo)".+-- */+-- CXCursor_CXXNewExpr = 134,++-- /** \brief A delete expression for memory deallocation and destructor calls,+-- * e.g. "delete[] pArray".+-- */+-- CXCursor_CXXDeleteExpr = 135,++-- /** \brief A unary expression.+-- */+-- CXCursor_UnaryExpr = 136,++-- /** \brief ObjCStringLiteral, used for Objective-C string literals i.e. "foo".+-- */+-- CXCursor_ObjCStringLiteral = 137,++-- /** \brief ObjCEncodeExpr, used for in Objective-C.+-- */+-- CXCursor_ObjCEncodeExpr = 138,++-- /** \brief ObjCSelectorExpr used for in Objective-C.+-- */+-- CXCursor_ObjCSelectorExpr = 139,++-- /** \brief Objective-C's protocol expression.+-- */+-- CXCursor_ObjCProtocolExpr = 140,++-- /** \brief An Objective-C "bridged" cast expression, which casts between+-- * Objective-C pointers and C pointers, transferring ownership in the process.+-- *+-- * \code+-- * NSString *str = (__bridge_transfer NSString *)CFCreateString();+-- * \endcode+-- */+-- CXCursor_ObjCBridgedCastExpr = 141,++-- /** \brief Represents a C++0x pack expansion that produces a sequence of+-- * expressions.+-- *+-- * A pack expansion expression contains a pattern (which itself is an+-- * expression) followed by an ellipsis. For example:+-- *+-- * \code+-- * template<typename F, typename ...Types>+-- * void forward(F f, Types &&...args) {+-- * f(static_cast<Types&&>(args)...);+-- * }+-- * \endcode+-- */+-- CXCursor_PackExpansionExpr = 142,++-- /** \brief Represents an expression that computes the length of a parameter+-- * pack.+-- *+-- * \code+-- * template<typename ...Types>+-- * struct count {+-- * static const unsigned value = sizeof...(Types);+-- * };+-- * \endcode+-- */+-- CXCursor_SizeOfPackExpr = 143,++-- /* \brief Represents a C++ lambda expression that produces a local function+-- * object.+-- *+-- * \code+-- * void abssort(float *x, unsigned N) {+-- * std::sort(x, x + N,+-- * [](float a, float b) {+-- * return std::abs(a) < std::abs(b);+-- * });+-- * }+-- * \endcode+-- */+-- CXCursor_LambdaExpr = 144,++-- /** \brief Objective-c Boolean Literal.+-- */+-- CXCursor_ObjCBoolLiteralExpr = 145,++-- /** \brief Represents the "self" expression in a ObjC method.+-- */+-- CXCursor_ObjCSelfExpr = 146,++-- CXCursor_LastExpr = CXCursor_ObjCSelfExpr,++-- /* Statements */+-- CXCursor_FirstStmt = 200,+-- /**+-- * \brief A statement whose specific kind is not exposed via this+-- * interface.+-- *+-- * Unexposed statements have the same operations as any other kind of+-- * statement; one can extract their location information, spelling,+-- * children, etc. However, the specific kind of the statement is not+-- * reported.+-- */+-- CXCursor_UnexposedStmt = 200,++-- /** \brief A labelled statement in a function.+-- *+-- * This cursor kind is used to describe the "start_over:" label statement in+-- * the following example:+-- *+-- * \code+-- * start_over:+-- * ++counter;+-- * \endcode+-- *+-- */+-- CXCursor_LabelStmt = 201,++-- /** \brief A group of statements like { stmt stmt }.+-- *+-- * This cursor kind is used to describe compound statements, e.g. function+-- * bodies.+-- */+-- CXCursor_CompoundStmt = 202,++-- /** \brief A case statment.+-- */+-- CXCursor_CaseStmt = 203,++-- /** \brief A default statement.+-- */+-- CXCursor_DefaultStmt = 204,++-- /** \brief An if statement+-- */+-- CXCursor_IfStmt = 205,++-- /** \brief A switch statement.+-- */+-- CXCursor_SwitchStmt = 206,++-- /** \brief A while statement.+-- */+-- CXCursor_WhileStmt = 207,++-- /** \brief A do statement.+-- */+-- CXCursor_DoStmt = 208,++-- /** \brief A for statement.+-- */+-- CXCursor_ForStmt = 209,++-- /** \brief A goto statement.+-- */+-- CXCursor_GotoStmt = 210,++-- /** \brief An indirect goto statement.+-- */+-- CXCursor_IndirectGotoStmt = 211,++-- /** \brief A continue statement.+-- */+-- CXCursor_ContinueStmt = 212,++-- /** \brief A break statement.+-- */+-- CXCursor_BreakStmt = 213,++-- /** \brief A return statement.+-- */+-- CXCursor_ReturnStmt = 214,++-- /** \brief A GNU inline assembly statement extension.+-- */+-- CXCursor_GCCAsmStmt = 215,+-- CXCursor_AsmStmt = CXCursor_GCCAsmStmt,++-- /** \brief Objective-C's overall @try-@catc-@finall statement.+-- */+-- CXCursor_ObjCAtTryStmt = 216,++-- /** \brief Objective-C's @catch statement.+-- */+-- CXCursor_ObjCAtCatchStmt = 217,++-- /** \brief Objective-C's @finally statement.+-- */+-- CXCursor_ObjCAtFinallyStmt = 218,++-- /** \brief Objective-C's @throw statement.+-- */+-- CXCursor_ObjCAtThrowStmt = 219,++-- /** \brief Objective-C's @synchronized statement.+-- */+-- CXCursor_ObjCAtSynchronizedStmt = 220,++-- /** \brief Objective-C's autorelease pool statement.+-- */+-- CXCursor_ObjCAutoreleasePoolStmt = 221,++-- /** \brief Objective-C's collection statement.+-- */+-- CXCursor_ObjCForCollectionStmt = 222,++-- /** \brief C++'s catch statement.+-- */+-- CXCursor_CXXCatchStmt = 223,++-- /** \brief C++'s try statement.+-- */+-- CXCursor_CXXTryStmt = 224,++-- /** \brief C++'s for (* : *) statement.+-- */+-- CXCursor_CXXForRangeStmt = 225,++-- /** \brief Windows Structured Exception Handling's try statement.+-- */+-- CXCursor_SEHTryStmt = 226,++-- /** \brief Windows Structured Exception Handling's except statement.+-- */+-- CXCursor_SEHExceptStmt = 227,++-- /** \brief Windows Structured Exception Handling's finally statement.+-- */+-- CXCursor_SEHFinallyStmt = 228,++-- /** \brief A MS inline assembly statement extension.+-- */+-- CXCursor_MSAsmStmt = 229,++-- /** \brief The null satement ";": C99 6.8.3p3.+-- *+-- * This cursor kind is used to describe the null statement.+-- */+-- CXCursor_NullStmt = 230,++-- /** \brief Adaptor class for mixing declarations with statements and+-- * expressions.+-- */+-- CXCursor_DeclStmt = 231,++-- /** \brief OpenMP parallel directive.+-- */+-- CXCursor_OMPParallelDirective = 232,++-- CXCursor_LastStmt = CXCursor_OMPParallelDirective,++-- /**+-- * \brief Cursor that represents the translation unit itself.+-- *+-- * The translation unit cursor exists primarily to act as the root+-- * cursor for traversing the contents of a translation unit.+-- */+-- CXCursor_TranslationUnit = 300,++-- /* Attributes */+-- CXCursor_FirstAttr = 400,+-- /**+-- * \brief An attribute whose specific kind is not exposed via this+-- * interface.+-- */+-- CXCursor_UnexposedAttr = 400,++-- CXCursor_IBActionAttr = 401,+-- CXCursor_IBOutletAttr = 402,+-- CXCursor_IBOutletCollectionAttr = 403,+-- CXCursor_CXXFinalAttr = 404,+-- CXCursor_CXXOverrideAttr = 405,+-- CXCursor_AnnotateAttr = 406,+-- CXCursor_AsmLabelAttr = 407,+-- CXCursor_PackedAttr = 408,+-- CXCursor_LastAttr = CXCursor_PackedAttr,++-- /* Preprocessing */+-- CXCursor_PreprocessingDirective = 500,+-- CXCursor_MacroDefinition = 501,+-- CXCursor_MacroExpansion = 502,+-- CXCursor_MacroInstantiation = CXCursor_MacroExpansion,+-- CXCursor_InclusionDirective = 503,+-- CXCursor_FirstPreprocessing = CXCursor_PreprocessingDirective,+-- CXCursor_LastPreprocessing = CXCursor_InclusionDirective++-- /* Extra Declarations */+-- /**+-- * \brief A module import declaration.+-- */+-- CXCursor_ModuleImportDecl = 600,+-- CXCursor_FirstExtraDecl = CXCursor_ModuleImportDecl,+-- CXCursor_LastExtraDecl = CXCursor_ModuleImportDecl+-- };+#c+enum CursorKind+ { UnexposedDeclCursor = CXCursor_UnexposedDecl+ , StructDeclCursor = CXCursor_StructDecl+ , UnionDeclCursor = CXCursor_UnionDecl+ , ClassDeclCursor = CXCursor_ClassDecl+ , EnumDeclCursor = CXCursor_EnumDecl+ , FieldDeclCursor = CXCursor_FieldDecl+ , EnumConstantDeclCursor = CXCursor_EnumConstantDecl+ , FunctionDeclCursor = CXCursor_FunctionDecl+ , VarDeclCursor = CXCursor_VarDecl+ , ParmDeclCursor = CXCursor_ParmDecl+ , ObjCInterfaceDeclCursor = CXCursor_ObjCInterfaceDecl+ , ObjCCategoryDeclCursor = CXCursor_ObjCCategoryDecl+ , ObjCProtocolDeclCursor = CXCursor_ObjCProtocolDecl+ , ObjCPropertyDeclCursor = CXCursor_ObjCPropertyDecl+ , ObjCIvarDeclCursor = CXCursor_ObjCIvarDecl+ , ObjCInstanceMethodDeclCursor = CXCursor_ObjCInstanceMethodDecl+ , ObjCClassMethodDeclCursor = CXCursor_ObjCClassMethodDecl+ , ObjCImplementationDeclCursor = CXCursor_ObjCImplementationDecl+ , ObjCCategoryImplDeclCursor = CXCursor_ObjCCategoryImplDecl+ , TypedefDeclCursor = CXCursor_TypedefDecl+ , CXXMethodCursor = CXCursor_CXXMethod+ , NamespaceCursor = CXCursor_Namespace+ , LinkageSpecCursor = CXCursor_LinkageSpec+ , ConstructorCursor = CXCursor_Constructor+ , DestructorCursor = CXCursor_Destructor+ , ConversionFunctionCursor = CXCursor_ConversionFunction+ , TemplateTypeParameterCursor = CXCursor_TemplateTypeParameter+ , NonTypeTemplateParameterCursor = CXCursor_NonTypeTemplateParameter+ , TemplateTemplateParameterCursor = CXCursor_TemplateTemplateParameter+ , FunctionTemplateCursor = CXCursor_FunctionTemplate+ , ClassTemplateCursor = CXCursor_ClassTemplate+ , ClassTemplatePartialSpecializationCursor = CXCursor_ClassTemplatePartialSpecialization+ , NamespaceAliasCursor = CXCursor_NamespaceAlias+ , UsingDirectiveCursor = CXCursor_UsingDirective+ , UsingDeclarationCursor = CXCursor_UsingDeclaration+ , TypeAliasDeclCursor = CXCursor_TypeAliasDecl+ , ObjCSynthesizeDeclCursor = CXCursor_ObjCSynthesizeDecl+ , ObjCDynamicDeclCursor = CXCursor_ObjCDynamicDecl+ , CXXAccessSpecifierCursor = CXCursor_CXXAccessSpecifier+ , ObjCSuperClassRefCursor = CXCursor_ObjCSuperClassRef+ , ObjCProtocolRefCursor = CXCursor_ObjCProtocolRef+ , ObjCClassRefCursor = CXCursor_ObjCClassRef+ , TypeRefCursor = CXCursor_TypeRef+ , CXXBaseSpecifierCursor = CXCursor_CXXBaseSpecifier+ , TemplateRefCursor = CXCursor_TemplateRef+ , NamespaceRefCursor = CXCursor_NamespaceRef+ , MemberRefCursor = CXCursor_MemberRef+ , LabelRefCursor = CXCursor_LabelRef+ , OverloadedDeclRefCursor = CXCursor_OverloadedDeclRef+ , VariableRefCursor = CXCursor_VariableRef+ , InvalidFileCursor = CXCursor_InvalidFile+ , NoDeclFoundCursor = CXCursor_NoDeclFound+ , NotImplementedCursor = CXCursor_NotImplemented+ , InvalidCodeCursor = CXCursor_InvalidCode+ , UnexposedExprCursor = CXCursor_UnexposedExpr+ , DeclRefExprCursor = CXCursor_DeclRefExpr+ , MemberRefExprCursor = CXCursor_MemberRefExpr+ , CallExprCursor = CXCursor_CallExpr+ , ObjCMessageExprCursor = CXCursor_ObjCMessageExpr+ , BlockExprCursor = CXCursor_BlockExpr+ , IntegerLiteralCursor = CXCursor_IntegerLiteral+ , FloatingLiteralCursor = CXCursor_FloatingLiteral+ , ImaginaryLiteralCursor = CXCursor_ImaginaryLiteral+ , StringLiteralCursor = CXCursor_StringLiteral+ , CharacterLiteralCursor = CXCursor_CharacterLiteral+ , ParenExprCursor = CXCursor_ParenExpr+ , UnaryOperatorCursor = CXCursor_UnaryOperator+ , ArraySubscriptExprCursor = CXCursor_ArraySubscriptExpr+ , BinaryOperatorCursor = CXCursor_BinaryOperator+ , CompoundAssignOperatorCursor = CXCursor_CompoundAssignOperator+ , ConditionalOperatorCursor = CXCursor_ConditionalOperator+ , CStyleCastExprCursor = CXCursor_CStyleCastExpr+ , CompoundLiteralExprCursor = CXCursor_CompoundLiteralExpr+ , InitListExprCursor = CXCursor_InitListExpr+ , AddrLabelExprCursor = CXCursor_AddrLabelExpr+ , StmtExprCursor = CXCursor_StmtExpr+ , GenericSelectionExprCursor = CXCursor_GenericSelectionExpr+ , GNUNullExprCursor = CXCursor_GNUNullExpr+ , CXXStaticCastExprCursor = CXCursor_CXXStaticCastExpr+ , CXXDynamicCastExprCursor = CXCursor_CXXDynamicCastExpr+ , CXXReinterpretCastExprCursor = CXCursor_CXXReinterpretCastExpr+ , CXXConstCastExprCursor = CXCursor_CXXConstCastExpr+ , CXXFunctionalCastExprCursor = CXCursor_CXXFunctionalCastExpr+ , CXXTypeidExprCursor = CXCursor_CXXTypeidExpr+ , CXXBoolLiteralExprCursor = CXCursor_CXXBoolLiteralExpr+ , CXXNullPtrLiteralExprCursor = CXCursor_CXXNullPtrLiteralExpr+ , CXXThisExprCursor = CXCursor_CXXThisExpr+ , CXXThrowExprCursor = CXCursor_CXXThrowExpr+ , CXXNewExprCursor = CXCursor_CXXNewExpr+ , CXXDeleteExprCursor = CXCursor_CXXDeleteExpr+ , UnaryExprCursor = CXCursor_UnaryExpr+ , ObjCStringLiteralCursor = CXCursor_ObjCStringLiteral+ , ObjCEncodeExprCursor = CXCursor_ObjCEncodeExpr+ , ObjCSelectorExprCursor = CXCursor_ObjCSelectorExpr+ , ObjCProtocolExprCursor = CXCursor_ObjCProtocolExpr+ , ObjCBridgedCastExprCursor = CXCursor_ObjCBridgedCastExpr+ , PackExpansionExprCursor = CXCursor_PackExpansionExpr+ , SizeOfPackExprCursor = CXCursor_SizeOfPackExpr+ , LambdaExprCursor = CXCursor_LambdaExpr+ , ObjCBoolLiteralExprCursor = CXCursor_ObjCBoolLiteralExpr+ , ObjCSelfExprCursor = CXCursor_ObjCSelfExpr+ , UnexposedStmtCursor = CXCursor_UnexposedStmt+ , LabelStmtCursor = CXCursor_LabelStmt+ , CompoundStmtCursor = CXCursor_CompoundStmt+ , CaseStmtCursor = CXCursor_CaseStmt+ , DefaultStmtCursor = CXCursor_DefaultStmt+ , IfStmtCursor = CXCursor_IfStmt+ , SwitchStmtCursor = CXCursor_SwitchStmt+ , WhileStmtCursor = CXCursor_WhileStmt+ , DoStmtCursor = CXCursor_DoStmt+ , ForStmtCursor = CXCursor_ForStmt+ , GotoStmtCursor = CXCursor_GotoStmt+ , IndirectGotoStmtCursor = CXCursor_IndirectGotoStmt+ , ContinueStmtCursor = CXCursor_ContinueStmt+ , BreakStmtCursor = CXCursor_BreakStmt+ , ReturnStmtCursor = CXCursor_ReturnStmt+ , AsmStmtCursor = CXCursor_AsmStmt+ , ObjCAtTryStmtCursor = CXCursor_ObjCAtTryStmt+ , ObjCAtCatchStmtCursor = CXCursor_ObjCAtCatchStmt+ , ObjCAtFinallyStmtCursor = CXCursor_ObjCAtFinallyStmt+ , ObjCAtThrowStmtCursor = CXCursor_ObjCAtThrowStmt+ , ObjCAtSynchronizedStmtCursor = CXCursor_ObjCAtSynchronizedStmt+ , ObjCAutoreleasePoolStmtCursor = CXCursor_ObjCAutoreleasePoolStmt+ , ObjCForCollectionStmtCursor = CXCursor_ObjCForCollectionStmt+ , CXXCatchStmtCursor = CXCursor_CXXCatchStmt+ , CXXTryStmtCursor = CXCursor_CXXTryStmt+ , CXXForRangeStmtCursor = CXCursor_CXXForRangeStmt+ , SEHTryStmtCursor = CXCursor_SEHTryStmt+ , SEHExceptStmtCursor = CXCursor_SEHExceptStmt+ , SEHFinallyStmtCursor = CXCursor_SEHFinallyStmt+ , MSAsmStmtCursor = CXCursor_MSAsmStmt+ , NullStmtCursor = CXCursor_NullStmt+ , DeclStmtCursor = CXCursor_DeclStmt+ , OMPParallelDirectiveCursor = CXCursor_OMPParallelDirective+ , TranslationUnitCursor = CXCursor_TranslationUnit+ , UnexposedAttrCursor = CXCursor_UnexposedAttr+ , IBActionAttrCursor = CXCursor_IBActionAttr+ , IBOutletAttrCursor = CXCursor_IBOutletAttr+ , IBOutletCollectionAttrCursor = CXCursor_IBOutletCollectionAttr+ , CXXFinalAttrCursor = CXCursor_CXXFinalAttr+ , CXXOverrideAttrCursor = CXCursor_CXXOverrideAttr+ , AnnotateAttrCursor = CXCursor_AnnotateAttr+ , AsmLabelAttrCursor = CXCursor_AsmLabelAttr+ , PackedAttrCursor = CXCursor_PackedAttr+ , PreprocessingDirectiveCursor = CXCursor_PreprocessingDirective+ , MacroDefinitionCursor = CXCursor_MacroDefinition+ , MacroExpansionCursor = CXCursor_MacroExpansion+ , InclusionDirectiveCursor = CXCursor_InclusionDirective+ , ModuleImportDeclCursor = CXCursor_ModuleImportDecl+ };+#endc+{#enum CursorKind{} deriving (Bounded, Eq, Ord, Read, Show, Typeable) #}++-- CursorKind ranges.+firstDeclCursor, lastDeclCursor, firstRefCursor, lastRefCursor :: CursorKind+firstInvalidCursor, lastInvalidCursor, firstExprCursor, lastExprCursor :: CursorKind+firstStmtCursor, lastStmtCursor, firstAttrCursor, lastAttrCursor :: CursorKind+firstPreprocessingCursor, lastPreprocessingCursor :: CursorKind+firstExtraDeclCursor, lastExtraDeclCursor :: CursorKind++firstDeclCursor = UnexposedDeclCursor+lastDeclCursor = CXXAccessSpecifierCursor+firstRefCursor = ObjCSuperClassRefCursor+lastRefCursor = VariableRefCursor+firstInvalidCursor = InvalidFileCursor+lastInvalidCursor = InvalidCodeCursor+firstExprCursor = UnexposedExprCursor+lastExprCursor = ObjCSelfExprCursor+firstStmtCursor = UnexposedStmtCursor+lastStmtCursor = OMPParallelDirectiveCursor+firstAttrCursor = UnexposedAttrCursor+lastAttrCursor = PackedAttrCursor+firstPreprocessingCursor = PreprocessingDirectiveCursor+lastPreprocessingCursor = InclusionDirectiveCursor+firstExtraDeclCursor = ModuleImportDeclCursor+lastExtraDeclCursor = ModuleImportDeclCursor++-- CursorKind aliases.+gccAsmStmtCursor, macroInstantiationCursor :: CursorKind+gccAsmStmtCursor = AsmStmtCursor+macroInstantiationCursor = MacroExpansionCursor++-- typedef struct {+-- const void *ASTNode;+-- CXTranslationUnit TranslationUnit;+-- } CXComment;+data Comment s = Comment !(Ptr ()) !(Ptr ())+ deriving (Eq, Ord, Typeable)++instance ClangValue Comment++instance Storable (Comment s) where+ sizeOf _ = sizeOfCXComment+ {-# INLINE sizeOf #-}++ alignment _ = alignOfCXComment+ {-# INLINE alignment #-}++ peek p = do+ astNode <- {#get CXComment->ASTNode #} p+ tu <- {#get CXComment->TranslationUnit #} p+ return $! Comment astNode tu+ {-# INLINE peek #-}++ poke p (Comment astNode tu)= do+ {#set CXComment->ASTNode #} p astNode+ {#set CXComment->TranslationUnit #} p tu+ {-# INLINE poke #-}++-- typedef struct {+-- enum CXCursorKind kind;+-- int xdata;+-- const void* data[3];+-- } CXCursor;+data Cursor s = Cursor !CursorKind !Int !(Ptr ()) !(Ptr ()) !(Ptr ())+ deriving (Ord, Typeable)++instance ClangValue Cursor++instance Storable (Cursor s) where+ sizeOf _ = sizeOfCXCursor+ {-# INLINE sizeOf #-}++ alignment _ = alignOfCXCursor+ {-# INLINE alignment #-}++ peek p = do+ cursorKind <- {#get CXCursor->kind #} p+ xdata <- {#get CXCursor->xdata #} p+ cursorData <- {#get CXCursor->data #} p >>= peekArray 3+ return $! Cursor (toEnum (fromIntegral cursorKind)) (fromIntegral xdata) (cursorData !! 0) (cursorData !! 1) (cursorData !! 2)+ {-# INLINE peek #-}++ poke p (Cursor kind xdata p0 p1 p2)= do+ ptrsArray <- mallocArray 3+ pokeArray ptrsArray [p0,p1,p2]+ {#set CXCursor->kind #} p (fromIntegral (fromEnum kind))+ {#set CXCursor->xdata #} p (fromIntegral xdata)+ {#set CXCursor->data #} p (castPtr ptrsArray)+ {-# INLINE poke #-}++instance Eq (Cursor s) where+ (Cursor aK aXdata aP1 aP2 aP3) == (Cursor bK bXdata bP1 bP2 bP3) =+ (aK == bK) &&+ (aXdata == bXdata) &&+ (aP1 == bP1) &&+ (aP2' == bP2') &&+ (aP3 == bP3)+ where+ aP2' = if isDeclaration aK then intPtrToPtr 0 else aP2+ bP2' = if isDeclaration bK then intPtrToPtr 0 else bP2+ {-# INLINE (==) #-}++instance Hashable (Cursor s) where+ hashWithSalt salt (Cursor k _ p1 p2 _) =+ let p = if isExpression k || isStatement k then p2 else p1+ kindHash = hashWithSalt salt (fromEnum k)+ pAsInt = fromIntegral (ptrToIntPtr p) :: Int+ in hashWithSalt kindHash pAsInt+ {-# INLINE hash #-}++-- CXCursor clang_getNullCursor(void);+getNullCursor :: ClangBase m => ClangT s m (Cursor s)+getNullCursor =+ return $ Cursor InvalidFileCursor 0 (intPtrToPtr 0) (intPtrToPtr 0) (intPtrToPtr 0)+{-# INLINE getNullCursor #-}++-- CXCursor clang_getTranslationUnitCursor(CXTranslationUnit);+{# fun wrapped_clang_getTranslationUnitCursor as clang_getTranslationUnitCursor { id `Ptr ()' } -> `Ptr (Cursor s)' castPtr #}+getTranslationUnitCursor :: Proxy s -> TranslationUnit s' -> IO (Cursor s)+getTranslationUnitCursor _ (TranslationUnit tPtr) = clang_getTranslationUnitCursor tPtr >>= peek++-- int clang_Cursor_isNull(CXCursor);+cursor_isNull :: Cursor s -> Bool+cursor_isNull (Cursor k xdata p1 p2 p3)+ | k == InvalidFileCursor &&+ xdata == 0 &&+ p1 == intPtrToPtr 0 &&+ p2 == intPtrToPtr 0 &&+ p3 == intPtrToPtr 0+ = True+ | otherwise+ = False+{-# INLINE cursor_isNull #-}++-- unsigned clang_hashCursor(CXCursor);+{# fun clang_hashCursor {withVoided* %`Cursor a' } -> `Word32' #}+hashCursor :: Cursor s -> IO Word32+hashCursor c = clang_hashCursor c+{-# INLINEABLE hashCursor #-}++getCursorKind :: Cursor s -> CursorKind+getCursorKind (Cursor k _ _ _ _) = k+{-# INLINE getCursorKind #-}++-- unsigned clang_isDeclaration(enum CursorKind);+isDeclaration :: CursorKind -> Bool+isDeclaration k =+ (k >= firstDeclCursor && k <= lastDeclCursor) ||+ (k >= firstExtraDeclCursor && k <= lastExtraDeclCursor)+{-# INLINE isDeclaration #-}++-- unsigned clang_isReference(enum CursorKind);+isReference :: CursorKind -> Bool+isReference k =+ (k >= firstRefCursor && k <= lastRefCursor)+{-# INLINE isReference #-}++-- unsigned clang_isExpression(enum CursorKind);+isExpression :: CursorKind -> Bool+isExpression k =+ (k >= firstExprCursor && k <= lastExprCursor)+{-# INLINE isExpression #-}++-- unsigned clang_isStatement(enum CursorKind);+isStatement :: CursorKind -> Bool+isStatement k =+ (k >= firstStmtCursor && k <= lastStmtCursor)+{-# INLINE isStatement #-}++isAttribute :: CursorKind -> Bool+isAttribute k =+ (k >= firstAttrCursor && k <= lastAttrCursor)+{-# INLINE isAttribute #-}++-- unsigned clang_isInvalid(enum CursorKind);+isInvalid :: CursorKind -> Bool+isInvalid k =+ (k >= firstInvalidCursor && k <= lastInvalidCursor)+{-# INLINE isInvalid #-}++-- unsigned clang_isTranslationUnit(enum CursorKind);+isTranslationUnit :: CursorKind -> Bool+isTranslationUnit TranslationUnitCursor = True+isTranslationUnit _ = False+{-# INLINE isTranslationUnit #-}++-- unsigned clang_isPreprocessing(enum CursorKind);+isPreprocessing :: CursorKind -> Bool+isPreprocessing k =+ (k >= firstPreprocessingCursor && k <= lastPreprocessingCursor)+{-# INLINE isPreprocessing #-}++-- unsigned clang_isUnexposed(enum CursorKind);+isUnexposed :: CursorKind -> Bool+isUnexposed k =+ (k >= firstPreprocessingCursor && k <= lastPreprocessingCursor)+{-# INLINE isUnexposed #-}++-- enum CXLinkageKind {+-- CXLinkage_Invalid,+-- CXLinkage_NoLinkage,+-- CXLinkage_Internal,+-- CXLinkage_UniqueExternal,+-- CXLinkage_External+-- };+#c+enum LinkageKind+ { Linkage_Invalid = CXLinkage_Invalid+ , Linkage_NoLinkage = CXLinkage_NoLinkage+ , Linkage_Internal = CXLinkage_Internal+ , Linkage_UniqueExternal = CXLinkage_UniqueExternal+ , Linkage_External = CXLinkage_External+ };+#endc+{#enum LinkageKind {} deriving (Bounded, Eq, Ord, Read, Show, Typeable) #}++-- enum CXLinkageKind clang_getCursorLinkage(CXCursor cursor);+{# fun clang_getCursorLinkage {withVoided* %`Cursor a' } -> `Int' #}+getCursorLinkage :: Cursor s -> IO LinkageKind+getCursorLinkage c = clang_getCursorLinkage c >>= return . toEnum++-- enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor);+{# fun clang_getCursorAvailability {withVoided* %`Cursor a' } -> `Int' #}+getCursorAvailability :: Cursor s -> IO AvailabilityKind+getCursorAvailability c = clang_getCursorAvailability c >>= return . toEnum++data PlatformAvailability = PlatformAvailability+ { availabilityPlatform :: !B.ByteString+ , availabilityIntroduced :: !Version+ , availabilityDeprecated :: !Version+ , availabilityObsoleted :: !Version+ , availabilityIsUnavailable :: !Bool+ , availabilityMessage :: !B.ByteString+ } deriving (Eq, Ord, Typeable)++instance Storable PlatformAvailability where+ sizeOf _ = sizeOfCXPlatformAvailability+ {-# INLINE sizeOf #-}++ alignment _ = alignOfCXPlatformAvailability+ {-# INLINE alignment #-}++ peek p = do+ (ClangString platD platF) <- peekByteOff p offsetCXPlatformAvailabilityPlatform+ platform <- B.packCString =<< getCStringPtr platD platF++ introduced <- peekByteOff p offsetCXPlatformAvailabilityIntroduced+ deprecated <- peekByteOff p offsetCXPlatformAvailabilityDeprecated+ obsoleted <- peekByteOff p offsetCXPlatformAvailabilityObsoleted+ intUnavailable :: Int <- fromCInt <$> peekByteOff p offsetCXPlatformAvailabilityUnavailable++ (ClangString msgD msgF) <- peekByteOff p offsetCXPlatformAvailabilityMessage+ message <- B.packCString =<< getCStringPtr msgD msgF++ return $! PlatformAvailability platform introduced deprecated obsoleted+ (if intUnavailable == 0 then False else True)+ message+ {-# INLINE peek #-}++ -- Since we can't construct ClangStrings, we can't really poke these.+ poke _ _ = undefined+ {-# INLINE poke #-}++-- void clang_disposeCXPlatformAvailability(CXPlatformAvailability);+{# fun clang_disposeCXPlatformAvailability { id `Ptr ()' } -> `()' #}+disposeCXPlatformAvailability :: Ptr PlatformAvailability -> IO ()+disposeCXPlatformAvailability p = clang_disposeCXPlatformAvailability (castPtr p)++-- int clang_getCursorPlatformAvailability(CXCursor cursor,+-- int *always_deprecated,+-- CXString *deprecated_message,+-- int *always_unavailable,+-- CXString *unavailable_message,+-- CXPlatformAvailability *availability,+-- int availability_size);+{# fun clang_getCursorPlatformAvailability {withVoided* %`Cursor a', alloca- `CInt' peek*, id `Ptr ()', alloca- `CInt' peek*, id `Ptr ()', id `Ptr ()', `Int' } -> `Int' #}+unsafe_getCursorPlatformAvailability :: Cursor s' -> Ptr PlatformAvailability -> Int -> IO (Bool, ClangString (), Bool, ClangString (), Int)+unsafe_getCursorPlatformAvailability c dest destLen =+ alloca (\(dMsgPtr :: (Ptr (ClangString ()))) ->+ alloca (\(uMsgPtr :: (Ptr (ClangString ()))) -> do+ (size, ad, au) <- clang_getCursorPlatformAvailability+ c+ (castPtr dMsgPtr)+ (castPtr uMsgPtr)+ (castPtr dest)+ destLen+ dm <- peek dMsgPtr+ um <- peek uMsgPtr+ return (toBool ad, dm, toBool au, um, size)))++data PlatformAvailabilityInfo s = PlatformAvailabilityInfo+ { availabilityAlwaysDeprecated :: !Bool+ , availabilityDeprecatedMessage :: !(ClangString s)+ , availabilityAlwaysUnavailable :: !Bool+ , availabilityUnavailableMessage :: !(ClangString s)+ , availabilityInfo :: ![PlatformAvailability]+ } deriving (Eq, Ord, Typeable)++instance ClangValue PlatformAvailabilityInfo++getCursorPlatformAvailability :: ClangBase m => Cursor s'+ -> ClangT s m (PlatformAvailabilityInfo s)+getCursorPlatformAvailability c = do+ (ad, dMsg, au, uMsg, infos) <-+ liftIO $ allocaArray maxPlatformAvailability $ \p -> do+ (ad, dMsg, au, uMsg, outSize) <-+ unsafe_getCursorPlatformAvailability c p maxPlatformAvailability+ let count = min outSize maxPlatformAvailability+ infos <- peekArray count p+ forM_ [0..(count - 1)] $ \idx -> do+ disposeCXPlatformAvailability (advancePtr p idx)+ return (ad, dMsg, au, uMsg, infos)+ dMsg' <- registerClangString $ return dMsg+ uMsg' <- registerClangString $ return uMsg+ return $ PlatformAvailabilityInfo ad dMsg' au uMsg' infos+ where+ maxPlatformAvailability = 32++-- enum CXLanguageKind {+-- CXLanguage_Invalid = 0,+-- CXLanguage_C,+-- CXLanguage_ObjC,+-- CXLanguage_CPlusPlus+-- };+#c+enum LanguageKind {+ Language_Invalid = CXLanguage_Invalid+ , Language_C = CXLanguage_C+ , Language_ObjC = CXLanguage_ObjC+ , Language_CPlusPlus = CXLanguage_CPlusPlus+ };+#endc++{#enum LanguageKind {} deriving (Bounded, Eq, Ord, Read, Show, Typeable) #}++-- enum CXLanguageKind clang_getCursorLanguage(CXCursor cursor);+{# fun clang_getCursorLanguage {withVoided* %`Cursor a' } -> `Int' #}+getCursorLanguage :: Cursor s -> IO LanguageKind+getCursorLanguage c = clang_getCursorLanguage c >>= return . toEnum++-- CXTranslationUnit clang_Cursor_getTranslationUnit(CXCursor);+{# fun clang_Cursor_getTranslationUnit {withVoided* %`Cursor a' } -> `Ptr ()' id #}+unsafe_Cursor_getTranslationUnit :: Cursor s -> IO (TranslationUnit ())+unsafe_Cursor_getTranslationUnit c =+ clang_Cursor_getTranslationUnit c >>= return . mkTranslationUnit++-- Note that we do not register the translation unit! This function+-- never creates a 'new' translation unit, so we don't need to dispose+-- it. Moreover, since translation units aren't reference counted doing+-- so will lead to crashes.+cursor_getTranslationUnit :: ClangBase m => Cursor s' -> ClangT s m (TranslationUnit s)+cursor_getTranslationUnit c = liftIO $ unsafeCoerce <$> unsafe_Cursor_getTranslationUnit c++-- typedef struct CXCursorSetImpl *CXCursorSet;+newtype CursorSet s = CursorSet { unCursorSet :: Ptr () }+ deriving (Eq, Ord, Typeable)++instance ClangValue CursorSet++-- void clang_disposeCXCursorSet(CXCursorSet cset);+{# fun clang_disposeCXCursorSet { id `Ptr ()' } -> `()' #}+disposeCXCursorSet :: CursorSet s -> IO ()+disposeCXCursorSet cs = clang_disposeCXCursorSet (unCursorSet cs)++registerCursorSet :: ClangBase m => IO (CursorSet ()) -> ClangT s m (CursorSet s)+registerCursorSet action = do+ (_, idx) <- clangAllocate (action >>= return . unsafeCoerce)+ (\i -> disposeCXCursorSet i)+ return idx+{-# INLINEABLE registerCursorSet #-}++-- CXCursorSet clang_createCXCursorSet();+{# fun clang_createCXCursorSet as clang_createCXCursorSet {} -> `Ptr ()' id #}+unsafe_createCXCursorSet :: IO (CursorSet ())+unsafe_createCXCursorSet = clang_createCXCursorSet >>= return . CursorSet++createCXCursorSet :: ClangBase m => ClangT s m (CursorSet s)+createCXCursorSet = registerCursorSet unsafe_createCXCursorSet++-- unsigned clang_CXCursorSet_contains(CXCursorSet cset, CXCursor cursor);+{# fun clang_CXCursorSet_contains {id `Ptr ()' ,withVoided* %`Cursor a' } -> `Bool' toBool #}+cXCursorSet_contains :: CursorSet s -> Cursor s' -> IO Bool+cXCursorSet_contains cs c =+ clang_CXCursorSet_contains (unCursorSet cs) c++-- unsigned clang_CXCursorSet_insert(CXCursorSet cset, CXCursor cursor);+{# fun clang_CXCursorSet_insert {id `Ptr ()', withVoided* %`Cursor a' } -> `Bool' toBool #}+cXCursorSet_insert :: CursorSet s -> Cursor s' -> IO Bool+cXCursorSet_insert cs c =+ clang_CXCursorSet_insert (unCursorSet cs) c++-- CXCursor clang_getCursorSemanticParent(CXCursor cursor);+{# fun wrapped_clang_getCursorSemanticParent as clang_getCursorSemanticParent {withVoided* %`Cursor a' } -> `Ptr (Cursor s)' castPtr #}+getCursorSemanticParent :: Proxy s -> Cursor s' -> IO (Cursor s)+getCursorSemanticParent _ c =+ clang_getCursorSemanticParent c >>= peek++-- CXCursor clang_getCursorLexicalParent(CXCursor cursor);+{# fun wrapped_clang_getCursorLexicalParent as clang_getCursorLexicalParent {withVoided* %`Cursor a' } -> `Ptr (Cursor s)' castPtr #}+getCursorLexicalParent :: Proxy s -> Cursor s' -> IO (Cursor s)+getCursorLexicalParent _ c =+ clang_getCursorLexicalParent c >>= peek++-- void clang_disposeOverriddenCursors(CXCursor *overridden);+{# fun clang_disposeOverriddenCursors { id `Ptr ()' } -> `()' #}+disposeOverridden :: CursorList s -> IO ()+disposeOverridden cl =+ let (csPtr, _) = fromCursorList cl in+ clang_disposeOverriddenCursors csPtr++registerOverriddenList :: ClangBase m => IO UnsafeCursorList -> ClangT s m (CursorList s)+registerOverriddenList action = do+ (_, cursorList) <- clangAllocate (action >>= cursorListToVector) disposeOverridden+ return cursorList+{-# INLINEABLE registerOverriddenList #-}++-- void clang_getOverriddenCursors(CXCursor cursor, CXCursor **overridden, unsigned *num_overridden);+{# fun clang_getOverriddenCursors {withVoided* %`Cursor a', id `Ptr (Ptr ())', alloca- `CUInt' peek* } -> `()' #}+unsafe_getOverriddenCursors :: Cursor s -> IO UnsafeCursorList+unsafe_getOverriddenCursors c = do+ cxListPtr <- mallocBytes (sizeOf (undefined :: (Ptr (Ptr (Cursor s)))))+ n <- clang_getOverriddenCursors c (castPtr cxListPtr)+ free cxListPtr+ return (toCursorList (cxListPtr, (fromIntegral n)))++getOverriddenCursors :: ClangBase m => Cursor s' -> ClangT s m (CursorList s)+getOverriddenCursors = registerOverriddenList . unsafe_getOverriddenCursors++-- CXFile clang_getIncludedFile(CXCursor cursor);+{# fun clang_getIncludedFile {withVoided* %`Cursor a' } -> `Ptr ()' id #}+getIncludedFile :: Proxy s -> Cursor s' -> IO (Maybe (File s))+getIncludedFile _ c =+ clang_getIncludedFile c >>= return . maybeFile . File . castPtr++-- CXCursor clang_getCursor(CXTranslationUnit, CXSourceLocation);+{# fun wrapped_clang_getCursor as clang_getCursor { id `Ptr ()' , withVoided* `SourceLocation a' } -> `Ptr (Cursor s)' castPtr #}+getCursor :: Proxy s -> TranslationUnit s' -> SourceLocation s'' -> IO (Cursor s)+getCursor _ t s = clang_getCursor (unTranslationUnit t) s >>= peek++-- CXSourceLocation clang_getCursorLocation(CXCursor);+{# fun wrapped_clang_getCursorLocation as clang_getCursorLocation {withVoided* %`Cursor a' } -> `Ptr (SourceLocation s)' castPtr #}+getCursorLocation :: Proxy s -> Cursor s' -> IO (SourceLocation s)+getCursorLocation _ c =+ clang_getCursorLocation c>>= peek+{-# INLINEABLE getCursorLocation #-}++-- Variant of clang_getCursorLocation that fuses a call to clang_getSpellingLocation.+getCursorSpellingLocation :: Proxy s -> Cursor s' -> IO (Maybe (File s), Int, Int, Int)+getCursorSpellingLocation _ c =+ allocaBytes {#sizeof PtrPtrCXFile #} (\ptrToFilePtr ->+ alloca (\(linePtr :: (Ptr CUInt)) ->+ alloca (\(columnPtr :: (Ptr CUInt)) ->+ alloca (\(offsetPtr :: (Ptr CUInt)) -> do+ slPtr <- clang_getCursorLocation c+ peek slPtr >>= \sl -> clang_getSpellingLocation sl ptrToFilePtr linePtr columnPtr offsetPtr+ filePtr <- {#get *CXFile #} ptrToFilePtr+ let _maybeFile = maybeFile (File filePtr)+ line <- peek linePtr+ column <- peek columnPtr+ offset <- peek offsetPtr+ return (_maybeFile, fromIntegral line, fromIntegral column, fromIntegral offset)))))+{-# INLINEABLE getCursorSpellingLocation #-}++-- CXSourceRange clang_getCursorExtent(CXCursor);+{# fun wrapped_clang_getCursorExtent as clang_getCursorExtent {withVoided* %`Cursor a' } -> `Ptr (SourceRange s)' castPtr #}+getCursorExtent :: Proxy s -> Cursor s' -> IO (SourceRange s)+getCursorExtent _ c =+ clang_getCursorExtent c >>= peek+{-# INLINEABLE getCursorExtent #-}++-- enum CXTypeKind {+-- CXType_Invalid = 0,+-- CXType_Unexposed = 1,+-- CXType_Void = 2,+-- CXType_Bool = 3,+-- CXType_Char_U = 4,+-- CXType_UChar = 5,+-- CXType_Char16 = 6,+-- CXType_Char32 = 7,+-- CXType_UShort = 8,+-- CXType_UInt = 9,+-- CXType_ULong = 10,+-- CXType_ULongLong = 11,+-- CXType_UInt128 = 12,+-- CXType_Char_S = 13,+-- CXType_SChar = 14,+-- CXType_WChar = 15,+-- CXType_Short = 16,+-- CXType_Int = 17,+-- CXType_Long = 18,+-- CXType_LongLong = 19,+-- CXType_Int128 = 20,+-- CXType_Float = 21,+-- CXType_Double = 22,+-- CXType_LongDouble = 23,+-- CXType_NullPtr = 24,+-- CXType_Overload = 25,+-- CXType_Dependent = 26,+-- CXType_ObjCId = 27,+-- CXType_ObjCClass = 28,+-- CXType_ObjCSel = 29,+-- CXType_FirstBuiltin = CXType_Void,+-- CXType_LastBuiltin = CXType_ObjCSel,+-- CXType_Complex = 100,+-- CXType_Pointer = 101,+-- CXType_BlockPointer = 102,+-- CXType_LValueReference = 103,+-- CXType_RValueReference = 104,+-- CXType_Record = 105,+-- CXType_Enum = 106,+-- CXType_Typedef = 107,+-- CXType_ObjCInterface = 108,+-- CXType_ObjCObjectPointer = 109,+-- CXType_FunctionNoProto = 110,+-- CXType_FunctionProto = 111+-- CXType_ConstantArray = 112+-- CXType_Vector = 113,+-- CXType_IncompleteArray = 114,+-- CXType_VariableArray = 115,+-- CXType_DependentSizedArray = 116,+-- CXType_MemberPointer = 117+-- };++#c+enum TypeKind+ { Type_Invalid = CXType_Invalid+ , Type_Unexposed = CXType_Unexposed+ , Type_Void = CXType_Void+ , Type_Bool = CXType_Bool+ , Type_Char_U = CXType_Char_U+ , Type_UChar = CXType_UChar+ , Type_Char16 = CXType_Char16+ , Type_Char32 = CXType_Char32+ , Type_UShort = CXType_UShort+ , Type_UInt = CXType_UInt+ , Type_ULong = CXType_ULong+ , Type_ULongLong = CXType_ULongLong+ , Type_UInt128 = CXType_UInt128+ , Type_Char_S = CXType_Char_S+ , Type_SChar = CXType_SChar+ , Type_WChar = CXType_WChar+ , Type_Short = CXType_Short+ , Type_Int = CXType_Int+ , Type_Long = CXType_Long+ , Type_LongLong = CXType_LongLong+ , Type_Int128 = CXType_Int128+ , Type_Float = CXType_Float+ , Type_Double = CXType_Double+ , Type_LongDouble = CXType_LongDouble+ , Type_NullPtr = CXType_NullPtr+ , Type_Overload = CXType_Overload+ , Type_Dependent = CXType_Dependent+ , Type_ObjCId = CXType_ObjCId+ , Type_ObjCClass = CXType_ObjCClass+ , Type_ObjCSel = CXType_ObjCSel+ , Type_Complex = CXType_Complex+ , Type_Pointer = CXType_Pointer+ , Type_BlockPointer = CXType_BlockPointer+ , Type_LValueReference = CXType_LValueReference+ , Type_RValueReference = CXType_RValueReference+ , Type_Record = CXType_Record+ , Type_Enum = CXType_Enum+ , Type_Typedef = CXType_Typedef+ , Type_ObjCInterface = CXType_ObjCInterface+ , Type_ObjCObjectPointer = CXType_ObjCObjectPointer+ , Type_FunctionNoProto = CXType_FunctionNoProto+ , Type_FunctionProto = CXType_FunctionProto+ , Type_ConstantArray = CXType_ConstantArray+ , Type_Vector = CXType_Vector+ , Type_IncompleteArray = CXType_IncompleteArray+ , Type_VariableArray = CXType_VariableArray+ , Type_DependentSizedArray = CXType_DependentSizedArray+ , Type_MemberPointer = CXType_MemberPointer+ };+#endc+{# enum TypeKind {} deriving (Bounded, Eq, Ord, Read, Show, Typeable) #}++type_FirstBuiltin, type_LastBuiltin :: TypeKind+type_FirstBuiltin = Type_Void+type_LastBuiltin = Type_ObjCSel++-- enum CXCallingConv {+-- CXCallingConv_Default = 0,+-- CXCallingConv_C = 1,+-- CXCallingConv_X86StdCall = 2,+-- CXCallingConv_X86FastCall = 3,+-- CXCallingConv_X86ThisCall = 4,+-- CXCallingConv_X86Pascal = 5,+-- CXCallingConv_AAPCS = 6,+-- CXCallingConv_AAPCS_VFP = 7,+-- CXCallingConv_IntelOclBicc = 9,+-- CXCallingConv_X86_64Win64 = 10,+-- CXCallingConv_X86_64SysV = 11,+-- CXCallingConv_Invalid = 100,+-- CXCallingConv_Unexposed = 200+-- };+#c+enum CallingConv+ { CallingConv_Default = CXCallingConv_Default+ , CallingConv_C = CXCallingConv_C+ , CallingConv_X86StdCall = CXCallingConv_X86StdCall+ , CallingConv_X86FastCall = CXCallingConv_X86FastCall+ , CallingConv_X86ThisCall = CXCallingConv_X86ThisCall+ , CallingConv_X86Pascal = CXCallingConv_X86Pascal+ , CallingConv_AAPCS = CXCallingConv_AAPCS+ , CallingConv_AAPCS_VFP = CXCallingConv_AAPCS_VFP+ , CallingConv_IntelOclBic = CXCallingConv_IntelOclBicc+ , CallingConv_X86_64Win64 = CXCallingConv_X86_64Win64+ , CallingConv_X86_64SysV = CXCallingConv_X86_64SysV+ , CallingConv_Invalid = CXCallingConv_Invalid+ , CallingConv_Unexposed = CXCallingConv_Unexposed+ };+#endc+{# enum CallingConv {} deriving (Bounded, Eq, Ord, Read, Show, Typeable) #}++-- typedef struct {+-- enum CXTypeKind kind;+-- void *data[2];+-- } CXType;+data Type s = Type !TypeKind !(Ptr ()) !(Ptr ())+ deriving (Eq, Ord, Typeable)++instance ClangValue Type++instance Storable (Type s) where+ sizeOf _ = {#sizeof CXType #}+ {-# INLINE sizeOf #-}++ alignment _ = {#alignof CXType #}+ {-# INLINE alignment #-}++ peek p = do+ kindCInt <- {#get CXType->kind #} p+ ptrsArray <- {#get CXType->data #} p >>= peekArray 2+ return $! Type (toEnum (fromIntegral kindCInt)) (ptrsArray !! 0) (ptrsArray !! 1)+ {-# INLINE peek #-}++ poke p (Type kind p0 p1)= do+ ptrsArray <- mallocArray 2+ pokeArray ptrsArray [p0,p1]+ {#set CXType->kind #} p (fromIntegral (fromEnum kind))+ {#set CXType->data #} p (castPtr ptrsArray)+ {-# INLINE poke #-}++getTypeKind :: Type s -> TypeKind+getTypeKind (Type k _ _) = k++-- CXType clang_getCursorType(CXCursor C);+{# fun wrapped_clang_getCursorType as clang_getCursorType {withVoided* %`Cursor a' } -> `Ptr (Type s)' castPtr #}+getCursorType :: Proxy s -> Cursor s' -> IO (Type s)+getCursorType proxy c =+ clang_getCursorType c >>= peek++-- CXString clang_getTypeSpelling(CXType CT);+{# fun wrapped_clang_getTypeSpelling as clang_getTypeSpelling {withVoided* %`Type a' } -> `Ptr (ClangString ())' castPtr #}+unsafe_getTypeSpelling :: (Type s) -> IO (ClangString ())+unsafe_getTypeSpelling t = do+ cxString <- clang_getTypeSpelling t+ peek cxString++getTypeSpelling :: ClangBase m => (Type s') -> ClangT s m (ClangString s)+getTypeSpelling = registerClangString . unsafe_getTypeSpelling++-- CXType clang_getTypedefDeclUnderlyingType(CXCursor C);+{# fun wrapped_clang_getTypedefDeclUnderlyingType as clang_getTypedefDeclUnderlyingType {withVoided* %`Cursor a' } -> `Ptr (Type s)' castPtr #}+getTypedefDeclUnderlyingType :: Proxy s -> Cursor s' -> IO (Type s)+getTypedefDeclUnderlyingType proxy c =+ clang_getTypedefDeclUnderlyingType c >>= peek++-- CXType clang_getEnumDeclIntegerType(CXCursor C);+{# fun wrapped_clang_getEnumDeclIntegerType as clang_getEnumDeclIntegerType {withVoided* %`Cursor a' } -> `Ptr (Type s)' castPtr #}+getEnumDeclIntegerType :: Proxy s -> Cursor s' -> IO (Type s)+getEnumDeclIntegerType proxy c =+ clang_getEnumDeclIntegerType c >>= peek++-- long long clang_getEnumConstantDeclValue(CXCursor);+{# fun clang_getEnumConstantDeclValue {withVoided* %`Cursor a' } -> `Int64' #}+getEnumConstantDeclValue :: Cursor s -> IO Int64+getEnumConstantDeclValue c = clang_getEnumConstantDeclValue c++-- unsigned long long clang_getEnumConstantDeclUnsignedValue(CXCursor);+{# fun clang_getEnumConstantDeclUnsignedValue {withVoided* %`Cursor a' } -> `Word64' #}+getEnumConstantDeclUnsignedValue :: Cursor s -> IO Word64+getEnumConstantDeclUnsignedValue c = clang_getEnumConstantDeclUnsignedValue c++-- int clang_getFieldDeclBitWidth(CXCursor C);+-- %fun clang_getFieldDeclBitWidth :: Cursor s -> IO Int+{# fun clang_getFieldDeclBitWidth {withVoided* %`Cursor a' } -> `Int' #}+getFieldDeclBitWidth :: Cursor s -> IO Int+getFieldDeclBitWidth c = clang_getFieldDeclBitWidth c++-- int clang_Cursor_getNumArguments(CXCursor C);+{# fun clang_Cursor_getNumArguments {withVoided* %`Cursor a' } -> `Int' #}+cursor_getNumArguments :: Cursor s -> IO Int+cursor_getNumArguments c = clang_Cursor_getNumArguments c++-- CXCursor clang_Cursor_getArgument(CXCursor C, unsigned i);+{# fun wrapped_clang_Cursor_getArgument as clang_Cursor_getArgument {withVoided* %`Cursor a', `Int' } -> `Ptr (Cursor s)' castPtr #}+cursor_getArgument :: Proxy s -> Cursor s' -> Int -> IO (Cursor s)+cursor_getArgument _ c i = clang_Cursor_getArgument c i >>= peek++-- unsigned clang_equalTypes(CXType A, CXType B);+{# fun clang_equalTypes {withVoided* %`Type a',withVoided* %`Type b' } -> `Bool' toBool #}+equalTypes :: Type s -> Type s' -> IO Bool+equalTypes t1 t2 = clang_equalTypes t1 t2++-- CXType clang_getCanonicalType(CXType T);+{# fun wrapped_clang_getCanonicalType as clang_getCanonicalType {withVoided* %`Type a' } -> `Ptr (Type s)' castPtr #}+getCanonicalType :: Proxy s -> Type s' -> IO (Type s)+getCanonicalType proxy t = do+ cPtr <- clang_getCanonicalType t+ peek cPtr++-- unsigned clang_isConstQualifiedType(CXType T);+{# fun clang_isConstQualifiedType {withVoided* %`Type a' } -> `Bool' toBool #}+isConstQualifiedType :: Type s -> IO Bool+isConstQualifiedType t = clang_isConstQualifiedType t++-- unsigned clang_isVolatileQualifiedType(CXType T);+{# fun clang_isVolatileQualifiedType {withVoided* %`Type a' } -> `Bool' toBool #}+isVolatileQualifiedType :: Type s -> IO Bool+isVolatileQualifiedType t = clang_isVolatileQualifiedType t++-- unsigned clang_isRestrictQualifiedType(CXType T);+{# fun clang_isRestrictQualifiedType {withVoided* %`Type a' } -> `Bool' toBool #}+isRestrictQualifiedType :: Type s -> IO Bool+isRestrictQualifiedType t = clang_isRestrictQualifiedType t++-- CXType clang_getPointeeType(CXType T);+{# fun wrapped_clang_getPointeeType as clang_getPointeeType { withVoided* %`Type a' } -> `Ptr (Type s)' castPtr #}+getPointeeType :: Proxy s -> Type s' -> IO (Type s)+getPointeeType proxy t = do+ cPtr <- clang_getPointeeType t+ peek cPtr++-- CXCursor clang_getTypeDeclaration(CXType T);+{# fun wrapped_clang_getTypeDeclaration as clang_getTypeDeclaration { withVoided* %`Type a' } -> `Ptr (Cursor s)' castPtr #}+getTypeDeclaration :: Proxy s -> Type s' -> IO (Cursor s)+getTypeDeclaration _ t = do+ cPtr <- clang_getTypeDeclaration t+ peek cPtr++-- CXString clang_getDeclObjCTypeEncoding(CXCursor C);+{# fun wrapped_clang_getDeclObjCTypeEncoding as clang_getDeclObjCTypeEncoding {withVoided* %`Cursor a' } -> `Ptr (ClangString ())' castPtr #}+unsafe_getDeclObjCTypeEncoding :: Cursor s -> IO (ClangString ())+unsafe_getDeclObjCTypeEncoding c = clang_getDeclObjCTypeEncoding c >>= peek++getDeclObjCTypeEncoding :: ClangBase m => Cursor s' -> ClangT s m (ClangString s)+getDeclObjCTypeEncoding = registerClangString . unsafe_getDeclObjCTypeEncoding++-- CXString clang_getTypeKindSpelling(enum CXTypeKind K);+{# fun wrapped_clang_getTypeKindSpelling as clang_getTypeKindSpelling { `CInt' } -> `Ptr (ClangString ())' castPtr #}+unsafe_getTypeKindSpelling :: TypeKind -> IO (ClangString ())+unsafe_getTypeKindSpelling tk = clang_getTypeKindSpelling (fromIntegral (fromEnum tk)) >>= peek++getTypeKindSpelling :: ClangBase m => TypeKind -> ClangT s m (ClangString s)+getTypeKindSpelling = registerClangString . unsafe_getTypeKindSpelling++-- enum CXCallingConv clang_getFunctionTypeCallingConv(CXType T);+{# fun clang_getFunctionTypeCallingConv { withVoided* %`Type a' } -> `CInt' id #}+getFunctionTypeCallingConv :: Type s' -> IO CallingConv+getFunctionTypeCallingConv t = clang_getFunctionTypeCallingConv t >>= return . toEnum . fromIntegral++-- CXType clang_getResultType(CXType T);+{# fun wrapped_clang_getResultType as clang_getResultType { withVoided* %`Type a' } -> `Ptr (Type s)' castPtr #}+getResultType :: Proxy s -> Type s' -> IO (Type s)+getResultType proxy t = clang_getResultType t >>= peek++-- CXType clang_getNumArgTypes(CXType T);+{# fun clang_getNumArgTypes { withVoided* %`Type a' } -> `Int' #}+getNumArgTypes :: Type s -> IO Int+getNumArgTypes t = clang_getNumArgTypes t++-- CXType clang_getArgType(CXType T, int i);+{# fun wrapped_clang_getArgType as clang_getArgType { withVoided* %`Type a', `Int' } -> `Ptr (Type s)' castPtr #}+getArgType :: Proxy s -> Type s' -> Int -> IO (Type s)+getArgType proxy t i = clang_getArgType t i >>= peek++-- unsigned clang_isFunctionTypeVariadic(CXType T);+{# fun clang_isFunctionTypeVariadic { withVoided* %`Type a' } -> `CUInt' id #}+isFunctionTypeVariadic :: Type s -> IO Bool+isFunctionTypeVariadic t = clang_isFunctionTypeVariadic t >>= return . (toBool :: Int -> Bool) . fromIntegral++-- CXType clang_getCursorResultType(CXCursor C);+{# fun wrapped_clang_getCursorResultType as clang_getCursorResultType {withVoided* %`Cursor a' } -> `Ptr (Type s)' castPtr #}+getCursorResultType :: Proxy s -> Cursor s' -> IO (Type s)+getCursorResultType p c = clang_getCursorResultType c >>= peek++-- unsigned clang_isPODType(CXType T);+{# fun clang_isPODType {withVoided* %`Type a' } -> `Bool' toBool #}+isPODType :: Type s -> IO Bool+isPODType t = clang_isPODType t++-- CXType clang_getElementType(CXType T);+{# fun wrapped_clang_getElementType as clang_getElementType { withVoided* %`Type a' } -> `Ptr (Type s)' castPtr #}+getElementType :: Proxy s -> Type s' -> IO (Type s)+getElementType proxy t = clang_getElementType t >>= peek++-- long long clang_getNumElements(CXType T);+{# fun clang_getNumElements { withVoided* %`Type a' } -> `Int64' #}+getNumElements :: Type s -> IO Int64+getNumElements t = clang_getNumElements t++-- CXType clang_getArrayElementType(CXType T);+{# fun wrapped_clang_getArrayElementType as clang_getArrayElementType { withVoided* %`Type a' } -> `Ptr (Type s)' castPtr #}+getArrayElementType :: Proxy s -> Type s' -> IO (Type s)+getArrayElementType proxy t = clang_getArrayElementType t >>= peek++-- long long clang_getArraySize(CXType T);+{# fun clang_getArraySize { withVoided* %`Type a' } -> `Int64' #}+getArraySize :: Type s -> IO Int64+getArraySize t = clang_getArraySize t++-- enum CXTypeLayoutError {+-- CXTypeLayoutError_Invalid = -1,+-- CXTypeLayoutError_Incomplete = -2,+-- CXTypeLayoutError_Dependent = -3,+-- CXTypeLayoutError_NotConstantSize = -4,+-- CXTypeLayoutError_InvalidFieldName = -5+-- };+#c+enum TypeLayoutError+ { TypeLayoutError_Invalid = CXTypeLayoutError_Invalid+ , TypeLayoutError_Incomplete = CXTypeLayoutError_Incomplete+ , TypeLayoutError_Dependent = CXTypeLayoutError_Dependent+ , TypeLayoutError_NotConstantSize = CXTypeLayoutError_NotConstantSize+ , TypeLayoutError_InvalidFieldName = CXTypeLayoutError_InvalidFieldName+ };+#endc+{# enum TypeLayoutError {} deriving (Bounded, Eq, Ord, Read, Show, Typeable) #}++int64OrLayoutError :: Int64 -> Either TypeLayoutError Int64+int64OrLayoutError v | v == -1 = Left TypeLayoutError_Invalid+ | v == -2 = Left TypeLayoutError_Incomplete+ | v == -3 = Left TypeLayoutError_Dependent+ | v == -4 = Left TypeLayoutError_NotConstantSize+ | v == -5 = Left TypeLayoutError_InvalidFieldName+ | otherwise = Right v++-- long long clang_Type_getAlignOf(CXType T);+{# fun clang_Type_getAlignOf { withVoided* %`Type a' } -> `Int64' #}+type_getAlignOf :: Type s -> IO (Either TypeLayoutError Int64)+type_getAlignOf t = clang_Type_getAlignOf t >>= return . int64OrLayoutError++-- CXType clang_Type_getClassType(CXType T);+{# fun wrapped_clang_Type_getClassType as clang_Type_getClassType { withVoided* %`Type a' } -> `Ptr (Type s)' castPtr #}+type_getClassType :: Proxy s -> Type s' -> IO (Type s)+type_getClassType proxy t = clang_getElementType t >>= peek++-- long long clang_Type_getSizeOf(CXType T);+{# fun clang_Type_getSizeOf { withVoided* %`Type a' } -> `Int64' #}+type_getSizeOf :: Type s -> IO (Either TypeLayoutError Int64)+type_getSizeOf t = clang_Type_getSizeOf t >>= return . int64OrLayoutError++-- long long clang_Type_getOffsetOf(CXType T, const char *S);+{# fun clang_Type_getOffsetOf { withVoided* %`Type a' , `CString' } -> `Int64' #}+unsafe_Type_getOffsetOf :: Type s -> CString -> IO (Either TypeLayoutError Int64)+unsafe_Type_getOffsetOf t s = clang_Type_getOffsetOf t s >>= return . int64OrLayoutError++type_getOffsetOf :: ClangBase m => Type s' -> B.ByteString+ -> ClangT s m (Either TypeLayoutError Int64)+type_getOffsetOf t field = liftIO $ B.useAsCString field $ \cField ->+ unsafe_Type_getOffsetOf t cField++-- enum CXRefQualifierKind {+-- CXRefQualifier_None = 0,+-- CXRefQualifier_LValue,+-- CXRefQualifier_RValue+-- };+#c+enum RefQualifierKind+ { RefQualifier_None = CXRefQualifier_None+ , RefQualifier_LValue = CXRefQualifier_LValue+ , RefQualifier_RValue = CXRefQualifier_RValue+ };+#endc+{# enum RefQualifierKind {} deriving (Bounded, Eq, Ord, Read, Show, Typeable) #}++-- enum CXRefQualifierKind clang_Type_getCXXRefQualifier(CXType T);+{# fun clang_Type_getCXXRefQualifier { withVoided* %`Type a' } -> `Int' #}+type_getCXXRefQualifier :: Type s -> IO RefQualifierKind+type_getCXXRefQualifier t = clang_Type_getCXXRefQualifier t >>= return . toEnum+++-- unsigned clang_Cursor_isBitField(CXCursor C);+{# fun clang_Cursor_isBitField {withVoided* %`Cursor a' } -> `Bool' toBool #}+isBitField :: Cursor s -> IO Bool+isBitField c = clang_Cursor_isBitField c++-- unsigned clang_isVirtualBase(CXCursor);+{# fun clang_isVirtualBase {withVoided* %`Cursor a' } -> `Bool' toBool #}+isVirtualBase :: Cursor s -> IO Bool+isVirtualBase c = clang_Cursor_isBitField c++-- enum CX_CXXAccessSpecifier {+-- CX_CXXInvalidAccessSpecifier,+-- CX_CXXPublic,+-- CX_CXXProtected,+-- CX_CXXPrivate+-- };+#c+enum CXXAccessSpecifier+ { CXXInvalidAccessSpecifier = CX_CXXInvalidAccessSpecifier+ , CXXPublic = CX_CXXPublic+ , CXXProtected = CX_CXXProtected+ , CXXPrivate = CX_CXXPrivate+ };+#endc++{# enum CXXAccessSpecifier {} deriving (Bounded, Eq, Ord, Read, Show, Typeable) #}++-- enum CX_CXXAccessSpecifier clang_getCXXAccessSpecifier(CXCursor);+{# fun clang_getCXXAccessSpecifier {withVoided* %`Cursor a' } -> `Int' #}+getCXXAccessSpecifier :: Cursor s -> IO CXXAccessSpecifier+getCXXAccessSpecifier c = clang_getCXXAccessSpecifier c >>= return . toEnum++-- unsigned clang_getNumOverloadedDecls(CXCursor cursor);+{# fun clang_getNumOverloadedDecls {withVoided* %`Cursor a' } -> `CUInt' #}+getNumOverloadedDecls :: Cursor s -> IO Int+getNumOverloadedDecls c = clang_getNumOverloadedDecls c >>= return . fromIntegral++-- CXCursor clang_getOverloadedDecl(CXCursor cursor,+-- unsigned index);+{# fun wrapped_clang_getOverloadedDecl as clang_getOverloadedDecl {withVoided* %`Cursor a', `Int' } -> `Ptr (Cursor s)' castPtr #}+getOverloadedDecl :: Proxy s -> Cursor s' -> Int -> IO (Cursor s)+getOverloadedDecl _ c i = clang_getOverloadedDecl c i >>= peek++-- CXType clang_getIBOutletCollectionType(CXCursor);+{# fun wrapped_clang_getIBOutletCollectionType as clang_getIBOutletCollectionType {withVoided* %`Cursor a' } -> `Ptr (Type s)' castPtr #}+getIBOutletCollectionType :: Proxy s -> Cursor s' -> IO (Type s)+getIBOutletCollectionType proxy c = clang_getIBOutletCollectionType c >>= peek+++-- We deliberately don't export the constructor for UnsafeCursorList.+-- The only way to unwrap it is registerCursorList.+type CursorList s = DVS.Vector (Cursor s)+instance ClangValueList Cursor+data UnsafeCursorList = UnsafeCursorList !(Ptr ()) !Int++-- void freeCursorList(CXCursor* cursors);+{# fun freeCursorList as freeCursorList' { id `Ptr ()' } -> `()' #}+freeCursorList :: CursorList s -> IO ()+freeCursorList cl = let (ptr, _) = fromCursorList cl in freeCursorList' ptr++registerCursorList :: ClangBase m => IO UnsafeCursorList -> ClangT s m (CursorList s)+registerCursorList action = do+ (_, cursorList) <- clangAllocate (action >>= cursorListToVector) freeCursorList+ return cursorList+{-# INLINEABLE registerCursorList #-}++cursorListToVector :: Storable a => UnsafeCursorList -> IO (DVS.Vector a)+cursorListToVector (UnsafeCursorList cs n) = do+ fptr <- newForeignPtr_ (castPtr cs)+ return $ DVS.unsafeFromForeignPtr fptr 0 n+{-# INLINE cursorListToVector #-}++fromCursorList :: CursorList s -> (Ptr (), Int)+fromCursorList cs = let (p, _, _) = DVS.unsafeToForeignPtr cs in+ (castPtr $ Foreign.ForeignPtr.Unsafe.unsafeForeignPtrToPtr p, DVS.length cs)++toCursorList :: (Ptr (), Int) -> UnsafeCursorList+toCursorList (cs, n) = UnsafeCursorList cs n++-- A more efficient alternative to clang_visitChildren.+-- void getChildren(CXCursor parent, CXCursor** childrenOut, unsigned* countOut)+{# fun getChildren as getChildren' {withVoided* %`Cursor a', id `Ptr (Ptr ())', alloca- `CUInt' peek* } -> `()' #}+unsafe_getChildren :: Cursor s -> IO UnsafeCursorList+unsafe_getChildren c =+ do+ cxListPtr <- mallocBytes (sizeOf (undefined :: (Ptr (Ptr ()))))+ n <- getChildren' c cxListPtr+ cxList <- peek cxListPtr+ free cxListPtr+ return (toCursorList (cxList, fromIntegral n))++getChildren :: ClangBase m => Cursor s' -> ClangT s m (CursorList s)+getChildren = registerCursorList . unsafe_getChildren++-- Like getChildren, but gets all transitive descendants.+-- void getDescendants(CXCursor parent, CXCursor** childrenOut, unsigned* countOut)+{# fun getDescendants as getDescendants' {withVoided* %`Cursor a', id `Ptr (Ptr ())', alloca- `CUInt' peek* } -> `()' #}+unsafe_getDescendants :: Cursor s -> IO UnsafeCursorList+unsafe_getDescendants c =+ do+ cxListPtr <- mallocBytes (sizeOf (undefined :: (Ptr (Cursor s))))+ n <- getDescendants' c cxListPtr+ cxList <- peek cxListPtr+ free cxListPtr+ return (toCursorList (cxList, fromIntegral n))++getDescendants :: ClangBase m => Cursor s' -> ClangT s m (CursorList s)+getDescendants = registerCursorList . unsafe_getDescendants++-- void getDeclarations(CXTranslationUnit tu, CXCursor** declsOut, unsigned* declCountOut);+{# fun getDeclarations as getDeclarations' { id `Ptr ()', id `Ptr (Ptr ())', alloca- `CUInt' peek* } -> `()' #}+unsafe_getDeclarations :: TranslationUnit s -> IO UnsafeCursorList+unsafe_getDeclarations t = do+ cxListPtr <- mallocBytes (sizeOf (undefined :: (Ptr (Ptr (Cursor ())))))+ n <- getDeclarations' (unTranslationUnit t) cxListPtr+ cxList <- peek cxListPtr+ free cxListPtr+ return (toCursorList (cxList, fromIntegral n))++getDeclarations :: ClangBase m => TranslationUnit s' -> ClangT s m (CursorList s)+getDeclarations = registerCursorList . unsafe_getDeclarations++-- void getReferences(CXTranslationUnit tu, CXCursor** declsOut, unsigned* declCountOut);+{# fun getReferences as getReferences' { id `Ptr ()', id `Ptr (Ptr ())', alloca- `CUInt' peek* } -> `()' #}+unsafe_getReferences :: TranslationUnit s -> IO UnsafeCursorList+unsafe_getReferences t = do+ cxListPtr <- mallocBytes (sizeOf (undefined :: (Ptr (Ptr ()))))+ n <- getReferences' (unTranslationUnit t) cxListPtr+ cxList <- peek cxListPtr+ free cxListPtr+ return (toCursorList (cxList, fromIntegral n))++getReferences :: ClangBase m => TranslationUnit s' -> ClangT s m (CursorList s)+getReferences = registerCursorList . unsafe_getReferences++-- void getDeclarationsAndReferences(CXTranslationUnit tu,+-- CXCursor** declsOut, unsigned* declCountOut,+-- CXCursor** refsOut, unsigned* refCountOut);+{# fun getDeclarationsAndReferences as getDeclarationsAndReferences'+ { id `Ptr ()', id `Ptr (Ptr ())', alloca- `CUInt' peek*, id `Ptr (Ptr ())' , alloca- `CUInt' peek* } -> `()' #}+unsafe_getDeclarationsAndReferences :: TranslationUnit s -> IO (UnsafeCursorList, UnsafeCursorList)+unsafe_getDeclarationsAndReferences t =+ alloca (\(declsPtr :: Ptr (Ptr ())) ->+ alloca (\(refsPtr :: Ptr (Ptr ())) -> do+ (nDecls, nRefs) <- getDeclarationsAndReferences' (unTranslationUnit t) (castPtr declsPtr) (castPtr refsPtr)+ decls <- peek declsPtr+ refs <- peek refsPtr+ return ((toCursorList (decls, fromIntegral nDecls)), (toCursorList (refs, fromIntegral nRefs)))))++-- %fun unsafe_getDeclarationsAndReferences :: TranslationUnit s -> IO (UnsafeCursorList, UnsafeCursorList)+-- %call (translationUnit t)+-- %code CXCursor* decls; unsigned declCount;+-- % CXCursor* refs; unsigned refCount;+-- % getDeclarationsAndReferences(t, &decls, &declCount, &refs, &refCount);+-- %result (cursorList decls declCount, cursorList refs refCount)++getDeclarationsAndReferences :: ClangBase m => TranslationUnit s'+ -> ClangT s m (CursorList s, CursorList s)+getDeclarationsAndReferences tu = do+ (ds, rs) <- liftIO $ unsafe_getDeclarationsAndReferences tu+ (,) <$> registerCursorList (return ds) <*> registerCursorList (return rs)++data ParentedCursor s = ParentedCursor+ { parentCursor :: !(Cursor s)+ , childCursor :: !(Cursor s)+ } deriving (Eq, Ord, Typeable)++instance ClangValue ParentedCursor++instance Storable (ParentedCursor s) where+ sizeOf _ = sizeOfParentedCursor+ {-# INLINE sizeOf #-}++ alignment _ = alignOfParentedCursor+ {-# INLINE alignment #-}++ peek p = do+ parent <- peekByteOff p offsetParentedCursorParent+ child <- peekByteOff p offsetParentedCursorCursor+ return $! ParentedCursor parent child+ {-# INLINE peek #-}++ poke p (ParentedCursor parent child) = do+ pokeByteOff p offsetParentedCursorParent parent+ pokeByteOff p offsetParentedCursorCursor child+ {-# INLINE poke #-}++-- We deliberately don't export the constructor for UnsafeParentedCursorList.+-- The only way to unwrap it is registerParentedCursorList.+type ParentedCursorList s = DVS.Vector (ParentedCursor s)+instance ClangValueList ParentedCursor+data UnsafeParentedCursorList = UnsafeParentedCursorList !(Ptr ()) !Int++-- void freeParentedCursorList(struct ParentedCursor* parentedCursors);+{# fun freeParentedCursorList as freeParentedCursorList' { id `Ptr ()' } -> `()' #}+freeParentedCursorList :: ParentedCursorList s -> IO ()+freeParentedCursorList pcl = let (pclPtr, _ ) = fromParentedCursorList pcl in freeParentedCursorList' pclPtr++registerParentedCursorList :: ClangBase m => IO UnsafeParentedCursorList+ -> ClangT s m (ParentedCursorList s)+registerParentedCursorList action = do+ (_, pcList) <- clangAllocate (action >>= mkSafe) freeParentedCursorList+ return pcList+ where+ mkSafe (UnsafeParentedCursorList cs n) = do+ fptr <- newForeignPtr_ (castPtr cs)+ return $ DVS.unsafeFromForeignPtr fptr 0 n+{-# INLINEABLE registerParentedCursorList #-}++fromParentedCursorList :: ParentedCursorList s -> (Ptr (), Int)+fromParentedCursorList cs =+ let (p, _, _) = DVS.unsafeToForeignPtr cs in+ (castPtr $ Foreign.ForeignPtr.Unsafe.unsafeForeignPtrToPtr p, DVS.length cs)++toParentedCursorList :: (Ptr (), Int) -> UnsafeParentedCursorList+toParentedCursorList (cs, n) = UnsafeParentedCursorList cs n++-- %dis parentedCursorList cs n = <fromParentedCursorList/toParentedCursorList> (ptr cs) (int n)++-- Like getParentedDescendants, but pairs each descendant with its parent.+-- void getParentedDescendants(CXCursor parent, struct ParentedCursor** descendantsOut,+-- unsigned* countOut)+{# fun getParentedDescendants as getParentedDescendants' {withVoided* %`Cursor a', id `Ptr (Ptr ())', alloca- `CUInt' peek* } -> `()' #}+unsafe_getParentedDescendants :: Cursor s -> IO UnsafeParentedCursorList+unsafe_getParentedDescendants c =+ do+ cxListPtr <- mallocBytes (sizeOf (undefined :: (Ptr (Ptr ()))))+ n <- getParentedDescendants' c cxListPtr+ cxList <- peek cxListPtr+ free cxListPtr+ return (toParentedCursorList (cxList, fromIntegral n))++getParentedDescendants :: ClangBase m => Cursor s' -> ClangT s m (ParentedCursorList s)+getParentedDescendants = registerParentedCursorList . unsafe_getParentedDescendants++-- void getParentedDeclarations(CXTranslationUnit tu, CXCursor** declsOut, unsigned* declCountOut);+{# fun getParentedDeclarations as getParentedDeclarations' { id `Ptr ()', id `Ptr (Ptr ())', alloca- `CUInt' peek* } -> `()' #}+unsafe_getParentedDeclarations :: TranslationUnit s -> IO UnsafeParentedCursorList+unsafe_getParentedDeclarations t = do+ cxListPtr <- mallocBytes (sizeOf (undefined :: (Ptr (Ptr (Cursor ())))))+ n <- getParentedDeclarations' (unTranslationUnit t) (castPtr cxListPtr)+ cxList <- peek cxListPtr+ free cxListPtr+ return (toParentedCursorList (cxList, fromIntegral n))++getParentedDeclarations :: ClangBase m => TranslationUnit s' -> ClangT s m (ParentedCursorList s)+getParentedDeclarations = registerParentedCursorList . unsafe_getParentedDeclarations++-- void getParentedReferences(CXTranslationUnit tu, CXCursor** declsOut, unsigned* declCountOut);+{# fun getParentedReferences as getParentedReferences' { id `Ptr ()', id `Ptr (Ptr ())', alloca- `CUInt' peek* } -> `()' #}+unsafe_getParentedReferences :: TranslationUnit s -> IO UnsafeParentedCursorList+unsafe_getParentedReferences t = do+ cxListPtr <- mallocBytes (sizeOf (undefined :: (Ptr (Ptr ()))))+ n <- getParentedReferences' (unTranslationUnit t) cxListPtr+ cxList <- peek cxListPtr+ free cxListPtr+ return (toParentedCursorList (cxList, fromIntegral n))++getParentedReferences :: ClangBase m => TranslationUnit s' -> ClangT s m (ParentedCursorList s)+getParentedReferences = registerParentedCursorList . unsafe_getParentedReferences++-- void getParentedDeclarationsAndReferences(CXTranslationUnit tu,+-- ParentedCursor** declsOut,+-- unsigned* declCountOut,+-- ParentedCursor** refsOut,+-- unsigned* refCountOut);+{# fun getParentedDeclarationsAndReferences as getParentedDeclarationsAndReferences'+ { id `Ptr ()', id `Ptr (Ptr ())', alloca- `CUInt' peek*, id `Ptr (Ptr ())' , alloca- `CUInt' peek* } -> `()' #}+unsafe_getParentedDeclarationsAndReferences :: TranslationUnit s -> IO (UnsafeParentedCursorList, UnsafeParentedCursorList)+unsafe_getParentedDeclarationsAndReferences t = do+ declsPtr <- mallocBytes (sizeOf (undefined :: (Ptr (Ptr ()))))+ refsPtr <- mallocBytes (sizeOf (undefined :: (Ptr (Ptr ()))))+ (nDecls, nRefs) <- getParentedDeclarationsAndReferences' (unTranslationUnit t) declsPtr refsPtr+ decls <- peek declsPtr+ refs <- peek refsPtr+ free declsPtr+ free refsPtr+ return ((toParentedCursorList (decls, fromIntegral nDecls)), (toParentedCursorList (refs, fromIntegral nRefs)))++getParentedDeclarationsAndReferences :: ClangBase m => TranslationUnit s'+ -> ClangT s m (ParentedCursorList s, ParentedCursorList s)+getParentedDeclarationsAndReferences tu = do+ (ds, rs) <- liftIO $ unsafe_getParentedDeclarationsAndReferences tu+ (,) <$> registerParentedCursorList (return ds) <*> registerParentedCursorList (return rs)++-- CXString clang_getCursorUSR(CXCursor);+{# fun wrapped_clang_getCursorUSR as clang_getCursorUSR {withVoided* %`Cursor a' } -> `Ptr (ClangString ())' castPtr #}+unsafe_getCursorUSR :: Cursor s -> IO (ClangString ())+unsafe_getCursorUSR c =+ clang_getCursorUSR c >>= peek++getCursorUSR :: ClangBase m => Cursor s' -> ClangT s m (ClangString s)+getCursorUSR = registerClangString . unsafe_getCursorUSR++-- CXString clang_constructUSR_ObjCClass(const char *class_name);+{# fun wrapped_clang_constructUSR_ObjCClass as clang_constructUSR_ObjCClass { `CString' } -> `Ptr (ClangString ())' castPtr #}+unsafe_constructUSR_ObjCClass :: String -> IO (ClangString ())+unsafe_constructUSR_ObjCClass s = withCString s (\sPtr -> clang_constructUSR_ObjCClass sPtr >>= peek)++constructUSR_ObjCClass :: ClangBase m => String -> ClangT s m (ClangString s)+constructUSR_ObjCClass = registerClangString . unsafe_constructUSR_ObjCClass++-- CXString+-- clang_constructUSR_ObjCCategory(const char *class_name,+-- const char *category_name);+{# fun wrapped_clang_constructUSR_ObjCCategory as clang_constructUSR_ObjCCategory { `CString', `CString' } -> `Ptr (ClangString ())' castPtr #}+unsafe_constructUSR_ObjCCategory :: String -> String -> IO (ClangString ())+unsafe_constructUSR_ObjCCategory s p =+ withCString s (\sPtr ->+ withCString p (\pPtr ->+ clang_constructUSR_ObjCCategory sPtr pPtr >>= peek))++constructUSR_ObjCCategory :: ClangBase m => String -> String -> ClangT s m (ClangString s)+constructUSR_ObjCCategory = (registerClangString .) . unsafe_constructUSR_ObjCCategory++-- CXString+-- clang_constructUSR_ObjCProtocol(const char *protocol_name);+{# fun wrapped_clang_constructUSR_ObjCProtocol as clang_constructUSR_ObjCProtocol { `CString' } -> `Ptr (ClangString ())' castPtr #}+unsafe_constructUSR_ObjCProtocol :: String -> IO (ClangString ())+unsafe_constructUSR_ObjCProtocol s = withCString s (\sPtr -> clang_constructUSR_ObjCProtocol sPtr >>= peek)++constructUSR_ObjCProtocol :: ClangBase m => String -> ClangT s m (ClangString s)+constructUSR_ObjCProtocol = registerClangString . unsafe_constructUSR_ObjCProtocol++-- CXString clang_constructUSR_ObjCIvar(const char *name,+-- CXString classUSR);+{# fun wrapped_clang_constructUSR_ObjCIvar as clang_constructUSR_ObjCIvar { `CString' , id `Ptr ()' } -> `Ptr (ClangString ())' castPtr #}+unsafe_constructUSR_ObjCIvar :: String -> Ptr () -> Word32 -> IO (ClangString ())+unsafe_constructUSR_ObjCIvar s d f =+ let clangString = ClangString d f in+ withCString s (\sPtr -> new clangString >>= \cs -> clang_constructUSR_ObjCIvar sPtr (castPtr cs) >>= peek)++constructUSR_ObjCIvar :: ClangBase m => String -> ClangString s' -> ClangT s m (ClangString s)+constructUSR_ObjCIvar s (ClangString d f) = registerClangString $ unsafe_constructUSR_ObjCIvar s d f++-- CXString clang_constructUSR_ObjCMethod(const char *name,+-- unsigned isInstanceMethod,+-- CXString classUSR);+{# fun wrapped_clang_constructUSR_ObjCMethod as clang_constructUSR_ObjCMethod { `CString' , `CUInt' , id `Ptr ()' } -> `Ptr (ClangString ())' castPtr #}+unsafe_constructUSR_ObjCMethod :: String -> Bool -> Ptr () -> Word32 -> IO (ClangString ())+unsafe_constructUSR_ObjCMethod s b d f =+ let clangString = ClangString d f in+ withCString s (\sPtr -> (new clangString >>= \cs -> clang_constructUSR_ObjCMethod sPtr (fromIntegral ((fromBool b) :: Int)) (castPtr cs) >>= peek))++constructUSR_ObjCMethod :: ClangBase m => String -> Bool -> ClangString s' -> ClangT s m (ClangString s)+constructUSR_ObjCMethod s b (ClangString d f) =+ registerClangString $ unsafe_constructUSR_ObjCMethod s b d f++-- CXString clang_constructUSR_ObjCProperty(const char *property,+-- CXString classUSR);+{# fun wrapped_clang_constructUSR_ObjCProperty as clang_constructUSR_ObjCProperty { `CString' , id `Ptr ()' } -> `Ptr (ClangString ())' castPtr #}+unsafe_constructUSR_ObjCProperty :: String -> Ptr () -> Word32 -> IO (ClangString ())+unsafe_constructUSR_ObjCProperty s d f =+ let clangString = ClangString d f in+ withCString s (\sPtr -> (new clangString >>= \cs -> clang_constructUSR_ObjCProperty sPtr (castPtr cs) >>= peek))++constructUSR_ObjCProperty :: ClangBase m => String -> ClangString s' -> ClangT s m (ClangString s)+constructUSR_ObjCProperty s (ClangString d f) =+ registerClangString $ unsafe_constructUSR_ObjCProperty s d f++-- CXString clang_getCursorSpelling(CXCursor);+{# fun wrapped_clang_getCursorSpelling as clang_getCursorSpelling {withVoided* %`Cursor a' } -> `Ptr (ClangString ())' castPtr #}+unsafe_getCursorSpelling :: Cursor s -> IO (ClangString ())+unsafe_getCursorSpelling c =+ clang_getCursorSpelling c >>= peek++getCursorSpelling :: ClangBase m => Cursor s' -> ClangT s m (ClangString s)+getCursorSpelling = registerClangString . unsafe_getCursorSpelling++-- CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor,+-- unsigned pieceIndex,+-- unsigned options);+{# fun wrapped_clang_Cursor_getSpellingNameRange as clang_Cursor_getSpellingNameRange {withVoided* %`Cursor a', `Int', `Int' } -> `Ptr (SourceRange s)' castPtr #}+cursor_getSpellingNameRange :: Proxy s -> Cursor s' -> Int -> IO (SourceRange s)+cursor_getSpellingNameRange _ c i = clang_Cursor_getSpellingNameRange c i 0 >>= peek++-- CXString clang_getCursorDisplayName(CXCursor);+{# fun wrapped_clang_getCursorDisplayName as clang_getCursorDisplayName {withVoided* %`Cursor a' } -> `Ptr (ClangString ())' castPtr #}+unsafe_getCursorDisplayName :: Cursor s -> IO (ClangString ())+unsafe_getCursorDisplayName c =+ clang_getCursorDisplayName c >>= peek++getCursorDisplayName :: ClangBase m => Cursor s' -> ClangT s m (ClangString s)+getCursorDisplayName = registerClangString . unsafe_getCursorDisplayName++-- CXCursor clang_getCursorReferenced(CXCursor);+{# fun wrapped_clang_getCursorReferenced as clang_getCursorReferenced {withVoided* %`Cursor a' } -> `Ptr (Cursor s)' castPtr #}+getCursorReferenced :: Proxy s -> Cursor s' -> IO (Cursor s)+getCursorReferenced _ c =+ clang_getCursorReferenced c >>= peek++-- CXCursor clang_getCursorDefinition(CXCursor);+{# fun wrapped_clang_getCursorDefinition as clang_getCursorDefinition {withVoided* %`Cursor a' } -> `Ptr (Cursor s)' castPtr #}+getCursorDefinition :: Proxy s -> Cursor s' -> IO (Cursor s)+getCursorDefinition _ c = clang_getCursorDefinition c >>= peek++-- unsigned clang_isCursorDefinition(CXCursor);+{# fun clang_isCursorDefinition {withVoided* %`Cursor a' } -> `Bool' toBool #}+isCursorDefinition :: Cursor s -> IO Bool+isCursorDefinition c = clang_isCursorDefinition c++-- unsigned clang_Cursor_isDynamicCall(CXCursor);+{# fun clang_Cursor_isDynamicCall {withVoided* %`Cursor a' } -> `Bool' toBool #}+cursor_isDynamicCall :: Cursor s -> IO Bool+cursor_isDynamicCall c = clang_Cursor_isDynamicCall c++-- CXCursor clang_getCanonicalCursor(CXCursor);+{# fun wrapped_clang_getCanonicalCursor as clang_getCanonicalCursor {withVoided* %`Cursor a' } -> `Ptr (Cursor s)' castPtr #}+getCanonicalCursor :: Proxy s -> Cursor s' -> IO (Cursor s)+getCanonicalCursor _ c =+ clang_getCanonicalCursor c >>= peek++-- int clang_Cursor_getObjCSelectorIndex(CXCursor);+{# fun clang_Cursor_getObjCSelectorIndex {withVoided* %`Cursor a' } -> `Int' #}+cursor_getObjCSelectorIndex :: Cursor s -> IO Int+cursor_getObjCSelectorIndex c = clang_Cursor_getObjCSelectorIndex c++-- CXType clang_Cursor_getReceiverType(CXCursor C);+{# fun wrapped_clang_Cursor_getReceiverType as clang_Cursor_getReceiverType {withVoided* %`Cursor a' } -> `Ptr (Type s)' castPtr #}+cursor_getReceiverType :: Proxy s -> Cursor s' -> IO (Type s)+cursor_getReceiverType proxy c =+ clang_Cursor_getReceiverType c >>= peek++-- typedef enum {+-- CXObjCPropertyAttr_noattr = 0x00,+-- CXObjCPropertyAttr_readonly = 0x01,+-- CXObjCPropertyAttr_getter = 0x02,+-- CXObjCPropertyAttr_assign = 0x04,+-- CXObjCPropertyAttr_readwrite = 0x08,+-- CXObjCPropertyAttr_retain = 0x10,+-- CXObjCPropertyAttr_copy = 0x20,+-- CXObjCPropertyAttr_nonatomic = 0x40,+-- CXObjCPropertyAttr_setter = 0x80,+-- CXObjCPropertyAttr_atomic = 0x100,+-- CXObjCPropertyAttr_weak = 0x200,+-- CXObjCPropertyAttr_strong = 0x400,+-- CXObjCPropertyAttr_unsafe_unretained = 0x800+-- } CXObjCPropertyAttrKind;++#c+enum ObjCPropertyAttrKind+ { ObjCPropertyAttr_noattr = CXObjCPropertyAttr_noattr+ , ObjCPropertyAttr_readonly = CXObjCPropertyAttr_readonly+ , ObjCPropertyAttr_getter = CXObjCPropertyAttr_getter+ , ObjCPropertyAttr_assign = CXObjCPropertyAttr_assign+ , ObjCPropertyAttr_readwrite = CXObjCPropertyAttr_readwrite+ , ObjCPropertyAttr_retain = CXObjCPropertyAttr_retain+ , ObjCPropertyAttr_copy = CXObjCPropertyAttr_copy+ , ObjCPropertyAttr_nonatomic = CXObjCPropertyAttr_nonatomic+ , ObjCPropertyAttr_setter = CXObjCPropertyAttr_setter+ , ObjCPropertyAttr_atomic = CXObjCPropertyAttr_atomic+ , ObjCPropertyAttr_weak = CXObjCPropertyAttr_weak+ , ObjCPropertyAttr_strong = CXObjCPropertyAttr_strong+ , ObjCPropertyAttr_unsafe_unretained= CXObjCPropertyAttr_unsafe_unretained+ };+#endc+{# enum ObjCPropertyAttrKind {} deriving (Bounded, Eq, Ord, Read, Show, Typeable) #}++instance BitFlags ObjCPropertyAttrKind where+ toBit ObjCPropertyAttr_noattr = 0x0+ toBit ObjCPropertyAttr_readonly = 0x1+ toBit ObjCPropertyAttr_getter = 0x2+ toBit ObjCPropertyAttr_assign = 0x4+ toBit ObjCPropertyAttr_readwrite = 0x8+ toBit ObjCPropertyAttr_retain = 0x10+ toBit ObjCPropertyAttr_copy = 0x20+ toBit ObjCPropertyAttr_nonatomic = 0x40+ toBit ObjCPropertyAttr_setter = 0x80+ toBit ObjCPropertyAttr_atomic = 0x100+ toBit ObjCPropertyAttr_weak = 0x200+ toBit ObjCPropertyAttr_strong = 0x400+ toBit ObjCPropertyAttr_unsafe_unretained = 0x800++-- unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved);+{# fun clang_Cursor_getObjCPropertyAttributes {withVoided* %`Cursor a', `Int' } -> `CUInt' #}+cursor_getObjCPropertyAttributes :: Cursor s -> IO Int+cursor_getObjCPropertyAttributes c = clang_Cursor_getObjCPropertyAttributes c 0 >>= return . fromIntegral++-- typedef enum {+-- CXObjCDeclQualifier_None = 0x0,+-- CXObjCDeclQualifier_In = 0x1,+-- CXObjCDeclQualifier_Inout = 0x2,+-- CXObjCDeclQualifier_Out = 0x4,+-- CXObjCDeclQualifier_Bycopy = 0x8,+-- CXObjCDeclQualifier_Byref = 0x10,+-- CXObjCDeclQualifier_Oneway = 0x20+-- } CXObjCDeclQualifierKind;++#c+enum ObjCDeclQualifierKind+ { ObjCDeclQualifier_None = CXObjCDeclQualifier_None+ , ObjCDeclQualifier_In = CXObjCDeclQualifier_In+ , ObjCDeclQualifier_Inout = CXObjCDeclQualifier_Inout+ , ObjCDeclQualifier_Out = CXObjCDeclQualifier_Out+ , ObjCDeclQualifier_Bycopy = CXObjCDeclQualifier_Bycopy+ , ObjCDeclQualifier_Byref = CXObjCDeclQualifier_Byref+ , ObjCDeclQualifier_Oneway = CXObjCDeclQualifier_Oneway+ };+#endc+{# enum ObjCDeclQualifierKind {} deriving (Bounded, Eq, Ord, Read, Show, Typeable) #}++instance BitFlags ObjCDeclQualifierKind where+ toBit ObjCDeclQualifier_None = 0x0+ toBit ObjCDeclQualifier_In = 0x1+ toBit ObjCDeclQualifier_Inout = 0x2+ toBit ObjCDeclQualifier_Out = 0x4+ toBit ObjCDeclQualifier_Bycopy = 0x8+ toBit ObjCDeclQualifier_Byref = 0x10+ toBit ObjCDeclQualifier_Oneway = 0x20++-- unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C);+{# fun clang_Cursor_getObjCDeclQualifiers {withVoided* %`Cursor a' } -> `CUInt' #}+cursor_getObjCDeclQualifiers :: Cursor s -> IO Int+cursor_getObjCDeclQualifiers c =+ clang_Cursor_getObjCDeclQualifiers c >>= return . fromIntegral++-- unsigned clang_Cursor_isObjCOptional(CXCursor);+{# fun clang_Cursor_isObjCOptional {withVoided* %`Cursor a' } -> `Bool' toBool #}+cursor_isObjCOptional :: Cursor s -> IO Bool+cursor_isObjCOptional c = clang_Cursor_isObjCOptional c++-- unsigned clang_Cursor_isVariadic(CXCursor);+{# fun clang_Cursor_isVariadic {withVoided* %`Cursor a' } -> `Bool' toBool #}+cursor_isVariadic :: Cursor s -> IO Bool+cursor_isVariadic c = clang_Cursor_isVariadic c++-- CXSourceRange clang_Cursor_getCommentRange(CXCursor C);+{# fun wrapped_clang_Cursor_getCommentRange as clang_Cursor_getCommentRange {withVoided* %`Cursor a' } -> `Ptr (SourceRange s)' castPtr #}+cursor_getCommentRange :: Proxy s -> Cursor s' -> IO (SourceRange s)+cursor_getCommentRange _ c = clang_Cursor_getCommentRange c >>= peek++-- CXString clang_Cursor_getRawCommentText(CXCursor C);+{# fun wrapped_clang_Cursor_getRawCommentText as clang_Cursor_getRawCommentText {withVoided* %`Cursor a' } -> `Ptr (ClangString ())' castPtr #}+unsafe_Cursor_getRawCommentText :: Cursor s -> IO (ClangString ())+unsafe_Cursor_getRawCommentText c =+ clang_Cursor_getRawCommentText c >>= peek++cursor_getRawCommentText :: ClangBase m => Cursor s' -> ClangT s m (ClangString s)+cursor_getRawCommentText = registerClangString . unsafe_Cursor_getRawCommentText++-- CXString clang_Cursor_getBriefCommentText(CXCursor C);+{# fun wrapped_clang_Cursor_getBriefCommentText as clang_Cursor_getBriefCommentText {withVoided* %`Cursor a' } -> `Ptr (ClangString ())' castPtr #}+unsafe_Cursor_getBriefCommentText :: Cursor s -> IO (ClangString ())+unsafe_Cursor_getBriefCommentText c =+ clang_Cursor_getBriefCommentText c >>= peek++cursor_getBriefCommentText :: ClangBase m => Cursor s' -> ClangT s m (ClangString s)+cursor_getBriefCommentText = registerClangString . unsafe_Cursor_getBriefCommentText++-- CXComment clang_Cursor_getParsedComment(CXCursor C);++{# fun wrapped_clang_Cursor_getParsedComment as clang_Cursor_getParsedComment {withVoided* %`Cursor a' } -> `Ptr (Comment s)' castPtr #}+cursor_getParsedComment :: Proxy s -> Cursor s' -> IO (Comment s)+cursor_getParsedComment _ c =+ clang_Cursor_getParsedComment c >>= peek++-- typedef void *CXModule;+newtype Module s = Module { unModule :: Ptr () }+ deriving (Eq, Ord, Typeable)++instance ClangValue Module++-- %dis cxmodule p = <unModule/Module> (ptr p)++maybeModule :: Module s' -> Maybe (Module s)+maybeModule (Module p) | p == nullPtr = Nothing+maybeModule f = Just (unsafeCoerce f)++unMaybeModule :: Maybe (Module s') -> Module s+unMaybeModule (Just f) = unsafeCoerce f+unMaybeModule Nothing = Module nullPtr++-- CXModule clang_Cursor_getModule(CXCursor C);+{# fun clang_Cursor_getModule {withVoided* %`Cursor a' } -> `Ptr ()' id #}+cursor_getModule :: Proxy s -> Cursor s' -> IO (Module s)+cursor_getModule _ c =+ clang_Cursor_getModule c >>= return . Module++-- CXFile clang_Module_getASTFile(CXModule Module);+{# fun clang_Module_getASTFile { id `Ptr ()' } -> `Ptr ()' id #}+module_getASTFile :: Proxy s -> Module s' -> IO (File s)+module_getASTFile _ m = clang_Module_getASTFile (unModule m) >>= return . File++-- CXModule clang_Module_getParent(CXModule Module);+{# fun clang_Module_getParent { id `Ptr ()' } -> `Ptr ()' id #}+module_getParent :: Proxy s -> Module s' -> IO (Maybe (Module s))+module_getParent _ m = clang_Module_getParent (unModule m) >>= return . maybeModule . Module++-- CXString clang_Module_getName(CXModule Module);+{# fun wrapped_clang_Module_getName as clang_Module_getName { id `Ptr ()' } -> `Ptr (ClangString ())' castPtr #}+unsafe_Module_getName :: Module s -> IO (ClangString ())+unsafe_Module_getName m = clang_Module_getName (unModule m) >>= peek++module_getName :: ClangBase m => Module s' -> ClangT s m (ClangString s)+module_getName = registerClangString . unsafe_Module_getName++-- CXString clang_Module_getFullName(CXModule Module);+{# fun wrapped_clang_Module_getFullName as clang_Module_getFullName { id `Ptr ()' } -> `Ptr (ClangString ())' castPtr #}+unsafe_Module_getFullName :: Module s -> IO (ClangString ())+unsafe_Module_getFullName m = clang_Module_getFullName (unModule m) >>= peek++module_getFullName :: ClangBase m => Module s' -> ClangT s m (ClangString s)+module_getFullName = registerClangString . unsafe_Module_getFullName++-- unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit, CXModule Module);+{# fun clang_Module_getNumTopLevelHeaders { id `Ptr ()', id `Ptr ()' } -> `Int' #}+module_getNumTopLevelHeaders :: TranslationUnit s -> Module s' -> IO Int+module_getNumTopLevelHeaders t m = clang_Module_getNumTopLevelHeaders (unTranslationUnit t) (unModule m)++-- CXFile clang_Module_getTopLevelHeader(CXTranslationUnit, CXModule Module, unsigned Index);+{# fun clang_Module_getTopLevelHeader { id `Ptr ()', id `Ptr ()', `Int' } -> `Ptr ()' id #}+module_getTopLevelHeader :: Proxy s -> TranslationUnit s' -> Module s'' -> Int -> IO (File s)+module_getTopLevelHeader _ t m i = clang_Module_getTopLevelHeader (unTranslationUnit t) (unModule m) i >>= return . File++-- unsigned clang_CXXMethod_isPureVirtual(CXCursor C);+{# fun clang_CXXMethod_isPureVirtual {withVoided* %`Cursor a' } -> `Bool' toBool #}+cXXMethod_isPureVirtual :: Cursor s -> IO Bool+cXXMethod_isPureVirtual c = clang_Cursor_isBitField c++-- unsigned clang_CXXMethod_isStatic(CXCursor C);+{# fun clang_CXXMethod_isStatic {withVoided* %`Cursor a' } -> `Bool' toBool #}+cXXMethod_isStatic :: Cursor s -> IO Bool+cXXMethod_isStatic c = clang_Cursor_isBitField c++-- unsigned clang_CXXMethod_isVirtual(CXCursor C);+{# fun clang_CXXMethod_isVirtual {withVoided* %`Cursor a' } -> `Bool' toBool #}+cXXMethod_isVirtual :: Cursor s -> IO Bool+cXXMethod_isVirtual c = clang_Cursor_isBitField c++-- enum CXCursorKind clang_getTemplateCursorKind(CXCursor C);+{# fun clang_getTemplateCursorKind {withVoided* %`Cursor a' } -> `Int' #}+getTemplateCursorKind :: Cursor s -> IO CursorKind+getTemplateCursorKind c =+ clang_getTemplateCursorKind c >>= return . toEnum++-- CXCursor clang_getSpecializedCursorTemplate(CXCursor C);+{# fun wrapped_clang_getSpecializedCursorTemplate as clang_getSpecializedCursorTemplate {withVoided* %`Cursor a' } -> `Ptr (Cursor s)' castPtr #}+getSpecializedCursorTemplate :: Proxy s -> Cursor s' -> IO (Cursor s)+getSpecializedCursorTemplate _ c =+ clang_getSpecializedCursorTemplate c >>= peek++-- CXSourceRange clang_getCursorReferenceNameRange(CXCursor C,+-- unsigned NameFlags,+-- unsigned PieceIndex);+{# fun wrapped_clang_getCursorReferenceNameRange as clang_getCursorReferenceNameRange {withVoided* %`Cursor a', `Int' , `Int' } -> `Ptr (SourceRange s)' castPtr #}+getCursorReferenceNameRange :: Proxy s -> Cursor s' -> Int -> Int -> IO (SourceRange s)+getCursorReferenceNameRange _ c fs idx = clang_getCursorReferenceNameRange c fs idx >>= peek++-- enum CXNameRefFlags {+-- CXNameRange_WantQualifier = 0x1,+-- CXNameRange_WantTemplateArgs = 0x2,+-- CXNameRange_WantSinglePiece = 0x4+-- };+#c+enum NameRefFlags+ { NameRange_WantQualifier = CXNameRange_WantQualifier+ , NameRange_WantTemplateArgs = CXNameRange_WantTemplateArgs+ , NameRange_WantSinglePiece = CXNameRange_WantSinglePiece+ };+#endc+{# enum NameRefFlags {} deriving (Bounded, Eq, Ord, Read, Show, Typeable) #}++instance BitFlags NameRefFlags where+ toBit NameRange_WantQualifier = 0x01+ toBit NameRange_WantTemplateArgs = 0x02+ toBit NameRange_WantSinglePiece = 0x04++-- enum CXCommentKind {+-- CXComment_Null = 0,+-- CXComment_Text = 1,+-- CXComment_InlineCommand = 2,+-- CXComment_HTMLStartTag = 3,+-- CXComment_HTMLEndTag = 4,+-- CXComment_Paragraph = 5,+-- CXComment_BlockCommand = 6,+-- CXComment_ParamCommand = 7,+-- CXComment_TParamCommand = 8,+-- CXComment_VerbatimBlockCommand = 9,+-- CXComment_VerbatimBlockLine = 10,+-- CXComment_VerbatimLine = 11,+-- CXComment_FullComment = 12+-- };+#c+enum CommentKind+ { NullComment = CXComment_Null+ , TextComment = CXComment_Text+ , InlineCommandComment = CXComment_InlineCommand+ , HTMLStartTagComment = CXComment_HTMLStartTag+ , HTMLEndTagComment = CXComment_HTMLEndTag+ , ParagraphComment = CXComment_Paragraph+ , BlockCommandComment = CXComment_BlockCommand+ , ParamCommandComment = CXComment_ParamCommand+ , TParamCommandComment = CXComment_TParamCommand+ , VerbatimBlockCommandComment = CXComment_VerbatimBlockCommand+ , VerbatimBlockLineComment = CXComment_VerbatimBlockLine+ , VerbatimLineComment = CXComment_VerbatimLine+ , FullComment = CXComment_FullComment+ };+#endc+{# enum CommentKind {} deriving (Bounded, Eq, Ord, Read, Show, Typeable) #}++-- enum CXCommentInlineCommandRenderKind {+-- CXCommentInlineCommandRenderKind_Normal,+-- CXCommentInlineCommandRenderKind_Bold,+-- CXCommentInlineCommandRenderKind_Monospaced,+-- CXCommentInlineCommandRenderKind_Emphasized+-- };++-- | A rendering style which should be used for the associated inline command in the comment AST.+#c+enum InlineCommandRenderStyle+ { NormalInlineCommandRenderStyle = CXCommentInlineCommandRenderKind_Normal+ , BoldInlineCommandRenderStyle = CXCommentInlineCommandRenderKind_Bold+ , MonospacedInlineCommandRenderStyle = CXCommentInlineCommandRenderKind_Monospaced+ , EmphasizedInlineCommandRenderStyle = CXCommentInlineCommandRenderKind_Emphasized+ };+#endc+{# enum InlineCommandRenderStyle {} deriving (Bounded, Eq, Ord, Read, Show, Typeable) #}+-- enum CXCommentParamPassDirection {+-- CXCommentParamPassDirection_In,+-- CXCommentParamPassDirection_Out,+-- CXCommentParamPassDirection_InOut+-- };++-- | A parameter passing direction.+#c+enum ParamPassDirectionKind+ { InParamPassDirection = CXCommentParamPassDirection_In+ , OutParamPassDirection = CXCommentParamPassDirection_Out+ , InOutParamPassDirection = CXCommentParamPassDirection_InOut+ };+#endc+{#enum ParamPassDirectionKind {} deriving (Bounded, Eq, Ord, Read, Show, Typeable) #}++-- enum CXCommentKind clang_Comment_getKind(CXComment Comment);+{# fun clang_Comment_getKind {withVoided* %`Comment a' } -> `Int' #}+comment_getKind :: Comment s -> IO CommentKind+comment_getKind c =+ clang_Comment_getKind c >>= return . toEnum++-- unsigned clang_Comment_getNumChildren(CXComment Comment);+{# fun clang_Comment_getNumChildren {withVoided* %`Comment a' } -> `Int' #}+comment_getNumChildren :: Comment s -> IO Int+comment_getNumChildren c =+ clang_Comment_getNumChildren c++-- CXComment clang_Comment_getChild(CXComment Comment, unsigned ChildIdx);+{# fun clang_Comment_getChild {withVoided* %`Comment a', `Int' } -> `Ptr (Comment s)' castPtr #}+comment_getChild :: Proxy s -> Comment s' -> Int -> IO (Comment s)+comment_getChild _ c i = clang_Comment_getChild c i >>= peek++-- unsigned clang_Comment_isWhitespace(CXComment Comment);+{# fun clang_Comment_isWhitespace {withVoided* %`Comment a' } -> `Bool' toBool #}+comment_isWhitespace :: Comment s -> IO Bool+comment_isWhitespace c = clang_Comment_isWhitespace c++-- unsigned clang_InlineContentComment_hasTrailingNewline(CXComment Comment);+{# fun clang_InlineContentComment_hasTrailingNewline {withVoided* %`Comment a' } -> `Bool' toBool #}+inlineContentComment_hasTrailingNewline :: Comment s -> IO Bool+inlineContentComment_hasTrailingNewline c = clang_InlineContentComment_hasTrailingNewline c++-- CXString clang_TextComment_getText(CXComment Comment);+{# fun wrapped_clang_TextComment_getText as clang_TextComment_getText {withVoided* %`Comment a' } -> `Ptr (ClangString ())' castPtr #}+unsafe_TextComment_getText :: Comment s -> IO (ClangString ())+unsafe_TextComment_getText c =+ clang_TextComment_getText c >>= peek++textComment_getText :: ClangBase m => Comment s' -> ClangT s m (ClangString s)+textComment_getText = registerClangString . unsafe_TextComment_getText++-- CXString clang_InlineCommandComment_getCommandName(CXComment Comment);+{# fun clang_InlineCommandComment_getCommandName {withVoided* %`Comment a' } -> `Ptr (ClangString ())' castPtr #}+unsafe_InlineCommandComment_getCommandName :: Comment s -> IO (ClangString ())+unsafe_InlineCommandComment_getCommandName c =+ clang_InlineCommandComment_getCommandName c >>= peek++inlineCommandComment_getCommandName :: ClangBase m => Comment s' -> ClangT s m (ClangString s)+inlineCommandComment_getCommandName = registerClangString . unsafe_InlineCommandComment_getCommandName++-- enum CXCommentInlineCommandRenderKind clang_InlineCommandComment_getRenderKind(CXComment Comment);+{# fun clang_InlineCommandComment_getRenderKind {withVoided* %`Comment a' } -> `Int' #}+inlineCommandComment_getRenderKind :: Comment s -> IO InlineCommandRenderStyle+inlineCommandComment_getRenderKind c =+ clang_InlineCommandComment_getRenderKind c >>= return . toEnum++-- unsigned clang_InlineCommandComment_getNumArgs(CXComment Comment);+{# fun clang_InlineCommandComment_getNumArgs {withVoided* %`Comment a' } -> `Int' #}+inlineCommandComment_getNumArgs :: Comment s -> IO Int+inlineCommandComment_getNumArgs c =+ clang_InlineCommandComment_getNumArgs c++-- CXString clang_InlineCommandComment_getArgText(CXComment Comment, unsigned ArgIdx);+{# fun clang_InlineCommandComment_getArgText {withVoided* %`Comment a', `Int' } -> `Ptr (ClangString ())' castPtr #}+unsafe_InlineCommandComment_getArgText :: Comment s -> Int -> IO (ClangString ())+unsafe_InlineCommandComment_getArgText c idx =+ clang_InlineCommandComment_getArgText c idx >>= peek++inlineCommandComment_getArgText :: ClangBase m => Comment s' -> Int -> ClangT s m (ClangString s)+inlineCommandComment_getArgText = (registerClangString .) . unsafe_InlineCommandComment_getArgText++-- CXString clang_HTMLTagComment_getTagName(CXComment Comment);+{# fun wrapped_clang_HTMLTagComment_getTagName as clang_HTMLTagComment_getTagName {withVoided* %`Comment a' } -> `Ptr (ClangString ())' castPtr #}+unsafe_HTMLTagComment_getTagName :: Comment s -> IO (ClangString ())+unsafe_HTMLTagComment_getTagName c =+ clang_HTMLTagComment_getTagName c >>= peek++hTMLTagComment_getTagName :: ClangBase m => Comment s' -> ClangT s m (ClangString s)+hTMLTagComment_getTagName = registerClangString . unsafe_HTMLTagComment_getTagName++-- unsigned clang_HTMLStartTagComment_isSelfClosing(CXComment Comment);+{# fun clang_HTMLStartTagComment_isSelfClosing {withVoided* %`Comment a' } -> `Bool' toBool #}+hTMLStartTagComment_isSelfClosing :: Comment s -> IO Bool+hTMLStartTagComment_isSelfClosing c = clang_HTMLStartTagComment_isSelfClosing c++-- unsigned clang_HTMLStartTag_getNumAttrs(CXComment Comment);+{# fun clang_HTMLStartTag_getNumAttrs {withVoided* %`Comment a' } -> `Int' #}+hTMLStartTag_getNumAttrs :: Comment s -> IO Int+hTMLStartTag_getNumAttrs c =+ clang_HTMLStartTag_getNumAttrs c++-- CXString clang_HTMLStartTag_getAttrName(CXComment Comment, unsigned AttrIdx);+{# fun clang_HTMLStartTag_getAttrName {withVoided* %`Comment a', `Int' } -> `Ptr (ClangString ())' castPtr #}+unsafe_HTMLStartTag_getAttrName :: Comment s -> Int -> IO (ClangString ())+unsafe_HTMLStartTag_getAttrName c idx =+ clang_HTMLStartTag_getAttrName c idx >>= peek++hTMLStartTag_getAttrName :: ClangBase m => Comment s' -> Int -> ClangT s m (ClangString s)+hTMLStartTag_getAttrName = (registerClangString .) . unsafe_HTMLStartTag_getAttrName++-- CXString clang_HTMLStartTag_getAttrValue(CXComment Comment, unsigned AttrIdx);+{# fun clang_HTMLStartTag_getAttrValue {withVoided* %`Comment a', `Int' } -> `Ptr (ClangString ())' castPtr #}+unsafe_HTMLStartTag_getAttrValue :: Comment s -> Int -> IO (ClangString ())+unsafe_HTMLStartTag_getAttrValue c idx =+ clang_HTMLStartTag_getAttrValue c idx >>= peek++hTMLStartTag_getAttrValue :: ClangBase m => Comment s' -> Int -> ClangT s m (ClangString s)+hTMLStartTag_getAttrValue = (registerClangString .) . unsafe_HTMLStartTag_getAttrValue++-- CXString clang_BlockCommandComment_getCommandName(CXComment Comment);+{# fun clang_BlockCommandComment_getCommandName {withVoided* %`Comment a' } -> `Ptr (ClangString ())' castPtr #}+unsafe_BlockCommandComment_getCommandName :: Comment s -> IO (ClangString ())+unsafe_BlockCommandComment_getCommandName c =+ clang_BlockCommandComment_getCommandName c >>= peek++blockCommandComment_getCommandName :: ClangBase m => Comment s' -> ClangT s m (ClangString s)+blockCommandComment_getCommandName = registerClangString . unsafe_BlockCommandComment_getCommandName++-- unsigned clang_BlockCommandComment_getNumArgs(CXComment Comment);+{# fun clang_BlockCommandComment_getNumArgs {withVoided* %`Comment a' } -> `Int' #}+blockCommandComment_getNumArgs :: Comment s -> IO Int+blockCommandComment_getNumArgs c =+ clang_BlockCommandComment_getNumArgs c++-- CXString clang_BlockCommandComment_getArgText(CXComment Comment, unsigned ArgIdx);+{# fun clang_BlockCommandComment_getArgText {withVoided* %`Comment a', `Int' } -> `Ptr (ClangString ())' castPtr #}+unsafe_BlockCommandComment_getArgText :: Comment s -> Int -> IO (ClangString ())+unsafe_BlockCommandComment_getArgText c idx =+ clang_BlockCommandComment_getArgText c idx >>= peek++blockCommandComment_getArgText :: ClangBase m => Comment s' -> Int -> ClangT s m (ClangString s)+blockCommandComment_getArgText = (registerClangString .) . unsafe_BlockCommandComment_getArgText++-- CXComment clang_BlockCommandComment_getParagraph(CXComment Comment);+{# fun clang_BlockCommandComment_getParagraph {withVoided* %`Comment a' } -> `Ptr (Comment s)' castPtr #}+blockCommandComment_getParagraph :: Proxy s -> Comment s' -> IO (Comment s)+blockCommandComment_getParagraph _ c =+ clang_BlockCommandComment_getParagraph c >>= peek++-- CXString clang_ParamCommandComment_getParamName(CXComment Comment);+{# fun clang_ParamCommandComment_getParamName {withVoided* %`Comment a' } -> `Ptr (ClangString ())' castPtr #}+unsafe_ParamCommandComment_getParamName :: Comment s -> IO (ClangString ())+unsafe_ParamCommandComment_getParamName c =+ clang_ParamCommandComment_getParamName c >>= peek++paramCommandComment_getParamName :: ClangBase m => Comment s' -> ClangT s m (ClangString s)+paramCommandComment_getParamName = registerClangString . unsafe_ParamCommandComment_getParamName++-- unsigned clang_ParamCommandComment_isParamIndexValid(CXComment Comment);+{# fun clang_ParamCommandComment_isParamIndexValid {withVoided* %`Comment a' } -> `Bool' toBool #}+paramCommandComment_isParamIndexValid :: Comment s -> IO Bool+paramCommandComment_isParamIndexValid c =+ clang_ParamCommandComment_isParamIndexValid c++-- unsigned clang_ParamCommandComment_getParamIndex(CXComment Comment);+{# fun clang_ParamCommandComment_getParamIndex {withVoided* %`Comment a' } -> `Int' #}+paramCommandComment_getParamIndex :: Comment s -> IO Int+paramCommandComment_getParamIndex c =+ clang_ParamCommandComment_getParamIndex c++-- unsigned clang_ParamCommandComment_isDirectionExplicit(CXComment Comment);+{# fun clang_ParamCommandComment_isDirectionExplicit {withVoided* %`Comment a' } -> `Bool' toBool #}+paramCommandComment_isDirectionExplicit :: Comment s -> IO Bool+paramCommandComment_isDirectionExplicit c =+ clang_ParamCommandComment_isDirectionExplicit c++-- enum CXCommentParamPassDirection clang_ParamCommandComment_getDirection(CXComment Comment);+{# fun clang_ParamCommandComment_getDirection {withVoided* %`Comment a' } -> `Int' #}+paramCommandComment_getDirection :: Comment s -> IO ParamPassDirectionKind+paramCommandComment_getDirection c =+ clang_ParamCommandComment_getDirection c >>= return . toEnum++-- CXString clang_TParamCommandComment_getParamName(CXComment Comment);+{# fun clang_TParamCommandComment_getParamName {withVoided* %`Comment a' } -> `Ptr (ClangString ())' castPtr #}+unsafe_TParamCommandComment_getParamName :: Comment s -> IO (ClangString ())+unsafe_TParamCommandComment_getParamName c =+ clang_TParamCommandComment_getParamName c >>= peek++tParamCommandComment_getParamName :: ClangBase m => Comment s' -> ClangT s m (ClangString s)+tParamCommandComment_getParamName = registerClangString . unsafe_TParamCommandComment_getParamName++-- unsigned clang_TParamCommandComment_isParamPositionValid(CXComment Comment);+{# fun clang_TParamCommandComment_isParamPositionValid {withVoided* %`Comment a' } -> `Bool' toBool #}+tParamCommandComment_isParamPositionValid :: Comment s -> IO Bool+tParamCommandComment_isParamPositionValid c =+ clang_TParamCommandComment_isParamPositionValid c++-- unsigned clang_TParamCommandComment_getDepth(CXComment Comment);+{# fun clang_TParamCommandComment_getDepth { withVoided* %`Comment a' } -> `Int' #}+tParamCommandComment_getDepth :: Comment s -> IO Int+tParamCommandComment_getDepth c =+ clang_TParamCommandComment_getDepth c++-- unsigned clang_TParamCommandComment_getIndex(CXComment Comment, unsigned Depth);+{# fun clang_TParamCommandComment_getIndex {withVoided* %`Comment a', `Int' } -> `Int' #}+tParamCommandComment_getIndex :: Comment s -> Int -> IO Int+tParamCommandComment_getIndex c idx =+ clang_TParamCommandComment_getIndex c idx++-- CXString clang_VerbatimBlockLineComment_getText(CXComment Comment);+{# fun clang_VerbatimBlockLineComment_getText {withVoided* %`Comment a' } -> `Ptr (ClangString ())' castPtr #}+unsafe_VerbatimBlockLineComment_getText :: Comment s -> IO (ClangString ())+unsafe_VerbatimBlockLineComment_getText c =+ clang_VerbatimBlockLineComment_getText c >>= peek++verbatimBlockLineComment_getText :: ClangBase m => Comment s' -> ClangT s m (ClangString s)+verbatimBlockLineComment_getText = registerClangString . unsafe_VerbatimBlockLineComment_getText++-- CXString clang_VerbatimLineComment_getText(CXComment Comment);+{# fun wrapped_clang_VerbatimLineComment_getText as clang_VerbatimLineComment_getText {withVoided* %`Comment a' } -> `Ptr (ClangString ())' castPtr #}+unsafe_VerbatimLineComment_getText :: Comment s -> IO (ClangString ())+unsafe_VerbatimLineComment_getText c =+ clang_VerbatimLineComment_getText c >>= peek++verbatimLineComment_getText :: ClangBase m => Comment s' -> ClangT s m (ClangString s)+verbatimLineComment_getText = registerClangString . unsafe_VerbatimLineComment_getText++-- CXString clang_HTMLTagComment_getAsString(CXComment Comment);+{# fun wrapped_clang_HTMLTagComment_getAsString as clang_HTMLTagComment_getAsString {withVoided* %`Comment a' } -> `Ptr (ClangString ())' castPtr #}+unsafe_HTMLTagComment_getAsString :: Comment s -> IO (ClangString ())+unsafe_HTMLTagComment_getAsString c =+ clang_HTMLTagComment_getAsString c >>= peek++hTMLTagComment_getAsString :: ClangBase m => Comment s' -> ClangT s m (ClangString s)+hTMLTagComment_getAsString = registerClangString . unsafe_HTMLTagComment_getAsString++-- CXString clang_FullComment_getAsHTML(CXComment Comment);+{# fun wrapped_clang_FullComment_getAsHTML as clang_FullComment_getAsHTML {withVoided* %`Comment a' } -> `Ptr (ClangString ())' castPtr #}+unsafe_FullComment_getAsHTML :: Comment s -> IO (ClangString ())+unsafe_FullComment_getAsHTML c =+ clang_FullComment_getAsHTML c >>= peek++fullComment_getAsHTML :: ClangBase m => Comment s' -> ClangT s m (ClangString s)+fullComment_getAsHTML = registerClangString . unsafe_FullComment_getAsHTML++-- CXString clang_FullComment_getAsXML(CXComment Comment);+{# fun wrapped_clang_FullComment_getAsXML as clang_FullComment_getAsXML {withVoided* %`Comment a' } -> `Ptr (ClangString ())' castPtr #}+unsafe_FullComment_getAsXML :: Comment s -> IO (ClangString ())+unsafe_FullComment_getAsXML c =+ clang_FullComment_getAsXML c >>= peek++fullComment_getAsXML :: ClangBase m => Comment s' -> ClangT s m (ClangString s)+fullComment_getAsXML = registerClangString . unsafe_FullComment_getAsXML++-- typedef enum CXTokenKind {+-- CXToken_Punctuation,+-- CXToken_Keyword,+-- CXToken_Identifier,+-- CXToken_Literal,+-- CXToken_Comment+-- } CXTokenKind;+#c+enum TokenKind+ { PunctuationToken = CXToken_Punctuation+ , KeywordToken = CXToken_Keyword+ , IdentifierToken = CXToken_Identifier+ , LiteralToken = CXToken_Literal+ , CommentToken = CXToken_Comment+ };+#endc+{# enum TokenKind {} deriving (Bounded, Eq, Ord, Read, Show, Typeable) #}++-- typedef struct {+-- unsigned int_data[4];+-- void *ptr_data;+-- } CXToken;+data Token s = Token !Int !Int !Int !Int !(Ptr ())+ deriving (Eq, Ord, Typeable)++instance ClangValue Token++instance Storable (Token s) where+ sizeOf _ = sizeOfCXToken+ {-# INLINE sizeOf #-}++ alignment _ = alignOfCXToken+ {-# INLINE alignment #-}++ peek p = do+ int_data <- {#get CXToken->int_data #} p >>= peekArray 4+ ptr_data <- {#get CXToken->ptr_data #} p+ return $! Token (fromIntegral (int_data !! 0)) (fromIntegral (int_data !! 1)) (fromIntegral (int_data !! 2)) (fromIntegral (int_data !! 3)) ptr_data+ {-# INLINE peek #-}++ poke p (Token i0 i1 i2 i3 ptr_data) = do+ intsArray <- mallocArray 4+ pokeArray intsArray (map fromIntegral [i0,i1,i2,i3])+ {#set CXToken->int_data #} p intsArray+ {#set CXToken->ptr_data #} p ptr_data+ {-# INLINE poke #-}++-- CXTokenKind clang_getTokenKind(CXToken);+{# fun clang_getTokenKind { withVoided* %`Token s' } -> `Int' #}+getTokenKind :: Token s -> IO TokenKind+getTokenKind t =+ clang_getTokenKind t >>= return . toEnum++-- CXString clang_getTokenSpelling(CXTranslationUnit, CXToken);+{# fun wrapped_clang_getTokenSpelling as clang_getTokenSpelling { id `Ptr ()', withVoided* %`Token s' } -> `Ptr (ClangString ())' castPtr #}+unsafe_getTokenSpelling :: TranslationUnit s -> Token s' -> IO (ClangString ())+unsafe_getTokenSpelling tu t =+ clang_getTokenSpelling (unTranslationUnit tu) t >>= peek++getTokenSpelling :: ClangBase m => TranslationUnit s' -> Token s'' -> ClangT s m (ClangString s)+getTokenSpelling = (registerClangString .) . unsafe_getTokenSpelling++-- CXSourceLocation clang_getTokenLocation(CXTranslationUnit,+-- CXToken);+{# fun wrapped_clang_getTokenLocation as clang_getTokenLocation { id `Ptr ()', withVoided* %`Token a' } -> `Ptr (SourceLocation s)' castPtr #}+getTokenLocation :: Proxy s -> TranslationUnit t -> Token s' -> IO (SourceLocation s)+getTokenLocation _ tu t =+ clang_getTokenLocation (unTranslationUnit tu) t >>= peek++-- CXSourceRange clang_getTokenExtent(CXTranslationUnit, CXToken);+{# fun wrapped_clang_getTokenExtent as clang_getTokenExtent { id `Ptr ()', withVoided* %`Token a' } -> `Ptr (SourceRange s)' castPtr #}+getTokenExtent :: Proxy s -> TranslationUnit t -> Token s' -> IO (SourceRange s)+getTokenExtent _ tu t =+ clang_getTokenExtent (unTranslationUnit tu) t >>= peek++-- We deliberately don't export the constructor for UnsafeTokenList.+-- The only way to unwrap it is registerTokenList.+type TokenList s = DVS.Vector (Token s)+instance ClangValueList Token+data UnsafeTokenList = UnsafeTokenList !(Ptr ()) !Int++foreign import ccall unsafe "FFI_stub_ffi.h clang_disposeTokens" clang_disposeTokens :: Ptr () -> Ptr () -> CUInt -> IO ()++disposeTokens :: TranslationUnit s -> TokenList s' -> IO ()+disposeTokens tu tl =+ let (tPtr, n) = fromTokenList tl in+ clang_disposeTokens (unTranslationUnit tu) tPtr (fromIntegral n)++registerTokenList :: ClangBase m => TranslationUnit s' -> IO UnsafeTokenList+ -> ClangT s m (TokenList s)+registerTokenList tu action = do+ (_, tokenList) <- clangAllocate (action >>= tokenListToVector) (disposeTokens tu)+ return tokenList+{-# INLINEABLE registerTokenList #-}++tokenListToVector :: Storable a => UnsafeTokenList -> IO (DVS.Vector a)+tokenListToVector (UnsafeTokenList ts n) = do+ fptr <- newForeignPtr_ (castPtr ts)+ return $ DVS.unsafeFromForeignPtr fptr 0 n+{-# INLINE tokenListToVector #-}++fromTokenList :: TokenList s -> (Ptr (), Int)+fromTokenList ts = let (p, _, _) = DVS.unsafeToForeignPtr ts in+ (castPtr $ Foreign.ForeignPtr.Unsafe.unsafeForeignPtrToPtr p, DVS.length ts)++toTokenList :: (Ptr (), Int) -> UnsafeTokenList+toTokenList (ts, n) = UnsafeTokenList ts n++-- void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,+-- CXToken **Tokens, unsigned *NumTokens);+{# fun clang_tokenize { id `Ptr ()',withVoided* %`SourceRange a', id `Ptr (Ptr ())', alloca- `CUInt' peek* } -> `()'#}+unsafe_tokenize :: TranslationUnit s -> SourceRange s' -> IO UnsafeTokenList+unsafe_tokenize tu sr = do+ tokensPtr <- mallocBytes (sizeOf (undefined :: (Ptr (Ptr (Token ())))))+ numTokens <- clang_tokenize (unTranslationUnit tu) sr (castPtr tokensPtr)+ return (toTokenList (tokensPtr, fromIntegral numTokens))++tokenize :: ClangBase m => TranslationUnit s' -> SourceRange s'' -> ClangT s m (TokenList s)+tokenize tu = registerTokenList tu . unsafe_tokenize tu++-- TODO: test me+-- Note that registerCursorList can be used for the result of this+-- function because it just calls free() to dispose of the list.+--+-- void clang_annotateTokens(CXTranslationUnit TU,+-- CXToken *Tokens, unsigned NumTokens,+-- CXCursor *Cursors);+{# fun clang_annotateTokens { id `Ptr ()', id `Ptr ()', `Int', id `Ptr ()' } -> `()' id#}+unsafe_annotateTokens :: TranslationUnit s -> TokenList s' -> IO UnsafeCursorList+unsafe_annotateTokens tu tl =+ let (tPtr, numTokens) = fromTokenList tl in+ do+ cPtr <- mallocBytes ((sizeOf (undefined :: (Ptr (Cursor ())))) * numTokens)+ clang_annotateTokens (unTranslationUnit tu) tPtr numTokens (castPtr cPtr)+ return (toCursorList (cPtr, numTokens))++annotateTokens :: ClangBase m => TranslationUnit s' -> TokenList s'' -> ClangT s m (CursorList s)+annotateTokens = (registerCursorList .) . unsafe_annotateTokens++-- CXString clang_getCursorKindSpelling(enum CXCursorKind Kind);+{# fun wrapped_clang_getCursorKindSpelling as clang_getCursorKindSpelling { `CInt' } -> `Ptr (ClangString ())' castPtr #}+unsafe_getCursorKindSpelling :: CursorKind -> IO (ClangString ())+unsafe_getCursorKindSpelling ck = clang_getCursorKindSpelling (fromIntegral (fromEnum ck)) >>= peek++getCursorKindSpelling :: ClangBase m => CursorKind -> ClangT s m (ClangString s)+getCursorKindSpelling = registerClangString . unsafe_getCursorKindSpelling++-- void clang_enableStackTraces(void);+foreign import ccall unsafe "clang-c/Index.h clang_enableStackTraces" enableStackTraces :: IO ()++-- typedef void *CXCompletionString;++-- | A semantic string that describes a code completion result.+--+-- A 'CompletionString' describes the formatting of a code completion+-- result as a single \"template\" of text that should be inserted into the+-- source buffer when a particular code completion result is selected.+-- Each semantic string is made up of some number of \"chunks\", each of which+-- contains some text along with a description of what that text means.+--+-- See 'ChunkKind' for more details about the role each kind of chunk plays.+newtype CompletionString s = CompletionString (Ptr ())+ deriving (Eq, Ord, Typeable)++instance ClangValue CompletionString++-- typedef struct {+-- enum CXCursorKind CursorKind;+-- CXCompletionString CompletionString;+-- } CXCompletionResult;+data CompletionResult s = CompletionResult !CursorKind !(CompletionString s)+ deriving (Eq, Ord, Typeable)++instance ClangValue CompletionResult++-- enum CXCompletionChunkKind {+-- CXCompletionChunk_Optional,+-- CXCompletionChunk_TypedText,+-- CXCompletionChunk_Text,+-- CXCompletionChunk_Placeholder,+-- CXCompletionChunk_Informative,+-- CXCompletionChunk_CurrentParameter,+-- CXCompletionChunk_LeftParen,+-- CXCompletionChunk_RightParen,+-- CXCompletionChunk_LeftBracket,+-- CXCompletionChunk_RightBracket,+-- CXCompletionChunk_LeftBrace,+-- CXCompletionChunk_RightBrace,+-- CXCompletionChunk_LeftAngle,+-- CXCompletionChunk_RightAngle,+-- CXCompletionChunk_Comma,+-- CXCompletionChunk_ResultType,+-- CXCompletionChunk_Colon,+-- CXCompletionChunk_SemiColon,+-- CXCompletionChunk_Equal,+-- CXCompletionChunk_HorizontalSpace,+-- CXCompletionChunk_VerticalSpace+-- };++-- | Describes a single piece of text within a code completion string.+--+-- * 'OptionalChunkKind': A code completion string that describes "optional" text that+-- could be a part of the template (but is not required).+-- This is the only kind of chunk that has a code completion+-- string for its representation. The code completion string describes an+-- describes an additional part of the template that is completely optional.+-- For example, optional chunks can be used to describe the placeholders for+-- arguments that match up with defaulted function parameters.+--+-- * 'TypedTextChunkKind': Text that a user would be expected to type to get this+-- code completion result.+-- There will be exactly one \"typed text\" chunk in a semantic string, which+-- will typically provide the spelling of a keyword or the name of a+-- declaration that could be used at the current code point. Clients are+-- expected to filter the code completion results based on the text in this+-- chunk.+--+-- * 'TextChunkKind': Text that should be inserted as part of a code completion result.+-- A \"text\" chunk represents text that is part of the template to be+-- inserted into user code should this particular code completion result+-- be selected.+--+-- * 'PlaceholderChunkKind': Placeholder text that should be replaced by the user.+-- A \"placeholder\" chunk marks a place where the user should insert text+-- into the code completion template. For example, placeholders might mark+-- the function parameters for a function declaration, to indicate that the+-- user should provide arguments for each of those parameters. The actual+-- text in a placeholder is a suggestion for the text to display before+-- the user replaces the placeholder with real code.+--+-- * 'InformativeChunkKind': Informative text that should be displayed but never inserted as+-- part of the template.+-- An \"informative\" chunk contains annotations that can be displayed to+-- help the user decide whether a particular code completion result is the+-- right option, but which is not part of the actual template to be inserted+-- by code completion.+--+-- * 'CurrentParameterChunkKind': Text that describes the current parameter+-- when code completion is referring to a function call, message send, or+-- template specialization.+-- A \"current parameter\" chunk occurs when code completion is providing+-- information about a parameter corresponding to the argument at the+-- code completion point. For example, given a function \"int add(int x, int y);\"+-- and the source code \"add(\", where the code completion point is after the+-- \"(\", the code completion string will contain a \"current parameter\" chunk+-- for \"int x\", indicating that the current argument will initialize that+-- parameter. After typing further, to \"add(17\", (where the code completion+-- point is after the \",\"), the code completion string will contain a+-- \"current parameter\" chunk to \"int y\".+--+-- * 'LeftParenChunkKind': A left parenthesis (\'(\'), used to initiate a function call or+-- signal the beginning of a function parameter list.+--+-- * 'RightParenChunkKind': A right parenthesis (\')\'), used to finish a function call or+-- signal the end of a function parameter list.+--+-- * 'LeftBracketChunkKind': A left bracket (\'[\').+--+-- * 'RightBracketChunkKind': A right bracket (\']\').+--+-- * 'LeftBraceChunkKind': A left brace (\'{\').+--+-- * 'RightBraceChunkKind': A right brace (\'}\').+--+-- * 'LeftAngleChunkKind': A left angle bracket (\'<\').+--+-- * 'RightAngleChunkKind': A right angle bracket (\'>\').+--+-- * 'CommaChunkKind': A comma separator (\',\').+--+-- * 'ResultTypeChunkKind': Text that specifies the result type of a given result.+-- This special kind of informative chunk is not meant to be inserted into+-- the text buffer. Rather, it is meant to illustrate the type that an+-- expression using the given completion string would have.+--+-- * 'ColonChunkKind': A colon (\':\').+--+-- * 'SemiColonChunkKind': A semicolon (\';\').+--+-- * 'EqualChunkKind': An \'=\' sign.+--+-- * 'HorizontalSpaceChunkKind': Horizontal space (\' \').+--+-- * 'VerticalSpaceChunkKind': Vertical space (\'\\n\'), after which it is generally+-- a good idea to perform indentation.+#c+enum ChunkKind+ { OptionalChunkKind = CXCompletionChunk_Optional+ , TypedTextChunkKind = CXCompletionChunk_TypedText+ , TextChunkKind = CXCompletionChunk_Text+ , PlaceholderChunkKind = CXCompletionChunk_Placeholder+ , InformativeChunkKind = CXCompletionChunk_Informative+ , CurrentParameterChunkKind = CXCompletionChunk_CurrentParameter+ , LeftParenChunkKind = CXCompletionChunk_LeftParen+ , RightParenChunkKind = CXCompletionChunk_RightParen+ , LeftBracketChunkKind = CXCompletionChunk_LeftBracket+ , RightBracketChunkKind = CXCompletionChunk_RightBracket+ , LeftBraceChunkKind = CXCompletionChunk_LeftBrace+ , RightBraceChunkKind = CXCompletionChunk_RightBrace+ , LeftAngleChunkKind = CXCompletionChunk_LeftAngle+ , RightAngleChunkKind = CXCompletionChunk_RightAngle+ , CommaChunkKind = CXCompletionChunk_Comma+ , ResultTypeChunkKind = CXCompletionChunk_ResultType+ , ColonChunkKind = CXCompletionChunk_Colon+ , SemiColonChunkKind = CXCompletionChunk_SemiColon+ , EqualChunkKind = CXCompletionChunk_Equal+ , HorizontalSpaceChunkKind = CXCompletionChunk_HorizontalSpace+ , VerticalSpaceChunkKind = CXCompletionChunk_VerticalSpace+ };+#endc+{# enum ChunkKind {} deriving (Bounded, Eq, Ord, Read, Show, Typeable) #}++-- enum CXCompletionChunkKind+-- clang_getCompletionChunkKind(CXCompletionString completion_string,+-- unsigned chunk_number);+{# fun clang_getCompletionChunkKind { id `Ptr ()', `Int'} -> `Int' #}+getCompletionChunkKind :: CompletionString s -> Int -> IO ChunkKind+getCompletionChunkKind (CompletionString ptr) i = clang_getCompletionChunkKind ptr i >>= return . toEnum++-- CXString+-- clang_getCompletionChunkText(CXCompletionString completion_string,+-- unsigned chunk_number);+{# fun wrapped_clang_getCompletionChunkText as clang_getCompletionChunkText { id `Ptr ()' , `Int' } -> `Ptr (ClangString ())' castPtr #}+unsafe_getCompletionChunkText :: CompletionString s -> Int -> IO (ClangString ())+unsafe_getCompletionChunkText (CompletionString ptr) i = clang_getCompletionChunkText ptr i >>= peek++getCompletionChunkText :: ClangBase m => CompletionString s' -> Int -> ClangT s m (ClangString s)+getCompletionChunkText = (registerClangString .) . unsafe_getCompletionChunkText++-- CXCompletionString+-- clang_getCompletionChunkCompletionString(CXCompletionString completion_string,+-- unsigned chunk_number);+{# fun clang_getCompletionChunkCompletionString { id `Ptr ()' , `Int' } -> `Ptr ()' id #}+getCompletionChunkCompletionString :: CompletionString s -> Int -> IO (CompletionString s')+getCompletionChunkCompletionString (CompletionString ptr) i =+ clang_getCompletionChunkCompletionString ptr i >>= return . CompletionString++-- unsigned+-- clang_getNumCompletionChunks(CXCompletionString completion_string);+{# fun clang_getNumCompletionChunks { id `Ptr ()' } -> `Int' #}+getNumCompletionChunks :: CompletionString s -> IO Int+getNumCompletionChunks (CompletionString ptr) = clang_getNumCompletionChunks ptr++-- unsigned+-- clang_getCompletionPriority(CXCompletionString completion_string);+{# fun clang_getCompletionPriority { id `Ptr ()' } -> `Int' #}+getCompletionPriority :: CompletionString s -> IO Int+getCompletionPriority (CompletionString ptr) = clang_getCompletionPriority ptr++-- enum CXAvailabilityKind+-- clang_getCompletionAvailability(CXCompletionString completion_string);+{# fun clang_getCompletionAvailability { id `Ptr ()' } -> `Int' #}+getCompletionAvailability :: CompletionString s -> IO AvailabilityKind+getCompletionAvailability (CompletionString ptr) = clang_getCompletionAvailability ptr >>= return . toEnum++-- unsigned clang_getCompletionNumAnnotations(CXCompletionString completion_string);+{# fun clang_getCompletionNumAnnotations { id `Ptr ()' } -> `Int' #}+getCompletionNumAnnotations :: CompletionString s -> IO Int+getCompletionNumAnnotations (CompletionString ptr) = clang_getCompletionNumAnnotations ptr++-- CXString clang_getCompletionAnnotation(CXCompletionString completion_string,+-- unsigned annotation_number);+{# fun wrapped_clang_getCompletionAnnotation as clang_getCompletionAnnotation { id `Ptr ()' , `Int' } -> `Ptr (ClangString ())' castPtr #}+unsafe_getCompletionAnnotation :: CompletionString s -> Int -> IO (ClangString ())+unsafe_getCompletionAnnotation (CompletionString ptr) i = clang_getCompletionAnnotation ptr i >>= peek++getCompletionAnnotation :: ClangBase m => CompletionString s' -> Int -> ClangT s m (ClangString s)+getCompletionAnnotation = (registerClangString .) . unsafe_getCompletionAnnotation++-- CXString clang_getCompletionParent(CXCompletionString completion_string,+-- enum CXCursorKind *kind);+{# fun wrapped_clang_getCompletionParent as clang_getCompletionParent { id `Ptr ()' , `CInt' } -> `Ptr (ClangString ())' castPtr #}+unsafe_getCompletionParent :: CompletionString s -> IO (ClangString ())+unsafe_getCompletionParent (CompletionString ptr) = clang_getCompletionParent ptr 0 >>= peek++getCompletionParent :: ClangBase m => CompletionString s' -> ClangT s m (ClangString s)+getCompletionParent = registerClangString . unsafe_getCompletionParent++-- CXString clang_getCompletionBriefComment(CXCompletionString completion_string);+{# fun wrapped_clang_getCompletionBriefComment as clang_getCompletionBriefComment { id `Ptr ()' } -> `Ptr (ClangString ())' castPtr #}+unsafe_getCompletionBriefComment :: CompletionString s -> IO (ClangString ())+unsafe_getCompletionBriefComment (CompletionString ptr) = clang_getCompletionBriefComment ptr >>= peek++getCompletionBriefComment :: ClangBase m => CompletionString s' -> ClangT s m (ClangString s)+getCompletionBriefComment = registerClangString . unsafe_getCompletionBriefComment++-- CXCompletionString clang_getCursorCompletionString(CXCursor cursor);+{# fun clang_getCursorCompletionString {withVoided* %`Cursor a' } -> `Ptr (ClangString ())' castPtr #}+unsafe_getCursorCompletionString :: Cursor s' -> IO (ClangString ())+unsafe_getCursorCompletionString c =+ clang_getCursorCompletionString c >>= peek++getCursorCompletionString :: ClangBase m => Cursor s' -> ClangT s m (CompletionString s)+getCursorCompletionString c =+ unsafeCoerce <$> (liftIO $ unsafe_getCursorCompletionString c)++-- enum CXCodeComplete_Flags {+-- CXCodeComplete_IncludeMacros = 0x01,+-- CXCodeComplete_IncludeCodePatterns = 0x02,+-- CXCodeComplete_IncludeBriefComments = 0x04+-- };++-- | Flags that can be used to modify the behavior of 'codeCompleteAt'.+--+-- * 'IncludeMacros': Whether to include macros within the set of code+-- completions returned.+--+-- * 'IncludeCodePatterns': Whether to include code patterns for language constructs+-- within the set of code completions, e.g., 'for' loops.+--+-- * 'IncludeBriefComments': Whether to include brief documentation within the set of code+-- completions returned.+#c+enum CodeCompleteFlags+ { IncludeMacros = CXCodeComplete_IncludeMacros+ , IncludeCodePatterns = CXCodeComplete_IncludeCodePatterns+ , IncludeBriefComments = CXCodeComplete_IncludeBriefComments+ };+#endc+{# enum CodeCompleteFlags {} deriving (Bounded, Eq, Ord, Read, Show, Typeable) #}++instance BitFlags CodeCompleteFlags where+ toBit IncludeMacros = 0x01+ toBit IncludeCodePatterns = 0x02+ toBit IncludeBriefComments = 0x04++-- unsigned clang_defaultCodeCompleteOptions(void);+{# fun clang_defaultCodeCompleteOptions as defaultCodeCompleteOptions {} -> `Int' #}++-- typedef struct {+-- CXCompletionResult *Results;+-- unsigned NumResults;+-- } CXCodeCompleteResults;++-- | The results of code completion.+newtype CodeCompleteResults s = CodeCompleteResults { unCodeCompleteResults :: Ptr () }+ deriving (Eq, Ord, Typeable)++instance ClangValue CodeCompleteResults++-- void clang_disposeCodeCompleteResults(CXCodeCompleteResults *Results);+{# fun clang_disposeCodeCompleteResults { id `Ptr ()' } -> `()' #}+disposeCodeCompleteResults :: CodeCompleteResults s -> IO ()+disposeCodeCompleteResults rs = clang_disposeCodeCompleteResults (unCodeCompleteResults rs)++registerCodeCompleteResults :: ClangBase m => IO (CodeCompleteResults ())+ -> ClangT s m (CodeCompleteResults s)+registerCodeCompleteResults action = do+ (_, ccrs) <- clangAllocate (action >>= return . unsafeCoerce)+ disposeCodeCompleteResults+ return ccrs+{-# INLINEABLE registerCodeCompleteResults #-}++-- CXCodeCompleteResults *clang_codeCompleteAt(CXTranslationUnit TU,+-- const char *complete_filename,+-- unsigned complete_line,+-- unsigned complete_column,+-- struct CXUnsavedFile *unsaved_files,+-- unsigned num_unsaved_files,+-- unsigned options);+{# fun clang_codeCompleteAt { id `Ptr ()', `CString', `Int', `Int', id `Ptr ()', `Int', `Int' } -> `Ptr ()' id #}+unsafe_codeCompleteAt :: TranslationUnit s -> String -> Int -> Int -> Ptr CUnsavedFile -> Int -> Int -> IO (CodeCompleteResults ())+unsafe_codeCompleteAt tu s i1 i2 ufs nufs i3 =+ withCString s (\sPtr -> clang_codeCompleteAt (unTranslationUnit tu) sPtr i1 i2 (castPtr ufs) nufs i3 >>= return . CodeCompleteResults)++codeCompleteAt :: ClangBase m => TranslationUnit s' -> String -> Int -> Int+ -> DV.Vector UnsavedFile -> Int -> ClangT s m (CodeCompleteResults s)+codeCompleteAt tu f l c ufs os =+ registerCodeCompleteResults $+ withUnsavedFiles ufs $ \ufsPtr ufsLen ->+ unsafe_codeCompleteAt tu f l c ufsPtr ufsLen os++-- This function, along with codeCompleteGetResult, exist to allow iteration over+-- the completion strings at the Haskell level. They're (obviously) not real+-- libclang functions.+{# fun codeCompleteGetNumResults as codeCompleteGetNumResults' { id `Ptr ()' } -> `Int' #}+codeCompleteGetNumResults :: CodeCompleteResults s -> IO Int+codeCompleteGetNumResults rs = codeCompleteGetNumResults' (unCodeCompleteResults rs)++-- We don't need to register CompletionStrings; they're always owned by another object.+-- They still need to be scoped, though.+{# fun codeCompleteGetResult as codeCompleteGetResult' { id `Ptr ()', `CInt', id `Ptr (Ptr ())' } -> `CInt' id #}+unsafe_codeCompleteGetResult :: CodeCompleteResults s -> Int -> IO (CompletionString (), CursorKind)+unsafe_codeCompleteGetResult rs idx = do+ sPtr <- mallocBytes (sizeOf (undefined :: (Ptr (Ptr ()))))+ kind <- codeCompleteGetResult' (unCodeCompleteResults rs) (fromIntegral idx) (castPtr sPtr)+ return ((CompletionString sPtr), toEnum (fromIntegral kind))++codeCompleteGetResult :: ClangBase m => CodeCompleteResults s' -> Int+ -> ClangT s m (CompletionString s, CursorKind)+codeCompleteGetResult rs n = do+ (string, kind) <- liftIO $ unsafe_codeCompleteGetResult rs n+ return (unsafeCoerce string, kind)++-- void clang_sortCodeCompletionResults(CXCompletionResult *Results,+-- unsigned NumResults);+{# fun clang_sortCodeCompletionResults { id `Ptr ()', `Int' } -> `()' #}+sortCodeCompletionResults :: CodeCompleteResults s -> IO ()+sortCodeCompletionResults rs =+ let results = unCodeCompleteResults rs in+ do+ rPtr <- peek (results `plusPtr` offsetCXCodeCompleteResultsResults)+ numRs <- peek (results `plusPtr` offsetCXCodeCompleteResultsNumResults)+ clang_sortCodeCompletionResults rPtr numRs++-- unsigned clang_codeCompleteGetNumDiagnostics(CXCodeCompleteResults *Results);+{# fun clang_codeCompleteGetNumDiagnostics { id `Ptr ()' } -> `Int' #}+codeCompleteGetNumDiagnostics :: CodeCompleteResults s -> IO Int+codeCompleteGetNumDiagnostics rs = clang_codeCompleteGetNumDiagnostics (unCodeCompleteResults rs)++-- CXDiagnostic clang_codeCompleteGetDiagnostic(CXCodeCompleteResults *Results,+-- unsigned Index);+{# fun clang_codeCompleteGetDiagnostic { id `Ptr ()' , `Int' } -> `Ptr ()' id #}+unsafe_codeCompleteGetDiagnostic :: CodeCompleteResults s -> Int -> IO (Diagnostic ())+unsafe_codeCompleteGetDiagnostic rs idx =+ clang_codeCompleteGetDiagnostic (unCodeCompleteResults rs) idx >>= return . mkDiagnostic++codeCompleteGetDiagnostic :: ClangBase m => CodeCompleteResults s' -> Int+ -> ClangT s m (Diagnostic s)+codeCompleteGetDiagnostic = (registerDiagnostic .) . unsafe_codeCompleteGetDiagnostic++-- enum CXCompletionContext {+-- CXCompletionContext_Unexposed = 0,+-- CXCompletionContext_AnyType = 1 << 0,+-- CXCompletionContext_AnyValue = 1 << 1,+-- CXCompletionContext_ObjCObjectValue = 1 << 2,+-- CXCompletionContext_ObjCSelectorValue = 1 << 3,+-- CXCompletionContext_CXXClassTypeValue = 1 << 4,+-- CXCompletionContext_DotMemberAccess = 1 << 5,+-- CXCompletionContext_ArrowMemberAccess = 1 << 6,+-- CXCompletionContext_ObjCPropertyAccess = 1 << 7,+-- CXCompletionContext_EnumTag = 1 << 8,+-- CXCompletionContext_UnionTag = 1 << 9,+-- CXCompletionContext_StructTag = 1 << 10,+-- CXCompletionContext_ClassTag = 1 << 11,+-- CXCompletionContext_Namespace = 1 << 12,+-- CXCompletionContext_NestedNameSpecifier = 1 << 13,+-- CXCompletionContext_ObjCInterface = 1 << 14,+-- CXCompletionContext_ObjCProtocol = 1 << 15,+-- CXCompletionContext_ObjCCategory = 1 << 16,+-- CXCompletionContext_ObjCInstanceMessage = 1 << 17,+-- CXCompletionContext_ObjCClassMessage = 1 << 18,+-- CXCompletionContext_ObjCSelectorName = 1 << 19,+-- CXCompletionContext_MacroName = 1 << 20,+-- CXCompletionContext_NaturalLanguage = 1 << 21,+-- CXCompletionContext_Unknown = ((1 << 22) - 1) -- Set all+ -- contexts... Not a real value.+-- };++-- | Contexts under which completion may occur. Multiple contexts may be+-- present at the same time.+--+-- * 'UnexposedCompletionContext': The context for completions is unexposed,+-- as only Clang results should be included.+--+-- * 'AnyTypeCompletionContext': Completions for any possible type should be+-- included in the results.+--+-- * 'AnyValueCompletionContext': Completions for any possible value (variables,+-- function calls, etc.) should be included in the results.+--+-- * 'ObjCObjectValueCompletionContext': Completions for values that resolve to+-- an Objective-C object should be included in the results.+--+-- * 'ObjCSelectorValueCompletionContext': Completions for values that resolve+-- to an Objective-C selector should be included in the results.+--+-- * 'CXXClassTypeValueCompletionContext': Completions for values that resolve+-- to a C++ class type should be included in the results.+--+-- * 'DotMemberAccessCompletionContext': Completions for fields of the member+-- being accessed using the dot operator should be included in the results.+--+-- * 'ArrowMemberAccessCompletionContext': Completions for fields of the member+-- being accessed using the arrow operator should be included in the results.+--+-- * 'ObjCPropertyAccessCompletionContext': Completions for properties of the+-- Objective-C object being accessed using the dot operator should be included in the results.+--+-- * 'EnumTagCompletionContext': Completions for enum tags should be included in the results.+--+-- * 'UnionTagCompletionContext': Completions for union tags should be included in the results.+--+-- * 'StructTagCompletionContext': Completions for struct tags should be included in the+-- results.+--+-- * 'ClassTagCompletionContext': Completions for C++ class names should be included in the+-- results.+--+-- * 'NamespaceCompletionContext': Completions for C++ namespaces and namespace aliases should+-- be included in the results.+--+-- * 'NestedNameSpecifierCompletionContext': Completions for C++ nested name specifiers should+-- be included in the results.+--+-- * 'ObjCInterfaceCompletionContext': Completions for Objective-C interfaces (classes) should+-- be included in the results.+--+-- * 'ObjCProtocolCompletionContext': Completions for Objective-C protocols should be included+-- in the results.+--+-- * 'ObjCCategoryCompletionContext': Completions for Objective-C categories should be included+-- in the results.+--+-- * 'ObjCInstanceMessageCompletionContext': Completions for Objective-C instance messages+-- should be included in the results.+--+-- * 'ObjCClassMessageCompletionContext': Completions for Objective-C class messages should be+-- included in the results.+--+-- * 'ObjCSelectorNameCompletionContext': Completions for Objective-C selector names should be+-- included in the results.+--+-- * 'MacroNameCompletionContext': Completions for preprocessor macro names should be included+-- in the results.+--+-- * 'NaturalLanguageCompletionContext': Natural language completions should be included in the+-- results.+#c+enum CompletionContext+ { UnexposedCompletionContext = CXCompletionContext_Unexposed+ , AnyTypeCompletionContext = CXCompletionContext_AnyType+ , AnyValueCompletionContext = CXCompletionContext_AnyValue+ , ObjCObjectValueCompletionContext = CXCompletionContext_ObjCObjectValue+ , ObjCSelectorValueCompletionContext = CXCompletionContext_ObjCSelectorValue+ , CXXClassTypeValueCompletionContext = CXCompletionContext_CXXClassTypeValue+ , DotMemberAccessCompletionContext = CXCompletionContext_DotMemberAccess+ , ArrowMemberAccessCompletionContext = CXCompletionContext_ArrowMemberAccess+ , ObjCPropertyAccessCompletionContext = CXCompletionContext_ObjCPropertyAccess+ , EnumTagCompletionContext = CXCompletionContext_EnumTag+ , UnionTagCompletionContext = CXCompletionContext_UnionTag+ , StructTagCompletionContext = CXCompletionContext_StructTag+ , ClassTagCompletionContext = CXCompletionContext_ClassTag+ , NamespaceCompletionContext = CXCompletionContext_Namespace+ , NestedNameSpecifierCompletionContext = CXCompletionContext_NestedNameSpecifier+ , ObjCInterfaceCompletionContext = CXCompletionContext_ObjCInterface+ , ObjCProtocolCompletionContext = CXCompletionContext_ObjCProtocol+ , ObjCCategoryCompletionContext = CXCompletionContext_ObjCCategory+ , ObjCInstanceMessageCompletionContext = CXCompletionContext_ObjCInstanceMessage+ , ObjCClassMessageCompletionContext = CXCompletionContext_ObjCClassMessage+ , ObjCSelectorNameCompletionContext = CXCompletionContext_ObjCSelectorName+ , MacroNameCompletionContext = CXCompletionContext_MacroName+ , NaturalLanguageCompletionContext = CXCompletionContext_NaturalLanguage+ };+#endc+{# enum CompletionContext {} deriving (Bounded, Eq, Ord, Read, Show, Typeable) #}++instance BitFlags CompletionContext where+ type FlagInt CompletionContext = Int64+ toBit UnexposedCompletionContext = 0x0+ toBit AnyTypeCompletionContext = 0x1+ toBit AnyValueCompletionContext = 0x2+ toBit ObjCObjectValueCompletionContext = 0x4+ toBit ObjCSelectorValueCompletionContext = 0x8+ toBit CXXClassTypeValueCompletionContext = 0x10+ toBit DotMemberAccessCompletionContext = 0x20+ toBit ArrowMemberAccessCompletionContext = 0x40+ toBit ObjCPropertyAccessCompletionContext = 0x80+ toBit EnumTagCompletionContext = 0x100+ toBit UnionTagCompletionContext = 0x200+ toBit StructTagCompletionContext = 0x400+ toBit ClassTagCompletionContext = 0x800+ toBit NamespaceCompletionContext = 0x1000+ toBit NestedNameSpecifierCompletionContext = 0x2000+ toBit ObjCInterfaceCompletionContext = 0x4000+ toBit ObjCProtocolCompletionContext = 0x8000+ toBit ObjCCategoryCompletionContext = 0x10000+ toBit ObjCInstanceMessageCompletionContext = 0x20000+ toBit ObjCClassMessageCompletionContext = 0x40000+ toBit ObjCSelectorNameCompletionContext = 0x80000+ toBit MacroNameCompletionContext = 0x100000+ toBit NaturalLanguageCompletionContext = 0x200000++-- unsigned long long clang_codeCompleteGetContexts(CXCodeCompleteResults *Results);+{# fun clang_codeCompleteGetContexts { id `Ptr ()' } -> `Int64' #}+codeCompleteGetContexts :: CodeCompleteResults s -> IO Int64+codeCompleteGetContexts rs = clang_codeCompleteGetContexts (unCodeCompleteResults rs)++-- enum CXCursorKind clang_codeCompleteGetContainerKind(CXCodeCompleteResults *Results,+-- unsigned *IsIncomplete);+{# fun clang_codeCompleteGetContainerKind { id `Ptr ()', id `Ptr CUInt' } -> `Int' #}+codeCompleteGetContainerKind :: CodeCompleteResults s -> IO (CursorKind, Bool)+codeCompleteGetContainerKind rs =+ alloca (\(iPtr :: (Ptr CUInt)) -> do+ k <- clang_codeCompleteGetContainerKind (unCodeCompleteResults rs) iPtr+ bool <- peek iPtr+ return (toEnum k, toBool ((fromIntegral bool) :: Int)))++-- CXString clang_codeCompleteGetContainerUSR(CXCodeCompleteResults *Results);+{# fun clang_codeCompleteGetContainerUSR { id `Ptr ()' } -> `Ptr (ClangString ())' castPtr #}+unsafe_codeCompleteGetContainerUSR :: CodeCompleteResults s -> IO (ClangString ())+unsafe_codeCompleteGetContainerUSR rs = clang_codeCompleteGetContainerUSR (unCodeCompleteResults rs) >>= peek++codeCompleteGetContainerUSR :: ClangBase m => CodeCompleteResults s' -> ClangT s m (ClangString s)+codeCompleteGetContainerUSR = registerClangString . unsafe_codeCompleteGetContainerUSR++-- CXString clang_codeCompleteGetObjCSelector(CXCodeCompleteResults *Results);+{# fun clang_codeCompleteGetObjCSelector { id `Ptr ()' } -> `Ptr (ClangString ())' castPtr #}+unsafe_codeCompleteGetObjCSelector :: CodeCompleteResults s -> IO (ClangString ())+unsafe_codeCompleteGetObjCSelector rs = clang_codeCompleteGetObjCSelector (unCodeCompleteResults rs) >>= peek++codeCompleteGetObjCSelector :: ClangBase m => CodeCompleteResults s' -> ClangT s m (ClangString s)+codeCompleteGetObjCSelector = registerClangString . unsafe_codeCompleteGetObjCSelector++-- CXString clang_getClangVersion();+{# fun wrapped_clang_getClangVersion as clang_getClangVersion {} -> `Ptr (ClangString ())' castPtr #}+unsafe_getClangVersion :: IO (ClangString ())+unsafe_getClangVersion = clang_getClangVersion >>= peek++getClangVersion :: ClangBase m => ClangT s m (ClangString s)+getClangVersion = registerClangString $ unsafe_getClangVersion++-- -- void clang_toggleCrashRecovery(unsigned isEnabled);+{# fun clang_toggleCrashRecovery as toggleCrashRecovery' { `Int' } -> `()' #}+toggleCrashRecovery :: Bool -> IO ()+toggleCrashRecovery b = toggleCrashRecovery' (fromBool b)++data Inclusion s = Inclusion !(File s) !(SourceLocation s) !Bool+ deriving (Eq, Ord, Typeable)++instance ClangValue Inclusion++instance Storable (Inclusion s) where+ sizeOf _ = sizeOfInclusion+ {-# INLINE sizeOf #-}++ alignment _ = alignOfInclusion+ {-# INLINE alignment #-}++ peek p = do+ let fromCUChar = fromIntegral :: Num b => CUChar -> b+ file <- File <$> peekByteOff p offsetInclusionInclusion+ sl <- peekByteOff p offsetInclusionLocation+ isDirect :: Int <- fromCUChar <$> peekByteOff p offsetInclusionIsDirect+ return $! Inclusion file sl (if isDirect == 0 then False else True)+ {-# INLINE peek #-}++ poke p (Inclusion (File file) sl isDirect) = do+ let toCUChar = fromIntegral :: Integral a => a -> CUChar+ pokeByteOff p offsetInclusionInclusion file+ pokeByteOff p offsetInclusionLocation sl+ pokeByteOff p offsetInclusionIsDirect+ (toCUChar $ if isDirect then 1 :: Int else 0)+ {-# INLINE poke #-}++type InclusionList s = DVS.Vector (Inclusion s)+instance ClangValueList Inclusion+data UnsafeInclusionList = UnsafeInclusionList !(Ptr ()) !Int++-- void freeInclusions(struct Inclusion* inclusions);+{# fun freeInclusionList as freeInclusionList' { id `Ptr ()' } -> `()' #}+freeInclusions :: InclusionList s -> IO ()+freeInclusions is =+ let (isPtr, n) = fromInclusionList is in+ freeInclusionList' isPtr++registerInclusionList :: ClangBase m => IO UnsafeInclusionList -> ClangT s m (InclusionList s)+registerInclusionList action = do+ (_, inclusionList) <- clangAllocate (action >>= mkSafe) freeInclusions+ return inclusionList+ where+ mkSafe (UnsafeInclusionList is n) = do+ fptr <- newForeignPtr_ (castPtr is)+ return $ DVS.unsafeFromForeignPtr fptr 0 n+{-# INLINEABLE registerInclusionList #-}++fromInclusionList :: InclusionList s -> (Ptr (), Int)+fromInclusionList is = let (p, _, _) = DVS.unsafeToForeignPtr is in+ (castPtr $ Foreign.ForeignPtr.Unsafe.unsafeForeignPtrToPtr p, DVS.length is)++toInclusionList :: (Ptr (), Int) -> UnsafeInclusionList+toInclusionList (is, n) = UnsafeInclusionList is n++#c+typedef Inclusion** PtrPtrInclusion;+#endc++-- A more efficient alternative to clang_getInclusions.+-- void getInclusions(CXTranslationUnit tu, struct Inclusion** inclusionsOut, unsigned* countOut)+{# fun getInclusions as getInclusions' { id `Ptr ()', id `Ptr (Ptr ())', alloca- `CUInt' peek* } -> `()' #}+unsafe_getInclusions :: TranslationUnit s -> IO UnsafeInclusionList+unsafe_getInclusions tu = do+ iPtrPtr <- mallocBytes {#sizeof PtrPtrInclusion #}+ n <- getInclusions' (unTranslationUnit tu) (castPtr iPtrPtr)+ firstInclusion <- peek (castPtr iPtrPtr :: Ptr (Ptr ()))+ free iPtrPtr+ return (toInclusionList (firstInclusion, fromIntegral n))+++getInclusions :: ClangBase m => TranslationUnit s' -> ClangT s m (InclusionList s)+getInclusions = registerInclusionList . unsafe_getInclusions++-- typedef void* CXRemapping;+newtype Remapping s = Remapping { unRemapping :: Ptr () }+ deriving (Eq, Ord, Typeable)++instance ClangValue Remapping++mkRemapping :: Ptr () -> Remapping ()+mkRemapping = Remapping++-- void clang_remap_dispose(CXRemapping);+{# fun clang_remap_dispose { id `Ptr ()' } -> `()' #}+remap_dispose :: Remapping s -> IO ()+remap_dispose d = clang_remap_dispose (unRemapping d)++registerRemapping :: ClangBase m => IO (Remapping ()) -> ClangT s m (Remapping s)+registerRemapping action = do+ (_, idx) <- clangAllocate (action >>= return . unsafeCoerce)+ (\i -> remap_dispose i)+ return idx+{-# INLINEABLE registerRemapping #-}++-- %dis remapping i = <unRemapping/mkRemapping> (ptr i)++maybeRemapping :: Remapping s' -> Maybe (Remapping s)+maybeRemapping (Remapping p) | p == nullPtr = Nothing+maybeRemapping f = Just (unsafeCoerce f)++unMaybeRemapping :: Maybe (Remapping s') -> Remapping s+unMaybeRemapping (Just f) = unsafeCoerce f+unMaybeRemapping Nothing = Remapping nullPtr++-- CXRemapping clang_getRemappings(const char *path);+{# fun clang_getRemappings { `CString' } -> `Ptr ()' id #}+unsafe_getRemappings :: FilePath -> IO (Maybe (Remapping ()))+unsafe_getRemappings fp =+ withCString fp (\sPtr -> clang_getRemappings sPtr >>= return . maybeRemapping . mkRemapping )++getRemappings :: ClangBase m => FilePath -> ClangT s m (Maybe (Remapping s))+getRemappings path = do+ mRemappings <- liftIO $ unsafe_getRemappings path+ case mRemappings of+ Just remappings -> Just <$> registerRemapping (return remappings)+ Nothing -> return Nothing++-- CXRemapping clang_getRemappingsFromFileList(const char **filePaths, unsigned numFiles);+{# fun clang_getRemappingsFromFileList { id `Ptr CString' , `Int' } -> `Ptr ()' id #}+unsafe_getRemappingsFromFileList :: Ptr CString -> Int -> IO (Maybe (Remapping ()))+unsafe_getRemappingsFromFileList paths numPaths =+ clang_getRemappingsFromFileList paths numPaths >>= return . maybeRemapping . mkRemapping++getRemappingsFromFileList :: ClangBase m => [FilePath] -> ClangT s m (Maybe (Remapping s))+getRemappingsFromFileList paths = do+ mRemappings <- liftIO $ withStringList paths unsafe_getRemappingsFromFileList+ case mRemappings of+ Just remappings -> Just <$> registerRemapping (return remappings)+ Nothing -> return Nothing++-- unsigned clang_remap_getNumFiles(CXRemapping);+{# fun clang_remap_getNumFiles { id `Ptr ()' } -> `Int' #}+remap_getNumFiles :: Remapping s -> IO Int+remap_getNumFiles remaps =+ clang_remap_getNumFiles (unRemapping remaps)++-- void clang_remap_getFilenames(CXRemapping, unsigned index,+-- CXString *original, CXString *transformed);+{# fun clang_remap_getFilenames { id `Ptr ()', `Int', id `Ptr ()', id `Ptr ()' } -> `()' #}+unsafe_remap_getFilenames :: Remapping s -> Int -> IO (ClangString (), ClangString ())+unsafe_remap_getFilenames remaps idx = do+ origPtr <- mallocBytes (sizeOf (undefined :: (Ptr (ClangString ()))))+ txPtr <- mallocBytes (sizeOf (undefined :: (Ptr (ClangString ()))))+ clang_remap_getFilenames (unRemapping remaps) idx origPtr txPtr+ orig <- peek (castPtr origPtr)+ tx <- peek (castPtr txPtr)+ free origPtr+ free txPtr+ return (orig, tx)++remap_getFilenames :: ClangBase m => Remapping s' -> Int -> ClangT s m (ClangString s, ClangString s)+remap_getFilenames r idx = do+ (orig, tr) <- liftIO $ unsafe_remap_getFilenames r idx+ (,) <$> registerClangString (return orig) <*> registerClangString (return tr)
+ src/Clang/Internal/FFIConstants.hsc view
@@ -0,0 +1,161 @@+{-# OPTIONS_GHC -fno-warn-missing-signatures #-}++module Clang.Internal.FFIConstants+( sizeOfCXCursor+, alignOfCXCursor+, offsetCXCursorKind+, offsetCXCursorXData+, offsetCXCursorP1+, offsetCXCursorP2+, offsetCXCursorP3+, sizeOfParentedCursor+, alignOfParentedCursor+, offsetParentedCursorParent+, offsetParentedCursorCursor+, sizeOfInclusion+, alignOfInclusion+, offsetInclusionInclusion+, offsetInclusionLocation+, offsetInclusionIsDirect+, sizeOfCXSourceLocation+, alignOfCXSourceLocation+, offsetCXSourceLocationP1+, offsetCXSourceLocationP2+, offsetCXSourceLocationData+, sizeOfCXSourceRange+, alignOfCXSourceRange+, offsetCXSourceRangeP1+, offsetCXSourceRangeP2+, offsetCXSourceRangeBegin+, offsetCXSourceRangeEnd+, sizeOfCXToken+, alignOfCXToken+, offsetCXTokenI1+, offsetCXTokenI2+, offsetCXTokenI3+, offsetCXTokenI4+, offsetCXTokenData+, sizeOfCXUnsavedFile+, alignOfCXUnsavedFile+, offsetCXUnsavedFileFilename+, offsetCXUnsavedFileContents+, offsetCXUnsavedFileContentsLen+, sizeOfCXComment+, alignOfCXComment+, offsetCXCommentASTNode+, offsetCXCommentTranslationUnit+, sizeOfCXVersion+, alignOfCXVersion+, offsetCXVersionMajor+, offsetCXVersionMinor+, offsetCXVersionSubminor+, sizeOfCXString+, alignOfCXString+, offsetCXStringData+, offsetCXStringFlags+, sizeOfCXPlatformAvailability+, alignOfCXPlatformAvailability+, offsetCXPlatformAvailabilityPlatform+, offsetCXPlatformAvailabilityIntroduced+, offsetCXPlatformAvailabilityDeprecated+, offsetCXPlatformAvailabilityObsoleted+, offsetCXPlatformAvailabilityUnavailable+, offsetCXPlatformAvailabilityMessage+, sizeOfCXCodeCompleteResults+, alignOfCXCodeCompleteResults+, offsetCXCodeCompleteResultsResults+, offsetCXCodeCompleteResultsNumResults+) where++#include <stddef.h>+#include "clang-c/Index.h"+#include "clang-c/Documentation.h"+#include "visitors.h"++-- CXCursor constants.+sizeOfCXCursor = (#const sizeof(CXCursor)) :: Int+alignOfCXCursor = (#const 4) :: Int -- in C11, could use alignof()+offsetCXCursorKind = (#const offsetof(CXCursor, kind)) :: Int+offsetCXCursorXData = (#const offsetof(CXCursor, xdata)) :: Int+offsetCXCursorP1 = (#const offsetof(CXCursor, data)) :: Int+offsetCXCursorP2 = (#const offsetof(CXCursor, data) + sizeof(void*)) :: Int+offsetCXCursorP3 = (#const offsetof(CXCursor, data) + 2 * sizeof(void*)) :: Int++-- ParentedCursor constants.+sizeOfParentedCursor = (#const sizeof(ParentedCursor)) :: Int+alignOfParentedCursor = (#const 4) :: Int+offsetParentedCursorParent = (#const offsetof(ParentedCursor, parent)) :: Int+offsetParentedCursorCursor = (#const offsetof(ParentedCursor, cursor)) :: Int++-- Inclusion constants.+sizeOfInclusion = (#const sizeof(Inclusion)) :: Int+alignOfInclusion = (#const 4) :: Int+offsetInclusionInclusion = (#const offsetof(Inclusion, inclusion)) :: Int+offsetInclusionLocation = (#const offsetof(Inclusion, location)) :: Int+offsetInclusionIsDirect = (#const offsetof(Inclusion, isDirect)) :: Int++-- SourceLocation constants.+sizeOfCXSourceLocation = (#const sizeof(CXSourceLocation)) :: Int+alignOfCXSourceLocation = (#const 4) :: Int+offsetCXSourceLocationP1 = (#const offsetof(CXSourceLocation, ptr_data)) :: Int+offsetCXSourceLocationP2 = (#const offsetof(CXSourceLocation, ptr_data) + sizeof(void*)) :: Int+offsetCXSourceLocationData = (#const offsetof(CXSourceLocation, int_data)) :: Int++-- SourceRange constants.+sizeOfCXSourceRange = (#const sizeof(CXSourceRange)) :: Int+alignOfCXSourceRange = (#const 4) :: Int+offsetCXSourceRangeP1 = (#const offsetof(CXSourceRange, ptr_data)) :: Int+offsetCXSourceRangeP2 = (#const offsetof(CXSourceRange, ptr_data) + sizeof(void*)) :: Int+offsetCXSourceRangeBegin= (#const offsetof(CXSourceRange, begin_int_data)) :: Int+offsetCXSourceRangeEnd = (#const offsetof(CXSourceRange, end_int_data) + sizeof(unsigned)) :: Int++-- CXToken constants.+sizeOfCXToken = (#const sizeof(CXToken)) :: Int+alignOfCXToken = (#const 4) :: Int+offsetCXTokenI1 = (#const offsetof(CXToken, int_data)) :: Int+offsetCXTokenI2 = (#const offsetof(CXToken, int_data) + sizeof(unsigned)) :: Int+offsetCXTokenI3 = (#const offsetof(CXToken, int_data) + 2 * sizeof(unsigned)) :: Int+offsetCXTokenI4 = (#const offsetof(CXToken, int_data) + 3 * sizeof(unsigned)) :: Int+offsetCXTokenData = (#const offsetof(CXToken, ptr_data)) :: Int++-- CXUnsavedFile constants.+sizeOfCXUnsavedFile = (#const sizeof(struct CXUnsavedFile)) :: Int+alignOfCXUnsavedFile = (#const 4) :: Int+offsetCXUnsavedFileFilename = (#const offsetof(struct CXUnsavedFile, Filename)) :: Int+offsetCXUnsavedFileContents = (#const offsetof(struct CXUnsavedFile, Contents)) :: Int+offsetCXUnsavedFileContentsLen = (#const offsetof(struct CXUnsavedFile, Length)) :: Int++-- CXComment constants.+sizeOfCXComment = (#const sizeof(CXComment)) :: Int+alignOfCXComment = (#const 4) :: Int+offsetCXCommentASTNode = (#const offsetof(CXComment, ASTNode)) :: Int+offsetCXCommentTranslationUnit = (#const offsetof(CXComment, TranslationUnit)) :: Int++-- CXVersion constants.+sizeOfCXVersion = (#const sizeof(CXVersion)) :: Int+alignOfCXVersion = (#const 4) :: Int+offsetCXVersionMajor = (#const offsetof(CXVersion, Major)) :: Int+offsetCXVersionMinor = (#const offsetof(CXVersion, Minor)) :: Int+offsetCXVersionSubminor = (#const offsetof(CXVersion, Subminor)) :: Int++-- CXString constants.+sizeOfCXString = (#const sizeof(CXString)) :: Int+alignOfCXString = (#const 4) :: Int+offsetCXStringData = (#const offsetof(CXString, data)) :: Int+offsetCXStringFlags = (#const offsetof(CXString, private_flags)) :: Int++-- CXPlatformAvailability constants.+sizeOfCXPlatformAvailability = (#const sizeof(CXPlatformAvailability)) :: Int+alignOfCXPlatformAvailability = (#const 4) :: Int+offsetCXPlatformAvailabilityPlatform = (#const offsetof(CXPlatformAvailability, Platform)) :: Int+offsetCXPlatformAvailabilityIntroduced = (#const offsetof(CXPlatformAvailability, Introduced)) :: Int+offsetCXPlatformAvailabilityDeprecated = (#const offsetof(CXPlatformAvailability, Deprecated)) :: Int+offsetCXPlatformAvailabilityObsoleted = (#const offsetof(CXPlatformAvailability, Obsoleted)) :: Int+offsetCXPlatformAvailabilityUnavailable = (#const offsetof(CXPlatformAvailability, Unavailable)) :: Int+offsetCXPlatformAvailabilityMessage = (#const offsetof(CXPlatformAvailability, Message)) :: Int++-- CXCodeCompleteResults constants.+sizeOfCXCodeCompleteResults = (#const sizeof(CXString)) :: Int+alignOfCXCodeCompleteResults = (#const 4) :: Int+offsetCXCodeCompleteResultsResults = (#const offsetof(CXCodeCompleteResults, Results)) :: Int+offsetCXCodeCompleteResultsNumResults = (#const offsetof(CXCodeCompleteResults, NumResults)) :: Int
+ src/Clang/Internal/Monad.hs view
@@ -0,0 +1,81 @@+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE EmptyDataDecls #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE ImpredicativeTypes #-}++module Clang.Internal.Monad+( ClangT+, ClangBase+, ClangValue(..)+, ClangValueList(..)+, Proxy+, runClangT+, clangScope+, clangAllocate+, mkProxy+) where++import Control.Applicative+import Control.Monad.Base+import Control.Monad.Trans+import Control.Monad.Trans.Resource+import qualified Data.Vector.Storable as DVS+import Unsafe.Coerce (unsafeCoerce) -- With GHC 7.8 we can use the safer 'coerce'.++newtype ClangT s m a = ClangT+ { unClangT :: ResourceT m a+ } deriving (Applicative, Functor, Monad, MonadIO, MonadThrow, MonadTrans)++instance MonadBase b m => MonadBase b (ClangT s m) where+ liftBase = lift . liftBase++instance ClangBase m => MonadResource (ClangT s m) where+ liftResourceT = transClangT liftIO++transClangT :: (m a -> n b) -> ResourceT m a -> ClangT s n b+transClangT f rt = ClangT $ transResourceT f rt++type ClangBase m = MonadResourceBase m++data Proxy s++runClangT :: ClangBase m => (forall s. ClangT s m a) -> m a+runClangT f = runResourceT . unClangT $ f+{-# INLINEABLE runClangT #-}++-- | Runs a monadic computation with libclang and frees all the+-- resources allocated by that computation immediately.+clangScope :: ClangBase m => (forall s. ClangT s m a) -> ClangT s' m a+clangScope = lift . runClangT+{-# INLINEABLE clangScope #-}++clangAllocate :: ClangBase m => IO a -> (a -> IO ()) -> ClangT s m (ReleaseKey, a)+clangAllocate = allocate+{-# INLINEABLE clangAllocate #-}++mkProxy :: Proxy s+mkProxy = undefined+{-# INLINE mkProxy #-}++class ClangValue v where+ -- | Promotes a value from an outer scope to the current inner scope.+ -- The value's lifetime remains that of the outer scope.+ -- This is never necessary, but it may allow you to write code more naturally in+ -- some situations, since it can occasionally be inconvenient that variables+ -- from different scopes are different types.+ fromOuterScope :: ClangBase m => v s' -> ClangT s m (v s)+ fromOuterScope = return . unsafeCoerce++class ClangValueList v where+ -- | Promotes a list from an outer scope to the current inner scope.+ -- The list's lifetime remains that of the outer scope.+ -- This is never necessary, but it may allow you to write code more naturally in+ -- some situations, since it can occasionally be inconvenient that variables+ -- from different scopes are different types.+ listFromOuterScope :: ClangBase m => DVS.Vector (v s') -> ClangT s m (DVS.Vector (v s))+ listFromOuterScope = return . unsafeCoerce
+ src/Clang/Location.hs view
@@ -0,0 +1,106 @@+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE FlexibleContexts #-}++-- | Functions for manipulating 'FFI.SourceLocation's, which map a location in a+-- translation unit to a location in on-disk or in-memory files.+--+-- This module is intended to be imported qualified.+module Clang.Location+(++-- * Creating locations+ create+, createForOffset+, createInvalid++-- * Mapping locations to files+, getExpansionLocation+, getPresumedLocation+, getSpellingLocation+, getFileLocation++-- * Analyzing locations+, getCursor+, isInSystemHeader+, isFromMainFile++) where++import Control.Monad.IO.Class++import qualified Clang.Internal.FFI as FFI+import Clang.Internal.Monad+import System.IO.Unsafe (unsafePerformIO)++-- | Retrieves a 'FFI.SourceLocation' representing the given location in the source code.+create :: ClangBase m+ => FFI.TranslationUnit s' -- ^ The translation unit.+ -> FFI.File s'' -- ^ The file.+ -> Int -- ^ The line.+ -> Int -- ^ The column.+ -> ClangT s m (FFI.SourceLocation s) -- ^ A 'FFI.SourceLocation' value representing+ -- the location.+create tu f line col = liftIO $ FFI.getLocation mkProxy tu f line col++-- | Like 'create', but uses an offset instead of a line and column.+createForOffset :: ClangBase m+ => FFI.TranslationUnit s' -- ^ The translation unit.+ -> FFI.File s'' -- ^ The file.+ -> Int -- ^ The offset.+ -> ClangT s m (FFI.SourceLocation s) -- ^ A 'FFI.SourceLocation' value+ -- representing the location.+createForOffset tu f off = liftIO $ FFI.getLocationForOffset mkProxy tu f off++-- | Creates an invalid 'FFI.SourceLocation'.+createInvalid :: ClangBase m => ClangT s m (FFI.SourceLocation s)+createInvalid = liftIO $ FFI.getNullLocation mkProxy++-- | Retrieves the 'FFI.File', line, column, and offset associated with the given location.+--+-- If the location points into a macro expansion, retrieves the location of the macro expansion.+-- This may be a position that doesn't exist in the original source.+getExpansionLocation :: ClangBase m => FFI.SourceLocation s'+ -> ClangT s m (Maybe (FFI.File s), Int, Int, Int)+getExpansionLocation l = liftIO $ FFI.getExpansionLocation mkProxy l++-- | Retrieves the 'FFI.File', line, and column associated with the given location, as+-- interpreted by the C preprocessor.+--+-- This may differ from the results given by 'getExpansionLocation' because it takes '#line'+-- directives into account, which 'getExpansionLocation' ignores.+getPresumedLocation :: ClangBase m => FFI.SourceLocation s'+ -> ClangT s m (FFI.ClangString s, Int, Int)+getPresumedLocation = FFI.getPresumedLocation++-- | Retrieves the 'FFI.File', line, column, and offset associated with the given location.+--+-- If the location points into a macro expansion, returns the corresponding position in the+-- original source. This may be where the macro was defined or where it was instantiated,+-- depending on what exactly the location points to.+getSpellingLocation :: ClangBase m => FFI.SourceLocation s'+ -> ClangT s m (Maybe (FFI.File s), Int, Int, Int)+getSpellingLocation l = liftIO $ FFI.getSpellingLocation mkProxy l++-- | Retrieves the 'FFI.File', line, column, and offset associated with the given location.+--+-- If the location points into a macro expansion, returns the position where the macro was+-- expanded or the position of the macro argument, if the cursor points at a macro argument.+getFileLocation :: ClangBase m => FFI.SourceLocation s'+ -> ClangT s m (Maybe (FFI.File s), Int, Int, Int)+getFileLocation l = liftIO $ FFI.getFileLocation mkProxy l++-- | Retrieves an AST cursor at the given source location.+--+-- The cursor can be traversed using the functions in "Clang.Cursor".+getCursor :: ClangBase m => FFI.TranslationUnit s' -> FFI.SourceLocation s''+ -> ClangT s m (FFI.Cursor s)+getCursor tu sl = liftIO $ FFI.getCursor mkProxy tu sl++-- | Returns 'True' if the given location is inside a system header.+isInSystemHeader :: FFI.SourceLocation s' -> Bool+isInSystemHeader l = unsafePerformIO $ FFI.location_isInSystemHeader l++-- | Returns 'True' if the given location is from the main file of the associated translation+-- unit.+isFromMainFile :: FFI.SourceLocation s' -> Bool+isFromMainFile l = unsafePerformIO $ FFI.location_isFromMainFile l
+ src/Clang/Module.hs view
@@ -0,0 +1,50 @@+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE FlexibleContexts #-}++-- | Functions for manipulating 'FFI.Module's. An 'FFI.Module' value+-- may be obtained using 'Clang.Cursor.getModule'.+--+-- This module is intended to be imported qualified.+module Clang.Module+( getASTFile+, getParent+, getName+, getFullName+, getTopLevelHeaders+) where++import Control.Monad+import Control.Monad.IO.Class++import qualified Clang.Internal.FFI as FFI+import Clang.Internal.Monad++-- | Retrieves the 'FFI.File' which contains the provided module.+getASTFile :: ClangBase m => FFI.Module s' -> ClangT s m (FFI.File s)+getASTFile m = liftIO $ FFI.module_getASTFile mkProxy m++-- | Given an module, returns either+--+-- * the parent module (for example, for \'std.vector\' the \'std\'+-- module will be returned), or+--+-- * 'Nothing' if the module is top-level.+getParent :: ClangBase m => FFI.Module s' -> ClangT s m (Maybe (FFI.Module s))+getParent m = liftIO $ FFI.module_getParent mkProxy m++-- | Retrieves the name of a module. For example, for \'std.vector\',+-- 'getName' will return \'vector\'.+getName :: ClangBase m => FFI.Module s' -> ClangT s m (FFI.ClangString s)+getName = FFI.module_getName++-- | Retrieves the full name of a module, e.g. \'std.vector\'.+getFullName :: ClangBase m => FFI.Module s' -> ClangT s m (FFI.ClangString s)+getFullName = FFI.module_getFullName++-- | Returns the list of top-level headers associated with the given module.+getTopLevelHeaders :: ClangBase m => FFI.TranslationUnit s' -> FFI.Module s''+ -> ClangT s m [FFI.File s]+getTopLevelHeaders tu m = do+ numHeaders <- liftIO $ FFI.module_getNumTopLevelHeaders tu m+ forM [0..(numHeaders - 1)] $ \idx ->+ liftIO $ FFI.module_getTopLevelHeader mkProxy tu m idx
+ src/Clang/Range.hs view
@@ -0,0 +1,49 @@+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE FlexibleContexts #-}++-- | Functions for manipulating 'FFI.SourceRange's, which represent a range of+-- locations in the source code between two points.+--+-- This module is intended to be imported qualified.+module Clang.Range+(++-- * Creating ranges+ create+, createInvalid++-- * Analyzing ranges+, getStart+, getEnd+, isInvalid++) where++import Control.Monad.IO.Class++import qualified Clang.Internal.FFI as FFI+import Clang.Internal.Monad+import System.IO.Unsafe (unsafePerformIO)++-- | Creates a 'FFI.SourceRange' representing the range between two locations.+create :: ClangBase m+ => FFI.SourceLocation s' -- ^ Starting location.+ -> FFI.SourceLocation s'' -- ^ Ending location.+ -> ClangT s m (FFI.SourceRange s)+create from to = liftIO $ FFI.getRange mkProxy from to++-- | Creates an invalid 'FFI.SourceRange'.+createInvalid :: ClangBase m => ClangT s m (FFI.SourceRange s)+createInvalid = liftIO $ FFI.getNullRange mkProxy++-- | Retrieves the beginning of the given range.+getStart :: ClangBase m => FFI.SourceRange s' -> ClangT s m (FFI.SourceLocation s)+getStart sr = liftIO $ FFI.getRangeStart mkProxy sr++-- | Retrieves the end of the given range.+getEnd :: ClangBase m => FFI.SourceRange s' -> ClangT s m (FFI.SourceLocation s)+getEnd sr = liftIO $ FFI.getRangeEnd mkProxy sr++-- | Returns 'True' if the given range is invalid.+isInvalid :: FFI.SourceRange s' -> Bool+isInvalid r = unsafePerformIO $ FFI.range_isNull r
+ src/Clang/Remapping.hs view
@@ -0,0 +1,37 @@+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE FlexibleContexts #-}++-- | Functions for manipulating remappings.+--+-- This module is intended to be imported qualified.+module Clang.Remapping+( getRemappings+, getRemappingsFromFileList+, getRemappedFiles+) where++import Control.Monad.IO.Class++import qualified Clang.Internal.FFI as FFI+import Clang.Internal.Monad++-- | Given a 'FilePath' for a file, returns information about the remappings that+-- apply to that file. If an error occurs, returns 'Nothing'.+getRemappings :: ClangBase m => FilePath -> ClangT s m (Maybe (FFI.Remapping s))+getRemappings = FFI.getRemappings++-- | Given a list of 'FilePath's, returns information about the+-- remappings that apply to the corresponding files. If an error+-- occurs, returns 'Nothing'.+getRemappingsFromFileList :: ClangBase m => [FilePath] -> ClangT s m (Maybe (FFI.Remapping s))+getRemappingsFromFileList = FFI.getRemappingsFromFileList++-- | Retrieves a list of the remappings described by a+-- 'FFI.Remapping'. Each entry in the list consists of a pair.+-- The first element is the original filename, and the second element+-- is the filename it has been remapped to.+getRemappedFiles :: ClangBase m => FFI.Remapping s'+ -> ClangT s m [(FFI.ClangString s, FFI.ClangString s)]+getRemappedFiles remaps = do+ numRemaps <- liftIO $ FFI.remap_getNumFiles remaps+ mapM (FFI.remap_getFilenames remaps) [0..(numRemaps - 1)]
+ src/Clang/String.hs view
@@ -0,0 +1,51 @@+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE FlexibleContexts #-}++-- | This module contains functions for working with+-- 'FFI.ClangString's, which represent strings that are part of the+-- libclang AST or managed by its API.+--+-- This module is intended to be imported qualified.+module Clang.String (+-- * Conversions+ unpack+, unpackText+, unpackByteString++-- * Unsafe conversions+, unsafeUnpackByteString+) where++import qualified Data.ByteString as B+import qualified Data.Text as T+import qualified Data.Text.Encoding as TE+import qualified Data.Text.Encoding.Error as TEE++import qualified Clang.Internal.FFI as FFI+import Clang.Internal.Monad++-- | Converts an 'FFI.ClangString' to a 'String'.+unpack :: ClangBase m => FFI.ClangString s' -> ClangT s m String+unpack = FFI.getString++-- | Converts an 'FFI.ClangString' to a 'T.Text'.+unpackText :: ClangBase m => FFI.ClangString s' -> ClangT s m T.Text+unpackText s = do+ -- Since unsafeGetByteString does not make a copy, this doesn't actually+ -- require the two copies that it appears to employ.+ str <- FFI.unsafeGetByteString s+ return $! TE.decodeUtf8With TEE.lenientDecode str++-- | Converts an 'FFI.ClangString' to a 'B.ByteString'. This is faster+-- than 'unpack' and 'unpackText' since it requires no encoding.+unpackByteString :: ClangBase m => FFI.ClangString s' -> ClangT s m B.ByteString+unpackByteString = FFI.getByteString++-- | Creates a 'B.ByteString' that shares the underlying memory of the+-- 'FFI.ClangString'. This is very fast since no copying has to be+-- done. However, it's also unsafe because the 'B.ByteString' may outlive+-- the scope of the 'FFI.ClangString', leading to corruption of+-- its contents or crashes. It's the caller's responsibility to+-- prevent this.+unsafeUnpackByteString :: ClangBase m => FFI.ClangString s' -> ClangT s m B.ByteString+unsafeUnpackByteString = FFI.unsafeGetByteString
+ src/Clang/Token.hs view
@@ -0,0 +1,90 @@+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE FlexibleContexts #-}++-- | Functions for manipulating 'Clang.Token's.+--+-- This module is intended to be imported qualified.+module Clang.Token+(+-- * Token lists+ tokenize+, List++-- * Token kinds+, getKind++-- * Mapping between tokens and source code+, getSpelling+, getLocation+, getExtent+, annotateTokens+) where++import Control.Monad.IO.Class+import qualified Data.Vector.Storable as DVS++import qualified Clang.Internal.FFI as FFI+import Clang.Internal.Monad++-- | Tokenizes the source code described by the given range into raw+-- lexical tokens.+tokenize :: ClangBase m+ => FFI.TranslationUnit s' -- ^ The translation list+ -- containing the source code.+ -> FFI.SourceRange s'' -- ^ The source range in which text+ -- should be tokenized.+ -> ClangT s m (List s)+tokenize = FFI.tokenize++-- | A list of tokens, stored as a 'DVS.Vector' for efficiency.+type List s = DVS.Vector (FFI.Token s)++-- | Determines the kind of the given token, expressed as a+-- 'FFI.TokenKind' value.+getKind :: ClangBase m => FFI.Token s' -> ClangT s m FFI.TokenKind+getKind t = liftIO $ FFI.getTokenKind t++-- | Retrieves the \'spelling\', or textual representation, of the+-- given token.+getSpelling :: ClangBase m => FFI.TranslationUnit s' -> FFI.Token s'' -> ClangT s m (FFI.ClangString s)+getSpelling = FFI.getTokenSpelling++-- | Returns the source location of the given token.+getLocation :: ClangBase m => FFI.TranslationUnit s' -> FFI.Token s''+ -> ClangT s m (FFI.SourceLocation s)+getLocation tu tk = liftIO $ FFI.getTokenLocation mkProxy tu tk++-- | Retrieves the source range that covers the given token.+getExtent :: ClangBase m => FFI.TranslationUnit s' -> FFI.Token s''+ -> ClangT s m (FFI.SourceRange s)+getExtent tu tk = liftIO $ FFI.getTokenExtent mkProxy tu tk++-- | Annotates the given set of tokens by providing cursors for each token+-- that can be mapped to a specific entity within the abstract syntax tree.+-- +-- This is equivalent to invoking 'Clang.Cursor.getCursor' on the+-- source locations of each of these tokens. The cursors provided are+-- filtered, so that only those cursors that have a direct+-- correspondence to the token are accepted. For example, given a+-- function call \'f(x)\', 'Clang.Cursor.getCursor' would provide the+-- following cursors:+-- +-- * When the cursor is over the \'f\', a 'Clang.DeclRefExpr' cursor+-- referring to \'f\'.+--+-- * When the cursor is over the \'(\' or the \')\', a+-- 'Clang.CallExpr' referring to \'f\'.+--+-- * When the cursor is over the \'x\', a 'Clang.DeclRefExpr' cursor+-- referring to \'x\'.+-- +-- Only the first and last of these cursors will occur within the+-- annotate, since the tokens \'f\' and \'x\' directly refer to a function+-- and a variable, respectively, but the parentheses are just a small+-- part of the full syntax of the function call expression, which is+-- not provided as an annotation.+annotateTokens :: ClangBase m+ => FFI.TranslationUnit s' -- ^ The translation unit that owns the tokens.+ -> List s'' -- ^ The tokens to annotate.+ -> ClangT s m (FFI.CursorList s)+annotateTokens = FFI.annotateTokens
+ src/Clang/TranslationUnit.hs view
@@ -0,0 +1,195 @@+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE RankNTypes #-}++-- | Functions for manipulating translation units.+--+-- To start analyzing a translation unit, call 'Index.withNew' to create a new index and+-- call 'withParsed' in the callback. Inside the callback for 'withParsed', you'll have+-- access to a 'FFI.TranslationUnit' value; you can call 'getCursor' to turn that into an+-- AST cursor which can be traversed using the functions in "Clang.Cursor".+--+-- This module is intended to be imported qualified.+module Clang.TranslationUnit+(++-- * Creating a translation unit+ withParsed+, withLoaded+, withReparsing+, FFI.TranslationUnitFlags+, FFI.ReparseFlags+, ReparsingCallback+, ParseContinuation(..)++-- * Saving+, save+, FFI.SaveTranslationUnitFlags++-- AST traversal and metadata+, getCursor+, getDiagnosticSet+, getSpelling++) where++import Data.Traversable+import Control.Monad.IO.Class+import Data.Maybe (fromMaybe)+import qualified Data.Vector as DV+-- import System.FilePath ((</>))++import Clang.Internal.BitFlags+import Clang.Internal.Monad+import qualified Clang.Internal.FFI as FFI+-- import Paths_LibClang (getDataFileName)++-- | Creates a translation unit by parsing source code.+--+-- Note that not all command line arguments which are accepted by the \'clang\' frontend can+-- be used here. You should avoid passing \'-c\', \'-o\', \'-fpch-deps\', and the various+-- \'-M\' options. If you provide a 'FilePath' when calling 'withParsed', also be sure not+-- to provide the filename in the command line arguments as well.+withParsed :: ClangBase m+ => FFI.Index s' -- ^ The index into which the translation unit should be loaded.+ -> Maybe FilePath -- ^ The file to load, or 'Nothing' if the file is specified in+ -- the command line arguments.+ -> [String] -- ^ The command line arguments libclang should use when compiling this+ -- file. Most arguments which you'd use with the \'clang\' frontend+ -- are accepted.+ -> DV.Vector FFI.UnsavedFile -- ^ Unsaved files which may be needed to parse this+ -- translation unit. This may include the source+ -- file itself or any file it includes.+ -> [FFI.TranslationUnitFlags] -- ^ Flags that affect the processing of this+ -- translation unit.+ -> (forall s. FFI.TranslationUnit s -> ClangT s m a) -- ^ A callback.+ -> ClangT s' m (Maybe a) -- ^ The return value of the callback, or 'Nothing'+ -- if the file couldn't be parsed.+withParsed idx mayPath args ufs flags f = do+ -- liftIO $ FFI.setClangResourcesPath idx =<< clangResourcesPath+ mayTU <- FFI.parseTranslationUnit idx mayPath args ufs (orFlags flags)+ traverse go mayTU+ where+ go tu = clangScope $ f =<< fromOuterScope tu++-- | Creates a translation unit by loading a saved AST file.+--+-- Such an AST file can be created using 'save'.+withLoaded :: ClangBase m+ => FFI.Index s' -- ^ The index into which the translation unit should be loaded.+ -> FilePath -- ^ The file to load.+ -> (forall s. FFI.TranslationUnit s -> ClangT s m a) -- ^ A callback.+ -> ClangT s' m a+withLoaded idx path f = do+ -- liftIO $ FFI.setClangResourcesPath idx =<< clangResourcesPath+ f =<< FFI.createTranslationUnit idx path+++-- | Creates a translation unit by parsing source code.+--+-- This works like 'withParsed', except that the translation unit can be reparsed over and over+-- again by returning a 'Reparse' value from the callback. This is useful for interactive+-- analyses like code completion. Processing can be stopped by returning a 'ParseComplete' value.+withReparsing :: ClangBase m+ => FFI.Index s' -- ^ The index into which the translation unit should be loaded.+ -> Maybe FilePath -- ^ The file to load, or 'Nothing' if the file is specified in+ -- the command line arguments.+ -> [String] -- ^ The command line arguments libclang should use when compiling+ -- this file. Most arguments which you'd use with the \'clang\'+ -- frontend are accepted.+ -> DV.Vector FFI.UnsavedFile -- ^ Unsaved files which may be needed to parse this+ -- translation unit. This may include the source+ -- file itself or any file it includes.+ -> [FFI.TranslationUnitFlags] -- ^ Flags that affect the processing of this+ -- translation unit.+ -> ReparsingCallback m r -- ^ A callback which uses the translation unit. May be+ -- called many times depending on the return value.+ -- See 'ParseContinuation' for more information.+ -> ClangT s' m (Maybe r) -- ^ The return value of the callback, as passed to+ -- 'ParseComplete', or 'Nothing' if the file could+ -- not be parsed.+withReparsing idx mayPath args ufs flags f = do+ -- liftIO $ FFI.setClangResourcesPath idx =<< clangResourcesPath+ mayTU <- FFI.parseTranslationUnit idx mayPath args ufs (orFlags flags)+ case mayTU of+ Nothing -> return Nothing+ Just tu -> iterReparse f tu++iterReparse :: ClangBase m+ => ReparsingCallback m r+ -> FFI.TranslationUnit s'+ -> ClangT s' m (Maybe r)+iterReparse f tu = do+ cont <- clangScope $ f =<< fromOuterScope tu+ case cont of+ Reparse nextF ufs mayFlags ->+ do res <- FFI.reparseTranslationUnit tu ufs (makeFlags mayFlags)+ if res then iterReparse nextF tu+ else return Nothing+ ParseComplete finalVal -> return $ Just finalVal+ where+ makeFlags = orFlags . (fromMaybe [FFI.DefaultReparseFlags])+++-- | A callback for use with 'withReparsing'.+type ReparsingCallback m r = forall s. FFI.TranslationUnit s+ -> ClangT s m (ParseContinuation m r)++-- | A continuation returned by a 'ReparsingCallback'.+data ParseContinuation m r+ -- | 'Reparse' signals that the translation unit should be reparsed. It contains a callback+ -- which will be called with the updated translation unit after reparsing, a 'DV.Vector' of+ -- unsaved files which may be needed to reparse, and a set of flags affecting reparsing. The+ -- default reparsing flags can be requested by specifying 'Nothing'.+ = Reparse (ReparsingCallback m r) (DV.Vector FFI.UnsavedFile) (Maybe [FFI.ReparseFlags])++ -- | 'ParseComplete' signals that processing is finished. It contains a final result which+ -- will be returned by 'withReparsing'.+ | ParseComplete r++-- clangResourcesPath :: IO FilePath+-- clangResourcesPath =+-- getDataFileName $ "build" </> "out" </> "lib" </> "clang" </> "3.4"++-- | Saves a translation unit as an AST file with can be loaded later using 'withLoaded'.+save :: ClangBase m+ => FFI.TranslationUnit s' -- ^ The translation unit to save.+ -> FilePath -- ^ The filename to save to.+ -> Maybe [FFI.SaveTranslationUnitFlags] -- ^ Flags that affect saving, or 'Nothing' for+ -- the default set of flags.+ -> ClangT s m Bool+save t fname mayFlags = liftIO $ FFI.saveTranslationUnit t fname (orFlags flags)+ where flags = fromMaybe [FFI.DefaultSaveTranslationUnitFlags] mayFlags++{-+-- | Reparses the provided translation unit using the same command line arguments+-- that were originally used to parse it. If the file has changed on disk, or if+-- the unsaved files have changed, those changes will become visible.+--+-- Note that 'reparse' invalidates all cursors and source locations that refer into+-- the reparsed translation unit. This makes it unsafe. However, 'reparse' can be+-- more efficient than calling 'withParsed' a second time.+reparse :: ClangBase m+ => FFI.TranslationUnit s' -- ^ The translation unit to reparse.+ -> DV.Vector FFI.UnsavedFile -- ^ Unsaved files which may be needed to reparse+ -- this translation unit.+ -> Maybe [FFI.ReparseFlags] -- ^ Flags that affect reparsing, or 'Nothing' for the+ -- default set of flags.+ -> ClangT s m Bool+reparse t ufs mayFlags = FFI.reparseTranslationUnit t ufs (orFlags flags)+ where flags = fromMaybe [FFI.DefaultReparseFlags] mayFlags+-}++-- | Retrieve the cursor associated with this translation unit. This cursor is the root of+-- this translation unit's AST; you can begin exploring the AST further using the functions+-- in "Clang.Cursor".+getCursor :: ClangBase m => FFI.TranslationUnit s' -> ClangT s m (FFI.Cursor s)+getCursor tu = liftIO $ FFI.getTranslationUnitCursor mkProxy tu++-- | Retrieve the complete set of diagnostics associated with the given translation unit.+getDiagnosticSet :: ClangBase m => FFI.TranslationUnit s'-> ClangT s m (FFI.DiagnosticSet s)+getDiagnosticSet = FFI.getDiagnosticSetFromTU++-- | Retrieve a textual representation of this translation unit.+getSpelling :: ClangBase m => FFI.TranslationUnit s' -> ClangT s m (FFI.ClangString s)+getSpelling = FFI.getTranslationUnitSpelling
+ src/Clang/Type.hs view
@@ -0,0 +1,142 @@+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE FlexibleContexts #-}++module Clang.Type+( isSameType+, getTypeSpelling+, getKind+, getCanonicalType+, getPointeeType+, getResultType+, getNumArgTypes+, getArgType+, isFunctionTypeVariadic++, getTypedefDeclUnderlyingType+, getEnumDeclIntegerType+, getEnumConstantDeclValue+, getEnumConstantDeclUnsignedValue+, getFieldDeclBitWidth++, isConstQualifiedType+, isVolatileQualifiedType+, isRestrictQualifiedType+, isPODType+, getElementType+, getNumElements+, getArrayElementType+, getArraySize+, getAlignOf+, getSizeOf+, getOffsetOf+, getClassType+, getCXXRefQualifier+, isVirtualBase+, getFunctionTypeCallingConv++, getTypeKindSpelling+) where++import Control.Monad.IO.Class+import qualified Data.ByteString as B+import Data.Int (Int64)+import Data.Word (Word64)++import qualified Clang.Internal.FFI as FFI+import Clang.Internal.Monad++isSameType :: ClangBase m => FFI.Type s' -> FFI.Type s'' -> ClangT s m Bool+isSameType a b = liftIO $ FFI.equalTypes a b++getTypeSpelling :: ClangBase m => FFI.Type s' -> ClangT s m (FFI.ClangString s)+getTypeSpelling = FFI.getTypeSpelling++getTypedefDeclUnderlyingType :: ClangBase m => FFI.Cursor s' -> ClangT s m (FFI.Type s)+getTypedefDeclUnderlyingType c = liftIO $ FFI.getTypedefDeclUnderlyingType mkProxy c++getEnumDeclIntegerType :: ClangBase m => FFI.Cursor s' -> ClangT s m (FFI.Type s)+getEnumDeclIntegerType c = liftIO $ FFI.getEnumDeclIntegerType mkProxy c++getEnumConstantDeclValue :: ClangBase m => FFI.Cursor s' -> ClangT s m Int64+getEnumConstantDeclValue c = liftIO $ FFI.getEnumConstantDeclValue c++getEnumConstantDeclUnsignedValue :: ClangBase m => FFI.Cursor s' -> ClangT s m Word64+getEnumConstantDeclUnsignedValue c = liftIO $ FFI.getEnumConstantDeclUnsignedValue c++getFieldDeclBitWidth :: ClangBase m => FFI.Cursor s' -> ClangT s m (Maybe Int)+getFieldDeclBitWidth c = do+ bitWidth <- liftIO $ FFI.getFieldDeclBitWidth c+ return $ if bitWidth < 0 then Nothing+ else Just bitWidth+ +getKind :: ClangBase m => FFI.Type s' -> ClangT s m FFI.TypeKind+getKind = return . FFI.getTypeKind++getCanonicalType :: ClangBase m => FFI.Type s' -> ClangT s m (FFI.Type s)+getCanonicalType t = liftIO $ FFI.getCanonicalType mkProxy t++getPointeeType :: ClangBase m => FFI.Type s' -> ClangT s m (FFI.Type s)+getPointeeType t = liftIO $ FFI.getPointeeType mkProxy t++getResultType :: ClangBase m => FFI.Type s' -> ClangT s m (FFI.Type s)+getResultType t = liftIO $ FFI.getResultType mkProxy t++getNumArgTypes :: ClangBase m => FFI.Type s' -> ClangT s m Int+getNumArgTypes t = liftIO $ FFI.getNumArgTypes t++getArgType :: ClangBase m => FFI.Type s' -> Int -> ClangT s m (FFI.Type s)+getArgType t i = liftIO $ FFI.getArgType mkProxy t i++isFunctionTypeVariadic :: ClangBase m => FFI.Type s' -> ClangT s m Bool+isFunctionTypeVariadic t = liftIO $ FFI.isFunctionTypeVariadic t++isConstQualifiedType :: ClangBase m => FFI.Type s' -> ClangT s m Bool+isConstQualifiedType t = liftIO $ FFI.isConstQualifiedType t++isVolatileQualifiedType :: ClangBase m => FFI.Type s' -> ClangT s m Bool+isVolatileQualifiedType t = liftIO $ FFI.isVolatileQualifiedType t++isRestrictQualifiedType :: ClangBase m => FFI.Type s' -> ClangT s m Bool+isRestrictQualifiedType t = liftIO $ FFI.isRestrictQualifiedType t++isPODType :: ClangBase m => FFI.Type s' -> ClangT s m Bool+isPODType t = liftIO $ FFI.isPODType t++getElementType :: ClangBase m => FFI.Type s' -> ClangT s m (FFI.Type s)+getElementType t = liftIO $ FFI.getElementType mkProxy t++getNumElements :: ClangBase m => FFI.Type s' -> ClangT s m Int64+getNumElements t = liftIO $ FFI.getNumElements t++getArrayElementType :: ClangBase m => FFI.Type s' -> ClangT s m (FFI.Type s)+getArrayElementType t = liftIO $ FFI.getArrayElementType mkProxy t++getArraySize :: ClangBase m => FFI.Type s' -> ClangT s m Int64+getArraySize t = liftIO $ FFI.getArraySize t++getAlignOf :: ClangBase m => FFI.Type s' -> ClangT s m (Either FFI.TypeLayoutError Int64)+getAlignOf t = liftIO $ FFI.type_getAlignOf t++getSizeOf :: ClangBase m => FFI.Type s' -> ClangT s m (Either FFI.TypeLayoutError Int64)+getSizeOf t = liftIO $ FFI.type_getSizeOf t++getOffsetOf :: ClangBase m => FFI.Type s' -> B.ByteString+ -> ClangT s m (Either FFI.TypeLayoutError Int64)+getOffsetOf = FFI.type_getOffsetOf++getClassType :: ClangBase m => FFI.Type s' -> ClangT s m (FFI.Type s)+getClassType t = liftIO $ FFI.type_getClassType mkProxy t++getCXXRefQualifier :: ClangBase m => FFI.Type s' -> ClangT s m FFI.RefQualifierKind+getCXXRefQualifier t = liftIO $ FFI.type_getCXXRefQualifier t++isVirtualBase :: ClangBase m => FFI.Cursor s' -> ClangT s m Bool+isVirtualBase c = liftIO $ FFI.isVirtualBase c++getFunctionTypeCallingConv :: ClangBase m => FFI.Type s' -> ClangT s m FFI.CallingConv+getFunctionTypeCallingConv t = liftIO $ FFI.getFunctionTypeCallingConv t+++-- Typekind functions+getTypeKindSpelling :: ClangBase m => FFI.TypeKind -> ClangT s m (FFI.ClangString s)+getTypeKindSpelling = FFI.getTypeKindSpelling
+ src/Clang/USR.hs view
@@ -0,0 +1,79 @@+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE FlexibleContexts #-}++-- | Functions for manipulating 'Unified Symbol Resolution' values, or+-- \'USRs\'. USRs are strings that provide an unambiguous reference to a+-- symbol. Any two cursors that refer to the same semantic entity will+-- have the same USR, even if they occur in different translation+-- units. This is very useful when attempting to cross-reference+-- between different source files in a project.+--+-- Most often, using USRs simply means retrieving the USR that+-- corresponds to a 'Clang.Cursor'. You can do this using+-- 'Clang.Cursor.getUSR', and then convert to a Haskell string using+-- the functions in "Clang.String".+--+-- This module is intended to be imported qualified.+module Clang.USR+( createFromObjCClass+, createFromObjCCategory+, createFromObjCProtocol+, createFromObjCIvar+, createFromObjCInstanceMethod+, createFromObjCClassMethod+, createFromObjCProperty+) where++import qualified Clang.Internal.FFI as FFI+import Clang.Internal.Monad++-- | Construct a USR for the specified Objective-C class.+createFromObjCClass :: ClangBase m+ => String -- ^ A class name.+ -> ClangT s m (FFI.ClangString s)+createFromObjCClass = FFI.constructUSR_ObjCClass++-- | Construct a USR for the specified Objective-C category.+createFromObjCCategory :: ClangBase m+ => String -- ^ A class name.+ -> String -- ^ A category name.+ -> ClangT s m (FFI.ClangString s)+createFromObjCCategory = FFI.constructUSR_ObjCCategory++-- | Construct a USR for the specified Objective-C protocol.+createFromObjCProtocol :: ClangBase m+ => String -- ^ A protocol name.+ -> ClangT s m (FFI.ClangString s)+createFromObjCProtocol = FFI.constructUSR_ObjCProtocol++-- | Construct a USR for the specified Objective-C instance variable,+-- given the USR for its containing class.+createFromObjCIvar :: ClangBase m+ => String -- ^ An instance variable name.+ -> FFI.ClangString s' -- ^ A class USR.+ -> ClangT s m (FFI.ClangString s)+createFromObjCIvar = FFI.constructUSR_ObjCIvar++-- | Construct a USR for the specified Objective-C instance method, given the USR+-- for its containing class.+createFromObjCInstanceMethod :: ClangBase m+ => String -- ^ A method name.+ -> FFI.ClangString s' -- ^ A class USR.+ -> ClangT s m (FFI.ClangString s)+createFromObjCInstanceMethod name = FFI.constructUSR_ObjCMethod name True++-- | Construct a USR for the specified Objective-C class method, given the USR+-- for its containing class.+createFromObjCClassMethod :: ClangBase m+ => String -- ^ A method name.+ -> FFI.ClangString s' -- ^ A class USR.+ -> ClangT s m (FFI.ClangString s)+createFromObjCClassMethod name = FFI.constructUSR_ObjCMethod name False++-- | Construct a USR for the specified Objective-C property, given the USR+-- for its containing class.+createFromObjCProperty :: ClangBase m+ => String -- ^ A property name.+ -> FFI.ClangString s' -- ^ A class USR.+ -> ClangT s m (FFI.ClangString s)+createFromObjCProperty = FFI.constructUSR_ObjCProperty
+ src/Clang/UnsavedFile.hs view
@@ -0,0 +1,44 @@+-- | Functions for working with unsaved files.+--+-- Unsaved files are used to represent files which are in memory, but haven't+-- yet been written to disk. You'll need to use unsaved files for situations+-- like supporting autocomplete in an editor without requiring the user to save+-- for up-to-date completions. See "Clang.TranslationUnit" for details about+-- using unsaved files.+--+-- This module is intended to be imported qualified.+module Clang.UnsavedFile+( ++-- * Creating an unsaved file+ new++-- * Field accessors+, filename+, contents++-- * Updates+, updateContents++) where++import qualified Data.ByteString as B++import qualified Clang.Internal.FFI as FFI++-- | Create a new unsaved file.+new :: B.ByteString -> B.ByteString -> FFI.UnsavedFile+new = FFI.newUnsavedFile++-- | Retrieve the filename of an unsaved file.+filename :: FFI.UnsavedFile -> B.ByteString+filename = FFI.unsavedFilename++-- | Retrieve the contents of an unsaved file.+contents :: FFI.UnsavedFile -> B.ByteString+contents = FFI.unsavedContents++-- | Update the contents of an unsaved file. This is more efficient than creating+-- a new unsaved file with the same filename.+updateContents :: FFI.UnsavedFile -> B.ByteString -> FFI.UnsavedFile+updateContents = FFI.updateUnsavedContents
+ src/Clang/Version.hs view
@@ -0,0 +1,30 @@+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE FlexibleContexts #-}++-- | This module allows you to query the version of libclang that this+-- library provides bindings for.+module Clang.Version+( getVersion+, apiVersion+, encodedAPIVersion+) where++import qualified Clang.Internal.FFI as FFI+import Clang.Internal.Monad++-- | Return a version string, suitable for showing to a user, but not+-- intended to be parsed (the format is not guaranteed to be stable).+-- This is the version usually used for libclang packages and public+-- documentation.+getVersion :: ClangBase m => ClangT s m (FFI.ClangString s)+getVersion = FFI.getClangVersion++-- | The API version, in (major, minor) format. This is a semantic+-- version that tracks only the libclang API itself. It's unrelated to+-- the associated LLVM or libclang version.+apiVersion :: (Int, Int)+apiVersion = (FFI.versionMajor, FFI.versionMinor)++-- | The API version, encoded as a single number.+encodedAPIVersion :: Int+encodedAPIVersion = FFI.encodedVersion
+ test/Makefile view
@@ -0,0 +1,25 @@+LLVM_CFG=../build/out/bin/llvm-config+CC=gcc+CFLAGS=-std=gnu99 +LLVM_CFLAGS=$(shell $(LLVM_CFG) --cflags)+LDFLAGS=$(shell $(LLVM_CFG) --ldflags)+LIBS=-ldl -pthread -Wl,-rpath -Wl,$(shell $(LLVM_CFG) --libdir) $(shell $(LLVM_CFG) --libs core) -lclang++all: Test_Diagnostics_c Test_Diagnostics_hs Test_InclusionVisitor_c Test_InclusionVisitor_hs Test_ChildVisitor_c Test_ChildVisitor_hs++test: all+ @echo "########### TESTING ##############"+ @./runTest.sh Test_Diagnostics Test_Diagnostics.c+ @./runTest.sh Test_InclusionVisitor Test_InclusionVisitor.c+ @./runTest.sh Test_ChildVisitor Test_ChildVisitor.c++%_c : %.c+ $(CC) $(CFLAGS) $(LLVM_CFLAGS) -o $@ $< $(LDFLAGS) $(LIBS)++%_hs : %.hs+ cd .. && cabal exec -- ghc -o test/$@ test/$<++clean:+ rm *_c *_hs *.o *.hi++.PHONY = all clean test
+ test/Test_ChildVisitor.c view
@@ -0,0 +1,26 @@+#include <stdio.h>+#include <clang-c/Index.h>++enum CXChildVisitResult visitor(CXCursor cursor, CXCursor parent, CXClientData data)+{+ enum CXCursorKind cKind = clang_getCursorKind(cursor);+ CXString nameString = clang_getCursorDisplayName(cursor);+ CXString typeString = clang_getCursorKindSpelling(cKind);+ printf("Name:%s, Kind:%s\n", clang_getCString(nameString), clang_getCString(typeString));+ clang_disposeString(nameString);+ clang_disposeString(typeString);+ return CXChildVisit_Continue;+}++int main(int argc, char * argv[])+{+ CXIndex index = clang_createIndex(0, 0);+ CXTranslationUnit txUnit = clang_parseTranslationUnit(index, 0, (const char * const *) argv, argc, 0, 0, CXTranslationUnit_None);++ CXCursor cur = clang_getTranslationUnitCursor(txUnit);+ clang_visitChildren(cur, visitor, NULL);++ clang_disposeTranslationUnit(txUnit);+ clang_disposeIndex(index);+ return 0;+}
+ test/Test_ChildVisitor.hs view
@@ -0,0 +1,20 @@+{-# LANGUAGE FlexibleContexts #-}+import System.Environment(getArgs)+import Control.Monad.IO.Class(liftIO)+import Text.Printf(printf)+import qualified Data.Vector.Storable as DVS(mapM_)++import Clang.String(unpack)+import Clang.TranslationUnit(getCursor)+import Clang(parseSourceFile, getChildren)+import Clang.Cursor(getKind, getDisplayName, getCursorKindSpelling)++test tu = getCursor tu >>= getChildren >>= DVS.mapM_ printInfo+ where printInfo c = do+ name <- getDisplayName c >>= unpack+ tstr <- getCursorKindSpelling (getKind c) >>= unpack+ liftIO $ printf "Name:%s, Kind:%s\n" name tstr++main = do+ (arg:args) <- getArgs+ parseSourceFile arg args test
+ test/Test_Diagnostics.c view
@@ -0,0 +1,22 @@+#include <stdio.h>+#include <clang-c/Index.h>++int main(int argc, const char * argv[])+{+ CXIndex index = clang_createIndex(0, 0);+ CXTranslationUnit txUnit = clang_parseTranslationUnit(index, 0, argv, argc, 0, 0, CXTranslationUnit_None);++ unsigned n = clang_getNumDiagnostics(txUnit);+ /* printf("numDiags:%d\n", n); */+ for(unsigned i = 0, n = clang_getNumDiagnostics(txUnit); i != n; ++i)+ {+ CXDiagnostic diag = clang_getDiagnostic(txUnit, i);+ CXString str = clang_formatDiagnostic(diag, clang_defaultDiagnosticDisplayOptions());+ printf("Diag:%s\n", clang_getCString(str));+ clang_disposeString(str);+ }++ clang_disposeTranslationUnit(txUnit);+ clang_disposeIndex(index);+ return 0;+}
+ test/Test_Diagnostics.hs view
@@ -0,0 +1,16 @@+{-# LANGUAGE FlexibleContexts #-}+import System.Environment(getArgs)+import Control.Monad.IO.Class(liftIO)+import Clang.String(unpack)+import Clang.TranslationUnit(getDiagnosticSet)+import Clang(parseSourceFile)+import qualified Clang.Diagnostic as Diagnostic(format, getElements)++test tu = do getDiagnosticSet tu >>= Diagnostic.getElements >>= mapM_ printDiag+ where printDiag d = Diagnostic.format Nothing d >>=+ unpack >>=+ (liftIO . putStrLn . ("Diag:" ++))++main = do+ (arg:args) <- getArgs+ parseSourceFile arg args test
+ test/Test_Diagnostics_FFI.hs view
@@ -0,0 +1,20 @@+import System(getArgs)+import Data.Maybe(fromJust, isJust)+import qualified Clang.FFI as Clang+-- import qualified Clang.TranslationUnit as Clang+-- import qualified Clang.Diagnostic as Diagnostic++main = do+ args <- getArgs+ index <- Clang.createIndex False False+ mtu <- Clang.parseTranslationUnit index Nothing args [] 0+ let tu = if isJust mtu then fromJust mtu else error "No TXUnit!"+ defDisplayOpts <- Clang.defaultDiagnosticDisplayOptions+ let printDiag i = do+ diag <- Clang.getDiagnostic tu i+ clstr <- Clang.formatDiagnostic diag defDisplayOpts+ str <- Clang.getCString clstr+ putStrLn $ "Diag:" ++ str+ numDiags <- Clang.getNumDiagnostics tu+ putStrLn $ "numDiags:" ++ show numDiags+ mapM_ printDiag [0..numDiags]
+ test/Test_InclusionVisitor.c view
@@ -0,0 +1,23 @@+#include <stdio.h>+#include <clang-c/Index.h>++void inclusionVisitor(CXFile file, CXSourceLocation * srcLocs, unsigned numSrcLocs, CXClientData data)+{+ if(0 == numSrcLocs)+ return;+ CXString fname = clang_getFileName(file);+ printf("Included:%s\n",clang_getCString(fname));+ clang_disposeString(fname);+}++int main(int argc, const char * argv[])+{+ CXIndex index = clang_createIndex(0, 0);+ CXTranslationUnit txUnit = clang_parseTranslationUnit(index, 0, argv, argc, 0, 0, CXTranslationUnit_None);++ clang_getInclusions(txUnit, inclusionVisitor, NULL);++ clang_disposeTranslationUnit(txUnit);+ clang_disposeIndex(index);+ return 0;+}
+ test/Test_InclusionVisitor.hs view
@@ -0,0 +1,17 @@+{-# LANGUAGE FlexibleContexts #-}+import System.Environment(getArgs)+import Control.Monad.IO.Class(liftIO)+import qualified Data.Vector.Storable as DVS(mapM_)++import Clang.String(unpack)+import Clang.File(getName)+import Clang(parseSourceFile, getInclusions, Inclusion(..))++test tu = getInclusions tu >>= DVS.mapM_ printInclusion+ where printInclusion (Inclusion fname _ _) = do+ name <- getName fname >>= unpack+ liftIO $ putStrLn $ "Included:" ++ name++main = do+ (arg:args) <- getArgs+ parseSourceFile arg args test
+ test/runTest.sh view
@@ -0,0 +1,20 @@+#!/bin/sh++TEST=$1+CTEST=${TEST}_c+HSTEST=${TEST}_hs++shift++TMPFILE=`mktemp -t libclangtest_XXX`+TMPFILE_C=$TMPFILE.ref+TMPFILE_HS=$TMPFILE.test+./$CTEST $* | grep -v "'linker' input unused" > $TMPFILE_C+./$HSTEST $* | grep -v "'linker' input unused" > $TMPFILE_HS+if [ -n "`diff $TMPFILE_C $TMPFILE_HS`" ]+then+ echo FAILED: $TEST refOutput: $TMPFILE_C testOutput: $TMPFILE_HS+else+ echo SUCCESS: $TEST+ rm $TMPFILE_HS $TMPFILE_C+fi