| 111 | } |
| 112 | |
| 113 | func (f *cgoFile) readNames(fragment string, cflags []string, filename string, callback func(map[string]clangCursor)) { |
| 114 | index := C.clang_createIndex(0, 0) |
| 115 | defer C.clang_disposeIndex(index) |
| 116 | |
| 117 | // pretend to be a .c file |
| 118 | filenameC := C.CString(filename + "!cgo.c") |
| 119 | defer C.free(unsafe.Pointer(filenameC)) |
| 120 | |
| 121 | fragmentC := C.CString(fragment) |
| 122 | defer C.free(unsafe.Pointer(fragmentC)) |
| 123 | |
| 124 | unsavedFile := C.struct_CXUnsavedFile{ |
| 125 | Filename: filenameC, |
| 126 | Length: C.ulong(len(fragment)), |
| 127 | Contents: fragmentC, |
| 128 | } |
| 129 | |
| 130 | // convert Go slice of strings to C array of strings. |
| 131 | cmdargsC := C.malloc(C.size_t(len(cflags)) * C.size_t(unsafe.Sizeof(uintptr(0)))) |
| 132 | defer C.free(cmdargsC) |
| 133 | cmdargs := (*[1 << 16]*C.char)(cmdargsC) |
| 134 | for i, cflag := range cflags { |
| 135 | s := C.CString(cflag) |
| 136 | cmdargs[i] = s |
| 137 | defer C.free(unsafe.Pointer(s)) |
| 138 | } |
| 139 | |
| 140 | var unit C.CXTranslationUnit |
| 141 | errCode := C.clang_parseTranslationUnit2( |
| 142 | index, |
| 143 | filenameC, |
| 144 | (**C.char)(cmdargsC), C.int(len(cflags)), // command line args |
| 145 | &unsavedFile, 1, // unsaved files |
| 146 | C.CXTranslationUnit_DetailedPreprocessingRecord, |
| 147 | &unit) |
| 148 | if errCode != 0 { |
| 149 | // This is probably a bug in the usage of libclang. |
| 150 | panic("cgo: failed to parse source with libclang") |
| 151 | } |
| 152 | defer C.clang_disposeTranslationUnit(unit) |
| 153 | |
| 154 | // Report parser and type errors. |
| 155 | if numDiagnostics := int(C.clang_getNumDiagnostics(unit)); numDiagnostics != 0 { |
| 156 | addDiagnostic := func(diagnostic C.CXDiagnostic) { |
| 157 | spelling := getString(C.clang_getDiagnosticSpelling(diagnostic)) |
| 158 | severity := diagnosticSeverity[C.clang_getDiagnosticSeverity(diagnostic)] |
| 159 | location := C.clang_getDiagnosticLocation(diagnostic) |
| 160 | pos := f.getClangLocationPosition(location, unit) |
| 161 | f.addError(pos, severity+": "+spelling) |
| 162 | } |
| 163 | for i := 0; i < numDiagnostics; i++ { |
| 164 | diagnostic := C.clang_getDiagnostic(unit, C.uint(i)) |
| 165 | addDiagnostic(diagnostic) |
| 166 | |
| 167 | // Child diagnostics (like notes on redefinitions). |
| 168 | diagnostics := C.clang_getChildDiagnostics(diagnostic) |
| 169 | for j := 0; j < int(C.clang_getNumDiagnosticsInSet(diagnostics)); j++ { |
| 170 | addDiagnostic(C.clang_getDiagnosticInSet(diagnostics, C.uint(j))) |