CXCompletionString clang_getCursorCompletionString(CXCursor cursor) { enum CXCursorKind kind = clang_getCursorKind(cursor); if (clang_isDeclaration(kind)) { Decl *decl = getCursorDecl(cursor); if (isa<NamedDecl>(decl)) { NamedDecl *namedDecl = (NamedDecl *)decl; ASTUnit *unit = getCursorASTUnit(cursor); if (unit->hasSema()) { Sema &S = unit->getSema(); CodeCompletionAllocator *Allocator = unit->getCursorCompletionAllocator().getPtr(); CodeCompletionResult Result(namedDecl); CodeCompletionString *String = Result.CreateCodeCompletionString(S, *Allocator); return String; } } } else if (kind == CXCursor_MacroDefinition) { MacroDefinition *definition = getCursorMacroDefinition(cursor); const IdentifierInfo *MacroInfo = definition->getName(); ASTUnit *unit = getCursorASTUnit(cursor); if (unit->hasSema()) { Sema &S = unit->getSema(); CodeCompletionAllocator *Allocator = unit->getCursorCompletionAllocator().getPtr(); CodeCompletionResult Result(const_cast<IdentifierInfo *>(MacroInfo)); CodeCompletionString *String = Result.CreateCodeCompletionString(S, *Allocator); return String; } } return NULL; }
void PreprocessingRecord::Ifndef(SourceLocation Loc, const Token &MacroNameTok, const MacroDefinition &MD) { // This is not actually a macro expansion but record it as a macro reference. if (MD) addMacroExpansion(MacroNameTok, MD.getMacroInfo(), MacroNameTok.getLocation()); }
ParameterDefinition *MacroParameterNode::getParameterDefinition( boolean includeDummies) { MacroDefinition *md = this->getNetwork()->getDefinition(); // // During deletion of a MacroDefinition, there is no MacroDefinition // for this node and therefore no ParameterDefinition. So return NULL. // if (!md) return NULL; int idx = this->getIndex(); if (idx <= 0) return NULL; if (this->isInput()) { ASSERT(this->isInputRepeatable() == FALSE); if (idx > md->getInputCount()) return NULL; } else { ASSERT(this->isOutputRepeatable() == FALSE); if (idx > md->getOutputCount()) return NULL; } ParameterDefinition *pd; if (this->isInput()) { if (includeDummies) pd = md->getInputDefinition(idx); else pd = md->getNonDummyInputDefinition(idx); } else { if (includeDummies) pd = md->getOutputDefinition(idx); else pd = md->getNonDummyOutputDefinition(idx); } return pd; }
void MacroRepeatedPPCallbacks::MacroExpands(const Token &MacroNameTok, const MacroDefinition &MD, SourceRange Range, const MacroArgs *Args) { // Ignore macro argument expansions. if (!Range.getBegin().isFileID()) return; const MacroInfo *MI = MD.getMacroInfo(); // Bail out if the contents of the macro are containing keywords that are // making the macro too complex. if (std::find_if( MI->tokens().begin(), MI->tokens().end(), [](const Token &T) { return T.isOneOf(tok::kw_if, tok::kw_else, tok::kw_switch, tok::kw_case, tok::kw_break, tok::kw_while, tok::kw_do, tok::kw_for, tok::kw_continue, tok::kw_goto, tok::kw_return); }) != MI->tokens().end()) return; for (unsigned ArgNo = 0U; ArgNo < MI->getNumArgs(); ++ArgNo) { const IdentifierInfo *Arg = *(MI->arg_begin() + ArgNo); const Token *ResultArgToks = Args->getUnexpArgument(ArgNo); if (hasSideEffects(ResultArgToks) && countArgumentExpansions(MI, Arg) >= 2) { Check.diag(ResultArgToks->getLocation(), "side effects in the %ordinal0 macro argument '%1' are " "repeated in macro expansion") << (ArgNo + 1) << Arg->getName(); Check.diag(MI->getDefinitionLoc(), "macro %0 defined here", DiagnosticIDs::Note) << MacroNameTok.getIdentifierInfo(); } } }
void MacroParameterNode::switchNetwork(Network *from, Network *to, boolean silently) { MacroDefinition *md = from->getDefinition(); ParameterDefinition *pd = this->getParameterDefinition(); ParameterDefinition *dummyPd; int n; dummyPd = new ParameterDefinition(-1); dummyPd->setDummy(TRUE); dummyPd->addType(new DXType(DXType::ObjectType)); if(this->isInput()) md->replaceInput(dummyPd, pd); else md->replaceOutput(dummyPd, pd); // // Switch the Network pointers // this->UniqueNameNode::switchNetwork(from, to, silently); // // Make sure we are a macro // to->makeMacro(TRUE); md = to->getDefinition(); if(this->isInput()) { n = md->getFirstAvailableInputPosition(); if (n <= md->getInputCount()) { dummyPd = md->getInputDefinition(n); ASSERT(dummyPd->isDummy()); md->replaceInput(pd,dummyPd); } else { md->addInput(pd); } this->setIndex(n); } else { n = md->getFirstAvailableOutputPosition(); if (n <= md->getOutputCount()) { ParameterDefinition *dummyPd = md->getOutputDefinition(n); ASSERT(dummyPd->isDummy()); md->replaceOutput(pd,dummyPd); } else { md->addOutput(pd); } this->setIndex(n); } // // See if the input is named input_%d or output_%d // and if so, change it to match the possibly new index. // pd = this->getParameterDefinition(); char buf[64]; if (this->isInput()) { strcpy(buf,"input_"); } else { strcpy(buf,"output_"); } int buflen = strlen(buf); const char* current_name = pd->getNameString(); const char* new_name = NUL(char*); boolean name_reset = FALSE; if (EqualSubstring(current_name, buf, buflen)) { int endint = 0; const char *end = ¤t_name[strlen(current_name)]; if (IsInteger(current_name+buflen,endint) && ((current_name+buflen+endint) == end)) { sprintf(buf+buflen,"%d",this->getIndex()); pd->setName(buf); name_reset = TRUE; } } // // Resolve name conflicts with other nodes using global names. // if (!name_reset) { int name_clash=0, i; if (this->isInput()) { int count = to->getInputCount(); for (i=1 ; !name_clash && (i <= count) ; i++) { ParameterDefinition *opd = to->getInputDefinition(i); if ((i != this->getIndex()) && EqualString(current_name,opd->getNameString())) name_clash = i; } } else { int count = to->getOutputCount(); for (i=1 ; !name_clash && (i <= count) ; i++) { ParameterDefinition *opd = to->getOutputDefinition(i); if ((i != this->getIndex()) && EqualString(current_name,opd->getNameString())) name_clash = i; } } if (name_clash) { char name_buf[64]; if (this->isInput()) { sprintf(name_buf,"input_%d", this->getIndex()); } else { sprintf(name_buf,"output_%d", this->getIndex()); } new_name = name_buf; if (!silently) WarningMessage ( "Parameter name `%s' is the same name used by parameter #%d.\n" "Your macro %s has been renamed \"%s\".", current_name, name_clash, (this->isInput()? "Input" : "Output"), new_name ); pd->setName(name_buf); name_reset = TRUE; } } if (!name_reset) { const char* conflict = to->nameConflictExists(this, this->getUniqueName()); if (conflict) { char name_buf[64]; if (this->isInput()) { sprintf(name_buf,"input_%d", this->getIndex()); } else { sprintf(name_buf,"output_%d", this->getIndex()); } new_name = name_buf; if (!silently) WarningMessage ( "A %s with name \"%s\" already exists.\n" "Your macro %s has been renamed \"%s\".", conflict, this->getUniqueName(), (this->isInput()? "Input" : "Output"), name_buf ); pd->setName(name_buf); name_reset = TRUE; } } }
MacroParameterNode::~MacroParameterNode() { Network *net = this->getNetwork(); MacroDefinition *md = net->getDefinition(); Parameter *p; ParameterDefinition *pd = this->getParameterDefinition(); if (this->isInput()) { if (pd && !net->isDeleted() || net == theDXApplication->network) { if(!net->isDeleted()) { if (this->index != net->getInputCount()) { int newIndex = net->getInputCount()+1; this->moveIndex(newIndex, FALSE); } else { for (int i = this->index; i > 1; --i) if (!this->moveIndex(i - 1, FALSE)) break; // this->index = i; } } if (md) md->removeInput(pd); if (pd) delete pd; } p = this->getOutputParameter(1); } else { if (pd && !net->isDeleted() || net == theDXApplication->network) { if(!net->isDeleted()) { if (this->index != net->getOutputCount()) { int newIndex = net->getOutputCount()+1; this->moveIndex(newIndex, FALSE); } else { for (int i = this->index; i > 1; --i) if (!this->moveIndex(i - 1, FALSE)) break; } } if (md) md->removeOutput(pd); if (pd) delete pd; } p = this->getInputParameter(1); } if(p) delete p->getDefinition(); if (net == theDXApplication->network) { if (md && md->getInputCount() == 0 && md->getOutputCount() == 0) net->makeMacro(FALSE); } }
boolean MacroParameterNode::initialize() { this->UniqueNameNode::initialize(); Network *net = this->getNetwork(); if (!net->isMacro()) net->makeMacro(TRUE); MacroDefinition *md = net->getDefinition(); ParameterDefinition *param=NULL; boolean input = this->isInput(); if (!md->isReadingNet()) { param = new ParameterDefinition(-1); param->addType(new DXType(DXType::ObjectType)); } char s[100]; if (input) { if (!md->isReadingNet()) { int n = md->getFirstAvailableInputPosition(); param->markAsInput(); if (n <= md->getInputCount()) { ParameterDefinition *dummyPd = md->getInputDefinition(n); ASSERT(dummyPd->isDummy()); md->replaceInput(param,dummyPd); } else { md->addInput(param); } this->setIndex(n); sprintf(s, "input_%d", this->index); param->setName(s); param->setDefaultValue("(no default)"); } // // The Parameter must have its own ParameterDefinition since // it may change depending upon what we are connected to. // FIXME: ParameterDefinition should have a dup() method. // Parameter *p = this->getOutputParameter(1); ParameterDefinition *pd = p->getDefinition(); #if 11 ParameterDefinition *newpd = pd->duplicate(); #else ParameterDefinition *newpd = new ParameterDefinition(pd->getNameSymbol()); List *l = pd->getTypes(); DXType *dxt; for (ListIterator li(*l); dxt = (DXType*)li.getNext();) newpd->addType(dxt); newpd->markAsOutput(); newpd->setDefaultVisibility(pd->getDefaultVisibility()); newpd->setViewability(pd->isViewable()); newpd->setDescription(pd->getDescription()); newpd->setWriteableCacheability(pd->hasWriteableCacheability()); newpd->setDefaultCacheability(pd->getDefaultCacheability()); if (pd->isRequired()) newpd->setRequired(); else newpd->setNotRequired(); if (pd->isDefaultValue()) newpd->setDefaultValue(pd->getDefaultValue()); else newpd->setDescriptiveValue(pd->getDefaultValue()); #endif p->setDefinition(newpd); } else { if (!md->isReadingNet()) { int n = md->getFirstAvailableOutputPosition(); param->markAsOutput(); if (n <= md->getOutputCount()) { ParameterDefinition *dummyPd = md->getOutputDefinition(n); ASSERT(dummyPd->isDummy()); md->replaceOutput(param,dummyPd); } else { md->addOutput(param); } this->setIndex(n); sprintf(s, "output_%d", this->index); param->setName(s); param->setDefaultValue("(no default)"); } // // The Parameter must have its own ParameterDefinition since // it may change depending upon what we are connected to. // FIXME: ParameterDefinition should have a dup() method. // Parameter *p = this->getInputParameter(1); ParameterDefinition *pd = p->getDefinition(); #if 11 ParameterDefinition *newpd = pd->duplicate(); #else ParameterDefinition *newpd = new ParameterDefinition(pd->getNameSymbol()); List *l = pd->getTypes(); DXType *dxt; for (ListIterator li(*l); dxt = (DXType*)li.getNext();) newpd->addType(dxt); newpd->markAsInput(); newpd->setDefaultVisibility(pd->getDefaultVisibility()); newpd->setViewability(pd->isViewable()); newpd->setDescription(pd->getDescription()); newpd->setWriteableCacheability(pd->hasWriteableCacheability()); newpd->setDefaultCacheability(pd->getDefaultCacheability()); if (pd->isRequired()) newpd->setRequired(); else newpd->setNotRequired(); if (pd->isDefaultValue()) newpd->setDefaultValue(pd->getDefaultValue()); else newpd->setDescriptiveValue(pd->getDefaultValue()); #endif p->setDefinition(newpd); } return TRUE; }
void PreprocessingRecord::MacroUndefined(const Token &Id, const MacroDefinition &MD, const MacroDirective *Undef) { MD.forAllDefinitions([&](MacroInfo *MI) { MacroDefinitions.erase(MI); }); }
void PreprocessingRecord::MacroExpands(const Token &Id, const MacroDefinition &MD, SourceRange Range, const MacroArgs *Args) { addMacroExpansion(Id, MD.getMacroInfo(), Range); }
/// EvaluateDefined - Process a 'defined(sym)' expression. static bool EvaluateDefined(PPValue &Result, Token &PeekTok, DefinedTracker &DT, bool ValueLive, Preprocessor &PP) { SourceLocation beginLoc(PeekTok.getLocation()); Result.setBegin(beginLoc); // Get the next token, don't expand it. PP.LexUnexpandedNonComment(PeekTok); // Two options, it can either be a pp-identifier or a (. SourceLocation LParenLoc; if (PeekTok.is(tok::l_paren)) { // Found a paren, remember we saw it and skip it. LParenLoc = PeekTok.getLocation(); PP.LexUnexpandedNonComment(PeekTok); } if (PeekTok.is(tok::code_completion)) { if (PP.getCodeCompletionHandler()) PP.getCodeCompletionHandler()->CodeCompleteMacroName(false); PP.setCodeCompletionReached(); PP.LexUnexpandedNonComment(PeekTok); } // If we don't have a pp-identifier now, this is an error. if (PP.CheckMacroName(PeekTok, MU_Other)) return true; // Otherwise, we got an identifier, is it defined to something? IdentifierInfo *II = PeekTok.getIdentifierInfo(); MacroDefinition Macro = PP.getMacroDefinition(II); Result.Val = !!Macro; Result.Val.setIsUnsigned(false); // Result is signed intmax_t. // If there is a macro, mark it used. if (Result.Val != 0 && ValueLive) PP.markMacroAsUsed(Macro.getMacroInfo()); // Save macro token for callback. Token macroToken(PeekTok); // If we are in parens, ensure we have a trailing ). if (LParenLoc.isValid()) { // Consume identifier. Result.setEnd(PeekTok.getLocation()); PP.LexUnexpandedNonComment(PeekTok); if (PeekTok.isNot(tok::r_paren)) { PP.Diag(PeekTok.getLocation(), diag::err_pp_expected_after) << "'defined'" << tok::r_paren; PP.Diag(LParenLoc, diag::note_matching) << tok::l_paren; return true; } // Consume the ). Result.setEnd(PeekTok.getLocation()); PP.LexNonComment(PeekTok); } else { // Consume identifier. Result.setEnd(PeekTok.getLocation()); PP.LexNonComment(PeekTok); } // Invoke the 'defined' callback. if (PPCallbacks *Callbacks = PP.getPPCallbacks()) { Callbacks->Defined(macroToken, Macro, SourceRange(beginLoc, PeekTok.getLocation())); } // Success, remember that we saw defined(X). DT.State = DefinedTracker::DefinedMacro; DT.TheMacro = II; return false; }
/// EvaluateDefined - Process a 'defined(sym)' expression. static bool EvaluateDefined(PPValue &Result, Token &PeekTok, DefinedTracker &DT, bool ValueLive, Preprocessor &PP) { SourceLocation beginLoc(PeekTok.getLocation()); Result.setBegin(beginLoc); // Get the next token, don't expand it. PP.LexUnexpandedNonComment(PeekTok); // Two options, it can either be a pp-identifier or a (. SourceLocation LParenLoc; if (PeekTok.is(tok::l_paren)) { // Found a paren, remember we saw it and skip it. LParenLoc = PeekTok.getLocation(); PP.LexUnexpandedNonComment(PeekTok); } if (PeekTok.is(tok::code_completion)) { if (PP.getCodeCompletionHandler()) PP.getCodeCompletionHandler()->CodeCompleteMacroName(false); PP.setCodeCompletionReached(); PP.LexUnexpandedNonComment(PeekTok); } // If we don't have a pp-identifier now, this is an error. if (PP.CheckMacroName(PeekTok, MU_Other)) return true; // Otherwise, we got an identifier, is it defined to something? IdentifierInfo *II = PeekTok.getIdentifierInfo(); MacroDefinition Macro = PP.getMacroDefinition(II); Result.Val = !!Macro; Result.Val.setIsUnsigned(false); // Result is signed intmax_t. // If there is a macro, mark it used. if (Result.Val != 0 && ValueLive) PP.markMacroAsUsed(Macro.getMacroInfo()); // Save macro token for callback. Token macroToken(PeekTok); // If we are in parens, ensure we have a trailing ). if (LParenLoc.isValid()) { // Consume identifier. Result.setEnd(PeekTok.getLocation()); PP.LexUnexpandedNonComment(PeekTok); if (PeekTok.isNot(tok::r_paren)) { PP.Diag(PeekTok.getLocation(), diag::err_pp_expected_after) << "'defined'" << tok::r_paren; PP.Diag(LParenLoc, diag::note_matching) << tok::l_paren; return true; } // Consume the ). Result.setEnd(PeekTok.getLocation()); PP.LexNonComment(PeekTok); } else { // Consume identifier. Result.setEnd(PeekTok.getLocation()); PP.LexNonComment(PeekTok); } // [cpp.cond]p4: // Prior to evaluation, macro invocations in the list of preprocessing // tokens that will become the controlling constant expression are replaced // (except for those macro names modified by the 'defined' unary operator), // just as in normal text. If the token 'defined' is generated as a result // of this replacement process or use of the 'defined' unary operator does // not match one of the two specified forms prior to macro replacement, the // behavior is undefined. // This isn't an idle threat, consider this program: // #define FOO // #define BAR defined(FOO) // #if BAR // ... // #else // ... // #endif // clang and gcc will pick the #if branch while Visual Studio will take the // #else branch. Emit a warning about this undefined behavior. if (beginLoc.isMacroID()) { bool IsFunctionTypeMacro = PP.getSourceManager() .getSLocEntry(PP.getSourceManager().getFileID(beginLoc)) .getExpansion() .isFunctionMacroExpansion(); // For object-type macros, it's easy to replace // #define FOO defined(BAR) // with // #if defined(BAR) // #define FOO 1 // #else // #define FOO 0 // #endif // and doing so makes sense since compilers handle this differently in // practice (see example further up). But for function-type macros, // there is no good way to write // # define FOO(x) (defined(M_ ## x) && M_ ## x) // in a different way, and compilers seem to agree on how to behave here. // So warn by default on object-type macros, but only warn in -pedantic // mode on function-type macros. if (IsFunctionTypeMacro) PP.Diag(beginLoc, diag::warn_defined_in_function_type_macro); else PP.Diag(beginLoc, diag::warn_defined_in_object_type_macro); } // Invoke the 'defined' callback. if (PPCallbacks *Callbacks = PP.getPPCallbacks()) { Callbacks->Defined(macroToken, Macro, SourceRange(beginLoc, PeekTok.getLocation())); } // Success, remember that we saw defined(X). DT.State = DefinedTracker::DefinedMacro; DT.TheMacro = II; return false; }
/// HandleMacroExpandedIdentifier - If an identifier token is read that is to be /// expanded as a macro, handle it and return the next token as 'Identifier'. bool Preprocessor::HandleMacroExpandedIdentifier(Token &Identifier, const MacroDefinition &M) { MacroInfo *MI = M.getMacroInfo(); // If this is a macro expansion in the "#if !defined(x)" line for the file, // then the macro could expand to different things in other contexts, we need // to disable the optimization in this case. if (CurPPLexer) CurPPLexer->MIOpt.ExpandedMacro(); // If this is a builtin macro, like __LINE__ or _Pragma, handle it specially. if (MI->isBuiltinMacro()) { ExpandBuiltinMacro(Identifier); return true; } /// Args - If this is a function-like macro expansion, this contains, /// for each macro argument, the list of tokens that were provided to the /// invocation. MacroArgs *Args = nullptr; // Remember where the end of the expansion occurred. For an object-like // macro, this is the identifier. For a function-like macro, this is the ')'. SourceLocation ExpansionEnd = Identifier.getLocation(); // If this is a function-like macro, read the arguments. if (MI->isFunctionLike()) { // Remember that we are now parsing the arguments to a macro invocation. // Preprocessor directives used inside macro arguments are not portable, and // this enables the warning. InMacroArgs = true; Args = ReadMacroCallArgumentList(Identifier, MI, ExpansionEnd); // Finished parsing args. InMacroArgs = false; // If there was an error parsing the arguments, bail out. if (!Args) return true; ++NumFnMacroExpanded; } else { ++NumMacroExpanded; } // Notice that this macro has been used. markMacroAsUsed(MI); // Remember where the token is expanded. SourceLocation ExpandLoc = Identifier.getLocation(); SourceRange ExpansionRange(ExpandLoc, ExpansionEnd); // If the macro definition is ambiguous, complain. if (M.isAmbiguous()) { Diag(Identifier, diag::warn_pp_ambiguous_macro) << Identifier.getIdentifierInfo(); Diag(MI->getDefinitionLoc(), diag::note_pp_ambiguous_macro_chosen) << Identifier.getIdentifierInfo(); M.forAllDefinitions([&](const MacroInfo *OtherMI) { if (OtherMI != MI) Diag(OtherMI->getDefinitionLoc(), diag::note_pp_ambiguous_macro_other) << Identifier.getIdentifierInfo(); }); } // If we started lexing a macro, enter the macro expansion body. // If this macro expands to no tokens, don't bother to push it onto the // expansion stack, only to take it right back off. if (MI->getNumTokens() == 0) { // No need for arg info. if (Args) Args->destroy(*this); // Propagate whitespace info as if we had pushed, then popped, // a macro context. Identifier.setFlag(Token::LeadingEmptyMacro); PropagateLineStartLeadingSpaceInfo(Identifier); ++NumFastMacroExpanded; return false; } else if (MI->getNumTokens() == 1 && isTrivialSingleTokenExpansion(MI, Identifier.getIdentifierInfo(), *this)) { // Otherwise, if this macro expands into a single trivially-expanded // token: expand it now. This handles common cases like // "#define VAL 42". // No need for arg info. if (Args) Args->destroy(*this); // Propagate the isAtStartOfLine/hasLeadingSpace markers of the macro // identifier to the expanded token. bool isAtStartOfLine = Identifier.isAtStartOfLine(); bool hasLeadingSpace = Identifier.hasLeadingSpace(); // Replace the result token. Identifier = MI->getReplacementToken(0); // Restore the StartOfLine/LeadingSpace markers. Identifier.setFlagValue(Token::StartOfLine , isAtStartOfLine); Identifier.setFlagValue(Token::LeadingSpace, hasLeadingSpace); // Update the tokens location to include both its expansion and physical // locations. SourceLocation Loc = SourceMgr.createExpansionLoc(Identifier.getLocation(), ExpandLoc, ExpansionEnd,Identifier.getLength()); Identifier.setLocation(Loc); // If this is a disabled macro or #define X X, we must mark the result as // unexpandable. if (IdentifierInfo *NewII = Identifier.getIdentifierInfo()) { if (MacroInfo *NewMI = getMacroInfo(NewII)) if (!NewMI->isEnabled() || NewMI == MI) { Identifier.setFlag(Token::DisableExpand); // Don't warn for "#define X X" like "#define bool bool" from // stdbool.h. if (NewMI != MI || MI->isFunctionLike()) Diag(Identifier, diag::pp_disabled_macro_expansion); } } // Since this is not an identifier token, it can't be macro expanded, so // we're done. ++NumFastMacroExpanded; return true; } // Start expanding the macro. EnterMacro(Identifier, ExpansionEnd, MI, Args); return false; }