summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/tools/clang/lib/Serialization/ASTReader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Serialization/ASTReader.cpp')
-rw-r--r--contrib/llvm/tools/clang/lib/Serialization/ASTReader.cpp212
1 files changed, 149 insertions, 63 deletions
diff --git a/contrib/llvm/tools/clang/lib/Serialization/ASTReader.cpp b/contrib/llvm/tools/clang/lib/Serialization/ASTReader.cpp
index d984415..22caeb8 100644
--- a/contrib/llvm/tools/clang/lib/Serialization/ASTReader.cpp
+++ b/contrib/llvm/tools/clang/lib/Serialization/ASTReader.cpp
@@ -257,7 +257,8 @@ static bool checkPreprocessorOptions(const PreprocessorOptions &PPOpts,
const PreprocessorOptions &ExistingPPOpts,
DiagnosticsEngine *Diags,
FileManager &FileMgr,
- std::string &SuggestedPredefines) {
+ std::string &SuggestedPredefines,
+ const LangOptions &LangOpts) {
// Check macro definitions.
MacroDefinitionsMap ASTFileMacros;
collectMacroDefinitions(PPOpts, ASTFileMacros);
@@ -323,6 +324,15 @@ static bool checkPreprocessorOptions(const PreprocessorOptions &PPOpts,
return true;
}
+ // Detailed record is important since it is used for the module cache hash.
+ if (LangOpts.Modules &&
+ PPOpts.DetailedRecord != ExistingPPOpts.DetailedRecord) {
+ if (Diags) {
+ Diags->Report(diag::err_pch_pp_detailed_record) << PPOpts.DetailedRecord;
+ }
+ return true;
+ }
+
// Compute the #include and #include_macros lines we need.
for (unsigned I = 0, N = ExistingPPOpts.Includes.size(); I != N; ++I) {
StringRef File = ExistingPPOpts.Includes[I];
@@ -363,7 +373,8 @@ bool PCHValidator::ReadPreprocessorOptions(const PreprocessorOptions &PPOpts,
return checkPreprocessorOptions(PPOpts, ExistingPPOpts,
Complain? &Reader.Diags : 0,
PP.getFileManager(),
- SuggestedPredefines);
+ SuggestedPredefines,
+ PP.getLangOpts());
}
void PCHValidator::ReadHeaderFileInfo(const HeaderFileInfo &HFI,
@@ -428,8 +439,12 @@ ASTSelectorLookupTrait::ReadData(Selector, const unsigned char* d,
data_type Result;
Result.ID = Reader.getGlobalSelectorID(F, ReadUnalignedLE32(d));
- unsigned NumInstanceMethods = ReadUnalignedLE16(d);
- unsigned NumFactoryMethods = ReadUnalignedLE16(d);
+ unsigned NumInstanceMethodsAndBits = ReadUnalignedLE16(d);
+ unsigned NumFactoryMethodsAndBits = ReadUnalignedLE16(d);
+ Result.InstanceBits = NumInstanceMethodsAndBits & 0x3;
+ Result.FactoryBits = NumFactoryMethodsAndBits & 0x3;
+ unsigned NumInstanceMethods = NumInstanceMethodsAndBits >> 2;
+ unsigned NumFactoryMethods = NumFactoryMethodsAndBits >> 2;
// Load instance methods
for (unsigned I = 0; I != NumInstanceMethods; ++I) {
@@ -1088,6 +1103,19 @@ bool ASTReader::ReadBlockAbbrevs(BitstreamCursor &Cursor, unsigned BlockID) {
}
}
+Token ASTReader::ReadToken(ModuleFile &F, const RecordData &Record,
+ unsigned &Idx) {
+ Token Tok;
+ Tok.startToken();
+ Tok.setLocation(ReadSourceLocation(F, Record, Idx));
+ Tok.setLength(Record[Idx++]);
+ if (IdentifierInfo *II = getLocalIdentifier(F, Record[Idx++]))
+ Tok.setIdentifierInfo(II);
+ Tok.setKind((tok::TokenKind)Record[Idx++]);
+ Tok.setFlag((Token::TokenFlags)Record[Idx++]);
+ return Tok;
+}
+
MacroInfo *ASTReader::ReadMacroRecord(ModuleFile &F, uint64_t Offset) {
BitstreamCursor &Stream = F.MacroCursor;
@@ -1188,14 +1216,8 @@ MacroInfo *ASTReader::ReadMacroRecord(ModuleFile &F, uint64_t Offset) {
// erroneous, just pretend we didn't see this.
if (Macro == 0) break;
- Token Tok;
- Tok.startToken();
- Tok.setLocation(ReadSourceLocation(F, Record[0]));
- Tok.setLength(Record[1]);
- if (IdentifierInfo *II = getLocalIdentifier(F, Record[2]))
- Tok.setIdentifierInfo(II);
- Tok.setKind((tok::TokenKind)Record[3]);
- Tok.setFlag((Token::TokenFlags)Record[4]);
+ unsigned Idx = 0;
+ Token Tok = ReadToken(F, Record, Idx);
Macro->AddTokenToBody(Tok);
break;
}
@@ -1563,9 +1585,9 @@ void ASTReader::installPCHMacroDirectives(IdentifierInfo *II,
}
/// \brief For the given macro definitions, check if they are both in system
-/// modules and if one of the two is in the clang builtin headers.
-static bool isSystemAndClangMacro(MacroInfo *PrevMI, MacroInfo *NewMI,
- Module *NewOwner, ASTReader &Reader) {
+/// modules.
+static bool areDefinedInSystemModules(MacroInfo *PrevMI, MacroInfo *NewMI,
+ Module *NewOwner, ASTReader &Reader) {
assert(PrevMI && NewMI);
if (!NewOwner)
return false;
@@ -1576,22 +1598,7 @@ static bool isSystemAndClangMacro(MacroInfo *PrevMI, MacroInfo *NewMI,
return false;
if (PrevOwner == NewOwner)
return false;
- if (!PrevOwner->IsSystem || !NewOwner->IsSystem)
- return false;
-
- SourceManager &SM = Reader.getSourceManager();
- FileID PrevFID = SM.getFileID(PrevMI->getDefinitionLoc());
- FileID NewFID = SM.getFileID(NewMI->getDefinitionLoc());
- const FileEntry *PrevFE = SM.getFileEntryForID(PrevFID);
- const FileEntry *NewFE = SM.getFileEntryForID(NewFID);
- if (PrevFE == 0 || NewFE == 0)
- return false;
-
- Preprocessor &PP = Reader.getPreprocessor();
- ModuleMap &ModMap = PP.getHeaderSearchInfo().getModuleMap();
- const DirectoryEntry *BuiltinDir = ModMap.getBuiltinIncludeDir();
-
- return (PrevFE->getDir() == BuiltinDir) != (NewFE->getDir() == BuiltinDir);
+ return PrevOwner->IsSystem && NewOwner->IsSystem;
}
void ASTReader::installImportedMacro(IdentifierInfo *II, MacroDirective *MD,
@@ -1607,15 +1614,12 @@ void ASTReader::installImportedMacro(IdentifierInfo *II, MacroDirective *MD,
if (NewMI != PrevMI && !PrevMI->isIdenticalTo(*NewMI, PP,
/*Syntactically=*/true)) {
// Before marking the macros as ambiguous, check if this is a case where
- // the system macro uses a not identical definition compared to a macro
- // from the clang headers. For example:
+ // both macros are in system headers. If so, we trust that the system
+ // did not get it wrong. This also handles cases where Clang's own
+ // headers have a different spelling of certain system macros:
// #define LONG_MAX __LONG_MAX__ (clang's limits.h)
// #define LONG_MAX 0x7fffffffffffffffL (system's limits.h)
- // in which case don't mark them to avoid the "ambiguous macro expansion"
- // warning.
- // FIXME: This should go away if the system headers get "fixed" to use
- // identical definitions.
- if (!isSystemAndClangMacro(PrevMI, NewMI, Owner, *this)) {
+ if (!areDefinedInSystemModules(PrevMI, NewMI, Owner, *this)) {
PrevDef.getDirective()->setAmbiguous(true);
DefMD->setAmbiguous(true);
}
@@ -2754,7 +2758,7 @@ static void moveMethodToBackOfGlobalList(Sema &S, ObjCMethodDecl *Method) {
ObjCMethodList &Start = Method->isInstanceMethod()? Known->second.first
: Known->second.second;
bool Found = false;
- for (ObjCMethodList *List = &Start; List; List = List->Next) {
+ for (ObjCMethodList *List = &Start; List; List = List->getNext()) {
if (!Found) {
if (List->Method == Method) {
Found = true;
@@ -2764,8 +2768,8 @@ static void moveMethodToBackOfGlobalList(Sema &S, ObjCMethodDecl *Method) {
}
}
- if (List->Next)
- List->Method = List->Next->Method;
+ if (List->getNext())
+ List->Method = List->getNext()->Method;
else
List->Method = Method;
}
@@ -3324,10 +3328,10 @@ void ASTReader::finalizeForWriting() {
HiddenNamesMap.clear();
}
-/// SkipCursorToControlBlock - Given a cursor at the start of an AST file, scan
-/// ahead and drop the cursor into the start of the CONTROL_BLOCK, returning
-/// false on success and true on failure.
-static bool SkipCursorToControlBlock(BitstreamCursor &Cursor) {
+/// \brief Given a cursor at the start of an AST file, scan ahead and drop the
+/// cursor into the start of the given block ID, returning false on success and
+/// true on failure.
+static bool SkipCursorToBlock(BitstreamCursor &Cursor, unsigned BlockID) {
while (1) {
llvm::BitstreamEntry Entry = Cursor.advance();
switch (Entry.Kind) {
@@ -3341,8 +3345,8 @@ static bool SkipCursorToControlBlock(BitstreamCursor &Cursor) {
break;
case llvm::BitstreamEntry::SubBlock:
- if (Entry.ID == CONTROL_BLOCK_ID) {
- if (Cursor.EnterSubBlock(CONTROL_BLOCK_ID))
+ if (Entry.ID == BlockID) {
+ if (Cursor.EnterSubBlock(BlockID))
return true;
// Found it!
return false;
@@ -3386,7 +3390,7 @@ std::string ASTReader::getOriginalSourceFile(const std::string &ASTFileName,
}
// Scan for the CONTROL_BLOCK_ID block.
- if (SkipCursorToControlBlock(Stream)) {
+ if (SkipCursorToBlock(Stream, CONTROL_BLOCK_ID)) {
Diags.Report(diag::err_fe_pch_malformed_block) << ASTFileName;
return std::string();
}
@@ -3441,7 +3445,7 @@ namespace {
bool Complain,
std::string &SuggestedPredefines) {
return checkPreprocessorOptions(ExistingPPOpts, PPOpts, 0, FileMgr,
- SuggestedPredefines);
+ SuggestedPredefines, ExistingLangOpts);
}
};
}
@@ -3473,8 +3477,29 @@ bool ASTReader::readASTFileControlBlock(StringRef Filename,
}
// Scan for the CONTROL_BLOCK_ID block.
- if (SkipCursorToControlBlock(Stream))
+ if (SkipCursorToBlock(Stream, CONTROL_BLOCK_ID))
return true;
+
+ bool NeedsInputFiles = Listener.needsInputFileVisitation();
+ BitstreamCursor InputFilesCursor;
+ if (NeedsInputFiles) {
+ InputFilesCursor = Stream;
+ if (SkipCursorToBlock(InputFilesCursor, INPUT_FILES_BLOCK_ID))
+ return true;
+
+ // Read the abbreviations
+ while (true) {
+ uint64_t Offset = InputFilesCursor.GetCurrentBitNo();
+ unsigned Code = InputFilesCursor.ReadCode();
+
+ // We expect all abbrevs to be at the start of the block.
+ if (Code != llvm::bitc::DEFINE_ABBREV) {
+ InputFilesCursor.JumpToBit(Offset);
+ break;
+ }
+ InputFilesCursor.ReadAbbrevRecord();
+ }
+ }
// Scan for ORIGINAL_FILE inside the control block.
RecordData Record;
@@ -3532,6 +3557,35 @@ bool ASTReader::readASTFileControlBlock(StringRef Filename,
break;
}
+ case INPUT_FILE_OFFSETS: {
+ if (!NeedsInputFiles)
+ break;
+
+ unsigned NumInputFiles = Record[0];
+ unsigned NumUserFiles = Record[1];
+ const uint32_t *InputFileOffs = (const uint32_t *)Blob.data();
+ for (unsigned I = 0; I != NumInputFiles; ++I) {
+ // Go find this input file.
+ bool isSystemFile = I >= NumUserFiles;
+ BitstreamCursor &Cursor = InputFilesCursor;
+ SavedStreamPosition SavedPosition(Cursor);
+ Cursor.JumpToBit(InputFileOffs[I]);
+
+ unsigned Code = Cursor.ReadCode();
+ RecordData Record;
+ StringRef Blob;
+ bool shouldContinue = false;
+ switch ((InputFileRecordTypes)Cursor.readRecord(Code, Record, &Blob)) {
+ case INPUT_FILE:
+ shouldContinue = Listener.visitInputFile(Blob, isSystemFile);
+ break;
+ }
+ if (!shouldContinue)
+ break;
+ }
+ break;
+ }
+
default:
// No other validation to perform.
break;
@@ -3907,6 +3961,7 @@ bool ASTReader::ParseLanguageOptions(const RecordData &Record,
LangOpts.CommentOpts.BlockCommandNames.push_back(
ReadString(Record, Idx));
}
+ LangOpts.CommentOpts.ParseAllComments = Record[Idx++];
return Listener.ReadLanguageOptions(LangOpts, Complain);
}
@@ -4017,6 +4072,7 @@ bool ASTReader::ParsePreprocessorOptions(const RecordData &Record,
}
PPOpts.UsePredefines = Record[Idx++];
+ PPOpts.DetailedRecord = Record[Idx++];
PPOpts.ImplicitPCHInclude = ReadString(Record, Idx);
PPOpts.ImplicitPTHInclude = ReadString(Record, Idx);
PPOpts.ObjCXXARCStandardLibrary =
@@ -4639,8 +4695,12 @@ QualType ASTReader::readTypeRecord(unsigned Index) {
return Context.getUnaryTransformType(BaseType, UnderlyingType, UKind);
}
- case TYPE_AUTO:
- return Context.getAutoType(readType(*Loc.F, Record, Idx));
+ case TYPE_AUTO: {
+ QualType Deduced = readType(*Loc.F, Record, Idx);
+ bool IsDecltypeAuto = Record[Idx++];
+ bool IsDependent = Deduced.isNull() ? Record[Idx++] : false;
+ return Context.getAutoType(Deduced, IsDecltypeAuto, IsDependent);
+ }
case TYPE_RECORD: {
if (Record.size() != 2) {
@@ -6015,8 +6075,8 @@ void ASTReader::InitializeSema(Sema &S) {
// Makes sure any declarations that were deserialized "too early"
// still get added to the identifier's declaration chains.
for (unsigned I = 0, N = PreloadedDecls.size(); I != N; ++I) {
- NamedDecl *ND = cast<NamedDecl>(PreloadedDecls[I]->getMostRecentDecl());
- SemaObj->pushExternalDeclIntoScope(ND, PreloadedDecls[I]->getDeclName());
+ pushExternalDeclIntoScope(PreloadedDecls[I],
+ PreloadedDecls[I]->getDeclName());
}
PreloadedDecls.clear();
@@ -6122,7 +6182,10 @@ StringRef ASTIdentifierIterator::Next() {
return Result;
}
-IdentifierIterator *ASTReader::getIdentifiers() const {
+IdentifierIterator *ASTReader::getIdentifiers() {
+ if (!loadGlobalIndex())
+ return GlobalIndex->createIdentifierIterator();
+
return new ASTIdentifierIterator(*this);
}
@@ -6131,13 +6194,16 @@ namespace clang { namespace serialization {
ASTReader &Reader;
Selector Sel;
unsigned PriorGeneration;
+ unsigned InstanceBits;
+ unsigned FactoryBits;
SmallVector<ObjCMethodDecl *, 4> InstanceMethods;
SmallVector<ObjCMethodDecl *, 4> FactoryMethods;
public:
ReadMethodPoolVisitor(ASTReader &Reader, Selector Sel,
unsigned PriorGeneration)
- : Reader(Reader), Sel(Sel), PriorGeneration(PriorGeneration) { }
+ : Reader(Reader), Sel(Sel), PriorGeneration(PriorGeneration),
+ InstanceBits(0), FactoryBits(0) { }
static bool visit(ModuleFile &M, void *UserData) {
ReadMethodPoolVisitor *This
@@ -6170,6 +6236,8 @@ namespace clang { namespace serialization {
This->InstanceMethods.append(Data.Instance.begin(), Data.Instance.end());
This->FactoryMethods.append(Data.Factory.begin(), Data.Factory.end());
+ This->InstanceBits = Data.InstanceBits;
+ This->FactoryBits = Data.FactoryBits;
return true;
}
@@ -6182,6 +6250,9 @@ namespace clang { namespace serialization {
ArrayRef<ObjCMethodDecl *> getFactoryMethods() const {
return FactoryMethods;
}
+
+ unsigned getInstanceBits() const { return InstanceBits; }
+ unsigned getFactoryBits() const { return FactoryBits; }
};
} } // end namespace clang::serialization
@@ -6219,6 +6290,8 @@ void ASTReader::ReadMethodPool(Selector Sel) {
addMethodsToPool(S, Visitor.getInstanceMethods(), Pos->second.first);
addMethodsToPool(S, Visitor.getFactoryMethods(), Pos->second.second);
+ Pos->second.first.setBits(Visitor.getInstanceBits());
+ Pos->second.second.setBits(Visitor.getFactoryBits());
}
void ASTReader::ReadKnownNamespaces(
@@ -6417,8 +6490,7 @@ ASTReader::SetGloballyVisibleDecls(IdentifierInfo *II,
// Introduce this declaration into the translation-unit scope
// and add it to the declaration chain for this identifier, so
// that (unqualified) name lookup will find it.
- NamedDecl *ND = cast<NamedDecl>(D->getMostRecentDecl());
- SemaObj->pushExternalDeclIntoScope(ND, II);
+ pushExternalDeclIntoScope(D, II);
} else {
// Queue this declaration so that it will be added to the
// translation unit scope and identifier's declaration chain
@@ -7165,9 +7237,9 @@ void ASTReader::ReadComments() {
(RawComment::CommentKind) Record[Idx++];
bool IsTrailingComment = Record[Idx++];
bool IsAlmostTrailingComment = Record[Idx++];
- Comments.push_back(new (Context) RawComment(SR, Kind,
- IsTrailingComment,
- IsAlmostTrailingComment));
+ Comments.push_back(new (Context) RawComment(
+ SR, Kind, IsTrailingComment, IsAlmostTrailingComment,
+ Context.getLangOpts().CommentOpts.ParseAllComments));
break;
}
}
@@ -7205,8 +7277,7 @@ void ASTReader::finishPendingActions() {
TLD != TLDEnd; ++TLD) {
IdentifierInfo *II = TLD->first;
for (unsigned I = 0, N = TLD->second.size(); I != N; ++I) {
- NamedDecl *ND = cast<NamedDecl>(TLD->second[I]->getMostRecentDecl());
- SemaObj->pushExternalDeclIntoScope(ND, II);
+ pushExternalDeclIntoScope(cast<NamedDecl>(TLD->second[I]), II);
}
}
@@ -7346,6 +7417,21 @@ void ASTReader::FinishedDeserializing() {
}
}
+void ASTReader::pushExternalDeclIntoScope(NamedDecl *D, DeclarationName Name) {
+ D = cast<NamedDecl>(D->getMostRecentDecl());
+
+ if (SemaObj->IdResolver.tryAddTopLevelDecl(D, Name) && SemaObj->TUScope) {
+ SemaObj->TUScope->AddDecl(D);
+ } else if (SemaObj->TUScope) {
+ // Adding the decl to IdResolver may have failed because it was already in
+ // (even though it was not added in scope). If it is already in, make sure
+ // it gets in the scope as well.
+ if (std::find(SemaObj->IdResolver.begin(Name),
+ SemaObj->IdResolver.end(), D) != SemaObj->IdResolver.end())
+ SemaObj->TUScope->AddDecl(D);
+ }
+}
+
ASTReader::ASTReader(Preprocessor &PP, ASTContext &Context,
StringRef isysroot, bool DisableValidation,
bool AllowASTWithCompilerErrors, bool UseGlobalIndex)
OpenPOWER on IntegriCloud