blob: b626847d6251a86ea87604a23165d152a6e90c0d [file] [log] [blame]
Douglas Gregor2436e712009-09-17 21:32:03 +00001//===---- CodeCompleteConsumer.h - Code Completion Interface ----*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the CodeCompleteConsumer class.
11//
12//===----------------------------------------------------------------------===//
13#include "clang/Sema/CodeCompleteConsumer.h"
Douglas Gregor56c2dbc2009-09-18 17:54:00 +000014#include "clang/AST/DeclCXX.h"
Douglas Gregorf45b0cf2009-09-18 15:37:17 +000015#include "clang/Parse/Scope.h"
Douglas Gregor2436e712009-09-17 21:32:03 +000016#include "clang/Lex/Preprocessor.h"
17#include "Sema.h"
18#include "llvm/ADT/STLExtras.h"
19#include "llvm/Support/Compiler.h"
20#include "llvm/Support/raw_ostream.h"
21#include <algorithm>
22#include <string.h>
23using namespace clang;
24
25CodeCompleteConsumer::CodeCompleteConsumer(Sema &S) : SemaRef(S) {
26 SemaRef.setCodeCompleteConsumer(this);
27}
28
29CodeCompleteConsumer::~CodeCompleteConsumer() {
30 SemaRef.setCodeCompleteConsumer(0);
31}
32
33void
34CodeCompleteConsumer::CodeCompleteMemberReferenceExpr(Scope *S,
35 QualType BaseType,
36 bool IsArrow) {
37 if (IsArrow) {
38 if (const PointerType *Ptr = BaseType->getAs<PointerType>())
39 BaseType = Ptr->getPointeeType();
40 else if (BaseType->isObjCObjectPointerType())
41 /*Do nothing*/ ;
42 else
43 return;
44 }
45
Douglas Gregorf45b0cf2009-09-18 15:37:17 +000046 ResultSet Results(*this);
Douglas Gregor2436e712009-09-17 21:32:03 +000047 unsigned NextRank = 0;
48
49 if (const RecordType *Record = BaseType->getAs<RecordType>()) {
Douglas Gregorf45b0cf2009-09-18 15:37:17 +000050 NextRank = CollectMemberLookupResults(Record->getDecl(), NextRank, Results);
Douglas Gregor2436e712009-09-17 21:32:03 +000051
52 if (getSema().getLangOptions().CPlusPlus) {
53 if (!Results.empty())
54 // The "template" keyword can follow "->" or "." in the grammar.
55 Results.MaybeAddResult(Result("template", NextRank++));
56
Douglas Gregor945e8d92009-09-18 17:42:29 +000057 // We could have the start of a nested-name-specifier. Add those
58 // results as well.
59 Results.setFilter(&CodeCompleteConsumer::IsNestedNameSpecifier);
60 CollectLookupResults(S, NextRank, Results);
Douglas Gregor2436e712009-09-17 21:32:03 +000061 }
62
63 // Hand off the results found for code completion.
64 ProcessCodeCompleteResults(Results.data(), Results.size());
65
66 // We're done!
67 return;
68 }
69}
70
Douglas Gregorf45b0cf2009-09-18 15:37:17 +000071void CodeCompleteConsumer::CodeCompleteTag(Scope *S, ElaboratedType::TagKind TK) {
72 ResultSet::LookupFilter Filter = 0;
73 switch (TK) {
74 case ElaboratedType::TK_enum:
75 Filter = &CodeCompleteConsumer::IsEnum;
76 break;
77
78 case ElaboratedType::TK_class:
79 case ElaboratedType::TK_struct:
80 Filter = &CodeCompleteConsumer::IsClassOrStruct;
81 break;
82
83 case ElaboratedType::TK_union:
84 Filter = &CodeCompleteConsumer::IsUnion;
85 break;
86 }
87
88 ResultSet Results(*this, Filter);
Douglas Gregor945e8d92009-09-18 17:42:29 +000089 unsigned NextRank = CollectLookupResults(S, 0, Results);
Douglas Gregorf45b0cf2009-09-18 15:37:17 +000090
Douglas Gregor945e8d92009-09-18 17:42:29 +000091 if (getSema().getLangOptions().CPlusPlus) {
92 // We could have the start of a nested-name-specifier. Add those
93 // results as well.
94 Results.setFilter(&CodeCompleteConsumer::IsNestedNameSpecifier);
95 CollectLookupResults(S, NextRank, Results);
96 }
Douglas Gregorf45b0cf2009-09-18 15:37:17 +000097
98 ProcessCodeCompleteResults(Results.data(), Results.size());
99}
100
Douglas Gregor2436e712009-09-17 21:32:03 +0000101void
102CodeCompleteConsumer::CodeCompleteQualifiedId(Scope *S,
103 NestedNameSpecifier *NNS,
104 bool EnteringContext) {
105 CXXScopeSpec SS;
106 SS.setScopeRep(NNS);
107 DeclContext *Ctx = getSema().computeDeclContext(SS, EnteringContext);
108 if (!Ctx)
109 return;
110
Douglas Gregorf45b0cf2009-09-18 15:37:17 +0000111 ResultSet Results(*this);
112 unsigned NextRank = CollectMemberLookupResults(Ctx, 0, Results);
Douglas Gregor2436e712009-09-17 21:32:03 +0000113
114 // The "template" keyword can follow "::" in the grammar
115 if (!Results.empty())
116 Results.MaybeAddResult(Result("template", NextRank));
117
118 ProcessCodeCompleteResults(Results.data(), Results.size());
119}
120
121void CodeCompleteConsumer::ResultSet::MaybeAddResult(Result R) {
122 if (R.Kind != Result::RK_Declaration) {
123 // For non-declaration results, just add the result.
124 Results.push_back(R);
125 return;
126 }
Douglas Gregor56c2dbc2009-09-18 17:54:00 +0000127
128 // Look through using declarations.
129 if (UsingDecl *Using = dyn_cast<UsingDecl>(R.Declaration))
130 return MaybeAddResult(Result(Using->getTargetDecl(), R.Rank));
Douglas Gregor2436e712009-09-17 21:32:03 +0000131
Douglas Gregor56c2dbc2009-09-18 17:54:00 +0000132 // Handle each declaration in an overload set separately.
133 if (OverloadedFunctionDecl *Ovl
134 = dyn_cast<OverloadedFunctionDecl>(R.Declaration)) {
135 for (OverloadedFunctionDecl::function_iterator F = Ovl->function_begin(),
136 FEnd = Ovl->function_end();
137 F != FEnd; ++F)
138 MaybeAddResult(Result(*F, R.Rank));
139
140 return;
141 }
Douglas Gregorf45b0cf2009-09-18 15:37:17 +0000142
Douglas Gregor2436e712009-09-17 21:32:03 +0000143 Decl *CanonDecl = R.Declaration->getCanonicalDecl();
144 unsigned IDNS = CanonDecl->getIdentifierNamespace();
145
146 // Friend declarations and declarations introduced due to friends are never
147 // added as results.
148 if (isa<FriendDecl>(CanonDecl) ||
149 (IDNS & (Decl::IDNS_OrdinaryFriend | Decl::IDNS_TagFriend)))
150 return;
151
Douglas Gregor945e8d92009-09-18 17:42:29 +0000152 if (const IdentifierInfo *Id = R.Declaration->getIdentifier()) {
153 // __va_list_tag is a freak of nature. Find it and skip it.
154 if (Id->isStr("__va_list_tag"))
155 return;
156
157 // FIXME: Should we filter out other names in the implementation's
158 // namespace, e.g., those containing a __ or that start with _[A-Z]?
159 }
160
161 // C++ constructors are never found by name lookup.
162 if (isa<CXXConstructorDecl>(CanonDecl))
163 return;
164
165 // Filter out any unwanted results.
166 if (Filter && !(Completer.*Filter)(R.Declaration))
167 return;
168
Douglas Gregor2436e712009-09-17 21:32:03 +0000169 ShadowMap &SMap = ShadowMaps.back();
170 ShadowMap::iterator I, IEnd;
171 for (llvm::tie(I, IEnd) = SMap.equal_range(R.Declaration->getDeclName());
172 I != IEnd; ++I) {
173 NamedDecl *ND = I->second.first;
174 unsigned Index = I->second.second;
175 if (ND->getCanonicalDecl() == CanonDecl) {
176 // This is a redeclaration. Always pick the newer declaration.
177 I->second.first = R.Declaration;
178 Results[Index].Declaration = R.Declaration;
179
180 // Pick the best rank of the two.
181 Results[Index].Rank = std::min(Results[Index].Rank, R.Rank);
182
183 // We're done.
184 return;
185 }
186 }
187
188 // This is a new declaration in this scope. However, check whether this
189 // declaration name is hidden by a similarly-named declaration in an outer
190 // scope.
191 std::list<ShadowMap>::iterator SM, SMEnd = ShadowMaps.end();
192 --SMEnd;
193 for (SM = ShadowMaps.begin(); SM != SMEnd; ++SM) {
194 for (llvm::tie(I, IEnd) = SM->equal_range(R.Declaration->getDeclName());
195 I != IEnd; ++I) {
196 // A tag declaration does not hide a non-tag declaration.
197 if (I->second.first->getIdentifierNamespace() == Decl::IDNS_Tag &&
198 (IDNS & (Decl::IDNS_Member | Decl::IDNS_Ordinary |
199 Decl::IDNS_ObjCProtocol)))
200 continue;
201
202 // Protocols are in distinct namespaces from everything else.
203 if (((I->second.first->getIdentifierNamespace() & Decl::IDNS_ObjCProtocol)
204 || (IDNS & Decl::IDNS_ObjCProtocol)) &&
205 I->second.first->getIdentifierNamespace() != IDNS)
206 continue;
207
208 // The newly-added result is hidden by an entry in the shadow map.
Douglas Gregor2da11082009-09-18 15:51:54 +0000209 if (Completer.canHiddenResultBeFound(R.Declaration, I->second.first)) {
210 // Note that this result was hidden.
211 R.Hidden = true;
212 } else {
213 // This result was hidden and cannot be found; don't bother adding
214 // it.
215 return;
216 }
217
Douglas Gregor2436e712009-09-17 21:32:03 +0000218 break;
219 }
220 }
221
Douglas Gregor945e8d92009-09-18 17:42:29 +0000222 // Make sure that any given declaration only shows up in the result set once.
223 if (!AllDeclsFound.insert(CanonDecl))
224 return;
225
Douglas Gregor2436e712009-09-17 21:32:03 +0000226 // Insert this result into the set of results and into the current shadow
227 // map.
228 SMap.insert(std::make_pair(R.Declaration->getDeclName(),
229 std::make_pair(R.Declaration, Results.size())));
230 Results.push_back(R);
231}
232
233/// \brief Enter into a new scope.
234void CodeCompleteConsumer::ResultSet::EnterNewScope() {
235 ShadowMaps.push_back(ShadowMap());
236}
237
238/// \brief Exit from the current scope.
239void CodeCompleteConsumer::ResultSet::ExitScope() {
240 ShadowMaps.pop_back();
241}
242
Douglas Gregorf45b0cf2009-09-18 15:37:17 +0000243// Find the next outer declaration context corresponding to this scope.
244static DeclContext *findOuterContext(Scope *S) {
245 for (S = S->getParent(); S; S = S->getParent())
246 if (S->getEntity())
247 return static_cast<DeclContext *>(S->getEntity())->getPrimaryContext();
248
249 return 0;
250}
251
252/// \brief Collect the results of searching for declarations within the given
253/// scope and its parent scopes.
254///
255/// \param S the scope in which we will start looking for declarations.
256///
257/// \param InitialRank the initial rank given to results in this scope.
258/// Larger rank values will be used for results found in parent scopes.
259unsigned CodeCompleteConsumer::CollectLookupResults(Scope *S,
260 unsigned InitialRank,
261 ResultSet &Results) {
262 if (!S)
263 return InitialRank;
264
265 // FIXME: Using directives!
266
267 unsigned NextRank = InitialRank;
268 Results.EnterNewScope();
269 if (S->getEntity() &&
270 !((DeclContext *)S->getEntity())->isFunctionOrMethod()) {
271 // Look into this scope's declaration context, along with any of its
272 // parent lookup contexts (e.g., enclosing classes), up to the point
273 // where we hit the context stored in the next outer scope.
274 DeclContext *Ctx = (DeclContext *)S->getEntity();
275 DeclContext *OuterCtx = findOuterContext(S);
276
277 for (; Ctx && Ctx->getPrimaryContext() != OuterCtx;
278 Ctx = Ctx->getLookupParent()) {
279 if (Ctx->isFunctionOrMethod())
280 continue;
281
282 NextRank = CollectMemberLookupResults(Ctx, NextRank + 1, Results);
283 }
284 } else if (!S->getParent()) {
285 // Look into the translation unit scope. We walk through the translation
286 // unit's declaration context, because the Scope itself won't have all of
287 // the declarations if
288 NextRank = CollectMemberLookupResults(
289 getSema().Context.getTranslationUnitDecl(),
290 NextRank + 1, Results);
291 } else {
292 // Walk through the declarations in this Scope.
293 for (Scope::decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
294 D != DEnd; ++D) {
295 if (NamedDecl *ND = dyn_cast<NamedDecl>((Decl *)((*D).get())))
296 Results.MaybeAddResult(Result(ND, NextRank));
297 }
298
299 NextRank = NextRank + 1;
300 }
301
302 // Lookup names in the parent scope.
303 NextRank = CollectLookupResults(S->getParent(), NextRank, Results);
304 Results.ExitScope();
305
306 return NextRank;
307}
308
Douglas Gregor2436e712009-09-17 21:32:03 +0000309/// \brief Collect the results of searching for members within the given
310/// declaration context.
311///
312/// \param Ctx the declaration context from which we will gather results.
313///
Douglas Gregorf45b0cf2009-09-18 15:37:17 +0000314/// \param InitialRank the initial rank given to results in this declaration
315/// context. Larger rank values will be used for, e.g., members found in
316/// base classes.
Douglas Gregor2436e712009-09-17 21:32:03 +0000317///
318/// \param Results the result set that will be extended with any results
319/// found within this declaration context (and, for a C++ class, its bases).
320///
321/// \returns the next higher rank value, after considering all of the
322/// names within this declaration context.
Douglas Gregorf45b0cf2009-09-18 15:37:17 +0000323unsigned CodeCompleteConsumer::CollectMemberLookupResults(DeclContext *Ctx,
324 unsigned InitialRank,
325 ResultSet &Results) {
Douglas Gregor2436e712009-09-17 21:32:03 +0000326 // Enumerate all of the results in this context.
327 Results.EnterNewScope();
328 for (DeclContext *CurCtx = Ctx->getPrimaryContext(); CurCtx;
329 CurCtx = CurCtx->getNextContext()) {
330 for (DeclContext::decl_iterator D = CurCtx->decls_begin(),
331 DEnd = CurCtx->decls_end();
332 D != DEnd; ++D) {
Douglas Gregorf45b0cf2009-09-18 15:37:17 +0000333 if (NamedDecl *ND = dyn_cast<NamedDecl>(*D))
Douglas Gregor2436e712009-09-17 21:32:03 +0000334 Results.MaybeAddResult(Result(ND, InitialRank));
Douglas Gregor2436e712009-09-17 21:32:03 +0000335 }
336 }
337
338 // Traverse the contexts of inherited classes.
339 unsigned NextRank = InitialRank;
340 if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(Ctx)) {
341 for (CXXRecordDecl::base_class_iterator B = Record->bases_begin(),
342 BEnd = Record->bases_end();
343 B != BEnd; ++B) {
344 QualType BaseType = B->getType();
345
346 // Don't look into dependent bases, because name lookup can't look
347 // there anyway.
348 if (BaseType->isDependentType())
349 continue;
350
351 const RecordType *Record = BaseType->getAs<RecordType>();
352 if (!Record)
353 continue;
354
355 // FIXME: We should keep track of the virtual bases we visit, so
356 // that we don't visit them more than once.
357
358 // FIXME: It would be nice to be able to determine whether referencing
359 // a particular member would be ambiguous. For example, given
360 //
361 // struct A { int member; };
362 // struct B { int member; };
363 // struct C : A, B { };
364 //
365 // void f(C *c) { c->### }
366 // accessing 'member' would result in an ambiguity. However, code
367 // completion could be smart enough to qualify the member with the
368 // base class, e.g.,
369 //
370 // c->B::member
371 //
372 // or
373 //
374 // c->A::member
375
376 // Collect results from this base class (and its bases).
377 NextRank = std::max(NextRank,
Douglas Gregorf45b0cf2009-09-18 15:37:17 +0000378 CollectMemberLookupResults(Record->getDecl(),
379 InitialRank + 1,
380 Results));
Douglas Gregor2436e712009-09-17 21:32:03 +0000381 }
382 }
383
384 // FIXME: Look into base classes in Objective-C!
385
386 Results.ExitScope();
387 return NextRank;
388}
389
Douglas Gregorf45b0cf2009-09-18 15:37:17 +0000390/// \brief Determines whether the given declaration is suitable as the
391/// start of a C++ nested-name-specifier, e.g., a class or namespace.
392bool CodeCompleteConsumer::IsNestedNameSpecifier(NamedDecl *ND) const {
393 // Allow us to find class templates, too.
394 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
395 ND = ClassTemplate->getTemplatedDecl();
396
397 return getSema().isAcceptableNestedNameSpecifier(ND);
398}
399
400/// \brief Determines whether the given declaration is an enumeration.
401bool CodeCompleteConsumer::IsEnum(NamedDecl *ND) const {
402 return isa<EnumDecl>(ND);
403}
404
405/// \brief Determines whether the given declaration is a class or struct.
406bool CodeCompleteConsumer::IsClassOrStruct(NamedDecl *ND) const {
407 // Allow us to find class templates, too.
408 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
409 ND = ClassTemplate->getTemplatedDecl();
410
411 if (RecordDecl *RD = dyn_cast<RecordDecl>(ND))
412 return RD->getTagKind() == TagDecl::TK_class ||
413 RD->getTagKind() == TagDecl::TK_struct;
414
415 return false;
416}
417
418/// \brief Determines whether the given declaration is a union.
419bool CodeCompleteConsumer::IsUnion(NamedDecl *ND) const {
420 // Allow us to find class templates, too.
421 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
422 ND = ClassTemplate->getTemplatedDecl();
423
424 if (RecordDecl *RD = dyn_cast<RecordDecl>(ND))
425 return RD->getTagKind() == TagDecl::TK_union;
426
427 return false;
428}
429
Douglas Gregor2436e712009-09-17 21:32:03 +0000430namespace {
431 struct VISIBILITY_HIDDEN SortCodeCompleteResult {
432 typedef CodeCompleteConsumer::Result Result;
433
434 bool operator()(const Result &X, const Result &Y) const {
435 // Sort first by rank.
436 if (X.Rank < Y.Rank)
437 return true;
438 else if (X.Rank > Y.Rank)
439 return false;
440
441 // Result kinds are ordered by decreasing importance.
442 if (X.Kind < Y.Kind)
443 return true;
444 else if (X.Kind > Y.Kind)
445 return false;
446
447 // Non-hidden names precede hidden names.
448 if (X.Hidden != Y.Hidden)
449 return !X.Hidden;
450
451 // Ordering depends on the kind of result.
452 switch (X.Kind) {
453 case Result::RK_Declaration:
454 // Order based on the declaration names.
455 return X.Declaration->getDeclName() < Y.Declaration->getDeclName();
456
457 case Result::RK_Keyword:
458 return strcmp(X.Keyword, Y.Keyword) == -1;
459 }
460
461 // If only our C++ compiler did control-flow warnings properly.
462 return false;
463 }
464 };
465}
466
Douglas Gregor2da11082009-09-18 15:51:54 +0000467/// \brief Determines whether the given hidden result could be found with
468/// some extra work, e.g., by qualifying the name.
469///
470/// \param Hidden the declaration that is hidden by the currenly \p Visible
471/// declaration.
472///
473/// \param Visible the declaration with the same name that is already visible.
474///
475/// \returns true if the hidden result can be found by some mechanism,
476/// false otherwise.
477bool CodeCompleteConsumer::canHiddenResultBeFound(NamedDecl *Hidden,
478 NamedDecl *Visible) {
479 // In C, there is no way to refer to a hidden name.
480 if (!getSema().getLangOptions().CPlusPlus)
481 return false;
482
483 DeclContext *HiddenCtx = Hidden->getDeclContext()->getLookupContext();
484
485 // There is no way to qualify a name declared in a function or method.
486 if (HiddenCtx->isFunctionOrMethod())
487 return false;
488
489 // If the hidden and visible declarations are in different name-lookup
490 // contexts, then we can qualify the name of the hidden declaration.
491 // FIXME: Optionally compute the string needed to refer to the hidden
492 // name.
493 return HiddenCtx != Visible->getDeclContext()->getLookupContext();
494}
495
Douglas Gregor2436e712009-09-17 21:32:03 +0000496void
497PrintingCodeCompleteConsumer::ProcessCodeCompleteResults(Result *Results,
498 unsigned NumResults) {
499 // Sort the results by rank/kind/etc.
500 std::stable_sort(Results, Results + NumResults, SortCodeCompleteResult());
501
502 // Print the results.
503 for (unsigned I = 0; I != NumResults; ++I) {
504 switch (Results[I].Kind) {
505 case Result::RK_Declaration:
506 OS << Results[I].Declaration->getNameAsString() << " : "
507 << Results[I].Rank;
508 if (Results[I].Hidden)
509 OS << " (Hidden)";
510 OS << '\n';
511 break;
512
513 case Result::RK_Keyword:
514 OS << Results[I].Keyword << " : " << Results[I].Rank << '\n';
515 break;
516 }
517 }
518
519 // Once we've printed the code-completion results, suppress remaining
520 // diagnostics.
521 // FIXME: Move this somewhere else!
522 getSema().PP.getDiagnostics().setSuppressAllDiagnostics();
523}