PreprocessingRecord.cpp 19 KB

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