Coverage Report

Created: 2020-02-25 14:32

/Users/buildslave/jenkins/workspace/coverage/llvm-project/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
37.4M
      UsedForHeaderGuard(false) {}
37
38
736k
unsigned MacroInfo::getDefinitionLengthSlow(const SourceManager &SM) const {
39
736k
  assert(!IsDefinitionLengthCached);
40
736k
  IsDefinitionLengthCached = true;
41
736k
42
736k
  if (ReplacementTokens.empty())
43
0
    return (DefinitionLength = 0);
44
736k
45
736k
  const Token &firstToken = ReplacementTokens.front();
46
736k
  const Token &lastToken = ReplacementTokens.back();
47
736k
  SourceLocation macroStart = firstToken.getLocation();
48
736k
  SourceLocation macroEnd = lastToken.getLocation();
49
736k
  assert(macroStart.isValid() && macroEnd.isValid());
50
736k
  assert((macroStart.isFileID() || firstToken.is(tok::comment)) &&
51
736k
         "Macro defined in macro?");
52
736k
  assert((macroEnd.isFileID() || lastToken.is(tok::comment)) &&
53
736k
         "Macro defined in macro?");
54
736k
  std::pair<FileID, unsigned>
55
736k
      startInfo = SM.getDecomposedExpansionLoc(macroStart);
56
736k
  std::pair<FileID, unsigned>
57
736k
      endInfo = SM.getDecomposedExpansionLoc(macroEnd);
58
736k
  assert(startInfo.first == endInfo.first &&
59
736k
         "Macro definition spanning multiple FileIDs ?");
60
736k
  assert(startInfo.second <= endInfo.second);
61
736k
  DefinitionLength = endInfo.second - startInfo.second;
62
736k
  DefinitionLength += lastToken.getLength();
63
736k
64
736k
  return DefinitionLength;
65
736k
}
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
300k
                              bool Syntactically) const {
76
300k
  bool Lexically = !Syntactically;
77
300k
78
300k
  // Check # tokens in replacement, number of args, and various flags all match.
79
300k
  if (ReplacementTokens.size() != Other.ReplacementTokens.size() ||
80
300k
      
getNumParams() != Other.getNumParams()300k
||
81
300k
      
isFunctionLike() != Other.isFunctionLike()300k
||
82
300k
      
isC99Varargs() != Other.isC99Varargs()300k
||
83
300k
      
isGNUVarargs() != Other.isGNUVarargs()300k
)
84
128
    return false;
85
300k
86
300k
  if (Lexically) {
87
300k
    // Check arguments.
88
300k
    for (param_iterator I = param_begin(), OI = Other.param_begin(),
89
300k
                        E = param_end();
90
300k
         I != E; 
++I, ++OI19
)
91
20
      if (*I != *OI) 
return false1
;
92
300k
  }
93
300k
94
300k
  // Check all the tokens.
95
601k
  
for (unsigned i = 0, e = ReplacementTokens.size(); 300k
i != e;
++i300k
) {
96
300k
    const Token &A = ReplacementTokens[i];
97
300k
    const Token &B = Other.ReplacementTokens[i];
98
300k
    if (A.getKind() != B.getKind())
99
86
      return false;
100
300k
101
300k
    // If this isn't the first first token, check that the whitespace and
102
300k
    // start-of-line characteristics match.
103
300k
    if (i != 0 &&
104
300k
        
(361
A.isAtStartOfLine() != B.isAtStartOfLine()361
||
105
361
         A.hasLeadingSpace() != B.hasLeadingSpace()))
106
2
      return false;
107
300k
108
300k
    // If this is an identifier, it is easy.
109
300k
    if (A.getIdentifierInfo() || 
B.getIdentifierInfo()300k
) {
110
364
      if (A.getIdentifierInfo() == B.getIdentifierInfo())
111
307
        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
300k
124
300k
    // Otherwise, check the spelling.
125
300k
    if (PP.getSpelling(A) != PP.getSpelling(B))
126
32
      return false;
127
300k
  }
128
300k
129
300k
  
return true300k
;
130
300k
}
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
254M
MacroDirective::DefInfo MacroDirective::getDefinition() {
179
254M
  MacroDirective *MD = this;
180
254M
  SourceLocation UndefLoc;
181
254M
  Optional<bool> isPublic;
182
254M
  for (; MD; 
MD = MD->getPrevious()122k
) {
183
254M
    if (DefMacroDirective *DefMD = dyn_cast<DefMacroDirective>(MD))
184
254M
      return DefInfo(DefMD, UndefLoc,
185
254M
                     !isPublic.hasValue() || 
isPublic.getValue()325
);
186
122k
187
122k
    
if (UndefMacroDirective *122k
UndefMD122k
= dyn_cast<UndefMacroDirective>(MD)) {
188
122k
      UndefLoc = UndefMD->getLocation();
189
122k
      continue;
190
122k
    }
191
18.4E
192
18.4E
    VisibilityMacroDirective *VisMD = cast<VisibilityMacroDirective>(MD);
193
18.4E
    if (!isPublic.hasValue())
194
325
      isPublic = VisMD->isPublic();
195
18.4E
  }
196
254M
197
254M
  return DefInfo(nullptr, UndefLoc,
198
939
                 !isPublic.hasValue() || 
isPublic.getValue()0
);
199
254M
}
200
201
const MacroDirective::DefInfo
202
MacroDirective::findDirectiveAtLoc(SourceLocation L,
203
115k
                                   const SourceManager &SM) const {
204
115k
  assert(L.isValid() && "SourceLocation is invalid.");
205
115k
  for (DefInfo Def = getDefinition(); Def; 
Def = Def.getPreviousDefinition()198
) {
206
115k
    if (Def.getLocation().isInvalid() ||  // For macros defined on the command line.
207
115k
        
SM.isBeforeInTranslationUnit(Def.getLocation(), L)107k
)
208
115k
      return (!Def.isUndefined() ||
209
115k
              
SM.isBeforeInTranslationUnit(L, Def.getUndefLocation())260
)
210
115k
                  ? 
Def114k
:
DefInfo()203
;
211
115k
  }
212
115k
  
return DefInfo()86
;
213
115k
}
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
1.96M
                                 ArrayRef<ModuleMacro *> Overrides) {
244
1.96M
  void *Mem = PP.getPreprocessorAllocator().Allocate(
245
1.96M
      sizeof(ModuleMacro) + sizeof(ModuleMacro *) * Overrides.size(),
246
1.96M
      alignof(ModuleMacro));
247
1.96M
  return new (Mem) ModuleMacro(OwningModule, II, Macro, Overrides);
248
1.96M
}