blob: 82dc17068e9a04588fb4a69d2a3364858d705cca [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);
24}
25
26Parser::~Parser() {
27 delete CurScope;
28}
29
Chris Lattner0bb5f832006-07-31 01:59:18 +000030
Chris Lattnerb9093cd2006-08-04 04:39:53 +000031void Parser::Diag(SourceLocation Loc, unsigned DiagID,
Chris Lattner0bb5f832006-07-31 01:59:18 +000032 const std::string &Msg) {
Chris Lattnerb9093cd2006-08-04 04:39:53 +000033 Diags.Report(Loc, DiagID, Msg);
Chris Lattner0bb5f832006-07-31 01:59:18 +000034}
35
Chris Lattner70f32b72006-07-31 05:09:04 +000036//===----------------------------------------------------------------------===//
37// C99 6.9: External Definitions.
38//===----------------------------------------------------------------------===//
Chris Lattner0bb5f832006-07-31 01:59:18 +000039
40/// ParseTranslationUnit:
Chris Lattner70f32b72006-07-31 05:09:04 +000041/// translation-unit: [C99 6.9]
Chris Lattner0bb5f832006-07-31 01:59:18 +000042/// external-declaration
43/// translation-unit external-declaration
44void Parser::ParseTranslationUnit() {
45
46 if (Tok.getKind() == tok::eof) // Empty source file is an extension.
47 Diag(diag::ext_empty_source_file);
48
49 while (Tok.getKind() != tok::eof)
50 ParseExternalDeclaration();
51}
52
53/// ParseExternalDeclaration:
Chris Lattner70f32b72006-07-31 05:09:04 +000054/// external-declaration: [C99 6.9]
Chris Lattner0bb5f832006-07-31 01:59:18 +000055/// function-definition [TODO]
56/// declaration [TODO]
57/// [EXT] ';'
58/// [GNU] asm-definition [TODO]
59/// [GNU] __extension__ external-declaration [TODO]
60/// [OBJC] objc-class-definition [TODO]
61/// [OBJC] objc-class-declaration [TODO]
62/// [OBJC] objc-alias-declaration [TODO]
63/// [OBJC] objc-protocol-definition [TODO]
64/// [OBJC] objc-method-definition [TODO]
65/// [OBJC] @end [TODO]
66///
67void Parser::ParseExternalDeclaration() {
68 switch (Tok.getKind()) {
69 case tok::semi:
70 Diag(diag::ext_top_level_semi);
71 ConsumeToken();
72 break;
73 default:
74 // We can't tell whether this is a function-definition or declaration yet.
75 ParseDeclarationOrFunctionDefinition();
76 break;
77 }
78}
79
80/// ParseDeclarationOrFunctionDefinition - Parse either a function-definition or
Chris Lattner70f32b72006-07-31 05:09:04 +000081/// a declaration. We can't tell which we have until we read up to the
82/// compound-statement in function-definition.
Chris Lattner0bb5f832006-07-31 01:59:18 +000083///
Chris Lattner70f32b72006-07-31 05:09:04 +000084/// function-definition: [C99 6.9.1]
85/// declaration-specifiers[opt] declarator declaration-list[opt]
86/// compound-statement [TODO]
87/// declaration: [C99 6.7]
Chris Lattner0bb5f832006-07-31 01:59:18 +000088/// declaration-specifiers init-declarator-list[opt] ';' [TODO]
Chris Lattnerd9c3c592006-08-05 06:26:47 +000089/// [!C99] init-declarator-list ';' [TODO]
Chris Lattner70f32b72006-07-31 05:09:04 +000090/// [OMP] threadprivate-directive [TODO]
91///
92/// init-declarator-list: [C99 6.7]
93/// init-declarator
94/// init-declarator-list ',' init-declarator
95/// init-declarator: [C99 6.7]
96/// declarator
97/// declarator '=' initializer
98///
Chris Lattner0bb5f832006-07-31 01:59:18 +000099void Parser::ParseDeclarationOrFunctionDefinition() {
Chris Lattner70f32b72006-07-31 05:09:04 +0000100 // Parse the common declaration-specifiers piece.
Chris Lattnerb9093cd2006-08-04 04:39:53 +0000101 // NOTE: this can not be missing for C99 'declaration's.
102 DeclSpec DS;
103 ParseDeclarationSpecifiers(DS);
Chris Lattnerd2864882006-08-05 08:09:44 +0000104
105 // C99 6.7.2.3p6: Handle "struct-or-union identifier;", "enum { X };"
106 if (Tok.getKind() == tok::semi)
107 assert(0 && "Unimp!");
108
Chris Lattner70f32b72006-07-31 05:09:04 +0000109
110 // Parse the common declarator piece.
111 ParseDeclarator();
112
Chris Lattnerd2864882006-08-05 08:09:44 +0000113
Chris Lattnerd9c3c592006-08-05 06:26:47 +0000114 // If the declarator was a function type... handle it.
115
116 // must be: decl-spec[opt] declarator init-declarator-list
117 // Parse declarator '=' initializer.
118 if (Tok.getKind() == tok::equal)
119 assert(0 && "cannot handle initializer yet!");
120
Chris Lattnerd2864882006-08-05 08:09:44 +0000121 while (Tok.getKind() == tok::comma) {
Chris Lattnerd9c3c592006-08-05 06:26:47 +0000122 // Consume the comma.
123 ConsumeToken();
124
125 // Parse the common declarator piece.
126 ParseDeclarator();
127
128 // declarator '=' initializer
129 if (Tok.getKind() == tok::equal)
130 assert(0 && "cannot handle initializer yet!");
131
132
133 }
Chris Lattnerd2864882006-08-05 08:09:44 +0000134
135 if (Tok.getKind() == tok::semi) {
Chris Lattner70f32b72006-07-31 05:09:04 +0000136 ConsumeToken();
Chris Lattnerd2864882006-08-05 08:09:44 +0000137 } else {
138 Diag(Tok, diag::err_parse_error);
139 // FIXME: skip to end of block or statement
140 while (Tok.getKind() != tok::semi && Tok.getKind() != tok::eof)
141 ConsumeToken();
142 if (Tok.getKind() == tok::semi)
143 ConsumeToken();
Chris Lattner70f32b72006-07-31 05:09:04 +0000144 }
145}
146