]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/clang/lib/Lex/PreprocessingRecord.cpp
Upgrade to OpenSSH 7.8p1.
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / clang / lib / Lex / PreprocessingRecord.cpp
1 //===- PreprocessingRecord.cpp - Record of Preprocessing ------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 //  This file implements the PreprocessingRecord class, which maintains a record
11 //  of what occurred during preprocessing, and its helpers.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #include "clang/Lex/PreprocessingRecord.h"
16 #include "clang/Basic/IdentifierTable.h"
17 #include "clang/Basic/LLVM.h"
18 #include "clang/Basic/SourceLocation.h"
19 #include "clang/Basic/SourceManager.h"
20 #include "clang/Basic/TokenKinds.h"
21 #include "clang/Lex/MacroInfo.h"
22 #include "clang/Lex/Token.h"
23 #include "llvm/ADT/DenseMap.h"
24 #include "llvm/ADT/Optional.h"
25 #include "llvm/ADT/StringRef.h"
26 #include "llvm/ADT/iterator_range.h"
27 #include "llvm/Support/Capacity.h"
28 #include "llvm/Support/Casting.h"
29 #include "llvm/Support/ErrorHandling.h"
30 #include <algorithm>
31 #include <cassert>
32 #include <cstddef>
33 #include <cstring>
34 #include <iterator>
35 #include <utility>
36 #include <vector>
37
38 using namespace clang;
39
40 ExternalPreprocessingRecordSource::~ExternalPreprocessingRecordSource() =
41     default;
42
43 InclusionDirective::InclusionDirective(PreprocessingRecord &PPRec,
44                                        InclusionKind Kind, StringRef FileName,
45                                        bool InQuotes, bool ImportedModule,
46                                        const FileEntry *File, SourceRange Range)
47     : PreprocessingDirective(InclusionDirectiveKind, Range), InQuotes(InQuotes),
48       Kind(Kind), ImportedModule(ImportedModule), File(File) {
49   char *Memory = (char *)PPRec.Allocate(FileName.size() + 1, alignof(char));
50   memcpy(Memory, FileName.data(), FileName.size());
51   Memory[FileName.size()] = 0;
52   this->FileName = StringRef(Memory, FileName.size());
53 }
54
55 PreprocessingRecord::PreprocessingRecord(SourceManager &SM) : SourceMgr(SM) {}
56
57 /// \brief Returns a pair of [Begin, End) iterators of preprocessed entities
58 /// that source range \p Range encompasses.
59 llvm::iterator_range<PreprocessingRecord::iterator>
60 PreprocessingRecord::getPreprocessedEntitiesInRange(SourceRange Range) {
61   if (Range.isInvalid())
62     return llvm::make_range(iterator(), iterator());
63
64   if (CachedRangeQuery.Range == Range) {
65     return llvm::make_range(iterator(this, CachedRangeQuery.Result.first),
66                             iterator(this, CachedRangeQuery.Result.second));
67   }
68
69   std::pair<int, int> Res = getPreprocessedEntitiesInRangeSlow(Range);
70   
71   CachedRangeQuery.Range = Range;
72   CachedRangeQuery.Result = Res;
73
74   return llvm::make_range(iterator(this, Res.first),
75                           iterator(this, Res.second));
76 }
77
78 static bool isPreprocessedEntityIfInFileID(PreprocessedEntity *PPE, FileID FID,
79                                            SourceManager &SM) {
80   assert(FID.isValid());
81   if (!PPE)
82     return false;
83
84   SourceLocation Loc = PPE->getSourceRange().getBegin();
85   if (Loc.isInvalid())
86     return false;
87
88   return SM.isInFileID(SM.getFileLoc(Loc), FID);
89 }
90
91 /// \brief Returns true if the preprocessed entity that \arg PPEI iterator
92 /// points to is coming from the file \arg FID.
93 ///
94 /// Can be used to avoid implicit deserializations of preallocated
95 /// preprocessed entities if we only care about entities of a specific file
96 /// and not from files \#included in the range given at
97 /// \see getPreprocessedEntitiesInRange.
98 bool PreprocessingRecord::isEntityInFileID(iterator PPEI, FileID FID) {
99   if (FID.isInvalid())
100     return false;
101
102   int Pos = std::distance(iterator(this, 0), PPEI);
103   if (Pos < 0) {
104     if (unsigned(-Pos-1) >= LoadedPreprocessedEntities.size()) {
105       assert(0 && "Out-of bounds loaded preprocessed entity");
106       return false;
107     }
108     assert(ExternalSource && "No external source to load from");
109     unsigned LoadedIndex = LoadedPreprocessedEntities.size()+Pos;
110     if (PreprocessedEntity *PPE = LoadedPreprocessedEntities[LoadedIndex])
111       return isPreprocessedEntityIfInFileID(PPE, FID, SourceMgr);
112
113     // See if the external source can see if the entity is in the file without
114     // deserializing it.
115     Optional<bool> IsInFile =
116         ExternalSource->isPreprocessedEntityInFileID(LoadedIndex, FID);
117     if (IsInFile.hasValue())
118       return IsInFile.getValue();
119
120     // The external source did not provide a definite answer, go and deserialize
121     // the entity to check it.
122     return isPreprocessedEntityIfInFileID(
123                                        getLoadedPreprocessedEntity(LoadedIndex),
124                                           FID, SourceMgr);
125   }
126
127   if (unsigned(Pos) >= PreprocessedEntities.size()) {
128     assert(0 && "Out-of bounds local preprocessed entity");
129     return false;
130   }
131   return isPreprocessedEntityIfInFileID(PreprocessedEntities[Pos],
132                                         FID, SourceMgr);
133 }
134
135 /// \brief Returns a pair of [Begin, End) iterators of preprocessed entities
136 /// that source range \arg R encompasses.
137 std::pair<int, int>
138 PreprocessingRecord::getPreprocessedEntitiesInRangeSlow(SourceRange Range) {
139   assert(Range.isValid());
140   assert(!SourceMgr.isBeforeInTranslationUnit(Range.getEnd(),Range.getBegin()));
141   
142   std::pair<unsigned, unsigned>
143     Local = findLocalPreprocessedEntitiesInRange(Range);
144   
145   // Check if range spans local entities.
146   if (!ExternalSource || SourceMgr.isLocalSourceLocation(Range.getBegin()))
147     return std::make_pair(Local.first, Local.second);
148   
149   std::pair<unsigned, unsigned>
150     Loaded = ExternalSource->findPreprocessedEntitiesInRange(Range);
151   
152   // Check if range spans local entities.
153   if (Loaded.first == Loaded.second)
154     return std::make_pair(Local.first, Local.second);
155   
156   unsigned TotalLoaded = LoadedPreprocessedEntities.size();
157   
158   // Check if range spans loaded entities.
159   if (Local.first == Local.second)
160     return std::make_pair(int(Loaded.first)-TotalLoaded,
161                           int(Loaded.second)-TotalLoaded);
162   
163   // Range spands loaded and local entities.
164   return std::make_pair(int(Loaded.first)-TotalLoaded, Local.second);
165 }
166
167 std::pair<unsigned, unsigned>
168 PreprocessingRecord::findLocalPreprocessedEntitiesInRange(
169                                                       SourceRange Range) const {
170   if (Range.isInvalid())
171     return std::make_pair(0,0);
172   assert(!SourceMgr.isBeforeInTranslationUnit(Range.getEnd(),Range.getBegin()));
173
174   unsigned Begin = findBeginLocalPreprocessedEntity(Range.getBegin());
175   unsigned End = findEndLocalPreprocessedEntity(Range.getEnd());
176   return std::make_pair(Begin, End);
177 }
178
179 namespace {
180
181 template <SourceLocation (SourceRange::*getRangeLoc)() const>
182 struct PPEntityComp {
183   const SourceManager &SM;
184
185   explicit PPEntityComp(const SourceManager &SM) : SM(SM) {}
186
187   bool operator()(PreprocessedEntity *L, PreprocessedEntity *R) const {
188     SourceLocation LHS = getLoc(L);
189     SourceLocation RHS = getLoc(R);
190     return SM.isBeforeInTranslationUnit(LHS, RHS);
191   }
192
193   bool operator()(PreprocessedEntity *L, SourceLocation RHS) const {
194     SourceLocation LHS = getLoc(L);
195     return SM.isBeforeInTranslationUnit(LHS, RHS);
196   }
197
198   bool operator()(SourceLocation LHS, PreprocessedEntity *R) const {
199     SourceLocation RHS = getLoc(R);
200     return SM.isBeforeInTranslationUnit(LHS, RHS);
201   }
202
203   SourceLocation getLoc(PreprocessedEntity *PPE) const {
204     SourceRange Range = PPE->getSourceRange();
205     return (Range.*getRangeLoc)();
206   }
207 };
208
209 } // namespace
210
211 unsigned PreprocessingRecord::findBeginLocalPreprocessedEntity(
212                                                      SourceLocation Loc) const {
213   if (SourceMgr.isLoadedSourceLocation(Loc))
214     return 0;
215
216   size_t Count = PreprocessedEntities.size();
217   size_t Half;
218   std::vector<PreprocessedEntity *>::const_iterator
219     First = PreprocessedEntities.begin();
220   std::vector<PreprocessedEntity *>::const_iterator I;
221
222   // Do a binary search manually instead of using std::lower_bound because
223   // The end locations of entities may be unordered (when a macro expansion
224   // is inside another macro argument), but for this case it is not important
225   // whether we get the first macro expansion or its containing macro.
226   while (Count > 0) {
227     Half = Count/2;
228     I = First;
229     std::advance(I, Half);
230     if (SourceMgr.isBeforeInTranslationUnit((*I)->getSourceRange().getEnd(),
231                                             Loc)){
232       First = I;
233       ++First;
234       Count = Count - Half - 1;
235     } else
236       Count = Half;
237   }
238
239   return First - PreprocessedEntities.begin();
240 }
241
242 unsigned PreprocessingRecord::findEndLocalPreprocessedEntity(
243                                                      SourceLocation Loc) const {
244   if (SourceMgr.isLoadedSourceLocation(Loc))
245     return 0;
246
247   std::vector<PreprocessedEntity *>::const_iterator
248   I = std::upper_bound(PreprocessedEntities.begin(),
249                        PreprocessedEntities.end(),
250                        Loc,
251                        PPEntityComp<&SourceRange::getBegin>(SourceMgr));
252   return I - PreprocessedEntities.begin();
253 }
254
255 PreprocessingRecord::PPEntityID
256 PreprocessingRecord::addPreprocessedEntity(PreprocessedEntity *Entity) {
257   assert(Entity);
258   SourceLocation BeginLoc = Entity->getSourceRange().getBegin();
259
260   if (isa<MacroDefinitionRecord>(Entity)) {
261     assert((PreprocessedEntities.empty() ||
262             !SourceMgr.isBeforeInTranslationUnit(
263                 BeginLoc,
264                 PreprocessedEntities.back()->getSourceRange().getBegin())) &&
265            "a macro definition was encountered out-of-order");
266     PreprocessedEntities.push_back(Entity);
267     return getPPEntityID(PreprocessedEntities.size()-1, /*isLoaded=*/false);
268   }
269
270   // Check normal case, this entity begin location is after the previous one.
271   if (PreprocessedEntities.empty() ||
272       !SourceMgr.isBeforeInTranslationUnit(BeginLoc,
273                    PreprocessedEntities.back()->getSourceRange().getBegin())) {
274     PreprocessedEntities.push_back(Entity);
275     return getPPEntityID(PreprocessedEntities.size()-1, /*isLoaded=*/false);
276   }
277
278   // The entity's location is not after the previous one; this can happen with
279   // include directives that form the filename using macros, e.g:
280   // "#include MACRO(STUFF)"
281   // or with macro expansions inside macro arguments where the arguments are
282   // not expanded in the same order as listed, e.g:
283   // \code
284   //  #define M1 1
285   //  #define M2 2
286   //  #define FM(x,y) y x
287   //  FM(M1, M2)
288   // \endcode
289
290   using pp_iter = std::vector<PreprocessedEntity *>::iterator;
291
292   // Usually there are few macro expansions when defining the filename, do a
293   // linear search for a few entities.
294   unsigned count = 0;
295   for (pp_iter RI    = PreprocessedEntities.end(),
296                Begin = PreprocessedEntities.begin();
297        RI != Begin && count < 4; --RI, ++count) {
298     pp_iter I = RI;
299     --I;
300     if (!SourceMgr.isBeforeInTranslationUnit(BeginLoc,
301                                            (*I)->getSourceRange().getBegin())) {
302       pp_iter insertI = PreprocessedEntities.insert(RI, Entity);
303       return getPPEntityID(insertI - PreprocessedEntities.begin(),
304                            /*isLoaded=*/false);
305     }
306   }
307
308   // Linear search unsuccessful. Do a binary search.
309   pp_iter I = std::upper_bound(PreprocessedEntities.begin(),
310                                PreprocessedEntities.end(),
311                                BeginLoc,
312                                PPEntityComp<&SourceRange::getBegin>(SourceMgr));
313   pp_iter insertI = PreprocessedEntities.insert(I, Entity);
314   return getPPEntityID(insertI - PreprocessedEntities.begin(),
315                        /*isLoaded=*/false);
316 }
317
318 void PreprocessingRecord::SetExternalSource(
319                                     ExternalPreprocessingRecordSource &Source) {
320   assert(!ExternalSource &&
321          "Preprocessing record already has an external source");
322   ExternalSource = &Source;
323 }
324
325 unsigned PreprocessingRecord::allocateLoadedEntities(unsigned NumEntities) {
326   unsigned Result = LoadedPreprocessedEntities.size();
327   LoadedPreprocessedEntities.resize(LoadedPreprocessedEntities.size() 
328                                     + NumEntities);
329   return Result;
330 }
331
332 void PreprocessingRecord::RegisterMacroDefinition(MacroInfo *Macro,
333                                                   MacroDefinitionRecord *Def) {
334   MacroDefinitions[Macro] = Def;
335 }
336
337 /// \brief Retrieve the preprocessed entity at the given ID.
338 PreprocessedEntity *PreprocessingRecord::getPreprocessedEntity(PPEntityID PPID){
339   if (PPID.ID < 0) {
340     unsigned Index = -PPID.ID - 1;
341     assert(Index < LoadedPreprocessedEntities.size() &&
342            "Out-of bounds loaded preprocessed entity");
343     return getLoadedPreprocessedEntity(Index);
344   }
345
346   if (PPID.ID == 0)
347     return nullptr;
348   unsigned Index = PPID.ID - 1;
349   assert(Index < PreprocessedEntities.size() &&
350          "Out-of bounds local preprocessed entity");
351   return PreprocessedEntities[Index];
352 }
353
354 /// \brief Retrieve the loaded preprocessed entity at the given index.
355 PreprocessedEntity *
356 PreprocessingRecord::getLoadedPreprocessedEntity(unsigned Index) {
357   assert(Index < LoadedPreprocessedEntities.size() && 
358          "Out-of bounds loaded preprocessed entity");
359   assert(ExternalSource && "No external source to load from");
360   PreprocessedEntity *&Entity = LoadedPreprocessedEntities[Index];
361   if (!Entity) {
362     Entity = ExternalSource->ReadPreprocessedEntity(Index);
363     if (!Entity) // Failed to load.
364       Entity = new (*this)
365          PreprocessedEntity(PreprocessedEntity::InvalidKind, SourceRange());
366   }
367   return Entity;
368 }
369
370 MacroDefinitionRecord *
371 PreprocessingRecord::findMacroDefinition(const MacroInfo *MI) {
372   llvm::DenseMap<const MacroInfo *, MacroDefinitionRecord *>::iterator Pos =
373       MacroDefinitions.find(MI);
374   if (Pos == MacroDefinitions.end())
375     return nullptr;
376
377   return Pos->second;
378 }
379
380 void PreprocessingRecord::addMacroExpansion(const Token &Id,
381                                             const MacroInfo *MI,
382                                             SourceRange Range) {
383   // We don't record nested macro expansions.
384   if (Id.getLocation().isMacroID())
385     return;
386
387   if (MI->isBuiltinMacro())
388     addPreprocessedEntity(new (*this)
389                               MacroExpansion(Id.getIdentifierInfo(), Range));
390   else if (MacroDefinitionRecord *Def = findMacroDefinition(MI))
391     addPreprocessedEntity(new (*this) MacroExpansion(Def, Range));
392 }
393
394 void PreprocessingRecord::Ifdef(SourceLocation Loc, const Token &MacroNameTok,
395                                 const MacroDefinition &MD) {
396   // This is not actually a macro expansion but record it as a macro reference.
397   if (MD)
398     addMacroExpansion(MacroNameTok, MD.getMacroInfo(),
399                       MacroNameTok.getLocation());
400 }
401
402 void PreprocessingRecord::Ifndef(SourceLocation Loc, const Token &MacroNameTok,
403                                  const MacroDefinition &MD) {
404   // This is not actually a macro expansion but record it as a macro reference.
405   if (MD)
406     addMacroExpansion(MacroNameTok, MD.getMacroInfo(),
407                       MacroNameTok.getLocation());
408 }
409
410 void PreprocessingRecord::Defined(const Token &MacroNameTok,
411                                   const MacroDefinition &MD,
412                                   SourceRange Range) {
413   // This is not actually a macro expansion but record it as a macro reference.
414   if (MD)
415     addMacroExpansion(MacroNameTok, MD.getMacroInfo(),
416                       MacroNameTok.getLocation());
417 }
418
419 void PreprocessingRecord::SourceRangeSkipped(SourceRange Range,
420                                              SourceLocation EndifLoc) {
421   SkippedRanges.emplace_back(Range.getBegin(), EndifLoc);
422 }
423
424 void PreprocessingRecord::MacroExpands(const Token &Id,
425                                        const MacroDefinition &MD,
426                                        SourceRange Range,
427                                        const MacroArgs *Args) {
428   addMacroExpansion(Id, MD.getMacroInfo(), Range);
429 }
430
431 void PreprocessingRecord::MacroDefined(const Token &Id,
432                                        const MacroDirective *MD) {
433   const MacroInfo *MI = MD->getMacroInfo();
434   SourceRange R(MI->getDefinitionLoc(), MI->getDefinitionEndLoc());
435   MacroDefinitionRecord *Def =
436       new (*this) MacroDefinitionRecord(Id.getIdentifierInfo(), R);
437   addPreprocessedEntity(Def);
438   MacroDefinitions[MI] = Def;
439 }
440
441 void PreprocessingRecord::MacroUndefined(const Token &Id,
442                                          const MacroDefinition &MD,
443                                          const MacroDirective *Undef) {
444   MD.forAllDefinitions([&](MacroInfo *MI) { MacroDefinitions.erase(MI); });
445 }
446
447 void PreprocessingRecord::InclusionDirective(
448     SourceLocation HashLoc,
449     const Token &IncludeTok,
450     StringRef FileName,
451     bool IsAngled,
452     CharSourceRange FilenameRange,
453     const FileEntry *File,
454     StringRef SearchPath,
455     StringRef RelativePath,
456     const Module *Imported) {
457   InclusionDirective::InclusionKind Kind = InclusionDirective::Include;
458   
459   switch (IncludeTok.getIdentifierInfo()->getPPKeywordID()) {
460   case tok::pp_include: 
461     Kind = InclusionDirective::Include; 
462     break;
463     
464   case tok::pp_import: 
465     Kind = InclusionDirective::Import; 
466     break;
467     
468   case tok::pp_include_next: 
469     Kind = InclusionDirective::IncludeNext; 
470     break;
471     
472   case tok::pp___include_macros: 
473     Kind = InclusionDirective::IncludeMacros;
474     break;
475     
476   default:
477     llvm_unreachable("Unknown include directive kind");
478   }
479
480   SourceLocation EndLoc;
481   if (!IsAngled) {
482     EndLoc = FilenameRange.getBegin();
483   } else {
484     EndLoc = FilenameRange.getEnd();
485     if (FilenameRange.isCharRange())
486       EndLoc = EndLoc.getLocWithOffset(-1); // the InclusionDirective expects
487                                             // a token range.
488   }
489   clang::InclusionDirective *ID =
490       new (*this) clang::InclusionDirective(*this, Kind, FileName, !IsAngled,
491                                             (bool)Imported, File,
492                                             SourceRange(HashLoc, EndLoc));
493   addPreprocessedEntity(ID);
494 }
495
496 size_t PreprocessingRecord::getTotalMemory() const {
497   return BumpAlloc.getTotalMemory()
498     + llvm::capacity_in_bytes(MacroDefinitions)
499     + llvm::capacity_in_bytes(PreprocessedEntities)
500     + llvm::capacity_in_bytes(LoadedPreprocessedEntities);
501 }