/// \brief Get the tentative definition that acts as the real definition in
/// a TU. Returns null if there is a proper definition available.
- const VarDecl *getActingDefinition() const;
VarDecl *getActingDefinition();
+ const VarDecl *getActingDefinition() const {
+ return const_cast<VarDecl*>(this)->getActingDefinition();
+ }
/// \brief Determine whether this is a tentative definition of a
/// variable in C.
bool isTentativeDefinitionNow() const;
- /// \brief Retrieve the definition of this variable, which may come
- /// from a previous declaration. Def will be set to the VarDecl that
- /// contains the initializer, and the result will be that
- /// initializer.
- const Expr *getDefinition(const VarDecl *&Def) const;
-
- const Expr *getDefinition() const {
- const VarDecl* Definition;
- return getDefinition(Definition);
+ /// \brief Get the real (not just tentative) definition for this declaration.
+ VarDecl *getDefinition();
+ const VarDecl *getDefinition() const {
+ return const_cast<VarDecl*>(this)->getDefinition();
}
/// \brief Determine whether this is or was instantiated from an out-of-line
return false;
}
+ /// getAnyInitializer - Get the initializer for this variable, no matter which
+ /// declaration it is attached to.
+ const Expr *getAnyInitializer() const {
+ const VarDecl *D;
+ return getAnyInitializer(D);
+ }
+
+ /// getAnyInitializer - Get the initializer for this variable, no matter which
+ /// declaration it is attached to. Also get that declaration.
+ const Expr *getAnyInitializer(const VarDecl *&D) const;
+
bool hasInit() const {
return !Init.isNull();
}
return Definition;
}
-const VarDecl *VarDecl::getActingDefinition() const {
- return const_cast<VarDecl*>(this)->getActingDefinition();
-}
-
VarDecl *VarDecl::getActingDefinition() {
DefinitionKind Kind = isThisDeclarationADefinition();
if (Kind != TentativeDefinition)
if ((*I)->isThisDeclarationADefinition() == Definition)
return false;
}
- return true;
+ return true;
+}
+
+VarDecl *VarDecl::getDefinition() {
+ for (redecl_iterator I = redecls_begin(), E = redecls_end(); I != E; ++I) {
+ if ((*I)->isThisDeclarationADefinition() == Definition)
+ return *I;
+ }
+ return 0;
}
-const Expr *VarDecl::getDefinition(const VarDecl *&Def) const {
+const Expr *VarDecl::getAnyInitializer(const VarDecl *&D) const {
redecl_iterator I = redecls_begin(), E = redecls_end();
while (I != E && !I->getInit())
++I;
if (I != E) {
- Def = *I;
+ D = *I;
return I->getInit();
}
return 0;
else if (VarDecl *Var = dyn_cast<VarDecl>(D)) {
if (Var->getType()->isIntegralType() &&
Var->getType().getCVRQualifiers() == Qualifiers::Const) {
- const VarDecl *Def = 0;
- if (const Expr *Init = Var->getDefinition(Def))
+ if (const Expr *Init = Var->getAnyInitializer())
if (Init->isValueDependent())
ValueDependent = true;
}
if (Quals.hasVolatile() || !Quals.hasConst())
return ICEDiag(2, cast<DeclRefExpr>(E)->getLocation());
- // Look for the definition of this variable, which will actually have
- // an initializer.
- const VarDecl *Def = 0;
- const Expr *Init = Dcl->getDefinition(Def);
+ // Look for a declaration of this variable that has an initializer.
+ const VarDecl *ID = 0;
+ const Expr *Init = Dcl->getAnyInitializer(ID);
if (Init) {
- if (Def->isInitKnownICE()) {
+ if (ID->isInitKnownICE()) {
// We have already checked whether this subexpression is an
// integral constant expression.
- if (Def->isInitICE())
+ if (ID->isInitICE())
return NoDiag();
else
return ICEDiag(2, cast<DeclRefExpr>(E)->getLocation());
// specify a constant-initializer which shall be an integral
// constant expression (5.19). In that case, the member can appear
// in integral constant expressions.
- if (Def->isOutOfLine()) {
+ if (ID->isOutOfLine()) {
Dcl->setInitKnownICE(false);
return ICEDiag(2, cast<DeclRefExpr>(E)->getLocation());
}
if (!VD->getType()->isReferenceType())
return APValue(E);
// FIXME: Check whether VD might be overridden!
- const VarDecl *Def = 0;
- if (const Expr *Init = VD->getDefinition(Def))
+ if (const Expr *Init = VD->getAnyInitializer())
return Visit(const_cast<Expr *>(Init));
}
if (Info.Ctx.getCanonicalType(E->getType()).getCVRQualifiers()
== Qualifiers::Const) {
if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
- const VarDecl *Def = 0;
- if (const Expr *Init = VD->getDefinition(Def)) {
+ if (const Expr *Init = VD->getAnyInitializer()) {
if (APValue *V = VD->getEvaluatedValue()) {
if (V->isInt())
return Success(V->getInt(), E);
QualType ASTTy = D->getType();
bool NonConstInit = false;
- const Expr *InitExpr = D->getDefinition();
+ const Expr *InitExpr = D->getAnyInitializer();
if (!InitExpr) {
// This is a tentative definition; tentative definitions are
}
if (isConstant) {
- const VarDecl *Def = 0;
- if (const Expr *Init = VD->getDefinition(Def))
+ if (const Expr *Init = VD->getAnyInitializer())
return SemaCheckStringLiteral(Init, TheCall,
HasVAListArg, format_idx, firstDataArg);
}
// attributes declared post-definition are currently ignored
if (Previous.isSingleResult()) {
- const VarDecl *Def = 0;
- VarDecl *PrevDecl = dyn_cast<VarDecl>(Previous.getFoundDecl());
- if (PrevDecl && PrevDecl->getDefinition(Def) && D.hasAttributes()) {
+ VarDecl *Def = dyn_cast<VarDecl>(Previous.getFoundDecl());
+ if (Def && (Def = Def->getDefinition()) &&
+ Def != NewVD && D.hasAttributes()) {
Diag(NewVD->getLocation(), diag::warn_attribute_precede_definition);
Diag(Def->getLocation(), diag::note_previous_definition);
}
AbstractVariableType))
VDecl->setInvalidDecl();
- const VarDecl *Def = 0;
- if (VDecl->getDefinition(Def)) {
+ const VarDecl *Def;
+ if ((Def = VDecl->getDefinition()) && Def != VDecl) {
Diag(VDecl->getLocation(), diag::err_redefinition)
<< VDecl->getDeclName();
Diag(Def->getLocation(), diag::note_previous_definition);
AbstractVariableType))
VDecl->setInvalidDecl();
- const VarDecl *Def = 0;
- if (VDecl->getDefinition(Def)) {
+ const VarDecl *Def;
+ if ((Def = VDecl->getDefinition()) && Def != VDecl) {
Diag(VDecl->getLocation(), diag::err_redefinition)
<< VDecl->getDeclName();
Diag(Def->getLocation(), diag::note_previous_definition);
}
case Decl::Var: {
- VarDecl *Var = cast<VarDecl>(D);
-
- // Variables with initializers have definitions.
- const VarDecl *Def = 0;
- if (Var->getDefinition(Def))
- return MakeCXCursor(const_cast<VarDecl *>(Def), CXXUnit);
-
- // extern and private_extern variables are not definitions.
- if (Var->hasExternalStorage())
- return clang_getNullCursor();
-
- // In-line static data members do not have definitions.
- if (Var->isStaticDataMember() && !Var->isOutOfLine())
- return clang_getNullCursor();
-
- // All other variables are themselves definitions.
- return C;
+ // Ask the variable if it has a definition.
+ if (VarDecl *Def = cast<VarDecl>(D)->getDefinition())
+ return MakeCXCursor(Def, CXXUnit);
+ return clang_getNullCursor();
}
case Decl::FunctionTemplate: {