aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/Parse/Parser.h2
-rw-r--r--lib/Parse/ParseCXXInlineMethods.cpp2
-rw-r--r--lib/Parse/ParseDeclCXX.cpp63
-rw-r--r--test/SemaCXX/default2.cpp6
4 files changed, 44 insertions, 29 deletions
diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h
index bebc874b62..dc6a577771 100644
--- a/include/clang/Parse/Parser.h
+++ b/include/clang/Parse/Parser.h
@@ -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]
diff --git a/lib/Parse/ParseCXXInlineMethods.cpp b/lib/Parse/ParseCXXInlineMethods.cpp
index 613e0e33f7..8afffe3815 100644
--- a/lib/Parse/ParseCXXInlineMethods.cpp
+++ b/lib/Parse/ParseCXXInlineMethods.cpp
@@ -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));
diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp
index b9b2979911..930d58dd26 100644
--- a/lib/Parse/ParseDeclCXX.cpp
+++ b/lib/Parse/ParseDeclCXX.cpp
@@ -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 ';')
diff --git a/test/SemaCXX/default2.cpp b/test/SemaCXX/default2.cpp
index edbd6b3e20..dc83ac489f 100644
--- a/test/SemaCXX/default2.cpp
+++ b/test/SemaCXX/default2.cpp
@@ -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(); }
+};