reference, declarationdefinition
definition → references, declarations, derived classes, virtual overrides
reference to multiple definitions → definitions
unreferenced
    1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
  108
  109
  110
  111
  112
  113
  114
  115
  116
  117
  118
  119
  120
  121
  122
  123
  124
  125
  126
  127
  128
  129
  130
  131
  132
  133
  134
  135
  136
  137
//===--- MacroArgs.h - Formal argument info for Macros ----------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file defines the MacroArgs interface.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_LEX_MACROARGS_H
#define LLVM_CLANG_LEX_MACROARGS_H

#include "clang/Basic/LLVM.h"
#include "clang/Lex/Token.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/Support/TrailingObjects.h"
#include <vector>

namespace clang {
  class MacroInfo;
  class Preprocessor;
  class SourceLocation;

/// MacroArgs - An instance of this class captures information about
/// the formal arguments specified to a function-like macro invocation.
class MacroArgs final
    : private llvm::TrailingObjects<MacroArgs, Token> {

  friend TrailingObjects;
  /// NumUnexpArgTokens - The number of raw, unexpanded tokens for the
  /// arguments.  All of the actual argument tokens are allocated immediately
  /// after the MacroArgs object in memory.  This is all of the arguments
  /// concatenated together, with 'EOF' markers at the end of each argument.
  unsigned NumUnexpArgTokens;

  /// VarargsElided - True if this is a C99 style varargs macro invocation and
  /// there was no argument specified for the "..." argument.  If the argument
  /// was specified (even empty) or this isn't a C99 style varargs function, or
  /// if in strict mode and the C99 varargs macro had only a ... argument, this
  /// is false.
  bool VarargsElided;

  /// PreExpArgTokens - Pre-expanded tokens for arguments that need them.  Empty
  /// if not yet computed.  This includes the EOF marker at the end of the
  /// stream.
  std::vector<std::vector<Token> > PreExpArgTokens;

  /// ArgCache - This is a linked list of MacroArgs objects that the
  /// Preprocessor owns which we use to avoid thrashing malloc/free.
  MacroArgs *ArgCache;

  /// MacroArgs - The number of arguments the invoked macro expects.
  unsigned NumMacroArgs;

  MacroArgs(unsigned NumToks, bool varargsElided, unsigned MacroArgs)
      : NumUnexpArgTokens(NumToks), VarargsElided(varargsElided),
        ArgCache(nullptr), NumMacroArgs(MacroArgs) {}
  ~MacroArgs() = default;

public:
  /// MacroArgs ctor function - Create a new MacroArgs object with the specified
  /// macro and argument info.
  static MacroArgs *create(const MacroInfo *MI,
                           ArrayRef<Token> UnexpArgTokens,
                           bool VarargsElided, Preprocessor &PP);

  /// destroy - Destroy and deallocate the memory for this object.
  ///
  void destroy(Preprocessor &PP);

  /// ArgNeedsPreexpansion - If we can prove that the argument won't be affected
  /// by pre-expansion, return false.  Otherwise, conservatively return true.
  bool ArgNeedsPreexpansion(const Token *ArgTok, Preprocessor &PP) const;

  /// getUnexpArgument - Return a pointer to the first token of the unexpanded
  /// token list for the specified formal.
  ///
  const Token *getUnexpArgument(unsigned Arg) const;

  /// getArgLength - Given a pointer to an expanded or unexpanded argument,
  /// return the number of tokens, not counting the EOF, that make up the
  /// argument.
  static unsigned getArgLength(const Token *ArgPtr);

  /// getPreExpArgument - Return the pre-expanded form of the specified
  /// argument.
  const std::vector<Token> &
    getPreExpArgument(unsigned Arg, Preprocessor &PP);

  /// getNumMacroArguments - Return the number of arguments the invoked macro
  /// expects.
  unsigned getNumMacroArguments() const { return NumMacroArgs; }

  /// isVarargsElidedUse - Return true if this is a C99 style varargs macro
  /// invocation and there was no argument specified for the "..." argument.  If
  /// the argument was specified (even empty) or this isn't a C99 style varargs
  /// function, or if in strict mode and the C99 varargs macro had only a ...
  /// argument, this returns false.
  bool isVarargsElidedUse() const { return VarargsElided; }

  /// Returns true if the macro was defined with a variadic (ellipsis) parameter
  /// AND was invoked with at least one token supplied as a variadic argument
  /// (after pre-expansion).
  ///
  /// \code
  ///   #define F(a)  a
  ///   #define V(a, ...) __VA_OPT__(a)
  ///   F()     <-- returns false on this invocation.
  ///   V(,a)   <-- returns true on this invocation.
  ///   V(,)    <-- returns false on this invocation.
  ///   V(,F()) <-- returns false on this invocation.
  /// \endcode
  ///
  bool invokedWithVariadicArgument(const MacroInfo *const MI, Preprocessor &PP);

  /// StringifyArgument - Implement C99 6.10.3.2p2, converting a sequence of
  /// tokens into the literal string token that should be produced by the C #
  /// preprocessor operator.  If Charify is true, then it should be turned into
  /// a character literal for the Microsoft charize (#@) extension.
  ///
  static Token StringifyArgument(const Token *ArgToks,
                                 Preprocessor &PP, bool Charify,
                                 SourceLocation ExpansionLocStart,
                                 SourceLocation ExpansionLocEnd);


  /// deallocate - This should only be called by the Preprocessor when managing
  /// its freelist.
  MacroArgs *deallocate();
};

}  // end namespace clang

#endif