[cfe-commits] r82166 - in /cfe/trunk: include/clang/Basic/ include/clang/Lex/ include/clang/Parse/ include/clang/Sema/ lib/Basic/ lib/Lex/ lib/Parse/ lib/Sema/ test/ test/CodeCompletion/ tools/clang-cc/

Douglas Gregor dgregor at apple.com
Mon Sep 21 08:50:47 PDT 2009


On Sep 18, 2009, at 2:08 PM, Chris Lattner wrote:

> On Sep 17, 2009, at 2:32 PM, Douglas Gregor wrote:
>> URL: http://llvm.org/viewvc/llvm-project?rev=82166&view=rev
>> Log:
>> Initial implementation of a code-completion interface in Clang. In
>
> Woot!

Thanks for the review!

>> +++ cfe/trunk/lib/Lex/Lexer.cpp Thu Sep 17 16:32:03 2009
>> @@ -1309,6 +1310,18 @@
>>    return true;  // Have a token.
>>  }
>>
>> +  if (IsEofCodeCompletion) {
>> +    // We're at the end of the file, but we've been asked to  
>> conside the
>> +    // end of the file to be a code-completion token. Return the
>> +    // code-completion token.
>> +    Result.startToken();
>> +    FormTokenWithChars(Result, CurPtr, tok::code_completion);
>> +
>> +    // Only do the eof -> code_completion translation once.
>> +    IsEofCodeCompletion = false;
>> +    return true;
>> +  }
>
> Can this be moved after the "lexing raw mode" case, so that raw mode  
> lexing doesn't pay the cost of an extra check?

Yes, good catch.

>
>> +++ cfe/trunk/include/clang/Sema/CodeCompleteConsumer.h Thu Sep 17  
>> 16:32:03 2009
>> +  /// \brief Captures a result of code completion.
>> +  struct Result {
>> +    /// \brief Describes the kind of result generated.
>> +    enum ResultKind {
>> +      RK_Declaration = 0, //< Refers to a declaration
>> +      RK_Keyword,        //< Refers to a keyword or symbol.
>> +    };
>> +
>> +    /// \brief The kind of result stored here.
>> +    ResultKind Kind;
>> +
>> +    union {
>> +      /// \brief When Kind == RK_Declaration, the declaration we  
>> are referring
>> +      /// to.
>> +      NamedDecl *Declaration;
>> +
>> +      /// \brief When Kind == RK_Keyword, the string representing  
>> the keyword
>> +      /// or symbol's spelling.
>> +      const char *Keyword;
>> +    };
>
> Wouldn't it be nice if PointerIntPair<> fell back to pair<void*,int>  
> if the pointer had no extra bits? :)

Would be nice.

> Should a Result have an optional "extra information" flag or do you  
> expect informational stuff to be derived from the decl in all  
> cases?  i.e. not from sema info?
>
>> +  /// \brief A container of code-completion results.
>> +  class ResultSet {
>
> The naming here is a bit strange.  The "Result" of a code completion  
> event is a "ResultSet", and a single entry in the result is a  
> "Result".  How about naming the classes "ResultEntry" and "Result"  
> or something?

With the ResultSet -> ResultBuilder renaming below, the name Result  
starts to make sense again.

>> +    /// \brief The actual results we have found.
>> +    std::vector<Result> Results;
>> +
>> +    /// \brief A mapping from declaration names to the  
>> declarations that have
>> +    /// this name within a particular scope and their index within  
>> the list of
>> +    /// results.
>> +    typedef std::multimap<DeclarationName,
>> +                          std::pair<NamedDecl *, unsigned> >  
>> ShadowMap;
>> +
>> +    /// \brief A list of shadow maps, which is used to model name  
>> hiding at
>> +    /// different levels of, e.g., the inheritance hierarchy.
>> +    std::list<ShadowMap> ShadowMaps;
>
> This is a very heavy-weight structure.  I haven't read this in  
> detail to understand why you need this, but... do you really need  
> this? :)

At least until I find something better, yes. This structure keeps  
track of what names we've seen in what scopes, so that we can properly  
determine when a name is hiding another name. Within Sema, we compute  
this information on-the-fly using Scopes, IdentifierInfo chains,  
DeclContexts, etc. There may still be a way to leverage that  
information here.

>> +  /// \brief Process the finalized code-completion results.
>> +  virtual void ProcessCodeCompleteResults(Result *Results,
>> +                                          unsigned NumResults) { }
>
> Oh, I see, Sema only gets the array of results.  Given this, should  
> "ResultSet" be renamed "ResultBuilder" and moved out of the public  
> header file into a private header in the Sema directory?

Yes. Sorry 'bout the confusion.

>> +  /// \brief Code completion for a member access expression, e.g.,  
>> "x->" or
>> +  /// "x.".
>> +  ///
>> +  /// \param S is the scope in which code-completion occurs.
>> +  ///
>> +  /// \param BaseType is the type whose members are being accessed.
>> +  ///
>> +  /// \param IsArrow whether this member referenced was written  
>> with an
>> +  /// arrow ("->") or a period (".").
>> +  virtual void CodeCompleteMemberReferenceExpr(Scope *S, QualType  
>> BaseType,
>> +                                               bool IsArrow);
>> +
>> +  /// \brief Code completion for a qualified-id, e.g., "std::"
>> +  ///
>> +  /// \param S the scope in which the nested-name-specifier occurs.
>> +  ///
>> +  /// \param NNS the nested-name-specifier before the code- 
>> completion location.
>> +  ///
>> +  /// \param EnteringContext whether the parser will be entering  
>> the scope of
>> +  /// the qualified-id.
>> +  virtual void CodeCompleteQualifiedId(Scope *S,  
>> NestedNameSpecifier *NNS,
>> +                                       bool EnteringContext);
>> +  //@}
>
> Why do these need to be in the public CodeCompleteConsumer  
> interface?  Doesn't Sema handle all the details of this?  Are  
> implementations of consumers expected to implement these?

I originally thought that the Result-based interface would be weak  
enough that consumers might want to tweak  
CodeCompleteMemberReferenceExpr et al, but Result is looking fairly  
useful and, with so many hooks in CodeCompleteConsumer, I doubt anyone  
will actually want to mess with them. Time for a refactoring!

	- Doug



More information about the cfe-commits mailing list