1193326Sed//===--- TokenConcatenation.h - Token Concatenation Avoidance ---*- C++ -*-===//
2193326Sed//
3193326Sed//                     The LLVM Compiler Infrastructure
4193326Sed//
5193326Sed// This file is distributed under the University of Illinois Open Source
6193326Sed// License. See LICENSE.TXT for details.
7193326Sed//
8193326Sed//===----------------------------------------------------------------------===//
9193326Sed//
10193326Sed// This file defines the TokenConcatenation class.
11193326Sed//
12193326Sed//===----------------------------------------------------------------------===//
13193326Sed
14193326Sed#ifndef CLANG_LEX_TOKEN_CONCATENATION_H
15193326Sed#define CLANG_LEX_TOKEN_CONCATENATION_H
16193326Sed
17193326Sed#include "clang/Basic/TokenKinds.h"
18193326Sed
19193326Sednamespace clang {
20193326Sed  class Preprocessor;
21193326Sed  class Token;
22198092Srdivacky
23193326Sed  /// TokenConcatenation class, which answers the question of
24193326Sed  ///   "Is it safe to emit two tokens without a whitespace between them, or
25193326Sed  ///    would that cause implicit concatenation of the tokens?"
26193326Sed  ///
27193326Sed  /// For example, it emitting two identifiers "foo" and "bar" next to each
28193326Sed  /// other would cause the lexer to produce one "foobar" token.  Emitting "1"
29193326Sed  /// and ")" next to each other is safe.
30193326Sed  ///
31193326Sed  class TokenConcatenation {
32193326Sed    Preprocessor &PP;
33198092Srdivacky
34193326Sed    enum AvoidConcatInfo {
35193326Sed      /// By default, a token never needs to avoid concatenation.  Most tokens
36193326Sed      /// (e.g. ',', ')', etc) don't cause a problem when concatenated.
37193326Sed      aci_never_avoid_concat = 0,
38198092Srdivacky
39193326Sed      /// aci_custom_firstchar - AvoidConcat contains custom code to handle this
40193326Sed      /// token's requirements, and it needs to know the first character of the
41193326Sed      /// token.
42193326Sed      aci_custom_firstchar = 1,
43198092Srdivacky
44193326Sed      /// aci_custom - AvoidConcat contains custom code to handle this token's
45193326Sed      /// requirements, but it doesn't need to know the first character of the
46193326Sed      /// token.
47193326Sed      aci_custom = 2,
48198092Srdivacky
49193326Sed      /// aci_avoid_equal - Many tokens cannot be safely followed by an '='
50193326Sed      /// character.  For example, "<<" turns into "<<=" when followed by an =.
51193326Sed      aci_avoid_equal = 4
52193326Sed    };
53198092Srdivacky
54193326Sed    /// TokenInfo - This array contains information for each token on what
55193326Sed    /// action to take when avoiding concatenation of tokens in the AvoidConcat
56193326Sed    /// method.
57193326Sed    char TokenInfo[tok::NUM_TOKENS];
58193326Sed  public:
59193326Sed    TokenConcatenation(Preprocessor &PP);
60198092Srdivacky
61207619Srdivacky    bool AvoidConcat(const Token &PrevPrevTok,
62207619Srdivacky                     const Token &PrevTok,
63207619Srdivacky                     const Token &Tok) const;
64193326Sed
65193326Sed  private:
66226633Sdim    /// IsIdentifierStringPrefix - Return true if the spelling of the token
67226633Sdim    /// is literally 'L', 'u', 'U', or 'u8'.
68226633Sdim    bool IsIdentifierStringPrefix(const Token &Tok) const;
69193326Sed  };
70193326Sed  } // end clang namespace
71193326Sed
72193326Sed#endif
73