diff options
author | Nikola Smiljanic <popizdeh@gmail.com> | 2014-09-26 00:28:20 +0000 |
---|---|---|
committer | Nikola Smiljanic <popizdeh@gmail.com> | 2014-09-26 00:28:20 +0000 |
commit | 7159053ff39fc804d43dde24ce0682394fd2600d (patch) | |
tree | 4ce17326e7e819ad73d2837d7d32a20ff53f7025 /lib/Sema/SemaCXXScopeSpec.cpp | |
parent | 91771659dc757aa861477ec32404a53a4af842b3 (diff) |
-ms-extensions: Implement __super scope specifier (PR13236).
We build a NestedNameSpecifier that records the CXXRecordDecl in which
__super appeared. Name lookup is performed in all base classes of the
recorded CXXRecordDecl. Use of __super is allowed only inside class and
member function scope.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@218484 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaCXXScopeSpec.cpp')
-rw-r--r-- | lib/Sema/SemaCXXScopeSpec.cpp | 37 |
1 files changed, 36 insertions, 1 deletions
diff --git a/lib/Sema/SemaCXXScopeSpec.cpp b/lib/Sema/SemaCXXScopeSpec.cpp index d3f0fad315..739cba7233 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) { @@ -953,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; } |