aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/clang/lib/Sema/SemaLookup.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/clang/lib/Sema/SemaLookup.cpp')
-rw-r--r--contrib/llvm-project/clang/lib/Sema/SemaLookup.cpp505
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;
+}