Skip to content

Commit 063400e

Browse files
committed
Implement the #define_other_target directive.
llvm-svn: 38984
1 parent 5836033 commit 063400e

File tree

5 files changed

+75
-8
lines changed

5 files changed

+75
-8
lines changed

clang/Lex/IdentifierTable.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,7 @@ IdentifierInfo &IdentifierTable::get(const char *NameStart,
209209
Identifier->TokInfo.TokenID = tok::identifier;
210210
Identifier->TokInfo.IsExtension = false;
211211
Identifier->TokInfo.IsPoisoned = false;
212+
Identifier->TokInfo.IsOtherTargetMacro = false;
212213
Identifier->TokInfo.FETokenInfo = 0;
213214

214215
// Copy the string information.

clang/Lex/PPExpressions.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,13 @@ static bool EvaluateValue(int &Result, LexerToken &PeekTok, DefinedTracker &DT,
106106
PP.getTargetInfo().DiagnoseNonPortability(PeekTok.getLocation(),
107107
diag::port_target_macro_use);
108108
}
109+
} else {
110+
// Use of a target-specific macro for some other target? If so, warn.
111+
if (II->isOtherTargetMacro()) {
112+
II->setIsOtherTargetMacro(false); // Don't warn on second use.
113+
PP.getTargetInfo().DiagnoseNonPortability(PeekTok.getLocation(),
114+
diag::port_target_macro_use);
115+
}
109116
}
110117

111118
// Consume identifier.

clang/Lex/Preprocessor.cpp

Lines changed: 54 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1012,7 +1012,7 @@ void Preprocessor::HandleIdentifier(LexerToken &Identifier) {
10121012
}
10131013

10141014
// If this is a macro to be expanded, do it.
1015-
if (MacroInfo *MI = II.getMacroInfo())
1015+
if (MacroInfo *MI = II.getMacroInfo()) {
10161016
if (!DisableMacroExpansion && !Identifier.isExpandDisabled()) {
10171017
if (MI->isEnabled()) {
10181018
if (!HandleMacroExpandedIdentifier(Identifier, MI))
@@ -1024,6 +1024,15 @@ void Preprocessor::HandleIdentifier(LexerToken &Identifier) {
10241024
Identifier.setFlag(LexerToken::DisableExpand);
10251025
}
10261026
}
1027+
} else if (II.isOtherTargetMacro() && !DisableMacroExpansion) {
1028+
// If this identifier is a macro on some other target, emit a diagnostic.
1029+
// This diagnosic is only emitted when macro expansion is enabled, because
1030+
// the macro would not have been expanded for the other target either.
1031+
II.setIsOtherTargetMacro(false); // Don't warn on second use.
1032+
getTargetInfo().DiagnoseNonPortability(Identifier.getLocation(),
1033+
diag::port_target_macro_use);
1034+
1035+
}
10271036

10281037
// Change the kind of this identifier to the appropriate token kind, e.g.
10291038
// turning "for" into a keyword.
@@ -1467,6 +1476,10 @@ void Preprocessor::HandleDirective(LexerToken &Result) {
14671476
if (Directive[0] == 'd' && !strcmp(Directive, "define_target"))
14681477
return HandleDefineDirective(Result, true);
14691478
break;
1479+
case 19:
1480+
if (Directive[0] == 'd' && !strcmp(Directive, "define_other_target"))
1481+
return HandleDefineOtherTargetDirective(Result);
1482+
break;
14701483
}
14711484
break;
14721485
}
@@ -1723,9 +1736,14 @@ void Preprocessor::HandleDefineDirective(LexerToken &DefineTok,
17231736
// mode.
17241737
CurLexer->KeepCommentMode = Features.KeepMacroComments;
17251738

1739+
// Create the new macro.
17261740
MacroInfo *MI = new MacroInfo(MacroNameTok.getLocation());
17271741
if (isTargetSpecific) MI->setIsTargetSpecific();
17281742

1743+
// If the identifier is an 'other target' macro, clear this bit.
1744+
MacroNameTok.getIdentifierInfo()->setIsOtherTargetMacro(false);
1745+
1746+
17291747
LexerToken Tok;
17301748
LexUnexpandedToken(Tok);
17311749

@@ -1848,6 +1866,29 @@ void Preprocessor::HandleDefineDirective(LexerToken &DefineTok,
18481866
MacroNameTok.getIdentifierInfo()->setMacroInfo(MI);
18491867
}
18501868

1869+
/// HandleDefineOtherTargetDirective - Implements #define_other_target.
1870+
void Preprocessor::HandleDefineOtherTargetDirective(LexerToken &Tok) {
1871+
LexerToken MacroNameTok;
1872+
ReadMacroName(MacroNameTok, 1);
1873+
1874+
// Error reading macro name? If so, diagnostic already issued.
1875+
if (MacroNameTok.getKind() == tok::eom)
1876+
return;
1877+
1878+
// Check to see if this is the last token on the #undef line.
1879+
CheckEndOfDirective("#define_other_target");
1880+
1881+
// If there is already a macro defined by this name, turn it into a
1882+
// target-specific define.
1883+
if (MacroInfo *MI = MacroNameTok.getIdentifierInfo()->getMacroInfo()) {
1884+
MI->setIsTargetSpecific(true);
1885+
return;
1886+
}
1887+
1888+
// Mark the identifier as being a macro on some other target.
1889+
MacroNameTok.getIdentifierInfo()->setIsOtherTargetMacro();
1890+
}
1891+
18511892

18521893
/// HandleUndefDirective - Implements #undef.
18531894
///
@@ -1867,6 +1908,9 @@ void Preprocessor::HandleUndefDirective(LexerToken &UndefTok) {
18671908
// Okay, we finally have a valid identifier to undef.
18681909
MacroInfo *MI = MacroNameTok.getIdentifierInfo()->getMacroInfo();
18691910

1911+
// #undef untaints an identifier if it were marked by define_other_target.
1912+
MacroNameTok.getIdentifierInfo()->setIsOtherTargetMacro(false);
1913+
18701914
// If the macro is not defined, this is a noop undef, just return.
18711915
if (MI == 0) return;
18721916

@@ -1910,7 +1954,8 @@ void Preprocessor::HandleIfdefDirective(LexerToken &Result, bool isIfndef,
19101954
CurLexer->MIOpt.EnterTopLevelIFNDEF(MacroNameTok.getIdentifierInfo());
19111955
}
19121956

1913-
MacroInfo *MI = MacroNameTok.getIdentifierInfo()->getMacroInfo();
1957+
IdentifierInfo *MII = MacroNameTok.getIdentifierInfo();
1958+
MacroInfo *MI = MII->getMacroInfo();
19141959

19151960
// If there is a macro, process it.
19161961
if (MI) {
@@ -1923,6 +1968,13 @@ void Preprocessor::HandleIfdefDirective(LexerToken &Result, bool isIfndef,
19231968
getTargetInfo().DiagnoseNonPortability(MacroNameTok.getLocation(),
19241969
diag::port_target_macro_use);
19251970
}
1971+
} else {
1972+
// Use of a target-specific macro for some other target? If so, warn.
1973+
if (MII->isOtherTargetMacro()) {
1974+
MII->setIsOtherTargetMacro(false); // Don't warn on second use.
1975+
getTargetInfo().DiagnoseNonPortability(MacroNameTok.getLocation(),
1976+
diag::port_target_macro_use);
1977+
}
19261978
}
19271979

19281980
// Should we include the stuff contained by this directive?

clang/include/clang/Lex/IdentifierTable.h

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,13 @@ namespace clang {
2929
/// variable or function name). The preprocessor keeps this information in a
3030
/// set, and all tok::identifier tokens have a pointer to one of these.
3131
class IdentifierInfo {
32-
unsigned NameLen; // String that is the identifier.
33-
MacroInfo *Macro; // Set if this identifier is #define'd.
34-
tok::TokenKind TokenID:8; // Front-end token ID or tok::identifier.
35-
bool IsExtension : 1; // True if this identifier is a language extension.
36-
bool IsPoisoned : 1; // True if this identifier is poisoned.
37-
void *FETokenInfo; // Managed by the language front-end.
32+
unsigned NameLen; // String that is the identifier.
33+
MacroInfo *Macro; // Set if this identifier is #define'd.
34+
tok::TokenKind TokenID : 8; // Front-end token ID or tok::identifier.
35+
bool IsExtension : 1; // True if identifier is a lang extension.
36+
bool IsPoisoned : 1; // True if identifier is poisoned.
37+
bool IsOtherTargetMacro : 1; // True if ident is a macro on another target.
38+
void *FETokenInfo; // Managed by the language front-end.
3839
friend class IdentifierTable;
3940
public:
4041
/// getName - Return the actual string for this identifier. The length of
@@ -76,6 +77,11 @@ class IdentifierInfo {
7677
/// isPoisoned - Return true if this token has been poisoned.
7778
bool isPoisoned() const { return IsPoisoned; }
7879

80+
/// setIsOtherTargetMacro/isOtherTargetMacro control whether this identifier
81+
/// is seen as being a macro on some other target.
82+
void setIsOtherTargetMacro(bool Val = true) { IsOtherTargetMacro = Val; }
83+
bool isOtherTargetMacro() const { return IsOtherTargetMacro; }
84+
7985
/// getFETokenInfo/setFETokenInfo - The language front-end is allowed to
8086
/// associate arbitrary metadata with this token.
8187
template<typename T>

clang/include/clang/Lex/Preprocessor.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -534,6 +534,7 @@ class Preprocessor {
534534
// Macro handling.
535535
void HandleDefineDirective(LexerToken &Tok, bool isTargetSpecific);
536536
void HandleUndefDirective(LexerToken &Tok);
537+
void HandleDefineOtherTargetDirective(LexerToken &Tok);
537538
// HandleAssertDirective(LexerToken &Tok);
538539
// HandleUnassertDirective(LexerToken &Tok);
539540

0 commit comments

Comments
 (0)