;
56using namespaceextractapi;
60std::optional<std::string> getRelativeIncludeName(
const CompilerInstance&CI,
62 bool*IsQuoted =
nullptr) {
64 "CompilerInstance does not have a FileNamager!");
66 using namespacellvm::sys;
70FS.makeAbsolute(FilePath);
71path::remove_dots(FilePath,
true);
72FilePath = path::convert_to_slash(FilePath);
77 autoCheckDir = [&](llvm::StringRef Dir) ->
unsigned{
79FS.makeAbsolute(DirPath);
80path::remove_dots(DirPath,
true);
82 for(
autoNI = path::begin(
File), NE = path::end(
File),
83DI = path::begin(Dir), DE = path::end(Dir);
86 while(NI != NE && *NI ==
".")
92 while(DI != DE && *DI ==
".")
98 returnNI - path::begin(
File);
101 if(NI->size() == 1 && DI->size() == 1 &&
102path::is_separator(NI->front()) && path::is_separator(DI->front()))
108 if(NI->ends_with(
".sdk") && DI->ends_with(
".sdk")) {
109StringRef NBasename = path::stem(*NI);
110StringRef DBasename = path::stem(*DI);
111 if(DBasename.starts_with(NBasename))
121 unsignedPrefixLength = 0;
134StringRef SpelledFilename = HMap->reverseLookupFilename(
File);
135 if(!SpelledFilename.empty())
136 returnSpelledFilename.str();
144PrefixLength = CheckDir(Entry.Path);
145 if(PrefixLength > 0) {
148 if(Entry.IsFramework) {
153 if(Matches.size() != 4)
156 returnpath::convert_to_slash(
157(Matches[1].drop_front(Matches[1].rfind(
'/') + 1) +
"/"+
164 returnpath::convert_to_slash(
File.drop_front(PrefixLength));
172std::optional<std::string> getRelativeIncludeName(
const CompilerInstance&CI,
174 bool*IsQuoted =
nullptr) {
178structLocationFileChecker {
183 autoFileLoc =
SM.getFileLoc(
Loc);
184 FileIDFID =
SM.getFileID(FileLoc);
192 if(KnownFileEntries.count(*
File))
195 if(ExternalFileEntries.count(*
File))
199 boolIsQuoted =
false;
200 if(
autoIncludeName = getRelativeIncludeName(CI, *
File, &IsQuoted))
201 if(llvm::any_of(KnownFiles,
202[&IsQuoted, &IncludeName](
const auto&KnownFile) {
203 returnKnownFile.first.equals(*IncludeName) &&
204KnownFile.second == IsQuoted;
206KnownFileEntries.insert(*
File);
212ExternalFileEntries.insert(*
File);
218: CI(CI), KnownFiles(KnownFiles), ExternalFileEntries() {
219 for(
const auto&KnownFile : KnownFiles)
221KnownFileEntries.insert(*FE);
227llvm::DenseSet<const FileEntry *> KnownFileEntries;
228llvm::DenseSet<const FileEntry *> ExternalFileEntries;
233 boolShouldBeIncluded =
true;
235 if(
auto*TD = llvm::dyn_cast<TagDecl>(
D))
236ShouldBeIncluded = TD->isThisDeclarationADefinition();
237 else if(
auto*
Interface= llvm::dyn_cast<ObjCInterfaceDecl>(
D))
238ShouldBeIncluded =
Interface->isThisDeclarationADefinition();
239 else if(
auto*Protocol = llvm::dyn_cast<ObjCProtocolDecl>(
D))
240ShouldBeIncluded =
Protocol->isThisDeclarationADefinition();
242ShouldBeIncluded = ShouldBeIncluded && LCF(
D->
getLocation());
243 returnShouldBeIncluded;
246BatchExtractAPIVisitor(LocationFileChecker &LCF,
ASTContext&Context,
251LocationFileChecker &LCF;
254classWrappingExtractAPIConsumer :
public ASTConsumer{
257: Visitor(Context, API) {}
271std::unique_ptr<LocationFileChecker> LCF,
APISet&API)
272: Visitor(*LCF, Context, API), LCF(
std::move(LCF)) {}
280BatchExtractAPIVisitor Visitor;
281std::unique_ptr<LocationFileChecker> LCF;
287:
SM(
SM), API(API), PP(PP) {}
290 for(
const auto&M : PP.macros()) {
291 auto*II = M.getFirst();
292 autoMD = PP.getMacroDefinition(II);
293 auto*MI = MD.getMacroInfo();
299 if(MI->isUsedForHeaderGuard())
303 if(MI->isBuiltinMacro())
306 autoDefLoc = MI->getDefinitionLoc();
308 if(
SM.isWrittenInBuiltinFile(DefLoc) ||
309 SM.isWrittenInCommandLineFile(DefLoc))
312 autoAssociatedModuleMacros = MD.getModuleMacros();
313StringRef OwningModuleName;
314 if(!AssociatedModuleMacros.empty())
315OwningModuleName = AssociatedModuleMacros.back()
317->getTopLevelModuleName();
319 if(!shouldMacroBeIncluded(DefLoc, OwningModuleName))
322StringRef Name = II->getName();
330 SM.isInSystemHeader(DefLoc));
334 virtual boolshouldMacroBeIncluded(
const SourceLocation&MacroLoc,
335StringRef ModuleName) {
344classAPIMacroCallback :
publicMacroCallback {
347LocationFileChecker &LCF)
348: MacroCallback(
SM, API, PP), LCF(LCF) {}
351StringRef ModuleName)
override{
353 returnLCF(MacroLoc);
357LocationFileChecker &LCF;
360std::unique_ptr<llvm::raw_pwrite_stream>
365llvm::sys::path::append(
FileName, OutputDirectory,
366BaseName +
".symbols.json");
381 autoConstructOutputFile = [&CI](Twine BaseName) {
382 returncreateAdditionalSymbolGraphFile(CI, BaseName);
389SerializationOptions);
396std::unique_ptr<ASTConsumer>
413 API= std::make_unique<APISet>(
417 autoLCF = std::make_unique<LocationFileChecker>(CI, KnownInputFiles);
428llvm::handleAllErrors(
433CI.getDiagnostics().Report(
434diag::err_extract_api_ignores_file_not_found)
439 returnstd::make_unique<ExtractAPIConsumer>(CI.
getASTContext(),
440std::move(LCF), *
API);
452 autoKind = Inputs[0].getKind();
456 boolIsQuoted =
false;
458 if(Kind.isObjectiveC())
459HeaderContents +=
"#import";
461HeaderContents +=
"#include";
463StringRef FilePath = FIF.getFile();
464 if(
autoRelativeName = getRelativeIncludeName(CI, FilePath, &IsQuoted)) {
466HeaderContents +=
" \"";
468HeaderContents +=
" <";
470HeaderContents += *RelativeName;
473HeaderContents +=
"\"\n";
475HeaderContents +=
">\n";
476KnownInputFiles.emplace_back(
static_cast<SmallString<32>>(*RelativeName),
479HeaderContents +=
" \"";
480HeaderContents += FilePath;
481HeaderContents +=
"\"\n";
482KnownInputFiles.emplace_back(FilePath,
true);
488<< HeaderContents <<
"\n";
490 Buffer= llvm::MemoryBuffer::getMemBufferCopy(HeaderContents,
491getInputBufferName());
495Inputs.emplace_back(
Buffer->getMemBufferRef(), Kind,
false);
500voidExtractAPIAction::EndSourceFileAction() {
504std::unique_ptr<ASTConsumer>
511CreatedASTConsumer =
true;
514 autoInputFilename = llvm::sys::path::filename(InFile);
515 OS= createAdditionalSymbolGraphFile(CI, InputFilename);
519 API= std::make_unique<APISet>(
532llvm::handleAllErrors(
537CI.getDiagnostics().Report(
538diag::err_extract_api_ignores_file_not_found)
543 autoWrappingConsumer =
545std::vector<std::unique_ptr<ASTConsumer>> Consumers;
546Consumers.push_back(std::move(OtherConsumer));
547Consumers.push_back(std::move(WrappingConsumer));
549 returnstd::make_unique<MultiplexConsumer>(std::move(Consumers));
552voidWrappingExtractAPIAction::EndSourceFileAction() {
556 if(CreatedASTConsumer) {
This file defines the APIRecord-based structs and the APISet class.
This file provides AST data structures related to concepts.
Defines the clang::ASTContext interface.
Defines interfaces for clang::FileEntry and clang::FileEntryRef.
Defines the clang::MacroInfo and clang::MacroDirective classes.
Defines the PPCallbacks interface.
Defines the clang::Preprocessor interface.
Defines the clang::SourceLocation class and associated facilities.
Defines the SourceManager interface.
This file defines the SymbolGraphSerializer class.
ASTConsumer - This is an abstract interface that should be implemented by clients that read ASTs.
virtual void HandleTranslationUnit(ASTContext &Ctx)
HandleTranslationUnit - This method is called when the ASTs for entire translation unit have been par...
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
TranslationUnitDecl * getTranslationUnitDecl() const
const clang::PrintingPolicy & getPrintingPolicy() const
void setPrintingPolicy(const clang::PrintingPolicy &Policy)
CompilerInstance - Helper class for managing a single instance of the Clang compiler.
FileManager * createFileManager(IntrusiveRefCntPtr< llvm::vfs::FileSystem > VFS=nullptr)
Create the file manager and replace any existing one with it.
bool hasFileManager() const
raw_ostream & getVerboseOutputStream()
Get the current stream for verbose output.
std::unique_ptr< raw_pwrite_stream > createDefaultOutputFile(bool Binary=true, StringRef BaseInput="", StringRef Extension="", bool RemoveFileOnSignal=true, bool CreateMissingDirectories=false, bool ForceUseTemporary=false)
Create the default output file (from the invocation's options) and add it to the list of tracked outp...
FileManager & getFileManager() const
Return the current file manager to the caller.
std::unique_ptr< raw_pwrite_stream > createOutputFile(StringRef OutputPath, bool Binary, bool RemoveFileOnSignal, bool UseTemporary, bool CreateMissingDirectories=false)
Create a new output file, optionally deriving the output path name, and add it to the list of tracked...
Preprocessor & getPreprocessor() const
Return the current preprocessor.
ASTContext & getASTContext() const
FrontendOptions & getFrontendOpts()
HeaderSearchOptions & getHeaderSearchOpts()
TargetInfo & getTarget() const
llvm::vfs::FileSystem & getVirtualFileSystem() const
SourceManager & getSourceManager() const
Return the current source manager.
Decl - This represents one declaration (or definition), e.g.
SourceLocation getLocation() const
A reference to a FileEntry that includes the name of the file as it was accessed by the FileManager's...
StringRef getNameAsRequested() const
The name of this FileEntry, as originally requested without applying any remappings for VFS 'use-exte...
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
OptionalFileEntryRef getOptionalFileRef(StringRef Filename, bool OpenFile=false, bool CacheFailure=true)
Get a FileEntryRef if it exists, without doing anything on error.
CompilerInstance & getCompilerInstance() const
An input file for the front end.
unsigned EmitSymbolGraphSymbolLabelsForTesting
Whether to emit symbol labels for testing in generated symbol graphs.
std::string ProductName
The name of the product the input files belong too.
std::string SymbolGraphOutputDir
unsigned EmitExtensionSymbolGraphs
Whether to emit additional symbol graphs for extended modules.
SmallVector< FrontendInputFile, 0 > Inputs
The input files and their types.
unsigned EmitPrettySymbolGraphs
Whether to emit symbol labels for testing in generated symbol graphs.
std::vector< std::string > ExtractAPIIgnoresFileList
This interface provides a way to observe the actions of the preprocessor as it does its thing.
virtual void EndOfMainFile()
Callback invoked when the end of the main file is reached.
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
void addPPCallbacks(std::unique_ptr< PPCallbacks > C)
Represents an unpacked "presumed" location which can be presented to the user.
Encodes a location in the source.
This class handles loading and caching of source files into memory.
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
void EndSourceFileAction() override
Callback at the end of processing a single input.
std::unique_ptr< ASTConsumer > CreateASTConsumer(CompilerInstance &CI, StringRef InFile) override
Create the AST consumer object for this action, if supported.
Defines the clang::TargetInfo interface.
@ Quoted
'#include ""' paths, added by 'gcc -iquote'.
bool generateUSRForMacro(const MacroDefinitionRecord *MD, const SourceManager &SM, SmallVectorImpl< char > &Buf)
Generate a USR for a macro, including the USR prefix.
The JSON file list parser is used to communicate input to InstallAPI.
@ Interface
The "__interface" keyword introduces the elaborated-type-specifier.
Describes how types, statements, expressions, and declarations should be printed.
unsigned AnonymousTagLocations
When printing an anonymous tag name, also print the location of that entity (e.g.,...
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4