]> granicus.if.org Git - clang/commitdiff
Add parsing of friend specifiers.
authorAnders Carlsson <andersca@mac.com>
Wed, 6 May 2009 04:46:28 +0000 (04:46 +0000)
committerAnders Carlsson <andersca@mac.com>
Wed, 6 May 2009 04:46:28 +0000 (04:46 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@71067 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Parse/DeclSpec.h
lib/Parse/DeclSpec.cpp
lib/Parse/ParseDecl.cpp
test/Parser/cxx-friend.cpp [new file with mode: 0644]

index e97c20f2d19b8f627569c61fc1f3c1428615f2b8..fad3f1e6768f06d5b89c5906a2c406498b338b4e 100644 (file)
@@ -123,6 +123,9 @@ private:
   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 @@ private:
   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 @@ public:
       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 @@ public:
   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:
   ///
index d742ef2ed093a93033a25f9ea0b33fdd5a12eeb6..e592deecd0439f2dbdcee0e1e23e1e280eba7a93 100644 (file)
@@ -294,6 +294,16 @@ bool DeclSpec::SetFunctionSpecExplicit(SourceLocation Loc, const char *&PrevSpec
   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
index 8b81c312d2e015e9c8e0f3104d93b849620f0b3d..b3c2d8c555613236e6a498c7bb9d1ede675ead04 100644 (file)
@@ -597,6 +597,8 @@ bool Parser::ParseImplicitInt(DeclSpec &DS, CXXScopeSpec *SS,
 /// [C99]   'inline'
 /// [C++]   'virtual'
 /// [C++]   'explicit'
+///       'friend': [C++ dcl.friend]
+
 ///
 void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
                                         TemplateParameterLists *TemplateParams,
@@ -846,6 +848,11 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
       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 (file)
index 0000000..5bfaf2f
--- /dev/null
@@ -0,0 +1,5 @@
+// RUN: clang-cc -fsyntax-only %s
+
+class C {
+  friend class D;
+};