diff --git a/src/CppParser/AST.cpp b/src/CppParser/AST.cpp index 3f0afa09..0154bdb8 100644 --- a/src/CppParser/AST.cpp +++ b/src/CppParser/AST.cpp @@ -416,6 +416,17 @@ TypedefDecl* DeclarationContext::FindTypedef(const std::string& Name, bool Creat return tdef; } +Variable* DeclarationContext::FindVariable(const std::string& USR) +{ + auto found = std::find_if(Variables.begin(), Variables.end(), + [&](Variable* var) { return var->USR == USR; }); + + if (found != Variables.end()) + return *found; + + return nullptr; +} + TypedefDecl::TypedefDecl() : Declaration(DeclarationKind::Typedef) {} DEF_STRING(Statement, String) diff --git a/src/CppParser/AST.h b/src/CppParser/AST.h index 4517e52a..0fe1e901 100644 --- a/src/CppParser/AST.h +++ b/src/CppParser/AST.h @@ -438,6 +438,8 @@ public: CS_IGNORE TypedefDecl* FindTypedef(const std::string& Name, bool Create = false); + CS_IGNORE Variable* FindVariable(const std::string& USR); + VECTOR(Namespace*, Namespaces) VECTOR(Enumeration*, Enums) VECTOR(Function*, Functions) diff --git a/src/CppParser/Parser.cpp b/src/CppParser/Parser.cpp index 1aa92b73..14c8c90d 100644 --- a/src/CppParser/Parser.cpp +++ b/src/CppParser/Parser.cpp @@ -2342,10 +2342,18 @@ Variable* Parser::WalkVariable(clang::VarDecl *VD) { using namespace clang; + auto NS = GetNamespace(VD); + assert(NS && "Expected a valid namespace"); + + auto USR = GetDeclUSR(VD); + if (auto Var = NS->FindVariable(USR)) + return Var; + auto Var = new Variable(); HandleDeclaration(VD, Var); Var->Name = VD->getName(); + Var->_Namespace = NS; Var->Access = ConvertToAccess(VD->getAccess()); auto TL = VD->getTypeSourceInfo()->getTypeLoc(); @@ -2354,6 +2362,8 @@ Variable* Parser::WalkVariable(clang::VarDecl *VD) auto Mangled = GetDeclMangledName(VD, TargetABI, /*IsDependent=*/false); Var->Mangled = Mangled; + NS->Variables.push_back(Var); + return Var; } @@ -2811,10 +2821,6 @@ Declaration* Parser::WalkDeclaration(clang::Decl* D, { auto VD = cast(D); Decl = WalkVariable(VD); - - auto NS = GetNamespace(VD); - Decl->_Namespace = NS; - NS->Variables.push_back(static_cast(Decl)); break; } case Decl::CXXConstructor: diff --git a/tests/Basic/Basic.Tests.cs b/tests/Basic/Basic.Tests.cs index e5833086..18e4bda1 100644 --- a/tests/Basic/Basic.Tests.cs +++ b/tests/Basic/Basic.Tests.cs @@ -369,6 +369,14 @@ public class BasicTests : GeneratorTestFixture Assert.That(prop.FieldValue, Is.EqualTo(10)); } + public void TestVariable() + { + // Test field property + var @var = new TestVariables(); + @var.Value = 10; + Assert.That(TestVariables.VALUE, Is.EqualTo(10)); + } + [Test] public unsafe void TestArraysPointers() { diff --git a/tests/Basic/Basic.h b/tests/Basic/Basic.h index dbf453a4..aa193627 100644 --- a/tests/Basic/Basic.h +++ b/tests/Basic/Basic.h @@ -498,6 +498,16 @@ public: int TestIndexedPropertiesInValueType::operator[](int i) { return i; } +// Tests variables +struct DLL_API TestVariables +{ + static int VALUE; + void SetValue(int value = VALUE); +}; + +int TestVariables::VALUE; +void TestVariables::SetValue(int value) { VALUE = value; } + enum struct MyEnum { A, B, C }; class DLL_API TestArraysPointers