mirror of
https://github.com/Gericom/teak-llvm.git
synced 2025-06-26 23:09:03 -04:00

inclusion directives, keeping track of every #include, #import, etc. in the translation unit. We keep track of the source location and kind of the inclusion, how the file name was spelled, and the underlying file to which the inclusion resolved. llvm-svn: 116952
167 lines
5.7 KiB
C++
167 lines
5.7 KiB
C++
//===--- PreprocessingRecord.cpp - Record of Preprocessing ------*- C++ -*-===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This file implements the PreprocessingRecord class, which maintains a record
|
|
// of what occurred during preprocessing, and its helpers.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
#include "clang/Lex/PreprocessingRecord.h"
|
|
#include "clang/Lex/MacroInfo.h"
|
|
#include "clang/Lex/Token.h"
|
|
#include "clang/Basic/IdentifierTable.h"
|
|
#include "llvm/Support/ErrorHandling.h"
|
|
|
|
using namespace clang;
|
|
|
|
ExternalPreprocessingRecordSource::~ExternalPreprocessingRecordSource() { }
|
|
|
|
void PreprocessingRecord::MaybeLoadPreallocatedEntities() const {
|
|
if (!ExternalSource || LoadedPreallocatedEntities)
|
|
return;
|
|
|
|
LoadedPreallocatedEntities = true;
|
|
ExternalSource->ReadPreprocessedEntities();
|
|
}
|
|
|
|
PreprocessingRecord::PreprocessingRecord()
|
|
: ExternalSource(0), NumPreallocatedEntities(0),
|
|
LoadedPreallocatedEntities(false)
|
|
{
|
|
}
|
|
|
|
PreprocessingRecord::iterator
|
|
PreprocessingRecord::begin(bool OnlyLocalEntities) {
|
|
if (OnlyLocalEntities)
|
|
return PreprocessedEntities.begin() + NumPreallocatedEntities;
|
|
|
|
MaybeLoadPreallocatedEntities();
|
|
return PreprocessedEntities.begin();
|
|
}
|
|
|
|
PreprocessingRecord::iterator PreprocessingRecord::end(bool OnlyLocalEntities) {
|
|
if (!OnlyLocalEntities)
|
|
MaybeLoadPreallocatedEntities();
|
|
|
|
return PreprocessedEntities.end();
|
|
}
|
|
|
|
PreprocessingRecord::const_iterator
|
|
PreprocessingRecord::begin(bool OnlyLocalEntities) const {
|
|
if (OnlyLocalEntities)
|
|
return PreprocessedEntities.begin() + NumPreallocatedEntities;
|
|
|
|
MaybeLoadPreallocatedEntities();
|
|
return PreprocessedEntities.begin();
|
|
}
|
|
|
|
PreprocessingRecord::const_iterator
|
|
PreprocessingRecord::end(bool OnlyLocalEntities) const {
|
|
if (!OnlyLocalEntities)
|
|
MaybeLoadPreallocatedEntities();
|
|
|
|
return PreprocessedEntities.end();
|
|
}
|
|
|
|
void PreprocessingRecord::addPreprocessedEntity(PreprocessedEntity *Entity) {
|
|
PreprocessedEntities.push_back(Entity);
|
|
}
|
|
|
|
void PreprocessingRecord::SetExternalSource(
|
|
ExternalPreprocessingRecordSource &Source,
|
|
unsigned NumPreallocatedEntities) {
|
|
assert(!ExternalSource &&
|
|
"Preprocessing record already has an external source");
|
|
ExternalSource = &Source;
|
|
this->NumPreallocatedEntities = NumPreallocatedEntities;
|
|
PreprocessedEntities.insert(PreprocessedEntities.begin(),
|
|
NumPreallocatedEntities, 0);
|
|
}
|
|
|
|
void PreprocessingRecord::SetPreallocatedEntity(unsigned Index,
|
|
PreprocessedEntity *Entity) {
|
|
assert(Index < NumPreallocatedEntities &&"Out-of-bounds preallocated entity");
|
|
PreprocessedEntities[Index] = Entity;
|
|
}
|
|
|
|
void PreprocessingRecord::RegisterMacroDefinition(MacroInfo *Macro,
|
|
MacroDefinition *MD) {
|
|
MacroDefinitions[Macro] = MD;
|
|
}
|
|
|
|
MacroDefinition *PreprocessingRecord::findMacroDefinition(const MacroInfo *MI) {
|
|
llvm::DenseMap<const MacroInfo *, MacroDefinition *>::iterator Pos
|
|
= MacroDefinitions.find(MI);
|
|
if (Pos == MacroDefinitions.end())
|
|
return 0;
|
|
|
|
return Pos->second;
|
|
}
|
|
|
|
void PreprocessingRecord::MacroExpands(const Token &Id, const MacroInfo* MI) {
|
|
if (MacroDefinition *Def = findMacroDefinition(MI))
|
|
PreprocessedEntities.push_back(
|
|
new (*this) MacroInstantiation(Id.getIdentifierInfo(),
|
|
Id.getLocation(),
|
|
Def));
|
|
}
|
|
|
|
void PreprocessingRecord::MacroDefined(const IdentifierInfo *II,
|
|
const MacroInfo *MI) {
|
|
SourceRange R(MI->getDefinitionLoc(), MI->getDefinitionEndLoc());
|
|
MacroDefinition *Def
|
|
= new (*this) MacroDefinition(II, MI->getDefinitionLoc(), R);
|
|
MacroDefinitions[MI] = Def;
|
|
PreprocessedEntities.push_back(Def);
|
|
}
|
|
|
|
void PreprocessingRecord::MacroUndefined(SourceLocation Loc,
|
|
const IdentifierInfo *II,
|
|
const MacroInfo *MI) {
|
|
llvm::DenseMap<const MacroInfo *, MacroDefinition *>::iterator Pos
|
|
= MacroDefinitions.find(MI);
|
|
if (Pos != MacroDefinitions.end())
|
|
MacroDefinitions.erase(Pos);
|
|
}
|
|
|
|
void PreprocessingRecord::InclusionDirective(SourceLocation HashLoc,
|
|
const clang::Token &IncludeTok,
|
|
llvm::StringRef FileName,
|
|
bool IsAngled,
|
|
const FileEntry *File,
|
|
clang::SourceLocation EndLoc) {
|
|
InclusionDirective::InclusionKind Kind = InclusionDirective::Include;
|
|
|
|
switch (IncludeTok.getIdentifierInfo()->getPPKeywordID()) {
|
|
case tok::pp_include:
|
|
Kind = InclusionDirective::Include;
|
|
break;
|
|
|
|
case tok::pp_import:
|
|
Kind = InclusionDirective::Import;
|
|
break;
|
|
|
|
case tok::pp_include_next:
|
|
Kind = InclusionDirective::IncludeNext;
|
|
break;
|
|
|
|
case tok::pp___include_macros:
|
|
Kind = InclusionDirective::IncludeMacros;
|
|
break;
|
|
|
|
default:
|
|
llvm_unreachable("Unknown include directive kind");
|
|
return;
|
|
}
|
|
|
|
clang::InclusionDirective *ID
|
|
= new (*this) clang::InclusionDirective(Kind, FileName, !IsAngled, File,
|
|
SourceRange(HashLoc, EndLoc));
|
|
PreprocessedEntities.push_back(ID);
|
|
}
|