clang API Documentation

PreprocessingRecord.cpp
Go to the documentation of this file.
00001 //===--- PreprocessingRecord.cpp - Record of Preprocessing ------*- C++ -*-===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 //  This file implements the PreprocessingRecord class, which maintains a record
00011 //  of what occurred during preprocessing, and its helpers.
00012 //
00013 //===----------------------------------------------------------------------===//
00014 #include "clang/Lex/PreprocessingRecord.h"
00015 #include "clang/Lex/MacroInfo.h"
00016 #include "clang/Lex/Token.h"
00017 #include "llvm/Support/Capacity.h"
00018 #include "llvm/Support/ErrorHandling.h"
00019 
00020 using namespace clang;
00021 
00022 ExternalPreprocessingRecordSource::~ExternalPreprocessingRecordSource() { }
00023 
00024 
00025 InclusionDirective::InclusionDirective(PreprocessingRecord &PPRec,
00026                                        InclusionKind Kind, 
00027                                        StringRef FileName, 
00028                                        bool InQuotes, bool ImportedModule,
00029                                        const FileEntry *File,
00030                                        SourceRange Range)
00031   : PreprocessingDirective(InclusionDirectiveKind, Range), 
00032     InQuotes(InQuotes), Kind(Kind), ImportedModule(ImportedModule), File(File)
00033 { 
00034   char *Memory 
00035     = (char*)PPRec.Allocate(FileName.size() + 1, llvm::alignOf<char>());
00036   memcpy(Memory, FileName.data(), FileName.size());
00037   Memory[FileName.size()] = 0;
00038   this->FileName = StringRef(Memory, FileName.size());
00039 }
00040 
00041 PreprocessingRecord::PreprocessingRecord(SourceManager &SM)
00042   : SourceMgr(SM),
00043     ExternalSource(nullptr) {
00044 }
00045 
00046 /// \brief Returns a pair of [Begin, End) iterators of preprocessed entities
00047 /// that source range \p Range encompasses.
00048 std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator>
00049 PreprocessingRecord::getPreprocessedEntitiesInRange(SourceRange Range) {
00050   if (Range.isInvalid())
00051     return std::make_pair(iterator(), iterator());
00052 
00053   if (CachedRangeQuery.Range == Range) {
00054     return std::make_pair(iterator(this, CachedRangeQuery.Result.first),
00055                           iterator(this, CachedRangeQuery.Result.second));
00056   }
00057 
00058   std::pair<int, int> Res = getPreprocessedEntitiesInRangeSlow(Range);
00059   
00060   CachedRangeQuery.Range = Range;
00061   CachedRangeQuery.Result = Res;
00062   
00063   return std::make_pair(iterator(this, Res.first), iterator(this, Res.second));
00064 }
00065 
00066 static bool isPreprocessedEntityIfInFileID(PreprocessedEntity *PPE, FileID FID,
00067                                            SourceManager &SM) {
00068   assert(!FID.isInvalid());
00069   if (!PPE)
00070     return false;
00071 
00072   SourceLocation Loc = PPE->getSourceRange().getBegin();
00073   if (Loc.isInvalid())
00074     return false;
00075   
00076   if (SM.isInFileID(SM.getFileLoc(Loc), FID))
00077     return true;
00078   else
00079     return false;
00080 }
00081 
00082 /// \brief Returns true if the preprocessed entity that \arg PPEI iterator
00083 /// points to is coming from the file \arg FID.
00084 ///
00085 /// Can be used to avoid implicit deserializations of preallocated
00086 /// preprocessed entities if we only care about entities of a specific file
00087 /// and not from files \#included in the range given at
00088 /// \see getPreprocessedEntitiesInRange.
00089 bool PreprocessingRecord::isEntityInFileID(iterator PPEI, FileID FID) {
00090   if (FID.isInvalid())
00091     return false;
00092 
00093   int Pos = PPEI.Position;
00094   if (Pos < 0) {
00095     if (unsigned(-Pos-1) >= LoadedPreprocessedEntities.size()) {
00096       assert(0 && "Out-of bounds loaded preprocessed entity");
00097       return false;
00098     }
00099     assert(ExternalSource && "No external source to load from");
00100     unsigned LoadedIndex = LoadedPreprocessedEntities.size()+Pos;
00101     if (PreprocessedEntity *PPE = LoadedPreprocessedEntities[LoadedIndex])
00102       return isPreprocessedEntityIfInFileID(PPE, FID, SourceMgr);
00103 
00104     // See if the external source can see if the entity is in the file without
00105     // deserializing it.
00106     Optional<bool> IsInFile =
00107         ExternalSource->isPreprocessedEntityInFileID(LoadedIndex, FID);
00108     if (IsInFile.hasValue())
00109       return IsInFile.getValue();
00110 
00111     // The external source did not provide a definite answer, go and deserialize
00112     // the entity to check it.
00113     return isPreprocessedEntityIfInFileID(
00114                                        getLoadedPreprocessedEntity(LoadedIndex),
00115                                           FID, SourceMgr);
00116   }
00117 
00118   if (unsigned(Pos) >= PreprocessedEntities.size()) {
00119     assert(0 && "Out-of bounds local preprocessed entity");
00120     return false;
00121   }
00122   return isPreprocessedEntityIfInFileID(PreprocessedEntities[Pos],
00123                                         FID, SourceMgr);
00124 }
00125 
00126 /// \brief Returns a pair of [Begin, End) iterators of preprocessed entities
00127 /// that source range \arg R encompasses.
00128 std::pair<int, int>
00129 PreprocessingRecord::getPreprocessedEntitiesInRangeSlow(SourceRange Range) {
00130   assert(Range.isValid());
00131   assert(!SourceMgr.isBeforeInTranslationUnit(Range.getEnd(),Range.getBegin()));
00132   
00133   std::pair<unsigned, unsigned>
00134     Local = findLocalPreprocessedEntitiesInRange(Range);
00135   
00136   // Check if range spans local entities.
00137   if (!ExternalSource || SourceMgr.isLocalSourceLocation(Range.getBegin()))
00138     return std::make_pair(Local.first, Local.second);
00139   
00140   std::pair<unsigned, unsigned>
00141     Loaded = ExternalSource->findPreprocessedEntitiesInRange(Range);
00142   
00143   // Check if range spans local entities.
00144   if (Loaded.first == Loaded.second)
00145     return std::make_pair(Local.first, Local.second);
00146   
00147   unsigned TotalLoaded = LoadedPreprocessedEntities.size();
00148   
00149   // Check if range spans loaded entities.
00150   if (Local.first == Local.second)
00151     return std::make_pair(int(Loaded.first)-TotalLoaded,
00152                           int(Loaded.second)-TotalLoaded);
00153   
00154   // Range spands loaded and local entities.
00155   return std::make_pair(int(Loaded.first)-TotalLoaded, Local.second);
00156 }
00157 
00158 std::pair<unsigned, unsigned>
00159 PreprocessingRecord::findLocalPreprocessedEntitiesInRange(
00160                                                       SourceRange Range) const {
00161   if (Range.isInvalid())
00162     return std::make_pair(0,0);
00163   assert(!SourceMgr.isBeforeInTranslationUnit(Range.getEnd(),Range.getBegin()));
00164 
00165   unsigned Begin = findBeginLocalPreprocessedEntity(Range.getBegin());
00166   unsigned End = findEndLocalPreprocessedEntity(Range.getEnd());
00167   return std::make_pair(Begin, End);
00168 }
00169 
00170 namespace {
00171 
00172 template <SourceLocation (SourceRange::*getRangeLoc)() const>
00173 struct PPEntityComp {
00174   const SourceManager &SM;
00175 
00176   explicit PPEntityComp(const SourceManager &SM) : SM(SM) { }
00177 
00178   bool operator()(PreprocessedEntity *L, PreprocessedEntity *R) const {
00179     SourceLocation LHS = getLoc(L);
00180     SourceLocation RHS = getLoc(R);
00181     return SM.isBeforeInTranslationUnit(LHS, RHS);
00182   }
00183 
00184   bool operator()(PreprocessedEntity *L, SourceLocation RHS) const {
00185     SourceLocation LHS = getLoc(L);
00186     return SM.isBeforeInTranslationUnit(LHS, RHS);
00187   }
00188 
00189   bool operator()(SourceLocation LHS, PreprocessedEntity *R) const {
00190     SourceLocation RHS = getLoc(R);
00191     return SM.isBeforeInTranslationUnit(LHS, RHS);
00192   }
00193 
00194   SourceLocation getLoc(PreprocessedEntity *PPE) const {
00195     SourceRange Range = PPE->getSourceRange();
00196     return (Range.*getRangeLoc)();
00197   }
00198 };
00199 
00200 }
00201 
00202 unsigned PreprocessingRecord::findBeginLocalPreprocessedEntity(
00203                                                      SourceLocation Loc) const {
00204   if (SourceMgr.isLoadedSourceLocation(Loc))
00205     return 0;
00206 
00207   size_t Count = PreprocessedEntities.size();
00208   size_t Half;
00209   std::vector<PreprocessedEntity *>::const_iterator
00210     First = PreprocessedEntities.begin();
00211   std::vector<PreprocessedEntity *>::const_iterator I;
00212 
00213   // Do a binary search manually instead of using std::lower_bound because
00214   // The end locations of entities may be unordered (when a macro expansion
00215   // is inside another macro argument), but for this case it is not important
00216   // whether we get the first macro expansion or its containing macro.
00217   while (Count > 0) {
00218     Half = Count/2;
00219     I = First;
00220     std::advance(I, Half);
00221     if (SourceMgr.isBeforeInTranslationUnit((*I)->getSourceRange().getEnd(),
00222                                             Loc)){
00223       First = I;
00224       ++First;
00225       Count = Count - Half - 1;
00226     } else
00227       Count = Half;
00228   }
00229 
00230   return First - PreprocessedEntities.begin();
00231 }
00232 
00233 unsigned PreprocessingRecord::findEndLocalPreprocessedEntity(
00234                                                      SourceLocation Loc) const {
00235   if (SourceMgr.isLoadedSourceLocation(Loc))
00236     return 0;
00237 
00238   std::vector<PreprocessedEntity *>::const_iterator
00239   I = std::upper_bound(PreprocessedEntities.begin(),
00240                        PreprocessedEntities.end(),
00241                        Loc,
00242                        PPEntityComp<&SourceRange::getBegin>(SourceMgr));
00243   return I - PreprocessedEntities.begin();
00244 }
00245 
00246 PreprocessingRecord::PPEntityID
00247 PreprocessingRecord::addPreprocessedEntity(PreprocessedEntity *Entity) {
00248   assert(Entity);
00249   SourceLocation BeginLoc = Entity->getSourceRange().getBegin();
00250 
00251   if (isa<MacroDefinition>(Entity)) {
00252     assert((PreprocessedEntities.empty() ||
00253             !SourceMgr.isBeforeInTranslationUnit(BeginLoc,
00254                    PreprocessedEntities.back()->getSourceRange().getBegin())) &&
00255            "a macro definition was encountered out-of-order");
00256     PreprocessedEntities.push_back(Entity);
00257     return getPPEntityID(PreprocessedEntities.size()-1, /*isLoaded=*/false);
00258   }
00259 
00260   // Check normal case, this entity begin location is after the previous one.
00261   if (PreprocessedEntities.empty() ||
00262       !SourceMgr.isBeforeInTranslationUnit(BeginLoc,
00263                    PreprocessedEntities.back()->getSourceRange().getBegin())) {
00264     PreprocessedEntities.push_back(Entity);
00265     return getPPEntityID(PreprocessedEntities.size()-1, /*isLoaded=*/false);
00266   }
00267 
00268   // The entity's location is not after the previous one; this can happen with
00269   // include directives that form the filename using macros, e.g:
00270   // "#include MACRO(STUFF)"
00271   // or with macro expansions inside macro arguments where the arguments are
00272   // not expanded in the same order as listed, e.g:
00273   // \code
00274   //  #define M1 1
00275   //  #define M2 2
00276   //  #define FM(x,y) y x
00277   //  FM(M1, M2)
00278   // \endcode
00279 
00280   typedef std::vector<PreprocessedEntity *>::iterator pp_iter;
00281 
00282   // Usually there are few macro expansions when defining the filename, do a
00283   // linear search for a few entities.
00284   unsigned count = 0;
00285   for (pp_iter RI    = PreprocessedEntities.end(),
00286                Begin = PreprocessedEntities.begin();
00287        RI != Begin && count < 4; --RI, ++count) {
00288     pp_iter I = RI;
00289     --I;
00290     if (!SourceMgr.isBeforeInTranslationUnit(BeginLoc,
00291                                            (*I)->getSourceRange().getBegin())) {
00292       pp_iter insertI = PreprocessedEntities.insert(RI, Entity);
00293       return getPPEntityID(insertI - PreprocessedEntities.begin(),
00294                            /*isLoaded=*/false);
00295     }
00296   }
00297 
00298   // Linear search unsuccessful. Do a binary search.
00299   pp_iter I = std::upper_bound(PreprocessedEntities.begin(),
00300                                PreprocessedEntities.end(),
00301                                BeginLoc,
00302                                PPEntityComp<&SourceRange::getBegin>(SourceMgr));
00303   pp_iter insertI = PreprocessedEntities.insert(I, Entity);
00304   return getPPEntityID(insertI - PreprocessedEntities.begin(),
00305                        /*isLoaded=*/false);
00306 }
00307 
00308 void PreprocessingRecord::SetExternalSource(
00309                                     ExternalPreprocessingRecordSource &Source) {
00310   assert(!ExternalSource &&
00311          "Preprocessing record already has an external source");
00312   ExternalSource = &Source;
00313 }
00314 
00315 unsigned PreprocessingRecord::allocateLoadedEntities(unsigned NumEntities) {
00316   unsigned Result = LoadedPreprocessedEntities.size();
00317   LoadedPreprocessedEntities.resize(LoadedPreprocessedEntities.size() 
00318                                     + NumEntities);
00319   return Result;
00320 }
00321 
00322 void PreprocessingRecord::RegisterMacroDefinition(MacroInfo *Macro,
00323                                                   MacroDefinition *Def) {
00324   MacroDefinitions[Macro] = Def;
00325 }
00326 
00327 /// \brief Retrieve the preprocessed entity at the given ID.
00328 PreprocessedEntity *PreprocessingRecord::getPreprocessedEntity(PPEntityID PPID){
00329   if (PPID.ID < 0) {
00330     unsigned Index = -PPID.ID - 1;
00331     assert(Index < LoadedPreprocessedEntities.size() &&
00332            "Out-of bounds loaded preprocessed entity");
00333     return getLoadedPreprocessedEntity(Index);
00334   }
00335 
00336   if (PPID.ID == 0)
00337     return nullptr;
00338   unsigned Index = PPID.ID - 1;
00339   assert(Index < PreprocessedEntities.size() &&
00340          "Out-of bounds local preprocessed entity");
00341   return PreprocessedEntities[Index];
00342 }
00343 
00344 /// \brief Retrieve the loaded preprocessed entity at the given index.
00345 PreprocessedEntity *
00346 PreprocessingRecord::getLoadedPreprocessedEntity(unsigned Index) {
00347   assert(Index < LoadedPreprocessedEntities.size() && 
00348          "Out-of bounds loaded preprocessed entity");
00349   assert(ExternalSource && "No external source to load from");
00350   PreprocessedEntity *&Entity = LoadedPreprocessedEntities[Index];
00351   if (!Entity) {
00352     Entity = ExternalSource->ReadPreprocessedEntity(Index);
00353     if (!Entity) // Failed to load.
00354       Entity = new (*this)
00355          PreprocessedEntity(PreprocessedEntity::InvalidKind, SourceRange());
00356   }
00357   return Entity;
00358 }
00359 
00360 MacroDefinition *PreprocessingRecord::findMacroDefinition(const MacroInfo *MI) {
00361   llvm::DenseMap<const MacroInfo *, MacroDefinition *>::iterator Pos
00362     = MacroDefinitions.find(MI);
00363   if (Pos == MacroDefinitions.end())
00364     return nullptr;
00365 
00366   return Pos->second;
00367 }
00368 
00369 void PreprocessingRecord::addMacroExpansion(const Token &Id,
00370                                             const MacroInfo *MI,
00371                                             SourceRange Range) {
00372   // We don't record nested macro expansions.
00373   if (Id.getLocation().isMacroID())
00374     return;
00375 
00376   if (MI->isBuiltinMacro())
00377     addPreprocessedEntity(
00378                       new (*this) MacroExpansion(Id.getIdentifierInfo(),Range));
00379   else if (MacroDefinition *Def = findMacroDefinition(MI))
00380     addPreprocessedEntity(
00381                        new (*this) MacroExpansion(Def, Range));
00382 }
00383 
00384 void PreprocessingRecord::Ifdef(SourceLocation Loc, const Token &MacroNameTok,
00385                                 const MacroDirective *MD) {
00386   // This is not actually a macro expansion but record it as a macro reference.
00387   if (MD)
00388     addMacroExpansion(MacroNameTok, MD->getMacroInfo(),
00389                       MacroNameTok.getLocation());
00390 }
00391 
00392 void PreprocessingRecord::Ifndef(SourceLocation Loc, const Token &MacroNameTok,
00393                                  const MacroDirective *MD) {
00394   // This is not actually a macro expansion but record it as a macro reference.
00395   if (MD)
00396     addMacroExpansion(MacroNameTok, MD->getMacroInfo(),
00397                       MacroNameTok.getLocation());
00398 }
00399 
00400 void PreprocessingRecord::Defined(const Token &MacroNameTok,
00401                                   const MacroDirective *MD,
00402                                   SourceRange Range) {
00403   // This is not actually a macro expansion but record it as a macro reference.
00404   if (MD)
00405     addMacroExpansion(MacroNameTok, MD->getMacroInfo(),
00406                       MacroNameTok.getLocation());
00407 }
00408 
00409 void PreprocessingRecord::SourceRangeSkipped(SourceRange Range) {
00410   SkippedRanges.push_back(Range);
00411 }
00412 
00413 void PreprocessingRecord::MacroExpands(const Token &Id,const MacroDirective *MD,
00414                                        SourceRange Range,
00415                                        const MacroArgs *Args) {
00416   addMacroExpansion(Id, MD->getMacroInfo(), Range);
00417 }
00418 
00419 void PreprocessingRecord::MacroDefined(const Token &Id,
00420                                        const MacroDirective *MD) {
00421   const MacroInfo *MI = MD->getMacroInfo();
00422   SourceRange R(MI->getDefinitionLoc(), MI->getDefinitionEndLoc());
00423   MacroDefinition *Def
00424       = new (*this) MacroDefinition(Id.getIdentifierInfo(), R);
00425   addPreprocessedEntity(Def);
00426   MacroDefinitions[MI] = Def;
00427 }
00428 
00429 void PreprocessingRecord::MacroUndefined(const Token &Id,
00430                                          const MacroDirective *MD) {
00431   // Note: MI may be null (when #undef'ining an undefined macro).
00432   if (MD)
00433     MacroDefinitions.erase(MD->getMacroInfo());
00434 }
00435 
00436 void PreprocessingRecord::InclusionDirective(
00437     SourceLocation HashLoc,
00438     const clang::Token &IncludeTok,
00439     StringRef FileName,
00440     bool IsAngled,
00441     CharSourceRange FilenameRange,
00442     const FileEntry *File,
00443     StringRef SearchPath,
00444     StringRef RelativePath,
00445     const Module *Imported) {
00446   InclusionDirective::InclusionKind Kind = InclusionDirective::Include;
00447   
00448   switch (IncludeTok.getIdentifierInfo()->getPPKeywordID()) {
00449   case tok::pp_include: 
00450     Kind = InclusionDirective::Include; 
00451     break;
00452     
00453   case tok::pp_import: 
00454     Kind = InclusionDirective::Import; 
00455     break;
00456     
00457   case tok::pp_include_next: 
00458     Kind = InclusionDirective::IncludeNext; 
00459     break;
00460     
00461   case tok::pp___include_macros: 
00462     Kind = InclusionDirective::IncludeMacros;
00463     break;
00464     
00465   default:
00466     llvm_unreachable("Unknown include directive kind");
00467   }
00468 
00469   SourceLocation EndLoc;
00470   if (!IsAngled) {
00471     EndLoc = FilenameRange.getBegin();
00472   } else {
00473     EndLoc = FilenameRange.getEnd();
00474     if (FilenameRange.isCharRange())
00475       EndLoc = EndLoc.getLocWithOffset(-1); // the InclusionDirective expects
00476                                             // a token range.
00477   }
00478   clang::InclusionDirective *ID
00479     = new (*this) clang::InclusionDirective(*this, Kind, FileName, !IsAngled,
00480                                             (bool)Imported,
00481                                             File, SourceRange(HashLoc, EndLoc));
00482   addPreprocessedEntity(ID);
00483 }
00484 
00485 size_t PreprocessingRecord::getTotalMemory() const {
00486   return BumpAlloc.getTotalMemory()
00487     + llvm::capacity_in_bytes(MacroDefinitions)
00488     + llvm::capacity_in_bytes(PreprocessedEntities)
00489     + llvm::capacity_in_bytes(LoadedPreprocessedEntities);
00490 }