summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/tools/clang/lib/Sema/DeclSpec.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Sema/DeclSpec.cpp')
-rw-r--r--contrib/llvm/tools/clang/lib/Sema/DeclSpec.cpp38
1 files changed, 26 insertions, 12 deletions
diff --git a/contrib/llvm/tools/clang/lib/Sema/DeclSpec.cpp b/contrib/llvm/tools/clang/lib/Sema/DeclSpec.cpp
index d12ca78..b3066eb 100644
--- a/contrib/llvm/tools/clang/lib/Sema/DeclSpec.cpp
+++ b/contrib/llvm/tools/clang/lib/Sema/DeclSpec.cpp
@@ -144,11 +144,13 @@ CXXScopeSpec::getWithLocInContext(ASTContext &Context) const {
/// DeclaratorChunk::getFunction - Return a DeclaratorChunk for a function.
/// "TheDeclarator" is the declarator that this will be added to.
-DeclaratorChunk DeclaratorChunk::getFunction(bool hasProto, bool isVariadic,
+DeclaratorChunk DeclaratorChunk::getFunction(bool hasProto,
bool isAmbiguous,
- SourceLocation EllipsisLoc,
+ SourceLocation LParenLoc,
ParamInfo *ArgInfo,
unsigned NumArgs,
+ SourceLocation EllipsisLoc,
+ SourceLocation RParenLoc,
unsigned TypeQuals,
bool RefQualifierIsLvalueRef,
SourceLocation RefQualifierLoc,
@@ -173,9 +175,11 @@ DeclaratorChunk DeclaratorChunk::getFunction(bool hasProto, bool isVariadic,
I.EndLoc = LocalRangeEnd;
I.Fun.AttrList = 0;
I.Fun.hasPrototype = hasProto;
- I.Fun.isVariadic = isVariadic;
+ I.Fun.isVariadic = EllipsisLoc.isValid();
I.Fun.isAmbiguous = isAmbiguous;
+ I.Fun.LParenLoc = LParenLoc.getRawEncoding();
I.Fun.EllipsisLoc = EllipsisLoc.getRawEncoding();
+ I.Fun.RParenLoc = RParenLoc.getRawEncoding();
I.Fun.DeleteArgInfo = false;
I.Fun.TypeQuals = TypeQuals;
I.Fun.NumArgs = NumArgs;
@@ -270,6 +274,7 @@ bool Declarator::isDeclarationOfFunction() const {
case TST_int:
case TST_int128:
case TST_struct:
+ case TST_interface:
case TST_union:
case TST_unknown_anytype:
case TST_unspecified:
@@ -325,10 +330,14 @@ unsigned DeclSpec::getParsedSpecifiers() const {
template <class T> static bool BadSpecifier(T TNew, T TPrev,
const char *&PrevSpec,
- unsigned &DiagID) {
+ unsigned &DiagID,
+ bool IsExtension = true) {
PrevSpec = DeclSpec::getSpecifierName(TPrev);
- DiagID = (TNew == TPrev ? diag::ext_duplicate_declspec
- : diag::err_invalid_decl_spec_combination);
+ if (TNew != TPrev)
+ DiagID = diag::err_invalid_decl_spec_combination;
+ else
+ DiagID = IsExtension ? diag::ext_duplicate_declspec :
+ diag::warn_duplicate_declspec;
return true;
}
@@ -396,6 +405,7 @@ const char *DeclSpec::getSpecifierName(DeclSpec::TST T) {
case DeclSpec::TST_class: return "class";
case DeclSpec::TST_union: return "union";
case DeclSpec::TST_struct: return "struct";
+ case DeclSpec::TST_interface: return "__interface";
case DeclSpec::TST_typename: return "type-name";
case DeclSpec::TST_typeofType:
case DeclSpec::TST_typeofExpr: return "typeof";
@@ -670,12 +680,16 @@ bool DeclSpec::SetTypeSpecError() {
}
bool DeclSpec::SetTypeQual(TQ T, SourceLocation Loc, const char *&PrevSpec,
- unsigned &DiagID, const LangOptions &Lang,
- bool IsTypeSpec) {
- // Duplicates are permitted in C99, and are permitted in C++11 unless the
- // cv-qualifier appears as a type-specifier.
- if ((TypeQualifiers & T) && !Lang.C99 && (!Lang.CPlusPlus0x || IsTypeSpec))
- return BadSpecifier(T, T, PrevSpec, DiagID);
+ unsigned &DiagID, const LangOptions &Lang) {
+ // Duplicates are permitted in C99, but are not permitted in C++. However,
+ // since this is likely not what the user intended, we will always warn. We
+ // do not need to set the qualifier's location since we already have it.
+ if (TypeQualifiers & T) {
+ bool IsExtension = true;
+ if (Lang.C99)
+ IsExtension = false;
+ return BadSpecifier(T, T, PrevSpec, DiagID, IsExtension);
+ }
TypeQualifiers |= T;
switch (T) {
OpenPOWER on IntegriCloud