Seperated out protobuf impl into wrapper classes. am: 2920754397

am: 85204bdd59

Change-Id: I0fd503ad5176efa6d16678e957a9c6a1d3a8510c
This commit is contained in:
Jayant Chowdhary
2017-01-26 02:15:17 +00:00
committed by android-build-merger
6 changed files with 583 additions and 144 deletions

View File

@@ -0,0 +1,326 @@
// Copyright (C) 2016 The Android Open Source Project
//
// 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
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// 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.
#include "abi_wrappers.h"
#include <clang/Tooling/Core/QualTypeNames.h>
#include <string>
using namespace abi_wrapper;
ABIWrapper::ABIWrapper(
clang::MangleContext *mangle_contextp,
const clang::ASTContext *ast_contextp,
const clang::CompilerInstance *compiler_instance_p)
: mangle_contextp_(mangle_contextp),
ast_contextp_(ast_contextp),
cip_(compiler_instance_p) {}
std::string ABIWrapper::GetDeclSourceFile(const clang::NamedDecl *decl) const {
clang::SourceManager &SM = cip_->getSourceManager();
clang::SourceLocation location = decl->getLocation();
llvm::StringRef file_name= SM.getFilename(location);
return file_name.str();
}
std::string ABIWrapper::AccessToString(const clang::AccessSpecifier sp) const {
std::string str = "public";
switch (sp) {
case clang::AS_private:
str = "private";
break;
case clang::AS_protected:
str = "protected";
break;
default:
break;
}
return str;
}
std::string ABIWrapper::GetMangledNameDecl(const clang::NamedDecl *decl) const {
std::string mangled_or_demangled_name = decl->getName();
if (mangle_contextp_->shouldMangleDeclName(decl)) {
llvm::raw_string_ostream ostream(mangled_or_demangled_name);
mangle_contextp_->mangleName(decl, ostream);
ostream.flush();
}
return mangled_or_demangled_name;
}
bool ABIWrapper::SetupTemplateParamNames(abi_dump::TemplateInfo *tinfo,
clang::TemplateParameterList *pl) const {
if (tinfo->template_parameters_size() > 0)
return true;
clang::TemplateParameterList::iterator template_it = pl->begin();
while (template_it != pl->end()) {
abi_dump::FieldDecl *template_parameterp =
tinfo->add_template_parameters();
if (!template_parameterp)
return false;
template_parameterp->set_field_name((*template_it)->getName());
template_it++;
}
return true;
}
bool ABIWrapper::SetupTemplateArguments(abi_dump::TemplateInfo *tinfo,
const clang::TemplateArgumentList *tl) const {
for (int i = 0; i < tl->size(); i++) {
const clang::TemplateArgument &arg = (*tl)[i];
std::string type = QualTypeToString(arg.getAsType());
abi_dump::FieldDecl *template_parameterp =
tinfo->add_template_parameters();
if (!template_parameterp)
return false;
template_parameterp->set_field_type((type));
}
return true;
}
std::string ABIWrapper::QualTypeToString(const clang::QualType &sweet_qt) const {
const clang::QualType salty_qt = sweet_qt.getDesugaredType(*ast_contextp_);
return clang::TypeName::getFullyQualifiedName(salty_qt, *ast_contextp_);
}
FunctionDeclWrapper::FunctionDeclWrapper(
clang::MangleContext *mangle_contextp,
const clang::ASTContext *ast_contextp,
const clang::CompilerInstance *compiler_instance_p,
const clang::FunctionDecl *decl)
: ABIWrapper(mangle_contextp, ast_contextp, compiler_instance_p),
function_decl_(decl) { }
bool FunctionDeclWrapper::SetupFunction(abi_dump::FunctionDecl *functionp,
const std::string &source_file) const {
// Go through all the parameters in the method and add them to the fields.
// Also get the fully qualfied name and mangled name and store them.
functionp->set_function_name(function_decl_->getQualifiedNameAsString());
functionp->set_mangled_function_name(GetMangledNameDecl(function_decl_));
functionp->set_source_file(source_file);
functionp->set_return_type(QualTypeToString(function_decl_->getReturnType()));
clang::FunctionDecl::param_const_iterator param_it =
function_decl_->param_begin();
while (param_it != function_decl_->param_end()) {
abi_dump::FieldDecl *function_fieldp = functionp->add_parameters();
if (!function_fieldp) {
llvm::errs() << "Couldn't add parameter to method. Aborting\n";
return false;
}
function_fieldp->set_field_name((*param_it)->getName());
function_fieldp->set_default_arg((*param_it)->hasDefaultArg());
function_fieldp->set_field_type(QualTypeToString((*param_it)->getType()));
param_it++;
}
functionp->set_access(AccessToString(function_decl_->getAccess()));
functionp->set_template_kind(function_decl_->getTemplatedKind());
if(!SetupTemplateInfo(functionp)) {
return false;
}
return true;
}
bool FunctionDeclWrapper::SetupTemplateInfo(abi_dump::FunctionDecl *functionp) const {
switch (function_decl_->getTemplatedKind()) {
case clang::FunctionDecl::TK_FunctionTemplate:
{
clang::FunctionTemplateDecl *template_decl =
function_decl_->getDescribedFunctionTemplate();
if (template_decl) {
clang::TemplateParameterList *template_parameter_list =
template_decl->getTemplateParameters();
if (template_parameter_list &&
!SetupTemplateParamNames(functionp->mutable_template_info(),
template_parameter_list)) {
return false;
}
}
break;
}
case clang::FunctionDecl::TK_FunctionTemplateSpecialization:
{
const clang::TemplateArgumentList *arg_list =
function_decl_->getTemplateSpecializationArgs();
if (arg_list &&
!SetupTemplateArguments(
functionp->mutable_template_info(), arg_list)) {
return false;
}
break;
}
default:
break;
}
return true;
}
std::unique_ptr<abi_dump::FunctionDecl> FunctionDeclWrapper::GetFunctionDecl() const {
std::unique_ptr<abi_dump::FunctionDecl> abi_decl(
new abi_dump::FunctionDecl());
std::string source_file = GetDeclSourceFile(function_decl_);
if (!SetupFunction(abi_decl.get(), source_file)) {
return nullptr;
}
return abi_decl;
}
RecordDeclWrapper::RecordDeclWrapper(
clang::MangleContext *mangle_contextp,
const clang::ASTContext *ast_contextp,
const clang::CompilerInstance *compiler_instance_p,
const clang::RecordDecl *decl)
: ABIWrapper(mangle_contextp, ast_contextp, compiler_instance_p),
record_decl_(decl) { }
bool RecordDeclWrapper::SetupRecordFields(abi_dump::RecordDecl *recordp,
const std::string &source_file) const {
clang::RecordDecl::field_iterator field = record_decl_->field_begin();
while (field != record_decl_->field_end()) {
abi_dump::FieldDecl *record_fieldp = recordp->add_fields();
if (!record_fieldp) {
llvm::errs() << " Couldn't add record field: " << field->getName()
<< " to reference dump\n";
return false;
}
record_fieldp->set_field_name(field->getName());
record_fieldp->set_field_type(QualTypeToString(field->getType()));
record_fieldp->set_access(AccessToString(field->getAccess()));
field++;
}
return true;
}
bool RecordDeclWrapper::SetupCXXBases(abi_dump::RecordDecl *cxxp) const {
const clang::CXXRecordDecl *cxx_record_decl =
clang::dyn_cast<clang::CXXRecordDecl>(record_decl_);
if (!cxx_record_decl)
return true;
clang::CXXRecordDecl::base_class_const_iterator base_class =
cxx_record_decl->bases_begin();
while (base_class != cxx_record_decl->bases_end()) {
abi_dump::CXXBaseSpecifier *base_specifierp = cxxp->add_base_specifiers();
if (!base_specifierp) {
llvm::errs() << " Couldn't add base specifier to reference dump\n";
return false;
}
base_specifierp->set_fully_qualified_name(
QualTypeToString(base_class->getType()));
base_specifierp->set_is_virtual(base_class->isVirtual());
base_specifierp->set_access(
AccessToString(base_class->getAccessSpecifier()));
base_class++;
}
return true;
}
bool RecordDeclWrapper::SetupTemplateInfo(abi_dump::RecordDecl *record_declp) const {
const clang::CXXRecordDecl *cxx_record_decl =
clang::dyn_cast<clang::CXXRecordDecl>(record_decl_);
if (!cxx_record_decl)
return true;
if (cxx_record_decl->isTemplateDecl()) {
clang::ClassTemplateDecl *template_decl =
cxx_record_decl->getDescribedClassTemplate();
if (template_decl) {
clang::TemplateParameterList *template_parameter_list =
template_decl->getTemplateParameters();
if (template_parameter_list
&& !SetupTemplateParamNames(record_declp->mutable_template_info(),
template_parameter_list)) {
return false;
}
}
} else {
const clang::ClassTemplateSpecializationDecl *specialization_decl =
clang::dyn_cast<clang::ClassTemplateSpecializationDecl>(
cxx_record_decl);
if(specialization_decl) {
const clang::TemplateArgumentList *arg_list =
&(specialization_decl->getTemplateArgs());
if (arg_list
&& !SetupTemplateArguments(record_declp->mutable_template_info(),
arg_list)) {
return false;
}
}
}
return true;
}
void RecordDeclWrapper::SetupRecordInfo(abi_dump::RecordDecl *record_declp,
const std::string &source_file) const {
record_declp->set_fully_qualified_name(
record_decl_->getQualifiedNameAsString());
record_declp->set_source_file(source_file);
record_declp->set_access(AccessToString(record_decl_->getAccess()));
}
std::unique_ptr<abi_dump::RecordDecl> RecordDeclWrapper::GetRecordDecl() const {
std::unique_ptr<abi_dump::RecordDecl> abi_decl(new abi_dump::RecordDecl());
std::string source_file = GetDeclSourceFile(record_decl_);
SetupRecordInfo(abi_decl.get(), source_file);
if (!SetupRecordFields(abi_decl.get(), source_file)) {
llvm::errs() << "Setting up Record Fields failed\n";
return nullptr;
}
if (!SetupCXXBases(abi_decl.get()) || !SetupTemplateInfo(abi_decl.get())) {
llvm::errs() << "Setting up CXX Bases / Template Info failed\n";
return nullptr;
}
return abi_decl;
}
EnumDeclWrapper::EnumDeclWrapper(
clang::MangleContext *mangle_contextp,
const clang::ASTContext *ast_contextp,
const clang::CompilerInstance *compiler_instance_p,
const clang::EnumDecl *decl)
: ABIWrapper(mangle_contextp, ast_contextp, compiler_instance_p),
enum_decl_(decl) { }
bool EnumDeclWrapper::SetupEnum(abi_dump::EnumDecl *enump,
const std::string &source_file) const {
//Enum's name.
enump->set_enum_name(enum_decl_->getQualifiedNameAsString());
//Enum's base integer type.
enump->set_enum_type(QualTypeToString(enum_decl_->getIntegerType()));
clang::EnumDecl::enumerator_iterator enum_it = enum_decl_->enumerator_begin();
while (enum_it != enum_decl_->enumerator_end()) {
abi_dump::EnumField *enum_fieldp = enump->add_enum_fields();
if (!enum_fieldp)
return false;
enum_fieldp->set_enum_field_name(enum_it->getQualifiedNameAsString());
enum_fieldp->set_enum_field_value(enum_it->getInitVal().getExtValue());
enum_it++;
}
return true;
}
std::unique_ptr<abi_dump::EnumDecl> EnumDeclWrapper::GetEnumDecl() const {
std::unique_ptr<abi_dump::EnumDecl> abi_decl(new abi_dump::EnumDecl());
std::string source_file = GetDeclSourceFile(enum_decl_);
if (!SetupEnum(abi_decl.get(), source_file)) {
llvm::errs() << "Setting up Enum fields failed\n";
return nullptr;
}
return abi_decl;
}

View File

@@ -0,0 +1,119 @@
// Copyright (C) 2016 The Android Open Source Project
//
// 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
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// 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 ABI_WRAPPERS_H_
#define ABI_WRAPPERS_H_
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-parameter"
#pragma clang diagnostic ignored "-Wnested-anon-types"
#include "proto/abi_dump.pb.h"
#pragma clang diagnostic pop
#include <clang/AST/AST.h>
#include <clang/AST/ASTConsumer.h>
#include <clang/AST/Mangle.h>
#include <clang/Frontend/CompilerInstance.h>
namespace abi_wrapper {
class ABIWrapper {
public:
ABIWrapper(clang::MangleContext *mangle_contextp,
const clang::ASTContext *ast_contextp,
const clang::CompilerInstance *compiler_instance_p);
std::string GetDeclSourceFile(const clang::NamedDecl *decl) const;
protected:
std::string AccessToString(const clang::AccessSpecifier sp) const;
std::string GetMangledNameDecl(const clang::NamedDecl *decl) const;
bool SetupTemplateParamNames(abi_dump::TemplateInfo *tinfo,
clang::TemplateParameterList *pl) const;
bool SetupTemplateArguments(abi_dump::TemplateInfo *tinfo,
const clang::TemplateArgumentList *tl) const;
std::string QualTypeToString(const clang::QualType &sweet_qt) const;
private:
clang::MangleContext *mangle_contextp_;
const clang::ASTContext *ast_contextp_;
const clang::CompilerInstance *cip_;
};
class RecordDeclWrapper : public ABIWrapper {
public:
RecordDeclWrapper(clang::MangleContext *mangle_contextp,
const clang::ASTContext *ast_contextp,
const clang::CompilerInstance *compiler_instance_p,
const clang::RecordDecl *decl);
std::unique_ptr<abi_dump::RecordDecl> GetRecordDecl() const;
private:
const clang::RecordDecl *record_decl_;
private:
void SetupRecordInfo(abi_dump::RecordDecl *record_declp,
const std::string &source_file) const;
bool SetupRecordFields(abi_dump::RecordDecl *recordp,
const std::string &source_file) const;
bool SetupCXXBases(abi_dump::RecordDecl *cxxp) const;
bool SetupTemplateInfo(abi_dump::RecordDecl *record_declp) const;
};
class FunctionDeclWrapper : public ABIWrapper {
public:
FunctionDeclWrapper(clang::MangleContext *mangle_contextp,
const clang::ASTContext *ast_contextp,
const clang::CompilerInstance *compiler_instance_p,
const clang::FunctionDecl *decl);
std::unique_ptr<abi_dump::FunctionDecl> GetFunctionDecl() const;
private:
const clang::FunctionDecl *function_decl_;
private:
bool SetupFunction(abi_dump::FunctionDecl *methodp,
const std::string &source_file) const;
bool SetupTemplateInfo(abi_dump::FunctionDecl *functionp) const;
};
class EnumDeclWrapper : public ABIWrapper {
public:
EnumDeclWrapper(clang::MangleContext *mangle_contextp,
const clang::ASTContext *ast_contextp,
const clang::CompilerInstance *compiler_instance_p,
const clang::EnumDecl *decl);
std::unique_ptr<abi_dump::EnumDecl> GetEnumDecl() const;
private:
const clang::EnumDecl *enum_decl_;
private:
bool SetupEnum(abi_dump::EnumDecl *enump,
const std::string &source_file) const;
};
} //end namespace abi_wrapper
#endif // ABI_WRAPPERS_H_

View File

@@ -1,4 +1,3 @@
// Copyright (C) 2016 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,6 +13,7 @@
// limitations under the License.
#include "ast_processing.h"
#include "abi_wrappers.h"
#include <clang/Lex/Token.h>
#include <clang/Tooling/Core/QualTypeNames.h>
@@ -24,6 +24,10 @@
#include <iostream>
#include <string>
using abi_wrapper::FunctionDeclWrapper;
using abi_wrapper::RecordDeclWrapper;
using abi_wrapper::EnumDeclWrapper;
HeaderASTVisitor::HeaderASTVisitor(
abi_dump::TranslationUnit *tu_ptr,
clang::MangleContext *mangle_contextp,
@@ -38,28 +42,75 @@ HeaderASTVisitor::HeaderASTVisitor(
// TODO: optimize source file initial check by preferably moving this into
// TraverseTranslationUnitDecl.
bool HeaderASTVisitor::VisitCXXRecordDecl(const clang::CXXRecordDecl *decl) {
std::string source_file = GetDeclSourceFile(decl);
bool HeaderASTVisitor::VisitRecordDecl(const clang::RecordDecl *decl) {
//forward declaration
if (!decl->isThisDeclarationADefinition()) {
return true;
}
RecordDeclWrapper record_decl_wrapper(mangle_contextp_,
ast_contextp_,
cip_,
decl);
std::string source_file = record_decl_wrapper.GetDeclSourceFile(decl);
if (source_file != current_file_name_)
return true;
abi_dump::RecordDecl *record_decl = tu_ptr_->add_classes();
if (!SetupClassFields(record_decl, decl, source_file) ||
!SetupClassBases(record_decl, decl)) {
std::unique_ptr<abi_dump::RecordDecl> wrapped_record_decl =
record_decl_wrapper.GetRecordDecl();
if (!wrapped_record_decl) {
llvm::errs() << "Getting Record Decl failed\n";
return false;
}
abi_dump::RecordDecl *record_declp = tu_ptr_->add_classes();
if (!record_declp) {
return false;
}
*record_declp = *wrapped_record_decl;
return true;
}
bool HeaderASTVisitor::VisitEnumDecl(const clang::EnumDecl *decl) {
if (!decl->isThisDeclarationADefinition()) {
return true;
}
EnumDeclWrapper enum_decl_wrapper(mangle_contextp_,
ast_contextp_,
cip_,
decl);
std::string source_file = enum_decl_wrapper.GetDeclSourceFile(decl);
if (source_file != current_file_name_)
return true;
std::unique_ptr<abi_dump::EnumDecl> wrapped_enum_decl =
enum_decl_wrapper.GetEnumDecl();
if (!wrapped_enum_decl) {
llvm::errs() << "Getting Enum Decl failed\n";
return false;
}
abi_dump::EnumDecl *enum_declp = tu_ptr_->add_enums();
if (!enum_declp) {
return false;
}
*enum_declp = *wrapped_enum_decl;
return true;
}
bool HeaderASTVisitor::VisitFunctionDecl(const clang::FunctionDecl *decl) {
std::string source_file = GetDeclSourceFile(decl);
if (source_file != current_file_name_) {
FunctionDeclWrapper function_decl_wrapper(mangle_contextp_,
ast_contextp_,
cip_,
decl);
std::string source_file = function_decl_wrapper.GetDeclSourceFile(decl);
if (source_file != current_file_name_)
return true;
}
abi_dump::FunctionDecl *function_decl = tu_ptr_->add_functions();
if (!SetupFunction(function_decl, decl, source_file)) {
std::unique_ptr<abi_dump::FunctionDecl> wrapped_function_decl =
function_decl_wrapper.GetFunctionDecl();
if (!wrapped_function_decl) {
llvm::errs() << "Getting Function Decl failed\n";
return false;
}
abi_dump::FunctionDecl *function_declp = tu_ptr_->add_functions();
if (!function_declp)
return false;
*function_declp = *wrapped_function_decl;
return true;
}
@@ -94,120 +145,6 @@ void HeaderASTConsumer::HandleVTable(clang::CXXRecordDecl *crd) {
llvm::errs() << "HandleVTable: " << crd->getName() << "\n";
}
std::string HeaderASTVisitor::GetDeclSourceFile(const clang::NamedDecl *decl) {
clang::SourceManager &SM = cip_->getSourceManager();
clang::SourceLocation location = decl->getLocation();
llvm::StringRef file_name= SM.getFilename(location);
return file_name.str();
}
std::string HeaderASTVisitor::AccessToString(const clang::AccessSpecifier sp) {
std::string str = "none";
switch (sp) {
case clang::AS_public:
str = "public";
break;
case clang::AS_private:
str = "private";
break;
case clang::AS_protected:
str = "protected";
break;
default:
break;
}
return str;
}
std::string HeaderASTVisitor::GetMangledNameDecl(const clang::NamedDecl *decl) {
std::string mangled_or_demangled_name = decl->getName();
if (mangle_contextp_->shouldMangleDeclName(decl)) {
llvm::raw_string_ostream ostream(mangled_or_demangled_name);
mangle_contextp_->mangleName(decl, ostream);
ostream.flush();
}
return mangled_or_demangled_name;
}
bool HeaderASTVisitor::SetupFunction(abi_dump::FunctionDecl *functionp,
const clang::FunctionDecl *decl,
const std::string &source_file) {
// Go through all the parameters in the method and add them to the fields.
// Also get the fully qualfied name and mangled name and store them.
functionp->set_function_name(decl->getQualifiedNameAsString());
functionp->set_mangled_function_name(GetMangledNameDecl(decl));
functionp->set_source_file(source_file);
clang::QualType return_type =
decl->getReturnType().getDesugaredType(*ast_contextp_);
functionp->set_return_type(
clang::TypeName::getFullyQualifiedName(return_type, *ast_contextp_));
clang::FunctionDecl::param_const_iterator param_it = decl->param_begin();
while (param_it != decl->param_end()) {
abi_dump::FieldDecl *function_fieldp = functionp->add_parameters();
if (!function_fieldp) {
llvm::errs() << "Couldn't add parameter to method. Aborting\n";
return false;
}
function_fieldp->set_field_name((*param_it)->getName());
clang::QualType field_type =
(*param_it)->getType().getDesugaredType(*ast_contextp_);
function_fieldp->set_field_type(
clang::TypeName::getFullyQualifiedName(field_type, *ast_contextp_));
param_it++;
}
functionp->set_access(AccessToString(decl->getAccess()));
return true;
}
bool HeaderASTVisitor::SetupClassFields(abi_dump::RecordDecl *classp,
const clang::CXXRecordDecl *decl,
const std::string &source_file) {
classp->set_fully_qualified_name(decl->getQualifiedNameAsString());
classp->set_source_file(source_file);
classp->set_entity_type("class");
clang::RecordDecl::field_iterator field = decl->field_begin();
while (field != decl->field_end()) {
abi_dump::FieldDecl *class_fieldp = classp->add_fields();
if (!class_fieldp) {
llvm::errs() << " Couldn't add class field: " << field->getName()
<< " to reference dump\n";
return false;
}
class_fieldp->set_field_name(field->getName());
clang::QualType field_type =
field->getType().getDesugaredType(*ast_contextp_);
class_fieldp->set_field_type(
clang::TypeName::getFullyQualifiedName(field_type, *ast_contextp_));
class_fieldp->set_access(AccessToString(field->getAccess()));
field++;
}
return true;
}
bool HeaderASTVisitor::SetupClassBases(abi_dump::RecordDecl *classp,
const clang::CXXRecordDecl *decl) {
clang::CXXRecordDecl::base_class_const_iterator base_class =
decl->bases_begin();
while (base_class != decl->bases_end()) {
abi_dump::CXXBaseSpecifier *base_specifierp = classp->add_base_specifiers();
if (!base_specifierp) {
llvm::errs() << " Couldn't add base specifier to reference dump\n";
return false;
}
//TODO: Make this pair into a function, used accross.
clang::QualType base_type =
base_class->getType().getDesugaredType(*ast_contextp_);
base_specifierp->set_fully_qualified_name(
clang::TypeName::getFullyQualifiedName(base_type, *ast_contextp_));
base_specifierp->set_is_virtual(base_class->isVirtual());
base_specifierp->set_access(
AccessToString(base_class->getAccessSpecifier()));
base_class++;
}
return true;
}
void HeaderASTPPCallbacks::MacroDefined(const clang::Token &macro_name_tok,
const clang::MacroDirective *) {
assert(macro_name_tok.isAnyIdentifier());

View File

@@ -37,27 +37,16 @@ class HeaderASTVisitor
const clang::CompilerInstance *compiler_instance_p,
const std::string &current_file_name);
bool VisitCXXRecordDecl(const clang::CXXRecordDecl *decl);
bool VisitRecordDecl(const clang::RecordDecl *decl);
bool VisitFunctionDecl(const clang::FunctionDecl *decl);
private:
bool SetupFunction(abi_dump::FunctionDecl *methodp,
const clang::FunctionDecl *decl,
const std::string &source_file);
bool VisitEnumDecl(const clang::EnumDecl *decl);
bool SetupClassFields(abi_dump::RecordDecl *classp,
const clang::CXXRecordDecl *decl,
const std::string &source_file);
bool SetupClassBases(abi_dump::RecordDecl *classp,
const clang::CXXRecordDecl *decl);
std::string GetDeclSourceFile(const clang::NamedDecl *decl);
std::string AccessToString(const clang::AccessSpecifier sp);
std::string GetMangledNameDecl(const clang::NamedDecl *decl);
//Enable recursive traversal of template instantiations.
bool shouldVisitTemplateInstantiations() const {
return true;
}
private:
abi_dump::TranslationUnit *tu_ptr_;

View File

@@ -15,12 +15,24 @@ message FunctionDecl {
repeated FieldDecl parameters = 6;
required string return_type = 7 [default = "VOID"];
required string access = 8 [default = "public"];
required uint32 template_kind = 9 [default = 0];
required TemplateInfo template_info = 10;
}
message FieldDecl {
required string field_name = 1 [default = "NONE"];
required string field_type = 2 [default = "VOID"];
required string access = 3 [default = "public"];
required bool default_arg = 4 [default = false];
}
message EnumField {
required string enum_field_name = 1 [default = "NONE"];
required int64 enum_field_value = 2 [default = 0]; // assumption: fits int64
}
message TemplateInfo {
repeated FieldDecl template_parameters = 1;
}
message CXXBaseSpecifier {
@@ -38,9 +50,21 @@ message RecordDecl {
required string entity_type = 7 [default = "NONE"];
required string source_file = 9 [default = "NONE"];
required bool is_c_struct = 10 [default = false];
required string template_kind = 11 [default = "NONE"];
required TemplateInfo template_info = 12;
required string access = 13 [default = "public"];
}
message EnumDecl {
required string enum_name = 1 [default = "NONE"];
required string access = 2 [default = "public"];
required string enum_type = 3 [default = "int"];
repeated EnumField enum_fields = 4;
required string source_file = 5 [default = "NONE"];
}
message TranslationUnit {
repeated RecordDecl classes = 1;
repeated FunctionDecl functions = 2;
repeated EnumDecl enums = 3;
}

View File

@@ -1,18 +1,62 @@
#ifndef EXAMPLE2_H_
#define EXAMPLE2_H_
#include <memory>
namespace test2 {
struct HelloAgain {
int foo_again;
std::unique_ptr<HelloAgain> foo_again;
int bar_again;
};
struct NowWeCrash;
} // namespace test2
enum Foo_s {
foosball = 10,
foosbat
};
namespace test3 {
template <typename T>
struct ByeAgain {
T foo_again;
int bar_again;
T method_foo(T);
};
template<>
struct ByeAgain<float> {
float foo_again;
float bar_Again;
float method_foo(int);
};
ByeAgain<double> double_bye;
template <typename T1, typename T2>
bool Begin(T1 arg1, T2 arg2);
template <>
bool Begin<int, float>(int a, float b);
bool End ( float arg = 2.0) {
bool ret = Begin(arg, 2);
return ret;
}
enum Kind {
kind1 = 24,
kind2 = 2312
};
class Outer {
public:
int a;
private:
class Inner {
int b;
};
};
} // namespace test3
#endif // EXAMPLE2_H_