Update Clang for rebase to r212749.
This also fixes a small issue with arm_neon.h not being generated always.
Includes a cherry-pick of:
r213450 - fixes mac-specific header issue
r213126 - removes a default -Bsymbolic on Android
Change-Id: I2a790a0f5d3b2aab11de596fc3a74e7cbc99081d
diff --git a/lib/Basic/Builtins.cpp b/lib/Basic/Builtins.cpp
index 6c78dc3..8efcac6 100644
--- a/lib/Basic/Builtins.cpp
+++ b/lib/Basic/Builtins.cpp
@@ -76,7 +76,7 @@
// Step #2: Register target-specific builtins.
for (unsigned i = 0, e = NumTSRecords; i != e; ++i)
- if (!LangOpts.NoBuiltin || !strchr(TSRecords[i].Attributes, 'f'))
+ if (BuiltinIsSupported(TSRecords[i], LangOpts))
Table.get(TSRecords[i].Name).setBuiltinID(i+Builtin::FirstTSBuiltin);
}
diff --git a/lib/Basic/Diagnostic.cpp b/lib/Basic/Diagnostic.cpp
index 13d2524..f784fe7 100644
--- a/lib/Basic/Diagnostic.cpp
+++ b/lib/Basic/Diagnostic.cpp
@@ -24,15 +24,13 @@
using namespace clang;
static void DummyArgToStringFn(DiagnosticsEngine::ArgumentKind AK, intptr_t QT,
- const char *Modifier, unsigned ML,
- const char *Argument, unsigned ArgLen,
- const DiagnosticsEngine::ArgumentValue *PrevArgs,
- unsigned NumPrevArgs,
- SmallVectorImpl<char> &Output,
- void *Cookie,
- ArrayRef<intptr_t> QualTypeVals) {
- const char *Str = "<can't format argument>";
- Output.append(Str, Str+strlen(Str));
+ StringRef Modifier, StringRef Argument,
+ ArrayRef<DiagnosticsEngine::ArgumentValue> PrevArgs,
+ SmallVectorImpl<char> &Output,
+ void *Cookie,
+ ArrayRef<intptr_t> QualTypeVals) {
+ StringRef Str = "<can't format argument>";
+ Output.append(Str.begin(), Str.end());
}
@@ -56,7 +54,7 @@
PrintTemplateTree = false;
ShowColors = false;
ShowOverloads = Ovl_All;
- ExtBehavior = Ext_Ignore;
+ ExtBehavior = diag::Severity::Ignored;
ErrorLimit = 0;
TemplateBacktraceLimit = 0;
@@ -162,12 +160,12 @@
return Pos;
}
-void DiagnosticsEngine::setDiagnosticMapping(diag::kind Diag, diag::Mapping Map,
- SourceLocation L) {
+void DiagnosticsEngine::setSeverity(diag::kind Diag, diag::Severity Map,
+ SourceLocation L) {
assert(Diag < diag::DIAG_UPPER_LIMIT &&
"Can only map builtin diagnostics");
assert((Diags->isBuiltinWarningOrExtension(Diag) ||
- (Map == diag::MAP_FATAL || Map == diag::MAP_ERROR)) &&
+ (Map == diag::Severity::Fatal || Map == diag::Severity::Error)) &&
"Cannot map errors into warnings!");
assert(!DiagStatePoints.empty());
assert((L.isInvalid() || SourceMgr) && "No SourceMgr for valid location");
@@ -175,17 +173,17 @@
FullSourceLoc Loc = SourceMgr? FullSourceLoc(L, *SourceMgr) : FullSourceLoc();
FullSourceLoc LastStateChangePos = DiagStatePoints.back().Loc;
// Don't allow a mapping to a warning override an error/fatal mapping.
- if (Map == diag::MAP_WARNING) {
- DiagnosticMappingInfo &Info = GetCurDiagState()->getOrAddMappingInfo(Diag);
- if (Info.getMapping() == diag::MAP_ERROR ||
- Info.getMapping() == diag::MAP_FATAL)
- Map = Info.getMapping();
+ if (Map == diag::Severity::Warning) {
+ DiagnosticMapping &Info = GetCurDiagState()->getOrAddMapping(Diag);
+ if (Info.getSeverity() == diag::Severity::Error ||
+ Info.getSeverity() == diag::Severity::Fatal)
+ Map = Info.getSeverity();
}
- DiagnosticMappingInfo MappingInfo = makeMappingInfo(Map, L);
+ DiagnosticMapping Mapping = makeUserMapping(Map, L);
// Common case; setting all the diagnostics of a group in one place.
if (Loc.isInvalid() || Loc == LastStateChangePos) {
- GetCurDiagState()->setMappingInfo(Diag, MappingInfo);
+ GetCurDiagState()->setMapping(Diag, Mapping);
return;
}
@@ -198,7 +196,7 @@
// the new state became active.
DiagStates.push_back(*GetCurDiagState());
PushDiagStatePoint(&DiagStates.back(), Loc);
- GetCurDiagState()->setMappingInfo(Diag, MappingInfo);
+ GetCurDiagState()->setMapping(Diag, Mapping);
return;
}
@@ -211,12 +209,12 @@
// Update all diagnostic states that are active after the given location.
for (DiagStatePointsTy::iterator
I = Pos+1, E = DiagStatePoints.end(); I != E; ++I) {
- GetCurDiagState()->setMappingInfo(Diag, MappingInfo);
+ GetCurDiagState()->setMapping(Diag, Mapping);
}
// If the location corresponds to an existing point, just update its state.
if (Pos->Loc == Loc) {
- GetCurDiagState()->setMappingInfo(Diag, MappingInfo);
+ GetCurDiagState()->setMapping(Diag, Mapping);
return;
}
@@ -225,14 +223,13 @@
assert(Pos->Loc.isBeforeInTranslationUnitThan(Loc));
DiagStates.push_back(*Pos->State);
DiagState *NewState = &DiagStates.back();
- GetCurDiagState()->setMappingInfo(Diag, MappingInfo);
+ GetCurDiagState()->setMapping(Diag, Mapping);
DiagStatePoints.insert(Pos+1, DiagStatePoint(NewState,
FullSourceLoc(Loc, *SourceMgr)));
}
-bool DiagnosticsEngine::setDiagnosticGroupMapping(
- StringRef Group, diag::Mapping Map, SourceLocation Loc)
-{
+bool DiagnosticsEngine::setSeverityForGroup(StringRef Group, diag::Severity Map,
+ SourceLocation Loc) {
// Get the diagnostics in this group.
SmallVector<diag::kind, 8> GroupDiags;
if (Diags->getDiagnosticsInGroup(Group, GroupDiags))
@@ -240,7 +237,7 @@
// Set the mapping.
for (unsigned i = 0, e = GroupDiags.size(); i != e; ++i)
- setDiagnosticMapping(GroupDiags[i], Map, Loc);
+ setSeverity(GroupDiags[i], Map, Loc);
return false;
}
@@ -250,7 +247,7 @@
// If we are enabling this feature, just set the diagnostic mappings to map to
// errors.
if (Enabled)
- return setDiagnosticGroupMapping(Group, diag::MAP_ERROR);
+ return setSeverityForGroup(Group, diag::Severity::Error);
// Otherwise, we want to set the diagnostic mapping's "no Werror" bit, and
// potentially downgrade anything already mapped to be a warning.
@@ -262,12 +259,11 @@
// Perform the mapping change.
for (unsigned i = 0, e = GroupDiags.size(); i != e; ++i) {
- DiagnosticMappingInfo &Info = GetCurDiagState()->getOrAddMappingInfo(
- GroupDiags[i]);
+ DiagnosticMapping &Info = GetCurDiagState()->getOrAddMapping(GroupDiags[i]);
- if (Info.getMapping() == diag::MAP_ERROR ||
- Info.getMapping() == diag::MAP_FATAL)
- Info.setMapping(diag::MAP_WARNING);
+ if (Info.getSeverity() == diag::Severity::Error ||
+ Info.getSeverity() == diag::Severity::Fatal)
+ Info.setSeverity(diag::Severity::Warning);
Info.setNoWarningAsError(true);
}
@@ -280,7 +276,7 @@
// If we are enabling this feature, just set the diagnostic mappings to map to
// fatal errors.
if (Enabled)
- return setDiagnosticGroupMapping(Group, diag::MAP_FATAL);
+ return setSeverityForGroup(Group, diag::Severity::Fatal);
// Otherwise, we want to set the diagnostic mapping's "no Werror" bit, and
// potentially downgrade anything already mapped to be an error.
@@ -292,11 +288,10 @@
// Perform the mapping change.
for (unsigned i = 0, e = GroupDiags.size(); i != e; ++i) {
- DiagnosticMappingInfo &Info = GetCurDiagState()->getOrAddMappingInfo(
- GroupDiags[i]);
+ DiagnosticMapping &Info = GetCurDiagState()->getOrAddMapping(GroupDiags[i]);
- if (Info.getMapping() == diag::MAP_FATAL)
- Info.setMapping(diag::MAP_ERROR);
+ if (Info.getSeverity() == diag::Severity::Fatal)
+ Info.setSeverity(diag::Severity::Error);
Info.setNoErrorAsFatal(true);
}
@@ -304,8 +299,8 @@
return false;
}
-void DiagnosticsEngine::setMappingToAllDiagnostics(diag::Mapping Map,
- SourceLocation Loc) {
+void DiagnosticsEngine::setSeverityForAll(diag::Severity Map,
+ SourceLocation Loc) {
// Get all the diagnostics.
SmallVector<diag::kind, 64> AllDiags;
Diags->getAllDiagnostics(AllDiags);
@@ -313,7 +308,7 @@
// Set the mapping.
for (unsigned i = 0, e = AllDiags.size(); i != e; ++i)
if (Diags->isBuiltinWarningOrExtension(AllDiags[i]))
- setDiagnosticMapping(AllDiags[i], Map, Loc);
+ setSeverity(AllDiags[i], Map, Loc);
}
void DiagnosticsEngine::Report(const StoredDiagnostic &storedDiag) {
@@ -829,9 +824,9 @@
case DiagnosticsEngine::ak_declcontext:
case DiagnosticsEngine::ak_attr:
getDiags()->ConvertArgToString(Kind, getRawArg(ArgNo),
- Modifier, ModifierLen,
- Argument, ArgumentLen,
- FormattedArgs.data(), FormattedArgs.size(),
+ StringRef(Modifier, ModifierLen),
+ StringRef(Argument, ArgumentLen),
+ FormattedArgs,
OutStr, QualTypeVals);
break;
case DiagnosticsEngine::ak_qualtype_pair:
@@ -853,10 +848,9 @@
TDT.PrintFromType = true;
TDT.PrintTree = true;
getDiags()->ConvertArgToString(Kind, val,
- Modifier, ModifierLen,
- Argument, ArgumentLen,
- FormattedArgs.data(),
- FormattedArgs.size(),
+ StringRef(Modifier, ModifierLen),
+ StringRef(Argument, ArgumentLen),
+ FormattedArgs,
Tree, QualTypeVals);
// If there is no tree information, fall back to regular printing.
if (!Tree.empty()) {
@@ -877,9 +871,9 @@
TDT.PrintTree = false;
TDT.PrintFromType = true;
getDiags()->ConvertArgToString(Kind, val,
- Modifier, ModifierLen,
- Argument, ArgumentLen,
- FormattedArgs.data(), FormattedArgs.size(),
+ StringRef(Modifier, ModifierLen),
+ StringRef(Argument, ArgumentLen),
+ FormattedArgs,
OutStr, QualTypeVals);
if (!TDT.TemplateDiffUsed)
FormattedArgs.push_back(std::make_pair(DiagnosticsEngine::ak_qualtype,
@@ -891,9 +885,9 @@
// Append second type
TDT.PrintFromType = false;
getDiags()->ConvertArgToString(Kind, val,
- Modifier, ModifierLen,
- Argument, ArgumentLen,
- FormattedArgs.data(), FormattedArgs.size(),
+ StringRef(Modifier, ModifierLen),
+ StringRef(Argument, ArgumentLen),
+ FormattedArgs,
OutStr, QualTypeVals);
if (!TDT.TemplateDiffUsed)
FormattedArgs.push_back(std::make_pair(DiagnosticsEngine::ak_qualtype,
diff --git a/lib/Basic/DiagnosticIDs.cpp b/lib/Basic/DiagnosticIDs.cpp
index 4779859..0bb0b9f 100644
--- a/lib/Basic/DiagnosticIDs.cpp
+++ b/lib/Basic/DiagnosticIDs.cpp
@@ -38,7 +38,7 @@
struct StaticDiagInfoRec {
uint16_t DiagID;
- unsigned Mapping : 3;
+ unsigned DefaultSeverity : 3;
unsigned Class : 3;
unsigned SFINAE : 2;
unsigned WarnNoWerror : 1;
@@ -66,12 +66,13 @@
} // namespace anonymous
static const StaticDiagInfoRec StaticDiagInfo[] = {
-#define DIAG(ENUM,CLASS,DEFAULT_MAPPING,DESC,GROUP, \
- SFINAE,NOWERROR,SHOWINSYSHEADER,CATEGORY) \
- { diag::ENUM, DEFAULT_MAPPING, CLASS, \
- DiagnosticIDs::SFINAE, \
- NOWERROR, SHOWINSYSHEADER, CATEGORY, GROUP, \
- STR_SIZE(DESC, uint16_t), DESC },
+#define DIAG(ENUM, CLASS, DEFAULT_SEVERITY, DESC, GROUP, SFINAE, NOWERROR, \
+ SHOWINSYSHEADER, CATEGORY) \
+ { \
+ diag::ENUM, DEFAULT_SEVERITY, CLASS, DiagnosticIDs::SFINAE, NOWERROR, \
+ SHOWINSYSHEADER, CATEGORY, GROUP, STR_SIZE(DESC, uint16_t), DESC \
+ } \
+ ,
#include "clang/Basic/DiagnosticCommonKinds.inc"
#include "clang/Basic/DiagnosticDriverKinds.inc"
#include "clang/Basic/DiagnosticFrontendKinds.inc"
@@ -152,24 +153,18 @@
return Found;
}
-static DiagnosticMappingInfo GetDefaultDiagMappingInfo(unsigned DiagID) {
- DiagnosticMappingInfo Info = DiagnosticMappingInfo::Make(
- diag::MAP_FATAL, /*IsUser=*/false, /*IsPragma=*/false);
+static DiagnosticMapping GetDefaultDiagMapping(unsigned DiagID) {
+ DiagnosticMapping Info = DiagnosticMapping::Make(
+ diag::Severity::Fatal, /*IsUser=*/false, /*IsPragma=*/false);
if (const StaticDiagInfoRec *StaticInfo = GetDiagInfo(DiagID)) {
- Info.setMapping((diag::Mapping) StaticInfo->Mapping);
+ Info.setSeverity((diag::Severity)StaticInfo->DefaultSeverity);
if (StaticInfo->WarnNoWerror) {
- assert(Info.getMapping() == diag::MAP_WARNING &&
+ assert(Info.getSeverity() == diag::Severity::Warning &&
"Unexpected mapping with no-Werror bit!");
Info.setNoWarningAsError(true);
}
-
- if (StaticInfo->WarnShowInSystemHeader) {
- assert(Info.getMapping() == diag::MAP_WARNING &&
- "Unexpected mapping with show-in-system-header bit!");
- Info.setShowInSystemHeader(true);
- }
}
return Info;
@@ -198,15 +193,14 @@
// Unfortunately, the split between DiagnosticIDs and Diagnostic is not
// particularly clean, but for now we just implement this method here so we can
// access GetDefaultDiagMapping.
-DiagnosticMappingInfo &DiagnosticsEngine::DiagState::getOrAddMappingInfo(
- diag::kind Diag)
-{
- std::pair<iterator, bool> Result = DiagMap.insert(
- std::make_pair(Diag, DiagnosticMappingInfo()));
+DiagnosticMapping &
+DiagnosticsEngine::DiagState::getOrAddMapping(diag::kind Diag) {
+ std::pair<iterator, bool> Result =
+ DiagMap.insert(std::make_pair(Diag, DiagnosticMapping()));
// Initialize the entry if we added it.
if (Result.second)
- Result.first->second = GetDefaultDiagMappingInfo(Diag);
+ Result.first->second = GetDefaultDiagMapping(Diag);
return Result.first->second;
}
@@ -346,9 +340,9 @@
if (DiagID >= diag::DIAG_UPPER_LIMIT ||
getBuiltinDiagClass(DiagID) != CLASS_EXTENSION)
return false;
-
+
EnabledByDefault =
- GetDefaultDiagMappingInfo(DiagID).getMapping() != diag::MAP_IGNORE;
+ GetDefaultDiagMapping(DiagID).getSeverity() != diag::Severity::Ignored;
return true;
}
@@ -356,12 +350,7 @@
if (DiagID >= diag::DIAG_UPPER_LIMIT)
return false;
- return GetDefaultDiagMappingInfo(DiagID).getMapping() == diag::MAP_ERROR;
-}
-
-bool DiagnosticIDs::isRemark(unsigned DiagID) {
- return DiagID < diag::DIAG_UPPER_LIMIT &&
- getBuiltinDiagClass(DiagID) == CLASS_REMARK;
+ return GetDefaultDiagMapping(DiagID).getSeverity() == diag::Severity::Error;
}
/// getDescription - Given a diagnostic ID, return a description of the
@@ -372,6 +361,22 @@
return CustomDiagInfo->getDescription(DiagID);
}
+static DiagnosticIDs::Level toLevel(diag::Severity SV) {
+ switch (SV) {
+ case diag::Severity::Ignored:
+ return DiagnosticIDs::Ignored;
+ case diag::Severity::Remark:
+ return DiagnosticIDs::Remark;
+ case diag::Severity::Warning:
+ return DiagnosticIDs::Warning;
+ case diag::Severity::Error:
+ return DiagnosticIDs::Error;
+ case diag::Severity::Fatal:
+ return DiagnosticIDs::Fatal;
+ }
+ llvm_unreachable("unexpected severity");
+}
+
/// getDiagnosticLevel - Based on the way the client configured the
/// DiagnosticsEngine object, classify the specified diagnostic ID into a Level,
/// by consumable the DiagnosticClient.
@@ -384,7 +389,7 @@
unsigned DiagClass = getBuiltinDiagClass(DiagID);
if (DiagClass == CLASS_NOTE) return DiagnosticIDs::Note;
- return getDiagnosticLevel(DiagID, DiagClass, Loc, Diag);
+ return toLevel(getDiagnosticSeverity(DiagID, Loc, Diag));
}
/// \brief Based on the way the client configured the Diagnostic
@@ -393,49 +398,37 @@
///
/// \param Loc The source location we are interested in finding out the
/// diagnostic state. Can be null in order to query the latest state.
-DiagnosticIDs::Level
-DiagnosticIDs::getDiagnosticLevel(unsigned DiagID, unsigned DiagClass,
- SourceLocation Loc,
- const DiagnosticsEngine &Diag) const {
+diag::Severity
+DiagnosticIDs::getDiagnosticSeverity(unsigned DiagID, SourceLocation Loc,
+ const DiagnosticsEngine &Diag) const {
+ assert(getBuiltinDiagClass(DiagID) != CLASS_NOTE);
+
// Specific non-error diagnostics may be mapped to various levels from ignored
// to error. Errors can only be mapped to fatal.
- DiagnosticIDs::Level Result = DiagnosticIDs::Fatal;
+ diag::Severity Result = diag::Severity::Fatal;
DiagnosticsEngine::DiagStatePointsTy::iterator
Pos = Diag.GetDiagStatePointForLoc(Loc);
DiagnosticsEngine::DiagState *State = Pos->State;
// Get the mapping information, or compute it lazily.
- DiagnosticMappingInfo &MappingInfo = State->getOrAddMappingInfo(
- (diag::kind)DiagID);
+ DiagnosticMapping &Mapping = State->getOrAddMapping((diag::kind)DiagID);
- switch (MappingInfo.getMapping()) {
- case diag::MAP_IGNORE:
- Result = DiagnosticIDs::Ignored;
- break;
- case diag::MAP_REMARK:
- Result = DiagnosticIDs::Remark;
- break;
- case diag::MAP_WARNING:
- Result = DiagnosticIDs::Warning;
- break;
- case diag::MAP_ERROR:
- Result = DiagnosticIDs::Error;
- break;
- case diag::MAP_FATAL:
- Result = DiagnosticIDs::Fatal;
- break;
- }
+ // TODO: Can a null severity really get here?
+ if (Mapping.getSeverity() != diag::Severity())
+ Result = Mapping.getSeverity();
// Upgrade ignored diagnostics if -Weverything is enabled.
- if (Diag.EnableAllWarnings && Result == DiagnosticIDs::Ignored &&
- !MappingInfo.isUser())
- Result = DiagnosticIDs::Warning;
+ if (Diag.EnableAllWarnings && Result == diag::Severity::Ignored &&
+ !Mapping.isUser())
+ Result = diag::Severity::Warning;
// Diagnostics of class REMARK are either printed as remarks or in case they
// have been added to -Werror they are printed as errors.
- if (DiagClass == CLASS_REMARK && Result == DiagnosticIDs::Warning)
- Result = DiagnosticIDs::Remark;
+ // FIXME: Disregarding user-requested remark mappings like this is bogus.
+ if (Result == diag::Severity::Warning &&
+ getBuiltinDiagClass(DiagID) == CLASS_REMARK)
+ Result = diag::Severity::Remark;
// Ignore -pedantic diagnostics inside __extension__ blocks.
// (The diagnostics controlled by -pedantic are the extension diagnostics
@@ -443,62 +436,46 @@
bool EnabledByDefault = false;
bool IsExtensionDiag = isBuiltinExtensionDiag(DiagID, EnabledByDefault);
if (Diag.AllExtensionsSilenced && IsExtensionDiag && !EnabledByDefault)
- return DiagnosticIDs::Ignored;
+ return diag::Severity::Ignored;
// For extension diagnostics that haven't been explicitly mapped, check if we
// should upgrade the diagnostic.
- if (IsExtensionDiag && !MappingInfo.isUser()) {
- switch (Diag.ExtBehavior) {
- case DiagnosticsEngine::Ext_Ignore:
- break;
- case DiagnosticsEngine::Ext_Warn:
- // Upgrade ignored diagnostics to warnings.
- if (Result == DiagnosticIDs::Ignored)
- Result = DiagnosticIDs::Warning;
- break;
- case DiagnosticsEngine::Ext_Error:
- // Upgrade ignored or warning diagnostics to errors.
- if (Result == DiagnosticIDs::Ignored || Result == DiagnosticIDs::Warning)
- Result = DiagnosticIDs::Error;
- break;
- }
- }
+ if (IsExtensionDiag && !Mapping.isUser())
+ Result = std::max(Result, Diag.ExtBehavior);
// At this point, ignored errors can no longer be upgraded.
- if (Result == DiagnosticIDs::Ignored)
+ if (Result == diag::Severity::Ignored)
return Result;
// Honor -w, which is lower in priority than pedantic-errors, but higher than
// -Werror.
- if (Result == DiagnosticIDs::Warning && Diag.IgnoreAllWarnings)
- return DiagnosticIDs::Ignored;
+ if (Result == diag::Severity::Warning && Diag.IgnoreAllWarnings)
+ return diag::Severity::Ignored;
// If -Werror is enabled, map warnings to errors unless explicitly disabled.
- if (Result == DiagnosticIDs::Warning) {
- if (Diag.WarningsAsErrors && !MappingInfo.hasNoWarningAsError())
- Result = DiagnosticIDs::Error;
+ if (Result == diag::Severity::Warning) {
+ if (Diag.WarningsAsErrors && !Mapping.hasNoWarningAsError())
+ Result = diag::Severity::Error;
}
// If -Wfatal-errors is enabled, map errors to fatal unless explicity
// disabled.
- if (Result == DiagnosticIDs::Error) {
- if (Diag.ErrorsAsFatal && !MappingInfo.hasNoErrorAsFatal())
- Result = DiagnosticIDs::Fatal;
+ if (Result == diag::Severity::Error) {
+ if (Diag.ErrorsAsFatal && !Mapping.hasNoErrorAsFatal())
+ Result = diag::Severity::Fatal;
}
+ // Custom diagnostics always are emitted in system headers.
+ bool ShowInSystemHeader =
+ !GetDiagInfo(DiagID) || GetDiagInfo(DiagID)->WarnShowInSystemHeader;
+
// If we are in a system header, we ignore it. We look at the diagnostic class
// because we also want to ignore extensions and warnings in -Werror and
// -pedantic-errors modes, which *map* warnings/extensions to errors.
- if (Result >= DiagnosticIDs::Warning &&
- DiagClass != CLASS_ERROR &&
- // Custom diagnostics always are emitted in system headers.
- DiagID < diag::DIAG_UPPER_LIMIT &&
- !MappingInfo.hasShowInSystemHeader() &&
- Diag.SuppressSystemWarnings &&
- Loc.isValid() &&
+ if (Diag.SuppressSystemWarnings && !ShowInSystemHeader && Loc.isValid() &&
Diag.getSourceManager().isInSystemHeader(
Diag.getSourceManager().getExpansionLoc(Loc)))
- return DiagnosticIDs::Ignored;
+ return diag::Severity::Ignored;
return Result;
}
diff --git a/lib/Basic/FileManager.cpp b/lib/Basic/FileManager.cpp
index 14731f6..22beed7 100644
--- a/lib/Basic/FileManager.cpp
+++ b/lib/Basic/FileManager.cpp
@@ -25,16 +25,13 @@
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/Support/system_error.h"
#include <map>
#include <set>
#include <string>
+#include <system_error>
using namespace clang;
-// FIXME: Enhance libsystem to support inode and other fields.
-#include <sys/stat.h>
-
/// NON_EXISTENT_DIR - A special value distinct from null that is used to
/// represent a dir name that doesn't exist on the disk.
#define NON_EXISTENT_DIR reinterpret_cast<DirectoryEntry*>((intptr_t)-1)
@@ -256,7 +253,7 @@
// FIXME: This will reduce the # syscalls.
// Nope, there isn't. Check to see if the file exists.
- vfs::File *F = nullptr;
+ std::unique_ptr<vfs::File> F;
FileData Data;
if (getStatValue(InterndFileName, Data, true, openFile ? &F : nullptr)) {
// There's no real file at the given path.
@@ -284,10 +281,6 @@
if (DirInfo != UFE.Dir && Data.IsVFSMapped)
UFE.Dir = DirInfo;
- // If the stat process opened the file, close it to avoid a FD leak.
- if (F)
- delete F;
-
return &UFE;
}
@@ -300,7 +293,7 @@
UFE.UniqueID = Data.UniqueID;
UFE.IsNamedPipe = Data.IsNamedPipe;
UFE.InPCH = Data.InPCH;
- UFE.File.reset(F);
+ UFE.File = std::move(F);
UFE.IsValid = true;
return &UFE;
}
@@ -388,9 +381,9 @@
llvm::MemoryBuffer *FileManager::
getBufferForFile(const FileEntry *Entry, std::string *ErrorStr,
- bool isVolatile) {
+ bool isVolatile, bool ShouldCloseOpenFile) {
std::unique_ptr<llvm::MemoryBuffer> Result;
- llvm::error_code ec;
+ std::error_code ec;
uint64_t FileSize = Entry->getSize();
// If there's a high enough chance that the file have changed since we
@@ -405,7 +398,10 @@
/*RequiresNullTerminator=*/true, isVolatile);
if (ErrorStr)
*ErrorStr = ec.message();
- Entry->closeFile();
+ // FIXME: we need a set of APIs that can make guarantees about whether a
+ // FileEntry is open or not.
+ if (ShouldCloseOpenFile)
+ Entry->closeFile();
return Result.release();
}
@@ -431,7 +427,7 @@
llvm::MemoryBuffer *FileManager::
getBufferForFile(StringRef Filename, std::string *ErrorStr) {
std::unique_ptr<llvm::MemoryBuffer> Result;
- llvm::error_code ec;
+ std::error_code ec;
if (FileSystemOpts.WorkingDir.empty()) {
ec = FS->getBufferForFile(Filename, Result);
if (ec && ErrorStr)
@@ -453,7 +449,7 @@
/// false if it's an existent real file. If FileDescriptor is NULL,
/// do directory look-up instead of file look-up.
bool FileManager::getStatValue(const char *Path, FileData &Data, bool isFile,
- vfs::File **F) {
+ std::unique_ptr<vfs::File> *F) {
// FIXME: FileSystemOpts shouldn't be passed in here, all paths should be
// absolute!
if (FileSystemOpts.WorkingDir.empty())
diff --git a/lib/Basic/FileSystemStatCache.cpp b/lib/Basic/FileSystemStatCache.cpp
index 0f16e94..7515cfb 100644
--- a/lib/Basic/FileSystemStatCache.cpp
+++ b/lib/Basic/FileSystemStatCache.cpp
@@ -52,8 +52,8 @@
/// implementation can optionally fill in FileDescriptor with a valid
/// descriptor and the client guarantees that it will close it.
bool FileSystemStatCache::get(const char *Path, FileData &Data, bool isFile,
- vfs::File **F, FileSystemStatCache *Cache,
- vfs::FileSystem &FS) {
+ std::unique_ptr<vfs::File> *F,
+ FileSystemStatCache *Cache, vfs::FileSystem &FS) {
LookupResult R;
bool isForDir = !isFile;
@@ -79,7 +79,7 @@
// Because of this, check to see if the file exists with 'open'. If the
// open succeeds, use fstat to get the stat info.
std::unique_ptr<vfs::File> OwnedFile;
- llvm::error_code EC = FS.openFileForRead(Path, OwnedFile);
+ std::error_code EC = FS.openFileForRead(Path, OwnedFile);
if (EC) {
// If the open fails, our "stat" fails.
@@ -92,7 +92,7 @@
if (Status) {
R = CacheExists;
copyStatusToFileData(*Status, Data);
- *F = OwnedFile.release();
+ *F = std::move(OwnedFile);
} else {
// fstat rarely fails. If it does, claim the initial open didn't
// succeed.
@@ -109,10 +109,8 @@
// demands.
if (Data.IsDirectory != isForDir) {
// If not, close the file if opened.
- if (F && *F) {
- (*F)->close();
+ if (F)
*F = nullptr;
- }
return true;
}
@@ -122,7 +120,7 @@
MemorizeStatCalls::LookupResult
MemorizeStatCalls::getStat(const char *Path, FileData &Data, bool isFile,
- vfs::File **F, vfs::FileSystem &FS) {
+ std::unique_ptr<vfs::File> *F, vfs::FileSystem &FS) {
LookupResult Result = statChained(Path, Data, isFile, F, FS);
// Do not cache failed stats, it is easy to construct common inconsistent
diff --git a/lib/Basic/OpenMPKinds.cpp b/lib/Basic/OpenMPKinds.cpp
index c014241..b48c02c 100644
--- a/lib/Basic/OpenMPKinds.cpp
+++ b/lib/Basic/OpenMPKinds.cpp
@@ -22,10 +22,10 @@
OpenMPDirectiveKind clang::getOpenMPDirectiveKind(StringRef Str) {
return llvm::StringSwitch<OpenMPDirectiveKind>(Str)
-#define OPENMP_DIRECTIVE(Name) \
- .Case(#Name, OMPD_##Name)
+#define OPENMP_DIRECTIVE(Name) .Case(#Name, OMPD_##Name)
+#define OPENMP_DIRECTIVE_EXT(Name, Str) .Case(Str, OMPD_##Name)
#include "clang/Basic/OpenMPKinds.def"
- .Default(OMPD_unknown);
+ .Default(OMPD_unknown);
}
const char *clang::getOpenMPDirectiveName(OpenMPDirectiveKind Kind) {
@@ -33,8 +33,12 @@
switch (Kind) {
case OMPD_unknown:
return "unknown";
-#define OPENMP_DIRECTIVE(Name) \
- case OMPD_##Name : return #Name;
+#define OPENMP_DIRECTIVE(Name) \
+ case OMPD_##Name: \
+ return #Name;
+#define OPENMP_DIRECTIVE_EXT(Name, Str) \
+ case OMPD_##Name: \
+ return Str;
#include "clang/Basic/OpenMPKinds.def"
break;
}
@@ -43,10 +47,9 @@
OpenMPClauseKind clang::getOpenMPClauseKind(StringRef Str) {
return llvm::StringSwitch<OpenMPClauseKind>(Str)
-#define OPENMP_CLAUSE(Name, Class) \
- .Case(#Name, OMPC_##Name)
+#define OPENMP_CLAUSE(Name, Class) .Case(#Name, OMPC_##Name)
#include "clang/Basic/OpenMPKinds.def"
- .Default(OMPC_unknown);
+ .Default(OMPC_unknown);
}
const char *clang::getOpenMPClauseName(OpenMPClauseKind Kind) {
@@ -54,8 +57,9 @@
switch (Kind) {
case OMPC_unknown:
return "unknown";
-#define OPENMP_CLAUSE(Name, Class) \
- case OMPC_##Name : return #Name;
+#define OPENMP_CLAUSE(Name, Class) \
+ case OMPC_##Name: \
+ return #Name;
#include "clang/Basic/OpenMPKinds.def"
case OMPC_threadprivate:
return "threadprivate or thread local";
@@ -68,16 +72,19 @@
switch (Kind) {
case OMPC_default:
return llvm::StringSwitch<OpenMPDefaultClauseKind>(Str)
-#define OPENMP_DEFAULT_KIND(Name) \
- .Case(#Name, OMPC_DEFAULT_##Name)
+#define OPENMP_DEFAULT_KIND(Name) .Case(#Name, OMPC_DEFAULT_##Name)
#include "clang/Basic/OpenMPKinds.def"
- .Default(OMPC_DEFAULT_unknown);
+ .Default(OMPC_DEFAULT_unknown);
case OMPC_proc_bind:
return llvm::StringSwitch<OpenMPProcBindClauseKind>(Str)
-#define OPENMP_PROC_BIND_KIND(Name) \
- .Case(#Name, OMPC_PROC_BIND_##Name)
+#define OPENMP_PROC_BIND_KIND(Name) .Case(#Name, OMPC_PROC_BIND_##Name)
#include "clang/Basic/OpenMPKinds.def"
- .Default(OMPC_PROC_BIND_unknown);
+ .Default(OMPC_PROC_BIND_unknown);
+ case OMPC_schedule:
+ return llvm::StringSwitch<OpenMPScheduleClauseKind>(Str)
+#define OPENMP_SCHEDULE_KIND(Name) .Case(#Name, OMPC_SCHEDULE_##Name)
+#include "clang/Basic/OpenMPKinds.def"
+ .Default(OMPC_SCHEDULE_unknown);
case OMPC_unknown:
case OMPC_threadprivate:
case OMPC_if:
@@ -86,9 +93,15 @@
case OMPC_collapse:
case OMPC_private:
case OMPC_firstprivate:
+ case OMPC_lastprivate:
case OMPC_shared:
+ case OMPC_reduction:
case OMPC_linear:
+ case OMPC_aligned:
case OMPC_copyin:
+ case OMPC_copyprivate:
+ case OMPC_ordered:
+ case OMPC_nowait:
break;
}
llvm_unreachable("Invalid OpenMP simple clause kind");
@@ -101,8 +114,9 @@
switch (Type) {
case OMPC_DEFAULT_unknown:
return "unknown";
-#define OPENMP_DEFAULT_KIND(Name) \
- case OMPC_DEFAULT_##Name : return #Name;
+#define OPENMP_DEFAULT_KIND(Name) \
+ case OMPC_DEFAULT_##Name: \
+ return #Name;
#include "clang/Basic/OpenMPKinds.def"
}
llvm_unreachable("Invalid OpenMP 'default' clause type");
@@ -110,11 +124,22 @@
switch (Type) {
case OMPC_PROC_BIND_unknown:
return "unknown";
-#define OPENMP_PROC_BIND_KIND(Name) \
- case OMPC_PROC_BIND_##Name : return #Name;
+#define OPENMP_PROC_BIND_KIND(Name) \
+ case OMPC_PROC_BIND_##Name: \
+ return #Name;
#include "clang/Basic/OpenMPKinds.def"
}
llvm_unreachable("Invalid OpenMP 'proc_bind' clause type");
+ case OMPC_schedule:
+ switch (Type) {
+ case OMPC_SCHEDULE_unknown:
+ return "unknown";
+#define OPENMP_SCHEDULE_KIND(Name) \
+ case OMPC_SCHEDULE_##Name: \
+ return #Name;
+#include "clang/Basic/OpenMPKinds.def"
+ }
+ llvm_unreachable("Invalid OpenMP 'schedule' clause type");
case OMPC_unknown:
case OMPC_threadprivate:
case OMPC_if:
@@ -123,9 +148,15 @@
case OMPC_collapse:
case OMPC_private:
case OMPC_firstprivate:
+ case OMPC_lastprivate:
case OMPC_shared:
+ case OMPC_reduction:
case OMPC_linear:
+ case OMPC_aligned:
case OMPC_copyin:
+ case OMPC_copyprivate:
+ case OMPC_ordered:
+ case OMPC_nowait:
break;
}
llvm_unreachable("Invalid OpenMP simple clause kind");
@@ -138,8 +169,9 @@
switch (DKind) {
case OMPD_parallel:
switch (CKind) {
-#define OPENMP_PARALLEL_CLAUSE(Name) \
- case OMPC_##Name: return true;
+#define OPENMP_PARALLEL_CLAUSE(Name) \
+ case OMPC_##Name: \
+ return true;
#include "clang/Basic/OpenMPKinds.def"
default:
break;
@@ -147,8 +179,59 @@
break;
case OMPD_simd:
switch (CKind) {
-#define OPENMP_SIMD_CLAUSE(Name) \
- case OMPC_##Name: return true;
+#define OPENMP_SIMD_CLAUSE(Name) \
+ case OMPC_##Name: \
+ return true;
+#include "clang/Basic/OpenMPKinds.def"
+ default:
+ break;
+ }
+ break;
+ case OMPD_for:
+ switch (CKind) {
+#define OPENMP_FOR_CLAUSE(Name) \
+ case OMPC_##Name: \
+ return true;
+#include "clang/Basic/OpenMPKinds.def"
+ default:
+ break;
+ }
+ break;
+ case OMPD_sections:
+ switch (CKind) {
+#define OPENMP_SECTIONS_CLAUSE(Name) \
+ case OMPC_##Name: \
+ return true;
+#include "clang/Basic/OpenMPKinds.def"
+ default:
+ break;
+ }
+ break;
+ case OMPD_single:
+ switch (CKind) {
+#define OPENMP_SINGLE_CLAUSE(Name) \
+ case OMPC_##Name: \
+ return true;
+#include "clang/Basic/OpenMPKinds.def"
+ default:
+ break;
+ }
+ break;
+ case OMPD_parallel_for:
+ switch (CKind) {
+#define OPENMP_PARALLEL_FOR_CLAUSE(Name) \
+ case OMPC_##Name: \
+ return true;
+#include "clang/Basic/OpenMPKinds.def"
+ default:
+ break;
+ }
+ break;
+ case OMPD_parallel_sections:
+ switch (CKind) {
+#define OPENMP_PARALLEL_SECTIONS_CLAUSE(Name) \
+ case OMPC_##Name: \
+ return true;
#include "clang/Basic/OpenMPKinds.def"
default:
break;
@@ -157,7 +240,40 @@
case OMPD_unknown:
case OMPD_threadprivate:
case OMPD_task:
+ case OMPD_section:
break;
}
return false;
}
+
+bool clang::isOpenMPLoopDirective(OpenMPDirectiveKind DKind) {
+ return DKind == OMPD_simd || DKind == OMPD_for ||
+ DKind == OMPD_parallel_for; // TODO add next directives.
+}
+
+bool clang::isOpenMPWorksharingDirective(OpenMPDirectiveKind DKind) {
+ return DKind == OMPD_for || DKind == OMPD_sections || DKind == OMPD_section ||
+ DKind == OMPD_single || DKind == OMPD_parallel_for ||
+ DKind == OMPD_parallel_sections; // TODO add next directives.
+}
+
+bool clang::isOpenMPParallelDirective(OpenMPDirectiveKind DKind) {
+ return DKind == OMPD_parallel || DKind == OMPD_parallel_for ||
+ DKind == OMPD_parallel_sections; // TODO add next directives.
+}
+
+bool clang::isOpenMPSimdDirective(OpenMPDirectiveKind DKind) {
+ return DKind == OMPD_simd; // TODO || DKind == OMPD_for_simd || ...
+}
+
+bool clang::isOpenMPPrivate(OpenMPClauseKind Kind) {
+ return Kind == OMPC_private || Kind == OMPC_firstprivate ||
+ Kind == OMPC_lastprivate || Kind == OMPC_linear ||
+ Kind == OMPC_reduction; // TODO add next clauses like 'reduction'.
+}
+
+bool clang::isOpenMPThreadPrivate(OpenMPClauseKind Kind) {
+ return Kind == OMPC_threadprivate ||
+ Kind == OMPC_copyin; // TODO add next clauses like 'copyprivate'.
+}
+
diff --git a/lib/Basic/SourceManager.cpp b/lib/Basic/SourceManager.cpp
index d2d5562..61dfe35 100644
--- a/lib/Basic/SourceManager.cpp
+++ b/lib/Basic/SourceManager.cpp
@@ -26,7 +26,6 @@
#include <algorithm>
#include <cstring>
#include <string>
-#include <sys/stat.h>
using namespace clang;
using namespace SrcMgr;
@@ -55,8 +54,8 @@
// Should be unreachable, but keep for sanity.
if (!Buffer.getPointer())
return llvm::MemoryBuffer::MemoryBuffer_Malloc;
-
- const llvm::MemoryBuffer *buf = Buffer.getPointer();
+
+ llvm::MemoryBuffer *buf = Buffer.getPointer();
return buf->getBufferKind();
}
@@ -69,8 +68,7 @@
: (unsigned) ContentsEntry->getSize();
}
-void ContentCache::replaceBuffer(const llvm::MemoryBuffer *B,
- bool DoNotFree) {
+void ContentCache::replaceBuffer(llvm::MemoryBuffer *B, bool DoNotFree) {
if (B && B == Buffer.getPointer()) {
assert(0 && "Replacing with the same buffer");
Buffer.setInt(DoNotFree? DoNotFreeFlag : 0);
@@ -83,10 +81,10 @@
Buffer.setInt(DoNotFree? DoNotFreeFlag : 0);
}
-const llvm::MemoryBuffer *ContentCache::getBuffer(DiagnosticsEngine &Diag,
- const SourceManager &SM,
- SourceLocation Loc,
- bool *Invalid) const {
+llvm::MemoryBuffer *ContentCache::getBuffer(DiagnosticsEngine &Diag,
+ const SourceManager &SM,
+ SourceLocation Loc,
+ bool *Invalid) const {
// Lazily create the Buffer for ContentCaches that wrap files. If we already
// computed it, just return what we have.
if (Buffer.getPointer() || !ContentsEntry) {
@@ -462,8 +460,8 @@
/// createMemBufferContentCache - Create a new ContentCache for the specified
/// memory buffer. This does no caching.
-const ContentCache*
-SourceManager::createMemBufferContentCache(const MemoryBuffer *Buffer) {
+const ContentCache *
+SourceManager::createMemBufferContentCache(llvm::MemoryBuffer *Buffer) {
// Add a new ContentCache to the MemBufferInfos list and return it.
ContentCache *Entry = ContentCacheAlloc.Allocate<ContentCache>();
new (Entry) ContentCache();
@@ -505,7 +503,7 @@
/// \brief As part of recovering from missing or changed content, produce a
/// fake, non-empty buffer.
-const llvm::MemoryBuffer *SourceManager::getFakeBufferForRecovery() const {
+llvm::MemoryBuffer *SourceManager::getFakeBufferForRecovery() const {
if (!FakeBufferForRecovery)
FakeBufferForRecovery
= llvm::MemoryBuffer::getMemBuffer("<<<INVALID BUFFER>>");
@@ -644,16 +642,15 @@
return SourceLocation::getMacroLoc(NextLocalOffset - (TokLength + 1));
}
-const llvm::MemoryBuffer *
-SourceManager::getMemoryBufferForFile(const FileEntry *File,
- bool *Invalid) {
+llvm::MemoryBuffer *SourceManager::getMemoryBufferForFile(const FileEntry *File,
+ bool *Invalid) {
const SrcMgr::ContentCache *IR = getOrCreateContentCache(File);
assert(IR && "getOrCreateContentCache() cannot return NULL");
return IR->getBuffer(Diag, *this, SourceLocation(), Invalid);
}
void SourceManager::overrideFileContents(const FileEntry *SourceFile,
- const llvm::MemoryBuffer *Buffer,
+ llvm::MemoryBuffer *Buffer,
bool DoNotFree) {
const SrcMgr::ContentCache *IR = getOrCreateContentCache(SourceFile);
assert(IR && "getOrCreateContentCache() cannot return NULL");
@@ -696,10 +693,9 @@
*Invalid = true;
return "<<<<<INVALID SOURCE LOCATION>>>>>";
}
-
- const llvm::MemoryBuffer *Buf
- = SLoc.getFile().getContentCache()->getBuffer(Diag, *this, SourceLocation(),
- &MyInvalid);
+
+ llvm::MemoryBuffer *Buf = SLoc.getFile().getContentCache()->getBuffer(
+ Diag, *this, SourceLocation(), &MyInvalid);
if (Invalid)
*Invalid = MyInvalid;
@@ -1117,9 +1113,8 @@
return "<<<<INVALID BUFFER>>>>";
}
- const llvm::MemoryBuffer *Buffer
- = Entry.getFile().getContentCache()
- ->getBuffer(Diag, *this, SourceLocation(), &CharDataInvalid);
+ llvm::MemoryBuffer *Buffer = Entry.getFile().getContentCache()->getBuffer(
+ Diag, *this, SourceLocation(), &CharDataInvalid);
if (Invalid)
*Invalid = CharDataInvalid;
return Buffer->getBufferStart() + (CharDataInvalid? 0 : LocInfo.second);
@@ -1131,7 +1126,7 @@
unsigned SourceManager::getColumnNumber(FileID FID, unsigned FilePos,
bool *Invalid) const {
bool MyInvalid = false;
- const llvm::MemoryBuffer *MemBuf = getBuffer(FID, &MyInvalid);
+ llvm::MemoryBuffer *MemBuf = getBuffer(FID, &MyInvalid);
if (Invalid)
*Invalid = MyInvalid;
@@ -1205,8 +1200,7 @@
llvm::BumpPtrAllocator &Alloc,
const SourceManager &SM, bool &Invalid) {
// Note that calling 'getBuffer()' may lazily page in the file.
- const MemoryBuffer *Buffer = FI->getBuffer(Diag, SM, SourceLocation(),
- &Invalid);
+ MemoryBuffer *Buffer = FI->getBuffer(Diag, SM, SourceLocation(), &Invalid);
if (Invalid)
return;
@@ -1763,7 +1757,7 @@
return FileLoc.getLocWithOffset(Size);
}
- const llvm::MemoryBuffer *Buffer = Content->getBuffer(Diag, *this);
+ llvm::MemoryBuffer *Buffer = Content->getBuffer(Diag, *this);
unsigned FilePos = Content->SourceLineCache[Line - 1];
const char *Buf = Buffer->getBufferStart() + FilePos;
unsigned BufLength = Buffer->getBufferSize() - FilePos;
diff --git a/lib/Basic/TargetInfo.cpp b/lib/Basic/TargetInfo.cpp
index 4d06648..adaa2e8 100644
--- a/lib/Basic/TargetInfo.cpp
+++ b/lib/Basic/TargetInfo.cpp
@@ -168,6 +168,21 @@
return NoInt;
}
+TargetInfo::IntType TargetInfo::getLeastIntTypeByWidth(unsigned BitWidth,
+ bool IsSigned) const {
+ if (getCharWidth() >= BitWidth)
+ return IsSigned ? SignedChar : UnsignedChar;
+ if (getShortWidth() >= BitWidth)
+ return IsSigned ? SignedShort : UnsignedShort;
+ if (getIntWidth() >= BitWidth)
+ return IsSigned ? SignedInt : UnsignedInt;
+ if (getLongWidth() >= BitWidth)
+ return IsSigned ? SignedLong : UnsignedLong;
+ if (getLongLongWidth() >= BitWidth)
+ return IsSigned ? SignedLongLong : UnsignedLongLong;
+ return NoInt;
+}
+
TargetInfo::RealType TargetInfo::getRealTypeByWidth(unsigned BitWidth) const {
if (getFloatWidth() == BitWidth)
return Float;
@@ -227,10 +242,10 @@
};
}
-/// setForcedLangOptions - Set forced language options.
+/// adjust - Set forced language options.
/// Apply changes to the target information with respect to certain
/// language options which change the target configuration.
-void TargetInfo::setForcedLangOptions(LangOptions &Opts) {
+void TargetInfo::adjust(const LangOptions &Opts) {
if (Opts.NoBitFieldTypeAlign)
UseBitFieldTypeAlignment = false;
if (Opts.ShortWChar)
diff --git a/lib/Basic/Targets.cpp b/lib/Basic/Targets.cpp
index 9343542..c88fed1 100644
--- a/lib/Basic/Targets.cpp
+++ b/lib/Basic/Targets.cpp
@@ -572,7 +572,7 @@
void getVisualStudioDefines(const LangOptions &Opts,
MacroBuilder &Builder) const {
if (Opts.CPlusPlus) {
- if (Opts.RTTI)
+ if (Opts.RTTIData)
Builder.defineMacro("_CPPRTTI");
if (Opts.Exceptions)
@@ -587,8 +587,12 @@
if (Opts.POSIXThreads)
Builder.defineMacro("_MT");
- if (Opts.MSCVersion != 0)
- Builder.defineMacro("_MSC_VER", Twine(Opts.MSCVersion));
+ if (Opts.MSCVersion != 0) {
+ Builder.defineMacro("_MSC_VER", Twine(Opts.MSCVersion / 100000));
+ Builder.defineMacro("_MSC_FULL_VER", Twine(Opts.MSCVersion));
+ // FIXME We cannot encode the revision information into 32-bits
+ Builder.defineMacro("_MSC_BUILD", Twine(1));
+ }
if (Opts.MicrosoftExt) {
Builder.defineMacro("_MSC_EXTENSIONS");
@@ -702,8 +706,9 @@
ArchDefinePwr6 = 1 << 9,
ArchDefinePwr6x = 1 << 10,
ArchDefinePwr7 = 1 << 11,
- ArchDefineA2 = 1 << 12,
- ArchDefineA2q = 1 << 13
+ ArchDefinePwr8 = 1 << 12,
+ ArchDefineA2 = 1 << 13,
+ ArchDefineA2q = 1 << 14
} ArchDefineTypes;
// Note: GCC recognizes the following additional cpus:
@@ -750,6 +755,8 @@
.Case("pwr6x", true)
.Case("power7", true)
.Case("pwr7", true)
+ .Case("power8", true)
+ .Case("pwr8", true)
.Case("powerpc", true)
.Case("ppc", true)
.Case("powerpc64", true)
@@ -1012,7 +1019,10 @@
| ArchDefinePpcsq)
.Case("pwr7", ArchDefineName | ArchDefinePwr6x | ArchDefinePwr6
| ArchDefinePwr5x | ArchDefinePwr5 | ArchDefinePwr4
- | ArchDefinePwr6 | ArchDefinePpcgr | ArchDefinePpcsq)
+ | ArchDefinePpcgr | ArchDefinePpcsq)
+ .Case("pwr8", ArchDefineName | ArchDefinePwr7 | ArchDefinePwr6x
+ | ArchDefinePwr6 | ArchDefinePwr5x | ArchDefinePwr5
+ | ArchDefinePwr4 | ArchDefinePpcgr | ArchDefinePpcsq)
.Case("power3", ArchDefinePpcgr)
.Case("power4", ArchDefinePwr4 | ArchDefinePpcgr | ArchDefinePpcsq)
.Case("power5", ArchDefinePwr5 | ArchDefinePwr4 | ArchDefinePpcgr
@@ -1026,7 +1036,10 @@
| ArchDefinePpcsq)
.Case("power7", ArchDefinePwr7 | ArchDefinePwr6x | ArchDefinePwr6
| ArchDefinePwr5x | ArchDefinePwr5 | ArchDefinePwr4
- | ArchDefinePwr6 | ArchDefinePpcgr | ArchDefinePpcsq)
+ | ArchDefinePpcgr | ArchDefinePpcsq)
+ .Case("power8", ArchDefinePwr8 | ArchDefinePwr7 | ArchDefinePwr6x
+ | ArchDefinePwr6 | ArchDefinePwr5x | ArchDefinePwr5
+ | ArchDefinePwr4 | ArchDefinePpcgr | ArchDefinePpcsq)
.Default(ArchDefineNone);
if (defs & ArchDefineName)
@@ -1053,6 +1066,8 @@
Builder.defineMacro("_ARCH_PWR6X");
if (defs & ArchDefinePwr7)
Builder.defineMacro("_ARCH_PWR7");
+ if (defs & ArchDefinePwr8)
+ Builder.defineMacro("_ARCH_PWR8");
if (defs & ArchDefineA2)
Builder.defineMacro("_ARCH_A2");
if (defs & ArchDefineA2q) {
@@ -1101,6 +1116,7 @@
.Case("g5", true)
.Case("pwr6", true)
.Case("pwr7", true)
+ .Case("pwr8", true)
.Case("ppc64", true)
.Case("ppc64le", true)
.Default(false);
@@ -1454,6 +1470,8 @@
"-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64";
class R600TargetInfo : public TargetInfo {
+ static const Builtin::Info BuiltinInfo[];
+
/// \brief The GPU profiles supported by the R600 target.
enum GPUKind {
GK_NONE,
@@ -1500,11 +1518,10 @@
void getTargetBuiltins(const Builtin::Info *&Records,
unsigned &NumRecords) const override {
- Records = nullptr;
- NumRecords = 0;
+ Records = BuiltinInfo;
+ NumRecords = clang::R600::LastTSBuiltin - Builtin::FirstTSBuiltin;
}
-
void getTargetDefines(const LangOptions &Opts,
MacroBuilder &Builder) const override {
Builder.defineMacro("__R600__");
@@ -1580,6 +1597,12 @@
}
};
+const Builtin::Info R600TargetInfo::BuiltinInfo[] = {
+#define BUILTIN(ID, TYPE, ATTRS) \
+ { #ID, TYPE, ATTRS, 0, ALL_LANGUAGES },
+#include "clang/Basic/BuiltinsR600.def"
+};
+
} // end anonymous namespace
namespace {
@@ -1863,7 +1886,7 @@
bool hasFeature(StringRef Feature) const override;
bool handleTargetFeatures(std::vector<std::string> &Features,
DiagnosticsEngine &Diags) override;
- const char* getABI() const override {
+ StringRef getABI() const override {
if (getTriple().getArch() == llvm::Triple::x86_64 && SSELevel >= AVX)
return "avx";
else if (getTriple().getArch() == llvm::Triple::x86 &&
@@ -3080,9 +3103,6 @@
WindowsTargetInfo<X86_32TargetInfo>::getTargetDefines(Opts, Builder);
}
};
-} // end anonymous namespace
-
-namespace {
// x86-32 Windows Visual Studio target
class MicrosoftX86_32TargetInfo : public WindowsX86_32TargetInfo {
@@ -3252,18 +3272,24 @@
class X86_64TargetInfo : public X86TargetInfo {
public:
X86_64TargetInfo(const llvm::Triple &Triple) : X86TargetInfo(Triple) {
- LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
+ const bool IsX32{getTriple().getEnvironment() == llvm::Triple::GNUX32};
+ LongWidth = LongAlign = PointerWidth = PointerAlign = IsX32 ? 32 : 64;
LongDoubleWidth = 128;
LongDoubleAlign = 128;
LargeArrayMinWidth = 128;
LargeArrayAlign = 128;
SuitableAlign = 128;
- IntMaxType = SignedLong;
- UIntMaxType = UnsignedLong;
- Int64Type = SignedLong;
+ SizeType = IsX32 ? UnsignedInt : UnsignedLong;
+ PtrDiffType = IsX32 ? SignedInt : SignedLong;
+ IntPtrType = IsX32 ? SignedInt : SignedLong;
+ IntMaxType = IsX32 ? SignedLongLong : SignedLong;
+ UIntMaxType = IsX32 ? UnsignedLongLong : UnsignedLong;
+ Int64Type = IsX32 ? SignedLongLong : SignedLong;
RegParmMax = 6;
- DescriptionString = "e-m:e-i64:64-f80:128-n8:16:32:64-S128";
+ DescriptionString = (IsX32)
+ ? "e-m:e-" "p:32:32-" "i64:64-f80:128-n8:16:32:64-S128"
+ : "e-m:e-" "i64:64-f80:128-n8:16:32:64-S128";
// Use fpret only for long double.
RealTypeUsesObjCFPRet = (1 << TargetInfo::LongDouble);
@@ -3272,10 +3298,8 @@
ComplexLongDoubleUsesFP2Ret = true;
// x86-64 has atomics up to 16 bytes.
- // FIXME: Once the backend is fixed, increase MaxAtomicInlineWidth to 128
- // on CPUs with cmpxchg16b
MaxAtomicPromoteWidth = 128;
- MaxAtomicInlineWidth = 64;
+ MaxAtomicInlineWidth = 128;
}
BuiltinVaListKind getBuiltinVaListKind() const override {
return TargetInfo::X86_64ABIBuiltinVaList;
@@ -3457,27 +3481,14 @@
static const Builtin::Info BuiltinInfo[];
static bool shouldUseInlineAtomic(const llvm::Triple &T) {
- if (T.isOSWindows())
- return true;
-
- // On linux, binaries targeting old cpus call functions in libgcc to
- // perform atomic operations. The implementation in libgcc then calls into
- // the kernel which on armv6 and newer uses ldrex and strex. The net result
- // is that if we assume the kernel is at least as recent as the hardware,
- // it is safe to use atomic instructions on armv6 and newer.
- if (!T.isOSLinux() &&
- T.getOS() != llvm::Triple::FreeBSD &&
- T.getOS() != llvm::Triple::NetBSD &&
- T.getOS() != llvm::Triple::Bitrig)
- return false;
StringRef ArchName = T.getArchName();
if (T.getArch() == llvm::Triple::arm ||
T.getArch() == llvm::Triple::armeb) {
StringRef VersionStr;
if (ArchName.startswith("armv"))
- VersionStr = ArchName.substr(4);
+ VersionStr = ArchName.substr(4, 1);
else if (ArchName.startswith("armebv"))
- VersionStr = ArchName.substr(6);
+ VersionStr = ArchName.substr(6, 1);
else
return false;
unsigned Version;
@@ -3489,9 +3500,9 @@
T.getArch() == llvm::Triple::thumbeb);
StringRef VersionStr;
if (ArchName.startswith("thumbv"))
- VersionStr = ArchName.substr(6);
+ VersionStr = ArchName.substr(6, 1);
else if (ArchName.startswith("thumbebv"))
- VersionStr = ArchName.substr(8);
+ VersionStr = ArchName.substr(8, 1);
else
return false;
unsigned Version;
@@ -3663,7 +3674,7 @@
// zero length bitfield.
UseZeroLengthBitfieldAlignment = true;
}
- const char *getABI() const override { return ABI.c_str(); }
+ StringRef getABI() const override { return ABI; }
bool setABI(const std::string &Name) override {
ABI = Name;
@@ -3819,7 +3830,8 @@
.Cases("cortex-r4", "cortex-r5", "7R")
.Case("swift", "7S")
.Case("cyclone", "8A")
- .Cases("cortex-m3", "cortex-m4", "7M")
+ .Case("cortex-m3", "7M")
+ .Case("cortex-m4", "7EM")
.Case("cortex-m0", "6M")
.Cases("cortex-a53", "cortex-a57", "8A")
.Default(nullptr);
@@ -3837,10 +3849,29 @@
if (!getCPUDefineSuffix(Name))
return false;
+ // Cortex M does not support 8 byte atomics, while general Thumb2 does.
+ StringRef Profile = getCPUProfile(Name);
+ if (Profile == "M" && MaxAtomicInlineWidth) {
+ MaxAtomicPromoteWidth = 32;
+ MaxAtomicInlineWidth = 32;
+ }
+
CPU = Name;
return true;
}
bool setFPMath(StringRef Name) override;
+ bool supportsThumb(StringRef ArchName, StringRef CPUArch,
+ unsigned CPUArchVer) const {
+ return CPUArchVer >= 7 || (CPUArch.find('T') != StringRef::npos) ||
+ (CPUArch.find('M') != StringRef::npos);
+ }
+ bool supportsThumb2(StringRef ArchName, StringRef CPUArch,
+ unsigned CPUArchVer) const {
+ // We check both CPUArchVer and ArchName because when only triple is
+ // specified, the default CPU is arm1136j-s.
+ return ArchName.endswith("v6t2") || ArchName.endswith("v7") ||
+ ArchName.endswith("v8") || CPUArch == "6T2" || CPUArchVer >= 7;
+ }
void getTargetDefines(const LangOptions &Opts,
MacroBuilder &Builder) const override {
// Target identification.
@@ -3856,10 +3887,40 @@
llvm_unreachable("Invalid char for architecture version number");
}
Builder.defineMacro("__ARM_ARCH_" + CPUArch + "__");
- Builder.defineMacro("__ARM_ARCH", CPUArch.substr(0, 1));
+
+ // ACLE 6.4.1 ARM/Thumb instruction set architecture
StringRef CPUProfile = getCPUProfile(CPU);
+ StringRef ArchName = getTriple().getArchName();
+
+ // __ARM_ARCH is defined as an integer value indicating the current ARM ISA
+ Builder.defineMacro("__ARM_ARCH", CPUArch.substr(0, 1));
+
+ // __ARM_ARCH_ISA_ARM is defined to 1 if the core supports the ARM ISA. It
+ // is not defined for the M-profile.
+ // NOTE that the deffault profile is assumed to be 'A'
+ if (CPUProfile.empty() || CPUProfile != "M")
+ Builder.defineMacro("__ARM_ARCH_ISA_ARM", "1");
+
+ // __ARM_ARCH_ISA_THUMB is defined to 1 if the core supporst the original
+ // Thumb ISA (including v6-M). It is set to 2 if the core supports the
+ // Thumb-2 ISA as found in the v6T2 architecture and all v7 architecture.
+ if (supportsThumb2(ArchName, CPUArch, CPUArchVer))
+ Builder.defineMacro("__ARM_ARCH_ISA_THUMB", "2");
+ else if (supportsThumb(ArchName, CPUArch, CPUArchVer))
+ Builder.defineMacro("__ARM_ARCH_ISA_THUMB", "1");
+
+ // __ARM_32BIT_STATE is defined to 1 if code is being generated for a 32-bit
+ // instruction set such as ARM or Thumb.
+ Builder.defineMacro("__ARM_32BIT_STATE", "1");
+
+ // ACLE 6.4.2 Architectural Profile (A, R, M or pre-Cortex)
+
+ // __ARM_ARCH_PROFILE is defined as 'A', 'R', 'M' or 'S', or unset.
if (!CPUProfile.empty())
- Builder.defineMacro("__ARM_ARCH_PROFILE", CPUProfile);
+ Builder.defineMacro("__ARM_ARCH_PROFILE", "'" + CPUProfile + "'");
+
+ // ACLE predefines.
+ Builder.defineMacro("__ARM_ACLE", "200");
// Subtarget options.
@@ -3889,11 +3950,7 @@
if (IsThumb) {
Builder.defineMacro("__THUMBEL__");
Builder.defineMacro("__thumb__");
- // We check both CPUArchVer and ArchName because when only triple is
- // specified, the default CPU is arm1136j-s.
- StringRef ArchName = getTriple().getArchName();
- if (CPUArch == "6T2" || CPUArchVer >= 7 || ArchName.endswith("v6t2") ||
- ArchName.endswith("v7") || ArchName.endswith("v8"))
+ if (supportsThumb2(ArchName, CPUArch, CPUArchVer))
Builder.defineMacro("__thumb2__");
}
if (((HWDiv & HWDivThumb) && IsThumb) || ((HWDiv & HWDivARM) && !IsThumb))
@@ -4115,6 +4172,7 @@
#include "clang/Basic/BuiltinsNEON.def"
#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, ALL_LANGUAGES },
+#define LANGBUILTIN(ID, TYPE, ATTRS, LANG) { #ID, TYPE, ATTRS, 0, LANG },
#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER,\
ALL_LANGUAGES },
#include "clang/Basic/BuiltinsARM.def"
@@ -4174,6 +4232,9 @@
// 31: VFPv3 40: VFPv4
Builder.defineMacro("_M_ARM_FP", "31");
}
+ BuiltinVaListKind getBuiltinVaListKind() const override {
+ return TargetInfo::CharPtrBuiltinVaList;
+ }
};
// Windows ARM + Itanium C++ ABI Target
@@ -4245,6 +4306,7 @@
NeonMode
};
+ std::string CPU;
unsigned FPU;
unsigned CRC;
unsigned Crypto;
@@ -4289,7 +4351,7 @@
TheCXXABI.set(TargetCXXABI::GenericAArch64);
}
- virtual const char *getABI() const { return ABI.c_str(); }
+ StringRef getABI() const override { return ABI; }
virtual bool setABI(const std::string &Name) {
if (Name != "aapcs" && Name != "darwinpcs")
return false;
@@ -4304,6 +4366,8 @@
.Cases("cortex-a53", "cortex-a57", true)
.Case("cyclone", true)
.Default(false);
+ if (CPUKnown)
+ CPU = Name;
return CPUKnown;
}
@@ -4375,6 +4439,23 @@
(Feature == "neon" && FPU == NeonMode);
}
+ void getDefaultFeatures(llvm::StringMap<bool> &Features) const override {
+
+ if (CPU == "cyclone") {
+ Features["fp-armv8"] = true;
+ Features["neon"] = true;
+ Features["crypto"] = true;
+ Features["crc"] = true;
+ Features["zcm"] = true;
+ Features["zcz"] = true;
+ } else if (CPU == "cortex-a53" || CPU == "cortex-a57") {
+ Features["fp-armv8"] = true;
+ Features["neon"] = true;
+ Features["crypto"] = true;
+ Features["crc"] = true;
+ }
+}
+
bool handleTargetFeatures(std::vector<std::string> &Features,
DiagnosticsEngine &Diags) override {
FPU = FPUMode;
@@ -5224,12 +5305,35 @@
IsNan2008(false), IsSingleFloat(false), FloatABI(HardFloat),
DspRev(NoDSP), HasMSA(false), HasFP64(false), ABI(ABIStr) {}
- const char *getABI() const override { return ABI.c_str(); }
- bool setABI(const std::string &Name) override = 0;
- bool setCPU(const std::string &Name) override {
- CPU = Name;
- return true;
+ bool isNaN2008Default() const {
+ return CPU == "mips32r6" || CPU == "mips64r6";
}
+
+ bool isFP64Default() const {
+ return CPU == "mips32r6" || ABI == "n32" || ABI == "n64" || ABI == "64";
+ }
+
+ StringRef getABI() const override { return ABI; }
+ bool setCPU(const std::string &Name) override {
+ bool IsMips32 = getTriple().getArch() == llvm::Triple::mips ||
+ getTriple().getArch() == llvm::Triple::mipsel;
+ CPU = Name;
+ return llvm::StringSwitch<bool>(Name)
+ .Case("mips1", IsMips32)
+ .Case("mips2", IsMips32)
+ .Case("mips3", true)
+ .Case("mips4", true)
+ .Case("mips5", true)
+ .Case("mips32", IsMips32)
+ .Case("mips32r2", IsMips32)
+ .Case("mips32r6", IsMips32)
+ .Case("mips64", true)
+ .Case("mips64r2", true)
+ .Case("mips64r6", true)
+ .Case("octeon", true)
+ .Default(false);
+ }
+ const std::string& getCPU() const { return CPU; }
void getDefaultFeatures(llvm::StringMap<bool> &Features) const override {
// The backend enables certain ABI's by default according to the
// architecture.
@@ -5239,7 +5343,10 @@
Features["n64"] = false;
Features[ABI] = true;
- Features[CPU] = true;
+ if (CPU == "octeon")
+ Features["mips64r2"] = Features["cnmips"] = true;
+ else
+ Features[CPU] = true;
}
void getTargetDefines(const LangOptions &Opts,
@@ -5376,11 +5483,11 @@
DiagnosticsEngine &Diags) override {
IsMips16 = false;
IsMicromips = false;
- IsNan2008 = false;
+ IsNan2008 = isNaN2008Default();
IsSingleFloat = false;
FloatABI = HardFloat;
DspRev = NoDSP;
- HasFP64 = ABI == "n32" || ABI == "n64" || ABI == "64";
+ HasFP64 = isFP64Default();
for (std::vector<std::string>::iterator it = Features.begin(),
ie = Features.end(); it != ie; ++it) {
@@ -5404,6 +5511,8 @@
HasFP64 = false;
else if (*it == "+nan2008")
IsNan2008 = true;
+ else if (*it == "-nan2008")
+ IsNan2008 = false;
}
// Remove front-end specific options.
@@ -5422,6 +5531,8 @@
if (RegNo == 1) return 5;
return -1;
}
+
+ bool isCLZForZeroUndef() const override { return false; }
};
const Builtin::Info MipsTargetInfoBase::BuiltinInfo[] = {
@@ -5440,20 +5551,24 @@
MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 32;
}
bool setABI(const std::string &Name) override {
- if ((Name == "o32") || (Name == "eabi")) {
+ if (Name == "o32" || Name == "eabi") {
ABI = Name;
return true;
- } else if (Name == "32") {
- ABI = "o32";
- return true;
- } else
- return false;
+ }
+ return false;
}
void getTargetDefines(const LangOptions &Opts,
MacroBuilder &Builder) const override {
MipsTargetInfoBase::getTargetDefines(Opts, Builder);
Builder.defineMacro("__mips", "32");
+ Builder.defineMacro("_MIPS_ISA", "_MIPS_ISA_MIPS32");
+
+ const std::string& CPUStr = getCPU();
+ if (CPUStr == "mips32")
+ Builder.defineMacro("__mips_isa_rev", "1");
+ else if (CPUStr == "mips32r2")
+ Builder.defineMacro("__mips_isa_rev", "2");
if (ABI == "o32") {
Builder.defineMacro("__mips_o32");
@@ -5574,9 +5689,10 @@
setN32ABITypes();
ABI = Name;
return true;
- } else if (Name == "n64" || Name == "64") {
+ }
+ if (Name == "n64") {
setN64ABITypes();
- ABI = "n64";
+ ABI = Name;
return true;
}
return false;
@@ -5589,6 +5705,13 @@
Builder.defineMacro("__mips", "64");
Builder.defineMacro("__mips64");
Builder.defineMacro("__mips64__");
+ Builder.defineMacro("_MIPS_ISA", "_MIPS_ISA_MIPS64");
+
+ const std::string& CPUStr = getCPU();
+ if (CPUStr == "mips64")
+ Builder.defineMacro("__mips_isa_rev", "1");
+ else if (CPUStr == "mips64r2")
+ Builder.defineMacro("__mips_isa_rev", "2");
if (ABI == "n32") {
Builder.defineMacro("__mips_n32");
@@ -5917,6 +6040,13 @@
default:
return nullptr;
+ case llvm::Triple::xcore:
+ return new XCoreTargetInfo(Triple);
+
+ case llvm::Triple::hexagon:
+ return new HexagonTargetInfo(Triple);
+
+ case llvm::Triple::aarch64:
case llvm::Triple::arm64:
if (Triple.isOSDarwin())
return new DarwinAArch64TargetInfo(Triple);
@@ -5930,33 +6060,8 @@
return new AArch64leTargetInfo(Triple);
}
- case llvm::Triple::arm64_be:
- switch (os) {
- case llvm::Triple::Linux:
- return new LinuxTargetInfo<AArch64beTargetInfo>(Triple);
- case llvm::Triple::NetBSD:
- return new NetBSDTargetInfo<AArch64beTargetInfo>(Triple);
- default:
- return new AArch64beTargetInfo(Triple);
- }
-
- case llvm::Triple::xcore:
- return new XCoreTargetInfo(Triple);
-
- case llvm::Triple::hexagon:
- return new HexagonTargetInfo(Triple);
-
- case llvm::Triple::aarch64:
- switch (os) {
- case llvm::Triple::Linux:
- return new LinuxTargetInfo<AArch64leTargetInfo>(Triple);
- case llvm::Triple::NetBSD:
- return new NetBSDTargetInfo<AArch64leTargetInfo>(Triple);
- default:
- return new AArch64leTargetInfo(Triple);
- }
-
case llvm::Triple::aarch64_be:
+ case llvm::Triple::arm64_be:
switch (os) {
case llvm::Triple::Linux:
return new LinuxTargetInfo<AArch64beTargetInfo>(Triple);
@@ -6226,6 +6331,7 @@
return new CygwinX86_32TargetInfo(Triple);
case llvm::Triple::GNU:
return new MinGWX86_32TargetInfo(Triple);
+ case llvm::Triple::Itanium:
case llvm::Triple::MSVC:
return new MicrosoftX86_32TargetInfo(Triple);
}
@@ -6296,8 +6402,9 @@
/// CreateTargetInfo - Return the target info object for the specified target
/// triple.
-TargetInfo *TargetInfo::CreateTargetInfo(DiagnosticsEngine &Diags,
- TargetOptions *Opts) {
+TargetInfo *
+TargetInfo::CreateTargetInfo(DiagnosticsEngine &Diags,
+ const std::shared_ptr<TargetOptions> &Opts) {
llvm::Triple Triple(Opts->Triple);
// Construct the target
@@ -6306,7 +6413,7 @@
Diags.Report(diag::err_target_unknown_triple) << Triple.str();
return nullptr;
}
- Target->setTargetOpts(Opts);
+ Target->TargetOpts = Opts;
// Set the target CPU if specified.
if (!Opts->CPU.empty() && !Target->setCPU(Opts->CPU)) {
diff --git a/lib/Basic/Version.cpp b/lib/Basic/Version.cpp
index ae32c01..c2b7753 100644
--- a/lib/Basic/Version.cpp
+++ b/lib/Basic/Version.cpp
@@ -13,7 +13,7 @@
#include "clang/Basic/Version.h"
#include "clang/Basic/LLVM.h"
-#include "llvm/Config/config.h"
+#include "clang/Config/config.h"
#include "llvm/Support/raw_ostream.h"
#include <cstdlib>
#include <cstring>
@@ -130,7 +130,7 @@
// If vendor supplied, include the base LLVM version as well.
#ifdef CLANG_VENDOR
- OS << " (based on LLVM " << PACKAGE_VERSION << ")";
+ OS << " (based on " << BACKEND_PACKAGE_STRING << ")";
#endif
return OS.str();
diff --git a/lib/Basic/VirtualFileSystem.cpp b/lib/Basic/VirtualFileSystem.cpp
index a469c9a..1f2a856 100644
--- a/lib/Basic/VirtualFileSystem.cpp
+++ b/lib/Basic/VirtualFileSystem.cpp
@@ -14,6 +14,8 @@
#include "llvm/ADT/iterator_range.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/StringSet.h"
+#include "llvm/Support/Errc.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/YAMLParser.h"
@@ -65,17 +67,15 @@
FileSystem::~FileSystem() {}
-error_code FileSystem::getBufferForFile(const llvm::Twine &Name,
- std::unique_ptr<MemoryBuffer> &Result,
- int64_t FileSize,
- bool RequiresNullTerminator,
- bool IsVolatile) {
+std::error_code FileSystem::getBufferForFile(
+ const llvm::Twine &Name, std::unique_ptr<MemoryBuffer> &Result,
+ int64_t FileSize, bool RequiresNullTerminator, bool IsVolatile) {
std::unique_ptr<File> F;
- if (error_code EC = openFileForRead(Name, F))
+ if (std::error_code EC = openFileForRead(Name, F))
return EC;
- error_code EC = F->getBuffer(Name, Result, FileSize, RequiresNullTerminator,
- IsVolatile);
+ std::error_code EC =
+ F->getBuffer(Name, Result, FileSize, RequiresNullTerminator, IsVolatile);
return EC;
}
@@ -96,11 +96,12 @@
public:
~RealFile();
ErrorOr<Status> status() override;
- error_code getBuffer(const Twine &Name, std::unique_ptr<MemoryBuffer> &Result,
- int64_t FileSize = -1,
- bool RequiresNullTerminator = true,
- bool IsVolatile = false) override;
- error_code close() override;
+ std::error_code getBuffer(const Twine &Name,
+ std::unique_ptr<MemoryBuffer> &Result,
+ int64_t FileSize = -1,
+ bool RequiresNullTerminator = true,
+ bool IsVolatile = false) override;
+ std::error_code close() override;
void setName(StringRef Name) override;
};
} // end anonymous namespace
@@ -110,7 +111,7 @@
assert(FD != -1 && "cannot stat closed file");
if (!S.isStatusKnown()) {
file_status RealStatus;
- if (error_code EC = sys::fs::status(FD, RealStatus))
+ if (std::error_code EC = sys::fs::status(FD, RealStatus))
return EC;
Status NewS(RealStatus);
NewS.setName(S.getName());
@@ -119,13 +120,19 @@
return S;
}
-error_code RealFile::getBuffer(const Twine &Name,
- std::unique_ptr<MemoryBuffer> &Result,
- int64_t FileSize, bool RequiresNullTerminator,
- bool IsVolatile) {
+std::error_code RealFile::getBuffer(const Twine &Name,
+ std::unique_ptr<MemoryBuffer> &Result,
+ int64_t FileSize,
+ bool RequiresNullTerminator,
+ bool IsVolatile) {
assert(FD != -1 && "cannot get buffer for closed file");
- return MemoryBuffer::getOpenFile(FD, Name.str().c_str(), Result, FileSize,
- RequiresNullTerminator, IsVolatile);
+ ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr =
+ MemoryBuffer::getOpenFile(FD, Name.str().c_str(), FileSize,
+ RequiresNullTerminator, IsVolatile);
+ if (std::error_code EC = BufferOrErr.getError())
+ return EC;
+ Result = std::move(BufferOrErr.get());
+ return std::error_code();
}
// FIXME: This is terrible, we need this for ::close.
@@ -138,11 +145,11 @@
#define S_ISFIFO(x) (0)
#endif
#endif
-error_code RealFile::close() {
+std::error_code RealFile::close() {
if (::close(FD))
- return error_code(errno, system_category());
+ return std::error_code(errno, std::generic_category());
FD = -1;
- return error_code::success();
+ return std::error_code();
}
void RealFile::setName(StringRef Name) {
@@ -154,28 +161,29 @@
class RealFileSystem : public FileSystem {
public:
ErrorOr<Status> status(const Twine &Path) override;
- error_code openFileForRead(const Twine &Path,
- std::unique_ptr<File> &Result) override;
+ std::error_code openFileForRead(const Twine &Path,
+ std::unique_ptr<File> &Result) override;
+ directory_iterator dir_begin(const Twine &Dir, std::error_code &EC) override;
};
} // end anonymous namespace
ErrorOr<Status> RealFileSystem::status(const Twine &Path) {
sys::fs::file_status RealStatus;
- if (error_code EC = sys::fs::status(Path, RealStatus))
+ if (std::error_code EC = sys::fs::status(Path, RealStatus))
return EC;
Status Result(RealStatus);
Result.setName(Path.str());
return Result;
}
-error_code RealFileSystem::openFileForRead(const Twine &Name,
- std::unique_ptr<File> &Result) {
+std::error_code RealFileSystem::openFileForRead(const Twine &Name,
+ std::unique_ptr<File> &Result) {
int FD;
- if (error_code EC = sys::fs::openFileForRead(Name, FD))
+ if (std::error_code EC = sys::fs::openFileForRead(Name, FD))
return EC;
Result.reset(new RealFile(FD));
Result->setName(Name.str());
- return error_code::success();
+ return std::error_code();
}
IntrusiveRefCntPtr<FileSystem> vfs::getRealFileSystem() {
@@ -183,6 +191,46 @@
return FS;
}
+namespace {
+class RealFSDirIter : public clang::vfs::detail::DirIterImpl {
+ std::string Path;
+ llvm::sys::fs::directory_iterator Iter;
+public:
+ RealFSDirIter(const Twine &_Path, std::error_code &EC)
+ : Path(_Path.str()), Iter(Path, EC) {
+ if (!EC && Iter != llvm::sys::fs::directory_iterator()) {
+ llvm::sys::fs::file_status S;
+ EC = Iter->status(S);
+ if (!EC) {
+ CurrentEntry = Status(S);
+ CurrentEntry.setName(Iter->path());
+ }
+ }
+ }
+
+ std::error_code increment() override {
+ std::error_code EC;
+ Iter.increment(EC);
+ if (EC) {
+ return EC;
+ } else if (Iter == llvm::sys::fs::directory_iterator()) {
+ CurrentEntry = Status();
+ } else {
+ llvm::sys::fs::file_status S;
+ EC = Iter->status(S);
+ CurrentEntry = Status(S);
+ CurrentEntry.setName(Iter->path());
+ }
+ return EC;
+ }
+};
+}
+
+directory_iterator RealFileSystem::dir_begin(const Twine &Dir,
+ std::error_code &EC) {
+ return directory_iterator(std::make_shared<RealFSDirIter>(Dir, EC));
+}
+
//===-----------------------------------------------------------------------===/
// OverlayFileSystem implementation
//===-----------------------------------------------------------------------===/
@@ -198,21 +246,90 @@
// FIXME: handle symlinks that cross file systems
for (iterator I = overlays_begin(), E = overlays_end(); I != E; ++I) {
ErrorOr<Status> Status = (*I)->status(Path);
- if (Status || Status.getError() != errc::no_such_file_or_directory)
+ if (Status || Status.getError() != llvm::errc::no_such_file_or_directory)
return Status;
}
- return error_code(errc::no_such_file_or_directory, system_category());
+ return make_error_code(llvm::errc::no_such_file_or_directory);
}
-error_code OverlayFileSystem::openFileForRead(const llvm::Twine &Path,
- std::unique_ptr<File> &Result) {
+std::error_code
+OverlayFileSystem::openFileForRead(const llvm::Twine &Path,
+ std::unique_ptr<File> &Result) {
// FIXME: handle symlinks that cross file systems
for (iterator I = overlays_begin(), E = overlays_end(); I != E; ++I) {
- error_code EC = (*I)->openFileForRead(Path, Result);
- if (!EC || EC != errc::no_such_file_or_directory)
+ std::error_code EC = (*I)->openFileForRead(Path, Result);
+ if (!EC || EC != llvm::errc::no_such_file_or_directory)
return EC;
}
- return error_code(errc::no_such_file_or_directory, system_category());
+ return make_error_code(llvm::errc::no_such_file_or_directory);
+}
+
+clang::vfs::detail::DirIterImpl::~DirIterImpl() { }
+
+namespace {
+class OverlayFSDirIterImpl : public clang::vfs::detail::DirIterImpl {
+ OverlayFileSystem &Overlays;
+ std::string Path;
+ OverlayFileSystem::iterator CurrentFS;
+ directory_iterator CurrentDirIter;
+ llvm::StringSet<> SeenNames;
+
+ std::error_code incrementFS() {
+ assert(CurrentFS != Overlays.overlays_end() && "incrementing past end");
+ ++CurrentFS;
+ for (auto E = Overlays.overlays_end(); CurrentFS != E; ++CurrentFS) {
+ std::error_code EC;
+ CurrentDirIter = (*CurrentFS)->dir_begin(Path, EC);
+ if (EC && EC != errc::no_such_file_or_directory)
+ return EC;
+ if (CurrentDirIter != directory_iterator())
+ break; // found
+ }
+ return std::error_code();
+ }
+
+ std::error_code incrementDirIter(bool IsFirstTime) {
+ assert((IsFirstTime || CurrentDirIter != directory_iterator()) &&
+ "incrementing past end");
+ std::error_code EC;
+ if (!IsFirstTime)
+ CurrentDirIter.increment(EC);
+ if (!EC && CurrentDirIter == directory_iterator())
+ EC = incrementFS();
+ return EC;
+ }
+
+ std::error_code incrementImpl(bool IsFirstTime) {
+ while (true) {
+ std::error_code EC = incrementDirIter(IsFirstTime);
+ if (EC || CurrentDirIter == directory_iterator()) {
+ CurrentEntry = Status();
+ return EC;
+ }
+ CurrentEntry = *CurrentDirIter;
+ StringRef Name = llvm::sys::path::filename(CurrentEntry.getName());
+ if (SeenNames.insert(Name))
+ return EC; // name not seen before
+ }
+ llvm_unreachable("returned above");
+ }
+
+public:
+ OverlayFSDirIterImpl(const Twine &Path, OverlayFileSystem &FS,
+ std::error_code &EC)
+ : Overlays(FS), Path(Path.str()), CurrentFS(Overlays.overlays_begin()) {
+ CurrentDirIter = (*CurrentFS)->dir_begin(Path, EC);
+ EC = incrementImpl(true);
+ }
+
+ std::error_code increment() override { return incrementImpl(false); }
+};
+} // end anonymous namespace
+
+directory_iterator OverlayFileSystem::dir_begin(const Twine &Dir,
+ std::error_code &EC) {
+ return directory_iterator(
+ std::make_shared<OverlayFSDirIterImpl>(Dir, *this, EC));
}
//===-----------------------------------------------------------------------===/
@@ -291,6 +408,19 @@
static bool classof(const Entry *E) { return E->getKind() == EK_File; }
};
+class VFSFromYAML;
+
+class VFSFromYamlDirIterImpl : public clang::vfs::detail::DirIterImpl {
+ std::string Dir;
+ VFSFromYAML &FS;
+ DirectoryEntry::iterator Current, End;
+public:
+ VFSFromYamlDirIterImpl(const Twine &Path, VFSFromYAML &FS,
+ DirectoryEntry::iterator Begin,
+ DirectoryEntry::iterator End, std::error_code &EC);
+ std::error_code increment() override;
+};
+
/// \brief A virtual file system parsed from a YAML file.
///
/// Currently, this class allows creating virtual directories and mapping
@@ -376,6 +506,9 @@
ErrorOr<Entry *> lookupPath(sys::path::const_iterator Start,
sys::path::const_iterator End, Entry *From);
+ /// \brief Get the status of a given an \c Entry.
+ ErrorOr<Status> status(const Twine &Path, Entry *E);
+
public:
~VFSFromYAML();
@@ -389,8 +522,30 @@
IntrusiveRefCntPtr<FileSystem> ExternalFS);
ErrorOr<Status> status(const Twine &Path) override;
- error_code openFileForRead(const Twine &Path,
- std::unique_ptr<File> &Result) override;
+ std::error_code openFileForRead(const Twine &Path,
+ std::unique_ptr<File> &Result) override;
+
+ directory_iterator dir_begin(const Twine &Dir, std::error_code &EC) override{
+ ErrorOr<Entry *> E = lookupPath(Dir);
+ if (!E) {
+ EC = E.getError();
+ return directory_iterator();
+ }
+ ErrorOr<Status> S = status(Dir, *E);
+ if (!S) {
+ EC = S.getError();
+ return directory_iterator();
+ }
+ if (!S->isDirectory()) {
+ EC = std::error_code(static_cast<int>(errc::not_a_directory),
+ std::system_category());
+ return directory_iterator();
+ }
+
+ DirectoryEntry *D = cast<DirectoryEntry>(*E);
+ return directory_iterator(std::make_shared<VFSFromYamlDirIterImpl>(Dir,
+ *this, D->contents_begin(), D->contents_end(), EC));
+ }
};
/// \brief A helper class to hold the common YAML parsing state.
@@ -740,21 +895,21 @@
Path_.toVector(Path);
// Handle relative paths
- if (error_code EC = sys::fs::make_absolute(Path))
+ if (std::error_code EC = sys::fs::make_absolute(Path))
return EC;
if (Path.empty())
- return error_code(errc::invalid_argument, system_category());
+ return make_error_code(llvm::errc::invalid_argument);
sys::path::const_iterator Start = sys::path::begin(Path);
sys::path::const_iterator End = sys::path::end(Path);
for (std::vector<Entry *>::iterator I = Roots.begin(), E = Roots.end();
I != E; ++I) {
ErrorOr<Entry *> Result = lookupPath(Start, End, *I);
- if (Result || Result.getError() != errc::no_such_file_or_directory)
+ if (Result || Result.getError() != llvm::errc::no_such_file_or_directory)
return Result;
}
- return error_code(errc::no_such_file_or_directory, system_category());
+ return make_error_code(llvm::errc::no_such_file_or_directory);
}
ErrorOr<Entry *> VFSFromYAML::lookupPath(sys::path::const_iterator Start,
@@ -767,7 +922,7 @@
if (CaseSensitive ? !Start->equals(From->getName())
: !Start->equals_lower(From->getName()))
// failure to match
- return error_code(errc::no_such_file_or_directory, system_category());
+ return make_error_code(llvm::errc::no_such_file_or_directory);
++Start;
@@ -778,25 +933,22 @@
DirectoryEntry *DE = dyn_cast<DirectoryEntry>(From);
if (!DE)
- return error_code(errc::not_a_directory, system_category());
+ return make_error_code(llvm::errc::not_a_directory);
for (DirectoryEntry::iterator I = DE->contents_begin(),
E = DE->contents_end();
I != E; ++I) {
ErrorOr<Entry *> Result = lookupPath(Start, End, *I);
- if (Result || Result.getError() != errc::no_such_file_or_directory)
+ if (Result || Result.getError() != llvm::errc::no_such_file_or_directory)
return Result;
}
- return error_code(errc::no_such_file_or_directory, system_category());
+ return make_error_code(llvm::errc::no_such_file_or_directory);
}
-ErrorOr<Status> VFSFromYAML::status(const Twine &Path) {
- ErrorOr<Entry *> Result = lookupPath(Path);
- if (!Result)
- return Result.getError();
-
+ErrorOr<Status> VFSFromYAML::status(const Twine &Path, Entry *E) {
+ assert(E != nullptr);
std::string PathStr(Path.str());
- if (FileEntry *F = dyn_cast<FileEntry>(*Result)) {
+ if (FileEntry *F = dyn_cast<FileEntry>(E)) {
ErrorOr<Status> S = ExternalFS->status(F->getExternalContentsPath());
assert(!S || S->getName() == F->getExternalContentsPath());
if (S && !F->useExternalName(UseExternalNames))
@@ -805,31 +957,39 @@
S->IsVFSMapped = true;
return S;
} else { // directory
- DirectoryEntry *DE = cast<DirectoryEntry>(*Result);
+ DirectoryEntry *DE = cast<DirectoryEntry>(E);
Status S = DE->getStatus();
S.setName(PathStr);
return S;
}
}
-error_code VFSFromYAML::openFileForRead(const Twine &Path,
- std::unique_ptr<vfs::File> &Result) {
+ErrorOr<Status> VFSFromYAML::status(const Twine &Path) {
+ ErrorOr<Entry *> Result = lookupPath(Path);
+ if (!Result)
+ return Result.getError();
+ return status(Path, *Result);
+}
+
+std::error_code
+VFSFromYAML::openFileForRead(const Twine &Path,
+ std::unique_ptr<vfs::File> &Result) {
ErrorOr<Entry *> E = lookupPath(Path);
if (!E)
return E.getError();
FileEntry *F = dyn_cast<FileEntry>(*E);
if (!F) // FIXME: errc::not_a_file?
- return error_code(errc::invalid_argument, system_category());
+ return make_error_code(llvm::errc::invalid_argument);
- if (error_code EC = ExternalFS->openFileForRead(F->getExternalContentsPath(),
- Result))
+ if (std::error_code EC =
+ ExternalFS->openFileForRead(F->getExternalContentsPath(), Result))
return EC;
if (!F->useExternalName(UseExternalNames))
Result->setName(Path.str());
- return error_code::success();
+ return std::error_code();
}
IntrusiveRefCntPtr<FileSystem>
@@ -981,3 +1141,70 @@
JSONWriter(OS).write(Mappings, IsCaseSensitive);
}
+
+VFSFromYamlDirIterImpl::VFSFromYamlDirIterImpl(const Twine &_Path,
+ VFSFromYAML &FS,
+ DirectoryEntry::iterator Begin,
+ DirectoryEntry::iterator End,
+ std::error_code &EC)
+ : Dir(_Path.str()), FS(FS), Current(Begin), End(End) {
+ if (Current != End) {
+ SmallString<128> PathStr(Dir);
+ llvm::sys::path::append(PathStr, (*Current)->getName());
+ llvm::ErrorOr<vfs::Status> S = FS.status(PathStr.str());
+ if (S)
+ CurrentEntry = *S;
+ else
+ EC = S.getError();
+ }
+}
+
+std::error_code VFSFromYamlDirIterImpl::increment() {
+ assert(Current != End && "cannot iterate past end");
+ if (++Current != End) {
+ SmallString<128> PathStr(Dir);
+ llvm::sys::path::append(PathStr, (*Current)->getName());
+ llvm::ErrorOr<vfs::Status> S = FS.status(PathStr.str());
+ if (!S)
+ return S.getError();
+ CurrentEntry = *S;
+ } else {
+ CurrentEntry = Status();
+ }
+ return std::error_code();
+}
+
+vfs::recursive_directory_iterator::recursive_directory_iterator(FileSystem &FS_,
+ const Twine &Path,
+ std::error_code &EC)
+ : FS(&FS_) {
+ directory_iterator I = FS->dir_begin(Path, EC);
+ if (!EC && I != directory_iterator()) {
+ State = std::make_shared<IterState>();
+ State->push(I);
+ }
+}
+
+vfs::recursive_directory_iterator &
+recursive_directory_iterator::increment(std::error_code &EC) {
+ assert(FS && State && !State->empty() && "incrementing past end");
+ assert(State->top()->isStatusKnown() && "non-canonical end iterator");
+ vfs::directory_iterator End;
+ if (State->top()->isDirectory()) {
+ vfs::directory_iterator I = FS->dir_begin(State->top()->getName(), EC);
+ if (EC)
+ return *this;
+ if (I != End) {
+ State->push(I);
+ return *this;
+ }
+ }
+
+ while (!State->empty() && State->top().increment(EC) == End)
+ State->pop();
+
+ if (State->empty())
+ State.reset(); // end iterator
+
+ return *this;
+}
diff --git a/lib/Basic/Warnings.cpp b/lib/Basic/Warnings.cpp
index b09e69a..196a215 100644
--- a/lib/Basic/Warnings.cpp
+++ b/lib/Basic/Warnings.cpp
@@ -67,11 +67,11 @@
// extension diagnostics onto WARNING or ERROR unless the user has futz'd
// around with them explicitly.
if (Opts.PedanticErrors)
- Diags.setExtensionHandlingBehavior(DiagnosticsEngine::Ext_Error);
+ Diags.setExtensionHandlingBehavior(diag::Severity::Error);
else if (Opts.Pedantic)
- Diags.setExtensionHandlingBehavior(DiagnosticsEngine::Ext_Warn);
+ Diags.setExtensionHandlingBehavior(diag::Severity::Warning);
else
- Diags.setExtensionHandlingBehavior(DiagnosticsEngine::Ext_Ignore);
+ Diags.setExtensionHandlingBehavior(diag::Severity::Ignored);
SmallVector<diag::kind, 10> _Diags;
const IntrusiveRefCntPtr< DiagnosticIDs > DiagIDs =
@@ -106,8 +106,9 @@
// Figure out how this option affects the warning. If -Wfoo, map the
// diagnostic to a warning, if -Wno-foo, map it to ignore.
- diag::Mapping Mapping = isPositive ? diag::MAP_WARNING : diag::MAP_IGNORE;
-
+ diag::Severity Mapping =
+ isPositive ? diag::Severity::Warning : diag::Severity::Ignored;
+
// -Wsystem-headers is a special case, not driven by the option table. It
// cannot be controlled with -Werror.
if (Opt == "system-headers") {
@@ -124,7 +125,7 @@
Diags.setEnableAllWarnings(true);
} else {
Diags.setEnableAllWarnings(false);
- Diags.setMappingToAllDiagnostics(diag::MAP_IGNORE);
+ Diags.setSeverityForAll(diag::Severity::Ignored);
}
}
continue;
@@ -193,7 +194,7 @@
EmitUnknownDiagWarning(Diags, isPositive ? "-W" : "-Wno-", Opt,
isPositive);
} else {
- Diags.setDiagnosticGroupMapping(Opt, Mapping);
+ Diags.setSeverityForGroup(Opt, Mapping);
}
}
}