├── .travis.yml ├── LICENSE ├── Makefile ├── README.md ├── availabilitykind.go ├── callingconv.go ├── cgoflags.go ├── cgoflags_darwin.go ├── cgoflags_droneio.go ├── cgoflags_linux.go ├── clang-c ├── BuildSystem.h ├── CXCompilationDatabase.h ├── CXErrorCode.h ├── CXString.h ├── Documentation.h ├── Index.h ├── Platform.h └── module.modulemap ├── clang.go ├── clang_test.go ├── comment.go ├── commentkind.go ├── compilationdb.go ├── compilationdb_test.go ├── complete.go ├── complete_test.go ├── cursor.go ├── cursorkind.go ├── cxstring.go ├── diagnostics.go ├── diagnostics_test.go ├── doc.go ├── file.go ├── fileuniqueid.go ├── go-clang-compdb └── main.go ├── go-clang-dump ├── main.go └── main_test.go ├── go-clang.h ├── module.go ├── objcdeclqualifier.go ├── objcpropertyattr.go ├── platformavailability.go ├── refqualifierkind.go ├── result.go ├── sourcelocation.go ├── sourcerange.go ├── testdata ├── compile_commands.json ├── hello.c └── struct.c ├── token.go ├── translationunit.go ├── translationunitflags.go ├── type.go ├── typekind.go ├── typelayouterror.go ├── unsavedfiles.go ├── unsavedfiles_test.go ├── version.go └── visitorwrap.c /.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | 3 | before_install: 4 | - sudo add-apt-repository -y ppa:costamagnagianfranco/locutusofborg-ppa 5 | - sudo apt-get update -qq 6 | - sudo apt-get install libclang-dev -qq 7 | 8 | install: 9 | - mkdir -p $GOPATH/src/github.com/sbinet/go-clang 10 | - mv * $GOPATH/src/github.com/sbinet/go-clang/. 11 | - pushd $GOPATH/src/github.com/sbinet/go-clang 12 | - go get -d -v ./... 13 | - go build -v ./... 14 | 15 | script: 16 | - pushd $GOPATH/src/github.com/sbinet/go-clang 17 | - go test ./... 18 | 19 | notifications: 20 | email: 21 | recipients: 22 | - binet@cern.ch 23 | on_success: change 24 | on_failure: always 25 | 26 | # whitelist 27 | branches: 28 | only: 29 | - release/clang-3.0 30 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | /*- 2 | * Copyright (c) 2008 The NetBSD Foundation, Inc. 3 | * All rights reserved. 4 | * 5 | * This code is derived from software contributed to The NetBSD Foundation 6 | * by 7 | * 8 | * Redistribution and use in source and binary forms, with or without 9 | * modification, are permitted provided that the following conditions 10 | * are met: 11 | * 1. Redistributions of source code must retain the above copyright 12 | * notice, this list of conditions and the following disclaimer. 13 | * 2. Redistributions in binary form must reproduce the above copyright 14 | * notice, this list of conditions and the following disclaimer in the 15 | * documentation and/or other materials provided with the distribution. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 18 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 19 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 20 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 21 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 | * POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | ## simple makefile to log workflow 2 | .PHONY: all test clean build install 3 | 4 | GOFLAGS ?= $(GOFLAGS:) 5 | 6 | all: install test 7 | 8 | 9 | build: 10 | @go build $(GOFLAGS) ./... 11 | 12 | install: 13 | @go get $(GOFLAGS) ./... 14 | 15 | gen: 16 | @go generate $(GOFLAGS) ./... 17 | 18 | test: install 19 | @go test $(GOFLAGS) ./... 20 | 21 | bench: install 22 | @go test -run=NONE -bench=. $(GOFLAGS) ./... 23 | 24 | clean: 25 | @go clean $(GOFLAGS) -i ./... 26 | 27 | ## EOF 28 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | go-clang 2 | ======== 3 | 4 | [![Build Status](https://secure.travis-ci.org/sbinet/go-clang.png)](http://travis-ci.org/sbinet/go-clang) 5 | [![Build Status](https://drone.io/github.com/sbinet/go-clang/status.png)](https://drone.io/github.com/sbinet/go-clang/latest) 6 | 7 | 8 | Naive Go bindings to the C-API of ``CLang``. 9 | 10 | ## WARNING - DEPRECATED 11 | 12 | **WARNING:** This repository is _**DEPRECATED**_. 13 | Please use instead one of the `clang` bindings under [github.com/go-clang](https://github.com/go-clang). 14 | 15 | --- 16 | 17 | Installation 18 | ------------ 19 | 20 | As there is no ``pkg-config`` entry for clang, you may have to tinker 21 | a bit the various CFLAGS and LDFLAGS options, or pass them via the 22 | shell: 23 | 24 | ``` 25 | $ CGO_CFLAGS="-I`llvm-config --includedir`" \ 26 | CGO_LDFLAGS="-L`llvm-config --libdir`" \ 27 | go get github.com/sbinet/go-clang 28 | ``` 29 | 30 | Example 31 | ------- 32 | 33 | An example on how to use the AST visitor of ``CLang`` is provided 34 | here: 35 | 36 | https://github.com/sbinet/go-clang/blob/master/go-clang-dump/main.go 37 | 38 | ``` go 39 | package main 40 | 41 | import ( 42 | "flag" 43 | "fmt" 44 | "os" 45 | 46 | "github.com/sbinet/go-clang" 47 | ) 48 | 49 | var fname *string = flag.String("fname", "", "the file to analyze") 50 | 51 | func main() { 52 | fmt.Printf(":: go-clang-dump...\n") 53 | flag.Parse() 54 | fmt.Printf(":: fname: %s\n", *fname) 55 | fmt.Printf(":: args: %v\n", flag.Args()) 56 | if *fname == "" { 57 | flag.Usage() 58 | fmt.Printf("please provide a file name to analyze\n") 59 | os.Exit(1) 60 | } 61 | idx := clang.NewIndex(0, 1) 62 | defer idx.Dispose() 63 | 64 | nidx := 0 65 | args := []string{} 66 | if len(flag.Args()) > 0 && flag.Args()[0] == "-" { 67 | nidx = 1 68 | args = make([]string, len(flag.Args()[nidx:])) 69 | copy(args, flag.Args()[nidx:]) 70 | } 71 | 72 | tu := idx.Parse(*fname, args, nil, 0) 73 | 74 | defer tu.Dispose() 75 | 76 | fmt.Printf("tu: %s\n", tu.Spelling()) 77 | cursor := tu.ToCursor() 78 | fmt.Printf("cursor-isnull: %v\n", cursor.IsNull()) 79 | fmt.Printf("cursor: %s\n", cursor.Spelling()) 80 | fmt.Printf("cursor-kind: %s\n", cursor.Kind().Spelling()) 81 | 82 | tu_fname := tu.File(*fname).Name() 83 | fmt.Printf("tu-fname: %s\n", tu_fname) 84 | 85 | fct := func(cursor, parent clang.Cursor) clang.ChildVisitResult { 86 | if cursor.IsNull() { 87 | fmt.Printf("cursor: \n") 88 | return clang.CVR_Continue 89 | } 90 | fmt.Printf("%s: %s (%s)\n", 91 | cursor.Kind().Spelling(), cursor.Spelling(), cursor.USR()) 92 | switch cursor.Kind() { 93 | case clang.CK_ClassDecl, clang.CK_EnumDecl, 94 | clang.CK_StructDecl, clang.CK_Namespace: 95 | return clang.CVR_Recurse 96 | } 97 | return clang.CVR_Continue 98 | } 99 | 100 | cursor.Visit(fct) 101 | 102 | fmt.Printf(":: bye.\n") 103 | } 104 | ``` 105 | 106 | which can be installed like so: 107 | 108 | ``` 109 | $ go get github.com/sbinet/go-clang/go-clang-dump 110 | ``` 111 | 112 | Limitations 113 | ----------- 114 | 115 | - Only a subset of the C-API of ``CLang`` has been provided yet. 116 | More will come as patches flow in and time goes by. 117 | 118 | - Go-doc documentation is lagging (but the doxygen docs from the C-API 119 | of ``CLang`` are in the ``.go`` files) 120 | 121 | 122 | Documentation 123 | ------------- 124 | 125 | Is available at ``godoc``: 126 | 127 | http://godoc.org/github.com/sbinet/go-clang 128 | 129 | -------------------------------------------------------------------------------- /availabilitykind.go: -------------------------------------------------------------------------------- 1 | package clang 2 | 3 | // #include 4 | // #include "go-clang.h" 5 | import "C" 6 | 7 | /** 8 | * \brief Describes the availability of a particular entity, which indicates 9 | * whether the use of this entity will result in a warning or error due to 10 | * it being deprecated or unavailable. 11 | */ 12 | type AvailabilityKind uint32 13 | 14 | const ( 15 | 16 | /** 17 | * \brief The entity is available. 18 | */ 19 | Available AvailabilityKind = C.CXAvailability_Available 20 | 21 | /** 22 | * \brief The entity is available, but has been deprecated (and its use is 23 | * not recommended). 24 | */ 25 | Deprecated AvailabilityKind = C.CXAvailability_Deprecated 26 | /** 27 | * \brief The entity is not available; any use of it will be an error. 28 | */ 29 | NotAvailable AvailabilityKind = C.CXAvailability_NotAvailable 30 | /** 31 | * \brief The entity is available, but not accessible; any use of it will be 32 | * an error. 33 | */ 34 | NotAccessible AvailabilityKind = C.CXAvailability_NotAccessible 35 | ) 36 | 37 | func (ak AvailabilityKind) String() string { 38 | switch ak { 39 | case Available: 40 | return "Available" 41 | case Deprecated: 42 | return "Deprecated" 43 | case NotAvailable: 44 | return "NotAvailable" 45 | case NotAccessible: 46 | return "NotAccessible" 47 | } 48 | return "" 49 | } 50 | -------------------------------------------------------------------------------- /callingconv.go: -------------------------------------------------------------------------------- 1 | package clang 2 | 3 | // #include 4 | // #include "go-clang.h" 5 | // 6 | import "C" 7 | 8 | // CallingConv describes the calling convention of a function type 9 | type CallingConv uint32 10 | 11 | const ( 12 | CallingConv_Default CallingConv = C.CXCallingConv_Default 13 | CallingConv_C = C.CXCallingConv_C 14 | CallingConv_X86StdCall = C.CXCallingConv_X86StdCall 15 | CallingConv_X86FastCall = C.CXCallingConv_X86FastCall 16 | CallingConv_X86ThisCall = C.CXCallingConv_X86ThisCall 17 | CallingConv_X86Pascal = C.CXCallingConv_X86Pascal 18 | CallingConv_CallingConv_AAPCS = C.CXCallingConv_AAPCS 19 | CallingConv_CallingConv_AAPCS_VFP = C.CXCallingConv_AAPCS_VFP 20 | CallingConv_PnaclCall = C.CXCallingConv_PnaclCall 21 | CallingConv_IntelOclBicc = C.CXCallingConv_IntelOclBicc 22 | CallingConv_X86_64Win64 = C.CXCallingConv_X86_64Win64 23 | CallingConv_X86_64SysV = C.CXCallingConv_X86_64SysV 24 | 25 | CallingConv_Invalid CallingConv = C.CXCallingConv_Invalid 26 | CallingConv_Unexposed = C.CXCallingConv_Unexposed 27 | ) 28 | -------------------------------------------------------------------------------- /cgoflags.go: -------------------------------------------------------------------------------- 1 | package clang 2 | 3 | // #cgo LDFLAGS: -lclang 4 | // #cgo CFLAGS: -I. 5 | import "C" 6 | 7 | //EOF 8 | -------------------------------------------------------------------------------- /cgoflags_darwin.go: -------------------------------------------------------------------------------- 1 | package clang 2 | 3 | // #cgo darwin LDFLAGS: -L/opt/local/libexec/llvm-3.5/lib 4 | import "C" 5 | 6 | //EOF 7 | -------------------------------------------------------------------------------- /cgoflags_droneio.go: -------------------------------------------------------------------------------- 1 | //+build droneio 2 | 3 | package clang 4 | 5 | // #cgo linux LDFLAGS: -L/usr/lib/llvm-3.5/lib 6 | import "C" 7 | -------------------------------------------------------------------------------- /cgoflags_linux.go: -------------------------------------------------------------------------------- 1 | package clang 2 | 3 | // #cgo LDFLAGS: -L/usr/lib/llvm 4 | import "C" 5 | 6 | //EOF 7 | -------------------------------------------------------------------------------- /clang-c/BuildSystem.h: -------------------------------------------------------------------------------- 1 | /*==-- clang-c/BuildSystem.h - Utilities for use by build systems -*- C -*-===*\ 2 | |* *| 3 | |* The LLVM Compiler Infrastructure *| 4 | |* *| 5 | |* This file is distributed under the University of Illinois Open Source *| 6 | |* License. See LICENSE.TXT for details. *| 7 | |* *| 8 | |*===----------------------------------------------------------------------===*| 9 | |* *| 10 | |* This header provides various utilities for use by build systems. *| 11 | |* *| 12 | \*===----------------------------------------------------------------------===*/ 13 | 14 | #ifndef CLANG_C_BUILD_SYSTEM_H 15 | #define CLANG_C_BUILD_SYSTEM_H 16 | 17 | #include "clang-c/Platform.h" 18 | #include "clang-c/CXErrorCode.h" 19 | #include "clang-c/CXString.h" 20 | 21 | #ifdef __cplusplus 22 | extern "C" { 23 | #endif 24 | 25 | /** 26 | * \defgroup BUILD_SYSTEM Build system utilities 27 | * @{ 28 | */ 29 | 30 | /** 31 | * \brief Return the timestamp for use with Clang's 32 | * \c -fbuild-session-timestamp= option. 33 | */ 34 | CINDEX_LINKAGE unsigned long long clang_getBuildSessionTimestamp(void); 35 | 36 | /** 37 | * \brief Object encapsulating information about overlaying virtual 38 | * file/directories over the real file system. 39 | */ 40 | typedef struct CXVirtualFileOverlayImpl *CXVirtualFileOverlay; 41 | 42 | /** 43 | * \brief Create a \c CXVirtualFileOverlay object. 44 | * Must be disposed with \c clang_VirtualFileOverlay_dispose(). 45 | * 46 | * \param options is reserved, always pass 0. 47 | */ 48 | CINDEX_LINKAGE CXVirtualFileOverlay 49 | clang_VirtualFileOverlay_create(unsigned options); 50 | 51 | /** 52 | * \brief Map an absolute virtual file path to an absolute real one. 53 | * The virtual path must be canonicalized (not contain "."/".."). 54 | * \returns 0 for success, non-zero to indicate an error. 55 | */ 56 | CINDEX_LINKAGE enum CXErrorCode 57 | clang_VirtualFileOverlay_addFileMapping(CXVirtualFileOverlay, 58 | const char *virtualPath, 59 | const char *realPath); 60 | 61 | /** 62 | * \brief Set the case sensitivity for the \c CXVirtualFileOverlay object. 63 | * The \c CXVirtualFileOverlay object is case-sensitive by default, this 64 | * option can be used to override the default. 65 | * \returns 0 for success, non-zero to indicate an error. 66 | */ 67 | CINDEX_LINKAGE enum CXErrorCode 68 | clang_VirtualFileOverlay_setCaseSensitivity(CXVirtualFileOverlay, 69 | int caseSensitive); 70 | 71 | /** 72 | * \brief Write out the \c CXVirtualFileOverlay object to a char buffer. 73 | * 74 | * \param options is reserved, always pass 0. 75 | * \param out_buffer_ptr pointer to receive the buffer pointer, which should be 76 | * disposed using \c free(). 77 | * \param out_buffer_size pointer to receive the buffer size. 78 | * \returns 0 for success, non-zero to indicate an error. 79 | */ 80 | CINDEX_LINKAGE enum CXErrorCode 81 | clang_VirtualFileOverlay_writeToBuffer(CXVirtualFileOverlay, unsigned options, 82 | char **out_buffer_ptr, 83 | unsigned *out_buffer_size); 84 | 85 | /** 86 | * \brief Dispose a \c CXVirtualFileOverlay object. 87 | */ 88 | CINDEX_LINKAGE void clang_VirtualFileOverlay_dispose(CXVirtualFileOverlay); 89 | 90 | /** 91 | * \brief Object encapsulating information about a module.map file. 92 | */ 93 | typedef struct CXModuleMapDescriptorImpl *CXModuleMapDescriptor; 94 | 95 | /** 96 | * \brief Create a \c CXModuleMapDescriptor object. 97 | * Must be disposed with \c clang_ModuleMapDescriptor_dispose(). 98 | * 99 | * \param options is reserved, always pass 0. 100 | */ 101 | CINDEX_LINKAGE CXModuleMapDescriptor 102 | clang_ModuleMapDescriptor_create(unsigned options); 103 | 104 | /** 105 | * \brief Sets the framework module name that the module.map describes. 106 | * \returns 0 for success, non-zero to indicate an error. 107 | */ 108 | CINDEX_LINKAGE enum CXErrorCode 109 | clang_ModuleMapDescriptor_setFrameworkModuleName(CXModuleMapDescriptor, 110 | const char *name); 111 | 112 | /** 113 | * \brief Sets the umbrealla header name that the module.map describes. 114 | * \returns 0 for success, non-zero to indicate an error. 115 | */ 116 | CINDEX_LINKAGE enum CXErrorCode 117 | clang_ModuleMapDescriptor_setUmbrellaHeader(CXModuleMapDescriptor, 118 | const char *name); 119 | 120 | /** 121 | * \brief Write out the \c CXModuleMapDescriptor object to a char buffer. 122 | * 123 | * \param options is reserved, always pass 0. 124 | * \param out_buffer_ptr pointer to receive the buffer pointer, which should be 125 | * disposed using \c free(). 126 | * \param out_buffer_size pointer to receive the buffer size. 127 | * \returns 0 for success, non-zero to indicate an error. 128 | */ 129 | CINDEX_LINKAGE enum CXErrorCode 130 | clang_ModuleMapDescriptor_writeToBuffer(CXModuleMapDescriptor, unsigned options, 131 | char **out_buffer_ptr, 132 | unsigned *out_buffer_size); 133 | 134 | /** 135 | * \brief Dispose a \c CXModuleMapDescriptor object. 136 | */ 137 | CINDEX_LINKAGE void clang_ModuleMapDescriptor_dispose(CXModuleMapDescriptor); 138 | 139 | /** 140 | * @} 141 | */ 142 | 143 | #ifdef __cplusplus 144 | } 145 | #endif 146 | 147 | #endif /* CLANG_C_BUILD_SYSTEM_H */ 148 | 149 | -------------------------------------------------------------------------------- /clang-c/CXCompilationDatabase.h: -------------------------------------------------------------------------------- 1 | /*===-- clang-c/CXCompilationDatabase.h - Compilation database ---*- C -*-===*\ 2 | |* *| 3 | |* The LLVM Compiler Infrastructure *| 4 | |* *| 5 | |* This file is distributed under the University of Illinois Open Source *| 6 | |* License. See LICENSE.TXT for details. *| 7 | |* *| 8 | |*===----------------------------------------------------------------------===*| 9 | |* *| 10 | |* This header provides a public inferface to use CompilationDatabase without *| 11 | |* the full Clang C++ API. *| 12 | |* *| 13 | \*===----------------------------------------------------------------------===*/ 14 | 15 | #ifndef CLANG_CXCOMPILATIONDATABASE_H 16 | #define CLANG_CXCOMPILATIONDATABASE_H 17 | 18 | #include "clang-c/Platform.h" 19 | #include "clang-c/CXString.h" 20 | 21 | #ifdef __cplusplus 22 | extern "C" { 23 | #endif 24 | 25 | /** \defgroup COMPILATIONDB CompilationDatabase functions 26 | * \ingroup CINDEX 27 | * 28 | * @{ 29 | */ 30 | 31 | /** 32 | * A compilation database holds all information used to compile files in a 33 | * project. For each file in the database, it can be queried for the working 34 | * directory or the command line used for the compiler invocation. 35 | * 36 | * Must be freed by \c clang_CompilationDatabase_dispose 37 | */ 38 | typedef void * CXCompilationDatabase; 39 | 40 | /** 41 | * \brief Contains the results of a search in the compilation database 42 | * 43 | * When searching for the compile command for a file, the compilation db can 44 | * return several commands, as the file may have been compiled with 45 | * different options in different places of the project. This choice of compile 46 | * commands is wrapped in this opaque data structure. It must be freed by 47 | * \c clang_CompileCommands_dispose. 48 | */ 49 | typedef void * CXCompileCommands; 50 | 51 | /** 52 | * \brief Represents the command line invocation to compile a specific file. 53 | */ 54 | typedef void * CXCompileCommand; 55 | 56 | /** 57 | * \brief Error codes for Compilation Database 58 | */ 59 | typedef enum { 60 | /* 61 | * \brief No error occurred 62 | */ 63 | CXCompilationDatabase_NoError = 0, 64 | 65 | /* 66 | * \brief Database can not be loaded 67 | */ 68 | CXCompilationDatabase_CanNotLoadDatabase = 1 69 | 70 | } CXCompilationDatabase_Error; 71 | 72 | /** 73 | * \brief Creates a compilation database from the database found in directory 74 | * buildDir. For example, CMake can output a compile_commands.json which can 75 | * be used to build the database. 76 | * 77 | * It must be freed by \c clang_CompilationDatabase_dispose. 78 | */ 79 | CINDEX_LINKAGE CXCompilationDatabase 80 | clang_CompilationDatabase_fromDirectory(const char *BuildDir, 81 | CXCompilationDatabase_Error *ErrorCode); 82 | 83 | /** 84 | * \brief Free the given compilation database 85 | */ 86 | CINDEX_LINKAGE void 87 | clang_CompilationDatabase_dispose(CXCompilationDatabase); 88 | 89 | /** 90 | * \brief Find the compile commands used for a file. The compile commands 91 | * must be freed by \c clang_CompileCommands_dispose. 92 | */ 93 | CINDEX_LINKAGE CXCompileCommands 94 | clang_CompilationDatabase_getCompileCommands(CXCompilationDatabase, 95 | const char *CompleteFileName); 96 | 97 | /** 98 | * \brief Get all the compile commands in the given compilation database. 99 | */ 100 | CINDEX_LINKAGE CXCompileCommands 101 | clang_CompilationDatabase_getAllCompileCommands(CXCompilationDatabase); 102 | 103 | /** 104 | * \brief Free the given CompileCommands 105 | */ 106 | CINDEX_LINKAGE void clang_CompileCommands_dispose(CXCompileCommands); 107 | 108 | /** 109 | * \brief Get the number of CompileCommand we have for a file 110 | */ 111 | CINDEX_LINKAGE unsigned 112 | clang_CompileCommands_getSize(CXCompileCommands); 113 | 114 | /** 115 | * \brief Get the I'th CompileCommand for a file 116 | * 117 | * Note : 0 <= i < clang_CompileCommands_getSize(CXCompileCommands) 118 | */ 119 | CINDEX_LINKAGE CXCompileCommand 120 | clang_CompileCommands_getCommand(CXCompileCommands, unsigned I); 121 | 122 | /** 123 | * \brief Get the working directory where the CompileCommand was executed from 124 | */ 125 | CINDEX_LINKAGE CXString 126 | clang_CompileCommand_getDirectory(CXCompileCommand); 127 | 128 | /** 129 | * \brief Get the number of arguments in the compiler invocation. 130 | * 131 | */ 132 | CINDEX_LINKAGE unsigned 133 | clang_CompileCommand_getNumArgs(CXCompileCommand); 134 | 135 | /** 136 | * \brief Get the I'th argument value in the compiler invocations 137 | * 138 | * Invariant : 139 | * - argument 0 is the compiler executable 140 | */ 141 | CINDEX_LINKAGE CXString 142 | clang_CompileCommand_getArg(CXCompileCommand, unsigned I); 143 | 144 | /** 145 | * \brief Get the number of source mappings for the compiler invocation. 146 | */ 147 | CINDEX_LINKAGE unsigned 148 | clang_CompileCommand_getNumMappedSources(CXCompileCommand); 149 | 150 | /** 151 | * \brief Get the I'th mapped source path for the compiler invocation. 152 | */ 153 | CINDEX_LINKAGE CXString 154 | clang_CompileCommand_getMappedSourcePath(CXCompileCommand, unsigned I); 155 | 156 | /** 157 | * \brief Get the I'th mapped source content for the compiler invocation. 158 | */ 159 | CINDEX_LINKAGE CXString 160 | clang_CompileCommand_getMappedSourceContent(CXCompileCommand, unsigned I); 161 | 162 | /** 163 | * @} 164 | */ 165 | 166 | #ifdef __cplusplus 167 | } 168 | #endif 169 | #endif 170 | 171 | -------------------------------------------------------------------------------- /clang-c/CXErrorCode.h: -------------------------------------------------------------------------------- 1 | /*===-- clang-c/CXErrorCode.h - C Index Error Codes --------------*- C -*-===*\ 2 | |* *| 3 | |* The LLVM Compiler Infrastructure *| 4 | |* *| 5 | |* This file is distributed under the University of Illinois Open Source *| 6 | |* License. See LICENSE.TXT for details. *| 7 | |* *| 8 | |*===----------------------------------------------------------------------===*| 9 | |* *| 10 | |* This header provides the CXErrorCode enumerators. *| 11 | |* *| 12 | \*===----------------------------------------------------------------------===*/ 13 | 14 | #ifndef CLANG_C_CXERRORCODE_H 15 | #define CLANG_C_CXERRORCODE_H 16 | 17 | #include "clang-c/Platform.h" 18 | 19 | #ifdef __cplusplus 20 | extern "C" { 21 | #endif 22 | 23 | /** 24 | * \brief Error codes returned by libclang routines. 25 | * 26 | * Zero (\c CXError_Success) is the only error code indicating success. Other 27 | * error codes, including not yet assigned non-zero values, indicate errors. 28 | */ 29 | enum CXErrorCode { 30 | /** 31 | * \brief No error. 32 | */ 33 | CXError_Success = 0, 34 | 35 | /** 36 | * \brief A generic error code, no further details are available. 37 | * 38 | * Errors of this kind can get their own specific error codes in future 39 | * libclang versions. 40 | */ 41 | CXError_Failure = 1, 42 | 43 | /** 44 | * \brief libclang crashed while performing the requested operation. 45 | */ 46 | CXError_Crashed = 2, 47 | 48 | /** 49 | * \brief The function detected that the arguments violate the function 50 | * contract. 51 | */ 52 | CXError_InvalidArguments = 3, 53 | 54 | /** 55 | * \brief An AST deserialization error has occurred. 56 | */ 57 | CXError_ASTReadError = 4 58 | }; 59 | 60 | #ifdef __cplusplus 61 | } 62 | #endif 63 | #endif 64 | 65 | -------------------------------------------------------------------------------- /clang-c/CXString.h: -------------------------------------------------------------------------------- 1 | /*===-- clang-c/CXString.h - C Index strings --------------------*- C -*-===*\ 2 | |* *| 3 | |* The LLVM Compiler Infrastructure *| 4 | |* *| 5 | |* This file is distributed under the University of Illinois Open Source *| 6 | |* License. See LICENSE.TXT for details. *| 7 | |* *| 8 | |*===----------------------------------------------------------------------===*| 9 | |* *| 10 | |* This header provides the interface to C Index strings. *| 11 | |* *| 12 | \*===----------------------------------------------------------------------===*/ 13 | 14 | #ifndef CLANG_CXSTRING_H 15 | #define CLANG_CXSTRING_H 16 | 17 | #include /* go-clang: for uintptr_t */ 18 | 19 | #include "clang-c/Platform.h" 20 | 21 | #ifdef __cplusplus 22 | extern "C" { 23 | #endif 24 | 25 | /** 26 | * \defgroup CINDEX_STRING String manipulation routines 27 | * \ingroup CINDEX 28 | * 29 | * @{ 30 | */ 31 | 32 | /** 33 | * \brief A character string. 34 | * 35 | * The \c CXString type is used to return strings from the interface when 36 | * the ownership of that string might differ from one call to the next. 37 | * Use \c clang_getCString() to retrieve the string data and, once finished 38 | * with the string data, call \c clang_disposeString() to free the string. 39 | */ 40 | typedef struct { 41 | uintptr_t data; 42 | unsigned private_flags; 43 | } CXString; 44 | 45 | /** 46 | * \brief Retrieve the character data associated with the given string. 47 | */ 48 | CINDEX_LINKAGE const char *clang_getCString(CXString string); 49 | 50 | /** 51 | * \brief Free the given string. 52 | */ 53 | CINDEX_LINKAGE void clang_disposeString(CXString string); 54 | 55 | /** 56 | * @} 57 | */ 58 | 59 | #ifdef __cplusplus 60 | } 61 | #endif 62 | #endif 63 | 64 | -------------------------------------------------------------------------------- /clang-c/Documentation.h: -------------------------------------------------------------------------------- 1 | /*==-- clang-c/Documentation.h - Utilities for comment processing -*- C -*-===*\ 2 | |* *| 3 | |* The LLVM Compiler Infrastructure *| 4 | |* *| 5 | |* This file is distributed under the University of Illinois Open Source *| 6 | |* License. See LICENSE.TXT for details. *| 7 | |* *| 8 | |*===----------------------------------------------------------------------===*| 9 | |* *| 10 | |* This header provides a supplementary interface for inspecting *| 11 | |* documentation comments. *| 12 | |* *| 13 | \*===----------------------------------------------------------------------===*/ 14 | 15 | #ifndef CLANG_C_DOCUMENTATION_H 16 | #define CLANG_C_DOCUMENTATION_H 17 | 18 | #include /* go-clang: for uintptr_t */ 19 | #include "clang-c/Index.h" 20 | 21 | #ifdef __cplusplus 22 | extern "C" { 23 | #endif 24 | 25 | /** 26 | * \defgroup CINDEX_COMMENT Comment introspection 27 | * 28 | * The routines in this group provide access to information in documentation 29 | * comments. These facilities are distinct from the core and may be subject to 30 | * their own schedule of stability and deprecation. 31 | * 32 | * @{ 33 | */ 34 | 35 | /** 36 | * \brief A parsed comment. 37 | */ 38 | typedef struct { 39 | uintptr_t ASTNode; 40 | CXTranslationUnit TranslationUnit; 41 | } CXComment; 42 | 43 | /** 44 | * \brief Given a cursor that represents a documentable entity (e.g., 45 | * declaration), return the associated parsed comment as a 46 | * \c CXComment_FullComment AST node. 47 | */ 48 | CINDEX_LINKAGE CXComment clang_Cursor_getParsedComment(CXCursor C); 49 | 50 | /** 51 | * \brief Describes the type of the comment AST node (\c CXComment). A comment 52 | * node can be considered block content (e. g., paragraph), inline content 53 | * (plain text) or neither (the root AST node). 54 | */ 55 | enum CXCommentKind { 56 | /** 57 | * \brief Null comment. No AST node is constructed at the requested location 58 | * because there is no text or a syntax error. 59 | */ 60 | CXComment_Null = 0, 61 | 62 | /** 63 | * \brief Plain text. Inline content. 64 | */ 65 | CXComment_Text = 1, 66 | 67 | /** 68 | * \brief A command with word-like arguments that is considered inline content. 69 | * 70 | * For example: \\c command. 71 | */ 72 | CXComment_InlineCommand = 2, 73 | 74 | /** 75 | * \brief HTML start tag with attributes (name-value pairs). Considered 76 | * inline content. 77 | * 78 | * For example: 79 | * \verbatim 80 | *

81 | * \endverbatim 82 | */ 83 | CXComment_HTMLStartTag = 3, 84 | 85 | /** 86 | * \brief HTML end tag. Considered inline content. 87 | * 88 | * For example: 89 | * \verbatim 90 | * 91 | * \endverbatim 92 | */ 93 | CXComment_HTMLEndTag = 4, 94 | 95 | /** 96 | * \brief A paragraph, contains inline comment. The paragraph itself is 97 | * block content. 98 | */ 99 | CXComment_Paragraph = 5, 100 | 101 | /** 102 | * \brief A command that has zero or more word-like arguments (number of 103 | * word-like arguments depends on command name) and a paragraph as an 104 | * argument. Block command is block content. 105 | * 106 | * Paragraph argument is also a child of the block command. 107 | * 108 | * For example: \\brief has 0 word-like arguments and a paragraph argument. 109 | * 110 | * AST nodes of special kinds that parser knows about (e. g., \\param 111 | * command) have their own node kinds. 112 | */ 113 | CXComment_BlockCommand = 6, 114 | 115 | /** 116 | * \brief A \\param or \\arg command that describes the function parameter 117 | * (name, passing direction, description). 118 | * 119 | * For example: \\param [in] ParamName description. 120 | */ 121 | CXComment_ParamCommand = 7, 122 | 123 | /** 124 | * \brief A \\tparam command that describes a template parameter (name and 125 | * description). 126 | * 127 | * For example: \\tparam T description. 128 | */ 129 | CXComment_TParamCommand = 8, 130 | 131 | /** 132 | * \brief A verbatim block command (e. g., preformatted code). Verbatim 133 | * block has an opening and a closing command and contains multiple lines of 134 | * text (\c CXComment_VerbatimBlockLine child nodes). 135 | * 136 | * For example: 137 | * \\verbatim 138 | * aaa 139 | * \\endverbatim 140 | */ 141 | CXComment_VerbatimBlockCommand = 9, 142 | 143 | /** 144 | * \brief A line of text that is contained within a 145 | * CXComment_VerbatimBlockCommand node. 146 | */ 147 | CXComment_VerbatimBlockLine = 10, 148 | 149 | /** 150 | * \brief A verbatim line command. Verbatim line has an opening command, 151 | * a single line of text (up to the newline after the opening command) and 152 | * has no closing command. 153 | */ 154 | CXComment_VerbatimLine = 11, 155 | 156 | /** 157 | * \brief A full comment attached to a declaration, contains block content. 158 | */ 159 | CXComment_FullComment = 12 160 | }; 161 | 162 | /** 163 | * \brief The most appropriate rendering mode for an inline command, chosen on 164 | * command semantics in Doxygen. 165 | */ 166 | enum CXCommentInlineCommandRenderKind { 167 | /** 168 | * \brief Command argument should be rendered in a normal font. 169 | */ 170 | CXCommentInlineCommandRenderKind_Normal, 171 | 172 | /** 173 | * \brief Command argument should be rendered in a bold font. 174 | */ 175 | CXCommentInlineCommandRenderKind_Bold, 176 | 177 | /** 178 | * \brief Command argument should be rendered in a monospaced font. 179 | */ 180 | CXCommentInlineCommandRenderKind_Monospaced, 181 | 182 | /** 183 | * \brief Command argument should be rendered emphasized (typically italic 184 | * font). 185 | */ 186 | CXCommentInlineCommandRenderKind_Emphasized 187 | }; 188 | 189 | /** 190 | * \brief Describes parameter passing direction for \\param or \\arg command. 191 | */ 192 | enum CXCommentParamPassDirection { 193 | /** 194 | * \brief The parameter is an input parameter. 195 | */ 196 | CXCommentParamPassDirection_In, 197 | 198 | /** 199 | * \brief The parameter is an output parameter. 200 | */ 201 | CXCommentParamPassDirection_Out, 202 | 203 | /** 204 | * \brief The parameter is an input and output parameter. 205 | */ 206 | CXCommentParamPassDirection_InOut 207 | }; 208 | 209 | /** 210 | * \param Comment AST node of any kind. 211 | * 212 | * \returns the type of the AST node. 213 | */ 214 | CINDEX_LINKAGE enum CXCommentKind clang_Comment_getKind(CXComment Comment); 215 | 216 | /** 217 | * \param Comment AST node of any kind. 218 | * 219 | * \returns number of children of the AST node. 220 | */ 221 | CINDEX_LINKAGE unsigned clang_Comment_getNumChildren(CXComment Comment); 222 | 223 | /** 224 | * \param Comment AST node of any kind. 225 | * 226 | * \param ChildIdx child index (zero-based). 227 | * 228 | * \returns the specified child of the AST node. 229 | */ 230 | CINDEX_LINKAGE 231 | CXComment clang_Comment_getChild(CXComment Comment, unsigned ChildIdx); 232 | 233 | /** 234 | * \brief A \c CXComment_Paragraph node is considered whitespace if it contains 235 | * only \c CXComment_Text nodes that are empty or whitespace. 236 | * 237 | * Other AST nodes (except \c CXComment_Paragraph and \c CXComment_Text) are 238 | * never considered whitespace. 239 | * 240 | * \returns non-zero if \c Comment is whitespace. 241 | */ 242 | CINDEX_LINKAGE unsigned clang_Comment_isWhitespace(CXComment Comment); 243 | 244 | /** 245 | * \returns non-zero if \c Comment is inline content and has a newline 246 | * immediately following it in the comment text. Newlines between paragraphs 247 | * do not count. 248 | */ 249 | CINDEX_LINKAGE 250 | unsigned clang_InlineContentComment_hasTrailingNewline(CXComment Comment); 251 | 252 | /** 253 | * \param Comment a \c CXComment_Text AST node. 254 | * 255 | * \returns text contained in the AST node. 256 | */ 257 | CINDEX_LINKAGE CXString clang_TextComment_getText(CXComment Comment); 258 | 259 | /** 260 | * \param Comment a \c CXComment_InlineCommand AST node. 261 | * 262 | * \returns name of the inline command. 263 | */ 264 | CINDEX_LINKAGE 265 | CXString clang_InlineCommandComment_getCommandName(CXComment Comment); 266 | 267 | /** 268 | * \param Comment a \c CXComment_InlineCommand AST node. 269 | * 270 | * \returns the most appropriate rendering mode, chosen on command 271 | * semantics in Doxygen. 272 | */ 273 | CINDEX_LINKAGE enum CXCommentInlineCommandRenderKind 274 | clang_InlineCommandComment_getRenderKind(CXComment Comment); 275 | 276 | /** 277 | * \param Comment a \c CXComment_InlineCommand AST node. 278 | * 279 | * \returns number of command arguments. 280 | */ 281 | CINDEX_LINKAGE 282 | unsigned clang_InlineCommandComment_getNumArgs(CXComment Comment); 283 | 284 | /** 285 | * \param Comment a \c CXComment_InlineCommand AST node. 286 | * 287 | * \param ArgIdx argument index (zero-based). 288 | * 289 | * \returns text of the specified argument. 290 | */ 291 | CINDEX_LINKAGE 292 | CXString clang_InlineCommandComment_getArgText(CXComment Comment, 293 | unsigned ArgIdx); 294 | 295 | /** 296 | * \param Comment a \c CXComment_HTMLStartTag or \c CXComment_HTMLEndTag AST 297 | * node. 298 | * 299 | * \returns HTML tag name. 300 | */ 301 | CINDEX_LINKAGE CXString clang_HTMLTagComment_getTagName(CXComment Comment); 302 | 303 | /** 304 | * \param Comment a \c CXComment_HTMLStartTag AST node. 305 | * 306 | * \returns non-zero if tag is self-closing (for example, <br />). 307 | */ 308 | CINDEX_LINKAGE 309 | unsigned clang_HTMLStartTagComment_isSelfClosing(CXComment Comment); 310 | 311 | /** 312 | * \param Comment a \c CXComment_HTMLStartTag AST node. 313 | * 314 | * \returns number of attributes (name-value pairs) attached to the start tag. 315 | */ 316 | CINDEX_LINKAGE unsigned clang_HTMLStartTag_getNumAttrs(CXComment Comment); 317 | 318 | /** 319 | * \param Comment a \c CXComment_HTMLStartTag AST node. 320 | * 321 | * \param AttrIdx attribute index (zero-based). 322 | * 323 | * \returns name of the specified attribute. 324 | */ 325 | CINDEX_LINKAGE 326 | CXString clang_HTMLStartTag_getAttrName(CXComment Comment, unsigned AttrIdx); 327 | 328 | /** 329 | * \param Comment a \c CXComment_HTMLStartTag AST node. 330 | * 331 | * \param AttrIdx attribute index (zero-based). 332 | * 333 | * \returns value of the specified attribute. 334 | */ 335 | CINDEX_LINKAGE 336 | CXString clang_HTMLStartTag_getAttrValue(CXComment Comment, unsigned AttrIdx); 337 | 338 | /** 339 | * \param Comment a \c CXComment_BlockCommand AST node. 340 | * 341 | * \returns name of the block command. 342 | */ 343 | CINDEX_LINKAGE 344 | CXString clang_BlockCommandComment_getCommandName(CXComment Comment); 345 | 346 | /** 347 | * \param Comment a \c CXComment_BlockCommand AST node. 348 | * 349 | * \returns number of word-like arguments. 350 | */ 351 | CINDEX_LINKAGE 352 | unsigned clang_BlockCommandComment_getNumArgs(CXComment Comment); 353 | 354 | /** 355 | * \param Comment a \c CXComment_BlockCommand AST node. 356 | * 357 | * \param ArgIdx argument index (zero-based). 358 | * 359 | * \returns text of the specified word-like argument. 360 | */ 361 | CINDEX_LINKAGE 362 | CXString clang_BlockCommandComment_getArgText(CXComment Comment, 363 | unsigned ArgIdx); 364 | 365 | /** 366 | * \param Comment a \c CXComment_BlockCommand or 367 | * \c CXComment_VerbatimBlockCommand AST node. 368 | * 369 | * \returns paragraph argument of the block command. 370 | */ 371 | CINDEX_LINKAGE 372 | CXComment clang_BlockCommandComment_getParagraph(CXComment Comment); 373 | 374 | /** 375 | * \param Comment a \c CXComment_ParamCommand AST node. 376 | * 377 | * \returns parameter name. 378 | */ 379 | CINDEX_LINKAGE 380 | CXString clang_ParamCommandComment_getParamName(CXComment Comment); 381 | 382 | /** 383 | * \param Comment a \c CXComment_ParamCommand AST node. 384 | * 385 | * \returns non-zero if the parameter that this AST node represents was found 386 | * in the function prototype and \c clang_ParamCommandComment_getParamIndex 387 | * function will return a meaningful value. 388 | */ 389 | CINDEX_LINKAGE 390 | unsigned clang_ParamCommandComment_isParamIndexValid(CXComment Comment); 391 | 392 | /** 393 | * \param Comment a \c CXComment_ParamCommand AST node. 394 | * 395 | * \returns zero-based parameter index in function prototype. 396 | */ 397 | CINDEX_LINKAGE 398 | unsigned clang_ParamCommandComment_getParamIndex(CXComment Comment); 399 | 400 | /** 401 | * \param Comment a \c CXComment_ParamCommand AST node. 402 | * 403 | * \returns non-zero if parameter passing direction was specified explicitly in 404 | * the comment. 405 | */ 406 | CINDEX_LINKAGE 407 | unsigned clang_ParamCommandComment_isDirectionExplicit(CXComment Comment); 408 | 409 | /** 410 | * \param Comment a \c CXComment_ParamCommand AST node. 411 | * 412 | * \returns parameter passing direction. 413 | */ 414 | CINDEX_LINKAGE 415 | enum CXCommentParamPassDirection clang_ParamCommandComment_getDirection( 416 | CXComment Comment); 417 | 418 | /** 419 | * \param Comment a \c CXComment_TParamCommand AST node. 420 | * 421 | * \returns template parameter name. 422 | */ 423 | CINDEX_LINKAGE 424 | CXString clang_TParamCommandComment_getParamName(CXComment Comment); 425 | 426 | /** 427 | * \param Comment a \c CXComment_TParamCommand AST node. 428 | * 429 | * \returns non-zero if the parameter that this AST node represents was found 430 | * in the template parameter list and 431 | * \c clang_TParamCommandComment_getDepth and 432 | * \c clang_TParamCommandComment_getIndex functions will return a meaningful 433 | * value. 434 | */ 435 | CINDEX_LINKAGE 436 | unsigned clang_TParamCommandComment_isParamPositionValid(CXComment Comment); 437 | 438 | /** 439 | * \param Comment a \c CXComment_TParamCommand AST node. 440 | * 441 | * \returns zero-based nesting depth of this parameter in the template parameter list. 442 | * 443 | * For example, 444 | * \verbatim 445 | * template class TT> 446 | * void test(TT aaa); 447 | * \endverbatim 448 | * for C and TT nesting depth is 0, 449 | * for T nesting depth is 1. 450 | */ 451 | CINDEX_LINKAGE 452 | unsigned clang_TParamCommandComment_getDepth(CXComment Comment); 453 | 454 | /** 455 | * \param Comment a \c CXComment_TParamCommand AST node. 456 | * 457 | * \returns zero-based parameter index in the template parameter list at a 458 | * given nesting depth. 459 | * 460 | * For example, 461 | * \verbatim 462 | * template class TT> 463 | * void test(TT aaa); 464 | * \endverbatim 465 | * for C and TT nesting depth is 0, so we can ask for index at depth 0: 466 | * at depth 0 C's index is 0, TT's index is 1. 467 | * 468 | * For T nesting depth is 1, so we can ask for index at depth 0 and 1: 469 | * at depth 0 T's index is 1 (same as TT's), 470 | * at depth 1 T's index is 0. 471 | */ 472 | CINDEX_LINKAGE 473 | unsigned clang_TParamCommandComment_getIndex(CXComment Comment, unsigned Depth); 474 | 475 | /** 476 | * \param Comment a \c CXComment_VerbatimBlockLine AST node. 477 | * 478 | * \returns text contained in the AST node. 479 | */ 480 | CINDEX_LINKAGE 481 | CXString clang_VerbatimBlockLineComment_getText(CXComment Comment); 482 | 483 | /** 484 | * \param Comment a \c CXComment_VerbatimLine AST node. 485 | * 486 | * \returns text contained in the AST node. 487 | */ 488 | CINDEX_LINKAGE CXString clang_VerbatimLineComment_getText(CXComment Comment); 489 | 490 | /** 491 | * \brief Convert an HTML tag AST node to string. 492 | * 493 | * \param Comment a \c CXComment_HTMLStartTag or \c CXComment_HTMLEndTag AST 494 | * node. 495 | * 496 | * \returns string containing an HTML tag. 497 | */ 498 | CINDEX_LINKAGE CXString clang_HTMLTagComment_getAsString(CXComment Comment); 499 | 500 | /** 501 | * \brief Convert a given full parsed comment to an HTML fragment. 502 | * 503 | * Specific details of HTML layout are subject to change. Don't try to parse 504 | * this HTML back into an AST, use other APIs instead. 505 | * 506 | * Currently the following CSS classes are used: 507 | * \li "para-brief" for \\brief paragraph and equivalent commands; 508 | * \li "para-returns" for \\returns paragraph and equivalent commands; 509 | * \li "word-returns" for the "Returns" word in \\returns paragraph. 510 | * 511 | * Function argument documentation is rendered as a \ list with arguments 512 | * sorted in function prototype order. CSS classes used: 513 | * \li "param-name-index-NUMBER" for parameter name (\); 514 | * \li "param-descr-index-NUMBER" for parameter description (\); 515 | * \li "param-name-index-invalid" and "param-descr-index-invalid" are used if 516 | * parameter index is invalid. 517 | * 518 | * Template parameter documentation is rendered as a \ list with 519 | * parameters sorted in template parameter list order. CSS classes used: 520 | * \li "tparam-name-index-NUMBER" for parameter name (\); 521 | * \li "tparam-descr-index-NUMBER" for parameter description (\); 522 | * \li "tparam-name-index-other" and "tparam-descr-index-other" are used for 523 | * names inside template template parameters; 524 | * \li "tparam-name-index-invalid" and "tparam-descr-index-invalid" are used if 525 | * parameter position is invalid. 526 | * 527 | * \param Comment a \c CXComment_FullComment AST node. 528 | * 529 | * \returns string containing an HTML fragment. 530 | */ 531 | CINDEX_LINKAGE CXString clang_FullComment_getAsHTML(CXComment Comment); 532 | 533 | /** 534 | * \brief Convert a given full parsed comment to an XML document. 535 | * 536 | * A Relax NG schema for the XML can be found in comment-xml-schema.rng file 537 | * inside clang source tree. 538 | * 539 | * \param Comment a \c CXComment_FullComment AST node. 540 | * 541 | * \returns string containing an XML document. 542 | */ 543 | CINDEX_LINKAGE CXString clang_FullComment_getAsXML(CXComment Comment); 544 | 545 | /** 546 | * @} 547 | */ 548 | 549 | 550 | #ifdef __cplusplus 551 | } 552 | #endif 553 | 554 | #endif /* CLANG_C_DOCUMENTATION_H */ 555 | 556 | -------------------------------------------------------------------------------- /clang-c/Platform.h: -------------------------------------------------------------------------------- 1 | /*===-- clang-c/Platform.h - C Index platform decls -------------*- C -*-===*\ 2 | |* *| 3 | |* The LLVM Compiler Infrastructure *| 4 | |* *| 5 | |* This file is distributed under the University of Illinois Open Source *| 6 | |* License. See LICENSE.TXT for details. *| 7 | |* *| 8 | |*===----------------------------------------------------------------------===*| 9 | |* *| 10 | |* This header provides platform specific macros (dllimport, deprecated, ...) *| 11 | |* *| 12 | \*===----------------------------------------------------------------------===*/ 13 | 14 | #ifndef CLANG_C_PLATFORM_H 15 | #define CLANG_C_PLATFORM_H 16 | 17 | #ifdef __cplusplus 18 | extern "C" { 19 | #endif 20 | 21 | /* MSVC DLL import/export. */ 22 | #ifdef _MSC_VER 23 | #ifdef _CINDEX_LIB_ 24 | #define CINDEX_LINKAGE __declspec(dllexport) 25 | #else 26 | #define CINDEX_LINKAGE __declspec(dllimport) 27 | #endif 28 | #else 29 | #define CINDEX_LINKAGE 30 | #endif 31 | 32 | #ifdef __GNUC__ 33 | #define CINDEX_DEPRECATED __attribute__((deprecated)) 34 | #else 35 | #ifdef _MSC_VER 36 | #define CINDEX_DEPRECATED __declspec(deprecated) 37 | #else 38 | #define CINDEX_DEPRECATED 39 | #endif 40 | #endif 41 | 42 | #ifdef __cplusplus 43 | } 44 | #endif 45 | #endif 46 | -------------------------------------------------------------------------------- /clang-c/module.modulemap: -------------------------------------------------------------------------------- 1 | module Clang_C { 2 | umbrella "." 3 | module * { export * } 4 | } 5 | -------------------------------------------------------------------------------- /clang.go: -------------------------------------------------------------------------------- 1 | package clang 2 | 3 | // #include 4 | // #include "go-clang.h" 5 | import "C" 6 | 7 | import ( 8 | "unsafe" 9 | ) 10 | 11 | // An "index" that consists of a set of translation units that would 12 | // typically be linked together into an executable or library 13 | type Index struct { 14 | c C.CXIndex 15 | } 16 | 17 | // NewIndex provides a shared context for creating 18 | // translation units. It provides two options: 19 | // 20 | // - excludeDeclarationsFromPCH: When non-zero, allows enumeration of "local" 21 | // declarations (when loading any new translation units). A "local" declaration 22 | // is one that belongs in the translation unit itself and not in a precompiled 23 | // header that was used by the translation unit. If zero, all declarations 24 | // will be enumerated. 25 | // 26 | // Here is an example: 27 | // 28 | // // excludeDeclsFromPCH = 1, displayDiagnostics=1 29 | // Idx = clang_createIndex(1, 1); 30 | // 31 | // // IndexTest.pch was produced with the following command: 32 | // // "clang -x c IndexTest.h -emit-ast -o IndexTest.pch" 33 | // TU = clang_createTranslationUnit(Idx, "IndexTest.pch"); 34 | // 35 | // // This will load all the symbols from 'IndexTest.pch' 36 | // clang_visitChildren(clang_getTranslationUnitCursor(TU), 37 | // TranslationUnitVisitor, 0); 38 | // clang_disposeTranslationUnit(TU); 39 | // 40 | // // This will load all the symbols from 'IndexTest.c', excluding symbols 41 | // // from 'IndexTest.pch'. 42 | // char *args[] = { "-Xclang", "-include-pch=IndexTest.pch" }; 43 | // TU = clang_createTranslationUnitFromSourceFile(Idx, "IndexTest.c", 2, args, 44 | // 0, 0); 45 | // clang_visitChildren(clang_getTranslationUnitCursor(TU), 46 | // TranslationUnitVisitor, 0); 47 | // clang_disposeTranslationUnit(TU); 48 | // 49 | // This process of creating the 'pch', loading it separately, and using it (via 50 | // -include-pch) allows 'excludeDeclsFromPCH' to remove redundant callbacks 51 | // (which gives the indexer the same performance benefit as the compiler). 52 | func NewIndex(excludeDeclarationsFromPCH, displayDiagnostics int) Index { 53 | idx := C.clang_createIndex(C.int(excludeDeclarationsFromPCH), 54 | C.int(displayDiagnostics)) 55 | return Index{idx} 56 | } 57 | 58 | // Dispose destroys the given index. 59 | // 60 | // The index must not be destroyed until all of the translation units created 61 | // within that index have been destroyed. 62 | func (idx Index) Dispose() { 63 | C.clang_disposeIndex(idx.c) 64 | } 65 | 66 | /** 67 | * \brief Create a translation unit from an AST file (-emit-ast). 68 | */ 69 | func (idx Index) CreateTranslationUnit(fname string) TranslationUnit { 70 | cstr := C.CString(fname) 71 | defer C.free(unsafe.Pointer(cstr)) 72 | o := C.clang_createTranslationUnit(idx.c, cstr) 73 | return TranslationUnit{o} 74 | } 75 | 76 | /** 77 | * \brief Return the CXTranslationUnit for a given source file and the provided 78 | * command line arguments one would pass to the compiler. 79 | * 80 | * Note: The 'source_filename' argument is optional. If the caller provides a 81 | * NULL pointer, the name of the source file is expected to reside in the 82 | * specified command line arguments. 83 | * 84 | * Note: When encountered in 'clang_command_line_args', the following options 85 | * are ignored: 86 | * 87 | * '-c' 88 | * '-emit-ast' 89 | * '-fsyntax-only' 90 | * '-o ' (both '-o' and '' are ignored) 91 | * 92 | * \param CIdx The index object with which the translation unit will be 93 | * associated. 94 | * 95 | * \param source_filename - The name of the source file to load, or NULL if the 96 | * source file is included in \p clang_command_line_args. 97 | * 98 | * \param num_clang_command_line_args The number of command-line arguments in 99 | * \p clang_command_line_args. 100 | * 101 | * \param clang_command_line_args The command-line arguments that would be 102 | * passed to the \c clang executable if it were being invoked out-of-process. 103 | * These command-line options will be parsed and will affect how the translation 104 | * unit is parsed. Note that the following options are ignored: '-c', 105 | * '-emit-ast', '-fsyntex-only' (which is the default), and '-o '. 106 | * 107 | * \param num_unsaved_files the number of unsaved file entries in \p 108 | * unsaved_files. 109 | * 110 | * \param unsaved_files the files that have not yet been saved to disk 111 | * but may be required for code completion, including the contents of 112 | * those files. The contents and name of these files (as specified by 113 | * CXUnsavedFile) are copied when necessary, so the client only needs to 114 | * guarantee their validity until the call to this function returns. 115 | */ 116 | func (idx Index) CreateTranslationUnitFromSourceFile(fname string, args []string, us UnsavedFiles) TranslationUnit { 117 | var ( 118 | c_fname *C.char = nil 119 | c_us = us.to_c() 120 | ) 121 | defer c_us.Dispose() 122 | if fname != "" { 123 | c_fname = C.CString(fname) 124 | } 125 | defer C.free(unsafe.Pointer(c_fname)) 126 | 127 | c_nargs := C.int(len(args)) 128 | c_cmds := make([]*C.char, len(args)) 129 | for i, _ := range args { 130 | cstr := C.CString(args[i]) 131 | defer C.free(unsafe.Pointer(cstr)) 132 | c_cmds[i] = cstr 133 | } 134 | 135 | var c_argv **C.char = nil 136 | if c_nargs > 0 { 137 | c_argv = &c_cmds[0] 138 | } 139 | 140 | o := C.clang_createTranslationUnitFromSourceFile( 141 | idx.c, 142 | c_fname, 143 | c_nargs, c_argv, 144 | C.uint(len(c_us)), c_us.ptr()) 145 | return TranslationUnit{o} 146 | 147 | } 148 | 149 | /** 150 | * \brief Parse the given source file and the translation unit corresponding 151 | * to that file. 152 | * 153 | * This routine is the main entry point for the Clang C API, providing the 154 | * ability to parse a source file into a translation unit that can then be 155 | * queried by other functions in the API. This routine accepts a set of 156 | * command-line arguments so that the compilation can be configured in the same 157 | * way that the compiler is configured on the command line. 158 | * 159 | * \param CIdx The index object with which the translation unit will be 160 | * associated. 161 | * 162 | * \param source_filename The name of the source file to load, or NULL if the 163 | * source file is included in \p command_line_args. 164 | * 165 | * \param command_line_args The command-line arguments that would be 166 | * passed to the \c clang executable if it were being invoked out-of-process. 167 | * These command-line options will be parsed and will affect how the translation 168 | * unit is parsed. Note that the following options are ignored: '-c', 169 | * '-emit-ast', '-fsyntex-only' (which is the default), and '-o '. 170 | * 171 | * \param num_command_line_args The number of command-line arguments in 172 | * \p command_line_args. 173 | * 174 | * \param unsaved_files the files that have not yet been saved to disk 175 | * but may be required for parsing, including the contents of 176 | * those files. The contents and name of these files (as specified by 177 | * CXUnsavedFile) are copied when necessary, so the client only needs to 178 | * guarantee their validity until the call to this function returns. 179 | * 180 | * \param num_unsaved_files the number of unsaved file entries in \p 181 | * unsaved_files. 182 | * 183 | * \param options A bitmask of options that affects how the translation unit 184 | * is managed but not its compilation. This should be a bitwise OR of the 185 | * CXTranslationUnit_XXX flags. 186 | * 187 | * \returns A new translation unit describing the parsed code and containing 188 | * any diagnostics produced by the compiler. If there is a failure from which 189 | * the compiler cannot recover, returns NULL. 190 | */ 191 | func (idx Index) Parse(fname string, args []string, us UnsavedFiles, options TranslationUnitFlags) TranslationUnit { 192 | var ( 193 | c_fname *C.char = nil 194 | c_us = us.to_c() 195 | ) 196 | defer c_us.Dispose() 197 | if fname != "" { 198 | c_fname = C.CString(fname) 199 | } 200 | defer C.free(unsafe.Pointer(c_fname)) 201 | 202 | c_nargs := C.int(len(args)) 203 | c_cmds := make([]*C.char, len(args)) 204 | for i, _ := range args { 205 | cstr := C.CString(args[i]) 206 | defer C.free(unsafe.Pointer(cstr)) 207 | c_cmds[i] = cstr 208 | } 209 | 210 | var c_args **C.char = nil 211 | if len(args) > 0 { 212 | c_args = &c_cmds[0] 213 | } 214 | o := C.clang_parseTranslationUnit( 215 | idx.c, 216 | c_fname, 217 | c_args, c_nargs, 218 | c_us.ptr(), C.uint(len(c_us)), 219 | C.uint(options)) 220 | return TranslationUnit{o} 221 | 222 | } 223 | 224 | // EOF 225 | -------------------------------------------------------------------------------- /clang_test.go: -------------------------------------------------------------------------------- 1 | package clang_test 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/sbinet/go-clang" 7 | ) 8 | 9 | func TestReparse(t *testing.T) { 10 | us := clang.UnsavedFiles{"hello.cpp": "int world();"} 11 | 12 | idx := clang.NewIndex(0, 0) 13 | defer idx.Dispose() 14 | tu := idx.Parse("hello.cpp", nil, us, 0) 15 | if !tu.IsValid() { 16 | t.Fatal("TranslationUnit is not valid") 17 | } 18 | defer tu.Dispose() 19 | ok := false 20 | tu.ToCursor().Visit(func(cursor, parent clang.Cursor) clang.ChildVisitResult { 21 | if cursor.Spelling() == "world" { 22 | ok = true 23 | return clang.CVR_Break 24 | } 25 | return clang.CVR_Continue 26 | }) 27 | if !ok { 28 | t.Error("Expected to find 'world', but didn't") 29 | } 30 | us["hello.cpp"] = "int world2();" 31 | tu.Reparse(us, 0) 32 | 33 | ok = false 34 | tu.ToCursor().Visit(func(cursor, parent clang.Cursor) clang.ChildVisitResult { 35 | if s := cursor.Spelling(); s == "world2" { 36 | ok = true 37 | return clang.CVR_Break 38 | } else if s == "world" { 39 | t.Errorf("'world' should no longer be part of the translationunit, but it still is") 40 | } 41 | return clang.CVR_Continue 42 | }) 43 | if !ok { 44 | t.Error("Expected to find 'world2', but didn't") 45 | } 46 | } 47 | 48 | // EOF 49 | -------------------------------------------------------------------------------- /comment.go: -------------------------------------------------------------------------------- 1 | package clang 2 | 3 | // #include 4 | // #include "go-clang.h" 5 | // 6 | import "C" 7 | 8 | /** 9 | * \brief A comment AST node. 10 | */ 11 | type Comment struct { 12 | c C.CXComment 13 | } 14 | 15 | /** 16 | * \param Comment AST node of any kind. 17 | * 18 | * \returns the type of the AST node. 19 | */ 20 | func (c Comment) Kind() CommentKind { 21 | return CommentKind(C.clang_Comment_getKind(c.c)) 22 | } 23 | 24 | /** 25 | * \param Comment AST node of any kind. 26 | * 27 | * \returns number of children of the AST node. 28 | */ 29 | func (c Comment) NumChildren() int { 30 | return int(C.clang_Comment_getNumChildren(c.c)) 31 | } 32 | 33 | /** 34 | * \param Comment AST node of any kind. 35 | * 36 | * \param ChildIdx child index (zero-based). 37 | * 38 | * \returns the specified child of the AST node. 39 | */ 40 | func (c Comment) Child(idx int) Comment { 41 | return Comment{C.clang_Comment_getChild(c.c, C.unsigned(idx))} 42 | } 43 | 44 | /** 45 | * \brief A \c CXComment_Paragraph node is considered whitespace if it contains 46 | * only \c CXComment_Text nodes that are empty or whitespace. 47 | * 48 | * Other AST nodes (except \c CXComment_Paragraph and \c CXComment_Text) are 49 | * never considered whitespace. 50 | * 51 | * \returns non-zero if \c Comment is whitespace. 52 | */ 53 | func (c Comment) IsWhitespace() bool { 54 | o := C.clang_Comment_isWhitespace(c.c) 55 | if o != 0 { 56 | return true 57 | } 58 | return false 59 | } 60 | 61 | /** 62 | * \returns non-zero if \c Comment is inline content and has a newline 63 | * immediately following it in the comment text. Newlines between paragraphs 64 | * do not count. 65 | */ 66 | func (c Comment) HasTrailingNewline() bool { 67 | o := C.clang_InlineContentComment_hasTrailingNewline(c.c) 68 | if 0 != o { 69 | return true 70 | } 71 | return false 72 | } 73 | 74 | /** 75 | * \param Comment a \c CXComment_Text AST node. 76 | * 77 | * \returns text contained in the AST node. 78 | */ 79 | func (c Comment) TextComment() string { 80 | o := cxstring{C.clang_TextComment_getText(c.c)} 81 | defer o.Dispose() 82 | return o.String() 83 | } 84 | 85 | // TODO: implement more of Comment API 86 | 87 | // /** 88 | // * \param Comment a \c CXComment_InlineCommand AST node. 89 | // * 90 | // * \returns name of the inline command. 91 | // */ 92 | // CINDEX_LINKAGE 93 | // CXString clang_InlineCommandComment_getCommandName(CXComment Comment); 94 | 95 | // /** 96 | // * \param Comment a \c CXComment_InlineCommand AST node. 97 | // * 98 | // * \returns the most appropriate rendering mode, chosen on command 99 | // * semantics in Doxygen. 100 | // */ 101 | // CINDEX_LINKAGE enum CXCommentInlineCommandRenderKind 102 | // clang_InlineCommandComment_getRenderKind(CXComment Comment); 103 | 104 | // /** 105 | // * \param Comment a \c CXComment_InlineCommand AST node. 106 | // * 107 | // * \returns number of command arguments. 108 | // */ 109 | // CINDEX_LINKAGE 110 | // unsigned clang_InlineCommandComment_getNumArgs(CXComment Comment); 111 | 112 | // /** 113 | // * \param Comment a \c CXComment_InlineCommand AST node. 114 | // * 115 | // * \param ArgIdx argument index (zero-based). 116 | // * 117 | // * \returns text of the specified argument. 118 | // */ 119 | // CINDEX_LINKAGE 120 | // CXString clang_InlineCommandComment_getArgText(CXComment Comment, 121 | // unsigned ArgIdx); 122 | 123 | // /** 124 | // * \param Comment a \c CXComment_HTMLStartTag or \c CXComment_HTMLEndTag AST 125 | // * node. 126 | // * 127 | // * \returns HTML tag name. 128 | // */ 129 | // CINDEX_LINKAGE CXString clang_HTMLTagComment_getTagName(CXComment Comment); 130 | 131 | // /** 132 | // * \param Comment a \c CXComment_HTMLStartTag AST node. 133 | // * 134 | // * \returns non-zero if tag is self-closing (for example, <br />). 135 | // */ 136 | // CINDEX_LINKAGE 137 | // unsigned clang_HTMLStartTagComment_isSelfClosing(CXComment Comment); 138 | 139 | // /** 140 | // * \param Comment a \c CXComment_HTMLStartTag AST node. 141 | // * 142 | // * \returns number of attributes (name-value pairs) attached to the start tag. 143 | // */ 144 | // CINDEX_LINKAGE unsigned clang_HTMLStartTag_getNumAttrs(CXComment Comment); 145 | 146 | // /** 147 | // * \param Comment a \c CXComment_HTMLStartTag AST node. 148 | // * 149 | // * \param AttrIdx attribute index (zero-based). 150 | // * 151 | // * \returns name of the specified attribute. 152 | // */ 153 | // CINDEX_LINKAGE 154 | // CXString clang_HTMLStartTag_getAttrName(CXComment Comment, unsigned AttrIdx); 155 | 156 | // /** 157 | // * \param Comment a \c CXComment_HTMLStartTag AST node. 158 | // * 159 | // * \param AttrIdx attribute index (zero-based). 160 | // * 161 | // * \returns value of the specified attribute. 162 | // */ 163 | // CINDEX_LINKAGE 164 | // CXString clang_HTMLStartTag_getAttrValue(CXComment Comment, unsigned AttrIdx); 165 | 166 | // /** 167 | // * \param Comment a \c CXComment_BlockCommand AST node. 168 | // * 169 | // * \returns name of the block command. 170 | // */ 171 | // CINDEX_LINKAGE 172 | // CXString clang_BlockCommandComment_getCommandName(CXComment Comment); 173 | 174 | // /** 175 | // * \param Comment a \c CXComment_BlockCommand AST node. 176 | // * 177 | // * \returns number of word-like arguments. 178 | // */ 179 | // CINDEX_LINKAGE 180 | // unsigned clang_BlockCommandComment_getNumArgs(CXComment Comment); 181 | 182 | // /** 183 | // * \param Comment a \c CXComment_BlockCommand AST node. 184 | // * 185 | // * \param ArgIdx argument index (zero-based). 186 | // * 187 | // * \returns text of the specified word-like argument. 188 | // */ 189 | // CINDEX_LINKAGE 190 | // CXString clang_BlockCommandComment_getArgText(CXComment Comment, 191 | // unsigned ArgIdx); 192 | 193 | // /** 194 | // * \param Comment a \c CXComment_BlockCommand or 195 | // * \c CXComment_VerbatimBlockCommand AST node. 196 | // * 197 | // * \returns paragraph argument of the block command. 198 | // */ 199 | // CINDEX_LINKAGE 200 | // CXComment clang_BlockCommandComment_getParagraph(CXComment Comment); 201 | 202 | // /** 203 | // * \param Comment a \c CXComment_ParamCommand AST node. 204 | // * 205 | // * \returns parameter name. 206 | // */ 207 | // CINDEX_LINKAGE 208 | // CXString clang_ParamCommandComment_getParamName(CXComment Comment); 209 | 210 | // /** 211 | // * \param Comment a \c CXComment_ParamCommand AST node. 212 | // * 213 | // * \returns non-zero if the parameter that this AST node represents was found 214 | // * in the function prototype and \c clang_ParamCommandComment_getParamIndex 215 | // * function will return a meaningful value. 216 | // */ 217 | // CINDEX_LINKAGE 218 | // unsigned clang_ParamCommandComment_isParamIndexValid(CXComment Comment); 219 | 220 | // /** 221 | // * \param Comment a \c CXComment_ParamCommand AST node. 222 | // * 223 | // * \returns zero-based parameter index in function prototype. 224 | // */ 225 | // CINDEX_LINKAGE 226 | // unsigned clang_ParamCommandComment_getParamIndex(CXComment Comment); 227 | 228 | // /** 229 | // * \param Comment a \c CXComment_ParamCommand AST node. 230 | // * 231 | // * \returns non-zero if parameter passing direction was specified explicitly in 232 | // * the comment. 233 | // */ 234 | // CINDEX_LINKAGE 235 | // unsigned clang_ParamCommandComment_isDirectionExplicit(CXComment Comment); 236 | 237 | // /** 238 | // * \param Comment a \c CXComment_ParamCommand AST node. 239 | // * 240 | // * \returns parameter passing direction. 241 | // */ 242 | // CINDEX_LINKAGE 243 | // enum CXCommentParamPassDirection clang_ParamCommandComment_getDirection( 244 | // CXComment Comment); 245 | 246 | // /** 247 | // * \param Comment a \c CXComment_TParamCommand AST node. 248 | // * 249 | // * \returns template parameter name. 250 | // */ 251 | // CINDEX_LINKAGE 252 | // CXString clang_TParamCommandComment_getParamName(CXComment Comment); 253 | 254 | // /** 255 | // * \param Comment a \c CXComment_TParamCommand AST node. 256 | // * 257 | // * \returns non-zero if the parameter that this AST node represents was found 258 | // * in the template parameter list and 259 | // * \c clang_TParamCommandComment_getDepth and 260 | // * \c clang_TParamCommandComment_getIndex functions will return a meaningful 261 | // * value. 262 | // */ 263 | // CINDEX_LINKAGE 264 | // unsigned clang_TParamCommandComment_isParamPositionValid(CXComment Comment); 265 | 266 | // /** 267 | // * \param Comment a \c CXComment_TParamCommand AST node. 268 | // * 269 | // * \returns zero-based nesting depth of this parameter in the template parameter list. 270 | // * 271 | // * For example, 272 | // * \verbatim 273 | // * template class TT> 274 | // * void test(TT aaa); 275 | // * \endverbatim 276 | // * for C and TT nesting depth is 0, 277 | // * for T nesting depth is 1. 278 | // */ 279 | // CINDEX_LINKAGE 280 | // unsigned clang_TParamCommandComment_getDepth(CXComment Comment); 281 | 282 | // /** 283 | // * \param Comment a \c CXComment_TParamCommand AST node. 284 | // * 285 | // * \returns zero-based parameter index in the template parameter list at a 286 | // * given nesting depth. 287 | // * 288 | // * For example, 289 | // * \verbatim 290 | // * template class TT> 291 | // * void test(TT aaa); 292 | // * \endverbatim 293 | // * for C and TT nesting depth is 0, so we can ask for index at depth 0: 294 | // * at depth 0 C's index is 0, TT's index is 1. 295 | // * 296 | // * For T nesting depth is 1, so we can ask for index at depth 0 and 1: 297 | // * at depth 0 T's index is 1 (same as TT's), 298 | // * at depth 1 T's index is 0. 299 | // */ 300 | // CINDEX_LINKAGE 301 | // unsigned clang_TParamCommandComment_getIndex(CXComment Comment, unsigned Depth); 302 | 303 | // /** 304 | // * \param Comment a \c CXComment_VerbatimBlockLine AST node. 305 | // * 306 | // * \returns text contained in the AST node. 307 | // */ 308 | // CINDEX_LINKAGE 309 | // CXString clang_VerbatimBlockLineComment_getText(CXComment Comment); 310 | 311 | // /** 312 | // * \param Comment a \c CXComment_VerbatimLine AST node. 313 | // * 314 | // * \returns text contained in the AST node. 315 | // */ 316 | // CINDEX_LINKAGE CXString clang_VerbatimLineComment_getText(CXComment Comment); 317 | 318 | // /** 319 | // * \brief Convert an HTML tag AST node to string. 320 | // * 321 | // * \param Comment a \c CXComment_HTMLStartTag or \c CXComment_HTMLEndTag AST 322 | // * node. 323 | // * 324 | // * \returns string containing an HTML tag. 325 | // */ 326 | // CINDEX_LINKAGE CXString clang_HTMLTagComment_getAsString(CXComment Comment); 327 | 328 | // /** 329 | // * \brief Convert a given full parsed comment to an HTML fragment. 330 | // * 331 | // * Specific details of HTML layout are subject to change. Don't try to parse 332 | // * this HTML back into an AST, use other APIs instead. 333 | // * 334 | // * Currently the following CSS classes are used: 335 | // * \li "para-brief" for \\brief paragraph and equivalent commands; 336 | // * \li "para-returns" for \\returns paragraph and equivalent commands; 337 | // * \li "word-returns" for the "Returns" word in \\returns paragraph. 338 | // * 339 | // * Function argument documentation is rendered as a \ list with arguments 340 | // * sorted in function prototype order. CSS classes used: 341 | // * \li "param-name-index-NUMBER" for parameter name (\); 342 | // * \li "param-descr-index-NUMBER" for parameter description (\); 343 | // * \li "param-name-index-invalid" and "param-descr-index-invalid" are used if 344 | // * parameter index is invalid. 345 | // * 346 | // * Template parameter documentation is rendered as a \ list with 347 | // * parameters sorted in template parameter list order. CSS classes used: 348 | // * \li "tparam-name-index-NUMBER" for parameter name (\); 349 | // * \li "tparam-descr-index-NUMBER" for parameter description (\); 350 | // * \li "tparam-name-index-other" and "tparam-descr-index-other" are used for 351 | // * names inside template template parameters; 352 | // * \li "tparam-name-index-invalid" and "tparam-descr-index-invalid" are used if 353 | // * parameter position is invalid. 354 | // * 355 | // * \param Comment a \c CXComment_FullComment AST node. 356 | // * 357 | // * \returns string containing an HTML fragment. 358 | // */ 359 | // CINDEX_LINKAGE CXString clang_FullComment_getAsHTML(CXComment Comment); 360 | 361 | // /** 362 | // * \brief Convert a given full parsed comment to an XML document. 363 | // * 364 | // * A Relax NG schema for the XML can be found in comment-xml-schema.rng file 365 | // * inside clang source tree. 366 | // * 367 | // * \param Comment a \c CXComment_FullComment AST node. 368 | // * 369 | // * \returns string containing an XML document. 370 | // */ 371 | // CINDEX_LINKAGE CXString clang_FullComment_getAsXML(CXComment Comment); 372 | -------------------------------------------------------------------------------- /commentkind.go: -------------------------------------------------------------------------------- 1 | package clang 2 | 3 | // #include 4 | // #include "go-clang.h" 5 | // 6 | import "C" 7 | 8 | /** 9 | * \brief Describes the type of the comment AST node (\c CXComment). A comment 10 | * node can be considered block content (e. g., paragraph), inline content 11 | * (plain text) or neither (the root AST node). 12 | */ 13 | type CommentKind int 14 | 15 | const ( 16 | /** 17 | * \brief Null comment. No AST node is constructed at the requested location 18 | * because there is no text or a syntax error. 19 | */ 20 | Comment_Null CommentKind = C.CXComment_Null 21 | 22 | /** 23 | * \brief Plain text. Inline content. 24 | */ 25 | Comment_Text = C.CXComment_Text 26 | 27 | /** 28 | * \brief A command with word-like arguments that is considered inline content. 29 | * 30 | * For example: \\c command. 31 | */ 32 | Comment_InlineCommand = C.CXComment_InlineCommand 33 | 34 | /** 35 | * \brief HTML start tag with attributes (name-value pairs). Considered 36 | * inline content. 37 | * 38 | * For example: 39 | * \verbatim 40 | *

41 | * \endverbatim 42 | */ 43 | Comment_HTMLStartTag = C.CXComment_HTMLStartTag 44 | 45 | /** 46 | * \brief HTML end tag. Considered inline content. 47 | * 48 | * For example: 49 | * \verbatim 50 | * 51 | * \endverbatim 52 | */ 53 | Comment_HTMLEndTag = C.CXComment_HTMLEndTag 54 | 55 | /** 56 | * \brief A paragraph, contains inline comment. The paragraph itself is 57 | * block content. 58 | */ 59 | Comment_Paragraph = C.CXComment_Paragraph 60 | 61 | /** 62 | * \brief A command that has zero or more word-like arguments (number of 63 | * word-like arguments depends on command name) and a paragraph as an 64 | * argument. Block command is block content. 65 | * 66 | * Paragraph argument is also a child of the block command. 67 | * 68 | * For example: \\brief has 0 word-like arguments and a paragraph argument. 69 | * 70 | * AST nodes of special kinds that parser knows about (e. g., \\param 71 | * command) have their own node kinds. 72 | */ 73 | Comment_BlockCommand = C.CXComment_BlockCommand 74 | 75 | /** 76 | * \brief A \\param or \\arg command that describes the function parameter 77 | * (name, passing direction, description). 78 | * 79 | * For example: \\param [in] ParamName description. 80 | */ 81 | Comment_ParamCommand = C.CXComment_ParamCommand 82 | 83 | /** 84 | * \brief A \\tparam command that describes a template parameter (name and 85 | * description). 86 | * 87 | * For example: \\tparam T description. 88 | */ 89 | Comment_TParamCommand = C.CXComment_TParamCommand 90 | 91 | /** 92 | * \brief A verbatim block command (e. g., preformatted code). Verbatim 93 | * block has an opening and a closing command and contains multiple lines of 94 | * text (\c CXComment_VerbatimBlockLine child nodes). 95 | * 96 | * For example: 97 | * \\verbatim 98 | * aaa 99 | * \\endverbatim 100 | */ 101 | Comment_VerbatimBlockCommand = C.CXComment_VerbatimBlockCommand 102 | 103 | /** 104 | * \brief A line of text that is contained within a 105 | * CXComment_VerbatimBlockCommand node. 106 | */ 107 | Comment_VerbatimBlockLine = C.CXComment_VerbatimBlockLine 108 | 109 | /** 110 | * \brief A verbatim line command. Verbatim line has an opening command, 111 | * a single line of text (up to the newline after the opening command) and 112 | * has no closing command. 113 | */ 114 | Comment_VerbatimLine = C.CXComment_VerbatimLine 115 | 116 | /** 117 | * \brief A full comment attached to a declaration, contains block content. 118 | */ 119 | Comment_FullComment = C.CXComment_FullComment 120 | ) 121 | 122 | /** 123 | * \brief The most appropriate rendering mode for an inline command, chosen on 124 | * command semantics in Doxygen. 125 | */ 126 | type CommentInlineCommandRenderKind int 127 | 128 | const ( 129 | /** 130 | * \brief Command argument should be rendered in a normal font. 131 | */ 132 | CommentInlineCommandRenderKind_Normal CommentInlineCommandRenderKind = C.CXCommentInlineCommandRenderKind_Normal 133 | 134 | /** 135 | * \brief Command argument should be rendered in a bold font. 136 | */ 137 | CommentInlineCommandRenderKind_Bold = C.CXCommentInlineCommandRenderKind_Bold 138 | 139 | /** 140 | * \brief Command argument should be rendered in a monospaced font. 141 | */ 142 | CommentInlineCommandRenderKind_Monospaced = C.CXCommentInlineCommandRenderKind_Monospaced 143 | 144 | /** 145 | * \brief Command argument should be rendered emphasized (typically italic 146 | * font). 147 | */ 148 | CommentInlineCommandRenderKind_Emphasized = C.CXCommentInlineCommandRenderKind_Emphasized 149 | ) 150 | 151 | /** 152 | * \brief Describes parameter passing direction for \\param or \\arg command. 153 | */ 154 | type CommentParamPassDirection int 155 | 156 | const ( 157 | /** 158 | * \brief The parameter is an input parameter. 159 | */ 160 | CommentParamPassDirection_In = C.CXCommentParamPassDirection_In 161 | 162 | /** 163 | * \brief The parameter is an output parameter. 164 | */ 165 | CommentParamPassDirection_Out = C.CXCommentParamPassDirection_Out 166 | 167 | /** 168 | * \brief The parameter is an input and output parameter. 169 | */ 170 | CommentParamPassDirection_InOut = C.CXCommentParamPassDirection_InOut 171 | ) 172 | -------------------------------------------------------------------------------- /compilationdb.go: -------------------------------------------------------------------------------- 1 | package clang 2 | 3 | // #include 4 | // #include "go-clang.h" 5 | // #include "clang-c/CXCompilationDatabase.h" 6 | // 7 | import "C" 8 | 9 | import ( 10 | "fmt" 11 | "unsafe" 12 | ) 13 | 14 | /** 15 | * A compilation database holds all information used to compile files in a 16 | * project. For each file in the database, it can be queried for the working 17 | * directory or the command line used for the compiler invocation. 18 | * 19 | * Must be freed by \c clang_CompilationDatabase_dispose 20 | */ 21 | type CompilationDatabase struct { 22 | c C.CXCompilationDatabase 23 | } 24 | 25 | /** 26 | * \brief Contains the results of a search in the compilation database 27 | * 28 | * When searching for the compile command for a file, the compilation db can 29 | * return several commands, as the file may have been compiled with 30 | * different options in different places of the project. This choice of compile 31 | * commands is wrapped in this opaque data structure. It must be freed by 32 | * \c clang_CompileCommands_dispose. 33 | */ 34 | type CompileCommands struct { 35 | c C.CXCompileCommands 36 | } 37 | 38 | /** 39 | * \brief Represents the command line invocation to compile a specific file. 40 | */ 41 | type CompileCommand struct { 42 | c C.CXCompileCommand 43 | } 44 | 45 | /** 46 | * \brief Error codes for Compilation Database 47 | */ 48 | type CompilationDatabaseError int 49 | 50 | func (err CompilationDatabaseError) Error() string { 51 | switch err { 52 | case CompilationDatabase_CanNotLoadDatabase: 53 | return "go-clang: can not load database" 54 | default: 55 | return fmt.Sprintf("go-clang: unknown compilationdatabase error (%d)", int(err)) 56 | } 57 | } 58 | 59 | const ( 60 | /* 61 | * \brief No error occurred 62 | */ 63 | CompilationDatabase_NoError CompilationDatabaseError = C.CXCompilationDatabase_NoError 64 | 65 | /* 66 | * \brief Database can not be loaded 67 | */ 68 | CompilationDatabase_CanNotLoadDatabase = C.CXCompilationDatabase_CanNotLoadDatabase 69 | ) 70 | 71 | /** 72 | * \brief Creates a compilation database from the database found in directory 73 | * buildDir. For example, CMake can output a compile_commands.json which can 74 | * be used to build the database. 75 | * 76 | * It must be freed by \c clang_CompilationDatabase_dispose. 77 | */ 78 | func NewCompilationDatabase(builddir string) (CompilationDatabase, error) { 79 | var db CompilationDatabase 80 | 81 | c_dir := C.CString(builddir) 82 | defer C.free(unsafe.Pointer(c_dir)) 83 | var c_err C.CXCompilationDatabase_Error 84 | c_db := C.clang_CompilationDatabase_fromDirectory(c_dir, &c_err) 85 | if c_err == C.CXCompilationDatabase_NoError { 86 | return CompilationDatabase{c_db}, nil 87 | } 88 | return db, CompilationDatabaseError(c_err) 89 | } 90 | 91 | /** 92 | * \brief Free the given compilation database 93 | */ 94 | func (db *CompilationDatabase) Dispose() { 95 | C.clang_CompilationDatabase_dispose(db.c) 96 | } 97 | 98 | /** 99 | * \brief Find the compile commands used for a file. The compile commands 100 | * must be freed by \c clang_CompileCommands_dispose. 101 | */ 102 | func (db *CompilationDatabase) GetCompileCommands(fname string) CompileCommands { 103 | c_fname := C.CString(fname) 104 | defer C.free(unsafe.Pointer(c_fname)) 105 | c_cmds := C.clang_CompilationDatabase_getCompileCommands(db.c, c_fname) 106 | return CompileCommands{c_cmds} 107 | } 108 | 109 | /** 110 | * \brief Get all the compile commands in the given compilation database. 111 | */ 112 | func (db *CompilationDatabase) GetAllCompileCommands() CompileCommands { 113 | c_cmds := C.clang_CompilationDatabase_getAllCompileCommands(db.c) 114 | return CompileCommands{c_cmds} 115 | } 116 | 117 | /** 118 | * \brief Get the number of CompileCommand we have for a file 119 | */ 120 | func (cmds CompileCommands) GetSize() int { 121 | return int(C.clang_CompileCommands_getSize(cmds.c)) 122 | } 123 | 124 | /** 125 | * \brief Get the I'th CompileCommand for a file 126 | * 127 | * Note : 0 <= i < clang_CompileCommands_getSize(CXCompileCommands) 128 | */ 129 | func (cmds CompileCommands) GetCommand(idx int) CompileCommand { 130 | c_cmd := C.clang_CompileCommands_getCommand(cmds.c, C.unsigned(idx)) 131 | return CompileCommand{c_cmd} 132 | } 133 | 134 | /** 135 | * \brief Get the working directory where the CompileCommand was executed from 136 | */ 137 | func (cmd CompileCommand) GetDirectory() string { 138 | c_str := cxstring{C.clang_CompileCommand_getDirectory(cmd.c)} 139 | defer c_str.Dispose() 140 | return c_str.String() 141 | } 142 | 143 | /** 144 | * \brief Get the number of arguments in the compiler invocation. 145 | * 146 | */ 147 | func (cmd CompileCommand) GetNumArgs() int { 148 | return int(C.clang_CompileCommand_getNumArgs(cmd.c)) 149 | } 150 | 151 | /** 152 | * \brief Get the I'th argument value in the compiler invocations 153 | * 154 | * Invariant : 155 | * - argument 0 is the compiler executable 156 | */ 157 | func (cmd CompileCommand) GetArg(idx int) string { 158 | c_str := cxstring{C.clang_CompileCommand_getArg(cmd.c, C.unsigned(idx))} 159 | defer c_str.Dispose() 160 | return c_str.String() 161 | } 162 | 163 | // /** 164 | // * \brief Get the number of source mappings for the compiler invocation. 165 | // */ 166 | // func (cmd CompileCommand) GetNumMappedSources() int { 167 | // return int(C.clang_CompileCommand_getNumMappedSources(cmd.c)) 168 | // } 169 | 170 | // /** 171 | // * \brief Get the I'th mapped source path for the compiler invocation. 172 | // */ 173 | // func (cmd CompileCommand) GetMappedSourcePath(idx int) string { 174 | // c_str := cxstring{C.clang_CompileCommand_getMappedSourcePath(cmd.c, C.unsigned(idx))} 175 | // defer c_str.Dispose() 176 | // return c_str.String() 177 | // } 178 | -------------------------------------------------------------------------------- /compilationdb_test.go: -------------------------------------------------------------------------------- 1 | package clang_test 2 | 3 | import ( 4 | "testing" 5 | 6 | clang "github.com/sbinet/go-clang" 7 | ) 8 | 9 | func TestCompilationDatabaseError(t *testing.T) { 10 | _, err := clang.NewCompilationDatabase("testdata-not-there") 11 | if err == nil { 12 | t.Fatalf("expected an error") 13 | } 14 | 15 | if err.(clang.CompilationDatabaseError) != clang.CompilationDatabase_CanNotLoadDatabase { 16 | t.Fatalf("expected %v", clang.CompilationDatabase_CanNotLoadDatabase) 17 | } 18 | } 19 | 20 | func TestCompilationDatabase(t *testing.T) { 21 | db, err := clang.NewCompilationDatabase("testdata") 22 | if err != nil { 23 | t.Fatalf("error loading compilation database: %v", err) 24 | } 25 | defer db.Dispose() 26 | 27 | table := []struct { 28 | directory string 29 | args []string 30 | }{ 31 | { 32 | directory: "/home/user/llvm/build", 33 | args: []string{ 34 | "/usr/bin/clang++", 35 | "-Irelative", 36 | //FIXME: bug in clang ? 37 | //`-DSOMEDEF="With spaces, quotes and \-es.`, 38 | "-DSOMEDEF=With spaces, quotes and -es.", 39 | "-c", 40 | "-o", 41 | "file.o", 42 | "file.cc", 43 | }, 44 | }, 45 | { 46 | directory: "@TESTDIR@", 47 | args: []string{"g++", "-c", "-DMYMACRO=a", "subdir/a.cpp"}, 48 | }, 49 | } 50 | 51 | cmds := db.GetAllCompileCommands() 52 | if cmds.GetSize() != len(table) { 53 | t.Errorf("expected #cmds=%d. got=%d", len(table), cmds.GetSize()) 54 | } 55 | 56 | for i := 0; i < cmds.GetSize(); i++ { 57 | cmd := cmds.GetCommand(i) 58 | if cmd.GetDirectory() != table[i].directory { 59 | t.Errorf("expected dir=%q. got=%q", table[i].directory, cmd.GetDirectory()) 60 | } 61 | 62 | nargs := cmd.GetNumArgs() 63 | if nargs != len(table[i].args) { 64 | t.Errorf("expected #args=%d. got=%d", len(table[i].args), nargs) 65 | } 66 | if nargs > len(table[i].args) { 67 | nargs = len(table[i].args) 68 | } 69 | for j := 0; j < nargs; j++ { 70 | arg := cmd.GetArg(j) 71 | if arg != table[i].args[j] { 72 | t.Errorf("expected arg[%d]=%q. got=%q", j, table[i].args[j], arg) 73 | } 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /complete.go: -------------------------------------------------------------------------------- 1 | package clang 2 | 3 | // #include "go-clang.h" 4 | import "C" 5 | 6 | import ( 7 | "fmt" 8 | "reflect" 9 | "unsafe" 10 | ) 11 | 12 | /** 13 | * \brief A semantic string that describes a code-completion result. 14 | * 15 | * A semantic string that describes the formatting of a code-completion 16 | * result as a single "template" of text that should be inserted into the 17 | * source buffer when a particular code-completion result is selected. 18 | * Each semantic string is made up of some number of "chunks", each of which 19 | * contains some text along with a description of what that text means, e.g., 20 | * the name of the entity being referenced, whether the text chunk is part of 21 | * the template, or whether it is a "placeholder" that the user should replace 22 | * with actual code,of a specific kind. See \c CXCompletionChunkKind for a 23 | * description of the different kinds of chunks. 24 | */ 25 | type CompletionString struct { 26 | c C.CXCompletionString 27 | } 28 | 29 | /** 30 | * \brief Determine the priority of this code completion. 31 | * 32 | * The priority of a code completion indicates how likely it is that this 33 | * particular completion is the completion that the user will select. The 34 | * priority is selected by various internal heuristics. 35 | * 36 | * \param completion_string The completion string to query. 37 | * 38 | * \returns The priority of this completion string. Smaller values indicate 39 | * higher-priority (more likely) completions. 40 | */ 41 | func (cs CompletionString) Priority() int { 42 | return int(C.clang_getCompletionPriority(cs.c)) 43 | } 44 | 45 | /** 46 | * \brief Determine the availability of the entity that this code-completion 47 | * string refers to. 48 | * 49 | * \param completion_string The completion string to query. 50 | * 51 | * \returns The availability of the completion string. 52 | */ 53 | func (cs CompletionString) Availability() AvailabilityKind { 54 | return AvailabilityKind(C.clang_getCompletionAvailability(cs.c)) 55 | } 56 | 57 | /** 58 | * \brief Retrieve the number of annotations associated with the given 59 | * completion string. 60 | * 61 | * \param completion_string the completion string to query. 62 | * 63 | * \returns the number of annotations associated with the given completion 64 | * string. 65 | */ 66 | func (cs CompletionString) NumAnnotations() int { 67 | return int(C.clang_getCompletionNumAnnotations(cs.c)) 68 | } 69 | 70 | /** 71 | * \brief Retrieve the annotation associated with the given completion string. 72 | * 73 | * \param completion_string the completion string to query. 74 | * 75 | * \param annotation_number the 0-based index of the annotation of the 76 | * completion string. 77 | * 78 | * \returns annotation string associated with the completion at index 79 | * \c annotation_number, or a NULL string if that annotation is not available. 80 | */ 81 | func (cs CompletionString) Annotation(i int) string { 82 | cx := cxstring{C.clang_getCompletionAnnotation(cs.c, C.uint(i))} 83 | defer cx.Dispose() 84 | return cx.String() 85 | } 86 | 87 | /** 88 | * \brief Retrieve the parent context of the given completion string. 89 | * 90 | * The parent context of a completion string is the semantic parent of 91 | * the declaration (if any) that the code completion represents. For example, 92 | * a code completion for an Objective-C method would have the method's class 93 | * or protocol as its context. 94 | * 95 | * \param completion_string The code completion string whose parent is 96 | * being queried. 97 | * 98 | * \param kind DEPRECATED: always set to CXCursor_NotImplemented if non-NULL. 99 | * 100 | * \returns The name of the completion parent, e.g., "NSObject" if 101 | * the completion string represents a method in the NSObject class. 102 | */ 103 | func (cs CompletionString) CompletionParent() string { 104 | o := cxstring{C.clang_getCompletionParent(cs.c, nil)} 105 | defer o.Dispose() 106 | return o.String() 107 | } 108 | 109 | /** 110 | * \brief Retrieve the brief documentation comment attached to the declaration 111 | * that corresponds to the given completion string. 112 | */ 113 | func (cs CompletionString) CompletionBriefComment() string { 114 | o := cxstring{C.clang_getCompletionBriefComment(cs.c)} 115 | defer o.Dispose() 116 | return o.String() 117 | } 118 | 119 | /** 120 | * \brief Retrieve the annotation associated with the given completion string. 121 | * 122 | * \param completion_string the completion string to query. 123 | * 124 | * \param annotation_number the 0-based index of the annotation of the 125 | * completion string. 126 | * 127 | * \returns annotation string associated with the completion at index 128 | * \c annotation_number, or a NULL string if that annotation is not available. 129 | */ 130 | 131 | func (cs CompletionString) Chunks() (ret []CompletionChunk) { 132 | ret = make([]CompletionChunk, C.clang_getNumCompletionChunks(cs.c)) 133 | for i := range ret { 134 | ret[i].cs = cs.c 135 | ret[i].number = C.uint(i) 136 | } 137 | return 138 | } 139 | 140 | type CompletionChunk struct { 141 | cs C.CXCompletionString 142 | number C.uint 143 | } 144 | 145 | func (cc CompletionChunk) String() string { 146 | return fmt.Sprintf("%s %s", cc.Kind(), cc.Text()) 147 | } 148 | 149 | /** 150 | * \brief Retrieve the text associated with a particular chunk within a 151 | * completion string. 152 | * 153 | * \param completion_string the completion string to query. 154 | * 155 | * \param chunk_number the 0-based index of the chunk in the completion string. 156 | * 157 | * \returns the text associated with the chunk at index \c chunk_number. 158 | */ 159 | func (cc CompletionChunk) Text() string { 160 | cx := cxstring{C.clang_getCompletionChunkText(cc.cs, cc.number)} 161 | defer cx.Dispose() 162 | return cx.String() 163 | } 164 | 165 | /** 166 | * \brief Determine the kind of a particular chunk within a completion string. 167 | * 168 | * \param completion_string the completion string to query. 169 | * 170 | * \param chunk_number the 0-based index of the chunk in the completion string. 171 | * 172 | * \returns the kind of the chunk at the index \c chunk_number. 173 | */ 174 | func (cs CompletionChunk) Kind() CompletionChunkKind { 175 | return CompletionChunkKind(C.clang_getCompletionChunkKind(cs.cs, cs.number)) 176 | } 177 | 178 | /** 179 | * \brief A single result of code completion. 180 | */ 181 | type CompletionResult struct { 182 | /** 183 | * \brief The kind of entity that this completion refers to. 184 | * 185 | * The cursor kind will be a macro, keyword, or a declaration (one of the 186 | * *Decl cursor kinds), describing the entity that the completion is 187 | * referring to. 188 | * 189 | * \todo In the future, we would like to provide a full cursor, to allow 190 | * the client to extract additional information from declaration. 191 | */ 192 | CursorKind CursorKind 193 | /** 194 | * \brief The code-completion string that describes how to insert this 195 | * code-completion result into the editing buffer. 196 | */ 197 | CompletionString CompletionString 198 | } 199 | 200 | /** 201 | * \brief Describes a single piece of text within a code-completion string. 202 | * 203 | * Each "chunk" within a code-completion string (\c CXCompletionString) is 204 | * either a piece of text with a specific "kind" that describes how that text 205 | * should be interpreted by the client or is another completion string. 206 | */ 207 | type CompletionChunkKind int 208 | 209 | const ( 210 | /** 211 | * \brief A code-completion string that describes "optional" text that 212 | * could be a part of the template (but is not required). 213 | * 214 | * The Optional chunk is the only kind of chunk that has a code-completion 215 | * string for its representation, which is accessible via 216 | * \c clang_getCompletionChunkCompletionString(). The code-completion string 217 | * describes an additional part of the template that is completely optional. 218 | * For example, optional chunks can be used to describe the placeholders for 219 | * arguments that match up with defaulted function parameters, e.g. given: 220 | * 221 | * \code 222 | * void f(int x, float y = 3.14, double z = 2.71828); 223 | * \endcode 224 | * 225 | * The code-completion string for this function would contain: 226 | * - a TypedText chunk for "f". 227 | * - a LeftParen chunk for "(". 228 | * - a Placeholder chunk for "int x" 229 | * - an Optional chunk containing the remaining defaulted arguments, e.g., 230 | * - a Comma chunk for "," 231 | * - a Placeholder chunk for "float y" 232 | * - an Optional chunk containing the last defaulted argument: 233 | * - a Comma chunk for "," 234 | * - a Placeholder chunk for "double z" 235 | * - a RightParen chunk for ")" 236 | * 237 | * There are many ways to handle Optional chunks. Two simple approaches are: 238 | * - Completely ignore optional chunks, in which case the template for the 239 | * function "f" would only include the first parameter ("int x"). 240 | * - Fully expand all optional chunks, in which case the template for the 241 | * function "f" would have all of the parameters. 242 | */ 243 | CompletionChunk_Optional CompletionChunkKind = C.CXCompletionChunk_Optional 244 | /** 245 | * \brief Text that a user would be expected to type to get this 246 | * code-completion result. 247 | * 248 | * There will be exactly one "typed text" chunk in a semantic string, which 249 | * will typically provide the spelling of a keyword or the name of a 250 | * declaration that could be used at the current code point. Clients are 251 | * expected to filter the code-completion results based on the text in this 252 | * chunk. 253 | */ 254 | CompletionChunk_TypedText CompletionChunkKind = C.CXCompletionChunk_TypedText 255 | /** 256 | * \brief Text that should be inserted as part of a code-completion result. 257 | * 258 | * A "text" chunk represents text that is part of the template to be 259 | * inserted into user code should this particular code-completion result 260 | * be selected. 261 | */ 262 | CompletionChunk_Text CompletionChunkKind = C.CXCompletionChunk_Text 263 | /** 264 | * \brief Placeholder text that should be replaced by the user. 265 | * 266 | * A "placeholder" chunk marks a place where the user should insert text 267 | * into the code-completion template. For example, placeholders might mark 268 | * the function parameters for a function declaration, to indicate that the 269 | * user should provide arguments for each of those parameters. The actual 270 | * text in a placeholder is a suggestion for the text to display before 271 | * the user replaces the placeholder with real code. 272 | */ 273 | CompletionChunk_Placeholder CompletionChunkKind = C.CXCompletionChunk_Placeholder 274 | /** 275 | * \brief Informative text that should be displayed but never inserted as 276 | * part of the template. 277 | * 278 | * An "informative" chunk contains annotations that can be displayed to 279 | * help the user decide whether a particular code-completion result is the 280 | * right option, but which is not part of the actual template to be inserted 281 | * by code completion. 282 | */ 283 | CompletionChunk_Informative CompletionChunkKind = C.CXCompletionChunk_Informative 284 | /** 285 | * \brief Text that describes the current parameter when code-completion is 286 | * referring to function call, message send, or template specialization. 287 | * 288 | * A "current parameter" chunk occurs when code-completion is providing 289 | * information about a parameter corresponding to the argument at the 290 | * code-completion point. For example, given a function 291 | * 292 | * \code 293 | * int add(int x, int y); 294 | * \endcode 295 | * 296 | * and the source code \c add(, where the code-completion point is after the 297 | * "(", the code-completion string will contain a "current parameter" chunk 298 | * for "int x", indicating that the current argument will initialize that 299 | * parameter. After typing further, to \c add(17, (where the code-completion 300 | * point is after the ","), the code-completion string will contain a 301 | * "current paremeter" chunk to "int y". 302 | */ 303 | CompletionChunk_CurrentParameter CompletionChunkKind = C.CXCompletionChunk_CurrentParameter 304 | /** 305 | * \brief A left parenthesis ('('), used to initiate a function call or 306 | * signal the beginning of a function parameter list. 307 | */ 308 | CompletionChunk_LeftParen CompletionChunkKind = C.CXCompletionChunk_LeftParen 309 | /** 310 | * \brief A right parenthesis (')'), used to finish a function call or 311 | * signal the end of a function parameter list. 312 | */ 313 | CompletionChunk_RightParen CompletionChunkKind = C.CXCompletionChunk_RightParen 314 | /** 315 | * \brief A left bracket ('['). 316 | */ 317 | CompletionChunk_LeftBracket CompletionChunkKind = C.CXCompletionChunk_LeftBracket 318 | /** 319 | * \brief A right bracket (']'). 320 | */ 321 | CompletionChunk_RightBracket CompletionChunkKind = C.CXCompletionChunk_RightBracket 322 | /** 323 | * \brief A left brace ('{'). 324 | */ 325 | CompletionChunk_LeftBrace CompletionChunkKind = C.CXCompletionChunk_LeftBrace 326 | /** 327 | * \brief A right brace ('}'). 328 | */ 329 | CompletionChunk_RightBrace CompletionChunkKind = C.CXCompletionChunk_RightBrace 330 | /** 331 | * \brief A left angle bracket ('<'). 332 | */ 333 | CompletionChunk_LeftAngle CompletionChunkKind = C.CXCompletionChunk_LeftAngle 334 | /** 335 | * \brief A right angle bracket ('>'). 336 | */ 337 | CompletionChunk_RightAngle CompletionChunkKind = C.CXCompletionChunk_RightAngle 338 | /** 339 | * \brief A comma separator (','). 340 | */ 341 | CompletionChunk_Comma CompletionChunkKind = C.CXCompletionChunk_Comma 342 | /** 343 | * \brief Text that specifies the result type of a given result. 344 | * 345 | * This special kind of informative chunk is not meant to be inserted into 346 | * the text buffer. Rather, it is meant to illustrate the type that an 347 | * expression using the given completion string would have. 348 | */ 349 | CompletionChunk_ResultType CompletionChunkKind = C.CXCompletionChunk_ResultType 350 | /** 351 | * \brief A colon (':'). 352 | */ 353 | CompletionChunk_Colon CompletionChunkKind = C.CXCompletionChunk_Colon 354 | /** 355 | * \brief A semicolon (';'). 356 | */ 357 | CompletionChunk_SemiColon CompletionChunkKind = C.CXCompletionChunk_SemiColon 358 | /** 359 | * \brief An '=' sign. 360 | */ 361 | CompletionChunk_Equal CompletionChunkKind = C.CXCompletionChunk_Equal 362 | /** 363 | * Horizontal space (' '). 364 | */ 365 | CompletionChunk_HorizontalSpace CompletionChunkKind = C.CXCompletionChunk_HorizontalSpace 366 | /** 367 | * Vertical space ('\n'), after which it is generally a good idea to 368 | * perform indentation. 369 | */ 370 | CompletionChunk_VerticalSpace CompletionChunkKind = C.CXCompletionChunk_VerticalSpace 371 | ) 372 | 373 | func (cck CompletionChunkKind) String() string { 374 | switch cck { 375 | case CompletionChunk_Optional: 376 | return "Optional" 377 | case CompletionChunk_TypedText: 378 | return "TypedText" 379 | case CompletionChunk_Text: 380 | return "Text" 381 | case CompletionChunk_Placeholder: 382 | return "Placeholder" 383 | case CompletionChunk_Informative: 384 | return "Informative" 385 | case CompletionChunk_CurrentParameter: 386 | return "CurrentParameter" 387 | case CompletionChunk_LeftParen: 388 | return "LeftParen" 389 | case CompletionChunk_RightParen: 390 | return "RightParen" 391 | case CompletionChunk_LeftBracket: 392 | return "LeftBracket" 393 | case CompletionChunk_RightBracket: 394 | return "RightBracket" 395 | case CompletionChunk_LeftBrace: 396 | return "LeftBrace" 397 | case CompletionChunk_RightBrace: 398 | return "RightBrace" 399 | case CompletionChunk_LeftAngle: 400 | return "LeftAngle" 401 | case CompletionChunk_RightAngle: 402 | return "RightAngle" 403 | case CompletionChunk_Comma: 404 | return "Comma" 405 | case CompletionChunk_ResultType: 406 | return "ResultType" 407 | case CompletionChunk_Colon: 408 | return "Colon" 409 | case CompletionChunk_SemiColon: 410 | return "SemiColon" 411 | case CompletionChunk_Equal: 412 | return "Equal" 413 | case CompletionChunk_HorizontalSpace: 414 | return "HorizontalSpace" 415 | case CompletionChunk_VerticalSpace: 416 | return "VerticalSpace" 417 | default: 418 | return "Invalid" 419 | } 420 | } 421 | 422 | /** 423 | * \brief Contains the results of code-completion. 424 | * 425 | * This data structure contains the results of code completion, as 426 | * produced by \c clang_codeCompleteAt(). Its contents must be freed by 427 | * \c clang_disposeCodeCompleteResults. 428 | */ 429 | type CodeCompleteResults struct { 430 | c *C.CXCodeCompleteResults 431 | } 432 | 433 | func (ccr CodeCompleteResults) IsValid() bool { 434 | return ccr.c != nil 435 | } 436 | 437 | // TODO(): is there a better way to handle this? 438 | func (ccr CodeCompleteResults) Results() (ret []CompletionResult) { 439 | header := (*reflect.SliceHeader)((unsafe.Pointer(&ret))) 440 | header.Cap = int(ccr.c.NumResults) 441 | header.Len = int(ccr.c.NumResults) 442 | header.Data = uintptr(unsafe.Pointer(ccr.c.Results)) 443 | return 444 | } 445 | 446 | /** 447 | * \brief Sort the code-completion results in case-insensitive alphabetical 448 | * order. 449 | * 450 | * \param Results The set of results to sort. 451 | * \param NumResults The number of results in \p Results. 452 | */ 453 | func (ccr CodeCompleteResults) Sort() { 454 | C.clang_sortCodeCompletionResults(ccr.c.Results, ccr.c.NumResults) 455 | } 456 | 457 | /** 458 | * \brief Free the given set of code-completion results. 459 | */ 460 | func (ccr CodeCompleteResults) Dispose() { 461 | C.clang_disposeCodeCompleteResults(ccr.c) 462 | } 463 | 464 | /** 465 | * \brief Retrieve a diagnostic associated with the given code completion. 466 | * 467 | * \param Results the code completion results to query. 468 | * \param Index the zero-based diagnostic number to retrieve. 469 | * 470 | * \returns the requested diagnostic. This diagnostic must be freed 471 | * via a call to \c clang_disposeDiagnostic(). 472 | */ 473 | func (ccr CodeCompleteResults) Diagnostics() (ret Diagnostics) { 474 | ret = make(Diagnostics, C.clang_codeCompleteGetNumDiagnostics(ccr.c)) 475 | for i := range ret { 476 | ret[i].c = C.clang_codeCompleteGetDiagnostic(ccr.c, C.uint(i)) 477 | } 478 | return 479 | } 480 | 481 | /** 482 | * \brief Flags that can be passed to \c clang_codeCompleteAt() to 483 | * modify its behavior. 484 | * 485 | * The enumerators in this enumeration can be bitwise-OR'd together to 486 | * provide multiple options to \c clang_codeCompleteAt(). 487 | */ 488 | type CodeCompleteFlags int 489 | 490 | const ( 491 | /** 492 | * \brief Whether to include macros within the set of code 493 | * completions returned. 494 | */ 495 | CodeCompleteFlags_IncludeMacros CodeCompleteFlags = C.CXCodeComplete_IncludeMacros 496 | 497 | /** 498 | * \brief Whether to include code patterns for language constructs 499 | * within the set of code completions, e.g., for loops. 500 | */ 501 | CodeCompleteFlags_IncludeCodePatterns = C.CXCodeComplete_IncludeCodePatterns 502 | 503 | /** 504 | * \brief Whether to include brief documentation within the set of code 505 | * completions returned. 506 | */ 507 | CodeCompleteFlags_IncludeBriefComments = C.CXCodeComplete_IncludeBriefComments 508 | ) 509 | 510 | /** 511 | * \brief Bits that represent the context under which completion is occurring. 512 | * 513 | * The enumerators in this enumeration may be bitwise-OR'd together if multiple 514 | * contexts are occurring simultaneously. 515 | */ 516 | type CompletionContext int 517 | 518 | const ( 519 | /** 520 | * \brief The context for completions is unexposed, as only Clang results 521 | * should be included. (This is equivalent to having no context bits set.) 522 | */ 523 | CompletionContext_Unexposed CompletionContext = C.CXCompletionContext_Unexposed 524 | 525 | /** 526 | * \brief Completions for any possible type should be included in the results. 527 | */ 528 | CompletionContext_AnyType CompletionContext = C.CXCompletionContext_AnyType 529 | 530 | /** 531 | * \brief Completions for any possible value (variables, function calls, etc.) 532 | * should be included in the results. 533 | */ 534 | CompletionContext_AnyValue CompletionContext = C.CXCompletionContext_AnyValue 535 | /** 536 | * \brief Completions for values that resolve to an Objective-C object should 537 | * be included in the results. 538 | */ 539 | CompletionContext_ObjCObjectValue CompletionContext = C.CXCompletionContext_ObjCObjectValue 540 | /** 541 | * \brief Completions for values that resolve to an Objective-C selector 542 | * should be included in the results. 543 | */ 544 | CompletionContext_ObjCSelectorValue CompletionContext = C.CXCompletionContext_ObjCSelectorValue 545 | /** 546 | * \brief Completions for values that resolve to a C++ class type should be 547 | * included in the results. 548 | */ 549 | CompletionContext_CXXClassTypeValue CompletionContext = C.CXCompletionContext_CXXClassTypeValue 550 | 551 | /** 552 | * \brief Completions for fields of the member being accessed using the dot 553 | * operator should be included in the results. 554 | */ 555 | CompletionContext_DotMemberAccess CompletionContext = C.CXCompletionContext_DotMemberAccess 556 | /** 557 | * \brief Completions for fields of the member being accessed using the arrow 558 | * operator should be included in the results. 559 | */ 560 | CompletionContext_ArrowMemberAccess CompletionContext = C.CXCompletionContext_ArrowMemberAccess 561 | /** 562 | * \brief Completions for properties of the Objective-C object being accessed 563 | * using the dot operator should be included in the results. 564 | */ 565 | CompletionContext_ObjCPropertyAccess CompletionContext = C.CXCompletionContext_ObjCPropertyAccess 566 | 567 | /** 568 | * \brief Completions for enum tags should be included in the results. 569 | */ 570 | CompletionContext_EnumTag CompletionContext = C.CXCompletionContext_EnumTag 571 | /** 572 | * \brief Completions for union tags should be included in the results. 573 | */ 574 | CompletionContext_UnionTag CompletionContext = C.CXCompletionContext_UnionTag 575 | /** 576 | * \brief Completions for struct tags should be included in the results. 577 | */ 578 | CompletionContext_StructTag CompletionContext = C.CXCompletionContext_StructTag 579 | 580 | /** 581 | * \brief Completions for C++ class names should be included in the results. 582 | */ 583 | CompletionContext_ClassTag CompletionContext = C.CXCompletionContext_ClassTag 584 | /** 585 | * \brief Completions for C++ namespaces and namespace aliases should be 586 | * included in the results. 587 | */ 588 | CompletionContext_Namespace CompletionContext = C.CXCompletionContext_Namespace 589 | /** 590 | * \brief Completions for C++ nested name specifiers should be included in 591 | * the results. 592 | */ 593 | CompletionContext_NestedNameSpecifier CompletionContext = C.CXCompletionContext_NestedNameSpecifier 594 | 595 | /** 596 | * \brief Completions for Objective-C interfaces (classes) should be included 597 | * in the results. 598 | */ 599 | CompletionContext_ObjCInterface CompletionContext = C.CXCompletionContext_ObjCInterface 600 | /** 601 | * \brief Completions for Objective-C protocols should be included in 602 | * the results. 603 | */ 604 | CompletionContext_ObjCProtocol CompletionContext = C.CXCompletionContext_ObjCProtocol 605 | /** 606 | * \brief Completions for Objective-C categories should be included in 607 | * the results. 608 | */ 609 | CompletionContext_ObjCCategory CompletionContext = C.CXCompletionContext_ObjCCategory 610 | /** 611 | * \brief Completions for Objective-C instance messages should be included 612 | * in the results. 613 | */ 614 | CompletionContext_ObjCInstanceMessage CompletionContext = C.CXCompletionContext_ObjCInstanceMessage 615 | /** 616 | * \brief Completions for Objective-C class messages should be included in 617 | * the results. 618 | */ 619 | CompletionContext_ObjCClassMessage CompletionContext = C.CXCompletionContext_ObjCClassMessage 620 | /** 621 | * \brief Completions for Objective-C selector names should be included in 622 | * the results. 623 | */ 624 | CompletionContext_ObjCSelectorName CompletionContext = C.CXCompletionContext_ObjCSelectorName 625 | 626 | /** 627 | * \brief Completions for preprocessor macro names should be included in 628 | * the results. 629 | */ 630 | CompletionContext_MacroName CompletionContext = C.CXCompletionContext_MacroName 631 | 632 | /** 633 | * \brief Natural language completions should be included in the results. 634 | */ 635 | CompletionContext_NaturalLanguage CompletionContext = C.CXCompletionContext_NaturalLanguage 636 | 637 | /** 638 | * \brief The current context is unknown, so set all contexts. 639 | */ 640 | CompletionContext_Unknown CompletionContext = C.CXCompletionContext_Unknown 641 | ) 642 | -------------------------------------------------------------------------------- /complete_test.go: -------------------------------------------------------------------------------- 1 | package clang_test 2 | 3 | import ( 4 | "strings" 5 | "testing" 6 | 7 | "github.com/sbinet/go-clang" 8 | ) 9 | 10 | func TestCompleteAt(t *testing.T) { 11 | idx := clang.NewIndex(0, 0) 12 | defer idx.Dispose() 13 | tu := idx.Parse("visitorwrap.c", nil, nil, 0) 14 | if !tu.IsValid() { 15 | t.Fatal("TranslationUnit is not valid") 16 | } 17 | defer tu.Dispose() 18 | 19 | const lineno = 10 // ie: call to clang_visitChildren 20 | res := tu.CompleteAt("visitorwrap.c", lineno, 16, nil, 0) 21 | if !res.IsValid() { 22 | t.Fatal("CompleteResults are not valid") 23 | } 24 | defer res.Dispose() 25 | if n := len(res.Results()); n < 10 { 26 | t.Errorf("Expected more results than %d", n) 27 | } 28 | t.Logf("%+v", res) 29 | for _, r := range res.Results() { 30 | t.Logf("%+v", r) 31 | for _, c := range r.CompletionString.Chunks() { 32 | t.Logf("\t%+v", c) 33 | } 34 | } 35 | 36 | diags := res.Diagnostics() 37 | defer diags.Dispose() 38 | ok := false 39 | for _, d := range diags { 40 | if strings.Contains(d.Spelling(), "_cgo_export.h") { 41 | ok = true 42 | } 43 | t.Log(d.Severity(), d.Spelling()) 44 | } 45 | if !ok { 46 | t.Errorf("Expected to find a diagnostic regarding _cgo_export.h") 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /cursorkind.go: -------------------------------------------------------------------------------- 1 | package clang 2 | 3 | // #include 4 | // #include "go-clang.h" 5 | import "C" 6 | 7 | /** 8 | * \brief Describes the kind of entity that a cursor refers to. 9 | */ 10 | type CursorKind uint32 //FIXME: use uint32? int64? 11 | const ( 12 | /** 13 | * \brief A declaration whose specific kind is not exposed via this 14 | * interface. 15 | * 16 | * Unexposed declarations have the same operations as any other kind 17 | * of declaration; one can extract their location information, 18 | * spelling, find their definitions, etc. However, the specific kind 19 | * of the declaration is not reported. 20 | */ 21 | CK_UnexposedDecl CursorKind = C.CXCursor_UnexposedDecl 22 | 23 | // A C or C++ struct. 24 | CK_StructDecl = C.CXCursor_StructDecl 25 | // A C or C++ union 26 | CK_UnionDecl = C.CXCursor_UnionDecl 27 | // A C++ class 28 | CK_ClassDecl = C.CXCursor_ClassDecl 29 | // An enumeration 30 | CK_EnumDecl = C.CXCursor_EnumDecl 31 | // A field (in C) or non-static data member (in C++) in a 32 | // struct, union, or C++ class. 33 | CK_FieldDecl = C.CXCursor_FieldDecl 34 | /** \brief An enumerator constant. */ 35 | CK_EnumConstantDecl = C.CXCursor_EnumConstantDecl 36 | /** \brief A function. */ 37 | CK_FunctionDecl = C.CXCursor_FunctionDecl 38 | /** \brief A variable. */ 39 | CK_VarDecl = C.CXCursor_VarDecl 40 | /** \brief A function or method parameter. */ 41 | CK_ParmDecl = C.CXCursor_ParmDecl 42 | /** \brief An Objective-C @interface. */ 43 | CK_ObjCInterfaceDecl = C.CXCursor_ObjCInterfaceDecl 44 | /** \brief An Objective-C @interface for a category. */ 45 | CK_ObjCCategoryDecl = C.CXCursor_ObjCCategoryDecl 46 | /** \brief An Objective-C @protocol declaration. */ 47 | CK_ObjCProtocolDecl = C.CXCursor_ObjCProtocolDecl 48 | /** \brief An Objective-C @property declaration. */ 49 | CK_ObjCPropertyDecl = C.CXCursor_ObjCPropertyDecl 50 | /** \brief An Objective-C instance variable. */ 51 | CK_ObjCIvarDecl = C.CXCursor_ObjCIvarDecl 52 | /** \brief An Objective-C instance method. */ 53 | CK_ObjCInstanceMethodDecl = C.CXCursor_ObjCInstanceMethodDecl 54 | /** \brief An Objective-C class method. */ 55 | CK_ObjCClassMethodDecl = C.CXCursor_ObjCClassMethodDecl 56 | /** \brief An Objective-C @implementation. */ 57 | CK_ObjCImplementationDecl = C.CXCursor_ObjCImplementationDecl 58 | /** \brief An Objective-C @implementation for a category. */ 59 | CK_ObjCCategoryImplDecl = C.CXCursor_ObjCCategoryImplDecl 60 | /** \brief A typedef */ 61 | CK_TypedefDecl = C.CXCursor_TypedefDecl 62 | /** \brief A C++ class method. */ 63 | CK_CXXMethod = C.CXCursor_CXXMethod 64 | /** \brief A C++ namespace. */ 65 | CK_Namespace = C.CXCursor_Namespace 66 | /** \brief A linkage specification, e.g. 'extern "C"'. */ 67 | CK_LinkageSpec = C.CXCursor_LinkageSpec 68 | /** \brief A C++ constructor. */ 69 | CK_Constructor = C.CXCursor_Constructor 70 | /** \brief A C++ destructor. */ 71 | CK_Destructor = C.CXCursor_Destructor 72 | /** \brief A C++ conversion function. */ 73 | CK_ConversionFunction = C.CXCursor_ConversionFunction 74 | /** \brief A C++ template type parameter. */ 75 | CK_TemplateTypeParameter = C.CXCursor_TemplateTypeParameter 76 | /** \brief A C++ non-type template parameter. */ 77 | CK_NonTypeTemplateParameter = C.CXCursor_NonTypeTemplateParameter 78 | /** \brief A C++ template template parameter. */ 79 | CK_TemplateTemplateParameter = C.CXCursor_TemplateTemplateParameter 80 | /** \brief A C++ function template. */ 81 | CK_FunctionTemplate = C.CXCursor_FunctionTemplate 82 | /** \brief A C++ class template. */ 83 | CK_ClassTemplate = C.CXCursor_ClassTemplate 84 | /** \brief A C++ class template partial specialization. */ 85 | CK_ClassTemplatePartialSpecialization = C.CXCursor_ClassTemplatePartialSpecialization 86 | /** \brief A C++ namespace alias declaration. */ 87 | CK_NamespaceAlias = C.CXCursor_NamespaceAlias 88 | /** \brief A C++ using directive. */ 89 | CK_UsingDirective = C.CXCursor_UsingDirective 90 | /** \brief A C++ using declaration. */ 91 | CK_UsingDeclaration = C.CXCursor_UsingDeclaration 92 | /** \brief A C++ alias declaration */ 93 | CK_TypeAliasDecl = C.CXCursor_TypeAliasDecl 94 | /** \brief An Objective-C @synthesize definition. */ 95 | CK_ObjCSynthesizeDecl = C.CXCursor_ObjCSynthesizeDecl 96 | /** \brief An Objective-C @dynamic definition. */ 97 | CK_ObjCDynamicDecl = C.CXCursor_ObjCDynamicDecl 98 | /** \brief An access specifier. */ 99 | CK_CXXAccessSpecifier = C.CXCursor_CXXAccessSpecifier 100 | 101 | CK_FirstDecl = C.CXCursor_FirstDecl 102 | CK_LastDecl = C.CXCursor_LastDecl 103 | 104 | /* References */ 105 | CK_FirstRef = C.CXCursor_FirstRef 106 | CK_ObjCSuperClassRef = C.CXCursor_ObjCSuperClassRef 107 | CK_ObjCProtocolRef = C.CXCursor_ObjCProtocolRef 108 | CK_ObjCClassRef = C.CXCursor_ObjCClassRef 109 | /** 110 | * \brief A reference to a type declaration. 111 | * 112 | * A type reference occurs anywhere where a type is named but not 113 | * declared. For example, given: 114 | * 115 | * \code 116 | * typedef unsigned size_type; 117 | * size_type size; 118 | * \endcode 119 | * 120 | * The typedef is a declaration of size_type (CXCursor_TypedefDecl), 121 | * while the type of the variable "size" is referenced. The cursor 122 | * referenced by the type of size is the typedef for size_type. 123 | */ 124 | CK_TypeRef = C.CXCursor_TypeRef 125 | CK_CXXBaseSpecifier = C.CXCursor_CXXBaseSpecifier 126 | /** 127 | * \brief A reference to a class template, function template, template 128 | * template parameter, or class template partial specialization. 129 | */ 130 | CK_TemplateRef = C.CXCursor_TemplateRef 131 | /** 132 | * \brief A reference to a namespace or namespace alias. 133 | */ 134 | CK_NamespaceRef = C.CXCursor_NamespaceRef 135 | /** 136 | * \brief A reference to a member of a struct, union, or class that occurs in 137 | * some non-expression context, e.g., a designated initializer. 138 | */ 139 | CK_MemberRef = C.CXCursor_MemberRef 140 | /** 141 | * \brief A reference to a labeled statement. 142 | * 143 | * This cursor kind is used to describe the jump to "start_over" in the 144 | * goto statement in the following example: 145 | * 146 | * \code 147 | * start_over: 148 | * ++counter; 149 | * 150 | * goto start_over; 151 | * \endcode 152 | * 153 | * A label reference cursor refers to a label statement. 154 | */ 155 | CK_LabelRef = C.CXCursor_LabelRef 156 | 157 | /** 158 | * \brief A reference to a set of overloaded functions or function templates 159 | * that has not yet been resolved to a specific function or function template. 160 | * 161 | * An overloaded declaration reference cursor occurs in C++ templates where 162 | * a dependent name refers to a function. For example: 163 | * 164 | * \code 165 | * template void swap(T&, T&); 166 | * 167 | * struct X { ... }; 168 | * void swap(X&, X&); 169 | * 170 | * template 171 | * void reverse(T* first, T* last) { 172 | * while (first < last - 1) { 173 | * swap(*first, *--last); 174 | * ++first; 175 | * } 176 | * } 177 | * 178 | * struct Y { }; 179 | * void swap(Y&, Y&); 180 | * \endcode 181 | * 182 | * Here, the identifier "swap" is associated with an overloaded declaration 183 | * reference. In the template definition, "swap" refers to either of the two 184 | * "swap" functions declared above, so both results will be available. At 185 | * instantiation time, "swap" may also refer to other functions found via 186 | * argument-dependent lookup (e.g., the "swap" function at the end of the 187 | * example). 188 | * 189 | * The functions \c clang_getNumOverloadedDecls() and 190 | * \c clang_getOverloadedDecl() can be used to retrieve the definitions 191 | * referenced by this cursor. 192 | */ 193 | CK_OverloadedDeclRef = C.CXCursor_OverloadedDeclRef 194 | 195 | CK_LastRef = C.CXCursor_LastRef 196 | 197 | /* Error conditions */ 198 | CK_FirstInvalid = C.CXCursor_FirstInvalid 199 | CK_InvalidFile = C.CXCursor_InvalidFile 200 | CK_NoDeclFound = C.CXCursor_NoDeclFound 201 | CK_NotImplemented = C.CXCursor_NotImplemented 202 | CK_InvalidCode = C.CXCursor_InvalidCode 203 | CK_LastInvalid = C.CXCursor_LastInvalid 204 | 205 | /* Expressions */ 206 | CK_FirstExpr = C.CXCursor_FirstExpr 207 | 208 | /** 209 | * \brief An expression whose specific kind is not exposed via this 210 | * interface. 211 | * 212 | * Unexposed expressions have the same operations as any other kind 213 | * of expression; one can extract their location information, 214 | * spelling, children, etc. However, the specific kind of the 215 | * expression is not reported. 216 | */ 217 | CK_UnexposedExpr = C.CXCursor_UnexposedExpr 218 | 219 | /** 220 | * \brief An expression that refers to some value declaration, such 221 | * as a function, varible, or enumerator. 222 | */ 223 | CK_DeclRefExpr = C.CXCursor_DeclRefExpr 224 | 225 | /** 226 | * \brief An expression that refers to a member of a struct, union, 227 | * class, Objective-C class, etc. 228 | */ 229 | CK_MemberRefExpr = C.CXCursor_MemberRefExpr 230 | 231 | /** \brief An expression that calls a function. */ 232 | CK_CallExpr = C.CXCursor_CallExpr 233 | 234 | /** \brief An expression that sends a message to an Objective-C 235 | object or class. */ 236 | CK_ObjCMessageExpr = C.CXCursor_ObjCMessageExpr 237 | 238 | /** \brief An expression that represents a block literal. */ 239 | CK_BlockExpr = C.CXCursor_BlockExpr 240 | 241 | /** \brief An integer literal. 242 | */ 243 | CK_IntegerLiteral = C.CXCursor_IntegerLiteral 244 | 245 | /** \brief A floating point number literal. 246 | */ 247 | CK_FloatingLiteral = C.CXCursor_FloatingLiteral 248 | 249 | /** \brief An imaginary number literal. 250 | */ 251 | CK_ImaginaryLiteral = C.CXCursor_ImaginaryLiteral 252 | 253 | /** \brief A string literal. 254 | */ 255 | CK_StringLiteral = C.CXCursor_StringLiteral 256 | 257 | /** \brief A character literal. 258 | */ 259 | CK_CharacterLiteral = C.CXCursor_CharacterLiteral 260 | 261 | /** \brief A parenthesized expression, e.g. "(1)". 262 | * 263 | * This AST node is only formed if full location information is requested. 264 | */ 265 | CK_ParenExpr = C.CXCursor_ParenExpr 266 | 267 | /** \brief This represents the unary-expression's (except sizeof and 268 | * alignof). 269 | */ 270 | CK_UnaryOperator = C.CXCursor_UnaryOperator 271 | 272 | /** \brief [C99 6.5.2.1] Array Subscripting. 273 | */ 274 | CK_ArraySubscriptExpr = C.CXCursor_ArraySubscriptExpr 275 | 276 | /** \brief A builtin binary operation expression such as "x + y" or 277 | * "x <= y". 278 | */ 279 | CK_BinaryOperator = C.CXCursor_BinaryOperator 280 | 281 | /** \brief Compound assignment such as "+=". 282 | */ 283 | CK_CompoundAssignOperator = C.CXCursor_CompoundAssignOperator 284 | 285 | /** \brief The ?: ternary operator. 286 | */ 287 | CK_ConditionalOperator = C.CXCursor_ConditionalOperator 288 | 289 | /** \brief An explicit cast in C (C99 6.5.4) or a C-style cast in C++ 290 | * (C++ [expr.cast]), which uses the syntax (Type)expr. 291 | * 292 | * For example: (int)f. 293 | */ 294 | CK_CStyleCastExpr = C.CXCursor_CStyleCastExpr 295 | 296 | /** \brief [C99 6.5.2.5] 297 | */ 298 | CK_CompoundLiteralExpr = C.CXCursor_CompoundLiteralExpr 299 | 300 | /** \brief Describes an C or C++ initializer list. 301 | */ 302 | CK_InitListExpr = C.CXCursor_InitListExpr 303 | 304 | /** \brief The GNU address of label extension, representing &&label. 305 | */ 306 | CK_AddrLabelExpr = C.CXCursor_AddrLabelExpr 307 | 308 | /** \brief This is the GNU Statement Expression extension: ({int X=4; X;}) 309 | */ 310 | CK_StmtExpr = C.CXCursor_StmtExpr 311 | 312 | /** \brief Represents a C1X generic selection. 313 | */ 314 | CK_GenericSelectionExpr = C.CXCursor_GenericSelectionExpr 315 | 316 | /** \brief Implements the GNU __null extension, which is a name for a null 317 | * pointer constant that has integral type (e.g., int or long) and is the same 318 | * size and alignment as a pointer. 319 | * 320 | * The __null extension is typically only used by system headers, which define 321 | * NULL as __null in C++ rather than using 0 (which is an integer that may not 322 | * match the size of a pointer). 323 | */ 324 | CK_GNUNullExpr = C.CXCursor_GNUNullExpr 325 | 326 | /** \brief C++'s static_cast<> expression. 327 | */ 328 | CK_CXXStaticCastExpr = C.CXCursor_CXXStaticCastExpr 329 | 330 | /** \brief C++'s dynamic_cast<> expression. 331 | */ 332 | CK_CXXDynamicCastExpr = C.CXCursor_CXXDynamicCastExpr 333 | 334 | /** \brief C++'s reinterpret_cast<> expression. 335 | */ 336 | CK_CXXReinterpretCastExpr = C.CXCursor_CXXReinterpretCastExpr 337 | 338 | /** \brief C++'s const_cast<> expression. 339 | */ 340 | CK_CXXConstCastExpr = C.CXCursor_CXXConstCastExpr 341 | 342 | /** \brief Represents an explicit C++ type conversion that uses "functional" 343 | * notion (C++ [expr.type.conv]). 344 | * 345 | * Example: 346 | * \code 347 | * x = int(0.5); 348 | * \endcode 349 | */ 350 | CK_CXXFunctionalCastExpr = C.CXCursor_CXXFunctionalCastExpr 351 | 352 | /** \brief A C++ typeid expression (C++ [expr.typeid]). 353 | */ 354 | CK_CXXTypeidExpr = C.CXCursor_CXXTypeidExpr 355 | 356 | /** \brief [C++ 2.13.5] C++ Boolean Literal. 357 | */ 358 | CK_CXXBoolLiteralExpr = C.CXCursor_CXXBoolLiteralExpr 359 | 360 | /** \brief [C++0x 2.14.7] C++ Pointer Literal. 361 | */ 362 | CK_CXXNullPtrLiteralExpr = C.CXCursor_CXXNullPtrLiteralExpr 363 | 364 | /** \brief Represents the "this" expression in C++ 365 | */ 366 | CK_CXXThisExpr = C.CXCursor_CXXThisExpr 367 | 368 | /** \brief [C++ 15] C++ Throw Expression. 369 | * 370 | * This handles 'throw' and 'throw' assignment-expression. When 371 | * assignment-expression isn't present, Op will be null. 372 | */ 373 | CK_CXXThrowExpr = C.CXCursor_CXXThrowExpr 374 | 375 | /** \brief A new expression for memory allocation and constructor calls, e.g: 376 | * "new CXXNewExpr(foo)". 377 | */ 378 | CK_CXXNewExpr = C.CXCursor_CXXNewExpr 379 | 380 | /** \brief A delete expression for memory deallocation and destructor calls, 381 | * e.g. "delete[] pArray". 382 | */ 383 | CK_CXXDeleteExpr = C.CXCursor_CXXDeleteExpr 384 | 385 | /** \brief A unary expression. 386 | */ 387 | CK_UnaryExpr = C.CXCursor_UnaryExpr 388 | 389 | /** \brief ObjCStringLiteral, used for Objective-C string literals i.e. "foo". 390 | */ 391 | CK_ObjCStringLiteral = C.CXCursor_ObjCStringLiteral 392 | 393 | /** \brief ObjCEncodeExpr, used for in Objective-C. 394 | */ 395 | CK_ObjCEncodeExpr = C.CXCursor_ObjCEncodeExpr 396 | 397 | /** \brief ObjCSelectorExpr used for in Objective-C. 398 | */ 399 | CK_ObjCSelectorExpr = C.CXCursor_ObjCSelectorExpr 400 | 401 | /** \brief Objective-C's protocol expression. 402 | */ 403 | CK_ObjCProtocolExpr = C.CXCursor_ObjCProtocolExpr 404 | 405 | /** \brief An Objective-C "bridged" cast expression, which casts between 406 | * Objective-C pointers and C pointers, transferring ownership in the process. 407 | * 408 | * \code 409 | * NSString *str = (__bridge_transfer NSString *)CFCreateString(); 410 | * \endcode 411 | */ 412 | CK_ObjCBridgedCastExpr = C.CXCursor_ObjCBridgedCastExpr 413 | 414 | /** \brief Represents a C++0x pack expansion that produces a sequence of 415 | * expressions. 416 | * 417 | * A pack expansion expression contains a pattern (which itself is an 418 | * expression) followed by an ellipsis. For example: 419 | * 420 | * \code 421 | * template 422 | * void forward(F f, Types &&...args) { 423 | * f(static_cast(args)...); 424 | * } 425 | * \endcode 426 | */ 427 | CK_PackExpansionExpr = C.CXCursor_PackExpansionExpr 428 | 429 | /** \brief Represents an expression that computes the length of a parameter 430 | * pack. 431 | * 432 | * \code 433 | * template 434 | * struct count { 435 | * static const unsigned value = sizeof...(Types); 436 | * }; 437 | * \endcode 438 | */ 439 | CK_SizeOfPackExpr = C.CXCursor_SizeOfPackExpr 440 | 441 | /** \brief Represents the "self" expression in a ObjC method. 442 | */ 443 | CK_ObjCSelfExpr = C.CXCursor_ObjCSelfExpr 444 | 445 | CK_LastExpr = C.CXCursor_LastExpr 446 | 447 | /* Statements */ 448 | CK_FirstStmt = C.CXCursor_FirstStmt 449 | /** 450 | * \brief A statement whose specific kind is not exposed via this 451 | * interface. 452 | * 453 | * Unexposed statements have the same operations as any other kind of 454 | * statement; one can extract their location information, spelling, 455 | * children, etc. However, the specific kind of the statement is not 456 | * reported. 457 | */ 458 | CK_UnexposedStmt = C.CXCursor_UnexposedStmt 459 | 460 | /** \brief A labelled statement in a function. 461 | * 462 | * This cursor kind is used to describe the "start_over:" label statement in 463 | * the following example: 464 | * 465 | * \code 466 | * start_over: 467 | * ++counter; 468 | * \endcode 469 | * 470 | */ 471 | CK_LabelStmt = C.CXCursor_LabelStmt 472 | 473 | /** \brief A group of statements like { stmt stmt }. 474 | * 475 | * This cursor kind is used to describe compound statements, e.g. function 476 | * bodies. 477 | */ 478 | CK_CompoundStmt = C.CXCursor_CompoundStmt 479 | 480 | /** \brief A case statment. 481 | */ 482 | CK_CaseStmt = C.CXCursor_CaseStmt 483 | 484 | /** \brief A default statement. 485 | */ 486 | CK_DefaultStmt = C.CXCursor_DefaultStmt 487 | 488 | /** \brief An if statement 489 | */ 490 | CK_IfStmt = C.CXCursor_IfStmt 491 | 492 | /** \brief A switch statement. 493 | */ 494 | CK_SwitchStmt = C.CXCursor_SwitchStmt 495 | 496 | /** \brief A while statement. 497 | */ 498 | CK_WhileStmt = C.CXCursor_WhileStmt 499 | 500 | /** \brief A do statement. 501 | */ 502 | CK_DoStmt = C.CXCursor_DoStmt 503 | 504 | /** \brief A for statement. 505 | */ 506 | CK_ForStmt = C.CXCursor_ForStmt 507 | 508 | /** \brief A goto statement. 509 | */ 510 | CK_GotoStmt = C.CXCursor_GotoStmt 511 | 512 | /** \brief An indirect goto statement. 513 | */ 514 | CK_IndirectGotoStmt = C.CXCursor_IndirectGotoStmt 515 | 516 | /** \brief A continue statement. 517 | */ 518 | CK_ContinueStmt = C.CXCursor_ContinueStmt 519 | 520 | /** \brief A break statement. 521 | */ 522 | CK_BreakStmt = C.CXCursor_BreakStmt 523 | 524 | /** \brief A return statement. 525 | */ 526 | CK_ReturnStmt = C.CXCursor_ReturnStmt 527 | 528 | /** \brief A GCC inline assembly statement extension. 529 | */ 530 | CK_GCCAsmStmt = C.CXCursor_GCCAsmStmt 531 | CK_AsmStmt = CK_GCCAsmStmt 532 | 533 | /** \brief Objective-C's overall @try-@catc-@finall statement. 534 | */ 535 | CK_ObjCAtTryStmt = C.CXCursor_ObjCAtTryStmt 536 | 537 | /** \brief Objective-C's @catch statement. 538 | */ 539 | CK_ObjCAtCatchStmt = C.CXCursor_ObjCAtCatchStmt 540 | 541 | /** \brief Objective-C's @finally statement. 542 | */ 543 | CK_ObjCAtFinallyStmt = C.CXCursor_ObjCAtFinallyStmt 544 | 545 | /** \brief Objective-C's @throw statement. 546 | */ 547 | CK_ObjCAtThrowStmt = C.CXCursor_ObjCAtThrowStmt 548 | 549 | /** \brief Objective-C's @synchronized statement. 550 | */ 551 | CK_ObjCAtSynchronizedStmt = C.CXCursor_ObjCAtSynchronizedStmt 552 | 553 | /** \brief Objective-C's autorelease pool statement. 554 | */ 555 | CK_ObjCAutoreleasePoolStmt = C.CXCursor_ObjCAutoreleasePoolStmt 556 | 557 | /** \brief Objective-C's collection statement. 558 | */ 559 | CK_ObjCForCollectionStmt = C.CXCursor_ObjCForCollectionStmt 560 | 561 | /** \brief C++'s catch statement. 562 | */ 563 | CK_CXXCatchStmt = C.CXCursor_CXXCatchStmt 564 | 565 | /** \brief C++'s try statement. 566 | */ 567 | CK_CXXTryStmt = C.CXCursor_CXXTryStmt 568 | 569 | /** \brief C++'s for (* : *) statement. 570 | */ 571 | CK_CXXForRangeStmt = C.CXCursor_CXXForRangeStmt 572 | 573 | /** \brief Windows Structured Exception Handling's try statement. 574 | */ 575 | CK_SEHTryStmt = C.CXCursor_SEHTryStmt 576 | 577 | /** \brief Windows Structured Exception Handling's except statement. 578 | */ 579 | CK_SEHExceptStmt = C.CXCursor_SEHExceptStmt 580 | 581 | /** \brief Windows Structured Exception Handling's finally statement. 582 | */ 583 | CK_SEHFinallyStmt = C.CXCursor_SEHFinallyStmt 584 | 585 | /** \brief A MS inline assembly statement extension. 586 | */ 587 | CK_MSAsmStmt = C.CXCursor_MSAsmStmt 588 | 589 | /** \brief The null satement ";": C99 6.8.3p3. 590 | * 591 | * This cursor kind is used to describe the null statement. 592 | */ 593 | CK_NullStmt = C.CXCursor_NullStmt 594 | 595 | /** \brief Adaptor class for mixing declarations with statements and 596 | * expressions. 597 | */ 598 | CK_DeclStmt = C.CXCursor_DeclStmt 599 | 600 | /** \brief OpenMP parallel directive. 601 | */ 602 | CK_OMPParallelDirective = C.CXCursor_OMPParallelDirective 603 | 604 | CK_LastStmt = C.CXCursor_LastStmt 605 | 606 | /** 607 | * \brief Cursor that represents the translation unit itself. 608 | * 609 | * The translation unit cursor exists primarily to act as the root 610 | * cursor for traversing the contents of a translation unit. 611 | */ 612 | CK_TranslationUnit = C.CXCursor_TranslationUnit 613 | 614 | /* Attributes */ 615 | CK_FirstAttr = C.CXCursor_FirstAttr 616 | /** 617 | * \brief An attribute whose specific kind is not exposed via this 618 | * interface. 619 | */ 620 | CK_UnexposedAttr = C.CXCursor_UnexposedAttr 621 | 622 | CK_IBActionAttr = C.CXCursor_IBActionAttr 623 | CK_IBOutletAttr = C.CXCursor_IBOutletAttr 624 | CK_IBOutletCollectionAttr = C.CXCursor_IBOutletCollectionAttr 625 | CK_CXXFinalAttr = C.CXCursor_CXXFinalAttr 626 | CK_CXXOverrideAttr = C.CXCursor_CXXOverrideAttr 627 | CK_AnnotateAttr = C.CXCursor_AnnotateAttr 628 | CK_LastAttr = C.CXCursor_LastAttr 629 | 630 | /* Preprocessing */ 631 | CK_PreprocessingDirective = C.CXCursor_PreprocessingDirective 632 | CK_MacroDefinition = C.CXCursor_MacroDefinition 633 | CK_MacroExpansion = C.CXCursor_MacroExpansion 634 | CK_MacroInstantiation = C.CXCursor_MacroInstantiation 635 | CK_InclusionDirective = C.CXCursor_InclusionDirective 636 | CK_FirstPreprocessing = C.CXCursor_FirstPreprocessing 637 | CK_LastPreprocessing = C.CXCursor_LastPreprocessing 638 | 639 | /* Extra Declarations */ 640 | /** 641 | * \brief A module import declaration. 642 | */ 643 | CK_ModuleImportDecl = C.CXCursor_ModuleImportDecl 644 | CK_FirstExtraDecl = C.CXCursor_FirstExtraDecl 645 | CK_LastExtraDecl = C.CXCursor_LastExtraDecl 646 | ) 647 | 648 | func (c CursorKind) to_c() uint32 { 649 | return uint32(c) 650 | } 651 | 652 | func (c CursorKind) String() string { 653 | return c.Spelling() 654 | } 655 | 656 | /* for debug/testing */ 657 | func (c CursorKind) Spelling() string { 658 | cstr := cxstring{C.clang_getCursorKindSpelling(c.to_c())} 659 | defer cstr.Dispose() 660 | return cstr.String() 661 | } 662 | 663 | // EOF 664 | -------------------------------------------------------------------------------- /cxstring.go: -------------------------------------------------------------------------------- 1 | package clang 2 | 3 | // #include 4 | // #include "go-clang.h" 5 | import "C" 6 | import ( 7 | //"unsafe" 8 | ) 9 | 10 | // cxstring is a character string. 11 | // 12 | // The cxstring type is used to return strings from the interface when the 13 | // ownership of that string might different from one call to the next. 14 | type cxstring struct { 15 | c C.CXString 16 | } 17 | 18 | func (c cxstring) String() string { 19 | cstr := C.clang_getCString(c.c) 20 | return C.GoString(cstr) 21 | } 22 | 23 | func (c cxstring) Dispose() { 24 | C.clang_disposeString(c.c) 25 | } 26 | 27 | // EOF 28 | -------------------------------------------------------------------------------- /diagnostics.go: -------------------------------------------------------------------------------- 1 | package clang 2 | 3 | // #include "go-clang.h" 4 | import "C" 5 | 6 | /** 7 | * \brief Describes the severity of a particular diagnostic. 8 | */ 9 | type DiagnosticSeverity int 10 | 11 | const ( 12 | /** 13 | * \brief A diagnostic that has been suppressed, e.g., by a command-line 14 | * option. 15 | */ 16 | Diagnostic_Ignored = C.CXDiagnostic_Ignored 17 | 18 | /** 19 | * \brief This diagnostic is a note that should be attached to the 20 | * previous (non-note) diagnostic. 21 | */ 22 | Diagnostic_Note = C.CXDiagnostic_Note 23 | 24 | /** 25 | * \brief This diagnostic indicates suspicious code that may not be 26 | * wrong. 27 | */ 28 | Diagnostic_Warning = C.CXDiagnostic_Warning 29 | 30 | /** 31 | * \brief This diagnostic indicates that the code is ill-formed. 32 | */ 33 | Diagnostic_Error = C.CXDiagnostic_Error 34 | 35 | /** 36 | * \brief This diagnostic indicates that the code is ill-formed such 37 | * that future parser recovery is unlikely to produce useful 38 | * results. 39 | */ 40 | Diagnostic_Fatal = C.CXDiagnostic_Fatal 41 | ) 42 | 43 | func (ds DiagnosticSeverity) String() string { 44 | switch ds { 45 | case Diagnostic_Ignored: 46 | return "Ignored" 47 | case Diagnostic_Note: 48 | return "Note" 49 | case Diagnostic_Warning: 50 | return "Warning" 51 | case Diagnostic_Error: 52 | return "Error" 53 | case Diagnostic_Fatal: 54 | return "Fatal" 55 | default: 56 | return "Invalid" 57 | } 58 | } 59 | 60 | /** 61 | * \brief A single diagnostic, containing the diagnostic's severity, 62 | * location, text, source ranges, and fix-it hints. 63 | */ 64 | type Diagnostic struct { 65 | c C.CXDiagnostic 66 | } 67 | 68 | type Diagnostics []Diagnostic 69 | 70 | func (d Diagnostics) Dispose() { 71 | for _, di := range d { 72 | di.Dispose() 73 | } 74 | } 75 | 76 | /** 77 | * \brief Destroy a diagnostic. 78 | */ 79 | func (d Diagnostic) Dispose() { 80 | C.clang_disposeDiagnostic(d.c) 81 | } 82 | 83 | /** 84 | * \brief Determine the severity of the given diagnostic. 85 | */ 86 | func (d Diagnostic) Severity() DiagnosticSeverity { 87 | return DiagnosticSeverity(C.clang_getDiagnosticSeverity(d.c)) 88 | } 89 | 90 | /** 91 | * \brief Retrieve the source location of the given diagnostic. 92 | * 93 | * This location is where Clang would print the caret ('^') when 94 | * displaying the diagnostic on the command line. 95 | */ 96 | func (d Diagnostic) Location() SourceLocation { 97 | return SourceLocation{C.clang_getDiagnosticLocation(d.c)} 98 | } 99 | 100 | /** 101 | * \brief Retrieve the text of the given diagnostic. 102 | */ 103 | func (d Diagnostic) Spelling() string { 104 | cx := cxstring{C.clang_getDiagnosticSpelling(d.c)} 105 | defer cx.Dispose() 106 | return cx.String() 107 | } 108 | 109 | /** 110 | * \brief Retrieve the name of the command-line option that enabled this 111 | * diagnostic. 112 | * 113 | * \param Diag The diagnostic to be queried. 114 | * 115 | * \param Disable If non-NULL, will be set to the option that disables this 116 | * diagnostic (if any). 117 | * 118 | * \returns A string that contains the command-line option used to enable this 119 | * warning, such as "-Wconversion" or "-pedantic". 120 | */ 121 | func (d Diagnostic) Option() (enable, disable string) { 122 | var c_disable cxstring 123 | cx := cxstring{C.clang_getDiagnosticOption(d.c, &c_disable.c)} 124 | defer cx.Dispose() 125 | defer c_disable.Dispose() 126 | return cx.String(), c_disable.String() 127 | } 128 | 129 | /** 130 | * \brief Retrieve a source range associated with the diagnostic. 131 | * 132 | * A diagnostic's source ranges highlight important elements in the source 133 | * code. On the command line, Clang displays source ranges by 134 | * underlining them with '~' characters. 135 | * 136 | * \param Diagnostic the diagnostic whose range is being extracted. 137 | * 138 | * \param Range the zero-based index specifying which range to 139 | * 140 | * \returns the requested source range. 141 | */ 142 | func (d Diagnostic) Ranges() (ret []SourceRange) { 143 | ret = make([]SourceRange, C.clang_getDiagnosticNumRanges(d.c)) 144 | for i := range ret { 145 | ret[i].c = C.clang_getDiagnosticRange(d.c, C.uint(i)) 146 | } 147 | return 148 | } 149 | 150 | type FixIt struct { 151 | Data string 152 | ReplacementRange SourceRange 153 | } 154 | 155 | /** 156 | * \brief Retrieve the replacement information for a given fix-it. 157 | * 158 | * Fix-its are described in terms of a source range whose contents 159 | * should be replaced by a string. This approach generalizes over 160 | * three kinds of operations: removal of source code (the range covers 161 | * the code to be removed and the replacement string is empty), 162 | * replacement of source code (the range covers the code to be 163 | * replaced and the replacement string provides the new code), and 164 | * insertion (both the start and end of the range point at the 165 | * insertion location, and the replacement string provides the text to 166 | * insert). 167 | * 168 | * \param Diagnostic The diagnostic whose fix-its are being queried. 169 | * 170 | * \param FixIt The zero-based index of the fix-it. 171 | * 172 | * \param ReplacementRange The source range whose contents will be 173 | * replaced with the returned replacement string. Note that source 174 | * ranges are half-open ranges [a, b), so the source code should be 175 | * replaced from a and up to (but not including) b. 176 | * 177 | * \returns A string containing text that should be replace the source 178 | * code indicated by the \c ReplacementRange. 179 | */ 180 | func (d Diagnostic) FixIts() (ret []FixIt) { 181 | ret = make([]FixIt, C.clang_getDiagnosticNumFixIts(d.c)) 182 | for i := range ret { 183 | cx := cxstring{C.clang_getDiagnosticFixIt(d.c, C.uint(i), &ret[i].ReplacementRange.c)} 184 | defer cx.Dispose() 185 | ret[i].Data = cx.String() 186 | } 187 | return 188 | } 189 | 190 | /** 191 | * \brief Format the given diagnostic in a manner that is suitable for display. 192 | * 193 | * This routine will format the given diagnostic to a string, rendering 194 | * the diagnostic according to the various options given. The 195 | * \c clang_defaultDiagnosticDisplayOptions() function returns the set of 196 | * options that most closely mimics the behavior of the clang compiler. 197 | * 198 | * \param Diagnostic The diagnostic to print. 199 | * 200 | * \param Options A set of options that control the diagnostic display, 201 | * created by combining \c CXDiagnosticDisplayOptions values. 202 | * 203 | * \returns A new string containing for formatted diagnostic. 204 | */ 205 | func (d Diagnostic) Format(options DiagnosticDisplayOptions) string { 206 | cx := cxstring{C.clang_formatDiagnostic(d.c, C.uint(options))} 207 | defer cx.Dispose() 208 | return cx.String() 209 | } 210 | 211 | func (d Diagnostic) String() string { 212 | return d.Format(DefaultDiagnosticDisplayOptions()) 213 | } 214 | 215 | /** 216 | * \brief Options to control the display of diagnostics. 217 | * 218 | * The values in this enum are meant to be combined to customize the 219 | * behavior of \c clang_displayDiagnostic(). 220 | */ 221 | type DiagnosticDisplayOptions int 222 | 223 | const ( 224 | /** 225 | * \brief Display the source-location information where the 226 | * diagnostic was located. 227 | * 228 | * When set, diagnostics will be prefixed by the file, line, and 229 | * (optionally) column to which the diagnostic refers. For example, 230 | * 231 | * \code 232 | * test.c:28: warning: extra tokens at end of #endif directive 233 | * \endcode 234 | * 235 | * This option corresponds to the clang flag \c -fshow-source-location. 236 | */ 237 | Diagnostic_DisplaySourceLocation = C.CXDiagnostic_DisplaySourceLocation 238 | 239 | /** 240 | * \brief If displaying the source-location information of the 241 | * diagnostic, also include the column number. 242 | * 243 | * This option corresponds to the clang flag \c -fshow-column. 244 | */ 245 | Diagnostic_DisplayColumn = C.CXDiagnostic_DisplayColumn 246 | 247 | /** 248 | * \brief If displaying the source-location information of the 249 | * diagnostic, also include information about source ranges in a 250 | * machine-parsable format. 251 | * 252 | * This option corresponds to the clang flag 253 | * \c -fdiagnostics-print-source-range-info. 254 | */ 255 | Diagnostic_DisplaySourceRanges = C.CXDiagnostic_DisplaySourceRanges 256 | 257 | /** 258 | * \brief Display the option name associated with this diagnostic, if any. 259 | * 260 | * The option name displayed (e.g., -Wconversion) will be placed in brackets 261 | * after the diagnostic text. This option corresponds to the clang flag 262 | * \c -fdiagnostics-show-option. 263 | */ 264 | Diagnostic_DisplayOption = C.CXDiagnostic_DisplayOption 265 | 266 | /** 267 | * \brief Display the category number associated with this diagnostic, if any. 268 | * 269 | * The category number is displayed within brackets after the diagnostic text. 270 | * This option corresponds to the clang flag 271 | * \c -fdiagnostics-show-category=id. 272 | */ 273 | Diagnostic_DisplayCategoryId = C.CXDiagnostic_DisplayCategoryId 274 | 275 | /** 276 | * \brief Display the category name associated with this diagnostic, if any. 277 | * 278 | * The category name is displayed within brackets after the diagnostic text. 279 | * This option corresponds to the clang flag 280 | * \c -fdiagnostics-show-category=name. 281 | */ 282 | Diagnostic_DisplayCategoryName = C.CXDiagnostic_DisplayCategoryName 283 | ) 284 | 285 | /** 286 | * \brief Retrieve the set of display options most similar to the 287 | * default behavior of the clang compiler. 288 | * 289 | * \returns A set of display options suitable for use with \c 290 | * clang_displayDiagnostic(). 291 | */ 292 | func DefaultDiagnosticDisplayOptions() DiagnosticDisplayOptions { 293 | return DiagnosticDisplayOptions(C.clang_defaultDiagnosticDisplayOptions()) 294 | } 295 | -------------------------------------------------------------------------------- /diagnostics_test.go: -------------------------------------------------------------------------------- 1 | package clang_test 2 | 3 | import ( 4 | "strings" 5 | "testing" 6 | 7 | "github.com/sbinet/go-clang" 8 | ) 9 | 10 | func TestDiagnostics(t *testing.T) { 11 | idx := clang.NewIndex(0, 0) 12 | defer idx.Dispose() 13 | tu := idx.Parse("visitorwrap.c", nil, nil, 0) 14 | if !tu.IsValid() { 15 | t.Fatal("TranslationUnit is not valid") 16 | } 17 | defer tu.Dispose() 18 | 19 | diags := tu.Diagnostics() 20 | defer diags.Dispose() 21 | ok := false 22 | for _, d := range diags { 23 | if strings.Contains(d.Spelling(), "_cgo_export.h") { 24 | ok = true 25 | } 26 | t.Log(d) 27 | t.Log(d.Severity(), d.Spelling()) 28 | t.Log(d.Format(clang.Diagnostic_DisplayCategoryName | clang.Diagnostic_DisplaySourceLocation)) 29 | } 30 | if !ok { 31 | t.Errorf("Expected to find a diagnostic regarding _cgo_export.h") 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /doc.go: -------------------------------------------------------------------------------- 1 | // clang provides naive bindings to the CLang C-API. 2 | // 3 | // typical usage follows: 4 | // 5 | // const excludeDeclarationsFromPCH = 1 6 | // const displayDiagnostics = 1 7 | // idx := clang.NewIndex(excludeDeclarationsFromPCH, displayDiagnostics) 8 | // defer idx.Dispose() 9 | // 10 | // args := []string{} 11 | // tu := idx.Parse("somefile.cxx", args) 12 | // defer tu.Dispose() 13 | // fmt.Printf("translation unit: %s\n", tu.Spelling()) 14 | // 15 | package clang 16 | 17 | // EOF 18 | -------------------------------------------------------------------------------- /file.go: -------------------------------------------------------------------------------- 1 | package clang 2 | 3 | // #include 4 | // #include "go-clang.h" 5 | import "C" 6 | 7 | import ( 8 | "time" 9 | ) 10 | 11 | // A particular source file that is part of a translation unit. 12 | type File struct { 13 | c C.CXFile 14 | } 15 | 16 | // Name retrieves the complete file and path name of the given file. 17 | func (c File) Name() string { 18 | cstr := cxstring{C.clang_getFileName(c.c)} 19 | defer cstr.Dispose() 20 | return cstr.String() 21 | } 22 | 23 | // ModTime retrieves the last modification time of the given file. 24 | func (c File) ModTime() time.Time { 25 | // time_t is in seconds since epoch 26 | sec := C.clang_getFileTime(c.c) 27 | const nsec = 0 28 | return time.Unix(int64(sec), nsec) 29 | } 30 | -------------------------------------------------------------------------------- /fileuniqueid.go: -------------------------------------------------------------------------------- 1 | package clang 2 | 3 | // #include 4 | // #include "go-clang.h" 5 | import "C" 6 | 7 | import ( 8 | "fmt" 9 | ) 10 | 11 | /** 12 | * \brief Uniquely identifies a CXFile, that refers to the same underlying file, 13 | * across an indexing session. 14 | */ 15 | type FileUniqueID struct { 16 | c C.CXFileUniqueID 17 | } 18 | 19 | /** 20 | * \brief Retrieve the unique ID for the given \c file. 21 | * 22 | * \param file the file to get the ID for. 23 | * \param outID stores the returned CXFileUniqueID. 24 | * \returns If there was a failure getting the unique ID, returns non-zero, 25 | * otherwise returns 0. 26 | */ 27 | func (f File) GetFileUniqueID() (FileUniqueID, error) { 28 | var fid FileUniqueID 29 | o := C.clang_getFileUniqueID(f.c, &fid.c) 30 | if o != 0 { 31 | return fid, fmt.Errorf("clang: could not get FileUniqueID (err=%d)", o) 32 | } 33 | return fid, nil 34 | } 35 | -------------------------------------------------------------------------------- /go-clang-compdb/main.go: -------------------------------------------------------------------------------- 1 | // go-clang-compdb dumps the content of a CLang compilation database 2 | package main 3 | 4 | import ( 5 | "fmt" 6 | "os" 7 | "path/filepath" 8 | "strings" 9 | 10 | clang "github.com/sbinet/go-clang" 11 | ) 12 | 13 | func main() { 14 | if len(os.Args) <= 1 { 15 | fmt.Printf("**error: you need to give a directory containing a 'compile_commands.json' file\n") 16 | os.Exit(1) 17 | } 18 | dir := os.ExpandEnv(os.Args[1]) 19 | fmt.Printf(":: inspecting [%s]...\n", dir) 20 | 21 | fname := filepath.Join(dir, "compile_commands.json") 22 | f, err := os.Open(fname) 23 | if err != nil { 24 | fmt.Printf("**error: could not open file [%s]: %v\n", fname, err) 25 | os.Exit(1) 26 | } 27 | f.Close() 28 | 29 | db, err := clang.NewCompilationDatabase(dir) 30 | if err != nil { 31 | fmt.Printf("**error: could not open compilation database at [%s]: %v\n", dir, err) 32 | os.Exit(1) 33 | } 34 | defer db.Dispose() 35 | 36 | cmds := db.GetAllCompileCommands() 37 | ncmds := cmds.GetSize() 38 | fmt.Printf(":: got %d compile commands\n", ncmds) 39 | for i := 0; i < ncmds; i++ { 40 | cmd := cmds.GetCommand(i) 41 | fmt.Printf(":: --- cmd=%d ---\n", i) 42 | fmt.Printf(":: dir= %q\n", cmd.GetDirectory()) 43 | nargs := cmd.GetNumArgs() 44 | fmt.Printf(":: nargs= %d\n", nargs) 45 | sargs := make([]string, 0, nargs) 46 | for iarg := 0; iarg < nargs; iarg++ { 47 | arg := cmd.GetArg(iarg) 48 | sfmt := "%q, " 49 | if iarg+1 == nargs { 50 | sfmt = "%q" 51 | } 52 | sargs = append(sargs, fmt.Sprintf(sfmt, arg)) 53 | 54 | } 55 | fmt.Printf(":: args= {%s}\n", strings.Join(sargs, "")) 56 | if i+1 != ncmds { 57 | fmt.Printf("::\n") 58 | } 59 | } 60 | fmt.Printf(":: inspecting [%s]... [done]\n", dir) 61 | } 62 | -------------------------------------------------------------------------------- /go-clang-dump/main.go: -------------------------------------------------------------------------------- 1 | // go-clang-dump shows how to dump the AST of a C/C++ file via the Cursor 2 | // visitor API. 3 | // 4 | // ex: 5 | // $ go-clang-dump -fname=foo.cxx 6 | package main 7 | 8 | import ( 9 | "flag" 10 | "fmt" 11 | "os" 12 | 13 | "github.com/sbinet/go-clang" 14 | ) 15 | 16 | var fname *string = flag.String("fname", "", "the file to analyze") 17 | 18 | func main() { 19 | fmt.Printf(":: go-clang-dump...\n") 20 | flag.Parse() 21 | fmt.Printf(":: fname: %s\n", *fname) 22 | fmt.Printf(":: args: %v\n", flag.Args()) 23 | if *fname == "" { 24 | flag.Usage() 25 | fmt.Printf("please provide a file name to analyze\n") 26 | os.Exit(1) 27 | } 28 | idx := clang.NewIndex(0, 1) 29 | defer idx.Dispose() 30 | 31 | nidx := 0 32 | args := []string{} 33 | if len(flag.Args()) > 0 && flag.Args()[0] == "-" { 34 | nidx = 1 35 | args = make([]string, len(flag.Args()[nidx:])) 36 | copy(args, flag.Args()[nidx:]) 37 | } 38 | 39 | tu := idx.Parse(*fname, args, nil, 0) 40 | 41 | defer tu.Dispose() 42 | 43 | fmt.Printf("tu: %s\n", tu.Spelling()) 44 | cursor := tu.ToCursor() 45 | fmt.Printf("cursor-isnull: %v\n", cursor.IsNull()) 46 | fmt.Printf("cursor: %s\n", cursor.Spelling()) 47 | fmt.Printf("cursor-kind: %s\n", cursor.Kind().Spelling()) 48 | 49 | tu_fname := tu.File(*fname).Name() 50 | fmt.Printf("tu-fname: %s\n", tu_fname) 51 | 52 | fct := func(cursor, parent clang.Cursor) clang.ChildVisitResult { 53 | if cursor.IsNull() { 54 | fmt.Printf("cursor: \n") 55 | return clang.CVR_Continue 56 | } 57 | fmt.Printf("%s: %s (%s)\n", 58 | cursor.Kind().Spelling(), cursor.Spelling(), cursor.USR()) 59 | switch cursor.Kind() { 60 | case clang.CK_ClassDecl, clang.CK_EnumDecl, 61 | clang.CK_StructDecl, clang.CK_Namespace: 62 | return clang.CVR_Recurse 63 | } 64 | return clang.CVR_Continue 65 | } 66 | 67 | cursor.Visit(fct) 68 | 69 | fmt.Printf(":: bye.\n") 70 | } 71 | 72 | // EOF 73 | -------------------------------------------------------------------------------- /go-clang-dump/main_test.go: -------------------------------------------------------------------------------- 1 | package main_test 2 | 3 | import ( 4 | "os/exec" 5 | "testing" 6 | ) 7 | 8 | func TestClangDump(t *testing.T) { 9 | for _, fname := range []string{ 10 | "../testdata/hello.c", 11 | "../testdata/struct.c", 12 | "../visitorwrap.c", 13 | } { 14 | cmd := exec.Command("go-clang-dump", "-fname", fname) 15 | err := cmd.Run() 16 | if err != nil { 17 | t.Fatalf("error running go-clang-dump on %q: %v\n", fname, err) 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /go-clang.h: -------------------------------------------------------------------------------- 1 | #ifndef _GO_CLANG 2 | #define _GO_CLANG 1 3 | 4 | /* 5 | * include our own clang-c/Index.h. 6 | * It should be exactly the same than the upstream one, except that: 7 | * - CXComment 8 | * - CXCursor 9 | * - CXIdxLoc 10 | * - CXSourceLocation 11 | * - CXSourceRange 12 | * - CXString 13 | * - CXTUResourceUsage 14 | * - CXToken 15 | * - CXType 16 | * have been modified to hide the 'void *field[x]' fields from the Go GC. 17 | * Not hiding these fields confuses the Go GC during garbage collection and pointer scanning, 18 | * making it think the heap/stack has been somehow corrupted. 19 | */ 20 | #include "clang-c/Index.h" 21 | 22 | inline static 23 | CXCursor _go_clang_ocursor_at(CXCursor *c, int idx) { 24 | return c[idx]; 25 | } 26 | 27 | inline static 28 | CXPlatformAvailability 29 | _goclang_get_platform_availability_at(CXPlatformAvailability* array, int idx) { 30 | return array[idx]; 31 | } 32 | 33 | unsigned _go_clang_visit_children(CXCursor c, uintptr_t callback_id); 34 | 35 | CXPlatformAvailability 36 | _goclang_get_platform_availability_at(CXPlatformAvailability* array, int idx); 37 | 38 | #endif /* !_GO_CLANG */ 39 | -------------------------------------------------------------------------------- /module.go: -------------------------------------------------------------------------------- 1 | package clang 2 | 3 | // #include 4 | // #include "go-clang.h" 5 | import "C" 6 | 7 | // Module describes a C++ Module 8 | type Module struct { 9 | c C.CXModule 10 | } 11 | 12 | /** 13 | * \param Module a module object. 14 | * 15 | * \returns the module file where the provided module object came from. 16 | */ 17 | func (m Module) ASTFile() File { 18 | return File{C.clang_Module_getASTFile(m.c)} 19 | } 20 | 21 | /** 22 | * \param Module a module object. 23 | * 24 | * \returns the parent of a sub-module or NULL if the given module is top-level, 25 | * e.g. for 'std.vector' it will return the 'std' module. 26 | */ 27 | func (m Module) Parent() Module { 28 | return Module{C.clang_Module_getParent(m.c)} 29 | } 30 | 31 | /** 32 | * \param Module a module object. 33 | * 34 | * \returns the name of the module, e.g. for the 'std.vector' sub-module it 35 | * will return "vector". 36 | */ 37 | func (m Module) Name() string { 38 | o := cxstring{C.clang_Module_getName(m.c)} 39 | defer o.Dispose() 40 | return o.String() 41 | } 42 | 43 | /** 44 | * \param Module a module object. 45 | * 46 | * \returns the full name of the module, e.g. "std.vector". 47 | */ 48 | func (m Module) FullName() string { 49 | o := cxstring{C.clang_Module_getFullName(m.c)} 50 | defer o.Dispose() 51 | return o.String() 52 | } 53 | -------------------------------------------------------------------------------- /objcdeclqualifier.go: -------------------------------------------------------------------------------- 1 | package clang 2 | 3 | // TODO: Objective-C support 4 | // /** 5 | // * \brief 'Qualifiers' written next to the return and parameter types in 6 | // * ObjC method declarations. 7 | // */ 8 | // typedef enum { 9 | // CXObjCDeclQualifier_None = 0x0, 10 | // CXObjCDeclQualifier_In = 0x1, 11 | // CXObjCDeclQualifier_Inout = 0x2, 12 | // CXObjCDeclQualifier_Out = 0x4, 13 | // CXObjCDeclQualifier_Bycopy = 0x8, 14 | // CXObjCDeclQualifier_Byref = 0x10, 15 | // CXObjCDeclQualifier_Oneway = 0x20 16 | // } CXObjCDeclQualifierKind; 17 | -------------------------------------------------------------------------------- /objcpropertyattr.go: -------------------------------------------------------------------------------- 1 | package clang 2 | 3 | // TODO: Objective-C support 4 | // /** 5 | // * \brief Property attributes for a \c CXCursor_ObjCPropertyDecl. 6 | // */ 7 | // typedef enum { 8 | // CXObjCPropertyAttr_noattr = 0x00, 9 | // CXObjCPropertyAttr_readonly = 0x01, 10 | // CXObjCPropertyAttr_getter = 0x02, 11 | // CXObjCPropertyAttr_assign = 0x04, 12 | // CXObjCPropertyAttr_readwrite = 0x08, 13 | // CXObjCPropertyAttr_retain = 0x10, 14 | // CXObjCPropertyAttr_copy = 0x20, 15 | // CXObjCPropertyAttr_nonatomic = 0x40, 16 | // CXObjCPropertyAttr_setter = 0x80, 17 | // CXObjCPropertyAttr_atomic = 0x100, 18 | // CXObjCPropertyAttr_weak = 0x200, 19 | // CXObjCPropertyAttr_strong = 0x400, 20 | // CXObjCPropertyAttr_unsafe_unretained = 0x800 21 | // } CXObjCPropertyAttrKind; 22 | -------------------------------------------------------------------------------- /platformavailability.go: -------------------------------------------------------------------------------- 1 | package clang 2 | 3 | // #include 4 | // #include "go-clang.h" 5 | import "C" 6 | 7 | /** 8 | * Describes the availability of a given entity on a particular platform, e.g., 9 | * a particular class might only be available on Mac OS 10.7 or newer. 10 | */ 11 | type PlatformAvailability struct { 12 | c C.CXPlatformAvailability 13 | } 14 | 15 | /** 16 | * \brief A string that describes the platform for which this structure 17 | * provides availability information. 18 | * 19 | * Possible values are "ios" or "macosx". 20 | */ 21 | func (p *PlatformAvailability) Platform() string { 22 | o := cxstring{p.c.Platform} 23 | //defer o.Dispose() // done by PlatformAvailability.Dispose() 24 | return o.String() 25 | } 26 | 27 | /** 28 | * \brief The version number in which this entity was introduced. 29 | */ 30 | func (p *PlatformAvailability) Introduced() Version { 31 | o := Version{p.c.Introduced} 32 | return o 33 | } 34 | 35 | /** 36 | * \brief The version number in which this entity was deprecated (but is 37 | * still available). 38 | */ 39 | func (p *PlatformAvailability) Deprecated() Version { 40 | o := Version{p.c.Deprecated} 41 | return o 42 | } 43 | 44 | /** 45 | * \brief The version number in which this entity was obsoleted, and therefore 46 | * is no longer available. 47 | */ 48 | func (p *PlatformAvailability) Obsoleted() Version { 49 | o := Version{p.c.Obsoleted} 50 | return o 51 | } 52 | 53 | /** 54 | * \brief Whether the entity is unconditionally unavailable on this platform. 55 | */ 56 | func (p *PlatformAvailability) Unavailable() int { 57 | return int(p.c.Unavailable) 58 | } 59 | 60 | /** 61 | * \brief An optional message to provide to a user of this API, e.g., to 62 | * suggest replacement APIs. 63 | */ 64 | func (p *PlatformAvailability) Message() string { 65 | o := cxstring{p.c.Message} 66 | //defer o.Dispose() // done by PlatformAvailability.Dispose() 67 | return o.String() 68 | } 69 | 70 | /** 71 | * \brief Free the memory associated with a \c CXPlatformAvailability structure. 72 | */ 73 | func (p *PlatformAvailability) Dispose() { 74 | C.clang_disposeCXPlatformAvailability(&p.c) 75 | } 76 | -------------------------------------------------------------------------------- /refqualifierkind.go: -------------------------------------------------------------------------------- 1 | package clang 2 | 3 | // #include 4 | // #include "go-clang.h" 5 | import "C" 6 | 7 | // RefQualifierKind describes the kind of reference a Type is decorated with 8 | type RefQualifierKind int 9 | 10 | const ( 11 | 12 | /** \brief No ref-qualifier was provided. */ 13 | RQK_None RefQualifierKind = C.CXRefQualifier_None 14 | 15 | /** \brief An lvalue ref-qualifier was provided (\c &). */ 16 | RQK_LValue = C.CXRefQualifier_LValue 17 | /** \brief An rvalue ref-qualifier was provided (\c &&). */ 18 | RQK_RValue = C.CXRefQualifier_RValue 19 | ) 20 | -------------------------------------------------------------------------------- /result.go: -------------------------------------------------------------------------------- 1 | package clang 2 | 3 | // #include 4 | // #include "go-clang.h" 5 | // 6 | import "C" 7 | 8 | // Result is the result of calling a c-clang function 9 | type Result int 10 | 11 | const ( 12 | /** 13 | * \brief Function returned successfully. 14 | */ 15 | Result_Success Result = C.CXResult_Success 16 | /** 17 | * \brief One of the parameters was invalid for the function. 18 | */ 19 | Result_Invalid = C.CXResult_Invalid 20 | /** 21 | * \brief The function was terminated by a callback (e.g. it returned 22 | * CXVisit_Break) 23 | */ 24 | Result_VisitBreak = C.CXResult_VisitBreak 25 | ) 26 | -------------------------------------------------------------------------------- /sourcelocation.go: -------------------------------------------------------------------------------- 1 | package clang 2 | 3 | // #include 4 | // #include "go-clang.h" 5 | import "C" 6 | 7 | // SourceLocation identifies a specific source location within a translation 8 | // unit. 9 | // 10 | // Use clang_getExpansionLocation() or clang_getSpellingLocation() 11 | // to map a source location to a particular file, line, and column. 12 | type SourceLocation struct { 13 | c C.CXSourceLocation 14 | } 15 | 16 | // NewNullLocation creates a NULL (invalid) source location. 17 | func NewNullLocation() SourceLocation { 18 | return SourceLocation{C.clang_getNullLocation()} 19 | } 20 | 21 | // EqualLocations determines whether two source locations, which must refer into 22 | // the same translation unit, refer to exactly the same point in the source 23 | // code. 24 | // Returns non-zero if the source locations refer to the same location, zero 25 | // if they refer to different locations. 26 | func EqualLocations(loc1, loc2 SourceLocation) bool { 27 | o := C.clang_equalLocations(loc1.c, loc2.c) 28 | if o != C.uint(0) { 29 | return true 30 | } 31 | return false 32 | } 33 | 34 | /** 35 | * \brief Returns non-zero if the given source location is in a system header. 36 | */ 37 | func (loc SourceLocation) IsInSystemHeader() bool { 38 | o := C.clang_Location_isInSystemHeader(loc.c) 39 | if o != 0 { 40 | return true 41 | } 42 | return false 43 | } 44 | 45 | /** 46 | * \brief Returns non-zero if the given source location is in the main file of 47 | * the corresponding translation unit. 48 | */ 49 | func (loc SourceLocation) IsFromMainFile() bool { 50 | o := C.clang_Location_isFromMainFile(loc.c) 51 | if o != 0 { 52 | return true 53 | } 54 | return false 55 | } 56 | 57 | // ExpansionLocation returns the file, line, column, and offset represented by 58 | // the given source location. 59 | // 60 | // If the location refers into a macro expansion, retrieves the 61 | // location of the macro expansion. 62 | // 63 | // file: if non-NULL, will be set to the file to which the given 64 | // source location points. 65 | // 66 | // line: if non-NULL, will be set to the line to which the given 67 | // source location points. 68 | // 69 | // column: if non-NULL, will be set to the column to which the given 70 | // source location points. 71 | // 72 | // offset: if non-NULL, will be set to the offset into the 73 | // buffer to which the given source location points. 74 | func (l SourceLocation) ExpansionLocation() (f File, line, column, offset uint) { 75 | cline := C.uint(0) 76 | ccol := C.uint(0) 77 | coff := C.uint(0) 78 | // FIXME: undefined reference to `clang_getExpansionLocation' 79 | C.clang_getInstantiationLocation(l.c, &f.c, &cline, &ccol, &coff) 80 | line = uint(cline) 81 | column = uint(ccol) 82 | offset = uint(coff) 83 | 84 | return 85 | } 86 | 87 | /** 88 | * \brief Retrieve the file, line, column, and offset represented by 89 | * the given source location, as specified in a # line directive. 90 | * 91 | * Example: given the following source code in a file somefile.c 92 | * 93 | * #123 "dummy.c" 1 94 | * 95 | * static int func(void) 96 | * { 97 | * return 0; 98 | * } 99 | * 100 | * the location information returned by this function would be 101 | * 102 | * File: dummy.c Line: 124 Column: 12 103 | * 104 | * whereas clang_getExpansionLocation would have returned 105 | * 106 | * File: somefile.c Line: 3 Column: 12 107 | * 108 | * \param location the location within a source file that will be decomposed 109 | * into its parts. 110 | * 111 | * \param filename [out] if non-NULL, will be set to the filename of the 112 | * source location. Note that filenames returned will be for "virtual" files, 113 | * which don't necessarily exist on the machine running clang - e.g. when 114 | * parsing preprocessed output obtained from a different environment. If 115 | * a non-NULL value is passed in, remember to dispose of the returned value 116 | * using \c clang_disposeString() once you've finished with it. For an invalid 117 | * source location, an empty string is returned. 118 | * 119 | * \param line [out] if non-NULL, will be set to the line number of the 120 | * source location. For an invalid source location, zero is returned. 121 | * 122 | * \param column [out] if non-NULL, will be set to the column number of the 123 | * source location. For an invalid source location, zero is returned. 124 | */ 125 | func (l SourceLocation) PresumedLocation() (fname string, line, column uint) { 126 | 127 | cname := cxstring{} 128 | defer cname.Dispose() 129 | cline := C.uint(0) 130 | ccol := C.uint(0) 131 | C.clang_getPresumedLocation(l.c, &cname.c, &cline, &ccol) 132 | fname = cname.String() 133 | line = uint(cline) 134 | column = uint(ccol) 135 | return 136 | } 137 | 138 | /** 139 | * \brief Legacy API to retrieve the file, line, column, and offset represented 140 | * by the given source location. 141 | * 142 | * This interface has been replaced by the newer interface 143 | * \see clang_getExpansionLocation(). See that interface's documentation for 144 | * details. 145 | */ 146 | func (l SourceLocation) InstantiationLocation() (file File, line, column, offset uint) { 147 | 148 | cline := C.uint(0) 149 | ccol := C.uint(0) 150 | coff := C.uint(0) 151 | C.clang_getInstantiationLocation(l.c, 152 | &file.c, 153 | &cline, 154 | &ccol, 155 | &coff) 156 | line = uint(cline) 157 | column = uint(ccol) 158 | offset = uint(coff) 159 | return 160 | } 161 | 162 | /** 163 | * \brief Retrieve the file, line, column, and offset represented by 164 | * the given source location. 165 | * 166 | * If the location refers into a macro instantiation, return where the 167 | * location was originally spelled in the source file. 168 | * 169 | * \param location the location within a source file that will be decomposed 170 | * into its parts. 171 | * 172 | * \param file [out] if non-NULL, will be set to the file to which the given 173 | * source location points. 174 | * 175 | * \param line [out] if non-NULL, will be set to the line to which the given 176 | * source location points. 177 | * 178 | * \param column [out] if non-NULL, will be set to the column to which the given 179 | * source location points. 180 | * 181 | * \param offset [out] if non-NULL, will be set to the offset into the 182 | * buffer to which the given source location points. 183 | */ 184 | func (l SourceLocation) SpellingLocation() (file File, line, column, offset uint) { 185 | 186 | cline := C.uint(0) 187 | ccol := C.uint(0) 188 | coff := C.uint(0) 189 | C.clang_getSpellingLocation(l.c, 190 | &file.c, 191 | &cline, 192 | &ccol, 193 | &coff) 194 | line = uint(cline) 195 | column = uint(ccol) 196 | offset = uint(coff) 197 | return 198 | } 199 | 200 | /** 201 | * \brief Retrieve the file, line, column, and offset represented by 202 | * the given source location. 203 | * 204 | * If the location refers into a macro expansion, return where the macro was 205 | * expanded or where the macro argument was written, if the location points at 206 | * a macro argument. 207 | * 208 | * \param location the location within a source file that will be decomposed 209 | * into its parts. 210 | * 211 | * \param file [out] if non-NULL, will be set to the file to which the given 212 | * source location points. 213 | * 214 | * \param line [out] if non-NULL, will be set to the line to which the given 215 | * source location points. 216 | * 217 | * \param column [out] if non-NULL, will be set to the column to which the given 218 | * source location points. 219 | * 220 | * \param offset [out] if non-NULL, will be set to the offset into the 221 | * buffer to which the given source location points. 222 | */ 223 | func (loc SourceLocation) GetFileLocation() (f File, line, column, offset uint) { 224 | cline := C.uint(0) 225 | ccol := C.uint(0) 226 | coff := C.uint(0) 227 | C.clang_getFileLocation(loc.c, 228 | &f.c, 229 | &cline, 230 | &ccol, 231 | &coff) 232 | line = uint(cline) 233 | column = uint(ccol) 234 | offset = uint(coff) 235 | return 236 | 237 | } 238 | -------------------------------------------------------------------------------- /sourcerange.go: -------------------------------------------------------------------------------- 1 | package clang 2 | 3 | // #include 4 | // #include "go-clang.h" 5 | import "C" 6 | 7 | // SourceRange identifies a half-open character range in the source code. 8 | // 9 | // Use clang_getRangeStart() and clang_getRangeEnd() to retrieve the 10 | // starting and end locations from a source range, respectively. 11 | type SourceRange struct { 12 | c C.CXSourceRange 13 | } 14 | 15 | // NewNullRange creates a NULL (invalid) source range. 16 | func NewNullRange() SourceRange { 17 | return SourceRange{C.clang_getNullRange()} 18 | } 19 | 20 | // NewRange creates a source range given the beginning and ending source 21 | // locations. 22 | func NewRange(beg, end SourceLocation) SourceRange { 23 | o := C.clang_getRange(beg.c, end.c) 24 | return SourceRange{o} 25 | } 26 | 27 | // EqualRanges determines whether two ranges are equivalent. 28 | func EqualRanges(r1, r2 SourceRange) bool { 29 | o := C.clang_equalRanges(r1.c, r2.c) 30 | if o != C.uint(0) { 31 | return true 32 | } 33 | return false 34 | } 35 | 36 | // IsNull checks if the underlying source range is null. 37 | func (r SourceRange) IsNull() bool { 38 | o := C.clang_Range_isNull(r.c) 39 | if o != C.int(0) { 40 | return true 41 | } 42 | return false 43 | } 44 | 45 | /** 46 | * \brief Retrieve a source location representing the first character within a 47 | * source range. 48 | */ 49 | func (s SourceRange) Start() SourceLocation { 50 | o := C.clang_getRangeStart(s.c) 51 | return SourceLocation{o} 52 | } 53 | 54 | /** 55 | * \brief Retrieve a source location representing the last character within a 56 | * source range. 57 | */ 58 | func (s SourceRange) End() SourceLocation { 59 | o := C.clang_getRangeEnd(s.c) 60 | return SourceLocation{o} 61 | } 62 | -------------------------------------------------------------------------------- /testdata/compile_commands.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "directory": "/home/user/llvm/build", 4 | "command": "/usr/bin/clang++ -Irelative -DSOMEDEF=\"With spaces, quotes and \\-es.\" -c -o file.o file.cc", 5 | "file": "file.cc", 6 | }, 7 | { 8 | "directory": "@TESTDIR@", 9 | "command": "g++ -c -DMYMACRO=a subdir/a.cpp", 10 | "file": "@TESTDIR@/subdir/a.cpp", 11 | }, 12 | ] 13 | -------------------------------------------------------------------------------- /testdata/hello.c: -------------------------------------------------------------------------------- 1 | #include 2 | int main(int argc, char **argv) { 3 | printf("hello\n"); 4 | } 5 | -------------------------------------------------------------------------------- /testdata/struct.c: -------------------------------------------------------------------------------- 1 | struct Foo { 2 | int a; 3 | float b; 4 | }; 5 | 6 | int add(int a, int b); 7 | int add(int a, int b) { 8 | return a+b; 9 | } 10 | -------------------------------------------------------------------------------- /token.go: -------------------------------------------------------------------------------- 1 | package clang 2 | 3 | // #include 4 | // #include "go-clang.h" 5 | import "C" 6 | 7 | import ( 8 | "fmt" 9 | ) 10 | 11 | // TokenKind describes a kind of token 12 | type TokenKind uint32 13 | 14 | const ( 15 | /** 16 | * \brief A token that contains some kind of punctuation. 17 | */ 18 | TK_Punctuation = C.CXToken_Punctuation 19 | 20 | /** 21 | * \brief A language keyword. 22 | */ 23 | TK_Keyword = C.CXToken_Keyword 24 | 25 | /** 26 | * \brief An identifier (that is not a keyword). 27 | */ 28 | TK_Identifier = C.CXToken_Identifier 29 | 30 | /** 31 | * \brief A numeric, string, or character literal. 32 | */ 33 | TK_Literal = C.CXToken_Literal 34 | 35 | /** 36 | * \brief A comment. 37 | */ 38 | TK_Comment = C.CXToken_Comment 39 | ) 40 | 41 | func (tk TokenKind) String() string { 42 | switch tk { 43 | case TK_Punctuation: 44 | return "Punctuation" 45 | case TK_Keyword: 46 | return "Keyword" 47 | case TK_Identifier: 48 | return "Identifier" 49 | case TK_Literal: 50 | return "Literal" 51 | case TK_Comment: 52 | return "Comment" 53 | default: 54 | panic(fmt.Errorf("clang: invalid TokenKind value (%d)", uint32(tk))) 55 | } 56 | } 57 | 58 | // Token is a single preprocessing token. 59 | type Token struct { 60 | c C.CXToken 61 | } 62 | 63 | // Kind determines the kind of this token 64 | func (t Token) Kind() TokenKind { 65 | o := C.clang_getTokenKind(t.c) 66 | return TokenKind(o) 67 | } 68 | 69 | /** 70 | * \brief Determine the spelling of the given token. 71 | * 72 | * The spelling of a token is the textual representation of that token, e.g., 73 | * the text of an identifier or keyword. 74 | */ 75 | func (tu TranslationUnit) TokenSpelling(tok Token) string { 76 | cstr := cxstring{C.clang_getTokenSpelling(tu.c, tok.c)} 77 | defer cstr.Dispose() 78 | return cstr.String() 79 | } 80 | 81 | /** 82 | * \brief Retrieve the source location of the given token. 83 | */ 84 | func (tu TranslationUnit) TokenLocation(tok Token) SourceLocation { 85 | o := C.clang_getTokenLocation(tu.c, tok.c) 86 | return SourceLocation{o} 87 | } 88 | 89 | /** 90 | * \brief Retrieve a source range that covers the given token. 91 | */ 92 | func (tu TranslationUnit) TokenExtent(tok Token) SourceRange { 93 | o := C.clang_getTokenExtent(tu.c, tok.c) 94 | return SourceRange{o} 95 | } 96 | 97 | /** 98 | * \brief Tokenize the source code described by the given range into raw 99 | * lexical tokens. 100 | * 101 | * \param TU the translation unit whose text is being tokenized. 102 | * 103 | * \param Range the source range in which text should be tokenized. All of the 104 | * tokens produced by tokenization will fall within this source range, 105 | * 106 | * \param Tokens this pointer will be set to point to the array of tokens 107 | * that occur within the given source range. The returned pointer must be 108 | * freed with clang_disposeTokens() before the translation unit is destroyed. 109 | * 110 | * \param NumTokens will be set to the number of tokens in the \c *Tokens 111 | * array. 112 | * 113 | */ 114 | func Tokenize(tu TranslationUnit, src SourceRange) Tokens { 115 | tokens := Tokens{} 116 | tokens.tu = tu.c 117 | C.clang_tokenize(tu.c, src.c, &tokens.c, &tokens.n) 118 | return tokens 119 | } 120 | 121 | // an array of tokens 122 | type Tokens struct { 123 | tu C.CXTranslationUnit 124 | c *C.CXToken 125 | n C.uint 126 | } 127 | 128 | /** 129 | * \brief Annotate the given set of tokens by providing cursors for each token 130 | * that can be mapped to a specific entity within the abstract syntax tree. 131 | * 132 | * This token-annotation routine is equivalent to invoking 133 | * clang_getCursor() for the source locations of each of the 134 | * tokens. The cursors provided are filtered, so that only those 135 | * cursors that have a direct correspondence to the token are 136 | * accepted. For example, given a function call \c f(x), 137 | * clang_getCursor() would provide the following cursors: 138 | * 139 | * * when the cursor is over the 'f', a DeclRefExpr cursor referring to 'f'. 140 | * * when the cursor is over the '(' or the ')', a CallExpr referring to 'f'. 141 | * * when the cursor is over the 'x', a DeclRefExpr cursor referring to 'x'. 142 | * 143 | * Only the first and last of these cursors will occur within the 144 | * annotate, since the tokens "f" and "x' directly refer to a function 145 | * and a variable, respectively, but the parentheses are just a small 146 | * part of the full syntax of the function call expression, which is 147 | * not provided as an annotation. 148 | * 149 | * \param TU the translation unit that owns the given tokens. 150 | * 151 | * \param Tokens the set of tokens to annotate. 152 | * 153 | * \param NumTokens the number of tokens in \p Tokens. 154 | * 155 | * \param Cursors an array of \p NumTokens cursors, whose contents will be 156 | * replaced with the cursors corresponding to each token. 157 | */ 158 | func (t Tokens) Annotate() []Cursor { 159 | cursors := make([]Cursor, int(t.n)) 160 | if t.n <= 0 { 161 | return cursors 162 | } 163 | c_cursors := make([]C.CXCursor, int(t.n)) 164 | C.clang_annotateTokens(t.tu, t.c, t.n, &c_cursors[0]) 165 | for i, _ := range cursors { 166 | cursors[i] = Cursor{C._go_clang_ocursor_at(&c_cursors[0], C.int(i))} 167 | } 168 | return cursors 169 | } 170 | 171 | /** 172 | * \brief Free the given set of tokens. 173 | */ 174 | func (t Tokens) Dispose() { 175 | C.clang_disposeTokens(t.tu, t.c, t.n) 176 | } 177 | 178 | // EOF 179 | -------------------------------------------------------------------------------- /translationunit.go: -------------------------------------------------------------------------------- 1 | package clang 2 | 3 | // #include 4 | // #include "go-clang.h" 5 | import "C" 6 | import ( 7 | "unsafe" 8 | ) 9 | 10 | // A single translation unit, which resides in an index 11 | type TranslationUnit struct { 12 | c C.CXTranslationUnit 13 | } 14 | 15 | /** 16 | * \brief Perform code completion at a given location in a translation unit. 17 | * 18 | * This function performs code completion at a particular file, line, and 19 | * column within source code, providing results that suggest potential 20 | * code snippets based on the context of the completion. The basic model 21 | * for code completion is that Clang will parse a complete source file, 22 | * performing syntax checking up to the location where code-completion has 23 | * been requested. At that point, a special code-completion token is passed 24 | * to the parser, which recognizes this token and determines, based on the 25 | * current location in the C/Objective-C/C++ grammar and the state of 26 | * semantic analysis, what completions to provide. These completions are 27 | * returned via a new \c CXCodeCompleteResults structure. 28 | * 29 | * Code completion itself is meant to be triggered by the client when the 30 | * user types punctuation characters or whitespace, at which point the 31 | * code-completion location will coincide with the cursor. For example, if \c p 32 | * is a pointer, code-completion might be triggered after the "-" and then 33 | * after the ">" in \c p->. When the code-completion location is afer the ">", 34 | * the completion results will provide, e.g., the members of the struct that 35 | * "p" points to. The client is responsible for placing the cursor at the 36 | * beginning of the token currently being typed, then filtering the results 37 | * based on the contents of the token. For example, when code-completing for 38 | * the expression \c p->get, the client should provide the location just after 39 | * the ">" (e.g., pointing at the "g") to this code-completion hook. Then, the 40 | * client can filter the results based on the current token text ("get"), only 41 | * showing those results that start with "get". The intent of this interface 42 | * is to separate the relatively high-latency acquisition of code-completion 43 | * results from the filtering of results on a per-character basis, which must 44 | * have a lower latency. 45 | * 46 | * \param TU The translation unit in which code-completion should 47 | * occur. The source files for this translation unit need not be 48 | * completely up-to-date (and the contents of those source files may 49 | * be overridden via \p unsaved_files). Cursors referring into the 50 | * translation unit may be invalidated by this invocation. 51 | * 52 | * \param complete_filename The name of the source file where code 53 | * completion should be performed. This filename may be any file 54 | * included in the translation unit. 55 | * 56 | * \param complete_line The line at which code-completion should occur. 57 | * 58 | * \param complete_column The column at which code-completion should occur. 59 | * Note that the column should point just after the syntactic construct that 60 | * initiated code completion, and not in the middle of a lexical token. 61 | * 62 | * \param unsaved_files the Tiles that have not yet been saved to disk 63 | * but may be required for parsing or code completion, including the 64 | * contents of those files. The contents and name of these files (as 65 | * specified by CXUnsavedFile) are copied when necessary, so the 66 | * client only needs to guarantee their validity until the call to 67 | * this function returns. 68 | * 69 | * \param num_unsaved_files The number of unsaved file entries in \p 70 | * unsaved_files. 71 | * 72 | * \param options Extra options that control the behavior of code 73 | * completion, expressed as a bitwise OR of the enumerators of the 74 | * CXCodeComplete_Flags enumeration. The 75 | * \c clang_defaultCodeCompleteOptions() function returns a default set 76 | * of code-completion options. 77 | * 78 | * \returns If successful, a new \c CXCodeCompleteResults structure 79 | * containing code-completion results, which should eventually be 80 | * freed with \c clang_disposeCodeCompleteResults(). If code 81 | * completion fails, returns NULL. 82 | */ 83 | func (tu TranslationUnit) CompleteAt(complete_filename string, complete_line, complete_column int, us UnsavedFiles, options CodeCompleteFlags) CodeCompleteResults { 84 | cfname := C.CString(complete_filename) 85 | defer C.free(unsafe.Pointer(cfname)) 86 | c_us := us.to_c() 87 | defer c_us.Dispose() 88 | cr := C.clang_codeCompleteAt(tu.c, cfname, C.uint(complete_line), C.uint(complete_column), c_us.ptr(), C.uint(len(c_us)), C.uint(options)) 89 | return CodeCompleteResults{cr} 90 | } 91 | 92 | func (tu TranslationUnit) IsValid() bool { 93 | return tu.c != nil 94 | } 95 | 96 | func (tu TranslationUnit) File(file_name string) File { 97 | cfname := C.CString(file_name) 98 | defer C.free(unsafe.Pointer(cfname)) 99 | f := C.clang_getFile(tu.c, cfname) 100 | return File{f} 101 | } 102 | 103 | // IsFileMultipleIncludeGuarded determines whether the given header is guarded 104 | // against multiple inclusions, either with the conventional 105 | // #ifndef/#define/#endif macro guards or with #pragma once. 106 | func (tu TranslationUnit) IsFileMultipleIncludeGuarded(file File) bool { 107 | o := C.clang_isFileMultipleIncludeGuarded(tu.c, file.c) 108 | if o != C.uint(0) { 109 | return true 110 | } 111 | return false 112 | } 113 | 114 | /** 115 | * \brief Retrieve the cursor that represents the given translation unit. 116 | * 117 | * The translation unit cursor can be used to start traversing the 118 | * various declarations within the given translation unit. 119 | */ 120 | func (tu TranslationUnit) ToCursor() Cursor { 121 | o := C.clang_getTranslationUnitCursor(tu.c) 122 | return Cursor{o} 123 | } 124 | 125 | /** 126 | * \brief Get the original translation unit source file name. 127 | */ 128 | func (tu TranslationUnit) Spelling() string { 129 | cstr := cxstring{C.clang_getTranslationUnitSpelling(tu.c)} 130 | defer cstr.Dispose() 131 | return cstr.String() 132 | } 133 | 134 | // CursorOf maps a source location to the cursor that describes the entity at that 135 | // location in the source code. 136 | // 137 | // clang_getCursor() maps an arbitrary source location within a translation 138 | // unit down to the most specific cursor that describes the entity at that 139 | // location. For example, given an expression \c x + y, invoking 140 | // clang_getCursor() with a source location pointing to "x" will return the 141 | // cursor for "x"; similarly for "y". If the cursor points anywhere between 142 | // "x" or "y" (e.g., on the + or the whitespace around it), clang_getCursor() 143 | // will return a cursor referring to the "+" expression. 144 | // 145 | // Returns a cursor representing the entity at the given source location, or 146 | // a NULL cursor if no such entity can be found. 147 | func (tu TranslationUnit) Cursor(loc SourceLocation) Cursor { 148 | o := C.clang_getCursor(tu.c, loc.c) 149 | return Cursor{o} 150 | } 151 | 152 | /** 153 | * \brief Reparse the source files that produced this translation unit. 154 | * 155 | * This routine can be used to re-parse the source files that originally 156 | * created the given translation unit, for example because those source files 157 | * have changed (either on disk or as passed via \p unsaved_files). The 158 | * source code will be reparsed with the same command-line options as it 159 | * was originally parsed. 160 | * 161 | * Reparsing a translation unit invalidates all cursors and source locations 162 | * that refer into that translation unit. This makes reparsing a translation 163 | * unit semantically equivalent to destroying the translation unit and then 164 | * creating a new translation unit with the same command-line arguments. 165 | * However, it may be more efficient to reparse a translation 166 | * unit using this routine. 167 | * 168 | * \param TU The translation unit whose contents will be re-parsed. The 169 | * translation unit must originally have been built with 170 | * \c clang_createTranslationUnitFromSourceFile(). 171 | * 172 | * \param num_unsaved_files The number of unsaved file entries in \p 173 | * unsaved_files. 174 | * 175 | * \param unsaved_files The files that have not yet been saved to disk 176 | * but may be required for parsing, including the contents of 177 | * those files. The contents and name of these files (as specified by 178 | * CXUnsavedFile) are copied when necessary, so the client only needs to 179 | * guarantee their validity until the call to this function returns. 180 | * 181 | * \param options A bitset of options composed of the flags in CXReparse_Flags. 182 | * The function \c clang_defaultReparseOptions() produces a default set of 183 | * options recommended for most uses, based on the translation unit. 184 | * 185 | * \returns 0 if the sources could be reparsed. A non-zero value will be 186 | * returned if reparsing was impossible, such that the translation unit is 187 | * invalid. In such cases, the only valid call for \p TU is 188 | * \c clang_disposeTranslationUnit(TU). 189 | */ 190 | func (tu TranslationUnit) Reparse(us UnsavedFiles, options TranslationUnitFlags) int { 191 | c_us := us.to_c() 192 | defer c_us.Dispose() 193 | return int(C.clang_reparseTranslationUnit(tu.c, C.uint(len(c_us)), c_us.ptr(), C.uint(options))) 194 | } 195 | 196 | /** 197 | * \brief Saves a translation unit into a serialized representation of 198 | * that translation unit on disk. 199 | * 200 | * Any translation unit that was parsed without error can be saved 201 | * into a file. The translation unit can then be deserialized into a 202 | * new \c CXTranslationUnit with \c clang_createTranslationUnit() or, 203 | * if it is an incomplete translation unit that corresponds to a 204 | * header, used as a precompiled header when parsing other translation 205 | * units. 206 | * 207 | * \param TU The translation unit to save. 208 | * 209 | * \param FileName The file to which the translation unit will be saved. 210 | * 211 | * \param options A bitmask of options that affects how the translation unit 212 | * is saved. This should be a bitwise OR of the 213 | * CXSaveTranslationUnit_XXX flags. 214 | * 215 | * \returns A value that will match one of the enumerators of the CXSaveError 216 | * enumeration. Zero (CXSaveError_None) indicates that the translation unit was 217 | * saved successfully, while a non-zero value indicates that a problem occurred. 218 | */ 219 | func (tu TranslationUnit) Save(fname string, options uint) uint32 { 220 | cstr := C.CString(fname) 221 | defer C.free(unsafe.Pointer(cstr)) 222 | o := C.clang_saveTranslationUnit(tu.c, cstr, C.uint(options)) 223 | // FIXME: should be a SaveError type... 224 | return uint32(o) 225 | } 226 | 227 | /** 228 | * \brief Retrieve a diagnostic associated with the given translation unit. 229 | * 230 | * \param Unit the translation unit to query. 231 | * \param Index the zero-based diagnostic number to retrieve. 232 | * 233 | * \returns the requested diagnostic. This diagnostic must be freed 234 | * via a call to \c clang_disposeDiagnostic(). 235 | */ 236 | func (tu TranslationUnit) Diagnostics() (ret Diagnostics) { 237 | ret = make(Diagnostics, C.clang_getNumDiagnostics(tu.c)) 238 | for i := range ret { 239 | ret[i].c = C.clang_getDiagnostic(tu.c, C.uint(i)) 240 | } 241 | return 242 | } 243 | 244 | /** 245 | * \brief Destroy the specified CXTranslationUnit object. 246 | */ 247 | func (tu TranslationUnit) Dispose() { 248 | C.clang_disposeTranslationUnit(tu.c) 249 | } 250 | 251 | // Location returns the source location associated with a given file/line/column 252 | // in a particular translation unit. 253 | func (tu TranslationUnit) Location(f File, line, column uint) SourceLocation { 254 | loc := C.clang_getLocation(tu.c, f.c, C.uint(line), C.uint(column)) 255 | return SourceLocation{loc} 256 | } 257 | 258 | // LocationForOffset returns the source location associated with a given 259 | // character offset in a particular translation unit. 260 | func (tu TranslationUnit) LocationForOffset(f File, offset uint) SourceLocation { 261 | loc := C.clang_getLocationForOffset(tu.c, f.c, C.uint(offset)) 262 | return SourceLocation{loc} 263 | } 264 | 265 | /** 266 | * \param Module a module object. 267 | * 268 | * \returns the number of top level headers associated with this module. 269 | */ 270 | func (tu TranslationUnit) NumTopLevelHeaders(m Module) int { 271 | return int(C.clang_Module_getNumTopLevelHeaders(tu.c, m.c)) 272 | } 273 | 274 | /** 275 | * \param Module a module object. 276 | * 277 | * \param Index top level header index (zero-based). 278 | * 279 | * \returns the specified top level header associated with the module. 280 | */ 281 | func (tu TranslationUnit) TopLevelHeader(m Module, i int) File { 282 | return File{C.clang_Module_getTopLevelHeader(tu.c, m.c, C.unsigned(i))} 283 | } 284 | 285 | // TODO 286 | // 287 | // /** 288 | // * \brief Find #import/#include directives in a specific file. 289 | // * 290 | // * \param TU translation unit containing the file to query. 291 | // * 292 | // * \param file to search for #import/#include directives. 293 | // * 294 | // * \param visitor callback that will receive pairs of CXCursor/CXSourceRange for 295 | // * each directive found. 296 | // * 297 | // * \returns one of the CXResult enumerators. 298 | // */ 299 | // CINDEX_LINKAGE CXResult clang_findIncludesInFile(CXTranslationUnit TU, 300 | // CXFile file, 301 | // CXCursorAndRangeVisitor visitor); 302 | 303 | // TODO 304 | // 305 | // CINDEX_LINKAGE 306 | // CXResult clang_findIncludesInFileWithBlock(CXTranslationUnit, CXFile, 307 | // CXCursorAndRangeVisitorBlock); 308 | -------------------------------------------------------------------------------- /translationunitflags.go: -------------------------------------------------------------------------------- 1 | package clang 2 | 3 | // #include 4 | // #include "go-clang.h" 5 | import "C" 6 | 7 | /** 8 | * \brief Flags that control the creation of translation units. 9 | * 10 | * The enumerators in this enumeration type are meant to be bitwise 11 | * ORed together to specify which options should be used when 12 | * constructing the translation unit. 13 | */ 14 | type TranslationUnitFlags uint32 15 | 16 | const ( 17 | /** 18 | * \brief Used to indicate that no special translation-unit options are 19 | * needed. 20 | */ 21 | TU_None = C.CXTranslationUnit_None 22 | 23 | /** 24 | * \brief Used to indicate that the parser should construct a "detailed" 25 | * preprocessing record, including all macro definitions and instantiations. 26 | * 27 | * Constructing a detailed preprocessing record requires more memory 28 | * and time to parse, since the information contained in the record 29 | * is usually not retained. However, it can be useful for 30 | * applications that require more detailed information about the 31 | * behavior of the preprocessor. 32 | */ 33 | TU_DetailedPreprocessingRecord = C.CXTranslationUnit_DetailedPreprocessingRecord 34 | 35 | /** 36 | * \brief Used to indicate that the translation unit is incomplete. 37 | * 38 | * When a translation unit is considered "incomplete", semantic 39 | * analysis that is typically performed at the end of the 40 | * translation unit will be suppressed. For example, this suppresses 41 | * the completion of tentative declarations in C and of 42 | * instantiation of implicitly-instantiation function templates in 43 | * C++. This option is typically used when parsing a header with the 44 | * intent of producing a precompiled header. 45 | */ 46 | TU_Incomplete = C.CXTranslationUnit_Incomplete 47 | 48 | /** 49 | * \brief Used to indicate that the translation unit should be built with an 50 | * implicit precompiled header for the preamble. 51 | * 52 | * An implicit precompiled header is used as an optimization when a 53 | * particular translation unit is likely to be reparsed many times 54 | * when the sources aren't changing that often. In this case, an 55 | * implicit precompiled header will be built containing all of the 56 | * initial includes at the top of the main file (what we refer to as 57 | * the "preamble" of the file). In subsequent parses, if the 58 | * preamble or the files in it have not changed, \c 59 | * clang_reparseTranslationUnit() will re-use the implicit 60 | * precompiled header to improve parsing performance. 61 | */ 62 | TU_PrecompiledPreamble = C.CXTranslationUnit_PrecompiledPreamble 63 | 64 | /** 65 | * \brief Used to indicate that the translation unit should cache some 66 | * code-completion results with each reparse of the source file. 67 | * 68 | * Caching of code-completion results is a performance optimization that 69 | * introduces some overhead to reparsing but improves the performance of 70 | * code-completion operations. 71 | */ 72 | TU_CacheCompletionResults = C.CXTranslationUnit_CacheCompletionResults 73 | 74 | /** 75 | * \brief Used to indicate that the translation unit will be serialized with 76 | * \c clang_saveTranslationUnit. 77 | * 78 | * This option is typically used when parsing a header with the intent of 79 | * producing a precompiled header. 80 | */ 81 | TU_ForSerialization = C.CXTranslationUnit_ForSerialization 82 | 83 | /** 84 | * \brief DEPRECATED: Enabled chained precompiled preambles in C++. 85 | * 86 | * Note: this is a *temporary* option that is available only while 87 | * we are testing C++ precompiled preamble support. It is deprecated. 88 | */ 89 | TU_CXXChainedPCH = C.CXTranslationUnit_CXXChainedPCH 90 | 91 | /** 92 | * \brief Used to indicate that function/method bodies should be skipped while 93 | * parsing. 94 | * 95 | * This option can be used to search for declarations/definitions while 96 | * ignoring the usages. 97 | */ 98 | TU_SkipFunctionBodies = C.CXTranslationUnit_SkipFunctionBodies 99 | 100 | /** 101 | * \brief Used to indicate that brief documentation comments should be 102 | * included into the set of code completions returned from this translation 103 | * unit. 104 | */ 105 | TU_IncludeBriefCommentsInCodeCompletion = C.CXTranslationUnit_IncludeBriefCommentsInCodeCompletion 106 | ) 107 | -------------------------------------------------------------------------------- /type.go: -------------------------------------------------------------------------------- 1 | package clang 2 | 3 | // #include 4 | // #include "go-clang.h" 5 | import "C" 6 | 7 | import ( 8 | "unsafe" 9 | ) 10 | 11 | // Type represents the type of an element in the abstract syntax tree. 12 | type Type struct { 13 | c C.CXType 14 | } 15 | 16 | func (c Type) Kind() TypeKind { 17 | return TypeKind(c.c.kind) 18 | } 19 | 20 | // EqualTypes determines whether two Types represent the same type. 21 | func EqualTypes(t1, t2 Type) bool { 22 | o := C.clang_equalTypes(t1.c, t2.c) 23 | if o != C.uint(0) { 24 | return true 25 | } 26 | return false 27 | } 28 | 29 | /** 30 | * \brief Pretty-print the underlying type using the rules of the 31 | * language of the translation unit from which it came. 32 | * 33 | * If the type is invalid, an empty string is returned. 34 | */ 35 | func (t Type) TypeSpelling() string { 36 | o := cxstring{C.clang_getTypeSpelling(t.c)} 37 | defer o.Dispose() 38 | return o.String() 39 | } 40 | 41 | // CanonicalType returns the canonical type for a Type. 42 | // 43 | // Clang's type system explicitly models typedefs and all the ways 44 | // a specific type can be represented. The canonical type is the underlying 45 | // type with all the "sugar" removed. For example, if 'T' is a typedef 46 | // for 'int', the canonical type for 'T' would be 'int'. 47 | func (t Type) CanonicalType() Type { 48 | o := C.clang_getCanonicalType(t.c) 49 | return Type{o} 50 | } 51 | 52 | // IsConstQualified determines whether a Type has the "const" qualifier set, 53 | // without looking through typedefs that may have added "const" at a 54 | // different level. 55 | func (t Type) IsConstQualified() bool { 56 | o := C.clang_isConstQualifiedType(t.c) 57 | if o != C.uint(0) { 58 | return true 59 | } 60 | return false 61 | } 62 | 63 | // IsVolatileQualified determines whether a Type has the "volatile" qualifier 64 | // set, without looking through typedefs that may have added "volatile" at a 65 | // different level. 66 | func (t Type) IsVolatileQualified() bool { 67 | o := C.clang_isVolatileQualifiedType(t.c) 68 | if o != C.uint(0) { 69 | return true 70 | } 71 | return false 72 | } 73 | 74 | // IsRestrictQualified determines whether a Type has the "restrict" qualifier 75 | // set, without looking through typedefs that may have added "restrict" at a 76 | // different level. 77 | func (t Type) IsRestrictQualified() bool { 78 | o := C.clang_isRestrictQualifiedType(t.c) 79 | if o != C.uint(0) { 80 | return true 81 | } 82 | return false 83 | } 84 | 85 | // PointeeType (for pointer types), returns the type of the pointee. 86 | func (t Type) PointeeType() Type { 87 | o := C.clang_getPointeeType(t.c) 88 | return Type{o} 89 | } 90 | 91 | // Declaration returns the cursor for the declaration of the given type. 92 | func (t Type) Declaration() Cursor { 93 | o := C.clang_getTypeDeclaration(t.c) 94 | return Cursor{o} 95 | } 96 | 97 | /** 98 | * \brief Retrieve the result type associated with a function type. 99 | */ 100 | func (t Type) ResultType() Type { 101 | o := C.clang_getResultType(t.c) 102 | return Type{o} 103 | } 104 | 105 | /** 106 | * \brief Return 1 if the CXType is a POD (plain old data) type, and 0 107 | * otherwise. 108 | */ 109 | func (t Type) IsPOD() bool { 110 | o := C.clang_isPODType(t.c) 111 | if o != C.uint(0) { 112 | return true 113 | } 114 | return false 115 | } 116 | 117 | /** 118 | * \brief Return the element type of an array type. 119 | * 120 | * If a non-array type is passed in, an invalid type is returned. 121 | */ 122 | func (t Type) ArrayElementType() Type { 123 | o := C.clang_getArrayElementType(t.c) 124 | return Type{o} 125 | } 126 | 127 | /** 128 | * \brief Return the the array size of a constant array. 129 | * 130 | * If a non-array type is passed in, -1 is returned. 131 | */ 132 | func (t Type) ArraySize() int64 { 133 | o := C.clang_getArraySize(t.c) 134 | return int64(o) 135 | } 136 | 137 | /** 138 | * \brief Return the alignment of a type in bytes as per C++[expr.alignof] 139 | * standard. 140 | * 141 | * If the type declaration is invalid, CXTypeLayoutError_Invalid is returned. 142 | * If the type declaration is an incomplete type, CXTypeLayoutError_Incomplete 143 | * is returned. 144 | * If the type declaration is a dependent type, CXTypeLayoutError_Dependent is 145 | * returned. 146 | * If the type declaration is not a constant size type, 147 | * CXTypeLayoutError_NotConstantSize is returned. 148 | */ 149 | func (t Type) AlignOf() (int, error) { 150 | o := C.clang_Type_getAlignOf(t.c) 151 | if o < 0 { 152 | return int(o), TypeLayoutError(o) 153 | } 154 | return int(o), nil 155 | } 156 | 157 | /** 158 | * \brief Return the class type of an member pointer type. 159 | * 160 | * If a non-member-pointer type is passed in, an invalid type is returned. 161 | */ 162 | func (t Type) ClassType() Type { 163 | return Type{C.clang_Type_getClassType(t.c)} 164 | } 165 | 166 | /** 167 | * \brief Return the size of a type in bytes as per C++[expr.sizeof] standard. 168 | * 169 | * If the type declaration is invalid, CXTypeLayoutError_Invalid is returned. 170 | * If the type declaration is an incomplete type, CXTypeLayoutError_Incomplete 171 | * is returned. 172 | * If the type declaration is a dependent type, CXTypeLayoutError_Dependent is 173 | * returned. 174 | */ 175 | func (t Type) SizeOf() (int, error) { 176 | o := C.clang_Type_getSizeOf(t.c) 177 | if o < 0 { 178 | return int(o), TypeLayoutError(o) 179 | } 180 | return int(o), nil 181 | } 182 | 183 | /** 184 | * \brief Return the offset of a field named S in a record of type T in bits 185 | * as it would be returned by __offsetof__ as per C++11[18.2p4] 186 | * 187 | * If the cursor is not a record field declaration, CXTypeLayoutError_Invalid 188 | * is returned. 189 | * If the field's type declaration is an incomplete type, 190 | * CXTypeLayoutError_Incomplete is returned. 191 | * If the field's type declaration is a dependent type, 192 | * CXTypeLayoutError_Dependent is returned. 193 | * If the field's name S is not found, 194 | * CXTypeLayoutError_InvalidFieldName is returned. 195 | */ 196 | func (t Type) OffsetOf(s string) (int, error) { 197 | c_str := C.CString(s) 198 | defer C.free(unsafe.Pointer(c_str)) 199 | o := C.clang_Type_getOffsetOf(t.c, c_str) 200 | if o < 0 { 201 | return int(o), TypeLayoutError(o) 202 | } 203 | return int(o), nil 204 | } 205 | 206 | /** 207 | * \brief Retrieve the ref-qualifier kind of a function or method. 208 | * 209 | * The ref-qualifier is returned for C++ functions or methods. For other types 210 | * or non-C++ declarations, CXRefQualifier_None is returned. 211 | */ 212 | func (t Type) CXXRefQualifier() RefQualifierKind { 213 | return RefQualifierKind(C.clang_Type_getCXXRefQualifier(t.c)) 214 | } 215 | 216 | // EOF 217 | -------------------------------------------------------------------------------- /typekind.go: -------------------------------------------------------------------------------- 1 | package clang 2 | 3 | // #include 4 | // #include "go-clang.h" 5 | // 6 | import "C" 7 | 8 | // TypeKind describes the kind of a type 9 | type TypeKind uint32 10 | 11 | const ( 12 | // Represents an invalid type (e.g., where no type is available). 13 | TK_Invalid TypeKind = C.CXType_Invalid 14 | 15 | // A type whose specific kind is not exposed via this interface. 16 | TK_Unexposed = C.CXType_Unexposed 17 | 18 | TK_Void = C.CXType_Void 19 | TK_Bool = C.CXType_Bool 20 | TK_Char_U = C.CXType_Char_U 21 | TK_UChar = C.CXType_UChar 22 | TK_Char16 = C.CXType_Char16 23 | TK_Char32 = C.CXType_Char32 24 | TK_UShort = C.CXType_UShort 25 | TK_UInt = C.CXType_UInt 26 | TK_ULong = C.CXType_ULong 27 | TK_ULongLong = C.CXType_ULongLong 28 | TK_UInt128 = C.CXType_UInt128 29 | TK_Char_S = C.CXType_Char_S 30 | TK_SChar = C.CXType_SChar 31 | TK_WChar = C.CXType_WChar 32 | TK_Short = C.CXType_Short 33 | TK_Int = C.CXType_Int 34 | TK_Long = C.CXType_Long 35 | TK_LongLong = C.CXType_LongLong 36 | TK_Int128 = C.CXType_Int128 37 | TK_Float = C.CXType_Float 38 | TK_Double = C.CXType_Double 39 | TK_LongDouble = C.CXType_LongDouble 40 | TK_NullPtr = C.CXType_NullPtr 41 | TK_Overload = C.CXType_Overload 42 | TK_Dependent = C.CXType_Dependent 43 | TK_ObjCId = C.CXType_ObjCId 44 | TK_ObjCClass = C.CXType_ObjCClass 45 | TK_ObjCSel = C.CXType_ObjCSel 46 | 47 | TK_FirstBuiltin = C.CXType_FirstBuiltin 48 | TK_LastBuiltin = C.CXType_LastBuiltin 49 | 50 | TK_Complex = C.CXType_Complex 51 | TK_Pointer = C.CXType_Pointer 52 | TK_BlockPointer = C.CXType_BlockPointer 53 | TK_LValueReference = C.CXType_LValueReference 54 | TK_RValueReference = C.CXType_RValueReference 55 | TK_Record = C.CXType_Record 56 | TK_Enum = C.CXType_Enum 57 | TK_Typedef = C.CXType_Typedef 58 | TK_ObjCInterface = C.CXType_ObjCInterface 59 | TK_ObjCObjectPointer = C.CXType_ObjCObjectPointer 60 | TK_FunctionNoProto = C.CXType_FunctionNoProto 61 | TK_FunctionProto = C.CXType_FunctionProto 62 | TK_ConstantArray = C.CXType_ConstantArray 63 | TK_Vector = C.CXType_Vector 64 | TK_IncompleteArray = C.CXType_IncompleteArray 65 | TK_VariableArray = C.CXType_VariableArray 66 | TK_DependentSizedArray = C.CXType_DependentSizedArray 67 | TK_MemberPointer = C.CXType_MemberPointer 68 | ) 69 | 70 | func (t TypeKind) to_c() uint32 { 71 | return uint32(t) 72 | } 73 | 74 | // Spelling returns the spelling of a given TypeKind. 75 | func (t TypeKind) Spelling() string { 76 | cstr := cxstring{C.clang_getTypeKindSpelling(t.to_c())} 77 | defer cstr.Dispose() 78 | return cstr.String() 79 | } 80 | -------------------------------------------------------------------------------- /typelayouterror.go: -------------------------------------------------------------------------------- 1 | package clang 2 | 3 | // #include 4 | // #include "go-clang.h" 5 | import "C" 6 | import ( 7 | "fmt" 8 | ) 9 | 10 | /** 11 | * \brief List the possible error codes for \c clang_Type_getSizeOf, 12 | * \c clang_Type_getAlignOf, \c clang_Type_getOffsetOf and 13 | * \c clang_Cursor_getOffsetOf. 14 | * 15 | * A value of this enumeration type can be returned if the target type is not 16 | * a valid argument to sizeof, alignof or offsetof. 17 | */ 18 | type TypeLayoutError int 19 | 20 | const ( 21 | /** 22 | * \brief Type is of kind CXType_Invalid. 23 | */ 24 | TLE_Invalid TypeLayoutError = C.CXTypeLayoutError_Invalid 25 | 26 | /** 27 | * \brief The type is an incomplete Type. 28 | */ 29 | TLE_Incomplete = C.CXTypeLayoutError_Incomplete 30 | 31 | /** 32 | * \brief The type is a dependent Type. 33 | */ 34 | TLE_Dependent = C.CXTypeLayoutError_Dependent 35 | 36 | /** 37 | * \brief The type is not a constant size type. 38 | */ 39 | TLE_NotConstantSize = C.CXTypeLayoutError_NotConstantSize 40 | 41 | /** 42 | * \brief The Field name is not valid for this record. 43 | */ 44 | TLE_InvalidFieldName = C.CXTypeLayoutError_InvalidFieldName 45 | ) 46 | 47 | func (tle TypeLayoutError) Error() string { 48 | switch tle { 49 | case TLE_Invalid: 50 | return "TypeLayout=Invalid" 51 | 52 | case TLE_Incomplete: 53 | return "TypeLayout=Incomplete" 54 | 55 | case TLE_Dependent: 56 | return "TypeLayout=Dependent" 57 | 58 | case TLE_NotConstantSize: 59 | return "TypeLayout=NotConstantSize" 60 | 61 | case TLE_InvalidFieldName: 62 | return "TypeLayout=InvalidFieldName" 63 | } 64 | 65 | return fmt.Sprintf("TypeLayout=unknown (%d)", int(tle)) 66 | } 67 | -------------------------------------------------------------------------------- /unsavedfiles.go: -------------------------------------------------------------------------------- 1 | package clang 2 | 3 | // #include 4 | // #include "go-clang.h" 5 | import "C" 6 | 7 | import ( 8 | "unsafe" 9 | ) 10 | 11 | type ( 12 | UnsavedFiles map[string]string 13 | cUnsavedFiles []C.struct_CXUnsavedFile 14 | ) 15 | 16 | func (us UnsavedFiles) to_c() (ret cUnsavedFiles) { 17 | ret = make(cUnsavedFiles, 0, len(us)) 18 | for filename, contents := range us { 19 | ret = append(ret, C.struct_CXUnsavedFile{Filename: C.CString(filename), Contents: C.CString(contents), Length: C.ulong(len(contents))}) 20 | } 21 | return ret 22 | } 23 | 24 | func (us cUnsavedFiles) Dispose() { 25 | for i := range us { 26 | C.free(unsafe.Pointer(us[i].Filename)) 27 | C.free(unsafe.Pointer(us[i].Contents)) 28 | } 29 | } 30 | 31 | func (us cUnsavedFiles) ptr() *C.struct_CXUnsavedFile { 32 | if len(us) > 0 { 33 | return &us[0] 34 | } 35 | return nil 36 | } 37 | -------------------------------------------------------------------------------- /unsavedfiles_test.go: -------------------------------------------------------------------------------- 1 | package clang_test 2 | 3 | import ( 4 | "testing" 5 | 6 | "github.com/sbinet/go-clang" 7 | ) 8 | 9 | func TestUnsavedFiles(t *testing.T) { 10 | us := clang.UnsavedFiles{"hello.cpp": ` 11 | #include 12 | int main(int argc, char **argv) { 13 | printf("Hello world!\n"); 14 | return 0; 15 | } 16 | `} 17 | 18 | idx := clang.NewIndex(0, 0) 19 | defer idx.Dispose() 20 | tu := idx.Parse("hello.cpp", nil, us, 0) 21 | if !tu.IsValid() { 22 | t.Fatal("TranslationUnit is not valid") 23 | } 24 | defer tu.Dispose() 25 | 26 | res := tu.CompleteAt("hello.cpp", 4, 1, us, 0) 27 | if !res.IsValid() { 28 | t.Fatal("CompleteResults are not valid") 29 | } 30 | defer res.Dispose() 31 | if n := len(res.Results()); n < 10 { 32 | t.Errorf("Expected more results than %d", n) 33 | } 34 | t.Logf("%+v", res) 35 | for _, r := range res.Results() { 36 | t.Logf("%+v", r) 37 | for _, c := range r.CompletionString.Chunks() { 38 | t.Logf("\t%+v", c) 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /version.go: -------------------------------------------------------------------------------- 1 | package clang 2 | 3 | // #include 4 | // #include "go-clang.h" 5 | // 6 | import "C" 7 | 8 | /** 9 | * \brief Describes a version number of the form major.minor.subminor. 10 | */ 11 | type Version struct { 12 | c C.CXVersion 13 | } 14 | 15 | /** 16 | * \brief The major version number, e.g., the '10' in '10.7.3'. A negative 17 | * value indicates that there is no version number at all. 18 | */ 19 | func (v Version) Major() int { 20 | return int(v.c.Major) 21 | } 22 | 23 | /** 24 | * \brief The minor version number, e.g., the '7' in '10.7.3'. This value 25 | * will be negative if no minor version number was provided, e.g., for 26 | * version '10'. 27 | */ 28 | func (v Version) Minor() int { 29 | return int(v.c.Minor) 30 | } 31 | 32 | /** 33 | * \brief The subminor version number, e.g., the '3' in '10.7.3'. This value 34 | * will be negative if no minor or subminor version number was provided, 35 | * e.g., in version '10' or '10.7'. 36 | */ 37 | func (v Version) Subminor() int { 38 | return int(v.c.Subminor) 39 | } 40 | -------------------------------------------------------------------------------- /visitorwrap.c: -------------------------------------------------------------------------------- 1 | /* helper functions to visit cursors 2 | */ 3 | 4 | #include "_cgo_export.h" 5 | #include "go-clang.h" 6 | 7 | unsigned 8 | _go_clang_visit_children(CXCursor c, uintptr_t callback_id) 9 | { 10 | return clang_visitChildren(c, (CXCursorVisitor)&GoClangCursorVisitor, (CXClientData)callback_id); 11 | } 12 | 13 | /* EOF */ 14 | --------------------------------------------------------------------------------