Alter Action's friend interface to prepare for templated friend declarations and

to stop making promises we can't currently keep.

llvm-svn: 81571
This commit is contained in:
John McCall 2009-09-11 21:02:39 +00:00
parent c0f8eef710
commit 2f212b3a72
5 changed files with 39 additions and 42 deletions

View File

@ -1202,11 +1202,19 @@ public:
return DeclPtrTy(); return DeclPtrTy();
} }
/// ActOnFriendDecl - This action is called when a friend declaration is /// ActOnFriendFunctionDecl - Parsed a friend function declarator.
/// encountered. /// The name is actually a slight misnomer, because the declarator
virtual DeclPtrTy ActOnFriendDecl(Scope *S, /// is not necessarily a function declarator.
llvm::PointerUnion<const DeclSpec*,Declarator*> D, virtual DeclPtrTy ActOnFriendFunctionDecl(Scope *S,
bool IsDefinition) { Declarator &D,
bool IsDefinition,
MultiTemplateParamsArg TParams) {
return DeclPtrTy();
}
/// ActOnFriendTypeDecl - Parsed a friend type declaration.
virtual DeclPtrTy ActOnFriendTypeDecl(Scope *S,
const DeclSpec &DS) {
return DeclPtrTy(); return DeclPtrTy();
} }

View File

@ -34,7 +34,7 @@ Parser::ParseCXXInlineMethodDef(AccessSpecifier AS, Declarator &D,
DeclPtrTy FnD; DeclPtrTy FnD;
if (D.getDeclSpec().isFriendSpecified()) if (D.getDeclSpec().isFriendSpecified())
// FIXME: Friend templates // FIXME: Friend templates
FnD = Actions.ActOnFriendDecl(CurScope, &D, /*IsDefinition*/ true); FnD = Actions.ActOnFriendFunctionDecl(CurScope, D, true, move(TemplateParams));
else // FIXME: pass template information through else // FIXME: pass template information through
FnD = Actions.ActOnCXXMemberDeclarator(CurScope, AS, D, FnD = Actions.ActOnCXXMemberDeclarator(CurScope, AS, D,
move(TemplateParams), 0, 0); move(TemplateParams), 0, 0);

View File

@ -1019,7 +1019,7 @@ void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
if (TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate) if (TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate)
return; return;
Actions.ActOnFriendDecl(CurScope, &DS, /*IsDefinition*/ false); Actions.ActOnFriendTypeDecl(CurScope, DS);
} else } else
Actions.ParsedFreeStandingDeclSpec(CurScope, DS); 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. // this call will *not* return the created decl; It will return null.
// See Sema::ActOnCXXMemberDeclarator for details. // See Sema::ActOnCXXMemberDeclarator for details.
Action::MultiTemplateParamsArg TemplateParams(Actions,
TemplateInfo.TemplateParams? TemplateInfo.TemplateParams->data() : 0,
TemplateInfo.TemplateParams? TemplateInfo.TemplateParams->size() : 0);
DeclPtrTy ThisDecl; DeclPtrTy ThisDecl;
if (DS.isFriendSpecified()) { if (DS.isFriendSpecified()) {
// TODO: handle initializers, bitfields, 'delete', friend templates // TODO: handle initializers, bitfields, 'delete'
ThisDecl = Actions.ActOnFriendDecl(CurScope, &DeclaratorInfo, ThisDecl = Actions.ActOnFriendFunctionDecl(CurScope, DeclaratorInfo,
/*IsDefinition*/ false); /*IsDefinition*/ false,
move(TemplateParams));
} else { } else {
Action::MultiTemplateParamsArg TemplateParams(Actions,
TemplateInfo.TemplateParams? TemplateInfo.TemplateParams->data() : 0,
TemplateInfo.TemplateParams? TemplateInfo.TemplateParams->size() : 0);
ThisDecl = Actions.ActOnCXXMemberDeclarator(CurScope, AS, ThisDecl = Actions.ActOnCXXMemberDeclarator(CurScope, AS,
DeclaratorInfo, DeclaratorInfo,
move(TemplateParams), move(TemplateParams),

View File

@ -2245,12 +2245,9 @@ public:
ExprArg AssertExpr, ExprArg AssertExpr,
ExprArg AssertMessageExpr); ExprArg AssertMessageExpr);
virtual DeclPtrTy ActOnFriendDecl(Scope *S, DeclPtrTy ActOnFriendTypeDecl(Scope *S, const DeclSpec &DS);
llvm::PointerUnion<const DeclSpec*,Declarator*> D, DeclPtrTy ActOnFriendFunctionDecl(Scope *S, Declarator &D, bool IsDefinition,
bool IsDefinition); MultiTemplateParamsArg TemplateParams);
DeclPtrTy ActOnFriendTypeDecl(Scope *S, const DeclSpec& DS,
bool IsDefinition);
DeclPtrTy ActOnFriendFunctionDecl(Scope *S, Declarator& D, bool IsDefinition);
QualType CheckConstructorDeclarator(Declarator &D, QualType R, QualType CheckConstructorDeclarator(Declarator &D, QualType R,
FunctionDecl::StorageClass& SC); FunctionDecl::StorageClass& SC);

View File

@ -4008,18 +4008,8 @@ Sema::DeclPtrTy Sema::ActOnStaticAssertDeclaration(SourceLocation AssertLoc,
return DeclPtrTy::make(Decl); 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, Sema::DeclPtrTy Sema::ActOnFriendTypeDecl(Scope *S,
const DeclSpec &DS, const DeclSpec &DS) {
bool IsDefinition) {
SourceLocation Loc = DS.getSourceRange().getBegin(); SourceLocation Loc = DS.getSourceRange().getBegin();
assert(DS.isFriendSpecified()); assert(DS.isFriendSpecified());
@ -4056,17 +4046,13 @@ Sema::DeclPtrTy Sema::ActOnFriendTypeDecl(Scope *S,
} }
} }
bool IsDefinition = false;
FriendDecl::FriendUnion FU = T.getTypePtr(); FriendDecl::FriendUnion FU = T.getTypePtr();
// The parser doesn't quite handle // We want to do a few things differently if the type was declared with
// friend class A { ... } // a tag: specifically, we want to use the associated RecordDecl as
// optimally, because it might have been the (valid) prefix of // the object of our friend declaration, and we want to disallow
// friend class A { ... } foo(); // class definitions.
// 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.
switch (DS.getTypeSpecType()) { switch (DS.getTypeSpecType()) {
default: break; default: break;
case DeclSpec::TST_class: case DeclSpec::TST_class:
@ -4106,9 +4092,13 @@ Sema::DeclPtrTy Sema::ActOnFriendTypeDecl(Scope *S,
return DeclPtrTy::make(FD); return DeclPtrTy::make(FD);
} }
Sema::DeclPtrTy Sema::ActOnFriendFunctionDecl(Scope *S, Sema::DeclPtrTy
Declarator &D, Sema::ActOnFriendFunctionDecl(Scope *S,
bool IsDefinition) { Declarator &D,
bool IsDefinition,
MultiTemplateParamsArg TemplateParams) {
// FIXME: do something with template parameters
const DeclSpec &DS = D.getDeclSpec(); const DeclSpec &DS = D.getDeclSpec();
assert(DS.isFriendSpecified()); assert(DS.isFriendSpecified());