Revert most of r145372 for now. Lookahead beyond the ';' in a function

declaration tickles a bug in the way we handle visibility pragmas.

The improvement to error recovery for template function definitions declared
with the 'typedef' specifier in r145372 is unrelated and not reverted here.

llvm-svn: 145541
This commit is contained in:
Richard Smith 2011-11-30 23:45:35 +00:00
parent ef42154c17
commit b3041feaf7
6 changed files with 1 additions and 73 deletions

View File

@ -138,8 +138,6 @@ def ext_expected_semi_decl_list : ExtWarn<
"expected ';' at end of declaration list">; "expected ';' at end of declaration list">;
def err_expected_member_name_or_semi : Error< def err_expected_member_name_or_semi : Error<
"expected member name or ';' after declaration specifiers">; "expected member name or ';' after declaration specifiers">;
def err_stray_semi_function_definition : Error<
"stray ';' in function definition">;
def err_function_declared_typedef : Error< def err_function_declared_typedef : Error<
"function definition declared 'typedef'">; "function definition declared 'typedef'">;
def err_iboutletcollection_builtintype : Error< def err_iboutletcollection_builtintype : Error<

View File

@ -1041,28 +1041,13 @@ Parser::DeclGroupPtrTy Parser::ParseDeclGroup(ParsingDeclSpec &DS,
return DeclGroupPtrTy(); return DeclGroupPtrTy();
} }
// Do we have a stray semicolon in the middle of a function definition?
if (AllowFunctionDefinitions && D.isFunctionDeclarator() &&
Tok.is(tok::semi) && Context == Declarator::FileContext) {
const Token &Next = NextToken();
if (Next.is(tok::l_brace) || Next.is(tok::kw_try) ||
(getLang().CPlusPlus &&
(Next.is(tok::colon) || Next.is(tok::equal)))) {
// Pretend we didn't see the semicolon.
SourceLocation SemiLoc = ConsumeToken();
Diag(SemiLoc, diag::err_stray_semi_function_definition)
<< FixItHint::CreateRemoval(SemiLoc);
assert(isStartOfFunctionDefinition(D) && "expected a function defn");
}
}
// Check to see if we have a function *definition* which must have a body. // Check to see if we have a function *definition* which must have a body.
if (AllowFunctionDefinitions && D.isFunctionDeclarator() && if (AllowFunctionDefinitions && D.isFunctionDeclarator() &&
// Look at the next token to make sure that this isn't a function // Look at the next token to make sure that this isn't a function
// declaration. We have to check this because __attribute__ might be the // declaration. We have to check this because __attribute__ might be the
// start of a function definition in GCC-extended K&R C. // start of a function definition in GCC-extended K&R C.
!isDeclarationAfterDeclarator()) { !isDeclarationAfterDeclarator()) {
if (isStartOfFunctionDefinition(D)) { if (isStartOfFunctionDefinition(D)) {
if (DS.getStorageClassSpec() == DeclSpec::SCS_typedef) { if (DS.getStorageClassSpec() == DeclSpec::SCS_typedef) {
Diag(Tok, diag::err_function_declared_typedef); Diag(Tok, diag::err_function_declared_typedef);

View File

@ -240,20 +240,6 @@ Parser::ParseSingleDeclarationAfterTemplate(
return 0; return 0;
} }
// Check for a stray semicolon in a function definition.
if (DeclaratorInfo.isFunctionDeclarator() && Tok.is(tok::semi) &&
Context == Declarator::FileContext) {
const Token &Next = NextToken();
if (Next.is(tok::l_brace) || Next.is(tok::kw_try) ||
Next.is(tok::equal) || Next.is(tok::colon)) {
SourceLocation SemiLoc = ConsumeToken();
Diag(SemiLoc, diag::err_stray_semi_function_definition)
<< FixItHint::CreateRemoval(SemiLoc);
assert(!isDeclarationAfterDeclarator() &&
isStartOfFunctionDefinition(DeclaratorInfo));
}
}
// If we have a declaration or declarator list, handle it. // If we have a declaration or declarator list, handle it.
if (isDeclarationAfterDeclarator()) { if (isDeclarationAfterDeclarator()) {
// Parse this declaration. // Parse this declaration.

View File

@ -58,26 +58,3 @@ namespace SemiCommaTypo {
n [[]], // expected-error {{expected ';' at end of declaration}} n [[]], // expected-error {{expected ';' at end of declaration}}
int o; int o;
} }
int extraSemi(); // expected-error {{stray ';' in function definition}}
= delete;
class ExtraSemi {
public:
ExtraSemi();
ExtraSemi(const ExtraSemi &);
int n;
};
ExtraSemi::ExtraSemi(); // expected-error {{stray ';'}}
: n(0) {
}
ExtraSemi::ExtraSemi(const ExtraSemi &); // expected-error {{stray ';'}}
= default;
template<typename T> T extraSemi(T t);
template<typename T> T extraSemi(T t); // expected-error {{stray ';'}}
{
return t;
}
template int extraSemi(int);

View File

@ -77,11 +77,3 @@ void oopsMoreCommas() {
static int b[] = { 3, 4, 5 }, static int b[] = { 3, 4, 5 },
&a == &b ? oopsMoreCommas() : removeUnusedLabels(a[0]); &a == &b ? oopsMoreCommas() : removeUnusedLabels(a[0]);
} }
void extraSemicolon();
{
void extraSemicolon();
{
return;
}
}

View File

@ -126,16 +126,6 @@ AD oopsMoreCommas() {
return ad; return ad;
} }
int extraSemi1(); // expected-error {{stray ';' in function definition}}
{
return 0;
}
int extraSemi2(); // expected-error {{stray ';' in function definition}}
try {
} catch (...) {
}
template<class T> struct Mystery; template<class T> struct Mystery;
template<class T> typedef Mystery<T>::type getMysteriousThing() { // \ template<class T> typedef Mystery<T>::type getMysteriousThing() { // \
expected-error {{function definition declared 'typedef'}} \ expected-error {{function definition declared 'typedef'}} \