Indexing a file with clang-c doesn't hit my ppIncludedFile callback
clang, compiler-construction
Solution
The processing at `#include` time may not be recorded since there's a lot of information there (and there may not be required in the general case). There's a `createPreporcessingRecord` function which doesn't generate data if the option hasn't been enabled.
The Clang documentation describes CXTranslationUnit_DetailedPreprocessingRecord which you can use as a flag instead of the `CXTranslationUnit_None` which may help.
Problem
I'm using the Objective-C class below to index an Objective-C file. I've tried parsing files that use both `#include` and `#import`, with both angle-bracket and quoted header files. In no case does my `ppIncludedFile` callback get hit. Clang is clearly including the files as I get index callbacks for the symbols defined in them. But regarding the overall structure, I get `enteredMainFile`, then I get `startedTranslationUnit` for the main file too. But I never find out what header files it's looking in. According to the documentation: /** * \brief Called when a file gets #included/#imported. */ CXIdxClientFile (*ppIncludedFile)(CXClientData client_data, const CXIdxIncludedFileInfo *); this isn't happening. Is it a bug, or do I need to do something to enable this callback? The version of `libclang` I'm using is from svn trunk r156259. ``` // // FZAClassParser.m // ObjectiveBrowser // // Created by Graham Lee on 07/05/2012. // Copyright (c) 2012 Fuzzy Aliens Ltd.. All rights reserved. // #import "FZAClassParser.h" #import "FZAClassParserDelegate.h" int abortQuery(CXClientData client_data, void *reserved); void diagnostic(CXClientData client_data, CXDiagnosticSet diagnostic_set, void *reserved); CXIdxClientFile enteredMainFile(CXClientData client_data, CXFile mainFile, void *reserved); CXIdxClientFile ppIncludedFile(CXClientData client_data, const CXIdxIncludedFileInfo *included_file); CXIdxClientASTFile importedASTFile(CXClientData client_data, const CXIdxImportedASTFileInfo *imported_ast); CXIdxClientContainer startedTranslationUnit(CXClientData client_data, void *reserved); void indexDeclaration(CXClientData client_data, const CXIdxDeclInfo *declaration); void indexEntityReference(CXClientData client_data, const CXIdxEntityRefInfo *entity_reference); static IndexerCallbacks indexerCallbacks = { .abortQuery = abortQuery, .diagnostic = diagnostic, .enteredMainFile = enteredMainFile, .ppIncludedFile = ppIncludedFile, .importedASTFile = importedASTFile, .startedTranslationUnit = startedTranslationUnit, .indexDeclaration = indexDeclaration, .indexEntityReference = indexEntityReference }; @interface FZAClassParser () - (void)realParse; @end @implementation FZAClassParser { NSString *sourceFile; NSOperationQueue *queue; } @synthesize delegate; - (id)initWithSourceFile:(NSString *)implementation { if ((self = [super init])) { if(![[NSFileManager defaultManager] fileExistsAtPath: implementation]) { return nil; } sourceFile = [implementation copy]; queue = [[NSOperationQueue alloc] init]; } return self; } - (void)parse { __weak id parser = self; [queue addOperationWithBlock: ^{ [parser realParse]; }]; } - (void)realParse { #pragma warning Pass errors back to the app @autoreleasepool { CXIndex index = clang_createIndex(1, 1); if (!index) { NSLog(@"fail: couldn't create translation unit"); return; } CXTranslationUnit translationUnit = clang_parseTranslationUnit(index, [sourceFile fileSystemRepresentation], NULL, 0, NULL, 0, CXTranslationUnit_None); if (!translationUnit) { NSLog(@"fail: couldn't compile %@", sourceFile); return; } CXIndexAction action = clang_IndexAction_create(index); if ([self.delegate respondsToSelector: @selector(classParser:willBeginParsingFile:)]) { [self.delegate classParser: self willBeginParsingFile: sourceFile]; } int indexResult = clang_indexTranslationUnit(action, (__bridge CXClientData)self, &indexerCallbacks, sizeof(indexerCallbacks), CXIndexOpt_SuppressWarnings, translationUnit); if ([self.delegate respondsToSelector: @selector(classParser:didFinishParsingFile:)]) { [self.delegate classParser: self didFinishParsingFile: sourceFile]; } clang_IndexAction_dispose(action); clang_disposeTranslationUnit(translationUnit); clang_disposeIndex(index); (void) indexResult; } } @end int abortQuery(CXClientData client_data, void *reserved) { @autoreleasepool { FZAClassParser *parser = (__bridge FZAClassParser *)client_data; if ([parser.delegate respondsToSelector: @selector(classParserShouldAbort:)]) { return [parser.delegate classParserShouldAbort: parser]; } return 0; } } void diagnostic(CXClientData client_data, CXDiagnosticSet diagnostic_set, void *reserved) { @autoreleasepool { FZAClassParser *parser = (__bridge FZAClassParser *)client_data; if ([parser.delegate respondsToSelector: @selector(classParser:foundDiagnostics:)]) { [parser.delegate classParser: parser foundDiagnostics: diagnostic_set]; } } } CXIdxClientFile enteredMainFile(CXClientData client_data, CXFile mainFile, void *reserved) { @autoreleasepool { FZAClassParser *parser = (__bridge FZAClassParser *)client_data; if ([parser.delegate respondsToSelector: @selector(classParser:enteredMainFile:)]) { return [parser.delegate classParser: parser enteredMainFile: mainFile]; } return NULL; } } CXIdxClientFile ppIncludedFile(CXClientData client_data, const CXIdxIncludedFileInfo *included_file) { @autoreleasepool { FZAClassParser *parser = (__bridge FZAClassParser *)client_data; if ([parser.delegate respondsToSelector: @selector(classParser:includedFile:)]) { return [parser.delegate classParser: parser includedFile: included_file]; } return NULL; } } CXIdxClientASTFile importedASTFile(CXClientData client_data, const CXIdxImportedASTFileInfo *imported_ast) { @autoreleasepool { FZAClassParser *parser = (__bridge FZAClassParser *)client_data; if ([parser.delegate respondsToSelector: @selector(classParser:importedPCH:)]) { return [parser.delegate classParser: parser importedPCH: imported_ast]; } return NULL; } } CXIdxClientContainer startedTranslationUnit(CXClientData client_data, void *reserved) { @autoreleasepool { FZAClassParser *parser = (__bridge FZAClassParser *)client_data; if ([parser.delegate respondsToSelector: @selector(classParserStartedTranslationUnit:)]) { return [parser.delegate classParserStartedTranslationUnit: parser]; } return NULL; } } void indexDeclaration(CXClientData client_data, const CXIdxDeclInfo *declaration) { @autoreleasepool { FZAClassParser *parser = (__bridge FZAClassParser *)client_data; if ([parser.delegate respondsToSelector: @selector(classParser:foundDeclaration:)]) { [parser.delegate classParser: parser foundDeclaration: declaration]; } } } void indexEntityReference(CXClientData client_data, const CXIdxEntityRefInfo *entity_reference) { @autoreleasepool { FZAClassParser *parser = (__bridge FZAClassParser *)client_data; if ([parser.delegate respondsToSelector: @selector(classParser:foundEntityReference:)]) { [parser.delegate classParser: parser foundEntityReference: entity_reference]; } } } ```