diff options
author | Roman Divacky <rdivacky@FreeBSD.org> | 2009-10-23 14:22:18 +0000 |
---|---|---|
committer | Roman Divacky <rdivacky@FreeBSD.org> | 2009-10-23 14:22:18 +0000 |
commit | 73490b890977362d28dd6326843a1ecae413921d (patch) | |
tree | 3fdd91eae574e32453a4baf462961c742df2691a /lib/Sema/SemaDecl.cpp | |
parent | a5f348eb914e67b51914117fac117c18c1f8d650 (diff) | |
download | src-73490b890977362d28dd6326843a1ecae413921d.tar.gz src-73490b890977362d28dd6326843a1ecae413921d.zip |
Notes
Diffstat (limited to 'lib/Sema/SemaDecl.cpp')
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 81 |
1 files changed, 53 insertions, 28 deletions
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 606b33f5f74b..b83181becb93 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -218,7 +218,7 @@ bool Sema::DiagnoseUnknownTypeName(const IdentifierInfo &II, << &II << DC << SS->getRange(); else if (isDependentScopeSpecifier(*SS)) { Diag(SS->getRange().getBegin(), diag::err_typename_missing) - << (NestedNameSpecifier *)SS->getScopeRep() << II.getName() + << (NestedNameSpecifier *)SS->getScopeRep() << II.getName() << SourceRange(SS->getRange().getBegin(), IILoc) << CodeModificationHint::CreateInsertion(SS->getRange().getBegin(), "typename "); @@ -1059,6 +1059,8 @@ void Sema::MergeVarDecl(VarDecl *New, Decl *OldD) { /// NeverFallThrough iff we never fall off the end of the statement. We assume /// that functions not marked noreturn will return. Sema::ControlFlowKind Sema::CheckFallThrough(Stmt *Root) { + // FIXME: Eventually share this CFG object when we have other warnings based + // of the CFG. This can be done using AnalysisContext. llvm::OwningPtr<CFG> cfg (CFG::buildCFG(Root, &Context)); // FIXME: They should never return 0, fix that, delete this code. @@ -1527,14 +1529,19 @@ Sema::DeclPtrTy Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS, Invalid = true; } + // Mock up a declarator. + Declarator Dc(DS, Declarator::TypeNameContext); + DeclaratorInfo *DInfo = 0; + GetTypeForDeclarator(Dc, S, &DInfo); + assert(DInfo && "couldn't build declarator info for anonymous struct/union"); + // Create a declaration for this anonymous struct/union. NamedDecl *Anon = 0; if (RecordDecl *OwningClass = dyn_cast<RecordDecl>(Owner)) { Anon = FieldDecl::Create(Context, OwningClass, Record->getLocation(), /*IdentifierInfo=*/0, Context.getTypeDeclType(Record), - // FIXME: Type source info. - /*DInfo=*/0, + DInfo, /*BitWidth=*/0, /*Mutable=*/false); Anon->setAccess(AS_public); if (getLangOptions().CPlusPlus) @@ -1561,8 +1568,7 @@ Sema::DeclPtrTy Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS, Anon = VarDecl::Create(Context, Owner, Record->getLocation(), /*IdentifierInfo=*/0, Context.getTypeDeclType(Record), - // FIXME: Type source info. - /*DInfo=*/0, + DInfo, SC); } Anon->setImplicit(); @@ -1903,16 +1909,9 @@ static QualType TryToFixInvalidVariablyModifiedType(QualType T, llvm::APSInt &Res = EvalResult.Val.getInt(); if (Res >= llvm::APSInt(Res.getBitWidth(), Res.isUnsigned())) { - Expr* ArySizeExpr = VLATy->getSizeExpr(); - // FIXME: here we could "steal" (how?) ArySizeExpr from the VLA, - // so as to transfer ownership to the ConstantArrayWithExpr. - // Alternatively, we could "clone" it (how?). - // Since we don't know how to do things above, we just use the - // very same Expr*. - return Context.getConstantArrayWithExprType(VLATy->getElementType(), - Res, ArySizeExpr, - ArrayType::Normal, 0, - VLATy->getBracketsRange()); + // TODO: preserve the size expression in declarator info + return Context.getConstantArrayType(VLATy->getElementType(), + Res, ArrayType::Normal, 0); } SizeIsNegative = true; @@ -3331,7 +3330,7 @@ void Sema::AddInitializerToDecl(DeclPtrTy dcl, ExprArg init, bool DirectInit) { << Init->getSourceRange(); VDecl->setInvalidDecl(); } else if (!VDecl->getType()->isDependentType()) - ImpCastExprToType(Init, VDecl->getType()); + ImpCastExprToType(Init, VDecl->getType(), CastExpr::CK_IntegralCast); } } } else if (VDecl->isFileVarDecl()) { @@ -3534,10 +3533,37 @@ Sema::DeclGroupPtrTy Sema::FinalizeDeclaratorGroup(Scope *S, const DeclSpec &DS, // Block scope. C99 6.7p7: If an identifier for an object is declared with // no linkage (C99 6.2.2p6), the type for the object shall be complete... if (IDecl->isBlockVarDecl() && !IDecl->hasExternalStorage()) { - if (!IDecl->isInvalidDecl() && - RequireCompleteType(IDecl->getLocation(), T, - diag::err_typecheck_decl_incomplete_type)) - IDecl->setInvalidDecl(); + if (T->isDependentType()) { + // If T is dependent, we should not require a complete type. + // (RequireCompleteType shouldn't be called with dependent types.) + // But we still can at least check if we've got an array of unspecified + // size without an initializer. + if (!IDecl->isInvalidDecl() && T->isIncompleteArrayType() && + !IDecl->getInit()) { + Diag(IDecl->getLocation(), diag::err_typecheck_decl_incomplete_type) + << T; + IDecl->setInvalidDecl(); + } + } else if (!IDecl->isInvalidDecl()) { + // If T is an incomplete array type with an initializer list that is + // dependent on something, its size has not been fixed. We could attempt + // to fix the size for such arrays, but we would still have to check + // here for initializers containing a C++0x vararg expansion, e.g. + // template <typename... Args> void f(Args... args) { + // int vals[] = { args }; + // } + const IncompleteArrayType *IAT = T->getAs<IncompleteArrayType>(); + Expr *Init = IDecl->getInit(); + if (IAT && Init && + (Init->isTypeDependent() || Init->isValueDependent())) { + // Check that the member type of the array is complete, at least. + if (RequireCompleteType(IDecl->getLocation(), IAT->getElementType(), + diag::err_typecheck_decl_incomplete_type)) + IDecl->setInvalidDecl(); + } else if (RequireCompleteType(IDecl->getLocation(), T, + diag::err_typecheck_decl_incomplete_type)) + IDecl->setInvalidDecl(); + } } // File scope. C99 6.9.2p2: A declaration of an identifier for an // object that has file scope without an initializer, and without a @@ -3707,12 +3733,13 @@ void Sema::ActOnFinishKNRParamDeclarations(Scope *S, Declarator &D, for (int i = FTI.NumArgs; i != 0; /* decrement in loop */) { --i; if (FTI.ArgInfo[i].Param == 0) { - std::string Code = " int "; - Code += FTI.ArgInfo[i].Ident->getName(); - Code += ";\n"; + llvm::SmallString<256> Code; + llvm::raw_svector_ostream(Code) << " int " + << FTI.ArgInfo[i].Ident->getName() + << ";\n"; Diag(FTI.ArgInfo[i].IdentLoc, diag::ext_param_not_declared) << FTI.ArgInfo[i].Ident - << CodeModificationHint::CreateInsertion(LocAfterDecls, Code); + << CodeModificationHint::CreateInsertion(LocAfterDecls, Code.str()); // Implicitly declare the argument as type 'int' for lack of a better // type. @@ -3975,9 +4002,7 @@ NamedDecl *Sema::ImplicitlyDefineFunction(SourceLocation Loc, } // Extension in C99. Legal in C90, but warn about it. - static const unsigned int BuiltinLen = strlen("__builtin_"); - if (II.getLength() > BuiltinLen && - std::equal(II.getName(), II.getName() + BuiltinLen, "__builtin_")) + if (II.getName().startswith("__builtin_")) Diag(Loc, diag::warn_builtin_unknown) << &II; else if (getLangOptions().C99) Diag(Loc, diag::ext_implicit_function_decl) << &II; @@ -5587,7 +5612,7 @@ void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc, // Adjust the Expr initializer and type. if (ECD->getInitExpr()) ECD->setInitExpr(new (Context) ImplicitCastExpr(NewTy, - CastExpr::CK_Unknown, + CastExpr::CK_IntegralCast, ECD->getInitExpr(), /*isLvalue=*/false)); if (getLangOptions().CPlusPlus) |