Skip to content

Commit f833aab

Browse files
[clang][extract-api] Enable processing of multiple headers
Before actually executing the ExtractAPIAction, clear the CompilationInstance's input list and replace it with a single synthesized file that just includes (or imports in ObjC) all the inputs. Depends on D122141 Differential Revision: https://reviews.llvm.org/D122175
1 parent ebc8466 commit f833aab

File tree

3 files changed

+416
-0
lines changed

3 files changed

+416
-0
lines changed

clang/include/clang/ExtractAPI/FrontendActions.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,22 @@ class ExtractAPIAction : public ASTFrontendAction {
2424
std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
2525
StringRef InFile) override;
2626

27+
private:
28+
/// The synthesized input buffer that contains all the provided input header
29+
/// files.
30+
std::unique_ptr<llvm::MemoryBuffer> Buffer;
31+
2732
public:
33+
/// Prepare to execute the action on the given CompilerInstance.
34+
///
35+
/// This is called before executing the action on any inputs. This generates a
36+
/// single header that includes all of CI's inputs and replaces CI's input
37+
/// list with it before actually executing the action.
38+
bool PrepareToExecuteAction(CompilerInstance &CI) override;
39+
2840
static std::unique_ptr<llvm::raw_pwrite_stream>
2941
CreateOutputFile(CompilerInstance &CI, StringRef InFile);
42+
static StringRef getInputBufferName() { return "<extract-api-includes>"; }
3043
};
3144

3245
} // namespace clang

clang/lib/ExtractAPI/ExtractAPIConsumer.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@
2727
#include "clang/ExtractAPI/Serialization/SymbolGraphSerializer.h"
2828
#include "clang/Frontend/ASTConsumers.h"
2929
#include "clang/Frontend/CompilerInstance.h"
30+
#include "clang/Frontend/FrontendOptions.h"
31+
#include "llvm/ADT/SmallVector.h"
32+
#include "llvm/Support/MemoryBuffer.h"
3033
#include "llvm/Support/raw_ostream.h"
3134

3235
using namespace clang;
@@ -339,6 +342,35 @@ ExtractAPIAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
339342
std::move(OS));
340343
}
341344

345+
bool ExtractAPIAction::PrepareToExecuteAction(CompilerInstance &CI) {
346+
auto &Inputs = CI.getFrontendOpts().Inputs;
347+
if (Inputs.empty())
348+
return true;
349+
350+
auto Kind = Inputs[0].getKind();
351+
352+
// Convert the header file inputs into a single input buffer.
353+
SmallString<256> HeaderContents;
354+
for (const FrontendInputFile &FIF : Inputs) {
355+
if (Kind.isObjectiveC())
356+
HeaderContents += "#import";
357+
else
358+
HeaderContents += "#include";
359+
HeaderContents += " \"";
360+
HeaderContents += FIF.getFile();
361+
HeaderContents += "\"\n";
362+
}
363+
364+
Buffer = llvm::MemoryBuffer::getMemBufferCopy(HeaderContents,
365+
getInputBufferName());
366+
367+
// Set that buffer up as our "real" input in the CompilerInstance.
368+
Inputs.clear();
369+
Inputs.emplace_back(Buffer->getMemBufferRef(), Kind, /*IsSystem*/ false);
370+
371+
return true;
372+
}
373+
342374
std::unique_ptr<raw_pwrite_stream>
343375
ExtractAPIAction::CreateOutputFile(CompilerInstance &CI, StringRef InFile) {
344376
std::unique_ptr<raw_pwrite_stream> OS =

0 commit comments

Comments
 (0)