mirror of
https://github.com/google/sandboxed-api.git
synced 2024-03-22 13:11:30 +08:00
Emit non-type template args as part of forward decls
This change allows us to emit forward declarations to classes that are templated. For headers generated by the proto compiler this is sometimes necessary. Note: - This will only emit types for a single level of template instantiations. That is, template template arguments are not supported. - Typedefs only occurring in template arguments will be fully desugared and thus will not be available under their aliased name in the generated API code. This is consistent with the Python based generator (which does not emit these at all and relies on text extraction). Signed-off-by: Christian Blichmann <cblichmann@google.com>
This commit is contained in:
parent
ea379ef4d6
commit
728355da87
|
@ -26,6 +26,7 @@
|
||||||
#include "absl/strings/string_view.h"
|
#include "absl/strings/string_view.h"
|
||||||
#include "absl/strings/strip.h"
|
#include "absl/strings/strip.h"
|
||||||
#include "clang/AST/DeclCXX.h"
|
#include "clang/AST/DeclCXX.h"
|
||||||
|
#include "clang/AST/DeclTemplate.h"
|
||||||
#include "clang/AST/Type.h"
|
#include "clang/AST/Type.h"
|
||||||
#include "clang/Format/Format.h"
|
#include "clang/Format/Format.h"
|
||||||
#include "sandboxed_api/tools/clang_generator/diagnostics.h"
|
#include "sandboxed_api/tools/clang_generator/diagnostics.h"
|
||||||
|
@ -180,6 +181,37 @@ std::vector<std::string> GetNamespacePath(const clang::TypeDecl* decl) {
|
||||||
return comps;
|
return comps;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string PrintRecordTemplateArguments(const clang::CXXRecordDecl* record) {
|
||||||
|
const auto* template_inst_decl = record->getTemplateInstantiationPattern();
|
||||||
|
if (!template_inst_decl) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
const auto* template_decl = template_inst_decl->getDescribedClassTemplate();
|
||||||
|
if (!template_decl) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
const auto* template_params = template_decl->getTemplateParameters();
|
||||||
|
if (!template_params) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
std::vector<std::string> params;
|
||||||
|
params.reserve(template_params->size());
|
||||||
|
for (const auto& template_param : *template_params) {
|
||||||
|
if (const auto* p =
|
||||||
|
llvm::dyn_cast<clang::NonTypeTemplateParmDecl>(template_param)) {
|
||||||
|
// TODO(cblichmann): These types should be included by
|
||||||
|
// CollectRelatedTypes().
|
||||||
|
params.push_back(
|
||||||
|
p->getType().getDesugaredType(record->getASTContext()).getAsString());
|
||||||
|
} else { // Also covers template template parameters
|
||||||
|
params.push_back("typename");
|
||||||
|
}
|
||||||
|
absl::StrAppend(¶ms.back(), " /*",
|
||||||
|
std::string(template_param->getName()), "*/");
|
||||||
|
}
|
||||||
|
return absl::StrCat("template <", absl::StrJoin(params, ", "), ">");
|
||||||
|
}
|
||||||
|
|
||||||
// Serializes the given Clang AST declaration back into compilable source code.
|
// Serializes the given Clang AST declaration back into compilable source code.
|
||||||
std::string PrintAstDecl(const clang::Decl* decl) {
|
std::string PrintAstDecl(const clang::Decl* decl) {
|
||||||
// TODO(cblichmann): Make types nicer
|
// TODO(cblichmann): Make types nicer
|
||||||
|
@ -188,7 +220,8 @@ std::string PrintAstDecl(const clang::Decl* decl) {
|
||||||
|
|
||||||
if (const auto* record = llvm::dyn_cast<clang::CXXRecordDecl>(decl)) {
|
if (const auto* record = llvm::dyn_cast<clang::CXXRecordDecl>(decl)) {
|
||||||
// For C++ classes/structs, only emit a forward declaration.
|
// For C++ classes/structs, only emit a forward declaration.
|
||||||
return absl::StrCat(record->isClass() ? "class " : "struct ",
|
return absl::StrCat(PrintRecordTemplateArguments(record),
|
||||||
|
record->isClass() ? "class " : "struct ",
|
||||||
std::string(record->getName()));
|
std::string(record->getName()));
|
||||||
}
|
}
|
||||||
std::string pretty;
|
std::string pretty;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user