diff options
Diffstat (limited to 'lib/Sema/SemaLookup.cpp')
-rw-r--r-- | lib/Sema/SemaLookup.cpp | 131 |
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(); |