aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2009-12-11 02:10:03 +0000
committerJohn McCall <rjmccall@apple.com>2009-12-11 02:10:03 +0000
commit60fa3cfd7aa63c29f9fc2d593bac56a3646337cc (patch)
treeeb0327997ca81a13f5706e7b3ff0a5a6b47936cf /lib
parent7e1848ddba7b2a5f73a17387de7078bf8de7a646 (diff)
Implement access declarations. Most of the work here is parsing them, which
is difficult because they're so terribly, terribly ambiguous. We implement access declarations in terms of using declarations, which is quite reasonable. However, we should really persist the access/using distinction in the AST and use the appropriate name in diagnostics. This isn't a priority, so I'll just file a PR and hope someone else does it. :) git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@91095 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/Parse/MinimalAction.cpp1
-rw-r--r--lib/Parse/ParseDeclCXX.cpp42
-rw-r--r--lib/Sema/Sema.h1
-rw-r--r--lib/Sema/SemaDeclCXX.cpp13
4 files changed, 56 insertions, 1 deletions
diff --git a/lib/Parse/MinimalAction.cpp b/lib/Parse/MinimalAction.cpp
index aa0b89b1a3..8b207fab43 100644
--- a/lib/Parse/MinimalAction.cpp
+++ b/lib/Parse/MinimalAction.cpp
@@ -45,6 +45,7 @@ Action::DeclPtrTy Action::ActOnUsingDirective(Scope *CurScope,
// Defined out-of-line here because of dependency on AttributeList
Action::DeclPtrTy Action::ActOnUsingDeclaration(Scope *CurScope,
AccessSpecifier AS,
+ bool HasUsingKeyword,
SourceLocation UsingLoc,
const CXXScopeSpec &SS,
UnqualifiedId &Name,
diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp
index 34ea9c7d9b..78336bbfb1 100644
--- a/lib/Parse/ParseDeclCXX.cpp
+++ b/lib/Parse/ParseDeclCXX.cpp
@@ -357,7 +357,7 @@ Parser::DeclPtrTy Parser::ParseUsingDeclaration(unsigned Context,
AttrList ? "attributes list" : "using declaration",
tok::semi);
- return Actions.ActOnUsingDeclaration(CurScope, AS, UsingLoc, SS, Name,
+ return Actions.ActOnUsingDeclaration(CurScope, AS, true, UsingLoc, SS, Name,
AttrList, IsTypeName, TypenameLoc);
}
@@ -1065,6 +1065,46 @@ void Parser::HandleMemberFunctionDefaultArgs(Declarator& DeclaratorInfo,
///
void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
const ParsedTemplateInfo &TemplateInfo) {
+ // Access declarations.
+ if (!TemplateInfo.Kind &&
+ (Tok.is(tok::identifier) || Tok.is(tok::coloncolon)) &&
+ TryAnnotateCXXScopeToken() &&
+ Tok.is(tok::annot_cxxscope)) {
+ bool isAccessDecl = false;
+ if (NextToken().is(tok::identifier))
+ isAccessDecl = GetLookAheadToken(2).is(tok::semi);
+ else
+ isAccessDecl = NextToken().is(tok::kw_operator);
+
+ if (isAccessDecl) {
+ // Collect the scope specifier token we annotated earlier.
+ CXXScopeSpec SS;
+ ParseOptionalCXXScopeSpecifier(SS, /*ObjectType*/ 0, false);
+
+ // Try to parse an unqualified-id.
+ UnqualifiedId Name;
+ if (ParseUnqualifiedId(SS, false, true, true, /*ObjectType*/ 0, Name)) {
+ SkipUntil(tok::semi);
+ return;
+ }
+
+ // TODO: recover from mistakenly-qualified operator declarations.
+ if (ExpectAndConsume(tok::semi,
+ diag::err_expected_semi_after,
+ "access declaration",
+ tok::semi))
+ return;
+
+ Actions.ActOnUsingDeclaration(CurScope, AS,
+ false, SourceLocation(),
+ SS, Name,
+ /* AttrList */ 0,
+ /* IsTypeName */ false,
+ SourceLocation());
+ return;
+ }
+ }
+
// static_assert-declaration
if (Tok.is(tok::kw_static_assert)) {
// FIXME: Check for templates
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
index 88de8da2b3..aed7a9bc84 100644
--- a/lib/Sema/Sema.h
+++ b/lib/Sema/Sema.h
@@ -1768,6 +1768,7 @@ public:
virtual DeclPtrTy ActOnUsingDeclaration(Scope *CurScope,
AccessSpecifier AS,
+ bool HasUsingKeyword,
SourceLocation UsingLoc,
const CXXScopeSpec &SS,
UnqualifiedId &Name,
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index 70ee24c68e..75021c2850 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -2876,6 +2876,7 @@ void Sema::PushUsingDirective(Scope *S, UsingDirectiveDecl *UDir) {
Sema::DeclPtrTy Sema::ActOnUsingDeclaration(Scope *S,
AccessSpecifier AS,
+ bool HasUsingKeyword,
SourceLocation UsingLoc,
const CXXScopeSpec &SS,
UnqualifiedId &Name,
@@ -2914,6 +2915,18 @@ Sema::DeclPtrTy Sema::ActOnUsingDeclaration(Scope *S,
if (!TargetName)
return DeclPtrTy();
+ // Warn about using declarations.
+ // TODO: store that the declaration was written without 'using' and
+ // talk about access decls instead of using decls in the
+ // diagnostics.
+ if (!HasUsingKeyword) {
+ UsingLoc = Name.getSourceRange().getBegin();
+
+ Diag(UsingLoc, diag::warn_access_decl_deprecated)
+ << CodeModificationHint::CreateInsertion(SS.getRange().getBegin(),
+ "using ");
+ }
+
NamedDecl *UD = BuildUsingDeclaration(S, AS, UsingLoc, SS,
Name.getSourceRange().getBegin(),
TargetName, AttrList,