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 18 using namespace clang; 19 20 ExternalPreprocessingRecordSource::~ExternalPreprocessingRecordSource() { } 21 22 void PreprocessingRecord::MaybeLoadPreallocatedEntities() const { 23 if (!ExternalSource || LoadedPreallocatedEntities) 24 return; 25 26 LoadedPreallocatedEntities = true; 27 ExternalSource->ReadPreprocessedEntities(); 28 } 29 30 PreprocessingRecord::PreprocessingRecord() 31 : ExternalSource(0), NumPreallocatedEntities(0), 32 LoadedPreallocatedEntities(false) 33 { 34 } 35 36 PreprocessingRecord::iterator 37 PreprocessingRecord::begin(bool OnlyLocalEntities) { 38 if (OnlyLocalEntities) 39 return PreprocessedEntities.begin() + NumPreallocatedEntities; 40 41 MaybeLoadPreallocatedEntities(); 42 return PreprocessedEntities.begin(); 43 } 44 45 PreprocessingRecord::iterator PreprocessingRecord::end(bool OnlyLocalEntities) { 46 if (!OnlyLocalEntities) 47 MaybeLoadPreallocatedEntities(); 48 49 return PreprocessedEntities.end(); 50 } 51 52 PreprocessingRecord::const_iterator 53 PreprocessingRecord::begin(bool OnlyLocalEntities) const { 54 if (OnlyLocalEntities) 55 return PreprocessedEntities.begin() + NumPreallocatedEntities; 56 57 MaybeLoadPreallocatedEntities(); 58 return PreprocessedEntities.begin(); 59 } 60 61 PreprocessingRecord::const_iterator 62 PreprocessingRecord::end(bool OnlyLocalEntities) const { 63 if (!OnlyLocalEntities) 64 MaybeLoadPreallocatedEntities(); 65 66 return PreprocessedEntities.end(); 67 } 68 69 void PreprocessingRecord::addPreprocessedEntity(PreprocessedEntity *Entity) { 70 PreprocessedEntities.push_back(Entity); 71 } 72 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); 82 } 83 84 void PreprocessingRecord::SetPreallocatedEntity(unsigned Index, 85 PreprocessedEntity *Entity) { 86 assert(Index < NumPreallocatedEntities &&"Out-of-bounds preallocated entity"); 87 PreprocessedEntities[Index] = Entity; 88 } 89 90 void PreprocessingRecord::RegisterMacroDefinition(MacroInfo *Macro, 91 MacroDefinition *MD) { 92 MacroDefinitions[Macro] = MD; 93 } 94 95 MacroDefinition *PreprocessingRecord::findMacroDefinition(const MacroInfo *MI) { 96 llvm::DenseMap<const MacroInfo *, MacroDefinition *>::iterator Pos 97 = MacroDefinitions.find(MI); 98 if (Pos == MacroDefinitions.end()) 99 return 0; 100 101 return Pos->second; 102 } 103 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(), 108 Id.getLocation(), 109 Def)); 110 } 111 112 void PreprocessingRecord::MacroDefined(const IdentifierInfo *II, 113 const MacroInfo *MI) { 114 SourceRange R(MI->getDefinitionLoc(), MI->getDefinitionEndLoc()); 115 MacroDefinition *Def 116 = new (*this) MacroDefinition(II, MI->getDefinitionLoc(), R); 117 MacroDefinitions[MI] = Def; 118 PreprocessedEntities.push_back(Def); 119 } 120 121 void PreprocessingRecord::MacroUndefined(const IdentifierInfo *II, 122 const MacroInfo *MI) { 123 llvm::DenseMap<const MacroInfo *, MacroDefinition *>::iterator Pos 124 = MacroDefinitions.find(MI); 125 if (Pos != MacroDefinitions.end()) 126 MacroDefinitions.erase(Pos); 127 } 128 129