/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/clang/include/clang/Lex/MacroInfo.h
Line | Count | Source (jump to first uncovered line) |
1 | | //===- MacroInfo.h - Information about #defined identifiers -----*- 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 | | /// \file |
10 | | /// Defines the clang::MacroInfo and clang::MacroDirective classes. |
11 | | // |
12 | | //===----------------------------------------------------------------------===// |
13 | | |
14 | | #ifndef LLVM_CLANG_LEX_MACROINFO_H |
15 | | #define LLVM_CLANG_LEX_MACROINFO_H |
16 | | |
17 | | #include "clang/Lex/Token.h" |
18 | | #include "clang/Basic/LLVM.h" |
19 | | #include "clang/Basic/SourceLocation.h" |
20 | | #include "llvm/ADT/ArrayRef.h" |
21 | | #include "llvm/ADT/FoldingSet.h" |
22 | | #include "llvm/ADT/PointerIntPair.h" |
23 | | #include "llvm/ADT/SmallVector.h" |
24 | | #include "llvm/Support/Allocator.h" |
25 | | #include <algorithm> |
26 | | #include <cassert> |
27 | | |
28 | | namespace clang { |
29 | | |
30 | | class DefMacroDirective; |
31 | | class IdentifierInfo; |
32 | | class Module; |
33 | | class Preprocessor; |
34 | | class SourceManager; |
35 | | |
36 | | /// Encapsulates the data about a macro definition (e.g. its tokens). |
37 | | /// |
38 | | /// There's an instance of this class for every #define. |
39 | | class MacroInfo { |
40 | | //===--------------------------------------------------------------------===// |
41 | | // State set when the macro is defined. |
42 | | |
43 | | /// The location the macro is defined. |
44 | | SourceLocation Location; |
45 | | |
46 | | /// The location of the last token in the macro. |
47 | | SourceLocation EndLocation; |
48 | | |
49 | | /// The list of arguments for a function-like macro. |
50 | | /// |
51 | | /// ParameterList points to the first of NumParameters pointers. |
52 | | /// |
53 | | /// This can be empty, for, e.g. "#define X()". In a C99-style variadic |
54 | | /// macro, this includes the \c __VA_ARGS__ identifier on the list. |
55 | | IdentifierInfo **ParameterList = nullptr; |
56 | | |
57 | | /// \see ParameterList |
58 | | unsigned NumParameters = 0; |
59 | | |
60 | | /// This is the list of tokens that the macro is defined to. |
61 | | SmallVector<Token, 8> ReplacementTokens; |
62 | | |
63 | | /// Length in characters of the macro definition. |
64 | | mutable unsigned DefinitionLength; |
65 | | mutable bool IsDefinitionLengthCached : 1; |
66 | | |
67 | | /// True if this macro is function-like, false if it is object-like. |
68 | | bool IsFunctionLike : 1; |
69 | | |
70 | | /// True if this macro is of the form "#define X(...)" or |
71 | | /// "#define X(Y,Z,...)". |
72 | | /// |
73 | | /// The __VA_ARGS__ token should be replaced with the contents of "..." in an |
74 | | /// invocation. |
75 | | bool IsC99Varargs : 1; |
76 | | |
77 | | /// True if this macro is of the form "#define X(a...)". |
78 | | /// |
79 | | /// The "a" identifier in the replacement list will be replaced with all |
80 | | /// arguments of the macro starting with the specified one. |
81 | | bool IsGNUVarargs : 1; |
82 | | |
83 | | /// True if this macro requires processing before expansion. |
84 | | /// |
85 | | /// This is the case for builtin macros such as __LINE__, so long as they have |
86 | | /// not been redefined, but not for regular predefined macros from the |
87 | | /// "<built-in>" memory buffer (see Preprocessing::getPredefinesFileID). |
88 | | bool IsBuiltinMacro : 1; |
89 | | |
90 | | /// Whether this macro contains the sequence ", ## __VA_ARGS__" |
91 | | bool HasCommaPasting : 1; |
92 | | |
93 | | //===--------------------------------------------------------------------===// |
94 | | // State that changes as the macro is used. |
95 | | |
96 | | /// True if we have started an expansion of this macro already. |
97 | | /// |
98 | | /// This disables recursive expansion, which would be quite bad for things |
99 | | /// like \#define A A. |
100 | | bool IsDisabled : 1; |
101 | | |
102 | | /// True if this macro is either defined in the main file and has |
103 | | /// been used, or if it is not defined in the main file. |
104 | | /// |
105 | | /// This is used to emit -Wunused-macros diagnostics. |
106 | | bool IsUsed : 1; |
107 | | |
108 | | /// True if this macro can be redefined without emitting a warning. |
109 | | bool IsAllowRedefinitionsWithoutWarning : 1; |
110 | | |
111 | | /// Must warn if the macro is unused at the end of translation unit. |
112 | | bool IsWarnIfUnused : 1; |
113 | | |
114 | | /// Whether this macro was used as header guard. |
115 | | bool UsedForHeaderGuard : 1; |
116 | | |
117 | | // Only the Preprocessor gets to create and destroy these. |
118 | | MacroInfo(SourceLocation DefLoc); |
119 | 12.7M | ~MacroInfo() = default; |
120 | | |
121 | | public: |
122 | | /// Return the location that the macro was defined at. |
123 | 67.9M | SourceLocation getDefinitionLoc() const { return Location; } |
124 | | |
125 | | /// Set the location of the last token in the macro. |
126 | 25.1M | void setDefinitionEndLoc(SourceLocation EndLoc) { EndLocation = EndLoc; } |
127 | | |
128 | | /// Return the location of the last token in the macro. |
129 | 1.33M | SourceLocation getDefinitionEndLoc() const { return EndLocation; } |
130 | | |
131 | | /// Get length in characters of the macro definition. |
132 | 12.9M | unsigned getDefinitionLength(const SourceManager &SM) const { |
133 | 12.9M | if (IsDefinitionLengthCached) |
134 | 12.4M | return DefinitionLength; |
135 | 502k | return getDefinitionLengthSlow(SM); |
136 | 502k | } |
137 | | |
138 | | /// Return true if the specified macro definition is equal to |
139 | | /// this macro in spelling, arguments, and whitespace. |
140 | | /// |
141 | | /// \param Syntactically if true, the macro definitions can be identical even |
142 | | /// if they use different identifiers for the function macro parameters. |
143 | | /// Otherwise the comparison is lexical and this implements the rules in |
144 | | /// C99 6.10.3. |
145 | | bool isIdenticalTo(const MacroInfo &Other, Preprocessor &PP, |
146 | | bool Syntactically) const; |
147 | | |
148 | | /// Set or clear the isBuiltinMacro flag. |
149 | 1.13M | void setIsBuiltinMacro(bool Val = true) { IsBuiltinMacro = Val; } |
150 | | |
151 | | /// Set the value of the IsUsed flag. |
152 | 18.4M | void setIsUsed(bool Val) { IsUsed = Val; } |
153 | | |
154 | | /// Set the value of the IsAllowRedefinitionsWithoutWarning flag. |
155 | 9 | void setIsAllowRedefinitionsWithoutWarning(bool Val) { |
156 | 9 | IsAllowRedefinitionsWithoutWarning = Val; |
157 | 9 | } |
158 | | |
159 | | /// Set the value of the IsWarnIfUnused flag. |
160 | 18 | void setIsWarnIfUnused(bool val) { IsWarnIfUnused = val; } |
161 | | |
162 | | /// Set the specified list of identifiers as the parameter list for |
163 | | /// this macro. |
164 | | void setParameterList(ArrayRef<IdentifierInfo *> List, |
165 | 3.56M | llvm::BumpPtrAllocator &PPAllocator) { |
166 | 3.56M | assert(ParameterList == nullptr && NumParameters == 0 && |
167 | 3.56M | "Parameter list already set!"); |
168 | 3.56M | if (List.empty()) |
169 | 10 | return; |
170 | 3.56M | |
171 | 3.56M | NumParameters = List.size(); |
172 | 3.56M | ParameterList = PPAllocator.Allocate<IdentifierInfo *>(List.size()); |
173 | 3.56M | std::copy(List.begin(), List.end(), ParameterList); |
174 | 3.56M | } |
175 | | |
176 | | /// Parameters - The list of parameters for a function-like macro. This can |
177 | | /// be empty, for, e.g. "#define X()". |
178 | | using param_iterator = IdentifierInfo *const *; |
179 | 49 | bool param_empty() const { return NumParameters == 0; } |
180 | 28.3M | param_iterator param_begin() const { return ParameterList; } |
181 | 20.7M | param_iterator param_end() const { return ParameterList + NumParameters; } |
182 | 18.4M | unsigned getNumParams() const { return NumParameters; } |
183 | 13.0k | ArrayRef<const IdentifierInfo *> params() const { |
184 | 13.0k | return ArrayRef<const IdentifierInfo *>(ParameterList, NumParameters); |
185 | 13.0k | } |
186 | | |
187 | | /// Return the parameter number of the specified identifier, |
188 | | /// or -1 if the identifier is not a formal parameter identifier. |
189 | 19.4M | int getParameterNum(const IdentifierInfo *Arg) const { |
190 | 45.8M | for (param_iterator I = param_begin(), E = param_end(); I != E; ++I26.4M ) |
191 | 34.1M | if (*I == Arg) |
192 | 7.77M | return I - param_begin(); |
193 | 19.4M | return -111.6M ; |
194 | 19.4M | } |
195 | | |
196 | | /// Function/Object-likeness. Keep track of whether this macro has formal |
197 | | /// parameters. |
198 | 3.58M | void setIsFunctionLike() { IsFunctionLike = true; } |
199 | 50.9M | bool isFunctionLike() const { return IsFunctionLike; } |
200 | 28.7M | bool isObjectLike() const { return !IsFunctionLike; } |
201 | | |
202 | | /// Varargs querying methods. This can only be set for function-like macros. |
203 | 71.4k | void setIsC99Varargs() { IsC99Varargs = true; } |
204 | 117 | void setIsGNUVarargs() { IsGNUVarargs = true; } |
205 | 4.22M | bool isC99Varargs() const { return IsC99Varargs; } |
206 | 638k | bool isGNUVarargs() const { return IsGNUVarargs; } |
207 | 4.83M | bool isVariadic() const { return IsC99Varargs | IsGNUVarargs; } |
208 | | |
209 | | /// Return true if this macro requires processing before expansion. |
210 | | /// |
211 | | /// This is true only for builtin macro, such as \__LINE__, whose values |
212 | | /// are not given by fixed textual expansions. Regular predefined macros |
213 | | /// from the "<built-in>" buffer are not reported as builtins by this |
214 | | /// function. |
215 | 22.5M | bool isBuiltinMacro() const { return IsBuiltinMacro; } |
216 | | |
217 | 13.9k | bool hasCommaPasting() const { return HasCommaPasting; } |
218 | 463 | void setHasCommaPasting() { HasCommaPasting = true; } |
219 | | |
220 | | /// Return false if this macro is defined in the main file and has |
221 | | /// not yet been used. |
222 | 1.20M | bool isUsed() const { return IsUsed; } |
223 | | |
224 | | /// Return true if this macro can be redefined without warning. |
225 | 312k | bool isAllowRedefinitionsWithoutWarning() const { |
226 | 312k | return IsAllowRedefinitionsWithoutWarning; |
227 | 312k | } |
228 | | |
229 | | /// Return true if we should emit a warning if the macro is unused. |
230 | 19.4M | bool isWarnIfUnused() const { return IsWarnIfUnused; } |
231 | | |
232 | | /// Return the number of tokens that this macro expands to. |
233 | 60.3M | unsigned getNumTokens() const { return ReplacementTokens.size(); } |
234 | | |
235 | 58.8M | const Token &getReplacementToken(unsigned Tok) const { |
236 | 58.8M | assert(Tok < ReplacementTokens.size() && "Invalid token #"); |
237 | 58.8M | return ReplacementTokens[Tok]; |
238 | 58.8M | } |
239 | | |
240 | | using tokens_iterator = SmallVectorImpl<Token>::const_iterator; |
241 | | |
242 | 26.2M | tokens_iterator tokens_begin() const { return ReplacementTokens.begin(); } |
243 | 12.9M | tokens_iterator tokens_end() const { return ReplacementTokens.end(); } |
244 | 427k | bool tokens_empty() const { return ReplacementTokens.empty(); } |
245 | 428k | ArrayRef<Token> tokens() const { return ReplacementTokens; } |
246 | | |
247 | | /// Add the specified token to the replacement text for the macro. |
248 | 127M | void AddTokenToBody(const Token &Tok) { |
249 | 127M | assert( |
250 | 127M | !IsDefinitionLengthCached && |
251 | 127M | "Changing replacement tokens after definition length got calculated"); |
252 | 127M | ReplacementTokens.push_back(Tok); |
253 | 127M | } |
254 | | |
255 | | /// Return true if this macro is enabled. |
256 | | /// |
257 | | /// In other words, that we are not currently in an expansion of this macro. |
258 | 22.7M | bool isEnabled() const { return !IsDisabled; } |
259 | | |
260 | 12.9M | void EnableMacro() { |
261 | 12.9M | assert(IsDisabled && "Cannot enable an already-enabled macro!"); |
262 | 12.9M | IsDisabled = false; |
263 | 12.9M | } |
264 | | |
265 | 12.9M | void DisableMacro() { |
266 | 12.9M | assert(!IsDisabled && "Cannot disable an already-disabled macro!"); |
267 | 12.9M | IsDisabled = true; |
268 | 12.9M | } |
269 | | |
270 | | /// Determine whether this macro was used for a header guard. |
271 | 878k | bool isUsedForHeaderGuard() const { return UsedForHeaderGuard; } |
272 | | |
273 | 434k | void setUsedForHeaderGuard(bool Val) { UsedForHeaderGuard = Val; } |
274 | | |
275 | | void dump() const; |
276 | | |
277 | | private: |
278 | | friend class Preprocessor; |
279 | | |
280 | | unsigned getDefinitionLengthSlow(const SourceManager &SM) const; |
281 | | }; |
282 | | |
283 | | /// Encapsulates changes to the "macros namespace" (the location where |
284 | | /// the macro name became active, the location where it was undefined, etc.). |
285 | | /// |
286 | | /// MacroDirectives, associated with an identifier, are used to model the macro |
287 | | /// history. Usually a macro definition (MacroInfo) is where a macro name |
288 | | /// becomes active (MacroDirective) but #pragma push_macro / pop_macro can |
289 | | /// create additional DefMacroDirectives for the same MacroInfo. |
290 | | class MacroDirective { |
291 | | public: |
292 | | enum Kind { |
293 | | MD_Define, |
294 | | MD_Undefine, |
295 | | MD_Visibility |
296 | | }; |
297 | | |
298 | | protected: |
299 | | /// Previous macro directive for the same identifier, or nullptr. |
300 | | MacroDirective *Previous = nullptr; |
301 | | |
302 | | SourceLocation Loc; |
303 | | |
304 | | /// MacroDirective kind. |
305 | | unsigned MDKind : 2; |
306 | | |
307 | | /// True if the macro directive was loaded from a PCH file. |
308 | | unsigned IsFromPCH : 1; |
309 | | |
310 | | // Used by VisibilityMacroDirective ----------------------------------------// |
311 | | |
312 | | /// Whether the macro has public visibility (when described in a |
313 | | /// module). |
314 | | unsigned IsPublic : 1; |
315 | | |
316 | | MacroDirective(Kind K, SourceLocation Loc) |
317 | 26.4M | : Loc(Loc), MDKind(K), IsFromPCH(false), IsPublic(true) {} |
318 | | |
319 | | public: |
320 | 149M | Kind getKind() const { return Kind(MDKind); } |
321 | | |
322 | 1.52M | SourceLocation getLocation() const { return Loc; } |
323 | | |
324 | | /// Set previous definition of the macro with the same name. |
325 | 26.3M | void setPrevious(MacroDirective *Prev) { Previous = Prev; } |
326 | | |
327 | | /// Get previous definition of the macro with the same name. |
328 | 0 | const MacroDirective *getPrevious() const { return Previous; } |
329 | | |
330 | | /// Get previous definition of the macro with the same name. |
331 | 877k | MacroDirective *getPrevious() { return Previous; } |
332 | | |
333 | | /// Return true if the macro directive was loaded from a PCH file. |
334 | 0 | bool isFromPCH() const { return IsFromPCH; } |
335 | | |
336 | 0 | void setIsFromPCH() { IsFromPCH = true; } |
337 | | |
338 | | class DefInfo { |
339 | | DefMacroDirective *DefDirective = nullptr; |
340 | | SourceLocation UndefLoc; |
341 | | bool IsPublic = true; |
342 | | |
343 | | public: |
344 | 2.52k | DefInfo() = default; |
345 | | DefInfo(DefMacroDirective *DefDirective, SourceLocation UndefLoc, |
346 | | bool isPublic) |
347 | 82.1M | : DefDirective(DefDirective), UndefLoc(UndefLoc), IsPublic(isPublic) {} |
348 | | |
349 | 0 | const DefMacroDirective *getDirective() const { return DefDirective; } |
350 | 15 | DefMacroDirective *getDirective() { return DefDirective; } |
351 | | |
352 | | inline SourceLocation getLocation() const; |
353 | | inline MacroInfo *getMacroInfo(); |
354 | | |
355 | 1.52M | const MacroInfo *getMacroInfo() const { |
356 | 1.52M | return const_cast<DefInfo *>(this)->getMacroInfo(); |
357 | 1.52M | } |
358 | | |
359 | 254 | SourceLocation getUndefLocation() const { return UndefLoc; } |
360 | 26.9M | bool isUndefined() const { return UndefLoc.isValid(); } |
361 | | |
362 | 0 | bool isPublic() const { return IsPublic; } |
363 | | |
364 | 82.6M | bool isValid() const { return DefDirective != nullptr; } |
365 | 55.5M | bool isInvalid() const { return !isValid(); } |
366 | | |
367 | 27.0M | explicit operator bool() const { return isValid(); } |
368 | | |
369 | | inline DefInfo getPreviousDefinition(); |
370 | | |
371 | 0 | const DefInfo getPreviousDefinition() const { |
372 | 0 | return const_cast<DefInfo *>(this)->getPreviousDefinition(); |
373 | 0 | } |
374 | | }; |
375 | | |
376 | | /// Traverses the macro directives history and returns the next |
377 | | /// macro definition directive along with info about its undefined location |
378 | | /// (if there is one) and if it is public or private. |
379 | | DefInfo getDefinition(); |
380 | 28.2M | const DefInfo getDefinition() const { |
381 | 28.2M | return const_cast<MacroDirective *>(this)->getDefinition(); |
382 | 28.2M | } |
383 | | |
384 | 26.8M | bool isDefined() const { |
385 | 26.8M | if (const DefInfo Def = getDefinition()) |
386 | 26.8M | return !Def.isUndefined(); |
387 | 105 | return false; |
388 | 105 | } |
389 | | |
390 | 1.36M | const MacroInfo *getMacroInfo() const { |
391 | 1.36M | return getDefinition().getMacroInfo(); |
392 | 1.36M | } |
393 | 53.8M | MacroInfo *getMacroInfo() { return getDefinition().getMacroInfo(); } |
394 | | |
395 | | /// Find macro definition active in the specified source location. If |
396 | | /// this macro was not defined there, return NULL. |
397 | | const DefInfo findDirectiveAtLoc(SourceLocation L, |
398 | | const SourceManager &SM) const; |
399 | | |
400 | | void dump() const; |
401 | | |
402 | 0 | static bool classof(const MacroDirective *) { return true; } |
403 | | }; |
404 | | |
405 | | /// A directive for a defined macro or a macro imported from a module. |
406 | | class DefMacroDirective : public MacroDirective { |
407 | | MacroInfo *Info; |
408 | | |
409 | | public: |
410 | | DefMacroDirective(MacroInfo *MI, SourceLocation Loc) |
411 | 26.2M | : MacroDirective(MD_Define, Loc), Info(MI) { |
412 | 26.2M | assert(MI && "MacroInfo is null"); |
413 | 26.2M | } |
414 | | explicit DefMacroDirective(MacroInfo *MI) |
415 | 0 | : DefMacroDirective(MI, MI->getDefinitionLoc()) {} |
416 | | |
417 | | /// The data for the macro definition. |
418 | 0 | const MacroInfo *getInfo() const { return Info; } |
419 | 56.2M | MacroInfo *getInfo() { return Info; } |
420 | | |
421 | 115M | static bool classof(const MacroDirective *MD) { |
422 | 115M | return MD->getKind() == MD_Define; |
423 | 115M | } |
424 | | |
425 | 0 | static bool classof(const DefMacroDirective *) { return true; } |
426 | | }; |
427 | | |
428 | | /// A directive for an undefined macro. |
429 | | class UndefMacroDirective : public MacroDirective { |
430 | | public: |
431 | | explicit UndefMacroDirective(SourceLocation UndefLoc) |
432 | 137k | : MacroDirective(MD_Undefine, UndefLoc) { |
433 | 137k | assert(UndefLoc.isValid() && "Invalid UndefLoc!"); |
434 | 137k | } |
435 | | |
436 | 138k | static bool classof(const MacroDirective *MD) { |
437 | 138k | return MD->getKind() == MD_Undefine; |
438 | 138k | } |
439 | | |
440 | 0 | static bool classof(const UndefMacroDirective *) { return true; } |
441 | | }; |
442 | | |
443 | | /// A directive for setting the module visibility of a macro. |
444 | | class VisibilityMacroDirective : public MacroDirective { |
445 | | public: |
446 | | explicit VisibilityMacroDirective(SourceLocation Loc, bool Public) |
447 | 174 | : MacroDirective(MD_Visibility, Loc) { |
448 | 174 | IsPublic = Public; |
449 | 174 | } |
450 | | |
451 | | /// Determine whether this macro is part of the public API of its |
452 | | /// module. |
453 | 645 | bool isPublic() const { return IsPublic; } |
454 | | |
455 | 32.5M | static bool classof(const MacroDirective *MD) { |
456 | 32.5M | return MD->getKind() == MD_Visibility; |
457 | 32.5M | } |
458 | | |
459 | 0 | static bool classof(const VisibilityMacroDirective *) { return true; } |
460 | | }; |
461 | | |
462 | 109k | inline SourceLocation MacroDirective::DefInfo::getLocation() const { |
463 | 109k | if (isInvalid()) |
464 | 0 | return {}; |
465 | 109k | return DefDirective->getLocation(); |
466 | 109k | } |
467 | | |
468 | 55.4M | inline MacroInfo *MacroDirective::DefInfo::getMacroInfo() { |
469 | 55.4M | if (isInvalid()) |
470 | 0 | return nullptr; |
471 | 55.4M | return DefDirective->getInfo(); |
472 | 55.4M | } |
473 | | |
474 | | inline MacroDirective::DefInfo |
475 | 2.39k | MacroDirective::DefInfo::getPreviousDefinition() { |
476 | 2.39k | if (isInvalid() || DefDirective->getPrevious() == nullptr) |
477 | 2.23k | return {}; |
478 | 162 | return DefDirective->getPrevious()->getDefinition(); |
479 | 162 | } |
480 | | |
481 | | /// Represents a macro directive exported by a module. |
482 | | /// |
483 | | /// There's an instance of this class for every macro #define or #undef that is |
484 | | /// the final directive for a macro name within a module. These entities also |
485 | | /// represent the macro override graph. |
486 | | /// |
487 | | /// These are stored in a FoldingSet in the preprocessor. |
488 | | class ModuleMacro : public llvm::FoldingSetNode { |
489 | | friend class Preprocessor; |
490 | | |
491 | | /// The name defined by the macro. |
492 | | IdentifierInfo *II; |
493 | | |
494 | | /// The body of the #define, or nullptr if this is a #undef. |
495 | | MacroInfo *Macro; |
496 | | |
497 | | /// The module that exports this macro. |
498 | | Module *OwningModule; |
499 | | |
500 | | /// The number of module macros that override this one. |
501 | | unsigned NumOverriddenBy = 0; |
502 | | |
503 | | /// The number of modules whose macros are directly overridden by this one. |
504 | | unsigned NumOverrides; |
505 | | |
506 | | ModuleMacro(Module *OwningModule, IdentifierInfo *II, MacroInfo *Macro, |
507 | | ArrayRef<ModuleMacro *> Overrides) |
508 | | : II(II), Macro(Macro), OwningModule(OwningModule), |
509 | 18.8k | NumOverrides(Overrides.size()) { |
510 | 18.8k | std::copy(Overrides.begin(), Overrides.end(), |
511 | 18.8k | reinterpret_cast<ModuleMacro **>(this + 1)); |
512 | 18.8k | } |
513 | | |
514 | | public: |
515 | | static ModuleMacro *create(Preprocessor &PP, Module *OwningModule, |
516 | | IdentifierInfo *II, MacroInfo *Macro, |
517 | | ArrayRef<ModuleMacro *> Overrides); |
518 | | |
519 | 48.4k | void Profile(llvm::FoldingSetNodeID &ID) const { |
520 | 48.4k | return Profile(ID, OwningModule, II); |
521 | 48.4k | } |
522 | | |
523 | | static void Profile(llvm::FoldingSetNodeID &ID, Module *OwningModule, |
524 | 67.4k | IdentifierInfo *II) { |
525 | 67.4k | ID.AddPointer(OwningModule); |
526 | 67.4k | ID.AddPointer(II); |
527 | 67.4k | } |
528 | | |
529 | | /// Get the name of the macro. |
530 | 0 | IdentifierInfo *getName() const { return II; } |
531 | | |
532 | | /// Get the ID of the module that exports this macro. |
533 | 20.5k | Module *getOwningModule() const { return OwningModule; } |
534 | | |
535 | | /// Get definition for this exported #define, or nullptr if this |
536 | | /// represents a #undef. |
537 | 22.3k | MacroInfo *getMacroInfo() const { return Macro; } |
538 | | |
539 | | /// Iterators over the overridden module IDs. |
540 | | /// \{ |
541 | | using overrides_iterator = ModuleMacro *const *; |
542 | | |
543 | 73.1k | overrides_iterator overrides_begin() const { |
544 | 73.1k | return reinterpret_cast<overrides_iterator>(this + 1); |
545 | 73.1k | } |
546 | | |
547 | 36.5k | overrides_iterator overrides_end() const { |
548 | 36.5k | return overrides_begin() + NumOverrides; |
549 | 36.5k | } |
550 | | |
551 | 36.5k | ArrayRef<ModuleMacro *> overrides() const { |
552 | 36.5k | return llvm::makeArrayRef(overrides_begin(), overrides_end()); |
553 | 36.5k | } |
554 | | /// \} |
555 | | |
556 | | /// Get the number of macros that override this one. |
557 | 187 | unsigned getNumOverridingMacros() const { return NumOverriddenBy; } |
558 | | }; |
559 | | |
560 | | /// A description of the current definition of a macro. |
561 | | /// |
562 | | /// The definition of a macro comprises a set of (at least one) defining |
563 | | /// entities, which are either local MacroDirectives or imported ModuleMacros. |
564 | | class MacroDefinition { |
565 | | llvm::PointerIntPair<DefMacroDirective *, 1, bool> LatestLocalAndAmbiguous; |
566 | | ArrayRef<ModuleMacro *> ModuleMacros; |
567 | | |
568 | | public: |
569 | 2.56M | MacroDefinition() = default; |
570 | | MacroDefinition(DefMacroDirective *MD, ArrayRef<ModuleMacro *> MMs, |
571 | | bool IsAmbiguous) |
572 | 32.5M | : LatestLocalAndAmbiguous(MD, IsAmbiguous), ModuleMacros(MMs) {} |
573 | | |
574 | | /// Determine whether there is a definition of this macro. |
575 | 34.8M | explicit operator bool() const { |
576 | 34.8M | return getLocalDirective() || !ModuleMacros.empty()2.69M ; |
577 | 34.8M | } |
578 | | |
579 | | /// Get the MacroInfo that should be used for this definition. |
580 | 53.1M | MacroInfo *getMacroInfo() const { |
581 | 53.1M | if (!ModuleMacros.empty()) |
582 | 2.15k | return ModuleMacros.back()->getMacroInfo(); |
583 | 53.1M | if (auto *MD = getLocalDirective()) |
584 | 51.9M | return MD->getMacroInfo(); |
585 | 1.20M | return nullptr; |
586 | 1.20M | } |
587 | | |
588 | | /// \c true if the definition is ambiguous, \c false otherwise. |
589 | 17.1M | bool isAmbiguous() const { return LatestLocalAndAmbiguous.getInt(); } |
590 | | |
591 | | /// Get the latest non-imported, non-\#undef'd macro definition |
592 | | /// for this macro. |
593 | 88.0M | DefMacroDirective *getLocalDirective() const { |
594 | 88.0M | return LatestLocalAndAmbiguous.getPointer(); |
595 | 88.0M | } |
596 | | |
597 | | /// Get the active module macros for this macro. |
598 | 115 | ArrayRef<ModuleMacro *> getModuleMacros() const { return ModuleMacros; } |
599 | | |
600 | 115 | template <typename Fn> void forAllDefinitions(Fn F) const { |
601 | 115 | if (auto *MD = getLocalDirective()) |
602 | 59 | F(MD->getMacroInfo()); |
603 | 115 | for (auto *MM : getModuleMacros()) |
604 | 97 | F(MM->getMacroInfo()); |
605 | 115 | } PPMacroExpansion.cpp:void clang::MacroDefinition::forAllDefinitions<clang::Preprocessor::HandleMacroExpandedIdentifier(clang::Token&, clang::MacroDefinition const&)::$_1>(clang::Preprocessor::HandleMacroExpandedIdentifier(clang::Token&, clang::MacroDefinition const&)::$_1) const Line | Count | Source | 600 | 45 | template <typename Fn> void forAllDefinitions(Fn F) const { | 601 | 45 | if (auto *MD = getLocalDirective()) | 602 | 13 | F(MD->getMacroInfo()); | 603 | 45 | for (auto *MM : getModuleMacros()) | 604 | 77 | F(MM->getMacroInfo()); | 605 | 45 | } |
PreprocessingRecord.cpp:void clang::MacroDefinition::forAllDefinitions<clang::PreprocessingRecord::MacroUndefined(clang::Token const&, clang::MacroDefinition const&, clang::MacroDirective const*)::$_0>(clang::PreprocessingRecord::MacroUndefined(clang::Token const&, clang::MacroDefinition const&, clang::MacroDirective const*)::$_0) const Line | Count | Source | 600 | 70 | template <typename Fn> void forAllDefinitions(Fn F) const { | 601 | 70 | if (auto *MD = getLocalDirective()) | 602 | 46 | F(MD->getMacroInfo()); | 603 | 70 | for (auto *MM : getModuleMacros()) | 604 | 20 | F(MM->getMacroInfo()); | 605 | 70 | } |
|
606 | | }; |
607 | | |
608 | | } // namespace clang |
609 | | |
610 | | #endif // LLVM_CLANG_LEX_MACROINFO_H |