diff options
author | dim <dim@FreeBSD.org> | 2011-02-20 13:06:31 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2011-02-20 13:06:31 +0000 |
commit | 39fcc9a984e2820e4ea0fa2ac4abd17d9f3a31df (patch) | |
tree | a9243275843fbeaa590afc07ee888e006b8d54ea /lib/Sema/DeclSpec.cpp | |
parent | 69b4eca4a4255ba43baa5c1d9bbdec3ec17f479e (diff) | |
download | FreeBSD-src-39fcc9a984e2820e4ea0fa2ac4abd17d9f3a31df.zip FreeBSD-src-39fcc9a984e2820e4ea0fa2ac4abd17d9f3a31df.tar.gz |
Vendor import of clang trunk r126079:
http://llvm.org/svn/llvm-project/cfe/trunk@126079
Diffstat (limited to 'lib/Sema/DeclSpec.cpp')
-rw-r--r-- | lib/Sema/DeclSpec.cpp | 114 |
1 files changed, 97 insertions, 17 deletions
diff --git a/lib/Sema/DeclSpec.cpp b/lib/Sema/DeclSpec.cpp index b46e8af..bc289ec 100644 --- a/lib/Sema/DeclSpec.cpp +++ b/lib/Sema/DeclSpec.cpp @@ -23,8 +23,8 @@ using namespace clang; static DiagnosticBuilder Diag(Diagnostic &D, SourceLocation Loc, - SourceManager &SrcMgr, unsigned DiagID) { - return D.Report(FullSourceLoc(Loc, SrcMgr), DiagID); + unsigned DiagID) { + return D.Report(Loc, DiagID); } @@ -46,11 +46,14 @@ void UnqualifiedId::setConstructorTemplateId(TemplateIdAnnotation *TemplateId) { /// 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(const ParsedAttributes &attrs, + bool hasProto, bool isVariadic, SourceLocation EllipsisLoc, ParamInfo *ArgInfo, unsigned NumArgs, unsigned TypeQuals, + bool RefQualifierIsLvalueRef, + SourceLocation RefQualifierLoc, bool hasExceptionSpec, SourceLocation ThrowLoc, bool hasAnyExceptionSpec, @@ -59,11 +62,13 @@ DeclaratorChunk DeclaratorChunk::getFunction(bool hasProto, bool isVariadic, unsigned NumExceptions, SourceLocation LPLoc, SourceLocation RPLoc, - Declarator &TheDeclarator) { + Declarator &TheDeclarator, + ParsedType TrailingReturnType) { DeclaratorChunk I; I.Kind = Function; I.Loc = LPLoc; I.EndLoc = RPLoc; + I.Fun.AttrList = attrs.getList(); I.Fun.hasPrototype = hasProto; I.Fun.isVariadic = isVariadic; I.Fun.EllipsisLoc = EllipsisLoc.getRawEncoding(); @@ -71,11 +76,14 @@ DeclaratorChunk DeclaratorChunk::getFunction(bool hasProto, bool isVariadic, I.Fun.TypeQuals = TypeQuals; I.Fun.NumArgs = NumArgs; I.Fun.ArgInfo = 0; + I.Fun.RefQualifierIsLValueRef = RefQualifierIsLvalueRef; + I.Fun.RefQualifierLoc = RefQualifierLoc.getRawEncoding(); I.Fun.hasExceptionSpec = hasExceptionSpec; I.Fun.ThrowLoc = ThrowLoc.getRawEncoding(); I.Fun.hasAnyExceptionSpec = hasAnyExceptionSpec; I.Fun.NumExceptions = NumExceptions; I.Fun.Exceptions = 0; + I.Fun.TrailingReturnType = TrailingReturnType.getAsOpaquePtr(); // new[] an argument array if needed. if (NumArgs) { @@ -218,7 +226,25 @@ const char *DeclSpec::getSpecifierName(TQ T) { bool DeclSpec::SetStorageClassSpec(SCS S, SourceLocation Loc, const char *&PrevSpec, - unsigned &DiagID) { + unsigned &DiagID, + const LangOptions &Lang) { + // OpenCL prohibits extern, auto, register, and static + // It seems sensible to prohibit private_extern too + if (Lang.OpenCL) { + switch (S) { + case SCS_extern: + case SCS_private_extern: + case SCS_auto: + case SCS_register: + case SCS_static: + DiagID = diag::err_not_opencl_storage_class_specifier; + PrevSpec = getSpecifierName(S); + return true; + default: + break; + } + } + if (StorageClassSpec != SCS_unspecified) { // Changing storage class is allowed only if the previous one // was the 'extern' that is part of a linkage specification and @@ -481,7 +507,7 @@ void DeclSpec::SaveWrittenBuiltinSpecs() { writtenBS.Type = getTypeSpecType(); // Search the list of attributes for the presence of a mode attribute. writtenBS.ModeAttr = false; - AttributeList* attrs = getAttributes(); + AttributeList* attrs = getAttributes().getList(); while (attrs) { if (attrs->getKind() == AttributeList::AT_mode) { writtenBS.ModeAttr = true; @@ -510,28 +536,27 @@ void DeclSpec::Finish(Diagnostic &D, Preprocessor &PP) { SaveStorageSpecifierAsWritten(); // Check the type specifier components first. - SourceManager &SrcMgr = PP.getSourceManager(); // Validate and finalize AltiVec vector declspec. if (TypeAltiVecVector) { if (TypeAltiVecBool) { // Sign specifiers are not allowed with vector bool. (PIM 2.1) if (TypeSpecSign != TSS_unspecified) { - Diag(D, TSSLoc, SrcMgr, diag::err_invalid_vector_bool_decl_spec) + Diag(D, TSSLoc, diag::err_invalid_vector_bool_decl_spec) << getSpecifierName((TSS)TypeSpecSign); } // Only char/int are valid with vector bool. (PIM 2.1) if (((TypeSpecType != TST_unspecified) && (TypeSpecType != TST_char) && (TypeSpecType != TST_int)) || TypeAltiVecPixel) { - Diag(D, TSTLoc, SrcMgr, diag::err_invalid_vector_bool_decl_spec) + Diag(D, TSTLoc, diag::err_invalid_vector_bool_decl_spec) << (TypeAltiVecPixel ? "__pixel" : getSpecifierName((TST)TypeSpecType)); } // Only 'short' is valid with vector bool. (PIM 2.1) if ((TypeSpecWidth != TSW_unspecified) && (TypeSpecWidth != TSW_short)) - Diag(D, TSWLoc, SrcMgr, diag::err_invalid_vector_bool_decl_spec) + Diag(D, TSWLoc, diag::err_invalid_vector_bool_decl_spec) << getSpecifierName((TSW)TypeSpecWidth); // Elements of vector bool are interpreted as unsigned. (PIM 2.1) @@ -555,7 +580,7 @@ void DeclSpec::Finish(Diagnostic &D, Preprocessor &PP) { TypeSpecType = TST_int; // unsigned -> unsigned int, signed -> signed int. else if (TypeSpecType != TST_int && TypeSpecType != TST_char && TypeSpecType != TST_wchar) { - Diag(D, TSSLoc, SrcMgr, diag::err_invalid_sign_spec) + Diag(D, TSSLoc, diag::err_invalid_sign_spec) << getSpecifierName((TST)TypeSpecType); // signed double -> double. TypeSpecSign = TSS_unspecified; @@ -570,7 +595,7 @@ void DeclSpec::Finish(Diagnostic &D, Preprocessor &PP) { if (TypeSpecType == TST_unspecified) TypeSpecType = TST_int; // short -> short int, long long -> long long int. else if (TypeSpecType != TST_int) { - Diag(D, TSWLoc, SrcMgr, + Diag(D, TSWLoc, TypeSpecWidth == TSW_short ? diag::err_invalid_short_spec : diag::err_invalid_longlong_spec) << getSpecifierName((TST)TypeSpecType); @@ -582,7 +607,7 @@ void DeclSpec::Finish(Diagnostic &D, Preprocessor &PP) { if (TypeSpecType == TST_unspecified) TypeSpecType = TST_int; // long -> long int. else if (TypeSpecType != TST_int && TypeSpecType != TST_double) { - Diag(D, TSWLoc, SrcMgr, diag::err_invalid_long_spec) + Diag(D, TSWLoc, diag::err_invalid_long_spec) << getSpecifierName((TST)TypeSpecType); TypeSpecType = TST_int; TypeSpecOwned = false; @@ -594,16 +619,16 @@ void DeclSpec::Finish(Diagnostic &D, Preprocessor &PP) { // disallow their use. Need information about the backend. if (TypeSpecComplex != TSC_unspecified) { if (TypeSpecType == TST_unspecified) { - Diag(D, TSCLoc, SrcMgr, diag::ext_plain_complex) + Diag(D, TSCLoc, diag::ext_plain_complex) << FixItHint::CreateInsertion( PP.getLocForEndOfToken(getTypeSpecComplexLoc()), " double"); TypeSpecType = TST_double; // _Complex -> _Complex double. } else if (TypeSpecType == TST_int || TypeSpecType == TST_char) { // Note that this intentionally doesn't include _Complex _Bool. - Diag(D, TSTLoc, SrcMgr, diag::ext_integer_complex); + Diag(D, TSTLoc, diag::ext_integer_complex); } else if (TypeSpecType != TST_float && TypeSpecType != TST_double) { - Diag(D, TSCLoc, SrcMgr, diag::err_invalid_complex_spec) + Diag(D, TSCLoc, diag::err_invalid_complex_spec) << getSpecifierName((TST)TypeSpecType); TypeSpecComplex = TSC_unspecified; } @@ -619,7 +644,7 @@ void DeclSpec::Finish(Diagnostic &D, Preprocessor &PP) { SourceLocation SCLoc = getStorageClassSpecLoc(); SourceLocation SCEndLoc = SCLoc.getFileLocWithOffset(strlen(SpecName)); - Diag(D, SCLoc, SrcMgr, diag::err_friend_storage_spec) + Diag(D, SCLoc, diag::err_friend_storage_spec) << SpecName << FixItHint::CreateRemoval(SourceRange(SCLoc, SCEndLoc)); @@ -665,3 +690,58 @@ void UnqualifiedId::setOperatorFunctionId(SourceLocation OperatorLoc, EndLocation = SymbolLocations[I]; } } + +bool VirtSpecifiers::SetSpecifier(Specifier VS, SourceLocation Loc, + const char *&PrevSpec) { + if (Specifiers & VS) { + PrevSpec = getSpecifierName(VS); + return true; + } + + Specifiers |= VS; + + switch (VS) { + default: assert(0 && "Unknown specifier!"); + case VS_Override: VS_overrideLoc = Loc; break; + case VS_Final: VS_finalLoc = Loc; break; + case VS_New: VS_newLoc = Loc; break; + } + + return false; +} + +const char *VirtSpecifiers::getSpecifierName(Specifier VS) { + switch (VS) { + default: assert(0 && "Unknown specifier"); + case VS_Override: return "override"; + case VS_Final: return "final"; + case VS_New: return "new"; + } +} + +bool ClassVirtSpecifiers::SetSpecifier(Specifier CVS, SourceLocation Loc, + const char *&PrevSpec) { + if (Specifiers & CVS) { + PrevSpec = getSpecifierName(CVS); + return true; + } + + Specifiers |= CVS; + + switch (CVS) { + default: assert(0 && "Unknown specifier!"); + case CVS_Final: CVS_finalLoc = Loc; break; + case CVS_Explicit: CVS_explicitLoc = Loc; break; + } + + return false; +} + +const char *ClassVirtSpecifiers::getSpecifierName(Specifier CVS) { + switch (CVS) { + default: assert(0 && "Unknown specifier"); + case CVS_Final: return "final"; + case CVS_Explicit: return "explicit"; + } +} + |