summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>2013-03-14 22:56:43 +0000
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>2013-03-14 22:56:43 +0000
commit3e56dd4fc94a189505f80c09422470f81ce19ca4 (patch)
tree6b65ba5a0c3e4c5624378c230cfd2e4ef922b78e /clang
parent4a89501f820d6472e680f8187e3fe30a6559f140 (diff)
downloadbcm5719-llvm-3e56dd4fc94a189505f80c09422470f81ce19ca4.tar.gz
bcm5719-llvm-3e56dd4fc94a189505f80c09422470f81ce19ca4.zip
Don't try to typo-correct 'super' in an objc method.
This created 2 issues: 1) Performance issue, since typo-correction with PCH/modules is rather expensive. 2) Correctness issue, since if it managed to "correct" 'super' then bogus compiler errors would be emitted, like this: 3.m:8:3: error: unknown type name 'super'; did you mean 'super1'? super.x = 0; ^~~~~ super1 t3.m:5:13: note: 'super1' declared here typedef int super1; ^ t3.m:8:8: error: expected identifier or '(' super.x = 0; ^ llvm-svn: 177126
Diffstat (limited to 'clang')
-rw-r--r--clang/include/clang/Basic/DiagnosticSemaKinds.td2
-rw-r--r--clang/include/clang/Sema/Sema.h4
-rw-r--r--clang/lib/Sema/Sema.cpp8
-rw-r--r--clang/lib/Sema/SemaCodeComplete.cpp2
-rw-r--r--clang/lib/Sema/SemaLookup.cpp10
-rw-r--r--clang/test/SemaObjC/typo-correction.m21
6 files changed, 45 insertions, 2 deletions
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index bd3d1b4e10a..470732ce684 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -6074,6 +6074,8 @@ def warn_direct_ivar_access : Warning<"instance variable %0 is being "
"directly accessed">, InGroup<DiagGroup<"direct-ivar-access">>, DefaultIgnore;
// Spell-checking diagnostics
+def warn_spellcheck_initiated : Warning<"spell-checking initiated for %0">,
+ InGroup<DiagGroup<"spellcheck">>, DefaultIgnore;
def err_unknown_type_or_class_name_suggest : Error<
"unknown %select{type|class}2 name %0; did you mean %1?">;
def err_unknown_typename_suggest : Error<
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 5f4bb1d8405..0f519398b75 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -7430,6 +7430,8 @@ private:
/// The parser maintains this state here.
Scope *CurScope;
+ mutable IdentifierInfo *Ident_super;
+
protected:
friend class Parser;
friend class InitializationSequence;
@@ -7447,6 +7449,8 @@ public:
/// template substitution or instantiation.
Scope *getCurScope() const { return CurScope; }
+ IdentifierInfo *getSuperIdentifier() const;
+
Decl *getObjCDeclContext() const;
DeclContext *getCurLexicalContext() const {
diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp
index 0ddd0619f92..4aeb511abd6 100644
--- a/clang/lib/Sema/Sema.cpp
+++ b/clang/lib/Sema/Sema.cpp
@@ -90,7 +90,7 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer,
AccessCheckingSFINAE(false), InNonInstantiationSFINAEContext(false),
NonInstantiationEntries(0), ArgumentPackSubstitutionIndex(-1),
CurrentInstantiationScope(0), TyposCorrected(0),
- AnalysisWarnings(*this)
+ AnalysisWarnings(*this), Ident_super(0)
{
TUScope = 0;
@@ -1302,3 +1302,9 @@ bool Sema::tryToRecoverWithCall(ExprResult &E, const PartialDiagnostic &PD,
E = ExprError();
return true;
}
+
+IdentifierInfo *Sema::getSuperIdentifier() const {
+ if (!Ident_super)
+ Ident_super = &Context.Idents.get("super");
+ return Ident_super;
+}
diff --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp
index 78d8518b234..6bb954315ab 100644
--- a/clang/lib/Sema/SemaCodeComplete.cpp
+++ b/clang/lib/Sema/SemaCodeComplete.cpp
@@ -5315,7 +5315,7 @@ void Sema::CodeCompleteObjCSuperMessage(Scope *S, SourceLocation SuperLoc,
} else {
// "super" may be the name of a type or variable. Figure out which
// it is.
- IdentifierInfo *Super = &Context.Idents.get("super");
+ IdentifierInfo *Super = getSuperIdentifier();
NamedDecl *ND = LookupSingleName(S, Super, SuperLoc,
LookupOrdinaryName);
if ((CDecl = dyn_cast_or_null<ObjCInterfaceDecl>(ND))) {
diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp
index eae6269ca69..86ddad21f5d 100644
--- a/clang/lib/Sema/SemaLookup.cpp
+++ b/clang/lib/Sema/SemaLookup.cpp
@@ -3734,6 +3734,16 @@ TypoCorrection Sema::CorrectTypo(const DeclarationNameInfo &TypoName,
if (!ActiveTemplateInstantiations.empty())
return TypoCorrection();
+ // Don't try to correct 'super'.
+ if (S && S->isInObjcMethodScope() && Typo == getSuperIdentifier())
+ return TypoCorrection();
+
+ // This is for regression testing. It's disabled by default.
+ if (Diags.getDiagnosticLevel(diag::warn_spellcheck_initiated,
+ TypoName.getLoc()) != DiagnosticsEngine::Ignored)
+ Diag(TypoName.getLoc(), diag::warn_spellcheck_initiated)
+ << TypoName.getName();
+
NamespaceSpecifierSet Namespaces(Context, CurContext, SS);
TypoCorrectionConsumer Consumer(*this, Typo);
diff --git a/clang/test/SemaObjC/typo-correction.m b/clang/test/SemaObjC/typo-correction.m
new file mode 100644
index 00000000000..cb2c91bb76c
--- /dev/null
+++ b/clang/test/SemaObjC/typo-correction.m
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 %s -verify -fsyntax-only -Wspellcheck
+
+@interface B
+@property int x;
+@end
+
+@interface S : B
+@end
+
+// Spell-checking 'undefined' is ok.
+undefined var; // expected-warning {{spell-checking initiated}} \
+ // expected-error {{unknown type name}}
+
+typedef int super1;
+@implementation S
+-(void)foo {
+ // Spell-checking 'super' is not ok.
+ super.x = 0;
+ self.x = 0;
+}
+@end
OpenPOWER on IntegriCloud