dang created this revision. dang added reviewers: zixuw, ributzka, QuietMisdreavus. Herald added a project: All. dang requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits.
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. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D122648 Files: clang/include/clang/ExtractAPI/FrontendActions.h clang/lib/ExtractAPI/ExtractAPIConsumer.cpp
Index: clang/lib/ExtractAPI/ExtractAPIConsumer.cpp =================================================================== --- clang/lib/ExtractAPI/ExtractAPIConsumer.cpp +++ clang/lib/ExtractAPI/ExtractAPIConsumer.cpp @@ -41,9 +41,8 @@ /// information. class ExtractAPIVisitor : public RecursiveASTVisitor<ExtractAPIVisitor> { public: - explicit ExtractAPIVisitor(ASTContext &Context) - : Context(Context), - API(Context.getTargetInfo().getTriple(), Context.getLangOpts()) {} + ExtractAPIVisitor(ASTContext &Context, APISet &API) + : Context(Context), API(API) {} const APISet &getAPI() const { return API; } @@ -304,42 +303,39 @@ } ASTContext &Context; - APISet API; + APISet &API; }; class ExtractAPIConsumer : public ASTConsumer { public: - ExtractAPIConsumer(ASTContext &Context, StringRef ProductName, - std::unique_ptr<raw_pwrite_stream> OS) - : Visitor(Context), 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, - 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.getLangOpts()); + + return std::make_unique<ExtractAPIConsumer>(CI.getASTContext(), *API); } bool ExtractAPIAction::PrepareToExecuteAction(CompilerInstance &CI) { @@ -371,6 +367,18 @@ 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 = Index: clang/include/clang/ExtractAPI/FrontendActions.h =================================================================== --- clang/include/clang/ExtractAPI/FrontendActions.h +++ 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,15 @@ StringRef InFile) override; private: - /// The synthesized input buffer that contains all the provided input header - /// files. - std::unique_ptr<llvm::MemoryBuffer> Buffer; + /// 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; -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 +42,15 @@ /// 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>"; } };
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits