blob: 8e73ee005fd89c7b2d8d51ef7a302753e04deeca [file] [log] [blame]
Chris Lattnerb9093cd2006-08-04 04:39:53 +00001//===--- Parse.cpp - C Language Family Parser -----------------------------===//
Chris Lattner0bb5f832006-07-31 01:59:18 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file was developed by Chris Lattner and is distributed under
6// the University of Illinois Open Source License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the Parser interfaces.
11//
12//===----------------------------------------------------------------------===//
13
14#include "clang/Parse/Parser.h"
Chris Lattnerb9093cd2006-08-04 04:39:53 +000015#include "clang/Parse/Declarations.h"
Chris Lattner971c6b62006-08-05 22:46:42 +000016#include "clang/Parse/Scope.h"
Chris Lattner0bb5f832006-07-31 01:59:18 +000017using namespace llvm;
18using namespace clang;
19
20Parser::Parser(Preprocessor &pp, ParserActions &actions)
Chris Lattner971c6b62006-08-05 22:46:42 +000021 : PP(pp), Actions(actions), Diags(PP.getDiagnostics()) {
22 // Create the global scope, install it as the current scope.
23 CurScope = new Scope(0);
Chris Lattneracd58a32006-08-06 17:24:14 +000024 Tok.SetKind(tok::eof);
Chris Lattner971c6b62006-08-05 22:46:42 +000025}
26
27Parser::~Parser() {
28 delete CurScope;
29}
30
Chris Lattner0bb5f832006-07-31 01:59:18 +000031
Chris Lattnerb9093cd2006-08-04 04:39:53 +000032void Parser::Diag(SourceLocation Loc, unsigned DiagID,
Chris Lattner0bb5f832006-07-31 01:59:18 +000033 const std::string &Msg) {
Chris Lattnerb9093cd2006-08-04 04:39:53 +000034 Diags.Report(Loc, DiagID, Msg);
Chris Lattner0bb5f832006-07-31 01:59:18 +000035}
36
Chris Lattner70f32b72006-07-31 05:09:04 +000037//===----------------------------------------------------------------------===//
38// C99 6.9: External Definitions.
39//===----------------------------------------------------------------------===//
Chris Lattner0bb5f832006-07-31 01:59:18 +000040
41/// ParseTranslationUnit:
Chris Lattner70f32b72006-07-31 05:09:04 +000042/// translation-unit: [C99 6.9]
Chris Lattner0bb5f832006-07-31 01:59:18 +000043/// external-declaration
44/// translation-unit external-declaration
45void Parser::ParseTranslationUnit() {
46
47 if (Tok.getKind() == tok::eof) // Empty source file is an extension.
48 Diag(diag::ext_empty_source_file);
49
50 while (Tok.getKind() != tok::eof)
51 ParseExternalDeclaration();
52}
53
54/// ParseExternalDeclaration:
Chris Lattner70f32b72006-07-31 05:09:04 +000055/// external-declaration: [C99 6.9]
Chris Lattner0bb5f832006-07-31 01:59:18 +000056/// function-definition [TODO]
57/// declaration [TODO]
58/// [EXT] ';'
59/// [GNU] asm-definition [TODO]
60/// [GNU] __extension__ external-declaration [TODO]
61/// [OBJC] objc-class-definition [TODO]
62/// [OBJC] objc-class-declaration [TODO]
63/// [OBJC] objc-alias-declaration [TODO]
64/// [OBJC] objc-protocol-definition [TODO]
65/// [OBJC] objc-method-definition [TODO]
66/// [OBJC] @end [TODO]
67///
68void Parser::ParseExternalDeclaration() {
69 switch (Tok.getKind()) {
70 case tok::semi:
71 Diag(diag::ext_top_level_semi);
72 ConsumeToken();
73 break;
74 default:
75 // We can't tell whether this is a function-definition or declaration yet.
76 ParseDeclarationOrFunctionDefinition();
77 break;
78 }
79}
80
81/// ParseDeclarationOrFunctionDefinition - Parse either a function-definition or
Chris Lattner70f32b72006-07-31 05:09:04 +000082/// a declaration. We can't tell which we have until we read up to the
83/// compound-statement in function-definition.
Chris Lattner0bb5f832006-07-31 01:59:18 +000084///
Chris Lattner70f32b72006-07-31 05:09:04 +000085/// function-definition: [C99 6.9.1]
86/// declaration-specifiers[opt] declarator declaration-list[opt]
87/// compound-statement [TODO]
88/// declaration: [C99 6.7]
Chris Lattner0bb5f832006-07-31 01:59:18 +000089/// declaration-specifiers init-declarator-list[opt] ';' [TODO]
Chris Lattnerd9c3c592006-08-05 06:26:47 +000090/// [!C99] init-declarator-list ';' [TODO]
Chris Lattner70f32b72006-07-31 05:09:04 +000091/// [OMP] threadprivate-directive [TODO]
92///
93/// init-declarator-list: [C99 6.7]
94/// init-declarator
95/// init-declarator-list ',' init-declarator
96/// init-declarator: [C99 6.7]
97/// declarator
98/// declarator '=' initializer
99///
Chris Lattner0bb5f832006-07-31 01:59:18 +0000100void Parser::ParseDeclarationOrFunctionDefinition() {
Chris Lattner70f32b72006-07-31 05:09:04 +0000101 // Parse the common declaration-specifiers piece.
Chris Lattnerb9093cd2006-08-04 04:39:53 +0000102 // NOTE: this can not be missing for C99 'declaration's.
103 DeclSpec DS;
104 ParseDeclarationSpecifiers(DS);
Chris Lattnerd2864882006-08-05 08:09:44 +0000105
106 // C99 6.7.2.3p6: Handle "struct-or-union identifier;", "enum { X };"
107 if (Tok.getKind() == tok::semi)
108 assert(0 && "Unimp!");
109
Chris Lattner70f32b72006-07-31 05:09:04 +0000110
Chris Lattner15356a72006-08-06 00:02:28 +0000111 // Parse the declarator.
112 {
Chris Lattneracd58a32006-08-06 17:24:14 +0000113 Declarator DeclaratorInfo(DS, Declarator::FileContext);
Chris Lattner15356a72006-08-06 00:02:28 +0000114 ParseDeclarator(DeclaratorInfo);
Chris Lattner70f32b72006-07-31 05:09:04 +0000115
Chris Lattner15356a72006-08-06 00:02:28 +0000116 // If the declarator was a function type... handle it.
Chris Lattnerd9c3c592006-08-05 06:26:47 +0000117
Chris Lattner15356a72006-08-06 00:02:28 +0000118 // must be: decl-spec[opt] declarator init-declarator-list
119 // Parse declarator '=' initializer.
120 if (Tok.getKind() == tok::equal)
121 assert(0 && "cannot handle initializer yet!");
122 }
Chris Lattnerd9c3c592006-08-05 06:26:47 +0000123
Chris Lattnerd2864882006-08-05 08:09:44 +0000124 while (Tok.getKind() == tok::comma) {
Chris Lattnerd9c3c592006-08-05 06:26:47 +0000125 // Consume the comma.
126 ConsumeToken();
127
Chris Lattner15356a72006-08-06 00:02:28 +0000128 // Parse the declarator.
Chris Lattneracd58a32006-08-06 17:24:14 +0000129 Declarator DeclaratorInfo(DS, Declarator::FileContext);
Chris Lattner15356a72006-08-06 00:02:28 +0000130 ParseDeclarator(DeclaratorInfo);
Chris Lattnerd9c3c592006-08-05 06:26:47 +0000131
132 // declarator '=' initializer
133 if (Tok.getKind() == tok::equal)
134 assert(0 && "cannot handle initializer yet!");
135
136
137 }
Chris Lattnerd2864882006-08-05 08:09:44 +0000138
139 if (Tok.getKind() == tok::semi) {
Chris Lattner70f32b72006-07-31 05:09:04 +0000140 ConsumeToken();
Chris Lattnerd2864882006-08-05 08:09:44 +0000141 } else {
142 Diag(Tok, diag::err_parse_error);
143 // FIXME: skip to end of block or statement
144 while (Tok.getKind() != tok::semi && Tok.getKind() != tok::eof)
145 ConsumeToken();
146 if (Tok.getKind() == tok::semi)
147 ConsumeToken();
Chris Lattner70f32b72006-07-31 05:09:04 +0000148 }
149}
150