clang: lib/Interpreter/CodeCompletion.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

27#include "llvm/Support/Debug.h"

28#define DEBUG_TYPE "REPLCC"

29

31

33

40 return Opts;

41}

42

44public:

49 CCTUInfo(CCAllocator), Results(Results), CC(CC) {}

50

51

52

53

56 unsigned NumResults) final;

57

59

61

62private:

63 std::shared_ptr CCAllocator;

65 std::vectorstd::string &Results;

67};

68

69

70

71

72

74protected:

76 std::vectorstd::string &Results;

77

78private:

80

81public:

83 std::vectorstd::string &Results)

85

87

88

91 if (PreferredType.isNull()) {

92 Results.push_back(Result.Declaration->getName().str());

93 return;

94 }

95

96 if (auto *VD = dyn_cast(Result.Declaration)) {

97 auto ArgumentType = VD->getType();

98 if (PreferredType->isReferenceType()) {

102 S.CompareReferenceRelationship(SourceLocation(), RT, ArgumentType,

103 &RefConv);

104 switch (RefRelationship) {

107 Results.push_back(VD->getName().str());

108 break;

110 break;

111 }

112 } else if (S.Context.hasSameType(ArgumentType, PreferredType)) {

113 Results.push_back(VD->getName().str());

114 }

115 }

116 }

117

118

119

121 auto Prefix = S.getPreprocessor().getCodeCompletionFilter();

122

123

125 return;

126 if (StringRef(Result.Keyword).starts_with(Prefix))

128 }

129

130

131

133

134

135

137};

138

140public:

142 std::vectorstd::string &Results)

145 auto *ID = Result.Declaration->getIdentifier();

146 if (ID)

147 return;

148 if (!isa(Result.Declaration))

149 return;

150 const auto *Fun = cast(Result.Declaration);

151 if (Fun->getParent()->getCanonicalDecl() ==

153 LLVM_DEBUG(llvm::dbgs() << "[In HandleCodeCompleteDOT] Name : "

154 << ID->getName() << "\n");

155 Results.push_back(ID->getName().str());

156 }

157 }

158

160};

161

165

166 auto Prefix = S.getPreprocessor().getCodeCompletionFilter();

168

169 std::unique_ptr CCH;

170

171

172

173 switch (Context.getKind()) {

176 break;

177 default:

179 };

180

181 for (unsigned I = 0; I < NumResults; I++) {

182 auto &Result = InResults[I];

183 switch (Result.Kind) {

186 break;

187 }

188 if (Result.Declaration->getDeclName().isIdentifier() ||

189 Result.Declaration->getName().starts_with(Prefix)) {

190 break;

191 }

192 CCH->handleDeclaration(Result);

193 break;

195 CCH->handleKeyword(Result);

196 break;

198 CCH->handleMacro(Result);

199 break;

201 CCH->handlePattern(Result);

202 break;

203 }

204 }

205

206 std::sort(Results.begin(), Results.end());

207}

208

211

212public:

214 : ParentCI(ParentCI) {}

215

216protected:

218};

219

224

225 std::unique_ptr Importer;

226

227public:

233 void

235};

236

237

238

245 myExternalSource);

248 true);

249

250

251

252

253

254

255

256

257

258

261}

262

265 : ChildTUDeclCtxt(ChildASTCtxt.getTranslationUnitDecl()),

266 ParentASTCtxt(ParentASTCtxt),

267 ParentTUDeclCtxt(ParentASTCtxt.getTranslationUnitDecl()) {

269 new ASTImporter(ChildASTCtxt, ChildFM, ParentASTCtxt, ParentFM,

270 true);

271 Importer.reset(importer);

272}

273

277

279

280 auto ParentDeclName =

282

284 ParentTUDeclCtxt->lookup(ParentDeclName);

285

286 if (!lookup_result.empty()) {

287 return true;

288 }

289 return false;

290}

291

294 assert(ChildDeclContext && ChildDeclContext == ChildTUDeclCtxt &&

295 "No child decl context!");

296

298 return;

299

300 for (auto *DeclCtxt = ParentTUDeclCtxt; DeclCtxt != nullptr;

302 for (auto &IDeclContext : DeclCtxt->decls()) {

303 if (!llvm::isa(IDeclContext))

304 continue;

305

306 NamedDecl *Decl = llvm::cast(IDeclContext);

307

308 auto DeclOrErr = Importer->Import(Decl);

309 if (!DeclOrErr) {

310

311

312

313

314

315

316 llvm::consumeError(DeclOrErr.takeError());

317 continue;

318 }

319

320 if (!llvm::isa(*DeclOrErr))

321 continue;

322

323 NamedDecl *importedNamedDecl = llvm::cast(*DeclOrErr);

324

327 importedNamedDecl);

328

329 if (!llvm::isa(importedNamedDecl))

330 continue;

331

332 auto *Record = llvm::cast(importedNamedDecl);

333

334 if (auto Err = Importer->ImportDefinition(Decl)) {

335

336 consumeError(std::move(Err));

337 continue;

338 }

339

340 Record->setHasLoadedFieldsFromExternalStorage(true);

341 LLVM_DEBUG(llvm::dbgs()

342 << "\nCXXRecrod : " << Record->getName() << " size(methods): "

343 << std::distance(Record->method_begin(), Record->method_end())

344 << " has def?: " << Record->hasDefinition()

345 << " # (methods): "

346 << std::distance(Record->getDefinition()->method_begin(),

347 Record->getDefinition()->method_end())

348 << "\n");

349 for (auto *Meth : Record->methods())

351 Meth);

352 }

354 }

355}

356

358 llvm::StringRef Content, unsigned Line,

359 unsigned Col,

361 std::vectorstd::string &CCResults) {

364

367 InterpCI->getInvocationPtr(), std::make_shared(),

368 diag));

373 auto Act = std::make_unique(ParentCI);

374 std::unique_ptrllvm::MemoryBuffer MB =

377

379

380

381 AU->setOwnsRemappedFileBuffers(false);

383 false, consumer,

384 std::make_sharedclang::PCHContainerOperations(), *diag,

385 InterpCI->getLangOpts(), AU->getSourceManager(),

386 AU->getFileManager(), sd, tb, std::move(Act));

387}

388

389}

Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.

llvm::MachO::Record Record

static QualType getPointeeType(const MemRegion *R)

Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...

TranslationUnitDecl * getTranslationUnitDecl() const

void setExternalSource(IntrusiveRefCntPtr< ExternalASTSource > Source)

Attach an external AST source to the AST context.

Imports selected nodes from one AST context into another context, merging AST nodes where appropriate...

static ASTUnit * LoadFromCompilerInvocationAction(std::shared_ptr< CompilerInvocation > CI, std::shared_ptr< PCHContainerOperations > PCHContainerOps, IntrusiveRefCntPtr< DiagnosticsEngine > Diags, FrontendAction *Action=nullptr, ASTUnit *Unit=nullptr, bool Persistent=true, StringRef ResourceFilesPath=StringRef(), bool OnlyLocalDecls=false, CaptureDiagsKind CaptureDiagnostics=CaptureDiagsKind::None, unsigned PrecompilePreambleAfterNParses=0, bool CacheCodeCompletionResults=false, bool UserFilesAreVolatile=false, std::unique_ptr< ASTUnit > *ErrAST=nullptr)

Create an ASTUnit from a source file, via a CompilerInvocation object, by invoking the optionally pro...

CXXRecordDecl * getCanonicalDecl() override

Retrieves the "canonical" declaration of the given declaration.

Abstract interface for a consumer of code-completion information.

Options controlling the behavior of code completion.

unsigned IncludeCodePatterns

Show code patterns in code completion results.

unsigned IncludeMacros

Show macros in code completion results.

unsigned IncludeBriefComments

Show brief documentation comments in code completion results.

unsigned IncludeGlobals

Show top-level decls in code completion results.

An allocator used specifically for the purpose of code completion.

The context in which code completion occurred, so that the code-completion consumer can process the r...

@ CCC_DotMemberAccess

Code completion occurred on the right-hand side of a member access expression using the dot operator.

QualType getBaseType() const

Retrieve the type of the base object in a member-access expression.

QualType getPreferredType() const

Retrieve the type that this expression would prefer to have, e.g., if the expression is a variable in...

Captures a result of code completion.

@ RK_Pattern

Refers to a precomputed pattern.

@ RK_Declaration

Refers to a declaration.

@ RK_Macro

Refers to a macro.

@ RK_Keyword

Refers to a keyword or symbol.

CompilerInstance - Helper class for managing a single instance of the Clang compiler.

FileManager & getFileManager() const

Return the current file manager to the caller.

IntrusiveRefCntPtr< DiagnosticsEngine > getDiagnosticsPtr() const

ASTContext & getASTContext() const

FrontendOptions & getFrontendOpts()

std::shared_ptr< CompilerInvocation > getInvocationPtr()

LangOptions & getLangOpts()

The class CompletionContextHandler contains four interfaces, each of which handles one type of comple...

CompletionContextHandler(Sema &S, CodeCompletionContext CCC, std::vector< std::string > &Results)

std::vector< std::string > & Results

virtual void handleMacro(const CodeCompletionResult &Result)

Converts a Macro completion result to a completion string, and then stores it in Results.

virtual void handleDeclaration(const CodeCompletionResult &Result)

Converts a Declaration completion result to a completion string, and then stores it in Results.

virtual void handlePattern(const CodeCompletionResult &Result)

Converts a Pattern completion result to a completion string, and then stores it in Results.

virtual void handleKeyword(const CodeCompletionResult &Result)

Converts a Keyword completion result to a completion string, and then stores it in Results.

virtual ~CompletionContextHandler()=default

CodeCompletionContext CCC

The results of name lookup within a DeclContext.

DeclContext - This is used only as base class of specific decl types that can act as declaration cont...

void setHasExternalVisibleStorage(bool ES=true) const

State whether this DeclContext has external storage for declarations visible in this context.

lookup_result lookup(DeclarationName Name) const

lookup - Find the declarations (if any) with the given Name in this context.

bool hasExternalVisibleStorage() const

Whether this DeclContext has external storage containing additional declarations that are visible in ...

lookups_range lookups() const

void setHasExternalLexicalStorage(bool ES=true) const

State whether this DeclContext has external storage for declarations lexically in this context.

Decl - This represents one declaration (or definition), e.g.

Decl * getPreviousDecl()

Retrieve the previous declaration that declares the same entity as this declaration,...

The name of a declaration.

Options for controlling the compiler diagnostics engine.

void handleDeclaration(const CodeCompletionResult &Result) override

Converts a Declaration completion result to a completion string, and then stores it in Results.

DotMemberAccessHandler(Sema &S, CodeCompletionContext CCC, std::vector< std::string > &Results)

void handleKeyword(const CodeCompletionResult &Result) override

Converts a Keyword completion result to a completion string, and then stores it in Results.

Abstract interface for external sources of AST nodes.

static DeclContextLookupResult SetExternalVisibleDeclsForName(const DeclContext *DC, DeclarationName Name, ArrayRef< NamedDecl * > Decls)

ExternalSource(ASTContext &ChildASTCtxt, FileManager &ChildFM, ASTContext &ParentASTCtxt, FileManager &ParentFM)

bool FindExternalVisibleDeclsByName(const DeclContext *DC, DeclarationName Name, const DeclContext *OriginalDC) override

Find all declarations with the given name in the given context, and add them to the context by callin...

void completeVisibleDeclsMap(const clang::DeclContext *childDeclContext) override

Ensures that the table of all visible declarations inside this context is up to date.

Implements support for file system lookup, file system caching, and directory search management.

CompilerInstance & getCompilerInstance() const

virtual void ExecuteAction()=0

Callback to run the program action, using the initialized compiler instance.

An input file for the front end.

SmallVector< FrontendInputFile, 0 > Inputs

The input files and their types.

Allocator for a cached set of global code completions.

Implements an efficient mapping from strings to IdentifierInfo nodes.

IdentifierInfo & get(StringRef Name)

Return the identifier token info for the specified named identifier.

IncrementalSyntaxOnlyAction(const CompilerInstance *ParentCI)

void ExecuteAction() override

Implement the ExecuteAction interface by running Sema on the already-initialized AST consumer.

This represents a decl that may have a name.

DeclarationName getDeclName() const

Get the actual, stored name of the declaration, which may be a special name.

A (possibly-)qualified type.

bool isNull() const

Return true if this QualType doesn't point to a type yet.

Base for LValueReferenceType and RValueReferenceType.

ReplCompletionConsumer(std::vector< std::string > &Results, ReplCodeCompleter &CC)

void ProcessCodeCompleteResults(class Sema &S, CodeCompletionContext Context, CodeCompletionResult *InResults, unsigned NumResults) final

Process the finalized code-completion results.

CodeCompletionAllocator & getAllocator() override

Retrieve the allocator that will be used to allocate code completion strings.

CodeCompletionTUInfo & getCodeCompletionTUInfo() override

Sema - This implements semantic analysis and AST building for C.

ReferenceCompareResult

ReferenceCompareResult - Expresses the result of comparing two types (cv1 T1 and cv2 T2) to determine...

@ Ref_Incompatible

Ref_Incompatible - The two types are incompatible, so direct reference binding is not possible.

@ Ref_Compatible

Ref_Compatible - The two types are reference-compatible.

@ Ref_Related

Ref_Related - The two types are reference-related, which means that their unqualified forms (T1 and T...

Encodes a location in the source.

The top declaration context.

CXXRecordDecl * getAsCXXRecordDecl() const

Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...

const T * castAs() const

Member-template castAs.

The JSON file list parser is used to communicate input to InstallAPI.

@ Result

The result type of a method or function.

clang::CodeCompleteOptions getClangCompleteOpts()

const std::string CodeCompletionFileName

void codeComplete(CompilerInstance *InterpCI, llvm::StringRef Content, unsigned Line, unsigned Col, const CompilerInstance *ParentCI, std::vector< std::string > &CCResults)

ReferenceConversions

The conversions that would be performed on an lvalue of type T2 when binding a reference of type T1 t...