Add parsing of friend specifiers.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@71067 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/Parse/DeclSpec.h b/include/clang/Parse/DeclSpec.h
index e97c20f..fad3f1e 100644
--- a/include/clang/Parse/DeclSpec.h
+++ b/include/clang/Parse/DeclSpec.h
@@ -123,6 +123,9 @@
bool FS_virtual_specified : 1;
bool FS_explicit_specified : 1;
+ // friend-specifier
+ bool Friend_specified : 1;
+
/// TypeRep - This contains action-specific information about a specific TST.
/// For example, for a typedef or struct, it might contain the declaration for
/// these.
@@ -145,6 +148,7 @@
SourceLocation TSWLoc, TSCLoc, TSSLoc, TSTLoc;
SourceLocation TQ_constLoc, TQ_restrictLoc, TQ_volatileLoc;
SourceLocation FS_inlineLoc, FS_virtualLoc, FS_explicitLoc;
+ SourceLocation FriendLoc;
bool BadSpecifier(TST T, const char *&PrevSpec);
bool BadSpecifier(TQ T, const char *&PrevSpec);
@@ -168,6 +172,7 @@
FS_inline_specified(false),
FS_virtual_specified(false),
FS_explicit_specified(false),
+ Friend_specified(false),
TypeRep(0),
AttrList(0),
ProtocolQualifiers(0),
@@ -277,6 +282,8 @@
bool SetFunctionSpecVirtual(SourceLocation Loc, const char *&PrevSpec);
bool SetFunctionSpecExplicit(SourceLocation Loc, const char *&PrevSpec);
+ bool SetFriendSpec(SourceLocation Loc, const char *&PrevSpec);
+
/// AddAttributes - contatenates two attribute lists.
/// The GCC attribute syntax allows for the following:
///
diff --git a/lib/Parse/DeclSpec.cpp b/lib/Parse/DeclSpec.cpp
index d742ef2..e592dee 100644
--- a/lib/Parse/DeclSpec.cpp
+++ b/lib/Parse/DeclSpec.cpp
@@ -294,6 +294,16 @@
return false;
}
+bool DeclSpec::SetFriendSpec(SourceLocation Loc, const char *&PrevSpec) {
+ if (Friend_specified) {
+ PrevSpec = "friend";
+ return true;
+ }
+
+ Friend_specified = true;
+ FriendLoc = Loc;
+ return false;
+}
/// Finish - This does final analysis of the declspec, rejecting things like
/// "_Imaginary" (lacking an FP type). This returns a diagnostic to issue or
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp
index 8b81c31..b3c2d8c 100644
--- a/lib/Parse/ParseDecl.cpp
+++ b/lib/Parse/ParseDecl.cpp
@@ -597,6 +597,8 @@
/// [C99] 'inline'
/// [C++] 'virtual'
/// [C++] 'explicit'
+/// 'friend': [C++ dcl.friend]
+
///
void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
TemplateParameterLists *TemplateParams,
@@ -846,6 +848,11 @@
isInvalid = DS.SetFunctionSpecExplicit(Loc, PrevSpec);
break;
+ // friend
+ case tok::kw_friend:
+ isInvalid = DS.SetFriendSpec(Loc, PrevSpec);
+ break;
+
// type-specifier
case tok::kw_short:
isInvalid = DS.SetTypeSpecWidth(DeclSpec::TSW_short, Loc, PrevSpec);
diff --git a/test/Parser/cxx-friend.cpp b/test/Parser/cxx-friend.cpp
new file mode 100644
index 0000000..5bfaf2f
--- /dev/null
+++ b/test/Parser/cxx-friend.cpp
@@ -0,0 +1,5 @@
+// RUN: clang-cc -fsyntax-only %s
+
+class C {
+ friend class D;
+};