blob: 1b473a5eabe1b69caf15464fed5b5a283df93c6d [file] [log] [blame] [edit]
// Part of the Crubit project, under the Apache License v2.0 with LLVM
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
#ifndef CRUBIT_RS_BINDINGS_FROM_CC_AST_UTIL_H_
#define CRUBIT_RS_BINDINGS_FROM_CC_AST_UTIL_H_
#include <optional>
#include <string>
#include "absl/functional/function_ref.h"
#include "absl/status/statusor.h"
#include "rs_bindings_from_cc/decl_importer.h"
#include "clang/AST/Attr.h"
#include "clang/AST/DeclBase.h"
#include "clang/AST/Type.h"
#include "clang/Basic/AttrKinds.h"
namespace crubit {
// Returns true if `decl` is either 1) a ClassTemplateSpecializationDecl (but
// not ClassTemplatePartialSpecializationDecl) or 2) a decl (e.g. a member
// function decl) nested inside a ClassTemplateSpecializationDecl.
bool IsFullClassTemplateSpecializationOrChild(const clang::Decl* decl);
// Returns a human-readable string containing the list of unknown attrs.
//
// is_known is called exactly once on every attribute, and returns true if the
// attribute is understood.
//
// Annotate attributes are ignored and CRUBIT_UNSAFE_IGNORE_ATTR is considered.
absl::StatusOr<std::optional<std::string>> CollectUnknownAttrs(
const clang::Decl& decl,
absl::FunctionRef<bool(const clang::Attr&)> is_known =
[](const clang::Attr& attr) { return false; });
// Returns a human-readable string containing the list of unknown attrs.
//
// is_known is called exactly once on every attribute, and returns true if the
// attribute is understood.
std::optional<std::string> CollectUnknownTypeAttrs(
const clang::Type& t, absl::FunctionRef<bool(clang::attr::Kind)> is_known =
[](clang::attr::Kind attr) { return false; });
// Returns true if `decl` is non-null and refers to a (code-generated) proto2
// message.
bool IsProto2Message(const clang::Decl& decl);
// An RAII guard that sets a fake TU scope for the duration of its lifetime
// and restores the previous TU scope when it goes out of scope.
class FakeTUScope {
public:
// Sets `ctx`'s `Sema`'s `TUScope` to a fake scope that points to the
// translation unit declaration.
explicit FakeTUScope(ImportContext& ctx)
: ctx_(ctx),
scope_(std::make_unique<clang::Scope>(nullptr, clang::Scope::DeclScope,
ctx_.sema_.getDiagnostics())),
old_tu_scope_(ctx_.sema_.TUScope) {
ctx_.sema_.TUScope = scope_.get();
ctx_.sema_.TUScope->setEntity(ctx_.ctx_.getTranslationUnitDecl());
}
~FakeTUScope() {
ctx_.sema_.TUScope->setEntity(nullptr);
ctx_.sema_.TUScope = old_tu_scope_;
}
private:
ImportContext& ctx_;
std::unique_ptr<clang::Scope> scope_;
clang::Scope* old_tu_scope_;
};
} // namespace crubit
#endif // CRUBIT_RS_BINDINGS_FROM_CC_AST_UTIL_H_