forked from OSchip/llvm-project
[libclang] Sync-up the way top-level decls in an ASTUnit are handled with how decls in a DeclContext are handled.
rdar://19775013 llvm-svn: 274378
This commit is contained in:
parent
0ba05f1835
commit
e7c91045da
|
@ -70,7 +70,7 @@
|
|||
// CHECK-NOT: properties-class-extensions.m:16:25: ObjCInstanceMethodDecl=bar:16:25 Extent=[16:25 - 16:28]
|
||||
// CHECK: properties-class-extensions.m:19:26: ObjCInstanceMethodDecl=setBar::19:26 Extent=[19:26 - 19:29]
|
||||
// CHECK: properties-class-extensions.m:19:26: ParmDecl=bar:19:26 (Definition) Extent=[19:26 - 19:29]
|
||||
// CHECK: properties-class-extensions.m:24:8: ObjCInterfaceDecl=Rdar8467189_Bar:24:8 Extent=[24:1 - 24:23]
|
||||
// CHECK-NOT: properties-class-extensions.m:24:8: ObjCInterfaceDecl=Rdar8467189_Bar:24:8
|
||||
// CHECK: properties-class-extensions.m:24:8: ObjCClassRef=Rdar8467189_Bar:24:8 Extent=[24:8 - 24:23]
|
||||
// CHECK: properties-class-extensions.m:25:11: ObjCProtocolDecl=Rdar8467189_FooProtocol:25:11 (Definition) Extent=[25:1 - 27:5]
|
||||
// CHECK: properties-class-extensions.m:26:39: ObjCPropertyDecl=Rdar8467189_Bar:26:39 [readonly,] Extent=[26:1 - 26:54]
|
||||
|
|
|
@ -523,8 +523,10 @@ bool CursorVisitor::VisitChildren(CXCursor Cursor) {
|
|||
for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
|
||||
TLEnd = CXXUnit->top_level_end();
|
||||
TL != TLEnd; ++TL) {
|
||||
if (Visit(MakeCXCursor(*TL, TU, RegionOfInterest), true))
|
||||
return true;
|
||||
const Optional<bool> V = handleDeclForVisitation(*TL);
|
||||
if (!V.hasValue())
|
||||
continue;
|
||||
return V.getValue();
|
||||
}
|
||||
} else if (VisitDeclContext(
|
||||
CXXUnit->getASTContext().getTranslationUnitDecl()))
|
||||
|
@ -621,42 +623,50 @@ bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
|
|||
Decl *D = *I;
|
||||
if (D->getLexicalDeclContext() != DC)
|
||||
continue;
|
||||
CXCursor Cursor = MakeCXCursor(D, TU, RegionOfInterest);
|
||||
|
||||
// Ignore synthesized ivars here, otherwise if we have something like:
|
||||
// @synthesize prop = _prop;
|
||||
// and '_prop' is not declared, we will encounter a '_prop' ivar before
|
||||
// encountering the 'prop' synthesize declaration and we will think that
|
||||
// we passed the region-of-interest.
|
||||
if (ObjCIvarDecl *ivarD = dyn_cast<ObjCIvarDecl>(D)) {
|
||||
if (ivarD->getSynthesize())
|
||||
continue;
|
||||
}
|
||||
|
||||
// FIXME: ObjCClassRef/ObjCProtocolRef for forward class/protocol
|
||||
// declarations is a mismatch with the compiler semantics.
|
||||
if (Cursor.kind == CXCursor_ObjCInterfaceDecl) {
|
||||
ObjCInterfaceDecl *ID = cast<ObjCInterfaceDecl>(D);
|
||||
if (!ID->isThisDeclarationADefinition())
|
||||
Cursor = MakeCursorObjCClassRef(ID, ID->getLocation(), TU);
|
||||
|
||||
} else if (Cursor.kind == CXCursor_ObjCProtocolDecl) {
|
||||
ObjCProtocolDecl *PD = cast<ObjCProtocolDecl>(D);
|
||||
if (!PD->isThisDeclarationADefinition())
|
||||
Cursor = MakeCursorObjCProtocolRef(PD, PD->getLocation(), TU);
|
||||
}
|
||||
|
||||
const Optional<bool> &V = shouldVisitCursor(Cursor);
|
||||
const Optional<bool> V = handleDeclForVisitation(D);
|
||||
if (!V.hasValue())
|
||||
continue;
|
||||
if (!V.getValue())
|
||||
return false;
|
||||
if (Visit(Cursor, true))
|
||||
return true;
|
||||
return V.getValue();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Optional<bool> CursorVisitor::handleDeclForVisitation(const Decl *D) {
|
||||
CXCursor Cursor = MakeCXCursor(D, TU, RegionOfInterest);
|
||||
|
||||
// Ignore synthesized ivars here, otherwise if we have something like:
|
||||
// @synthesize prop = _prop;
|
||||
// and '_prop' is not declared, we will encounter a '_prop' ivar before
|
||||
// encountering the 'prop' synthesize declaration and we will think that
|
||||
// we passed the region-of-interest.
|
||||
if (auto *ivarD = dyn_cast<ObjCIvarDecl>(D)) {
|
||||
if (ivarD->getSynthesize())
|
||||
return None;
|
||||
}
|
||||
|
||||
// FIXME: ObjCClassRef/ObjCProtocolRef for forward class/protocol
|
||||
// declarations is a mismatch with the compiler semantics.
|
||||
if (Cursor.kind == CXCursor_ObjCInterfaceDecl) {
|
||||
auto *ID = cast<ObjCInterfaceDecl>(D);
|
||||
if (!ID->isThisDeclarationADefinition())
|
||||
Cursor = MakeCursorObjCClassRef(ID, ID->getLocation(), TU);
|
||||
|
||||
} else if (Cursor.kind == CXCursor_ObjCProtocolDecl) {
|
||||
auto *PD = cast<ObjCProtocolDecl>(D);
|
||||
if (!PD->isThisDeclarationADefinition())
|
||||
Cursor = MakeCursorObjCProtocolRef(PD, PD->getLocation(), TU);
|
||||
}
|
||||
|
||||
const Optional<bool> V = shouldVisitCursor(Cursor);
|
||||
if (!V.hasValue())
|
||||
return None;
|
||||
if (!V.getValue())
|
||||
return false;
|
||||
if (Visit(Cursor, true))
|
||||
return true;
|
||||
return None;
|
||||
}
|
||||
|
||||
bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
|
||||
llvm_unreachable("Translation units are visited directly by Visit()");
|
||||
}
|
||||
|
|
|
@ -265,6 +265,9 @@ public:
|
|||
bool RunVisitorWorkList(VisitorWorkList &WL);
|
||||
void EnqueueWorkList(VisitorWorkList &WL, const Stmt *S);
|
||||
LLVM_ATTRIBUTE_NOINLINE bool Visit(const Stmt *S);
|
||||
|
||||
private:
|
||||
Optional<bool> handleDeclForVisitation(const Decl *D);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue