Parser.h revision 4fa7afd07421e7276d1717e4fdf43a5fdd65a622
15f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===--- Parser.h - C Language Parser ---------------------------*- C++ -*-===//
25f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
35f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//                     The LLVM Compiler Infrastructure
45f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
55f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// This file was developed by Chris Lattner and is distributed under
65f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// the University of Illinois Open Source License. See LICENSE.TXT for details.
75f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
85f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
95f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//  This file defines the Parser interface.
115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#ifndef LLVM_CLANG_PARSE_PARSER_H
155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#define LLVM_CLANG_PARSE_PARSER_H
165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "clang/Lex/Preprocessor.h"
185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "clang/Parse/Action.h"
195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencernamespace clang {
215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  class DeclSpec;
225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  class Declarator;
235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  class AttributeList;
245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  class Scope;
255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// Parser - This implements a parser for the C family of languages.  After
275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// parsing units of the grammar, productions are invoked to handle whatever has
285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// been read.
295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer///
305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerclass Parser {
315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  Preprocessor &PP;
325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// Tok - The current token we are peeking head.  All parsing methods assume
345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// that this is valid.
35d217773f106856a11879ec79dc468efefaf2ee75Chris Lattner  Token Tok;
365f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  unsigned short ParenCount, BracketCount, BraceCount;
385f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
395f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// Actions - These are the callbacks we invoke as we parse various constructs
405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// in the file.  This refers to the common base class between MinimalActions
415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// and SemaActions for those uses that don't matter.
425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  Action &Actions;
435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  Scope *CurScope;
455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  Diagnostic &Diags;
469e344c65b1e8b83e1d3ada507cf653526ff2c005Chris Lattner
479e344c65b1e8b83e1d3ada507cf653526ff2c005Chris Lattner  /// ScopeCache - Cache scopes to reduce malloc traffic.
489e344c65b1e8b83e1d3ada507cf653526ff2c005Chris Lattner  enum { ScopeCacheSize = 16 };
499e344c65b1e8b83e1d3ada507cf653526ff2c005Chris Lattner  unsigned NumCachedScopes;
509e344c65b1e8b83e1d3ada507cf653526ff2c005Chris Lattner  Scope *ScopeCache[ScopeCacheSize];
515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerpublic:
525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  Parser(Preprocessor &PP, Action &Actions);
535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  ~Parser();
545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  const LangOptions &getLang() const { return PP.getLangOptions(); }
565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  TargetInfo &getTargetInfo() const { return PP.getTargetInfo(); }
575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  Action &getActions() const { return Actions; }
585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Type forwarding.  All of these are statically 'void*', but they may all be
605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // different actual classes based on the actions in place.
615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  typedef Action::ExprTy ExprTy;
625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  typedef Action::StmtTy StmtTy;
635f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  typedef Action::DeclTy DeclTy;
645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  typedef Action::TypeTy TypeTy;
655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
665f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Parsing methods.
675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// ParseTranslationUnit - All in one method that initializes parses, and
695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// shuts down the parser.
705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void ParseTranslationUnit();
715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// Initialize - Warm up the parser.
735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  ///
745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void Initialize();
755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// ParseTopLevelDecl - Parse one top-level declaration, return whatever the
775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// action tells us to.  This returns true if the EOF was encountered.
785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool ParseTopLevelDecl(DeclTy*& Result);
795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// Finalize - Shut down the parser.
815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  ///
825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void Finalize();
835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerprivate:
855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  //===--------------------------------------------------------------------===//
865f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Low-Level token peeking and consumption methods.
875f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  //
885f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// isTokenParen - Return true if the cur token is '(' or ')'.
905f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool isTokenParen() const {
915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return Tok.getKind() == tok::l_paren || Tok.getKind() == tok::r_paren;
925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// isTokenBracket - Return true if the cur token is '[' or ']'.
945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool isTokenBracket() const {
955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return Tok.getKind() == tok::l_square || Tok.getKind() == tok::r_square;
965f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// isTokenBrace - Return true if the cur token is '{' or '}'.
985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool isTokenBrace() const {
995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return Tok.getKind() == tok::l_brace || Tok.getKind() == tok::r_brace;
1005f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
1015f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// isTokenStringLiteral - True if this token is a string-literal.
1035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  ///
1045f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool isTokenStringLiteral() const {
1055f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return Tok.getKind() == tok::string_literal ||
1065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer           Tok.getKind() == tok::wide_string_literal;
1075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
1085f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1095f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// ConsumeToken - Consume the current 'peek token' and lex the next one.
1105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// This does not work will all kinds of tokens: strings and specific other
1115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// tokens must be consumed with custom methods below.  This returns the
1125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// location of the consumed token.
1135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  SourceLocation ConsumeToken() {
1145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    assert(!isTokenStringLiteral() && !isTokenParen() && !isTokenBracket() &&
1155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer           !isTokenBrace() &&
1165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer           "Should consume special tokens with Consume*Token");
1175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    SourceLocation L = Tok.getLocation();
1185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    PP.Lex(Tok);
1195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return L;
1205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
1215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// ConsumeAnyToken - Dispatch to the right Consume* method based on the
1235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// current token type.  This should only be used in cases where the type of
1245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// the token really isn't known, e.g. in error recovery.
1255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  SourceLocation ConsumeAnyToken() {
1265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    if (isTokenParen())
1275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      return ConsumeParen();
1285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    else if (isTokenBracket())
1295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      return ConsumeBracket();
1305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    else if (isTokenBrace())
1315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      return ConsumeBrace();
1325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    else
1335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      return ConsumeToken();
1345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
1355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1365f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// ConsumeParen - This consume method keeps the paren count up-to-date.
1375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  ///
1385f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  SourceLocation ConsumeParen() {
1395f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    assert(isTokenParen() && "wrong consume method");
1405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    if (Tok.getKind() == tok::l_paren)
1415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      ++ParenCount;
1425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    else if (ParenCount)
1435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      --ParenCount;       // Don't let unbalanced )'s drive the count negative.
1445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    SourceLocation L = Tok.getLocation();
1455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    PP.Lex(Tok);
1465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return L;
1475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
1485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// ConsumeBracket - This consume method keeps the bracket count up-to-date.
1505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  ///
1515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  SourceLocation ConsumeBracket() {
1525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    assert(isTokenBracket() && "wrong consume method");
1535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    if (Tok.getKind() == tok::l_square)
1545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      ++BracketCount;
1555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    else if (BracketCount)
1565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      --BracketCount;     // Don't let unbalanced ]'s drive the count negative.
1575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    SourceLocation L = Tok.getLocation();
1595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    PP.Lex(Tok);
1605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return L;
1615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
1625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1635f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// ConsumeBrace - This consume method keeps the brace count up-to-date.
1645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  ///
1655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  SourceLocation ConsumeBrace() {
1665f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    assert(isTokenBrace() && "wrong consume method");
1675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    if (Tok.getKind() == tok::l_brace)
1685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      ++BraceCount;
1695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    else if (BraceCount)
1705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      --BraceCount;     // Don't let unbalanced }'s drive the count negative.
1715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    SourceLocation L = Tok.getLocation();
1735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    PP.Lex(Tok);
1745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return L;
1755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
1765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// ConsumeStringToken - Consume the current 'peek token', lexing a new one
1785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// and returning the token kind.  This method is specific to strings, as it
1795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// handles string literal concatenation, as per C99 5.1.1.2, translation
1805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// phase #6.
1815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  SourceLocation ConsumeStringToken() {
1825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    assert(isTokenStringLiteral() &&
1835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer           "Should only consume string literals with this method");
1845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    SourceLocation L = Tok.getLocation();
1855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    PP.Lex(Tok);
1865f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return L;
1875f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
1885f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// MatchRHSPunctuation - For punctuation with a LHS and RHS (e.g. '['/']'),
1905f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// this helper function matches and consumes the specified RHS token if
1915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// present.  If not present, it emits the specified diagnostic indicating
1925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// that the parser failed to match the RHS of the token at LHSLoc.  LHSName
1935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// should be the name of the unmatched LHS token.  This returns the location
1945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// of the consumed token.
1955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  SourceLocation MatchRHSPunctuation(tok::TokenKind RHSTok,
1965f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                                     SourceLocation LHSLoc);
1975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
1985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// ExpectAndConsume - The parser expects that 'ExpectedTok' is next in the
1995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// input.  If so, it is consumed and false is returned.
2005f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  ///
2015f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// If the input is malformed, this emits the specified diagnostic.  Next, if
2025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// SkipToTok is specified, it calls SkipUntil(SkipToTok).  Finally, true is
2035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// returned.
2045f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool ExpectAndConsume(tok::TokenKind ExpectedTok, unsigned Diag,
2055f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                        const char *DiagMsg = "",
2065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                        tok::TokenKind SkipToTok = tok::unknown);
2075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
2085f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  //===--------------------------------------------------------------------===//
2095f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Scope manipulation
2105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
2115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// EnterScope - Start a new scope.
2125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void EnterScope(unsigned ScopeFlags);
2135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
2145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// ExitScope - Pop a scope off the scope stack.
2155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void ExitScope();
2165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
2175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  //===--------------------------------------------------------------------===//
2185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Diagnostic Emission and Error recovery.
2195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
2205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void Diag(SourceLocation Loc, unsigned DiagID,
2215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer            const std::string &Msg = std::string());
222d217773f106856a11879ec79dc468efefaf2ee75Chris Lattner  void Diag(const Token &Tok, unsigned DiagID,
2235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer            const std::string &M = std::string()) {
2245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    Diag(Tok.getLocation(), DiagID, M);
2255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
2265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
2275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// SkipUntil - Read tokens until we get to the specified token, then consume
22882c7e6d8215567935d3d52741ccca9876a8ea461Steve Naroff  /// it (unless DontConsume is true).  Because we cannot guarantee that the
2295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// token will ever occur, this skips to the next token, or to some likely
2305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// good stopping point.  If StopAtSemi is true, skipping will stop at a ';'
2315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// character.
2325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  ///
2335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// If SkipUntil finds the specified token, it returns true, otherwise it
2345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// returns false.
2355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool SkipUntil(tok::TokenKind T, bool StopAtSemi = true,
2365f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                 bool DontConsume = false) {
2375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return SkipUntil(&T, 1, StopAtSemi, DontConsume);
2385f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
2395f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool SkipUntil(tok::TokenKind T1, tok::TokenKind T2, bool StopAtSemi = true,
2405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                 bool DontConsume = false) {
2415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    tok::TokenKind TokArray[] = {T1, T2};
2425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return SkipUntil(TokArray, 2, StopAtSemi, DontConsume);
2435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
2445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool SkipUntil(const tok::TokenKind *Toks, unsigned NumToks,
2455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                 bool StopAtSemi = true, bool DontConsume = false);
2465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
2475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  //===--------------------------------------------------------------------===//
2485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // C99 6.9: External Definitions.
2495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  DeclTy *ParseExternalDeclaration();
2505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  DeclTy *ParseDeclarationOrFunctionDefinition();
2515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  DeclTy *ParseFunctionDefinition(Declarator &D);
2525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void ParseKNRParamDeclarations(Declarator &D);
2535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void ParseSimpleAsm();
2545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void ParseAsmStringLiteral();
2555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
2565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // Objective-C External Declarations
257dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff  DeclTy *ParseObjCAtDirectives();
258dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff  DeclTy *ParseObjCAtClassDeclaration(SourceLocation atLoc);
259dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff  DeclTy *ParseObjCAtInterfaceDeclaration(SourceLocation atLoc,
260dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff                                          AttributeList *prefixAttrs = 0);
261ddbff78fb719a645b04bd27099fa6ec8c4693b3cSteve Naroff  void ParseObjCClassInstanceVariables(DeclTy *interfaceDecl);
262dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff  bool ParseObjCProtocolReferences();
263294494e1cce92043562b4680c613df7fd028c02eSteve Naroff  void ParseObjCInterfaceDeclList(DeclTy *interfaceDecl);
2647ef58fdbefddf693910e6403a71b3d367444c897Steve Naroff  DeclTy *ParseObjCAtProtocolDeclaration(SourceLocation atLoc);
265dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff  DeclTy *ParseObjCAtImplementationDeclaration();
266dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff  DeclTy *ParseObjCAtEndDeclaration();
267dac269b65eed82182fc3e96566dedd6562dfe11eSteve Naroff  DeclTy *ParseObjCAtAliasDeclaration();
2685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
269294494e1cce92043562b4680c613df7fd028c02eSteve Naroff  IdentifierInfo *ParseObjCSelector();
2704fa7afd07421e7276d1717e4fdf43a5fdd65a622Steve Naroff  bool isObjCTypeQualifier();
271294494e1cce92043562b4680c613df7fd028c02eSteve Naroff  void ParseObjCTypeName();
272294494e1cce92043562b4680c613df7fd028c02eSteve Naroff  void ParseObjCMethodRequirement();
273294494e1cce92043562b4680c613df7fd028c02eSteve Naroff  void ParseObjCMethodPrototype();
274294494e1cce92043562b4680c613df7fd028c02eSteve Naroff  void ParseObjCMethodDecl(tok::TokenKind mType, SourceLocation mLoc);
275294494e1cce92043562b4680c613df7fd028c02eSteve Naroff  void ParseObjCPropertyDecl(SourceLocation atLoc);
276294494e1cce92043562b4680c613df7fd028c02eSteve Naroff
2777ef58fdbefddf693910e6403a71b3d367444c897Steve Naroff  void ParseObjCInstanceMethodDefinition();
2787ef58fdbefddf693910e6403a71b3d367444c897Steve Naroff  void ParseObjCClassMethodDefinition();
2795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
2805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  //===--------------------------------------------------------------------===//
2815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // C99 6.5: Expressions.
2825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
2835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  typedef Action::ExprResult ExprResult;
2845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  typedef Action::StmtResult StmtResult;
2855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
2865f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  ExprResult ParseExpression();
2875f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  ExprResult ParseConstantExpression();
2885f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  ExprResult ParseAssignmentExpression();  // Expr that doesn't include commas.
2895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
290d217773f106856a11879ec79dc468efefaf2ee75Chris Lattner  ExprResult ParseExpressionWithLeadingIdentifier(const Token &Tok);
291d217773f106856a11879ec79dc468efefaf2ee75Chris Lattner  ExprResult ParseAssignmentExprWithLeadingIdentifier(const Token &Tok);
292d217773f106856a11879ec79dc468efefaf2ee75Chris Lattner  ExprResult ParseAssignmentExpressionWithLeadingStar(const Token &Tok);
2935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
2945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  ExprResult ParseRHSOfBinaryExpression(ExprResult LHS, unsigned MinPrec);
2955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  ExprResult ParseCastExpression(bool isUnaryExpression);
2965f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  ExprResult ParsePostfixExpressionSuffix(ExprResult LHS);
2975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  ExprResult ParseSizeofAlignofExpression();
2985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  ExprResult ParseBuiltinPrimaryExpression();
2995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
3005f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// ParenParseOption - Control what ParseParenExpression will parse.
3015f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  enum ParenParseOption {
3025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    SimpleExpr,      // Only parse '(' expression ')'
3035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    CompoundStmt,    // Also allow '(' compound-statement ')'
3045f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    CompoundLiteral, // Also allow '(' type-name ')' '{' ... '}'
3055f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    CastExpr         // Also allow '(' type-name ')' <anything>
3065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  };
3075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  ExprResult ParseParenExpression(ParenParseOption &ExprType, TypeTy *&CastTy,
3085f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                                  SourceLocation &RParenLoc);
3095f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
3105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  ExprResult ParseSimpleParenExpression() {  // Parse SimpleExpr only.
3115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    SourceLocation RParenLoc;
3125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return ParseSimpleParenExpression(RParenLoc);
3135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
3145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  ExprResult ParseSimpleParenExpression(SourceLocation &RParenLoc) {
3155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    ParenParseOption Op = SimpleExpr;
3165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    TypeTy *CastTy;
3175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return ParseParenExpression(Op, CastTy, RParenLoc);
3185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
3195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  ExprResult ParseStringLiteralExpression();
3205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
3215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  //===--------------------------------------------------------------------===//
3225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // C++ 5.2p1: C++ Casts
3235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  ExprResult ParseCXXCasts();
3245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
3255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  //===--------------------------------------------------------------------===//
3265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // C++ 2.13.5: C++ Boolean Literals
3275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  ExprResult ParseCXXBoolLiteral();
3285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
3295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  //===--------------------------------------------------------------------===//
3305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // C99 6.7.8: Initialization.
3315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  ExprResult ParseInitializer();
3325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  ExprResult ParseInitializerWithPotentialDesignator();
3335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
3345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  //===--------------------------------------------------------------------===//
3355508518a2702b00be3b15a26d772bde968972f54Anders Carlsson  // Objective-C Expressions
3365508518a2702b00be3b15a26d772bde968972f54Anders Carlsson  ExprResult ParseObjCExpression();
3375508518a2702b00be3b15a26d772bde968972f54Anders Carlsson  ExprResult ParseObjCStringLiteral();
338f9bcf01f82dfd2688f81e57bcc6300c9b13c51a6Anders Carlsson  ExprResult ParseObjCEncodeExpression();
339f9bcf01f82dfd2688f81e57bcc6300c9b13c51a6Anders Carlsson
3405508518a2702b00be3b15a26d772bde968972f54Anders Carlsson  //===--------------------------------------------------------------------===//
3415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // C99 6.8: Statements and Blocks.
3425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
3435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  StmtResult ParseStatement() { return ParseStatementOrDeclaration(true); }
3445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  StmtResult ParseStatementOrDeclaration(bool OnlyStatement = false);
3455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  StmtResult ParseIdentifierStatement(bool OnlyStatement);
3465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  StmtResult ParseCaseStatement();
3475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  StmtResult ParseDefaultStatement();
3485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  StmtResult ParseCompoundStatement();
3495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  StmtResult ParseCompoundStatementBody();
3505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  StmtResult ParseIfStatement();
3515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  StmtResult ParseSwitchStatement();
3525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  StmtResult ParseWhileStatement();
3535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  StmtResult ParseDoStatement();
3545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  StmtResult ParseForStatement();
3555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  StmtResult ParseGotoStatement();
3565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  StmtResult ParseContinueStatement();
3575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  StmtResult ParseBreakStatement();
3585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  StmtResult ParseReturnStatement();
3595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  StmtResult ParseAsmStatement();
3605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void ParseAsmOperandsOpt();
3615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
3625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  //===--------------------------------------------------------------------===//
3635f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  // C99 6.7: Declarations.
3645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
3655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  DeclTy *ParseDeclaration(unsigned Context);
3665f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  DeclTy *ParseInitDeclaratorListAfterFirstDeclarator(Declarator &D);
3675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void ParseDeclarationSpecifiers(DeclSpec &DS);
3685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void ParseSpecifierQualifierList(DeclSpec &DS);
3695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
3705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool ParseTag(DeclTy *&Decl, unsigned TagType, SourceLocation StartLoc);
3715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void ParseEnumSpecifier(DeclSpec &DS);
3725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void ParseEnumBody(SourceLocation StartLoc, DeclTy *TagDecl);
3735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void ParseStructUnionSpecifier(DeclSpec &DS);
3745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void ParseStructUnionBody(SourceLocation StartLoc, unsigned TagType,
3755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                            DeclTy *TagDecl);
37628a7ca80da5dd2d0fca75d9a3b7a5f4851712592Steve Naroff  void ParseStructDeclaration(DeclTy *TagDecl,
37728a7ca80da5dd2d0fca75d9a3b7a5f4851712592Steve Naroff     llvm::SmallVector<DeclTy*, 32> &FieldDecls);
37828a7ca80da5dd2d0fca75d9a3b7a5f4851712592Steve Naroff
3795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool isDeclarationSpecifier() const;
3805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  bool isTypeSpecifierQualifier() const;
3815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
3825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  TypeTy *ParseTypeName();
3835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  AttributeList *ParseAttributes();
384d1861fd633d5096a00777c918eb8575ea7162fe7Steve Naroff  void ParseTypeofSpecifier(DeclSpec &DS);
3855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
3865f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  /// ParseDeclarator - Parse and verify a newly-initialized declarator.
3875f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void ParseDeclarator(Declarator &D);
3885f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void ParseDeclaratorInternal(Declarator &D);
3895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void ParseTypeQualifierListOpt(DeclSpec &DS);
3905f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void ParseDirectDeclarator(Declarator &D);
3915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void ParseParenDeclarator(Declarator &D);
3925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  void ParseBracketDeclarator(Declarator &D);
3935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer};
3945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
3955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}  // end namespace clang
3965f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
3975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#endif
398