[cfe-dev] Distinguishing system headers from user headers using libclang

Argyrios Kyrtzidis akyrtzi at gmail.com
Fri Apr 12 10:09:28 PDT 2013

On Apr 12, 2013, at 8:23 AM, "Siedlarek, Mikołaj" <m.siedlarek at nctz.net> wrote:

> On Fri, Apr 12, 2013 at 4:59 PM, Argyrios Kyrtzidis <akyrtzi at gmail.com> wrote:
>> On Apr 11, 2013, at 11:43 PM, "Siedlarek, Mikołaj" <m.siedlarek at nctz.net> wrote:
>>> On Thu, Apr 11, 2013 at 7:22 PM, Argyrios Kyrtzidis <akyrtzi at gmail.com> wrote:
>>>> On Apr 5, 2013, at 4:20 AM, "Siedlarek, Mikołaj" <m.siedlarek at nctz.net>
>>>> wrote:
>>>> On Fri, Apr 5, 2013 at 12:37 PM, Siedlarek, Mikołaj
>>>> <m.siedlarek at nctz.net> wrote:
>>>> On Fri, Apr 5, 2013 at 12:22 AM, Argyrios Kyrtzidis <akyrtzi at gmail.com>
>>>> wrote:
>>>> On Apr 2, 2013, at 1:33 AM, Mikołaj Siedlarek <m.siedlarek at nctz.net> wrote:
>>>> Hi,
>>>> I'm writing a simple code dependency analysis tool using libclang and I'm
>>>> missing some way of distinguishing system headers from user headers. I see
>>>> clang::DirectoryLookup::getDirCharacteristic() provides such interface, but
>>>> is there any way I could obtain this information using just libclang? My
>>>> tool is rather simple and I'd like to keep it that way - libclang seems to
>>>> be sufficient for the rest of my needs.
>>>> There is no way currently, but it should relatively easy, are you interested
>>>> in providing such a patch ?
>>>> The clang function you may need to look into using is
>>>> "SourceManager::isInSystemHeader(SourceLocation Loc)"
>>>> The libclang function would accept a CXTranslationUnit and a
>>>> CXSourceLocation.
>>>> How about this? That's the best and most elastic approach I could think of.
>>>> There was unnecessary CINDEX_LINKAGE in the first version of my patch.
>>>> Here's corrected one.
>>>> +  /**
>>>> +   * \brief System code which is implicitly 'extern "C"' in C++ mode
>>>> +   */
>>>> +  CXCharacteristicKind_ExternCSystem
>>>> This is very "legacy-hacky-compiler-specific"; I can't think of a reason
>>>> that a libclang client would need to know this.
>>>> I suggest just adding a
>>>> int clang_SourceLocation_isInSystemHeader(CXSourceLocation location)
>>>> function.
>>> I agree ExternCSystem may not be useful - I added it to mimic
>>> underlaying library interface. Nevertheless, I don't think boolean
>>> isInSystemHeader is enough. For example - in my program I need to know
>>> whether given source location is in user code. !isInSystemHeader
>>> wouldn't be enough, because there are also invalid locations like
>>> built-in compiler declarations or anything really that has no
>>> corresponding location in the source.
>> To check for invalid locations you can do:
>> if (clang_equalLocations(Location, clang_getNullLocation()) {
>>  // invalid
>> }
> I don't really think that's user/client-friendly approach to have a
> combination of
> different interface functions providing same information type, but I guess it's
> your choice.

From my viewpoint this is what your enum returning version did, it provided an additional way to determine if a source location was invalid, while there was already a standard one.
In general there are libclang functions to determine if an object is null/invalid and more functions to query information from the object. If all clang_is* functions were changed to return an enum to also cover the null/invalid case, this would be rather user unfriendly.

> Here's simple isInSystemHeader.

Committed a modified patch in r179384, thanks!

> -- 
> Mikołaj Siedlarek
> m.siedlarek at nctz.net
> <file-characteristics-v3.diff>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20130412/cfb820f5/attachment.html>

More information about the cfe-dev mailing list