git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@69987 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Steve Naroff 2009-04-24 20:03:17 +00:00
Родитель ff11cd148b
Коммит 83d63c7881
8 изменённых файлов: 104 добавлений и 37 удалений

Просмотреть файл

@ -211,7 +211,11 @@ namespace clang {
/// \brief The value of the next __COUNTER__ to dispense.
/// [PP_COUNTER_VALUE, Val]
PP_COUNTER_VALUE = 4
PP_COUNTER_VALUE = 4,
/// \brief Describes one header file info [isImport, DirInfo, NumIncludes]
/// ControlloingMacro is optional.
PP_HEADER_FILE_INFO = 5
};
/// \defgroup PCHAST Precompiled header AST constants

Просмотреть файл

@ -23,6 +23,30 @@ class FileEntry;
class FileManager;
class IdentifierInfo;
/// HeaderFileInfo - The preprocessor keeps track of this information for each
/// file that is #included.
struct HeaderFileInfo {
/// isImport - True if this is a #import'd or #pragma once file.
bool isImport : 1;
/// DirInfo - Keep track of whether this is a system header, and if so,
/// whether it is C++ clean or not. This can be set by the include paths or
/// by #pragma gcc system_header. This is an instance of
/// SrcMgr::CharacteristicKind.
unsigned DirInfo : 2;
/// NumIncludes - This is the number of times the file has been included
/// already.
unsigned short NumIncludes;
/// ControllingMacro - If this file has a #ifndef XXX (or equivalent) guard
/// that protects the entire contents of the file, this is the identifier
/// for the macro that controls whether or not it has any effect.
const IdentifierInfo *ControllingMacro;
HeaderFileInfo() : isImport(false), DirInfo(SrcMgr::C_User),
NumIncludes(0), ControllingMacro(0) {}
};
/// HeaderSearch - This class encapsulates the information needed to find the
/// file referenced by a #include or #include_next, (sub-)framework lookup, etc.
@ -39,35 +63,10 @@ class HeaderSearch {
unsigned SystemDirIdx;
bool NoCurDirSearch;
/// PreFileInfo - The preprocessor keeps track of this information for each
/// file that is #included.
struct PerFileInfo {
/// isImport - True if this is a #import'd or #pragma once file.
bool isImport : 1;
/// DirInfo - Keep track of whether this is a system header, and if so,
/// whether it is C++ clean or not. This can be set by the include paths or
/// by #pragma gcc system_header. This is an instance of
/// SrcMgr::CharacteristicKind.
unsigned DirInfo : 2;
/// NumIncludes - This is the number of times the file has been included
/// already.
unsigned short NumIncludes;
/// ControllingMacro - If this file has a #ifndef XXX (or equivalent) guard
/// that protects the entire contents of the file, this is the identifier
/// for the macro that controls whether or not it has any effect.
const IdentifierInfo *ControllingMacro;
PerFileInfo() : isImport(false), DirInfo(SrcMgr::C_User),
NumIncludes(0), ControllingMacro(0) {}
};
/// FileInfo - This contains all of the preprocessor-specific data about files
/// that are included. The vector is indexed by the FileEntry's UID.
///
std::vector<PerFileInfo> FileInfo;
std::vector<HeaderFileInfo> FileInfo;
/// LookupFileCache - This is keeps track of each lookup performed by
/// LookupFile. The first part of the value is the starting index in
@ -191,12 +190,19 @@ public:
void IncrementFrameworkLookupCount() { ++NumFrameworkLookups; }
typedef std::vector<HeaderFileInfo>::iterator header_file_iterator;
header_file_iterator header_file_begin() { return FileInfo.begin(); }
header_file_iterator header_file_end() { return FileInfo.end(); }
// Used by PCHReader.
void setHeaderFileInfoForUID(HeaderFileInfo HFI, unsigned UID);
void PrintStats();
private:
/// getFileInfo - Return the PerFileInfo structure for the specified
/// getFileInfo - Return the HeaderFileInfo structure for the specified
/// FileEntry.
PerFileInfo &getFileInfo(const FileEntry *FE);
HeaderFileInfo &getFileInfo(const FileEntry *FE);
};
} // end namespace clang

Просмотреть файл

@ -23,6 +23,7 @@
#include "clang/AST/Type.h"
#include "clang/Lex/MacroInfo.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Lex/HeaderSearch.h"
#include "clang/Basic/OnDiskHashTable.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/SourceManagerInternals.h"
@ -1444,6 +1445,7 @@ void PCHReader::ReadMacroRecord(uint64_t Offset) {
RecordData Record;
llvm::SmallVector<IdentifierInfo*, 16> MacroArgs;
MacroInfo *Macro = 0;
while (true) {
unsigned Code = Stream.ReadCode();
switch (Code) {
@ -1536,7 +1538,9 @@ void PCHReader::ReadMacroRecord(uint64_t Offset) {
Macro->AddTokenToBody(Tok);
break;
}
}
case pch::PP_HEADER_FILE_INFO:
break; // Already processed by ReadPreprocessorBlock().
}
}
}
@ -1545,6 +1549,7 @@ bool PCHReader::ReadPreprocessorBlock() {
return Error("Malformed preprocessor block record");
RecordData Record;
unsigned NumHeaderInfos = 0;
while (true) {
unsigned Code = Stream.ReadCode();
switch (Code) {
@ -1581,8 +1586,16 @@ bool PCHReader::ReadPreprocessorBlock() {
case pch::PP_MACRO_OBJECT_LIKE:
case pch::PP_MACRO_FUNCTION_LIKE:
case pch::PP_TOKEN:
// Once we've hit a macro definition or a token, we're done.
return false;
break;
case pch::PP_HEADER_FILE_INFO: {
HeaderFileInfo HFI;
HFI.isImport = Record[0];
HFI.DirInfo = Record[1];
HFI.NumIncludes = Record[2];
HFI.ControllingMacro = DecodeIdentifierInfo(Record[3]);
PP.getHeaderSearchInfo().setHeaderFileInfoForUID(HFI, NumHeaderInfos++);
break;
}
}
}
}

Просмотреть файл

@ -23,6 +23,7 @@
#include "clang/AST/Type.h"
#include "clang/Lex/MacroInfo.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Lex/HeaderSearch.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/OnDiskHashTable.h"
#include "clang/Basic/SourceManager.h"
@ -1548,6 +1549,21 @@ void PCHWriter::WritePreprocessor(const Preprocessor &PP) {
++NumMacros;
}
// Loop over all the header files.
HeaderSearch &HS = PP.getHeaderSearchInfo();
for (HeaderSearch::header_file_iterator I = HS.header_file_begin(),
E = HS.header_file_end();
I != E; ++I) {
Record.push_back((*I).isImport);
Record.push_back((*I).DirInfo);
Record.push_back((*I).NumIncludes);
if ((*I).ControllingMacro)
AddIdentifierRef((*I).ControllingMacro, Record);
else
Record.push_back(0);
Stream.EmitRecord(pch::PP_HEADER_FILE_INFO, Record);
Record.clear();
}
Stream.ExitBlock();
}

Просмотреть файл

@ -377,14 +377,20 @@ LookupSubframeworkHeader(const char *FilenameStart,
//===----------------------------------------------------------------------===//
/// getFileInfo - Return the PerFileInfo structure for the specified
/// getFileInfo - Return the HeaderFileInfo structure for the specified
/// FileEntry.
HeaderSearch::PerFileInfo &HeaderSearch::getFileInfo(const FileEntry *FE) {
HeaderFileInfo &HeaderSearch::getFileInfo(const FileEntry *FE) {
if (FE->getUID() >= FileInfo.size())
FileInfo.resize(FE->getUID()+1);
return FileInfo[FE->getUID()];
}
void HeaderSearch::setHeaderFileInfoForUID(HeaderFileInfo HFI, unsigned UID) {
if (UID >= FileInfo.size())
FileInfo.resize(UID+1);
FileInfo[UID] = HFI;
}
/// ShouldEnterIncludeFile - Mark the specified file as a target of of a
/// #include, #include_next, or #import directive. Return false if #including
/// the file will have no effect or true if we should include it.
@ -392,7 +398,7 @@ bool HeaderSearch::ShouldEnterIncludeFile(const FileEntry *File, bool isImport){
++NumIncluded; // Count # of attempted #includes.
// Get information about this file.
PerFileInfo &FileInfo = getFileInfo(File);
HeaderFileInfo &FileInfo = getFileInfo(File);
// If this is a #import directive, check that we have not already imported
// this header.

Просмотреть файл

@ -179,7 +179,7 @@ bool Preprocessor::HandleEndOfFile(Token &Result, bool isEndOfMacro) {
if (CurPPLexer) { // Not ending a macro, ignore it.
if (const IdentifierInfo *ControllingMacro =
CurPPLexer->MIOpt.GetControllingMacroAtEndOfFile()) {
// Okay, this has a controlling macro, remember in PerFileInfo.
// Okay, this has a controlling macro, remember in HeaderFileInfo.
if (const FileEntry *FE =
SourceMgr.getFileEntryForID(CurPPLexer->getFileID()))
HeaderInfo.SetFileControllingMacro(FE, ControllingMacro);

7
test/PCH/objc_import.h Normal file
Просмотреть файл

@ -0,0 +1,7 @@
/* For use with the objc_import.m test */
@interface TestPCH
+ alloc;
- (void)instMethod;
@end

15
test/PCH/objc_import.m Normal file
Просмотреть файл

@ -0,0 +1,15 @@
// Test this without pch.
// RUN: clang-cc -include %S/objc_import.h -fsyntax-only -verify %s &&
// Test with pch.
// RUN: clang-cc -x=objective-c -emit-pch -o %t %S/objc_import.h &&
// RUN: clang-cc -include-pch %t -fsyntax-only -verify %s
#import "objc_import.h"
void func() {
TestPCH *xx;
xx = [TestPCH alloc];
[xx instMethod];
}