clang API Documentation
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 }