aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/clang/include/clang/Sema/Lookup.h
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/clang/include/clang/Sema/Lookup.h')
-rw-r--r--contrib/llvm-project/clang/include/clang/Sema/Lookup.h127
1 files changed, 97 insertions, 30 deletions
diff --git a/contrib/llvm-project/clang/include/clang/Sema/Lookup.h b/contrib/llvm-project/clang/include/clang/Sema/Lookup.h
index 54fe7081b710..2f2f2607a937 100644
--- a/contrib/llvm-project/clang/include/clang/Sema/Lookup.h
+++ b/contrib/llvm-project/clang/include/clang/Sema/Lookup.h
@@ -26,10 +26,10 @@
#include "clang/Basic/Specifiers.h"
#include "clang/Sema/Sema.h"
#include "llvm/ADT/MapVector.h"
-#include "llvm/ADT/Optional.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/Casting.h"
#include <cassert>
+#include <optional>
#include <utility>
namespace clang {
@@ -117,6 +117,17 @@ public:
/// @endcode
AmbiguousReference,
+ /// Name lookup results in an ambiguity because multiple placeholder
+ /// variables were found in the same scope.
+ /// @code
+ /// void f() {
+ /// int _ = 0;
+ /// int _ = 0;
+ /// return _; // ambiguous use of placeholder variable
+ /// }
+ /// @endcode
+ AmbiguousReferenceToPlaceholderVariable,
+
/// Name lookup results in an ambiguity because an entity with a
/// tag name was hidden by an entity with an ordinary name from
/// a different context.
@@ -148,20 +159,22 @@ public:
: SemaPtr(&SemaRef), NameInfo(NameInfo), LookupKind(LookupKind),
Redecl(Redecl != Sema::NotForRedeclaration),
ExternalRedecl(Redecl == Sema::ForExternalRedeclaration),
- Diagnose(Redecl == Sema::NotForRedeclaration) {
+ DiagnoseAccess(Redecl == Sema::NotForRedeclaration),
+ DiagnoseAmbiguous(Redecl == Sema::NotForRedeclaration) {
configure();
}
// TODO: consider whether this constructor should be restricted to take
// as input a const IdentifierInfo* (instead of Name),
// forcing other cases towards the constructor taking a DNInfo.
- LookupResult(Sema &SemaRef, DeclarationName Name,
- SourceLocation NameLoc, Sema::LookupNameKind LookupKind,
+ LookupResult(Sema &SemaRef, DeclarationName Name, SourceLocation NameLoc,
+ Sema::LookupNameKind LookupKind,
Sema::RedeclarationKind Redecl = Sema::NotForRedeclaration)
: SemaPtr(&SemaRef), NameInfo(Name, NameLoc), LookupKind(LookupKind),
Redecl(Redecl != Sema::NotForRedeclaration),
ExternalRedecl(Redecl == Sema::ForExternalRedeclaration),
- Diagnose(Redecl == Sema::NotForRedeclaration) {
+ DiagnoseAccess(Redecl == Sema::NotForRedeclaration),
+ DiagnoseAmbiguous(Redecl == Sema::NotForRedeclaration) {
configure();
}
@@ -192,12 +205,14 @@ public:
Redecl(std::move(Other.Redecl)),
ExternalRedecl(std::move(Other.ExternalRedecl)),
HideTags(std::move(Other.HideTags)),
- Diagnose(std::move(Other.Diagnose)),
+ DiagnoseAccess(std::move(Other.DiagnoseAccess)),
+ DiagnoseAmbiguous(std::move(Other.DiagnoseAmbiguous)),
AllowHidden(std::move(Other.AllowHidden)),
Shadowed(std::move(Other.Shadowed)),
TemplateNameLookup(std::move(Other.TemplateNameLookup)) {
Other.Paths = nullptr;
- Other.Diagnose = false;
+ Other.DiagnoseAccess = false;
+ Other.DiagnoseAmbiguous = false;
}
LookupResult &operator=(LookupResult &&Other) {
@@ -215,17 +230,22 @@ public:
Redecl = std::move(Other.Redecl);
ExternalRedecl = std::move(Other.ExternalRedecl);
HideTags = std::move(Other.HideTags);
- Diagnose = std::move(Other.Diagnose);
+ DiagnoseAccess = std::move(Other.DiagnoseAccess);
+ DiagnoseAmbiguous = std::move(Other.DiagnoseAmbiguous);
AllowHidden = std::move(Other.AllowHidden);
Shadowed = std::move(Other.Shadowed);
TemplateNameLookup = std::move(Other.TemplateNameLookup);
Other.Paths = nullptr;
- Other.Diagnose = false;
+ Other.DiagnoseAccess = false;
+ Other.DiagnoseAmbiguous = false;
return *this;
}
~LookupResult() {
- if (Diagnose) diagnose();
+ if (DiagnoseAccess)
+ diagnoseAccess();
+ if (DiagnoseAmbiguous)
+ diagnoseAmbiguous();
if (Paths) deletePaths(Paths);
}
@@ -346,30 +366,56 @@ public:
/// Determine whether the given declaration is visible to the
/// program.
- static bool isVisible(Sema &SemaRef, NamedDecl *D) {
- // If this declaration is not hidden, it's visible.
- if (D->isUnconditionallyVisible())
- return true;
+ static bool isVisible(Sema &SemaRef, NamedDecl *D);
- // During template instantiation, we can refer to hidden declarations, if
- // they were visible in any module along the path of instantiation.
- return isVisibleSlow(SemaRef, D);
+ static bool isReachable(Sema &SemaRef, NamedDecl *D);
+
+ static bool isAcceptable(Sema &SemaRef, NamedDecl *D,
+ Sema::AcceptableKind Kind) {
+ return Kind == Sema::AcceptableKind::Visible ? isVisible(SemaRef, D)
+ : isReachable(SemaRef, D);
}
+ /// Determine whether this lookup is permitted to see the declaration.
+ /// Note that a reachable but not visible declaration inhabiting a namespace
+ /// is not allowed to be seen during name lookup.
+ ///
+ /// For example:
+ /// ```
+ /// // m.cppm
+ /// export module m;
+ /// struct reachable { int v; }
+ /// export auto func() { return reachable{43}; }
+ /// // Use.cpp
+ /// import m;
+ /// auto Use() {
+ /// // Not valid. We couldn't see reachable here.
+ /// // So isAvailableForLookup would return false when we look
+ /// up 'reachable' here.
+ /// // return reachable(43).v;
+ /// // Valid. The field name 'v' is allowed during name lookup.
+ /// // So isAvailableForLookup would return true when we look up 'v' here.
+ /// return func().v;
+ /// }
+ /// ```
+ static bool isAvailableForLookup(Sema &SemaRef, NamedDecl *ND);
+
/// Retrieve the accepted (re)declaration of the given declaration,
/// if there is one.
NamedDecl *getAcceptableDecl(NamedDecl *D) const {
if (!D->isInIdentifierNamespace(IDNS))
return nullptr;
- if (isVisible(getSema(), D) || isHiddenDeclarationVisible(D))
+ if (isAvailableForLookup(getSema(), D) || isHiddenDeclarationVisible(D))
return D;
return getAcceptableDeclSlow(D);
}
private:
- static bool isVisibleSlow(Sema &SemaRef, NamedDecl *D);
+ static bool isAcceptableSlow(Sema &SemaRef, NamedDecl *D,
+ Sema::AcceptableKind Kind);
+ static bool isReachableSlow(Sema &SemaRef, NamedDecl *D);
NamedDecl *getAcceptableDeclSlow(NamedDecl *D) const;
public:
@@ -481,7 +527,7 @@ public:
Paths = nullptr;
}
} else {
- llvm::Optional<AmbiguityKind> SavedAK;
+ std::optional<AmbiguityKind> SavedAK;
bool WasAmbiguous = false;
if (ResultKind == Ambiguous) {
SavedAK = Ambiguity;
@@ -495,7 +541,7 @@ public:
if (ResultKind == Ambiguous) {
(void)WasAmbiguous;
assert(WasAmbiguous);
- Ambiguity = SavedAK.getValue();
+ Ambiguity = *SavedAK;
} else if (Paths) {
deletePaths(Paths);
Paths = nullptr;
@@ -581,13 +627,20 @@ public:
/// Suppress the diagnostics that would normally fire because of this
/// lookup. This happens during (e.g.) redeclaration lookups.
void suppressDiagnostics() {
- Diagnose = false;
+ DiagnoseAccess = false;
+ DiagnoseAmbiguous = false;
}
- /// Determines whether this lookup is suppressing diagnostics.
- bool isSuppressingDiagnostics() const {
- return !Diagnose;
- }
+ /// Suppress the diagnostics that would normally fire because of this
+ /// lookup due to access control violations.
+ void suppressAccessDiagnostics() { DiagnoseAccess = false; }
+
+ /// Determines whether this lookup is suppressing access control diagnostics.
+ bool isSuppressingAccessDiagnostics() const { return !DiagnoseAccess; }
+
+ /// Determines whether this lookup is suppressing ambiguous lookup
+ /// diagnostics.
+ bool isSuppressingAmbiguousDiagnostics() const { return !DiagnoseAmbiguous; }
/// Sets a 'context' source range.
void setContextRange(SourceRange SR) {
@@ -631,6 +684,15 @@ public:
F.CalledDone = true;
}
+ // The move assignment operator is defined as deleted pending
+ // further motivation.
+ Filter &operator=(Filter &&) = delete;
+
+ // The copy constrcutor and copy assignment operator is defined as deleted
+ // pending further motivation.
+ Filter(const Filter &) = delete;
+ Filter &operator=(const Filter &) = delete;
+
~Filter() {
assert(CalledDone &&
"LookupResult::Filter destroyed without done() call");
@@ -691,11 +753,15 @@ public:
}
private:
- void diagnose() {
+ void diagnoseAccess() {
+ if (!isAmbiguous() && isClassLookup() &&
+ getSema().getLangOpts().AccessControl)
+ getSema().CheckLookupAccess(*this);
+ }
+
+ void diagnoseAmbiguous() {
if (isAmbiguous())
getSema().DiagnoseAmbiguousLookup(*this);
- else if (isClassLookup() && getSema().getLangOpts().AccessControl)
- getSema().CheckLookupAccess(*this);
}
void setAmbiguous(AmbiguityKind AK) {
@@ -741,7 +807,8 @@ private:
/// are present
bool HideTags = true;
- bool Diagnose = false;
+ bool DiagnoseAccess = false;
+ bool DiagnoseAmbiguous = false;
/// True if we should allow hidden declarations to be 'visible'.
bool AllowHidden = false;