ParseDeclCXX.cpp revision bda0b626e74513950405c27525af87e214e605e2
1//===--- ParseDeclCXX.cpp - C++ Declaration Parsing -----------------------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
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) {
43  assert(Tok.is(tok::kw_namespace) && "Not a namespace!");
44  SourceLocation NamespaceLoc = ConsumeToken();  // eat the 'namespace'.
45
46  SourceLocation IdentLoc;
47  IdentifierInfo *Ident = 0;
48
49  if (Tok.is(tok::identifier)) {
50    Ident = Tok.getIdentifierInfo();
51    IdentLoc = ConsumeToken();  // eat the identifier.
52  }
53
54  // Read label attributes, if present.
55  DeclTy *AttrList = 0;
56  if (Tok.is(tok::kw___attribute))
57    // FIXME: save these somewhere.
58    AttrList = ParseAttributes();
59
60  if (Tok.is(tok::equal)) {
61    // FIXME: Verify no attributes were present.
62    // FIXME: parse this.
63  } else if (Tok.is(tok::l_brace)) {
64    SourceLocation LBrace = ConsumeBrace();
65    // FIXME: push a scope, push a namespace decl.
66
67    while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
68      // FIXME capture the decls.
69      ParseExternalDeclaration();
70    }
71
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}
83
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}
120