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