aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaDecl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Sema/SemaDecl.cpp')
-rw-r--r--lib/Sema/SemaDecl.cpp272
1 files changed, 136 insertions, 136 deletions
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 9930dbc19b..64c85a2aad 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -471,11 +471,16 @@ NamespaceDecl *Sema::GetStdNamespace() {
/// MergeTypeDefDecl - We just parsed a typedef 'New' which has the
/// same name and scope as a previous declaration 'Old'. Figure out
/// how to resolve this situation, merging decls or emitting
-/// diagnostics as appropriate. Returns true if there was an error,
-/// false otherwise.
+/// diagnostics as appropriate. If there was an error, set New to be invalid.
///
-bool Sema::MergeTypeDefDecl(TypedefDecl *New, Decl *OldD) {
+void Sema::MergeTypeDefDecl(TypedefDecl *New, Decl *OldD) {
+ // If either decl is known invalid already, set the new one to be invalid and
+ // don't bother doing any merging checks.
+ if (New->isInvalidDecl() || OldD->isInvalidDecl())
+ return New->setInvalidDecl();
+
bool objc_types = false;
+
// Allow multiple definitions for ObjC built-in typedefs.
// FIXME: Verify the underlying types are equivalent!
if (getLangOptions().ObjC1) {
@@ -492,20 +497,17 @@ bool Sema::MergeTypeDefDecl(TypedefDecl *New, Decl *OldD) {
if (!TypeID->isStr("Class"))
break;
Context.setObjCClassType(Context.getTypeDeclType(New));
- objc_types = true;
- return false;
+ return;
case 3:
if (!TypeID->isStr("SEL"))
break;
Context.setObjCSelType(Context.getTypeDeclType(New));
- objc_types = true;
- return false;
+ return;
case 8:
if (!TypeID->isStr("Protocol"))
break;
Context.setObjCProtoType(New->getUnderlyingType());
- objc_types = true;
- return false;
+ return;
}
// Fall through - the typedef name was not a builtin type.
}
@@ -514,9 +516,9 @@ bool Sema::MergeTypeDefDecl(TypedefDecl *New, Decl *OldD) {
if (!Old) {
Diag(New->getLocation(), diag::err_redefinition_different_kind)
<< New->getDeclName();
- if (!objc_types)
+ if (OldD->getLocation().isValid())
Diag(OldD->getLocation(), diag::note_previous_definition);
- return true;
+ return New->setInvalidDecl();
}
// Determine the "old" type we'll use for checking and diagnostics.
@@ -534,12 +536,13 @@ bool Sema::MergeTypeDefDecl(TypedefDecl *New, Decl *OldD) {
Context.getCanonicalType(New->getUnderlyingType())) {
Diag(New->getLocation(), diag::err_redefinition_different_typedef)
<< New->getUnderlyingType() << OldType;
- if (!objc_types)
+ if (Old->getLocation().isValid())
Diag(Old->getLocation(), diag::note_previous_definition);
- return true;
+ return New->setInvalidDecl();
}
- if (objc_types) return false;
- if (getLangOptions().Microsoft) return false;
+
+ if (objc_types || getLangOptions().Microsoft)
+ return;
// C++ [dcl.typedef]p2:
// In a given non-class scope, a typedef specifier can be used to
@@ -547,11 +550,11 @@ bool Sema::MergeTypeDefDecl(TypedefDecl *New, Decl *OldD) {
// to the type to which it already refers.
if (getLangOptions().CPlusPlus) {
if (!isa<CXXRecordDecl>(CurContext))
- return false;
+ return;
Diag(New->getLocation(), diag::err_redefinition)
<< New->getDeclName();
Diag(Old->getLocation(), diag::note_previous_definition);
- return true;
+ return New->setInvalidDecl();
}
// If we have a redefinition of a typedef in C, emit a warning. This warning
@@ -560,7 +563,7 @@ bool Sema::MergeTypeDefDecl(TypedefDecl *New, Decl *OldD) {
Diag(New->getLocation(), diag::warn_redefinition_of_typedef)
<< New->getDeclName();
Diag(Old->getLocation(), diag::note_previous_definition);
- return false;
+ return;
}
/// DeclhasAttr - returns true if decl Declaration already has the target
@@ -883,14 +886,19 @@ bool Sema::MergeCompatibleFunctionDecls(FunctionDecl *New, FunctionDecl *Old) {
/// FinalizeDeclaratorGroup. Unfortunately, we can't analyze tentative
/// definitions here, since the initializer hasn't been attached.
///
-bool Sema::MergeVarDecl(VarDecl *New, Decl *OldD) {
+void Sema::MergeVarDecl(VarDecl *New, Decl *OldD) {
+ // If either decl is invalid, make sure the new one is marked invalid and
+ // don't do any other checking.
+ if (New->isInvalidDecl() || OldD->isInvalidDecl())
+ return New->setInvalidDecl();
+
// Verify the old decl was also a variable.
VarDecl *Old = dyn_cast<VarDecl>(OldD);
if (!Old) {
Diag(New->getLocation(), diag::err_redefinition_different_kind)
<< New->getDeclName();
Diag(OldD->getLocation(), diag::note_previous_definition);
- return true;
+ return New->setInvalidDecl();
}
MergeAttributes(New, Old, Context);
@@ -901,7 +909,7 @@ bool Sema::MergeVarDecl(VarDecl *New, Decl *OldD) {
Diag(New->getLocation(), diag::err_redefinition_different_type)
<< New->getDeclName();
Diag(Old->getLocation(), diag::note_previous_definition);
- return true;
+ return New->setInvalidDecl();
}
New->setType(MergedT);
@@ -910,7 +918,7 @@ bool Sema::MergeVarDecl(VarDecl *New, Decl *OldD) {
(Old->getStorageClass() == VarDecl::None || Old->hasExternalStorage())) {
Diag(New->getLocation(), diag::err_static_non_static) << New->getDeclName();
Diag(Old->getLocation(), diag::note_previous_definition);
- return true;
+ return New->setInvalidDecl();
}
// C99 6.2.2p4:
// For an identifier declared with the storage-class specifier
@@ -927,7 +935,7 @@ bool Sema::MergeVarDecl(VarDecl *New, Decl *OldD) {
Old->getStorageClass() == VarDecl::Static) {
Diag(New->getLocation(), diag::err_non_static_static) << New->getDeclName();
Diag(Old->getLocation(), diag::note_previous_definition);
- return true;
+ return New->setInvalidDecl();
}
// Variables with external linkage are analyzed in FinalizeDeclaratorGroup.
@@ -940,7 +948,7 @@ bool Sema::MergeVarDecl(VarDecl *New, Decl *OldD) {
!New->getLexicalDeclContext()->isRecord())) {
Diag(New->getLocation(), diag::err_redefinition) << New->getDeclName();
Diag(Old->getLocation(), diag::note_previous_definition);
- return true;
+ return New->setInvalidDecl();
}
if (New->isThreadSpecified() && !Old->isThreadSpecified()) {
@@ -953,8 +961,6 @@ bool Sema::MergeVarDecl(VarDecl *New, Decl *OldD) {
// Keep a chain of previous declarations.
New->setPreviousDeclaration(Old);
-
- return false;
}
/// CheckParmsForFunctionDef - Check that the parameters of the given
@@ -1337,7 +1343,7 @@ Sema::ActOnDeclarator(Scope *S, Declarator &D, bool IsFunctionDefinition) {
// All of these full declarators require an identifier. If it doesn't have
// one, the ParsedFreeStandingDeclSpec action should be used.
if (!Name) {
- if (!D.getInvalidType()) // Reject this if we think it is valid.
+ if (!D.isInvalidType()) // Reject this if we think it is valid.
Diag(D.getDeclSpec().getSourceRange().getBegin(),
diag::err_declarator_need_ident)
<< D.getDeclSpec().getSourceRange() << D.getSourceRange();
@@ -1353,11 +1359,10 @@ Sema::ActOnDeclarator(Scope *S, Declarator &D, bool IsFunctionDefinition) {
DeclContext *DC;
NamedDecl *PrevDecl;
NamedDecl *New;
- bool InvalidDecl = false;
QualType R = GetTypeForDeclarator(D, S);
if (R.isNull()) {
- InvalidDecl = true;
+ D.setInvalidType();
R = Context.IntTy;
if (IsFunctionDefinition) // int(...)
R = Context.getFunctionType(R, 0, 0, true, 0);
@@ -1368,7 +1373,7 @@ Sema::ActOnDeclarator(Scope *S, Declarator &D, bool IsFunctionDefinition) {
if (D.getCXXScopeSpec().isInvalid()) {
DC = CurContext;
PrevDecl = 0;
- InvalidDecl = true;
+ D.setInvalidType();
} else if (!D.getCXXScopeSpec().isSet()) {
LookupNameKind NameKind = LookupOrdinaryName;
@@ -1430,14 +1435,16 @@ Sema::ActOnDeclarator(Scope *S, Declarator &D, bool IsFunctionDefinition) {
else
Diag(L, diag::err_invalid_declarator_scope)
<< Name << cast<NamedDecl>(DC) << R;
- InvalidDecl = true;
+ D.setInvalidType();
}
}
if (PrevDecl && PrevDecl->isTemplateParameter()) {
// Maybe we will complain about the shadowed template parameter.
- InvalidDecl = InvalidDecl
- || DiagnoseTemplateParameterShadow(D.getIdentifierLoc(), PrevDecl);
+ if (!D.isInvalidType())
+ if (DiagnoseTemplateParameterShadow(D.getIdentifierLoc(), PrevDecl))
+ D.setInvalidType();
+
// Just pretend that we didn't see the previous declaration.
PrevDecl = 0;
}
@@ -1452,15 +1459,12 @@ Sema::ActOnDeclarator(Scope *S, Declarator &D, bool IsFunctionDefinition) {
bool Redeclaration = false;
if (D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_typedef) {
- New = ActOnTypedefDeclarator(S, D, DC, R, PrevDecl,
- InvalidDecl, Redeclaration);
+ New = ActOnTypedefDeclarator(S, D, DC, R, PrevDecl, Redeclaration);
} else if (R->isFunctionType()) {
New = ActOnFunctionDeclarator(S, D, DC, R, PrevDecl,
- IsFunctionDefinition, InvalidDecl,
- Redeclaration);
+ IsFunctionDefinition, Redeclaration);
} else {
- New = ActOnVariableDeclarator(S, D, DC, R, PrevDecl,
- InvalidDecl, Redeclaration);
+ New = ActOnVariableDeclarator(S, D, DC, R, PrevDecl, Redeclaration);
}
if (New == 0)
@@ -1468,11 +1472,8 @@ Sema::ActOnDeclarator(Scope *S, Declarator &D, bool IsFunctionDefinition) {
// If this has an identifier and is not an invalid redeclaration,
// add it to the scope stack.
- if (Name && !(Redeclaration && InvalidDecl))
+ if (Name && !(Redeclaration && New->isInvalidDecl()))
PushOnScopeChains(New, S);
- // If any semantic error occurred, mark the decl as invalid.
- if (D.getInvalidType() || InvalidDecl)
- New->setInvalidDecl();
return DeclPtrTy::make(New);
}
@@ -1568,13 +1569,12 @@ void Sema::DiagnoseFunctionSpecifiers(Declarator& D) {
NamedDecl*
Sema::ActOnTypedefDeclarator(Scope* S, Declarator& D, DeclContext* DC,
- QualType R, Decl* PrevDecl, bool& InvalidDecl,
- bool &Redeclaration) {
+ QualType R, Decl* PrevDecl, bool &Redeclaration) {
// Typedef declarators cannot be qualified (C++ [dcl.meaning]p1).
if (D.getCXXScopeSpec().isSet()) {
Diag(D.getIdentifierLoc(), diag::err_qualified_typedef_declarator)
<< D.getCXXScopeSpec().getRange();
- InvalidDecl = true;
+ D.setInvalidType();
// Pretend we didn't see the scope specifier.
DC = 0;
}
@@ -1591,6 +1591,9 @@ Sema::ActOnTypedefDeclarator(Scope* S, Declarator& D, DeclContext* DC,
TypedefDecl *NewTD = ParseTypedefDecl(S, D, R);
if (!NewTD) return 0;
+
+ if (D.isInvalidType())
+ NewTD->setInvalidDecl();
// Handle attributes prior to checking for duplicates in MergeVarDecl
ProcessDeclAttributes(NewTD, D);
@@ -1598,8 +1601,7 @@ Sema::ActOnTypedefDeclarator(Scope* S, Declarator& D, DeclContext* DC,
// in an outer scope, it isn't the same thing.
if (PrevDecl && isDeclInScope(PrevDecl, DC, S)) {
Redeclaration = true;
- if (MergeTypeDefDecl(NewTD, PrevDecl))
- InvalidDecl = true;
+ MergeTypeDefDecl(NewTD, PrevDecl);
}
// C99 6.7.7p2: If a typedef name specifies a variably modified type
@@ -1622,7 +1624,7 @@ Sema::ActOnTypedefDeclarator(Scope* S, Declarator& D, DeclContext* DC,
Diag(D.getIdentifierLoc(), diag::err_vla_decl_in_file_scope);
else
Diag(D.getIdentifierLoc(), diag::err_vm_decl_in_file_scope);
- InvalidDecl = true;
+ NewTD->setInvalidDecl();
}
}
}
@@ -1696,7 +1698,7 @@ isOutOfScopePreviousDeclaration(NamedDecl *PrevDecl, DeclContext *DC,
NamedDecl*
Sema::ActOnVariableDeclarator(Scope* S, Declarator& D, DeclContext* DC,
- QualType R,NamedDecl* PrevDecl, bool& InvalidDecl,
+ QualType R,NamedDecl* PrevDecl,
bool &Redeclaration) {
DeclarationName Name = GetNameForDeclarator(D);
@@ -1718,7 +1720,7 @@ Sema::ActOnVariableDeclarator(Scope* S, Declarator& D, DeclContext* DC,
// mutable can only appear on non-static class members, so it's always
// an error here
Diag(D.getIdentifierLoc(), diag::err_mutable_nonmember);
- InvalidDecl = true;
+ D.setInvalidType();
SC = VarDecl::None;
break;
}
@@ -1737,7 +1739,7 @@ Sema::ActOnVariableDeclarator(Scope* S, Declarator& D, DeclContext* DC,
// appear in the declaration specifiers in an external declaration.
if (SC == VarDecl::Auto || SC == VarDecl::Register) {
Diag(D.getIdentifierLoc(), diag::err_typecheck_sclass_fscope);
- InvalidDecl = true;
+ D.setInvalidType();
}
}
if (DC->isRecord() && !CurContext->isRecord()) {
@@ -1757,6 +1759,9 @@ Sema::ActOnVariableDeclarator(Scope* S, Declarator& D, DeclContext* DC,
// FIXME: Move to DeclGroup...
D.getDeclSpec().getSourceRange().getBegin());
+ if (D.isInvalidType())
+ NewVD->setInvalidDecl();
+
if (D.getDeclSpec().isThreadSpecified()) {
if (NewVD->hasLocalStorage())
Diag(D.getDeclSpec().getThreadSpecLoc(), diag::err_thread_non_global);
@@ -1797,22 +1802,21 @@ Sema::ActOnVariableDeclarator(Scope* S, Declarator& D, DeclContext* DC,
Diag(NewVD->getLocation(), diag::err_nonstatic_member_out_of_line)
<< D.getCXXScopeSpec().getRange();
PrevDecl = 0;
- InvalidDecl = true;
+ NewVD->setInvalidDecl();
}
} else if (D.getCXXScopeSpec().isSet()) {
// No previous declaration in the qualifying scope.
Diag(D.getIdentifierLoc(), diag::err_typecheck_no_member)
<< Name << D.getCXXScopeSpec().getRange();
- InvalidDecl = true;
+ NewVD->setInvalidDecl();
}
- if (CheckVariableDeclaration(NewVD, PrevDecl, Redeclaration))
- InvalidDecl = true;
+ CheckVariableDeclaration(NewVD, PrevDecl, Redeclaration);
// If this is a locally-scoped extern C variable, update the map of
// such variables.
if (CurContext->isFunctionOrMethod() && NewVD->isExternC(Context) &&
- !InvalidDecl)
+ !NewVD->isInvalidDecl())
RegisterLocallyScopedExternCDecl(NewVD, PrevDecl, S);
return NewVD;
@@ -1826,23 +1830,25 @@ Sema::ActOnVariableDeclarator(Scope* S, Declarator& D, DeclContext* DC,
/// check variables after they have been parsed and their declarators
/// have been translated into a declaration, and to check
///
-/// \returns true if an error was encountered, false otherwise.
-bool Sema::CheckVariableDeclaration(VarDecl *NewVD, NamedDecl *PrevDecl,
+/// Sets NewVD->isInvalidDecl() if an error was encountered.
+void Sema::CheckVariableDeclaration(VarDecl *NewVD, NamedDecl *PrevDecl,
bool &Redeclaration) {
- bool Invalid = false;
-
+ // If the decl is already known invalid, don't check it.
+ if (NewVD->isInvalidDecl())
+ return;
+
QualType T = NewVD->getType();
if (T->isObjCInterfaceType()) {
Diag(NewVD->getLocation(), diag::err_statically_allocated_object);
- Invalid = true;
+ return NewVD->setInvalidDecl();
}
// The variable can not have an abstract class type.
if (RequireNonAbstractType(NewVD->getLocation(), T,
diag::err_abstract_type_in_decl,
AbstractVariableType))
- Invalid = true;
+ return NewVD->setInvalidDecl();
// Emit an error if an address space was applied to decl with local storage.
// This includes arrays of objects with address space qualifiers, but not
@@ -1850,7 +1856,7 @@ bool Sema::CheckVariableDeclaration(VarDecl *NewVD, NamedDecl *PrevDecl,
// ISO/IEC TR 18037 S5.1.2
if (NewVD->hasLocalStorage() && (T.getAddressSpace() != 0)) {
Diag(NewVD->getLocation(), diag::err_as_qualified_auto_decl);
- Invalid = true;
+ return NewVD->setInvalidDecl();
}
if (NewVD->hasLocalStorage() && T.isObjCGCWeak()
@@ -1866,34 +1872,35 @@ bool Sema::CheckVariableDeclaration(VarDecl *NewVD, NamedDecl *PrevDecl,
bool SizeIsNegative;
QualType FixedTy =
TryToFixInvalidVariablyModifiedType(T, Context, SizeIsNegative);
- if (!FixedTy.isNull()) {
- Diag(NewVD->getLocation(), diag::warn_illegal_constant_array_size);
- NewVD->setType(FixedTy);
- } else if (T->isVariableArrayType()) {
- Invalid = true;
-
+
+ if (FixedTy.isNull() && T->isVariableArrayType()) {
const VariableArrayType *VAT = Context.getAsVariableArrayType(T);
// FIXME: This won't give the correct result for
// int a[10][n];
SourceRange SizeRange = VAT->getSizeExpr()->getSourceRange();
-
+
if (NewVD->isFileVarDecl())
Diag(NewVD->getLocation(), diag::err_vla_decl_in_file_scope)
- << SizeRange;
+ << SizeRange;
else if (NewVD->getStorageClass() == VarDecl::Static)
Diag(NewVD->getLocation(), diag::err_vla_decl_has_static_storage)
- << SizeRange;
+ << SizeRange;
else
Diag(NewVD->getLocation(), diag::err_vla_decl_has_extern_linkage)
- << SizeRange;
- } else {
- Invalid = true;
-
+ << SizeRange;
+ return NewVD->setInvalidDecl();
+ }
+
+ if (FixedTy.isNull()) {
if (NewVD->isFileVarDecl())
Diag(NewVD->getLocation(), diag::err_vm_decl_in_file_scope);
else
Diag(NewVD->getLocation(), diag::err_vm_decl_has_extern_linkage);
+ return NewVD->setInvalidDecl();
}
+
+ Diag(NewVD->getLocation(), diag::warn_illegal_constant_array_size);
+ NewVD->setType(FixedTy);
}
if (!PrevDecl && NewVD->isExternC(Context)) {
@@ -1906,26 +1913,22 @@ bool Sema::CheckVariableDeclaration(VarDecl *NewVD, NamedDecl *PrevDecl,
PrevDecl = Pos->second;
}
- if (!Invalid && T->isVoidType() && !NewVD->hasExternalStorage()) {
+ if (T->isVoidType() && !NewVD->hasExternalStorage()) {
Diag(NewVD->getLocation(), diag::err_typecheck_decl_incomplete_type)
<< T;
- Invalid = true;
+ return NewVD->setInvalidDecl();
}
if (PrevDecl) {
Redeclaration = true;
- if (MergeVarDecl(NewVD, PrevDecl))
- Invalid = true;
+ MergeVarDecl(NewVD, PrevDecl);
}
-
- return NewVD->isInvalidDecl() || Invalid;
}
NamedDecl*
Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
QualType R, NamedDecl* PrevDecl,
- bool IsFunctionDefinition,
- bool &InvalidDecl, bool &Redeclaration) {
+ bool IsFunctionDefinition, bool &Redeclaration) {
assert(R.getTypePtr()->isFunctionType());
DeclarationName Name = GetNameForDeclarator(D);
@@ -1937,7 +1940,7 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
case DeclSpec::SCS_mutable:
Diag(D.getDeclSpec().getStorageClassSpecLoc(),
diag::err_typecheck_sclass_func);
- InvalidDecl = true;
+ D.setInvalidType();
break;
case DeclSpec::SCS_unspecified: SC = FunctionDecl::None; break;
case DeclSpec::SCS_extern: SC = FunctionDecl::Extern; break;
@@ -1973,14 +1976,14 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
R->getAsFunctionType()->getResultType(),
diag::err_abstract_type_in_decl,
AbstractReturnType))
- InvalidDecl = true;
+ D.setInvalidType();
// Do not allow returning a objc interface by-value.
if (R->getAsFunctionType()->getResultType()->isObjCInterfaceType()) {
Diag(D.getIdentifierLoc(),
diag::err_object_cannot_be_passed_returned_by_value) << 0
<< R->getAsFunctionType()->getResultType();
- InvalidDecl = true;
+ D.setInvalidType();
}
bool isVirtualOkay = false;
@@ -1990,7 +1993,8 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
assert(DC->isRecord() &&
"Constructors can only be declared in a member context");
- InvalidDecl = InvalidDecl || CheckConstructorDeclarator(D, R, SC);
+ if (!D.isInvalidType())
+ D.setInvalidType(CheckConstructorDeclarator(D, R, SC));
// Create the new declaration
NewFD = CXXConstructorDecl::Create(Context,
@@ -2001,8 +2005,9 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
} else if (D.getKind() == Declarator::DK_Destructor) {
// This is a C++ destructor declaration.
if (DC->isRecord()) {
- InvalidDecl = InvalidDecl || CheckDestructorDeclarator(D, R, SC);
-
+ if (!D.isInvalidType())
+ D.setInvalidType(CheckDestructorDeclarator(D, R, SC));
+
NewFD = CXXDestructorDecl::Create(Context,
cast<CXXRecordDecl>(DC),
D.getIdentifierLoc(), Name, R,
@@ -2020,7 +2025,7 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
/*hasPrototype=*/true,
// FIXME: Move to DeclGroup...
D.getDeclSpec().getSourceRange().getBegin());
- InvalidDecl = true;
+ D.setInvalidType();
}
} else if (D.getKind() == Declarator::DK_Conversion) {
if (!DC->isRecord()) {
@@ -2028,7 +2033,8 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
diag::err_conv_function_not_member);
return 0;
} else {
- InvalidDecl = InvalidDecl || CheckConversionDeclarator(D, R, SC);
+ if (!D.isInvalidType())
+ D.setInvalidType(CheckConversionDeclarator(D, R, SC));
NewFD = CXXConversionDecl::Create(Context, cast<CXXRecordDecl>(DC),
D.getIdentifierLoc(), Name, R,
@@ -2062,7 +2068,7 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
D.getDeclSpec().getSourceRange().getBegin());
}
- if (InvalidDecl)
+ if (D.isInvalidType())
NewFD->setInvalidDecl();
// Set the lexical context. If the declarator has a C++
@@ -2079,7 +2085,7 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
// function is also virtual if it overrides an already virtual
// function. This is important to do here because it's part of the
// declaration.
- if (isVirtual && !InvalidDecl) {
+ if (isVirtual && !NewFD->isInvalidDecl()) {
if (!isVirtualOkay) {
Diag(D.getDeclSpec().getVirtualSpecLoc(),
diag::err_virtual_non_function);
@@ -2218,17 +2224,16 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
// Perform semantic checking on the function declaration.
bool OverloadableAttrRequired = false; // FIXME: HACK!
- if (CheckFunctionDeclaration(NewFD, PrevDecl, Redeclaration,
- /*FIXME:*/OverloadableAttrRequired))
- InvalidDecl = true;
+ CheckFunctionDeclaration(NewFD, PrevDecl, Redeclaration,
+ /*FIXME:*/OverloadableAttrRequired);
- if (D.getCXXScopeSpec().isSet() && !InvalidDecl) {
+ if (D.getCXXScopeSpec().isSet() && !NewFD->isInvalidDecl()) {
// An out-of-line member function declaration must also be a
// definition (C++ [dcl.meaning]p1).
if (!IsFunctionDefinition) {
Diag(NewFD->getLocation(), diag::err_out_of_line_declaration)
<< D.getCXXScopeSpec().getRange();
- InvalidDecl = true;
+ NewFD->setInvalidDecl();
} else if (!Redeclaration) {
// The user tried to provide an out-of-line definition for a
// function that is a member of a class or namespace, but there
@@ -2246,7 +2251,7 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
// whether the parameter types are references).
Diag(D.getIdentifierLoc(), diag::err_member_def_does_not_match)
<< cast<NamedDecl>(DC) << D.getCXXScopeSpec().getRange();
- InvalidDecl = true;
+ NewFD->setInvalidDecl();
LookupResult Prev = LookupQualifiedName(DC, Name, LookupOrdinaryName,
true);
@@ -2284,7 +2289,7 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
// If this is a locally-scoped extern C function, update the
// map of such names.
if (CurContext->isFunctionOrMethod() && NewFD->isExternC(Context)
- && !InvalidDecl)
+ && !NewFD->isInvalidDecl())
RegisterLocallyScopedExternCDecl(NewFD, PrevDecl, S);
return NewFD;
@@ -2300,18 +2305,21 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
/// that have been instantiated via C++ template instantiation (called
/// via InstantiateDecl).
///
-/// \returns true if there was an error, false otherwise.
-bool Sema::CheckFunctionDeclaration(FunctionDecl *NewFD, NamedDecl *&PrevDecl,
+/// This sets NewFD->isInvalidDecl() to true if there was an error.
+void Sema::CheckFunctionDeclaration(FunctionDecl *NewFD, NamedDecl *&PrevDecl,
bool &Redeclaration,
bool &OverloadableAttrRequired) {
- bool InvalidDecl = false;
+ // If NewFD is already known erroneous, don't do any of this checking.
+ if (NewFD->isInvalidDecl())
+ return;
// Semantic checking for this function declaration (in isolation).
if (getLangOptions().CPlusPlus) {
// C++-specific checks.
- if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(NewFD))
- InvalidDecl = InvalidDecl || CheckConstructor(Constructor);
- else if (isa<CXXDestructorDecl>(NewFD)) {
+ if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(NewFD)) {
+ if (CheckConstructor(Constructor))
+ return NewFD->setInvalidDecl();
+ } else if (isa<CXXDestructorDecl>(NewFD)) {
CXXRecordDecl *Record = cast<CXXRecordDecl>(NewFD->getParent());
Record->setUserDeclaredDestructor(true);
// C++ [class]p4: A POD-struct is an aggregate class that has [...] no
@@ -2328,7 +2336,7 @@ bool Sema::CheckFunctionDeclaration(FunctionDecl *NewFD, NamedDecl *&PrevDecl,
// Extra checking for C++ overloaded operators (C++ [over.oper]).
if (NewFD->isOverloadedOperator() &&
CheckOverloadedOperatorDeclaration(NewFD))
- InvalidDecl = true;
+ return NewFD->setInvalidDecl();
}
// C99 6.7.4p6:
@@ -2386,7 +2394,6 @@ bool Sema::CheckFunctionDeclaration(FunctionDecl *NewFD, NamedDecl *&PrevDecl,
if (!NewFD->getType()->getAsFunctionProtoType()) {
Diag(NewFD->getLocation(), diag::err_attribute_overloadable_no_prototype)
<< NewFD;
- InvalidDecl = true;
Redeclaration = true;
// Turn this into a variadic function with no parameters.
@@ -2394,6 +2401,7 @@ bool Sema::CheckFunctionDeclaration(FunctionDecl *NewFD, NamedDecl *&PrevDecl,
NewFD->getType()->getAsFunctionType()->getResultType(),
0, 0, true, 0);
NewFD->setType(R);
+ return NewFD->setInvalidDecl();
}
}
@@ -2411,21 +2419,17 @@ bool Sema::CheckFunctionDeclaration(FunctionDecl *NewFD, NamedDecl *&PrevDecl,
// NewFD and OldDecl represent declarations that need to be
// merged.
if (MergeFunctionDecl(NewFD, OldDecl))
- InvalidDecl = true;
+ return NewFD->setInvalidDecl();
- if (!InvalidDecl)
- NewFD->setPreviousDeclaration(cast<FunctionDecl>(OldDecl));
+ NewFD->setPreviousDeclaration(cast<FunctionDecl>(OldDecl));
}
}
- if (getLangOptions().CPlusPlus && !CurContext->isRecord()) {
- // In C++, check default arguments now that we have merged decls. Unless
- // the lexical context is the class, because in this case this is done
- // during delayed parsing anyway.
+ // In C++, check default arguments now that we have merged decls. Unless
+ // the lexical context is the class, because in this case this is done
+ // during delayed parsing anyway.
+ if (getLangOptions().CPlusPlus && !CurContext->isRecord())
CheckCXXDefaultArguments(NewFD);
- }
-
- return InvalidDecl || NewFD->isInvalidDecl();
}
bool Sema::CheckForConstantInitializer(Expr *Init, QualType DclT) {
@@ -2798,9 +2802,6 @@ Sema::ActOnParamDeclarator(Scope *S, Declarator &D) {
if (getLangOptions().CPlusPlus)
CheckExtraCXXDefaultArguments(D);
- // In this context, we *do not* check D.getInvalidType(). If the declarator
- // type was invalid, GetTypeForDeclarator() still returns a "valid" type,
- // though it will not reflect the user specified type.
QualType parmDeclType = GetTypeForDeclarator(D, S);
if (parmDeclType.isNull()) {
D.setInvalidType(true);
@@ -2850,7 +2851,7 @@ Sema::ActOnParamDeclarator(Scope *S, Declarator &D) {
D.getIdentifierLoc(), II, T,
parmDeclType, StorageClass, 0);
- if (D.getInvalidType())
+ if (D.isInvalidType())
New->setInvalidDecl();
// Parameter declarators cannot be interface types. All ObjC objects are
@@ -3210,7 +3211,7 @@ TypedefDecl *Sema::ParseTypedefDecl(Scope *S, Declarator &D, QualType T) {
TD->setTypedefForAnonDecl(NewTD);
}
- if (D.getInvalidType())
+ if (D.isInvalidType())
NewTD->setInvalidDecl();
return NewTD;
}
@@ -3712,6 +3713,7 @@ FieldDecl *Sema::CheckFieldDecl(DeclarationName Name, QualType T,
Declarator *D) {
IdentifierInfo *II = Name.getAsIdentifierInfo();
bool InvalidDecl = false;
+ if (D) InvalidDecl = D->isInvalidType();
// If we receive a broken type, recover by assuming 'int' and
// marking this declaration as invalid.
@@ -3753,6 +3755,8 @@ FieldDecl *Sema::CheckFieldDecl(DeclarationName Name, QualType T,
FieldDecl *NewFD = FieldDecl::Create(Context, Record, Loc, II, T, BitWidth,
Mutable);
+ if (InvalidDecl)
+ NewFD->setInvalidDecl();
if (PrevDecl && !isa<TagDecl>(PrevDecl)) {
Diag(Loc, diag::err_duplicate_member) << II;
@@ -3772,9 +3776,6 @@ FieldDecl *Sema::CheckFieldDecl(DeclarationName Name, QualType T,
if (T.isObjCGCWeak())
Diag(Loc, diag::warn_attribute_weak_on_field);
- if (InvalidDecl)
- NewFD->setInvalidDecl();
-
NewFD->setAccess(AS);
// C++ [dcl.init.aggr]p1:
@@ -3820,16 +3821,15 @@ Sema::DeclPtrTy Sema::ActOnIvar(Scope *S,
// example, unnamed unions inject all members into the struct namespace!
QualType T = GetTypeForDeclarator(D, S);
- bool InvalidDecl = D.getInvalidType();
- if (T.isNull()) {
- InvalidDecl = true;
- T = Context.IntTy;
- }
+ if (T.isNull()) {
+ D.setInvalidType();
+ T = Context.IntTy;
+ }
if (BitWidth) {
// 6.7.2.1p3, 6.7.2.1p4
if (VerifyBitField(Loc, II, T, BitWidth)) {
- InvalidDecl = true;
+ D.setInvalidType();
DeleteExpr(BitWidth);
BitWidth = 0;
}
@@ -3844,7 +3844,7 @@ Sema::DeclPtrTy Sema::ActOnIvar(Scope *S,
// than a variably modified type.
if (T->isVariablyModifiedType()) {
Diag(Loc, diag::err_typecheck_ivar_variable_size);
- InvalidDecl = true;
+ D.setInvalidType();
}
// Get the visibility (access control) for this ivar.
@@ -3869,7 +3869,7 @@ Sema::DeclPtrTy Sema::ActOnIvar(Scope *S,
// Process attributes attached to the ivar.
ProcessDeclAttributes(NewID, D);
- if (D.getInvalidType() || InvalidDecl)
+ if (D.isInvalidType())
NewID->setInvalidDecl();
if (II) {