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