MacroInfo.h revision c215bd659d8266a1d6b66ce231a63405a4c61daf
15f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===--- MacroInfo.h - Information about #defined identifiers ---*- C++ -*-===// 25f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 35f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// The LLVM Compiler Infrastructure 45f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 55f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// This file was developed by Chris Lattner and is distributed under 65f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// the University of Illinois Open Source License. See LICENSE.TXT for details. 75f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 85f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===// 95f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// This file defines the MacroInfo interface. 115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===// 135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#ifndef LLVM_CLANG_MACROINFO_H 155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#define LLVM_CLANG_MACROINFO_H 165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "clang/Lex/LexerToken.h" 185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include <vector> 199dc62f044a6ba21f503bd56607d94b32704e7945Chris Lattner#include <cassert> 205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencernamespace clang { 225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer class Preprocessor; 235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// MacroInfo - Each identifier that is #define'd has an instance of this class 255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// associated with it, used to implement macro expansion. 265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerclass MacroInfo { 275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer //===--------------------------------------------------------------------===// 285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // State set when the macro is defined. 295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// Location - This is the place the macro is defined. 315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer SourceLocation Location; 325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// Arguments - The list of arguments for a function-like macro. This can be 345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// empty, for, e.g. "#define X()". In a C99-style variadic macro, this 355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// includes the __VA_ARGS__ identifier on the list. 365f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer std::vector<IdentifierInfo*> Arguments; 375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 385f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// ReplacementTokens - This is the list of tokens that the macro is defined 395f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// to. 405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer std::vector<LexerToken> ReplacementTokens; 415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// IsFunctionLike - True if this macro is a function-like macro, false if it 435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// is an object-like macro. 445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer bool IsFunctionLike : 1; 455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// IsC99Varargs - True if this macro is of the form "#define X(...)" or 475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// "#define X(Y,Z,...)". The __VA_ARGS__ token should be replaced with the 485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// contents of "..." in an invocation. 495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer bool IsC99Varargs : 1; 505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// IsGNUVarargs - True if this macro is of the form "#define X(a...)". The 525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// "a" identifier in th replacement list will be replaced with all arguments 535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// of the macro starting with the specified one. 545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer bool IsGNUVarargs : 1; 555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// IsBuiltinMacro - True if this is a builtin macro, such as __LINE__, and if 575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// it has not yet been redefined or undefined. 585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer bool IsBuiltinMacro : 1; 595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// IsTargetSpecific - True if this is a target-specific macro defined with 615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// #define_target. 625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer bool IsTargetSpecific : 1; 635f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerprivate: 645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer //===--------------------------------------------------------------------===// 655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // State that changes as the macro is used. 665f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// IsDisabled - True if we have started an expansion of this macro already. 685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// This disbles recursive expansion, which would be quite bad for things like 695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// #define A A. 705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer bool IsDisabled : 1; 715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// IsUsed - True if this macro is either defined in the main file and has 735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// been used, or if it is not defined in the main file. This is used to 745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// emit -Wunused-macros diagnostics. 755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer bool IsUsed : 1; 765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerpublic: 775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer MacroInfo(SourceLocation DefLoc); 785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// getDefinitionLoc - Return the location that the macro was defined at. 805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// 815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer SourceLocation getDefinitionLoc() const { return Location; } 825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// isIdenticalTo - Return true if the specified macro definition is equal to 845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// this macro in spelling, arguments, and whitespace. This is used to emit 855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// duplicate definition warnings. This implements the rules in C99 6.10.3. 865f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer bool isIdenticalTo(const MacroInfo &Other, Preprocessor &PP) const; 875f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 885f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// setIsBuiltinMacro - Set or clear the isBuiltinMacro flag. 895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// 905f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer void setIsBuiltinMacro(bool Val = true) { 915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer IsBuiltinMacro = Val; 925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// setIsTargetSpecific - Set or clear the IsTargetSpecific flag. 955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// 965f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer void setIsTargetSpecific(bool Val = true) { 975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer IsTargetSpecific = Val; 985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer bool isTargetSpecific() const { return IsTargetSpecific; } 1005f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 1015f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// setIsUsed - Set the value of the IsUsed flag. 1025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// 1035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer void setIsUsed(bool Val) { 1045f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer IsUsed = Val; 1055f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 1065f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 1075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// addArgument - Add an argument to the list of formal arguments for this 1085f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// function-like macro. 1095f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer void addArgument(IdentifierInfo *Arg) { 1105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer Arguments.push_back(Arg); 1115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 1125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 1135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// getArgumentNum - Return the argument number of the specified identifier, 1145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// or -1 if the identifier is not a formal argument identifier. 1155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer int getArgumentNum(IdentifierInfo *Arg) { 1165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer for (unsigned i = 0, e = Arguments.size(); i != e; ++i) 1175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (Arguments[i] == Arg) return i; 1185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer return -1; 1195f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 1205f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 1215f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// Arguments - The list of arguments for a function-like macro. This can be 1225f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// empty, for, e.g. "#define X()". 1235f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer typedef std::vector<IdentifierInfo*>::const_iterator arg_iterator; 1245f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer arg_iterator arg_begin() const { return Arguments.begin(); } 1255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer arg_iterator arg_end() const { return Arguments.end(); } 1265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer unsigned getNumArgs() const { return Arguments.size(); } 1275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 1285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// Function/Object-likeness. Keep track of whether this macro has formal 1295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// parameters. 1305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer void setIsFunctionLike() { IsFunctionLike = true; } 1315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer bool isFunctionLike() const { return IsFunctionLike; } 1325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer bool isObjectLike() const { return !IsFunctionLike; } 1335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 1345f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// Varargs querying methods. This can only be set for function-like macros. 1355f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer void setIsC99Varargs() { IsC99Varargs = true; } 1365f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer void setIsGNUVarargs() { IsGNUVarargs = true; } 1375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer bool isC99Varargs() const { return IsC99Varargs; } 1385f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer bool isGNUVarargs() const { return IsGNUVarargs; } 1395f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer bool isVariadic() const { return IsC99Varargs | IsGNUVarargs; } 1405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 1415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// isBuiltinMacro - Return true if this macro is a builtin macro, such as 1425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// __LINE__, which requires processing before expansion. 1435f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer bool isBuiltinMacro() const { return IsBuiltinMacro; } 1445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 1455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// isUsed - Return false if this macro is defined in the main file and has 1465f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// not yet been used. 1475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer bool isUsed() const { return IsUsed; } 1485f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 1495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// getNumTokens - Return the number of tokens that this macro expands to. 1505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// 1515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer unsigned getNumTokens() const { 1525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer return ReplacementTokens.size(); 1535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 1545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 1555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer const LexerToken &getReplacementToken(unsigned Tok) const { 1565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer assert(Tok < ReplacementTokens.size() && "Invalid token #"); 1575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer return ReplacementTokens[Tok]; 1585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 1595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 160c215bd659d8266a1d6b66ce231a63405a4c61dafChris Lattner typedef std::vector<LexerToken>::const_iterator tokens_iterator; 161c215bd659d8266a1d6b66ce231a63405a4c61dafChris Lattner tokens_iterator tokens_begin() const { return ReplacementTokens.begin(); } 162c215bd659d8266a1d6b66ce231a63405a4c61dafChris Lattner tokens_iterator tokens_end() const { return ReplacementTokens.end(); } 163c215bd659d8266a1d6b66ce231a63405a4c61dafChris Lattner 1645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// AddTokenToBody - Add the specified token to the replacement text for the 1655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// macro. 1665f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer void AddTokenToBody(const LexerToken &Tok) { 1675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer ReplacementTokens.push_back(Tok); 1685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 1695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 1705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// isEnabled - Return true if this macro is enabled: in other words, that we 1715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer /// are not currently in an expansion of this macro. 1725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer bool isEnabled() const { return !IsDisabled; } 1735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 1745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer void EnableMacro() { 1755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer assert(IsDisabled && "Cannot enable an already-enabled macro!"); 1765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer IsDisabled = false; 1775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 1785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 1795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer void DisableMacro() { 1805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer assert(!IsDisabled && "Cannot disable an already-disabled macro!"); 1815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer IsDisabled = true; 1825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 1835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer}; 1845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 1855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} // end namespace clang 1865f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 1875f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#endif 188