summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/tools/clang/lib/Basic
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Basic')
-rw-r--r--contrib/llvm/tools/clang/lib/Basic/Builtins.cpp10
-rw-r--r--contrib/llvm/tools/clang/lib/Basic/Diagnostic.cpp239
-rw-r--r--contrib/llvm/tools/clang/lib/Basic/DiagnosticIDs.cpp397
-rw-r--r--contrib/llvm/tools/clang/lib/Basic/FileManager.cpp50
-rw-r--r--contrib/llvm/tools/clang/lib/Basic/IdentifierTable.cpp47
-rw-r--r--contrib/llvm/tools/clang/lib/Basic/LangOptions.cpp30
-rw-r--r--contrib/llvm/tools/clang/lib/Basic/SourceLocation.cpp22
-rw-r--r--contrib/llvm/tools/clang/lib/Basic/SourceManager.cpp797
-rw-r--r--contrib/llvm/tools/clang/lib/Basic/TargetInfo.cpp29
-rw-r--r--contrib/llvm/tools/clang/lib/Basic/Targets.cpp1098
-rw-r--r--contrib/llvm/tools/clang/lib/Basic/Version.cpp9
-rw-r--r--contrib/llvm/tools/clang/lib/Basic/VersionTuple.cpp2
12 files changed, 1957 insertions, 773 deletions
diff --git a/contrib/llvm/tools/clang/lib/Basic/Builtins.cpp b/contrib/llvm/tools/clang/lib/Basic/Builtins.cpp
index 7df24a0..7bdcdc6 100644
--- a/contrib/llvm/tools/clang/lib/Basic/Builtins.cpp
+++ b/contrib/llvm/tools/clang/lib/Basic/Builtins.cpp
@@ -32,11 +32,15 @@ const Builtin::Info &Builtin::Context::GetRecord(unsigned ID) const {
return TSRecords[ID - Builtin::FirstTSBuiltin];
}
-Builtin::Context::Context(const TargetInfo &Target) {
+Builtin::Context::Context() {
// Get the target specific builtins from the target.
TSRecords = 0;
NumTSRecords = 0;
- Target.getTargetBuiltins(TSRecords, NumTSRecords);
+}
+
+void Builtin::Context::InitializeTarget(const TargetInfo &Target) {
+ assert(NumTSRecords == 0 && "Already initialized target?");
+ Target.getTargetBuiltins(TSRecords, NumTSRecords);
}
/// InitializeBuiltins - Mark the identifiers for all the builtins with their
@@ -59,7 +63,7 @@ void Builtin::Context::InitializeBuiltins(IdentifierTable &Table,
}
void
-Builtin::Context::GetBuiltinNames(llvm::SmallVectorImpl<const char *> &Names,
+Builtin::Context::GetBuiltinNames(SmallVectorImpl<const char *> &Names,
bool NoBuiltins) {
// Final all target-independent names
for (unsigned i = Builtin::NotBuiltin+1; i != Builtin::FirstTSBuiltin; ++i)
diff --git a/contrib/llvm/tools/clang/lib/Basic/Diagnostic.cpp b/contrib/llvm/tools/clang/lib/Basic/Diagnostic.cpp
index ae363a0..e5f3901 100644
--- a/contrib/llvm/tools/clang/lib/Basic/Diagnostic.cpp
+++ b/contrib/llvm/tools/clang/lib/Basic/Diagnostic.cpp
@@ -20,21 +20,22 @@
using namespace clang;
-static void DummyArgToStringFn(Diagnostic::ArgumentKind AK, intptr_t QT,
+static void DummyArgToStringFn(DiagnosticsEngine::ArgumentKind AK, intptr_t QT,
const char *Modifier, unsigned ML,
const char *Argument, unsigned ArgLen,
- const Diagnostic::ArgumentValue *PrevArgs,
+ const DiagnosticsEngine::ArgumentValue *PrevArgs,
unsigned NumPrevArgs,
- llvm::SmallVectorImpl<char> &Output,
+ SmallVectorImpl<char> &Output,
void *Cookie,
- llvm::SmallVectorImpl<intptr_t> &QualTypeVals) {
+ SmallVectorImpl<intptr_t> &QualTypeVals) {
const char *Str = "<can't format argument>";
Output.append(Str, Str+strlen(Str));
}
-Diagnostic::Diagnostic(const llvm::IntrusiveRefCntPtr<DiagnosticIDs> &diags,
- DiagnosticClient *client, bool ShouldOwnClient)
+DiagnosticsEngine::DiagnosticsEngine(
+ const llvm::IntrusiveRefCntPtr<DiagnosticIDs> &diags,
+ DiagnosticConsumer *client, bool ShouldOwnClient)
: Diags(diags), Client(client), OwnsDiagClient(ShouldOwnClient),
SourceMgr(0) {
ArgToStringFn = DummyArgToStringFn;
@@ -43,6 +44,7 @@ Diagnostic::Diagnostic(const llvm::IntrusiveRefCntPtr<DiagnosticIDs> &diags,
AllExtensionsSilenced = 0;
IgnoreAllWarnings = false;
WarningsAsErrors = false;
+ EnableAllWarnings = false;
ErrorsAsFatal = false;
SuppressSystemWarnings = false;
SuppressAllDiagnostics = false;
@@ -55,12 +57,13 @@ Diagnostic::Diagnostic(const llvm::IntrusiveRefCntPtr<DiagnosticIDs> &diags,
Reset();
}
-Diagnostic::~Diagnostic() {
+DiagnosticsEngine::~DiagnosticsEngine() {
if (OwnsDiagClient)
delete Client;
}
-void Diagnostic::setClient(DiagnosticClient *client, bool ShouldOwnClient) {
+void DiagnosticsEngine::setClient(DiagnosticConsumer *client,
+ bool ShouldOwnClient) {
if (OwnsDiagClient && Client)
delete Client;
@@ -68,11 +71,11 @@ void Diagnostic::setClient(DiagnosticClient *client, bool ShouldOwnClient) {
OwnsDiagClient = ShouldOwnClient;
}
-void Diagnostic::pushMappings(SourceLocation Loc) {
+void DiagnosticsEngine::pushMappings(SourceLocation Loc) {
DiagStateOnPushStack.push_back(GetCurDiagState());
}
-bool Diagnostic::popMappings(SourceLocation Loc) {
+bool DiagnosticsEngine::popMappings(SourceLocation Loc) {
if (DiagStateOnPushStack.empty())
return false;
@@ -84,7 +87,7 @@ bool Diagnostic::popMappings(SourceLocation Loc) {
return true;
}
-void Diagnostic::Reset() {
+void DiagnosticsEngine::Reset() {
ErrorOccurred = false;
FatalErrorOccurred = false;
UnrecoverableErrorOccurred = false;
@@ -92,11 +95,13 @@ void Diagnostic::Reset() {
NumWarnings = 0;
NumErrors = 0;
NumErrorsSuppressed = 0;
+ TrapNumErrorsOccurred = 0;
+ TrapNumUnrecoverableErrorsOccurred = 0;
CurDiagID = ~0U;
// Set LastDiagLevel to an "unset" state. If we set it to 'Ignored', notes
- // using a Diagnostic associated to a translation unit that follow
- // diagnostics from a Diagnostic associated to anoter t.u. will not be
+ // using a DiagnosticsEngine associated to a translation unit that follow
+ // diagnostics from a DiagnosticsEngine associated to anoter t.u. will not be
// displayed.
LastDiagLevel = (DiagnosticIDs::Level)-1;
DelayedDiagID = 0;
@@ -112,8 +117,8 @@ void Diagnostic::Reset() {
PushDiagStatePoint(&DiagStates.back(), SourceLocation());
}
-void Diagnostic::SetDelayedDiagnostic(unsigned DiagID, llvm::StringRef Arg1,
- llvm::StringRef Arg2) {
+void DiagnosticsEngine::SetDelayedDiagnostic(unsigned DiagID, StringRef Arg1,
+ StringRef Arg2) {
if (DelayedDiagID)
return;
@@ -122,15 +127,15 @@ void Diagnostic::SetDelayedDiagnostic(unsigned DiagID, llvm::StringRef Arg1,
DelayedDiagArg2 = Arg2.str();
}
-void Diagnostic::ReportDelayed() {
+void DiagnosticsEngine::ReportDelayed() {
Report(DelayedDiagID) << DelayedDiagArg1 << DelayedDiagArg2;
DelayedDiagID = 0;
DelayedDiagArg1.clear();
DelayedDiagArg2.clear();
}
-Diagnostic::DiagStatePointsTy::iterator
-Diagnostic::GetDiagStatePointForLoc(SourceLocation L) const {
+DiagnosticsEngine::DiagStatePointsTy::iterator
+DiagnosticsEngine::GetDiagStatePointForLoc(SourceLocation L) const {
assert(!DiagStatePoints.empty());
assert(DiagStatePoints.front().Loc.isInvalid() &&
"Should have created a DiagStatePoint for command-line");
@@ -155,7 +160,7 @@ Diagnostic::GetDiagStatePointForLoc(SourceLocation L) const {
///
/// \param The source location that this change of diagnostic state should
/// take affect. It can be null if we are setting the latest state.
-void Diagnostic::setDiagnosticMapping(diag::kind Diag, diag::Mapping Map,
+void DiagnosticsEngine::setDiagnosticMapping(diag::kind Diag, diag::Mapping Map,
SourceLocation L) {
assert(Diag < diag::DIAG_UPPER_LIMIT &&
"Can only map builtin diagnostics");
@@ -167,10 +172,19 @@ void Diagnostic::setDiagnosticMapping(diag::kind Diag, diag::Mapping Map,
bool isPragma = L.isValid();
FullSourceLoc Loc(L, *SourceMgr);
FullSourceLoc LastStateChangePos = DiagStatePoints.back().Loc;
+ DiagnosticMappingInfo MappingInfo = DiagnosticMappingInfo::Make(
+ Map, /*IsUser=*/true, isPragma);
+
+ // If this is a pragma mapping, then set the diagnostic mapping flags so that
+ // we override command line options.
+ if (isPragma) {
+ MappingInfo.setNoWarningAsError(true);
+ MappingInfo.setNoErrorAsFatal(true);
+ }
// Common case; setting all the diagnostics of a group in one place.
if (Loc.isInvalid() || Loc == LastStateChangePos) {
- setDiagnosticMappingInternal(Diag, Map, GetCurDiagState(), true, isPragma);
+ GetCurDiagState()->setMappingInfo(Diag, MappingInfo);
return;
}
@@ -183,7 +197,7 @@ void Diagnostic::setDiagnosticMapping(diag::kind Diag, diag::Mapping Map,
// the new state became active.
DiagStates.push_back(*GetCurDiagState());
PushDiagStatePoint(&DiagStates.back(), Loc);
- setDiagnosticMappingInternal(Diag, Map, GetCurDiagState(), true, isPragma);
+ GetCurDiagState()->setMappingInfo(Diag, MappingInfo);
return;
}
@@ -196,12 +210,12 @@ void Diagnostic::setDiagnosticMapping(diag::kind Diag, diag::Mapping Map,
// Update all diagnostic states that are active after the given location.
for (DiagStatePointsTy::iterator
I = Pos+1, E = DiagStatePoints.end(); I != E; ++I) {
- setDiagnosticMappingInternal(Diag, Map, I->State, true, isPragma);
+ GetCurDiagState()->setMappingInfo(Diag, MappingInfo);
}
// If the location corresponds to an existing point, just update its state.
if (Pos->Loc == Loc) {
- setDiagnosticMappingInternal(Diag, Map, Pos->State, true, isPragma);
+ GetCurDiagState()->setMappingInfo(Diag, MappingInfo);
return;
}
@@ -210,12 +224,86 @@ void Diagnostic::setDiagnosticMapping(diag::kind Diag, diag::Mapping Map,
Pos->Loc.isBeforeInTranslationUnitThan(Loc);
DiagStates.push_back(*Pos->State);
DiagState *NewState = &DiagStates.back();
- setDiagnosticMappingInternal(Diag, Map, NewState, true, isPragma);
+ GetCurDiagState()->setMappingInfo(Diag, MappingInfo);
DiagStatePoints.insert(Pos+1, DiagStatePoint(NewState,
FullSourceLoc(Loc, *SourceMgr)));
}
-void Diagnostic::Report(const StoredDiagnostic &storedDiag) {
+bool DiagnosticsEngine::setDiagnosticGroupMapping(
+ StringRef Group, diag::Mapping Map, SourceLocation Loc)
+{
+ // Get the diagnostics in this group.
+ llvm::SmallVector<diag::kind, 8> GroupDiags;
+ if (Diags->getDiagnosticsInGroup(Group, GroupDiags))
+ return true;
+
+ // Set the mapping.
+ for (unsigned i = 0, e = GroupDiags.size(); i != e; ++i)
+ setDiagnosticMapping(GroupDiags[i], Map, Loc);
+
+ return false;
+}
+
+bool DiagnosticsEngine::setDiagnosticGroupWarningAsError(StringRef Group,
+ bool Enabled) {
+ // If we are enabling this feature, just set the diagnostic mappings to map to
+ // errors.
+ if (Enabled)
+ return setDiagnosticGroupMapping(Group, diag::MAP_ERROR);
+
+ // Otherwise, we want to set the diagnostic mapping's "no Werror" bit, and
+ // potentially downgrade anything already mapped to be a warning.
+
+ // Get the diagnostics in this group.
+ llvm::SmallVector<diag::kind, 8> GroupDiags;
+ if (Diags->getDiagnosticsInGroup(Group, GroupDiags))
+ return true;
+
+ // Perform the mapping change.
+ for (unsigned i = 0, e = GroupDiags.size(); i != e; ++i) {
+ DiagnosticMappingInfo &Info = GetCurDiagState()->getOrAddMappingInfo(
+ GroupDiags[i]);
+
+ if (Info.getMapping() == diag::MAP_ERROR ||
+ Info.getMapping() == diag::MAP_FATAL)
+ Info.setMapping(diag::MAP_WARNING);
+
+ Info.setNoWarningAsError(true);
+ }
+
+ return false;
+}
+
+bool DiagnosticsEngine::setDiagnosticGroupErrorAsFatal(StringRef Group,
+ bool Enabled) {
+ // If we are enabling this feature, just set the diagnostic mappings to map to
+ // fatal errors.
+ if (Enabled)
+ return setDiagnosticGroupMapping(Group, diag::MAP_FATAL);
+
+ // Otherwise, we want to set the diagnostic mapping's "no Werror" bit, and
+ // potentially downgrade anything already mapped to be an error.
+
+ // Get the diagnostics in this group.
+ llvm::SmallVector<diag::kind, 8> GroupDiags;
+ if (Diags->getDiagnosticsInGroup(Group, GroupDiags))
+ return true;
+
+ // Perform the mapping change.
+ for (unsigned i = 0, e = GroupDiags.size(); i != e; ++i) {
+ DiagnosticMappingInfo &Info = GetCurDiagState()->getOrAddMappingInfo(
+ GroupDiags[i]);
+
+ if (Info.getMapping() == diag::MAP_FATAL)
+ Info.setMapping(diag::MAP_ERROR);
+
+ Info.setNoErrorAsFatal(true);
+ }
+
+ return false;
+}
+
+void DiagnosticsEngine::Report(const StoredDiagnostic &storedDiag) {
assert(CurDiagID == ~0U && "Multiple diagnostics in flight at once!");
CurDiagLoc = storedDiag.getLocation();
@@ -232,19 +320,20 @@ void Diagnostic::Report(const StoredDiagnostic &storedDiag) {
DiagRanges[i++] = *RI;
NumFixItHints = storedDiag.fixit_size();
- assert(NumFixItHints < Diagnostic::MaxFixItHints && "Too many fix-it hints!");
+ assert(NumFixItHints < DiagnosticsEngine::MaxFixItHints &&
+ "Too many fix-it hints!");
i = 0;
for (StoredDiagnostic::fixit_iterator
FI = storedDiag.fixit_begin(),
FE = storedDiag.fixit_end(); FI != FE; ++FI)
FixItHints[i++] = *FI;
- assert(Client && "DiagnosticClient not set!");
+ assert(Client && "DiagnosticConsumer not set!");
Level DiagLevel = storedDiag.getLevel();
- DiagnosticInfo Info(this, storedDiag.getMessage());
+ Diagnostic Info(this, storedDiag.getMessage());
Client->HandleDiagnostic(DiagLevel, Info);
if (Client->IncludeInDiagnosticCounts()) {
- if (DiagLevel == Diagnostic::Warning)
+ if (DiagLevel == DiagnosticsEngine::Warning)
++NumWarnings;
}
@@ -263,11 +352,11 @@ bool DiagnosticBuilder::Emit() {
if (DiagObj == 0) return false;
// When emitting diagnostics, we set the final argument count into
- // the Diagnostic object.
+ // the DiagnosticsEngine object.
FlushCounts();
// Process the diagnostic, sending the accumulated information to the
- // DiagnosticClient.
+ // DiagnosticConsumer.
bool Emitted = DiagObj->ProcessDiag();
// Clear out the current diagnostic object.
@@ -285,16 +374,16 @@ bool DiagnosticBuilder::Emit() {
}
-DiagnosticClient::~DiagnosticClient() {}
+DiagnosticConsumer::~DiagnosticConsumer() {}
-void DiagnosticClient::HandleDiagnostic(Diagnostic::Level DiagLevel,
- const DiagnosticInfo &Info) {
+void DiagnosticConsumer::HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
+ const Diagnostic &Info) {
if (!IncludeInDiagnosticCounts())
return;
- if (DiagLevel == Diagnostic::Warning)
+ if (DiagLevel == DiagnosticsEngine::Warning)
++NumWarnings;
- else if (DiagLevel >= Diagnostic::Error)
+ else if (DiagLevel >= DiagnosticsEngine::Error)
++NumErrors;
}
@@ -337,9 +426,9 @@ static const char *ScanFormat(const char *I, const char *E, char Target) {
/// "%2" has a value from 0-2. If the value is 0, the diagnostic prints 'foo'.
/// If the value is 1, it prints 'bar'. If it has the value 2, it prints 'baz'.
/// This is very useful for certain classes of variant diagnostics.
-static void HandleSelectModifier(const DiagnosticInfo &DInfo, unsigned ValNo,
+static void HandleSelectModifier(const Diagnostic &DInfo, unsigned ValNo,
const char *Argument, unsigned ArgumentLen,
- llvm::SmallVectorImpl<char> &OutStr) {
+ SmallVectorImpl<char> &OutStr) {
const char *ArgumentEnd = Argument+ArgumentLen;
// Skip over 'ValNo' |'s.
@@ -362,7 +451,7 @@ static void HandleSelectModifier(const DiagnosticInfo &DInfo, unsigned ValNo,
/// letter 's' to the string if the value is not 1. This is used in cases like
/// this: "you idiot, you have %4 parameter%s4!".
static void HandleIntegerSModifier(unsigned ValNo,
- llvm::SmallVectorImpl<char> &OutStr) {
+ SmallVectorImpl<char> &OutStr) {
if (ValNo != 1)
OutStr.push_back('s');
}
@@ -372,7 +461,7 @@ static void HandleIntegerSModifier(unsigned ValNo,
/// to the first ordinal. Currently this is hard-coded to use the
/// English form.
static void HandleOrdinalModifier(unsigned ValNo,
- llvm::SmallVectorImpl<char> &OutStr) {
+ SmallVectorImpl<char> &OutStr) {
assert(ValNo != 0 && "ValNo must be strictly positive!");
llvm::raw_svector_ostream Out(OutStr);
@@ -495,9 +584,9 @@ static bool EvalPluralExpr(unsigned ValNo, const char *Start, const char *End) {
/// {1:form0|[2,4]:form1|:form2}
/// Polish (requires repeated form):
/// {1:form0|%100=[10,20]:form2|%10=[2,4]:form1|:form2}
-static void HandlePluralModifier(const DiagnosticInfo &DInfo, unsigned ValNo,
+static void HandlePluralModifier(const Diagnostic &DInfo, unsigned ValNo,
const char *Argument, unsigned ArgumentLen,
- llvm::SmallVectorImpl<char> &OutStr) {
+ SmallVectorImpl<char> &OutStr) {
const char *ArgumentEnd = Argument + ArgumentLen;
while (1) {
assert(Argument < ArgumentEnd && "Plural expression didn't match.");
@@ -523,34 +612,34 @@ static void HandlePluralModifier(const DiagnosticInfo &DInfo, unsigned ValNo,
/// FormatDiagnostic - Format this diagnostic into a string, substituting the
/// formal arguments into the %0 slots. The result is appended onto the Str
/// array.
-void DiagnosticInfo::
-FormatDiagnostic(llvm::SmallVectorImpl<char> &OutStr) const {
+void Diagnostic::
+FormatDiagnostic(SmallVectorImpl<char> &OutStr) const {
if (!StoredDiagMessage.empty()) {
OutStr.append(StoredDiagMessage.begin(), StoredDiagMessage.end());
return;
}
- llvm::StringRef Diag =
+ StringRef Diag =
getDiags()->getDiagnosticIDs()->getDescription(getID());
FormatDiagnostic(Diag.begin(), Diag.end(), OutStr);
}
-void DiagnosticInfo::
+void Diagnostic::
FormatDiagnostic(const char *DiagStr, const char *DiagEnd,
- llvm::SmallVectorImpl<char> &OutStr) const {
+ SmallVectorImpl<char> &OutStr) const {
/// FormattedArgs - Keep track of all of the arguments formatted by
/// ConvertArgToString and pass them into subsequent calls to
/// ConvertArgToString, allowing the implementation to avoid redundancies in
/// obvious cases.
- llvm::SmallVector<Diagnostic::ArgumentValue, 8> FormattedArgs;
+ SmallVector<DiagnosticsEngine::ArgumentValue, 8> FormattedArgs;
/// QualTypeVals - Pass a vector of arrays so that QualType names can be
/// compared to see if more information is needed to be printed.
- llvm::SmallVector<intptr_t, 2> QualTypeVals;
+ SmallVector<intptr_t, 2> QualTypeVals;
for (unsigned i = 0, e = getNumArgs(); i < e; ++i)
- if (getArgKind(i) == Diagnostic::ak_qualtype)
+ if (getArgKind(i) == DiagnosticsEngine::ak_qualtype)
QualTypeVals.push_back(getRawArg(i));
while (DiagStr != DiagEnd) {
@@ -600,17 +689,17 @@ FormatDiagnostic(const char *DiagStr, const char *DiagEnd,
assert(isdigit(*DiagStr) && "Invalid format for argument in diagnostic");
unsigned ArgNo = *DiagStr++ - '0';
- Diagnostic::ArgumentKind Kind = getArgKind(ArgNo);
+ DiagnosticsEngine::ArgumentKind Kind = getArgKind(ArgNo);
switch (Kind) {
// ---- STRINGS ----
- case Diagnostic::ak_std_string: {
+ case DiagnosticsEngine::ak_std_string: {
const std::string &S = getArgStdStr(ArgNo);
assert(ModifierLen == 0 && "No modifiers for strings yet");
OutStr.append(S.begin(), S.end());
break;
}
- case Diagnostic::ak_c_string: {
+ case DiagnosticsEngine::ak_c_string: {
const char *S = getArgCStr(ArgNo);
assert(ModifierLen == 0 && "No modifiers for strings yet");
@@ -622,7 +711,7 @@ FormatDiagnostic(const char *DiagStr, const char *DiagEnd,
break;
}
// ---- INTEGERS ----
- case Diagnostic::ak_sint: {
+ case DiagnosticsEngine::ak_sint: {
int Val = getArgSInt(ArgNo);
if (ModifierIs(Modifier, ModifierLen, "select")) {
@@ -641,7 +730,7 @@ FormatDiagnostic(const char *DiagStr, const char *DiagEnd,
}
break;
}
- case Diagnostic::ak_uint: {
+ case DiagnosticsEngine::ak_uint: {
unsigned Val = getArgUInt(ArgNo);
if (ModifierIs(Modifier, ModifierLen, "select")) {
@@ -660,7 +749,7 @@ FormatDiagnostic(const char *DiagStr, const char *DiagEnd,
break;
}
// ---- NAMES and TYPES ----
- case Diagnostic::ak_identifierinfo: {
+ case DiagnosticsEngine::ak_identifierinfo: {
const IdentifierInfo *II = getArgIdentifier(ArgNo);
assert(ModifierLen == 0 && "No modifiers for strings yet");
@@ -674,11 +763,11 @@ FormatDiagnostic(const char *DiagStr, const char *DiagEnd,
llvm::raw_svector_ostream(OutStr) << '\'' << II->getName() << '\'';
break;
}
- case Diagnostic::ak_qualtype:
- case Diagnostic::ak_declarationname:
- case Diagnostic::ak_nameddecl:
- case Diagnostic::ak_nestednamespec:
- case Diagnostic::ak_declcontext:
+ case DiagnosticsEngine::ak_qualtype:
+ case DiagnosticsEngine::ak_declarationname:
+ case DiagnosticsEngine::ak_nameddecl:
+ case DiagnosticsEngine::ak_nestednamespec:
+ case DiagnosticsEngine::ak_declcontext:
getDiags()->ConvertArgToString(Kind, getRawArg(ArgNo),
Modifier, ModifierLen,
Argument, ArgumentLen,
@@ -690,10 +779,10 @@ FormatDiagnostic(const char *DiagStr, const char *DiagEnd,
// Remember this argument info for subsequent formatting operations. Turn
// std::strings into a null terminated string to make it be the same case as
// all the other ones.
- if (Kind != Diagnostic::ak_std_string)
+ if (Kind != DiagnosticsEngine::ak_std_string)
FormattedArgs.push_back(std::make_pair(Kind, getRawArg(ArgNo)));
else
- FormattedArgs.push_back(std::make_pair(Diagnostic::ak_c_string,
+ FormattedArgs.push_back(std::make_pair(DiagnosticsEngine::ak_c_string,
(intptr_t)getArgStdStr(ArgNo).c_str()));
}
@@ -701,12 +790,12 @@ FormatDiagnostic(const char *DiagStr, const char *DiagEnd,
StoredDiagnostic::StoredDiagnostic() { }
-StoredDiagnostic::StoredDiagnostic(Diagnostic::Level Level, unsigned ID,
- llvm::StringRef Message)
+StoredDiagnostic::StoredDiagnostic(DiagnosticsEngine::Level Level, unsigned ID,
+ StringRef Message)
: ID(ID), Level(Level), Loc(), Message(Message) { }
-StoredDiagnostic::StoredDiagnostic(Diagnostic::Level Level,
- const DiagnosticInfo &Info)
+StoredDiagnostic::StoredDiagnostic(DiagnosticsEngine::Level Level,
+ const Diagnostic &Info)
: ID(Info.getID()), Level(Level)
{
assert((Info.getLocation().isInvalid() || Info.hasSourceManager()) &&
@@ -726,13 +815,23 @@ StoredDiagnostic::StoredDiagnostic(Diagnostic::Level Level,
FixIts.push_back(Info.getFixItHint(I));
}
+StoredDiagnostic::StoredDiagnostic(DiagnosticsEngine::Level Level, unsigned ID,
+ StringRef Message, FullSourceLoc Loc,
+ ArrayRef<CharSourceRange> Ranges,
+ ArrayRef<FixItHint> Fixits)
+ : ID(ID), Level(Level), Loc(Loc), Message(Message)
+{
+ this->Ranges.assign(Ranges.begin(), Ranges.end());
+ this->FixIts.assign(FixIts.begin(), FixIts.end());
+}
+
StoredDiagnostic::~StoredDiagnostic() { }
/// IncludeInDiagnosticCounts - This method (whose default implementation
/// returns true) indicates whether the diagnostics handled by this
-/// DiagnosticClient should be included in the number of diagnostics
-/// reported by Diagnostic.
-bool DiagnosticClient::IncludeInDiagnosticCounts() const { return true; }
+/// DiagnosticConsumer should be included in the number of diagnostics
+/// reported by DiagnosticsEngine.
+bool DiagnosticConsumer::IncludeInDiagnosticCounts() const { return true; }
PartialDiagnostic::StorageAllocator::StorageAllocator() {
for (unsigned I = 0; I != NumCached; ++I)
diff --git a/contrib/llvm/tools/clang/lib/Basic/DiagnosticIDs.cpp b/contrib/llvm/tools/clang/lib/Basic/DiagnosticIDs.cpp
index 147ba7e..9481287 100644
--- a/contrib/llvm/tools/clang/lib/Basic/DiagnosticIDs.cpp
+++ b/contrib/llvm/tools/clang/lib/Basic/DiagnosticIDs.cpp
@@ -21,6 +21,8 @@
#include "clang/Lex/LexDiagnostic.h"
#include "clang/Parse/ParseDiagnostic.h"
#include "clang/Sema/SemaDiagnostic.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/ErrorHandling.h"
#include <map>
using namespace clang;
@@ -45,6 +47,8 @@ struct StaticDiagInfoRec {
unsigned Class : 3;
unsigned SFINAE : 1;
unsigned AccessControl : 1;
+ unsigned WarnNoWerror : 1;
+ unsigned WarnShowInSystemHeader : 1;
unsigned Category : 5;
uint8_t NameLen;
@@ -61,21 +65,21 @@ struct StaticDiagInfoRec {
const char *BriefExplanationStr;
const char *FullExplanationStr;
- llvm::StringRef getName() const {
- return llvm::StringRef(NameStr, NameLen);
+ StringRef getName() const {
+ return StringRef(NameStr, NameLen);
}
- llvm::StringRef getOptionGroup() const {
- return llvm::StringRef(OptionGroupStr, OptionGroupLen);
+ StringRef getOptionGroup() const {
+ return StringRef(OptionGroupStr, OptionGroupLen);
}
- llvm::StringRef getDescription() const {
- return llvm::StringRef(DescriptionStr, DescriptionLen);
+ StringRef getDescription() const {
+ return StringRef(DescriptionStr, DescriptionLen);
}
- llvm::StringRef getBriefExplanation() const {
- return llvm::StringRef(BriefExplanationStr, BriefExplanationLen);
+ StringRef getBriefExplanation() const {
+ return StringRef(BriefExplanationStr, BriefExplanationLen);
}
- llvm::StringRef getFullExplanation() const {
- return llvm::StringRef(FullExplanationStr, FullExplanationLen);
+ StringRef getFullExplanation() const {
+ return StringRef(FullExplanationStr, FullExplanationLen);
}
bool operator<(const StaticDiagInfoRec &RHS) const {
@@ -88,8 +92,8 @@ struct StaticDiagNameIndexRec {
unsigned short DiagID;
uint8_t NameLen;
- llvm::StringRef getName() const {
- return llvm::StringRef(NameStr, NameLen);
+ StringRef getName() const {
+ return StringRef(NameStr, NameLen);
}
bool operator<(const StaticDiagNameIndexRec &RHS) const {
@@ -114,8 +118,10 @@ public:
static const StaticDiagInfoRec StaticDiagInfo[] = {
#define DIAG(ENUM,CLASS,DEFAULT_MAPPING,DESC,GROUP, \
- SFINAE,ACCESS,CATEGORY,BRIEF,FULL) \
- { diag::ENUM, DEFAULT_MAPPING, CLASS, SFINAE, ACCESS, CATEGORY, \
+ SFINAE,ACCESS,NOWERROR,SHOWINSYSHEADER, \
+ CATEGORY,BRIEF,FULL) \
+ { diag::ENUM, DEFAULT_MAPPING, CLASS, SFINAE, ACCESS, \
+ NOWERROR, SHOWINSYSHEADER, CATEGORY, \
STR_SIZE(#ENUM, uint8_t), STR_SIZE(GROUP, uint8_t), \
STR_SIZE(DESC, uint16_t), STR_SIZE(BRIEF, uint16_t), \
STR_SIZE(FULL, uint16_t), \
@@ -129,7 +135,7 @@ static const StaticDiagInfoRec StaticDiagInfo[] = {
#include "clang/Basic/DiagnosticSemaKinds.inc"
#include "clang/Basic/DiagnosticAnalysisKinds.inc"
#undef DIAG
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
};
static const unsigned StaticDiagInfoSize =
@@ -166,7 +172,8 @@ static const StaticDiagInfoRec *GetDiagInfo(unsigned DiagID) {
#endif
// Search the diagnostic table with a binary search.
- StaticDiagInfoRec Find = { DiagID, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0 };
+ StaticDiagInfoRec Find = { static_cast<unsigned short>(DiagID),
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
const StaticDiagInfoRec *Found =
std::lower_bound(StaticDiagInfo, StaticDiagInfo + StaticDiagInfoSize, Find);
@@ -177,19 +184,36 @@ static const StaticDiagInfoRec *GetDiagInfo(unsigned DiagID) {
return Found;
}
-static unsigned GetDefaultDiagMapping(unsigned DiagID) {
- if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID))
- return Info->Mapping;
- return diag::MAP_FATAL;
+static DiagnosticMappingInfo GetDefaultDiagMappingInfo(unsigned DiagID) {
+ DiagnosticMappingInfo Info = DiagnosticMappingInfo::Make(
+ diag::MAP_FATAL, /*IsUser=*/false, /*IsPragma=*/false);
+
+ if (const StaticDiagInfoRec *StaticInfo = GetDiagInfo(DiagID)) {
+ Info.setMapping((diag::Mapping) StaticInfo->Mapping);
+
+ if (StaticInfo->WarnNoWerror) {
+ assert(Info.getMapping() == diag::MAP_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;
}
/// getWarningOptionForDiag - Return the lowest-level warning option that
/// enables the specified diagnostic. If there is no -Wfoo flag that controls
/// the diagnostic, this returns null.
-llvm::StringRef DiagnosticIDs::getWarningOptionForDiag(unsigned DiagID) {
+StringRef DiagnosticIDs::getWarningOptionForDiag(unsigned DiagID) {
if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID))
return Info->getOptionGroup();
- return llvm::StringRef();
+ return StringRef();
}
/// getCategoryNumberForDiag - Return the category number that a specified
@@ -206,12 +230,28 @@ namespace {
const char *NameStr;
uint8_t NameLen;
- llvm::StringRef getName() const {
- return llvm::StringRef(NameStr, NameLen);
+ StringRef getName() const {
+ return StringRef(NameStr, NameLen);
}
};
}
+// 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()));
+
+ // Initialize the entry if we added it.
+ if (Result.second)
+ Result.first->second = GetDefaultDiagMappingInfo(Diag);
+
+ return Result.first->second;
+}
+
static const StaticDiagCategoryRec CategoryNameTable[] = {
#define GET_CATEGORY_TABLE
#define CATEGORY(X, ENUM) { X, STR_SIZE(X, uint8_t) },
@@ -228,9 +268,9 @@ unsigned DiagnosticIDs::getNumberOfCategories() {
/// getCategoryNameFromID - Given a category ID, return the name of the
/// category, an empty string if CategoryID is zero, or null if CategoryID is
/// invalid.
-llvm::StringRef DiagnosticIDs::getCategoryNameFromID(unsigned CategoryID) {
+StringRef DiagnosticIDs::getCategoryNameFromID(unsigned CategoryID) {
if (CategoryID >= getNumberOfCategories())
- return llvm::StringRef();
+ return StringRef();
return CategoryNameTable[CategoryID].getName();
}
@@ -256,20 +296,23 @@ DiagnosticIDs::getDiagnosticSFINAEResponse(unsigned DiagID) {
}
/// getName - Given a diagnostic ID, return its name
-llvm::StringRef DiagnosticIDs::getName(unsigned DiagID) {
+StringRef DiagnosticIDs::getName(unsigned DiagID) {
if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID))
return Info->getName();
- return llvm::StringRef();
+ return StringRef();
}
/// getIdFromName - Given a diagnostic name, return its ID, or 0
-unsigned DiagnosticIDs::getIdFromName(llvm::StringRef Name) {
+unsigned DiagnosticIDs::getIdFromName(StringRef Name) {
const StaticDiagNameIndexRec *StaticDiagNameIndexEnd =
StaticDiagNameIndex + StaticDiagNameIndexSize;
if (Name.empty()) { return diag::DIAG_UPPER_LIMIT; }
- StaticDiagNameIndexRec Find = { Name.data(), 0, Name.size() };
+ assert(Name.size() == static_cast<uint8_t>(Name.size()) &&
+ "Name is too long");
+ StaticDiagNameIndexRec Find = { Name.data(), 0,
+ static_cast<uint8_t>(Name.size()) };
const StaticDiagNameIndexRec *Found =
std::lower_bound( StaticDiagNameIndex, StaticDiagNameIndexEnd, Find);
@@ -282,18 +325,18 @@ unsigned DiagnosticIDs::getIdFromName(llvm::StringRef Name) {
/// getBriefExplanation - Given a diagnostic ID, return a brief explanation
/// of the issue
-llvm::StringRef DiagnosticIDs::getBriefExplanation(unsigned DiagID) {
+StringRef DiagnosticIDs::getBriefExplanation(unsigned DiagID) {
if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID))
return Info->getBriefExplanation();
- return llvm::StringRef();
+ return StringRef();
}
/// getFullExplanation - Given a diagnostic ID, return a full explanation
/// of the issue
-llvm::StringRef DiagnosticIDs::getFullExplanation(unsigned DiagID) {
+StringRef DiagnosticIDs::getFullExplanation(unsigned DiagID) {
if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID))
return Info->getFullExplanation();
- return llvm::StringRef();
+ return StringRef();
}
/// getBuiltinDiagClass - Return the class field of the diagnostic.
@@ -305,6 +348,35 @@ static unsigned getBuiltinDiagClass(unsigned DiagID) {
}
//===----------------------------------------------------------------------===//
+// diag_iterator
+//===----------------------------------------------------------------------===//
+
+llvm::StringRef DiagnosticIDs::diag_iterator::getDiagName() const {
+ return static_cast<const StaticDiagNameIndexRec*>(impl)->getName();
+}
+
+unsigned DiagnosticIDs::diag_iterator::getDiagID() const {
+ return static_cast<const StaticDiagNameIndexRec*>(impl)->DiagID;
+}
+
+DiagnosticIDs::diag_iterator &DiagnosticIDs::diag_iterator::operator++() {
+ const StaticDiagNameIndexRec* ptr =
+ static_cast<const StaticDiagNameIndexRec*>(impl);;
+ ++ptr;
+ impl = ptr;
+ return *this;
+}
+
+DiagnosticIDs::diag_iterator DiagnosticIDs::diags_begin() {
+ return DiagnosticIDs::diag_iterator(StaticDiagNameIndex);
+}
+
+DiagnosticIDs::diag_iterator DiagnosticIDs::diags_end() {
+ return DiagnosticIDs::diag_iterator(StaticDiagNameIndex +
+ StaticDiagNameIndexSize);
+}
+
+//===----------------------------------------------------------------------===//
// Custom Diagnostic information
//===----------------------------------------------------------------------===//
@@ -318,7 +390,7 @@ namespace clang {
/// getDescription - Return the description of the specified custom
/// diagnostic.
- llvm::StringRef getDescription(unsigned DiagID) const {
+ StringRef getDescription(unsigned DiagID) const {
assert(this && DiagID-DIAG_UPPER_LIMIT < DiagInfo.size() &&
"Invalid diagnosic ID");
return DiagInfo[DiagID-DIAG_UPPER_LIMIT].second;
@@ -331,7 +403,7 @@ namespace clang {
return DiagInfo[DiagID-DIAG_UPPER_LIMIT].first;
}
- unsigned getOrCreateDiagID(DiagnosticIDs::Level L, llvm::StringRef Message,
+ unsigned getOrCreateDiagID(DiagnosticIDs::Level L, StringRef Message,
DiagnosticIDs &Diags) {
DiagDesc D(L, Message);
// Check to see if it already exists.
@@ -366,7 +438,7 @@ DiagnosticIDs::~DiagnosticIDs() {
/// getCustomDiagID - Return an ID for a diagnostic with the specified message
/// and level. If this is the first request for this diagnosic, it is
/// registered and created, otherwise the existing ID is returned.
-unsigned DiagnosticIDs::getCustomDiagID(Level L, llvm::StringRef Message) {
+unsigned DiagnosticIDs::getCustomDiagID(Level L, StringRef Message) {
if (CustomDiagInfo == 0)
CustomDiagInfo = new diag::CustomDiagInfo();
return CustomDiagInfo->getOrCreateDiagID(L, Message, *this);
@@ -400,32 +472,39 @@ bool DiagnosticIDs::isBuiltinExtensionDiag(unsigned DiagID,
getBuiltinDiagClass(DiagID) != CLASS_EXTENSION)
return false;
- EnabledByDefault = GetDefaultDiagMapping(DiagID) != diag::MAP_IGNORE;
+ EnabledByDefault =
+ GetDefaultDiagMappingInfo(DiagID).getMapping() != diag::MAP_IGNORE;
return true;
}
+bool DiagnosticIDs::isDefaultMappingAsError(unsigned DiagID) {
+ if (DiagID >= diag::DIAG_UPPER_LIMIT)
+ return false;
+
+ return GetDefaultDiagMappingInfo(DiagID).getMapping() == diag::MAP_ERROR;
+}
+
/// getDescription - Given a diagnostic ID, return a description of the
/// issue.
-llvm::StringRef DiagnosticIDs::getDescription(unsigned DiagID) const {
+StringRef DiagnosticIDs::getDescription(unsigned DiagID) const {
if (const StaticDiagInfoRec *Info = GetDiagInfo(DiagID))
return Info->getDescription();
return CustomDiagInfo->getDescription(DiagID);
}
-/// getDiagnosticLevel - Based on the way the client configured the Diagnostic
-/// object, classify the specified diagnostic ID into a Level, consumable by
-/// the DiagnosticClient.
+/// getDiagnosticLevel - Based on the way the client configured the
+/// DiagnosticsEngine object, classify the specified diagnostic ID into a Level,
+/// by consumable the DiagnosticClient.
DiagnosticIDs::Level
DiagnosticIDs::getDiagnosticLevel(unsigned DiagID, SourceLocation Loc,
- const Diagnostic &Diag,
- diag::Mapping *mapping) const {
+ const DiagnosticsEngine &Diag) const {
// Handle custom diagnostics, which cannot be mapped.
if (DiagID >= diag::DIAG_UPPER_LIMIT)
return CustomDiagInfo->getLevel(DiagID);
unsigned DiagClass = getBuiltinDiagClass(DiagID);
assert(DiagClass != CLASS_NOTE && "Cannot get diagnostic level of a note!");
- return getDiagnosticLevel(DiagID, DiagClass, Loc, Diag, mapping);
+ return getDiagnosticLevel(DiagID, DiagClass, Loc, Diag);
}
/// \brief Based on the way the client configured the Diagnostic
@@ -437,130 +516,119 @@ DiagnosticIDs::getDiagnosticLevel(unsigned DiagID, SourceLocation Loc,
DiagnosticIDs::Level
DiagnosticIDs::getDiagnosticLevel(unsigned DiagID, unsigned DiagClass,
SourceLocation Loc,
- const Diagnostic &Diag,
- diag::Mapping *mapping) const {
+ const DiagnosticsEngine &Diag) const {
// 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;
- Diagnostic::DiagStatePointsTy::iterator
+ DiagnosticsEngine::DiagStatePointsTy::iterator
Pos = Diag.GetDiagStatePointForLoc(Loc);
- Diagnostic::DiagState *State = Pos->State;
-
- // Get the mapping information, if unset, compute it lazily.
- unsigned MappingInfo = Diag.getDiagnosticMappingInfo((diag::kind)DiagID,
- State);
- if (MappingInfo == 0) {
- MappingInfo = GetDefaultDiagMapping(DiagID);
- Diag.setDiagnosticMappingInternal(DiagID, MappingInfo, State, false, false);
- }
-
- if (mapping)
- *mapping = (diag::Mapping) (MappingInfo & 7);
+ DiagnosticsEngine::DiagState *State = Pos->State;
- bool ShouldEmitInSystemHeader = false;
+ // Get the mapping information, or compute it lazily.
+ DiagnosticMappingInfo &MappingInfo = State->getOrAddMappingInfo(
+ (diag::kind)DiagID);
- switch (MappingInfo & 7) {
- default: assert(0 && "Unknown mapping!");
+ switch (MappingInfo.getMapping()) {
+ default: llvm_unreachable("Unknown mapping!");
case diag::MAP_IGNORE:
- // Ignore this, unless this is an extension diagnostic and we're mapping
- // them onto warnings or errors.
- if (!isBuiltinExtensionDiag(DiagID) || // Not an extension
- Diag.ExtBehavior == Diagnostic::Ext_Ignore || // Ext ignored
- (MappingInfo & 8) != 0) // User explicitly mapped it.
- return DiagnosticIDs::Ignored;
+ Result = DiagnosticIDs::Ignored;
+ break;
+ case diag::MAP_WARNING:
Result = DiagnosticIDs::Warning;
- if (Diag.ExtBehavior == Diagnostic::Ext_Error) Result = DiagnosticIDs::Error;
- if (Result == DiagnosticIDs::Error && Diag.ErrorsAsFatal)
- Result = DiagnosticIDs::Fatal;
break;
case diag::MAP_ERROR:
Result = DiagnosticIDs::Error;
- if (Diag.ErrorsAsFatal)
- Result = DiagnosticIDs::Fatal;
break;
case diag::MAP_FATAL:
Result = DiagnosticIDs::Fatal;
break;
- case diag::MAP_WARNING_SHOW_IN_SYSTEM_HEADER:
- ShouldEmitInSystemHeader = true;
- // continue as MAP_WARNING.
- case diag::MAP_WARNING:
- // If warnings are globally mapped to ignore or error, do it.
- if (Diag.IgnoreAllWarnings)
- return DiagnosticIDs::Ignored;
+ }
+ // Upgrade ignored diagnostics if -Weverything is enabled.
+ if (Diag.EnableAllWarnings && Result == DiagnosticIDs::Ignored &&
+ !MappingInfo.isUser())
Result = DiagnosticIDs::Warning;
- // If this is an extension diagnostic and we're in -pedantic-error mode, and
- // if the user didn't explicitly map it, upgrade to an error.
- if (Diag.ExtBehavior == Diagnostic::Ext_Error &&
- (MappingInfo & 8) == 0 &&
- isBuiltinExtensionDiag(DiagID))
- Result = DiagnosticIDs::Error;
-
- if (Diag.WarningsAsErrors)
- Result = DiagnosticIDs::Error;
- if (Result == DiagnosticIDs::Error && Diag.ErrorsAsFatal)
- Result = DiagnosticIDs::Fatal;
- break;
+ // Ignore -pedantic diagnostics inside __extension__ blocks.
+ // (The diagnostics controlled by -pedantic are the extension diagnostics
+ // that are not enabled by default.)
+ bool EnabledByDefault;
+ bool IsExtensionDiag = isBuiltinExtensionDiag(DiagID, EnabledByDefault);
+ if (Diag.AllExtensionsSilenced && IsExtensionDiag && !EnabledByDefault)
+ return DiagnosticIDs::Ignored;
- case diag::MAP_WARNING_NO_WERROR:
- // Diagnostics specified with -Wno-error=foo should be set to warnings, but
- // not be adjusted by -Werror or -pedantic-errors.
- Result = DiagnosticIDs::Warning;
+ // 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 warnings are globally mapped to ignore or error, do it.
- if (Diag.IgnoreAllWarnings)
- return DiagnosticIDs::Ignored;
+ // At this point, ignored errors can no longer be upgraded.
+ if (Result == DiagnosticIDs::Ignored)
+ return Result;
- break;
+ // Honor -w, which is lower in priority than pedantic-errors, but higher than
+ // -Werror.
+ if (Result == DiagnosticIDs::Warning && Diag.IgnoreAllWarnings)
+ return DiagnosticIDs::Ignored;
- case diag::MAP_ERROR_NO_WFATAL:
- // Diagnostics specified as -Wno-fatal-error=foo should be errors, but
- // unaffected by -Wfatal-errors.
- Result = DiagnosticIDs::Error;
- break;
+ // If -Werror is enabled, map warnings to errors unless explicitly disabled.
+ if (Result == DiagnosticIDs::Warning) {
+ if (Diag.WarningsAsErrors && !MappingInfo.hasNoWarningAsError())
+ Result = DiagnosticIDs::Error;
}
- // Okay, we're about to return this as a "diagnostic to emit" one last check:
- // if this is any sort of extension warning, and if we're in an __extension__
- // block, silence it.
- if (Diag.AllExtensionsSilenced && isBuiltinExtensionDiag(DiagID))
- return DiagnosticIDs::Ignored;
+ // 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 we are in a system header, we ignore it.
- // We also want to ignore extensions and warnings in -Werror and
+ // 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 &&
- !ShouldEmitInSystemHeader &&
+ !MappingInfo.hasShowInSystemHeader() &&
Diag.SuppressSystemWarnings &&
Loc.isValid() &&
Diag.getSourceManager().isInSystemHeader(
- Diag.getSourceManager().getInstantiationLoc(Loc)))
+ Diag.getSourceManager().getExpansionLoc(Loc)))
return DiagnosticIDs::Ignored;
return Result;
}
-namespace {
- struct WarningOption {
- // Be safe with the size of 'NameLen' because we don't statically check if
- // the size will fit in the field; the struct size won't decrease with a
- // shorter type anyway.
- size_t NameLen;
- const char *NameStr;
- const short *Members;
- const short *SubGroups;
+struct clang::WarningOption {
+ // Be safe with the size of 'NameLen' because we don't statically check if
+ // the size will fit in the field; the struct size won't decrease with a
+ // shorter type anyway.
+ size_t NameLen;
+ const char *NameStr;
+ const short *Members;
+ const short *SubGroups;
- llvm::StringRef getName() const {
- return llvm::StringRef(NameStr, NameLen);
- }
- };
-}
+ StringRef getName() const {
+ return StringRef(NameStr, NameLen);
+ }
+};
#define GET_DIAG_ARRAYS
#include "clang/Basic/DiagnosticGroups.inc"
@@ -580,54 +648,43 @@ static bool WarningOptionCompare(const WarningOption &LHS,
return LHS.getName() < RHS.getName();
}
-static void MapGroupMembers(const WarningOption *Group, diag::Mapping Mapping,
- SourceLocation Loc, Diagnostic &Diag) {
- // Option exists, poke all the members of its diagnostic set.
+void DiagnosticIDs::getDiagnosticsInGroup(
+ const WarningOption *Group,
+ llvm::SmallVectorImpl<diag::kind> &Diags) const
+{
+ // Add the members of the option diagnostic set.
if (const short *Member = Group->Members) {
for (; *Member != -1; ++Member)
- Diag.setDiagnosticMapping(*Member, Mapping, Loc);
+ Diags.push_back(*Member);
}
- // Enable/disable all subgroups along with this one.
+ // Add the members of the subgroups.
if (const short *SubGroups = Group->SubGroups) {
for (; *SubGroups != (short)-1; ++SubGroups)
- MapGroupMembers(&OptionTable[(short)*SubGroups], Mapping, Loc, Diag);
+ getDiagnosticsInGroup(&OptionTable[(short)*SubGroups], Diags);
}
}
-/// setDiagnosticGroupMapping - Change an entire diagnostic group (e.g.
-/// "unknown-pragmas" to have the specified mapping. This returns true and
-/// ignores the request if "Group" was unknown, false otherwise.
-bool DiagnosticIDs::setDiagnosticGroupMapping(llvm::StringRef Group,
- diag::Mapping Map,
- SourceLocation Loc,
- Diagnostic &Diag) const {
- assert((Loc.isValid() ||
- Diag.DiagStatePoints.empty() ||
- Diag.DiagStatePoints.back().Loc.isInvalid()) &&
- "Loc should be invalid only when the mapping comes from command-line");
- assert((Loc.isInvalid() || Diag.DiagStatePoints.empty() ||
- Diag.DiagStatePoints.back().Loc.isInvalid() ||
- !Diag.SourceMgr->isBeforeInTranslationUnit(Loc,
- Diag.DiagStatePoints.back().Loc)) &&
- "Source location of new mapping is before the previous one!");
-
+bool DiagnosticIDs::getDiagnosticsInGroup(
+ StringRef Group,
+ llvm::SmallVectorImpl<diag::kind> &Diags) const
+{
WarningOption Key = { Group.size(), Group.data(), 0, 0 };
const WarningOption *Found =
std::lower_bound(OptionTable, OptionTable + OptionTableSize, Key,
WarningOptionCompare);
if (Found == OptionTable + OptionTableSize ||
Found->getName() != Group)
- return true; // Option not found.
+ return true; // Option not found.
- MapGroupMembers(Found, Map, Loc, Diag);
+ getDiagnosticsInGroup(Found, Diags);
return false;
}
/// ProcessDiag - This is the method used to report a diagnostic that is
/// finally fully formed.
-bool DiagnosticIDs::ProcessDiag(Diagnostic &Diag) const {
- DiagnosticInfo Info(&Diag);
+bool DiagnosticIDs::ProcessDiag(DiagnosticsEngine &Diag) const {
+ Diagnostic Info(&Diag);
if (Diag.SuppressAllDiagnostics)
return false;
@@ -665,6 +722,13 @@ bool DiagnosticIDs::ProcessDiag(Diagnostic &Diag) const {
Diag.LastDiagLevel = DiagLevel;
}
+ // Update counts for DiagnosticErrorTrap even if a fatal error occurred.
+ if (DiagLevel >= DiagnosticIDs::Error) {
+ ++Diag.TrapNumErrorsOccurred;
+ if (isUnrecoverable(DiagID))
+ ++Diag.TrapNumUnrecoverableErrorsOccurred;
+ }
+
// If a fatal error has already been emitted, silence all subsequent
// diagnostics.
if (Diag.FatalErrorOccurred) {
@@ -685,27 +749,26 @@ bool DiagnosticIDs::ProcessDiag(Diagnostic &Diag) const {
return false;
if (DiagLevel >= DiagnosticIDs::Error) {
- Diag.TrapErrorOccurred = true;
- if (isUnrecoverable(DiagID)) {
- Diag.TrapUnrecoverableErrorOccurred = true;
+ if (isUnrecoverable(DiagID))
Diag.UnrecoverableErrorOccurred = true;
- }
if (Diag.Client->IncludeInDiagnosticCounts()) {
Diag.ErrorOccurred = true;
++Diag.NumErrors;
}
- // If we've emitted a lot of errors, emit a fatal error after it to stop a
- // flood of bogus errors.
- if (Diag.ErrorLimit && Diag.NumErrors >= Diag.ErrorLimit &&
- DiagLevel == DiagnosticIDs::Error)
+ // If we've emitted a lot of errors, emit a fatal error instead of it to
+ // stop a flood of bogus errors.
+ if (Diag.ErrorLimit && Diag.NumErrors > Diag.ErrorLimit &&
+ DiagLevel == DiagnosticIDs::Error) {
Diag.SetDelayedDiagnostic(diag::fatal_too_many_errors);
+ return false;
+ }
}
// If we have any Fix-Its, make sure that all of the Fix-Its point into
- // source locations that aren't macro instantiations. If any point into
- // macro instantiations, remove all of the Fix-Its.
+ // source locations that aren't macro expansions. If any point into macro
+ // expansions, remove all of the Fix-Its.
for (unsigned I = 0, N = Diag.NumFixItHints; I != N; ++I) {
const FixItHint &FixIt = Diag.FixItHints[I];
if (FixIt.RemoveRange.isInvalid() ||
@@ -717,7 +780,7 @@ bool DiagnosticIDs::ProcessDiag(Diagnostic &Diag) const {
}
// Finally, report it.
- Diag.Client->HandleDiagnostic((Diagnostic::Level)DiagLevel, Info);
+ Diag.Client->HandleDiagnostic((DiagnosticsEngine::Level)DiagLevel, Info);
if (Diag.Client->IncludeInDiagnosticCounts()) {
if (DiagLevel == DiagnosticIDs::Warning)
++Diag.NumWarnings;
diff --git a/contrib/llvm/tools/clang/lib/Basic/FileManager.cpp b/contrib/llvm/tools/clang/lib/Basic/FileManager.cpp
index f747c53..c1f715e 100644
--- a/contrib/llvm/tools/clang/lib/Basic/FileManager.cpp
+++ b/contrib/llvm/tools/clang/lib/Basic/FileManager.cpp
@@ -217,25 +217,26 @@ void FileManager::removeStatCache(FileSystemStatCache *statCache) {
/// \brief Retrieve the directory that the given file name resides in.
/// Filename can point to either a real file or a virtual file.
static const DirectoryEntry *getDirectoryFromFile(FileManager &FileMgr,
- llvm::StringRef Filename) {
+ StringRef Filename,
+ bool CacheFailure) {
if (Filename.empty())
return NULL;
if (llvm::sys::path::is_separator(Filename[Filename.size() - 1]))
return NULL; // If Filename is a directory.
- llvm::StringRef DirName = llvm::sys::path::parent_path(Filename);
+ StringRef DirName = llvm::sys::path::parent_path(Filename);
// Use the current directory if file has no path component.
if (DirName.empty())
DirName = ".";
- return FileMgr.getDirectory(DirName);
+ return FileMgr.getDirectory(DirName, CacheFailure);
}
/// Add all ancestors of the given path (pointing to either a file or
/// a directory) as virtual directories.
-void FileManager::addAncestorsAsVirtualDirs(llvm::StringRef Path) {
- llvm::StringRef DirName = llvm::sys::path::parent_path(Path);
+void FileManager::addAncestorsAsVirtualDirs(StringRef Path) {
+ StringRef DirName = llvm::sys::path::parent_path(Path);
if (DirName.empty())
return;
@@ -263,7 +264,8 @@ void FileManager::addAncestorsAsVirtualDirs(llvm::StringRef Path) {
/// (real or virtual). This returns NULL if the directory doesn't
/// exist.
///
-const DirectoryEntry *FileManager::getDirectory(llvm::StringRef DirName) {
+const DirectoryEntry *FileManager::getDirectory(StringRef DirName,
+ bool CacheFailure) {
++NumDirLookups;
llvm::StringMapEntry<DirectoryEntry *> &NamedDirEnt =
SeenDirEntries.GetOrCreateValue(DirName);
@@ -287,6 +289,8 @@ const DirectoryEntry *FileManager::getDirectory(llvm::StringRef DirName) {
struct stat StatBuf;
if (getStatValue(InterndDirName, StatBuf, 0/*directory lookup*/)) {
// There's no real directory at the given path.
+ if (!CacheFailure)
+ SeenDirEntries.erase(DirName);
return 0;
}
@@ -309,7 +313,8 @@ const DirectoryEntry *FileManager::getDirectory(llvm::StringRef DirName) {
/// getFile - Lookup, cache, and verify the specified file (real or
/// virtual). This returns NULL if the file doesn't exist.
///
-const FileEntry *FileManager::getFile(llvm::StringRef Filename, bool openFile) {
+const FileEntry *FileManager::getFile(StringRef Filename, bool openFile,
+ bool CacheFailure) {
++NumFileLookups;
// See if there is already an entry in the map.
@@ -335,10 +340,15 @@ const FileEntry *FileManager::getFile(llvm::StringRef Filename, bool openFile) {
// subdirectory. This will let us avoid having to waste time on known-to-fail
// searches when we go to find sys/bar.h, because all the search directories
// without a 'sys' subdir will get a cached failure result.
- const DirectoryEntry *DirInfo = getDirectoryFromFile(*this, Filename);
- if (DirInfo == 0) // Directory doesn't exist, file can't exist.
+ const DirectoryEntry *DirInfo = getDirectoryFromFile(*this, Filename,
+ CacheFailure);
+ if (DirInfo == 0) { // Directory doesn't exist, file can't exist.
+ if (!CacheFailure)
+ SeenFileEntries.erase(Filename);
+
return 0;
-
+ }
+
// FIXME: Use the directory info to prune this, before doing the stat syscall.
// FIXME: This will reduce the # syscalls.
@@ -347,6 +357,9 @@ const FileEntry *FileManager::getFile(llvm::StringRef Filename, bool openFile) {
struct stat StatBuf;
if (getStatValue(InterndFileName, StatBuf, &FileDescriptor)) {
// There's no real file at the given path.
+ if (!CacheFailure)
+ SeenFileEntries.erase(Filename);
+
return 0;
}
@@ -381,7 +394,7 @@ const FileEntry *FileManager::getFile(llvm::StringRef Filename, bool openFile) {
}
const FileEntry *
-FileManager::getVirtualFile(llvm::StringRef Filename, off_t Size,
+FileManager::getVirtualFile(StringRef Filename, off_t Size,
time_t ModificationTime) {
++NumFileLookups;
@@ -404,7 +417,8 @@ FileManager::getVirtualFile(llvm::StringRef Filename, off_t Size,
// Now that all ancestors of Filename are in the cache, the
// following call is guaranteed to find the DirectoryEntry from the
// cache.
- const DirectoryEntry *DirInfo = getDirectoryFromFile(*this, Filename);
+ const DirectoryEntry *DirInfo = getDirectoryFromFile(*this, Filename,
+ /*CacheFailure=*/true);
assert(DirInfo &&
"The directory of a virtual file should already be in the cache.");
@@ -451,8 +465,8 @@ FileManager::getVirtualFile(llvm::StringRef Filename, off_t Size,
return UFE;
}
-void FileManager::FixupRelativePath(llvm::SmallVectorImpl<char> &path) const {
- llvm::StringRef pathRef(path.data(), path.size());
+void FileManager::FixupRelativePath(SmallVectorImpl<char> &path) const {
+ StringRef pathRef(path.data(), path.size());
if (FileSystemOpts.WorkingDir.empty()
|| llvm::sys::path::is_absolute(pathRef))
@@ -499,7 +513,7 @@ getBufferForFile(const FileEntry *Entry, std::string *ErrorStr) {
}
llvm::MemoryBuffer *FileManager::
-getBufferForFile(llvm::StringRef Filename, std::string *ErrorStr) {
+getBufferForFile(StringRef Filename, std::string *ErrorStr) {
llvm::OwningPtr<llvm::MemoryBuffer> Result;
llvm::error_code ec;
if (FileSystemOpts.WorkingDir.empty()) {
@@ -537,7 +551,7 @@ bool FileManager::getStatValue(const char *Path, struct stat &StatBuf,
StatCache.get());
}
-bool FileManager::getNoncachedStatValue(llvm::StringRef Path,
+bool FileManager::getNoncachedStatValue(StringRef Path,
struct stat &StatBuf) {
llvm::SmallString<128> FilePath(Path);
FixupRelativePath(FilePath);
@@ -546,7 +560,7 @@ bool FileManager::getNoncachedStatValue(llvm::StringRef Path,
}
void FileManager::GetUniqueIDMapping(
- llvm::SmallVectorImpl<const FileEntry *> &UIDToFiles) const {
+ SmallVectorImpl<const FileEntry *> &UIDToFiles) const {
UIDToFiles.clear();
UIDToFiles.resize(NextFileUID);
@@ -558,7 +572,7 @@ void FileManager::GetUniqueIDMapping(
UIDToFiles[FE->getValue()->getUID()] = FE->getValue();
// Map virtual file entries
- for (llvm::SmallVector<FileEntry*, 4>::const_iterator
+ for (SmallVector<FileEntry*, 4>::const_iterator
VFE = VirtualFileEntries.begin(), VFEEnd = VirtualFileEntries.end();
VFE != VFEEnd; ++VFE)
if (*VFE && *VFE != NON_EXISTENT_FILE)
diff --git a/contrib/llvm/tools/clang/lib/Basic/IdentifierTable.cpp b/contrib/llvm/tools/clang/lib/Basic/IdentifierTable.cpp
index 188e2d4..38f09a0 100644
--- a/contrib/llvm/tools/clang/lib/Basic/IdentifierTable.cpp
+++ b/contrib/llvm/tools/clang/lib/Basic/IdentifierTable.cpp
@@ -32,6 +32,7 @@ IdentifierInfo::IdentifierInfo() {
ObjCOrBuiltinID = 0;
HasMacro = false;
IsExtension = false;
+ IsCXX11CompatKeyword = false;
IsPoisoned = false;
IsCPPOperatorKeyword = false;
NeedsHandleIdentifier = false;
@@ -55,7 +56,7 @@ namespace {
class EmptyLookupIterator : public IdentifierIterator
{
public:
- virtual llvm::StringRef Next() { return llvm::StringRef(); }
+ virtual StringRef Next() { return StringRef(); }
};
}
@@ -102,11 +103,11 @@ namespace {
/// identifiers because they are language keywords. This causes the lexer to
/// automatically map matching identifiers to specialized token codes.
///
-/// The C90/C99/CPP/CPP0x flags are set to 2 if the token should be
-/// enabled in the specified langauge, set to 1 if it is an extension
-/// in the specified language, and set to 0 if disabled in the
-/// specified language.
-static void AddKeyword(llvm::StringRef Keyword,
+/// The C90/C99/CPP/CPP0x flags are set to 3 if the token is a keyword in a
+/// future language standard, set to 2 if the token should be enabled in the
+/// specified langauge, set to 1 if it is an extension in the specified
+/// language, and set to 0 if disabled in the specified language.
+static void AddKeyword(StringRef Keyword,
tok::TokenKind TokenCode, unsigned Flags,
const LangOptions &LangOpts, IdentifierTable &Table) {
unsigned AddResult = 0;
@@ -115,7 +116,7 @@ static void AddKeyword(llvm::StringRef Keyword,
else if (LangOpts.CPlusPlus0x && (Flags & KEYCXX0X)) AddResult = 2;
else if (LangOpts.C99 && (Flags & KEYC99)) AddResult = 2;
else if (LangOpts.GNUKeywords && (Flags & KEYGNU)) AddResult = 1;
- else if (LangOpts.Microsoft && (Flags & KEYMS)) AddResult = 1;
+ else if (LangOpts.MicrosoftExt && (Flags & KEYMS)) AddResult = 1;
else if (LangOpts.Borland && (Flags & KEYBORLAND)) AddResult = 1;
else if (LangOpts.Bool && (Flags & BOOLSUPPORT)) AddResult = 2;
else if (LangOpts.AltiVec && (Flags & KEYALTIVEC)) AddResult = 2;
@@ -123,17 +124,20 @@ static void AddKeyword(llvm::StringRef Keyword,
else if (!LangOpts.CPlusPlus && (Flags & KEYNOCXX)) AddResult = 2;
else if (LangOpts.C1X && (Flags & KEYC1X)) AddResult = 2;
else if (LangOpts.ObjCAutoRefCount && (Flags & KEYARC)) AddResult = 2;
-
+ else if (LangOpts.CPlusPlus && (Flags & KEYCXX0X)) AddResult = 3;
+
// Don't add this keyword if disabled in this language.
if (AddResult == 0) return;
- IdentifierInfo &Info = Table.get(Keyword, TokenCode);
+ IdentifierInfo &Info =
+ Table.get(Keyword, AddResult == 3 ? tok::identifier : TokenCode);
Info.setIsExtensionToken(AddResult == 1);
+ Info.setIsCXX11CompatKeyword(AddResult == 3);
}
/// AddCXXOperatorKeyword - Register a C++ operator keyword alternative
/// representations.
-static void AddCXXOperatorKeyword(llvm::StringRef Keyword,
+static void AddCXXOperatorKeyword(StringRef Keyword,
tok::TokenKind TokenCode,
IdentifierTable &Table) {
IdentifierInfo &Info = Table.get(Keyword, TokenCode);
@@ -142,7 +146,7 @@ static void AddCXXOperatorKeyword(llvm::StringRef Keyword,
/// AddObjCKeyword - Register an Objective-C @keyword like "class" "selector" or
/// "property".
-static void AddObjCKeyword(llvm::StringRef Name,
+static void AddObjCKeyword(StringRef Name,
tok::ObjCKeywordKind ObjCID,
IdentifierTable &Table) {
Table.get(Name).setObjCKeywordID(ObjCID);
@@ -153,20 +157,20 @@ static void AddObjCKeyword(llvm::StringRef Name,
void IdentifierTable::AddKeywords(const LangOptions &LangOpts) {
// Add keywords and tokens for the current language.
#define KEYWORD(NAME, FLAGS) \
- AddKeyword(llvm::StringRef(#NAME), tok::kw_ ## NAME, \
+ AddKeyword(StringRef(#NAME), tok::kw_ ## NAME, \
FLAGS, LangOpts, *this);
#define ALIAS(NAME, TOK, FLAGS) \
- AddKeyword(llvm::StringRef(NAME), tok::kw_ ## TOK, \
+ AddKeyword(StringRef(NAME), tok::kw_ ## TOK, \
FLAGS, LangOpts, *this);
#define CXX_KEYWORD_OPERATOR(NAME, ALIAS) \
if (LangOpts.CXXOperatorNames) \
- AddCXXOperatorKeyword(llvm::StringRef(#NAME), tok::ALIAS, *this);
+ AddCXXOperatorKeyword(StringRef(#NAME), tok::ALIAS, *this);
#define OBJC1_AT_KEYWORD(NAME) \
if (LangOpts.ObjC1) \
- AddObjCKeyword(llvm::StringRef(#NAME), tok::objc_##NAME, *this);
+ AddObjCKeyword(StringRef(#NAME), tok::objc_##NAME, *this);
#define OBJC2_AT_KEYWORD(NAME) \
if (LangOpts.ObjC2) \
- AddObjCKeyword(llvm::StringRef(#NAME), tok::objc_##NAME, *this);
+ AddObjCKeyword(StringRef(#NAME), tok::objc_##NAME, *this);
#define TESTING_KEYWORD(NAME, FLAGS)
#include "clang/Basic/TokenKinds.def"
@@ -217,6 +221,7 @@ tok::PPKeywordKind IdentifierInfo::getPPKeywordID() const {
CASE(12, 'i', 'c', include_next);
CASE(16, '_', 'i', __include_macros);
+ CASE(16, '_', 'e', __export_macro__);
#undef CASE
#undef HASH
}
@@ -336,9 +341,9 @@ IdentifierInfo *Selector::getIdentifierInfoForSlot(unsigned argIndex) const {
return SI->getIdentifierInfoForSlot(argIndex);
}
-llvm::StringRef Selector::getNameForSlot(unsigned int argIndex) const {
+StringRef Selector::getNameForSlot(unsigned int argIndex) const {
IdentifierInfo *II = getIdentifierInfoForSlot(argIndex);
- return II? II->getName() : llvm::StringRef();
+ return II? II->getName() : StringRef();
}
std::string MultiKeywordSelector::getName() const {
@@ -377,7 +382,7 @@ std::string Selector::getAsString() const {
/// Interpreting the given string using the normal CamelCase
/// conventions, determine whether the given string starts with the
/// given "word", which is assumed to end in a lowercase letter.
-static bool startsWithWord(llvm::StringRef name, llvm::StringRef word) {
+static bool startsWithWord(StringRef name, StringRef word) {
if (name.size() < word.size()) return false;
return ((name.size() == word.size() ||
!islower(name[word.size()]))
@@ -388,10 +393,11 @@ ObjCMethodFamily Selector::getMethodFamilyImpl(Selector sel) {
IdentifierInfo *first = sel.getIdentifierInfoForSlot(0);
if (!first) return OMF_None;
- llvm::StringRef name = first->getName();
+ StringRef name = first->getName();
if (sel.isUnarySelector()) {
if (name == "autorelease") return OMF_autorelease;
if (name == "dealloc") return OMF_dealloc;
+ if (name == "finalize") return OMF_finalize;
if (name == "release") return OMF_release;
if (name == "retain") return OMF_retain;
if (name == "retainCount") return OMF_retainCount;
@@ -491,4 +497,3 @@ const char *clang::getOperatorSpelling(OverloadedOperatorKind Operator) {
return 0;
}
-
diff --git a/contrib/llvm/tools/clang/lib/Basic/LangOptions.cpp b/contrib/llvm/tools/clang/lib/Basic/LangOptions.cpp
new file mode 100644
index 0000000..5f479db
--- /dev/null
+++ b/contrib/llvm/tools/clang/lib/Basic/LangOptions.cpp
@@ -0,0 +1,30 @@
+//===--- LangOptions.cpp - C Language Family Language Options ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the LangOptions class.
+//
+//===----------------------------------------------------------------------===//
+#include "clang/Basic/LangOptions.h"
+
+using namespace clang;
+
+LangOptions::LangOptions() {
+#define LANGOPT(Name, Bits, Default, Description) Name = Default;
+#define ENUM_LANGOPT(Name, Type, Bits, Default, Description) set##Name(Default);
+#include "clang/Basic/LangOptions.def"
+}
+
+void LangOptions::resetNonModularOptions() {
+#define LANGOPT(Name, Bits, Default, Description)
+#define BENIGN_LANGOPT(Name, Bits, Default, Description) Name = Default;
+#define BENIGN_ENUM_LANGOPT(Name, Type, Bits, Default, Description) \
+ Name = Default;
+#include "clang/Basic/LangOptions.def"
+}
+
diff --git a/contrib/llvm/tools/clang/lib/Basic/SourceLocation.cpp b/contrib/llvm/tools/clang/lib/Basic/SourceLocation.cpp
index 5062d43..6e4f3e6 100644
--- a/contrib/llvm/tools/clang/lib/Basic/SourceLocation.cpp
+++ b/contrib/llvm/tools/clang/lib/Basic/SourceLocation.cpp
@@ -23,7 +23,7 @@ using namespace clang;
// PrettyStackTraceLoc
//===----------------------------------------------------------------------===//
-void PrettyStackTraceLoc::print(llvm::raw_ostream &OS) const {
+void PrettyStackTraceLoc::print(raw_ostream &OS) const {
if (Loc.isValid()) {
Loc.print(OS, SM);
OS << ": ";
@@ -35,7 +35,7 @@ void PrettyStackTraceLoc::print(llvm::raw_ostream &OS) const {
// SourceLocation
//===----------------------------------------------------------------------===//
-void SourceLocation::print(llvm::raw_ostream &OS, const SourceManager &SM)const{
+void SourceLocation::print(raw_ostream &OS, const SourceManager &SM)const{
if (!isValid()) {
OS << "<invalid loc>";
return;
@@ -48,13 +48,13 @@ void SourceLocation::print(llvm::raw_ostream &OS, const SourceManager &SM)const{
OS << "<invalid>";
return;
}
- // The instantiation and spelling pos is identical for file locs.
+ // The macro expansion and spelling pos is identical for file locs.
OS << PLoc.getFilename() << ':' << PLoc.getLine()
<< ':' << PLoc.getColumn();
return;
}
- SM.getInstantiationLoc(*this).print(OS, SM);
+ SM.getExpansionLoc(*this).print(OS, SM);
OS << " <Spelling=";
SM.getSpellingLoc(*this).print(OS, SM);
@@ -75,9 +75,9 @@ FileID FullSourceLoc::getFileID() const {
}
-FullSourceLoc FullSourceLoc::getInstantiationLoc() const {
+FullSourceLoc FullSourceLoc::getExpansionLoc() const {
assert(isValid());
- return FullSourceLoc(SrcMgr->getInstantiationLoc(*this), *SrcMgr);
+ return FullSourceLoc(SrcMgr->getExpansionLoc(*this), *SrcMgr);
}
FullSourceLoc FullSourceLoc::getSpellingLoc() const {
@@ -85,14 +85,14 @@ FullSourceLoc FullSourceLoc::getSpellingLoc() const {
return FullSourceLoc(SrcMgr->getSpellingLoc(*this), *SrcMgr);
}
-unsigned FullSourceLoc::getInstantiationLineNumber(bool *Invalid) const {
+unsigned FullSourceLoc::getExpansionLineNumber(bool *Invalid) const {
assert(isValid());
- return SrcMgr->getInstantiationLineNumber(*this, Invalid);
+ return SrcMgr->getExpansionLineNumber(*this, Invalid);
}
-unsigned FullSourceLoc::getInstantiationColumnNumber(bool *Invalid) const {
+unsigned FullSourceLoc::getExpansionColumnNumber(bool *Invalid) const {
assert(isValid());
- return SrcMgr->getInstantiationColumnNumber(*this, Invalid);
+ return SrcMgr->getExpansionColumnNumber(*this, Invalid);
}
unsigned FullSourceLoc::getSpellingLineNumber(bool *Invalid) const {
@@ -125,7 +125,7 @@ const llvm::MemoryBuffer* FullSourceLoc::getBuffer(bool *Invalid) const {
return SrcMgr->getBuffer(SrcMgr->getFileID(*this), Invalid);
}
-llvm::StringRef FullSourceLoc::getBufferData(bool *Invalid) const {
+StringRef FullSourceLoc::getBufferData(bool *Invalid) const {
return getBuffer(Invalid)->getBuffer();
}
diff --git a/contrib/llvm/tools/clang/lib/Basic/SourceManager.cpp b/contrib/llvm/tools/clang/lib/Basic/SourceManager.cpp
index 45922c1..364663e 100644
--- a/contrib/llvm/tools/clang/lib/Basic/SourceManager.cpp
+++ b/contrib/llvm/tools/clang/lib/Basic/SourceManager.cpp
@@ -17,10 +17,12 @@
#include "clang/Basic/FileManager.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/Path.h"
+#include "llvm/Support/Capacity.h"
#include <algorithm>
#include <string>
#include <cstring>
@@ -39,9 +41,8 @@ ContentCache::~ContentCache() {
delete Buffer.getPointer();
}
-/// getSizeBytesMapped - Returns the number of bytes actually mapped for
-/// this ContentCache. This can be 0 if the MemBuffer was not actually
-/// instantiated.
+/// getSizeBytesMapped - Returns the number of bytes actually mapped for this
+/// ContentCache. This can be 0 if the MemBuffer was not actually expanded.
unsigned ContentCache::getSizeBytesMapped() const {
return Buffer.getPointer() ? Buffer.getPointer()->getBufferSize() : 0;
}
@@ -78,7 +79,7 @@ void ContentCache::replaceBuffer(const llvm::MemoryBuffer *B,
Buffer.setInt(DoNotFree? DoNotFreeFlag : 0);
}
-const llvm::MemoryBuffer *ContentCache::getBuffer(Diagnostic &Diag,
+const llvm::MemoryBuffer *ContentCache::getBuffer(DiagnosticsEngine &Diag,
const SourceManager &SM,
SourceLocation Loc,
bool *Invalid) const {
@@ -105,7 +106,7 @@ const llvm::MemoryBuffer *ContentCache::getBuffer(Diagnostic &Diag,
// that we are in an inconsistent situation and error out as quickly as
// possible.
if (!Buffer.getPointer()) {
- const llvm::StringRef FillStr("<<<MISSING SOURCE FILE>>>\n");
+ const StringRef FillStr("<<<MISSING SOURCE FILE>>>\n");
Buffer.setPointer(MemoryBuffer::getNewMemBuffer(ContentsEntry->getSize(),
"<invalid>"));
char *Ptr = const_cast<char*>(Buffer.getPointer()->getBufferStart());
@@ -143,7 +144,7 @@ const llvm::MemoryBuffer *ContentCache::getBuffer(Diagnostic &Diag,
// If the buffer is valid, check to see if it has a UTF Byte Order Mark
// (BOM). We only support UTF-8 with and without a BOM right now. See
// http://en.wikipedia.org/wiki/Byte_order_mark for more information.
- llvm::StringRef BufStr = Buffer.getPointer()->getBuffer();
+ StringRef BufStr = Buffer.getPointer()->getBuffer();
const char *InvalidBOM = llvm::StringSwitch<const char *>(BufStr)
.StartsWith("\xFE\xFF", "UTF-16 (BE)")
.StartsWith("\xFF\xFE", "UTF-16 (LE)")
@@ -169,7 +170,7 @@ const llvm::MemoryBuffer *ContentCache::getBuffer(Diagnostic &Diag,
return Buffer.getPointer();
}
-unsigned LineTableInfo::getLineTableFilenameID(llvm::StringRef Name) {
+unsigned LineTableInfo::getLineTableFilenameID(StringRef Name) {
// Look up the filename in the string table, returning the pre-existing value
// if it exists.
llvm::StringMapEntry<unsigned> &Entry =
@@ -186,7 +187,7 @@ unsigned LineTableInfo::getLineTableFilenameID(llvm::StringRef Name) {
/// AddLineNote - Add a line note to the line table that indicates that there
/// is a #line at the specified FID/Offset location which changes the presumed
/// location to LineNo/FilenameID.
-void LineTableInfo::AddLineNote(unsigned FID, unsigned Offset,
+void LineTableInfo::AddLineNote(int FID, unsigned Offset,
unsigned LineNo, int FilenameID) {
std::vector<LineEntry> &Entries = LineEntries[FID];
@@ -217,7 +218,7 @@ void LineTableInfo::AddLineNote(unsigned FID, unsigned Offset,
/// presumed #include stack. If it is 1, this is a file entry, if it is 2 then
/// this is a file exit. FileKind specifies whether this is a system header or
/// extern C system header.
-void LineTableInfo::AddLineNote(unsigned FID, unsigned Offset,
+void LineTableInfo::AddLineNote(int FID, unsigned Offset,
unsigned LineNo, int FilenameID,
unsigned EntryExit,
SrcMgr::CharacteristicKind FileKind) {
@@ -251,7 +252,7 @@ void LineTableInfo::AddLineNote(unsigned FID, unsigned Offset,
/// FindNearestLineEntry - Find the line entry nearest to FID that is before
/// it. If there is no line entry before Offset in FID, return null.
-const LineEntry *LineTableInfo::FindNearestLineEntry(unsigned FID,
+const LineEntry *LineTableInfo::FindNearestLineEntry(int FID,
unsigned Offset) {
const std::vector<LineEntry> &Entries = LineEntries[FID];
assert(!Entries.empty() && "No #line entries for this FID after all!");
@@ -270,14 +271,14 @@ const LineEntry *LineTableInfo::FindNearestLineEntry(unsigned FID,
/// \brief Add a new line entry that has already been encoded into
/// the internal representation of the line table.
-void LineTableInfo::AddEntry(unsigned FID,
+void LineTableInfo::AddEntry(int FID,
const std::vector<LineEntry> &Entries) {
LineEntries[FID] = Entries;
}
/// getLineTableFilenameID - Return the uniqued ID for the specified filename.
///
-unsigned SourceManager::getLineTableFilenameID(llvm::StringRef Name) {
+unsigned SourceManager::getLineTableFilenameID(StringRef Name) {
if (LineTable == 0)
LineTable = new LineTableInfo();
return LineTable->getLineTableFilenameID(Name);
@@ -289,7 +290,7 @@ unsigned SourceManager::getLineTableFilenameID(llvm::StringRef Name) {
/// unspecified.
void SourceManager::AddLineNote(SourceLocation Loc, unsigned LineNo,
int FilenameID) {
- std::pair<FileID, unsigned> LocInfo = getDecomposedInstantiationLoc(Loc);
+ std::pair<FileID, unsigned> LocInfo = getDecomposedExpansionLoc(Loc);
bool Invalid = false;
const SLocEntry &Entry = getSLocEntry(LocInfo.first, &Invalid);
@@ -319,7 +320,7 @@ void SourceManager::AddLineNote(SourceLocation Loc, unsigned LineNo,
return AddLineNote(Loc, LineNo, FilenameID);
}
- std::pair<FileID, unsigned> LocInfo = getDecomposedInstantiationLoc(Loc);
+ std::pair<FileID, unsigned> LocInfo = getDecomposedExpansionLoc(Loc);
bool Invalid = false;
const SLocEntry &Entry = getSLocEntry(LocInfo.first, &Invalid);
@@ -362,7 +363,7 @@ LineTableInfo &SourceManager::getLineTable() {
// Private 'Create' methods.
//===----------------------------------------------------------------------===//
-SourceManager::SourceManager(Diagnostic &Diag, FileManager &FileMgr)
+SourceManager::SourceManager(DiagnosticsEngine &Diag, FileManager &FileMgr)
: Diag(Diag), FileMgr(FileMgr), OverridenFilesKeepOriginalName(true),
ExternalSLocEntries(0), LineTable(0), NumLinearScans(0),
NumBinaryProbes(0), FakeBufferForRecovery(0) {
@@ -387,11 +388,18 @@ SourceManager::~SourceManager() {
}
delete FakeBufferForRecovery;
+
+ for (llvm::DenseMap<FileID, MacroArgsMap *>::iterator
+ I = MacroArgsCacheMap.begin(),E = MacroArgsCacheMap.end(); I!=E; ++I) {
+ delete I->second;
+ }
}
void SourceManager::clearIDTables() {
MainFileID = FileID();
- SLocEntryTable.clear();
+ LocalSLocEntryTable.clear();
+ LoadedSLocEntryTable.clear();
+ SLocEntryLoaded.clear();
LastLineNoFileIDQuery = FileID();
LastLineNoContentCache = 0;
LastFileIDLookup = FileID();
@@ -399,9 +407,10 @@ void SourceManager::clearIDTables() {
if (LineTable)
LineTable->clear();
- // Use up FileID #0 as an invalid instantiation.
- NextOffset = 0;
- createInstantiationLoc(SourceLocation(),SourceLocation(),SourceLocation(), 1);
+ // Use up FileID #0 as an invalid expansion.
+ NextLocalOffset = 0;
+ CurrentLoadedOffset = MaxLoadedOffset;
+ createExpansionLoc(SourceLocation(),SourceLocation(),SourceLocation(), 1);
}
/// getOrCreateContentCache - Create or return a cached ContentCache for the
@@ -452,33 +461,16 @@ SourceManager::createMemBufferContentCache(const MemoryBuffer *Buffer) {
return Entry;
}
-void SourceManager::PreallocateSLocEntries(ExternalSLocEntrySource *Source,
- unsigned NumSLocEntries,
- unsigned NextOffset) {
- ExternalSLocEntries = Source;
- this->NextOffset = NextOffset;
- unsigned CurPrealloc = SLocEntryLoaded.size();
- // If we've ever preallocated, we must not count the dummy entry.
- if (CurPrealloc) --CurPrealloc;
- SLocEntryLoaded.resize(NumSLocEntries + 1);
- SLocEntryLoaded[0] = true;
- SLocEntryTable.resize(SLocEntryTable.size() + NumSLocEntries - CurPrealloc);
-}
-
-void SourceManager::ClearPreallocatedSLocEntries() {
- unsigned I = 0;
- for (unsigned N = SLocEntryLoaded.size(); I != N; ++I)
- if (!SLocEntryLoaded[I])
- break;
-
- // We've already loaded all preallocated source location entries.
- if (I == SLocEntryLoaded.size())
- return;
-
- // Remove everything from location I onward.
- SLocEntryTable.resize(I);
- SLocEntryLoaded.clear();
- ExternalSLocEntries = 0;
+std::pair<int, unsigned>
+SourceManager::AllocateLoadedSLocEntries(unsigned NumSLocEntries,
+ unsigned TotalSize) {
+ assert(ExternalSLocEntries && "Don't have an external sloc source");
+ LoadedSLocEntryTable.resize(LoadedSLocEntryTable.size() + NumSLocEntries);
+ SLocEntryLoaded.resize(LoadedSLocEntryTable.size());
+ CurrentLoadedOffset -= TotalSize;
+ assert(CurrentLoadedOffset >= NextLocalOffset && "Out of source locations");
+ int ID = LoadedSLocEntryTable.size();
+ return std::make_pair(-ID - 1, CurrentLoadedOffset);
}
/// \brief As part of recovering from missing or changed content, produce a
@@ -492,7 +484,7 @@ const llvm::MemoryBuffer *SourceManager::getFakeBufferForRecovery() const {
}
//===----------------------------------------------------------------------===//
-// Methods to create new FileID's and instantiations.
+// Methods to create new FileID's and macro expansions.
//===----------------------------------------------------------------------===//
/// createFileID - Create a new FileID for the specified ContentCache and
@@ -501,77 +493,76 @@ const llvm::MemoryBuffer *SourceManager::getFakeBufferForRecovery() const {
FileID SourceManager::createFileID(const ContentCache *File,
SourceLocation IncludePos,
SrcMgr::CharacteristicKind FileCharacter,
- unsigned PreallocatedID,
- unsigned Offset) {
- if (PreallocatedID) {
- // If we're filling in a preallocated ID, just load in the file
- // entry and return.
- assert(PreallocatedID < SLocEntryLoaded.size() &&
- "Preallocate ID out-of-range");
- assert(!SLocEntryLoaded[PreallocatedID] &&
- "Source location entry already loaded");
- assert(Offset && "Preallocate source location cannot have zero offset");
- SLocEntryTable[PreallocatedID]
- = SLocEntry::get(Offset, FileInfo::get(IncludePos, File, FileCharacter));
- SLocEntryLoaded[PreallocatedID] = true;
- FileID FID = FileID::get(PreallocatedID);
- return FID;
+ int LoadedID, unsigned LoadedOffset) {
+ if (LoadedID < 0) {
+ assert(LoadedID != -1 && "Loading sentinel FileID");
+ unsigned Index = unsigned(-LoadedID) - 2;
+ assert(Index < LoadedSLocEntryTable.size() && "FileID out of range");
+ assert(!SLocEntryLoaded[Index] && "FileID already loaded");
+ LoadedSLocEntryTable[Index] = SLocEntry::get(LoadedOffset,
+ FileInfo::get(IncludePos, File, FileCharacter));
+ SLocEntryLoaded[Index] = true;
+ return FileID::get(LoadedID);
}
-
- SLocEntryTable.push_back(SLocEntry::get(NextOffset,
- FileInfo::get(IncludePos, File,
- FileCharacter)));
+ LocalSLocEntryTable.push_back(SLocEntry::get(NextLocalOffset,
+ FileInfo::get(IncludePos, File,
+ FileCharacter)));
unsigned FileSize = File->getSize();
- assert(NextOffset+FileSize+1 > NextOffset && "Ran out of source locations!");
- NextOffset += FileSize+1;
+ assert(NextLocalOffset + FileSize + 1 > NextLocalOffset &&
+ NextLocalOffset + FileSize + 1 <= CurrentLoadedOffset &&
+ "Ran out of source locations!");
+ // We do a +1 here because we want a SourceLocation that means "the end of the
+ // file", e.g. for the "no newline at the end of the file" diagnostic.
+ NextLocalOffset += FileSize + 1;
// Set LastFileIDLookup to the newly created file. The next getFileID call is
// almost guaranteed to be from that file.
- FileID FID = FileID::get(SLocEntryTable.size()-1);
+ FileID FID = FileID::get(LocalSLocEntryTable.size()-1);
return LastFileIDLookup = FID;
}
SourceLocation
-SourceManager::createMacroArgInstantiationLoc(SourceLocation SpellingLoc,
- SourceLocation ILoc,
- unsigned TokLength) {
- InstantiationInfo II =
- InstantiationInfo::createForMacroArg(SpellingLoc, ILoc);
- return createInstantiationLocImpl(II, TokLength);
-}
-
-SourceLocation SourceManager::createInstantiationLoc(SourceLocation SpellingLoc,
- SourceLocation ILocStart,
- SourceLocation ILocEnd,
- unsigned TokLength,
- unsigned PreallocatedID,
- unsigned Offset) {
- InstantiationInfo II =
- InstantiationInfo::create(SpellingLoc, ILocStart, ILocEnd);
- return createInstantiationLocImpl(II, TokLength, PreallocatedID, Offset);
+SourceManager::createMacroArgExpansionLoc(SourceLocation SpellingLoc,
+ SourceLocation ExpansionLoc,
+ unsigned TokLength) {
+ ExpansionInfo Info = ExpansionInfo::createForMacroArg(SpellingLoc,
+ ExpansionLoc);
+ return createExpansionLocImpl(Info, TokLength);
}
SourceLocation
-SourceManager::createInstantiationLocImpl(const InstantiationInfo &II,
- unsigned TokLength,
- unsigned PreallocatedID,
- unsigned Offset) {
- if (PreallocatedID) {
- // If we're filling in a preallocated ID, just load in the
- // instantiation entry and return.
- assert(PreallocatedID < SLocEntryLoaded.size() &&
- "Preallocate ID out-of-range");
- assert(!SLocEntryLoaded[PreallocatedID] &&
- "Source location entry already loaded");
- assert(Offset && "Preallocate source location cannot have zero offset");
- SLocEntryTable[PreallocatedID] = SLocEntry::get(Offset, II);
- SLocEntryLoaded[PreallocatedID] = true;
- return SourceLocation::getMacroLoc(Offset);
+SourceManager::createExpansionLoc(SourceLocation SpellingLoc,
+ SourceLocation ExpansionLocStart,
+ SourceLocation ExpansionLocEnd,
+ unsigned TokLength,
+ int LoadedID,
+ unsigned LoadedOffset) {
+ ExpansionInfo Info = ExpansionInfo::create(SpellingLoc, ExpansionLocStart,
+ ExpansionLocEnd);
+ return createExpansionLocImpl(Info, TokLength, LoadedID, LoadedOffset);
+}
+
+SourceLocation
+SourceManager::createExpansionLocImpl(const ExpansionInfo &Info,
+ unsigned TokLength,
+ int LoadedID,
+ unsigned LoadedOffset) {
+ if (LoadedID < 0) {
+ assert(LoadedID != -1 && "Loading sentinel FileID");
+ unsigned Index = unsigned(-LoadedID) - 2;
+ assert(Index < LoadedSLocEntryTable.size() && "FileID out of range");
+ assert(!SLocEntryLoaded[Index] && "FileID already loaded");
+ LoadedSLocEntryTable[Index] = SLocEntry::get(LoadedOffset, Info);
+ SLocEntryLoaded[Index] = true;
+ return SourceLocation::getMacroLoc(LoadedOffset);
}
- SLocEntryTable.push_back(SLocEntry::get(NextOffset, II));
- assert(NextOffset+TokLength+1 > NextOffset && "Ran out of source locations!");
- NextOffset += TokLength+1;
- return SourceLocation::getMacroLoc(NextOffset-(TokLength+1));
+ LocalSLocEntryTable.push_back(SLocEntry::get(NextLocalOffset, Info));
+ assert(NextLocalOffset + TokLength + 1 > NextLocalOffset &&
+ NextLocalOffset + TokLength + 1 <= CurrentLoadedOffset &&
+ "Ran out of source locations!");
+ // See createFileID for that +1.
+ NextLocalOffset += TokLength + 1;
+ return SourceLocation::getMacroLoc(NextLocalOffset - (TokLength + 1));
}
const llvm::MemoryBuffer *
@@ -602,9 +593,9 @@ void SourceManager::overrideFileContents(const FileEntry *SourceFile,
OverriddenFiles[SourceFile] = NewFile;
}
-llvm::StringRef SourceManager::getBufferData(FileID FID, bool *Invalid) const {
+StringRef SourceManager::getBufferData(FileID FID, bool *Invalid) const {
bool MyInvalid = false;
- const SLocEntry &SLoc = getSLocEntry(FID.ID, &MyInvalid);
+ const SLocEntry &SLoc = getSLocEntry(FID, &MyInvalid);
if (!SLoc.isFile() || MyInvalid) {
if (Invalid)
*Invalid = true;
@@ -627,18 +618,32 @@ llvm::StringRef SourceManager::getBufferData(FileID FID, bool *Invalid) const {
// SourceLocation manipulation methods.
//===----------------------------------------------------------------------===//
-/// getFileIDSlow - Return the FileID for a SourceLocation. This is a very hot
-/// method that is used for all SourceManager queries that start with a
-/// SourceLocation object. It is responsible for finding the entry in
-/// SLocEntryTable which contains the specified location.
+/// \brief Return the FileID for a SourceLocation.
///
+/// This is the cache-miss path of getFileID. Not as hot as that function, but
+/// still very important. It is responsible for finding the entry in the
+/// SLocEntry tables that contains the specified location.
FileID SourceManager::getFileIDSlow(unsigned SLocOffset) const {
if (!SLocOffset)
return FileID::get(0);
+ // Now it is time to search for the correct file. See where the SLocOffset
+ // sits in the global view and consult local or loaded buffers for it.
+ if (SLocOffset < NextLocalOffset)
+ return getFileIDLocal(SLocOffset);
+ return getFileIDLoaded(SLocOffset);
+}
+
+/// \brief Return the FileID for a SourceLocation with a low offset.
+///
+/// This function knows that the SourceLocation is in a local buffer, not a
+/// loaded one.
+FileID SourceManager::getFileIDLocal(unsigned SLocOffset) const {
+ assert(SLocOffset < NextLocalOffset && "Bad function choice");
+
// After the first and second level caches, I see two common sorts of
- // behavior: 1) a lot of searched FileID's are "near" the cached file location
- // or are "near" the cached instantiation location. 2) others are just
+ // behavior: 1) a lot of searched FileID's are "near" the cached file
+ // location or are "near" the cached expansion location. 2) others are just
// completely random and may be a very long way away.
//
// To handle this, we do a linear search for up to 8 steps to catch #1 quickly
@@ -649,12 +654,13 @@ FileID SourceManager::getFileIDSlow(unsigned SLocOffset) const {
// most newly created FileID.
std::vector<SrcMgr::SLocEntry>::const_iterator I;
- if (SLocEntryTable[LastFileIDLookup.ID].getOffset() < SLocOffset) {
+ if (LastFileIDLookup.ID < 0 ||
+ LocalSLocEntryTable[LastFileIDLookup.ID].getOffset() < SLocOffset) {
// Neither loc prunes our search.
- I = SLocEntryTable.end();
+ I = LocalSLocEntryTable.end();
} else {
// Perhaps it is near the file point.
- I = SLocEntryTable.begin()+LastFileIDLookup.ID;
+ I = LocalSLocEntryTable.begin()+LastFileIDLookup.ID;
}
// Find the FileID that contains this. "I" is an iterator that points to a
@@ -662,25 +668,12 @@ FileID SourceManager::getFileIDSlow(unsigned SLocOffset) const {
unsigned NumProbes = 0;
while (1) {
--I;
- if (ExternalSLocEntries) {
- bool Invalid = false;
- getSLocEntry(FileID::get(I - SLocEntryTable.begin()), &Invalid);
- if (Invalid)
- return FileID::get(0);
- }
-
if (I->getOffset() <= SLocOffset) {
-#if 0
- printf("lin %d -> %d [%s] %d %d\n", SLocOffset,
- I-SLocEntryTable.begin(),
- I->isInstantiation() ? "inst" : "file",
- LastFileIDLookup.ID, int(SLocEntryTable.end()-I));
-#endif
- FileID Res = FileID::get(I-SLocEntryTable.begin());
-
- // If this isn't an instantiation, remember it. We have good locality
- // across FileID lookups.
- if (!I->isInstantiation())
+ FileID Res = FileID::get(int(I - LocalSLocEntryTable.begin()));
+
+ // If this isn't an expansion, remember it. We have good locality across
+ // FileID lookups.
+ if (!I->isExpansion())
LastFileIDLookup = Res;
NumLinearScans += NumProbes+1;
return Res;
@@ -691,7 +684,7 @@ FileID SourceManager::getFileIDSlow(unsigned SLocOffset) const {
// Convert "I" back into an index. We know that it is an entry whose index is
// larger than the offset we are looking for.
- unsigned GreaterIndex = I-SLocEntryTable.begin();
+ unsigned GreaterIndex = I - LocalSLocEntryTable.begin();
// LessIndex - This is the lower bound of the range that we're searching.
// We know that the offset corresponding to the FileID is is less than
// SLocOffset.
@@ -700,8 +693,7 @@ FileID SourceManager::getFileIDSlow(unsigned SLocOffset) const {
while (1) {
bool Invalid = false;
unsigned MiddleIndex = (GreaterIndex-LessIndex)/2+LessIndex;
- unsigned MidOffset = getSLocEntry(FileID::get(MiddleIndex), &Invalid)
- .getOffset();
+ unsigned MidOffset = getLocalSLocEntry(MiddleIndex, &Invalid).getOffset();
if (Invalid)
return FileID::get(0);
@@ -715,18 +707,14 @@ FileID SourceManager::getFileIDSlow(unsigned SLocOffset) const {
}
// If the middle index contains the value, succeed and return.
+ // FIXME: This could be made faster by using a function that's aware of
+ // being in the local area.
if (isOffsetInFileID(FileID::get(MiddleIndex), SLocOffset)) {
-#if 0
- printf("bin %d -> %d [%s] %d %d\n", SLocOffset,
- I-SLocEntryTable.begin(),
- I->isInstantiation() ? "inst" : "file",
- LastFileIDLookup.ID, int(SLocEntryTable.end()-I));
-#endif
FileID Res = FileID::get(MiddleIndex);
- // If this isn't an instantiation, remember it. We have good locality
+ // If this isn't a macro expansion, remember it. We have good locality
// across FileID lookups.
- if (!I->isInstantiation())
+ if (!LocalSLocEntryTable[MiddleIndex].isExpansion())
LastFileIDLookup = Res;
NumBinaryProbes += NumProbes;
return Res;
@@ -737,17 +725,82 @@ FileID SourceManager::getFileIDSlow(unsigned SLocOffset) const {
}
}
+/// \brief Return the FileID for a SourceLocation with a high offset.
+///
+/// This function knows that the SourceLocation is in a loaded buffer, not a
+/// local one.
+FileID SourceManager::getFileIDLoaded(unsigned SLocOffset) const {
+ assert(SLocOffset >= CurrentLoadedOffset && "Bad function choice");
+
+ // Sanity checking, otherwise a bug may lead to hanging in release build.
+ if (SLocOffset < CurrentLoadedOffset)
+ return FileID();
+
+ // Essentially the same as the local case, but the loaded array is sorted
+ // in the other direction.
+
+ // First do a linear scan from the last lookup position, if possible.
+ unsigned I;
+ int LastID = LastFileIDLookup.ID;
+ if (LastID >= 0 || getLoadedSLocEntryByID(LastID).getOffset() < SLocOffset)
+ I = 0;
+ else
+ I = (-LastID - 2) + 1;
+
+ unsigned NumProbes;
+ for (NumProbes = 0; NumProbes < 8; ++NumProbes, ++I) {
+ // Make sure the entry is loaded!
+ const SrcMgr::SLocEntry &E = getLoadedSLocEntry(I);
+ if (E.getOffset() <= SLocOffset) {
+ FileID Res = FileID::get(-int(I) - 2);
+
+ if (!E.isExpansion())
+ LastFileIDLookup = Res;
+ NumLinearScans += NumProbes + 1;
+ return Res;
+ }
+ }
+
+ // Linear scan failed. Do the binary search. Note the reverse sorting of the
+ // table: GreaterIndex is the one where the offset is greater, which is
+ // actually a lower index!
+ unsigned GreaterIndex = I;
+ unsigned LessIndex = LoadedSLocEntryTable.size();
+ NumProbes = 0;
+ while (1) {
+ ++NumProbes;
+ unsigned MiddleIndex = (LessIndex - GreaterIndex) / 2 + GreaterIndex;
+ const SrcMgr::SLocEntry &E = getLoadedSLocEntry(MiddleIndex);
+
+ ++NumProbes;
+
+ if (E.getOffset() > SLocOffset) {
+ GreaterIndex = MiddleIndex;
+ continue;
+ }
+
+ if (isOffsetInFileID(FileID::get(-int(MiddleIndex) - 2), SLocOffset)) {
+ FileID Res = FileID::get(-int(MiddleIndex) - 2);
+ if (!E.isExpansion())
+ LastFileIDLookup = Res;
+ NumBinaryProbes += NumProbes;
+ return Res;
+ }
+
+ LessIndex = MiddleIndex;
+ }
+}
+
SourceLocation SourceManager::
-getInstantiationLocSlowCase(SourceLocation Loc) const {
+getExpansionLocSlowCase(SourceLocation Loc) const {
do {
// Note: If Loc indicates an offset into a token that came from a macro
// expansion (e.g. the 5th character of the token) we do not want to add
- // this offset when going to the instantiation location. The instatiation
+ // this offset when going to the expansion location. The expansion
// location is the macro invocation, which the offset has nothing to do
// with. This is unlike when we get the spelling loc, because the offset
// directly correspond to the token whose spelling we're inspecting.
- Loc = getSLocEntry(getFileID(Loc)).getInstantiation()
- .getInstantiationLocStart();
+ Loc = getSLocEntry(getFileID(Loc)).getExpansion().getExpansionLocStart();
} while (!Loc.isFileID());
return Loc;
@@ -756,23 +809,32 @@ getInstantiationLocSlowCase(SourceLocation Loc) const {
SourceLocation SourceManager::getSpellingLocSlowCase(SourceLocation Loc) const {
do {
std::pair<FileID, unsigned> LocInfo = getDecomposedLoc(Loc);
- Loc = getSLocEntry(LocInfo.first).getInstantiation().getSpellingLoc();
- Loc = Loc.getFileLocWithOffset(LocInfo.second);
+ Loc = getSLocEntry(LocInfo.first).getExpansion().getSpellingLoc();
+ Loc = Loc.getLocWithOffset(LocInfo.second);
+ } while (!Loc.isFileID());
+ return Loc;
+}
+
+SourceLocation SourceManager::getFileLocSlowCase(SourceLocation Loc) const {
+ do {
+ if (isMacroArgExpansion(Loc))
+ Loc = getImmediateSpellingLoc(Loc);
+ else
+ Loc = getImmediateExpansionRange(Loc).first;
} while (!Loc.isFileID());
return Loc;
}
std::pair<FileID, unsigned>
-SourceManager::getDecomposedInstantiationLocSlowCase(
+SourceManager::getDecomposedExpansionLocSlowCase(
const SrcMgr::SLocEntry *E) const {
- // If this is an instantiation record, walk through all the instantiation
- // points.
+ // If this is an expansion record, walk through all the expansion points.
FileID FID;
SourceLocation Loc;
unsigned Offset;
do {
- Loc = E->getInstantiation().getInstantiationLocStart();
+ Loc = E->getExpansion().getExpansionLocStart();
FID = getFileID(Loc);
E = &getSLocEntry(FID);
@@ -785,16 +847,16 @@ SourceManager::getDecomposedInstantiationLocSlowCase(
std::pair<FileID, unsigned>
SourceManager::getDecomposedSpellingLocSlowCase(const SrcMgr::SLocEntry *E,
unsigned Offset) const {
- // If this is an instantiation record, walk through all the instantiation
- // points.
+ // If this is an expansion record, walk through all the expansion points.
FileID FID;
SourceLocation Loc;
do {
- Loc = E->getInstantiation().getSpellingLoc();
+ Loc = E->getExpansion().getSpellingLoc();
+ Loc = Loc.getLocWithOffset(Offset);
FID = getFileID(Loc);
E = &getSLocEntry(FID);
- Offset += Loc.getOffset()-E->getOffset();
+ Offset = Loc.getOffset()-E->getOffset();
} while (!Loc.isFileID());
return std::make_pair(FID, Offset);
@@ -807,45 +869,45 @@ SourceManager::getDecomposedSpellingLocSlowCase(const SrcMgr::SLocEntry *E,
SourceLocation SourceManager::getImmediateSpellingLoc(SourceLocation Loc) const{
if (Loc.isFileID()) return Loc;
std::pair<FileID, unsigned> LocInfo = getDecomposedLoc(Loc);
- Loc = getSLocEntry(LocInfo.first).getInstantiation().getSpellingLoc();
- return Loc.getFileLocWithOffset(LocInfo.second);
+ Loc = getSLocEntry(LocInfo.first).getExpansion().getSpellingLoc();
+ return Loc.getLocWithOffset(LocInfo.second);
}
-/// getImmediateInstantiationRange - Loc is required to be an instantiation
-/// location. Return the start/end of the instantiation information.
+/// getImmediateExpansionRange - Loc is required to be an expansion location.
+/// Return the start/end of the expansion information.
std::pair<SourceLocation,SourceLocation>
-SourceManager::getImmediateInstantiationRange(SourceLocation Loc) const {
- assert(Loc.isMacroID() && "Not an instantiation loc!");
- const InstantiationInfo &II = getSLocEntry(getFileID(Loc)).getInstantiation();
- return II.getInstantiationLocRange();
+SourceManager::getImmediateExpansionRange(SourceLocation Loc) const {
+ assert(Loc.isMacroID() && "Not a macro expansion loc!");
+ const ExpansionInfo &Expansion = getSLocEntry(getFileID(Loc)).getExpansion();
+ return Expansion.getExpansionLocRange();
}
-/// getInstantiationRange - Given a SourceLocation object, return the
-/// range of tokens covered by the instantiation in the ultimate file.
+/// getExpansionRange - Given a SourceLocation object, return the range of
+/// tokens covered by the expansion in the ultimate file.
std::pair<SourceLocation,SourceLocation>
-SourceManager::getInstantiationRange(SourceLocation Loc) const {
+SourceManager::getExpansionRange(SourceLocation Loc) const {
if (Loc.isFileID()) return std::make_pair(Loc, Loc);
std::pair<SourceLocation,SourceLocation> Res =
- getImmediateInstantiationRange(Loc);
+ getImmediateExpansionRange(Loc);
- // Fully resolve the start and end locations to their ultimate instantiation
+ // Fully resolve the start and end locations to their ultimate expansion
// points.
while (!Res.first.isFileID())
- Res.first = getImmediateInstantiationRange(Res.first).first;
+ Res.first = getImmediateExpansionRange(Res.first).first;
while (!Res.second.isFileID())
- Res.second = getImmediateInstantiationRange(Res.second).second;
+ Res.second = getImmediateExpansionRange(Res.second).second;
return Res;
}
-bool SourceManager::isMacroArgInstantiation(SourceLocation Loc) const {
+bool SourceManager::isMacroArgExpansion(SourceLocation Loc) const {
if (!Loc.isMacroID()) return false;
FileID FID = getFileID(Loc);
const SrcMgr::SLocEntry *E = &getSLocEntry(FID);
- const SrcMgr::InstantiationInfo &II = E->getInstantiation();
- return II.isMacroArgInstantiation();
+ const SrcMgr::ExpansionInfo &Expansion = E->getExpansion();
+ return Expansion.isMacroArgExpansion();
}
@@ -913,10 +975,10 @@ unsigned SourceManager::getSpellingColumnNumber(SourceLocation Loc,
return getColumnNumber(LocInfo.first, LocInfo.second, Invalid);
}
-unsigned SourceManager::getInstantiationColumnNumber(SourceLocation Loc,
- bool *Invalid) const {
+unsigned SourceManager::getExpansionColumnNumber(SourceLocation Loc,
+ bool *Invalid) const {
if (isInvalid(Loc, Invalid)) return 0;
- std::pair<FileID, unsigned> LocInfo = getDecomposedInstantiationLoc(Loc);
+ std::pair<FileID, unsigned> LocInfo = getDecomposedExpansionLoc(Loc);
return getColumnNumber(LocInfo.first, LocInfo.second, Invalid);
}
@@ -927,10 +989,10 @@ unsigned SourceManager::getPresumedColumnNumber(SourceLocation Loc,
}
static LLVM_ATTRIBUTE_NOINLINE void
-ComputeLineNumbers(Diagnostic &Diag, ContentCache *FI,
+ComputeLineNumbers(DiagnosticsEngine &Diag, ContentCache *FI,
llvm::BumpPtrAllocator &Alloc,
const SourceManager &SM, bool &Invalid);
-static void ComputeLineNumbers(Diagnostic &Diag, ContentCache *FI,
+static void ComputeLineNumbers(DiagnosticsEngine &Diag, ContentCache *FI,
llvm::BumpPtrAllocator &Alloc,
const SourceManager &SM, bool &Invalid) {
// Note that calling 'getBuffer()' may lazily page in the file.
@@ -941,7 +1003,7 @@ static void ComputeLineNumbers(Diagnostic &Diag, ContentCache *FI,
// Find the file offsets of all of the *physical* source lines. This does
// not look at trigraphs, escaped newlines, or anything else tricky.
- llvm::SmallVector<unsigned, 256> LineOffsets;
+ SmallVector<unsigned, 256> LineOffsets;
// Line #1 starts at char 0.
LineOffsets.push_back(0);
@@ -1108,10 +1170,10 @@ unsigned SourceManager::getSpellingLineNumber(SourceLocation Loc,
std::pair<FileID, unsigned> LocInfo = getDecomposedSpellingLoc(Loc);
return getLineNumber(LocInfo.first, LocInfo.second);
}
-unsigned SourceManager::getInstantiationLineNumber(SourceLocation Loc,
- bool *Invalid) const {
+unsigned SourceManager::getExpansionLineNumber(SourceLocation Loc,
+ bool *Invalid) const {
if (isInvalid(Loc, Invalid)) return 0;
- std::pair<FileID, unsigned> LocInfo = getDecomposedInstantiationLoc(Loc);
+ std::pair<FileID, unsigned> LocInfo = getDecomposedExpansionLoc(Loc);
return getLineNumber(LocInfo.first, LocInfo.second);
}
unsigned SourceManager::getPresumedLineNumber(SourceLocation Loc,
@@ -1131,7 +1193,7 @@ unsigned SourceManager::getPresumedLineNumber(SourceLocation Loc,
SrcMgr::CharacteristicKind
SourceManager::getFileCharacteristic(SourceLocation Loc) const {
assert(!Loc.isInvalid() && "Can't get file characteristic of invalid loc!");
- std::pair<FileID, unsigned> LocInfo = getDecomposedInstantiationLoc(Loc);
+ std::pair<FileID, unsigned> LocInfo = getDecomposedExpansionLoc(Loc);
bool Invalid = false;
const SLocEntry &SEntry = getSLocEntry(LocInfo.first, &Invalid);
if (Invalid || !SEntry.isFile())
@@ -1172,13 +1234,13 @@ const char *SourceManager::getBufferName(SourceLocation Loc,
/// or GNU line marker directives. This provides a view on the data that a
/// user should see in diagnostics, for example.
///
-/// Note that a presumed location is always given as the instantiation point
-/// of an instantiation location, not at the spelling location.
+/// Note that a presumed location is always given as the expansion point of an
+/// expansion location, not at the spelling location.
PresumedLoc SourceManager::getPresumedLoc(SourceLocation Loc) const {
if (Loc.isInvalid()) return PresumedLoc();
- // Presumed locations are always for instantiation points.
- std::pair<FileID, unsigned> LocInfo = getDecomposedInstantiationLoc(Loc);
+ // Presumed locations are always for expansion points.
+ std::pair<FileID, unsigned> LocInfo = getDecomposedExpansionLoc(Loc);
bool Invalid = false;
const SLocEntry &Entry = getSLocEntry(LocInfo.first, &Invalid);
@@ -1229,7 +1291,7 @@ PresumedLoc SourceManager::getPresumedLoc(SourceLocation Loc) const {
// Handle virtual #include manipulation.
if (Entry->IncludeOffset) {
IncludeLoc = getLocForStartOfFile(LocInfo.first);
- IncludeLoc = IncludeLoc.getFileLocWithOffset(Entry->IncludeOffset);
+ IncludeLoc = IncludeLoc.getLocWithOffset(Entry->IncludeOffset);
}
}
}
@@ -1237,6 +1299,25 @@ PresumedLoc SourceManager::getPresumedLoc(SourceLocation Loc) const {
return PresumedLoc(Filename, LineNo, ColNo, IncludeLoc);
}
+/// \brief The size of the SLocEnty that \arg FID represents.
+unsigned SourceManager::getFileIDSize(FileID FID) const {
+ bool Invalid = false;
+ const SrcMgr::SLocEntry &Entry = getSLocEntry(FID, &Invalid);
+ if (Invalid)
+ return 0;
+
+ int ID = FID.ID;
+ unsigned NextOffset;
+ if ((ID > 0 && unsigned(ID+1) == local_sloc_entry_size()))
+ NextOffset = getNextLocalOffset();
+ else if (ID+1 == -1)
+ NextOffset = MaxLoadedOffset;
+ else
+ NextOffset = getSLocEntry(FileID::get(ID+1)).getOffset();
+
+ return NextOffset - Entry.getOffset() - 1;
+}
+
//===----------------------------------------------------------------------===//
// Other miscellaneous methods.
//===----------------------------------------------------------------------===//
@@ -1259,24 +1340,36 @@ static llvm::Optional<ino_t> getActualFileInode(const FileEntry *File) {
/// \brief Get the source location for the given file:line:col triplet.
///
/// If the source file is included multiple times, the source location will
-/// be based upon the first inclusion.
-SourceLocation SourceManager::getLocation(const FileEntry *SourceFile,
- unsigned Line, unsigned Col) {
+/// be based upon an arbitrary inclusion.
+SourceLocation SourceManager::translateFileLineCol(const FileEntry *SourceFile,
+ unsigned Line,
+ unsigned Col) const {
assert(SourceFile && "Null source file!");
assert(Line && Col && "Line and column should start from 1!");
+ FileID FirstFID = translateFile(SourceFile);
+ return translateLineCol(FirstFID, Line, Col);
+}
+
+/// \brief Get the FileID for the given file.
+///
+/// If the source file is included multiple times, the FileID will be the
+/// first inclusion.
+FileID SourceManager::translateFile(const FileEntry *SourceFile) const {
+ assert(SourceFile && "Null source file!");
+
// Find the first file ID that corresponds to the given file.
FileID FirstFID;
// First, check the main file ID, since it is common to look for a
// location in the main file.
llvm::Optional<ino_t> SourceFileInode;
- llvm::Optional<llvm::StringRef> SourceFileName;
+ llvm::Optional<StringRef> SourceFileName;
if (!MainFileID.isInvalid()) {
bool Invalid = false;
const SLocEntry &MainSLoc = getSLocEntry(MainFileID, &Invalid);
if (Invalid)
- return SourceLocation();
+ return FileID();
if (MainSLoc.isFile()) {
const ContentCache *MainContentCache
@@ -1308,12 +1401,12 @@ SourceLocation SourceManager::getLocation(const FileEntry *SourceFile,
if (FirstFID.isInvalid()) {
// The location we're looking for isn't in the main file; look
- // through all of the source locations.
- for (unsigned I = 0, N = sloc_entry_size(); I != N; ++I) {
+ // through all of the local source locations.
+ for (unsigned I = 0, N = local_sloc_entry_size(); I != N; ++I) {
bool Invalid = false;
- const SLocEntry &SLoc = getSLocEntry(I, &Invalid);
+ const SLocEntry &SLoc = getLocalSLocEntry(I, &Invalid);
if (Invalid)
- return SourceLocation();
+ return FileID();
if (SLoc.isFile() &&
SLoc.getFile().getContentCache() &&
@@ -1322,6 +1415,18 @@ SourceLocation SourceManager::getLocation(const FileEntry *SourceFile,
break;
}
}
+ // If that still didn't help, try the modules.
+ if (FirstFID.isInvalid()) {
+ for (unsigned I = 0, N = loaded_sloc_entry_size(); I != N; ++I) {
+ const SLocEntry &SLoc = getLoadedSLocEntry(I);
+ if (SLoc.isFile() &&
+ SLoc.getFile().getContentCache() &&
+ SLoc.getFile().getContentCache()->OrigEntry == SourceFile) {
+ FirstFID = FileID::get(-int(I) - 2);
+ break;
+ }
+ }
+ }
}
// If we haven't found what we want yet, try again, but this time stat()
@@ -1333,10 +1438,12 @@ SourceLocation SourceManager::getLocation(const FileEntry *SourceFile,
(SourceFileInode ||
(SourceFileInode = getActualFileInode(SourceFile)))) {
bool Invalid = false;
- for (unsigned I = 0, N = sloc_entry_size(); I != N; ++I) {
- const SLocEntry &SLoc = getSLocEntry(I, &Invalid);
+ for (unsigned I = 0, N = local_sloc_entry_size(); I != N; ++I) {
+ FileID IFileID;
+ IFileID.ID = I;
+ const SLocEntry &SLoc = getSLocEntry(IFileID, &Invalid);
if (Invalid)
- return SourceLocation();
+ return FileID();
if (SLoc.isFile()) {
const ContentCache *FileContentCache
@@ -1355,20 +1462,38 @@ SourceLocation SourceManager::getLocation(const FileEntry *SourceFile,
}
}
}
-
- if (FirstFID.isInvalid())
+
+ return FirstFID;
+}
+
+/// \brief Get the source location in \arg FID for the given line:col.
+/// Returns null location if \arg FID is not a file SLocEntry.
+SourceLocation SourceManager::translateLineCol(FileID FID,
+ unsigned Line,
+ unsigned Col) const {
+ if (FID.isInvalid())
+ return SourceLocation();
+
+ bool Invalid = false;
+ const SLocEntry &Entry = getSLocEntry(FID, &Invalid);
+ if (Invalid)
+ return SourceLocation();
+
+ if (!Entry.isFile())
return SourceLocation();
+ SourceLocation FileLoc = SourceLocation::getFileLoc(Entry.getOffset());
+
if (Line == 1 && Col == 1)
- return getLocForStartOfFile(FirstFID);
+ return FileLoc;
ContentCache *Content
- = const_cast<ContentCache *>(getOrCreateContentCache(SourceFile));
+ = const_cast<ContentCache *>(Entry.getFile().getContentCache());
if (!Content)
return SourceLocation();
// If this is the first use of line information for this buffer, compute the
- /// SourceLineCache for it on demand.
+ // SourceLineCache for it on demand.
if (Content->SourceLineCache == 0) {
bool MyInvalid = false;
ComputeLineNumbers(Diag, Content, ContentCacheAlloc, *this, MyInvalid);
@@ -1380,33 +1505,150 @@ SourceLocation SourceManager::getLocation(const FileEntry *SourceFile,
unsigned Size = Content->getBuffer(Diag, *this)->getBufferSize();
if (Size > 0)
--Size;
- return getLocForStartOfFile(FirstFID).getFileLocWithOffset(Size);
+ return FileLoc.getLocWithOffset(Size);
}
unsigned FilePos = Content->SourceLineCache[Line - 1];
const char *Buf = Content->getBuffer(Diag, *this)->getBufferStart() + FilePos;
unsigned BufLength = Content->getBuffer(Diag, *this)->getBufferEnd() - Buf;
+ if (BufLength == 0)
+ return FileLoc.getLocWithOffset(FilePos);
+
unsigned i = 0;
// Check that the given column is valid.
while (i < BufLength-1 && i < Col-1 && Buf[i] != '\n' && Buf[i] != '\r')
++i;
if (i < Col-1)
- return getLocForStartOfFile(FirstFID).getFileLocWithOffset(FilePos + i);
+ return FileLoc.getLocWithOffset(FilePos + i);
- return getLocForStartOfFile(FirstFID).getFileLocWithOffset(FilePos + Col - 1);
+ return FileLoc.getLocWithOffset(FilePos + Col - 1);
}
-/// Given a decomposed source location, move it up the include/instantiation
-/// stack to the parent source location. If this is possible, return the
-/// decomposed version of the parent in Loc and return false. If Loc is the
-/// top-level entry, return true and don't modify it.
+/// \brief Compute a map of macro argument chunks to their expanded source
+/// location. Chunks that are not part of a macro argument will map to an
+/// invalid source location. e.g. if a file contains one macro argument at
+/// offset 100 with length 10, this is how the map will be formed:
+/// 0 -> SourceLocation()
+/// 100 -> Expanded macro arg location
+/// 110 -> SourceLocation()
+void SourceManager::computeMacroArgsCache(MacroArgsMap *&CachePtr,
+ FileID FID) const {
+ assert(!FID.isInvalid());
+ assert(!CachePtr);
+
+ CachePtr = new MacroArgsMap();
+ MacroArgsMap &MacroArgsCache = *CachePtr;
+ // Initially no macro argument chunk is present.
+ MacroArgsCache.insert(std::make_pair(0, SourceLocation()));
+
+ int ID = FID.ID;
+ while (1) {
+ ++ID;
+ // Stop if there are no more FileIDs to check.
+ if (ID > 0) {
+ if (unsigned(ID) >= local_sloc_entry_size())
+ return;
+ } else if (ID == -1) {
+ return;
+ }
+
+ const SrcMgr::SLocEntry &Entry = getSLocEntryByID(ID);
+ if (Entry.isFile()) {
+ SourceLocation IncludeLoc = Entry.getFile().getIncludeLoc();
+ if (IncludeLoc.isInvalid())
+ continue;
+ if (!isInFileID(IncludeLoc, FID))
+ return; // No more files/macros that may be "contained" in this file.
+
+ // Skip the files/macros of the #include'd file, we only care about macros
+ // that lexed macro arguments from our file.
+ if (Entry.getFile().NumCreatedFIDs)
+ ID += Entry.getFile().NumCreatedFIDs - 1/*because of next ++ID*/;
+ continue;
+ }
+
+ if (!Entry.getExpansion().isMacroArgExpansion())
+ continue;
+
+ SourceLocation SpellLoc =
+ getSpellingLoc(Entry.getExpansion().getSpellingLoc());
+ unsigned BeginOffs;
+ if (!isInFileID(SpellLoc, FID, &BeginOffs))
+ return; // No more files/macros that may be "contained" in this file.
+ unsigned EndOffs = BeginOffs + getFileIDSize(FileID::get(ID));
+
+ // Add a new chunk for this macro argument. A previous macro argument chunk
+ // may have been lexed again, so e.g. if the map is
+ // 0 -> SourceLocation()
+ // 100 -> Expanded loc #1
+ // 110 -> SourceLocation()
+ // and we found a new macro FileID that lexed from offet 105 with length 3,
+ // the new map will be:
+ // 0 -> SourceLocation()
+ // 100 -> Expanded loc #1
+ // 105 -> Expanded loc #2
+ // 108 -> Expanded loc #1
+ // 110 -> SourceLocation()
+ //
+ // Since re-lexed macro chunks will always be the same size or less of
+ // previous chunks, we only need to find where the ending of the new macro
+ // chunk is mapped to and update the map with new begin/end mappings.
+
+ MacroArgsMap::iterator I = MacroArgsCache.upper_bound(EndOffs);
+ --I;
+ SourceLocation EndOffsMappedLoc = I->second;
+ MacroArgsCache[BeginOffs] = SourceLocation::getMacroLoc(Entry.getOffset());
+ MacroArgsCache[EndOffs] = EndOffsMappedLoc;
+ }
+}
+
+/// \brief If \arg Loc points inside a function macro argument, the returned
+/// location will be the macro location in which the argument was expanded.
+/// If a macro argument is used multiple times, the expanded location will
+/// be at the first expansion of the argument.
+/// e.g.
+/// MY_MACRO(foo);
+/// ^
+/// Passing a file location pointing at 'foo', will yield a macro location
+/// where 'foo' was expanded into.
+SourceLocation
+SourceManager::getMacroArgExpandedLocation(SourceLocation Loc) const {
+ if (Loc.isInvalid() || !Loc.isFileID())
+ return Loc;
+
+ FileID FID;
+ unsigned Offset;
+ llvm::tie(FID, Offset) = getDecomposedLoc(Loc);
+ if (FID.isInvalid())
+ return Loc;
+
+ MacroArgsMap *&MacroArgsCache = MacroArgsCacheMap[FID];
+ if (!MacroArgsCache)
+ computeMacroArgsCache(MacroArgsCache, FID);
+
+ assert(!MacroArgsCache->empty());
+ MacroArgsMap::iterator I = MacroArgsCache->upper_bound(Offset);
+ --I;
+
+ unsigned MacroArgBeginOffs = I->first;
+ SourceLocation MacroArgExpandedLoc = I->second;
+ if (MacroArgExpandedLoc.isValid())
+ return MacroArgExpandedLoc.getLocWithOffset(Offset - MacroArgBeginOffs);
+
+ return Loc;
+}
+
+/// Given a decomposed source location, move it up the include/expansion stack
+/// to the parent source location. If this is possible, return the decomposed
+/// version of the parent in Loc and return false. If Loc is the top-level
+/// entry, return true and don't modify it.
static bool MoveUpIncludeHierarchy(std::pair<FileID, unsigned> &Loc,
const SourceManager &SM) {
SourceLocation UpperLoc;
const SrcMgr::SLocEntry &Entry = SM.getSLocEntry(Loc.first);
- if (Entry.isInstantiation())
- UpperLoc = Entry.getInstantiation().getInstantiationLocStart();
+ if (Entry.isExpansion())
+ UpperLoc = Entry.getExpansion().getExpansionLocEnd();
else
UpperLoc = Entry.getFile().getIncludeLoc();
@@ -1427,11 +1669,6 @@ bool SourceManager::isBeforeInTranslationUnit(SourceLocation LHS,
if (LHS == RHS)
return false;
- // If both locations are macro instantiations, the order of their offsets
- // reflect the order that the tokens, pointed to by these locations, were
- // instantiated (during parsing each token that is instantiated by a macro,
- // expands the SLocEntries).
-
std::pair<FileID, unsigned> LOffs = getDecomposedLoc(LHS);
std::pair<FileID, unsigned> ROffs = getDecomposedLoc(RHS);
@@ -1445,41 +1682,28 @@ bool SourceManager::isBeforeInTranslationUnit(SourceLocation LHS,
return IsBeforeInTUCache.getCachedResult(LOffs.second, ROffs.second);
// Okay, we missed in the cache, start updating the cache for this query.
- IsBeforeInTUCache.setQueryFIDs(LOffs.first, ROffs.first);
-
- // "Traverse" the include/instantiation stacks of both locations and try to
- // find a common "ancestor". FileIDs build a tree-like structure that
- // reflects the #include hierarchy, and this algorithm needs to find the
- // nearest common ancestor between the two locations. For example, if you
- // have a.c that includes b.h and c.h, and are comparing a location in b.h to
- // a location in c.h, we need to find that their nearest common ancestor is
- // a.c, and compare the locations of the two #includes to find their relative
- // ordering.
- //
- // SourceManager assigns FileIDs in order of parsing. This means that an
- // includee always has a larger FileID than an includer. While you might
- // think that we could just compare the FileID's here, that doesn't work to
- // compare a point at the end of a.c with a point within c.h. Though c.h has
- // a larger FileID, we have to compare the include point of c.h to the
- // location in a.c.
- //
- // Despite not being able to directly compare FileID's, we can tell that a
- // larger FileID is necessarily more deeply nested than a lower one and use
- // this information to walk up the tree to the nearest common ancestor.
+ IsBeforeInTUCache.setQueryFIDs(LOffs.first, ROffs.first,
+ /*isLFIDBeforeRFID=*/LOffs.first.ID < ROffs.first.ID);
+
+ // We need to find the common ancestor. The only way of doing this is to
+ // build the complete include chain for one and then walking up the chain
+ // of the other looking for a match.
+ // We use a map from FileID to Offset to store the chain. Easier than writing
+ // a custom set hash info that only depends on the first part of a pair.
+ typedef llvm::DenseMap<FileID, unsigned> LocSet;
+ LocSet LChain;
do {
- // If LOffs is larger than ROffs, then LOffs must be more deeply nested than
- // ROffs, walk up the #include chain.
- if (LOffs.first.ID > ROffs.first.ID) {
- if (MoveUpIncludeHierarchy(LOffs, *this))
- break; // We reached the top.
-
- } else {
- // Otherwise, ROffs is larger than LOffs, so ROffs must be more deeply
- // nested than LOffs, walk up the #include chain.
- if (MoveUpIncludeHierarchy(ROffs, *this))
- break; // We reached the top.
- }
- } while (LOffs.first != ROffs.first);
+ LChain.insert(LOffs);
+ // We catch the case where LOffs is in a file included by ROffs and
+ // quit early. The other way round unfortunately remains suboptimal.
+ } while (LOffs.first != ROffs.first && !MoveUpIncludeHierarchy(LOffs, *this));
+ LocSet::iterator I;
+ while((I = LChain.find(ROffs.first)) == LChain.end()) {
+ if (MoveUpIncludeHierarchy(ROffs, *this))
+ break; // Met at topmost file.
+ }
+ if (I != LChain.end())
+ LOffs = *I;
// If we exited because we found a nearest common ancestor, compare the
// locations within the common file and cache them.
@@ -1488,26 +1712,21 @@ bool SourceManager::isBeforeInTranslationUnit(SourceLocation LHS,
return IsBeforeInTUCache.getCachedResult(LOffs.second, ROffs.second);
}
- // There is no common ancestor, most probably because one location is in the
- // predefines buffer or an AST file.
- // FIXME: We should rearrange the external interface so this simply never
- // happens; it can't conceptually happen. Also see PR5662.
- IsBeforeInTUCache.setQueryFIDs(FileID(), FileID()); // Don't try caching.
-
- // Zip both entries up to the top level record.
- while (!MoveUpIncludeHierarchy(LOffs, *this)) /*empty*/;
- while (!MoveUpIncludeHierarchy(ROffs, *this)) /*empty*/;
-
- // If exactly one location is a memory buffer, assume it precedes the other.
-
- // Strip off macro instantation locations, going up to the top-level File
- // SLocEntry.
- bool LIsMB = getFileEntryForID(LOffs.first) == 0;
- bool RIsMB = getFileEntryForID(ROffs.first) == 0;
- if (LIsMB != RIsMB)
- return LIsMB;
-
- // Otherwise, just assume FileIDs were created in order.
+ // This can happen if a location is in a built-ins buffer.
+ // But see PR5662.
+ // Clear the lookup cache, it depends on a common location.
+ IsBeforeInTUCache.clear();
+ bool LIsBuiltins = strcmp("<built-in>",
+ getBuffer(LOffs.first)->getBufferIdentifier()) == 0;
+ bool RIsBuiltins = strcmp("<built-in>",
+ getBuffer(ROffs.first)->getBufferIdentifier()) == 0;
+ // built-in is before non-built-in
+ if (LIsBuiltins != RIsBuiltins)
+ return LIsBuiltins;
+ assert(LIsBuiltins && RIsBuiltins &&
+ "Non-built-in locations must be rooted in the main file");
+ // Both are in built-in buffers, but from different files. We just claim that
+ // lower IDs come first.
return LOffs.first < ROffs.first;
}
@@ -1517,20 +1736,26 @@ void SourceManager::PrintStats() const {
llvm::errs() << "\n*** Source Manager Stats:\n";
llvm::errs() << FileInfos.size() << " files mapped, " << MemBufferInfos.size()
<< " mem buffers mapped.\n";
- llvm::errs() << SLocEntryTable.size() << " SLocEntry's allocated ("
- << SLocEntryTable.capacity()*sizeof(SrcMgr::SLocEntry)
+ llvm::errs() << LocalSLocEntryTable.size() << " local SLocEntry's allocated ("
+ << llvm::capacity_in_bytes(LocalSLocEntryTable)
<< " bytes of capacity), "
- << NextOffset << "B of Sloc address space used.\n";
-
+ << NextLocalOffset << "B of Sloc address space used.\n";
+ llvm::errs() << LoadedSLocEntryTable.size()
+ << " loaded SLocEntries allocated, "
+ << MaxLoadedOffset - CurrentLoadedOffset
+ << "B of Sloc address space used.\n";
+
unsigned NumLineNumsComputed = 0;
unsigned NumFileBytesMapped = 0;
for (fileinfo_iterator I = fileinfo_begin(), E = fileinfo_end(); I != E; ++I){
NumLineNumsComputed += I->second->SourceLineCache != 0;
NumFileBytesMapped += I->second->getSizeBytesMapped();
}
+ unsigned NumMacroArgsComputed = MacroArgsCacheMap.size();
llvm::errs() << NumFileBytesMapped << " bytes of files mapped, "
- << NumLineNumsComputed << " files with line #'s computed.\n";
+ << NumLineNumsComputed << " files with line #'s computed, "
+ << NumMacroArgsComputed << " files with macro args computed.\n";
llvm::errs() << "FileID scans: " << NumLinearScans << " linear, "
<< NumBinaryProbes << " binary.\n";
}
@@ -1557,3 +1782,11 @@ SourceManager::MemoryBufferSizes SourceManager::getMemoryBufferSizes() const {
return MemoryBufferSizes(malloc_bytes, mmap_bytes);
}
+size_t SourceManager::getDataStructureSizes() const {
+ return llvm::capacity_in_bytes(MemBufferInfos)
+ + llvm::capacity_in_bytes(LocalSLocEntryTable)
+ + llvm::capacity_in_bytes(LoadedSLocEntryTable)
+ + llvm::capacity_in_bytes(SLocEntryLoaded)
+ + llvm::capacity_in_bytes(FileInfos)
+ + llvm::capacity_in_bytes(OverriddenFiles);
+}
diff --git a/contrib/llvm/tools/clang/lib/Basic/TargetInfo.cpp b/contrib/llvm/tools/clang/lib/Basic/TargetInfo.cpp
index 30a9bdb..593db2b 100644
--- a/contrib/llvm/tools/clang/lib/Basic/TargetInfo.cpp
+++ b/contrib/llvm/tools/clang/lib/Basic/TargetInfo.cpp
@@ -16,6 +16,7 @@
#include "clang/Basic/LangOptions.h"
#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/Support/ErrorHandling.h"
#include <cctype>
#include <cstdlib>
using namespace clang;
@@ -33,6 +34,8 @@ TargetInfo::TargetInfo(const std::string &T) : Triple(T) {
IntWidth = IntAlign = 32;
LongWidth = LongAlign = 32;
LongLongWidth = LongLongAlign = 64;
+ HalfWidth = 16;
+ HalfAlign = 16;
FloatWidth = 32;
FloatAlign = 32;
DoubleWidth = 64;
@@ -41,6 +44,7 @@ TargetInfo::TargetInfo(const std::string &T) : Triple(T) {
LongDoubleAlign = 64;
LargeArrayMinWidth = 0;
LargeArrayAlign = 0;
+ MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 0;
SizeType = UnsignedLong;
PtrDiffType = SignedLong;
IntMaxType = SignedLongLong;
@@ -53,6 +57,9 @@ TargetInfo::TargetInfo(const std::string &T) : Triple(T) {
Int64Type = SignedLongLong;
SigAtomicType = SignedInt;
UseBitFieldTypeAlignment = true;
+ UseZeroLengthBitfieldAlignment = false;
+ ZeroLengthBitfieldBoundary = 0;
+ HalfFormat = &llvm::APFloat::IEEEhalf;
FloatFormat = &llvm::APFloat::IEEEsingle;
DoubleFormat = &llvm::APFloat::IEEEdouble;
LongDoubleFormat = &llvm::APFloat::IEEEdouble;
@@ -60,6 +67,8 @@ TargetInfo::TargetInfo(const std::string &T) : Triple(T) {
"i64:64:64-f32:32:32-f64:64:64-n32";
UserLabelPrefix = "_";
MCountName = "mcount";
+ RegParmMax = 0;
+ SSERegParmMax = 0;
HasAlignMac68kSupport = false;
// Default to no types using fpret.
@@ -83,7 +92,7 @@ TargetInfo::~TargetInfo() {}
/// For example, SignedShort -> "short".
const char *TargetInfo::getTypeName(IntType T) {
switch (T) {
- default: assert(0 && "not an integer!");
+ default: llvm_unreachable("not an integer!");
case SignedShort: return "short";
case UnsignedShort: return "unsigned short";
case SignedInt: return "int";
@@ -99,7 +108,7 @@ const char *TargetInfo::getTypeName(IntType T) {
/// integer type enum. For example, SignedLong -> "L".
const char *TargetInfo::getTypeConstantSuffix(IntType T) {
switch (T) {
- default: assert(0 && "not an integer!");
+ default: llvm_unreachable("not an integer!");
case SignedShort:
case SignedInt: return "";
case SignedLong: return "L";
@@ -115,7 +124,7 @@ const char *TargetInfo::getTypeConstantSuffix(IntType T) {
/// enum. For example, SignedInt -> getIntWidth().
unsigned TargetInfo::getTypeWidth(IntType T) const {
switch (T) {
- default: assert(0 && "not an integer!");
+ default: llvm_unreachable("not an integer!");
case SignedShort:
case UnsignedShort: return getShortWidth();
case SignedInt:
@@ -131,7 +140,7 @@ unsigned TargetInfo::getTypeWidth(IntType T) const {
/// enum. For example, SignedInt -> getIntAlign().
unsigned TargetInfo::getTypeAlign(IntType T) const {
switch (T) {
- default: assert(0 && "not an integer!");
+ default: llvm_unreachable("not an integer!");
case SignedShort:
case UnsignedShort: return getShortAlign();
case SignedInt:
@@ -147,7 +156,7 @@ unsigned TargetInfo::getTypeAlign(IntType T) const {
/// the type is signed; false otherwise.
bool TargetInfo::isTypeSigned(IntType T) {
switch (T) {
- default: assert(0 && "not an integer!");
+ default: llvm_unreachable("not an integer!");
case SignedShort:
case SignedInt:
case SignedLong:
@@ -174,7 +183,7 @@ void TargetInfo::setForcedLangOptions(LangOptions &Opts) {
//===----------------------------------------------------------------------===//
-static llvm::StringRef removeGCCRegisterPrefix(llvm::StringRef Name) {
+static StringRef removeGCCRegisterPrefix(StringRef Name) {
if (Name[0] == '%' || Name[0] == '#')
Name = Name.substr(1);
@@ -184,7 +193,7 @@ static llvm::StringRef removeGCCRegisterPrefix(llvm::StringRef Name) {
/// isValidClobber - Returns whether the passed in string is
/// a valid clobber in an inline asm statement. This is used by
/// Sema.
-bool TargetInfo::isValidClobber(llvm::StringRef Name) const {
+bool TargetInfo::isValidClobber(StringRef Name) const {
return (isValidGCCRegisterName(Name) ||
Name == "memory" || Name == "cc");
}
@@ -192,7 +201,7 @@ bool TargetInfo::isValidClobber(llvm::StringRef Name) const {
/// isValidGCCRegisterName - Returns whether the passed in string
/// is a valid register name according to GCC. This is used by Sema for
/// inline asm statements.
-bool TargetInfo::isValidGCCRegisterName(llvm::StringRef Name) const {
+bool TargetInfo::isValidGCCRegisterName(StringRef Name) const {
if (Name.empty())
return false;
@@ -248,8 +257,8 @@ bool TargetInfo::isValidGCCRegisterName(llvm::StringRef Name) const {
return false;
}
-llvm::StringRef
-TargetInfo::getNormalizedGCCRegisterName(llvm::StringRef Name) const {
+StringRef
+TargetInfo::getNormalizedGCCRegisterName(StringRef Name) const {
assert(isValidGCCRegisterName(Name) && "Invalid register passed in");
// Get rid of any register prefix.
diff --git a/contrib/llvm/tools/clang/lib/Basic/Targets.cpp b/contrib/llvm/tools/clang/lib/Basic/Targets.cpp
index 4c1eeed..6d0d7bb 100644
--- a/contrib/llvm/tools/clang/lib/Basic/Targets.cpp
+++ b/contrib/llvm/tools/clang/lib/Basic/Targets.cpp
@@ -26,6 +26,7 @@
#include "llvm/ADT/StringSwitch.h"
#include "llvm/ADT/Triple.h"
#include "llvm/MC/MCSectionMachO.h"
+#include "llvm/Support/ErrorHandling.h"
#include "llvm/Type.h"
#include <algorithm>
using namespace clang;
@@ -37,7 +38,7 @@ using namespace clang;
/// DefineStd - Define a macro name and standard variants. For example if
/// MacroName is "unix", then this will define "__unix", "__unix__", and "unix"
/// when in GNU mode.
-static void DefineStd(MacroBuilder &Builder, llvm::StringRef MacroName,
+static void DefineStd(MacroBuilder &Builder, StringRef MacroName,
const LangOptions &Opts) {
assert(MacroName[0] != '_' && "Identifier should be in the user's namespace");
@@ -77,7 +78,7 @@ public:
static void getDarwinDefines(MacroBuilder &Builder, const LangOptions &Opts,
const llvm::Triple &Triple,
- llvm::StringRef &PlatformName,
+ StringRef &PlatformName,
VersionTuple &PlatformMinVersion) {
Builder.defineMacro("__APPLE_CC__", "5621");
Builder.defineMacro("__APPLE__");
@@ -89,7 +90,7 @@ static void getDarwinDefines(MacroBuilder &Builder, const LangOptions &Opts,
Builder.defineMacro("__weak", "__attribute__((objc_gc(weak)))");
// Darwin defines __strong even in C mode (just to nothing).
- if (Opts.getGCMode() != LangOptions::NonGC)
+ if (Opts.getGC() != LangOptions::NonGC)
Builder.defineMacro("__strong", "__attribute__((objc_gc(strong)))");
else
Builder.defineMacro("__strong", "");
@@ -146,6 +147,14 @@ static void getDarwinDefines(MacroBuilder &Builder, const LangOptions &Opts,
}
}
+ // If -ccc-host-triple arch-pc-win32-macho option specified, we're
+ // generating code for Win32 ABI. No need to emit
+ // __ENVIRONMENT_XX_OS_VERSION_MIN_REQUIRED__.
+ if (PlatformName == "win32") {
+ PlatformMinVersion = VersionTuple(Maj, Min, Rev);
+ return;
+ }
+
// Set the appropriate OS version define.
if (PlatformName == "ios") {
assert(Maj < 10 && Min < 100 && Rev < 100 && "Invalid version!");
@@ -194,9 +203,9 @@ public:
this->MCountName = "\01mcount";
}
- virtual std::string isValidSectionSpecifier(llvm::StringRef SR) const {
+ virtual std::string isValidSectionSpecifier(StringRef SR) const {
// Let MCSectionMachO validate this.
- llvm::StringRef Segment, Section;
+ StringRef Segment, Section;
unsigned TAA, StubSize;
bool HasTAA;
return llvm::MCSectionMachO::ParseSectionSpecifier(SR, Segment, Section,
@@ -242,9 +251,8 @@ protected:
if (Release == 0U)
Release = 8U;
- Builder.defineMacro("__FreeBSD__", llvm::Twine(Release));
- Builder.defineMacro("__FreeBSD_cc_version",
- llvm::Twine(Release * 100000U + 1U));
+ Builder.defineMacro("__FreeBSD__", Twine(Release));
+ Builder.defineMacro("__FreeBSD_cc_version", Twine(Release * 100000U + 1U));
Builder.defineMacro("__KPRINTF_ATTRIBUTE__");
DefineStd(Builder, "unix", Opts);
Builder.defineMacro("__ELF__");
@@ -497,9 +505,9 @@ protected:
Builder.defineMacro("_MT");
if (Opts.MSCVersion != 0)
- Builder.defineMacro("_MSC_VER", llvm::Twine(Opts.MSCVersion));
+ Builder.defineMacro("_MSC_VER", Twine(Opts.MSCVersion));
- if (Opts.Microsoft) {
+ if (Opts.MicrosoftExt) {
Builder.defineMacro("_MSC_EXTENSIONS");
if (Opts.CPlusPlus0x) {
@@ -871,13 +879,41 @@ public:
} // end anonymous namespace.
namespace {
+ static const unsigned PTXAddrSpaceMap[] = {
+ 0, // opencl_global
+ 4, // opencl_local
+ 1 // opencl_constant
+ };
class PTXTargetInfo : public TargetInfo {
static const char * const GCCRegNames[];
static const Builtin::Info BuiltinInfo[];
+ std::vector<llvm::StringRef> AvailableFeatures;
public:
PTXTargetInfo(const std::string& triple) : TargetInfo(triple) {
TLSSupported = false;
LongWidth = LongAlign = 64;
+ AddrSpaceMap = &PTXAddrSpaceMap;
+ // Define available target features
+ // These must be defined in sorted order!
+ AvailableFeatures.push_back("compute10");
+ AvailableFeatures.push_back("compute11");
+ AvailableFeatures.push_back("compute12");
+ AvailableFeatures.push_back("compute13");
+ AvailableFeatures.push_back("compute20");
+ AvailableFeatures.push_back("double");
+ AvailableFeatures.push_back("no-fma");
+ AvailableFeatures.push_back("ptx20");
+ AvailableFeatures.push_back("ptx21");
+ AvailableFeatures.push_back("ptx22");
+ AvailableFeatures.push_back("ptx23");
+ AvailableFeatures.push_back("sm10");
+ AvailableFeatures.push_back("sm11");
+ AvailableFeatures.push_back("sm12");
+ AvailableFeatures.push_back("sm13");
+ AvailableFeatures.push_back("sm20");
+ AvailableFeatures.push_back("sm21");
+ AvailableFeatures.push_back("sm22");
+ AvailableFeatures.push_back("sm23");
}
virtual void getTargetDefines(const LangOptions &Opts,
MacroBuilder &Builder) const {
@@ -910,6 +946,10 @@ namespace {
// FIXME: implement
return "typedef char* __builtin_va_list;";
}
+
+ virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features,
+ const std::string &Name,
+ bool Enabled) const;
};
const Builtin::Info PTXTargetInfo::BuiltinInfo[] = {
@@ -929,6 +969,17 @@ namespace {
NumNames = llvm::array_lengthof(GCCRegNames);
}
+ bool PTXTargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,
+ const std::string &Name,
+ bool Enabled) const {
+ if(std::binary_search(AvailableFeatures.begin(), AvailableFeatures.end(),
+ Name)) {
+ Features[Name] = Enabled;
+ return true;
+ } else {
+ return false;
+ }
+ }
class PTX32TargetInfo : public PTXTargetInfo {
public:
@@ -1121,10 +1172,134 @@ class X86TargetInfo : public TargetInfo {
bool HasAES;
bool HasAVX;
+ /// \brief Enumeration of all of the X86 CPUs supported by Clang.
+ ///
+ /// Each enumeration represents a particular CPU supported by Clang. These
+ /// loosely correspond to the options passed to '-march' or '-mtune' flags.
+ enum CPUKind {
+ CK_Generic,
+
+ /// \name i386
+ /// i386-generation processors.
+ //@{
+ CK_i386,
+ //@}
+
+ /// \name i486
+ /// i486-generation processors.
+ //@{
+ CK_i486,
+ CK_WinChipC6,
+ CK_WinChip2,
+ CK_C3,
+ //@}
+
+ /// \name i586
+ /// i586-generation processors, P5 microarchitecture based.
+ //@{
+ CK_i586,
+ CK_Pentium,
+ CK_PentiumMMX,
+ //@}
+
+ /// \name i686
+ /// i686-generation processors, P6 / Pentium M microarchitecture based.
+ //@{
+ CK_i686,
+ CK_PentiumPro,
+ CK_Pentium2,
+ CK_Pentium3,
+ CK_Pentium3M,
+ CK_PentiumM,
+ CK_C3_2,
+
+ /// This enumerator is a bit odd, as GCC no longer accepts -march=yonah.
+ /// Clang however has some logic to suport this.
+ // FIXME: Warn, deprecate, and potentially remove this.
+ CK_Yonah,
+ //@}
+
+ /// \name Netburst
+ /// Netburst microarchitecture based processors.
+ //@{
+ CK_Pentium4,
+ CK_Pentium4M,
+ CK_Prescott,
+ CK_Nocona,
+ //@}
+
+ /// \name Core
+ /// Core microarchitecture based processors.
+ //@{
+ CK_Core2,
+
+ /// This enumerator, like \see CK_Yonah, is a bit odd. It is another
+ /// codename which GCC no longer accepts as an option to -march, but Clang
+ /// has some logic for recognizing it.
+ // FIXME: Warn, deprecate, and potentially remove this.
+ CK_Penryn,
+ //@}
+
+ /// \name Atom
+ /// Atom processors
+ //@{
+ CK_Atom,
+ //@}
+
+ /// \name Nehalem
+ /// Nehalem microarchitecture based processors.
+ //@{
+ CK_Corei7,
+ CK_Corei7AVX,
+ CK_CoreAVXi,
+ //@}
+
+ /// \name K6
+ /// K6 architecture processors.
+ //@{
+ CK_K6,
+ CK_K6_2,
+ CK_K6_3,
+ //@}
+
+ /// \name K7
+ /// K7 architecture processors.
+ //@{
+ CK_Athlon,
+ CK_AthlonThunderbird,
+ CK_Athlon4,
+ CK_AthlonXP,
+ CK_AthlonMP,
+ //@}
+
+ /// \name K8
+ /// K8 architecture processors.
+ //@{
+ CK_Athlon64,
+ CK_Athlon64SSE3,
+ CK_AthlonFX,
+ CK_K8,
+ CK_K8SSE3,
+ CK_Opteron,
+ CK_OpteronSSE3,
+
+ /// This specification is deprecated and will be removed in the future.
+ /// Users should prefer \see CK_K8.
+ // FIXME: Warn on this when the CPU is set to it.
+ CK_x86_64,
+ //@}
+
+ /// \name Geode
+ /// Geode processors.
+ //@{
+ CK_Geode
+ //@}
+ } CPU;
+
public:
X86TargetInfo(const std::string& triple)
: TargetInfo(triple), SSELevel(NoSSE), MMX3DNowLevel(NoMMX3DNow),
- HasAES(false), HasAVX(false) {
+ HasAES(false), HasAVX(false), CPU(CK_Generic) {
LongDoubleFormat = &llvm::APFloat::x87DoubleExtended;
}
virtual void getTargetBuiltins(const Builtin::Info *&Records,
@@ -1158,16 +1333,122 @@ public:
virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features,
const std::string &Name,
bool Enabled) const;
- virtual void getDefaultFeatures(const std::string &CPU,
- llvm::StringMap<bool> &Features) const;
+ virtual void getDefaultFeatures(llvm::StringMap<bool> &Features) const;
virtual void HandleTargetFeatures(std::vector<std::string> &Features);
virtual const char* getABI() const {
return MMX3DNowLevel == NoMMX3DNow ? "no-mmx" : "";
}
+ virtual bool setCPU(const std::string &Name) {
+ CPU = llvm::StringSwitch<CPUKind>(Name)
+ .Case("i386", CK_i386)
+ .Case("i486", CK_i486)
+ .Case("winchip-c6", CK_WinChipC6)
+ .Case("winchip2", CK_WinChip2)
+ .Case("c3", CK_C3)
+ .Case("i586", CK_i586)
+ .Case("pentium", CK_Pentium)
+ .Case("pentium-mmx", CK_PentiumMMX)
+ .Case("i686", CK_i686)
+ .Case("pentiumpro", CK_PentiumPro)
+ .Case("pentium2", CK_Pentium2)
+ .Case("pentium3", CK_Pentium3)
+ .Case("pentium3m", CK_Pentium3M)
+ .Case("pentium-m", CK_PentiumM)
+ .Case("c3-2", CK_C3_2)
+ .Case("yonah", CK_Yonah)
+ .Case("pentium4", CK_Pentium4)
+ .Case("pentium4m", CK_Pentium4M)
+ .Case("prescott", CK_Prescott)
+ .Case("nocona", CK_Nocona)
+ .Case("core2", CK_Core2)
+ .Case("penryn", CK_Penryn)
+ .Case("atom", CK_Atom)
+ .Case("corei7", CK_Corei7)
+ .Case("corei7-avx", CK_Corei7AVX)
+ .Case("core-avx-i", CK_CoreAVXi)
+ .Case("k6", CK_K6)
+ .Case("k6-2", CK_K6_2)
+ .Case("k6-3", CK_K6_3)
+ .Case("athlon", CK_Athlon)
+ .Case("athlon-tbird", CK_AthlonThunderbird)
+ .Case("athlon-4", CK_Athlon4)
+ .Case("athlon-xp", CK_AthlonXP)
+ .Case("athlon-mp", CK_AthlonMP)
+ .Case("athlon64", CK_Athlon64)
+ .Case("athlon64-sse3", CK_Athlon64SSE3)
+ .Case("athlon-fx", CK_AthlonFX)
+ .Case("k8", CK_K8)
+ .Case("k8-sse3", CK_K8SSE3)
+ .Case("opteron", CK_Opteron)
+ .Case("opteron-sse3", CK_OpteronSSE3)
+ .Case("x86-64", CK_x86_64)
+ .Case("geode", CK_Geode)
+ .Default(CK_Generic);
+
+ // Perform any per-CPU checks necessary to determine if this CPU is
+ // acceptable.
+ // FIXME: This results in terrible diagnostics. Clang just says the CPU is
+ // invalid without explaining *why*.
+ switch (CPU) {
+ case CK_Generic:
+ // No processor selected!
+ return false;
+
+ case CK_i386:
+ case CK_i486:
+ case CK_WinChipC6:
+ case CK_WinChip2:
+ case CK_C3:
+ case CK_i586:
+ case CK_Pentium:
+ case CK_PentiumMMX:
+ case CK_i686:
+ case CK_PentiumPro:
+ case CK_Pentium2:
+ case CK_Pentium3:
+ case CK_Pentium3M:
+ case CK_PentiumM:
+ case CK_Yonah:
+ case CK_C3_2:
+ case CK_Pentium4:
+ case CK_Pentium4M:
+ case CK_Prescott:
+ case CK_K6:
+ case CK_K6_2:
+ case CK_K6_3:
+ case CK_Athlon:
+ case CK_AthlonThunderbird:
+ case CK_Athlon4:
+ case CK_AthlonXP:
+ case CK_AthlonMP:
+ case CK_Geode:
+ // Only accept certain architectures when compiling in 32-bit mode.
+ if (PointerWidth != 32)
+ return false;
+
+ // Fallthrough
+ case CK_Nocona:
+ case CK_Core2:
+ case CK_Penryn:
+ case CK_Atom:
+ case CK_Corei7:
+ case CK_Corei7AVX:
+ case CK_CoreAVXi:
+ case CK_Athlon64:
+ case CK_Athlon64SSE3:
+ case CK_AthlonFX:
+ case CK_K8:
+ case CK_K8SSE3:
+ case CK_Opteron:
+ case CK_OpteronSSE3:
+ case CK_x86_64:
+ return true;
+ }
+ llvm_unreachable("Unhandled CPU kind");
+ }
};
-void X86TargetInfo::getDefaultFeatures(const std::string &CPU,
- llvm::StringMap<bool> &Features) const {
+void X86TargetInfo::getDefaultFeatures(llvm::StringMap<bool> &Features) const {
// FIXME: This should not be here.
Features["3dnow"] = false;
Features["3dnowa"] = false;
@@ -1190,57 +1471,100 @@ void X86TargetInfo::getDefaultFeatures(const std::string &CPU,
if (PointerWidth == 64)
Features["sse2"] = Features["sse"] = Features["mmx"] = true;
- if (CPU == "generic" || CPU == "i386" || CPU == "i486" || CPU == "i586" ||
- CPU == "pentium" || CPU == "i686" || CPU == "pentiumpro")
- ;
- else if (CPU == "pentium-mmx" || CPU == "pentium2")
+ switch (CPU) {
+ case CK_Generic:
+ case CK_i386:
+ case CK_i486:
+ case CK_i586:
+ case CK_Pentium:
+ case CK_i686:
+ case CK_PentiumPro:
+ break;
+ case CK_PentiumMMX:
+ case CK_Pentium2:
setFeatureEnabled(Features, "mmx", true);
- else if (CPU == "pentium3") {
+ break;
+ case CK_Pentium3:
+ case CK_Pentium3M:
setFeatureEnabled(Features, "mmx", true);
setFeatureEnabled(Features, "sse", true);
- } else if (CPU == "pentium-m" || CPU == "pentium4" || CPU == "x86-64") {
+ break;
+ case CK_PentiumM:
+ case CK_Pentium4:
+ case CK_Pentium4M:
+ case CK_x86_64:
setFeatureEnabled(Features, "mmx", true);
setFeatureEnabled(Features, "sse2", true);
- } else if (CPU == "yonah" || CPU == "prescott" || CPU == "nocona") {
+ break;
+ case CK_Yonah:
+ case CK_Prescott:
+ case CK_Nocona:
setFeatureEnabled(Features, "mmx", true);
setFeatureEnabled(Features, "sse3", true);
- } else if (CPU == "core2") {
+ break;
+ case CK_Core2:
setFeatureEnabled(Features, "mmx", true);
setFeatureEnabled(Features, "ssse3", true);
- } else if (CPU == "penryn") {
+ break;
+ case CK_Penryn:
setFeatureEnabled(Features, "mmx", true);
setFeatureEnabled(Features, "sse4", true);
Features["sse42"] = false;
- } else if (CPU == "atom") {
+ break;
+ case CK_Atom:
setFeatureEnabled(Features, "mmx", true);
- setFeatureEnabled(Features, "sse3", true);
- } else if (CPU == "corei7") {
+ setFeatureEnabled(Features, "ssse3", true);
+ break;
+ case CK_Corei7:
setFeatureEnabled(Features, "mmx", true);
setFeatureEnabled(Features, "sse4", true);
setFeatureEnabled(Features, "aes", true);
- } else if (CPU == "corei7-avx") {
+ break;
+ case CK_Corei7AVX:
+ case CK_CoreAVXi:
setFeatureEnabled(Features, "mmx", true);
setFeatureEnabled(Features, "sse4", true);
setFeatureEnabled(Features, "aes", true);
//setFeatureEnabled(Features, "avx", true);
- } else if (CPU == "k6" || CPU == "winchip-c6")
+ break;
+ case CK_K6:
+ case CK_WinChipC6:
setFeatureEnabled(Features, "mmx", true);
- else if (CPU == "k6-2" || CPU == "k6-3" || CPU == "athlon" ||
- CPU == "athlon-tbird" || CPU == "winchip2" || CPU == "c3") {
+ break;
+ case CK_K6_2:
+ case CK_K6_3:
+ case CK_WinChip2:
+ case CK_C3:
setFeatureEnabled(Features, "3dnow", true);
- } else if (CPU == "athlon-4" || CPU == "athlon-xp" || CPU == "athlon-mp") {
+ break;
+ case CK_Athlon:
+ case CK_AthlonThunderbird:
+ case CK_Geode:
+ setFeatureEnabled(Features, "3dnowa", true);
+ break;
+ case CK_Athlon4:
+ case CK_AthlonXP:
+ case CK_AthlonMP:
setFeatureEnabled(Features, "sse", true);
setFeatureEnabled(Features, "3dnowa", true);
- } else if (CPU == "k8" || CPU == "opteron" || CPU == "athlon64" ||
- CPU == "athlon-fx") {
+ break;
+ case CK_K8:
+ case CK_Opteron:
+ case CK_Athlon64:
+ case CK_AthlonFX:
setFeatureEnabled(Features, "sse2", true);
setFeatureEnabled(Features, "3dnowa", true);
- } else if (CPU == "k8-sse3") {
+ break;
+ case CK_K8SSE3:
+ case CK_OpteronSSE3:
+ case CK_Athlon64SSE3:
setFeatureEnabled(Features, "sse3", true);
setFeatureEnabled(Features, "3dnowa", true);
- } else if (CPU == "c3-2") {
+ break;
+ case CK_C3_2:
setFeatureEnabled(Features, "mmx", true);
setFeatureEnabled(Features, "sse", true);
+ break;
}
}
@@ -1278,7 +1602,8 @@ bool X86TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,
else if (Name == "aes")
Features["aes"] = true;
else if (Name == "avx")
- Features["avx"] = true;
+ Features["avx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
+ Features["ssse3"] = Features["sse41"] = Features["sse42"] = true;
} else {
if (Name == "mmx")
Features["mmx"] = Features["3dnow"] = Features["3dnowa"] = false;
@@ -1360,8 +1685,8 @@ void X86TargetInfo::HandleTargetFeatures(std::vector<std::string> &Features) {
Features.erase(it);
}
-/// X86TargetInfo::getTargetDefines - Return a set of the X86-specific #defines
-/// that are not tied to a specific subtarget.
+/// X86TargetInfo::getTargetDefines - Return the set of the X86-specific macro
+/// definitions for this particular subtarget.
void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
MacroBuilder &Builder) const {
// Target identification.
@@ -1376,19 +1701,140 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
DefineStd(Builder, "i386", Opts);
}
- if (HasAES)
- Builder.defineMacro("__AES__");
-
- if (HasAVX)
- Builder.defineMacro("__AVX__");
+ // Subtarget options.
+ // FIXME: We are hard-coding the tune parameters based on the CPU, but they
+ // truly should be based on -mtune options.
+ switch (CPU) {
+ case CK_Generic:
+ break;
+ case CK_i386:
+ // The rest are coming from the i386 define above.
+ Builder.defineMacro("__tune_i386__");
+ break;
+ case CK_i486:
+ case CK_WinChipC6:
+ case CK_WinChip2:
+ case CK_C3:
+ Builder.defineMacro("__i486");
+ Builder.defineMacro("__i486__");
+ Builder.defineMacro("__tune_i486__");
+ break;
+ case CK_PentiumMMX:
+ Builder.defineMacro("__pentium_mmx__");
+ Builder.defineMacro("__tune_pentium_mmx__");
+ // Fallthrough
+ case CK_i586:
+ case CK_Pentium:
+ Builder.defineMacro("__i586");
+ Builder.defineMacro("__i586__");
+ Builder.defineMacro("__tune_i586__");
+ Builder.defineMacro("__pentium");
+ Builder.defineMacro("__pentium__");
+ Builder.defineMacro("__tune_pentium__");
+ break;
+ case CK_Pentium3:
+ case CK_Pentium3M:
+ case CK_PentiumM:
+ Builder.defineMacro("__tune_pentium3__");
+ // Fallthrough
+ case CK_Pentium2:
+ case CK_C3_2:
+ Builder.defineMacro("__tune_pentium2__");
+ // Fallthrough
+ case CK_PentiumPro:
+ Builder.defineMacro("__tune_i686__");
+ Builder.defineMacro("__tune_pentiumpro__");
+ // Fallthrough
+ case CK_i686:
+ Builder.defineMacro("__i686");
+ Builder.defineMacro("__i686__");
+ // Strangely, __tune_i686__ isn't defined by GCC when CPU == i686.
+ Builder.defineMacro("__pentiumpro");
+ Builder.defineMacro("__pentiumpro__");
+ break;
+ case CK_Pentium4:
+ case CK_Pentium4M:
+ Builder.defineMacro("__pentium4");
+ Builder.defineMacro("__pentium4__");
+ Builder.defineMacro("__tune_pentium4__");
+ break;
+ case CK_Yonah:
+ case CK_Prescott:
+ case CK_Nocona:
+ Builder.defineMacro("__nocona");
+ Builder.defineMacro("__nocona__");
+ Builder.defineMacro("__tune_nocona__");
+ break;
+ case CK_Core2:
+ case CK_Penryn:
+ Builder.defineMacro("__core2");
+ Builder.defineMacro("__core2__");
+ Builder.defineMacro("__tune_core2__");
+ break;
+ case CK_Atom:
+ Builder.defineMacro("__atom");
+ Builder.defineMacro("__atom__");
+ Builder.defineMacro("__tune_atom__");
+ break;
+ case CK_Corei7:
+ case CK_Corei7AVX:
+ case CK_CoreAVXi:
+ Builder.defineMacro("__corei7");
+ Builder.defineMacro("__corei7__");
+ Builder.defineMacro("__tune_corei7__");
+ break;
+ case CK_K6_2:
+ Builder.defineMacro("__k6_2__");
+ Builder.defineMacro("__tune_k6_2__");
+ // Fallthrough
+ case CK_K6_3:
+ if (CPU != CK_K6_2) { // In case of fallthrough
+ // FIXME: GCC may be enabling these in cases where some other k6
+ // architecture is specified but -m3dnow is explicitly provided. The
+ // exact semantics need to be determined and emulated here.
+ Builder.defineMacro("__k6_3__");
+ Builder.defineMacro("__tune_k6_3__");
+ }
+ // Fallthrough
+ case CK_K6:
+ Builder.defineMacro("__k6");
+ Builder.defineMacro("__k6__");
+ Builder.defineMacro("__tune_k6__");
+ break;
+ case CK_Athlon:
+ case CK_AthlonThunderbird:
+ case CK_Athlon4:
+ case CK_AthlonXP:
+ case CK_AthlonMP:
+ Builder.defineMacro("__athlon");
+ Builder.defineMacro("__athlon__");
+ Builder.defineMacro("__tune_athlon__");
+ if (SSELevel != NoSSE) {
+ Builder.defineMacro("__athlon_sse__");
+ Builder.defineMacro("__tune_athlon_sse__");
+ }
+ break;
+ case CK_K8:
+ case CK_K8SSE3:
+ case CK_x86_64:
+ case CK_Opteron:
+ case CK_OpteronSSE3:
+ case CK_Athlon64:
+ case CK_Athlon64SSE3:
+ case CK_AthlonFX:
+ Builder.defineMacro("__k8");
+ Builder.defineMacro("__k8__");
+ Builder.defineMacro("__tune_k8__");
+ break;
+ case CK_Geode:
+ Builder.defineMacro("__geode");
+ Builder.defineMacro("__geode__");
+ Builder.defineMacro("__tune_geode__");
+ break;
+ }
// Target properties.
Builder.defineMacro("__LITTLE_ENDIAN__");
-
- // Subtarget options.
- Builder.defineMacro("__nocona");
- Builder.defineMacro("__nocona__");
- Builder.defineMacro("__tune_nocona__");
Builder.defineMacro("__REGISTER_PREFIX__", "");
// Define __NO_MATH_INLINES on linux/x86 so that we don't get inline
@@ -1396,6 +1842,12 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
// backend can't deal with (PR879).
Builder.defineMacro("__NO_MATH_INLINES");
+ if (HasAES)
+ Builder.defineMacro("__AES__");
+
+ if (HasAVX)
+ Builder.defineMacro("__AVX__");
+
// Each case falls through to the previous one here.
switch (SSELevel) {
case SSE42:
@@ -1416,20 +1868,20 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
break;
}
- if (Opts.Microsoft && PointerWidth == 32) {
+ if (Opts.MicrosoftExt && PointerWidth == 32) {
switch (SSELevel) {
case SSE42:
case SSE41:
case SSSE3:
case SSE3:
case SSE2:
- Builder.defineMacro("_M_IX86_FP", llvm::Twine(2));
+ Builder.defineMacro("_M_IX86_FP", Twine(2));
break;
case SSE1:
- Builder.defineMacro("_M_IX86_FP", llvm::Twine(1));
+ Builder.defineMacro("_M_IX86_FP", Twine(1));
break;
default:
- Builder.defineMacro("_M_IX86_FP", llvm::Twine(0));
+ Builder.defineMacro("_M_IX86_FP", Twine(0));
}
}
@@ -1523,7 +1975,7 @@ public:
LongDoubleAlign = 32;
DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
"i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-"
- "a0:0:64-f80:32:32-n8:16:32";
+ "a0:0:64-f80:32:32-n8:16:32-S128";
SizeType = UnsignedInt;
PtrDiffType = SignedInt;
IntPtrType = SignedInt;
@@ -1533,6 +1985,11 @@ public:
RealTypeUsesObjCFPRet = ((1 << TargetInfo::Float) |
(1 << TargetInfo::Double) |
(1 << TargetInfo::LongDouble));
+
+ // x86-32 has atomics up to 8 bytes
+ // FIXME: Check that we actually have cmpxchg8b before setting
+ // MaxAtomicInlineWidth. (cmpxchg8b is an i586 instruction.)
+ MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
}
virtual const char *getVAListDeclaration() const {
return "typedef char* __builtin_va_list;";
@@ -1569,7 +2026,7 @@ public:
IntPtrType = SignedLong;
DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
"i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-"
- "a0:0:64-f80:128:128-n8:16:32";
+ "a0:0:64-f80:128:128-n8:16:32-S128";
HasAlignMac68kSupport = true;
}
@@ -1587,7 +2044,7 @@ public:
DoubleAlign = LongLongAlign = 64;
DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
"i64:64:64-f32:32:32-f64:64:64-f80:128:128-v64:64:64-"
- "v128:128:128-a0:0:64-f80:32:32-n8:16:32";
+ "v128:128:128-a0:0:64-f80:32:32-n8:16:32-S32";
}
virtual void getTargetDefines(const LangOptions &Opts,
MacroBuilder &Builder) const {
@@ -1636,7 +2093,7 @@ public:
// mingw32-gcc provides __declspec(a) as alias of __attribute__((a)).
// In contrast, clang-cc1 provides __declspec(a) with -fms-extensions.
- if (Opts.Microsoft)
+ if (Opts.MicrosoftExt)
// Provide "as-is" __declspec.
Builder.defineMacro("__declspec", "__declspec");
else
@@ -1657,7 +2114,7 @@ public:
DoubleAlign = LongLongAlign = 64;
DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
"i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-"
- "a0:0:64-f80:32:32-n8:16:32";
+ "a0:0:64-f80:32:32-n8:16:32-S32";
}
virtual void getTargetDefines(const LangOptions &Opts,
MacroBuilder &Builder) const {
@@ -1699,9 +2156,6 @@ protected:
MacroBuilder &Builder) const {
// RTEMS defines; list based off of gcc output
- // FIXME: Move version number handling to llvm::Triple.
- llvm::StringRef Release = Triple.getOSName().substr(strlen("rtems"), 1);
-
Builder.defineMacro("__rtems__");
Builder.defineMacro("__ELF__");
}
@@ -1767,10 +2221,16 @@ public:
DescriptionString = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
"i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-"
- "a0:0:64-s0:64:64-f80:128:128-n8:16:32:64";
+ "a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128";
// Use fpret only for long double.
RealTypeUsesObjCFPRet = (1 << TargetInfo::LongDouble);
+
+ // 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;
}
virtual const char *getVAListDeclaration() const {
return "typedef struct __va_list_tag {"
@@ -1855,7 +2315,7 @@ public:
// mingw32-gcc provides __declspec(a) as alias of __attribute__((a)).
// In contrast, clang-cc1 provides __declspec(a) with -fms-extensions.
- if (Opts.Microsoft)
+ if (Opts.MicrosoftExt)
// Provide "as-is" __declspec.
Builder.defineMacro("__declspec", "__declspec");
else
@@ -1934,15 +2394,19 @@ public:
// so set preferred for small types to 32.
DescriptionString = ("e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-"
"i64:64:64-f32:32:32-f64:64:64-"
- "v64:64:64-v128:64:128-a0:0:32-n32");
+ "v64:64:64-v128:64:128-a0:0:32-n32-S64");
} else {
DescriptionString = ("e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
"i64:64:64-f32:32:32-f64:64:64-"
- "v64:64:64-v128:64:128-a0:0:64-n32");
+ "v64:64:64-v128:64:128-a0:0:64-n32-S64");
}
// ARM targets default to using the ARM C++ ABI.
CXXABI = CXXABI_ARM;
+
+ // ARM has atomics up to 8 bytes
+ // FIXME: Set MaxAtomicInlineWidth if we have the feature v6e
+ MaxAtomicPromoteWidth = 64;
}
virtual const char *getABI() const { return ABI.c_str(); }
virtual bool setABI(const std::string &Name) {
@@ -1960,16 +2424,27 @@ public:
// structures. This corresponds to PCC_BITFIELD_TYPE_MATTERS in gcc.
UseBitFieldTypeAlignment = false;
+ /// Do force alignment of members that follow zero length bitfields. If
+ /// the alignment of the zero-length bitfield is greater than the member
+ /// that follows it, `bar', `bar' will be aligned as the type of the
+ /// zero length bitfield.
+ UseZeroLengthBitfieldAlignment = true;
+
+ /// gcc forces the alignment to 4 bytes, regardless of the type of the
+ /// zero length bitfield. This corresponds to EMPTY_FIELD_BOUNDARY in
+ /// gcc.
+ ZeroLengthBitfieldBoundary = 32;
+
if (IsThumb) {
// Thumb1 add sp, #imm requires the immediate value be multiple of 4,
// so set preferred for small types to 32.
DescriptionString = ("e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-"
"i64:32:64-f32:32:32-f64:32:64-"
- "v64:32:64-v128:32:128-a0:0:32-n32");
+ "v64:32:64-v128:32:128-a0:0:32-n32-S32");
} else {
DescriptionString = ("e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
"i64:32:64-f32:32:32-f64:32:64-"
- "v64:32:64-v128:32:128-a0:0:32-n32");
+ "v64:32:64-v128:32:128-a0:0:32-n32-S32");
}
// FIXME: Override "preferred align" for double and long long.
@@ -1983,8 +2458,7 @@ public:
return true;
}
- void getDefaultFeatures(const std::string &CPU,
- llvm::StringMap<bool> &Features) const {
+ void getDefaultFeatures(llvm::StringMap<bool> &Features) const {
if (CPU == "arm1136jf-s" || CPU == "arm1176jzf-s" || CPU == "mpcore")
Features["vfp2"] = true;
else if (CPU == "cortex-a8" || CPU == "cortex-a9")
@@ -2029,7 +2503,7 @@ public:
Features.erase(it);
}
- static const char *getCPUDefineSuffix(llvm::StringRef Name) {
+ static const char *getCPUDefineSuffix(StringRef Name) {
return llvm::StringSwitch<const char*>(Name)
.Cases("arm8", "arm810", "4")
.Cases("strongarm", "strongarm110", "strongarm1100", "strongarm1110", "4")
@@ -2068,7 +2542,7 @@ public:
Builder.defineMacro("__LITTLE_ENDIAN__");
Builder.defineMacro("__REGISTER_PREFIX__", "");
- llvm::StringRef CPUArch = getCPUDefineSuffix(CPU);
+ StringRef CPUArch = getCPUDefineSuffix(CPU);
Builder.defineMacro("__ARM_ARCH_" + CPUArch + "__");
// Subtarget options.
@@ -2131,6 +2605,9 @@ public:
case 'P': // VFP Floating point register double precision
Info.setAllowsRegister();
return true;
+ case 'Q': // A memory address that is a single base register.
+ Info.setAllowsMemory();
+ return true;
case 'U': // a memory reference...
switch (Name[1]) {
case 'q': // ...ARMV4 ldrsb
@@ -2247,6 +2724,9 @@ public:
DarwinARMTargetInfo(const std::string& triple)
: DarwinTargetInfo<ARMTargetInfo>(triple) {
HasAlignMac68kSupport = true;
+ // iOS always has 64-bit atomic instructions.
+ // FIXME: This should be based off of the target features in ARMTargetInfo.
+ MaxAtomicInlineWidth = 64;
}
};
} // end anonymous namespace.
@@ -2592,6 +3072,12 @@ namespace {
// target processor and program binary. TCE co-design environment is
// publicly available in http://tce.cs.tut.fi
+ static const unsigned TCEOpenCLAddrSpaceMap[] = {
+ 3, // opencl_global
+ 4, // opencl_local
+ 5 // opencl_constant
+ };
+
class TCETargetInfo : public TargetInfo{
public:
TCETargetInfo(const std::string& triple) : TargetInfo(triple) {
@@ -2620,6 +3106,7 @@ namespace {
"i16:16:32-i32:32:32-i64:32:32-"
"f32:32:32-f64:32:32-v64:32:32-"
"v128:32:32-a0:0:32-n32";
+ AddrSpaceMap = &TCEOpenCLAddrSpaceMap;
}
virtual void getTargetDefines(const LangOptions &Opts,
@@ -2648,51 +3135,30 @@ namespace {
}
namespace {
-class MipsTargetInfo : public TargetInfo {
- std::string ABI, CPU;
- static const TargetInfo::GCCRegAlias GCCRegAliases[];
- static const char * const GCCRegNames[];
+class MipsTargetInfoBase : public TargetInfo {
+ std::string CPU;
+protected:
+ std::string ABI;
public:
- MipsTargetInfo(const std::string& triple) : TargetInfo(triple), ABI("o32") {
- DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-"
- "i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32";
+ MipsTargetInfoBase(const std::string& triple, const std::string& ABIStr)
+ : TargetInfo(triple), ABI(ABIStr) {
SizeType = UnsignedInt;
PtrDiffType = SignedInt;
}
virtual const char *getABI() const { return ABI.c_str(); }
- virtual bool setABI(const std::string &Name) {
-
- if ((Name == "o32") || (Name == "eabi")) {
- ABI = Name;
- return true;
- } else
- return false;
- }
+ virtual bool setABI(const std::string &Name) = 0;
virtual bool setCPU(const std::string &Name) {
CPU = Name;
return true;
}
- void getDefaultFeatures(const std::string &CPU,
- llvm::StringMap<bool> &Features) const {
+ void getDefaultFeatures(llvm::StringMap<bool> &Features) const {
Features[ABI] = true;
Features[CPU] = true;
}
virtual void getArchDefines(const LangOptions &Opts,
- MacroBuilder &Builder) const {
- if (ABI == "o32")
- Builder.defineMacro("__mips_o32");
- else if (ABI == "eabi")
- Builder.defineMacro("__mips_eabi");
- }
+ MacroBuilder &Builder) const = 0;
virtual void getTargetDefines(const LangOptions &Opts,
- MacroBuilder &Builder) const {
- DefineStd(Builder, "mips", Opts);
- Builder.defineMacro("_mips");
- DefineStd(Builder, "MIPSEB", Opts);
- Builder.defineMacro("_MIPSEB");
- Builder.defineMacro("__REGISTER_PREFIX__", "");
- getArchDefines(Opts, Builder);
- }
+ MacroBuilder &Builder) const = 0;
virtual void getTargetBuiltins(const Builtin::Info *&Records,
unsigned &NumRecords) const {
// FIXME: Implement!
@@ -2701,9 +3167,24 @@ public:
return "typedef void* __builtin_va_list;";
}
virtual void getGCCRegNames(const char * const *&Names,
- unsigned &NumNames) const;
+ unsigned &NumNames) const {
+ static const char * const GCCRegNames[] = {
+ "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
+ "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
+ "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
+ "$24", "$25", "$26", "$27", "$28", "$sp", "$fp", "$31",
+ "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7",
+ "$f8", "$f9", "$f10", "$f11", "$f12", "$f13", "$f14", "$f15",
+ "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",
+ "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31",
+ "hi", "lo", "", "$fcc0","$fcc1","$fcc2","$fcc3","$fcc4",
+ "$fcc5","$fcc6","$fcc7"
+ };
+ Names = GCCRegNames;
+ NumNames = llvm::array_lengthof(GCCRegNames);
+ }
virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
- unsigned &NumAliases) const;
+ unsigned &NumAliases) const = 0;
virtual bool validateAsmConstraint(const char *&Name,
TargetInfo::ConstraintInfo &Info) const {
switch (*Name) {
@@ -2724,89 +3205,296 @@ public:
}
};
-const char * const MipsTargetInfo::GCCRegNames[] = {
- "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
- "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
- "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
- "$24", "$25", "$26", "$27", "$28", "$sp", "$fp", "$31",
- "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7",
- "$f8", "$f9", "$f10", "$f11", "$f12", "$f13", "$f14", "$f15",
- "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",
- "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "$f30", "$f31",
- "hi", "lo", "", "$fcc0","$fcc1","$fcc2","$fcc3","$fcc4",
- "$fcc5","$fcc6","$fcc7"
+class Mips32TargetInfoBase : public MipsTargetInfoBase {
+public:
+ Mips32TargetInfoBase(const std::string& triple) :
+ MipsTargetInfoBase(triple, "o32") {}
+ virtual bool setABI(const std::string &Name) {
+ if ((Name == "o32") || (Name == "eabi")) {
+ ABI = Name;
+ return true;
+ } else
+ return false;
+ }
+ virtual void getArchDefines(const LangOptions &Opts,
+ MacroBuilder &Builder) const {
+ if (ABI == "o32") {
+ Builder.defineMacro("__mips_o32");
+ Builder.defineMacro("_ABIO32", "1");
+ Builder.defineMacro("_MIPS_SIM", "_ABIO32");
+ }
+ else if (ABI == "eabi")
+ Builder.defineMacro("__mips_eabi");
+ else
+ llvm_unreachable("Invalid ABI for Mips32.");
+ }
+ virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
+ unsigned &NumAliases) const {
+ static const TargetInfo::GCCRegAlias GCCRegAliases[] = {
+ { { "at" }, "$1" },
+ { { "v0" }, "$2" },
+ { { "v1" }, "$3" },
+ { { "a0" }, "$4" },
+ { { "a1" }, "$5" },
+ { { "a2" }, "$6" },
+ { { "a3" }, "$7" },
+ { { "t0" }, "$8" },
+ { { "t1" }, "$9" },
+ { { "t2" }, "$10" },
+ { { "t3" }, "$11" },
+ { { "t4" }, "$12" },
+ { { "t5" }, "$13" },
+ { { "t6" }, "$14" },
+ { { "t7" }, "$15" },
+ { { "s0" }, "$16" },
+ { { "s1" }, "$17" },
+ { { "s2" }, "$18" },
+ { { "s3" }, "$19" },
+ { { "s4" }, "$20" },
+ { { "s5" }, "$21" },
+ { { "s6" }, "$22" },
+ { { "s7" }, "$23" },
+ { { "t8" }, "$24" },
+ { { "t9" }, "$25" },
+ { { "k0" }, "$26" },
+ { { "k1" }, "$27" },
+ { { "gp" }, "$28" },
+ { { "sp" }, "$29" },
+ { { "fp" }, "$30" },
+ { { "ra" }, "$31" }
+ };
+ Aliases = GCCRegAliases;
+ NumAliases = llvm::array_lengthof(GCCRegAliases);
+ }
};
-void MipsTargetInfo::getGCCRegNames(const char * const *&Names,
- unsigned &NumNames) const {
- Names = GCCRegNames;
- NumNames = llvm::array_lengthof(GCCRegNames);
-}
+class Mips32EBTargetInfo : public Mips32TargetInfoBase {
+public:
+ Mips32EBTargetInfo(const std::string& triple) : Mips32TargetInfoBase(triple) {
+ DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-"
+ "i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32";
+ }
+ virtual void getTargetDefines(const LangOptions &Opts,
+ MacroBuilder &Builder) const {
+ DefineStd(Builder, "mips", Opts);
+ Builder.defineMacro("_mips");
+ DefineStd(Builder, "MIPSEB", Opts);
+ Builder.defineMacro("_MIPSEB");
+ Builder.defineMacro("__REGISTER_PREFIX__", "");
+ getArchDefines(Opts, Builder);
+ }
+};
-const TargetInfo::GCCRegAlias MipsTargetInfo::GCCRegAliases[] = {
- { { "at" }, "$1" },
- { { "v0" }, "$2" },
- { { "v1" }, "$3" },
- { { "a0" }, "$4" },
- { { "a1" }, "$5" },
- { { "a2" }, "$6" },
- { { "a3" }, "$7" },
- { { "t0" }, "$8" },
- { { "t1" }, "$9" },
- { { "t2" }, "$10" },
- { { "t3" }, "$11" },
- { { "t4" }, "$12" },
- { { "t5" }, "$13" },
- { { "t6" }, "$14" },
- { { "t7" }, "$15" },
- { { "s0" }, "$16" },
- { { "s1" }, "$17" },
- { { "s2" }, "$18" },
- { { "s3" }, "$19" },
- { { "s4" }, "$20" },
- { { "s5" }, "$21" },
- { { "s6" }, "$22" },
- { { "s7" }, "$23" },
- { { "t8" }, "$24" },
- { { "t9" }, "$25" },
- { { "k0" }, "$26" },
- { { "k1" }, "$27" },
- { { "gp" }, "$28" },
- { { "sp" }, "$29" },
- { { "fp" }, "$30" },
- { { "ra" }, "$31" }
+class Mips32ELTargetInfo : public Mips32TargetInfoBase {
+public:
+ Mips32ELTargetInfo(const std::string& triple) : Mips32TargetInfoBase(triple) {
+ DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-"
+ "i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32";
+ }
+ virtual void getTargetDefines(const LangOptions &Opts,
+ MacroBuilder &Builder) const {
+ DefineStd(Builder, "mips", Opts);
+ Builder.defineMacro("_mips");
+ DefineStd(Builder, "MIPSEL", Opts);
+ Builder.defineMacro("_MIPSEL");
+ Builder.defineMacro("__REGISTER_PREFIX__", "");
+ getArchDefines(Opts, Builder);
+ }
};
-void MipsTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
- unsigned &NumAliases) const {
- Aliases = GCCRegAliases;
- NumAliases = llvm::array_lengthof(GCCRegAliases);
-}
+class Mips64TargetInfoBase : public MipsTargetInfoBase {
+ virtual void SetDescriptionString(const std::string &Name) = 0;
+public:
+ Mips64TargetInfoBase(const std::string& triple) :
+ MipsTargetInfoBase(triple, "n64") {}
+ virtual bool setABI(const std::string &Name) {
+ SetDescriptionString(Name);
+ if ((Name == "n32") || (Name == "n64")) {
+ ABI = Name;
+ return true;
+ } else
+ return false;
+ }
+ virtual void getArchDefines(const LangOptions &Opts,
+ MacroBuilder &Builder) const {
+ if (ABI == "n32") {
+ Builder.defineMacro("__mips_n32");
+ Builder.defineMacro("_ABIN32", "2");
+ Builder.defineMacro("_MIPS_SIM", "_ABIN32");
+ }
+ else if (ABI == "n64") {
+ Builder.defineMacro("__mips_n64");
+ Builder.defineMacro("_ABI64", "3");
+ Builder.defineMacro("_MIPS_SIM", "_ABI64");
+ }
+ else
+ llvm_unreachable("Invalid ABI for Mips64.");
+ }
+ virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
+ unsigned &NumAliases) const {
+ static const TargetInfo::GCCRegAlias GCCRegAliases[] = {
+ { { "at" }, "$1" },
+ { { "v0" }, "$2" },
+ { { "v1" }, "$3" },
+ { { "a0" }, "$4" },
+ { { "a1" }, "$5" },
+ { { "a2" }, "$6" },
+ { { "a3" }, "$7" },
+ { { "a4" }, "$8" },
+ { { "a5" }, "$9" },
+ { { "a6" }, "$10" },
+ { { "a7" }, "$11" },
+ { { "t0" }, "$12" },
+ { { "t1" }, "$13" },
+ { { "t2" }, "$14" },
+ { { "t3" }, "$15" },
+ { { "s0" }, "$16" },
+ { { "s1" }, "$17" },
+ { { "s2" }, "$18" },
+ { { "s3" }, "$19" },
+ { { "s4" }, "$20" },
+ { { "s5" }, "$21" },
+ { { "s6" }, "$22" },
+ { { "s7" }, "$23" },
+ { { "t8" }, "$24" },
+ { { "t9" }, "$25" },
+ { { "k0" }, "$26" },
+ { { "k1" }, "$27" },
+ { { "gp" }, "$28" },
+ { { "sp" }, "$29" },
+ { { "fp" }, "$30" },
+ { { "ra" }, "$31" }
+ };
+ Aliases = GCCRegAliases;
+ NumAliases = llvm::array_lengthof(GCCRegAliases);
+ }
+};
+
+class Mips64EBTargetInfo : public Mips64TargetInfoBase {
+ virtual void SetDescriptionString(const std::string &Name) {
+ // Change DescriptionString only if ABI is n32.
+ if (Name == "n32")
+ DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-"
+ "i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32";
+ }
+public:
+ Mips64EBTargetInfo(const std::string& triple) : Mips64TargetInfoBase(triple) {
+ // Default ABI is n64.
+ DescriptionString = "E-p:64:64:64-i1:8:8-i8:8:32-i16:16:32-i32:32:32-"
+ "i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32";
+ }
+ virtual void getTargetDefines(const LangOptions &Opts,
+ MacroBuilder &Builder) const {
+ DefineStd(Builder, "mips", Opts);
+ Builder.defineMacro("_mips");
+ DefineStd(Builder, "MIPSEB", Opts);
+ Builder.defineMacro("_MIPSEB");
+ Builder.defineMacro("__REGISTER_PREFIX__", "");
+ getArchDefines(Opts, Builder);
+ }
+};
+
+class Mips64ELTargetInfo : public Mips64TargetInfoBase {
+ virtual void SetDescriptionString(const std::string &Name) {
+ // Change DescriptionString only if ABI is n32.
+ if (Name == "n32")
+ DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-"
+ "i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32";
+ }
+public:
+ Mips64ELTargetInfo(const std::string& triple) : Mips64TargetInfoBase(triple) {
+ // Default ABI is n64.
+ DescriptionString = "e-p:64:64:64-i1:8:8-i8:8:32-i16:16:32-i32:32:32-"
+ "i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32";
+ }
+ virtual void getTargetDefines(const LangOptions &Opts,
+ MacroBuilder &Builder) const {
+ DefineStd(Builder, "mips", Opts);
+ Builder.defineMacro("_mips");
+ DefineStd(Builder, "MIPSEL", Opts);
+ Builder.defineMacro("_MIPSEL");
+ Builder.defineMacro("__REGISTER_PREFIX__", "");
+ getArchDefines(Opts, Builder);
+ }
+};
} // end anonymous namespace.
namespace {
-class MipselTargetInfo : public MipsTargetInfo {
+class PNaClTargetInfo : public TargetInfo {
public:
- MipselTargetInfo(const std::string& triple) : MipsTargetInfo(triple) {
- DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:32-i16:16:32-i32:32:32-"
- "i64:64:64-f32:32:32-f64:64:64-v64:64:64-n32";
+ PNaClTargetInfo(const std::string& triple) : TargetInfo(triple) {
+ this->UserLabelPrefix = "";
+ this->LongAlign = 32;
+ this->LongWidth = 32;
+ this->PointerAlign = 32;
+ this->PointerWidth = 32;
+ this->IntMaxType = TargetInfo::SignedLongLong;
+ this->UIntMaxType = TargetInfo::UnsignedLongLong;
+ this->Int64Type = TargetInfo::SignedLongLong;
+ this->DoubleAlign = 64;
+ this->LongDoubleWidth = 64;
+ this->LongDoubleAlign = 64;
+ this->SizeType = TargetInfo::UnsignedInt;
+ this->PtrDiffType = TargetInfo::SignedInt;
+ this->IntPtrType = TargetInfo::SignedInt;
+ this->RegParmMax = 2;
+ DescriptionString = "e-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-"
+ "f32:32:32-f64:64:64-p:32:32:32-v128:32:32";
}
+ void getDefaultFeatures(llvm::StringMap<bool> &Features) const {
+ }
+ virtual void getArchDefines(const LangOptions &Opts,
+ MacroBuilder &Builder) const {
+ Builder.defineMacro("__le32__");
+ Builder.defineMacro("__pnacl__");
+ }
virtual void getTargetDefines(const LangOptions &Opts,
- MacroBuilder &Builder) const;
+ MacroBuilder &Builder) const {
+ DefineStd(Builder, "unix", Opts);
+ Builder.defineMacro("__ELF__");
+ if (Opts.POSIXThreads)
+ Builder.defineMacro("_REENTRANT");
+ if (Opts.CPlusPlus)
+ Builder.defineMacro("_GNU_SOURCE");
+
+ Builder.defineMacro("__native_client__");
+ getArchDefines(Opts, Builder);
+ }
+ virtual void getTargetBuiltins(const Builtin::Info *&Records,
+ unsigned &NumRecords) const {
+ }
+ virtual const char *getVAListDeclaration() const {
+ return "typedef int __builtin_va_list[4];";
+ }
+ virtual void getGCCRegNames(const char * const *&Names,
+ unsigned &NumNames) const;
+ virtual void getGCCRegAliases(const GCCRegAlias *&Aliases,
+ unsigned &NumAliases) const;
+ virtual bool validateAsmConstraint(const char *&Name,
+ TargetInfo::ConstraintInfo &Info) const {
+ return false;
+ }
+
+ virtual const char *getClobbers() const {
+ return "";
+ }
};
-void MipselTargetInfo::getTargetDefines(const LangOptions &Opts,
- MacroBuilder &Builder) const {
- DefineStd(Builder, "mips", Opts);
- Builder.defineMacro("_mips");
- DefineStd(Builder, "MIPSEL", Opts);
- Builder.defineMacro("_MIPSEL");
- Builder.defineMacro("__REGISTER_PREFIX__", "");
- getArchDefines(Opts, Builder);
+void PNaClTargetInfo::getGCCRegNames(const char * const *&Names,
+ unsigned &NumNames) const {
+ Names = NULL;
+ NumNames = 0;
+}
+
+void PNaClTargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases,
+ unsigned &NumAliases) const {
+ Aliases = NULL;
+ NumAliases = 0;
}
} // end anonymous namespace.
+
//===----------------------------------------------------------------------===//
// Driver code
//===----------------------------------------------------------------------===//
@@ -2847,40 +3535,74 @@ static TargetInfo *AllocateTarget(const std::string &T) {
case llvm::Triple::mips:
switch (os) {
- case llvm::Triple::Psp:
- return new PSPTargetInfo<MipsTargetInfo>(T);
case llvm::Triple::Linux:
- return new LinuxTargetInfo<MipsTargetInfo>(T);
+ return new LinuxTargetInfo<Mips32EBTargetInfo>(T);
case llvm::Triple::RTEMS:
- return new RTEMSTargetInfo<MipsTargetInfo>(T);
+ return new RTEMSTargetInfo<Mips32EBTargetInfo>(T);
case llvm::Triple::FreeBSD:
- return new FreeBSDTargetInfo<MipsTargetInfo>(T);
+ return new FreeBSDTargetInfo<Mips32EBTargetInfo>(T);
case llvm::Triple::NetBSD:
- return new NetBSDTargetInfo<MipsTargetInfo>(T);
+ return new NetBSDTargetInfo<Mips32EBTargetInfo>(T);
default:
- return new MipsTargetInfo(T);
+ return new Mips32EBTargetInfo(T);
}
case llvm::Triple::mipsel:
switch (os) {
- case llvm::Triple::Psp:
- return new PSPTargetInfo<MipselTargetInfo>(T);
case llvm::Triple::Linux:
- return new LinuxTargetInfo<MipselTargetInfo>(T);
+ return new LinuxTargetInfo<Mips32ELTargetInfo>(T);
case llvm::Triple::RTEMS:
- return new RTEMSTargetInfo<MipselTargetInfo>(T);
+ return new RTEMSTargetInfo<Mips32ELTargetInfo>(T);
case llvm::Triple::FreeBSD:
- return new FreeBSDTargetInfo<MipselTargetInfo>(T);
+ return new FreeBSDTargetInfo<Mips32ELTargetInfo>(T);
case llvm::Triple::NetBSD:
- return new NetBSDTargetInfo<MipselTargetInfo>(T);
+ return new NetBSDTargetInfo<Mips32ELTargetInfo>(T);
default:
- return new MipsTargetInfo(T);
+ return new Mips32ELTargetInfo(T);
+ }
+
+ case llvm::Triple::mips64:
+ switch (os) {
+ case llvm::Triple::Linux:
+ return new LinuxTargetInfo<Mips64EBTargetInfo>(T);
+ case llvm::Triple::RTEMS:
+ return new RTEMSTargetInfo<Mips64EBTargetInfo>(T);
+ case llvm::Triple::FreeBSD:
+ return new FreeBSDTargetInfo<Mips64EBTargetInfo>(T);
+ case llvm::Triple::NetBSD:
+ return new NetBSDTargetInfo<Mips64EBTargetInfo>(T);
+ default:
+ return new Mips64EBTargetInfo(T);
+ }
+
+ case llvm::Triple::mips64el:
+ switch (os) {
+ case llvm::Triple::Linux:
+ return new LinuxTargetInfo<Mips64ELTargetInfo>(T);
+ case llvm::Triple::RTEMS:
+ return new RTEMSTargetInfo<Mips64ELTargetInfo>(T);
+ case llvm::Triple::FreeBSD:
+ return new FreeBSDTargetInfo<Mips64ELTargetInfo>(T);
+ case llvm::Triple::NetBSD:
+ return new NetBSDTargetInfo<Mips64ELTargetInfo>(T);
+ default:
+ return new Mips64ELTargetInfo(T);
+ }
+
+ case llvm::Triple::le32:
+ switch (os) {
+ case llvm::Triple::NativeClient:
+ return new PNaClTargetInfo(T);
+ default:
+ return NULL;
}
case llvm::Triple::ppc:
if (Triple.isOSDarwin())
return new DarwinPPC32TargetInfo(T);
switch (os) {
+ case llvm::Triple::Linux:
+ return new LinuxTargetInfo<PPC32TargetInfo>(T);
case llvm::Triple::FreeBSD:
return new FreeBSDTargetInfo<PPC32TargetInfo>(T);
case llvm::Triple::NetBSD:
@@ -2895,6 +3617,8 @@ static TargetInfo *AllocateTarget(const std::string &T) {
if (Triple.isOSDarwin())
return new DarwinPPC64TargetInfo(T);
switch (os) {
+ case llvm::Triple::Linux:
+ return new LinuxTargetInfo<PPC64TargetInfo>(T);
case llvm::Triple::Lv2:
return new PS3PPUTargetInfo<PPC64TargetInfo>(T);
case llvm::Triple::FreeBSD:
@@ -2915,6 +3639,8 @@ static TargetInfo *AllocateTarget(const std::string &T) {
case llvm::Triple::sparc:
switch (os) {
+ case llvm::Triple::Linux:
+ return new LinuxTargetInfo<SparcV8TargetInfo>(T);
case llvm::Triple::AuroraUX:
return new AuroraUXSparcV8TargetInfo(T);
case llvm::Triple::Solaris:
@@ -3003,7 +3729,7 @@ static TargetInfo *AllocateTarget(const std::string &T) {
/// CreateTargetInfo - Return the target info object for the specified target
/// triple.
-TargetInfo *TargetInfo::CreateTargetInfo(Diagnostic &Diags,
+TargetInfo *TargetInfo::CreateTargetInfo(DiagnosticsEngine &Diags,
TargetOptions &Opts) {
llvm::Triple Triple(Opts.Triple);
@@ -3035,7 +3761,7 @@ TargetInfo *TargetInfo::CreateTargetInfo(Diagnostic &Diags,
// Compute the default target features, we need the target to handle this
// because features may have dependencies on one another.
llvm::StringMap<bool> Features;
- Target->getDefaultFeatures(Opts.CPU, Features);
+ Target->getDefaultFeatures(Features);
// Apply the user specified deltas.
for (std::vector<std::string>::const_iterator it = Opts.Features.begin(),
diff --git a/contrib/llvm/tools/clang/lib/Basic/Version.cpp b/contrib/llvm/tools/clang/lib/Basic/Version.cpp
index 89076ca..390a685 100644
--- a/contrib/llvm/tools/clang/lib/Basic/Version.cpp
+++ b/contrib/llvm/tools/clang/lib/Basic/Version.cpp
@@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//
#include "clang/Basic/Version.h"
+#include "clang/Basic/LLVM.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Config/config.h"
#include <cstring>
@@ -24,14 +25,14 @@ std::string getClangRepositoryPath() {
return CLANG_REPOSITORY_STRING;
#else
#ifdef SVN_REPOSITORY
- llvm::StringRef URL(SVN_REPOSITORY);
+ StringRef URL(SVN_REPOSITORY);
#else
- llvm::StringRef URL("");
+ StringRef URL("");
#endif
// If the SVN_REPOSITORY is empty, try to use the SVN keyword. This helps us
// pick up a tag in an SVN export, for example.
- static llvm::StringRef SVNRepository("$URL: http://llvm.org/svn/llvm-project/cfe/trunk/lib/Basic/Version.cpp $");
+ static StringRef SVNRepository("$URL: http://llvm.org/svn/llvm-project/cfe/branches/release_30/lib/Basic/Version.cpp $");
if (URL.empty()) {
URL = SVNRepository.slice(SVNRepository.find(':'),
SVNRepository.find("/lib/Basic"));
@@ -42,7 +43,7 @@ std::string getClangRepositoryPath() {
// Trim path prefix off, assuming path came from standard cfe path.
size_t Start = URL.find("cfe/");
- if (Start != llvm::StringRef::npos)
+ if (Start != StringRef::npos)
URL = URL.substr(Start + 4);
return URL;
diff --git a/contrib/llvm/tools/clang/lib/Basic/VersionTuple.cpp b/contrib/llvm/tools/clang/lib/Basic/VersionTuple.cpp
index d5cf126..77aad39 100644
--- a/contrib/llvm/tools/clang/lib/Basic/VersionTuple.cpp
+++ b/contrib/llvm/tools/clang/lib/Basic/VersionTuple.cpp
@@ -25,7 +25,7 @@ std::string VersionTuple::getAsString() const {
return Result;
}
-llvm::raw_ostream& clang::operator<<(llvm::raw_ostream &Out,
+raw_ostream& clang::operator<<(raw_ostream &Out,
const VersionTuple &V) {
Out << V.getMajor();
if (llvm::Optional<unsigned> Minor = V.getMinor())
OpenPOWER on IntegriCloud