Skip to content

Commit

Permalink
Merge pull request #17 from srydell/constructors
Browse files Browse the repository at this point in the history
Constructors
  • Loading branch information
srydell authored Dec 31, 2021
2 parents ef8446d + b62afe5 commit c3faaec
Show file tree
Hide file tree
Showing 58 changed files with 515 additions and 380 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/macos.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: MacOS
name: MacO

on:
push:
Expand All @@ -14,7 +14,7 @@ env:
jobs:
build:

runs-on: macos-latest
runs-on: macOS-10.15
if: "!contains(github.event.head_commit.message, '[skip ci]') && !contains(github.event.head_commit.message, '[skip macos]')"

steps:
Expand Down
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ add_llvm_library(
src/Helpers/Utils/split.cpp
src/Helpers/Utils/string.cpp
src/Helpers/commandLineArgs.cpp
src/Helpers/getStructData.cpp
src/Helpers/walkIRStructure.cpp
src/Parser/Parse.cpp
src/Parser/Windows/systemIncludeHelper.cpp
Expand Down
9 changes: 5 additions & 4 deletions src/Builders/commonBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,15 @@ buildParentStructure(clang::DeclContext const* parent,
return structure;
}

std::optional<IR::AccessModifier>
std::optional<IRProxy::AccessModifier>
convertToIRAccess(clang::AccessSpecifier access) {
switch (access) {
case clang::AS_public: return IR::AccessModifier::Public;
case clang::AS_private: return IR::AccessModifier::Private;
case clang::AS_protected: return IR::AccessModifier::Protected;
case clang::AS_public: return IRProxy::AccessModifier::Public;
case clang::AS_private: return IRProxy::AccessModifier::Private;
case clang::AS_protected: return IRProxy::AccessModifier::Protected;
case clang::AS_none: return {};
}
return {};
}

} // namespace Builders
Expand Down
4 changes: 2 additions & 2 deletions src/Builders/commonBuilder.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@
namespace Builders {

/**
* Convert the clang::AccessSpecifier to IR::AccessModifier and add them to the structure
* Convert the clang::AccessSpecifier to IRProxy::AccessModifier and add them to the structure
*/
std::optional<IR::AccessModifier>
std::optional<IRProxy::AccessModifier>
convertToIRAccess(clang::AccessSpecifier access);

/**
Expand Down
9 changes: 6 additions & 3 deletions src/Builders/enumBuilder.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "Builders/structBuilder.hpp"
#include "Helpers/getStructData.hpp"
#include "Helpers/walkIRStructure.hpp"
#include "IR/ir.hpp"
#include <algorithm>
Expand All @@ -10,14 +11,16 @@

namespace {

void addEnumToVariant(std::optional<IR::AccessModifier> modifier,
void addEnumToVariant(std::optional<IRProxy::AccessModifier> modifier,
std::variant<IR::Namespace*, IR::Struct*> const& v,
IR::Enum e) {
if (auto ns = std::get_if<IR::Namespace*>(&v)) {
(*ns)->m_enums.push_back(e);
} else if (auto irStruct = std::get_if<IR::Struct*>(&v)) {
// TODO: Error on modifier no value
(*irStruct)->m_enums.push_back({modifier.value(), e});
if (auto data = Helpers::getStructDataBasedOnAccess(**irStruct,
modifier.value())) {
data->m_enums.push_back(e);
}
}
}

Expand Down
5 changes: 3 additions & 2 deletions src/Builders/fieldBuilder.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "Builders/fieldBuilder.hpp"
#include "Builders/commonBuilder.hpp"
#include "Builders/typeBuilder.hpp"
#include "IRProxy/IRData.hpp"
#include <IR/ir.hpp>
#include <clang/AST/ASTContext.h>
#include <clang/AST/Decl.h>
Expand All @@ -9,11 +10,11 @@
#include <optional>

namespace Builders {
std::optional<std::pair<IR::AccessModifier, IR::Variable>>
std::optional<std::pair<IRProxy::AccessModifier, IR::Variable>>
buildField(clang::FieldDecl* field,
std::optional<clang::QualType> templateSpecialization) {
IR::Variable variable;
IR::AccessModifier modifier;
IRProxy::AccessModifier modifier;
variable.m_name = field->getName();

// This is passed so that while extracting text from types it is exactly what the user wrote
Expand Down
5 changes: 3 additions & 2 deletions src/Builders/fieldBuilder.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#pragma once

#include "IRProxy/IRData.hpp"
#include <IR/ir.hpp>
#include <clang/AST/Decl.h>
#include <clang/AST/Type.h>
Expand All @@ -15,9 +16,9 @@ namespace Builders {
* @param: clang::FieldDecl field
* std::optional<clang::QualType> templateSpecialization
*
* @return: std::optional<std::pair<IR::AccessModifier modifier, IR::Variable variable>>
* @return: std::optional<std::pair<IRProxy::AccessModifier modifier, IR::Variable variable>>
*/
std::optional<std::pair<IR::AccessModifier, IR::Variable>> buildField(
std::optional<std::pair<IRProxy::AccessModifier, IR::Variable>> buildField(
clang::FieldDecl* field,
std::optional<clang::QualType> templateSpecialization = std::nullopt);

Expand Down
36 changes: 31 additions & 5 deletions src/Builders/functionBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,49 @@
#include "Builders/commonBuilder.hpp"
#include "Builders/structBuilder.hpp"
#include "Builders/typeBuilder.hpp"
#include "Helpers/getStructData.hpp"
#include "Helpers/walkIRStructure.hpp"
#include <IR/ir.hpp>
#include <algorithm>
#include <clang/AST/ASTContext.h>
#include <clang/AST/Decl.h>
#include <clang/AST/DeclCXX.h>
#include <clang/AST/PrettyPrinter.h>
#include <clang/AST/Type.h>
#include <clang/Basic/Specifiers.h>
#include <deque>
#include <llvm/Support/Casting.h>
#include <string>
#include <variant>

namespace {
struct FunctionData {
std::optional<IRProxy::AccessModifier> m_modifier;
bool m_isConstructor;
bool m_isDestructor;
};

void addFunctionToVariant(std::optional<IR::AccessModifier> modifier,
void addFunctionToVariant(FunctionData data,
std::variant<IR::Namespace*, IR::Struct*> const& v,
IR::Function f) {
if (auto ns = std::get_if<IR::Namespace*>(&v)) {
auto& functions = (*ns)->m_functions;
functions.push_back(f);
} else if (auto irStruct = std::get_if<IR::Struct*>(&v)) {
auto& functions = (*irStruct)->m_functions;
functions.push_back({modifier.value(), f});
// Add to the correct container in the struct
if (auto structData = Helpers::getStructDataBasedOnAccess(
**irStruct, data.m_modifier.value())) {
if (data.m_isConstructor) {
auto& functions = structData->m_constructors;
functions.push_back(f);
} else if (data.m_isDestructor) {
auto& functions = structData->m_destructors;
functions.push_back(f);
} else {
auto& functions = structData->m_functions;
functions.push_back(f);
}
}
}
}

Expand Down Expand Up @@ -53,8 +73,9 @@ void addFunction(IRProxy::Function const& f, IR::Namespace& globalNamespace) {
Helpers::walkPathThroughStructure(path, globalNamespace);

// Create and add the function
addFunctionToVariant(
f.m_modifier, parentOfNewFunction, createFunction(name, f));
addFunctionToVariant({f.m_modifier, f.m_isConstructor, f.m_isDestructor},
parentOfNewFunction,
createFunction(name, f));
}
} // namespace

Expand Down Expand Up @@ -99,6 +120,11 @@ buildFunction(clang::FunctionDecl* functionDecl,

parsedFunc.m_isStatic = functionDecl->isStatic();

parsedFunc.m_isConstructor =
llvm::isa<clang::CXXConstructorDecl>(functionDecl);
parsedFunc.m_isDestructor =
llvm::isa<clang::CXXDestructorDecl>(functionDecl);

return {FunctionError::Ok, parsedFunc};
}

Expand Down
4 changes: 2 additions & 2 deletions src/Builders/namespaceBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
#include "IR/ir.hpp"
#include <algorithm>
#include <deque>
#include <map>
#include <queue>
#include <string>
#include <string_view>
#include <unordered_map>
#include <vector>

namespace {
Expand Down Expand Up @@ -55,7 +55,7 @@ void addNamespaceToRoot(IR::Namespace& rootNS,
namespace Builders {

void addGlobalVariables(
std::unordered_map<std::string, std::vector<IR::Variable>> const& variables,
std::map<std::string, std::vector<IR::Variable>> const& variables,
IR::Namespace& globalNS) {
std::queue<IR::Namespace*> namespaces;
namespaces.push(&globalNS);
Expand Down
4 changes: 2 additions & 2 deletions src/Builders/namespaceBuilder.hpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#pragma once

#include <IR/ir.hpp>
#include <map>
#include <string>
#include <unordered_map>
#include <vector>

namespace Builders {
Expand All @@ -17,6 +17,6 @@ buildNamespaceStructure(std::vector<std::string> const& namespaces);
* Add the variables to the corresponding namespaces
*/
void addGlobalVariables(
std::unordered_map<std::string, std::vector<IR::Variable>> const& variables,
std::map<std::string, std::vector<IR::Variable>> const& variables,
IR::Namespace& globalNS);
} // namespace Builders
46 changes: 34 additions & 12 deletions src/Builders/structBuilder.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "Builders/structBuilder.hpp"
#include "Helpers/getStructData.hpp"
#include "Helpers/walkIRStructure.hpp"
#include "IR/ir.hpp"
#include <algorithm>
Expand All @@ -11,14 +12,18 @@

namespace {

void addStructToVariant(std::variant<IR::Namespace*, IR::Struct*> const& v,
void addStructToVariant(std::optional<IRProxy::AccessModifier> modifier,
std::variant<IR::Namespace*, IR::Struct*> const& v,
IR::Struct newStruct) {
if (auto ns = std::get_if<IR::Namespace*>(&v)) {
auto& children = (*ns)->m_structs;
children.push_back(newStruct);
} else if (auto irStruct = std::get_if<IR::Struct*>(&v)) {
auto& children = (*irStruct)->m_structs;
children.push_back(newStruct);
if (auto structData = Helpers::getStructDataBasedOnAccess(
**irStruct, modifier.value())) {
auto& children = structData->m_structs;
children.push_back(newStruct);
}
}
}

Expand All @@ -30,7 +35,11 @@ IR::Struct createStruct(IRProxy::Struct& s) {
newStruct.m_name = name;
// Representation is the fully qualified name
newStruct.m_representation = s.m_fullyQualifiedName;
newStruct.m_memberVariables = s.m_variables;

newStruct.m_public.m_memberVariables = s.m_publicVariables;
newStruct.m_private.m_memberVariables = s.m_privateVariables;
newStruct.m_protected.m_memberVariables = s.m_protectedVariables;

newStruct.m_templateArguments = s.m_templateArguments;

newStruct.m_hasImplicitDefaultConstructor =
Expand All @@ -48,13 +57,13 @@ void addStruct(IRProxy::Struct& s, IR::Namespace& globalNamespace) {
Helpers::walkPathThroughStructure(path, globalNamespace);

// Create and add the struct
addStructToVariant(parentOfNewStruct, createStruct(s));
addStructToVariant(s.m_modifier, parentOfNewStruct, createStruct(s));
}

std::optional<std::vector<IRProxy::MemberVariable>> getVariables(
IRProxy::Struct const& s,
std::unordered_map<std::string, std::vector<IRProxy::MemberVariable>>&
memberVariables) {
std::optional<std::vector<IRProxy::MemberVariable>>
getVariables(IRProxy::Struct const& s,
std::map<std::string, std::vector<IRProxy::MemberVariable>>&
memberVariables) {
if (auto variables = memberVariables.find(s.m_fullyQualifiedName);
variables != memberVariables.end()) {
return variables->second;
Expand All @@ -66,12 +75,25 @@ std::optional<std::vector<IRProxy::MemberVariable>> getVariables(

namespace Builders {

void addMemberVariables(std::vector<IRProxy::Struct>& structs,
std::unordered_map<std::string, std::vector<IRProxy::MemberVariable>>& memberVariables) {
void addMemberVariables(
std::vector<IRProxy::Struct>& structs,
std::map<std::string, std::vector<IRProxy::MemberVariable>>&
memberVariables) {
for (auto& s : structs) {
if (auto variables = getVariables(s, memberVariables)) {
for (auto& variable : variables.value()) {
s.m_variables.push_back({variable.m_modifier, variable.m_variable});
using IRProxy::AccessModifier;
switch (variable.m_modifier) {
case AccessModifier::Public:
s.m_publicVariables.push_back(variable.m_variable);
break;
case AccessModifier::Private:
s.m_privateVariables.push_back(variable.m_variable);
break;
case AccessModifier::Protected:
s.m_protectedVariables.push_back(variable.m_variable);
break;
}
}
}
}
Expand Down
8 changes: 5 additions & 3 deletions src/Builders/structBuilder.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,18 @@

#include "IR/ir.hpp"
#include "IRProxy/IRData.hpp"
#include <map>
#include <string>
#include <unordered_map>
#include <vector>

namespace Builders {
/**
* Add the variables to the structs
*/
void addMemberVariables(std::vector<IRProxy::Struct>& structs,
std::unordered_map<std::string, std::vector<IRProxy::MemberVariable>>& memberVariables);
void addMemberVariables(
std::vector<IRProxy::Struct>& structs,
std::map<std::string, std::vector<IRProxy::MemberVariable>>&
memberVariables);

/**
* Convert the Helpers::Struct to IR::Struct and add them to the structure
Expand Down
17 changes: 17 additions & 0 deletions src/Helpers/getStructData.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#include "Helpers/getStructData.hpp"
#include "IRProxy/IRData.hpp"
#include <IR/ir.hpp>

namespace Helpers {

IR::StructData* getStructDataBasedOnAccess(IR::Struct& s,
IRProxy::AccessModifier access) {
using IRProxy::AccessModifier;
switch (access) {
case AccessModifier::Public: return &s.m_public;
case AccessModifier::Private: return &s.m_private;
case AccessModifier::Protected: return &s.m_protected;
}
return nullptr;
}
}
15 changes: 15 additions & 0 deletions src/Helpers/getStructData.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#pragma once

#include "IRProxy/IRData.hpp"
#include <IR/ir.hpp>

namespace Helpers {

/**
* Find the data prefixed with accessModifier (i.e. public/private/protected)
* This contains functions etc.
* Returns nullptr if not found (should not happen)
*/
IR::StructData* getStructDataBasedOnAccess(IR::Struct& s,
IRProxy::AccessModifier access);
}
Loading

0 comments on commit c3faaec

Please sign in to comment.