blob: 46dcb5748191552bab99cc824f3cc1952649cf04 [file] [log] [blame]
Chris Lattnerf7b2e552007-08-25 06:57:03 +00001//===--- ParseDeclCXX.cpp - C++ Declaration Parsing -----------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
Chris Lattner959e5be2007-12-29 19:59:25 +00005// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
Chris Lattnerf7b2e552007-08-25 06:57:03 +00007//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the C++ Declaration portions of the Parser interfaces.
11//
12//===----------------------------------------------------------------------===//
13
14#include "clang/Parse/Parser.h"
15#include "clang/Parse/Scope.h"
16#include "clang/Basic/Diagnostic.h"
17using namespace clang;
18
19/// ParseNamespace - We know that the current token is a namespace keyword. This
20/// may either be a top level namespace or a block-level namespace alias.
21///
22/// namespace-definition: [C++ 7.3: basic.namespace]
23/// named-namespace-definition
24/// unnamed-namespace-definition
25///
26/// unnamed-namespace-definition:
27/// 'namespace' attributes[opt] '{' namespace-body '}'
28///
29/// named-namespace-definition:
30/// original-namespace-definition
31/// extension-namespace-definition
32///
33/// original-namespace-definition:
34/// 'namespace' identifier attributes[opt] '{' namespace-body '}'
35///
36/// extension-namespace-definition:
37/// 'namespace' original-namespace-name '{' namespace-body '}'
38///
39/// namespace-alias-definition: [C++ 7.3.2: namespace.alias]
40/// 'namespace' identifier '=' qualified-namespace-specifier ';'
41///
42Parser::DeclTy *Parser::ParseNamespace(unsigned Context) {
Chris Lattner34a01ad2007-10-09 17:33:22 +000043 assert(Tok.is(tok::kw_namespace) && "Not a namespace!");
Chris Lattnerf7b2e552007-08-25 06:57:03 +000044 SourceLocation NamespaceLoc = ConsumeToken(); // eat the 'namespace'.
45
46 SourceLocation IdentLoc;
47 IdentifierInfo *Ident = 0;
48
Chris Lattner34a01ad2007-10-09 17:33:22 +000049 if (Tok.is(tok::identifier)) {
Chris Lattnerf7b2e552007-08-25 06:57:03 +000050 Ident = Tok.getIdentifierInfo();
51 IdentLoc = ConsumeToken(); // eat the identifier.
52 }
53
54 // Read label attributes, if present.
55 DeclTy *AttrList = 0;
Chris Lattner34a01ad2007-10-09 17:33:22 +000056 if (Tok.is(tok::kw___attribute))
Chris Lattnerf7b2e552007-08-25 06:57:03 +000057 // FIXME: save these somewhere.
58 AttrList = ParseAttributes();
59
Chris Lattner34a01ad2007-10-09 17:33:22 +000060 if (Tok.is(tok::equal)) {
Chris Lattnerf7b2e552007-08-25 06:57:03 +000061 // FIXME: Verify no attributes were present.
62 // FIXME: parse this.
Chris Lattner34a01ad2007-10-09 17:33:22 +000063 } else if (Tok.is(tok::l_brace)) {
Chris Lattnerf7b2e552007-08-25 06:57:03 +000064 SourceLocation LBrace = ConsumeBrace();
65 // FIXME: push a scope, push a namespace decl.
66
Chris Lattner34a01ad2007-10-09 17:33:22 +000067 while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
Chris Lattner9c135722007-08-25 18:15:16 +000068 // FIXME capture the decls.
69 ParseExternalDeclaration();
70 }
Chris Lattnerf7b2e552007-08-25 06:57:03 +000071
72 SourceLocation RBrace = MatchRHSPunctuation(tok::r_brace, LBrace);
73
74 // FIXME: act on this.
75 } else {
76 unsigned D = Ident ? diag::err_expected_lbrace :
77 diag::err_expected_ident_lbrace;
78 Diag(Tok.getLocation(), D);
79 }
80
81 return 0;
82}
Chris Lattner806a5f52008-01-12 07:05:38 +000083
84/// ParseLinkage - We know that the current token is a string_literal
85/// and just before that, that extern was seen.
86///
87/// linkage-specification: [C++ 7.5p2: dcl.link]
88/// 'extern' string-literal '{' declaration-seq[opt] '}'
89/// 'extern' string-literal declaration
90///
91Parser::DeclTy *Parser::ParseLinkage(unsigned Context) {
92 assert(Tok.is(tok::string_literal) && "Not a stringliteral!");
93 llvm::SmallVector<char, 8> LangBuffer;
94 // LangBuffer is guaranteed to be big enough.
95 LangBuffer.resize(Tok.getLength());
96 const char *LangBufPtr = &LangBuffer[0];
97 unsigned StrSize = PP.getSpelling(Tok, LangBufPtr);
98
99 SourceLocation Loc = ConsumeStringToken();
100 DeclTy *D = 0;
101 SourceLocation LBrace, RBrace;
102
103 if (Tok.isNot(tok::l_brace)) {
104 D = ParseDeclaration(Context);
105 } else {
106 LBrace = ConsumeBrace();
107 while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
108 // FIXME capture the decls.
109 D = ParseExternalDeclaration();
110 }
111
112 RBrace = MatchRHSPunctuation(tok::r_brace, LBrace);
113 }
114
115 if (!D)
116 return 0;
117
118 return Actions.ActOnLinkageSpec(Loc, LBrace, RBrace, LangBufPtr, StrSize, D);
119}