forked from OSchip/llvm-project
Permanently end the whole "pragma got handled by the parser too early"
mess by handling all pragmas which the parser touches uniformly. <rdar://problem/12248901>, etc. llvm-svn: 165195
This commit is contained in:
parent
0b744b3105
commit
68be1649ee
clang
include/clang
lib
test
|
@ -407,8 +407,6 @@ def err_object_cannot_be_passed_returned_by_value : Error<
|
|||
def err_parameters_retval_cannot_have_fp16_type : Error<
|
||||
"%select{parameters|function return value}0 cannot have __fp16 type; did you forget * ?">;
|
||||
def warn_enum_value_overflow : Warning<"overflow in enumeration value">;
|
||||
def warn_pragma_options_align_unsupported_option : Warning<
|
||||
"unsupported alignment option in '#pragma options align'">;
|
||||
def warn_pragma_options_align_reset_failed : Warning<
|
||||
"#pragma options align=reset failed: %0">;
|
||||
def err_pragma_options_align_mac68k_target_unsupported : Error<
|
||||
|
|
|
@ -602,6 +602,41 @@ ANNOTATION(pragma_pack)
|
|||
// handles them.
|
||||
ANNOTATION(pragma_parser_crash)
|
||||
|
||||
// Annotation for #pragma ms_struct...
|
||||
// The lexer produces these so that they only take effect when the parser
|
||||
// handles them.
|
||||
ANNOTATION(pragma_msstruct)
|
||||
|
||||
// Annotation for #pragma align...
|
||||
// The lexer produces these so that they only take effect when the parser
|
||||
// handles them.
|
||||
ANNOTATION(pragma_align)
|
||||
|
||||
// Annotation for #pragma weak id
|
||||
// The lexer produces these so that they only take effect when the parser
|
||||
// handles them.
|
||||
ANNOTATION(pragma_weak)
|
||||
|
||||
// Annotation for #pragma weak id = id
|
||||
// The lexer produces these so that they only take effect when the parser
|
||||
// handles them.
|
||||
ANNOTATION(pragma_weakalias)
|
||||
|
||||
// Annotation for #pragma redefine_extname...
|
||||
// The lexer produces these so that they only take effect when the parser
|
||||
// handles them.
|
||||
ANNOTATION(pragma_redefine_extname)
|
||||
|
||||
// Annotation for #pragma STDC FP_CONTRACT...
|
||||
// The lexer produces these so that they only take effect when the parser
|
||||
// handles them.
|
||||
ANNOTATION(pragma_fp_contract)
|
||||
|
||||
// Annotation for #pragma OPENCL EXTENSION...
|
||||
// The lexer produces these so that they only take effect when the parser
|
||||
// handles them.
|
||||
ANNOTATION(pragma_opencl_extension)
|
||||
|
||||
#undef ANNOTATION
|
||||
#undef TESTING_KEYWORD
|
||||
#undef OBJC2_AT_KEYWORD
|
||||
|
|
|
@ -441,6 +441,34 @@ private:
|
|||
/// #pragma pack...
|
||||
void HandlePragmaPack();
|
||||
|
||||
/// \brief Handle the annotation token produced for
|
||||
/// #pragma ms_struct...
|
||||
void HandlePragmaMSStruct();
|
||||
|
||||
/// \brief Handle the annotation token produced for
|
||||
/// #pragma align...
|
||||
void HandlePragmaAlign();
|
||||
|
||||
/// \brief Handle the annotation token produced for
|
||||
/// #pragma weak id...
|
||||
void HandlePragmaWeak();
|
||||
|
||||
/// \brief Handle the annotation token produced for
|
||||
/// #pragma weak id = id...
|
||||
void HandlePragmaWeakAlias();
|
||||
|
||||
/// \brief Handle the annotation token produced for
|
||||
/// #pragma redefine_extname...
|
||||
void HandlePragmaRedefineExtname();
|
||||
|
||||
/// \brief Handle the annotation token produced for
|
||||
/// #pragma STDC FP_CONTRACT...
|
||||
void HandlePragmaFPContract();
|
||||
|
||||
/// \brief Handle the annotation token produced for
|
||||
/// #pragma OPENCL EXTENSION...
|
||||
void HandlePragmaOpenCLExtension();
|
||||
|
||||
/// GetLookAheadToken - This peeks ahead N tokens and returns that token
|
||||
/// without consuming any tokens. LookAhead(0) returns 'Tok', LookAhead(1)
|
||||
/// returns the token after Tok, etc.
|
||||
|
|
|
@ -6328,8 +6328,7 @@ public:
|
|||
|
||||
/// ActOnPragmaOptionsAlign - Called on well formed \#pragma options align.
|
||||
void ActOnPragmaOptionsAlign(PragmaOptionsAlignKind Kind,
|
||||
SourceLocation PragmaLoc,
|
||||
SourceLocation KindLoc);
|
||||
SourceLocation PragmaLoc);
|
||||
|
||||
enum PragmaPackKind {
|
||||
PPK_Default, // #pragma pack([n])
|
||||
|
|
|
@ -40,7 +40,7 @@ void Parser::HandlePragmaVisibility() {
|
|||
struct PragmaPackInfo {
|
||||
Sema::PragmaPackKind Kind;
|
||||
IdentifierInfo *Name;
|
||||
Expr *Alignment;
|
||||
Token Alignment;
|
||||
SourceLocation LParenLoc;
|
||||
SourceLocation RParenLoc;
|
||||
};
|
||||
|
@ -50,10 +50,107 @@ void Parser::HandlePragmaPack() {
|
|||
PragmaPackInfo *Info =
|
||||
static_cast<PragmaPackInfo *>(Tok.getAnnotationValue());
|
||||
SourceLocation PragmaLoc = ConsumeToken();
|
||||
Actions.ActOnPragmaPack(Info->Kind, Info->Name, Info->Alignment, PragmaLoc,
|
||||
ExprResult Alignment;
|
||||
if (Info->Alignment.is(tok::numeric_constant)) {
|
||||
Alignment = Actions.ActOnNumericConstant(Info->Alignment);
|
||||
if (Alignment.isInvalid())
|
||||
return;
|
||||
}
|
||||
Actions.ActOnPragmaPack(Info->Kind, Info->Name, Alignment.get(), PragmaLoc,
|
||||
Info->LParenLoc, Info->RParenLoc);
|
||||
}
|
||||
|
||||
void Parser::HandlePragmaMSStruct() {
|
||||
assert(Tok.is(tok::annot_pragma_msstruct));
|
||||
Sema::PragmaMSStructKind Kind =
|
||||
static_cast<Sema::PragmaMSStructKind>(
|
||||
reinterpret_cast<uintptr_t>(Tok.getAnnotationValue()));
|
||||
Actions.ActOnPragmaMSStruct(Kind);
|
||||
ConsumeToken(); // The annotation token.
|
||||
}
|
||||
|
||||
void Parser::HandlePragmaAlign() {
|
||||
assert(Tok.is(tok::annot_pragma_align));
|
||||
Sema::PragmaOptionsAlignKind Kind =
|
||||
static_cast<Sema::PragmaOptionsAlignKind>(
|
||||
reinterpret_cast<uintptr_t>(Tok.getAnnotationValue()));
|
||||
SourceLocation PragmaLoc = ConsumeToken();
|
||||
Actions.ActOnPragmaOptionsAlign(Kind, PragmaLoc);
|
||||
}
|
||||
|
||||
void Parser::HandlePragmaWeak() {
|
||||
assert(Tok.is(tok::annot_pragma_weak));
|
||||
SourceLocation PragmaLoc = ConsumeToken();
|
||||
Actions.ActOnPragmaWeakID(Tok.getIdentifierInfo(), PragmaLoc,
|
||||
Tok.getLocation());
|
||||
ConsumeToken(); // The weak name.
|
||||
}
|
||||
|
||||
void Parser::HandlePragmaWeakAlias() {
|
||||
assert(Tok.is(tok::annot_pragma_weakalias));
|
||||
SourceLocation PragmaLoc = ConsumeToken();
|
||||
IdentifierInfo *WeakName = Tok.getIdentifierInfo();
|
||||
SourceLocation WeakNameLoc = Tok.getLocation();
|
||||
ConsumeToken();
|
||||
IdentifierInfo *AliasName = Tok.getIdentifierInfo();
|
||||
SourceLocation AliasNameLoc = Tok.getLocation();
|
||||
ConsumeToken();
|
||||
Actions.ActOnPragmaWeakAlias(WeakName, AliasName, PragmaLoc,
|
||||
WeakNameLoc, AliasNameLoc);
|
||||
|
||||
}
|
||||
|
||||
void Parser::HandlePragmaRedefineExtname() {
|
||||
assert(Tok.is(tok::annot_pragma_redefine_extname));
|
||||
SourceLocation RedefLoc = ConsumeToken();
|
||||
IdentifierInfo *RedefName = Tok.getIdentifierInfo();
|
||||
SourceLocation RedefNameLoc = Tok.getLocation();
|
||||
ConsumeToken();
|
||||
IdentifierInfo *AliasName = Tok.getIdentifierInfo();
|
||||
SourceLocation AliasNameLoc = Tok.getLocation();
|
||||
ConsumeToken();
|
||||
Actions.ActOnPragmaRedefineExtname(RedefName, AliasName, RedefLoc,
|
||||
RedefNameLoc, AliasNameLoc);
|
||||
}
|
||||
|
||||
void Parser::HandlePragmaFPContract() {
|
||||
assert(Tok.is(tok::annot_pragma_fp_contract));
|
||||
tok::OnOffSwitch OOS =
|
||||
static_cast<tok::OnOffSwitch>(
|
||||
reinterpret_cast<uintptr_t>(Tok.getAnnotationValue()));
|
||||
Actions.ActOnPragmaFPContract(OOS);
|
||||
ConsumeToken(); // The annotation token.
|
||||
}
|
||||
|
||||
namespace {
|
||||
typedef llvm::PointerIntPair<IdentifierInfo *, 1, bool> OpenCLExtData;
|
||||
}
|
||||
|
||||
void Parser::HandlePragmaOpenCLExtension() {
|
||||
assert(Tok.is(tok::annot_pragma_opencl_extension));
|
||||
OpenCLExtData data =
|
||||
OpenCLExtData::getFromOpaqueValue(Tok.getAnnotationValue());
|
||||
unsigned state = data.getInt();
|
||||
IdentifierInfo *ename = data.getPointer();
|
||||
SourceLocation NameLoc = Tok.getLocation();
|
||||
ConsumeToken(); // The annotation token.
|
||||
|
||||
OpenCLOptions &f = Actions.getOpenCLOptions();
|
||||
// OpenCL 1.1 9.1: "The all variant sets the behavior for all extensions,
|
||||
// overriding all previously issued extension directives, but only if the
|
||||
// behavior is set to disable."
|
||||
if (state == 0 && ename->isStr("all")) {
|
||||
#define OPENCLEXT(nm) f.nm = 0;
|
||||
#include "clang/Basic/OpenCLExtensions.def"
|
||||
}
|
||||
#define OPENCLEXT(nm) else if (ename->isStr(#nm)) { f.nm = state; }
|
||||
#include "clang/Basic/OpenCLExtensions.def"
|
||||
else {
|
||||
PP.Diag(NameLoc, diag::warn_pragma_unknown_extension) << ename;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// #pragma GCC visibility comes in two variants:
|
||||
// 'push' '(' [visibility] ')'
|
||||
// 'pop'
|
||||
|
@ -130,13 +227,12 @@ void PragmaPackHandler::HandlePragma(Preprocessor &PP,
|
|||
|
||||
Sema::PragmaPackKind Kind = Sema::PPK_Default;
|
||||
IdentifierInfo *Name = 0;
|
||||
ExprResult Alignment;
|
||||
Token Alignment;
|
||||
Alignment.startToken();
|
||||
SourceLocation LParenLoc = Tok.getLocation();
|
||||
PP.Lex(Tok);
|
||||
if (Tok.is(tok::numeric_constant)) {
|
||||
Alignment = Actions.ActOnNumericConstant(Tok);
|
||||
if (Alignment.isInvalid())
|
||||
return;
|
||||
Alignment = Tok;
|
||||
|
||||
PP.Lex(Tok);
|
||||
|
||||
|
@ -165,9 +261,7 @@ void PragmaPackHandler::HandlePragma(Preprocessor &PP,
|
|||
PP.Lex(Tok);
|
||||
|
||||
if (Tok.is(tok::numeric_constant)) {
|
||||
Alignment = Actions.ActOnNumericConstant(Tok);
|
||||
if (Alignment.isInvalid())
|
||||
return;
|
||||
Alignment = Tok;
|
||||
|
||||
PP.Lex(Tok);
|
||||
} else if (Tok.is(tok::identifier)) {
|
||||
|
@ -182,9 +276,7 @@ void PragmaPackHandler::HandlePragma(Preprocessor &PP,
|
|||
return;
|
||||
}
|
||||
|
||||
Alignment = Actions.ActOnNumericConstant(Tok);
|
||||
if (Alignment.isInvalid())
|
||||
return;
|
||||
Alignment = Tok;
|
||||
|
||||
PP.Lex(Tok);
|
||||
}
|
||||
|
@ -219,7 +311,7 @@ void PragmaPackHandler::HandlePragma(Preprocessor &PP,
|
|||
new (Info) PragmaPackInfo();
|
||||
Info->Kind = Kind;
|
||||
Info->Name = Name;
|
||||
Info->Alignment = Alignment.release();
|
||||
Info->Alignment = Alignment;
|
||||
Info->LParenLoc = LParenLoc;
|
||||
Info->RParenLoc = RParenLoc;
|
||||
|
||||
|
@ -265,12 +357,23 @@ void PragmaMSStructHandler::HandlePragma(Preprocessor &PP,
|
|||
<< "ms_struct";
|
||||
return;
|
||||
}
|
||||
Actions.ActOnPragmaMSStruct(Kind);
|
||||
|
||||
Token *Toks =
|
||||
(Token*) PP.getPreprocessorAllocator().Allocate(
|
||||
sizeof(Token) * 1, llvm::alignOf<Token>());
|
||||
new (Toks) Token();
|
||||
Toks[0].startToken();
|
||||
Toks[0].setKind(tok::annot_pragma_msstruct);
|
||||
Toks[0].setLocation(MSStructTok.getLocation());
|
||||
Toks[0].setAnnotationValue(reinterpret_cast<void*>(
|
||||
static_cast<uintptr_t>(Kind)));
|
||||
PP.EnterTokenStream(Toks, 1, /*DisableMacroExpansion=*/true,
|
||||
/*OwnsTokens=*/false);
|
||||
}
|
||||
|
||||
// #pragma 'align' '=' {'native','natural','mac68k','power','reset'}
|
||||
// #pragma 'options 'align' '=' {'native','natural','mac68k','power','reset'}
|
||||
static void ParseAlignPragma(Sema &Actions, Preprocessor &PP, Token &FirstTok,
|
||||
static void ParseAlignPragma(Preprocessor &PP, Token &FirstTok,
|
||||
bool IsOptions) {
|
||||
Token Tok;
|
||||
|
||||
|
@ -317,7 +420,6 @@ static void ParseAlignPragma(Sema &Actions, Preprocessor &PP, Token &FirstTok,
|
|||
return;
|
||||
}
|
||||
|
||||
SourceLocation KindLoc = Tok.getLocation();
|
||||
PP.Lex(Tok);
|
||||
if (Tok.isNot(tok::eod)) {
|
||||
PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
|
||||
|
@ -325,19 +427,29 @@ static void ParseAlignPragma(Sema &Actions, Preprocessor &PP, Token &FirstTok,
|
|||
return;
|
||||
}
|
||||
|
||||
Actions.ActOnPragmaOptionsAlign(Kind, FirstTok.getLocation(), KindLoc);
|
||||
Token *Toks =
|
||||
(Token*) PP.getPreprocessorAllocator().Allocate(
|
||||
sizeof(Token) * 1, llvm::alignOf<Token>());
|
||||
new (Toks) Token();
|
||||
Toks[0].startToken();
|
||||
Toks[0].setKind(tok::annot_pragma_align);
|
||||
Toks[0].setLocation(FirstTok.getLocation());
|
||||
Toks[0].setAnnotationValue(reinterpret_cast<void*>(
|
||||
static_cast<uintptr_t>(Kind)));
|
||||
PP.EnterTokenStream(Toks, 1, /*DisableMacroExpansion=*/true,
|
||||
/*OwnsTokens=*/false);
|
||||
}
|
||||
|
||||
void PragmaAlignHandler::HandlePragma(Preprocessor &PP,
|
||||
PragmaIntroducerKind Introducer,
|
||||
Token &AlignTok) {
|
||||
ParseAlignPragma(Actions, PP, AlignTok, /*IsOptions=*/false);
|
||||
ParseAlignPragma(PP, AlignTok, /*IsOptions=*/false);
|
||||
}
|
||||
|
||||
void PragmaOptionsHandler::HandlePragma(Preprocessor &PP,
|
||||
PragmaIntroducerKind Introducer,
|
||||
Token &OptionsTok) {
|
||||
ParseAlignPragma(Actions, PP, OptionsTok, /*IsOptions=*/true);
|
||||
ParseAlignPragma(PP, OptionsTok, /*IsOptions=*/true);
|
||||
}
|
||||
|
||||
// #pragma unused(identifier)
|
||||
|
@ -426,7 +538,6 @@ void PragmaUnusedHandler::HandlePragma(Preprocessor &PP,
|
|||
void PragmaWeakHandler::HandlePragma(Preprocessor &PP,
|
||||
PragmaIntroducerKind Introducer,
|
||||
Token &WeakTok) {
|
||||
// FIXME: Should we be expanding macros here? My guess is no.
|
||||
SourceLocation WeakLoc = WeakTok.getLocation();
|
||||
|
||||
Token Tok;
|
||||
|
@ -436,19 +547,20 @@ void PragmaWeakHandler::HandlePragma(Preprocessor &PP,
|
|||
return;
|
||||
}
|
||||
|
||||
IdentifierInfo *WeakName = Tok.getIdentifierInfo(), *AliasName = 0;
|
||||
SourceLocation WeakNameLoc = Tok.getLocation(), AliasNameLoc;
|
||||
Token WeakName = Tok;
|
||||
bool HasAlias = false;
|
||||
Token AliasName;
|
||||
|
||||
PP.Lex(Tok);
|
||||
if (Tok.is(tok::equal)) {
|
||||
HasAlias = true;
|
||||
PP.Lex(Tok);
|
||||
if (Tok.isNot(tok::identifier)) {
|
||||
PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
|
||||
<< "weak";
|
||||
return;
|
||||
}
|
||||
AliasName = Tok.getIdentifierInfo();
|
||||
AliasNameLoc = Tok.getLocation();
|
||||
AliasName = Tok;
|
||||
PP.Lex(Tok);
|
||||
}
|
||||
|
||||
|
@ -457,11 +569,29 @@ void PragmaWeakHandler::HandlePragma(Preprocessor &PP,
|
|||
return;
|
||||
}
|
||||
|
||||
if (AliasName) {
|
||||
Actions.ActOnPragmaWeakAlias(WeakName, AliasName, WeakLoc, WeakNameLoc,
|
||||
AliasNameLoc);
|
||||
if (HasAlias) {
|
||||
Token *Toks =
|
||||
(Token*) PP.getPreprocessorAllocator().Allocate(
|
||||
sizeof(Token) * 3, llvm::alignOf<Token>());
|
||||
Token &pragmaUnusedTok = Toks[0];
|
||||
pragmaUnusedTok.startToken();
|
||||
pragmaUnusedTok.setKind(tok::annot_pragma_weakalias);
|
||||
pragmaUnusedTok.setLocation(WeakLoc);
|
||||
Toks[1] = WeakName;
|
||||
Toks[2] = AliasName;
|
||||
PP.EnterTokenStream(Toks, 3,
|
||||
/*DisableMacroExpansion=*/true, /*OwnsTokens=*/false);
|
||||
} else {
|
||||
Actions.ActOnPragmaWeakID(WeakName, WeakLoc, WeakNameLoc);
|
||||
Token *Toks =
|
||||
(Token*) PP.getPreprocessorAllocator().Allocate(
|
||||
sizeof(Token) * 2, llvm::alignOf<Token>());
|
||||
Token &pragmaUnusedTok = Toks[0];
|
||||
pragmaUnusedTok.startToken();
|
||||
pragmaUnusedTok.setKind(tok::annot_pragma_weak);
|
||||
pragmaUnusedTok.setLocation(WeakLoc);
|
||||
Toks[1] = WeakName;
|
||||
PP.EnterTokenStream(Toks, 2,
|
||||
/*DisableMacroExpansion=*/true, /*OwnsTokens=*/false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -479,17 +609,16 @@ void PragmaRedefineExtnameHandler::HandlePragma(Preprocessor &PP,
|
|||
return;
|
||||
}
|
||||
|
||||
IdentifierInfo *RedefName = Tok.getIdentifierInfo(), *AliasName = 0;
|
||||
SourceLocation RedefNameLoc = Tok.getLocation(), AliasNameLoc;
|
||||
|
||||
Token RedefName = Tok;
|
||||
PP.Lex(Tok);
|
||||
|
||||
if (Tok.isNot(tok::identifier)) {
|
||||
PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
|
||||
<< "redefine_extname";
|
||||
return;
|
||||
}
|
||||
AliasName = Tok.getIdentifierInfo();
|
||||
AliasNameLoc = Tok.getLocation();
|
||||
|
||||
Token AliasName = Tok;
|
||||
PP.Lex(Tok);
|
||||
|
||||
if (Tok.isNot(tok::eod)) {
|
||||
|
@ -498,8 +627,17 @@ void PragmaRedefineExtnameHandler::HandlePragma(Preprocessor &PP,
|
|||
return;
|
||||
}
|
||||
|
||||
Actions.ActOnPragmaRedefineExtname(RedefName, AliasName, RedefLoc,
|
||||
RedefNameLoc, AliasNameLoc);
|
||||
Token *Toks =
|
||||
(Token*) PP.getPreprocessorAllocator().Allocate(
|
||||
sizeof(Token) * 3, llvm::alignOf<Token>());
|
||||
Token &pragmaRedefTok = Toks[0];
|
||||
pragmaRedefTok.startToken();
|
||||
pragmaRedefTok.setKind(tok::annot_pragma_redefine_extname);
|
||||
pragmaRedefTok.setLocation(RedefLoc);
|
||||
Toks[1] = RedefName;
|
||||
Toks[2] = AliasName;
|
||||
PP.EnterTokenStream(Toks, 3,
|
||||
/*DisableMacroExpansion=*/true, /*OwnsTokens=*/false);
|
||||
}
|
||||
|
||||
|
||||
|
@ -511,7 +649,17 @@ PragmaFPContractHandler::HandlePragma(Preprocessor &PP,
|
|||
if (PP.LexOnOffSwitch(OOS))
|
||||
return;
|
||||
|
||||
Actions.ActOnPragmaFPContract(OOS);
|
||||
Token *Toks =
|
||||
(Token*) PP.getPreprocessorAllocator().Allocate(
|
||||
sizeof(Token) * 1, llvm::alignOf<Token>());
|
||||
new (Toks) Token();
|
||||
Toks[0].startToken();
|
||||
Toks[0].setKind(tok::annot_pragma_fp_contract);
|
||||
Toks[0].setLocation(Tok.getLocation());
|
||||
Toks[0].setAnnotationValue(reinterpret_cast<void*>(
|
||||
static_cast<uintptr_t>(OOS)));
|
||||
PP.EnterTokenStream(Toks, 1, /*DisableMacroExpansion=*/true,
|
||||
/*OwnsTokens=*/false);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -550,19 +698,23 @@ PragmaOpenCLExtensionHandler::HandlePragma(Preprocessor &PP,
|
|||
return;
|
||||
}
|
||||
|
||||
OpenCLOptions &f = Actions.getOpenCLOptions();
|
||||
// OpenCL 1.1 9.1: "The all variant sets the behavior for all extensions,
|
||||
// overriding all previously issued extension directives, but only if the
|
||||
// behavior is set to disable."
|
||||
if (state == 0 && ename->isStr("all")) {
|
||||
#define OPENCLEXT(nm) f.nm = 0;
|
||||
#include "clang/Basic/OpenCLExtensions.def"
|
||||
}
|
||||
#define OPENCLEXT(nm) else if (ename->isStr(#nm)) { f.nm = state; }
|
||||
#include "clang/Basic/OpenCLExtensions.def"
|
||||
else {
|
||||
PP.Diag(NameLoc, diag::warn_pragma_unknown_extension) << ename;
|
||||
PP.Lex(Tok);
|
||||
if (Tok.isNot(tok::eod)) {
|
||||
PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) <<
|
||||
"OPENCL EXTENSION";
|
||||
return;
|
||||
}
|
||||
|
||||
OpenCLExtData data(ename, state);
|
||||
Token *Toks =
|
||||
(Token*) PP.getPreprocessorAllocator().Allocate(
|
||||
sizeof(Token) * 1, llvm::alignOf<Token>());
|
||||
new (Toks) Token();
|
||||
Toks[0].startToken();
|
||||
Toks[0].setKind(tok::annot_pragma_opencl_extension);
|
||||
Toks[0].setLocation(NameLoc);
|
||||
Toks[0].setAnnotationValue(data.getOpaqueValue());
|
||||
PP.EnterTokenStream(Toks, 1, /*DisableMacroExpansion=*/true,
|
||||
/*OwnsTokens=*/false);
|
||||
}
|
||||
|
||||
|
|
|
@ -21,9 +21,8 @@ namespace clang {
|
|||
class Parser;
|
||||
|
||||
class PragmaAlignHandler : public PragmaHandler {
|
||||
Sema &Actions;
|
||||
public:
|
||||
explicit PragmaAlignHandler(Sema &A) : PragmaHandler("align"), Actions(A) {}
|
||||
explicit PragmaAlignHandler() : PragmaHandler("align") {}
|
||||
|
||||
virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
|
||||
Token &FirstToken);
|
||||
|
@ -31,38 +30,31 @@ public:
|
|||
|
||||
class PragmaGCCVisibilityHandler : public PragmaHandler {
|
||||
public:
|
||||
explicit PragmaGCCVisibilityHandler(Sema &/*A*/)
|
||||
: PragmaHandler("visibility") {}
|
||||
explicit PragmaGCCVisibilityHandler() : PragmaHandler("visibility") {}
|
||||
|
||||
virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
|
||||
Token &FirstToken);
|
||||
};
|
||||
|
||||
class PragmaOptionsHandler : public PragmaHandler {
|
||||
Sema &Actions;
|
||||
public:
|
||||
explicit PragmaOptionsHandler(Sema &A) : PragmaHandler("options"),
|
||||
Actions(A) {}
|
||||
explicit PragmaOptionsHandler() : PragmaHandler("options") {}
|
||||
|
||||
virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
|
||||
Token &FirstToken);
|
||||
};
|
||||
|
||||
class PragmaPackHandler : public PragmaHandler {
|
||||
Sema &Actions;
|
||||
public:
|
||||
explicit PragmaPackHandler(Sema &A) : PragmaHandler("pack"),
|
||||
Actions(A) {}
|
||||
explicit PragmaPackHandler() : PragmaHandler("pack") {}
|
||||
|
||||
virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
|
||||
Token &FirstToken);
|
||||
};
|
||||
|
||||
class PragmaMSStructHandler : public PragmaHandler {
|
||||
Sema &Actions;
|
||||
public:
|
||||
explicit PragmaMSStructHandler(Sema &A) : PragmaHandler("ms_struct"),
|
||||
Actions(A) {}
|
||||
explicit PragmaMSStructHandler() : PragmaHandler("ms_struct") {}
|
||||
|
||||
virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
|
||||
Token &FirstToken);
|
||||
|
@ -70,48 +62,39 @@ public:
|
|||
|
||||
class PragmaUnusedHandler : public PragmaHandler {
|
||||
public:
|
||||
PragmaUnusedHandler(Sema &/*A*/)
|
||||
: PragmaHandler("unused") {}
|
||||
PragmaUnusedHandler() : PragmaHandler("unused") {}
|
||||
|
||||
virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
|
||||
Token &FirstToken);
|
||||
};
|
||||
|
||||
class PragmaWeakHandler : public PragmaHandler {
|
||||
Sema &Actions;
|
||||
public:
|
||||
explicit PragmaWeakHandler(Sema &A)
|
||||
: PragmaHandler("weak"), Actions(A) {}
|
||||
explicit PragmaWeakHandler() : PragmaHandler("weak") {}
|
||||
|
||||
virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
|
||||
Token &FirstToken);
|
||||
};
|
||||
|
||||
class PragmaRedefineExtnameHandler : public PragmaHandler {
|
||||
Sema &Actions;
|
||||
public:
|
||||
explicit PragmaRedefineExtnameHandler(Sema &A)
|
||||
: PragmaHandler("redefine_extname"), Actions(A) {}
|
||||
explicit PragmaRedefineExtnameHandler() : PragmaHandler("redefine_extname") {}
|
||||
|
||||
virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
|
||||
Token &FirstToken);
|
||||
};
|
||||
|
||||
class PragmaOpenCLExtensionHandler : public PragmaHandler {
|
||||
Sema &Actions;
|
||||
public:
|
||||
PragmaOpenCLExtensionHandler(Sema &A) :
|
||||
PragmaHandler("EXTENSION"), Actions(A) {}
|
||||
PragmaOpenCLExtensionHandler() : PragmaHandler("EXTENSION") {}
|
||||
virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
|
||||
Token &FirstToken);
|
||||
};
|
||||
|
||||
|
||||
class PragmaFPContractHandler : public PragmaHandler {
|
||||
Sema &Actions;
|
||||
public:
|
||||
PragmaFPContractHandler(Sema &A) :
|
||||
PragmaHandler("FP_CONTRACT"), Actions(A) {}
|
||||
PragmaFPContractHandler() : PragmaHandler("FP_CONTRACT") {}
|
||||
virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
|
||||
Token &FirstToken);
|
||||
};
|
||||
|
|
|
@ -253,6 +253,16 @@ Retry:
|
|||
ProhibitAttributes(Attrs);
|
||||
HandlePragmaPack();
|
||||
return StmtEmpty();
|
||||
|
||||
case tok::annot_pragma_fp_contract:
|
||||
ProhibitAttributes(Attrs);
|
||||
HandlePragmaFPContract();
|
||||
return StmtEmpty();
|
||||
|
||||
case tok::annot_pragma_opencl_extension:
|
||||
ProhibitAttributes(Attrs);
|
||||
HandlePragmaOpenCLExtension();
|
||||
return StmtEmpty();
|
||||
}
|
||||
|
||||
// If we reached this code, the statement must end in a semicolon.
|
||||
|
|
|
@ -60,35 +60,35 @@ Parser::Parser(Preprocessor &pp, Sema &actions, bool SkipFunctionBodies)
|
|||
|
||||
// Add #pragma handlers. These are removed and destroyed in the
|
||||
// destructor.
|
||||
AlignHandler.reset(new PragmaAlignHandler(actions));
|
||||
AlignHandler.reset(new PragmaAlignHandler());
|
||||
PP.AddPragmaHandler(AlignHandler.get());
|
||||
|
||||
GCCVisibilityHandler.reset(new PragmaGCCVisibilityHandler(actions));
|
||||
GCCVisibilityHandler.reset(new PragmaGCCVisibilityHandler());
|
||||
PP.AddPragmaHandler("GCC", GCCVisibilityHandler.get());
|
||||
|
||||
OptionsHandler.reset(new PragmaOptionsHandler(actions));
|
||||
OptionsHandler.reset(new PragmaOptionsHandler());
|
||||
PP.AddPragmaHandler(OptionsHandler.get());
|
||||
|
||||
PackHandler.reset(new PragmaPackHandler(actions));
|
||||
PackHandler.reset(new PragmaPackHandler());
|
||||
PP.AddPragmaHandler(PackHandler.get());
|
||||
|
||||
MSStructHandler.reset(new PragmaMSStructHandler(actions));
|
||||
MSStructHandler.reset(new PragmaMSStructHandler());
|
||||
PP.AddPragmaHandler(MSStructHandler.get());
|
||||
|
||||
UnusedHandler.reset(new PragmaUnusedHandler(actions));
|
||||
UnusedHandler.reset(new PragmaUnusedHandler());
|
||||
PP.AddPragmaHandler(UnusedHandler.get());
|
||||
|
||||
WeakHandler.reset(new PragmaWeakHandler(actions));
|
||||
WeakHandler.reset(new PragmaWeakHandler());
|
||||
PP.AddPragmaHandler(WeakHandler.get());
|
||||
|
||||
RedefineExtnameHandler.reset(new PragmaRedefineExtnameHandler(actions));
|
||||
RedefineExtnameHandler.reset(new PragmaRedefineExtnameHandler());
|
||||
PP.AddPragmaHandler(RedefineExtnameHandler.get());
|
||||
|
||||
FPContractHandler.reset(new PragmaFPContractHandler(actions));
|
||||
FPContractHandler.reset(new PragmaFPContractHandler());
|
||||
PP.AddPragmaHandler("STDC", FPContractHandler.get());
|
||||
|
||||
if (getLangOpts().OpenCL) {
|
||||
OpenCLExtensionHandler.reset(new PragmaOpenCLExtensionHandler(actions));
|
||||
OpenCLExtensionHandler.reset(new PragmaOpenCLExtensionHandler());
|
||||
PP.AddPragmaHandler("OPENCL", OpenCLExtensionHandler.get());
|
||||
|
||||
PP.AddPragmaHandler("OPENCL", FPContractHandler.get());
|
||||
|
@ -635,6 +635,27 @@ Parser::ParseExternalDeclaration(ParsedAttributesWithRange &attrs,
|
|||
case tok::annot_pragma_pack:
|
||||
HandlePragmaPack();
|
||||
return DeclGroupPtrTy();
|
||||
case tok::annot_pragma_msstruct:
|
||||
HandlePragmaMSStruct();
|
||||
return DeclGroupPtrTy();
|
||||
case tok::annot_pragma_align:
|
||||
HandlePragmaAlign();
|
||||
return DeclGroupPtrTy();
|
||||
case tok::annot_pragma_weak:
|
||||
HandlePragmaWeak();
|
||||
return DeclGroupPtrTy();
|
||||
case tok::annot_pragma_weakalias:
|
||||
HandlePragmaWeakAlias();
|
||||
return DeclGroupPtrTy();
|
||||
case tok::annot_pragma_redefine_extname:
|
||||
HandlePragmaRedefineExtname();
|
||||
return DeclGroupPtrTy();
|
||||
case tok::annot_pragma_fp_contract:
|
||||
HandlePragmaFPContract();
|
||||
return DeclGroupPtrTy();
|
||||
case tok::annot_pragma_opencl_extension:
|
||||
HandlePragmaOpenCLExtension();
|
||||
return DeclGroupPtrTy();
|
||||
case tok::semi:
|
||||
ConsumeExtraSemi(OutsideFunction);
|
||||
// TODO: Invoke action for top-level semicolon.
|
||||
|
|
|
@ -136,23 +136,12 @@ void Sema::AddMsStructLayoutForRecord(RecordDecl *RD) {
|
|||
}
|
||||
|
||||
void Sema::ActOnPragmaOptionsAlign(PragmaOptionsAlignKind Kind,
|
||||
SourceLocation PragmaLoc,
|
||||
SourceLocation KindLoc) {
|
||||
SourceLocation PragmaLoc) {
|
||||
if (PackContext == 0)
|
||||
PackContext = new PragmaPackStack();
|
||||
|
||||
PragmaPackStack *Context = static_cast<PragmaPackStack*>(PackContext);
|
||||
|
||||
// Reset just pops the top of the stack, or resets the current alignment to
|
||||
// default.
|
||||
if (Kind == Sema::POAK_Reset) {
|
||||
if (!Context->pop(0, /*IsReset=*/true)) {
|
||||
Diag(PragmaLoc, diag::warn_pragma_options_align_reset_failed)
|
||||
<< "stack empty";
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
switch (Kind) {
|
||||
// For all targets we support native and natural are the same.
|
||||
//
|
||||
|
@ -181,9 +170,13 @@ void Sema::ActOnPragmaOptionsAlign(PragmaOptionsAlignKind Kind,
|
|||
Context->setAlignment(PackStackEntry::kMac68kAlignmentSentinel);
|
||||
break;
|
||||
|
||||
default:
|
||||
Diag(PragmaLoc, diag::warn_pragma_options_align_unsupported_option)
|
||||
<< KindLoc;
|
||||
case POAK_Reset:
|
||||
// Reset just pops the top of the stack, or resets the current alignment to
|
||||
// default.
|
||||
if (!Context->pop(0, /*IsReset=*/true)) {
|
||||
Diag(PragmaLoc, diag::warn_pragma_options_align_reset_failed)
|
||||
<< "stack empty";
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,3 +34,15 @@ float fp_contract_3(float a, float b, float c) {
|
|||
// CHECK: tail call float @llvm.fmuladd
|
||||
return template_muladd<float>(a, b, c);
|
||||
}
|
||||
|
||||
template<typename T> class fp_contract_4 {
|
||||
float method(float a, float b, float c) {
|
||||
#pragma STDC FP_CONTRACT ON
|
||||
return a * b + c;
|
||||
#pragma STDC FP_CONTRACT OFF
|
||||
}
|
||||
};
|
||||
|
||||
template class fp_contract_4<int>;
|
||||
// CHECK: _ZN13fp_contract_4IiE6methodEfff
|
||||
// CHECK: tail call float @llvm.fmuladd
|
||||
|
|
|
@ -18,7 +18,7 @@ This test serves two purposes:
|
|||
|
||||
The list of warnings below should NEVER grow. It should gradually shrink to 0.
|
||||
|
||||
CHECK: Warnings without flags (158):
|
||||
CHECK: Warnings without flags (157):
|
||||
CHECK-NEXT: ext_delete_void_ptr_operand
|
||||
CHECK-NEXT: ext_enum_friend
|
||||
CHECK-NEXT: ext_expected_semi_decl_list
|
||||
|
@ -133,7 +133,6 @@ CHECK-NEXT: warn_pragma_expected_rparen
|
|||
CHECK-NEXT: warn_pragma_extra_tokens_at_eol
|
||||
CHECK-NEXT: warn_pragma_ms_struct
|
||||
CHECK-NEXT: warn_pragma_options_align_reset_failed
|
||||
CHECK-NEXT: warn_pragma_options_align_unsupported_option
|
||||
CHECK-NEXT: warn_pragma_options_expected_align
|
||||
CHECK-NEXT: warn_pragma_pack_invalid_action
|
||||
CHECK-NEXT: warn_pragma_pack_invalid_alignment
|
||||
|
|
|
@ -38,5 +38,16 @@ struct s3 {
|
|||
};
|
||||
extern int a[sizeof(struct s3) == 8 ? 1 : -1];
|
||||
|
||||
#pragma pack(push,2)
|
||||
#pragma options align=power
|
||||
struct s4 {
|
||||
char c;
|
||||
int x;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
#pragma options align=reset
|
||||
extern int a[sizeof(struct s4) == 8 ? 1 : -1];
|
||||
|
||||
/* expected-warning {{#pragma options align=reset failed: stack empty}} */ #pragma options align=reset
|
||||
/* expected-warning {{#pragma pack(pop, ...) failed: stack empty}} */ #pragma pack(pop)
|
||||
|
||||
|
|
Loading…
Reference in New Issue