diff options
Diffstat (limited to 'lib/Sema/DeclSpec.cpp')
| -rw-r--r-- | lib/Sema/DeclSpec.cpp | 100 | 
1 files changed, 87 insertions, 13 deletions
| diff --git a/lib/Sema/DeclSpec.cpp b/lib/Sema/DeclSpec.cpp index 3b3ab2c27b4a..c2f16157b8eb 100644 --- a/lib/Sema/DeclSpec.cpp +++ b/lib/Sema/DeclSpec.cpp @@ -13,6 +13,7 @@  #include "clang/Sema/DeclSpec.h"  #include "clang/AST/ASTContext.h" +#include "clang/AST/DeclCXX.h"  #include "clang/AST/Expr.h"  #include "clang/AST/NestedNameSpecifier.h"  #include "clang/AST/TypeLoc.h" @@ -325,6 +326,19 @@ bool Declarator::isDeclarationOfFunction() const {    llvm_unreachable("Invalid TypeSpecType!");  } +bool Declarator::isStaticMember() { +  assert(getContext() == MemberContext); +  return getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_static || +         CXXMethodDecl::isStaticOverloadedOperator( +             getName().OperatorFunctionId.Operator); +} + +bool DeclSpec::hasTagDefinition() const { +  if (!TypeSpecOwned) +    return false; +  return cast<TagDecl>(getRepAsDecl())->isCompleteDefinition(); +} +  /// getParsedSpecifiers - Return a bitmask of which flavors of specifiers this  /// declaration specifier includes.  /// @@ -341,7 +355,7 @@ unsigned DeclSpec::getParsedSpecifiers() const {      Res |= PQ_TypeSpecifier;    if (FS_inline_specified || FS_virtual_specified || FS_explicit_specified || -      FS_noreturn_specified) +      FS_noreturn_specified || FS_forceinline_specified)      Res |= PQ_FunctionSpecifier;    return Res;  } @@ -651,7 +665,7 @@ bool DeclSpec::SetTypeSpecType(TST T, SourceLocation TagKwLoc,    DeclRep = Rep;    TSTLoc = TagKwLoc;    TSTNameLoc = TagNameLoc; -  TypeSpecOwned = Owned; +  TypeSpecOwned = Owned && Rep != 0;    return false;  } @@ -707,6 +721,20 @@ bool DeclSpec::SetTypeAltiVecPixel(bool isAltiVecPixel, SourceLocation Loc,    return false;  } +bool DeclSpec::SetTypeAltiVecBool(bool isAltiVecBool, SourceLocation Loc, +                          const char *&PrevSpec, unsigned &DiagID) { +  if (!TypeAltiVecVector || TypeAltiVecBool || +      (TypeSpecType != TST_unspecified)) { +    PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType); +    DiagID = diag::err_invalid_vector_bool_decl_spec; +    return true; +  } +  TypeAltiVecBool = isAltiVecBool; +  TSTLoc = Loc; +  TSTNameLoc = Loc; +  return false; +} +  bool DeclSpec::SetTypeSpecError() {    TypeSpecType = TST_error;    TypeSpecOwned = false; @@ -717,9 +745,10 @@ bool DeclSpec::SetTypeSpecError() {  bool DeclSpec::SetTypeQual(TQ T, SourceLocation Loc, const char *&PrevSpec,                             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. +  // Duplicates are permitted in C99 onwards, but are not permitted in C89 or +  // 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) @@ -739,29 +768,72 @@ bool DeclSpec::SetTypeQual(TQ T, SourceLocation Loc, const char *&PrevSpec,    llvm_unreachable("Unknown type qualifier!");  } -bool DeclSpec::setFunctionSpecInline(SourceLocation Loc) { -  // 'inline inline' is ok. +bool DeclSpec::setFunctionSpecInline(SourceLocation Loc, const char *&PrevSpec, +                                     unsigned &DiagID) { +  // 'inline inline' is ok.  However, since this is likely not what the user +  // intended, we will always warn, similar to duplicates of type qualifiers. +  if (FS_inline_specified) { +    DiagID = diag::warn_duplicate_declspec; +    PrevSpec = "inline"; +    return true; +  }    FS_inline_specified = true;    FS_inlineLoc = Loc;    return false;  } -bool DeclSpec::setFunctionSpecVirtual(SourceLocation Loc) { -  // 'virtual virtual' is ok. +bool DeclSpec::setFunctionSpecForceInline(SourceLocation Loc, const char *&PrevSpec, +                                          unsigned &DiagID) { +  if (FS_forceinline_specified) { +    DiagID = diag::warn_duplicate_declspec; +    PrevSpec = "__forceinline"; +    return true; +  } +  FS_forceinline_specified = true; +  FS_forceinlineLoc = Loc; +  return false; +} + +bool DeclSpec::setFunctionSpecVirtual(SourceLocation Loc, +                                      const char *&PrevSpec, +                                      unsigned &DiagID) { +  // 'virtual virtual' is ok, but warn as this is likely not what the user +  // intended. +  if (FS_virtual_specified) { +    DiagID = diag::warn_duplicate_declspec; +    PrevSpec = "virtual"; +    return true; +  }    FS_virtual_specified = true;    FS_virtualLoc = Loc;    return false;  } -bool DeclSpec::setFunctionSpecExplicit(SourceLocation Loc) { -  // 'explicit explicit' is ok. +bool DeclSpec::setFunctionSpecExplicit(SourceLocation Loc, +                                       const char *&PrevSpec, +                                       unsigned &DiagID) { +  // 'explicit explicit' is ok, but warn as this is likely not what the user +  // intended. +  if (FS_explicit_specified) { +    DiagID = diag::warn_duplicate_declspec; +    PrevSpec = "explicit"; +    return true; +  }    FS_explicit_specified = true;    FS_explicitLoc = Loc;    return false;  } -bool DeclSpec::setFunctionSpecNoreturn(SourceLocation Loc) { -  // '_Noreturn _Noreturn' is ok. +bool DeclSpec::setFunctionSpecNoreturn(SourceLocation Loc, +                                       const char *&PrevSpec, +                                       unsigned &DiagID) { +  // '_Noreturn _Noreturn' is ok, but warn as this is likely not what the user +  // intended. +  if (FS_noreturn_specified) { +    DiagID = diag::warn_duplicate_declspec; +    PrevSpec = "_Noreturn"; +    return true; +  }    FS_noreturn_specified = true;    FS_noreturnLoc = Loc;    return false; @@ -1096,6 +1168,7 @@ bool VirtSpecifiers::SetSpecifier(Specifier VS, SourceLocation Loc,    switch (VS) {    default: llvm_unreachable("Unknown specifier!");    case VS_Override: VS_overrideLoc = Loc; break; +  case VS_Sealed:    case VS_Final:    VS_finalLoc = Loc; break;    } @@ -1107,5 +1180,6 @@ const char *VirtSpecifiers::getSpecifierName(Specifier VS) {    default: llvm_unreachable("Unknown specifier");    case VS_Override: return "override";    case VS_Final: return "final"; +  case VS_Sealed: return "sealed";    }  } | 
