зеркало из https://github.com/microsoft/clang-1.git
Step #1 to fixing PR2012: c89 allows declspecs to be completely
missing from function definitions only. If we see a function definiton with missing declspecs, just fudge in an int. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@49250 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
b10f273eb6
Коммит
a798ebc826
|
@ -49,6 +49,8 @@ struct LangOptions {
|
|||
LaxVectorConversions = 0;
|
||||
}
|
||||
|
||||
bool isC90() const { return !C99 && !CPlusPlus; }
|
||||
|
||||
/// Emit - Emit this LangOptions object to bitcode.
|
||||
void Emit(llvm::Serializer& S) const;
|
||||
|
||||
|
|
|
@ -356,8 +356,10 @@ Parser::DeclTy *Parser::ParseExternalDeclaration() {
|
|||
/// compound-statement in function-definition.
|
||||
///
|
||||
/// function-definition: [C99 6.9.1]
|
||||
/// declaration-specifiers[opt] declarator declaration-list[opt]
|
||||
/// compound-statement
|
||||
/// decl-specs declarator declaration-list[opt] compound-statement
|
||||
/// [C90] function-definition: [C99 6.7.1] - implicit int result
|
||||
/// [C90] decl-specs[opt] declarator declaration-list[opt] compound-statement
|
||||
///
|
||||
/// declaration: [C99 6.7]
|
||||
/// declaration-specifiers init-declarator-list[opt] ';'
|
||||
/// [!C99] init-declarator-list ';' [TODO: warn in c99 mode]
|
||||
|
@ -451,8 +453,10 @@ Parser::DeclTy *Parser::ParseDeclarationOrFunctionDefinition() {
|
|||
/// Declarator is well formed. If this is a K&R-style function, read the
|
||||
/// parameters declaration-list, then start the compound-statement.
|
||||
///
|
||||
/// declaration-specifiers[opt] declarator declaration-list[opt]
|
||||
/// compound-statement [TODO]
|
||||
/// function-definition: [C99 6.9.1]
|
||||
/// decl-specs declarator declaration-list[opt] compound-statement
|
||||
/// [C90] function-definition: [C99 6.7.1] - implicit int result
|
||||
/// [C90] decl-specs[opt] declarator declaration-list[opt] compound-statement
|
||||
///
|
||||
Parser::DeclTy *Parser::ParseFunctionDefinition(Declarator &D) {
|
||||
const DeclaratorChunk &FnTypeInfo = D.getTypeObject(0);
|
||||
|
@ -460,6 +464,15 @@ Parser::DeclTy *Parser::ParseFunctionDefinition(Declarator &D) {
|
|||
"This isn't a function declarator!");
|
||||
const DeclaratorChunk::FunctionTypeInfo &FTI = FnTypeInfo.Fun;
|
||||
|
||||
// If this is C90 and the declspecs were completely missing, fudge in an
|
||||
// implicit int. We do this here because this is the only place where
|
||||
// declaration-specifiers are completely optional in the grammar.
|
||||
if (getLang().isC90() && !D.getDeclSpec().getParsedSpecifiers() == 0) {
|
||||
const char *PrevSpec;
|
||||
D.getDeclSpec().SetTypeSpecType(DeclSpec::TST_int, D.getIdentifierLoc(),
|
||||
PrevSpec);
|
||||
}
|
||||
|
||||
// If this declaration was formed with a K&R-style identifier list for the
|
||||
// arguments, parse declarations for all of the args next.
|
||||
// int foo(a,b) int a; float b; {}
|
||||
|
|
|
@ -33,3 +33,9 @@ void test5(register);
|
|||
/* PR2041 */
|
||||
int *restrict;
|
||||
int *__restrict; /* expected-error {{expected identifier}} */
|
||||
|
||||
|
||||
/* Implicit int, always ok */
|
||||
foo() {}
|
||||
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче