Validate RecordDecl

This commit is contained in:
Fangrui Song 2018-08-03 16:11:32 -07:00
parent b5c2a48bb0
commit 3931951406
2 changed files with 23 additions and 4 deletions

View File

@ -27,7 +27,7 @@ OUTPUT:
"bases": [], "bases": [],
"derived": [], "derived": [],
"vars": [], "vars": [],
"uses": ["5:3-5:9|10177235824697315808|3|16420", "5:3-5:9|2459767597003442547|3|16420"], "uses": ["5:3-5:9|10177235824697315808|3|16420"],
"callees": [] "callees": []
}, { }, {
"usr": 2459767597003442547, "usr": 2459767597003442547,

View File

@ -301,6 +301,19 @@ const Decl* GetSpecialized(const Decl* D) {
return Template; return Template;
} }
bool ValidateRecord(const RecordDecl *RD) {
for (const auto *I : RD->fields()){
QualType FQT = I->getType();
if (FQT->isIncompleteType() || FQT->isDependentType())
return false;
if (const RecordType *ChildType = I->getType()->getAs<RecordType>())
if (const RecordDecl *Child = ChildType->getDecl())
if (!ValidateRecord(Child))
return false;
}
return true;
}
class IndexDataConsumer : public index::IndexDataConsumer { class IndexDataConsumer : public index::IndexDataConsumer {
public: public:
ASTContext *Ctx; ASTContext *Ctx;
@ -831,18 +844,24 @@ public:
: lsSymbolKind::Class; : lsSymbolKind::Class;
if (is_def) { if (is_def) {
SmallVector<std::pair<const RecordDecl *, int>, 2> Stack{{RD, 0}}; SmallVector<std::pair<const RecordDecl *, int>, 2> Stack{{RD, 0}};
llvm::DenseSet<const RecordDecl *> Seen;
Seen.insert(RD);
while (Stack.size()) { while (Stack.size()) {
int offset; int offset;
std::tie(RD, offset) = Stack.back(); std::tie(RD, offset) = Stack.back();
Stack.pop_back(); Stack.pop_back();
if (!RD->isCompleteDefinition() || RD->isDependentType()) if (!RD->isCompleteDefinition() || RD->isDependentType() ||
!ValidateRecord(RD))
offset = -1; offset = -1;
for (FieldDecl *FD : RD->fields()) { for (FieldDecl *FD : RD->fields()) {
int offset1 = offset >= 0 ? offset + Ctx->getFieldOffset(FD) : -1; int offset1 = offset >= 0 ? offset + Ctx->getFieldOffset(FD) : -1;
if (FD->getIdentifier()) if (FD->getIdentifier())
type->def.vars.emplace_back(GetUsr(FD), offset1); type->def.vars.emplace_back(GetUsr(FD), offset1);
else if (const auto *RT1 = FD->getType()->getAs<RecordType>()) else if (const auto *RT1 = FD->getType()->getAs<RecordType>()) {
Stack.push_back({RT1->getDecl(), offset1}); if (const RecordDecl *RD1 = RT1->getDecl())
if (Seen.insert(RD1).second)
Stack.push_back({RD1, offset1});
}
} }
} }
} }