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