TokenConcatenation.h revision 5cee1195584fa8672253139c86e922daeda69b9e
1d7038e18ef540a78fe6ce2a43125ce9b08fdbbc5Chris Lattner//===--- TokenConcatenation.h - Token Concatenation Avoidance ---*- C++ -*-===//
2d7038e18ef540a78fe6ce2a43125ce9b08fdbbc5Chris Lattner//
3d7038e18ef540a78fe6ce2a43125ce9b08fdbbc5Chris Lattner//                     The LLVM Compiler Infrastructure
4d7038e18ef540a78fe6ce2a43125ce9b08fdbbc5Chris Lattner//
5d7038e18ef540a78fe6ce2a43125ce9b08fdbbc5Chris Lattner// This file is distributed under the University of Illinois Open Source
6d7038e18ef540a78fe6ce2a43125ce9b08fdbbc5Chris Lattner// License. See LICENSE.TXT for details.
7d7038e18ef540a78fe6ce2a43125ce9b08fdbbc5Chris Lattner//
8d7038e18ef540a78fe6ce2a43125ce9b08fdbbc5Chris Lattner//===----------------------------------------------------------------------===//
9d7038e18ef540a78fe6ce2a43125ce9b08fdbbc5Chris Lattner//
10d7038e18ef540a78fe6ce2a43125ce9b08fdbbc5Chris Lattner// This file defines the TokenConcatenation class.
11d7038e18ef540a78fe6ce2a43125ce9b08fdbbc5Chris Lattner//
12d7038e18ef540a78fe6ce2a43125ce9b08fdbbc5Chris Lattner//===----------------------------------------------------------------------===//
13d7038e18ef540a78fe6ce2a43125ce9b08fdbbc5Chris Lattner
14d7038e18ef540a78fe6ce2a43125ce9b08fdbbc5Chris Lattner#ifndef CLANG_LEX_TOKEN_CONCATENATION_H
15d7038e18ef540a78fe6ce2a43125ce9b08fdbbc5Chris Lattner#define CLANG_LEX_TOKEN_CONCATENATION_H
16d7038e18ef540a78fe6ce2a43125ce9b08fdbbc5Chris Lattner
17d7038e18ef540a78fe6ce2a43125ce9b08fdbbc5Chris Lattner#include "clang/Basic/TokenKinds.h"
18d7038e18ef540a78fe6ce2a43125ce9b08fdbbc5Chris Lattner
19d7038e18ef540a78fe6ce2a43125ce9b08fdbbc5Chris Lattnernamespace clang {
20d7038e18ef540a78fe6ce2a43125ce9b08fdbbc5Chris Lattner  class Preprocessor;
21d7038e18ef540a78fe6ce2a43125ce9b08fdbbc5Chris Lattner  class Token;
221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
23d7038e18ef540a78fe6ce2a43125ce9b08fdbbc5Chris Lattner  /// TokenConcatenation class, which answers the question of
24d7038e18ef540a78fe6ce2a43125ce9b08fdbbc5Chris Lattner  ///   "Is it safe to emit two tokens without a whitespace between them, or
25d7038e18ef540a78fe6ce2a43125ce9b08fdbbc5Chris Lattner  ///    would that cause implicit concatenation of the tokens?"
26d7038e18ef540a78fe6ce2a43125ce9b08fdbbc5Chris Lattner  ///
27d7038e18ef540a78fe6ce2a43125ce9b08fdbbc5Chris Lattner  /// For example, it emitting two identifiers "foo" and "bar" next to each
28d7038e18ef540a78fe6ce2a43125ce9b08fdbbc5Chris Lattner  /// other would cause the lexer to produce one "foobar" token.  Emitting "1"
29d7038e18ef540a78fe6ce2a43125ce9b08fdbbc5Chris Lattner  /// and ")" next to each other is safe.
30d7038e18ef540a78fe6ce2a43125ce9b08fdbbc5Chris Lattner  ///
31d7038e18ef540a78fe6ce2a43125ce9b08fdbbc5Chris Lattner  class TokenConcatenation {
32d7038e18ef540a78fe6ce2a43125ce9b08fdbbc5Chris Lattner    Preprocessor &PP;
331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
34d7038e18ef540a78fe6ce2a43125ce9b08fdbbc5Chris Lattner    enum AvoidConcatInfo {
35d7038e18ef540a78fe6ce2a43125ce9b08fdbbc5Chris Lattner      /// By default, a token never needs to avoid concatenation.  Most tokens
36d7038e18ef540a78fe6ce2a43125ce9b08fdbbc5Chris Lattner      /// (e.g. ',', ')', etc) don't cause a problem when concatenated.
37d7038e18ef540a78fe6ce2a43125ce9b08fdbbc5Chris Lattner      aci_never_avoid_concat = 0,
381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
39d7038e18ef540a78fe6ce2a43125ce9b08fdbbc5Chris Lattner      /// aci_custom_firstchar - AvoidConcat contains custom code to handle this
40d7038e18ef540a78fe6ce2a43125ce9b08fdbbc5Chris Lattner      /// token's requirements, and it needs to know the first character of the
41d7038e18ef540a78fe6ce2a43125ce9b08fdbbc5Chris Lattner      /// token.
42d7038e18ef540a78fe6ce2a43125ce9b08fdbbc5Chris Lattner      aci_custom_firstchar = 1,
431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
44d7038e18ef540a78fe6ce2a43125ce9b08fdbbc5Chris Lattner      /// aci_custom - AvoidConcat contains custom code to handle this token's
45d7038e18ef540a78fe6ce2a43125ce9b08fdbbc5Chris Lattner      /// requirements, but it doesn't need to know the first character of the
46d7038e18ef540a78fe6ce2a43125ce9b08fdbbc5Chris Lattner      /// token.
47d7038e18ef540a78fe6ce2a43125ce9b08fdbbc5Chris Lattner      aci_custom = 2,
481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
49d7038e18ef540a78fe6ce2a43125ce9b08fdbbc5Chris Lattner      /// aci_avoid_equal - Many tokens cannot be safely followed by an '='
50d7038e18ef540a78fe6ce2a43125ce9b08fdbbc5Chris Lattner      /// character.  For example, "<<" turns into "<<=" when followed by an =.
51d7038e18ef540a78fe6ce2a43125ce9b08fdbbc5Chris Lattner      aci_avoid_equal = 4
52d7038e18ef540a78fe6ce2a43125ce9b08fdbbc5Chris Lattner    };
531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
54d7038e18ef540a78fe6ce2a43125ce9b08fdbbc5Chris Lattner    /// TokenInfo - This array contains information for each token on what
55d7038e18ef540a78fe6ce2a43125ce9b08fdbbc5Chris Lattner    /// action to take when avoiding concatenation of tokens in the AvoidConcat
56d7038e18ef540a78fe6ce2a43125ce9b08fdbbc5Chris Lattner    /// method.
57d7038e18ef540a78fe6ce2a43125ce9b08fdbbc5Chris Lattner    char TokenInfo[tok::NUM_TOKENS];
58d7038e18ef540a78fe6ce2a43125ce9b08fdbbc5Chris Lattner  public:
59d7038e18ef540a78fe6ce2a43125ce9b08fdbbc5Chris Lattner    TokenConcatenation(Preprocessor &PP);
601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
618877321ca66b2887c2f377a7f724a62f34fdf1cdChris Lattner    bool AvoidConcat(const Token &PrevPrevTok,
628877321ca66b2887c2f377a7f724a62f34fdf1cdChris Lattner                     const Token &PrevTok,
638877321ca66b2887c2f377a7f724a62f34fdf1cdChris Lattner                     const Token &Tok) const;
64d7038e18ef540a78fe6ce2a43125ce9b08fdbbc5Chris Lattner
65d7038e18ef540a78fe6ce2a43125ce9b08fdbbc5Chris Lattner  private:
665cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor    /// IsIdentifierStringPrefix - Return true if the spelling of the token
675cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor    /// is literally 'L', 'u', 'U', or 'u8'.
685cee1195584fa8672253139c86e922daeda69b9eDouglas Gregor    bool IsIdentifierStringPrefix(const Token &Tok) const;
69d7038e18ef540a78fe6ce2a43125ce9b08fdbbc5Chris Lattner  };
70d7038e18ef540a78fe6ce2a43125ce9b08fdbbc5Chris Lattner  } // end clang namespace
71d7038e18ef540a78fe6ce2a43125ce9b08fdbbc5Chris Lattner
72d7038e18ef540a78fe6ce2a43125ce9b08fdbbc5Chris Lattner#endif
73