diff options
author | Douglas Gregor <dgregor@apple.com> | 2012-10-16 23:40:58 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2012-10-16 23:40:58 +0000 |
commit | 57016dda61498294120b1a881d9e6606337b29d9 (patch) | |
tree | 5dfc64766b1250929020a9c1bba6347e84c1046b /lib/Serialization/ASTReader.cpp | |
parent | 708f69bcc1be715efd1e9f46266a9c1ead184be6 (diff) |
Serialize TargetOptions into an AST file, and make sure that we keep
target options around so they can be accessed at any point (rather
than keeping them transient).
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@166072 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Serialization/ASTReader.cpp')
-rw-r--r-- | lib/Serialization/ASTReader.cpp | 85 |
1 files changed, 76 insertions, 9 deletions
diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp index a62f2578e9..67a54caf64 100644 --- a/lib/Serialization/ASTReader.cpp +++ b/lib/Serialization/ASTReader.cpp @@ -37,6 +37,7 @@ #include "clang/Basic/FileManager.h" #include "clang/Basic/FileSystemStatCache.h" #include "clang/Basic/TargetInfo.h" +#include "clang/Basic/TargetOptions.h" #include "clang/Basic/Version.h" #include "clang/Basic/VersionTuple.h" #include "llvm/ADT/StringExtras.h" @@ -101,13 +102,66 @@ PCHValidator::ReadLanguageOptions(const ModuleFile &M, return false; } -bool PCHValidator::ReadTargetTriple(const ModuleFile &M, StringRef Triple) { - if (Triple == PP.getTargetInfo().getTriple().str()) - return false; +bool PCHValidator::ReadTargetOptions(const ModuleFile &M, + const TargetOptions &TargetOpts) { + const TargetOptions &ExistingTargetOpts = PP.getTargetInfo().getTargetOpts(); + +#define CHECK_TARGET_OPT(Field, Name) \ + if (TargetOpts.Field != ExistingTargetOpts.Field) { \ + Reader.Diag(diag::err_pch_targetopt_mismatch) \ + << Name << TargetOpts.Field << ExistingTargetOpts.Field; \ + return true; \ + } + + CHECK_TARGET_OPT(Triple, "target"); + CHECK_TARGET_OPT(CPU, "target CPU"); + CHECK_TARGET_OPT(ABI, "target ABI"); + CHECK_TARGET_OPT(CXXABI, "target C++ ABI"); + CHECK_TARGET_OPT(LinkerVersion, "target linker version"); +#undef CHECK_TARGET_OPT + + // Compare feature sets. + SmallVector<StringRef, 4> ExistingFeatures( + ExistingTargetOpts.FeaturesAsWritten.begin(), + ExistingTargetOpts.FeaturesAsWritten.end()); + SmallVector<StringRef, 4> ReadFeatures(TargetOpts.FeaturesAsWritten.begin(), + TargetOpts.FeaturesAsWritten.end()); + std::sort(ExistingFeatures.begin(), ExistingFeatures.end()); + std::sort(ReadFeatures.begin(), ReadFeatures.end()); + + unsigned ExistingIdx = 0, ExistingN = ExistingFeatures.size(); + unsigned ReadIdx = 0, ReadN = ReadFeatures.size(); + while (ExistingIdx < ExistingN && ReadIdx < ReadN) { + if (ExistingFeatures[ExistingIdx] == ReadFeatures[ReadIdx]) { + ++ExistingIdx; + ++ReadIdx; + continue; + } + + if (ReadFeatures[ReadIdx] < ExistingFeatures[ExistingIdx]) { + Reader.Diag(diag::err_pch_targetopt_feature_mismatch) + << false << ReadFeatures[ReadIdx]; + return true; + } - Reader.Diag(diag::warn_pch_target_triple) - << Triple << PP.getTargetInfo().getTriple().str(); - return true; + Reader.Diag(diag::err_pch_targetopt_feature_mismatch) + << true << ExistingFeatures[ExistingIdx]; + return true; + } + + if (ExistingIdx < ExistingN) { + Reader.Diag(diag::err_pch_targetopt_feature_mismatch) + << true << ExistingFeatures[ExistingIdx]; + return true; + } + + if (ReadIdx < ReadN) { + Reader.Diag(diag::err_pch_targetopt_feature_mismatch) + << false << ReadFeatures[ReadIdx]; + return true; + } + + return false; } namespace { @@ -1834,7 +1888,7 @@ ASTReader::ReadASTBlock(ModuleFile &F) { case METADATA: { if (Record[0] != VERSION_MAJOR && !DisableValidation) { Diag(Record[0] < VERSION_MAJOR? diag::warn_pch_version_too_old - : diag::warn_pch_version_too_new); + : diag::warn_pch_version_too_new); return IgnorePCH; } @@ -1846,8 +1900,21 @@ ASTReader::ReadASTBlock(ModuleFile &F) { RelocatablePCH = Record[4]; if (Listener) { - std::string TargetTriple(BlobStart, BlobLen); - if (Listener->ReadTargetTriple(F, TargetTriple)) + unsigned Idx = 6; + TargetOptions TargetOpts; + TargetOpts.Triple = ReadString(Record, Idx); + TargetOpts.CPU = ReadString(Record, Idx); + TargetOpts.ABI = ReadString(Record, Idx); + TargetOpts.CXXABI = ReadString(Record, Idx); + TargetOpts.LinkerVersion = ReadString(Record, Idx); + for (unsigned N = Record[Idx++]; N; --N) { + TargetOpts.FeaturesAsWritten.push_back(ReadString(Record, Idx)); + } + for (unsigned N = Record[Idx++]; N; --N) { + TargetOpts.Features.push_back(ReadString(Record, Idx)); + } + + if (Listener->ReadTargetOptions(F, TargetOpts)) return IgnorePCH; } break; |