<commit_before>/*
    c2ffi
    Copyright (C) 2013  <NAME>

    This file is part of c2ffi.

    c2ffi is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 2 of the License, or
    (at your option) any later version.

    c2ffi is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with c2ffi.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <iostream>

#include <clang/AST/PrettyPrinter.h>
#include <clang/AST/Type.h>
#include <clang/AST/DeclObjC.h>
#include <clang/AST/DeclTemplate.h>
#include <clang/AST/ASTContext.h>
#include "c2ffi.h"
#include "c2ffi/ast.h"

using namespace c2ffi;

Type::Type(const clang::CompilerInstance &ci, const clang::Type *t)
    : _ci(ci), _type(t), _id(0), _bit_offset(0), _bit_size(0), _bit_alignment(0) { }

std::string Type::metatype() const {
    if(_type)
        return std::string("<") + _type->getTypeClassName() + ">";
    else
        return std::string("<none>");
}

SimpleType::SimpleType(const clang::CompilerInstance &ci, const clang::Type *t,
                       std::string name)
    : Type(ci, t), _name(name) { }

BasicType::BasicType(const clang::CompilerInstance &ci, const clang::Type *t,
                     std::string name)
    : SimpleType(ci, t, name) {
    const clang::ASTContext &ctx = ci.getASTContext();
    set_bit_size(ctx.getTypeSize(t));
    set_bit_alignment(ctx.getTypeAlign(t));
}

RecordType::RecordType(C2FFIASTConsumer *ast,
                       const clang::Type *t,
                       std::string name, bool is_union,
                       bool is_class,
                       const clang::TemplateArgumentList *arglist)
    : SimpleType(ast->ci(), t, name),
      TemplateMixin(ast, arglist),
      _is_union(is_union),
      _is_class(is_class) { }


DeclType::DeclType(clang::CompilerInstance &ci, const clang::Type *t,
                   Decl *d, const clang::Decl *cd)
    : Type(ci, t), _d(d) {
    _d->set_location(ci, cd);
}

static std::string make_builtin_name(const clang::BuiltinType *bt) {
    clang::PrintingPolicy pp = clang::PrintingPolicy(clang::LangOptions());
    std::string name = std::string(":") + bt->getNameAsCString(pp);

    for(int i = 0; i < name.size(); i++)
        if(name[i] == ' ')
            name[i] = '-';

    return name;
}

Type* Type::make_type(C2FFIASTConsumer *ast, const clang::Type *t) {
    clang::CompilerInstance &ci = ast->ci();
    clang::ASTContext &ctx = ci.getASTContext();

    /*
    std::cout << "type: " << t->getTypeClassName() << std::endl
              << "    ";
    t->dump();
    */

    /*** Order is important here ***/

    if(t->isVoidType())
        return new SimpleType(ci, t, ":void");

    if_const_cast(td, clang::TypedefType, t) {
        const clang::TypedefNameDecl *tdd = td->getDecl();
        return new SimpleType(ci, td, tdd->getDeclName().getAsString());
    }

    if_const_cast(tt, clang::SubstTemplateTypeParmType, t) {
        if(tt != tt->desugar().getTypePtr())
            return make_type(ast, tt->desugar().getTypePtr());
    }

    if(t->isBuiltinType()) {
        const clang::BuiltinType *bt = llvm::dyn_cast<clang::BuiltinType>(t);
        if(!bt) return new SimpleType(ci, t, std::string("<unknown-builtin-type:") +
                                      t->getTypeClassName() + ">");

        return new BasicType(ci, t, make_builtin_name(bt));
    }

    if_const_cast(e, clang::ElaboratedType, t)
        return make_type(ast, e->getNamedType().getTypePtr());

    if(t->isFunctionPointerType())
        return new SimpleType(ci, t, ":function-pointer");

    if(t->isFunctionType())
        return new SimpleType(ci, t, ":function");

    if(t->isPointerType())
        return new PointerType(ci, t, make_type(ast, t->getPointeeType().getTypePtr()));

    if(t->isReferenceType())
        return new ReferenceType(ci, t, make_type(ast, t->getPointeeType().getTypePtr()));

    if_const_cast(rt, clang::RecordType, t) {
        clang::RecordDecl *rd = rt->getDecl();

        ast->add_cxx_decl(rd);

        if((rd->isThisDeclarationADefinition() && rd->isEmbeddedInDeclarator() && !ast->is_cur_decl(rd)) ||
           (rd != rd->getDefinition())) {<commit_msg>Don't try processing invalid RecordDecls for RecordTypes<commit_after>/*
    c2ffi
    Copyright (C) 2013  <NAME>

    This file is part of c2ffi.

    c2ffi is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 2 of the License, or
    (at your option) any later version.

    c2ffi is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with c2ffi.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <iostream>

#include <clang/AST/PrettyPrinter.h>
#include <clang/AST/Type.h>
#include <clang/AST/DeclObjC.h>
#include <clang/AST/DeclTemplate.h>
#include <clang/AST/ASTContext.h>
#include "c2ffi.h"
#include "c2ffi/ast.h"

using namespace c2ffi;

Type::Type(const clang::CompilerInstance &ci, const clang::Type *t)
    : _ci(ci), _type(t), _id(0), _bit_offset(0), _bit_size(0), _bit_alignment(0) { }

std::string Type::metatype() const {
    if(_type)
        return std::string("<") + _type->getTypeClassName() + ">";
    else
        return std::string("<none>");
}

SimpleType::SimpleType(const clang::CompilerInstance &ci, const clang::Type *t,
                       std::string name)
    : Type(ci, t), _name(name) { }

BasicType::BasicType(const clang::CompilerInstance &ci, const clang::Type *t,
                     std::string name)
    : SimpleType(ci, t, name) {
    const clang::ASTContext &ctx = ci.getASTContext();
    set_bit_size(ctx.getTypeSize(t));
    set_bit_alignment(ctx.getTypeAlign(t));
}

RecordType::RecordType(C2FFIASTConsumer *ast,
                       const clang::Type *t,
                       std::string name, bool is_union,
                       bool is_class,
                       const clang::TemplateArgumentList *arglist)
    : SimpleType(ast->ci(), t, name),
      TemplateMixin(ast, arglist),
      _is_union(is_union),
      _is_class(is_class) { }


DeclType::DeclType(clang::CompilerInstance &ci, const clang::Type *t,
                   Decl *d, const clang::Decl *cd)
    : Type(ci, t), _d(d) {
    _d->set_location(ci, cd);
}

static std::string make_builtin_name(const clang::BuiltinType *bt) {
    clang::PrintingPolicy pp = clang::PrintingPolicy(clang::LangOptions());
    std::string name = std::string(":") + bt->getNameAsCString(pp);

    for(int i = 0; i < name.size(); i++)
        if(name[i] == ' ')
            name[i] = '-';

    return name;
}

Type* Type::make_type(C2FFIASTConsumer *ast, const clang::Type *t) {
    clang::CompilerInstance &ci = ast->ci();
    clang::ASTContext &ctx = ci.getASTContext();

    /*
    std::cout << "type: " << t->getTypeClassName() << std::endl
              << "    ";
    t->dump();
    */

    /*** Order is important here ***/

    if(t->isVoidType())
        return new SimpleType(ci, t, ":void");

    if_const_cast(td, clang::TypedefType, t) {
        const clang::TypedefNameDecl *tdd = td->getDecl();
        return new SimpleType(ci, td, tdd->getDeclName().getAsString());
    }

    if_const_cast(tt, clang::SubstTemplateTypeParmType, t) {
        if(tt != tt->desugar().getTypePtr())
            return make_type(ast, tt->desugar().getTypePtr());
    }

    if(t->isBuiltinType()) {
        const clang::BuiltinType *bt = llvm::dyn_cast<clang::BuiltinType>(t);
        if(!bt) return new SimpleType(ci, t, std::string("<unknown-builtin-type:") +
                                      t->getTypeClassName() + ">");

        return new BasicType(ci, t, make_builtin_name(bt));
    }

    if_const_cast(e, clang::ElaboratedType, t)
        return make_type(ast, e->getNamedType().getTypePtr());

    if(t->isFunctionPointerType())
        return new SimpleType(ci, t, ":function-pointer");

    if(t->isFunctionType())
        return new SimpleType(ci, t, ":function");

    if(t->isPointerType())
        return new PointerType(ci, t, make_type(ast, t->getPointeeType().getTypePtr()));

    if(t->isReferenceType())
        return new ReferenceType(ci, t, make_type(ast, t->getPointeeType().getTypePtr()));

    if_const_cast(rt, clang::RecordType, t) {
        clang::RecordDecl *rd = rt->getDecl();

        if(rd->isInvalidDecl())
            return new SimpleType(ci, t, std::string("<invalid-type:") +
                                  t->getTypeClassName() + ">");

        ast->add_cxx_decl(rd);

        if((rd->isThisDeclarationADefinition() && rd->isEmbeddedInDeclarator() && !ast->is_cur_decl(rd)) ||
           (rd != rd->getDefinition())) {
{'fraction_non_alphanumeric': 0.1495105948155319, 'fraction_numerical': 0.004302463160159191, 'mean_word_length': 3.00258286698235, 'pattern_counts': {'":': 8, '<': 46, '<?xml version=': 0, '>': 84, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 3, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1010413', 'n_tokens_mistral': 3065, 'n_tokens_neox': 3004, 'n_words': 699}