summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--AST/Builtins.cpp11
-rw-r--r--AST/TranslationUnit.cpp4
-rw-r--r--Basic/IdentifierTable.cpp8
-rw-r--r--Basic/TargetInfo.cpp227
-rw-r--r--Basic/Targets.cpp63
-rw-r--r--Driver/clang.cpp15
-rw-r--r--Lex/MacroInfo.cpp3
-rw-r--r--Lex/PPExpressions.cpp17
-rw-r--r--Lex/Preprocessor.cpp82
-rw-r--r--NOTES.txt120
-rw-r--r--Sema/SemaDecl.cpp9
-rw-r--r--include/clang/Basic/DiagnosticKinds.def13
-rw-r--r--include/clang/Basic/IdentifierTable.h16
-rw-r--r--include/clang/Basic/TargetInfo.h69
-rw-r--r--include/clang/Basic/TokenKinds.def5
-rw-r--r--include/clang/Lex/MacroInfo.h10
-rw-r--r--include/clang/Lex/Preprocessor.h3
-rw-r--r--test/Parser/portability.c5
18 files changed, 60 insertions, 620 deletions
diff --git a/AST/Builtins.cpp b/AST/Builtins.cpp
index 9781c5e944..e2bf5ca007 100644
--- a/AST/Builtins.cpp
+++ b/AST/Builtins.cpp
@@ -40,17 +40,12 @@ void Builtin::Context::InitializeBuiltins(IdentifierTable &Table,
for (unsigned i = Builtin::NotBuiltin+1; i != Builtin::FirstTSBuiltin; ++i)
Table.get(BuiltinInfo[i].Name).setBuiltinID(i);
- // Step #2: handle target builtins.
- std::vector<const char *> NonPortableBuiltins;
- Target.getTargetBuiltins(TSRecords, NumTSRecords, NonPortableBuiltins);
+ // Step #2: Get target builtins.
+ Target.getTargetBuiltins(TSRecords, NumTSRecords);
- // Step #2a: Register target-specific builtins.
+ // Step #3: Register target-specific builtins.
for (unsigned i = 0, e = NumTSRecords; i != e; ++i)
Table.get(TSRecords[i].Name).setBuiltinID(i+Builtin::FirstTSBuiltin);
-
- // Step #2b: Mark non-portable builtins as such.
- for (unsigned i = 0, e = NonPortableBuiltins.size(); i != e; ++i)
- Table.get(NonPortableBuiltins[i]).setNonPortableBuiltin(true);
}
/// DecodeTypeFromStr - This decodes one type descriptor from Str, advancing the
diff --git a/AST/TranslationUnit.cpp b/AST/TranslationUnit.cpp
index c00b344ff8..b91448b2d3 100644
--- a/AST/TranslationUnit.cpp
+++ b/AST/TranslationUnit.cpp
@@ -191,9 +191,7 @@ TranslationUnit* TranslationUnit::Create(llvm::Deserializer& Dezr,
{ // Read the TargetInfo.
llvm::SerializedPtrID PtrID = Dezr.ReadPtrID();
char* triple = Dezr.ReadCStr(NULL,0,true);
- std::string Triple(triple);
- Dezr.RegisterPtr(PtrID,TargetInfo::CreateTargetInfo(&Triple,
- &Triple+1));
+ Dezr.RegisterPtr(PtrID,TargetInfo::CreateTargetInfo(std::string(triple)));
delete [] triple;
}
diff --git a/Basic/IdentifierTable.cpp b/Basic/IdentifierTable.cpp
index 45d888140a..65e984a0f7 100644
--- a/Basic/IdentifierTable.cpp
+++ b/Basic/IdentifierTable.cpp
@@ -32,9 +32,7 @@ IdentifierInfo::IdentifierInfo() {
HasMacro = false;
IsExtension = false;
IsPoisoned = false;
- IsOtherTargetMacro = false;
IsCPPOperatorKeyword = false;
- IsNonPortableBuiltin = false;
FETokenInfo = 0;
}
@@ -203,8 +201,6 @@ tok::PPKeywordKind IdentifierInfo::getPPKeywordID() const {
CASE( 8, 'u', 'a', unassert);
CASE(12, 'i', 'c', include_next);
- CASE(13, 'd', 'f', define_target);
- CASE(19, 'd', 'f', define_other_target);
#undef CASE
#undef HASH
}
@@ -406,9 +402,7 @@ void IdentifierInfo::Emit(llvm::Serializer& S) const {
S.EmitBool(hasMacroDefinition());
S.EmitBool(isExtensionToken());
S.EmitBool(isPoisoned());
- S.EmitBool(isOtherTargetMacro());
S.EmitBool(isCPlusPlusOperatorKeyword());
- S.EmitBool(isNonPortableBuiltin());
// FIXME: FETokenInfo
}
@@ -419,9 +413,7 @@ void IdentifierInfo::Read(llvm::Deserializer& D) {
setHasMacroDefinition(D.ReadBool());
setIsExtensionToken(D.ReadBool());
setIsPoisoned(D.ReadBool());
- setIsOtherTargetMacro(D.ReadBool());
setIsCPlusPlusOperatorKeyword(D.ReadBool());
- setNonPortableBuiltin(D.ReadBool());
// FIXME: FETokenInfo
}
diff --git a/Basic/TargetInfo.cpp b/Basic/TargetInfo.cpp
index 15472a473c..8701b38a0f 100644
--- a/Basic/TargetInfo.cpp
+++ b/Basic/TargetInfo.cpp
@@ -54,167 +54,28 @@ void TargetInfo::getLongDoubleInfo(uint64_t &Size, unsigned &Align,
//===----------------------------------------------------------------------===//
TargetInfo::~TargetInfo() {
- delete PrimaryTarget;
- for (unsigned i = 0; i < SecondaryTargets.size(); ++i)
- delete SecondaryTargets[i];
+ delete Target;
}
const char* TargetInfo::getTargetTriple() const {
- return PrimaryTarget->getTargetTriple();
+ return Target->getTargetTriple();
}
const char *TargetInfo::getTargetPrefix() const {
- return PrimaryTarget->getTargetPrefix();
-}
-
-/// DiagnoseNonPortability - When a use of a non-portable target feature is
-/// used, this method emits the diagnostic and marks the translation unit as
-/// non-portable.
-void TargetInfo::DiagnoseNonPortability(FullSourceLoc Loc,
- unsigned DiagKind) {
- NonPortable = true;
- if (Diag && Loc.isValid()) Diag->Report(Loc, DiagKind);
-}
-
-/// GetTargetDefineMap - Get the set of target #defines in an associative
-/// collection for easy lookup.
-static void GetTargetDefineMap(const TargetInfoImpl *Target,
- llvm::StringMap<std::string> &Map) {
- std::vector<char> Defines;
- Defines.reserve(4096);
- Target->getTargetDefines(Defines);
-
- for (const char *DefStr = &Defines[0], *E = DefStr+Defines.size();
- DefStr != E;) {
- // Skip the '#define ' portion.
- assert(memcmp(DefStr, "#define ", strlen("#define ")) == 0 &&
- "#define didn't start with #define!");
- DefStr += strlen("#define ");
-
- // Find the divider between the key and value.
- const char *SpacePos = strchr(DefStr, ' ');
-
- std::string &Entry = Map.GetOrCreateValue(DefStr, SpacePos).getValue();
-
- const char *EndPos = strchr(SpacePos+1, '\n');
- Entry = std::string(SpacePos+1, EndPos);
- DefStr = EndPos+1;
- }
+ return Target->getTargetPrefix();
}
/// getTargetDefines - Appends the target-specific #define values for this
/// target set to the specified buffer.
void TargetInfo::getTargetDefines(std::vector<char> &Buffer) {
- // If we have no secondary targets, be a bit more efficient.
- if (SecondaryTargets.empty()) {
- PrimaryTarget->getTargetDefines(Buffer);
- return;
- }
-
- // This is tricky in the face of secondary targets. Specifically,
- // target-specific #defines that are present and identical across all
- // secondary targets are turned into #defines, #defines that are present in
- // the primary target but are missing or different in the secondary targets
- // are turned into #define_target, and #defines that are not defined in the
- // primary, but are defined in a secondary are turned into
- // #define_other_target. This allows the preprocessor to correctly track uses
- // of target-specific macros.
-
- // Get the set of primary #defines.
- llvm::StringMap<std::string> PrimaryDefines;
- GetTargetDefineMap(PrimaryTarget, PrimaryDefines);
-
- // Get the sets of secondary #defines.
- llvm::StringMap<std::string> *SecondaryDefines
- = new llvm::StringMap<std::string>[SecondaryTargets.size()];
- for (unsigned i = 0, e = SecondaryTargets.size(); i != e; ++i)
- GetTargetDefineMap(SecondaryTargets[i], SecondaryDefines[i]);
-
- // Loop over all defines in the primary target, processing them until we run
- // out.
- for (llvm::StringMap<std::string>::iterator PDI =
- PrimaryDefines.begin(), E = PrimaryDefines.end(); PDI != E; ++PDI) {
- std::string DefineName(PDI->getKeyData(),
- PDI->getKeyData() + PDI->getKeyLength());
- std::string DefineValue = PDI->getValue();
-
- // Check to see whether all secondary targets have this #define and whether
- // it is to the same value. Remember if not, but remove the #define from
- // their collection in any case if they have it.
- bool isPortable = true;
-
- for (unsigned i = 0, e = SecondaryTargets.size(); i != e; ++i) {
- llvm::StringMap<std::string>::iterator I =
- SecondaryDefines[i].find(&DefineName[0],
- &DefineName[0]+DefineName.size());
- if (I == SecondaryDefines[i].end()) {
- // Secondary target doesn't have this #define.
- isPortable = false;
- } else {
- // Secondary target has this define, remember if it disagrees.
- if (isPortable)
- isPortable = I->getValue() == DefineValue;
- // Remove it from the secondary target unconditionally.
- SecondaryDefines[i].erase(I);
- }
- }
-
- // If this define is non-portable, turn it into #define_target, otherwise
- // just use #define.
- const char *Command = isPortable ? "#define " : "#define_target ";
- Buffer.insert(Buffer.end(), Command, Command+strlen(Command));
-
- // Insert "defname defvalue\n".
- Buffer.insert(Buffer.end(), DefineName.begin(), DefineName.end());
- Buffer.push_back(' ');
- Buffer.insert(Buffer.end(), DefineValue.begin(), DefineValue.end());
- Buffer.push_back('\n');
- }
-
- // Now that all of the primary target's defines have been handled and removed
- // from the secondary target's define sets, go through the remaining secondary
- // target's #defines and taint them.
- for (unsigned i = 0, e = SecondaryTargets.size(); i != e; ++i) {
- llvm::StringMap<std::string> &Defs = SecondaryDefines[i];
- while (!Defs.empty()) {
- const char *DefStart = Defs.begin()->getKeyData();
- const char *DefEnd = DefStart + Defs.begin()->getKeyLength();
-
- // Insert "#define_other_target defname".
- const char *Command = "#define_other_target ";
- Buffer.insert(Buffer.end(), Command, Command+strlen(Command));
- Buffer.insert(Buffer.end(), DefStart, DefEnd);
- Buffer.push_back('\n');
-
- // If any other secondary targets have this same define, remove it from
- // them to avoid duplicate #define_other_target directives.
- for (unsigned j = i+1; j != e; ++j) {
- llvm::StringMap<std::string>::iterator I =
- SecondaryDefines[j].find(DefStart, DefEnd);
- if (I != SecondaryDefines[j].end())
- SecondaryDefines[j].erase(I);
- }
- Defs.erase(Defs.begin());
- }
- }
-
- delete[] SecondaryDefines;
+ Target->getTargetDefines(Buffer);
}
/// ComputeWCharWidth - Determine the width of the wchar_t type for the primary
/// target, diagnosing whether this is non-portable across the secondary
/// targets.
void TargetInfo::ComputeWCharInfo(FullSourceLoc Loc) {
- PrimaryTarget->getWCharInfo(WCharWidth, WCharAlign);
-
- // Check whether this is portable across the secondary targets if the T-U is
- // portable so far.
- for (unsigned i = 0, e = SecondaryTargets.size(); i != e; ++i) {
- unsigned Width, Align;
- SecondaryTargets[i]->getWCharInfo(Width, Align);
- if (Width != WCharWidth || Align != WCharAlign)
- return DiagnoseNonPortability(Loc, diag::port_wchar_t);
- }
+ Target->getWCharInfo(WCharWidth, WCharAlign);
}
@@ -222,69 +83,18 @@ void TargetInfo::ComputeWCharInfo(FullSourceLoc Loc) {
/// the current primary target, and info about which builtins are non-portable
/// across the current set of primary and secondary targets.
void TargetInfo::getTargetBuiltins(const Builtin::Info *&Records,
- unsigned &NumRecords,
- std::vector<const char *> &NPortable) const {
+ unsigned &NumRecords) const {
// Get info about what actual builtins we will expose.
- PrimaryTarget->getTargetBuiltins(Records, NumRecords);
- if (SecondaryTargets.empty()) return;
-
- // Compute the set of non-portable builtins.
-
- // Start by computing a mapping from the primary target's builtins to their
- // info records for efficient lookup.
- llvm::StringMap<const Builtin::Info*> PrimaryRecs;
- for (unsigned i = 0, e = NumRecords; i != e; ++i) {
- const char *BIName = Records[i].Name;
- PrimaryRecs.GetOrCreateValue(BIName, BIName+strlen(BIName)).getValue()
- = Records+i;
- }
-
- for (unsigned i = 0, e = SecondaryTargets.size(); i != e; ++i) {
- // Get the builtins for this secondary target.
- const Builtin::Info *Records2nd;
- unsigned NumRecords2nd;
- SecondaryTargets[i]->getTargetBuiltins(Records2nd, NumRecords2nd);
-
- // Remember all of the secondary builtin names.
- std::set<std::string> BuiltinNames2nd;
-
- for (unsigned j = 0, e = NumRecords2nd; j != e; ++j) {
- BuiltinNames2nd.insert(Records2nd[j].Name);
-
- // Check to see if the primary target has this builtin.
- llvm::StringMap<const Builtin::Info*>::iterator I =
- PrimaryRecs.find(Records2nd[j].Name,
- Records2nd[j].Name+strlen(Records2nd[j].Name));
- if (I != PrimaryRecs.end()) {
- const Builtin::Info *PrimBI = I->getValue();
- // If does. If they are not identical, mark the builtin as being
- // non-portable.
- if (Records2nd[j] != *PrimBI)
- NPortable.push_back(PrimBI->Name);
- } else {
- // The primary target doesn't have this, it is non-portable.
- NPortable.push_back(Records2nd[j].Name);
- }
- }
-
- // Now that we checked all the secondary builtins, check to see if the
- // primary target has any builtins that the secondary one doesn't. If so,
- // then those are non-portable.
- for (unsigned j = 0, e = NumRecords; j != e; ++j) {
- if (!BuiltinNames2nd.count(Records[j].Name))
- NPortable.push_back(Records[j].Name);
- }
- }
+ Target->getTargetBuiltins(Records, NumRecords);
}
/// getVAListDeclaration - Return the declaration to use for
/// __builtin_va_list, which is target-specific.
const char *TargetInfo::getVAListDeclaration() const {
- return PrimaryTarget->getVAListDeclaration();
+ return Target->getVAListDeclaration();
}
-static void removeGCCRegisterPrefix(const char *&Name)
-{
+static void removeGCCRegisterPrefix(const char *&Name) {
if (Name[0] == '%' || Name[0] == '#')
Name++;
}
@@ -304,7 +114,7 @@ bool TargetInfo::isValidGCCRegisterName(const char *Name) const {
strcmp(Name, "cc") == 0)
return true;
- PrimaryTarget->getGCCRegNames(Names, NumNames);
+ Target->getGCCRegNames(Names, NumNames);
// If we have a number it maps to an entry in the register name array.
if (isdigit(Name[0])) {
@@ -324,7 +134,7 @@ bool TargetInfo::isValidGCCRegisterName(const char *Name) const {
const TargetInfoImpl::GCCRegAlias *Aliases;
unsigned NumAliases;
- PrimaryTarget->getGCCRegAliases(Aliases, NumAliases);
+ Target->getGCCRegAliases(Aliases, NumAliases);
for (unsigned i = 0; i < NumAliases; i++) {
for (unsigned j = 0 ; j < llvm::array_lengthof(Aliases[i].Aliases); j++) {
if (!Aliases[i].Aliases[j])
@@ -346,7 +156,7 @@ const char *TargetInfo::getNormalizedGCCRegisterName(const char *Name) const
const char * const *Names;
unsigned NumNames;
- PrimaryTarget->getGCCRegNames(Names, NumNames);
+ Target->getGCCRegNames(Names, NumNames);
// First, check if we have a number.
if (isdigit(Name[0])) {
@@ -363,7 +173,7 @@ const char *TargetInfo::getNormalizedGCCRegisterName(const char *Name) const
const TargetInfoImpl::GCCRegAlias *Aliases;
unsigned NumAliases;
- PrimaryTarget->getGCCRegAliases(Aliases, NumAliases);
+ Target->getGCCRegAliases(Aliases, NumAliases);
for (unsigned i = 0; i < NumAliases; i++) {
for (unsigned j = 0 ; j < llvm::array_lengthof(Aliases[i].Aliases); j++) {
if (!Aliases[i].Aliases[j])
@@ -392,7 +202,7 @@ bool TargetInfo::validateOutputConstraint(const char *Name,
while (*Name) {
switch (*Name) {
default:
- if (!PrimaryTarget->validateAsmConstraint(*Name, info)) {
+ if (!Target->validateAsmConstraint(*Name, info)) {
// FIXME: This assert is in place temporarily
// so we can add more constraints as we hit it.
// Eventually, an unknown constraint should just be treated as 'g'.
@@ -431,7 +241,7 @@ bool TargetInfo::validateInputConstraint(const char *Name,
// Check if matching constraint is out of bounds.
if (i >= NumOutputs)
return false;
- } else if (!PrimaryTarget->validateAsmConstraint(*Name, info)) {
+ } else if (!Target->validateAsmConstraint(*Name, info)) {
// FIXME: This assert is in place temporarily
// so we can add more constraints as we hit it.
// Eventually, an unknown constraint should just be treated as 'g'.
@@ -461,12 +271,11 @@ bool TargetInfo::validateInputConstraint(const char *Name,
}
std::string TargetInfo::convertConstraint(const char Constraint) const {
- return PrimaryTarget->convertConstraint(Constraint);
+ return Target->convertConstraint(Constraint);
}
-const char *TargetInfo::getClobbers() const
-{
- return PrimaryTarget->getClobbers();
+const char *TargetInfo::getClobbers() const {
+ return Target->getClobbers();
}
diff --git a/Basic/Targets.cpp b/Basic/Targets.cpp
index 7d64942b4f..d170fbefb6 100644
--- a/Basic/Targets.cpp
+++ b/Basic/Targets.cpp
@@ -776,54 +776,27 @@ static inline bool IsX86(const std::string& TT) {
TT[4] == '-' && TT[1] - '3' < 6);
}
-/// CreateTarget - Create the TargetInfoImpl object for the specified target
-/// enum value.
-static TargetInfoImpl *CreateTarget(const std::string& T) {
+/// CreateTargetInfo - Return the target info object for the specified target
+/// triple.
+TargetInfo* TargetInfo::CreateTargetInfo(const std::string &T) {
if (T.find("ppc-") == 0 || T.find("powerpc-") == 0)
- return new DarwinPPCTargetInfo(T);
- else if (T.find("ppc64-") == 0 || T.find("powerpc64-") == 0)
- return new DarwinPPC64TargetInfo(T);
- else if (T.find("sparc-") == 0)
- return new SolarisSparcV8TargetInfo(T); // ugly hack
- else if (T.find("x86_64-") == 0)
- return new DarwinX86_64TargetInfo(T);
- else if (IsX86(T))
- return new DarwinI386TargetInfo(T);
- else if (T.find("bogusW16W16-") == 0) // For testing portability.
- return new LinuxTargetInfo(T);
- else
- return NULL;
-}
-
-/// CreateTargetInfo - Return the set of target info objects as specified by
-/// the -arch command line option.
-TargetInfo* TargetInfo::CreateTargetInfo(const std::string* TriplesStart,
- const std::string* TriplesEnd,
- Diagnostic *Diags) {
-
- // Create the primary target and target info.
- TargetInfoImpl* PrimaryTarget = CreateTarget(*TriplesStart);
-
- if (!PrimaryTarget)
- return NULL;
+ return new TargetInfo(new DarwinPPCTargetInfo(T));
- TargetInfo *TI = new TargetInfo(PrimaryTarget, Diags);
+ if (T.find("ppc64-") == 0 || T.find("powerpc64-") == 0)
+ return new TargetInfo(new DarwinPPC64TargetInfo(T));
- // Add all secondary targets.
- for (const std::string* I=TriplesStart+1; I != TriplesEnd; ++I) {
- TargetInfoImpl* SecondaryTarget = CreateTarget(*I);
-
- if (!SecondaryTarget) {
- fprintf (stderr,
- "Warning: secondary target '%s' unrecognized.\n",
- I->c_str());
-
- continue;
- }
-
- TI->AddSecondaryTarget(SecondaryTarget);
- }
+ if (T.find("sparc-") == 0)
+ return new TargetInfo(new SolarisSparcV8TargetInfo(T)); // ugly hack
+
+ if (T.find("x86_64-") == 0)
+ return new TargetInfo(new DarwinX86_64TargetInfo(T));
+
+ if (IsX86(T))
+ return new TargetInfo(new DarwinI386TargetInfo(T));
+
+ if (T.find("bogusW16W16-") == 0) // For testing portability.
+ return new TargetInfo(new LinuxTargetInfo(T));
- return TI;
+ return NULL;
}
diff --git a/Driver/clang.cpp b/Driver/clang.cpp
index 5d004977ca..f5790df482 100644
--- a/Driver/clang.cpp
+++ b/Driver/clang.cpp
@@ -466,7 +466,7 @@ static llvm::cl::opt<std::string>
TargetTriple("triple",
llvm::cl::desc("Specify target triple (e.g. i686-apple-darwin9)."));
-static llvm::cl::list<std::string>
+static llvm::cl::opt<std::string>
Archs("arch",
llvm::cl::desc("Specify target architecture (e.g. i686)."));
@@ -518,9 +518,9 @@ static void CreateTargetTriples(std::vector<std::string>& triples) {
// host-triple with no archs or using a specified target triple.
if (!TargetTriple.getValue().empty() || Archs.empty())
tp.addTriple(Triple);
-
- for (unsigned i = 0, e = Archs.size(); i !=e; ++i)
- tp.addTriple(Archs[i] + "-" + suffix);
+
+ if (!Archs.empty())
+ tp.addTriple(Archs + "-" + suffix);
}
//===----------------------------------------------------------------------===//
@@ -1307,14 +1307,9 @@ int main(int argc, char **argv) {
// Get information about the targets being compiled for. Note that this
// pointer and the TargetInfoImpl objects are never deleted by this toy
// driver.
- TargetInfo *Target;
-
- // Create triples, and create the TargetInfo.
std::vector<std::string> triples;
CreateTargetTriples(triples);
- Target = TargetInfo::CreateTargetInfo(&triples[0],
- &triples[0]+triples.size(),
- &Diags);
+ TargetInfo *Target = TargetInfo::CreateTargetInfo(triples[0]);
if (Target == 0) {
fprintf(stderr, "Sorry, I don't know what target this is: %s\n",
diff --git a/Lex/MacroInfo.cpp b/Lex/MacroInfo.cpp
index 4640e47ce7..de19ff502a 100644
--- a/Lex/MacroInfo.cpp
+++ b/Lex/MacroInfo.cpp
@@ -20,7 +20,6 @@ MacroInfo::MacroInfo(SourceLocation DefLoc) : Location(DefLoc) {
IsC99Varargs = false;
IsGNUVarargs = false;
IsBuiltinMacro = false;
- IsTargetSpecific = false;
IsDisabled = false;
IsUsed = true;
@@ -32,8 +31,6 @@ MacroInfo::MacroInfo(SourceLocation DefLoc) : Location(DefLoc) {
/// this macro in spelling, arguments, and whitespace. This is used to emit
/// duplicate definition warnings. This implements the rules in C99 6.10.3.
///
-/// Note that this intentionally does not check isTargetSpecific for matching.
-///
bool MacroInfo::isIdenticalTo(const MacroInfo &Other, Preprocessor &PP) const {
// Check # tokens in replacement, number of args, and various flags all match.
if (ReplacementTokens.size() != Other.ReplacementTokens.size() ||
diff --git a/Lex/PPExpressions.cpp b/Lex/PPExpressions.cpp
index 427d95bf36..c56692e1f4 100644
--- a/Lex/PPExpressions.cpp
+++ b/Lex/PPExpressions.cpp
@@ -108,23 +108,6 @@ static bool EvaluateValue(llvm::APSInt &Result, Token &PeekTok,
if (Result != 0 && ValueLive) {
MacroInfo *Macro = PP.getMacroInfo(II);
Macro->setIsUsed(true);
-
- // If this is the first use of a target-specific macro, warn about it.
- if (Macro->isTargetSpecific()) {
- // Don't warn on second use.
- Macro->setIsTargetSpecific(false);
- PP.getTargetInfo().DiagnoseNonPortability(
- PP.getFullLoc(PeekTok.getLocation()),
- diag::port_target_macro_use);
- }
- } else if (ValueLive) {
- // Use of a target-specific macro for some other target? If so, warn.
- if (II->isOtherTargetMacro()) {
- II->setIsOtherTargetMacro(false); // Don't warn on second use.
- PP.getTargetInfo().DiagnoseNonPortability(
- PP.getFullLoc(PeekTok.getLocation()),
- diag::port_target_macro_use);
- }
}
// Consume identifier.
diff --git a/Lex/Preprocessor.cpp b/Lex/Preprocessor.cpp
index be2ffefaa7..0f6ebabe37 100644
--- a/Lex/Preprocessor.cpp
+++ b/Lex/Preprocessor.cpp
@@ -808,13 +808,6 @@ bool Preprocessor::HandleMacroExpandedIdentifier(Token &Identifier,
return false;
}
- // If this is the first use of a target-specific macro, warn about it.
- if (MI->isTargetSpecific()) {
- MI->setIsTargetSpecific(false); // Don't warn on second use.
- getTargetInfo().DiagnoseNonPortability(getFullLoc(Identifier.getLocation()),
- diag::port_target_macro_use);
- }
-
/// Args - If this is a function-like macro expansion, this contains,
/// for each macro argument, the list of tokens that were provided to the
/// invocation.
@@ -1242,14 +1235,6 @@ void Preprocessor::HandleIdentifier(Token &Identifier) {
Identifier.setFlag(Token::DisableExpand);
}
}
- } else if (II.isOtherTargetMacro() && !DisableMacroExpansion) {
- // If this identifier is a macro on some other target, emit a diagnostic.
- // This diagnosic is only emitted when macro expansion is enabled, because
- // the macro would not have been expanded for the other target either.
- II.setIsOtherTargetMacro(false); // Don't warn on second use.
- getTargetInfo().DiagnoseNonPortability(getFullLoc(Identifier.getLocation()),
- diag::port_target_macro_use);
-
}
// C++ 2.11p2: If this is an alternative representation of a C++ operator,
@@ -1775,7 +1760,7 @@ TryAgain:
// C99 6.10.3 - Macro Replacement.
case tok::pp_define:
- return HandleDefineDirective(Result, false);
+ return HandleDefineDirective(Result);
case tok::pp_undef:
return HandleUndefDirective(Result);
@@ -1812,12 +1797,6 @@ TryAgain:
case tok::pp_unassert:
//isExtension = true; // FIXME: implement #unassert
break;
-
- // clang extensions.
- case tok::pp_define_target:
- return HandleDefineDirective(Result, true);
- case tok::pp_define_other_target:
- return HandleDefineOtherTargetDirective(Result);
}
break;
}
@@ -2176,11 +2155,8 @@ bool Preprocessor::ReadMacroDefinitionArgList(MacroInfo *MI) {
}
/// HandleDefineDirective - Implements #define. This consumes the entire macro
-/// line then lets the caller lex the next real token. If 'isTargetSpecific' is
-/// true, then this is a "#define_target", otherwise this is a "#define".
-///
-void Preprocessor::HandleDefineDirective(Token &DefineTok,
- bool isTargetSpecific) {
+/// line then lets the caller lex the next real token.
+void Preprocessor::HandleDefineDirective(Token &DefineTok) {
++NumDefined;
Token MacroNameTok;
@@ -2196,11 +2172,6 @@ void Preprocessor::HandleDefineDirective(Token &DefineTok,
// Create the new macro.
MacroInfo *MI = new MacroInfo(MacroNameTok.getLocation());
- if (isTargetSpecific) MI->setIsTargetSpecific();
-
- // If the identifier is an 'other target' macro, clear this bit.
- MacroNameTok.getIdentifierInfo()->setIsOtherTargetMacro(false);
-
Token Tok;
LexUnexpandedToken(Tok);
@@ -2337,30 +2308,6 @@ void Preprocessor::HandleDefineDirective(Token &DefineTok,
setMacroInfo(MacroNameTok.getIdentifierInfo(), MI);
}
-/// HandleDefineOtherTargetDirective - Implements #define_other_target.
-void Preprocessor::HandleDefineOtherTargetDirective(Token &Tok) {
- Token MacroNameTok;
- ReadMacroName(MacroNameTok, 1);
-
- // Error reading macro name? If so, diagnostic already issued.
- if (MacroNameTok.is(tok::eom))
- return;
-
- // Check to see if this is the last token on the #undef line.
- CheckEndOfDirective("#define_other_target");
-
- // If there is already a macro defined by this name, turn it into a
- // target-specific define.
- if (MacroInfo *MI = getMacroInfo(MacroNameTok.getIdentifierInfo())) {
- MI->setIsTargetSpecific(true);
- return;
- }
-
- // Mark the identifier as being a macro on some other target.
- MacroNameTok.getIdentifierInfo()->setIsOtherTargetMacro();
-}
-
-
/// HandleUndefDirective - Implements #undef.
///
void Preprocessor::HandleUndefDirective(Token &UndefTok) {
@@ -2379,9 +2326,6 @@ void Preprocessor::HandleUndefDirective(Token &UndefTok) {
// Okay, we finally have a valid identifier to undef.
MacroInfo *MI = getMacroInfo(MacroNameTok.getIdentifierInfo());
- // #undef untaints an identifier if it were marked by define_other_target.
- MacroNameTok.getIdentifierInfo()->setIsOtherTargetMacro(false);
-
// If the macro is not defined, this is a noop undef, just return.
if (MI == 0) return;
@@ -2436,26 +2380,8 @@ void Preprocessor::HandleIfdefDirective(Token &Result, bool isIfndef,
MacroInfo *MI = getMacroInfo(MII);
// If there is a macro, process it.
- if (MI) {
- // Mark it used.
+ if (MI) // Mark it used.
MI->setIsUsed(true);
-
- // If this is the first use of a target-specific macro, warn about it.
- if (MI->isTargetSpecific()) {
- MI->setIsTargetSpecific(false); // Don't warn on second use.
- getTargetInfo().DiagnoseNonPortability(
- getFullLoc(MacroNameTok.getLocation()),
- diag::port_target_macro_use);
- }
- } else {
- // Use of a target-specific macro for some other target? If so, warn.
- if (MII->isOtherTargetMacro()) {
- MII->setIsOtherTargetMacro(false); // Don't warn on second use.
- getTargetInfo().DiagnoseNonPortability(
- getFullLoc(MacroNameTok.getLocation()),
- diag::port_target_macro_use);
- }
- }
// Should we include the stuff contained by this directive?
if (!MI == isIfndef) {
diff --git a/NOTES.txt b/NOTES.txt
index 1266718ec0..623f01cd64 100644
--- a/NOTES.txt
+++ b/NOTES.txt
@@ -6,27 +6,6 @@ C90/C99/C++ Comparisons:
http://david.tribble.com/text/cdiffs.htm
//===---------------------------------------------------------------------===//
-Extensions:
-
- * "#define_target X Y"
- This preprocessor directive works exactly the same was as #define, but it
- notes that 'X' is a target-specific preprocessor directive. When used, a
- diagnostic is emitted indicating that the translation unit is non-portable.
-
- If a target-define is #undef'd before use, no diagnostic is emitted. If 'X'
- were previously a normal #define macro, the macro is tainted. If 'X' is
- subsequently #defined as a non-target-specific define, the taint bit is
- cleared.
-
- * "#define_other_target X"
- The preprocessor directive takes a single identifier argument. It notes
- that this identifier is a target-specific #define for some target other than
- the current one. Use of this identifier will result in a diagnostic.
-
- If 'X' is later #undef'd or #define'd, the taint bit is cleared. If 'X' is
- already defined, X is marked as a target-specific define.
-
-//===---------------------------------------------------------------------===//
To time GCC preprocessing speed without output, use:
"time gcc -MM file"
@@ -159,102 +138,3 @@ The "selection of target" behavior is defined as follows:
ppc64-apple-darwin9 (secondary target)
The secondary targets are used in the 'portability' model (see below).
-
-//===---------------------------------------------------------------------===//
-
-The 'portability' model in clang is sufficient to catch translation units (or
-their parts) that are not portable, but it doesn't help if the system headers
-are non-portable and not fixed. An alternative model that would be easy to use
-is a 'tainting' scheme. Consider:
-
-int32_t
-OSHostByteOrder(void) {
-#if defined(__LITTLE_ENDIAN__)
- return OSLittleEndian;
-#elif defined(__BIG_ENDIAN__)
- return OSBigEndian;
-#else
- return OSUnknownByteOrder;
-#endif
-}
-
-It would be trivial to mark 'OSHostByteOrder' as being non-portable (tainted)
-instead of marking the entire translation unit. Then, if OSHostByteOrder is
-never called/used by the current translation unit, the t-u wouldn't be marked
-non-portable. However, there is no good way to handle stuff like:
-
-extern int X, Y;
-
-#ifndef __POWERPC__
-#define X Y
-#endif
-
-int bar() { return X; }
-
-When compiling for powerpc, the #define is skipped, so it doesn't know that bar
-uses a #define that is set on some other target. In practice, limited cases
-could be handled by scanning the skipped region of a #if, but the fully general
-case cannot be implemented efficiently. In this case, for example, the #define
-in the protected region could be turned into either a #define_target or
-#define_other_target as appropriate. The harder case is code like this (from
-OSByteOrder.h):
-
- #if (defined(__ppc__) || defined(__ppc64__))
- #include <libkern/ppc/OSByteOrder.h>
- #elif (defined(__i386__) || defined(__x86_64__))
- #include <libkern/i386/OSByteOrder.h>
- #else
- #include <libkern/machine/OSByteOrder.h>
- #endif
-
-The realistic way to fix this is by having an initial #ifdef __llvm__ that
-defines its contents in terms of the llvm bswap intrinsics. Other things should
-be handled on a case-by-case basis.
-
-
-We probably have to do something smarter like this in the future. The C++ header
-<limits> contains a lot of code like this:
-
- static const int digits10 = __LDBL_DIG__;
- static const int min_exponent = __LDBL_MIN_EXP__;
- static const int min_exponent10 = __LDBL_MIN_10_EXP__;
- static const float_denorm_style has_denorm
- = bool(__LDBL_DENORM_MIN__) ? denorm_present : denorm_absent;
-
- ... since this isn't being used in an #ifdef, it should be easy enough to taint
-the decl for these ivars.
-
-
-/usr/include/sys/cdefs.h contains stuff like this:
-
-#if defined(__ppc__)
-# if defined(__LDBL_MANT_DIG__) && defined(__DBL_MANT_DIG__) && \
- __LDBL_MANT_DIG__ > __DBL_MANT_DIG__
-# if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__-0 < 1040
-# define __DARWIN_LDBL_COMPAT(x) __asm("_" __STRING(x) "$LDBLStub")
-# else
-# define __DARWIN_LDBL_COMPAT(x) __asm("_" __STRING(x) "$LDBL128")
-# endif
-# define __DARWIN_LDBL_COMPAT2(x) __asm("_" __STRING(x) "$LDBL128")
-# define __DARWIN_LONG_DOUBLE_IS_DOUBLE 0
-# else
-# define __DARWIN_LDBL_COMPAT(x) /* nothing */
-# define __DARWIN_LDBL_COMPAT2(x) /* nothing */
-# define __DARWIN_LONG_DOUBLE_IS_DOUBLE 1
-# endif
-#elif defined(__i386__) || defined(__ppc64__) || defined(__x86_64__)
-# define __DARWIN_LDBL_COMPAT(x) /* nothing */
-# define __DARWIN_LDBL_COMPAT2(x) /* nothing */
-# define __DARWIN_LONG_DOUBLE_IS_DOUBLE 0
-#else
-# error Unknown architecture
-#endif
-
-An ideal way to solve this issue is to mark __DARWIN_LDBL_COMPAT /
-__DARWIN_LDBL_COMPAT2 / __DARWIN_LONG_DOUBLE_IS_DOUBLE as being non-portable
-because they depend on non-portable macros. In practice though, this may end
-up being a serious problem: every use of printf will mark the translation unit
-non-portable if targetting ppc32 and something else.
-
-//===---------------------------------------------------------------------===//
-
diff --git a/Sema/SemaDecl.cpp b/Sema/SemaDecl.cpp
index 3b63a80566..b45317ac9c 100644
--- a/Sema/SemaDecl.cpp
+++ b/Sema/SemaDecl.cpp
@@ -135,15 +135,6 @@ ScopedDecl *Sema::LookupScopedDecl(IdentifierInfo *II, unsigned NSI,
// corresponds to a compiler builtin, create the decl object for the builtin
// now, injecting it into translation unit scope, and return it.
if (NS == Decl::IDNS_Ordinary) {
- // If this is a builtin on some other target, or if this builtin varies
- // across targets (e.g. in type), emit a diagnostic and mark the translation
- // unit non-portable for using it.
- if (II->isNonPortableBuiltin()) {
- // Only emit this diagnostic once for this builtin.
- II->setNonPortableBuiltin(false);
- Context.Target.DiagnoseNonPortability(Context.getFullLoc(IdLoc),
- diag::port_target_builtin_use);
- }
// If this is a builtin on this (or all) targets, create the decl.
if (unsigned BuiltinID = II->getBuiltinID())
return LazilyCreateBuiltin(II, BuiltinID, S);
diff --git a/include/clang/Basic/DiagnosticKinds.def b/include/clang/Basic/DiagnosticKinds.def
index bfc5aca031..97310a1f0b 100644
--- a/include/clang/Basic/DiagnosticKinds.def
+++ b/include/clang/Basic/DiagnosticKinds.def
@@ -20,19 +20,6 @@
// ERROR - Error, compilation will stop after parsing completes.
//===----------------------------------------------------------------------===//
-// Portability
-//===----------------------------------------------------------------------===//
-
-DIAG(port_target_macro_use, NOTE,
- "use of a target-specific macro, source is not 'portable'")
-
-DIAG(port_target_builtin_use, NOTE,
- "use of a target-specific builtin function, source is not 'portable'")
-
-DIAG(port_wchar_t, NOTE,
- "sizeof(wchar_t) varies between targets, source is not 'portable'")
-
-//===----------------------------------------------------------------------===//
// Lexer Diagnostics
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Basic/IdentifierTable.h b/include/clang/Basic/IdentifierTable.h
index fa3143f656..f64fd6fda4 100644
--- a/include/clang/Basic/IdentifierTable.h
+++ b/include/clang/Basic/IdentifierTable.h
@@ -45,10 +45,8 @@ class IdentifierInfo {
bool HasMacro : 1; // True if there is a #define for this.
bool IsExtension : 1; // True if identifier is a lang extension.
bool IsPoisoned : 1; // True if identifier is poisoned.
- bool IsOtherTargetMacro : 1; // True if ident is macro on another target.
bool IsCPPOperatorKeyword : 1; // True if ident is a C++ operator keyword.
- bool IsNonPortableBuiltin : 1; // True if builtin varies across targets.
- // 4 bits left in 32-bit word.
+ // 6 bits left in 32-bit word.
void *FETokenInfo; // Managed by the language front-end.
IdentifierInfo(const IdentifierInfo&); // NONCOPYABLE.
void operator=(const IdentifierInfo&); // NONASSIGNABLE.
@@ -106,13 +104,6 @@ public:
assert(BuiltinID == ID && "ID too large for field!");
}
- /// isNonPortableBuiltin - Return true if this identifier corresponds to a
- /// builtin on some other target, but isn't one on this target, or if it is on
- /// the target but not on another, or if it is on both but it differs somehow
- /// in behavior.
- bool isNonPortableBuiltin() const { return IsNonPortableBuiltin; }
- void setNonPortableBuiltin(bool Val) { IsNonPortableBuiltin = Val; }
-
/// get/setExtension - Initialize information about whether or not this
/// language token is an extension. This controls extension warnings, and is
/// only valid if a custom token ID is set.
@@ -126,11 +117,6 @@ public:
/// isPoisoned - Return true if this token has been poisoned.
bool isPoisoned() const { return IsPoisoned; }
- /// setIsOtherTargetMacro/isOtherTargetMacro control whether this identifier
- /// is seen as being a macro on some other target.
- void setIsOtherTargetMacro(bool Val = true) { IsOtherTargetMacro = Val; }
- bool isOtherTargetMacro() const { return IsOtherTargetMacro; }
-
/// isCPlusPlusOperatorKeyword/setIsCPlusPlusOperatorKeyword controls whether
/// this identifier is a C++ alternate representation of an operator.
void setIsCPlusPlusOperatorKeyword(bool Val = true)
diff --git a/include/clang/Basic/TargetInfo.h b/include/clang/Basic/TargetInfo.h
index 0550e51e82..16c959c6d0 100644
--- a/include/clang/Basic/TargetInfo.h
+++ b/include/clang/Basic/TargetInfo.h
@@ -29,33 +29,13 @@ class SourceManager;
namespace Builtin { struct Info; }
-/// TargetInfo - This class exposes information about the current target set.
-/// A target set consists of a primary target and zero or more secondary targets
-/// which are each represented by a TargetInfoImpl object. TargetInfo responds
-/// to various queries as though it were the primary target, but keeps track of,
-/// and warns about, the first query made of it that are contradictary among the
-/// targets it tracks. For example, if it contains a "PPC32" and "PPC64"
-/// target, it will warn the first time the size of the 'long' datatype is
-/// queried.
+/// TargetInfo - This class exposes information about the current target.
///
class TargetInfo {
/// Primary - This tracks the primary target in the target set.
///
- const TargetInfoImpl *PrimaryTarget;
+ const TargetInfoImpl *Target;
- /// SecondaryTargets - This tracks the set of secondary targets.
- ///
- std::vector<const TargetInfoImpl*> SecondaryTargets;
-
- /// Diag - If non-null, this object is used to report the first use of
- /// non-portable functionality in the translation unit.
- ///
- Diagnostic *Diag;
-
- /// NonPortable - This instance variable keeps track of whether or not the
- /// current translation unit is portable across the set of targets tracked.
- bool NonPortable;
-
/// These are all caches for target values.
unsigned WCharWidth, WCharAlign;
@@ -63,53 +43,22 @@ class TargetInfo {
// TargetInfo Construction.
//==----------------------------------------------------------------==/
- TargetInfo(const TargetInfoImpl *Primary, Diagnostic *D = 0) {
- PrimaryTarget = Primary;
- Diag = D;
- NonPortable = false;
+ TargetInfo(const TargetInfoImpl *TII) {
+ Target = TII;
// Initialize Cache values to uncomputed.
WCharWidth = 0;
}
- /// AddSecondaryTarget - Add a secondary target to the target set.
- void AddSecondaryTarget(const TargetInfoImpl *Secondary) {
- SecondaryTargets.push_back(Secondary);
- }
-
public:
- /// CreateTargetInfo - Create a TargetInfo object from a group of
- /// target triples. The first target triple is considered the primary
- /// target.
- static TargetInfo* CreateTargetInfo(const std::string* TriplesBeg,
- const std::string* TripledEnd,
- Diagnostic* Diags = NULL);
+ /// CreateTargetInfo - Return the target info object for the specified target
+ /// triple.
+ static TargetInfo* CreateTargetInfo(const std::string &Triple);
~TargetInfo();
- //==----------------------------------------------------------------==/
- // Accessors.
- //==----------------------------------------------------------------==/
-
- /// isNonPortable - Return true if the current translation unit has used a
- /// target property that is non-portable across the secondary targets.
- bool isNonPortable() const {
- return NonPortable;
- }
-
- /// isPortable - Return true if this translation unit is portable across the
- /// secondary targets so far.
- bool isPortable() const {
- return !NonPortable;
- }
-
///===---- Target property query methods --------------------------------===//
- /// DiagnoseNonPortability - Emit a diagnostic indicating that the current
- /// translation unit is non-portable due to a construct at the specified
- /// location. DiagKind indicates what went wrong.
- void DiagnoseNonPortability(FullSourceLoc Loc, unsigned DiagKind);
-
/// getTargetDefines - Appends the target-specific #define values for this
/// target set to the specified buffer.
void getTargetDefines(std::vector<char> &DefineBuffer);
@@ -197,8 +146,8 @@ public:
/// getTargetBuiltins - Return information about target-specific builtins for
/// the current primary target, and info about which builtins are non-portable
/// across the current set of primary and secondary targets.
- void getTargetBuiltins(const Builtin::Info *&Records, unsigned &NumRecords,
- std::vector<const char *> &NonPortableBuiltins) const;
+ void getTargetBuiltins(const Builtin::Info *&Records,
+ unsigned &NumRecords) const;
/// getVAListDeclaration - Return the declaration to use for
/// __builtin_va_list, which is target-specific.
diff --git a/include/clang/Basic/TokenKinds.def b/include/clang/Basic/TokenKinds.def
index d4c9265146..9b636183dd 100644
--- a/include/clang/Basic/TokenKinds.def
+++ b/include/clang/Basic/TokenKinds.def
@@ -79,11 +79,6 @@ PPKEYWORD(sccs)
PPKEYWORD(assert)
PPKEYWORD(unassert)
-// clang extensions.
-PPKEYWORD(define_target)
-PPKEYWORD(define_other_target)
-
-
//===----------------------------------------------------------------------===//
// Language keywords.
//===----------------------------------------------------------------------===//
diff --git a/include/clang/Lex/MacroInfo.h b/include/clang/Lex/MacroInfo.h
index f690d955bd..c63b701a85 100644
--- a/include/clang/Lex/MacroInfo.h
+++ b/include/clang/Lex/MacroInfo.h
@@ -59,9 +59,6 @@ class MacroInfo {
/// it has not yet been redefined or undefined.
bool IsBuiltinMacro : 1;
- /// IsTargetSpecific - True if this is a target-specific macro defined with
- /// #define_target.
- bool IsTargetSpecific : 1;
private:
//===--------------------------------------------------------------------===//
// State that changes as the macro is used.
@@ -97,13 +94,6 @@ public:
IsBuiltinMacro = Val;
}
- /// setIsTargetSpecific - Set or clear the IsTargetSpecific flag.
- ///
- void setIsTargetSpecific(bool Val = true) {
- IsTargetSpecific = Val;
- }
- bool isTargetSpecific() const { return IsTargetSpecific; }
-
/// setIsUsed - Set the value of the IsUsed flag.
///
void setIsUsed(bool Val) {
diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h
index 1a8c2937ec..e18b40ac56 100644
--- a/include/clang/Lex/Preprocessor.h
+++ b/include/clang/Lex/Preprocessor.h
@@ -480,9 +480,8 @@ private:
void HandleImportDirective(Token &Tok);
// Macro handling.
- void HandleDefineDirective(Token &Tok, bool isTargetSpecific);
+ void HandleDefineDirective(Token &Tok);
void HandleUndefDirective(Token &Tok);
- void HandleDefineOtherTargetDirective(Token &Tok);
// HandleAssertDirective(Token &Tok);
// HandleUnassertDirective(Token &Tok);
diff --git a/test/Parser/portability.c b/test/Parser/portability.c
deleted file mode 100644
index b6e9715285..0000000000
--- a/test/Parser/portability.c
+++ /dev/null
@@ -1,5 +0,0 @@
-// RUN: clang -arch ppc -arch bogusW16W16 -fsyntax-only %s 2>&1 | grep note | wc -l | grep 1
-
-// wchar_t varies across targets.
-void *X = L"foo";
-