virtual DeclTy *ActOnStaticAssertDeclaration(SourceLocation AssertLoc,
ExprArg AssertExpr,
- ExprArg AssertMessageExpr,
- SourceLocation RParenLoc) {
+ ExprArg AssertMessageExpr) {
llvm::cout << __FUNCTION__ << "\n";
return 0;
}
};
class StaticAssertDecl : public Decl {
- SourceLocation AssertLoc;
-
Expr *AssertExpr;
StringLiteral *Message;
-
+
StaticAssertDecl(DeclContext *DC, SourceLocation L,
Expr *assertexpr, StringLiteral *message)
- : Decl(StaticAssert, DC, L), AssertExpr(assertexpr), Message(message) { }
+ : Decl(StaticAssert, DC, L), AssertExpr(assertexpr), Message(message) { }
public:
static StaticAssertDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L, Expr *AssertExpr,
StringLiteral *Message);
+ Expr *getAssertExpr() { return AssertExpr; }
+ const Expr *getAssertExpr() const { return AssertExpr; }
+
+ StringLiteral *getMessage() { return Message; }
+ const StringLiteral *getMessage() const { return Message; }
+
virtual ~StaticAssertDecl();
virtual void Destroy(ASTContext& C);
/// ActOnStaticAssertDeclaration - Parse a C++0x static_assert declaration.
virtual DeclTy *ActOnStaticAssertDeclaration(SourceLocation AssertLoc,
ExprArg AssertExpr,
- ExprArg AssertMessageExpr,
- SourceLocation RParenLoc) {
+ ExprArg AssertMessageExpr) {
return 0;
}
if (AssertMessage.isInvalid())
return 0;
- SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
+ MatchRHSPunctuation(tok::r_paren, LParenLoc);
ExpectAndConsume(tok::semi, diag::err_expected_semi_after_static_assert);
return Actions.ActOnStaticAssertDeclaration(StaticAssertLoc, move(AssertExpr),
- move(AssertMessage),
- RParenLoc);
+ move(AssertMessage));
}
/// ParseClassName - Parse a C++ class-name, which names a class. Note
virtual DeclTy *ActOnStaticAssertDeclaration(SourceLocation AssertLoc,
ExprArg AssertExpr,
- ExprArg AssertMessageExpr,
- SourceLocation RParenLoc);
+ ExprArg AssertMessageExpr);
bool CheckConstructorDeclarator(Declarator &D, QualType &R,
FunctionDecl::StorageClass& SC);
Sema::DeclTy *Sema::ActOnStaticAssertDeclaration(SourceLocation AssertLoc,
ExprArg assertexpr,
- ExprArg assertmessageexpr,
- SourceLocation RParenLoc) {
+ ExprArg assertmessageexpr) {
Expr *AssertExpr = (Expr *)assertexpr.get();
StringLiteral *AssertMessage =
cast<StringLiteral>((Expr *)assertmessageexpr.get());
if (Value == 0) {
std::string str(AssertMessage->getStrData(),
AssertMessage->getByteLength());
- Diag(AssertLoc, diag::err_static_assert_failed) << str;
+ Diag(AssertLoc, diag::err_static_assert_failed)
+ << str << AssertExpr->getSourceRange();
}
}
if (New->isInvalidDecl())
Invalid = true;
}
+ } else if (StaticAssertDecl *SA = dyn_cast<StaticAssertDecl>(*Member)) {
+ Expr *AssertExpr = SA->getAssertExpr();
+
+ OwningExprResult InstantiatedAssertExpr
+ = InstantiateExpr(AssertExpr,
+ ClassTemplateSpec->getTemplateArgs(),
+ ClassTemplateSpec->getNumTemplateArgs());
+ if (!InstantiatedAssertExpr.isInvalid()) {
+ OwningExprResult Message = Clone(SA->getMessage());
+
+ Decl *New =
+ (Decl *)ActOnStaticAssertDeclaration(SA->getLocation(),
+ move(InstantiatedAssertExpr),
+ move(Message));
+ if (New->isInvalidDecl())
+ Invalid = true;
+
+ } else
+ Invalid = true;
}
}
};
template<int N> struct T {
- static_assert(N == 2, "N is not 2!");
+ static_assert(N == 2, "N is not 2!"); // expected-error {{static_assert failed "N is not 2!"}}
};
+T<1> t1; // expected-note {{in instantiation of template class 'struct T<1>' requested here}}
+T<2> t2;
+
template<typename T> struct S {
- static_assert(sizeof(T) > sizeof(char), "Type not big enough!");
+ static_assert(sizeof(T) > sizeof(char), "Type not big enough!"); // expected-error {{static_assert failed "Type not big enough!"}}
};
+S<char> s1; // expected-note {{in instantiation of template class 'struct S<char>' requested here}}
+S<int> s2;
+