2019-06-25 20:48:56 +08:00
|
|
|
// Copyright 2020 Google LLC
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
// you may not use this file except in compliance with the License.
|
|
|
|
// You may obtain a copy of the License at
|
|
|
|
//
|
2022-01-28 17:38:27 +08:00
|
|
|
// https://www.apache.org/licenses/LICENSE-2.0
|
2019-06-25 20:48:56 +08:00
|
|
|
//
|
|
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
// See the License for the specific language governing permissions and
|
|
|
|
// limitations under the License.
|
|
|
|
|
|
|
|
#ifndef SANDBOXED_API_TOOLS_CLANG_GENERATOR_GENERATOR_H_
|
|
|
|
#define SANDBOXED_API_TOOLS_CLANG_GENERATOR_GENERATOR_H_
|
|
|
|
|
2022-10-12 20:22:51 +08:00
|
|
|
#include <memory>
|
2019-06-25 20:48:56 +08:00
|
|
|
#include <string>
|
2023-08-24 21:23:03 +08:00
|
|
|
#include <utility>
|
|
|
|
#include <vector>
|
2019-06-25 20:48:56 +08:00
|
|
|
|
|
|
|
#include "absl/container/flat_hash_set.h"
|
2022-03-02 21:17:10 +08:00
|
|
|
#include "absl/strings/string_view.h"
|
2019-06-25 20:48:56 +08:00
|
|
|
#include "clang/AST/ASTConsumer.h"
|
2022-11-15 00:18:42 +08:00
|
|
|
#include "clang/AST/Decl.h"
|
2019-06-25 20:48:56 +08:00
|
|
|
#include "clang/AST/RecursiveASTVisitor.h"
|
|
|
|
#include "clang/Frontend/CompilerInstance.h"
|
2022-03-17 17:31:29 +08:00
|
|
|
#include "clang/Frontend/CompilerInvocation.h"
|
2019-06-25 20:48:56 +08:00
|
|
|
#include "clang/Frontend/FrontendAction.h"
|
2023-06-13 16:03:52 +08:00
|
|
|
#include "clang/Lex/Preprocessor.h"
|
2019-06-25 20:48:56 +08:00
|
|
|
#include "clang/Tooling/Tooling.h"
|
2020-09-25 16:13:50 +08:00
|
|
|
#include "sandboxed_api/tools/clang_generator/emitter.h"
|
2019-06-25 20:48:56 +08:00
|
|
|
#include "sandboxed_api/tools/clang_generator/types.h"
|
|
|
|
|
|
|
|
namespace sapi {
|
|
|
|
|
|
|
|
struct GeneratorOptions {
|
|
|
|
template <typename ContainerT>
|
|
|
|
GeneratorOptions& set_function_names(const ContainerT& value) {
|
|
|
|
function_names.clear();
|
|
|
|
function_names.insert(std::begin(value), std::end(value));
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2022-11-24 01:09:09 +08:00
|
|
|
template <typename ContainerT>
|
|
|
|
GeneratorOptions& set_in_files(const ContainerT& value) {
|
|
|
|
in_files.clear();
|
|
|
|
in_files.insert(std::begin(value), std::end(value));
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
GeneratorOptions& set_limit_scan_depth(bool value) {
|
|
|
|
limit_scan_depth = value;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2019-06-25 20:48:56 +08:00
|
|
|
bool has_namespace() const { return !namespace_name.empty(); }
|
|
|
|
|
|
|
|
absl::flat_hash_set<std::string> function_names;
|
2022-11-24 01:09:09 +08:00
|
|
|
absl::flat_hash_set<std::string> in_files;
|
|
|
|
bool limit_scan_depth = false;
|
2019-06-25 20:48:56 +08:00
|
|
|
|
|
|
|
// Output options
|
|
|
|
std::string work_dir;
|
|
|
|
std::string name; // Name of the Sandboxed API
|
|
|
|
std::string namespace_name; // Namespace to wrap the SAPI in
|
2020-09-25 16:13:50 +08:00
|
|
|
// Output path of the generated header. Used to build the header include
|
|
|
|
// guard.
|
2022-11-01 23:59:48 +08:00
|
|
|
std::string out_file = "out_file.cc";
|
2020-09-25 16:13:50 +08:00
|
|
|
std::string embed_dir; // Directory with embedded includes
|
|
|
|
std::string embed_name; // Identifier of the embed object
|
2019-06-25 20:48:56 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
class GeneratorASTVisitor
|
|
|
|
: public clang::RecursiveASTVisitor<GeneratorASTVisitor> {
|
|
|
|
public:
|
2020-09-25 16:13:50 +08:00
|
|
|
explicit GeneratorASTVisitor(const GeneratorOptions& options)
|
|
|
|
: options_(options) {}
|
|
|
|
|
2022-11-15 00:18:42 +08:00
|
|
|
bool VisitTypeDecl(clang::TypeDecl* decl);
|
2019-06-25 20:48:56 +08:00
|
|
|
bool VisitFunctionDecl(clang::FunctionDecl* decl);
|
|
|
|
|
2022-11-23 21:20:47 +08:00
|
|
|
TypeCollector& collector() { return collector_; }
|
2019-06-25 20:48:56 +08:00
|
|
|
|
2022-11-23 21:20:47 +08:00
|
|
|
const std::vector<clang::FunctionDecl*>& functions() const {
|
|
|
|
return functions_;
|
|
|
|
}
|
2020-10-06 16:04:11 +08:00
|
|
|
|
2022-11-23 21:20:47 +08:00
|
|
|
private:
|
|
|
|
TypeCollector collector_;
|
2019-06-25 20:48:56 +08:00
|
|
|
std::vector<clang::FunctionDecl*> functions_;
|
2020-09-25 16:13:50 +08:00
|
|
|
const GeneratorOptions& options_;
|
|
|
|
};
|
2019-06-25 20:48:56 +08:00
|
|
|
|
|
|
|
class GeneratorASTConsumer : public clang::ASTConsumer {
|
|
|
|
public:
|
2020-09-25 16:13:50 +08:00
|
|
|
GeneratorASTConsumer(std::string in_file, Emitter& emitter,
|
|
|
|
const GeneratorOptions& options)
|
|
|
|
: in_file_(std::move(in_file)), visitor_(options), emitter_(emitter) {}
|
2019-06-25 20:48:56 +08:00
|
|
|
|
|
|
|
private:
|
|
|
|
void HandleTranslationUnit(clang::ASTContext& context) override;
|
|
|
|
|
|
|
|
std::string in_file_;
|
|
|
|
GeneratorASTVisitor visitor_;
|
2020-09-25 16:13:50 +08:00
|
|
|
Emitter& emitter_;
|
2019-06-25 20:48:56 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
class GeneratorAction : public clang::ASTFrontendAction {
|
|
|
|
public:
|
2020-09-25 16:13:50 +08:00
|
|
|
GeneratorAction(Emitter& emitter, const GeneratorOptions& options)
|
|
|
|
: emitter_(emitter), options_(options) {}
|
2019-06-25 20:48:56 +08:00
|
|
|
|
|
|
|
private:
|
|
|
|
std::unique_ptr<clang::ASTConsumer> CreateASTConsumer(
|
|
|
|
clang::CompilerInstance&, llvm::StringRef in_file) override {
|
2022-09-05 22:14:55 +08:00
|
|
|
return std::make_unique<GeneratorASTConsumer>(std::string(in_file),
|
|
|
|
emitter_, options_);
|
2019-06-25 20:48:56 +08:00
|
|
|
}
|
|
|
|
|
2023-06-13 16:03:52 +08:00
|
|
|
bool BeginSourceFileAction(clang::CompilerInstance& ci) override {
|
|
|
|
ci.getPreprocessor().enableIncrementalProcessing();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2019-06-25 20:48:56 +08:00
|
|
|
bool hasCodeCompletionSupport() const override { return false; }
|
|
|
|
|
2020-09-25 16:13:50 +08:00
|
|
|
Emitter& emitter_;
|
|
|
|
const GeneratorOptions& options_;
|
2019-06-25 20:48:56 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
class GeneratorFactory : public clang::tooling::FrontendActionFactory {
|
|
|
|
public:
|
2020-09-25 16:13:50 +08:00
|
|
|
// Does not take ownership
|
|
|
|
GeneratorFactory(Emitter& emitter, const GeneratorOptions& options)
|
|
|
|
: emitter_(emitter), options_(options) {}
|
2019-06-25 20:48:56 +08:00
|
|
|
|
|
|
|
private:
|
2020-06-10 14:30:55 +08:00
|
|
|
#if LLVM_VERSION_MAJOR >= 10
|
|
|
|
std::unique_ptr<clang::FrontendAction> create() override {
|
2022-09-05 22:14:55 +08:00
|
|
|
return std::make_unique<GeneratorAction>(emitter_, options_);
|
2020-06-10 14:30:55 +08:00
|
|
|
}
|
|
|
|
#else
|
2019-06-25 20:48:56 +08:00
|
|
|
clang::FrontendAction* create() override {
|
2020-09-25 16:13:50 +08:00
|
|
|
return new GeneratorAction(emitter_, options_);
|
2019-06-25 20:48:56 +08:00
|
|
|
}
|
2020-06-10 14:30:55 +08:00
|
|
|
#endif
|
2019-06-25 20:48:56 +08:00
|
|
|
|
2022-03-17 17:31:29 +08:00
|
|
|
bool runInvocation(
|
|
|
|
std::shared_ptr<clang::CompilerInvocation> invocation,
|
|
|
|
clang::FileManager* files,
|
|
|
|
std::shared_ptr<clang::PCHContainerOperations> pch_container_ops,
|
|
|
|
clang::DiagnosticConsumer* diag_consumer) override;
|
|
|
|
|
2020-09-25 16:13:50 +08:00
|
|
|
Emitter& emitter_;
|
|
|
|
const GeneratorOptions& options_;
|
2019-06-25 20:48:56 +08:00
|
|
|
};
|
|
|
|
|
2020-09-25 16:13:50 +08:00
|
|
|
std::string GetOutputFilename(absl::string_view source_file);
|
|
|
|
|
2022-03-02 21:17:10 +08:00
|
|
|
inline absl::string_view ToStringView(llvm::StringRef ref) {
|
|
|
|
return absl::string_view(ref.data(), ref.size());
|
|
|
|
}
|
|
|
|
|
2019-06-25 20:48:56 +08:00
|
|
|
} // namespace sapi
|
|
|
|
|
2020-05-28 22:01:09 +08:00
|
|
|
#endif // SANDBOXED_API_TOOLS_CLANG_GENERATOR_GENERATOR_H_
|