[cfe-commits] r38841 - in /cfe/cfe/trunk: Parse/ParseDecl.cpp Parse/Parser.cpp include/clang/Basic/DiagnosticKinds.def include/clang/Parse/DeclSpec.h
sabre at cs.uiuc.edu
sabre at cs.uiuc.edu
Wed Jul 11 09:25:05 PDT 2007
Author: sabre
Date: Wed Jul 11 11:25:05 2007
New Revision: 38841
URL: http://llvm.org/viewvc/llvm-project?rev=38841&view=rev
Log:
Simplify and fill out parsing of function bodies.
Modified:
cfe/cfe/trunk/Parse/ParseDecl.cpp
cfe/cfe/trunk/Parse/Parser.cpp
cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def
cfe/cfe/trunk/include/clang/Parse/DeclSpec.h
Modified: cfe/cfe/trunk/Parse/ParseDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Parse/ParseDecl.cpp?rev=38841&r1=38840&r2=38841&view=diff
==============================================================================
--- cfe/cfe/trunk/Parse/ParseDecl.cpp (original)
+++ cfe/cfe/trunk/Parse/ParseDecl.cpp Wed Jul 11 11:25:05 2007
@@ -455,12 +455,14 @@
// NOTE: better to only create a scope if not '()'
bool IsVariadic;
bool HasPrototype;
+ bool IsEmpty = false;
bool ErrorEmitted = false;
if (Tok.getKind() == tok::r_paren) {
// int() -> no prototype, no '...'.
IsVariadic = false;
HasPrototype = false;
+ IsEmpty = true;
} else if (Tok.getKind() == tok::identifier &&
0/*TODO: !isatypedefname(Tok.getIdentifierInfo())*/) {
// Identifier list. Note that '(' identifier-list ')' is only allowed for
@@ -545,7 +547,7 @@
// Remember that we parsed a function type, and remember the attributes.
D.AddTypeInfo(DeclaratorTypeInfo::getFunction(HasPrototype, IsVariadic,
- StartLoc));
+ IsEmpty, StartLoc));
// If we have the closing ')', eat it and we're done.
Modified: cfe/cfe/trunk/Parse/Parser.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Parse/Parser.cpp?rev=38841&r1=38840&r2=38841&view=diff
==============================================================================
--- cfe/cfe/trunk/Parse/Parser.cpp (original)
+++ cfe/cfe/trunk/Parse/Parser.cpp Wed Jul 11 11:25:05 2007
@@ -187,7 +187,6 @@
///
void Parser::ParseDeclarationOrFunctionDefinition() {
// Parse the common declaration-specifiers piece.
- // NOTE: this can not be missing for C99 'declaration's.
DeclSpec DS;
ParseDeclarationSpecifiers(DS);
@@ -196,41 +195,63 @@
assert(0 && "Unimp!");
- // Parse the declarator.
- {
- Declarator DeclaratorInfo(DS, Declarator::FileContext);
- ParseDeclarator(DeclaratorInfo);
+ // Parse the first declarator.
+ Declarator DeclaratorInfo(DS, Declarator::FileContext);
+ ParseDeclarator(DeclaratorInfo);
+ // Error parsing the declarator?
+ if (DeclaratorInfo.getIdentifier() == 0) {
+ // If so, skip until the semi-colon or a }.
+ SkipUntil(tok::r_brace, true);
+ if (Tok.getKind() == tok::semi)
+ ConsumeToken();
+ return;
+ }
- // If the declarator was the start of a function definition, handle it.
- if (Tok.getKind() != tok::equal && // int X()= -> not a function def
- Tok.getKind() != tok::comma && // int X(), -> not a function def
- Tok.getKind() != tok::semi && // int X(); -> not a function def
- DS.StorageClassSpec != DeclSpec::SCS_typedef && // typedef int X()
- DeclaratorInfo.isInnermostFunctionType()) { // int *X -> not a fn def.
- assert(0 && "unimp");
-
-
- }
+ // If the declarator is the start of a function definition, handle it.
+ if (Tok.getKind() == tok::equal || // int X()= -> not a function def
+ Tok.getKind() == tok::comma || // int X(), -> not a function def
+ Tok.getKind() == tok::semi || // int X(); -> not a function def
+ Tok.getKind() == tok::kw_asm || // int X() __asm__ -> not a fn def
+ Tok.getKind() == tok::kw___attribute) {// int X() __attr__ -> not a fn def
+ // FALL THROUGH.
+ } else if (DeclaratorInfo.isInnermostFunctionType() &&
+ (Tok.getKind() == tok::l_brace || // int X() {}
+ isDeclarationSpecifier())) { // int X(f) int f; {}
+ ParseFunctionDefinition(DeclaratorInfo);
+ return;
+ } else {
+ if (DeclaratorInfo.isInnermostFunctionType())
+ Diag(Tok, diag::err_expected_fn_body);
+ else
+ Diag(Tok, diag::err_expected_after_declarator);
+ SkipUntil(tok::r_brace, true);
+ if (Tok.getKind() == tok::semi)
+ ConsumeToken();
+ return;
+ }
+ // At this point, we know that it is not a function definition. Parse the
+ // rest of the init-declarator-list.
+ while (1) {
// must be: decl-spec[opt] declarator init-declarator-list
// Parse declarator '=' initializer.
if (Tok.getKind() == tok::equal)
assert(0 && "cannot handle initializer yet!");
- }
- while (Tok.getKind() == tok::comma) {
+
+ // TODO: install declarator.
+
+ // If we don't have a comma, it is either the end of the list (a ';') or an
+ // error, bail out.
+ if (Tok.getKind() != tok::comma)
+ break;
+
// Consume the comma.
ConsumeToken();
- // Parse the declarator.
- Declarator DeclaratorInfo(DS, Declarator::FileContext);
+ // Parse the next declarator.
+ DeclaratorInfo.clear();
ParseDeclarator(DeclaratorInfo);
-
- // declarator '=' initializer
- if (Tok.getKind() == tok::equal)
- assert(0 && "cannot handle initializer yet!");
-
-
}
if (Tok.getKind() == tok::semi) {
@@ -244,3 +265,60 @@
}
}
+/// ParseFunctionDefinition - We parsed and verified that the specified
+/// 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]
+///
+void Parser::ParseFunctionDefinition(Declarator &D) {
+ const DeclaratorTypeInfo &FnTypeInfo = D.getTypeObject(0);
+ assert(FnTypeInfo.Kind == DeclaratorTypeInfo::Function &&
+ "This isn't a function declarator!");
+
+ // 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; {}
+ if (!FnTypeInfo.Fun.hasPrototype && !FnTypeInfo.Fun.isEmpty) {
+ // Read all the argument declarations.
+ while (isDeclarationSpecifier()) {
+ // Parse the common declaration-specifiers piece.
+ DeclSpec DS;
+ ParseDeclarationSpecifiers(DS);
+
+ Declarator DeclaratorInfo(DS, Declarator::FileContext);
+ ParseDeclarator(DeclaratorInfo);
+
+ while (Tok.getKind() == tok::comma) {
+ // Consume the comma.
+ ConsumeToken();
+
+ // Parse the next declarator.
+ DeclaratorInfo.clear();
+ ParseDeclarator(DeclaratorInfo);
+ }
+
+ if (Tok.getKind() == tok::semi) {
+ ConsumeToken();
+ } else {
+ Diag(Tok, diag::err_expected_semi_knr_fn_body);
+ // Skip to end of block or statement
+ SkipUntil(tok::l_brace, true);
+ if (Tok.getKind() == tok::semi)
+ ConsumeToken();
+ }
+ }
+
+ // Note, check that we got them all.
+ } else {
+ //if (isDeclarationSpecifier())
+ // Diag('k&r declspecs with prototype?');
+
+ // FIXME: Install the arguments into the current scope.
+ }
+
+
+
+}
+
Modified: cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def?rev=38841&r1=38840&r2=38841&view=diff
==============================================================================
--- cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def Wed Jul 11 11:25:05 2007
@@ -264,6 +264,12 @@
"expected identifier or '('")
DIAG(err_expected_rparen, ERROR,
"expected ')'")
+DIAG(err_expected_semi_knr_fn_body, ERROR,
+ "expected ';' at end of K&R-style function argument declaration list")
+DIAG(err_expected_fn_body, ERROR,
+ "expected function body after function declarator")
+DIAG(err_expected_after_declarator, ERROR,
+ "expected '=', ',', ';', 'asm', or '__attribute__' after declarator")
/// err_matching - this is used as a continuation of a previous error, e.g. to
/// specify the '(' when we expected a ')'. This should probably be some
Modified: cfe/cfe/trunk/include/clang/Parse/DeclSpec.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/Parse/DeclSpec.h?rev=38841&r1=38840&r2=38841&view=diff
==============================================================================
--- cfe/cfe/trunk/include/clang/Parse/DeclSpec.h (original)
+++ cfe/cfe/trunk/include/clang/Parse/DeclSpec.h Wed Jul 11 11:25:05 2007
@@ -172,6 +172,7 @@
/// with ',...)', this is true.
bool isVariadic : 1;
// TODO: capture argument info.
+ bool isEmpty : 1;
};
union {
@@ -209,12 +210,14 @@
/// getFunction - Return a DeclaratorTypeInfo for a function.
///
static DeclaratorTypeInfo getFunction(bool hasProto, bool isVariadic,
+ bool isEmpty /*fixme arg info*/,
SourceLocation Loc) {
DeclaratorTypeInfo I;
I.Kind = Function;
I.Loc = Loc;
I.Fun.hasPrototype = hasProto;
I.Fun.isVariadic = isVariadic;
+ I.Fun.isEmpty = isEmpty;
return I;
}
};
More information about the cfe-commits
mailing list