summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/tools/clang/lib/Sema/SemaObjCProperty.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Sema/SemaObjCProperty.cpp')
-rw-r--r--contrib/llvm/tools/clang/lib/Sema/SemaObjCProperty.cpp42
1 files changed, 39 insertions, 3 deletions
diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaObjCProperty.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaObjCProperty.cpp
index 72b6020..5e7b4b8 100644
--- a/contrib/llvm/tools/clang/lib/Sema/SemaObjCProperty.cpp
+++ b/contrib/llvm/tools/clang/lib/Sema/SemaObjCProperty.cpp
@@ -19,6 +19,7 @@
#include "clang/AST/ExprObjC.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Lex/Lexer.h"
+#include "clang/Lex/Preprocessor.h"
#include "clang/Sema/Initialization.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/SmallString.h"
@@ -406,9 +407,11 @@ Sema::HandlePropertyInClassExtension(Scope *S,
// this conversion is safe only because the wider type is for a 'readonly'
// property in primary class and 'narrowed' type for a 'readwrite' property
// in continuation class.
- if (!isa<ObjCObjectPointerType>(PIDecl->getType()) ||
- !isa<ObjCObjectPointerType>(PDecl->getType()) ||
- (!isObjCPointerConversion(PDecl->getType(), PIDecl->getType(),
+ QualType PrimaryClassPropertyT = Context.getCanonicalType(PIDecl->getType());
+ QualType ClassExtPropertyT = Context.getCanonicalType(PDecl->getType());
+ if (!isa<ObjCObjectPointerType>(PrimaryClassPropertyT) ||
+ !isa<ObjCObjectPointerType>(ClassExtPropertyT) ||
+ (!isObjCPointerConversion(ClassExtPropertyT, PrimaryClassPropertyT,
ConvertedType, IncompatibleObjC))
|| IncompatibleObjC) {
Diag(AtLoc,
@@ -1854,6 +1857,39 @@ void Sema::DiagnoseOwningPropertyGetterSynthesis(const ObjCImplementationDecl *D
Diag(PD->getLocation(), diag::err_cocoa_naming_owned_rule);
else
Diag(PD->getLocation(), diag::warn_cocoa_naming_owned_rule);
+
+ // Look for a getter explicitly declared alongside the property.
+ // If we find one, use its location for the note.
+ SourceLocation noteLoc = PD->getLocation();
+ SourceLocation fixItLoc;
+ for (auto *getterRedecl : method->redecls()) {
+ if (getterRedecl->isImplicit())
+ continue;
+ if (getterRedecl->getDeclContext() != PD->getDeclContext())
+ continue;
+ noteLoc = getterRedecl->getLocation();
+ fixItLoc = getterRedecl->getLocEnd();
+ }
+
+ Preprocessor &PP = getPreprocessor();
+ TokenValue tokens[] = {
+ tok::kw___attribute, tok::l_paren, tok::l_paren,
+ PP.getIdentifierInfo("objc_method_family"), tok::l_paren,
+ PP.getIdentifierInfo("none"), tok::r_paren,
+ tok::r_paren, tok::r_paren
+ };
+ StringRef spelling = "__attribute__((objc_method_family(none)))";
+ StringRef macroName = PP.getLastMacroWithSpelling(noteLoc, tokens);
+ if (!macroName.empty())
+ spelling = macroName;
+
+ auto noteDiag = Diag(noteLoc, diag::note_cocoa_naming_declare_family)
+ << method->getDeclName() << spelling;
+ if (fixItLoc.isValid()) {
+ SmallString<64> fixItText(" ");
+ fixItText += spelling;
+ noteDiag << FixItHint::CreateInsertion(fixItLoc, fixItText);
+ }
}
}
}
OpenPOWER on IntegriCloud