1193326Sed//===--- MacroInfo.cpp - Information about #defined identifiers -----------===//
2193326Sed//
3193326Sed//                     The LLVM Compiler Infrastructure
4193326Sed//
5193326Sed// This file is distributed under the University of Illinois Open Source
6193326Sed// License. See LICENSE.TXT for details.
7193326Sed//
8193326Sed//===----------------------------------------------------------------------===//
9193326Sed//
10193326Sed// This file implements the MacroInfo interface.
11193326Sed//
12193326Sed//===----------------------------------------------------------------------===//
13193326Sed
14193326Sed#include "clang/Lex/MacroInfo.h"
15193326Sed#include "clang/Lex/Preprocessor.h"
16193326Sedusing namespace clang;
17193326Sed
18245431SdimMacroInfo::MacroInfo(SourceLocation DefLoc)
19245431Sdim  : Location(DefLoc),
20245431Sdim    ArgumentList(0),
21245431Sdim    NumArguments(0),
22245431Sdim    IsDefinitionLengthCached(false),
23245431Sdim    IsFunctionLike(false),
24245431Sdim    IsC99Varargs(false),
25245431Sdim    IsGNUVarargs(false),
26245431Sdim    IsBuiltinMacro(false),
27252723Sdim    HasCommaPasting(false),
28245431Sdim    IsDisabled(false),
29245431Sdim    IsUsed(false),
30245431Sdim    IsAllowRedefinitionsWithoutWarning(false),
31245431Sdim    IsWarnIfUnused(false),
32252723Sdim    FromASTFile(false) {
33193326Sed}
34193326Sed
35224145Sdimunsigned MacroInfo::getDefinitionLengthSlow(SourceManager &SM) const {
36224145Sdim  assert(!IsDefinitionLengthCached);
37224145Sdim  IsDefinitionLengthCached = true;
38224145Sdim
39224145Sdim  if (ReplacementTokens.empty())
40224145Sdim    return (DefinitionLength = 0);
41224145Sdim
42224145Sdim  const Token &firstToken = ReplacementTokens.front();
43224145Sdim  const Token &lastToken = ReplacementTokens.back();
44224145Sdim  SourceLocation macroStart = firstToken.getLocation();
45224145Sdim  SourceLocation macroEnd = lastToken.getLocation();
46224145Sdim  assert(macroStart.isValid() && macroEnd.isValid());
47224145Sdim  assert((macroStart.isFileID() || firstToken.is(tok::comment)) &&
48224145Sdim         "Macro defined in macro?");
49224145Sdim  assert((macroEnd.isFileID() || lastToken.is(tok::comment)) &&
50224145Sdim         "Macro defined in macro?");
51224145Sdim  std::pair<FileID, unsigned>
52226890Sdim      startInfo = SM.getDecomposedExpansionLoc(macroStart);
53224145Sdim  std::pair<FileID, unsigned>
54226890Sdim      endInfo = SM.getDecomposedExpansionLoc(macroEnd);
55224145Sdim  assert(startInfo.first == endInfo.first &&
56224145Sdim         "Macro definition spanning multiple FileIDs ?");
57224145Sdim  assert(startInfo.second <= endInfo.second);
58224145Sdim  DefinitionLength = endInfo.second - startInfo.second;
59224145Sdim  DefinitionLength += lastToken.getLength();
60224145Sdim
61224145Sdim  return DefinitionLength;
62224145Sdim}
63224145Sdim
64252723Sdim/// \brief Return true if the specified macro definition is equal to
65252723Sdim/// this macro in spelling, arguments, and whitespace.
66193326Sed///
67252723Sdim/// \param Syntactically if true, the macro definitions can be identical even
68252723Sdim/// if they use different identifiers for the function macro parameters.
69252723Sdim/// Otherwise the comparison is lexical and this implements the rules in
70252723Sdim/// C99 6.10.3.
71252723Sdimbool MacroInfo::isIdenticalTo(const MacroInfo &Other, Preprocessor &PP,
72252723Sdim                              bool Syntactically) const {
73252723Sdim  bool Lexically = !Syntactically;
74252723Sdim
75193326Sed  // Check # tokens in replacement, number of args, and various flags all match.
76193326Sed  if (ReplacementTokens.size() != Other.ReplacementTokens.size() ||
77193326Sed      getNumArgs() != Other.getNumArgs() ||
78193326Sed      isFunctionLike() != Other.isFunctionLike() ||
79193326Sed      isC99Varargs() != Other.isC99Varargs() ||
80193326Sed      isGNUVarargs() != Other.isGNUVarargs())
81193326Sed    return false;
82193326Sed
83252723Sdim  if (Lexically) {
84252723Sdim    // Check arguments.
85252723Sdim    for (arg_iterator I = arg_begin(), OI = Other.arg_begin(), E = arg_end();
86252723Sdim         I != E; ++I, ++OI)
87252723Sdim      if (*I != *OI) return false;
88252723Sdim  }
89198092Srdivacky
90193326Sed  // Check all the tokens.
91193326Sed  for (unsigned i = 0, e = ReplacementTokens.size(); i != e; ++i) {
92193326Sed    const Token &A = ReplacementTokens[i];
93193326Sed    const Token &B = Other.ReplacementTokens[i];
94193326Sed    if (A.getKind() != B.getKind())
95193326Sed      return false;
96198092Srdivacky
97193326Sed    // If this isn't the first first token, check that the whitespace and
98193326Sed    // start-of-line characteristics match.
99193326Sed    if (i != 0 &&
100193326Sed        (A.isAtStartOfLine() != B.isAtStartOfLine() ||
101193326Sed         A.hasLeadingSpace() != B.hasLeadingSpace()))
102193326Sed      return false;
103198092Srdivacky
104193326Sed    // If this is an identifier, it is easy.
105193326Sed    if (A.getIdentifierInfo() || B.getIdentifierInfo()) {
106252723Sdim      if (A.getIdentifierInfo() == B.getIdentifierInfo())
107252723Sdim        continue;
108252723Sdim      if (Lexically)
109193326Sed        return false;
110252723Sdim      // With syntactic equivalence the parameter names can be different as long
111252723Sdim      // as they are used in the same place.
112252723Sdim      int AArgNum = getArgumentNum(A.getIdentifierInfo());
113252723Sdim      if (AArgNum == -1)
114252723Sdim        return false;
115252723Sdim      if (AArgNum != Other.getArgumentNum(B.getIdentifierInfo()))
116252723Sdim        return false;
117193326Sed      continue;
118193326Sed    }
119198092Srdivacky
120193326Sed    // Otherwise, check the spelling.
121193326Sed    if (PP.getSpelling(A) != PP.getSpelling(B))
122193326Sed      return false;
123193326Sed  }
124198092Srdivacky
125193326Sed  return true;
126193326Sed}
127252723Sdim
128252723SdimMacroDirective::DefInfo MacroDirective::getDefinition(bool AllowHidden) {
129252723Sdim  MacroDirective *MD = this;
130252723Sdim  SourceLocation UndefLoc;
131252723Sdim  Optional<bool> isPublic;
132252723Sdim  for (; MD; MD = MD->getPrevious()) {
133252723Sdim    if (!AllowHidden && MD->isHidden())
134252723Sdim      continue;
135252723Sdim
136252723Sdim    if (DefMacroDirective *DefMD = dyn_cast<DefMacroDirective>(MD))
137252723Sdim      return DefInfo(DefMD, UndefLoc,
138252723Sdim                     !isPublic.hasValue() || isPublic.getValue());
139252723Sdim
140252723Sdim    if (UndefMacroDirective *UndefMD = dyn_cast<UndefMacroDirective>(MD)) {
141252723Sdim      UndefLoc = UndefMD->getLocation();
142252723Sdim      continue;
143252723Sdim    }
144252723Sdim
145252723Sdim    VisibilityMacroDirective *VisMD = cast<VisibilityMacroDirective>(MD);
146252723Sdim    if (!isPublic.hasValue())
147252723Sdim      isPublic = VisMD->isPublic();
148252723Sdim  }
149252723Sdim
150252723Sdim  return DefInfo();
151252723Sdim}
152252723Sdim
153252723Sdimconst MacroDirective::DefInfo
154252723SdimMacroDirective::findDirectiveAtLoc(SourceLocation L, SourceManager &SM) const {
155252723Sdim  assert(L.isValid() && "SourceLocation is invalid.");
156252723Sdim  for (DefInfo Def = getDefinition(); Def; Def = Def.getPreviousDefinition()) {
157252723Sdim    if (Def.getLocation().isInvalid() ||  // For macros defined on the command line.
158252723Sdim        SM.isBeforeInTranslationUnit(Def.getLocation(), L))
159252723Sdim      return (!Def.isUndefined() ||
160252723Sdim              SM.isBeforeInTranslationUnit(L, Def.getUndefLocation()))
161252723Sdim                  ? Def : DefInfo();
162252723Sdim  }
163252723Sdim  return DefInfo();
164252723Sdim}
165