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(0) { 44 } 45 46 /// \brief Returns a pair of [Begin, End) iterators of preprocessed entities 47 /// that source range \p Range encompasses. 48 std::pair<PreprocessingRecord::iterator, PreprocessingRecord::iterator> 49 PreprocessingRecord::getPreprocessedEntitiesInRange(SourceRange Range) { 50 if (Range.isInvalid()) 51 return std::make_pair(iterator(), iterator()); 52 53 if (CachedRangeQuery.Range == Range) { 54 return std::make_pair(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 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 int Pos = PPEI.Position; 94 if (Pos < 0) { 95 assert(unsigned(-Pos-1) < LoadedPreprocessedEntities.size() && 96 "Out-of bounds loaded preprocessed entity"); 97 assert(ExternalSource && "No external source to load from"); 98 unsigned LoadedIndex = LoadedPreprocessedEntities.size()+Pos; 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(Pos) < PreprocessedEntities.size() && 117 "Out-of bounds local preprocessed entity"); 118 return isPreprocessedEntityIfInFileID(PreprocessedEntities[Pos], 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<int, int> 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 PreprocessingRecord::PPEntityID 243 PreprocessingRecord::addPreprocessedEntity(PreprocessedEntity *Entity) { 244 assert(Entity); 245 SourceLocation BeginLoc = Entity->getSourceRange().getBegin(); 246 247 if (isa<MacroDefinition>(Entity)) { 248 assert((PreprocessedEntities.empty() || 249 !SourceMgr.isBeforeInTranslationUnit(BeginLoc, 250 PreprocessedEntities.back()->getSourceRange().getBegin())) && 251 "a macro definition was encountered out-of-order"); 252 PreprocessedEntities.push_back(Entity); 253 return getPPEntityID(PreprocessedEntities.size()-1, /*isLoaded=*/false); 254 } 255 256 // Check normal case, this entity begin location is after the previous one. 257 if (PreprocessedEntities.empty() || 258 !SourceMgr.isBeforeInTranslationUnit(BeginLoc, 259 PreprocessedEntities.back()->getSourceRange().getBegin())) { 260 PreprocessedEntities.push_back(Entity); 261 return getPPEntityID(PreprocessedEntities.size()-1, /*isLoaded=*/false); 262 } 263 264 // The entity's location is not after the previous one; this can happen with 265 // include directives that form the filename using macros, e.g: 266 // "#include MACRO(STUFF)" 267 // or with macro expansions inside macro arguments where the arguments are 268 // not expanded in the same order as listed, e.g: 269 // \code 270 // #define M1 1 271 // #define M2 2 272 // #define FM(x,y) y x 273 // FM(M1, M2) 274 // \endcode 275 276 typedef std::vector<PreprocessedEntity *>::iterator pp_iter; 277 278 // Usually there are few macro expansions when defining the filename, do a 279 // linear search for a few entities. 280 unsigned count = 0; 281 for (pp_iter RI = PreprocessedEntities.end(), 282 Begin = PreprocessedEntities.begin(); 283 RI != Begin && count < 4; --RI, ++count) { 284 pp_iter I = RI; 285 --I; 286 if (!SourceMgr.isBeforeInTranslationUnit(BeginLoc, 287 (*I)->getSourceRange().getBegin())) { 288 pp_iter insertI = PreprocessedEntities.insert(RI, Entity); 289 return getPPEntityID(insertI - PreprocessedEntities.begin(), 290 /*isLoaded=*/false); 291 } 292 } 293 294 // Linear search unsuccessful. Do a binary search. 295 pp_iter I = std::upper_bound(PreprocessedEntities.begin(), 296 PreprocessedEntities.end(), 297 BeginLoc, 298 PPEntityComp<&SourceRange::getBegin>(SourceMgr)); 299 pp_iter insertI = PreprocessedEntities.insert(I, Entity); 300 return getPPEntityID(insertI - PreprocessedEntities.begin(), 301 /*isLoaded=*/false); 302 } 303 304 void PreprocessingRecord::SetExternalSource( 305 ExternalPreprocessingRecordSource &Source) { 306 assert(!ExternalSource && 307 "Preprocessing record already has an external source"); 308 ExternalSource = &Source; 309 } 310 311 unsigned PreprocessingRecord::allocateLoadedEntities(unsigned NumEntities) { 312 unsigned Result = LoadedPreprocessedEntities.size(); 313 LoadedPreprocessedEntities.resize(LoadedPreprocessedEntities.size() 314 + NumEntities); 315 return Result; 316 } 317 318 void PreprocessingRecord::RegisterMacroDefinition(MacroInfo *Macro, 319 PPEntityID PPID) { 320 MacroDefinitions[Macro] = PPID; 321 } 322 323 /// \brief Retrieve the preprocessed entity at the given ID. 324 PreprocessedEntity *PreprocessingRecord::getPreprocessedEntity(PPEntityID PPID){ 325 if (PPID.ID < 0) { 326 unsigned Index = -PPID.ID - 1; 327 assert(Index < LoadedPreprocessedEntities.size() && 328 "Out-of bounds loaded preprocessed entity"); 329 return getLoadedPreprocessedEntity(Index); 330 } 331 332 if (PPID.ID == 0) 333 return 0; 334 unsigned Index = PPID.ID - 1; 335 assert(Index < PreprocessedEntities.size() && 336 "Out-of bounds local preprocessed entity"); 337 return PreprocessedEntities[Index]; 338 } 339 340 /// \brief Retrieve the loaded preprocessed entity at the given index. 341 PreprocessedEntity * 342 PreprocessingRecord::getLoadedPreprocessedEntity(unsigned Index) { 343 assert(Index < LoadedPreprocessedEntities.size() && 344 "Out-of bounds loaded preprocessed entity"); 345 assert(ExternalSource && "No external source to load from"); 346 PreprocessedEntity *&Entity = LoadedPreprocessedEntities[Index]; 347 if (!Entity) { 348 Entity = ExternalSource->ReadPreprocessedEntity(Index); 349 if (!Entity) // Failed to load. 350 Entity = new (*this) 351 PreprocessedEntity(PreprocessedEntity::InvalidKind, SourceRange()); 352 } 353 return Entity; 354 } 355 356 MacroDefinition *PreprocessingRecord::findMacroDefinition(const MacroInfo *MI) { 357 llvm::DenseMap<const MacroInfo *, PPEntityID>::iterator Pos 358 = MacroDefinitions.find(MI); 359 if (Pos == MacroDefinitions.end()) 360 return 0; 361 362 PreprocessedEntity *Entity = getPreprocessedEntity(Pos->second); 363 if (Entity->isInvalid()) 364 return 0; 365 return cast<MacroDefinition>(Entity); 366 } 367 368 void PreprocessingRecord::addMacroExpansion(const Token &Id, 369 const MacroInfo *MI, 370 SourceRange Range) { 371 // We don't record nested macro expansions. 372 if (Id.getLocation().isMacroID()) 373 return; 374 375 if (MI->isBuiltinMacro()) 376 addPreprocessedEntity( 377 new (*this) MacroExpansion(Id.getIdentifierInfo(),Range)); 378 else if (MacroDefinition *Def = findMacroDefinition(MI)) 379 addPreprocessedEntity( 380 new (*this) MacroExpansion(Def, Range)); 381 } 382 383 void PreprocessingRecord::Ifdef(SourceLocation Loc, const Token &MacroNameTok, 384 const MacroInfo *MI) { 385 // This is not actually a macro expansion but record it as a macro reference. 386 if (MI) 387 addMacroExpansion(MacroNameTok, MI, MacroNameTok.getLocation()); 388 } 389 390 void PreprocessingRecord::Ifndef(SourceLocation Loc, const Token &MacroNameTok, 391 const MacroInfo *MI) { 392 // This is not actually a macro expansion but record it as a macro reference. 393 if (MI) 394 addMacroExpansion(MacroNameTok, MI, MacroNameTok.getLocation()); 395 } 396 397 void PreprocessingRecord::Defined(const Token &MacroNameTok, 398 const MacroInfo *MI) { 399 // This is not actually a macro expansion but record it as a macro reference. 400 if (MI) 401 addMacroExpansion(MacroNameTok, MI, MacroNameTok.getLocation()); 402 } 403 404 void PreprocessingRecord::MacroExpands(const Token &Id, const MacroInfo* MI, 405 SourceRange Range) { 406 addMacroExpansion(Id, MI, Range); 407 } 408 409 void PreprocessingRecord::MacroDefined(const Token &Id, 410 const MacroInfo *MI) { 411 SourceRange R(MI->getDefinitionLoc(), MI->getDefinitionEndLoc()); 412 MacroDefinition *Def 413 = new (*this) MacroDefinition(Id.getIdentifierInfo(), R); 414 MacroDefinitions[MI] = addPreprocessedEntity(Def); 415 } 416 417 void PreprocessingRecord::MacroUndefined(const Token &Id, 418 const MacroInfo *MI) { 419 // Note: MI may be null (when #undef'ining an undefined macro). 420 if (MI) 421 MacroDefinitions.erase(MI); 422 } 423 424 void PreprocessingRecord::InclusionDirective( 425 SourceLocation HashLoc, 426 const clang::Token &IncludeTok, 427 StringRef FileName, 428 bool IsAngled, 429 CharSourceRange FilenameRange, 430 const FileEntry *File, 431 StringRef SearchPath, 432 StringRef RelativePath, 433 const Module *Imported) { 434 InclusionDirective::InclusionKind Kind = InclusionDirective::Include; 435 436 switch (IncludeTok.getIdentifierInfo()->getPPKeywordID()) { 437 case tok::pp_include: 438 Kind = InclusionDirective::Include; 439 break; 440 441 case tok::pp_import: 442 Kind = InclusionDirective::Import; 443 break; 444 445 case tok::pp_include_next: 446 Kind = InclusionDirective::IncludeNext; 447 break; 448 449 case tok::pp___include_macros: 450 Kind = InclusionDirective::IncludeMacros; 451 break; 452 453 default: 454 llvm_unreachable("Unknown include directive kind"); 455 } 456 457 SourceLocation EndLoc; 458 if (!IsAngled) { 459 EndLoc = FilenameRange.getBegin(); 460 } else { 461 EndLoc = FilenameRange.getEnd(); 462 if (FilenameRange.isCharRange()) 463 EndLoc = EndLoc.getLocWithOffset(-1); // the InclusionDirective expects 464 // a token range. 465 } 466 clang::InclusionDirective *ID 467 = new (*this) clang::InclusionDirective(*this, Kind, FileName, !IsAngled, 468 (bool)Imported, 469 File, SourceRange(HashLoc, EndLoc)); 470 addPreprocessedEntity(ID); 471 } 472 473 size_t PreprocessingRecord::getTotalMemory() const { 474 return BumpAlloc.getTotalMemory() 475 + llvm::capacity_in_bytes(MacroDefinitions) 476 + llvm::capacity_in_bytes(PreprocessedEntities) 477 + llvm::capacity_in_bytes(LoadedPreprocessedEntities); 478 } 479