PreprocessingRecord.cpp 17 KB

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