diff options
Diffstat (limited to 'contrib/llvm-project/clang/lib/Sema/SemaLookup.cpp')
-rw-r--r-- | contrib/llvm-project/clang/lib/Sema/SemaLookup.cpp | 505 |
1 files changed, 187 insertions, 318 deletions
diff --git a/contrib/llvm-project/clang/lib/Sema/SemaLookup.cpp b/contrib/llvm-project/clang/lib/Sema/SemaLookup.cpp index 02b1a045df44..d3d4bf27ae72 100644 --- a/contrib/llvm-project/clang/lib/Sema/SemaLookup.cpp +++ b/contrib/llvm-project/clang/lib/Sema/SemaLookup.cpp @@ -34,9 +34,11 @@ #include "clang/Sema/ScopeInfo.h" #include "clang/Sema/Sema.h" #include "clang/Sema/SemaInternal.h" +#include "clang/Sema/SemaRISCV.h" #include "clang/Sema/TemplateDeduction.h" #include "clang/Sema/TypoCorrection.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/STLForwardCompat.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/TinyPtrVector.h" #include "llvm/ADT/edit_distance.h" @@ -568,7 +570,7 @@ void LookupResult::resolveKind() { // For non-type declarations, check for a prior lookup result naming this // canonical declaration. - if (!D->isPlaceholderVar(getSema().getLangOpts()) && !ExistingI) { + if (!ExistingI) { auto UniqueResult = Unique.insert(std::make_pair(D, I)); if (!UniqueResult.second) { // We've seen this entity before. @@ -912,8 +914,6 @@ static void InsertOCLBuiltinDeclarationsFromTable(Sema &S, LookupResult &LR, LR.resolveKind(); } -/// Lookup a builtin function, when name lookup would otherwise -/// fail. bool Sema::LookupBuiltin(LookupResult &R) { Sema::LookupNameKind NameKind = R.getLookupKind(); @@ -944,13 +944,13 @@ bool Sema::LookupBuiltin(LookupResult &R) { } } - if (DeclareRISCVVBuiltins || DeclareRISCVSiFiveVectorBuiltins) { - if (!RVIntrinsicManager) - RVIntrinsicManager = CreateRISCVIntrinsicManager(*this); + if (RISCV().DeclareRVVBuiltins || RISCV().DeclareSiFiveVectorBuiltins) { + if (!RISCV().IntrinsicManager) + RISCV().IntrinsicManager = CreateRISCVIntrinsicManager(*this); - RVIntrinsicManager->InitIntrinsicList(); + RISCV().IntrinsicManager->InitIntrinsicList(); - if (RVIntrinsicManager->CreateIntrinsicIfFound(R, II, PP)) + if (RISCV().IntrinsicManager->CreateIntrinsicIfFound(R, II, PP)) return true; } @@ -1200,8 +1200,8 @@ static bool LookupDirect(Sema &S, LookupResult &R, const DeclContext *DC) { // Perform template argument deduction against the type that we would // expect the function to have. if (R.getSema().DeduceTemplateArguments(ConvTemplate, nullptr, ExpectedType, - Specialization, Info) - == Sema::TDK_Success) { + Specialization, Info) == + TemplateDeductionResult::Success) { R.addDecl(Specialization); Found = true; } @@ -1282,6 +1282,18 @@ bool Sema::CppLookupName(LookupResult &R, Scope *S) { DeclareImplicitMemberFunctionsWithName(*this, Name, R.getNameLoc(), DC); } + // C++23 [temp.dep.general]p2: + // The component name of an unqualified-id is dependent if + // - it is a conversion-function-id whose conversion-type-id + // is dependent, or + // - it is operator= and the current class is a templated entity, or + // - the unqualified-id is the postfix-expression in a dependent call. + if (Name.getNameKind() == DeclarationName::CXXConversionFunctionName && + Name.getCXXNameType()->isDependentType()) { + R.setNotFoundInCurrentInstantiation(); + return false; + } + // Implicitly declare member functions with the name we're looking for, if in // fact we are in a scope where it matters. @@ -1580,7 +1592,6 @@ llvm::DenseSet<Module*> &Sema::getLookupModules() { return LookupModulesCache; } -/// Determine if we could use all the declarations in the module. bool Sema::isUsableModule(const Module *M) { assert(M && "We shouldn't check nullness for module here"); // Return quickly if we cached the result. @@ -1592,22 +1603,32 @@ bool Sema::isUsableModule(const Module *M) { // [module.global.frag]p1: // The global module fragment can be used to provide declarations that are // attached to the global module and usable within the module unit. - if (M == TheGlobalModuleFragment || M == TheImplicitGlobalModuleFragment || - // If M is the module we're parsing, it should be usable. This covers the - // private module fragment. The private module fragment is usable only if - // it is within the current module unit. And it must be the current - // parsing module unit if it is within the current module unit according - // to the grammar of the private module fragment. NOTE: This is covered by - // the following condition. The intention of the check is to avoid string - // comparison as much as possible. - M == getCurrentModule() || - // The module unit which is in the same module with the current module - // unit is usable. - // - // FIXME: Here we judge if they are in the same module by comparing the - // string. Is there any better solution? - M->getPrimaryModuleInterfaceName() == - llvm::StringRef(getLangOpts().CurrentModule).split(':').first) { + if (M == TheGlobalModuleFragment || M == TheImplicitGlobalModuleFragment) { + UsableModuleUnitsCache.insert(M); + return true; + } + + // Otherwise, the global module fragment from other translation unit is not + // directly usable. + if (M->isGlobalModule()) + return false; + + Module *Current = getCurrentModule(); + + // If we're not parsing a module, we can't use all the declarations from + // another module easily. + if (!Current) + return false; + + // If M is the module we're parsing or M and the current module unit lives in + // the same module, M should be usable. + // + // Note: It should be fine to search the vector `ModuleScopes` linearly since + // it should be generally small enough. There should be rare module fragments + // in a named module unit. + if (llvm::count_if(ModuleScopes, + [&M](const ModuleScope &MS) { return MS.Module == M; }) || + getASTContext().isInSameModule(M, Current)) { UsableModuleUnitsCache.insert(M); return true; } @@ -2151,34 +2172,6 @@ bool LookupResult::isAvailableForLookup(Sema &SemaRef, NamedDecl *ND) { return false; } -/// Perform unqualified name lookup starting from a given -/// scope. -/// -/// Unqualified name lookup (C++ [basic.lookup.unqual], C99 6.2.1) is -/// used to find names within the current scope. For example, 'x' in -/// @code -/// int x; -/// int f() { -/// return x; // unqualified name look finds 'x' in the global scope -/// } -/// @endcode -/// -/// Different lookup criteria can find different names. For example, a -/// particular scope can have both a struct and a function of the same -/// name, and each can be found by certain lookup criteria. For more -/// information about lookup criteria, see the documentation for the -/// class LookupCriteria. -/// -/// @param S The scope from which unqualified name lookup will -/// begin. If the lookup criteria permits, name lookup may also search -/// in the parent scopes. -/// -/// @param [in,out] R Specifies the lookup to perform (e.g., the name to -/// look up and the lookup kind), and is updated with the results of lookup -/// including zero or more declarations and possibly additional information -/// used to diagnose ambiguities. -/// -/// @returns \c true if lookup succeeded and false otherwise. bool Sema::LookupName(LookupResult &R, Scope *S, bool AllowBuiltinCreation, bool ForceNoCPlusPlus) { DeclarationName Name = R.getLookupName(); @@ -2332,7 +2325,7 @@ static bool LookupQualifiedNameInUsingDirectives(Sema &S, LookupResult &R, // We have already looked into the initial namespace; seed the queue // with its using-children. for (auto *I : StartDC->using_directives()) { - NamespaceDecl *ND = I->getNominatedNamespace()->getOriginalNamespace(); + NamespaceDecl *ND = I->getNominatedNamespace()->getFirstDecl(); if (S.isVisible(I) && Visited.insert(ND).second) Queue.push_back(ND); } @@ -2396,28 +2389,6 @@ static bool LookupQualifiedNameInUsingDirectives(Sema &S, LookupResult &R, return Found; } -/// Perform qualified name lookup into a given context. -/// -/// Qualified name lookup (C++ [basic.lookup.qual]) is used to find -/// names when the context of those names is explicit specified, e.g., -/// "std::vector" or "x->member", or as part of unqualified name lookup. -/// -/// Different lookup criteria can find different names. For example, a -/// particular scope can have both a struct and a function of the same -/// name, and each can be found by certain lookup criteria. For more -/// information about lookup criteria, see the documentation for the -/// class LookupCriteria. -/// -/// \param R captures both the lookup criteria and any lookup results found. -/// -/// \param LookupCtx The context in which qualified name lookup will -/// search. If the lookup criteria permits, name lookup may also search -/// in the parent contexts or (for C++ classes) base classes. -/// -/// \param InUnqualifiedLookup true if this is qualified name lookup that -/// occurs as part of unqualified name lookup. -/// -/// \returns true if lookup succeeded, false if it failed. bool Sema::LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx, bool InUnqualifiedLookup) { assert(LookupCtx && "Sema::LookupQualifiedName requires a lookup context"); @@ -2445,10 +2416,31 @@ bool Sema::LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx, } } QL(LookupCtx); + CXXRecordDecl *LookupRec = dyn_cast<CXXRecordDecl>(LookupCtx); + // FIXME: Per [temp.dep.general]p2, an unqualified name is also dependent + // if it's a dependent conversion-function-id or operator= where the current + // class is a templated entity. This should be handled in LookupName. + if (!InUnqualifiedLookup && !R.isForRedeclaration()) { + // C++23 [temp.dep.type]p5: + // A qualified name is dependent if + // - it is a conversion-function-id whose conversion-type-id + // is dependent, or + // - [...] + // - its lookup context is the current instantiation and it + // is operator=, or + // - [...] + if (DeclarationName Name = R.getLookupName(); + Name.getNameKind() == DeclarationName::CXXConversionFunctionName && + Name.getCXXNameType()->isDependentType()) { + R.setNotFoundInCurrentInstantiation(); + return false; + } + } + if (LookupDirect(*this, R, LookupCtx)) { R.resolveKind(); - if (isa<CXXRecordDecl>(LookupCtx)) - R.setNamingClass(cast<CXXRecordDecl>(LookupCtx)); + if (LookupRec) + R.setNamingClass(LookupRec); return true; } @@ -2470,7 +2462,6 @@ bool Sema::LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx, // If this isn't a C++ class, we aren't allowed to look into base // classes, we're done. - CXXRecordDecl *LookupRec = dyn_cast<CXXRecordDecl>(LookupCtx); if (!LookupRec || !LookupRec->getDefinition()) return false; @@ -2672,21 +2663,6 @@ bool Sema::LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx, return true; } -/// Performs qualified name lookup or special type of lookup for -/// "__super::" scope specifier. -/// -/// This routine is a convenience overload meant to be called from contexts -/// that need to perform a qualified name lookup with an optional C++ scope -/// specifier that might require special kind of lookup. -/// -/// \param R captures both the lookup criteria and any lookup results found. -/// -/// \param LookupCtx The context in which qualified name lookup will -/// search. -/// -/// \param SS An optional C++ scope-specifier. -/// -/// \returns true if lookup succeeded, false if it failed. bool Sema::LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx, CXXScopeSpec &SS) { auto *NNS = SS.getScopeRep(); @@ -2697,69 +2673,60 @@ bool Sema::LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx, return LookupQualifiedName(R, LookupCtx); } -/// Performs name lookup for a name that was parsed in the -/// source code, and may contain a C++ scope specifier. -/// -/// This routine is a convenience routine meant to be called from -/// contexts that receive a name and an optional C++ scope specifier -/// (e.g., "N::M::x"). It will then perform either qualified or -/// unqualified name lookup (with LookupQualifiedName or LookupName, -/// respectively) on the given name and return those results. It will -/// perform a special type of lookup for "__super::" scope specifier. -/// -/// @param S The scope from which unqualified name lookup will -/// begin. -/// -/// @param SS An optional C++ scope-specifier, e.g., "::N::M". -/// -/// @param EnteringContext Indicates whether we are going to enter the -/// context of the scope-specifier SS (if present). -/// -/// @returns True if any decls were found (but possibly ambiguous) bool Sema::LookupParsedName(LookupResult &R, Scope *S, CXXScopeSpec *SS, - bool AllowBuiltinCreation, bool EnteringContext) { - if (SS && SS->isInvalid()) { - // When the scope specifier is invalid, don't even look for - // anything. + QualType ObjectType, bool AllowBuiltinCreation, + bool EnteringContext) { + // When the scope specifier is invalid, don't even look for anything. + if (SS && SS->isInvalid()) return false; - } - - if (SS && SS->isSet()) { - NestedNameSpecifier *NNS = SS->getScopeRep(); - if (NNS->getKind() == NestedNameSpecifier::Super) - return LookupInSuper(R, NNS->getAsRecordDecl()); - if (DeclContext *DC = computeDeclContext(*SS, EnteringContext)) { - // We have resolved the scope specifier to a particular declaration - // contex, and will perform name lookup in that context. + // Determine where to perform name lookup + DeclContext *DC = nullptr; + bool IsDependent = false; + if (!ObjectType.isNull()) { + // This nested-name-specifier occurs in a member access expression, e.g., + // x->B::f, and we are looking into the type of the object. + assert((!SS || SS->isEmpty()) && + "ObjectType and scope specifier cannot coexist"); + DC = computeDeclContext(ObjectType); + IsDependent = !DC && ObjectType->isDependentType(); + assert(((!DC && ObjectType->isDependentType()) || + !ObjectType->isIncompleteType() || !ObjectType->getAs<TagType>() || + ObjectType->castAs<TagType>()->isBeingDefined()) && + "Caller should have completed object type"); + } else if (SS && SS->isNotEmpty()) { + // This nested-name-specifier occurs after another nested-name-specifier, + // so long into the context associated with the prior nested-name-specifier. + if ((DC = computeDeclContext(*SS, EnteringContext))) { + // The declaration context must be complete. if (!DC->isDependentContext() && RequireCompleteDeclContext(*SS, DC)) return false; - R.setContextRange(SS->getRange()); - return LookupQualifiedName(R, DC); + // FIXME: '__super' lookup semantics could be implemented by a + // LookupResult::isSuperLookup flag which skips the initial search of + // the lookup context in LookupQualified. + if (NestedNameSpecifier *NNS = SS->getScopeRep(); + NNS->getKind() == NestedNameSpecifier::Super) + return LookupInSuper(R, NNS->getAsRecordDecl()); } + IsDependent = !DC && isDependentScopeSpecifier(*SS); + } else { + // Perform unqualified name lookup starting in the given scope. + return LookupName(R, S, AllowBuiltinCreation); + } + // If we were able to compute a declaration context, perform qualified name + // lookup in that context. + if (DC) + return LookupQualifiedName(R, DC); + else if (IsDependent) // We could not resolve the scope specified to a specific declaration // context, which means that SS refers to an unknown specialization. // Name lookup can't find anything in this case. R.setNotFoundInCurrentInstantiation(); - R.setContextRange(SS->getRange()); - return false; - } - - // Perform unqualified name lookup starting in the given scope. - return LookupName(R, S, AllowBuiltinCreation); + return false; } -/// Perform qualified name lookup into all base classes of the given -/// class. -/// -/// \param R captures both the lookup criteria and any lookup results found. -/// -/// \param Class The context in which qualified name lookup will -/// search. Name lookup will search in all base classes merging the results. -/// -/// @returns True if any decls were found (but possibly ambiguous) bool Sema::LookupInSuper(LookupResult &R, CXXRecordDecl *Class) { // The access-control rules we use here are essentially the rules for // doing a lookup in Class that just magically skipped the direct @@ -2789,10 +2756,6 @@ bool Sema::LookupInSuper(LookupResult &R, CXXRecordDecl *Class) { return !R.empty(); } -/// Produce a diagnostic describing the ambiguity that resulted -/// from name lookup. -/// -/// \param Result The result of the ambiguous lookup to be diagnosed. void Sema::DiagnoseAmbiguousLookup(LookupResult &Result) { assert(Result.isAmbiguous() && "Lookup result must be ambiguous"); @@ -3243,6 +3206,10 @@ addAssociatedClassesAndNamespaces(AssociatedLookup &Result, QualType Ty) { case Type::Pipe: T = cast<PipeType>(T)->getElementType().getTypePtr(); continue; + + // Array parameter types are treated as fundamental types. + case Type::ArrayParameter: + break; } if (Queue.empty()) @@ -3251,13 +3218,6 @@ addAssociatedClassesAndNamespaces(AssociatedLookup &Result, QualType Ty) { } } -/// Find the associated classes and namespaces for -/// argument-dependent lookup for a call with the given set of -/// arguments. -/// -/// This routine computes the sets of associated classes and associated -/// namespaces searched by argument-dependent lookup -/// (C++ [basic.lookup.argdep]) for a given set of arguments. void Sema::FindAssociatedClassesAndNamespaces( SourceLocation InstantiationLoc, ArrayRef<Expr *> Args, AssociatedNamespaceSet &AssociatedNamespaces, @@ -3312,15 +3272,6 @@ NamedDecl *Sema::LookupSingleName(Scope *S, DeclarationName Name, return R.getAsSingle<NamedDecl>(); } -/// Find the protocol with the given name, if any. -ObjCProtocolDecl *Sema::LookupProtocol(IdentifierInfo *II, - SourceLocation IdLoc, - RedeclarationKind Redecl) { - Decl *D = LookupSingleName(TUScope, II, IdLoc, - LookupObjCProtocolName, Redecl); - return cast_or_null<ObjCProtocolDecl>(D); -} - void Sema::LookupOverloadedOperatorName(OverloadedOperatorKind Op, Scope *S, UnresolvedSetImpl &Functions) { // C++ [over.match.oper]p3: @@ -3337,21 +3288,20 @@ void Sema::LookupOverloadedOperatorName(OverloadedOperatorKind Op, Scope *S, Functions.append(Operators.begin(), Operators.end()); } -Sema::SpecialMemberOverloadResult Sema::LookupSpecialMember(CXXRecordDecl *RD, - CXXSpecialMember SM, - bool ConstArg, - bool VolatileArg, - bool RValueThis, - bool ConstThis, - bool VolatileThis) { +Sema::SpecialMemberOverloadResult +Sema::LookupSpecialMember(CXXRecordDecl *RD, CXXSpecialMemberKind SM, + bool ConstArg, bool VolatileArg, bool RValueThis, + bool ConstThis, bool VolatileThis) { assert(CanDeclareSpecialMemberFunction(RD) && "doing special member lookup into record that isn't fully complete"); RD = RD->getDefinition(); if (RValueThis || ConstThis || VolatileThis) - assert((SM == CXXCopyAssignment || SM == CXXMoveAssignment) && + assert((SM == CXXSpecialMemberKind::CopyAssignment || + SM == CXXSpecialMemberKind::MoveAssignment) && "constructors and destructors always have unqualified lvalue this"); if (ConstArg || VolatileArg) - assert((SM != CXXDefaultConstructor && SM != CXXDestructor) && + assert((SM != CXXSpecialMemberKind::DefaultConstructor && + SM != CXXSpecialMemberKind::Destructor) && "parameter-less special members can't have qualified arguments"); // FIXME: Get the caller to pass in a location for the lookup. @@ -3359,7 +3309,7 @@ Sema::SpecialMemberOverloadResult Sema::LookupSpecialMember(CXXRecordDecl *RD, llvm::FoldingSetNodeID ID; ID.AddPointer(RD); - ID.AddInteger(SM); + ID.AddInteger(llvm::to_underlying(SM)); ID.AddInteger(ConstArg); ID.AddInteger(VolatileArg); ID.AddInteger(RValueThis); @@ -3378,7 +3328,7 @@ Sema::SpecialMemberOverloadResult Sema::LookupSpecialMember(CXXRecordDecl *RD, Result = new (Result) SpecialMemberOverloadResultEntry(ID); SpecialMemberCache.InsertNode(Result, InsertPoint); - if (SM == CXXDestructor) { + if (SM == CXXSpecialMemberKind::Destructor) { if (RD->needsImplicitDestructor()) { runWithSufficientStackSpace(RD->getLocation(), [&] { DeclareImplicitDestructor(RD); @@ -3402,7 +3352,7 @@ Sema::SpecialMemberOverloadResult Sema::LookupSpecialMember(CXXRecordDecl *RD, QualType ArgType = CanTy; ExprValueKind VK = VK_LValue; - if (SM == CXXDefaultConstructor) { + if (SM == CXXSpecialMemberKind::DefaultConstructor) { Name = Context.DeclarationNames.getCXXConstructorName(CanTy); NumArgs = 0; if (RD->needsImplicitDefaultConstructor()) { @@ -3411,7 +3361,8 @@ Sema::SpecialMemberOverloadResult Sema::LookupSpecialMember(CXXRecordDecl *RD, }); } } else { - if (SM == CXXCopyConstructor || SM == CXXMoveConstructor) { + if (SM == CXXSpecialMemberKind::CopyConstructor || + SM == CXXSpecialMemberKind::MoveConstructor) { Name = Context.DeclarationNames.getCXXConstructorName(CanTy); if (RD->needsImplicitCopyConstructor()) { runWithSufficientStackSpace(RD->getLocation(), [&] { @@ -3449,7 +3400,8 @@ Sema::SpecialMemberOverloadResult Sema::LookupSpecialMember(CXXRecordDecl *RD, // Possibly an XValue is actually correct in the case of move, but // there is no semantic difference for class types in this restricted // case. - if (SM == CXXCopyConstructor || SM == CXXCopyAssignment) + if (SM == CXXSpecialMemberKind::CopyConstructor || + SM == CXXSpecialMemberKind::CopyAssignment) VK = VK_LValue; else VK = VK_PRValue; @@ -3457,7 +3409,7 @@ Sema::SpecialMemberOverloadResult Sema::LookupSpecialMember(CXXRecordDecl *RD, OpaqueValueExpr FakeArg(LookupLoc, ArgType, VK); - if (SM != CXXDefaultConstructor) { + if (SM != CXXSpecialMemberKind::DefaultConstructor) { NumArgs = 1; Arg = &FakeArg; } @@ -3483,7 +3435,7 @@ Sema::SpecialMemberOverloadResult Sema::LookupSpecialMember(CXXRecordDecl *RD, // type, rather than because there's some other declared constructor. // Every class has a copy/move constructor, copy/move assignment, and // destructor. - assert(SM == CXXDefaultConstructor && + assert(SM == CXXSpecialMemberKind::DefaultConstructor && "lookup for a constructor or assignment operator was empty"); Result->setMethod(nullptr); Result->setKind(SpecialMemberOverloadResult::NoMemberOrDeleted); @@ -3501,7 +3453,8 @@ Sema::SpecialMemberOverloadResult Sema::LookupSpecialMember(CXXRecordDecl *RD, DeclAccessPair Cand = DeclAccessPair::make(CandDecl, AS_public); auto CtorInfo = getConstructorInfo(Cand); if (CXXMethodDecl *M = dyn_cast<CXXMethodDecl>(Cand->getUnderlyingDecl())) { - if (SM == CXXCopyAssignment || SM == CXXMoveAssignment) + if (SM == CXXSpecialMemberKind::CopyAssignment || + SM == CXXSpecialMemberKind::MoveAssignment) AddMethodCandidate(M, Cand, RD, ThisTy, Classification, llvm::ArrayRef(&Arg, NumArgs), OCS, true); else if (CtorInfo) @@ -3513,7 +3466,8 @@ Sema::SpecialMemberOverloadResult Sema::LookupSpecialMember(CXXRecordDecl *RD, /*SuppressUserConversions*/ true); } else if (FunctionTemplateDecl *Tmpl = dyn_cast<FunctionTemplateDecl>(Cand->getUnderlyingDecl())) { - if (SM == CXXCopyAssignment || SM == CXXMoveAssignment) + if (SM == CXXSpecialMemberKind::CopyAssignment || + SM == CXXSpecialMemberKind::MoveAssignment) AddMethodTemplateCandidate(Tmpl, Cand, RD, nullptr, ThisTy, Classification, llvm::ArrayRef(&Arg, NumArgs), OCS, true); @@ -3556,38 +3510,34 @@ Sema::SpecialMemberOverloadResult Sema::LookupSpecialMember(CXXRecordDecl *RD, return *Result; } -/// Look up the default constructor for the given class. CXXConstructorDecl *Sema::LookupDefaultConstructor(CXXRecordDecl *Class) { SpecialMemberOverloadResult Result = - LookupSpecialMember(Class, CXXDefaultConstructor, false, false, false, - false, false); + LookupSpecialMember(Class, CXXSpecialMemberKind::DefaultConstructor, + false, false, false, false, false); return cast_or_null<CXXConstructorDecl>(Result.getMethod()); } -/// Look up the copying constructor for the given class. CXXConstructorDecl *Sema::LookupCopyingConstructor(CXXRecordDecl *Class, unsigned Quals) { assert(!(Quals & ~(Qualifiers::Const | Qualifiers::Volatile)) && "non-const, non-volatile qualifiers for copy ctor arg"); - SpecialMemberOverloadResult Result = - LookupSpecialMember(Class, CXXCopyConstructor, Quals & Qualifiers::Const, - Quals & Qualifiers::Volatile, false, false, false); + SpecialMemberOverloadResult Result = LookupSpecialMember( + Class, CXXSpecialMemberKind::CopyConstructor, Quals & Qualifiers::Const, + Quals & Qualifiers::Volatile, false, false, false); return cast_or_null<CXXConstructorDecl>(Result.getMethod()); } -/// Look up the moving constructor for the given class. CXXConstructorDecl *Sema::LookupMovingConstructor(CXXRecordDecl *Class, unsigned Quals) { - SpecialMemberOverloadResult Result = - LookupSpecialMember(Class, CXXMoveConstructor, Quals & Qualifiers::Const, - Quals & Qualifiers::Volatile, false, false, false); + SpecialMemberOverloadResult Result = LookupSpecialMember( + Class, CXXSpecialMemberKind::MoveConstructor, Quals & Qualifiers::Const, + Quals & Qualifiers::Volatile, false, false, false); return cast_or_null<CXXConstructorDecl>(Result.getMethod()); } -/// Look up the constructors for the given class. DeclContext::lookup_result Sema::LookupConstructors(CXXRecordDecl *Class) { // If the implicit constructors have not yet been declared, do so now. if (CanDeclareSpecialMemberFunction(Class)) { @@ -3606,7 +3556,6 @@ DeclContext::lookup_result Sema::LookupConstructors(CXXRecordDecl *Class) { return Class->lookup(Name); } -/// Look up the copying assignment operator for the given class. CXXMethodDecl *Sema::LookupCopyingAssignment(CXXRecordDecl *Class, unsigned Quals, bool RValueThis, unsigned ThisQuals) { @@ -3614,50 +3563,35 @@ CXXMethodDecl *Sema::LookupCopyingAssignment(CXXRecordDecl *Class, "non-const, non-volatile qualifiers for copy assignment arg"); assert(!(ThisQuals & ~(Qualifiers::Const | Qualifiers::Volatile)) && "non-const, non-volatile qualifiers for copy assignment this"); - SpecialMemberOverloadResult Result = - LookupSpecialMember(Class, CXXCopyAssignment, Quals & Qualifiers::Const, - Quals & Qualifiers::Volatile, RValueThis, - ThisQuals & Qualifiers::Const, - ThisQuals & Qualifiers::Volatile); + SpecialMemberOverloadResult Result = LookupSpecialMember( + Class, CXXSpecialMemberKind::CopyAssignment, Quals & Qualifiers::Const, + Quals & Qualifiers::Volatile, RValueThis, ThisQuals & Qualifiers::Const, + ThisQuals & Qualifiers::Volatile); return Result.getMethod(); } -/// Look up the moving assignment operator for the given class. CXXMethodDecl *Sema::LookupMovingAssignment(CXXRecordDecl *Class, unsigned Quals, bool RValueThis, unsigned ThisQuals) { assert(!(ThisQuals & ~(Qualifiers::Const | Qualifiers::Volatile)) && "non-const, non-volatile qualifiers for copy assignment this"); - SpecialMemberOverloadResult Result = - LookupSpecialMember(Class, CXXMoveAssignment, Quals & Qualifiers::Const, - Quals & Qualifiers::Volatile, RValueThis, - ThisQuals & Qualifiers::Const, - ThisQuals & Qualifiers::Volatile); + SpecialMemberOverloadResult Result = LookupSpecialMember( + Class, CXXSpecialMemberKind::MoveAssignment, Quals & Qualifiers::Const, + Quals & Qualifiers::Volatile, RValueThis, ThisQuals & Qualifiers::Const, + ThisQuals & Qualifiers::Volatile); return Result.getMethod(); } -/// Look for the destructor of the given class. -/// -/// During semantic analysis, this routine should be used in lieu of -/// CXXRecordDecl::getDestructor(). -/// -/// \returns The destructor for this class. CXXDestructorDecl *Sema::LookupDestructor(CXXRecordDecl *Class) { return cast_or_null<CXXDestructorDecl>( - LookupSpecialMember(Class, CXXDestructor, false, false, false, false, - false) + LookupSpecialMember(Class, CXXSpecialMemberKind::Destructor, false, false, + false, false, false) .getMethod()); } -/// LookupLiteralOperator - Determine which literal operator should be used for -/// a user-defined literal, per C++11 [lex.ext]. -/// -/// Normal overload resolution is not used to select which literal operator to -/// call for a user-defined literal. Look up the provided literal operator name, -/// and filter the results to the appropriate set for the given argument types. Sema::LiteralOperatorLookupResult Sema::LookupLiteralOperator(Scope *S, LookupResult &R, ArrayRef<QualType> ArgTys, bool AllowRaw, @@ -4425,10 +4359,6 @@ void Sema::LookupVisibleDecls(DeclContext *Ctx, LookupNameKind Kind, H.lookupVisibleDecls(*this, Ctx, Kind, IncludeGlobalScope); } -/// LookupOrCreateLabel - Do a name lookup of a label with the specified name. -/// If GnuLabelLoc is a valid source location, then this is a definition -/// of an __label__ label name, otherwise it is a normal label definition -/// or use. LabelDecl *Sema::LookupOrCreateLabel(IdentifierInfo *II, SourceLocation Loc, SourceLocation GnuLabelLoc) { // Do a lookup to see if we have a label with this name already. @@ -4443,7 +4373,8 @@ LabelDecl *Sema::LookupOrCreateLabel(IdentifierInfo *II, SourceLocation Loc, } // Not a GNU local label. - Res = LookupSingleName(CurScope, II, Loc, LookupLabel, NotForRedeclaration); + Res = LookupSingleName(CurScope, II, Loc, LookupLabel, + RedeclarationKind::NotForRedeclaration); // If we found a label, check to see if it is in the same context as us. // When in a Block, we don't want to reuse a label in an enclosing function. if (Res && Res->getDeclContext() != CurContext) @@ -5011,8 +4942,9 @@ static void LookupPotentialTypoResult(Sema &SemaRef, return; } - SemaRef.LookupParsedName(Res, S, SS, /*AllowBuiltinCreation=*/false, - EnteringContext); + SemaRef.LookupParsedName(Res, S, SS, + /*ObjectType=*/QualType(), + /*AllowBuiltinCreation=*/false, EnteringContext); // Fake ivar lookup; this should really be part of // LookupParsedName. @@ -5051,7 +4983,7 @@ static void AddKeywordsToConsumer(Sema &SemaRef, static const char *const CTypeSpecs[] = { "char", "const", "double", "enum", "float", "int", "long", "short", "signed", "struct", "union", "unsigned", "void", "volatile", - "_Complex", "_Imaginary", + "_Complex", // storage-specifiers as well "extern", "inline", "static", "typedef" }; @@ -5059,6 +4991,9 @@ static void AddKeywordsToConsumer(Sema &SemaRef, for (const auto *CTS : CTypeSpecs) Consumer.addKeywordResult(CTS); + if (SemaRef.getLangOpts().C99 && !SemaRef.getLangOpts().C2y) + Consumer.addKeywordResult("_Imaginary"); + if (SemaRef.getLangOpts().C99) Consumer.addKeywordResult("restrict"); if (SemaRef.getLangOpts().Bool || SemaRef.getLangOpts().CPlusPlus) @@ -5323,37 +5258,6 @@ std::unique_ptr<TypoCorrectionConsumer> Sema::makeTypoCorrectionConsumer( return Consumer; } -/// Try to "correct" a typo in the source code by finding -/// visible declarations whose names are similar to the name that was -/// present in the source code. -/// -/// \param TypoName the \c DeclarationNameInfo structure that contains -/// the name that was present in the source code along with its location. -/// -/// \param LookupKind the name-lookup criteria used to search for the name. -/// -/// \param S the scope in which name lookup occurs. -/// -/// \param SS the nested-name-specifier that precedes the name we're -/// looking for, if present. -/// -/// \param CCC A CorrectionCandidateCallback object that provides further -/// validation of typo correction candidates. It also provides flags for -/// determining the set of keywords permitted. -/// -/// \param MemberContext if non-NULL, the context in which to look for -/// a member access expression. -/// -/// \param EnteringContext whether we're entering the context described by -/// the nested-name-specifier SS. -/// -/// \param OPT when non-NULL, the search for visible declarations will -/// also walk the protocols in the qualified interfaces of \p OPT. -/// -/// \returns a \c TypoCorrection containing the corrected name if the typo -/// along with information such as the \c NamedDecl where the corrected name -/// was declared, and any additional \c NestedNameSpecifier needed to access -/// it (C++ only). The \c TypoCorrection is empty if there is no correction. TypoCorrection Sema::CorrectTypo(const DeclarationNameInfo &TypoName, Sema::LookupNameKind LookupKind, Scope *S, CXXScopeSpec *SS, @@ -5451,44 +5355,6 @@ TypoCorrection Sema::CorrectTypo(const DeclarationNameInfo &TypoName, return FailedCorrection(Typo, TypoName.getLoc(), RecordFailure && !SecondBestTC); } -/// Try to "correct" a typo in the source code by finding -/// visible declarations whose names are similar to the name that was -/// present in the source code. -/// -/// \param TypoName the \c DeclarationNameInfo structure that contains -/// the name that was present in the source code along with its location. -/// -/// \param LookupKind the name-lookup criteria used to search for the name. -/// -/// \param S the scope in which name lookup occurs. -/// -/// \param SS the nested-name-specifier that precedes the name we're -/// looking for, if present. -/// -/// \param CCC A CorrectionCandidateCallback object that provides further -/// validation of typo correction candidates. It also provides flags for -/// determining the set of keywords permitted. -/// -/// \param TDG A TypoDiagnosticGenerator functor that will be used to print -/// diagnostics when the actual typo correction is attempted. -/// -/// \param TRC A TypoRecoveryCallback functor that will be used to build an -/// Expr from a typo correction candidate. -/// -/// \param MemberContext if non-NULL, the context in which to look for -/// a member access expression. -/// -/// \param EnteringContext whether we're entering the context described by -/// the nested-name-specifier SS. -/// -/// \param OPT when non-NULL, the search for visible declarations will -/// also walk the protocols in the qualified interfaces of \p OPT. -/// -/// \returns a new \c TypoExpr that will later be replaced in the AST with an -/// Expr representing the result of performing typo correction, or nullptr if -/// typo correction is not possible. If nullptr is returned, no diagnostics will -/// be emitted and it is the responsibility of the caller to emit any that are -/// needed. TypoExpr *Sema::CorrectTypoDelayed( const DeclarationNameInfo &TypoName, Sema::LookupNameKind LookupKind, Scope *S, CXXScopeSpec *SS, CorrectionCandidateCallback &CCC, @@ -5765,19 +5631,13 @@ void Sema::diagnoseMissingImport(SourceLocation UseLoc, const NamedDecl *Decl, if (M->isModuleMapModule()) return M->getFullModuleName(); - Module *CurrentModule = getCurrentModule(); - if (M->isImplicitGlobalModule()) M = M->getTopLevelModule(); - bool IsInTheSameModule = - CurrentModule && CurrentModule->getPrimaryModuleInterfaceName() == - M->getPrimaryModuleInterfaceName(); - // If the current module unit is in the same module with M, it is OK to show // the partition name. Otherwise, it'll be sufficient to show the primary // module name. - if (IsInTheSameModule) + if (getASTContext().isInSameModule(M, getCurrentModule())) return M->getTopLevelModuleName().str(); else return M->getPrimaryModuleInterfaceName().str(); @@ -5810,18 +5670,6 @@ void Sema::diagnoseMissingImport(SourceLocation UseLoc, const NamedDecl *Decl, createImplicitModuleImportForErrorRecovery(UseLoc, Modules[0]); } -/// Diagnose a successfully-corrected typo. Separated from the correction -/// itself to allow external validation of the result, etc. -/// -/// \param Correction The result of performing typo correction. -/// \param TypoDiag The diagnostic to produce. This will have the corrected -/// string added to it (and usually also a fixit). -/// \param PrevNote A note to use when indicating the location of the entity to -/// which we are correcting. Will have the correction string added to it. -/// \param ErrorRecovery If \c true (the default), the caller is going to -/// recover from the typo as if the corrected string had been typed. -/// In this case, \c PDiag must be an error, and we will attach a fixit -/// to it. void Sema::diagnoseTypo(const TypoCorrection &Correction, const PartialDiagnostic &TypoDiag, const PartialDiagnostic &PrevNote, @@ -5846,6 +5694,16 @@ void Sema::diagnoseTypo(const TypoCorrection &Correction, NamedDecl *ChosenDecl = Correction.isKeyword() ? nullptr : Correction.getFoundDecl(); + + // For builtin functions which aren't declared anywhere in source, + // don't emit the "declared here" note. + if (const auto *FD = dyn_cast_if_present<FunctionDecl>(ChosenDecl); + FD && FD->getBuiltinID() && + PrevNote.getDiagID() == diag::note_previous_decl && + Correction.getCorrectionRange().getBegin() == FD->getBeginLoc()) { + ChosenDecl = nullptr; + } + if (PrevNote.getDiagID() && ChosenDecl) Diag(ChosenDecl->getLocation(), PrevNote) << CorrectedQuotedStr << (ErrorRecovery ? FixItHint() : FixTypo); @@ -5883,7 +5741,8 @@ void Sema::clearDelayedTypo(TypoExpr *TE) { void Sema::ActOnPragmaDump(Scope *S, SourceLocation IILoc, IdentifierInfo *II) { DeclarationNameInfo Name(II, IILoc); - LookupResult R(*this, Name, LookupAnyName, Sema::NotForRedeclaration); + LookupResult R(*this, Name, LookupAnyName, + RedeclarationKind::NotForRedeclaration); R.suppressDiagnostics(); R.setHideTags(false); LookupName(R, S); @@ -5893,3 +5752,13 @@ void Sema::ActOnPragmaDump(Scope *S, SourceLocation IILoc, IdentifierInfo *II) { void Sema::ActOnPragmaDump(Expr *E) { E->dump(); } + +RedeclarationKind Sema::forRedeclarationInCurContext() const { + // A declaration with an owning module for linkage can never link against + // anything that is not visible. We don't need to check linkage here; if + // the context has internal linkage, redeclaration lookup won't find things + // from other TUs, and we can't safely compute linkage yet in general. + if (cast<Decl>(CurContext)->getOwningModuleForLinkage()) + return RedeclarationKind::ForVisibleRedeclaration; + return RedeclarationKind::ForExternalRedeclaration; +} |