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