summaryrefslogtreecommitdiffstats
path: root/lib/Sema/SemaCXXScopeSpec.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Sema/SemaCXXScopeSpec.cpp')
-rw-r--r--lib/Sema/SemaCXXScopeSpec.cpp65
1 files changed, 54 insertions, 11 deletions
diff --git a/lib/Sema/SemaCXXScopeSpec.cpp b/lib/Sema/SemaCXXScopeSpec.cpp
index a70aca2..3e56e67 100644
--- a/lib/Sema/SemaCXXScopeSpec.cpp
+++ b/lib/Sema/SemaCXXScopeSpec.cpp
@@ -148,6 +148,9 @@ DeclContext *Sema::computeDeclContext(const CXXScopeSpec &SS,
case NestedNameSpecifier::Global:
return Context.getTranslationUnitDecl();
+
+ case NestedNameSpecifier::Super:
+ return NNS->getAsRecordDecl();
}
llvm_unreachable("Invalid NestedNameSpecifier::Kind!");
@@ -240,12 +243,43 @@ bool Sema::RequireCompleteDeclContext(CXXScopeSpec &SS,
return true;
}
-bool Sema::ActOnCXXGlobalScopeSpecifier(Scope *S, SourceLocation CCLoc,
+bool Sema::ActOnCXXGlobalScopeSpecifier(SourceLocation CCLoc,
CXXScopeSpec &SS) {
SS.MakeGlobal(Context, CCLoc);
return false;
}
+bool Sema::ActOnSuperScopeSpecifier(SourceLocation SuperLoc,
+ SourceLocation ColonColonLoc,
+ CXXScopeSpec &SS) {
+ CXXRecordDecl *RD = nullptr;
+ for (Scope *S = getCurScope(); S; S = S->getParent()) {
+ if (S->isFunctionScope()) {
+ if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(S->getEntity()))
+ RD = MD->getParent();
+ break;
+ }
+ if (S->isClassScope()) {
+ RD = cast<CXXRecordDecl>(S->getEntity());
+ break;
+ }
+ }
+
+ if (!RD) {
+ Diag(SuperLoc, diag::err_invalid_super_scope);
+ return true;
+ } else if (RD->isLambda()) {
+ Diag(SuperLoc, diag::err_super_in_lambda_unsupported);
+ return true;
+ } else if (RD->getNumBases() == 0) {
+ Diag(SuperLoc, diag::err_no_base_classes) << RD->getName();
+ return true;
+ }
+
+ SS.MakeSuper(Context, RD, SuperLoc, ColonColonLoc);
+ return false;
+}
+
/// \brief Determines whether the given declaration is an valid acceptable
/// result for name lookup of a nested-name-specifier.
bool Sema::isAcceptableNestedNameSpecifier(const NamedDecl *SD) {
@@ -376,9 +410,6 @@ class NestedNameSpecifierValidatorCCC : public CorrectionCandidateCallback {
/// \brief Build a new nested-name-specifier for "identifier::", as described
/// by ActOnCXXNestedNameSpecifier.
///
-/// This routine differs only slightly from ActOnCXXNestedNameSpecifier, in
-/// that it contains an extra parameter \p ScopeLookupResult.
-///
/// \param S Scope in which the nested-name-specifier occurs.
/// \param Identifier Identifier in the sequence "identifier" "::".
/// \param IdentifierLoc Location of the \p Identifier.
@@ -541,12 +572,11 @@ bool Sema::BuildCXXNestedNameSpecifier(Scope *S,
// We haven't found anything, and we're not recovering from a
// different kind of error, so look for typos.
DeclarationName Name = Found.getLookupName();
- NestedNameSpecifierValidatorCCC Validator(*this);
Found.clear();
- if (TypoCorrection Corrected =
- CorrectTypo(Found.getLookupNameInfo(), Found.getLookupKind(), S,
- &SS, Validator, CTK_ErrorRecovery, LookupCtx,
- EnteringContext)) {
+ if (TypoCorrection Corrected = CorrectTypo(
+ Found.getLookupNameInfo(), Found.getLookupKind(), S, &SS,
+ llvm::make_unique<NestedNameSpecifierValidatorCCC>(*this),
+ CTK_ErrorRecovery, LookupCtx, EnteringContext)) {
if (LookupCtx) {
bool DroppedSpecifier =
Corrected.WillReplaceSpecifier() &&
@@ -612,10 +642,17 @@ bool Sema::BuildCXXNestedNameSpecifier(Scope *S,
}
}
+ if (auto *TD = dyn_cast_or_null<TypedefNameDecl>(SD))
+ MarkAnyDeclReferenced(TD->getLocation(), TD, /*OdrUse=*/false);
+
// If we're just performing this lookup for error-recovery purposes,
// don't extend the nested-name-specifier. Just return now.
if (ErrorRecoveryLookup)
return false;
+
+ // The use of a nested name specifier may trigger deprecation warnings.
+ DiagnoseUseOfDecl(SD, CCLoc);
+
if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(SD)) {
SS.Extend(Context, Namespace, IdentifierLoc, CCLoc);
@@ -703,8 +740,13 @@ bool Sema::BuildCXXNestedNameSpecifier(Scope *S,
if (getLangOpts().MSVCCompat) {
DeclContext *DC = LookupCtx ? LookupCtx : CurContext;
if (DC->isDependentContext() && DC->isFunctionOrMethod()) {
- SS.Extend(Context, &Identifier, IdentifierLoc, CCLoc);
- return false;
+ CXXRecordDecl *ContainingClass = dyn_cast<CXXRecordDecl>(DC->getParent());
+ if (ContainingClass && ContainingClass->hasAnyDependentBases()) {
+ Diag(IdentifierLoc, diag::ext_undeclared_unqual_id_with_dependent_base)
+ << &Identifier << ContainingClass;
+ SS.Extend(Context, &Identifier, IdentifierLoc, CCLoc);
+ return false;
+ }
}
}
@@ -945,6 +987,7 @@ bool Sema::ShouldEnterDeclaratorScope(Scope *S, const CXXScopeSpec &SS) {
case NestedNameSpecifier::Identifier:
case NestedNameSpecifier::TypeSpec:
case NestedNameSpecifier::TypeSpecWithTemplate:
+ case NestedNameSpecifier::Super:
// These are never namespace scopes.
return true;
}
OpenPOWER on IntegriCloud