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/ErrorHandling.h"
18 #include "llvm/Support/Capacity.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, const FileEntry *File,
29                                        SourceRange Range)
30   : PreprocessingDirective(InclusionDirectiveKind, Range),
31     InQuotes(InQuotes), Kind(Kind), File(File)
32 {
33   char *Memory
34     = (char*)PPRec.Allocate(FileName.size() + 1, llvm::alignOf<char>());
35   memcpy(Memory, FileName.data(), FileName.size());
36   Memory[FileName.size()] = 0;
37   this->FileName = StringRef(Memory, FileName.size());
38 }
39 
40 PreprocessingRecord::PreprocessingRecord(SourceManager &SM)
41   : SourceMgr(SM), ExternalSource(0)
42 {
43 }
44 
45 /// \brief Returns a pair of [Begin, End) iterators of preprocessed entities
46 /// that source range \arg R encompasses.
47 std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator>
48 PreprocessingRecord::getPreprocessedEntitiesInRange(SourceRange Range) {
49   if (Range.isInvalid())
50     return std::make_pair(iterator(), iterator());
51 
52   if (CachedRangeQuery.Range == Range) {
53     return std::make_pair(iterator(this, CachedRangeQuery.Result.first),
54                           iterator(this, CachedRangeQuery.Result.second));
55   }
56 
57   std::pair<PPEntityID, PPEntityID>
58     Res = getPreprocessedEntitiesInRangeSlow(Range);
59 
60   CachedRangeQuery.Range = Range;
61   CachedRangeQuery.Result = Res;
62 
63   return std::make_pair(iterator(this, Res.first), iterator(this, Res.second));
64 }
65 
66 static bool isPreprocessedEntityIfInFileID(PreprocessedEntity *PPE, FileID FID,
67                                            SourceManager &SM) {
68   assert(!FID.isInvalid());
69   if (!PPE)
70     return false;
71 
72   SourceLocation Loc = PPE->getSourceRange().getBegin();
73   if (Loc.isInvalid())
74     return false;
75 
76   if (SM.isInFileID(SM.getFileLoc(Loc), FID))
77     return true;
78   else
79     return false;
80 }
81 
82 /// \brief Returns true if the preprocessed entity that \arg PPEI iterator
83 /// points to is coming from the file \arg FID.
84 ///
85 /// Can be used to avoid implicit deserializations of preallocated
86 /// preprocessed entities if we only care about entities of a specific file
87 /// and not from files #included in the range given at
88 /// \see getPreprocessedEntitiesInRange.
89 bool PreprocessingRecord::isEntityInFileID(iterator PPEI, FileID FID) {
90   if (FID.isInvalid())
91     return false;
92 
93   PPEntityID PPID = PPEI.Position;
94   if (PPID < 0) {
95     assert(unsigned(-PPID-1) < LoadedPreprocessedEntities.size() &&
96            "Out-of bounds loaded preprocessed entity");
97     assert(ExternalSource && "No external source to load from");
98     unsigned LoadedIndex = LoadedPreprocessedEntities.size()+PPID;
99     if (PreprocessedEntity *PPE = LoadedPreprocessedEntities[LoadedIndex])
100       return isPreprocessedEntityIfInFileID(PPE, FID, SourceMgr);
101 
102     // See if the external source can see if the entity is in the file without
103     // deserializing it.
104     llvm::Optional<bool>
105       IsInFile = ExternalSource->isPreprocessedEntityInFileID(LoadedIndex, FID);
106     if (IsInFile.hasValue())
107       return IsInFile.getValue();
108 
109     // The external source did not provide a definite answer, go and deserialize
110     // the entity to check it.
111     return isPreprocessedEntityIfInFileID(
112                                        getLoadedPreprocessedEntity(LoadedIndex),
113                                           FID, SourceMgr);
114   }
115 
116   assert(unsigned(PPID) < PreprocessedEntities.size() &&
117          "Out-of bounds local preprocessed entity");
118   return isPreprocessedEntityIfInFileID(PreprocessedEntities[PPID],
119                                         FID, SourceMgr);
120 }
121 
122 /// \brief Returns a pair of [Begin, End) iterators of preprocessed entities
123 /// that source range \arg R encompasses.
124 std::pair<PreprocessingRecord::PPEntityID, PreprocessingRecord::PPEntityID>
125 PreprocessingRecord::getPreprocessedEntitiesInRangeSlow(SourceRange Range) {
126   assert(Range.isValid());
127   assert(!SourceMgr.isBeforeInTranslationUnit(Range.getEnd(),Range.getBegin()));
128 
129   std::pair<unsigned, unsigned>
130     Local = findLocalPreprocessedEntitiesInRange(Range);
131 
132   // Check if range spans local entities.
133   if (!ExternalSource || SourceMgr.isLocalSourceLocation(Range.getBegin()))
134     return std::make_pair(Local.first, Local.second);
135 
136   std::pair<unsigned, unsigned>
137     Loaded = ExternalSource->findPreprocessedEntitiesInRange(Range);
138 
139   // Check if range spans local entities.
140   if (Loaded.first == Loaded.second)
141     return std::make_pair(Local.first, Local.second);
142 
143   unsigned TotalLoaded = LoadedPreprocessedEntities.size();
144 
145   // Check if range spans loaded entities.
146   if (Local.first == Local.second)
147     return std::make_pair(int(Loaded.first)-TotalLoaded,
148                           int(Loaded.second)-TotalLoaded);
149 
150   // Range spands loaded and local entities.
151   return std::make_pair(int(Loaded.first)-TotalLoaded, Local.second);
152 }
153 
154 std::pair<unsigned, unsigned>
155 PreprocessingRecord::findLocalPreprocessedEntitiesInRange(
156                                                       SourceRange Range) const {
157   if (Range.isInvalid())
158     return std::make_pair(0,0);
159   assert(!SourceMgr.isBeforeInTranslationUnit(Range.getEnd(),Range.getBegin()));
160 
161   unsigned Begin = findBeginLocalPreprocessedEntity(Range.getBegin());
162   unsigned End = findEndLocalPreprocessedEntity(Range.getEnd());
163   return std::make_pair(Begin, End);
164 }
165 
166 namespace {
167 
168 template <SourceLocation (SourceRange::*getRangeLoc)() const>
169 struct PPEntityComp {
170   const SourceManager &SM;
171 
172   explicit PPEntityComp(const SourceManager &SM) : SM(SM) { }
173 
174   bool operator()(PreprocessedEntity *L, PreprocessedEntity *R) const {
175     SourceLocation LHS = getLoc(L);
176     SourceLocation RHS = getLoc(R);
177     return SM.isBeforeInTranslationUnit(LHS, RHS);
178   }
179 
180   bool operator()(PreprocessedEntity *L, SourceLocation RHS) const {
181     SourceLocation LHS = getLoc(L);
182     return SM.isBeforeInTranslationUnit(LHS, RHS);
183   }
184 
185   bool operator()(SourceLocation LHS, PreprocessedEntity *R) const {
186     SourceLocation RHS = getLoc(R);
187     return SM.isBeforeInTranslationUnit(LHS, RHS);
188   }
189 
190   SourceLocation getLoc(PreprocessedEntity *PPE) const {
191     SourceRange Range = PPE->getSourceRange();
192     return (Range.*getRangeLoc)();
193   }
194 };
195 
196 }
197 
198 unsigned PreprocessingRecord::findBeginLocalPreprocessedEntity(
199                                                      SourceLocation Loc) const {
200   if (SourceMgr.isLoadedSourceLocation(Loc))
201     return 0;
202 
203   size_t Count = PreprocessedEntities.size();
204   size_t Half;
205   std::vector<PreprocessedEntity *>::const_iterator
206     First = PreprocessedEntities.begin();
207   std::vector<PreprocessedEntity *>::const_iterator I;
208 
209   // Do a binary search manually instead of using std::lower_bound because
210   // The end locations of entities may be unordered (when a macro expansion
211   // is inside another macro argument), but for this case it is not important
212   // whether we get the first macro expansion or its containing macro.
213   while (Count > 0) {
214     Half = Count/2;
215     I = First;
216     std::advance(I, Half);
217     if (SourceMgr.isBeforeInTranslationUnit((*I)->getSourceRange().getEnd(),
218                                             Loc)){
219       First = I;
220       ++First;
221       Count = Count - Half - 1;
222     } else
223       Count = Half;
224   }
225 
226   return First - PreprocessedEntities.begin();
227 }
228 
229 unsigned PreprocessingRecord::findEndLocalPreprocessedEntity(
230                                                      SourceLocation Loc) const {
231   if (SourceMgr.isLoadedSourceLocation(Loc))
232     return 0;
233 
234   std::vector<PreprocessedEntity *>::const_iterator
235   I = std::upper_bound(PreprocessedEntities.begin(),
236                        PreprocessedEntities.end(),
237                        Loc,
238                        PPEntityComp<&SourceRange::getBegin>(SourceMgr));
239   return I - PreprocessedEntities.begin();
240 }
241 
242 void PreprocessingRecord::addPreprocessedEntity(PreprocessedEntity *Entity) {
243   assert(Entity);
244   SourceLocation BeginLoc = Entity->getSourceRange().getBegin();
245 
246   // Check normal case, this entity begin location is after the previous one.
247   if (PreprocessedEntities.empty() ||
248       !SourceMgr.isBeforeInTranslationUnit(BeginLoc,
249                    PreprocessedEntities.back()->getSourceRange().getBegin())) {
250     PreprocessedEntities.push_back(Entity);
251     return;
252   }
253 
254   // The entity's location is not after the previous one; this can happen rarely
255   // e.g. with "#include MACRO".
256   // Iterate the entities vector in reverse until we find the right place to
257   // insert the new entity.
258   for (std::vector<PreprocessedEntity *>::iterator
259          RI = PreprocessedEntities.end(), Begin = PreprocessedEntities.begin();
260        RI != Begin; --RI) {
261     std::vector<PreprocessedEntity *>::iterator I = RI;
262     --I;
263     if (!SourceMgr.isBeforeInTranslationUnit(BeginLoc,
264                                            (*I)->getSourceRange().getBegin())) {
265       PreprocessedEntities.insert(RI, Entity);
266       return;
267     }
268   }
269 }
270 
271 void PreprocessingRecord::SetExternalSource(
272                                     ExternalPreprocessingRecordSource &Source) {
273   assert(!ExternalSource &&
274          "Preprocessing record already has an external source");
275   ExternalSource = &Source;
276 }
277 
278 unsigned PreprocessingRecord::allocateLoadedEntities(unsigned NumEntities) {
279   unsigned Result = LoadedPreprocessedEntities.size();
280   LoadedPreprocessedEntities.resize(LoadedPreprocessedEntities.size()
281                                     + NumEntities);
282   return Result;
283 }
284 
285 void PreprocessingRecord::RegisterMacroDefinition(MacroInfo *Macro,
286                                                   PPEntityID PPID) {
287   MacroDefinitions[Macro] = PPID;
288 }
289 
290 /// \brief Retrieve the preprocessed entity at the given ID.
291 PreprocessedEntity *PreprocessingRecord::getPreprocessedEntity(PPEntityID PPID){
292   if (PPID < 0) {
293     assert(unsigned(-PPID-1) < LoadedPreprocessedEntities.size() &&
294            "Out-of bounds loaded preprocessed entity");
295     return getLoadedPreprocessedEntity(LoadedPreprocessedEntities.size()+PPID);
296   }
297   assert(unsigned(PPID) < PreprocessedEntities.size() &&
298          "Out-of bounds local preprocessed entity");
299   return PreprocessedEntities[PPID];
300 }
301 
302 /// \brief Retrieve the loaded preprocessed entity at the given index.
303 PreprocessedEntity *
304 PreprocessingRecord::getLoadedPreprocessedEntity(unsigned Index) {
305   assert(Index < LoadedPreprocessedEntities.size() &&
306          "Out-of bounds loaded preprocessed entity");
307   assert(ExternalSource && "No external source to load from");
308   PreprocessedEntity *&Entity = LoadedPreprocessedEntities[Index];
309   if (!Entity) {
310     Entity = ExternalSource->ReadPreprocessedEntity(Index);
311     if (!Entity) // Failed to load.
312       Entity = new (*this)
313          PreprocessedEntity(PreprocessedEntity::InvalidKind, SourceRange());
314   }
315   return Entity;
316 }
317 
318 MacroDefinition *PreprocessingRecord::findMacroDefinition(const MacroInfo *MI) {
319   llvm::DenseMap<const MacroInfo *, PPEntityID>::iterator Pos
320     = MacroDefinitions.find(MI);
321   if (Pos == MacroDefinitions.end())
322     return 0;
323 
324   PreprocessedEntity *Entity = getPreprocessedEntity(Pos->second);
325   if (Entity->isInvalid())
326     return 0;
327   return cast<MacroDefinition>(Entity);
328 }
329 
330 void PreprocessingRecord::MacroExpands(const Token &Id, const MacroInfo* MI,
331                                        SourceRange Range) {
332   // We don't record nested macro expansions.
333   if (Id.getLocation().isMacroID())
334     return;
335 
336   if (MI->isBuiltinMacro())
337     addPreprocessedEntity(
338                       new (*this) MacroExpansion(Id.getIdentifierInfo(),Range));
339   else if (MacroDefinition *Def = findMacroDefinition(MI))
340     addPreprocessedEntity(
341                        new (*this) MacroExpansion(Def, Range));
342 }
343 
344 void PreprocessingRecord::MacroDefined(const Token &Id,
345                                        const MacroInfo *MI) {
346   SourceRange R(MI->getDefinitionLoc(), MI->getDefinitionEndLoc());
347   MacroDefinition *Def
348       = new (*this) MacroDefinition(Id.getIdentifierInfo(), R);
349   addPreprocessedEntity(Def);
350   MacroDefinitions[MI] = getPPEntityID(PreprocessedEntities.size()-1,
351                                        /*isLoaded=*/false);
352 }
353 
354 void PreprocessingRecord::MacroUndefined(const Token &Id,
355                                          const MacroInfo *MI) {
356   llvm::DenseMap<const MacroInfo *, PPEntityID>::iterator Pos
357     = MacroDefinitions.find(MI);
358   if (Pos != MacroDefinitions.end())
359     MacroDefinitions.erase(Pos);
360 }
361 
362 void PreprocessingRecord::InclusionDirective(
363     SourceLocation HashLoc,
364     const clang::Token &IncludeTok,
365     StringRef FileName,
366     bool IsAngled,
367     const FileEntry *File,
368     clang::SourceLocation EndLoc,
369     StringRef SearchPath,
370     StringRef RelativePath) {
371   InclusionDirective::InclusionKind Kind = InclusionDirective::Include;
372 
373   switch (IncludeTok.getIdentifierInfo()->getPPKeywordID()) {
374   case tok::pp_include:
375     Kind = InclusionDirective::Include;
376     break;
377 
378   case tok::pp_import:
379     Kind = InclusionDirective::Import;
380     break;
381 
382   case tok::pp_include_next:
383     Kind = InclusionDirective::IncludeNext;
384     break;
385 
386   case tok::pp___include_macros:
387     Kind = InclusionDirective::IncludeMacros;
388     break;
389 
390   default:
391     llvm_unreachable("Unknown include directive kind");
392   }
393 
394   clang::InclusionDirective *ID
395     = new (*this) clang::InclusionDirective(*this, Kind, FileName, !IsAngled,
396                                             File, SourceRange(HashLoc, EndLoc));
397   addPreprocessedEntity(ID);
398 }
399 
400 size_t PreprocessingRecord::getTotalMemory() const {
401   return BumpAlloc.getTotalMemory()
402     + llvm::capacity_in_bytes(MacroDefinitions)
403     + llvm::capacity_in_bytes(PreprocessedEntities)
404     + llvm::capacity_in_bytes(LoadedPreprocessedEntities);
405 }
406