Fix the parsing of default arguments for inline member function

definitions.

I'm not very familiar with this code, so please review.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@76796 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Eli Friedman 2009-07-22 21:45:50 +00:00
Родитель bd04878257
Коммит d33133cdc1
4 изменённых файлов: 44 добавлений и 29 удалений

Просмотреть файл

@ -1147,6 +1147,8 @@ private:
void ParseCXXClassMemberDeclaration(AccessSpecifier AS);
void ParseConstructorInitializer(DeclPtrTy ConstructorDecl);
MemInitResult ParseMemInitializer(DeclPtrTy ConstructorDecl);
void HandleMemberFunctionDefaultArgs(Declarator& DeclaratorInfo,
DeclPtrTy ThisDecl);
//===--------------------------------------------------------------------===//
// C++ 10: Derived classes [class.derived]

Просмотреть файл

@ -29,6 +29,8 @@ Parser::ParseCXXInlineMethodDef(AccessSpecifier AS, Declarator &D) {
DeclPtrTy FnD = Actions.ActOnCXXMemberDeclarator(CurScope, AS, D, 0, 0);
HandleMemberFunctionDefaultArgs(D, FnD);
// Consume the tokens and store them for later parsing.
getCurrentClass().MethodDefs.push_back(LexedMethod(FnD));

Просмотреть файл

@ -852,6 +852,39 @@ AccessSpecifier Parser::getAccessSpecifierIfPresent() const
}
}
void Parser::HandleMemberFunctionDefaultArgs(Declarator& DeclaratorInfo,
DeclPtrTy ThisDecl) {
// We just declared a member function. If this member function
// has any default arguments, we'll need to parse them later.
LateParsedMethodDeclaration *LateMethod = 0;
DeclaratorChunk::FunctionTypeInfo &FTI
= DeclaratorInfo.getTypeObject(0).Fun;
for (unsigned ParamIdx = 0; ParamIdx < FTI.NumArgs; ++ParamIdx) {
if (LateMethod || FTI.ArgInfo[ParamIdx].DefaultArgTokens) {
if (!LateMethod) {
// Push this method onto the stack of late-parsed method
// declarations.
getCurrentClass().MethodDecls.push_back(
LateParsedMethodDeclaration(ThisDecl));
LateMethod = &getCurrentClass().MethodDecls.back();
// Add all of the parameters prior to this one (they don't
// have default arguments).
LateMethod->DefaultArgs.reserve(FTI.NumArgs);
for (unsigned I = 0; I < ParamIdx; ++I)
LateMethod->DefaultArgs.push_back(
LateParsedDefaultArgument(FTI.ArgInfo[ParamIdx].Param));
}
// Add this parameter to the list of parameters (it or may
// not have a default argument).
LateMethod->DefaultArgs.push_back(
LateParsedDefaultArgument(FTI.ArgInfo[ParamIdx].Param,
FTI.ArgInfo[ParamIdx].DefaultArgTokens));
}
}
}
/// ParseCXXClassMemberDeclaration - Parse a C++ class member declaration.
///
/// member-declaration:
@ -1047,35 +1080,7 @@ void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS) {
if (DeclaratorInfo.isFunctionDeclarator() &&
DeclaratorInfo.getDeclSpec().getStorageClassSpec()
!= DeclSpec::SCS_typedef) {
// We just declared a member function. If this member function
// has any default arguments, we'll need to parse them later.
LateParsedMethodDeclaration *LateMethod = 0;
DeclaratorChunk::FunctionTypeInfo &FTI
= DeclaratorInfo.getTypeObject(0).Fun;
for (unsigned ParamIdx = 0; ParamIdx < FTI.NumArgs; ++ParamIdx) {
if (LateMethod || FTI.ArgInfo[ParamIdx].DefaultArgTokens) {
if (!LateMethod) {
// Push this method onto the stack of late-parsed method
// declarations.
getCurrentClass().MethodDecls.push_back(
LateParsedMethodDeclaration(ThisDecl));
LateMethod = &getCurrentClass().MethodDecls.back();
// Add all of the parameters prior to this one (they don't
// have default arguments).
LateMethod->DefaultArgs.reserve(FTI.NumArgs);
for (unsigned I = 0; I < ParamIdx; ++I)
LateMethod->DefaultArgs.push_back(
LateParsedDefaultArgument(FTI.ArgInfo[ParamIdx].Param));
}
// Add this parameter to the list of parameters (it or may
// not have a default argument).
LateMethod->DefaultArgs.push_back(
LateParsedDefaultArgument(FTI.ArgInfo[ParamIdx].Param,
FTI.ArgInfo[ParamIdx].DefaultArgTokens));
}
}
HandleMemberFunctionDefaultArgs(DeclaratorInfo, ThisDecl);
}
// If we don't have a comma, it is either the end of the list (a ';')

Просмотреть файл

@ -127,3 +127,9 @@ class C2 {
static void g(int = f()); // expected-error{{use of default argument to function 'f' that is declared later in class 'C2'}}
static int f(int = 10); // expected-note{{default argument declared here}}
};
// Make sure we actually parse the default argument for an inline definition
class XX {
void A(int length = -1 ) { }
void B() { A(); }
};