Skip to content

Commit

Permalink
[clang][ExtractAPI] Refactor ExtractAPIVisitor to make it more extens…
Browse files Browse the repository at this point in the history
…ible

Use CRTP to enable creating statically dispatched subclasses of
ExtractAPIVisitor.
This enables adding extension points and customising the behavior more
easily.

This is used in CXExtractAPI.cpp to create a specialized visitor for
Libclang as well as streamlining the batch implementation in ExtractAPIConsumer.cpp
  • Loading branch information
daniel-grumberg committed Mar 27, 2023
1 parent 0ceb7a1 commit ea35740
Show file tree
Hide file tree
Showing 8 changed files with 692 additions and 610 deletions.
573 changes: 562 additions & 11 deletions clang/include/clang/ExtractAPI/ExtractAPIVisitor.h

Large diffs are not rendered by default.

1 change: 0 additions & 1 deletion clang/lib/ExtractAPI/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ add_clang_library(clangExtractAPI
APIIgnoresList.cpp
AvailabilityInfo.cpp
ExtractAPIConsumer.cpp
ExtractAPIVisitor.cpp
DeclarationFragments.cpp
Serialization/SerializerBase.cpp
Serialization/SymbolGraphSerializer.cpp
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/ExtractAPI/DeclarationFragments.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
//===----------------------------------------------------------------------===//

#include "clang/ExtractAPI/DeclarationFragments.h"
#include "TypedefUnderlyingTypeResolver.h"
#include "clang/ExtractAPI/TypedefUnderlyingTypeResolver.h"
#include "clang/Index/USRGeneration.h"
#include "llvm/ADT/StringSwitch.h"

Expand Down
32 changes: 29 additions & 3 deletions clang/lib/ExtractAPI/ExtractAPIConsumer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@
///
//===----------------------------------------------------------------------===//

#include "clang/AST/ASTConcept.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/DeclObjC.h"
#include "clang/Basic/DiagnosticFrontend.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/SourceManager.h"
Expand All @@ -33,6 +35,7 @@
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/MemoryBuffer.h"
Expand Down Expand Up @@ -164,7 +167,7 @@ std::optional<std::string> getRelativeIncludeName(const CompilerInstance &CI,

struct LocationFileChecker {
bool operator()(SourceLocation Loc) {
// If the loc refers to a macro expansion we need to first get the file
// If the loc refersSourceLocationxpansion we need to first get the file
// location of the expansion.
auto &SM = CI.getSourceManager();
auto FileLoc = SM.getFileLoc(Loc);
Expand Down Expand Up @@ -219,19 +222,42 @@ struct LocationFileChecker {
llvm::DenseSet<const FileEntry *> ExternalFileEntries;
};

struct BatchExtractAPIVisitor : ExtractAPIVisitor<BatchExtractAPIVisitor> {
bool shouldDeclBeIncluded(const Decl *D) const {
bool ShouldBeIncluded = true;
// Check that we have the definition for redeclarable types.
if (auto *TD = llvm::dyn_cast<TagDecl>(D))
ShouldBeIncluded = TD->isThisDeclarationADefinition();
else if (auto *Interface = llvm::dyn_cast<ObjCInterfaceDecl>(D))
ShouldBeIncluded = Interface->isThisDeclarationADefinition();
else if (auto *Protocol = llvm::dyn_cast<ObjCProtocolDecl>(D))
ShouldBeIncluded = Protocol->isThisDeclarationADefinition();

ShouldBeIncluded = ShouldBeIncluded && LCF(D->getLocation());
return ShouldBeIncluded;
}

BatchExtractAPIVisitor(LocationFileChecker &LCF, ASTContext &Context,
APISet &API)
: ExtractAPIVisitor<BatchExtractAPIVisitor>(Context, API), LCF(LCF) {}

private:
LocationFileChecker &LCF;
};

class ExtractAPIConsumer : public ASTConsumer {
public:
ExtractAPIConsumer(ASTContext &Context,
std::unique_ptr<LocationFileChecker> LCF, APISet &API)
: Visitor(Context, *LCF, API), LCF(std::move(LCF)) {}
: Visitor(*LCF, Context, API), LCF(std::move(LCF)) {}

void HandleTranslationUnit(ASTContext &Context) override {
// Use ExtractAPIVisitor to traverse symbol declarations in the context.
Visitor.TraverseDecl(Context.getTranslationUnitDecl());
}

private:
ExtractAPIVisitor Visitor;
BatchExtractAPIVisitor Visitor;
std::unique_ptr<LocationFileChecker> LCF;
};

Expand Down

0 comments on commit ea35740

Please sign in to comment.