aboutsummaryrefslogtreecommitdiff
path: root/include/clang/Sema/Sema.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/clang/Sema/Sema.h')
-rw-r--r--include/clang/Sema/Sema.h60
1 files changed, 47 insertions, 13 deletions
diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h
index 5db08ba830..a905efe836 100644
--- a/include/clang/Sema/Sema.h
+++ b/include/clang/Sema/Sema.h
@@ -234,17 +234,23 @@ public:
private:
Sema &S;
DeclContext *SavedContext;
-
+ unsigned SavedParsingDeclDepth;
+
public:
- ContextRAII(Sema &S, DeclContext *ContextToPush)
- : S(S), SavedContext(S.CurContext) {
+ ContextRAII(Sema &S, DeclContext *ContextToPush,
+ unsigned ParsingDeclDepth = 0)
+ : S(S), SavedContext(S.CurContext),
+ SavedParsingDeclDepth(S.ParsingDeclDepth)
+ {
assert(ContextToPush && "pushing null context");
S.CurContext = ContextToPush;
+ S.ParsingDeclDepth = 0;
}
void pop() {
if (!SavedContext) return;
S.CurContext = SavedContext;
+ S.ParsingDeclDepth = SavedParsingDeclDepth;
SavedContext = 0;
}
@@ -2803,6 +2809,10 @@ public:
/// A flag to suppress access checking.
bool SuppressAccessChecking;
+ /// \brief When true, access checking violations are treated as SFINAE
+ /// failures rather than hard errors.
+ bool AccessCheckingSFINAE;
+
void ActOnStartSuppressingAccessChecks();
void ActOnStopSuppressingAccessChecks();
@@ -3708,6 +3718,13 @@ public:
llvm::SmallVector<ActiveTemplateInstantiation, 16>
ActiveTemplateInstantiations;
+ /// \brief Whether we are in a SFINAE context that is not associated with
+ /// template instantiation.
+ ///
+ /// This is used when setting up a SFINAE trap (\c see SFINAETrap) outside
+ /// of a template instantiation or template argument deduction.
+ bool InNonInstantiationSFINAEContext;
+
/// \brief The number of ActiveTemplateInstantiation entries in
/// \c ActiveTemplateInstantiations that are not actual instantiations and,
/// therefore, should not be counted as part of the instantiation depth.
@@ -3729,7 +3746,7 @@ public:
/// should be instantiated as themselves. Otherwise, the index specifies
/// which argument within the parameter pack will be used for substitution.
int ArgumentPackSubstitutionIndex;
-
+
/// \brief RAII object used to change the argument pack substitution index
/// within a \c Sema object.
///
@@ -3855,6 +3872,7 @@ public:
private:
Sema &SemaRef;
bool Invalid;
+ bool SavedInNonInstantiationSFINAEContext;
bool CheckInstantiationDepth(SourceLocation PointOfInstantiation,
SourceRange InstantiationRange);
@@ -3870,23 +3888,39 @@ public:
/// template argument substitution failures are not considered
/// errors.
///
- /// \returns The nearest template-deduction context object, if we are in a
- /// SFINAE context, which can be used to capture diagnostics that will be
- /// suppressed. Otherwise, returns NULL to indicate that we are not within a
- /// SFINAE context.
- sema::TemplateDeductionInfo *isSFINAEContext() const;
+ /// \returns An empty \c llvm::Optional if we're not in a SFINAE context.
+ /// Otherwise, contains a pointer that, if non-NULL, contains the nearest
+ /// template-deduction context object, which can be used to capture
+ /// diagnostics that will be suppressed.
+ llvm::Optional<sema::TemplateDeductionInfo *> isSFINAEContext() const;
/// \brief RAII class used to determine whether SFINAE has
/// trapped any errors that occur during template argument
- /// deduction.
+ /// deduction.`
class SFINAETrap {
Sema &SemaRef;
unsigned PrevSFINAEErrors;
+ bool PrevInNonInstantiationSFINAEContext;
+ bool PrevAccessCheckingSFINAE;
+
public:
- explicit SFINAETrap(Sema &SemaRef)
- : SemaRef(SemaRef), PrevSFINAEErrors(SemaRef.NumSFINAEErrors) { }
+ explicit SFINAETrap(Sema &SemaRef, bool AccessCheckingSFINAE = false)
+ : SemaRef(SemaRef), PrevSFINAEErrors(SemaRef.NumSFINAEErrors),
+ PrevInNonInstantiationSFINAEContext(
+ SemaRef.InNonInstantiationSFINAEContext),
+ PrevAccessCheckingSFINAE(SemaRef.AccessCheckingSFINAE)
+ {
+ if (!SemaRef.isSFINAEContext())
+ SemaRef.InNonInstantiationSFINAEContext = true;
+ SemaRef.AccessCheckingSFINAE = AccessCheckingSFINAE;
+ }
- ~SFINAETrap() { SemaRef.NumSFINAEErrors = PrevSFINAEErrors; }
+ ~SFINAETrap() {
+ SemaRef.NumSFINAEErrors = PrevSFINAEErrors;
+ SemaRef.InNonInstantiationSFINAEContext
+ = PrevInNonInstantiationSFINAEContext;
+ SemaRef.AccessCheckingSFINAE = PrevAccessCheckingSFINAE;
+ }
/// \brief Determine whether any SFINAE errors have been trapped.
bool hasErrorOccurred() const {