|
|
@ -70,6 +70,8 @@ void* IgnorePtr = reinterpret_cast<void*>(0x1); |
|
|
|
|
|
|
|
|
|
|
|
Parser::Parser(CppParserOptions* Opts) : lib(Opts->ASTContext), opts(Opts), index(0) |
|
|
|
Parser::Parser(CppParserOptions* Opts) : lib(Opts->ASTContext), opts(Opts), index(0) |
|
|
|
{ |
|
|
|
{ |
|
|
|
|
|
|
|
supportedStdTypes.insert("allocator"); |
|
|
|
|
|
|
|
supportedStdTypes.insert("basic_string"); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
LayoutField Parser::WalkVTablePointer(Class* Class, |
|
|
|
LayoutField Parser::WalkVTablePointer(Class* Class, |
|
|
@ -821,14 +823,14 @@ Class* Parser::WalkRecordCXX(const clang::CXXRecordDecl* Record) |
|
|
|
static int I = 0; |
|
|
|
static int I = 0; |
|
|
|
|
|
|
|
|
|
|
|
static bool IsRecordValid(const clang::RecordDecl* RC, |
|
|
|
static bool IsRecordValid(const clang::RecordDecl* RC, |
|
|
|
std::vector<const clang::RecordDecl*>& Visited) |
|
|
|
std::unordered_set<const clang::RecordDecl*>& Visited) |
|
|
|
{ |
|
|
|
{ |
|
|
|
using namespace clang; |
|
|
|
using namespace clang; |
|
|
|
|
|
|
|
|
|
|
|
if (std::find(Visited.begin(), Visited.end(), RC) != Visited.end()) |
|
|
|
if (Visited.find(RC) != Visited.end()) |
|
|
|
return true; |
|
|
|
return true; |
|
|
|
|
|
|
|
|
|
|
|
Visited.push_back(RC); |
|
|
|
Visited.insert(RC); |
|
|
|
if (RC->isInvalidDecl()) |
|
|
|
if (RC->isInvalidDecl()) |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
for (auto Field : RC->fields()) |
|
|
|
for (auto Field : RC->fields()) |
|
|
@ -845,7 +847,7 @@ static bool IsRecordValid(const clang::RecordDecl* RC, |
|
|
|
|
|
|
|
|
|
|
|
static bool IsRecordValid(const clang::RecordDecl* RC) |
|
|
|
static bool IsRecordValid(const clang::RecordDecl* RC) |
|
|
|
{ |
|
|
|
{ |
|
|
|
std::vector<const clang::RecordDecl*> Visited; |
|
|
|
std::unordered_set<const clang::RecordDecl*> Visited; |
|
|
|
return IsRecordValid(RC, Visited); |
|
|
|
return IsRecordValid(RC, Visited); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -881,6 +883,23 @@ static bool HasLayout(const clang::RecordDecl* Record) |
|
|
|
return true; |
|
|
|
return true; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool Parser::IsSupported(const clang::RecordDecl* RD) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
return !c->getSourceManager().isInSystemHeader(RD->getLocStart()) || |
|
|
|
|
|
|
|
supportedStdTypes.find(RD->getName()) != supportedStdTypes.end(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool Parser::IsSupported(const clang::CXXMethodDecl* MD) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
using namespace clang; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return !c->getSourceManager().isInSystemHeader(MD->getLocStart()) || |
|
|
|
|
|
|
|
isa<CXXConstructorDecl>(MD) || isa<CXXDestructorDecl>(MD) || |
|
|
|
|
|
|
|
(MD->getName() == "c_str" && |
|
|
|
|
|
|
|
supportedStdTypes.find(MD->getParent()->getName()) != |
|
|
|
|
|
|
|
supportedStdTypes.end()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void Parser::WalkRecord(const clang::RecordDecl* Record, Class* RC) |
|
|
|
void Parser::WalkRecord(const clang::RecordDecl* Record, Class* RC) |
|
|
|
{ |
|
|
|
{ |
|
|
|
using namespace clang; |
|
|
|
using namespace clang; |
|
|
@ -920,11 +939,15 @@ void Parser::WalkRecord(const clang::RecordDecl* Record, Class* RC) |
|
|
|
ReadClassLayout(RC, Record, CharUnits(), true); |
|
|
|
ReadClassLayout(RC, Record, CharUnits(), true); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
for(auto it = Record->decls_begin(); it != Record->decls_end(); ++it) |
|
|
|
for (auto FD : Record->fields()) |
|
|
|
{ |
|
|
|
WalkFieldCXX(FD, RC); |
|
|
|
auto D = *it; |
|
|
|
|
|
|
|
|
|
|
|
if (!IsSupported(Record)) |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
|
|
switch(D->getKind()) |
|
|
|
for (auto D : Record->decls()) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
switch (D->getKind()) |
|
|
|
{ |
|
|
|
{ |
|
|
|
case Decl::CXXConstructor: |
|
|
|
case Decl::CXXConstructor: |
|
|
|
case Decl::CXXDestructor: |
|
|
|
case Decl::CXXDestructor: |
|
|
@ -932,13 +955,8 @@ void Parser::WalkRecord(const clang::RecordDecl* Record, Class* RC) |
|
|
|
case Decl::CXXMethod: |
|
|
|
case Decl::CXXMethod: |
|
|
|
{ |
|
|
|
{ |
|
|
|
auto MD = cast<CXXMethodDecl>(D); |
|
|
|
auto MD = cast<CXXMethodDecl>(D); |
|
|
|
WalkMethodCXX(MD); |
|
|
|
if (IsSupported(MD)) |
|
|
|
break; |
|
|
|
WalkMethodCXX(MD); |
|
|
|
} |
|
|
|
|
|
|
|
case Decl::Field: |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
auto FD = cast<FieldDecl>(D); |
|
|
|
|
|
|
|
WalkFieldCXX(FD, RC); |
|
|
|
|
|
|
|
break; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
case Decl::AccessSpec: |
|
|
|
case Decl::AccessSpec: |
|
|
@ -954,6 +972,7 @@ void Parser::WalkRecord(const clang::RecordDecl* Record, Class* RC) |
|
|
|
RC->Specifiers.push_back(AccessDecl); |
|
|
|
RC->Specifiers.push_back(AccessDecl); |
|
|
|
break; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
case Decl::Field: // fields already handled
|
|
|
|
case Decl::IndirectField: // FIXME: Handle indirect fields
|
|
|
|
case Decl::IndirectField: // FIXME: Handle indirect fields
|
|
|
|
break; |
|
|
|
break; |
|
|
|
case Decl::CXXRecord: |
|
|
|
case Decl::CXXRecord: |
|
|
|