Browse Source

Added support for unnamed enums to new parser.

pull/229/head
Elias Holzer 12 years ago
parent
commit
24cd3840b5
  1. 43
      src/CppParser/AST.cpp
  2. 4
      src/CppParser/AST.h
  3. 36
      src/CppParser/Parser.cpp

43
src/CppParser/AST.cpp

@ -270,6 +270,17 @@ Class* DeclarationContext::FindClass(const std::string& Name, bool IsComplete, @@ -270,6 +270,17 @@ Class* DeclarationContext::FindClass(const std::string& Name, bool IsComplete,
return newClass;
}
Enumeration* DeclarationContext::FindEnum(void* OriginalPtr)
{
auto foundEnum = std::find_if(Enums.begin(), Enums.end(),
[&](Enumeration* enumeration) { return enumeration->OriginalPtr == OriginalPtr; });
if (foundEnum != Enums.end())
return *foundEnum;
return nullptr;
}
Enumeration* DeclarationContext::FindEnum(const std::string& Name, bool Create)
{
auto entries = split<std::string>(Name, "::");
@ -304,6 +315,27 @@ Enumeration* DeclarationContext::FindEnum(const std::string& Name, bool Create) @@ -304,6 +315,27 @@ Enumeration* DeclarationContext::FindEnum(const std::string& Name, bool Create)
return _namespace->FindEnum(enumName, Create);
}
Enumeration* DeclarationContext::FindEnumWithItem(const std::string& Name)
{
auto foundEnumIt = std::find_if(Enums.begin(), Enums.end(),
[&](Enumeration* _enum) { return _enum->FindItemByName(Name) != nullptr; });
if (foundEnumIt != Enums.end())
return *foundEnumIt;
for (auto it = Namespaces.begin(); it != Namespaces.end(); ++it)
{
auto foundEnum = (*it)->FindEnumWithItem(Name);
if (foundEnum != nullptr)
return foundEnum;
}
for (auto it = Classes.begin(); it != Classes.end(); ++it)
{
auto foundEnum = (*it)->FindEnumWithItem(Name);
if (foundEnum != nullptr)
return foundEnum;
}
return nullptr;
}
Function* DeclarationContext::FindFunction(const std::string& Name, bool Create)
{
auto foundFunction = std::find_if(Functions.begin(), Functions.end(),
@ -384,6 +416,8 @@ DEF_VECTOR(Function, Parameter*, Parameters) @@ -384,6 +416,8 @@ DEF_VECTOR(Function, Parameter*, Parameters)
Method::Method() : IsDefaultConstructor(false), IsCopyConstructor(false),
IsMoveConstructor(false) { Kind = DeclarationKind::Method; }
// Enumeration
Enumeration::Enumeration() : Declaration(DeclarationKind::Enumeration),
Modifiers((EnumModifiers)0), Type(0), BuiltinType(0) {}
@ -396,6 +430,15 @@ Enumeration::Item::Item(const Item& rhs) : Declaration(rhs), @@ -396,6 +430,15 @@ Enumeration::Item::Item(const Item& rhs) : Declaration(rhs),
DEF_STRING(Enumeration::Item, Expression)
Enumeration::Item* Enumeration::FindItemByName(const std::string& Name)
{
auto foundEnumItem = std::find_if(Items.begin(), Items.end(),
[&](Item _item) { return _item.Name == Name; });
if (foundEnumItem != Items.end())
return &*foundEnumItem;
return nullptr;
}
Variable::Variable() : Declaration(DeclarationKind::Variable) {}
DEF_STRING(Variable, Mangled)

4
src/CppParser/AST.h

@ -402,7 +402,9 @@ struct CS_API DeclarationContext : public Declaration @@ -402,7 +402,9 @@ struct CS_API DeclarationContext : public Declaration
CS_IGNORE FunctionTemplate* FindFunctionTemplate(const std::string& Name,
const std::vector<TemplateParameter>& Params);
CS_IGNORE Enumeration* FindEnum(void* OriginalPtr);
CS_IGNORE Enumeration* FindEnum(const std::string& Name, bool Create = false);
CS_IGNORE Enumeration* FindEnumWithItem(const std::string& Name);
CS_IGNORE Function* FindFunction(const std::string& Name, bool Create = false);
@ -560,6 +562,8 @@ struct CS_API Enumeration : public Declaration @@ -560,6 +562,8 @@ struct CS_API Enumeration : public Declaration
CppSharp::CppParser::AST::Type* Type;
CppSharp::CppParser::AST::BuiltinType* BuiltinType;
VECTOR(Item, Items)
Item* FindItemByName(const std::string& Name);
};
struct CS_API Variable : public Declaration

36
src/CppParser/Parser.cpp

@ -1695,18 +1695,48 @@ Type* Parser::WalkType(clang::QualType QualType, clang::TypeLoc* TL, @@ -1695,18 +1695,48 @@ Type* Parser::WalkType(clang::QualType QualType, clang::TypeLoc* TL,
Enumeration* Parser::WalkEnum(clang::EnumDecl* ED)
{
using namespace clang;
auto NS = GetNamespace(ED);
assert(NS && "Expected a valid namespace");
auto Name = GetTagDeclName(ED);
auto E = NS->FindEnum(Name, /*Create=*/false);
auto E = NS->FindEnum(ED->getCanonicalDecl());
if (E && !E->IsIncomplete)
return E;
if (!E)
{
auto Name = GetTagDeclName(ED);
if (!Name.empty())
E = NS->FindEnum(Name, /*Create=*/false);
else
{
// Enum with no identifier - try to find existing enum through enum items
for (auto it = ED->enumerator_begin(); it != ED->enumerator_end(); ++it)
{
EnumConstantDecl* ECD = (*it);
auto EnumItemName = ECD->getNameAsString();
E = NS->FindEnumWithItem(EnumItemName);
break;
}
}
}
if (E && !E->IsIncomplete)
return E;
if (!E)
{
E = NS->FindEnum(Name, /*Create=*/true);
auto Name = GetTagDeclName(ED);
if (!Name.empty())
E = NS->FindEnum(Name, /*Create=*/true);
else
{
E = new Enumeration();
E->Name = Name;
E->_Namespace = NS;
NS->Enums.push_back(E);
}
HandleDeclaration(ED, E);
}

Loading…
Cancel
Save