diff options
Diffstat (limited to 'clang/lib/Parse')
-rw-r--r-- | clang/lib/Parse/Action.cpp | 104 | ||||
-rw-r--r-- | clang/lib/Parse/AttributeList.cpp | 134 | ||||
-rw-r--r-- | clang/lib/Parse/CMakeLists.txt | 4 | ||||
-rw-r--r-- | clang/lib/Parse/DeclSpec.cpp | 610 | ||||
-rw-r--r-- | clang/lib/Parse/ParseAST.cpp | 113 | ||||
-rw-r--r-- | clang/lib/Parse/ParseCXXInlineMethods.cpp | 4 | ||||
-rw-r--r-- | clang/lib/Parse/ParseDecl.cpp | 4 | ||||
-rw-r--r-- | clang/lib/Parse/ParseDeclCXX.cpp | 6 | ||||
-rw-r--r-- | clang/lib/Parse/ParseExpr.cpp | 6 | ||||
-rw-r--r-- | clang/lib/Parse/ParseExprCXX.cpp | 4 | ||||
-rw-r--r-- | clang/lib/Parse/ParseInit.cpp | 4 | ||||
-rw-r--r-- | clang/lib/Parse/ParseObjc.cpp | 6 | ||||
-rw-r--r-- | clang/lib/Parse/ParsePragma.cpp | 4 | ||||
-rw-r--r-- | clang/lib/Parse/ParseStmt.cpp | 4 | ||||
-rw-r--r-- | clang/lib/Parse/ParseTemplate.cpp | 6 | ||||
-rw-r--r-- | clang/lib/Parse/ParseTentative.cpp | 2 | ||||
-rw-r--r-- | clang/lib/Parse/Parser.cpp | 6 |
17 files changed, 142 insertions, 879 deletions
diff --git a/clang/lib/Parse/Action.cpp b/clang/lib/Parse/Action.cpp deleted file mode 100644 index b34d14f50a0..00000000000 --- a/clang/lib/Parse/Action.cpp +++ /dev/null @@ -1,104 +0,0 @@ -//===--- Action.cpp - Implement the Action 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 Action 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; - -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'; -} - -/// 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(); -} diff --git a/clang/lib/Parse/AttributeList.cpp b/clang/lib/Parse/AttributeList.cpp deleted file mode 100644 index 8263923fe25..00000000000 --- a/clang/lib/Parse/AttributeList.cpp +++ /dev/null @@ -1,134 +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("vecreturn", AT_vecreturn) - .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("ownership_returns", AT_ownership_returns) - .Case("ownership_holds", AT_ownership_holds) - .Case("ownership_takes", AT_ownership_takes) - .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/clang/lib/Parse/CMakeLists.txt b/clang/lib/Parse/CMakeLists.txt index ca62f1558d1..cb0c186f5b8 100644 --- a/clang/lib/Parse/CMakeLists.txt +++ b/clang/lib/Parse/CMakeLists.txt @@ -1,9 +1,7 @@ set(LLVM_NO_RTTI 1) add_clang_library(clangParse - Action.cpp - AttributeList.cpp - DeclSpec.cpp + ParseAST.cpp ParseCXXInlineMethods.cpp ParseDecl.cpp ParseDeclCXX.cpp diff --git a/clang/lib/Parse/DeclSpec.cpp b/clang/lib/Parse/DeclSpec.cpp deleted file mode 100644 index c5072276bc1..00000000000 --- a/clang/lib/Parse/DeclSpec.cpp +++ /dev/null @@ -1,610 +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) { - // Changing storage class is allowed only if the previous one - // was the 'extern' that is part of a linkage specification and - // the new storage class is 'typedef'. - if (!(SCS_extern_in_linkage_spec && - StorageClassSpec == SCS_extern && - S == SCS_typedef)) - 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(); - } -} - -void DeclSpec::SaveStorageSpecifierAsWritten() { - if (SCS_extern_in_linkage_spec && StorageClassSpec == SCS_extern) - // If 'extern' is part of a linkage specification, - // then it is not a storage class "as written". - StorageClassSpecAsWritten = SCS_unspecified; - else - StorageClassSpecAsWritten = StorageClassSpec; -} - -/// 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/clang/lib/Parse/ParseAST.cpp b/clang/lib/Parse/ParseAST.cpp new file mode 100644 index 00000000000..0279bb9e06c --- /dev/null +++ b/clang/lib/Parse/ParseAST.cpp @@ -0,0 +1,113 @@ +//===--- 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/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.getAsVal<DeclGroupRef>()); + }; + // Check for any pending objective-c implementation decl. + while ((ADecl = P.FinishPendingObjCActions())) + Consumer->HandleTopLevelDecl(ADecl.getAsVal<DeclGroupRef>()); + + // 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/clang/lib/Parse/ParseCXXInlineMethods.cpp b/clang/lib/Parse/ParseCXXInlineMethods.cpp index fbb8a7369d9..6b3374db4fd 100644 --- a/clang/lib/Parse/ParseCXXInlineMethods.cpp +++ b/clang/lib/Parse/ParseCXXInlineMethods.cpp @@ -13,8 +13,8 @@ #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 diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index 928c2a9b512..3f976362cd4 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -13,8 +13,8 @@ #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 "RAIIObjectsForParser.h" #include "llvm/ADT/SmallSet.h" using namespace clang; diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp index 5f404ac4300..0772450867d 100644 --- a/clang/lib/Parse/ParseDeclCXX.cpp +++ b/clang/lib/Parse/ParseDeclCXX.cpp @@ -14,9 +14,9 @@ #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 "RAIIObjectsForParser.h" using namespace clang; diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp index 844dd3f873b..21033b4d193 100644 --- a/clang/lib/Parse/ParseExpr.cpp +++ b/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" diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp index f5ade8a8fb5..67b109c833a 100644 --- a/clang/lib/Parse/ParseExprCXX.cpp +++ b/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; diff --git a/clang/lib/Parse/ParseInit.cpp b/clang/lib/Parse/ParseInit.cpp index 8451aebc04b..138058545f9 100644 --- a/clang/lib/Parse/ParseInit.cpp +++ b/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; diff --git a/clang/lib/Parse/ParseObjc.cpp b/clang/lib/Parse/ParseObjc.cpp index 00df5a2c5ab..ddfc7c014a1 100644 --- a/clang/lib/Parse/ParseObjc.cpp +++ b/clang/lib/Parse/ParseObjc.cpp @@ -11,10 +11,10 @@ // //===----------------------------------------------------------------------===// -#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/Scope.h" #include "llvm/ADT/SmallVector.h" using namespace clang; diff --git a/clang/lib/Parse/ParsePragma.cpp b/clang/lib/Parse/ParsePragma.cpp index c53b2e4d27c..c468869e5b4 100644 --- a/clang/lib/Parse/ParsePragma.cpp +++ b/clang/lib/Parse/ParsePragma.cpp @@ -13,9 +13,9 @@ #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" +#include "clang/Sema/Action.h" using namespace clang; diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp index ccd56e98aa1..d4c83a73fb7 100644 --- a/clang/lib/Parse/ParseStmt.cpp +++ b/clang/lib/Parse/ParseStmt.cpp @@ -14,8 +14,8 @@ #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/Scope.h" #include "clang/Basic/Diagnostic.h" #include "clang/Basic/PrettyStackTrace.h" #include "clang/Basic/SourceManager.h" diff --git a/clang/lib/Parse/ParseTemplate.cpp b/clang/lib/Parse/ParseTemplate.cpp index ccf953d2824..a8faee3b439 100644 --- a/clang/lib/Parse/ParseTemplate.cpp +++ b/clang/lib/Parse/ParseTemplate.cpp @@ -13,9 +13,9 @@ #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; diff --git a/clang/lib/Parse/ParseTentative.cpp b/clang/lib/Parse/ParseTentative.cpp index dfd866ff841..dcf1d406289 100644 --- a/clang/lib/Parse/ParseTentative.cpp +++ b/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 diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp index 4e0ae872345..2864bf28bae 100644 --- a/clang/lib/Parse/Parser.cpp +++ b/clang/lib/Parse/Parser.cpp @@ -13,9 +13,9 @@ #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" |