Details | Last modification | View Log | RSS feed
| Rev | Author | Line No. | Line | 
|---|---|---|---|
| 14 | pmbaty | 1 | //===--- MacroArgs.h - Formal argument info for Macros ----------*- C++ -*-===// | 
| 2 | // | ||
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
| 4 | // See https://llvm.org/LICENSE.txt for license information. | ||
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
| 6 | // | ||
| 7 | //===----------------------------------------------------------------------===// | ||
| 8 | // | ||
| 9 | // This file defines the MacroArgs interface. | ||
| 10 | // | ||
| 11 | //===----------------------------------------------------------------------===// | ||
| 12 | |||
| 13 | #ifndef LLVM_CLANG_LEX_MACROARGS_H | ||
| 14 | #define LLVM_CLANG_LEX_MACROARGS_H | ||
| 15 | |||
| 16 | #include "clang/Basic/LLVM.h" | ||
| 17 | #include "clang/Lex/Token.h" | ||
| 18 | #include "llvm/ADT/ArrayRef.h" | ||
| 19 | #include "llvm/Support/TrailingObjects.h" | ||
| 20 | #include <vector> | ||
| 21 | |||
| 22 | namespace clang { | ||
| 23 | class MacroInfo; | ||
| 24 | class Preprocessor; | ||
| 25 | class SourceLocation; | ||
| 26 | |||
| 27 | /// MacroArgs - An instance of this class captures information about | ||
| 28 | /// the formal arguments specified to a function-like macro invocation. | ||
| 29 | class MacroArgs final | ||
| 30 | : private llvm::TrailingObjects<MacroArgs, Token> { | ||
| 31 | |||
| 32 | friend TrailingObjects; | ||
| 33 |   /// NumUnexpArgTokens - The number of raw, unexpanded tokens for the | ||
| 34 |   /// arguments.  All of the actual argument tokens are allocated immediately | ||
| 35 |   /// after the MacroArgs object in memory.  This is all of the arguments | ||
| 36 |   /// concatenated together, with 'EOF' markers at the end of each argument. | ||
| 37 | unsigned NumUnexpArgTokens; | ||
| 38 | |||
| 39 |   /// VarargsElided - True if this is a C99 style varargs macro invocation and | ||
| 40 |   /// there was no argument specified for the "..." argument.  If the argument | ||
| 41 |   /// was specified (even empty) or this isn't a C99 style varargs function, or | ||
| 42 |   /// if in strict mode and the C99 varargs macro had only a ... argument, this | ||
| 43 |   /// is false. | ||
| 44 | bool VarargsElided; | ||
| 45 | |||
| 46 |   /// PreExpArgTokens - Pre-expanded tokens for arguments that need them.  Empty | ||
| 47 |   /// if not yet computed.  This includes the EOF marker at the end of the | ||
| 48 |   /// stream. | ||
| 49 | std::vector<std::vector<Token> > PreExpArgTokens; | ||
| 50 | |||
| 51 |   /// ArgCache - This is a linked list of MacroArgs objects that the | ||
| 52 |   /// Preprocessor owns which we use to avoid thrashing malloc/free. | ||
| 53 | MacroArgs *ArgCache; | ||
| 54 | |||
| 55 |   /// MacroArgs - The number of arguments the invoked macro expects. | ||
| 56 | unsigned NumMacroArgs; | ||
| 57 | |||
| 58 | MacroArgs(unsigned NumToks, bool varargsElided, unsigned MacroArgs) | ||
| 59 | : NumUnexpArgTokens(NumToks), VarargsElided(varargsElided), | ||
| 60 | ArgCache(nullptr), NumMacroArgs(MacroArgs) {} | ||
| 61 | ~MacroArgs() = default; | ||
| 62 | |||
| 63 | public: | ||
| 64 |   /// MacroArgs ctor function - Create a new MacroArgs object with the specified | ||
| 65 |   /// macro and argument info. | ||
| 66 | static MacroArgs *create(const MacroInfo *MI, | ||
| 67 | ArrayRef<Token> UnexpArgTokens, | ||
| 68 | bool VarargsElided, Preprocessor &PP); | ||
| 69 | |||
| 70 |   /// destroy - Destroy and deallocate the memory for this object. | ||
| 71 |   /// | ||
| 72 | void destroy(Preprocessor &PP); | ||
| 73 | |||
| 74 |   /// ArgNeedsPreexpansion - If we can prove that the argument won't be affected | ||
| 75 |   /// by pre-expansion, return false.  Otherwise, conservatively return true. | ||
| 76 | bool ArgNeedsPreexpansion(const Token *ArgTok, Preprocessor &PP) const; | ||
| 77 | |||
| 78 |   /// getUnexpArgument - Return a pointer to the first token of the unexpanded | ||
| 79 |   /// token list for the specified formal. | ||
| 80 |   /// | ||
| 81 | const Token *getUnexpArgument(unsigned Arg) const; | ||
| 82 | |||
| 83 |   /// getArgLength - Given a pointer to an expanded or unexpanded argument, | ||
| 84 |   /// return the number of tokens, not counting the EOF, that make up the | ||
| 85 |   /// argument. | ||
| 86 | static unsigned getArgLength(const Token *ArgPtr); | ||
| 87 | |||
| 88 |   /// getPreExpArgument - Return the pre-expanded form of the specified | ||
| 89 |   /// argument. | ||
| 90 | const std::vector<Token> & | ||
| 91 | getPreExpArgument(unsigned Arg, Preprocessor &PP); | ||
| 92 | |||
| 93 |   /// getNumMacroArguments - Return the number of arguments the invoked macro | ||
| 94 |   /// expects. | ||
| 95 | unsigned getNumMacroArguments() const { return NumMacroArgs; } | ||
| 96 | |||
| 97 |   /// isVarargsElidedUse - Return true if this is a C99 style varargs macro | ||
| 98 |   /// invocation and there was no argument specified for the "..." argument.  If | ||
| 99 |   /// the argument was specified (even empty) or this isn't a C99 style varargs | ||
| 100 |   /// function, or if in strict mode and the C99 varargs macro had only a ... | ||
| 101 |   /// argument, this returns false. | ||
| 102 | bool isVarargsElidedUse() const { return VarargsElided; } | ||
| 103 | |||
| 104 |   /// Returns true if the macro was defined with a variadic (ellipsis) parameter | ||
| 105 |   /// AND was invoked with at least one token supplied as a variadic argument | ||
| 106 |   /// (after pre-expansion). | ||
| 107 |   /// | ||
| 108 |   /// \code | ||
| 109 |   ///   #define F(a)  a | ||
| 110 |   ///   #define V(a, ...) __VA_OPT__(a) | ||
| 111 |   ///   F()     <-- returns false on this invocation. | ||
| 112 |   ///   V(,a)   <-- returns true on this invocation. | ||
| 113 |   ///   V(,)    <-- returns false on this invocation. | ||
| 114 |   ///   V(,F()) <-- returns false on this invocation. | ||
| 115 |   /// \endcode | ||
| 116 |   /// | ||
| 117 | bool invokedWithVariadicArgument(const MacroInfo *const MI, Preprocessor &PP); | ||
| 118 | |||
| 119 |   /// StringifyArgument - Implement C99 6.10.3.2p2, converting a sequence of | ||
| 120 |   /// tokens into the literal string token that should be produced by the C # | ||
| 121 |   /// preprocessor operator.  If Charify is true, then it should be turned into | ||
| 122 |   /// a character literal for the Microsoft charize (#@) extension. | ||
| 123 |   /// | ||
| 124 | static Token StringifyArgument(const Token *ArgToks, | ||
| 125 | Preprocessor &PP, bool Charify, | ||
| 126 | SourceLocation ExpansionLocStart, | ||
| 127 | SourceLocation ExpansionLocEnd); | ||
| 128 | |||
| 129 | |||
| 130 |   /// deallocate - This should only be called by the Preprocessor when managing | ||
| 131 |   /// its freelist. | ||
| 132 | MacroArgs *deallocate(); | ||
| 133 | }; | ||
| 134 | |||
| 135 | } // end namespace clang | ||
| 136 | |||
| 137 | #endif |