[cfe-commits] r90300 - in /cfe/trunk: include/clang/Basic/SourceManager.h include/clang/Lex/Lexer.h include/clang/Lex/Preprocessor.h lib/Basic/SourceManager.cpp lib/Frontend/CompilerInstance.cpp lib/Lex/Lexer.cpp lib/Lex/Preprocessor.cpp
Chris Lattner
clattner at apple.com
Wed Dec 2 16:24:01 PST 2009
On Dec 1, 2009, at 11:43 PM, Douglas Gregor wrote:
>>
>> This API is somewhat unfortunate. It doesn't make a lot of sense
>> (to me) for SourceMgr to load a file, then have to 'override' it.
>> It seems that libfrontend (the only thing that should know about
>> "truncation" IMO) should call into SourceMgr (potentially before
>> the preprocessor is even constructed!) with a
>> "setMemoryBufferForFileEntry" call. This call would assert if the
>> FileEntry already had a MemoryBuffer.
>
> It can't assert. The second client of overrideFileContents (not
> committed yet) allows us to replace the contents of a FileEntry*
> with the contents of a totally unrelated FileEntry* from the command
> line (e.g., "pretend that a.cpp has the contents of /tmp/a.cpp").
> These contents may then be overridden again by truncation for code-
> completion purposes. I don't want to force clients to tip-toe around
> double-replacements
Ok, works for me!
>> The nice thing about this is that we hoist all the handling of
>> "truncation" completely out of libbasic and liblex. The only thing
>> we need to add is a single (simple) SourceManager API
>> (setMemoryBufferForFileEntry or whatever you decide to call it).
>
> Aside from assert vs. replacing an existing buffer, we're talking
> about the same simple API but with two different names
> (overrideFileContents or setMemoryBufferForFileEntry), right?
Yes, if you need 'override' for the later client, than keeping it the
way it is is fine. I was just trying to 'strength reduce' the API.
>> This should be moved to libfrontend, I consider this part of the
>> 'truncation' half of this.
>
> I kinda sorta agree, but moving the truncation bits to libfrontend
> splits the low-level mechanism for code completion (truncation + EOF
> translation) into two almost completely unrelated parts of the
> compiler.
Right, that's the point though: these are orthogonal concepts which
happen to be used together (today) for one use. I don't think that
two orthogonal pieces being in different places is a bad thing at all.
>>> +++ cfe/trunk/lib/Lex/Lexer.cpp Wed Dec 2 00:49:09 2009
>>> @@ -1326,24 +1321,16 @@
>>> // Otherwise, check if we are code-completing, then issue
>>> diagnostics for
>>> // unterminated #if and missing newline.
>>>
>>> + if (PP && PP->isCodeCompletionFile(FileLoc)) {
>>
>> I'm fine with a hook being here to turn EOF ->
>> tok::code_completion. It would be slightly cleaner conceptually to
>> have the 'IsEofCodeCompletion' bool back, to prevent having to poke
>> the preprocessor to get this state, but I'm fine with it either way.
>
> Even when we had IsEofCodeCompletion, we had to poke the
> preprocessor because the lexer sees many EOFs... only the one for
> the CodeCompletionFile actually translates into
> tok::code_completion. Adding isCodeCompletionFile into the
> preprocessor centralized the logic.
Right, the PP would have to only set this bit for the "last" file.
I'm fine keeping it the way you have it, no worries.
>>
>> This should be moved to libfrontend, I consider this part of the
>> 'truncation' half of this.
>
>
> I just had a "Duh!" moment about this... the preprocessor needs to
> know about code completion anyway, because we should be able to
> complete things like:
>
> #<list of preprocessor directives>
> #if defined(<list of things that are defined>
> #pragma <known pragmas>
>
> #define FOO(X, Y, Z)
> FOO(blah, <completion containing Y, Z)>
>
> all of which are in the domain of the preprocessor. We just haven't
> tried to implement any code completions in the preprocessor yet.
Again, I'm not opposed to lex/pp knowing about code completion, I
don't want them to know about truncation.
-Chris
More information about the cfe-commits
mailing list