diff options
Diffstat (limited to 'contrib/llvm-project/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp')
-rw-r--r-- | contrib/llvm-project/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp | 119 |
1 files changed, 56 insertions, 63 deletions
diff --git a/contrib/llvm-project/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp b/contrib/llvm-project/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp index fd62d841197d..d6335854cbf2 100644 --- a/contrib/llvm-project/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp +++ b/contrib/llvm-project/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp @@ -30,6 +30,8 @@ #include "clang/Frontend/CompilerInstance.h" #include "clang/Frontend/FrontendOptions.h" #include "clang/Frontend/MultiplexConsumer.h" +#include "clang/Index/USRGeneration.h" +#include "clang/InstallAPI/HeaderFile.h" #include "clang/Lex/MacroInfo.h" #include "clang/Lex/PPCallbacks.h" #include "clang/Lex/Preprocessor.h" @@ -38,6 +40,7 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringRef.h" #include "llvm/Support/Casting.h" #include "llvm/Support/Error.h" #include "llvm/Support/FileSystem.h" @@ -61,9 +64,6 @@ std::optional<std::string> getRelativeIncludeName(const CompilerInstance &CI, "CompilerInstance does not have a FileNamager!"); using namespace llvm::sys; - // Matches framework include patterns - const llvm::Regex Rule("/(.+)\\.framework/(.+)?Headers/(.+)"); - const auto &FS = CI.getVirtualFileSystem(); SmallString<128> FilePath(File.begin(), File.end()); @@ -147,7 +147,8 @@ std::optional<std::string> getRelativeIncludeName(const CompilerInstance &CI, // include name `<Framework/Header.h>` if (Entry.IsFramework) { SmallVector<StringRef, 4> Matches; - Rule.match(File, &Matches); + clang::installapi::HeaderFile::getFrameworkIncludeRule().match( + File, &Matches); // Returned matches are always in stable order. if (Matches.size() != 4) return std::nullopt; @@ -328,11 +329,12 @@ public: StringRef Name = PM.MacroNameToken.getIdentifierInfo()->getName(); PresumedLoc Loc = SM.getPresumedLoc(PM.MacroNameToken.getLocation()); - StringRef USR = - API.recordUSRForMacro(Name, PM.MacroNameToken.getLocation(), SM); + SmallString<128> USR; + index::generateUSRForMacro(Name, PM.MacroNameToken.getLocation(), SM, + USR); - API.addMacroDefinition( - Name, USR, Loc, + API.createRecord<extractapi::MacroDefinitionRecord>( + USR, Name, SymbolReference(), Loc, DeclarationFragmentsBuilder::getFragmentsForMacro(Name, PM.MD), DeclarationFragmentsBuilder::getSubHeadingForMacro(Name), SM.isInSystemHeader(PM.MacroNameToken.getLocation())); @@ -373,40 +375,57 @@ private: LocationFileChecker &LCF; }; +std::unique_ptr<llvm::raw_pwrite_stream> +createAdditionalSymbolGraphFile(CompilerInstance &CI, Twine BaseName) { + auto OutputDirectory = CI.getFrontendOpts().SymbolGraphOutputDir; + + SmallString<256> FileName; + llvm::sys::path::append(FileName, OutputDirectory, + BaseName + ".symbols.json"); + return CI.createOutputFile( + FileName, /*Binary*/ false, /*RemoveFileOnSignal*/ false, + /*UseTemporary*/ true, /*CreateMissingDirectories*/ true); +} + } // namespace -void ExtractAPIActionBase::ImplEndSourceFileAction() { - if (!OS) - return; +void ExtractAPIActionBase::ImplEndSourceFileAction(CompilerInstance &CI) { + SymbolGraphSerializerOption SerializationOptions; + SerializationOptions.Compact = !CI.getFrontendOpts().EmitPrettySymbolGraphs; + SerializationOptions.EmitSymbolLabelsForTesting = + CI.getFrontendOpts().EmitSymbolGraphSymbolLabelsForTesting; + + if (CI.getFrontendOpts().EmitExtensionSymbolGraphs) { + auto ConstructOutputFile = [&CI](Twine BaseName) { + return createAdditionalSymbolGraphFile(CI, BaseName); + }; + + SymbolGraphSerializer::serializeWithExtensionGraphs( + *OS, *API, IgnoresList, ConstructOutputFile, SerializationOptions); + } else { + SymbolGraphSerializer::serializeMainSymbolGraph(*OS, *API, IgnoresList, + SerializationOptions); + } - // Setup a SymbolGraphSerializer to write out collected API information in - // the Symbol Graph format. - // FIXME: Make the kind of APISerializer configurable. - SymbolGraphSerializer SGSerializer(*API, IgnoresList); - SGSerializer.serialize(*OS); + // Flush the stream and close the main output stream. OS.reset(); } -std::unique_ptr<raw_pwrite_stream> -ExtractAPIAction::CreateOutputFile(CompilerInstance &CI, StringRef InFile) { - std::unique_ptr<raw_pwrite_stream> OS; - OS = CI.createDefaultOutputFile(/*Binary=*/false, InFile, - /*Extension=*/"json", - /*RemoveFileOnSignal=*/false); - if (!OS) - return nullptr; - return OS; -} - std::unique_ptr<ASTConsumer> ExtractAPIAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { - OS = CreateOutputFile(CI, InFile); + auto ProductName = CI.getFrontendOpts().ProductName; + + if (CI.getFrontendOpts().SymbolGraphOutputDir.empty()) + OS = CI.createDefaultOutputFile(/*Binary*/ false, InFile, + /*Extension*/ "symbols.json", + /*RemoveFileOnSignal*/ false, + /*CreateMissingDirectories*/ true); + else + OS = createAdditionalSymbolGraphFile(CI, ProductName); if (!OS) return nullptr; - auto ProductName = CI.getFrontendOpts().ProductName; - // Now that we have enough information about the language options and the // target triple, let's create the APISet before anyone uses it. API = std::make_unique<APISet>( @@ -496,7 +515,9 @@ bool ExtractAPIAction::PrepareToExecuteAction(CompilerInstance &CI) { return true; } -void ExtractAPIAction::EndSourceFileAction() { ImplEndSourceFileAction(); } +void ExtractAPIAction::EndSourceFileAction() { + ImplEndSourceFileAction(getCompilerInstance()); +} std::unique_ptr<ASTConsumer> WrappingExtractAPIAction::CreateASTConsumer(CompilerInstance &CI, @@ -507,11 +528,9 @@ WrappingExtractAPIAction::CreateASTConsumer(CompilerInstance &CI, CreatedASTConsumer = true; - OS = CreateOutputFile(CI, InFile); - if (!OS) - return nullptr; - - auto ProductName = CI.getFrontendOpts().ProductName; + ProductName = CI.getFrontendOpts().ProductName; + auto InputFilename = llvm::sys::path::filename(InFile); + OS = createAdditionalSymbolGraphFile(CI, InputFilename); // Now that we have enough information about the language options and the // target triple, let's create the APISet before anyone uses it. @@ -553,32 +572,6 @@ void WrappingExtractAPIAction::EndSourceFileAction() { WrapperFrontendAction::EndSourceFileAction(); if (CreatedASTConsumer) { - ImplEndSourceFileAction(); + ImplEndSourceFileAction(getCompilerInstance()); } } - -std::unique_ptr<raw_pwrite_stream> -WrappingExtractAPIAction::CreateOutputFile(CompilerInstance &CI, - StringRef InFile) { - std::unique_ptr<raw_pwrite_stream> OS; - std::string OutputDir = CI.getFrontendOpts().SymbolGraphOutputDir; - - // The symbol graphs need to be generated as a side effect of regular - // compilation so the output should be dumped in the directory provided with - // the command line option. - llvm::SmallString<128> OutFilePath(OutputDir); - auto Seperator = llvm::sys::path::get_separator(); - auto Infilename = llvm::sys::path::filename(InFile); - OutFilePath.append({Seperator, Infilename}); - llvm::sys::path::replace_extension(OutFilePath, "json"); - // StringRef outputFilePathref = *OutFilePath; - - // don't use the default output file - OS = CI.createOutputFile(/*OutputPath=*/OutFilePath, /*Binary=*/false, - /*RemoveFileOnSignal=*/true, - /*UseTemporary=*/true, - /*CreateMissingDirectories=*/true); - if (!OS) - return nullptr; - return OS; -} |