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();
}
/// 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();
}

View 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);

View 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),

View 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);

View 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());