aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/Sema/Sema.cpp6
-rw-r--r--lib/Sema/SemaCXXScopeSpec.cpp31
-rw-r--r--lib/Sema/SemaDecl.cpp78
-rw-r--r--lib/Sema/SemaDeclCXX.cpp111
-rw-r--r--lib/Sema/SemaDeclObjC.cpp33
-rw-r--r--lib/Sema/SemaExpr.cpp41
-rw-r--r--lib/Sema/SemaExprMember.cpp38
-rw-r--r--lib/Sema/SemaExprObjC.cpp28
-rw-r--r--lib/Sema/SemaInit.cpp20
-rw-r--r--lib/Sema/SemaLookup.cpp851
-rw-r--r--lib/Sema/SemaTemplate.cpp25
-rw-r--r--lib/Sema/SemaTemplateVariadic.cpp16
-rw-r--r--lib/Serialization/ASTReader.cpp20
-rw-r--r--lib/Serialization/ASTWriter.cpp16
14 files changed, 809 insertions, 505 deletions
diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp
index 7d22031ecb..9550f9aad2 100644
--- a/lib/Sema/Sema.cpp
+++ b/lib/Sema/Sema.cpp
@@ -154,6 +154,8 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer,
AnalysisWarnings(*this)
{
TUScope = 0;
+ LoadedExternalKnownNamespaces = false;
+
if (getLangOptions().CPlusPlus)
FieldCollector.reset(new CXXFieldCollector());
@@ -778,6 +780,10 @@ ExternalSemaSource::ReadMethodPool(Selector Sel) {
return std::pair<ObjCMethodList, ObjCMethodList>();
}
+void ExternalSemaSource::ReadKnownNamespaces(
+ llvm::SmallVectorImpl<NamespaceDecl *> &Namespaces) {
+}
+
void PrettyDeclStackTraceEntry::print(llvm::raw_ostream &OS) const {
SourceLocation Loc = this->Loc;
if (!Loc.isValid() && TheDecl) Loc = TheDecl->getLocation();
diff --git a/lib/Sema/SemaCXXScopeSpec.cpp b/lib/Sema/SemaCXXScopeSpec.cpp
index 61d9e93f2f..e54857196a 100644
--- a/lib/Sema/SemaCXXScopeSpec.cpp
+++ b/lib/Sema/SemaCXXScopeSpec.cpp
@@ -464,26 +464,29 @@ bool Sema::BuildCXXNestedNameSpecifier(Scope *S,
// We haven't found anything, and we're not recovering from a
// different kind of error, so look for typos.
DeclarationName Name = Found.getLookupName();
- if (CorrectTypo(Found, S, &SS, LookupCtx, EnteringContext,
- CTC_NoKeywords) &&
- Found.isSingleResult() &&
- isAcceptableNestedNameSpecifier(Found.getAsSingle<NamedDecl>())) {
+ TypoCorrection Corrected;
+ Found.clear();
+ if ((Corrected = CorrectTypo(Found.getLookupNameInfo(),
+ Found.getLookupKind(), S, &SS, LookupCtx,
+ EnteringContext, CTC_NoKeywords)) &&
+ isAcceptableNestedNameSpecifier(Corrected.getCorrectionDecl())) {
+ std::string CorrectedStr(Corrected.getAsString(getLangOptions()));
+ std::string CorrectedQuotedStr(Corrected.getQuoted(getLangOptions()));
if (LookupCtx)
Diag(Found.getNameLoc(), diag::err_no_member_suggest)
- << Name << LookupCtx << Found.getLookupName() << SS.getRange()
- << FixItHint::CreateReplacement(Found.getNameLoc(),
- Found.getLookupName().getAsString());
+ << Name << LookupCtx << CorrectedQuotedStr << SS.getRange()
+ << FixItHint::CreateReplacement(Found.getNameLoc(), CorrectedStr);
else
Diag(Found.getNameLoc(), diag::err_undeclared_var_use_suggest)
- << Name << Found.getLookupName()
- << FixItHint::CreateReplacement(Found.getNameLoc(),
- Found.getLookupName().getAsString());
+ << Name << CorrectedQuotedStr
+ << FixItHint::CreateReplacement(Found.getNameLoc(), CorrectedStr);
- if (NamedDecl *ND = Found.getAsSingle<NamedDecl>())
- Diag(ND->getLocation(), diag::note_previous_decl)
- << ND->getDeclName();
+ if (NamedDecl *ND = Corrected.getCorrectionDecl()) {
+ Diag(ND->getLocation(), diag::note_previous_decl) << CorrectedQuotedStr;
+ Found.addDecl(ND);
+ }
+ Found.setLookupName(Corrected.getCorrection());
} else {
- Found.clear();
Found.setLookupName(&Identifier);
}
}
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index efb06f6687..2779faeb15 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -287,41 +287,42 @@ bool Sema::DiagnoseUnknownTypeName(const IdentifierInfo &II,
// There may have been a typo in the name of the type. Look up typo
// results, in case we have something that we can suggest.
- LookupResult Lookup(*this, &II, IILoc, LookupOrdinaryName,
- NotForRedeclaration);
+ if (TypoCorrection Corrected = CorrectTypo(DeclarationNameInfo(&II, IILoc),
+ LookupOrdinaryName, S, SS, NULL,
+ false, CTC_Type)) {
+ std::string CorrectedStr(Corrected.getAsString(getLangOptions()));
+ std::string CorrectedQuotedStr(Corrected.getQuoted(getLangOptions()));
- if (DeclarationName Corrected = CorrectTypo(Lookup, S, SS, 0, 0, CTC_Type)) {
- if (NamedDecl *Result = Lookup.getAsSingle<NamedDecl>()) {
+ if (Corrected.isKeyword()) {
+ // We corrected to a keyword.
+ // FIXME: Actually recover with the keyword we suggest, and emit a fix-it.
+ Diag(IILoc, diag::err_unknown_typename_suggest)
+ << &II << CorrectedQuotedStr;
+ return true;
+ } else {
+ NamedDecl *Result = Corrected.getCorrectionDecl();
if ((isa<TypeDecl>(Result) || isa<ObjCInterfaceDecl>(Result)) &&
!Result->isInvalidDecl()) {
// We found a similarly-named type or interface; suggest that.
if (!SS || !SS->isSet())
Diag(IILoc, diag::err_unknown_typename_suggest)
- << &II << Lookup.getLookupName()
- << FixItHint::CreateReplacement(SourceRange(IILoc),
- Result->getNameAsString());
+ << &II << CorrectedQuotedStr
+ << FixItHint::CreateReplacement(SourceRange(IILoc), CorrectedStr);
else if (DeclContext *DC = computeDeclContext(*SS, false))
Diag(IILoc, diag::err_unknown_nested_typename_suggest)
- << &II << DC << Lookup.getLookupName() << SS->getRange()
- << FixItHint::CreateReplacement(SourceRange(IILoc),
- Result->getNameAsString());
+ << &II << DC << CorrectedQuotedStr << SS->getRange()
+ << FixItHint::CreateReplacement(SourceRange(IILoc), CorrectedStr);
else
llvm_unreachable("could not have corrected a typo here");
Diag(Result->getLocation(), diag::note_previous_decl)
- << Result->getDeclName();
+ << CorrectedQuotedStr;
SuggestedType = getTypeName(*Result->getIdentifier(), IILoc, S, SS,
false, false, ParsedType(),
/*NonTrivialTypeSourceInfo=*/true);
return true;
}
- } else if (Lookup.empty()) {
- // We corrected to a keyword.
- // FIXME: Actually recover with the keyword we suggest, and emit a fix-it.
- Diag(IILoc, diag::err_unknown_typename_suggest)
- << &II << Corrected;
- return true;
}
}
@@ -509,11 +510,14 @@ Corrected:
// Perform typo correction to determine if there is another name that is
// close to this name.
if (!SecondTry) {
- if (DeclarationName Corrected = CorrectTypo(Result, S, &SS)) {
+ if (TypoCorrection Corrected = CorrectTypo(Result.getLookupNameInfo(),
+ Result.getLookupKind(), S, &SS)) {
unsigned UnqualifiedDiag = diag::err_undeclared_var_use_suggest;
unsigned QualifiedDiag = diag::err_no_member_suggest;
+ std::string CorrectedStr(Corrected.getAsString(getLangOptions()));
+ std::string CorrectedQuotedStr(Corrected.getQuoted(getLangOptions()));
- NamedDecl *FirstDecl = Result.empty()? 0 : *Result.begin();
+ NamedDecl *FirstDecl = Corrected.getCorrectionDecl();
NamedDecl *UnderlyingFirstDecl
= FirstDecl? FirstDecl->getUnderlyingDecl() : 0;
if (getLangOptions().CPlusPlus && NextToken.is(tok::less) &&
@@ -528,25 +532,34 @@ Corrected:
QualifiedDiag = diag::err_unknown_nested_typename_suggest;
}
+ if (Corrected.getCorrectionSpecifier())
+ SS.MakeTrivial(Context, Corrected.getCorrectionSpecifier(), SourceRange(NameLoc));
+
if (SS.isEmpty())
Diag(NameLoc, UnqualifiedDiag)
- << Name << Corrected
- << FixItHint::CreateReplacement(NameLoc, Corrected.getAsString());
+ << Name << CorrectedQuotedStr
+ << FixItHint::CreateReplacement(NameLoc, CorrectedStr);
else
Diag(NameLoc, QualifiedDiag)
- << Name << computeDeclContext(SS, false) << Corrected
+ << Name << computeDeclContext(SS, false) << CorrectedQuotedStr
<< SS.getRange()
- << FixItHint::CreateReplacement(NameLoc, Corrected.getAsString());
+ << FixItHint::CreateReplacement(NameLoc, CorrectedStr);
// Update the name, so that the caller has the new name.
- Name = Corrected.getAsIdentifierInfo();
+ Name = Corrected.getCorrectionAsIdentifierInfo();
+ // Also update the LookupResult...
+ // FIXME: This should probably go away at some point
+ Result.clear();
+ Result.setLookupName(Corrected.getCorrection());
+ if (FirstDecl) Result.addDecl(FirstDecl);
+
// Typo correction corrected to a keyword.
- if (Result.empty())
- return Corrected.getAsIdentifierInfo();
+ if (Corrected.isKeyword())
+ return Corrected.getCorrectionAsIdentifierInfo();
Diag(FirstDecl->getLocation(), diag::note_previous_decl)
- << FirstDecl->getDeclName();
+ << CorrectedQuotedStr;
// If we found an Objective-C instance variable, let
// LookupInObjCMethod build the appropriate expression to
@@ -1137,17 +1150,18 @@ void Sema::ActOnPopScope(SourceLocation Loc, Scope *S) {
/// class could not be found.
ObjCInterfaceDecl *Sema::getObjCInterfaceDecl(IdentifierInfo *&Id,
SourceLocation IdLoc,
- bool TypoCorrection) {
+ bool DoTypoCorrection) {
// The third "scope" argument is 0 since we aren't enabling lazy built-in
// creation from this context.
NamedDecl *IDecl = LookupSingleName(TUScope, Id, IdLoc, LookupOrdinaryName);
- if (!IDecl && TypoCorrection) {
+ if (!IDecl && DoTypoCorrection) {
// Perform typo correction at the given location, but only if we
// find an Objective-C class name.
- LookupResult R(*this, Id, IdLoc, LookupOrdinaryName);
- if (CorrectTypo(R, TUScope, 0, 0, false, CTC_NoKeywords) &&
- (IDecl = R.getAsSingle<ObjCInterfaceDecl>())) {
+ TypoCorrection C;
+ if ((C = CorrectTypo(DeclarationNameInfo(Id, IdLoc), LookupOrdinaryName,
+ TUScope, NULL, NULL, false, CTC_NoKeywords)) &&
+ (IDecl = C.getCorrectionDeclAs<ObjCInterfaceDecl>())) {
Diag(IdLoc, diag::err_undef_interface_suggest)
<< Id << IDecl->getDeclName()
<< FixItHint::CreateReplacement(IdLoc, IDecl->getNameAsString());
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index c0d34da922..ac51138b91 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -1426,25 +1426,27 @@ Sema::ActOnMemInitializer(Decl *ConstructorD,
}
// If no results were found, try to correct typos.
+ TypoCorrection Corr;
if (R.empty() && BaseType.isNull() &&
- CorrectTypo(R, S, &SS, ClassDecl, 0, CTC_NoKeywords) &&
- R.isSingleResult()) {
- if (FieldDecl *Member = R.getAsSingle<FieldDecl>()) {
+ (Corr = CorrectTypo(R.getLookupNameInfo(), R.getLookupKind(), S, &SS,
+ ClassDecl, false, CTC_NoKeywords))) {
+ std::string CorrectedStr(Corr.getAsString(getLangOptions()));
+ std::string CorrectedQuotedStr(Corr.getQuoted(getLangOptions()));
+ if (FieldDecl *Member = Corr.getCorrectionDeclAs<FieldDecl>()) {
if (Member->getDeclContext()->getRedeclContext()->Equals(ClassDecl)) {
// We have found a non-static data member with a similar
// name to what was typed; complain and initialize that
// member.
Diag(R.getNameLoc(), diag::err_mem_init_not_member_or_class_suggest)
- << MemberOrBase << true << R.getLookupName()
- << FixItHint::CreateReplacement(R.getNameLoc(),
- R.getLookupName().getAsString());
+ << MemberOrBase << true << CorrectedQuotedStr
+ << FixItHint::CreateReplacement(R.getNameLoc(), CorrectedStr);
Diag(Member->getLocation(), diag::note_previous_decl)
- << Member->getDeclName();
+ << CorrectedQuotedStr;
return BuildMemberInitializer(Member, (Expr**)Args, NumArgs, IdLoc,
LParenLoc, RParenLoc);
}
- } else if (TypeDecl *Type = R.getAsSingle<TypeDecl>()) {
+ } else if (TypeDecl *Type = Corr.getCorrectionDeclAs<TypeDecl>()) {
const CXXBaseSpecifier *DirectBaseSpec;
const CXXBaseSpecifier *VirtualBaseSpec;
if (FindBaseInitializer(*this, ClassDecl,
@@ -1454,9 +1456,8 @@ Sema::ActOnMemInitializer(Decl *ConstructorD,
// similar name to what was typed; complain and initialize
// that base class.
Diag(R.getNameLoc(), diag::err_mem_init_not_member_or_class_suggest)
- << MemberOrBase << false << R.getLookupName()
- << FixItHint::CreateReplacement(R.getNameLoc(),
- R.getLookupName().getAsString());
+ << MemberOrBase << false << CorrectedQuotedStr
+ << FixItHint::CreateReplacement(R.getNameLoc(), CorrectedStr);
const CXXBaseSpecifier *BaseSpec = DirectBaseSpec? DirectBaseSpec
: VirtualBaseSpec;
@@ -4706,6 +4707,13 @@ Decl *Sema::ActOnStartNamespaceDef(Scope *NamespcScope,
// Make our StdNamespace cache point at the first real definition of the
// "std" namespace.
StdNamespace = Namespc;
+
+ // Add this instance of "std" to the set of known namespaces
+ KnownNamespaces[Namespc] = false;
+ } else if (!Namespc->isInline()) {
+ // Since this is an "original" namespace, add it to the known set of
+ // namespaces if it is not an inline namespace.
+ KnownNamespaces[Namespc] = false;
}
PushOnScopeChains(Namespc, DeclRegionScope);
@@ -4841,6 +4849,39 @@ static bool IsUsingDirectiveInToplevelContext(DeclContext *CurContext) {
}
}
+static bool TryNamespaceTypoCorrection(Sema &S, LookupResult &R, Scope *Sc,
+ CXXScopeSpec &SS,
+ SourceLocation IdentLoc,
+ IdentifierInfo *Ident) {
+ R.clear();
+ if (TypoCorrection Corrected = S.CorrectTypo(R.getLookupNameInfo(),
+ R.getLookupKind(), Sc, &SS, NULL,
+ false, S.CTC_NoKeywords, NULL)) {
+ if (Corrected.getCorrectionDeclAs<NamespaceDecl>() ||
+ Corrected.getCorrectionDeclAs<NamespaceAliasDecl>()) {
+ std::string CorrectedStr(Corrected.getAsString(S.getLangOptions()));
+ std::string CorrectedQuotedStr(Corrected.getQuoted(S.getLangOptions()));
+ if (DeclContext *DC = S.computeDeclContext(SS, false))
+ S.Diag(IdentLoc, diag::err_using_directive_member_suggest)
+ << Ident << DC << CorrectedQuotedStr << SS.getRange()
+ << FixItHint::CreateReplacement(IdentLoc, CorrectedStr);
+ else
+ S.Diag(IdentLoc, diag::err_using_directive_suggest)
+ << Ident << CorrectedQuotedStr
+ << FixItHint::CreateReplacement(IdentLoc, CorrectedStr);
+
+ S.Diag(Corrected.getCorrectionDecl()->getLocation(),
+ diag::note_namespace_defined_here) << CorrectedQuotedStr;
+
+ Ident = Corrected.getCorrectionAsIdentifierInfo();
+ R.addDecl(Corrected.getCorrectionDecl());
+ return true;
+ }
+ R.setLookupName(Ident);
+ }
+ return false;
+}
+
Decl *Sema::ActOnUsingDirective(Scope *S,
SourceLocation UsingLoc,
SourceLocation NamespcLoc,
@@ -4869,6 +4910,7 @@ Decl *Sema::ActOnUsingDirective(Scope *S,
return 0;
if (R.empty()) {
+ R.clear();
// Allow "using namespace std;" or "using namespace ::std;" even if
// "std" hasn't been defined yet, for GCC compatibility.
if ((!Qualifier || Qualifier->getKind() == NestedNameSpecifier::Global) &&
@@ -4878,27 +4920,7 @@ Decl *Sema::ActOnUsingDirective(Scope *S,
R.resolveKind();
}
// Otherwise, attempt typo correction.
- else if (DeclarationName Corrected = CorrectTypo(R, S, &SS, 0, false,
- CTC_NoKeywords, 0)) {
- if (R.getAsSingle<NamespaceDecl>() ||
- R.getAsSingle<NamespaceAliasDecl>()) {
- if (DeclContext *DC = computeDeclContext(SS, false))
- Diag(IdentLoc, diag::err_using_directive_member_suggest)
- << NamespcName << DC << Corrected << SS.getRange()
- << FixItHint::CreateReplacement(IdentLoc, Corrected.getAsString());
- else
- Diag(IdentLoc, diag::err_using_directive_suggest)
- << NamespcName << Corrected
- << FixItHint::CreateReplacement(IdentLoc, Corrected.getAsString());
- Diag(R.getFoundDecl()->getLocation(), diag::note_namespace_defined_here)
- << Corrected;
-
- NamespcName = Corrected.getAsIdentifierInfo();
- } else {
- R.clear();
- R.setLookupName(NamespcName);
- }
- }
+ else TryNamespaceTypoCorrection(*this, R, S, SS, IdentLoc, NamespcName);
}
if (!R.empty()) {
@@ -5816,30 +5838,7 @@ Decl *Sema::ActOnNamespaceAliasDef(Scope *S,
return 0;
if (R.empty()) {
- if (DeclarationName Corrected = CorrectTypo(R, S, &SS, 0, false,
- CTC_NoKeywords, 0)) {
- if (R.getAsSingle<NamespaceDecl>() ||
- R.getAsSingle<NamespaceAliasDecl>()) {
- if (DeclContext *DC = computeDeclContext(SS, false))
- Diag(IdentLoc, diag::err_using_directive_member_suggest)
- << Ident << DC << Corrected << SS.getRange()
- << FixItHint::CreateReplacement(IdentLoc, Corrected.getAsString());
- else
- Diag(IdentLoc, diag::err_using_directive_suggest)
- << Ident << Corrected
- << FixItHint::CreateReplacement(IdentLoc, Corrected.getAsString());
-
- Diag(R.getFoundDecl()->getLocation(), diag::note_namespace_defined_here)
- << Corrected;
-
- Ident = Corrected.getAsIdentifierInfo();
- } else {
- R.clear();
- R.setLookupName(Ident);
- }
- }
-
- if (R.empty()) {
+ if (!TryNamespaceTypoCorrection(*this, R, S, SS, IdentLoc, Ident)) {
Diag(NamespaceLoc, diag::err_expected_namespace_name) << SS.getRange();
return 0;
}
diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp
index a3f53ec234..a9f4f95c20 100644
--- a/lib/Sema/SemaDeclObjC.cpp
+++ b/lib/Sema/SemaDeclObjC.cpp
@@ -442,9 +442,10 @@ ActOnStartClassInterface(SourceLocation AtInterfaceLoc,
if (!PrevDecl) {
// Try to correct for a typo in the superclass name.
- LookupResult R(*this, SuperName, SuperLoc, LookupOrdinaryName);
- if (CorrectTypo(R, TUScope, 0, 0, false, CTC_NoKeywords) &&
- (PrevDecl = R.getAsSingle<ObjCInterfaceDecl>())) {
+ TypoCorrection Corrected = CorrectTypo(
+ DeclarationNameInfo(SuperName, SuperLoc), LookupOrdinaryName, TUScope,
+ NULL, NULL, false, CTC_NoKeywords);
+ if ((PrevDecl = Corrected.getCorrectionDeclAs<ObjCInterfaceDecl>())) {
Diag(SuperLoc, diag::err_undef_superclass_suggest)
<< SuperName << ClassName << PrevDecl->getDeclName();
Diag(PrevDecl->getLocation(), diag::note_previous_decl)
@@ -655,12 +656,12 @@ Sema::FindProtocolDeclaration(bool WarnOnDeclarations,
ObjCProtocolDecl *PDecl = LookupProtocol(ProtocolId[i].first,
ProtocolId[i].second);
if (!PDecl) {
- LookupResult R(*this, ProtocolId[i].first, ProtocolId[i].second,
- LookupObjCProtocolName);
- if (CorrectTypo(R, TUScope, 0, 0, false, CTC_NoKeywords) &&
- (PDecl = R.getAsSingle<ObjCProtocolDecl>())) {
+ TypoCorrection Corrected = CorrectTypo(
+ DeclarationNameInfo(ProtocolId[i].first, ProtocolId[i].second),
+ LookupObjCProtocolName, TUScope, NULL, NULL, false, CTC_NoKeywords);
+ if ((PDecl = Corrected.getCorrectionDeclAs<ObjCProtocolDecl>())) {
Diag(ProtocolId[i].second, diag::err_undeclared_protocol_suggest)
- << ProtocolId[i].first << R.getLookupName();
+ << ProtocolId[i].first << Corrected.getCorrection();
Diag(PDecl->getLocation(), diag::note_previous_decl)
<< PDecl->getDeclName();
}
@@ -897,20 +898,20 @@ Decl *Sema::ActOnStartClassImplementation(
} else {
// We did not find anything with the name ClassName; try to correct for
// typos in the class name.
- LookupResult R(*this, ClassName, ClassLoc, LookupOrdinaryName);
- if (CorrectTypo(R, TUScope, 0, 0, false, CTC_NoKeywords) &&
- (IDecl = R.getAsSingle<ObjCInterfaceDecl>())) {
+ TypoCorrection Corrected = CorrectTypo(
+ DeclarationNameInfo(ClassName, ClassLoc), LookupOrdinaryName, TUScope,
+ NULL, NULL, false, CTC_NoKeywords);
+ if ((IDecl = Corrected.getCorrectionDeclAs<ObjCInterfaceDecl>())) {
// Suggest the (potentially) correct interface name. However, put the
// fix-it hint itself in a separate note, since changing the name in
// the warning would make the fix-it change semantics.However, don't
// provide a code-modification hint or use the typo name for recovery,
// because this is just a warning. The program may actually be correct.
+ DeclarationName CorrectedName = Corrected.getCorrection();
Diag(ClassLoc, diag::warn_undef_interface_suggest)
- << ClassName << R.getLookupName();
- Diag(IDecl->getLocation(), diag::note_previous_decl)
- << R.getLookupName()
- << FixItHint::CreateReplacement(ClassLoc,
- R.getLookupName().getAsString());
+ << ClassName << CorrectedName;
+ Diag(IDecl->getLocation(), diag::note_previous_decl) << CorrectedName
+ << FixItHint::CreateReplacement(ClassLoc, CorrectedName.getAsString());
IDecl = 0;
} else {
Diag(ClassLoc, diag::warn_undef_interface) << ClassName;
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 3423d71af4..b99076005b 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -1397,39 +1397,44 @@ bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R,
}
// We didn't find anything, so try to correct for a typo.
- DeclarationName Corrected;
- if (S && (Corrected = CorrectTypo(R, S, &SS, 0, false, CTC))) {
- if (!R.empty()) {
- if (isa<ValueDecl>(*R.begin()) || isa<FunctionTemplateDecl>(*R.begin())) {
+ TypoCorrection Corrected;
+ if (S && (Corrected = CorrectTypo(R.getLookupNameInfo(), R.getLookupKind(),
+ S, &SS, NULL, false, CTC))) {
+ std::string CorrectedStr(Corrected.getAsString(getLangOptions()));
+ std::string CorrectedQuotedStr(Corrected.getQuoted(getLangOptions()));
+ R.setLookupName(Corrected.getCorrection());
+
+ if (!Corrected.isKeyword()) {
+ NamedDecl *ND = Corrected.getCorrectionDecl();
+ R.addDecl(ND);
+ if (isa<ValueDecl>(ND) || isa<FunctionTemplateDecl>(ND)) {
if (SS.isEmpty())
- Diag(R.getNameLoc(), diagnostic_suggest) << Name << R.getLookupName()
- << FixItHint::CreateReplacement(R.getNameLoc(),
- R.getLookupName().getAsString());
+ Diag(R.getNameLoc(), diagnostic_suggest) << Name << CorrectedQuotedStr
+ << FixItHint::CreateReplacement(R.getNameLoc(), CorrectedStr);
else
Diag(R.getNameLoc(), diag::err_no_member_suggest)
- << Name << computeDeclContext(SS, false) << R.getLookupName()
+ << Name << computeDeclContext(SS, false) << CorrectedQuotedStr
<< SS.getRange()
- << FixItHint::CreateReplacement(R.getNameLoc(),
- R.getLookupName().getAsString());
- if (NamedDecl *ND = R.getAsSingle<NamedDecl>())
+ << FixItHint::CreateReplacement(R.getNameLoc(), CorrectedStr);
+ if (ND)
Diag(ND->getLocation(), diag::note_previous_decl)
- << ND->getDeclName();
+ << CorrectedQuotedStr;
// Tell the callee to try to recover.
return false;
}
- if (isa<TypeDecl>(*R.begin()) || isa<ObjCInterfaceDecl>(*R.begin())) {
+ if (isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND)) {
// FIXME: If we ended up with a typo for a type name or
// Objective-C class name, we're in trouble because the parser
// is in the wrong place to recover. Suggest the typo
// correction, but don't make it a fix-it since we're not going
// to recover well anyway.
if (SS.isEmpty())
- Diag(R.getNameLoc(), diagnostic_suggest) << Name << R.getLookupName();
+ Diag(R.getNameLoc(), diagnostic_suggest) << Name << CorrectedQuotedStr;
else
Diag(R.getNameLoc(), diag::err_no_member_suggest)
- << Name << computeDeclContext(SS, false) << R.getLookupName()
+ << Name << computeDeclContext(SS, false) << CorrectedQuotedStr
<< SS.getRange();
// Don't try to recover; it won't work.
@@ -1439,15 +1444,15 @@ bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R,
// FIXME: We found a keyword. Suggest it, but don't provide a fix-it
// because we aren't able to recover.
if (SS.isEmpty())
- Diag(R.getNameLoc(), diagnostic_suggest) << Name << Corrected;
+ Diag(R.getNameLoc(), diagnostic_suggest) << Name << CorrectedQuotedStr;
else
Diag(R.getNameLoc(), diag::err_no_member_suggest)
- << Name << computeDeclContext(SS, false) << Corrected
+ << Name << computeDeclContext(SS, false) << CorrectedQuotedStr
<< SS.getRange();
return true;
}
- R.clear();
}
+ R.clear();
// Emit a special diagnostic for failed member lookups.
// FIXME: computing the declaration context might fail here (?)
diff --git a/lib/Sema/SemaExprMember.cpp b/lib/Sema/SemaExprMember.cpp
index 9509768205..2488dc8849 100644
--- a/lib/Sema/SemaExprMember.cpp
+++ b/lib/Sema/SemaExprMember.cpp
@@ -555,20 +555,24 @@ LookupMemberExprInRecord(Sema &SemaRef, LookupResult &R,
// We didn't find anything with the given name, so try to correct
// for typos.
DeclarationName Name = R.getLookupName();
- if (SemaRef.CorrectTypo(R, 0, &SS, DC, false, Sema::CTC_MemberLookup) &&
- !R.empty() &&
- (isa<ValueDecl>(*R.begin()) || isa<FunctionTemplateDecl>(*R.begin()))) {
+ TypoCorrection Corrected = SemaRef.CorrectTypo(R.getLookupNameInfo(),
+ R.getLookupKind(), NULL,
+ &SS, DC, false,
+ Sema::CTC_MemberLookup);
+ NamedDecl *ND = Corrected.getCorrectionDecl();
+ R.clear();
+ if (ND && (isa<ValueDecl>(ND) || isa<FunctionTemplateDecl>(ND))) {
+ std::string CorrectedStr(
+ Corrected.getAsString(SemaRef.getLangOptions()));
+ std::string CorrectedQuotedStr(
+ Corrected.getQuoted(SemaRef.getLangOptions()));
+ R.setLookupName(Corrected.getCorrection());
+ R.addDecl(ND);
SemaRef.Diag(R.getNameLoc(), diag::err_no_member_suggest)
- << Name << DC << R.getLookupName() << SS.getRange()
- << FixItHint::CreateReplacement(R.getNameLoc(),
- R.getLookupName().getAsString());
- if (NamedDecl *ND = R.getAsSingle<NamedDecl>())
- SemaRef.Diag(ND->getLocation(), diag::note_previous_decl)
- << ND->getDeclName();
- return false;
- } else {
- R.clear();
- R.setLookupName(Name);
+ << Name << DC << CorrectedQuotedStr << SS.getRange()
+ << FixItHint::CreateReplacement(R.getNameLoc(), CorrectedStr);
+ SemaRef.Diag(ND->getLocation(), diag::note_previous_decl)
+ << ND->getDeclName();
}
return false;
@@ -1068,10 +1072,10 @@ Sema::LookupMemberExpr(LookupResult &R, ExprResult &BaseExpr,
// Attempt to correct for typos in ivar names.
LookupResult Res(*this, R.getLookupName(), R.getNameLoc(),
LookupMemberName);
- if (CorrectTypo(Res, 0, 0, IDecl, false,
- IsArrow ? CTC_ObjCIvarLookup
- : CTC_ObjCPropertyLookup) &&
- (IV = Res.getAsSingle<ObjCIvarDecl>())) {
+ TypoCorrection Corrected = CorrectTypo(
+ R.getLookupNameInfo(), LookupMemberName, NULL, NULL, IDecl, false,
+ IsArrow ? CTC_ObjCIvarLookup : CTC_ObjCPropertyLookup);
+ if ((IV = Corrected.getCorrectionDeclAs<ObjCIvarDecl>())) {
Diag(R.getNameLoc(),
diag::err_typecheck_member_reference_ivar_suggest)
<< IDecl->getDeclName() << MemberName << IV->getDeclName()
diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp
index 80d3a7451d..c02b634547 100644
--- a/lib/Sema/SemaExprObjC.cpp
+++ b/lib/Sema/SemaExprObjC.cpp
@@ -663,14 +663,15 @@ HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT,
}
// Attempt to correct for typos in property names.
- LookupResult Res(*this, MemberName, MemberLoc, LookupOrdinaryName);
- if (CorrectTypo(Res, 0, 0, IFace, false, CTC_NoKeywords, OPT) &&
- Res.getAsSingle<ObjCPropertyDecl>()) {
- DeclarationName TypoResult = Res.getLookupName();
+ TypoCorrection Corrected = CorrectTypo(
+ DeclarationNameInfo(MemberName, MemberLoc), LookupOrdinaryName, NULL,
+ NULL, IFace, false, CTC_NoKeywords, OPT);
+ if (ObjCPropertyDecl *Property =
+ Corrected.getCorrectionDeclAs<ObjCPropertyDecl>()) {
+ DeclarationName TypoResult = Corrected.getCorrection();
Diag(MemberLoc, diag::err_property_not_found_suggest)
<< MemberName << QualType(OPT, 0) << TypoResult
<< FixItHint::CreateReplacement(MemberLoc, TypoResult.getAsString());
- ObjCPropertyDecl *Property = Res.getAsSingle<ObjCPropertyDecl>();
Diag(Property->getLocation(), diag::note_previous_decl)
<< Property->getDeclName();
return HandleExprPropertyRefExpr(OPT, BaseExpr, OpLoc,
@@ -898,29 +899,30 @@ Sema::ObjCMessageKind Sema::getObjCMessageKind(Scope *S,
Method->getClassInterface()->getSuperClass())
CTC = CTC_ObjCMessageReceiver;
- if (DeclarationName Corrected = CorrectTypo(Result, S, 0, 0, false, CTC)) {
- if (Result.isSingleResult()) {
+ if (TypoCorrection Corrected = CorrectTypo(Result.getLookupNameInfo(),
+ Result.getLookupKind(), S, NULL,
+ NULL, false, CTC)) {
+ if (NamedDecl *ND = Corrected.getCorrectionDecl()) {
// If we found a declaration, correct when it refers to an Objective-C
// class.
- NamedDecl *ND = Result.getFoundDecl();
if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(ND)) {
Diag(NameLoc, diag::err_unknown_receiver_suggest)
- << Name << Result.getLookupName()
+ << Name << Corrected.getCorrection()
<< FixItHint::CreateReplacement(SourceRange(NameLoc),
ND->getNameAsString());
Diag(ND->getLocation(), diag::note_previous_decl)
- << Corrected;
+ << Corrected.getCorrection();
QualType T = Context.getObjCInterfaceType(Class);
TypeSourceInfo *TSInfo = Context.getTrivialTypeSourceInfo(T, NameLoc);
ReceiverType = CreateParsedType(T, TSInfo);
return ObjCClassMessage;
}
- } else if (Result.empty() && Corrected.getAsIdentifierInfo() &&
- Corrected.getAsIdentifierInfo()->isStr("super")) {
+ } else if (Corrected.isKeyword() &&
+ Corrected.getCorrectionAsIdentifierInfo()->isStr("super")) {
// If we've found the keyword "super", this is a send to super.
Diag(NameLoc, diag::err_unknown_receiver_suggest)
- << Name << Corrected
+ << Name << Corrected.getCorrection()
<< FixItHint::CreateReplacement(SourceRange(NameLoc), "super");
return ObjCSuperMessage;
}
diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp
index 16ba2a2910..da20e0e8fd 100644
--- a/lib/Sema/SemaInit.cpp
+++ b/lib/Sema/SemaInit.cpp
@@ -1443,19 +1443,23 @@ InitListChecker::CheckDesignatedInitializer(const InitializedEntity &Entity,
// was a typo for another field name.
LookupResult R(SemaRef, FieldName, D->getFieldLoc(),
Sema::LookupMemberName);
- if (SemaRef.CorrectTypo(R, /*Scope=*/0, /*SS=*/0, RT->getDecl(), false,
- Sema::CTC_NoKeywords) &&
- (ReplacementField = R.getAsSingle<FieldDecl>()) &&
+ TypoCorrection Corrected = SemaRef.CorrectTypo(
+ DeclarationNameInfo(FieldName, D->getFieldLoc()),
+ Sema::LookupMemberName, /*Scope=*/NULL, /*SS=*/NULL,
+ RT->getDecl(), false, Sema::CTC_NoKeywords);
+ if ((ReplacementField = Corrected.getCorrectionDeclAs<FieldDecl>()) &&
ReplacementField->getDeclContext()->getRedeclContext()
->Equals(RT->getDecl())) {
+ std::string CorrectedStr(
+ Corrected.getAsString(SemaRef.getLangOptions()));
+ std::string CorrectedQuotedStr(
+ Corrected.getQuoted(SemaRef.getLangOptions()));
SemaRef.Diag(D->getFieldLoc(),
diag::err_field_designator_unknown_suggest)
- << FieldName << CurrentObjectType << R.getLookupName()
- << FixItHint::CreateReplacement(D->getFieldLoc(),
- R.getLookupName().getAsString());
+ << FieldName << CurrentObjectType << CorrectedQuotedStr
+ << FixItHint::CreateReplacement(D->getFieldLoc(), CorrectedStr);
SemaRef.Diag(ReplacementField->getLocation(),
- diag::note_previous_decl)
- << ReplacementField->getDeclName();
+ diag::note_previous_decl) << CorrectedQuotedStr;
} else {
SemaRef.Diag(D->getFieldLoc(), diag::err_field_designator_unknown)
<< FieldName << CurrentObjectType;
diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp
index e09ec66457..0c1a1fa216 100644
--- a/lib/Sema/SemaLookup.cpp
+++ b/lib/Sema/SemaLookup.cpp
@@