forked from OSchip/llvm-project
Implement the #define_other_target directive.
llvm-svn: 38984
This commit is contained in:
parent
58360339bd
commit
063400e46e
|
@ -209,6 +209,7 @@ IdentifierInfo &IdentifierTable::get(const char *NameStart,
|
|||
Identifier->TokInfo.TokenID = tok::identifier;
|
||||
Identifier->TokInfo.IsExtension = false;
|
||||
Identifier->TokInfo.IsPoisoned = false;
|
||||
Identifier->TokInfo.IsOtherTargetMacro = false;
|
||||
Identifier->TokInfo.FETokenInfo = 0;
|
||||
|
||||
// Copy the string information.
|
||||
|
|
|
@ -106,6 +106,13 @@ static bool EvaluateValue(int &Result, LexerToken &PeekTok, DefinedTracker &DT,
|
|||
PP.getTargetInfo().DiagnoseNonPortability(PeekTok.getLocation(),
|
||||
diag::port_target_macro_use);
|
||||
}
|
||||
} else {
|
||||
// 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(PeekTok.getLocation(),
|
||||
diag::port_target_macro_use);
|
||||
}
|
||||
}
|
||||
|
||||
// Consume identifier.
|
||||
|
|
|
@ -1012,7 +1012,7 @@ void Preprocessor::HandleIdentifier(LexerToken &Identifier) {
|
|||
}
|
||||
|
||||
// If this is a macro to be expanded, do it.
|
||||
if (MacroInfo *MI = II.getMacroInfo())
|
||||
if (MacroInfo *MI = II.getMacroInfo()) {
|
||||
if (!DisableMacroExpansion && !Identifier.isExpandDisabled()) {
|
||||
if (MI->isEnabled()) {
|
||||
if (!HandleMacroExpandedIdentifier(Identifier, MI))
|
||||
|
@ -1024,6 +1024,15 @@ void Preprocessor::HandleIdentifier(LexerToken &Identifier) {
|
|||
Identifier.setFlag(LexerToken::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(Identifier.getLocation(),
|
||||
diag::port_target_macro_use);
|
||||
|
||||
}
|
||||
|
||||
// Change the kind of this identifier to the appropriate token kind, e.g.
|
||||
// turning "for" into a keyword.
|
||||
|
@ -1467,6 +1476,10 @@ void Preprocessor::HandleDirective(LexerToken &Result) {
|
|||
if (Directive[0] == 'd' && !strcmp(Directive, "define_target"))
|
||||
return HandleDefineDirective(Result, true);
|
||||
break;
|
||||
case 19:
|
||||
if (Directive[0] == 'd' && !strcmp(Directive, "define_other_target"))
|
||||
return HandleDefineOtherTargetDirective(Result);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -1723,9 +1736,14 @@ void Preprocessor::HandleDefineDirective(LexerToken &DefineTok,
|
|||
// mode.
|
||||
CurLexer->KeepCommentMode = Features.KeepMacroComments;
|
||||
|
||||
// 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);
|
||||
|
||||
|
||||
LexerToken Tok;
|
||||
LexUnexpandedToken(Tok);
|
||||
|
||||
|
@ -1848,6 +1866,29 @@ void Preprocessor::HandleDefineDirective(LexerToken &DefineTok,
|
|||
MacroNameTok.getIdentifierInfo()->setMacroInfo(MI);
|
||||
}
|
||||
|
||||
/// HandleDefineOtherTargetDirective - Implements #define_other_target.
|
||||
void Preprocessor::HandleDefineOtherTargetDirective(LexerToken &Tok) {
|
||||
LexerToken MacroNameTok;
|
||||
ReadMacroName(MacroNameTok, 1);
|
||||
|
||||
// Error reading macro name? If so, diagnostic already issued.
|
||||
if (MacroNameTok.getKind() == 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 = MacroNameTok.getIdentifierInfo()->getMacroInfo()) {
|
||||
MI->setIsTargetSpecific(true);
|
||||
return;
|
||||
}
|
||||
|
||||
// Mark the identifier as being a macro on some other target.
|
||||
MacroNameTok.getIdentifierInfo()->setIsOtherTargetMacro();
|
||||
}
|
||||
|
||||
|
||||
/// HandleUndefDirective - Implements #undef.
|
||||
///
|
||||
|
@ -1867,6 +1908,9 @@ void Preprocessor::HandleUndefDirective(LexerToken &UndefTok) {
|
|||
// Okay, we finally have a valid identifier to undef.
|
||||
MacroInfo *MI = MacroNameTok.getIdentifierInfo()->getMacroInfo();
|
||||
|
||||
// #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;
|
||||
|
||||
|
@ -1910,7 +1954,8 @@ void Preprocessor::HandleIfdefDirective(LexerToken &Result, bool isIfndef,
|
|||
CurLexer->MIOpt.EnterTopLevelIFNDEF(MacroNameTok.getIdentifierInfo());
|
||||
}
|
||||
|
||||
MacroInfo *MI = MacroNameTok.getIdentifierInfo()->getMacroInfo();
|
||||
IdentifierInfo *MII = MacroNameTok.getIdentifierInfo();
|
||||
MacroInfo *MI = MII->getMacroInfo();
|
||||
|
||||
// If there is a macro, process it.
|
||||
if (MI) {
|
||||
|
@ -1923,6 +1968,13 @@ void Preprocessor::HandleIfdefDirective(LexerToken &Result, bool isIfndef,
|
|||
getTargetInfo().DiagnoseNonPortability(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(MacroNameTok.getLocation(),
|
||||
diag::port_target_macro_use);
|
||||
}
|
||||
}
|
||||
|
||||
// Should we include the stuff contained by this directive?
|
||||
|
|
|
@ -29,12 +29,13 @@ namespace clang {
|
|||
/// variable or function name). The preprocessor keeps this information in a
|
||||
/// set, and all tok::identifier tokens have a pointer to one of these.
|
||||
class IdentifierInfo {
|
||||
unsigned NameLen; // String that is the identifier.
|
||||
MacroInfo *Macro; // Set if this identifier is #define'd.
|
||||
tok::TokenKind TokenID:8; // Front-end token ID or tok::identifier.
|
||||
bool IsExtension : 1; // True if this identifier is a language extension.
|
||||
bool IsPoisoned : 1; // True if this identifier is poisoned.
|
||||
void *FETokenInfo; // Managed by the language front-end.
|
||||
unsigned NameLen; // String that is the identifier.
|
||||
MacroInfo *Macro; // Set if this identifier is #define'd.
|
||||
tok::TokenKind TokenID : 8; // Front-end token ID or tok::identifier.
|
||||
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 a macro on another target.
|
||||
void *FETokenInfo; // Managed by the language front-end.
|
||||
friend class IdentifierTable;
|
||||
public:
|
||||
/// getName - Return the actual string for this identifier. The length of
|
||||
|
@ -76,6 +77,11 @@ 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; }
|
||||
|
||||
/// getFETokenInfo/setFETokenInfo - The language front-end is allowed to
|
||||
/// associate arbitrary metadata with this token.
|
||||
template<typename T>
|
||||
|
|
|
@ -534,6 +534,7 @@ private:
|
|||
// Macro handling.
|
||||
void HandleDefineDirective(LexerToken &Tok, bool isTargetSpecific);
|
||||
void HandleUndefDirective(LexerToken &Tok);
|
||||
void HandleDefineOtherTargetDirective(LexerToken &Tok);
|
||||
// HandleAssertDirective(LexerToken &Tok);
|
||||
// HandleUnassertDirective(LexerToken &Tok);
|
||||
|
||||
|
|
Loading…
Reference in New Issue