]> granicus.if.org Git - clang/commitdiff
Alter Action's friend interface to prepare for templated friend declarations and
authorJohn McCall <rjmccall@apple.com>
Fri, 11 Sep 2009 21:02:39 +0000 (21:02 +0000)
committerJohn McCall <rjmccall@apple.com>
Fri, 11 Sep 2009 21:02:39 +0000 (21:02 +0000)
to stop making promises we can't currently keep.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@81571 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Parse/Action.h
lib/Parse/ParseCXXInlineMethods.cpp
lib/Parse/ParseDeclCXX.cpp
lib/Sema/Sema.h
lib/Sema/SemaDeclCXX.cpp

index 0cacfdbf142d6a6e5e8c67e49c9b7a119c66b84c..83fc0ae263057fe9e2f344961d0577a6e9611a2c 100644 (file)
@@ -1202,11 +1202,19 @@ public:
     return DeclPtrTy();
   }
 
-  /// ActOnFriendDecl - This action is called when a friend declaration is
-  /// encountered.
-  virtual DeclPtrTy ActOnFriendDecl(Scope *S,
-                        llvm::PointerUnion<const DeclSpec*,Declarator*> D,
-                                    bool IsDefinition) {
+  /// ActOnFriendFunctionDecl - Parsed a friend function declarator.
+  /// The name is actually a slight misnomer, because the declarator
+  /// is not necessarily a function declarator.
+  virtual DeclPtrTy ActOnFriendFunctionDecl(Scope *S,
+                                            Declarator &D,
+                                            bool IsDefinition,
+                                            MultiTemplateParamsArg TParams) {
+    return DeclPtrTy();
+  }
+
+  /// ActOnFriendTypeDecl - Parsed a friend type declaration.
+  virtual DeclPtrTy ActOnFriendTypeDecl(Scope *S,
+                                        const DeclSpec &DS) {
     return DeclPtrTy();
   }
 
index 82b7da9f68e5ef5ae546ebf6f848a9fb8292c95d..c34653ee425c4b8d2864ed8f0d1ced3ba0438d2d 100644 (file)
@@ -34,7 +34,7 @@ Parser::ParseCXXInlineMethodDef(AccessSpecifier AS, Declarator &D,
   DeclPtrTy FnD;
   if (D.getDeclSpec().isFriendSpecified())
     // FIXME: Friend templates
-    FnD = Actions.ActOnFriendDecl(CurScope, &D, /*IsDefinition*/ true);
+    FnD = Actions.ActOnFriendFunctionDecl(CurScope, D, true, move(TemplateParams));
   else // FIXME: pass template information through
     FnD = Actions.ActOnCXXMemberDeclarator(CurScope, AS, D,
                                            move(TemplateParams), 0, 0);
index bb268e70c005e6eb61f13d1a9528b5e01a959eaf..b9a0d6165e7e8c1e8f5a37571ac2c58396ffa1e0 100644 (file)
@@ -1019,7 +1019,7 @@ void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
       if (TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate)
         return;
       
-      Actions.ActOnFriendDecl(CurScope, &DS, /*IsDefinition*/ false);
+      Actions.ActOnFriendTypeDecl(CurScope, DS);
     } else
       Actions.ParsedFreeStandingDeclSpec(CurScope, DS);
 
@@ -1122,15 +1122,17 @@ void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
     // this call will *not* return the created decl; It will return null.
     // See Sema::ActOnCXXMemberDeclarator for details.
 
+    Action::MultiTemplateParamsArg TemplateParams(Actions,
+        TemplateInfo.TemplateParams? TemplateInfo.TemplateParams->data() : 0,
+        TemplateInfo.TemplateParams? TemplateInfo.TemplateParams->size() : 0);
+
     DeclPtrTy ThisDecl;
     if (DS.isFriendSpecified()) {
-      // TODO: handle initializers, bitfields, 'delete', friend templates
-      ThisDecl = Actions.ActOnFriendDecl(CurScope, &DeclaratorInfo,
-                                         /*IsDefinition*/ false);
+      // TODO: handle initializers, bitfields, 'delete'
+      ThisDecl = Actions.ActOnFriendFunctionDecl(CurScope, DeclaratorInfo,
+                                                 /*IsDefinition*/ false,
+                                                 move(TemplateParams));
     } else {
-      Action::MultiTemplateParamsArg TemplateParams(Actions,
-          TemplateInfo.TemplateParams? TemplateInfo.TemplateParams->data() : 0,
-          TemplateInfo.TemplateParams? TemplateInfo.TemplateParams->size() : 0);
       ThisDecl = Actions.ActOnCXXMemberDeclarator(CurScope, AS,
                                                   DeclaratorInfo,
                                                   move(TemplateParams),
index 873cc47d89139be568163ae264a35382e8d8f291..d6bc6e51dddc47aa8a53a8dc63a91d24e8ca92a5 100644 (file)
@@ -2245,12 +2245,9 @@ public:
                                                  ExprArg AssertExpr,
                                                  ExprArg AssertMessageExpr);
 
-  virtual DeclPtrTy ActOnFriendDecl(Scope *S,
-                          llvm::PointerUnion<const DeclSpec*,Declarator*> D,
-                                    bool IsDefinition);
-  DeclPtrTy ActOnFriendTypeDecl(Scope *S, const DeclSpec& DS,
-                                bool IsDefinition);
-  DeclPtrTy ActOnFriendFunctionDecl(Scope *S, Declarator& D, bool IsDefinition);
+  DeclPtrTy ActOnFriendTypeDecl(Scope *S, const DeclSpec &DS);
+  DeclPtrTy ActOnFriendFunctionDecl(Scope *S, Declarator &D, bool IsDefinition,
+                                    MultiTemplateParamsArg TemplateParams);
 
   QualType CheckConstructorDeclarator(Declarator &D, QualType R,
                                       FunctionDecl::StorageClass& SC);
index 97d7b2f76da94040e1833997c037e9bcf7ec8887..79b017b330058621150780a60b5dd6538a43c838 100644 (file)
@@ -4008,18 +4008,8 @@ Sema::DeclPtrTy Sema::ActOnStaticAssertDeclaration(SourceLocation AssertLoc,
   return DeclPtrTy::make(Decl);
 }
 
-Sema::DeclPtrTy Sema::ActOnFriendDecl(Scope *S,
-                       llvm::PointerUnion<const DeclSpec*,Declarator*> DU,
-                                      bool IsDefinition) {
-  if (DU.is<Declarator*>())
-    return ActOnFriendFunctionDecl(S, *DU.get<Declarator*>(), IsDefinition);
-  else
-    return ActOnFriendTypeDecl(S, *DU.get<const DeclSpec*>(), IsDefinition);
-}
-
 Sema::DeclPtrTy Sema::ActOnFriendTypeDecl(Scope *S,
-                                          const DeclSpec &DS,
-                                          bool IsDefinition) {
+                                          const DeclSpec &DS) {
   SourceLocation Loc = DS.getSourceRange().getBegin();
 
   assert(DS.isFriendSpecified());
@@ -4056,17 +4046,13 @@ Sema::DeclPtrTy Sema::ActOnFriendTypeDecl(Scope *S,
     }
   }
 
+  bool IsDefinition = false;
   FriendDecl::FriendUnion FU = T.getTypePtr();
 
-  // The parser doesn't quite handle
-  //   friend class A { ... }
-  // optimally, because it might have been the (valid) prefix of
-  //   friend class A { ... } foo();
-  // So in a very particular set of circumstances, we need to adjust
-  // IsDefinition.
-  //
-  // Also, if we made a RecordDecl in ActOnTag, we want that to be the
-  // object of our friend declaration.
+  // We want to do a few things differently if the type was declared with
+  // a tag:  specifically, we want to use the associated RecordDecl as
+  // the object of our friend declaration, and we want to disallow
+  // class definitions.
   switch (DS.getTypeSpecType()) {
   default: break;
   case DeclSpec::TST_class:
@@ -4106,9 +4092,13 @@ Sema::DeclPtrTy Sema::ActOnFriendTypeDecl(Scope *S,
   return DeclPtrTy::make(FD);
 }
 
-Sema::DeclPtrTy Sema::ActOnFriendFunctionDecl(Scope *S,
-                                              Declarator &D,
-                                              bool IsDefinition) {
+Sema::DeclPtrTy
+Sema::ActOnFriendFunctionDecl(Scope *S,
+                              Declarator &D,
+                              bool IsDefinition,
+                              MultiTemplateParamsArg TemplateParams) {
+  // FIXME: do something with template parameters
+
   const DeclSpec &DS = D.getDeclSpec();
 
   assert(DS.isFriendSpecified());