Author: Daniel Grumberg Date: 2022-03-30T18:32:58+01:00 New Revision: a9909d23e9bb8c4649cba1c14d479c28df4ca185
URL: https://github.com/llvm/llvm-project/commit/a9909d23e9bb8c4649cba1c14d479c28df4ca185 DIFF: https://github.com/llvm/llvm-project/commit/a9909d23e9bb8c4649cba1c14d479c28df4ca185.diff LOG: [clang][extractapi] Tie API and serialization to the FrontendAction Make the API records a property of the action instead of the ASTVisitor so that it can be accessed outside the AST visitation and push back serialization to the end of the frontend action. This will allow accessing and modifying the API records outside of the ASTVisitor, which is a prerequisite for supporting macros. Added: Modified: clang/include/clang/ExtractAPI/FrontendActions.h clang/lib/ExtractAPI/ExtractAPIConsumer.cpp Removed: ################################################################################ diff --git a/clang/include/clang/ExtractAPI/FrontendActions.h b/clang/include/clang/ExtractAPI/FrontendActions.h index 4c9449fe73a92..2bdb61dc6994d 100644 --- a/clang/include/clang/ExtractAPI/FrontendActions.h +++ b/clang/include/clang/ExtractAPI/FrontendActions.h @@ -14,6 +14,7 @@ #ifndef LLVM_CLANG_EXTRACTAPI_FRONTEND_ACTIONS_H #define LLVM_CLANG_EXTRACTAPI_FRONTEND_ACTIONS_H +#include "clang/ExtractAPI/API.h" #include "clang/Frontend/FrontendAction.h" namespace clang { @@ -25,11 +26,19 @@ class ExtractAPIAction : public ASTFrontendAction { StringRef InFile) override; private: + /// A representation of the APIs this action extracts. + std::unique_ptr<extractapi::APISet> API; + + /// A stream to the output file of this action. + std::unique_ptr<raw_pwrite_stream> OS; + + /// The product this action is extracting API information for. + std::string ProductName; + /// The synthesized input buffer that contains all the provided input header /// files. std::unique_ptr<llvm::MemoryBuffer> Buffer; -public: /// Prepare to execute the action on the given CompilerInstance. /// /// This is called before executing the action on any inputs. This generates a @@ -37,8 +46,15 @@ class ExtractAPIAction : public ASTFrontendAction { /// list with it before actually executing the action. bool PrepareToExecuteAction(CompilerInstance &CI) override; + /// Called after executing the action on the synthesized input buffer. + /// + /// Note: Now that we have gathered all the API definitions to surface we can + /// emit them in this callback. + void EndSourceFileAction() override; + static std::unique_ptr<llvm::raw_pwrite_stream> CreateOutputFile(CompilerInstance &CI, StringRef InFile); + static StringRef getInputBufferName() { return "<extract-api-includes>"; } }; diff --git a/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp b/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp index bcc01dbd710d8..10b28873611e9 100644 --- a/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp +++ b/clang/lib/ExtractAPI/ExtractAPIConsumer.cpp @@ -41,8 +41,8 @@ namespace { /// information. class ExtractAPIVisitor : public RecursiveASTVisitor<ExtractAPIVisitor> { public: - ExtractAPIVisitor(ASTContext &Context, Language Lang) - : Context(Context), API(Context.getTargetInfo().getTriple(), Lang) {} + ExtractAPIVisitor(ASTContext &Context, APISet &API) + : Context(Context), API(API) {} const APISet &getAPI() const { return API; } @@ -489,43 +489,40 @@ class ExtractAPIVisitor : public RecursiveASTVisitor<ExtractAPIVisitor> { } ASTContext &Context; - APISet API; + APISet &API; }; class ExtractAPIConsumer : public ASTConsumer { public: - ExtractAPIConsumer(ASTContext &Context, StringRef ProductName, Language Lang, - std::unique_ptr<raw_pwrite_stream> OS) - : Visitor(Context, Lang), ProductName(ProductName), OS(std::move(OS)) {} + ExtractAPIConsumer(ASTContext &Context, APISet &API) + : Visitor(Context, API) {} void HandleTranslationUnit(ASTContext &Context) override { // Use ExtractAPIVisitor to traverse symbol declarations in the context. Visitor.TraverseDecl(Context.getTranslationUnitDecl()); - - // Setup a SymbolGraphSerializer to write out collected API information in - // the Symbol Graph format. - // FIXME: Make the kind of APISerializer configurable. - SymbolGraphSerializer SGSerializer(Visitor.getAPI(), ProductName); - SGSerializer.serialize(*OS); } private: ExtractAPIVisitor Visitor; - std::string ProductName; - std::unique_ptr<raw_pwrite_stream> OS; }; } // namespace std::unique_ptr<ASTConsumer> ExtractAPIAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { - std::unique_ptr<raw_pwrite_stream> OS = CreateOutputFile(CI, InFile); + OS = CreateOutputFile(CI, InFile); if (!OS) return nullptr; - return std::make_unique<ExtractAPIConsumer>( - CI.getASTContext(), CI.getInvocation().getFrontendOpts().ProductName, - CI.getFrontendOpts().Inputs.back().getKind().getLanguage(), - std::move(OS)); + + 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>( + CI.getTarget().getTriple(), + CI.getFrontendOpts().Inputs.back().getKind().getLanguage()); + + return std::make_unique<ExtractAPIConsumer>(CI.getASTContext(), *API); } bool ExtractAPIAction::PrepareToExecuteAction(CompilerInstance &CI) { @@ -557,6 +554,18 @@ bool ExtractAPIAction::PrepareToExecuteAction(CompilerInstance &CI) { return true; } +void ExtractAPIAction::EndSourceFileAction() { + if (!OS) + return; + + // Setup a SymbolGraphSerializer to write out collected API information in + // the Symbol Graph format. + // FIXME: Make the kind of APISerializer configurable. + SymbolGraphSerializer SGSerializer(*API, ProductName); + SGSerializer.serialize(*OS); + OS->flush(); +} + std::unique_ptr<raw_pwrite_stream> ExtractAPIAction::CreateOutputFile(CompilerInstance &CI, StringRef InFile) { std::unique_ptr<raw_pwrite_stream> OS = _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits