1 //===--- MacroInfo.h - Information about #defined identifiers ---*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file defines the MacroInfo interface. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_CLANG_MACROINFO_H 15 #define LLVM_CLANG_MACROINFO_H 16 17 #include "clang/Lex/Token.h" 18 #include "llvm/ADT/SmallVector.h" 19 #include "llvm/Support/Allocator.h" 20 #include <cassert> 21 22 namespace clang { 23 class Preprocessor; 24 25 /// \brief Encapsulates the data about a macro definition (e.g. its tokens). 26 /// There's an instance of this class for every #define. 27 class MacroInfo { 28 //===--------------------------------------------------------------------===// 29 // State set when the macro is defined. 30 31 /// Location - This is the place the macro is defined. 32 SourceLocation Location; 33 /// EndLocation - The location of the last token in the macro. 34 SourceLocation EndLocation; 35 36 /// Arguments - The list of arguments for a function-like macro. This can be 37 /// empty, for, e.g. "#define X()". In a C99-style variadic macro, this 38 /// includes the \c __VA_ARGS__ identifier on the list. 39 IdentifierInfo **ArgumentList; 40 unsigned NumArguments; 41 42 /// \brief This is the list of tokens that the macro is defined to. 43 SmallVector<Token, 8> ReplacementTokens; 44 45 /// \brief Length in characters of the macro definition. 46 mutable unsigned DefinitionLength; 47 mutable bool IsDefinitionLengthCached : 1; 48 49 /// \brief True if this macro is a function-like macro, false if it 50 /// is an object-like macro. 51 bool IsFunctionLike : 1; 52 53 /// IsC99Varargs - True if this macro is of the form "#define X(...)" or 54 /// "#define X(Y,Z,...)". The __VA_ARGS__ token should be replaced with the 55 /// contents of "..." in an invocation. 56 bool IsC99Varargs : 1; 57 58 /// IsGNUVarargs - True if this macro is of the form "#define X(a...)". The 59 /// "a" identifier in the replacement list will be replaced with all arguments 60 /// of the macro starting with the specified one. 61 bool IsGNUVarargs : 1; 62 63 /// IsBuiltinMacro - True if this is a builtin macro, such as __LINE__, and if 64 /// it has not yet been redefined or undefined. 65 bool IsBuiltinMacro : 1; 66 67 /// \brief Whether this macro contains the sequence ", ## __VA_ARGS__" 68 bool HasCommaPasting : 1; 69 70 private: 71 //===--------------------------------------------------------------------===// 72 // State that changes as the macro is used. 73 74 /// IsDisabled - True if we have started an expansion of this macro already. 75 /// This disables recursive expansion, which would be quite bad for things 76 /// like \#define A A. 77 bool IsDisabled : 1; 78 79 /// IsUsed - True if this macro is either defined in the main file and has 80 /// been used, or if it is not defined in the main file. This is used to 81 /// emit -Wunused-macros diagnostics. 82 bool IsUsed : 1; 83 84 /// AllowRedefinitionsWithoutWarning - True if this macro can be redefined 85 /// without emitting a warning. 86 bool IsAllowRedefinitionsWithoutWarning : 1; 87 88 /// \brief Must warn if the macro is unused at the end of translation unit. 89 bool IsWarnIfUnused : 1; 90 ~MacroInfo()91 ~MacroInfo() { 92 assert(ArgumentList == 0 && "Didn't call destroy before dtor!"); 93 } 94 95 public: 96 MacroInfo(SourceLocation DefLoc); 97 98 /// FreeArgumentList - Free the argument list of the macro, restoring it to a 99 /// state where it can be reused for other devious purposes. FreeArgumentList()100 void FreeArgumentList() { 101 ArgumentList = 0; 102 NumArguments = 0; 103 } 104 105 /// Destroy - destroy this MacroInfo object. Destroy()106 void Destroy() { 107 FreeArgumentList(); 108 this->~MacroInfo(); 109 } 110 111 /// getDefinitionLoc - Return the location that the macro was defined at. 112 /// getDefinitionLoc()113 SourceLocation getDefinitionLoc() const { return Location; } 114 115 /// setDefinitionEndLoc - Set the location of the last token in the macro. 116 /// setDefinitionEndLoc(SourceLocation EndLoc)117 void setDefinitionEndLoc(SourceLocation EndLoc) { EndLocation = EndLoc; } 118 119 /// getDefinitionEndLoc - Return the location of the last token in the macro. 120 /// getDefinitionEndLoc()121 SourceLocation getDefinitionEndLoc() const { return EndLocation; } 122 123 /// \brief Get length in characters of the macro definition. getDefinitionLength(SourceManager & SM)124 unsigned getDefinitionLength(SourceManager &SM) const { 125 if (IsDefinitionLengthCached) 126 return DefinitionLength; 127 return getDefinitionLengthSlow(SM); 128 } 129 130 /// isIdenticalTo - Return true if the specified macro definition is equal to 131 /// this macro in spelling, arguments, and whitespace. This is used to emit 132 /// duplicate definition warnings. This implements the rules in C99 6.10.3. 133 bool isIdenticalTo(const MacroInfo &Other, Preprocessor &PP) const; 134 135 /// setIsBuiltinMacro - Set or clear the isBuiltinMacro flag. 136 /// 137 void setIsBuiltinMacro(bool Val = true) { 138 IsBuiltinMacro = Val; 139 } 140 141 /// setIsUsed - Set the value of the IsUsed flag. 142 /// setIsUsed(bool Val)143 void setIsUsed(bool Val) { 144 IsUsed = Val; 145 } 146 147 /// setIsAllowRedefinitionsWithoutWarning - Set the value of the 148 /// IsAllowRedefinitionsWithoutWarning flag. setIsAllowRedefinitionsWithoutWarning(bool Val)149 void setIsAllowRedefinitionsWithoutWarning(bool Val) { 150 IsAllowRedefinitionsWithoutWarning = Val; 151 } 152 153 /// \brief Set the value of the IsWarnIfUnused flag. setIsWarnIfUnused(bool val)154 void setIsWarnIfUnused(bool val) { 155 IsWarnIfUnused = val; 156 } 157 158 /// setArgumentList - Set the specified list of identifiers as the argument 159 /// list for this macro. setArgumentList(IdentifierInfo * const * List,unsigned NumArgs,llvm::BumpPtrAllocator & PPAllocator)160 void setArgumentList(IdentifierInfo* const *List, unsigned NumArgs, 161 llvm::BumpPtrAllocator &PPAllocator) { 162 assert(ArgumentList == 0 && NumArguments == 0 && 163 "Argument list already set!"); 164 if (NumArgs == 0) return; 165 166 NumArguments = NumArgs; 167 ArgumentList = PPAllocator.Allocate<IdentifierInfo*>(NumArgs); 168 for (unsigned i = 0; i != NumArgs; ++i) 169 ArgumentList[i] = List[i]; 170 } 171 172 /// Arguments - The list of arguments for a function-like macro. This can be 173 /// empty, for, e.g. "#define X()". 174 typedef IdentifierInfo* const *arg_iterator; arg_empty()175 bool arg_empty() const { return NumArguments == 0; } arg_begin()176 arg_iterator arg_begin() const { return ArgumentList; } arg_end()177 arg_iterator arg_end() const { return ArgumentList+NumArguments; } getNumArgs()178 unsigned getNumArgs() const { return NumArguments; } 179 180 /// getArgumentNum - Return the argument number of the specified identifier, 181 /// or -1 if the identifier is not a formal argument identifier. getArgumentNum(IdentifierInfo * Arg)182 int getArgumentNum(IdentifierInfo *Arg) const { 183 for (arg_iterator I = arg_begin(), E = arg_end(); I != E; ++I) 184 if (*I == Arg) return I-arg_begin(); 185 return -1; 186 } 187 188 /// Function/Object-likeness. Keep track of whether this macro has formal 189 /// parameters. setIsFunctionLike()190 void setIsFunctionLike() { IsFunctionLike = true; } isFunctionLike()191 bool isFunctionLike() const { return IsFunctionLike; } isObjectLike()192 bool isObjectLike() const { return !IsFunctionLike; } 193 194 /// Varargs querying methods. This can only be set for function-like macros. setIsC99Varargs()195 void setIsC99Varargs() { IsC99Varargs = true; } setIsGNUVarargs()196 void setIsGNUVarargs() { IsGNUVarargs = true; } isC99Varargs()197 bool isC99Varargs() const { return IsC99Varargs; } isGNUVarargs()198 bool isGNUVarargs() const { return IsGNUVarargs; } isVariadic()199 bool isVariadic() const { return IsC99Varargs | IsGNUVarargs; } 200 201 /// isBuiltinMacro - Return true if this macro is a builtin macro, such as 202 /// __LINE__, which requires processing before expansion. isBuiltinMacro()203 bool isBuiltinMacro() const { return IsBuiltinMacro; } 204 hasCommaPasting()205 bool hasCommaPasting() const { return HasCommaPasting; } setHasCommaPasting()206 void setHasCommaPasting() { HasCommaPasting = true; } 207 208 /// isUsed - Return false if this macro is defined in the main file and has 209 /// not yet been used. isUsed()210 bool isUsed() const { return IsUsed; } 211 212 /// isAllowRedefinitionsWithoutWarning - Return true if this macro can be 213 /// redefined without warning. isAllowRedefinitionsWithoutWarning()214 bool isAllowRedefinitionsWithoutWarning() const { 215 return IsAllowRedefinitionsWithoutWarning; 216 } 217 218 /// \brief Return true if we should emit a warning if the macro is unused. isWarnIfUnused()219 bool isWarnIfUnused() const { 220 return IsWarnIfUnused; 221 } 222 223 /// getNumTokens - Return the number of tokens that this macro expands to. 224 /// getNumTokens()225 unsigned getNumTokens() const { 226 return ReplacementTokens.size(); 227 } 228 getReplacementToken(unsigned Tok)229 const Token &getReplacementToken(unsigned Tok) const { 230 assert(Tok < ReplacementTokens.size() && "Invalid token #"); 231 return ReplacementTokens[Tok]; 232 } 233 234 typedef SmallVector<Token, 8>::const_iterator tokens_iterator; tokens_begin()235 tokens_iterator tokens_begin() const { return ReplacementTokens.begin(); } tokens_end()236 tokens_iterator tokens_end() const { return ReplacementTokens.end(); } tokens_empty()237 bool tokens_empty() const { return ReplacementTokens.empty(); } 238 239 /// AddTokenToBody - Add the specified token to the replacement text for the 240 /// macro. AddTokenToBody(const Token & Tok)241 void AddTokenToBody(const Token &Tok) { 242 assert(!IsDefinitionLengthCached && 243 "Changing replacement tokens after definition length got calculated"); 244 ReplacementTokens.push_back(Tok); 245 } 246 247 /// isEnabled - Return true if this macro is enabled: in other words, that we 248 /// are not currently in an expansion of this macro. isEnabled()249 bool isEnabled() const { return !IsDisabled; } 250 EnableMacro()251 void EnableMacro() { 252 assert(IsDisabled && "Cannot enable an already-enabled macro!"); 253 IsDisabled = false; 254 } 255 DisableMacro()256 void DisableMacro() { 257 assert(!IsDisabled && "Cannot disable an already-disabled macro!"); 258 IsDisabled = true; 259 } 260 261 private: 262 unsigned getDefinitionLengthSlow(SourceManager &SM) const; 263 }; 264 265 /// \brief Encapsulates changes to the "macros namespace" (the location where 266 /// the macro name became active, the location where it was undefined, etc.). 267 /// 268 /// MacroDirectives, associated with an identifier, are used to model the macro 269 /// history. Usually a macro definition (MacroInfo) is where a macro name 270 /// becomes active (MacroDirective) but modules can have their own macro 271 /// history, separate from the local (current translation unit) macro history. 272 /// 273 /// For example, if "@import A;" imports macro FOO, there will be a new local 274 /// MacroDirective created to indicate that "FOO" became active at the import 275 /// location. Module "A" itself will contain another MacroDirective in its macro 276 /// history (at the point of the definition of FOO) and both MacroDirectives 277 /// will point to the same MacroInfo object. 278 /// 279 class MacroDirective { 280 MacroInfo *Info; 281 282 /// \brief Previous definition, the identifier of this macro was defined to, 283 /// or NULL. 284 MacroDirective *Previous; 285 286 SourceLocation Loc; 287 288 /// \brief The location where the macro was #undef'd, or an invalid location 289 /// for macros that haven't been undefined. 290 SourceLocation UndefLocation; 291 292 /// \brief The location at which this macro was either explicitly exported 293 /// from its module or marked as private. 294 /// 295 /// If invalid, this macro has not been explicitly given any visibility. 296 SourceLocation VisibilityLocation; 297 298 /// \brief True if this macro was loaded from an AST file. 299 bool IsImported : 1; 300 301 /// \brief Whether the macro has public (when described in a module). 302 bool IsPublic : 1; 303 304 /// \brief Whether the macro definition is currently "hidden". 305 /// Note that this is transient state that is never serialized to the AST 306 /// file. 307 bool IsHidden : 1; 308 309 /// \brief Whether the definition of this macro is ambiguous, due to 310 /// multiple definitions coming in from multiple modules. 311 bool IsAmbiguous : 1; 312 313 /// \brief Whether this macro changed after it was loaded from an AST file. 314 bool ChangedAfterLoad : 1; 315 316 public: MacroDirective(MacroInfo * MI)317 explicit MacroDirective(MacroInfo *MI) 318 : Info(MI), Previous(0), Loc(MI->getDefinitionLoc()), 319 IsImported(false), IsPublic(true), IsHidden(false), IsAmbiguous(false), 320 ChangedAfterLoad(false) { 321 assert(MI && "MacroInfo is null"); 322 } 323 MacroDirective(MacroInfo * MI,SourceLocation Loc,bool isImported)324 MacroDirective(MacroInfo *MI, SourceLocation Loc, bool isImported) 325 : Info(MI), Previous(0), Loc(Loc), 326 IsImported(isImported), IsPublic(true), IsHidden(false), 327 IsAmbiguous(false), ChangedAfterLoad(false) { 328 assert(MI && "MacroInfo is null"); 329 } 330 getLocation()331 SourceLocation getLocation() const { return Loc; } 332 333 /// \brief Set the location where macro was undefined. Can only be set once. setUndefLoc(SourceLocation UndefLoc)334 void setUndefLoc(SourceLocation UndefLoc) { 335 assert(UndefLocation.isInvalid() && "UndefLocation is already set!"); 336 assert(UndefLoc.isValid() && "Invalid UndefLoc!"); 337 UndefLocation = UndefLoc; 338 } 339 340 /// \brief The data for the macro definition. getInfo()341 const MacroInfo *getInfo() const { return Info; } getInfo()342 MacroInfo *getInfo() { return Info; } 343 344 /// \brief Get the location where macro was undefined. getUndefLoc()345 SourceLocation getUndefLoc() const { return UndefLocation; } 346 347 /// \brief Set previous definition of the macro with the same name. setPrevious(MacroDirective * Prev)348 void setPrevious(MacroDirective *Prev) { 349 Previous = Prev; 350 } 351 352 /// \brief Get previous definition of the macro with the same name. getPrevious()353 const MacroDirective *getPrevious() const { return Previous; } 354 355 /// \brief Get previous definition of the macro with the same name. getPrevious()356 MacroDirective *getPrevious() { return Previous; } 357 358 /// \brief Find macro definition active in the specified source location. If 359 /// this macro was not defined there, return NULL. 360 const MacroDirective *findDirectiveAtLoc(SourceLocation L, 361 SourceManager &SM) const; 362 363 /// \brief Set the export location for this macro. setVisibility(bool Public,SourceLocation Loc)364 void setVisibility(bool Public, SourceLocation Loc) { 365 VisibilityLocation = Loc; 366 IsPublic = Public; 367 } 368 369 /// \brief Determine whether this macro is part of the public API of its 370 /// module. isPublic()371 bool isPublic() const { return IsPublic; } 372 373 /// \brief Determine the location where this macro was explicitly made 374 /// public or private within its module. getVisibilityLocation()375 SourceLocation getVisibilityLocation() const { return VisibilityLocation; } 376 377 /// \brief True if this macro was loaded from an AST file. isImported()378 bool isImported() const { return IsImported; } 379 380 /// \brief Determine whether this macro is currently defined (and has not 381 /// been #undef'd) or has been hidden. isDefined()382 bool isDefined() const { return UndefLocation.isInvalid() && !IsHidden; } 383 384 /// \brief Determine whether this macro definition is hidden. isHidden()385 bool isHidden() const { return IsHidden; } 386 387 /// \brief Set whether this macro definition is hidden. setHidden(bool Val)388 void setHidden(bool Val) { IsHidden = Val; } 389 390 /// \brief Determine whether this macro definition is ambiguous with 391 /// other macro definitions. isAmbiguous()392 bool isAmbiguous() const { return IsAmbiguous; } 393 394 /// \brief Set whether this macro definition is ambiguous. setAmbiguous(bool Val)395 void setAmbiguous(bool Val) { IsAmbiguous = Val; } 396 397 /// \brief Determine whether this macro has changed since it was loaded from 398 /// an AST file. hasChangedAfterLoad()399 bool hasChangedAfterLoad() const { return ChangedAfterLoad; } 400 401 /// \brief Note whether this macro has changed after it was loaded from an 402 /// AST file. 403 void setChangedAfterLoad(bool CAL = true) { ChangedAfterLoad = CAL; } 404 }; 405 406 } // end namespace clang 407 408 #endif 409