1 1.1 joerg //===--- MacroArgs.cpp - Formal argument info for Macros ------------------===// 2 1.1 joerg // 3 1.1 joerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 1.1 joerg // See https://llvm.org/LICENSE.txt for license information. 5 1.1 joerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 1.1 joerg // 7 1.1 joerg //===----------------------------------------------------------------------===// 8 1.1 joerg // 9 1.1 joerg // This file implements the MacroArgs interface. 10 1.1 joerg // 11 1.1 joerg //===----------------------------------------------------------------------===// 12 1.1 joerg 13 1.1 joerg #include "clang/Lex/MacroArgs.h" 14 1.1 joerg #include "clang/Lex/LexDiagnostic.h" 15 1.1 joerg #include "clang/Lex/MacroInfo.h" 16 1.1 joerg #include "clang/Lex/Preprocessor.h" 17 1.1 joerg #include "llvm/ADT/SmallString.h" 18 1.1 joerg #include "llvm/Support/SaveAndRestore.h" 19 1.1 joerg #include <algorithm> 20 1.1 joerg 21 1.1 joerg using namespace clang; 22 1.1 joerg 23 1.1 joerg /// MacroArgs ctor function - This destroys the vector passed in. 24 1.1 joerg MacroArgs *MacroArgs::create(const MacroInfo *MI, 25 1.1 joerg ArrayRef<Token> UnexpArgTokens, 26 1.1 joerg bool VarargsElided, Preprocessor &PP) { 27 1.1 joerg assert(MI->isFunctionLike() && 28 1.1 joerg "Can't have args for an object-like macro!"); 29 1.1 joerg MacroArgs **ResultEnt = nullptr; 30 1.1 joerg unsigned ClosestMatch = ~0U; 31 1.1 joerg 32 1.1 joerg // See if we have an entry with a big enough argument list to reuse on the 33 1.1 joerg // free list. If so, reuse it. 34 1.1 joerg for (MacroArgs **Entry = &PP.MacroArgCache; *Entry; 35 1.1 joerg Entry = &(*Entry)->ArgCache) { 36 1.1 joerg if ((*Entry)->NumUnexpArgTokens >= UnexpArgTokens.size() && 37 1.1 joerg (*Entry)->NumUnexpArgTokens < ClosestMatch) { 38 1.1 joerg ResultEnt = Entry; 39 1.1 joerg 40 1.1 joerg // If we have an exact match, use it. 41 1.1 joerg if ((*Entry)->NumUnexpArgTokens == UnexpArgTokens.size()) 42 1.1 joerg break; 43 1.1 joerg // Otherwise, use the best fit. 44 1.1 joerg ClosestMatch = (*Entry)->NumUnexpArgTokens; 45 1.1 joerg } 46 1.1 joerg } 47 1.1 joerg MacroArgs *Result; 48 1.1 joerg if (!ResultEnt) { 49 1.1 joerg // Allocate memory for a MacroArgs object with the lexer tokens at the end, 50 1.1 joerg // and construct the MacroArgs object. 51 1.1 joerg Result = new ( 52 1.1 joerg llvm::safe_malloc(totalSizeToAlloc<Token>(UnexpArgTokens.size()))) 53 1.1 joerg MacroArgs(UnexpArgTokens.size(), VarargsElided, MI->getNumParams()); 54 1.1 joerg } else { 55 1.1 joerg Result = *ResultEnt; 56 1.1 joerg // Unlink this node from the preprocessors singly linked list. 57 1.1 joerg *ResultEnt = Result->ArgCache; 58 1.1 joerg Result->NumUnexpArgTokens = UnexpArgTokens.size(); 59 1.1 joerg Result->VarargsElided = VarargsElided; 60 1.1 joerg Result->NumMacroArgs = MI->getNumParams(); 61 1.1 joerg } 62 1.1 joerg 63 1.1 joerg // Copy the actual unexpanded tokens to immediately after the result ptr. 64 1.1 joerg if (!UnexpArgTokens.empty()) { 65 1.1 joerg static_assert(std::is_trivial<Token>::value, 66 1.1 joerg "assume trivial copyability if copying into the " 67 1.1 joerg "uninitialized array (as opposed to reusing a cached " 68 1.1 joerg "MacroArgs)"); 69 1.1 joerg std::copy(UnexpArgTokens.begin(), UnexpArgTokens.end(), 70 1.1 joerg Result->getTrailingObjects<Token>()); 71 1.1 joerg } 72 1.1 joerg 73 1.1 joerg return Result; 74 1.1 joerg } 75 1.1 joerg 76 1.1 joerg /// destroy - Destroy and deallocate the memory for this object. 77 1.1 joerg /// 78 1.1 joerg void MacroArgs::destroy(Preprocessor &PP) { 79 1.1 joerg // Don't clear PreExpArgTokens, just clear the entries. Clearing the entries 80 1.1 joerg // would deallocate the element vectors. 81 1.1 joerg for (unsigned i = 0, e = PreExpArgTokens.size(); i != e; ++i) 82 1.1 joerg PreExpArgTokens[i].clear(); 83 1.1 joerg 84 1.1 joerg // Add this to the preprocessor's free list. 85 1.1 joerg ArgCache = PP.MacroArgCache; 86 1.1 joerg PP.MacroArgCache = this; 87 1.1 joerg } 88 1.1 joerg 89 1.1 joerg /// deallocate - This should only be called by the Preprocessor when managing 90 1.1 joerg /// its freelist. 91 1.1 joerg MacroArgs *MacroArgs::deallocate() { 92 1.1 joerg MacroArgs *Next = ArgCache; 93 1.1 joerg 94 1.1 joerg // Run the dtor to deallocate the vectors. 95 1.1 joerg this->~MacroArgs(); 96 1.1 joerg // Release the memory for the object. 97 1.1 joerg static_assert(std::is_trivially_destructible<Token>::value, 98 1.1 joerg "assume trivially destructible and forego destructors"); 99 1.1 joerg free(this); 100 1.1 joerg 101 1.1 joerg return Next; 102 1.1 joerg } 103 1.1 joerg 104 1.1 joerg 105 1.1 joerg /// getArgLength - Given a pointer to an expanded or unexpanded argument, 106 1.1 joerg /// return the number of tokens, not counting the EOF, that make up the 107 1.1 joerg /// argument. 108 1.1 joerg unsigned MacroArgs::getArgLength(const Token *ArgPtr) { 109 1.1 joerg unsigned NumArgTokens = 0; 110 1.1 joerg for (; ArgPtr->isNot(tok::eof); ++ArgPtr) 111 1.1 joerg ++NumArgTokens; 112 1.1 joerg return NumArgTokens; 113 1.1 joerg } 114 1.1 joerg 115 1.1 joerg 116 1.1 joerg /// getUnexpArgument - Return the unexpanded tokens for the specified formal. 117 1.1 joerg /// 118 1.1 joerg const Token *MacroArgs::getUnexpArgument(unsigned Arg) const { 119 1.1 joerg 120 1.1 joerg assert(Arg < getNumMacroArguments() && "Invalid arg #"); 121 1.1 joerg // The unexpanded argument tokens start immediately after the MacroArgs object 122 1.1 joerg // in memory. 123 1.1 joerg const Token *Start = getTrailingObjects<Token>(); 124 1.1 joerg const Token *Result = Start; 125 1.1 joerg 126 1.1 joerg // Scan to find Arg. 127 1.1 joerg for (; Arg; ++Result) { 128 1.1 joerg assert(Result < Start+NumUnexpArgTokens && "Invalid arg #"); 129 1.1 joerg if (Result->is(tok::eof)) 130 1.1 joerg --Arg; 131 1.1 joerg } 132 1.1 joerg assert(Result < Start+NumUnexpArgTokens && "Invalid arg #"); 133 1.1 joerg return Result; 134 1.1 joerg } 135 1.1 joerg 136 1.1 joerg bool MacroArgs::invokedWithVariadicArgument(const MacroInfo *const MI, 137 1.1 joerg Preprocessor &PP) { 138 1.1 joerg if (!MI->isVariadic()) 139 1.1 joerg return false; 140 1.1 joerg const int VariadicArgIndex = getNumMacroArguments() - 1; 141 1.1 joerg return getPreExpArgument(VariadicArgIndex, PP).front().isNot(tok::eof); 142 1.1 joerg } 143 1.1 joerg 144 1.1 joerg /// ArgNeedsPreexpansion - If we can prove that the argument won't be affected 145 1.1 joerg /// by pre-expansion, return false. Otherwise, conservatively return true. 146 1.1 joerg bool MacroArgs::ArgNeedsPreexpansion(const Token *ArgTok, 147 1.1 joerg Preprocessor &PP) const { 148 1.1 joerg // If there are no identifiers in the argument list, or if the identifiers are 149 1.1 joerg // known to not be macros, pre-expansion won't modify it. 150 1.1 joerg for (; ArgTok->isNot(tok::eof); ++ArgTok) 151 1.1 joerg if (IdentifierInfo *II = ArgTok->getIdentifierInfo()) 152 1.1 joerg if (II->hasMacroDefinition()) 153 1.1 joerg // Return true even though the macro could be a function-like macro 154 1.1 joerg // without a following '(' token, or could be disabled, or not visible. 155 1.1 joerg return true; 156 1.1 joerg return false; 157 1.1 joerg } 158 1.1 joerg 159 1.1 joerg /// getPreExpArgument - Return the pre-expanded form of the specified 160 1.1 joerg /// argument. 161 1.1 joerg const std::vector<Token> &MacroArgs::getPreExpArgument(unsigned Arg, 162 1.1 joerg Preprocessor &PP) { 163 1.1 joerg assert(Arg < getNumMacroArguments() && "Invalid argument number!"); 164 1.1 joerg 165 1.1 joerg // If we have already computed this, return it. 166 1.1 joerg if (PreExpArgTokens.size() < getNumMacroArguments()) 167 1.1 joerg PreExpArgTokens.resize(getNumMacroArguments()); 168 1.1 joerg 169 1.1 joerg std::vector<Token> &Result = PreExpArgTokens[Arg]; 170 1.1 joerg if (!Result.empty()) return Result; 171 1.1 joerg 172 1.1 joerg SaveAndRestore<bool> PreExpandingMacroArgs(PP.InMacroArgPreExpansion, true); 173 1.1 joerg 174 1.1 joerg const Token *AT = getUnexpArgument(Arg); 175 1.1 joerg unsigned NumToks = getArgLength(AT)+1; // Include the EOF. 176 1.1 joerg 177 1.1 joerg // Otherwise, we have to pre-expand this argument, populating Result. To do 178 1.1 joerg // this, we set up a fake TokenLexer to lex from the unexpanded argument 179 1.1 joerg // list. With this installed, we lex expanded tokens until we hit the EOF 180 1.1 joerg // token at the end of the unexp list. 181 1.1 joerg PP.EnterTokenStream(AT, NumToks, false /*disable expand*/, 182 1.1 joerg false /*owns tokens*/, false /*is reinject*/); 183 1.1 joerg 184 1.1 joerg // Lex all of the macro-expanded tokens into Result. 185 1.1 joerg do { 186 1.1 joerg Result.push_back(Token()); 187 1.1 joerg Token &Tok = Result.back(); 188 1.1 joerg PP.Lex(Tok); 189 1.1 joerg } while (Result.back().isNot(tok::eof)); 190 1.1 joerg 191 1.1 joerg // Pop the token stream off the top of the stack. We know that the internal 192 1.1 joerg // pointer inside of it is to the "end" of the token stream, but the stack 193 1.1 joerg // will not otherwise be popped until the next token is lexed. The problem is 194 1.1 joerg // that the token may be lexed sometime after the vector of tokens itself is 195 1.1 joerg // destroyed, which would be badness. 196 1.1 joerg if (PP.InCachingLexMode()) 197 1.1 joerg PP.ExitCachingLexMode(); 198 1.1 joerg PP.RemoveTopOfLexerStack(); 199 1.1 joerg return Result; 200 1.1 joerg } 201 1.1 joerg 202 1.1 joerg 203 1.1 joerg /// StringifyArgument - Implement C99 6.10.3.2p2, converting a sequence of 204 1.1 joerg /// tokens into the literal string token that should be produced by the C # 205 1.1 joerg /// preprocessor operator. If Charify is true, then it should be turned into 206 1.1 joerg /// a character literal for the Microsoft charize (#@) extension. 207 1.1 joerg /// 208 1.1 joerg Token MacroArgs::StringifyArgument(const Token *ArgToks, 209 1.1 joerg Preprocessor &PP, bool Charify, 210 1.1 joerg SourceLocation ExpansionLocStart, 211 1.1 joerg SourceLocation ExpansionLocEnd) { 212 1.1 joerg Token Tok; 213 1.1 joerg Tok.startToken(); 214 1.1 joerg Tok.setKind(Charify ? tok::char_constant : tok::string_literal); 215 1.1 joerg 216 1.1 joerg const Token *ArgTokStart = ArgToks; 217 1.1 joerg 218 1.1 joerg // Stringify all the tokens. 219 1.1 joerg SmallString<128> Result; 220 1.1 joerg Result += "\""; 221 1.1 joerg 222 1.1 joerg bool isFirst = true; 223 1.1 joerg for (; ArgToks->isNot(tok::eof); ++ArgToks) { 224 1.1 joerg const Token &Tok = *ArgToks; 225 1.1 joerg if (!isFirst && (Tok.hasLeadingSpace() || Tok.isAtStartOfLine())) 226 1.1 joerg Result += ' '; 227 1.1 joerg isFirst = false; 228 1.1 joerg 229 1.1 joerg // If this is a string or character constant, escape the token as specified 230 1.1 joerg // by 6.10.3.2p2. 231 1.1 joerg if (tok::isStringLiteral(Tok.getKind()) || // "foo", u8R"x(foo)x"_bar, etc. 232 1.1 joerg Tok.is(tok::char_constant) || // 'x' 233 1.1 joerg Tok.is(tok::wide_char_constant) || // L'x'. 234 1.1 joerg Tok.is(tok::utf8_char_constant) || // u8'x'. 235 1.1 joerg Tok.is(tok::utf16_char_constant) || // u'x'. 236 1.1 joerg Tok.is(tok::utf32_char_constant)) { // U'x'. 237 1.1 joerg bool Invalid = false; 238 1.1 joerg std::string TokStr = PP.getSpelling(Tok, &Invalid); 239 1.1 joerg if (!Invalid) { 240 1.1 joerg std::string Str = Lexer::Stringify(TokStr); 241 1.1 joerg Result.append(Str.begin(), Str.end()); 242 1.1 joerg } 243 1.1 joerg } else if (Tok.is(tok::code_completion)) { 244 1.1 joerg PP.CodeCompleteNaturalLanguage(); 245 1.1 joerg } else { 246 1.1 joerg // Otherwise, just append the token. Do some gymnastics to get the token 247 1.1 joerg // in place and avoid copies where possible. 248 1.1 joerg unsigned CurStrLen = Result.size(); 249 1.1 joerg Result.resize(CurStrLen+Tok.getLength()); 250 1.1 joerg const char *BufPtr = Result.data() + CurStrLen; 251 1.1 joerg bool Invalid = false; 252 1.1 joerg unsigned ActualTokLen = PP.getSpelling(Tok, BufPtr, &Invalid); 253 1.1 joerg 254 1.1 joerg if (!Invalid) { 255 1.1 joerg // If getSpelling returned a pointer to an already uniqued version of 256 1.1 joerg // the string instead of filling in BufPtr, memcpy it onto our string. 257 1.1 joerg if (ActualTokLen && BufPtr != &Result[CurStrLen]) 258 1.1 joerg memcpy(&Result[CurStrLen], BufPtr, ActualTokLen); 259 1.1 joerg 260 1.1 joerg // If the token was dirty, the spelling may be shorter than the token. 261 1.1 joerg if (ActualTokLen != Tok.getLength()) 262 1.1 joerg Result.resize(CurStrLen+ActualTokLen); 263 1.1 joerg } 264 1.1 joerg } 265 1.1 joerg } 266 1.1 joerg 267 1.1 joerg // If the last character of the string is a \, and if it isn't escaped, this 268 1.1 joerg // is an invalid string literal, diagnose it as specified in C99. 269 1.1 joerg if (Result.back() == '\\') { 270 1.1 joerg // Count the number of consecutive \ characters. If even, then they are 271 1.1 joerg // just escaped backslashes, otherwise it's an error. 272 1.1 joerg unsigned FirstNonSlash = Result.size()-2; 273 1.1 joerg // Guaranteed to find the starting " if nothing else. 274 1.1 joerg while (Result[FirstNonSlash] == '\\') 275 1.1 joerg --FirstNonSlash; 276 1.1 joerg if ((Result.size()-1-FirstNonSlash) & 1) { 277 1.1 joerg // Diagnose errors for things like: #define F(X) #X / F(\) 278 1.1 joerg PP.Diag(ArgToks[-1], diag::pp_invalid_string_literal); 279 1.1 joerg Result.pop_back(); // remove one of the \'s. 280 1.1 joerg } 281 1.1 joerg } 282 1.1 joerg Result += '"'; 283 1.1 joerg 284 1.1 joerg // If this is the charify operation and the result is not a legal character 285 1.1 joerg // constant, diagnose it. 286 1.1 joerg if (Charify) { 287 1.1 joerg // First step, turn double quotes into single quotes: 288 1.1 joerg Result[0] = '\''; 289 1.1 joerg Result[Result.size()-1] = '\''; 290 1.1 joerg 291 1.1 joerg // Check for bogus character. 292 1.1 joerg bool isBad = false; 293 1.1 joerg if (Result.size() == 3) 294 1.1 joerg isBad = Result[1] == '\''; // ''' is not legal. '\' already fixed above. 295 1.1 joerg else 296 1.1 joerg isBad = (Result.size() != 4 || Result[1] != '\\'); // Not '\x' 297 1.1 joerg 298 1.1 joerg if (isBad) { 299 1.1 joerg PP.Diag(ArgTokStart[0], diag::err_invalid_character_to_charify); 300 1.1 joerg Result = "' '"; // Use something arbitrary, but legal. 301 1.1 joerg } 302 1.1 joerg } 303 1.1 joerg 304 1.1 joerg PP.CreateString(Result, Tok, 305 1.1 joerg ExpansionLocStart, ExpansionLocEnd); 306 1.1 joerg return Tok; 307 1.1 joerg } 308