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