mirror of
https://github.com/llvm/llvm-project.git
synced 2025-05-02 07:26:08 +00:00

indicating the nature of the default argument in a ParmVarDecl. Instead, this adds a proper enum stored exclusively in the ParmVarDecl bits (which we have plenty of) for this. This even allows us to track a previously unrepresented state in Clang when we parse a function declaration with a default argument on a parameter but we cannot even form an invalid expression node (for example, it is an invalid token). Now, we can model this state in the AST at least, and potentially improve recovery in this area in the future. I've also cleaned up the functions managing both variable initializer expressions and parameter default argument expresssions as much as possible. I've left some comments about further improvements based on a discussion with Richard Smith. Lots of credit to him for walking me through exactly which of the *many* tradeoffs here he felt was the best fit. Should be NFC for now. I've tried my best to preserve existing behavior. This is part of a series of patches to allow LLVM to check for complete pointee types when computing its pointer traits. This is absolutely necessary to get correct (or reproducible) results for things like how many low bits are guaranteed to be zero. llvm-svn: 256609
115 lines
2.8 KiB
C++
115 lines
2.8 KiB
C++
//===--- StmtIterator.cpp - Iterators for Statements ------------------------===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This file defines internal methods for StmtIterator.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "clang/AST/StmtIterator.h"
|
|
#include "clang/AST/Decl.h"
|
|
|
|
using namespace clang;
|
|
|
|
// FIXME: Add support for dependent-sized array types in C++?
|
|
// Does it even make sense to build a CFG for an uninstantiated template?
|
|
static inline const VariableArrayType *FindVA(const Type* t) {
|
|
while (const ArrayType *vt = dyn_cast<ArrayType>(t)) {
|
|
if (const VariableArrayType *vat = dyn_cast<VariableArrayType>(vt))
|
|
if (vat->getSizeExpr())
|
|
return vat;
|
|
|
|
t = vt->getElementType().getTypePtr();
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
void StmtIteratorBase::NextVA() {
|
|
assert (getVAPtr());
|
|
|
|
const VariableArrayType *p = getVAPtr();
|
|
p = FindVA(p->getElementType().getTypePtr());
|
|
setVAPtr(p);
|
|
|
|
if (p)
|
|
return;
|
|
|
|
if (inDeclGroup()) {
|
|
if (VarDecl* VD = dyn_cast<VarDecl>(*DGI))
|
|
if (VD->hasInit())
|
|
return;
|
|
|
|
NextDecl();
|
|
}
|
|
else {
|
|
assert(inSizeOfTypeVA());
|
|
RawVAPtr = 0;
|
|
}
|
|
}
|
|
|
|
void StmtIteratorBase::NextDecl(bool ImmediateAdvance) {
|
|
assert(getVAPtr() == nullptr);
|
|
assert(inDeclGroup());
|
|
|
|
if (ImmediateAdvance)
|
|
++DGI;
|
|
|
|
for ( ; DGI != DGE; ++DGI)
|
|
if (HandleDecl(*DGI))
|
|
return;
|
|
|
|
RawVAPtr = 0;
|
|
}
|
|
|
|
bool StmtIteratorBase::HandleDecl(Decl* D) {
|
|
if (VarDecl* VD = dyn_cast<VarDecl>(D)) {
|
|
if (const VariableArrayType* VAPtr = FindVA(VD->getType().getTypePtr())) {
|
|
setVAPtr(VAPtr);
|
|
return true;
|
|
}
|
|
|
|
if (VD->getInit())
|
|
return true;
|
|
}
|
|
else if (TypedefNameDecl* TD = dyn_cast<TypedefNameDecl>(D)) {
|
|
if (const VariableArrayType* VAPtr =
|
|
FindVA(TD->getUnderlyingType().getTypePtr())) {
|
|
setVAPtr(VAPtr);
|
|
return true;
|
|
}
|
|
}
|
|
else if (EnumConstantDecl* ECD = dyn_cast<EnumConstantDecl>(D)) {
|
|
if (ECD->getInitExpr())
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
StmtIteratorBase::StmtIteratorBase(Decl** dgi, Decl** dge)
|
|
: DGI(dgi), RawVAPtr(DeclGroupMode), DGE(dge) {
|
|
NextDecl(false);
|
|
}
|
|
|
|
StmtIteratorBase::StmtIteratorBase(const VariableArrayType* t)
|
|
: DGI(nullptr), RawVAPtr(SizeOfTypeVAMode) {
|
|
RawVAPtr |= reinterpret_cast<uintptr_t>(t);
|
|
}
|
|
|
|
Stmt*& StmtIteratorBase::GetDeclExpr() const {
|
|
if (const VariableArrayType* VAPtr = getVAPtr()) {
|
|
assert (VAPtr->SizeExpr);
|
|
return const_cast<Stmt*&>(VAPtr->SizeExpr);
|
|
}
|
|
|
|
assert (inDeclGroup());
|
|
VarDecl* VD = cast<VarDecl>(*DGI);
|
|
return *VD->getInitAddress();
|
|
}
|