diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Parse')
19 files changed, 1498 insertions, 2049 deletions
diff --git a/contrib/llvm/tools/clang/lib/Parse/AttributeList.cpp b/contrib/llvm/tools/clang/lib/Parse/AttributeList.cpp deleted file mode 100644 index 98d5d07..0000000 --- a/contrib/llvm/tools/clang/lib/Parse/AttributeList.cpp +++ /dev/null @@ -1,130 +0,0 @@ -//===--- AttributeList.cpp --------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines the AttributeList class implementation -// -//===----------------------------------------------------------------------===// - -#include "clang/Parse/AttributeList.h" -#include "clang/Basic/IdentifierTable.h" -#include "llvm/ADT/StringSwitch.h" -using namespace clang; - -AttributeList::AttributeList(IdentifierInfo *aName, SourceLocation aLoc, - IdentifierInfo *sName, SourceLocation sLoc, - IdentifierInfo *pName, SourceLocation pLoc, - ActionBase::ExprTy **ExprList, unsigned numArgs, - AttributeList *n, bool declspec, bool cxx0x) - : AttrName(aName), AttrLoc(aLoc), ScopeName(sName), ScopeLoc(sLoc), - ParmName(pName), ParmLoc(pLoc), NumArgs(numArgs), Next(n), - DeclspecAttribute(declspec), CXX0XAttribute(cxx0x), Invalid(false) { - - if (numArgs == 0) - Args = 0; - else { - Args = new ActionBase::ExprTy*[numArgs]; - memcpy(Args, ExprList, numArgs*sizeof(Args[0])); - } -} - -AttributeList::~AttributeList() { - if (Args) { - // FIXME: before we delete the vector, we need to make sure the Expr's - // have been deleted. Since ActionBase::ExprTy is "void", we are dependent - // on the actions module for actually freeing the memory. The specific - // hooks are ActOnDeclarator, ActOnTypeName, ActOnParamDeclaratorType, - // ParseField, ParseTag. Once these routines have freed the expression, - // they should zero out the Args slot (to indicate the memory has been - // freed). If any element of the vector is non-null, we should assert. - delete [] Args; - } - delete Next; -} - -AttributeList::Kind AttributeList::getKind(const IdentifierInfo *Name) { - llvm::StringRef AttrName = Name->getName(); - - // Normalize the attribute name, __foo__ becomes foo. - if (AttrName.startswith("__") && AttrName.endswith("__")) - AttrName = AttrName.substr(2, AttrName.size() - 4); - - return llvm::StringSwitch<AttributeList::Kind>(AttrName) - .Case("weak", AT_weak) - .Case("weakref", AT_weakref) - .Case("pure", AT_pure) - .Case("mode", AT_mode) - .Case("used", AT_used) - .Case("alias", AT_alias) - .Case("align", AT_aligned) - .Case("final", AT_final) - .Case("cdecl", AT_cdecl) - .Case("const", AT_const) - .Case("blocks", AT_blocks) - .Case("format", AT_format) - .Case("hiding", AT_hiding) - .Case("malloc", AT_malloc) - .Case("packed", AT_packed) - .Case("unused", AT_unused) - .Case("aligned", AT_aligned) - .Case("cleanup", AT_cleanup) - .Case("nodebug", AT_nodebug) - .Case("nonnull", AT_nonnull) - .Case("nothrow", AT_nothrow) - .Case("objc_gc", AT_objc_gc) - .Case("regparm", AT_regparm) - .Case("section", AT_section) - .Case("stdcall", AT_stdcall) - .Case("annotate", AT_annotate) - .Case("fastcall", AT_fastcall) - .Case("ibaction", AT_IBAction) - .Case("iboutlet", AT_IBOutlet) - .Case("iboutletcollection", AT_IBOutletCollection) - .Case("noreturn", AT_noreturn) - .Case("noinline", AT_noinline) - .Case("override", AT_override) - .Case("sentinel", AT_sentinel) - .Case("NSObject", AT_nsobject) - .Case("dllimport", AT_dllimport) - .Case("dllexport", AT_dllexport) - .Case("may_alias", IgnoredAttribute) // FIXME: TBAA - .Case("base_check", AT_base_check) - .Case("deprecated", AT_deprecated) - .Case("visibility", AT_visibility) - .Case("destructor", AT_destructor) - .Case("format_arg", AT_format_arg) - .Case("gnu_inline", AT_gnu_inline) - .Case("weak_import", AT_weak_import) - .Case("vector_size", AT_vector_size) - .Case("constructor", AT_constructor) - .Case("unavailable", AT_unavailable) - .Case("overloadable", AT_overloadable) - .Case("address_space", AT_address_space) - .Case("always_inline", AT_always_inline) - .Case("returns_twice", IgnoredAttribute) - .Case("vec_type_hint", IgnoredAttribute) - .Case("objc_exception", AT_objc_exception) - .Case("ext_vector_type", AT_ext_vector_type) - .Case("transparent_union", AT_transparent_union) - .Case("analyzer_noreturn", AT_analyzer_noreturn) - .Case("warn_unused_result", AT_warn_unused_result) - .Case("carries_dependency", AT_carries_dependency) - .Case("ns_returns_not_retained", AT_ns_returns_not_retained) - .Case("ns_returns_retained", AT_ns_returns_retained) - .Case("cf_returns_not_retained", AT_cf_returns_not_retained) - .Case("cf_returns_retained", AT_cf_returns_retained) - .Case("reqd_work_group_size", AT_reqd_wg_size) - .Case("init_priority", AT_init_priority) - .Case("no_instrument_function", AT_no_instrument_function) - .Case("thiscall", AT_thiscall) - .Case("__cdecl", AT_cdecl) - .Case("__stdcall", AT_stdcall) - .Case("__fastcall", AT_fastcall) - .Case("__thiscall", AT_thiscall) - .Default(UnknownAttribute); -} diff --git a/contrib/llvm/tools/clang/lib/Parse/CMakeLists.txt b/contrib/llvm/tools/clang/lib/Parse/CMakeLists.txt index fafcf77..189af3d 100644 --- a/contrib/llvm/tools/clang/lib/Parse/CMakeLists.txt +++ b/contrib/llvm/tools/clang/lib/Parse/CMakeLists.txt @@ -1,9 +1,7 @@ set(LLVM_NO_RTTI 1) add_clang_library(clangParse - AttributeList.cpp - DeclSpec.cpp - MinimalAction.cpp + ParseAST.cpp ParseCXXInlineMethods.cpp ParseDecl.cpp ParseDeclCXX.cpp @@ -18,4 +16,4 @@ add_clang_library(clangParse Parser.cpp ) -add_dependencies(clangParse ClangAttrList ClangDiagnosticParse) +add_dependencies(clangParse ClangAttrClasses ClangAttrList ClangDeclNodes ClangDiagnosticParse ClangStmtNodes) diff --git a/contrib/llvm/tools/clang/lib/Parse/DeclSpec.cpp b/contrib/llvm/tools/clang/lib/Parse/DeclSpec.cpp deleted file mode 100644 index d2cd744..0000000 --- a/contrib/llvm/tools/clang/lib/Parse/DeclSpec.cpp +++ /dev/null @@ -1,595 +0,0 @@ -//===--- SemaDeclSpec.cpp - Declaration Specifier Semantic Analysis -------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file implements semantic analysis for declaration specifiers. -// -//===----------------------------------------------------------------------===// - -#include "clang/Parse/DeclSpec.h" -#include "clang/Parse/ParseDiagnostic.h" -#include "clang/Parse/Template.h" -#include "clang/Lex/Preprocessor.h" -#include "clang/Basic/LangOptions.h" -#include "llvm/ADT/STLExtras.h" -#include "llvm/Support/ErrorHandling.h" -#include <cstring> -using namespace clang; - - -static DiagnosticBuilder Diag(Diagnostic &D, SourceLocation Loc, - SourceManager &SrcMgr, unsigned DiagID) { - return D.Report(FullSourceLoc(Loc, SrcMgr), DiagID); -} - - -void UnqualifiedId::setTemplateId(TemplateIdAnnotation *TemplateId) { - assert(TemplateId && "NULL template-id annotation?"); - Kind = IK_TemplateId; - this->TemplateId = TemplateId; - StartLocation = TemplateId->TemplateNameLoc; - EndLocation = TemplateId->RAngleLoc; -} - -void UnqualifiedId::setConstructorTemplateId(TemplateIdAnnotation *TemplateId) { - assert(TemplateId && "NULL template-id annotation?"); - Kind = IK_ConstructorTemplateId; - this->TemplateId = TemplateId; - StartLocation = TemplateId->TemplateNameLoc; - EndLocation = TemplateId->RAngleLoc; -} - -/// 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, - SourceLocation EllipsisLoc, - ParamInfo *ArgInfo, - unsigned NumArgs, - unsigned TypeQuals, - bool hasExceptionSpec, - SourceLocation ThrowLoc, - bool hasAnyExceptionSpec, - ActionBase::TypeTy **Exceptions, - SourceRange *ExceptionRanges, - unsigned NumExceptions, - SourceLocation LPLoc, - SourceLocation RPLoc, - Declarator &TheDeclarator) { - DeclaratorChunk I; - I.Kind = Function; - I.Loc = LPLoc; - I.EndLoc = RPLoc; - I.Fun.hasPrototype = hasProto; - I.Fun.isVariadic = isVariadic; - I.Fun.EllipsisLoc = EllipsisLoc.getRawEncoding(); - I.Fun.DeleteArgInfo = false; - I.Fun.TypeQuals = TypeQuals; - I.Fun.NumArgs = NumArgs; - I.Fun.ArgInfo = 0; - I.Fun.hasExceptionSpec = hasExceptionSpec; - I.Fun.ThrowLoc = ThrowLoc.getRawEncoding(); - I.Fun.hasAnyExceptionSpec = hasAnyExceptionSpec; - I.Fun.NumExceptions = NumExceptions; - I.Fun.Exceptions = 0; - - // new[] an argument array if needed. - if (NumArgs) { - // If the 'InlineParams' in Declarator is unused and big enough, put our - // parameter list there (in an effort to avoid new/delete traffic). If it - // is already used (consider a function returning a function pointer) or too - // small (function taking too many arguments), go to the heap. - if (!TheDeclarator.InlineParamsUsed && - NumArgs <= llvm::array_lengthof(TheDeclarator.InlineParams)) { - I.Fun.ArgInfo = TheDeclarator.InlineParams; - I.Fun.DeleteArgInfo = false; - TheDeclarator.InlineParamsUsed = true; - } else { - I.Fun.ArgInfo = new DeclaratorChunk::ParamInfo[NumArgs]; - I.Fun.DeleteArgInfo = true; - } - memcpy(I.Fun.ArgInfo, ArgInfo, sizeof(ArgInfo[0])*NumArgs); - } - // new[] an exception array if needed - if (NumExceptions) { - I.Fun.Exceptions = new DeclaratorChunk::TypeAndRange[NumExceptions]; - for (unsigned i = 0; i != NumExceptions; ++i) { - I.Fun.Exceptions[i].Ty = Exceptions[i]; - I.Fun.Exceptions[i].Range = ExceptionRanges[i]; - } - } - return I; -} - -/// getParsedSpecifiers - Return a bitmask of which flavors of specifiers this -/// declaration specifier includes. -/// -unsigned DeclSpec::getParsedSpecifiers() const { - unsigned Res = 0; - if (StorageClassSpec != SCS_unspecified || - SCS_thread_specified) - Res |= PQ_StorageClassSpecifier; - - if (TypeQualifiers != TQ_unspecified) - Res |= PQ_TypeQualifier; - - if (hasTypeSpecifier()) - Res |= PQ_TypeSpecifier; - - if (FS_inline_specified || FS_virtual_specified || FS_explicit_specified) - Res |= PQ_FunctionSpecifier; - return Res; -} - -template <class T> static bool BadSpecifier(T TNew, T TPrev, - const char *&PrevSpec, - unsigned &DiagID) { - PrevSpec = DeclSpec::getSpecifierName(TPrev); - DiagID = (TNew == TPrev ? diag::ext_duplicate_declspec - : diag::err_invalid_decl_spec_combination); - return true; -} - -const char *DeclSpec::getSpecifierName(DeclSpec::SCS S) { - switch (S) { - case DeclSpec::SCS_unspecified: return "unspecified"; - case DeclSpec::SCS_typedef: return "typedef"; - case DeclSpec::SCS_extern: return "extern"; - case DeclSpec::SCS_static: return "static"; - case DeclSpec::SCS_auto: return "auto"; - case DeclSpec::SCS_register: return "register"; - case DeclSpec::SCS_private_extern: return "__private_extern__"; - case DeclSpec::SCS_mutable: return "mutable"; - } - llvm_unreachable("Unknown typespec!"); -} - -const char *DeclSpec::getSpecifierName(TSW W) { - switch (W) { - case TSW_unspecified: return "unspecified"; - case TSW_short: return "short"; - case TSW_long: return "long"; - case TSW_longlong: return "long long"; - } - llvm_unreachable("Unknown typespec!"); -} - -const char *DeclSpec::getSpecifierName(TSC C) { - switch (C) { - case TSC_unspecified: return "unspecified"; - case TSC_imaginary: return "imaginary"; - case TSC_complex: return "complex"; - } - llvm_unreachable("Unknown typespec!"); -} - - -const char *DeclSpec::getSpecifierName(TSS S) { - switch (S) { - case TSS_unspecified: return "unspecified"; - case TSS_signed: return "signed"; - case TSS_unsigned: return "unsigned"; - } - llvm_unreachable("Unknown typespec!"); -} - -const char *DeclSpec::getSpecifierName(DeclSpec::TST T) { - switch (T) { - case DeclSpec::TST_unspecified: return "unspecified"; - case DeclSpec::TST_void: return "void"; - case DeclSpec::TST_char: return "char"; - case DeclSpec::TST_wchar: return "wchar_t"; - case DeclSpec::TST_char16: return "char16_t"; - case DeclSpec::TST_char32: return "char32_t"; - case DeclSpec::TST_int: return "int"; - case DeclSpec::TST_float: return "float"; - case DeclSpec::TST_double: return "double"; - case DeclSpec::TST_bool: return "_Bool"; - case DeclSpec::TST_decimal32: return "_Decimal32"; - case DeclSpec::TST_decimal64: return "_Decimal64"; - case DeclSpec::TST_decimal128: return "_Decimal128"; - case DeclSpec::TST_enum: return "enum"; - case DeclSpec::TST_class: return "class"; - case DeclSpec::TST_union: return "union"; - case DeclSpec::TST_struct: return "struct"; - case DeclSpec::TST_typename: return "type-name"; - case DeclSpec::TST_typeofType: - case DeclSpec::TST_typeofExpr: return "typeof"; - case DeclSpec::TST_auto: return "auto"; - case DeclSpec::TST_decltype: return "(decltype)"; - case DeclSpec::TST_error: return "(error)"; - } - llvm_unreachable("Unknown typespec!"); -} - -const char *DeclSpec::getSpecifierName(TQ T) { - switch (T) { - case DeclSpec::TQ_unspecified: return "unspecified"; - case DeclSpec::TQ_const: return "const"; - case DeclSpec::TQ_restrict: return "restrict"; - case DeclSpec::TQ_volatile: return "volatile"; - } - llvm_unreachable("Unknown typespec!"); -} - -bool DeclSpec::SetStorageClassSpec(SCS S, SourceLocation Loc, - const char *&PrevSpec, - unsigned &DiagID) { - if (StorageClassSpec != SCS_unspecified) - return BadSpecifier(S, (SCS)StorageClassSpec, PrevSpec, DiagID); - StorageClassSpec = S; - StorageClassSpecLoc = Loc; - assert((unsigned)S == StorageClassSpec && "SCS constants overflow bitfield"); - return false; -} - -bool DeclSpec::SetStorageClassSpecThread(SourceLocation Loc, - const char *&PrevSpec, - unsigned &DiagID) { - if (SCS_thread_specified) { - PrevSpec = "__thread"; - DiagID = diag::ext_duplicate_declspec; - return true; - } - SCS_thread_specified = true; - SCS_threadLoc = Loc; - return false; -} - - -/// These methods set the specified attribute of the DeclSpec, but return true -/// and ignore the request if invalid (e.g. "extern" then "auto" is -/// specified). -bool DeclSpec::SetTypeSpecWidth(TSW W, SourceLocation Loc, - const char *&PrevSpec, - unsigned &DiagID) { - if (TypeSpecWidth != TSW_unspecified && - // Allow turning long -> long long. - (W != TSW_longlong || TypeSpecWidth != TSW_long)) - return BadSpecifier(W, (TSW)TypeSpecWidth, PrevSpec, DiagID); - TypeSpecWidth = W; - TSWLoc = Loc; - if (TypeAltiVecVector && !TypeAltiVecBool && - ((TypeSpecWidth == TSW_long) || (TypeSpecWidth == TSW_longlong))) { - PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType); - DiagID = diag::warn_vector_long_decl_spec_combination; - return true; - } - return false; -} - -bool DeclSpec::SetTypeSpecComplex(TSC C, SourceLocation Loc, - const char *&PrevSpec, - unsigned &DiagID) { - if (TypeSpecComplex != TSC_unspecified) - return BadSpecifier(C, (TSC)TypeSpecComplex, PrevSpec, DiagID); - TypeSpecComplex = C; - TSCLoc = Loc; - return false; -} - -bool DeclSpec::SetTypeSpecSign(TSS S, SourceLocation Loc, - const char *&PrevSpec, - unsigned &DiagID) { - if (TypeSpecSign != TSS_unspecified) - return BadSpecifier(S, (TSS)TypeSpecSign, PrevSpec, DiagID); - TypeSpecSign = S; - TSSLoc = Loc; - return false; -} - -bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc, - const char *&PrevSpec, - unsigned &DiagID, - void *Rep, bool Owned) { - if (TypeSpecType != TST_unspecified) { - PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType); - DiagID = diag::err_invalid_decl_spec_combination; - return true; - } - if (TypeAltiVecVector && (T == TST_bool) && !TypeAltiVecBool) { - TypeAltiVecBool = true; - TSTLoc = Loc; - return false; - } - TypeSpecType = T; - TypeRep = Rep; - TSTLoc = Loc; - TypeSpecOwned = Owned; - if (TypeAltiVecVector && !TypeAltiVecBool && (TypeSpecType == TST_double)) { - PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType); - DiagID = diag::err_invalid_vector_decl_spec; - return true; - } - return false; -} - -bool DeclSpec::SetTypeAltiVecVector(bool isAltiVecVector, SourceLocation Loc, - const char *&PrevSpec, unsigned &DiagID) { - if (TypeSpecType != TST_unspecified) { - PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType); - DiagID = diag::err_invalid_vector_decl_spec_combination; - return true; - } - TypeAltiVecVector = isAltiVecVector; - AltiVecLoc = Loc; - return false; -} - -bool DeclSpec::SetTypeAltiVecPixel(bool isAltiVecPixel, SourceLocation Loc, - const char *&PrevSpec, unsigned &DiagID) { - if (!TypeAltiVecVector || TypeAltiVecPixel || - (TypeSpecType != TST_unspecified)) { - PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType); - DiagID = diag::err_invalid_pixel_decl_spec_combination; - return true; - } - TypeAltiVecPixel = isAltiVecPixel; - TSTLoc = Loc; - return false; -} - -bool DeclSpec::SetTypeSpecError() { - TypeSpecType = TST_error; - TypeRep = 0; - TSTLoc = SourceLocation(); - return false; -} - -bool DeclSpec::SetTypeQual(TQ T, SourceLocation Loc, const char *&PrevSpec, - unsigned &DiagID, const LangOptions &Lang) { - // Duplicates turn into warnings pre-C99. - if ((TypeQualifiers & T) && !Lang.C99) - return BadSpecifier(T, T, PrevSpec, DiagID); - TypeQualifiers |= T; - - switch (T) { - default: assert(0 && "Unknown type qualifier!"); - case TQ_const: TQ_constLoc = Loc; break; - case TQ_restrict: TQ_restrictLoc = Loc; break; - case TQ_volatile: TQ_volatileLoc = Loc; break; - } - return false; -} - -bool DeclSpec::SetFunctionSpecInline(SourceLocation Loc, const char *&PrevSpec, - unsigned &DiagID) { - // 'inline inline' is ok. - FS_inline_specified = true; - FS_inlineLoc = Loc; - return false; -} - -bool DeclSpec::SetFunctionSpecVirtual(SourceLocation Loc, const char *&PrevSpec, - unsigned &DiagID) { - // 'virtual virtual' is ok. - FS_virtual_specified = true; - FS_virtualLoc = Loc; - return false; -} - -bool DeclSpec::SetFunctionSpecExplicit(SourceLocation Loc, const char *&PrevSpec, - unsigned &DiagID) { - // 'explicit explicit' is ok. - FS_explicit_specified = true; - FS_explicitLoc = Loc; - return false; -} - -bool DeclSpec::SetFriendSpec(SourceLocation Loc, const char *&PrevSpec, - unsigned &DiagID) { - if (Friend_specified) { - PrevSpec = "friend"; - DiagID = diag::ext_duplicate_declspec; - return true; - } - - Friend_specified = true; - FriendLoc = Loc; - return false; -} - -bool DeclSpec::SetConstexprSpec(SourceLocation Loc, const char *&PrevSpec, - unsigned &DiagID) { - // 'constexpr constexpr' is ok. - Constexpr_specified = true; - ConstexprLoc = Loc; - return false; -} - -void DeclSpec::setProtocolQualifiers(const ActionBase::DeclPtrTy *Protos, - unsigned NP, - SourceLocation *ProtoLocs, - SourceLocation LAngleLoc) { - if (NP == 0) return; - ProtocolQualifiers = new ActionBase::DeclPtrTy[NP]; - ProtocolLocs = new SourceLocation[NP]; - memcpy((void*)ProtocolQualifiers, Protos, sizeof(ActionBase::DeclPtrTy)*NP); - memcpy(ProtocolLocs, ProtoLocs, sizeof(SourceLocation)*NP); - NumProtocolQualifiers = NP; - ProtocolLAngleLoc = LAngleLoc; -} - -void DeclSpec::SaveWrittenBuiltinSpecs() { - writtenBS.Sign = getTypeSpecSign(); - writtenBS.Width = getTypeSpecWidth(); - writtenBS.Type = getTypeSpecType(); - // Search the list of attributes for the presence of a mode attribute. - writtenBS.ModeAttr = false; - AttributeList* attrs = getAttributes(); - while (attrs) { - if (attrs->getKind() == AttributeList::AT_mode) { - writtenBS.ModeAttr = true; - break; - } - attrs = attrs->getNext(); - } -} - -/// Finish - This does final analysis of the declspec, rejecting things like -/// "_Imaginary" (lacking an FP type). This returns a diagnostic to issue or -/// diag::NUM_DIAGNOSTICS if there is no error. After calling this method, -/// DeclSpec is guaranteed self-consistent, even if an error occurred. -void DeclSpec::Finish(Diagnostic &D, Preprocessor &PP) { - // Before possibly changing their values, save specs as written. - SaveWrittenBuiltinSpecs(); - 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) - << 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) - << (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) - << getSpecifierName((TSW)TypeSpecWidth); - - // Elements of vector bool are interpreted as unsigned. (PIM 2.1) - if ((TypeSpecType == TST_char) || (TypeSpecType == TST_int) || - (TypeSpecWidth != TSW_unspecified)) - TypeSpecSign = TSS_unsigned; - } - - if (TypeAltiVecPixel) { - //TODO: perform validation - TypeSpecType = TST_int; - TypeSpecSign = TSS_unsigned; - TypeSpecWidth = TSW_short; - } - } - - // signed/unsigned are only valid with int/char/wchar_t. - if (TypeSpecSign != TSS_unspecified) { - if (TypeSpecType == TST_unspecified) - 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) - << getSpecifierName((TST)TypeSpecType); - // signed double -> double. - TypeSpecSign = TSS_unspecified; - } - } - - // Validate the width of the type. - switch (TypeSpecWidth) { - case TSW_unspecified: break; - case TSW_short: // short int - case TSW_longlong: // long long int - if (TypeSpecType == TST_unspecified) - TypeSpecType = TST_int; // short -> short int, long long -> long long int. - else if (TypeSpecType != TST_int) { - Diag(D, TSWLoc, SrcMgr, - TypeSpecWidth == TSW_short ? diag::err_invalid_short_spec - : diag::err_invalid_longlong_spec) - << getSpecifierName((TST)TypeSpecType); - TypeSpecType = TST_int; - } - break; - case TSW_long: // long double, long int - 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) - << getSpecifierName((TST)TypeSpecType); - TypeSpecType = TST_int; - } - break; - } - - // TODO: if the implementation does not implement _Complex or _Imaginary, - // disallow their use. Need information about the backend. - if (TypeSpecComplex != TSC_unspecified) { - if (TypeSpecType == TST_unspecified) { - Diag(D, TSCLoc, SrcMgr, 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); - } else if (TypeSpecType != TST_float && TypeSpecType != TST_double) { - Diag(D, TSCLoc, SrcMgr, diag::err_invalid_complex_spec) - << getSpecifierName((TST)TypeSpecType); - TypeSpecComplex = TSC_unspecified; - } - } - - // C++ [class.friend]p6: - // No storage-class-specifier shall appear in the decl-specifier-seq - // of a friend declaration. - if (isFriendSpecified() && getStorageClassSpec()) { - DeclSpec::SCS SC = getStorageClassSpec(); - const char *SpecName = getSpecifierName(SC); - - SourceLocation SCLoc = getStorageClassSpecLoc(); - SourceLocation SCEndLoc = SCLoc.getFileLocWithOffset(strlen(SpecName)); - - Diag(D, SCLoc, SrcMgr, diag::err_friend_storage_spec) - << SpecName - << FixItHint::CreateRemoval(SourceRange(SCLoc, SCEndLoc)); - - ClearStorageClassSpecs(); - } - - // Okay, now we can infer the real type. - - // TODO: return "auto function" and other bad things based on the real type. - - // 'data definition has no type or storage class'? -} - -bool DeclSpec::isMissingDeclaratorOk() { - TST tst = getTypeSpecType(); - return (tst == TST_union - || tst == TST_struct - || tst == TST_class - || tst == TST_enum - ) && getTypeRep() != 0 && StorageClassSpec != DeclSpec::SCS_typedef; -} - -void UnqualifiedId::clear() { - if (Kind == IK_TemplateId) - TemplateId->Destroy(); - - Kind = IK_Identifier; - Identifier = 0; - StartLocation = SourceLocation(); - EndLocation = SourceLocation(); -} - -void UnqualifiedId::setOperatorFunctionId(SourceLocation OperatorLoc, - OverloadedOperatorKind Op, - SourceLocation SymbolLocations[3]) { - Kind = IK_OperatorFunctionId; - StartLocation = OperatorLoc; - EndLocation = OperatorLoc; - OperatorFunctionId.Operator = Op; - for (unsigned I = 0; I != 3; ++I) { - OperatorFunctionId.SymbolLocations[I] = SymbolLocations[I].getRawEncoding(); - - if (SymbolLocations[I].isValid()) - EndLocation = SymbolLocations[I]; - } -} diff --git a/contrib/llvm/tools/clang/lib/Parse/Makefile b/contrib/llvm/tools/clang/lib/Parse/Makefile index 238e02d..5ec7c333 100644 --- a/contrib/llvm/tools/clang/lib/Parse/Makefile +++ b/contrib/llvm/tools/clang/lib/Parse/Makefile @@ -13,7 +13,6 @@ CLANG_LEVEL := ../.. LIBRARYNAME := clangParse -BUILD_ARCHIVE = 1 include $(CLANG_LEVEL)/Makefile diff --git a/contrib/llvm/tools/clang/lib/Parse/MinimalAction.cpp b/contrib/llvm/tools/clang/lib/Parse/MinimalAction.cpp deleted file mode 100644 index b720516..0000000 --- a/contrib/llvm/tools/clang/lib/Parse/MinimalAction.cpp +++ /dev/null @@ -1,281 +0,0 @@ -//===--- MinimalAction.cpp - Implement the MinimalAction class ------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file implements the MinimalAction interface. -// -//===----------------------------------------------------------------------===// - -#include "clang/Parse/Parser.h" -#include "clang/Parse/DeclSpec.h" -#include "clang/Parse/Scope.h" -#include "clang/Basic/TargetInfo.h" -#include "llvm/Support/Allocator.h" -#include "llvm/Support/RecyclingAllocator.h" -#include "llvm/Support/raw_ostream.h" -using namespace clang; - -/// Out-of-line virtual destructor to provide home for ActionBase class. -ActionBase::~ActionBase() {} - -/// Out-of-line virtual destructor to provide home for Action class. -Action::~Action() {} - -Action::ObjCMessageKind Action::getObjCMessageKind(Scope *S, - IdentifierInfo *Name, - SourceLocation NameLoc, - bool IsSuper, - bool HasTrailingDot, - TypeTy *&ReceiverType) { - ReceiverType = 0; - - if (IsSuper && !HasTrailingDot && S->isInObjcMethodScope()) - return ObjCSuperMessage; - - if (TypeTy *TyName = getTypeName(*Name, NameLoc, S)) { - DeclSpec DS; - const char *PrevSpec = 0; - unsigned DiagID = 0; - if (!DS.SetTypeSpecType(DeclSpec::TST_typename, NameLoc, PrevSpec, - DiagID, TyName)) { - DS.SetRangeEnd(NameLoc); - Declarator DeclaratorInfo(DS, Declarator::TypeNameContext); - TypeResult Ty = ActOnTypeName(S, DeclaratorInfo); - if (!Ty.isInvalid()) - ReceiverType = Ty.get(); - } - return ObjCClassMessage; - } - - return ObjCInstanceMessage; -} - -// Defined out-of-line here because of dependecy on AttributeList -Action::DeclPtrTy Action::ActOnUsingDirective(Scope *CurScope, - SourceLocation UsingLoc, - SourceLocation NamespcLoc, - CXXScopeSpec &SS, - SourceLocation IdentLoc, - IdentifierInfo *NamespcName, - AttributeList *AttrList) { - - // FIXME: Parser seems to assume that Action::ActOn* takes ownership over - // passed AttributeList, however other actions don't free it, is it - // temporary state or bug? - delete AttrList; - return DeclPtrTy(); -} - -// Defined out-of-line here because of dependency on AttributeList -Action::DeclPtrTy Action::ActOnUsingDeclaration(Scope *CurScope, - AccessSpecifier AS, - bool HasUsingKeyword, - SourceLocation UsingLoc, - CXXScopeSpec &SS, - UnqualifiedId &Name, - AttributeList *AttrList, - bool IsTypeName, - SourceLocation TypenameLoc) { - - // FIXME: Parser seems to assume that Action::ActOn* takes ownership over - // passed AttributeList, however other actions don't free it, is it - // temporary state or bug? - delete AttrList; - return DeclPtrTy(); -} - - -void PrettyStackTraceActionsDecl::print(llvm::raw_ostream &OS) const { - if (Loc.isValid()) { - Loc.print(OS, SM); - OS << ": "; - } - OS << Message; - - std::string Name = Actions.getDeclName(TheDecl); - if (!Name.empty()) - OS << " '" << Name << '\''; - - OS << '\n'; -} - -/// TypeNameInfo - A link exists here for each scope that an identifier is -/// defined. -namespace { - struct TypeNameInfo { - TypeNameInfo *Prev; - bool isTypeName; - - TypeNameInfo(bool istypename, TypeNameInfo *prev) { - isTypeName = istypename; - Prev = prev; - } - }; - - struct TypeNameInfoTable { - llvm::RecyclingAllocator<llvm::BumpPtrAllocator, TypeNameInfo> Allocator; - - void AddEntry(bool isTypename, IdentifierInfo *II) { - TypeNameInfo *TI = Allocator.Allocate<TypeNameInfo>(); - new (TI) TypeNameInfo(isTypename, II->getFETokenInfo<TypeNameInfo>()); - II->setFETokenInfo(TI); - } - - void DeleteEntry(TypeNameInfo *Entry) { - Entry->~TypeNameInfo(); - Allocator.Deallocate(Entry); - } - }; -} - -static TypeNameInfoTable *getTable(void *TP) { - return static_cast<TypeNameInfoTable*>(TP); -} - -MinimalAction::MinimalAction(Preprocessor &pp) - : Idents(pp.getIdentifierTable()), PP(pp) { - TypeNameInfoTablePtr = new TypeNameInfoTable(); -} - -MinimalAction::~MinimalAction() { - delete getTable(TypeNameInfoTablePtr); -} - -void MinimalAction::ActOnTranslationUnitScope(SourceLocation Loc, Scope *S) { - TUScope = S; - - TypeNameInfoTable &TNIT = *getTable(TypeNameInfoTablePtr); - - if (PP.getTargetInfo().getPointerWidth(0) >= 64) { - // Install [u]int128_t for 64-bit targets. - TNIT.AddEntry(true, &Idents.get("__int128_t")); - TNIT.AddEntry(true, &Idents.get("__uint128_t")); - } - - if (PP.getLangOptions().ObjC1) { - // Recognize the ObjC built-in type identifiers as types. - TNIT.AddEntry(true, &Idents.get("id")); - TNIT.AddEntry(true, &Idents.get("SEL")); - TNIT.AddEntry(true, &Idents.get("Class")); - TNIT.AddEntry(true, &Idents.get("Protocol")); - } -} - -/// isTypeName - This looks at the IdentifierInfo::FETokenInfo field to -/// determine whether the name is a type name (objc class name or typedef) or -/// not in this scope. -/// -/// FIXME: Use the passed CXXScopeSpec for accurate C++ type checking. -Action::TypeTy * -MinimalAction::getTypeName(IdentifierInfo &II, SourceLocation Loc, - Scope *S, CXXScopeSpec *SS, - bool isClassName, TypeTy *ObjectType) { - if (TypeNameInfo *TI = II.getFETokenInfo<TypeNameInfo>()) - if (TI->isTypeName) - return TI; - return 0; -} - -/// isCurrentClassName - Always returns false, because MinimalAction -/// does not support C++ classes with constructors. -bool MinimalAction::isCurrentClassName(const IdentifierInfo &, Scope *, - const CXXScopeSpec *) { - return false; -} - -TemplateNameKind -MinimalAction::isTemplateName(Scope *S, - CXXScopeSpec &SS, - UnqualifiedId &Name, - TypeTy *ObjectType, - bool EnteringScope, - TemplateTy &TemplateDecl, - bool &MemberOfUnknownSpecialization) { - MemberOfUnknownSpecialization = false; - return TNK_Non_template; -} - -/// ActOnDeclarator - If this is a typedef declarator, we modify the -/// IdentifierInfo::FETokenInfo field to keep track of this fact, until S is -/// popped. -Action::DeclPtrTy -MinimalAction::ActOnDeclarator(Scope *S, Declarator &D) { - IdentifierInfo *II = D.getIdentifier(); - - // If there is no identifier associated with this declarator, bail out. - if (II == 0) return DeclPtrTy(); - - TypeNameInfo *weCurrentlyHaveTypeInfo = II->getFETokenInfo<TypeNameInfo>(); - bool isTypeName = - D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_typedef; - - // this check avoids creating TypeNameInfo objects for the common case. - // It does need to handle the uncommon case of shadowing a typedef name with a - // non-typedef name. e.g. { typedef int a; a xx; { int a; } } - if (weCurrentlyHaveTypeInfo || isTypeName) { - // Allocate and add the 'TypeNameInfo' "decl". - getTable(TypeNameInfoTablePtr)->AddEntry(isTypeName, II); - - // Remember that this needs to be removed when the scope is popped. - S->AddDecl(DeclPtrTy::make(II)); - } - return DeclPtrTy(); -} - -Action::DeclPtrTy -MinimalAction::ActOnStartClassInterface(SourceLocation AtInterfaceLoc, - IdentifierInfo *ClassName, - SourceLocation ClassLoc, - IdentifierInfo *SuperName, - SourceLocation SuperLoc, - const DeclPtrTy *ProtoRefs, - unsigned NumProtocols, - const SourceLocation *ProtoLocs, - SourceLocation EndProtoLoc, - AttributeList *AttrList) { - // Allocate and add the 'TypeNameInfo' "decl". - getTable(TypeNameInfoTablePtr)->AddEntry(true, ClassName); - return DeclPtrTy(); -} - -/// ActOnForwardClassDeclaration - -/// Scope will always be top level file scope. -Action::DeclPtrTy -MinimalAction::ActOnForwardClassDeclaration(SourceLocation AtClassLoc, - IdentifierInfo **IdentList, - SourceLocation *IdentLocs, - unsigned NumElts) { - for (unsigned i = 0; i != NumElts; ++i) { - // Allocate and add the 'TypeNameInfo' "decl". - getTable(TypeNameInfoTablePtr)->AddEntry(true, IdentList[i]); - - // Remember that this needs to be removed when the scope is popped. - TUScope->AddDecl(DeclPtrTy::make(IdentList[i])); - } - return DeclPtrTy(); -} - -/// ActOnPopScope - When a scope is popped, if any typedefs are now -/// out-of-scope, they are removed from the IdentifierInfo::FETokenInfo field. -void MinimalAction::ActOnPopScope(SourceLocation Loc, Scope *S) { - TypeNameInfoTable &Table = *getTable(TypeNameInfoTablePtr); - - for (Scope::decl_iterator I = S->decl_begin(), E = S->decl_end(); - I != E; ++I) { - IdentifierInfo &II = *(*I).getAs<IdentifierInfo>(); - TypeNameInfo *TI = II.getFETokenInfo<TypeNameInfo>(); - assert(TI && "This decl didn't get pushed??"); - - if (TI) { - TypeNameInfo *Next = TI->Prev; - Table.DeleteEntry(TI); - - II.setFETokenInfo(Next); - } - } -} diff --git a/contrib/llvm/tools/clang/lib/Parse/ParseAST.cpp b/contrib/llvm/tools/clang/lib/Parse/ParseAST.cpp new file mode 100644 index 0000000..d027879 --- /dev/null +++ b/contrib/llvm/tools/clang/lib/Parse/ParseAST.cpp @@ -0,0 +1,114 @@ +//===--- ParseAST.cpp - Provide the clang::ParseAST method ----------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements the clang::ParseAST method. +// +//===----------------------------------------------------------------------===// + +#include "clang/Parse/ParseAST.h" +#include "clang/Sema/Sema.h" +#include "clang/Sema/CodeCompleteConsumer.h" +#include "clang/Sema/SemaConsumer.h" +#include "clang/Sema/ExternalSemaSource.h" +#include "clang/AST/ASTConsumer.h" +#include "clang/AST/DeclCXX.h" +#include "clang/AST/ExternalASTSource.h" +#include "clang/AST/Stmt.h" +#include "clang/Parse/Parser.h" +#include <cstdio> + +using namespace clang; + +static void DumpRecordLayouts(ASTContext &C) { + for (ASTContext::type_iterator I = C.types_begin(), E = C.types_end(); + I != E; ++I) { + const RecordType *RT = dyn_cast<RecordType>(*I); + if (!RT) + continue; + + const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl()); + if (!RD || RD->isImplicit() || RD->isDependentType() || + RD->isInvalidDecl() || !RD->getDefinition()) + continue; + + // FIXME: Do we really need to hard code this? + if (RD->getQualifiedNameAsString() == "__va_list_tag") + continue; + + C.DumpRecordLayout(RD, llvm::errs()); + } +} + +//===----------------------------------------------------------------------===// +// Public interface to the file +//===----------------------------------------------------------------------===// + +/// ParseAST - Parse the entire file specified, notifying the ASTConsumer as +/// the file is parsed. This inserts the parsed decls into the translation unit +/// held by Ctx. +/// +void clang::ParseAST(Preprocessor &PP, ASTConsumer *Consumer, + ASTContext &Ctx, bool PrintStats, + bool CompleteTranslationUnit, + CodeCompleteConsumer *CompletionConsumer) { + Sema S(PP, Ctx, *Consumer, CompleteTranslationUnit, CompletionConsumer); + ParseAST(S, PrintStats); +} + +void clang::ParseAST(Sema &S, bool PrintStats) { + // Collect global stats on Decls/Stmts (until we have a module streamer). + if (PrintStats) { + Decl::CollectingStats(true); + Stmt::CollectingStats(true); + } + + ASTConsumer *Consumer = &S.getASTConsumer(); + + Parser P(S.getPreprocessor(), S); + S.getPreprocessor().EnterMainSourceFile(); + P.Initialize(); + S.Initialize(); + + if (ExternalASTSource *External = S.getASTContext().getExternalSource()) + External->StartTranslationUnit(Consumer); + + Parser::DeclGroupPtrTy ADecl; + + while (!P.ParseTopLevelDecl(ADecl)) { // Not end of file. + // If we got a null return and something *was* parsed, ignore it. This + // is due to a top-level semicolon, an action override, or a parse error + // skipping something. + if (ADecl) + Consumer->HandleTopLevelDecl(ADecl.get()); + }; + // Check for any pending objective-c implementation decl. + while ((ADecl = P.FinishPendingObjCActions())) + Consumer->HandleTopLevelDecl(ADecl.get()); + + // Process any TopLevelDecls generated by #pragma weak. + for (llvm::SmallVector<Decl*,2>::iterator + I = S.WeakTopLevelDecls().begin(), + E = S.WeakTopLevelDecls().end(); I != E; ++I) + Consumer->HandleTopLevelDecl(DeclGroupRef(*I)); + + // Dump record layouts, if requested. + if (S.getLangOptions().DumpRecordLayouts) + DumpRecordLayouts(S.getASTContext()); + + Consumer->HandleTranslationUnit(S.getASTContext()); + + if (PrintStats) { + fprintf(stderr, "\nSTATISTICS:\n"); + P.getActions().PrintStats(); + S.getASTContext().PrintStats(); + Decl::PrintStats(); + Stmt::PrintStats(); + Consumer->PrintStats(); + } +} diff --git a/contrib/llvm/tools/clang/lib/Parse/ParseCXXInlineMethods.cpp b/contrib/llvm/tools/clang/lib/Parse/ParseCXXInlineMethods.cpp index 62a7ecd..d327db4 100644 --- a/contrib/llvm/tools/clang/lib/Parse/ParseCXXInlineMethods.cpp +++ b/contrib/llvm/tools/clang/lib/Parse/ParseCXXInlineMethods.cpp @@ -13,26 +13,25 @@ #include "clang/Parse/ParseDiagnostic.h" #include "clang/Parse/Parser.h" -#include "clang/Parse/DeclSpec.h" -#include "clang/Parse/Scope.h" +#include "clang/Sema/DeclSpec.h" +#include "clang/Sema/Scope.h" using namespace clang; /// ParseCXXInlineMethodDef - We parsed and verified that the specified /// Declarator is a well formed C++ inline method definition. Now lex its body /// and store its tokens for parsing after the C++ class is complete. -Parser::DeclPtrTy -Parser::ParseCXXInlineMethodDef(AccessSpecifier AS, Declarator &D, +Decl *Parser::ParseCXXInlineMethodDef(AccessSpecifier AS, Declarator &D, const ParsedTemplateInfo &TemplateInfo) { assert(D.getTypeObject(0).Kind == DeclaratorChunk::Function && "This isn't a function declarator!"); assert((Tok.is(tok::l_brace) || Tok.is(tok::colon) || Tok.is(tok::kw_try)) && "Current token not a '{', ':' or 'try'!"); - Action::MultiTemplateParamsArg TemplateParams(Actions, + MultiTemplateParamsArg TemplateParams(Actions, TemplateInfo.TemplateParams ? TemplateInfo.TemplateParams->data() : 0, TemplateInfo.TemplateParams ? TemplateInfo.TemplateParams->size() : 0); - DeclPtrTy FnD; + Decl *FnD; if (D.getDeclSpec().isFriendSpecified()) // FIXME: Friend templates FnD = Actions.ActOnFriendFunctionDecl(getCurScope(), D, true, @@ -139,12 +138,17 @@ void Parser::ParseLexedMethodDeclarations(ParsingClass &Class) { assert(Tok.is(tok::equal) && "Default argument not starting with '='"); SourceLocation EqualLoc = ConsumeToken(); - OwningExprResult DefArgResult(ParseAssignmentExpression()); + ExprResult DefArgResult(ParseAssignmentExpression()); if (DefArgResult.isInvalid()) Actions.ActOnParamDefaultArgumentError(LM.DefaultArgs[I].Param); - else + else { + if (Tok.is(tok::cxx_defaultarg_end)) + ConsumeToken(); + else + Diag(Tok.getLocation(), diag::err_default_arg_unparsed); Actions.ActOnParamDefaultArgument(LM.DefaultArgs[I].Param, EqualLoc, - move(DefArgResult)); + DefArgResult.take()); + } assert(!PP.getSourceManager().isBeforeInTranslationUnit(origLoc, Tok.getLocation()) && @@ -227,7 +231,7 @@ void Parser::ParseLexedMethodDefs(ParsingClass &Class) { // Error recovery. if (!Tok.is(tok::l_brace)) { - Actions.ActOnFinishFunctionBody(LM.D, Action::StmtArg(Actions)); + Actions.ActOnFinishFunctionBody(LM.D, 0); continue; } } else diff --git a/contrib/llvm/tools/clang/lib/Parse/ParseDecl.cpp b/contrib/llvm/tools/clang/lib/Parse/ParseDecl.cpp index 62ef3ec..555fcf0 100644 --- a/contrib/llvm/tools/clang/lib/Parse/ParseDecl.cpp +++ b/contrib/llvm/tools/clang/lib/Parse/ParseDecl.cpp @@ -13,8 +13,9 @@ #include "clang/Parse/Parser.h" #include "clang/Parse/ParseDiagnostic.h" -#include "clang/Parse/Scope.h" -#include "clang/Parse/Template.h" +#include "clang/Sema/Scope.h" +#include "clang/Sema/ParsedTemplate.h" +#include "clang/Sema/PrettyDeclStackTrace.h" #include "RAIIObjectsForParser.h" #include "llvm/ADT/SmallSet.h" using namespace clang; @@ -28,7 +29,7 @@ using namespace clang; /// specifier-qualifier-list abstract-declarator[opt] /// /// Called type-id in C++. -Action::TypeResult Parser::ParseTypeName(SourceRange *Range) { +TypeResult Parser::ParseTypeName(SourceRange *Range) { // Parse the common declaration-specifiers piece. DeclSpec DS; ParseSpecifierQualifierList(DS); @@ -131,7 +132,7 @@ AttributeList *Parser::ParseGNUAttributes(SourceLocation *EndLoc) { // now parse the non-empty comma separated list of expressions while (1) { - OwningExprResult ArgExpr(ParseAssignmentExpression()); + ExprResult ArgExpr(ParseAssignmentExpression()); if (ArgExpr.isInvalid()) { ArgExprsOk = false; SkipUntil(tok::r_paren); @@ -174,11 +175,13 @@ AttributeList *Parser::ParseGNUAttributes(SourceLocation *EndLoc) { case tok::kw_double: case tok::kw_void: case tok::kw_typeof: + CurrAttr = new AttributeList(AttrName, AttrNameLoc, 0, AttrNameLoc, + 0, SourceLocation(), 0, 0, CurrAttr); + if (CurrAttr->getKind() == AttributeList::AT_IBOutletCollection) + Diag(Tok, diag::err_iboutletcollection_builtintype); // If it's a builtin type name, eat it and expect a rparen // __attribute__(( vec_type_hint(char) )) ConsumeToken(); - CurrAttr = new AttributeList(AttrName, AttrNameLoc, 0, AttrNameLoc, - 0, SourceLocation(), 0, 0, CurrAttr); if (Tok.is(tok::r_paren)) ConsumeParen(); break; @@ -189,7 +192,7 @@ AttributeList *Parser::ParseGNUAttributes(SourceLocation *EndLoc) { // now parse the list of expressions while (1) { - OwningExprResult ArgExpr(ParseAssignmentExpression()); + ExprResult ArgExpr(ParseAssignmentExpression()); if (ArgExpr.isInvalid()) { ArgExprsOk = false; SkipUntil(tok::r_paren); @@ -254,9 +257,9 @@ AttributeList* Parser::ParseMicrosoftDeclSpec(AttributeList *CurrAttr) { ConsumeParen(); // FIXME: This doesn't parse __declspec(property(get=get_func_name)) // correctly. - OwningExprResult ArgExpr(ParseAssignmentExpression()); + ExprResult ArgExpr(ParseAssignmentExpression()); if (!ArgExpr.isInvalid()) { - ExprTy* ExprList = ArgExpr.take(); + Expr *ExprList = ArgExpr.take(); CurrAttr = new AttributeList(AttrName, AttrNameLoc, 0, AttrNameLoc, 0, SourceLocation(), &ExprList, 1, CurrAttr, true); @@ -290,6 +293,17 @@ AttributeList* Parser::ParseMicrosoftTypeAttributes(AttributeList *CurrAttr) { return CurrAttr; } +AttributeList* Parser::ParseBorlandTypeAttributes(AttributeList *CurrAttr) { + // Treat these like attributes + while (Tok.is(tok::kw___pascal)) { + IdentifierInfo *AttrName = Tok.getIdentifierInfo(); + SourceLocation AttrNameLoc = ConsumeToken(); + CurrAttr = new AttributeList(AttrName, AttrNameLoc, 0, AttrNameLoc, 0, + SourceLocation(), 0, 0, CurrAttr, true); + } + return CurrAttr; +} + /// ParseDeclaration - Parse a full 'declaration', which consists of /// declaration-specifiers, some number of declarators, and a semicolon. /// 'Context' should be a Declarator::TheContext value. This returns the @@ -311,7 +325,7 @@ Parser::DeclGroupPtrTy Parser::ParseDeclaration(unsigned Context, CXX0XAttributeList Attr) { ParenBraceBracketBalancer BalancerRAIIObj(*this); - DeclPtrTy SingleDecl; + Decl *SingleDecl = 0; switch (Tok.getKind()) { case tok::kw_template: case tok::kw_export: @@ -320,6 +334,17 @@ Parser::DeclGroupPtrTy Parser::ParseDeclaration(unsigned Context, << Attr.Range; SingleDecl = ParseDeclarationStartingWithTemplate(Context, DeclEnd); break; + case tok::kw_inline: + // Could be the start of an inline namespace. Allowed as an ext in C++03. + if (getLang().CPlusPlus && NextToken().is(tok::kw_namespace)) { + if (Attr.HasAttr) + Diag(Attr.Range.getBegin(), diag::err_attributes_not_allowed) + << Attr.Range; + SourceLocation InlineLoc = ConsumeToken(); + SingleDecl = ParseNamespace(Context, DeclEnd, InlineLoc); + break; + } + return ParseSimpleDeclaration(Context, DeclEnd, Attr.AttrList, true); case tok::kw_namespace: if (Attr.HasAttr) Diag(Attr.Range.getBegin(), diag::err_attributes_not_allowed) @@ -366,7 +391,7 @@ Parser::DeclGroupPtrTy Parser::ParseSimpleDeclaration(unsigned Context, // declaration-specifiers init-declarator-list[opt] ';' if (Tok.is(tok::semi)) { if (RequireSemi) ConsumeToken(); - DeclPtrTy TheDecl = Actions.ParsedFreeStandingDeclSpec(getCurScope(), AS_none, + Decl *TheDecl = Actions.ParsedFreeStandingDeclSpec(getCurScope(), AS_none, DS); DS.complete(TheDecl); return Actions.ConvertDeclToDeclGroup(TheDecl); @@ -410,7 +435,7 @@ Parser::DeclGroupPtrTy Parser::ParseDeclGroup(ParsingDeclSpec &DS, DS.ClearStorageClassSpecs(); } - DeclPtrTy TheDecl = ParseFunctionDefinition(D); + Decl *TheDecl = ParseFunctionDefinition(D); return Actions.ConvertDeclToDeclGroup(TheDecl); } @@ -427,10 +452,10 @@ Parser::DeclGroupPtrTy Parser::ParseDeclGroup(ParsingDeclSpec &DS, } } - llvm::SmallVector<DeclPtrTy, 8> DeclsInGroup; - DeclPtrTy FirstDecl = ParseDeclarationAfterDeclarator(D); + llvm::SmallVector<Decl *, 8> DeclsInGroup; + Decl *FirstDecl = ParseDeclarationAfterDeclarator(D); D.complete(FirstDecl); - if (FirstDecl.get()) + if (FirstDecl) DeclsInGroup.push_back(FirstDecl); // If we don't have a comma, it is either the end of the list (a ';') or an @@ -457,9 +482,9 @@ Parser::DeclGroupPtrTy Parser::ParseDeclGroup(ParsingDeclSpec &DS, ParseDeclarator(D); - DeclPtrTy ThisDecl = ParseDeclarationAfterDeclarator(D); + Decl *ThisDecl = ParseDeclarationAfterDeclarator(D); D.complete(ThisDecl); - if (ThisDecl.get()) + if (ThisDecl) DeclsInGroup.push_back(ThisDecl); } @@ -507,15 +532,15 @@ Parser::DeclGroupPtrTy Parser::ParseDeclGroup(ParsingDeclSpec &DS, /// According to the standard grammar, =default and =delete are function /// definitions, but that definitely doesn't fit with the parser here. /// -Parser::DeclPtrTy Parser::ParseDeclarationAfterDeclarator(Declarator &D, +Decl *Parser::ParseDeclarationAfterDeclarator(Declarator &D, const ParsedTemplateInfo &TemplateInfo) { // If a simple-asm-expr is present, parse it. if (Tok.is(tok::kw_asm)) { SourceLocation Loc; - OwningExprResult AsmLabel(ParseSimpleAsm(&Loc)); + ExprResult AsmLabel(ParseSimpleAsm(&Loc)); if (AsmLabel.isInvalid()) { SkipUntil(tok::semi, true, true); - return DeclPtrTy(); + return 0; } D.setAsmLabel(AsmLabel.release()); @@ -530,7 +555,7 @@ Parser::DeclPtrTy Parser::ParseDeclarationAfterDeclarator(Declarator &D, } // Inform the current actions module that we just parsed this declarator. - DeclPtrTy ThisDecl; + Decl *ThisDecl = 0; switch (TemplateInfo.Kind) { case ParsedTemplateInfo::NonTemplate: ThisDecl = Actions.ActOnDeclarator(getCurScope(), D); @@ -539,21 +564,21 @@ Parser::DeclPtrTy Parser::ParseDeclarationAfterDeclarator(Declarator &D, case ParsedTemplateInfo::Template: case ParsedTemplateInfo::ExplicitSpecialization: ThisDecl = Actions.ActOnTemplateDeclarator(getCurScope(), - Action::MultiTemplateParamsArg(Actions, + MultiTemplateParamsArg(Actions, TemplateInfo.TemplateParams->data(), TemplateInfo.TemplateParams->size()), D); break; case ParsedTemplateInfo::ExplicitInstantiation: { - Action::DeclResult ThisRes + DeclResult ThisRes = Actions.ActOnExplicitInstantiation(getCurScope(), TemplateInfo.ExternLoc, TemplateInfo.TemplateLoc, D); if (ThisRes.isInvalid()) { SkipUntil(tok::semi, true, true); - return DeclPtrTy(); + return 0; } ThisDecl = ThisRes.get(); @@ -580,7 +605,7 @@ Parser::DeclPtrTy Parser::ParseDeclarationAfterDeclarator(Declarator &D, return ThisDecl; } - OwningExprResult Init(ParseInitializer()); + ExprResult Init(ParseInitializer()); if (getLang().CPlusPlus && D.getCXXScopeSpec().isSet()) { Actions.ActOnCXXExitDeclInitializer(getCurScope(), ThisDecl); @@ -591,7 +616,7 @@ Parser::DeclPtrTy Parser::ParseDeclarationAfterDeclarator(Declarator &D, SkipUntil(tok::comma, true, true); Actions.ActOnInitializerError(ThisDecl); } else - Actions.AddInitializerToDecl(ThisDecl, move(Init)); + Actions.AddInitializerToDecl(ThisDecl, Init.take()); } } else if (Tok.is(tok::l_paren)) { // Parse C++ direct initializer: '(' expression-list ')' @@ -771,7 +796,7 @@ bool Parser::ParseImplicitInt(DeclSpec &DS, CXXScopeSpec *SS, // This is almost certainly an invalid type name. Let the action emit a // diagnostic and attempt to recover. - Action::TypeTy *T = 0; + ParsedType T; if (Actions.DiagnoseUnknownTypeName(*Tok.getIdentifierInfo(), Loc, getCurScope(), SS, T)) { // The action emitted a diagnostic, so we don't have to. @@ -781,8 +806,7 @@ bool Parser::ParseImplicitInt(DeclSpec &DS, CXXScopeSpec *SS, // name token, and we're done. const char *PrevSpec; unsigned DiagID; - DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec, DiagID, T, - false); + DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec, DiagID, T); DS.SetRangeEnd(Tok.getLocation()); ConsumeToken(); @@ -851,21 +875,7 @@ Parser::getDeclSpecContextFromDeclaratorContext(unsigned Context) { void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, const ParsedTemplateInfo &TemplateInfo, AccessSpecifier AS, - DeclSpecContext DSContext) { - if (Tok.is(tok::code_completion)) { - Action::CodeCompletionContext CCC = Action::CCC_Namespace; - if (TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate) - CCC = DSContext == DSC_class? Action::CCC_MemberTemplate - : Action::CCC_Template; - else if (DSContext == DSC_class) - CCC = Action::CCC_Class; - else if (ObjCImpDecl) - CCC = Action::CCC_ObjCImplementation; - - Actions.CodeCompleteOrdinaryName(getCurScope(), CCC); - ConsumeCodeCompletionToken(); - } - + DeclSpecContext DSContext) { DS.SetRangeStart(Tok.getLocation()); while (1) { bool isInvalid = false; @@ -882,6 +892,38 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, DS.Finish(Diags, PP); return; + case tok::code_completion: { + Sema::ParserCompletionContext CCC = Sema::PCC_Namespace; + if (DS.hasTypeSpecifier()) { + bool AllowNonIdentifiers + = (getCurScope()->getFlags() & (Scope::ControlScope | + Scope::BlockScope | + Scope::TemplateParamScope | + Scope::FunctionPrototypeScope | + Scope::AtCatchScope)) == 0; + bool AllowNestedNameSpecifiers + = DSContext == DSC_top_level || + (DSContext == DSC_class && DS.isFriendSpecified()); + + Actions.CodeCompleteDeclarator(getCurScope(), AllowNonIdentifiers, + AllowNestedNameSpecifiers); + ConsumeCodeCompletionToken(); + return; + } + + if (TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate) + CCC = DSContext == DSC_class? Sema::PCC_MemberTemplate + : Sema::PCC_Template; + else if (DSContext == DSC_class) + CCC = Sema::PCC_Class; + else if (ObjCImpDecl) + CCC = Sema::PCC_ObjCImplementation; + + Actions.CodeCompleteOrdinaryName(getCurScope(), CCC); + ConsumeCodeCompletionToken(); + return; + } + case tok::coloncolon: // ::foo::bar // C++ scope specifier. Annotate and loop, or bail out on error. if (TryAnnotateCXXScopeToken(true)) { @@ -898,7 +940,7 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, goto DoneWithDeclSpec; CXXScopeSpec SS; - SS.setScopeRep(Tok.getAnnotationValue()); + SS.setScopeRep((NestedNameSpecifier*) Tok.getAnnotationValue()); SS.setRange(Tok.getAnnotationRange()); // We are looking for a qualified typename. @@ -961,10 +1003,11 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, if (Next.is(tok::annot_typename)) { DS.getTypeSpecScope() = SS; ConsumeToken(); // The C++ scope. - if (Tok.getAnnotationValue()) + if (Tok.getAnnotationValue()) { + ParsedType T = getTypeAnnotation(Tok); isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, - PrevSpec, DiagID, - Tok.getAnnotationValue()); + PrevSpec, DiagID, T); + } else DS.SetTypeSpecError(); DS.SetRangeEnd(Tok.getAnnotationEndLoc()); @@ -993,8 +1036,9 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, << Next.getIdentifierInfo(); } - TypeTy *TypeRep = Actions.getTypeName(*Next.getIdentifierInfo(), - Next.getLocation(), getCurScope(), &SS); + ParsedType TypeRep = Actions.getTypeName(*Next.getIdentifierInfo(), + Next.getLocation(), + getCurScope(), &SS); // If the referenced identifier is not a type, then this declspec is // erroneous: We already checked about that it has no type specifier, and @@ -1021,10 +1065,11 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, } case tok::annot_typename: { - if (Tok.getAnnotationValue()) + if (Tok.getAnnotationValue()) { + ParsedType T = getTypeAnnotation(Tok); isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec, - DiagID, Tok.getAnnotationValue()); - else + DiagID, T); + } else DS.SetTypeSpecError(); if (isInvalid) @@ -1041,7 +1086,7 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, continue; SourceLocation LAngleLoc, EndProtoLoc; - llvm::SmallVector<DeclPtrTy, 8> ProtocolDecl; + llvm::SmallVector<Decl *, 8> ProtocolDecl; llvm::SmallVector<SourceLocation, 8> ProtocolLocs; ParseObjCProtocolReferences(ProtocolDecl, ProtocolLocs, false, LAngleLoc, EndProtoLoc); @@ -1077,12 +1122,13 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, break; // It has to be available as a typedef too! - TypeTy *TypeRep = Actions.getTypeName(*Tok.getIdentifierInfo(), - Tok.getLocation(), getCurScope()); + ParsedType TypeRep = + Actions.getTypeName(*Tok.getIdentifierInfo(), + Tok.getLocation(), getCurScope()); // If this is not a typedef name, don't parse it as part of the declspec, // it must be an implicit int or an error. - if (TypeRep == 0) { + if (!TypeRep) { if (ParseImplicitInt(DS, 0, TemplateInfo, AS)) continue; goto DoneWithDeclSpec; } @@ -1110,7 +1156,7 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, continue; SourceLocation LAngleLoc, EndProtoLoc; - llvm::SmallVector<DeclPtrTy, 8> ProtocolDecl; + llvm::SmallVector<Decl *, 8> ProtocolDecl; llvm::SmallVector<SourceLocation, 8> ProtocolLocs; ParseObjCProtocolReferences(ProtocolDecl, ProtocolLocs, false, LAngleLoc, EndProtoLoc); @@ -1172,6 +1218,11 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, DS.AddAttributes(ParseMicrosoftTypeAttributes()); continue; + // Borland single token adornments. + case tok::kw___pascal: + DS.AddAttributes(ParseBorlandTypeAttributes()); + continue; + // storage-class-specifier case tok::kw_typedef: isInvalid = DS.SetStorageClassSpec(DeclSpec::SCS_typedef, Loc, PrevSpec, @@ -1383,7 +1434,7 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, { SourceLocation LAngleLoc, EndProtoLoc; - llvm::SmallVector<DeclPtrTy, 8> ProtocolDecl; + llvm::SmallVector<Decl *, 8> ProtocolDecl; llvm::SmallVector<SourceLocation, 8> ProtocolLocs; ParseObjCProtocolReferences(ProtocolDecl, ProtocolLocs, false, LAngleLoc, EndProtoLoc); @@ -1403,7 +1454,12 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, if (isInvalid) { assert(PrevSpec && "Method did not return previous specifier!"); assert(DiagID); - Diag(Tok, DiagID) << PrevSpec; + + if (DiagID == diag::ext_duplicate_declspec) + Diag(Tok, DiagID) + << PrevSpec << FixItHint::CreateRemoval(Tok.getLocation()); + else + Diag(Tok, DiagID) << PrevSpec; } DS.SetRangeEnd(Tok.getLocation()); ConsumeToken(); @@ -1495,10 +1551,10 @@ bool Parser::ParseOptionalTypeSpecifier(DeclSpec &DS, bool& isInvalid, // simple-type-specifier: case tok::annot_typename: { - if (Tok.getAnnotationValue()) + if (ParsedType T = getTypeAnnotation(Tok)) { isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec, - DiagID, Tok.getAnnotationValue()); - else + DiagID, T); + } else DS.SetTypeSpecError(); DS.SetRangeEnd(Tok.getAnnotationEndLoc()); ConsumeToken(); // The typename @@ -1511,7 +1567,7 @@ bool Parser::ParseOptionalTypeSpecifier(DeclSpec &DS, bool& isInvalid, return true; SourceLocation LAngleLoc, EndProtoLoc; - llvm::SmallVector<DeclPtrTy, 8> ProtocolDecl; + llvm::SmallVector<Decl *, 8> ProtocolDecl; llvm::SmallVector<SourceLocation, 8> ProtocolLocs; ParseObjCProtocolReferences(ProtocolDecl, ProtocolLocs, false, LAngleLoc, EndProtoLoc); @@ -1643,6 +1699,7 @@ bool Parser::ParseOptionalTypeSpecifier(DeclSpec &DS, bool& isInvalid, isInvalid = DS.SetTypeSpecType(DeclSpec::TST_auto, Loc, PrevSpec, DiagID); break; + case tok::kw___ptr64: case tok::kw___w64: case tok::kw___cdecl: @@ -1652,6 +1709,10 @@ bool Parser::ParseOptionalTypeSpecifier(DeclSpec &DS, bool& isInvalid, DS.AddAttributes(ParseMicrosoftTypeAttributes()); return true; + case tok::kw___pascal: + DS.AddAttributes(ParseBorlandTypeAttributes()); + return true; + default: // Not a type-specifier; do nothing. return false; @@ -1728,7 +1789,7 @@ ParseStructDeclaration(DeclSpec &DS, FieldCallback &Fields) { if (Tok.is(tok::colon)) { ConsumeToken(); - OwningExprResult Res(ParseConstantExpression()); + ExprResult Res(ParseConstantExpression()); if (Res.isInvalid()) SkipUntil(tok::semi, true, true); else @@ -1743,7 +1804,7 @@ ParseStructDeclaration(DeclSpec &DS, FieldCallback &Fields) { } // We're done with this declarator; invoke the callback. - DeclPtrTy D = Fields.invoke(DeclaratorInfo); + Decl *D = Fields.invoke(DeclaratorInfo); PD.complete(D); // If we don't have a comma, it is either the end of the list (a ';') @@ -1769,10 +1830,9 @@ ParseStructDeclaration(DeclSpec &DS, FieldCallback &Fields) { /// [OBC] '@' 'defs' '(' class-name ')' /// void Parser::ParseStructUnionBody(SourceLocation RecordLoc, - unsigned TagType, DeclPtrTy TagDecl) { - PrettyStackTraceActionsDecl CrashInfo(TagDecl, RecordLoc, Actions, - PP.getSourceManager(), - "parsing struct/union body"); + unsigned TagType, Decl *TagDecl) { + PrettyDeclStackTraceEntry CrashInfo(Actions, TagDecl, RecordLoc, + "parsing struct/union body"); SourceLocation LBraceLoc = ConsumeBrace(); @@ -1782,10 +1842,10 @@ void Parser::ParseStructUnionBody(SourceLocation RecordLoc, // Empty structs are an extension in C (C99 6.7.2.1p7), but are allowed in // C++. if (Tok.is(tok::r_brace) && !getLang().CPlusPlus) - Diag(Tok, diag::ext_empty_struct_union_enum) - << DeclSpec::getSpecifierName((DeclSpec::TST)TagType); + Diag(Tok, diag::ext_empty_struct_union) + << (TagType == TST_union); - llvm::SmallVector<DeclPtrTy, 32> FieldDecls; + llvm::SmallVector<Decl *, 32> FieldDecls; // While we still have something to read, read the declarations in the struct. while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) { @@ -1806,16 +1866,16 @@ void Parser::ParseStructUnionBody(SourceLocation RecordLoc, if (!Tok.is(tok::at)) { struct CFieldCallback : FieldCallback { Parser &P; - DeclPtrTy TagDecl; - llvm::SmallVectorImpl<DeclPtrTy> &FieldDecls; + Decl *TagDecl; + llvm::SmallVectorImpl<Decl *> &FieldDecls; - CFieldCallback(Parser &P, DeclPtrTy TagDecl, - llvm::SmallVectorImpl<DeclPtrTy> &FieldDecls) : + CFieldCallback(Parser &P, Decl *TagDecl, + llvm::SmallVectorImpl<Decl *> &FieldDecls) : P(P), TagDecl(TagDecl), FieldDecls(FieldDecls) {} - virtual DeclPtrTy invoke(FieldDeclarator &FD) { + virtual Decl *invoke(FieldDeclarator &FD) { // Install the declarator into the current TagDecl. - DeclPtrTy Field = P.Actions.ActOnField(P.getCurScope(), TagDecl, + Decl *Field = P.Actions.ActOnField(P.getCurScope(), TagDecl, FD.D.getDeclSpec().getSourceRange().getBegin(), FD.D, FD.BitfieldSize); FieldDecls.push_back(Field); @@ -1838,7 +1898,7 @@ void Parser::ParseStructUnionBody(SourceLocation RecordLoc, SkipUntil(tok::semi, true); continue; } - llvm::SmallVector<DeclPtrTy, 16> Fields; + llvm::SmallVector<Decl *, 16> Fields; Actions.ActOnDefs(getCurScope(), TagDecl, Tok.getLocation(), Tok.getIdentifierInfo(), Fields); FieldDecls.insert(FieldDecls.end(), Fields.begin(), Fields.end()); @@ -1905,7 +1965,7 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS, CXXScopeSpec &SS = DS.getTypeSpecScope(); if (getLang().CPlusPlus) { - if (ParseOptionalCXXScopeSpecifier(SS, 0, false)) + if (ParseOptionalCXXScopeSpecifier(SS, ParsedType(), false)) return; if (SS.isSet() && Tok.isNot(tok::identifier)) { @@ -1944,18 +2004,18 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS, // enum foo {..}; void bar() { enum foo; } <- new foo in bar. // enum foo {..}; void bar() { enum foo x; } <- use of old foo. // - Action::TagUseKind TUK; + Sema::TagUseKind TUK; if (Tok.is(tok::l_brace)) - TUK = Action::TUK_Definition; + TUK = Sema::TUK_Definition; else if (Tok.is(tok::semi)) - TUK = Action::TUK_Declaration; + TUK = Sema::TUK_Declaration; else - TUK = Action::TUK_Reference; + TUK = Sema::TUK_Reference; // enums cannot be templates, although they can be referenced from a // template. if (TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate && - TUK != Action::TUK_Reference) { + TUK != Sema::TUK_Reference) { Diag(Tok, diag::err_enum_template); // Skip the rest of this declarator, up until the comma or semicolon. @@ -1968,11 +2028,11 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS, SourceLocation TSTLoc = NameLoc.isValid()? NameLoc : StartLoc; const char *PrevSpec = 0; unsigned DiagID; - DeclPtrTy TagDecl = Actions.ActOnTag(getCurScope(), DeclSpec::TST_enum, TUK, - StartLoc, SS, Name, NameLoc, Attr.get(), - AS, - Action::MultiTemplateParamsArg(Actions), - Owned, IsDependent); + Decl *TagDecl = Actions.ActOnTag(getCurScope(), DeclSpec::TST_enum, TUK, + StartLoc, SS, Name, NameLoc, Attr.get(), + AS, + MultiTemplateParamsArg(Actions), + Owned, IsDependent); if (IsDependent) { // This enum has a dependent nested-name-specifier. Handle it as a // dependent tag. @@ -1991,13 +2051,13 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS, } if (DS.SetTypeSpecType(DeclSpec::TST_typename, TSTLoc, PrevSpec, DiagID, - Type.get(), false)) + Type.get())) Diag(StartLoc, DiagID) << PrevSpec; return; } - if (!TagDecl.get()) { + if (!TagDecl) { // The action failed to produce an enumeration tag. If this is a // definition, consume the entire definition. if (Tok.is(tok::l_brace)) { @@ -2012,10 +2072,10 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS, if (Tok.is(tok::l_brace)) ParseEnumBody(StartLoc, TagDecl); - // FIXME: The DeclSpec should keep the locations of both the keyword and the - // name (if there is one). + // FIXME: The DeclSpec should keep the locations of both the keyword + // and the name (if there is one). if (DS.SetTypeSpecType(DeclSpec::TST_enum, TSTLoc, PrevSpec, DiagID, - TagDecl.getAs<void>(), Owned)) + TagDecl, Owned)) Diag(StartLoc, DiagID) << PrevSpec; } @@ -2029,7 +2089,7 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS, /// enumeration-constant: /// identifier /// -void Parser::ParseEnumBody(SourceLocation StartLoc, DeclPtrTy EnumDecl) { +void Parser::ParseEnumBody(SourceLocation StartLoc, Decl *EnumDecl) { // Enter the scope of the enum body and start the definition. ParseScope EnumScope(this, Scope::DeclScope); Actions.ActOnTagStartDefinition(getCurScope(), EnumDecl); @@ -2040,9 +2100,9 @@ void Parser::ParseEnumBody(SourceLocation StartLoc, DeclPtrTy EnumDecl) { if (Tok.is(tok::r_brace) && !getLang().CPlusPlus) Diag(Tok, diag::error_empty_enum); - llvm::SmallVector<DeclPtrTy, 32> EnumConstantDecls; + llvm::SmallVector<Decl *, 32> EnumConstantDecls; - DeclPtrTy LastEnumConstDecl; + Decl *LastEnumConstDecl = 0; // Parse the enumerator-list. while (Tok.is(tok::identifier)) { @@ -2050,7 +2110,7 @@ void Parser::ParseEnumBody(SourceLocation StartLoc, DeclPtrTy EnumDecl) { SourceLocation IdentLoc = ConsumeToken(); SourceLocation EqualLoc; - OwningExprResult AssignedVal(Actions); + ExprResult AssignedVal; if (Tok.is(tok::equal)) { EqualLoc = ConsumeToken(); AssignedVal = ParseConstantExpression(); @@ -2059,11 +2119,11 @@ void Parser::ParseEnumBody(SourceLocation StartLoc, DeclPtrTy EnumDecl) { } // Install the enumerator constant into EnumDecl. - DeclPtrTy EnumConstDecl = Actions.ActOnEnumConstant(getCurScope(), EnumDecl, - LastEnumConstDecl, - IdentLoc, Ident, - EqualLoc, - AssignedVal.release()); + Decl *EnumConstDecl = Actions.ActOnEnumConstant(getCurScope(), EnumDecl, + LastEnumConstDecl, + IdentLoc, Ident, + EqualLoc, + AssignedVal.release()); EnumConstantDecls.push_back(EnumConstDecl); LastEnumConstDecl = EnumConstDecl; @@ -2229,6 +2289,7 @@ bool Parser::isTypeSpecifierQualifier() { case tok::kw___thiscall: case tok::kw___w64: case tok::kw___ptr64: + case tok::kw___pascal: return true; } } @@ -2337,6 +2398,7 @@ bool Parser::isDeclarationSpecifier() { case tok::kw___w64: case tok::kw___ptr64: case tok::kw___forceinline: + case tok::kw___pascal: return true; } } @@ -2346,7 +2408,7 @@ bool Parser::isConstructorDeclarator() { // Parse the C++ scope specifier. CXXScopeSpec SS; - if (ParseOptionalCXXScopeSpecifier(SS, 0, true)) { + if (ParseOptionalCXXScopeSpecifier(SS, ParsedType(), true)) { TPA.Revert(); return false; } @@ -2388,15 +2450,19 @@ bool Parser::isConstructorDeclarator() { } /// ParseTypeQualifierListOpt -/// type-qualifier-list: [C99 6.7.5] -/// type-qualifier -/// [GNU] attributes [ only if AttributesAllowed=true ] -/// type-qualifier-list type-qualifier -/// [GNU] type-qualifier-list attributes [ only if AttributesAllowed=true ] -/// [C++0x] attribute-specifier[opt] is allowed before cv-qualifier-seq -/// if CXX0XAttributesAllowed = true +/// type-qualifier-list: [C99 6.7.5] +/// type-qualifier +/// [vendor] attributes +/// [ only if VendorAttributesAllowed=true ] +/// type-qualifier-list type-qualifier +/// [vendor] type-qualifier-list attributes +/// [ only if VendorAttributesAllowed=true ] +/// [C++0x] attribute-specifier[opt] is allowed before cv-qualifier-seq +/// [ only if CXX0XAttributesAllowed=true ] +/// Note: vendor can be GNU, MS, etc. /// -void Parser::ParseTypeQualifierListOpt(DeclSpec &DS, bool GNUAttributesAllowed, +void Parser::ParseTypeQualifierListOpt(DeclSpec &DS, + bool VendorAttributesAllowed, bool CXX0XAttributesAllowed) { if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier()) { SourceLocation Loc = Tok.getLocation(); @@ -2414,6 +2480,11 @@ void Parser::ParseTypeQualifierListOpt(DeclSpec &DS, bool GNUAttributesAllowed, SourceLocation Loc = Tok.getLocation(); switch (Tok.getKind()) { + case tok::code_completion: + Actions.CodeCompleteTypeQualifiers(DS); + ConsumeCodeCompletionToken(); + break; + case tok::kw_const: isInvalid = DS.SetTypeQual(DeclSpec::TQ_const , Loc, PrevSpec, DiagID, getLang()); @@ -2432,13 +2503,19 @@ void Parser::ParseTypeQualifierListOpt(DeclSpec &DS, bool GNUAttributesAllowed, case tok::kw___stdcall: case tok::kw___fastcall: case tok::kw___thiscall: - if (GNUAttributesAllowed) { + if (VendorAttributesAllowed) { DS.AddAttributes(ParseMicrosoftTypeAttributes()); continue; } goto DoneWithTypeQuals; + case tok::kw___pascal: + if (VendorAttributesAllowed) { + DS.AddAttributes(ParseBorlandTypeAttributes()); + continue; + } + goto DoneWithTypeQuals; case tok::kw___attribute: - if (GNUAttributesAllowed) { + if (VendorAttributesAllowed) { DS.AddAttributes(ParseGNUAttributes()); continue; // do *not* consume the next token! } @@ -2494,6 +2571,7 @@ void Parser::ParseDeclaratorInternal(Declarator &D, DirectDeclParseFunction DirectDeclParser) { if (Diags.hasAllExtensionsSilenced()) D.setExtension(); + // C++ member pointers start with a '::' or a nested-name. // Member pointers get special handling, since there's no place for the // scope spec in the generic path below. @@ -2501,7 +2579,7 @@ void Parser::ParseDeclaratorInternal(Declarator &D, (Tok.is(tok::coloncolon) || Tok.is(tok::identifier) || Tok.is(tok::annot_cxxscope))) { CXXScopeSpec SS; - ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, true); // ignore fail + ParseOptionalCXXScopeSpecifier(SS, ParsedType(), true); // ignore fail if (SS.isNotEmpty()) { if (Tok.isNot(tok::star)) { @@ -2660,8 +2738,7 @@ void Parser::ParseDirectDeclarator(Declarator &D) { if (getLang().CPlusPlus && D.mayHaveIdentifier()) { // ParseDeclaratorInternal might already have parsed the scope. if (D.getCXXScopeSpec().isEmpty()) { - ParseOptionalCXXScopeSpecifier(D.getCXXScopeSpec(), /*ObjectType=*/0, - true); + ParseOptionalCXXScopeSpecifier(D.getCXXScopeSpec(), ParsedType(), true); } if (D.getCXXScopeSpec().isValid()) { @@ -2690,7 +2767,7 @@ void Parser::ParseDirectDeclarator(Declarator &D) { /*EnteringContext=*/true, /*AllowDestructorName=*/true, AllowConstructorName, - /*ObjectType=*/0, + ParsedType(), D.getName()) || // Once we're past the identifier, if the scope was bad, mark the // whole declarator bad. @@ -2724,7 +2801,10 @@ void Parser::ParseDirectDeclarator(Declarator &D) { // scope when parsing the parenthesized declarator, then exited // the scope already. Re-enter the scope, if we need to. if (D.getCXXScopeSpec().isSet()) { - if (Actions.ShouldEnterDeclaratorScope(getCurScope(), D.getCXXScopeSpec())) + // If there was an error parsing parenthesized declarator, declarator + // scope may have been enterred before. Don't do it again. + if (!D.isInvalidType() && + Actions.ShouldEnterDeclaratorScope(getCurScope(), D.getCXXScopeSpec())) // Change the declaration context for name lookup, until this function // is exited (and the declarator has been parsed). DeclScopeObj.EnterDeclaratorScope(); @@ -2820,6 +2900,10 @@ void Parser::ParseParenDeclarator(Declarator &D) { Tok.is(tok::kw___w64) || Tok.is(tok::kw___ptr64)) { AttrList.reset(ParseMicrosoftTypeAttributes(AttrList.take())); } + // Eat any Borland extensions. + if (Tok.is(tok::kw___pascal)) { + AttrList.reset(ParseBorlandTypeAttributes(AttrList.take())); + } // If we haven't past the identifier yet (or where the identifier would be // stored, if this is an abstract declarator), then this is probably just @@ -2922,7 +3006,7 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D, bool hasExceptionSpec = false; SourceLocation ThrowLoc; bool hasAnyExceptionSpec = false; - llvm::SmallVector<TypeTy*, 2> Exceptions; + llvm::SmallVector<ParsedType, 2> Exceptions; llvm::SmallVector<SourceRange, 2> ExceptionRanges; if (getLang().CPlusPlus) { ParseTypeQualifierListOpt(DS, false /*no attributes*/); @@ -3061,7 +3145,7 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D, // Inform the actions module about the parameter declarator, so it gets // added to the current scope. - DeclPtrTy Param = Actions.ActOnParamDeclarator(getCurScope(), ParmDecl); + Decl *Param = Actions.ActOnParamDeclarator(getCurScope(), ParmDecl); // Parse the default argument, if any. We parse the default // arguments in all dialects; the semantic analysis in @@ -3085,21 +3169,29 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D, delete DefArgToks; DefArgToks = 0; Actions.ActOnParamDefaultArgumentError(Param); - } else + } else { + // Mark the end of the default argument so that we know when to + // stop when we parse it later on. + Token DefArgEnd; + DefArgEnd.startToken(); + DefArgEnd.setKind(tok::cxx_defaultarg_end); + DefArgEnd.setLocation(Tok.getLocation()); + DefArgToks->push_back(DefArgEnd); Actions.ActOnParamUnparsedDefaultArgument(Param, EqualLoc, (*DefArgToks)[1].getLocation()); + } } else { // Consume the '='. ConsumeToken(); - OwningExprResult DefArgResult(ParseAssignmentExpression()); + ExprResult DefArgResult(ParseAssignmentExpression()); if (DefArgResult.isInvalid()) { Actions.ActOnParamDefaultArgumentError(Param); SkipUntil(tok::comma, tok::r_paren, true, true); } else { // Inform the actions module about the default argument Actions.ActOnParamDefaultArgument(Param, EqualLoc, - move(DefArgResult)); + DefArgResult.take()); } } } @@ -3141,7 +3233,7 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D, bool hasExceptionSpec = false; SourceLocation ThrowLoc; bool hasAnyExceptionSpec = false; - llvm::SmallVector<TypeTy*, 2> Exceptions; + llvm::SmallVector<ParsedType, 2> Exceptions; llvm::SmallVector<SourceRange, 2> ExceptionRanges; if (getLang().CPlusPlus) { @@ -3202,8 +3294,7 @@ void Parser::ParseFunctionDeclaratorIdentifierList(SourceLocation LParenLoc, // The first identifier was already read, and is known to be the first // identifier in the list. Remember this identifier in ParamInfo. ParamsSoFar.insert(FirstIdent); - ParamInfo.push_back(DeclaratorChunk::ParamInfo(FirstIdent, FirstIdentLoc, - DeclPtrTy())); + ParamInfo.push_back(DeclaratorChunk::ParamInfo(FirstIdent, FirstIdentLoc, 0)); while (Tok.is(tok::comma)) { // Eat the comma. @@ -3229,7 +3320,7 @@ void Parser::ParseFunctionDeclaratorIdentifierList(SourceLocation LParenLoc, // Remember this identifier in ParamInfo. ParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII, Tok.getLocation(), - DeclPtrTy())); + 0)); } // Eat the identifier. @@ -3271,7 +3362,7 @@ void Parser::ParseBracketDeclarator(Declarator &D) { } // Remember that we parsed the empty array type. - OwningExprResult NumElements(Actions); + ExprResult NumElements; D.AddTypeInfo(DeclaratorChunk::getArray(0, false, false, 0, StartLoc, EndLoc), EndLoc); @@ -3279,7 +3370,7 @@ void Parser::ParseBracketDeclarator(Declarator &D) { } else if (Tok.getKind() == tok::numeric_constant && GetLookAheadToken(1).is(tok::r_square)) { // [4] is very common. Parse the numeric constant expression. - OwningExprResult ExprRes(Actions.ActOnNumericConstant(Tok)); + ExprResult ExprRes(Actions.ActOnNumericConstant(Tok)); ConsumeToken(); SourceLocation EndLoc = MatchRHSPunctuation(tok::r_square, StartLoc); @@ -3317,7 +3408,7 @@ void Parser::ParseBracketDeclarator(Declarator &D) { // Handle "direct-declarator [ type-qual-list[opt] * ]". bool isStar = false; - OwningExprResult NumElements(Actions); + ExprResult NumElements; // Handle the case where we have '[*]' as the array size. However, a leading // star could be the start of an expression, for example 'X[*p + 4]'. Verify @@ -3382,12 +3473,12 @@ void Parser::ParseTypeofSpecifier(DeclSpec &DS) { const bool hasParens = Tok.is(tok::l_paren); bool isCastExpr; - TypeTy *CastTy; + ParsedType CastTy; SourceRange CastRange; - OwningExprResult Operand = ParseExprAfterTypeofSizeofAlignof(OpTok, - isCastExpr, - CastTy, - CastRange); + ExprResult Operand = ParseExprAfterTypeofSizeofAlignof(OpTok, + isCastExpr, + CastTy, + CastRange); if (hasParens) DS.setTypeofParensRange(CastRange); @@ -3422,7 +3513,7 @@ void Parser::ParseTypeofSpecifier(DeclSpec &DS) { unsigned DiagID; // Check for duplicate type specifiers (e.g. "int typeof(int)"). if (DS.SetTypeSpecType(DeclSpec::TST_typeofExpr, StartLoc, PrevSpec, - DiagID, Operand.release())) + DiagID, Operand.get())) Diag(StartLoc, DiagID) << PrevSpec; } diff --git a/contrib/llvm/tools/clang/lib/Parse/ParseDeclCXX.cpp b/contrib/llvm/tools/clang/lib/Parse/ParseDeclCXX.cpp index 590ba6c..b277156 100644 --- a/contrib/llvm/tools/clang/lib/Parse/ParseDeclCXX.cpp +++ b/contrib/llvm/tools/clang/lib/Parse/ParseDeclCXX.cpp @@ -14,37 +14,42 @@ #include "clang/Basic/OperatorKinds.h" #include "clang/Parse/Parser.h" #include "clang/Parse/ParseDiagnostic.h" -#include "clang/Parse/DeclSpec.h" -#include "clang/Parse/Scope.h" -#include "clang/Parse/Template.h" +#include "clang/Sema/DeclSpec.h" +#include "clang/Sema/Scope.h" +#include "clang/Sema/ParsedTemplate.h" +#include "clang/Sema/PrettyDeclStackTrace.h" #include "RAIIObjectsForParser.h" using namespace clang; /// ParseNamespace - We know that the current token is a namespace keyword. This -/// may either be a top level namespace or a block-level namespace alias. +/// may either be a top level namespace or a block-level namespace alias. If +/// there was an inline keyword, it has already been parsed. /// /// namespace-definition: [C++ 7.3: basic.namespace] /// named-namespace-definition /// unnamed-namespace-definition /// /// unnamed-namespace-definition: -/// 'namespace' attributes[opt] '{' namespace-body '}' +/// 'inline'[opt] 'namespace' attributes[opt] '{' namespace-body '}' /// /// named-namespace-definition: /// original-namespace-definition /// extension-namespace-definition /// /// original-namespace-definition: -/// 'namespace' identifier attributes[opt] '{' namespace-body '}' +/// 'inline'[opt] 'namespace' identifier attributes[opt] +/// '{' namespace-body '}' /// /// extension-namespace-definition: -/// 'namespace' original-namespace-name '{' namespace-body '}' +/// 'inline'[opt] 'namespace' original-namespace-name +/// '{' namespace-body '}' /// /// namespace-alias-definition: [C++ 7.3.2: namespace.alias] /// 'namespace' identifier '=' qualified-namespace-specifier ';' /// -Parser::DeclPtrTy Parser::ParseNamespace(unsigned Context, - SourceLocation &DeclEnd) { +Decl *Parser::ParseNamespace(unsigned Context, + SourceLocation &DeclEnd, + SourceLocation InlineLoc) { assert(Tok.is(tok::kw_namespace) && "Not a namespace!"); SourceLocation NamespaceLoc = ConsumeToken(); // eat the 'namespace'. @@ -75,6 +80,9 @@ Parser::DeclPtrTy Parser::ParseNamespace(unsigned Context, if (Tok.is(tok::equal)) { if (AttrList) Diag(attrTok, diag::err_unexpected_namespace_attributes_alias); + if (InlineLoc.isValid()) + Diag(InlineLoc, diag::err_inline_namespace_alias) + << FixItHint::CreateRemoval(InlineLoc); return ParseNamespaceAlias(NamespaceLoc, IdentLoc, Ident, DeclEnd); } @@ -82,7 +90,7 @@ Parser::DeclPtrTy Parser::ParseNamespace(unsigned Context, if (Tok.isNot(tok::l_brace)) { Diag(Tok, Ident ? diag::err_expected_lbrace : diag::err_expected_ident_lbrace); - return DeclPtrTy(); + return 0; } SourceLocation LBrace = ConsumeBrace(); @@ -92,19 +100,22 @@ Parser::DeclPtrTy Parser::ParseNamespace(unsigned Context, getCurScope()->getFnParent()) { Diag(LBrace, diag::err_namespace_nonnamespace_scope); SkipUntil(tok::r_brace, false); - return DeclPtrTy(); + return 0; } + // If we're still good, complain about inline namespaces in non-C++0x now. + if (!getLang().CPlusPlus0x && InlineLoc.isValid()) + Diag(InlineLoc, diag::ext_inline_namespace); + // Enter a scope for the namespace. ParseScope NamespaceScope(this, Scope::DeclScope); - DeclPtrTy NamespcDecl = - Actions.ActOnStartNamespaceDef(getCurScope(), IdentLoc, Ident, LBrace, - AttrList.get()); + Decl *NamespcDecl = + Actions.ActOnStartNamespaceDef(getCurScope(), InlineLoc, IdentLoc, Ident, + LBrace, AttrList.get()); - PrettyStackTraceActionsDecl CrashInfo(NamespcDecl, NamespaceLoc, Actions, - PP.getSourceManager(), - "parsing namespace"); + PrettyDeclStackTraceEntry CrashInfo(Actions, NamespcDecl, NamespaceLoc, + "parsing namespace"); while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) { CXX0XAttributeList Attr; @@ -126,7 +137,7 @@ Parser::DeclPtrTy Parser::ParseNamespace(unsigned Context, /// ParseNamespaceAlias - Parse the part after the '=' in a namespace /// alias definition. /// -Parser::DeclPtrTy Parser::ParseNamespaceAlias(SourceLocation NamespaceLoc, +Decl *Parser::ParseNamespaceAlias(SourceLocation NamespaceLoc, SourceLocation AliasLoc, IdentifierInfo *Alias, SourceLocation &DeclEnd) { @@ -141,13 +152,13 @@ Parser::DeclPtrTy Parser::ParseNamespaceAlias(SourceLocation NamespaceLoc, CXXScopeSpec SS; // Parse (optional) nested-name-specifier. - ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, false); + ParseOptionalCXXScopeSpecifier(SS, ParsedType(), false); if (SS.isInvalid() || Tok.isNot(tok::identifier)) { Diag(Tok, diag::err_expected_namespace_name); // Skip to end of the definition and eat the ';'. SkipUntil(tok::semi); - return DeclPtrTy(); + return 0; } // Parse identifier. @@ -170,7 +181,7 @@ Parser::DeclPtrTy Parser::ParseNamespaceAlias(SourceLocation NamespaceLoc, /// 'extern' string-literal '{' declaration-seq[opt] '}' /// 'extern' string-literal declaration /// -Parser::DeclPtrTy Parser::ParseLinkage(ParsingDeclSpec &DS, +Decl *Parser::ParseLinkage(ParsingDeclSpec &DS, unsigned Context) { assert(Tok.is(tok::string_literal) && "Not a string literal!"); llvm::SmallString<8> LangBuffer; @@ -178,12 +189,12 @@ Parser::DeclPtrTy Parser::ParseLinkage(ParsingDeclSpec &DS, bool Invalid = false; llvm::StringRef Lang = PP.getSpelling(Tok, LangBuffer, &Invalid); if (Invalid) - return DeclPtrTy(); + return 0; SourceLocation Loc = ConsumeStringToken(); ParseScope LinkageScope(this, Scope::DeclScope); - DeclPtrTy LinkageSpec + Decl *LinkageSpec = Actions.ActOnStartLinkageSpecification(getCurScope(), /*FIXME: */SourceLocation(), Loc, Lang, @@ -196,7 +207,8 @@ Parser::DeclPtrTy Parser::ParseLinkage(ParsingDeclSpec &DS, } if (Tok.isNot(tok::l_brace)) { - ParseDeclarationOrFunctionDefinition(DS, Attr.AttrList); + DS.setExternInLinkageSpec(true); + ParseExternalDeclaration(Attr, &DS); return Actions.ActOnFinishLinkageSpecification(getCurScope(), LinkageSpec, SourceLocation()); } @@ -221,7 +233,7 @@ Parser::DeclPtrTy Parser::ParseLinkage(ParsingDeclSpec &DS, /// ParseUsingDirectiveOrDeclaration - Parse C++ using using-declaration or /// using-directive. Assumes that current token is 'using'. -Parser::DeclPtrTy Parser::ParseUsingDirectiveOrDeclaration(unsigned Context, +Decl *Parser::ParseUsingDirectiveOrDeclaration(unsigned Context, SourceLocation &DeclEnd, CXX0XAttributeList Attr) { assert(Tok.is(tok::kw_using) && "Not using token"); @@ -257,7 +269,7 @@ Parser::DeclPtrTy Parser::ParseUsingDirectiveOrDeclaration(unsigned Context, /// 'using' 'namespace' ::[opt] nested-name-specifier[opt] /// namespace-name attributes[opt] ; /// -Parser::DeclPtrTy Parser::ParseUsingDirective(unsigned Context, +Decl *Parser::ParseUsingDirective(unsigned Context, SourceLocation UsingLoc, SourceLocation &DeclEnd, AttributeList *Attr) { @@ -273,7 +285,7 @@ Parser::DeclPtrTy Parser::ParseUsingDirective(unsigned Context, CXXScopeSpec SS; // Parse (optional) nested-name-specifier. - ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, false); + ParseOptionalCXXScopeSpecifier(SS, ParsedType(), false); IdentifierInfo *NamespcName = 0; SourceLocation IdentLoc = SourceLocation(); @@ -284,7 +296,7 @@ Parser::DeclPtrTy Parser::ParseUsingDirective(unsigned Context, // If there was invalid namespace name, skip to end of decl, and eat ';'. SkipUntil(tok::semi); // FIXME: Are there cases, when we would like to call ActOnUsingDirective? - return DeclPtrTy(); + return 0; } // Parse identifier. @@ -316,7 +328,7 @@ Parser::DeclPtrTy Parser::ParseUsingDirective(unsigned Context, /// unqualified-id /// 'using' :: unqualified-id /// -Parser::DeclPtrTy Parser::ParseUsingDeclaration(unsigned Context, +Decl *Parser::ParseUsingDeclaration(unsigned Context, SourceLocation UsingLoc, SourceLocation &DeclEnd, AccessSpecifier AS) { @@ -335,12 +347,12 @@ Parser::DeclPtrTy Parser::ParseUsingDeclaration(unsigned Context, IsTypeName = false; // Parse nested-name-specifier. - ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, false); + ParseOptionalCXXScopeSpecifier(SS, ParsedType(), false); // Check nested-name specifier. if (SS.isInvalid()) { SkipUntil(tok::semi); - return DeclPtrTy(); + return 0; } // Parse the unqualified-id. We allow parsing of both constructor and @@ -351,10 +363,10 @@ Parser::DeclPtrTy Parser::ParseUsingDeclaration(unsigned Context, /*EnteringContext=*/false, /*AllowDestructorName=*/true, /*AllowConstructorName=*/true, - /*ObjectType=*/0, + ParsedType(), Name)) { SkipUntil(tok::semi); - return DeclPtrTy(); + return 0; } // Parse (optional) attributes (most likely GNU strong-using extension). @@ -377,43 +389,44 @@ Parser::DeclPtrTy Parser::ParseUsingDeclaration(unsigned Context, /// static_assert-declaration: /// static_assert ( constant-expression , string-literal ) ; /// -Parser::DeclPtrTy Parser::ParseStaticAssertDeclaration(SourceLocation &DeclEnd){ +Decl *Parser::ParseStaticAssertDeclaration(SourceLocation &DeclEnd){ assert(Tok.is(tok::kw_static_assert) && "Not a static_assert declaration"); SourceLocation StaticAssertLoc = ConsumeToken(); if (Tok.isNot(tok::l_paren)) { Diag(Tok, diag::err_expected_lparen); - return DeclPtrTy(); + return 0; } SourceLocation LParenLoc = ConsumeParen(); - OwningExprResult AssertExpr(ParseConstantExpression()); + ExprResult AssertExpr(ParseConstantExpression()); if (AssertExpr.isInvalid()) { SkipUntil(tok::semi); - return DeclPtrTy(); + return 0; } if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "", tok::semi)) - return DeclPtrTy(); + return 0; if (Tok.isNot(tok::string_literal)) { Diag(Tok, diag::err_expected_string_literal); SkipUntil(tok::semi); - return DeclPtrTy(); + return 0; } - OwningExprResult AssertMessage(ParseStringLiteralExpression()); + ExprResult AssertMessage(ParseStringLiteralExpression()); if (AssertMessage.isInvalid()) - return DeclPtrTy(); + return 0; MatchRHSPunctuation(tok::r_paren, LParenLoc); DeclEnd = Tok.getLocation(); ExpectAndConsume(tok::semi, diag::err_expected_semi_after_static_assert); - return Actions.ActOnStaticAssertDeclaration(StaticAssertLoc, move(AssertExpr), - move(AssertMessage)); + return Actions.ActOnStaticAssertDeclaration(StaticAssertLoc, + AssertExpr.take(), + AssertMessage.take()); } /// ParseDecltypeSpecifier - Parse a C++0x decltype specifier. @@ -437,8 +450,8 @@ void Parser::ParseDecltypeSpecifier(DeclSpec &DS) { // C++0x [dcl.type.simple]p4: // The operand of the decltype specifier is an unevaluated operand. EnterExpressionEvaluationContext Unevaluated(Actions, - Action::Unevaluated); - OwningExprResult Result = ParseExpression(); + Sema::Unevaluated); + ExprResult Result = ParseExpression(); if (Result.isInvalid()) { SkipUntil(tok::r_paren); return; @@ -483,7 +496,7 @@ Parser::TypeResult Parser::ParseClassName(SourceLocation &EndLocation, AnnotateTemplateIdTokenAsType(SS); assert(Tok.is(tok::annot_typename) && "template-id -> type failed"); - TypeTy *Type = Tok.getAnnotationValue(); + ParsedType Type = getTypeAnnotation(Tok); EndLocation = Tok.getAnnotationEndLoc(); ConsumeToken(); @@ -536,13 +549,13 @@ Parser::TypeResult Parser::ParseClassName(SourceLocation &EndLocation, // Retrieve the type from the annotation token, consume that token, and // return. EndLocation = Tok.getAnnotationEndLoc(); - TypeTy *Type = Tok.getAnnotationValue(); + ParsedType Type = getTypeAnnotation(Tok); ConsumeToken(); return Type; } // We have an identifier; check whether it is actually a type. - TypeTy *Type = Actions.getTypeName(*Id, IdLoc, getCurScope(), SS, true); + ParsedType Type = Actions.getTypeName(*Id, IdLoc, getCurScope(), SS, true); if (!Type) { Diag(IdLoc, diag::err_expected_class_name); return true; @@ -550,7 +563,19 @@ Parser::TypeResult Parser::ParseClassName(SourceLocation &EndLocation, // Consume the identifier. EndLocation = IdLoc; - return Type; + + // Fake up a Declarator to use with ActOnTypeName. + DeclSpec DS; + DS.SetRangeStart(IdLoc); + DS.SetRangeEnd(EndLocation); + DS.getTypeSpecScope() = *SS; + + const char *PrevSpec = 0; + unsigned DiagID; + DS.SetTypeSpecType(TST_typename, IdLoc, PrevSpec, DiagID, Type); + + Declarator DeclaratorInfo(DS, Declarator::TypeNameContext); + return Actions.ActOnTypeName(getCurScope(), DeclaratorInfo); } /// ParseClassSpecifier - Parse a C++ class-specifier [C++ class] or @@ -633,7 +658,7 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, AttrList = ParseGNUAttributes(); // If declspecs exist after tag, parse them. - if (Tok.is(tok::kw___declspec)) + while (Tok.is(tok::kw___declspec)) AttrList = ParseMicrosoftDeclSpec(AttrList); // If C++0x attributes exist here, parse them. @@ -648,7 +673,7 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, // token sequence "struct __is_pod", make __is_pod into a normal // identifier rather than a keyword, to allow libstdc++ 4.2 to work // properly. - Tok.getIdentifierInfo()->setTokenID(tok::identifier); + Tok.getIdentifierInfo()->RevertTokenIDToIdentifier(); Tok.setKind(tok::identifier); } @@ -658,7 +683,7 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, // token sequence "struct __is_empty", make __is_empty into a normal // identifier rather than a keyword, to allow libstdc++ 4.2 to work // properly. - Tok.getIdentifierInfo()->setTokenID(tok::identifier); + Tok.getIdentifierInfo()->RevertTokenIDToIdentifier(); Tok.setKind(tok::identifier); } @@ -668,7 +693,8 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, // "FOO : BAR" is not a potential typo for "FOO::BAR". ColonProtectionRAIIObject X(*this); - ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, true); + if (ParseOptionalCXXScopeSpecifier(SS, ParsedType(), true)) + DS.SetTypeSpecError(); if (SS.isSet()) if (Tok.isNot(tok::identifier) && Tok.isNot(tok::annot_template_id)) Diag(Tok, diag::err_expected_ident); @@ -769,9 +795,9 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, // or // &T::operator struct s; // For these, SuppressDeclarations is true. - Action::TagUseKind TUK; + Sema::TagUseKind TUK; if (SuppressDeclarations) - TUK = Action::TUK_Reference; + TUK = Sema::TUK_Reference; else if (Tok.is(tok::l_brace) || (getLang().CPlusPlus && Tok.is(tok::colon))){ if (DS.isFriendSpecified()) { // C++ [class.friend]p2: @@ -782,20 +808,23 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, // Skip everything up to the semicolon, so that this looks like a proper // friend class (or template thereof) declaration. SkipUntil(tok::semi, true, true); - TUK = Action::TUK_Friend; + TUK = Sema::TUK_Friend; } else { // Okay, this is a class definition. - TUK = Action::TUK_Definition; + TUK = Sema::TUK_Definition; } } else if (Tok.is(tok::semi)) - TUK = DS.isFriendSpecified() ? Action::TUK_Friend : Action::TUK_Declaration; + TUK = DS.isFriendSpecified() ? Sema::TUK_Friend : Sema::TUK_Declaration; else - TUK = Action::TUK_Reference; - - if (!Name && !TemplateId && TUK != Action::TUK_Definition) { - // We have a declaration or reference to an anonymous class. - Diag(StartLoc, diag::err_anon_type_definition) - << DeclSpec::getSpecifierName(TagType); + TUK = Sema::TUK_Reference; + + if (!Name && !TemplateId && (DS.getTypeSpecType() == DeclSpec::TST_error || + TUK != Sema::TUK_Definition)) { + if (DS.getTypeSpecType() != DeclSpec::TST_error) { + // We have a declaration or reference to an anonymous class. + Diag(StartLoc, diag::err_anon_type_definition) + << DeclSpec::getSpecifierName(TagType); + } SkipUntil(tok::comma, true); @@ -805,8 +834,8 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, } // Create the tag portion of the class or class template. - Action::DeclResult TagOrTempResult = true; // invalid - Action::TypeResult TypeResult = true; // invalid + DeclResult TagOrTempResult = true; // invalid + TypeResult TypeResult = true; // invalid bool Owned = false; if (TemplateId) { @@ -816,7 +845,7 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, TemplateId->getTemplateArgs(), TemplateId->NumArgs); if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation && - TUK == Action::TUK_Declaration) { + TUK == Sema::TUK_Declaration) { // This is an explicit instantiation of a class template. TagOrTempResult = Actions.ActOnExplicitInstantiation(getCurScope(), @@ -825,7 +854,7 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, TagType, StartLoc, SS, - TemplateTy::make(TemplateId->Template), + TemplateId->Template, TemplateId->TemplateNameLoc, TemplateId->LAngleLoc, TemplateArgsPtr, @@ -836,11 +865,11 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, // they have template headers, in which case they're ill-formed // (FIXME: "template <class T> friend class A<T>::B<int>;"). // We diagnose this error in ActOnClassTemplateSpecialization. - } else if (TUK == Action::TUK_Reference || - (TUK == Action::TUK_Friend && + } else if (TUK == Sema::TUK_Reference || + (TUK == Sema::TUK_Friend && TemplateInfo.Kind == ParsedTemplateInfo::NonTemplate)) { TypeResult - = Actions.ActOnTemplateIdType(TemplateTy::make(TemplateId->Template), + = Actions.ActOnTemplateIdType(TemplateId->Template, TemplateId->TemplateNameLoc, TemplateId->LAngleLoc, TemplateArgsPtr, @@ -862,7 +891,7 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, // but it actually has a definition. Most likely, this was // meant to be an explicit specialization, but the user forgot // the '<>' after 'template'. - assert(TUK == Action::TUK_Definition && "Expected a definition here"); + assert(TUK == Sema::TUK_Definition && "Expected a definition here"); SourceLocation LAngleLoc = PP.getLocForEndOfToken(TemplateInfo.TemplateLoc); @@ -887,19 +916,19 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, TagOrTempResult = Actions.ActOnClassTemplateSpecialization(getCurScope(), TagType, TUK, StartLoc, SS, - TemplateTy::make(TemplateId->Template), + TemplateId->Template, TemplateId->TemplateNameLoc, TemplateId->LAngleLoc, TemplateArgsPtr, TemplateId->RAngleLoc, AttrList, - Action::MultiTemplateParamsArg(Actions, + MultiTemplateParamsArg(Actions, TemplateParams? &(*TemplateParams)[0] : 0, TemplateParams? TemplateParams->size() : 0)); } TemplateId->Destroy(); } else if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation && - TUK == Action::TUK_Declaration) { + TUK == Sema::TUK_Declaration) { // Explicit instantiation of a member of a class template // specialization, e.g., // @@ -913,7 +942,7 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, NameLoc, AttrList); } else { if (TemplateInfo.Kind == ParsedTemplateInfo::ExplicitInstantiation && - TUK == Action::TUK_Definition) { + TUK == Sema::TUK_Definition) { // FIXME: Diagnose this particular error. } @@ -922,7 +951,7 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, // Declaration or definition of a class type TagOrTempResult = Actions.ActOnTag(getCurScope(), TagType, TUK, StartLoc, SS, Name, NameLoc, AttrList, AS, - Action::MultiTemplateParamsArg(Actions, + MultiTemplateParamsArg(Actions, TemplateParams? &(*TemplateParams)[0] : 0, TemplateParams? TemplateParams->size() : 0), Owned, IsDependent); @@ -935,7 +964,7 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, } // If there is a body, parse it and inform the actions module. - if (TUK == Action::TUK_Definition) { + if (TUK == Sema::TUK_Definition) { assert(Tok.is(tok::l_brace) || (getLang().CPlusPlus && Tok.is(tok::colon))); if (getLang().CPlusPlus) @@ -944,27 +973,25 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, ParseStructUnionBody(StartLoc, TagType, TagOrTempResult.get()); } - void *Result; + // FIXME: The DeclSpec should keep the locations of both the keyword and the + // name (if there is one). + SourceLocation TSTLoc = NameLoc.isValid()? NameLoc : StartLoc; + + const char *PrevSpec = 0; + unsigned DiagID; + bool Result; if (!TypeResult.isInvalid()) { - TagType = DeclSpec::TST_typename; - Result = TypeResult.get(); - Owned = false; + Result = DS.SetTypeSpecType(DeclSpec::TST_typename, TSTLoc, + PrevSpec, DiagID, TypeResult.get()); } else if (!TagOrTempResult.isInvalid()) { - Result = TagOrTempResult.get().getAs<void>(); + Result = DS.SetTypeSpecType(TagType, TSTLoc, PrevSpec, DiagID, + TagOrTempResult.get(), Owned); } else { DS.SetTypeSpecError(); return; } - const char *PrevSpec = 0; - unsigned DiagID; - - // FIXME: The DeclSpec should keep the locations of both the keyword and the - // name (if there is one). - SourceLocation TSTLoc = NameLoc.isValid()? NameLoc : StartLoc; - - if (DS.SetTypeSpecType(TagType, TSTLoc, PrevSpec, DiagID, - Result, Owned)) + if (Result) Diag(StartLoc, DiagID) << PrevSpec; // At this point, we've successfully parsed a class-specifier in 'definition' @@ -974,7 +1001,7 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, // the end of the declaration and recover that way. // // This switch enumerates the valid "follow" set for definition. - if (TUK == Action::TUK_Definition) { + if (TUK == Sema::TUK_Definition) { bool ExpectedSemi = true; switch (Tok.getKind()) { default: break; @@ -1048,12 +1075,12 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, /// base-specifier-list: /// base-specifier '...'[opt] /// base-specifier-list ',' base-specifier '...'[opt] -void Parser::ParseBaseClause(DeclPtrTy ClassDecl) { +void Parser::ParseBaseClause(Decl *ClassDecl) { assert(Tok.is(tok::colon) && "Not a base clause"); ConsumeToken(); // Build up an array of parsed base specifiers. - llvm::SmallVector<BaseTy *, 8> BaseInfo; + llvm::SmallVector<CXXBaseSpecifier *, 8> BaseInfo; while (true) { // Parse a base-specifier. @@ -1090,7 +1117,7 @@ void Parser::ParseBaseClause(DeclPtrTy ClassDecl) { /// class-name /// access-specifier 'virtual'[opt] ::[opt] nested-name-specifier[opt] /// class-name -Parser::BaseResult Parser::ParseBaseSpecifier(DeclPtrTy ClassDecl) { +Parser::BaseResult Parser::ParseBaseSpecifier(Decl *ClassDecl) { bool IsVirtual = false; SourceLocation StartLoc = Tok.getLocation(); @@ -1120,8 +1147,7 @@ Parser::BaseResult Parser::ParseBaseSpecifier(DeclPtrTy ClassDecl) { // Parse optional '::' and optional nested-name-specifier. CXXScopeSpec SS; - ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, - /*EnteringContext=*/false); + ParseOptionalCXXScopeSpecifier(SS, ParsedType(), /*EnteringContext=*/false); // The location of the base class itself. SourceLocation BaseLoc = Tok.getLocation(); @@ -1158,7 +1184,7 @@ AccessSpecifier Parser::getAccessSpecifierIfPresent() const { } void Parser::HandleMemberFunctionDefaultArgs(Declarator& DeclaratorInfo, - DeclPtrTy ThisDecl) { + Decl *ThisDecl) { // We just declared a member function. If this member function // has any default arguments, we'll need to parse them later. LateParsedMethodDeclaration *LateMethod = 0; @@ -1218,7 +1244,8 @@ void Parser::HandleMemberFunctionDefaultArgs(Declarator& DeclaratorInfo, /// '=' constant-expression /// void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS, - const ParsedTemplateInfo &TemplateInfo) { + const ParsedTemplateInfo &TemplateInfo, + ParsingDeclRAIIObject *TemplateDiags) { // Access declarations. if (!TemplateInfo.Kind && (Tok.is(tok::identifier) || Tok.is(tok::coloncolon)) && @@ -1233,11 +1260,11 @@ void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS, if (isAccessDecl) { // Collect the scope specifier token we annotated earlier. CXXScopeSpec SS; - ParseOptionalCXXScopeSpecifier(SS, /*ObjectType*/ 0, false); + ParseOptionalCXXScopeSpecifier(SS, ParsedType(), false); // Try to parse an unqualified-id. UnqualifiedId Name; - if (ParseUnqualifiedId(SS, false, true, true, /*ObjectType*/ 0, Name)) { + if (ParseUnqualifiedId(SS, false, true, true, ParsedType(), Name)) { SkipUntil(tok::semi); return; } @@ -1281,7 +1308,7 @@ void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS, // __extension__ silences extension warnings in the subexpression. ExtensionRAIIObject O(Diags); // Use RAII to do this. ConsumeToken(); - return ParseCXXClassMemberDeclaration(AS, TemplateInfo); + return ParseCXXClassMemberDeclaration(AS, TemplateInfo, TemplateDiags); } // Don't parse FOO:BAR as if it were a typo for FOO::BAR, in this context it @@ -1317,17 +1344,19 @@ void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS, SourceLocation DSStart = Tok.getLocation(); // decl-specifier-seq: // Parse the common declaration-specifiers piece. - ParsingDeclSpec DS(*this); + ParsingDeclSpec DS(*this, TemplateDiags); DS.AddAttributes(AttrList.AttrList); ParseDeclarationSpecifiers(DS, TemplateInfo, AS, DSC_class); - Action::MultiTemplateParamsArg TemplateParams(Actions, + MultiTemplateParamsArg TemplateParams(Actions, TemplateInfo.TemplateParams? TemplateInfo.TemplateParams->data() : 0, TemplateInfo.TemplateParams? TemplateInfo.TemplateParams->size() : 0); if (Tok.is(tok::semi)) { ConsumeToken(); - Actions.ParsedFreeStandingDeclSpec(getCurScope(), AS, DS); + Decl *TheDecl = + Actions.ParsedFreeStandingDeclSpec(getCurScope(), AS, DS); + DS.complete(TheDecl); return; } @@ -1385,9 +1414,9 @@ void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS, // member-declarator // member-declarator-list ',' member-declarator - llvm::SmallVector<DeclPtrTy, 8> DeclsInGroup; - OwningExprResult BitfieldSize(Actions); - OwningExprResult Init(Actions); + llvm::SmallVector<Decl *, 8> DeclsInGroup; + ExprResult BitfieldSize; + ExprResult Init; bool Deleted = false; while (1) { @@ -1426,7 +1455,7 @@ void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS, // If a simple-asm-expr is present, parse it. if (Tok.is(tok::kw_asm)) { SourceLocation Loc; - OwningExprResult AsmLabel(ParseSimpleAsm(&Loc)); + ExprResult AsmLabel(ParseSimpleAsm(&Loc)); if (AsmLabel.isInvalid()) SkipUntil(tok::comma, true, true); @@ -1445,7 +1474,7 @@ void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS, // this call will *not* return the created decl; It will return null. // See Sema::ActOnCXXMemberDeclarator for details. - DeclPtrTy ThisDecl; + Decl *ThisDecl = 0; if (DS.isFriendSpecified()) { // TODO: handle initializers, bitfields, 'delete' ThisDecl = Actions.ActOnFriendFunctionDecl(getCurScope(), DeclaratorInfo, @@ -1515,14 +1544,13 @@ void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS, /// access-specifier ':' member-specification[opt] /// void Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc, - unsigned TagType, DeclPtrTy TagDecl) { + unsigned TagType, Decl *TagDecl) { assert((TagType == DeclSpec::TST_struct || TagType == DeclSpec::TST_union || TagType == DeclSpec::TST_class) && "Invalid TagType!"); - PrettyStackTraceActionsDecl CrashInfo(TagDecl, RecordLoc, Actions, - PP.getSourceManager(), - "parsing struct/union/class body"); + PrettyDeclStackTraceEntry CrashInfo(Actions, TagDecl, RecordLoc, + "parsing struct/union/class body"); // Determine whether this is a non-nested class. Note that local // classes are *not* considered to be nested classes. @@ -1681,21 +1709,28 @@ void Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc, /// [C++] mem-initializer-list: /// mem-initializer /// mem-initializer , mem-initializer-list -void Parser::ParseConstructorInitializer(DeclPtrTy ConstructorDecl) { +void Parser::ParseConstructorInitializer(Decl *ConstructorDecl) { assert(Tok.is(tok::colon) && "Constructor initializer always starts with ':'"); SourceLocation ColonLoc = ConsumeToken(); - llvm::SmallVector<MemInitTy*, 4> MemInitializers; + llvm::SmallVector<CXXBaseOrMemberInitializer*, 4> MemInitializers; bool AnyErrors = false; do { - MemInitResult MemInit = ParseMemInitializer(ConstructorDecl); - if (!MemInit.isInvalid()) - MemInitializers.push_back(MemInit.get()); - else - AnyErrors = true; - + if (Tok.is(tok::code_completion)) { + Actions.CodeCompleteConstructorInitializer(ConstructorDecl, + MemInitializers.data(), + MemInitializers.size()); + ConsumeCodeCompletionToken(); + } else { + MemInitResult MemInit = ParseMemInitializer(ConstructorDecl); + if (!MemInit.isInvalid()) + MemInitializers.push_back(MemInit.get()); + else + AnyErrors = true; + } + if (Tok.is(tok::comma)) ConsumeToken(); else if (Tok.is(tok::l_brace)) @@ -1724,11 +1759,11 @@ void Parser::ParseConstructorInitializer(DeclPtrTy ConstructorDecl) { /// [C++] mem-initializer-id: /// '::'[opt] nested-name-specifier[opt] class-name /// identifier -Parser::MemInitResult Parser::ParseMemInitializer(DeclPtrTy ConstructorDecl) { +Parser::MemInitResult Parser::ParseMemInitializer(Decl *ConstructorDecl) { // parse '::'[opt] nested-name-specifier[opt] CXXScopeSpec SS; - ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, false); - TypeTy *TemplateTypeTy = 0; + ParseOptionalCXXScopeSpecifier(SS, ParsedType(), false); + ParsedType TemplateTypeTy; if (Tok.is(tok::annot_template_id)) { TemplateIdAnnotation *TemplateId = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue()); @@ -1736,7 +1771,7 @@ Parser::MemInitResult Parser::ParseMemInitializer(DeclPtrTy ConstructorDecl) { TemplateId->Kind == TNK_Dependent_template_name) { AnnotateTemplateIdTokenAsType(&SS); assert(Tok.is(tok::annot_typename) && "template-id -> type failed"); - TemplateTypeTy = Tok.getAnnotationValue(); + TemplateTypeTy = getTypeAnnotation(Tok); } } if (!TemplateTypeTy && Tok.isNot(tok::identifier)) { @@ -1785,9 +1820,9 @@ Parser::MemInitResult Parser::ParseMemInitializer(DeclPtrTy ConstructorDecl) { /// type-id-list ',' type-id /// bool Parser::ParseExceptionSpecification(SourceLocation &EndLoc, - llvm::SmallVector<TypeTy*, 2> + llvm::SmallVectorImpl<ParsedType> &Exceptions, - llvm::SmallVector<SourceRange, 2> + llvm::SmallVectorImpl<SourceRange> &Ranges, bool &hasAnyExceptionSpec) { assert(Tok.is(tok::kw_throw) && "expected throw"); @@ -1831,7 +1866,7 @@ bool Parser::ParseExceptionSpecification(SourceLocation &EndLoc, /// \brief We have just started parsing the definition of a new class, /// so push that class onto our stack of classes that is currently /// being parsed. -void Parser::PushParsingClass(DeclPtrTy ClassDecl, bool NonNestedClass) { +void Parser::PushParsingClass(Decl *ClassDecl, bool NonNestedClass) { assert((NonNestedClass || !ClassStack.empty()) && "Nested class without outer class"); ClassStack.push(new ParsingClass(ClassDecl, NonNestedClass)); @@ -1997,7 +2032,7 @@ CXX0XAttributeList Parser::ParseCXX0XAttributes(SourceLocation *EndLoc) { } SourceLocation ParamLoc = ConsumeParen(); - OwningExprResult ArgExpr = ParseCXX0XAlignArgument(ParamLoc); + ExprResult ArgExpr = ParseCXX0XAlignArgument(ParamLoc); MatchRHSPunctuation(tok::r_paren, ParamLoc); @@ -2042,15 +2077,14 @@ CXX0XAttributeList Parser::ParseCXX0XAttributes(SourceLocation *EndLoc) { /// /// [C++0x] 'align' '(' type-id ')' /// [C++0x] 'align' '(' assignment-expression ')' -Parser::OwningExprResult Parser::ParseCXX0XAlignArgument(SourceLocation Start) { +ExprResult Parser::ParseCXX0XAlignArgument(SourceLocation Start) { if (isTypeIdInParens()) { - EnterExpressionEvaluationContext Unevaluated(Actions, - Action::Unevaluated); + EnterExpressionEvaluationContext Unevaluated(Actions, Sema::Unevaluated); SourceLocation TypeLoc = Tok.getLocation(); - TypeTy *Ty = ParseTypeName().get(); + ParsedType Ty = ParseTypeName().get(); SourceRange TypeRange(Start, Tok.getLocation()); - return Actions.ActOnSizeOfAlignOfExpr(TypeLoc, false, true, Ty, - TypeRange); + return Actions.ActOnSizeOfAlignOfExpr(TypeLoc, false, true, + Ty.getAsOpaquePtr(), TypeRange); } else return ParseConstantExpression(); } diff --git a/contrib/llvm/tools/clang/lib/Parse/ParseExpr.cpp b/contrib/llvm/tools/clang/lib/Parse/ParseExpr.cpp index e7973f7..c4beab1 100644 --- a/contrib/llvm/tools/clang/lib/Parse/ParseExpr.cpp +++ b/contrib/llvm/tools/clang/lib/Parse/ParseExpr.cpp @@ -20,9 +20,9 @@ //===----------------------------------------------------------------------===// #include "clang/Parse/Parser.h" -#include "clang/Parse/DeclSpec.h" -#include "clang/Parse/Scope.h" -#include "clang/Parse/Template.h" +#include "clang/Sema/DeclSpec.h" +#include "clang/Sema/Scope.h" +#include "clang/Sema/ParsedTemplate.h" #include "clang/Basic/PrettyStackTrace.h" #include "RAIIObjectsForParser.h" #include "llvm/ADT/SmallVector.h" @@ -30,8 +30,7 @@ using namespace clang; /// getBinOpPrecedence - Return the precedence of the specified binary operator -/// token. This returns: -/// +/// token. static prec::Level getBinOpPrecedence(tok::TokenKind Kind, bool GreaterThanIsOperator, bool CPlusPlus0x) { @@ -176,8 +175,8 @@ static prec::Level getBinOpPrecedence(tok::TokenKind Kind, /// assignment-expression /// expression ',' assignment-expression /// -Parser::OwningExprResult Parser::ParseExpression() { - OwningExprResult LHS(ParseAssignmentExpression()); +ExprResult Parser::ParseExpression() { + ExprResult LHS(ParseAssignmentExpression()); if (LHS.isInvalid()) return move(LHS); return ParseRHSOfBinaryExpression(move(LHS), prec::Comma); @@ -188,9 +187,9 @@ Parser::OwningExprResult Parser::ParseExpression() { /// routine is necessary to disambiguate @try-statement from, /// for example, @encode-expression. /// -Parser::OwningExprResult +ExprResult Parser::ParseExpressionWithLeadingAt(SourceLocation AtLoc) { - OwningExprResult LHS(ParseObjCAtExpression(AtLoc)); + ExprResult LHS(ParseObjCAtExpression(AtLoc)); if (LHS.isInvalid()) return move(LHS); return ParseRHSOfBinaryExpression(move(LHS), prec::Comma); @@ -199,9 +198,9 @@ Parser::ParseExpressionWithLeadingAt(SourceLocation AtLoc) { /// This routine is called when a leading '__extension__' is seen and /// consumed. This is necessary because the token gets consumed in the /// process of disambiguating between an expression and a declaration. -Parser::OwningExprResult +ExprResult Parser::ParseExpressionWithLeadingExtension(SourceLocation ExtLoc) { - OwningExprResult LHS(Actions, true); + ExprResult LHS(true); { // Silence extension warnings in the sub-expression ExtensionRAIIObject O(Diags); @@ -211,27 +210,27 @@ Parser::ParseExpressionWithLeadingExtension(SourceLocation ExtLoc) { } LHS = Actions.ActOnUnaryOp(getCurScope(), ExtLoc, tok::kw___extension__, - move(LHS)); + LHS.take()); if (LHS.isInvalid()) return move(LHS); - return ParseRHSOfBinaryExpression(move(LHS), prec::Comma); + return ParseRHSOfBinaryExpression(LHS.take(), prec::Comma); } /// ParseAssignmentExpression - Parse an expr that doesn't include commas. /// -Parser::OwningExprResult Parser::ParseAssignmentExpression() { +ExprResult Parser::ParseAssignmentExpression() { if (Tok.is(tok::code_completion)) { - Actions.CodeCompleteOrdinaryName(getCurScope(), Action::CCC_Expression); + Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Expression); ConsumeCodeCompletionToken(); } if (Tok.is(tok::kw_throw)) return ParseThrowExpression(); - OwningExprResult LHS(ParseCastExpression(false)); + ExprResult LHS(ParseCastExpression(false)); if (LHS.isInvalid()) return move(LHS); - return ParseRHSOfBinaryExpression(move(LHS), prec::Assignment); + return ParseRHSOfBinaryExpression(LHS.take(), prec::Assignment); } /// ParseAssignmentExprWithObjCMessageExprStart - Parse an assignment expression @@ -242,38 +241,38 @@ Parser::OwningExprResult Parser::ParseAssignmentExpression() { /// /// Since this handles full assignment-expression's, it handles postfix /// expressions and other binary operators for these expressions as well. -Parser::OwningExprResult +ExprResult Parser::ParseAssignmentExprWithObjCMessageExprStart(SourceLocation LBracLoc, SourceLocation SuperLoc, - TypeTy *ReceiverType, - ExprArg ReceiverExpr) { - OwningExprResult R(ParseObjCMessageExpressionBody(LBracLoc, SuperLoc, - ReceiverType, - move(ReceiverExpr))); + ParsedType ReceiverType, + Expr *ReceiverExpr) { + ExprResult R + = ParseObjCMessageExpressionBody(LBracLoc, SuperLoc, + ReceiverType, ReceiverExpr); if (R.isInvalid()) return move(R); - R = ParsePostfixExpressionSuffix(move(R)); + R = ParsePostfixExpressionSuffix(R.take()); if (R.isInvalid()) return move(R); - return ParseRHSOfBinaryExpression(move(R), prec::Assignment); + return ParseRHSOfBinaryExpression(R.take(), prec::Assignment); } -Parser::OwningExprResult Parser::ParseConstantExpression() { +ExprResult Parser::ParseConstantExpression() { // C++ [basic.def.odr]p2: // An expression is potentially evaluated unless it appears where an // integral constant expression is required (see 5.19) [...]. EnterExpressionEvaluationContext Unevaluated(Actions, - Action::Unevaluated); + Sema::Unevaluated); - OwningExprResult LHS(ParseCastExpression(false)); + ExprResult LHS(ParseCastExpression(false)); if (LHS.isInvalid()) return move(LHS); - return ParseRHSOfBinaryExpression(move(LHS), prec::Conditional); + return ParseRHSOfBinaryExpression(LHS.take(), prec::Conditional); } /// ParseRHSOfBinaryExpression - Parse a binary expression that starts with /// LHS and has a precedence of at least MinPrec. -Parser::OwningExprResult -Parser::ParseRHSOfBinaryExpression(OwningExprResult LHS, prec::Level MinPrec) { +ExprResult +Parser::ParseRHSOfBinaryExpression(ExprResult LHS, prec::Level MinPrec) { prec::Level NextTokPrec = getBinOpPrecedence(Tok.getKind(), GreaterThanIsOperator, getLang().CPlusPlus0x); @@ -291,7 +290,7 @@ Parser::ParseRHSOfBinaryExpression(OwningExprResult LHS, prec::Level MinPrec) { ConsumeToken(); // Special case handling for the ternary operator. - OwningExprResult TernaryMiddle(Actions, true); + ExprResult TernaryMiddle(true); if (NextTokPrec == prec::Conditional) { if (Tok.isNot(tok::colon)) { // Don't parse FOO:BAR as if it were a typo for FOO::BAR. @@ -358,7 +357,7 @@ Parser::ParseRHSOfBinaryExpression(OwningExprResult LHS, prec::Level MinPrec) { // Therefore we need some special-casing here. // Also note that the third operand of the conditional operator is // an assignment-expression in C++. - OwningExprResult RHS(Actions); + ExprResult RHS; if (getLang().CPlusPlus && NextTokPrec <= prec::Conditional) RHS = ParseAssignmentExpression(); else @@ -385,7 +384,7 @@ Parser::ParseRHSOfBinaryExpression(OwningExprResult LHS, prec::Level MinPrec) { // is okay, to bind exactly as tightly. For example, compile A=B=C=D as // A=(B=(C=D)), where each paren is a level of recursion here. // The function takes ownership of the RHS. - RHS = ParseRHSOfBinaryExpression(move(RHS), + RHS = ParseRHSOfBinaryExpression(RHS.get(), static_cast<prec::Level>(ThisPrec + !isRightAssoc)); if (RHS.isInvalid()) return move(RHS); @@ -408,11 +407,11 @@ Parser::ParseRHSOfBinaryExpression(OwningExprResult LHS, prec::Level MinPrec) { Actions.getExprRange(RHS.get()).getEnd())); LHS = Actions.ActOnBinOp(getCurScope(), OpToken.getLocation(), - OpToken.getKind(), move(LHS), move(RHS)); + OpToken.getKind(), LHS.take(), RHS.take()); } else LHS = Actions.ActOnConditionalOp(OpToken.getLocation(), ColonLoc, - move(LHS), move(TernaryMiddle), - move(RHS)); + LHS.take(), TernaryMiddle.take(), + RHS.take()); } } } @@ -422,11 +421,11 @@ Parser::ParseRHSOfBinaryExpression(OwningExprResult LHS, prec::Level MinPrec) { /// id-expression that is the operand of address-of gets special treatment /// due to member pointers. /// -Parser::OwningExprResult Parser::ParseCastExpression(bool isUnaryExpression, +ExprResult Parser::ParseCastExpression(bool isUnaryExpression, bool isAddressOfOperand, - TypeTy *TypeOfCast) { + ParsedType TypeOfCast) { bool NotCastExpr; - OwningExprResult Res = ParseCastExpression(isUnaryExpression, + ExprResult Res = ParseCastExpression(isUnaryExpression, isAddressOfOperand, NotCastExpr, TypeOfCast); @@ -527,14 +526,14 @@ Parser::OwningExprResult Parser::ParseCastExpression(bool isUnaryExpression, /// '::'[opt] 'delete' '[' ']' cast-expression /// /// [GNU] unary-type-trait: -/// '__has_nothrow_assign' [TODO] -/// '__has_nothrow_copy' [TODO] -/// '__has_nothrow_constructor' [TODO] +/// '__has_nothrow_assign' +/// '__has_nothrow_copy' +/// '__has_nothrow_constructor' /// '__has_trivial_assign' [TODO] /// '__has_trivial_copy' [TODO] /// '__has_trivial_constructor' /// '__has_trivial_destructor' -/// '__has_virtual_destructor' [TODO] +/// '__has_virtual_destructor' /// '__is_abstract' [TODO] /// '__is_class' /// '__is_empty' [TODO] @@ -546,11 +545,11 @@ Parser::OwningExprResult Parser::ParseCastExpression(bool isUnaryExpression, /// [GNU] binary-type-trait: /// '__is_base_of' [TODO] /// -Parser::OwningExprResult Parser::ParseCastExpression(bool isUnaryExpression, +ExprResult Parser::ParseCastExpression(bool isUnaryExpression, bool isAddressOfOperand, bool &NotCastExpr, - TypeTy *TypeOfCast) { - OwningExprResult Res(Actions); + ParsedType TypeOfCast) { + ExprResult Res; tok::TokenKind SavedKind = Tok.getKind(); NotCastExpr = false; @@ -561,16 +560,17 @@ Parser::OwningExprResult Parser::ParseCastExpression(bool isUnaryExpression, // expression, or statement expression. // // If the parsed tokens consist of a primary-expression, the cases below - // call ParsePostfixExpressionSuffix to handle the postfix expression - // suffixes. Cases that cannot be followed by postfix exprs should - // return without invoking ParsePostfixExpressionSuffix. + // break out of the switch; at the end we call ParsePostfixExpressionSuffix + // to handle the postfix expression suffixes. Cases that cannot be followed + // by postfix exprs should return without invoking + // ParsePostfixExpressionSuffix. switch (SavedKind) { case tok::l_paren: { // If this expression is limited to being a unary-expression, the parent can // not start a cast expression. ParenParseOption ParenExprType = - isUnaryExpression ? CompoundLiteral : CastExpr; - TypeTy *CastTy; + (isUnaryExpression && !getLang().CPlusPlus)? CompoundLiteral : CastExpr; + ParsedType CastTy; SourceLocation LParenLoc = Tok.getLocation(); SourceLocation RParenLoc; @@ -597,8 +597,7 @@ Parser::OwningExprResult Parser::ParseCastExpression(bool isUnaryExpression, return move(Res); } - // These can be followed by postfix-expr pieces. - return ParsePostfixExpressionSuffix(move(Res)); + break; } // primary-expression @@ -608,9 +607,7 @@ Parser::OwningExprResult Parser::ParseCastExpression(bool isUnaryExpression, Res = Actions.ActOnNumericConstant(Tok); ConsumeToken(); - - // These can be followed by postfix-expr pieces. - return ParsePostfixExpressionSuffix(move(Res)); + break; case tok::kw_true: case tok::kw_false: @@ -661,9 +658,12 @@ Parser::OwningExprResult Parser::ParseCastExpression(bool isUnaryExpression, Res = Actions.ActOnClassPropertyRefExpr(II, PropertyName, ILoc, PropertyLoc); - // These can be followed by postfix-expr pieces. - return ParsePostfixExpressionSuffix(move(Res)); + break; } + + // Make sure to pass down the right value for isAddressOfOperand. + if (isAddressOfOperand && isPostfixExpressionSuffixStart()) + isAddressOfOperand = false; // Function designators are allowed to be undeclared (C99 6.5.1p2), so we // need to know whether or not this identifier is a function designator or @@ -672,29 +672,23 @@ Parser::OwningExprResult Parser::ParseCastExpression(bool isUnaryExpression, CXXScopeSpec ScopeSpec; Name.setIdentifier(&II, ILoc); Res = Actions.ActOnIdExpression(getCurScope(), ScopeSpec, Name, - Tok.is(tok::l_paren), false); - - // These can be followed by postfix-expr pieces. - return ParsePostfixExpressionSuffix(move(Res)); + Tok.is(tok::l_paren), isAddressOfOperand); + break; } case tok::char_constant: // constant: character-constant Res = Actions.ActOnCharacterConstant(Tok); ConsumeToken(); - // These can be followed by postfix-expr pieces. - return ParsePostfixExpressionSuffix(move(Res)); + break; case tok::kw___func__: // primary-expression: __func__ [C99 6.4.2.2] case tok::kw___FUNCTION__: // primary-expression: __FUNCTION__ [GNU] case tok::kw___PRETTY_FUNCTION__: // primary-expression: __P..Y_F..N__ [GNU] Res = Actions.ActOnPredefinedExpr(Tok.getLocation(), SavedKind); ConsumeToken(); - // These can be followed by postfix-expr pieces. - return ParsePostfixExpressionSuffix(move(Res)); + break; case tok::string_literal: // primary-expression: string-literal case tok::wide_string_literal: Res = ParseStringLiteralExpression(); - if (Res.isInvalid()) return move(Res); - // This can be followed by postfix-expr pieces (e.g. "foo"[1]). - return ParsePostfixExpressionSuffix(move(Res)); + break; case tok::kw___builtin_va_arg: case tok::kw___builtin_offsetof: case tok::kw___builtin_choose_expr: @@ -703,12 +697,16 @@ Parser::OwningExprResult Parser::ParseCastExpression(bool isUnaryExpression, case tok::kw___null: return Actions.ActOnGNUNullExpr(ConsumeToken()); break; - case tok::plusplus: // unary-expression: '++' unary-expression - case tok::minusminus: { // unary-expression: '--' unary-expression + case tok::plusplus: // unary-expression: '++' unary-expression [C99] + case tok::minusminus: { // unary-expression: '--' unary-expression [C99] + // C++ [expr.unary] has: + // unary-expression: + // ++ cast-expression + // -- cast-expression SourceLocation SavedLoc = ConsumeToken(); - Res = ParseCastExpression(true); + Res = ParseCastExpression(!getLang().CPlusPlus); if (!Res.isInvalid()) - Res = Actions.ActOnUnaryOp(getCurScope(), SavedLoc, SavedKind, move(Res)); + Res = Actions.ActOnUnaryOp(getCurScope(), SavedLoc, SavedKind, Res.get()); return move(Res); } case tok::amp: { // unary-expression: '&' cast-expression @@ -716,7 +714,7 @@ Parser::OwningExprResult Parser::ParseCastExpression(bool isUnaryExpression, SourceLocation SavedLoc = ConsumeToken(); Res = ParseCastExpression(false, true); if (!Res.isInvalid()) - Res = Actions.ActOnUnaryOp(getCurScope(), SavedLoc, SavedKind, move(Res)); + Res = Actions.ActOnUnaryOp(getCurScope(), SavedLoc, SavedKind, Res.get()); return move(Res); } @@ -730,7 +728,7 @@ Parser::OwningExprResult Parser::ParseCastExpression(bool isUnaryExpression, SourceLocation SavedLoc = ConsumeToken(); Res = ParseCastExpression(false); if (!Res.isInvalid()) - Res = Actions.ActOnUnaryOp(getCurScope(), SavedLoc, SavedKind, move(Res)); + Res = Actions.ActOnUnaryOp(getCurScope(), SavedLoc, SavedKind, Res.get()); return move(Res); } @@ -740,7 +738,7 @@ Parser::OwningExprResult Parser::ParseCastExpression(bool isUnaryExpression, SourceLocation SavedLoc = ConsumeToken(); Res = ParseCastExpression(false); if (!Res.isInvalid()) - Res = Actions.ActOnUnaryOp(getCurScope(), SavedLoc, SavedKind, move(Res)); + Res = Actions.ActOnUnaryOp(getCurScope(), SavedLoc, SavedKind, Res.get()); return move(Res); } case tok::kw_sizeof: // unary-expression: 'sizeof' unary-expression @@ -766,16 +764,13 @@ Parser::OwningExprResult Parser::ParseCastExpression(bool isUnaryExpression, case tok::kw_reinterpret_cast: case tok::kw_static_cast: Res = ParseCXXCasts(); - // These can be followed by postfix-expr pieces. - return ParsePostfixExpressionSuffix(move(Res)); + break; case tok::kw_typeid: Res = ParseCXXTypeid(); - // This can be followed by postfix-expr pieces. - return ParsePostfixExpressionSuffix(move(Res)); + break; case tok::kw_this: Res = ParseCXXThis(); - // This can be followed by postfix-expr pieces. - return ParsePostfixExpressionSuffix(move(Res)); + break; case tok::kw_char: case tok::kw_wchar_t: @@ -814,8 +809,7 @@ Parser::OwningExprResult Parser::ParseCastExpression(bool isUnaryExpression, << DS.getSourceRange()); Res = ParseCXXTypeConstructExpression(DS); - // This can be followed by postfix-expr pieces. - return ParsePostfixExpressionSuffix(move(Res)); + break; } case tok::annot_cxxscope: { // [C++] id-expression: qualified-id @@ -836,7 +830,7 @@ Parser::OwningExprResult Parser::ParseCastExpression(bool isUnaryExpression, // type, translate it into a type and continue parsing as a // cast expression. CXXScopeSpec SS; - ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, false); + ParseOptionalCXXScopeSpecifier(SS, ParsedType(), false); AnnotateTemplateIdTokenAsType(&SS); return ParseCastExpression(isUnaryExpression, isAddressOfOperand, NotCastExpr, TypeOfCast); @@ -845,7 +839,7 @@ Parser::OwningExprResult Parser::ParseCastExpression(bool isUnaryExpression, // Parse as an id-expression. Res = ParseCXXIdExpression(isAddressOfOperand); - return ParsePostfixExpressionSuffix(move(Res)); + break; } case tok::annot_template_id: { // [C++] template-id @@ -865,7 +859,7 @@ Parser::OwningExprResult Parser::ParseCastExpression(bool isUnaryExpression, case tok::kw_operator: // [C++] id-expression: operator/conversion-function-id Res = ParseCXXIdExpression(isAddressOfOperand); - return ParsePostfixExpressionSuffix(move(Res)); + break; case tok::coloncolon: { // ::foo::bar -> global qualified name etc. If TryAnnotateTypeOrScopeToken @@ -906,6 +900,10 @@ Parser::OwningExprResult Parser::ParseCastExpression(bool isUnaryExpression, case tok::kw___has_trivial_copy: case tok::kw___has_trivial_assign: case tok::kw___has_trivial_destructor: + case tok::kw___has_nothrow_assign: + case tok::kw___has_nothrow_copy: + case tok::kw___has_nothrow_constructor: + case tok::kw___has_virtual_destructor: return ParseUnaryTypeTrait(); case tok::at: { @@ -915,7 +913,7 @@ Parser::OwningExprResult Parser::ParseCastExpression(bool isUnaryExpression, case tok::caret: return ParsePostfixExpressionSuffix(ParseBlockLiteralExpression()); case tok::code_completion: - Actions.CodeCompleteOrdinaryName(getCurScope(), Action::CCC_Expression); + Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Expression); ConsumeCodeCompletionToken(); return ParseCastExpression(isUnaryExpression, isAddressOfOperand, NotCastExpr, TypeOfCast); @@ -929,8 +927,9 @@ Parser::OwningExprResult Parser::ParseCastExpression(bool isUnaryExpression, return ExprError(); } - // unreachable. - abort(); + // These can be followed by postfix-expr pieces. + if (Res.isInvalid()) return move(Res); + return ParsePostfixExpressionSuffix(Res.get()); } /// ParsePostfixExpressionSuffix - Once the leading part of a postfix-expression @@ -951,8 +950,8 @@ Parser::OwningExprResult Parser::ParseCastExpression(bool isUnaryExpression, /// argument-expression /// argument-expression-list ',' assignment-expression /// -Parser::OwningExprResult -Parser::ParsePostfixExpressionSuffix(OwningExprResult LHS) { +ExprResult +Parser::ParsePostfixExpressionSuffix(ExprResult LHS) { // Now that the primary-expression piece of the postfix-expression has been // parsed, see if there are any postfix-expression pieces here. SourceLocation Loc; @@ -972,13 +971,13 @@ Parser::ParsePostfixExpressionSuffix(OwningExprResult LHS) { return move(LHS); Loc = ConsumeBracket(); - OwningExprResult Idx(ParseExpression()); + ExprResult Idx(ParseExpression()); SourceLocation RLoc = Tok.getLocation(); if (!LHS.isInvalid() && !Idx.isInvalid() && Tok.is(tok::r_square)) { - LHS = Actions.ActOnArraySubscriptExpr(getCurScope(), move(LHS), Loc, - move(Idx), RLoc); + LHS = Actions.ActOnArraySubscriptExpr(getCurScope(), LHS.take(), Loc, + Idx.take(), RLoc); } else LHS = ExprError(); @@ -1004,7 +1003,7 @@ Parser::ParsePostfixExpressionSuffix(OwningExprResult LHS) { } if (Tok.isNot(tok::r_paren)) { - if (ParseExpressionList(ArgExprs, CommaLocs, &Action::CodeCompleteCall, + if (ParseExpressionList(ArgExprs, CommaLocs, &Sema::CodeCompleteCall, LHS.get())) { SkipUntil(tok::r_paren); return ExprError(); @@ -1020,7 +1019,7 @@ Parser::ParsePostfixExpressionSuffix(OwningExprResult LHS) { if (!LHS.isInvalid()) { assert((ArgExprs.size() == 0 || ArgExprs.size()-1 == CommaLocs.size())&& "Unexpected number of commas!"); - LHS = Actions.ActOnCallExpr(getCurScope(), move(LHS), Loc, + LHS = Actions.ActOnCallExpr(getCurScope(), LHS.take(), Loc, move_arg(ArgExprs), CommaLocs.data(), Tok.getLocation()); } @@ -1036,10 +1035,10 @@ Parser::ParsePostfixExpressionSuffix(OwningExprResult LHS) { SourceLocation OpLoc = ConsumeToken(); // Eat the "." or "->" token. CXXScopeSpec SS; - Action::TypeTy *ObjectType = 0; + ParsedType ObjectType; bool MayBePseudoDestructor = false; if (getLang().CPlusPlus && !LHS.isInvalid()) { - LHS = Actions.ActOnStartCXXMemberReference(getCurScope(), move(LHS), + LHS = Actions.ActOnStartCXXMemberReference(getCurScope(), LHS.take(), OpLoc, OpKind, ObjectType, MayBePseudoDestructor); if (LHS.isInvalid()) @@ -1048,7 +1047,7 @@ Parser::ParsePostfixExpressionSuffix(OwningExprResult LHS) { ParseOptionalCXXScopeSpecifier(SS, ObjectType, false, &MayBePseudoDestructor); if (SS.isNotEmpty()) - ObjectType = 0; + ObjectType = ParsedType(); } if (Tok.is(tok::code_completion)) { @@ -1059,8 +1058,8 @@ Parser::ParsePostfixExpressionSuffix(OwningExprResult LHS) { ConsumeCodeCompletionToken(); } - if (MayBePseudoDestructor) { - LHS = ParseCXXPseudoDestructor(move(LHS), OpLoc, OpKind, SS, + if (MayBePseudoDestructor && !LHS.isInvalid()) { + LHS = ParseCXXPseudoDestructor(LHS.take(), OpLoc, OpKind, SS, ObjectType); break; } @@ -1080,7 +1079,7 @@ Parser::ParsePostfixExpressionSuffix(OwningExprResult LHS) { return ExprError(); if (!LHS.isInvalid()) - LHS = Actions.ActOnMemberAccessExpr(getCurScope(), move(LHS), OpLoc, + LHS = Actions.ActOnMemberAccessExpr(getCurScope(), LHS.take(), OpLoc, OpKind, SS, Name, ObjCImpDecl, Tok.is(tok::l_paren)); break; @@ -1089,7 +1088,7 @@ Parser::ParsePostfixExpressionSuffix(OwningExprResult LHS) { case tok::minusminus: // postfix-expression: postfix-expression '--' if (!LHS.isInvalid()) { LHS = Actions.ActOnPostfixUnaryOp(getCurScope(), Tok.getLocation(), - Tok.getKind(), move(LHS)); + Tok.getKind(), LHS.take()); } ConsumeToken(); break; @@ -1114,17 +1113,17 @@ Parser::ParsePostfixExpressionSuffix(OwningExprResult LHS) { /// typeof ( type-name ) /// [GNU/C++] typeof unary-expression /// -Parser::OwningExprResult +ExprResult Parser::ParseExprAfterTypeofSizeofAlignof(const Token &OpTok, bool &isCastExpr, - TypeTy *&CastTy, + ParsedType &CastTy, SourceRange &CastRange) { assert((OpTok.is(tok::kw_typeof) || OpTok.is(tok::kw_sizeof) || OpTok.is(tok::kw___alignof) || OpTok.is(tok::kw_alignof)) && "Not a typeof/sizeof/alignof expression!"); - OwningExprResult Operand(Actions); + ExprResult Operand; // If the operand doesn't start with an '(', it must be an expression. if (Tok.isNot(tok::l_paren)) { @@ -1141,7 +1140,7 @@ Parser::ParseExprAfterTypeofSizeofAlignof(const Token &OpTok, // The GNU typeof and alignof extensions also behave as unevaluated // operands. EnterExpressionEvaluationContext Unevaluated(Actions, - Action::Unevaluated); + Sema::Unevaluated); Operand = ParseCastExpression(true/*isUnaryExpression*/); } else { // If it starts with a '(', we know that it is either a parenthesized @@ -1158,10 +1157,9 @@ Parser::ParseExprAfterTypeofSizeofAlignof(const Token &OpTok, // The GNU typeof and alignof extensions also behave as unevaluated // operands. EnterExpressionEvaluationContext Unevaluated(Actions, - Action::Unevaluated); + Sema::Unevaluated); Operand = ParseParenExpression(ExprType, true/*stopIfCastExpr*/, - 0/*TypeOfCast*/, - CastTy, RParenLoc); + ParsedType(), CastTy, RParenLoc); CastRange = SourceRange(LParenLoc, RParenLoc); // If ParseParenExpression parsed a '(typename)' sequence only, then this is @@ -1171,10 +1169,14 @@ Parser::ParseExprAfterTypeofSizeofAlignof(const Token &OpTok, return ExprEmpty(); } - // If this is a parenthesized expression, it is the start of a - // unary-expression, but doesn't include any postfix pieces. Parse these - // now if present. - Operand = ParsePostfixExpressionSuffix(move(Operand)); + if (getLang().CPlusPlus || OpTok.isNot(tok::kw_typeof)) { + // GNU typeof in C requires the expression to be parenthesized. Not so for + // sizeof/alignof or in C++. Therefore, the parenthesized expression is + // the start of a unary-expression, but doesn't include any postfix + // pieces. Parse these now if present. + if (!Operand.isInvalid()) + Operand = ParsePostfixExpressionSuffix(Operand.get()); + } } // If we get here, the operand to the typeof/sizeof/alignof was an expresion. @@ -1190,7 +1192,7 @@ Parser::ParseExprAfterTypeofSizeofAlignof(const Token &OpTok, /// [GNU] '__alignof' unary-expression /// [GNU] '__alignof' '(' type-name ')' /// [C++0x] 'alignof' '(' type-id ')' -Parser::OwningExprResult Parser::ParseSizeofAlignofExpression() { +ExprResult Parser::ParseSizeofAlignofExpression() { assert((Tok.is(tok::kw_sizeof) || Tok.is(tok::kw___alignof) || Tok.is(tok::kw_alignof)) && "Not a sizeof/alignof expression!"); @@ -1198,9 +1200,9 @@ Parser::OwningExprResult Parser::ParseSizeofAlignofExpression() { ConsumeToken(); bool isCastExpr; - TypeTy *CastTy; + ParsedType CastTy; SourceRange CastRange; - OwningExprResult Operand = ParseExprAfterTypeofSizeofAlignof(OpTok, + ExprResult Operand = ParseExprAfterTypeofSizeofAlignof(OpTok, isCastExpr, CastTy, CastRange); @@ -1208,7 +1210,8 @@ Parser::OwningExprResult Parser::ParseSizeofAlignofExpression() { if (isCastExpr) return Actions.ActOnSizeOfAlignOfExpr(OpTok.getLocation(), OpTok.is(tok::kw_sizeof), - /*isType=*/true, CastTy, + /*isType=*/true, + CastTy.getAsOpaquePtr(), CastRange); // If we get here, the operand to the sizeof/alignof was an expresion. @@ -1234,8 +1237,8 @@ Parser::OwningExprResult Parser::ParseSizeofAlignofExpression() { /// [GNU] offsetof-member-designator '.' identifier /// [GNU] offsetof-member-designator '[' expression ']' /// -Parser::OwningExprResult Parser::ParseBuiltinPrimaryExpression() { - OwningExprResult Res(Actions); +ExprResult Parser::ParseBuiltinPrimaryExpression() { + ExprResult Res; const IdentifierInfo *BuiltinII = Tok.getIdentifierInfo(); tok::TokenKind T = Tok.getKind(); @@ -1252,7 +1255,7 @@ Parser::OwningExprResult Parser::ParseBuiltinPrimaryExpression() { switch (T) { default: assert(0 && "Not a builtin primary expression!"); case tok::kw___builtin_va_arg: { - OwningExprResult Expr(ParseAssignmentExpression()); + ExprResult Expr(ParseAssignmentExpression()); if (Expr.isInvalid()) { SkipUntil(tok::r_paren); return ExprError(); @@ -1270,7 +1273,7 @@ Parser::OwningExprResult Parser::ParseBuiltinPrimaryExpression() { if (Ty.isInvalid()) Res = ExprError(); else - Res = Actions.ActOnVAArg(StartLoc, move(Expr), Ty.get(), ConsumeParen()); + Res = Actions.ActOnVAArg(StartLoc, Expr.take(), Ty.get(), ConsumeParen()); break; } case tok::kw___builtin_offsetof: { @@ -1292,9 +1295,9 @@ Parser::OwningExprResult Parser::ParseBuiltinPrimaryExpression() { } // Keep track of the various subcomponents we see. - llvm::SmallVector<Action::OffsetOfComponent, 4> Comps; + llvm::SmallVector<Sema::OffsetOfComponent, 4> Comps; - Comps.push_back(Action::OffsetOfComponent()); + Comps.push_back(Sema::OffsetOfComponent()); Comps.back().isBrackets = false; Comps.back().U.IdentInfo = Tok.getIdentifierInfo(); Comps.back().LocStart = Comps.back().LocEnd = ConsumeToken(); @@ -1303,7 +1306,7 @@ Parser::OwningExprResult Parser::ParseBuiltinPrimaryExpression() { while (1) { if (Tok.is(tok::period)) { // offsetof-member-designator: offsetof-member-designator '.' identifier - Comps.push_back(Action::OffsetOfComponent()); + Comps.push_back(Sema::OffsetOfComponent()); Comps.back().isBrackets = false; Comps.back().LocStart = ConsumeToken(); @@ -1317,7 +1320,7 @@ Parser::OwningExprResult Parser::ParseBuiltinPrimaryExpression() { } else if (Tok.is(tok::l_square)) { // offsetof-member-designator: offsetof-member-design '[' expression ']' - Comps.push_back(Action::OffsetOfComponent()); + Comps.push_back(Sema::OffsetOfComponent()); Comps.back().isBrackets = true; Comps.back().LocStart = ConsumeBracket(); Res = ParseExpression(); @@ -1346,7 +1349,7 @@ Parser::OwningExprResult Parser::ParseBuiltinPrimaryExpression() { break; } case tok::kw___builtin_choose_expr: { - OwningExprResult Cond(ParseAssignmentExpression()); + ExprResult Cond(ParseAssignmentExpression()); if (Cond.isInvalid()) { SkipUntil(tok::r_paren); return move(Cond); @@ -1354,7 +1357,7 @@ Parser::OwningExprResult Parser::ParseBuiltinPrimaryExpression() { if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "",tok::r_paren)) return ExprError(); - OwningExprResult Expr1(ParseAssignmentExpression()); + ExprResult Expr1(ParseAssignmentExpression()); if (Expr1.isInvalid()) { SkipUntil(tok::r_paren); return move(Expr1); @@ -1362,7 +1365,7 @@ Parser::OwningExprResult Parser::ParseBuiltinPrimaryExpression() { if (ExpectAndConsume(tok::comma, diag::err_expected_comma, "",tok::r_paren)) return ExprError(); - OwningExprResult Expr2(ParseAssignmentExpression()); + ExprResult Expr2(ParseAssignmentExpression()); if (Expr2.isInvalid()) { SkipUntil(tok::r_paren); return move(Expr2); @@ -1371,8 +1374,8 @@ Parser::OwningExprResult Parser::ParseBuiltinPrimaryExpression() { Diag(Tok, diag::err_expected_rparen); return ExprError(); } - Res = Actions.ActOnChooseExpr(StartLoc, move(Cond), move(Expr1), - move(Expr2), ConsumeParen()); + Res = Actions.ActOnChooseExpr(StartLoc, Cond.take(), Expr1.take(), + Expr2.take(), ConsumeParen()); break; } case tok::kw___builtin_types_compatible_p: @@ -1396,9 +1399,12 @@ Parser::OwningExprResult Parser::ParseBuiltinPrimaryExpression() { break; } + if (Res.isInvalid()) + return ExprError(); + // These can be followed by postfix-expr pieces because they are // primary-expressions. - return ParsePostfixExpressionSuffix(move(Res)); + return ParsePostfixExpressionSuffix(Res.take()); } /// ParseParenExpression - This parses the unit that starts with a '(' token, @@ -1415,25 +1421,25 @@ Parser::OwningExprResult Parser::ParseBuiltinPrimaryExpression() { /// cast-expression: [C99 6.5.4] /// '(' type-name ')' cast-expression /// -Parser::OwningExprResult +ExprResult Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr, - TypeTy *TypeOfCast, TypeTy *&CastTy, + ParsedType TypeOfCast, ParsedType &CastTy, SourceLocation &RParenLoc) { assert(Tok.is(tok::l_paren) && "Not a paren expr!"); GreaterThanIsOperatorScope G(GreaterThanIsOperator, true); SourceLocation OpenLoc = ConsumeParen(); - OwningExprResult Result(Actions, true); + ExprResult Result(true); bool isAmbiguousTypeId; - CastTy = 0; + CastTy = ParsedType(); if (ExprType >= CompoundStmt && Tok.is(tok::l_brace)) { Diag(Tok, diag::ext_gnu_statement_expr); - OwningStmtResult Stmt(ParseCompoundStatement(0, true)); + StmtResult Stmt(ParseCompoundStatement(0, true)); ExprType = CompoundStmt; // If the substmt parsed correctly, build the AST node. if (!Stmt.isInvalid() && Tok.is(tok::r_paren)) - Result = Actions.ActOnStmtExpr(OpenLoc, move(Stmt), Tok.getLocation()); + Result = Actions.ActOnStmtExpr(OpenLoc, Stmt.take(), Tok.getLocation()); } else if (ExprType >= CompoundLiteral && isTypeIdInParens(isAmbiguousTypeId)) { @@ -1473,7 +1479,7 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr, // Note that this doesn't parse the subsequent cast-expression, it just // returns the parsed type to the callee. if (stopIfCastExpr) - return OwningExprResult(Actions); + return ExprResult(); // Reject the cast of super idiom in ObjC. if (Tok.is(tok::identifier) && getLang().ObjC1 && @@ -1490,7 +1496,7 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr, Result = ParseCastExpression(false, false, CastTy); if (!Result.isInvalid()) Result = Actions.ActOnCastExpr(getCurScope(), OpenLoc, CastTy, RParenLoc, - move(Result)); + Result.take()); return move(Result); } @@ -1510,7 +1516,7 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr, Result = ParseExpression(); ExprType = SimpleExpr; if (!Result.isInvalid() && Tok.is(tok::r_paren)) - Result = Actions.ActOnParenExpr(OpenLoc, Tok.getLocation(), move(Result)); + Result = Actions.ActOnParenExpr(OpenLoc, Tok.getLocation(), Result.take()); } // Match the ')'. @@ -1534,16 +1540,16 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr, /// '(' type-name ')' '{' initializer-list '}' /// '(' type-name ')' '{' initializer-list ',' '}' /// -Parser::OwningExprResult -Parser::ParseCompoundLiteralExpression(TypeTy *Ty, +ExprResult +Parser::ParseCompoundLiteralExpression(ParsedType Ty, SourceLocation LParenLoc, SourceLocation RParenLoc) { assert(Tok.is(tok::l_brace) && "Not a compound literal!"); if (!getLang().C99) // Compound literals don't exist in C90. Diag(LParenLoc, diag::ext_c99_compound_literal); - OwningExprResult Result = ParseInitializer(); + ExprResult Result = ParseInitializer(); if (!Result.isInvalid() && Ty) - return Actions.ActOnCompoundLiteral(LParenLoc, Ty, RParenLoc, move(Result)); + return Actions.ActOnCompoundLiteral(LParenLoc, Ty, RParenLoc, Result.take()); return move(Result); } @@ -1553,7 +1559,7 @@ Parser::ParseCompoundLiteralExpression(TypeTy *Ty, /// /// primary-expression: [C99 6.5.1] /// string-literal -Parser::OwningExprResult Parser::ParseStringLiteralExpression() { +ExprResult Parser::ParseStringLiteralExpression() { assert(isTokenStringLiteral() && "Not a string literal!"); // String concat. Note that keywords like __func__ and __FUNCTION__ are not @@ -1579,12 +1585,13 @@ Parser::OwningExprResult Parser::ParseStringLiteralExpression() { /// [C++] assignment-expression /// [C++] expression-list , assignment-expression /// -bool Parser::ParseExpressionList(ExprListTy &Exprs, CommaLocsTy &CommaLocs, - void (Action::*Completer)(Scope *S, - void *Data, - ExprTy **Args, +bool Parser::ParseExpressionList(llvm::SmallVectorImpl<Expr*> &Exprs, + llvm::SmallVectorImpl<SourceLocation> &CommaLocs, + void (Sema::*Completer)(Scope *S, + Expr *Data, + Expr **Args, unsigned NumArgs), - void *Data) { + Expr *Data) { while (1) { if (Tok.is(tok::code_completion)) { if (Completer) @@ -1592,7 +1599,7 @@ bool Parser::ParseExpressionList(ExprListTy &Exprs, CommaLocsTy &CommaLocs, ConsumeCodeCompletionToken(); } - OwningExprResult Expr(ParseAssignmentExpression()); + ExprResult Expr(ParseAssignmentExpression()); if (Expr.isInvalid()) return true; @@ -1642,7 +1649,7 @@ void Parser::ParseBlockId() { /// [clang] block-args: /// [clang] '(' parameter-list ')' /// -Parser::OwningExprResult Parser::ParseBlockLiteralExpression() { +ExprResult Parser::ParseBlockLiteralExpression() { assert(Tok.is(tok::caret) && "block literal starts with ^"); SourceLocation CaretLoc = ConsumeToken(); @@ -1717,7 +1724,7 @@ Parser::OwningExprResult Parser::ParseBlockLiteralExpression() { } - OwningExprResult Result(Actions, true); + ExprResult Result(true); if (!Tok.is(tok::l_brace)) { // Saw something like: ^expr Diag(Tok, diag::err_expected_expression); @@ -1725,9 +1732,9 @@ Parser::OwningExprResult Parser::ParseBlockLiteralExpression() { return ExprError(); } - OwningStmtResult Stmt(ParseCompoundStatementBody()); + StmtResult Stmt(ParseCompoundStatementBody()); if (!Stmt.isInvalid()) - Result = Actions.ActOnBlockStmtExpr(CaretLoc, move(Stmt), getCurScope()); + Result = Actions.ActOnBlockStmtExpr(CaretLoc, Stmt.take(), getCurScope()); else Actions.ActOnBlockError(CaretLoc, getCurScope()); return move(Result); diff --git a/contrib/llvm/tools/clang/lib/Parse/ParseExprCXX.cpp b/contrib/llvm/tools/clang/lib/Parse/ParseExprCXX.cpp index 579d3bd..5041a21 100644 --- a/contrib/llvm/tools/clang/lib/Parse/ParseExprCXX.cpp +++ b/contrib/llvm/tools/clang/lib/Parse/ParseExprCXX.cpp @@ -13,8 +13,8 @@ #include "clang/Parse/ParseDiagnostic.h" #include "clang/Parse/Parser.h" -#include "clang/Parse/DeclSpec.h" -#include "clang/Parse/Template.h" +#include "clang/Sema/DeclSpec.h" +#include "clang/Sema/ParsedTemplate.h" #include "llvm/Support/ErrorHandling.h" using namespace clang; @@ -57,14 +57,14 @@ using namespace clang; /// /// \returns true if there was an error parsing a scope specifier bool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS, - Action::TypeTy *ObjectType, + ParsedType ObjectType, bool EnteringContext, bool *MayBePseudoDestructor) { assert(getLang().CPlusPlus && "Call sites of this function should be guarded by checking for C++"); if (Tok.is(tok::annot_cxxscope)) { - SS.setScopeRep(Tok.getAnnotationValue()); + SS.setScopeRep(static_cast<NestedNameSpecifier*>(Tok.getAnnotationValue())); SS.setRange(Tok.getAnnotationRange()); ConsumeToken(); return false; @@ -104,7 +104,7 @@ bool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS, // // To implement this, we clear out the object type as soon as we've // seen a leading '::' or part of a nested-name-specifier. - ObjectType = 0; + ObjectType = ParsedType(); if (Tok.is(tok::code_completion)) { // Code completion for a nested-name-specifier, where the code @@ -212,13 +212,13 @@ bool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS, HasScopeSpecifier = true; } - if (TypeToken.getAnnotationValue()) - SS.setScopeRep( - Actions.ActOnCXXNestedNameSpecifier(getCurScope(), SS, - TypeToken.getAnnotationValue(), + if (ParsedType T = getTypeAnnotation(TypeToken)) { + CXXScopeTy *Scope = + Actions.ActOnCXXNestedNameSpecifier(getCurScope(), SS, T, TypeToken.getAnnotationRange(), - CCLoc)); - else + CCLoc); + SS.setScopeRep(Scope); + } else SS.setScopeRep(0); SS.setEndLoc(CCLoc); continue; @@ -294,6 +294,7 @@ bool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS, TemplateName.setIdentifier(&II, Tok.getLocation()); bool MemberOfUnknownSpecialization; if (TemplateNameKind TNK = Actions.isTemplateName(getCurScope(), SS, + /*hasTemplateKeyword=*/false, TemplateName, ObjectType, EnteringContext, @@ -396,40 +397,27 @@ bool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS, /// the only place where a qualified-id naming a non-static class member may /// appear. /// -Parser::OwningExprResult Parser::ParseCXXIdExpression(bool isAddressOfOperand) { +ExprResult Parser::ParseCXXIdExpression(bool isAddressOfOperand) { // qualified-id: // '::'[opt] nested-name-specifier 'template'[opt] unqualified-id // '::' unqualified-id // CXXScopeSpec SS; - ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, false); + ParseOptionalCXXScopeSpecifier(SS, ParsedType(), false); UnqualifiedId Name; if (ParseUnqualifiedId(SS, /*EnteringContext=*/false, /*AllowDestructorName=*/false, /*AllowConstructorName=*/false, - /*ObjectType=*/0, + /*ObjectType=*/ ParsedType(), Name)) return ExprError(); // This is only the direct operand of an & operator if it is not // followed by a postfix-expression suffix. - if (isAddressOfOperand) { - switch (Tok.getKind()) { - case tok::l_square: - case tok::l_paren: - case tok::arrow: - case tok::period: - case tok::plusplus: - case tok::minusminus: - isAddressOfOperand = false; - break; - - default: - break; - } - } + if (isAddressOfOperand && isPostfixExpressionSuffixStart()) + isAddressOfOperand = false; return Actions.ActOnIdExpression(getCurScope(), SS, Name, Tok.is(tok::l_paren), isAddressOfOperand); @@ -445,7 +433,7 @@ Parser::OwningExprResult Parser::ParseCXXIdExpression(bool isAddressOfOperand) { /// 'reinterpret_cast' '<' type-name '>' '(' expression ')' /// 'const_cast' '<' type-name '>' '(' expression ')' /// -Parser::OwningExprResult Parser::ParseCXXCasts() { +ExprResult Parser::ParseCXXCasts() { tok::TokenKind Kind = Tok.getKind(); const char *CastName = 0; // For error messages @@ -474,7 +462,7 @@ Parser::OwningExprResult Parser::ParseCXXCasts() { if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after, CastName)) return ExprError(); - OwningExprResult Result = ParseExpression(); + ExprResult Result = ParseExpression(); // Match the ')'. RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc); @@ -483,7 +471,7 @@ Parser::OwningExprResult Parser::ParseCXXCasts() { Result = Actions.ActOnCXXNamedCast(OpLoc, Kind, LAngleBracketLoc, CastTy.get(), RAngleBracketLoc, - LParenLoc, move(Result), RParenLoc); + LParenLoc, Result.take(), RParenLoc); return move(Result); } @@ -494,7 +482,7 @@ Parser::OwningExprResult Parser::ParseCXXCasts() { /// 'typeid' '(' expression ')' /// 'typeid' '(' type-id ')' /// -Parser::OwningExprResult Parser::ParseCXXTypeid() { +ExprResult Parser::ParseCXXTypeid() { assert(Tok.is(tok::kw_typeid) && "Not 'typeid'!"); SourceLocation OpLoc = ConsumeToken(); @@ -506,7 +494,7 @@ Parser::OwningExprResult Parser::ParseCXXTypeid() { "typeid")) return ExprError(); - OwningExprResult Result(Actions); + ExprResult Result; if (isTypeIdInParens()) { TypeResult Ty = ParseTypeName(); @@ -518,7 +506,7 @@ Parser::OwningExprResult Parser::ParseCXXTypeid() { return ExprError(); Result = Actions.ActOnCXXTypeid(OpLoc, LParenLoc, /*isType=*/true, - Ty.get(), RParenLoc); + Ty.get().getAsOpaquePtr(), RParenLoc); } else { // C++0x [expr.typeid]p3: // When typeid is applied to an expression other than an lvalue of a @@ -529,7 +517,7 @@ Parser::OwningExprResult Parser::ParseCXXTypeid() { // polymorphic class type until after we've parsed the expression, so // we the expression is potentially potentially evaluated. EnterExpressionEvaluationContext Unevaluated(Actions, - Action::PotentiallyPotentiallyEvaluated); + Sema::PotentiallyPotentiallyEvaluated); Result = ParseExpression(); // Match the ')'. @@ -560,11 +548,11 @@ Parser::OwningExprResult Parser::ParseCXXTypeid() { /// ~type-name /// ::[opt] nested-name-specifier[opt] ~type-name /// -Parser::OwningExprResult +ExprResult Parser::ParseCXXPseudoDestructor(ExprArg Base, SourceLocation OpLoc, tok::TokenKind OpKind, CXXScopeSpec &SS, - Action::TypeTy *ObjectType) { + ParsedType ObjectType) { // We're parsing either a pseudo-destructor-name or a dependent // member access that has the same form as a // pseudo-destructor-name. We parse both in the same way and let @@ -612,7 +600,8 @@ Parser::ParseCXXPseudoDestructor(ExprArg Base, SourceLocation OpLoc, /*TemplateKWLoc*/SourceLocation())) return ExprError(); - return Actions.ActOnPseudoDestructorExpr(getCurScope(), move(Base), OpLoc, OpKind, + return Actions.ActOnPseudoDestructorExpr(getCurScope(), Base, + OpLoc, OpKind, SS, FirstTypeName, CCLoc, TildeLoc, SecondTypeName, Tok.is(tok::l_paren)); @@ -623,7 +612,7 @@ Parser::ParseCXXPseudoDestructor(ExprArg Base, SourceLocation OpLoc, /// boolean-literal: [C++ 2.13.5] /// 'true' /// 'false' -Parser::OwningExprResult Parser::ParseCXXBoolLiteral() { +ExprResult Parser::ParseCXXBoolLiteral() { tok::TokenKind Kind = Tok.getKind(); return Actions.ActOnCXXBoolLiteral(ConsumeToken(), Kind); } @@ -632,7 +621,7 @@ Parser::OwningExprResult Parser::ParseCXXBoolLiteral() { /// /// throw-expression: [C++ 15] /// 'throw' assignment-expression[opt] -Parser::OwningExprResult Parser::ParseThrowExpression() { +ExprResult Parser::ParseThrowExpression() { assert(Tok.is(tok::kw_throw) && "Not throw!"); SourceLocation ThrowLoc = ConsumeToken(); // Eat the throw token. @@ -646,12 +635,12 @@ Parser::OwningExprResult Parser::ParseThrowExpression() { case tok::r_brace: case tok::colon: case tok::comma: - return Actions.ActOnCXXThrow(ThrowLoc, ExprArg(Actions)); + return Actions.ActOnCXXThrow(ThrowLoc, 0); default: - OwningExprResult Expr(ParseAssignmentExpression()); + ExprResult Expr(ParseAssignmentExpression()); if (Expr.isInvalid()) return move(Expr); - return Actions.ActOnCXXThrow(ThrowLoc, move(Expr)); + return Actions.ActOnCXXThrow(ThrowLoc, Expr.take()); } } @@ -660,7 +649,7 @@ Parser::OwningExprResult Parser::ParseThrowExpression() { /// C++ 9.3.2: In the body of a non-static member function, the keyword this is /// a non-lvalue expression whose value is the address of the object for which /// the function is called. -Parser::OwningExprResult Parser::ParseCXXThis() { +ExprResult Parser::ParseCXXThis() { assert(Tok.is(tok::kw_this) && "Not 'this'!"); SourceLocation ThisLoc = ConsumeToken(); return Actions.ActOnCXXThis(ThisLoc); @@ -675,10 +664,10 @@ Parser::OwningExprResult Parser::ParseCXXThis() { /// simple-type-specifier '(' expression-list[opt] ')' [C++ 5.2.3] /// typename-specifier '(' expression-list[opt] ')' [TODO] /// -Parser::OwningExprResult +ExprResult Parser::ParseCXXTypeConstructExpression(const DeclSpec &DS) { Declarator DeclaratorInfo(DS, Declarator::TypeNameContext); - TypeTy *TypeRep = Actions.ActOnTypeName(getCurScope(), DeclaratorInfo).get(); + ParsedType TypeRep = Actions.ActOnTypeName(getCurScope(), DeclaratorInfo).get(); assert(Tok.is(tok::l_paren) && "Expected '('!"); SourceLocation LParenLoc = ConsumeParen(); @@ -728,27 +717,27 @@ Parser::ParseCXXTypeConstructExpression(const DeclSpec &DS) { /// converted to a boolean value. /// /// \returns true if there was a parsing, false otherwise. -bool Parser::ParseCXXCondition(OwningExprResult &ExprResult, - DeclPtrTy &DeclResult, +bool Parser::ParseCXXCondition(ExprResult &ExprOut, + Decl *&DeclOut, SourceLocation Loc, bool ConvertToBoolean) { if (Tok.is(tok::code_completion)) { - Actions.CodeCompleteOrdinaryName(getCurScope(), Action::CCC_Condition); + Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Condition); ConsumeCodeCompletionToken(); } if (!isCXXConditionDeclaration()) { // Parse the expression. - ExprResult = ParseExpression(); // expression - DeclResult = DeclPtrTy(); - if (ExprResult.isInvalid()) + ExprOut = ParseExpression(); // expression + DeclOut = 0; + if (ExprOut.isInvalid()) return true; // If required, convert to a boolean value. if (ConvertToBoolean) - ExprResult - = Actions.ActOnBooleanCondition(getCurScope(), Loc, move(ExprResult)); - return ExprResult.isInvalid(); + ExprOut + = Actions.ActOnBooleanCondition(getCurScope(), Loc, ExprOut.get()); + return ExprOut.isInvalid(); } // type-specifier-seq @@ -762,7 +751,7 @@ bool Parser::ParseCXXCondition(OwningExprResult &ExprResult, // simple-asm-expr[opt] if (Tok.is(tok::kw_asm)) { SourceLocation Loc; - OwningExprResult AsmLabel(ParseSimpleAsm(&Loc)); + ExprResult AsmLabel(ParseSimpleAsm(&Loc)); if (AsmLabel.isInvalid()) { SkipUntil(tok::semi); return true; @@ -779,17 +768,17 @@ bool Parser::ParseCXXCondition(OwningExprResult &ExprResult, } // Type-check the declaration itself. - Action::DeclResult Dcl = Actions.ActOnCXXConditionDeclaration(getCurScope(), + DeclResult Dcl = Actions.ActOnCXXConditionDeclaration(getCurScope(), DeclaratorInfo); - DeclResult = Dcl.get(); - ExprResult = ExprError(); + DeclOut = Dcl.get(); + ExprOut = ExprError(); // '=' assignment-expression if (Tok.is(tok::equal)) { SourceLocation EqualLoc = ConsumeToken(); - OwningExprResult AssignExpr(ParseAssignmentExpression()); + ExprResult AssignExpr(ParseAssignmentExpression()); if (!AssignExpr.isInvalid()) - Actions.AddInitializerToDecl(DeclResult, move(AssignExpr)); + Actions.AddInitializerToDecl(DeclOut, AssignExpr.take()); } else { // FIXME: C++0x allows a braced-init-list Diag(Tok, diag::err_expected_equal_after_declarator); @@ -874,7 +863,7 @@ void Parser::ParseCXXSimpleTypeSpecifier(DeclSpec &DS) { // type-name case tok::annot_typename: { DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec, DiagID, - Tok.getAnnotationValue()); + getTypeAnnotation(Tok)); break; } @@ -1002,7 +991,7 @@ bool Parser::ParseUnqualifiedIdTemplateId(CXXScopeSpec &SS, IdentifierInfo *Name, SourceLocation NameLoc, bool EnteringContext, - TypeTy *ObjectType, + ParsedType ObjectType, UnqualifiedId &Id, bool AssumeTemplateId, SourceLocation TemplateKWLoc) { @@ -1023,8 +1012,9 @@ bool Parser::ParseUnqualifiedIdTemplateId(CXXScopeSpec &SS, return true; } else { bool MemberOfUnknownSpecialization; - TNK = Actions.isTemplateName(getCurScope(), SS, Id, ObjectType, - EnteringContext, Template, + TNK = Actions.isTemplateName(getCurScope(), SS, + TemplateKWLoc.isValid(), Id, + ObjectType, EnteringContext, Template, MemberOfUnknownSpecialization); if (TNK == TNK_Non_template && MemberOfUnknownSpecialization && @@ -1059,7 +1049,8 @@ bool Parser::ParseUnqualifiedIdTemplateId(CXXScopeSpec &SS, UnqualifiedId TemplateName; bool MemberOfUnknownSpecialization; TemplateName.setIdentifier(Name, NameLoc); - TNK = Actions.isTemplateName(getCurScope(), SS, TemplateName, ObjectType, + TNK = Actions.isTemplateName(getCurScope(), SS, TemplateKWLoc.isValid(), + TemplateName, ObjectType, EnteringContext, Template, MemberOfUnknownSpecialization); break; @@ -1076,11 +1067,12 @@ bool Parser::ParseUnqualifiedIdTemplateId(CXXScopeSpec &SS, if (TNK == TNK_Non_template) return true; } else { - TNK = Actions.isTemplateName(getCurScope(), SS, TemplateName, ObjectType, + TNK = Actions.isTemplateName(getCurScope(), SS, TemplateKWLoc.isValid(), + TemplateName, ObjectType, EnteringContext, Template, MemberOfUnknownSpecialization); - if (TNK == TNK_Non_template && Id.DestructorName == 0) { + if (TNK == TNK_Non_template && !Id.DestructorName.get()) { Diag(NameLoc, diag::err_destructor_template_id) << Name << SS.getRange(); return true; @@ -1124,7 +1116,7 @@ bool Parser::ParseUnqualifiedIdTemplateId(CXXScopeSpec &SS, TemplateId->TemplateNameLoc = Id.StartLocation; } - TemplateId->Template = Template.getAs<void*>(); + TemplateId->Template = Template; TemplateId->Kind = TNK; TemplateId->LAngleLoc = LAngleLoc; TemplateId->RAngleLoc = RAngleLoc; @@ -1142,7 +1134,7 @@ bool Parser::ParseUnqualifiedIdTemplateId(CXXScopeSpec &SS, TemplateArgs.size()); // Constructor and destructor names. - Action::TypeResult Type + TypeResult Type = Actions.ActOnTemplateIdType(Template, NameLoc, LAngleLoc, TemplateArgsPtr, RAngleLoc); @@ -1198,7 +1190,7 @@ bool Parser::ParseUnqualifiedIdTemplateId(CXXScopeSpec &SS, /// /// \returns true if parsing fails, false otherwise. bool Parser::ParseUnqualifiedIdOperator(CXXScopeSpec &SS, bool EnteringContext, - TypeTy *ObjectType, + ParsedType ObjectType, UnqualifiedId &Result) { assert(Tok.is(tok::kw_operator) && "Expected 'operator' keyword"); @@ -1334,7 +1326,7 @@ bool Parser::ParseUnqualifiedIdOperator(CXXScopeSpec &SS, bool EnteringContext, ParseDeclaratorInternal(D, /*DirectDeclParser=*/0); // Finish up the type. - Action::TypeResult Ty = Actions.ActOnTypeName(getCurScope(), D); + TypeResult Ty = Actions.ActOnTypeName(getCurScope(), D); if (Ty.isInvalid()) return true; @@ -1377,7 +1369,7 @@ bool Parser::ParseUnqualifiedIdOperator(CXXScopeSpec &SS, bool EnteringContext, bool Parser::ParseUnqualifiedId(CXXScopeSpec &SS, bool EnteringContext, bool AllowDestructorName, bool AllowConstructorName, - TypeTy *ObjectType, + ParsedType ObjectType, UnqualifiedId &Result) { // Handle 'A::template B'. This is for template-ids which have not @@ -1511,17 +1503,17 @@ bool Parser::ParseUnqualifiedId(CXXScopeSpec &SS, bool EnteringContext, SourceLocation ClassNameLoc = ConsumeToken(); if (TemplateSpecified || Tok.is(tok::less)) { - Result.setDestructorName(TildeLoc, 0, ClassNameLoc); + Result.setDestructorName(TildeLoc, ParsedType(), ClassNameLoc); return ParseUnqualifiedIdTemplateId(SS, ClassName, ClassNameLoc, EnteringContext, ObjectType, Result, TemplateSpecified, TemplateKWLoc); } // Note that this is a destructor name. - Action::TypeTy *Ty = Actions.getDestructorName(TildeLoc, *ClassName, - ClassNameLoc, getCurScope(), - SS, ObjectType, - EnteringContext); + ParsedType Ty = Actions.getDestructorName(TildeLoc, *ClassName, + ClassNameLoc, getCurScope(), + SS, ObjectType, + EnteringContext); if (!Ty) return true; @@ -1561,7 +1553,7 @@ bool Parser::ParseUnqualifiedId(CXXScopeSpec &SS, bool EnteringContext, /// '(' expression-list[opt] ')' /// [C++0x] braced-init-list [TODO] /// -Parser::OwningExprResult +ExprResult Parser::ParseCXXNewExpression(bool UseGlobal, SourceLocation Start) { assert(Tok.is(tok::kw_new) && "expected 'new' token"); ConsumeToken(); // Consume 'new' @@ -1665,7 +1657,7 @@ void Parser::ParseDirectNewDeclarator(Declarator &D) { bool first = true; while (Tok.is(tok::l_square)) { SourceLocation LLoc = ConsumeBracket(); - OwningExprResult Size(first ? ParseExpression() + ExprResult Size(first ? ParseExpression() : ParseConstantExpression()); if (Size.isInvalid()) { // Recover @@ -1694,7 +1686,8 @@ void Parser::ParseDirectNewDeclarator(Declarator &D) { /// new-placement: /// '(' expression-list ')' /// -bool Parser::ParseExpressionListOrTypeId(ExprListTy &PlacementArgs, +bool Parser::ParseExpressionListOrTypeId( + llvm::SmallVectorImpl<Expr*> &PlacementArgs, Declarator &D) { // The '(' was already consumed. if (isTypeIdInParens()) { @@ -1721,7 +1714,7 @@ bool Parser::ParseExpressionListOrTypeId(ExprListTy &PlacementArgs, /// delete-expression: /// '::'[opt] 'delete' cast-expression /// '::'[opt] 'delete' '[' ']' cast-expression -Parser::OwningExprResult +ExprResult Parser::ParseCXXDeleteExpression(bool UseGlobal, SourceLocation Start) { assert(Tok.is(tok::kw_delete) && "Expected 'delete' keyword"); ConsumeToken(); // Consume 'delete' @@ -1736,11 +1729,11 @@ Parser::ParseCXXDeleteExpression(bool UseGlobal, SourceLocation Start) { return ExprError(); } - OwningExprResult Operand(ParseCastExpression(false)); + ExprResult Operand(ParseCastExpression(false)); if (Operand.isInvalid()) return move(Operand); - return Actions.ActOnCXXDelete(Start, UseGlobal, ArrayDelete, move(Operand)); + return Actions.ActOnCXXDelete(Start, UseGlobal, ArrayDelete, Operand.take()); } static UnaryTypeTrait UnaryTypeTraitFromTokKind(tok::TokenKind kind) { @@ -1772,7 +1765,7 @@ static UnaryTypeTrait UnaryTypeTraitFromTokKind(tok::TokenKind kind) { /// primary-expression: /// [GNU] unary-type-trait '(' type-id ')' /// -Parser::OwningExprResult Parser::ParseUnaryTypeTrait() { +ExprResult Parser::ParseUnaryTypeTrait() { UnaryTypeTrait UTT = UnaryTypeTraitFromTokKind(Tok.getKind()); SourceLocation Loc = ConsumeToken(); @@ -1796,17 +1789,17 @@ Parser::OwningExprResult Parser::ParseUnaryTypeTrait() { /// ParseCXXAmbiguousParenExpression - We have parsed the left paren of a /// parenthesized ambiguous type-id. This uses tentative parsing to disambiguate /// based on the context past the parens. -Parser::OwningExprResult +ExprResult Parser::ParseCXXAmbiguousParenExpression(ParenParseOption &ExprType, - TypeTy *&CastTy, + ParsedType &CastTy, SourceLocation LParenLoc, SourceLocation &RParenLoc) { assert(getLang().CPlusPlus && "Should only be called for C++!"); assert(ExprType == CastExpr && "Compound literals are not ambiguous!"); assert(isTypeIdInParens() && "Not a type-id!"); - OwningExprResult Result(Actions, true); - CastTy = 0; + ExprResult Result(true); + CastTy = ParsedType(); // We need to disambiguate a very ugly part of the C++ syntax: // @@ -1851,7 +1844,8 @@ Parser::ParseCXXAmbiguousParenExpression(ParenParseOption &ExprType, // will be consumed. Result = ParseCastExpression(false/*isUnaryExpression*/, false/*isAddressofOperand*/, - NotCastExpr, 0/*TypeOfCast*/); + NotCastExpr, + ParsedType()/*TypeOfCast*/); } // If we parsed a cast-expression, it's really a type-id, otherwise it's @@ -1894,7 +1888,7 @@ Parser::ParseCXXAmbiguousParenExpression(ParenParseOption &ExprType, // Result is what ParseCastExpression returned earlier. if (!Result.isInvalid()) Result = Actions.ActOnCastExpr(getCurScope(), LParenLoc, CastTy, RParenLoc, - move(Result)); + Result.take()); return move(Result); } @@ -1904,7 +1898,7 @@ Parser::ParseCXXAmbiguousParenExpression(ParenParseOption &ExprType, ExprType = SimpleExpr; Result = ParseExpression(); if (!Result.isInvalid() && Tok.is(tok::r_paren)) - Result = Actions.ActOnParenExpr(LParenLoc, Tok.getLocation(), move(Result)); + Result = Actions.ActOnParenExpr(LParenLoc, Tok.getLocation(), Result.take()); // Match the ')'. if (Result.isInvalid()) { diff --git a/contrib/llvm/tools/clang/lib/Parse/ParseInit.cpp b/contrib/llvm/tools/clang/lib/Parse/ParseInit.cpp index 8451aeb..4347294 100644 --- a/contrib/llvm/tools/clang/lib/Parse/ParseInit.cpp +++ b/contrib/llvm/tools/clang/lib/Parse/ParseInit.cpp @@ -11,10 +11,10 @@ // //===----------------------------------------------------------------------===// -#include "clang/Parse/Designator.h" #include "clang/Parse/Parser.h" #include "clang/Parse/ParseDiagnostic.h" -#include "clang/Parse/Scope.h" +#include "clang/Sema/Designator.h" +#include "clang/Sema/Scope.h" #include "llvm/ADT/SmallString.h" #include "llvm/Support/raw_ostream.h" using namespace clang; @@ -71,7 +71,7 @@ static void CheckArrayDesignatorSyntax(Parser &P, SourceLocation Loc, /// initializer (because it is an expression). We need to consider this case /// when parsing array designators. /// -Parser::OwningExprResult Parser::ParseInitializerWithPotentialDesignator() { +ExprResult Parser::ParseInitializerWithPotentialDesignator() { // If this is the old-style GNU extension: // designation ::= identifier ':' @@ -137,7 +137,7 @@ Parser::OwningExprResult Parser::ParseInitializerWithPotentialDesignator() { // [4][foo bar] -> obsolete GNU designation with objc message send. // SourceLocation StartLoc = ConsumeBracket(); - OwningExprResult Idx(Actions); + ExprResult Idx; // If Objective-C is enabled and this is a typename (class message // send) or send to 'super', parse this as a message send @@ -149,8 +149,9 @@ Parser::OwningExprResult Parser::ParseInitializerWithPotentialDesignator() { NextToken().isNot(tok::period) && getCurScope()->isInObjcMethodScope()) { CheckArrayDesignatorSyntax(*this, StartLoc, Desig); return ParseAssignmentExprWithObjCMessageExprStart(StartLoc, - ConsumeToken(), 0, - ExprArg(Actions)); + ConsumeToken(), + ParsedType(), + 0); } // Parse the receiver, which is either a type or an expression. @@ -167,35 +168,35 @@ Parser::OwningExprResult Parser::ParseInitializerWithPotentialDesignator() { CheckArrayDesignatorSyntax(*this, StartLoc, Desig); return ParseAssignmentExprWithObjCMessageExprStart(StartLoc, SourceLocation(), - TypeOrExpr, - ExprArg(Actions)); + ParsedType::getFromOpaquePtr(TypeOrExpr), + 0); } // If the receiver was an expression, we still don't know // whether we have a message send or an array designator; just // adopt the expression for further analysis below. // FIXME: potentially-potentially evaluated expression above? - Idx = OwningExprResult(Actions, TypeOrExpr); + Idx = ExprResult(static_cast<Expr*>(TypeOrExpr)); } else if (getLang().ObjC1 && Tok.is(tok::identifier)) { IdentifierInfo *II = Tok.getIdentifierInfo(); SourceLocation IILoc = Tok.getLocation(); - TypeTy *ReceiverType; + ParsedType ReceiverType; // Three cases. This is a message send to a type: [type foo] // This is a message send to super: [super foo] // This is a message sent to an expr: [super.bar foo] - switch (Action::ObjCMessageKind Kind + switch (Sema::ObjCMessageKind Kind = Actions.getObjCMessageKind(getCurScope(), II, IILoc, II == Ident_super, NextToken().is(tok::period), ReceiverType)) { - case Action::ObjCSuperMessage: - case Action::ObjCClassMessage: + case Sema::ObjCSuperMessage: + case Sema::ObjCClassMessage: CheckArrayDesignatorSyntax(*this, StartLoc, Desig); - if (Kind == Action::ObjCSuperMessage) + if (Kind == Sema::ObjCSuperMessage) return ParseAssignmentExprWithObjCMessageExprStart(StartLoc, ConsumeToken(), - 0, - ExprArg(Actions)); + ParsedType(), + 0); ConsumeToken(); // the identifier if (!ReceiverType) { SkipUntil(tok::r_square); @@ -205,9 +206,9 @@ Parser::OwningExprResult Parser::ParseInitializerWithPotentialDesignator() { return ParseAssignmentExprWithObjCMessageExprStart(StartLoc, SourceLocation(), ReceiverType, - ExprArg(Actions)); + 0); - case Action::ObjCInstanceMessage: + case Sema::ObjCInstanceMessage: // Fall through; we'll just parse the expression and // (possibly) treat this like an Objective-C message send // later. @@ -239,7 +240,8 @@ Parser::OwningExprResult Parser::ParseInitializerWithPotentialDesignator() { CheckArrayDesignatorSyntax(*this, Tok.getLocation(), Desig); return ParseAssignmentExprWithObjCMessageExprStart(StartLoc, SourceLocation(), - 0, move(Idx)); + ParsedType(), + Idx.take()); } // If this is a normal array designator, remember it. @@ -250,7 +252,7 @@ Parser::OwningExprResult Parser::ParseInitializerWithPotentialDesignator() { Diag(Tok, diag::ext_gnu_array_range); SourceLocation EllipsisLoc = ConsumeToken(); - OwningExprResult RHS(ParseConstantExpression()); + ExprResult RHS(ParseConstantExpression()); if (RHS.isInvalid()) { SkipUntil(tok::r_square); return move(RHS); @@ -307,7 +309,7 @@ Parser::OwningExprResult Parser::ParseInitializerWithPotentialDesignator() { /// designation[opt] initializer /// initializer-list ',' designation[opt] initializer /// -Parser::OwningExprResult Parser::ParseBraceInitializer() { +ExprResult Parser::ParseBraceInitializer() { SourceLocation LBraceLoc = ConsumeBrace(); /// InitExprs - This is the actual list of expressions contained in the @@ -319,7 +321,7 @@ Parser::OwningExprResult Parser::ParseBraceInitializer() { if (!getLang().CPlusPlus) Diag(LBraceLoc, diag::ext_gnu_empty_initializer); // Match the '}'. - return Actions.ActOnInitList(LBraceLoc, Action::MultiExprArg(Actions), + return Actions.ActOnInitList(LBraceLoc, MultiExprArg(Actions), ConsumeBrace()); } @@ -330,7 +332,7 @@ Parser::OwningExprResult Parser::ParseBraceInitializer() { // If we know that this cannot be a designation, just parse the nested // initializer directly. - OwningExprResult SubElt(Actions); + ExprResult SubElt; if (MayBeDesignationStart(Tok.getKind(), PP)) SubElt = ParseInitializerWithPotentialDesignator(); else diff --git a/contrib/llvm/tools/clang/lib/Parse/ParseObjc.cpp b/contrib/llvm/tools/clang/lib/Parse/ParseObjc.cpp index 68473a5..6861ce9 100644 --- a/contrib/llvm/tools/clang/lib/Parse/ParseObjc.cpp +++ b/contrib/llvm/tools/clang/lib/Parse/ParseObjc.cpp @@ -11,10 +11,11 @@ // //===----------------------------------------------------------------------===// -#include "clang/Parse/Parser.h" -#include "clang/Parse/DeclSpec.h" -#include "clang/Parse/Scope.h" #include "clang/Parse/ParseDiagnostic.h" +#include "clang/Parse/Parser.h" +#include "clang/Sema/DeclSpec.h" +#include "clang/Sema/PrettyDeclStackTrace.h" +#include "clang/Sema/Scope.h" #include "llvm/ADT/SmallVector.h" using namespace clang; @@ -27,7 +28,7 @@ using namespace clang; /// [OBJC] objc-protocol-definition /// [OBJC] objc-method-definition /// [OBJC] '@' 'end' -Parser::DeclPtrTy Parser::ParseObjCAtDirectives() { +Decl *Parser::ParseObjCAtDirectives() { SourceLocation AtLoc = ConsumeToken(); // the "@" if (Tok.is(tok::code_completion)) { @@ -55,7 +56,7 @@ Parser::DeclPtrTy Parser::ParseObjCAtDirectives() { default: Diag(AtLoc, diag::err_unexpected_at); SkipUntil(tok::semi); - return DeclPtrTy(); + return 0; } } @@ -63,7 +64,7 @@ Parser::DeclPtrTy Parser::ParseObjCAtDirectives() { /// objc-class-declaration: /// '@' 'class' identifier-list ';' /// -Parser::DeclPtrTy Parser::ParseObjCAtClassDeclaration(SourceLocation atLoc) { +Decl *Parser::ParseObjCAtClassDeclaration(SourceLocation atLoc) { ConsumeToken(); // the identifier "class" llvm::SmallVector<IdentifierInfo *, 8> ClassNames; llvm::SmallVector<SourceLocation, 8> ClassLocs; @@ -73,7 +74,7 @@ Parser::DeclPtrTy Parser::ParseObjCAtClassDeclaration(SourceLocation atLoc) { if (Tok.isNot(tok::identifier)) { Diag(Tok, diag::err_expected_ident); SkipUntil(tok::semi); - return DeclPtrTy(); + return 0; } ClassNames.push_back(Tok.getIdentifierInfo()); ClassLocs.push_back(Tok.getLocation()); @@ -87,7 +88,7 @@ Parser::DeclPtrTy Parser::ParseObjCAtClassDeclaration(SourceLocation atLoc) { // Consume the ';'. if (ExpectAndConsume(tok::semi, diag::err_expected_semi_after, "@class")) - return DeclPtrTy(); + return 0; return Actions.ActOnForwardClassDeclaration(atLoc, ClassNames.data(), ClassLocs.data(), @@ -122,7 +123,7 @@ Parser::DeclPtrTy Parser::ParseObjCAtClassDeclaration(SourceLocation atLoc) { /// __attribute__((unavailable)) /// __attribute__((objc_exception)) - used by NSException on 64-bit /// -Parser::DeclPtrTy Parser::ParseObjCAtInterfaceDeclaration( +Decl *Parser::ParseObjCAtInterfaceDeclaration( SourceLocation atLoc, AttributeList *attrList) { assert(Tok.isObjCAtKeyword(tok::objc_interface) && "ParseObjCAtInterfaceDeclaration(): Expected @interface"); @@ -136,7 +137,7 @@ Parser::DeclPtrTy Parser::ParseObjCAtInterfaceDeclaration( if (Tok.isNot(tok::identifier)) { Diag(Tok, diag::err_expected_ident); // missing class or category name. - return DeclPtrTy(); + return 0; } // We have a class or category name - consume it. @@ -159,27 +160,27 @@ Parser::DeclPtrTy Parser::ParseObjCAtInterfaceDeclaration( } else if (!getLang().ObjC2) { Diag(Tok, diag::err_expected_ident); // missing category name. - return DeclPtrTy(); + return 0; } if (Tok.isNot(tok::r_paren)) { Diag(Tok, diag::err_expected_rparen); SkipUntil(tok::r_paren, false); // don't stop at ';' - return DeclPtrTy(); + return 0; } rparenLoc = ConsumeParen(); // Next, we need to check for any protocol references. SourceLocation LAngleLoc, EndProtoLoc; - llvm::SmallVector<DeclPtrTy, 8> ProtocolRefs; + llvm::SmallVector<Decl *, 8> ProtocolRefs; llvm::SmallVector<SourceLocation, 8> ProtocolLocs; if (Tok.is(tok::less) && ParseObjCProtocolReferences(ProtocolRefs, ProtocolLocs, true, LAngleLoc, EndProtoLoc)) - return DeclPtrTy(); + return 0; if (attrList) // categories don't support attributes. Diag(Tok, diag::err_objc_no_attributes_on_category); - DeclPtrTy CategoryType = + Decl *CategoryType = Actions.ActOnStartCategoryInterface(atLoc, nameId, nameLoc, categoryId, categoryLoc, @@ -209,21 +210,21 @@ Parser::DeclPtrTy Parser::ParseObjCAtInterfaceDeclaration( if (Tok.isNot(tok::identifier)) { Diag(Tok, diag::err_expected_ident); // missing super class name. - return DeclPtrTy(); + return 0; } superClassId = Tok.getIdentifierInfo(); superClassLoc = ConsumeToken(); } // Next, we need to check for any protocol references. - llvm::SmallVector<Action::DeclPtrTy, 8> ProtocolRefs; + llvm::SmallVector<Decl *, 8> ProtocolRefs; llvm::SmallVector<SourceLocation, 8> ProtocolLocs; SourceLocation LAngleLoc, EndProtoLoc; if (Tok.is(tok::less) && ParseObjCProtocolReferences(ProtocolRefs, ProtocolLocs, true, LAngleLoc, EndProtoLoc)) - return DeclPtrTy(); + return 0; - DeclPtrTy ClsType = + Decl *ClsType = Actions.ActOnStartClassInterface(atLoc, nameId, nameLoc, superClassId, superClassLoc, ProtocolRefs.data(), ProtocolRefs.size(), @@ -241,30 +242,30 @@ Parser::DeclPtrTy Parser::ParseObjCAtInterfaceDeclaration( /// it's used, but instead it's been lifted to here to support VS2005. struct Parser::ObjCPropertyCallback : FieldCallback { Parser &P; - DeclPtrTy IDecl; - llvm::SmallVectorImpl<DeclPtrTy> &Props; + Decl *IDecl; + llvm::SmallVectorImpl<Decl *> &Props; ObjCDeclSpec &OCDS; SourceLocation AtLoc; tok::ObjCKeywordKind MethodImplKind; - ObjCPropertyCallback(Parser &P, DeclPtrTy IDecl, - llvm::SmallVectorImpl<DeclPtrTy> &Props, + ObjCPropertyCallback(Parser &P, Decl *IDecl, + llvm::SmallVectorImpl<Decl *> &Props, ObjCDeclSpec &OCDS, SourceLocation AtLoc, tok::ObjCKeywordKind MethodImplKind) : P(P), IDecl(IDecl), Props(Props), OCDS(OCDS), AtLoc(AtLoc), MethodImplKind(MethodImplKind) { } - DeclPtrTy invoke(FieldDeclarator &FD) { + Decl *invoke(FieldDeclarator &FD) { if (FD.D.getIdentifier() == 0) { P.Diag(AtLoc, diag::err_objc_property_requires_field_name) << FD.D.getSourceRange(); - return DeclPtrTy(); + return 0; } if (FD.BitfieldSize) { P.Diag(AtLoc, diag::err_objc_property_bitfield) << FD.D.getSourceRange(); - return DeclPtrTy(); + return 0; } // Install the property declarator into interfaceDecl. @@ -282,7 +283,7 @@ struct Parser::ObjCPropertyCallback : FieldCallback { P.PP.getSelectorTable(), FD.D.getIdentifier()); bool isOverridingProperty = false; - DeclPtrTy Property = + Decl *Property = P.Actions.ActOnProperty(P.getCurScope(), AtLoc, FD, OCDS, GetterSel, SetterSel, IDecl, &isOverridingProperty, @@ -306,10 +307,10 @@ struct Parser::ObjCPropertyCallback : FieldCallback { /// @required /// @optional /// -void Parser::ParseObjCInterfaceDeclList(DeclPtrTy interfaceDecl, +void Parser::ParseObjCInterfaceDeclList(Decl *interfaceDecl, tok::ObjCKeywordKind contextKey) { - llvm::SmallVector<DeclPtrTy, 32> allMethods; - llvm::SmallVector<DeclPtrTy, 16> allProperties; + llvm::SmallVector<Decl *, 32> allMethods; + llvm::SmallVector<Decl *, 16> allProperties; llvm::SmallVector<DeclGroupPtrTy, 8> allTUVariables; tok::ObjCKeywordKind MethodImplKind = tok::objc_not_keyword; @@ -318,7 +319,7 @@ void Parser::ParseObjCInterfaceDeclList(DeclPtrTy interfaceDecl, while (1) { // If this is a method prototype, parse it. if (Tok.is(tok::minus) || Tok.is(tok::plus)) { - DeclPtrTy methodPrototype = + Decl *methodPrototype = ParseObjCMethodPrototype(interfaceDecl, MethodImplKind); allMethods.push_back(methodPrototype); // Consume the ';' here, since ParseObjCMethodPrototype() is re-used for @@ -329,10 +330,10 @@ void Parser::ParseObjCInterfaceDeclList(DeclPtrTy interfaceDecl, } if (Tok.is(tok::l_paren)) { Diag(Tok, diag::err_expected_minus_or_plus); - DeclPtrTy methodPrototype = ParseObjCMethodDecl(Tok.getLocation(), - tok::minus, - interfaceDecl, - MethodImplKind); + ParseObjCMethodDecl(Tok.getLocation(), + tok::minus, + interfaceDecl, + MethodImplKind); continue; } // Ignore excess semicolons. @@ -348,8 +349,8 @@ void Parser::ParseObjCInterfaceDeclList(DeclPtrTy interfaceDecl, // Code completion within an Objective-C interface. if (Tok.is(tok::code_completion)) { Actions.CodeCompleteOrdinaryName(getCurScope(), - ObjCImpDecl? Action::CCC_ObjCImplementation - : Action::CCC_ObjCInterface); + ObjCImpDecl? Sema::PCC_ObjCImplementation + : Sema::PCC_ObjCInterface); ConsumeCodeCompletionToken(); } @@ -468,8 +469,8 @@ void Parser::ParseObjCInterfaceDeclList(DeclPtrTy interfaceDecl, /// copy /// nonatomic /// -void Parser::ParseObjCPropertyAttribute(ObjCDeclSpec &DS, DeclPtrTy ClassDecl, - DeclPtrTy *Methods, +void Parser::ParseObjCPropertyAttribute(ObjCDeclSpec &DS, Decl *ClassDecl, + Decl **Methods, unsigned NumMethods) { assert(Tok.getKind() == tok::l_paren); SourceLocation LHSLoc = ConsumeParen(); // consume '(' @@ -562,14 +563,13 @@ void Parser::ParseObjCPropertyAttribute(ObjCDeclSpec &DS, DeclPtrTy ClassDecl, /// objc-method-attributes: [OBJC2] /// __attribute__((deprecated)) /// -Parser::DeclPtrTy Parser::ParseObjCMethodPrototype(DeclPtrTy IDecl, - tok::ObjCKeywordKind MethodImplKind) { +Decl *Parser::ParseObjCMethodPrototype(Decl *IDecl, + tok::ObjCKeywordKind MethodImplKind) { assert((Tok.is(tok::minus) || Tok.is(tok::plus)) && "expected +/-"); tok::TokenKind methodType = Tok.getKind(); SourceLocation mLoc = ConsumeToken(); - - DeclPtrTy MDecl = ParseObjCMethodDecl(mLoc, methodType, IDecl,MethodImplKind); + Decl *MDecl = ParseObjCMethodDecl(mLoc, methodType, IDecl,MethodImplKind); // Since this rule is used for both method declarations and definitions, // the caller is (optionally) responsible for consuming the ';'. return MDecl; @@ -584,9 +584,31 @@ Parser::DeclPtrTy Parser::ParseObjCMethodPrototype(DeclPtrTy IDecl, /// in out inout bycopy byref oneway int char float double void _Bool /// IdentifierInfo *Parser::ParseObjCSelectorPiece(SourceLocation &SelectorLoc) { + switch (Tok.getKind()) { default: return 0; + case tok::ampamp: + case tok::ampequal: + case tok::amp: + case tok::pipe: + case tok::tilde: + case tok::exclaim: + case tok::exclaimequal: + case tok::pipepipe: + case tok::pipeequal: + case tok::caret: + case tok::caretequal: { + std::string ThisTok(PP.getSpelling(Tok)); + if (isalpha(ThisTok[0])) { + IdentifierInfo *II = &PP.getIdentifierTable().get(ThisTok.data()); + Tok.setKind(tok::identifier); + SelectorLoc = ConsumeToken(); + return II; + } + return 0; + } + case tok::identifier: case tok::kw_asm: case tok::kw_auto: @@ -680,8 +702,13 @@ bool Parser::isTokIdentifier_in() const { /// objc-type-qualifier /// objc-type-qualifiers objc-type-qualifier /// -void Parser::ParseObjCTypeQualifierList(ObjCDeclSpec &DS) { +void Parser::ParseObjCTypeQualifierList(ObjCDeclSpec &DS, bool IsParameter) { while (1) { + if (Tok.is(tok::code_completion)) { + Actions.CodeCompleteObjCPassingType(getCurScope(), DS); + ConsumeCodeCompletionToken(); + } + if (Tok.isNot(tok::identifier)) return; @@ -715,16 +742,16 @@ void Parser::ParseObjCTypeQualifierList(ObjCDeclSpec &DS) { /// '(' objc-type-qualifiers[opt] type-name ')' /// '(' objc-type-qualifiers[opt] ')' /// -Parser::TypeTy *Parser::ParseObjCTypeName(ObjCDeclSpec &DS) { +ParsedType Parser::ParseObjCTypeName(ObjCDeclSpec &DS, bool IsParameter) { assert(Tok.is(tok::l_paren) && "expected ("); SourceLocation LParenLoc = ConsumeParen(); SourceLocation TypeStartLoc = Tok.getLocation(); // Parse type qualifiers, in, inout, etc. - ParseObjCTypeQualifierList(DS); + ParseObjCTypeQualifierList(DS, IsParameter); - TypeTy *Ty = 0; + ParsedType Ty; if (isTypeSpecifierQualifier()) { TypeResult TypeSpec = ParseTypeName(); if (!TypeSpec.isInvalid()) @@ -773,23 +800,23 @@ Parser::TypeTy *Parser::ParseObjCTypeName(ObjCDeclSpec &DS) { /// objc-keyword-attributes: [OBJC2] /// __attribute__((unused)) /// -Parser::DeclPtrTy Parser::ParseObjCMethodDecl(SourceLocation mLoc, - tok::TokenKind mType, - DeclPtrTy IDecl, - tok::ObjCKeywordKind MethodImplKind) { +Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc, + tok::TokenKind mType, + Decl *IDecl, + tok::ObjCKeywordKind MethodImplKind) { ParsingDeclRAIIObject PD(*this); if (Tok.is(tok::code_completion)) { Actions.CodeCompleteObjCMethodDecl(getCurScope(), mType == tok::minus, - /*ReturnType=*/0, IDecl); + /*ReturnType=*/ ParsedType(), IDecl); ConsumeCodeCompletionToken(); } // Parse the return type if present. - TypeTy *ReturnType = 0; + ParsedType ReturnType; ObjCDeclSpec DSRet; if (Tok.is(tok::l_paren)) - ReturnType = ParseObjCTypeName(DSRet); + ReturnType = ParseObjCTypeName(DSRet, false); // If attributes exist before the method, parse them. llvm::OwningPtr<AttributeList> MethodAttrs; @@ -812,7 +839,7 @@ Parser::DeclPtrTy Parser::ParseObjCMethodDecl(SourceLocation mLoc, << SourceRange(mLoc, Tok.getLocation()); // Skip until we get a ; or {}. SkipUntil(tok::r_brace); - return DeclPtrTy(); + return 0; } llvm::SmallVector<DeclaratorChunk::ParamInfo, 8> CParamInfo; @@ -823,7 +850,7 @@ Parser::DeclPtrTy Parser::ParseObjCMethodDecl(SourceLocation mLoc, ParseGNUAttributes())); Selector Sel = PP.getSelectorTable().getNullarySelector(SelIdent); - DeclPtrTy Result + Decl *Result = Actions.ActOnMethodDeclaration(mLoc, Tok.getLocation(), mType, IDecl, DSRet, ReturnType, Sel, 0, @@ -835,10 +862,10 @@ Parser::DeclPtrTy Parser::ParseObjCMethodDecl(SourceLocation mLoc, } llvm::SmallVector<IdentifierInfo *, 12> KeyIdents; - llvm::SmallVector<Action::ObjCArgInfo, 12> ArgInfos; + llvm::SmallVector<Sema::ObjCArgInfo, 12> ArgInfos; while (1) { - Action::ObjCArgInfo ArgInfo; + Sema::ObjCArgInfo ArgInfo; // Each iteration parses a single keyword argument. if (Tok.isNot(tok::colon)) { @@ -847,9 +874,9 @@ Parser::DeclPtrTy Parser::ParseObjCMethodDecl(SourceLocation mLoc, } ConsumeToken(); // Eat the ':'. - ArgInfo.Type = 0; + ArgInfo.Type = ParsedType(); if (Tok.is(tok::l_paren)) // Parse the argument type if present. - ArgInfo.Type = ParseObjCTypeName(ArgInfo.DeclSpec); + ArgInfo.Type = ParseObjCTypeName(ArgInfo.DeclSpec, true); // If attributes exist before the argument name, parse them. ArgInfo.ArgAttrs = 0; @@ -918,7 +945,7 @@ Parser::DeclPtrTy Parser::ParseObjCMethodDecl(SourceLocation mLoc, Declarator ParmDecl(DS, Declarator::PrototypeContext); ParseDeclarator(ParmDecl); IdentifierInfo *ParmII = ParmDecl.getIdentifier(); - DeclPtrTy Param = Actions.ActOnParamDeclarator(getCurScope(), ParmDecl); + Decl *Param = Actions.ActOnParamDeclarator(getCurScope(), ParmDecl); CParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII, ParmDecl.getIdentifierLoc(), Param, @@ -933,10 +960,10 @@ Parser::DeclPtrTy Parser::ParseObjCMethodDecl(SourceLocation mLoc, ParseGNUAttributes())); if (KeyIdents.size() == 0) - return DeclPtrTy(); + return 0; Selector Sel = PP.getSelectorTable().getSelector(KeyIdents.size(), &KeyIdents[0]); - DeclPtrTy Result + Decl *Result = Actions.ActOnMethodDeclaration(mLoc, Tok.getLocation(), mType, IDecl, DSRet, ReturnType, Sel, &ArgInfos[0], @@ -946,7 +973,7 @@ Parser::DeclPtrTy Parser::ParseObjCMethodDecl(SourceLocation mLoc, PD.complete(Result); // Delete referenced AttributeList objects. - for (llvm::SmallVectorImpl<Action::ObjCArgInfo>::iterator + for (llvm::SmallVectorImpl<Sema::ObjCArgInfo>::iterator I = ArgInfos.begin(), E = ArgInfos.end(); I != E; ++I) delete I->ArgAttrs; @@ -957,7 +984,7 @@ Parser::DeclPtrTy Parser::ParseObjCMethodDecl(SourceLocation mLoc, /// '<' identifier-list '>' /// bool Parser:: -ParseObjCProtocolReferences(llvm::SmallVectorImpl<Action::DeclPtrTy> &Protocols, +ParseObjCProtocolReferences(llvm::SmallVectorImpl<Decl *> &Protocols, llvm::SmallVectorImpl<SourceLocation> &ProtocolLocs, bool WarnOnDeclarations, SourceLocation &LAngleLoc, SourceLocation &EndLoc) { @@ -1024,11 +1051,11 @@ ParseObjCProtocolReferences(llvm::SmallVectorImpl<Action::DeclPtrTy> &Protocols, /// objc-instance-variable-decl: /// struct-declaration /// -void Parser::ParseObjCClassInstanceVariables(DeclPtrTy interfaceDecl, +void Parser::ParseObjCClassInstanceVariables(Decl *interfaceDecl, tok::ObjCKeywordKind visibility, SourceLocation atLoc) { assert(Tok.is(tok::l_brace) && "expected {"); - llvm::SmallVector<DeclPtrTy, 32> AllIvarDecls; + llvm::SmallVector<Decl *, 32> AllIvarDecls; ParseScope ClassScope(this, Scope::DeclScope|Scope::ClassScope); @@ -1071,24 +1098,24 @@ void Parser::ParseObjCClassInstanceVariables(DeclPtrTy interfaceDecl, if (Tok.is(tok::code_completion)) { Actions.CodeCompleteOrdinaryName(getCurScope(), - Action::CCC_ObjCInstanceVariableList); + Sema::PCC_ObjCInstanceVariableList); ConsumeCodeCompletionToken(); } struct ObjCIvarCallback : FieldCallback { Parser &P; - DeclPtrTy IDecl; + Decl *IDecl; tok::ObjCKeywordKind visibility; - llvm::SmallVectorImpl<DeclPtrTy> &AllIvarDecls; + llvm::SmallVectorImpl<Decl *> &AllIvarDecls; - ObjCIvarCallback(Parser &P, DeclPtrTy IDecl, tok::ObjCKeywordKind V, - llvm::SmallVectorImpl<DeclPtrTy> &AllIvarDecls) : + ObjCIvarCallback(Parser &P, Decl *IDecl, tok::ObjCKeywordKind V, + llvm::SmallVectorImpl<Decl *> &AllIvarDecls) : P(P), IDecl(IDecl), visibility(V), AllIvarDecls(AllIvarDecls) { } - DeclPtrTy invoke(FieldDeclarator &FD) { + Decl *invoke(FieldDeclarator &FD) { // Install the declarator into the interface decl. - DeclPtrTy Field + Decl *Field = P.Actions.ActOnIvar(P.getCurScope(), FD.D.getDeclSpec().getSourceRange().getBegin(), IDecl, FD.D, FD.BitfieldSize, visibility); @@ -1097,7 +1124,7 @@ void Parser::ParseObjCClassInstanceVariables(DeclPtrTy interfaceDecl, return Field; } } Callback(*this, interfaceDecl, visibility, AllIvarDecls); - + // Parse all the comma separated declarators. DeclSpec DS; ParseStructDeclaration(DS, Callback); @@ -1111,6 +1138,7 @@ void Parser::ParseObjCClassInstanceVariables(DeclPtrTy interfaceDecl, } } SourceLocation RBraceLoc = MatchRHSPunctuation(tok::r_brace, LBraceLoc); + Actions.ActOnLastBitfield(RBraceLoc, interfaceDecl, AllIvarDecls); // Call ActOnFields() even if we don't have any decls. This is useful // for code rewriting tools that need to be aware of the empty list. Actions.ActOnFields(getCurScope(), atLoc, interfaceDecl, @@ -1135,7 +1163,7 @@ void Parser::ParseObjCClassInstanceVariables(DeclPtrTy interfaceDecl, /// "@protocol identifier ;" should be resolved as "@protocol /// identifier-list ;": objc-interface-decl-list may not start with a /// semicolon in the first alternative if objc-protocol-refs are omitted. -Parser::DeclPtrTy Parser::ParseObjCAtProtocolDeclaration(SourceLocation AtLoc, +Decl *Parser::ParseObjCAtProtocolDeclaration(SourceLocation AtLoc, AttributeList *attrList) { assert(Tok.isObjCAtKeyword(tok::objc_protocol) && "ParseObjCAtProtocolDeclaration(): Expected @protocol"); @@ -1148,7 +1176,7 @@ Parser::DeclPtrTy Parser::ParseObjCAtProtocolDeclaration(SourceLocation AtLoc, if (Tok.isNot(tok::identifier)) { Diag(Tok, diag::err_expected_ident); // missing protocol name. - return DeclPtrTy(); + return 0; } // Save the protocol name, then consume it. IdentifierInfo *protocolName = Tok.getIdentifierInfo(); @@ -1171,7 +1199,7 @@ Parser::DeclPtrTy Parser::ParseObjCAtProtocolDeclaration(SourceLocation AtLoc, if (Tok.isNot(tok::identifier)) { Diag(Tok, diag::err_expected_ident); SkipUntil(tok::semi); - return DeclPtrTy(); + return 0; } ProtocolRefs.push_back(IdentifierLocPair(Tok.getIdentifierInfo(), Tok.getLocation())); @@ -1182,7 +1210,7 @@ Parser::DeclPtrTy Parser::ParseObjCAtProtocolDeclaration(SourceLocation AtLoc, } // Consume the ';'. if (ExpectAndConsume(tok::semi, diag::err_expected_semi_after, "@protocol")) - return DeclPtrTy(); + return 0; return Actions.ActOnForwardProtocolDeclaration(AtLoc, &ProtocolRefs[0], @@ -1193,14 +1221,14 @@ Parser::DeclPtrTy Parser::ParseObjCAtProtocolDeclaration(SourceLocation AtLoc, // Last, and definitely not least, parse a protocol declaration. SourceLocation LAngleLoc, EndProtoLoc; - llvm::SmallVector<DeclPtrTy, 8> ProtocolRefs; + llvm::SmallVector<Decl *, 8> ProtocolRefs; llvm::SmallVector<SourceLocation, 8> ProtocolLocs; if (Tok.is(tok::less) && ParseObjCProtocolReferences(ProtocolRefs, ProtocolLocs, false, LAngleLoc, EndProtoLoc)) - return DeclPtrTy(); + return 0; - DeclPtrTy ProtoType = + Decl *ProtoType = Actions.ActOnStartProtocolInterface(AtLoc, protocolName, nameLoc, ProtocolRefs.data(), ProtocolRefs.size(), @@ -1220,7 +1248,7 @@ Parser::DeclPtrTy Parser::ParseObjCAtProtocolDeclaration(SourceLocation AtLoc, /// /// objc-category-implementation-prologue: /// @implementation identifier ( identifier ) -Parser::DeclPtrTy Parser::ParseObjCAtImplementationDeclaration( +Decl *Parser::ParseObjCAtImplementationDeclaration( SourceLocation atLoc) { assert(Tok.isObjCAtKeyword(tok::objc_implementation) && "ParseObjCAtImplementationDeclaration(): Expected @implementation"); @@ -1234,7 +1262,7 @@ Parser::DeclPtrTy Parser::ParseObjCAtImplementationDeclaration( if (Tok.isNot(tok::identifier)) { Diag(Tok, diag::err_expected_ident); // missing class or category name. - return DeclPtrTy(); + return 0; } // We have a class or category name - consume it. IdentifierInfo *nameId = Tok.getIdentifierInfo(); @@ -1256,20 +1284,20 @@ Parser::DeclPtrTy Parser::ParseObjCAtImplementationDeclaration( categoryLoc = ConsumeToken(); } else { Diag(Tok, diag::err_expected_ident); // missing category name. - return DeclPtrTy(); + return 0; } if (Tok.isNot(tok::r_paren)) { Diag(Tok, diag::err_expected_rparen); SkipUntil(tok::r_paren, false); // don't stop at ';' - return DeclPtrTy(); + return 0; } rparenLoc = ConsumeParen(); - DeclPtrTy ImplCatType = Actions.ActOnStartCategoryImplementation( + Decl *ImplCatType = Actions.ActOnStartCategoryImplementation( atLoc, nameId, nameLoc, categoryId, categoryLoc); ObjCImpDecl = ImplCatType; PendingObjCImpDecl.push_back(ObjCImpDecl); - return DeclPtrTy(); + return 0; } // We have a class implementation SourceLocation superClassLoc; @@ -1279,12 +1307,12 @@ Parser::DeclPtrTy Parser::ParseObjCAtImplementationDeclaration( ConsumeToken(); if (Tok.isNot(tok::identifier)) { Diag(Tok, diag::err_expected_ident); // missing super class name. - return DeclPtrTy(); + return 0; } superClassId = Tok.getIdentifierInfo(); superClassLoc = ConsumeToken(); // Consume super class name } - DeclPtrTy ImplClsType = Actions.ActOnStartClassImplementation( + Decl *ImplClsType = Actions.ActOnStartClassImplementation( atLoc, nameId, nameLoc, superClassId, superClassLoc); @@ -1294,17 +1322,17 @@ Parser::DeclPtrTy Parser::ParseObjCAtImplementationDeclaration( ObjCImpDecl = ImplClsType; PendingObjCImpDecl.push_back(ObjCImpDecl); - return DeclPtrTy(); + return 0; } -Parser::DeclPtrTy Parser::ParseObjCAtEndDeclaration(SourceRange atEnd) { +Decl *Parser::ParseObjCAtEndDeclaration(SourceRange atEnd) { assert(Tok.isObjCAtKeyword(tok::objc_end) && "ParseObjCAtEndDeclaration(): Expected @end"); - DeclPtrTy Result = ObjCImpDecl; + Decl *Result = ObjCImpDecl; ConsumeToken(); // the "end" identifier if (ObjCImpDecl) { Actions.ActOnAtEnd(getCurScope(), atEnd, ObjCImpDecl); - ObjCImpDecl = DeclPtrTy(); + ObjCImpDecl = 0; PendingObjCImpDecl.pop_back(); } else { @@ -1314,10 +1342,11 @@ Parser::DeclPtrTy Parser::ParseObjCAtEndDeclaration(SourceRange atEnd) { return Result; } -Parser::DeclGroupPtrTy Parser::RetrievePendingObjCImpDecl() { +Parser::DeclGroupPtrTy Parser::FinishPendingObjCActions() { + Actions.DiagnoseUseOfUnimplementedSelectors(); if (PendingObjCImpDecl.empty()) - return Actions.ConvertDeclToDeclGroup(DeclPtrTy()); - DeclPtrTy ImpDecl = PendingObjCImpDecl.pop_back_val(); + return Actions.ConvertDeclToDeclGroup(0); + Decl *ImpDecl = PendingObjCImpDecl.pop_back_val(); Actions.ActOnAtEnd(getCurScope(), SourceRange(), ImpDecl); return Actions.ConvertDeclToDeclGroup(ImpDecl); } @@ -1325,25 +1354,25 @@ Parser::DeclGroupPtrTy Parser::RetrievePendingObjCImpDecl() { /// compatibility-alias-decl: /// @compatibility_alias alias-name class-name ';' /// -Parser::DeclPtrTy Parser::ParseObjCAtAliasDeclaration(SourceLocation atLoc) { +Decl *Parser::ParseObjCAtAliasDeclaration(SourceLocation atLoc) { assert(Tok.isObjCAtKeyword(tok::objc_compatibility_alias) && "ParseObjCAtAliasDeclaration(): Expected @compatibility_alias"); ConsumeToken(); // consume compatibility_alias if (Tok.isNot(tok::identifier)) { Diag(Tok, diag::err_expected_ident); - return DeclPtrTy(); + return 0; } IdentifierInfo *aliasId = Tok.getIdentifierInfo(); SourceLocation aliasLoc = ConsumeToken(); // consume alias-name if (Tok.isNot(tok::identifier)) { Diag(Tok, diag::err_expected_ident); - return DeclPtrTy(); + return 0; } IdentifierInfo *classId = Tok.getIdentifierInfo(); SourceLocation classLoc = ConsumeToken(); // consume class-name; if (Tok.isNot(tok::semi)) { Diag(Tok, diag::err_expected_semi_after) << "@compatibility_alias"; - return DeclPtrTy(); + return 0; } return Actions.ActOnCompatiblityAlias(atLoc, aliasId, aliasLoc, classId, classLoc); @@ -1360,7 +1389,7 @@ Parser::DeclPtrTy Parser::ParseObjCAtAliasDeclaration(SourceLocation atLoc) { /// identifier /// identifier '=' identifier /// -Parser::DeclPtrTy Parser::ParseObjCPropertySynthesize(SourceLocation atLoc) { +Decl *Parser::ParseObjCPropertySynthesize(SourceLocation atLoc) { assert(Tok.isObjCAtKeyword(tok::objc_synthesize) && "ParseObjCPropertyDynamic(): Expected '@synthesize'"); SourceLocation loc = ConsumeToken(); // consume synthesize @@ -1374,7 +1403,7 @@ Parser::DeclPtrTy Parser::ParseObjCPropertySynthesize(SourceLocation atLoc) { if (Tok.isNot(tok::identifier)) { Diag(Tok, diag::err_synthesized_property_name); SkipUntil(tok::semi); - return DeclPtrTy(); + return 0; } IdentifierInfo *propertyIvar = 0; @@ -1409,7 +1438,7 @@ Parser::DeclPtrTy Parser::ParseObjCPropertySynthesize(SourceLocation atLoc) { } else ConsumeToken(); // consume ';' - return DeclPtrTy(); + return 0; } /// property-dynamic: @@ -1419,7 +1448,7 @@ Parser::DeclPtrTy Parser::ParseObjCPropertySynthesize(SourceLocation atLoc) { /// identifier /// property-list ',' identifier /// -Parser::DeclPtrTy Parser::ParseObjCPropertyDynamic(SourceLocation atLoc) { +Decl *Parser::ParseObjCPropertyDynamic(SourceLocation atLoc) { assert(Tok.isObjCAtKeyword(tok::objc_dynamic) && "ParseObjCPropertyDynamic(): Expected '@dynamic'"); SourceLocation loc = ConsumeToken(); // consume dynamic @@ -1432,7 +1461,7 @@ Parser::DeclPtrTy Parser::ParseObjCPropertyDynamic(SourceLocation atLoc) { if (Tok.isNot(tok::identifier)) { Diag(Tok, diag::err_expected_ident); SkipUntil(tok::semi); - return DeclPtrTy(); + return 0; } IdentifierInfo *propertyId = Tok.getIdentifierInfo(); @@ -1450,14 +1479,14 @@ Parser::DeclPtrTy Parser::ParseObjCPropertyDynamic(SourceLocation atLoc) { } else ConsumeToken(); // consume ';' - return DeclPtrTy(); + return 0; } /// objc-throw-statement: /// throw expression[opt]; /// -Parser::OwningStmtResult Parser::ParseObjCThrowStmt(SourceLocation atLoc) { - OwningExprResult Res(Actions); +StmtResult Parser::ParseObjCThrowStmt(SourceLocation atLoc) { + ExprResult Res; ConsumeToken(); // consume throw if (Tok.isNot(tok::semi)) { Res = ParseExpression(); @@ -1468,13 +1497,13 @@ Parser::OwningStmtResult Parser::ParseObjCThrowStmt(SourceLocation atLoc) { } // consume ';' ExpectAndConsume(tok::semi, diag::err_expected_semi_after, "@throw"); - return Actions.ActOnObjCAtThrowStmt(atLoc, move(Res), getCurScope()); + return Actions.ActOnObjCAtThrowStmt(atLoc, Res.take(), getCurScope()); } /// objc-synchronized-statement: /// @synchronized '(' expression ')' compound-statement /// -Parser::OwningStmtResult +StmtResult Parser::ParseObjCSynchronizedStmt(SourceLocation atLoc) { ConsumeToken(); // consume synchronized if (Tok.isNot(tok::l_paren)) { @@ -1482,7 +1511,7 @@ Parser::ParseObjCSynchronizedStmt(SourceLocation atLoc) { return StmtError(); } ConsumeParen(); // '(' - OwningExprResult Res(ParseExpression()); + ExprResult Res(ParseExpression()); if (Res.isInvalid()) { SkipUntil(tok::semi); return StmtError(); @@ -1500,12 +1529,12 @@ Parser::ParseObjCSynchronizedStmt(SourceLocation atLoc) { // statements can always hold declarations. ParseScope BodyScope(this, Scope::DeclScope); - OwningStmtResult SynchBody(ParseCompoundStatementBody()); + StmtResult SynchBody(ParseCompoundStatementBody()); BodyScope.Exit(); if (SynchBody.isInvalid()) SynchBody = Actions.ActOnNullStmt(Tok.getLocation()); - return Actions.ActOnObjCAtSynchronizedStmt(atLoc, move(Res), move(SynchBody)); + return Actions.ActOnObjCAtSynchronizedStmt(atLoc, Res.take(), SynchBody.take()); } /// objc-try-catch-statement: @@ -1519,7 +1548,7 @@ Parser::ParseObjCSynchronizedStmt(SourceLocation atLoc) { /// parameter-declaration /// '...' [OBJC2] /// -Parser::OwningStmtResult Parser::ParseObjCTryStmt(SourceLocation atLoc) { +StmtResult Parser::ParseObjCTryStmt(SourceLocation atLoc) { bool catch_or_finally_seen = false; ConsumeToken(); // consume try @@ -1528,9 +1557,9 @@ Parser::OwningStmtResult Parser::ParseObjCTryStmt(SourceLocation atLoc) { return StmtError(); } StmtVector CatchStmts(Actions); - OwningStmtResult FinallyStmt(Actions); + StmtResult FinallyStmt; ParseScope TryScope(this, Scope::DeclScope); - OwningStmtResult TryBody(ParseCompoundStatementBody()); + StmtResult TryBody(ParseCompoundStatementBody()); TryScope.Exit(); if (TryBody.isInvalid()) TryBody = Actions.ActOnNullStmt(Tok.getLocation()); @@ -1546,7 +1575,7 @@ Parser::OwningStmtResult Parser::ParseObjCTryStmt(SourceLocation atLoc) { SourceLocation AtCatchFinallyLoc = ConsumeToken(); if (Tok.isObjCAtKeyword(tok::objc_catch)) { - DeclPtrTy FirstPart; + Decl *FirstPart = 0; ConsumeToken(); // consume catch if (Tok.is(tok::l_paren)) { ConsumeParen(); @@ -1573,7 +1602,7 @@ Parser::OwningStmtResult Parser::ParseObjCTryStmt(SourceLocation atLoc) { else // Skip over garbage, until we get to ')'. Eat the ')'. SkipUntil(tok::r_paren, true, false); - OwningStmtResult CatchBody(Actions, true); + StmtResult CatchBody(true); if (Tok.is(tok::l_brace)) CatchBody = ParseCompoundStatementBody(); else @@ -1581,10 +1610,10 @@ Parser::OwningStmtResult Parser::ParseObjCTryStmt(SourceLocation atLoc) { if (CatchBody.isInvalid()) CatchBody = Actions.ActOnNullStmt(Tok.getLocation()); - OwningStmtResult Catch = Actions.ActOnObjCAtCatchStmt(AtCatchFinallyLoc, + StmtResult Catch = Actions.ActOnObjCAtCatchStmt(AtCatchFinallyLoc, RParenLoc, FirstPart, - move(CatchBody)); + CatchBody.take()); if (!Catch.isInvalid()) CatchStmts.push_back(Catch.release()); @@ -1599,7 +1628,7 @@ Parser::OwningStmtResult Parser::ParseObjCTryStmt(SourceLocation atLoc) { ConsumeToken(); // consume finally ParseScope FinallyScope(this, Scope::DeclScope); - OwningStmtResult FinallyBody(Actions, true); + StmtResult FinallyBody(true); if (Tok.is(tok::l_brace)) FinallyBody = ParseCompoundStatementBody(); else @@ -1607,7 +1636,7 @@ Parser::OwningStmtResult Parser::ParseObjCTryStmt(SourceLocation atLoc) { if (FinallyBody.isInvalid()) FinallyBody = Actions.ActOnNullStmt(Tok.getLocation()); FinallyStmt = Actions.ActOnObjCAtFinallyStmt(AtCatchFinallyLoc, - move(FinallyBody)); + FinallyBody.take()); catch_or_finally_seen = true; break; } @@ -1617,19 +1646,18 @@ Parser::OwningStmtResult Parser::ParseObjCTryStmt(SourceLocation atLoc) { return StmtError(); } - return Actions.ActOnObjCAtTryStmt(atLoc, move(TryBody), + return Actions.ActOnObjCAtTryStmt(atLoc, TryBody.take(), move_arg(CatchStmts), - move(FinallyStmt)); + FinallyStmt.take()); } /// objc-method-def: objc-method-proto ';'[opt] '{' body '}' /// -Parser::DeclPtrTy Parser::ParseObjCMethodDefinition() { - DeclPtrTy MDecl = ParseObjCMethodPrototype(ObjCImpDecl); +Decl *Parser::ParseObjCMethodDefinition() { + Decl *MDecl = ParseObjCMethodPrototype(ObjCImpDecl); - PrettyStackTraceActionsDecl CrashInfo(MDecl, Tok.getLocation(), Actions, - PP.getSourceManager(), - "parsing Objective-C method"); + PrettyDeclStackTraceEntry CrashInfo(Actions, MDecl, Tok.getLocation(), + "parsing Objective-C method"); // parse optional ';' if (Tok.is(tok::semi)) { @@ -1649,7 +1677,7 @@ Parser::DeclPtrTy Parser::ParseObjCMethodDefinition() { // If we didn't find the '{', bail out. if (Tok.isNot(tok::l_brace)) - return DeclPtrTy(); + return 0; } SourceLocation BraceLoc = Tok.getLocation(); @@ -1661,7 +1689,7 @@ Parser::DeclPtrTy Parser::ParseObjCMethodDefinition() { // specified Declarator for the method. Actions.ActOnStartOfObjCMethodDef(getCurScope(), MDecl); - OwningStmtResult FnBody(ParseCompoundStatementBody()); + StmtResult FnBody(ParseCompoundStatementBody()); // If the function body could not be parsed, make a bogus compoundstmt. if (FnBody.isInvalid()) @@ -1669,7 +1697,7 @@ Parser::DeclPtrTy Parser::ParseObjCMethodDefinition() { MultiStmtArg(Actions), false); // TODO: Pass argument information. - Actions.ActOnFinishFunctionBody(MDecl, move(FnBody)); + Actions.ActOnFinishFunctionBody(MDecl, FnBody.take()); // Leave the function body scope. BodyScope.Exit(); @@ -1677,7 +1705,7 @@ Parser::DeclPtrTy Parser::ParseObjCMethodDefinition() { return MDecl; } -Parser::OwningStmtResult Parser::ParseObjCAtStatement(SourceLocation AtLoc) { +StmtResult Parser::ParseObjCAtStatement(SourceLocation AtLoc) { if (Tok.is(tok::code_completion)) { Actions.CodeCompleteObjCAtStatement(getCurScope()); ConsumeCodeCompletionToken(); @@ -1693,7 +1721,7 @@ Parser::OwningStmtResult Parser::ParseObjCAtStatement(SourceLocation AtLoc) { if (Tok.isObjCAtKeyword(tok::objc_synchronized)) return ParseObjCSynchronizedStmt(AtLoc); - OwningExprResult Res(ParseExpressionWithLeadingAt(AtLoc)); + ExprResult Res(ParseExpressionWithLeadingAt(AtLoc)); if (Res.isInvalid()) { // If the expression is invalid, skip ahead to the next semicolon. Not // doing this opens us up to the possibility of infinite loops if @@ -1704,10 +1732,10 @@ Parser::OwningStmtResult Parser::ParseObjCAtStatement(SourceLocation AtLoc) { // Otherwise, eat the semicolon. ExpectAndConsume(tok::semi, diag::err_expected_semi_after_expr); - return Actions.ActOnExprStmt(Actions.MakeFullExpr(Res)); + return Actions.ActOnExprStmt(Actions.MakeFullExpr(Res.take())); } -Parser::OwningExprResult Parser::ParseObjCAtExpression(SourceLocation AtLoc) { +ExprResult Parser::ParseObjCAtExpression(SourceLocation AtLoc) { switch (Tok.getKind()) { case tok::code_completion: Actions.CodeCompleteObjCAtExpression(getCurScope()); @@ -1764,7 +1792,7 @@ bool Parser::ParseObjCXXMessageReceiver(bool &IsExpr, void *&TypeOrExpr) { if (!isCXXSimpleTypeSpecifier()) { // objc-receiver: // expression - OwningExprResult Receiver = ParseExpression(); + ExprResult Receiver = ParseExpression(); if (Receiver.isInvalid()) return true; @@ -1793,11 +1821,11 @@ bool Parser::ParseObjCXXMessageReceiver(bool &IsExpr, void *&TypeOrExpr) { // postfix-expression suffix, followed by the (optional) // right-hand side of the binary expression. We have an // instance method. - OwningExprResult Receiver = ParseCXXTypeConstructExpression(DS); + ExprResult Receiver = ParseCXXTypeConstructExpression(DS); if (!Receiver.isInvalid()) - Receiver = ParsePostfixExpressionSuffix(move(Receiver)); + Receiver = ParsePostfixExpressionSuffix(Receiver.take()); if (!Receiver.isInvalid()) - Receiver = ParseRHSOfBinaryExpression(move(Receiver), prec::Comma); + Receiver = ParseRHSOfBinaryExpression(Receiver.take(), prec::Comma); if (Receiver.isInvalid()) return true; @@ -1815,7 +1843,7 @@ bool Parser::ParseObjCXXMessageReceiver(bool &IsExpr, void *&TypeOrExpr) { return true; IsExpr = false; - TypeOrExpr = Type.get(); + TypeOrExpr = Type.get().getAsOpaquePtr(); return false; } @@ -1840,7 +1868,7 @@ bool Parser::isSimpleObjCMessageExpression() { /// class-name /// type-name /// -Parser::OwningExprResult Parser::ParseObjCMessageExpression() { +ExprResult Parser::ParseObjCMessageExpression() { assert(Tok.is(tok::l_square) && "'[' expected"); SourceLocation LBracLoc = ConsumeBracket(); // consume '[' @@ -1860,8 +1888,8 @@ Parser::OwningExprResult Parser::ParseObjCMessageExpression() { // get in Objective-C. if (Tok.is(tok::identifier) && Tok.getIdentifierInfo() == Ident_super && NextToken().isNot(tok::period) && getCurScope()->isInObjcMethodScope()) - return ParseObjCMessageExpressionBody(LBracLoc, ConsumeToken(), 0, - ExprArg(Actions)); + return ParseObjCMessageExpressionBody(LBracLoc, ConsumeToken(), + ParsedType(), 0); // Parse the receiver, which is either a type or an expression. bool IsExpr; @@ -1872,26 +1900,28 @@ Parser::OwningExprResult Parser::ParseObjCMessageExpression() { } if (IsExpr) - return ParseObjCMessageExpressionBody(LBracLoc, SourceLocation(), 0, - OwningExprResult(Actions, TypeOrExpr)); + return ParseObjCMessageExpressionBody(LBracLoc, SourceLocation(), + ParsedType(), + static_cast<Expr*>(TypeOrExpr)); return ParseObjCMessageExpressionBody(LBracLoc, SourceLocation(), - TypeOrExpr, ExprArg(Actions)); + ParsedType::getFromOpaquePtr(TypeOrExpr), + 0); } if (Tok.is(tok::identifier)) { IdentifierInfo *Name = Tok.getIdentifierInfo(); SourceLocation NameLoc = Tok.getLocation(); - TypeTy *ReceiverType; + ParsedType ReceiverType; switch (Actions.getObjCMessageKind(getCurScope(), Name, NameLoc, Name == Ident_super, NextToken().is(tok::period), ReceiverType)) { - case Action::ObjCSuperMessage: - return ParseObjCMessageExpressionBody(LBracLoc, ConsumeToken(), 0, - ExprArg(Actions)); + case Sema::ObjCSuperMessage: + return ParseObjCMessageExpressionBody(LBracLoc, ConsumeToken(), + ParsedType(), 0); - case Action::ObjCClassMessage: + case Sema::ObjCClassMessage: if (!ReceiverType) { SkipUntil(tok::r_square); return ExprError(); @@ -1900,24 +1930,23 @@ Parser::OwningExprResult Parser::ParseObjCMessageExpression() { ConsumeToken(); // the type name return ParseObjCMessageExpressionBody(LBracLoc, SourceLocation(), - ReceiverType, - ExprArg(Actions)); + ReceiverType, 0); - case Action::ObjCInstanceMessage: + case Sema::ObjCInstanceMessage: // Fall through to parse an expression. break; } } // Otherwise, an arbitrary expression can be the receiver of a send. - OwningExprResult Res(ParseExpression()); + ExprResult Res(ParseExpression()); if (Res.isInvalid()) { SkipUntil(tok::r_square); return move(Res); } - return ParseObjCMessageExpressionBody(LBracLoc, SourceLocation(), 0, - move(Res)); + return ParseObjCMessageExpressionBody(LBracLoc, SourceLocation(), + ParsedType(), Res.take()); } /// \brief Parse the remainder of an Objective-C message following the @@ -1958,10 +1987,10 @@ Parser::OwningExprResult Parser::ParseObjCMessageExpression() { /// assignment-expression /// nonempty-expr-list , assignment-expression /// -Parser::OwningExprResult +ExprResult Parser::ParseObjCMessageExpressionBody(SourceLocation LBracLoc, SourceLocation SuperLoc, - TypeTy *ReceiverType, + ParsedType ReceiverType, ExprArg ReceiverExpr) { if (Tok.is(tok::code_completion)) { if (SuperLoc.isValid()) @@ -1969,7 +1998,7 @@ Parser::ParseObjCMessageExpressionBody(SourceLocation LBracLoc, else if (ReceiverType) Actions.CodeCompleteObjCClassMessage(getCurScope(), ReceiverType, 0, 0); else - Actions.CodeCompleteObjCInstanceMessage(getCurScope(), ReceiverExpr.get(), + Actions.CodeCompleteObjCInstanceMessage(getCurScope(), ReceiverExpr, 0, 0); ConsumeCodeCompletionToken(); } @@ -1999,7 +2028,7 @@ Parser::ParseObjCMessageExpressionBody(SourceLocation LBracLoc, ConsumeToken(); // Eat the ':'. /// Parse the expression after ':' - OwningExprResult Res(ParseAssignmentExpression()); + ExprResult Res(ParseAssignmentExpression()); if (Res.isInvalid()) { // We must manually skip to a ']', otherwise the expression skipper will // stop at the ']' when it skips to the ';'. We want it to skip beyond @@ -2022,7 +2051,7 @@ Parser::ParseObjCMessageExpressionBody(SourceLocation LBracLoc, KeyIdents.data(), KeyIdents.size()); else - Actions.CodeCompleteObjCInstanceMessage(getCurScope(), ReceiverExpr.get(), + Actions.CodeCompleteObjCInstanceMessage(getCurScope(), ReceiverExpr, KeyIdents.data(), KeyIdents.size()); ConsumeCodeCompletionToken(); @@ -2038,7 +2067,7 @@ Parser::ParseObjCMessageExpressionBody(SourceLocation LBracLoc, while (Tok.is(tok::comma)) { ConsumeToken(); // Eat the ','. /// Parse the expression after ',' - OwningExprResult Res(ParseAssignmentExpression()); + ExprResult Res(ParseAssignmentExpression()); if (Res.isInvalid()) { // We must manually skip to a ']', otherwise the expression skipper will // stop at the ']' when it skips to the ';'. We want it to skip beyond @@ -2082,24 +2111,24 @@ Parser::ParseObjCMessageExpressionBody(SourceLocation LBracLoc, if (SuperLoc.isValid()) return Actions.ActOnSuperMessage(getCurScope(), SuperLoc, Sel, LBracLoc, SelectorLoc, RBracLoc, - Action::MultiExprArg(Actions, - KeyExprs.take(), - KeyExprs.size())); + MultiExprArg(Actions, + KeyExprs.take(), + KeyExprs.size())); else if (ReceiverType) return Actions.ActOnClassMessage(getCurScope(), ReceiverType, Sel, LBracLoc, SelectorLoc, RBracLoc, - Action::MultiExprArg(Actions, - KeyExprs.take(), - KeyExprs.size())); - return Actions.ActOnInstanceMessage(getCurScope(), move(ReceiverExpr), Sel, + MultiExprArg(Actions, + KeyExprs.take(), + KeyExprs.size())); + return Actions.ActOnInstanceMessage(getCurScope(), ReceiverExpr, Sel, LBracLoc, SelectorLoc, RBracLoc, - Action::MultiExprArg(Actions, - KeyExprs.take(), - KeyExprs.size())); + MultiExprArg(Actions, + KeyExprs.take(), + KeyExprs.size())); } -Parser::OwningExprResult Parser::ParseObjCStringLiteral(SourceLocation AtLoc) { - OwningExprResult Res(ParseStringLiteralExpression()); +ExprResult Parser::ParseObjCStringLiteral(SourceLocation AtLoc) { + ExprResult Res(ParseStringLiteralExpression()); if (Res.isInvalid()) return move(Res); // @"foo" @"bar" is a valid concatenated string. Eat any subsequent string @@ -2117,7 +2146,7 @@ Parser::OwningExprResult Parser::ParseObjCStringLiteral(SourceLocation AtLoc) { if (!isTokenStringLiteral()) return ExprError(Diag(Tok, diag::err_objc_concat_string)); - OwningExprResult Lit(ParseStringLiteralExpression()); + ExprResult Lit(ParseStringLiteralExpression()); if (Lit.isInvalid()) return move(Lit); @@ -2130,7 +2159,7 @@ Parser::OwningExprResult Parser::ParseObjCStringLiteral(SourceLocation AtLoc) { /// objc-encode-expression: /// @encode ( type-name ) -Parser::OwningExprResult +ExprResult Parser::ParseObjCEncodeExpression(SourceLocation AtLoc) { assert(Tok.isObjCAtKeyword(tok::objc_encode) && "Not an @encode expression!"); @@ -2154,7 +2183,7 @@ Parser::ParseObjCEncodeExpression(SourceLocation AtLoc) { /// objc-protocol-expression /// @protocol ( protocol-name ) -Parser::OwningExprResult +ExprResult Parser::ParseObjCProtocolExpression(SourceLocation AtLoc) { SourceLocation ProtoLoc = ConsumeToken(); @@ -2177,8 +2206,7 @@ Parser::ParseObjCProtocolExpression(SourceLocation AtLoc) { /// objc-selector-expression /// @selector '(' objc-keyword-selector ')' -Parser::OwningExprResult -Parser::ParseObjCSelectorExpression(SourceLocation AtLoc) { +ExprResult Parser::ParseObjCSelectorExpression(SourceLocation AtLoc) { SourceLocation SelectorLoc = ConsumeToken(); if (Tok.isNot(tok::l_paren)) @@ -2187,21 +2215,43 @@ Parser::ParseObjCSelectorExpression(SourceLocation AtLoc) { llvm::SmallVector<IdentifierInfo *, 12> KeyIdents; SourceLocation LParenLoc = ConsumeParen(); SourceLocation sLoc; + + if (Tok.is(tok::code_completion)) { + Actions.CodeCompleteObjCSelector(getCurScope(), KeyIdents.data(), + KeyIdents.size()); + ConsumeCodeCompletionToken(); + MatchRHSPunctuation(tok::r_paren, LParenLoc); + return ExprError(); + } + IdentifierInfo *SelIdent = ParseObjCSelectorPiece(sLoc); - if (!SelIdent && Tok.isNot(tok::colon)) // missing selector name. + if (!SelIdent && // missing selector name. + Tok.isNot(tok::colon) && Tok.isNot(tok::coloncolon)) return ExprError(Diag(Tok, diag::err_expected_ident)); KeyIdents.push_back(SelIdent); unsigned nColons = 0; if (Tok.isNot(tok::r_paren)) { while (1) { - if (Tok.isNot(tok::colon)) + if (Tok.is(tok::coloncolon)) { // Handle :: in C++. + ++nColons; + KeyIdents.push_back(0); + } else if (Tok.isNot(tok::colon)) return ExprError(Diag(Tok, diag::err_expected_colon)); - nColons++; + ++nColons; ConsumeToken(); // Eat the ':'. if (Tok.is(tok::r_paren)) break; + + if (Tok.is(tok::code_completion)) { + Actions.CodeCompleteObjCSelector(getCurScope(), KeyIdents.data(), + KeyIdents.size()); + ConsumeCodeCompletionToken(); + MatchRHSPunctuation(tok::r_paren, LParenLoc); + return ExprError(); + } + // Check for another keyword selector. SourceLocation Loc; SelIdent = ParseObjCSelectorPiece(Loc); diff --git a/contrib/llvm/tools/clang/lib/Parse/ParsePragma.cpp b/contrib/llvm/tools/clang/lib/Parse/ParsePragma.cpp index 64a4c16..ddba09a 100644 --- a/contrib/llvm/tools/clang/lib/Parse/ParsePragma.cpp +++ b/contrib/llvm/tools/clang/lib/Parse/ParsePragma.cpp @@ -13,11 +13,63 @@ #include "ParsePragma.h" #include "clang/Parse/ParseDiagnostic.h" -#include "clang/Lex/Preprocessor.h" -#include "clang/Parse/Action.h" #include "clang/Parse/Parser.h" +#include "clang/Lex/Preprocessor.h" using namespace clang; + +// #pragma GCC visibility comes in two variants: +// 'push' '(' [visibility] ')' +// 'pop' +void PragmaGCCVisibilityHandler::HandlePragma(Preprocessor &PP, Token &VisTok) { + SourceLocation VisLoc = VisTok.getLocation(); + + Token Tok; + PP.Lex(Tok); + + const IdentifierInfo *PushPop = Tok.getIdentifierInfo(); + + bool IsPush; + const IdentifierInfo *VisType; + if (PushPop && PushPop->isStr("pop")) { + IsPush = false; + VisType = 0; + } else if (PushPop && PushPop->isStr("push")) { + IsPush = true; + PP.Lex(Tok); + if (Tok.isNot(tok::l_paren)) { + PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen) + << "visibility"; + return; + } + PP.Lex(Tok); + VisType = Tok.getIdentifierInfo(); + if (!VisType) { + PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) + << "visibility"; + return; + } + PP.Lex(Tok); + if (Tok.isNot(tok::r_paren)) { + PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_rparen) + << "visibility"; + return; + } + } else { + PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) + << "visibility"; + return; + } + PP.Lex(Tok); + if (Tok.isNot(tok::eom)) { + PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) + << "visibility"; + return; + } + + Actions.ActOnPragmaVisibility(IsPush, VisType, VisLoc); +} + // #pragma pack(...) comes in the following delicious flavors: // pack '(' [integer] ')' // pack '(' 'show' ')' @@ -32,9 +84,9 @@ void PragmaPackHandler::HandlePragma(Preprocessor &PP, Token &PackTok) { return; } - Action::PragmaPackKind Kind = Action::PPK_Default; + Sema::PragmaPackKind Kind = Sema::PPK_Default; IdentifierInfo *Name = 0; - Action::OwningExprResult Alignment(Actions); + ExprResult Alignment; SourceLocation LParenLoc = Tok.getLocation(); PP.Lex(Tok); if (Tok.is(tok::numeric_constant)) { @@ -46,13 +98,13 @@ void PragmaPackHandler::HandlePragma(Preprocessor &PP, Token &PackTok) { } else if (Tok.is(tok::identifier)) { const IdentifierInfo *II = Tok.getIdentifierInfo(); if (II->isStr("show")) { - Kind = Action::PPK_Show; + Kind = Sema::PPK_Show; PP.Lex(Tok); } else { if (II->isStr("push")) { - Kind = Action::PPK_Push; + Kind = Sema::PPK_Push; } else if (II->isStr("pop")) { - Kind = Action::PPK_Pop; + Kind = Sema::PPK_Pop; } else { PP.Diag(Tok.getLocation(), diag::warn_pragma_pack_invalid_action); return; @@ -110,46 +162,52 @@ void PragmaPackHandler::HandlePragma(Preprocessor &PP, Token &PackTok) { LParenLoc, RParenLoc); } -// #pragma 'options' 'align' '=' {'native','natural','mac68k','power','reset'} -void PragmaOptionsHandler::HandlePragma(Preprocessor &PP, Token &OptionsTok) { - SourceLocation OptionsLoc = OptionsTok.getLocation(); - +// #pragma 'align' '=' {'native','natural','mac68k','power','reset'} +// #pragma 'options 'align' '=' {'native','natural','mac68k','power','reset'} +static void ParseAlignPragma(Sema &Actions, Preprocessor &PP, Token &FirstTok, + bool IsOptions) { Token Tok; - PP.Lex(Tok); - if (Tok.isNot(tok::identifier) || !Tok.getIdentifierInfo()->isStr("align")) { - PP.Diag(Tok.getLocation(), diag::warn_pragma_options_expected_align); - return; + + if (IsOptions) { + PP.Lex(Tok); + if (Tok.isNot(tok::identifier) || + !Tok.getIdentifierInfo()->isStr("align")) { + PP.Diag(Tok.getLocation(), diag::warn_pragma_options_expected_align); + return; + } } PP.Lex(Tok); if (Tok.isNot(tok::equal)) { - PP.Diag(Tok.getLocation(), diag::warn_pragma_options_expected_equal); + PP.Diag(Tok.getLocation(), diag::warn_pragma_align_expected_equal) + << IsOptions; return; } PP.Lex(Tok); if (Tok.isNot(tok::identifier)) { PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier) - << "options"; + << (IsOptions ? "options" : "align"); return; } - Action::PragmaOptionsAlignKind Kind = Action::POAK_Natural; + Sema::PragmaOptionsAlignKind Kind = Sema::POAK_Natural; const IdentifierInfo *II = Tok.getIdentifierInfo(); if (II->isStr("native")) - Kind = Action::POAK_Native; + Kind = Sema::POAK_Native; else if (II->isStr("natural")) - Kind = Action::POAK_Natural; + Kind = Sema::POAK_Natural; else if (II->isStr("packed")) - Kind = Action::POAK_Packed; + Kind = Sema::POAK_Packed; else if (II->isStr("power")) - Kind = Action::POAK_Power; + Kind = Sema::POAK_Power; else if (II->isStr("mac68k")) - Kind = Action::POAK_Mac68k; + Kind = Sema::POAK_Mac68k; else if (II->isStr("reset")) - Kind = Action::POAK_Reset; + Kind = Sema::POAK_Reset; else { - PP.Diag(Tok.getLocation(), diag::warn_pragma_options_invalid_option); + PP.Diag(Tok.getLocation(), diag::warn_pragma_align_invalid_option) + << IsOptions; return; } @@ -157,11 +215,19 @@ void PragmaOptionsHandler::HandlePragma(Preprocessor &PP, Token &OptionsTok) { PP.Lex(Tok); if (Tok.isNot(tok::eom)) { PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol) - << "options"; + << (IsOptions ? "options" : "align"); return; } - Actions.ActOnPragmaOptionsAlign(Kind, OptionsLoc, KindLoc); + Actions.ActOnPragmaOptionsAlign(Kind, FirstTok.getLocation(), KindLoc); +} + +void PragmaAlignHandler::HandlePragma(Preprocessor &PP, Token &AlignTok) { + ParseAlignPragma(Actions, PP, AlignTok, /*IsOptions=*/false); +} + +void PragmaOptionsHandler::HandlePragma(Preprocessor &PP, Token &OptionsTok) { + ParseAlignPragma(Actions, PP, OptionsTok, /*IsOptions=*/true); } // #pragma unused(identifier) diff --git a/contrib/llvm/tools/clang/lib/Parse/ParsePragma.h b/contrib/llvm/tools/clang/lib/Parse/ParsePragma.h index 929ec46..0feaa99 100644 --- a/contrib/llvm/tools/clang/lib/Parse/ParsePragma.h +++ b/contrib/llvm/tools/clang/lib/Parse/ParsePragma.h @@ -17,41 +17,58 @@ #include "clang/Lex/Pragma.h" namespace clang { - class Action; + class Sema; class Parser; +class PragmaAlignHandler : public PragmaHandler { + Sema &Actions; +public: + explicit PragmaAlignHandler(Sema &A) : PragmaHandler("align"), Actions(A) {} + + virtual void HandlePragma(Preprocessor &PP, Token &FirstToken); +}; + +class PragmaGCCVisibilityHandler : public PragmaHandler { + Sema &Actions; +public: + explicit PragmaGCCVisibilityHandler(Sema &A) : PragmaHandler("visibility"), + Actions(A) {} + + virtual void HandlePragma(Preprocessor &PP, Token &FirstToken); +}; + class PragmaOptionsHandler : public PragmaHandler { - Action &Actions; + Sema &Actions; public: - explicit PragmaOptionsHandler(Action &A) : PragmaHandler("options"), - Actions(A) {} + explicit PragmaOptionsHandler(Sema &A) : PragmaHandler("options"), + Actions(A) {} virtual void HandlePragma(Preprocessor &PP, Token &FirstToken); }; class PragmaPackHandler : public PragmaHandler { - Action &Actions; + Sema &Actions; public: - explicit PragmaPackHandler(Action &A) : PragmaHandler("pack"), - Actions(A) {} + explicit PragmaPackHandler(Sema &A) : PragmaHandler("pack"), + Actions(A) {} virtual void HandlePragma(Preprocessor &PP, Token &FirstToken); }; class PragmaUnusedHandler : public PragmaHandler { - Action &Actions; + Sema &Actions; Parser &parser; public: - PragmaUnusedHandler(Action &A, Parser& p) + PragmaUnusedHandler(Sema &A, Parser& p) : PragmaHandler("unused"), Actions(A), parser(p) {} virtual void HandlePragma(Preprocessor &PP, Token &FirstToken); }; class PragmaWeakHandler : public PragmaHandler { - Action &Actions; + Sema &Actions; public: - explicit PragmaWeakHandler(Action &A) + explicit PragmaWeakHandler(Sema &A) : PragmaHandler("weak"), Actions(A) {} virtual void HandlePragma(Preprocessor &PP, Token &FirstToken); diff --git a/contrib/llvm/tools/clang/lib/Parse/ParseStmt.cpp b/contrib/llvm/tools/clang/lib/Parse/ParseStmt.cpp index c908ed9..6c240e6 100644 --- a/contrib/llvm/tools/clang/lib/Parse/ParseStmt.cpp +++ b/contrib/llvm/tools/clang/lib/Parse/ParseStmt.cpp @@ -14,8 +14,9 @@ #include "clang/Parse/Parser.h" #include "RAIIObjectsForParser.h" -#include "clang/Parse/DeclSpec.h" -#include "clang/Parse/Scope.h" +#include "clang/Sema/DeclSpec.h" +#include "clang/Sema/PrettyDeclStackTrace.h" +#include "clang/Sema/Scope.h" #include "clang/Basic/Diagnostic.h" #include "clang/Basic/PrettyStackTrace.h" #include "clang/Basic/SourceManager.h" @@ -73,10 +74,10 @@ using namespace clang; /// [OBC] '@' 'throw' expression ';' /// [OBC] '@' 'throw' ';' /// -Parser::OwningStmtResult +StmtResult Parser::ParseStatementOrDeclaration(bool OnlyStatement) { const char *SemiError = 0; - OwningStmtResult Res(Actions); + StmtResult Res; ParenBraceBracketBalancer BalancerRAIIObj(*this); @@ -98,7 +99,7 @@ Parser::ParseStatementOrDeclaration(bool OnlyStatement) { } case tok::code_completion: - Actions.CodeCompleteOrdinaryName(getCurScope(), Action::CCC_Statement); + Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Statement); ConsumeCodeCompletionToken(); return ParseStatementOrDeclaration(OnlyStatement); @@ -125,7 +126,7 @@ Parser::ParseStatementOrDeclaration(bool OnlyStatement) { // FIXME: Use the attributes // expression[opt] ';' - OwningExprResult Expr(ParseExpression()); + ExprResult Expr(ParseExpression()); if (Expr.isInvalid()) { // If the expression is invalid, skip ahead to the next semicolon or '}'. // Not doing this opens us up to the possibility of infinite loops if @@ -137,7 +138,7 @@ Parser::ParseStatementOrDeclaration(bool OnlyStatement) { } // Otherwise, eat the semicolon. ExpectAndConsume(tok::semi, diag::err_expected_semi_after_expr); - return Actions.ActOnExprStmt(Actions.MakeFullExpr(Expr)); + return Actions.ActOnExprStmt(Actions.MakeFullExpr(Expr.get())); } case tok::kw_case: // C99 6.8.1: labeled-statement @@ -217,7 +218,7 @@ Parser::ParseStatementOrDeclaration(bool OnlyStatement) { /// identifier ':' statement /// [GNU] identifier ':' attributes[opt] statement /// -Parser::OwningStmtResult Parser::ParseLabeledStatement(AttributeList *Attr) { +StmtResult Parser::ParseLabeledStatement(AttributeList *Attr) { assert(Tok.is(tok::identifier) && Tok.getIdentifierInfo() && "Not an identifier!"); @@ -234,7 +235,7 @@ Parser::OwningStmtResult Parser::ParseLabeledStatement(AttributeList *Attr) { if (Tok.is(tok::kw___attribute)) AttrList.reset(addAttributeLists(AttrList.take(), ParseGNUAttributes())); - OwningStmtResult SubStmt(ParseStatement()); + StmtResult SubStmt(ParseStatement()); // Broken substmt shouldn't prevent the label from being added to the AST. if (SubStmt.isInvalid()) @@ -243,7 +244,7 @@ Parser::OwningStmtResult Parser::ParseLabeledStatement(AttributeList *Attr) { // FIXME: use attributes? return Actions.ActOnLabelStmt(IdentTok.getLocation(), IdentTok.getIdentifierInfo(), - ColonLoc, move(SubStmt)); + ColonLoc, SubStmt.get()); } /// ParseCaseStatement @@ -251,7 +252,7 @@ Parser::OwningStmtResult Parser::ParseLabeledStatement(AttributeList *Attr) { /// 'case' constant-expression ':' statement /// [GNU] 'case' constant-expression '...' constant-expression ':' statement /// -Parser::OwningStmtResult Parser::ParseCaseStatement(AttributeList *Attr) { +StmtResult Parser::ParseCaseStatement(AttributeList *Attr) { assert(Tok.is(tok::kw_case) && "Not a case stmt!"); // FIXME: Use attributes? delete Attr; @@ -272,7 +273,7 @@ Parser::OwningStmtResult Parser::ParseCaseStatement(AttributeList *Attr) { // TopLevelCase - This is the highest level we have parsed. 'case 1' in the // example above. - OwningStmtResult TopLevelCase(Actions, true); + StmtResult TopLevelCase(true); // DeepestParsedCaseStmt - This is the deepest statement we have parsed, which // gets updated each time a new case is parsed, and whose body is unset so @@ -293,7 +294,7 @@ Parser::OwningStmtResult Parser::ParseCaseStatement(AttributeList *Attr) { /// expression. ColonProtectionRAIIObject ColonProtection(*this); - OwningExprResult LHS(ParseConstantExpression()); + ExprResult LHS(ParseConstantExpression()); if (LHS.isInvalid()) { SkipUntil(tok::colon); return StmtError(); @@ -301,7 +302,7 @@ Parser::OwningStmtResult Parser::ParseCaseStatement(AttributeList *Attr) { // GNU case range extension. SourceLocation DotDotDotLoc; - OwningExprResult RHS(Actions); + ExprResult RHS; if (Tok.is(tok::ellipsis)) { Diag(Tok, diag::ext_gnu_case_range); DotDotDotLoc = ConsumeToken(); @@ -323,9 +324,9 @@ Parser::OwningStmtResult Parser::ParseCaseStatement(AttributeList *Attr) { SourceLocation ColonLoc = ConsumeToken(); - OwningStmtResult Case = - Actions.ActOnCaseStmt(CaseLoc, move(LHS), DotDotDotLoc, - move(RHS), ColonLoc); + StmtResult Case = + Actions.ActOnCaseStmt(CaseLoc, LHS.get(), DotDotDotLoc, + RHS.get(), ColonLoc); // If we had a sema error parsing this case, then just ignore it and // continue parsing the sub-stmt. @@ -336,11 +337,11 @@ Parser::OwningStmtResult Parser::ParseCaseStatement(AttributeList *Attr) { } else { // If this is the first case statement we parsed, it becomes TopLevelCase. // Otherwise we link it into the current chain. - StmtTy *NextDeepest = Case.get(); + Stmt *NextDeepest = Case.get(); if (TopLevelCase.isInvalid()) TopLevelCase = move(Case); else - Actions.ActOnCaseStmtBody(DeepestParsedCaseStmt, move(Case)); + Actions.ActOnCaseStmtBody(DeepestParsedCaseStmt, Case.get()); DeepestParsedCaseStmt = NextDeepest; } @@ -350,7 +351,7 @@ Parser::OwningStmtResult Parser::ParseCaseStatement(AttributeList *Attr) { assert(!TopLevelCase.isInvalid() && "Should have parsed at least one case!"); // If we found a non-case statement, start by parsing it. - OwningStmtResult SubStmt(Actions); + StmtResult SubStmt; if (Tok.isNot(tok::r_brace)) { SubStmt = ParseStatement(); @@ -367,7 +368,7 @@ Parser::OwningStmtResult Parser::ParseCaseStatement(AttributeList *Attr) { SubStmt = Actions.ActOnNullStmt(SourceLocation()); // Install the body into the most deeply-nested case. - Actions.ActOnCaseStmtBody(DeepestParsedCaseStmt, move(SubStmt)); + Actions.ActOnCaseStmtBody(DeepestParsedCaseStmt, SubStmt.get()); // Return the top level parsed statement tree. return move(TopLevelCase); @@ -378,7 +379,7 @@ Parser::OwningStmtResult Parser::ParseCaseStatement(AttributeList *Attr) { /// 'default' ':' statement /// Note that this does not parse the 'statement' at the end. /// -Parser::OwningStmtResult Parser::ParseDefaultStatement(AttributeList *Attr) { +StmtResult Parser::ParseDefaultStatement(AttributeList *Attr) { //FIXME: Use attributes? delete Attr; @@ -399,12 +400,12 @@ Parser::OwningStmtResult Parser::ParseDefaultStatement(AttributeList *Attr) { return StmtError(); } - OwningStmtResult SubStmt(ParseStatement()); + StmtResult SubStmt(ParseStatement()); if (SubStmt.isInvalid()) return StmtError(); return Actions.ActOnDefaultStmt(DefaultLoc, ColonLoc, - move(SubStmt), getCurScope()); + SubStmt.get(), getCurScope()); } @@ -435,7 +436,7 @@ Parser::OwningStmtResult Parser::ParseDefaultStatement(AttributeList *Attr) { /// [OMP] barrier-directive /// [OMP] flush-directive /// -Parser::OwningStmtResult Parser::ParseCompoundStatement(AttributeList *Attr, +StmtResult Parser::ParseCompoundStatement(AttributeList *Attr, bool isStmtExpr) { //FIXME: Use attributes? delete Attr; @@ -455,7 +456,7 @@ Parser::OwningStmtResult Parser::ParseCompoundStatement(AttributeList *Attr, /// ActOnCompoundStmt action. This expects the '{' to be the current token, and /// consume the '}' at the end of the block. It does not manipulate the scope /// stack. -Parser::OwningStmtResult Parser::ParseCompoundStatementBody(bool isStmtExpr) { +StmtResult Parser::ParseCompoundStatementBody(bool isStmtExpr) { PrettyStackTraceLoc CrashInfo(PP.getSourceManager(), Tok.getLocation(), "in compound statement ('{}')"); @@ -468,7 +469,7 @@ Parser::OwningStmtResult Parser::ParseCompoundStatementBody(bool isStmtExpr) { typedef StmtVector StmtsTy; StmtsTy Stmts(Actions); while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) { - OwningStmtResult R(Actions); + StmtResult R; if (Tok.isNot(tok::kw___extension__)) { R = ParseStatementOrDeclaration(false); } else { @@ -496,7 +497,7 @@ Parser::OwningStmtResult Parser::ParseCompoundStatementBody(bool isStmtExpr) { R = Actions.ActOnDeclStmt(Res, DeclStart, DeclEnd); } else { // Otherwise this was a unary __extension__ marker. - OwningExprResult Res(ParseExpressionWithLeadingExtension(ExtLoc)); + ExprResult Res(ParseExpressionWithLeadingExtension(ExtLoc)); if (Res.isInvalid()) { SkipUntil(tok::semi); @@ -507,7 +508,7 @@ Parser::OwningStmtResult Parser::ParseCompoundStatementBody(bool isStmtExpr) { // Eat the semicolon at the end of stmt and convert the expr into a // statement. ExpectAndConsume(tok::semi, diag::err_expected_semi_after_expr); - R = Actions.ActOnExprStmt(Actions.MakeFullExpr(Res)); + R = Actions.ActOnExprStmt(Actions.MakeFullExpr(Res.get())); } } @@ -518,6 +519,7 @@ Parser::OwningStmtResult Parser::ParseCompoundStatementBody(bool isStmtExpr) { // We broke out of the while loop because we found a '}' or EOF. if (Tok.isNot(tok::r_brace)) { Diag(Tok, diag::err_expected_rbrace); + Diag(LBraceLoc, diag::note_matching) << "{"; return StmtError(); } @@ -537,8 +539,8 @@ Parser::OwningStmtResult Parser::ParseCompoundStatementBody(bool isStmtExpr) { /// should try to recover harder. It returns false if the condition is /// successfully parsed. Note that a successful parse can still have semantic /// errors in the condition. -bool Parser::ParseParenExprOrCondition(OwningExprResult &ExprResult, - DeclPtrTy &DeclResult, +bool Parser::ParseParenExprOrCondition(ExprResult &ExprResult, + Decl *&DeclResult, SourceLocation Loc, bool ConvertToBoolean) { bool ParseError = false; @@ -549,18 +551,18 @@ bool Parser::ParseParenExprOrCondition(OwningExprResult &ExprResult, ConvertToBoolean); else { ExprResult = ParseExpression(); - DeclResult = DeclPtrTy(); + DeclResult = 0; // If required, convert to a boolean value. if (!ExprResult.isInvalid() && ConvertToBoolean) ExprResult - = Actions.ActOnBooleanCondition(getCurScope(), Loc, move(ExprResult)); + = Actions.ActOnBooleanCondition(getCurScope(), Loc, ExprResult.get()); } // If the parser was confused by the condition and we don't have a ')', try to // recover by skipping ahead to a semi and bailing out. If condexp is // semantically invalid but we have well formed code, keep going. - if (ExprResult.isInvalid() && !DeclResult.get() && Tok.isNot(tok::r_paren)) { + if (ExprResult.isInvalid() && !DeclResult && Tok.isNot(tok::r_paren)) { SkipUntil(tok::semi); // Skipping may have stopped if it found the containing ')'. If so, we can // continue parsing the if statement. @@ -581,7 +583,7 @@ bool Parser::ParseParenExprOrCondition(OwningExprResult &ExprResult, /// [C++] 'if' '(' condition ')' statement /// [C++] 'if' '(' condition ')' statement 'else' statement /// -Parser::OwningStmtResult Parser::ParseIfStatement(AttributeList *Attr) { +StmtResult Parser::ParseIfStatement(AttributeList *Attr) { // FIXME: Use attributes? delete Attr; @@ -611,12 +613,12 @@ Parser::OwningStmtResult Parser::ParseIfStatement(AttributeList *Attr) { ParseScope IfScope(this, Scope::DeclScope | Scope::ControlScope, C99orCXX); // Parse the condition. - OwningExprResult CondExp(Actions); - DeclPtrTy CondVar; + ExprResult CondExp; + Decl *CondVar = 0; if (ParseParenExprOrCondition(CondExp, CondVar, IfLoc, true)) return StmtError(); - FullExprArg FullCondExp(Actions.MakeFullExpr(CondExp)); + FullExprArg FullCondExp(Actions.MakeFullExpr(CondExp.get())); // C99 6.8.4p3 - In C99, the body of the if statement is a scope, even if // there is no compound stmt. C90 does not have this clause. We only do this @@ -641,7 +643,7 @@ Parser::OwningStmtResult Parser::ParseIfStatement(AttributeList *Attr) { // Read the 'then' stmt. SourceLocation ThenStmtLoc = Tok.getLocation(); - OwningStmtResult ThenStmt(ParseStatement()); + StmtResult ThenStmt(ParseStatement()); // Pop the 'if' scope if needed. InnerScope.Exit(); @@ -649,7 +651,7 @@ Parser::OwningStmtResult Parser::ParseIfStatement(AttributeList *Attr) { // If it has an else, parse it. SourceLocation ElseLoc; SourceLocation ElseStmtLoc; - OwningStmtResult ElseStmt(Actions); + StmtResult ElseStmt; if (Tok.is(tok::kw_else)) { ElseLoc = ConsumeToken(); @@ -667,13 +669,7 @@ Parser::OwningStmtResult Parser::ParseIfStatement(AttributeList *Attr) { ParseScope InnerScope(this, Scope::DeclScope, C99orCXX && Tok.isNot(tok::l_brace)); - // Regardless of whether or not InnerScope actually pushed a scope, set the - // ElseScope flag for the innermost scope so we can diagnose use of the if - // condition variable in C++. - unsigned OldFlags = getCurScope()->getFlags(); - getCurScope()->setFlags(OldFlags | Scope::ElseScope); ElseStmt = ParseStatement(); - getCurScope()->setFlags(OldFlags); // Pop the 'else' scope if needed. InnerScope.Exit(); @@ -683,7 +679,7 @@ Parser::OwningStmtResult Parser::ParseIfStatement(AttributeList *Attr) { // If the condition was invalid, discard the if statement. We could recover // better by replacing it with a valid expr, but don't do that yet. - if (CondExp.isInvalid() && !CondVar.get()) + if (CondExp.isInvalid() && !CondVar) return StmtError(); // If the then or else stmt is invalid and the other is valid (and present), @@ -702,15 +698,15 @@ Parser::OwningStmtResult Parser::ParseIfStatement(AttributeList *Attr) { if (ElseStmt.isInvalid()) ElseStmt = Actions.ActOnNullStmt(ElseStmtLoc); - return Actions.ActOnIfStmt(IfLoc, FullCondExp, CondVar, move(ThenStmt), - ElseLoc, move(ElseStmt)); + return Actions.ActOnIfStmt(IfLoc, FullCondExp, CondVar, ThenStmt.get(), + ElseLoc, ElseStmt.get()); } /// ParseSwitchStatement /// switch-statement: /// 'switch' '(' expression ')' statement /// [C++] 'switch' '(' condition ')' statement -Parser::OwningStmtResult Parser::ParseSwitchStatement(AttributeList *Attr) { +StmtResult Parser::ParseSwitchStatement(AttributeList *Attr) { // FIXME: Use attributes? delete Attr; @@ -743,13 +739,13 @@ Parser::OwningStmtResult Parser::ParseSwitchStatement(AttributeList *Attr) { ParseScope SwitchScope(this, ScopeFlags); // Parse the condition. - OwningExprResult Cond(Actions); - DeclPtrTy CondVar; + ExprResult Cond; + Decl *CondVar = 0; if (ParseParenExprOrCondition(Cond, CondVar, SwitchLoc, false)) return StmtError(); - OwningStmtResult Switch - = Actions.ActOnStartOfSwitchStmt(SwitchLoc, move(Cond), CondVar); + StmtResult Switch + = Actions.ActOnStartOfSwitchStmt(SwitchLoc, Cond.get(), CondVar); if (Switch.isInvalid()) { // Skip the switch body. @@ -779,7 +775,7 @@ Parser::OwningStmtResult Parser::ParseSwitchStatement(AttributeList *Attr) { C99orCXX && Tok.isNot(tok::l_brace)); // Read the body statement. - OwningStmtResult Body(ParseStatement()); + StmtResult Body(ParseStatement()); // Pop the scopes. InnerScope.Exit(); @@ -789,14 +785,14 @@ Parser::OwningStmtResult Parser::ParseSwitchStatement(AttributeList *Attr) { // FIXME: Remove the case statement list from the Switch statement. Body = Actions.ActOnNullStmt(Tok.getLocation()); - return Actions.ActOnFinishSwitchStmt(SwitchLoc, move(Switch), move(Body)); + return Actions.ActOnFinishSwitchStmt(SwitchLoc, Switch.get(), Body.get()); } /// ParseWhileStatement /// while-statement: [C99 6.8.5.1] /// 'while' '(' expression ')' statement /// [C++] 'while' '(' condition ')' statement -Parser::OwningStmtResult Parser::ParseWhileStatement(AttributeList *Attr) { +StmtResult Parser::ParseWhileStatement(AttributeList *Attr) { // FIXME: Use attributes? delete Attr; @@ -833,12 +829,12 @@ Parser::OwningStmtResult Parser::ParseWhileStatement(AttributeList *Attr) { ParseScope WhileScope(this, ScopeFlags); // Parse the condition. - OwningExprResult Cond(Actions); - DeclPtrTy CondVar; + ExprResult Cond; + Decl *CondVar = 0; if (ParseParenExprOrCondition(Cond, CondVar, WhileLoc, true)) return StmtError(); - FullExprArg FullCond(Actions.MakeFullExpr(Cond)); + FullExprArg FullCond(Actions.MakeFullExpr(Cond.get())); // C99 6.8.5p5 - In C99, the body of the if statement is a scope, even if // there is no compound stmt. C90 does not have this clause. We only do this @@ -855,23 +851,23 @@ Parser::OwningStmtResult Parser::ParseWhileStatement(AttributeList *Attr) { C99orCXX && Tok.isNot(tok::l_brace)); // Read the body statement. - OwningStmtResult Body(ParseStatement()); + StmtResult Body(ParseStatement()); // Pop the body scope if needed. InnerScope.Exit(); WhileScope.Exit(); - if ((Cond.isInvalid() && !CondVar.get()) || Body.isInvalid()) + if ((Cond.isInvalid() && !CondVar) || Body.isInvalid()) return StmtError(); - return Actions.ActOnWhileStmt(WhileLoc, FullCond, CondVar, move(Body)); + return Actions.ActOnWhileStmt(WhileLoc, FullCond, CondVar, Body.get()); } /// ParseDoStatement /// do-statement: [C99 6.8.5.2] /// 'do' statement 'while' '(' expression ')' ';' /// Note: this lets the caller parse the end ';'. -Parser::OwningStmtResult Parser::ParseDoStatement(AttributeList *Attr) { +StmtResult Parser::ParseDoStatement(AttributeList *Attr) { // FIXME: Use attributes? delete Attr; @@ -901,7 +897,7 @@ Parser::OwningStmtResult Parser::ParseDoStatement(AttributeList *Attr) { Tok.isNot(tok::l_brace)); // Read the body statement. - OwningStmtResult Body(ParseStatement()); + StmtResult Body(ParseStatement()); // Pop the body scope if needed. InnerScope.Exit(); @@ -924,15 +920,15 @@ Parser::OwningStmtResult Parser::ParseDoStatement(AttributeList *Attr) { // Parse the parenthesized condition. SourceLocation LPLoc = ConsumeParen(); - OwningExprResult Cond = ParseExpression(); + ExprResult Cond = ParseExpression(); SourceLocation RPLoc = MatchRHSPunctuation(tok::r_paren, LPLoc); DoScope.Exit(); if (Cond.isInvalid() || Body.isInvalid()) return StmtError(); - return Actions.ActOnDoStmt(DoLoc, move(Body), WhileLoc, LPLoc, - move(Cond), RPLoc); + return Actions.ActOnDoStmt(DoLoc, Body.get(), WhileLoc, LPLoc, + Cond.get(), RPLoc); } /// ParseForStatement @@ -948,7 +944,7 @@ Parser::OwningStmtResult Parser::ParseDoStatement(AttributeList *Attr) { /// [C++] expression-statement /// [C++] simple-declaration /// -Parser::OwningStmtResult Parser::ParseForStatement(AttributeList *Attr) { +StmtResult Parser::ParseForStatement(AttributeList *Attr) { // FIXME: Use attributes? delete Attr; @@ -988,20 +984,20 @@ Parser::OwningStmtResult Parser::ParseForStatement(AttributeList *Attr) { ParseScope ForScope(this, ScopeFlags); SourceLocation LParenLoc = ConsumeParen(); - OwningExprResult Value(Actions); + ExprResult Value; bool ForEach = false; - OwningStmtResult FirstPart(Actions); + StmtResult FirstPart; bool SecondPartIsInvalid = false; FullExprArg SecondPart(Actions); - OwningExprResult Collection(Actions); + ExprResult Collection; FullExprArg ThirdPart(Actions); - DeclPtrTy SecondVar; + Decl *SecondVar = 0; if (Tok.is(tok::code_completion)) { Actions.CodeCompleteOrdinaryName(getCurScope(), - C99orCXXorObjC? Action::CCC_ForInit - : Action::CCC_Expression); + C99orCXXorObjC? Sema::PCC_ForInit + : Sema::PCC_Expression); ConsumeCodeCompletionToken(); } @@ -1029,6 +1025,11 @@ Parser::OwningStmtResult Parser::ParseForStatement(AttributeList *Attr) { Actions.ActOnForEachDeclStmt(DG); // ObjC: for (id x in expr) ConsumeToken(); // consume 'in' + + if (Tok.is(tok::code_completion)) { + Actions.CodeCompleteObjCForCollection(getCurScope(), DG); + ConsumeCodeCompletionToken(); + } Collection = ParseExpression(); } else { Diag(Tok, diag::err_expected_semi_for); @@ -1039,12 +1040,17 @@ Parser::OwningStmtResult Parser::ParseForStatement(AttributeList *Attr) { // Turn the expression into a stmt. if (!Value.isInvalid()) - FirstPart = Actions.ActOnExprStmt(Actions.MakeFullExpr(Value)); + FirstPart = Actions.ActOnExprStmt(Actions.MakeFullExpr(Value.get())); if (Tok.is(tok::semi)) { ConsumeToken(); } else if ((ForEach = isTokIdentifier_in())) { ConsumeToken(); // consume 'in' + + if (Tok.is(tok::code_completion)) { + Actions.CodeCompleteObjCForCollection(getCurScope(), DeclGroupPtrTy()); + ConsumeCodeCompletionToken(); + } Collection = ParseExpression(); } else { if (!Value.isInvalid()) Diag(Tok, diag::err_expected_semi_for); @@ -1052,36 +1058,36 @@ Parser::OwningStmtResult Parser::ParseForStatement(AttributeList *Attr) { } } if (!ForEach) { - assert(!SecondPart->get() && "Shouldn't have a second expression yet."); + assert(!SecondPart.get() && "Shouldn't have a second expression yet."); // Parse the second part of the for specifier. if (Tok.is(tok::semi)) { // for (...;; // no second part. } else { - OwningExprResult Second(Actions); + ExprResult Second; if (getLang().CPlusPlus) ParseCXXCondition(Second, SecondVar, ForLoc, true); else { Second = ParseExpression(); if (!Second.isInvalid()) Second = Actions.ActOnBooleanCondition(getCurScope(), ForLoc, - move(Second)); + Second.get()); } SecondPartIsInvalid = Second.isInvalid(); - SecondPart = Actions.MakeFullExpr(Second); + SecondPart = Actions.MakeFullExpr(Second.get()); } if (Tok.is(tok::semi)) { ConsumeToken(); } else { - if (!SecondPartIsInvalid || SecondVar.get()) + if (!SecondPartIsInvalid || SecondVar) Diag(Tok, diag::err_expected_semi_for); SkipUntil(tok::semi); } // Parse the third part of the for specifier. if (Tok.isNot(tok::r_paren)) { // for (...;...;) - OwningExprResult Third = ParseExpression(); - ThirdPart = Actions.MakeFullExpr(Third); + ExprResult Third = ParseExpression(); + ThirdPart = Actions.MakeFullExpr(Third.take()); } } // Match the ')'. @@ -1102,7 +1108,7 @@ Parser::OwningStmtResult Parser::ParseForStatement(AttributeList *Attr) { C99orCXXorObjC && Tok.isNot(tok::l_brace)); // Read the body statement. - OwningStmtResult Body(ParseStatement()); + StmtResult Body(ParseStatement()); // Pop the body scope if needed. InnerScope.Exit(); @@ -1114,14 +1120,14 @@ Parser::OwningStmtResult Parser::ParseForStatement(AttributeList *Attr) { return StmtError(); if (!ForEach) - return Actions.ActOnForStmt(ForLoc, LParenLoc, move(FirstPart), SecondPart, - SecondVar, ThirdPart, RParenLoc, move(Body)); + return Actions.ActOnForStmt(ForLoc, LParenLoc, FirstPart.take(), SecondPart, + SecondVar, ThirdPart, RParenLoc, Body.take()); // FIXME: It isn't clear how to communicate the late destruction of // C++ temporaries used to create the collection. - return Actions.ActOnObjCForCollectionStmt(ForLoc, LParenLoc, move(FirstPart), - move(Collection), RParenLoc, - move(Body)); + return Actions.ActOnObjCForCollectionStmt(ForLoc, LParenLoc, FirstPart.take(), + Collection.take(), RParenLoc, + Body.take()); } /// ParseGotoStatement @@ -1131,14 +1137,14 @@ Parser::OwningStmtResult Parser::ParseForStatement(AttributeList *Attr) { /// /// Note: this lets the caller parse the end ';'. /// -Parser::OwningStmtResult Parser::ParseGotoStatement(AttributeList *Attr) { +StmtResult Parser::ParseGotoStatement(AttributeList *Attr) { // FIXME: Use attributes? delete Attr; assert(Tok.is(tok::kw_goto) && "Not a goto stmt!"); SourceLocation GotoLoc = ConsumeToken(); // eat the 'goto'. - OwningStmtResult Res(Actions); + StmtResult Res; if (Tok.is(tok::identifier)) { Res = Actions.ActOnGotoStmt(GotoLoc, Tok.getLocation(), Tok.getIdentifierInfo()); @@ -1147,12 +1153,12 @@ Parser::OwningStmtResult Parser::ParseGotoStatement(AttributeList *Attr) { // GNU indirect goto extension. Diag(Tok, diag::ext_gnu_indirect_goto); SourceLocation StarLoc = ConsumeToken(); - OwningExprResult R(ParseExpression()); + ExprResult R(ParseExpression()); if (R.isInvalid()) { // Skip to the semicolon, but don't consume it. SkipUntil(tok::semi, false, true); return StmtError(); } - Res = Actions.ActOnIndirectGotoStmt(GotoLoc, StarLoc, move(R)); + Res = Actions.ActOnIndirectGotoStmt(GotoLoc, StarLoc, R.take()); } else { Diag(Tok, diag::err_expected_ident); return StmtError(); @@ -1167,7 +1173,7 @@ Parser::OwningStmtResult Parser::ParseGotoStatement(AttributeList *Attr) { /// /// Note: this lets the caller parse the end ';'. /// -Parser::OwningStmtResult Parser::ParseContinueStatement(AttributeList *Attr) { +StmtResult Parser::ParseContinueStatement(AttributeList *Attr) { // FIXME: Use attributes? delete Attr; @@ -1181,7 +1187,7 @@ Parser::OwningStmtResult Parser::ParseContinueStatement(AttributeList *Attr) { /// /// Note: this lets the caller parse the end ';'. /// -Parser::OwningStmtResult Parser::ParseBreakStatement(AttributeList *Attr) { +StmtResult Parser::ParseBreakStatement(AttributeList *Attr) { // FIXME: Use attributes? delete Attr; @@ -1192,14 +1198,14 @@ Parser::OwningStmtResult Parser::ParseBreakStatement(AttributeList *Attr) { /// ParseReturnStatement /// jump-statement: /// 'return' expression[opt] ';' -Parser::OwningStmtResult Parser::ParseReturnStatement(AttributeList *Attr) { +StmtResult Parser::ParseReturnStatement(AttributeList *Attr) { // FIXME: Use attributes? delete Attr; assert(Tok.is(tok::kw_return) && "Not a return stmt!"); SourceLocation ReturnLoc = ConsumeToken(); // eat the 'return'. - OwningExprResult R(Actions); + ExprResult R; if (Tok.isNot(tok::semi)) { if (Tok.is(tok::code_completion)) { Actions.CodeCompleteReturn(getCurScope()); @@ -1214,12 +1220,12 @@ Parser::OwningStmtResult Parser::ParseReturnStatement(AttributeList *Attr) { return StmtError(); } } - return Actions.ActOnReturnStmt(ReturnLoc, move(R)); + return Actions.ActOnReturnStmt(ReturnLoc, R.take()); } /// FuzzyParseMicrosoftAsmStatement. When -fms-extensions is enabled, this /// routine is called to skip/ignore tokens that comprise the MS asm statement. -Parser::OwningStmtResult Parser::FuzzyParseMicrosoftAsmStatement() { +StmtResult Parser::FuzzyParseMicrosoftAsmStatement() { if (Tok.is(tok::l_brace)) { unsigned short savedBraceCount = BraceCount; do { @@ -1240,16 +1246,16 @@ Parser::OwningStmtResult Parser::FuzzyParseMicrosoftAsmStatement() { } Token t; t.setKind(tok::string_literal); - t.setLiteralData("\"FIXME: not done\""); + t.setLiteralData("\"/*FIXME: not done*/\""); t.clearFlag(Token::NeedsCleaning); - t.setLength(17); - OwningExprResult AsmString(Actions.ActOnStringLiteral(&t, 1)); + t.setLength(21); + ExprResult AsmString(Actions.ActOnStringLiteral(&t, 1)); ExprVector Constraints(Actions); ExprVector Exprs(Actions); ExprVector Clobbers(Actions); return Actions.ActOnAsmStmt(Tok.getLocation(), true, true, 0, 0, 0, move_arg(Constraints), move_arg(Exprs), - move(AsmString), move_arg(Clobbers), + AsmString.take(), move_arg(Clobbers), Tok.getLocation(), true); } @@ -1280,7 +1286,7 @@ Parser::OwningStmtResult Parser::FuzzyParseMicrosoftAsmStatement() { /// assembly-instruction ';'[opt] /// assembly-instruction-list ';' assembly-instruction ';'[opt] /// -Parser::OwningStmtResult Parser::ParseAsmStatement(bool &msAsm) { +StmtResult Parser::ParseAsmStatement(bool &msAsm) { assert(Tok.is(tok::kw_asm) && "Not an asm stmt"); SourceLocation AsmLoc = ConsumeToken(); @@ -1307,7 +1313,7 @@ Parser::OwningStmtResult Parser::ParseAsmStatement(bool &msAsm) { } Loc = ConsumeParen(); - OwningExprResult AsmString(ParseAsmStringLiteral()); + ExprResult AsmString(ParseAsmStringLiteral()); if (AsmString.isInvalid()) return StmtError(); @@ -1322,7 +1328,7 @@ Parser::OwningStmtResult Parser::ParseAsmStatement(bool &msAsm) { return Actions.ActOnAsmStmt(AsmLoc, /*isSimple*/ true, isVolatile, /*NumOutputs*/ 0, /*NumInputs*/ 0, 0, move_arg(Constraints), move_arg(Exprs), - move(AsmString), move_arg(Clobbers), + AsmString.take(), move_arg(Clobbers), RParenLoc); } @@ -1367,17 +1373,19 @@ Parser::OwningStmtResult Parser::ParseAsmStatement(bool &msAsm) { if (!AteExtraColon) ConsumeToken(); - // Parse the asm-string list for clobbers. - while (1) { - OwningExprResult Clobber(ParseAsmStringLiteral()); + // Parse the asm-string list for clobbers if present. + if (Tok.isNot(tok::r_paren)) { + while (1) { + ExprResult Clobber(ParseAsmStringLiteral()); - if (Clobber.isInvalid()) - break; + if (Clobber.isInvalid()) + break; - Clobbers.push_back(Clobber.release()); + Clobbers.push_back(Clobber.release()); - if (Tok.isNot(tok::comma)) break; - ConsumeToken(); + if (Tok.isNot(tok::comma)) break; + ConsumeToken(); + } } } @@ -1385,7 +1393,7 @@ Parser::OwningStmtResult Parser::ParseAsmStatement(bool &msAsm) { return Actions.ActOnAsmStmt(AsmLoc, false, isVolatile, NumOutputs, NumInputs, Names.data(), move_arg(Constraints), move_arg(Exprs), - move(AsmString), move_arg(Clobbers), + AsmString.take(), move_arg(Clobbers), RParenLoc); } @@ -1428,7 +1436,7 @@ bool Parser::ParseAsmOperandsOpt(llvm::SmallVectorImpl<IdentifierInfo *> &Names, } else Names.push_back(0); - OwningExprResult Constraint(ParseAsmStringLiteral()); + ExprResult Constraint(ParseAsmStringLiteral()); if (Constraint.isInvalid()) { SkipUntil(tok::r_paren); return true; @@ -1443,7 +1451,7 @@ bool Parser::ParseAsmOperandsOpt(llvm::SmallVectorImpl<IdentifierInfo *> &Names, // Read the parenthesized expression. SourceLocation OpenLoc = ConsumeParen(); - OwningExprResult Res(ParseExpression()); + ExprResult Res(ParseExpression()); MatchRHSPunctuation(tok::r_paren, OpenLoc); if (Res.isInvalid()) { SkipUntil(tok::r_paren); @@ -1458,25 +1466,24 @@ bool Parser::ParseAsmOperandsOpt(llvm::SmallVectorImpl<IdentifierInfo *> &Names, return true; } -Parser::DeclPtrTy Parser::ParseFunctionStatementBody(DeclPtrTy Decl) { +Decl *Parser::ParseFunctionStatementBody(Decl *Decl) { assert(Tok.is(tok::l_brace)); SourceLocation LBraceLoc = Tok.getLocation(); - PrettyStackTraceActionsDecl CrashInfo(Decl, LBraceLoc, Actions, - PP.getSourceManager(), - "parsing function body"); + PrettyDeclStackTraceEntry CrashInfo(Actions, Decl, LBraceLoc, + "parsing function body"); // Do not enter a scope for the brace, as the arguments are in the same scope // (the function body) as the body itself. Instead, just read the statement // list and put it into a CompoundStmt for safe keeping. - OwningStmtResult FnBody(ParseCompoundStatementBody()); + StmtResult FnBody(ParseCompoundStatementBody()); // If the function body could not be parsed, make a bogus compoundstmt. if (FnBody.isInvalid()) FnBody = Actions.ActOnCompoundStmt(LBraceLoc, LBraceLoc, MultiStmtArg(Actions), false); - return Actions.ActOnFinishFunctionBody(Decl, move(FnBody)); + return Actions.ActOnFinishFunctionBody(Decl, FnBody.take()); } /// ParseFunctionTryBlock - Parse a C++ function-try-block. @@ -1484,27 +1491,26 @@ Parser::DeclPtrTy Parser::ParseFunctionStatementBody(DeclPtrTy Decl) { /// function-try-block: /// 'try' ctor-initializer[opt] compound-statement handler-seq /// -Parser::DeclPtrTy Parser::ParseFunctionTryBlock(DeclPtrTy Decl) { +Decl *Parser::ParseFunctionTryBlock(Decl *Decl) { assert(Tok.is(tok::kw_try) && "Expected 'try'"); SourceLocation TryLoc = ConsumeToken(); - PrettyStackTraceActionsDecl CrashInfo(Decl, TryLoc, Actions, - PP.getSourceManager(), - "parsing function try block"); + PrettyDeclStackTraceEntry CrashInfo(Actions, Decl, TryLoc, + "parsing function try block"); // Constructor initializer list? if (Tok.is(tok::colon)) ParseConstructorInitializer(Decl); SourceLocation LBraceLoc = Tok.getLocation(); - OwningStmtResult FnBody(ParseCXXTryBlockCommon(TryLoc)); + StmtResult FnBody(ParseCXXTryBlockCommon(TryLoc)); // If we failed to parse the try-catch, we just give the function an empty // compound statement as the body. if (FnBody.isInvalid()) FnBody = Actions.ActOnCompoundStmt(LBraceLoc, LBraceLoc, MultiStmtArg(Actions), false); - return Actions.ActOnFinishFunctionBody(Decl, move(FnBody)); + return Actions.ActOnFinishFunctionBody(Decl, FnBody.take()); } /// ParseCXXTryBlock - Parse a C++ try-block. @@ -1512,7 +1518,7 @@ Parser::DeclPtrTy Parser::ParseFunctionTryBlock(DeclPtrTy Decl) { /// try-block: /// 'try' compound-statement handler-seq /// -Parser::OwningStmtResult Parser::ParseCXXTryBlock(AttributeList* Attr) { +StmtResult Parser::ParseCXXTryBlock(AttributeList* Attr) { // FIXME: Add attributes? delete Attr; @@ -1534,11 +1540,11 @@ Parser::OwningStmtResult Parser::ParseCXXTryBlock(AttributeList* Attr) { /// handler-seq: /// handler handler-seq[opt] /// -Parser::OwningStmtResult Parser::ParseCXXTryBlockCommon(SourceLocation TryLoc) { +StmtResult Parser::ParseCXXTryBlockCommon(SourceLocation TryLoc) { if (Tok.isNot(tok::l_brace)) return StmtError(Diag(Tok, diag::err_expected_lbrace)); // FIXME: Possible draft standard bug: attribute-specifier should be allowed? - OwningStmtResult TryBlock(ParseCompoundStatement(0)); + StmtResult TryBlock(ParseCompoundStatement(0)); if (TryBlock.isInvalid()) return move(TryBlock); @@ -1551,7 +1557,7 @@ Parser::OwningStmtResult Parser::ParseCXXTryBlockCommon(SourceLocation TryLoc) { if (Tok.isNot(tok::kw_catch)) return StmtError(Diag(Tok, diag::err_expected_catch)); while (Tok.is(tok::kw_catch)) { - OwningStmtResult Handler(ParseCXXCatchBlock()); + StmtResult Handler(ParseCXXCatchBlock()); if (!Handler.isInvalid()) Handlers.push_back(Handler.release()); } @@ -1560,7 +1566,7 @@ Parser::OwningStmtResult Parser::ParseCXXTryBlockCommon(SourceLocation TryLoc) { if (Handlers.empty()) return StmtError(); - return Actions.ActOnCXXTryBlock(TryLoc, move(TryBlock), move_arg(Handlers)); + return Actions.ActOnCXXTryBlock(TryLoc, TryBlock.take(), move_arg(Handlers)); } /// ParseCXXCatchBlock - Parse a C++ catch block, called handler in the standard @@ -1574,7 +1580,7 @@ Parser::OwningStmtResult Parser::ParseCXXTryBlockCommon(SourceLocation TryLoc) { /// type-specifier-seq /// '...' /// -Parser::OwningStmtResult Parser::ParseCXXCatchBlock() { +StmtResult Parser::ParseCXXCatchBlock() { assert(Tok.is(tok::kw_catch) && "Expected 'catch'"); SourceLocation CatchLoc = ConsumeToken(); @@ -1590,7 +1596,7 @@ Parser::OwningStmtResult Parser::ParseCXXCatchBlock() { // exception-declaration is equivalent to '...' or a parameter-declaration // without default arguments. - DeclPtrTy ExceptionDecl; + Decl *ExceptionDecl = 0; if (Tok.isNot(tok::ellipsis)) { DeclSpec DS; if (ParseCXXTypeSpecifierSeq(DS)) @@ -1608,9 +1614,9 @@ Parser::OwningStmtResult Parser::ParseCXXCatchBlock() { return StmtError(Diag(Tok, diag::err_expected_lbrace)); // FIXME: Possible draft standard bug: attribute-specifier should be allowed? - OwningStmtResult Block(ParseCompoundStatement(0)); + StmtResult Block(ParseCompoundStatement(0)); if (Block.isInvalid()) return move(Block); - return Actions.ActOnCXXCatchBlock(CatchLoc, ExceptionDecl, move(Block)); + return Actions.ActOnCXXCatchBlock(CatchLoc, ExceptionDecl, Block.take()); } diff --git a/contrib/llvm/tools/clang/lib/Parse/ParseTemplate.cpp b/contrib/llvm/tools/clang/lib/Parse/ParseTemplate.cpp index e1aaf91..dfb4785 100644 --- a/contrib/llvm/tools/clang/lib/Parse/ParseTemplate.cpp +++ b/contrib/llvm/tools/clang/lib/Parse/ParseTemplate.cpp @@ -13,15 +13,15 @@ #include "clang/Parse/Parser.h" #include "clang/Parse/ParseDiagnostic.h" -#include "clang/Parse/DeclSpec.h" -#include "clang/Parse/Scope.h" -#include "clang/Parse/Template.h" +#include "clang/Sema/DeclSpec.h" +#include "clang/Sema/ParsedTemplate.h" +#include "clang/Sema/Scope.h" #include "RAIIObjectsForParser.h" using namespace clang; /// \brief Parse a template declaration, explicit instantiation, or /// explicit specialization. -Parser::DeclPtrTy +Decl * Parser::ParseDeclarationStartingWithTemplate(unsigned Context, SourceLocation &DeclEnd, AccessSpecifier AS) { @@ -70,7 +70,7 @@ namespace { /// /// explicit-specialization: [ C++ temp.expl.spec] /// 'template' '<' '>' declaration -Parser::DeclPtrTy +Decl * Parser::ParseTemplateDeclarationOrSpecialization(unsigned Context, SourceLocation &DeclEnd, AccessSpecifier AS) { @@ -80,6 +80,10 @@ Parser::ParseTemplateDeclarationOrSpecialization(unsigned Context, // Enter template-parameter scope. ParseScope TemplateParmScope(this, Scope::TemplateParamScope); + // Tell the action that names should be checked in the context of + // the declaration to come. + ParsingDeclRAIIObject ParsingTemplateParams(*this); + // Parse multiple levels of template headers within this template // parameter scope, e.g., // @@ -118,19 +122,19 @@ Parser::ParseTemplateDeclarationOrSpecialization(unsigned Context, TemplateLoc = ConsumeToken(); } else { Diag(Tok.getLocation(), diag::err_expected_template); - return DeclPtrTy(); + return 0; } // Parse the '<' template-parameter-list '>' SourceLocation LAngleLoc, RAngleLoc; - TemplateParameterList TemplateParams; + llvm::SmallVector<Decl*, 4> TemplateParams; if (ParseTemplateParameters(Depth, TemplateParams, LAngleLoc, RAngleLoc)) { // Skip until the semi-colon or a }. SkipUntil(tok::r_brace, true, true); if (Tok.is(tok::semi)) ConsumeToken(); - return DeclPtrTy(); + return 0; } ParamLists.push_back( @@ -152,6 +156,7 @@ Parser::ParseTemplateDeclarationOrSpecialization(unsigned Context, ParsedTemplateInfo(&ParamLists, isSpecialization, LastParamListWasEmpty), + ParsingTemplateParams, DeclEnd, AS); } @@ -175,10 +180,11 @@ Parser::ParseTemplateDeclarationOrSpecialization(unsigned Context, /// declaration. Will be AS_none for namespace-scope declarations. /// /// \returns the new declaration. -Parser::DeclPtrTy +Decl * Parser::ParseSingleDeclarationAfterTemplate( unsigned Context, const ParsedTemplateInfo &TemplateInfo, + ParsingDeclRAIIObject &DiagsFromTParams, SourceLocation &DeclEnd, AccessSpecifier AS) { assert(TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate && @@ -186,12 +192,13 @@ Parser::ParseSingleDeclarationAfterTemplate( if (Context == Declarator::MemberContext) { // We are parsing a member template. - ParseCXXClassMemberDeclaration(AS, TemplateInfo); - return DeclPtrTy::make((void*)0); + ParseCXXClassMemberDeclaration(AS, TemplateInfo, &DiagsFromTParams); + return 0; } - // Parse the declaration specifiers. - ParsingDeclSpec DS(*this); + // Parse the declaration specifiers, stealing the accumulated + // diagnostics from the template parameters. + ParsingDeclSpec DS(DiagsFromTParams); if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier()) DS.AddAttributes(ParseCXX0XAttributes().AttrList); @@ -201,7 +208,7 @@ Parser::ParseSingleDeclarationAfterTemplate( if (Tok.is(tok::semi)) { DeclEnd = ConsumeToken(); - DeclPtrTy Decl = Actions.ParsedFreeStandingDeclSpec(getCurScope(), AS, DS); + Decl *Decl = Actions.ParsedFreeStandingDeclSpec(getCurScope(), AS, DS); DS.complete(Decl); return Decl; } @@ -215,14 +222,14 @@ Parser::ParseSingleDeclarationAfterTemplate( SkipUntil(tok::r_brace, true, true); if (Tok.is(tok::semi)) ConsumeToken(); - return DeclPtrTy(); + return 0; } // If we have a declaration or declarator list, handle it. if (isDeclarationAfterDeclarator()) { // Parse this declaration. - DeclPtrTy ThisDecl = ParseDeclarationAfterDeclarator(DeclaratorInfo, - TemplateInfo); + Decl *ThisDecl = ParseDeclarationAfterDeclarator(DeclaratorInfo, + TemplateInfo); if (Tok.is(tok::comma)) { Diag(Tok, diag::err_multiple_template_declarators) @@ -251,7 +258,7 @@ Parser::ParseSingleDeclarationAfterTemplate( } else { SkipUntil(tok::semi); } - return DeclPtrTy(); + return 0; } return ParseFunctionDefinition(DeclaratorInfo, TemplateInfo); } @@ -261,7 +268,7 @@ Parser::ParseSingleDeclarationAfterTemplate( else Diag(Tok, diag::err_invalid_token_after_toplevel_declarator); SkipUntil(tok::semi); - return DeclPtrTy(); + return 0; } /// ParseTemplateParameters - Parses a template-parameter-list enclosed in @@ -274,7 +281,7 @@ Parser::ParseSingleDeclarationAfterTemplate( /// /// \returns true if an error occurred, false otherwise. bool Parser::ParseTemplateParameters(unsigned Depth, - TemplateParameterList &TemplateParams, + llvm::SmallVectorImpl<Decl*> &TemplateParams, SourceLocation &LAngleLoc, SourceLocation &RAngleLoc) { // Get the template parameter list. @@ -307,9 +314,9 @@ bool Parser::ParseTemplateParameters(unsigned Depth, /// template-parameter-list ',' template-parameter bool Parser::ParseTemplateParameterList(unsigned Depth, - TemplateParameterList &TemplateParams) { + llvm::SmallVectorImpl<Decl*> &TemplateParams) { while (1) { - if (DeclPtrTy TmpParam + if (Decl *TmpParam = ParseTemplateParameter(Depth, TemplateParams.size())) { TemplateParams.push_back(TmpParam); } else { @@ -414,8 +421,7 @@ bool Parser::isStartOfTemplateTypeParameter() { /// 'typename' identifier[opt] '=' type-id /// 'template' ...[opt][C++0x] '<' template-parameter-list '>' 'class' identifier[opt] /// 'template' '<' template-parameter-list '>' 'class' identifier[opt] = id-expression -Parser::DeclPtrTy -Parser::ParseTemplateParameter(unsigned Depth, unsigned Position) { +Decl *Parser::ParseTemplateParameter(unsigned Depth, unsigned Position) { if (isStartOfTemplateTypeParameter()) return ParseTypeParameter(Depth, Position); @@ -437,7 +443,7 @@ Parser::ParseTemplateParameter(unsigned Depth, unsigned Position) { /// 'class' identifier[opt] '=' type-id /// 'typename' ...[opt][C++0x] identifier[opt] /// 'typename' identifier[opt] '=' type-id -Parser::DeclPtrTy Parser::ParseTypeParameter(unsigned Depth, unsigned Position){ +Decl *Parser::ParseTypeParameter(unsigned Depth, unsigned Position) { assert((Tok.is(tok::kw_class) || Tok.is(tok::kw_typename)) && "A type-parameter starts with 'class' or 'typename'"); @@ -468,14 +474,14 @@ Parser::DeclPtrTy Parser::ParseTypeParameter(unsigned Depth, unsigned Position){ // don't consume this token. } else { Diag(Tok.getLocation(), diag::err_expected_ident); - return DeclPtrTy(); + return 0; } // Grab a default argument (if available). // Per C++0x [basic.scope.pdecl]p9, we parse the default argument before // we introduce the type parameter into the local scope. SourceLocation EqualLoc; - TypeTy *DefaultArg = 0; + ParsedType DefaultArg; if (Tok.is(tok::equal)) { EqualLoc = ConsumeToken(); DefaultArg = ParseTypeName().get(); @@ -492,19 +498,19 @@ Parser::DeclPtrTy Parser::ParseTypeParameter(unsigned Depth, unsigned Position){ /// type-parameter: [C++ temp.param] /// 'template' '<' template-parameter-list '>' 'class' identifier[opt] /// 'template' '<' template-parameter-list '>' 'class' identifier[opt] = id-expression -Parser::DeclPtrTy +Decl * Parser::ParseTemplateTemplateParameter(unsigned Depth, unsigned Position) { assert(Tok.is(tok::kw_template) && "Expected 'template' keyword"); // Handle the template <...> part. SourceLocation TemplateLoc = ConsumeToken(); - TemplateParameterList TemplateParams; + llvm::SmallVector<Decl*,8> TemplateParams; SourceLocation LAngleLoc, RAngleLoc; { ParseScope TemplateParmScope(this, Scope::TemplateParamScope); if (ParseTemplateParameters(Depth + 1, TemplateParams, LAngleLoc, RAngleLoc)) { - return DeclPtrTy(); + return 0; } } @@ -513,7 +519,7 @@ Parser::ParseTemplateTemplateParameter(unsigned Depth, unsigned Position) { if (!Tok.is(tok::kw_class)) { Diag(Tok.getLocation(), diag::err_expected_class_before) << PP.getSpelling(Tok); - return DeclPtrTy(); + return 0; } SourceLocation ClassLoc = ConsumeToken(); @@ -528,7 +534,7 @@ Parser::ParseTemplateTemplateParameter(unsigned Depth, unsigned Position) { // don't consume this token. } else { Diag(Tok.getLocation(), diag::err_expected_ident); - return DeclPtrTy(); + return 0; } TemplateParamsTy *ParamList = @@ -568,7 +574,7 @@ Parser::ParseTemplateTemplateParameter(unsigned Depth, unsigned Position) { /// template-parameter: /// ... /// parameter-declaration -Parser::DeclPtrTy +Decl * Parser::ParseNonTypeTemplateParameter(unsigned Depth, unsigned Position) { SourceLocation StartLoc = Tok.getLocation(); @@ -581,21 +587,21 @@ Parser::ParseNonTypeTemplateParameter(unsigned Depth, unsigned Position) { // Parse this as a typename. Declarator ParamDecl(DS, Declarator::TemplateParamContext); ParseDeclarator(ParamDecl); - if (DS.getTypeSpecType() == DeclSpec::TST_unspecified && !DS.getTypeRep()) { + if (DS.getTypeSpecType() == DeclSpec::TST_unspecified) { // This probably shouldn't happen - and it's more of a Sema thing, but // basically we didn't parse the type name because we couldn't associate // it with an AST node. we should just skip to the comma or greater. // TODO: This is currently a placeholder for some kind of Sema Error. Diag(Tok.getLocation(), diag::err_parse_error); SkipUntil(tok::comma, tok::greater, true, true); - return DeclPtrTy(); + return 0; } // If there is a default value, parse it. // Per C++0x [basic.scope.pdecl]p9, we parse the default argument before // we introduce the template parameter into the local scope. SourceLocation EqualLoc; - OwningExprResult DefaultArg(Actions); + ExprResult DefaultArg; if (Tok.is(tok::equal)) { EqualLoc = ConsumeToken(); @@ -614,7 +620,7 @@ Parser::ParseNonTypeTemplateParameter(unsigned Depth, unsigned Position) { // Create the parameter. return Actions.ActOnNonTypeTemplateParameter(getCurScope(), ParamDecl, Depth, Position, EqualLoc, - move(DefaultArg)); + DefaultArg.take()); } /// \brief Parses a template-id that after the template name has @@ -766,7 +772,7 @@ bool Parser::AnnotateTemplateIdToken(TemplateTy Template, TemplateNameKind TNK, // Build the annotation token. if (TNK == TNK_Type_template && AllowTypeAnnotation) { - Action::TypeResult Type + TypeResult Type = Actions.ActOnTemplateIdType(Template, TemplateNameLoc, LAngleLoc, TemplateArgsPtr, RAngleLoc); @@ -779,7 +785,7 @@ bool Parser::AnnotateTemplateIdToken(TemplateTy Template, TemplateNameKind TNK, } Tok.setKind(tok::annot_typename); - Tok.setAnnotationValue(Type.get()); + setTypeAnnotation(Tok, Type.get()); if (SS && SS->isNotEmpty()) Tok.setLocation(SS->getBeginLoc()); else if (TemplateKWLoc.isValid()) @@ -800,7 +806,7 @@ bool Parser::AnnotateTemplateIdToken(TemplateTy Template, TemplateNameKind TNK, TemplateId->Name = 0; TemplateId->Operator = TemplateName.OperatorFunctionId.Operator; } - TemplateId->Template = Template.getAs<void*>(); + TemplateId->Template = Template; TemplateId->Kind = TNK; TemplateId->LAngleLoc = LAngleLoc; TemplateId->RAngleLoc = RAngleLoc; @@ -844,15 +850,15 @@ void Parser::AnnotateTemplateIdTokenAsType(const CXXScopeSpec *SS) { TemplateId->getTemplateArgs(), TemplateId->NumArgs); - Action::TypeResult Type - = Actions.ActOnTemplateIdType(TemplateTy::make(TemplateId->Template), + TypeResult Type + = Actions.ActOnTemplateIdType(TemplateId->Template, TemplateId->TemplateNameLoc, TemplateId->LAngleLoc, TemplateArgsPtr, TemplateId->RAngleLoc); // Create the new "type" annotation token. Tok.setKind(tok::annot_typename); - Tok.setAnnotationValue(Type.isInvalid()? 0 : Type.get()); + setTypeAnnotation(Tok, Type.isInvalid() ? ParsedType() : Type.get()); if (SS && SS->isNotEmpty()) // it was a C++ qualified type name. Tok.setLocation(SS->getBeginLoc()); // End location stays the same @@ -887,7 +893,7 @@ ParsedTemplateArgument Parser::ParseTemplateTemplateArgument() { // followed by a token that terminates a template argument, such as ',', // '>', or (in some cases) '>>'. CXXScopeSpec SS; // nested-name-specifier, if present - ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, + ParseOptionalCXXScopeSpecifier(SS, ParsedType(), /*EnteringContext=*/false); if (SS.isSet() && Tok.is(tok::kw_template)) { @@ -906,8 +912,9 @@ ParsedTemplateArgument Parser::ParseTemplateTemplateArgument() { // template argument. TemplateTy Template; if (isEndOfTemplateArgument(Tok) && - Actions.ActOnDependentTemplateName(getCurScope(), TemplateLoc, SS, Name, - /*ObjectType=*/0, + Actions.ActOnDependentTemplateName(getCurScope(), TemplateLoc, + SS, Name, + /*ObjectType=*/ ParsedType(), /*EnteringContext=*/false, Template)) return ParsedTemplateArgument(SS, Template, Name.StartLocation); @@ -921,8 +928,10 @@ ParsedTemplateArgument Parser::ParseTemplateTemplateArgument() { if (isEndOfTemplateArgument(Tok)) { bool MemberOfUnknownSpecialization; - TemplateNameKind TNK = Actions.isTemplateName(getCurScope(), SS, Name, - /*ObjectType=*/0, + TemplateNameKind TNK = Actions.isTemplateName(getCurScope(), SS, + /*hasTemplateKeyword=*/false, + Name, + /*ObjectType=*/ ParsedType(), /*EnteringContext=*/false, Template, MemberOfUnknownSpecialization); @@ -957,7 +966,8 @@ ParsedTemplateArgument Parser::ParseTemplateArgument() { if (TypeArg.isInvalid()) return ParsedTemplateArgument(); - return ParsedTemplateArgument(ParsedTemplateArgument::Type, TypeArg.get(), + return ParsedTemplateArgument(ParsedTemplateArgument::Type, + TypeArg.get().getAsOpaquePtr(), Loc); } @@ -978,7 +988,7 @@ ParsedTemplateArgument Parser::ParseTemplateArgument() { // Parse a non-type template argument. SourceLocation Loc = Tok.getLocation(); - OwningExprResult ExprArg = ParseConstantExpression(); + ExprResult ExprArg = ParseConstantExpression(); if (ExprArg.isInvalid() || !ExprArg.get()) return ParsedTemplateArgument(); @@ -1053,12 +1063,15 @@ Parser::ParseTemplateArgumentList(TemplateArgList &TemplateArgs) { /// 'extern' [opt] 'template' declaration /// /// Note that the 'extern' is a GNU extension and C++0x feature. -Parser::DeclPtrTy -Parser::ParseExplicitInstantiation(SourceLocation ExternLoc, - SourceLocation TemplateLoc, - SourceLocation &DeclEnd) { +Decl *Parser::ParseExplicitInstantiation(SourceLocation ExternLoc, + SourceLocation TemplateLoc, + SourceLocation &DeclEnd) { + // This isn't really required here. + ParsingDeclRAIIObject ParsingTemplateParams(*this); + return ParseSingleDeclarationAfterTemplate(Declarator::FileContext, ParsedTemplateInfo(ExternLoc, TemplateLoc), + ParsingTemplateParams, DeclEnd, AS_none); } diff --git a/contrib/llvm/tools/clang/lib/Parse/ParseTentative.cpp b/contrib/llvm/tools/clang/lib/Parse/ParseTentative.cpp index 5e64e61..c22d99f 100644 --- a/contrib/llvm/tools/clang/lib/Parse/ParseTentative.cpp +++ b/contrib/llvm/tools/clang/lib/Parse/ParseTentative.cpp @@ -14,7 +14,7 @@ #include "clang/Parse/Parser.h" #include "clang/Parse/ParseDiagnostic.h" -#include "clang/Parse/Template.h" +#include "clang/Sema/ParsedTemplate.h" using namespace clang; /// isCXXDeclarationStatement - C++-specialized function that disambiguates @@ -172,14 +172,6 @@ Parser::TPResult Parser::TryParseSimpleDeclaration() { /// '{' '}' /// Parser::TPResult Parser::TryParseInitDeclaratorList() { - // GCC only examines the first declarator for disambiguation: - // i.e: - // int(x), ++x; // GCC regards it as ill-formed declaration. - // - // Comeau and MSVC will regard the above statement as correct expression. - // Clang examines all of the declarators and also regards the above statement - // as correct expression. - while (1) { // declarator TPResult TPR = TryParseDeclarator(false/*mayBeAbstract*/); @@ -196,15 +188,22 @@ Parser::TPResult Parser::TryParseInitDeclaratorList() { ConsumeParen(); if (!SkipUntil(tok::r_paren)) return TPResult::Error(); - } else if (Tok.is(tok::equal)) { - // MSVC won't examine the rest of declarators if '=' is encountered, it - // will conclude that it is a declaration. - // Comeau and Clang will examine the rest of declarators. - // Note that "int(x) = {0}, ++x;" will be interpreted as ill-formed - // expression. + } else if (Tok.is(tok::equal) || isTokIdentifier_in()) { + // MSVC and g++ won't examine the rest of declarators if '=' is + // encountered; they just conclude that we have a declaration. + // EDG parses the initializer completely, which is the proper behavior + // for this case. // - // Parse through the initializer-clause. - SkipUntil(tok::comma, true/*StopAtSemi*/, true/*DontConsume*/); + // At present, Clang follows MSVC and g++, since the parser does not have + // the ability to parse an expression fully without recording the + // results of that parse. + // Also allow 'in' after on objective-c declaration as in: + // for (int (^b)(void) in array). Ideally this should be done in the + // context of parsing for-init-statement of a foreach statement only. But, + // in any other context 'in' is invalid after a declaration and parser + // issues the error regardless of outcome of this decision. + // FIXME. Change if above assumption does not hold. + return TPResult::True(); } if (Tok.isNot(tok::comma)) @@ -758,6 +757,10 @@ Parser::TPResult Parser::isCXXDeclarationSpecifier() { case tok::kw___ptr64: case tok::kw___forceinline: return TPResult::True(); + + // Borland + case tok::kw___pascal: + return TPResult::True(); // AltiVec case tok::kw___vector: diff --git a/contrib/llvm/tools/clang/lib/Parse/Parser.cpp b/contrib/llvm/tools/clang/lib/Parse/Parser.cpp index ac78f11..44bd0fb 100644 --- a/contrib/llvm/tools/clang/lib/Parse/Parser.cpp +++ b/contrib/llvm/tools/clang/lib/Parse/Parser.cpp @@ -13,15 +13,15 @@ #include "clang/Parse/Parser.h" #include "clang/Parse/ParseDiagnostic.h" -#include "clang/Parse/DeclSpec.h" -#include "clang/Parse/Scope.h" -#include "clang/Parse/Template.h" +#include "clang/Sema/DeclSpec.h" +#include "clang/Sema/Scope.h" +#include "clang/Sema/ParsedTemplate.h" #include "llvm/Support/raw_ostream.h" #include "RAIIObjectsForParser.h" #include "ParsePragma.h" using namespace clang; -Parser::Parser(Preprocessor &pp, Action &actions) +Parser::Parser(Preprocessor &pp, Sema &actions) : CrashInfo(*this), PP(pp), Actions(actions), Diags(PP.getDiagnostics()), GreaterThanIsOperator(true), ColonIsSacred(false), TemplateParameterDepth(0) { @@ -29,10 +29,16 @@ Parser::Parser(Preprocessor &pp, Action &actions) Actions.CurScope = 0; NumCachedScopes = 0; ParenCount = BracketCount = BraceCount = 0; - ObjCImpDecl = DeclPtrTy(); + ObjCImpDecl = 0; // Add #pragma handlers. These are removed and destroyed in the // destructor. + AlignHandler.reset(new PragmaAlignHandler(actions)); + PP.AddPragmaHandler(AlignHandler.get()); + + GCCVisibilityHandler.reset(new PragmaGCCVisibilityHandler(actions)); + PP.AddPragmaHandler("GCC", GCCVisibilityHandler.get()); + OptionsHandler.reset(new PragmaOptionsHandler(actions)); PP.AddPragmaHandler(OptionsHandler.get()); @@ -44,6 +50,8 @@ Parser::Parser(Preprocessor &pp, Action &actions) WeakHandler.reset(new PragmaWeakHandler(actions)); PP.AddPragmaHandler(WeakHandler.get()); + + PP.setCodeCompletionHandler(*this); } /// If a crash happens while the parser is active, print out a line indicating @@ -298,6 +306,10 @@ Parser::~Parser() { delete ScopeCache[i]; // Remove the pragma handlers we installed. + PP.RemovePragmaHandler(AlignHandler.get()); + AlignHandler.reset(); + PP.RemovePragmaHandler("GCC", GCCVisibilityHandler.get()); + GCCVisibilityHandler.reset(); PP.RemovePragmaHandler(OptionsHandler.get()); OptionsHandler.reset(); PP.RemovePragmaHandler(PackHandler.get()); @@ -306,18 +318,19 @@ Parser::~Parser() { UnusedHandler.reset(); PP.RemovePragmaHandler(WeakHandler.get()); WeakHandler.reset(); + PP.clearCodeCompletionHandler(); } /// Initialize - Warm up the parser. /// void Parser::Initialize() { - // Prime the lexer look-ahead. - ConsumeToken(); - // Create the translation unit scope. Install it as the current scope. assert(getCurScope() == 0 && "A scope is already active?"); EnterScope(Scope::DeclScope); - Actions.ActOnTranslationUnitScope(Tok.getLocation(), getCurScope()); + Actions.ActOnTranslationUnitScope(getCurScope()); + + // Prime the lexer look-ahead. + ConsumeToken(); if (Tok.is(tok::eof) && !getLang().CPlusPlus) // Empty source file is an extension in C @@ -395,10 +408,11 @@ void Parser::ParseTranslationUnit() { /// ';' /// /// [C++0x/GNU] 'extern' 'template' declaration -Parser::DeclGroupPtrTy Parser::ParseExternalDeclaration(CXX0XAttributeList Attr) { +Parser::DeclGroupPtrTy Parser::ParseExternalDeclaration(CXX0XAttributeList Attr, + ParsingDeclSpec *DS) { ParenBraceBracketBalancer BalancerRAIIObj(*this); - DeclPtrTy SingleDecl; + Decl *SingleDecl = 0; switch (Tok.getKind()) { case tok::semi: if (!getLang().CPlusPlus0x) @@ -426,14 +440,14 @@ Parser::DeclGroupPtrTy Parser::ParseExternalDeclaration(CXX0XAttributeList Attr) Diag(Attr.Range.getBegin(), diag::err_attributes_not_allowed) << Attr.Range; - OwningExprResult Result(ParseSimpleAsm()); + ExprResult Result(ParseSimpleAsm()); ExpectAndConsume(tok::semi, diag::err_expected_semi_after, "top-level asm block"); if (Result.isInvalid()) return DeclGroupPtrTy(); - SingleDecl = Actions.ActOnFileScopeAsmDecl(Tok.getLocation(), move(Result)); + SingleDecl = Actions.ActOnFileScopeAsmDecl(Tok.getLocation(), Result.get()); break; } case tok::at: @@ -453,8 +467,8 @@ Parser::DeclGroupPtrTy Parser::ParseExternalDeclaration(CXX0XAttributeList Attr) break; case tok::code_completion: Actions.CodeCompleteOrdinaryName(getCurScope(), - ObjCImpDecl? Action::CCC_ObjCImplementation - : Action::CCC_Namespace); + ObjCImpDecl? Sema::PCC_ObjCImplementation + : Sema::PCC_Namespace); ConsumeCodeCompletionToken(); return ParseExternalDeclaration(Attr); case tok::kw_using: @@ -468,6 +482,15 @@ Parser::DeclGroupPtrTy Parser::ParseExternalDeclaration(CXX0XAttributeList Attr) SourceLocation DeclEnd; return ParseDeclaration(Declarator::FileContext, DeclEnd, Attr); } + + case tok::kw_inline: + if (getLang().CPlusPlus && NextToken().is(tok::kw_namespace)) { + // Inline namespaces. Allowed as an extension even in C++03. + SourceLocation DeclEnd; + return ParseDeclaration(Declarator::FileContext, DeclEnd, Attr); + } + goto dont_know; + case tok::kw_extern: if (getLang().CPlusPlus && NextToken().is(tok::kw_template)) { // Extern templates @@ -477,14 +500,16 @@ Parser::DeclGroupPtrTy Parser::ParseExternalDeclaration(CXX0XAttributeList Attr) return Actions.ConvertDeclToDeclGroup( ParseExplicitInstantiation(ExternLoc, TemplateLoc, DeclEnd)); } - // FIXME: Detect C++ linkage specifications here? - - // Fall through to handle other declarations or function definitions. + goto dont_know; default: + dont_know: // We can't tell whether this is a function-definition or declaration yet. - return ParseDeclarationOrFunctionDefinition(Attr.AttrList); + if (DS) + return ParseDeclarationOrFunctionDefinition(*DS, Attr.AttrList); + else + return ParseDeclarationOrFunctionDefinition(Attr.AttrList); } // This routine returns a DeclGroup, if the thing we parsed only contains a @@ -551,7 +576,7 @@ Parser::ParseDeclarationOrFunctionDefinition(ParsingDeclSpec &DS, // declaration-specifiers init-declarator-list[opt] ';' if (Tok.is(tok::semi)) { ConsumeToken(); - DeclPtrTy TheDecl = Actions.ParsedFreeStandingDeclSpec(getCurScope(), AS, DS); + Decl *TheDecl = Actions.ParsedFreeStandingDeclSpec(getCurScope(), AS, DS); DS.complete(TheDecl); return Actions.ConvertDeclToDeclGroup(TheDecl); } @@ -575,7 +600,7 @@ Parser::ParseDeclarationOrFunctionDefinition(ParsingDeclSpec &DS, if (DS.SetTypeSpecType(DeclSpec::TST_unspecified, AtLoc, PrevSpec, DiagID)) Diag(AtLoc, DiagID) << PrevSpec; - DeclPtrTy TheDecl; + Decl *TheDecl = 0; if (Tok.isObjCAtKeyword(tok::objc_protocol)) TheDecl = ParseObjCAtProtocolDeclaration(AtLoc, DS.getAttributes()); else @@ -589,7 +614,7 @@ Parser::ParseDeclarationOrFunctionDefinition(ParsingDeclSpec &DS, if (Tok.is(tok::string_literal) && getLang().CPlusPlus && DS.getStorageClassSpec() == DeclSpec::SCS_extern && DS.getParsedSpecifiers() == DeclSpec::PQ_StorageClassSpecifier) { - DeclPtrTy TheDecl = ParseLinkage(DS, Declarator::FileContext); + Decl *TheDecl = ParseLinkage(DS, Declarator::FileContext); return Actions.ConvertDeclToDeclGroup(TheDecl); } @@ -617,7 +642,7 @@ Parser::ParseDeclarationOrFunctionDefinition(AttributeList *Attr, /// [C++] function-definition: [C++ 8.4] /// decl-specifier-seq[opt] declarator function-try-block /// -Parser::DeclPtrTy Parser::ParseFunctionDefinition(ParsingDeclarator &D, +Decl *Parser::ParseFunctionDefinition(ParsingDeclarator &D, const ParsedTemplateInfo &TemplateInfo) { const DeclaratorChunk &FnTypeInfo = D.getTypeObject(0); assert(FnTypeInfo.Kind == DeclaratorChunk::Function && @@ -653,7 +678,7 @@ Parser::DeclPtrTy Parser::ParseFunctionDefinition(ParsingDeclarator &D, // If we didn't find the '{', bail out. if (Tok.isNot(tok::l_brace)) - return DeclPtrTy(); + return 0; } // Enter a scope for the function body. @@ -661,9 +686,9 @@ Parser::DeclPtrTy Parser::ParseFunctionDefinition(ParsingDeclarator &D, // Tell the actions module that we have entered a function definition with the // specified Declarator for the function. - DeclPtrTy Res = TemplateInfo.TemplateParams? + Decl *Res = TemplateInfo.TemplateParams? Actions.ActOnStartOfFunctionTemplateDef(getCurScope(), - Action::MultiTemplateParamsArg(Actions, + MultiTemplateParamsArg(Actions, TemplateInfo.TemplateParams->data(), TemplateInfo.TemplateParams->size()), D) @@ -686,7 +711,7 @@ Parser::DeclPtrTy Parser::ParseFunctionDefinition(ParsingDeclarator &D, // Recover from error. if (!Tok.is(tok::l_brace)) { - Actions.ActOnFinishFunctionBody(Res, Action::StmtArg(Actions)); + Actions.ActOnFinishFunctionBody(Res, 0); return Res; } } else @@ -752,7 +777,7 @@ void Parser::ParseKNRParamDeclarations(Declarator &D) { } // Ask the actions module to compute the type for this declarator. - Action::DeclPtrTy Param = + Decl *Param = Actions.ActOnParamDeclarator(getCurScope(), ParmDeclarator); if (Param && @@ -819,13 +844,13 @@ void Parser::ParseKNRParamDeclarations(Declarator &D) { /// [GNU] asm-string-literal: /// string-literal /// -Parser::OwningExprResult Parser::ParseAsmStringLiteral() { +Parser::ExprResult Parser::ParseAsmStringLiteral() { if (!isTokenStringLiteral()) { Diag(Tok, diag::err_expected_string_literal); return ExprError(); } - OwningExprResult Res(ParseStringLiteralExpression()); + ExprResult Res(ParseStringLiteralExpression()); if (Res.isInvalid()) return move(Res); // TODO: Diagnose: wide string literal in 'asm' @@ -838,7 +863,7 @@ Parser::OwningExprResult Parser::ParseAsmStringLiteral() { /// [GNU] simple-asm-expr: /// 'asm' '(' asm-string-literal ')' /// -Parser::OwningExprResult Parser::ParseSimpleAsm(SourceLocation *EndLoc) { +Parser::ExprResult Parser::ParseSimpleAsm(SourceLocation *EndLoc) { assert(Tok.is(tok::kw_asm) && "Not an asm!"); SourceLocation Loc = ConsumeToken(); @@ -859,7 +884,7 @@ Parser::OwningExprResult Parser::ParseSimpleAsm(SourceLocation *EndLoc) { Loc = ConsumeParen(); - OwningExprResult Result(ParseAsmStringLiteral()); + ExprResult Result(ParseAsmStringLiteral()); if (Result.isInvalid()) { SkipUntil(tok::r_paren, true, true); @@ -911,7 +936,7 @@ bool Parser::TryAnnotateTypeOrScopeToken(bool EnteringContext) { // simple-template-id SourceLocation TypenameLoc = ConsumeToken(); CXXScopeSpec SS; - if (ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, false)) + if (ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/ParsedType(), false)) return true; if (!SS.isSet()) { Diag(Tok.getLocation(), diag::err_expected_qualified_after_typename); @@ -939,7 +964,7 @@ bool Parser::TryAnnotateTypeOrScopeToken(bool EnteringContext) { if (Tok.getAnnotationValue()) Ty = Actions.ActOnTypenameType(getCurScope(), TypenameLoc, SS, SourceLocation(), - Tok.getAnnotationValue()); + getTypeAnnotation(Tok)); else Ty = true; } else { @@ -950,7 +975,7 @@ bool Parser::TryAnnotateTypeOrScopeToken(bool EnteringContext) { SourceLocation EndLoc = Tok.getLastLoc(); Tok.setKind(tok::annot_typename); - Tok.setAnnotationValue(Ty.isInvalid()? 0 : Ty.get()); + setTypeAnnotation(Tok, Ty.isInvalid() ? ParsedType() : Ty.get()); Tok.setAnnotationEndLoc(EndLoc); Tok.setLocation(TypenameLoc); PP.AnnotateCachedTokens(Tok); @@ -962,17 +987,18 @@ bool Parser::TryAnnotateTypeOrScopeToken(bool EnteringContext) { CXXScopeSpec SS; if (getLang().CPlusPlus) - if (ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, EnteringContext)) + if (ParseOptionalCXXScopeSpecifier(SS, ParsedType(), EnteringContext)) return true; if (Tok.is(tok::identifier)) { // Determine whether the identifier is a type name. - if (TypeTy *Ty = Actions.getTypeName(*Tok.getIdentifierInfo(), - Tok.getLocation(), getCurScope(), &SS)) { + if (ParsedType Ty = Actions.getTypeName(*Tok.getIdentifierInfo(), + Tok.getLocation(), getCurScope(), + &SS)) { // This is a typename. Replace the current token in-place with an // annotation type token. Tok.setKind(tok::annot_typename); - Tok.setAnnotationValue(Ty); + setTypeAnnotation(Tok, Ty); Tok.setAnnotationEndLoc(Tok.getLocation()); if (SS.isNotEmpty()) // it was a C++ qualified type name. Tok.setLocation(SS.getBeginLoc()); @@ -997,9 +1023,11 @@ bool Parser::TryAnnotateTypeOrScopeToken(bool EnteringContext) { TemplateName.setIdentifier(Tok.getIdentifierInfo(), Tok.getLocation()); bool MemberOfUnknownSpecialization; if (TemplateNameKind TNK - = Actions.isTemplateName(getCurScope(), SS, TemplateName, - /*ObjectType=*/0, EnteringContext, - Template, MemberOfUnknownSpecialization)) { + = Actions.isTemplateName(getCurScope(), SS, + /*hasTemplateKeyword=*/false, TemplateName, + /*ObjectType=*/ ParsedType(), + EnteringContext, + Template, MemberOfUnknownSpecialization)) { // Consume the identifier. ConsumeToken(); if (AnnotateTemplateIdToken(Template, TNK, &SS, TemplateName)) { @@ -1066,7 +1094,7 @@ bool Parser::TryAnnotateCXXScopeToken(bool EnteringContext) { "Cannot be a type or scope token!"); CXXScopeSpec SS; - if (ParseOptionalCXXScopeSpecifier(SS, /*ObjectType=*/0, EnteringContext)) + if (ParseOptionalCXXScopeSpecifier(SS, ParsedType(), EnteringContext)) return true; if (SS.isEmpty()) return false; @@ -1090,17 +1118,17 @@ bool Parser::TryAnnotateCXXScopeToken(bool EnteringContext) { void Parser::CodeCompletionRecovery() { for (Scope *S = getCurScope(); S; S = S->getParent()) { if (S->getFlags() & Scope::FnScope) { - Actions.CodeCompleteOrdinaryName(getCurScope(), Action::CCC_RecoveryInFunction); + Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_RecoveryInFunction); return; } if (S->getFlags() & Scope::ClassScope) { - Actions.CodeCompleteOrdinaryName(getCurScope(), Action::CCC_Class); + Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Class); return; } } - Actions.CodeCompleteOrdinaryName(getCurScope(), Action::CCC_Namespace); + Actions.CodeCompleteOrdinaryName(getCurScope(), Sema::PCC_Namespace); } // Anchor the Parser::FieldCallback vtable to this translation unit. @@ -1109,3 +1137,32 @@ void Parser::CodeCompletionRecovery() { // performance-sensitive. void Parser::FieldCallback::_anchor() { } + +// Code-completion pass-through functions + +void Parser::CodeCompleteDirective(bool InConditional) { + Actions.CodeCompletePreprocessorDirective(InConditional); +} + +void Parser::CodeCompleteInConditionalExclusion() { + Actions.CodeCompleteInPreprocessorConditionalExclusion(getCurScope()); +} + +void Parser::CodeCompleteMacroName(bool IsDefinition) { + Actions.CodeCompletePreprocessorMacroName(IsDefinition); +} + +void Parser::CodeCompletePreprocessorExpression() { + Actions.CodeCompletePreprocessorExpression(); +} + +void Parser::CodeCompleteMacroArgument(IdentifierInfo *Macro, + MacroInfo *MacroInfo, + unsigned ArgumentIndex) { + Actions.CodeCompletePreprocessorMacroArgument(getCurScope(), Macro, MacroInfo, + ArgumentIndex); +} + +void Parser::CodeCompleteNaturalLanguage() { + Actions.CodeCompleteNaturalLanguage(); +} |