blob: f3c84f47c305cd6f4b050a2836206d8240cc2917 [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 Lattner70f32b72006-07-31 05:09:04 +000095
96 // Parse the common declarator piece.
97 ParseDeclarator();
98
Chris Lattnerd9c3c592006-08-05 06:26:47 +000099 // If the declarator was a function type... handle it.
100
101 // must be: decl-spec[opt] declarator init-declarator-list
102 // Parse declarator '=' initializer.
103 if (Tok.getKind() == tok::equal)
104 assert(0 && "cannot handle initializer yet!");
105
106 while (Tok.getKind() != tok::semi) {
107 if (Tok.getKind() != tok::comma && Tok.getKind() != tok::semi) {
108 // FIXME: skip toe nd of block or statement
109 Diag(Tok, diag::err_parse_error);
110 ConsumeToken();
111 }
112
113 // 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 Lattner70f32b72006-07-31 05:09:04 +0000125 switch (Tok.getKind()) {
Chris Lattner70f32b72006-07-31 05:09:04 +0000126 case tok::comma: // must be: decl-spec[opt] declarator init-declarator-list
127 default:
128 assert(0 && "unimp!");
129 case tok::semi:
130 ConsumeToken();
131 break;
132 }
133}
134