Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/clang/lib/Lex/MacroInfo.cpp
Line
Count
Source (jump to first uncovered line)
1
//===- MacroInfo.cpp - Information about #defined identifiers -------------===//
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
// This file implements the MacroInfo interface.
10
//
11
//===----------------------------------------------------------------------===//
12
13
#include "clang/Lex/MacroInfo.h"
14
#include "clang/Basic/IdentifierTable.h"
15
#include "clang/Basic/LLVM.h"
16
#include "clang/Basic/SourceLocation.h"
17
#include "clang/Basic/SourceManager.h"
18
#include "clang/Basic/TokenKinds.h"
19
#include "clang/Lex/Preprocessor.h"
20
#include "clang/Lex/Token.h"
21
#include "llvm/ADT/Optional.h"
22
#include "llvm/ADT/StringRef.h"
23
#include "llvm/Support/Casting.h"
24
#include "llvm/Support/Compiler.h"
25
#include "llvm/Support/raw_ostream.h"
26
#include <cassert>
27
#include <utility>
28
29
using namespace clang;
30
31
MacroInfo::MacroInfo(SourceLocation DefLoc)
32
    : Location(DefLoc), IsDefinitionLengthCached(false), IsFunctionLike(false),
33
      IsC99Varargs(false), IsGNUVarargs(false), IsBuiltinMacro(false),
34
      HasCommaPasting(false), IsDisabled(false), IsUsed(false),
35
      IsAllowRedefinitionsWithoutWarning(false), IsWarnIfUnused(false),
36
26.2M
      UsedForHeaderGuard(false) {}
37
38
502k
unsigned MacroInfo::getDefinitionLengthSlow(const SourceManager &SM) const {
39
502k
  assert(!IsDefinitionLengthCached);
40
502k
  IsDefinitionLengthCached = true;
41
502k
42
502k
  if (ReplacementTokens.empty())
43
0
    return (DefinitionLength = 0);
44
502k
45
502k
  const Token &firstToken = ReplacementTokens.front();
46
502k
  const Token &lastToken = ReplacementTokens.back();
47
502k
  SourceLocation macroStart = firstToken.getLocation();
48
502k
  SourceLocation macroEnd = lastToken.getLocation();
49
502k
  assert(macroStart.isValid() && macroEnd.isValid());
50
502k
  assert((macroStart.isFileID() || firstToken.is(tok::comment)) &&
51
502k
         "Macro defined in macro?");
52
502k
  assert((macroEnd.isFileID() || lastToken.is(tok::comment)) &&
53
502k
         "Macro defined in macro?");
54
502k
  std::pair<FileID, unsigned>
55
502k
      startInfo = SM.getDecomposedExpansionLoc(macroStart);
56
502k
  std::pair<FileID, unsigned>
57
502k
      endInfo = SM.getDecomposedExpansionLoc(macroEnd);
58
502k
  assert(startInfo.first == endInfo.first &&
59
502k
         "Macro definition spanning multiple FileIDs ?");
60
502k
  assert(startInfo.second <= endInfo.second);
61
502k
  DefinitionLength = endInfo.second - startInfo.second;
62
502k
  DefinitionLength += lastToken.getLength();
63
502k
64
502k
  return DefinitionLength;
65
502k
}
66
67
/// Return true if the specified macro definition is equal to
68
/// this macro in spelling, arguments, and whitespace.
69
///
70
/// \param Syntactically if true, the macro definitions can be identical even
71
/// if they use different identifiers for the function macro parameters.
72
/// Otherwise the comparison is lexical and this implements the rules in
73
/// C99 6.10.3.
74
bool MacroInfo::isIdenticalTo(const MacroInfo &Other, Preprocessor &PP,
75
312k
                              bool Syntactically) const {
76
312k
  bool Lexically = !Syntactically;
77
312k
78
312k
  // Check # tokens in replacement, number of args, and various flags all match.
79
312k
  if (ReplacementTokens.size() != Other.ReplacementTokens.size() ||
80
312k
      
getNumParams() != Other.getNumParams()312k
||
81
312k
      
isFunctionLike() != Other.isFunctionLike()312k
||
82
312k
      
isC99Varargs() != Other.isC99Varargs()312k
||
83
312k
      
isGNUVarargs() != Other.isGNUVarargs()312k
)
84
140
    return false;
85
312k
86
312k
  if (Lexically) {
87
312k
    // Check arguments.
88
312k
    for (param_iterator I = param_begin(), OI = Other.param_begin(),
89
312k
                        E = param_end();
90
312k
         I != E; 
++I, ++OI142
)
91
143
      if (*I != *OI) 
return false1
;
92
312k
  }
93
312k
94
312k
  // Check all the tokens.
95
626k
  
for (unsigned i = 0, e = ReplacementTokens.size(); 312k
i != e;
++i313k
) {
96
314k
    const Token &A = ReplacementTokens[i];
97
314k
    const Token &B = Other.ReplacementTokens[i];
98
314k
    if (A.getKind() != B.getKind())
99
87
      return false;
100
314k
101
314k
    // If this isn't the first first token, check that the whitespace and
102
314k
    // start-of-line characteristics match.
103
314k
    if (i != 0 &&
104
314k
        
(1.43k
A.isAtStartOfLine() != B.isAtStartOfLine()1.43k
||
105
1.43k
         A.hasLeadingSpace() != B.hasLeadingSpace()))
106
2
      return false;
107
314k
108
314k
    // If this is an identifier, it is easy.
109
314k
    if (A.getIdentifierInfo() || 
B.getIdentifierInfo()313k
) {
110
671
      if (A.getIdentifierInfo() == B.getIdentifierInfo())
111
614
        continue;
112
57
      if (Lexically)
113
36
        return false;
114
21
      // With syntactic equivalence the parameter names can be different as long
115
21
      // as they are used in the same place.
116
21
      int AArgNum = getParameterNum(A.getIdentifierInfo());
117
21
      if (AArgNum == -1)
118
0
        return false;
119
21
      if (AArgNum != Other.getParameterNum(B.getIdentifierInfo()))
120
1
        return false;
121
20
      continue;
122
20
    }
123
313k
124
313k
    // Otherwise, check the spelling.
125
313k
    if (PP.getSpelling(A) != PP.getSpelling(B))
126
33
      return false;
127
313k
  }
128
312k
129
312k
  
return true312k
;
130
312k
}
131
132
19
LLVM_DUMP_METHOD void MacroInfo::dump() const {
133
19
  llvm::raw_ostream &Out = llvm::errs();
134
19
135
19
  // FIXME: Dump locations.
136
19
  Out << "MacroInfo " << this;
137
19
  if (IsBuiltinMacro) 
Out << " builtin"0
;
138
19
  if (IsDisabled) 
Out << " disabled"0
;
139
19
  if (IsUsed) 
Out << " used"2
;
140
19
  if (IsAllowRedefinitionsWithoutWarning)
141
0
    Out << " allow_redefinitions_without_warning";
142
19
  if (IsWarnIfUnused) 
Out << " warn_if_unused"0
;
143
19
  if (UsedForHeaderGuard) 
Out << " header_guard"1
;
144
19
145
19
  Out << "\n    #define <macro>";
146
19
  if (IsFunctionLike) {
147
0
    Out << "(";
148
0
    for (unsigned I = 0; I != NumParameters; ++I) {
149
0
      if (I) Out << ", ";
150
0
      Out << ParameterList[I]->getName();
151
0
    }
152
0
    if (IsC99Varargs || IsGNUVarargs) {
153
0
      if (NumParameters && IsC99Varargs) Out << ", ";
154
0
      Out << "...";
155
0
    }
156
0
    Out << ")";
157
0
  }
158
19
159
19
  bool First = true;
160
19
  for (const Token &Tok : ReplacementTokens) {
161
18
    // Leading space is semantically meaningful in a macro definition,
162
18
    // so preserve it in the dump output.
163
18
    if (First || 
Tok.hasLeadingSpace()0
)
164
18
      Out << " ";
165
18
    First = false;
166
18
167
18
    if (const char *Punc = tok::getPunctuatorSpelling(Tok.getKind()))
168
0
      Out << Punc;
169
18
    else if (Tok.isLiteral() && Tok.getLiteralData())
170
0
      Out << StringRef(Tok.getLiteralData(), Tok.getLength());
171
18
    else if (auto *II = Tok.getIdentifierInfo())
172
0
      Out << II->getName();
173
18
    else
174
18
      Out << Tok.getName();
175
18
  }
176
19
}
177
178
82.1M
MacroDirective::DefInfo MacroDirective::getDefinition() {
179
82.1M
  MacroDirective *MD = this;
180
82.1M
  SourceLocation UndefLoc;
181
82.1M
  Optional<bool> isPublic;
182
82.2M
  for (; MD; 
MD = MD->getPrevious()138k
) {
183
82.2M
    if (DefMacroDirective *DefMD = dyn_cast<DefMacroDirective>(MD))
184
82.1M
      return DefInfo(DefMD, UndefLoc,
185
82.1M
                     !isPublic.hasValue() || 
isPublic.getValue()325
);
186
138k
187
138k
    if (UndefMacroDirective *UndefMD = dyn_cast<UndefMacroDirective>(MD)) {
188
137k
      UndefLoc = UndefMD->getLocation();
189
137k
      continue;
190
137k
    }
191
323
192
323
    VisibilityMacroDirective *VisMD = cast<VisibilityMacroDirective>(MD);
193
323
    if (!isPublic.hasValue())
194
325
      isPublic = VisMD->isPublic();
195
323
  }
196
82.1M
197
82.1M
  return DefInfo(nullptr, UndefLoc,
198
105
                 !isPublic.hasValue() || 
isPublic.getValue()0
);
199
82.1M
}
200
201
const MacroDirective::DefInfo
202
MacroDirective::findDirectiveAtLoc(SourceLocation L,
203
56.5k
                                   const SourceManager &SM) const {
204
56.5k
  assert(L.isValid() && "SourceLocation is invalid.");
205
56.6k
  for (DefInfo Def = getDefinition(); Def; 
Def = Def.getPreviousDefinition()186
) {
206
56.6k
    if (Def.getLocation().isInvalid() ||  // For macros defined on the command line.
207
56.6k
        
SM.isBeforeInTranslationUnit(Def.getLocation(), L)52.9k
)
208
56.4k
      return (!Def.isUndefined() ||
209
56.4k
              
SM.isBeforeInTranslationUnit(L, Def.getUndefLocation())253
)
210
56.4k
                  ? 
Def56.2k
:
DefInfo()199
;
211
56.6k
  }
212
56.5k
  
return DefInfo()77
;
213
56.5k
}
214
215
0
LLVM_DUMP_METHOD void MacroDirective::dump() const {
216
0
  llvm::raw_ostream &Out = llvm::errs();
217
0
218
0
  switch (getKind()) {
219
0
  case MD_Define: Out << "DefMacroDirective"; break;
220
0
  case MD_Undefine: Out << "UndefMacroDirective"; break;
221
0
  case MD_Visibility: Out << "VisibilityMacroDirective"; break;
222
0
  }
223
0
  Out << " " << this;
224
0
  // FIXME: Dump SourceLocation.
225
0
  if (auto *Prev = getPrevious())
226
0
    Out << " prev " << Prev;
227
0
  if (IsFromPCH) Out << " from_pch";
228
0
229
0
  if (isa<VisibilityMacroDirective>(this))
230
0
    Out << (IsPublic ? " public" : " private");
231
0
232
0
  if (auto *DMD = dyn_cast<DefMacroDirective>(this)) {
233
0
    if (auto *Info = DMD->getInfo()) {
234
0
      Out << "\n  ";
235
0
      Info->dump();
236
0
    }
237
0
  }
238
0
  Out << "\n";
239
0
}
240
241
ModuleMacro *ModuleMacro::create(Preprocessor &PP, Module *OwningModule,
242
                                 IdentifierInfo *II, MacroInfo *Macro,
243
18.8k
                                 ArrayRef<ModuleMacro *> Overrides) {
244
18.8k
  void *Mem = PP.getPreprocessorAllocator().Allocate(
245
18.8k
      sizeof(ModuleMacro) + sizeof(ModuleMacro *) * Overrides.size(),
246
18.8k
      alignof(ModuleMacro));
247
18.8k
  return new (Mem) ModuleMacro(OwningModule, II, Macro, Overrides);
248
18.8k
}