typedef llvm::TinyPtrVector<const CXXMethodDecl*> CXXMethodVector;
llvm::DenseMap<const CXXMethodDecl *, CXXMethodVector> OverriddenMethods;
- /// \brief Used to cache results from \c getBaseObjCCategoriesAfterInterface.
- mutable llvm::DenseMap<const ObjCInterfaceDecl *,
- llvm::SmallVector<const ObjCCategoryDecl *, 2> > CatsAfterInterface;
-
/// \brief Mapping from each declaration context to its corresponding lambda
/// mangling context.
llvm::DenseMap<const DeclContext *, LambdaMangleContext> LambdaMangleContexts;
void getOverriddenMethods(
const NamedDecl *Method,
SmallVectorImpl<const NamedDecl *> &Overridden) const;
-
- /// \brief Returns the ObjC categories of base classes, that were declared
- /// after the given interface declaration.
- void getBaseObjCCategoriesAfterInterface(const ObjCInterfaceDecl *D,
- SmallVectorImpl<const ObjCCategoryDecl *> &Cats) const;
-
+
/// \brief Notify the AST context that a new import declaration has been
/// parsed or implicitly created within this translation unit.
void addedLocalImportDecl(ImportDecl *Import);
assert(D);
if (const CXXMethodDecl *CXXMethod = dyn_cast<CXXMethodDecl>(D)) {
- Overridden.append(overridden_methods_begin(CXXMethod),
- overridden_methods_end(CXXMethod));
+ Overridden.append(CXXMethod->begin_overridden_methods(),
+ CXXMethod->end_overridden_methods());
return;
}
Overridden.append(OverDecls.begin(), OverDecls.end());
}
-void ASTContext::getBaseObjCCategoriesAfterInterface(
- const ObjCInterfaceDecl *D,
- SmallVectorImpl<const ObjCCategoryDecl *> &Cats) const {
- if (!D)
- return;
-
- typedef llvm::SmallVector<const ObjCCategoryDecl *, 2> VecTy;
- typedef llvm::DenseMap<const ObjCInterfaceDecl *, VecTy> MapTy;
-
- std::pair<MapTy::iterator, bool>
- InsertOp = CatsAfterInterface.insert(std::make_pair(D, VecTy()));
- VecTy &Vec = InsertOp.first->second;
- if (!InsertOp.second) {
- // already in map.
- Cats.append(Vec.begin(), Vec.end());
- return;
- }
-
- SourceLocation Loc = D->getLocation();
- for (const ObjCInterfaceDecl *
- Class = D->getSuperClass(); Class; Class = Class->getSuperClass()) {
- for (ObjCInterfaceDecl::known_categories_iterator
- CatI = Class->known_categories_begin(),
- CatEnd = Class->known_categories_end();
- CatI != CatEnd; ++CatI) {
- if (SourceMgr.isBeforeInTranslationUnit(Loc, CatI->getLocation()))
- Vec.push_back(*CatI);
- }
- }
-
- Cats.append(Vec.begin(), Vec.end());
-}
-
void ASTContext::addedLocalImportDecl(ImportDecl *Import) {
assert(!Import->NextLocalImport && "Import declaration already in the chain");
assert(!Import->isFromASTFile() && "Non-local import declaration");
}
}
+static void collectOnCategoriesAfterLocation(SourceLocation Loc,
+ const ObjCInterfaceDecl *Class,
+ SourceManager &SM,
+ const ObjCMethodDecl *Method,
+ SmallVectorImpl<const ObjCMethodDecl *> &Methods) {
+ if (!Class)
+ return;
+
+ for (ObjCInterfaceDecl::known_categories_iterator
+ Cat = Class->known_categories_begin(),
+ CatEnd = Class->known_categories_end();
+ Cat != CatEnd; ++Cat) {
+ if (SM.isBeforeInTranslationUnit(Loc, Cat->getLocation()))
+ CollectOverriddenMethodsRecurse(*Cat, Method, Methods, true);
+ }
+
+ collectOnCategoriesAfterLocation(Loc, Class->getSuperClass(), SM,
+ Method, Methods);
+}
+
/// \brief Faster collection that is enabled when ObjCMethodDecl::isOverriding()
/// returns false.
/// You'd think that in that case there are no overrides but categories can
/// further in super classes.
/// Methods in an implementation can overide methods in super class's category
/// but not in current class's category. But, such methods
-static void collectOverriddenMethodsFast(ASTContext &Ctx,
+static void collectOverriddenMethodsFast(SourceManager &SM,
const ObjCMethodDecl *Method,
SmallVectorImpl<const ObjCMethodDecl *> &Methods) {
assert(!Method->isOverriding());
if (!Class)
return;
- SmallVector<const ObjCCategoryDecl *, 32> Cats;
- Ctx.getBaseObjCCategoriesAfterInterface(Class, Cats);
- for (SmallVectorImpl<const ObjCCategoryDecl *>::iterator
- I = Cats.begin(), E = Cats.end(); I != E; ++I)
- CollectOverriddenMethodsRecurse(*I, Method, Methods, true);
+ collectOnCategoriesAfterLocation(Class->getLocation(), Class->getSuperClass(),
+ SM, Method, Methods);
}
void ObjCMethodDecl::getOverriddenMethods(
}
if (!Method->isOverriding()) {
- collectOverriddenMethodsFast(getASTContext(), Method, Overridden);
+ collectOverriddenMethodsFast(getASTContext().getSourceManager(),
+ Method, Overridden);
} else {
collectOverriddenMethodsSlow(Method, Overridden);
assert(!Overridden.empty() &&
}
@end
+@interface Base1
+@end
+@interface Sub1 : Base1
+@end
+@interface Sub1(cat)
+-(id)prop;
+@end
+
+void test1(Sub1 *s) {
+ use([s prop]);
+ use([s prop]);
+}
+
+@interface Base1(cat)
+@property (weak) id prop;
+@end
+
+void test2(Sub1 *s) {
+ use([s prop]); // expected-warning{{weak property 'prop' is accessed multiple times}}
+ use([s prop]); // expected-note{{also accessed here}}
+}
+
class Wrapper {
Test *a;