blob: f57ecb579cd30d4f2e311060b932de6080da887c [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 Lattner0bb5f832006-07-31 01:59:18 +000016using namespace llvm;
17using namespace clang;
18
19Parser::Parser(Preprocessor &pp, ParserActions &actions)
20 : PP(pp), Actions(actions), Diags(PP.getDiagnostics()) {}
21
Chris Lattnerb9093cd2006-08-04 04:39:53 +000022void Parser::Diag(SourceLocation Loc, unsigned DiagID,
Chris Lattner0bb5f832006-07-31 01:59:18 +000023 const std::string &Msg) {
Chris Lattnerb9093cd2006-08-04 04:39:53 +000024 Diags.Report(Loc, DiagID, Msg);
Chris Lattner0bb5f832006-07-31 01:59:18 +000025}
26
Chris Lattner70f32b72006-07-31 05:09:04 +000027//===----------------------------------------------------------------------===//
28// C99 6.9: External Definitions.
29//===----------------------------------------------------------------------===//
Chris Lattner0bb5f832006-07-31 01:59:18 +000030
31/// ParseTranslationUnit:
Chris Lattner70f32b72006-07-31 05:09:04 +000032/// translation-unit: [C99 6.9]
Chris Lattner0bb5f832006-07-31 01:59:18 +000033/// external-declaration
34/// translation-unit external-declaration
35void Parser::ParseTranslationUnit() {
36
37 if (Tok.getKind() == tok::eof) // Empty source file is an extension.
38 Diag(diag::ext_empty_source_file);
39
40 while (Tok.getKind() != tok::eof)
41 ParseExternalDeclaration();
42}
43
44/// ParseExternalDeclaration:
Chris Lattner70f32b72006-07-31 05:09:04 +000045/// external-declaration: [C99 6.9]
Chris Lattner0bb5f832006-07-31 01:59:18 +000046/// function-definition [TODO]
47/// declaration [TODO]
48/// [EXT] ';'
49/// [GNU] asm-definition [TODO]
50/// [GNU] __extension__ external-declaration [TODO]
51/// [OBJC] objc-class-definition [TODO]
52/// [OBJC] objc-class-declaration [TODO]
53/// [OBJC] objc-alias-declaration [TODO]
54/// [OBJC] objc-protocol-definition [TODO]
55/// [OBJC] objc-method-definition [TODO]
56/// [OBJC] @end [TODO]
57///
58void Parser::ParseExternalDeclaration() {
59 switch (Tok.getKind()) {
60 case tok::semi:
61 Diag(diag::ext_top_level_semi);
62 ConsumeToken();
63 break;
64 default:
65 // We can't tell whether this is a function-definition or declaration yet.
66 ParseDeclarationOrFunctionDefinition();
67 break;
68 }
69}
70
71/// ParseDeclarationOrFunctionDefinition - Parse either a function-definition or
Chris Lattner70f32b72006-07-31 05:09:04 +000072/// a declaration. We can't tell which we have until we read up to the
73/// compound-statement in function-definition.
Chris Lattner0bb5f832006-07-31 01:59:18 +000074///
Chris Lattner70f32b72006-07-31 05:09:04 +000075/// function-definition: [C99 6.9.1]
76/// declaration-specifiers[opt] declarator declaration-list[opt]
77/// compound-statement [TODO]
78/// declaration: [C99 6.7]
Chris Lattner0bb5f832006-07-31 01:59:18 +000079/// declaration-specifiers init-declarator-list[opt] ';' [TODO]
Chris Lattnerd9c3c592006-08-05 06:26:47 +000080/// [!C99] init-declarator-list ';' [TODO]
Chris Lattner70f32b72006-07-31 05:09:04 +000081/// [OMP] threadprivate-directive [TODO]
82///
83/// init-declarator-list: [C99 6.7]
84/// init-declarator
85/// init-declarator-list ',' init-declarator
86/// init-declarator: [C99 6.7]
87/// declarator
88/// declarator '=' initializer
89///
Chris Lattner0bb5f832006-07-31 01:59:18 +000090void Parser::ParseDeclarationOrFunctionDefinition() {
Chris Lattner70f32b72006-07-31 05:09:04 +000091 // Parse the common declaration-specifiers piece.
Chris Lattnerb9093cd2006-08-04 04:39:53 +000092 // NOTE: this can not be missing for C99 'declaration's.
93 DeclSpec DS;
94 ParseDeclarationSpecifiers(DS);
Chris Lattnerd2864882006-08-05 08:09:44 +000095
96 // C99 6.7.2.3p6: Handle "struct-or-union identifier;", "enum { X };"
97 if (Tok.getKind() == tok::semi)
98 assert(0 && "Unimp!");
99
Chris Lattner70f32b72006-07-31 05:09:04 +0000100
101 // Parse the common declarator piece.
102 ParseDeclarator();
103
Chris Lattnerd2864882006-08-05 08:09:44 +0000104
Chris Lattnerd9c3c592006-08-05 06:26:47 +0000105 // If the declarator was a function type... handle it.
106
107 // must be: decl-spec[opt] declarator init-declarator-list
108 // Parse declarator '=' initializer.
109 if (Tok.getKind() == tok::equal)
110 assert(0 && "cannot handle initializer yet!");
111
Chris Lattnerd2864882006-08-05 08:09:44 +0000112 while (Tok.getKind() == tok::comma) {
Chris Lattnerd9c3c592006-08-05 06:26:47 +0000113 // Consume the comma.
114 ConsumeToken();
115
116 // Parse the common declarator piece.
117 ParseDeclarator();
118
119 // declarator '=' initializer
120 if (Tok.getKind() == tok::equal)
121 assert(0 && "cannot handle initializer yet!");
122
123
124 }
Chris Lattnerd2864882006-08-05 08:09:44 +0000125
126 if (Tok.getKind() == tok::semi) {
Chris Lattner70f32b72006-07-31 05:09:04 +0000127 ConsumeToken();
Chris Lattnerd2864882006-08-05 08:09:44 +0000128 } else {
129 Diag(Tok, diag::err_parse_error);
130 // FIXME: skip to end of block or statement
131 while (Tok.getKind() != tok::semi && Tok.getKind() != tok::eof)
132 ConsumeToken();
133 if (Tok.getKind() == tok::semi)
134 ConsumeToken();
Chris Lattner70f32b72006-07-31 05:09:04 +0000135 }
136}
137