aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaLookup.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Sema/SemaLookup.cpp')
-rw-r--r--lib/Sema/SemaLookup.cpp131
1 files changed, 37 insertions, 94 deletions
diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp
index ac6fb25cae..e8ef5ac6b9 100644
--- a/lib/Sema/SemaLookup.cpp
+++ b/lib/Sema/SemaLookup.cpp
@@ -23,6 +23,7 @@
#include "clang/AST/ExprCXX.h"
#include "clang/Basic/Builtins.h"
#include "clang/Basic/LangOptions.h"
+#include "clang/Lex/Preprocessor.h"
#include "clang/Sema/DeclSpec.h"
#include "clang/Sema/ExternalSemaSource.h"
#include "clang/Sema/Overload.h"
@@ -244,10 +245,11 @@ static inline unsigned getIDNS(Sema::LookupNameKind NameKind,
IDNS = Decl::IDNS_Tag;
}
break;
+
case Sema::LookupLabel:
IDNS = Decl::IDNS_Label;
break;
-
+
case Sema::LookupMemberName:
IDNS = Decl::IDNS_Member;
if (CPlusPlus)
@@ -263,8 +265,10 @@ static inline unsigned getIDNS(Sema::LookupNameKind NameKind,
break;
case Sema::LookupUsingDeclName:
- IDNS = Decl::IDNS_Ordinary | Decl::IDNS_Tag
- | Decl::IDNS_Member | Decl::IDNS_Using;
+ assert(Redeclaration && "should only be used for redecl lookup");
+ IDNS = Decl::IDNS_Ordinary | Decl::IDNS_Tag | Decl::IDNS_Member |
+ Decl::IDNS_Using | Decl::IDNS_TagFriend | Decl::IDNS_OrdinaryFriend |
+ Decl::IDNS_LocalExtern;
break;
case Sema::LookupObjCProtocolName:
@@ -2308,43 +2312,6 @@ void Sema::FindAssociatedClassesAndNamespaces(
}
}
-/// IsAcceptableNonMemberOperatorCandidate - Determine whether Fn is
-/// an acceptable non-member overloaded operator for a call whose
-/// arguments have types T1 (and, if non-empty, T2). This routine
-/// implements the check in C++ [over.match.oper]p3b2 concerning
-/// enumeration types.
-static bool
-IsAcceptableNonMemberOperatorCandidate(FunctionDecl *Fn,
- QualType T1, QualType T2,
- ASTContext &Context) {
- if (T1->isDependentType() || (!T2.isNull() && T2->isDependentType()))
- return true;
-
- if (T1->isRecordType() || (!T2.isNull() && T2->isRecordType()))
- return true;
-
- const FunctionProtoType *Proto = Fn->getType()->getAs<FunctionProtoType>();
- if (Proto->getNumParams() < 1)
- return false;
-
- if (T1->isEnumeralType()) {
- QualType ArgType = Proto->getParamType(0).getNonReferenceType();
- if (Context.hasSameUnqualifiedType(T1, ArgType))
- return true;
- }
-
- if (Proto->getNumParams() < 2)
- return false;
-
- if (!T2.isNull() && T2->isEnumeralType()) {
- QualType ArgType = Proto->getParamType(1).getNonReferenceType();
- if (Context.hasSameUnqualifiedType(T2, ArgType))
- return true;
- }
-
- return false;
-}
-
NamedDecl *Sema::LookupSingleName(Scope *S, DeclarationName Name,
SourceLocation Loc,
LookupNameKind NameKind,
@@ -2371,37 +2338,13 @@ void Sema::LookupOverloadedOperatorName(OverloadedOperatorKind Op, Scope *S,
// unqualified lookup of operator@ in the context of the
// expression according to the usual rules for name lookup in
// unqualified function calls (3.4.2) except that all member
- // functions are ignored. However, if no operand has a class
- // type, only those non-member functions in the lookup set
- // that have a first parameter of type T1 or "reference to
- // (possibly cv-qualified) T1", when T1 is an enumeration
- // type, or (if there is a right operand) a second parameter
- // of type T2 or "reference to (possibly cv-qualified) T2",
- // when T2 is an enumeration type, are candidate functions.
+ // functions are ignored.
DeclarationName OpName = Context.DeclarationNames.getCXXOperatorName(Op);
LookupResult Operators(*this, OpName, SourceLocation(), LookupOperatorName);
LookupName(Operators, S);
assert(!Operators.isAmbiguous() && "Operator lookup cannot be ambiguous");
-
- if (Operators.empty())
- return;
-
- for (LookupResult::iterator Op = Operators.begin(), OpEnd = Operators.end();
- Op != OpEnd; ++Op) {
- NamedDecl *Found = (*Op)->getUnderlyingDecl();
- if (FunctionDecl *FD = dyn_cast<FunctionDecl>(Found)) {
- if (IsAcceptableNonMemberOperatorCandidate(FD, T1, T2, Context))
- Functions.addDecl(*Op, Op.getAccess()); // FIXME: canonical FD
- } else if (FunctionTemplateDecl *FunTmpl
- = dyn_cast<FunctionTemplateDecl>(Found)) {
- // FIXME: friend operators?
- // FIXME: do we need to check IsAcceptableNonMemberOperatorCandidate,
- // later?
- if (!FunTmpl->getDeclContext()->isRecord())
- Functions.addDecl(*Op, Op.getAccess());
- }
- }
+ Functions.append(Operators.begin(), Operators.end());
}
Sema::SpecialMemberOverloadResult *Sema::LookupSpecialMember(CXXRecordDecl *RD,
@@ -2522,7 +2465,7 @@ Sema::SpecialMemberOverloadResult *Sema::LookupSpecialMember(CXXRecordDecl *RD,
// Now we perform lookup on the name we computed earlier and do overload
// resolution. Lookup is only performed directly into the class since there
// will always be a (possibly implicit) declaration to shadow any others.
- OverloadCandidateSet OCS(RD->getLocation());
+ OverloadCandidateSet OCS(RD->getLocation(), OverloadCandidateSet::CSK_Normal);
DeclContext::lookup_result R = RD->lookup(Name);
assert(!R.empty() &&
"lookup for a constructor or assignment operator was empty");
@@ -2842,9 +2785,8 @@ void ADLResult::insert(NamedDecl *New) {
Old = New;
}
-void Sema::ArgumentDependentLookup(DeclarationName Name, bool Operator,
- SourceLocation Loc, ArrayRef<Expr *> Args,
- ADLResult &Result) {
+void Sema::ArgumentDependentLookup(DeclarationName Name, SourceLocation Loc,
+ ArrayRef<Expr *> Args, ADLResult &Result) {
// Find all of the associated namespaces and classes based on the
// arguments we have.
AssociatedNamespaceSet AssociatedNamespaces;
@@ -2853,13 +2795,6 @@ void Sema::ArgumentDependentLookup(DeclarationName Name, bool Operator,
AssociatedNamespaces,
AssociatedClasses);
- QualType T1, T2;
- if (Operator) {
- T1 = Args[0]->getType();
- if (Args.size() >= 2)
- T2 = Args[1]->getType();
- }
-
// C++ [basic.lookup.argdep]p3:
// Let X be the lookup set produced by unqualified lookup (3.4.1)
// and let Y be the lookup set produced by argument dependent
@@ -2912,12 +2847,7 @@ void Sema::ArgumentDependentLookup(DeclarationName Name, bool Operator,
if (isa<UsingShadowDecl>(D))
D = cast<UsingShadowDecl>(D)->getTargetDecl();
- if (isa<FunctionDecl>(D)) {
- if (Operator &&
- !IsAcceptableNonMemberOperatorCandidate(cast<FunctionDecl>(D),
- T1, T2, Context))
- continue;
- } else if (!isa<FunctionTemplateDecl>(D))
+ if (!isa<FunctionDecl>(D) && !isa<FunctionTemplateDecl>(D))
continue;
Result.insert(D);
@@ -3995,6 +3925,7 @@ TypoCorrection Sema::CorrectTypo(const DeclarationNameInfo &TypoName,
Sema::LookupNameKind LookupKind,
Scope *S, CXXScopeSpec *SS,
CorrectionCandidateCallback &CCC,
+ CorrectTypoKind Mode,
DeclContext *MemberContext,
bool EnteringContext,
const ObjCObjectPointerType *OPT,
@@ -4049,10 +3980,20 @@ TypoCorrection Sema::CorrectTypo(const DeclarationNameInfo &TypoName,
if (getLangOpts().AltiVec && Typo->isStr("vector"))
return TypoCorrection();
- NamespaceSpecifierSet Namespaces(Context, CurContext, SS);
-
TypoCorrectionConsumer Consumer(*this, Typo);
+ if ((Mode == CTK_ErrorRecovery) && getLangOpts().Modules &&
+ getLangOpts().ModulesSearchAll) {
+ if (PP.getModuleLoader().lookupMissingImports(Typo->getName(),
+ TypoName.getLocStart())) {
+ TypoCorrection TC(TypoName.getName(), (NestedNameSpecifier *)0, 0);
+ TC.setCorrectionRange(SS, TypoName);
+ TC.setRequiresImport(true);
+ }
+ }
+
+ NamespaceSpecifierSet Namespaces(Context, CurContext, SS);
+
// If a callback object considers an empty typo correction candidate to be
// viable, assume it does not do any actual validation of the candidates.
TypoCorrection EmptyCorrection;
@@ -4511,10 +4452,9 @@ bool CorrectionCandidateCallback::ValidateCandidate(const TypoCorrection &candid
FunctionCallFilterCCC::FunctionCallFilterCCC(Sema &SemaRef, unsigned NumArgs,
bool HasExplicitTemplateArgs,
- bool AllowNonStaticMethods)
+ MemberExpr *ME)
: NumArgs(NumArgs), HasExplicitTemplateArgs(HasExplicitTemplateArgs),
- AllowNonStaticMethods(AllowNonStaticMethods),
- CurContext(SemaRef.CurContext) {
+ CurContext(SemaRef.CurContext), MemberFn(ME) {
WantTypeSpecifiers = SemaRef.getLangOpts().CPlusPlus;
WantRemainingKeywords = false;
}
@@ -4550,13 +4490,16 @@ bool FunctionCallFilterCCC::ValidateCandidate(const TypoCorrection &candidate) {
FD->getMinRequiredArguments() <= NumArgs))
continue;
- // If the current candidate is a non-static C++ method and non-static
- // methods are being excluded, then skip the candidate unless the current
- // DeclContext is a method in the same class or a descendent class of the
- // candidate's parent class.
+ // If the current candidate is a non-static C++ method, skip the candidate
+ // unless the method being corrected--or the current DeclContext, if the
+ // function being corrected is not a method--is a method in the same class
+ // or a descendent class of the candidate's parent class.
if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) {
- if (!AllowNonStaticMethods && !MD->isStatic()) {
- CXXMethodDecl *CurMD = dyn_cast_or_null<CXXMethodDecl>(CurContext);
+ if (MemberFn || !MD->isStatic()) {
+ CXXMethodDecl *CurMD =
+ MemberFn
+ ? dyn_cast_or_null<CXXMethodDecl>(MemberFn->getMemberDecl())
+ : dyn_cast_or_null<CXXMethodDecl>(CurContext);
CXXRecordDecl *CurRD =
CurMD ? CurMD->getParent()->getCanonicalDecl() : 0;
CXXRecordDecl *RD = MD->getParent()->getCanonicalDecl();