зеркало из https://github.com/microsoft/clang-1.git
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:
Родитель
bd04878257
Коммит
d33133cdc1
|
@ -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(); }
|
||||
};
|
||||
|
|
Загрузка…
Ссылка в новой задаче