blob: c446d96b4527caa282deb13729441dafb7cffb68 [file] [log] [blame]
Douglas Gregor065f8d12010-03-18 17:52:52 +00001//===--- 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
18using namespace clang;
19
Douglas Gregoraae92242010-03-19 21:51:54 +000020ExternalPreprocessingRecordSource::~ExternalPreprocessingRecordSource() { }
21
22void PreprocessingRecord::MaybeLoadPreallocatedEntities() const {
23 if (!ExternalSource || LoadedPreallocatedEntities)
24 return;
25
26 LoadedPreallocatedEntities = true;
27 ExternalSource->ReadPreprocessedEntities();
28}
29
30PreprocessingRecord::PreprocessingRecord()
31 : ExternalSource(0), NumPreallocatedEntities(0),
32 LoadedPreallocatedEntities(false)
33{
34}
35
36PreprocessingRecord::iterator
37PreprocessingRecord::begin(bool OnlyLocalEntities) {
38 if (OnlyLocalEntities)
39 return PreprocessedEntities.begin() + NumPreallocatedEntities;
40
41 MaybeLoadPreallocatedEntities();
42 return PreprocessedEntities.begin();
43}
44
45PreprocessingRecord::iterator PreprocessingRecord::end(bool OnlyLocalEntities) {
46 if (!OnlyLocalEntities)
47 MaybeLoadPreallocatedEntities();
48
49 return PreprocessedEntities.end();
50}
51
52PreprocessingRecord::const_iterator
53PreprocessingRecord::begin(bool OnlyLocalEntities) const {
54 if (OnlyLocalEntities)
55 return PreprocessedEntities.begin() + NumPreallocatedEntities;
56
57 MaybeLoadPreallocatedEntities();
58 return PreprocessedEntities.begin();
59}
60
61PreprocessingRecord::const_iterator
62PreprocessingRecord::end(bool OnlyLocalEntities) const {
63 if (!OnlyLocalEntities)
64 MaybeLoadPreallocatedEntities();
65
66 return PreprocessedEntities.end();
67}
68
Douglas Gregor065f8d12010-03-18 17:52:52 +000069void PreprocessingRecord::addPreprocessedEntity(PreprocessedEntity *Entity) {
70 PreprocessedEntities.push_back(Entity);
71}
72
Douglas Gregoraae92242010-03-19 21:51:54 +000073void 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
84void PreprocessingRecord::SetPreallocatedEntity(unsigned Index,
85 PreprocessedEntity *Entity) {
86 assert(Index < NumPreallocatedEntities &&"Out-of-bounds preallocated entity");
87 PreprocessedEntities[Index] = Entity;
88}
89
90void PreprocessingRecord::RegisterMacroDefinition(MacroInfo *Macro,
91 MacroDefinition *MD) {
92 MacroDefinitions[Macro] = MD;
93}
94
Douglas Gregor8aaca672010-03-19 21:58:23 +000095MacroDefinition *PreprocessingRecord::findMacroDefinition(const MacroInfo *MI) {
Douglas Gregor7dc87222010-03-19 17:12:43 +000096 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
104void PreprocessingRecord::MacroExpands(const Token &Id, const MacroInfo* MI) {
Douglas Gregor8aaca672010-03-19 21:58:23 +0000105 if (MacroDefinition *Def = findMacroDefinition(MI))
106 PreprocessedEntities.push_back(
Douglas Gregor7dc87222010-03-19 17:12:43 +0000107 new (*this) MacroInstantiation(Id.getIdentifierInfo(),
108 Id.getLocation(),
Douglas Gregor8aaca672010-03-19 21:58:23 +0000109 Def));
Douglas Gregor7dc87222010-03-19 17:12:43 +0000110}
111
112void 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}
Douglas Gregoraae92242010-03-19 21:51:54 +0000120
Benjamin Kramerd05f31d2010-08-07 22:27:00 +0000121void PreprocessingRecord::MacroUndefined(SourceLocation Loc,
122 const IdentifierInfo *II,
Douglas Gregor8aaca672010-03-19 21:58:23 +0000123 const MacroInfo *MI) {
124 llvm::DenseMap<const MacroInfo *, MacroDefinition *>::iterator Pos
125 = MacroDefinitions.find(MI);
126 if (Pos != MacroDefinitions.end())
127 MacroDefinitions.erase(Pos);
128}
129