PreprocessingRecord.cpp 18 KB

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