1 //===--- PreprocessingRecord.cpp - Record of Preprocessing ------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file implements the PreprocessingRecord class, which maintains a record
11 // of what occurred during preprocessing, and its helpers.
13 //===----------------------------------------------------------------------===//
14 #include "clang/Lex/PreprocessingRecord.h"
15 #include "clang/Lex/MacroInfo.h"
16 #include "clang/Lex/Token.h"
18 using namespace clang;
20 ExternalPreprocessingRecordSource::~ExternalPreprocessingRecordSource() { }
22 void PreprocessingRecord::MaybeLoadPreallocatedEntities() const {
23 if (!ExternalSource || LoadedPreallocatedEntities)
26 LoadedPreallocatedEntities = true;
27 ExternalSource->ReadPreprocessedEntities();
30 PreprocessingRecord::PreprocessingRecord()
31 : ExternalSource(0), NumPreallocatedEntities(0),
32 LoadedPreallocatedEntities(false)
36 PreprocessingRecord::iterator
37 PreprocessingRecord::begin(bool OnlyLocalEntities) {
38 if (OnlyLocalEntities)
39 return PreprocessedEntities.begin() + NumPreallocatedEntities;
41 MaybeLoadPreallocatedEntities();
42 return PreprocessedEntities.begin();
45 PreprocessingRecord::iterator PreprocessingRecord::end(bool OnlyLocalEntities) {
46 if (!OnlyLocalEntities)
47 MaybeLoadPreallocatedEntities();
49 return PreprocessedEntities.end();
52 PreprocessingRecord::const_iterator
53 PreprocessingRecord::begin(bool OnlyLocalEntities) const {
54 if (OnlyLocalEntities)
55 return PreprocessedEntities.begin() + NumPreallocatedEntities;
57 MaybeLoadPreallocatedEntities();
58 return PreprocessedEntities.begin();
61 PreprocessingRecord::const_iterator
62 PreprocessingRecord::end(bool OnlyLocalEntities) const {
63 if (!OnlyLocalEntities)
64 MaybeLoadPreallocatedEntities();
66 return PreprocessedEntities.end();
69 void PreprocessingRecord::addPreprocessedEntity(PreprocessedEntity *Entity) {
70 PreprocessedEntities.push_back(Entity);
73 void PreprocessingRecord::SetExternalSource(
74 ExternalPreprocessingRecordSource &Source,
75 unsigned NumPreallocatedEntities) {
76 assert(!ExternalSource &&
77 "Preprocessing record already has an external source");
78 ExternalSource = &Source;
79 this->NumPreallocatedEntities = NumPreallocatedEntities;
80 PreprocessedEntities.insert(PreprocessedEntities.begin(),
81 NumPreallocatedEntities, 0);
84 void PreprocessingRecord::SetPreallocatedEntity(unsigned Index,
85 PreprocessedEntity *Entity) {
86 assert(Index < NumPreallocatedEntities &&"Out-of-bounds preallocated entity");
87 PreprocessedEntities[Index] = Entity;
90 void PreprocessingRecord::RegisterMacroDefinition(MacroInfo *Macro,
91 MacroDefinition *MD) {
92 MacroDefinitions[Macro] = MD;
95 MacroDefinition *PreprocessingRecord::findMacroDefinition(const MacroInfo *MI) {
96 llvm::DenseMap<const MacroInfo *, MacroDefinition *>::iterator Pos
97 = MacroDefinitions.find(MI);
98 if (Pos == MacroDefinitions.end())
104 void PreprocessingRecord::MacroExpands(const Token &Id, const MacroInfo* MI) {
105 if (MacroDefinition *Def = findMacroDefinition(MI))
106 PreprocessedEntities.push_back(
107 new (*this) MacroInstantiation(Id.getIdentifierInfo(),
112 void PreprocessingRecord::MacroDefined(const IdentifierInfo *II,
113 const MacroInfo *MI) {
114 SourceRange R(MI->getDefinitionLoc(), MI->getDefinitionEndLoc());
116 = new (*this) MacroDefinition(II, MI->getDefinitionLoc(), R);
117 MacroDefinitions[MI] = Def;
118 PreprocessedEntities.push_back(Def);
121 void PreprocessingRecord::MacroUndefined(SourceLocation Loc,
122 const IdentifierInfo *II,
123 const MacroInfo *MI) {
124 llvm::DenseMap<const MacroInfo *, MacroDefinition *>::iterator Pos
125 = MacroDefinitions.find(MI);
126 if (Pos != MacroDefinitions.end())
127 MacroDefinitions.erase(Pos);