mirror of
https://github.com/Gericom/teak-llvm.git
synced 2025-06-26 14:58:59 -04:00

includes get resolved, especially when they are found relatively to another include file. We also try to get it working for framework includes, but that part of the code is untested, as I don't have a code base that uses it. llvm-svn: 130246
187 lines
6.2 KiB
C++
187 lines
6.2 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() { }
|
|
|
|
|
|
InclusionDirective::InclusionDirective(PreprocessingRecord &PPRec,
|
|
InclusionKind Kind,
|
|
llvm::StringRef FileName,
|
|
bool InQuotes, const FileEntry *File,
|
|
SourceRange Range)
|
|
: PreprocessingDirective(InclusionDirectiveKind, Range),
|
|
InQuotes(InQuotes), Kind(Kind), File(File)
|
|
{
|
|
char *Memory
|
|
= (char*)PPRec.Allocate(FileName.size() + 1, llvm::alignOf<char>());
|
|
memcpy(Memory, FileName.data(), FileName.size());
|
|
Memory[FileName.size()] = 0;
|
|
this->FileName = llvm::StringRef(Memory, FileName.size());
|
|
}
|
|
|
|
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 Token &Id,
|
|
const MacroInfo *MI) {
|
|
SourceRange R(MI->getDefinitionLoc(), MI->getDefinitionEndLoc());
|
|
MacroDefinition *Def
|
|
= new (*this) MacroDefinition(Id.getIdentifierInfo(),
|
|
MI->getDefinitionLoc(),
|
|
R);
|
|
MacroDefinitions[MI] = Def;
|
|
PreprocessedEntities.push_back(Def);
|
|
}
|
|
|
|
void PreprocessingRecord::MacroUndefined(const Token &Id,
|
|
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,
|
|
llvm::StringRef SearchPath,
|
|
llvm::StringRef RelativePath) {
|
|
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(*this, Kind, FileName, !IsAngled,
|
|
File, SourceRange(HashLoc, EndLoc));
|
|
PreprocessedEntities.push_back(ID);
|
|
}
|